Este conteúdo não está disponível no idioma selecionado.
Chapter 30. Configuring IPsec VPN connections by using RHEL system roles
Configure IPsec VPN connections to establish encrypted tunnels over untrusted networks and ensure the integrity of data in transit. By using the RHEL system roles, you can automate the setup for use cases, such as connecting branch offices to headquarters.
The vpn
RHEL system role can only create VPN configurations that use pre-shared keys (PSKs) or certificates to authenticate peers to each other.
30.1. Configuring an IPsec host-to-host VPN with PSK authentication by using the vpn RHEL system role Copiar o linkLink copiado para a área de transferência!
A host-to-host VPN establishes an encrypted connection between two devices, allowing applications to communicate safely over an insecure network. By using the vpn
RHEL system role, you can automate the process of creating IPsec host-to-host connections.
For authentication, a pre-shared key (PSK) is a straightforward method that uses a single, shared secret known only to the two peers. This approach is simple to configure and ideal for basic setups where ease of deployment is a priority. However, you must keep the key strictly confidential. An attacker with access to the key can compromise the connection.
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:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example playbook include the following:
hosts: <list>
Defines a YAML dictionary with the peers 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
... - hosts: ... external-host.example.com: hostname: 192.0.2.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The role configures the VPN connection on each managed node. The connections are named
<peer_A>-to-<peer_B>
, for example,managed-node-01.example.com-to-managed-node-02.example.com
. Note that the role cannot configure Libreswan on external (unmanaged) nodes. You must manually create the configuration on these peers.auth_method: psk
-
Enables PSK authentication between the peers. The role uses
openssl
on the control node to create the PSK. auto: <startup_method>
-
Specifies the startup 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
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
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"'
# 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'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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.
30.2. Configuring an IPsec host-to-host VPN with PSK authentication and separate data and control planes by using the vpn RHEL system role Copiar o linkLink copiado para a área de transferência!
Use the vpn
RHEL system role to automate the process of creating an IPsec host-to-host VPN. To enhance security by minimizing the risk of control messages being intercepted or disrupted, configure separate connections for both the data traffic and the control traffic.
A host-to-host VPN establishes a direct, secure, and encrypted connection between two devices, allowing applications to communicate safely over an insecure network, such as the internet.
For authentication, a pre-shared key (PSK) is a straightforward method that uses a single, shared secret known only to the two peers. This approach is simple to configure and ideal for basic setups where ease of deployment is a priority. However, you must keep the key strictly confidential. An attacker with access to the key can compromise the connection.
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:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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 cannot 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: <startup_method>
-
Specifies the startup 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
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
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"'
# 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'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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.
30.3. Configuring an IPsec site-to-site VPN with PSK authentication by using the vpn RHEL system role Copiar o linkLink copiado para a área de transferência!
A site-to-site VPN establishes an encrypted tunnel between two distinct networks, seamlessly linking them across an insecure public network. By using the vpn
RHEL system role, you can automate the process of creating IPsec site-to-site VPN connections.
A site-to-site VPN enables devices in a branch office to access resources at a corporate headquarters just as if they were all part of the same local network.
For authentication, a pre-shared key (PSK) is a straightforward method that uses a single, shared secret known only to the two peers. This approach is simple to configure and ideal for basic setups where ease of deployment is a priority. However, you must keep the key strictly confidential. An attacker with access to the key can compromise the connection.
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:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example playbook include the following:
hosts: <list>
Defines a YAML dictionary with the gateways 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
... - hosts: ... external-host.example.com: hostname: 192.0.2.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The role configures the VPN connection on each managed node. The connections are named
<gateway_A>-to-<gateway_B>
, for example,managed-node-01.example.com-to-managed-node-02.example.com
. Note that the role cannot configure Libreswan on external (unmanaged) nodes. You must manually create the configuration on these peers.subnets: <yaml_list_of_subnets>
- Defines subnets in classless inter-domain routing (CIDR) format that are connected through the tunnel.
auth_method: psk
-
Enables PSK authentication between the peers. The role uses
openssl
on the control node to create the PSK. auto: <startup_method>
-
Specifies the startup 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
$ ansible-playbook --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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
$ ansible-playbook ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
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"'
# 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'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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.
30.4. Configuring an IPsec mesh VPN with certificate-based authentication by using the vpn RHEL system role Copiar o linkLink copiado para a área de transferência!
An IPsec mesh creates a fully interconnected network where every server can communicate securely and directly with every other server. By using the vpn
RHEL system role, you can automate configuring a VPN mesh with certificate-based authentication among managed nodes.
An IPsec mesh is ideal for distributed database clusters or high-availability environments that span multiple data centers or cloud providers. Establishing a direct, encrypted tunnel between each pair of servers ensures secure communication without a central bottleneck.
For authentication, using digital certificates managed by a Certificate Authority (CA) offers a highly secure and scalable solution. Each host in the mesh presents a certificate signed by a trusted CA. This method provides strong, verifiable authentication and simplifies user management. Access can be granted or revoked centrally at the CA, and Libreswan enforces this by checking each certificate against a certificate revocation list (CRL), denying access if a certificate appears on the list.
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 private key of the server
- The server certificate
- The CA certificate
- If required, intermediate certificates
-
The files are named
<managed_node_name_as_in_the_inventory>.p12
. - The files are stored in the same directory as the playbook.
The server certificate contains the following fields:
-
Extended Key Usage (EKU) is set to
TLS Web Server Authentication
. - Common Name (CN) or Subject Alternative Name (SAN) is set to the fully-qualified domain name (FQDN) of the host.
- X509v3 CRL distribution points contains URLs to Certificate Revocation Lists (CRLs).
-
Extended Key Usage (EKU) is set to
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
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
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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
$ ansible-vault create ~/vault.yml New Vault password: <vault_password> Confirm New Vault password: <vault_password>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow After the
ansible-vault create
command opens an editor, enter the sensitive data in the<key>: <value>
format:pkcs12_pwd: <password>
pkcs12_pwd: <password>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 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:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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 can be encrypted and which of them should continue using plain text connections. auth_method: cert
- Enables certificate-based authentication. This requires that you specify 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
$ ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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
$ ansible-playbook --ask-vault-pass ~/playbook.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
On a node in the mesh, ping another node to activate the connection:
ping managed-node-02.example.com
[root@managed-node-01]# ping managed-node-02.example.com
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Confirm that the connection is active:
ipsec trafficstatus
[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'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow