Spcnet.it Notizie geek e OSS/Linux. Su Telegram: InfoSec ITA Notizie
Home > Articolo > Fail2ban su Linux: come configurarlo per bloccare davvero gli attacchi brute-force
Fail2ban su Linux: come configurarlo per bloccare davvero gli attacchi brute-force

Perché ogni server esposto a Internet ha bisogno di Fail2ban

Basta controllare i log di autenticazione di un qualunque server Linux raggiungibile da Internet per rendersi conto di un fatto scomodo: nel giro di poche ore compaiono centinaia di tentativi di accesso falliti su SSH, pannelli web o form di login. Non è un attacco mirato: sono scanner automatici che perlustrano di continuo intere sottoreti, alla ricerca di credenziali deboli o servizi mal configurati. Ignorare questo rumore di fondo non è un’opzione, ma bloccare manualmente ogni IP sospetto è impraticabile.

Fail2ban risolve il problema analizzando i log in tempo reale e bannando automaticamente, tramite il firewall, gli indirizzi IP che superano una soglia di tentativi falliti in una finestra temporale configurabile. È uno strumento maturo, leggero, presente nei repository di tutte le principali distribuzioni, ma la configurazione di default lascia molto sul tavolo: un bantime di 10 minuti, tanto per fare un esempio, è quasi inutile contro un attaccante automatizzato che può semplicemente aspettare e riprovare.

In questa guida vediamo come installare, configurare e soprattutto tunare Fail2ban per ottenere una protezione reale, con particolare attenzione agli scenari più comuni su un server di produzione: SSH, Nginx, firewall moderni basati su nftables e persistenza dei ban tra un reboot e l’altro.

I tre concetti chiave: filter, jail, action

Prima di mettere mano alla configurazione conviene avere chiaro il modello concettuale di Fail2ban, perché tutta la configurazione ruota attorno a tre elementi:

  • Filter: un insieme di espressioni regolari che individuano le righe di log corrispondenti a un tentativo di accesso fallito.
  • Jail: combina un filtro con il percorso del log da monitorare, le soglie di attivazione e l’azione da eseguire al superamento della soglia.
  • Action: cosa succede quando la soglia viene superata. Nella maggior parte dei casi è una regola firewall, ma può includere anche l’invio di una notifica via email.

Fail2ban include già filtri e jail pronti per decine di servizi (SSH, Apache, Nginx, Postfix, Dovecot…). Nella pratica quotidiana ci si limita ad abilitare le jail utili e a regolare qualche parametro.

Installazione

Fail2ban è disponibile nei repository ufficiali di tutte le distribuzioni principali.

Debian/Ubuntu:

sudo apt update
sudo apt install fail2ban

Fedora / RHEL 9+ / Rocky / AlmaLinux:

sudo dnf install fail2ban

Arch Linux:

sudo pacman -S fail2ban

Abilitiamo e avviamo il servizio, poi verifichiamo lo stato:

sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban

Se lo stato non riporta active (running), i log vanno controllati con sudo journalctl -u fail2ban -n 50.

Configurare Fail2ban nel modo corretto

Un errore comune è modificare direttamente /etc/fail2ban/jail.conf: questo file viene sovrascritto a ogni aggiornamento del pacchetto, con conseguente perdita delle personalizzazioni. L’approccio corretto è creare un file dedicato dentro jail.d/:

sudo nano /etc/fail2ban/jail.d/custom.conf

In alternativa si può copiare il file di default in jail.local, che ha priorità sui valori in jail.conf:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

La sezione [DEFAULT]

Nella sezione [DEFAULT] si impostano i valori applicati a tutte le jail, salvo override specifico:

[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1
  • bantime: durata del ban. Il default (spesso 10 minuti) è troppo permissivo: 1 ora è un buon punto di partenza, e per attaccanti persistenti si può salire a 24h o 1w. Il valore -1 produce un ban permanente, da usare con cautela.
  • findtime: la finestra temporale in cui vengono contati i fallimenti.
  • maxretry: numero di tentativi falliti prima del ban. 5 è ragionevole per SSH, si può scendere a 3 per una postura più aggressiva.
  • ignoreip: gli IP che non verranno mai bannati. È fondamentale aggiungere qui il proprio IP prima di abilitare qualsiasi jail: restare fuori dal proprio server per un ban accidentale è un classico errore da evitare.

Se il server ha un indirizzo IPv6 pubblico, va incluso anche quello: alcuni filtri più datati intercettano solo IPv4, quindi conviene verificare che le jail catturino correttamente entrambi i protocolli.

La jail SSH

È la jail più importante per la maggior parte dei server. In jail.local o in un nuovo file /etc/fail2ban/jail.d/sshd.conf:

[sshd]
enabled  = true
port     = ssh
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s
maxretry = 3
bantime  = 1h

Se SSH è stato spostato su una porta non standard (buona pratica consigliata), va aggiornata la riga port. Sui sistemi basati su systemd, %(sshd_log)s punta automaticamente al journal; sui sistemi più datati che usano /var/log/auth.log o /var/log/secure, Fail2ban gestisce la differenza tramite il parametro backend. Dopo ogni modifica alla configurazione:

sudo fail2ban-client reload

Jail per Nginx

I server web attirano un tipo diverso di abuso: scanner di URL 404, bruteforcer su form di login, bot che generano richieste inutili.

[nginx-http-auth]
enabled  = true
logpath  = %(nginx_error_log)s
maxretry = 3

[nginx-limit-req]
enabled  = true
logpath  = %(nginx_error_log)s
maxretry = 10

La jail nginx-limit-req intercetta i client che superano i limit_req configurati in Nginx: è una combinazione efficace se il server web è già stato ottimizzato per gestire traffico elevato. Se Fail2ban segnala che un percorso di log non esiste, va impostato esplicitamente, ad esempio logpath = /var/log/nginx/error.log.

Verificare jail e ban attivi

Il comando fail2ban-client è lo strumento principale per monitorare la situazione. Elenco delle jail attive:

sudo fail2ban-client status

Dettaglio di una jail specifica, comprensivo di IP attualmente bannati:

sudo fail2ban-client status sshd

Per bannare o sbannare manualmente un IP:

sudo fail2ban-client set sshd banip 203.0.113.99
sudo fail2ban-client set sshd unbanip 203.0.113.99

Il comando unbanip è quello da tenere a portata di mano nel caso in cui ci si banni da soli per errore, prima di aver aggiunto il proprio IP a ignoreip.

Ban incrementali con la jail recidive

Una delle funzionalità meno conosciute ma più efficaci di Fail2ban è la jail recidive, che monitora il log interno di Fail2ban stesso e applica ban molto più lunghi agli IP che, dopo la scadenza di un primo ban, tornano a fare bruteforcing.

[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
action   = %(action_mwl)s
bantime  = 1w
findtime = 1d
maxretry = 5

Con questa configurazione, un IP bannato 5 volte in un giorno riceve un ban di una settimana: è l’equivalente più vicino a una blocklist persistente senza dover integrare feed di threat intelligence esterni. Su sistemi che scrivono solo sul journal, va impostato backend = systemd nella jail recidive, oppure va verificato che Fail2ban stia scrivendo un log tradizionale.

Testare i filtri prima di attivarli

Prima di abilitare una jail, conviene verificare che il regex del filtro corrisponda davvero alle righe di log presenti sul sistema:

sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

L’output riporta gli IP individuati e il numero di righe che hanno fatto match. Un filtro che non intercetta nulla non protegge nulla: questo comando è indispensabile soprattutto quando si scrive un filtro personalizzato per un’applicazione custom, dentro /etc/fail2ban/filter.d/:

# /etc/fail2ban/filter.d/myapp-auth.conf
[Definition]
failregex = ^<HOST> .* "POST /login" 401
ignoreregex =

Il tag <HOST> è obbligatorio: Fail2ban lo sostituisce con un’espressione regolare che cattura l’indirizzo IP da bannare. Un pattern troppo generico rischia di bannare traffico legittimo, quindi va sempre validato con fail2ban-regex prima di collegarlo a una jail attiva.

nftables, firewalld e persistenza dei ban

Su Debian 12+ e Ubuntu 22.04+, nftables è il backend firewall di default. L’azione di ban predefinita di Fail2ban usa ancora iptables, che nella maggior parte delle installazioni funziona tramite il layer di compatibilità iptables-nft. Se invece si usa nftables puro, l’azione va impostata esplicitamente:

banaction = nftables-multiport
banaction_allports = nftables-allports

Su RHEL, Fedora e Rocky, dove firewalld è lo standard, va usata l’azione corrispondente:

banaction = firewallcmd-rich-rules
banaction_allports = firewallcmd-allports

Per default, i ban sono mantenuti in memoria e vengono persi a ogni riavvio. Per farli sopravvivere ai reboot va abilitato il database SQLite (su molte distribuzioni recenti è già attivo di default):

dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 7d

Una configurazione di partenza completa

Ecco un file /etc/fail2ban/jail.d/custom.conf che copre i casi d’uso più comuni su un server Linux tipico, da usare come punto di partenza:

[DEFAULT]
bantime  = 2h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 7d

[sshd]
enabled  = true
port     = ssh
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s
maxretry = 3
bantime  = 6h

[nginx-http-auth]
enabled  = true
logpath  = %(nginx_error_log)s
maxretry = 4

[nginx-limit-req]
enabled  = true
logpath  = %(nginx_error_log)s
maxretry = 10

[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
bantime  = 1w
findtime = 1d
maxretry = 5
sudo fail2ban-client reload
sudo fail2ban-client status

Cosa Fail2ban non risolve

Fail2ban è uno strumento reattivo, non preventivo: banna un IP solo dopo che ha già effettuato diversi tentativi. Non copre, da solo, alcuni scenari:

  • attacchi bruteforce distribuiti su migliaia di IP diversi, ciascuno con uno o due tentativi soltanto;
  • exploit zero-day che non generano righe di log riconoscibili;
  • attacchi a livello applicativo che non producono un fallimento di autenticazione tracciabile.

Per una protezione a più livelli, Fail2ban va affiancato all’autenticazione SSH tramite chiavi (disabilitando del tutto l’autenticazione via password), a un firewall configurato correttamente e a una revisione periodica dei log. Un’attenzione particolare va riservata ai server dietro Cloudflare o un altro reverse proxy: senza ripristinare l’IP originale del visitatore (tramite mod_remoteip su Apache o real_ip_module su Nginx), Fail2ban finirebbe per bannare gli IP del proxy stesso invece degli attaccanti reali.

Comandi da tenere sempre a portata di mano

  • sudo fail2ban-client status — elenco di tutte le jail attive
  • sudo fail2ban-client status sshd — stato dettagliato di una jail
  • sudo fail2ban-client set sshd banip 1.2.3.4 — ban manuale di un IP
  • sudo fail2ban-client set sshd unbanip 1.2.3.4 — rimozione manuale di un ban
  • sudo fail2ban-client reload — ricarica la configurazione dopo una modifica
  • sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf — test di un filtro
  • sudo tail -f /var/log/fail2ban.log — monitoraggio dei ban in tempo reale

Conclusione

Fail2ban resta uno degli strumenti che meritano un posto fisso su ogni server Linux esposto a Internet: l’installazione richiede pochi minuti e già con una configurazione minima riduce in modo drastico il rumore generato da scanner SSH e probe automatizzati sui servizi web. La differenza reale, però, la fanno tre accorgimenti spesso trascurati: impostare un bantime ragionevole (il default di 10 minuti è quasi inutile), aggiungere sempre il proprio IP a ignoreip prima di abilitare le jail, e attivare la jail recidive per penalizzare chi insiste. Da soli, questi tre passaggi fanno la differenza tra un’installazione di default e una protezione che funziona davvero.

Fonte: Fail2ban on Linux: Protect Your Server from Brute-Force Attacks, LinuxBlog.io

Condividi: Twitter  |  Facebook  |  LinkedIn
Unisciti alla discussione

Questo è un blog del Fediverso: puoi trovare questo articolo ovunque con @blog@insicurezzadigitale.com e ogni commento/risposta apparirà qui sotto.

Se vuoi commentare su Fail2ban su Linux: come configurarlo per bloccare davvero gli attacchi brute-force, utilizza la discussione sul Forum.

>> forum community