A laptopod a VPN-en van, dig service.internal.example 10.x címre válaszol, a curl viszont továbbra is Could not resolve host-gyel lép ki. Nem az alagút a baj: panasz nélkül szállította a dig-kérdést. Az a különbség, hogy ki teszi fel a kérdést. A dig egyetlen kérdést küld egyetlen, általad megnevezett kiszolgálónak, míg a curl az operációs rendszer keresőláncán halad át, és annak a láncnak saját szabályai vannak arra, melyik kiszolgálót kérdezi.

Két keresés ugyanarra a névre

A dig a saját stub resolverje. Beolvassa az /etc/resolv.conf fájlt, kiválaszt egy névkiszolgálót, elküld egyetlen A vagy AAAA kérdést, és kiírja a választ. Teljesen átugorja az nsswitch-et, és semmit sem tud arról a kapcsolatonkénti állapotról, amelyet a systemd-resolved vagy a NetworkManager azon a fájlon kívül tart, ezért lehet egy dig-válasz helyes, és mégsem mond semmit arról, mit fog látni az alkalmazásod.

Az alkalmazások a getaddrinfo-t hívják, és a getaddrinfo hosszabb láncot jár be: az nsswitch modulsorrendjét, majd a nevet kezelő modult, végül az aktuális kapcsolatkonfigurációból épített resolver-t. Egy systemd-s gépen a kérdés a 127.0.0.53-ra megy, és a systemd-resolved a tun-interfészhez kapcsolt útvonalválasztási tartomány alapján választ kapcsolatonkénti felső kiszolgálót.

Két parancs választja el ezeket a rétegeket találgatás nélkül:

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

A getent ugyanazt az utat használja, mint a curl, így egy getent-hiba egy működő dig mellett a keresési szabályzatban lokalizálja a hibát, nem a csomagútvonalválasztásban. A resolvectl query kiírja az interfészt és a választ adó felső kiszolgálót is, ami megmutatja, hogy az alagút kapcsolata vagy a fizikai kapcsolat nyerte-e a döntést.

Olvasd ki azt a resolver-t, amelyet az alkalmazás tényleg használ

/etc/resolv.conf a legtöbb asztali gépen generált, és egy VPN-kliensnek három módja van a kezelésére: névkiszolgálót illeszt elé, felülírja a fájlt, vagy átadja a kiszolgálóit a NetworkManagernek, és hagyja, hogy a démon újraírja. Csak a harmadik minta tartja meg a kapcsolatonkénti DNS-t, mert a kiszolgálók egy interfészhez kötve maradnak, ahelyett hogy egy globális listába lapulnának.

NetworkManager-es rendszereken az eredmény az /etc/NetworkManager/NetworkManager.conf backendjétől függ:

[main]
dns=systemd-resolved

A(z) dns=default beállítással a kliens kiszolgálói a nyertes sorrendben olvadnak bele a resolv.conf-ba, és egy privát keresés még mindig a nyilvános resolver-hez kerülhet. A kapcsolatokat értő backenddel, systemd-resolved vagy dnsmasq, az alagút kiszolgálói az alagútra korlátozódnak, és csak az útvonalválasztási tartományának megfelelő nevek mennek oda. Ez a korlátozás az, amit a split DNS a gyakorlatban jelent, és ez az a darab, amely a leggyakrabban hiányzik, amikor egy kliens azt állítja, hogy támogatja.

Olvasd ki az állapotot, mielőtt bármit módosítasz:

resolvectl status
resolvectl dns tun0

Azt szeretnéd látni, hogy a tun-interfész DNS-kiszolgálóval és a privát utótag útvonalválasztási tartományával szerepel, ~internal.example formában megjelenítve. Ha nincs kiszolgáló a kapcsolaton, a kliens nem küldött semmit. A tartomány nélküli kiszolgáló azt jelenti, hogy a keresések vagy mind oda mennek, vagy egy sem, a klienstől függően, és egyik sem split DNS.

Ahol az nsswitch túl korán lezárja a keresést

Egy szokásos asztali sor így néz ki:

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

Az mdns4_minimal a multicast DNS-t kezeli, és minden .local-ra végződő névre igényt tart. Egy Kubernetes-szolgáltatás, például az api.infra.svc.cluster.local, szintén .local-ra végződik. Amikor az mDNS-modul NOTFOUND-ot jelent, a(z) [NOTFOUND=return] művelet lezárja az egész keresést ahelyett, hogy továbbmenne a dns-modulhoz, így a név soha nem kerül a VPN resolver-éhez. A dig teljesen megkerüli a fájlt, és pontosan ezért nem értenek egyet a két eszköz.

