Cómo comprobar el estado de la VPN sin ping en Android, iOS y Windows
El ping solo demuestra que un host respondió, no que el túnel esté activo. Consulte las API de estado de Android, iOS y Windows y luego verifique la ruta que su aplicación realmente necesita.
Hacer ping a 192.0.2.10 solo le dice que una dirección respondió a un eco ICMP, y nada más. En una red sin túnel puede funcionar igualmente, porque la dirección puede estar en la subred local; con un túnel sano puede fallar, porque el servidor descarta ICMP mientras sirve HTTPS. La comprobación que necesita su script es una consulta de estado de la plataforma más una prueba de ruta hacia el destino que usa la aplicación. Trátelas como dos campos separados, nunca como un solo booleano.
Qué demuestra realmente una respuesta de eco
ICMP es un protocolo de alcanzabilidad que no entiende de interfaces ni de túneles. Cuando llega una respuesta, el núcleo informa de que un host respondió; no informa de qué ruta llevó la petición ni de cuál llevó la respuesta. El filtrado hace la señal aún más ruidosa, porque un cortafuegos que bloquea peticiones de eco no dice nada de los puertos que hay detrás. Y un perfil con túnel dividido puede excluir a propósito la dirección probada mientras todos los demás destinos funcionan.
Lo que realmente quiere saber es si un servicio concreto es utilizable por la ruta que toma la aplicación. Elija el host y el puerto que llama la aplicación y luego exija una respuesta en la capa de aplicación.
La alcanzabilidad y el estado del túnel son hechos distintos, y cualquiera de los dos puede ser cierto mientras el otro es falso. Mantenerlos separados le dice de quién es el fallo. Fundirlos en una sola comprobación produce un ticket que nadie puede encaminar.
Pregunte a Android por el transporte, no por un ping
Android responde a la pregunta de estado directamente mediante ConnectivityManager. Las capacidades de la red activa llevan un indicador de transporte VPN, que se establece cuando el tráfico se enruta por una interfaz VPN. La llamada es local, barata e independiente de que responda algún host remoto.
Esta versión de Java devuelve false en lugar de lanzar una excepción cuando no hay red activa. Como lee la red activa, refleja el perfil que el usuario eligió en Ajustes.
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActiveNetwork());
boolean tunnel = caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
Para las notificaciones de cambio, registre un NetworkCallback en lugar de sondear con un temporizador. No lo confunda con VpnService.prepare, que solo informa de si el usuario concedió permiso para una VPN, no de si fluyen paquetes. La revocación llega por VpnService.onRevoke, pero olvidar un perfil en Ajustes no produce ninguna difusión.
iOS: los nombres de interfaz son una heurística, no un contrato
Muchos fragmentos de iOS inspeccionan los ajustes de proxy, encuentran el diccionario __SCOPED__ y buscan claves de interfaz como tap, tun, utun2, ppp o ipsec. Ese enfoque es una convención de nombres, no una garantía documentada, así que una actualización del sistema que renombre una interfaz puede romperlo. Además tiende a informar cierto para entradas obsoletas que sobreviven al túnel.
Cuando su aplicación es dueña de la configuración, NEVPNManager le da un estado real. Describe el túnel que inició su aplicación; con una VPN por aplicación, otras aplicaciones pueden quedar completamente fuera de ese túnel.
Recargue las preferencias antes de leer el estado, porque el valor cambia a medida que el túnel aparece y desaparece:
let manager = NEVPNManager.shared()
manager.loadFromPreferences { error in
let up = manager.connection.status == .connected
print(up)
}
Un indicador de estado de la plataforma sigue sin demostrar que el tráfico llegue al par. Ese hueco es el que cubre la prueba de ruta, y por eso un solo booleano no basta para soporte.
Los perfiles de Windows exponen un campo de estado real
Windows rastrea los perfiles VPN por separado de los adaptadores, y Get-VpnConnection expone un ConnectionStatus para cada perfil que conoce. Aquí aparecen los perfiles creados con el cliente de Windows o con un paquete de aprovisionamiento. El cmdlet no es un detector general de túneles.
Lea el campo para un perfil con nombre, añadiendo -AllUserConnection cuando el perfil es de todos los usuarios:
Get-VpnConnection -Name "Fabrikam" | Select-Object Name, ConnectionStatus, ServerAddress
Los clientes de terceros suelen quedar invisibles para este cmdlet incluso con su túnel activo, así que un resultado vacío significa desconocido, no desconectado. Los listados de adaptadores engañan igual: un adaptador de fabricante puede persistir mientras está inactivo, y algunos adaptadores solo existen durante una sesión. Para un perfil que Windows posee, rasdial informa de un código de salida sobre el que puede ramificar. Todo esto describe una creencia local, no la alcanzabilidad del par.
Estado más ruta: la comprobación en dos partes
Un perfil conectado no dice nada sobre adónde van los paquetes. El túnel dividido puede mantener el túnel activo mientras excluye el destino que le importa. Los perfiles always-on siguen conectados con un servidor muerto, y un kill switch bloquea el tráfico a propósito cuando el túnel cae.
Pruebe ambas capas: confirme que hay un transporte VPN o un perfil activo y luego que el destino se resuelve y responde por esa ruta. En Linux, pregunte al núcleo qué interfaz usaría:
ip route get 192.0.2.10
resolvectl query intranet.example.test
Cuando el cliente está fuera de su control, registre ambos resultados y deje que el patrón señale la capa. Conectado más una prueba de ruta fallida sugiere túnel dividido, DNS o política. Desconectado más una prueba de ruta correcta significa que otra ruta lleva el tráfico.
Una prueba que puede ejecutar en orden
Registre primero el estado de la plataforma, antes de cambiar cualquier estado de red. Resuelva el nombre de host y anote la familia de direcciones, porque un registro AAAA puede tomar un camino distinto que un registro A. Abra el puerto del servicio y exija una respuesta de aplicación en lugar de un simple handshake. Guarde cada observación en su propio campo de registro.
En una máquina Linux con dig y curl, tres comandos cubren resolución, ruta y el propio servicio. Ejecútelos con el túnel activo y de nuevo con el túnel caído:
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
Cuatro campos separados superan a un solo booleano, porque el estado, el DNS, la ruta y la política fallan de forma independiente y recaen en equipos distintos. Un ping en la terminal sigue siendo una buena comprobación manual. Es una mala definición de conectividad para la automatización, donde la API de la plataforma y una prueba de ruta responden a la pregunta real.