Debian VPN Server for iPhone

This HowTo describes how to set-up your Debian machine as a VPN server for the iPhone. The iPhone uses L2TP over IPsec as a VPN protocol. Others are possible as well but here we stick to L2TP over IPsec.


Install the following packages:

Network layout

Internet === Router ( === Debian PC ( 



First we configure freeradius. In /etc/freeradius/clients.conf change the default secret (line 101):

secret          = mysecret

Create a default user for freeradius by adding the following lines in /etc/freeradius/users:

DEFAULT         Auth-Type := System
                Fall-Through = Yes

With this Auth-Type system users of the Debian PC will be used for freeradius. Add users to your system as required if existing users are not appropriate.


The implementation of L2TP on the iPhone (and OS-X in general) has some flaws which prevent it from working with l2tpns out of the box. The hackish way around that is to comment out a few lines in the source of l2tpns.c:

--- l2tpns_orig.c       2006-06-22 17:30:50.000000000 +0200
+++ l2tpns.c    2011-06-13 09:22:38.000000000 +0200
@@ -2835,6 +2835,7 @@
                // Send hello
+               /*
                if (tunnel[t].state == TUNNELOPEN && !tunnel[t].controlc && (time_now - tunnel[t].lastrec) > 60)
                        controlt *c = controlnew(6); // sending HELLO
@@ -2842,6 +2843,7 @@
                        LOG(3, 0, t, "Sending HELLO message\n");
+               */
                // Check for tunnel changes requested from the CLI
                if ((a = cli_tunnel_actions[t].action))

Get the source via apt-get source l2tpns, change l2tpns.c, recompile and copy the l2tpns binary to /usr/sbin/.

In /etc/l2ptns/ip_range a range of IP addresses which will be assigned to VPN clients can be defined. The IP range shall be a subnet of your own internal network.

/etc/l2tpns/startup-config is the main configuration file for l2tpns. Most of the settings can be left commented out. Only the following lines are active in my setup:

set debug 2
set log_file "/var/log/l2tpns"
set pid_file "/var/run/"
set l2tp_secret ""
set primary_dns
set secondary_dns
set primary_radius
set primary_radius_port 1812
set radius_secret "mysecret"
set accounting_dir "/var/run/l2tpns/acct"
set bind_address
set send_garp yes
set peer_address
set throttle_speed 64
set cluster_interface lo
set cluster_hb_interval 100
set cluster_hb_timeout 20

Make sure you have set peer_address to the IP of your router. The setting primary_radius is set to the the local IP since freeradius is running on the same machine. In my case primary_dns is set to the IP of the Debian machine since I'm running a local DNS server.


In /etc/ipsec.secrets we add our ipsec secret. This is then later on used for configuring the VPN connection on your iPhone: PSK "mykey"

The ipsec main configuration file /etc/ipsec.conf is looking like this:

# /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
        # NAT-TRAVERSAL support, see README.NAT-Traversal
        # exclude networks used on server side by adding %v4:!a.b.c.0/24
        # OE is now off by default. Uncomment and change to on, to enable.
        # which IPsec stack to use. auto will try netkey, then klips then mast
conn road_warrior

Make sure you have excluded your entire local IP range in virtual_private using ! The setting left in the connection setup shall be set to the IP of your Debian machine. The setting leftnexthop is set to the IP of your router.

Network configuration

In order to map your VPN subnet to the local network ARP proxying can be used. Enable proxy_arp for your main network interface in /etc/network/interfaces:

iface eth0 inet static
        up sysctl net.ipv4.conf.eth0.proxy_arp=1

On your router you have to forward udp packets to ports 500 and 4500 to your Debian PC:

iptables -t nat -I PREROUTING -i $WANDEV -p udp --dport 500 -j DNAT --to-destination
iptables -t nat -I PREROUTING -i $WANDEV -p udp --dport 4500 -j DNAT --to-destination


On the iPhone go to Settings -> General -> Network -> VPN and create a new VPN configuration. Server shall be the external DNS name or IP of your router. Account shall be the user name existing on your Debian machine. RSA SecureID is OFF. Password is the password of the user used for the Account setting. Secret is the secret defined in /etc/ipsec.secrets.

iPhone VPN Setup