Per què els noms d’amfitrió interns es resolen amb dig però fallen amb curl en una VPN
dig respon, però curl informa que no pot resoldre l’amfitrió. Compareu les dues cadenes de resolució i després arregleu nsswitch, el DNS per enllaç o un sufix de cerca incorrecte.
El teu portàtil és a la VPN, dig service.internal.example respon amb una adreça 10.x i curl encara surt amb Could not resolve host. El túnel no és el problema: va transportar la consulta de dig sense queixar-se. El que canvia és qui fa la pregunta. dig envia una consulta a un servidor que tu anomenes, mentre que curl passa per la cadena de resolució del sistema operatiu, i aquesta cadena té les seves pròpies regles sobre a quin servidor es pregunta.
Dues resolucions per al mateix nom
dig és un stub resolver propi. Llegeix /etc/resolv.conf, tria un servidor de noms, envia una única consulta A o AAAA i imprimeix la resposta. S’estalvia del tot nsswitch i no sap res de l’estat per enllaç que systemd-resolved o NetworkManager mantenen fora d’aquest fitxer, i per això una resposta de dig pot ser correcta i no dir-te res del que veurà la teva aplicació.
Les aplicacions criden getaddrinfo, i getaddrinfo recorre una cadena més llarga: l’ordre de mòduls de nsswitch, després el mòdul que tracta el nom i finalment el resolver construït a partir de la configuració d’enllaç actual. En una màquina amb systemd la consulta va a 127.0.0.53 i systemd-resolved tria un servidor upstream per enllaç segons el domini d’encaminament associat a la interfície tun.
Dues ordres separen aquestes capes sense endevinar:
getent ahosts service.internal.example
resolvectl query service.internal.example
getent fa servir el mateix camí que curl, així que un error de getent al costat d’un dig que funciona localitza la fallada en la política de resolució i no en l’encaminament de paquets. resolvectl query també imprimeix la interfície i l’upstream que va donar la resposta, cosa que mostra si l’enllaç del túnel o l’enllaç físic va guanyar la decisió.
Llegeix el resolver que l’aplicació fa servir de debò
/etc/resolv.conf es genera a la majoria d’escriptoris, i un client VPN té tres maneres d’interactuar-hi: anteposar un servidor de noms, sobreescriure el fitxer o lliurar els seus servidors a NetworkManager i deixar que el dimoni el reescrigui. Només el tercer patró conserva el DNS per enllaç, perquè els servidors queden lligats a una interfície en lloc d’aplanar-se en una llista global.
En sistemes NetworkManager el resultat depèn del backend a /etc/NetworkManager/NetworkManager.conf:
[main]
dns=systemd-resolved
Amb dns=default els servidors del client es fusionen a resolv.conf en l’ordre que guanyi, i una consulta privada encara es pot enviar al resolver públic. Amb un backend que entén els enllaços, systemd-resolved o dnsmasq, els servidors del túnel queden limitats al túnel i només hi van els noms que coincideixen amb el seu domini d’encaminament. Aquesta limitació és el que significa split DNS a la pràctica, i és la peça que més sovint falta quan un client diu que ho admet.
Llegeix l’estat abans d’editar res:
resolvectl status
resolvectl dns tun0
Vols veure la interfície tun llistada amb un servidor DNS i un domini d’encaminament per al sufix privat, mostrat com ~internal.example. Cap servidor a l’enllaç significa que el client no ha enviat res. Un servidor sense domini significa que les consultes hi van totes o cap, segons el client, i cap de les dues coses és split DNS.
On nsswitch atura la resolució massa aviat
Una línia estàndard d’escriptori es veu així:
hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns myhostname
mdns4_minimal gestiona el DNS multicast i reclama qualsevol nom que acabi en .local. Un servei de Kubernetes com api.infra.svc.cluster.local també acaba en .local. Quan el mòdul mDNS informa NOTFOUND, l’acció [NOTFOUND=return] acaba tota la resolució en lloc de continuar cap al mòdul dns, així que el nom mai s’envia al resolver de la VPN. dig evita el fitxer del tot, i és exactament per això que les dues eines no coincideixen.
Aquest és el contrast més nítid d’aquest problema, i es redueix a una paraula en un fitxer de configuració més antic que la teva VPN. Canviar l’acció a [NOTFOUND=continue] conserva mDNS per a impressores i dispositius locals mentre deixa que DNS vegi el nom. Substituir la línia per hosts: files dns també funciona i és més groller: elimina la resolució .local per a la impressora que realment fas servir.
Noms que viuen en una sola xarxa
Les zones privades només són autoritàries en un lloc. Un nom d’AWS com ip-10-0-4-31.eu-west-1.compute.internal es respon a través del resolver de la VPC d’aquella regió, i només mentre el teu punt final de VPN sigui a la mateixa regió que el recurs. Connecta amb un punt final de Frankfurt, consulta un nom compute.internal d’Irlanda, i cap configuració local ajudarà: la zona que guarda el registre no és abastable des d’allà.
Els dominis de cerca produeixen la imatge inversa. Un service nu es completa amb el sufix que el resolver considera aplicable, i amb un enllaç VPN el domini local pot guanyar el corporatiu. Consulta amb un punt final per treure l’endevinació, getent ahosts service.internal.example., i si això funciona mentre el nom curt falla, la correcció és el domini de cerca al túnel, no l’adreça del servidor.
Els clients gestionats afegeixen una tercera capa per sobre del resolver del sistema. Un perfil de VPN de Windows pot portar la seva pròpia política de resolució de noms, regles per aplicació i una taula NRPT que s’aplica fins i tot amb el túnel aturat. Les aplicacions amb memòria cau DNS pròpia, habituals en els runtimes .NET i Java, mantenen una fallada obsoleta molt després que la cadena estigui arreglada. Els clients d’Apple configuren split DNS mitjançant dominis de coincidència als ajustos de DNS en lloc de resolv.conf, i Chromium o Firefox en mode DNS segur poden saltar-se el resolver del sistema per a noms públics. La referència de Microsoft sobre resolució de noms de VPN descriu la banda Windows d’aquesta capa de política.
Decideix quina capa cal arreglar
Treballa del símptoma a la capa en lloc de provar correccions en ordre:
| Symptom | What it means | Check first |
|---|---|---|
| dig answers, getent fails | lookup chain, not the packet path | nsswitch line and resolvectl status |
| Timeout rather than NXDOMAIN | private resolver unreachable through the tunnel | resolvectl dns tun0, route to that address |
| NXDOMAIN | an authority answered and does not know the name | zone owner, endpoint region |
| FQDN works, short name fails | search suffix mismatch | resolvectl domain on the tun link |
| getent works, app fails | app cache or its own resolver | restart the app, check secure DNS |
Dues files carreguen gairebé tot el pes. Un temps d’espera és un problema d’abastabilitat: el resolver privat no respon a través del túnel, així que comprova la ruta fins a la seva adreça i si el servidor DNS de l’enllaç és el que creus. NXDOMAIN és un problema d’autoritat: alguna cosa va respondre i no coneix el nom, cosa que apunta a la zona, a la regió o a un resolver que mai no hauria d’haver rebut la consulta.
L’última fila és la que la gent passa per alt perquè les dues meitats semblen un èxit. Un nom curt que es resol diferent del FQDN és un desajust de sufix, i reconnectar el túnel no canviarà quin sufix envia el client.
Captura l’estat abans d’editar un fitxer de configuració, perquè puguis dir si l’edició ha fet res:
resolvectl status > before.txt
getent ahosts service.internal.example >> before.txt
Executa les comprovacions en aquest ordre i atura’t a la primera que falli. getent i resolvectl query han de coincidir; si getent falla mentre dig respon, queda’t a la cadena de resolució i no toquis l’encaminament. resolvectl status ha de mostrar un servidor DNS i un domini d’encaminament a la interfície tun. nsswitch no ha de tornar aviat amb NOTFOUND per al sufix que estàs provant. El nom ha de ser autoritari a la xarxa a la qual està connectat el teu punt final, provat amb un punt final. L’aplicació no ha de guardar la seva pròpia memòria cau ni una anul·lació de DNS segur.
Arregla només la primera capa que falla i torna a executar les mateixes ordres. Dos canvis alhora et deixen sense poder dir quin va comptar, i la propera avaria comença la investigació des de zero.