IPsec VPN Configuration with strongSwan
strongSwan is a comprehensive, open-source IPsec implementation for Linux providing both IKEv2 and legacy IKEv1 protocol support. Unlike simpler VPN solutions, IPsec operates at the network layer, encrypting all traffic between networks transparently. strongSwan supports complex scenarios including site-to-site connectivity, roadwarrior (mobile) access, split tunneling, and advanced authentication mechanisms. This guide covers installation, core configuration, certificate-based authentication, various deployment scenarios, and advanced features.
Table of Contents
- System Requirements
- Installation
- Generating Certificates
- Basic IKEv2 Configuration
- Site-to-Site VPN
- Roadwarrior Configuration
- Split Tunneling
- ipsec.conf Syntax
- Firewall Integration
- Monitoring and Troubleshooting
- Conclusion
System Requirements
strongSwan requires standard Linux development tools and libraries:
- GCC compiler or Clang
- OpenSSL or wolfSSL (cryptography library)
- libcurl (optional, for revocation checking)
- Linux kernel with IPsec support (ESP, AH, XFRM)
- At least 256 MB RAM (1 GB+ recommended)
Verify kernel IPsec support:
grep -i ipsec /boot/config-$(uname -r) | head -10
cat /proc/net/ipsec_interfaces
Installation
Install strongSwan from official repositories or compile from source.
For Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y strongswan strongswan-charon strongswan-libcharon charon-cmd
For CentOS/RHEL:
sudo yum install -y strongswan
For Fedora:
sudo dnf install -y strongswan
Install optional components for advanced features:
sudo apt-get install -y libstrongswan libstrongswan-extra-plugins strongswan-plugin-eap-tls
Verify installation:
ipsec version
ipsec status
Enable IP forwarding:
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
Make persistent:
sudo nano /etc/sysctl.conf
Add:
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.icmp_ignore_bogus_error_responses=1
Apply:
sudo sysctl -p
Generating Certificates
strongSwan supports pre-shared key (PSK) and certificate-based authentication. Certificates provide stronger security for production deployments.
Create a certificate authority (CA):
mkdir -p /etc/strongswan/ipsec.d/cacerts
cd /tmp
openssl genrsa -out cakey.pem 4096
Generate CA certificate:
openssl req -new -x509 -days 3650 -key cakey.pem -out cacert.pem \
-subj "/C=US/ST=State/L=City/O=Organization/CN=strongSwan-CA"
Create server certificate signing request:
openssl genrsa -out serverkey.pem 2048
openssl req -new -key serverkey.pem -out server.csr \
-subj "/C=US/ST=State/L=City/O=Organization/CN=vpn.example.com"
Sign server certificate:
openssl x509 -req -days 730 -in server.csr -CA cacert.pem -CAkey cakey.pem \
-CAcreateserial -out servercert.pem \
-extensions v3_req -extfile <(printf "subjectAltName=DNS:vpn.example.com")
Create client certificate:
openssl genrsa -out clientkey.pem 2048
openssl req -new -key clientkey.pem -out client.csr \
-subj "/C=US/ST=State/L=City/O=Organization/[email protected]"
openssl x509 -req -days 730 -in client.csr -CA cacert.pem -CAkey cakey.pem \
-CAcreateserial -out clientcert.pem
Copy certificates to strongSwan directories:
sudo cp cacert.pem /etc/strongswan/ipsec.d/cacerts/
sudo cp servercert.pem /etc/strongswan/ipsec.d/certs/
sudo cp serverkey.pem /etc/strongswan/ipsec.d/private/
sudo cp clientcert.pem /etc/strongswan/ipsec.d/certs/
sudo cp clientkey.pem /etc/strongswan/ipsec.d/private/
sudo chown root:root /etc/strongswan/ipsec.d/private/*
sudo chmod 600 /etc/strongswan/ipsec.d/private/*
Basic IKEv2 Configuration
Configure strongSwan for IKEv2 with certificate authentication.
Edit the main configuration file:
sudo nano /etc/strongswan/ipsec.conf
Basic IKEv2 server configuration:
config setup
uniqueids = never
charondebug = "all"
strictcrlpolicy = no
conn %default
type = tunnel
dpdaction = clear
dpddelay = 300s
rekey = no
left = %any
leftcert = servercert.pem
leftid = vpn.example.com
leftauth = pubkey
right = %any
rightid = %any
rightauth = pubkey
rightsourceip = 10.8.0.0/24
compression = yes
conn ikev2-pubkey
keyexchange = ikev2
auto = add
Configure IPsec credentials in secrets file:
sudo nano /etc/strongswan/ipsec.secrets
Add certificate passphrases:
: RSA serverkey.pem
: RSA clientkey.pem
Start strongSwan:
sudo systemctl start strongswan
sudo systemctl enable strongswan
Verify configuration:
sudo ipsec status
sudo ipsec listall
Site-to-Site VPN
Configure IPsec tunnel between two sites.
Site A (203.0.113.1) configuration:
sudo nano /etc/strongswan/ipsec.conf
Content:
config setup
uniqueids = never
dpdaction = restart
dpddelay = 10s
dpdtimeout = 30s
conn site-to-site
type = tunnel
keyexchange = ikev2
ike = aes256-sha2_256-modp2048!
esp = aes256-aes256!
dpdaction = restart
left = 203.0.113.1
leftcert = sitea-cert.pem
leftid = site-a.example.com
leftsubnet = 192.168.1.0/24
right = 198.51.100.5
rightid = site-b.example.com
rightcert = siteb-cert.pem
rightsubnet = 192.168.2.0/24
auto = start
rekey = yes
reauth = no
Site B (198.51.100.5) configuration:
sudo nano /etc/strongswan/ipsec.conf
Content:
config setup
uniqueids = never
dpdaction = restart
dpddelay = 10s
conn site-to-site
type = tunnel
keyexchange = ikev2
ike = aes256-sha2_256-modp2048!
esp = aes256-aes256!
dpdaction = restart
left = 198.51.100.5
leftcert = siteb-cert.pem
leftid = site-b.example.com
leftsubnet = 192.168.2.0/24
right = 203.0.113.1
rightid = site-a.example.com
rightcert = sitea-cert.pem
rightsubnet = 192.168.1.0/24
auto = start
rekey = yes
Reload configuration:
sudo ipsec reread
sudo ipsec reload
Initiate the tunnel from Site A:
sudo ipsec up site-to-site
Verify tunnel status:
sudo ipsec status site-to-site
Test connectivity:
# From Site A
ping 192.168.2.5 # Site B internal server
Roadwarrior Configuration
Configure IPsec for remote clients connecting to a VPN gateway.
VPN gateway configuration:
conn %default
type = tunnel
keyexchange = ikev2
ike = aes128-sha2_256-modp2048!
esp = aes128-sha2_256!
dpdaction = clear
left = 203.0.113.1
leftcert = vpn-cert.pem
leftid = vpn.example.com
leftauth = pubkey
right = %any
rightid = %any
rightauth = pubkey
rightsourceip = 10.8.0.0/24
rightdns = 8.8.8.8,8.8.4.4
conn ikev2-pubkey
keyexchange = ikev2
auto = add
Secrets file:
: RSA vpn-key.pem
Configure DHCP pool for remote clients. Edit charon daemon configuration:
sudo nano /etc/strongswan/strongswan.d/charon.conf
Add:
charon {
dns1 = 8.8.8.8
dns2 = 8.8.4.4
pools = dns_pool
}
dns_pool {
addrs = 10.8.0.0/24
}
Export client certificate and key for distribution:
# Create PKCS12 file for Windows clients
openssl pkcs12 -export -in clientcert.pem -inkey clientkey.pem \
-certfile cacert.pem -out client.p12 -name "VPN Client"
On client machine, import certificate and configure:
conn vpn-client
type = tunnel
keyexchange = ikev2
ike = aes128-sha2_256-modp2048!
esp = aes128-sha2_256!
left = %defaultroute
leftauth = pubkey
leftcert = clientcert.pem
leftid = [email protected]
right = 203.0.113.1
rightid = vpn.example.com
rightauth = pubkey
rightsourceip = %dhcp
auto = start
Split Tunneling
Configure split tunneling to route only specific traffic through the VPN.
Modify roadwarrior configuration to exclude certain traffic:
conn vpn-splitdns
type = tunnel
keyexchange = ikev2
left = %defaultroute
leftauth = pubkey
leftcert = clientcert.pem
right = 203.0.113.1
rightid = vpn.example.com
rightauth = pubkey
# Only route corporate subnet through VPN
rightsubnet = 192.168.1.0/24
auto = start
With this configuration, only traffic to 192.168.1.0/24 goes through VPN; other traffic uses local default route.
Configure traffic selectors for fine-grained control:
conn selective-vpn
type = tunnel
keyexchange = ikev2
left = %defaultroute
leftid = [email protected]
leftauth = pubkey
right = 203.0.113.1
rightid = vpn.example.com
rightauth = pubkey
# Multiple subnets through VPN
rightsubnet = 192.168.1.0/24,192.168.2.0/24,10.0.0.0/8
# Exclude 192.168.3.0/24 from VPN tunnel
leftsubnet = 0.0.0.0/0 except 192.168.3.0/24
auto = start
ipsec.conf Syntax
Understand the syntax and options for strongSwan configuration.
Common IKEv2 parameters:
ike = aes256-sha2_256-modp2048! # IKE encryption-hash-dhgroup
esp = aes256-sha2_256! # ESP encryption-hash
lifetime = 24h # Rekeying interval
dpdaction = restart # Dead peer detection action
dpddelay = 10s # Dead peer detection interval
Traffic selector options:
leftsubnet = 192.168.1.0/24 # Left subnet to protect
rightsubnet = 10.0.0.0/24 # Right subnet to protect
type = tunnel # tunnel vs transport mode
Authentication options:
leftauth = pubkey # Certificate-based
rightauth = psk # Pre-shared key
leftid = vpn.example.com # Identity
Source IP options:
rightsourceip = 10.8.0.0/24 # Assign IP from pool
rightsourceip = %dhcp # Dynamic allocation
rightsourceip = %config # Demand specific IP
Firewall Integration
Configure firewall rules to allow IPsec traffic.
Allow IKE (Internet Key Exchange) traffic:
sudo iptables -A INPUT -p udp --dport 500 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 4500 -j ACCEPT
Allow IPsec protocols (ESP and AH):
sudo iptables -A INPUT -p esp -j ACCEPT
sudo iptables -A INPUT -p ah -j ACCEPT
Allow traffic from VPN clients to internal networks:
sudo iptables -A FORWARD -i ipsec0 -s 10.8.0.0/24 -j ACCEPT
sudo iptables -A FORWARD -o ipsec0 -d 10.8.0.0/24 -j ACCEPT
Configure NAT for VPN clients:
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
Save rules:
sudo iptables-save > /etc/iptables/rules.v4
Using ufw (simplified):
sudo ufw allow 500/udp
sudo ufw allow 4500/udp
sudo ufw allow in on ipsec0
sudo ufw allow out on ipsec0
Monitoring and Troubleshooting
Monitor IPsec connections and troubleshoot issues.
View VPN status:
sudo ipsec status
sudo ipsec statusall
List all connections:
sudo ipsec listall
Monitor live traffic:
sudo ipsec traffic
View connected clients:
sudo ipsec leases
Check configuration syntax:
sudo ipsec checkconfig
Enable debugging:
sudo ipsec set-loglevel -c charon -d 3
View strongSwan logs:
sudo journalctl -u strongswan -f
Test connectivity through VPN:
ping 192.168.2.5 # Remote network address
Troubleshoot connection failures:
# Check IKE negotiation
sudo ipsec status
# Check SAD (Security Association Database)
sudo ip xfrm state
# Check SPD (Security Policy Database)
sudo ip xfrm policy
View detailed statistics:
sudo ipsec leases pool-name
sudo ipsec listcerts
sudo ipsec listcrl
Test with tcpdump to see actual IPsec packets:
sudo tcpdump -i eth0 'udp port 500 or udp port 4500 or esp'
Conclusion
strongSwan provides enterprise-grade IPsec VPN capabilities for diverse deployment scenarios. By following this guide, you've installed strongSwan, generated and managed X.509 certificates for secure authentication, configured IKEv2 tunnels for modern security, deployed site-to-site VPNs for network interconnection, set up roadwarrior access for remote clients, implemented split tunneling for selective routing, integrated with firewalls for security control, and established monitoring for ongoing operation. Whether protecting site-to-site traffic with mutual authentication or enabling remote workers with split-tunnel VPN, strongSwan scales from small deployments to large enterprise networks with transparent IPsec encryption and advanced security policies.


