StrongSwan IKEv2 iOS road-warrior server config
Note: this is an old post from 2016 and hasn’t been updated nor reviewed since. Nowadays I would recommend using Wireguard which is harder to configure insecurely, or at least use something like OpenWrt which provides a nice GUI to configure IKEv2.
Here’s a really basic Strongswan configuration for a single client, authenticated using a PSK. This has been successfully tested with iOS 10 but should work on any other decent OS. It can be useful to secure traffic from public Wi-Fi or a compromised/evil mobile carrier.
Install #
Compile and install Strongswan with swanctl support, as most distros’ packages don’t yet have that feature enabled. [2026 note: this is unlikely to be necessary anymore - packaged versions should support this by now]
Configuration #
Save the following as /etc/swanctl/swanctl.conf and adjust it according to your setup. Don’t forget to set a secret PSK.
connections {
myconn {
unique = replace
pools = v4pool, v6pool
local {
id = gateway.example.com # server's ID, corresponds to "remote ID" on iOS
auth = psk
}
remote {
id = someone.example.com # client's ID, corresponds to "local ID" on iOS
auth = psk
}
children {
child {
local_ts = 0.0.0.0/0, ::/0
}
}
}
}
secrets {
ike {
id = gateway.example.com # use the values defined above
id = someone.example.com
secret = keepthisreallysecret # shhh!
}
}
pools {
v4pool {
addrs = <an IP or subnet routed to the gateway>
dns = <DNS resolver for the client> # you can run a resolver on the gateway itself if you want
}
v6pool {
addrs = <IPv6 or subnet>
dns = <IPv6 DNS resolver>
}
}
You should have an IP address or subnet routed to the VPN gateway for this to work. For IPv4 you could in theory use a private subnet and do NAT.
Enable IP forwarding as well, by creating /etc/sysctl.d/90-forwarding.conf with the following contents:
net.ipv4.conf.all.forwarding = 1
net.ipv6.conf.all.forwarding = 1
And apply the changes right away by loading the file:
sysctl -p /etc/sysctl.d/90-forwarding.conf
Adjust your firewall rules if necessary. You need to allow ESP packets for the inbound encrypted packets themselves, and UDP packets with destination ports 500 and 4500 for the IKE key exchange.
For the actual data, you can target packets with IPtables’ policy module, using the ipsec policy.
If using NAT you should also add the corresponding entry in the NAT table, something like:
iptables -t NAT -A POSTROUTING -s <assigned IP or subnet> -j MASQUERADE
Enable and start Strongswan by activating its systemd service:
systemctl enable --now strongswan-swanctl.service
Connect to it from your IOS device and it should just work.