Ihr Laptop ist im VPN, dig service.internal.example antwortet mit einer 10.x-Adresse, und curl bricht weiterhin mit Could not resolve host ab. Der Tunnel ist nicht das Problem: Er hat die dig-Abfrage anstandslos befördert. Unterschiedlich ist, wer die Frage stellt. dig schickt eine Abfrage an einen von Ihnen benannten Server, während curl die Auflösungskette des Betriebssystems durchläuft, und diese Kette hat eigene Regeln dafür, welcher Server gefragt wird.

Zwei Auflösungen für denselben Namen

dig ist ein eigener Stub-Resolver. Es liest /etc/resolv.conf, wählt einen Nameserver, sendet eine einzelne A- oder AAAA-Abfrage und gibt die Antwort aus. nsswitch überspringt es vollständig und weiß nichts über den linkbezogenen Zustand, den systemd-resolved oder NetworkManager außerhalb dieser Datei führen; deshalb kann eine dig-Antwort korrekt sein und Ihnen trotzdem nichts darüber sagen, was Ihre Anwendung sehen wird.

Anwendungen rufen getaddrinfo auf, und getaddrinfo durchläuft eine längere Kette: die Modulreihenfolge aus nsswitch, dann das Modul, das den Namen behandelt, dann den Resolver, der aus der aktuellen Link-Konfiguration aufgebaut wird. Auf einem systemd-System geht die Abfrage an 127.0.0.53, und systemd-resolved wählt einen vorgelagerten, linkbezogenen Server anhand der Routing-Domain, die an das tun-Interface gebunden ist.

Zwei Befehle trennen diese Schichten, ohne raten zu müssen:

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

getent nutzt denselben Pfad wie curl; ein getent-Fehler neben einem funktionierenden dig grenzt den Fehler also auf die Auflösungsrichtlinie ein statt auf das Paket-Routing. resolvectl query gibt außerdem das Interface und den Upstream aus, der die Antwort geliefert hat, und so sehen Sie, ob die Tunnel-Verbindung oder die physische Verbindung die Entscheidung gewonnen hat.

Den Resolver lesen, den die Anwendung tatsächlich nutzt

/etc/resolv.conf wird auf den meisten Desktops generiert, und ein VPN-Client hat drei Möglichkeiten, damit umzugehen: einen Nameserver voranstellen, die Datei überschreiben oder seine Server an NetworkManager übergeben und den Daemon sie neu schreiben lassen. Nur das dritte Muster erhält linkbezogenes DNS, weil die Server an ein Interface gebunden bleiben, statt in einer globalen Liste zusammengefasst zu werden.

Auf NetworkManager-Systemen hängt das Ergebnis vom Backend in /etc/NetworkManager/NetworkManager.conf ab:

[main]
dns=systemd-resolved

Mit dns=default werden die Server des Clients in beliebiger Reihenfolge in resolv.conf zusammengeführt, und eine private Abfrage kann trotzdem an den öffentlichen Resolver gehen. Bei einem Backend, das Links versteht, systemd-resolved oder dnsmasq, bleiben die Server des Tunnels auf den Tunnel beschränkt, und nur Namen, die zu seiner Routing-Domain passen, gehen dorthin. Diese Beschränkung ist es, was Split-DNS in der Praxis bedeutet, und genau dieses Stück fehlt am häufigsten, wenn ein Client behauptet, es zu unterstützen.

Lesen Sie den Zustand, bevor Sie etwas ändern:

resolvectl status
resolvectl dns tun0

Sie möchten das tun-Interface mit einem DNS-Server und einer Routing-Domain für das private Suffix aufgeführt sehen, angezeigt als ~internal.example. Kein Server am Link bedeutet, dass der Client nichts übermittelt hat. Ein Server ohne Domain bedeutet, dass Abfragen entweder alle dorthin oder gar nicht gehen, je nach Client, und beides ist kein Split-DNS.

Wo nsswitch die Auflösung vorzeitig beendet

Eine Standard-Desktop-Zeile sieht so aus:

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

mdns4_minimal behandelt Multicast-DNS und beansprucht jeden Namen, der auf .local endet. Ein Kubernetes-Dienst wie api.infra.svc.cluster.local endet ebenfalls auf .local. Wenn das mDNS-Modul NOTFOUND meldet, beendet die Aktion [NOTFOUND=return] die gesamte Auflösung, statt mit dem dns-Modul fortzufahren, der Name wird also nie an den VPN-Resolver geschickt. dig umgeht die Datei vollständig, und genau deshalb sind sich die beiden Werkzeuge uneinig.

