Este conteúdo não está disponível no idioma selecionado.
Chapter 31. Configuring VPN connections by using RHEL system roles
A VPN is an encrypted connection to securely transmit traffic over untrusted networks. By using the vpn
RHEL system role, you can automate the process of creating VPN configurations.
The vpn
RHEL system role supports only Libreswan, which is an IPsec implementation, as the VPN provider.
31.1. Creating a host-to-host IPsec VPN with PSK authentication by using the vpn
RHEL system role
You can use IPsec to directly connect hosts to each other through a VPN. The hosts can use a pre-shared key (PSK) to authenticate to each other. By using the vpn
RHEL system role, you can automate the process of creating IPsec host-to-host connections with PSK authentication.
By default, the role creates a tunnel-based VPN.
Prerequisites
- You have prepared the control node and the managed nodes.
- You are logged in to the control node as a user who can run playbooks on the managed nodes.
-
The account you use to connect to the managed nodes has
sudo
permissions on them.
Procedure
Create a playbook file, for example
~/playbook.yml
, with the following content:--- - name: Configuring VPN hosts: managed-node-01.example.com, managed-node-02.example.com tasks: - name: IPsec VPN with PSK authentication ansible.builtin.include_role: name: rhel-system-roles.vpn vars: vpn_connections: - hosts: managed-node-01.example.com: managed-node-02.example.com: auth_method: psk auto: start vpn_manage_firewall: true vpn_manage_selinux: true
The settings specified in the example playbook include the following:
hosts: <list>
Defines a YAML dictionary with the hosts between which you want to configure a VPN. If an entry is not an Ansible managed node, you must specify its fully-qualified domain name (FQDN) or IP address in the
hostname
parameter, for example:... - hosts: ... external-host.example.com: hostname: 192.0.2.1
The role configures the VPN connection on each managed node. The connections are named
<host_A>-to-<host_B>
, for example,managed-node-01.example.com-to-managed-node-02.example.com
. Note that the role can not configure Libreswan on external (unmanaged) nodes. You must manually create the configuration on these hosts.auth_method: psk
-
Enables PSK authentication between the hosts. The role uses
openssl
on the control node to create the PSK. auto: <start-up_method>
-
Specifies the start-up method of the connection. Valid values are
add
,ondemand
,start
, andignore
. For details, see theipsec.conf(5)
man page on a system with Libreswan installed. The default value of this variable is null, which means no automatic startup operation. vpn_manage_firewall: true
-
Defines that the role opens the required ports in the
firewalld
service on the managed nodes. vpn_manage_selinux: true
- Defines that the role sets the required SELinux port type on the IPsec ports.
For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
file on the control node.Validate the playbook syntax:
$ ansible-playbook --syntax-check ~/playbook.yml
Note that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
$ ansible-playbook ~/playbook.yml
Verification
Confirm that the connections are successfully started, for example:
# ansible managed-node-01.example.com -m shell -a 'ipsec trafficstatus | grep "managed-node-01.example.com-to-managed-node-02.example.com"' ... 006 #3: "managed-node-01.example.com-to-managed-node-02.example.com", type=ESP, add_time=1741857153, inBytes=38622, outBytes=324626, maxBytes=2^63B, id='@managed-node-02.example.com'
Note that this command only succeeds if the VPN connection is active. If you set the
auto
variable in the playbook to a value other thanstart
, you might need to manually activate the connection on the managed nodes first.
Additional resources
-
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
file -
/usr/share/doc/rhel-system-roles/vpn/
directory
31.2. Creating a host-to-host IPsec VPN with PSK authentication and separate data and control planes by using the vpn
RHEL system role
You can use IPsec to directly connect hosts to each other through a VPN. For example, to enhance the security by minimizing the risk of control messages being intercepted or disrupted, you can configure separate connections for both the data traffic and the control traffic. By using the vpn
RHEL system role, you can automate the process of creating IPsec host-to-host connections with a separate data and control plane and PSK authentication.
Prerequisites
- You have prepared the control node and the managed nodes.
- You are logged in to the control node as a user who can run playbooks on the managed nodes.
-
The account you use to connect to the managed nodes has
sudo
permissions on them.
Procedure
Create a playbook file, for example
~/playbook.yml
, with the following content:--- - name: Configuring VPN hosts: managed-node-01.example.com, managed-node-02.example.com tasks: - name: IPsec VPN with PSK authentication ansible.builtin.include_role: name: rhel-system-roles.vpn vars: vpn_connections: - name: control_plane_vpn hosts: managed-node-01.example.com: hostname: 203.0.113.1 # IP address for the control plane managed-node-02.example.com: hostname: 198.51.100.2 # IP address for the control plane auth_method: psk auto: start - name: data_plane_vpn hosts: managed-node-01.example.com: hostname: 10.0.0.1 # IP address for the data plane managed-node-02.example.com: hostname: 172.16.0.2 # IP address for the data plane auth_method: psk auto: start vpn_manage_firewall: true vpn_manage_selinux: true
The settings specified in the example playbook include the following:
hosts: <list>
Defines a YAML dictionary with the hosts between which you want to configure a VPN. The connections are named
<name>-<IP_address_A>-to-<IP_address_B>
, for examplecontrol_plane_vpn-203.0.113.1-to-198.51.100.2
.The role configures the VPN connection on each managed node. Note that the role can not configure Libreswan on external (unmanaged) nodes. You must manually create the configuration on these hosts.
auth_method: psk
-
Enables PSK authentication between the hosts. The role uses
openssl
on the control node to create the pre-shared key. auto: <start-up_method>
-
Specifies the start-up method of the connection. Valid values are
add
,ondemand
,start
, andignore
. For details, see theipsec.conf(5)
man page on a system with Libreswan installed. The default value of this variable is null, which means no automatic startup operation. vpn_manage_firewall: true
-
Defines that the role opens the required ports in the
firewalld
service on the managed nodes. vpn_manage_selinux: true
- Defines that the role sets the required SELinux port type on the IPsec ports.
For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
file on the control node.Validate the playbook syntax:
$ ansible-playbook --syntax-check ~/playbook.yml
Note that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
$ ansible-playbook ~/playbook.yml
Verification
Confirm that the connections are successfully started, for example:
# ansible managed-node-01.example.com -m shell -a 'ipsec trafficstatus | grep "control_plane_vpn-203.0.113.1-to-198.51.100.2"' ... 006 #3: "control_plane_vpn-203.0.113.1-to-198.51.100.2", type=ESP, add_time=1741860073, inBytes=0, outBytes=0, maxBytes=2^63B, id='198.51.100.2'
Note that this command only succeeds if the VPN connection is active. If you set the
auto
variable in the playbook to a value other thanstart
, you might need to manually activate the connection on the managed nodes first.
Additional resources
-
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
file -
/usr/share/doc/rhel-system-roles/vpn/
directory
31.3. Creating an IPsec mesh VPN among multiple hosts with certificate-based authentication by using the vpn
RHEL system role
Libreswan supports creating an opportunistic mesh to establish IPsec connections among a large number of hosts with a single configuration on each host. Adding hosts to the mesh does not require updating the configuration on existing hosts. For enhanced security, use certificate-based authentication in Libreswan.
By using the vpn
RHEL system role, you can automate configuring a VPN mesh with certificate-based authentication among managed nodes.
Prerequisites
- You have prepared the control node and the managed nodes.
- You are logged in to the control node as a user who can run playbooks on the managed nodes.
-
The account you use to connect to the managed nodes has
sudo
permissions on them. You prepared a PKCS #12 file for each managed node:
Each file contains:
- The certificate authority (CA) certificate
- The node’s private key
- The node’s client certificate
-
The files are named
<managed_node_name_as_in_the_inventory>.p12
. - The files are stored in the same directory as the playbook.
Procedure
Edit the
~/inventory
file, and append thecert_name
variable:managed-node-01.example.com cert_name=managed-node-01.example.com managed-node-02.example.com cert_name=managed-node-02.example.com managed-node-03.example.com cert_name=managed-node-03.example.com
Set the
cert_name
variable to the value of the common name (CN) field used in the certificate for each host. Typically, the CN field is set to the fully-qualified domain name (FQDN).Store your sensitive variables in an encrypted file:
Create the vault:
$ ansible-vault create vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
After the
ansible-vault create
command opens an editor, enter the sensitive data in the<key>: <value>
format:pkcs12_pwd: <password>
- Save the changes, and close the editor. Ansible encrypts the data in the vault.
Create a playbook file, for example
~/playbook.yml
, with the following content:- name: Configuring VPN hosts: managed-node-01.example.com, managed-node-02.example.com, managed-node-03.example.com vars_files: - vault.yml tasks: - name: Install LibreSwan ansible.builtin.package: name: libreswan state: present - name: Identify the path to IPsec NSS database ansible.builtin.set_fact: nss_db_dir: "{{ '/etc/ipsec.d/' if ansible_distribution in ['CentOS', 'RedHat'] and ansible_distribution_major_version is version('8', '=') else '/var/lib/ipsec/nss/' }}" - name: Locate IPsec NSS database files ansible.builtin.find: paths: "{{ nss_db_dir }}" patterns: "*.db" register: db_files - name: Remove IPsec NSS database files ansible.builtin.file: path: "{{ item.path }}" state: absent loop: "{{ db_files.files }}" when: db_files.matched > 0 - name: Initialize IPsec NSS database ansible.builtin.command: cmd: ipsec initnss - name: Copy PKCS #12 file to the managed node ansible.builtin.copy: src: "~/{{ inventory_hostname }}.p12" dest: "/etc/ipsec.d/{{ inventory_hostname }}.p12" mode: 0600 - name: Import PKCS #12 file in IPsec NSS database ansible.builtin.shell: cmd: 'pk12util -d {{ nss_db_dir }} -i /etc/ipsec.d/{{ inventory_hostname }}.p12 -W "{{ pkcs12_pwd }}"' - name: Remove PKCS #12 file ansible.builtin.file: path: "/etc/ipsec.d/{{ inventory_hostname }}.p12" state: absent - name: Opportunistic mesh IPsec VPN with certificate-based authentication ansible.builtin.include_role: name: rhel-system-roles.vpn vars: vpn_connections: - opportunistic: true auth_method: cert policies: - policy: private cidr: default - policy: private cidr: 192.0.2.0/24 - policy: clear cidr: 192.0.2.1/32 vpn_manage_firewall: true vpn_manage_selinux: true
The settings specified in the example playbook include the following:
opportunistic: true
-
Enables an opportunistic mesh among multiple hosts. The
policies
variable defines for which subnets and hosts traffic must or or can be encrypted and which of them should continue using clear text connections. auth_method: cert
- Enables certificate-based authentication. This requires that you specified the nickname of each managed node’s certificate in the inventory.
policies: <list_of_policies>
Defines the Libreswan policies in YAML list format.
The default policy is
private-or-clear
. To change it toprivate
, the above playbook contains an according policy for the defaultcidr
entry.To prevent a loss of the SSH connection during the execution of the playbook if the Ansible control node is in the same IP subnet as the managed nodes, add a
clear
policy for the control node’s IP address. For example, if the mesh should be configured for the192.0.2.0/24
subnet and the control node uses the IP address192.0.2.1
, you require aclear
policy for192.0.2.1/32
as shown in the playbook.For details about policies, see the
ipsec.conf(5)
man page on a system with Libreswan installed.vpn_manage_firewall: true
-
Defines that the role opens the required ports in the
firewalld
service on the managed nodes. vpn_manage_selinux: true
- Defines that the role sets the required SELinux port type on the IPsec ports.
For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
file on the control node.Validate the playbook syntax:
$ ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
Note that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
$ ansible-playbook --ask-vault-pass ~/playbook.yml
Verification
On a node in the mesh, ping another node to activate the connection:
[root@managed-node-01]# ping managed-node-02.example.com
Confirm that the connections is active:
[root@managed-node-01]# ipsec trafficstatus 006 #2: "private#192.0.2.0/24"[1] ...192.0.2.2, type=ESP, add_time=1741938929, inBytes=372408, outBytes=545728, maxBytes=2^63B, id='CN=managed-node-02.example.com'
Additional resources
-
/usr/share/ansible/roles/rhel-system-roles.vpn/README.md
file -
/usr/share/doc/rhel-system-roles/vpn/
directory