Linux to Cisco Openswan IPSec Configuration

Reading Time: 6 minutes

[notice]For this example I use the following IP scheme|–O–—–[INTERNET]——–O–|[/notice]

I was approached a few weeks back to assist in creating a VPN Tunnel between two end points. Of course in my naivety I readily assumed it was between to Cisco devices but that turned out not to be the case. The tunnel was to be between a Linux box (in this case Ubuntu on a hosted VPS provider) and an unknown endpoint. This tunnel was going to be host to host as opposed to LAN to LAN. After some quick discovery work, getting access to the Linux box, and seeing the required proposal from the other side I started diving into the unknown of Openswan. Luckily, after doing som research for the configuration and verification things started shaping up and much to my approval, a lot of what you would look for in Cisco verification was the same on the Linux box. The configuration goes as such.

Naturally the first step is to install Openswan. As per usual use your distributions software management to install this. The first thing I configured was the ipsec configuration file. On the Ubuntu box this resided in “/etc/ipsec.conf”. The configuration was as follows.

config setup

        ## PHASE 1 ##
        ## PHASE 2 ##
        ## FOR DIRECT ROUTING ##

I’ll break down the configuraiton file above a little bit to clarify the concept.

The line at the top stating “virtual_private” underneath the “config setup” declaration is essentially telling IPSec which private networks are allowed to be encrypted. This goes at the top of the file because you can create more than one connection through the same configuration file. In this case we only had one which is labled “conn IPSEC_VPN”

Also in the “config setup” section we are indicating that this configuration is not going to use nat_traversal. Another key line is the “plutoopts” line which is similar to stating a “source interface” on a Cisco GRE tunnel.

From there we move on to the tunnel configuration itself. This is done under the “conn IPSEC_VPN” declaration. Again, you can have more than one in this configuration file.

Underneath here we state we will be authenticating by a preshared secret. The “authby=secret” statement tells Openswan to look at /etc/ipsec.secrets for the pre shared key and peers. We also tell the tunnel to automatically start when Openswan does.

Phase 1 of the tunnel is indicated by the configuration statement “ike=” along with “keyexchange=ike”. In Phase 1 of this tunnel we used AES-256, SHA1, and DH Group 5 indcated by “modp1536”

Phase 2 of the tunnel is configured via the “phase2”, “esp”, and “salifetime” statements. Here we told Phase 2 to utilize ESP and defined AES-256 and SHA1. We also changed the Security Association Lifetime to 3600 seconds.

The next steps are explained by keeping in mind that left is equivelent to the near end of the tunnel (think our side we are configuring) and right is equivelent to the far end of the tunnel. With that in mind, the “left=” and “right=” statements define the public peer ends. The “leftsubnet=” and “rightsubnet=” represent the ACL stating which near end traffic destined to which farend traffic is to be encrypted. In our case, as it was a host to host tunnel we used /32 host prefixes. We also told the near end to use its standard default route to get towards its peer.

Next we configure the preshared keys in the /etc/ipsec.secrets file. This is fairly straight forward indicating the left “near end” public IP followed by the right “far end” public IP ending with a “:”. The key itself follows the PSK statement. PSK MY$3CR3T!

Next, since we needed all traffic from our Linux boxed destined to the private network at the other end to be sourced from our private address we need to add a static route. Linux allows you to add a static route to a destination, define the interface and IP address traffic should be sourced from. This essentially caused the Linux box to source any traffic it generated to the VPN subnet to look at is if came from it’s private address. This allows commands to be run without needing to be able to specify a source interface in the commands. This is the band-aide as some commands don’t have a source interface option.

ip route via dev eth0 src

Naturally I ran into some issues while configuring this as I haven’t ever worked with Openswan or its syntax so I got familiar with the “ipsec auto –status” command. This is similar to debug ipsec and isakmp on a Cisco router. Lines to note are highlighted. Specifically watching for “ISAKMP SA Established” and “IPSec SA Established” just like we would when running “show crypto isakmp sa” and “show crypto ipsec sa”. See marked lines 72 and 74.

