SSH is the primary remote administration interface for most RHEL 8 servers, making it a prime target for brute-force attacks and unauthorized access attempts. A default OpenSSH installation leaves several insecure options enabled that should be disabled immediately after provisioning. This guide walks through a comprehensive SSH hardening process covering configuration directives, host access controls, intrusion prevention with fail2ban, and cipher-suite auditing with ssh-audit. Following these steps reduces your attack surface significantly and brings your server closer to CIS Benchmark compliance.

Prerequisites

  • RHEL 8 server with a non-root sudo user
  • EPEL 8 repository enabled (dnf install -y epel-release)
  • SSH key pair already generated on your client machine
  • Console or out-of-band access in case SSH becomes unavailable during changes
  • firewalld running (systemctl status firewalld)

Step 1 — Back Up and Edit sshd_config

Always back up the original configuration before making changes. Open the file and apply the core hardening directives shown below.

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

sudo vi /etc/ssh/sshd_config

Add or update the following directives:

# Disable root login
PermitRootLogin no

# Disable password authentication (key-based only)
PasswordAuthentication no

# Force Protocol 2
Protocol 2

# Limit authentication attempts
MaxAuthTries 3

# Restrict which users may log in (replace with your username)
AllowUsers deployer

# Disable X11 forwarding
X11Forwarding no

# Terminate idle sessions after 10 minutes
ClientAliveInterval 300
ClientAliveCountMax 2

Step 2 — Change the Default SSH Port

Changing from port 22 to a non-standard port reduces automated scan noise. Update both sshd_config and the firewall, and inform SELinux of the new port.

# In /etc/ssh/sshd_config, set:
Port 2222

# Allow the new port through SELinux
sudo semanage port -a -t ssh_port_t -p tcp 2222

# Update firewalld
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload

# Restart SSH
sudo systemctl restart sshd

Step 3 — Restrict Access with hosts.allow and hosts.deny

TCP Wrappers provide a coarse but effective additional layer of access control for services compiled with libwrap support, including sshd on RHEL 8.

# /etc/hosts.allow — permit only your management subnet
sshd : 192.168.1.0/24

# /etc/hosts.deny — deny everything else
sshd : ALL

Edit both files as root. The allow file is evaluated first; unmatched connections fall through to the deny rule.

Step 4 — Install and Configure fail2ban

fail2ban monitors log files and bans IPs that exceed a threshold of failed authentication attempts by adding temporary firewalld rules.

sudo dnf install -y fail2ban

# Create a local override (never edit jail.conf directly)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Edit /etc/fail2ban/jail.local and configure the sshd jail:

[sshd]
enabled  = true
port     = 2222
filter   = sshd
logpath  = /var/log/secure
maxretry = 3
bantime  = 3600
findtime = 600

# Enable systemd backend on RHEL 8
backend  = systemd
sudo systemctl enable --now fail2ban

# Verify the jail is active
sudo fail2ban-client status sshd

Step 5 — Harden Cipher Suites with ssh-audit

ssh-audit scans your SSH server and flags weak key-exchange algorithms, ciphers, and MACs. Install it and apply the recommended settings.

sudo dnf install -y python3-pip
pip3 install ssh-audit

# Run against localhost (use the new port)
ssh-audit localhost -p 2222

Based on the output, add explicit cipher directives to /etc/ssh/sshd_config:

KexAlgorithms curve25519-sha256,[email protected]
Ciphers [email protected],[email protected],[email protected]
MACs [email protected],[email protected]

sudo systemctl restart sshd
ssh-audit localhost -p 2222

Step 6 — Verify the Final Configuration

Test all changes before closing your current session to ensure you can still log in.

# Check sshd config for syntax errors
sudo sshd -t

# Confirm no root login is possible
ssh -p 2222 root@your_server_ip

# View current fail2ban bans
sudo fail2ban-client status sshd

# Review /var/log/secure for recent auth events
sudo tail -50 /var/log/secure

Conclusion

You have hardened SSH on RHEL 8 by disabling root and password logins, restricting allowed users, moving to a non-default port, enforcing strict cipher suites, and deploying fail2ban to automatically ban brute-force sources. These changes collectively eliminate the most common SSH attack vectors while preserving legitimate administrative access via key-based authentication.

Next steps: How to Set Up WireGuard VPN on RHEL 8, How to Configure SELinux on RHEL 8, and How to Configure firewalld on RHEL 8.