Routing dei criteri in OpenWrt: la catena che intercetta il DNS locale
Le query dei client e quelle del router stesso entrano da hook diversi. Una policy rivolta a prerouting trasporta ogni query della LAN e lascia il router sull’uplink dell’ISP.
I client sulla LAN risolvono attraverso il tunnel e le query del router stesso, in silenzio, non lo fanno. Aggiornamenti dei pacchetti, sincronizzazione dell’ora e DNS dinamico escono tutti dall’uplink ordinario mentre ogni query inoltrata prende la VPN, e nulla nell’interfaccia suggerisce che esistano due percorsi diversi. La spiegazione non è un bug della policy ma una questione di quale hook vede il pacchetto. Due flussi, un indirizzo di resolver, e solo uno dei due attraversa il router. Separarli è tutta la correzione.
Due flussi, un indirizzo di resolver
Il primo flusso è quello che le persone immaginano. Un client interroga il resolver del router, il resolver inoltra a monte, e quel pacchetto inoltrato passa attraverso il router in uscita. Quel pacchetto è visibile a qualunque cosa osservi il traffico inoltrato.
Il secondo flusso non arriva mai da nessuna parte. Lo crea il router, quindi non c’è alcun pacchetto in ingresso né alcun passo di inoltro da far corrispondere.
Entrambi possono puntare allo stesso indirizzo di resolver, ed è proprio per questo che la differenza sfugge facilmente. Stessa destinazione, origine diversa, catena diversa. Una volta visto l’origine, il resto della diagnosi segue.
I pacchetti inoltrati e quelli generati localmente entrano in modo diverso
Il traffico inoltrato viene valutato quando arriva da un’altra interfaccia. I pacchetti di routing dei criteri lo espongono come catena prerouting, e una regola collocata lì vede ogni pacchetto che attraversa il router. Per questo le query dei client si comportano esattamente come descrive la policy, e per questo il router la ignora. La regola non è sbagliata, è solo agganciata a un hook che il router non raggiunge mai. Spostala e la stessa corrispondenza inizia a funzionare.
Il traffico generato localmente è creato da un processo sul router ed entra nel percorso di uscita. Lo instrada la decisione del router stesso e incontra la policy solo se la policy copre quella catena. Non c’è alcuna interfaccia in ingresso da far corrispondere né alcuna decisione di inoltro da osservare.
È una proprietà di dove nascono i pacchetti, non di un pacchetto particolare. Una regola scritta per una catena semplicemente non ha opinioni sull’altra. Nessuna regolazione delle regole lo cambia.
Scegli la catena di uscita, poi restringi la corrispondenza
La correzione è agganciare la stessa intenzione anche alla catena di uscita, o spostare lì la regola quando sono le query del router stesso che ti interessano. In un’installazione OpenWrt costruita su un pacchetto di routing dei criteri, ciò significa scegliere output invece di prerouting nell’impostazione della catena della regola. Mantieni entrambe le regole se entrambe le popolazioni hanno bisogno di copertura.
Poi restringi ciò a cui corrisponde la regola. Gli indirizzi di resolver di destinazione sulla porta che il resolver usa davvero sono una decisione molto più piccola che mandare nel tunnel tutto ciò che il router origina.
Mantieni le due regole esplicite invece di provare a scriverne una che copra entrambe le catene. Regole separate sono più facili da leggere e ti permettono di disattivare il percorso del router senza disturbare il traffico dei client mentre fai debug. Rendono anche i contatori significativi uno alla volta.
Tieni il trasporto del tunnel fuori dalla regola
Anche la connessione esterna del tunnel è creata dal router. Una regola che manda tutto il traffico generato localmente nel tunnel instraderà il tunnel attraverso sé stesso, e non si alzerà affatto.
L’accesso di gestione è la seconda vittima. Le sessioni amministrative originate dal router, o le risposte a esse, possono essere trascinate nel tunnel da una regola locale troppo ampia e diventare irraggiungibili dalla LAN.
Escludi l’endpoint del tunnel dalla corrispondenza e tieni la regola limitata agli indirizzi di resolver. Questo basta per il requisito DNS ed è abbastanza piccolo da poterci ragionare.
Prova entrambe le popolazioni, non una
Osserva il router fare la propria query e annota quale interfaccia l’ha portata. Ripeti la query da un host della LAN e annota il percorso che ha preso. I contatori sulle regole di policy rendono visibili entrambe le risposte senza indovinare.
Tratta i risultati come due riscontri. Un client che risolve attraverso il tunnel non dice nulla sul router, e un router che risolve correttamente non dice nulla su un client su un altro listener. Scrivili come righe separate nel registro delle modifiche.
Controlla anche la porta: una regola che corrisponde alla porta di destinazione 53 manca un resolver raggiunto tramite DNS over TLS sulla 853 o un endpoint HTTPS. Fai corrispondere il trasporto che l’upstream configurato usa davvero, e la fuga si chiude per il motivo giusto.