Fail2ban
1) Install & start fail2ban
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
⸻
2) Use jail.local (don’t edit packaged files)
Create /etc/fail2ban/jail.local — this overrides defaults and survives package updates.
sudo nano /etc/fail2ban/jail.local
Paste this example (explained below):
[DEFAULT]
# ban time in seconds (1h)
bantime = 3600
# number of failures before ban
maxretry = 5
# time window for maxretry (seconds) - 10 minutes
findtime = 600
# sendmail configuration left empty unless you want email alerts
# destemail = root@localhost
# action = iptables-multiport[name=default, port="ssh", protocol=tcp]
banaction = iptables-multiport
# whitelist local trusted hosts (your office IPs)
# add any IPs you DO NOT want to ban:
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 203.0.113.5
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 4
bantime = 3600
findtime = 600
# block invalid HTTP auth attempts (useful if you have basic-auth sites)
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 3600
# block repeated 404s or common bot patterns
[nginx-404]
enabled = true
filter = nginx-404
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 20
findtime = 600
bantime = 3600
Save and exit.
⸻
3) Add filters (if not present)
Fail2ban ships many filters. You likely already have sshd, nginx-http-auth. For nginx-404 create a small filter.
Create /etc/fail2ban/filter.d/nginx-404.conf:
sudo nano /etc/fail2ban/filter.d/nginx-404.conf
Paste:
[Definition]
# catches many bots hammering for non-existent pages
failregex = ^<HOST> -.*"(GET|POST).*" 404
ignoreregex =
Save.
(If you want more advanced nginx bot filters there are community filters such as nginx-badbots or nginx-noscript you can add similarly.)
⸻
4) Test the filters with fail2ban-regex
Before reloading, test your filter against log files:
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-404.conf
sudo fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-http-auth.conf
The command will show which lines match and help you tune failregex.
⸻
5) Reload fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status
Check status of jails:
sudo fail2ban-client status sshd
sudo fail2ban-client status nginx-404
⸻
6) Common admin commands • List all jails:
sudo fail2ban-client status
• Show details of a jail:
sudo fail2ban-client status sshd
• Unban an IP:
sudo fail2ban-client set sshd unbanip 203.0.113.123
• Manually ban an IP:
sudo fail2ban-client set sshd banip 203.0.113.123
⸻
7) Helpful tips / best practices
- Whitelist your home/work IPs in ignoreip so you don’t lock yourself out.
- If you use a nonstandard SSH port, set port = 2222 in the sshd section or use port = ssh if your /etc/services maps it.
- If you run a cloud firewall (UFW or provider firewall), fail2ban still works with iptables on the instance; ensure your firewall allows fail2ban to add rules. If you use ufw, default banaction = ufw can be used instead of iptables-multiport.
- Use maxretry and findtime to tune aggressiveness. Lower maxretry = more aggressive banning.
- Monitor logs: /var/log/fail2ban.log.
⸻
8) Nginx-specific notes
- nginx-http-auth blocks repeated basic-auth failures (uses error.log). Works well if you protect endpoints with HTTP auth.
- nginx-404 is helpful to block crawlers looking for admin panels, wp-login, etc. Tune maxretry higher (e.g., 20) so normal users aren’t banned.
- You can add nginx-badbots filter to block known malicious user-agents; make sure it doesn’t match legit bots you rely on (e.g., Googlebot).
⸻
9) Quick verification
After enabling and restarting, try fetching:
sudo fail2ban-client status
# Then intentionally trigger a rule from a throwaway IP or simulate logs, or review:
sudo tail -n 50 /var/log/fail2ban.log