1 14/04/2026 10 min

Su CentOS 8 FirewallD è il punto giusto da cui partire quando devi esporre un servizio senza aprire più del necessario. La differenza pratica non è tra “firewall acceso” e “firewall spento”, ma tra un host che accetta traffico solo dove serve e un host che espone porte per abitudine. In produzione questa distinzione conta: una regola sbagliata può bloccare SSH, nascondere un backend o, al contrario, rendere visibile un servizio che doveva restare interno.

La logica corretta è semplice: prima capisci quale interfaccia sta cadendo in quale zona, poi controlli cosa è già permesso, infine applichi il cambiamento nel runtime e lo rendi permanente. Se salti uno di questi passaggi, ti ritrovi con il classico problema da sysadmin: “funziona fino al reboot”.

Che cosa fa davvero FirewallD su CentOS 8

FirewallD non è un sostituto magico delle regole di rete: è un livello di gestione che traduce zone, servizi, porte e ricche regole in configurazioni kernel-side. Su CentOS 8, dietro le quinte, il backend è nftables. Questo significa che il lavoro operativo si divide in due piani: quello dichiarativo di FirewallD e quello effettivo del traffico che passa.

Il concetto chiave è la zona. Ogni interfaccia o sorgente viene associata a una zona, e la zona decide il profilo di fiducia. Se non sai in quale zona finisce la tua NIC, il resto delle verifiche è quasi sempre tempo sprecato.

Un errore comune è aprire una porta nella zona “giusta” ma sull’interfaccia sbagliata. Il risultato è invisibile dall’esterno e sembra un problema di servizio, mentre in realtà è solo un mismatch di assegnazione zona/interfaccia.

Verifica iniziale: stato del servizio, zona attiva e porte esposte

Prima di cambiare qualsiasi cosa, conferma lo stato del demone e la configurazione attuale. Questa è la fotografia minima che ti evita di lavorare alla cieca.

1. Controlla che FirewallD sia attivo:

systemctl status firewalld

Atteso: active (running). Se è inactive o failed, prima capisci perché il servizio non parte; non ha senso parlare di regole se il firewall non è in esecuzione.

2. Guarda le zone attive e l’associazione delle interfacce:

firewall-cmd --get-active-zones

Qui devi vedere qualcosa del tipo public con la tua interfaccia, ad esempio ens192. Se l’interfaccia non compare, il traffico potrebbe stare passando da una zona diversa da quella che stai modificando.

3. Elenca le regole della zona attiva:

firewall-cmd --zone=public --list-all

Qui controlli servizi, porte, masquerade, forward-port e sorgenti già ammesse. Se la tua porta non compare, non è autorizzata in quella zona. Se compare ma il servizio continua a non rispondere, il problema è probabilmente più a valle: applicazione, socket, binding o SELinux.

4. Verifica se la regola è solo runtime o anche permanente:

firewall-cmd --zone=public --list-ports --permanent
firewall-cmd --zone=public --list-ports

Se la porta appare solo nella prima o solo nella seconda uscita, hai una configurazione incoerente. In pratica: o il servizio sparisce al reload, oppure non è ancora stato applicato in runtime.

Aprire una porta in modo corretto, senza lasciare buchi inutili

La regola base è: apri il minimo indispensabile, nella zona corretta, e fai subito la verifica. Se stai esponendo un servizio standard, meglio usare il nome del servizio invece del numero di porta: riduci errori e migliori la leggibilità della configurazione.

Per esempio, per HTTP e HTTPS:

firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-service=https

Verifica immediata:

firewall-cmd --zone=public --list-services

Se invece devi aprire una porta custom, per esempio 8443/TCP:

firewall-cmd --zone=public --add-port=8443/tcp

Verifica con:

firewall-cmd --zone=public --list-ports

Il punto importante è distinguere tra TCP e UDP. Scrivere solo 8443 non basta: FirewallD vuole il protocollo. Se sbagli protocollo, la porta sembra “aperta” nel comando ma il traffico reale non entra.

Per rendere persistente il cambio, aggiungi --permanent e ricarica la configurazione:

firewall-cmd --zone=public --add-port=8443/tcp --permanent
firewall-cmd --reload

La sequenza corretta è questa: prima applichi il runtime, verifichi, poi rendi permanente. Se fai il contrario e sbagli, il riavvio ti riporta all’errore iniziale.

Assegnare un’interfaccia alla zona giusta

Se il server ha più NIC o più VLAN, il problema spesso non è la porta ma la zona. Una zona “public” può essere corretta per l’interfaccia esposta su Internet, mentre una “internal” può essere adatta alla rete di management o a una rete backend.

Per associare un’interfaccia alla zona:

firewall-cmd --zone=public --change-interface=ens192

Verifica subito:

firewall-cmd --get-active-zones

Se la modifica deve sopravvivere al reboot, usa anche il parametro permanente oppure la configurazione del sistema di rete, in base alla tua gestione dell’host. Qui c’è un dettaglio operativo utile: se una NIC viene riassegnata via NetworkManager o provisioning, FirewallD può ritrovarsi con una zona diversa da quella attesa dopo un restart della rete. Il controllo da fare è sempre lo stesso: interfaccia, zona, regola.

Usare i servizi predefiniti invece delle porte manuali

Quando esiste un servizio definito in FirewallD, conviene usare quello. Non è solo una questione estetica: i servizi portano con sé porte multiple e, in alcuni casi, dipendenze che altrimenti dovresti ricordare a mano. Per esempio, un servizio DNS o un servizio di gestione remota può richiedere più di una porta o più protocolli.

Elenca i servizi disponibili sul sistema:

firewall-cmd --get-services

Per aggiungere un servizio:

firewall-cmd --zone=public --add-service=ssh

Se il tuo obiettivo è, ad esempio, esporre un server web, usare http e https è più leggibile di due numeri di porta. Inoltre, quando un collega legge la configurazione, capisce subito l’intento senza dover ricordare l’assegnazione delle porte standard.

Regole ricche: sorgenti, forwarding e masquerade

FirewallD non serve solo ad aprire porte. Se devi limitare l’accesso a un range di IP, fare NAT o pubblicare un servizio interno tramite forwarding, le ricche regole diventano la parte interessante. Qui però la prudenza è d’obbligo: una regola di forwarding sbagliata può trasformare il server in un relay indesiderato.

Per autorizzare solo una sorgente o una rete, usa una zona dedicata o una source rule. Un esempio semplice:

firewall-cmd --permanent --zone=trusted --add-source=192.0.2.0/24
firewall-cmd --reload

Verifica con:

firewall-cmd --zone=trusted --list-sources

Per il masquerade, utile in scenari di routing/NAT:

firewall-cmd --zone=public --add-masquerade --permanent
firewall-cmd --reload

Controlla lo stato con:

firewall-cmd --zone=public --query-masquerade

Per il port forwarding, la configurazione va trattata con la stessa attenzione di una modifica di routing. Prima testala su una finestra di manutenzione o con una regola temporanea, poi rendila persistente solo se il flusso è corretto.

Debug operativo: quando la porta è aperta ma il servizio non risponde

Questo è il caso più frequente: FirewallD risulta configurato correttamente, ma dall’esterno non arriva nulla o il client riceve timeout. A quel punto il firewall non è più il sospetto principale. Devi spostarti sul layer successivo senza perdere tempo.

