presentazioni
Quello che vediamo è un modo per gestire il traffico di rete, a meno della sintassi utilizzata e dal particolare strumento la stessa cosa può essere fatta con qualsiasi firewall.
nftables è il nuovo sistema di filtraggio dei pacchetti per il kernel di Linux, dovrebbe sostituire il vecchio (ma attualmente molto usato) iptables.
Va però rilevato che il sistema è più nuovo rispetto ad iptables (gli autori sono sempre gli stessi) e che la documentazione non è ancora... sovrabbondante... le informazioni fanno riferimento a nftables>0.8 e un kernel linux>3.18
Il pacchetto da installare è nftables
e
l'inoltro dei pacchetti (forwarding) del kernel deve essere ovviamente abilitato.
strutture generali
In linea di principio il funzionamento del sistema si basa su delle tabelle che contengono
delle catene che a loro volta contengono regole. Per interagire con il sistema (che fa parte del kernel)
si usa il comando nft
.
- table
- è la tabella e va associata ad un protocollo come ad esempio ipV4 o ipV6, la regola successiva
crea una tabella per lavorare su ipV4
nft add table ip tEsempio
- chain
- è una catena in cui verranno inserite le regole, ogni catena ha un punto di aggancio
nel sistema di instradamento del kernel:
i punti di aggancio sono i rettangoli nel diagramma, in giallo sono evidenziati quelli che attraversano il server. Ogni catena ha una priorità (perché catene di tabelle diverse vengono valutate in base alla loro priorità) e una politica di default che è accept o drop.nft add chain ip tEsempio cEsempio { type filter hook prerouting priority 0 \; policy accept \; }
Parafrasi: aggiungi una catena chiamatacEsempio
alla tabella chiamatatEsempio
che processa trafficoipV4
, questa catena è un filtro che va agganciato nel punto chiamatoprerouting
, come comportamento predefinito accetta i paccetti. - rule
- sono le regole che decidono le sorti dei pacchetti: specificano una regola per selezionare i pacchetti e un verdetto per i pacchetti che combaciano con la regola (es: butta tutti i pacchetti che arrivano dall'hosto 10.1.2.3).
gestione delle tabelle
I comandi per la gestione delle tabelle sono piuttosto sempici, ne vediamo un breve elenco (nel quale tutte le tabelle iniziano con "t" soltanto per evidenziarne il nome).
nft add table ip tNAT
- aggiunge la tabella tNAT che lavora su ip
nft delete table ip tNAT
- elimina la tabella
nft list tables
- visualizza un elenco di tutte le tabelle presenti nel sistema
nft list table ip tNAT
- mostra il contenuto della tabella tNAT
nft list ruleset
- mostra tutte le regole
In generale "ip" può essere omesso perché viene assunto come valore predefinito.
NAT/masquerading
Vediamo per primo il percorso più semplice, ma lo vediamo in 3 modi diversi!
Negli esempi usiamo 10.0.1.0/24
come rete interna su cui vogliamo
fare Network Address Translation (o Masquerading che dir si voglia) e
10.0.0.2 come IP della nostra macchina verso la rete esterna.
Comandi diretti
Scriviamo uno per uno i comandi:
# nft add table tMascheramento # nft add chain tMascheramento cIngresso { type nat hook prerouting priority 0 \; } # nft add chain tMascheramento cUscita { type nat hook postrouting priority 100 \; } # nft add rule tMascheramento cUscita ip saddr 10.0.1.0/24 oif enp2s11 masquerade
La regola asserisce: "tutto il traffico che viene dalla rete 10.0.1.0/24 e va verso l'interfaccia enp2s11 va mascherato".
Attenzione ad un paio di cose: la catena agganciata al punto di prerouting serve (anche se è vuota) per i pacchetti di ritorno, il "\" prima del ";" serve soltanto per evitare che la shell (Bash o chi per lui) interpreti il punto e virgola.
Uno script per nft
Scrivere il seguente codice in un file e renderlo eseguibile. La prima riga indica che ad interpretare il file deve essere il solito comando... nft!
#!/usr/sbin/nft -f add table tMascheramento add chain tMascheramento cIngresso { type nat hook prerouting priority 0 ; } add chain tMascheramento cUscita { type nat hook postrouting priority 100 ; } add rule tMascheramento cUscita ip saddr 10.0.1.0/24 oif enp2s11 masquerade
Altro script per nft
Stesso discorso di sopra ma con una sintassi diversa (quella ottenuta
in output da nft list ruleset
)
#!/usr/sbin/nft -f table ip tMascheramento { chain cIngresso { type nat hook prerouting priority 0; policy accept; } chain cUscita { type nat hook postrouting priority 100; policy accept; nftrace set 1 ip saddr 10.0.1.0/24 oif "enp2s11" masquerade } }
alternativa
Anzichè usare "masquerade" è possibile usare una sintassi diversa... che fa però lo stesso lavoro:
snat indirizzo_IP
e al posto di indirizzo_IP va inserito l'IP che deve essere inserito
nel pacchetto in uscita, cioè quello dell'interfaccia che usiamo per uscire: 10.0.0.2 nel nostro caso.
Firewall
In linea di principio non è difficile a questo punto scartare i pacchetti, poniamo di avere una tabella chiamata tFuoco con una catena chiamata cInoltro agganciata su forward.
Come si crea la catena cInoltro?
nft add chain cInoltro { type filter hook forward priority 100 \; }non hai inserito il nome della tabella nft add chain tFuoco cInoltro { type filter hook prerouting priority 100 \; }il punto di aggancio è sbagliato nft add chain tFuoco cInoltro { type filter hook forward priority 100 \; } nft add chain tFuoco cInoltro non hai specificato la configurazioen della catenaSe ad esempio voglio scartare tutti i pacchetti che vanno verso uno dei DNS di Google posso scrivere:
nft add rule tFuoco cInoltro ip daddr 8.8.8.8 drop
Port forwarding
Se un server funge da punto di accesso ad una rete potrebbe capitare che deve inoltrare alcune richieste verso altre macchine che non sono connesse ad internet con un IP pubblico: questo meccanismo si chiama "forwarding". Capita ad esempio quando il server web non è direttamente connesso alla rete esterna.
Siccome queste regole (una sola per ogni server!) sono di tipo NAT potrebbe essere una buona idea inserirle nella tabella che fa già NAT (se la abbiamo ovviamente).
Il caso più semplice è questo: le richieste che mi arrivano sulla porta 80 devo girarle al server
il cui indirizzo è a.b.c.d la regola è la seguente:
nft add rule tTabella cCatena iif enp2s11 tcp dport 80 dnat a.b.c.d
oppure con una sintassi alternativa:
nft add rule tTabella cCatena dnat tcp dport map { 80 : a.b.c.d }
Esiste però la possibilità che le richieste che mi arrivano su una porta io debba instradarle
verso un'altra macchina e un'altra porta, possibile anche questo:
nft add rule tNomeTabella cNomeCatena iif enp2s11 dnat tcp dport map { 8080 : 10.0.1.2 } : tcp dport map { 8080 : 80 }
parafrasi: tutto il traffico che arriva dall'interfaccia enp2s11 sulla porta 8080 devi inoltrarlo verso
la macchina 10.0.1.2 porta 80.
In caso possa servire posso redirigere più porte verso macchine diverse con un unico comando:
nft add rule tNomeTabella cNomeCatena dnat
tcp dport map { 8888 : 10.0.1.2, 9999: 10.0.1.3}
: tcp dport map { 8888 : 80, 9999: 8080 }
debug
Purtroppo le cose non vanno sempre bene! Fortunatamente abbiamo degli strumenti per tracciare cosa succede.
Basta inserire meta nftrace set 1
in una regola prima del verdetto (accept o simile) come
ad esempio in
nft add rule tMascheramento cUscita meta nftrace set 1 ip saddr 10.0.1.0/24 oif enp2s11 masquerade
oppure inserendo una regola come la seguente all'inizio di una catena
nft add rule tMascheramento cUscita meta nftrace set 1
Fatto questo il comando nft monitor trace
ci permetterà di vedere cosa succede
al traffico che attraversa il sistema.