Setup IKE/IPSec VPN with strongSwan Feb 23rd 2020 Words: 1.4k

The setup environment is Ubuntu 18.04

The private network building is 10.10.10.0/24

Install strongSwan and plugins

1
2
3
4
5
6
7
sudo apt install strongswan

#Include plugins like EAP-MSCHAPv2, optional
sudo apt install libstrongswan-extra-plugins libcharon-extra-plugins

#Used to generate the certificate, optional
sudo apt install strongswan-pki

Generate the certificate

Cautious: Wildcard certificate is not supported. That’s designed for security reasons, so don’t bother trying.

Generate CA certificate and key if you don’t have one

1
2
3
4
5
6
#CA key
ipsec pki --gen --type rsa --size 4096 --outform pem > ./ca.pem

#CA certificate
ipsec pki --self --ca --lifetime 3650 --in ./ca.pem \
--type rsa --dn "CN=VPN root CA" --outform pem > ./ca.crt

Generate server certificate and key

This certificate is used to verify the server’s identity, so it must be trusted by the client.
If you are using your custom CA, make sure it is installed on all client properly.

1
2
3
4
5
6
7
8
9
10
11
#Server key
ipsec pki --gen --type rsa --size 4096 --outform pem > ./server-key.pem

#Server certificate
ipsec pki --pub --in ~/pki/private/server-key.pem --type rsa \
| ipsec pki --issue --lifetime 1825 \
--cacert ~/pki/cacerts/ca-cert.pem \
--cakey ~/pki/private/ca-key.pem \
--dn "CN=<Server IP or Domain>" --san "<Server IP or Domain>" \
--flag serverAuth --flag ikeIntermediate --outform pem \
> ./server-cert.pem

Copy the certificate and keys to a specific folder

1
2
3
sudo mv ./ca.crt /etc/ipsec.d/cacert/
sudo mv ./server-cert.pem /etc/ipsec.d/certs/
sudo mv ./server-key. /etc/ipsec.d/private/

If you are using certificates located in a custom directory, you may encounter permission error, as the following log indicates.

1
2
3
4
5
6
7
8
9
10
charon (9144) started after 40 ms
05[CFG] received stroke: add connection 'ikev2-psk'
05[CFG] adding virtual IP address pool 10.10.10.0/24
05[CFG] added configuration 'ikev2-psk'
07[CFG] received stroke: add connection 'ikev2-eap'
07[CFG] reusing virtual IP address pool 10.10.10.0/24
07[LIB] opening '/var/www/cert/cert.pem' failed: Permission denied
07[LIB] building CRED_CERTIFICATE - ANY failed, tried 1 builders
07[CFG] loading certificate from '/var/www/cert/cert.pem' failed
07[CFG] added configuration 'ikev2-eap'

This may be caused by apparmor. Check the apparmor status sudo apparmor_status.
If charon or stroke is in enforce mode, you need to whitelist them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apparmor module is loaded.
7 profiles are loaded.
7 profiles are in enforce mode.
/usr/bin/man
/usr/lib/ipsec/charon
/usr/lib/ipsec/stroke
man_filter
man_groff
nvidia_modprobe
nvidia_modprobe//kmod
0 profiles are in complain mode.
1 processes have profiles defined.
1 processes are in enforce mode.
/usr/lib/ipsec/charon (9144)
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

White list the process

1
2
sudo apparmor_parser -R /etc/apparmor.d/usr.lib.ipsec.charon
sudo apparmor_parser -R /etc/apparmor.d/usr.lib.ipsec.stroke

Symlink the certificate files to the /etc/ipsec.d/ could have solved the problem as well, but some users have reported this method not not effective.

Enable forward and set iptables

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
sudo nano /etc/sysctl.conf
#Append
net.ipv4.ip_forward = 1
sudo sysctl -p

#Add iptables rules with root
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.10.10.0/24 -j ACCEPT
iptables -A FORWARD -s 10.10.10.0/24 -j ACCEPT
iptables -A FORWARD -s 10.10.10.0/24 -j ACCEPT
iptables -A INPUT -i <Interface> -p esp -j ACCEPT
iptables -A INPUT -i <Interface> -p udp --dport 500 -j ACCEPT
iptables -A INPUT -i <Interface> -p tcp --dport 500 -j ACCEPT
iptables -A INPUT -i <Interface> -p udp --dport 4500 -j ACCEPT
iptables -A INPUT -i <Interface> -p udp --dport 1701 -j ACCEPT
iptables -A INPUT -i <Interface> -p tcp --dport 1723 -j ACCEPT
iptables -A FORWARD -j REJECT

#Use SNAT if server has static IP (better performance)
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o <Interface> -j SNAT --to-source <Server IP>
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o <Interface> -j SNAT --to-source <Server IP>
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o <Interface> -j SNAT --to-source <Server IP>

#Use MASQUERADE if server does not have static IP (slower)
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o <Interface> -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o <Interface> -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o <Interface> -j MASQUERADE

#Make change persistent
sudo apt install iptables-persistent
sudo iptables-save > /etc/iptables/rules.v4

Configure IPSec and strongSwan

/etc/ipsec.conf

Cautious: Start from strongSwan v5.6.1, some deprecated cipher were removed, which may cause [IKE] no proposal found. Therefore to increase the compatibility of the VPN server, these ciphers need to be enabled manually using ike and esp under conn. Although this is not recommended.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# ipsec.conf - strongSwan IPsec configuration file

