DevTools Hub

Search tools

Search for a developer tool

OpenVPN Security Best Practices

Part of the VPN Toolkit

OpenVPN has been around since 2001, which is both its biggest strength and its biggest practical risk: it's mature, extensively audited, and runs on nearly everything, but it also carries two decades of accumulated defaults and options, some of which were reasonable choices in 2005 and are clearly outdated today. Unlike WireGuard, which ships with exactly one cipher suite, OpenVPN negotiates from a genuine menu of ciphers, digests, and control-channel options — which means the same software can produce a genuinely hardened config or a quietly weak one, both of which connect and pass traffic identically. This post covers the directives that actually matter.

Two separate channels, two separate concerns

OpenVPN runs two logically distinct channels over the same connection: the control channel, a TLS handshake that authenticates both sides and negotiates session keys, and the data channel, which actually encrypts your traffic using the keys the control channel produced. Hardening advice splits cleanly along this line — cipher and auth affect the data channel, while tls-auth/tls-crypt and remote-cert-tls affect the control channel — and a config can be strong on one side while neglecting the other.

The data channel: cipher and auth

cipher AES-256-GCM
# or, for OpenVPN 2.5+ cipher negotiation:
data-ciphers AES-256-GCM:AES-128-GCM

AES-256-GCM (or AES-128-GCM, or ChaCha20-Poly1305) is an AEAD cipher — authenticated encryption with associated data — meaning it provides both confidentiality and integrity in one operation, with no separate HMAC step needed. Older configs commonly specify cipher AES-256-CBC paired with a separate auth SHA256 digest, which still works but is the more complex, pre-AEAD way of achieving the same goal. What's worth actively removing: BF-CBC (Blowfish, OpenVPN's old default and now deprecated), any bare DES variant, and auth MD5 or bare auth SHA1 — all considered weak or broken by current standards, even though OpenVPN itself raises no error using them.

The control channel: tls-auth and tls-crypt

A TLS handshake, by itself, responds to anyone who initiates one — which means an OpenVPN server with no additional control-channel protection replies to any TCP or UDP probe on its port, visible to port scanners and a target for certain denial-of-service attempts against the TLS stack itself.

# Authenticates the control channel (older, still common)
tls-auth ta.key 0

# Authenticates AND encrypts the control channel (newer, recommended)
tls-crypt ta.key

Both use a pre-shared static key, distributed to every legitimate client ahead of time, to add an HMAC signature to control-channel packets — a server configured this way silently drops any packet that doesn't carry a valid signature, before it does any TLS processing at all, which is exactly what makes it invisible to a scanner that doesn't have that key. tls-crypt goes one step further and encrypts the control channel too, hiding the TLS handshake's contents — including which client certificate is being presented — from anyone observing the traffic. Neither directive protects the data channel itself; that's cipher's job.

Verifying you're actually talking to the server

remote-cert-tls server

Without this, a client only confirms the presented certificate was signed by a trusted CA — not that it specifically belongs to the server rather than to some other client certificate signed by the same CA. remote-cert-tls server additionally checks the certificate's extended key usage field for the server role, closing a real, if narrow, impersonation gap in setups using a shared CA for both server and client certificates.

Compression and the VORACLE attack

# Avoid:
comp-lzo yes
compress lzo

# Prefer: no compression, or phasing it out
compress migrate

