Chapter 6. Setting up an IPsec VPN


A virtual private network (VPN) is a way of connecting to a local network over the internet. IPsec provided by Libreswan is the preferred method for creating a VPN. Libreswan is a user-space IPsec implementation for VPN. A VPN enables the communication between your LAN, and another, remote LAN by setting up a tunnel across an intermediate network such as the internet. For security reasons, a VPN tunnel always uses authentication and encryption. For cryptographic operations, Libreswan uses the NSS library.

6.1. Libreswan as an IPsec VPN implementation

In RHEL, you can configure a Virtual Private Network (VPN) by using the IPsec protocol, which is supported by the Libreswan application. Libreswan is a continuation of the Openswan application, and many examples from the Openswan documentation are interchangeable with Libreswan.

The IPsec protocol for a VPN is configured using the Internet Key Exchange (IKE) protocol. The terms IPsec and IKE are used interchangeably. An IPsec VPN is also called an IKE VPN, IKEv2 VPN, XAUTH VPN, Cisco VPN or IKE/IPsec VPN.

Libreswan is an open-source, user-space IKE implementation. IKE v1 and v2 are implemented as a user-level daemon. The IKE protocol is also encrypted. The IPsec protocol is implemented by the Linux kernel, and Libreswan configures the kernel to add and remove VPN tunnel configurations.

The IKE protocol uses UDP port 500 and 4500. The IPsec protocol consists of two protocols:

  • Encapsulated Security Payload (ESP), which has protocol number 50.
  • Authenticated Header (AH), which has protocol number 51.

The AH protocol is not recommended for use. Users of AH are recommended to migrate to ESP with null encryption.

The IPsec protocol provides two modes of operation:

  • Tunnel Mode (the default)
  • Transport Mode

You can configure the kernel with IPsec without IKE. This is called manual keying. You can also configure manual keying using the ip xfrm commands, however, this is strongly discouraged for security reasons. Libreswan communicates with the Linux kernel using the Netlink interface. The kernel performs packet encryption and decryption.

Libreswan uses the Network Security Services (NSS) cryptographic library.

Important

IKE/IPsec VPNs, implemented by Libreswan and the Linux kernel, is the only VPN technology recommended for use in RHEL. Do not use any other VPN technology without understanding the risks of doing so.

In RHEL, Libreswan follows system-wide cryptographic policies by default. This ensures that Libreswan uses secure settings for current threat models including IKEv2 as a default protocol. See Using system-wide crypto policies for more information.

Libreswan does not use the terms "source" and "destination" or "server" and "client" because IKE/IPsec are peer to peer protocols. Instead, it uses the terms "left" and "right" to refer to end points (the hosts). This also allows you to use the same configuration on both end points in most cases. However, administrators usually choose to always use "left" for the local host and "right" for the remote host.

The leftid and rightid options serve as identification of the respective hosts in the authentication process. See the ipsec.conf(5) man page for more information.

6.2. Authentication methods in Libreswan

Libreswan supports several authentication methods, each of which fits a different scenario.

Pre-Shared key (PSK)
Pre-Shared Key (PSK) is the simplest authentication method. For security reasons, do not use PSKs shorter than 64 random characters. In FIPS mode, PSKs must comply with a minimum-strength requirement depending on the integrity algorithm used. You can set PSK by using the authby=secret connection.
Raw RSA keys

Raw RSA keys are commonly used for static host-to-host or subnet-to-subnet IPsec configurations. Each host is manually configured with the public RSA keys of all other hosts, and Libreswan sets up an IPsec tunnel between each pair of hosts. This method does not scale well for large numbers of hosts.

You can generate a raw RSA key on a host using the ipsec newhostkey command. You can list generated keys by using the ipsec showhostkey command. The leftrsasigkey= line is required for connection configurations that use CKA ID keys. Use the authby=rsasig connection option for raw RSA keys.

X.509 certificates

X.509 certificates are commonly used for large-scale deployments with hosts that connect to a common IPsec gateway. A central certificate authority (CA) signs RSA certificates for hosts or users. This central CA is responsible for relaying trust, including the revocations of individual hosts or users.

For example, you can generate X.509 certificates using the openssl command and the NSS certutil command. Because Libreswan reads user certificates from the NSS database using the certificates' nickname in the leftcert= configuration option, provide a nickname when you create a certificate.

If you use a custom CA certificate, you must import it to the Network Security Services (NSS) database. You can import any certificate in the PKCS #12 format to the Libreswan NSS database by using the ipsec import command.

Warning

Libreswan requires an Internet Key Exchange (IKE) peer ID as a subject alternative name (SAN) for every peer certificate as described in section 3.1 of RFC 4945. Disabling this check by setting the require-id-on-certificate=no connection option can make the system vulnerable to man-in-the-middle attacks.

Use the authby=rsasig connection option for authentication based on X.509 certificates using RSA with SHA-2. You can further limit it for ECDSA digital signatures using SHA-2 by setting authby= to ecdsa and RSA Probabilistic Signature Scheme (RSASSA-PSS) digital signatures based authentication with SHA-2 through authby=rsa-sha2. The default value for IKEv2 peer authentication is authby=rsasig,ecdsa.

The certificates and the authby= signature methods should match. This increases interoperability and preserves authentication in one digital signature system.

NULL authentication
NULL authentication is used to gain mesh encryption without authentication. It protects against passive attacks but not against active attacks. However, because IKEv2 allows asymmetric authentication methods, NULL authentication can also be used for internet-scale opportunistic IPsec. In this model, clients authenticate the server, but servers do not authenticate the client. This model is similar to secure websites using TLS. Use authby=null for NULL authentication.
Protection against quantum computers

In addition to the previously mentioned authentication methods, you can use the Post-quantum Pre-shared Key (PPK) method to protect against possible attacks by quantum computers. Individual clients or groups of clients can use their own PPK by specifying a PPK ID that corresponds to an out-of-band configured pre-shared key.

Using IKEv1 with pre-shared keys protects against quantum attackers. The redesign of IKEv2 does not offer this protection natively. Libreswan offers the use of a Post-quantum Pre-shared Key (PPK) to protect IKEv2 connections against quantum attacks.

To enable optional PPK support, add ppk=yes to the connection definition. To require PPK, add ppk=insist. Then, each client can be given a PPK ID with a secret value that is communicated out-of-band (and preferably quantum-safe). The PPK’s should be very strong in randomness and not based on dictionary words. The PPK ID and PPK data are stored in the ipsec.secrets file, for example:

@west @east : PPKS "user1" "thestringismeanttobearandomstr"
Copy to Clipboard

The PPKS option refers to static PPKs. This experimental function uses one-time-pad-based Dynamic PPKs. Upon each connection, a new part of the one-time pad is used as the PPK. When used, that part of the dynamic PPK inside the file is overwritten with zeros to prevent re-use. If there is no more one-time-pad material left, the connection fails. See the ipsec.secrets(5) man page for more information.

6.3. Installing Libreswan

Before you can set a VPN through the Libreswan IPsec/IKE implementation, you must install the corresponding packages, start the ipsec service, and allow the service in your firewall.

Prerequisites

  • The AppStream repository is enabled.

Procedure

  1. Install the libreswan packages:

    # dnf install libreswan
    Copy to Clipboard
  2. If you are re-installing Libreswan, remove its old database files and create a new database:

    # systemctl stop ipsec
    # rm /var/lib/ipsec/nss/*db
    # ipsec initnss
    Copy to Clipboard
  3. Start the ipsec service, and enable the service to be started automatically on boot:

    # systemctl enable ipsec --now
    Copy to Clipboard
  4. Configure the firewall to allow 500 and 4500/UDP ports for the IKE, ESP, and AH protocols by adding the ipsec service:

    # firewall-cmd --add-service="ipsec"
    # firewall-cmd --runtime-to-permanent
    Copy to Clipboard

6.4. Creating a host-to-host VPN

You can configure Libreswan to create a host-to-host IPsec VPN between two hosts referred to as left and right using authentication by raw RSA keys.

Prerequisites

  • Libreswan is installed and the ipsec service is started on each node.

