wiki:Hardening

Hardening OpenVPN

A number of things can be done to harden OpenVPN's security. This is a non-exclusive list of ways to harden OpenVPN on a number of levels.

Practice secure PKI management

This one is so obvious it's often missed in hardening/security review. Your security system is only as secure as its weakest link, and the PKI is no exception. Practice secure PKI management, safeguard your CA-related passphrases, and ensure you have the level of control and auditing over your PKI infrastructure as suitable for your security needs.

Some basic principles of secure PKI management can include:

  • Keep the CA PKI on a secure system:
    • Limited user login access
    • Limited software installed that could compromise the system
    • Do not perform CA PKI tasks as root; use a restricted/limited account
    • Maintain filesystem controls/access
  • Generate private keys on the target system
    • As above, do not use root/admin accounts to generate keypairs/requests
    • Do not transport private keys, even encrypted ones (attackers can attempt to guess/brute-force passphrases)
    • Any passphrase used needs to be shared/transported as well
    • When keys are shared, future compromise can't be as easily shown to come from a specific one
  • Use secure passphrases
    • A copied/stolen encrypted key is no good if the passphrase used to protect it is weak/guessable
    • Standard password practices apply, such as not re-using passwords elsewhere
  • Use a CRL, and quickly revoke lost/compromised keys
    • Generate/use a CRL upfront, even when initially empty (OpenVPN requires a restart to add this option later)
    • Ensure holders of issued certificates know to promptly report loss/compromise of private keys
    • Have a system in place for revoking certificates and deploying them to live systems
    • Consider if clients need a copy of the CRL as well; some considerations:
      • multiple servers?
      • re-issuance of a compromised server?
      • key rollover for other reasons prior to expiry?

X.509 key size

For asymmetric keys, general wisdom is that 1024-bit keys are no longer sufficient to protect against well-equipped adversaries. Use of 2048-bit is a good minimum. It is wise to ensure all keys across your active PKI (including the CA root keypair) are using at least 2048-bit keys.

Up to 4096-bit is accepted by nearly all RSA systems (including OpenVPN,) but use of keys this large will dramatically increase generation time, TLS handshake delays, and CPU usage for TLS operations; the benefit beyond 2048-bit keys is small enough not to be of great use at the current time. It is often a larger benefit to consider lower validity times than more bits past 2048, but that is for you to decide.

There is some reference material on the topic; in October of 2013 the European Union Agency for Network and Information Security released their Algorithms, Key Sizes and Parameters Report https://www.enisa.europa.eu/activities/identity-and-trust/library/deliverables/algorithms-key-sizes-and-parameters-report which specified that for "future system near term use", specified to be at least ten years, RSA keys of 3072 bits or more are recommended.

Use of --tls-version-min

As of OpenVPN 2.3.3, OpenVPN supports TLS version negotiation. Earlier versions only supported TLS 1.0. Also since OpenVPN 2.3.3, the --tls-version-min option is available to enforce a minimum TLS version. Hardened setups should set --tls-version-min to 1.2 if possible. But be aware that setting tls-version-min to 1.2 will make it impossible to connect for pre-2.3.3 clients, clients using the cryptoapicert option, or clients using on old TLS library version that does not support TLS 1.2. To allow clients using the cryptoapicert option to connect, do not set tls-version-min greater than 1.1.

Use of --tls-cipher

OpenVPN 2.4 and newer limits the default cipher list more than earlier versions did. This makes it less prudent to harden your configuration using --tls-cipher. Also be aware that it is very easy to create hard-to-debug connection failures when using --tls-cipher incorrectly. That said, further limiting the number of ciphers does reduce the attack surface.

In OpenVPN 2.3 and earlier, OpenVPN accepted a wide range of possible TLS cipher-suites by default. These versions can be hardened by limiting this to an acceptable list, (which can be just 1 cipher) as shown with openvpn --show-tls. Up to OpenVPN 2.3.2, only TLSv1.0 RSA ciphers are usable. You should use a DHE cipher-suite as well for forward-secrecy.

OpenVPN 2.3.3 enables support for TLSv1.2 cipher-suites, but note that requiring only TLSv1.2 cipher-suites is not backwards-compat with <=2.3.3 clients; your server/client may accept both a TLSv1.0 and TLSv1.2 option though, allowing older (pre-2.3.3) clients to connect as well.

It's wise to use as small of a list as possible for your --tls-cipher option. Exceptions could include if you wish to provide the client their choice of several acceptable options.

Limiting to TLSv1.0 DHE + RSA choices yields the following list, suitable for <=2.3.2 peers. DES choices are best avoided, especially single-DES (known very weak.)

  • TLS-DHE-RSA-WITH-AES-256-CBC-SHA
  • TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA
  • TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA
  • TLS-DHE-RSA-WITH-AES-128-CBC-SHA
  • TLS-DHE-RSA-WITH-SEED-CBC-SHA
  • TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA
  • TLS-DHE-RSA-WITH-DES-CBC-SHA
    • Avoid all DES cipher suites: DES is known to be very weak, 3DES-EDE is known to be weak
    • Avoid all RC4 cipher suites: RC4 is known to be weak
    • Avoid all EXPORT cipher suites: EXPORT is specified to be weak many years ago

The following are TLSv1.2 DHE + RSA choices, requiring a compatible peer running at least OpenVPN 2.3.3:

  • TLS-DHE-RSA-WITH-AES-256-GCM-SHA384
  • TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
  • TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
  • TLS-DHE-RSA-WITH-AES-128-CBC-SHA256

To use ECDH(E) or ECDSA cipher-suites, both client and server must be OpenVPN 2.4.0 or newer. (Older versions might work, but this is not something you can rely on.)

Use of --tls-auth

The --tls-auth option uses a static pre-shared key (PSK) that must be generated in advance and shared among all peers. This features adds "extra protection" to the TLS channel by requiring that incoming packets have a valid signature generated using the PSK key. If this key is ever changed, it must be changed on all peers at the same time (there is no support for rollover.)

The primary benefit is that an unauthenticated client cannot cause the same CPU/crypto load against a server as the junk traffic can be dropped much sooner. This can aid in mitigating denial-of-service attempts.

This feature by itself does not improve the TLS auth in any way, although it offers a 2nd line of defense if a future flaw is discovered in a particular TLS cipher-suite or implementation (such as CVE-2014-0160, Heartbleed, where the tls-auth key provided protection against attackers who did not have a copy). However, it offers no protection at all in the event of a complete cryptographic break that can allow decryption of a cipher-suite's traffic.

Generate a PSK with:

openvpn --genkey --secret ta.key

And reference it in the configs as such. The 0/1 value is arbitrary and must be the opposite between peers (or omitted entirely.)

# server-example
--tls-auth ta.key 0
# client-example
--tls-auth ta.key 1
Last modified 2 months ago Last modified on 03/26/17 17:16:17