Jūsų nešiojamasis kompiuteris yra VPN tinkle, dig service.internal.example atsako 10.x adresu, o curl vis tiek baigiasi su Could not resolve host. Tunelis nėra problema: jis pernešė dig užklausą be priekaištų. Skiriasi tai, kas užduoda klausimą. dig siunčia vieną užklausą vienam jūsų nurodytam serveriui, o curl eina per operacinės sistemos paieškos grandinę, ir ta grandinė turi savo taisykles, kurio serverio klausiama.

Dvi paieškos tam pačiam vardui

dig yra savas stub resolver. Jis nuskaito /etc/resolv.conf, pasirenka vardų serverį, siunčia vieną A arba AAAA užklausą ir atspausdina atsakymą. Jis visiškai praleidžia nsswitch ir nieko nežino apie ryšio lygmens būseną, kurią systemd-resolved arba NetworkManager laiko už to failo ribų, todėl dig atsakymas gali būti teisingas ir vis tiek nieko nepasakyti apie tai, ką pamatys jūsų programa.

Programos kviečia getaddrinfo, o getaddrinfo eina ilgesne grandine: nsswitch modulių tvarka, tada modulis, kuris apdoroja vardą, ir galiausiai resolver, sukurtas iš dabartinės ryšio konfigūracijos. systemd sistemoje užklausa keliauja į 127.0.0.53, o systemd-resolved pasirenka ryšio lygmens viršutinį serverį pagal maršrutizavimo domeną, priskirtą tun sąsajai.

Dvi komandos atskiria tuos sluoksnius neatspėdamos:

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

getent naudoja tą patį kelią kaip curl, todėl getent klaida šalia veikiančio dig nurodo gedimą paieškos politikoje, o ne paketų maršrutizavime. resolvectl query taip pat atspausdina sąsają ir viršutinį serverį, kuris pateikė atsakymą, o tai parodo, ar sprendimą laimėjo tunelio ryšys, ar fizinis ryšys.

Perskaitykite resolver, kurį programa iš tikrųjų naudoja

/etc/resolv.conf generuojamas daugumoje darbalaukių, o VPN klientas turi tris būdus su juo sąveikauti: pridėti vardų serverį į priekį, perrašyti failą arba perduoti savo serverius NetworkManager ir leisti demonui jį perrašyti. Tik trečiasis modelis išsaugo ryšio lygmens DNS, nes serveriai lieka pririšti prie sąsajos, o ne suplokštinami į vieną globalų sąrašą.

NetworkManager sistemose rezultatas priklauso nuo backend /etc/NetworkManager/NetworkManager.conf faile:

[main]
dns=systemd-resolved

Su dns=default kliento serveriai suliejami į resolv.conf ta tvarka, kuri laimi, ir privati užklausa vis tiek gali būti nusiųsta viešajam resolver. Su backend, kuris supranta ryšius, systemd-resolved arba dnsmasq, tunelio serveriai lieka apriboti tuneliu, ir ten patenka tik jo maršrutizavimo domeną atitinkantys vardai. Šis apribojimas ir yra tai, ką split DNS reiškia praktiškai, ir tai yra dalis, kurios dažniausiai trūksta, kai klientas teigia jį palaikantis.

Perskaitykite būseną prieš ką nors keisdami:

resolvectl status
resolvectl dns tun0

Norite matyti tun sąsają su DNS serveriu ir privataus sufikso maršrutizavimo domenu, rodomą kaip ~internal.example. Jokio serverio ryšyje reiškia, kad klientas nieko neperdavė. Serveris be domeno reiškia, kad užklausos arba visos siunčiamos ten, arba nė viena, priklausomai nuo kliento, ir nė vienas variantas nėra split DNS.

Kur nsswitch baigia paiešką per anksti

Įprasta darbalaukio eilutė atrodo taip:

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

mdns4_minimal tvarko multicast DNS ir pretenduoja į kiekvieną vardą, pasibaigiantį .local. Kubernetes paslauga, pavyzdžiui, api.infra.svc.cluster.local, taip pat baigiasi .local. Kai mDNS modulis praneša NOTFOUND, veiksmas [NOTFOUND=return] baigia visą paiešką, o ne tęsia į dns modulį, todėl vardas niekada nesiunčiamas VPN resolver. dig apeina failą visiškai, ir būtent todėl abu įrankiai nesutaria.

