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.