admin@server1:~$ sudo ipsec auto --status
000 using kernel interface: netkey
000 interface eth0/eth0 2001:4800:780e:510:5b34:924b:ff03:c48d
000 interface lo/lo ::1
000 interface eth0/eth0
000 %myid = (none)
000 debug none
000 virtual_private (%priv):
000 - allowed 2 subnets: 
000 - disallowed 0 subnets: 
000 WARNING: Either virtual_private= is not specified, or there is a syntax 
000          error in that line. 'left/rightsubnet=vhost:%priv' will not work!
000 WARNING: Disallowed subnets in virtual_private= is empty. If you have 
000          private address space in internal use, it should be excluded!
000 algorithm ESP encrypt: id=2, name=ESP_DES, ivlen=8, keysizemin=64, keysizemax=64
000 algorithm ESP encrypt: id=3, name=ESP_3DES, ivlen=8, keysizemin=192, keysizemax=192
000 algorithm ESP encrypt: id=6, name=ESP_CAST, ivlen=8, keysizemin=40, keysizemax=128
000 algorithm ESP encrypt: id=7, name=ESP_BLOWFISH, ivlen=8, keysizemin=40, keysizemax=448
000 algorithm ESP encrypt: id=11, name=ESP_NULL, ivlen=0, keysizemin=0, keysizemax=0
000 algorithm ESP encrypt: id=12, name=ESP_AES, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=13, name=ESP_AES_CTR, ivlen=8, keysizemin=160, keysizemax=288
000 algorithm ESP encrypt: id=14, name=ESP_AES_CCM_A, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=15, name=ESP_AES_CCM_B, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=16, name=ESP_AES_CCM_C, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=18, name=ESP_AES_GCM_A, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=19, name=ESP_AES_GCM_B, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=20, name=ESP_AES_GCM_C, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=22, name=ESP_CAMELLIA, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=252, name=ESP_SERPENT, ivlen=8, keysizemin=128, keysizemax=256
000 algorithm ESP encrypt: id=253, name=ESP_TWOFISH, ivlen=8, 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 algorithm ESP auth attr: id=5, name=AUTH_ALGORITHM_HMAC_SHA2_256, keysizemin=256, keysizemax=256
000 algorithm ESP auth attr: id=6, name=AUTH_ALGORITHM_HMAC_SHA2_384, keysizemin=384, keysizemax=384
000 algorithm ESP auth attr: id=7, name=AUTH_ALGORITHM_HMAC_SHA2_512, keysizemin=512, keysizemax=512
000 algorithm ESP auth attr: id=8, name=AUTH_ALGORITHM_HMAC_RIPEMD, keysizemin=160, keysizemax=160
000 algorithm ESP auth attr: id=9, name=AUTH_ALGORITHM_AES_CBC, keysizemin=128, keysizemax=128
000 algorithm ESP auth attr: id=251, name=(null), keysizemin=0, keysizemax=0
000 algorithm IKE encrypt: id=0, name=(null), blocksize=16, keydeflen=131
000 algorithm IKE encrypt: id=5, name=OAKLEY_3DES_CBC, blocksize=8, keydeflen=192
000 algorithm IKE encrypt: id=7, name=OAKLEY_AES_CBC, blocksize=16, keydeflen=128
000 algorithm IKE hash: id=1, name=OAKLEY_MD5, hashsize=16
000 algorithm IKE hash: id=2, name=OAKLEY_SHA1, hashsize=20
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 algorithm IKE dh group: id=22, name=OAKLEY_GROUP_DH22, bits=1024
000 algorithm IKE dh group: id=23, name=OAKLEY_GROUP_DH23, bits=2048
000 algorithm IKE dh group: id=24, name=OAKLEY_GROUP_DH24, bits=2048
000 stats db_ops: {curr_cnt, total_cnt, maxsz} :context={0,4,64} trans={0,4,3072} attrs={0,4,2048} 
000 "IPSEC_VPN":[+S=C]---[+S=C]===; erouted; eroute owner: #4
000 "IPSEC_VPN":     myip=unset; hisip=unset;
000 "IPSEC_VPN":   ike_life: 3600s; ipsec_life: 3600s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0
000 "IPSEC_VPN":   policy: PSK+ENCRYPT+TUNNEL+UP+IKEv2ALLOW+SAREFTRACK+lKOD+rKOD; prio: 32,32; interface: eth0; 
000 "IPSEC_VPN":   newest ISAKMP SA: #3; newest IPsec SA: #4; 
000 "IPSEC_VPN":   IKE algorithms wanted: AES_CBC(7)_256-SHA1(2)_000-MODP1536(5); flags=-strict
000 "IPSEC_VPN":   IKE algorithms found:  AES_CBC(7)_256-SHA1(2)_160-MODP1536(5)
000 "IPSEC_VPN":   IKE algorithm newest: AES_CBC_256-SHA1-MODP1536
000 "IPSEC_VPN":   ESP algorithms wanted: AES(12)_256-SHA1(2)_000; flags=-strict
000 "IPSEC_VPN":   ESP algorithms loaded: AES(12)_256-SHA1(2)_160
000 "IPSEC_VPN":   ESP algorithm newest: AES_256-HMAC_SHA1; pfsgroup=<N/A>
000 #4: "IPSEC_VPN":500 STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 2992s; newest IPSEC; eroute owner; isakmp#3; idle; import:admin initiate
000 #4: "IPSEC_VPN" esp.bf25447b@ esp.71c3706e@ tun.0@ tun.0@ ref=0 refhim=4294901761
000 #3: "IPSEC_VPN":500 STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 2747s; newest ISAKMP; lastdpd=-1s(seq in:0 out:0); idle; import:admin initiate

There was also a simple command to quickly see if the tunnel made it to the up state or not. This command was “service ipsec status”. The output is self explanitary.

admin@server1:/etc/network$sudo service ipsec status
IPsec running  - pluto pid: 7846
pluto pid 7846
1 tunnels up
some eroutes exist

Finally we verified private host to host connectivity with a simple ping.

Ping Proof

admin@server1:~$ ping
PING ( from X.X.X.X eth1: 56(84) bytes of data.
64 bytes from icmp_req=1 ttl=126 time=43.4 ms
64 bytes from icmp_req=2 ttl=126 time=43.4 ms
64 bytes from icmp_req=3 ttl=126 time=43.8 ms
64 bytes from icmp_req=4 ttl=126 time=43.3 ms
64 bytes from icmp_req=5 ttl=126 time=45.3 ms
Share this article:

Permanent link to this article: