Last updated: 2026-05-15
strongSwan TLS/IPsec Configuration Guide
This guide provides recommended IKEv2/IPsec settings for strongSwan to establish encrypted VPN tunnels using certificate-based authentication. strongSwan implements the IKEv2 protocol with modern cryptographic algorithms for secure site-to-site and remote access VPN connections.
Prerequisites
- strongSwan 5.9 or later
- OpenSSL 1.1.1 or later (or a compatible crypto backend)
- X.509 certificates (server certificate, private key, and CA certificate)
RHEL/CentOS: Install with
dnf install strongswan.Debian/Ubuntu: Install with
apt install strongswan strongswan-pki.
Certificate Setup
Generate Certificates with strongSwan PKI
# Generate a CA private key and certificate
pki --gen --type rsa --size 4096 --outform pem > /etc/strongswan/ipsec.d/private/ca-key.pem
pki --self --ca --lifetime 3650 --in /etc/strongswan/ipsec.d/private/ca-key.pem \
--dn "CN=VPN CA" --outform pem > /etc/strongswan/ipsec.d/cacerts/ca-cert.pem
# Generate a server private key and certificate
pki --gen --type rsa --size 2048 --outform pem > /etc/strongswan/ipsec.d/private/server-key.pem
pki --req --type priv --in /etc/strongswan/ipsec.d/private/server-key.pem \
--dn "CN=vpn.example.com" --san vpn.example.com --outform pem > server.csr
pki --issue --cacert /etc/strongswan/ipsec.d/cacerts/ca-cert.pem \
--cakey /etc/strongswan/ipsec.d/private/ca-key.pem \
--type pkcs10 --in server.csr --serial 01 --lifetime 365 \
--flag serverAuth --flag ikeIntermediate \
--san vpn.example.com --outform pem > /etc/strongswan/ipsec.d/certs/server-cert.pem
Using Existing Certificates
If you have certificates from an external CA:
cp ca.crt /etc/strongswan/ipsec.d/cacerts/ca-cert.pem
cp server.crt /etc/strongswan/ipsec.d/certs/server-cert.pem
cp server.key /etc/strongswan/ipsec.d/private/server-key.pem
chmod 600 /etc/strongswan/ipsec.d/private/server-key.pem
Set Permissions
chmod 600 /etc/strongswan/ipsec.d/private/*.pem
chown root:root /etc/strongswan/ipsec.d/private/*.pem
swanctl Configuration
strongSwan 5.7+ uses swanctl.conf as the primary configuration format. The file is located at /etc/strongswan/swanctl/swanctl.conf.
IKEv2 Proposals
Configure strong cryptographic proposals for the IKE (control) channel:
connections {
vpn {
version = 2
proposals = aes256gcm16-sha384-x25519,aes256gcm16-sha384-ecp384,aes128gcm16-sha256-x25519,aes128gcm16-sha256-ecp256
}
}
ESP (Data Channel) Proposals
Configure the ESP proposals for encrypting tunnel traffic:
connections {
vpn {
children {
net {
esp_proposals = aes256gcm16-sha384,aes128gcm16-sha256,chacha20poly1305-sha256
}
}
}
}
Configuration Explained
- aes256gcm16 -- AES-256-GCM with 128-bit ICV (authenticated encryption)
- sha384 -- SHA-384 for PRF and integrity (IKE only; not used with GCM in ESP)
- x25519 -- Curve25519 Diffie-Hellman key exchange
- ecp384 -- NIST P-384 elliptic curve Diffie-Hellman
- chacha20poly1305 -- ChaCha20-Poly1305 authenticated encryption (good for devices without AES-NI)
Certificate Authentication
Configure certificate-based authentication in the connection:
connections {
vpn {
local {
auth = pubkey
certs = server-cert.pem
id = vpn.example.com
}
remote {
auth = pubkey
cacerts = ca-cert.pem
}
}
}
See RFC 8446 ยง4.3.2 for the TLS Certificate Request specification, and Wikipedia: Mutual authentication for a general overview.
Complete Configuration
swanctl.conf
connections {
vpn {
version = 2
rekey_time = 86400
dpd_delay = 30
# IKE proposals (control channel)
proposals = aes256gcm16-sha384-x25519,aes256gcm16-sha384-ecp384,aes128gcm16-sha256-x25519,aes128gcm16-sha256-ecp256
# Local (server) authentication
local {
auth = pubkey
certs = server-cert.pem
id = vpn.example.com
}
# Remote (client) authentication
remote {
auth = pubkey
cacerts = ca-cert.pem
}
# Child SA (tunnel)
children {
net {
local_ts = 10.0.0.0/24
esp_proposals = aes256gcm16-sha384,aes128gcm16-sha256,chacha20poly1305-sha256
rekey_time = 3600
dpd_action = restart
}
}
}
}
secrets {
private {
file = server-key.pem
}
}
Remote Access (Road Warrior)
For remote access VPN with virtual IP assignment:
connections {
roadwarrior {
version = 2
proposals = aes256gcm16-sha384-x25519,aes128gcm16-sha256-x25519
pools = client_pool
local {
auth = pubkey
certs = server-cert.pem
id = vpn.example.com
}
remote {
auth = pubkey
cacerts = ca-cert.pem
}
children {
roadwarrior {
local_ts = 0.0.0.0/0
esp_proposals = aes256gcm16-sha384,aes128gcm16-sha256
}
}
}
}
pools {
client_pool {
addrs = 10.10.10.0/24
dns = 10.0.0.1
}
}
Client Configuration
Generate Client Certificate
pki --gen --type rsa --size 2048 --outform pem > client-key.pem
pki --req --type priv --in client-key.pem --dn "CN=client@example.com" --outform pem > client.csr
pki --issue --cacert /etc/strongswan/ipsec.d/cacerts/ca-cert.pem \
--cakey /etc/strongswan/ipsec.d/private/ca-key.pem \
--type pkcs10 --in client.csr --serial 02 --lifetime 365 \
--flag clientAuth --outform pem > client-cert.pem
Export as PKCS#12 for import into clients:
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem \
-certfile /etc/strongswan/ipsec.d/cacerts/ca-cert.pem \
-out client.p12 -name "VPN Client"
Native Client Support
- Windows 10/11 -- Import the
.p12file and CA certificate, then create an IKEv2 VPN connection - macOS/iOS -- Import certificates via a
.mobileconfigprofile or manually in Keychain Access - Android -- Import the
.p12file in Settings > Security, configure IKEv2/IPsec VPN - Linux -- Use strongSwan or NetworkManager with the strongswan plugin
Security Notes
strongSwan implements IKEv2/IPsec, not TLS. The cryptographic considerations are similar but the attack surface differs:
- POODLE / BEAST / FREAK / LOGJAM: Not applicable. These attacks exploit flaws in SSL/TLS protocol versions. IKEv2 uses its own proposal negotiation and algorithm selection, independent of SSL/TLS.
- Forward secrecy: Guaranteed by using ECDHE (x25519, ecp384) in the IKE proposals. Each session negotiates a unique Diffie-Hellman exchange.
- Weak algorithms excluded: The recommended proposals exclude DES, 3DES, MD5, and short-key RSA. Only AES-GCM (authenticated encryption) and SHA-384/SHA-256 are recommended.
- Sweet32 (CVE-2016-2183, 2016): 3DES/64-bit block ciphers are excluded from all IKE and ESP proposals.
- Downgrade attacks: IKEv2 proposal negotiation includes a cookie mechanism and strong proposal selection; the recommended configuration avoids legacy algorithms that could be used in a downgrade scenario.
- Replay attacks: IKEv2 includes anti-replay protection in the ESP data channel via sequence numbers.
The following are not applicable to IKEv2/IPsec:
- Heartbleed (CVE-2014-0160, 2014): Not applicable to IKEv2/IPsec. strongSwan does not use OpenSSL for the IKEv2 key exchange itself. If you expose an HTTPS management interface on the same host, ensure the web server's OpenSSL is patched.
- BREACH / CRIME (2012-2013): Not applicable. These target HTTP-level and TLS-level compression, respectively; IPsec tunnels do not use either.
- DROWN (CVE-2016-0800, 2016): Not applicable. strongSwan does not use SSLv2.
Verification
Load the configuration and start the connection:
swanctl --load-all
swanctl --list-conns
Check active security associations:
swanctl --list-sas
View the negotiated algorithms:
swanctl --list-sas --raw
Check strongSwan logs for IKE negotiation details:
grep -i ike /var/log/syslog
Verify the connection from a client:
swanctl --initiate --child net
swanctl --list-sas