Marvin Pascale

08 Ottobre 2026

CrowdSec 1.8+

Indice navigabile

Uno scudo ferma i bot davanti a una rete di server, in pixel art rossa su sfondo nero

Installare un componente di sicurezza e vedere il servizio segnato in verde è rassicurante. Capire quali richieste riesce davvero a fermare richiede qualche passaggio in più.

Con CrowdSec la distinzione conta parecchio: analizzare i log, bloccare un indirizzo IP e ispezionare una richiesta HTTP sono lavori diversi. La serie 1.8 aggiunge un tassello interessante, la verifica dei client web attraverso una challenge, ma rende ancora più utile sapere dove interviene ogni componente.

Vediamo cosa cambia e poi mettiamo le mani su due situazioni comuni: una VM Linux con SSH esposto e un’applicazione dietro NGINX.

Cosa cambia

La 1.8.0, rilasciata il 31 agosto 2026, introduce la bot detection nel WAF: il browser può ricevere una challenge che combina una prova di lavoro con l’analisi delle caratteristiche del client. Se supera la verifica, il browser riceve un cookie per proseguire. Il risultato aiuta a riconoscere l’automazione indesiderata, senza certificare le intenzioni di chi usa il browser.

Ci sono anche un datasource dedicato ai log dei pod Kubernetes, recuperati attraverso l’API del cluster, nuovi helper HTTP utilizzabili nelle espressioni e miglioramenti all’endpoint della Local API che distribuisce le decisioni. Due correzioni riguardano possibili denial of service nei datasource HTTP e Kubernetes audit.

Il 3 settembre è arrivata la 1.8.1, che corregge un falso positivo della bot detection con Brave e Shields attivi. È la versione stabile di riferimento per gli esempi, verificata al 7 ottobre 2026. Quel piccolo numero finale merita attenzione: una protezione che scambia i visitatori per aggressori crea un problema concreto.

AppSec e il firewall bouncer esistevano già. La novità della 1.8 non consiste nel trasformare improvvisamente ogni installazione in un WAF.

Chi rileva e chi blocca

Il Security Engine legge gli eventi e applica parser e scenari. La Local API, o LAPI, raccoglie alert e decisioni. I componenti di remediation, che continuiamo a chiamare bouncer, applicano i blocchi.

Un firewall bouncer aggiorna il firewall del sistema. AppSec, invece, riceve le richieste dal componente integrato nel reverse proxy, le analizza e restituisce un verdetto. Il proxy può così fermare una richiesta prima che raggiunga l’applicazione.

Tenere insieme questi due livelli è utile. Confonderli porta a cercare una SQL injection dentro una regola che conosce soltanto indirizzi IP.

Mani in pasta

I due esempi partono da una VM Debian con systemd, repository CrowdSec già configurato e Security Engine 1.8.1 installato e funzionante. Nel secondo caso aggiungiamo un NGINX che serve già il sito di laboratorio e termina HTTPS sulla stessa VM; il backend deve accettare connessioni soltanto dal proxy, altrimenti si può aggirare il controllo.

Sono esempi di configurazione verificati nella documentazione, non il resoconto di prove eseguite in laboratorio. Prima di applicarli, salviamo una copia delle configurazioni e assicuriamoci di poter accedere alla console del provider.

Il firewall bouncer

Prendiamo SSH: i tentativi di accesso vengono scritti nei log, CrowdSec li legge e gli scenari riconoscono i comportamenti sospetti. Quando CrowdSec produce una decisione di blocco, il bouncer la trasferisce al firewall.

Verifichiamo versione, collezioni e acquisizione:

sudo cscli version
sudo cscli collections list
sudo cscli metrics show acquisition parsers

Deve esserci la collezione per SSH e devono arrivare eventi reali. Se manca la collezione:

sudo cscli collections install crowdsecurity/sshd
sudo systemctl reload crowdsec

La sola installazione della collezione non configura una sorgente di log. Controlliamo i file in /etc/crowdsec/acquis.d/: a seconda della VM potremmo leggere auth.log oppure il journal di systemd. Evitiamo di acquisire due volte gli stessi eventi. Generiamo un accesso SSH dal nostro client di laboratorio e ricontrolliamo le metriche.

