Ler o DNS de Android correctamente: por rede, non en resolv.conf
A túa app de Android resolve mediante un resolvedor por rede, non mediante o resolv.conf que acabas de ler. Inspecciona primeiro LinkProperties, as ligazóns de socket e o DNS privado.
Obtés unha shell no dispositivo, les /etc/resolv.conf ou desenterras un valor antigo de net.dns1, e obtés un enderezo. A app que tes diante resolve por algo completamente distinto. Nunha versión actual de Android o resolvedor é por rede: o sistema mantén unha política para cada Network e aplícaa ao socket que fixo a petición. O ficheiro e a propiedade heredada son restos, e ningún dos dous describe o camiño que realmente seguiu a túa consulta.
Esa fenda aparece durante os despregamentos de split tunnel e DNS privado, onde dúas apps do mesmo teléfono poden ver respostas distintas de forma lexítima. Este percorrido comeza na consulta errónea ou ausente e retrocede ata a configuración á que pertence.
A resolución de nomes pertence a unha rede, non ao dispositivo
A resolución de nomes en Android 9 e posteriores pasa por un resolvedor do sistema que se basea na Network á que está vinculado un socket. Cada rede leva as súas propias LinkProperties, e esas propiedades conteñen a lista de servidores DNS, os dominios de busca e o estado do DNS privado só para esa rede. Nada dese modelo se corresponde cunha lista única para todo o dispositivo que poidas ler dun ficheiro.
Unha VPN fai obvia a separación. Cando sobe o túnel, a app de VPN fornece servidores DNS rexistrados na rede propia da VPN, así que as apps encamiñadas por ela resolven contra eses servidores mentres as apps excluídas seguen usando a rede subxacente. Un dispositivo, dous camiños de resposta, ningunha contradición.
Ler a instantánea desde dentro da app afectada
Pregúntalle á propia app. Un método que teña un Context e o permiso normal android.permission.ACCESS_NETWORK_STATE pode ler a instantánea sen tocar propiedades do sistema:
val cm = getSystemService(ConnectivityManager::class.java) ?: return
val network = cm.activeNetwork
val links = network?.let { cm.getLinkProperties(it) }
val dnsServers = links?.dnsServers
val privateDnsActive = links?.isPrivateDnsActive
val privateDnsName = links?.privateDnsServerNameactiveNetwork é a rede predeterminada do teu proceso, non a única do dispositivo, e pode ser null cando o chamador non ten unha predeterminada utilizábel. Unha VPN predeterminada bloqueada é a razón habitual. isPrivateDnsActive diche se as consultas nesa rede van por TLS a un resolvedor con nome, o que cambia o que mostrará unha sonda UDP 53 simple. A superficie de API está documentada en LinkProperties, e cada valor que contén é unha instantánea de configuración, non a proba de que unha consulta concreta chegara a un servidor concreto.
Cando a rede predeterminada non é a que traballa
A instantánea só responde pola rede predeterminada. Unha app pode vincular o seu proceso ou un só socket a outra rede, e entón a consulta segue esa escolla mentres o teu diagnóstico segue informando da predeterminada. Un navegador que trae o seu propio resolvedor DNS-over-HTTPS nunca consulta a lista do sistema, así que as súas respostas non din nada do resto do dispositivo. Unha app de perfil de traballo execútase baixo un usuario á parte coa súa propia política. Comproba a ligazón antes de culpar os servidores.
A integración con VPN é a outra metade. Recibir unha liña dhcp-option DNS nun perfil de OpenVPN e rexistrar ese enderezo na rede VPN de Android son dous pasos distintos, e unha ruta ausente cara ao servidor falla coa mesma discreción que un enderezo equivocado. Desde unha máquina de desenvolvemento, adb shell dumpsys connectivity imprime as mesmas propiedades de ligazón por rede cando a compilación o permite, o que confirma a lista sen escribir código.
Comparar a configuración cunha consulta que poidas facer
Escolle un nome que deba resolverse dentro do espazo privado e outro público, e anota ambos os resultados xunto á instantánea: rede, servidores configurados, estado do DNS privado e o texto exacto do erro. Unha consulta directa a un servidor con nome demostra que ese servidor che responde; non demostra que a resolución normal da aplicación o escollera. Unha resposta en caché non é unha proba nova, así que baleira a caché ou usa un nome que ninguén consultase hoxe.
Se o resolvedor só atende clientes dunha rede de acceso concreta, o que ve tras a saída da VPN pode decidir o resultado, e iso é unha cuestión de política para quen o opera e non a proba de que os operadores bloqueen o UDP 53. Onde o DNS privado está activo, un nome de host sen cualificar pode rexeitarse por deseño mentres o mesmo servidor responde con normalidade a nomes públicos. Ler as propiedades diche que modo está vixente, así deixas de adiviñar filtros de paquetes.
Corrixir a capa á que pertence a discrepancia
Traballa cara arriba no canto de editar o estado global. Se a app está vinculada á rede equivocada, corrixe a ligazón. Se o perfil trae a opción DNS equivocada, corrixe o perfil. Se o DNS privado é estrito nunha rede cuxo resolvedor non pode servir a túa zona privada, iso é unha decisión de xestión do dispositivo e non unha razón para desactivar a función en todas partes.
Forzar resolvedores públicos nun hook de DHCP ou nunha propiedade do sistema é a reparación que non deixa de causar incidentes: os nomes privados deixan de resolverse, o cambio sobrevive á sesión de VPN e a seguinte persoa no dispositivo atopa un enderezo obsoleto sen dono. Mantén o cambio dentro da VPN, da app ou da capa de xestión á que pertence a discrepancia, e despois volve ler a instantánea para confirmar que a lista de servidores cambiou de verdade.
O que queres ao final é unha petición de app ligada a unha rede, unha lista de resolvedores e un estado de DNS privado. Unha vez que poidas mostrar esa cadea, un enderezo coñecido nun ficheiro deixa de ser proba de nada.