fail2ban watches a log file for a pattern, counts matches per address, and adds a firewall rule when the count is exceeded. That is all it does, and knowing that tells you exactly what it can and cannot help with.

What it stops

  • Repeated SSH password attempts - though keys already stop those.
  • Repeated failed logins on a form, if the failures are logged.
  • Simple scanners walking a list of known paths.

What it does not

It is reactive: it acts after several failures, so a single successful guess is never seen. It also cannot help against an attempt spread over a thousand addresses, each trying twice - which is what a serious attempt looks like.

A jail for a web login

# /etc/fail2ban/filter.d/mysite-login.conf
[Definition]
failregex = ^<HOST> .* "POST /login" 401
ignoreregex =
# /etc/fail2ban/jail.local
[mysite-login]
enabled  = true
filter   = mysite-login
logpath  = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime  = 3600

Test the pattern before enabling

fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/mysite-login.conf

It prints how many lines matched. Zero matches means the jail will never fire and you will believe you are protected.

Do not ban yourself

ignoreip = 127.0.0.1/8 ::1 YOUR.OFFICE.IP.HERE
Behind a CDN every request carries the proxy address, so the first ban blocks the proxy and with it every visitor you have. Configure the real client address first - see the article on being behind a CDN.
fail2ban-client status mysite-login\nfail2ban-client set mysite-login unbanip 1.2.3.4
Start with a one-hour ban, not a permanent one. A permanent ban list grows, is never reviewed, and eventually contains a customer.