Per una VM che usa nftables installiamo il relativo bouncer:

sudo apt install crowdsec-firewall-bouncer-nftables
sudo systemctl enable --now crowdsec-firewall-bouncer
sudo cscli bouncers list

Controlliamo la configurazione in /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml: modalità nftables, indirizzo della LAPI locale e credenziale di registrazione devono essere coerenti. In modalità gestita il bouncer crea regole e set; con un firewall già complesso va prima verificata la loro interazione. La modalità che aggiorna soltanto i set richiede invece regole predisposte da noi.

Ora inseriamo una decisione breve per un indirizzo riservato agli esempi:

sudo cscli decisions add --ip 198.51.100.23 --duration 2m --reason collaudo-manuale
sudo cscli decisions list
sudo nft list ruleset

Attendiamo il ciclo di aggiornamento del bouncer e cerchiamo l’indirizzo nel set. Dall’elenco annotiamo l’ID della decisione appena aggiunta e usiamolo al posto di ID_DECISIONE per rimuovere soltanto quella:

sudo cscli decisions delete --id ID_DECISIONE

Questo verifica il passaggio dalla LAPI al firewall. Non dimostra ancora il blocco di una connessione reale, né il riconoscimento di un attacco nei log. Per provare il blocco serve un secondo client con un IP noto, diverso da quello usato per amministrare la VM, anche dopo un eventuale NAT. Ripetiamo la procedura sostituendo l’indirizzo di esempio con l’IP reale del client e tentiamo una nuova connessione durante il ban; al termine rimuoviamo la decisione usando il suo ID. Se un’allowlist esclude il client, scegliamo un’altra sorgente controllata per la prova.

L’esempio riguarda servizi che terminano sulla VM. Porte pubblicate da Docker, traffico inoltrato e servizi dietro un CDN richiedono di controllare il percorso dei pacchetti: il firewall può vedere il proxy anziché il visitatore. Gli header che dichiarano l’IP reale vanno accettati soltanto da intermediari fidati. Correggere l’indirizzo nei log non cambia quello visto dal firewall: bloccare il CDN può fermare anche il traffico legittimo.

AppSec con NGINX

Qui vogliamo fermare una richiesta sospetta anche quando arriva da un IP senza una precedente decisione di ban. NGINX vede la richiesta HTTP dopo aver terminato TLS e la passa ad AppSec prima del backend. Le regole in-band possono rifiutare subito la richiesta; l’analisi out-of-band può invece alimentare il rilevamento di comportamenti ripetuti. Il rifiuto di una richiesta non equivale automaticamente a un ban IP duraturo.

Sul sistema di laboratorio installiamo dipendenze e bouncer NGINX:

sudo apt install nginx lua5.1 libnginx-mod-http-lua luarocks gettext-base lua-cjson
sudo apt install crowdsec-nginx-bouncer

Verifichiamo la registrazione alla LAPI:

sudo cscli bouncers list

Il bouncer deve avere la propria chiave valida; non riutilizziamo quella del firewall come scorciatoia.

Installiamo le collezioni per virtual patching e regole generiche:

sudo cscli collections install crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules

Creiamo /etc/crowdsec/acquis.d/appsec.yaml con questa configurazione:

source: appsec
listen_addr: 127.0.0.1:7422
appsec_configs:
  - crowdsecurity/appsec-default
labels:
  type: appsec

Se il file esiste già, integriamo la configurazione evitando un secondo listener sulla stessa porta. Validiamo:

sudo crowdsec -t

Se il controllo riesce, riavviamo il motore:

sudo systemctl restart crowdsec

Per gli override usiamo /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf.local:

APPSEC_URL=http://127.0.0.1:7422

Questo indirizzo locale va bene perché NGINX e CrowdSec sono sulla stessa VM, senza container separati. La porta AppSec deve restare accessibile soltanto al reverse proxy; anche la LAPI deve essere protetta dall’accesso pubblico.

