Come verificare lo stato della VPN senza ping su Android, iOS e Windows
Un ping dimostra solo che un host ha risposto, non che il tunnel sia attivo. Interroga le API di stato di Android, iOS e Windows, poi verifica la rotta che alla tua applicazione serve davvero.
Fare ping a 192.0.2.10 ti dice solo che un indirizzo ha risposto a un echo ICMP, e nient'altro. Su una rete senza tunnel può comunque riuscire, perché l'indirizzo può stare nella sottorete locale; con un tunnel sano può fallire, perché il server scarta ICMP mentre serve HTTPS. Il controllo che serve al tuo script è un'interrogazione dello stato della piattaforma più un test di rotta verso la destinazione che l'applicazione usa. Trattali come due campi separati, mai come un solo booleano.
Che cosa dimostra davvero una risposta echo
ICMP è un protocollo di raggiungibilità che non conosce interfacce né tunnel. Quando arriva una risposta, il kernel segnala che un host ha risposto; non segnala quale rotta ha portato la richiesta né quale ha portato la risposta. Il filtraggio rende il segnale ancora più rumoroso, perché un firewall che blocca le richieste echo non dice nulla sulle porte che ha dietro. E un profilo a tunnel diviso può escludere di proposito l'indirizzo testato mentre ogni altra destinazione funziona.
Quello che vuoi davvero sapere è se un servizio specifico è utilizzabile lungo il percorso che l'app prende. Scegli l'host e la porta che l'app chiama, poi pretendi una risposta a livello applicativo.
Raggiungibilità e stato del tunnel sono fatti diversi, e ciascuno può essere vero mentre l'altro è falso. Tenerli separati ti dice a chi appartiene il guasto. Fonderli in un solo controllo produce un ticket che nessuno può instradare.
Chiedi ad Android il trasporto, non un ping
Android risponde direttamente alla domanda sullo stato tramite ConnectivityManager. Le capacità della rete attiva portano un flag di trasporto VPN, impostato quando il traffico è instradato attraverso un'interfaccia VPN. La chiamata è locale, economica e indipendente dal fatto che un host remoto risponda.
Questa versione Java restituisce false invece di sollevare un'eccezione quando non c'è rete attiva. Poiché legge la rete attiva, riflette il profilo scelto dall'utente nelle Impostazioni.
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActiveNetwork());
boolean tunnel = caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
Per le notifiche di cambiamento registra un NetworkCallback invece di interrogare con un timer. Non confonderlo con VpnService.prepare, che riporta solo se l'utente ha concesso il permesso per una VPN, non se i pacchetti stanno fluendo. La revoca arriva tramite VpnService.onRevoke, ma dimenticare un profilo nelle Impostazioni non produce alcun broadcast.
iOS: i nomi delle interfacce sono un'euristica, non un contratto
Molti frammenti iOS ispezionano le impostazioni del proxy, trovano il dizionario __SCOPED__ e cercano chiavi di interfaccia come tap, tun, utun2, ppp o ipsec. Quell'approccio è una convenzione di denominazione, non una garanzia documentata, quindi un aggiornamento del sistema che rinomina un'interfaccia può romperlo. Tende anche a riportare true per voci obsolete che sopravvivono al tunnel.
Quando è la tua app a possedere la configurazione, NEVPNManager ti dà uno stato reale. Descrive il tunnel avviato dalla tua app; con una VPN per app, altre app possono restare del tutto fuori da quel tunnel.
Ricarica le preferenze prima di leggere lo stato, perché il valore cambia mentre il tunnel sale e scende:
let manager = NEVPNManager.shared()
manager.loadFromPreferences { error in
let up = manager.connection.status == .connected
print(up)
}
Un flag di stato della piattaforma non dimostra comunque che il traffico raggiunga il peer. È proprio quel vuoto che copre il test di rotta, ed è per questo che un solo booleano non basta per il supporto.
I profili Windows espongono un vero campo di stato
Windows tiene traccia dei profili VPN separatamente dagli adattatori, e Get-VpnConnection espone un ConnectionStatus per ogni profilo che conosce. I profili creati tramite il client Windows o un pacchetto di provisioning compaiono qui. Il cmdlet non è un rilevatore generico di tunnel.
Leggi il campo per un profilo con nome, aggiungendo -AllUserConnection quando il profilo appartiene a tutti gli utenti:
Get-VpnConnection -Name "Fabrikam" | Select-Object Name, ConnectionStatus, ServerAddress
I client di terze parti restano spesso invisibili a questo cmdlet anche mentre il loro tunnel è attivo, quindi un risultato vuoto significa sconosciuto, non disconnesso. Gli elenchi di adattatori ingannano altrettanto: un adattatore del fornitore può persistere mentre è inattivo, e alcuni adattatori esistono solo durante una sessione. Per un profilo che Windows possiede, rasdial riporta un codice di uscita su cui puoi diramare. Tutto questo descrive una convinzione locale, non la raggiungibilità del peer.
Stato più rotta: il controllo in due parti
Un profilo connesso non dice nulla su dove vadano i pacchetti. Il tunnel diviso può mantenere il tunnel attivo escludendo la destinazione che ti interessa. I profili always-on restano connessi con un server morto, e un kill switch blocca il traffico di proposito quando il tunnel cade.
Testa entrambi i livelli: conferma che un trasporto VPN o un profilo sia attivo, poi conferma che la destinazione si risolva e risponda lungo quel percorso. Su Linux, chiedi al kernel quale interfaccia userebbe:
ip route get 192.0.2.10
resolvectl query intranet.example.test
Quando il client è fuori dal tuo controllo, registra entrambi i risultati e lascia che lo schema indichi il livello. Connesso più test di rotta fallito suggerisce tunnel diviso, DNS o criterio. Disconnesso più test di rotta funzionante significa che un altro percorso sta portando il traffico.
Un test che puoi eseguire in ordine
Registra prima lo stato della piattaforma, prima di cambiare qualsiasi stato di rete. Risolvi il nome host e annota la famiglia di indirizzi, perché un record AAAA può prendere un percorso diverso da un record A. Apri la porta del servizio ed esigi una risposta applicativa anziché una semplice stretta di mano. Tieni ogni osservazione nel suo campo di log.
Su una macchina Linux con dig e curl, tre comandi coprono risoluzione, rotta e il servizio stesso. Eseguili con il tunnel attivo e di nuovo con il tunnel spento:
dig +short intranet.example.test
ip route get 198.51.100.20
curl -sS -o /dev/null -w "%{http_code}" --max-time 8 https://intranet.example.test/health
Quattro campi separati battono un booleano, perché stato, DNS, rotta e criterio falliscono in modo indipendente e finiscono in team diversi. Un ping da terminale resta un buon controllo manuale. È una pessima definizione di connettività per l'automazione, dove l'API della piattaforma e un test di rotta rispondono alla domanda reale.