Strongswan
strongSwan - IPsec-based VPN
Install / Use
/learn @strongswan/StrongswanREADME
strongSwan Configuration
Overview
strongSwan is an OpenSource IPsec-based VPN solution.
This document is just a short introduction of the strongSwan swanctl command which uses the modern vici Versatile IKE Configuration Interface. The deprecated ipsec command using the legacy stroke configuration interface is described here. For more detailed information consult the man pages, our new documentation site and the legacy wiki.
Quickstart
Certificates for users, hosts and gateways are issued by a fictitious
strongSwan CA. In our example scenarios the CA certificate strongswanCert.pem
must be present on all VPN endpoints in order to be able to authenticate the
peers. For your particular VPN application you can either use certificates from
any third-party CA or generate the needed private keys and certificates yourself
with the strongSwan pki tool, the use of which will be explained in one of
the sections following below.
Site-to-Site Case
In this scenario two security gateways moon and sun will connect the two subnets moon-net and sun-net with each other through a VPN tunnel set up between the two gateways:
10.1.0.0/16 -- | 192.168.0.1 | === | 192.168.0.2 | -- 10.2.0.0/16
moon-net moon sun sun-net
Configuration on gateway moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
net-net {
remote_addrs = 192.168.0.2
local {
auth = pubkey
certs = moonCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=sun.strongswan.org"
}
children {
net-net {
local_ts = 10.1.0.0/16
remote_ts = 10.2.0.0/16
start_action = trap
}
}
}
}
Configuration on gateway sun:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/sunCert.pem
/etc/swanctl/private/sunKey.pem
/etc/swanctl/swanctl.conf:
connections {
net-net {
remote_addrs = 192.168.0.1
local {
auth = pubkey
certs = sunCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=moon.strongswan.org"
}
children {
net-net {
local_ts = 10.2.0.0/16
remote_ts = 10.1.0.0/16
start_action = trap
}
}
}
}
The local and remote identities used in this scenario are the subjectDistinguishedNames contained in the end entity certificates. The certificates and private keys are loaded into the charon daemon with the command
swanctl --load-creds
whereas
swanctl --load-conns
loads the connections defined in swanctl.conf. With start_action = trap the
IPsec connection is automatically set up with the first plaintext payload IP
packet wanting to go through the tunnel.
Host-to-Host Case
This is a setup between two single hosts which don't have a subnet behind them. Although IPsec transport mode would be sufficient for host-to-host connections we will use the default IPsec tunnel mode.
| 192.168.0.1 | === | 192.168.0.2 |
moon sun
Configuration on host moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
host-host {
remote_addrs = 192.168.0.2
local {
auth=pubkey
certs = moonCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=sun.strongswan.org"
}
children {
net-net {
start_action = trap
}
}
}
}
Configuration on host sun:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/sunCert.pem
/etc/swanctl/private/sunKey.pem
/etc/swanctl/swanctl.conf:
connections {
host-host {
remote_addrs = 192.168.0.1
local {
auth = pubkey
certs = sunCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=moon.strongswan.org"
}
children {
host-host {
start_action = trap
}
}
}
}
Roadwarrior Case
This is a very common case where a strongSwan gateway serves an arbitrary number of remote VPN clients usually having dynamic IP addresses.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
Configuration on gateway moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = pubkey
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
}
}
Configuration on roadwarrior carol:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/carolCert.pem
/etc/swanctl/private/carolKey.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
local {
auth = pubkey
certs = carolCert.pem
id = carol@strongswan.org
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
For remote_addrs the hostname moon.strongswan.org was chosen which will be
resolved by DNS at runtime into the corresponding IP destination address.
In this scenario the identity of the roadwarrior carol is the email address
carol@strongswan.org which must be included as a subjectAlternativeName in
the roadwarrior certificate carolCert.pem.
Roadwarrior Case with Virtual IP
Roadwarriors usually have dynamic IP addresses assigned by the ISP they are currently attached to. In order to simplify the routing from moon-net back to the remote access client carol it would be desirable if the roadwarrior had an inner IP address chosen from a pre-defined pool.
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x | -- 10.3.0.1
moon-net moon carol virtual IP
In our example the virtual IP address is chosen from the address pool
10.3.0.0/16 which can be configured by adding the section
pools {
rw_pool {
addrs = 10.3.0.0/16
}
}
to the gateway's swanctl.conf from where they are loaded into the charon
daemon using the command
swanctl --load-pools
To request an IP address from this pool a roadwarrior can use IKEv1 mode config or IKEv2 configuration payloads. The configuration for both is the same
vips = 0.0.0.0
Configuration on gateway moon:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
pools = rw_pool
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = pubkey
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
}
}
pools {
rw_pool {
addrs = 10.30.0.0/16
}
}
Configuration on roadwarrior carol:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/carolCert.pem
/etc/swanctl/private/carolKey.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
vips = 0.0.0.0
local {
auth = pubkey
certs = carolCert.pem
id = carol@strongswan.org
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
Roadwarrior Case with EAP Authentication
This is a very common case where a strongSwan gateway serves an arbitrary number of remote VPN clients which authenticate themselves via a pas
Related Skills
node-connect
335.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
82.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
335.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
82.7kCommit, push, and open a PR
