La risposta esce dalla LAN, non dal tunnel: perché e come
Una richiesta che arriva dal tunnel non fa uscire la risposta per lo stesso percorso. Linux cerca la destinazione, e la sottorete locale di solito vince.
Un servizio pubblicato attraverso un gateway funziona dalla maggior parte di Internet e fallisce da un ufficio. Qualcuno controlla il tunnel, vede arrivare la richiesta e conclude che la risposta debba seguire lo stesso percorso al ritorno. Linux non funziona così, e nessuna ispezione del tunnel cambierà la risposta. La risposta viene instradata in base alla destinazione, e quell'unico chiamante che fallisce si trova su una sottorete che l'host raggiunge già direttamente.
Che cosa decide davvero un pacchetto in uscita
Il kernel cerca una rotta per la destinazione del pacchetto, consultando le regole di policy in ordine di priorità e poi la tabella che una regola corrispondente seleziona. L'interfaccia da cui è arrivato un pacchetto non ha alcun ruolo, a meno che una regola o un mark non sia stato scritto per renderla rilevante. È un fatto di routing di questo host, non un guasto del tunnel.
Una richiesta ricevuta dal tunnel può quindi produrre una risposta che esce dall'interfaccia fisica, e il flusso diventa unidirezionale senza che alcun dispositivo segnali un errore. Controlla entrambe le direzioni prima di trarre una conclusione sul tunnel. Una risposta che esce dalla parte sbagliata scompare dai contatori del tunnel, ed è per questo che le due estremità non concordano sul fatto che qualcosa sia stato inviato. Nota quale contatore si è mosso prima di toccare una regola.
Perché vince la sottorete locale
Un host con un indirizzo su una rete locale ha una rotta connessa per quel prefisso nella tabella principale, e una rotta connessa è una corrispondenza diretta. Quando il chiamante arriva da quella stessa sottorete, la ricerca trova il collegamento locale prima ancora che il tunnel venga considerato.
È l'asimmetria a rendere la diagnosi confusa. I chiamanti dal resto di Internet funzionano perché non corrispondono a nessuna rotta locale, mentre l'unico chiamante che condivide il prefisso dell'ufficio fallisce, ed è esattamente quello con cui qualcuno esegue il test.
La copertura dei peer non è lo stesso delle rotte installate
Dal lato del tunnel, gli intervalli consentiti di un peer descrivono cosa può essere inviato nel tunnel e quali sorgenti vengono accettate da esso. Non dicono nulla su dove la tabella di routing locale invierà un pacchetto.
Se lo strumento del tunnel installa una rotta predefinita sull'host, può trascinare traffico non correlato nel tunnel come danno collaterale. Dove invece dovrebbe essere una regola di policy a possedere la decisione, l'opzione di installazione delle rotte dello strumento esiste proprio per impedirlo, e gli indirizzi, le chiavi e le impostazioni dell'endpoint restano esattamente come erano. Una rotta predefinita aggiunta per comodità è un modo comune con cui un host perde la propria rete locale.
Scegli la tabella in base all'indirizzo sorgente
Una regola basata sulla sorgente invia le risposte dall'indirizzo del servizio in una tabella privata il cui valore predefinito è il tunnel, mentre tutto il resto continua a usare la tabella principale. Scegli numeri di tabella e di priorità non usati localmente, e leggi le regole esistenti prima di inserire qualsiasi cosa. Leggi le regole attive invece di un file salvato, perché i due possono differire dopo un riavvio.
ip -6 route add default dev wg0 table 200
ip -6 rule add priority 32000 from 2001:db8:aa::20/128 lookup 200
ip -6 rule add priority 32001 from 2001:db8:aa::20/128 unreachableL'ultima riga fa fallire in modo visibile una rotta mancante invece di ripiegare sul collegamento locale. La sorgente deve essere realmente assegnata all'host, e le ordinarie ricerche locale e principale devono restare nelle loro posizioni precedenti. La regola sceglie una tabella in base alla sorgente; non confronta le lunghezze dei prefissi tra le tabelle.
Conferma il percorso, poi il servizio
Chiedi al kernel cosa farebbe invece di dedurlo da una cattura, usando l'indirizzo del servizio come selettore di sorgente. Una risposta sbagliata qui risparmia un'intera traccia dei pacchetti.
ip -6 route get 2001:db8:bb::30 from 2001:db8:aa::20L'output dovrebbe nominare il tunnel. Poi prova una sorgente che non hai toccato e conferma che prende ancora il collegamento locale, così che la modifica sia rimasta limitata a un indirizzo. Un selettore più ampio non proverebbe nulla sulla lamentela originale.
Cosa non risolve questo
Lascia l'inoltro, le regole del firewall e il comportamento di ICMPv6 sul gateway come erano, perché una rotta di sorgente non sostituisce nessuno di essi. Un messaggio Packet Too Big mancante continua a rompere le risposte grandi, qualunque tabella abbia vinto la ricerca. Correggi questo prima di aggiungere regole di routing, altrimenti il sintomo sopravviverà alla modifica.
Conferma il modello di pubblicazione prima di applicare qualsiasi cosa di questo. Un proxy inverso che apre la propria connessione backend presenta la propria sorgente e non conserva il chiamante, quindi questo guasto non può verificarsi in quel progetto. Applicare la regola lì aggiungerebbe un'eccezione di routing che non risolve nulla e nasconde la causa reale.
Infine, annota i numeri delle regole e la tabella nella gestione della configurazione dell'host. Una regola di policy aggiunta a mano scompare alla successiva ricostruzione, e il chiamante dell'ufficio torna con la stessa lamentela.