Introduction
SSH (Secure Shell) is the primary tool for remote management of Linux servers. However, a standard OpenSSH installation leaves several vulnerabilities that are actively exploited by attackers: password brute-forcing, root login attempts, and port 22 scanning. This guide will walk you through five key steps to harden your SSH server. Upon completion, you will have a secure connection resilient to automated attacks without sacrificing convenience.
Prerequisites
Before you begin, ensure you have:
- Access to a server with sudo (or root) privileges.
- A installed OpenSSH server (the
openssh-serverpackage). - Working SSH key-based authentication (recommended to configure in advance).
- A backup of the configuration file:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup - A text editor (
nano,vim, or another).
Step 1: Change the SSH Port
The default port 22 is a target for mass scanning. Changing the port reduces noise from bots.
- Open the configuration file:
sudo nano /etc/ssh/sshd_config - Find the line
#Port 22, remove the#symbol, and change the port number, for example, to2222:Port 2222⚠️ Important: Choose a port from the 1024-65535 range that is not used by other services.
- Save the file (
Ctrl+O,Enter,Ctrl+Xin nano). - Restart the SSH daemon:
- For systemd (Ubuntu/Debian/CentOS 7+/Fedora):
sudo systemctl restart sshd # Ubuntu/Debian # or sudo systemctl restart ssh # CentOS/Fedora (ssh package)
- For systemd (Ubuntu/Debian/CentOS 7+/Fedora):
- Open the new port in the firewall:
- UFW (Ubuntu/Debian):
sudo ufw allow 2222/tcp sudo ufw reload - firewalld (CentOS/Fedora):
sudo firewall-cmd --permanent --add-port=2222/tcp sudo firewall-cmd --reload
- UFW (Ubuntu/Debian):
- Verify the service is listening on the new port:
The output should showsudo ss -tlnp | grep sshd*:2222.
Step 2: Disable Root Login
Root login is a common attack vector. Prohibit it and use a regular user with sudo.
- In the same
/etc/ssh/sshd_configfile, find the#PermitRootLoginparameter and set:PermitRootLogin no - Save and restart the SSH daemon (as in Step 1).
Step 3: Disable Password Authentication
If you are using SSH keys, disable password authentication—this eliminates password brute-forcing.
- In
/etc/ssh/sshd_config, find#PasswordAuthenticationand set:PasswordAuthentication no - Critically important: Before applying, ensure you can log in with a key from a new client. Test:
If the connection is successful—apply the setting.ssh -p 2222 user@your-server-ip - Restart the SSH daemon.
Step 4: Configure Fail2ban
Fail2ban automatically blocks IPs after several failed login attempts.
- Install Fail2ban:
- Debian/Ubuntu:
sudo apt update && sudo apt install fail2ban - CentOS/Fedora:
sudo yum install fail2ban # CentOS 7 # or sudo dnf install fail2ban # CentOS 8+/Fedora
- Debian/Ubuntu:
- Create a local config (do not edit
jail.confdirectly):sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local - Edit
jail.local:
Find thesudo nano /etc/fail2ban/jail.local[sshd]section and ensure the parameters match:enabled = true port = 2222 # if you changed the port, specify it; otherwise leave as ssh filter = sshd logpath = /var/log/auth.log # Debian/Ubuntu # logpath = /var/log/secure # CentOS/Fedora maxretry = 3 # number of attempts before blocking bantime = 3600 # block for 1 hour (in seconds)💡 Tip: For CentOS/Fedora, change
logpathto/var/log/secure. - Restart Fail2ban:
sudo systemctl restart fail2ban sudo systemctl enable fail2ban - Check the status:
sudo fail2ban-client status sshd
Step 5: Restrict Users
Allow connections only for specific users, reducing the risk of compromising service accounts.
- In
/etc/ssh/sshd_config, add (or uncomment) theAllowUsersparameter:AllowUsers alice bob admin # list usernames separated by spaces⚠️ Important: Ensure your current user is included in the list, or you will lock yourself out.
- Save and restart the SSH daemon.
Verification
Ensure all settings are working:
- Connect from a new client using:
- The non-standard port (if changed):
ssh -p 2222 user@server-ip - Key-based authentication only (passwords should be rejected).
- Try logging in as root—the connection should be denied.
- The non-standard port (if changed):
- Check Fail2ban status:
The output should show blocked IPs (if there were attempts).sudo fail2ban-client status sshd - Confirm the SSH service is listening on the correct port:
sudo ss -tlnp | grep sshd
Troubleshooting
- Locked yourself out after configuration: Use console access (KVM/IPMI) via your hosting provider's panel. In the console, restore
/etc/ssh/sshd_configfrom the backup and restart SSH. - Port not open in firewall: Check the rules (
sudo ufw statusorsudo firewall-cmd --list-all). Ensure the port is added and the firewall is active. - Key-based authentication not working: Check permissions on
~/.ssh/authorized_keys(should be600) and the home directory (755). Ensure the public key is added toauthorized_keys. - Fail2ban not blocking IPs: Check the logs (
sudo tail -f /var/log/fail2ban.log). Ensurelogpathinjail.localpoints to the correct file (auth.logfor Debian/Ubuntu,securefor CentOS/Fedora). - SSH fails to restart: Check the config syntax before restarting:
If the output is empty—the config is valid.sudo sshd -t