Due client VPN possono uscire tramite due indirizzi IPv4 pubblici diversi, e la regola che lo fa è più corta di quanto la maggior parte delle persone immagini. A farla funzionare non è la sintassi di iptables ma lo stato del pacchetto quando raggiunge la catena di uscita: l’indirizzo di origine lì deve ancora distinguere i client. Se un masquerade precedente ha già fatto confluire entrambi su un solo indirizzo, nessuna regola per client può recuperare la distinzione. Risolvi prima questa questione, poi scrivi la traduzione.

Quale identità sopravvive fino al gateway

La regola corrisponde all’indirizzo di origine del pacchetto, non a un nome utente VPN e non al nome che mostra un’applicazione client. Tutto ciò che traduce il pacchetto prima nel percorso determina ciò che la tua regola può ancora vedere. Esegui la tabella nat in ordine e trova il punto in cui l’origine è ancora per client.

iptables -t nat -S POSTROUTING

Leggi quell’elenco dall’alto. Una regola di masquerade vicino all’inizio riscrive l’origine per ogni flusso corrispondente, e le voci per client collocate dopo corrispondono a un indirizzo che non esiste più. Quando due dispositivi LAN condividono un tunnel e arrivano come un unico indirizzo interno, il progetto deve cambiare prima del firewall: mantieni separati i loro intervalli di origine o assegna a ciascuno il proprio indirizzo interno.

Lega l’assegnazione dell’indirizzo interno al client autenticato. Consegnare quell’indirizzo a un altro dispositivo consegna anche la politica di uscita, e la traduzione della sorgente non è di per sé una prova di identità.

La traduzione non può inventare un indirizzo

Ogni indirizzo pubblico deve essere assegnato o instradato verso questo punto di uscita, e le risposte devono trovare la via di ritorno. Una regola che invia traffico da un indirizzo verso cui nessuno instrada al ritorno viene scartata all’estremità remota o riceve risposta verso un host che non l’ha mai chiesta. Un’istanza di un provider cloud di solito ha l’indirizzo pubblico tradotto in un indirizzo di interfaccia privata prima che il pacchetto parta, quindi l’origine SNAT deve essere l’indirizzo che il provider accetterà, non il valore mostrato dalla console. Leggi il modello di indirizzamento del provider e seguilo invece di copiare il valore pubblico in ogni pacchetto.

In pratica ciò significa controllare il prefisso instradato nella console del provider prima di toccare il firewall, e usare l’indirizzo di interfaccia privata come origine della traduzione quando la corrispondenza è uno a uno. Gli indirizzi usati negli esempi seguenti provengono dagli intervalli di documentazione, quindi la prima cosa da sostituire è il testo dell’indirizzo stesso.

Inserisci prima del masquerade generico

Conferma l’interfaccia di uscita e la catena attuale prima di aggiungere qualsiasi cosa. La prima decide quali pacchetti la regola può corrispondere, e la seconda mostra ciò che sta già davanti a essa.

ip -4 route show default
iptables -t nat -L POSTROUTING -n -v --line-numbers

Il primo comando indica l’interfaccia da cui esce davvero un pacchetto verso internet. Il secondo stampa la catena con i numeri di riga. La voce masquerade generica è la riga sopra la quale bisogna restare.

iptables -t nat -I POSTROUTING 1 -s 10.88.4.20/32 -o ens3 -j SNAT --to-source 198.51.100.77
iptables -t nat -I POSTROUTING 1 -s 10.88.4.21/32 -o ens3 -j SNAT --to-source 198.51.100.78

Le due regole sopra corrispondono ciascuna a un indirizzo interno, limitano la corrispondenza all’interfaccia di uscita e impostano l’origine in modo esplicito. Inserisci invece di aggiungere: in posizione 1 vengono valutate prima della riga masquerade. L’ordine tra le due non conta perché le loro origini differiscono. Sostituisci ens3 con ciò che ha riportato il comando di route, e tieni gli altri gestori di firewall lontani dagli stessi hook, poiché due strumenti che scrivono una sola tabella sono la ragione abituale per cui una regola corretta non ha effetto.

Dimostra la sorgente con un nuovo flusso

Il NAT con stato lega una traduzione quando inizia un flusso e la riutilizza per i pacchetti successivi, quindi una sessione aperta prima della modifica conserva la vecchia origine dopo la modifica. Solo una connessione avviata di recente dimostra la regola.

conntrack -L -s 10.88.4.20 -p tcp --dport 443

Leggi la direzione di risposta di quella voce: la sua destinazione è l’indirizzo che l’estremità remota vede come origine. Confrontala con l’indirizzo pubblico che intendevi, e considera una voce che porta l’indirizzo vecchio come prova di un flusso iniziato troppo presto, non di una regola rotta. Chiedi al client di aprire una nuova connessione, poi ripeti la query. Svuotare l’intera tabella di tracciamento per forzare il test interrompe ogni altra sessione sul gateway.

La traduzione non sceglie ancora la rotta, non fa passare il flusso attraverso il filtro e non pubblica un servizio in ingresso. Una rotta sbagliata e una regola di autorizzazione mancante continuano a fallire dopo una regola SNAT perfetta. Controlla anche IPv6 e qualsiasi percorso di uscita secondario, poi annota le coppie interno-pubblico nella documentazione del firewall, così la prossima modifica parte dalla corrispondenza e non dal testo della regola.

Articoli correlati