Installare e configurare Fail2Ban su un VPS Linux

13 min di lettura·Matthieu·ubuntudebianufwnftablesnginxsshsecurityfail2ban|

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.

Pronto a provare?

Proteggi il tuo VPS Linux con Fail2Ban.

Vedi piani VPS