IPSEC L2TP VPN on Ubuntu 12.04 with OpenSwan, xl2tpd and ppp

01-12-2014 | Remy van Elst

Table of Contents

This is a guide on setting up a IPSEC/L2TP vpn on Ubuntu 12.04 using Openswan as the IPsec server, xl2tpd as the l2tp provider and ppp for authentication. We choose the IPSEC/L2TP protocol stack because of recent vulnerabilities found in pptpd VPN's.

This tutorial is available for the following platforms:

This tutorial was written and tested on a Digital Ocean VPS. If you like this tutorial and want to support my website, use this link to order a Digital Ocean VPS: https://www.digitalocean.com/?refcode=7435ae6b8212. You will get $10 free credit, which is equal to two months of a free $5 VPS.

IPSec encrypts your IP packets to provide encryption and authentication, so no one can decrypt or forge data between your clients and your server. L2TP provides a tunnel to send data. It does not provide encryption and authentication though, that is why we need to use it together with IPSec.

To work trough this tutorial you should have:

  • 1 ubuntu 12.04 server with at least 1 public IP address and root access
  • 1 (or more) clients running an OS that support IPsec/L2tp vpn's (Ubuntu, Mac OS, Windows, Android).
  • Ports 1701 TCP, 4500 UDP and 500 UDP opened in the firewall.

If you are not running Ubuntu 12.04 you might have to compile the packages manually because openswan and xl2tpd in the older repositories seem to have critical bugs which make this all fail.

I do all the steps as the root user. You should do to, but only via * -i* or * su -*. Do not allow root to login via SSH!

Install ppp openswan and xl2tpd

First we will install the required packages:

 apt-get install openswan xl2tpd ppp 

The openswan installation will ask some questions, this tutorial works with the default answers (just enter through it).

If you do not have lsof installed you also need to install that, otherwise the ipsec verify will fail:

 apt-get install lsof

Firewall and sysctl

We are going to set the firewall and make sure the kernel forwards IP packets:

Execute this command to enable the iptables firewall to allow the vpn:

iptables --table nat --append POSTROUTING --jump MASQUERADE

Execute the below commands to enable kernel IP packet forwarding and disable ICP redirects.

echo "net.ipv4.ip_forward = 1" |  tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.accept_redirects = 0" |  tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.send_redirects = 0" |  tee -a /etc/sysctl.conf
for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
 sysctl -p

To make sure this keeps working at boot you might want to add the following to /etc/rc.local:

for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
iptables --table nat --append POSTROUTING --jump MASQUERADE

There are better ways to do this (via sysctl.conf and ufw for example) but this is something that just works.

Configure Openswan (IPSEC)

Use your favorite editor to edit the following file:


Below is the contents of mine. Most lines have a comment below it explaining what it does.

config setup
    #in what directory should things started by setup (notably the Pluto daemon) be allowed to dump core?
    #whether to accept/offer to support NAT (NAPT, also known as "IP Masqurade") workaround for IPsec
    #contains the networks that are allowed as subnet= for the remote client. In other words, the address ranges that may live behind a NAT router through which a client connects.
    #decide which protocol stack is going to be used.


conn L2TP-PSK-noNAT
    #shared secret. Use rsasig for certificates.
    #Disable pfs
    #start at boot
    #Only negotiate a conn. 3 times.
    #because we use l2tp as tunnel protocol
    #fill in server IP above

**Make sure there is a blank line at the bottom of the /etc/ipsec.conf file. This is because of bug #1370 in OpenSwan. Note that their bugtracker was moved so this link now points to the general bugtracker.

The shared secret

The shared secret is defined in the /etc/ipsec.secrets file. Make sure it is long and random:

%SERVERIP%  %any:   PSK "69EA16F2C5DCED8B29E74A7D1B0FE99E69F6BDCD3E44"

Now to make sure IPSEC works, execute the following command:

 ipsec verify

My output looks like this:

Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path                                 [OK]
Linux Openswan U2.6.37/K3.2.0-29-generic-pae (netkey)
Checking for IPsec support in kernel                            [OK]
 SAref kernel support                                           [N/A]
 NETKEY:  Testing XFRM related proc values                      [OK]
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            [OK]
Checking NAT and MASQUERADEing                                  [OK]
Checking for 'ip' command                                       [OK]
Checking /bin/sh is not /bin/dash                               [WARNING]
Checking for 'iptables' command                                 [OK]
Opportunistic Encryption Support                                [DISABLED]

The /bin/sh and Opportunistic Encryption warnings can be ignored. The first one is a openswan bug and the second doesn't matter.

Configure xl2tpd

Use your favorite editor to edit the following file:


Below is the contents of mine. Most lines have a comment below it explaining what it does.

ipsec saref = yes

[lns default]
ip range =
local ip =
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
  • ip range = range of IP's to give to the connecting clients
  • local ip = IP of VPN server
  • refuse pap = refure pap authentication
  • ppp debug = yes when testing, no when in production

Local user (PAM//etc/passwd) authentication

To use local user accounts via pam (or /etc/passwd), and thus not having plain text user passwords in a text file you have to do a few extra steps. Huge thanks to Sascha Scandella for the hard work and troubleshooting.

In your /etc/xl2tpd/xl2tpd.conf add the following line:

unix authentication = yes

and remove the following line:

refuse pap = yes

In the file /etc/ppp/options.xl2tpd make sure you do not add the following line (below it states to add it, but not if you want to use UNIX authentication):


Also in that file (/etc/ppp/options.xl2tpd) add the following extra line:


Change /etc/pam.d/ppp to this:

auth    required        pam_nologin.so
auth    required        pam_unix.so
account required        pam_unix.so
session required        pam_unix.so

Add the following to /etc/ppp/pap-secrets:

*       l2tpd           ""              *

(And, skip the chap-secrets file below (adding users).)

Configuring PPP

Use your favorite editor to edit the following file:


Below is the contents of mine. Most lines have a comment below it explaining what it does.

mtu 1200
mru 1000
name l2tpd
lcp-echo-interval 30
lcp-echo-failure 4
  • ms-dns = The dns to give to the client. I use google's public DNS.
  • proxyarp = Add an entry to this system's ARP [Address Resolution Protocol] table with the IP address of the peer and the Ethernet address of this system. This will have the effect of making the peer appear to other systems to be on the local ethernet.
  • name l2tpd = is used in the ppp authentication file.

Adding users

Every user should be defined in the /etc/ppp/chap-secrets file. Below is an example file.

# Secrets for authentication using CHAP
# client       server  secret                  IP addresses
alice          l2tpd   0F92E5FC2414101EA            *
bob            l2tpd   DF98F09F74C06A2F             *
  • client = username for the user
  • server = the name we define in the ppp.options file for xl2tpd
  • secret = password for the user
  • IP Address = leave to * for any address or define addresses from were a user can login.

Testing it

To make sure everything has the newest config files restart openswan and xl2tpd:

/etc/init.d/ipsec restart;  /etc/init.d/xl2tpd restart

On the client connect to the server IP address (or add a DNS name) with a valid user, password and the shared secret. Test if you have internet access and which IP you have (via for example whatsmyip.org. ). If it is the VPN servers IP then it works.

Another nice test is to connect multiple clients of which one has a webserver. Make sure it only listens on a VPN IP (172.16.1.xxx in above example). Test if you can access it only via the VPN. You now have a "secret" webserver.

If you experience problems make sure to check the client log files and the ubuntu /var/log/syslog file. If you google the error messages you most of the time get a good answer.

Tags: debian,ipsec,l2tp,openvpn,pptp,ubuntu,vpn,