# basic configuration

config setup
# strictcrlpolicy=yes
uniqueids = no
# charondebug="chd 2, ike 2, knl 2, net 2, esp 2, dmn 2, mgr 2, lib 1, cfg 1, enc 1"

# Add connections here.

conn %default
leftid[email protected]<Server IP or Domain>
left=%any
leftsubnet=0.0.0.0/0
right=%any
rightsourceip=10.10.10.0/24

conn ikev2-eap
auto=add
keyexchange=ikev2
leftauth=pubkey
leftcert=cert.crt
leftsendcert=always
rightauth=eap-mschapv2
rightsendcert=no
eap_identity=%any

conn ikev2-psk
auto=add
keyexchange=ikev2
leftauth=psk
rightauth=psk

conn ipsec-xauth-psk
auto=add
keyexchange=ikev1
ike=aes128-sha1-modp1024,aes128-sha1-modp1536,aes128-sha1-modp2048,aes128-sha256-ecp256,aes128-sha256-modp1024,aes128-sha256-modp1536,aes128-sha256-modp2048,aes256-aes128-sha256-sha1-modp2048-modp4096-modp1024,aes256-sha1-modp1024,aes256-sha256-modp1024,aes256-sha256-modp1536,aes256-sha256-modp2048,aes256-sha256-modp4096,aes256-sha384-ecp384,aes256-sha384-modp1024,aes256-sha384-modp1536,aes256-sha384-modp2048,aes256-sha384-modp4096,aes256gcm16-aes256gcm12-aes128gcm16-aes128gcm12-sha256-sha1-modp2048-modp4096-modp1024,3des-sha1-modp1024!
esp=aes128-aes256-sha1-sha256-modp2048-modp4096-modp1024,aes128-sha1,aes128-sha1-modp1024,aes128-sha1-modp1536,aes128-sha1-modp2048,aes128-sha256,aes128-sha256-ecp256,aes128-sha256-modp1024,aes128-sha256-modp1536,aes128-sha256-modp2048,aes128gcm12-aes128gcm16-aes256gcm12-aes256gcm16-modp2048-modp4096-modp1024,aes128gcm16,aes128gcm16-ecp256,aes256-sha1,aes256-sha256,aes256-sha256-modp1024,aes256-sha256-modp1536,aes256-sha256-modp2048,aes256-sha256-modp4096,aes256-sha384,aes256-sha384-ecp384,aes256-sha384-modp1024,aes256-sha384-modp1536,aes256-sha384-modp2048,aes256-sha384-modp4096,aes256gcm16,aes256gcm16-ecp384,3des-sha1!
leftauth=psk
rightauth=psk
rightauth2=xauth

conn ipsec-hybrid-rsa
auto=add
keyexchange=ikev1
ike=aes128-sha1-modp1024,aes128-sha1-modp1536,aes128-sha1-modp2048,aes128-sha256-ecp256,aes128-sha256-modp1024,aes128-sha256-modp1536,aes128-sha256-modp2048,aes256-aes128-sha256-sha1-modp2048-modp4096-modp1024,aes256-sha1-modp1024,aes256-sha256-modp1024,aes256-sha256-modp1536,aes256-sha256-modp2048,aes256-sha256-modp4096,aes256-sha384-ecp384,aes256-sha384-modp1024,aes256-sha384-modp1536,aes256-sha384-modp2048,aes256-sha384-modp4096,aes256gcm16-aes256gcm12-aes128gcm16-aes128gcm12-sha256-sha1-modp2048-modp4096-modp1024,3des-sha1-modp1024!
esp=aes128-aes256-sha1-sha256-modp2048-modp4096-modp1024,aes128-sha1,aes128-sha1-modp1024,aes128-sha1-modp1536,aes128-sha1-modp2048,aes128-sha256,aes128-sha256-ecp256,aes128-sha256-modp1024,aes128-sha256-modp1536,aes128-sha256-modp2048,aes128gcm12-aes128gcm16-aes256gcm12-aes256gcm16-modp2048-modp4096-modp1024,aes128gcm16,aes128gcm16-ecp256,aes256-sha1,aes256-sha256,aes256-sha256-modp1024,aes256-sha256-modp1536,aes256-sha256-modp2048,aes256-sha256-modp4096,aes256-sha384,aes256-sha384-ecp384,aes256-sha384-modp1024,aes256-sha384-modp1536,aes256-sha384-modp2048,aes256-sha384-modp4096,aes256gcm16,aes256gcm16-ecp384,3des-sha1!
leftauth=pubkey
leftcert=cert.crt
leftsendcert=always
rightauth=xauth

include /var/lib/strongswan/ipsec.conf.inc

/etc/ipsec.secrets

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 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.

# this file is managed with debconf and will contain the automatically created private key
: RSA server-key.pem
: PSK "<Pre-shared key>"
: XAUTH "<XAuth password>"
<Username 0> : EAP "<EAP password for Username 0>"
<Username 1> : EAP "<EAP password for Username 1>"

include /var/lib/strongswan/ipsec.secrets.inc

Finishing

1
sudo systemctl restart strongswan

Apply the configuration and try to connect the server with the clients.

Helpful articles

EOF