How to Secure Your Raspberry Pi with fail2ban and SSH Hardening

How to Secure Your Raspberry Pi with fail2ban and SSH Hardening

If your Raspberry Pi is accessible over the network, especially with SSH enabled, it is a potential target for brute-force login attempts. fail2ban is a service that monitors log files for repeated failed authentication attempts and automatically bans offending IP addresses. Combined with SSH hardening and a firewall, it forms a solid security foundation for your Pi.

What is fail2ban?

fail2ban is an intrusion prevention framework that scans log files like /var/log/auth.log and bans IP addresses that show signs of malicious activity. It works by adding temporary firewall rules to block offenders. Key features include:

  • Automatic banning of IPs after repeated failed login attempts
  • Configurable ban duration and thresholds
  • Support for SSH, Apache, Nginx, and many other services
  • Email notifications for ban events

Prerequisites

  • A Raspberry Pi running Raspberry Pi OS
  • SSH access to your Pi
  • sudo privileges

Installing fail2ban

Update your system and install fail2ban:

Bash
sudo apt update
sudo apt install fail2ban -y

fail2ban starts automatically after installation. Verify it is running:

Bash
sudo systemctl status fail2ban

Configuring fail2ban for SSH

The default configuration is stored in /etc/fail2ban/jail.conf, but you should never edit that file directly since it gets overwritten on updates. Instead, create a local override file:

Bash
sudo nano /etc/fail2ban/jail.local

Add the following configuration:

INI
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
banaction = iptables-multiport

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 24h

This configuration does the following:

  • bantime = 1h: Default ban duration of 1 hour for all jails
  • findtime = 10m: Time window to count failed attempts
  • maxretry = 5: Default max failures before banning
  • sshd jail: Overrides with stricter settings, banning for 24 hours after just 3 failed SSH login attempts

Restart fail2ban to apply the changes:

Bash
sudo systemctl restart fail2ban

Checking fail2ban Status

View the overall status and active jails:

Bash
sudo fail2ban-client status

Check the SSH jail specifically to see banned IPs:

Bash
sudo fail2ban-client status sshd

To manually unban an IP address if you accidentally lock yourself out:

Bash
sudo fail2ban-client set sshd unbanip 192.168.1.100

SSH Hardening

fail2ban protects against brute-force attacks, but hardening SSH itself adds another layer of defense.

Generate SSH Keys

On your local machine (not the Pi), generate an SSH key pair:

Bash
ssh-keygen -t ed25519 -C "your-email@example.com"

When prompted, choose a location for the key (the default ~/.ssh/id_ed25519 is fine) and optionally set a passphrase.

Copy the public key to your Raspberry Pi:

Bash
ssh-copy-id pi@your-pi-ip

Test that key-based login works before proceeding:

Bash
ssh pi@your-pi-ip

Disable Password Authentication and Root Login

Once key-based authentication is confirmed working, edit the SSH daemon configuration:

Bash
sudo nano /etc/ssh/sshd_config

Find and update these lines (or add them if they do not exist):

TEXT
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Restart the SSH service:

Bash
sudo systemctl restart sshd

Warning: Make sure your SSH key login works before disabling password authentication. If key login is not set up correctly, you will be locked out of your Pi.

Setting Up UFW Alongside fail2ban

UFW (Uncomplicated Firewall) complements fail2ban by controlling which ports are accessible. Install and configure it:

Bash
sudo apt install ufw -y

Allow SSH before enabling the firewall to avoid locking yourself out:

Bash
sudo ufw allow ssh
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable

If you run other services, allow their ports as well:

Bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Check the firewall status:

Bash
sudo ufw status verbose

For a more detailed guide on UFW, see our UFW setup guide.

Troubleshooting

  • Locked yourself out via SSH: Connect a keyboard and monitor directly to the Pi. Run sudo fail2ban-client set sshd unbanip <your-ip> and verify your SSH key is in ~/.ssh/authorized_keys on the Pi.
  • fail2ban not banning IPs: Check that the log path in your jail configuration matches where your system writes auth logs. Run sudo fail2ban-client status sshd to verify the jail is active.
  • fail2ban service fails to start: Check for syntax errors in /etc/fail2ban/jail.local by running sudo fail2ban-client -t.
  • SSH connection refused after config change: Ensure sshd is running with sudo systemctl status sshd. Review /etc/ssh/sshd_config for typos.
  • UFW blocking legitimate traffic: Review rules with sudo ufw status numbered and delete incorrect rules with sudo ufw delete <rule-number>.

Conclusion

Combining fail2ban with SSH hardening and UFW gives your Raspberry Pi a robust security posture. fail2ban automatically responds to brute-force attempts, key-based SSH authentication eliminates password guessing, and UFW ensures only the ports you explicitly allow are accessible. These three layers together significantly reduce the attack surface of your Pi.