Procedure

  1. Generate a raw RSA key pair on each host:

    # ipsec newhostkey
    Copy to Clipboard
  2. The previous step returned the generated key’s ckaid. Use that ckaid with the following command on left, for example:

    # ipsec showhostkey --left --ckaid 2d3ea57b61c9419dfd6cf43a1eb6cb306c0e857d
    Copy to Clipboard

    The output of the previous command generated the leftrsasigkey= line required for the configuration. Do the same on the second host (right):

    # ipsec showhostkey --right --ckaid a9e1f6ce9ecd3608c24e8f701318383f41798f03
    Copy to Clipboard
  3. In the /etc/ipsec.d/ directory, create a new my_host-to-host.conf file. Write the RSA host keys from the output of the ipsec showhostkey commands in the previous step to the new file. For example:

    conn mytunnel
        leftid=@west
        left=192.1.2.23
        leftrsasigkey=0sAQOrlo+hOafUZDlCQmXFrje/oZm [...] W2n417C/4urYHQkCvuIQ==
        rightid=@east
        right=192.1.2.45
        rightrsasigkey=0sAQO3fwC6nSSGgt64DWiYZzuHbc4 [...] D/v8t5YTQ==
        authby=rsasig
    Copy to Clipboard
  4. After importing keys, restart the ipsec service:

    # systemctl restart ipsec
    Copy to Clipboard
  5. Load the connection:

    # ipsec add mytunnel
    Copy to Clipboard
  6. Establish the tunnel:

    # ipsec up mytunnel
    Copy to Clipboard
  7. To automatically start the tunnel when the ipsec service is started, add the following line to the connection definition:

    auto=start
    Copy to Clipboard
  8. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

6.5. Configuring a site-to-site VPN

To create a site-to-site IPsec VPN, by joining two networks, an IPsec tunnel between the two hosts is created. The hosts thus act as the end points, which are configured to permit traffic from one or more subnets to pass through. Therefore you can think of the host as gateways to the remote portion of the network.

The configuration of the site-to-site VPN only differs from the host-to-host VPN in that one or more networks or subnets must be specified in the configuration file.

Prerequisites

Procedure

  1. Copy the file with the configuration of your host-to-host VPN to a new file, for example:

    # cp /etc/ipsec.d/my_host-to-host.conf /etc/ipsec.d/my_site-to-site.conf
    Copy to Clipboard
  2. Add the subnet configuration to the file created in the previous step, for example:

    conn mysubnet
         also=mytunnel
         leftsubnet=192.0.1.0/24
         rightsubnet=192.0.2.0/24
         auto=start
    
    conn mysubnet6
         also=mytunnel
         leftsubnet=2001:db8:0:1::/64
         rightsubnet=2001:db8:0:2::/64
         auto=start
    
    # the following part of the configuration file is the same for both host-to-host and site-to-site connections:
    
    conn mytunnel
        leftid=@west
        left=192.1.2.23
        leftrsasigkey=0sAQOrlo+hOafUZDlCQmXFrje/oZm [...] W2n417C/4urYHQkCvuIQ==
        rightid=@east
        right=192.1.2.45
        rightrsasigkey=0sAQO3fwC6nSSGgt64DWiYZzuHbc4 [...] D/v8t5YTQ==
        authby=rsasig
    Copy to Clipboard
  3. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

6.6. Configuring a remote access VPN

Road warriors are traveling users with mobile clients and a dynamically assigned IP address. The mobile clients authenticate using X.509 certificates.

The following example shows configuration for IKEv2, and it avoids using the IKEv1 XAUTH protocol.

On the server:

conn roadwarriors
    keyexchange=ikev2
    # support (roaming) MOBIKE clients (RFC 4555)
    mobike=yes
    fragmentation=yes
    left=1.2.3.4
    # if access to the LAN is given, enable this, otherwise use 0.0.0.0/0
    # leftsubnet=10.10.0.0/16
    leftsubnet=0.0.0.0/0
    leftcert=gw.example.com
    leftid=%fromcert
    leftxauthserver=yes
    leftmodecfgserver=yes
    right=%any
    # trust our own Certificate Agency
    rightca=%same
    # pick an IP address pool to assign to remote users
    # 100.64.0.0/16 prevents RFC1918 clashes when remote users are behind NAT
    rightaddresspool=100.64.13.100-100.64.13.254
    # if you want remote clients to use some local DNS zones and servers
    modecfgdns="1.2.3.4, 5.6.7.8"
    modecfgdomains="internal.company.com, corp"
    rightxauthclient=yes
    rightmodecfgclient=yes
    authby=rsasig
    # optionally, run the client X.509 ID through pam to allow or deny client
    # pam-authorize=yes
    # load connection, do not initiate
    auto=add
    # kill vanished roadwarriors
Copy to Clipboard

On the mobile client, the road warrior’s device, use a slight variation of the previous configuration:

conn to-vpn-server
    keyexchange=ikev2
    # pick up our dynamic IP
    left=%defaultroute
    leftsubnet=0.0.0.0/0
    leftcert=myname.example.com
    leftid=%fromcert
    leftmodecfgclient=yes
    # right can also be a DNS hostname
    right=1.2.3.4
    # if access to the remote LAN is required, enable this, otherwise use 0.0.0.0/0
    # rightsubnet=10.10.0.0/16
    rightsubnet=0.0.0.0/0
    fragmentation=yes
    # trust our own Certificate Agency
    rightca=%same
    authby=rsasig
    # allow narrowing to the server's suggested assigned IP and remote subnet
    narrowing=yes
    # support (roaming) MOBIKE clients (RFC 4555)
    mobike=yes
    # initiate connection
    auto=start
Copy to Clipboard

6.7. Configuring a mesh VPN

A mesh VPN network, which is also known as an any-to-any VPN, is a network where all nodes communicate using IPsec. The configuration allows for exceptions for nodes that cannot use IPsec. The mesh VPN network can be configured in two ways:

  • To require IPsec.
  • To prefer IPsec but allow a fallback to clear-text communication.

Authentication between the nodes can be based on X.509 certificates or on DNS Security Extensions (DNSSEC).

You can use any regular IKEv2 authentication method for opportunistic IPsec, because these connections are regular Libreswan configurations, except for the opportunistic IPsec that is defined by right=%opportunisticgroup entry. A common authentication method is for hosts to authenticate each other based on X.509 certificates by using a commonly shared certification authority (CA). Cloud deployments typically issue certificates for each node in the cloud as part of the standard procedure.

Important

Do not use PreSharedKey (PSK) authentication because one compromised host would result in the group PSK secret being compromised as well.

You can use NULL authentication to deploy encryption between nodes without authentication, which protects only against passive attackers.

The following procedure uses X.509 certificates. You can generate these certificates by using any kind of CA management system, such as the Dogtag Certificate System. Dogtag assumes that the certificates for each node are available in the PKCS #12 format (.p12 files), which contain the private key, the node certificate, and the Root CA certificate used to validate other nodes' X.509 certificates.

Each node has an identical configuration with the exception of its X.509 certificate. This allows for adding new nodes without reconfiguring any of the existing nodes in the network. The PKCS #12 files require a "friendly name", for which we use the name "node" so that the configuration files referencing the friendly name can be identical for all nodes.

Prerequisites

  • Libreswan is installed, and the ipsec service is started on each node.
  • A new NSS database is initialized.

    1. If you already have an old NSS database, remove the old database files:

      # systemctl stop ipsec
      # rm /var/lib/ipsec/nss/*db
      Copy to Clipboard
    2. You can initialize a new database with the following command:

      # ipsec initnss
      Copy to Clipboard

