StrongSwan: Difference between revisions

From ArchWiki
(Update section levels.)
 
(29 intermediate revisions by 16 users not shown)
Line 1: Line 1:
{{Lowercase title}}
{{Lowercase title}}
[[Category:Virtual Private Network]]
[[Category:Virtual Private Network]]
[[zh-cn:StrongSwan]]
[[ja:StrongSwan]]
[[zh-hans:StrongSwan]]
{{Related articles start}}
{{Related articles start}}
{{Related|L2TP/IPsec VPN client setup}}
{{Related|Openswan L2TP/IPsec VPN client setup}}
{{Related articles end}}
{{Related articles end}}


Line 15: Line 16:
== Installation ==
== Installation ==


First, install the {{AUR|strongswan}} package.
[[Install]] the {{Pkg|strongswan}} package.


== Certificates ==
== Certificates ==
Line 27: Line 28:


  $ cd /etc/ipsec.d/
  $ cd /etc/ipsec.d/
  $ ipsec pki --gen --type rsa --size 4096 \
  $ ipsec pki --gen --type rsa --size 4096 --outform pem > private/strongswanKey.pem
  --outform pem \
  > private/strongswanKey.pem
  $ chmod 600 private/strongswanKey.pem
  $ chmod 600 private/strongswanKey.pem
  $ ipsec pki --self --ca --lifetime 3650 \
  $ ipsec pki --self --ca --lifetime 3650 --outform pem \
  --in private/strongswanKey.pem --type rsa \
            --in private/strongswanKey.pem --type rsa \
  --dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
            --dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
  --outform pem \
      > cacerts/strongswanCert.pem
    > cacerts/strongswanCert.pem


The result is a 4096 bit RSA private key {{ic|strongswanKey.pem}} (line 4) and
The result is a 4096 bit RSA private key {{ic|strongswanKey.pem}} (line 2) and
a self-signed CA certificate {{ic|strongswanCert.pem}} (line 10) with a
a self-signed CA certificate {{ic|strongswanCert.pem}} (line 7) with a
validity of 10 years (3650 days). The files are stored in PEM encoded format.
validity of 10 years (3650 days). The files are stored in PEM encoded format.


Line 47: Line 45:
following command:
following command:


$ ipsec pki --print --in cacerts/strongswanCert.pem
{{hc|$ ipsec pki --print --in cacerts/strongswanCert.pem|2=
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
}}


