Fail2ban se instalira prvi i tu se obično sve i završava: paket je unutra, servis radi, sshd je naizgled pokriven. Šest meseci kasnije ispostavi se da jail čita fajl koji na ovom sistemu ne postoji i da sve ostalo — pošta, kontrolni panel, forma za prijavu na sajtu — nikada nije ni bilo pokriveno.

Pređimo šta vredi uključiti na običnom VPS-u sa sajtom, koje brojeve tamo staviti i kako se uveriti da jail radi umesto da samo postoji u konfiguraciji.

Prvo proverite da li sshd išta hvata

Jedna komanda:

sudo fail2ban-client status sshd

Izlaz sadrži redove Currently failed, Total failed i Total banned. Ako je Total failed nula na serveru koji je na internetu bar jedan dan, jail ne radi. Uporedite to sa stvarnošću:

sudo lastb | wc -l

Hiljade neuspešnih pokušaja u lastb naspram nula u Fail2ban-u znače tačno jedno: filter gleda na pogrešno mesto.

Najčešći uzrok je Debian 12. On više ne instalira rsyslog podrazumevano, fajl /var/log/auth.log jednostavno ne postoji, a podrazumevani jail sshd podešen je da čita taj fajl. O tome nema poruke o grešci: servis se pokreće, status se ispisuje, brojači ostaju na nuli. Ispravka je prelazak na systemd dnevnik:

[sshd]
enabled = true
backend = systemd

Druga mogućnost je vratiti rsyslog kao paket, ako je običan tekstualni auth.log bitan drugim alatima. Ubuntu 24.04 ponaša se isto.

Gde idu vaša podešavanja

Ostavite /etc/fail2ban/jail.conf na miru: prepisuje se pri ažuriranju paketa i svaka izmena napravljena tamo jednog dana će tiho nestati. Vaša podešavanja idu u /etc/fail2ban/jail.local — taj fajl se čita poslednji i nadjačava zajednički.

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.25
bantime  = 1h
findtime = 10m
maxretry = 5
backend  = systemd

ignoreip sa sopstvenom adresom nije luksuz nego osiguranje: zaključati sebe napolje zbog greške u kucanju lakše je nego što zvuči. Ako nemate statičku adresu, držite drugi način ulaza pored SSH-a — konzolu provajdera ili VNC.

Jail koji menja sliku: recidive

Običan jail ima kratko pamćenje: pet pokušaja u deset minuta, sat vremena blokade, i sat kasnije sve počinje iznova. Bot sa tim živi sasvim udobno i vratiće se sutra i prekosutra. recidive zatvara upravo taj procep: čita ne sistemski dnevnik nego Fail2ban-ov sopstveni, što znači da blokira onoga koga je Fail2ban već blokirao.

[recidive]
enabled  = true
bantime  = 1w
findtime = 1d
maxretry = 5

Čitajte to kao „blokiran pet puta u jednom danu, nestaje na nedelju dana". Jail-u treba fajl /var/log/fail2ban.log, pa ako ste Fail2ban-ovo sopstveno beleženje premestili u syslog, i recidive će zahtevati backend = systemd.

U praksi je efekat ovog jednog jail-a obično primetniji od finog podešavanja svih ostalih: stalni gosti otpadaju i u dnevnicima ostaje samo sveža pozadina.

Šta još uključiti kada server nosi sajt

Po opadajućoj korisnosti:

  • nginx-http-auth ili apache-auth — gruba sila protiv osnovne autentifikacije. Potrebno ako su administracija ili probni sajt iza lozinke veb servera;
  • nginx-botsearch — skeniranje poznatih putanja: /wp-login.php, /phpmyadmin, /.env. To nije provala nego izviđanje, i upravo ono prethodi svemu ostalom;
  • nginx-limit-req — radi samo ako je limit_req_zone definisan u samom Nginx-u; bez toga je jail uključen i beskoristan;
  • postfix-sasl i dovecot — neophodni ako imate sopstvenu poštu. Pogađanje lozinki poštanskih sandučića je neprekidno i obično ga niko ne prati.
[nginx-botsearch]
enabled = true
logpath = /var/log/nginx/access.log

Forma za prijavu na samom sajtu posebna je priča. Aplikacija nema sopstveni dnevnik neuspešnih prijava, a u access.log neuspešan pokušaj izgleda kao običan POST sa 200 ili 302 — nerazlučiv od uspešnog bilo kojim opštim filterom. Postoje dve mogućnosti: naterati aplikaciju da neuspehe piše u syslog (većina sistema za upravljanje sadržajem ima dodatak za to) ili ograničiti učestalost zahteva ka stranici za prijavu. Drugo je ograničivač, a ne detektor, i bolje je to znati unapred.

Brojevi

bantime = 10m je podrazumevana vrednost zbog koje ljudi otpisuju Fail2ban kao beskoristan: deset minuta je dovoljno da se bot vrati. Sat vremena za prvu blokadu plus recidive na nedelju dana radi daleko bolje od trajnih blokada, koje se s vremenom pretvaraju u beskrajnu listu pravila.

maxretry = 3 za SSH pouzdan je način da zaključate sebe napolje. Pet pokušaja u deset minuta preseca grubu silu jednako dobro.

Sporo pogađanje — jedan pokušaj svakih pet minuta — nikada neće upasti u findtime. To nije razlog da prozor razvučete na jedan dan: dobićete lažne pozitive protiv sopstvenih kolega. Protiv sporog pogađanja ne radi prag nego isključena autentifikacija lozinkom.

Uverite se da blokada stiže do paketa

Fail2ban samo poziva spoljnu komandu. Ako se banaction ne poklapa sa onim što zaista filtrira saobraćaj, dnevnik će se puniti veselim redovima Ban 198.51.100.7 dok paketi nastavljaju da stižu. Debian 12 podrazumevano koristi nftables, a sa uključenim UFW-om ispravan izbor je banaction = ufw. Za proveru:

sudo nft list ruleset | grep -c f2b
sudo iptables -S | grep f2b

Bar jedna od dve treba da prikaže pravila. A sam filter možete testirati ne čekajući napad:

sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf

Na dnu izlaza piše koliko se redova poklopilo. Nula znači da se filter i dnevnik ne susreću i nema smisla dalje bilo šta podešavati.

Šta Fail2ban ne radi

Ne štiti od distribuirane grube sile: hiljadu adresa sa po jednim pokušajem nikada neće dostići prag ni pri kakvim podešavanjima. Ne otklanja uzrok — blokirana adresa ne poništava slabu lozinku. I ne zna ništa o reputaciji: adresa koja je jučerašnji dan provela provaljujući tuđe servere za njega je čista dok ne krene na vaš. Otuda kombinacija koja se koristi u praksi: ključevi umesto lozinki, Fail2ban kao ograničivač šuma i zajednička lista blokiranih (CrowdSec) kao znanje o tuđem iskustvu.

Poseban problem je što sve ovo povremeno treba pogledati. Niko nedeljama ne kuca fail2ban-client status po jail-u, a rastući broj blokada primeti se pošto je nešto već palo. Na demo stranicama ispod isti podaci stoje na jednoj stranici: lista jail-ova, ko je blokiran upravo sada i odakle dolaze pokušaji.