🔐 Fail2Ban Setup and Configuration for Home Server
Overview
Fail2Ban monitors log files and bans IPs showing malicious signs (e.g., repeated failed login attempts). This guide covers:
- Installing Fail2Ban
- Configuring jails and filters for NGINX and Docker services (e.g., Portainer)
- Recommended filters for common attack vectors
1. Install Fail2Ban
sudo apt update
sudo apt install fail2ban
2. Configure Fail2Ban Jails
Use default (find them here: /etc/fail2ban/filter.d/), or use selfmade filters.
Create or edit /etc/fail2ban/jail.local to enable protections:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 192.168.0.0/16
# Protect NGINX HTTP authentication (e.g. basic auth, Portainer login via NGINX)
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
# Protect NGINX bad bots and common web attacks
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
# Protect SSH (optional, if you use SSH on this host)
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxretry = 5
bantime: duration for which an IP is banned (1 hour here).findtime: time window in which failures are counted (10 minutes).maxretry: number of failures allowed before ban.ignoreip: trusted IP addresses and ranges to whitelist.
3. Filters
-
nginx-http-auth Detects failed HTTP auth attempts by matching 401 Unauthorized in NGINX error logs. File: /etc/fail2ban/filter.d/nginx-http-auth.conf
-
nginx-botsearch Detects common malicious bots and scanning activity by matching suspicious request patterns in access logs. File: /etc/fail2ban/filter.d/nginx-botsearch.conf
-
sshd Protects SSH login by detecting failed login attempts in system auth logs.
4. Sample Filter Contents (If Missing)
/etc/fail2ban/filter.d/nginx-http-auth.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*(HTTP/1\.1|HTTP/2\.0)" 401
ignoreregex =
/etc/fail2ban/filter.d/nginx-botsearch.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*(etc/passwd|wp-admin|wp-login|phpmyadmin|xmlrpc\.php|\.env|\.git|\.svn|/admin|/login|/db_admin)"
ignoreregex =
5. Restart Fail2Ban
After configuration:
sudo systemctl restart fail2ban
6. Check Status and Bans
Check status of Fail2Ban and active jails:
sudo fail2ban-client status
sudo fail2ban-client status nginx-http-auth
sudo fail2ban-client status nginx-botsearch
sudo fail2ban-client status sshd
View currently banned IPs for a jail:
sudo fail2ban-client status <jailname>
For example:
sudo fail2ban-client status nginx-http-auth
7. Additional Tips
- Whitelist trusted IPs in the ignoreip directive to avoid accidental bans.
- Make sure your NGINX logging level includes error and access logs at the appropriate verbosity.
- Check /var/log/fail2ban.log for Fail2Ban activity.
- Consider adding email notifications for bans by configuring the action in jail.local.