Red Hat Training

A Red Hat training course is available for RHEL 8

Chapter 1. Using secure communications between two systems with OpenSSH

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 to collect unencrypted passwords from the connection.

Red Hat Enterprise Linux 8 includes the basic OpenSSH packages: the general openssh package, the openssh-server package and the openssh-clients package. Note that the OpenSSH packages require the OpenSSL package openssl-libs, which installs several important cryptographic libraries that enable OpenSSH to provide encrypted communications.

1.1. SSH and OpenSSH

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 first installed, or when the host boots for the first time.

OpenSSH is an implementation of the SSH protocol supported by a number of 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 to ssh-agent
  • ssh-keygen generates, manages, and converts authentication keys for ssh
  • ssh-copy-id is a script that adds local public keys to the authorized_keys file on a remote SSH server
  • ssh-keyscan - gathers SSH public host keys

Two versions of SSH currently exist: version 1, and the newer version 2. The OpenSSH suite in Red Hat Enterprise Linux 8 supports only SSH version 2, which has an enhanced key-exchange algorithm not vulnerable to known exploits in version 1.

OpenSSH, as one of the RHEL core cryptographic subsystems uses system-wide crypto policies. This ensures that weak cipher suites and cryptographic algorithms are disabled in the default configuration. To adjust the policy, the administrator must either use the update-crypto-policies command to make settings stricter or looser or manually opt-out of the system-wide crypto policies.

The OpenSSH suite uses two different sets of configuration files: those for client programs (that is, ssh, scp, and sftp), and those for the server (the sshd daemon). System-wide SSH configuration information is stored in the /etc/ssh/ directory. 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.

Additional resources

1.2. Configuring and starting an OpenSSH server

Use the following procedure for a basic configuration that might be required for your environment and for starting an OpenSSH server. Note that after the default RHEL installation, the sshd daemon is already started and server host keys are automatically created.

Prerequisites

  • The openssh-server package is installed.

Procedure

  1. Start the sshd daemon in the current session and set it to start automatically at boot time:

    # systemctl start sshd
    # systemctl enable sshd
  2. To specify different addresses than the default 0.0.0.0 (IPv4) or :: (IPv6) for the ListenAddress directive in the /etc/ssh/sshd_config configuration file and to use a slower dynamic network configuration, add the dependency on the network-online.target target unit to the sshd.service unit file. To achieve this, create the /etc/systemd/system/sshd.service.d/local.conf file with the following content:

    [Unit]
    Wants=network-online.target
    After=network-online.target
  3. Review if OpenSSH server settings in the /etc/ssh/sshd_config configuration file meet the requirements of your scenario.
  4. Optionally, change the welcome message that your OpenSSH server displays before a client authenticates by editing the /etc/issue file, for example:

    Welcome to ssh-server.example.com
    Warning: By accessing this server, you agree to the referenced terms and conditions.

    Ensure that the Banner option is not commented out in /etc/ssh/sshd_config and its value contains /etc/issue:

    # less /etc/ssh/sshd_config | grep Banner
    Banner /etc/issue

    Note that to change the message displayed after a successful login you have to edit the /etc/motd file on the server. See the pam_motd man page for more information.

  5. Reload the systemd configuration and restart sshd to apply the changes:

    # systemctl daemon-reload
    # systemctl restart sshd

Verification

  1. Check that the sshd daemon is running:

    # systemctl status sshd
    ● sshd.service - OpenSSH server daemon
       Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
       Active: active (running) since Mon 2019-11-18 14:59:58 CET; 6min ago
         Docs: man:sshd(8)
               man:sshd_config(5)
     Main PID: 1149 (sshd)
        Tasks: 1 (limit: 11491)
       Memory: 1.9M
       CGroup: /system.slice/sshd.service
               └─1149 /usr/sbin/sshd -D -oCiphers=aes128-ctr,aes256-ctr,aes128-cbc,aes256-cbc -oMACs=hmac-sha2-256,>
    
    Nov 18 14:59:58 ssh-server-example.com systemd[1]: Starting OpenSSH server daemon...
    Nov 18 14:59:58 ssh-server-example.com sshd[1149]: Server listening on 0.0.0.0 port 22.
    Nov 18 14:59:58 ssh-server-example.com sshd[1149]: Server listening on :: port 22.
    Nov 18 14:59:58 ssh-server-example.com systemd[1]: Started OpenSSH server daemon.
  2. Connect to the SSH server with an SSH client.

    # ssh user@ssh-server-example.com
    ECDSA key fingerprint is SHA256:dXbaS0RG/UzlTTku8GtXSz0S1++lPegSy31v3L/FAEc.
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added 'ssh-server-example.com' (ECDSA) to the list of known hosts.
    
    user@ssh-server-example.com's password:

