Thursday, November 1, 2012

connecting to osx using l2tp/ipsec from linux

recently i needed to connect to a network using L2TP/IPSec from my linux laptop. to be honest, i think l2tp/ipsec is a stack of crap. there are actually 3 levels of protocols involved: ppp/l2tp/ipsec. it's truly horrible and seems a bit daunting to setup. tragically when i tried to use the automatic setup tools, like network manager, they all failed miserably with some cryptic error.

so i started with the basics and debugged up the stack. fortunately, in the end i did some pair debugging (thanx saleem!)

i found that when i went step by step it slowly came together.

step 1: setup ipsec

i'm using racoon for the ipsec key exchange server, so first i need to configure that. we start with /etc/racoon/racoon.conf:

path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";

padding {
        maximum_length 20;
        randomize off;
        strict_check off;
        exclusive_tail off;
remote VPNIP {
        exchange_mode main,base;
        nat_traversal on;
        dpd_delay 10;
        proposal {
                encryption_algorithm 3des;
                hash_algorithm sha1;
                authentication_method pre_shared_key;
                dh_group 2;

sainfo anonymous address VPNIP udp {
        encryption_algorithm aes128;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate;
        lifetime time 60 minutes;
VPNIP is the ip address of your vpn server. this file simply sets up the key exchange parameters. one key parameter (that killed a couple of hours of debugging) is the nat_traversal which signals ipsec to do the encapsulation properly.

now we need to setup the preshared secret in /etc/racoon/psk.txt:
now that racoon is configured, we just need to setup the policy for ipsec to kick in. we will write a simple shell script

setkey -c <<EOF


spdadd VPNIP[1701] udp -P in ipsec esp/transport//require;
spdadd VPNIP[1701] udp -P out ipsec esp/transport//require;

this policy says to use ipsec if we are sending to port 1701 (l2tp) on VPNIP.

once we run ipsec will be setup and we will be ready to startup l2tp.

step 2 setup l2tp

l2tp is made up of two parts: the tunneling protocol and ppp running over that protocol. the tunneling protocol really doesn't do much. it's not even authenticated. here is the /etc/xl2tpd/xl2tpd.conf:
ipsec saref = yes

[lac vpn]
lns = VPNIP
pppoptfile = /etc/ppp/options.l2tpd.client
redial timeout = 5
again there isn't really much here. the [lac vpn] line indicates that we are going to be initiating the connection to the l2tp server. vpn is the name of the connection. we will use this to actually make the connection.

the real work of actually handling the network traffic is done by ppp. we configure that in /etc/ppp/options.l2tpd.client:
password PASSWORD
make sure to replace USERID and PASSWORD with your user id and password. the first two lines are going to configure our local ip address for the tunnel. unfortunately it doesn't setup the route correctly. (it seems like it should... more investigation needed.) for now we will do it manually in the final step.

step 3: pull it all together

now that we have all the configuration files lets enhance the script to start everything up:

setkey -c <<EOF


spdadd VPNIP[1701] udp -P in ipsec esp/transport//require;
spdadd VPNIP[1701] udp -P out ipsec esp/transport//require;


xl2tpd-control connect om
while [ ! -d /proc/sys/net/ipv4/conf/ppp0 ]
        echo waiting on l2tp
        sleep 1

sleep 1

route add -net NETWORK ppp0


btw, if you need to debug you can turn on ppp and racoon debugging in the config files. turning on debugging on the server side also helps greatly! wireshark and tcpdump are your friends!

this really is just a hack. i still want to figure out how to get the network route to self configure. i also would like to figure out how keep the credentials in a more secure store.

No comments:

Post a Comment