Long title, I know. First some background, I’ve tried this in the past and haven’t been able to get it to work. I tried it this weekend and had it working in no time at all so that’s good. This is the first cut of this guide so I might update it as OpenWRT changes and as I optimize my configuration or write a new post if it seems like a better way to go.

First off, my environment is a Netgear WNDR3700 running Barrier Breaker 14.07. The IOS device used is an iPhone 6 running IOS 8.1.2. Although there are guides out there for this I thought it might need a little more detail given I had some problems with my firewall on the router and certificate verification on the IOS device introduced in IOS 8. I used StrongSwan as my VPN terminator.

1 - Install Required Packages

Log into router using SSH (I’m using the shell for my instructions here) and run the following:

opkg update

opkg install strongswan-default strongswan-mod-dhcp strongswan-mod-af-alg strongswan-mod-gcrypt strongswan-mod-blowfish strongswan-mod-md4 strongswan-mod-openssl strongswan-mod-pkcs11 strongswan-mod-pkcs8 strongswan-mod-test-vectors strongswan-mod-farp strongswan-mod-kernel-libipsec kmod-tun openssl-utils

This should install all the required packages.

2 – Add Required Configuration

Add the following section to your /etc/ipsec.conf file:

conn ios
         keyexchange=ikev1
         authby=xauthrsasig
         xauth=server
         left=%any
         leftsubnet=0.0.0.0/0
         leftfirewall=yes
         leftcert=serverCert.pem
         right=%any
         rightsubnet=192.168.1.0/24
         rightsourceip=%dhcp
         rightcert=clientCert.pem
         forceencaps=yes
         auto=add

Make sure you change 192.168.1.0/24 to the whole subnet on the LAN side of your router. This configuration will cause the client device to be automatically allocated an IP address from your dynamically allocated range on the LAN side of your router as though it was joining the network via WIFI or wired ethernet connection.

Add the following to your /etc/ipsec.secrets file:

: RSA serverKey.pem
anyuser : XAUTH "anypassword"

Replace user and password with a username and password of your choice (this will be the “account” and “password” fields on your IOS device).

Replace your /etc/strongswan.conf with the following:

# strongswan.conf - strongSwan configuration file

charon {

        dns1 = 192.168.1.1

        threads = 16

        plugins {

                dhcp {
                        server = 192.168.1.1
                }
        }

}

pluto {

}

libstrongswan {

        #  set to no, the DH exponent size is optimized
        #  dh_exponent_ansi_x9_42 = no
}

Replace 192.168.1.1 with the LAN IP address of your OpenWRT router.

Add the following to your /etc/firewall.user file in order to permit ipsec traffic:

iptables -I INPUT  -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD  -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD  -m policy --dir out --pol ipsec --proto esp -j ACCEPT
iptables -I OUTPUT   -m policy --dir out --pol ipsec --proto esp -j ACCEPT

Add the following to your /etc/config/firewall file in order to permit ipsec traffic:

config rule
 option src 'wan'
 option proto 'esp'
 option target 'ACCEPT'

config rule
 option src 'wan'
 option proto 'udp'
 option dest_port '500'
 option target 'ACCEPT'

config rule
 option src 'wan'
 option proto 'udp'
 option dest_port '4500'
 option target 'ACCEPT'

config rule
 option src 'wan'
 option proto 'ah'
 option target 'ACCEPT'

3 – Certificate Generation

Generate the CA Certificate

Run the following commands to generate the CA key. You may leave all the certificate details as below or you may set the certificate attributes if you want. There are no requirements on the CA Key for IOS:

ipsec pki --gen --outform pem > caKey.pem
ipsec pki --self --in caKey.pem --dn "C=DE, O=xxx, CN=xxxx" --ca --outform pem > caCert.pem

Generate and Sign the Server Certificate

Run the following commands to generate the server side (OpenWRT router) certificate and sign it with your custom CA certificate:

ipsec pki --gen --outform pem > serverKey.pem
ipsec pki --pub --in serverKey.pem | ipsec pki --issue --cacert caCert.pem --cakey caKey.pem --dn "C=DE, O=xxx, CN=xxx.dyndns.org" --san="xxx.dyndns.org" --flag serverAuth --flag ikeIntermediate --outform pem > serverCert.pem

Here you must replace xxx.dyndns.org with the Hostname or IP address you are entering into the “server” field on your IOS device. The IOS device will validate the certificate and that will fail if it does not match when you try to create the VPN connection on your IOS device.

Generate and Sign the Client Certificate

Run the following commands to generate the client side (IOS device) certificate and sign it with your custom CA certificate:

 ipsec pki --gen --outform pem > clientKey.pem
 ipsec pki --pub --in clientKey.pem | ipsec pki --issue --cacert caCert.pem --cakey caKey.pem --dn "C=DE, O=xxx, CN=client" --outform pem > clientCert.pem

Now you have to convert the certificate to the format IOS is after. When you get prompted for a password you must specify one, if you don’t you will not be able to install the certificate as IOS prompts for one even when one doesn’t exist and the field on IOS won’t validate if it’s blank:

openssl pkcs12 -export -inkey clientKey.pem -in clientCert.pem -name "client" -certfile caCert.pem -caname "xxxx" -out clientCert.p12

Copy the Certificates
You now have to copy the certificates to where Strongswan expects them:

cp caCert.pem /etc/ipsec.d/cacerts/
cp serverCert.pem /etc/ipsec.d/certs/
cp serverKey.pem /etc/ipsec.d/private/
cp clientCert.pem /etc/ipsec.d/certs/
cp clientKey.pem /etc/ipsec.d/private/

5 – Start OpenSwan

Run /etc/init.d/ipsec start to start OpenSwan (make sure there are no errors). Set OpenSwan to start at bootup using /etc/init.d/ipsec enable.

6 – Additional Firewall Setting

I had trouble with my firewall so this section is a bit of a workaround. Under “Firewall” settings in the web interface on the router change “Forward” to “accept”. Without this I could only ever get connectivity to the router itself but nothing on the LAN. Once I enabled this setting I was able to get full access as though I was on the local LAN.

7 – Send Certificates to the IOS Device and Create VPN Setting

Download caCert.pem and clientCert.p12 from your router and then email them to an email account you have on the iPhone. Open the email on your iPhone and import the certificates by tapping on the attachments. I’m not including screenshots of this bit because it is quite straightforward. If you need them let me know and I’ll expand this article.

Create a VPN configuration and select IPSec.

  • Server : VPN Server, remember this hostname/IP must match the CN attribute in the client certificate or it won’t validate
  • Account/Password : The username/password from the ipsec.secrets file
  • Use Certificate : Set to on
  • Certificate : Select the client certificate imported earlier

iPhone VPN Setup

At this point you should be able to turn the VPN on on your IOS device and it should connect fine. If you have problems I suggest you check the log on your OpenWRT router, there is a great deal of information about connectivity and authentication in the logs that should help you.