Fail2ban creates Firewall Rule but Auth Session still open

MisterIX

New Member
Dear forum members

I use NGINX as reverse proxy to protect my Gitea dashboard on a VServer. SSL with Let's encrypt went fine and I installed fail2ban to block IP-addresses when a user tries to log on more than 5 times with the wrong username / PW combination.

And fail2ban works fine. I'm using the ufw-multiport.conf from Xela in actions.d and the firewall rules look like this, once I provoke a ban by giving false credentials:

Code:
root@********:/var/log# ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 80,443/tcp                 DENY IN     177.191.157.126             (log)
[ 2] 32221                      ALLOW IN    Anywhere
[ 3] 80/tcp                     ALLOW IN    Anywhere
[ 4] 443                        ALLOW IN    Anywhere
[ 5] 32221 (v6)                 ALLOW IN    Anywhere (v6)
[ 6] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 7] 443 (v6)                   ALLOW IN    Anywhere (v6)

So the first rule is the new deny rule for my IP.
But unfortunately the authentication session stays open. I can provide more false credentials and my attempts are logged in the fail2ban.log:

Code:
2022-09-18 11:15:31,970 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:15:31
2022-09-18 11:15:34,692 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:15:34
2022-09-18 11:15:37,759 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:15:37
2022-09-18 11:15:40,560 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:15:40
2022-09-18 11:15:43,265 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:15:43
2022-09-18 11:15:43,320 fail2ban.actions        [15244]: NOTICE  [gitea] Ban 177.191.157.126
2022-09-18 11:15:49,663 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:15:49
2022-09-18 11:15:52,699 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:15:52
2022-09-18 11:15:55,404 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:15:55
2022-09-18 11:16:01,314 fail2ban.filter         [15244]: INFO    [gitea] Found 177.191.157.126 - 2022-09-18 11:16:00
2022-09-18 11:30:43,305 fail2ban.actions        [15244]: NOTICE  [gitea] Unban 177.191.157.126

Only when I use another browser to open the gitea dashboard or if I restart the browser that I used before, the ban is successful.
So obviously the open authentication session outrules the firewall configuration. I'm now searching for a ban action that I can add to my gitea configuration in .../jail.d/jail.local that will force nginx to drop the session immediately and force the site to reload into emptyness.

Code:
[gitea]
enabled = true
filter = gitea
logpath = /var/lib/gitea/log/gitea.log
maxretry = 5
findtime = 600
bantime = 900
action = ufw-multiport[port="80,443", protocol=tcp]

I thought the nginx-block-map-conf in actions.d could maybe help, but I didn't find a usage example.

Any incoming ideas will be greatly appreciated.

Kind regards, MisterIX.

PS. Oh, aus reiner Gewohnheit habe ich auf Englisch gepostet. Ich hoffe, dass ist nicht so schlimm, sorry.
 
Last edited:
ufw ist meines Wissens ja nur ein Frontend von iptables. Es wäre mal interessant zu wissen, wie der komplette iptables-Regelsatz aussieht, der da am Ende bei rauskommt. DIesen kannst du mit iptables -L ausgeben lassen. Es wäre denkbar, dass es relativ an Anfang eine Regel gibt, die bestehende Verbindungen erlaubt, bevor ufw die Regeln von fail2ban einbaut.
Deine jail ist korrekt konfiguriert, denn der Block greift prinzipiell ja. Problematisch ist da entweder die ufw Konfiguration oder die Ban-Action von fail2ban.
 
Ok, so sehen meine IP-Tables aus:

Code:
root@*************:~# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ufw-before-logging-input  all  --  anywhere             anywhere
ufw-before-input  all  --  anywhere             anywhere
ufw-after-input  all  --  anywhere             anywhere
ufw-after-logging-input  all  --  anywhere             anywhere
ufw-reject-input  all  --  anywhere             anywhere
ufw-track-input  all  --  anywhere             anywhere

Chain FORWARD (policy DROP)
target     prot opt source               destination
ufw-before-logging-forward  all  --  anywhere             anywhere
ufw-before-forward  all  --  anywhere             anywhere
ufw-after-forward  all  --  anywhere             anywhere
ufw-after-logging-forward  all  --  anywhere             anywhere
ufw-reject-forward  all  --  anywhere             anywhere
ufw-track-forward  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ufw-before-logging-output  all  --  anywhere             anywhere
ufw-before-output  all  --  anywhere             anywhere
ufw-after-output  all  --  anywhere             anywhere
ufw-after-logging-output  all  --  anywhere             anywhere
ufw-reject-output  all  --  anywhere             anywhere
ufw-track-output  all  --  anywhere             anywhere

Chain ufw-after-forward (1 references)
target     prot opt source               destination

Chain ufw-after-input (1 references)
target     prot opt source               destination
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:netbios-ns
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:netbios-dgm
ufw-skip-to-policy-input  tcp  --  anywhere             anywhere             tcp dpt:netbios-ssn
ufw-skip-to-policy-input  tcp  --  anywhere             anywhere             tcp dpt:microsoft-ds
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:bootps
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:bootpc
ufw-skip-to-policy-input  all  --  anywhere             anywhere             ADDRTYPE match dst-type BROADCAST

Chain ufw-after-logging-forward (1 references)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-after-logging-input (1 references)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-after-logging-output (1 references)
target     prot opt source               destination