VORACLE is a real, published attack against VPN protocols that compress traffic before encrypting it: an attacker who can inject chosen content into the tunnel (the canonical scenario involves a malicious web page causing the victim's browser to send attacker-chosen data over the connection) can observe how much the resulting ciphertext shrinks and use that to recover parts of the original plaintext. The fix costs nothing — disable compression entirely, or use compress migrate, which negotiates compression off while remaining compatible with older peers during a transition period.

Key renegotiation

reneg-sec 3600  # default: renegotiate session keys hourly

OpenVPN periodically renegotiates the TLS session and derives fresh data-channel keys by default — reneg-sec 0 disables this, meaning the same keys are used for the entire life of a long-running connection instead of being rotated. There's rarely a good reason to disable it; the default interval already balances security against the modest overhead of a renegotiation handshake.

Revoking access when a client shouldn't have it anymore

# On the CA/server: revoke a client certificate
easyrsa revoke client-name
easyrsa gen-crl

crl-verify crl.pem

A server-config detail that's easy to skip entirely: without crl-verify pointing at a current Certificate Revocation List, a client certificate remains valid forever, even after that person leaves a team or a device is decommissioned — the server has no way to reject it short of rebuilding the entire CA. crl-verify tells OpenVPN to check every connecting client's certificate against a list the administrator maintains and regenerates whenever access needs to be pulled, which is the actual mechanism behind "revoke this person's VPN access" rather than something that happens automatically just because someone stopped using their credential.

Common mistakes

  • Carrying forward an old config's cipher choice unreviewed. A working config from years ago connects identically whether it's using AES-256-GCM or BF-CBC — nothing about day-to-day behavior tells you which.
  • Skipping tls-auth/tls-crypt entirely. The server still works without it; it's just visibly responsive to anyone probing the port.
  • Leaving compression on out of habit. A VORACLE-relevant configuration that costs real security for negligible benefit on already-compressed modern traffic.
  • Distributing the same .ovpn file to multiple people. If it embeds a private key, that file is a shared credential — anyone who has a copy can connect as that identity, with no way to revoke just one copy.
  • Assuming remote-cert-tls is implied by TLS working at all. A successful TLS handshake only proves the certificate is validly signed, not that it belongs to the server specifically.

FAQ

What's the actual difference between tls-auth and tls-crypt?

tls-auth adds an HMAC signature to control-channel packets, letting the server verify a packet came from someone holding the shared key before it does any TLS processing — but the TLS handshake content itself is still visible to an observer. tls-crypt does both: it encrypts the control channel with the shared key in addition to authenticating it, hiding the handshake (and, notably, the client's certificate) from network observation. tls-crypt is the newer, stricter option; tls-auth remains for compatibility with older setups.

If I'm using an AEAD cipher like AES-256-GCM, do I still need an auth directive?

No — AEAD ciphers authenticate the data channel as part of encryption itself, making a separate auth digest redundant for that purpose. The auth directive still matters for the control channel in older negotiation modes, and for compatibility with peers that haven't moved to AEAD-only negotiation, but a modern client-server pair negotiating AES-256-GCM doesn't need auth SHA256 doing extra, unnecessary work on the data channel.

Is UDP or TCP more secure for OpenVPN?

Neither is inherently more secure — the security properties (TLS handshake, cipher, authentication) are identical either way. TCP-over-TCP has a well-known performance problem ("TCP meltdown") when both the outer transport and something inside the tunnel are TCP and packet loss occurs, since both layers try to retransmit independently. UDP is the default recommendation for that reason; TCP is mainly useful when a network only allows outbound traffic on ports conventionally associated with TCP, like 443.

Does disabling compression hurt performance meaningfully?

For most traffic today — already-compressed video, images, and TLS-encrypted web traffic — compression achieves close to nothing anyway, since compressing already-compressed or already-encrypted data doesn't shrink it further. The VORACLE risk applies specifically when compression is combined with encryption on data that does compress well and where an attacker can inject chosen content, making the security cost outweigh the now-marginal benefit for nearly all setups.

What does remote-cert-tls server actually prevent?

Without it, any certificate signed by the same certificate authority — including another legitimate client's certificate — could technically be used to impersonate the server, since OpenVPN alone doesn't distinguish a server certificate from a client one by role. remote-cert-tls server tells the client to check the certificate's extended key usage field specifically for the server flag, closing that gap.

Try it yourself

OpenVPN Config Auditor checks an .ovpn file for every issue covered here — deprecated ciphers, weak digests, missing tls-crypt, and VORACLE-vulnerable compression — entirely in your browser.

Related tools