Linux L2TP/IPsec VPN Client

In this tutorial, we’ll learn how to connect a Linux workstation to a Linux or Windows L2TP/IPsec VPN server running on the Crosspeer Cloud.
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=<The IP address of your VPN Server>
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: <The IP address of your VPN Server> 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 = <The IP address of your VPN server>
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 <Your username for CHAP authentication (users connecting to a Windows VPN server should use their Windows username)>
password <Your CHAP secret (or Windows 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 Crosspeer Cloud 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 <the IP address of your VPN server> via <the IP address of your current internet gateway>
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.
Copyright © 2012 - 2014 Crosspeer, Inc.
               All Rights Reserved