NAT della LAN attraverso tun0 su un gateway VPN OpenBSD
Scegli tra NAT di origine e una rotta di ritorno per il traffico LAN che esce da un'uscita tun0 OpenBSD, poi colloca la regola nat-to dove pf la lascerà ancora passare.
Due ingegneri con lo stesso gateway OpenBSD ti consegneranno spesso due set di regole diversi per raggiungere una rete remota, ed entrambi sono difendibili. La scelta tra traduzione di origine e rotta di ritorno non è affatto una questione di sintassi. Dipende da cosa il lato remoto sa già di 192.168.88.0/24 e da cosa devi conservare nei tuoi log. Se sbagli questo, la riga nat-to sembrerà perfettamente corretta mentre le risposte svaniscono nel gateway predefinito remoto.
Instradamento e riscrittura rispondono a domande diverse
La tabella di instradamento decide che 172.20.0.0/16 è raggiungibile via tun0, e quella decisione avviene prima che si consulti qualsiasi traduzione pf. Poi la traduzione di origine cambia l'intestazione del pacchetto così che l'estremità remota veda l'indirizzo del tunnel del gateway invece di un host LAN. Nessuno dei due meccanismi sostituisce l'altro: una regola nat non può far comparire una rotta, e una rotta non può persuadere un router remoto che non ha mai sentito parlare della tua sottorete privata. Quando il lato remoto non ha un percorso di ritorno, le risposte vengono scartate o inoltrate al suo gateway predefinito, e nessuna messa a punto delle regole lo sistema.
Detto chiaramente, l'inoltro risponde a dove va il traffico e la traduzione risponde da dove sembra arrivare. Tienili in scatole mentali separate mentre progetti il set di regole.
Tre condizioni che decidono
Poni tre domande in ordine e di solito il progetto si sceglie da solo. La rete remota ha una rotta statica che punta all'indirizzo del tunnel per 192.168.88.0/24, oppure il suo amministratore controlla i router su quel percorso? Se sì, lascia viaggiare gli indirizzi LAN senza modifiche e salta del tutto la traduzione. Ti serve visibilità per client sul lato remoto, per la politica di accesso o per una traccia di audit? Se sì, preservare l'origine vale il lavoro di instradamento. L'indirizzo del tunnel è abbastanza stabile da essere scritto in una rotta remota, o cambia tra una riconnessione e l'altra?
Se una qualsiasi risposta è no o sconosciuta, nat-to è l'opzione pragmatica, ed è anche quella reversibile. Una regola di traduzione si toglie in una sola riga quando il lato remoto aggiunge una rotta adeguata. Una rotta di ritorno mai installata ti costa un thread di supporto ogni volta che qualcuno chiede perché il tunnel funziona solo in una direzione.
Collocare il frammento perché pf lo valuti davvero
Il frammento seguente presuppone che la LAN sia 192.168.88.0/24, la rete remota 172.20.0.0/16 e l'interfaccia del tunnel tun0. Nulla in esso sceglie un next hop. Riscrive solo l'origine sui pacchetti che stanno già uscendo dal tunnel.
match out on tun0 inet from 192.168.88.0/24 to 172.20.0.0/16 nat-to (tun0)
pass in on em0 inet from 192.168.88.0/24 to any keep state
Due dettagli in quella prima riga portano la maggior parte del peso. Le parentesi attorno a tun0 dicono a pf di leggere l'indirizzo dell'interfaccia ogni volta che costruisce una voce di stato, il che conta quando il tunnel viene rinumerato dopo una riconnessione. La parola match significa che la regola riscrive e poi ricade, quindi una regola pass separata deve comunque ammettere il flusso. L'interfaccia nominata nella riga match deve anche essere quella che la tabella di instradamento seleziona, altrimenti pf valuta la regola su un percorso in uscita diverso da quello che il pacchetto prende davvero.
Non dimenticare il lato kernel. L'inoltro IPv4 deve essere abilitato, e le regole pass con stato per tunnel e LAN devono esistere prima che tutto questo abbia senso. La sezione PF NAT delle FAQ di OpenBSD è il riferimento giusto per l'ordine delle parole chiave qui.
Verifica il set di regole prima di fidarti del traffico
Controlla prima la sintassi con pfctl -nf /etc/pf.conf, che analizza il file senza caricarlo. Poi carica la politica e rileggi ciò che il kernel tiene davvero, perché una regola analizzata correttamente può comunque essere oscurata o agganciata all'interfaccia sbagliata. pfctl -sn stampa le regole di traduzione nella loro forma caricata, e pfctl -sr stampa le regole di filtro in ordine di valutazione.
Poi osserva il cavo. Sul gateway, tcpdump -ni tun0 'host 172.20.0.10' mostra se l'indirizzo di origine che esce dal tunnel è quello del tunnel o quello dell'host LAN. Un rapido netstat -rn -f inet conferma su quale interfaccia si risolve la destinazione. Una volta che il traffico scorre, pfctl -ss elenca le voci di stato; se un flusso non ha prodotto stato, il pacchetto non ha mai incontrato una regola che lo crei.
Se il lato tunnel sembra a posto e le risposte ancora non arrivano, smetti di modificare pf. Il guasto restante sta sul router remoto, dove la risposta viene inviata verso un indirizzo privato che quel lato non può raggiungere.
Quando la traduzione costa più di quanto faccia risparmiare
La traduzione nasconde i client, e a volte è esattamente lo scambio sbagliato. Le sottoreti sovrapposte sono un caso: se anche il lato remoto usa 192.168.88.0/24 internamente, presentare gli host LAN come gateway peggiora la collisione invece di migliorarla. Le politiche IPsec che selezionano il traffico per coppia di indirizzi sono un altro, perché il database delle politiche di sicurezza viene confrontato prima della traduzione e non vede mai il pacchetto riscritto. Qualsiasi distribuzione che fatturi, limiti o verifichi per utente perde anche l'identità che le serve nel momento in cui l'origine collassa a un solo indirizzo.
I derivati portatili di pf sono una trappola a parte. I prodotti che generano i propri file di regole si aspettano che NAT sia configurato tramite la loro interfaccia, e i frammenti modificati a mano vengono sovrascritti al ricaricamento successivo. I set di regole copiati da guide scritte prima che esistesse la parola chiave match non si caricheranno su un kernel attuale, quindi porta la sintassi e leggi l'errore invece di indovinare.
La regola decisionale che sopravvive al contatto con le reti reali è breve: installa una rotta di ritorno quando puoi, traduci quando non puoi, e annota quale delle tre condizioni ti ha fatto scegliere. Quella nota risparmia un pomeriggio alla persona successiva.