Best Practices for Hardening SSH Security on Linux Servers

Secure your Linux server immediately by mastering these essential SSH hardening techniques. This expert guide provides actionable steps, focusing on configuration changes in `sshd_config`. Learn how to disable the high-risk root login, implement mandatory key-based authentication to eliminate weak passwords, change the default port, and install Fail2Ban for effective rate limiting against brute-force attacks. Protect your system by transforming SSH into a robust, secure channel.

Best Practices for Hardening SSH Security on Linux Servers

SSH is usually the first door you open on a Linux server, so hardening SSH security should happen before you expose that host to the internet. Bots constantly try weak passwords, reused credentials, and default accounts on port 22.

The goal is simple: keep remote access usable for you and painful for attackers. Start from a second terminal session, keep your current SSH session open, and test every change before restarting the daemon.

Back Up and Test the Configuration First

Before editing /etc/ssh/sshd_config, make a backup. A typo can lock you out of the server.

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak_$(date +%F)

After editing, check the syntax:

sudo sshd -t

If the test passes, reload or restart SSH. The service name is commonly sshd on RHEL-style systems and ssh on Debian/Ubuntu:

sudo systemctl restart sshd
# or
sudo systemctl restart ssh

1. Disable Root Login

Direct root login gives an attacker the most valuable username up front. Use a normal user account, then elevate with sudo when you need administrative access.

Configuration Step

Open /etc/ssh/sshd_config and locate the PermitRootLogin directive. Change its value to no.

# Before:
# PermitRootLogin yes

# After (Best Practice):
PermitRootLogin no

Before you restart SSH, confirm you can log in as a standard user with sudo privileges.

2. Require Key-Based Authentication

Password authentication is easy to attack at scale. SSH keys are harder to guess, easier to rotate, and safer for daily administration when you protect the private key with a passphrase.

Generate and Install Keys

  1. Generate the key pair on your local machine:
    ssh-keygen -t ed25519 -C "[email protected]"
    
  2. Copy the public key to the server:
    ssh-copy-id -i ~/.ssh/id_ed25519 user@your_server_ip
    

Disable Password Authentication

Once you confirm that you can log in successfully using your SSH key, disable password authentication entirely.

# Disable passwords
PasswordAuthentication no

# Ensure keys are enabled
PubkeyAuthentication yes

Ed25519 is a good default for new keys. If you need RSA for compatibility with older systems, use a large key such as 4096 bits.

3. Consider Changing the Default SSH Port

Changing SSH from TCP port 22 to a non-standard port can reduce noisy automated scans. It is not a replacement for keys, access controls, or rate limiting, because anyone can still discover the open port with a scan.

Configuration Step

In /etc/ssh/sshd_config, change the Port directive:

# Before:
# Port 22

# After (Example non-standard port):
Port 22222

Update your firewall and any cloud security group before restarting SSH. Otherwise, your new SSH daemon may be listening on a port you cannot reach.

Example using firewalld (CentOS/RHEL):

sudo firewall-cmd --permanent --add-port=22222/tcp
sudo firewall-cmd --reload

4. Limit Access to Specific Users and Groups

If only a small set of people should use SSH, say that in sshd_config. This blocks forgotten local accounts from becoming remote entry points.

Configuration Directives

Use one or both of the following directives in sshd_config:

  1. Allow specific users:
    AllowUsers alice bob
    
  2. Allow specific groups:
    AllowGroups sshaccess admins
    

If these directives are present, any user or group not explicitly listed will be denied access.

5. Keep Modern SSH Defaults and Disable Legacy Methods

Current OpenSSH releases already use SSH protocol 2; older protocol 1 support has been removed from modern OpenSSH. Avoid copying old hardening snippets that include unsupported Protocol directives or a stale cipher list. Those can break SSH after an upgrade.

Focus on disabling legacy trust mechanisms unless you know you need them:

HostbasedAuthentication no
IgnoreRhosts yes
PermitEmptyPasswords no

If your organization requires custom cipher, MAC, or key-exchange policy, check what your installed server supports before changing it:

sshd -T | grep -E '^(ciphers|macs|kexalgorithms) '

Then apply only a tested policy that matches your client base. A too-strict list can lock out older automation hosts.

6. Add Rate Limiting with Fail2Ban

Even with key-based authentication, repeated probes waste resources and clutter logs. Fail2Ban watches authentication logs and adds temporary firewall bans after repeated failures.

  1. Install Fail2Ban:

    # Debian/Ubuntu
    sudo apt update && sudo apt install fail2ban
    
    # RHEL/CentOS/Fedora
    sudo dnf install fail2ban
    
  2. Enable the sshd jail. Many systems ship a default config, but you should put local overrides in /etc/fail2ban/jail.local or a file under /etc/fail2ban/jail.d/.

    [sshd]
    enabled = true
    port = 22222
    maxretry = 5
    bantime = 1h
    
  3. Start the service:

    sudo systemctl enable --now fail2ban
    

If you changed the SSH port, make the Fail2Ban jail match the new port.

7. Tune Session and Authentication Settings

These settings help close idle sessions and remove weak authentication paths:

Directive Recommended Value Purpose
ClientAliveInterval 300 Sends a server-side keepalive check every 300 seconds.
ClientAliveCountMax 3 Disconnects after three unanswered checks.
UsePAM yes Enables Pluggable Authentication Modules (PAM) for additional local system security policies.
PermitEmptyPasswords no Blocks accounts with empty passwords from logging in.
MaxAuthTries 3 Limits repeated authentication attempts per connection.
X11Forwarding no Disables X11 forwarding unless you actually use it.

Hardening Checklist

Use this checklist to ensure your server meets basic SSH hardening standards:

  1. Backup sshd_config before making changes.
  2. Set PermitRootLogin no.
  3. Set PasswordAuthentication no (after key setup).
  4. Change the Port to a non-standard value.
  5. Update the firewall to allow the new port.
  6. Use AllowUsers or AllowGroups to restrict access.
  7. Disable legacy trust methods such as HostbasedAuthentication.
  8. Install and configure Fail2Ban.
  9. Check configuration with sshd -t before restarting.

Hardening SSH security works best as layered defense. Keys stop password guessing, user restrictions reduce who can connect, firewall rules limit where connections come from, and Fail2Ban slows down repeated probes. Keep one working session open while you test, then document the new port and login method for anyone who operates the server.