Procedure

  1. On each node, import PKCS #12 files. This step requires the password used to generate the PKCS #12 files:

    # ipsec import nodeXXX.p12
    Copy to Clipboard
  2. Create the following three connection definitions for the IPsec required (private), IPsec optional (private-or-clear), and No IPsec (clear) profiles:

    # cat /etc/ipsec.d/mesh.conf
    conn clear
    	auto=ondemand 
    1
    
    	type=passthrough
    	authby=never
    	left=%defaultroute
    	right=%group
    
    conn private
    	auto=ondemand
    	type=transport
    	authby=rsasig
    	failureshunt=drop
    	negotiationshunt=drop
    	keyexchange=ikev2
    	left=%defaultroute
    	leftcert=nodeXXXX
    	leftid=%fromcert 
    2
    
    	rightid=%fromcert
    	right=%opportunisticgroup
    
    conn private-or-clear
    	auto=ondemand
    	type=transport
    	authby=rsasig
    	failureshunt=passthrough
    	negotiationshunt=passthrough
    	# left
    	left=%defaultroute
    	leftcert=nodeXXXX 
    3
    
    	leftid=%fromcert
    	leftrsasigkey=%cert
    	# right
    	rightrsasigkey=%cert
    	rightid=%fromcert
    	right=%opportunisticgroup
    Copy to Clipboard
    1
    The auto variable has several options:

    You can use the ondemand connection option with opportunistic IPsec to initiate the IPsec connection, or for explicitly configured connections that do not need to be active all the time. This option sets up a trap XFRM policy in the kernel, enabling the IPsec connection to begin when it receives the first packet that matches that policy.

    You can effectively configure and manage your IPsec connections, whether you use Opportunistic IPsec or explicitly configured connections, by using the following options:

    The add option
    Loads the connection configuration and prepares it for responding to remote initiations. However, the connection is not automatically initiated from the local side. You can manually start the IPsec connection by using the command ipsec up.
    The start option
    Loads the connection configuration and prepares it for responding to remote initiations. Additionally, it immediately initiates a connection to the remote peer. You can use this option for permanent and always active connections.
    2
    The leftid and rightid variables identify the right and the left channel of the IPsec tunnel connection. You can use these variables to obtain the value of the local IP address or the subject DN of the local certificate, if you have configured one.
    3
    The leftcert variable defines the nickname of the NSS database that you want to use.
  3. Add the IP address of the network to the corresponding category. For example, if all nodes reside in the 10.15.0.0/16 network, and all nodes must use IPsec encryption:

    # echo "10.15.0.0/16" >> /etc/ipsec.d/policies/private
    Copy to Clipboard
  4. To allow certain nodes, for example, 10.15.34.0/24, to work with and without IPsec, add those nodes to the private-or-clear group:

    # echo "10.15.34.0/24" >> /etc/ipsec.d/policies/private-or-clear
    Copy to Clipboard
  5. To define a host, for example, 10.15.1.2, which is not capable of IPsec into the clear group, use:

    # echo "10.15.1.2/32" >> /etc/ipsec.d/policies/clear
    Copy to Clipboard

    You can create the files in the /etc/ipsec.d/policies directory from a template for each new node, or you can provision them by using Puppet or Ansible.

    Note that every node has the same list of exceptions or different traffic flow expectations. Two nodes, therefore, might not be able to communicate because one requires IPsec and the other cannot use IPsec.

  6. Restart the node to add it to the configured mesh:

    # systemctl restart ipsec
    Copy to Clipboard
  7. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

Verification

  1. Open an IPsec tunnel by using the ping command:

    # ping <nodeYYY>
    Copy to Clipboard
  2. Display the NSS database with the imported certification:

    # certutil -L -d sql:/var/lib/ipsec/nss/
    
    Certificate Nickname    Trust Attributes
                            SSL,S/MIME,JAR/XPI
    
    west                    u,u,u
    ca                      CT,,
    Copy to Clipboard
  3. See which tunnels are open on the node:

    # ipsec trafficstatus
    006 #2: "private#10.15.0.0/16"[1] ...<nodeYYY>, type=ESP, add_time=1691399301, inBytes=512, outBytes=512, maxBytes=2^63B, id='C=US, ST=NC, O=Example Organization, CN=east'
    Copy to Clipboard

6.8. Deploying a FIPS-compliant IPsec VPN

You can deploy a FIPS-compliant IPsec VPN solution with Libreswan. To do so, you can identify which cryptographic algorithms are available and which are disabled for Libreswan in FIPS mode.

Prerequisites

  • The AppStream repository is enabled.
  • Your system has been installed in FIPS mode

Procedure

  1. Install the libreswan packages:

    # dnf install libreswan
    Copy to Clipboard
  2. If you are re-installing Libreswan, remove its old NSS database:

    # systemctl stop ipsec
    # rm /var/lib/ipsec/nss/*db
    Copy to Clipboard
  3. Start the ipsec service, and enable the service to be started automatically on boot:

    # systemctl enable ipsec --now
    Copy to Clipboard
  4. Configure the firewall to allow 500 and 4500 UDP ports for the IKE, ESP, and AH protocols by adding the ipsec service:

    # firewall-cmd --add-service="ipsec"
    # firewall-cmd --runtime-to-permanent
    Copy to Clipboard

Verification

  1. Confirm Libreswan is running in FIPS mode:

    # ipsec whack --fipsstatus
    FIPS mode enabled
    Copy to Clipboard
  2. Alternatively, check entries for the ipsec unit in the systemd journal:

    $ journalctl -u ipsec
    ...
    Jan 22 11:26:50 localhost.localdomain pluto[3076]: FIPS Mode: ON
    Copy to Clipboard
  3. To see the available algorithms in FIPS mode:

    # ipsec pluto --selftest 2>&1 | head -6
    Initializing NSS using read-only database "sql:/var/lib/ipsec/nss"
    FIPS Mode: ON
    NSS crypto library initialized
    FIPS mode enabled for pluto daemon
    NSS library is running in FIPS mode
    FIPS HMAC integrity support [not required]
    Copy to Clipboard
  4. To query disabled algorithms in FIPS mode:

    # ipsec pluto --selftest 2>&1 | grep disabled
    Encryption algorithm CAMELLIA_CTR disabled; not FIPS compliant
    Encryption algorithm CAMELLIA_CBC disabled; not FIPS compliant
    Encryption algorithm NULL disabled; not FIPS compliant
    Encryption algorithm CHACHA20_POLY1305 disabled; not FIPS compliant
    Hash algorithm MD5 disabled; not FIPS compliant
    PRF algorithm HMAC_MD5 disabled; not FIPS compliant
    PRF algorithm AES_XCBC disabled; not FIPS compliant
    Integrity algorithm HMAC_MD5_96 disabled; not FIPS compliant
    Integrity algorithm HMAC_SHA2_256_TRUNCBUG disabled; not FIPS compliant
    Integrity algorithm AES_XCBC_96 disabled; not FIPS compliant
    DH algorithm MODP1536 disabled; not FIPS compliant
    DH algorithm DH31 disabled; not FIPS compliant
    Copy to Clipboard
  5. To list all allowed algorithms and ciphers in FIPS mode:

    # ipsec pluto --selftest 2>&1 | grep ESP | grep FIPS | sed "s/^.*FIPS//"
    aes_ccm, aes_ccm_c
    aes_ccm_b
    aes_ccm_a
    NSS(CBC)  3des
    NSS(GCM)  aes_gcm, aes_gcm_c
    NSS(GCM)  aes_gcm_b
    NSS(GCM)  aes_gcm_a
    NSS(CTR)  aesctr
    NSS(CBC)  aes
    aes_gmac
    NSS       sha, sha1, sha1_96, hmac_sha1
    NSS       sha512, sha2_512, sha2_512_256, hmac_sha2_512
    NSS       sha384, sha2_384, sha2_384_192, hmac_sha2_384
    NSS       sha2, sha256, sha2_256, sha2_256_128, hmac_sha2_256
    aes_cmac
    null
    NSS(MODP) null, dh0
    NSS(MODP) dh14
    NSS(MODP) dh15
    NSS(MODP) dh16
    NSS(MODP) dh17
    NSS(MODP) dh18
    NSS(ECP)  ecp_256, ecp256
    NSS(ECP)  ecp_384, ecp384
    NSS(ECP)  ecp_521, ecp521
    Copy to Clipboard

6.9. Protecting the IPsec NSS database by a password

By default, the IPsec service creates its Network Security Services (NSS) database with an empty password during the first start. To enhance security, you can add password protection.

Prerequisites

  • The /var/lib/ipsec/nss/ directory contains NSS database files.

Procedure

  1. Enable password protection for the NSS database for Libreswan:

    # certutil -N -d sql:/var/lib/ipsec/nss
    Enter Password or Pin for "NSS Certificate DB":
    Enter a password which will be used to encrypt your keys.
    The password should be at least 8 characters long,
    and should contain at least one non-alphabetic character.
    
    Enter new password:
    Copy to Clipboard
  2. Create the /etc/ipsec.d/nsspassword file that contains the password you have set in the previous step, for example:

    # cat /etc/ipsec.d/nsspassword
    NSS Certificate DB:<password>
    Copy to Clipboard

    The nsspassword file use the following syntax:

    <token_1>:<password1>
    <token_2>:<password2>
    Copy to Clipboard

    The default NSS software token is NSS Certificate DB. If your system is running in FIPS mode, the name of the token is NSS FIPS 140-2 Certificate DB.

  3. Depending on your scenario, either start or restart the ipsec service after you finish the nsspassword file:

    # systemctl restart ipsec
    Copy to Clipboard

