Strongswan VPN for iOS quick-start guide

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.

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 = # server's ID, corresponds to "remote ID" on iOS
            auth = psk
        remote {
            id = # client's ID, corresponds to "local ID" on iOS
            auth = psk
        children {
            child {
                local_ts =, ::/0

secrets {
    ike {
        id = # use the values defined above
        id =
        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 but that sucks so avoid if possible.

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

Make Strongswan start at boot by activating its systemd service:

systemctl enable strongswan-swanctl.service

Start the server #

Finally let’s start everything and try it out:

systemctl start strongswan-swanctl.service

Connect to it from your IOS device and it should just work.


Now read this

Setting an alternative shell in macOS Terminal

After switching to Zsh on my new Mac I noticed a little issue with the built-in Terminal. When using the default Bash shell, the app could tell whether a process (besides the shell) was running in it and present a confirmation if you... Continue →