Emulador de Android y VPN del host: instantánea de DNS y explicación de NAT
El invitado está detrás del NAT del emulador y conserva la lista de DNS copiada al arrancar. Levante el túnel antes del arranque y luego pruebe la resolución desde dentro del invitado.
Cuando el emulador no llega a un servidor de compilación que el navegador del host abre sin problemas, la pregunta útil no es si el VPN funciona. Es cuál de dos mecanismos le falta al invitado. El dispositivo virtual ejecuta su propia pila de red detrás del NAT del emulador, y su lista de resolutores es una copia tomada al arrancar, así que un túnel que subió después cambia la ruta del host sin cambiar lo que pregunta el invitado. Entender esas dos capas explica casi todas las variantes de este problema.
El invitado es una pila aparte detrás de un NAT fijo
La red QEMU en modo usuario sitúa al invitado en 10.0.2.15, la puerta de enlace en 10.0.2.2 y el servicio DNS en 10.0.2.3 hasta 10.0.2.6. El kernel del host no reenvía el tráfico saliente del invitado; lo traduce en sockets del lado del host, uno por conexión del invitado, y esos sockets salen del espacio de direcciones del host. Por eso una conexión del invitado hereda la decisión de enrutamiento del host en el momento de crearse, y por eso el invitado no tiene ninguna entrada en la tabla de rutas que nombre su túnel.
El mismo mecanismo da al invitado una salida útil. 10.0.2.2 es un alias de la interfaz de bucle local del host, así que un servicio que escucha en 127.0.0.1 en el portátil es alcanzable desde el invitado en esa dirección. Todo lo que el cliente expone solo en bucle local se puede alcanzar así, y esa es la base del montaje de proxy descrito más abajo.
Lo que el invitado no puede hacer es observar la red del host como si fuera un espacio de nombres sobre ella. No hay puente, ni tabla de rutas compartida, ni resolutor heredado; solo el servicio NAT que acepta sus paquetes y la instantánea que tomó el lanzador al iniciar el dispositivo virtual.
El DNS es una instantánea, no una vista en vivo
Al arrancar, el emulador lee la lista de resolutores del host y entrega al invitado hasta cuatro servidores, expuestos en las direcciones 10.0.2.3 a 10.0.2.6. Si el túnel estaba caído en ese momento, la instantánea contiene cualquier resolutor público que usara el portátil, y el invitado sigue preguntándole toda su vida. Los nombres públicos se resuelven, los internos fallan, y cada síntoma apunta al VPN cuando el valor obsoleto real es una lista de resolutores capturada minutos antes de que subiera el túnel.
Así que la corrección por orden no es folclore. Conecte primero el túnel, reinicie después el emulador y prefiera un arranque en frío a restaurar una instantánea, porque una imagen de arranque rápido puede volver con el estado de resolutor y rutas que guardó antes. Si necesita ver qué usa el invitado ahora, pregunte al dispositivo y no al host:
adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.exampleEl emulador también acepta un resolutor explícito al arrancar, lo que es útil cuando sabe exactamente qué servidor debe usar el invitado y peligroso cuando ese servidor es público:
emulator -avd Pixel_API_34 -dns-server 203.0.113.53Un resolutor público no tiene copia de una zona interna, así que fijar uno convierte un problema de orden en un fallo permanente. Si el perfil empuja DNS privado, deje que el túnel lo proporcione y arranque el invitado en frío en lugar de codificar una dirección.
El enrutamiento sigue al host en el momento de la conexión
Como las conexiones del invitado se convierten en sockets del host, la decisión de enrutamiento se toma al crear el socket. Un túnel levantado antes de la petición significa que la petición sale por el túnel según las rutas del perfil. Un perfil de túnel dividido que solo lleva prefijos seleccionados dejará su subred privada fuera, así que la alcanzabilidad del host es una hipótesis sobre el invitado, no un resultado. Las conexiones existentes del invitado conservan la ruta con la que se crearon, y por eso un cliente que se reconecta no siempre arregla una descarga atascada dentro del emulador.
La verificación va en la interfaz del host, no en las estadísticas del invitado:
sudo tcpdump -ni tun0 'host 203.0.113.10'Si la petición del invitado aparece en la interfaz del túnel, el enrutamiento funciona y el problema está por encima. Si aparece en la interfaz física, el perfil no cubre ese prefijo, y ninguna reconfiguración en el lado del invitado lo cambiará.
Cuando el cliente solo ofrece un proxy de bucle local
Algunos clientes comerciales no crean ningún túnel de sistema. Exponen un escucha HTTP o SOCKS en 127.0.0.1 y esperan que las aplicaciones lo usen. El invitado no ve ese socket directamente, pero se puede decir al emulador que lo use, ya sea por los controles extendidos (Ajustes, luego Proxy, modo manual, host 127.0.0.1 y el puerto que imprime el cliente) o al arrancar:
emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080Copie el puerto de la ventana del cliente; un puerto adivinado falla en silencio y parece un túnel roto. Tenga en cuenta qué cubre esto: la configuración de proxy HTTP la respetan las aplicaciones conscientes del proxy, y los sockets crudos la ignoran por completo. Si la carga es un binario nativo que abre sus propias conexiones, la ruta por proxy no equivale a un túnel y la comparación debe hacerse de forma explícita.
Demuestre el resultado desde dentro del invitado
Separe resolución de enrutamiento con dos pruebas en la misma sesión. Un nombre que falla mientras la dirección numérica responde es un problema de instantánea de DNS, y la solución es el orden o un resolutor explícito. Si fallan ambos, apunta a enrutamiento o política, y la siguiente comprobación es si la aplicación corre en un perfil de trabajo con sus propias restricciones de red.
Por último, sepa en qué invitado prueba. Imágenes muy antiguas del emulador se distribuyeron sin el soporte tun que necesita un cliente VPN del lado del invitado, así que ningún perfil podía funcionar allí; las imágenes actuales lo incluyen. Un cliente que falla en una imagen actual es un problema de cliente o de perfil, y reconstruir el túnel del host no cambiará el resultado.