Openswan – Use The KLIPS stack

Openswan is a very good IPSec VPN software available on Linux.
It supports two protocol stacks, the native NETKEY and KLIPS. Many Linux distribution kernel contains support for NETKEY (with NAT Tranversal), and building a klips module is quite easy(However, if you want NAT-T support, you must patch and rebuild your kernel if your kernel version is less than 2.6.23).

In the idial case, switch from netkey to klips would require no change to the configuration, because in the default setup, protostack=auto, which whill use klips if available, fall back to netkey if not. However, such an “ideal case” trapped me a whole night, sleepless!

Here’s the story.

++++++++++++++network diagram+++++++++++++++++++++

hostA( ---->GW(,no NAT,>

ipsec.conf of hostA

version 2.0 
config setup
conn tklips

ipsec.conf of hostB

version 2.0 
config setup
conn tklips

After bring up the tunnel, a traceroute tells me everything goes fine.

root@hosA: # traceroute
traceroute to (, 30 hops max, 40 byte packets
 1 (  18.820 ms  19.484 ms  19.291 ms

A little satisfied, I started build the klips module, then load it with modprobe, and restart ipsec service. and run ipsec verify to check if it’s OK.

ipsec verify
Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path                                 [OK]
Linux Openswan 2.6.31 (klips)
Checking for IPsec support in kernel                            [OK]
KLIPS detected, checking for NAT Traversal support              [OK]
SAref kernel support                                            [N/A]
Checking that pluto is running                                  [OK]
Pluto listening for IKE on udp 500                              [OK]
Pluto listening for NAT-T on udp 4500                           [OK]
Two or more interfaces found, checking IP forwarding            [FAILED]
Checking for 'ip' command                                       [OK]
Checking for 'iptables' command                                 [OK]
Opportunistic Encryption Support                                [DISABLED]

Seems OK, then check if the tunnel is up

# psec auto --status
000 using kernel interface: mast
000 interface mast0/eth0
000 interface mast0/eth0
000 %myid = (none)
000 debug none
000 virtual_private (%priv):
000 - allowed 0 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=3, name=ESP_3DES, ivlen=64, keysizemin=192, keysizemax=192
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 algorithm IKE encrypt: id=3, name=OAKLEY_BLOWFISH_CBC, blocksize=8, keydeflen=128
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 encrypt: id=65004, name=OAKLEY_SERPENT_CBC, blocksize=16, keydeflen=128
000 algorithm IKE encrypt: id=65005, name=OAKLEY_TWOFISH_CBC, blocksize=16, keydeflen=128
000 algorithm IKE encrypt: id=65289, name=OAKLEY_TWOFISH_CBC_SSH, 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 hash: id=4, name=OAKLEY_SHA2_256, hashsize=32
000 algorithm IKE hash: id=6, name=OAKLEY_SHA2_512, hashsize=64
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 stats db_ops: {curr_cnt, total_cnt, maxsz} :context={0,0,0} trans={0,0,0} attrs={0,0,0}
000 "tklips":<>[+S=C]...<>[+S=C]; erouted; eroute owner: #2
000 "tklips":     myip=unset; hisip=unset;
000 "tklips":   ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0
000 "tklips":   policy: RSASIG+ENCRYPT+TUNNEL+PFS+UP+IKEv2ALLOW; prio: 32,32; interface: eth0;
000 "tklips":   newest ISAKMP SA: #1; newest IPsec SA: #2;
000 "tklips":   IKE algorithm newest: AES_CBC_128-SHA1-MODP2048
000 #2: "tklips":500 STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 27778s; newest IPSEC; eroute owner; isakmp#1; idle; import:admin initiate
000 #2: "tklips" esp.8d3f82a5@ esp.1e9dd485@ tun.1001@ tun.1002@ ref=3 refhim=1
000 #1: "tklips":500 STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 2548s; newest ISAKMP; lastdpd=-1s(seq in:0 out:0); idle; import:admin initiate

Well, the “ISAKMP SA established” line told me that the tunnel is up. I was glad, drop a ping from hostA to hostB…. Squirrel! No respone! What’s wrong!

root@hostB: # ipsec eroute
# oops. nothing output

Then I did a tcpdum on ipsec0 interface of hostB, I can see packet from hostA, but it didn’t reply to that. Then I went crazy, asked the question on openswan mail list, no one come to help(maybe they were all busy ^_^), and then googling and testing and googling and testing… still no luck. At 6:00 am, my sight blur…

After 3 hours of sleep, I feel better. open a book on Openswan, the following content come to my rescue.

While you are editing /etc/sysctl.conf, it is also a good idea to disable net.ipv4.conf. default.rp_filter by setting it to 0. The rp_filter setting controls the built-in spoof protection of the Linux kernel. It is a very simplistic protection that discards packets that appear to have arrived at the machine from the wrong network device, as is the case in some IP spoofing attacks. However, when using KLIPS, the packets suddenly appear from ipsec0, while rp_filter deems they should have come in on the external physical interface (for instance eth0) and concludes these packets are spoofed and the Linux kernel will thus drop them. Openswan used to warn about rp_filter when running the ipsec verify command, but this test has been removed in more recent versions because Openswan will just detect and disable rp_filter automatically.

then I disable the rp_filter

for i in /proc/sys/net/ipv4/*/rp_filter; do echo 0 > $i; done

and change protostack=auto to protostack=klips in ipsec.conf ( I can’t remember how did I find that change this will cause ipsec eroute to show up). restart ipsec. Wow! I made it!


when switch to klips, remember to:
1. disable rp_filter, enable ip_forward
2. set protostack=klips explicitly.

This entry was posted in System Administration, VPN and tagged , , . Bookmark the permalink.

One Response to Openswan – Use The KLIPS stack

  1. Pingback: openswan / openvpn tunnel between 4 ubuntu servers

Leave a Reply