Verification

  1. Check that the ipsec service is running after you have added a non-empty password to its NSS database:

    # systemctl status ipsec
    ● ipsec.service - Internet Key Exchange (IKE) Protocol Daemon for IPsec
       Loaded: loaded (/usr/lib/systemd/system/ipsec.service; enabled; vendor preset: disable>
       Active: active (running)…
    Copy to Clipboard
  2. Check that the Journal log contains entries that confirm a successful initialization:

    # journalctl -u ipsec
    …
    pluto[6214]: Initializing NSS using read-only database "sql:/var/lib/ipsec/nss"
    pluto[6214]: NSS Password from file "/etc/ipsec.d/nsspassword" for token "NSS Certificate DB" with length 20 passed to NSS
    pluto[6214]: NSS crypto library initialized
    …
    Copy to Clipboard

6.10. Configuring an IPsec VPN to use TCP

Libreswan supports TCP encapsulation of IKE and IPsec packets as described in RFC 8229. With this feature, you can establish IPsec VPNs on networks that prevent traffic transmitted via UDP and Encapsulating Security Payload (ESP). You can configure VPN servers and clients to use TCP either as a fallback or as the main VPN transport protocol. Because TCP encapsulation has bigger performance costs, use TCP as the main VPN protocol only if UDP is permanently blocked in your scenario.

Prerequisites

Procedure

  1. Add the following option to the /etc/ipsec.conf file in the config setup section:

    listen-tcp=yes
    Copy to Clipboard
  2. To use TCP encapsulation as a fallback option when the first attempt over UDP fails, add the following two options to the client’s connection definition:

    enable-tcp=fallback
    tcp-remoteport=4500
    Copy to Clipboard

    Alternatively, if you know that UDP is permanently blocked, use the following options in the client’s connection configuration:

    enable-tcp=yes
    tcp-remoteport=4500
    Copy to Clipboard

6.11. 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.

Note

The vpn RHEL system role supports only Libreswan, which is an IPsec implementation, as the VPN provider.

6.11.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

Procedure

  1. 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: redhat.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
    Copy to Clipboard

    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
    Copy to Clipboard

    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, and ignore. For details, see the ipsec.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.

  2. Validate the playbook syntax:

    $ ansible-playbook --syntax-check ~/playbook.yml
    Copy to Clipboard

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  3. Run the playbook:

    $ ansible-playbook ~/playbook.yml
    Copy to Clipboard

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'
    Copy to Clipboard

    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 than start, you might need to manually activate the connection on the managed nodes first.

6.11.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

Procedure

  1. 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: redhat.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
    Copy to Clipboard

    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 example control_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, and ignore. For details, see the ipsec.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.

  2. Validate the playbook syntax:

    $ ansible-playbook --syntax-check ~/playbook.yml
    Copy to Clipboard

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  3. Run the playbook:

    $ ansible-playbook ~/playbook.yml
    Copy to Clipboard

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'
    Copy to Clipboard

    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 than start, you might need to manually activate the connection on the managed nodes first.

6.11.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

  1. Edit the ~/inventory file, and append the cert_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
    Copy to Clipboard

    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).

  2. Store your sensitive variables in an encrypted file:

    1. Create the vault:

      $ ansible-vault create ~/vault.yml
      New Vault password: <vault_password>
      Confirm New Vault password: <vault_password>
      Copy to Clipboard
    2. After the ansible-vault create command opens an editor, enter the sensitive data in the <key>: <value> format:

      pkcs12_pwd: <password>
      Copy to Clipboard
    3. Save the changes, and close the editor. Ansible encrypts the data in the vault.
  3. 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: redhat.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
    Copy to Clipboard

    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 to private, the above playbook contains an according policy for the default cidr 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 the 192.0.2.0/24 subnet and the control node uses the IP address 192.0.2.1, you require a clear policy for 192.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.

  4. Validate the playbook syntax:

    $ ansible-playbook --ask-vault-pass --syntax-check ~/playbook.yml
    Copy to Clipboard

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  5. Run the playbook:

    $ ansible-playbook --ask-vault-pass ~/playbook.yml
    Copy to Clipboard

Verification

  1. On a node in the mesh, ping another node to activate the connection:

    [root@managed-node-01]# ping managed-node-02.example.com
    Copy to Clipboard
  2. 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'
    Copy to Clipboard

6.12. Configuring IPsec connections that opt out of the system-wide crypto policies

Overriding system-wide crypto-policies for a connection:

The RHEL system-wide cryptographic policies create a special connection called %default. This connection contains the default values for the ikev2, esp, and ike options. However, you can override the default values by specifying the mentioned option in the connection configuration file.

For example, the following configuration allows connections that use IKEv1 with AES and SHA-1 or SHA-2, and IPsec (ESP) with either AES-GCM or AES-CBC:

conn MyExample
  ...
  keyexchange=ikev1
  ike=aes-sha2,aes-sha1;modp2048
  esp=aes_gcm,aes-sha2,aes-sha1
  ...
Copy to Clipboard

Note that AES-GCM is available for IPsec (ESP) and for IKEv2, but not for IKEv1.

Disabling system-wide crypto policies for all connections:

To disable system-wide crypto policies for all IPsec connections, comment out the following line in the /etc/ipsec.conf file:

include /etc/crypto-policies/back-ends/libreswan.config
Copy to Clipboard

Then add the keyexchange=ikev1 option to your connection configuration file.

6.13. Troubleshooting IPsec VPN configurations

Problems related to IPsec VPN configurations most commonly occur due to several main reasons. If you are encountering such problems, you can check if the cause of the problem corresponds to any of the following scenarios, and apply the corresponding solution.

Basic connection troubleshooting

Most problems with VPN connections occur in new deployments, where administrators configured endpoints with mismatched configuration options. Also, a working configuration can suddenly stop working, often due to newly introduced incompatible values. This could be the result of an administrator changing the configuration. Alternatively, an administrator may have installed a firmware update or a package update with different default values for certain options, such as encryption algorithms.

To confirm that an IPsec VPN connection is established:

# ipsec trafficstatus
006 #8: "vpn.example.com"[1] 192.0.2.1, type=ESP, add_time=1595296930, inBytes=5999, outBytes=3231, id='@vpn.example.com', lease=100.64.13.5/32
Copy to Clipboard

If the output is empty or does not show an entry with the connection name, the tunnel is broken.

To check that the problem is in the connection:

  1. Reload the vpn.example.com connection:

    # ipsec add vpn.example.com
    002 added connection description "vpn.example.com"
    Copy to Clipboard
  2. Next, initiate the VPN connection:

    # ipsec up vpn.example.com
    Copy to Clipboard
Firewall-related problems

The most common problem is that a firewall on one of the IPsec endpoints or on a router between the endpoints is dropping all Internet Key Exchange (IKE) packets.

  • For IKEv2, an output similar to the following example indicates a problem with a firewall:

    # ipsec up vpn.example.com
    181 "vpn.example.com"[1] 192.0.2.2 #15: initiating IKEv2 IKE SA
    181 "vpn.example.com"[1] 192.0.2.2 #15: STATE_PARENT_I1: sent v2I1, expected v2R1
    010 "vpn.example.com"[1] 192.0.2.2 #15: STATE_PARENT_I1: retransmission; will wait 0.5 seconds for response
    010 "vpn.example.com"[1] 192.0.2.2 #15: STATE_PARENT_I1: retransmission; will wait 1 seconds for response
    010 "vpn.example.com"[1] 192.0.2.2 #15: STATE_PARENT_I1: retransmission; will wait 2 seconds for
    ...
    Copy to Clipboard
  • For IKEv1, the output of the initiating command looks like:

    # ipsec up vpn.example.com
    002 "vpn.example.com" #9: initiating Main Mode
    102 "vpn.example.com" #9: STATE_MAIN_I1: sent MI1, expecting MR1
    010 "vpn.example.com" #9: STATE_MAIN_I1: retransmission; will wait 0.5 seconds for response
    010 "vpn.example.com" #9: STATE_MAIN_I1: retransmission; will wait 1 seconds for response
    010 "vpn.example.com" #9: STATE_MAIN_I1: retransmission; will wait 2 seconds for response
    ...
    Copy to Clipboard

    Because the IKE protocol, which is used to set up IPsec, is encrypted, you can troubleshoot only a limited subset of problems using the tcpdump tool. If a firewall is dropping IKE or IPsec packets, you can try to find the cause using the tcpdump utility. However, tcpdump cannot diagnose other problems with IPsec VPN connections.

  • To capture the negotiation of the VPN and all encrypted data on the eth0 interface:

    # tcpdump -i eth0 -n -n esp or udp port 500 or udp port 4500 or tcp port 4500
    Copy to Clipboard
