Kvifor interne vertsnamn blir løyste med dig, men feilar med curl på ein VPN
dig svarar, men curl rapporterer at han ikkje kan løyse verten. Samanlikn dei to oppslagskjedene, og rett deretter nsswitch, DNS per lenke eller eit feil søkjesuffiks.
Den berbare maskinen din er på VPN, dig service.internal.example svarar med ein 10.x-adresse, og curl endar framleis med Could not resolve host. Tunnelen er ikkje problemet: han frakta dig-spørjinga utan klager. Det som skil, er kven som stiller spørsmålet. dig sender éi spørjing til éin tenar som du namngir, medan curl går gjennom oppslagskjeda til operativsystemet, og den kjeda har sine eigne reglar for kva tenar som blir spurd.
To oppslag for same namnet
dig er sin eigen stub resolver. Han les /etc/resolv.conf, vel ein namnetenar, sender éi A- eller AAAA-spørjing og skriv ut svaret. Han hoppar heilt over nsswitch og veit ingenting om tilstanden per lenke som systemd-resolved eller NetworkManager held utanfor den fila, og difor kan eit dig-svar vere rett og likevel ikkje seie deg noko om kva programmet ditt vil sjå.
Program kallar på getaddrinfo, og getaddrinfo går gjennom ei lengre kjede: rekkjefølgja av modular i nsswitch, så modulen som handsamar namnet, og til slutt resolveren som er bygd frå den gjeldande lenkekonfigurasjonen. På ein systemd-maskin går spørjinga til 127.0.0.53, og systemd-resolved vel ein oppstraums tenar per lenke ut frå rutingsdomenet som er knytt til tun-grensesnittet.
To kommandoar skil desse laga utan å gjete:
getent ahosts service.internal.example
resolvectl query service.internal.example
getent nyttar same vegen som curl, så ein getent-feil ved sida av ein fungerande dig lokaliserer feilen i oppslagspolitikken og ikkje i pakkerutinga. resolvectl query skriv òg ut grensesnittet og oppstraums tenaren som gav svaret, noko som viser om tunnellenka eller den fysiske lenka vann avgjerda.
Les resolveren som programmet faktisk nyttar
/etc/resolv.conf blir generert på dei fleste skrivebord, og ein VPN-klient har tre måtar å handsame han på: setje ein namnetenar først, skrive over fila eller overlate tenarane sine til NetworkManager og la daemonen skrive ho på nytt. Berre det tredje mønsteret held på DNS per lenke, fordi tenarane blir verande knytte til eit grensesnitt i staden for å bli flata ut til éi global liste.
På NetworkManager-system er resultatet avhengig av backend i /etc/NetworkManager/NetworkManager.conf:
[main]
dns=systemd-resolved
Med dns=default blir tenarane til klienten slegne saman i resolv.conf i den rekkjefølgja som vinn, og eit privat oppslag kan framleis bli sendt til den offentlege resolveren. Med ein backend som forstår lenker, systemd-resolved eller dnsmasq, blir tenarane til tunnelen verande avgrensa til tunnelen, og berre namn som svarar til rutingsdomenet hans går dit. Den avgrensinga er det split DNS tyder i praksis, og det er den delen som oftast manglar når ein klient hevdar at han støttar det.
Les tilstanden før du endrar noko:
resolvectl status
resolvectl dns tun0
Du vil sjå tun-grensesnittet lista med ein DNS-tenar og eit rutingsdomene for det private suffikset, vist som ~internal.example. Ingen tenar på lenka tyder at klienten ikkje sende noko. Ein tenar utan domene tyder at oppslaga anten alle går dit eller ingen, avhengig av klienten, og ingen av delane er split DNS.
Der nsswitch avsluttar oppslaget for tidleg
Ei vanleg skrivebordslinje ser slik ut:
hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns myhostname
mdns4_minimal handsamar multicast DNS og gjer krav på kvart namn som endar på .local. Ein Kubernetes-teneste som api.infra.svc.cluster.local endar òg på .local. Når mDNS-modulen melder NOTFOUND, avsluttar handlinga [NOTFOUND=return] heile oppslaget i staden for å halde fram til dns-modulen, så namnet blir aldri sendt til VPN-resolveren. dig går heilt utanom fila, og nettopp difor er dei to verktya ikkje samde.
Det er den skarpaste kontrasten i denne problema, og han kjem ned til eitt ord i ei konfigurasjonsfil som er eldre enn VPN-en din. Å endre handlinga til [NOTFOUND=continue] held på mDNS for skrivarar og lokale einingar medan DNS kan sjå namnet. Å byta ut linja med hosts: files dns fungerer òg og er grovare: det droppar .local-oppslaget for skrivaren du faktisk nyttar.
Namn som berre finst i eitt nett
Private soner er autoritative på nøyaktig éin stad. Eit AWS-namn som ip-10-0-4-31.eu-west-1.compute.internal blir svart på gjennom VPC-resolveren i den regionen, og berre så lenge VPN-endepunktet ditt er i same regionen som ressursen. Kople til eit endepunkt i Frankfurt, spør etter eit compute.internal-namn frå Irland, og ingen lokal innstilling vil hjelpe: sona som held posten, er ikkje tilgjengeleg derifrå.
Søkjedomene gir spegelbiletet. Eit bert service blir fylt ut med suffikset som resolveren meiner gjeld, og med ei VPN-lenke kan det lokale domenet vinne over det bedriftsinterne. Spør med eit punktum til slutt for å fjerne gjettinga, getent ahosts service.internal.example., og om det verkar medan det korte namnet feilar, er rettinga søkjedomenet på tunnelen, ikkje tenaradressa.
Styrte klientar legg eit tredje lag over resolveren til systemet. Ein Windows VPN-profil kan bera si eiga namneløysingspolitikk, reglar per program og ein NRPT-tabell som gjeld sjølv når tunnelen er nede. Program med eigen DNS-cache, vanlege i .NET- og Java-miljø, held på ein forelda feil lenge etter at kjeda er retta. Apple-klientar set opp split DNS gjennom samsvarande domene i DNS-innstillingane i staden for gjennom resolv.conf, og Chromium eller Firefox i trygg-DNS-modus kan gå utanom resolveren til systemet for offentlege namn. Referansen frå Microsoft om VPN-namneløysing skildrar Windows-sida av det politikk laget.
Avgjer kva lag som skal rettast
Arbeid frå symptomet til laget i staden for å prøve rettingar i rekkjefølgje:
| 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 |
To linjer ber det meste av vekta. Tidsavbrot er eit tilgjengeproblem: den private resolveren svarar ikkje gjennom tunnelen, så sjekk ruta til adressa hans og om DNS-tenaren på lenka er den du trur. NXDOMAIN er eit autoritetsproblem: noko svara, og det kjenner ikkje namnet, noko som peikar på sona, regionen eller ein resolver som aldri skulle ha motteke spørjinga.
Den siste linja er den folk hoppar over fordi båe halvdelane ser ut som suksess. Eit kort namn som blir løyst annleis enn FQDN, er eit suffiksmisforhold, og å kople til tunnelen på nytt vil ikkje endre kva suffiks klienten sender.
Ta vare på tilstanden før du redigerer ei konfigurasjonsfil, så du kan seie om endringa gjorde noko:
resolvectl status > before.txt
getent ahosts service.internal.example >> before.txt
Køyr kontrollane i denne rekkjefølgja og stopp ved den første som feilar. getent og resolvectl query må stemme; om getent feilar medan dig svarar, hald deg i oppslagskjeda og rør ikkje rutinga. resolvectl status må vise ein DNS-tenar og eit rutingsdomene på tun-grensesnittet. nsswitch må ikkje kome for tidleg tilbake med NOTFOUND for suffikset du testar. Namnet må vere autoritativt i nettet som endepunktet ditt er knytt til, testa med eit punktum til slutt. Programmet må ikkje halde eigen cache eller ei overstyring av trygg DNS.
Rett berre det første laget som feilar, og køyr deretter dei same kommandoane på nytt. To endringar samstundes gjer det umogleg å seie kva som mona, og neste bryt byrjar granskinga frå null.