Security Recommendations
There are a couple of security-relevant topics that have to be considered when using strongSwan to set up IKE connections and policy-based IPsec tunnels.
Weak Cryptographic Algorithms
The following cryptographic algorithms are weak and prone to attacks and therefore must not be used.
- Encryption
-
des,3des,cast,blowfish
- Integrity Protection / Pseudo Random Functions
-
md5,sha1
- Diffie-Hellman Groups
-
modp512,modp768,modp1024,modp1024s160,modp1536,modp2048s224,modp2048s256,ecp192
These algorithms do not directly relate to plugins. To disable them you must
specify a set of crypto proposals that exclude these algorithms in the connection
definitions of swanctl.conf
connections.<conn>.proposals connections.<conn>.children.<child>.esp_proposals connections.<conn>.children.<child>.ah_proposals
Do not set ah_proposals
unless you want the CHILD_SA to use the AH
(Authentication Header) IPsec protocol instead of the ESP
(Encapsulating Security
Payload) IPsec protocol or UDPENCAP
(ESP in UDP Encapsulation) used when a NAT
situation is detected or when UDPENCAP
is explicitly enforced.
If no explicit proposals are defined in swanctl.conf then strongSwan uses its default proposals that neither propose nor accept any of the weak algorithms listed above, with the exception of 3des and sha1 which are still heavily used e.g. by Microsoft Windows. |
Certificate Trust Chain Verification
If you want to enforce specific (strong) algorithms in the certificate chain of the
peer, you can do this using the
remote.auth
settings in
swanctl.conf
.
Here is an example for enforcing the use of sha256
, sha384
or sha512
in the certificate trust chain and to reject any other hashing algorithms. The same
can be done for the algorithm of the actual pubkey (RSA or ECDSA).
Examples:
connection.<conn>.remote.auth = pubkey-sha256-sha384-sha512 connection.<conn>.remote.auth = rsa-sha256-sha384-sha512 connection.<conn>.remote.auth = ecdsa-sha384
Cipher Selection
The available ciphers for IKE depend on the crypto modules loaded in the IKE
charon
daemon. For kernel processing of ESP and AH
packets the available ciphers depend on the kernel support for them and if
they are supported by the XFRM
or PF_KEY
kernel interface.
It is advised to adhere to the recommendation of the appropriate security authority
when choosing ciphers to secure the tunnel cryptographically. keylength.com
lists some of the standards for western Europe and the US. It is strongly advised
to use at least a 2048
bit key length for MODP Diffie-Hellman groups.
The National Institute of Standards and Technology (NIST) has mandated that a minimum cryptographic strength of 128 bit is sufficient for security beyond the year 2030. This results in the following cipher set:
aes128-sha256-modp3072
For systems without support for SHA-256, SHA-1 might be used instead. SHA-1 must not be used for anything else than an HMAC for IKE or ESP.
Alternatively the Commercial National Security Algorithm (CNSA) Suite may also be used where supported
aes256-sha384-ecp384,aes256gcm16-prfsha384-ecp384
The supported algorithm proposal keywords are limited
to what the various libstrongswan
plugins implement.
The supported ESP/AH cipher suites are limited to what the Linux kernel supports.
If you’re using userland ESP encryption based on the
kernel-libipsec
plugin then all IKE algorithms
are also available for ESP.
Preshared Keys
There is nothing to be said against Pre-Shared Keys (PSKs) as long as they are
chosen randomly with sufficient entropy. The openssl rand
command can be used
to generate a PSK with >256
bit entropy converted to base64 format:
$ openssl rand -base64 33 bjsqbPZB3Isk/RHMCH6Pe9G+TDc4tJVmbvRlWLXMSjS+
Alternatively the dd
command can be used to directly retrieve the entropy
either from /dev/random
or the non-blocking /dev/urandom
device
$ dd if=/dev/random count=1 bs=33 2>/dev/random | base64 s1Jy/Li0Bkqmd3C7eYG71EoPxmcataF/LL4ATA3gE+au
The PSK can then be used in the
secrets
section of
swanctl.conf
to configure the IKE user
credentials
secrets { ike-alice { id = alice@strongswan.org secret = 0sbjsqbPZB3Isk/RHMCH6Pe9G+TDc4tJVmbvRlWLXMSjS+ } ike-bob { id = bob@strongswan.org secret = 0ss1Jy/Li0Bkqmd3C7eYG71EoPxmcataF/LL4ATA3gE+au } }
For base64-encoded secrets the 0s
prefix is used whereas 0x
designates a
hex-encoded value.
IKEv1 Aggressive Mode with PSK Authentication
IKEv1 Aggressive Mode is inherently flawed, as a hash of the PSK is transmitted in the clear, which a passive attacker can directly use to try to crack the password using an offline dictionary or brute force attack. Thus it is strongly advised to avoid IKEv1 Aggressive Mode.
MITM Attacks on IKEv2 PSK Authentication
If user credentials don’t have enough entropy what is usually the case if you let the users freely choose their passwords, then PSK-based IKEv2 authentication is vulnerable to active Man-In-The-Middle (MITM) attacks.
Since a VPN client is usually the IKEv2 initiator, it sends its AUTH payload containing the password hash in the IKE_AUTH request to an unauthenticated and thus untrusted VPN server. If an attacker inserts herself into the IKE connection between client and server she can intercept the AUTH payload and start an offline dictionary or brute force attack on the PSK.
Thus it is of utmost importance that cryptographically strong PSKs are used with PSK-based authentication. Since in most cases this cannot be enforced, we highly recommend to use EAP-based authentication instead where the VPN server is authenticated first based on a X.509 server certificate, so that the VPN client can then send its [potentially weak] password hash later on to a trusted peer.
Certificate-based Authentication
Certificate-based authentication is inherently stronger than PSK-based authentication. A properly built PKI architecture has usually one root CA and one or several intermediate CAs, where the private key of the intermediate CA is used to sign the end entity certificates and the private key of the root CA can be kept on a smartcard stored in a safe or at lease on a system disconnected from the Internet. The private root CA key is never stored on an insecure or online system. Securing the root CA enables the PKI administrator to revoke any certificates and recreate the PKI from scratch, if any intermediate CAs are compromised.
Using the default revocation
plugin, Certificate Revocation Lists (CRLs) and
the Online Certificate Status Protocol (OCSP) can be used to check if a given
certificate has been revoked for some reason. strongSwan supports locally-stored
CRLs, as well as fetching fresh CRLs and OCSP information via the fetcher plugins
curl
, soup
or winhttp
.
CRL Distribution Points (CDPs) are either retrieved from the certificate or can
be added manually using an
authorities
section in
swanctl.conf
.
X.509 certificates should be based on RSA public keys with a modulus of at least
2048
bits (preferably 3072
bits for end entity certificates and 4096
bits for CA certificates). Alternatively ECDSA public keys with at least 256
bits (preferably 384
bits) can be used. For certificate signatures at least
SHA-256 must be used since both SHA-1 and MD5 are hopelessly broken.
All X.509 certificates must conform to the PKIX Internet standard
(RFC 5280).
Perfect Forward Secrecy
Perfect Forward Secrecy (PFS) is strongly recommended to make IPsec peers negotiate an independent session key for each IPsec or CHILD SA. This protects the long-term confidentiality of the IPsec traffic if the IKE shared secret is leaked. Note that the session keys of the first CHILD_SA of a new IKEv2 connection are derived from the IKE shared secret. However, subsequent CHILD_SAs will use independent keys if PFS is used.
PFS is enabled by appending a DH group to the ESP or AH cipher proposal. Using PFS introduces no significant performance overhead, unless you rekey more than about 80 CHILD_SAs per second.
Tunnel Shunting
As IPsec connections on Linux are usually policy-based, there is no tunnel interface over which packets are routed. Instead XFRM policies and states transform the packet transparently.
Note that any traffic for which there is no matching IPsec policy will not be
subject to IPsec processing. This can cause traffic leakage into your LAN and into
the attached WAN. Such a scenario can occur when your site-to-site tunnel is
configured with start_action = none
and your firewall rules do not drop packets
that should be protected with IPsec but actually aren’t.
Usually it is highly undesired to let such traffic just pass. Take care to shunt
the connections correctly using the policy
match module in iptables
.
It is strongly advised to use start_action = trap
in site-to-site setups to
make sure that the kernel tells the charon
daemon
to establish a CHILD_SA
when there is no SA for a security policy. It is advisable
to take a look at the strongswan.conf
setting
charon.ignore_acquire_ts
when doing this.
RFC1918 private networks and others that are not allowed to be used on
the public Internet must not occur in the source or destination fields of an IP
packet. A suitable method to prevent that is to use an iptables
rule that
rejects or drops packets with such a destination without a matching IPsec policy
using the policy
match module. An alternative is to use a DROP
policy in the
configuration with a higher priority than the normal IPsec policies.
If you do not know the priorities of your normal rules, check them with
ip xfrm policy
. If the priorities automatically computed by the
charon
daemon based on the traffic selectors do not
fit (see kernel_netlink_ipsec.c
) then the priority of the XFRM policies
can be set manually in
swanctl.conf
via
the <child>.priority
attribute.
If you NAT traffic into the tunnel by using DNAT, SNAT or MASQUERADE, the traffic
selector of the DROP policy must be adjusted accordingly. The IPsec SPD in the
kernel or the charon
daemon are not aware of your
firewall’s NAT rules. Again the priority of the DROP policy must be higher than
the one of your normal policies.
DROP Policy Example
connections { shunts { rekey_time = 0 local_addrs = 127.0.0.1 remote_addrs = 127.0.0.1 children { # prevent unprotected traffic from any network to the roadwarriors drop-rwv4 { # internet local_ts = 0.0.0.0/0 # roadwarrior subnet remote_ts = 172.16.20.0/24 mode = drop start_action = trap } # enabling policies_fwd_out is necessary for other children to avoid forwarded traffic from getting dropped } } }
In the following example, the REJECT target is used to give the user a clear error message.
iptables -A FORWARD -d 10.0.0.0/8 -m policy --pol none --dir out -j REJECT --reject-with icmp-admin-prohibited
Generally it is important to understand how iptables
/Netfilter work together
with XFRM to design suitable firewall rules that protect your network in case tunnels
go down or can not be brought up. When NAT is brought into the discussion, it can
be impossible to design a general rule in iptables
that just drops the
unprotected packets and specific rules need to be inserted for your specific NATed
addresses.