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?
- Security: all data is encrypted and cannot be read by malicious people trying to eavesdrop on your data.
- Performance: my subjective experience is that a VPN can speed up web browsing, it seems to reduce latency.
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:
To setup the VPN, we need to configure the following steps:
- install the software
- configure IPSec
- configure L2TP
- configure PPP
- open up the appropriate firewall Ports
- setup firewall rules to forward traffic between the iPhone and Internet
- configuring the iPhone
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.
- 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
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.
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.
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:
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..."
- Enter a description
- Enter the IP address or DNS name of your Linux box.
- The 'account' field can be anything you like.
- Leave RSA SecurID off.
- The Password is the PPP password configured in /etc/ppp/chap-secrets
- The IPSec secret (/etc/ipsec.secrets) goes into the 'Secret' field.
- 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.
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.