Skip to main content Logo (IEC resistor symbol)logo

Quis custodiet ipsos custodes?
Home | About | All pages | RSS Feed | Gopher

IPSEC VPN on Centos 7 with StrongSwan

Published: 30-12-2014 | Author: Remy van Elst | Text only version of this article

Table of Contents

This is a guide on setting up an IPSEC VPN server on CentOS 7 using StrongSwanas the IPsec server and for authentication. It has a detailed explanation withevery step. We choose the IPSEC protocol stack because of recent vulnerabilitiesfound in pptpd VPNs and because it is supported on all recent operating systemsby default.

Why a VPN?

More than ever, your freedom and privacy when online is under threat.Governments and ISPs want to control what you can and can't see while keeping arecord of everything you do, and even the shady-looking guy lurking around yourcoffee shop or the airport gate can grab your bank details easier than you maythink. A self hosted VPN lets you surf the web the way it was intended:anonymously and without oversight.

A VPN (virtual private network) creates a secure, encrypted tunnel through whichall of your online data passes back and forth. Any application that requires aninternet connection works with this self hosted VPN, including your web browser,email client, and instant messaging program, keeping everything you do onlinehidden from prying eyes while masking your physical location and giving youunfettered access to any website or web service no matter where you happen tolive or travel to.

This tutorial is available for the following platforms:

If you like this article, consider sponsoring me by trying out a Digital OceanVPS. With this link you'll get $100 credit for 60 days). (referral link)

IPSEC encrypts your IP packets to provide encryption and authentication, so noone can decrypt or forge data between your clients and your server. It alsoprovides a tunnel to send data to the server.

To work trough this tutorial you should have:

I do all the steps as the root user. You should do to, but only via * -i* or *su -*.

Version History:

No L2TP?

The previous tutorials all used L2TP to set up the VPN tunnel and use IPSEC onlyfor the encryption. With the IKEv2 protocol and recent operating systems (likeOS X 10.8+, Android 4+, iOS 6+ and Windows 7+) supporting IKEv2 we can also useIPSEC to set up the tunnel, before we used IPSEC to do that.

This VPN will therefore not work out of the box on older operating systems. Seemy other tutorials with L2TP on how to do that.


The tutorial consists out of the following steps:

Android and Windows client configuration is covered at the end of the tutorial.

Install EPEL 7:

Strongswan packages are available in the EPEL. The CentOS/RHEL repo's only shipLibreswan, which is not what we'll use in this tutorial. You can read more aboutthe EPEL here:, packages can be foundhere:

Install and enable the EPEL using Yum:

yum install

Install Strongswan

After the EPEL is enabled we can install StrongSwan. StrongSwan is a descendantof FreeS/WAN, just like Openswan or Libreswan. Strongswan however has a veryactive community and is actively developed, whereas the other ones are less. Youcan read more about Strongswan on wikipedia or their website.

yum install strongswan


The VPN server will identify itself with a certificate to the clients. Theclients can use a certificate to authenticate themself, this tutorial howeverkeeps it simple and sets up username and password authentication as well.

On Android with the StrongSwan Application you can just import the .p12 we aregoing to create later on. On Windows 7, we'll use EAP to configure a usernameand password for our client.

You might want to install haveged to speed up the key generation process:

yum install havegedsystemctl enable havegedsystemctl start haveged

Haveged provides a constant source of entropy and randomness.

Start by creating a self singed root CA. Create a private key:

cd /etc/strongswanstrongswan pki --gen --type rsa --size 4096 --outform der > ipsec.d/private/strongswanKey.derchmod 600 ipsec.d/private/strongswanKey.der

Next generate a self signed root CA certificate:

strongswan pki --self --ca --lifetime 3650 --in ipsec.d/private/strongswanKey.der --type rsa --dn "C=NL, O=Example Company, CN=strongSwan Root CA" --outform der > ipsec.d/cacerts/strongswanCert.der

You can view the certificate properties with the following command:

strongswan  pki --print --in ipsec.d/cacerts/strongswanCert.der

Example output:

cert:      X509subject:  "C=NL, O=Example Company, CN=strongSwan Root CA"issuer:   "C=NL, O=Example Company, CN=strongSwan Root CA"validity:  not before Dec 24 07:40:57 2014, ok           not after  Dec 21 07:40:57 2024, ok (expires in 3649 days)serial:    74:3b:96:ab:4c:14:1d:78flags:     CA CRLSign self-signedsubjkeyId: d8:fb:1f:ae:15:7c:02:4c:d7:95:bc:dd:9c:40:e4:db:33:38:8a:b4pubkey:    RSA 4096 bitskeyid:     c6:3a:c8:2e:31:cf:12:aa:67:4f:7c:da:65:3c:4f:84:bc:69:46:02subjkey:   d8:fb:1f:ae:15:7c:02:4c:d7:95:bc:dd:9c:40:e4:db:33:38:8a:b4

