Github Actions (PRs & mainline):
This role installs OpenVPN, configures it as a server, sets up networking and firewalls (primarily firewalld, ufw and iptables are best effort), and can optionally create client certificates.
OSes in CI build:
- Fedora 38+
- CentOS 9
Note: I am providing code in the repository to you under an open source license. Because this is my personal repository, the license you receive to my code is from me and not my employer.
OpenVPN must be available as a package in yum/dnf/apt! For CentOS users, this role will run dnf install epel-release
to ensure openvpn is available.
With the release of Ansible 2.10, modules have been moved into collections. Two collections are now required:
ansible.posix
community.general
Install the collections with:
ansible-galaxy install -r /path/to/ansible-role-openvpn/requirements.yml
I personally use this role to manage OpenVPN on CentOS Stream 9. I try to keep the role on that platform fully functional with the default config. Please recognise that I am a single person, and I have a full time job and other commitments.
Responses to any issues will be on a best effort basis on my part, including the possibility that I don't respond at all. Issues arising from use of the non-defaults (including any of the major community contributions) will be deprioritized.
Major community contributions:
- Functionality to revoke certs
- All of the LDAP support
These options change how the role works. This is a catch-all group, specific groups are broken out below.
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
clients | list | [] | List of clients to add to OpenVPN | |
openvpn_base_dir | string | /etc/openvpn/server | Path where your OpenVPN config will be stored | |
openvpn_client_config_no_log | boolean | true, false | true | Prevent client configuration files to be logged to stdout by Ansible |
openvpn_key_dir | string | /etc/openvpn/keys | Path where your server private keys and CA will be stored | |
openvpn_ovpn_dir | string | /etc/openvpn | Path where your client configurations will be stored | |
openvpn_revoke_these_certs | list | [] | List of client certificates to revoke. | |
openvpn_selinux_module | string | my-openvpn-server | Set the SELinux module name | |
openvpn_service_name | string | openvpn-server@{{ openvpn_config_file }}.service | Name of the service. Used by systemctl to start the service | |
openvpn_sync_certs | boolean | true, false | false | Revoke certificates not explicitly defined in 'clients' |
openvpn_uninstall | boolean | true, false | false | Set to true to uninstall the OpenVPN service |
openvpn_use_ldap | boolean | true, false | false | Active LDAP backend for authentication. Client certificate not needed anymore |
openvpn_use_prebuilt_ldap_plugin | boolean | true, false | true | Use a distro-distributed version of the LDAP plugin |
Change these options if you need to adjust how the configs are download to your local system
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
openvpn_fetch_client_configs | boolean | true, false | true | Download generated client configurations to the local system |
openvpn_fetch_client_configs_dir | string | /tmp/ansible | If openvpn_fetch_client_configs is true, the local directory to download the client config files into | |
openvpn_fetch_client_configs_suffix | string | "" | If openvpn_fetch_client_configs is true, the suffix to append to the downloaded client config files before the trailing .ovpn extension |
Change these options if you need to force a particular firewall or change how the playbook interacts with the firewall.
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
openvpn_iptables_service | string | iptables | Override the iptables service name | |
openvpn_manage_firewall_rules | boolean | true, false | true | Allow playbook to manage iptables |
openvpn_firewall | string | auto, firewalld, ufw, iptables | auto | The firewall software to configure network rules. "auto" will attempt to detect it by inspecting the system |
openvpn_masquerade_not_snat | boolean | true, false | false | Set to true if you want to set up MASQUERADE instead of the default SNAT in iptables. |
These options change how OpenVPN itself works. Refer to the respective OpenVPN Reference Manual (OpenVPN 2.5, OpenVPN 2.6) for the interpretations.
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
openvpn_client_register_dns | boolean | true, false | true | Add register-dns option to client config (Windows only). |
openvpn_client_to_client | boolean | true, false | false | Set to true if you want clients to access each other. |
openvpn_set_dns | boolean | true, false | true | Push a list of DNS Servers to use to the client |
openvpn_custom_dns | list[string] | ["1.0.0.1", "1.1.1.1", "8.8.8.8", "8.8.4.4"] | List of DNS servers, only applied if openvpn_set_dns is set to true |
|
openvpn_dualstack | boolean | true | Whether or not to use a dualstack (IPv4 + v6) socket | |
openvpn_keepalive_ping | int | 5 | Set keepalive ping interval seconds. |
|
openvpn_keepalive_timeout | int | 30 | Set keepalive timeout seconds |
|
openvpn_local | string | unset |
Local host name or IP address for bind. If specified, OpenVPN will bind to this address only. If unspecified, OpenVPN will bind to all interfaces. | |
openvpn_port | int | 1194 | The port you want OpenVPN to run on. If you have different ports on different servers, I suggest you set the port in your inventory file. | |
openvpn_proto | string | udp, tcp | udp | The protocol you want OpenVPN to use |
openvpn_redirect_gateway | string | def1 bypass-dhcp ipv6 |
Flag values | |
openvpn_resolv_retry | int/string | any int, infinite | 5 | Hostname resolv failure retry seconds. Set "infinite" to retry indefinitely in case of poor connection or laptop sleep mode recovery etc. |
openvpn_server_hostname | string | {{ inventory_hostname }} |
The server name to place in the client configuration file | |
openvpn_server_ipv6_network | string | fdbf:dd0d:1a49:2091::/64 |
The network address and prefix of an IPv6 network to assign to clients. | |
openvpn_server_netmask | string | 255.255.255.0 | Netmask of the private network | |
openvpn_server_netmask_cidr | string | Determined at runtime from openvpn_server_network and openvpn_server_netmask |
CIDR suffix to use in firewall rules | |
openvpn_server_network | string | 10.9.0.0 | Private network used by OpenVPN service | |
openvpn_tun_mtu | int | unset |
Set tun-mtu value. Empty for default. |
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
openvpn_auth_alg | string | SHA256 | Set auth authentication algoritm. |
|
openvpn_ca_key | dict | unset |
Contain "crt" and "key". If not set, CA cert and key will be automatically generated on the target system. | |
openvpn_cipher | string | AES-256-GCM:AES-128-GCM:AES-256-CBC |
Set data-cipher option for server and client. |
|
openvpn_duplicate_cn | boolean | true, false | false | Add duplicate-cn option to server config - this allows clients to connect multiple times with the one key. NOTE: client ip addresses won't be static anymore! |
openvpn_rsa_bits | int | 2048 | Number of bits used to protect generated certificates | |
openvpn_script_security | int | 1 | Set openvpn script security option | |
openvpn_use_tls_crypt | boolean | true, false | true | Use TLS to encrypt OpenVPN control packets |
openvpn_tls_crypt_key | string | unset |
Path to a pre-generated OpenVPN key. | |
openvpn_tls_auth_required | boolean | true, false | false | Use TLS to sign OpenVPN control packets (deprecated in favour of openvpn_use_tls_crypt ) |
openvpn_tls_auth_key | string | unset |
Path to a pre-generated OpenVPN key. | |
openvpn_use_crl | boolean | true, false | false | Configure OpenVPN server to honor certificate revocation list. |
openvpn_manage_crl_without_systemd | boolean | true, false | false | Acknowledge that you're going to renew the CRL through a different method |
openvpn_tls_version_min | string | 1.2 or-highest |
Set the minimum required TLS version | |
openvpn_use_pregenerated_dh_params | boolean | true, false | false | DH params are generted with the install by default |
openvpn_verify_cn | boolean | true, false | false | Check that the CN of the certificate match the FQDN |
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
openvpn_addl_client_options | list | empty | List of user-defined client options that are not already present in the client template. (e.g. - mssfix 1400 ) |
|
openvpn_addl_server_options | list | empty | List of user-defined server options that are not already present in the server template. (e.g. - ping-timer-rem ) |
|
openvpn_compression | string | unset |
Set compress compression option. Empty for no compression. |
|
openvpn_config_file | string | openvpn_{{ openvpn_proto }}_{{ openvpn_port }} | The config file name you want to use (set in vars/main.yml) | |
openvpn_enable_management | boolean | true, false | false | |
openvpn_ifconfig_pool_persist_file | string | ipp.txt | ||
openvpn_management_bind | string | /var/run/openvpn/management unix | The interface to bind on for the management interface. Can be unix or TCP socket. | |
openvpn_management_client_user | string | root | Use this user when using a Unix socket for management interface. | |
openvpn_push | list | empty | Set here a list of string that will be inserted into the config file as push "" . E.g - route 10.20.30.0 255.255.255.0 will generate push "route 10.20.30.0 255.255.255.0" |
|
openvpn_script_client_connect | string | unset |
Path to your openvpn client-connect script | |
openvpn_script_client_disconnect | string | unset |
Path to your openvpn client-disconnect script | |
openvpn_script_down | string | unset |
Path to your openvpn down script | |
openvpn_script_up | string | unset |
Path to your openvpn up script | |
openvpn_service_group | string | nogroup | Set the openvpn service group. | |
openvpn_service_user | string | nobody | Set the openvpn service user. | |
openvpn_status_version | int | 1, 2, 3 | 1 | Define the formatting of the openvpn-status.log file where are listed current client connection |
openvpn_topology | string | subnet |
the "topology" keyword will be set in the server config with the specified value. |
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
openvpn_client_config | Boolean | false | Set to true if enable client configuration directory | |
openvpn_client_config_dir | string | ccd | Path of client-config-dir |
|
openvpn_client_configs | dict | {} | Dict of settings custom client configs |
Set your own custom logrotate options
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
openvpn_log_dir | string | /var/log | Set location of openvpn log files. This parameter is a part of log-append configuration value. |
|
openvpn_log_file | string | openvpn.log | Set log filename. This parameter is a part of log-append configuration value. If empty, syslog is used. |
|
openvpn_logrotate_config | string | rotate 4 weekly missingok notifempty sharedscripts copytruncate delaycompress |
Configure logrotate script. |
This role pulls in a bunch of different packages. Override the names as necessary.
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
epel_package_name | string | epel-release | Name of the epel-release package to install from the package manager | |
iptables_persistent_package_name | string | iptables-persistent | Name of the iptables-persistent package to install from the package manager | |
iptables_services_package_name | string | iptables-services | Name of the iptables-services package to install from the package manager | |
openssl_package_name | string | openssl | Name of the openssl package to install from the package manager | |
openvpn_ldap_plugin_package_name | string | openvpn-auth-ldap | Name of the openvpn-auth-ldap package to install from the package manager | |
openvpn_package_name | string | openvpn | Name of the openvpn package to install from the package manager | |
python_firewall_package_name | string | python-firewall | Name of the python-firewall package to install from the package manager |
Variable | Type | Choices | Default | Comment |
---|---|---|---|---|
openvpn_ldap | dict | Dictionary that contain LDAP configuration | ||
url | string | ldap://host.example.com | Address of you LDAP backend with syntax ldap[s]://host[:port] | |
anonymous_bind | string | False , True | False | This is not an Ansible boolean but a string that will be pushed into the configuration file. |
bind_dn | string | uid=Manager,ou=People,dc=example,dc=com | Bind DN used if "anonymous_bind" set to "False" | |
bind_password | string | mysecretpassword | Password of the bind_dn user | |
tls_enable | string | yes , no | no | Force TLS encryption. Not necessary with ldaps addresses |
tls_ca_cert_file | string | /etc/openvpn/auth/ca.pem | Path to the CA ldap backend. This must have been pushed before | |
tls_cert_file | string | Path to client authentication certificate | ||
tls_key_file | string | Path to client authentication key | ||
base_dn | string | ou=People,dc=example,dc=com | Base DN where the backend will look for valid user | |
search_filter | string | (&(uid=%u)(accountStatus=active)) | Filter the ldap search | |
require_group | string | False , True | This is not an Ansible boolean but a string that will be pushed into the configuration file. | |
group_base_dn | string | ou=Groups,dc=example,dc=com | Precise the group to look for. Required if require_group is set to "True" | |
group_search_filter | string | ((cn=developers)(cn=artists)) | Precise valid groups | |
verify_client_cert | string | none , optional , require | none | Defaults to none because of historical default of client-cert-not-required , which is deprecated. |
Does not depend on any other roles
- hosts: vpn
gather_facts: true
become: true
roles:
- role: kyl191.openvpn
openvpn_port: 4300
openvpn_sync_certs: true
clients:
- client1
- client2
MIT
Written by Kyle Lexmond