Firewall a controllo di pacchetti
Un firewall a controllo di pacchetti è un filtro tra una rete e un'altra: per ogni pacchetto che passa decide se lasciarlo transitare (accept) o buttarlo (drop). Vediamo come funziona, le regole e come metterci mano.
Il pacchetto
Ogni scambio di informazioni tra due reti è formato da almeno un pacchetto che porta con sé alcune informazioni che il firewall guarda:
- IP sorgente da dove arriva.
- IP e porta di destinazione dove è diretto (la porta identifica il servizio: 22 per SSH, 443 per HTTPS, 53 per DNS…).
- Protocollo tipicamente TCP o UDP.
Il firewall confronta questi dati con una lista di regole e prende una decisione.
First match wins
Un firewall valuta le regole in ordine, dall'alto verso il basso, e si ferma alla prima che combacia. Quella regola decide il destino del pacchetto.
Questa singola proprietà è la causa della maggior parte degli errori di configurazione. Considera queste due regole:
allow tcp 192.168.1.0/24 :22
deny tcp any :22Un pacchetto SSH dalla rete interna combacia con la prima regola → accept. Ma se inverti l'ordine:
deny tcp any :22
allow tcp 192.168.1.0/24 :22ora lo stesso pacchetto combacia prima con il deny any → drop, e la regola di allow sotto non verrà mai raggiunta. Stesse regole, ordine diverso, risultato opposto.
Osservazione
Le regole specifiche vanno sopra quelle generiche. Se una regola generica (any) sta in cima, oscura tutte le regole più precise che le stanno sotto.
Default policy
E se un pacchetto non combacia con nessuna regola? Si usa la default policy, la decisione finale in fondo alla lista. Qui esistono due filosofie:
- Default deny (whitelist) — si blocca tutto, tranne ciò che è esplicitamente permesso, aprendo solo lo stretto necessario.
- Default allow (blacklist) — si permette tutto, tranne ciò che è esplicitamente bloccato, ogni servizio nuovo è esposto finché non viene chiuso.
Nella sicurezza vale il principio del privilegio minimo: parti da default deny e aggiungi solo le eccezioni che ti servono.
CIDR
Nel campo sorgente non si mette solo un IP singolo: si usa la notazione CIDR per indicare intere sottoreti. La notazione CIDR raggruppa IP e subnet mask: 192.168.1.0/24 significa "tutti gli indirizzi da 192.168.1.0 a 192.168.1.255". Un /32 è un host singolo, 0.0.0.0/0 (o any) è qualunque IP. Trovi tutti i dettagli nella guida su IP, subnet e classi.
Stateless e stateful
Il modello che abbiamo descritto è stateless: ogni pacchetto viene valutato in modo indipendente, senza tenere traccia dei pacchetti o delle connessioni precedenti.
I firewall utilizzati nella maggior parte delle reti moderne sono invece stateful: mantengono informazioni sullo stato delle connessioni attive. In questo modo, quando una connessione viene autorizzata, i pacchetti di risposta appartenenti a quella stessa connessione vengono consentiti automaticamente, senza richiedere una regola specifica. La logica di valutazione delle regole ("first match" seguito dalla "default policy") rimane comunque la stessa.
Configurare un firewall
Ho preparato un simulatore firewall interattivo: scrivi le regole, lancia un pacchetto e guarda quale regola decide e perché. Prova a riordinare le regole o a cambiare la default policy e osserva come il verdetto cambia.
Configurare su un server
Sui sistemi Linux la stessa logica si esprime con firewall software come ufw o nftables. Un esempio minimale con ufw in default deny:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
sudo ufw allow 443/tcp
sudo ufw enableBlocchiamo tutto l'ingresso, permettiamo SSH solo dalla rete interna e HTTPS da chiunque. Tutto il resto cade nella default policy → drop. Questa configurazione si abbina bene all'hardening di SSH: il firewall riduce la superficie esposta, l'hardening protegge ciò che resta aperto.
Riepilogo
- Un firewall valuta le regole dall'alto, e vince la prima che combacia.
- Le regole specifiche vanno sopra quelle generiche, altrimenti restano inutilizzate.
- Parti sempre da default deny e apri solo lo stretto necessario.
- Il CIDR ti fa esprimere intere sottoreti in una riga.
- I firewall reali sono stateful, ma la logica di lettura delle regole è la stessa.