Configuring StrongSwan/OpenSwan for iOS Native IPsec VPN: Complete Setup Guide with NAT Traversal


2 views

Before diving into configuration, ensure your Linux server has:

# Ubuntu/Debian
sudo apt update
sudo apt install strongswan strongswan-pki charon-systemd

iOS requires certificate authentication. Generate a CA and server certificates:

# Create private key for CA
ipsec pki --gen --type rsa --size 4096 --outform pem > ca-key.pem

# Create CA certificate
ipsec pki --self --ca --lifetime 3650 --in ca-key.pem \
    --type rsa --dn "C=US, O=MyOrg, CN=MyVPN CA" \
    --outform pem > ca-cert.pem
# Generate server key
ipsec pki --gen --type rsa --size 4096 --outform pem > server-key.pem

# Create server certificate
ipsec pki --pub --in server-key.pem --type rsa | \
    ipsec pki --issue --lifetime 730 \
    --cacert ca-cert.pem \
    --cakey ca-key.pem \
    --dn "C=US, O=MyOrg, CN=vpn.example.com" \
    --san vpn.example.com \
    --flag serverAuth --flag ikeIntermediate \
    --outform pem > server-cert.pem

Configure the main StrongSwan settings:

config setup
    charondebug="ike 2, knl 3, cfg 2"
    uniqueids=no

conn %default
    ikelifetime=60m
    keylife=20m
    rekeymargin=3m
    keyingtries=1
    keyexchange=ikev2
    ike=aes256-sha256-modp1024,aes128-sha1-modp1024!
    esp=aes256-sha256,aes128-sha1!
    mobike=no

conn ios-ikev2
    left=%any
    leftid=@vpn.example.com
    leftcert=server-cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=%any
    rightauth=eap-mschapv2
    rightsourceip=10.10.10.0/24
    rightsendcert=never
    eap_identity=%identity
    auto=add
: RSA server-key.pem

# User credentials
username : EAP "password"

Add these kernel parameters to enable NAT-T:

# /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

Essential iptables rules for NAT and forwarding:

iptables -A INPUT -p udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp --dport 4500 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
  1. Install the CA certificate on your iOS device
  2. Create new VPN configuration: IKEv2 type
  3. Server: vpn.example.com
  4. Remote ID: vpn.example.com
  5. Local ID: (leave blank)
  6. Authentication: Username/Password

Check these logs when troubleshooting:

# View StrongSwan logs
sudo journalctl -u strongswan -f

# Detailed debugging
sudo ipsec stroke loglevel cfg 2
sudo ipsec stroke loglevel knl 3

Setting up IPsec VPN with Apple's native client requires proper configuration of both server-side daemons (StrongSwan/OpenSwan) and client-side parameters. The main pain points typically involve:

  • NAT traversal configuration for routers like Linksys
  • Certificate generation and management
  • Proper IKEv2/EAP configuration

For Debian-based systems:

sudo apt-get install strongswan libstrongswan-standard-plugins \
libcharon-extra-plugins strongswan-pki

For RHEL/CentOS:

sudo yum install strongswan strongswan-pki

Create the CA private key and certificate:

ipsec pki --gen --type rsa --size 4096 --outform pem > ca-key.pem
ipsec pki --self --ca --lifetime 3650 --in ca-key.pem \
--type rsa --dn "CN=VPN CA" --outform pem > ca-cert.pem
ipsec pki --gen --type rsa --size 4096 --outform pem > server-key.pem
ipsec pki --pub --in server-key.pem --type rsa | \
ipsec pki --issue --lifetime 3650 \
--cacert ca-cert.pem --cakey ca-key.pem \
--dn "CN=vpn.example.com" --san "vpn.example.com" \
--flag serverAuth --flag ikeIntermediate --outform pem > server-cert.pem

Edit /etc/ipsec.conf:

config setup
    charondebug="ike 2, cfg 2"
    uniqueids=never

conn ios-ikev2
    auto=add
    compress=no
    type=tunnel
    keyexchange=ikev2
    fragmentation=yes
    forceencaps=yes
    ike=aes256-sha256-modp2048,aes128-sha1-modp2048!
    esp=aes256-sha256,aes128-sha1!
    dpdaction=clear
    dpddelay=300s
    rekey=no
    left=%any
    leftid=@vpn.example.com
    leftcert=server-cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=%any
    rightauth=eap-mschapv2
    rightsourceip=10.10.10.0/24
    rightdns=8.8.8.8,8.8.4.4
    eap_identity=%identity

Edit /etc/ipsec.secrets:

: RSA server-key.pem
username : EAP "password"

For Linksys routers, ensure these sysctl settings:

net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

Add these firewall rules (for iptables):

iptables -A INPUT -p udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp --dport 4500 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy \
--dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE

Transfer these files to your iOS device:

  1. CA certificate (ca-cert.pem)
  2. Client certificate if using certificate auth

On iOS:
1. Go to Settings → General → VPN → Add VPN Configuration
2. Select IKEv2 type
3. Enter server address (vpn.example.com)
4. Remote ID: vpn.example.com
5. Local ID: leave empty
6. User Authentication: Username/Password or Certificate

Check these logs when encountering issues:

sudo ipsec statusall
sudo journalctl -u strongswan -f
sudo tail -f /var/log/syslog

Common errors and solutions:

  • NAT-T failures: Ensure UDP 4500 is forwarded
  • Certificate issues: Verify timestamps and CN/SAN matches
  • EAP failures: Check username/password in ipsec.secrets