IPsec, Solaris 10 and non-global zones

I have been working on joining a data-center-only VPN to be able to talk to another data-center-only VPN other by creating a IPsec tunnel between a server in each data center.  I chose to use the Sun Fire V490s that are also my Solaris 10 zone servers, since they are the most common system I have in each data center.  I started with Sun’s Protecting a VPN with IPsec document, but soon found some errors.

ipsecconf

I followed the steps for the “How to Protect a VPN With an IPsec Tunnel in Tunnel Mode Over IPv4” and ran into my first problem with step 5 “(Optional) Verify the syntax of the IPsec policy file”.  It states:

ipsecconf -c -f /etc/inet/ipsecinit.conf

Which give me the error:

ipsecconf: -f : Policy config file cannot be opened: No such file or directory

and rearraning the arguments so that the -c finds the file:

Usage:  ipsecconf
ipsecconf -a ([-]|) [-q]
ipsecconf -c
ipsecconf -r ([-]|) [-q]
ipsecconf -d [-i tunnel-interface]
ipsecconf -d
ipsecconf -l [-n] [-i tunnel-interface]
ipsecconf -f [-i tunnel-interface]
ipsecconf -L [-n]
ipsecconf -F
ipsecconf: Multiple commands or interface not required.
ipsecconf: Fatal error – exiting.

Seems you do not want the -f

ipsecconf -c /etc/inet/ipsecinit.conf
IPsec configuration does not contain any errors.
IPsec policy was not modified.

In troubleshooting this error, I caused the tunnel not to be using IPsec at all.  The ifconfig output for the tunnel went from this:

ip.tun0: flags=11028d1 mtu 1480 index 9
inet tunnel src 172.16.124.38 tunnel dst 172.16.3.139
tunnel security settings  –>  use ‘ipsecconf -ln -i ip.tun0’
tunnel hop limit 60
inet 192.168.192.131 –> 192.168.192.68 netmask ffffffc0

to this:

ip.tun0: flags=11028d1 mtu 1480 index 9
inet tunnel src 172.16.124.38 tunnel dst 172.16.3.139
tunnel hop limit 60
inet 192.168.192.131 –> 192.168.192.68 netmask ffffffc0

Note that the “tunnel security settings” went away.  I did not notice this until I rebooted one of the servers the next morning.  I had the tunnels sending (unecrypted) traffic between the hosts and the next day it was broken again.  The takeaway of this is make sure the ifconfig has tunnel security settings in the output.

ike/config

When setting up the IPsec tunnel, Sun recommends you use IKE to handle key management.  To make my setup easier, I followed the How to Configure IKE With Preshared Keys.  The document had me setup the /etc/inet/ike/config file with these contents:

{ label “myhost-remotehost”
local_addr 172.16.124.38
remote_addr 172.16.3.139
p1_xform
{ auth_method preshared oakley_group 5 auth_alg sha1 encr_alg aes }
p2_pfs 5
}

But in the previous document (IPsec), they have you setup the ipsecinit.conf file with this:

{tunnel ip.tun0 negotiate tunnel} ipsec {encr_algs aes encr_auth_algs sha1 sa shared}

The problem is that the encryption and authentication algorithms must match between IPsec and IKE.  I had to change the ipsecinit.conf file to be this:

{tunnel ip.tun1 negotiate tunnel} ipsec {encr_algs aes auth_algs sha1 sa shared}

I  could then get IKE exchanging keys between the two servers.  The IKE documentation does not seem to support using encr_auth_algs.

Firewalls

Something that was not covered in the documents was exactly what ports you need to open up to allow the connections to work.  Through trial and error, these are the rules I needed to add to my IPFilter config file:

pass in quick on ce0 proto udp from 172.16.3.139 port = 500 to 172.16.124.38 port = 500 keep state group 102
pass in quick on ce0 proto ipip from 172.16.3.139 to 172.16.124.38 keep state group 100
pass in quick on ce0 proto esp from 172.16.3.139 to 172.16.124.38 keep state group 100
pass in quick on ce0 proto ah from 172.16.3.139 to 172.16.124.38 keep state group 100
pass out quick on ce0 proto udp from 172.16.124.38 port = 500 to 172.16.3.139 port = 500 keep state group 152
pass out quick on ce0 proto ipip from 172.16.124.38 to 172.16.3.139 keep state group 150
pass out quick on ce0 proto esp from 172.16.124.38 to 172.16.3.139 keep state group 150
pass out quick on ce0 proto ah from 172.16.124.38 to 172.16.3.139 keep state group 150

The UDP port 500 traffic is the IKE daemon (in.iked) talking between the two hosts.  The “ipip” is for tunnel IP traffic (even unencrypted), the “ah” is for the authentication header packets and “esp” is for the encapuslated security payloads (the encrypted packets).

Zones

At this point, I have a working tunnel that most machines can use between the data centers, the one major exception is the non global zones (NGZs) on the v490s themselves.  After opening a support call with Sun and spending many weeks on this, they came back to say tunnels are not supported in the NGZs.  The functionallity will not be available until Solaris 11 and is provided by RFEs CR 6218826 – need to be able to tunnel into a zone and CR 6858533 – Clearview IP Tunneling.

Conclusion

You can use Solaris 10 Zones or IP Tunnels on a machine, but not both.  Back to the drawing board to set up extra servers just to run the IPsec tunnel.