Chain ufw-after-output (1 references)
target     prot opt source               destination

Chain ufw-before-forward (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere             icmp destination-unreachable
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     icmp --  anywhere             anywhere             icmp parameter-problem
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ufw-user-forward  all  --  anywhere             anywhere

Chain ufw-before-input (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ufw-logging-deny  all  --  anywhere             anywhere             ctstate INVALID
DROP       all  --  anywhere             anywhere             ctstate INVALID
ACCEPT     icmp --  anywhere             anywhere             icmp destination-unreachable
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     icmp --  anywhere             anywhere             icmp parameter-problem
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ACCEPT     udp  --  anywhere             anywhere             udp spt:bootps dpt:bootpc
ufw-not-local  all  --  anywhere             anywhere
ACCEPT     udp  --  anywhere             224.0.0.251          udp dpt:mdns
ACCEPT     udp  --  anywhere             239.255.255.250      udp dpt:1900
ufw-user-input  all  --  anywhere             anywhere

Chain ufw-before-logging-forward (1 references)
target     prot opt source               destination

Chain ufw-before-logging-input (1 references)
target     prot opt source               destination

Chain ufw-before-logging-output (1 references)
target     prot opt source               destination

Chain ufw-before-output (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ufw-user-output  all  --  anywhere             anywhere

Chain ufw-logging-allow (0 references)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW ALLOW] "

Chain ufw-logging-deny (2 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere             ctstate INVALID limit: avg 3/min burst 10
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-not-local (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type MULTICAST
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type BROADCAST
ufw-logging-deny  all  --  anywhere             anywhere             limit: avg 3/min burst 10
DROP       all  --  anywhere             anywhere

Chain ufw-reject-forward (1 references)
target     prot opt source               destination

Chain ufw-reject-input (1 references)
target     prot opt source               destination

Chain ufw-reject-output (1 references)
target     prot opt source               destination

Chain ufw-skip-to-policy-forward (0 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere

Chain ufw-skip-to-policy-input (7 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere

Chain ufw-skip-to-policy-output (0 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

Chain ufw-track-forward (1 references)
target     prot opt source               destination

Chain ufw-track-input (1 references)
target     prot opt source               destination

Chain ufw-track-output (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             ctstate NEW
ACCEPT     udp  --  anywhere             anywhere             ctstate NEW

Chain ufw-user-forward (1 references)
target     prot opt source               destination

Chain ufw-user-input (1 references)
target     prot opt source               destination
ufw-user-logging-input  tcp  --  dynamic-077-191-157-126.77.191.pool.telefonica.de  anywhere             multiport dports http,https
DROP       tcp  --  dynamic-077-191-157-126.77.191.pool.telefonica.de  anywhere             multiport dports http,https
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:32221
ACCEPT     udp  --  anywhere             anywhere             udp dpt:32221
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
ACCEPT     udp  --  anywhere             anywhere             udp dpt:https

Chain ufw-user-limit (0 references)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 5 LOG level warning prefix "[UFW LIMIT BLOCK] "
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain ufw-user-limit-accept (0 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

Chain ufw-user-logging-forward (0 references)
target     prot opt source               destination

Chain ufw-user-logging-input (1 references)
target     prot opt source               destination
LOG        tcp  --  dynamic-077-191-157-126.77.191.pool.telefonica.de  anywhere             multiport dports http,https ctstate NEW limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "
RETURN     tcp  --  dynamic-077-191-157-126.77.191.pool.telefonica.de  anywhere             multiport dports http,https

Chain ufw-user-logging-output (0 references)
target     prot opt source               destination

Chain ufw-user-output (1 references)
target     prot opt source               destination
 
Das netfilter Modul im Kernel arbeitet die Regeln der Reihe nach ab, bis eine Regel zutrifft. ufw hat in der Chain ufw-before-input an zweiter Stelle den ACCEPT für bestehende Verbindungen stehen, während fail2ban in die ufw-user-input reinschreibt, wenn ich das richtig interepretiert habe - der Eintrag von einem Telefonica-Anschluss. Die ufw-user-input wird aber in der ufw-before-input erst an letztere Stelle eingetragen und die wird bei bestehenden Verbindungen gar nicht mehr abgearbeitet.
Da ich ufw nicht nutze (arbeite direkt mit iptables), kann ich dir aber nicht sagen, wie du diese Verhalten bei der ufw beeinflussen kannst.
 
Danke nochmal @danton! Also schließlich habe ich mich von ufw verabschiedet und bin in die iptables Konfiguration gewechselt.
apt-get purge ufw
reboot
iptables -F (löscht alle verbliebenden nicht standard rules)
und dann dieser Anleitung folgen:
https://upcloud.com/resources/tutorials/configure-iptables-ubuntu
Wichtig, falls jemand dies liest und sich noch nicht mit iptables auskennt: Die Firewall rules müssen manuell gespeichert werden.
Ohne das package iptables-persistent werden diese nach einem Neustart des Servers nicht wieder eingelesen. Steht alles in der Anleitung.
Nach der Umstellung der fail2ban Regeln in jail.local zurück auf

iptables-multiport[name=*********, port="http,https"]

greifen die Firewall Regeln.
 
Back
Top