10 KiB
Debian 13: Systemresolver von systemd-resolved auf lokalen BIND9 umstellen
Stand: 27. Oktober 2026
Beispielsystem: lists.mx (produktiver Mail-/Listenserver, Debian 13)
Skript: switch-resolver-to-bind9.sh
1. Ziel und Hintergrund
Auf dem Host läuft bereits ein rekursiver BIND9 auf 127.0.0.1:53 und [::1]:53, einschließlich eigener DNSSEC-Validierung (dnssec-validation auto;). Bislang nutzten Programme /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf und damit 127.0.0.53 (systemd-resolved), der wiederum an BIND9 weiterleitete.
Beobachtetes Problem: Die IPv6-PTR-Abfrage für 2607:f8b0:4864:20::72e ergab über 127.0.0.53 SERVFAIL mit DNSSEC validation failed: failed-auxiliary, über 127.0.0.1 jedoch korrekt mail-qk1-x72e.google.com.. Mit DNSSEC=no in systemd-resolved funktionierte die PTR-Auflösung, aber Anfragen für die absichtlich DNSSEC-fehlerhafte Zone www.dnssec-failed.org liefen über 127.0.0.53 weiterhin in einen Timeout. Ein Loopback-Mitschnitt zeigte vielfach wiederholte Abfragen trotz SERVFAIL-Antworten von BIND9. Der DNS-Proxy auf 127.0.0.54 übergab dagegen SERVFAIL korrekt.
Ziel: BIND9 direkt über die glibc-/NSS-DNS-Auflösung nutzen; systemd-resolved nach erfolgreichem Test stoppen und deaktivieren. Keine Änderung an Maildiensten, BIND-Konfiguration, Interfaces, Firewall oder Routing.
2. Zielkonfiguration
/etc/nsswitch.conf:
hosts: files myhostname dns
/etc/resolv.conf (reguläre Datei statt Symlink):
# Local BIND9 recursive resolver; DNSSEC validated by BIND9.
nameserver 127.0.0.1
options edns0 trust-ad
search warenform.de
search warenform.de ist systemspezifisch. Das Skript übernimmt eine bereits vorhandene search-Zeile aus der bestehenden Konfiguration; es erfindet keine Suchdomäne. Bei lists.mx ist sie bereits gesetzt. trust-ad bedeutet nicht, dass glibc selbst DNSSEC prüft. Das validierende Glied ist BIND9. Programme mit eigenen Resolver-Bibliotheken können eine abweichende DNS-Konfiguration haben; dies ggf. anwendungsspezifisch prüfen.
Die lokale DNS-Auflösung setzt die Verfügbarkeit von BIND9 voraus. Mit nur 127.0.0.1 gibt es bewusst keinen externen Fallback, der lokale DNSSEC-Validierung umgehen könnte.
3. Voraussetzungen
- Debian 13, Root-Shell; BIND9 ist installiert, gestartet und lauscht auf IPv4-Loopback
127.0.0.1:53. dig,getent,systemctl, die üblichen Coreutils sowie Bash sind verfügbar.- BIND9 kann rekursiv auflösen und validiert DNSSEC unabhängig von
systemd-resolved. - Änderungen werden in einem Wartungsfenster bzw. mit vorhandener administrativer Konsole vorgenommen. Keine Netzwerkdienste oder Interfaces neu starten.
- Vorhandene dynamische DNS-Konfiguration (DHCP, VPN, Split-DNS, interne Domains) prüfen; das Skript bildet keine
systemd-resolved-Link-Konfiguration nach. - Eventuelle lokale Abhängigkeiten von
systemd-resolved,resolvectl, LLMNR/mDNS und DNS-Stub-Adressen127.0.0.53/127.0.0.54vor dem Abschalten ausschließen.
Achtung: Auf lists.mx wurde networking.service zuvor als failed gemeldet. Das ist ein separates Thema und wird von diesem Skript ausdrücklich nicht behandelt. Insbesondere kein systemctl restart networking ausführen.
4. DNSSEC-Vorabprüfung
dig @127.0.0.1 cloudflare.com A +dnssec +adflag
dig @127.0.0.1 www.dnssec-failed.org A +time=5 +tries=1
dig @127.0.0.1 -x 2607:f8b0:4864:20::72e
Erwartung: cloudflare.com → NOERROR und Flag ad, www.dnssec-failed.org → SERVFAIL (nicht Timeout), PTR → mail-qk1-x72e.google.com. (Stand des beobachteten Beispiels; DNS-Daten können sich ändern). Das Skript führt einen Positiv- und Negativ-DNSSEC-Test zusätzlich selbst aus. Die Testdomain ist absichtlich fehlerhaft signiert.
5. Skriptinstallation und Verwendung
Datei an einen geeigneten Ort kopieren, beispielsweise:
install -o root -g root -m 0755 switch-resolver-to-bind9.sh \
/usr/local/sbin/switch-resolver-to-bind9.sh
bash -n /usr/local/sbin/switch-resolver-to-bind9.sh
# Nur lesen und prüfen (Standard):
/usr/local/sbin/switch-resolver-to-bind9.sh --check
# Umstellung mit interaktiver Bestätigung (exakt 'yes'):
/usr/local/sbin/switch-resolver-to-bind9.sh --apply
# Rückbau des durch dieses Skript vorgenommenen Zustands:
/usr/local/sbin/switch-resolver-to-bind9.sh --rollback
Statusausgaben verwenden die bekannten Muster [ Info ], [ ok ], [ failed ], [ skipped ]. Keine automatische Paketinstallation und kein Reboot. Die Änderung erfolgt nicht schon beim Aufruf ohne Parameter.
Was --apply tut
- Prüft Root-Rechte, benötigte Kommandos und BIND9; DNSSEC-Positiv- und Negativtest.
- Zeigt den geplanten Eingriff und verlangt
Einverstanden [yes/no, default: no]?. - Legt eine Sicherung von Datei bzw. Symlink
/etc/resolv.conf,/etc/nsswitch.confund dem bisherigensystemd-resolved-Dienststatus unter/var/backups/oopen-bind9-direct-resolver/run-.../an (Verzeichnis nur für Root). - Ändert, soweit erforderlich, die
hosts:-NSS-Zeile und erstellt/etc/resolv.confmitnameserver 127.0.0.1. Eine vorhandenesearch-Zeile wird übernommen. - Prüft normale Vorwärts- und Reverse-Auflösung.
- Stoppt und deaktiviert
systemd-resolvedund prüft BIND9/DNSSEC erneut. - Bei einem Fehler versucht das Skript automatisch einen Rückbau der gesicherten Dateien und des gespeicherten Dienstzustands. Ein automatischer Rückbau ist eine Schutzmaßnahme, keine Garantie bei Stromausfall oder hartem Prozessabbruch.
Bereits vollständig umgestellte Systeme werden ohne Änderungen mit [ skipped ] erkannt. Existiert noch ein offener, vom Skript angelegter Rückbauzustand, bricht ein weiterer --apply-Lauf ab. So wird verhindert, dass die ursprüngliche Sicherung unbemerkt überschrieben wird.
Besonderheit bei lists.mx (bereits manuell umgestellt)
Auf lists.mx wurden /etc/nsswitch.conf und /etc/resolv.conf am 27.10.2026 bereits manuell auf direkten BIND9 umgestellt. Das Skript erkennt dies und kann bei --apply den Dienst systemd-resolved noch stoppen und deaktivieren, sofern dies noch nicht erfolgt ist. Der Skript-Rollback stellt dann den Zustand unmittelbar vor diesem Skriptlauf wieder her, nicht automatisch den historischen systemd-resolved-Zustand vom Morgen.
Die zuvor manuell erstellte Sicherung liegt unter:
/root/dns-resolver-backup-20261027-120829
Dort ist resolv.conf ein relativer Symlink. Er muss bei manueller Wiederherstellung an seinem ursprünglichen Ort /etc/resolv.conf wieder angelegt werden. Der historische Zustand lässt sich mit gesichertem nsswitch.conf und dem ursprünglichen Symlink wiederherstellen; dafür systemd-resolved zuerst wieder aktivieren.
6. Abschließende Prüfungen
cat /etc/resolv.conf
grep '^hosts:' /etc/nsswitch.conf
systemctl is-active bind9
systemctl is-active systemd-resolved
systemctl is-enabled systemd-resolved
getent ahostsv4 oopen.de
getent hosts 2607:f8b0:4864:20::72e
dig cloudflare.com A +dnssec +adflag
dig www.dnssec-failed.org A +time=5 +tries=1
Erwartung: BIND9 active, systemd-resolved inactive und disabled, erfolgreiche normale Auflösung, DNSSEC-Positivtest ad, Negativtest SERVFAIL. Bei dig muss SERVER: 127.0.0.1#53 erscheinen. Zusätzlich Mail-Logs und anwendungsspezifische Namensauflösung kontrollieren. Änderungen bestehen über einen Neustart fort, sofern kein anderer Netzwerkdienst /etc/resolv.conf ersetzt und BIND9 beim Boot zuverlässig startet; einen Neustart des Produktivservers führt das Skript nicht aus.
7. Rollback
Falls --apply dieses Skripts zuvor erfolgreich gelaufen ist:
/usr/local/sbin/switch-resolver-to-bind9.sh --rollback
Das stellt die bei diesem Skriptlauf gesicherten Dateien und den Dienststatus nach Bestätigung wieder her. Die Sicherungsdateien bleiben archiviert. Falls die Dateien vor dem ersten Skriptlauf schon direkt BIND9 benutzten, bringt dieser Rollback folgerichtig nicht den ursprünglichen systemd-Stub zurück.
Manueller Rückbau auf lists.mx in den früheren Zustand (nur bei gezieltem Bedarf und mit konsistenter DNS-Prüfung):
# Ursprünglichen NSS-Zustand wiederherstellen:
cp -a /root/dns-resolver-backup-20261027-120829/nsswitch.conf /etc/nsswitch.conf
# Dienst starten, Stub-Datei prüfen:
systemctl enable --now systemd-resolved
test -f /run/systemd/resolve/stub-resolv.conf
# Ziel-Symlink atomar am ursprünglichen Ort wiederherstellen:
ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf.rollback-link
mv -Tf /etc/resolv.conf.rollback-link /etc/resolv.conf
# Ergebnis prüfen:
getent ahostsv4 oopen.de
dig -x 2607:f8b0:4864:20::72e
Die frühere Einstellung DNSSEC=no in /etc/systemd/resolved.conf.d/90-local-bind9.conf bleibt bei diesem manuellen Rückbau erhalten, solange sie nicht separat geändert wird. DNSSEC bleibt dann bei BIND9 aktiv.
8. Grenzen und Sicherheit
- Das Skript setzt einen bereits gesunden lokalen BIND9 voraus und ist kein BIND9-Installationsskript.
- Kein automatisches Umschalten auf öffentliche Resolver; bei BIND-Ausfall würde lokale DNS-Auflösung ausfallen.
- Ein vereinfachter
hosts:-Eintragfiles myhostname dnsist auf diesem Server geprüft. Systeme mit weiteren NSS-Modulen wiemymachines,mdnsoder LDAP benötigen eine angepasste Variante. systemd-resolvedkann von speziellen Diensten per D-Bus oderresolvectlverwendet werden. Das muss vor dem Deaktivieren separat berücksichtigt werden.systemd-resolvedwird nur gestoppt/deaktiviert, nicht deinstalliert oder maskiert.- Bei fehlgeschlagenem Rollback nicht mehrfach blind ausführen: Ausgabe und gesichertes Backup-Verzeichnis überprüfen.