Installare e configurare Fail2Ban su un VPS Linux
Configura Fail2Ban per bloccare attacchi brute-force su SSH e Nginx. Copre le azioni di ban con UFW e nftables, jail personalizzate, escalation recidive e test dei filtri su Ubuntu 24.04 e Debian 12.
Fail2Ban monitora i file di log alla ricerca di autenticazioni fallite ripetute e blocca gli indirizzi IP incriminati attraverso il firewall. Ferma gli attacchi brute-force prima che abbiano successo. Un VPS appena avviato riceve tipicamente tentativi di login SSH nel giro di pochi minuti. Fail2Ban è la difesa standard.
Questa guida copre l'installazione su Ubuntu 24.04 e Debian 12, la configurazione delle jail SSH e Nginx, entrambi i backend di azione di ban (UFW e nftables), la jail recidive per i recidivi, e il test dei filtri con fail2ban-regex. Ogni modifica alla configurazione include un passaggio di verifica.
Prerequisiti: Un VPS con Ubuntu 24.04 o Debian 12 con accesso root o sudo. Il firewall deve essere già attivo e SSH deve essere già messo in sicurezza. Questa guida fa parte della serie sicurezza VPS Linux.
Come installo Fail2Ban su Ubuntu 24.04 e Debian 12?
Installa Fail2Ban con apt. Il pacchetto si trova nei repository predefiniti di entrambe le distribuzioni. Ubuntu 24.04 fornisce la versione 1.0.2, così come Debian 12. Su Debian 12, è necessario anche python3-systemd affinché Fail2Ban possa leggere il journal di systemd.
sudo apt update && sudo apt install -y fail2ban
Su Debian 12, installa i binding Python per systemd:
sudo apt install -y python3-systemd
Abilita e avvia il servizio:
sudo systemctl enable --now fail2ban
Il flag enable fa avviare Fail2Ban al boot. Il flag --now lo avvia immediatamente. Verifica che sia in esecuzione:
sudo systemctl status fail2ban
L'output mostra Active: active (running) nell'output. Se lo stato mostra failed, controlla il journal:
journalctl -u fail2ban -n 20 --no-pager
Qual è la differenza tra jail.conf, jail.local e jail.d/?
jail.conf è il file di configurazione predefinito distribuito con il pacchetto. Gli aggiornamenti del pacchetto lo sovrascrivono. Non modificare mai jail.conf direttamente. Le tue modifiche spariranno al prossimo apt upgrade.
jail.local è il file di override tradizionale. Fail2Ban legge prima jail.conf, poi applica le impostazioni di jail.local sopra. Funziona, ma il file diventa un monolite difficile da mantenere.
La directory jail.d/ è l'approccio migliore. Inserisci un file .conf per ogni jail. Fail2Ban li carica in ordine alfabetico dopo jail.conf e jail.local. Ogni servizio resta isolato ed è facile aggiungere o rimuovere jail senza toccare altre configurazioni.
Questa guida usa file drop-in in jail.d/. Verifica che la directory esista:
ls /etc/fail2ban/jail.d/
Dovrebbe già esistere. Se vedi file come defaults-debian.conf, è normale. Su Ubuntu 24.04, questo file abilita la jail sshd e imposta banaction = nftables come azione di ban predefinita. Su Debian 12, abilita la jail sshd. Poiché Fail2Ban carica i file di jail.d/ in ordine alfabetico, qualsiasi file di impostazioni predefinite personalizzato deve essere ordinato dopo defaults-debian.conf per sovrascriverne le impostazioni. Questa guida usa zz-defaults.conf per questo motivo.
Come configuro la jail SSH in Fail2Ban?
La jail SSH monitora i log di autenticazione e blocca gli IP che falliscono troppe volte il login. Su Ubuntu 24.04 e Debian 12, la jail sshd è abilitata di default tramite /etc/fail2ban/jail.d/defaults-debian.conf. Ma i valori predefiniti sono permissivi (5 tentativi, ban di 10 minuti). Inaspriscili.
Crea una configurazione drop-in:
sudo tee /etc/fail2ban/jail.d/sshd.conf > /dev/null << 'EOF'
[sshd]
enabled = true
mode = aggressive
port = ssh
backend = systemd
maxretry = 3
findtime = 600
bantime = 3600
EOF
Significato di ogni parametro:
| Parametro | Valore | Significato |
|---|---|---|
enabled |
true |
Attiva questa jail |
mode |
aggressive |
Rileva più pattern di errore SSH, inclusi errori di autenticazione con chiave |
port |
ssh |
Monitora la porta SSH (risolta in 22, o la tua porta personalizzata) |
backend |
systemd |
Legge dal journal di systemd anziché dai file di log |
maxretry |
3 |
Blocca dopo 3 tentativi falliti |
findtime |
600 |
Conta i fallimenti in una finestra di 10 minuti |
bantime |
3600 |
Blocca per 1 ora (3600 secondi) |
Se hai cambiato la porta SSH (dovresti farlo), sostituisci ssh con il tuo numero di porta:
port = 2222
Riavvia Fail2Ban per applicare:
sudo systemctl restart fail2ban
Verifica che la jail sia attiva:
sudo fail2ban-client status sshd
Output atteso:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
la riga Journal matches conferma che Fail2Ban legge dal journal di systemd, non da un file di log. Questo è corretto per Ubuntu 24.04 e Debian 12.
Come configuro Fail2Ban con UFW come azione di ban?
Se usi UFW come firewall, configura Fail2Ban per inserire le regole di ban tramite UFW. È il percorso più semplice, adatto alla maggior parte delle configurazioni.
Crea un file di impostazioni predefinite che imposta UFW come azione di ban. Il nome zz-defaults.conf è intenzionale: su Ubuntu 24.04, il pacchetto include defaults-debian.conf che imposta banaction = nftables. Il tuo file deve essere ordinato alfabeticamente dopo per sovrascrivere quel valore.
sudo tee /etc/fail2ban/jail.d/zz-defaults.conf > /dev/null << 'EOF'
[DEFAULT]
banaction = ufw
banaction_allports = ufw
backend = systemd
EOF
Riavvia e verifica:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Quando Fail2Ban blocca un IP, esegue ufw insert 1 deny from <IP> to any. Controlla le regole UFW dopo un ban:
sudo ufw status numbered
Vedrai le regole deny di Fail2Ban in cima alla lista.
Come configuro Fail2Ban per usare nftables invece di iptables?
Per server di produzione che usano nftables direttamente (senza UFW), usa l'azione di ban nftables-multiport. Fail2Ban crea la propria tabella nftables e gestisce le regole di ban lì senza interferire con il tuo set di regole esistente.
Crea il file delle impostazioni predefinite. Su Ubuntu 24.04, defaults-debian.conf imposta già banaction = nftables, quindi questo passaggio è tecnicamente opzionale. Ma è buona pratica essere espliciti. Su Debian 12, questo file è obbligatorio.
sudo tee /etc/fail2ban/jail.d/zz-defaults.conf > /dev/null << 'EOF'
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables[type=allports]
chain = input
backend = systemd
EOF
Riavvia e verifica:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Per confermare l'integrazione nftables, elenca la tabella Fail2Ban:
sudo nft list tables
L'output mostra una tabella chiamata inet f2b-table. Dopo un ban, ispeziona il suo contenuto:
sudo nft list table inet f2b-table
Confronto tra azioni di ban UFW e nftables
| Aspetto | UFW (banaction = ufw) |
nftables (banaction = nftables-multiport) |
|---|---|---|
| Comando di ban | ufw insert 1 deny from <IP> |
Aggiunge l'IP a un set nftables |
| Dove compaiono le regole | ufw status numbered |
nft list table inet f2b-table |
| Supporto IPv6 | Sì (UFW lo gestisce) | Sì (famiglia inet) |
| Persistenza | Le regole UFW persistono ai riavvii | Fail2Ban le riapplica all'avvio |
| Prestazioni | Corrispondenza lineare delle regole | Ricerca basata su set (più veloce su larga scala) |
| Adatto per | Configurazioni semplici, servizio singolo | Produzione, molte jail, alto numero di ban |
Scegli un approccio. Non mescolare azioni di ban UFW e nftables sullo stesso server.
Come metto il mio indirizzo IP in whitelist in Fail2Ban?
Aggiungi il tuo IP a ignoreip per evitare di bloccarti. Questo è importante. Se sbagli la password tre volte, Fail2Ban bloccherà il tuo stesso IP. Perderai l'accesso SSH.
Aggiungi il tuo IP alle impostazioni predefinite:
sudo tee /etc/fail2ban/jail.d/01-whitelist.conf > /dev/null << 'EOF'
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 YOUR_IP_HERE
EOF
Sostituisci YOUR_IP_HERE con il tuo indirizzo IP pubblico reale. Puoi trovarlo eseguendo curl -4 ifconfig.me dalla tua macchina locale. Aggiungi più IP separati da spazi.
Riavvia e verifica che la whitelist sia caricata:
sudo systemctl restart fail2ban
sudo fail2ban-client get sshd ignoreip
L'output elenca tutti gli IP e gli intervalli in whitelist. Conferma che il tuo IP compaia nella lista.
Attenzione: Se ti connetti da un IP dinamico, aggiungerlo alla whitelist offre protezione limitata. Mantieni un metodo di accesso secondario (accesso console dal pannello del tuo provider di hosting) come backup in caso di ban.
Come proteggo Nginx con jail Fail2Ban personalizzate?
Fail2Ban include diversi filtri per Nginx. I più utili sono nginx-http-auth per il brute-force sull'autenticazione HTTP Basic e nginx-botsearch per gli scanner che cercano percorsi inesistenti. Puoi anche scrivere filtri personalizzati per pattern specifici della tua applicazione.
Jail nginx-http-auth
Questa jail blocca gli IP che falliscono ripetutamente l'autenticazione HTTP Basic. Legge dal log degli errori di Nginx.
sudo tee /etc/fail2ban/jail.d/nginx-http-auth.conf > /dev/null << 'EOF'
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
findtime = 600
bantime = 3600
EOF
Jail nginx-botsearch
Questa jail cattura i bot che scansionano percorsi vulnerabili (/wp-admin, /phpmyadmin, /.env). Legge il log di accesso di Nginx per le risposte 404.
sudo tee /etc/fail2ban/jail.d/nginx-botsearch.conf > /dev/null << 'EOF'
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 7200
EOF
Filtro personalizzato: bloccare errori 4xx eccessivi
Per le applicazioni dietro Nginx, potresti voler bloccare gli IP che generano troppi errori 4xx. Questo cattura credential stuffing, abuso di API e enumerazione dei percorsi. I filtri integrati non coprono questo caso, quindi crea un filtro personalizzato.
Crea il file del filtro:
sudo tee /etc/fail2ban/filter.d/nginx-4xx.conf > /dev/null << 'EOF'
[Definition]
failregex = ^<HOST> - \S+ \[.*\] "[A-Z]+ .+" (400|401|403|404|405) \d+
ignoreregex = ^<HOST> - \S+ \[.*\] "[A-Z]+ /favicon\.ico
^<HOST> - \S+ \[.*\] "[A-Z]+ /robots\.txt
EOF
La failregex corrisponde alle righe del log di accesso di Nginx dove la risposta è un codice di stato 4xx. La ignoreregex esclude i falsi positivi comuni come le richieste a favicon.ico e robots.txt.
Crea la jail:
sudo tee /etc/fail2ban/jail.d/nginx-4xx.conf > /dev/null << 'EOF'
[nginx-4xx]
enabled = true
port = http,https
filter = nginx-4xx
logpath = /var/log/nginx/access.log
maxretry = 20
findtime = 600
bantime = 3600
EOF
Il maxretry più alto di 20 evita di bloccare utenti legittimi che incontrano qualche 404 durante la navigazione normale.
Riavvia Fail2Ban e verifica che tutte le jail siano caricate:
sudo systemctl restart fail2ban
sudo fail2ban-client status
Output atteso che mostra tutte le jail attive:
Status
|- Number of jail: 4
`- Jail list: nginx-4xx, nginx-botsearch, nginx-http-auth, sshd
Per approfondire la protezione di Nginx a livello applicativo, consulta la guida sul rate limiting di Nginx.
Come testo i filtri Fail2Ban con fail2ban-regex?
Prima di attivare una jail, testa il suo filtro contro log reali. Lo strumento fail2ban-regex esegue un filtro su un file di log e riporta le corrispondenze. Questo evita di distribuire un filtro che non corrisponde a nulla (inutile) o che corrisponde a tutto (blocca utenti legittimi).
Testa il filtro personalizzato nginx-4xx:
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-4xx.conf
Esempio di output:
Running tests
=============
Use failregex filter file : nginx-4xx, basedir: /etc/fail2ban
Use log file : /var/log/nginx/access.log
Use encoding : utf-8
Results
=======
Failregex: 42 total
|- #) [# of hits] regular expression
| 1) [42] ^<HOST> - \S+ \[.*\] "[A-Z]+ .+" (400|401|403|404|405) \d+
`-
Ignoreregex: 3 total
Date template hits:
...
Lines: 1842 lines, 0 ignored, 42 matched, 1800 missed
l'output mostra 42 righe corrispondenti su 1842. È un rapporto ragionevole. Se il filtro corrispondesse al 90% delle righe, la regex è troppo ampia. Se corrispondesse a 0 righe, o la regex è errata o il log non contiene ancora errori 4xx.
Per vedere quali righe hanno corrisposto:
sudo fail2ban-regex --print-all-matched /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-4xx.conf
Per vedere quali righe non hanno corrisposto (utile per la messa a punto):
sudo fail2ban-regex --print-all-missed /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-4xx.conf
Testa il filtro sshd integrato contro il journal di systemd:
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf
Come configuro la jail recidive per i recidivi?
La jail recidive monitora il log stesso di Fail2Ban. Quando un IP viene bloccato più volte in qualsiasi jail, la jail recidive applica un ban più lungo. È un'escalation: prima infrazione = 1 ora, recidivi = 1 settimana.
Su un server di produzione con molto traffico, è la jail recidive che tiene davvero lontani gli attaccanti persistenti.
sudo tee /etc/fail2ban/jail.d/recidive.conf > /dev/null << 'EOF'
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
maxretry = 3
findtime = 86400
bantime = 604800
EOF
| Parametro | Valore | Significato |
|---|---|---|
logpath |
/var/log/fail2ban.log |
Percorso di log di fallback. Con backend = systemd, Fail2Ban legge le proprie voci di journal (il filtro recidive ha una direttiva journalmatch integrata) |
maxretry |
3 |
Si attiva dopo 3 ban da altre jail |
findtime |
86400 |
Guarda indietro di 24 ore (86400 secondi) |
bantime |
604800 |
Blocca per 1 settimana (604800 secondi) |
banaction |
%(banaction_allports)s |
Blocca tutte le porte, non solo quella che ha causato il ban |
Il filtro recidive è incluso in Fail2Ban in /etc/fail2ban/filter.d/recidive.conf. Non è necessario crearlo.
Riavvia e verifica:
sudo systemctl restart fail2ban
sudo fail2ban-client status recidive
Come monitoro i ban e sblocco un indirizzo IP?
Fail2Ban fornisce fail2ban-client per tutte le attività di monitoraggio e gestione. Questi comandi funzionano indipendentemente dal backend di azione di ban in uso.
Controllare lo stato generale
sudo fail2ban-client status
Elenca tutte le jail attive e i relativi contatori di ban.
Controllare una jail specifica
sudo fail2ban-client status sshd
Mostra gli IP attualmente bloccati, il totale dei ban e i fallimenti attuali.
Bloccare manualmente un IP
sudo fail2ban-client set sshd banip 203.0.113.50
Sbloccare un IP
sudo fail2ban-client set sshd unbanip 203.0.113.50
Se l'IP è stato bloccato dalla jail recidive, sbloccalo anche lì:
sudo fail2ban-client set recidive unbanip 203.0.113.50
Verificare quale azione di ban usa una jail
sudo fail2ban-client get sshd actions
Ricaricare la configurazione senza riavviare
sudo fail2ban-client reload
Leggere il log di Fail2Ban
journalctl -u fail2ban -f
Segue il log del servizio Fail2Ban in tempo reale. Vedrai gli eventi di ban e sblocco man mano che si verificano.
Il log applicativo di Fail2Ban con i dettagli dei ban:
sudo tail -f /var/log/fail2ban.log
Riferimento comandi fail2ban-client
| Comando | Scopo |
|---|---|
fail2ban-client status |
Elencare tutte le jail |
fail2ban-client status <jail> |
Mostrare dettagli della jail e IP bloccati |
fail2ban-client set <jail> banip <IP> |
Bloccare manualmente un IP |
fail2ban-client set <jail> unbanip <IP> |
Sbloccare un IP |
fail2ban-client reload |
Ricaricare tutta la configurazione |
fail2ban-client reload <jail> |
Ricaricare una singola jail |
fail2ban-client get <jail> bantime |
Mostrare la durata del ban |
fail2ban-client get <jail> findtime |
Mostrare la finestra di conteggio dei fallimenti |
fail2ban-client get <jail> maxretry |
Mostrare la soglia di tentativi |
fail2ban-client get <jail> ignoreip |
Mostrare gli IP in whitelist |
fail2ban-client get <jail> actions |
Mostrare l'azione di ban in uso |
Verifica end-to-end: provocare un ban e confermarne il funzionamento
Non dare per scontato che la tua configurazione funzioni. Testala. Provoca un ban reale e verifica l'intera catena: rilevamento nei log, azione di ban, regola firewall e sblocco.
Passaggio 1: Da un'altra macchina (non il tuo IP in whitelist), prova accessi SSH con password errata. Dopo 3 fallimenti (corrispondenti a maxretry), la connessione dovrebbe essere rifiutata.
Se non hai una seconda macchina, usa fail2ban-client per simulare un ban:
sudo fail2ban-client set sshd banip 198.51.100.25
Passaggio 2: Verifica che il ban sia registrato:
sudo fail2ban-client status sshd
L'IP bloccato dovrebbe apparire in Banned IP list.
Passaggio 3: Verifica che la regola firewall esista.
Per UFW:
sudo ufw status numbered | grep 198.51.100.25
Per nftables:
sudo nft list table inet f2b-table
L'IP dovrebbe apparire in un set all'interno della tabella.
Passaggio 4: Sblocca e verifica la rimozione:
sudo fail2ban-client set sshd unbanip 198.51.100.25
sudo fail2ban-client status sshd
L'IP non dovrebbe più apparire nella lista dei ban. Controlla nuovamente il firewall per confermare che la regola sia stata rimossa.
Riferimento parametri di configurazione Fail2Ban
| Parametro | Predefinito | Consigliato | Descrizione |
|---|---|---|---|
bantime |
10m |
1h o 3600 |
Durata del ban |
findtime |
10m |
10m o 600 |
Finestra per il conteggio dei fallimenti |
maxretry |
5 |
3 per SSH, 5-20 per web |
Fallimenti prima del ban |
ignoreip |
127.0.0.1/8 ::1 |
Aggiungi il tuo IP | IP mai bloccati |
banaction |
nftables (Ubuntu 24.04), iptables-multiport (upstream) |
ufw o nftables-multiport |
Comando firewall da eseguire |
backend |
auto |
systemd |
Fonte dei log (journal systemd sulle distribuzioni moderne) |
destemail |
root@localhost |
La tua email | Destinatario degli avvisi |
action |
%(action_)s |
%(action_mwl)s per avvisi via email |
Azione eseguita al ban |
Qualcosa non funziona?
Fail2Ban non si avvia: Controlla gli errori di sintassi nei file delle jail. Una parentesi mancante o un valore non valido impediranno l'avvio.
sudo fail2ban-client -t
Testa la configurazione senza avviare il servizio. Correggi gli errori segnalati.
La jail mostra 0 corrispondenze ma gli attacchi ci sono: Il backend è probabilmente sbagliato. Su Ubuntu 24.04 e Debian 12, usa backend = systemd. Se usi backend = auto e il sistema non ha /var/log/auth.log, Fail2Ban non legge nulla.
L'IP bloccato riesce ancora a connettersi: L'azione di ban non corrisponde al tuo firewall. Se usi UFW, imposta banaction = ufw. Se usi nftables direttamente, imposta banaction = nftables-multiport. Verifica che la regola firewall esista dopo un ban.
Ti sei bloccato da solo: Accedi al server tramite la console web del tuo provider di hosting (VNC/KVM). Da lì:
sudo fail2ban-client set sshd unbanip YOUR_IP
Oppure ferma completamente Fail2Ban:
sudo systemctl stop fail2ban
Poi correggi la configurazione di ignoreip e riavvia.
Fail2Ban consuma troppa memoria: Su server con file di log grandi, Fail2Ban può consumare memoria. Imposta dbpurgeage per limitare la dimensione del database:
sudo tee /etc/fail2ban/jail.d/99-performance.conf > /dev/null << 'EOF'
[DEFAULT]
dbpurgeage = 7d
EOF
Copyright 2026 Virtua.Cloud. Tutti i diritti riservati. Questo contenuto è un'opera originale del team Virtua.Cloud. La riproduzione, ripubblicazione o redistribuzione senza autorizzazione scritta è vietata.