Guida

Configurare ufw in Linux: firewall del server e basi di nftables

Aggiornato: · Skillaria.Top

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.

StrumentoLivelloQuando usarlo
ufwinterfaccia semplificatasingolo server Ubuntu/Debian, regole tipiche
firewalldinterfaccia con zoneRHEL, Rocky, Fedora
nftables (nft)basso livello, modernoregole complesse, NAT, insiemi di indirizzi
iptablesbasso livello, in disusosistemi 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.

CompitoComando
Porta TCPsudo ufw allow 443/tcp
Porta UDPsudo ufw allow 51820/udp
Intervallo di portesudo ufw allow 6000:6007/tcp
Per nome del serviziosudo ufw allow https
Da un solo IPsudo ufw allow from 203.0.113.10
Da una sottorete verso una portasudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp
Su una specifica interfacciasudo ufw allow in on eth1 to any port 3306 proto tcp
Vietaresudo ufw deny 23/tcp
Rifiutare con rispostasudo 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 OpenSSH oppure sudo ufw disable.
  • Porta aperta ma servizio non raggiungibile — il servizio ascolta su 127.0.0.1 e non sull'indirizzo esterno. Controlla con ss -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.

Impara l’argomento in video

Questo argomento è trattato in modo approfondito, con pratica, nel corso «Linux: с нуля до уверенного администрирования».

Vai al corso