How to Setup L2TP/IPSec VPN Servers (Debian)

I was recently asked how to access BBC iPlayer and itv from New Zealand. These services are geolocked and require you to be in the UK to access them. Anyway it prompted me to setup a VPN server.

As the VPN Server needs to be on 24/7, it would ideally be a server which consumes little power and maintenance. For this I have chosen an Orange PI Zero. I have grown to love this little ARM computer, it’s so small and can be powered off a router’s USB port, no wall wart required.

This post will aim to guide a user through setting up the VPN server and clients and their associated settings.

First thing to note is that although L2TP/IPSec is used, there are many flavours of this, and specifically my requirement is that the server must be compatible with native L2TP/IPSec clients on Windows, OSX, Android and iPhone.

IPSec can operate in tunnel mode where two routers establish an encrypted connection over the internet. In this case we want to setup a client-server type relationship, as such IPSec transport mode will be used.

To keep things simple we’ll also use PreSharedKey (PSK) authentication instead of certificates.


Orange Pi OS & VPN Server:
– Armbian based off Debian Scratch
– xl2tpd to manage L2TP connections
– strongSwan for IPSec

Router Settings

To allow our VPN server to be visible on the internet, the router will need to enable port forwarding to the Orange PI to receive on the IPSec ports. The IKE (500) and NAT-Traversal (4500) UDP ports should be open and forwarded to the VPN Server in this case

IP Protocol 50 (ESP) also needs to be open and not blocked.

L2TP UDP Port 1701 does not need for be forwarded as we don’t want to allow basic unencrypted L2TP tunnels to be opened up to our VPN server.


VPN Server Settings

Install xl2tpd and strongswan:

sudo apt-get install xl2tpd
sudo apt-get install strongswan

xl2tpd is the L2TP server and strongswan handles the IPSec.


To allow clients on the network to access the internet we add this line.

iptables -t nat -A POSTROUTING -s -j MASQUERADE

This basically sets up (double) NAT for the private network that the VPN Server manages.

So that DNS queries to do ‘leak’ out we also need to allow DNS redirection to our selected DNS server

iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination
iptables -t nat -A PREROUTING -p tcp --dport 53 -j DNAT --to-destination


There’s a good explanation of this command here:


xl2tpd settings

Configure the xl2tpd settings.
Navigate to /etc/xl2tpd/xl2tpd.conf

port = 1701
access control = no

[lns default]
ip range =
local ip =
require authentication = yes
name = LinuxVPN
pppoptfile = /etc/ppp/options.xl2tpd


When VPN clients connect to us we assign them a VPN IP Address, in this case I’ve kept it separate from the addresses and used

The VPN Server itself now has 2 IP Addresses, and It will also assign IPs in the range of as clients connect.


PPP Settings

Why do we need PPP? In a way this is PPP/L2TP/IPSec, where PPP (read internet data) packets go through the L2TP tunnel and then encrypted by IPSec. See for a nice diagram and further explanation.

Normally a ppp server is included with the Linux distro, if not you can install using:

apt-get install ppp

Navigate to /etc/ppp/options.xl2tp

Setup the PPP Server settings for the xl2tp server at /etc/ppp/options.xl2tpd

mtu 1410
mru 1410

The ms-dns is the DNS server which clients will be directed to resolve addresses when they connect to the VPN server. Beware that a DNS leak can be caused if say a DNS such as is used as the client will try to directly contact Ideally the DNS resolution is done via the VPN server.

If you want more info regarding these settings goto:

On the client side, you’ll also want to update the /etc/resolv.conf and replace the default nameserver with the VPN IP address too, otherwise you might run the risk of DNS leaks.

PPP Authentication

To allow the pppd to authenticate users we need to add the account to the chap-secrets file.

Add users with the command:

#echo “User * mysecretpass *” >> /etc/ppp/chap-secrets

You can also edit the chap-secrets file manually to add users.

IPSec Settings

We now have to configure strongSwan. Edit the file /etc/ipsec.conf

# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
        # strictcrlpolicy=yes
        # uniqueids = no

# Add connections here.
conn vpnserver
include /var/lib/strongswan/


Take note how the type is ‘transport’ and authby is ‘secret’. This means we are using IPSec in transport and PSK mode. StrongSwan uses this ‘left’ and ‘right’ kind of configuration file where the server is left and the clients are right. Sometimes these can be switch, but strongswan will figure it out.

In this instance we are using the same IKE/ESP authentication mode as commonly used by Windows/OSX etc, which is aes128-sha1. IKE represents the settings used by IPSec Phase 1 and ESP is the method used in IPSec Phase 2.

Some tutorial has This can cause issues in OSX clients (which use racoon IPSec) where they check that the server id matches. If the ServerID does not match, then Phase 1 can fail.

You can read more about the IPSec Phases here:



IPSec Password

The final part is to add the IPSec secret by editing the /etc/ipsec.secrets file

# This file holds shared secrets or RSA private keys for authentication.
# RSA private key for this host, authenticating it to any other host
# which knows the public part.
%any %any : PSK "ipsecpass"
# this file is managed with debconf and will contain the automatically created private key
include /var/lib/strongswan/


Stay tuned for Part 2 on how to setup the VPN for the clients such as macOS, Windows, FreeBSD and Ubuntu/Debian Linux!


PPP Manual


2 thoughts on “How to Setup L2TP/IPSec VPN Servers (Debian)

  1. If there is no requirement for clients to be able to access the internet via the VPN, can all 3 of the ‘iptables -t nat’ rules be left out (i.e. in this case clients can only access services running on the LAN extended by the VPN)?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s