strongSwan Server for Sierra

Apple products are notoriously finicky and poorly implement standards.  This always makes network configuration an adventure.  I have a Debian server behind a firewall running strongSwan 5.2.x as a VPN server.  Configuring the server to play nice with Android, Windows and Linux road-warriors is easy.  Getting OSX to play nice is more daunting.  After a bit of work I got an IKEv2 with IPSec tunnels working for a Sierra road-warrior.  The Raymii.org  tutorial was a great help and got me to 90%. I am not going to duplicate that page here, but most of the commands listed here are identical.  

In Debain: 

(use sudo or be root as needed)

1. Install strongSwan and the extras for charon using standard 'apt' commands. The 'libcharon-exta-plugins' package seems to be required, but not installed be default with strongSwan.

2. Create your directory structure for your certificates.

cd /etc/ipsec.d/

mkdir private

mkdir cacerts

mkdir certs

mkdir p12

The p12 directory is only used if you are using certificates for client authentication. 

3. Create a self-signed Certification Authority (CA) Key (or import a real one)

ipsec pki --gen --type rsa --size 4096 --outform der > private/organizationalKey.der

chmod 600 private/organizationalKey.der

 4. Create the root CA certificate from that key.

ipsec pki --self --ca --lifetime 3650 --in private/organizationalKey.der --type rsa --dn "C=US, O=Company Name, CN=Root CA" --outform der > cacerts/organizationalCert.der

C is for Country, O is organization name, and CN is certificate name  Adjust these as you see fit.5 

5. Verify your host's FQDN and IP.

hostname -f

hostname -I

Take note of the responses.  They will be used in the next step. 

6. Create the server's private and public keys to allow the server to authenticate its self to the client.

ipsec pki --gen --type rsa --size 4096 --outform der > private/vpnServerKey.der

chmod 600 private/vpnServerKey.der

ipsec pki --pub --in private/vpnServerKey.der --type rsa | ipsec pki --issue --lifetime 730 --cacert cacerts/organizationalCert.der --cakey private/organizationalKey.der --dn "C=NL, O=Example Company, CN=vpn.yourHost.org" --san vpn.yourHost.org --san 192.168.5.1  --san @192.168.5.1 --flag serverAuth --flag ikeIntermediate --outform der > certs/vpnServerCert.der

PAY ATTENTION HERE.  Notice the  Certificate Name (CN) and Subject Alternative Names.  For OSX to work, these MUST be correct.  The CN and SAN must be your Full Qualified Domain Name (FQDN).  This is the output from the 'hostname -f' command. The next two SAN will be the IP address from above using the 'hostname -I' command.  OSX will not authenticate if these are not correct.  My server is behind a firewall and NAT'd;  that is why I have non-routed IPs.   The FQDN does not have to match the DNS resolved name for the server, but it must match the FQDN the server thinks it has.  If you are using a dynamic DNS your resolved name might be myhost.ddns.net while your server identifies as myhost.mycompany.com.  Use the myhost.mycompany.com in the certificates.  

7.  Create your secrets file.

pico /etc/ipsec.secrets

Add:

 : RSA vpnServerKey.der

username : EAP "mySecretPreSharedKey"

This identifies the server key from Step 6 as authentication and gives a username and password for authentication. 

*******   STOP HERE if you only want to use a USERNAME and PASSWORD on OSX, Skip to Step 12  ******

Now we will create a P12 client cert for authentication. You should create one for every user and device, but one can be shared.

8. Create the private key.

ipsec pki --gen --type rsa --size 2048 --outform der > private/ClientKey.der

chmod 600 private/ClientKey.der

 

9. Create the public key.  This is signed with the CA from Step 3.

ipsec pki --pub --in private/ClientKey.der --type rsa | ipsec pki --issue --lifetime 730 --cacert cacerts/organizationalCert.der --cakey private/organizationalKey.der --dn "C=US, O=Example Company, CN=client@yourHost.org" --san "client@yourhost.org" --san "client@192.168.5.1" --outform der > certs/ClientCert.der

PAY ATTENTION HERE. Look back at the warning for Step 6.

10. Convert everything into PEM format.

openssl rsa -inform DER -in private/ClientKey.der -out private/ClientKey.pem -outform PEM

openssl x509 -inform DER -in certs/ClientCert.der -out certs/ClientCert.pem -outform PEM

