Improving my OpenVPN Ansible Playbook

I had a working OpenVPN configuration. But it wasn’t the best it could be. The manpage for OpenVPN 2.3 ( was used to find particularly interesting options.

For most of the changes I had to find examples and more information through Googling, though is of particular note for popping up very often.

Improving TLS Security

  1. Added auth SHA256 so MACs on the individual packets are done with SHA256 instead of SHA1.

  2. Added tls-version-min 1.2 to drop SSL3 + TLS v1.0 support. This breaks older clients (2.3.2+), but those updated versions have been out for a while.

  3. Restricted the tls-ciphers allowed to a subset of Mozilla’s modern cipher list + DHE for older clients. ECDSA support is included for when ECDSA keys can be used. I’m uncertain of the usefulness of the ECDHE ciphers, as both my client and server support it, but the RSA cipher that’s 3rd in the list is still used. Continuing to investigate this.

The last 2 changes are gated by the openvpn_use_modern_tls variable, which defaults to true.

  1. New keys are 2048 bit by default, downgraded from 4096 bit. This is based on Mozilla’s SSL guidance, combined with the expectation of being able to use ECDSA keys in a later revision of this playbook.

  2. As part of the move to 2048 bit keys, the 4096 bit DH parameters are no longer distributed. It was originally distributed since generating it took ~75 minutes, but the new 2048 bit parameters take considerably less time.

Adding Cert Validations

OpenVPN has at least two kinds of certification validation available: (Extended) Key Usage checks, and certificate content validation.


Previously only the client was verifying that the server cert had the correct usage, now the verification is bi-directional.
OpenVPN, more about EKU checks: 1 & 2

Certificate content

Added the ability to verify the common name that is part of each certificate. This required changing the common names that each certificate is generated with, which means that the ability to wipe out the existing keys was added as well.

The server verifies client names by looking at the common name prefix using verify-x509-name ... name-prefix, while the client checks the exact name provided by the server.

Again, both these changes are gated by a variable (openvpn_verify_cn). Because this requires rather large client changes, it is off by default.

Wiping out & reinstalling

Added the ability to wipe out & reinstall OpenVPN. Currently it leaves firewall rules behind, but other than that everything is removed.

Use ansible-playbook -v openvpn.yml --extra-vars="openvpn_uninstall=true" --tags uninstall to just run the uninstall portion.

Connect over IPv6

Previously, you had to explicitly use udp6 or tcp6 to use IPv6. OpenVPN isn’t dual stacked if you use plain udp/tcp, which results in being unable to connect to the OpenVPN server if it has an AAAA record, on your device has a functional IPv6 connection, since the client will choose which stack to use if you just use plain udp/tcp.

Since this playbook is only on Linux, which supports IPv4 connections on IPv6 sockets, the server config is now IPv6 by default (, by means of using {{openvpn_proto}}6.

Hat tip to T-Mobile for revealing this problem with my setup.


  1. Add revoked cert check

  2. Generate ellptic curve keys instead of RSA keys However, as noted above, ECDHE ciphers don’t appear to be supported, so I’m not sure of OpenVPN will support EC keys.

  3. Add IPv6 within tunnel support (Possibly waiting for OpenVPN 2.4.0, since major changes are happening there)

This SO question seems to be my exact situation.

Both this SO question and another source are possibly related as well.

Tried splitting the assigned /64 subnet with:

ip -6 addr del 2607:5600:ae:ae::42/64 dev venet0
ip -6 addr add 2607:5600:ae:ae::42/65 dev venet0
  1. Investigate using openssl ca instead of openssl x509next version of easyrsa uses ca

, ,

  1. No comments yet.
(will not be published)