Debian 7 Wheezy – L2TP VPN Server behind NAT with strongSwan and self-signed certificate authentication

As usual before everything else a few good and must read articles on the subject: https://www.zeitgeist.se/2013/11/22/strongswan-howto-create-your-own-vpn/ – a very good tutorial on setting up strongSwan, http://www.manabii.info/2014/08/debian-wheezy-strongswan-l2tp-ipsec.html – another very good tutorial on L2TP strongSwan configuration /you will have to translate it from Japan unless you are a ninja :-)/ and of course the very important strongSwan wiki documentation at https://wiki.strongswan.org/projects/strongswan.

Why strongSwan and L2TP? Well after some research I have done on the available IPsec implementations for Linux I have decided to go for strongSwan because of its active development. As for L2TP I decided that a bit of overhead, which any modern hardware can handle the capability to use other protocols as well as IP over the VPN connection is worth the hassle.

 

STEP 1 – GENERAL PREPARATION

The assumption is you already have control over a DNS server, local network in range of 192.168.0.0/24, a server running Debian 7 Wheezy  with IP address 192.168.0.10 and as a good practice advises – first make sure your system is up to date, just run /do not forget to be a root user or use sudo when necessary/:

#apt-get update && apt-get upgrade

Normally Debian 7 will install strongSwan 4, but I wanted version 5 because it only runs the charon daemon which handles everything for you and you do not have to configure NAT-T – it is triggered for you automatically if needed. To do this you will have to alter the /etc/apt/sources.list file adding those lines in it:

deb http://ftp.debian.org/debian/ wheezy-backports main
deb-src http://ftp.debian.org/debian/ wheezy-backports main

After that you can run the set of commands which will update the sources, install the xl2tpd daemon /this is the software responsible for L2TP/ and install strongSwan:

#apt-get update
#apt-get install xl2tpd
#apt-get -t wheezy-backports install strongswan

Just to check you have the version 5 of strongSwan:

#dpkg -l | grep strong

The next important thing is to change the kernel parameter so it can route the VPN traffic /later on NAT will be configured/. To achieve this in a permanent way some parameters in /etc/sysctrl.conf must be set properly, you will need to have this:

net.ipv4.ip_forward = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0

To apply the changes run the following command:

#sysctl –p

 

STEP 2 – CERTIFICATES PREPARATION

Before generating certificates find out the fully qualified domain name of your VPN server, make sure an A record for it exist in your DNS server and use it as CN when generating certificates. To find your FQDN run the fallowing command:

#hostname –f

Now you are ready to generate the certificate authority key and certificate:

#cd /etc/ipsec.d/
#ipsec pki –gen –type rsa –size 4096 \
–outform pem \
> private/CA_Key.pem

#chmod 600 private/CA_Key.pem

#ipsec pki –self –ca –lifetime 3650 \
–in private/CA_Key.pem –type rsa \
–dn “C=GB, O=SomeName, CN=server.example.com” \
–outform pem \
> cacerts/CA_Cert.pem

 

Create the VPN Server Key and Certificate

#ipsec pki –gen –type rsa –size 2048 \
–outform pem \
> private/VPN_Server_Key.pem

#chmod 600 private/VPN_Server_Key.pem

#ipsec pki –pub –in private/VPN_Server_Key.pem –type rsa | \
ipsec pki –issue –lifetime 3650 \
–cacert cacerts/CA_Cert.pem \
–cakey private/CA_Key.pem \
–dn ” C=GB, O=SomeName, CN=server.example.com ” \
–san server.example.com \
–flag serverAuth –flag ikeIntermediate \
–outform pem > certs/VPN_Server_Cert.pem

 

Create Client Certificate

#ipsec pki –gen –type rsa –size 2048 \
–outform pem \
> private/ClientKey.pem

#chmod 600 private/ClientKey.pem

#ipsec pki –pub –in private/ClientKey.pem –type rsa | \
ipsec pki –issue –lifetime 3650 \
–cacert cacerts/CA_Cert.pem \
–cakey private/CA_Key.pem \
–dn ” C=GB, O=SomeName, CN=server.example.com ” \
–san user@example.com \
–outform pem > certs/ClientCert.pem

 

Export Certificate for the Client as PKCS#12

#openssl pkcs12 -export -inkey private/ClientKey.pem \
-in certs/ClientCert.pem -name “Client VPN Certificate” \
-certfile cacerts/CA_Cert.pem \
-caname “server.example.com” \
-out Client.p12

 

STEP 3 – SETTING UP srongSwan