Mismatched algorithms, protocols, and policies

VPN connections require that the endpoints have matching IKE algorithms, IPsec algorithms, and IP address ranges. If a mismatch occurs, the connection fails. If you identify a mismatch by using one of the following methods, fix it by aligning algorithms, protocols, or policies.

  • If the remote endpoint is not running IKE/IPsec, you can see an ICMP packet indicating it. For example:

    # ipsec up vpn.example.com
    ...
    000 "vpn.example.com"[1] 192.0.2.2 #16: ERROR: asynchronous network error report on wlp2s0 (192.0.2.2:500), complainant 198.51.100.1: Connection refused [errno 111, origin ICMP type 3 code 3 (not authenticated)]
    ...
    Copy to Clipboard
  • Example of mismatched IKE algorithms:

    # ipsec up vpn.example.com
    ...
    003 "vpn.example.com"[1] 193.110.157.148 #3: dropping unexpected IKE_SA_INIT message containing NO_PROPOSAL_CHOSEN notification; message payloads: N; missing payloads: SA,KE,Ni
    Copy to Clipboard
  • Example of mismatched IPsec algorithms:

    # ipsec up vpn.example.com
    ...
    182 "vpn.example.com"[1] 193.110.157.148 #5: STATE_PARENT_I2: sent v2I2, expected v2R2 {auth=IKEv2 cipher=AES_GCM_16_256 integ=n/a prf=HMAC_SHA2_256 group=MODP2048}
    002 "vpn.example.com"[1] 193.110.157.148 #6: IKE_AUTH response contained the error notification NO_PROPOSAL_CHOSEN
    Copy to Clipboard

    A mismatched IKE version could also result in the remote endpoint dropping the request without a response. This looks identical to a firewall dropping all IKE packets.

  • Example of mismatched IP address ranges for IKEv2 (called Traffic Selectors - TS):

    # ipsec up vpn.example.com
    ...
    1v2 "vpn.example.com" #1: STATE_PARENT_I2: sent v2I2, expected v2R2 {auth=IKEv2 cipher=AES_GCM_16_256 integ=n/a prf=HMAC_SHA2_512 group=MODP2048}
    002 "vpn.example.com" #2: IKE_AUTH response contained the error notification TS_UNACCEPTABLE
    Copy to Clipboard
  • Example of mismatched IP address ranges for IKEv1:

    # ipsec up vpn.example.com
    ...
    031 "vpn.example.com" #2: STATE_QUICK_I1: 60 second timeout exceeded after 0 retransmits.  No acceptable response to our first Quick Mode message: perhaps peer likes no proposal
    Copy to Clipboard
  • When using PreSharedKeys (PSK) in IKEv1, if both sides do not put in the same PSK, the entire IKE message becomes unreadable:

    # ipsec up vpn.example.com
    ...
    003 "vpn.example.com" #1: received Hash Payload does not match computed value
    223 "vpn.example.com" #1: sending notification INVALID_HASH_INFORMATION to 192.0.2.23:500
    Copy to Clipboard
  • In IKEv2, the mismatched-PSK error results in an AUTHENTICATION_FAILED message:

    # ipsec up vpn.example.com
    ...
    002 "vpn.example.com" #1: IKE SA authentication request rejected by peer: AUTHENTICATION_FAILED
    Copy to Clipboard
Maximum transmission unit

Other than firewalls blocking IKE or IPsec packets, the most common cause of networking problems relates to an increased packet size of encrypted packets. Network hardware fragments packets larger than the maximum transmission unit (MTU), for example, 1500 bytes. Often, the fragments are lost and the packets fail to re-assemble. This leads to intermittent failures, when a ping test, which uses small-sized packets, works but other traffic fails. In this case, you can establish an SSH session but the terminal freezes as soon as you use it, for example, by entering the 'ls -al /usr' command on the remote host.

To work around the problem, reduce MTU size by adding the mtu=1400 option to the tunnel configuration file.

Alternatively, for TCP connections, enable an iptables rule that changes the MSS value:

# iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Copy to Clipboard

If the previous command does not solve the problem in your scenario, directly specify a lower size in the set-mss parameter:

# iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380
Copy to Clipboard
Network address translation (NAT)

When an IPsec host also serves as a NAT router, it could accidentally remap packets. The following example configuration demonstrates the problem:

conn myvpn
    left=172.16.0.1
    leftsubnet=10.0.2.0/24
    right=172.16.0.2
    rightsubnet=192.168.0.0/16
…
Copy to Clipboard

The system with address 172.16.0.1 have a NAT rule:

iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
Copy to Clipboard

If the system on address 10.0.2.33 sends a packet to 192.168.0.1, then the router translates the source 10.0.2.33 to 172.16.0.1 before it applies the IPsec encryption.

Then, the packet with the source address 10.0.2.33 no longer matches the conn myvpn configuration, and IPsec does not encrypt this packet.

To solve this problem, insert rules that exclude NAT for target IPsec subnet ranges on the router, in this example:

iptables -t nat -I POSTROUTING -s 10.0.2.0/24 -d 192.168.0.0/16 -j RETURN
Copy to Clipboard
Kernel IPsec subsystem bugs

The kernel IPsec subsystem might fail, for example, when a bug causes a desynchronizing of the IKE user space and the IPsec kernel. To check for such problems:

$ cat /proc/net/xfrm_stat
XfrmInError                 0
XfrmInBufferError           0
...
Copy to Clipboard

Any non-zero value in the output of the previous command indicates a problem. If you encounter this problem, open a new support case, and attach the output of the previous command along with the corresponding IKE logs.

Libreswan logs

Libreswan logs using the syslog protocol by default. You can use the journalctl command to find log entries related to IPsec. Because the corresponding entries to the log are sent by the pluto IKE daemon, search for the "pluto” keyword, for example:

$ journalctl -b | grep pluto
Copy to Clipboard

To show a live log for the ipsec service:

$ journalctl -f -u ipsec
Copy to Clipboard

If the default level of logging does not reveal your configuration problem, enable debug logs by adding the plutodebug=all option to the config setup section in the /etc/ipsec.conf file.

Note that debug logging produces a lot of entries, and it is possible that either the journald or syslogd service rate-limits the syslog messages. To ensure you have complete logs, redirect the logging to a file. Edit the /etc/ipsec.conf, and add the logfile=/var/log/pluto.log in the config setup section.

6.14. Configuring a VPN connection with control-center

If you use Red Hat Enterprise Linux with a graphical interface, you can configure a VPN connection in the GNOME control-center.

Prerequisites

  • The NetworkManager-libreswan-gnome package is installed.

