Configuration 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 is explained
in the certificates quickstart section.
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
(DNs) 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 { host-host { 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 { rw { 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 { remote_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 subjectAltName
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 { rw { local_ts = 10.1.0.0/16 } } } } pools { rw_pool { addrs = 10.3.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 { remote_ts = 10.1.0.0/16 start_action = start } } } }
Roadwarrior Case with EAP
This is a very common case where a strongSwan gateway serves an arbitrary
number of remote VPN clients which authenticate themselves via a password-based
Extended Authentication Protocol as e.g. EAP-MD5
or EAP-MSCHAPv2
.
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 = eap-md5 } children { rw { local_ts = 10.1.0.0/16 } } send_certreq = no } }
The swanctl.conf
file additionally
contains a secrets
section defining all client credentials
secrets { eap-carol { id = carol@strongswan.org secret = Ar3etTnp } eap-dave { id = dave@strongswan.org secret = W7R0g3do } }
Configuration on roadwarrior carol
:
/etc/swanctl/x509ca/strongswanCert.pem /etc/swanctl/swanctl.conf: connections { home { remote_addrs = moon.strongswan.org local { auth = eap id = carol@strongswan.org } remote { auth = pubkey id = moon.strongswan.org } children { home { remote_ts = 10.1.0.0/16 start_action = start } } } } secrets { eap-carol { id = carol@strongswan.org secret = Ar3etTnp } }
Roadwarrior Case with EAP Identity
Often a client EAP identity is exchanged via EAP which differs from the external IKEv2 identity. In this example the IKEv2 identity defaults to the IPv4 address of the client.
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 = eap-md5 eap_id = %any } children { rw { local_ts = 10.1.0.0/16 } } send_certreq = no } } secrets { eap-carol { id = carol secret = Ar3etTnp } eap-dave { id = dave secret = W7R0g3do } }
Configuration on roadwarrior carol
:
/etc/swanctl/x509ca/strongswanCert.pem /etc/swanctl/swanctl.conf: connections { home { remote_addrs = moon.strongswan.org local { auth = eap eap_id = carol } remote { auth = pubkey id = moon.strongswan.org } children { home { remote_ts = 10.1.0.0/16 start_action = start } } } } secrets { eap-carol { id = carol secret = Ar3etTnp } }
Passthrough/bypass policies
Passthrough or bypass policies allow excluding specific traffic from IPsec processing.
For a local LAN
To automatically install passthrough policies for locally connected subnets,
the bypass-lan
plugin may be used.
The following is a manual passthrough policy that applies to packets from and
to the 10.0.0.0/8
subnet. remote_addrs
is set to 127.0.0.1
to
prevent this connection from being considered if a peer connects.
/etc/swanctl/swanctl.conf: connections { passthrough-lan { remote_addrs = 127.0.0.1 children { passthrough-lan { local_ts = 10.0.0.0/8 remote_ts = 10.0.0.0/8 mode = pass start_action = trap } } } }
For arbitrary subnets/addresses
The following is a passthrough policy that applies to packets that are sent
from an address in 192.168.2.0/24
to an address in 10.1.0.0/24
or
vice-versa.
/etc/swanctl/swanctl.conf: connections { passthrough-subnet { remote_addrs = 127.0.0.1 children { passthrough-subnet { local_ts = 10.1.0.0/24 remote_ts = 192.168.2.0/24 mode = pass start_action = trap } } } }
For specific protocols and/or ports
The following is a passthrough policy that allows traffic to the local SSH port from any remote address/port.
/etc/swanctl/swanctl.conf: connections { passthrough-ssh { remote_addrs = 127.0.0.1 children { passthrough-ssh { local_ts = dynamic[tcp/22] remote_ts = 0.0.0.0/0 mode = pass start_action = trap } } } }
For specific port ranges
The following is a passthrough policy that allows traffic to the local TCP port
range 65000-65255
from any remote address/port. Using the little-known
capability of the kernel-netlink
plugin to implement port ranges defined by
a bit mask (similar to an IP subnet mask), the arbitrary port range defined above
can be split into the following six contiguous subranges described by a bit mask
each:
port subrange | number of ports in range | start port | end port | bit mask |
---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/etc/swanctl/swanctl.conf: connections { passthrough-port-range { remote_addrs = 127.0.0.1 children { passthrough-port-range { local_ts = dynamic[tcp/65000-65007],dynamic[tcp/65008-65023],dynamic[tcp/65024-65151],dynamic[tcp/65152-65215],dynamic[tcp/65216-65247],dynamic[tcp/65248-65255] remote_ts = 0.0.0.0/0 mode = pass start_action = trap } } } }