Security

SSH Hardening: Secure Your Server in 30 Minutes

The minimum viable SSH security config that actually matters. Disable password auth, enforce keys, fail2ban, and sleep better.

Why SSH Hardening Matters

Every day, servers get scanned and compromised via weak SSH configurations. Log into any fresh VPS and run tail -f /var/log/auth.log โ€” you'll see bots hammering root, admin, ubuntu with password guesses within minutes of the server going live.

SSH hardening isn't optional. It's the first thing you do, before you install any software, before you point DNS. This guide covers what actually reduces risk, with specific configs you can copy-paste.

Before You Start

  • You need root or sudo access to the server
  • Have a second SSH session open while testing changes โ€” don't lock yourself out
  • Know your current SSH port (default: 22)

1. Use SSH Keys, Not Passwords

Password authentication is fundamentally insecure: it's vulnerable to brute force, credential stuffing, and phishing. SSH keys are asymmetric cryptography โ€” the private key never leaves your machine, and the server only holds the public half.

Generate a Key (if you don't have one)

# Use Ed25519 โ€” it's the modern standard
ssh-keygen -t ed25519 -C "your_email@example.com"

# Save to default location (~/.ssh/id_ed25519) # Enter a strong passphrase, not empty

Copy Your Key to the Server

# The easy way
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server-ip

# If ssh-copy-id isn't available cat ~/.ssh/id_ed25519.pub | ssh user@your-server-ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Verify It Works

# Test key-based auth before disabling passwords
ssh -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes user@your-server-ip
# You should log in without a password prompt

2. Disable Password Authentication

Now that key-based auth works, disable passwords.

sudoedit /etc/ssh/sshd_config

Set these values:

# Disable password authentication entirely
PasswordAuthentication no
ChallengeResponseAuthentication no

# Disable root login via SSH PermitRootLogin no

# Disable empty passwords PermitEmptyPasswords no

# Only listen on specific interfaces if you don't need all # ListenAddress 0.0.0.0

# Change default port (optional, but reduces noise by 95%) Port 2222

Warning: Don't change the port and forget it. Note it somewhere. If you lock yourself out, you need console access to recover.
# Test the config before reloading
sudo sshd -t

# Reload SSH (existing sessions stay open) sudo systemctl reload sshd

3. Configure fail2ban

fail2ban monitors auth logs and temporarily bans IPs that fail too many authentication attempts. It's not a substitute for good security, but it reduces noise and automated attacks.

Install

# Ubuntu/Debian
sudo apt update && sudo apt install fail2ban -y

# CentOS/RHEL sudo yum install fail2ban -y

Configure

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudoedit /etc/fail2ban/jail.local

Set these values in [sshd] section:

[sshd]
enabled = true
port = 2222
maxretry = 3
findtime = 10m
bantime = 1h
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Check Status

sudo fail2ban-client status sshd
# Shows banned IPs and current rules

4. Limit SSH Access by User

Only specific users should be able to SSH in. Add an allow list.

# In /etc/ssh/sshd_config
AllowUsers deploy admin backupuser

Or allow only users in a specific group:

# Create an sshusers group
sudo groupadd sshusers
sudo usermod -aG sshusers deploy
sudo usermod -aG sshusers admin

# In /etc/ssh/sshd_config AllowGroups sshusers

5. Use a Restricted Authorized Keys File

Your users' authorized_keys files can include options that restrict what commands are allowed, forward ports, and limit source IPs.

# On the server, edit a specific user's authorized_keys
sudoedit /home/deploy/.ssh/authorized_keys

# Add restrictions before the key from="203.0.113.0/24",no-pty,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAA...

This example restricts that key to connections from the 203.0.113.0/24 subnet, disables TTY, and disables agent/X11 forwarding.

6. Harden the SSH Daemon Further

sudoedit /etc/ssh/sshd_config

Add or modify these:

# Use modern key exchange
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org

# Use modern ciphers Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com

# Use modern MACs MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

# Disable unused authentication methods HostbasedAuthentication no GSSAPIAuthentication no

# Disable .rhosts (legacy) IgnoreRhosts yes

# Log more detail LogLevel VERBOSE

# Disable connection multiplexing for sensitive servers DisableForwarding yes

Test and reload:

sudo sshd -t && sudo systemctl reload sshd

7. Set Up SSH Certificates (Advanced)

For teams managing many servers, SSH certificates eliminate the need to distribute and update public keys. This is how GitHub, GitLab, and major cloud providers handle SSH access at scale.

The setup requires a CA (Certificate Authority) key, signing server keys, and distributing the CA public key to servers. It's more complex but scales better and allows time-limited access.

This is beyond this guide's scope, but worth researching if you're managing more than 5 servers.

Verification Checklist

Run through this before declaring the server "done":

  • [ ] Can I SSH in with my key from a new location? (Test it)
  • [ ] Does password authentication fail? (ssh -o PreferredAuthentications=password ...)
  • [ ] Does root login fail? (ssh root@server)
  • [ ] Does fail2ban ban after 3 failed attempts? (Test from a throwaway IP or with a friend)
  • [ ] Are unused auth methods disabled?
  • [ ] Is the SSH port changed (if configured)?
  • [ ] Is the second SSH session still open? (Don't close it until everything works)
  • What This Doesn't Cover

    SSH hardening is necessary but not sufficient:

  • Firewall: Configure a firewall (ufw, iptables, or cloud security groups) to allow only necessary ports
  • Updates: Keep the OS and SSH package updated (apt update && apt upgrade)
  • Monitoring: Log and monitor SSH access โ€” know who's logging in and when
  • Backup access: Have a recovery plan (console access, rescue mode) if you break SSH

Quick Recovery if Locked Out

If you break SSH and get locked out:

1. Access the server console (most providers offer this) 2. Mount the disk 3. Edit /etc/ssh/sshd_config to restore working settings 4. Restart SSH

Don't let the config stop you from hardening โ€” just always keep a working session open while testing.

Rather than DIY? Let OpsHelp handle everything.

Managed hosting with support, security, backups, and monitoring โ€” from ยฃ50/mo.

Get Managed Hosting โ†’

Need help with your server setup?

OpsHelp provides professional server management, setup, and hardening services.

Get Help from OpsHelp โ†’