This is a guide on setting up an IPSEC/L2TP vpn server with Ubuntu 14.04 using Openswan as the IPsec server, xl2tpd as the l2tp provider and ppp or local users / PAM for authentication. It has a detailed explanation with every step. We choose the IPSEC/L2TP protocol stack because of recent vulnerabilities found in pptpd VPNs and because it is supported on all major operating systems by default.
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:
First we will install the required packages:
apt-get install openswan xl2tpd ppp lsof
The openswan installation will ask some questions, this tutorial works with the default answers (just enter through it).
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 vpn traffic:
iptables -t nat -A POSTROUTING -j SNAT --to-source %SERVERIP% -o eth+
Replace %SERVERIP% with the external IP of your VPS. If your external interface is not named ethX (+ is a wildcard) then rename appropriately.
Execute the below commands to enable kernel IP packet forwarding and disable ICP redirects.
echo "net.ipv4.ip_forward = 1" | tee -a /etc/sysctl.confecho "net.ipv4.conf.all.accept_redirects = 0" | tee -a /etc/sysctl.confecho "net.ipv4.conf.all.send_redirects = 0" | tee -a /etc/sysctl.confecho "net.ipv4.conf.default.rp_filter = 0" | tee -a /etc/sysctl.confecho "net.ipv4.conf.default.accept_source_route = 0" | tee -a /etc/sysctl.confecho "net.ipv4.conf.default.send_redirects = 0" | tee -a /etc/sysctl.confecho "net.ipv4.icmp_ignore_bogus_error_responses = 1" | tee -a /etc/sysctl.conf
Set these settings for other network interfaces:
for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
To make sure this keeps working at boot you might want to add the following to nano /etc/rc.local:
for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; doneiptables -t nat -A POSTROUTING -j SNAT --to-source %SERVERIP% -o eth+
Add it before the exit 0 line and replace %SERVERIP% with the external IP of your VPS.
Use your favorite editor to edit the following file:
Replace the contents with the following (Most lines have a comment below it explaining what it does):
config setup dumpdir=/var/run/pluto/ #in what directory should things started by setup (notably the Pluto daemon) be allowed to dump core?
nat_traversal=yes #whether to accept/offer to support NAT (NAPT, also known as "IP Masqurade") workaround for IPsec
virtual_private=%v4:10.0.0.0/24,%v4:192.168.0.0/24,%v4:172.16.0.0/24,%v6:fd00::/8,%v6:fe80::/10 #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.
protostack=netkey #decide which protocol stack is going to be used.
force_keepalive=yes keep_alive=60 # Send a keep-alive packet every 60 seconds.
conn L2TP-PSK-noNAT authby=secret #shared secret. Use rsasig for certificates.
pfs=no #Disable pfs
auto=add #the ipsec tunnel should be started and routes created when the ipsec daemon itself starts.
keyingtries=3 #Only negotiate a conn. 3 times.
ike=aes256-sha1,aes128-sha1,3des-sha1 phase2alg=aes256-sha1,aes128-sha1,3des-sha1 # https://lists.openswan.org/pipermail/users/2014-April/022947.html # specifies the phase 1 encryption scheme, the hashing algorithm, and the diffie-hellman group. The modp1024 is for Diffie-Hellman 2. Why 'modp' instead of dh? DH2 is a 1028 bit encryption algorithm that modulo's a prime number, e.g. modp1028. See RFC 5114 for details or the wiki page on diffie hellmann, if interested.
type=transport #because we use l2tp as tunnel protocol
left=%SERVERIP% #fill in server IP above
leftprotoport=17/1701 right=%any rightprotoport=17/%any
dpddelay=10 # Dead Peer Dectection (RFC 3706) keepalives delay dpdtimeout=20 # length of time (in seconds) we will idle without hearing either an R_U_THERE poll from our peer, or an R_U_THERE_ACK reply. dpdaction=clear # When a DPD enabled peer is declared dead, what action should be taken. clear means the eroute and SA with both be cleared.
Replace %SERVERIP% with the external IP of your server. You can find it out by:
The shared secret is defined in the nano /etc/ipsec.secrets file. Make sure it is long and random:
%SERVERIP% %any: PSK "69EA16F2C529E74A7D1B0FE99E69F6BDCD3E44"
Yet again, replace %SERVERIP% with the IP of your server here. If you want to generate a random key you can use the following openssl command:
openssl rand -hex 30
Now to make sure IPSEC works, execute the following command:
My output looks like this:
The /bin/sh and Opportunistic Encryption warnings can be ignored. The first one is a openswan bug and the second one causes xl2tpd to trip.
Replace the contents with the following:
[global]ipsec saref = yessaref refinfo = 30
;debug avp = yes;debug network = yes;debug state = yes;debug tunnel = yes
[lns default]ip range = 172.16.1.30-172.16.1.100local ip = 172.16.1.1refuse pap = yesrequire authentication = yes;ppp debug = yespppoptfile = /etc/ppp/options.xl2tpdlength bit = yes
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.
In your nano /etc/xl2tpd/xl2tpd.conf add the following line:
unix authentication = yes
and remove the following line:
refuse pap = yes
In the file nano /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 (nano /etc/ppp/options.xl2tpd) add the following extra line:
Change nano /etc/pam.d/ppp to this:
auth required pam_nologin.soauth required pam_unix.soaccount required pam_unix.sosession required pam_unix.so
(As in, remove existing lines and add these)
Add the following to nano /etc/ppp/pap-secrets:
* l2tpd "" *
(And, skip the chap-secrets file below (adding users).)
require-mschap-v2ms-dns 184.108.40.206ms-dns 220.127.116.11authmtu 1200mru 1000crtsctshide-passwordmodemname l2tpdproxyarplcp-echo-interval 30lcp-echo-failure 4
Every user should be defined in the nano /etc/ppp/chap-secrets file. Below is an example file.
# Secrets for authentication using CHAP# client server secret IP addressesalice l2tpd 0F92E5FC2414101EA *bob l2tpd DF98F09F74C06A2F *
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 http://whatsmyip.org. If it is the VPN servers IP then it works.
If you experience problems make sure to check the client log files and the ubuntu /var/log/syslog and /var/log/auth.log files. If you google the error messages you most of the time get a good answer.