UFW + fail2ban not working with `nginx` to block attack scripts

But as you see the IP is already banned and the attacker still can access.

This issue is similar https://github.com/fail2ban/fail2ban/issues/2545

Shortly: keep-alive vs. ufw (so I suggest don't use it, or extend an action to kill a connection).

But why I don't get an IPv6 log entry then?

There are 2 reasons:

  • either your fail2ban version <= 0.9 (IPv6 support got first time implemented in 0.10);
  • or the logged message looks a bit different for IPv6, so failregex doesn't match that anymore (rewrite failregex compatible for both families);

UPD 1:

  • either (better) place the rule for established connections after chain with fail2ban rules, or simply remove the rule whitelistening established connection;
  • or you can use something like this to kill all established connection from IP to both local http/https ports:
ss -o state established -K dst $ip 'sport = 80 or sport = 443'

Note this expecting modern kernel (version >= 4.9 I suppose).
You can also add it directly in jail.local (without creating new local action config-file):

[some-nginx-jail]
_killstmt = ss -o state established -K dst <ip> 'sport = 80 or sport = 443'
banaction = %(known/banaction)s[actionban="<known/actionban><br>%(_killstmt)s"]
  • or force nginx to close the connection by failed authentication (e. g. use own 40x location with keepalive_timeout 0;, which can also write an error into different log-file in order to avoid "parasite" traffic in sense of fail2ban, see fail2ban/wiki/Best-practice#reduce-parasitic-log-traffic for more info);
    or simply make return 444; in corresponding location, that will cause a close the connection (see http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return for documentation)