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:
sudo apt update
sudo apt install fail2ban -y
fail2ban starts automatically after installation. Verify it is running:
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:
sudo nano /etc/fail2ban/jail.local
Add the following configuration:
[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:
sudo systemctl restart fail2ban
Checking fail2ban Status
View the overall status and active jails:
sudo fail2ban-client status
Check the SSH jail specifically to see banned IPs:
sudo fail2ban-client status sshd
To manually unban an IP address if you accidentally lock yourself out:
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:
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:
ssh-copy-id pi@your-pi-ip
Test that key-based login works before proceeding:
ssh pi@your-pi-ip
Disable Password Authentication and Root Login
Once key-based authentication is confirmed working, edit the SSH daemon configuration:
sudo nano /etc/ssh/sshd_config
Find and update these lines (or add them if they do not exist):
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Restart the SSH service:
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:
sudo apt install ufw -y
Allow SSH before enabling the firewall to avoid locking yourself out:
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:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Check the firewall status:
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_keyson 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 sshdto verify the jail is active. - fail2ban service fails to start: Check for syntax errors in
/etc/fail2ban/jail.localby runningsudo fail2ban-client -t. - SSH connection refused after config change: Ensure
sshdis running withsudo systemctl status sshd. Review/etc/ssh/sshd_configfor typos. - UFW blocking legitimate traffic: Review rules with
sudo ufw status numberedand delete incorrect rules withsudo 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.