SSH Hardening
SSH is the primary method for remote Linux server management and also the most commonly targeted entry point for attackers. This article systematically covers SSH security hardening measures, from key-based authentication to Fail2Ban brute-force protection, helping you build a secure remote access environment.
Use Key-Based Authentication Instead of Passwords
Section titled “Use Key-Based Authentication Instead of Passwords”Key-based authentication is more secure and convenient than password authentication. Once configured, you should completely disable password login.
Generate a Key Pair on the Client
Section titled “Generate a Key Pair on the Client”Follow the prompts. It is recommended to set a passphrase for an additional layer of security:
Generating public/private ed25519 key pair.Enter file in which to save the key (/home/user/.ssh/id_ed25519): Press EnterEnter passphrase (empty for no passphrase): Enter passphraseEnter same passphrase again: Re-enter passphraseCopy the Public Key to the Server
Section titled “Copy the Public Key to the Server”ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server_ipOr copy it manually:
cat ~/.ssh/id_ed25519.pub | ssh user@server_ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"Verify Key-Based Login
Section titled “Verify Key-Based Login”ssh user@server_ipIf you are no longer prompted for a password (or only need to enter the key passphrase), key-based authentication is working.
Harden sshd_config
Section titled “Harden sshd_config”The main SSH configuration file is located at /etc/ssh/sshd_config. After each change, you need to restart the sshd service.
Back Up the Original Configuration
Section titled “Back Up the Original Configuration”sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bakDisable Direct Root Login
Section titled “Disable Direct Root Login”sudo vi /etc/ssh/sshd_configFind or add:
PermitRootLogin noDisable Password Authentication
Section titled “Disable Password Authentication”After confirming that key-based login works properly, disable password authentication:
PasswordAuthentication noAlso disable other insecure authentication methods:
ChallengeResponseAuthentication noKbdInteractiveAuthentication noChange the SSH Port
Section titled “Change the SSH Port”Changing the SSH port from the default 22 to another port can significantly reduce automated scanning attacks:
Port 2222After changing the port, adjust SELinux and the firewall:
# Allow SELinux to use the new portsudo semanage port -a -t ssh_port_t -p tcp 2222
# Allow the new port through the firewallsudo firewall-cmd --permanent --add-port=2222/tcpsudo firewall-cmd --permanent --remove-service=sshsudo firewall-cmd --reloadConfigure AllowUsers Whitelist
Section titled “Configure AllowUsers Whitelist”Only allow specific users to log in via SSH:
AllowUsers admin deployYou can also restrict by source IP:
AllowUsers [email protected]/24 [email protected]/8Similarly, you can use AllowGroups for group-based authorization:
AllowGroups sshusers# Create the group and add userssudo groupadd sshuserssudo usermod -aG sshusers adminsudo usermod -aG sshusers deployAdditional Security Recommendations
Section titled “Additional Security Recommendations”# Disable empty password loginPermitEmptyPasswords no
# Set maximum authentication attemptsMaxAuthTries 3
# Set login timeout (seconds)LoginGraceTime 30
# Disable X11 forwarding (if GUI is not needed)X11Forwarding no
# Specify supported key exchange algorithms (remove weak ones)
# Specify supported encryption algorithms
# Specify supported MAC algorithms
# Set client alive check intervalClientAliveInterval 300ClientAliveCountMax 2
# Display last login informationPrintLastLog yes
# Use SSH protocol 2 (default on modern systems)Protocol 2Apply Configuration
Section titled “Apply Configuration”Check the configuration syntax:
sudo sshd -tIf there is no output, the syntax is correct. Restart the service:
sudo systemctl restart sshdSSH Configuration Best Practice Template
Section titled “SSH Configuration Best Practice Template”The following is a recommended complete security configuration:
# /etc/ssh/sshd_config security configurationPort 2222Protocol 2
# Authentication settingsPermitRootLogin noPasswordAuthentication noPermitEmptyPasswords noChallengeResponseAuthentication noKbdInteractiveAuthentication noPubkeyAuthentication yesAuthorizedKeysFile .ssh/authorized_keys
# User controlAllowUsers admin deployMaxAuthTries 3LoginGraceTime 30
# Security enhancementsX11Forwarding noAllowTcpForwarding noAllowAgentForwarding no
# Session managementClientAliveInterval 300ClientAliveCountMax 2
# LoggingLogLevel VERBOSE
# AlgorithmsInstall and Configure Fail2Ban
Section titled “Install and Configure Fail2Ban”Fail2Ban monitors log files and automatically bans IP addresses with multiple authentication failures, making it an effective tool against brute-force attacks.
Install Fail2Ban
Section titled “Install Fail2Ban”sudo dnf install epel-release -ysudo dnf install fail2ban -yStart the Service
Section titled “Start the Service”sudo systemctl enable --now fail2banConfigure Fail2Ban
Section titled “Configure Fail2Ban”Do not modify /etc/fail2ban/jail.conf directly. Instead, create a local override configuration:
sudo vi /etc/fail2ban/jail.localAdd the following configuration:
[DEFAULT]# Ban duration (seconds), -1 for permanent banbantime = 3600
# Detection time window (seconds)findtime = 600
# Maximum number of failuresmaxretry = 3
# Ban action (using firewalld)banaction = firewallcmd-rich-rulesbanaction_allports = firewallcmd-rich-rules
# Notification email (optional)destemail = [email protected]sender = [email protected]action = %(action_mwl)s
[sshd]enabled = trueport = 2222logpath = /var/log/securebackend = systemdmaxretry = 3bantime = 3600Restart Fail2Ban
Section titled “Restart Fail2Ban”sudo systemctl restart fail2banCheck Fail2Ban Status
Section titled “Check Fail2Ban Status”# Check overall statussudo fail2ban-client status
# Check SSH jail detailssudo fail2ban-client status sshdExample output:
Status for the jail: sshd|- Filter| |- Currently failed: 2| |- Total failed: 15| `- File list: /var/log/secure`- Actions |- Currently banned: 1 |- Total banned: 3 `- Banned IP list: 203.0.113.50Manage Banned IPs
Section titled “Manage Banned IPs”# Manually unban an IPsudo fail2ban-client set sshd unbanip 203.0.113.50
# Manually ban an IPsudo fail2ban-client set sshd banip 203.0.113.100
# View all banned IPssudo fail2ban-client bannedComplete Hardening Workflow
Section titled “Complete Hardening Workflow”-
Generate and deploy SSH keys:
Terminal window # Run on the clientssh-keygen -t ed25519 -C "admin key"ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@server_ip -
After verifying key-based login works, harden the sshd configuration:
Terminal window # Run on the serversudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.baksudo tee /etc/ssh/sshd_config.d/hardening.conf <<'EOF'Port 2222PermitRootLogin noPasswordAuthentication noPermitEmptyPasswords noChallengeResponseAuthentication noMaxAuthTries 3LoginGraceTime 30AllowUsers adminX11Forwarding noClientAliveInterval 300ClientAliveCountMax 2LogLevel VERBOSEEOF -
Adjust SELinux and firewall:
Terminal window sudo semanage port -a -t ssh_port_t -p tcp 2222sudo firewall-cmd --permanent --add-port=2222/tcpsudo firewall-cmd --reload -
Check the configuration and restart SSH:
Terminal window sudo sshd -tsudo systemctl restart sshd -
Test the connection on the new port (keep the old session open):
Terminal window # Run in a new terminalssh -p 2222 admin@server_ip -
After confirming the new port works, close the old port:
Terminal window sudo firewall-cmd --permanent --remove-service=sshsudo firewall-cmd --reload -
Install and configure Fail2Ban:
Terminal window sudo dnf install epel-release fail2ban -ysudo tee /etc/fail2ban/jail.local <<'EOF'[DEFAULT]bantime = 3600findtime = 600maxretry = 3banaction = firewallcmd-rich-rules[sshd]enabled = trueport = 2222backend = systemdEOFsudo systemctl enable --now fail2bansudo fail2ban-client status sshd
After completing these steps, your SSH service will have multiple layers of protection: key-based authentication, a non-standard port, a user whitelist, and automatic banning of brute-force IPs. Using these measures together significantly improves server security.