Das ist der schärfste Gegensatz in diesem Problem, und er läuft auf ein einziges Wort in einer Konfigurationsdatei hinaus, die älter ist als Ihr VPN. Wenn Sie die Aktion auf [NOTFOUND=continue] ändern, bleibt mDNS für Drucker und lokale Geräte erhalten, während DNS den Namen sehen kann. Die Zeile durch hosts: files dns zu ersetzen funktioniert ebenfalls und ist gröber: Es fällt die .local-Auflösung für den Drucker weg, den Sie tatsächlich benutzen.

Namen, die in genau einem Netzwerk leben

Private Zonen sind an genau einer Stelle autoritativ. Ein AWS-Name wie ip-10-0-4-31.eu-west-1.compute.internal wird über den VPC-Resolver der jeweiligen Region beantwortet, und zwar nur, solange Ihr VPN-Endpunkt in derselben Region wie die Ressource liegt. Verbinden Sie sich mit einem Frankfurter Endpunkt und fragen einen compute.internal-Namen aus Irland ab, hilft keine lokale Einstellung: Die Zone mit dem Datensatz ist von dort nicht erreichbar.

Suchdomänen erzeugen das Spiegelbild. Ein bloßes service wird mit dem Suffix vervollständigt, das der Resolver für passend hält, und bei einer VPN-Verbindung kann die lokale Domäne die des Unternehmens schlagen. Fragen Sie mit einem abschließenden Punkt ab, um das Raten zu beseitigen, getent ahosts service.internal.example., und wenn das funktioniert, während der Kurzname scheitert, dann ist die Suchdomäne am Tunnel die Lösung, nicht die Serveradresse.

Verwaltete Clients fügen eine dritte Schicht über dem Resolver des Betriebssystems hinzu. Ein Windows-VPN-Profil kann eine eigene Namensauflösungsrichtlinie, Regeln pro App und eine NRPT-Tabelle mitbringen, die auch dann gilt, wenn der Tunnel getrennt ist. Anwendungen mit eigenem DNS-Cache, wie sie in .NET- und Java-Laufzeiten üblich sind, behalten einen veralteten Fehler noch lange, nachdem die Kette repariert ist. Apple-Clients konfigurieren Split-DNS über Match-Domains in den DNS-Einstellungen statt über resolv.conf, und Chromium oder Firefox im Secure-DNS-Modus können den Systemresolver für öffentliche Namen umgehen. Microsofts VPN-Namensauflösungsreferenz beschreibt die Windows-Seite dieser Richtlinienebene.

Entscheiden, welche Schicht zu reparieren ist

Arbeiten Sie vom Symptom zur Schicht, statt Korrekturen der Reihe nach zu probieren:

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

Zwei Zeilen tragen das meiste Gewicht. Ein Timeout ist ein Erreichbarkeitsproblem: Der private Resolver antwortet nicht durch den Tunnel, also prüfen Sie die Route zu seiner Adresse und ob der DNS-Server am Link der ist, den Sie vermuten. NXDOMAIN ist ein Autoritätsproblem: Etwas hat geantwortet und kennt den Namen nicht, was auf die Zone, die Region oder einen Resolver deutet, der die Abfrage nie hätte erhalten sollen.

Die letzte Zeile ist die, die viele übersehen, weil beide Hälften wie Erfolg aussehen. Ein Kurzname, der anders als der FQDN aufgelöst wird, ist eine Suffix-Fehlanpassung, und ein erneutes Verbinden des Tunnels ändert nicht, welches Suffix der Client übermittelt.

Erfassen Sie den Zustand, bevor Sie eine Konfigurationsdatei bearbeiten, damit Sie sehen können, ob die Änderung etwas bewirkt hat:

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

Führen Sie die Prüfungen in dieser Reihenfolge aus und halten Sie bei der ersten an, die fehlschlägt. getent und resolvectl query müssen übereinstimmen; wenn getent scheitert, während dig antwortet, bleiben Sie in der Auflösungskette und lassen das Routing in Ruhe. resolvectl status muss einen DNS-Server und eine Routing-Domain am tun-Interface zeigen. nsswitch darf bei NOTFOUND nicht vorzeitig für das getestete Suffix zurückkehren. Der Name muss in dem Netzwerk autoritativ sein, an dem Ihr Endpunkt hängt, geprüft mit einem abschließenden Punkt. Die Anwendung darf keinen eigenen Cache und keine Secure-DNS-Übersteuerung halten.

Beheben Sie nur die erste fehlschlagende Schicht und führen Sie dann dieselben Befehle erneut aus. Zwei Änderungen auf einmal lassen Sie nicht sagen, welche davon zählte, und der nächste Ausfall beginnt die Untersuchung bei null.

Ähnliche Artikel