User Tools

Site Tools


IPsec Modern IKEv2 Road-Warrior Configuration

IPsec Road-Warrior Configuration: Android (app), Windows 7+ (native), iOS9+ (native) BB10 (native), PlayBook, Dtek mobile devices.

For an overview over all existing Virtual private network (VPN)-related articles in the OpenWrt wiki, please visit overview
:!: This page is about strongswan. The old outdated racoon documentation can be found here. Most of the racoon information is relevant (sort-of).

The basic context of the so called “road warrior” configuration:

  1. Your OpenWrt router is the firewalled IPsec host or gateway that receives requests to connect from mobile IPsec users
  2. IPsec users have a dynamically assigned (private) IP outside your private net which changes frequently.
  3. IPsec users frequently move around roaming across different networks.
  4. IPsec users require access to both internal and external resources (full tunnel support) through a “gateway”.

This is an IPsec IKEv2 setup that recreates the usual client-server VPN setup. Everything else (PPTP, IPsec IKEv1+xauth, L2TP/IPsec IKEv1, TUN/TAP based TLS VPN)in my opinion is obsolete and should not be used for new deployments. IKEv2 is built-in to any modern OS. It is supported in Android as well using the Strongswan app.

A note about terminology. IPsec is not a client-server protocol, and it is not a VPN protocol either. Hence, it is incorrect to talk about IPsec server or IPsec clients. However, in this page we talk about IPsec-based VPN server and clients indicating the IPsec gateway or IPsec users respectively.

This configuration makes use of various authentication mechanisms: a certificate based one and two EAP based methods using either a username/password challenge (EAP-MSCHAPv2) or certificates (EAP-TLS). They can also be used in parallel implementing a double round authentication for an added layer of security if your client supports that configuration.

