O teu portátil está na VPN, dig service.internal.example responde cun enderezo 10.x e curl aínda sae con Could not resolve host. O túnel non é o problema: transportou a consulta de dig sen queixarse. O que cambia é quen fai a pregunta. dig envía unha consulta a un servidor que ti nomeas, mentres que curl pasa pola cadea de resolución do sistema operativo, e esa cadea ten as súas propias regras sobre a que servidor se pregunta.

Dúas resolucións para o mesmo nome

dig é un stub resolver propio. Le /etc/resolv.conf, escolle un servidor de nomes, envía unha única consulta A ou AAAA e imprime a resposta. Salta nsswitch por completo e non sabe nada do estado por ligazón que systemd-resolved ou NetworkManager manteñen fóra dese ficheiro, e por iso unha resposta de dig pode ser correcta e non dicirche nada sobre o que verá a túa aplicación.

As aplicacións chaman getaddrinfo, e getaddrinfo percorre unha cadea máis longa: a orde de módulos de nsswitch, despois o módulo que trata o nome e logo o resolver construído a partir da configuración de ligazón actual. Nunha máquina con systemd a consulta vai a 127.0.0.53 e systemd-resolved escolle un servidor upstream por ligazón segundo o dominio de encamiñamento asociado á interface tun.

Dous comandos separan esas capas sen adiviñar:

getent ahosts service.internal.example
resolvectl query service.internal.example

getent usa o mesmo camiño que curl, así que un fallo de getent xunto a un dig que funciona localiza a avaría na política de resolución e non no encamiñamento de paquetes. resolvectl query tamén imprime a interface e o upstream que deu a resposta, o que mostra se a ligazón do túnel ou a ligazón física gañou a decisión.

Le o resolver que a aplicación usa de verdade

/etc/resolv.conf xérase na maioría dos escritorios, e un cliente VPN ten tres xeitos de interactuar con el: antepor un servidor de nomes, sobrescribir o ficheiro ou entregar os seus servidores a NetworkManager e deixar que o daemon o reescriba. Só o terceiro patrón conserva o DNS por ligazón, porque os servidores quedan ligados a unha interface en vez de aplanarse nunha lista global.

En sistemas NetworkManager o resultado depende do backend en /etc/NetworkManager/NetworkManager.conf:

[main]
dns=systemd-resolved

Con dns=default os servidores do cliente fusiónanse en resolv.conf na orde que gañe, e unha consulta privada aínda pode ir ao resolver público. Cun backend que entende as ligazóns, systemd-resolved ou dnsmasq, os servidores do túnel quedan limitados ao túnel e só van alí os nomes que coinciden co seu dominio de encamiñamento. Esa limitación é o que significa split DNS na práctica, e é a peza que máis a miúdo falta cando un cliente di que o admite.

Le o estado antes de editar nada:

resolvectl status
resolvectl dns tun0

Queres ver a interface tun listada cun servidor DNS e un dominio de encamiñamento para o sufixo privado, mostrado como ~internal.example. Ningún servidor na ligazón significa que o cliente non enviou nada. Un servidor sen dominio significa que as consultas van todas alí ou ningunha, segundo o cliente, e ningunha das dúas cousas é split DNS.

Onde nsswitch detén a resolución demasiado cedo

Unha liña estándar de escritorio vese así:

hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns myhostname

mdns4_minimal xestiona o DNS multicast e reclama calquera nome que remate en .local. Un servizo de Kubernetes como api.infra.svc.cluster.local tamén remata en .local. Cando o módulo mDNS informa NOTFOUND, a acción [NOTFOUND=return] remata toda a resolución en vez de continuar cara ao módulo dns, así que o nome nunca se envía ao resolver da VPN. dig evita o ficheiro por completo, e é exactamente por iso que as dúas ferramentas non coinciden.

