Setting Up a VPN With Your iPhone Using L2TP, IPSec and Linux

December 11, 2011 Category: Security

This blogpost discusses how to setup an IPSec-based VPN between your iPhone and a Linux server.

Updated 16 October 2012 - now compatible with Ubuntu 12.04 LTS

IMPORTANT! (update January 2013)

I find using OpenVPN with the new iOS OpenVPN client a way better solution. OpenVPN actually restores VPN connectivity when returning from sleep.

Why using a VPN with your iPhone?

  1. Security: all data is encrypted and cannot be read by malicious people trying to eavesdrop on your data.
  2. Performance: my subjective experience is that a VPN can speed up web browsing, it seems to reduce latency.

Introduction

I am assuming that you use:

  • an iPhone as the VPN client
  • a Debian-based Linux distro, such as Debian or Ubuntu (used here)

We will use the following software:

  • openswan
  • xl2tpd
  • pppd

To setup the VPN, we need to configure the following steps:

  1. install the software
  2. configure IPSec
  3. configure L2TP
  4. configure PPP
  5. open up the appropriate firewall Ports
  6. setup firewall rules to forward traffic between the iPhone and Internet
  7. configuring the iPhone

This set of instructions is 90% based on instructions on peen.net made by Niels Peen (Groeten!). I borrowed some other stuff from this blog.

I use openswan for IPSec support because strongswan does not support NAT by default. I just want to use software as part of the operating system and don't like to have to maintain manually compiled versions. This is why.

Initial assumptions

  • You are using a Linux host as the VPN server
  • The server is accessible from the internet or the appropriate UDP ports are forwarded to the box.
  • You have full control over the box and it's firewall configuration.
  • Your iPhone has an unfiltered internet connection. If UDP is blocked, this type of VPN is not for you.

Install the software

First, we start with installing all required software:

apt-get install openswan xl2tpd ppp

Configure IPSec

Now we start with configuring the software. First we start with IPSec:

/etc/ipsec.conf

config setup
    nat_traversal=yes
    protostack=netkey
    plutostderrlog=/tmp/log.txt (for debugging)

conn L2TP-PSK
    authby=secret
    pfs=no
    rekey=no
    type=tunnel
    esp=aes128-sha1
    ike=aes128-sha-modp1024
    ikelifetime=8h
    keylife=1h
    left=<INTERNET IP ADDRESS OF ROUTER / SERVER>
    leftnexthop=%defaultroute
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
    rightsubnetwithin=0.0.0.0/0
    auto=add
    dpddelay=30
    dpdtimeout=120
    dpdaction=clear

Some notes about this configuration:

  • We use a secret or password for authentication. Sources on the internet seem to suggest that the iPhone cannot handle certificates.
  • we must configure the dead peer detection rules at the bottom or else you cannot reconnect to the VPN when returning from sleep.

We thus also need to configure an encryption secret (password) for the IPSec tunnel.

/etc/ipsec.secrets

%any %any: PSK "thisismysupersecretpassword"

It is smart to choose a strong (long) password.

Configure L2TP

Inside the directory /etc/xl2tpd you have to edit xl2tpd.conf like this:

[global]
auth file = /etc/l2tpd/l2tp-secrets
debug network = yes
debug tunnel = yes

[lns default]

ip range = 10.0.1.201-10.0.1.240
local ip = 10.0.1.200
require chap = yes
refuse pap = yes
require authentication = yes
name = <ENTER SOME NAME HERE>
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

The "ip range" is within your internal network. It is a range outside of your DHCP-scope. The "ip range" must not include the "local ip". This IP address is dedicated to your Linux host.

Important: once the VPN setup is working properly Turn off all debugging options (set them to 'no'). Otherwise, your logs will fill up very quickly because every time a packet is transmitted, this is logged.

Configure PPP

Now we must configure PPP. Edit /etc/ppp/options.xl2tpd and make it look like this:

ipcp-accept-local
ipcp-accept-remote
ms-dns <ADDRESS OF LOCAL OR REMOTE DNS SERVER>
noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute 
debug
lock
proxyarp
connect-delay 5000

Note that you must enter a valid DNS server that must be reachable by the VPN client (iPhone) through the tunnel.

We are almost there. Now we must also configure a password for the PPP connection. Edit /etc/ppp/chap-secrets and make it look like this:

* * thisissomesecretpassword *

This password is not related to the IPSec password. I think it is wise to configure different passwords for IPSec and PPP.

Configuring the firewall

An IPSec + L2TP + PPP VPN requires the following ports to be opened:

  • 500/udp
  • 4500/udp
  • 1701/udp

You must open these ports in your firewall yourself.

Configuring traffic forwarding rules

If you use a Linux box with IPtables, you may already have a functioning configuration. However, this line is required for traffic forwarding to work:

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

You must replace the correct IP addresses according to your configuration. You may also have to enable traffic forwarding like this:

echo 1 > /proc/sys/net/ipv4/ip_forwarding

A detailed firewall configuration guide is outside the scope of this tutorial.

If you use IPtables for your local firewall, you may be interested in my "Linux Firewall script" (shameless plug alert).

Configuring the iPhone

To configure a VPN profile, goto settings -> general -> network -> vpn (at the bottom). Choose 'Add VPN Configuration..."

ipsec iphone config

  1. Enter a description
  2. Enter the IP address or DNS name of your Linux box.
  3. The 'account' field can be anything you like.
  4. Leave RSA SecurID off.
  5. The Password is the PPP password configured in /etc/ppp/chap-secrets
  6. The IPSec secret (/etc/ipsec.secrets) goes into the 'Secret' field.
  7. Keep 'Send All Traffic' enabled.

If the connection succeeds, a VPN symbol will show up in the iPhone status bar. All traffic from then on will flow through the VPN.

It may not immediately work. Look in /var/log/auth.log and /var/log/daemon.log for debug messages.

Once it is working properly, disable all debug settings in xl2tpd.conf and restart the daemon.

Final remarks

You may have to tweak the 'dead peer detection' within the IPSec configuration. When the iPhone comes out of sleep, the VPN connection cannot be reinitiated right away, which is inconvenient.

Also, I'm not sure what the impact is on battery life.

Comments