Project

General

Profile

Migration from ipsec.conf to swanctl.conf

Basic structure of swanctl.conf

connections {
        connection-name {
                local {
                }
                remote {
                }
                children {
                        child-name {
                        }
                }
        }
}
pools {
}
secrets {
}
authorities {
}

You can have several connection names within the connections{} section and several child names within a children{} section. Empty sections can be omitted with the exception of the children{} section and at least one child-name{} sub-section. No section name may have dots in it, e.g. replace vpn.mysystems.tld with vpn-mysystems-tld or vpn_mysystems_tld. Connections are loaded by the swanctl --load-conns command.

In the main section of any connection you define things global to that connection like IKE version, your own and the peer's IP addresses, or algorithm proposals, dead peer detection and rekeying parameters for the IKE_SA.

In the local{} and remote{} sections you primarily define things related to authenticating the peers of the IKE_SA:

  • In the local{} section you define properties of your end of the connection, e.g. what authentication scheme, IDs and certificates to use. A lot of the left...= parameters have equivalents here.
  • In the remote{} section you define things that describe the remote end of the connection (basically constraints about the peers), again e.g. the authentication scheme, IDs and certificates to use. A lot of the right...= parameters have equivalents here.

There may be additional local{} and remote{} sections having arbitrary suffixes e.g. "-2" in remote-2, which describe additional authentication rounds (RFC 4739 for IKEv2, XAuth for IKEv1). Authentication rounds are ordered by their position in the config file, however, this can be influenced with the round setting.

In the children{} section you primarily define the local and remote traffic selectors and generally everything that belongs to negotiating CHILD_SAs, such as algorithm proposals and rekeying parameters.

The pools{} section defines named pools that can be referenced from a connection-name{} section. They are used to assign virtual IP addresses (roughly equivalent to rightsourceip) and other attributes like DNS servers (equivalent to rightdns). Pools configured here are loaded by swanctl --load-pools.

The secrets{} section is the equivalent to ipsec.secrets and is loaded by swanctl --load-creds. Note that private keys stored in sub-directories of the swanctl directory are loaded automatically (if they are encrypted and no password is configured in the secrets{} section swanctl will prompt the user for it, unless --noprompt is used).

In the documentation and manual pages the settings are named
  • connections.<conn>.remote<suffix>.auth=...
    or
  • connections.<conn>.children.<child>.local_ts=...

<conn> designates a connection name, <suffix> an optional extension to the given section name and <child> a child name. The <suffix> can be omitted in many cases except when defining secondary authentication rounds or e.g. when defining multiple secrets of the same type. Written out the two settings above appear as:

connections {
        connection_name {
                ...
                remote {
                        auth=...
                }
                children {
                        child_name {
                                local_ts=...
                        }
                }
        }
}

There may also be an authorities {} section corresponding to the ca <name> sections in ipsec.conf. In this case <name> becomes a sub-section within authorities {}. They are loaded by the swanctl --load-authorities command.

Migration Process

To migrate from ipsec.conf to swanctl.conf begin with the basic structure shown above. In most simple cases every conn name becomes a connection-name. However, in particular if also was used, they might also be added simply as additional child-name{} section. Then look up the old parameters in the following table and fill in the equivalent settings. Defaults can be omitted, but take care: the defaults sometimes differ between ipsec.conf and strongswan.conf. Also note that swanctl.conf has several new options that are not available in ipsec.conf.

The connection-name and the child-name may be equal. This comes in conveniently when bringing up connections manually: the command ipsec up refers to a conn <name> while the corresponding swanctl --initiate --child refers to a child-name. Keeping both equal makes things a bit easier. But remember: no dots in names!

/etc/ipsec.conf

config setup

cachecrls=yes in strongswan.conf:
charon.cache_crls=yes
charondebug in strongswan.conf, see LoggerConfiguration
strictcrlpolicy=no (default)
strictcrlpolicy=yes
strictcrlpolicy=ifuri
in swanctl.conf per connection:
connections.<conn>.remote<suffix>.revocation=relaxed (default)
connections.<conn>.remote<suffix>.revocation=strict
connections.<conn>.remote<suffix>.revocation=ifuri
uniqueids=yes|replace (default)
uniqueids=no
uniqueids=never
uniqueids=keep
in swanctl.conf per connection:
connections.<conn>.unique=replace (NOT default!)
connections.<conn>.unique=no (default!)
connections.<conn>.unique=never
connections.<conn>.unique=keep
/etc/ipsec.conf /etc/swanctl/swanctl.conf

conn <name>

