L'impostazione sembra un interruttore per applicazione, così la gente associa il client all'interfaccia WireGuard e si aspetta che solo quel client usi il tunnel. Ciò che fa davvero l'associazione è scegliere un indirizzo di origine. Poi il kernel cerca una rotta per la destinazione, trova la solita rotta predefinita e manda il pacchetto fuori dal collegamento fisico con l'indirizzo del tunnel allegato. Solo una rotta scelta per quell'indirizzo di origine completa l'intento.

Il meccanismo ha due metà: una tabella di instradamento che solo il traffico del tunnel dovrebbe usare, e una regola che manda lì l'origine corrispondente.

L'associazione imposta un indirizzo di origine, nulla di più

Linux sceglie un'interfaccia di uscita cercando la destinazione in una tabella di instradamento, dopo che le regole di policy hanno avuto la possibilità di reindirizzare quella ricerca. Le regole possono selezionare in base all'indirizzo di origine, a un marchio del firewall, all'interfaccia in ingresso, a un UID o persino a una porta; ognuna è un altro modo di dire questo traffico invece di tutto. La configurazione del client VPN sceglie la tabella che contiene le rotte del tunnel; la regola sceglie quale traffico può consultarla. L'associazione da sola non fornisce nessuna delle due.

Ecco perché il guasto sembra così strano. L'applicazione usa senz'altro l'indirizzo del tunnel, il tunnel è senz'altro attivo e il traffico esce senz'altro dall'interfaccia sbagliata. Ogni affermazione è vera, e insieme descrivono un sistema in cui nulla collegava l'indirizzo alla rotta.

Dai al tunnel la sua tabella

wg-quick installa le rotte dove il profilo gli dice. Aggiungere Table = 40 sotto [Interface] le sposta nella tabella 40 invece che nella tabella principale. Alza l'interfaccia e verifica che siano arrivate: ip -4 route ls table 40 dovrebbe mostrare le rotte del tunnel, e ip -4 route get 10.66.127.142 mostra come il kernel ne risolve una in questo momento. Con le rotte nella loro tabella, la tabella principale continua a funzionare per tutto il resto.

Fai lo stesso per IPv6 invece di far corrispondere un prefisso ampio. ip -6 rule add from fd00::2/128 lookup 40 fissa un indirizzo; fc00::/8 può entrare in collisione con altre interfacce dell'host e produrre una regola che corrisponde a più del previsto.

Aggiungi la regola di origine e guarda i contatori

Poi collega le metà: ip -4 rule add from 10.66.127.142/32 lookup 40, con lo stesso indirizzo allegato all'interfaccia WireGuard. Metti entrambe le regole in PostUp così una riconnessione le ripristina. Verifica con una richiesta reale e non con un'impostazione: ip route get 1.1.1.1 from 10.66.127.142 dovrebbe nominare il dispositivo del tunnel, e curl --interface wg0 ifconfig.me dovrebbe riportare l'indirizzo del tunnel invece di quello di casa.

Quando continua a fallire, leggi ip -s rule. Una regola che esiste ma non ha mai corrisposto mostra contatori a zero, e questo distingue una regola sbagliata dall'assenza di regola. Quel singolo comando risparmia molte congetture sul fatto che l'applicazione abbia ignorato la sua impostazione di interfaccia.

Il caso inverso: tieni SSH fuori dal tunnel

Il problema opposto è altrettanto comune: wg-quick possiede la rotta predefinita e la sessione SSH verso il server muore a metà. Le sue regole stanno su un numero di priorità basso, quindi un'eccezione deve essere valutata prima di loro. ip rule add dport 22 ipproto tcp table main priority 123 lo fa su un iproute2 recente; dove il selettore non è disponibile, marca il flusso in nftables e fai corrispondere il marchio.

Controlla anche il percorso di ritorno. Una sessione SSH che si stabilisce e poi tace di solito ha instradamento asimmetrico, con una direzione che esce dal tunnel e l'altra dall'interfaccia fisica. ip route get per l'indirizzo del server ti dice da che parte andrebbe la risposta.

Annota il numero di tabella, la regola di origine e l'eccezione nel profilo stesso. Tutte e tre appartengono a un solo progetto e verranno modificate insieme.

Articoli correlati