How to configure strongSwan client on headless Debian-based Linux computer
Requirements
- Self-hosted hardened strongSwan IKEv2/IPsec VPN server 📦
- Linux or macOS computer (referred to as “certificate authority computer”)
- Debian-based Linux computer (referred to as “client computer”)
Caveats
- When copy/pasting commands that start with
$
, strip out$
as this character is not part of the command - When copy/pasting commands that start with
cat << "EOF"
, select all lines at once (fromcat << "EOF"
toEOF
inclusively) as they are part of the same (single) command
Guide
Step 1: create client certs using certificate authority from How to self-host hardened strongSwan IKEv2/IPsec VPN server for iOS and macOS (using certificate authority computer).
Navigate to strongswan-certs
folder
cd ~/Desktop/strongswan-certs
Set client common name
STRONGSWAN_CLIENT_COMMON_NAME=bob@vpn-server.com
Update OpenSSL config file
cat << EOF > openssl.cnf
[ req ]
distinguished_name = req_distinguished_name
attributes = req_attributes
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
countryName_default = US
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Self-hosted strongSwan VPN
commonName = Common Name (eg, fully qualified host name)
commonName_max = 64
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
[ ca ]
subjectKeyIdentifier = hash
basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, keyCertSign
[ server ]
authorityKeyIdentifier = keyid
subjectAltName = DNS:vpn-server.com
extendedKeyUsage = serverAuth, 1.3.6.1.5.5.8.2.2
[ client ]
authorityKeyIdentifier = keyid
subjectAltName = email:$STRONGSWAN_CLIENT_COMMON_NAME
extendedKeyUsage = serverAuth, 1.3.6.1.5.5.8.2.2
EOF
Generate client cert
$ openssl genrsa -out bob.key 4096
Generating RSA private key, 4096 bit long modulus
..............................++
....................................................................................................++
e is 65537 (0x10001)
$ openssl req -new -config openssl.cnf -extensions client -key bob.key -subj "/C=US/O=Self-hosted strongSwan VPN/CN=$STRONGSWAN_CLIENT_COMMON_NAME" -out bob.csr
$ openssl x509 -req -extfile openssl.cnf -extensions client -in bob.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out bob.crt
Signature ok
subject=/C=US/O=Self-hosted strongSwan VPN/CN=bob@vpn-server.com
Getting CA Private Key
Step 2: log in to client computer
Replace pi@10.0.1.69
with SSH destination of client computer and ~/.ssh/pi
with path to associated private key.
ssh pi@10.0.1.69 -i ~/.ssh/pi
Step 3: switch to root
su -
Step 4: configure iptables
Heads-up: input rules are likely already configured (run
iptables-save
andip6tables-save
to check).
Configure IPv4 rules
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p udp --dport 500 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p udp --dport 4500 -m state --state NEW -j ACCEPT
Configure IPv6 rules (if network is dual stack)
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 500 -m state --state NEW -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 4500 -m state --state NEW -j ACCEPT
Make iptables rules persistent
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
Step 5: update APT index
apt update
Step 6: install strongSwan
If you are shown an “Old runlevel management superseded” warning, answer “Ok”.
apt install -y strongswan libcharon-extra-plugins
Step 7: configure strongSwan
Backup and override /etc/ipsec.conf
Replace 185.193.126.203
with IP of server.
cp /etc/ipsec.conf /etc/ipsec.conf.backup
cat << EOF > /etc/ipsec.conf
conn ikev2
auto=start
ike=aes256gcm16-prfsha512-ecp384!
esp=aes256gcm16-ecp384!
dpdaction=restart
closeaction=restart
keyingtries=%forever
leftid=bob@vpn-server.com
leftsourceip=%config
leftauth=eap-tls
leftcert=bob.crt
right=185.193.126.203
rightid=vpn-server.com
rightsubnet=0.0.0.0/0
rightauth=pubkey
EOF
Backup and override /etc/ipsec.secrets
cp /etc/ipsec.secrets /etc/ipsec.secrets.backup
cat << "EOF" > /etc/ipsec.secrets
: RSA bob.key
EOF
Disable unused plugins
cd /etc/strongswan.d/charon
sed -i 's/load = yes/load = no/' ./*.conf
sed -i 's/load = no/load = yes/' ./eap-tls.conf ./aes.conf ./dhcp.conf ./farp.conf ./gcm.conf ./hmac.conf ./kernel-netlink.conf ./nonce.conf ./openssl.conf ./pem.conf ./pgp.conf ./pkcs12.conf ./pkcs7.conf ./pkcs8.conf ./pubkey.conf ./random.conf ./revocation.conf ./sha2.conf ./socket-default.conf ./stroke.conf ./x509.conf
cd -
Step 8: copy/paste content of ca.crt
, bob.key
and bob.crt
to server and make private key root-only.
On certificate authority computer: run cat ca.crt
On client computer: run vi /etc/ipsec.d/cacerts/ca.crt
, press i, paste output from previous step in window, press esc and press shift+z+z
On certificate authority computer: run cat bob.key
On client computer: run vi /etc/ipsec.d/private/bob.key
, press i, paste output from previous step in window, press esc and press shift+z+z
On certificate authority computer: run cat bob.crt
On client computer: run vi /etc/ipsec.d/certs/bob.crt
, press i, paste output from previous step in window, press esc and press shift+z+z
On client computer: run chmod -R 600 /etc/ipsec.d/private
Step 9: restart strongSwan
systemctl restart strongswan
Step 10: confirm strongSwan client is connected
$ ipsec status
Security Associations (1 up, 0 connecting):
ikev2[1]: ESTABLISHED 3 minutes ago, 10.0.1.69[bob@vpn-server.com]...185.193.126.203[vpn-server.com]
ikev2{1}: INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: c3fcabed_i c2b0c4cd_o
ikev2{1}: 10.0.2.199/32 === 0.0.0.0/0
ESTABLISHED
👍
Heads-up: use following steps to assign static IP to strongSwan client
Step 11: log in to server
Replace 185.193.126.203
with IP of server.
ssh vpn-server-admin@185.193.126.203 -i ~/.ssh/vpn-server
Step 12: switch to root
su -
Step 13: get virtual MAC address assigned to strongSwan client
Heads-up: run
ipsec status
as root on headless Debian-based Linux computer to see which IP was assigned to strongSwan client (10.0.2.199
in the following example).
$ cat /var/lib/misc/dnsmasq.leases | grep "10.0.2.199" | awk '{print $2}'
7a:a7:3b:4b:77:16
Step 14: assign static IP to strongSwan client
echo "dhcp-host=7a:a7:3b:4b:77:16,10.0.2.2" >> /etc/dnsmasq.d/01-dhcp-strongswan.conf
Step 15: restart dnsmasq
systemctl restart dnsmasq
Step 16: log in to client computer
Replace pi@10.0.1.69
with SSH destination of client computer and ~/.ssh/pi
with path to associated private key.
ssh pi@10.0.1.69 -i ~/.ssh/pi
Step 17: switch to root
su -
Step 18: restart strongSwan
systemctl restart strongswan
Step 19: confirm strongSwan client has IP 10.0.2.2
$ ipsec status
Security Associations (1 up, 0 connecting):
ikev2[1]: ESTABLISHED 3 minutes ago, 10.0.1.69[bob@vpn-server.com]...185.193.126.203[vpn-server.com]
ikev2{1}: INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: c3fcabed_i c2b0c4cd_o
ikev2{1}: 10.0.2.5/32 === 0.0.0.0/0
10.0.2.2/32
👍