Routing per origine per due pool VPN: cosa si perde la vostra regola
Una regola della forma from corrisponde all'indirizzo del client prima che SNAT lo riscriva, e un test dal gateway non corrisponde a nessuna delle due. Eseguite la ricerca per pool e leggete invece le priorità.
Due pool di client, un gateway e il piano sembra banale: una regola manda il primo pool sul collegamento rapido, un'altra manda il secondo pool attraverso un tunnel partner. Poi le regole sono a posto e il secondo pool esce ancora dalla rotta predefinita. La regola non è rotta. L'origine del pacchetto non è quella che l'autore si aspettava al momento della ricerca, perché traduzione e ricerca avvengono in punti diversi del viaggio dello stesso pacchetto, e l'ordine è l'opposto dello schema mentale che quasi tutti disegnano.
La ricerca avviene prima che l'origine venga riscritta
Per un pacchetto inoltrato da un client VPN, il kernel esegue una sequenza fissa. Arriva sull'interfaccia del tunnel, passa per prerouting dove vivono conntrack e DNAT, poi viene presa la decisione di routing, poi l'inoltro, poi postrouting dove SNAT viene applicato per ultimo. Una regola della forma from viene consultata durante quella decisione di routing, cioè vede l'indirizzo originale del client, non quello tradotto.
Aggiungere una regola masquerade non cambia quindi quale politica corrisponde al flusso uscente. Cambia ciò che vede l'estremità remota, e quindi quale percorso di ritorno esiste. Sono due conseguenze diverse, e le revisioni dei cambiamenti le confondono continuamente. Separatele e il progetto diventa di solito evidente entro un minuto.
È nella direzione della risposta che l'indirizzo tradotto compare nelle regole. Un pacchetto che torna al gateway è indirizzato all'indirizzo tradotto, e se avete regole di politica basate sulla destinazione o sull'interfaccia da cui è arrivato, è quel valore che confronterete. La stessa connessione, una fonte di verità diversa in ciascuna direzione.
| Stage | Source the kernel sees | What it means for your rule |
|---|---|---|
| Prerouting | Client address, 172.31.7.42 | Where marks and DNAT are applied |
| Routing decision | Still 172.31.7.42 | This is where from rules match |
| Postrouting | Becomes 198.51.100.9 | What the far end and its return route see |
Due pool con origini diverse hanno quindi davvero bisogno di tabelle diverse, e il progetto è solido. Ciò che la tabella qui sopra esclude è la scorciatoia di fare debug guardando cosa ha ricevuto il sito remoto e deducendone la regola.
Un test dal gateway non è un test del pool
Il traffico che il gateway stesso genera non passa mai per prerouting, perché non è arrivato su un'interfaccia. Viene instradato nel percorso di output, con l'indirizzo del gateway stesso come origine, e una regola from basata su un intervallo di client non corrisponderà. Ogni ticket in questo ambito che dice che funziona dalla macchina ma non dal client è lo stesso fatto ripetuto.
Simulate il client invece di approssimarlo. Alla ricerca di routing si può chiedere direttamente, fornendo un'origine e un'interfaccia di ingresso:
ip route get 198.51.100.9 from 172.31.7.42 iif tun0
ip route get 198.51.100.9 from 172.31.8.42 iif tun0
ip route show table 201
Eseguitelo una volta per pool. Se i due comandi restituiscono la stessa interfaccia, le regole non separano i pool, e il motivo è o una regola mancante o una regola con priorità più alta che corrisponde a entrambi. Se restituiscono interfacce diverse ma il client continua a fallire, il guasto è a valle della ricerca e potete smettere di guardare le regole.
La priorità, non la posizione nel file
Le regole vengono valutate in ordine crescente di priorità, e conta il numero, non l'ordine in cui le avete digitate. La tabella local sta a priorità 0, la tabella main a 32766 e la regola predefinita a 32767, per questo una regola aggiunta con la priorità predefinita finisce vicino alla fine dell'elenco e perde contro quasi tutto.
ip rule show
ip rule add from 172.31.8.0/24 lookup 201 priority 1000
ip -4 route show table 201
Una priorità esplicita rende visibile l'ordine voluto nel file e in revisione. Impedisce anche che un'aggiunta successiva scavalchi silenziosamente una regola esistente, che è la causa più frequente di una politica che funziona e smette di funzionare dopo un cambiamento non correlato.
Una regola corrispondente che punta a una tabella incompleta è l'altra trappola. Se la tabella 201 contiene una rotta predefinita ma nessuna rotta verso la destinazione, il pacchetto viene scartato o inviato nel posto sbagliato, e la regola sembra perfettamente corretta isolata. Leggete la tabella, non solo la regola. Una regola è un puntatore, e una tabella vuota è un puntatore al nulla.
Il percorso di ritorno deve comunque esistere
La politica di origine sceglie un'uscita. Non crea un percorso di ritorno. Se il secondo pool esce attraverso un tunnel partner, il partner deve sapere come raggiungere 172.31.8.0/24, o con una rotta di ritorno verso il gateway o ricevendo indirizzi tradotti che già conosce.
Scegliere tra le due è una decisione di progetto con conseguenze visibili. Instradare l'intervallo client di ritorno conserva l'identità di ogni client presso il partner e richiede che accetti il vostro prefisso. La traduzione nasconde il pool dietro un solo indirizzo e richiede che il partner accetti solo quell'indirizzo, al costo che i vostri registri e i suoi non concordino più su chi si è connesso.
Qualunque cosa scegliate, scrivetela accanto alla definizione del pool. Una rotta di ritorno che esiste solo nella memoria di qualcuno è esattamente il tipo di cosa che sopravvive finché il partner cambia un firewall, e poi richiede un giorno per essere ricostruita.
Non catturate il tunnel del gateway nella politica
Le regole che scrivete per i client valgono anche per il traffico che il gateway genera, a meno che non lo escludiate. Una regola ampia basata su un mark o sull'interfaccia di uscita può catturare la connessione del gateway stesso verso il partner, e allora il tunnel che trasporta la politica viene instradato dalla politica. Questo produce un loop o un'interruzione che sembra un guasto del provider.
Limitate ogni regola il più possibile: prefisso di origine, interfaccia di ingresso e, dove supportato, un mark che solo i pacchetti dei client portano. Poi testate la connettività del gateway stesso dopo ogni modifica alle regole, perché il guasto è autoreferenziale e non compare in un test dal client.
La pagina di manuale di ip-rule documenta la semantica del selettore e della priorità. Combinatela con un test di ricerca per pool e il progetto diventa verificabile, che è la differenza tra un routing policy che dura un anno e uno che tutti temono di toccare.