Output:
{{Warning|The private key {{ic|/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.}}
 
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
 
{{Warning|The private key {{ic|/etc/ipsec.d/private/strongswanKey.pem}} of the CA should be moved somewhere safe, ossibly to a special signing host without access to the Internet. Theft of this master signing key would completely compromise your public key infrastructure.}}


=== Host Certificate ===
=== Host Certificate ===
Line 72: Line 68:


  $ cd /etc/ipsec.d/
  $ cd /etc/ipsec.d/
  $ ipsec pki --gen --type rsa --size 2048 \
  $ ipsec pki --gen --type rsa --size 2048 --outform pem > private/vpnHostKey.pem
  --outform pem \
  > private/vpnHostKey.pem
  $ chmod 600 private/vpnHostKey.pem
  $ chmod 600 private/vpnHostKey.pem
  $ ipsec pki --pub --in private/vpnHostKey.pem --type rsa | \
  $ ipsec pki --pub --in private/vpnHostKey.pem --type rsa | \
ipsec pki --issue --lifetime 730 \
      ipsec pki --issue --lifetime 730 --outform pem \
  --cacert cacerts/strongswanCert.pem \
                --cacert cacerts/strongswanCert.pem \
  --cakey private/strongswanKey.pem \
                --cakey private/strongswanKey.pem \
  --dn "C=CH, O=strongSwan, CN=vpn.example.com" \
                --dn "C=CH, O=strongSwan, CN='''vpn.example.com'''" \
  --san vpn.example.com \
                --san '''vpn.example.com''' \
  --flag serverAuth --flag ikeIntermediate \
                --flag serverAuth --flag ikeIntermediate \
  --outform pem > certs/vpnHostCert.pem
          > certs/vpnHostCert.pem


The result is a 2048 bit RSA private key {{ic|vpnHostKey.pem}} (line 4). In
The result is a 2048 bit RSA private key {{ic|vpnHostKey.pem}} (line 2). In
line 6 we extract its public key and pipe it over to issue
line 4 we extract its public key and pipe it over to issue
{{ic|vpnHostCert.pem}} (line 13), a host certificate signed by your CA. The
{{ic|vpnHostCert.pem}} (line 11), a host certificate signed by your CA. The
certificate has a validity of two years (730 days). It identifies the VPN host
certificate has a validity of two years (730 days). It identifies the VPN host
by its Fully Qualified Domain Name (FQDN) (here: {{ic|vpn.example.com}}).
by its Fully Qualified Domain Name (FQDN) (here: {{ic|vpn.example.com}}).


{{Warning|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), but preferably in both. Make sure both times to replace vpn.example.com with your VPN's hostname – or else the connection between client and server will fail!}}
{{Warning|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 ({{ic|1=CN=}}) and/or in a subject Alternative Name ({{ic|--san}}), but preferably in both. Make sure both times to replace {{ic|'''vpn.example.com'''}} with your VPN's hostname – or else the connection between client and server will fail!}}


{{Note|If you are going to use the built-in VPN client of Windows 7, you MUST add the {{ic|serverAuth}} extended key usage flag to your host certificate as shown above, or the client will refuse to connect.
{{Note|If you are going to use the built-in VPN client of Windows 7, you [https://wiki.strongswan.org/projects/strongswan/wiki/Win7CertReq MUST] add the {{ic|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 {{ic|ikeIntermediate}} flag, which we also added here.
In addition, OS X 10.7.3 or older requires the {{ic|ikeIntermediate}} flag, which we also added here.
Line 101: Line 95:
Let us take a look at the properties of our newly generated certificate.
Let us take a look at the properties of our newly generated certificate.


$ ipsec pki --print --in certs/vpnHostCert.pem
{{hc|$ ipsec pki --print --in certs/vpnHostCert.pem|2=
 
cert:      X509
Output:
subject:  "C=CH, O=strongSwan, CN=vpn.example.com"
 
issuer:  "C=CH, O=strongSwan, CN=strongSwan Root CA"
cert:      X509
validity:  not before Nov 22 21:16:51 2013, ok
subject:  "C=CH, O=strongSwan, CN=vpn.example.com"
          not after  Nov 22 21:16:51 2015, ok (expires in 729 days)
issuer:  "C=CH, O=strongSwan, CN=strongSwan Root CA"
serial:    0c:05:d7:d5:57:0e:d9:48
validity:  not before Nov 22 21:16:51 2013, ok
altNames:  vpn.example.com
            not after  Nov 22 21:16:51 2015, ok (expires in 729 days)
flags:    serverAuth iKEIntermediate  
serial:    0c:05:d7:d5:57:0e:d9:48
authkeyId: 9b:57:35:fb:cd:9e:2d:20:37:1d:61:4c:e7:c4:5b:5e:dc:64:ad:fc
altNames:  vpn.zeitgeist.se
subjkeyId: 5f:12:c2:06:ee:2b:1e:cc:5f:78:54:ff:f0:f3:7b:a0:2b:c0:b4:d6
flags:    serverAuth iKEIntermediate  
pubkey:    RSA 2048 bits
authkeyId: 9b:57:35:fb:cd:9e:2d:20:37:1d:61:4c:e7:c4:5b:5e:dc:64:ad:fc
keyid:    6f:a7:99:60:27:27:09:96:02:c1:b9:d9:7d:c1:b0:10:e3:e1:d5:45
subjkeyId: 5f:12:c2:06:ee:2b:1e:cc:5f:78:54:ff:f0:f3:7b:a0:2b:c0:b4:d6
subjkey:  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


=== Client Certificate ===
=== Client Certificate ===
Line 126: Line 118:


  $ cd /etc/ipsec.d/
  $ cd /etc/ipsec.d/
  $ ipsec pki --gen --type rsa --size 2048 \
  $ ipsec pki --gen --type rsa --size 2048 --outform pem > private/ClientKey.pem
  --outform pem \
  > private/ClientKey.pem
  $ chmod 600 private/ClientKey.pem
  $ chmod 600 private/ClientKey.pem
  $ ipsec pki --pub --in private/ClientKey.pem --type rsa | \
  $ ipsec pki --pub --in private/ClientKey.pem --type rsa | \
ipsec pki --issue --lifetime 730 \
      ipsec pki --issue --lifetime 730 --outform pem \
  --cacert cacerts/strongswanCert.pem \
                --cacert cacerts/strongswanCert.pem \
  --cakey private/strongswanKey.pem \
                --cakey private/strongswanKey.pem \
  --dn "C=CH, O=strongSwan, CN=myself@example.com" \
                --dn "C=CH, O=strongSwan, CN=myself@example.com" \
  --san myself@example.com \
                --san myself@example.com \
  --outform pem > certs/ClientCert.pem
          > certs/ClientCert.pem
$ openssl pkcs12 -export -inkey private/ClientKey.pem \
 
  -in certs/ClientCert.pem -name "My own VPN client certificate" \
The result is a 2048 bit RSA private key {{ic|ClientKey.pem}} (line 2).
  -certfile cacerts/strongswanCert.pem \
In line 6 we extract its public key and pipe it over to issue {{ic|ClientCert.pem}} (line 10), the first client certificate signed by your CA.
  -caname "strongSwan Root CA" \
The certificate has a validity of two years (730 days) and identifies the client by its e-mail address (here: {{ic|myself@example.com}}).
  -out Client.p12
 
Finally we will bundle all needed certificates and keys into a PKCS#12 file with a passphrase, which is the most convenient format for clients.


The result is a 2048 bit RSA private key {{ic|ClientKey.pem}} (line 4). In line
$ openssl pkcs12 -export -name "My own VPN client certificate" \
6 we extract its public key and pipe it over to issue {{ic|ClientCert.pem}}
                  -inkey private/ClientKey.pem \
(line 12), the first client certificate signed by your CA. The certificate has
                  -in certs/ClientCert.pem \
a validity of two years (730 days) and identifies the client by his e-mail
                  -certfile cacerts/strongswanCert.pem \
address (here: {{ic|myself@example.com}}). The last command bundles all needed
                  -caname "strongSwan Root CA" \
certificates and keys into a PKCS#12 file with a passphrase, which is the most
                  -out Client.p12
convenient format for clients.


== VPN Variants ==
== VPN Variants ==
Line 223: Line 213:


{{Expansion|Need to better explain the differences, advantages and inconvenients, then write a tutorial.}}
{{Expansion|Need to better explain the differences, advantages and inconvenients, then write a tutorial.}}
Compared to tunnel mode, transport mode does not encrypt the original IP header from its point of view.  This is useful if something else (i.e. GRE) has already encapsulated the original packet to be transported through a tunnel, before IPSec gets it.  From the point of view of IPSec, the IP header it thinks is the original is actually the IP header already setup for the tunneling, and it will encrypt what is truly the original IP header as just part of the encapsulated packet payload, without realizing it is doing it.


=== IPSec/L2TP ===
=== IPSec/L2TP ===
Line 232: Line 224:
== Secrets ==
== Secrets ==


strongSwan needs to know which clients are allowed to connect to the VPN. This
The server's private key needs to be configured in {{ic|/etc/ipsec.secrets}}, like the following example:
is configured in the {{ic|/etc/ipsec.secrets}} file, like the following
example:
 
{{hc|/etc/ipsec.secrets|<nowiki># 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 ClientKey.pem
{{hc|/etc/ipsec.secrets|
user1 : EAP "topsecretpassword"
# RSA private key for this host
user2 : XAUTH "evenmoretopsecretpassword"
: RSA vpnHostKey.pem
</nowiki>}}
}}


Whenever you edit /etc/ipsec.secrets while strongSwan is running, you must
Whenever you edit {{ic|/etc/ipsec.secrets}} while strongSwan is running, you must
reload the file:
reload the file:


Line 282: Line 265:
* UDP 500: Key exchanges (IKE)
* UDP 500: Key exchanges (IKE)


Finally, you can [[start]] and [[enable]] the {{ic|strongswan}} service.
== Starting ==
 
{{Out of date|The systemd unit file name was changed in version 5.8.0.|section=Starting the service: replace legacy with new starter?}}
 
Finally, you can [[start]] and [[enable]] {{ic|strongswan-starter.service}}.


=== Running Strongswan in a Container ===
=== Running Strongswan in a Container ===
For running {{ic|strongswan}} in a container like [[systemd-nspawn]] you need the following service file:
For running {{ic|strongswan}} in a container like [[systemd-nspawn]] you need the following service file:


Line 296: Line 284:


{{Expansion|Need to explain at least ip xfrm and common issues}}
{{Expansion|Need to explain at least ip xfrm and common issues}}
=== Routing issues ===
If you are having troubles with routing traffic from client (road warrior) to the remote network, try disabling the {{ic|bypass-lan}} plugin on the server. This plugin is enabled by default in the official Arch package since version 5.6.0. See the associated [https://wiki.strongswan.org/issues/2462 issue] in strongswan bugtracker.
{{hc|/etc/strongswan.d/charon/bypass-lan.conf|2=
# Whether to load the plugin. Can also be an integer to increase the
# priority of this plugin.
load = no
}}
=== SSL Handshake Timeouts ===
Some users have had intermittent SSL handshake timeouts, such as:
* {{ic|<nowiki>curl -v https://example.com</nowiki>}} getting stuck at "TLSv1.3 (OUT), TLS handshake, Client hello (1):"
* Firefox stalling loading a page, showing "Performing a TLS handshake to www.example.com"
Some users have fixed (or worked around?) this problem by decreasing their network interface mtu to be in the 1422-1438 range, even if they do not need to do so without a VPN or when using OpenVPN. [https://bbs.archlinux.org/viewtopic.php?id=244606] [https://wiki.strongswan.org/projects/strongswan/wiki/ForwardingAndSplitTunneling#MTUMSS-issues]
Lowering mtu could potentially cause other problems, so your mileage may vary.  This fix/workaround will likely somewhat decrease internet and internal network performance.  (But, SSL handshakes will stop stalling.)  If you are using jumbo frames, this may significantly decrease internal network performance.
Check your interface's mtu: (The one being used to connect to the VPN)
$ ip link
Consider this default (probably 1500) bad.
You can efficiently try to find a mtu that prevents an SSL timeout by repeating this process, perhaps starting with a really low '''''trial-mtu''''' like 1300, or lower if that still fails: ('''''interface''''' is the name shown above by {{ic|ip link}}, not a full path like {{ic|/dev/device}})
# ip link set dev '''''interface''''' mtu '''''trial-mtu'''''
$ while(<nowiki>curl -v https://example.com</nowiki>); do
> sleep 2
> done
If it succeeds enough times for you to be confident an intermittent failure should have happened, consider this mtu as good, and hit {{ic|CTRL+C}}.  Re-run the above commands with a '''''trial-mtu''''' halfway between this one and your closest known bad mtu.
If it gets stuck on a TLS handshake, consider this as bad, and hit {{ic|CTRL+C}}.  Re-run the above with halfway between this one and your closest known good mtu.
=== Connection established but no traffic ===
{{Expansion|[[NetworkManager#Use openresolv|NetworkManager needs to be configured to use openresolv]].}}
In certain setups, like KDE, you might get a established connection using {{ic|ipsec up}} but you cannot reach any outside machine. This could be due to the {{Pkg|openresolv}} package not being installed. It is an optional dependency, but it might be required for your situation.


== See also ==
== See also ==


* [https://www.zeitgeist.se/2013/11/22/strongswan-howto-create-your-own-vpn/ strongSwan 5: How to create your own VPN] — The source used to write the initial revision of this article, with permission from the original author.
* [https://www.zeitgeist.se/2013/11/22/strongswan-howto-create-your-own-vpn/ strongSwan 5: How to create your own VPN] — The source used to write the initial revision of this article, with permission from the original author.
* [https://www.digitalocean.com/community/tutorials/how-to-set-up-an-ikev2-vpn-server-with-strongswan-on-ubuntu-16-04 How to Set Up an IKEv2 VPN Server with StrongSwan on Ubuntu 16.04]

Latest revision as of 19:10, 21 March 2022

IPSec is an encryption and authentication standard that can be used to build secure Virtual Private Networks (VPNs).

It is natively supported by the Linux kernel, but configuration of encryption keys is left to the user. The IKE protocols are therefore used in IPSec VPNs to automatically negotiate key exchanges securely using a variety of means, including certificates, pre-shared keys or both.

They are typically implemented in userspace daemons on the server side. strongSwan is an IKE daemon with full support for IKEv1 and IKEv2. It is natively supported by most modern clients, including Linux, Windows 7, Apple iOS, Mac OSX, FreeBSD and BlackBerry OS.

Installation

Install the strongswan package.

Certificates

The first step is to generate the X.509 certificates, including a certificate authority (CA), a server certificate, and at least one client certificate.

Certificate Authority

Let us 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 --outform pem \
            --in private/strongswanKey.pem --type rsa \
            --dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
      > cacerts/strongswanCert.pem

The result is a 4096 bit RSA private key strongswanKey.pem (line 2) and a self-signed CA certificate strongswanCert.pem (line 7) with a validity of 10 years (3650 days). The files are stored in PEM encoded format.

You can change the Distinguished Name (DN) to more relevant values for country (C), organization (O), and common name (CN), but you do not have to.

To list the properties of your newly generated certificate, type in the following command:

$ ipsec pki --print --in cacerts/strongswanCert.pem
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
Warning: 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.

Host Certificate

This certificate will be used to authenticate the VPN server. Run the following commands:

$ 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 --outform pem \
                --cacert cacerts/strongswanCert.pem \
                --cakey private/strongswanKey.pem \
                --dn "C=CH, O=strongSwan, CN=vpn.example.com" \
                --san vpn.example.com \
                --flag serverAuth --flag ikeIntermediate \
          > certs/vpnHostCert.pem

The result is a 2048 bit RSA private key vpnHostKey.pem (line 2). In line 4 we extract its public key and pipe it over to issue vpnHostCert.pem (line 11), 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.example.com).

Warning: 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 (CN=) and/or in a subject Alternative Name (--san), but preferably in both. Make sure both times to replace vpn.example.com with your VPN's hostname – or else the connection between client and server will fail!
Note: If you are 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 will not hurt anyone, you should make sure you keep them there.

Let us take a look at the properties of our newly generated certificate.

$ ipsec pki --print --in certs/vpnHostCert.pem
cert:      X509
subject:  "C=CH, O=strongSwan, CN=vpn.example.com"
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.example.com
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

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/ClientKey.pem
$ chmod 600 private/ClientKey.pem
$ ipsec pki --pub --in private/ClientKey.pem --type rsa | \
      ipsec pki --issue --lifetime 730 --outform pem \
                --cacert cacerts/strongswanCert.pem \
                --cakey private/strongswanKey.pem \
                --dn "C=CH, O=strongSwan, CN=myself@example.com" \
                --san myself@example.com \
          > certs/ClientCert.pem

The result is a 2048 bit RSA private key ClientKey.pem (line 2). In line 6 we extract its public key and pipe it over to issue ClientCert.pem (line 10), the first client certificate signed by your CA. The certificate has a validity of two years (730 days) and identifies the client by its e-mail address (here: myself@example.com).

Finally we will bundle all needed certificates and keys into a PKCS#12 file with a passphrase, which is the most convenient format for clients.

$ openssl pkcs12 -export -name "My own VPN client certificate" \
                 -inkey private/ClientKey.pem \
                 -in certs/ClientCert.pem  \
                 -certfile cacerts/strongswanCert.pem \
                 -caname "strongSwan Root CA" \
                 -out Client.p12

VPN Variants

The easiest configuration to get running with is IPSec in tunnel mode, described below.

IPSec in tunnel mode

VPN configuration can be found in /etc/ipsec.conf. The following contains the necessary options to build a basic, functional VPN server:

/etc/ipsec.conf
# ipsec.conf - strongSwan IPsec configuration file
config setup

  # By default only one client can connect at the same time with an identical
  # certificate and/or password combination. Enable this option to disable
  # this behavior.
  # uniqueids=never

  # Slightly more verbose logging. Very useful for debugging.
  charondebug="cfg 2, dmn 2, ike 2, net 2"

# Default configuration options, used below if an option is not specified.
# See: https://wiki.strongswan.org/projects/strongswan/wiki/ConnSection
conn %default

  # Use IKEv2 by default
  keyexchange=ikev2

  # Prefer modern cipher suites that allow PFS (Perfect Forward Secrecy)
  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!

  # Dead Peer Discovery
  dpdaction=clear
  dpddelay=300s

  # Do not renegotiate a connection if it is about to expire
  rekey=no

  # Server side
  left=%any
  leftsubnet=0.0.0.0/0
  leftcert=vpnHostCert.pem

  # Client side
  right=%any
  rightdns=8.8.8.8,8.8.4.4
  rightsourceip=%dhcp

# IKEv2: Newer version of the IKE protocol
conn IPSec-IKEv2
  keyexchange=ikev2
  auto=add

# IKEv2-EAP
conn IPSec-IKEv2-EAP
  also="IPSec-IKEv2"
  rightauth=eap-mschapv2
  rightsendcert=never
  eap_identity=%any

# IKEv1 (Cisco-compatible version)
conn CiscoIPSec
  keyexchange=ikev1
  # forceencaps=yes
  rightauth=pubkey
  rightauth2=xauth
  auto=add

IPSec in transport mode

This article or section needs expansion.

Reason: Need to better explain the differences, advantages and inconvenients, then write a tutorial. (Discuss in Talk:StrongSwan)

Compared to tunnel mode, transport mode does not encrypt the original IP header from its point of view. This is useful if something else (i.e. GRE) has already encapsulated the original packet to be transported through a tunnel, before IPSec gets it. From the point of view of IPSec, the IP header it thinks is the original is actually the IP header already setup for the tunneling, and it will encrypt what is truly the original IP header as just part of the encapsulated packet payload, without realizing it is doing it.

IPSec/L2TP

The L2TP/IPsec VPN client setup page describes how to setup a client to connect to an IPSec/L2TP server. This variant of an IPSec VPN has the advantage of allowing to tunnel non-IP packets, contrary to pure IPSec, but at the expense of having to run an additional L2TP daemon.

This article or section needs expansion.

Reason: Need to better explain the differences, advantages and inconvenients, then write a tutorial. (Discuss in Talk:StrongSwan)

Secrets

The server's private key needs to be configured in /etc/ipsec.secrets, like the following example:

/etc/ipsec.secrets
# RSA private key for this host
: RSA vpnHostKey.pem

Whenever you edit /etc/ipsec.secrets while strongSwan is running, you must reload the file:

$ ipsec rereadsecrets

Networking

You’re almost done setting up your server. There are a few things left to make your VPN server properly route the VPN tunnel:

/etc/sysctl.d/10-net-forward.conf
# VPN
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

The VPN configuration above automatically assigns an IP address to the client using DHCP, so you need to have a working DHCP server. If the server is running on the same host as strongSwan, you may need to edit /etc/strongswan.d/charon/dhcp.conf like this:

/etc/strongswan.d/charon/dhcp.conf
dhcp {
 force_server_address = yes
 server = 192.168.0.255
}

You may also need to allow the following protocols in your firewall:

  • ESP (Encrypted Secure Payload): Standard IPSec traffic
  • UDP 4500: IPSec traffic in "NAT Traversal" mode
  • UDP 500: Key exchanges (IKE)

Starting

This article or section is out of date.

Reason: The systemd unit file name was changed in version 5.8.0. (Discuss in Talk:StrongSwan#Starting the service: replace legacy with new starter?)

Finally, you can start and enable strongswan-starter.service.

Running Strongswan in a Container

For running strongswan in a container like systemd-nspawn you need the following service file:

/etc/systemd/system/systemd-nspawn@.service.d/override.conf}
[Service]
ExecStart=
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --settings=override --machine=%I --capability=CAP_NET_ADMIN --network-veth 

Troubleshooting

This article or section needs expansion.

Reason: Need to explain at least ip xfrm and common issues (Discuss in Talk:StrongSwan)

Routing issues

If you are having troubles with routing traffic from client (road warrior) to the remote network, try disabling the bypass-lan plugin on the server. This plugin is enabled by default in the official Arch package since version 5.6.0. See the associated issue in strongswan bugtracker.

/etc/strongswan.d/charon/bypass-lan.conf
# Whether to load the plugin. Can also be an integer to increase the
# priority of this plugin.
load = no

SSL Handshake Timeouts

Some users have had intermittent SSL handshake timeouts, such as:

  • curl -v https://example.com getting stuck at "TLSv1.3 (OUT), TLS handshake, Client hello (1):"
  • Firefox stalling loading a page, showing "Performing a TLS handshake to www.example.com"

Some users have fixed (or worked around?) this problem by decreasing their network interface mtu to be in the 1422-1438 range, even if they do not need to do so without a VPN or when using OpenVPN. [1] [2]

Lowering mtu could potentially cause other problems, so your mileage may vary. This fix/workaround will likely somewhat decrease internet and internal network performance. (But, SSL handshakes will stop stalling.) If you are using jumbo frames, this may significantly decrease internal network performance.

Check your interface's mtu: (The one being used to connect to the VPN)

$ ip link

Consider this default (probably 1500) bad.

You can efficiently try to find a mtu that prevents an SSL timeout by repeating this process, perhaps starting with a really low trial-mtu like 1300, or lower if that still fails: (interface is the name shown above by ip link, not a full path like /dev/device)

# ip link set dev interface mtu trial-mtu
$ while(curl -v https://example.com); do
> sleep 2
> done

If it succeeds enough times for you to be confident an intermittent failure should have happened, consider this mtu as good, and hit CTRL+C. Re-run the above commands with a trial-mtu halfway between this one and your closest known bad mtu.

If it gets stuck on a TLS handshake, consider this as bad, and hit CTRL+C. Re-run the above with halfway between this one and your closest known good mtu.

Connection established but no traffic

This article or section needs expansion.

In certain setups, like KDE, you might get a established connection using ipsec up but you cannot reach any outside machine. This could be due to the openresolv package not being installed. It is an optional dependency, but it might be required for your situation.

See also