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:

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

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.

Relaterte artiklar