Procedure

  1. Press the Super key, type Settings, and press Enter to open the control-center application.
  2. Select the Network entry on the left.
  3. Click the + icon.
  4. Select VPN.
  5. Select the Identity menu entry to see the basic configuration options:

    General

    Gateway - The name or IP address of the remote VPN gateway.

    Authentication

    Type

    • IKEv2 (Certificate)- client is authenticated by certificate. It is more secure (default).
    • IKEv1 (XAUTH) - client is authenticated by user name and password, or a pre-shared key (PSK).

      The following configuration settings are available under the Advanced section:

      Warning

      When configuring an IPsec-based VPN connection using the gnome-control-center application, the Advanced dialog displays the configuration, but it does not allow any changes. As a consequence, users cannot change any advanced IPsec options. Use the nm-connection-editor or nmcli tools instead to perform configuration of the advanced properties.

      Identification

    • Domain - If required, enter the Domain Name.

      Security

    • Phase1 Algorithms - corresponds to the ike Libreswan parameter - enter the algorithms to be used to authenticate and set up an encrypted channel.
    • Phase2 Algorithms - corresponds to the esp Libreswan parameter - enter the algorithms to be used for the IPsec negotiations.

      Check the Disable PFS field to turn off Perfect Forward Secrecy (PFS) to ensure compatibility with old servers that do not support PFS.

    • Phase1 Lifetime - corresponds to the ikelifetime Libreswan parameter - how long the key used to encrypt the traffic will be valid.
    • Phase2 Lifetime - corresponds to the salifetime Libreswan parameter - how long a particular instance of a connection should last before expiring.

      Note that the encryption key should be changed from time to time for security reasons.

    • Remote network - corresponds to the rightsubnet Libreswan parameter - the destination private remote network that should be reached through the VPN.

      Check the narrowing field to enable narrowing. Note that it is only effective in IKEv2 negotiation.

    • Enable fragmentation - corresponds to the fragmentation Libreswan parameter - whether or not to allow IKE fragmentation. Valid values are yes (default) or no.
    • Enable Mobike - corresponds to the mobike Libreswan parameter - whether or not to allow Mobility and Multihoming Protocol (MOBIKE, RFC 4555) to enable a connection to migrate its endpoint without needing to restart the connection from scratch. This is used on mobile devices that switch between wired, wireless, or mobile data connections. The values are no (default) or yes.
  6. Select the IPv4 menu entry:

    IPv4 Method

    • Automatic (DHCP) - Choose this option if the network you are connecting to uses a DHCP server to assign dynamic IP addresses.
    • Link-Local Only - Choose this option if the network you are connecting to does not have a DHCP server and you do not want to assign IP addresses manually. Random addresses will be assigned as per RFC 3927 with prefix 169.254/16.
    • Manual - Choose this option if you want to assign IP addresses manually.
    • Disable - IPv4 is disabled for this connection.

      DNS

      In the DNS section, when Automatic is ON, switch it to OFF to enter the IP address of a DNS server you want to use separating the IPs by comma.

      Routes

      Note that in the Routes section, when Automatic is ON, routes from DHCP are used, but you can also add additional static routes. When OFF, only static routes are used.

    • Address - Enter the IP address of a remote network or host.
    • Netmask - The netmask or prefix length of the IP address entered above.
    • Gateway - The IP address of the gateway leading to the remote network or host entered above.
    • Metric - A network cost, a preference value to give to this route. Lower values will be preferred over higher values.

      Use this connection only for resources on its network

      Select this check box to prevent the connection from becoming the default route. Selecting this option means that only traffic specifically destined for routes learned automatically over the connection or entered here manually is routed over the connection.

  7. To configure IPv6 settings in a VPN connection, select the IPv6 menu entry:

    IPv6 Method

    • Automatic - Choose this option to use IPv6 Stateless Address AutoConfiguration (SLAAC) to create an automatic, stateless configuration based on the hardware address and Router Advertisements (RA).
    • Automatic, DHCP only - Choose this option to not use RA, but request information from DHCPv6 directly to create a stateful configuration.
    • Link-Local Only - Choose this option if the network you are connecting to does not have a DHCP server and you do not want to assign IP addresses manually. Random addresses will be assigned as per RFC 4862 with prefix FE80::0.
    • Manual - Choose this option if you want to assign IP addresses manually.
    • Disable - IPv6 is disabled for this connection.

      Note that DNS, Routes, Use this connection only for resources on its network are common to IPv4 settings.

  8. Once you have finished editing the VPN connection, click the Add button to customize the configuration or the Apply button to save it for the existing one.
  9. Switch the profile to ON to activate the VPN connection.
  10. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

6.15. Configuring an IPsec based VPN connection by using nmstatectl

IPsec (Internet Protocol Security) is a security protocol suite, provided by Libreswan, for implementation of VPN. IPsec includes protocols to initiate authentication at the time of connection establishment and manage keys during the data transfer. When an application deploys in a network and communicates by using the IP protocol, IPsec can protect data communication.

To manage an IPsec-based configuration for authenticating VPN connections, you can use the nmstatectl utility. This utility provides command line access to a declarative API for host network management. The following are the authentication types for the host-to-subnet and host-to-host communication modes:

  • Host-to-subnet PKI authentication
  • Host-to-subnet RSA authentication
  • Host-to-subnet PSK authentication
  • Host-to-host tunnel mode authentication
  • Host-to-host transport mode authentication

6.15.1. Configuring a host-to-subnet IPSec VPN with PKI authentication and tunnel mode by using nmstatectl

If you want to use encryption based on the trusted entity authentication in IPsec, Public Key Infrastructure (PKI) provides secure communication by using cryptographic keys between two hosts. Both communicating hosts generate private and public keys where each host maintains a private key by sharing public key with the trusted entity Certificate Authority (CA). The CA generates a digital certificate after verifying the authenticity. In case of encryption and decryption, the host uses a private key for encryption and public key for decryption.

By using Nmstate, a declarative API for network management, you can configure a PKI authentication-based IPsec connection. After setting the configuration, the Nmstate API ensures that the result matches with the configuration file. If anything fails, nmstate automatically rolls back the changes to avoid an incorrect state of the system.

To establish encrypted communication in host-to-subnet configuration, remote IPsec end provides another IP to host by using parameter dhcp: true. In the case of defining systems for IPsec in nmstate, the left-named system is the local host while the right-named system is the remote host.

Note that, due to the design of the NetworkManager-libreswan plugin, you can use nmstatectl on one side and you must manually configure IPsec on the other side.

Prerequisites

  • By using a password, you have generated a PKCS #12 file that stores certificates and cryptographic keys.

Procedure

  1. Install the required packages:

    # dnf install nmstate libreswan NetworkManager-libreswan
    Copy to Clipboard
  2. Restart the NetworkManager service:

    # systemctl restart NetworkManager
    Copy to Clipboard
  3. As Libreswan was already installed, remove its old database files and re-create them:

    # systemctl stop ipsec
    # rm /var/lib/ipsec/nss/*db
    # ipsec initnss
    Copy to Clipboard
  4. Enable and start the ipsec service:

    # systemctl enable --now ipsec
    Copy to Clipboard
  5. Import the PKCS#12 file:

    # ipsec import node-example.p12
    Copy to Clipboard

    When importing the PKCS#12 file, enter the password that was used to create the file.

  6. Create a YAML file, for example ~/create-pki-authentication.yml, with the following content:

    ---
    interfaces:
    - name: 'example_ipsec_conn1'            
    1
    
      type: ipsec
      ipv4:
        enabled: true
        dhcp: true
      libreswan:
        ipsec-interface: 'yes'               
    2
    
        left: '192.0.2.150'                  
    3
    
        leftid: '%fromcert'                  
    4
    
        leftcert: 'local-host.example.com'   
    5
    
        right: '192.0.2.250'                 
    6
    
        rightid: '%fromcert'                 
    7
    
        ikev2: 'insist'                      
    8
    
        ikelifetime: '24h'                   
    9
    
        salifetime: '24h'                    
    10
    Copy to Clipboard

    The YAML file defines the following settings:

    1
    An IPsec connection name
    2
    The value yes means libreswan creates an IPsec xfrm virtual interface ipsec<number> and automatically finds the next available number
    3
    A static IPv4 address of public network interface for a local host
    4
    On a local host, the value of %fromcert sets the ID to a Distinguished Name (DN) that is fetched from a loaded certificate
    5
    A Distinguished Name (DN) of a local host’s public key
    6
    A static IPv4 address of public network interface for a remote host
    7
    On a remote host, the value of %fromcert sets the ID to a Distinguished Name (DN) that is fetched from a loaded certificate.
    8
    insist value accepts and receives only the Internet Key Exchange (IKEv2) protocol
    9
    The duration of IKE protocol
    10
    The duration of IPsec security association (SA)
  7. Apply settings to the system:

    # nmstatectl apply ~/create-pki-authentication.yml
    Copy to Clipboard
  8. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

Verification

  1. Verify IPsec status:

    # ip xfrm state
    Copy to Clipboard
  2. Verify IPsec policies:

    # ip xfrm policy
    Copy to Clipboard

6.15.2. Configuring a host-to-subnet IPSec VPN with RSA authentication and tunnel mode by using nmstatectl

If you want to use asymmetric cryptography-based key authentication in IPsec, the RSA algorithm provides secure communication by using either of private and public keys for encryption and decryption between two hosts. This method uses a private key for encryption, and a public key for decryption.

By using Nmstate, a declarative API for network management, you can configure RSA-based IPsec authentication. After setting the configuration, the Nmstate API ensures that the result matches with the configuration file. If anything fails, nmstate automatically rolls back the changes to avoid an incorrect state of the system.

To establish encrypted communication in host-to-subnet configuration, remote IPsec end provides another IP to host by using parameter dhcp: true. In the case of defining systems for IPsec in nmstate, the left-named system is the local host while the right-named system is the remote host.

Note that, due to the design of the NetworkManager-libreswan plugin, you can use nmstatectl on one side and you must manually configure IPsec on the other side.