La sequenza di controllo utile è questa:

  • Verifica che il servizio ascolti davvero sulla porta attesa: ss -lntp o ss -lnup. Atteso: socket in ascolto su 0.0.0.0:PORTA o sull’IP corretto.
  • Controlla i log dell’applicazione: per un servizio systemd, journalctl -u nome-servizio -n 100 --no-pager. Cerca errori di binding, permessi o crash all’avvio.
  • Se il servizio ascolta solo su 127.0.0.1, il firewall non c’entra: il problema è nel binding dell’app o nella sua configurazione.
  • Se il servizio è dietro reverse proxy o load balancer, verifica che il proxy stia puntando all’IP e alla porta corretti, non al nome host sbagliato.
  • Un test rapido dall’host stesso aiuta a separare i problemi locali da quelli di rete:

    curl -I http://127.0.0.1:8080
    curl -I http://IP_DEL_SERVER:8080

    Se il primo funziona e il secondo no, il servizio è vivo ma il bind o il firewall non consentono l’accesso sulla rete. Se entrambi falliscono, il problema è nel servizio, non nel firewall.

    Persistenza, reload e differenza tra runtime e permanent

    FirewallD tiene separate le modifiche temporanee da quelle permanenti. È un vantaggio, perché puoi testare senza compromettere la stabilità, ma è anche una trappola per chi dimentica di sincronizzare i due stati.

    Le regole runtime vivono fino al reload o al riavvio. Le regole permanenti si salvano nella configurazione e diventano attive solo dopo un reload o un restart del servizio. La procedura corretta è quindi:

  • Applica la modifica in runtime.
  • Verifica con un test reale, non solo con il comando di elenco.
  • Se tutto è corretto, replica la modifica con --permanent.
  • Ricarica il firewall e verifica di nuovo.
  • Per vedere la configurazione permanente della zona:

    firewall-cmd --permanent --zone=public --list-all

    Per ricaricare senza interrompere il servizio in modo drastico:

    firewall-cmd --reload

    Se hai bisogno di un reset della zona, fallo solo con piena consapevolezza del blast radius. Un reset può rimuovere eccezioni importanti, compreso l’accesso amministrativo. In pratica: backup prima, console fuori banda se disponibile, e rollback chiaro.

    Gestione sicura di SSH e accesso amministrativo

    SSH è il punto dove molti si fanno male. Aprire o chiudere regole su un server remoto senza una sessione di recupero è una pessima idea. Prima di toccare la zona che protegge SSH, mantieni almeno una sessione aperta o un accesso console alternativo.

    Controlla che la porta SSH sia effettivamente quella prevista:

    sshd -T | grep -i '^port '
    firewall-cmd --list-services

    Se SSH non è sulla porta standard 22, apri la porta reale, non il servizio predefinito. Per esempio:

    firewall-cmd --zone=public --add-port=2222/tcp --permanent
    firewall-cmd --reload

    Verifica da un secondo terminale prima di chiudere la sessione corrente. Il rischio qui non è teorico: basta una rule mismatch e perdi l’accesso remoto.

    File di configurazione e dove mettere le mani se serve audit

    Quando devi fare audit o capire perché una modifica non si comporta come previsto, i file permanenti sono il riferimento utile. Su CentOS 8, le configurazioni di zona e servizio sono sotto /etc/firewalld/. È lì che trovi la parte persistente, non nel runtime.

    Le posizioni tipiche da controllare sono:

  • /etc/firewalld/zones/ per le zone personalizzate o modificate
  • /etc/firewalld/services/ per i servizi definiti localmente
  • /usr/lib/firewalld/ per i servizi e le zone forniti dal pacchetto
  • Se devi creare un servizio custom, conviene definire un file XML dedicato in /etc/firewalld/services/ invece di accumulare porte sparse in più punti. In questo modo la configurazione resta leggibile e riutilizzabile. Un esempio concettuale di servizio personalizzato può essere utile se hai un’applicazione con più porte fisse o con una porta non standard ma stabile nel tempo.

    Ricorda però che ogni modifica manuale ai file sotto /etc/firewalld/ va trattata come change controllato: backup del file, diff chiaro, reload e test. Se non sai spiegare a cosa serve una regola tra tre mesi, probabilmente è già troppo complicata.

    Checklist pratica per un setup pulito

    Se vuoi un approccio lineare, usa questa sequenza ogni volta che devi configurare FirewallD su CentOS 8:

  • Identifica l’interfaccia esposta e la zona attiva con firewall-cmd --get-active-zones.
  • Controlla regole già presenti con firewall-cmd --zone=ZONA --list-all.
  • Aggiungi prima la regola runtime, non quella permanente.
  • Verifica con un test reale dalla rete corretta, non solo con il comando di elenco.
  • Replica il cambio con --permanent e fai --reload.
  • Conferma che il servizio risponda dopo il reload e dopo un riavvio, se possibile in finestra di manutenzione.
  • Questa sequenza riduce gli errori più comuni: zona sbagliata, protocollo sbagliato, modifica non persistente e servizio che sembra accessibile solo perché hai testato da localhost.

    Valutazione finale: quando FirewallD è la soluzione giusta

    Su CentOS 8 FirewallD è adatto alla quasi totalità dei server general purpose: web, database, reverse proxy, applicazioni custom, VPN, servizi interni. Ti dà un modello leggibile, zone separate e un livello di astrazione che riduce gli errori rispetto alla manipolazione diretta di regole grezze.

    La sua efficacia però dipende dalla disciplina operativa. Se non distingui tra runtime e permanent, se non controlli la zona dell’interfaccia, o se apri porte senza verificare il processo in ascolto, il firewall diventa solo un altro posto dove cercare colpe a posteriori. Usato bene, invece, è uno strumento pulito: ti fa esporre solo ciò che serve, nel punto giusto, con un audit leggibile e un rollback semplice.