Establishing IPsec tunnel/connection between FreeBSD and Linux (openswan IPsec Cisco WRT54G Router)
Below is a simple setup demonstrating steps to establish an IPsec connection/tunnel between two machines one running Ipsec/racoon (on FreeBSD) and the other running openswan Ipsec (on WRT54G running Linux) using pre-shared key: This IPsec setup example shows how to control the Private LAN_A (146.64.0.0) network access.
.........(INTERNET)
.........|
.........|
..| FreeBSD | ......10.50.1.3..............................10.50.1.80| Openswan IPsec|
.| Router_A |<========> (“NETWORK”)<=======>| Router_B |
.| 146.64.17.1 |................................................................| 10.1.13.1 |
............ ||.........................................................................||
...Private LAN_A....................................................PPrivate LAN_B
...........|.......................................................................................|...........
....Client_A (146.64.17.12) ..................................Client_B (10.1.13.130)
NOTE: Before running racoon/ipsec and openswan ipsec, ensure that all nodes can successfully reach (ping) each other.
INSTALLING OPENSWAN ON WRT54G
To install, add the following to /etc/ipkg.conf:
src openswan ftp://ftp.openswan.org/openswan/binaries/openwrt/buildroot-20040509/ipkg/
and then run:
ipkg update
ipkg install gmp mawk openswan-module openswan
NOTE: Since /etc/ipkg.conf would normally be a link to the file in /rom directory; You can simple delete the link, and then copy the file over.
CONFIGURATION (Router_A IPsec)
There are three (3) configuration files on Router_A that needs to be edited: ipsec.conf (found in /etc on FreeBSD), psk.conf.(found in /usr/local/etc/racoon/ on FreeBSD) and racoon.conf.(found in /usr/local/etc/racoon/ on FreeBSD).
Add the following two lines in ipsec.conf: (This file defines the ends points of the tunnel to be established. There’d be two lines for each LAN_B client )
spdadd 146.64.0.0/16 10.1.13.0/24 any -P out ipsec esp/tunnel/10.50.1.3-10.50.1.80/require;
spdadd 10.1.13.0/24 146.64.0.0/16 any -P in ipsec esp/tunnel/10.50.1.80-10.50.1.3/require;
Roughly; the first line says “traffic coming from 146.64.0.0 network destined for 10.1.13.0 network must be transported via an IPsec tunnel with local endpoint 10.50.1.3 and far endpoint 10.50.1.80”.
The second line says “traffic coming from 10.1.13.0 network destined for 146.64.0.0 network must/would use an IPsec tunnel with a far endpoint 10.50.1.80 and local endpoint 10.50.1.3”.
Add the following line to psk.conf (This file defines the pre-shared key to be used between Router_A and Router_B).
10.50.1.80 presharedkey
NOTE: Comments must be on a different line to the pre-shared key entry, otherwise the comments are interpreted as part of the pre-shared key.
Add the following lines to racoon.conf
path pre_shared_key "/usr/local/etc/racoon/psk.txt" ;
remote anonymous
{
# exchange_mode aggressive,main ;
exchange_mode main ;
lifetime time 24 hour ;
proposal {
encryption_algorithm 3des ;
hash_algorithm sha1;
authentication_method pre_shared_key ;
dh_group 2 ;
}
}
sainfo anonymous
{
lifetime time 12 hour ;
encryption_algorithm 3des, blowfish, des, rijndael ;
authentication_algorithm hmac_sha1, hmac_md5 ;
compression_algorithm deflate ;
}
IMPORTANT: The IPsec version (2.3.1) used in this example did not seem to support “aggressive” exchange_mode hence “main” is specified. However, it is possible to include more than mode by separating them with comma; i.e.
exchange_mode aggressive, main ;
Both ways (specifying one or more modes) works! Further other lines with more than one values separated by comma may contain only one value as described for exchange_mode above.
CONFIGURATION (Openswan IPsec, Router_B)
There are two (2) files on Router_B that needs editing: ipsec.conf (found in /etc on Linux) and ipsec.secrets (found in /etc on Linux).
Add the following line in ipsec.secrets: (This file defines the ends points of the tunnel to be established and also the pre-shared key to be used)
10.50.1.3 10.50.1.80: PSK “presharedkey”
NOTE: 1. Place the string after PSK in quotes if it does not start with 0x (as in a hexadecimal number), otherwise openswan will complain.
2. The string after PSK must be the same as that specified in psk.conf on Router_A.
Add the following lines in ipsec.conf: (This file defines among other things, the network to be protected, authentication methods, type of connection, etc.)
config setup
interfaces="ipsec0=eth1"
klipsdebug=none
plutodebug=none
uniqueids=yes
conn %default
keyingtries=0
authby=secret #rsasig
conn crypt
left=10.50.1.80
leftid=10.50.1.80
leftsubnet=10.1.13.1/24
right=10.50.1.3
rightid=10.50.1.3
rightsubnet=146.64.8.8/16
auto=start
type=tunnel
NOTE: The name of our connection is called “crypt”. Under “config setup”, the line interfaces=”ipsec0=eth1” must refer to a real interface (ifconfig will show available interfaces) and also must be the interface through which the data to be protected will travel, in case of more than one NIC. The line “auto=start” says, the connection “crypt” must be brought up when openswan ipsec starts up; to bring up the connection manually either comment out the line or specify “auto=ignore”. The explanation given for ipsec.conf on Router_A is pretty much the same as for Router_B.
STARTING UP IPsec and Racoon (FreeBSD).
At this point all machines are able to reach (ping) each other successfully. Next ensure ipsec and racoon are not running. On my machine I do:
verdi2istc#/etc/rc.d/ipsec stop
Clearing ipsec manual keys/policies.
to stop ipsec if it was already running; and do
verdi2istc# setkey -P -D
No SPD entries.
To ensure there are no IPsec SA/SP database entries; and next do
verdi2istc#killall racoon
to stop racoon.
Next issue
verdi2istc# /etc/rc.d/ipsec restart
to start ipsec, and to verify ipsec started successfully then do
verdi2istd# setkey -P -D
10.1.13.0/24[any] 146.64.0.0/16[any] any
in ipsec
esp/tunnel/10.50.1.80-10.50.1.3/require
created: Aug 30
lifetime: 0(s) validtime: 0(s)
spid=16531 seq=1 pid=583
refcnt=1
146.64.0.0/16[any] 10.1.13.0/24[any] any
out ipsec
esp/tunnel/10.50.1.3-10.50.1.80/require
created: Aug 30
lifetime: 0(s) validtime: 0(s)
spid=16530 seq=0 pid=583
refcnt=1
From Router_A, type either racoon (to run in the backgroung) or racoon –F
verdi2istd#racoon
or to fun in foreground type
verdi2istd#racoon -F -d
Foreground mode.
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
2005-08-30
The –d option is for debug, to see more output add extra –d.
IMPORTANT: At this point if all went well Client_A should not be reachable (try ping) from Router_B and Client_B; meaning private LAN_A is now protected. However, Router_A and Router_B should be able reach/see each other. Do not continue until this is accomplished.
STARTING UP OPENSWAN IPSEC
Now, on Router_B do:
root@Lawrence:/# ipsec setup restart
ipsec_setup: Stopping Openswan IPsec...
ipsec_setup: Starting Openswan IPsec 2.3.1...
verify that the IPsec tunnel has been established correctly by issuing:
root@Lawrence:/# ipsec whack --status
000 interface ipsec0/eth1 10.50.1.80
000 %myid = (none)
000 debug none
000
000 algorithm ESP encrypt: id=3, name=ESP_3DES, ivlen=64, keysizemin=168, keysizemax=168
000 algorithm ESP encrypt: id=12, name=ESP_AES, ivlen=128, keysizemin=128, keysizemax=256
000 algorithm ESP auth attr: id=1, name=AUTH_ALGORITHM_HMAC_MD5, keysizemin=128, keysizemax=128
000 algorithm ESP auth attr: id=2, name=AUTH_ALGORITHM_HMAC_SHA1, keysizemin=160, keysizemax=160
000
000 algorithm IKE encrypt: id=7, name=OAKLEY_AES_CBC, blocksize=16, keydeflen=128
000 algorithm IKE encrypt: id=5, name=OAKLEY_3DES_CBC, blocksize=8, keydeflen=192
000 algorithm IKE hash: id=2, name=OAKLEY_SHA1, hashsize=20
000 algorithm IKE hash: id=1, name=OAKLEY_MD5, hashsize=16
000 algorithm IKE dh group: id=2, name=OAKLEY_GROUP_MODP1024, bits=1024
000 algorithm IKE dh group: id=5, name=OAKLEY_GROUP_MODP1536, bits=1536
000 algorithm IKE dh group: id=14, name=OAKLEY_GROUP_MODP2048, bits=2048
000 algorithm IKE dh group: id=15, name=OAKLEY_GROUP_MODP3072, bits=3072
000 algorithm IKE dh group: id=16, name=OAKLEY_GROUP_MODP4096, bits=4096
000 algorithm IKE dh group: id=17, name=OAKLEY_GROUP_MODP6144, bits=6144
000 algorithm IKE dh group: id=18, name=OAKLEY_GROUP_MODP8192, bits=8192
000
000 stats db_ops.c: {curr_cnt, total_cnt, maxsz} :context={0,0,0} trans={0,0,0} attrs={0,0,0}
000
000 "crypt": 10.1.13.0/24===10.50.1.80...10.50.1.3===146.64.0.0/16; erouted; eroute owner: #2
000 "crypt": srcip=unset; dstip=unset
000 "crypt": ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0
000 "crypt": policy: PSK+ENCRYPT+TUNNEL+PFS+UP; prio: 24,16; interface: eth1;
000 "crypt": newest ISAKMP SA: #1; newest IPsec SA: #2;
000 "crypt": IKE algorithm newest: 3DES_CBC_192-SHA1-MODP1024
000
000 #2: "crypt":500 STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 27961s; newest IPSEC; eroute owner
000 #2: "crypt" esp.2ec9213@10.50.1.3 esp.aa7dc439@10.50.1.80 tun.1002@10.50.1.3 tun.1001@10.50.1.80
000 #1: "crypt":500 STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 2625s; newest ISAKMP; nodpd
000
root@Lawrence:/#
At this point Client_A should be reachable by Client_B. On each/either Router do a tcpdump; and any packets with ESP indicates that the setup tunnel is currently handling data from the clients.
NOTE: ESP packets will only appear if there are packets from either client to the other client.
Earlier I showed how to stop a connection from being started up automatically by openswan. IPsec. So now with ipsec running but our connection “crypt” NOT up, we will debug the starting up of the connection (crypt). To debug the key exchange with racoon, first create a script with following content:
ipsec pluto --debug-all
ipsec whack \
--name crypt \
--tunnel \
--host 10.50.1.80 \
--nexthop 10.50.1.3 \
--client 10.1.13.1/24 \
--updown 'ipsec _updown' --id 10.50.1.80 \
--to \
--host 10.50.1.3 \
--client 146.64.8.1/16 \
--updown 'ipsec _updown' --id 10.50.1.3 \
--psk \
--esp 3des-md5,3des-sha1 \
--ike 3des-md5,3des-sha1 \
--encrypt
ipsec whack --listen
ipsec whack --route --name crypt
ipsec whack --initiate --name crypt
Running this script will show the various key exchange messages. The messages are pretty much clear to see what it’s happening.