- Fix a bug in UFW rule creation that broke UFW (#232)
- Only run cert revocation steps when
openvpn_use_crlis truthy (#228) - Test cleanups
In part because of Requiring OpenVPN 2.5, some variable and variable defaults were changed.
-
openvpn_use_hardened_tlshardcoded the Minimum TLS version to1.2. It is replaced byopenvpn_tls_version_minwhich is now a string, and defaults to1.2 or-highest.- Restore the old behaviour with
openvpn_tls_version_min: "1.2"
- Restore the old behaviour with
-
openvpn_use_modern_tlshardcoded the (then) Mozilla Modern Cipher List. There is no equivalent replacement, it is dropped in favour of using the OpenVPN defaults, which are the crypto library's defaults.- Restore the old behaviour with
openvpn_addl_server_options: ["tls-cipher TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384:TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"]
-
openvpn_ciphernow sets thedata-cipheroption instead ofcipher. The new default isAES-256-GCM:AES-128-GCM:AES-256-CBC.- Restore the old behaviour with
openvpn_cipher: null openvpn_addl_server_options: ["cipher AES-256-CBC"]
-
openvpn_tls_auth_requiredhas been replaced withopenvpn_use_tls_crypt. The default foropenvpn_tls_auth_requiredis nowfalse.- Restore the old behaviour with
openvpn_tls_auth_required: true
- Restore the old behaviour with
-
Functionality needing the
openvpn_firewalld_default_interface_zonehas been replaced by using the zone from the interface with the default route. Theopenvpn_firewalld_default_interface_zonevariable has been removed.- It is not possible to restore the old behaviour
-
openvpn_server_ipv6_networkdefaults to"fdbf:dd0d:1a49:2091::/64", enabling IPv6- Restore the old behaviour with
openvpn_server_ipv6_network: null
- Restore the old behaviour with
-
openvpn_redirect_gatewayis now the stringdef1 bypass-dhcp ipv6instead of a boolean- Restore the old behaviour with
openvpn_redirect_gateway: "def1 bypass-dhcp"
- Restore the old behaviour with
-
Setting both
openvpn_crl_pathandopenvpn_use_crlresulted in duplicatecrl-verifydirectives. This has been resolved in favour of removingopenvpn_crl_pathfor consistency since the other certificate paths can't be set.- It is not possible to restore the old behaviour
-
openvpn_ldap.verify_client_certnow defaults tonone, was previously unset so the defaultclient-cert-not-requiredwould be set instead.client-cert-not-requiredis deprecated,verify_client_cert noneis functionally identical- There is no functional change in behaviour
-
openvpn_topologydefaults tosubnetper the OpenVPN recommendation to opt-in early:OpenVPN recommends using topology subnet now, so that when the default is changed, you will not be affected.
- Restore the old behaviour with
openvpn_topology: net30
- Restore the old behaviour with
Variables are prefixed with openvpn_ to make sure they are isolated to this role. (There are limited exceptions) You will need to update any variable you have overriden.
Configurable variable renames include:
clientsbecomingopenvpn_clientsldapdict becomingopenvpn_ldaptls_auth_requiredbecomingopenvpn_tls_auth_requiredmanage_firewall_rulesbecomingopenvpn_manage_firewall_rulesiptables_servicebecomingopenvpn_iptables_service
There are some internal variables that have been renamed to have a __ prefix to indicate they are internal.
openvpn_cipherwill be unset and fallback to using the OpenVPN defaultsopenvpn_tls_auth_requiredwill be removed completely
IPv6 wasn't routed through the VPN, so traffic to IPv6 addresses would leak. Instead of disabling IPv6, I've added NAT IPv6 support using private IPv6 addresses.
If desired, you can generate your own IPv6 network address with
- https://simpledns.plus/private-ipv6 (look for "Combined/CID")
- https://unique-local-ipv6.com/ (look for "First subnet")
I do not recommend generating addresses dynamically without using some fixed seed.
Because of the potential for leaking IPv6 traffic, continue routing IPv6 traffic over the VPN but enable the OpenVPN block-ipv6 directive with
openvpn_addl_client_options: ["block-ipv6"]
openvpn_addl_server_options: ["block-ipv6"]If you want to use routed IPv6, set openvpn_server_ipv6_network to the IPv6 netblock you want to assign to the VPN. You will need to perform any other external changes yourself (eg splitting an assigned /64 into two /65s).
ansible-lint isn't complaining anymore. I've added it to the CI system so the role shouldn't regress.
I've also started using is truthy/falsy instead of inconsistently using |bool for boolean comparisons. If you overriding variables on the CLI when invoking the playbook, the behaviour may change.
Versions early than 2.5 are uniformly out of support and OpenVPN enourages people to "upgrade to a newer release ASAP".
OpenVPN deprecated cipher and replaced it with data-cipher. All the supported OSes are OpenVPN2.5+, so I've updated the server config to use data-cipher when openvpn_cipher is set.
If the event you need fallback support on the server for older clients, set the value data-ciphers-fallback through the playbook option openvpn_addl_server_options.
If you're forced to use OpenVPN 2.4 or earlier, this should work:
- Unset
openvpn_cipherin your vars file, egopenvpn_cipher: ~ - Include
cipherinopenvpn_addl_server_options, egopenvpn_addl_server_options: ["cipher AES-256-CBC"]
Similarly on the client, you can use openvpn_addl_client_options to set cipher if needed.
Discussion in this issue.
The TLS settings are cleaned up because they were confusing me:
openvpn_use_hardened_tlshardcoded the Minimum TLS version to1.2. It is replaced byopenvpn_tls_version_minwhich is now a string, and defaults to1.2 or-highest.openvpn_use_modern_tlshardcoded the (then) Mozilla Modern Cipher List. It is dropped in favour of using the OpenVPN defaults, which are the crypto library's defaults.- TLS Auth for the control channel (
openvpn_tls_auth_required) is deprecated in favour of TLS Crypt for the control channel (openvpn_use_tls_crypt)
Finally, I've also moved the Certificate Revocation List management behind a openvpn_use_crl check. Previously it was unconditionally setup (including adding a cronjob) even though it wasn't enabled in the OpenVPN config.
Actually supported - I make sure an OpenVPN connection works before putting up a Ansible Galaxy release:
- Fedora 38+ (OpenVPN 2.6)
- CentOS Stream 9/AlmaLinux/Rocky/RHEL 9+ (OpenVPN 2.5)
Kind of supported - CI does sanity checks, I do manual checks if I've got time:
- Ubuntu 22.04+ (OpenVPN 2.5, list of distro releases)
- Debian 12 (OpenVPN 2.6, list of distro releases)
Community contributions - no automated checks, they might work:
- FreeBSD
- Solaris
Older OSes might work - I avoid explicitly blocking OS versions, but workarounds will be removed with EOLed OSes to simplify the role.
- CentOS 6 - no longer ignore errors when setting sysctls
- CentOS 7 - Potentially affected by defaulting service name to the systemd style
- Fedora <33 - no longer installing
python2-dnfandpython2-firewalldfor Ansible to run on Python 2.
Known issue: RHEL-alike 8 can't manage packages using ansible-core >=2.17.0, you will need to use an earlier version of Ansible.
Other notes on RHEL-alike 8 variants:
- AlmaLinux 8 and Rocky Linux 8 need an out-of-band python upgrade with
dnf install python3.9and setting theansible_python_interpretervalue to/usr/bin/python3.9 - CentOS 8 and CentOS Stream 8 packages were vaulted (CentOS 8 announcement, Stream 8 announcement), which breaks Yum downloading packages
- The OpenVPN version in EPEL 8 is 2.4.12, which doesn't work with the new
openvpn genkeysyntax. Generating tls-auth or tls-crypt OpenVPN keys will fail, addopenvpn_use_tls_crypt: false.
This thing has honestly made me nervous since merging it because it's rather complicated. A compliation issue was reported, and Fedora/EPEL, Debian, and Ubuntu all provide packages for openvpn-auth-ldap so I'm dropping the compilation step to simplify the role.
- Fedora/EPEL: https://packages.fedoraproject.org/pkgs/openvpn-auth-ldap/openvpn-auth-ldap/index.html
- Debian: https://packages.debian.org/search?keywords=openvpn-auth-ldap
- Ubuntu: https://launchpad.net/ubuntu/+source/openvpn-auth-ldap
If you need it and there's no prebuilt package, manually build & configure it yourself and set the variable openvpn_use_prebuilt_ldap_plugin to False to skip the failing package install.
CentOS 8+, Ubuntu 22.04 and Debian 12 are all using systemd service units, so I've updated the default openvpn_service_name to be systemd style. I've kept the existing openvpn value for Solaris and FreeBSD, hopefully it works there.
The CRL crontab is also replaced by a systemd timer.
Fedora/CentOS use firewalld and Debian recommends firewalld. Ubuntu is alone in using ufw
nftables is the replacement for iptables, firewalld uses nftables as the default backend. Unfortunately there is no nftables support in Ansible yet, so I'm choosing to drop iptables and suggest firewalld as the replacement.
This will realistically be done when iptables starts requiring more maintenance than it does right now.
The Fedora & CentOS connection testing is currently manual. (This is also blocking the better testing of the Debian & Ubuntu distros).
The CI currently tests the role on AlmaLinux/Rocky Linux 8 using the highest supported Ansible version for CentOS 8 as a control node - ansible-8.7.0/ansible-core-2.15.13, but this is limited to running the playbook without attempting an OpenVPN connection.
This is partly because the minimum ansible-core version for this role is 2.11 - if this run starts failing, I'll know the minimum ansible-core version will need to be bumped.
At some point in the future I'll switch to testing different ansible-core versions explicitly, and drop the RHEL-alike 8 CI builds at that time.
-
Added
auth SHA256so MACs on the individual packets are done with SHA256 instead of SHA1. -
Added
tls-version-min 1.2to drop SSL3 + TLS v1.0 support. This breaks older clients (2.3.2+), but those versions have been out for a while. -
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. -
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.
-
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.
Points 2 & 3 are gated by the openvpn_use_modern_tls variable, which defaults to true.
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.
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.
Again, both these changes are gated by a variable (openvpn_verify_cn). Because this requires rather large client changes, it is off by default.
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.
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 (https://github.com/OpenVPN/openvpn/blob/master/README.IPv6#L50), by means of using {{ openvpn_proto }}6 in the server template. Specifying a *6 protocol for openvpn_proto is now an error, and will cause OpenVPN to fail to start.