Você obtém um shell no dispositivo, lê /etc/resolv.conf ou desenterra um valor antigo de net.dns1, e recebe um endereço. O app à sua frente resolve por algo totalmente diferente. Em uma versão atual do Android, o resolvedor é por rede: o sistema mantém uma política para cada Network e a aplica ao socket que fez a requisição. O arquivo e a propriedade legada são sobras, e nenhum dos dois descreve o caminho que sua consulta realmente percorreu.

Essa lacuna aparece durante implantações de split tunnel e DNS privado, em que dois apps no mesmo telefone podem legitimamente ver respostas diferentes. Este guia começa na consulta errada ou ausente e volta até a configuração que é dona dela.

O resolvedor pertence a uma rede, não ao dispositivo

A resolução de nomes no Android 9 e posteriores passa por um resolvedor do sistema que se baseia na Network à qual um socket está vinculado. Cada rede carrega suas próprias LinkProperties, e essas propriedades contêm a lista de servidores DNS, os domínios de busca e o estado do DNS privado apenas daquela rede. Nada nesse modelo corresponde a uma lista única do dispositivo que você possa ler de um arquivo.

Uma VPN torna a divisão óbvia. Quando o túnel sobe, o app de VPN fornece servidores DNS registrados na rede própria da VPN, então apps roteados por ela resolvem nesses servidores enquanto apps excluídos continuam usando a rede subjacente. Um dispositivo, dois caminhos de resposta, nenhuma contradição.

Ler o instantâneo de dentro do app afetado

Pergunte ao próprio app. Um método que tenha um Context e a permissão normal android.permission.ACCESS_NETWORK_STATE pode ler o instantâneo sem tocar em propriedades 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?.privateDnsServerName

activeNetwork é a rede padrão do seu processo, não a única do dispositivo, e pode ser null quando o chamador não tem um padrão utilizável. Uma VPN padrão bloqueada é o motivo habitual. isPrivateDnsActive diz se as consultas naquela rede vão por TLS até um resolvedor nomeado, o que muda o que uma sonda UDP 53 simples mostrará. A superfície de API está documentada em LinkProperties, e cada valor nela é um instantâneo da configuração, não prova de que uma consulta específica chegou a um servidor específico.

Quando a rede padrão não é a que faz o trabalho

O instantâneo responde apenas pela rede padrão. Um app pode vincular seu processo ou um único socket a outra rede, e então a consulta segue essa escolha enquanto seu diagnóstico continua relatando a padrão. Um navegador que traz seu próprio resolvedor DNS-over-HTTPS nunca consulta a lista do sistema, então suas respostas não dizem nada sobre o resto do dispositivo. Um app de perfil de trabalho roda sob outro usuário com política própria. Verifique o vínculo antes de culpar os servidores.

A integração de VPN é a outra metade. Receber uma linha dhcp-option DNS em um perfil OpenVPN e registrar esse endereço na rede VPN do Android são dois passos separados, e uma rota ausente até o servidor falha tão silenciosamente quanto um endereço errado. De uma máquina de desenvolvimento, adb shell dumpsys connectivity imprime as mesmas propriedades de link por rede quando a build permite, o que confirma a lista sem escrever código.

Comparar a configuração com uma consulta que você pode fazer

Escolha um nome que precise resolver no espaço privado e um nome público, e anote os dois resultados ao lado do instantâneo: rede, servidores configurados, estado do DNS privado e o texto exato do erro. Uma consulta direta a um servidor nomeado prova que aquele servidor responde a você; não prova que a resolução normal da aplicação o escolheu. Uma resposta em cache não é um teste novo, então limpe o cache ou use um nome que ninguém consultou hoje.

Se o resolvedor só atende clientes de uma rede de acesso específica, o que ele vê após a saída da VPN pode decidir o resultado, e isso é uma questão de política para quem o opera, não evidência de que as operadoras bloqueiam UDP 53. Onde o DNS privado está ativo, um nome de host não qualificado pode ser recusado por projeto enquanto o mesmo servidor responde nomes públicos normalmente. Ler as propriedades diz qual modo está em vigor, então você para de adivinhar filtros de pacotes.

Corrigir a camada que é dona da divergência

Suba em vez de editar o estado global. Se o app está vinculado à rede errada, corrija o vínculo. Se o perfil traz a opção DNS errada, corrija o perfil. Se o DNS privado é estrito em uma rede cujo resolvedor não consegue atender sua zona privada, isso é uma decisão de gestão de dispositivos, não um motivo para desligar o recurso em todos os lugares.

Forçar resolvedores públicos em um gancho DHCP ou em uma propriedade do sistema é o reparo que não para de causar incidentes: nomes privados deixam de resolver, a mudança sobrevive à sessão de VPN, e a próxima pessoa no dispositivo encontra um endereço obsoleto sem dono. Mantenha a mudança dentro da VPN, do app ou da camada de gestão que é dona da divergência, e depois releia o instantâneo para confirmar que a lista de servidores realmente mudou.

O que você quer no fim é uma requisição de app ligada a uma rede, uma lista de resolvedores e um estado de DNS privado. Quando você consegue mostrar essa cadeia, um endereço familiar em um arquivo deixa de ser prova de qualquer coisa.

Artigos relacionados