Hardening OpenVPN on Windows

TRAN Ngoc Thach
5 min readJan 26, 2020


Default settings often work well in most cases. But knowing how to optimize the tool as well as its environment brings a stronger control over its operation, especially against corner cases which could backfire when least expected.

This article is specifically based on my setup of OpenVPN. That said, it’s for OpenVPN on Windows; tun-mode (i.e. Routing).

Hardening OpenVPN Server

  • Non-default port:

This may help against quick blocking of OpenVPN usage.

port 40000
  • UDP protocol:

Better protection against DoS attack and port scanning [1].

proto udp4
  • Large RSA Key size, i.e. DH_KEY_SIZE=4096:

More time to generate, but better safe than sorry. Bonus point: future-proof against Quantum Computing [2].

  • Large Symmetric Key:

This key is used to encrypt the Data Channel, and here we indicate the desired Cipher to be used. Advanced Encryption Standard with 256 bit key length. Nothing can be better! [3]

cipher AES-256-CBC
  • TLS minimum supported version:

As recommended in [5], it helps defend against Downgrade Attack [6].

tls-version-min 1.2
  • Stronger Hashing algorithm for message authentication:

According to [7], SHA-256 is advised. In addition, at present, no collision found for SHA-256 yet [8].

auth SHA-256
  • Disable logging:

When OpenVPN Server is running stably, it’s better to disable Logging, so no trace, particularly the Client’s Public IP address, is stored on disk.

verb 0
;status openvpn-status.log
  • Prevent DNS query leak:

DNS queries are carried out in Client side. With this setting pushed from Server to Client, no DNS queries are leaked outside of the VPN.

Plus, let’s ask Client to redirect its traffic through the OpenVPN interface.

push "block-outside-dns"
push "redirect-gateway def1"
  • Disable IPv6:

In my case, Client’s OS supports both IPv4 and IPv6. In addition, public IP addresses assigned by ISP are also available for both. However, Server’s OS only supports IPv4. When testing with [10] after the VPN was established, I found a serious issue: the public IPv4 in Client side is the public IPv4 of Server, which was expected; but the public IPv6 in Client side is its real IPv6, meaning it is leaked. There might be some settings to overcome this situation; but I do not know. I workarounded by simply disabling IPv6 on Client’s OS.

Disable IPv6
  • Hide TLS Handshake and reduce DoS Attacks:

The key file is used to not only authenticate, but also encrypt the TLS Control Channel, which helps hide the initialization of TLS handshake as well as preventing TLS DoS Attacks. (Meta)Data is encrypted twice, once by tls-crypt and once by the TLS session. See [11].

tls-crypt "ta.key"

Hardening OpenVPN Client

The Client shares some settings with the Servers’. They must be the same so that Server and Client can work well together in establishing the VPN.

proto udp4
tls-crypt "ta.key"
cipher AES-256-CBC
verb 0
auth SHA256

Another big setup in Client side is to enforce that there is no accidential traffic leaking out of the established VPN between Server and Client. Totally relying on correctly configuring OpenVPN all the time might be challenging. Therefore, we need “fail-safe” mode; in case things don’t turn out expectedly (Our expectation: all the Client’s traffic must go through the VPN toward Server, and contact the Internet up there), we just simply lose Internet connection, and no network package is leaked whatsovever.

To enforce such requirement, I leverage Windows built-in Firewall.

Update on 27.01.2020: To be more clear, this configuration assumes that the normal Internet network connection, which you use to connect to Internet without VPN, is of Public profile (see below: Ethernet, picture “Connection Types”). In contrast, the network connection under VPN is of Private profile (see below: ClientVPN, picture “Connection Types”). The OpenVPN process should access Internet directly via the normal connection, while any other processes, e.g. uTorrent, must be put through VPN connection.

Firstly, Inbound/Outbound connections are forbidden unless allowed.

Windows Firewall

Secondly, only allow specific programs, e.g. uTorrent, to access Internet through Private profile. Note: Of course, the OpenVPN Client (bin\openvpn.exe) must be allowed to access Internet directly.

Lastly, in Client side, the OpenVPN’s Tap-Interface must be made private:

Connection Types

Thanks to [12], find out the OpenVPN’s Tap-interface index (route print -4), e.g. 15. Then add a static route (route -p add mask metric 50 if 15). The is the IP address of the OpenVPN Server within the VPN. After that, when connecting to the remote OpenVPN Server, Windows will ask us to classify the Network as either Private or Public. Certainly, we choose Private. The key point here is that this configuration survives the reboot of the Client’s PC as well as disconnecting/reconnecting to OpenVPN Server.

From now on, in Client side, making a VPN toward the OpenVPN Server is as easy as clicking the Connect menu.

Connect to OpenVPN Server from OpenVPN Client GUI


After the VPN is established, how can one make sure that configuration is done correctly? Let’s test that with [10], [13] and [15] in a browser. Notice that it must return results as if the browser ran on the Server.


We have learned techniques to harden the use of OpenVPN in both Server and Client sides. On Linux, we might go even further, e.g. run OpenVPN in least privileged mode; however, it is outside the scope of this article because we’re using Windows! Protecting traffic by encrypting it through a VPN is great, but the presence of OpenVPN usage, to Network Administrators, is detectable. See [14]. Another technique, called Obfsproxy, can help obfuscate the OpenVPN traffic. But this might in turn raise suspicion…

Last but not least, I can’t stress enough the false assumption of utilizing powerful tools as well-illustrated here.

Source: https://xkcd.com/538/


[1] https://openvpn.net/community-resources/how-to/

[2] https://en.wikipedia.org/wiki/Key_size#Effect_of_quantum_computing_attacks_on_key_strength

[3] https://serverfault.com/questions/439471/which-openvpn-cipher-should-i-use

[4] https://community.openvpn.net/openvpn/wiki/Hardening

[5] https://community.openvpn.net/openvpn/wiki/Hardening#Useof--tls-version-min

[6] https://crypto.stackexchange.com/questions/10493/why-is-tls-susceptible-to-protocol-downgrade-attacks

[7] https://blog.g3rt.nl/openvpn-security-tips.html#15-use-sha-2-for-message-authentication

[8] https://crypto.stackexchange.com/questions/47809/why-havent-any-sha-256-collisions-been-found-yet

[9] https://forums.openvpn.net/viewtopic.php?t=22039

[10] https://ipv6-test.com/

[11] https://serverfault.com/questions/929484/openvpn-2-4-security-differences-between-tls-crypt-and-tls-auth

[12] https://superuser.com/questions/120038/changing-network-type-from-unidentified-network-to-private-network-on-an-openvpn

[13] https://www.where-am-i.net

[14] https://security.stackexchange.com/questions/187649/is-it-possible-to-detect-vpn-in-the-network

[15] https://www.dnsleaktest.com