Introduction
This guide explains how to install and configure Fail2Ban on a Raspberry Pi to protect:
- SSH (sshd) from brute-force attacks
- Apache web server from malicious requests and bots
The setup uses nftables (modern firewall backend) instead of legacy iptables.
Prerequisites
- Raspberry Pi running Raspberry Pi OS (Debian-based)
- Root or sudo access
- Apache installed and logging to:
/var/log/apache2/access.log
1. Install Required Packages
sudo apt update
sudo apt install fail2ban nftables -y
Enable and start nftables:
sudo systemctl enable nftables
sudo systemctl start nftables
2. Configure nftables (Base Firewall)
Edit the configuration:
sudo nano /etc/nftables.conf
Example minimal ruleset:
table inet filter {
chain input {
type filter hook input priority 0;
policy drop;
iif lo accept
ct state established,related accept
tcp dport 22 accept
ip protocol icmp accept
counter drop
}
}
Apply the rules:
sudo nft -f /etc/nftables.conf
3. Configure Fail2Ban
Create a local configuration file:
sudo nano /etc/fail2ban/jail.local
Global Settings
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables-allports
findtime = 10m
bantime = 1h
maxretry = 5
backend = systemd
ignoreip = 127.0.0.1/8 ::1
4. Protect SSH (sshd)
Add the following:
[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
5. Protect Apache
Add protection for multiple access logs:
# Authentication failures
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/access.log
maxretry = 5
findtime = 10m
bantime = 1h
# Bad bots and scanners
[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/access.log
maxretry = 2
findtime = 10m
bantime = 6h
# Script probing (phpmyadmin, etc.)
[apache-noscript]
enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache2/access.log
maxretry = 3
findtime = 10m
bantime = 6h
# Exploit attempts
[apache-overflows]
enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/access.log
maxretry = 2
findtime = 10m
bantime = 12h
6. Start and Enable Fail2Ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
7. Verify Configuration
Check active jails:
sudo fail2ban-client status
Example output should include:
- sshd
- apache-auth
- apache-badbots
- apache-noscript
- apache-overflows
Check a specific jail:
sudo fail2ban-client status sshd
8. Monitor Logs
Real-time monitoring:
sudo tail -f /var/log/fail2ban.log
Check SSH logs:
sudo journalctl -u ssh
9. Testing
Simulate failed SSH logins:
ssh invaliduser@localhost
After multiple failures, verify the ban:
sudo fail2ban-client status sshd
10. Important Notes
- Ensure Apache logs use a standard format (combined log format recommended)
- Avoid mixing iptables with nftables
- Always whitelist your own IP using
ignoreip - Custom log formats may require custom Fail2Ban filters
11. Optional Hardening
Edit SSH configuration:
sudo nano /etc/ssh/sshd_config
Recommended settings:
PermitRootLogin no
PasswordAuthentication no
Restart SSH:
sudo systemctl restart ssh
Conclusion
With this setup:
- SSH brute-force attacks are automatically blocked
- Apache scanners and malicious bots are banned
- Firewall rules are handled efficiently using nftables
This provides a solid baseline security layer for any Raspberry Pi exposed to the internet.