Generate the VPN Host key. This is the keypair the VPN server host will use toauthenticate itself to clietns. First the private key:

strongswan pki --gen --type rsa --size 2048 --outform der > ipsec.d/private/vpnHostKey.derchmod 600 ipsec.d/private/vpnHostKey.der

The public key:

strongswan pki --pub --in ipsec.d/private/vpnHostKey.der --type rsa | strongswan pki --issue --lifetime 730 --cacert ipsec.d/cacerts/strongswanCert.der --cakey ipsec.d/private/strongswanKey.der --dn "C=NL, O=Example Company," --san --san --san  --san @ --flag serverAuth --flag ikeIntermediate --outform der > ipsec.d/certs/vpnHostCert.der

The domain name or IP address of your VPN server, which is later entered in theclients connection properties, MUST be contained either in the subjectDistinguished Name (CN) and/or in a subject Alternative Name (--san). If thisdoes not match the clients will fail to connect.

The built in Windows 7 VPN client needs the serverAuth extended key usage flagin your host certificate as shown above, or the client will refuse to connect.In addition, OS X 10.7.3 or older requires the ikeIntermediate flag, which wealso add here.

We add the IP address twice, one with an @ in front so that it gets added asan subjectAltName of the dNSName type and one of the iPAddess type.

Let's view the certificate:

strongswan pki --print --in ipsec.d/certs/vpnHostCert.der


cert:      X509subject:  "C=NL, O=Example Company,"issuer:   "C=NL, O=Example Company, CN=strongSwan Root CA"validity:  not before Dec 24 12:14:00 2014, ok           not after  Dec 23 12:14:00 2016, ok (expires in 729 days)serial:    70:27:27:e3:58:d1:a7:d3altNames:,,,     serverAuth iKEIntermediateauthkeyId: d1:72:26:da:6b:50:e0:4d:89:f8:39:f9:7f:b9:97:48:04:df:2b:00subjkeyId: 2b:03:2a:36:d5:6e:37:69:b8:79:0f:36:35:b6:b4:3d:b2:76:9d:2epubkey:    RSA 2048 bitskeyid:     60:af:b0:25:bc:19:eb:b6:b4:4c:b0:f9:9f:ee:75:06:78:94:22:6fsubjkey:   2b:03:2a:36:d5:6e:37:69:b8:79:0f:36:35:b6:b4:3d:b2:76:9d:2e

You can also use OpenSSL to see the contents, here is an excerpt:

openssl x509 -inform DER -in ipsec.d/certs/vpnHostCert.der -noout -text


Certificate:            Data:                Version: 3 (0x2)                Serial Number: 8081471913740838867 (0x702727e358d1a7d3)            Signature Algorithm: sha1WithRSAEncryption                Issuer: C=NL, O=Example Company, CN=strongSwan Root CA                Validity                    Not Before: Dec 24 11:14:00 2014 GMT                    Not After : Dec 23 11:14:00 2016 GMT                Subject: C=NL, O=Example Company,                Subject Public Key Info:                    Public Key Algorithm: rsaEncryption                        Public-Key: (2048 bit)        [...]        X509v3 extensions:        X509v3 Authority Key Identifier:             keyid:D1:72:26:DA:6B:50:E0:4D:89:F8:39:F9:7F:B9:97:48:04:DF:2B:00        X509v3 Subject Alternative Name:   ,, IP Address:, DNS:        X509v3 Extended Key Usage:            TLS Web Server Authentication,        [...]

The private key (/etc/openswan/ipsec.d/private/strongswanKey.der) of the CAshould be moved somewhere safe, possibly to a special signing host withoutaccess to the Internet. Theft of this master signing key would completelycompromise your public key infrastructure. Use it only to generate clientcertificates when needed.

Client certificate

Any client will require a personal certificate in order to use the VPN. Theprocess is analogous to generating a host certificate, except that we identify aclient certificate by the clients e-mail address rather than a hostname.

We create a keypair for the example user "John".

Private key:

cd /etc/strongswan/strongswan pki --gen --type rsa --size 2048 --outform der > ipsec.d/private/JohnKey.derchmod 600 ipsec.d/private/JohnKey.der

Public key:

strongswan pki --pub --in ipsec.d/private/JohnKey.der --type rsa | strongswan pki --issue --lifetime 730 --cacert ipsec.d/cacerts/strongswanCert.der --cakey ipsec.d/private/strongswanKey.der --dn "C=NL, O=Example Company," --san "" --san "" --outform der > ipsec.d/certs/JohnCert.der

A VPN client needs a client certificate, its private key, and the signing CAcertificate. The most convenient way is to put everything in a single signedPKCS#12 file and export it with a paraphrase.

Convert the required keys to PEM formt before converting to a .p12:

cd /etc/strongswan/openssl rsa -inform DER -in ipsec.d/private/JohnKey.der -out ipsec.d/private/JohnKey.pem -outform PEMopenssl x509 -inform DER -in ipsec.d/certs/JohnCert.der -out ipsec.d/certs/JohnCert.pem -outform PEMopenssl x509 -inform DER -in ipsec.d/cacerts/strongswanCert.der -out ipsec.d/cacerts/strongswanCert.pem -outform PEM

Construct the .p12:

openssl pkcs12 -export  -inkey ipsec.d/private/JohnKey.pem -in ipsec.d/certs/JohnCert.pem -name "John's VPN Certificate"  -certfile ipsec.d/cacerts/strongswanCert.pem -caname "strongSwan Root CA" -out John.p12

Enter a password twice, then you have a .p12. You can send John.p12 and itsexport paraphrase to the person whos going to install it onto the client. Insome cases (iOS for example) you have to separately include the CA certificateipsec.d/cacerts/strongswanCert.pem.

Transport this John.p12 file and the password over seperate channels to aclient.

If you need any more user certificate, repeat the above steps with other userdata.

IPSEC Configuration

The main ipsec configuration file is located in /etc/strongswan. We aregoing to edit it:

vim /etc/strongswan/ipsec.conf

Place the following contents:

# ipsec.conf - strongSwan IPsec configuration fileconfig setup    charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2,  mgr 2"conn %default    keyexchange=ikev2    ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024!    esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1!    dpdaction=clear    dpddelay=300s    rekey=no    left=%any    leftsubnet=    leftcert=vpnHostCert.der    right=%any    rightdns=,    rightsourceip= IPSec-IKEv2    keyexchange=ikev2    auto=addconn IPSec-IKEv2-EAP    also="IPSec-IKEv2"    rightauth=eap-mschapv2    rightauthby2=pubkey    rightsendcert=never    eap_identity=%anyconn CiscoIPSec    keyexchange=ikev1    forceencaps=yes    authby=xauthrsasig    xauth=server    auto=add

This configuration has settings for three types of VPN services: IKEv2 + RSAcertificate, IKEv2 + EAP, and IKEv1 + Xauth RSA, thus providing compatibilityfor a wide range of IPsec clients.

iOS clients below iOS 8 need to use ikev1. Apple added support for IKEv2 iniOS 8, but it needs to be configured using a custom configuration profile.

OS X does not support IKEv2 (not on 10.10 or lower) so they need to use ikev1as well.

Android 4+ and Windows 7+ support IKEv2 and can use that.

Clients will get the Google DNS servers and an IP address in the We use a strong ciphersuite.

The leftcert=vpnHostCert.der expands to the path/etc/strongswan/ipsec.d/certs/vpnHostCert.der.

VPN user accounts and secrets

The users are configured in the /etc/strongswan/ipsec.secrets file.

vim /etc/strongswan/ipsec.secrets

Example content:

: RSA vpnHostKey.deralice : EAP "YzCgnveYuL429fH" bob : EAP "E23pOjvW8z248iAp" hipster: XAUTH "xauth_ikev1_example_password"

In the example above the RSA private key file vpnHostKey.der stored in the/etc/openswan/ipsec.d/private/ directory is not protected by symmetricencryption (a password).

The format of the EAP MSCHAPv2 user credentials is:

[<domain>\]<username> : EAP "<plaintext password>" 

Add as many users as you like there. The first line allows all users with avalid certificate to use the VPN, the other lines allow users without acertificate to login with a username and password. The space between theusername, the colon (:) and EAP needs to be there.

If you have users that need to use IKEv1 with a password and XAUTH you need toseperately configure those. Note that certificate authentication is prefersed,those users do not have to be configured there.

If you need to generate password, OpenSSL can help you there:

 openssl rand -base64 24 jzHMIj6sqBbSI6LFmXINrwZWkXG9O8GW

Firewall & Packet Routing

Configure the firewall to allow the below ports on the VM. CentOS 7 usesfirewalld to configure iptables, so lets use that. Add the required ports tothe dmz zone, make sure the server NAT's our traffic and activate that zone:

