Beenden Sie den Wettstreit zweier Linux-Dienste um /etc/resolv.conf
Finden Sie heraus, wem die Datei gehört, bevor Sie sie bearbeiten. Das Unveränderlichkeits-Flag verdeckt den Konflikt, und Wiederverbindungen oder DHCP-Erneuerungen machen eine manuelle DNS-Reparatur immer wieder rückgängig.
DNS fällt immer wieder zurück, die VPN-Wiederverbindung macht Ihre Korrektur rückgängig, und irgendwann schlägt jemand im Team vor, die Datei zu sperren. Diese Abfolge ist ein Symptom, keine Lösung: Zwei Komponenten glauben beide, ihnen gehöre /etc/resolv.conf, und wer zuletzt schreibt, gewinnt. Die Datei zu sperren löst den Eigentumskonflikt nicht, es verbirgt ihn nur und beschädigt dabei die Komponente, die Sie eigentlich wollten. Gehen Sie die vier Prüfungen unten der Reihe nach durch und korrigieren Sie die Anordnung auf der Ebene, der sie gehört, nicht an der Datei.
Prüfung 1: Ist es ein Symlink, und wohin
Beginnen Sie mit der Datei selbst, denn der Pfad, den Sie bearbeiten, ist möglicherweise gar nicht die Datei. Ein Symlink in das Laufzeitverzeichnis eines Resolvers verhält sich völlig anders als eine gewöhnliche Datei, die ein Client-Skript neu schreibt:
ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
Ein Link auf einen Stub-Pfad von systemd-resolved bedeutet, dass der Inhalt der Datei erzeugt wird und manuelle Bearbeitung beim nächsten Ereignis überschrieben wird. Eine gewöhnliche Datei mit nameserver-Zeilen wird meist von dem Client- oder DHCP-Hook geschrieben, der beim Verbinden läuft. Beides ist legitim; entscheidend ist, zu wissen, welches von beiden Sie haben, bevor Sie etwas ändern.
Prüfung 2: Welcher Daemon läuft
Finden Sie heraus, was tatsächlich aktiv ist, nicht was installiert ist. Auf einer modernen Distribution können mehrere Resolver vorhanden sein, und derjenige, der Port 53 auf der Loopback-Schnittstelle hält, antwortet:
systemctl status systemd-resolved --no-pager
resolvectl status
ss -lunp | grep ':53'
Die Statusausgabe nennt die DNS-Server pro Verbindung und die Routing-Domains — die Karte, die Sie für Split-DNS brauchen. Müssen interne Namen zu einem internen Server und alles andere zu einem öffentlichen, lebt diese Richtlinie in den Domains pro Verbindung, und sie in eine statische nameserver-Liste in der Datei einzuebnen verliert diese Unterscheidung stillschweigend.
Die eigene Konfiguration von NetworkManager entscheidet, welches dieser Backends er verwendet. Seine Einstellung dns= in der Hauptkonfigurationsdatei wählt zwischen seinem internen Resolver, dnsmasq, systemd-resolved und none, und eine Distribution hat vielleicht für Sie gewählt. Lesen Sie diese Einstellung, bevor Sie entscheiden, was „DNS reparieren“ auf diesem Host bedeutet.
Prüfung 3: Was der VPN-Client schreiben darf
Hier lebt der Konflikt normalerweise. Ein VPN-Client, der die Resolver-Datei direkt neu schreibt, kämpft gegen jeden Dienst, der sie ebenfalls pflegt, und der Verlierer ist, wer zuerst läuft. Neuere OpenVPN-Versionen können die DNS-Einstellungen an systemd-resolved übergeben, statt die Datei neu zu schreiben — das ist das kooperative Verhalten, das Sie wollen; ältere Skripte und handgeschriebene Hooks rufen oft einen veralteten Helfer auf oder überschreiben einfach die Datei.
WireGuards Situation ist ähnlich geformt: Die Schnittstellenkonfiguration selbst verwaltet kein DNS, das tun die Werkzeuge darum herum, über einen Resolver-Helfer oder die resolved-Integration. Sind zwei solche Helfer installiert, versuchen beide, beim Verbinden ihr Weltbild durchzusetzen.
Lesen Sie die Up- und Down-Hooks des Clients, statt zu raten. Ein paar Zeilen Shell in /etc/openvpn/up.sh oder einem entsprechenden Verzeichnis erklären ein Verhalten, das sonst zufällig wirkt, und dort können Sie den Client auch zur Zusammenarbeit statt zum Wettstreit bringen.
Prüfung 4: Beheben Sie es beim Eigentümer, nicht an der Datei
Wenn Sie den Eigentümer kennen, konfigurieren Sie DNS über dessen unterstützte Schnittstelle. Für systemd-resolved heißt das Einstellungen pro Verbindung und Routing-Domains statt einer statischen Datei; für NetworkManager die DNS-Einstellungen des Verbindungsprofils und das gewählte Backend; für eine Distribution mit resolvconf-Integration das Schreiben über diesen Helfer.
Machen Sie die Datei nicht unveränderlich. Das Unveränderlichkeitsattribut stoppt legitime DHCP-Erneuerungen und VPN-Updates zusammen mit denen, gegen die Sie gekämpft haben, und es hinterlässt das System in einem Zustand, in dem die nächste Paketaktualisierung oder Wiederverbindung einen Fehler erzeugt, den niemand aus der Konfiguration erklären kann. Es verbirgt den Eigentumskonflikt — genau das, was Sie lösen wollten.
Wo zwei Komponenten wirklich koexistieren müssen, geben Sie ihnen unterschiedliche Aufgaben. Lassen Sie den Netzwerkmanager die Konfiguration auf Schnittstellenebene besitzen, lassen Sie den VPN-Client DNS und Domains pro Verbindung über dieselbe Integration beisteuern, und entfernen Sie das dritte Skript, das die Datei direkt schreibt. Die systemd-resolved-Dokumentation beschreibt die Modi, die er unterstützt, und was jeder davon in /etc/resolv.conf sichtbar macht. Wählen Sie den Modus, der dazu passt, wie viel Richtlinie Sie behalten müssen. Wenn Split-DNS wichtig ist, bewahrt die Stub-Anordnung mit Domains pro Verbindung ihn, während der Modus, der Upstream-Server in die Datei kopiert, ihn stillschweigend einebnet.
Prüfen Sie nach einer Wiederverbindung, nicht nach der Bearbeitung
Eine Datei, die direkt nach Ihrer Änderung korrekt aussieht, beweist nichts, denn das nächste Ereignis ist noch nicht eingetreten. Lösen Sie die Abfolge aus, die sie früher kaputt gemacht hat: Fahren Sie den Tunnel herunter und wieder hoch, erneuern Sie das DHCP-Lease oder schalten Sie die Schnittstelle um, und lesen Sie dann dieselben Werte erneut.
resolvectl query build.corp.example
resolvectl query example.com
resolvectl status | head -40
Bestätigen Sie dann die Unterscheidung, auf die es ankommt: Der interne Name wird über den internen Server aufgelöst, während der öffentliche Name weiterhin funktioniert. Eine Konfiguration, die alles an den internen Server schickt, sieht gut aus, bis jemand über den Tunnel ins Internet will, und eine Konfiguration, die alles an den öffentlichen schickt, leakt interne Namen.
Notieren Sie Eigentümer, Backend und Symlink-Modus in den Deployment-Notizen. Dieser eine Absatz macht aus einer künftigen Paketaktualisierung einen Prüfpunkt statt eines Vorfalls, und er hindert die nächste Person daran, denselben Konflikt mit einem chattr-Befehl erneut zu entdecken.