Make OpenSSH more secure

Harden your system security by modifying OpenSSH configurations, such as implementing stronger keys and restricting user access. This helps protect your server against various attacks.

To make SSH truly effective, prevent the use of insecure connection protocols and replace them with the OpenSSH suite. Otherwise, a user’s password might be protected by SSH for one session only, only to be captured later when logging in through Telnet. Also, disabling passwords for authentication and allowing only key pairs reduces the attack surface.

In RHEL 10, the PermitRootLogin option is set to prohibit-password by default. This enforces key-based authentication instead of passwords for logging in as root and reduces risk by preventing brute-force attacks.

Warning

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

Create and enforce stronger SSH key types

Generate only ECDSA or Ed25519 keys to use their security and performance advantages over older algorithms. You can also configure the OpenSSH server to disable the automatic generation of RSA host keys and enforce the use of stronger key types.

Before you begin

  • The openssh-server package is installed on your system.

About this task

You can instruct the ssh-keygen command 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.

Important
The Ed25519 algorithm is not FIPS-140-compliant, and OpenSSH does not work with Ed25519 keys in FIPS mode.

Procedure

  1. 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
    Note
    In images with the cloud-init method enabled, the ssh-keygen units are automatically disabled. This is because the ssh-keygen template service can interfere with the cloud-init tool and cause problems with host key generation. To prevent these problems, the etc/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf drop-in configuration file disables the ssh-keygen units if cloud-init is running.
  2. Because OpenSSH creates RSA, ECDSA, and Ed25519 server host keys automatically if they are missing, remove the keys with less secure cryptography:
    # rm -f /etc/ssh/ssh_host_rsa_key
  3. To allow only a particular key type for SSH connections, uncomment the relevant line in /etc/ssh/sshd_config. 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_ed25519_key
  4. Restart the sshd service:
    # systemctl restart sshd

Results

  • Verify that only the configured host key types exist:
    # ls -l /etc/ssh/ssh_host_*_key

    The output shows only the key types you configured. If you enforce Ed25519 only, only ssh_host_ed25519_key files appear.

  • Verify the SSH server uses only the configured key types by connecting from a client:
    $ ssh -v <server> 2>&1 | grep "Server host key"
    Server host key: ssh-ed25519 SHA256:...

Customize allowed cryptography on OpenSSH servers

You can specify the cryptography configuration of your OpenSSH server either by using the /etc/ssh/sshd_config.d/ directory or by applying a custom system-wide cryptographic policy. This enables you to harden or loosen SSH connections depending on your scenario.

Before you begin

  • The openssh-server package is installed.
  • The sshd daemon is running on the server.

About this task

To override the system-wide cryptographic policies for your OpenSSH server, specify the cryptographic policy in a drop-in configuration file located in /etc/ssh/sshd_config.d/. Because the first match wins, name the file with a two-digit number prefix smaller than 50 and with a .conf suffix, for example, 49-crypto-policy-override.conf. This way, it lexicographically precedes the 50-redhat.conf file and overrides the default configuration.

See the sshd_config(5) man page for more information.

Procedure

  1. Create a new configuration file with a name that lexicographically precedes 50-redhat.conf, for example:
    # touch /etc/ssh/sshd_config.d/49-crypto-policy-override.conf
  2. Open the file in a text editor, and specify ciphers and message authentication codes (MACs) you want to allow, for example:
    Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com
    MACs hmac-sha2-512,hmac-sha2-256
  3. Save the changes, and reload the sshd service:
    # systemctl reload sshd

Results

  • Check ciphers and MACs allowed on your OpenSSH server in the output of the sshd -T command:
    # sshd -T | grep -iE '(ciphers|macs)'

What to do next

Set a non-default port for SSH

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.

Before you begin

  • Commands that start with the # command prompt require administrative privileges provided by sudo or root user access. For information on how to configure sudo access, see Enabling unprivileged users to run certain commands.
  • The policycoreutils-python-utils package is installed on your system.

About this task

Note

Changing the SSH port provides only limited security benefits. An attacker performing a full port scan can discover the service regardless of the port number. Real security improvements come from disabling password authentication, using key-based authentication, and implementing proper access controls.

Important

After changing the SSH port, update client configurations to use the new port. This includes:

  • user SSH configuration files (~/.ssh/config)
  • automation tools and scripts that connect to the server
  • monitoring systems and backup tools
  • load balancers and proxy configurations

Without these updates, connections to the server fail.

Procedure

  1. Open the /etc/ssh/sshd_config configuration file in a text editor of your choice.
  2. Remove the # character before the Port directive and specify a port number different from 22, for example:
    Port <49286>
  3. Update the default SELinux policy to allow the use of a non-default port:
    # semanage port -a -t ssh_port_t -p tcp <49286>
  4. Update the firewalld configuration:
    # firewall-cmd --add-port <49286>/tcp
    # firewall-cmd --remove-port=22/tcp
    # firewall-cmd --runtime-to-permanent
  5. Restart the sshd service:
    # systemctl restart sshd

Results

  • Use a tool that displays port numbers of running services, for example:
    # ss -tulpn | grep sshd
    tcp   LISTEN 0      128             [::]:49286            [::]:*    users:(("sshd",pid=1784,fd=8))

    Check the output for the new port number.

SSH access only for specific users, groups, or IP ranges

By using the AllowUsers and AllowGroups directives in the /etc/ssh/sshd_config configuration file, you can permit only certain users, domains, or groups to connect to your OpenSSH server.

Warning

Misconfiguring AllowUsers or AllowGroups can lock you out of the server. Before applying these directives, verify that your user account and source IP match the restrictions. Test the configuration by opening a new SSH session while keeping your current session active, so you can revert changes if the new connection fails.

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

This configuration allows only connections if all of the following conditions are met:

  • 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 the AllowUsers directive lists a user that is not part of a group listed in the AllowGroups directive, then the user cannot log in.

Using allowlists (directives starting with Allow) is more secure than using denylists (options starting with Deny) because allowlists also block new unauthorized users or groups.

X Security extension

Disable X11 forwarding in the OpenSSH server configuration if you do not need it to reduce your system’s attack surface.

The X server in Red Hat Enterprise Linux clients does not provide the X Security extension. Without this extension, clients cannot request an additional security layer when connecting to untrusted SSH servers with X11 forwarding.

By default, the ForwardX11Trusted option in the /etc/ssh/ssh_config.d/50-redhat.conf file is set to yes. This means the ssh -X remote_machine and ssh -Y remote_machine commands behave identically.

To disable X11 forwarding, set the X11Forwarding directive to no in the /etc/ssh/sshd_config configuration file.