Aggiungete una rotta predefinita attraverso il tunnel e i pacchetti del tunnel stesso la seguiranno. La tabella contiene allora una regola che sconfigge se stessa. La connessione cifrata al server tenta di viaggiare dentro la connessione che sta cercando di stabilire.

Due meccanismi impediscono questo ciclo. Uno è visibile nella tabella di routing, l'altro vive dentro l'applicazione.

Il traffico interno e quello esterno sono decisioni diverse

Un pacchetto applicativo entra nell'interfaccia virtuale e viene incapsulato. Il risultato è un nuovo pacchetto indirizzato all'indirizzo pubblico del server. Quel pacchetto ha bisogno di una rotta sulla rete fisica, perché nulla di esso può entrare nel tunnel.

Entrambe sono decisioni di routing, e solo la prima appartiene al tunnel. Quando il client installa una rotta predefinita che copre anche il server, anche il pacchetto esterno viene catturato.

I sintomi sono immediati e totali. L'handshake si completa e poi non scorre nulla, oppure la connessione cade nell'istante in cui viene installata la rotta. In entrambi i casi il keepalive non può più uscire.

Opzione uno: una rotta host per l'endpoint

L'approccio diretto aggiunge una rotta per l'indirizzo del server attraverso il gateway originale. Richiede una sola riga. È visibile a chiunque legga la tabella. È anche facile da spiegare in un registro delle modifiche.

La sua debolezza appare quando il percorso sottostante cambia. La rotta salvata nomina un gateway e un'interfaccia della vecchia rete. Dopo un cambio di Wi-Fi quel gateway potrebbe non esistere, e la rotta resta indietro, sembra corretta e non fa nulla.

# before the tunnel: which path reaches the endpoint?
ip route get 198.51.100.7

# pin it through the current gateway
ip route add 198.51.100.7/32 via 192.168.1.1 dev wlan0

# after the tunnel is up, confirm the pin survived
ip route get 198.51.100.7

Un nome host rende tutto più difficile. Se l'endpoint è un nome che si risolve in più indirizzi, l'esclusione deve coprire l'indirizzo realmente in uso. Una risoluzione successiva può restituire qualcosa che la rotta non ha mai coperto.

Opzione due: proteggere il socket

L'altro approccio non tocca mai la tabella di routing. Il client contrassegna o protegge il socket che trasporta il tunnel, così il sistema operativo invia il traffico di quel socket fuori dal tunnel per politica. Android espone il meccanismo direttamente alle applicazioni VPN. I client desktop implementano equivalenti con contrassegni del firewall o chiamate di associazione al dispositivo.

Il vantaggio è che l'eccezione segue la connessione invece di un gateway salvato. Un cambio di rete riscrive il percorso sottostante, e il socket protetto si sposta con esso perché non è mai stato fissato a un indirizzo. La tabella di routing resta pulita.

Il costo è la visibilità. Nulla nella tabella di routing mostra l'eccezione, quindi un revisore che cerca una rotta host non trova nulla e può concludere che il progetto non sia sicuro. La protezione vive nel codice del client e nelle regole di politica che quel codice installa.

Scegliere tra i due

Scegliete il meccanismo a livello di socket quando il client lo supporta, perché sopravvive ai cambi di rete che rompono una rotta fissata. Scegliete la rotta host quando l'eccezione deve essere visibile ad altri strumenti, o quando il client non offre nulla di meglio.

Nessuno dei due meccanismi elimina la necessità che l'indirizzo del server sia raggiungibile. Un gateway privato ha un indirizzo di ascolto pubblico, ed è quell'indirizzo che deve restare fuori dal tunnel. Le reti interne dietro di esso diventano raggiungibili solo dopo che il tunnel esiste.

Qualunque scegliate, tenetelo con il componente che possiede il tunnel. Una rotta host vagante aggiunta a mano funziona fino alla rete successiva, e poi diventa il misterioso guasto di domani.

Articoli correlati