L2TP + IPsec VPN server on Raspberry Pi (IOS 10 support)

First at all, what is Raspbery Pi?

It is super small computer (credit card size) running on version of Debian linux called Raspbian. It is ideal for home server, and control of your home devices such as cameras, printers,etc… In case your provider gave you the router without VPN support (which is my case) it is the perfect way to make your own VPN server.

As Apple has removed PPTP from IOS 10, L2TP + IPsec is one of the options. Here is my config that works perfectly on my iPhone and iPad. Raspberry Pi runs Raspbian Jessie.

(This setup should be the same on all linux platforms)


1. Forward udp ports 500 and 4500 on your router. You can also put your Pi in DMZ, so all ports will be exposed to internet.


2. Install openswan

apt-get install xl2tpd openswan ppp lsof

Note: Answer NO when asked if an X.509 certificate for this host can be automatically created or imported. This certificate can be created and imported later using:

dpkg-reconfigure openswan

3. Give your Pi static IP

/etc/dhcpcd.conf
nohook lookup-hostname
interface eth0
static ip_address=192.168.0.166/24
static routers=192.168.0.1
static domain_name_servers=8.8.8.8

192.168.0.166 is my Raspberry Pi ip, and 192.168.0.1 is my router. You have to switch those to your ip addresses.

4. Firewall and IP forwarding

Execute those line by line. You have to be root, or you can use sudo.

iptables –table nat –append POSTROUTING –jump MASQUERADE

echo “net.ipv4.ip_forward = 1” |  tee -a /etc/sysctl.conf

echo “net.ipv4.conf.all.accept_redirects = 0” |  tee -a /etc/sysctl.conf

echo “net.ipv4.conf.all.send_redirects = 0” |  tee -a /etc/sysctl.conf

for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done

sysctl -p

Add this code to /etc/rc.local

for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done

iptables --table nat --append POSTROUTING --jump MASQUERADE

5. /etc/ipsec.conf

This is whole config. Just replace 192.168.0.166 to your IP and 192.168.0.1 to your router IP

version 2.0
config setup
nat_traversal=yes
protostack=netkey
virtual_private=%v4:192.168.0.0/16,%v4:10.0.0.0/8,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:!10.25$
oe=off
plutodebug=all
plutostderrlog=/var/log/openswan.log
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3

# we cannot rekey for %any, let client rekey
rekey=no

# Apple iOS doesn't send delete notify so we need dead peer detection
# to detect vanishing clients

dpddelay=30
dpdtimeout=120
dpdaction=clear

# Set ikelifetime and keylife to same defaults windows has

ikelifetime=8h
keylife=1h

# l2tp-over-ipsec is transport mode
type=transport
#
left=192.168.0.166
#
# For updated Windows 2000/XP clients,
# to support old clients as well, use leftprotoport=17/%any
leftprotoport=17/%any
#
# The remote user.
#
right=%any
# Using the magic port of "%any" means "any one single port". This is
# a work around required for Apple OSX clients that use a randomly
# high port.
rightprotoport=17/%any
#force all to be nat'ed. because of ios
forceencaps=yes

# Normally, KLIPS drops all plaintext traffic from IP's it has a crypted
# connection with. With L2TP clients behind NAT, that's not really what
# you want. The connection below allows both l2tp/ipsec and plaintext
# connections from behind the same NAT router.
# The l2tpd use a leftprotoport, so they are more specific and will be used
# first. Then, packets for the host on different ports and protocols (eg ssh)
# will match this passthrough conn.

conn passthrough-for-non-l2tp
type=passthrough
left=192.168.0.166
leftnexthop=192.168.0.1
right=0.0.0.0
rightsubnet=0.0.0.0/0

auto=route

6. /etc/ipsec.secrets

Just put your IP address and your secret here.

include /var/lib/openswan/ipsec.secrets.inc
192.168.0.166 %any: PSK "your_password_here"

7. /etc/xl2tpd/xl2tpd.conf

Put your IP here and set range that will not conflict with your router dhcp

[global]
ipsec saref = yes
listen-addr = 192.168.0.166
[lns default]
ip range = 192.168.0.201-192.168.0.250
local ip = 192.168.0.166
assign ip = yes
require chap = yes
refuse pap = yes
require authentication = yes
name = linkVPN
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

8. /etc/ppp/options.xl2tpd

This one you can just copy.

require-mschap-v2
ipcp-accept-local
ipcp-accept-remote
ms-dns 8.8.8.8
asyncmap 0
auth
crtscts
lock
idle 1800
mtu 1200
mru 1200
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4
nodefaultroute
connect-delay 5000

9. /etc/ppp/chap-secrets

Set your user and password here.

# Secrets for authentication using CHAP
# client server secret IP addresses
username * password *

10. Restart the service

/etc/init.d/xl2tpd restart

/etc/init.d/ipsec restart

And that is it. Make sure your VPN server starts on boot:

update-rc.d -f ipsec remove

update-rc.d ipsec defaults

Chose MS-Chap v2 when connecting

And put your IPsec secret here

On IOS 10

Important

Windows does not support IPsec NAT-T by default, which is used whenever the server is behind a NAT (as in this case). You have to add a registry key to enable this.

On your Windows Vista, 7 or 8 client machine change or add the following registry item:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgent\

New DWORD (32-bit) Value:AssumeUDPEncapsulationContextOnSendRule 
Set the value to 2

This allows the client or server to be behind a NAT firewall.

3 Comments so far:

  1. Hi! Thank you for the great tutorial! The VPN works fine but it did not run after rebbot. I executed update-rc.d -f ipsec remove and
    update-rc.d ipsec defaults but it did not starts after a reboot. Any idea what to do?

  2. hi – thanks a lot “iptables –-table nat –-append POSTROUTING –-jump MASQUERADE” if you copy this there is a ‘-‘ missing

Leave a Reply to Hannan Cancel reply

Your email address will not be published. Required fields are marked *

Posted by: lesorsier on

Tags: , , , , ,

seo reseller