Protego field desk
System Hardening · Hardening

L9. SSH Hardening: Keys, Config and Fail2Ban

Course outlineLesson 9 of 20

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:

  1. Your client connects to port 22 (by default) on the remote host
  2. The server presents its host key so your client can verify it is the real server
  3. Both sides negotiate encryption algorithms
  4. The server authenticates you (password, key, or another method)
  5. 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. Rate limiting reduces repeated attempts; use protected private keys and a tested authentication policy.

How SSH Keys Work

SSH key authentication uses a pair of cryptographic keys:

ComponentLocationPurpose
Private keyYour local machine (~/.ssh/id_ed25519)Proves your identity (never share this)
Public keyRemote server (~/.ssh/authorized_keys)Verifies signatures from the private key
When you connect, the server sends a challenge. Your client signs it with the private key, and the server checks the signature against the public key. During public-key authentication, the account password is not sent to the server.

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-server

This 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 no

Even 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.

The upstream PermitRootLogin default is prohibit-password, which still permits root public-key login; no is an explicit stricter choice. Distribution configuration can override upstream defaults.

Disable Password Authentication

PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey

Confirm a second key-based session first. PasswordAuthentication no alone does not disable keyboard-interactive authentication. ChallengeResponseAuthentication is a deprecated alias of KbdInteractiveAuthentication. The example enforces public-key authentication; adapt it if your approved design uses keyboard-interactive MFA.

Change the Default Port

Port 2222

Changing 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

# Detect an unresponsive client (not an idle human user) ClientAliveInterval 300 ClientAliveCountMax 3

# Restrict which users can log in via SSH AllowUsers deploy monitor

# Disable X11 forwarding unless you need it X11Forwarding no

ClientAliveCountMax 0 disables connection termination; alive probes are not an interactive user inactivity timer. Keep the current session open, confirm console recovery access, and validate before reloading:

sudo sshd -t            # Test for syntax errors
sudo sshd -T           # Inspect effective configuration; use -C for Match contexts
# Reload the service for your distribution (ssh or sshd), then test a second login

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.local

Key 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:

  1. Key-only authentication removes the password attack vector
  2. sshd_config hardening limits who can log in and how
  3. 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.

References

Exam Focus Points
  • ✓SSH key pairs use public-key cryptography: the private key never leaves your machine, and the public key goes on the server
  • ✓Disable password and keyboard-interactive authentication and explicitly require publickey when key-only access is intended
  • ✓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
Knowledge Check

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?