Tai ryškiausias šios problemos kontrastas, ir jis susiveda į vieną žodį konfigūracijos faile, senesniame už jūsų VPN. Pakeitus veiksmą į [NOTFOUND=continue], mDNS išlieka spausdintuvams ir vietiniams įrenginiams, o DNS gali matyti vardą. Eilutės pakeitimas į hosts: files dns taip pat veikia ir yra grubesnis: jis atsisako .local sprendimo spausdintuvui, kurį iš tikrųjų naudojate.

Vardai, gyvenantys tiksliai viename tinkle

Privačios zonos yra autoritetingos tiksliai vienoje vietoje. AWS vardas, pavyzdžiui, ip-10-0-4-31.eu-west-1.compute.internal, atsakomas per to regiono VPC resolver, ir tik tol, kol jūsų VPN galinis taškas yra tame pačiame regione kaip išteklius. Prisijunkite prie Frankfurto galinio taško, užklauskite Airijos compute.internal vardą, ir jokia vietinė nuostata nepadės: zona, laikanti įrašą, iš ten nepasiekiama.

Paieškos domenai sukuria veidrodinį vaizdą. Plikas service papildomas suffixu, kurį resolver laiko taikomu, o su VPN ryšiu vietinis domenas gali įveikti įmonės domeną. Užklauskite su pabaigos tašku, kad pašalintumėte spėliojimą, getent ahosts service.internal.example., ir jei tai veikia, o trumpas vardas nepavyksta, pataisymas yra paieškos domenas tunelyje, o ne serverio adresas.

Valdomi klientai prideda trečią sluoksnį virš sistemos resolver. Windows VPN profilis gali turėti savo vardų sprendimo politiką, taisykles pagal programą ir NRPT lentelę, kuri galioja net tada, kai tunelis išjungtas. Programos su savo DNS podėliu, įprastos .NET ir Java vykdymo aplinkose, ilgai išlaiko pasenusią klaidą po to, kai grandinė sutvarkyta. Apple klientai konfigūruoja split DNS per atitikties domenus DNS nustatymuose, o ne per resolv.conf, o Chromium arba Firefox saugaus DNS režimu gali apeiti sistemos resolver viešiems vardams. Microsoft VPN vardų sprendimo nuoroda aprašo to politikos sluoksnio Windows pusę.

Nuspręskite, kurį sluoksnį taisyti

Eikite nuo simptomo prie sluoksnio, o ne bandykite pataisymus iš eilės:

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

Dvi eilutės neša didžiausią svorį. Skirtasis laikas yra pasiekiamumo problema: privatus resolver neatsako per tunelį, todėl patikrinkite maršrutą į jo adresą ir ar ryšio DNS serveris yra tas, kurį manote. NXDOMAIN yra autoriteto problema: kažkas atsakė ir nežino vardo, o tai nurodo zoną, regioną arba resolver, kuris niekada neturėjo gauti užklausos.

Paskutinė eilutė yra ta, kurią žmonės praleidžia, nes abi pusės atrodo kaip sėkmė. Trumpas vardas, sprendžiamas kitaip nei FQDN, yra sufiksų neatitikimas, o tunelio prijungimas iš naujo nepakeis, kokį sufiksą siunčia klientas.

Užfiksuokite būseną prieš redaguodami konfigūracijos failą, kad galėtumėte pasakyti, ar redagavimas ką nors pakeitė:

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

Vykdykite patikras šia tvarka ir sustokite ties pirmąja, kuri nepavyksta. getent ir resolvectl query turi sutapti; jei getent nepavyksta, o dig atsako, likite paieškos grandinėje ir nelieskite maršrutizavimo. resolvectl status turi rodyti DNS serverį ir maršrutizavimo domeną tun sąsajoje. nsswitch negali grįžti anksti su NOTFOUND testuojamam sufiksui. Vardas turi būti autoritetingas tinkle, prie kurio prijungtas jūsų galinis taškas, patikrintas su pabaigos tašku. Programa neturi laikyti savo podėlio ar saugaus DNS nepaisymo.

Taisykite tik pirmąjį nepavykstantį sluoksnį, tada vėl vykdykite tas pačias komandas. Du pakeitimai iš karto neleidžia pasakyti, kuris turėjo reikšmės, o kitas sutrikimas pradeda tyrimą nuo nulio.

Susiję straipsniai