Easy IKEv2 strongSwan VPN for iOS

Using a VPN on your mobile devices, especially on public hotspots, should be mandatory.
If you are going to run your own VPN server OpenVPN is the way to go (expecially on Linux) but on iOS (and OSX, Windows, Android..) this will need a client App to run properly.
I noticed all platforms do support IPSec based solutions and according to some articles IKEv2 isn’t so bad (if you use strongswan, the opensource solution).
But setting it up isn’t as straightforward as setting up an openvpn server.. so after some research and trail and error I came to these basic steps to get up and running almost as fast as setting up an openvpn server.

Step 1

Install all packages needed. I’m using Debian Jessie (so this will probably also work on Ubuntu)

1
apt-get install strongswan libcharon-extra-plugins

and we are done :-)

Step 2

Configure ipsec/strongswan.
To get up and running ‘fast’ we are not going to use complex certificates which would be selfsigned anyway, instead we are going to use a pasphrase and complex passwords per user.
Open /etc/strongswan.conf in your favorite editor and replace everything with:

1
2
3
4
5
6
7
8
9
10
charon {
load_modular = yes
dns1 = 8.8.8.8
dns2 = 8.8.4.4
plugins {
include strongswan.d/charon/*.conf
}
}

include strongswan.d/*.conf

You can replace the dns1 and dns2 with your favorite dns-server, or the ones listed in /etc/resolv.conf on your server.

Now open up /etc/ipsec.conf and replace everything with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
config setup
strictcrlpolicy=no
uniqueids = no

conn %default
mobike=yes
dpdaction=clear
dpddelay=35s
dpdtimeout=200s
fragmentation=yes

conn iOS-IKEV2
auto=add
keyexchange=ikev2
eap_identity=%any
left=%any
leftsubnet=0.0.0.0/0
leftauth=psk
leftid=com.<your host or domain>.ipsec.server
right=%any
rightsourceip=10.0.0.1/24
rightauth=eap-mschapv2
rightid=com.<your host or domain>.ipsec.client

Replace the your host or domain and you can replace the 10.0.0.1 if you would like a different range for your vpn clients.

Step 3

Setup the user accounts.
Open /etc/ipsec.secrets in your favorite editor and add the passphrase and some users:

1
2
3
4
5
6
7
8
9
10
11
12
# This file holds shared secrets or RSA private keys for authentication.

# RSA private key for this host, authenticating it to any other host
# which knows the public part.

# this file is managed with debconf and will contain the automatically created private key
include /var/lib/strongswan/ipsec.secrets.inc

# logins
: PSK "m1WWmOIWzBvVipKsZsicKo38TtkucAvPBRvwpESoOOK6DdxlVgOpURxwLirxrmN"
myiphone : EAP "9TP9PoWRZ29hh5i3LqNKRSKm9ptUEmcNG2Wfq26P4E7lIondfBw6dGrl6lGKXrh"
anotheruser : EAP "IleeahMa3Of4UzCCiIwKAk7r43UGl2F4msiNa5xdScgwcr8KA4eKokBrnf8ZgMd"

Do not copy paste the keys, but render your own and replace them. I used this WLAN Key Generator to create the passphrases (passwords).

Now create a seperate mobileconfig file for each user added to the secrets file, for example myiphone.mobileconfig and add the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>IKEv2</key>
<dict>
<key>AuthName</key>
<string>(username from the ipsec.secrets in this case myiphone)</string>
<key>AuthPassword</key>
<string>(password from the ipsec.secrets for this user)</string>
<key>AuthenticationMethod</key>
<string>SharedSecret</string>
<key>ChildSecurityAssociationParameters</key>
<dict>
<key>DiffieHellmanGroup</key>
<integer>2</integer>
<key>EncryptionAlgorithm</key>
<string>3DES</string>
<key>IntegrityAlgorithm</key>
<string>SHA1-96</string>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>DeadPeerDetectionRate</key>
<string>Medium</string>
<key>DisableMOBIKE</key>
<integer>0</integer>
<key>DisableRedirect</key>
<integer>0</integer>
<key>EnableCertificateRevocationCheck</key>
<integer>0</integer>
<key>EnablePFS</key>
<integer>0</integer>
<key>ExtendedAuthEnabled</key>
<true/>
<key>IKESecurityAssociationParameters</key>
<dict>
<key>DiffieHellmanGroup</key>
<integer>2</integer>
<key>EncryptionAlgorithm</key>
<string>3DES</string>
<key>IntegrityAlgorithm</key>
<string>SHA1-96</string>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>LocalIdentifier</key>
<string>com.(your domain).ipsec.client</string>
<key>RemoteAddress</key>
<string>(host/ip of your server)</string>
<key>RemoteIdentifier</key>
<string>com.(your domain).ipsec.server</string>
<key>SharedSecret</key>
<string>(the preshared key from the ipsec.secrets)</string>
<key>UseConfigurationAttributeInternalIPSubnet</key>
<integer>0</integer>
</dict>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
<key>PayloadDescription</key>
<string>Configures VPN settings for iphone</string>
<key>PayloadDisplayName</key>
<string>My VPN</string>
<key>PayloadIdentifier</key>
<string>com.apple.vpn.managed.(run uuidgen and append results)</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadUUID</key>
<string>(run uuidgen on the commandline and copy paste here)</string>
<key>PayloadVersion</key>
<real>1</real>
<key>Proxies</key>
<dict>
<key>HTTPEnable</key>
<integer>0</integer>
<key>HTTPSEnable</key>
<integer>0</integer>
<key>ProxyAutoConfigEnable</key>
<integer>0</integer>
<key>ProxyAutoDiscoveryEnable</key>
<integer>0</integer>
</dict>
<key>UserDefinedName</key>
<string>My VPN</string>
<key>VPNType</key>
<string>IKEv2</string>
<key>VendorConfig</key>
<dict/>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>IKEv2</string>
<key>PayloadIdentifier</key>
<string>(run uuidgen on the commandline and copy paste here)</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>(run uuidgen on the commandline and copy paste here)</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

You need to create some uuid’s to fill in the marked spots in this configfile, you can do this by just running:

1
2
~$ uuidgen
fd7fc14d-0c12-4244-8668-d9dbf0a242b5

Do this four times and copy paste them in the correct places.
Replace the (your domain) with the same string used as leftid and rightid in the /etc/ipsec.conf file.
And don’t forget to copy paste the generated PSK and username/password from the ipsec.secrets and the vpn server’s host/ip into the right places.

Step 4

Routing and Testing is the final step.

uncomment the following line in /etc/sysctl.conf

1
net.ipv4.ip_forward=1

and reload the sysctl.conf

1
sudo sysctl -p /etc/sysctl.conf

now setup some basic routing for the connected VPN clients

1
2
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT

And be sure to reload all config files once in ipsec

1
sudo service ipsec restart

And you are done!

Put the myiphone.mobileconfig in your /www directory and visit the file from your iphone (or macbook etc.)
It will instantly recognize the file and add the profile as an VPN option. Just turn it On and Off directly from your Settings App.

note you will need UDP port 500 and 4500 access to the server
note2 for dhcp 10.0.0.1/24 is used so you can add 10.0.0.1 to your server’s interface and bind services to it that should be only accessible in the VPN

1
sudo ip addr add 10.0.0.1/32 dev eth0