Examples would be a phone or laptop that wants to VPN into a private home network. Note that Strongswan's IKEv2 with MOBIKE lets you leave VPN up ALL the time on a phone with near zero battery drain or perceptible performance hit. The benefits of this cannot be overstated for the road warrior.


  • Supported version of OpenWrt (opkg will complain about kernel version if not).
  • You probably want to have 16MB flash for strongswan to fit in. And 64MB ram to run it properly.
  • strongswan-full
  • OpenSSL (libopenssl) (to make the .p12 or PKCS#12 package you distribute to clients)
  • openssl-util (to make the .p12 or PKCS#12 package you distribute to clients)
  • If OpenWRT-LEDE version is less than 17.0.5 then patch the \lib\ file line 161 to:

modprobe $m || :

Tested on OpenWrt Barrier Breaker r37092-r39879 through to the current (July 2017) Openwrt Designated Driver 50107 on WNDR3700v2.
Tested on LEDE Reboot 17.01.4 r3560-79f57e422d / LuCI lede-17.01 branch (git-18.147.69097-36945b5) on D-Link DIR-885L
Tested on CHAOS CALMER (15.05.1, r48532) on Generic Broadcom BCM47xx board
Tested on OpenWrt 19.07 branch (git-20.057.55219-13dd17f) / OpenWrt 19.07.2 r10947-65030d81f3 on HiWiFi HC5962

To make sure Strongswan runs, you can type /etc/init.d/ipsec start

For testing, you will want to run logread in a scrolling window as follows:

logread && logread -f

We're going to edit the following:

  • /etc/strongswan.conf: Strongswan configuration file
  • /etc/ipsec.conf: Tunnel definitions
  • /etc/ipsec.secrets: List of secrets and keys
  • /etc/ipsec.d: Folder for certificates
  • /etc/config/firewall: Firewall changes to allow VPN traffic

Note after openssl-util packages installed: You may want to disable LUCI's (actually uhttp's) https redirection by commentting out the two “list listen_https” lines in /etc/config/uhttpd file.


charon {
        dns1 =
        nbns1 =
        plugins {
                include strongswan.d/charon/*.conf
include strongswan.d/*.conf

In this setup, the IKEv2 daemon will assign the router IP as DNS and WINS server to be used by remote clients. For example, here we use servers available on the private LAN, but you can use public ones as well if you like, even for debug-only purposes. If the server runs on the same device you are configuring this strongswan instance, make sure that DNS server is configured to serve local DNS queries, as requests from virtual clients will appear as originated from inside the router. The default DNS server in OpenWrt, dnsmasq, has such an option: make sure it's enabled. The load_modular option allows charon to dynamically load required plugins. Note that in earlier versions of StrongSwan (5.1.1 or earlier), you may find that charon plugins are not loading dynamically. You can spot by changing charondebug in ipsec.conf to check. If you must use an older version, try explicitly telling charon which plugins you want by adding “load = …” to charon like this:

charon {
load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac stroke kernel-netlink socket-default updown attr farp dhcp

The above issue seems to have been resolved in 5.1.2 according to the Wiki here. Replace the IP addresses with the appropriate values for your INTERNAL network. In this and other examples, I expect your private internal network to be “dns1” entry tells charon (the IKEv2 service) where to go for dns - typically the openwrt host. “nbns1” entry tells charon where to go for netbios name services if you want to use windows file sharing.


Note that server is always authenticated via public key, both for certificate-based (pubkey and eap-tls) and username/password-based (eap-mschapv2) client authentication configurations. This REQUIRES you to install certificates on the server and clients. You can choose one or more from the below example configurations, although certificate-based ones are recommended. For certificate-based configurations, if ALL your clients support this feature, you could optionally require an additional username/password-based challenge round.

config setup

conn %default



conn rwPUBKEY

conn rwEAPTLS


Explanation: The notion of “left” and “right” is explained in the strongswan documentation, but briefly, “left” here is the “Local” (Left = Local) or private net you want access to, and “right” is the “Remote” (Right = Remote) or client side.

  • The config setup block is needed but can be empty
  • The conn %default block provides default settings if you plan on adding more profiles.
  • The ike=aes256-aes128-sha256-sha1-modp3072-modp2048-modp1024 makes Windows clients connect without modifying the windows registry.
  • conn roadwarriorPUBKRYIOS is our roadwarrior configuration for pure “IKEv2 Certificate” authenticated clients (select Certificate in iOS VPN settings)
  • conn roadwarriorEAPTLSIOS is our roadwarrior configuration for “IKEv2 EAP” via EAP-TLS, aka “EAP Certificate” (select None then Certificate for iOS VPN settings)
  • conn roadwarriorPUBKRY is our roadwarrior configuration for pure “IKEv2 Certificate” authenticated clients.
  • conn roadwarriorEAPTLS is our roadwarrior configuration for “IKEv2 EAP” via EAP-TLS, aka “EAP Certificate”
  • conn roadwarriorEAPMSCHAPV2 is our roadwarrior configuration for “IKEv2 EAP” via EAP-MSCHAPv2, aka “EAP Password”
  • leftauth = pubkey tells the host to use certificates.
  • leftid = the FQDN you put in the cert as subjectAltName (see “–san” option when you make your certs below). Note that it could be anything as long as it matches what you set on the client. Use of dyndns (in example) is advised if your gateway is also assigned a dynamic address.
  • leftsubnet = the scope of VPN. is a full tunnel, meaning ALL traffic will go through the VPN. You can put if you want your clients on to use the VPN to reach ONLY those addresses and your private net is The full tunnel option is more secure because it prevents a client from acting as a bridge.
  • leftsendcert = always required by iOS native IKEv2 client
  • right = %any lets any peer IP connect. (remote user)
  • rightid = SANFORIOSCLIENT lets iOS client match its Local ID with SAN of client certificate.
  • rightdns = Feel free to enable this to push dns to clients.
  • rightsourceip = the pool of internal addresses to use for the VPN clients. You may want to assign multiple clients IPs from a subnet which doesn't overlap any of your private LANs (on, like in this example, setting to something like Note that if you have only ONE client connecting, you could use instead, which means that only 1 single host can connect and it will be given that address Otherwise, if you like the clients to be part of the same private subnet you can set this to a single address or a subnet portion which is free and not overlapping with DHCP ranges. Finally, you may alternatively set this to %dhcp and configure /etc/strongswan.d/charon/dhcp.conf accordingly if you want client's addresses to be released by DHCP.
  • rightcert = the cert the client needs
  • rightauth = pubkey as in roadwarriorPUBKEY section, requires the client to authenticate via pure IKEv2 certificates.
  • rightauth = eap-tls as in roadwarriorEAPTLS section, requires the client to authenticate via EAP using EAP-TLS method, which is another way of doing certificate based auth not directly within IKEv2.
  • #rightauth2 = eap-mschapv2 uncomment to enable, requires the client to authenticate via “IKEv2 … + EAP” which means to perform a second auth round via EAP using EAP-MSCHAPv2 method (aka “EAP username and password”), but this is not supported on iOS and Windows native IKEv2 clients. Because of strongswan limitations you can't simultaneously support both single round and double round auth for pubkey authenticated roadwarrior clients (=clients connecting from unknown network locations)
  • eap_identity = %identity tells strongswan to ask the client for its specific identity to be used in EAP auth, instead of using its IKEv2 identity (ip address).

If you want to issue personal certificates to your clients then you should verify the signing CA's identity instead of the client certificates itself. To achieve this, use the rightca=“C=US, O=yyy, CN=xxxx” directive instead of rightcert, where yyy and xxxx are what you choose in the next steps at Making Keys. More information on this: strongSwan documentation With the above configuration, you will need to also install caCert.pem on your clients in addition to the client cert - see 'Making Keys' section below.


This configures the key used by server to authenticate itself against the client, and valid client credentials for any EAP authentication round done via eap-mschapv2 with user/password.

: RSA serverKey.pem
remoteusername : EAP "secretpassword"

You can skip/ignore this last line if you don't use easp-mschapv2 authentication. Replace remoteusername and secretpassword with the values you want.

Making Keys

To make keys, run this script and follow on-screen instructions. It is intended to be run on the OpenWrt router, but you can also manually run the first half on Linux/WSL and move the needed key and certs into router thereafter.

Existing CACert would be retained for new server/client certs. Remove/rename client* if you want to regenerate clientCert for another user.

cd ~
echo "Building certificates for [ $SERVERDOMAINNAME ] and client [ $CLIENTNAME ($SANFORIOSCLIENT for iOS) ] "
if [ -f "caCert.pem" ] ; then
  echo "caCert exists, using existing caCert for serverCert and clientCert...."
  echo "generating caCert for [ $CANAME ]..."
  ipsec pki --gen --outform pem > caKey.pem
  ipsec pki --self --lifetime 3652 --in caKey.pem --dn "C=$COUNTRYNAME, O=$ORGNAME, CN=$CANAME" --ca --outform pem > caCert.pem
  openssl x509 -inform PEM -outform DER -in caCert.pem -out caCert.crt
  echo "Now building CA keys bundle, choose a secure password known by IPsec Administrator ONLY"
  openssl pkcs12 -export -inkey caKey.pem -in caCert.pem -name "$CANAME" -certfile caCert.pem -caname "$CANAME" -out ca.p12
echo "generating server certificates for [ $SERVERDOMAINNAME ]... "
ipsec pki --gen --outform pem > serverKey_$SERVERDOMAINNAME.pem
ipsec pki --pub --in serverKey_$SERVERDOMAINNAME.pem | ipsec pki --issue --lifetime 3652 --cacert caCert.pem --cakey caKey.pem --dn "C=$COUNTRYNAME, O=$ORGNAME, CN=$SERVERDOMAINNAME" --san="$SERVERDOMAINNAME" --flag serverAuth --flag ikeIntermediate --outform pem > serverCert_$SERVERDOMAINNAME.pem
#openssl x509 -inform PEM -outform DER -in serverCert_$SERVERDOMAINNAME.pem -out serverCert_$SERVERDOMAINNAME.crt
if [ -f "clientCert.pem" ] ; then
  echo "clientCert exists, not generating new clientCert."
  echo "generating clientCert for [ $CLIENTNAME ($SANFORIOSCLIENT for iOS) ]..."
  ipsec pki --gen --outform pem > clientKey.pem
  ipsec pki --pub --in clientKey.pem | ipsec pki --issue --lifetime 3652 --cacert caCert.pem --cakey caKey.pem --dn "C=$COUNTRYNAME, O=$ORGNAME, CN=$CLIENTNAME" --san="$CLIENTNAME" --san="$SANFORIOSCLIENT" --outform pem > clientCert.pem  #--san="$CLIENTNAME@$SERVERDOMAINNAME"
  openssl x509 -inform PEM -outform DER -in clientCert.pem -out clientCert.crt
  echo "Now building Client keys bundle, choose a secure password known by Client ONLY (this password will only be required to install certificate and key, not for IPsec authentication)"
  openssl pkcs12 -export -inkey clientKey.pem -in clientCert.pem -name "$CLIENTNAME" -certfile caCert.pem -caname "$CANAME" -out client.p12
  openssl x509 -inform PEM -outform DER -in clientCert.pem -out clientCert.crt
# where to put them
cp caCert.pem /etc/ipsec.d/cacerts/
echo "copy ca.p12 /somewhere/safe/on/your/pc (includes caCert and caKey, needed to generate more certs for more clients)"
cp serverCert*.pem /etc/ipsec.d/certs/
cp serverKey*.pem /etc/ipsec.d/private/ # keep on your router only, delete and regenerate a fresh one if router gets compromised
cp clientCert.pem /etc/ipsec.d/certs/ # not needed if you authenticate via righca instead of rightcert
echo "copy client.p12 /somewhere/safe/on/your/clients"
echo "copy caCert.crt and clientCert.crt to /somewhere/safe/on/your/clients for Android clients"

Now install client.p12 on the clients. Note that caCert has been included already in the client.p12 if you used the above commands. If the client platform requires you to install the CA certificate separately, extract that cert from client.p12 or use the caCert.crt file, then install it.


Add the following to your firewall configuration. You can use Luci for this.

config rule 'ipsec_esp'
	option src 'wan'
	option name 'IPSec ESP'
	option proto 'esp'
	option target 'ACCEPT'
config rule 'ipsec_ike'
	option src 'wan'
	option name 'IPSec IKE'
	option proto 'udp'
	option dest_port '500'
	option target 'ACCEPT'
config rule 'ipsec_nat_traversal'
	option src 'wan'
	option name 'IPSec NAT-T'
	option proto 'udp'
	option dest_port '4500'
	option target 'ACCEPT'
config rule 'ipsec_auth_header'
	option src 'wan'
	option name 'Auth Header'
	option proto 'ah'
	option target 'ACCEPT'

Explanation: Basically you're opening up the ports/protocols on the WAN zone that strongswan needs to accept traffic from a client. You can also create a custom zone called “VPN” if you want to get fancy.

You will also need additional rules in /etc/firewall.user. Note that strongswan mentions the leftfirewall=yes setting in ipsec.conf which used to add the iptables entries using the _updown script in /usr/libexec/ipsec/_updown but this has been deprecated and doesn't do anything.


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
iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT

Explanation: You're accepting INPUT, FORWARD(in/out) and OUTPUT traffic originated from and directed to clients matching an IPsec policy. The last rule exempts traffic that matches an IPsec policy from being NAT-ed before tunneling. You wouldn't be able to reach or ping roadwarrior clients without this last rule.

You'll need to setup NAT (or SNAT) for your vpn clients to be able to access internet if you are running on a typical openwrt router which is NATing.


something like:

iptables -t nat -I POSTROUTING -s -o pppoe-wan -j MASQUERADE


For testing, I used a Blackberry Z10 with NATIVE Ikev2 support (LOVE your Blackberry), an android phone with the StrongSwan Client, Windows 7 and 10 machines using native IKEv2, and a Blackberry DTek running Android with Dtek.

You can email client.p12 (and caCert, if needed) to the mobile clients.

For BlackBerry Clients

as PUBKEY roadwarriors

BlackBerry allows you to specify Perfect Forward Secrecy. You will want/need this. This should be standard. If you have problems, try adding the following lines to the ipsec.conf file in the conn roadwarriorPUBKEY section:


What this does is specify what cipher suites to use, including the Diffie Hellman Groups; you can read about these settings in the strongswan IKEv2 cipher suite documentation. Previously (before Strongswan 5.x), you'd use the pfs=yes statement. This has been deprecated.

Import your certificates into the Berry first, then add a VPN profile with the following settings:

  • Your gateway type will be “Generic IKEv2 VPN Server”,
  • Authentication Type = PKI,
  • Authentication ID Type= Identity Certificate Distinguished Name
  • Client Certificate = The name of your client cert (“myvpnclient” in the above example)
  • Gateway Auth Type = PKI
  • Gateway Auth ID Type = Identify Certificate Distinguished Name
  • Gateway CA Certificate = your server Certificate name (“xxxx” in the above example)
  • Perfect Forward Secrecy = On (VERY IMPORTANT)
  • Automatically determine IP = ON
  • Automatically determine DNS = ON
  • Automatically determine algorithm = ON

The rest can be left to defaults.

If you receive Authentication Error you can try to use distuingished name (DN) of your server's certificate instead of the FQDN for the leftid property. It is “C=US, O=yyy,” in the example above, but you can find out yours using the command below and looking for the “Subject” field

openssl x509 -in /etc/ipsec.d/certs/serverCert.pem -text -noout

For Windows 7+ Clients

You'll need “ike=aes256-aes128-sha256-sha1-modp3072-modp2048-modp1024” in ipsec.conf for windows clients to connect.

as PUBKEY roadwarriors

You will need administrative rights to setup this kind of VPN connection. Only traditional desktop editions are supported.

In windows, import your client and CA certificates into Local Machine storage, not Current User. If you followed this tutorial the CA certificate is already in bundle with the client cert into the client.p12 package, just take care of importing, again, into Local Machine and keep selected the option to automatically choose appropriate certificate store. At the end of the import you should have the CA into “Trusted Root Certification Authorities\Certificates” store and the client cert into “My\Certificates” store.

Follow these instructions to setup the Windows VPN connection for using Machine Certificates:

as EAPTLS roadwarriors

You don't need administrative rights to setup this kind of VPN connection. Modern WinRT based editions are also supported (including WP8+ mobile editions).

In windows, import your client and CA certificate into Current User, not Local Machine. If you followed this tutorial the CA certificate is already in bundle with the client cert into the client.p12 package, just take care of importing, again, into Current User and keep selected the option to automatically choose appropriate certificate store. At the end of the import you should have the CA into “Trusted Root Certification Authorities\Certificates” store and the client cert into “My\Certificates” store.

Create a new VPN connection from the wizard, choose IKEv2 as type and select “Certificate” for authentication method. Connect, and pick your “myvpnclient” cert when prompted. Please note, split-tunneling is enabled by default in Windows 10+ (just google for “disable Split Tunneling windows” or read here:

For Android Clients

as PUBKEY roadwarriors

In Android, go to “Settings > Security” to import certificates.

If you can see both client certificate and ca certificate in the Trusted Credentials - User, you can use “IKEv2 Certificate” or “IKEv2 Certificate + EAP”

In the Strongswan client, specify “IKEv2 Certificate” (“+ EAP” if you enabled second round auth) as the type of VPN, pick “myvpnclient” for the certificate you just imported, and eventually specify the username/password combo you added to /etc/ipsec.secrets for second round auth. Keep an eye on the log file (see above) during initial login to spot any issues.

If you get a ciphersuite proposal error in your log (eg. “… inacceptable, requesting …”, “NO_PROPOSAL_CHOSEN”, “no acceptable proposal found”), you need to override default ciphersuites proposal in your StrongSwan VPN Profile with something your router supports.

To do that, click Edit on the Profile, and scroll to the bottom to Advanced settings. At the bottom, you will find a section called Algorithms.

If the error relates to IKE_SA, edit IKEv2 Algorithms, downgrade to aes256-sha256-modp1024 or whatever crypto algorithms your router supports for IKE.
If the error relates to CHILD_SA, edit IPsec/ESP Algorithms, downgrade to aes256-sha256 or aes256-sha1 or aes128-sha1 or whatever crypto algorithms your router supports for ESP.
Save, and then try to connect again. Please, avoid using weak or broken algorithms, and also avoid using too strong ESP algorithms your router doesn't handle with good performance.

If you can only see CA certificate in Android certificate storage, strongswan client app would probably unable to pick up your client certificate too. But you can still use IKEv2 + MSCHAPv2 aka “IKEv2 EAP (Username/Password)”, simply input username/password as you've set in ipsec.secrets and server hostname, then you should be up and running.

For iPhones/iOS Clients

as PUBKEY roadwarriors

Versions of iOS prior to iOS 9, like Android, only support IKEv1. This setup is not recommended. For versions of iOS prior to iOS 9, you will need to use an app to use IKEv2. Cisco's Anyconnect may work, but has not been tested.

Beginning with iOS 9, IKEv2 connections are natively supported. However, iOS9 only supports the use of certificates or username/password, but not both. Therefore, the native IKEv2 implementation in iOS 9 will not work with second round auth enabled. If you wish to use both certificates and username/passwords together for iOS 9 clients of your IPsec VPN, you will have to use a third-party application like Cisco's Anyconnect, but has not been tested.

To use the native IKEv2 support:

You must install the CA certificate (caCert.crt) and the personal certificate (client.p12) onto the device, such as by access through iCloud drive or an email attachment. You do not need to set the CA certificate to be trusted for web sites. You'll need to do it one at a time. And make sure they are marked green as “verified”. Install the CA certificate again if one is still “unverified” although you've done both.

iOS 12 client requires an additional directive leftsendcert=always in the ipsec.conf connection profile example above.

Sample iOS configuration, from Settings→VPN→Add Configuration…

Type: IKEv2
Description: <your choice>
Server: <domain name of VPN server:>
Remote ID: <same as Server>
Local ID: <SANFORIOSCLIENT matches one of the client certificate san $SANFORIOSCLIENT as well as the rightid in ipsec.conf in IOS related connection settings>
User Authentication: None
Use Cerificiate: enabled
Certificate: select the certificate imported from client.p12


Type: IKEv2
Description: <your choice>
Server: <domain name of VPN server:>
Remote ID: <same as Server>
Local ID: <SANFORIOSCLIENT matches one of the client certificate san $SANFORIOSCLIENT as well as the rightid in ipsec.conf in IOS related connection settings>
User Authentication: Certificate
Certificate: select the certificate imported from client.p12


Type: IKEv2
Description: <your choice>
Server: <domain name of VPN server:>
Remote ID: <same as Server>
Local ID: <can be left blank>
User Authentication: Username
Username: <the one you set in ipsec.secrets>
Password: <the one you set in ipsec.secrets>

Note: the last config above needs only caCert.crt to be installed on iOS

If you encounter “no matching peer config found” error (in the strongswan machine's log), please check “Local ID” on the iSO client side is set correctly as the rightid in ipsec.conf and matches one of the SANs of the client certificate.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
docs/guide-user/services/vpn/ipsec/strongswan/roadwarrior.txt · Last modified: 2020/04/04 16:23 by sunshinejnjn