[strongSwan-dev] strongSwan IPsec support for Open vSwitch

Ansis Atteka ansisatteka at gmail.com
Wed Feb 13 22:19:55 CET 2013


We are considering to switch our Open vSwtich IPsec daemon underlying
implementation from racoon to strongSwan. But before doing that, there
are few limitations that we have to overcome.

Since StrongSwan's ikev2 does not support IPsec transport mode, we had
to switch to IPsec tunnel mode. To keep things *transparent* we had to
add two iptables rules from the updown script on the peer behind the


# We assume that IN mark is equal to OUT mark. We NAT&encrypt only
packets where mark=1
NF_MARK_MATCH="-m mark --mark $PLUTO_MARK_OUT"

case "$PLUTO_VERB" in
	# These rules are installed only when IPsec packets are NATed. And only
	# on the peer who is behind the NAT.
	iptables -A PREROUTING  -t nat $NF_MATCH_IN -j DNAT \
			--to-destination $PLUTO_ME
	iptables -A POSTROUTING -t nat $NF_MATCH_OUT -j SNAT \
			--to-source $MY_FIREWALLED_IP
	conntrack -D -d $PLUTO_PEER
	iptables -D PREROUTING  -t nat $NF_MATCH_IN  -j DNAT \
			--to-destination $PLUTO_ME
	iptables -D POSTROUTING -t nat $NF_MATCH_OUT -j SNAT \
			--to-source $MY_FIREWALLED_IP
	conntrack -D -d $PLUTO_PEER
*)	echo "unknown action $PLUTO_VERB"
	exit 1

Basically these two iptables rules on the peer behind the NAT would
DNAT incoming packets to the $PLUTO_ME and SNAT outgoing packets to
$PLUTO_MY_CLIENT. IPsec policies are purely based on netfilter marks
and they work as expected (e.g. mark=1 means encrypt packet; othewise
don't encrypt).

The problem I am facing is netfilter/conntrack statefullness with NAT.
Imagine that our Open vSwitch kernel module sends out:
1. GRE packet with mark=0; source IP address $PLUTO_ME; destination IP
address $PLUTO_PEER; Then we would expect that this packet shouldn't
be SNATed and should bypass IPsec tunnel.
2. GRE packet with mark=1; source IP address $PLUTO_ME; destination IP
address $PLUTO_PEER; Then we would expect that this packet should be
SNATed and should enter IPsec tunnel.

The first packet that would be sent from the kernel module would
create a conntrack entry. Unfortunately this entry would get into way
for the second [ipsec_]gre tunnel and NAT wouldn't work as expected
(either NAT would happen when not desired or wouldn't happen when

Any ideas how to solve this problem and allow gre and ipsec_gre
tunnels to coexist by fixing this NAT issue?

Few solutions that come into my mind:
1. somehow get IPsec transport mode to work with ikev2 (this has
already been discussed in strongswan's mailinglist; But my
understanding is that this isn't implemented with ikev2)
2. somehow make iptables to do stateless NAT (google tells me that
this is not supported with iptables)
3. make netfilter capable to distuinguish between these two conntrack
NAT entries by using netfilter marks (unfortunately it seems that
nf_conntrack_tuple in linux kernel does not include mark?)
4. create a new dedicated kernel module that does stateless NAT by
using netfilter hooks (I haven't investigated this solution in
details, but this seems like a lot of work)

*I know that this should be rather asked in Netfilter mailinglist, but
I was wondering, if anyone from strongswan community has already
solved a similar issue?

Thanks in advance,
Ansis Atteka

More information about the Dev mailing list