Configurare ufw in Linux: firewall del server e basi di nftables
Configurare ufw richiede tre passi: impostare le policy predefinite (sudo ufw default deny incoming e allow outgoing), consentire SSH e le porte necessarie (sudo ufw allow 22/tcp, sudo ufw allow 443/tcp) e infine attivare il firewall con sudo ufw enable. Le regole si verificano con sudo ufw status numbered; sotto il cofano ufw gestisce netfilter tramite iptables o nftables.
Il firewall di Linux decide quali pacchetti di rete lasciar passare verso il server e quali scartare. È il kernel a farlo, tramite il sottosistema netfilter, e a gestirlo sono degli strumenti: iptables e nftables a basso livello e ufw (Uncomplicated Firewall) come interfaccia semplificata. Su un server Ubuntu o Debian configurare ufw richiede cinque minuti: bloccare tutto il traffico in entrata, aprire SSH e le porte dei servizi, attivare. Qui sotto trovi la procedura passo passo, gli errori tipici e il minimo di nftables per capire cosa succede sotto il cofano.
Come funziona il firewall in Linux
Il filtraggio dei pacchetti avviene nel kernel: è netfilter. Esso mette a disposizione dei punti di aggancio (hook): traffico in entrata verso l'host, traffico in uscita e traffico in transito (forward). Le utility in user space scrivono nel kernel le regole per questi punti.
| Strumento | Livello | Quando usarlo |
|---|---|---|
ufw | interfaccia semplificata | singolo server Ubuntu/Debian, regole tipiche |
firewalld | interfaccia con zone | RHEL, Rocky, Fedora |
nftables (nft) | basso livello, moderno | regole complesse, NAT, insiemi di indirizzi |
iptables | basso livello, in disuso | sistemi e script datati |
Importante: usa un solo strumento di gestione. Se modifichi le regole contemporaneamente con ufw e a mano con iptables, si sovrascrivono a vicenda e il risultato diventa imprevedibile.
Installazione e verifica di ufw
Su Ubuntu ufw di solito è già installato ma disattivato. Su Debian va installato a parte:
$ sudo apt update
$ sudo apt install ufw
$ sudo ufw status
Status: inactive
Lo stato inactive significa che le regole di ufw non sono applicate. Non attivare ancora il firewall: prima consenti SSH, altrimenti su un server remoto ti tagli fuori da solo.
Configurazione di ufw passo passo
Passo 1. Policy predefinite
La policy predefinita stabilisce cosa fare di un pacchetto quando nessuna regola corrisponde. Per un server lo schema sicuro è: in entrata vietato, in uscita consentito.
$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow'
Le risposte alle connessioni che avvii tu passano automaticamente: ufw tiene traccia dello stato delle connessioni (connection tracking), quindi non serve aprire porte per le risposte.
Passo 2. Consentire SSH
$ sudo ufw allow OpenSSH
Rules updated
Rules updated (v6)
OpenSSH è un profilo applicativo. Se SSH ascolta su una porta non standard, consentila in modo esplicito: sudo ufw allow 2222/tcp. Per verificare su quale porta sta davvero ascoltando sshd, usa sudo ss -tlnp | grep sshd.
Passo 3. Aprire le porte dei servizi
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp
Indica sempre il protocollo: senza /tcp ufw apre la porta sia per TCP sia per UDP, e una porta aperta in più non serve a nulla.
Passo 4. Attivare il firewall
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
ufw si avvia subito e si attiverà a ogni boot. Non chiudere la sessione SSH attuale: apri un secondo terminale e verifica che la connessione funzioni.
Passo 5. Controllare le regole
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
Le regole IPv6 le crea ufw da solo, se in /etc/default/ufw è impostato IPV6=yes (valore predefinito).
Come aprire una porta in ufw: tutte le sintassi
Il comando ufw allow accetta una forma breve e una estesa. La forma breve è comoda per i casi tipici, quella estesa serve quando bisogna indicare origine, interfaccia o destinazione.
| Compito | Comando |
|---|---|
| Porta TCP | sudo ufw allow 443/tcp |
| Porta UDP | sudo ufw allow 51820/udp |
| Intervallo di porte | sudo ufw allow 6000:6007/tcp |
| Per nome del servizio | sudo ufw allow https |
| Da un solo IP | sudo ufw allow from 203.0.113.10 |
| Da una sottorete verso una porta | sudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp |
| Su una specifica interfaccia | sudo ufw allow in on eth1 to any port 3306 proto tcp |
| Vietare | sudo ufw deny 23/tcp |
| Rifiutare con risposta | sudo ufw reject 25/tcp |
Differenza tra deny e reject: deny scarta il pacchetto in silenzio e il client attende fino al timeout; reject invia una risposta che dichiara la porta chiusa. Per il traffico esterno di solito si sceglie deny, per le reti interne reject è più comodo, perché i client vedono subito l'errore.
Database accessibile solo da un server
Un caso frequente: PostgreSQL o MySQL non devono essere visibili da Internet, ma l'applicazione su un server vicino deve potersi collegare.
$ sudo ufw allow from 10.0.0.5 to any port 5432 proto tcp
Rule added
La porta 5432 resta chiusa per tutti gli altri grazie alla policy deny incoming. In aggiunta conviene configurare il database perché ascolti solo sull'indirizzo interno: firewall e impostazioni del servizio si proteggono a vicenda.
Profili applicativi
I pacchetti possono depositare la descrizione delle proprie porte in /etc/ufw/applications.d/. Elenco e contenuto dei profili:
$ sudo ufw app list
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
$ sudo ufw app info "Nginx Full"
Profile: Nginx Full
Title: Web Server (Nginx, HTTP + HTTPS)
Description: Small, but very powerful and efficient web server
Ports:
80,443/tcp
Per consentire un profilo: sudo ufw allow "Nginx Full". I nomi con spazi vanno tra virgolette. Un profilo personalizzato si descrive in formato INI nella stessa cartella e si applica con sudo ufw app update nome.
Come eliminare una regola di ufw
Il modo più sicuro è per numero:
$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] OpenSSH ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
[ 4] OpenSSH (v6) ALLOW IN Anywhere (v6)
[ 5] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 6] 443/tcp (v6) ALLOW IN Anywhere (v6)
$ sudo ufw delete 2
Deleting:
allow 80/tcp
Proceed with operation (y|n)? y
Rule deleted
Dopo ogni eliminazione i numeri scorrono, quindi prima di una nuova cancellazione esegui di nuovo status numbered. Il secondo metodo è ripetere la regola preceduta da delete: sudo ufw delete allow 80/tcp; elimina in un colpo solo sia la variante IPv4 sia quella IPv6.
Ordine delle regole e inserimento in cima
ufw controlla le regole dall'alto verso il basso e vale la prima che corrisponde. Per questo un divieto per un indirizzo specifico deve stare sopra un'autorizzazione generale:
$ sudo ufw insert 1 deny from 198.51.100.23
Rule inserted
Se aggiungi un deny con il comando normale, finisce in fondo alla lista, dopo allow 443/tcp, e per quella porta non viene applicato.
Protezione SSH dagli attacchi a forza bruta: ufw limit
La regola limit consente la connessione ma blocca l'indirizzo che ha aperto 6 o più connessioni in 30 secondi:
$ sudo ufw limit OpenSSH
Rule updated
È una difesa semplice contro il tentativo massivo di indovinare le password. Per una protezione seria aggiungi l'accesso solo con chiavi e, se vuoi, fail2ban, che sa bannare gli indirizzi tramite ufw.
Log di ufw
La registrazione si attiva con sudo ufw logging on; i livelli sono low, medium, high, full. Le voci finiscono in /var/log/ufw.log (tramite rsyslog) e nel journal del kernel:
$ sudo journalctl -k | grep 'UFW BLOCK' | tail -2
Oct 14 10:12:03 web kernel: [UFW BLOCK] IN=eth0 OUT= SRC=45.155.205.1 DST=192.0.2.10 PROTO=TCP SPT=51544 DPT=3389
Oct 14 10:12:09 web kernel: [UFW BLOCK] IN=eth0 OUT= SRC=89.248.165.7 DST=192.0.2.10 PROTO=TCP SPT=40312 DPT=23
I campi SRC e DPT mostrano chi ha bussato e a quale porta. Se un servizio non risponde e nel log compare UFW BLOCK sulla sua porta, la regola non è stata aggiunta.
ufw e Docker: perché le porte si aprono nonostante le regole
È la trappola più nota. Quando pubblica una porta (-p 8080:80), Docker aggiunge da solo le regole NAT e la catena DOCKER, e il traffico verso il container passa per forward, aggirando le regole di ingresso di ufw. Il risultato: ufw status non mostra la porta 8080, ma dall'esterno è raggiungibile.
Soluzioni possibili:
- Pubblicare le porte solo su localhost:
-p 127.0.0.1:8080:80, esponendo il servizio all'esterno tramite un reverse proxy (nginx). - Aggiungere le proprie regole nella catena
DOCKER-USER, che Docker non sovrascrive. - Non pubblicare affatto le porte dei container di servizio, collegandoli tramite la rete Docker.
Reset e disattivazione
$ sudo ufw disable # disattiva, le regole restano salvate
$ sudo ufw reset # elimina tutte le regole e disattiva
$ sudo ufw reload # rilegge la configurazione
Prima di reset ufw salva copie dei file delle regole in /etc/ufw/ con un suffisso contenente la data. Le regole vere e proprie sono in /etc/ufw/user.rules e user6.rules: non vanno modificate a mano, solo con i comandi.
Basi di nftables
nftables è il moderno sostituto di iptables nel kernel Linux. Su Debian 10+ e Ubuntu 20.10+ il comando iptables lavora di default tramite il livello di compatibilità iptables-nft, quindi anche le regole di ufw finiscono in nftables. Per vedere tutto ciò che è caricato nel kernel:
$ sudo nft list ruleset
Struttura di nftables: una tabella (famiglia ip, ip6 oppure inet per entrambe) contiene catene agganciate ai punti di netfilter, e le catene contengono le regole. Un firewall minimo per il server nel file /etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
ip protocol icmp accept
meta l4proto ipv6-icmp accept
tcp dport { 22, 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Applicare e attivare all'avvio:
$ sudo nft -c -f /etc/nftables.conf # solo verifica della sintassi
$ sudo systemctl enable --now nftables
Le regole si possono aggiungere anche al volo, ma spariscono al riavvio se non le scrivi nel file:
$ sudo nft add rule inet filter input tcp dport 5432 ip saddr 10.0.0.5 accept
$ sudo nft -a list chain inet filter input # -a mostra l'handle delle regole
$ sudo nft delete rule inet filter input handle 9
Il vantaggio principale di nftables sono gli insiemi ({ 22, 80, 443 }) e una sola tabella inet per IPv4 e IPv6. Non avviare il tuo nftables.service insieme a ufw: flush ruleset cancellerebbe le regole di ufw.
Errori tipici
- Attivato ufw senza una regola per SSH — accesso perso. Ti salva la console del provider (VNC/seriale):
sudo ufw allow OpenSSHoppuresudo ufw disable. - Porta aperta ma servizio non raggiungibile — il servizio ascolta su
127.0.0.1e non sull'indirizzo esterno. Controlla conss -tlnp. - C'è anche un firewall del cloud — molti provider hanno gruppi di sicurezza; la porta va aperta anche lì.
- deny non funziona — la regola sta sotto una regola di autorizzazione; usa
insert 1.
Conclusioni
La configurazione base di ufw consiste in default deny incoming, autorizzazione di SSH e delle porte dei servizi, ufw enable e verifica con status numbered. Per un accesso mirato usa le regole con from e port, per SSH limit, e ricorda che Docker aggira ufw. Quando servono NAT o insiemi di regole complessi, passa a nftables. La protezione del server con il firewall è trattata in pratica nel corso di Linux.
Domande frequenti
In cosa ufw si differenzia da iptables?
ufw è un'interfaccia con sintassi semplice che genera da sola le regole di iptables o nftables. iptables e nftables sono strumenti di basso livello che danno pieno controllo, ma richiedono più conoscenze.
Le regole di ufw restano dopo un riavvio?
Sì. Dopo sudo ufw enable il firewall si avvia al boot e le regole sono salvate in /etc/ufw/user.rules e user6.rules.
Bisogna aprire le porte per le connessioni in uscita?
Con la policy allow outgoing no. Le risposte alle connessioni in uscita passano automaticamente grazie al tracciamento dello stato.
Come consentire il ping con ufw attivo?
Di default ufw già lascia passare le richieste ICMP echo in ingresso: la regola è definita in /etc/ufw/before.rules. Per vietare il ping, cambia in quel file ACCEPT in DROP ed esegui sudo ufw reload.
C'è ufw su CentOS e Rocky Linux?
Lo strumento standard lì è firewalld con il comando firewall-cmd. ufw si può installare da EPEL, ma non conviene mescolarlo con firewalld.
Questo argomento è trattato in modo approfondito, con pratica, nel corso «Linux: с нуля до уверенного администрирования».
Vai al corso