Migration from ipsec.conf to swanctl.conf¶
- Table of contents
- Migration from ipsec.conf to swanctl.conf
Basic structure of swanctl.conf¶
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 theleft...=
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 theright...=
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).
connections.<conn>.remote<suffix>.auth=...
orconnections.<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:
The two settings above expanded from dot-notation
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¶
Automated¶
Noel Kuntze wrote a python script for translating ipsec.conf to swanctl.conf.
Manual¶
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) |
connections.<conn>.aggressive=no (default) |
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 (default: 4h) connections.<conn>.over_time=10m (default: 10% of rekey_time) 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) or preferably connections.<conn>.children.<child>.rekey_bytes |
lifepackets=<number> | connections.<conn>.children.<child>.life_packets (default: 110% * rekey_packets) or preferably connections.<conn>.children.<child>.rekey_packets |
lifetime=1h (default) | connections.<conn>.children.<child>.life_time=1h (default: 110% * rekey_time) but configuring connections.<conn>.children.<child>.rekey_time (default: 1h, so setting life_time to 1h without changing this, will disable rekeying) instead is preferred, see below and ExpiryRekey for details |
marginbytes=<number> | no direct equivalent, but to achieve a similar result, configure: connections.<conn>.children.<child>.rekey_bytes=lifebytes-marginbytes connections.<conn>.children.<child>.life_bytes=lifebytes (default: 110% * rekey_bytes) connections.<conn>.children.<child>.rand_bytes=marginbytes*rekeyfuzz (default: life_bytes - rekey_bytes |
marginpackets=<number> | no direct equivalent, but to achieve a similar result, configure: connections.<conn>.children.<child>.rekey_packets=lifepackets-marginpackets connections.<conn>.children.<child>.life_packets=lifepackets (default: 110% * rekey_packets) connections.<conn>.children.<child>.rand_packets=marginpackets*rekeyfuzz (default: life_packets - rekey_packets) |
margintime=9m (default) | no direct equivalent, but to achieve a similar result, configure: connections.<conn>.rekey_time=ikelifetime-margintime connections.<conn>.over_time=margintime (default: 10% of rekey_time) connections.<conn>.rand_time=margintime*rekeyfuzz (default: over_time) and connections.<conn>.children.<child>.rekey_time=lifetime-margintime connections.<conn>.children.<child>.life_time=lifetime (default: 110% * rekey_time) connections.<conn>.children.<child>.rand_time=margintime*rekeyfuzz (default: life_time - rekey_time) 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 |
leftid=<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.
IKEV2 Responder with Public Key Authentication and EAP-MSCHAP2