[Openswan dev] routed based vpn with openswan

Paul Wouters paul at xelerance.com
Sun Feb 20 21:32:49 EST 2011

I guess we should see if we can accomodate this better, as it is sadly
very common for those type of "vpn" tunnels.


---------- Forwarded message ----------
Date: Mon, 21 Feb 2011 03:05:07 +0100
From: Jacques Caruso <jacques at caruso.bz>
To: users at openswan.org
Subject: Re: [Openswan Users] Route based VPN

Ainsi parla Andrew Nowrot <andrew.nowrot at gmail.com>, le 15 February de l'an de
grâce 2011 :
> I need to set up two ipsec tunnels to one provider, in the
> requirements they said that it has to work in route-based mode where
> local-proxy id and remote-proxy id should be unset (both parameters
> should have

Well, I just wondered how to do that myself, and I may have a partial

> I tried to do this as I normally do, but then they told my that I am
> using policy based VPN and proxy-id on their Juniper NetScreen does
> not match.

Hmmm. Haven't got any Juniper hardware around here, but I tried with a
Cisco configured with an IPsec VTI, and got positive results. I guess
the Juniper stuff should work as well...

> How can I do this with openswan? I am using Openswan-2.6.31 with
> KLIPS. Is it possible to configure Openswan to work in route-based
> mode? If so how can I do this?

The good news is that it looks indeed possible. The bad news is, it
won't work out of the box. The main issues are:

   1. OpenS/WAN apparently cannot grok the idea that the ipsecX device
      may have a different IP address than the underlying interface
   2. The left and right subnets need to be set to for a
      route-based VPN, and if you do so, the _updown.klips script will
      happily mangle your default route :-(

The solution I've found works but is a bit convoluted. I'll outline the
required steps for a VPN with the following settings, change them to
suit your environment:

^ Setting          ^ Left (Linux + OpenS/WAN)  ^ Right (Cisco router)  ^
| Public IP        | (eth0)         |         |
| LAN IP           |           |       |
| Tunnel endpoint  |        |    |

First, you need to copy the /usr/lib/ipsec/_updown* files to
/usr/local/lib/ipsec, then apply the patches at the end of this message
to these copies. Please note that the patches assume a Debian-like
distro, if you're using something else, the necessary adaptations are up
to you. Also, please note these patches are a total hack, and I
certainly do not vouch for their correctness. The only thing I can say
is, they appear to work for me. YMMV.

In a nutshell, what the patch does is remove all addresses and routes
from the ipsec0 device, and call the ifupdown scripts on ipsec0 when the
tunnel is set up or removed. This ensures that you can configure the
right addresses and routes in your distro's configuration and have them
correctly applied. The doroute() function is skipped altogether to avoid
the default route getting overridden (which can be *extremely* annoying
if the box isn't on the premises).

When the files have been patched, you can add the necessary
configuration for ipsec0 to your /etc/network/interfaces:

iface ipsec0 inet static
         up ip route add via
         down ip route del via

And then, you can configure the VPN. Your /etc/ipsec.conf should look
somewhat like this (irrelevant settings omitted):

config setup

conn foobar

Restart OpenS/WAN, ipsec0 should be down and unnumbered:

# service ipsec restart
ipsec_setup: Stopping Openswan IPsec...
ipsec_setup: Starting Openswan IPsec 2.6.28...
# ip addr show ipsec0
4: ipsec0: <NOARP> mtu 16260 qdisc pfifo_fast state DOWN qlen 10
     link/ether 22:82:84:71:7e:bb brd ff:ff:ff:ff:ff:ff

Start the foobar tunnel, ipsec0 should now have an IP address, and the
route to the other LAN should be present:

# ipsec auto --up foobar | tail -n 1
004 "foobar" #2: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0xe34cba4e <0x0bf6e23e xfrm=3DES_0-HMAC_MD5 NATOA=none NATD=none DPD=none}
# ip route show | grep ipsec0 dev ipsec0  proto kernel  scope link  src via dev ipsec0
# ping -I -c 5 | tail -n 2 | head -n 1
5 packets transmitted, 5 received, 0% packet loss, time 4037ms

If this works, you can go ahead and change auto=route to auto=start in
your ipsec.conf.

The patches I used are reproduced below, while we wait for an official

====[ _updown.patch ]====
--- /usr/lib/ipsec/_updown	2010-12-24 10:39:03.000000000 +0100
+++ /usr/local/lib/ipsec/_updown	2011-01-31 02:50:56.000000000 +0100
@@ -128,11 +128,11 @@
      2.*) ;;

-if [ -x /usr/lib/ipsec/_updown.${PLUTO_STACK} ]
+if [ -x /usr/local/lib/ipsec/_updown.${PLUTO_STACK} ]
-	exec /usr/lib/ipsec/_updown.${PLUTO_STACK} $*
+	exec /usr/local/lib/ipsec/_updown.${PLUTO_STACK} $*
-	echo "FATAL: Could not execute /usr/lib/ipsec/_updown.${PLUTO_STACK} $*"
+	echo "FATAL: Could not execute /usr/local/lib/ipsec/_updown.${PLUTO_STACK} $*"

  exit 3;
====[ _updown.patch ]====

====[ _updown.klips.patch ]====
--- /usr/lib/ipsec/_updown.klips	2010-12-24 10:39:03.000000000 +0100
+++ /usr/local/lib/ipsec/_updown.klips	2011-02-21 02:37:15.000000000 +0100
@@ -499,9 +499,26 @@
  	return $st
+fixifparams() {
+	# Remove wrong parameters set by OpenS/WAN
+	ROUTES=`ip route show | grep $PLUTO_INTERFACE`
+	echo $ROUTES | while read R; do if [ "$R" != "" ]; then ip route del $R; fi; done
+	ADDRS=`ip addr show $PLUTO_INTERFACE | grep inet | grep -v 'inet6 fe80' | sed -r 's/.*inet //' | cut -d' ' -f1`
+	echo $ADDRS | while read A; do ip addr del $A dev $PLUTO_INTERFACE; done
+	ip link set $PLUTO_INTERFACE down

+ifctl() {
+	if [ "$1" = "add" ]; then
+	else
+		ifdown --force $PLUTO_INTERFACE
+	fi

  # the big choice
+CONFIGURED=`cat /etc/network/interfaces | grep $PLUTO_INTERFACE`
  case "$PLUTO_VERB:$1" in
  	# delete possibly-existing route (preliminary to adding a route)
@@ -541,15 +558,22 @@
  		echo "$0: \`$it' failed ($oops)" >&2
+if [ "$CONFIGURED" != "" ]; then
+	fixifparams
  	exit $status
  	# connection to me or my client subnet being routed
+if [ "$CONFIGURED" = "" ]; then
  	# connection to me or my client subnet being unrouted
+if [ "$CONFIGURED" = "" ]; then
  	# connection to me coming up
@@ -563,12 +587,20 @@
  	# connection to my client subnet coming up
+if [ "$CONFIGURED" = "" ]; then
+	ifctl add
  	# If you are doing a custom version, firewall commands go here.
  	# connection to my client subnet going down
+if [ "$CONFIGURED" = "" ]; then
+	ifctl delete
  	# If you are doing a custom version, firewall commands go here.
====[ _updown.klips.patch ]====

    Jacques Caruso |    Administrateur système    | Laissez-vous pousser
jacques at caruso.bz |   Webmaster, jeuxdroles.org  | les dents. Ne marchez
(+33) 493 574 815 | Membre des Minotaures du Sud | pas sur les opossums.
  PGP : 0xC04BC266 |     Membre de Linux-Azur     | Mangez des kiwis.
Users at openswan.org
Micropayments: https://flattr.com/thing/38387/IPsec-for-Linux-made-easy
Building and Integrating Virtual Private Networks with Openswan:

More information about the Dev mailing list