The following are instructions for setting up an L2TP VPN server on a Raspberry Pi running Raspbian Jessie. This allows you to connect your iPhone or other device using L2TP VPN to your home network, to securely access resources on it. This set up uses a Raspberry Pi sitting behind your normal router.
These instructions are based on an older forum post on the Raspberry Pi forums.
All of the following commands will need to be run as root. Use sudo to become the root user.
$ sudo su -
Configuring a Static IP Address
Since your Raspberry Pi is running a server, it will be important to give it a consistent IP address so that we can forward the necessary ports to it. The IP address you choose depends on your local network setup. My network uses the 192.168.1.XXX range, so I have decided to use 192.168.1.16 for my Raspberry Pi. Here are the full settings for my setup:
IP Address: 192.168.1.16
Netmask: 255.255.255.0
Gateway: 192.168.1.254
DNS Server(s): 192.168.1.254
With the release of Raspbian Jessie, the method for configuring IP addresses has changed. Raspbian now uses dhcpcd as the default, so it is no longer recommended that you directly modify /etc/network/interfaces. Instead, we will modify dhcpcd’s configuration.
Edit /etc/dhcpcd.conf and add the following to the end. You will need to modify some of these values based on your setup.
interface eth0 static ip_address=192.168.1.16/24 static routers=192.168.1.254 static domain_name_servers=192.168.1.254
Once you reboot, your Raspberry Pi should now be using the address you have specified.
Installing xl2tpd and openswan
We need to install xl2tpd for our VPN tunnel and openswan for our IPSec security.
Warning: openswan is no longer maintained and has been replaced by strongswan. I have not yet tried this with strongswan.
$ apt-get update
$ apt-get install openswan xl2tpd ppp lsof
Configuring xl2tpd
xl2tpd provides our VPN tunnel into our network.
Replace the contents of /etc/xl2tpd/xl2tpd.conf with the following. You may need to make changes based on your network settings and your static IP address we configured previously.
[global] ipsec saref = yes listen-addr = 192.168.1.16 [lns default] ip range = 192.168.1.201-192.168.1.250 local ip = 192.168.1.16 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
Replace your /etc/ppp/options.xl2tpd with the following:
ipcp-accept-local ipcp-accept-remote ms-dns 192.168.1.254 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
Configuring IPSec
IPSec is the encryption layer for your VPN tunnel. We are using the openswan implementation.
Replace your /etc/ipsec.conf with the following. Again, you will need to replace any values depending on your network setup.
# /etc/ipsec.conf - Openswan IPsec configuration file # This file: /usr/share/doc/openswan/ipsec.conf-sample # # Manual:    ipsec.conf.5 version   2.0   # conforms to second version of ipsec.conf specification # basic configuration config setup    # Do not set debug options to debug configuration issues!    # plutodebug / klipsdebug = "all", "none" or a combation from below:    # "raw crypt parsing emitting control klips pfkey natt x509 dpd private"    # eg:    # plutodebug="control parsing"    # Again: only enable plutodebug or klipsdebug when asked by a developer    #    # enable to get logs per-peer    # plutoopts="--perpeerlog"    #    # Enable core dumps (might require system changes, like ulimit -C)    # This is required for abrtd to work properly    # Note: incorrect SElinux policies might prevent pluto writing the core    dumpdir=/var/run/pluto/    #    # NAT-TRAVERSAL support, see README.NAT-Traversal    nat_traversal=yes    # exclude networks used on server side by adding %v4:!a.b.c.0/24    # It seems that T-Mobile in the US and Rogers/Fido in Canada are    # using 25/8 as "private" address space on their 3G network.    # This range has not been announced via BGP (at least upto 2010-12-21)    #virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:fe80::/10:    virtual_private=%v4:192.168.0.0/16,%v4:10.10.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:!10.25.0.0/16    # OE is now off by default. Uncomment and change to on, to enable.    oe=off    # which IPsec stack to use. auto will try netkey, then klips then mast    protostack=netkey    # Use this to log to a file, or disable logging on embedded systems (like openwrt)    #plutostderrlog=/dev/null # Add connections here # sample VPN connection # for more examples, see /etc/ipsec.d/examples/ #conn sample #      # Left security gateway, subnet behind it, nexthop toward right. #      left=10.0.0.1 #      leftsubnet=172.16.0.0/24 #      leftnexthop=10.22.33.44 #      # Right security gateway, subnet behind it, nexthop toward left. #      right=10.12.12.1 #      rightsubnet=192.168.0.0/24 #      rightnexthop=10.101.102.103 #      # To authorize this connection, but not actually start it, #      # at startup, uncomment this. #      #auto=add conn L2TP-PSK-NAT    # !mwd - disabling this fixed stuff    #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.1.16        #        # For updated Windows 2000/XP clients,        # to support old clients as well, use leftprotoport=17/%any        leftprotoport=17/1701        #        # 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.1.16        leftnexthop=192.168.1.254        right=0.0.0.0        rightsubnet=0.0.0.0/0        auto=route
Configuring your Secret Key
The secret key is a shared key that all of your users will use. Edit /etc/ipsec.secrets
# This file holds shared secrets or RSA private keys for inter-Pluto # authentication. See ipsec_pluto(8) manpage, and HTML documentation. # RSA private key for this host, authenticating it to any other host # which knows the public part. Suitable public keys, for ipsec.conf, DNS, # or configuration of other implementations, can be extracted conveniently # with "ipsec showhostkey". # this file is managed with debconf and will contain the automatically created RSA keys #include /var/lib/openswan/ipsec.secrets.inc 192.168.1.16 %any:  PSK "MYSECRET"
Configuring your Users
You can create as many vpn users as you want. These users are separate from any linux user accounts on your Raspberry Pi. Edit /etc/ppp/chap-secrets
# Secrets for authentication using CHAP # client   server   secret         IP addresses username   *   password   *
Modifying iptables and System Services
We need to make some changes to the routing table and system configuration. First we will set some values and add them to our /etc/sysctl.conf which will be loaded each time the system starts up:
$ 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
$ sysctl -p
The iptables and /proc settings won’t survive a reboot. We’ll add these commands to the end of our /etc/rc.local to make sure they are executed on start up:
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
Finally, let’s make sure our xl2tpd and ipsec services will be started on boot:
$ update-rc.d -f ipsec remove
$ update-rc.d ipsec defaults
At this point, you should restart your Raspberry Pi to make sure all settings have taken effect and is configured correctly.
Configuring your Router Port Forwarding
This section depends on your router. Most consumer routers/wifi have a web admin interface at either 192.168.1.1 or 192.168.1.254. Once you are logged in, you’ll need to find the port forwarding or NAT/Gaming section. You will need to have the following ports forwarded to your Raspberry Pi IP Address, which in my case is 192.168.1.16. Please be aware that these ports are UDP not TCP.
Port 4500 UDP
Port 500 UDP
Connecting an iPhone
On your iPhone, go to Setting > General > VPN
Choose “Add VPN Configuration”. Select “L2TP” as the Type.
Type: L2TP
Description: Home VPN
Server: Your public IP address (this is NOT your 192.168.1.16 address. You can get this from your router or from http://whatismyip.com)
Account: The username you configured in /etc/ppp/chap-secrets
RSA SecureID: Disabled
Password: The password you configured in /etc/ppp/chap-secrets
Secret: The Shared secret you configured in /etc/ipsec.secrets
Send All Traffic: If enabled, then ALL your internet traffic will be routed through your home network. If you disable this, then normal internet traffic won’t go through your home network. The VPN will only be used to access devices on your home network