+
Update 04/20/2014: Adjusted to take into account the modular configuration layout introduced in strongSwan 5.1.2. Tweaked cipher settings to provide perfect forward secrecy if supported by the client.
+
This article is a step by step guide on how to prepare strongSwan 5 to run your own private VPN, allowing you to stop snoopers from spying on your online activities, to bypass geo-restrictions, and to circumvent overzealous firewalls.
+
+
+
strongSwan is a modern and complete IPsec implementation with full support for IKEv1 and IKEv2. It’s natively supported by most modern clients, including Linux, Windows 7, Apple iOS, Mac OSX, FreeBSD and BlackBerry OS.
+
If you wonder why I chose strongSwan over Openswan, check out this post from strongSwan maintainer Prof. Andreas Steffen (yes, it’s biased and dated, but I find it convincing nonetheless).
+
Throughout this post I assume that you’re using Debian Wheezy. If you don’t – don’t worry. It should be easy to follow the guide even if you favor another Linux distribution.
+
Installation
+
+
Debian Wheezy ships with strongSwan 4.5.2. I prefer strongSwan 5, the new mainline branch, which got rid of Pluto in favor of a single daemon, charon, to handle both IKEv1 and IKEv2. Instead of installing from source, let’s get a copy from wheezy-backports, which includes strongSwan 5.1.2 from Debian testing recompiled for Wheezy.
+
Add wheezy-backports to your APT repository
+
$ echo "deb http://ftp.debian.org/debian wheezy-backports main" \
+ > /etc/apt/sources.list.d/wheezy-backports.list
+$ apt-get update
+
Install strongSwan
+
$ apt-get -t wheezy-backports install strongswan libcharon-extra-plugins
+
This installs the strongSwan package along with its dependencies (there are only a few). To determine that you’re running the right version, do:
+
$ ipsec version
+
Output:
+
Linux strongSwan U5.1.2/K3.2.0-4-amd64
+Institute for Internet Technologies and Applications
+University of Applied Sciences Rapperswil, Switzerland
+See 'ipsec --copyright' for copyright information.
+
Excellent – you’re now running strongSwan 5.1.2 on Linux kernel 3.2.0.
+
Certificate generation
+
Create your certification authority (CA)
+
The first step is to generate the X.509 certificates, including a certificate authority (CA), a server certificate, and at least one client certificate.
+
Let’s start by creating a self-signed root CA certificate.
+
$ cd /etc/ipsec.d/
+$ ipsec pki --gen --type rsa --size 4096 \
+ --outform pem \
+ > private/strongswanKey.pem
+$ chmod 600 private/strongswanKey.pem
+$ ipsec pki --self --ca --lifetime 3650 \
+ --in private/strongswanKey.pem --type rsa \
+ --dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
+ --outform pem \
+ > cacerts/strongswanCert.pem
+
The result is a 4096 bit RSA private key strongswanKey.pem
(line 4) and a self-signed CA certificate strongswanCert.pem
(line 10) with a validity of 10 years (3650 days). The files are stored in PEM encoded format (I prefer working with PEM over binary DER, the strongSwan default).
+
You can change the Distinguished Name (DN) to more relevant values for country (C), organization (O), and common name (CN), but you don’t have to.
+
To list the properties of your newly generated certificate, type in the following command:
+
$ ipsec pki --print --in cacerts/strongswanCert.pem
+
Output:
+
cert: X509
+subject: "C=CH, O=strongSwan, CN=strongSwan Root CA"
+issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA"
+validity: not before Nov 22 11:55:41 2013, ok
+ not after Nov 20 11:55:41 2023, ok (expires in 3649 days)
+serial: 65:39:93:df:a0:f8:40:03
+flags: CA CRLSign self-signed
+authkeyId: 45:30:11:da:a4:0e:0b:0a:a3:41:a5:81:41:ab:d8:04:7a:40:6c:c0
+subjkeyId: 45:30:11:da:a4:0e:0b:0a:a3:41:a5:81:41:ab:d8:04:7a:40:6c:c0
+pubkey: RSA 4096 bits
+keyid: dc:15:91:95:04:07:a5:13:69:5f:77:65:26:d7:02:3f:60:ec:73:c8
+subjkey: 45:30:11:da:a4:0e:0b:0a:a3:41:a5:81:41:ab:d8:04:7a:40:6c:c0
+
Create your VPN host certificate
+
$ cd /etc/ipsec.d/
+$ ipsec pki --gen --type rsa --size 2048 \
+ --outform pem \
+ > private/vpnHostKey.pem
+$ chmod 600 private/vpnHostKey.pem
+$ ipsec pki --pub --in private/vpnHostKey.pem --type rsa | \
+ ipsec pki --issue --lifetime 730 \
+ --cacert cacerts/strongswanCert.pem \
+ --cakey private/strongswanKey.pem \
+ --dn "C=CH, O=strongSwan, CN=vpn.zeitgeist.se" \
+ --san vpn.zeitgeist.se \
+ --flag serverAuth --flag ikeIntermediate \
+ --outform pem > certs/vpnHostCert.pem
+
The result is a 2048 bit RSA private key vpnHostKey.pem
(line 4). In line 6 we extract its public key and pipe it over to issue vpnHostCert.pem
(line 13), a host certificate signed by your CA. The certificate has a validity of two years (730 days). It identifies the VPN host by its Fully Qualified Domain Name (FQDN) (here: vpn.zeitgeist.se).
+
Important: The domain name or IP address of your VPN server, which is later entered in the client’s connection properties, MUST be contained either in the subject Distinguished Name (here in CN, line 10) and/or in a subject Alternative Name (line11). I prefer to include it in both. Make sure both times to replace vpn.zeitgeist.se with your VPN’s hostname – or else the connection between client and server will fail!
+
Important: If you’re going to use the built-in VPN client of Windows 7, you MUST add the serverAuth extended key usage flag to 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 we also added here. Since the addition of these two flags probably won’t hurt anyone (as far as I know), you should make sure you keep them there.
+
Let’s take a look at the properties of our newly generated certificate.
+
$ ipsec pki --print --in certs/vpnHostCert.pem
+
Output:
+
cert: X509
+subject: "C=CH, O=strongSwan, CN=vpn.zeitgeist.se"
+issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA"
+validity: not before Nov 22 21:16:51 2013, ok
+ not after Nov 22 21:16:51 2015, ok (expires in 729 days)
+serial: 0c:05:d7:d5:57:0e:d9:48
+altNames: vpn.zeitgeist.se
+flags: serverAuth iKEIntermediate
+authkeyId: 9b:57:35:fb:cd:9e:2d:20:37:1d:61:4c:e7:c4:5b:5e:dc:64:ad:fc
+subjkeyId: 5f:12:c2:06:ee:2b:1e:cc:5f:78:54:ff:f0:f3:7b:a0:2b:c0:b4:d6
+pubkey: RSA 2048 bits
+keyid: 6f:a7:99:60:27:27:09:96:02:c1:b9:d9:7d:c1:b0:10:e3:e1:d5:45
+subjkey: 5f:12:c2:06:ee:2b:1e:cc:5f:78:54:ff:f0:f3:7b:a0:2b:c0:b4:d6
+
Create a client certificate
+
Any client will require a personal certificate in order to use the VPN. The process is analogous to generating a host certificate, except that we identify a client certificate by the client’s e-mail address rather than a hostname.
+
$ cd /etc/ipsec.d/
+$ ipsec pki --gen --type rsa --size 2048 \
+ --outform pem \
+ > private/AlexanderKey.pem
+$ chmod 600 private/AlexanderKey.pem
+$ ipsec pki --pub --in private/AlexanderKey.pem --type rsa | \
+ ipsec pki --issue --lifetime 730 \
+ --cacert cacerts/strongswanCert.pem \
+ --cakey private/strongswanKey.pem \
+ --dn "C=CH, O=strongSwan, CN=alexander@zeitgeist.se" \
+ --san alexander@zeitgeist.se \
+ --outform pem > certs/AlexanderCert.pem
+
The result is a 2048 bit RSA private key AlexanderKey.pem
(line 4). In line 6 we extract its public key and pipe it over to issue AlexanderCert.pem
(line 12), the first client certificate signed by your CA. The certificate has a validity of two years (730 days) and identifies the client by his e-mail address (here: alexander@zeitgeist.se).
+
Export client certificate as a PKCS#12 file
+
A VPN client needs a client certificate, its private key, and the signing CA certificate. The most convenient way is to put everything in a single signed PKCS#12 file and export it with a paraphrase.
+
$ cd /etc/ipsec.d/
+$ openssl pkcs12 -export -inkey private/AlexanderKey.pem \
+ -in certs/AlexanderCert.pem -name "Alexander's VPN Certificate" \
+ -certfile cacerts/strongswanCert.pem \
+ -caname "strongSwan Root CA" \
+ -out Alexander.p12
+
Now you can send Alexander.p12 and its export paraphrase to the person who’s going to install it onto the client. In some cases (iOS for example) you have to separately include the CA certificate cacerts/strongswanCert.pem
.
+
Revoke a certificate (if necessary)
+
If a certificate is lost or stolen, it must be revoked so nobody can use it to connect to your VPN server. Assuming the certificate from the previous step got stolen, we revoke it with:
+
$ cd /etc/ipsec.d/
+$ ipsec pki --signcrl --reason key-compromise \
+ --cacert cacerts/strongswanCert.pem \
+ --cakey private/strongswanKey.pem \
+ --cert certs/AlexanderCert.pem \
+ --outform pem > crls/crl.pem
+
This generates the new certificate revocation list (CRL) crls/crl.pem. When someone tries to authenticate with the stolen certificate, he’ll receive an authentication credentials error message, and your log file will contain something like:
+
charon: 13[CFG] certificate was revoked
+ on Nov 24 17:34:40 UTC 2013, reason: key compromise
+
To add another revoked certificate to the same list, we need to copy the existing list into a temporary file:
+
$ cd /etc/ipsec.d/
+$ cp crls/crl.pem crl.pem.tmp
+$ ipsec pki --signcrl --reason key-compromise \
+ --cacert cacerts/strongswanCert.pem \
+ --cakey private/strongswanKey.pem \
+ --cert certs/AnotherStolenCert.pem \
+ --lastcrl crl.pem.tmp \
+ --outform pem > crls/crl.pem
+$ rm crl.pem.tmp
+
Certificates – Recap
+
So far you’ve created the following files:
+
/etc/ipsec.d/private/strongswanKey.pem # CA private key
+/etc/ipsec.d/cacerts/strongswanCert.pem # CA certificate
+/etc/ipsec.d/private/vpnHostKey.pem # VPN host private key
+/etc/ipsec.d/certs/vpnHostCert.pem # VPN host certificate
+/etc/ipsec.d/private/AlexanderKey.pem # Client "Alexander" private key
+/etc/ipsec.d/certs/AlexanderCert.pem # Client "Alexander" certificate
+/etc/ipsec.d/Alexander.p12 # Client "Alexander" PKCS#12 file
+
The private key /etc/ipsec.d/private/strongswanKey.pem
of the CA should be moved somewhere safe, possibly to a special signing host without access to the Internet. Theft of this master signing key would completely compromise your public key infrastructure.
+
Server configuration
+
Only three files are required for your strongSwan configuration:
+
+/etc/strongswan.conf
, which may point to a directory containing further configuration snippets
+/etc/ipsec.conf
+/etc/ipsec.secrets
+
+
Fortunately, the default strongSwan application configuration works just fine for us. For the purpose of this article there is nothing you need to do here. I invite you though to take a look at the strongSwan Wiki for a full list of configuration options of strongswan.conf.
+
Let’s do the fun stuff. Here is my /etc/ipsec.conf
file:
+
# ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ # uniqueids=never
+ charondebug="cfg 2, dmn 2, ike 2, net 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=0.0.0.0/0
+ leftcert=vpnHostCert.pem
+ right=%any
+ rightdns=8.8.8.8,8.8.4.4
+ rightsourceip=172.16.16.0/24
+
+conn IPSec-IKEv2
+ keyexchange=ikev2
+ auto=add
+
+conn IPSec-IKEv2-EAP
+ also="IPSec-IKEv2"
+ rightauth=eap-mschapv2
+ rightsendcert=never
+ eap_identity=%any
+
+conn CiscoIPSec
+ keyexchange=ikev1
+ # forceencaps=yes
+ rightauth=pubkey
+ rightauth2=xauth
+ auto=add
+
This configuration has settings for three types of VPN services: IKEv2 + RSA certificate, IKEv2 + EAP, and IKEv1 + Xauth RSA, thus providing compatibility for a wide range of IPsec clients.
+
Let’s go briefly over the important items:
+
+- line 4: (disabled here) by default only one client can connect at the same time with an identical certificate and/or password combo; the newer connection will always replace the older (in other words, a new connecting client using the same credentials kicks out the older still connected client). If you don’t like this, for instance because you want to use the same client certificates on multiple clients at the same time, enable this option
+- line 5: slightly more verbose logging. Very useful for debugging. Check out this link for a full list of options.
+- line 7: individual conn sections inherit the settings from the conn %default section. Put everything in here that you would otherwise have to repeat in the other conn sections. Helps to keep your setting file more concise.
+- line 21: settings specific to IKEv2 + RSA certificate connections
+- line 25: settings specific to IKEv2 + EAP connections
+- line 31: settings specific to IKEv1 + Xauth RSA connections
+
+
Your best resource for learning more about the available options is the strongSwan Wiki.
+
For now, if you like to enable your VPN server as quickly as possible, use above configuration as a template; only make sure to modify line 16 leftcert=vpnHostCert.pem to name your host VPN certificate instead.
+
Lastly, here is my /etc/ipsec.secrets
file:
+
# This file holds shared secrets or RSA private keys for authentication.
+
+# RSA private key for this host, authenticating it to any other host
+# which knows the public part. Suitable public keys, for ipsec.conf, DNS,
+# or configuration of other implementations, can be extracted conveniently
+# with "ipsec showhostkey".
+
+: RSA vpnHostKey.pem
+user1 : EAP "topsecretpassword"
+user2 : XAUTH "evenmoretopsecretpassword"
+
+- line 8: identifies the private key of the VPN host to allow your host to authenticate itself with its host certificate
+- line 9: defines an EAP credential (username / password) that can be used by clients to connect without client certificate
+- line 10: defines an XAUTH credential (username / password) that is required in addition to a client certificate for IKEv1 + Xauth RSA connections (as used by Apple iOS clients for example)
+
+
Whenever you edit /etc/ipsec.secrets
while strongSwan is running, you must reload the file:
+
$ ipsec rereadsecrets
+
Once again, the strongSwan Wiki has all the details if you are interested.
+
You’re almost done setting up your server. There are a few things left to make your VPN server properly route the VPN tunnel:
+
$ echo 1 > /proc/sys/net/ipv4/ip_forward
+$ echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
+$ echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
+
Or to make it permanent, add the following to your /etc/sysctl.conf
file:
+
# VPN
+net.ipv4.ip_forward = 1
+net.ipv4.conf.all.accept_redirects = 0
+net.ipv4.conf.all.send_redirects = 0
+
Use the following iptables rules (adjust the interface if yours isn’t eth0, and make sure to enter your VPN host IP where indicated):
+
$ iptables -t nat -A POSTROUTING -o eth0 ! -p esp \
+ -j SNAT --to-source <your VPN host IP>
+
Speaking of iptables, if you have a restrictive firewall for incoming traffic, don’t forget to allow IPsec communications. Three rules are required:
+
$ iptables -A INPUT -p udp --dport 500 --j ACCEPT
+$ iptables -A INPUT -p udp --dport 4500 --j ACCEPT
+$ iptables -A INPUT -p esp -j ACCEPT
+
+- line 1: for ISAKMP (handling of security associations)
+- line 2: for NAT-T (handling of IPsec between natted devices)
+- line 3: for ESP payload (the encrypted data packets)
+
+
That’s it! Restart strongSwan and your VPN server is ready.
+
$ service ipsec restart
+
Client configuration
+
Of course you cannot do anything with until you’ve configured your clients. Instead of boring you with dull screenshots, here are the essential strongSwan Wiki articles describing how to configure IPsec clients for popular systems. Of course you can also Google for other howtos since the client configuration is mostly independent from the server software.
+
Windows 7 with IKEv2 + RSA certificate
+
+
Windows 7 with IKEv2 + EAP
+
+
Mac OS X / iOS
+
+
Further reading
+
+
+
+
+
Hi,
+I have followed your guide on setting this up on Ubuntu 14.04 and I’m having an issue with authentication.
+When trying to connect the VPN from my iPhone I get the following error “VPN Connection – User authentication failed.” almost immediately.
+Specifying the wrong secret on the iPhone client yields a longer time-out before a different error, so seems that this has been set correctly.
+auth.log is showing “localhost charon: 01[IKE] 220.233.42.xxx is initiating a Main Mode IKE_SA” when trying to connect. There are no other errors showing in this log file when the connection fails to authenticate.
+Is this just a case that I have not specified the xauth user somewhere? I have tried this with two accounts setup on the ubuntu server (including root).
+Any pointers you can provide would be appreciated.
+Nate, I accidentally truncated a line in ipsec.secrets. Yes, you’re right, the XAUTH entry was missing. Thanks for the heads up!
+Cheers,
++Jan
Thanks!! added the user details to ipsec.secrets, restarted the strongswan service and I was able to authenticate.
+I’m glad it was something trivial!
+Thanks for the help.
++ +-
+
+
+
+
+
+
+
+
+
+ binar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+guys i dont get how the ipsec.secret should look like ? can u post an working example ?
++btw i have the same error as Nate had
+regards
Hi!
+I used your ipsec.conf and when I try to start Strongswan it gave me this error:
++start: Job failed to start
I then typed ipsec start and I get the following error:
++Starting strongSwan 5.1.2 IPsec [starter]…
+/etc/ipsec.conf:6: syntax error, unexpected FIRST_SPACES [ ]
+unable to start strongSwan — fatal errors in config
+ +-
+
+
+
+
+
+
+
+
+
+ Franz
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+I had the same problem. Deleting all file contents and just pasting the new configuration into the file solved the problem for me.
+Kelvin, looks like some sort of copy-paste problem. Check for wrong indentation and thinks like that.
+Cheers,
++Jan
Hi,
+I have followed the guide. My andriod phone connects no problems, however once its connected I still can’t ping anything.
++Can’t ping either of the interfaces eth0 (external) or eth1 (internal) and cant ping the phone either. It gets an IP and I can see the rule appear in /var/log/syslog. Any chance you could help?
+I have setup exactly as above…
Help!!
+Thanks
++Rob
I followed your easy through instructions all the way. Both my android and ios can connect to the server, however there is no data going through……any directions you wanna point me to? very much appreciated mate.
++ +-
+
+
+
+
+
+
+
+
+
+ Jan
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Mike, four things come to mind:
++a) It’s just a DNS problem,
ping 8.8.8.8
may be working+b) MASQUERADE rule issue
+c) Paket forwarding is not enabled
+d) Try
iptables -P INPUT ACCEPT && iptables -P FORWARD ACCEPT
as well just to make sure it’s not a firewall issue.But other than that, I don’t know.
+Cheers,
++Jan
you need to compile strongswan with –enable-kernel-libipsec
+