The interoperability of IPsec implementations on various platforms has been becoming better and better over the last few years. For example, Windows 7 and newer releases fully support the IKEv2 (RFC 4306) and MOBIKE (RFC 4555) standards, and iOS started to support configuration of IKEv2 in the GUI since version 9.0.
In this tutorial, we'll install strongSwan 5.3.3 in openwrt 15.05, configure it to provide IKEv2 service with public key authentication of the server and username/password based authentication of the clients using EAP-MSCHAP v2, and finally setup the VPN clients in Windows, Android and iOS so they can connect to it. Much of the complexity of IKEv2 configuration lies in the creation of SSL certificates.
First of all, install necessary strongSwan packages in openwrt 15.05:
root@OpenWrt:~# opkg update root@OpenWrt:~# opkg install strongswan-minimal strongswan-mod-eap-mschapv2 strongswan-mod-eap-identity strongswan-mod-constraints strongswan-mod-md5 strongswan-mod-pem strongswan-mod-pkcs1 strongswan-mod-revocation
Creating CA and server certificates
I recommend using XCA to create and maintain your root CA for your IKEv2 service. iOS silently refuses to trust CA certificates with MD5 signatures. So make sure to create CA certificates with SHA1, or better SHA256, signatures. Export your CA certificate in DER format. In the configuration example below, our CA cert is exported as file ZhangsRootCA2.cer. You are advised to upload the CA certificate to a secured web server or mail it to your own E-mail accounts.
Different IPsec implementations have different requirements on the server certificate. See the strongSwan wiki article for details. These requirements can be satisfied in XCA by making the following changes to a new certificate based on its HTTPS_server template:
- Add "IP security end entity" to "X509v3 Extended Key Usage" attribute.
Add all domain names and IP addresses of the IPsec server to the "X509v3 Subject Alternative Name" in the type of DNS and IP. IP addresses can be added to the SAN attribute as both DNS and IP to achieve best compatibility.
Here are the important details of an example IPsec server certificate created using XCA:
X509v3 Extended Key Usage: TLS Web Server Authentication, IP security end entity
X509v3 Subject Alternative Name: DNS:openwrt, DNS:openwrt.lan, DNS:ipsec.example.com, DNS:192.168.1.1, DNS:10.8.0.1, IP Address:192.168.1.1, IP Address:10.8.0.1
Netscape Cert Type: SSL Server
Export the server cert and the server key as openwrt.cer and openwrt.der respectively. The server key should only be stored in openwrt.
- Save the CA certificate in folder /etc/ipsec.d/cacerts/.
Save the server key as /etc/ipsec.d/private/openwrt.der. Change the file permission of the key file to 0600:
# chmod 0600 /etc/ipsec.d/private/*
- Save the server certificate as /etc/ipsec.d/certs/openwrt.cer.
# ipsec.conf - strongSwan IPsec configuration file # basic configuration config setup # strictcrlpolicy=yes # uniqueids = no uniqueids=never conn roadwarrior-ikev2 keyexchange=ikev2 dpdaction=clear dpddelay=60s dpdtimeout=300s rekey=no left=%any leftid=openwrt leftcert=openwrt.cer leftauth=pubkey leftsendcert=always leftsubnet=0.0.0.0/0 leftfirewall=yes right=%any rightauth=eap-mschapv2 rightsourceip=<CIDR> rightdns=<DNS.Server> eap_identity=%identity auto=add
Note: rightsourceip can specify an IP address pool in the form of CIDR notation. rightdns specifies the IP address of the DNS server that the IPsec clients should use.
# /etc/ipsec.secrets - strongSwan IPsec secrets file : RSA openwrt.der Username : EAP "PASSWORD"
If you want to connect from the WAN side, add the following configuration to /etc/config/firewall:
# allow incoming IPsec connections 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
and then restart the firewall:
root@OpenWrt:~# /etc/init.d/firewall restart
Circumventing the PMTUD Problem
It's a common practice in IPsec implementations to set the MTU of the IPsec tunnel interface to 1400 or lower. You won't experience Path MTU Discovery problems if the MTU of your WAN interface is standard, which is 1500 in the case of Ethernet, or 1492 in the case of PPPoE. However, if the MTU of your WAN interface is significantly lower than 1500, you need to set the MTU of the installed routes for IPsec clients to a value lower than 1400, which can be achieved using the strongswan kernel-netlink module.
The MTU of my PPPoE WAN interface is 1442. To prevent IPsec clients from running into PMTUD problems, I have to change the mtu option in /etc/strongswan.d/charon/kernel-netlink.conf to around 1350:
# MTU to set on installed routes, 0 to disable. mtu = 1352
Now stop the IPsec IKE daemon and restart it in foreground, so that we can immediately see its log messages on the ssh console:
root@OpenWrt:~# ipsec stop root@OpenWrt:~# ipsec start --nofork
After testing is done, interrupt the ipsec start --nofork command by pressing Ctrl-C and start ipsec again by typing the following command:
root@OpenWrt:~# ipsec start
We can check the detailed information about connections by typing the ipsec status and ipsec statusall commands.
root@OpenWrt:~# ipsec status root@OpenWrt:~# ipsec statusall
- Install the official strongSwan app.
Import the CA certificate ZhangsRootCA2.cer. When opening the certificate, you'll be prompted whether to open with the android "Certificate Installer" or the strongSwan "Import certificate" utility. If you're using the CA certificate for IPsec only, you may import it to the strongSwan app, instead of the system certificate store of your Android device.
Open the strongSwan app, and tap ADD VPN Profile.
Edit the profile as follows. Uncheck the Select automatically option under "CA certificate:" and manually select the CA certificate we just imported. Tap Save.
- Import the CA certificate. As of iOS 9.2.1, a reboot is apparently necessary for the certificate import to take effect.
Open Settings / VPN, tap Add VPN Configuration.... Enter all the necessary information as follows, and then tap Done.
Description: Profile name
Server: Server Address
Remote ID: commonName (CN) of Server Certificate
- Import the CA certificate to the system certificate store:
Double-click the certificate file, click Open and then Install Certificate.... You must choose Local Computer as Store Location. On the Certificate Store popup, choose the option Place all certificates in the following store. Click Browse... and choose the Trusted Root Certification Authorities / Certificates folder. Click Next and then Finish to complete the certificate import.
Click the Windwos Start menu / Settings / Network and Internet / VPN / Add VPN Connection. Enter information as shown in the following screenshot. Click Save.
By default, Windows 10 IPsec client adds a route to the remote network based on its IPv4 address class. If you want to set the default gateway on the remote network, you need to change the adapter settings of the VPN connection:
On the Network and Internet / VPN settings page, click Change Adapter Settings. Right-click the VPN connection you just created and then click Properties / Networking tab / Internet Protocol Version 4 (TCP/IPv4) / Properties / Advanced(V).... On the Advanced TCP/IP Properties dialog, check Use default gateway on the remote network. Click the OK buttons to close the configuration dialogs you just opened.
Note: Although Windows 10 can successfully get the remote DNS server addresses when establishing IPsec connections, it keeps querying the local DNS servers for resolving domain names. This can cause connectivity issues for GSLB (Global Server Load Balancing) domain names and those domain names under DNS-poisoning attacks. In such cases, you're strongly advised to use a http proxy or a socks5 proxy server on the remote network.
The NetworkManager strongswan plugin hasn't improved much over the years. It doesn't work with EAP-MSCHAPv2 and its pre-shared key option doesn't even include an input box for the key. We'll have to stick with file-based configuration in Ubuntu 18.04.
- Install necessary packages:
$ sudo apt update $ sudo apt install strongswan libcharon-extra-plugins
- Edit /etc/ipsec.conf:
config setup # strictcrlpolicy=yes # uniqueids=no conn WR720Nv2 left=<Own.Address> leftsourceip=%config4 leftfirewall=yes leftauth=eap-mschapv2 eap_identity=<Username> right=<Server.Address> rightauth=pubkey rightid=openwrt rightsubnet=<Subnet> auto=start
- Put your password in /etc/ipsec.secrets:
Username : EAP "PASSWORD"
- Save the CA certificate file in folder /etc/ipsec.d/cacerts.
Reload the IKE daemon:
$ sudo ipsec reload
As with the server configuration in OpenWrt, you can use commands ipsec status and ipsec statusall to check your connection status.