Perché nftables
nftables è il sottosistema di filtraggio dei pacchetti del kernel Linux che ha sostituito iptables. Su Ubuntu 24.04 è già tutto pronto: il pacchetto nftables è installato, il comando iptables stesso è solo un traduttore verso nftables (iptables-nft) e il servizio nftables.service carica all’avvio il file /etc/nftables.conf.
Rispetto a iptables hai alcuni vantaggi concreti:
- un solo comando,
nft, per IPv4, IPv6, ARP e bridge; - la famiglia inet: una sola tabella filtra insieme IPv4 e IPv6, quindi non devi mantenere due firewall paralleli che prima o poi divergono;
- variabili (
define) e set nominati: elenchi di indirizzi o porte che consulti in una sola regola e che puoi modificare a caldo; - caricamento atomico:
nft -fapplica tutto il file o niente, senza stati intermedi.
In questa guida costruiamo due firewall completi: quello di un server esposto su Internet e quello di un gateway che separa WAN, LAN e DMZ.
I concetti in cinque minuti
In nftables non esistono tabelle e catene predefinite: le crei tu. Una tabella appartiene a una famiglia (ip, ip6, inet…) e contiene catene e set. Una catena base si aggancia a un punto del percorso del pacchetto nel kernel (l’hook) con una certa priorità e una policy, cioè il verdetto applicato se nessuna regola decide.
Tre regole che eviteranno molti mal di testa:
- Il primo verdetto vince, dentro una catena. Le regole si leggono dall’alto: il primo
acceptodropchiude la valutazione di quella catena. dropè definitivo,acceptno. Se allo stesso hook ci sono più catene base (la tua, quella di Docker, quella di fail2ban), unacceptfa passare il pacchetto alla catena successiva; undropin una qualsiasi lo scarta per sempre. Le catene si eseguono in ordine di priorità, dal numero più basso.iifnameinvece diiifper le interfacce fisiche e virtuali:iifusa l’indice dell’interfaccia, che deve esistere quando carichi le regole;iifnameconfronta il nome e funziona anche con interfacce create dopo (wg0,ppp0,gre1). Perlo, che esiste sempre,iifva benissimo ed è più veloce.
Le priorità hanno nomi simbolici: raw (−300), mangle (−150), dstnat (−100), filter (0), srcnat (100). Li userai nelle definizioni delle catene.
Preparazione
1. Spegnere UFW
Su Ubuntu è installato anche UFW, normalmente inattivo. UFW genera le sue regole tramite iptables-nft: se lo usi insieme a un /etc/nftables.conf scritto a mano ottieni due firewall che si sovrappongono, e un drop dell’uno vanifica gli accept dell’altro. Scegline uno solo. Per questa guida:
sudo ufw status # deve rispondere "Status: inactive"
sudo ufw disable # se era attivo
sudo systemctl disable --now ufw
2. Avere un piano di emergenza
Prima di toccare il firewall di una macchina remota assicurati di avere un accesso fuori banda: la console della macchina virtuale, l’iDRAC/iLO, la console seriale o la console web del provider. Se non ce l’hai, segui alla lettera la procedura con il rollback automatico descritta più avanti, in Applicare le regole senza chiudersi fuori.
3. Salvare le regole attuali
sudo sh -c '{ echo "flush ruleset"; nft list ruleset; } > /root/nft-prima.nft'
sudo cp /etc/nftables.conf /root/nftables.conf.orig
Il primo file è una fotografia delle regole caricate in questo momento, pronta per essere ricaricata così com’è.
Parte 1: il firewall di un server
Scenario: un server web Ubuntu con un’interfaccia ens18 su Internet. Vogliamo:
- tutto chiuso in ingresso, salvo quello che apriamo esplicitamente;
- SSH raggiungibile solo dalla rete di amministrazione (192.168.50.0/24, un IP fisso dell’ufficio 198.51.100.7 e la rete IPv6 2001:db8:50::/64), con un limite alle nuove connessioni;
- HTTP e HTTPS aperti a tutti;
- i pacchetti scartati registrati nel log, senza intasarlo;
- il traffico in uscita libero.
#!/usr/sbin/nft -f
# Firewall del server web – Ubuntu 24.04
# Verifica: nft -c -f /etc/nftables.conf Applica: nft -f /etc/nftables.conf
flush ruleset
define PORTA_SSH = 22
define PORTE_WEB = { 80, 443 }
table inet filtro {
# --- Reti da cui è consentito SSH -------------------------------
set admin4 {
type ipv4_addr
flags interval
elements = { 192.168.50.0/24, 198.51.100.7 }
}
set admin6 {
type ipv6_addr
flags interval
elements = { 2001:db8:50::/64 }
}
# --- Set dinamici per limitare le nuove connessioni SSH ---------
# Ogni sorgente resta nel set per 2 minuti dall'ultimo tentativo
set ssh_lim4 {
type ipv4_addr
flags dynamic
timeout 2m
}
set ssh_lim6 {
type ipv6_addr
flags dynamic
timeout 2m
}
chain input {
type filter hook input priority filter; policy drop;
# Loopback e connessioni già stabilite
iif "lo" accept
ct state established,related accept
ct state invalid drop
# ICMPv6: neighbor discovery e router advertisement sono
# indispensabili, senza IPv6 smette di funzionare
icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } ip6 hoplimit 255 accept
icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept
icmpv6 type echo-request limit rate 10/second accept
# ICMP IPv4: errori (servono alla scoperta dell'MTU) e ping limitato
icmp type { destination-unreachable, time-exceeded, parameter-problem } accept
icmp type echo-request limit rate 10/second accept
# DHCPv6: serve solo se il server prende l'indirizzo IPv6 via DHCPv6
# ip6 saddr fe80::/10 udp sport 547 udp dport 546 accept
# SSH: solo dalle reti di amministrazione, massimo 4 nuove
# connessioni al minuto per indirizzo sorgente
tcp dport $PORTA_SSH ct state new ip saddr @admin4 update @ssh_lim4 { ip saddr limit rate over 4/minute } counter drop
tcp dport $PORTA_SSH ct state new ip saddr @admin4 accept
tcp dport $PORTA_SSH ct state new ip6 saddr @admin6 update @ssh_lim6 { ip6 saddr limit rate over 4/minute } counter drop
tcp dport $PORTA_SSH ct state new ip6 saddr @admin6 accept
# Servizi pubblici
tcp dport $PORTE_WEB accept
# udp dport 443 accept # solo se servi HTTP/3 (QUIC)
# Tutto il resto finisce nella policy drop: registriamo
# al massimo 5 righe al minuto per non riempire il log
counter limit rate 5/minute burst 10 packets log prefix "nft-in-drop: " level info
}
chain forward {
# Il server non instrada: niente passa
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}Perché la tabella inet
Con table inet filtro la stessa catena input vede sia i pacchetti IPv4 sia quelli IPv6. Le regole che non citano la versione del protocollo (tcp dport 443, ct state) valgono per entrambe; quelle che usano ip saddr valgono solo per IPv4, quelle con ip6 saddr solo per IPv6. Con le famiglie separate ip e ip6 dovresti scrivere e tenere allineati due file: il classico errore è chiudere bene IPv4 e lasciare IPv6 spalancato.
Stato delle connessioni e loopback
ct state established,related accept sta in alto perché riguarda la stragrande maggioranza dei pacchetti: le risposte alle connessioni già accettate, comprese quelle aperte dal server verso l’esterno (aggiornamenti, DNS). related copre i pacchetti collegati a una connessione esistente, come i messaggi ICMP di errore. I pacchetti invalid non appartengono a nessuna connessione valida e si possono scartare subito.
ICMP e ICMPv6: non chiuderli
In IPv6 non c’è ARP: la risoluzione degli indirizzi dei vicini (neighbor solicitation/advertisement) e la configurazione automatica (router advertisement) viaggiano in ICMPv6. Se le blocchi, IPv6 funziona per qualche minuto grazie alla cache e poi il server diventa irraggiungibile. Il controllo ip6 hoplimit 255 garantisce che questi messaggi arrivino dal collegamento locale e non da un router remoto.
Anche in IPv4 i messaggi di errore servono: destination-unreachable trasporta il “fragmentation needed” usato dalla scoperta dell’MTU del percorso. Il ping è utile per il monitoraggio: lo lasciamo passare con un limite.
SSH: set nominati e rate limiting
I set admin4 e admin6 contengono reti e singoli indirizzi (flags interval permette di usare i prefissi). Aggiungere una sede significa modificare una riga, non duplicare regole.
I set ssh_lim4 e ssh_lim6 sono dinamici: li riempie il firewall stesso. L’istruzione update @ssh_lim4 { ip saddr limit rate over 4/minute } inserisce l’indirizzo sorgente nel set (o ne aggiorna la scadenza) e associa a ognuno un proprio contatore. Se una sorgente supera le 4 nuove connessioni al minuto, la regola è vera e il pacchetto viene scartato; altrimenti si passa alla regola successiva, che accetta. È la versione moderna dei meter, ora deprecati.
Il limite riguarda solo i pacchetti ct state new: le sessioni già aperte non ne risentono. Per un blocco basato sui tentativi di login falliti, e non sul semplice numero di connessioni, affianca fail2ban.
Il log dei pacchetti scartati
L’ultima regola della catena input non dà un verdetto: conta e registra, poi il pacchetto cade nella policy drop. Il limit è fondamentale: senza, una scansione di porte scriverebbe migliaia di righe al secondo. Il prefisso nft-in-drop: ti permette di filtrare il log del kernel.
Applicare le regole senza chiudersi fuori
Se lavori in SSH, un errore nella regola di SSH ti chiude fuori. La procedura sicura ha quattro passi.
1. Controllare la sintassi
sudo nft -c -f /etc/nftables.conf
Con -c nft analizza il file e lo valida con il kernel, ma non lo applica. Se non stampa nulla, il file è corretto. Attenzione: il controllo trova gli errori di sintassi, non quelli di logica come una rete di amministrazione sbagliata.
2. Programmare il ritorno alle regole precedenti
Prima di applicare, prepara un rollback che scatta da solo dopo 3 minuti:
sudo systemd-run --on-active=3min --unit=nft-rollback /usr/sbin/nft -f /root/nft-prima.nft
In alternativa, con il pacchetto at (da installare) o con un semplice sleep lasciato in esecuzione in una sessione tmux:
echo "/usr/sbin/nft flush ruleset" | sudo at now + 3 minutes
sudo sh -c 'sleep 180 && nft flush ruleset' # dentro tmux: annulli con Ctrl+C
nft flush ruleset cancella tutte le regole e lascia la macchina completamente aperta: va bene come paracadute, ma solo per pochi minuti.
3. Applicare e verificare da una nuova sessione
sudo nft -f /etc/nftables.conf
La sessione SSH già aperta sopravvive grazie a ct state established: non è una prova. Apri una seconda sessione SSH da un indirizzo della rete di amministrazione. Se entra, annulla il rollback:
sudo systemctl stop nft-rollback.timer
# oppure, con at:
atq
sudo atrm <numero-del-job>
Se la seconda sessione non entra, non fare niente: entro 3 minuti tornano le regole di prima.
4. Rendere le regole permanenti
sudo systemctl enable --now nftables
systemctl status nftables
Il servizio carica /etc/nftables.conf all’avvio, prima che la rete salga. Dopo ogni modifica al file usa sudo systemctl reload nftables (o direttamente sudo nft -f /etc/nftables.conf), sempre preceduto da nft -c.
systemctl stop nftables esegue nft flush ruleset: cancella le tue regole ma anche quelle di Docker, fail2ban e di chiunque altro. Vedi Convivere con Docker, UFW e fail2ban.
Parte 2: il firewall di un gateway
Secondo scenario: un server Ubuntu con tre schede di rete fa da router e firewall per una piccola sede.
Prima di scrivere le regole, decidi la matrice dei flussi: chi può parlare con chi. Tutto ciò che non è nella tabella è vietato.
| Da → A | Internet (WAN) | DMZ | LAN | Gateway stesso |
|---|---|---|---|---|
| Internet | – | solo 80/443 verso 172.16.0.10 | no | no |
| DMZ | HTTP/HTTPS, DNS, NTP | – | no | no |
| LAN | sì | sì | – | DNS, DHCP, SSH |
La regola d’oro della DMZ: la DMZ non apre mai connessioni verso la LAN. Se il server web viene compromesso, l’attaccante resta confinato lì.
Abilitare l’instradamento
net.ipv4.ip_forward = 1sudo sysctl --system
sysctl net.ipv4.ip_forward # deve valere 1
La configurazione del gateway
#!/usr/sbin/nft -f
# Firewall del gateway – Ubuntu 24.04
flush ruleset
define WAN = "ens18"
define LAN = "ens19"
define DMZ = "ens20"
define RETE_LAN = 192.168.1.0/24
define RETE_DMZ = 172.16.0.0/24
define WEB_DMZ = 172.16.0.10
table inet filtro {
# Indirizzi che non possono arrivare legittimamente da Internet
set bogon4 {
type ipv4_addr
flags interval
elements = { 0.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8,
169.254.0.0/16, 172.16.0.0/12, 192.168.0.0/16,
224.0.0.0/3 }
}
# --- Anti-spoofing, prima di NAT e filtro -----------------------
chain antispoof {
type filter hook prerouting priority mangle; policy accept;
iifname $WAN ip saddr @bogon4 counter drop
# Le richieste DHCP dei client hanno sorgente 0.0.0.0:
# le escludiamo dal controllo successivo
udp sport 68 udp dport 67 accept
# Reverse path filter: la sorgente deve essere raggiungibile
# attraverso l'interfaccia da cui il pacchetto è entrato
meta nfproto ipv4 fib saddr . iif oif missing counter drop
}
# --- Traffico diretto al gateway --------------------------------
chain input {
type filter hook input priority filter; policy drop;
iif "lo" accept
ct state established,related accept
ct state invalid drop
icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } ip6 hoplimit 255 accept
icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept
icmp type { destination-unreachable, time-exceeded, parameter-problem } accept
icmp type echo-request limit rate 10/second accept
# Servizi del gateway per la LAN: DNS, DHCP, SSH di gestione
iifname $LAN udp dport { 53, 67 } accept
iifname $LAN tcp dport { 22, 53 } accept
counter limit rate 5/minute burst 10 packets log prefix "nft-in-drop: " level info
}
# --- Traffico che attraversa il gateway -------------------------
chain forward {
type filter hook forward priority filter; policy drop;
# MSS clamping: adegua l'MSS dei SYN all'MTU del percorso
tcp flags syn tcp option maxseg size set rt mtu
ct state established,related accept
ct state invalid drop
# LAN: verso Internet e verso la DMZ
iifname $LAN oifname { $WAN, $DMZ } accept
# DMZ: verso Internet solo aggiornamenti, DNS e NTP.
# Verso la LAN niente: lo decide la policy drop
iifname $DMZ oifname $WAN tcp dport { 80, 443 } accept
iifname $DMZ oifname $WAN udp dport { 53, 123 } accept
# Internet: solo le connessioni pubblicate con DNAT
iifname $WAN oifname $DMZ ip daddr $WEB_DMZ tcp dport { 80, 443 } ct status dnat accept
counter limit rate 5/minute burst 10 packets log prefix "nft-fwd-drop: " level info
}
chain output {
type filter hook output priority filter; policy accept;
}
}
# --- NAT (solo IPv4) ------------------------------------------------
table ip natgw {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
# Port forwarding verso il server web in DMZ
iifname $WAN tcp dport { 80, 443 } dnat to $WEB_DMZ
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
# LAN e DMZ escono con l'indirizzo pubblico del gateway
oifname $WAN ip saddr { $RETE_LAN, $RETE_DMZ } masquerade
}
}Forward con policy drop
Tutto il lavoro di un gateway sta nella catena forward. Con la policy drop ogni flusso che non hai previsto viene bloccato, compreso il traffico IPv6 tra le zone: se in futuro instraderai anche IPv6, aggiungi le regole corrispondenti. Nota come le regole seguono riga per riga la matrice dei flussi: è il modo più semplice per rileggerle a distanza di mesi.
Masquerade e port forwarding
Il NAT ha una sua tabella, di famiglia ip perché riguarda solo IPv4. La chiamo natgw e non nat di proposito: ip nat è il nome della tabella che crea iptables-nft (e quindi Docker), e conviene non mescolarle.
- masquerade in
postroutingsostituisce l’indirizzo sorgente con quello dell’interfaccia WAN. Rispetto asnat toha il vantaggio di seguire da solo l’indirizzo anche se cambia (DHCP, PPPoE). - dnat in
preroutingriscrive la destinazione prima della decisione di instradamento: il pacchetto entra per 203.0.113.2 e la catenaforwardlo vede già diretto a 172.16.0.10. Per questo la regola inforwardusa l’indirizzo interno.ct status dnataggiunge una garanzia: passa solo il traffico che è davvero stato traslato.
MSS clamping
Se un tratto del percorso ha MTU inferiore a 1500 (PPPoE, tunnel) e qualcuno filtra i messaggi ICMP, le connessioni TCP si bloccano sui pacchetti grandi: il sito si apre a metà, i trasferimenti si fermano. La regola tcp option maxseg size set rt mtu corregge al volo l’MSS dei pacchetti SYN in base all’MTU della rotta di uscita. Sta prima di ct state established perché deve vedere anche il SYN/ACK di risposta, che appartiene già a una connessione nota.
Anti-spoofing
La catena antispoof si aggancia a prerouting con priorità mangle (−150), cioè prima del DNAT (−100). Fa due controlli:
- scarta i pacchetti che arrivano dalla WAN con sorgente privata o riservata (il set
bogon4); - con
fib saddr . iif oif missingchiede alla tabella di instradamento se la sorgente è raggiungibile attraverso l’interfaccia di ingresso. Un pacchetto che entra dalla WAN con sorgente 192.168.1.50 non supera il controllo.
Quando l’interfaccia WAN ha un indirizzo privato (per esempio 192.168.0.2 dietro il router dell’operatore), il set bogon4 scarterebbe anche le risposte DHCP e il traffico del modem: togli dal set la rete del collegamento verso il modem. Il controllo fib resta valido. In alternativa al fib puoi usare il filtro del kernel con net.ipv4.conf.all.rp_filter = 1; Ubuntu lo imposta di default a 2, la modalità “loose”, più permissiva.
Convivere con Docker, UFW e fail2ban
Più programmi possono scrivere regole nel kernel nello stesso momento. Ognuno usa le proprie tabelle, ma tutti condividono gli stessi hook.
UFW
Non usare UFW e un /etc/nftables.conf scritto a mano sulla stessa macchina. UFW crea catene con policy propria agli stessi hook: un pacchetto deve essere accettato da entrambi i firewall, e il risultato è difficile da prevedere e da diagnosticare. UFW va benissimo su un server semplice; per un gateway o per regole come quelle di questa guida, usa solo nftables.
fail2ban
fail2ban, con l’azione nftables predefinita su Ubuntu 24.04, crea la sua tabella inet f2b-table con una catena in input a priorità −1, quindi valutata prima della tua: un indirizzo bannato viene respinto anche se le tue regole lo accetterebbero. Il problema è il flush ruleset in testa al tuo file: ogni volta che ricarichi nftables cancelli anche la tabella di fail2ban, e i ban spariscono. Dopo ogni ricarica:
sudo nft -f /etc/nftables.conf && sudo systemctl restart fail2ban
Tutti i dettagli nella guida Fail2ban su Linux.
Docker
Docker gestisce la rete dei container con iptables-nft: crea le tabelle ip filter e ip nat con le sue catene. Due conseguenze:
- Il
flush rulesetcancella le regole di Docker. Dopo aver ricaricato il firewall, eseguisudo systemctl restart docker, altrimenti i container perdono la rete e le porte pubblicate. - La tua policy
dropinforwardvale anche per i container. Il traffico verso i container attraversaforward: se la tua catena lo scarta, l’acceptdi Docker non basta. Su un host Docker aggiungi inforward, dopo la rigact state established,related accept, per esempioiifname "docker0" accept(i container escono) eoifname "docker0" ct status dnat accept(le porte pubblicate), adattandole alle reti dei tuoi container: le reti definite condocker network createusano interfaccebr-…, nondocker0.
Se sulla macchina convivono più programmi, al posto di flush ruleset puoi azzerare solo le tue tabelle. All’inizio del file scrivi, per ogni tabella:
table inet filtro
delete table inet filtro
La prima riga crea la tabella se non esiste, la seconda la elimina: così il file si ricarica sempre senza errori e senza toccare f2b-table o le tabelle di Docker. Ricorda però che systemctl stop nftables esegue comunque un flush ruleset completo.
Verifiche: regole, contatori e log
Leggere le regole caricate
sudo nft list ruleset # tutto, comprese le tabelle di Docker e fail2ban
sudo nft list table inet filtro
sudo nft -a list chain inet filtro input # con -a mostra l'handle di ogni regola
Le regole con counter mostrano pacchetti e byte: counter packets 1532 bytes 91920. È il modo più rapido per capire se una regola “lavora”.
Set a caldo
# vedere chi è nel set del rate limiting SSH, con la scadenza
sudo nft list set inet filtro ssh_lim4
# aggiungere al volo un IP di amministrazione (si perde al riavvio:
# riportalo anche in /etc/nftables.conf)
sudo nft add element inet filtro admin4 { 203.0.113.50 }
sudo nft delete element inet filtro admin4 { 203.0.113.50 }
Il log del kernel
sudo journalctl -k -g "nft-in-drop" --since "1 hour ago"
sudo journalctl -k -f # in tempo reale
Ogni riga riporta interfaccia, sorgente, destinazione, protocollo e porte. Con rsyslog installato le stesse righe finiscono anche in /var/log/kern.log.
Seguire un pacchetto passo per passo
Quando non capisci quale regola scarta un pacchetto, usa il tracciamento. Inserisci in testa a una catena una regola che marca il traffico che ti interessa e osserva:
sudo nft insert rule inet filtro input ip saddr 192.168.50.20 meta nftrace set 1
sudo nft monitor trace
# finito: cancella la regola usando il suo handle
sudo nft -a list chain inet filtro input
sudo nft delete rule inet filtro input handle <numero>
nft monitor trace mostra ogni catena e ogni regola attraversata, fino al verdetto finale.
Problemi comuni
| Sintomo | Causa probabile | Cosa fare |
|---|---|---|
| Dopo aver applicato le regole non entri più in SSH | Rete di amministrazione sbagliata, porta SSH diversa da 22, IP di uscita diverso da quello che pensavi | Aspetta il rollback o usa la console; controlla il tuo IP reale con ss -tn sul server prima di applicare |
| IPv6 funziona per qualche minuto e poi smette | ICMPv6 neighbor discovery bloccato | Accetta nd-neighbor-solicit, nd-neighbor-advert e nd-router-advert |
| Ping OK, ma alcuni siti o trasferimenti si bloccano | MTU/MSS, ICMP “packet too big” o “fragmentation needed” scartati | Regola di MSS clamping in forward; non bloccare gli ICMP di errore |
| La LAN non naviga | ip_forward a 0 o masquerade mancante | sysctl net.ipv4.ip_forward; controlla i contatori in forward e postrouting |
| Il port forwarding funziona da Internet ma non dalla LAN | Il DNAT vale solo per il traffico che entra dalla WAN (manca l’hairpin NAT) | Dalla LAN usa l’indirizzo interno, con un DNS interno che risolve il nome in 172.16.0.10 |
Dopo reload i container Docker non hanno rete | flush ruleset ha cancellato le regole di Docker | sudo systemctl restart docker; valuta di azzerare solo le tue tabelle |
| fail2ban non banna più dopo una ricarica | La tabella f2b-table è stata cancellata | sudo systemctl restart fail2ban |
| Regole corrette ma il traffico viene scartato lo stesso | UFW o un altro programma ha catene con policy drop sullo stesso hook | sudo nft list ruleset: cerca altre catene base su input e forward |
Error: Could not process rule al caricamento | Set o variabile non definiti, errore di battitura, regola IPv4 in una tabella ip6 | Leggi la riga indicata dall’errore; nft -c -f segnala il punto esatto |
| Nessuna riga nel log | La regola di log non viene raggiunta o il limite è troppo basso | Controlla il suo contatore; usa journalctl -k, non il log di sistema generico |
Il passo successivo
Il firewall decide chi può raggiungere un servizio; non sa distinguere un login riuscito da mille tentativi falliti. Per bloccare gli attacchi a forza bruta in base ai log, aggiungi Fail2ban su Linux, che usa proprio nftables per i ban. Per proteggere il servizio più esposto, vedi SSH sicuro su Linux. Se il gateway deve collegare altre sedi, i tunnel sono in Tunnel GRE tra Cisco e Ubuntu e VPN IPsec tra Cisco e Ubuntu.
Prova sempre la configurazione in laboratorio, salva quella attuale prima di modificarla e tieni un accesso di emergenza (console o accesso fuori banda) quando lavori su firewall e VPN da remoto.