connection-name{} or children-name{} section
aaa_identity=<id> connections.<conn>.local<suffix>.aaa_id
ah=<cipher suites> connections.<conn>.children.<child>.ah_proposals=<cipher suites>
aggressive=no (default)
aggressive=yes
connections.<conn>.aggressive=no (default)
connections.<conn>.aggressive=yes (insecure!)
also= see Referencing other Sections (since 5.7.0)
authby= deprecated, see left|rightauth
auto=ignore (default)
auto=add
auto=route
auto=start
no equivalent, comment out the connection instead
connections.<conn>.children.<child>.start_action=none (default)
connections.<conn>.children.<child>.start_action=trap
connections.<conn>.children.<child>.start_action=start
closeaction=none (default) | clear
closeaction=hold
closeaction=restart
connections.<conn>.children.<child>.close_action=none (default)
connections.<conn>.children.<child>.close_action=trap
connections.<conn>.children.<child>.close_action=start
compress=no (default)
compress=yes
connections.<conn>.children.<child>.ipcomp=no (default)
connections.<conn>.children.<child>.ipcomp=yes
dpdaction=none (default) connections.<conn>.dpd_delay=0s (default)
dpdaction=clear
dpdaction=hold
dpdaction=restart
connections.<conn>.dpd_delay != 0s plus one of
connections.<conn>.children.<child>.dpd_action=clear (default)
connections.<conn>.children.<child>.dpd_action=trap
connections.<conn>.children.<child>.dpd_action=start
dpddelay=30s (default)
dpddelay=0
connections.<conn>.dpd_delay=30s
connections.<conn>.dpd_delay=0s (default)
dpdtimeout=150s (default)
dpdtimeout=0
connections.<conn>.dpd_timeout=150s
connections.<conn>.dpd_timeout=0s (default)
inactivity=<time> connections.<conn>.children.<child>.inactivity=<time>
eap_identity=<id> (client/initiator) connections.<conn>.local<suffix>.eap_id=<id>
eap_identity=%identity (server/responder)
eap_identity=<id> (server/responder)
connections.<conn>.remote<suffix>.eap_id=%any
connections.<conn>.remote<suffix>.eap_id=<id>
esp=<cipher suites>!
esp=<cipher suites>
connections.<conn>.children.<child>.esp_proposals=<cipher suites>
connections.<conn>.children.<child>.esp_proposals=<cipher suites>,default
forceencaps=no (default) | yes connections.<conn>.encap=no (default) | yes
fragmentation=yes (default) | no | accept | force connections.<conn>.fragmentation=yes (default) | no | accept | force
ike=<cipher suites>!
ike=<cipher suites>
connections.<conn>.proposals=<cipher suites>
connections.<conn>.proposals=<cipher suites>,default
ikedscp=<value> connections.<conn>.dscp=<value>
ikelifetime=3h (default) connections.<conn>.rekey_time=170m
connections.<conn>.over_time=10m
see ExpiryRekey for details
installpolicy=yes (default) | no connections.<conn>.children.<child>.policies=yes (default) | no
keyexchange=ike (default)
keyexchange=ikev1
keyexchange=ikev2
connections.<conn>.version=0 (default)
connections.<conn>.version=1
connections.<conn>.version=2
keyingtries=3 (default)
keyingtries=%forever
connections.<conn>.keyingtries=3 (default: 1)
connections.<conn>.keyingtries=0
lifebytes=<number> connections.<conn>.children.<child>.life_bytes (default: 110% * rekey_bytes)
lifepackets=<number> connections.<conn>.children.<child>.life_packets (default: 110% * rekey_packets)
lifetime=1h (default) connections.<conn>.children.<child>.life_time=1h (default: 110% * rekey_time)
see ExpiryRekey for details
marginbytes=<number> no direct equivalent, but to achieve a similar result, configure:
connections.<conn>.children.<child>.life_bytes=lifebytes
connections.<conn>.children.<child>.rekey_bytes=lifebytes-marginbytes
connections.<conn>.children.<child>.rand_bytes=marginbytes*rekeyfuzz
marginpackets=<number> no direct equivalent, but to achieve a similar result, configure:
connections.<conn>.children.<child>.life_packets=lifepackets
connections.<conn>.children.<child>.rekey_packets=lifepackets-marginpackets
connections.<conn>.children.<child>.rand_packets=marginpackets*rekeyfuzz
margintime=9m (default) no direct equivalent, but to achieve a similar result, configure:
connections.<conn>.rekey_time=ikelifetime-margintime
connections.<conn>.over_time=margintime
connections.<conn>.rand_time=margintime*rekeyfuzz
and
connections.<conn>.children.<child>.life_time=lifetime
connections.<conn>.children.<child>.rekey_time=lifetime-margintime
connections.<conn>.children.<child>.rand_time=margintime*rekeyfuzz
see ExpiryRekey for details
mark=<value>[/<mask> ]
mark=%unique
mark=%unique-dir
connections.<conn>.children.<child>.mark_in=
connections.<conn>.children.<child>.mark_out=
(configure both)
mark_in= connections.<conn>.children.<child>.mark_in=
mark_out= connections.<conn>.children.<child>.mark_out=
mobike=yes (default) | no connections.<conn>.mobike=yes (default) | no
modeconfig=pull (default)
modeconfig=push
connections.<conn>.pull=yes (default)
connections.<conn>.pull=no (IKEv1 only)
reauth=yes (default)
reauth=no
connections.<conn>.reauth_time != 0
connections.<conn>.reauth_time=0 (default)
rekey=no connections.<conn>.rekey_time=0
connections.<conn>.reauth_time=0 (default)
connections.<conn>.children.<child>.life_time=0
connections.<conn>.children.<child>.life_bytes=0 (default)
connections.<conn>.children.<child>.life_packets=0 (default)
rekeyfuzz=100% (default) see marginbytes, marginpackets, margintime
replay_window=<value> (default: -1)
(-1 uses charon.replay_window from strongswan.conf, default 32)
connections.<conn>.children.<child>.replay_window=<value> (default: 32)
reqid=<number> connections.<conn>.children.<child>.reqid=<number>
sha256_96=no (default) | yes connections.<conn>.children.<child>.sha256_96=no (default) | yes
tfc=<value> (default: 0)
tfc=%mtu
connections.<conn>.children.<child>.tfc_padding=<value> (default: 0)
connections.<conn>.children.<child>.tfc_padding=mtu
type=tunnel (default)
type=transport
type=transport_proxy
type=passthrough
type=drop
connections.<conn>.children.<child>.mode=tunnel (default)
connections.<conn>.children.<child>.mode=transport
connections.<conn>.children.<child>.mode=transport_proxy
connections.<conn>.children.<child>.mode=pass
connections.<conn>.children.<child>.mode=drop
xauth=client (default) | server configure appropriate authentication rounds
xauth_identity=<id> connections.<conn>.local<suffix>.xauth_id=<id>
left=<value>
left=%<value != %any*>
connections.<conn>.local_addrs=<value>
see left|rightallowany
right=<value>
right=%<value != %any*>
connections.<conn>.remote_addrs=<value>
see left|rightallowany
left|rightallowany=yes | no (default) add 0.0.0.0/0,::/0 to local|remote_addrs
leftauth=<auth method>
rightauth=<auth method>
connections.<conn>.local<suffix>.auth=<auth method>
connections.<conn>.remote<suffix>.auth=<auth method>
leftauth2=<auth method>
rightauth2=<auth method>
connections.<conn>.local<suffix>.auth=<auth method>
connections.<conn>.remote<suffix>.auth=<auth method>
where local|remote<suffix> refer to a second authentication round
rightca=<issuer dn>
rightca=%same
connections.<conn>.remote<suffix>.cacerts=<ca certificates> (place in cacerts directory)
no equivalent as the cacerts option only applies to remote peers
rightca2=<issuer dn>
rightca2=%same
see above, but with a second authentication round
leftcert=<path>
rightcert=<path>
connections.<conn>.local<suffix>.certs=<filenames>
connections.<conn>.remote<suffix>.certs=<filenames>
(place in x509 directory)
left|rightcert=%smartcard[<slot>[@<module>]]:<keyid> connections.<conn>.local|remote<suffix>.cert<suffix>.handle=<keyid>
connections.<conn>.local|remote<suffix>.cert<suffix>.slot
connections.<conn>.local|remote<suffix>.cert<suffix>.module
left|rightcert2=<path> see above, but with a second authentication round
rightcertpolicy=<OIDs> connections.<conn>.remote<suffix>.cert_policy=<OIDs>
leftdns=<ip>
leftdns=%config4,%config6
no equivalent
rightdns=<ip>[,…] connections.<conn>.pools=<poolname>
pools.<poolname>.dns=<ip>[,…]
leftfirewall=no (default) connections.<conn>.children.<child>.updown=(empty, default)
leftfirewall=yes connections.<conn>.children.<child>.updown=<path to default updown script> iptables
e.g.
connections.<conn>.children.<child>.updown=/usr/local/libexec/ipsec/_updown iptables
rightgroups=<group list> connections.<conn>.remote<suffix>.groups=<group list>
rightgroups2=<group list> see above, but with a second authentication round
lefthostaccess=no (default) | yes connections.<conn>.children.<child>.hostaccess=no (default) | yes
lefttid=<id>
rightid=<id>
connections.<conn>.local<suffix>.id=<id>
connections.<conn>.remote<suffix>.id=<id>
rightid=%<id> no equivalent
left|rightid2=<id> see above, but with a second authentication round
leftikeport=<port>
rightikeport=<port>
connections.<conn>.local_port=<port>
connections.<conn>.remote_port=<port>
left|rightprotoport=<protocol>/<port> configured in local|remote_ts
left|rightrsasigkey= see left|rightsigkey
left|rightsigkey=<raw public key> no direct equivalent, store the keys in files and use
connections.<conn>.local<suffix>.pubkeys=<filenames>
connections.<conn>.remote<suffix>.pubkeys=<filenames>
leftsendcert=ifasked (default)
leftsendcert=never|no
leftsendcert=always|yes
connections.<conn>.send_cert=ifasked (default)
connections.<conn>.send_cert=never
connections.<conn>.send_cert=always
rightsendcert=never|no
rightsendcert=ifasked|always|yes
connections.<conn>.send_certreq=no
connections.<conn>.send_certreq=yes (default)
leftsourceip=%config4,%config6
leftsourceip=<ip address>
connections.<conn>.vips=0.0.0.0,::
connections.<conn>.vips=<ip address>
rightsourceip=<ip address>[,...]
rightsourceip=<network/netmask>
rightsourceip=<address range>
connections.<conn>.pools=<poolname>
pools.<poolname>.addrs=<ip address>[,...]
pools.<poolname>.addrs=<network/netmask>
pools.<poolname>.addrs=<address range>
rightsourceip=%config
rightsourceip=%dhcp
rightsourceip=%radius
no equivalent
connections.<conn>.pools=dhcp
connections.<conn>.pools=radius
leftsubnet=<ip subnet>[,...]
rightsubnet=<ip subnet>[,...]
connections.<conn>.children.<child>.local_ts=<ip subnet>[,...]
connections.<conn>.children.<child>.remote_ts=<ip subnet>[,...]
(only one subnet with IKEv1)
# left|rightsubnet=(not set) connections.<conn>.children.<child>.local|remote_ts=dynamic (default)
leftupdown=<path> connections.<conn>.children.<child>.updown=<path>
mediation=yes | no (default) connections.<conn>.mediation=yes | no (default)
mediated_by=<name> connections.<conn>.mediated_by=<name>
me_peerid=<id> connections.<conn>.mediation_peer=<id>

ca <name>

authorities.<name>
also=<name> see Referencing other Sections (since 5.7.0)
auto=ignore (default)
auto=add
no equivalent, comment out the sub-section instead
default
cacert=<path> authorities.<name>.cacert=<path>
crluri=<uri>
crluri1 (synonym for crluri)
crluri2=<uri2>
authorities.<name>.crl_uris=<uri>[,<uri2>][,...]
ocspuri=<uri>
ocspuri1 (synonym for ocspuri)
ocspuri2=<uri>
authorities.<name>.ocsp_uris=<uri>[,<uri2>][,...]
certuribase=<uri> authorities.<name>.cert_uri_base=<uri>
/etc/ipsec.secrets /etc/swanctl/swanctl.conf

/etc/ipsec.secrets

[ <username> ] : PSK <secret> secrets.ike<suffix>.secret=<secret>
secrets.ike<suffix>.id<suffix>=<username>
[ <username1> <username2> ] : PSK <secret> secrets.ike<suffix>.secret=<secret>
secrets.ike<suffix>.id<suffix1>=<username1>
secrets.ike<suffix>.id<suffix2>=<username2>
<username> : EAP <secret> secrets.eap<suffix>.secret=<secret>
secrets.eap<suffix>.id<suffix>=<username>
Analoguous for XAUTH secrets (via xauth sections), although that's really just an alias for EAP/eap. Both types of secrets are available for EAP and XAuth.
<username> : NTLM <secret> secrets.ntlm<suffix>.secret=<secret>
secrets.ntlm<suffix>.id<suffix>=<username>
: PIN %smartcard[<slot>[@<module>]]:<keyid> <pin> secrets.token<suffix>.handle=<keyid>
secrets.token<suffix>.slot
secrets.token<suffix>.module
secrets.token<suffix>.pin
: PIN %smartcard[<slot>[@<module>]]:<keyid> %prompt see above, but don't specify pin to get prompted by --load-creds
: P12 <PKCS#12 file> <passphrase> secrets.pkcs12<suffix>.file=<PKCS#12 file>
secrets.pkcs12<suffix>.secret=<passphrase>
Private keys stored in sub-directories of the swanctl directory are loaded automatically. Passwords for encrypted keys can be configured as follows. If not configured, --load-creds will prompt the user for it (so that's equivalent to configuring %prompt in ipsec.secrets).
: RSA|ECDSA|BLISS <key file> <passphrase> secrets.private<suffix>.file=<key file>
secrets.private<suffix>.secret=<passphrase>
The above works if the key is stored in the private sub-directory, which should work for all types of private keys with current releases. There are dirs/sections for specific key types if necessary.

Example

More example configs may be found here.