Controlliamo anche APPSEC_FAILURE_ACTION: con passthrough, una risposta 500 di AppSec lascia passare la richiesta; con deny viene negata. La scelta va fatta conoscendo le esigenze dell’applicazione e verificando il comportamento del bouncer anche sui timeout.

C’è inoltre un limite da verificare sulle richieste con un corpo: nel bouncer NGINX, quelle HTTP/2 o HTTP/3 senza Content-Length possono essere valutate dal WAF senza il contenuto del corpo. Questa impostazione nello stesso file fa rifiutare direttamente a NGINX le richieste il cui corpo non può essere letto:

APPSEC_DROP_UNREADABLE_BODY=true

Prima di abilitarla, proviamo anche upload e client legittimi dell’applicazione.

sudo nginx -t

Solo dopo un esito positivo:

sudo systemctl restart nginx

Per il controllo usiamo il nostro sito di laboratorio: una pagina normale deve continuare a funzionare. Poi richiediamo il percorso /.env, senza creare o esporre un file contenente segreti, e osserviamo:

sudo cscli metrics show appsec

Ci aspettiamo un rifiuto della richiesta e un incremento del contatore della regola crowdsecurity/vpatch-env-access. Un 403 da solo non basta: potrebbe averlo restituito NGINX o l’applicazione. Dobbiamo collegare la risposta alla regola scattata e controllare che la richiesta bloccata non arrivi al backend.

La bot detection

È un passaggio successivo al WAF funzionante. La funzionalità è ancora Alpha, richiede un bouncer compatibile e client capaci di eseguire JavaScript e accettare cookie. Un client API o un servizio che controlla la disponibilità del sito può essere perfettamente legittimo senza comportarsi come un browser.

La collezione prevista è crowdsecurity/appsec-bot-challenge; va anche caricata la relativa configurazione nell’acquisizione AppSec. Installarla e dimenticare il secondo passaggio non basta. Aggiorniamo la sola lista appsec_configs della sorgente, conservando la configurazione di base e aggiungendo il pattern tra apici:

appsec_configs:
  - crowdsecurity/appsec-default
  - 'crowdsecurity/appsec-bot-*'

Evitiamo di sovrapporre i bundle standard, strict e permissive: finiremmo per applicare la soglia più restrittiva.

Prima di estenderla al sito intero proverei un percorso limitato, controllando login, browser con protezioni privacy, esclusioni dei client automatici autorizzati e compatibilità della Content Security Policy. La configurazione standard non si limita da sola alla pagina di login. Un’esclusione dalla challenge non dovrebbe diventare un’esclusione indiscriminata dal WAF.

Va verificato anche l’host: il runtime della challenge richiede arm64 oppure amd64 con SSE4.1 e la possibilità di mappare memoria eseguibile. Su sistemi con restrizioni particolari questo può impedire l’avvio di AppSec.

Prepariamo anche il ritorno alla configurazione precedente. Se la challenge crea falsi positivi, rimuoviamo dalla sorgente le configurazioni bot aggiunte, conserviamo quella AppSec di base, validiamo e ricarichiamo CrowdSec. Poi ripetiamo le prove: spegnere ogni controllo non è il primo passo per isolare un problema.

Verificare i risultati

Per valutare questo aggiornamento partirei da tre domande: quali log vengono letti, quali decisioni vengono prodotte e dove vengono applicate? Per il web aggiungiamo richieste normali, richieste bloccate e comportamento in caso di guasto.

CrowdSec può unire rilevamento, informazioni condivise e protezione delle applicazioni. Resta nostro il lavoro di configurarlo sul traffico giusto e capire cosa succede quando qualcosa non funziona. Il virtual patching può darci tempo; la correzione dell’applicazione rimane da fare.

Il servizio segnato in verde è un buon inizio. La prova che blocchi ciò che deve, lasciando passare ciò che serve, vale molto di più.


Le opinioni in quanto tali sono opinabili e nulla ti vieta di approfondire l’argomento.

Risorse: