Reactive Web Firewall: dal 403 al ban nftables in tempo reale

Implementazione pratica di un Reactive Web Firewall: modulo Apache, regole applicative, helper Unix socket, fast-ban nftables, whitelist, test end-to-end e troubleshooting.

Un firewall di rete vede indirizzi, porte e protocolli. Apache vede invece URI, metodo HTTP, header e comportamento applicativo. RwF nasce per unire i due livelli: una richiesta ostile viene bloccata con 403 e, quando la policy lo prevede, l’indirizzo sorgente viene inserito immediatamente in un set nftables temporaneo.

Architettura

L’implementazione usata qui è composta da quattro pezzi separati: mod_rwf dentro Apache, un helper asincrono raggiunto tramite Unix socket, un meccanismo di fast-ban locale basato su nftables e, opzionalmente, la propagazione del ban verso il firewall di frontiera.

Apache + mod_rwf
        |
        | match regola
        v
403 + evento al helper
        |
        v
/run/reactive-web-firewall/helper.sock
        |
        v
fastban_v4 / fastban_v6 (nftables)
        |
        +--> eventuale propagazione al firewall di frontiera

Prerequisiti e compilazione del modulo Apache

Il modulo va compilato contro la stessa ABI di Apache in uso. Su Debian/Ubuntu il pacchetto utile è apache2-dev, che fornisce apxs.

apt update
apt install apache2-dev build-essential

apxs -c mod_rwf.c
apxs -i mod_rwf.la

apache2ctl configtest
systemctl reload apache2

Dopo l’installazione controlliamo che il modulo sia realmente caricato:

apache2ctl -M | grep rwf

Configurazione Apache

Le regole vengono mantenute fuori dai VirtualHost, in un file dedicato, per esempio /etc/reactive-web-firewall/apache-rules.conf. Il socket dell’helper è /run/reactive-web-firewall/helper.sock.

RwfEnabled On

RwfWhitelistIP 127.0.0.1
RwfWhitelistIP 10.0.20.0/24

RwfRuleExact  "/__rwf-test__"               "test"
RwfRulePrefix "/.git/"                      "git-probe"
RwfRulePrefix "/wp-config.php"              "wp-config-probe"
RwfRuleRegex  "(?i)/(\.env|\.svn|id_rsa)" "secret-probe"

Include /etc/reactive-web-firewall/apache-rules.conf

Dopo ogni modifica:

apache2ctl configtest && systemctl reload apache2

Fast-ban con nftables

Nel nostro schema i set si chiamano fastban_v4 e fastban_v6 dentro la tabella inet custom_web_fastban. I timeout fanno sì che il blocco si auto-estingua senza dover mantenere una lista infinita di IP.

nft list table inet custom_web_fastban
nft list set inet custom_web_fastban fastban_v4
nft list set inet custom_web_fastban fastban_v6

La parte legacy del fast-ban è gestita da /usr/local/sbin/custom-web-fastban e dalla configurazione nftables in /etc/nftables.d/custom-web-fastban.nft. Il servizio che carica le regole deve risultare attivo:

systemctl status custom-web-fastban.service
nft list ruleset | sed -n '/custom_web_fastban/,+80p'

Test end-to-end

Creiamo volutamente una regola innocua sul path di test e richiamiamola da una macchina non in whitelist.

curl -i https://www.example.net/__rwf-test__

La risposta attesa è 403. Subito dopo controlliamo il ban:

nft list set inet custom_web_fastban fastban_v4

# Nel nostro ambiente è disponibile anche:
check-fw-ban 203.0.113.25

Il controllo deve dirci non soltanto “presente/non presente”, ma anche dove: allowlist banIP, set temporaneo locale, firewall di frontiera e timeout residuo.

Reverse proxy e CDN: non bannare Cloudflare

Se Apache riceve la connessione da un reverse proxy o da una CDN, l’IP TCP visto dal backend non è necessariamente quello dell’attaccante. Il sistema deve fidarsi dell’header che contiene il client reale solo quando la connessione arriva da proxy esplicitamente autorizzati. In caso contrario un client potrebbe forgiare l’header e far bannare un indirizzo arbitrario.

Debug

# Apache
LogLevel alert rwf:debug

journalctl -u apache2 -f
journalctl -u custom-web-fastban.service -f

ss -xl | grep reactive-web-firewall
ls -l /run/reactive-web-firewall/helper.sock

Per misurare il costo del modulo possono essere registrati anche i timestamp apache_start_us, rwf_enter_us, rwf_exit_us e apache_end_us. È utile per dimostrare che la decisione applicativa non sta aggiungendo latenze rilevanti.

Cosa deve restare fuori da RwF

RwF non sostituisce patching, autenticazione, rate limiting, segmentazione e logging. È una reazione rapida a un segnale ad alta confidenza. Le regole devono essere poche, spiegabili e verificabili.