Fail2ban fa una cosa sola, e la fa bene: legge i log con espressioni regolari, conta le occorrenze, banna l'IP nel firewall locale. Il problema? Questo modello — concepito nel 2004, ricordiamolo — porta con sé tre limiti che oggi pesano parecchio:
- Reattività pura. L'IP viene bannato dopo che ha già provato (e magari indovinato) qualcosa. Se hai migliaia di server, ognuno è un'isola che riparte da zero davanti agli stessi attaccanti.
- Scalabilità delle regole iptables. Fail2ban inserisce una regola firewall per ogni IP bloccato. Con 10.000 ban attivi, il firewall comincia a sudare freddo. nftables con i
set gestisce milioni di IP in O(1), ma Fail2ban storicamente non ne approfitta in modo nativo.
- Pattern statici. Ogni nuova variante di attacco richiede una nuova regex. Niente comprensione semantica del traffico HTTP, niente fingerprint dei bot, niente correlazione temporale oltre al classico "N fail in M minuti".
Detto questo, su un bastion SSH casalingo Fail2ban basta e avanza. Su un sito pubblico con WordPress, API esposte o pannello admin Nginx, l'esperienza concreta mi dice un'altra cosa: servono livelli di difesa diversi. Ed è esattamente qui che entra CrowdSec.
Cos'è CrowdSec e come cambia il gioco
CrowdSec è un IPS behavior-based che separa nettamente rilevamento ed esecuzione. L'agente (LAPI, Local API) legge i log tramite parser, applica scenari di comportamento e produce decisioni contro gli IP malevoli. Queste decisioni vengono poi consumate da componenti chiamati bouncer, che le applicano dove ha senso: firewall nftables, Nginx con CAPTCHA, Cloudflare edge, Traefik middleware. È modulare per costruzione, e si vede.
L'innovazione vera, però, è la Central API: ogni agente CrowdSec contribuisce in modo anonimo la lista degli IP che ha visto attaccare e in cambio riceve una blocklist comunitaria curata. Se un IP attacca un server in Polonia alle 14:02, il tuo server a Milano riceve la notifica e blocca l'IP prima ancora che provi un singolo pacchetto contro di te. Su un sito pubblico, questo riduce il rumore di fondo del 70-80% nell'arco di una settimana — un numero che ho misurato personalmente su tre VPS diversi, quindi non è marketing.
Architettura in tre componenti
Conviene fissare subito i pezzi del puzzle, perché la documentazione ufficiale a volte li dà per scontati:
- Agent + LAPI: il processo
crowdsec che fa parsing e decisione. Espone un'API REST locale (porta 8080 di default) consultata dai bouncer.
- cscli: la CLI di amministrazione. È il tuo coltellino svizzero per gestire collezioni, alert, decisioni, bouncer e console.
- Bouncer: processi esterni all'agente che applicano i ban. Il più comune è
crowdsec-firewall-bouncer-nftables, ma ne esistono per Nginx, Traefik, Caddy, HAProxy, AWS WAF, Cloudflare e altri.
Installazione su Ubuntu 24.04 LTS
Partiamo da una macchina pulita. La pipeline ufficiale aggiunge il repository APT con la chiave GPG corretta — indispensabile per ricevere aggiornamenti automatici:
curl -s https://install.crowdsec.net | sudo sh
sudo apt update
sudo apt install -y crowdsec
sudo cscli version
L'output di cscli version dovrebbe mostrare la versione (1.6.x al momento della scrittura). Il servizio è già attivo, quindi possiamo subito controllare la salute:
sudo systemctl status crowdsec
sudo cscli metrics show
Il comando metrics è uno dei migliori segnali "vitalità": se vedi parser che processano linee e nessun errore, sei a posto. Già di default CrowdSec installa la collezione crowdsecurity/linux, che monitora auth.log e gli eventi sudo.
Installare il bouncer nftables
Senza un bouncer, CrowdSec è un sensore che osserva ma non agisce. Su Ubuntu 24.04 nftables è il default ed è la scelta naturale:
sudo apt install -y crowdsec-firewall-bouncer-nftables
sudo systemctl enable --now crowdsec-firewall-bouncer
sudo systemctl status crowdsec-firewall-bouncer
Durante l'installazione il pacchetto registra automaticamente il bouncer presso l'agente e scrive la chiave API in /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml. Verifica con:
sudo cscli bouncers list
# Name IP Address Valid Last API pull
# cs-firewall-bouncer-XXXXXX 127.0.0.1 ✔️ 2026-05-13T08:14:22Z
Apri il file di configurazione del bouncer e controlla che il firewall_type sia nftables e che IPv6 sia abilitato (perché sì, gli attaccanti IPv6 esistono e crescono):
sudo nano /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
mode: nftables
update_frequency: 10s
log_mode: file
log_dir: /var/log/
log_level: info
api_url: http://127.0.0.1:8080/
api_key: ${API_KEY}
disable_ipv6: false
deny_action: DROP
deny_log: false
supported_decisions_types:
- ban
nftables:
ipv4:
enabled: true
set-only: false
table: crowdsec
chain: crowdsec-chain
priority: -10
ipv6:
enabled: true
set-only: false
table: crowdsec6
chain: crowdsec6-chain
priority: -10
Il priority: -10 garantisce che la catena CrowdSec venga valutata prima della input di sistema. Se hai già regole nftables tue (vedi la mia guida nftables), questo è il comportamento corretto: blocca l'attaccante prima ancora che entri nelle tue regole.
⚠️ Attenzione a UFW
Se sul server è attivo UFW, gestisce le proprie chain nftables. Far convivere UFW e il bouncer nftables di CrowdSec può funzionare, ma genera diagnostica confusa (parlo per esperienza, dopo un pomeriggio sprecato a inseguire un ban che "spariva"). Le opzioni sane sono due: disabilitare UFW e gestire le regole base direttamente con nftables, oppure usare la variante crowdsec-firewall-bouncer-iptables che coesiste meglio con UFW. Personalmente, sui server gestiti, consiglio la prima — meno strati, meno sorprese.
Collezioni: il vero punto di forza
Le collections sono pacchetti curati che includono parser e scenari per servizi specifici. Sono il motivo per cui CrowdSec out-of-the-box copre molto più di Fail2ban:
sudo cscli collections install crowdsecurity/sshd
sudo cscli collections install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/base-http-scenarios
sudo cscli collections install crowdsecurity/http-cve
sudo cscli collections install crowdsecurity/wordpress # se serve
sudo cscli collections upgrade --all
sudo systemctl reload crowdsec
Per vedere cosa hai installato:
sudo cscli collections list
sudo cscli scenarios list
sudo cscli parsers list
La collezione http-cve merita un cenno particolare: contiene scenari per CVE web ad alto impatto (Log4Shell, Spring4Shell, vulnerabilità WordPress note, path traversal Apache 2.4.49/2.4.50). Ogni volta che esce una CVE diffusa, il team CrowdSec aggiorna gli scenari entro 24-48 ore — un livello di reattività che con Fail2ban, semplicemente, non esiste.
Scenari: leggere e scrivere comportamenti
Uno scenario CrowdSec è un file YAML che descrive un comportamento sospetto nel tempo. Ecco un esempio incluso in crowdsecurity/sshd:
type: leaky
name: crowdsecurity/ssh-bf
description: "Detect ssh bruteforce"
filter: "evt.Meta.log_type == 'ssh_failed-auth'"
leakspeed: "10s"
capacity: 5
groupby: "evt.Meta.source_ip"
blackhole: 1m
labels:
service: ssh
type: bruteforce
remediation: true
Tradotto in italiano: ogni IP sorgente accumula un "secchio" che si svuota di 1 evento ogni 10 secondi e ha capienza 5. Se l'IP genera eventi più velocemente di quanto il secchio si svuoti, esonda e scatta la decisione. Decisamente più espressivo della classica soglia "5 fail in 5 minuti" di Fail2ban.
Scenario personalizzato per la tua app
Supponiamo che tu abbia un'API che logga i 401 in un formato custom (capita spesso). Crea il file /etc/crowdsec/scenarios/my-api-bf.yaml:
type: leaky
name: tua-azienda/api-401-bf
description: "Bruteforce API endpoint /v1/login"
filter: 'evt.Meta.http_status == "401" && evt.Meta.http_path startsWith "/v1/login"'
leakspeed: "30s"
capacity: 10
groupby: "evt.Meta.source_ip"
blackhole: 5m
labels:
service: api
type: bruteforce
remediation: true
Ricarica e verifica:
sudo systemctl reload crowdsec
sudo cscli scenarios list | grep api-401-bf
sudo cscli hubtest run tua-azienda/api-401-bf # se hai un test
Cloudflare Bouncer: difesa al bordo
Se il tuo dominio passa da Cloudflare, l'integrazione con il Cloudflare bouncer è il vero salto di qualità: gli IP malevoli vengono bloccati all'edge di Cloudflare, prima ancora che il pacchetto raggiunga il tuo VPS. Risparmi banda, risparmi CPU e riduci la superficie d'attacco quasi a zero. Difficile chiedere di meglio.
sudo apt install -y crowdsec-cloudflare-bouncer
sudo cscli bouncers add cloudflare-bouncer
# salva la chiave restituita
sudo nano /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml
crowdsec_lapi_url: http://127.0.0.1:8080/
crowdsec_lapi_key: ${CHIAVE_RESTITUITA_SOPRA}
crowdsec_update_frequency: 10s
cloudflare_config:
accounts:
- id: ${ACCOUNT_ID}
token: ${API_TOKEN_CON_PERMESSO_WAF}
ip_list_prefix: cs
default_action: challenge
zones:
- actions: [challenge, block]
zone_id: ${ZONE_ID}
Il token Cloudflare deve avere i permessi Account: Account Filter Lists: Edit e Zone: Firewall Services: Edit sulla zona target. Genera il token dal pannello Cloudflare in My Profile → API Tokens, mai dalla Global API Key — è uno dei suggerimenti del CIS Benchmark per Cloudflare 2026, e non è un consiglio da prendere alla leggera.
Avvia il bouncer e osserva il dashboard di Cloudflare nella sezione Security → WAF → Tools: nel giro di pochi minuti vedrai apparire una IP List chiamata cs_* che si popola con gli IP malevoli condivisi dalla community. La prima volta è una piccola soddisfazione.
CrowdSec vs Fail2ban: confronto onesto
| Caratteristica | Fail2ban | CrowdSec |
| Architettura | Parser log + regole firewall | Agent + LAPI + Bouncer separati |
| Linguaggio rilevamento | Regex Python | YAML + filtri expr |
| Threat intel condivisa | Nessuna | Blocklist comunitaria |
| Multi-server | Manuale (rsync, fwknop) | Nativo (LAPI condivisa) |
| Scalabilità ban | Una regola per IP | nftables set, milioni di IP |
| Integrazione Cloudflare | Custom action manuale | Bouncer ufficiale |
| Ban di default | 10 minuti | 4 ore |
| Memoria RSS tipica | 30-60 MB | 80-150 MB |
| Curva di apprendimento | Semplice | Media |
| Reattività a nuove CVE | Update manuali | Hub aggiornato dal team |
Quando tenere Fail2ban
Non c'è alcun bisogno di migrare per il gusto della novità. Fail2ban resta una scelta sensata se:
- Hai un singolo server casalingo o un bastion SSH con traffico moderato.
- Vuoi memoria minima (sistemi embedded, VPS da 512 MB).
- Hai già automazioni Ansible/Puppet che funzionano e non c'è ROI nel riscrivere tutto.
Quando passare a CrowdSec
- Gestisci più di un server e vuoi che imparino gli uni dagli altri.
- Esponi servizi web (WordPress, API, pannelli admin) costantemente sotto attacco.
- Usi Cloudflare o un CDN e vuoi spostare i ban all'edge.
- Ti serve correlazione comportamentale, non solo conteggio fail.
L'opzione ibrida: entrambi
Niente vieta di tenere Fail2ban per SSH (è collaudato, leggero, funziona) e CrowdSec per il resto (Nginx, Apache, WordPress, API). L'importante è non far gestire allo stesso strumento gli stessi log, altrimenti rischi doppi ban e regole firewall ridondanti — un classico, mi ci sono trovato anch'io. Nella pratica funziona bene se assegni a Fail2ban solo auth.log e a CrowdSec tutti i log applicativi.
Monitoraggio e operatività quotidiana
Comandi cscli che mi ritrovo a digitare quasi ogni giorno:
sudo cscli metrics # statistiche live di parser e bucket
sudo cscli alerts list # alert raggruppati per scenario
sudo cscli alerts inspect 42 # dettaglio di un alert specifico
sudo cscli decisions list # ban attualmente attivi
sudo cscli decisions delete -i 1.2.3.4 # unban manuale
sudo cscli decisions add -i 5.6.7.8 -d 24h -r "manual ban"
sudo cscli bouncers list # bouncer registrati
sudo cscli hub list # collezioni installate vs disponibili
Per ispezione del firewall live:
sudo nft list set inet crowdsec crowdsec-blacklists | head -20
sudo nft list set inet crowdsec6 crowdsec6-blacklists | head -20
Console web (opzionale ma utile)
La CrowdSec Console è una dashboard cloud gratuita per il tier hobby. Iscrizione, enroll key e via:
sudo cscli console enroll ${ENROLL_KEY}
sudo cscli console enable -a
sudo systemctl reload crowdsec
È particolarmente comoda se gestisci 3-4 server: vedi alert, mappe geografiche degli attaccanti e top scenari in un unico posto. Devo ammettere che la mappa, dopo le prime 24 ore, è anche un po' ipnotica.
Errori comuni e troubleshooting
Il bouncer non blocca nulla
Nove volte su dieci la causa è una di queste:
- Il bouncer non è registrato (
cscli bouncers list non lo mostra).
- La priority della chain nftables è più alta di un'altra chain
accept a monte. Verifica con nft list ruleset.
- UFW gestisce regole che precedono quelle del bouncer.
Falsi positivi sul tuo IP
Aggiungi il tuo IP (o subnet uffici) a una whitelist persistente — capita anche ai migliori di bannarsi da soli dopo qualche errore di password:
sudo nano /etc/crowdsec/parsers/s02-enrich/whitelists.yaml
name: crowdsecurity/whitelists
description: "Whitelist IP fidati"
whitelist:
reason: "trusted networks"
ip:
- "127.0.0.1"
cidr:
- "10.0.0.0/24"
- "192.168.1.0/24"
- "203.0.113.42/32"
Ricarica con sudo systemctl reload crowdsec.
Memoria che cresce nel tempo
Su agenti con molte collezioni e log voluminosi, il processo può arrivare a 300+ MB. Le opzioni sono limitare le collezioni a quelle effettivamente utili (cscli collections remove ...) o, su sistemi piccoli, considerare crowdsec-lite via Docker dedicato.
FAQ
CrowdSec invia i miei log a un server centrale?
No. Le decisioni (l'IP banalizzato + lo scenario che è scattato) vengono inviate in modo anonimo alla Central API. I log non lasciano mai il tuo server. Puoi disabilitare anche questa condivisione con cscli capi disable, ma perdi la blocklist comunitaria — francamente, non lo consiglio.
Posso usare CrowdSec senza Internet?
Sì, in modalità "local only". Disabiliti la Central API e fai solo rilevamento locale + bouncer. Perdi la threat intelligence condivisa, ma mantieni scenari e correlazione comportamentale — che è già più di quanto offre Fail2ban.
CrowdSec funziona con Docker e Kubernetes?
Sì, esiste un'immagine ufficiale crowdsecurity/crowdsec e bouncer specifici per Traefik, Nginx Ingress Controller e Kubernetes (l'CrowdSec Operator). Per workload containerizzati il pattern consigliato è un agente per host che monta i log del container engine in read-only.
Quanto tempo serve perché la blocklist comunitaria sia efficace?
Già nelle prime ore blocca migliaia di IP noti. La curva di apprendimento globale è continua: dopo 7 giorni, il numero di tentativi che raggiungono i servizi applicativi cala in media del 70-85% sui server pubblici. Il dato cambia col tipo di servizio e con la geografia, ma l'ordine di grandezza è sempre quello.
CrowdSec ha un piano enterprise?
Sì, il tier Enterprise include blocklist premium (TOR, VPN datacenter, scanner specializzati), SLA e SSO. Per la maggior parte degli use case self-hosted il tier gratuito (Free e Hobby) copre tutto ciò che serve, comprese 3 macchine nella Console.
Conclusioni
CrowdSec non è "Fail2ban in YAML". È un cambio di paradigma: dal singolo server isolato a una rete collaborativa, dalla regex statica al comportamento, dal ban locale alla difesa multi-layer fino al CDN. Per chi gestisce infrastruttura pubblicamente esposta nel 2026, l'investimento di un pomeriggio di setup ripaga in settimane di rumore eliminato e attacchi fermati all'edge.
Fail2ban resta un classico onorevole — non c'è niente di sbagliato a usarlo, se basta. Ma se ti accorgi di passare le serate a scrivere filtri custom per nuovi pattern di attacco, è il segnale che è ora di provare CrowdSec. La community fa già metà del lavoro al posto tuo, e si sente parecchio.