[[TOC(depth=2)]] = Hardening OpenVPN = This is a work in progress. 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-cipher == By default, OpenVPN accepts a wide range of possible TLS cipher-suites; hardened systems should limit this to an acceptable list (which can be just 1) cipher as shown with `openvpn --show-tls`. '''As of OpenVPN 2.3.3, only TLSv1.0 RSA ciphers are usable'''. You should use a DHE cipher-suite as well for forward-secrecy. A git-master (slated to be included in >=2.3.4) 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. 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 still fine)^ * ^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 (git-master today, and targeted for a future >=2.3.4 version.): * 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 Today, OpenVPN does not support TLS-ECDHE-* or more exotic cipher-suites as there is no elliptic curve support currently. == 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 }}}