Last updated: 2026-02-13
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
}
}
}
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
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