Additional resources

  • sshd(8) and sshd_config(5) man pages

1.3. Setting an OpenSSH server for key-based authentication

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.

Procedure

  1. Open the /etc/ssh/sshd_config configuration in a text editor, for example:

    # vi /etc/ssh/sshd_config
  2. Change the PasswordAuthentication option to no:

    PasswordAuthentication no

    On a system other than a new default installation, check that PubkeyAuthentication no has not been set and the ChallengeResponseAuthentication directive is set to no. If you are connected remotely, not using console or out-of-band access, test the key-based login process before disabling password authentication.

  3. 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
  4. Reload the sshd daemon to apply the changes:

    # systemctl reload sshd

Additional resources

  • sshd(8), sshd_config(5), and setsebool(8) man pages

1.4. Generating SSH key pairs

Use this procedure to generate an SSH key pair on a local system and to copy the generated public key to an OpenSSH server. If the server is configured accordingly, you can log in to the OpenSSH server without providing any password.

Important

If you complete the following steps as root, only root is able to use the keys.

Procedure

  1. To generate an ECDSA key pair for version 2 of the SSH protocol:

    $ ssh-keygen -t ecdsa
    Generating public/private ecdsa key pair.
    Enter file in which to save the key (/home/joesec/.ssh/id_ecdsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/joesec/.ssh/id_ecdsa.
    Your public key has been saved in /home/joesec/.ssh/id_ecdsa.pub.
    The key fingerprint is:
    SHA256:Q/x+qms4j7PCQ0qFd09iZEFHA+SqwBKRNaU72oZfaCI joesec@localhost.example.com
    The key's randomart image is:
    +---[ECDSA 256]---+
    |.oo..o=++        |
    |.. o .oo .       |
    |. .. o. o        |
    |....o.+...       |
    |o.oo.o +S .      |
    |.=.+.   .o       |
    |E.*+.  .  . .    |
    |.=..+ +..  o     |
    |  .  oo*+o.      |
    +----[SHA256]-----+

    You can also generate an RSA key pair by using the -t rsa option with the ssh-keygen command or an Ed25519 key pair by entering the ssh-keygen -t ed25519 command.

  2. To copy the public key to a remote machine:

    $ ssh-copy-id joesec@ssh-server-example.com
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    joesec@ssh-server-example.com's password:
    ...
    Number of key(s) added: 1
    
    Now try logging into the machine, with: "ssh 'joesec@ssh-server-example.com'" and check to make sure that only the key(s) you wanted were added.

    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 by ssh-agent, use the ssh-copy-id command with the -i option.

Note

If you reinstall your system and want to keep previously generated key pairs, back up the ~/.ssh/ directory. After reinstalling, copy it back to your home directory. You can do this for all users on your system, including root.

Verification

  1. Log in to the OpenSSH server without providing any password:

    $ ssh joesec@ssh-server-example.com
    Welcome message.
    ...
    Last login: Mon Nov 18 18:28:42 2019 from ::1

Additional resources

  • ssh-keygen(1) and ssh-copy-id(1) man pages

1.5. Using SSH keys stored on a smart card

Red Hat Enterprise Linux enables you to use RSA and ECDSA keys stored on a smart card on OpenSSH clients. Use this procedure to enable authentication using a smart card instead of using a password.

Prerequisites

  • On the client side, the opensc package is installed and the pcscd service is running.

Procedure

  1. 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:
    ssh-rsa AAAAB3NzaC1yc2E...KKZMzcQZzx pkcs11:id=%02;object=SIGN%20pubkey;token=SSH%20key;manufacturer=piv_II?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so
    ecdsa-sha2-nistp256 AAA...J0hkYnnsM= pkcs11:id=%01;object=PIV%20AUTH%20pubkey;token=SSH%20key;manufacturer=piv_II?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so
  2. To enable authentication using a smart card on a remote server (example.com), transfer the public key to the remote server. Use the ssh-copy-id command with keys.pub created in the previous step:

    $ ssh-copy-id -f -i keys.pub username@example.com
  3. To connect to example.com using the ECDSA key from the output of the ssh-keygen -D command in step 1, 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" example.com
    Enter PIN for 'SSH key':
    [example.com] $
  4. 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 example.com
    Enter PIN for 'SSH key':
    [example.com] $

    Because OpenSSH uses the p11-kit-proxy wrapper and the OpenSC PKCS #11 module is registered to PKCS#11 Kit, you can simplify the previous commands:

    $ ssh -i "pkcs11:id=%01" example.com
    Enter PIN for 'SSH key':
    [example.com] $

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: example.com
Enter PIN for 'SSH key':
[example.com] $

Additional resources

1.6. Making OpenSSH more secure

The following tips help you to increase security when using OpenSSH. Note that changes in the /etc/ssh/sshd_config OpenSSH configuration file require reloading the sshd daemon to take effect:

# systemctl reload sshd
Important

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. For this reason, consider disabling insecure protocols, such as telnet, rsh, rlogin, and ftp.

Enabling key-based authentication and disabling password-based authentication

  • Disabling passwords for authentication and allowing only key pairs reduces the attack surface and it also might save users’ time. On clients, generate key pairs using the ssh-keygen tool and use the ssh-copy-id utility to copy public keys from clients on the OpenSSH server. To disable password-based authentication on your OpenSSH server, edit /etc/ssh/sshd_config and change the PasswordAuthentication option to no:

    PasswordAuthentication no

Key types

  • Although the ssh-keygen command generates a pair of RSA keys by default, you can instruct it to generate ECDSA or Ed25519 keys by using the -t option. The ECDSA (Elliptic Curve Digital Signature Algorithm) 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 8, 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
  • To exclude particular key types for SSH connections, comment out the relevant lines in /etc/ssh/sshd_config, and reload the sshd service. For example, to allow only Ed25519 host keys:

    # HostKey /etc/ssh/ssh_host_rsa_key
    # HostKey /etc/ssh/ssh_host_ecdsa_key
    HostKey /etc/ssh/ssh_host_ed25519_key

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 and thus increase security through obscurity. You can specify the port using the Port 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 the policycoreutils-python-utils package:

    # semanage port -a -t ssh_port_t -p tcp port_number

    Furthermore, update firewalld configuration:

    # firewall-cmd --add-port port_number/tcp
    # firewall-cmd --runtime-to-permanent

    In the previous commands, replace port_number with the new port number specified using the Port directive.

No root login

  • If your particular use case does not require the possibility of logging in as the root user, you should consider setting the PermitRootLogin configuration directive to no in the /etc/ssh/sshd_config file. By disabling the possibility of logging in as the root user, the administrator can audit which users run what privileged commands after they log in as regular users and then gain root rights.

    Alternatively, set PermitRootLogin to prohibit-password:

    PermitRootLogin prohibit-password

    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.

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/05-redhat.conf file is set to yes, and there is no difference between the ssh -X remote_machine (untrusted host) and ssh -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 to no.

Restricting access to specific users, groups, or domains

  • The AllowUsers and AllowGroups 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 combine AllowUsers and AllowGroups to restrict access more precisely, for example:

    AllowUsers *@192.168.1.*,*@10.0.0.*,!*@192.168.1.2
    AllowGroups example-group

    The previous configuration lines accept connections from all users from systems in 192.168.1.* and 10.0.0.* subnets except from the system with the 192.168.1.2 address. All users must be in the example-group group. The OpenSSH server denies all other connections.

    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
    Setting system policy to FUTURE
  • To opt-out of the system-wide crypto policies for your OpenSSH server, uncomment the line with the CRYPTO_POLICY= variable in the /etc/sysconfig/sshd file. After this change, values that you specify in the Ciphers, MACs, KexAlgoritms, and GSSAPIKexAlgorithms sections in the /etc/ssh/sshd_config file are not overridden. Note that this task requires deep expertise in configuring cryptographic options.
  • See Using system-wide cryptographic policies in the RHEL 8 Security hardening title for more information.

Additional resources

  • sshd_config(5), ssh-keygen(1), crypto-policies(7), and update-crypto-policies(8) man pages

1.7. Connecting to a remote server using an SSH jump host

Use this procedure for connecting your local system to a remote server through an intermediary server, also called jump host.

Prerequisites

  • A jump host accepts SSH connections from your local system.
  • A remote server accepts SSH connections only from the jump host.

Procedure

  1. Define the jump host by editing the ~/.ssh/config file on your local system, for example:

    Host jump-server1
      HostName jump1.example.com
    • The Host parameter defines a name or alias for the host you can use in ssh 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.
  2. Add the remote server jump configuration with the ProxyJump directive to ~/.ssh/config file on your local system, for example:

    Host remote-server
      HostName remote1.example.com
      ProxyJump jump-server1
  3. Use your local system to connect to the remote server through the jump server:

    $ ssh remote-server

    The previous command is equivalent to the ssh -J jump-server1 remote-server command if you omit the configuration steps 1 and 2.

Note

You can specify more jump servers and you can also skip adding host definitions to the configurations file when you provide their complete host names, for example:

$ ssh -J jump1.example.com,jump2.example.com,jump3.example.com remote1.example.com

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 johndoe@jump1.example.com:75,johndoe@jump2.example.com:75,johndoe@jump3.example.com:75 joesec@remote1.example.com:220

Additional resources

  • ssh_config(5) and ssh(1) man pages

1.8. Connecting to remote machines with SSH keys using ssh-agent

To avoid entering a passphrase each time you initiate an SSH connection, you can use the ssh-agent utility to cache the private SSH key. The private key and the passphrase remain secure.

Prerequisites

  • You have a remote host with SSH daemon running and reachable through the network.
  • You know the IP address or hostname and credentials to log in to the remote host.
  • You have generated an SSH key pair with a passphrase and transferred the public key to the remote machine. For more information, see Generating SSH key pairs.

Procedure

  1. Optional: Verify you can use the key to authenticate to the remote host:

    1. Connect to the remote host using SSH:

      $ ssh example.user1@198.51.100.1 hostname
    2. Enter the passphrase you set while creating the key to grant access to the private key.

      $ ssh example.user1@198.51.100.1 hostname
       host.example.com
  2. Start the ssh-agent.

    $ eval $(ssh-agent)
    Agent pid 20062
  3. Add the key to ssh-agent.

    $ ssh-add ~/.ssh/id_rsa
    Enter passphrase for ~/.ssh/id_rsa:
    Identity added: ~/.ssh/id_rsa (example.user0@198.51.100.12)

Verification

  • Optional: Log in to the host machine using SSH.

    $ ssh example.user1@198.51.100.1
    
    Last login: Mon Sep 14 12:56:37 2020

    Note that you did not have to enter the passphrase.

1.9. Configuring secure communication with the SSH System Roles

As an administrator, you can use the SSHD System Role to configure SSH servers and the SSH System Role to configure SSH clients consistently on any number of RHEL systems at the same time by using Red Hat Ansible Automation Platform.

1.9.1. SSHD System Role variables

In an SSHD System Role playbook, you can define the parameters for the SSH configuration file according to your preferences and limitations.

If you do not configure these variables, the system role produces an sshd_config file that matches the RHEL defaults.

In all cases, Booleans correctly render as yes and no in sshd configuration. You can define multi-line configuration items using lists. For example:

sshd_ListenAddress:
  - 0.0.0.0
  - '::'

renders as:

ListenAddress 0.0.0.0
ListenAddress ::

Variables for the SSHD System Role

sshd_enable
If set to False, the role is completely disabled. Defaults to True.
sshd_skip_defaults
If set to True, the system role does not apply default values. Instead, you specify the complete set of configuration defaults by using either the sshd dict, or sshd_Key variables. Defaults to False.
sshd_manage_service
If set to False, the service is not managed, which means it is not enabled on boot and does not start or reload. Defaults to True except when running inside a container or AIX, because the Ansible service module does not currently support enabled for AIX.
sshd_allow_reload
If set to False, sshd does not reload after a change of configuration. This can help with troubleshooting. To apply the changed configuration, reload sshd manually. Defaults to the same value as sshd_manage_service except on AIX, where sshd_manage_service defaults to False but sshd_allow_reload defaults to True.
sshd_install_service

If set to True, the role installs service files for the sshd service. This overrides files provided in the operating system. Do not set to True unless you are configuring a second instance and you also change the sshd_service variable. Defaults to False.

The role uses the files pointed by the following variables as templates:

sshd_service_template_service (default: templates/sshd.service.j2)
sshd_service_template_at_service (default: templates/sshd@.service.j2)
sshd_service_template_socket (default: templates/sshd.socket.j2)
sshd_service
This variable changes the sshd service name, which is useful for configuring a second sshd service instance.
sshd

A dict that contains configuration. For example:

sshd:
  Compression: yes
  ListenAddress:
    - 0.0.0.0
sshd_OptionName

You can define options by using simple variables consisting of the sshd_ prefix and the option name instead of a dict. The simple variables override values in the sshd dict.. For example:

sshd_Compression: no
sshd_match and sshd_match_1 to sshd_match_9
A list of dicts or just a dict for a Match section. Note that these variables do not override match blocks as defined in the sshd dict. All of the sources will be reflected in the resulting configuration file.

Secondary variables for the SSHD System Role

You can use these variables to override the defaults that correspond to each supported platform.

sshd_packages
You can override the default list of installed packages using this variable.
sshd_config_owner, sshd_config_group, and sshd_config_mode
You can set the ownership and permissions for the openssh configuration file that this role produces using these variables.
sshd_config_file
The path where this role saves the openssh server configuration produced.
sshd_binary
The path to the sshd executable of openssh.
sshd_service
The name of the sshd service. By default, this variable contains the name of the sshd service that the target platform uses. You can also use it to set the name of the custom sshd service when the role uses the sshd_install_service variable.
sshd_verify_hostkeys
Defaults to auto. When set to auto, this lists all host keys that are present in the produced configuration file, and generates any paths that are not present. Additionally, permissions and file owners are set to default values. This is useful if the role is used in the deployment stage to make sure the service is able to start on the first attempt. To disable this check, set this variable to an empty list [].
sshd_hostkey_owner, sshd_hostkey_group, sshd_hostkey_mode
Use these variables to set the ownership and permissions for the host keys from sshd_verify_hostkeys.
sshd_sysconfig
On RHEL-based systems, this variable configures additional details of the sshd service. If set to true, this role manages also the /etc/sysconfig/sshd configuration file based on the following configuration. Defaults to false.
sshd_sysconfig_override_crypto_policy
In RHEL 8, when set to true, this variable overrides the system-wide crypto policy. Defaults to false.
sshd_sysconfig_use_strong_rng
On RHEL-based systems, this variable can force sshd to reseed the openssl random number generator with the number of bytes given as the argument. The default is 0, which disables this functionality. Do not turn this on if the system does not have a hardware random number generator.

1.9.2. Configuring OpenSSH servers using the SSHD System Role

You can use the SSHD System Role to configure multiple SSH servers by running an Ansible playbook.

Prerequisites

  • Access and permissions to one or more managed nodes, which are systems you want to configure with the SSHD System Role.
  • Access and permissions to a control node, which is a system from which Red Hat Ansible Engine configures other systems.

    On the control node:

    • Red Hat Ansible Engine is installed.
    • The rhel-system-roles package is installed.
    • An inventory file which lists the managed nodes.

Procedure

  1. Copy the example playbook for the SSHD System Role:

    # cp /usr/share/doc/rhel-system-roles/sshd/example-root-login-playbook.yml path/custom-playbook.yml
  2. Open the copied playbook by using a text editor, for example:

    # vim path/custom-playbook.yml
    
    ---
    - hosts: all
      tasks:
      - name: Configure sshd to prevent root and password login except from particular subnet
        include_role:
          name: rhel-system-roles.sshd
        vars:
          sshd:
            # root login and password login is enabled only from a particular subnet
            PermitRootLogin: no
            PasswordAuthentication: no
            Match:
            - Condition: "Address 192.0.2.0/24"
              PermitRootLogin: yes
              PasswordAuthentication: yes

    The playbook configures the managed node as an SSH server configured so that:

    • password and root user login is disabled
    • password and root user login is enabled only from the subnet 192.0.2.0/24

    You can modify the variables according to your preferences. For more details, see SSHD Server System Role variables .

  3. Optional: Verify playbook syntax.

    # ansible-playbook --syntax-check path/custom-playbook.yml
  4. Run the playbook on your inventory file:

    # ansible-playbook -i inventory_file path/custom-playbook.yml
    
    ...
    
    PLAY RECAP
    **************************************************
    
    localhost : ok=12 changed=2 unreachable=0 failed=0
    skipped=10 rescued=0 ignored=0

Verification

  1. Log in to the SSH server:

    $ ssh user1@10.1.1.1

    Where:

    • user1 is a user on the SSH server.
    • 10.1.1.1 is the IP address of the SSH server.
  2. Check the contents of the sshd_config file on the SSH server:

    $ vim /etc/ssh/sshd_config
    
    # Ansible managed
    HostKey /etc/ssh/ssh_host_rsa_key
    HostKey /etc/ssh/ssh_host_ecdsa_key
    HostKey /etc/ssh/ssh_host_ed25519_key
    AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
    AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
    AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
    AcceptEnv XMODIFIERS
    AuthorizedKeysFile .ssh/authorized_keys
    ChallengeResponseAuthentication no
    GSSAPIAuthentication yes
    GSSAPICleanupCredentials no
    PasswordAuthentication no
    PermitRootLogin no
    PrintMotd no
    Subsystem sftp /usr/libexec/openssh/sftp-server
    SyslogFacility AUTHPRIV
    UsePAM yes
    X11Forwarding yes
    Match Address 192.0.2.0/24
      PasswordAuthentication yes
      PermitRootLogin yes
  3. Check that you can connect to the server as root from the 192.0.2.0/24 subnet:

    1. Determine your IP address:

      $ hostname -I
      192.0.2.1

      If the IP address is within the 192.0.2.1 - 192.0.2.254 range, you can connect to the server.

    2. Connect to the server as root:

      $ ssh root@10.1.1.1

Additional resources

  • For details about the parameters used in the SSH System Role and additional information about the SSH System Role, see the /usr/share/doc/rhel-system-roles/sshd/README.md file.
  • For details about the ansible-playbook command, see the ansible-playbook(1) man page.

1.9.3. SSH System Role variables

In an SSH System Role playbook, you can define the parameters for the client SSH configuration file according to your preferences and limitations.

If you do not configure these variables, the system role produces a global ssh_config file that matches the RHEL defaults.

In all cases, booleans correctly render as yes or no in ssh configuration. You can define multi-line configuration items using lists. For example:

LocalForward:
  - 22 localhost:2222
  - 403 localhost:4003

renders as:

LocalForward 22 localhost:2222
LocalForward 403 localhost:4003
Note

The configuration options are case sensitive.

Variables for the SSH System Role

ssh_user
You can define an existing user name for which the system role modifies user-specific configuration. The user-specific configuration is saved in ~/.ssh/config of the given user. The default value is null, which modifies global configuration for all users.
ssh_skip_defaults
Defaults to auto. If set to auto, the system role writes the system-wide configuration file /etc/ssh/ssh_config and keeps the RHEL defaults defined there. Creating a drop-in configuration file, for example by defining the ssh_drop_in_name variable, automatically disables the ssh_skip_defaults variable.
ssh_drop_in_name

Defines the name for the drop-in configuration file, which is placed in the system-wide drop-in directory. The name is used in the template /etc/ssh/ssh_config.d/{ssh_drop_in_name}.conf to reference the configuration file to be modified. If the system does not support drop-in directory, the default value is null. If the system supports drop-in directories, the default value is 00-ansible.

Warning

If the system does not support drop-in directories, setting this option will make the play fail.

The suggested format is NN-name, where NN is a two-digit number used for ordering the configuration files and name is any descriptive name for the content or the owner of the file.

ssh
A dict that contains configuration options and their respective values.
ssh_OptionName
You can define options by using simple variables consisting of the ssh_ prefix and the option name instead of a dict. The simple variables override values in the ssh dict.
ssh_additional_packages
This role automatically installs the openssh and openssh-clients packages, which are needed for the most common use cases. If you need to install additional packages, for example, openssh-keysign for host-based authentication, you can specify them in this variable.
ssh_config_file

The path to which the role saves the configuration file produced. Default value:

  • If the system has a drop-in directory, the default value is defined by the template /etc/ssh/ssh_config.d/{ssh_drop_in_name}.conf.
  • If the system does not have a drop-in directory, the default value is /etc/ssh/ssh_config.
  • if the ssh_user variable is defined, the default value is ~/.ssh/config.
ssh_config_owner, ssh_config_group, ssh_config_mode
The owner, group and modes of the created configuration file. By default, the owner of the file is root:root, and the mode is 0644. If ssh_user is defined, the mode is 0600, and the owner and group are derived from the user name specified in the ssh_user variable.

1.9.4. Configuring OpenSSH clients using the SSH System Role

You can use the SSH System Role to configure multiple SSH clients by running an Ansible playbook.

Prerequisites

  • Access and permissions to one or more managed nodes, which are systems you want to configure with the SSH System Role.
  • Access and permissions to a control node, which is a system from which Red Hat Ansible Engine configures other systems.

    On the control node:

    • Red Hat Ansible Engine is installed.
    • The rhel-system-roles package is installed.
    • An inventory file which lists the managed nodes.

Procedure

  1. Create a new playbook.yml file with the following content:

    ---
    - hosts: all
      tasks:
      - name: "Configure ssh clients"
        include_role:
          name: rhel-system-roles.ssh
        vars:
          ssh_user: root
          ssh:
            Compression: true
            GSSAPIAuthentication: no
            ControlMaster: auto
            ControlPath: ~/.ssh/.cm%C
            Host:
              - Condition: example
                Hostname: example.com
                User: user1
          ssh_ForwardX11: no

    This playbook configures the root user’s SSH client preferences on the managed nodes with the following configurations:

    • Compression is enabled.
    • ControlMaster multiplexing is set to auto.
    • The example alias for connecting to the example.com host is user1.
    • The example host alias is created, which represents a connection to the example.com host the with user1 user name.
    • X11 forwarding is disabled.

    Optionally, you can modify these variables according to your preferences. For more details, see SSH Client Role variables .

  2. Optional: Verify playbook syntax.

    # ansible-playbook --syntax-check path/custom-playbook.yml
  3. Run the playbook on your inventory file:

    # ansible-playbook -i inventory_file path/custom-playbook.yml

Verification

  • Verify that the managed node has the correct configuration by opening the SSH configuration file in a text editor, for example:

    # vi ~root/.ssh/config

    After application of the example playbook shown above, the configuration file should have the following content:

    # Ansible managed
    Compression yes
    ControlMaster auto
    ControlPath ~/.ssh/.cm%C
    ForwardX11 no
    GSSAPIAuthentication no
    Host example
      Hostname example.com
      User user1

1.10. Additional resources

  • sshd(8) man page documents available command-line options and provides a complete list of supported configuration files and directories.
  • ssh(1) man page provides a complete list of available command-line options and supported configuration files and directories.
  • scp(1) man page provides a more detailed description of the scp utility and its usage.
  • sftp(1) man page provides a more detailed description of the sftp utility and its usage.
  • ssh-keygen(1) man page documents in detail the use of the ssh-keygen utility to generate, manage, and convert authentication keys used by ssh.
  • ssh-copy-id(1) man page describes the use of the ssh-copy-id script.
  • ssh_config(5) man page documents available SSH client configuration options.
  • sshd_config(5) man page provides a full description of available SSH daemon configuration options.
  • update-crypto-policies(8) man page provides guidance on managing system-wide cryptographic policies
  • crypto-policies(7) man page provides an overview of system-wide cryptographic policy levels
  • OpenSSH Home Page - contains further documentation, frequently asked questions, links to the mailing lists, bug reports, and other useful resources.
  • Configuring SELinux for applications and services with non-standard configurations - you can apply analogous procedures for OpenSSH in a non-standard configuration with SELinux in enforcing mode.
  • Controlling network traffic using firewalld - provides guidance on updating firewalld settings after changing an SSH port