L9. SSH Hardening: Keys, Config and Fail2Ban
Video generating
Check back soon for the video lesson on SSH Hardening: Keys, Config and Fail2Ban
SSH is the primary way administrators access Linux servers, which makes it a top target for attackers. Learn how to replace password authentication with key pairs, harden sshd_config, and use Fail2Ban to block brute-force attempts automatically.
How SSH Works
SSH (Secure Shell) creates an encrypted tunnel between your local machine and a remote server. When you type ssh user@server, a few things happen behind the scenes:
- Your client connects to port 22 (by default) on the remote host
- The server presents its host key so your client can verify it is the real server
- Both sides negotiate encryption algorithms
- The server authenticates you (password, key, or another method)
- You get a shell session over an encrypted channel
Every step in this process has security implications, and most of them can be tuned through a single configuration file.
Password Authentication vs Key-Based Authentication
The Problem with Passwords
Password-based SSH is simple to set up, but it opens the door to brute-force attacks. Automated scanners continuously probe internet-facing servers on port 22, trying thousands of username and password combinations per minute. Even strong passwords are vulnerable if there is no rate limiting.
How SSH Keys Work
SSH key authentication uses a pair of cryptographic keys:
| Component | Location | Purpose |
|---|---|---|
| Private key | Your local machine (~/.ssh/id_ed25519) | Proves your identity (never share this) |
| Public key | Remote server (~/.ssh/authorized_keys) | Verifies signatures from the private key |
Generating a Key Pair
# Generate an Ed25519 key pair (recommended over RSA for new setups)
ssh-keygen -t ed25519 -C "yourname@workstation"# You will be prompted for a file location and a passphrase
# Always set a passphrase: it encrypts the private key at rest
Copy the public key to the remote server:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote-serverThis appends your public key to ~/.ssh/authorized_keys on the server. After this, you can log in without a password.
Hardening sshd_config
The SSH daemon's configuration lives at /etc/ssh/sshd_config. Every setting below reduces your attack surface.
Disable Root Login
# /etc/ssh/sshd_config
PermitRootLogin noEven if an attacker guesses a password, they cannot log in directly as root. Administrators should log in with a normal account and escalate with sudo.
Disable Password Authentication
PasswordAuthentication no
PubkeyAuthentication yesOnce you have confirmed that key-based login works, disabling passwords eliminates brute-force attacks entirely.
Change the Default Port
Port 2222Changing the port does not stop a determined attacker, but it drops the volume of automated scans dramatically. Think of it as reducing noise, not adding real security.
Additional Hardening Options
# Limit login attempts per connection
MaxAuthTries 3# Disconnect idle sessions after 5 minutes
ClientAliveInterval 300
ClientAliveCountMax 0
# Restrict which users can log in via SSH
AllowUsers deploy monitor
# Disable X11 forwarding unless you need it
X11Forwarding no
After making changes, validate the config and restart:
sudo sshd -t # Test for syntax errors
sudo systemctl restart sshd
Fail2Ban: Automated Brute-Force Protection
Fail2Ban monitors log files for repeated failed login attempts and temporarily blocks offending IP addresses using firewall rules.
Installing Fail2Ban
# Debian/Ubuntu
sudo apt install fail2ban# RHEL/CentOS
sudo dnf install fail2ban
Basic Configuration
Create a local override file (never edit the main config directly):
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.localKey settings in /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = 2222 # Match your SSH port
maxretry = 5 # Ban after 5 failures
findtime = 600 # Within a 10-minute window
bantime = 3600 # Ban for 1 hour
Managing Fail2Ban
# Start and enable the service
sudo systemctl enable --now fail2ban# Check which IPs are currently banned
sudo fail2ban-client status sshd
# Manually unban an IP
sudo fail2ban-client set sshd unbanip 192.168.1.50
Putting It All Together
A hardened SSH setup combines all three layers:
- Key-only authentication removes the password attack vector
- sshd_config hardening limits who can log in and how
- Fail2Ban blocks IPs that still attempt brute-force scans
No single measure is enough on its own. Defense in depth applies to SSH just as it does to any other security domain.
- ✓SSH key pairs use public-key cryptography: the private key never leaves your machine, and the public key goes on the server
- ✓Disabling PasswordAuthentication in sshd_config eliminates brute-force password attacks
- ✓PermitRootLogin no forces administrators to use a regular account and escalate with sudo
- ✓Fail2Ban monitors logs and automatically bans IPs that exceed a failed-login threshold
1. What is the primary security benefit of disabling password authentication in sshd_config?
2. Which file on the remote server stores the public keys authorized to log in as a specific user?
3. What does Fail2Ban do when it detects repeated failed SSH login attempts from an IP address?