[Openswan Users] Route based VPN
Jacques Caruso
jacques at caruso.bz
Sun Feb 20 21:05:07 EST 2011
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 0.0.0.0/0).
Well, I just wondered how to do that myself, and I may have a partial
answer.
> 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 0.0.0.0/0 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 | 192.0.2.42 (eth0) | 198.51.100.11 |
| LAN IP | 10.42.40.254/24 | 10.42.20.254/24 |
| Tunnel endpoint | 169.254.253.249/30 | 169.254.253.250/30 |
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
address 169.254.253.249
netmask 255.255.255.252
up ip route add 10.42.20.0/24 via 169.254.253.250
down ip route del 10.42.20.0/24 via 169.254.253.250
And then, you can configure the VPN. Your /etc/ipsec.conf should look
somewhat like this (irrelevant settings omitted):
config setup
protostack=klips
interfaces="ipsec0=eth0"
conn foobar
left=192.0.2.42
leftsubnet=0.0.0.0/0
leftupdown=/usr/local/lib/ipsec/_updown
right=198.51.100.11
rightsubnet=0.0.0.0/0
auto=route
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
169.254.253.248/30 dev ipsec0 proto kernel scope link src 169.254.253.249
10.42.20.0/24 via 169.254.253.250 dev ipsec0
# ping -I 10.42.40.254 -c 5 10.42.20.254 | 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
solution:
====[ _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.*) ;;
esac
-if [ -x /usr/lib/ipsec/_updown.${PLUTO_STACK} ]
+if [ -x /usr/local/lib/ipsec/_updown.${PLUTO_STACK} ]
then
- exec /usr/lib/ipsec/_updown.${PLUTO_STACK} $*
+ exec /usr/local/lib/ipsec/_updown.${PLUTO_STACK} $*
else
- echo "FATAL: Could not execute /usr/lib/ipsec/_updown.${PLUTO_STACK} $*"
+ echo "FATAL: Could not execute /usr/local/lib/ipsec/_updown.${PLUTO_STACK} $*"
fi
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 @@
fi
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
+ ifup $PLUTO_INTERFACE
+ else
+ ifdown --force $PLUTO_INTERFACE
+ fi
+}
# the big choice
+CONFIGURED=`cat /etc/network/interfaces | grep $PLUTO_INTERFACE`
case "$PLUTO_VERB:$1" in
prepare-host:*|prepare-client:*)
# delete possibly-existing route (preliminary to adding a route)
@@ -541,15 +558,22 @@
then
echo "$0: \`$it' failed ($oops)" >&2
fi
+if [ "$CONFIGURED" != "" ]; then
+ fixifparams
+fi
exit $status
;;
route-host:*|route-client:*)
# connection to me or my client subnet being routed
+if [ "$CONFIGURED" = "" ]; then
uproute
+fi
;;
unroute-host:*|unroute-client:*)
# connection to me or my client subnet being unrouted
+if [ "$CONFIGURED" = "" ]; then
downroute
+fi
;;
up-host:*)
# connection to me coming up
@@ -563,12 +587,20 @@
;;
up-client:)
# connection to my client subnet coming up
+if [ "$CONFIGURED" = "" ]; then
uprule
+else
+ ifctl add
+fi
# If you are doing a custom version, firewall commands go here.
;;
down-client:)
# connection to my client subnet going down
+if [ "$CONFIGURED" = "" ]; then
downrule
+else
+ ifctl delete
+fi
# If you are doing a custom version, firewall commands go here.
;;
updateresolvconf-host|updateresolvconf-client)
====[ _updown.klips.patch ]====
Regards,
--
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.
More information about the Users
mailing list