Ez a legélesebb ellentét ebben a problémában, és egyetlen szóra vezethető vissza egy olyan konfigurációs fájlban, amely régebbi, mint a VPN-ed. A művelet [NOTFOUND=continue]-re változtatása megtartja az mDNS-t a nyomtatókhoz és a helyi eszközökhöz, miközben a DNS láthatja a nevet. A sor hosts: files dns-re cserélése is működik, és durvább: elhagyja a .local feloldását annak a nyomtatónak, amelyet tényleg használsz.

Nevek, amelyek pontosan egy hálózatban élnek

A privát zónák pontosan egy helyen mérvadók. Egy AWS-név, például az ip-10-0-4-31.eu-west-1.compute.internal, az adott régió VPC-resolverén keresztül válaszol, és csak addig, amíg a VPN-végpontod ugyanabban a régióban van, mint az erőforrás. Csatlakozz egy frankfurti végponthoz, kérdezz le egy írországi compute.internal nevet, és semmilyen helyi beállítás nem segít: a rekordot tartó zóna onnan nem érhető el.

A keresési tartományok a tükörképet adják. Egy csupasz service kiegészül azzal az utótaggal, amelyet a resolver alkalmazhatónak tart, és VPN-kapcsolatnál a helyi tartomány legyőzheti a vállalatit. Kérdezz le záró ponttal, hogy kivegyed a találgatást, getent ahosts service.internal.example., és ha ez működik, míg a rövid név nem, akkor a javítás az alagúton lévő keresési tartomány, nem a kiszolgáló címe.

A kezelt kliensek egy harmadik réteget adnak a rendszer resolver-e fölé. Egy Windows VPN-profil saját névfeloldási házirendet, alkalmazásonkénti szabályokat és egy NRPT-táblázatot hordozhat, amely akkor is érvényes, amikor az alagút le van állva. A saját DNS-gyorsítótárral rendelkező alkalmazások, amelyek gyakoriak a .NET és Java runtime-okban, jóval a lánc megjavítása után is megtartják az elavult hibát. Az Apple-kliensek a split DNS-t egyeztető tartományokkal állítják be a DNS-beállításokban, nem a resolv.conf-on keresztül, és a Chromium vagy a Firefox biztonságos DNS módban megkerülheti a rendszer resolver-ét a nyilvános neveknél. A Microsoft VPN-névfeloldási referenciája a házirend-réteg Windows-oldalát írja le.

Döntsd el, melyik réteget javítsd

A tünettől haladj a réteg felé, ahelyett hogy sorban próbálnád a javításokat:

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

Két sor viseli a legnagyobb súlyt. Az időtúllépés elérhetőségi probléma: a privát resolver nem válaszol az alagúton keresztül, ezért ellenőrizd a címéhez vezető útvonalat, és hogy a kapcsolat DNS-kiszolgálója az-e, amelyet gondolsz. Az NXDOMAIN tekintélyi probléma: valami válaszolt, és nem ismeri a nevet, ami a zónára, a régióra vagy egy resolver-re mutat, amelynek soha nem kellett volna megkapnia a kérdést.

Az utolsó sor az, amelyet az emberek kihagynak, mert mindkét fél sikernek látszik. Az FQDN-től eltérően feloldódó rövid név utótag-eltérés, és az alagút újracsatlakoztatása nem változtatja meg, melyik utótagot küldi a kliens.

Rögzítsd az állapotot, mielőtt szerkesztesz egy konfigurációs fájlt, hogy meg tudd mondani, tett-e valamit a szerkesztés:

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

Futtasd az ellenőrzéseket ebben a sorrendben, és állj meg az elsőnél, amelyik elbukik. A getent és a resolvectl query eredményének egyeznie kell; ha a getent elbukik, miközben a dig válaszol, maradj a keresőláncban, és ne nyúlj az útvonalválasztáshoz. A resolvectl status-nak DNS-kiszolgálót és útvonalválasztási tartományt kell mutatnia a tun-interfészen. Az nsswitch nem térhet vissza korán NOTFOUND-dal a tesztelt utótagra. A névnek mérvadónak kell lennie abban a hálózatban, amelyhez a végpontod kapcsolódik, záró ponttal tesztelve. Az alkalmazás nem tarthat saját gyorsítótárat vagy biztonságos DNS-felülírást.

Csak az első elbukó réteget javítsd, majd futtasd újra ugyanazokat a parancsokat. Két változtatás egyszerre nem engedi megmondani, melyik számított, és a következő kiesés nulláról indítja a vizsgálatot.

Kapcsolódó cikkek