Due salti VPN di fila: chi vede davvero il tuo traffico?
I salti in serie decifrano e ricifrano al primo gateway; i salti annidati rimuovono solo lo strato esterno. Percorrete entrambi i progetti e vedete quale operatore legge cosa.
Ogni profilo client nomina un server, quindi dal posto dell’utente c’è un tunnel e un punto in cui la protezione finisce. Ciò che accade dopo quel primo gateway è una decisione di progetto che il client non vede mai, e i due progetti comuni si comportano in modo molto diverso sotto ispezione. In una catena seriale il primo gateway decifra e ricifra. In una catena annidata rimuove uno strato esterno e inoltra un tunnel interno che non può aprire. Il numero di salti è identico in entrambi, per questo la differenza va disegnata e non contata.
Partite dal client e nominate entrambi gli estremi
Partite da dove parte l’utente, nel profilo di connessione. Contiene un indirizzo remoto, un metodo di autenticazione e, quando il progetto lo supporta, un elenco di route. Etichettate quel tunnel esterno dal client al gateway A e dategli indirizzi di esempio: l’indirizzo del tunnel del client 10.77.0.2, quello di A 10.77.0.1 e l’endpoint pubblico di A 198.51.100.10, presi dall’intervallo di documentazione TEST-NET-2 così che nulla nell’esempio possa scontrarsi con un host reale.
Niente in quel profilo menziona il gateway B, e non è un difetto. Il secondo salto appartiene ad A, e l’unico obbligo del client è consegnare il traffico ad A e accettare ciò che torna. Se A termina il tunnel, lo inoltra o ne apre uno nuovo è la domanda a cui risponde il resto di questo percorso, ed è quella che decide cosa A può leggere.
In serie: A decifra, poi ricifra
Nel progetto seriale A termina il traffico due volte. Rimuove la protezione dal client, ottiene il pacchetto IP dell’applicazione e poi invia quel pacchetto attraverso un secondo tunnel che A origina verso B. Tra queste due operazioni il pacchetto si trova nel percorso di inoltro di A come un normale pacchetto IP indirizzato a una destinazione privata.
Ciò produce due conseguenze che vale la pena dire chiaramente. A può applicare una politica al pacchetto interno, sotto forma di route, regole di filtro e registrazione di sorgente e destinazione, e A deve tenere due set di credenziali: uno come server per il client e uno come client di B. La protezione esiste in ogni istante, ma l’oggetto protetto cambia identità presso A.
Da ciò non segue che A legga il testo in chiaro dell’applicazione. Quando il client e il servizio usano TLS e verificano i certificati reciproci, A vede un flusso di record TLS anziché una richiesta leggibile. Confermare dove finisce quella protezione richiede uno sguardo alla catena di certificati del servizio, non al diagramma del tunnel.
Annidato: A rimuove solo lo strato esterno
Nel progetto annidato il client costruisce prima un tunnel interno verso B e poi trasporta quel tunnel dentro quello esterno fino ad A. A rimuove l’intestazione esterna, trova un tunnel interno e lo inoltra senza tenerne le chiavi, quindi la protezione interna termina ancora presso B.
Il collegamento ascendente del client porta allora due strati, mentre il percorso tra A e B ne porta uno. A vede gli indirizzi esterni del tunnel interno, il che basta a sapere che esiste traffico e all’incirca dove è diretto, e non basta a leggere il carico utile. È tutta la differenza rispetto al caso seriale, e nessun contatore di salti la mostra. Ciò che A può ancora fare è rifiutarsi di inoltrare ciò che non può leggere, e questo è sempre disponibile per l’operatore di quel gateway.
L’annidamento si fa pagare questa proprietà. Ogni strato aggiunge sovraccarico di intestazione, quindi la pianificazione di MTU e MSS diventa obbligatoria e non solo ordinata, e un percorso che funziona con uno strato può scartare in silenzio pacchetti grandi con due. Ogni strato ha anche bisogno del proprio comportamento di riconnessione e di keepalive, e un guasto in uno strato appare come un’interruzione parziale attraverso l’altro.
Disegnate gli osservatori, non solo i tunnel
I tunnel sono la parte facile del disegno. Gli osservatori sono l’argomento del progetto, quindi scrivete una riga per punto di osservazione e riempite ciò che ciascuno può davvero leggere.
| Vantage point | Serial chain | Nested chain |
|---|---|---|
| Client's access network | Outer tunnel only | Outer tunnel only |
| Operator of A | Inner IP packet between A and B | Outer addresses of the inner tunnel, not its payload |
| Path between A and B | Second tunnel | Second tunnel |
| Operator of B | Inner packet re-originated by A | Payload after the inner layer is removed |
| Service edge | Traffic from the exit address | Traffic from the exit address |
Due righe vengono continuamente confuse: l’operatore di A e il fornitore del tunnel del client. Possono essere un’unica entità, e nomi di gateway separati non li rendono indipendenti. Una proprietà indipendente richiede controllo amministrativo separato, credenziali separate e registrazione separata.
I metadati sopravvivono a entrambi i progetti. Tempi, dimensioni dei pacchetti e numero di connessioni restano osservabili a ogni salto, quindi due salti alzano il costo della correlazione invece di rimuovere il segnale. Un progetto che promette invisibilità andrebbe confrontato con quell’elenco prima che qualcuno vi si affidi.
Percorrete i percorsi di guasto prima di scegliere
Rompite le cose di proposito dal client, nell’ordine in cui un utente le incontrerebbe. Iniziate dall’interfaccia e dal suo MTU, perché l’annidamento fallisce sulla dimensione dei pacchetti molto prima di fallire sull’autenticazione.
ip -4 addr show dev tun0
ip link show dev tun0 | grep mtu
ping -M do -s 1380 -c 2 10.77.1.1
Poi confermate gli endpoint di protezione invece di darli per scontati. Chiedete al servizio il suo certificato dall’interno del tunnel attivo, e confrontate la catena che il client vede con la catena che il servizio presenta davvero. Un gateway che rifirma o intercetta cambia quel certificato, e l’ispezione diventa visibile con un solo comando.
openssl s_client -connect intranet.example.com:443 -brief < /dev/null
Chiudete con la matrice di riconnessione: cade il tunnel del client, cade il tunnel di B, cambia il percorso tra A e B. Annotate cosa torna e cosa no, e se una connessione interna ricade mai su una route fuori dal suo trasporto previsto. Registrate gli indirizzi usati da ogni test, perché ripeterlo su un’altra rete di accesso risponde a un’altra domanda. Ripetete anche la prova MTU dopo ogni riconnessione, perché un percorso cambiato può abbassare la dimensione utilizzabile senza che si muova una sola riga di configurazione.
Scegliete il seriale quando A deve applicare una politica al pacchetto interno, o quando il client non può eseguire due tunnel impilati. Scegliete l’annidamento quando il carico interno deve restare illeggibile presso A. Scrivete la scelta con i suoi osservatori e i suoi numeri di MTU, e la persona successiva non dovrà ridisegnare l’intero quadro per rispondere a una domanda.