Procedure

  1. Install the required packages:

    # dnf install nmstate libreswan NetworkManager-libreswan
    Copy to Clipboard
  2. Restart the NetworkManager service:

    # systemctl restart NetworkManager
    Copy to Clipboard
  3. If Libreswan was already installed, remove its old database files and re-create them:

    # systemctl stop ipsec
    # rm /var/lib/ipsec/nss/*db
    # ipsec initnss
    Copy to Clipboard
  4. Generate a RSA key pair on each host:

    # ipsec newhostkey
    Copy to Clipboard
  5. The previous step returned the generated key ckaid. Use that ckaid with the following command on left, for example:

    # ipsec showhostkey --left --ckaid <0sAwEAAesFfVZqFzRA9F>
    Copy to Clipboard
  6. The output of the previous command generated the leftrsasigkey= line required for the configuration. Do the same on the second host (right):

    # ipsec showhostkey --right --ckaid <0sAwEAAesFfVZqFzRA9E>
    Copy to Clipboard
  7. Enable the ipsec service to automatically start it on boot:

    # systemctl enable --now ipsec
    Copy to Clipboard
  8. Create a YAML file, for example ~/create-rsa-authentication.yml, with the following content:

    ---
    interfaces:
    - name: 'example_ipsec_conn1'               
    1
    
      type: ipsec                               
    2
    
      ipv4:
        enabled: true
        dhcp: true
      libreswan:
        ipsec-interface: '99'                   
    3
    
        leftrsasigkey: '0sAwEAAesFfVZqFzRA9F'   
    4
    
        left: '192.0.2.150'                     
    5
    
        leftid: 'local-host-rsa.example.com'    
    6
    
        right: '192.0.2.250'                    
    7
    
        rightrsasigkey: '0sAwEAAesFfVZqFzRA9E'  
    8
    
        rightid: 'remote-host-rsa.example.com'  
    9
    
        ikev2: 'insist'                         
    10
    Copy to Clipboard

    The YAML file defines the following settings:

    1
    An IPsec connection name
    2
    An interface name
    3
    The value 99 means that libreswan creates an IPsec xfrm virtual interface ipsec<number> and automatically finds the next available number
    4
    The RSA public key of a local host
    5
    A static IPv4 address of public network interface of a local host
    6
    A Distinguished Name (DN) for a local host
    7
    The RSA public key of a remote host
    8
    A static IPv4 address of public network interface of a remote host
    9
    A Distinguished Name(DN) for a remote host
    10
    insist value accepts and receives only the Internet Key Exchange (IKEv2) protocol
  9. Apply the settings to the system:

    # nmstatectl apply ~/create-rsa-authentication.yml
    Copy to Clipboard
  10. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

Verification

  1. Display the IP settings of the network interface:

    # ip addr show <device_name>
    Copy to Clipboard
  2. Verify IPsec status:

    # ip xfrm state
    Copy to Clipboard
  3. Verify IPsec policies:

    # ip xfrm policy
    Copy to Clipboard

6.15.3. Configuring a host-to-subnet IPSec VPN with PSK authentication and tunnel mode by using nmstatectl

If you want to use encryption based on mutual authentication in IPsec, the Pre-Shared Key (PSK) method provides secure communication by using a secret key between two hosts. A file stores the secret key and the same key encrypts the data flowing through the tunnel.

By using Nmstate, a declarative API for network management, you can configure PSK-based IPsec authentication. After setting the configuration, the Nmstate API ensures that the result matches with the configuration file. If anything fails, nmstate automatically rolls back the changes to avoid incorrect state of the system.

To establish encrypted communication in host-to-subnet configuration, remote IPsec end provides another IP to host by using parameter dhcp: true. In the case of defining systems for IPsec in nmstate, the left-named system is the local host while the right-named system is the remote host.

Note that, due to the design of the NetworkManager-libreswan plugin, you can use nmstatectl on one side and you must manually configure IPsec on the other side.

Note

As this method uses static strings for authentication and encryption, use it only for testing/development purposes.

Procedure

  1. Install the required packages:

    # dnf install nmstate libreswan NetworkManager-libreswan
    Copy to Clipboard
  2. Restart the NetworkManager service:

    # systemctl restart NetworkManager
    Copy to Clipboard
  3. If Libreswan was already installed, remove its old database files and re-create them:

    # systemctl stop ipsec
    # rm /var/lib/ipsec/nss/*db
    # ipsec initnss
    Copy to Clipboard
  4. Enable the ipsec service to automatically start it on boot:

    # systemctl enable --now ipsec
    Copy to Clipboard
  5. Create a YAML file, for example ~/create-pks-authentication.yml, with the following content:

    ---
    interfaces:
    - name: 'example_ipsec_conn1'           
    1
    
      type: ipsec
      ipv4:
        enabled: true
        dhcp: true
      libreswan:
        ipsec-interface: 'no'               
    2
    
        right: '192.0.2.150'                
    3
    
        rightid: 'remote-host.example.org'  
    4
    
        left: '192.0.2.250'                 
    5
    
        leftid: 'local-host.example.org'    
    6
    
        psk: "example_password"
        ikev2: 'insist'                     
    7
    Copy to Clipboard

    The YAML file defines the following settings:

    1
    An IPsec connection name
    2
    Setting no value indicates that libreswan creates only xfrm policies, and not a virtual xfrm interface
    3
    A static IPv4 address of public network interface of a remote host
    4
    A Distinguished Name (DN) for a remote host
    5
    A static IPv4 address of public network interface of a local host
    6
    A Distinguished Name (DN) for a local host
    7
    insist value accepts and receives only the Internet Key Exchange (IKEv2) protocol
  6. Apply the settings to the system:

    # nmstatectl apply ~/create-pks-authentication.yml
    Copy to Clipboard
  7. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

Verification

  1. Display the IP settings of network interface:

    # ip addr show <device_name>
    Copy to Clipboard
  2. Verify IPsec status:

    # ip xfrm state
    Copy to Clipboard
  3. Verify IPsec policies:

    # ip xfrm policy
    Copy to Clipboard

6.15.4. Configuring a host-to-host IPsec VPN with PKI authentication and tunnel mode by using nmstatectl

IPsec (Internet Protocol Security) is a security protocol suite to authenticate and encrypt IP communications within networks and devices. The Libreswan software provides an IPsec implementation for VPNs.

In tunnel mode, the source and destination IP address of communication is encrypted in the IPsec tunnel. External network sniffers can only get left IP and right IP. In general, for tunnel mode, it supports host-to-host, host-to-subnet, and subnet-to-subnet. In this mode, a new IP packet encapsulates an existing packet along with its payload and header. Encapsulation in this mode protects IP data, source, and destination headers over an unsecure network. This mode is useful to transfer data in subnet-to-subnet, remote access connections, and untrusted networks, such as open public Wi-Fi networks. By default, IPsec establishes a secure channel between two sites in tunnel mode. With the following configuration, you can establish a VPN connection as a host-to-host architecture.

By using Nmstate, a declarative API for network management, you can configure an IPsec VPN connection. After setting the configuration, the Nmstate API ensures that the result matches with the configuration file. If anything fails, nmstate automatically rolls back the changes to avoid incorrect state of the system.

In host-to-host configuration, you need to set leftmodecfgclient: no so that it can’t receive network configuration from the server, hence the value no. In the case of defining systems for IPsec in nmstate, the left-named system is the local host while the right-named system is the remote host.

Note that, due to the design of the NetworkManager-libreswan plugin, you can use nmstatectl on one side and you must manually configure IPsec on the other side.

Prerequisites

  • By using a password, you have generated a PKCS #12 file that stores certificates and cryptographic keys.

Procedure

  1. Install the required packages:

    # dnf install nmstate libreswan NetworkManager-libreswan
    Copy to Clipboard
  2. Restart the NetworkManager service:

    # systemctl restart NetworkManager
    Copy to Clipboard
  3. As Libreswan was already installed, remove its old database files and re-create them:

    # systemctl stop ipsec
    # rm /var/lib/ipsec/nss/*db
    # ipsec initnss
    Copy to Clipboard
  4. Import the PKCS#12 file:

    # ipsec import node-example.p12
    Copy to Clipboard

    When importing the PKCS#12 file, enter the password that was used to generate the file.

  5. Enable and start the ipsec service:

    # systemctl enable --now ipsec
    Copy to Clipboard
  6. Create a YAML file, for example ~/create-p2p-vpn-authentication.yml, with the following content:

    ---
    interfaces:
    - name: 'example_ipsec_conn1'             
    1
    
      type: ipsec
      libreswan:
        left: '192.0.2.150'                   
    2
    
        leftid:  'local-host.example.com'     
    3
    
        leftcert: 'local-host.example.com'    
    4
    
        leftmodecfgclient: no                 
    5
    
        right: '192.0.2.250'                  
    6
    
        rightid: 'remote-host.example.com'    
    7
    
        rightsubnet: '192.0.2.150/32'         
    8
    
        ikev2: 'insist'                       
    9
    Copy to Clipboard

    The YAML file defines the following settings:

    1
    An IPsec connection name
    2
    A static IPv4 address of public network interface for a local host
    3
    A distinguished Name (DN) of a local host
    4
    A certificate name installed on a local host
    5
    The value for not to retrieve client configuration from a remote host
    6
    A static IPv4 address of public network interface for a remote host
    7
    A distinguished Name (DN) of a remote host
    8
    The subnet range of a remote host - 192.0.2.150 with 32 IPv4 addresses
    9
    The value to accept and receive only the Internet Key Exchange (IKEv2) protocol
  7. Apply the settings to the system:

    # nmstatectl apply ~/create-p2p-vpn-authentication.yml
    Copy to Clipboard
  8. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

Verification

  1. Display the created P2P policy:

    # ip xfrm policy
    Copy to Clipboard
  2. Verify IPsec status:

    # ip xfrm state
    Copy to Clipboard

6.15.5. Configuring a host-to-host IPsec VPN with PKI authentication and transport mode by using nmstatectl

IPsec (Internet Protocol Security) is a security protocol suite to authenticate and encrypt IP communications within networks and devices. The Libreswan utility provides IPsec based implementation for VPN.

In transport mode, encryption works only for the payload of an IP packet. Also, a new IPsec header gets appended to the IP packet by keeping the original IP header as it is. Transport mode does not encrypt the source and destination IP of communication but copies them to an external IP header. Hence, encryption protects only IP data across the network. This mode is useful to transfer data in a host-to-host connection of a network. This mode is often used along with the GRE tunnel to save 20 bytes (IP header) of overheads. By default, the IPsec utility uses tunnel mode. To use transfer mode, set type: transport for host-to-host connection data transfer.

By using Nmstate, a declarative API for network management, you can configure an IPsec VPN connection. After setting the configuration, the Nmstate API ensures that the result matches with the configuration file. If anything fails, nmstate automatically rolls back the changes to avoid incorrect state of the system. To override the default tunnel mode, specify transport mode.

In the case of defining systems for IPsec in nmstate, the left-named system is the local host while the right-named system is the remote host.

Note that, due to the design of the NetworkManager-libreswan plugin, you can use nmstatectl on one side and you must manually configure IPsec on the other side.

Prerequisites

  • By using a password, you have generated a PKCS #12 file that stores certificates and cryptographic keys.

Procedure

  1. Install the required packages:

    # dnf install nmstate libreswan NetworkManager-libreswan
    Copy to Clipboard
  2. Restart the NetworkManager service:

    # systemctl restart NetworkManager
    Copy to Clipboard
  3. As Libreswan was already installed, remove its old database files and re-create them:

    # systemctl stop ipsec
    # rm /var/lib/ipsec/nss/*db
    # ipsec initnss
    Copy to Clipboard
  4. Import the PKCS#12 file:

    # ipsec import node-example.p12
    Copy to Clipboard

    When importing the PKCS#12 file, enter the password that was used to create the file.

  5. Enable and start the ipsec service:

    # systemctl enable --now ipsec
    Copy to Clipboard
  6. Create a YAML file, for example ~/create-p2p-transport-authentication.yml, with the following content:

    ---
    interfaces:
    - name: 'example_ipsec_conn1'           
    1
    
      type: ipsec
      libreswan:
        type: 'transport'                   
    2
    
        ipsec-interface: '99'               
    3
    
        left: '192.0.2.150'                 
    4
    
        leftid: '%fromcert'                 
    5
    
        leftcert: 'local-host.example.org'  
    6
    
        right: '192.0.2.250'                
    7
    
        prefix-length: '32'                 
    8
    
        rightid: '%fromcert'                
    9
    
        ikev2: 'insist'                     
    10
    
        ikelifetime: '24h'                  
    11
    
        salifetime: '24h'                   
    12
    Copy to Clipboard

    The YAML file defines the following settings:

    1
    An IPsec connection name
    2
    An IPsec mode
    3
    The value 99 means that libreswan creates an IPsec xfrm virtual interface ipsec<number> and automatically finds the next available number
    4
    A static IPv4 address of public network interface for a local host
    5
    On a local host, the value of %fromcert sets the ID to a Distinguished Name (DN) which is fetched from a loaded certificate
    6
    A Distinguished Name (DN) of a local host’s public key
    7
    A static IPv4 address of public network interface for a remote host
    8
    The subnet mask of a static IPv4 address of a local host
    9
    On a remote host, the value of %fromcert sets the ID to a Distinguished Name (DN) which is fetched from a loaded certificate
    10
    The value to accept and receive only the Internet Key Exchange (IKEv2) protocol
    11
    The duration of IKE protocol
    12
    The duration of IPsec security association (SA)
  7. Apply the settings to the system:

    # nmstatectl apply ~/create-p2p-transport-authentication.yml
    Copy to Clipboard
  8. If you use this host in a network with DHCP or Stateless Address Autoconfiguration (SLAAC), the connection can be vulnerable to being redirected. For details and mitigation steps, see Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel.

Verification

  1. Verify IPsec status:

    # ip xfrm state
    Copy to Clipboard
  2. Verify IPsec policies:

    # ip xfrm policy
    Copy to Clipboard

6.16. Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel

Both a DHCP server and Stateless Address Autoconfiguration (SLAAC) can add routes to a client’s routing table. For example, a malicious DHCP server can use this feature to force a host with VPN connection to redirect traffic through a physical interface instead of the VPN tunnel. This vulnerability is also known as TunnelVision and described in the CVE-2024-3661 vulnerability article.

To mitigate this vulnerability, you can assign the VPN connection to a dedicated routing table. This prevents the DHCP configuration or SLAAC to manipulate routing decisions for network packets intended for the VPN tunnel.

Follow the steps if at least one of the conditions applies to your environment:

  • At least one network interface uses DHCP or SLAAC.
  • Your network does not use mechanisms, such as DHCP snooping, that prevent a rogue DHCP server.
Important

Routing the entire traffic through the VPN prevents the host from accessing local network resources.

Procedure

  1. Decide which routing table you want to use. The following steps use table 75. By default, RHEL does not use the tables 1-254, and you can use any of them.
  2. Configure the VPN connection profile to place the VPN routes in a dedicated routing table:

    # nmcli connection modify <vpn_connection_profile> ipv4.route-table 75 ipv6.route-table 75
    Copy to Clipboard
  3. Set a low priority value for the table you used in the previous command:

    # nmcli connection modify <vpn_connection_profile> ipv4.routing-rules "priority 32345 from all table 75" ipv6.routing-rules "priority 32345 from all table 75"
    Copy to Clipboard

    The priority value can be any value between 1 and 32766. The lower the value, the higher the priority.

  4. Reconnect the VPN connection:

    # nmcli connection down <vpn_connection_profile>
    # nmcli connection up <vpn_connection_profile>
    Copy to Clipboard

Verification

  1. Display the IPv4 routes in table 75:

    # ip route show table 75
    ...
    192.0.2.0/24 via 192.0.2.254 dev vpn_device proto static metric 50
    default dev vpn_device proto static scope link metric 50
    Copy to Clipboard

    The output confirms that both the route to the remote network and the default gateway are assigned to routing table 75 and, therefore, all traffic is routed through the tunnel. If you set ipv4.never-default true in the VPN connection profile, a default route is not created and, therefore, not visible in this output.

  2. Display the IPv6 routes in table 75:

    # ip -6 route show table 75
    ...
    2001:db8:1::/64 dev vpn_device proto kernel metric 50 pref medium
    default dev vpn_device proto static metric 50 pref medium
    Copy to Clipboard

    The output confirms that both the route to the remote network and the default gateway are assigned to routing table 75 and, therefore, all traffic is routed through the tunnel. If you set ipv6.never-default true in the VPN connection profile, a default route is not created and, therefore, not visible in this output.

Back to top
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2025 Red Hat