Securing networks
Configuring secured networks and network communication
Abstract
Providing feedback on Red Hat documentation Copy linkLink copied to clipboard!
We appreciate your feedback on our documentation. Let us know how we can improve it.
Submitting feedback through Jira (account required)
- Log in to the Jira website.
- Click Create in the top navigation bar
- Enter a descriptive title in the Summary field.
- Enter your suggestion for improvement in the Description field. Include links to the relevant parts of the documentation.
- Click Create at the bottom of the dialogue.
Chapter 1. Using secure communications between two systems with OpenSSH Copy linkLink copied to clipboard!
SSH (Secure Shell) is a protocol which provides secure communications between two systems using a client-server architecture and allows users to log in to server host systems remotely. Unlike other remote communication protocols, such as FTP or Telnet, SSH encrypts the login session, which prevents intruders from collecting unencrypted passwords from the connection.
1.1. SSH and OpenSSH Copy linkLink copied to clipboard!
SSH (Secure Shell) is a program for logging into a remote machine and executing commands on that machine. The SSH protocol provides secure encrypted communications between two untrusted hosts over an insecure network. You can also forward X11 connections and arbitrary TCP/IP ports over the secure channel.
The SSH protocol mitigates security threats, such as interception of communication between two systems and impersonation of a particular host, when you use it for remote shell login or file copying. This is because the SSH client and server use digital signatures to verify their identities. Additionally, all communication between the client and server systems is encrypted.
A host key authenticates hosts in the SSH protocol. Host keys are cryptographic keys that are generated automatically when OpenSSH is started for the first time or when the host boots for the first time.
OpenSSH is an implementation of the SSH protocol supported by Linux, UNIX, and similar operating systems. It includes the core files necessary for both the OpenSSH client and server. The OpenSSH suite consists of the following user-space tools:
-
ssh
is a remote login program (SSH client). -
sshd
is an OpenSSH SSH daemon. -
scp
is a secure remote file copy program. -
sftp
is a secure file transfer program. -
ssh-agent
is an authentication agent for caching private keys. -
ssh-add
adds private key identities tossh-agent
. -
ssh-keygen
generates, manages, and converts authentication keys forssh
. -
ssh-copy-id
is a script that adds local public keys to theauthorized_keys
file on a remote SSH server. -
ssh-keyscan
gathers SSH public host keys.
In RHEL 9 and later, the Secure copy protocol (SCP) is replaced with the SSH File Transfer Protocol (SFTP) by default. This is because SCP has already caused security issues, for example CVE-2020-15778.
If SFTP is unavailable or incompatible in your scenario, you can use the scp
command with the -O
option to force the use of the original SCP/RCP protocol.
For additional information, see the OpenSSH SCP protocol deprecation in Red Hat Enterprise Linux 9 article.
The OpenSSH suite in RHEL supports only SSH version 2. It has an enhanced key-exchange algorithm that is not vulnerable to exploits known in the older version 1.
Red Hat Enterprise Linux includes the following OpenSSH
packages: the general openssh
package, the openssh-server
package, and the openssh-clients
package. The OpenSSH
packages require the OpenSSL
package openssl-libs
, which installs several important cryptographic libraries that enable OpenSSH
to provide encrypted communications.
OpenSSH, as one of core cryptographic subsystems of RHEL, uses system-wide crypto policies. This ensures that weak cipher suites and cryptographic algorithms are disabled in the default configuration. To modify the policy, the administrator must either use the update-crypto-policies
command to adjust the settings or manually opt out of the system-wide crypto policies. See the Excluding an application from following system-wide crypto policies section for more information.
The OpenSSH suite uses two sets of configuration files: one for client programs (that is, ssh
, scp
, and sftp
), and another for the server (the sshd
daemon).
System-wide SSH configuration information is stored in the /etc/ssh/
directory. The /etc/ssh/ssh_config
file contains the client configuration, and the /etc/ssh/sshd_config
file is the default OpenSSH server configuration file.
User-specific SSH configuration information is stored in ~/.ssh/
in the user’s home directory. For a detailed list of OpenSSH configuration files, see the FILES
section in the sshd(8)
man page on your system.
1.2. Generating SSH key pairs Copy linkLink copied to clipboard!
You can log in to an OpenSSH server without entering a password by generating an SSH key pair on a local system and copying the generated public key to the OpenSSH server. Each user who wants to create a key must run this procedure.
To preserve previously generated key pairs after you reinstall the system, back up the ~/.ssh/
directory before you create new keys. After reinstalling, copy it back to your home directory. You can do this for all users on your system, including root
.
Prerequisites
- You are logged in as a user who wants to connect to the OpenSSH server by using keys.
- The OpenSSH server is configured to allow key-based authentication.
Procedure
Generate an ECDSA key pair:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You can also generate an RSA key pair by using the
ssh-keygen
command without any parameter or an Ed25519 key pair by entering thessh-keygen -t ed25519
command. Note that the Ed25519 algorithm is not FIPS-140-compliant, and OpenSSH does not work with Ed25519 keys in FIPS mode.Copy the public key to a remote machine:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Replace
<username>@<ssh-server-example.com>
with your credentials.If you do not use the
ssh-agent
program in your session, the previous command copies the most recently modified~/.ssh/id*.pub
public key if it is not yet installed. To specify another public-key file or to prioritize keys in files over keys cached in memory byssh-agent
, use thessh-copy-id
command with the-i
option.
Verification
Log in to the OpenSSH server by using the key file:
ssh -o PreferredAuthentications=publickey <username>@<ssh-server-example.com>
$ ssh -o PreferredAuthentications=publickey <username>@<ssh-server-example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.3. Setting key-based authentication as the only method on an OpenSSH server Copy linkLink copied to clipboard!
To improve system security, enforce key-based authentication by disabling password authentication on your OpenSSH server.
Prerequisites
-
The
openssh-server
package is installed. -
The
sshd
daemon is running on the server. You can already connect to the OpenSSH server by using a key.
See the Generating SSH key pairs section for details.
Procedure
Open the
/etc/ssh/sshd_config
configuration in a text editor, for example:vi /etc/ssh/sshd_config
# vi /etc/ssh/sshd_config
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Change the
PasswordAuthentication
option tono
:PasswordAuthentication no
PasswordAuthentication no
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
On a system other than a new default installation, check that the
PubkeyAuthentication
parameter is either not set or set toyes
. Set the
KbdInteractiveAuthentication
directive tono
.Note that the corresponding entry is commented out in the configuration file and the default value is
yes
.To use key-based authentication with NFS-mounted home directories, enable the
use_nfs_home_dirs
SELinux boolean:setsebool -P use_nfs_home_dirs 1
# setsebool -P use_nfs_home_dirs 1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - If you are connected remotely, not using console or out-of-band access, test the key-based login process before disabling password authentication.
Reload the
sshd
daemon to apply the changes:systemctl reload sshd
# systemctl reload sshd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.4. Authenticating by SSH keys stored on a smart card Copy linkLink copied to clipboard!
You can create and store ECDSA and RSA keys on a smart card and authenticate by the smart card on an OpenSSH client. Smart-card authentication replaces the default password authentication.
Prerequisites
-
On the client side, the
opensc
package is installed and thepcscd
service is running.
Procedure
List all keys provided by the OpenSC PKCS #11 module including their PKCS #11 URIs and save the output to the
keys.pub
file:ssh-keygen -D pkcs11: > keys.pub
$ ssh-keygen -D pkcs11: > keys.pub
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Transfer the public key to the remote server. Use the
ssh-copy-id
command with thekeys.pub
file created in the previous step:ssh-copy-id -f -i keys.pub <username@ssh-server-example.com>
$ ssh-copy-id -f -i keys.pub <username@ssh-server-example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Connect to
<ssh-server-example.com>
by using the ECDSA key. You can use just a subset of the URI, which uniquely references your key, for example:ssh -i "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" <ssh-server-example.com>
$ ssh -i "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Because OpenSSH uses the
p11-kit-proxy
wrapper and the OpenSC PKCS #11 module is registered to thep11-kit
tool, you can simplify the previous command:ssh -i "pkcs11:id=%01" <ssh-server-example.com>
$ ssh -i "pkcs11:id=%01" <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you skip the
id=
part of a PKCS #11 URI, OpenSSH loads all keys that are available in the proxy module. This can reduce the amount of typing required:ssh -i pkcs11: <ssh-server-example.com>
$ ssh -i pkcs11: <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: You can use the same URI string in the
~/.ssh/config
file to make the configuration permanent:cat ~/.ssh/config IdentityFile "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" ssh <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
$ cat ~/.ssh/config IdentityFile "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" $ ssh <ssh-server-example.com> Enter PIN for 'SSH key': [ssh-server-example.com] $
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
ssh
client utility now automatically uses this URI and the key from the smart card.
1.5. Making OpenSSH more secure Copy linkLink copied to clipboard!
You can tweak the system to increase security when using OpenSSH.
Note that changes in the /etc/ssh/sshd_config
OpenSSH server configuration file require reloading the sshd
daemon to take effect:
systemctl reload sshd
# systemctl reload sshd
The majority of security hardening configuration changes reduce compatibility with clients that do not support up-to-date algorithms or cipher suites.
- Disabling insecure connection protocols
- To make SSH truly effective, prevent the use of insecure connection protocols that are replaced by the OpenSSH suite. Otherwise, a user’s password might be protected using SSH for one session only to be captured later when logging in using Telnet.
- Disabling password-based authentication
- Disabling passwords for authentication and allowing only key pairs reduces the attack surface. See the Setting key-based authentication as the only method on an OpenSSH server section for more information.
- Stronger key types
Although the
ssh-keygen
command generates a pair of RSA keys by default, you can instruct it to generate Elliptic Curve Digital Signature Algorithm (ECDSA) or Edwards-Curve 25519 (Ed25519) keys by using the-t
option. The ECDSA offers better performance than RSA at the equivalent symmetric key strength. It also generates shorter keys. The Ed25519 public-key algorithm is an implementation of twisted Edwards curves that is more secure and also faster than RSA, DSA, and ECDSA.OpenSSH creates RSA, ECDSA, and Ed25519 server host keys automatically if they are missing. To configure the host key creation in RHEL, use the
sshd-keygen@.service
instantiated service. For example, to disable the automatic creation of the RSA key type:systemctl mask sshd-keygen@rsa.service rm -f /etc/ssh/ssh_host_rsa_key* systemctl restart sshd
# systemctl mask sshd-keygen@rsa.service # rm -f /etc/ssh/ssh_host_rsa_key* # systemctl restart sshd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteIn images with the
cloud-init
method enabled, thessh-keygen
units are automatically disabled. This is because thessh-keygen template
service can interfere with thecloud-init
tool and cause problems with host key generation. To prevent these problems theetc/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf
drop-in configuration file disables thessh-keygen
units ifcloud-init
is running.To allow only a particular key type for SSH connections, remove a comment out at the beginning of the relevant line in
/etc/ssh/sshd_config
, and reload thesshd
service. For example, to allow only Ed25519 host keys, the corresponding lines must be as follows:HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_ecdsa_key
# HostKey /etc/ssh/ssh_host_rsa_key # HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantThe Ed25519 algorithm is not FIPS-140-compliant, and OpenSSH does not work with Ed25519 keys in FIPS mode.
- Non-default port
By default, the
sshd
daemon listens on TCP port 22. Changing the port reduces the exposure of the system to attacks based on automated network scanning on the default port and therefore increases security through obscurity. You can specify the port using thePort
directive in the/etc/ssh/sshd_config
configuration file.You also have to update the default SELinux policy to allow the use of a non-default port. To do so, use the
semanage
tool from thepolicycoreutils-python-utils
package:semanage port -a -t ssh_port_t -p tcp <port_number>
# semanage port -a -t ssh_port_t -p tcp <port_number>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Furthermore, update
firewalld
configuration:firewall-cmd --add-port <port_number>/tcp firewall-cmd --remove-port=22/tcp firewall-cmd --runtime-to-permanent
# firewall-cmd --add-port <port_number>/tcp # firewall-cmd --remove-port=22/tcp # firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow In the previous commands, replace
<port_number>
with the new port number specified using thePort
directive.- Root login
PermitRootLogin
is set toprohibit-password
by default. This enforces the use of key-based authentication instead of the use of passwords for logging in as root and reduces risks by preventing brute-force attacks.WarningEnabling logging in as the root user is not a secure practice because the administrator cannot audit which users run which privileged commands. For using administrative commands, log in and use
sudo
instead.- Using the X Security extension
The X server in Red Hat Enterprise Linux clients does not provide the X Security extension. Therefore, clients cannot request another security layer when connecting to untrusted SSH servers with X11 forwarding. Most applications are not able to run with this extension enabled anyway.
By default, the
ForwardX11Trusted
option in the/etc/ssh/ssh_config.d/50-redhat.conf
file is set toyes
, and there is no difference between thessh -X remote_machine
(untrusted host) andssh -Y remote_machine
(trusted host) command.If your scenario does not require the X11 forwarding feature at all, set the
X11Forwarding
directive in the/etc/ssh/sshd_config
configuration file tono
.- Restricting SSH access to specific users, groups, or IP ranges
The
AllowUsers
andAllowGroups
directives in the/etc/ssh/sshd_config
configuration file server enable you to permit only certain users, domains, or groups to connect to your OpenSSH server. You can combineAllowUsers
andAllowGroups
to restrict access more precisely, for example:AllowUsers *@192.168.1.* *@10.0.0.* !*@192.168.1.2 AllowGroups example-group
AllowUsers *@192.168.1.* *@10.0.0.* !*@192.168.1.2 AllowGroups example-group
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This configuration allows only connections if all of the following conditions meet:
- The connection’s source IP is within the 192.168.1.0/24 or 10.0.0.0/24 subnet.
- The source IP is not 192.168.1.2.
- The user is a member of the example-group group.
The OpenSSH server permits only connections that pass all Allow and Deny directives in
/etc/ssh/sshd_config
. For example, if theAllowUsers
directive lists a user that is not part of a group listed in theAllowGroups
directive, then the user cannot log in.Note that using allowlists (directives starting with Allow) is more secure than using blocklists (options starting with Deny) because allowlists block also new unauthorized users or groups.
- Changing system-wide cryptographic policies
OpenSSH uses RHEL system-wide cryptographic policies, and the default system-wide cryptographic policy level offers secure settings for current threat models. To make your cryptographic settings more strict, change the current policy level:
update-crypto-policies --set FUTURE
# update-crypto-policies --set FUTURE Setting system policy to FUTURE
Copy to Clipboard Copied! Toggle word wrap Toggle overflow WarningIf your system communicates with legacy systems, you might face interoperability problems due to the strict setting of the
FUTURE
policy.
You can also disable only specific ciphers for the SSH protocol through the system-wide cryptographic policies. See the Customizing system-wide cryptographic policies with subpolicies section in the Security hardening document for more information.
- Opting out of system-wide cryptographic policies
To opt out of the system-wide cryptographic policies for your OpenSSH server, specify the cryptographic policy in a drop-in configuration file located in the
/etc/ssh/sshd_config.d/
directory, with a two-digit number prefix smaller than 50, so that it lexicographically precedes the50-redhat.conf
file, and with a.conf
suffix, for example,49-crypto-policy-override.conf
.See the
sshd_config(5)
man page for more information.To opt out of system-wide cryptographic policies for your OpenSSH client, perform one of the following tasks:
-
For a given user, override the global
ssh_config
with a user-specific configuration in the~/.ssh/config
file. -
For the entire system, specify the cryptographic policy in a drop-in configuration file located in the
/etc/ssh/ssh_config.d/
directory, with a two-digit number prefix smaller than 50, so that it lexicographically precedes the50-redhat.conf
file, and with a.conf
suffix, for example,49-crypto-policy-override.conf
.
-
For a given user, override the global
1.6. Connecting to a remote server through an SSH jump host Copy linkLink copied to clipboard!
You can connect from your local system to a remote server through an intermediary server, also called jump host. A jump server bridges hosts from different security zones and can manage multiple client-server connections.
Prerequisites
- A jump host accepts SSH connections from your local system.
- A remote server accepts SSH connections from the jump host.
Procedure
If you connect through a jump server or more intermediary servers once, use the
ssh -J
command and specify the jump servers directly, for example:ssh -J <jump-1.example.com>,<jump-2.example.com>,<jump-3.example.com> <target-server-1.example.com>
$ ssh -J <jump-1.example.com>,<jump-2.example.com>,<jump-3.example.com> <target-server-1.example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Change the host name-only notation in the previous command if the user names or SSH ports on the jump servers differ from the names and ports on the remote server, for example:
ssh -J <example.user.1>@<jump-1.example.com>:<75>,<example.user.2>@<jump-2.example.com>:<75>,<example.user.3>@<jump-3.example.com>:<75> <example.user.f>@<target-server-1.example.com>:<220>
$ ssh -J <example.user.1>@<jump-1.example.com>:<75>,<example.user.2>@<jump-2.example.com>:<75>,<example.user.3>@<jump-3.example.com>:<75> <example.user.f>@<target-server-1.example.com>:<220>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you connect to a remote server through jump servers regularly, store the jump-server configuration in your SSH configuration file:
Define the jump host by editing the
~/.ssh/config
file on your local system, for example:Host <jump-server-1> HostName <jump-1.example.com>
Host <jump-server-1> HostName <jump-1.example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
Host
parameter defines a name or alias for the host you can use inssh
commands. The value can match the real host name, but can also be any string. -
The
HostName
parameter sets the actual host name or IP address of the jump host.
-
The
Add the remote server jump configuration with the
ProxyJump
directive to~/.ssh/config
file on your local system, for example:Host <remote-server-1> HostName <target-server-1.example.com> ProxyJump <jump-server-1>
Host <remote-server-1> HostName <target-server-1.example.com> ProxyJump <jump-server-1>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use your local system to connect to the remote server through the jump server:
ssh <remote-server-1>
$ ssh <remote-server-1>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This command is equivalent to the
ssh -J jump-server1 remote-server
command if you omit the previous configuration steps.
1.7. Configuring the OpenSSH server and client by using RHEL system roles Copy linkLink copied to clipboard!
You can use the sshd
RHEL system role to configure OpenSSH servers and the ssh
RHEL system role to configure OpenSSH clients consistently, in an automated fashion, and on any number of RHEL systems at the same time. Such configurations are necessary for any system where secure remote interaction is needed, for example:
- Remote system administration: securely connecting to your machine from another computer by using an SSH client.
- Secure file transfers: the Secure File Transfer Protocol (SFTP) provided by OpenSSH enable you to securely transfer files between your local machine and a remote system.
- Automated DevOps pipelines: automating software deployments that require secure connection to remote servers (CI/CD pipelines).
- Tunneling and port forwarding: forwarding a local port to access a web service on a remote server behind a firewall. For example a remote database or a development server.
- Key-based authentication: more secure alternative to password-based logins.
- Certificate-based authentication: centralized trust management and better scalability.
- Enhanced security: disabling root logins, restricting user access, enforcing strong encryption and other such forms of hardening ensures stronger system security.
1.7.1. How the sshd RHEL system role maps settings from a playbook to the configuration file Copy linkLink copied to clipboard!
In the sshd
RHEL system role playbook, you can define the parameters for the server SSH configuration file.
If you do not specify these settings, the role produces the sshd_config
file that matches the RHEL defaults.
In all cases, booleans correctly render as yes
and no
in the final configuration on your managed nodes. You can use lists to define multi-line configuration items. For example:
sshd_ListenAddress: - 0.0.0.0 - '::'
sshd_ListenAddress:
- 0.0.0.0
- '::'
renders as:
ListenAddress 0.0.0.0 ListenAddress ::
ListenAddress 0.0.0.0
ListenAddress ::
1.7.2. Configuring OpenSSH servers by using the sshd RHEL system role Copy linkLink copied to clipboard!
You can use the sshd
RHEL system role to configure multiple OpenSSH servers. These ensure secure communication environment for remote users by providing namely:
- Management of incoming SSH connections from remote clients
- Credentials verification
- Secure data transfer and command execution
You can use the sshd
RHEL system role alongside with other RHEL system roles that change SSHD configuration, for example the Identity Management RHEL system roles. To prevent the configuration from being overwritten, ensure the sshd
RHEL system role uses namespaces (RHEL 8 and earlier versions) or a drop-in directory (RHEL 9 and later).
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:
PasswordAuthentication: yes|no
-
Controls whether the OpenSSH server (
sshd
) accepts authentication from clients that use the username and password combination. Match:
-
The match block allows the
root
user login by using password only from the subnet192.0.2.0/24
.
For details about the role variables and the OpenSSH configuration options used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.sshd/README.md
file and thesshd_config(5)
manual page 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
Log in to the SSH server:
ssh <username>@<ssh_server>
$ ssh <username>@<ssh_server>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify the contents of the
sshd_config
file on the SSH server:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Check that you can connect to the server as root from the
192.0.2.0/24
subnet:Determine your IP address:
hostname -I
$ hostname -I 192.0.2.1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the IP address is within the
192.0.2.1
-192.0.2.254
range, you can connect to the server.Connect to the server as
root
:ssh root@<ssh_server>
$ ssh root@<ssh_server>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.3. Using the sshd RHEL system role for non-exclusive configuration Copy linkLink copied to clipboard!
By default, applying the sshd
RHEL system role overwrites the entire configuration. This may be problematic if you have previously adjusted the configuration, for example, with a different RHEL system role or a playbook. To apply the sshd
RHEL system role for only selected configuration options while keeping other options in place, you can use the non-exclusive configuration.
You can apply a non-exclusive configuration:
- In RHEL 8 and earlier by using a configuration snippet.
-
In RHEL 9 and later by using files in a drop-in directory. The default configuration file is already placed in the drop-in directory as
/etc/ssh/sshd_config.d/00-ansible_system_role.conf
.
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:For managed nodes that run RHEL 8 or earlier:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For managed nodes that run RHEL 9 or later:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example playbooks include the following:
sshd_config_namespace: <my_application>
- The role places the configuration that you specify in the playbook to configuration snippets in the existing configuration file under the given namespace. You need to select a different namespace when running the role from different context.
sshd_config_file: /etc/ssh/sshd_config.d/<42-my_application>.conf
-
In the
sshd_config_file
variable, define the.conf
file into which thesshd
system role writes the configuration options. Use a two-digit prefix, for example42-
to specify the order in which the configuration files will be applied. AcceptEnv:
Controls which environment variables the OpenSSH server (
sshd
) will accept from a client:-
LANG
: defines the language and locale settings. -
LS_COLORS
: defines the displaying color scheme for thels
command in the terminal. -
EDITOR
: specifies the default text editor for the command-line programs that need to open an editor.
-
For details about the role variables and the OpenSSH configuration options used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.sshd/README.md
file and thesshd_config(5)
manual page 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
Verify the configuration on the SSH server:
For managed nodes that run RHEL 8 or earlier:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For managed nodes that run RHEL 9 or later:
cat /etc/ssh/sshd_config.d/42-my_application.conf Ansible managed # AcceptEnv LANG LS_COLORS EDITOR
# cat /etc/ssh/sshd_config.d/42-my_application.conf # Ansible managed # AcceptEnv LANG LS_COLORS EDITOR
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.4. Overriding the system-wide cryptographic policy on an SSH server by using the sshd RHEL system role Copy linkLink copied to clipboard!
When the default cryptographic settings do not meet certain security or compatibility needs, you may want to override the system-wide cryptographic policy on the OpenSSH server by using the sshd
RHEL system role. Especially, in the following notable situations:
- Compatibility with older clients: necessity to use weaker-than-default encryption algorithms, key exchange protocols, or ciphers.
- Enforcing stronger security policies: simultaneously, you can disable weaker algorithms. Such a measure could exceed the default system cryptographic policies, especially in the highly secure and regulated environments.
- Performance considerations: the system defaults could enforce stronger algorithms that can be computationally intensive for some systems.
- Customizing for specific security needs: adapting for unique requirements that are not covered by the default cryptographic policies.
It is not possible to override all aspects of the cryptographic policies from the sshd
RHEL system role. For example, SHA-1 signatures might be forbidden on a different layer so for a more generic solution, see Setting a custom cryptographic policy by using RHEL system roles.
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:
sshd_KexAlgorithms
-
You can choose key exchange algorithms, for example,
ecdh-sha2-nistp256
,ecdh-sha2-nistp384
,ecdh-sha2-nistp521
,diffie-hellman-group14-sha1
, ordiffie-hellman-group-exchange-sha256
. sshd_Ciphers
-
You can choose ciphers, for example,
aes128-ctr
,aes192-ctr
, oraes256-ctr
. sshd_MACs
-
You can choose MACs, for example,
hmac-sha2-256
,hmac-sha2-512
, orhmac-sha1
. sshd_HostKeyAlgorithms
-
You can choose a public key algorithm, for example,
ecdsa-sha2-nistp256
,ecdsa-sha2-nistp384
,ecdsa-sha2-nistp521
, orssh-rsa
.
For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.sshd/README.md
file on the control node.NoteOn RHEL 9 managed nodes, the system role writes the configuration into the
/etc/ssh/sshd_config.d/00-ansible_system_role.conf
file, where cryptographic options are applied automatically. You can change the file by using thesshd_config_file
variable. However, to ensure the configuration is effective, use a file name that lexicographically precedes the/etc/ssh/sshd_config.d/50-redhat.conf
file, which includes the configured crypto policies.On RHEL 8 managed nodes, you must enable override by setting the
sshd_sysconfig_override_crypto_policy
andsshd_sysconfig
variables totrue
.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
You can verify the success of the procedure by using the verbose SSH connection and check the defined variables in the following output:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.5. How the ssh RHEL system role maps settings from a playbook to the configuration file Copy linkLink copied to clipboard!
In the ssh
RHEL system role playbook, you can define the parameters for the client SSH configuration file.
If you do not specify these settings, the role produces a global ssh_config
file that matches the RHEL defaults.
In all the cases, booleans correctly render as yes
or no
in the final configuration on your managed nodes. You can use lists to define multi-line configuration items. For example:
LocalForward: - 22 localhost:2222 - 403 localhost:4003
LocalForward:
- 22 localhost:2222
- 403 localhost:4003
renders as:
LocalForward 22 localhost:2222 LocalForward 403 localhost:4003
LocalForward 22 localhost:2222
LocalForward 403 localhost:4003
The configuration options are case sensitive.
1.7.6. Configuring OpenSSH clients by using the ssh RHEL system role Copy linkLink copied to clipboard!
You can use the ssh
RHEL system role to configure multiple OpenSSH clients. These enable the local user to establish a secure connection with the remote OpenSSH server by ensuring namely:
- Secure connection initiation
- Credentials provision
- Negotiation with the OpenSSH server on the encryption method used for the secure communication channel
- Ability to send files securely to and from the OpenSSH server
You can use the ssh
RHEL system role alongside with other system roles that change SSH configuration, for example the Identity Management RHEL system roles. To prevent the configuration from being overwritten, make sure that the ssh
RHEL system role uses a drop-in directory (default in RHEL 8 and later).
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:
ssh_user: root
-
Configures the
root
user’s SSH client preferences on the managed nodes with certain configuration specifics. Compression: true
- Compression is enabled.
ControlMaster: auto
-
ControlMaster multiplexing is set to
auto
. Host
-
Creates alias
example
for connecting to theserver.example.com
host as a user calleduser1
. ssh_ForwardX11: no
- X11 forwarding is disabled.
For details about the role variables and the OpenSSH configuration options used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.ssh/README.md
file and thessh_config(5)
manual page 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
Verify that the managed node has the correct configuration by displaying the SSH configuration file:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 2. Creating and managing TLS keys and certificates Copy linkLink copied to clipboard!
You can encrypt communication transmitted between two systems by using the TLS (Transport Layer Security) protocol. This standard uses asymmetric cryptography with private and public keys, digital signatures, and certificates.
2.1. TLS certificates Copy linkLink copied to clipboard!
TLS (Transport Layer Security) is a protocol that enables client-server applications to pass information securely. TLS uses a system of public and private key pairs to encrypt communication transmitted between clients and servers. TLS is the successor protocol to SSL (Secure Sockets Layer).
TLS uses X.509 certificates to bind identities, such as hostnames or organizations, to public keys using digital signatures. X.509 is a standard that defines the format of public key certificates.
Authentication of a secure application depends on the integrity of the public key value in the application’s certificate. If an attacker replaces the public key with its own public key, it can impersonate the true application and gain access to secure data. To prevent this type of attack, all certificates must be signed by a certification authority (CA). A CA is a trusted node that confirms the integrity of the public key value in a certificate.
A CA signs a public key by adding its digital signature and issues a certificate. A digital signature is a message encoded with the CA’s private key. The CA’s public key is made available to applications by distributing the certificate of the CA. Applications verify that certificates are validly signed by decoding the CA’s digital signature with the CA’s public key.
To have a certificate signed by a CA, you must generate a public key, and send it to a CA for signing. This is referred to as a certificate signing request (CSR). A CSR contains also a distinguished name (DN) for the certificate. The DN information that you can provide for either type of certificate can include a two-letter country code for your country, a full name of your state or province, your city or town, a name of your organization, your email address, and it can also be empty. Many current commercial CAs prefer the Subject Alternative Name extension and ignore DNs in CSRs.
RHEL provides two main toolkits for working with TLS certificates: GnuTLS and OpenSSL. You can create, read, sign, and verify certificates using the openssl
utility from the openssl
package. The certtool
utility provided by the gnutls-utils
package can do the same operations using a different syntax and above all a different set of libraries in the back end.
2.2. Creating a private CA by using OpenSSL Copy linkLink copied to clipboard!
Private certificate authorities (CA) are useful when your scenario requires verifying entities within your internal network. For example, use a private CA when you create a VPN gateway with authentication based on certificates signed by a CA under your control or when you do not want to pay a commercial CA. To sign certificates in such use cases, the private CA uses a self-signed certificate.
Prerequisites
-
You have
root
privileges or permissions to enter administrative commands withsudo
. Commands that require such privileges are marked with#
.
Procedure
Generate a private key for your CA. For example, the following command creates a 256-bit Elliptic Curve Digital Signature Algorithm (ECDSA) key:
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <ca.key>
$ openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <ca.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The time for the key-generation process depends on the hardware and entropy of the host, the selected algorithm, and the length of the key.
Create a certificate signed using the private key generated in the previous command:
openssl req -key <ca.key> -new -x509 -days 3650 -addext keyUsage=critical,keyCertSign,cRLSign -subj "/CN=<example_CA>" -out <ca.crt>
$ openssl req -key <ca.key> -new -x509 -days 3650 -addext keyUsage=critical,keyCertSign,cRLSign -subj "/CN=<example_CA>" -out <ca.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The generated
ca.crt
file is a self-signed CA certificate that you can use to sign other certificates for ten years. In the case of a private CA, you can replace<example_CA>
with any string as the common name (CN).Set secure permissions on the private key of your CA, for example:
chown <root>:<root> <ca.key> chmod 600 <ca.key>
# chown <root>:<root> <ca.key> # chmod 600 <ca.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps
To use a self-signed CA certificate as a trust anchor on client systems, copy the CA certificate to the client and add it to the clients' system-wide truststore as
root
:trust anchor <ca.crt>
# trust anchor <ca.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow See the Using shared system certificates chapter for more information.
Verification
Create a certificate signing request (CSR), and use your CA to sign the request. The CA must successfully create a certificate based on the CSR, for example:
openssl x509 -req -in <client-cert.csr> -CA <ca.crt> -CAkey <ca.key> -CAcreateserial -days 365 -extfile <openssl.cnf> -extensions <client-cert> -out <client-cert.crt>
$ openssl x509 -req -in <client-cert.csr> -CA <ca.crt> -CAkey <ca.key> -CAcreateserial -days 365 -extfile <openssl.cnf> -extensions <client-cert> -out <client-cert.crt> Signature ok subject=C = US, O = Example Organization, CN = server.example.com Getting CA Private Key
Copy to Clipboard Copied! Toggle word wrap Toggle overflow See Section 2.5, “Using a private CA to issue certificates for CSRs with OpenSSL” for more information.
Display the basic information about your self-signed CA:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify the consistency of the private key:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.3. Creating a private key and a CSR for a TLS server certificate by using OpenSSL Copy linkLink copied to clipboard!
You can use TLS-encrypted communication channels only if you have a valid TLS certificate from a certificate authority (CA). To obtain the certificate, you must create a private key and a certificate signing request (CSR) for your server first.
Procedure
Generate a private key on your server system, for example:
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <server_private.key>
$ openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <server_private.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Use a text editor of your choice to prepare a configuration file that simplifies creating your CSR, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
extendedKeyUsage = serverAuth
option limits the use of a certificate.Create a CSR using the private key you created previously:
openssl req -key <server_private.key> -config <example_server.cnf> -new -out <server_cert.csr>
$ openssl req -key <server_private.key> -config <example_server.cnf> -new -out <server_cert.csr>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you omit the
-config
option, thereq
utility prompts you for additional information, for example:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps
- Submit the CSR to a CA of your choice for signing. Alternatively, for an internal use scenario within a trusted network, use your private CA for signing. See Using a private CA to issue certificates for CSRs with OpenSSL for more information.
Verification
After you obtain the requested certificate from the CA, check that the human-readable parts of the certificate match your requirements, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.4. Creating a private key and a CSR for a TLS client certificate by using OpenSSL Copy linkLink copied to clipboard!
You can use TLS-encrypted communication channels only if you have a valid TLS certificate from a certificate authority (CA). To obtain the certificate, you must create a private key and a certificate signing request (CSR) for your client first.
Procedure
Generate a private key on your client system, for example:
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <client-private.key>
$ openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out <client-private.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Use a text editor of your choice to prepare a configuration file that simplifies creating your CSR, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
extendedKeyUsage = clientAuth
option limits the use of a certificate.Create a CSR using the private key you created previously:
openssl req -key <client-private.key> -config <example_client.cnf> -new -out <client-cert.csr>
$ openssl req -key <client-private.key> -config <example_client.cnf> -new -out <client-cert.csr>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you omit the
-config
option, thereq
utility prompts you for additional information, for example:You are about to be asked to enter information that will be incorporated into your certificate request. … Common Name (eg, your name or your server's hostname) []: <client.example.com> Email Address []: <client@example.com>
You are about to be asked to enter information that will be incorporated into your certificate request. … Common Name (eg, your name or your server's hostname) []: <client.example.com> Email Address []: <client@example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps
- Submit the CSR to a CA of your choice for signing. Alternatively, for an internal use scenario within a trusted network, use your private CA for signing. See the Using a private CA to issue certificates for CSRs with OpenSSL section for more information.
Verification
Check that the human-readable parts of the certificate match your requirements, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.5. Using a private CA to issue certificates for CSRs with OpenSSL Copy linkLink copied to clipboard!
To enable systems to establish a TLS-encrypted communication channel, a certificate authority (CA) must provide valid certificates to them. If you have a private CA, you can create the requested certificates by signing certificate signing requests (CSRs) from the systems.
Prerequisites
- You have already configured a private CA. See the Creating a private CA by using OpenSSL section for more information.
- You have a file containing a CSR. You can find an example of creating the CSR in the Section 2.3, “Creating a private key and a CSR for a TLS server certificate by using OpenSSL” section.
Procedure
Optional: Use a text editor of your choice to prepare an OpenSSL configuration file for adding extensions to certificates, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Note that the previous example illustrates only the principle and
openssl
does not add all extensions to the certificate automatically. You must add the extensions you require either to the CNF file or append them to parameters of theopenssl
command.Use the
x509
utility to create a certificate based on a CSR, for example:openssl x509 -req -in <server_cert.csr> -CA <ca.crt> -CAkey <ca.key> -days 365 -extfile <openssl.cnf> -extensions <server_cert> -out <server_cert.crt>
$ openssl x509 -req -in <server_cert.csr> -CA <ca.crt> -CAkey <ca.key> -days 365 -extfile <openssl.cnf> -extensions <server_cert> -out <server_cert.crt> Signature ok subject=C = US, O = Example Organization, CN = server.example.com Getting CA Private Key
Copy to Clipboard Copied! Toggle word wrap Toggle overflow To increase security, delete the serial-number file before you create another certificate from a CSR. This way, you ensure that the serial number is always random. If you omit the
CAserial
option for specifying a custom file name, the serial-number file name is the same as the file name of the certificate, but its extension is replaced with the.srl
extension (server-cert.srl
in the previous example).
2.6. Post-quantum cryptography algorithms in OpenSSL Copy linkLink copied to clipboard!
After you enable post-quantum algorithms system-wide, you can use the OpenSSL TLS toolkit for generating keys, signing messages, verifying signatures, and creating X.509 certificates with the ML-DSA post-quantum algorithms.
Example usage of ML-DSA for keys in OpenSSL
$ openssl genpkey -algorithm mldsa65 -out <mldsa-privatekey.pem>
- Create a private key with the ML-DSA-65 algorithm.
$ openssl pkey -in <mldsa-privatekey.pem> -pubout -out <mldsa-publickey.pem>
- Create a public key based on the ML-DSA-65-encrypted private key.
$ openssl dgst -sign <mldsa-privatekey.pem> -out <signature_message>
- Sign a message with the private key.
$ openssl dgst -verify <mldsa-publickey.pem> -signature <signature_message>
- Verify the ML-DSA-65 signature with the public key.
Example usage of ML-DSA for certificates in OpenSSL
Because no public certificate authorities (CA) currently support post-quantum signatures, you can use only a local CA or self-signed certificates with ML-DSA signatures. For example:
With a set of certificates and the system configured to the DEFAULT:TEST-PQ
system-wide cryptographic policy, an OpenSSL server and client can establish a post-quantum connection and a connection that uses only traditional algorithms.
Establish a connection with PQC key exchange and PQC certificates, for example:
Establish a connection that uses only non-post-quantum cryptographic algorithms, for example:
You can configure a server to simultaneously use traditional certificates (RSA, ECDSA, and EdDSA) and post-quantum certificates. The server automatically and transparently selects the certificates preferred and supported by clients: the post-quantum for new clients and traditional for legacy ones.
All PQC algorithms in Red Hat Enterprise Linux 10 are provided as a Technology Preview feature. The package and system-wide cryptographic policy name are subject to change when post-quantum cryptography exits the Technology Preview state.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
2.7. Creating a private CA by using GnuTLS Copy linkLink copied to clipboard!
Private certificate authorities (CA) are useful when your scenario requires verifying entities within your internal network. For example, use a private CA when you create a VPN gateway with authentication based on certificates signed by a CA under your control or when you do not want to pay a commercial CA. To sign certificates in such use cases, the private CA uses a self-signed certificate.
Prerequisites
-
You have
root
privileges or permissions to enter administrative commands withsudo
. Commands that require such privileges are marked with#
. You have already installed GnuTLS on your system. If you did not, you can use this command:
dnf install gnutls-utils
$ dnf install gnutls-utils
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Procedure
Generate a private key for your CA. For example, the following command creates a 256-bit ECDSA (Elliptic Curve Digital Signature Algorithm) key:
certtool --generate-privkey --sec-param High --key-type=ecdsa --outfile <ca.key>
$ certtool --generate-privkey --sec-param High --key-type=ecdsa --outfile <ca.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The time for the key-generation process depends on the hardware and entropy of the host, the selected algorithm, and the length of the key.
Create a template file for a certificate.
Create a file with a text editor of your choice, for example:
vi <ca.cfg>
$ vi <ca.cfg>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Edit the file to include the necessary certification details:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Create a certificate signed using the private key generated in step 1:
The generated <ca.crt> file is a self-signed CA certificate that you can use to sign other certificates for one year. <ca.crt> file is the public key (certificate). The loaded file <ca.key> is the private key. You should keep this file in safe location.
certtool --generate-self-signed --load-privkey <ca.key> --template <ca.cfg> --outfile <ca.crt>
$ certtool --generate-self-signed --load-privkey <ca.key> --template <ca.cfg> --outfile <ca.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set secure permissions on the private key of your CA, for example:
chown <root>:<root> <ca.key> chmod 600 <ca.key>
# chown <root>:<root> <ca.key> # chmod 600 <ca.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps
To use a self-signed CA certificate as a trust anchor on client systems, copy the CA certificate to the client and add it to the clients' system-wide truststore as
root
:trust anchor <ca.crt>
# trust anchor <ca.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow See the Using shared system certificates chapter for more information.
Verification
Display the basic information about your self-signed CA:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a certificate signing request (CSR), and use your CA to sign the request. The CA must successfully create a certificate based on the CSR, for example:
Generate a private key for your CA:
certtool --generate-privkey --outfile <example_server.key>
$ certtool --generate-privkey --outfile <example_server.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Open a new configuration file in a text editor of your choice, for example:
vi <example_server.cfg>
$ vi <example_server.cfg>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Edit the file to include the necessary certification details:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Generate a request with the previously created private key:
certtool --generate-request --load-privkey <example_server.key> --template <example_server.cfg> --outfile <example_server.crq>
$ certtool --generate-request --load-privkey <example_server.key> --template <example_server.cfg> --outfile <example_server.crq>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Generate the certificate and sign it with the private key of the CA:
certtool --generate-certificate --load-request <example_server.crq> --load-ca-certificate <ca.crt> --load-ca-privkey <ca.key> --outfile <example_server.crt>
$ certtool --generate-certificate --load-request <example_server.crq> --load-ca-certificate <ca.crt> --load-ca-privkey <ca.key> --outfile <example_server.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.8. Creating a private key and a CSR for a TLS server certificate by using GnuTLS Copy linkLink copied to clipboard!
To obtain the certificate, you must create a private key and a certificate signing request (CSR) for your server first.
Procedure
Generate a private key on your server system, for example:
certtool --generate-privkey --sec-param High --outfile <example_server.key>
$ certtool --generate-privkey --sec-param High --outfile <example_server.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Use a text editor of your choice to prepare a configuration file that simplifies creating your CSR, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a CSR by using the private key you created previously:
certtool --generate-request --template <example_server.cfg> --load-privkey <example_server.key> --outfile <example_server.crq>
$ certtool --generate-request --template <example_server.cfg> --load-privkey <example_server.key> --outfile <example_server.crq>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you omit the
--template
option, thecertool
utility prompts you for additional information, for example:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps
- Submit the CSR to a CA of your choice for signing. Alternatively, for an internal use scenario within a trusted network, use your private CA for signing. See the Using a private CA to issue certificates for CSRs with GnuTLS for more information.
Verification
After you obtain the requested certificate from the CA, check that the human-readable parts of the certificate match your requirements, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.9. Creating a private key and a CSR for a TLS client certificate by using GnuTLS Copy linkLink copied to clipboard!
To obtain the certificate, you must create a private key and a certificate signing request (CSR) for your client first.
Procedure
Generate a private key on your client system, for example:
certtool --generate-privkey --sec-param High --outfile <example_client.key>
$ certtool --generate-privkey --sec-param High --outfile <example_client.key>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Use a text editor of your choice to prepare a configuration file that simplifies creating your CSR, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a CSR using the private key you created previously:
certtool --generate-request --template <example_client.cfg> --load-privkey <example_client.key> --outfile <example_client.crq>
$ certtool --generate-request --template <example_client.cfg> --load-privkey <example_client.key> --outfile <example_client.crq>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you omit the
--template
option, thecerttool
utility prompts you for additional information, for example:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps
- Submit the CSR to a CA of your choice for signing. Alternatively, for an internal use scenario within a trusted network, use your private CA for signing. See Section 2.10, “Using a private CA to issue certificates for CSRs with GnuTLS” for more information.
Verification
Check that the human-readable parts of the certificate match your requirements, for example:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.10. Using a private CA to issue certificates for CSRs with GnuTLS Copy linkLink copied to clipboard!
To enable systems to establish a TLS-encrypted communication channel, a certificate authority (CA) must provide valid certificates to them. If you have a private CA, you can create the requested certificates by signing certificate signing requests (CSRs) from the systems.
Prerequisites
- You have already configured a private CA. See Section 2.7, “Creating a private CA by using GnuTLS” for more information.
- You have a file containing a CSR. You can find an example of creating the CSR in Section 2.8, “Creating a private key and a CSR for a TLS server certificate by using GnuTLS” .
Procedure
Optional: Use a text editor of your choice to prepare an GnuTLS configuration file for adding extensions to certificates, for example:
vi <server_extensions.cfg>
$ vi <server_extensions.cfg> honor_crq_extensions ocsp_uri = "http://ocsp.example.com"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use the
certtool
utility to create a certificate based on a CSR, for example:certtool --generate-certificate --load-request <example_server.crq> --load-ca-privkey <ca.key> --load-ca-certificate <ca.crt> --template <server_extensions.cfg> --outfile <example_server.crt>
$ certtool --generate-certificate --load-request <example_server.crq> --load-ca-privkey <ca.key> --load-ca-certificate <ca.crt> --template <server_extensions.cfg> --outfile <example_server.crt>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 4. Planning and implementing TLS Copy linkLink copied to clipboard!
TLS (Transport Layer Security) is a cryptographic protocol used to secure network communications. When hardening system security settings by configuring preferred key-exchange protocols, authentication methods, and encryption algorithms, it is necessary to bear in mind that the broader the range of supported clients, the lower the resulting security. Conversely, strict security settings lead to limited compatibility with clients, which can result in some users being locked out of the system. Be sure to target the strictest available configuration and only relax it when it is required for compatibility reasons.
4.1. SSL and TLS protocols Copy linkLink copied to clipboard!
The Secure Sockets Layer (SSL) protocol was originally developed by Netscape Corporation to provide a mechanism for secure communication over the Internet. Subsequently, the protocol was adopted by the Internet Engineering Task Force (IETF) and renamed to Transport Layer Security (TLS).
The TLS protocol sits between an application protocol layer and a reliable transport layer, such as TCP/IP. It is independent of the application protocol and can thus be layered underneath many different protocols, for example: HTTP, FTP, SMTP, and so on.
Protocol version | Usage recommendation |
---|---|
SSL v2 | Do not use. Has serious security vulnerabilities. Removed from the core crypto libraries since RHEL 7. |
SSL v3 | Do not use. Has serious security vulnerabilities. Removed from the core crypto libraries since RHEL 8. |
TLS 1.0 | Not recommended to use. Has known issues that cannot be mitigated in a way that guarantees interoperability, and does not support modern cipher suites. In RHEL 10, disabled in all cryptographic policies. |
TLS 1.1 | Use for interoperability purposes where needed. Does not support modern cipher suites. In RHEL 10, disabled in all cryptographic policies. |
TLS 1.2 | Supports the modern AEAD cipher suites. This version is enabled in all system-wide crypto policies, but optional parts of this protocol contain vulnerabilities and TLS 1.2 also allows outdated algorithms. |
TLS 1.3 | Recommended version. TLS 1.3 removes known problematic options, provides additional privacy by encrypting more of the negotiation handshake and can be faster thanks usage of more efficient modern cryptographic algorithms. TLS 1.3 is also enabled in all system-wide cryptographic policies. |
4.2. Security considerations for TLS in RHEL 10 Copy linkLink copied to clipboard!
In RHEL 10, TLS configuration is performed using the system-wide cryptographic policies mechanism. TLS versions below 1.2 are not supported anymore. DEFAULT
, FUTURE
, and LEGACY
cryptographic policies allow only TLS 1.2 and 1.3. See the Using system-wide cryptographic policies chapter in the Security hardening document for more information.
The default settings provided by libraries included in RHEL 10 are secure enough for most deployments. The TLS implementations use secure algorithms where possible while not preventing connections from or to legacy clients or servers. Apply hardened settings in environments with strict security requirements where legacy clients or servers that do not support secure algorithms or protocols are not expected or allowed to connect.
The most straightforward way to harden your TLS configuration is switching the system-wide cryptographic policy level to FUTURE
using the update-crypto-policies --set FUTURE
command.
Algorithms disabled for the LEGACY
cryptographic policy do not conform to Red Hat’s vision of RHEL 10 security, and their security properties are not reliable. Consider moving away from using these algorithms instead of re-enabling them. If you do decide to re-enable them, for example for interoperability with old hardware, treat them as insecure and apply extra protection measures, such as isolating their network interactions to separate network segments. Do not use them across public networks.
If you decide to not follow RHEL system-wide cryptographic policies or create custom cryptographic policies tailored to your setup, use the following recommendations for preferred protocols, cipher suites, and key lengths on your custom configuration:
4.2.1. Protocols Copy linkLink copied to clipboard!
The latest version of TLS provides the best security mechanism. TLS 1.2 is now the minimum version even when using the LEGACY
cryptographic policy. Re-enabling older protocol versions is possible through either opting out of cryptographic policies or providing a custom policy, but the resulting configuration will not be supported.
Note that even though that RHEL 10 supports TLS version 1.3, not all features of this protocol are fully supported by RHEL 10 components. For example, the 0-RTT (Zero Round Trip Time) feature, which reduces connection latency, is not yet fully supported by the Apache web server.
A RHEL 9.2 and later system running in FIPS mode enforces that any TLS 1.2 connection must use the Extended Master Secret (EMS) extension (RFC 7627) as requires the FIPS 140-3 standard. Thus, legacy clients not supporting EMS or TLS 1.3 cannot connect to RHEL 9 and 10 servers running in FIPS mode, RHEL 9 a 10 clients in FIPS mode cannot connect to servers that support only TLS 1.2 without EMS. See the TLS Extension "Extended Master Secret" enforced with Red Hat Enterprise Linux 9.2 Red Hat Knowledgebase solution for more information.
4.2.2. Cipher suites Copy linkLink copied to clipboard!
Modern, more secure cipher suites should be preferred to old, insecure ones. Always disable the use of eNULL and aNULL cipher suites, which do not offer any encryption or authentication at all. If at all possible, ciphers suites based on RC4 or HMAC-MD5, which have serious shortcomings, should also be disabled. The same applies to the so-called export cipher suites, which have been intentionally made weaker, and thus are easy to break.
While not immediately insecure, cipher suites that offer less than 128 bits of security should not be considered for their short useful life. Algorithms that use 128 bits of security or more can be expected to be unbreakable for at least several years, and are thus strongly recommended. Note that while 3DES ciphers advertise the use of 168 bits, they actually offer 112 bits of security.
Always prefer cipher suites that support (perfect) forward secrecy (PFS), which ensures the confidentiality of encrypted data even in case the server key is compromised. This rules out the fast RSA key exchange, but allows for the use of ECDHE and DHE. Of the two, ECDHE is the faster and therefore the preferred choice.
You should also prefer AEAD ciphers, such as AES-GCM, over CBC-mode ciphers as they are not vulnerable to padding oracle attacks. Additionally, in many cases, AES-GCM is faster than AES in CBC mode, especially when the hardware has cryptographic accelerators for AES.
Note also that when using the ECDHE key exchange with ECDSA certificates, the transaction is even faster than a pure RSA key exchange. To provide support for legacy clients, you can install two pairs of certificates and keys on a server: one with ECDSA keys (for new clients) and one with RSA keys (for legacy ones).
4.2.3. Public key length Copy linkLink copied to clipboard!
When using RSA keys, always prefer key lengths of at least 3072 bits signed by at least SHA-256, which is sufficiently large for true 128 bits of security.
The security of your system is only as strong as the weakest link in the chain. For example, a strong cipher alone does not guarantee good security. The keys and the certificates are just as important, as well as the hash functions and keys used by the Certification Authority (CA) to sign your keys.
4.3. Hardening TLS configuration in applications Copy linkLink copied to clipboard!
In RHEL, system-wide crypto policies provide a convenient way to ensure that your applications that use cryptographic libraries do not allow known insecure protocols, ciphers, or algorithms.
If you want to harden your TLS-related configuration with your customized cryptographic settings, you can use the cryptographic configuration options described in this section, and override the system-wide crypto policies just in the minimum required amount.
Regardless of the configuration you choose to use, always ensure that your server application enforces server-side cipher order, so that the cipher suite to be used is determined by the order you configure.
4.3.1. Configuring the Apache HTTP server to use TLS Copy linkLink copied to clipboard!
The Apache HTTP Server
can use both OpenSSL
and NSS
libraries for its TLS needs. RHEL 10 provides the mod_ssl
functionality through eponymous packages:
dnf install mod_ssl
# dnf install mod_ssl
The mod_ssl
package installs the /etc/httpd/conf.d/ssl.conf
configuration file, which can be used to modify the TLS-related settings of the Apache HTTP Server
.
Install the httpd-manual
package to obtain complete documentation for the Apache HTTP Server
, including TLS configuration. The directives available in the /etc/httpd/conf.d/ssl.conf
configuration file are described in detail in the /usr/share/httpd/manual/mod/mod_ssl.html
file. Examples of various settings are described in the /usr/share/httpd/manual/ssl/ssl_howto.html
file.
When modifying the settings in the /etc/httpd/conf.d/ssl.conf
configuration file, be sure to consider the following three directives at the minimum:
SSLProtocol
- Use this directive to specify the version of TLS or SSL you want to allow.
SSLCipherSuite
- Use this directive to specify your preferred cipher suite or disable the ones you want to disallow.
SSLHonorCipherOrder
-
Uncomment and set this directive to
on
to ensure that the connecting clients adhere to the order of ciphers you specified.
For example, to use only the TLS 1.2 and 1.3 protocol:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
See the Configuring TLS encryption on an Apache HTTP Server chapter in the Deploying web servers and reverse proxies document for more information.
4.3.2. Configuring the Nginx HTTP and proxy server to use TLS Copy linkLink copied to clipboard!
To enable TLS 1.3 support in Nginx
, add the TLSv1.3
value to the ssl_protocols
option in the server
section of the /etc/nginx/nginx.conf
configuration file:
See the Adding TLS encryption to an Nginx web server chapter in the Deploying web servers and reverse proxies document for more information.
4.3.3. Configuring the Dovecot mail server to use TLS Copy linkLink copied to clipboard!
To configure your installation of the Dovecot
mail server to use TLS, modify the /etc/dovecot/conf.d/10-ssl.conf
configuration file. You can find an explanation of some of the basic configuration directives available in that file in the /usr/share/doc/dovecot/wiki/SSL.DovecotConfiguration.txt
file, which is installed along with the standard installation of Dovecot
.
When modifying the settings in the /etc/dovecot/conf.d/10-ssl.conf
configuration file, be sure to consider the following three directives at the minimum:
ssl_protocols
- Use this directive to specify the version of TLS or SSL you want to allow or disable.
ssl_cipher_list
- Use this directive to specify your preferred cipher suites or disable the ones you want to disallow.
ssl_prefer_server_ciphers
-
Uncomment and set this directive to
yes
to ensure that the connecting clients adhere to the order of ciphers you specified.
For example, the following line in /etc/dovecot/conf.d/10-ssl.conf
allows only TLS 1.1 and later:
ssl_protocols = !SSLv2 !SSLv3 !TLSv1
ssl_protocols = !SSLv2 !SSLv3 !TLSv1
Chapter 5. Securing system DNS traffic with encrypted DNS Copy linkLink copied to clipboard!
You can enable encrypted DNS to secure DNS communication that uses DNS-over-TLS (DoT) protocol. Encrypted DNS (eDNS) encrypts all DNS traffic end-to-end, with no fallback to insecure protocols, and aligns with the principles of zero trust architecture (ZTA).
The current implementation of eDNS in RHEL uses only the DoT protocol. There are two primary methods to install RHEL with eDNS enabled. You can perform an interactive installation from local media, or you can build a custom bootable ISO to ensure eDNS is configured with an enforce
policy during and after installation. Alternatively, you can convert an existing RHEL installation to use eDNS.
Encrypted DNS is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
5.1. Overview of components for eDNS in RHEL Copy linkLink copied to clipboard!
The following components comprise the eDNS setup in RHEL and interact in a layered fashion:
- NetworkManager
-
NetworkManager enables eDNS and enforces the use of encrypted DNS protocols based on the configured policy. It is set to use
dnsconfd
as its backend DNS resolver. dnsconfd
-
dnsconfd
is a local DNS cache configuration daemon. It simplifies the setup of DNS caching, split DNS, and DNS over TLS (DoT). unbound
-
unbound
is a validating, recursive, and caching DNS resolver. In the eDNS setup, it serves as the runtime cache service fordnsconfd
.unbound
uses TLS for upstream DNS queries, which is essential for encrypting DNS traffic to external DoT servers.unbound
also manages various caches to store DNS responses, which reduces the need for repeated external queries and improves performance.
5.1.1. eDNS resolution process and core interactions Copy linkLink copied to clipboard!
- An application requests to resolve a hostname.
-
The system reads the
/etc/resolv.conf
file and sends the query to the localunbound
service. -
unbound
first checks its internal caches for a valid, cached response. -
If the request record is not found,
unbound
encrypts the DNS query by using TLS and sends it to the configured upstream DoT enabled DNS server. -
The upstream DoT server processes the query and sends an encrypted DNS response back to
unbound
. -
unbound
decrypts, validates, and caches the response. -
Finally,
unbound
sends the resolved DNS response back to the application.
5.2. Installing RHEL with eDNS enabled from a local installation media Copy linkLink copied to clipboard!
Install a RHEL system with an eDNS enforce
policy that ensures that all DNS queries are private and secure during and after installation. If you require a custom CA certificate bundle, you must install it by using the %certificate
section in the Kickstart file.
During the installation, you must provide both the RHEL installation content and the Kickstart file from local media. You cannot download the Kickstart file from a remote HTTP server because the installer would need to use DNS to resolve the server’s hostname. If your environment allows a fallback to unencrypted DNS, you can perform a standard RHEL installation and configure eDNS afterwards.
Prerequisites
-
Commands that start with the
#
command prompt require administrative privileges provided bysudo
or root user access. For information on how to configuresudo
access, see Enabling unprivileged users to run certain commands. - You have the RHEL installation media available locally.
-
If you require a custom CA bundle, have your Kickstart file with a
%certificate
section available locally.
Procedure
Optional: Create a Kickstart file with a
%certificate
section. Ensure the certificate is saved in a file namedtls-ca-bundle.pem
.%certificate --dir /etc/pki/dns/extracted/pem/ --filename tls-ca-bundle.pem -----BEGIN CERTIFICATE----- <Base64-encoded_certificate_content> -----END CERTIFICATE----- %end
%certificate --dir /etc/pki/dns/extracted/pem/ --filename tls-ca-bundle.pem -----BEGIN CERTIFICATE----- <Base64-encoded_certificate_content> -----END CERTIFICATE----- %end
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Prepare your bootable installation media, and include the Kickstart file if you need a custom CA bundle.
- Boot the installation media.
-
From the boot menu window, select the required option and press the
e
key to edit the boot parameters. Add the eDNS kernel arguments:
linux ($root)/vmlinuz-6.12.0-0.el10_0.x86_64 root=/dev/mapper/rhel-root ro crashkernel=2G-64G:256M,64G-:512M resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet emergency ip=dhcp rd.net.dns=dns+tls://<server_ip>#<dns_server_hostname> rd.net.dns-resolve-mode=exclusive rd.net.dns-backend=dnsconfd inst.ks=hd:/dev/sdb1/mykickstart.ks
linux ($root)/vmlinuz-6.12.0-0.el10_0.x86_64 root=/dev/mapper/rhel-root ro crashkernel=2G-64G:256M,64G-:512M resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet emergency ip=dhcp rd.net.dns=dns+tls://<server_ip>#<dns_server_hostname> rd.net.dns-resolve-mode=exclusive rd.net.dns-backend=dnsconfd inst.ks=hd:/dev/sdb1/mykickstart.ks
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
When you finish editing, press
Ctrl+X
to start the installation using the specified options.
Verification
Verify your eDNS configuration:
dnsconfd status
$ dnsconfd status
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Expected output:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that DNS server is responsive by using
nslookup
:nslookup <domain_name>
$ nslookup <domain_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Replace the
<domain_name>
with the domain that you want to query.
Troubleshooting
Enable detailed logging in
unbound
:unbound-control verbosity 5
# unbound-control verbosity 5
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review logs for the relevant service:
journalctl -xe -u <service_name>
$ journalctl -xe -u <service_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Replace
<service_name>
withNetworkManager
,dnsconfd
, orunbound
.
5.3. Installing RHEL with eDNS enabled using a custom bootable ISO Copy linkLink copied to clipboard!
Create a custom bootable ISO to install RHEL with an eDNS enforce
policy that ensures that all DNS queries are private and secure during and after installation. If you require a custom CA certificate bundle, you must install it by using the %certificate
section in the Kickstart file. You then reference this Kickstart file in a script to build a new ISO, which includes kernel arguments to enforce a strict DoT policy. If your environment allows a fallback to unencrypted DNS, you can perform a standard RHEL installation and configure eDNS afterwards.
Prerequisites
-
Commands that start with the
#
command prompt require administrative privileges provided bysudo
or root user access. For information on how to configuresudo
access, see Enabling unprivileged users to run certain commands. - You have downloaded the minimal installation Boot ISO image from the Product Downloads page.
-
You have a Kickstart file ready with a
%certificate
section if you need a custom CA bundle. -
The
lorax
package is installed.
Procedure
Optional: Create a Kickstart file with a
%certificate
section. Ensure the certificate is saved in a file namedtls-ca-bundle.pem
.%certificate --dir /etc/pki/dns/extracted/pem/ --filename tls-ca-bundle.pem -----BEGIN CERTIFICATE----- <Base64-encoded_certificate_content> -----END CERTIFICATE----- %end
%certificate --dir /etc/pki/dns/extracted/pem/ --filename tls-ca-bundle.pem -----BEGIN CERTIFICATE----- <Base64-encoded_certificate_content> -----END CERTIFICATE----- %end
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add the Kickstart file and kernel arguments into the ISO:
The following script example demonstrates how to create a custom bootable ISO with eDNS enabled. You must create a script file to automate this process.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Run the script.
sh <script_filename>
sh <script_filename>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Install RHEL using the customized ISO file.
Verification
Verify your eDNS configuration:
dnsconfd status
$ dnsconfd status
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Expected output:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that DNS server is responsive by using
nslookup
:nslookup <domain_name>
$ nslookup <domain_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Replace the
<domain_name>
with the domain that you want to query.
Troubleshooting
Enable detailed logging in
unbound
:unbound-control verbosity 5
# unbound-control verbosity 5
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review logs for the relevant service:
journalctl -xe -u <service_name>
$ journalctl -xe -u <service_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Replace
<service_name>
withNetworkManager
,dnsconfd
, orunbound
.
5.4. Enabling eDNS on an existing RHEL installation Copy linkLink copied to clipboard!
You can enable encrypted DNS (eDNS) on an existing RHEL installation to handle all DNS traffic by using DNS-over-TLS.
Prerequisites
-
Commands that start with the
#
command prompt require administrative privileges provided bysudo
or root user access. For information on how to configuresudo
access, see Enabling unprivileged users to run certain commands. - Have an existing RHEL installation.
The following packages are installed on your system:
-
dnsconfd
-
dnsconfd-dracut
-
grubby
-
-
If on an IBM Z system, the
zipl
utility is installed.
Procedure
Configure NetworkManager in the
/etc/NetworkManager/conf.d/global-dot.conf
file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow For more details on global DNS options, see the
GLOBAL-DNS SECTION
inNetworkManager.conf(5)
man page on your system.Optional: To use a custom CA bundle for validating upstream DoT servers, copy the PEM-formatted file to the
/etc/pki/dns/extracted/pem/tls-ca-bundle.pem
file.NoteAfter adding or removing certificates in
/etc/pki/dns/extracted/pem
, restart thednsconfd
service to apply the changes.Enable the
dnsconfd
service:systemctl enable --now dnsconfd
# systemctl enable --now dnsconfd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Reload NetworkManager:
systemctl reload NetworkManager
# systemctl reload NetworkManager
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Regenerate
initramfs
for all installed kernels to includednsconfd
and its configuration:for kernel in `rpm -q kernel --qf '%{VERSION}-%{RELEASE}.%{ARCH}\n'`; do dracut -f --kver="$kernel" done
# for kernel in `rpm -q kernel --qf '%{VERSION}-%{RELEASE}.%{ARCH}\n'`; do dracut -f --kver="$kernel" done
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set kernel arguments to the current and newly installed kernel version:
grubby --args="rd.net.dns=dns+tls://<server_ip>#<dns_server_hostname> rd.net.dns-resolve-mode=exclusive rd.net.dns-backend=dnsconfd" --update-kernel=ALL
# grubby --args="rd.net.dns=dns+tls://<server_ip>#<dns_server_hostname> rd.net.dns-resolve-mode=exclusive rd.net.dns-backend=dnsconfd" --update-kernel=ALL
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If on IBM Z, update the boot menu:
zipl
# zipl
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify your eDNS configuration:
dnsconfd status
$ dnsconfd status
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Expected output:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the DNS server is responsive by using
nslookup
:nslookup <domain_name>
$ nslookup <domain_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Replace the
<domain_name>
with the domain that you want to query.
Troubleshooting
Enable detailed logging in
unbound
:unbound-control verbosity 5
# unbound-control verbosity 5
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review logs for the relevant service:
journalctl -xe -u <service_name>
$ journalctl -xe -u <service_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Replace
<service_name>
withNetworkManager
,dnsconfd
, orunbound
.
5.5. Kernel parameters for DNS configuration Copy linkLink copied to clipboard!
You can use kernel arguments to enable DNS over TLS (DoT) at boot time and set DNS resolution behavior for your system.
rd.net.dns-resolve-mode
Defines how DNS servers from global configuration are used during resolution. The following modes are relevant for both kernel arguments and NetworkManager.conf
global configuration:
exclusive
-
Uses only the DNS servers specified by kernel arguments or in
NetworkManager.conf
. Forbids fallback to DNS servers retrieved from connections. This mode is currently relevant only fordnsconfd
plugin. prefer
- Forbids using DNS servers from connections for general queries unless the queries are subdomains of domains set by connection.
backup
- Merges and uses DNS servers from both the global configuration and network connections for the same purposes.
rd.net.dns-servers
Configure the list of DNS servers to use. To define multiple DNS servers, set rd.net.dns
multiple times:
rd.net.dns=dns+tls://<server_ip_1>#<dns_server_hostname_1> rd.net.dns=dns+tls://<server_ip_2>#<dns_server_hostname_2>
rd.net.dns=dns+tls://<server_ip_1>#<dns_server_hostname_1> rd.net.dns=dns+tls://<server_ip_2>#<dns_server_hostname_2>
For example:
rd.net.dns=dns+tls://198.51.100.143#dot.dns.example.com rd.net.dns=dns+tls://203.0.113.1#dot.dns.example.net
rd.net.dns=dns+tls://198.51.100.143#dot.dns.example.com rd.net.dns=dns+tls://203.0.113.1#dot.dns.example.net
rd.net.dns-backend
Specifies the backend DNS resolver. When set to dnsconfd
, the system uses dnsconfd
as a local DNS cache configuration daemon.
Chapter 6. Setting up an IPsec VPN Copy linkLink copied to clipboard!
Configure and manage a secure Virtual Private Network (VPN) by using the Libreswan implementation of the IPsec protocol suite to create encrypted tunnels for secure data transmission over the internet.
IPsec tunnels ensure the confidentiality and integrity of data in transit. Common use cases include connecting branch offices to headquarters or providing remote users with secure access to a corporate network.
RHEL provides different options to configure Libreswan:
- Manually edit the Libreswan configuration files for granular control over advanced options.
-
Use the
vpn
RHEL system role to automate the process of creating Libreswan VPN configurations. - Use Nmstate to configure a Libreswan connection through a declarative API.
Libreswan does not use terms such as "client" and "server". Instead, IPsec refers to endpoints as "left" and "right". This design often enables you to use the same configuration on both hosts because Libreswan dynamically determines which role to adopt. As a convention, administrators typically use "left" for the local host and "right" for the remote host.
Libreswan is the only supported VPN technology in RHEL.
IPsec relies on standardized protocols, such as Internet Key Exchange (IKE), to ensure that different systems can communicate effectively. However, in practice, minor differences in how vendors implement these standards can lead to compatibility problems. If you encounter such interoperability issues when connecting Libreswan to a third-party IPsec peer, contact Red Hat Support.
6.1. Components in an IPsec VPN Copy linkLink copied to clipboard!
Before setting up an IPsec VPN, it is important to understand its main components: Internet Key Exchange (IKE) for authentication and negotiation, and IPsec for data encryption and transport.
IKE is the protocol two endpoints use to authenticate each other and negotiate connection rules, including encryption algorithms. Libreswan implements IKE in a daemon called pluto
.
IPsec is the part of the protocol that actually encrypts and transports data according to the policy agreed upon during the IKE negotiation. The Linux kernel implements the IPsec protocol suite.
6.2. Libreswan authentication methods Copy linkLink copied to clipboard!
Select the appropriate authentication method to establish a secure VPN connection based on your security needs and network environment.
Libreswan supports the following authentication methods:
- Pre-Shared key
- The Pre-Shared Key (PSK) method involves both endpoints by using the same secret to authenticate each other. PSKs offer simplicity and broad compatibility, making them suitable for small-scale deployments. However, managing PSKs is risky if the key is reused or not rotated frequently. For security, PSKs should consist of more than 64 random characters and must meet FIPS strength requirements if your host operates in FIPS mode.
- Raw RSA key
- This method uses an RSA public and private key pair on each peer for mutual identification. Raw RSA keys provide stronger security than PSKs and are ideal for environments where a full certificate infrastructure is not required.
- X.509 certificates
- This method uses X.509 certificates issued by a trusted Certificate Authority (CA). Each peer proves its identity by using its certificate and private key, which the other peer verifies against the trusted CA. While providing the highest level of security and scalability for large enterprises, this method is more complex as it requires deploying and maintaining a public key infrastructure (PKI).
- NULL authentication
- This method provides only encryption with no authentication between peers. Because it does not verify the identity of the remote endpoint, NULL authentication is insecure and offers no protection against man-in-the-middle attacks.
- Protection against quantum computers
- While not a standalone authentication method, Libreswan offers Post-quantum Pre-shared Keys (PPKs) to protect modern IKEv2 connections from future attacks by quantum computers. This feature is necessary because neither the older IKEv1 protocol nor standard IKEv2 is inherently quantum-resistant on its own. A PPK adds another layer of security on top of the primary authentication method, and its security relies on using a cryptographically strong key that has been distributed securely through an external communication channel.
6.3. Manually configuring an IPsec host-to-host VPN with raw RSA key authentication Copy linkLink copied to clipboard!
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, RSA keys are more secure than pre-shared keys (PSKs) because their asymmetric encryption eliminates the risk of a shared secret. Using RSA keys also simplifies deployment by avoiding the need for a certificate authority (CA), while still providing strong peer-to-peer authentication.
Perform the steps on both hosts.
Procedure
If Libreswan is not yet installed, perform the following steps:
Install the
libreswan
package:dnf install libreswan
# dnf install libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize the Network Security Services (NSS) database:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates the database in the
/var/lib/ipsec/nss/
directory.Enable and start the
ipsec
service:systemctl enable --now ipsec
# systemctl enable --now ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Open the IPsec ports and protocols in the firewall:
firewall-cmd --permanent --add-service="ipsec" firewall-cmd --reload
# firewall-cmd --permanent --add-service="ipsec" # firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Create an RSA key pair:
ipsec newhostkey
# ipsec newhostkey
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
ipsec
utility stores the key pair in the NSS database.- Designate your peers. In an IPsec tunnel, you must designate one host as left and the other as right. This is an arbitrary choice. A common practice is to call your local host left and the remote host right.
Display the Certificate Key Attribute ID (CKAID) on both the left and right peer:
ipsec showhostkey --list
# ipsec showhostkey --list < 1> RSA keyid: <key_id> ckaid: <ckaid>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You require the CKAIDs of both peers in the next steps.
Display the public keys:
On the left peer, enter:
ipsec showhostkey --left --ckaid <ckaid_of_left_peer>
# ipsec showhostkey --left --ckaid <ckaid_of_left_peer> # rsakey AwEAAdKCx leftrsasigkey=0sAwEAAdKCxpc9db48cehzQiQD...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow On the right peer, enter:
ipsec showhostkey --right --ckaid <ckaid_of_right_peer>
# ipsec showhostkey --right --ckaid <ckaid_of_right_peer> # rsakey AwEAAcNWC rightrsasigkey=0sAwEAAcNWCzZO+PR1j8WbO8X...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The commands display the public keys with the corresponding parameters that you must use in the configuration file.
Create a
.conf
file for the connection in the/etc/ipsec.d/
directory. For example, create the/etc/ipsec.d/host-to-host.conf
file with the following settings:Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteYou can use the same configuration file on both hosts, and Libreswan identifies whether it is operating on the left or right host by using internal information. However, it is important that all values in
left*
parameters belong to one peer and the values inright*
parameters belong to the other.The settings specified in the example include the following:
conn <connection_name>
- Defines the connection name. The name is arbitrary, and Libreswan uses it to identify the connection. You must indent parameters in this connection by at least one space or tab.
auto=<type>
-
Controls how the connection is initiated. If you set the value to
start
, Libreswan activates the connection automatically when the service starts. authby=rsasig
- Enables RSA signature authentication for this connection.
left=<ip_address_or_fqdn_of_left_peer>
andright=<ip_address_or_fqdn_of_right_peer>
- Defines the IP address or DNS name of the peers.
leftid=<id>
andrightid=<id>
-
Defines how each peer is identified during the Internet Key Exchange (IKE) negotiation process. This can be a fully-qualified domain name (FQDN), an IP address, or a literal string. In the latter case, precede the string with an
@
sign. leftrsasigkey=<public_key>
andrightrsasigkey=<public_key>
-
Specifies the public key of the peers. Use the values displayed by the
ipsec showhostkey
command in a previous step.
Restart the
ipsec
service:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you use
auto=start
in the configuration file, the connection is automatically activated. With other methods, additional steps are required to activate the connection. For details, see theipsec.conf(5)
man page on your system.
Verification
Display the IPsec status:
ipsec status
# ipsec status
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the connection is successfully established, the output contains lines as follows:
Phase 1 of an Internet Key Exchange version 2 (IKEv2) negotiation has been successfully completed:
000 #1: "<connection_name>":500 STATE_V2_ESTABLISHED_IKE_SA (established IKE SA); REKEY in 27935s; REPLACE in 28610s; newest; idle;
000 #1: "<connection_name>":500 STATE_V2_ESTABLISHED_IKE_SA (established IKE SA); REKEY in 27935s; REPLACE in 28610s; newest; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The Security Association (SA) is now ready to negotiate the actual data encryption tunnels, known as child SAs or Phase 2 SAs.
A child SA has been established:
000 #2: "<connection_name>":500 STATE_V2_ESTABLISHED_CHILD_SA (established Child SA); REKEY in 27671s; REPLACE in 28610s; IKE SA #1; idle;
000 #2: "<connection_name>":500 STATE_V2_ESTABLISHED_CHILD_SA (established Child SA); REKEY in 27671s; REPLACE in 28610s; IKE SA #1; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This is the actual tunnel that your data traffic flows through.
Next steps
- 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.4. Manually configuring an IPsec site-to-site VPN with raw RSA key authentication Copy linkLink copied to clipboard!
A site-to-site VPN establishes a secure, encrypted tunnel between two distinct networks, seamlessly linking them across an insecure public network such as the internet.
For example, 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 authenticating the gateway devices, RSA keys are more secure than pre-shared keys (PSKs) because their asymmetric encryption eliminates the risk of a shared secret. Using RSA keys also simplifies deployment by avoiding the need for a certificate authority (CA), while still providing strong peer-to-peer authentication.
Perform the steps on both gateway devices.
Prerequisites
- Routes in both networks ensure that the traffic to the remote networks is sent through the local VPN gateway devices.
Procedure
If Libreswan is not yet installed, perform the following steps:
Install the
libreswan
package:dnf install libreswan
# dnf install libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize the Network Security Services (NSS) database:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates the database in the
/var/lib/ipsec/nss/
directory.Enable and start the
ipsec
service:systemctl enable --now ipsec
# systemctl enable --now ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Open the IPsec ports and protocols in the firewall:
firewall-cmd --permanent --add-service="ipsec" firewall-cmd --reload
# firewall-cmd --permanent --add-service="ipsec" # firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Create an RSA key pair:
ipsec newhostkey
# ipsec newhostkey
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
ipsec
utility stores the key pair in the NSS database.- Designate your peers. In an IPsec tunnel, you must designate one host as left and the other as right. This is an arbitrary choice. A common practice is to call your local host left and the remote host right.
Display the Certificate Key Attribute ID (CKAID) on both the left and right peer:
ipsec showhostkey --list
# ipsec showhostkey --list < 1> RSA keyid: <key_id> ckaid: <ckaid>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You require the CKAIDs of both peers in the next steps.
Display the public keys:
On the left peer, enter:
ipsec showhostkey --left --ckaid <ckaid_of_left_peer>
# ipsec showhostkey --left --ckaid <ckaid_of_left_peer> # rsakey AwEAAdKCx leftrsasigkey=0sAwEAAdKCxpc9db48cehzQiQD...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow On the right peer, enter:
ipsec showhostkey --right --ckaid <ckaid_of_right_peer>
# ipsec showhostkey --right --ckaid <ckaid_of_right_peer> # rsakey AwEAAcNWC rightrsasigkey=0sAwEAAcNWCzZO+PR1j8WbO8X...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The commands display the public keys with the corresponding parameters that you must use in the configuration file.
Create a
.conf
file for the connection in the/etc/ipsec.d/
directory. For example, create the/etc/ipsec.d/site-to-site.conf
file with the following settings:Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteYou can use the same configuration file on both gateway devices, and Libreswan identifies whether it is operating on the left or right host by using internal information. However, it is important that all values in
left*
parameters belong to one peer and the values inright*
parameters belong to the other.The settings specified in the example include the following:
conn <connection_name>
- Defines the connection name. The name is arbitrary, and Libreswan uses it to identify the connection. You must indent parameters in this connection by at least one space or tab.
auto=<type>
-
Controls how the connection is initiated. If you set the value to
start
, Libreswan activates the connection automatically when the service starts. authby=rsasig
- Enables RSA signature authentication for this connection.
left=<ip_address_or_fqdn_of_left_peer>
andright=<ip_address_or_fqdn_of_right_peer>
- Defines the IP address or DNS name of the peers.
leftid=<id>
andrightid=<id>
-
Defines how each peer is identified during the Internet Key Exchange (IKE) negotiation process. This can be a fully-qualified domain name (FQDN), an IP address, or a literal string. In the latter case, precede the string with an
@
sign. leftrsasigkey=<public_key>
andrightrsasigkey=<public_key>
-
Specifies the public key of the peers. Use the values displayed by the
ipsec showhostkey
command in a previous step. leftsubnet=<subnet>
andrightsubnet=<subnet>
- Defines subnets in classless inter-domain routing (CIDR) format that are connected through the tunnel. If you want to tunnel multiple subnets on one side, specify them in curly brackets and separate them with a comma.
Enable packet forwarding:
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the
ipsec
service:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you use
auto=start
in the configuration file, the connection is automatically activated. With other methods, additional steps are required to activate the connection. For details, see theipsec.conf(5)
man page on your system.
Verification
Display the IPsec status:
ipsec status
# ipsec status
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the connection is successfully established, the output contains lines as follows:
Phase 1 of an Internet Key Exchange version 2 (IKEv2) negotiation has been successfully completed:
#2: "<connection_name>":500 ESTABLISHED_IKE_SA (established IKE SA); REKEY in 28523s; REPLACE in 28793s; newest; idle;
#2: "<connection_name>":500 ESTABLISHED_IKE_SA (established IKE SA); REKEY in 28523s; REPLACE in 28793s; newest; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The Security Association (SA) is now ready to negotiate the actual data encryption tunnels, known as child SAs or Phase 2 SAs.
A child SA has been established:
#3: "<connection_name>":500 ESTABLISHED_CHILD_SA (established Child SA); REKEY in 28523s; REPLACE in 28793s; newest; eroute owner; IKE SA #2; idle;
#3: "<connection_name>":500 ESTABLISHED_CHILD_SA (established Child SA); REKEY in 28523s; REPLACE in 28793s; newest; eroute owner; IKE SA #2; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This is the actual tunnel that your data traffic flows through.
- From a client in the local subnet, ping a client in the remote subnet.
Next steps
- 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. Manually configuring an IPsec host-to-site VPN with certificate-based authentication Copy linkLink copied to clipboard!
A host-to-site VPN establishes a secure, encrypted connection between an individual remote computer and a private network, allowing them to be seamlessly linked across an insecure public network, such as the internet.
A host-to-site VPN is ideal for remote employees who need to access resources on their company’s internal network from their computer as if they were physically in the office.
For authentication, using digital certificates managed by a Certificate Authority (CA) offers a highly secure and scalable solution. Each connecting host and the gateway 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.
6.5.1. Setting up an IPsec gateway manually Copy linkLink copied to clipboard!
You must configure the Libreswan IPsec gateway properly to enable secure remote access. Libreswan reads the server certificate, private key, and CA certificate from a Network Security Services (NSS) database.
The following example permits authenticated clients to access the internal 192.0.2.0/24 subnet and dynamically assigns an IP address from a virtual IP pool to each client. To maintain security, the gateway verifies that client certificates are issued by the same trusted CA and automatically uses a certificate revocation list (CRL) to ensure access is denied for any revoked certificates.
Prerequisites
The Public Key Cryptography Standards #12 (PKCS #12) file
~/file.p12
exists on the gateway with the following contents:- The private key of the server
- The server certificate
- The CA certificate
- If required, intermediate certificates
For details about creating a private key and certificate signing request (CSR), as well as about requesting a certificate from a CA, see your CA’s documentation.
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 gateway.
- X509v3 CRL distribution points contains URLs to Certificate Revocation Lists (CRLs).
-
Extended Key Usage (EKU) is set to
- A return route for VPN client traffic is configured on the internal network, pointing to the VPN gateway.
Procedure
If Libreswan is not yet installed:
Install the
libreswan
package:dnf install libreswan
# dnf install libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize the Network Security Services (NSS) database:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates the database in the
/var/lib/ipsec/nss/
directory.Enable and start the
ipsec
service:systemctl enable --now ipsec
# systemctl enable --now ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Open the IPsec ports and protocols in the firewall:
firewall-cmd --permanent --add-service="ipsec" firewall-cmd --reload
# firewall-cmd --permanent --add-service="ipsec" # firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Import the PKCS #12 file into the NSS database:
ipsec import ~/file.p12
# ipsec import ~/file.p12 Enter password for PKCS12 file: <password> pk12util: PKCS12 IMPORT SUCCESSFUL correcting trust bits for Example-CA
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display the nicknames of the server and CA certificates:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You need this information for the configuration file.
Create a
.conf
file for the connection in the/etc/ipsec.d/
directory. For example, create the/etc/ipsec.d/host-to-site.conf
file with the following settings:Add a
config setup
section to enable CRL checks:config setup crl-strict=yes crlcheckinterval=1h
config setup crl-strict=yes crlcheckinterval=1h
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example include the following:
crl-strict=yes
- Enables CRL checks. Authenticating clients are rejected if no CRL is available in the NSS database.
crlcheckinterval=1h
- Re-fetches the CRL from the URL specified in the server’s certificate after the specified period.
Add a section for the gateway:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example include the following:
ikev2=insist
- Defines the modern IKEv2 protocol as the only allowed protocol without fallback to IKEv1.
left=%defaultroute
-
Dynamically sets the IP address of the default route interface when the
ipsec
service starts. Alternatively, you can set theleft
parameter to the IP address or the FQDN of the host. leftid=%fromcert
andrightid=%fromcert
- Configures Libreswan to retrieve the identity from the distinguished name (DN) field of the certificate.
leftcert="<server_certificate_nickname>"
- Sets the nickname of the server’s certificate used in the NSS database.
leftrsasigkey=%cert
andrightrsasigkey=%cert
- Configures Libreswan to use the RSA public key embedded in the certificate.
leftsendcert=always
- Instructs the gateway to always send the certificate, so that clients can validate it against the CA certificate.
leftsubnet=<subnets>
- Specifies the subnets connected to the gateway that clients can access through the tunnel.
mobike=yes
- Enables clients to seamlessly roam among networks.
rightaddresspool=<ip_range>
- Specifies from which range the gateway can assign IP addresses to the clients.
modecfgclient=yes
-
Enables clients to receive the DNS server IP set in the
modecfgdns
parameter and the DNS search domain set inmodecfgdomains
.
For details about all parameters used in the example, see the
ipsec.conf(5)
man page on your system.Enable packet forwarding:
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the
ipsec
service:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you use
auto=start
in the configuration file, the connection is automatically activated. With other methods, additional steps are required to activate the connection. For details, see theipsec.conf(5)
man page on your system.
Verification
- Configure a client and connect to the VPN gateway.
Check if the service loaded the CRL and added the entries to the NSS database:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps:
- Configure firewall rules to ensure that clients can only communicate with required resources. For details about firewalls, see Configuring firewalls and packet filters.
6.5.2. Configuring a client to connect to an IPsec VPN gateway by using GNOME Settings Copy linkLink copied to clipboard!
To access resources on a remote private network, users must first configure an IPsec VPN connection. The GNOME Settings application provides a graphical solution to create an IPsec VPN connection profile in NetworkManager and to establish the tunnel.
Prerequisites
- You configured the IPsec VPN gateway.
-
The
NetworkManager-libreswan-gnome
package is installed. The PKCS #12 file
~/file.p12
exists on the client with the following contents:- The private key of the user
- The user certificate
- The CA certificate
- If required, intermediate certificates
For details about creating a private key and certificate signing request (CSR), as well as about requesting a certificate from a CA, see your CA’s documentation.
-
The Extended Key Usage (EKU) in the certificate is set to
TLS Web Client Authentication
.
Procedure
Initialize the Network Security Services (NSS) database:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates the database in the
/var/lib/ipsec/nss/
directory.Import the PKCS #12 file into the NSS database:
ipsec import ~/file.p12
# ipsec import ~/file.p12 Enter password for PKCS12 file: <password> pk12util: PKCS12 IMPORT SUCCESSFUL correcting trust bits for Example-CA
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display the nicknames of the user and CA certificates:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You require this information in the configuration file.
- Press the Super key, type Settings, and press Enter to open the GNOME Settings application.
- Click the VPN entry. button next to the
- Select IPsec based VPN from the list.
On the Identity tab, fill the fields as follows:
Expand Table 6.1. Identity tab settings Field name Value Corresponding ipsec.conf
parameterName
<networkmanager_profile_name>
N/A
Gateway
<ip_address_or_fqdn_of_the_gateway>
right
Type
IKEv2 (certificate)
authby
Group name
%fromcert
leftid
Certificate name
<user_certificate_nickname>
leftcert
Remote ID
%fromcert
rightid
- Click Advanced.
In the Advanced properties window, fill the fields of the Connectivity tab as follows:
Expand Table 6.2. Connectivity tab settings Field name Value Corresponding ipsec.conf
parameterRemote Network
192.0.2.0/24
rightsubnet
Narrowing
Selected
narrowing
Enable MOBIKE
yes
mobike
Delay
30
dpddelay
Timeout
120
dpdtimeout
Action
Clear
dpdaction
- Click to return to the connection settings.
- Click to save the connection.
- In the Network tab of the Settings application, toggle the switch next to the VPN profile to activate the connection.
Verification
- Establish a connection to a host in the remote network or ping it.
Next steps
- 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. Manually configuring an IPsec mesh VPN with certificate-based authentication Copy linkLink copied to clipboard!
An IPsec mesh creates a fully interconnected network where every server can communicate securely and directly with every other server. This 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
A Public Key Cryptography Standards #12 (PKCS #12) file exists on each peer in the mesh with the following contents:
- The private key of the server
- The server certificate
- The CA certificate
- If required, intermediate certificates
For details about creating a private key and certificate signing request (CSR), as well as about requesting a certificate from a CA, see your CA’s documentation.
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
If Libreswan is not yet installed, perform the following steps:
Install the
libreswan
package:dnf install libreswan
# dnf install libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize the Network Security Services (NSS) database:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates the database in the
/var/lib/ipsec/nss/
directory.Enable and start the
ipsec
service:systemctl enable --now ipsec
# systemctl enable --now ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Open the IPsec ports and protocols in the firewall:
firewall-cmd --permanent --add-service="ipsec" firewall-cmd --reload
# firewall-cmd --permanent --add-service="ipsec" # firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Import the PKCS #12 file into the NSS database:
ipsec import <file>.p12
# ipsec import <file>.p12 Enter password for PKCS12 file: <password> pk12util: PKCS12 IMPORT SUCCESSFUL correcting trust bits for Example-CA
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display the nicknames of the server and CA certificates:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You need this information for the configuration file.
Create a
.conf
file for the connection in the/etc/ipsec.d/
directory. For example, create the/etc/ipsec.d/mesh.conf
file with the following settings:Add a
config setup
section to enable CRL checks:config setup crl-strict=yes crlcheckinterval=1h
config setup crl-strict=yes crlcheckinterval=1h
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example include the following:
crl-strict=yes
- Enables CRL checks. Authenticating peers are rejected if no CRL is available in the NSS database.
crlcheckinterval=1h
- Re-fetches the CRL from the URL specified in the server’s certificate after the specified period.
Add a section that enforces traffic among members in the mesh:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example include the following:
left=%defaultroute
-
Dynamically sets the IP address of the default route interface when the
ipsec
service starts. Alternatively, you can set theleft
parameter to the IP address or the FQDN of the host. leftid=%fromcert
andrightid=%fromcert
- Configures Libreswan to retrieve the identity from the distinguished name (DN) field of the certificate.
leftcert="<server_certificate_nickname>"
- Sets the nickname of the server’s certificate used in the NSS database.
leftrsasigkey=%cert
- Configures Libreswan to use the RSA public key embedded in the certificate.
leftsendcert=always
- Instructs the peer to always send the certificate, so that peers can validate it against the CA certificate.
failureshunt=drop
- Enforces encryption and drops traffic if IPsec negotiation fails. This is critical for a secure mesh.
right=%opportunisticgroup
- Specifies that the connection should apply to a dynamic group of remote peers defined in a policy file. This enables Libreswan to instantiate IPsec tunnels opportunistically for each listed IP or subnet in that group.
For details about all parameters used in the example, see the
ipsec.conf(5)
man page on your system.Create the
/etc/ipsec.d/policies/server-mesh
policy file that specifies the peers or subnets in classless inter-domain routing (CIDR) format:192.0.2.0/24 198.51.100.0/24
192.0.2.0/24 198.51.100.0/24
Copy to Clipboard Copied! Toggle word wrap Toggle overflow With these settings, the
ipsec
service encrypts traffic between hosts in these subnets. If a host is not configured as a member of the IPsec mesh, communication between this host and the mesh members fails.Restart the
ipsec
service:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Repeat the procedure on every host in the subnets you specified in the policy file.
Verification
Send traffic to a host in the mesh to establish the tunnel. For example, ping the host:
ping -c3 <peer_in_mesh>
# ping -c3 <peer_in_mesh>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display the IPsec status:
ipsec status
# ipsec status
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the connection is successfully established, the output contains lines as follows for the peer:
Phase 1 of an Internet Key Exchange version 2 (IKEv2) negotiation has been successfully completed:
#1: "<connection_name>#192.0.2.0/24"[1] ...192.0.2.2:500 ESTABLISHED_IKE_SA (established IKE SA); REKEY in 12822s; REPLACE in 13875s; newest; idle;
#1: "<connection_name>#192.0.2.0/24"[1] ...192.0.2.2:500 ESTABLISHED_IKE_SA (established IKE SA); REKEY in 12822s; REPLACE in 13875s; newest; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The Security Association (SA) is now ready to negotiate the actual data encryption tunnels, known as child SAs or Phase 2 SAs.
A child SA has been established:
#2: "<connection_name>#192.0.2.0/24"[1] ...192.0.2.2:500 ESTABLISHED_CHILD_SA (established Child SA); REKEY in 13071s; REPLACE in 13875s; newest; eroute owner; IKE SA #1; idle;
#2: "<connection_name>#192.0.2.0/24"[1] ...192.0.2.2:500 ESTABLISHED_CHILD_SA (established Child SA); REKEY in 13071s; REPLACE in 13875s; newest; eroute owner; IKE SA #1; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This is the actual tunnel that your data traffic flows through.
Check if the service loaded the CRL and added the entries to the NSS database:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps
- 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.7. Protecting the IPsec NSS database with a password Copy linkLink copied to clipboard!
By default, only the root user can access the IPsec Network Security Services (NSS) database in the /var/lib/ipsec/nss/
directory. You can additionally protect the database with a password. This is required if you run RHEL in Federal Information Processing Standard (FIPS) mode.
Prerequisites
-
The
/var/lib/ipsec/nss/
directory contains the NSS database.
Procedure
Enable password protection for the Libreswan NSS database:
certutil -W -d /var/lib/ipsec/nss/
# certutil -W -d /var/lib/ipsec/nss/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enter the current password:
Enter Password or Pin for "NSS Certificate DB": <password>
Enter Password or Pin for "NSS Certificate DB": <password>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the database is currently not protected by a password, press Enter.
Enter the new password:
Enter new password: <new_password> Re-enter password: <new_password>
Enter new password: <new_password> Re-enter password: <new_password>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow To unlock the database, the
ipsec
service requires the/etc/ipsec.d/nsspassword
file. Create the file with the following content:If the host does not run in FIPS mode:
NSS Certificate DB:<password>
NSS Certificate DB:<password>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the host runs in FIPS mode:
NSS FIPS 140-2 Certificate DB:<password>
NSS FIPS 140-2 Certificate DB:<password>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Set secure permissions on the
/etc/ipsec.d/nsspassword
file:chmod 600 /etc/ipsec.d/nsspassword chown root:root /etc/ipsec.d/nsspassword
# chmod 600 /etc/ipsec.d/nsspassword # chown root:root /etc/ipsec.d/nsspassword
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the
ipsec
service:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the
ipsec
service is running:systemctl is-active ipsec
# systemctl is-active ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the command returns
active
, the service successfully uses the password file to unlock the NSS database.Perform an action on the NSS database that requires the password. For example, display the private keys:
certutil -K -d /var/lib/ipsec/nss/
# certutil -K -d /var/lib/ipsec/nss/ certutil: Checking token "NSS Certificate DB" in slot "NSS User Private Key and Certificate Services" Enter Password or Pin for "NSS Certificate DB":
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the command prompts for the password.
6.8. Using IPsec on a system with FIPS mode enabled Copy linkLink copied to clipboard!
RHEL in Federal Information Processing Standard (FIPS) mode exclusively uses validated cryptographic modules, automatically disabling legacy protocols and ciphers. Enabling FIPS mode is often a requirement for federal compliance and enhances system security.
The Libreswan IPsec implementation provided by RHEL is fully FIPS-compliant. When the system is in FIPS mode, Libreswan automatically uses the certified cryptographic modules without requiring any additional configuration, regardless of whether Libreswan is installed on a new FIPS-enabled system or when FIPS mode is activated on a system with an existing Libreswan VPN.
If FIPS mode is enabled, you can confirm that Libreswan is running in FIPS mode:
ipsec whack --fipsstatus
# ipsec whack --fipsstatus
FIPS mode enabled
To list the allowed algorithms and ciphers in Libreswan in FIPS mode, enter:
6.9. Configuring TCP fallback for an IPsec VPN connection Copy linkLink copied to clipboard!
Standard IPsec VPNs can fail on restrictive networks that block the UDP and Encapsulating Security Payload (ESP) protocols. To ensure connectivity in such environments, Libreswan can encapsulate all VPN traffic within a TCP connection.
Encapsulating VPN packets within TCP can reduce throughput and increase latency. For this reason, use TCP encapsulation only as a fallback option or if UDP-based connections are consistently blocked in your environment.
Prerequisites
- The IPsec connection is configured.
Procedure
Edit the
/etc/ipsec.conf
file, and make the following changes in theconfig setup
section:Configure Libreswan to listen on a TCP port:
listen-tcp=yes
listen-tcp=yes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow By default, Libreswan listens on port 4500. If you want to use a different port, enter:
tcp-remoteport=<port_number>
tcp-remoteport=<port_number>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Decide whether TCP should be used as a fallback option if UDP is not available or permanent:
As a fallback option, enter:
enable-tcp=fallback retransmit-timeout=5s
enable-tcp=fallback retransmit-timeout=5s
Copy to Clipboard Copied! Toggle word wrap Toggle overflow By default, Libreswan waits 60 seconds after a failed attempt to connect by using UDP before retrying the connection over TCP. Lowering the
retransmit-timeout
value shortens the delay, enabling the fallback protocol to initiate more quickly.As a permanent replacement for UDP, enter:
enable-tcp=yes
enable-tcp=yes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Restart the
ipsec
service:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you configured a TCP port other than the default 4500, open the port in the firewall:
firewall-cmd --permanent --add-port=<tcp_port>/tcp firewall-cmd --reload
# firewall-cmd --permanent --add-port=<tcp_port>/tcp # firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Repeat the procedure on the peers that use this gateway.
6.10. Enabling legacy ciphers and algorithms in Libreswan Copy linkLink copied to clipboard!
Enable legacy ciphers and algorithms in Libreswan for backward compatibility with other IPsec peers. This overrides the RHEL system-wide cryptographic policies which, by default, enforce strongencryption ciphers and algorithms for IPsec and Internet Key Exchange (IKE).
The RHEL system-wide cryptographic policies create a special connection called %default
. This connection sets the default values for the keyexchange
, esp
, and ike
parameters.
Prerequisites
- Libreswan is installed.
Procedure
To override the defaults set by the RHEL system-wide cryptographic policies, add the
keyexchange
,esp
, andike
parameters to your connection configuration and set them to the values you require. For example:conn <connection_name> keyexchange=ikev1 ike=aes-sha2,aes-sha1;modp2048 esp=aes-sha2,aes-sha1 ...
conn <connection_name> keyexchange=ikev1 ike=aes-sha2,aes-sha1;modp2048 esp=aes-sha2,aes-sha1 ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the
ipsec
service:systemctl restart ipsec
# systemctl restart ipsec
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
6.11. Assigning a VPN connection to a dedicated routing table to prevent the connection from bypassing the tunnel Copy linkLink copied to clipboard!
To protect your VPN connection from traffic redirection attacks, assign it to a dedicated routing table. This prevents malicious network servers from bypassing the secure tunnel and compromising data integrity.
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 from manipulating 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.
Routing the entire traffic through the VPN prevents the host from accessing local network resources.
Procedure
- 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.
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
# nmcli connection modify <vpn_connection_profile> ipv4.route-table 75 ipv6.route-table 75
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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"
# 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 Copied! Toggle word wrap Toggle overflow The priority value can be any value between 1 and 32766. The lower the value, the higher the priority.
Reconnect the VPN connection:
nmcli connection down <vpn_connection_profile> nmcli connection up <vpn_connection_profile>
# nmcli connection down <vpn_connection_profile> # nmcli connection up <vpn_connection_profile>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the IPv4 routes in table 75:
ip route show 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 Copied! Toggle word wrap Toggle overflow 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.Display the IPv6 routes in table 75:
ip -6 route show 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 Copied! Toggle word wrap Toggle overflow 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.
6.12. Configuring IPsec VPN connections by using RHEL system roles Copy linkLink copied to clipboard!
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.
6.12.1. Configuring an IPsec host-to-host VPN with PSK authentication by using the vpn RHEL system role Copy linkLink copied to clipboard!
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.
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.
6.12.3. Configuring an IPsec site-to-site VPN with PSK authentication by using the vpn RHEL system role Copy linkLink copied to clipboard!
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.
6.12.4. Configuring an IPsec mesh VPN with certificate-based authentication by using the vpn RHEL system role Copy linkLink copied to clipboard!
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
6.13. Configuring IPsec VPN connections by using nmstatectl Copy linkLink copied to clipboard!
Configure IPsec VPN connections to establish encrypted tunnels over untrusted networks and ensure the integrity of data in transit. By using Nmstate, you can create IPsec VPN connections by using a declarative API.
You can use the nmstatectl
utility to configure Libreswan IPsec VPN connections through the Nmstate API. The nmstatectl
utility is a command-line tool to manage host networking through the declarative Nmstate API. Instead of running multiple imperative commands to configure an interface, you define the expected state in a YAML file. Nmstate then takes this definition and applies it to the system. A key advantage of this approach is an atomic result. Nmstate ensures that the resulting configuration precisely matches your YAML definition. If any part of the configuration fails to apply, it automatically rolls back all changes and prevents the system from entering an incorrect or broken network state.
Due to the design of the NetworkManager-libreswan
plugin, you can use nmstatectl
only on one peer and must manually configure Libreswan on the other peer.
6.13.1. Configuring an IPsec host-to-host VPN with raw RSA key authentication by using nmstatectl Copy linkLink copied to clipboard!
You can use the declarative Nmstate API to configure a host-to-host VPN between two devices to communicate safely over an insecure network. Nmstate ensures that the result matches the configuration file or rolls back the changes.
For authentication, RSA keys are more secure than pre-shared keys (PSKs) because their asymmetric encryption eliminates the risk of a shared secret. Using RSA keys also simplifies deployment by avoiding the need for a certificate authority (CA), while still providing strong peer-to-peer authentication.
In general, the choice of which host is named left and right is arbitrary. However, NetworkManager always uses the term left for the local host and right for the remote host.
Prerequisites
The remote peer runs Libreswan IPsec and is prepared for a host-to-host connection.
Due to the design of the
NetworkManager-libreswan
plugin, Nmstate cannot communicate with other peers that also use this plugin for the same connection.
Procedure
If Libreswan is not yet installed, perform the following steps:
Install the required packages:
dnf install nmstate libreswan NetworkManager-libreswan
# dnf install nmstate libreswan NetworkManager-libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the NetworkManager service:
systemctl restart NetworkManager
# systemctl restart NetworkManager
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize the Network Security Services (NSS) database:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates the database in the
/var/lib/ipsec/nss/
directory.Open the IPsec ports and protocols in the firewall:
firewall-cmd --permanent --add-service="ipsec" firewall-cmd --reload
# firewall-cmd --permanent --add-service="ipsec" # firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Create an RSA key pair:
ipsec newhostkey
# ipsec newhostkey
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
ipsec
utility stores the key pair in the NSS database.Display the Certificate Key Attribute ID (CKAID) on both the left and right peers:
ipsec showhostkey --list
# ipsec showhostkey --list < 1> RSA keyid: <key_id> ckaid: <ckaid>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You require the CKAIDs of both peers in the next steps.
Display the public keys:
On the left peer, enter:
ipsec showhostkey --left --ckaid <ckaid_of_left_peer>
# ipsec showhostkey --left --ckaid <ckaid_of_left_peer> # rsakey AwEAAdKCx leftrsasigkey=0sAwEAAdKCxpc9db48cehzQiQD...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow On the right peer, enter:
ipsec showhostkey --right --ckaid <ckaid_of_right_peer>
# ipsec showhostkey --right --ckaid <ckaid_of_right_peer> # rsakey AwEAAcNWC rightrsasigkey=0sAwEAAcNWCzZO+PR1j8WbO8X...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The commands display the public keys with the corresponding parameters that you must use in the configuration file.
Create a YAML file, for example
~/ipsec-host-to-host-rsa-auth.yml
, with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example include the following:
ikev2: insist
- Defines the modern IKEv2 protocol as the only allowed protocol without fallback to IKEv1. This setting is mandatory in a host-to-host configuration with Nmstate.
left=<ip_address_or_fqdn_of_left_peer>
andright=<ip_address_or_fqdn_of_right_peer>
- Defines the IP address or DNS name of the peers.
leftid=<id>
andrightid=<id>
-
Defines how each peer is identified during the Internet Key Exchange (IKE) negotiation process. This can be an IP address or a literal string. Note that NetworkManager interprets all values other than IP addresses as a literal string and internally adds a leading
@
sign. This requires that the Libreswan peer also uses literal strings as IDs or authentication fails. leftrsasigkey=<public_key>
andrightrsasigkey=<public_key>
-
Specifies the public key of the peers. Use the values displayed by the
ipsec showhostkey
command in a previous step. leftmodecfgclient: false
- Disables dynamic configuration on this host. This setting is mandatory in a host-to-host configuration with Nmstate.
rightsubnet: <ip_address_of_right_peer>/32
- Defines that the host can only access this peer. This setting is mandatory in a host-to-host configuration with Nmstate.
Apply the settings to the system:
nmstatectl apply ~/ipsec-host-to-host-rsa-auth.yml
# nmstatectl apply ~/ipsec-host-to-host-rsa-auth.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the IPsec status:
ipsec status
# ipsec status
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the connection is successfully established, the output contains lines as follows:
Phase 1 of an Internet Key Exchange version 2 (IKEv2) negotiation has been successfully completed:
000 #1: "<connection_name>":500 STATE_V2_ESTABLISHED_IKE_SA (established IKE SA); REKEY in 27935s; REPLACE in 28610s; newest; idle;
000 #1: "<connection_name>":500 STATE_V2_ESTABLISHED_IKE_SA (established IKE SA); REKEY in 27935s; REPLACE in 28610s; newest; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The Security Association (SA) is now ready to negotiate the actual data encryption tunnels, known as child SAs or Phase 2 SAs.
A child SA has been established:
000 #2: "<connection_name>":500 STATE_V2_ESTABLISHED_CHILD_SA (established Child SA); REKEY in 27671s; REPLACE in 28610s; IKE SA #1; idle;
000 #2: "<connection_name>":500 STATE_V2_ESTABLISHED_CHILD_SA (established Child SA); REKEY in 27671s; REPLACE in 28610s; IKE SA #1; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This is the actual tunnel that your data traffic flows through.
Troubleshooting
To display the actual configuration NetworkManager passes to Libreswan, enter:
nmcli connection export <connection_name>
# nmcli connection export <connection_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output can help to identify deviating settings, such as IDs and keys, when you compare them with the Libreswan configuration on the remote host.
Next steps
- 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.13.2. Configuring an IPsec site-to-site VPN with raw RSA key authentication by using nmstatectl Copy linkLink copied to clipboard!
You can use the declarative Nmstate API to configure a site-to-site VPN between two distinct networks, seamlessly linking them across an insecure network. Nmstate ensures that the result matches the configuration file or rolls back the changes.
For authenticating the gateway devices, RSA keys are more secure than pre-shared keys (PSKs) because their asymmetric encryption eliminates the risk of a shared secret. Using RSA keys also simplifies deployment by avoiding the need for a certificate authority (CA), while still providing strong peer-to-peer authentication.
In general, the choice which host is named left and right is arbitrary. However, NetworkManager always uses the term left for the local host and right for the remote host.
Prerequisites
The remote gateway runs Libreswan IPsec and is prepared for a site-to-site connection.
Due to the design of the
NetworkManager-libreswan
plugin, Nmstate cannot communicate with other peers that also use this plugin for the same connection.
Procedure
If Libreswan is not yet installed, perform the following steps:
Install the required packages:
dnf install nmstate libreswan NetworkManager-libreswan
# dnf install nmstate libreswan NetworkManager-libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the NetworkManager service:
systemctl restart NetworkManager
# systemctl restart NetworkManager
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize the Network Security Services (NSS) database:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates the database in the
/var/lib/ipsec/nss/
directory.Open the IPsec ports and protocols in the firewall:
firewall-cmd --permanent --add-service="ipsec" firewall-cmd --reload
# firewall-cmd --permanent --add-service="ipsec" # firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Create an RSA key pair:
ipsec newhostkey
# ipsec newhostkey
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
ipsec
utility stores the key pair in the NSS database.Display the Certificate Key Attribute ID (CKAID) on both the left and right peer:
ipsec showhostkey --list
# ipsec showhostkey --list < 1> RSA keyid: <key_id> ckaid: <ckaid>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You require the CKAIDs of both peers in the following steps.
Display the public keys:
On the left peer, enter:
ipsec showhostkey --left --ckaid <ckaid_of_left_peer>
# ipsec showhostkey --left --ckaid <ckaid_of_left_peer> # rsakey AwEAAdKCx leftrsasigkey=0sAwEAAdKCxpc9db48cehzQiQD...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow On the right peer, enter:
ipsec showhostkey --right --ckaid <ckaid_of_right_peer>
# ipsec showhostkey --right --ckaid <ckaid_of_right_peer> # rsakey AwEAAcNWC rightrsasigkey=0sAwEAAcNWCzZO+PR1j8WbO8X...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The commands display the public keys with the corresponding parameters that you must use in the configuration file.
Create a YAML file, for example
~/ipsec-site-to-site-rsa-auth.yml
, with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example include the following:
ikev2: insist
- Defines the modern IKEv2 protocol as the only allowed protocol without fallback to IKEv1. This setting is mandatory in a site-to-site configuration with Nmstate.
left=<ip_address_or_fqdn_of_left_peer>
andright=<ip_address_or_fqdn_of_right_peer>
- Defines the IP address or DNS name of the peers.
leftid=<id>
andrightid=<id>
-
Defines how each peer is identified during the Internet Key Exchange (IKE) negotiation process. This can be an IP address or a literal string. Note that NetworkManager interprets all values other than IP addresses as a literal string and internally adds a leading
@
sign. This requires that the Libreswan peer also uses literal strings as IDs or authentication fails. leftrsasigkey=<public_key>
andrightrsasigkey=<public_key>
-
Specifies the public key of the peers. Use the values displayed by the
ipsec showhostkey
command in a previous step. leftmodecfgclient: false
- Disables dynamic configuration on this host. This setting is mandatory in a site-to-site configuration with Nmstate.
leftsubnet=<subnet>
andrightsubnet=<subnet>
- Defines subnets in classless inter-domain routing (CIDR) format that are connected through the tunnel.
Enable packet forwarding:
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the settings to the system:
nmstatectl apply ~/ipsec-site-to-site-rsa-auth.yml
# nmstatectl apply ~/ipsec-site-to-site-rsa-auth.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the IPsec status:
ipsec status
# ipsec status
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the connection is successfully established, the output contains lines as follows:
Phase 1 of an Internet Key Exchange version 2 (IKEv2) negotiation has been successfully completed:
000 #1: "<connection_name>":500 STATE_V2_ESTABLISHED_IKE_SA (established IKE SA); REKEY in 27935s; REPLACE in 28610s; newest; idle;
000 #1: "<connection_name>":500 STATE_V2_ESTABLISHED_IKE_SA (established IKE SA); REKEY in 27935s; REPLACE in 28610s; newest; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The Security Association (SA) is now ready to negotiate the actual data encryption tunnels, known as child SAs or Phase 2 SAs.
A child SA has been established:
000 #2: "<connection_name>":500 STATE_V2_ESTABLISHED_CHILD_SA (established Child SA); REKEY in 27671s; REPLACE in 28610s; IKE SA #1; idle;
000 #2: "<connection_name>":500 STATE_V2_ESTABLISHED_CHILD_SA (established Child SA); REKEY in 27671s; REPLACE in 28610s; IKE SA #1; idle;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This is the actual tunnel that your data traffic flows through.
- From a client in the local subnet, ping a client in the remote subnet.
Troubleshooting
To display the actual configuration NetworkManager passes to Libreswan, enter:
nmcli connection export <connection_name>
# nmcli connection export <connection_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output can help to identify deviating settings, such as IDs and keys, when you compare them with the Libreswan configuration on the remote host.
Next steps
- 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.13.3. Configuring a client to connect to an IPsec VPN gateway by using nmstatectl Copy linkLink copied to clipboard!
To access resources on a remote private network, users must first configure an IPsec VPN connection. By using Nmstate, you can create the connection with an existing Libreswan IPsec gateway by using a declarative API.
In general, the choice of which host is named left and right is arbitrary. However, NetworkManager always uses the term left for the local host and right for the remote host.
Prerequisites
The remote gateway runs Libreswan IPsec and is prepared for a host-to-site connection with certificate-based authentication.
Due to the design of the
NetworkManager-libreswan
plugin, Nmstate cannot communicate with other peers that also use this plugin for the same connection.The PKCS#12 file
~/file.p12
exists on the client with the following contents:- The private key of the user
- The user certificate
- The CA certificate
- If required, intermediate certificates
For details about creating a private key and certificate signing request (CSR), as well as about requesting a certificate from a CA, see your CA’s documentation.
-
The Extended Key Usage (EKU) in the certificate is set to
TLS Web Client Authentication
.
Procedure
If Libreswan is not yet installed:
Install the required packages:
dnf install nmstate libreswan NetworkManager-libreswan
# dnf install nmstate libreswan NetworkManager-libreswan
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the NetworkManager service:
systemctl restart NetworkManager
# systemctl restart NetworkManager
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize the Network Security Services (NSS) database:
ipsec initnss
# ipsec initnss
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates the database in the
/var/lib/ipsec/nss/
directory.Open the IPsec ports and protocols in the firewall:
firewall-cmd --permanent --add-service="ipsec" firewall-cmd --reload
# firewall-cmd --permanent --add-service="ipsec" # firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Import the PKCS #12 file into the NSS database:
ipsec import ~/file.p12
# ipsec import ~/file.p12 Enter password for PKCS12 file: <password> pk12util: PKCS12 IMPORT SUCCESSFUL correcting trust bits for Example-CA
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display the nicknames of the user and CA certificates:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You require this information in the Nmstate YAML file.
Create a YAML file, for example,
~/ipsec-host-to-site-cert-auth.yml
, with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example include the following:
ikev2: insist
- Defines the modern IKEv2 protocol as the only allowed protocol without fallback to IKEv1. This setting is mandatory in a host-to-site configuration with Nmstate.
left=<ip_address_or_fqdn_of_left_peer>
andright=<ip_address_or_fqdn_of_right_peer>
- Defines the IP address or DNS name of the peers.
leftid=%fromcert
andrightid=%fromcert
- Configures Libreswan to retrieve the identity from the distinguished name (DN) field of the certificate.
leftcert="<server_certificate_nickname>"
- Sets the nickname of the server’s certificate used in the NSS database.
rightsubnet: <subnet>
- Defines the subnet in classless inter-domain routing (CIDR) format that is connected to the gateway.
Apply the settings to the system:
nmstatectl apply ~/ipsec-host-to-site-cert-auth.yml
# nmstatectl apply ~/ipsec-host-to-site-cert-auth.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
- Establish a connection to a host in the remote network or ping it.
Troubleshooting
To display the actual configuration NetworkManager passes to Libreswan, enter:
nmcli connection export <connection_name>
# nmcli connection export <connection_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output can help to identify deviating settings, such as IDs and keys, when you compare them with the Libreswan configuration on the remote host.
Next steps
- 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.14. Troubleshooting IPsec configurations Copy linkLink copied to clipboard!
Diagnosing IPsec configuration failures can be challenging, because issues can be caused by mismatched settings, firewall rules, and kernel-level errors. The following information provides a systematic approach to resolving common problems with IPsec VPN connections.
6.14.1. Basic connection issues Copy linkLink copied to clipboard!
Problems with VPN connections often occur due to mismatched configurations between the endpoints.
To confirm that an IPsec connection is established, enter:
ipsec trafficstatus
# 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=198.51.100.1/32
For a successful connection, the command shows an entry with the connection’s name and details. If the output is empty, the tunnel is not established.
6.14.3. Mismatched Configurations Copy linkLink copied to clipboard!
VPN connections fail if the endpoints are not configured with matching Internet Key Exchange (IKE) versions, algorithms, IP address ranges, or pre-shared keys (PSK). If you identify a mismatch, you must align the settings on both endpoints to resolve the issue.
- Remote Peer Not Running IKE/IPsec
If the connection was refused, an ICMP error is displayed:
ipsec up vpn.example.com
# 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 Copied! Toggle word wrap Toggle overflow - Mismatched IKE Algorithms
The connection fails with a
NO_PROPOSAL_CHOSEN
notification during the initial setup:ipsec up vpn.example.com
# 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 Copied! Toggle word wrap Toggle overflow - Mismatched IPsec Algorithms
The connection fails with a
NO_PROPOSAL_CHOSEN
error after the initial exchange:ipsec up vpn.example.com
# 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 Copied! Toggle word wrap Toggle overflow - Mismatched IP Address Ranges (IKEv2)
The remote peer responds with a
TS_UNACCEPTABLE
error:ipsec up vpn.example.com
# 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 Copied! Toggle word wrap Toggle overflow - Mismatched IP Address Ranges (IKEv1)
The connection times out during quick mode, with a message indicating the peer did not accept the proposal:
ipsec up vpn.example.com
# 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 Copied! Toggle word wrap Toggle overflow - Mismatched PSK (IKEv2)
The peer rejects the connection with an
AUTHENTICATION_FAILED
error:ipsec up vpn.example.com
# 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 Copied! Toggle word wrap Toggle overflow - Mismatched PSK (IKEv1)
The hash payload does not match, making the IKE message unreadable and resulting in an
INVALID_HASH_INFORMATION
error:ipsec up vpn.example.com
# ipsec up vpn.example.com ... 002 "vpn.example.com" #1: IKE SA authentication request rejected by peer: AUTHENTICATION_FAILED
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
6.14.4. MTU issues Copy linkLink copied to clipboard!
Diagnose intermittent IPsec connection failures caused by Maximum Transmission Unit (MTU) issues. Encryption increases packet size, leading to fragmentation and lost data when packets exceed the network’s MTU, often seen with larger data transfers.
A common symptom is that small packets, for example pings, work correctly, but larger packets, such as an SSH session, freeze after the login. To fix the problem, lower the MTU for the tunnel by adding the mtu=1400
option to the configuration file.
6.14.5. NAT conflicts Copy linkLink copied to clipboard!
Resolve NAT conflicts that occur when an IPsec host also acts as a NAT router. Incorrect NAT application can translate source IP addresses before encryption, causing packets to be sent unencrypted over the network.
For example, if the source IP address of the packet is translated by a masquerade rule before IPsec encryption is applied, the packet’s source no longer matches the IPsec policy, and Libreswan sends it unencrypted over the network.
To solve this problem, add a firewall rule that excludes traffic between the IPsec subnets from NAT. This rule should be inserted at the beginning of the POSTROUTING
chain to ensure it is processed before the general NAT rule.
Example 6.1. Solution by using the nftables
framework
The following example uses nftables
to set up a basic NAT environment that excludes traffic between the 192.0.2.0/24 and 198.51.100.0/24 subnets from address translation:
nft add table ip nat nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; } nft add rule ip nat postrouting ip saddr 192.0.2.0/24 ip daddr 198.51.100.0/24 return
# nft add table ip nat
# nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
# nft add rule ip nat postrouting ip saddr 192.0.2.0/24 ip daddr 198.51.100.0/24 return
6.14.6. Kernel-level IPsec issues Copy linkLink copied to clipboard!
Troubleshoot kernel-level IPsec issues when a VPN tunnel appears established but no traffic flows. In this case, inspect the kernel’s IPsec state to check if the tunnel policies and cryptographic keys were correctly installed.
This process involves checking two components:
- The Security Policy Database (SPD): The rule that instructs the kernel what traffic to encrypt.
- The Security Association Database (SAD): The keys that instruct the kernel how to encrypt that traffic.
First, check if the correct policy exists in the SPD:
ip xfrm policy
# ip xfrm policy
src 192.0.2.1/32 dst 10.0.0.0/8
dir out priority 666 ptype main
tmpl src 198.51.100.13 dst 203.0.113.22
proto esp reqid 16417 mode tunnel
The output should contain the policies matching your leftsubnet
and rightsubnet
parameters with both in and out directions. If you do not see a policy for your traffic, Libreswan failed to create the kernel rule, and traffic is not encrypted.
If the policy exists, check if it has a corresponding set of keys in the SAD:
ip xfrm state
# ip xfrm state
src 203.0.113.22 dst 198.51.100.13
proto esp spi 0xa78b3fdb reqid 16417 mode tunnel
auth-trunc hmac(sha1) 0x3763cd3b... 96
enc cbc(aes) 0xd9dba399...
This command displays private cryptographic keys. Do not share this output, because attackers can use it to decrypt your VPN traffic.
If a policy exists but you see no corresponding state with the same reqid
, it typically means the Internet Key Exchange (IKE) negotiation failed. The two VPN endpoints could not agree on a set of keys.
For more detailed diagnostics, use the -s
option with either of the commands. This option adds traffic counters, which can help you identify if the kernel processes packets by a specific rule.
6.14.7. Kernel IPsec subsystem bugs Copy linkLink copied to clipboard!
Under rare conditions, a defect in the IPsec subsystem of the kernel can cause it to lose synchronization with the Internet Key Exchange (IKE) user-space daemon. This de-synchronization can result in discrepancies between negotiated security associations and the actual enforcement of IPsec policies within the kernel, potentially disrupting secure network communication. To check for kernel-level errors, display the transform (XFRM) statistics:
cat /proc/net/xfrm_stat
# cat /proc/net/xfrm_stat
If any of the counters in the output, such as XfrmInError
, show a nonzero value, it indicates a problem with the kernel subsystem. In this case, open a support case, and attach the output of the command along with the corresponding IKE logs.
6.14.8. Displaying Libreswan logs Copy linkLink copied to clipboard!
Display Libreswan logs to diagnose and troubleshoot IPsec service events and issues. Access the journal for the ipsec
service to gain insights into connection status and potential problems.
To display the journal, enter:
journalctl -xeu ipsec
# journalctl -xeu ipsec
If the default logging level does not provide enough details, enable comprehensive debug logging by adding the following settings to the config setup
section in the /etc/ipsec.conf
file:
plutodebug=all logfile=/var/log/pluto.log
plutodebug=all
logfile=/var/log/pluto.log
Because debug logging can produce many entries, redirecting the messages to a dedicated log file can prevent the journald
and systemd
services from rate-limiting the messages.
Chapter 7. Using MACsec to encrypt layer-2 traffic in the same physical network Copy linkLink copied to clipboard!
You can use MACsec to secure the communication between two devices (point-to-point). For example, your branch office is connected over a Metro-Ethernet connection with the central office, you can configure MACsec on the two hosts that connect the offices to increase the security.
7.1. How MACsec increases security Copy linkLink copied to clipboard!
Media Access Control security (MACsec) is a layer-2 protocol that secures different traffic types over the Ethernet links, including:
- Dynamic host configuration protocol (DHCP)
- address resolution protocol (ARP)
- IPv4 and IPv6 traffic
- Any traffic over IP such as TCP or UDP
MACsec encrypts and authenticates all traffic in LANs, by default with the GCM-AES-128 algorithm, and uses a pre-shared key to establish the connection between the participant hosts. To change the pre-shared key, you must update the NM configuration on all network hosts that use MACsec.
A MACsec connection uses an Ethernet device, such as an Ethernet network card, VLAN, or tunnel device, as a parent. You can either set an IP configuration only on the MACsec device to communicate with other hosts only by using the encrypted connection, or you can also set an IP configuration on the parent device. In the latter case, you can use the parent device to communicate with other hosts using an unencrypted connection and the MACsec device for encrypted connections.
MACsec does not require any special hardware. For example, you can use any switch, except if you want to encrypt traffic only between a host and a switch. In this scenario, the switch must also support MACsec.
In other words, you can configure MACsec for two common scenarios:
- Host-to-host
- Host-to-switch and switch-to-other-hosts
You can use MACsec only between hosts being in the same physical or virtual LAN.
Using the MACsec security standard for securing communication at the link layer, also known as layer 2 of the Open Systems Interconnection (OSI) model provides the following notable benefits:
- Encryption at layer 2 eliminates the need for encrypting individual services at layer 7. This reduces the overhead associated with managing a large number of certificates for each endpoint on each host.
- Point-to-point security between directly connected network devices such as routers and switches.
- No changes needed for applications and higher-layer protocols.
7.2. Configuring a MACsec connection by using nmcli Copy linkLink copied to clipboard!
You can use the nmcli
utility to configure Ethernet interfaces to use MACsec. For example, you can create a MACsec connection between two hosts that are connected over Ethernet.
Procedure
On the first host on which you configure MACsec:
Create the connectivity association key (CAK) and connectivity-association key name (CKN) for the pre-shared key:
Create a 16-byte hexadecimal CAK:
dd if=/dev/urandom count=16 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"'
# dd if=/dev/urandom count=16 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"' 50b71a8ef0bd5751ea76de6d6c98c03a
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a 32-byte hexadecimal CKN:
dd if=/dev/urandom count=32 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"'
# dd if=/dev/urandom count=32 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"' f2b4297d39da7330910a74abc0449feb45b5c0b9fc23df1430e1898fcf1c4550
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
- On both hosts you want to connect over a MACsec connection:
Create the MACsec connection:
nmcli connection add type macsec con-name macsec0 ifname macsec0 connection.autoconnect yes macsec.parent enp1s0 macsec.mode psk macsec.mka-cak 50b71a8ef0bd5751ea76de6d6c98c03a macsec.mka-ckn f2b4297d39da7330910a74abc0449feb45b5c0b9fc23df1430e1898fcf1c4550
# nmcli connection add type macsec con-name macsec0 ifname macsec0 connection.autoconnect yes macsec.parent enp1s0 macsec.mode psk macsec.mka-cak 50b71a8ef0bd5751ea76de6d6c98c03a macsec.mka-ckn f2b4297d39da7330910a74abc0449feb45b5c0b9fc23df1430e1898fcf1c4550
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use the CAK and CKN generated in the previous step in the
macsec.mka-cak
andmacsec.mka-ckn
parameters. The values must be the same on every host in the MACsec-protected network.Configure the IP settings on the MACsec connection.
Configure the
IPv4
settings. For example, to set a staticIPv4
address, network mask, default gateway, and DNS server to themacsec0
connection, enter:nmcli connection modify macsec0 ipv4.method manual ipv4.addresses '192.0.2.1/24' ipv4.gateway '192.0.2.254' ipv4.dns '192.0.2.253'
# nmcli connection modify macsec0 ipv4.method manual ipv4.addresses '192.0.2.1/24' ipv4.gateway '192.0.2.254' ipv4.dns '192.0.2.253'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Configure the
IPv6
settings. For example, to set a staticIPv6
address, network mask, default gateway, and DNS server to themacsec0
connection, enter:nmcli connection modify macsec0 ipv6.method manual ipv6.addresses '2001:db8:1::1/32' ipv6.gateway '2001:db8:1::fffe' ipv6.dns '2001:db8:1::fffd'
# nmcli connection modify macsec0 ipv6.method manual ipv6.addresses '2001:db8:1::1/32' ipv6.gateway '2001:db8:1::fffe' ipv6.dns '2001:db8:1::fffd'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Activate the connection:
nmcli connection up macsec0
# nmcli connection up macsec0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the traffic is encrypted:
tcpdump -nn -i enp1s0
# tcpdump -nn -i enp1s0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Display the unencrypted traffic:
tcpdump -nn -i macsec0
# tcpdump -nn -i macsec0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display MACsec statistics:
ip macsec show
# ip macsec show
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display individual counters for each type of protection: integrity-only (encrypt off) and encryption (encrypt on)
ip -s macsec show
# ip -s macsec show
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
7.3. Configuring a MACsec connection by using nmstatectl Copy linkLink copied to clipboard!
You can configure Ethernet interfaces to use MACsec through the nmstatectl
utility in a declarative way. For example, in a YAML file, you describe the desired state of your network, which is supposed to have a MACsec connection between two hosts connected over Ethernet. The nmstatectl
utility interprets the YAML file and deploys persistent and consistent network configuration across the hosts.
Prerequisites
- A physical or virtual Ethernet Network Interface Controller (NIC) exists in the server configuration.
-
The
nmstate
package is installed.
Procedure
On the first host on which you configure MACsec, create the connectivity association key (CAK) and connectivity-association key name (CKN) for the pre-shared key:
Create a 16-byte hexadecimal CAK:
dd if=/dev/urandom count=16 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"'
# dd if=/dev/urandom count=16 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"' 50b71a8ef0bd5751ea76de6d6c98c03a
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a 32-byte hexadecimal CKN:
dd if=/dev/urandom count=32 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"'
# dd if=/dev/urandom count=32 bs=1 2> /dev/null | hexdump -e '1/2 "%04x"' f2b4297d39da7330910a74abc0449feb45b5c0b9fc23df1430e1898fcf1c4550
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
On both hosts that you want to connect over a MACsec connection, complete the following steps:
Create a YAML file, for example
create-macsec-connection.yml
, with the following settings:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Use the CAK and CKN generated in the previous step in the
mka-cak
andmka-ckn
parameters. The values must be the same on every host in the MACsec-protected network. Optional: In the same YAML configuration file, you can also configure the following settings:
-
A static IPv4 address -
192.0.2.1
with the/32
subnet mask -
A static IPv6 address -
2001:db8:1::1
with the/64
subnet mask -
An IPv4 default gateway -
192.0.2.2
-
An IPv4 DNS server -
192.0.2.200
-
An IPv6 DNS server -
2001:db8:1::ffbb
-
A DNS search domain -
example.com
-
A static IPv4 address -
Apply the settings to the system:
nmstatectl apply create-macsec-connection.yml
# nmstatectl apply create-macsec-connection.yml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the current state in YAML format:
nmstatectl show macsec0
# nmstatectl show macsec0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the traffic is encrypted:
tcpdump -nn -i enp0s1
# tcpdump -nn -i enp0s1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Display the unencrypted traffic:
tcpdump -nn -i macsec0
# tcpdump -nn -i macsec0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display MACsec statistics:
ip macsec show
# ip macsec show
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display individual counters for each type of protection: integrity-only (encrypt off) and encryption (encrypt on)
ip -s macsec show
# ip -s macsec show
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 8. Securing network services Copy linkLink copied to clipboard!
Red Hat Enterprise Linux supports many different types of network servers. Their network services can expose the system security to risks of various types of attacks, such as denial of service attacks (DoS), distributed denial of service attacks (DDoS), script vulnerability attacks, and buffer overflow attacks.
To increase the system security against attacks, it is important to monitor active network services that you use. For example, when a network service is running on a machine, its daemon listens for connections on network ports, and this can reduce the security. To limit exposure to attacks over the network, all services that are unused should be turned off.
8.1. Securing the rpcbind service Copy linkLink copied to clipboard!
The rpcbind
service is a dynamic port-assignment daemon for remote procedure calls (RPC) services such as Network Information Service (NIS) and Network File System (NFS). Because it has weak authentication mechanisms and can assign a wide range of ports for the services it controls, it is important to secure rpcbind
.
You can secure rpcbind
by restricting access to all networks and defining specific exceptions using firewall rules on the server.
-
The
rpcbind
service is required onNFSv3
servers. -
The
rpcbind
service is not required onNFSv4
.
Prerequisites
-
The
rpcbind
package is installed. -
The
firewalld
package is installed and the service is running.
Procedure
Add firewall rules, for example:
Limit TCP connection and accept packages only from the
192.168.0.0/24
host via the111
port:firewall-cmd --add-rich-rule='rule family="ipv4" port port="111" protocol="tcp" source address="192.168.0.0/24" invert="True" drop'
# firewall-cmd --add-rich-rule='rule family="ipv4" port port="111" protocol="tcp" source address="192.168.0.0/24" invert="True" drop'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Limit TCP connection and accept packages only from local host via the
111
port:firewall-cmd --add-rich-rule='rule family="ipv4" port port="111" protocol="tcp" source address="127.0.0.1" accept'
# firewall-cmd --add-rich-rule='rule family="ipv4" port port="111" protocol="tcp" source address="127.0.0.1" accept'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Limit UDP connection and accept packages only from the
192.168.0.0/24
host via the111
port:firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="111" protocol="udp" source address="192.168.0.0/24" invert="True" drop'
# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="111" protocol="udp" source address="192.168.0.0/24" invert="True" drop'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow To make the firewall settings permanent, use the
--permanent
option when adding firewall rules.
Reload the firewall to apply the new rules:
firewall-cmd --reload
# firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
List the firewall rules:
firewall-cmd --list-rich-rule
# firewall-cmd --list-rich-rule rule family="ipv4" port port="111" protocol="tcp" source address="192.168.0.0/24" invert="True" drop rule family="ipv4" port port="111" protocol="tcp" source address="127.0.0.1" accept rule family="ipv4" port port="111" protocol="udp" source address="192.168.0.0/24" invert="True" drop
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.2. Securing the rpc.mountd service Copy linkLink copied to clipboard!
The rpc.mountd
daemon implements the server side of the NFS mount protocol. The NFS mount protocol is used by NFS version 3 (RFC 1813).
You can secure the rpc.mountd
service by adding firewall rules to the server. You can restrict access to all networks and define specific exceptions using firewall rules.
Prerequisites
-
The
rpc.mountd
package is installed. -
The
firewalld
package is installed and the service is running.
Procedure
Add firewall rules to the server, for example:
Accept
mountd
connections from the192.168.0.0/24
host:firewall-cmd --add-rich-rule 'rule family="ipv4" service name="mountd" source address="192.168.0.0/24" invert="True" drop'
# firewall-cmd --add-rich-rule 'rule family="ipv4" service name="mountd" source address="192.168.0.0/24" invert="True" drop'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Accept
mountd
connections from the local host:firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="127.0.0.1" service name="mountd" accept'
# firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="127.0.0.1" service name="mountd" accept'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow To make the firewall settings permanent, use the
--permanent
option when adding firewall rules.
Reload the firewall to apply the new rules:
firewall-cmd --reload
# firewall-cmd --reload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
List the firewall rules:
firewall-cmd --list-rich-rule
# firewall-cmd --list-rich-rule rule family="ipv4" service name="mountd" source address="192.168.0.0/24" invert="True" drop rule family="ipv4" source address="127.0.0.1" service name="mountd" accept
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.3. Securing the NFS service Copy linkLink copied to clipboard!
You can secure Network File System version 4 (NFSv4) by authenticating and encrypting all file system operations using Kerberos. When using NFSv4 with Network Address Translation (NAT) or a firewall, you can turn off the delegations by modifying the /etc/default/nfs
file. Delegation is a technique by which the server delegates the management of a file to a client. In contrast, NFSv3 do not use Kerberos for locking and mounting files.
The NFS service sends the traffic using TCP in all versions of NFS. The service supports Kerberos user and group authentication, as part of the RPCSEC_GSS
kernel module.
NFS allows remote hosts to mount file systems over a network and interact with those file systems as if they are mounted locally. You can merge the resources on centralized servers and additionally customize NFS mount options in the /etc/nfsmount.conf
file when sharing the file systems.
8.3.1. Export options for securing an NFS server Copy linkLink copied to clipboard!
The NFS server determines a list structure of directories and hosts about which file systems to export to which hosts in the /etc/exports
file.
You can use the following export options on the /etc/exports
file:
ro
- Exports the NFS volume as read-only.
rw
-
Allows read and write requests on the NFS volume. Use this option cautiously because allowing write access increases the risk of attacks. If your scenario requires mounting the directories with the
rw
option, make sure they are not writable for all users to reduce possible risks. root_squash
-
Maps requests from
uid
/gid
0 to the anonymousuid
/gid
. This does not apply to any otheruids
orgids
that might be equally sensitive, such as thebin
user or thestaff
group. no_root_squash
-
Turns off root squashing. By default, NFS shares change the
root
user to thenobody
user, which is an unprivileged user account. This changes the owner of all theroot
created files tonobody
, which prevents the uploading of programs with thesetuid
bit set. When using theno_root_squash
option, remote root users can change any file on the shared file system and leave applications infected by trojans for other users. secure
-
Restricts exports to reserved ports. By default, the server allows client communication only through reserved ports. However, it is easy for anyone to become a
root
user on a client on many networks, so it is rarely safe for the server to assume that communication through a reserved port is privileged. Therefore the restriction to reserved ports is of limited value; it is better to rely on Kerberos, firewalls, and restriction of exports to particular clients.
Extra spaces in the syntax of the /etc/exports
file can lead to major changes in the configuration.
In the following example, the /tmp/nfs/
directory is shared with the bob.example.com
host and has read and write permissions.
/tmp/nfs/ bob.example.com(rw)
/tmp/nfs/ bob.example.com(rw)
The following example is the same as the previous one but shares the same directory to the bob.example.com
host with read-only permissions and shares it to the world with read and write permissions due to a single space character after the hostname.
/tmp/nfs/ bob.example.com (rw)
/tmp/nfs/ bob.example.com (rw)
You can check the shared directories on your system by entering the showmount -e <hostname>
command.
Additionally, consider the following best practices when exporting an NFS server:
- Exporting home directories is a risk because some applications store passwords in plain text or in a weakly encrypted format. You can reduce the risk by reviewing and improving the application code.
- Some users do not set passwords on SSH keys which again leads to risks with home directories. You can reduce these risks by enforcing the use of passwords or using Kerberos.
-
Restrict the NFS exports only to required clients. Use the
showmount -e
command on the NFS server to review what the server is exporting. Do not export anything that is not specifically required. - Do not allow unnecessary users to log in to a server to reduce the risk of attacks. You can periodically check who and what can access the server.
Export an entire file system because exporting a subdirectory of a file system is not secure. An attacker might access the unexported part of a partially-exported file system.
8.3.2. Mount options for securing an NFS client Copy linkLink copied to clipboard!
You can pass the following options to the mount
command to increase the security of NFS-based clients:
nosuid
-
Use the
nosuid
option to disable theset-user-identifier
orset-group-identifier
bits. This prevents remote users from gaining higher privileges by running asetuid
program and you can use this option opposite tosetuid
option. noexec
-
Use the
noexec
option to disable all executable files on the client. Use this to prevent users from accidentally executing files placed in the shared file system. nodev
-
Use the
nodev
option to prevent the client’s processing of device files as a hardware device. resvport
-
Use the
resvport
option to restrict communication to a reserved port and you can use a privileged source port to communicate with the server. The reserved ports are reserved for privileged users and processes such as theroot
user. sec
-
Use the
sec
option on the NFS server to choose the RPCGSS security flavor for accessing files on the mount point. Valid security flavors arenone
,sys
,krb5
,krb5i
, andkrb5p
.
The MIT Kerberos libraries provided by the krb5-libs
package do not support the Data Encryption Standard (DES) algorithm in new deployments. DES is deprecated and disabled by default in Kerberos libraries because of security and compatibility reasons. Use newer and more secure algorithms instead of DES, unless your environment requires DES for compatibility reasons.
8.3.3. Securing NFS with firewall Copy linkLink copied to clipboard!
To secure the firewall on an NFS server, keep only the required ports open. Do not use the NFS connection port numbers for any other service.
Prerequisites
-
The
nfs-utils
package is installed. -
The
firewalld
package is installed and running.
Procedure
-
On NFSv4, the firewall must open TCP port
2049
. On NFSv3, open four additional ports with
2049
:rpcbind
service assigns the NFS ports dynamically, which might cause problems when creating firewall rules. To simplify this process, use the/etc/nfs.conf
file to specify which ports to use:-
Set TCP and UDP port for
mountd
(rpc.mountd
) in the[mountd]
section inport=<value>
format. -
Set TCP and UDP port for
statd
(rpc.statd
) in the[statd]
section inport=<value>
format.
-
Set TCP and UDP port for
Set the TCP and UDP port for the NFS lock manager (
nlockmgr
) in the/etc/nfs.conf
file:-
Set TCP port for
nlockmgr
(rpc.statd
) in the[lockd]
section inport=value
format. Alternatively, you can use thenlm_tcpport
option in the/etc/modprobe.d/lockd.conf
file. -
Set UDP port for
nlockmgr
(rpc.statd
) in the[lockd]
section inudp-port=value
format. Alternatively, you can use thenlm_udpport
option in the/etc/modprobe.d/lockd.conf
file.
-
Set TCP port for
Verification
List the active ports and RPC programs on the NFS server:
rpcinfo -p
$ rpcinfo -p
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.4. Securing the FTP service Copy linkLink copied to clipboard!
You can use the File Transfer Protocol (FTP) to transfer files over a network. Because all FTP transactions with the server, including user authentication, are unencrypted, make sure it is configured securely.
Red Hat Enterprise Linux provides two FTP servers:
- Red Hat Content Accelerator (
tux
) - A kernel-space web server with FTP capabilities.
- Very Secure FTP Daemon (
vsftpd
) - A standalone, security-oriented implementation of the FTP service.
The following security guidelines are for setting up the vsftpd
FTP service.
8.4.1. Securing the FTP greeting banner Copy linkLink copied to clipboard!
When a user connects to the FTP service, FTP shows a greeting banner, which by default includes version information. Attackers might use this information to identify weaknesses in the system. You can hide this information by changing the default banner.
You can define a custom banner by editing the /etc/banners/ftp.msg
file to either directly include a single-line message, or to refer to a separate file, which can contain a multi-line message.
Procedure
To define a single line message, add the following option to the
/etc/vsftpd/vsftpd.conf
file:ftpd_banner=Hello, all activity on ftp.example.com is logged.
ftpd_banner=Hello, all activity on ftp.example.com is logged.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow To define a message in a separate file:
Create a
.msg
file which contains the banner message, for example/etc/banners/ftp.msg
:######### Hello, all activity on ftp.example.com is logged. #########
######### Hello, all activity on ftp.example.com is logged. #########
Copy to Clipboard Copied! Toggle word wrap Toggle overflow To simplify the management of multiple banners, place all banners into the
/etc/banners/
directory.Add the path to the banner file to the
banner_file
option in the/etc/vsftpd/vsftpd.conf
file:banner_file=/etc/banners/ftp.msg
banner_file=/etc/banners/ftp.msg
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the modified banner:
ftp localhost
$ ftp localhost Trying ::1… Connected to localhost (::1). Hello, all activity on ftp.example.com is logged.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.4.2. Preventing anonymous access and uploads in FTP Copy linkLink copied to clipboard!
By default, installing the vsftpd
package creates the /var/ftp/
directory and a directory tree for anonymous users with read-only permissions on the directories. Because anonymous users can access the data, do not store sensitive data in these directories.
To increase the security of the system, you can configure the FTP server to allow anonymous users to upload files to a specific directory and prevent anonymous users from reading data. In the following procedure, the anonymous user must be able to upload files in the directory owned by the root
user but not change it.
Procedure
Create a write-only directory in the
/var/ftp/pub/
directory:mkdir /var/ftp/pub/upload chmod 730 /var/ftp/pub/upload ls -ld /var/ftp/pub/upload
# mkdir /var/ftp/pub/upload # chmod 730 /var/ftp/pub/upload # ls -ld /var/ftp/pub/upload drwx-wx---. 2 root ftp 4096 Nov 14 22:57 /var/ftp/pub/upload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add the following lines to the
/etc/vsftpd/vsftpd.conf
file:anon_upload_enable=YES anonymous_enable=YES
anon_upload_enable=YES anonymous_enable=YES
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Optional: If your system has SELinux enabled and enforcing, enable SELinux boolean attributes
allow_ftpd_anon_write
andallow_ftpd_full_access
.
Allowing anonymous users to read and write in directories might lead to the server becoming a repository for stolen software.
8.4.3. Securing user accounts for FTP Copy linkLink copied to clipboard!
FTP transmits usernames and passwords unencrypted over insecure networks for authentication. You can improve the security of FTP by denying system users access to the server from their user accounts.
Perform as many of the following steps as applicable for your configuration.
Procedure
Disable all user accounts in the
vsftpd
server, by adding the following line to the/etc/vsftpd/vsftpd.conf
file:local_enable=NO
local_enable=NO
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Disable FTP access for specific accounts or specific groups of accounts, such as the
root
user and users withsudo
privileges, by adding the usernames to the/etc/pam.d/vsftpd
PAM configuration file. -
Disable user accounts, by adding the usernames to the
/etc/vsftpd/ftpusers
file.
8.5. Securing HTTP servers Copy linkLink copied to clipboard!
8.5.1. Security enhancements in httpd.conf Copy linkLink copied to clipboard!
You can enhance the security of the Apache HTTP server by configuring security options in the /etc/httpd/conf/httpd.conf
file.
Always verify that all scripts running on the system work correctly before putting them into production.
Ensure that only the root
user has write permissions to any directory containing scripts or Common Gateway Interfaces (CGI). To change the directory ownership to root
with write permissions, enter the following commands:
chown root <directory_name> chmod 755 <directory_name>
# chown root <directory_name>
# chmod 755 <directory_name>
In the /etc/httpd/conf/httpd.conf
file, you can configure the following options:
FollowSymLinks
- This directive is enabled by default and follows symbolic links in the directory.
Indexes
- This directive is enabled by default. Disable this directive to prevent visitors from browsing files on the server.
UserDir
-
This directive is disabled by default because it can confirm the presence of a user account on the system. To activate user directory browsing for all user directories other than
/root/
, use theUserDir enabled
andUserDir disabled
root directives. To add users to the list of disabled accounts, add a space-delimited list of users on theUserDir disabled
line. ServerTokens
This directive controls the server response header field which is sent back to clients. You can use the following parameters to customize the information:
ServerTokens Full
Provides all available information such as web server version number, server operating system details, installed Apache modules, for example:
Apache/2.4.37 (Red Hat Enterprise Linux) MyMod/1.2
Apache/2.4.37 (Red Hat Enterprise Linux) MyMod/1.2
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Full-Release
Provides all available information with release versions, for example:
Apache/2.4.37 (Red Hat Enterprise Linux) (Release 41.module+el8.5.0+11772+c8e0c271)
Apache/2.4.37 (Red Hat Enterprise Linux) (Release 41.module+el8.5.0+11772+c8e0c271)
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Prod / ServerTokens ProductOnly
Provides the web server name, for example:
Apache
Apache
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Major
Provides the web server major release version, for example:
Apache/2
Apache/2
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Minor
Provides the web server minor release version, for example:
Apache/2.4
Apache/2.4
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens Min
/ServerTokens Minimal
Provides the web server minimal release version, for example:
Apache/2.4.37
Apache/2.4.37
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ServerTokens OS
Provides the web server release version and operating system, for example:
Apache/2.4.37 (Red Hat Enterprise Linux)
Apache/2.4.37 (Red Hat Enterprise Linux)
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use the
ServerTokens Prod
option to reduce the risk of attackers gaining any valuable information about your system.
Do not remove the IncludesNoExec
directive. By default, the Server Side Includes (SSI) module cannot execute commands. Changing this can allow an attacker to enter commands on the system.
Removing httpd modules
You can remove the httpd
modules to limit the functionality of the HTTP server. To do so, edit configuration files in the /etc/httpd/conf.modules.d/
or /etc/httpd/conf.d/
directory. For example, to remove the proxy module:
echo '# All proxy modules disabled' > /etc/httpd/conf.modules.d/00-proxy.conf
echo '# All proxy modules disabled' > /etc/httpd/conf.modules.d/00-proxy.conf
8.5.2. Securing the Nginx server configuration Copy linkLink copied to clipboard!
Nginx is a high-performance HTTP and proxy server. You can harden your Nginx configuration with the following configuration options.
Procedure
To disable version strings, modify the
server_tokens
configuration option:server_tokens off;
server_tokens off;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This option stops displaying additional details such as server version number. This configuration displays only the server name in all requests served by Nginx, for example:
curl -sI http://localhost | grep Server
$ curl -sI http://localhost | grep Server Server: nginx
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add extra security headers that mitigate certain known web application vulnerabilities in specific
/etc/nginx/
conf files:For example, the
X-Frame-Options
header option denies any page outside of your domain to frame any content served by Nginx, mitigating clickjacking attacks:add_header X-Frame-Options "SAMEORIGIN";
add_header X-Frame-Options "SAMEORIGIN";
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For example, the
x-content-type
header prevents MIME-type sniffing in certain older browsers:add_header X-Content-Type-Options nosniff;
add_header X-Content-Type-Options nosniff;
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For example, the
X-XSS-Protection
header enables Cross-Site Scripting (XSS) filtering, which prevents browsers from rendering potentially malicious content included in a response by Nginx:add_header X-XSS-Protection "1; mode=block";
add_header X-XSS-Protection "1; mode=block";
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
You can limit the services exposed to the public and limit what they do and accept from the visitors, for example:
limit_except GET { allow 192.168.1.0/32; deny all; }
limit_except GET { allow 192.168.1.0/32; deny all; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The snippet will limit access to all methods except
GET
andHEAD
.You can disable HTTP methods, for example:
Allow GET, PUT, POST; return "405 Method Not Allowed" for all others.
# Allow GET, PUT, POST; return "405 Method Not Allowed" for all others. if ( $request_method !~ ^(GET|PUT|POST)$ ) { return 405; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - You can configure SSL to protect the data served by your Nginx web server, consider serving it over HTTPS only. Furthermore, you can generate a secure configuration profile for enabling SSL in your Nginx server using the Mozilla SSL Configuration Generator. The generated configuration ensures that known vulnerable protocols (for example, SSLv2 and SSLv3), ciphers, and hashing algorithms (for example, 3DES and MD5) are disabled. You can also use the SSL Server Test to verify that your configuration meets modern security requirements.
8.6. Securing PostgreSQL by limiting access to authenticated local users Copy linkLink copied to clipboard!
PostgreSQL is an object-relational database management system (DBMS). In Red Hat Enterprise Linux, PostgreSQL is provided by the postgresql-server
package.
You can reduce the risks of attacks by configuring client authentication. The pg_hba.conf
configuration file stored in the database cluster’s data directory controls the client authentication. Follow the procedure to configure PostgreSQL for host-based authentication.
Procedure
Install PostgreSQL:
dnf install postgresql-server
# dnf install postgresql-server
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Initialize a database storage area using one of the following options:
Using the
initdb
utility:initdb -D /home/postgresql/db1/
$ initdb -D /home/postgresql/db1/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
initdb
command with the-D
option creates the directory you specify if it does not already exist, for example/home/postgresql/db1/
. This directory then contains all the data stored in the database and also the client authentication configuration file.Using the
postgresql-setup
script:postgresql-setup --initdb
$ postgresql-setup --initdb
Copy to Clipboard Copied! Toggle word wrap Toggle overflow By default, the script uses the
/var/lib/pgsql/data/
directory. This script helps system administrators with basic database cluster administration.
To allow any authenticated local users to access any database with their usernames, modify the following line in the
pg_hba.conf
file:local all all trust
local all all trust
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This can be problematic when you use layered applications that create database users and no local users. If you do not want to explicitly control all user names on the system, remove the
local
line entry from thepg_hba.conf
file.Restart the database to apply the changes:
systemctl restart postgresql
# systemctl restart postgresql
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The previous command updates the database and also verifies the syntax of the configuration file.
8.7. Securing the Memcached service Copy linkLink copied to clipboard!
Memcached is an open source, high-performance, distributed memory object caching system. It can improve the performance of dynamic web applications by lowering database load.
Memcached is an in-memory key-value store for small chunks of arbitrary data, such as strings and objects, from results of database calls, API calls, or page rendering. Memcached allows assigning memory from underutilized areas to applications that require more memory.
In 2018, vulnerabilities of DDoS amplification attacks by exploiting Memcached servers exposed to the public internet were discovered. These attacks took advantage of Memcached communication using the UDP protocol for transport. The attack was effective because of the high amplification ratio where a request with the size of a few hundred bytes could generate a response of a few megabytes or even hundreds of megabytes in size.
In most situations, the memcached
service does not need to be exposed to the public Internet. Such exposure may have its own security problems, allowing remote attackers to leak or modify information stored in Memcached.
8.7.1. Hardening Memcached against DDoS Copy linkLink copied to clipboard!
To mitigate security risks, perform as many of the following steps as applicable for your configuration.
Procedure
Configure a firewall in your LAN. If your Memcached server should be accessible only in your local network, do not route external traffic to ports used by the
memcached
service. For example, remove the default port11211
from the list of allowed ports:firewall-cmd --remove-port=11211/udp firewall-cmd --runtime-to-permanent
# firewall-cmd --remove-port=11211/udp # firewall-cmd --runtime-to-permanent
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you use a single Memcached server on the same machine as your application, set up
memcached
to listen to localhost traffic only. Modify theOPTIONS
value in the/etc/sysconfig/memcached
file:OPTIONS="-l 127.0.0.1,::1"
OPTIONS="-l 127.0.0.1,::1"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable Simple Authentication and Security Layer (SASL) authentication:
Modify or add the
/etc/sasl2/memcached.conf
file:sasldb_path: /path.to/memcached.sasldb
sasldb_path: /path.to/memcached.sasldb
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add an account in the SASL database:
saslpasswd2 -a memcached -c cacheuser -f /path.to/memcached.sasldb
# saslpasswd2 -a memcached -c cacheuser -f /path.to/memcached.sasldb
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Ensure that the database is accessible for the
memcached
user and group:chown memcached:memcached /path.to/memcached.sasldb
# chown memcached:memcached /path.to/memcached.sasldb
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable SASL support in Memcached by adding the
-S
value to theOPTIONS
parameter in the/etc/sysconfig/memcached
file:OPTIONS="-S"
OPTIONS="-S"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the Memcached server to apply the changes:
systemctl restart memcached
# systemctl restart memcached
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Add the username and password created in the SASL database to the Memcached client configuration of your application.
Encrypt communication between Memcached clients and servers with TLS:
Enable encrypted communication between Memcached clients and servers with TLS by adding the
-Z
value to theOPTIONS
parameter in the/etc/sysconfig/memcached
file:OPTIONS="-Z"
OPTIONS="-Z"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Add the certificate chain file path in the PEM format using the
-o ssl_chain_cert
option. -
Add a private key file path using the
-o ssl_key
option.
8.8. Securing the Postfix service Copy linkLink copied to clipboard!
Postfix is a mail transfer agent (MTA) that uses the Simple Mail Transfer Protocol (SMTP) to deliver electronic messages between other MTAs and to email clients or delivery agents. Although MTAs can encrypt traffic between one another, they might not do so by default. You can also mitigate risks to various attacks by changing setting to more secure values.
8.8.2. Postfix configuration options for limiting DoS attacks Copy linkLink copied to clipboard!
An attacker can flood the server with traffic, or send information that triggers a crash, causing a denial of service (DoS) attack. You can configure your system to reduce the risk of such attacks by setting limits in the /etc/postfix/main.cf
file. You can change the value of the existing directives or you can add new directives with custom values in the <directive> = <value>
format.
Use the following list of directives for limiting a DoS attack:
smtpd_client_connection_rate_limit
-
Limits the maximum number of connection attempts any client can make to this service per time unit. The default value is
0
, which means a client can make as many connections per time unit as Postfix can accept. By default, the directive excludes clients in trusted networks. anvil_rate_time_unit
-
Defines a time unit to calculate the rate limit. The default value is
60
seconds. smtpd_client_event_limit_exceptions
- Excludes clients from the connection and rate limit commands. By default, the directive excludes clients in trusted networks.
smtpd_client_message_rate_limit
- Defines the maximum number of message deliveries from client to request per time unit (regardless of whether or not Postfix actually accepts those messages).
default_process_limit
-
Defines the default maximum number of Postfix child processes that provide a given service. You can ignore this rule for specific services in the
master.cf
file. By default, the value is100
. queue_minfree
-
Defines the minimum amount of free space required to receive mail in the queue file system. The directive is currently used by the Postfix SMTP server to decide if it accepts any mail at all. By default, the Postfix SMTP server rejects
MAIL FROM
commands when the amount of free space is less than 1.5 times themessage_size_limit
. To specify a higher minimum free space limit, specify aqueue_minfree
value that is at least 1.5 times themessage_size_limit
. By default, thequeue_minfree
value is0
. header_size_limit
-
Defines the maximum amount of memory in bytes for storing a message header. If a header is large, it discards the excess header. By default, the value is
102400
bytes. message_size_limit
-
Defines the maximum size of a message including the envelope information in bytes. By default, the value is
10240000
bytes.
8.8.3. Configuring Postfix to use SASL Copy linkLink copied to clipboard!
Postfix supports Simple Authentication and Security Layer (SASL) based SMTP Authentication (AUTH). SMTP AUTH is an extension of the Simple Mail Transfer Protocol. Currently, the Postfix SMTP server supports the SASL implementations in the following ways:
- Dovecot SASL
- The Postfix SMTP server can communicate with the Dovecot SASL implementation by using either a UNIX-domain socket or a TCP socket. Use this method if Postfix and Dovecot applications are running on separate machines.
- Cyrus SASL
- When enabled, SMTP clients must authenticate with the SMTP server by using an authentication method supported and accepted by both the server and the client.
Prerequisites
-
The
dovecot
package is installed on the system
Procedure
Set up Dovecot:
Include the following lines in the
/etc/dovecot/conf.d/10-master.conf
file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The previous example uses UNIX-domain sockets for communication between Postfix and Dovecot. The example also assumes default Postfix SMTP server settings, which include the mail queue located in the
/var/spool/postfix/
directory, and the application running under thepostfix
user and group.Optional: Set up Dovecot to listen for Postfix authentication requests through TCP:
service auth { inet_listener { port = <port_number> } }
service auth { inet_listener { port = <port_number> } }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Specify the method that the email client uses to authenticate with Dovecot by editing the
auth_mechanisms
parameter in/etc/dovecot/conf.d/10-auth.conf
file:auth_mechanisms = plain login
auth_mechanisms = plain login
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
auth_mechanisms
parameter supports different plain text and non-plain text authentication methods.
Set up Postfix by modifying the
/etc/postfix/main.cf
file:Enable SMTP Authentication on the Postfix SMTP server:
smtpd_sasl_auth_enable = yes
smtpd_sasl_auth_enable = yes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable the use of Dovecot SASL implementation for SMTP Authentication:
smtpd_sasl_type = dovecot
smtpd_sasl_type = dovecot
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Provide the authentication path relative to the Postfix queue directory. Note that the use of a relative path ensures that the configuration works regardless of whether the Postfix server runs in
chroot
or not:smtpd_sasl_path = private/auth
smtpd_sasl_path = private/auth
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This step uses UNIX-domain sockets for communication between Postfix and Dovecot.
To configure Postfix to look for Dovecot on a different machine in case you use TCP sockets for communication, use configuration values similar to the following:
smtpd_sasl_path = inet: <IP_address> : <port_number>
smtpd_sasl_path = inet: <IP_address> : <port_number>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow In the previous example, replace the
<IP_address>
with the IP address of the Dovecot machine and<port_number>
with the port number specified in Dovecot’s/etc/dovecot/conf.d/10-master.conf
file.Specify SASL mechanisms that the Postfix SMTP server makes available to clients. Note that you can specify different mechanisms for encrypted and unencrypted sessions.
smtpd_sasl_security_options = noanonymous, noplaintext smtpd_sasl_tls_security_options = noanonymous
smtpd_sasl_security_options = noanonymous, noplaintext smtpd_sasl_tls_security_options = noanonymous
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The previous directives specify that during unencrypted sessions, no anonymous authentication is allowed and no mechanisms that transmit unencrypted user names or passwords are allowed. For encrypted sessions that use TLS, only non-anonymous authentication mechanisms are allowed.