Este é o contraste máis nítido deste problema, e redúcese a unha palabra nun ficheiro de configuración máis antigo que a túa VPN. Cambiar a acción a [NOTFOUND=continue] conserva mDNS para impresoras e dispositivos locais mentres deixa que DNS vexa o nome. Substituír a liña por hosts: files dns tamén funciona e é máis groso: elimina a resolución .local para a impresora que realmente usas.

Nomes que viven nunha soa rede

As zonas privadas só son autoritativas nun lugar. Un nome de AWS como ip-10-0-4-31.eu-west-1.compute.internal respóndese a través do resolver da VPC daquela rexión, e só mentres o teu punto final de VPN estea na mesma rexión que o recurso. Conecta cun punto final de Frankfurt, consulta un nome compute.internal de Irlanda, e ningunha configuración local axudará: a zona que garda o rexistro non é alcanzable desde alí.

Os dominios de busca producen a imaxe inversa. Un service espido complétase co sufixo que o resolver considera aplicable, e cunha ligazón VPN o dominio local pode gañar o corporativo. Consulta cun punto final para quitar a adiviñanza, getent ahosts service.internal.example., e se iso funciona mentres o nome curto falla, a corrección é o dominio de busca no túnel, non o enderezo do servidor.

Os clientes xestionados engaden unha terceira capa por riba do resolver do sistema. Un perfil de VPN de Windows pode levar a súa propia política de resolución de nomes, regras por aplicación e unha táboa NRPT que se aplica mesmo co túnel parado. As aplicacións con caché DNS propia, habituais nos runtimes .NET e Java, manteñen un fallo obsoleto moito despois de arranxar a cadea. Os clientes de Apple configuran split DNS mediante dominios de coincidencia nos axustes de DNS en vez de resolv.conf, e Chromium ou Firefox en modo DNS seguro poden saltar o resolver do sistema para nomes públicos. A referencia de Microsoft sobre resolución de nomes de VPN describe o lado Windows desa capa de política.

Decide que capa arranxar

Traballa do síntoma á capa en vez de probar correccións en orde:

SymptomWhat it meansCheck first
dig answers, getent failslookup chain, not the packet pathnsswitch line and resolvectl status
Timeout rather than NXDOMAINprivate resolver unreachable through the tunnelresolvectl dns tun0, route to that address
NXDOMAINan authority answered and does not know the namezone owner, endpoint region
FQDN works, short name failssearch suffix mismatchresolvectl domain on the tun link
getent works, app failsapp cache or its own resolverrestart the app, check secure DNS

Dúas filas levan case todo o peso. Un tempo de espera é un problema de alcanzabilidade: o resolver privado non responde a través do túnel, así que comproba a ruta ata o seu enderezo e se o servidor DNS da ligazón é o que pensas. NXDOMAIN é un problema de autoridade: algo respondeu e non coñece o nome, o que apunta á zona, á rexión ou a un resolver que nunca debería recibir a consulta.

A última fila é a que a xente pasa por alto porque as dúas metades parecen un éxito. Un nome curto que se resolve distinto do FQDN é un desaxuste de sufixo, e reconectar o túnel non cambiará que sufixo envía o cliente.

Captura o estado antes de editar un ficheiro de configuración, para que poidas dicir se a edición fixo algo:

resolvectl status > before.txt
getent ahosts service.internal.example >> before.txt

Executa as comprobacións nesta orde e detente na primeira que falle. getent e resolvectl query deben coincidir; se getent falla mentres dig responde, queda na cadea de resolución e non toques o encamiñamento. resolvectl status debe mostrar un servidor DNS e un dominio de encamiñamento na interface tun. nsswitch non debe volver cedo con NOTFOUND para o sufixo que estás probando. O nome debe ser autoritativo na rede á que está conectado o teu punto final, probado cun punto final. A aplicación non debe gardar a súa propia caché nin unha anulación de DNS seguro.

Arranxa só a primeira capa que falla e despois volve executar os mesmos comandos. Dous cambios á vez déixanche sen poder dicir cal contou, e a seguinte avaría comeza a investigación desde cero.

Artigos relacionados