openssl x509 -inform DER -in cacerts/organizationalCert.der -out cacerts/organizationalCert.pem -outform PEM

11. Make it a PKCS#12 package.

openssl pkcs12 -export -inkey private/ClientKey.pem -in certs/ClientCert.pem -name "Client's VPN Certificate" -certfile cacerts/organizationalCert.pem -caname "Root CA" -out p12/Client.p12

This will require you to set a password used to open the P12 file.  Remember the client will use this password to install the P12 on the client system.  Use a password that can be given to the client.

12. Set up the /etc/ipsec.conf file

## ipsec.conf - strongSwan IPsec configuration file

config setup  #adjust your debug ass necessary, turn this WAY down on a production server

    charondebug="ike 4, knl 4, cfg 4, net 4, esp 4, dmn 4,  mgr 4"

conn %default

    keyexchange=ikev2

    ike=aes128-sha1-modp1024,aes128-sha1-modp1536,aes128-sha1-modp2048,aes128-sha256-ecp256,aes128-sha256-modp1024,aes128-sha256-modp1536,aes128-sha256-modp2048,aes256-a$

    esp=aes128-aes256-sha1-sha256-modp2048-modp4096-modp1024,aes128-sha1,aes128-sha1-modp1024,aes128-sha1-modp1536,aes128-sha1-modp2048,aes128-sha256,aes128-sha256-ecp25$

    dpdaction=clear

    dpddelay=40

    dpdtimeout=130

    keyingtries=3

    forceencaps=yes

    type=transport

    leftfirewall=yes

    rekey=no

    left=%any

    leftid=vpn.yourhost.org

    leftsubnet=0.0.0.0/0

    leftsendcert=always

    leftcert=vpnServerCert.der

    right=%any

#Enable the IPV6 stuff if you need it

#ADJUST these IPs to match your needs

    rightdns=8.8.8.8,#,2001:4860:4860::8888 

    rightsourceip=192.168.55.230/29,#,2002:2222:2222:2::/112

    

#ANDROID

conn IPSec-IKEv2-Droid

    keyexchange=ikev2

    leftauth=pubkey

    rightauth=pubkek

    leftsendcert=always

    auto=add

#OSX with P12 cert

conn IPSec-IKEv2-OSX

    keyexchange=ikev2

    leftauth=pubkey

    rightauth=eap-tls

    leftsendcert=always

    auto=add

#OSX with USERNAME and PASSWORD

conn IPSec-IKEv2-EAP

    keyexchange=ikev2

    leftauth=pubkey

    leftsendcert=always

    rightauth=eap-mschapv2

    rightsendcert=never

    eap_identity=%any

    auto=add

include /var/lib/strongswan/ipsec.conf.inc

This is what works for me and Sierra. Make sure leftid=vpn.yourhost.org matches the cert from Step 6.

9. Restart ipsec.

ipsec restart

10. Configure your firewall and routing as needed.  If you need off the server and on the LAN don't forget echo "net.ipv4.ip_forward = 1"

On Sierra: 

1. Copy your vpnServerCert.der file from your Debian server to your Mac.  

2. Double-click the file to insert the cert into your keychain. Add it to the System  keychain.  

3. Double click the cert in the Keychain Access window to change its defaults.  Set it to 'Always Trust'. And close the windows.

    If  you are using a client certificate, repeat 1-3 for the Client.p12 file. This will require the password from Step 11 above.

4. In the System Preferences windows find Network.  In the left column click the '+' to create a new connection.

5. Set Interface to VPN and VPN Type to IKEv2. Now click Create.

6. Set Server Address to whatever works.  If you have a static IP you can use that or the DNS resolvable name.  Or you can use a dynamic domain name service or alias.  This DOES NOT have to match your FQDN from above.

7. Set Remote ID to the FQDN from Steps 5, 6 and 8 in the server setup.  This MUST be exact!

8. Click Authentication Settings... and choose Username. Enter the username and password from server Step 7.

                            -- OR --

    ...choose Certificate and select the client@yourhost.org certificate imported on the P12 file. And enter "client@yourhost.org" into the Local ID box.

Extra:

Android:

Transfer and import the P12 file to your Droid.

Create a IPSec IKEv2 RSA VPN Client.

The user and CA cert are both the P12 you imported.

Everything should work now.