firewall-cmd --zone=dmz --permanent --add-rich-rule='rule protocol value="esp" accept' # ESP (the encrypted data packets)firewall-cmd --zone=dmz --permanent --add-rich-rule='rule protocol value="ah" accept' # AH (authenticated headers)firewall-cmd --zone=dmz --permanent --add-port=500/udp #IKE  (security associations)firewall-cmd --zone=dmz --permanent --add-port=4500/udp # IKE NAT Traversal (IPsec between natted devices)firewall-cmd --permanent --add-service="ipsec"firewall-cmd --zone=dmz --permanent --add-masqueradefirewall-cmd --permanent --set-default-zone=dmzfirewall-cmd --reloadfirewall-cmd --list-all

Configure sysctl to allow packet forwarding:

vim /etc/sysctl.conf

Add the following:

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

Apply with:

sysctl -p

(Or apply with a reboot)

Start the VPN

All the configuration on the server is now done. Enable the VPN at startup:

systemctl enable strongswan

And start it:

systemctl start strongswan

If you get errors like below:

connecting to 'unix:///var/run/charon.ctl' failed: Permission deniedfailed to connect to stroke socket 'unix:///var/run/charon.ctl'

You can use the below command to start the VPN if it does not work correctly:

strongswan restart

Client configuration

Windows 7

While the connecting user is authenticated with Username/Password usingMSCHAPv2, the gateway is authenticated in advance using Certificates. Thereforewe need to install the client .p12 certificate.


To install the trusted CA certificate locally, call up the Microsoft ManagementConsole (mmc) and add the Certificates Snap-In:

It is of the utmost importance that you select Computer account:

Go into the Certificates (Local Computer) / Trusted Root CertificationAuthorities / Certificates folder:

and select the Import action which will start the Certificate Import Wizard:

Never double-click on a certificate file because the content will end up in thecurrent user instead of the local computer part of the Windows registry and willnot be available for IPsec.

Select the John.p12 certificate file to be imported and install it in theTrusted Root Certification Authorities store.


Add VPN Connection

In the Network and Sharing Center choose Set up a new connection or network andas a connection option select Connect to a workplace:

Click on Use my Internet connection (VPN):

Enter the IPv4 or IPv6 internet address or the fully-qualified hostname of thestrongSwan VPN gateway. The destination name string can be chosen freely, let'scall the connection VPN:

Enter your user name and password. These credentials are used in the MSCHAPv2authentication exchange. We've configred these credentials in theipsec.secrets file.

Windows 7 will try to use IKEv2 to establish the VPN connection. If that fails,it will fall back to other VPN protocols.

To restrict Windows 7 to IKEv2, you might want to change the Type of VPN toIKEv2 in the Security tab of the VPN Properties menu.


Starting the VPN

VPN connections can be managed either from the Network and Internet / Networkand Sharing Center menu:

or more concisely from the Network and Internet / Network Connections menu:

Double click the adapter or click on Connect and the VPN tunnel comes up afterwhich the following status information is available:

The console command ipconfig /all shows the created virtual VPN interface:

PPP adapter VPN:   Connection-specific DNS Suffix  . :   Description . . . . . . . . . . . : VPN   Physical Address. . . . . . . . . :   DHCP Enabled. . . . . . . . . . . : No   Autoconfiguration Enabled . . . . : Yes   IPv4 Address. . . . . . . . . . . :   Subnet Mask . . . . . . . . . . . :   Default Gateway . . . . . . . . . :   NetBIOS over Tcpip. . . . . . . . : Enabled

Configuring Android

On Android we use the StrongSwan Application:

Download the .p12 certificate, but not double tap it or install it.

Open the Strongswan app and tap Add VPN Profile

Tap Select user certificate. Tap Install. Navigate to your .p12certificate and install it. Give the correct password and select the VPN andApps usage reference:

Select that certificate for use:

Tap Save:

To connect, tap the VPN name and it will connect:

The following command can be used to see if there are clients connected:

strongswan status

With one (android) client connected, it looks like this:

Security Associations (1 up, 0 connecting): IPSec-IKEv2[4]: ESTABLISHED 20 seconds ago,[C=NL, O=Example Company,]...[C=NL, O=Example Company,] IPSec-IKEv2{2}:  INSTALLED, TUNNEL, ESP in UDP SPIs: c6eadabb_i 58998789_o IPSec-IKEv2{2}: ===


Thanks to:

Tags: centos, ikev2, ipsec, openswan, openvpn, pptp, redhat, rhel, strongswan, tutorials, vpn