Váš notebook je na VPN, dig service.internal.example odpovídá adresou 10.x a curl stále končí s Could not resolve host. Tunel není problém: přenesl dotaz dig bez stížností. Rozdíl je v tom, kdo klade otázku. dig pošle jeden dotaz jednomu serveru, který určíte vy, zatímco curl prochází vyhledávacím řetězcem operačního systému a ten řetězec má vlastní pravidla o tom, který server se ptá.

Dvě vyhledání pro stejný název

dig je vlastní stub resolver. Přečte /etc/resolv.conf, vybere jmenný server, pošle jeden dotaz A nebo AAAA a vypíše odpověď. nsswitch úplně přeskakuje a neví nic o stavu na spojení, který systemd-resolved nebo NetworkManager drží mimo tento soubor, a proto může být odpověď dig správná a přesto vám nic neřekne o tom, co uvidí vaše aplikace.

Aplikace volají getaddrinfo a getaddrinfo prochází delší řetězec: pořadí modulů nsswitch, potom modul, který zpracovává název, a nakonec resolver sestavený z aktuální konfigurace spojení. Na stroji se systemd jde dotaz na 127.0.0.53 a systemd-resolved vybere nadřazený server pro každé spojení podle směrovací domény přiřazené rozhraní tun.

Dva příkazy oddělují tyto vrstvy bez hádání:

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

getent používá stejnou cestu jako curl, takže selhání getent vedle fungujícího dig lokalizuje chybu ve vyhledávací politice, nikoli ve směrování paketů. resolvectl query vypíše také rozhraní a nadřazený server, který odpověď poskytl, což ukazuje, zda rozhodnutí vyhrálo spojení tunelu nebo fyzické spojení.

Přečtěte si resolver, který aplikace skutečně používá

/etc/resolv.conf se generuje na většině pracovních ploch a klient VPN má tři způsoby interakce s ním: přidat jmenný server na začátek, přepsat soubor nebo předat své servery NetworkManageru a nechat démona ho přepsat. Jen třetí vzor zachovává DNS na spojení, protože servery zůstávají přiřazené k rozhraní místo toho, aby byly zploštěny do jednoho globálního seznamu.

V systémech NetworkManager výsledek závisí na backendu v /etc/NetworkManager/NetworkManager.conf:

[main]
dns=systemd-resolved

S dns=default se servery klienta sloučí do resolv.conf v pořadí, které vyhraje, a soukromý dotaz může být stále odeslán veřejnému resolveru. S backendem, který rozumí spojením, systemd-resolved nebo dnsmasq, zůstanou servery tunelu omezeny na tunel a jdou tam jen názvy odpovídající jeho směrovací doméně. Toto omezení je to, co split DNS znamená v praxi, a je to část, která nejčastěji chybí, když klient tvrdí, že ho podporuje.

Přečtěte si stav, než cokoli změníte:

resolvectl status
resolvectl dns tun0

Chcete vidět rozhraní tun uvedené se serverem DNS a směrovací doménou pro soukromou příponu, zobrazené jako ~internal.example. Žádný server na spojení znamená, že klient nic neposlal. Server bez domény znamená, že dotazy jdou buď všechny tam, nebo žádné, podle klienta, a ani jedno není split DNS.

Kde nsswitch ukončí vyhledávání příliš brzy

Běžný řádek pracovní plochy vypadá takto:

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

mdns4_minimal zpracovává multicast DNS a nárokuje si každý název končící na .local. Služba Kubernetes jako api.infra.svc.cluster.local také končí na .local. Když modul mDNS hlásí NOTFOUND, akce [NOTFOUND=return] ukončí celé vyhledávání místo pokračování do modulu dns, takže název se nikdy neodešle resolveru VPN. dig obchází soubor úplně, a právě proto se oba nástroje neshodují.

To je nejostřejší kontrast v tomto problému a zužuje se na jedno slovo v konfiguračním souboru, který je starší než vaše VPN. Změna akce na [NOTFOUND=continue] zachová mDNS pro tiskárny a lokální zařízení, přičemž DNS může název vidět. Nahrazení řádku s hosts: files dns také funguje a je hrubší: vynechává rozlišení .local pro tiskárnu, kterou skutečně používáte.

Názvy, které žijí přesně v jedné síti

Soukromé zóny jsou autoritativní přesně na jednom místě. Název AWS jako ip-10-0-4-31.eu-west-1.compute.internal se odpovídá přes resolver VPC daného regionu, a to jen dokud je váš koncový bod VPN ve stejném regionu jako zdroj. Připojte se ke koncovému bodu ve Frankfurtu, požádejte o název compute.internal z Irska a žádné lokální nastavení nepomůže: zóna, která drží záznam, odtud není dostupná.

Vyhledávací domény vytvářejí zrcadlový obraz. Holé service se doplní příponou, kterou resolver považuje za platnou, a se spojením VPN může lokální doména porazit firemní. Ptejte se s koncovou tečkou, abyste odstranili hádání, getent ahosts service.internal.example., a pokud to funguje, zatímco krátký název selhává, oprava je vyhledávací doména na tunelu, ne adresa serveru.

Spravovaní klienti přidávají třetí vrstvu nad systémovým resolverem. Profil VPN ve Windows může nést vlastní politiku překladu názvů, pravidla pro jednotlivé aplikace a tabulku NRPT, která platí i tehdy, když je tunel vypnutý. Aplikace s vlastní mezipamětí DNS, běžné v runtime .NET a Java, si drží zastaralé selhání dlouho po opravě řetězce. Klienti Apple konfigurují split DNS přes odpovídající domény v nastavení DNS místo resolv.conf a Chromium nebo Firefox v režimu zabezpečeného DNS mohou obejít systémový resolver pro veřejné názvy. Reference Microsoftu k překladu názvů VPN popisuje stranu Windows této vrstvy politiky.

Rozhodněte, kterou vrstvu opravit

Postupujte od příznaku k vrstvě místo zkoušení oprav v pořadí:

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

Dva řádky nesou většinu váhy. Časový limit je problém dosažitelnosti: soukromý resolver neodpovídá přes tunel, proto zkontrolujte trasu k jeho adrese a zda je server DNS na spojení ten, který si myslíte. NXDOMAIN je problém autority: něco odpovědělo a nezná název, což ukazuje na zónu, region nebo resolver, který dotaz nikdy neměl dostat.

Poslední řádek je ten, který lidé vynechávají, protože obě poloviny vypadají jako úspěch. Krátký název, který se přeloží jinak než FQDN, je nesoulad přípony a opětovné připojení tunelu nezmění, kterou příponu klient odešle.

Zachyťte stav před úpravou konfiguračního souboru, abyste mohli říct, zda úprava něco udělala:

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

Spusťte kontroly v tomto pořadí a zastavte u první, která selže. getent a resolvectl query se musí shodovat; pokud getent selže, zatímco dig odpovídá, zůstaňte ve vyhledávacím řetězci a nedotýkejte se směrování. resolvectl status musí zobrazit server DNS a směrovací doménu na rozhraní tun. nsswitch se nesmí vrátit brzy s NOTFOUND pro příponu, kterou testujete. Název musí být autoritativní v síti, ke které je připojen váš koncový bod, testovaný s koncovou tečkou. Aplikace nesmí držet vlastní mezipaměť ani přepsání zabezpečeného DNS.

Opravte jen první selhávající vrstvu a potom znovu spusťte stejné příkazy. Dvě změny najednou vám nedovolí říct, která byla důležitá, a další porucha začíná vyšetřování od nuly.

Související články