There are few files used to configure strongSwan all located in /etc folder. The file /etc/strongswan.conf I left unchanged as it probably is set correctly for most users, but of course you can check its content and if you are sure you know what you are doing adjust it to your needs.
Next is the file /etc/ipsec.conf, which you can backup first before changing:

#cp /etc/ipsec.conf /etc/ipsec.conf.bac

Then you can create the configuration you need, mine looks like:

# ipsec.conf – strongSwan IPsec configuration file

# basic configuration

config setup
#       strictcrlpolicy=yes
#       uniqueids = no
charondebug=”cfg 2, dmn 2, ike 2, net 2″

# Add connections here.
conn L2TP
forceencaps=yes
auto=add
keyexchange=ikev1
keyingtries=3
rekey=no
ikelifetime=8h
lifetime=1h
type=transport
left=192.168.0.10
leftsubnet=0.0.0.0/0[udp/1701]
leftauth=pubkey
leftcert=VPN_Server_Cert.pem
right=%any
rightsubnet=0.0.0.0/0[udp/%any]
rightauth=pubkey
rightcert=ClientCert.pem
dpddelay=40
dpdtimeout=130
dpdaction=clear

include /var/lib/strongswan/ipsec.conf.inc

And finally the file /etc/ipsec.secrets has to be set so the client can log in. Mine is set as follows:

: RSA VPN_Server_Key.pem
#user1 : EAP “BigSecret”
#user2 : XAUTH “AnotherBigSecret”

It is not a bad idea to set the permissions:

#chmod 600 /etc/ipsec.secrets

To make sure ipsec service loads on boot:

#insserv ipsec

 

STEP 4 – SETTING UP L2TP

Three files must be configured so xl2tpd daemon to work properly. First one is /etc/xl2tpd/xl2tpd.conf where the global parameters are set and in my case it is like that:

[global]
[lns default]
ip range = 192.168.111.2 – 192.168.111.254
local ip = 192.168.111.1
length bit = yes
refuse chap = yes
require authentication = yes
name = l2tp
pppoptfile = /etc/ppp/l2tpd-options

The next one is obviously the file /etc/ppp/l2tpd-options where you set some PPP options and mine are set as:

name l2tp
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
nodefaultroute
lock
nobsdcomp
mtu 1280
mru 1280

And finally you set the PPP user in the file /etc/ppp/chap-secrets:

# client    server  secret      IP addresses
vpnuser    l2tp    “aPassword”  *

 

STEP 5 – SETTING UP NAT

We are almost there now. The final bit is to set up the NAT, which is done with iptables, but before that I recon it is not a bad idea to install the iptables-persistent package and have your rules saved and loaded properly on reboot. To do this you will have to:

#apt-get install iptables-persistent

Then you can create the rule and have it saved. To go for SNAT or Masquerading is a personal choice, but as you most likely will have a static IP address for your server probably SNAT is better:

#iptables -t nat -A POSTROUTING -j SNAT –to-source 192.168.0.10 -o eth+
#iptables-save > /etc/iptables/rules.v4

To check if your services are running you can see their status or/and network activity:

#service –status-all

or

#netstat -lnput | grep charon
#netstat -lnput | grep xl2tpd

Do not forget to forward UDP ports 500, 1701 and 4500 on your router.

And now the funny part…  Connecting your clients. Android devices connect effortlessly, just install your client certificate using the p12 file, put your PPP username and password as well as the server IP address /which will be the public address of your router/ or its DNS name /should resolve to your router’s public address/ and you are done.
Have not tried iOS device yet, but as Mac OS X connects I would assume there will not be a problem, though it was a bit tricky with the Mac. Make sure you install the client certificate in your System key chain and then make it trusted. Make sure you have a record in your DNS server with exactly the same name of your VPN server as it is in the certificate and when setting the connection do not use the IP address, use the domain name. If you do not do it this way you will not be able to connect.
Windows… well I could not manage to connect even a single Windows 7 client PC regardless of what I tried – switching off firewall and antivirus software, changing the configuration of the VPN server, had the certificates properly installed with MMC, and before you ask – yes, I have had the AssumeUDPEncapsulationContextOnSendRule in the registry set to 2. Nothing worked. Had a brief look at third party VPN clients for Windows, but could not find a good enough to support L2TP VPN with certificates. So if anyone have experience with this I will be happy to see what is wrong and where, I could not figure it out from the server logs.

“And that’s all I’ve got to say about that” – Forrest Gump 🙂

For now. 🙂

Advertisement

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: