How to Connect to L2TP/IPsec VPN on Linux

In this tutorial, we’ll learn how to connect a Linux workstation to a Linux or Windows L2TP/IPsec VPN server running on ElasticHosts. To do this, we’ll be using Openswan and the Layer 2 Tunneling Protocol daemon, xl2tpd. Windows users can find a tutorial on how to connect to an IPsec VPN using Windows here.

Step 1: Initial setup

The steps in this tutorial have been written specifically for Ubuntu, but should be similar for other versions of Linux or BSDs. Besides common distribution-specific details such as the use of apt as a package manager, the only clear difference we have found between Linux distributions is in the name of the Openswan binary. This may be ipsec on Debian and related distributions (including Ubuntu) or openswan, for example.

We will be performing privileged operations, and therefore recommend running all the commands below as root, or using sudo. We will start by installing the required packages.

$ apt-get update
$ apt-get install openswan xl2tpd

Step 2: Configure IPsec

In order to configure IPsec, you will need to know three things:

  • The IP address of the VPN server to which you will be connecting.
  • A preshared key to connect to the server, also referred to as a PSK or shared secret. Alternatively, you may have been provided with a certificate or RSA key.
  • A username and password for CHAP authentication. If you are connecting to a Windows server, these will be the username and password of your Windows user account on the remote machine.

Armed with these, open the main Openswan configuration file using your text editor of choice.

$ nano /etc/ipsec.conf
config setup  
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12  
nat_traversal=yes  
protostack=netkey  
oe=off  
plutoopts=“--interface=eth0”  
conn L2TP-PSK  
authby=secret  
pfs=no  
auto=add  
keyingtries=3  
dpddelay=30  
dpdtimeout=120  
dpdaction=clear  
rekey=yes  
ikelifetime=8h  
keylife=1h  
type=transport  
left=%defaultroute  
leftnexthop=%defaultroute  
leftprotoport=17/1701  
right=****  

If you followed our tutorial to build a Linux VPN server, much of this will look familiar. Here are a few points of interest, however:

  • plutoopts=“–interface=eth0 – This tells Openswan’s Pluto engine which network interface you will be using. You can see available interfaces by running the command ip address show if you’re not sure which to use: for example, wireless users may find they need to replace eth0 with wlan0.
  • The authby keyword allows you to set the authentication type we will be using. For this tutorial we will be using secret for shared secret or PSK authentication, but if you have been provided with a certificate or RSA key you will want to use rsasig. For more information read man 5 ipsec.conf.
  • left and right refer to the client and server respectively. Here, we set left to %defaultroute, allowing you to connect from any IP address. right is the IP address of the VPN server.

Next, we must configure the authentication.

$ nano /etc/ipsec.secrets
0.0.0.0: **** PSK **“Your PSK”**  

This breaks down as left IP, right IP, PSK. If you are using a different form of authentication, you may wish to read man 5 ipsec.secrets. 0.0.0.0 is a reserved IP address which we’re using here to mean “any IP address”. We could use a static IP address here, but this is useful because many users’ IPs are prone to change, and it saves us editing this file each time we want to use the connection. That’s the IPsec part of the connection finished – if you would like, you can now test that this works by running:

$ /etc/init.d/ipsec start
$ ipsec auto --up L2TP-PSK

You should see some output telling you that a connection has been successfully negotiated. For now, we will stop Openswan again and continue with our setup.

$ /etc/init.d/ipsec stop

Step 3: Configure L2TP

Next, we must configure xl2tpd.

$ nano /etc/xl2tpd/xl2tpd.conf
[lac vpn-connection]
lns = ****  
refuse chap = yes  
refuse pap = yes  
require authentication = yes  
name = vpn-server  
ppp debug = yes  
pppoptfile = /etc/ppp/options.l2tpd.client  
length bit = yes  

Now open the PPP options file we have just defined.

$ nano /etc/ppp/options.l2tpd.client
ipcp-accept-local  
ipcp-accept-remote  
refuse-eap  
require-mschap-v2  
noccp  
noauth  
idle 1800  
mtu 1410  
mru 1410  
defaultroute  
usepeerdns  
debug  
lock  
connect-delay 5000  
name ****  
password ****  

We’re almost done – let’s start the connection, and configure our routing information.

Step 4: Connect to the VPN

To start the tunnel, we need to run three commands.

$ /etc/init.d/ipsec start
$ /etc/init.d/xl2tpd start
$ ipsec auto --up L2TP-PSK
$ echo "c vpn-connection" > /var/run/xl2tpd/l2tp-control
  • The first two commands start Openswan and xl2tpd respectively.
  • ipsec auto –up L2TP-PSK – This starts the IPsec connection. L2TP-PSK refers the name for the connection that we set in /etc/ipsec.conf
  • echo “c vpn-connection” > /var/run/xl2tpd/l2tp-control – This is a control setting, which tells xl2tpd to start the tunnel.

You can check that the tunnel has started by running ip address show: if all has worked correctly, you should see that a PPP network device has been created. This is usually named something like ppp0, and will have an IP address assigned from the range that the remote network is using. If you are using the VPN to connect to servers in your ElasticHosts VLAN, for example, this range will be in the same subnet as the internal addresses of machines on your VLAN.

All we need to do now is tell Linux to route traffic to this subnet over the VPN connection. For the purposes of this tutorial, we will assume that the remote subnet is 10.0.5.0/24 and the VPN server has an internal address of 10.0.5.1, as it was in our VPN server tutorials. It’s important to understand that the VPN server will be our remote gateway into this network.

$ ip route add 10.0.5.0/24 via 10.0.5.1

You can confirm that this has worked by running ip route show. The results should look something like this, where the first two entries are routing for the tunnel we have created, and the third is Linux’s normal default route:

10.0.5.0/24 via 10.0.5.1 dev ppp0  
10.0.5.1 dev ppp0 proto kernel scope link src 10.0.5.50  
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.2  

If you make a mistake, you can easily delete any route by running ip route delete with the same syntax. For example, to undo this last step the command would be ip route delete 10.0.5.0/24 via 10.0.5.1. If you have other machines attached over the remote VLAN, you should now be able to ping them.

Congratulations! The commands used in this section can be easily combined into a file and run as a script, to avoid repeating this process every time you want to connect. If that’s all you wanted to do, then this is the end of the tutorial. Otherwise, carry on to:

Step 5 (Optional): Route internet traffic over the VPN

In order to pass normal internet traffic through the remote server, we must run two more commands. If you’re not the administrator of the VPN server we recommend that you first check that you have been given permission to do this, or you may find that the remote server disallows it. To do this, we will make the VPN server our default gateway for all internet connections. But since we need to be able to reach it over the internet before that will work, we must first set an explicit route to the VPN server.

$ ip route add **** via ****

You can run ip route show default if you’re not sure of the gateway address. Finally, we set the new default route for all other locations to go through our VPN gateway:

$ ip route add default via 10.0.5.1 

Check that you have internet connection: you can use a utility such as mtr or traceroute to confirm that traffic is indeed being routed through the VPN server.