Il traffico passa davvero per la VPN? Come verificarlo
La ricerca della rotta, il primo hop, una cattura sull'adattatore fisico e un controllo dell'indirizzo dall'esterno rispondono a parti diverse della domanda.
Due guasti sembrano identici dall'icona nella barra delle applicazioni: il traffico che entra nel tunnel e quello che lo aggira in silenzio. Il client mostra Connected in entrambi i casi, perché Connected significa solo che l'interfaccia del tunnel esiste e che il client ha installato le rotte che voleva. Se un pacchetto di un'applicazione abbia usato quelle rotte è una domanda separata, a cui si risponde altrove nello stack. Quattro misure risolvono la maggior parte — la ricerca della rotta, il primo hop, una cattura sull'adattatore fisico e un'osservazione dall'esterno — e la vista di sessione sul server copre il resto.
Iniziate dalla rotta che prenderà il pacchetto
La tabella di routing è la decisione, quindi chiedetela su una sola destinazione invece di leggerla tutta e tirare a indovinare. Su Linux, ip route get indica l'interfaccia e l'indirizzo di origine scelti dal kernel:
ip route get 203.0.113.10
ip route get 10.20.5.7Su Windows, Find-NetRoute -RemoteIPAddress 203.0.113.10 è più utile di route print -4 per lo stesso motivo: riporta la rotta che ha vinto, non tutte quelle che esistono. Leggete comunque la tabella una volta per la sua riga 0.0.0.0. Una coppia /1 lì significa che un client a tunnel completo ha riscritto la rotta predefinita: l'opzione redirect-gateway def1 di OpenVPN installa 0.0.0.0/1 e 128.0.0.0/1 attraverso il tunnel, che batte la 0.0.0.0/0 esistente sulla corrispondenza di prefisso più lunga senza cancellare la rotta predefinita fisica. Per questo due rotte predefinite possono convivere mentre tutto continua a entrare nel tunnel.
Due dettagli rendono la tabella bugiarda. Primo, guardate il prefisso che ha corrisposto e non il numero di rotte predefinite, perché una metrica di interfaccia o una coppia /1 decidono il vincitore. Secondo, una connessione già esistente conserva il percorso con cui è stata stabilita; dopo l'aumento del tunnel, una sessione aperta può continuare a usare la vecchia rotta finché non viene reimpostata, ed è per questo che riconnettersi sembra risolvere un problema di routing. Un client in esecuzione — ps ax | grep openvpn — prova solo che il processo è partito.
Tracciate un nome interno e un nome pubblico
La ricerca della rotta mostra l'intenzione; il percorso mostra la consegna. Tracciate un nome che deve essere interno e uno che non deve esserlo, mentre siete connessi, e confrontate il primo hop:
traceroute intranet.corp.example
traceroute 1.1.1.1Lo stesso primo hop per entrambi significa che il nome interno non è mai entrato nel tunnel e il guasto sta sopra, di solito un nome che risolve in un indirizzo pubblico o una rotta che non è mai stata installata. Se il traffico interno esce da 10.8.0.1 mentre quello pubblico esce da 192.168.1.1, il tunnel diviso fa esattamente ciò per cui è stato configurato. Un tracciato che raggiunge il gateway VPN e poi restituisce solo timeout è di solito un problema di percorso di ritorno o del firewall del server, non una rotta di inoltro mancante.
Un ICMP filtrato rende bugiardo questo controllo: stelle su entrambi i tracciati sembrano un tunnel morto e di solito sono un firewall. Provate una porta TCP dove potete — traceroute -T -p 443 su Linux — e ricordate che il tracciato non dice quale resolver ha risposto: un nome può risolversi localmente ed essere comunque raggiungibile attraverso il tunnel.
Catturate sull'adattatore fisico, non sul tunnel
Il collegamento fisico è l'unico posto che mostra ciò che la rete vede davvero. Con il tunnel attivo, una sessione verso l'ufficio dovrebbe apparire come carico cifrato indirizzato al server VPN, non come una connessione a 10.20.5.7:
sudo tcpdump -ni eth0 udp port 53
sudo tcpdump -ni eth0 host 10.20.0.5Il primo filtro cattura la risoluzione dei nomi che esce localmente, che è la fuga più comune e la più silenziosa — la pagina si carica lo stesso, il resolver ha solo visto la query. Il secondo cattura il traffico semplice verso un indirizzo interno che dovrebbe esistere solo dentro il tunnel. Su Windows, pktmon fa lo stesso lavoro senza driver: pktmon filter add -p 53, poi pktmon start --capture --pkt-size 128, poi pktmon stop e pktmon format pktmon.etl -o capture.txt. Questi flag variano un po' tra le build di Windows, quindi controllate pktmon filter add /? prima di fidarvi della sintassi.
Catturate l'interfaccia fisica per trovare le fughe; una cattura sul tunnel contiene i pacchetti che già credete presenti, e su un server contiene pacchetti esterni illeggibili la cui origine è il gateway. I contatori di byte su qualsiasi interfaccia descrivono pacchetti, non programmi; attribuire traffico a un processo richiede un monitor che associ socket e processi.
Chiedete a un servizio esterno, poi richiedetelo per ogni applicazione
L'unico controllo che prova l'uscita è una risposta dall'esterno: un servizio che restituisce l'indirizzo di origine che ha visto. Eseguitelo da una shell, dove potete scegliere l'interfaccia, ed eseguitelo due volte:
sudo curl --interface tun0 https://example.net/ip
sudo curl --interface eth0 https://example.net/ipRisposte diverse vi danno la prova di entrambi i percorsi e un modo per testare un'applicazione specifica: vincolatela, oppure eseguitela in uno spazio dei nomi di rete con una sola rotta, e vedete quale indirizzo registra l'estremità remota. Risposte identiche sono il guasto interessante: o il vincolo non ha avuto effetto, o qualcosa tra l'host e l'estremità remota riscrive l'indirizzo di origine prima che arrivi. Su Windows, curl --interface vuole l'indirizzo dell'adattatore e non il suo nome.
Un browser che riporta l'indirizzo della VPN prova il browser. Un client di posta, un gestore di pacchetti, un agente di backup o un secondo profilo del browser possono ciascuno prendere un percorso diverso, soprattutto quando un'impostazione proxy o una rotta di tunnel diviso ne copre uno. Un cambio di indirizzo non è prova di fuga di per sé: un bilanciatore può rispondere diversamente secondo l'uscita che ha visto, quindi confrontate l'indirizzo di origine registrato, non la pagina.
Usate la vista del server per confermare il peer
Il server risponde a un'altra domanda: se un peer è connesso, quanto ha trasportato e se la sessione si è riavviata. Un peer attivo sul server mentre i contatori del client si muovono appena significa che il traffico dell'applicazione non entra nel tunnel, qualunque cosa dica la tabella del client. Un peer che muove molti dati per un utente che riferisce che nulla funziona è un'altra indagine.
Qui si nascondono due trappole. Un tunnel mascherato fa apparire ogni flusso come proveniente dal gateway, così i log e la contabilità per client collassano su un solo indirizzo. E un client è trattato come host locale, quindi la domanda se qualcuno copi file attraverso la VPN trova risposta nel traffico di condivisione file sul server o nell'audit dell'host sul server — osservare il tunnel dà estremi e volume, non nomi di file.
Distinguete una decisione di progetto da una fuga
Non tutto ciò che sta fuori dal tunnel è una fuga. Il traffico link-local e broadcast resta locale per progetto, una stampante trovata via multicast continua ad annunciarsi sulla LAN, e DHCP deve uscire localmente. Un'applicazione vincolata a un'interfaccia specifica aggira di proposito la tabella di routing, e solo una regola del firewall, uno spazio dei nomi o una rotta di policy lo cambiano.
IPv6 merita una riga propria nella lista di controllo. Un tunnel che trasporta solo IPv4 lascia un host dual-stack con un secondo percorso utilizzabile, e una destinazione dual-stack lo preferirà — incluso il DNS, se il resolver è raggiungibile via IPv6. Disattivate IPv6 sull'adattatore o confermate che il tunnel lo trasporta prima di considerare completo un risultato IPv4.
Quando i controlli non concordano, la discordanza di solito nomina il guasto:
| What you see | What it means | Next step |
|---|---|---|
| The route picks tun0 but the capture shows cleartext to 10.20.5.7 | Something bypassed the table: a bound app, a policy route or a session older than the tunnel | Reset the flow, check the app bind, check the ip rule list |
| The route picks eth0 for an internal name | The name resolves to a public address, or the route was never installed | Compare the resolved address with the routes the server pushes |
| The capture shows DNS to the LAN resolver | Resolver leak: data is tunneled, lookups are not | Point the resolver inside, or push it from the server |
| All four checks agree and one app still fails | Path selection is fine; suspect MTU, a per-app proxy or the far end | Test the same destination from a known-good client |
Un ordine che funziona: salvate la tabella di routing prima e dopo la connessione, tracciate un nome interno e uno pubblico, catturate il DNS sull'adattatore fisico, restituite l'indirizzo di uscita dalla shell per l'applicazione specifica, poi leggete il server per il volume. Se i primi quattro concordano, il tunnel trasporta ciò che pensate e il problema restante sta sopra. Se due di essi discordano, la coppia che discorda è il guasto, non l'icona.