# 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`: ```text hosts: files myhostname dns ``` `/etc/resolv.conf` (reguläre Datei statt Symlink): ```text # 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-Adressen `127.0.0.53`/`127.0.0.54` vor 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 ```bash 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: ```bash 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 1. Prüft Root-Rechte, benötigte Kommandos und BIND9; DNSSEC-Positiv- und Negativtest. 2. Zeigt den geplanten Eingriff und verlangt `Einverstanden [yes/no, default: no]?`. 3. Legt eine Sicherung von **Datei bzw. Symlink** `/etc/resolv.conf`, `/etc/nsswitch.conf` und dem bisherigen `systemd-resolved`-Dienststatus unter `/var/backups/oopen-bind9-direct-resolver/run-.../` an (Verzeichnis nur für Root). 4. Ändert, soweit erforderlich, die `hosts:`-NSS-Zeile und erstellt `/etc/resolv.conf` mit `nameserver 127.0.0.1`. Eine vorhandene `search`-Zeile wird übernommen. 5. Prüft normale Vorwärts- und Reverse-Auflösung. 6. Stoppt und deaktiviert `systemd-resolved` und prüft BIND9/DNSSEC erneut. 7. 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: ```text /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 ```bash 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: ```bash /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): ```bash # 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:`-Eintrag `files myhostname dns` ist auf diesem Server geprüft. Systeme mit weiteren NSS-Modulen wie `mymachines`, `mdns` oder LDAP benötigen eine angepasste Variante. - `systemd-resolved` kann von speziellen Diensten per D-Bus oder `resolvectl` verwendet werden. Das muss vor dem Deaktivieren separat berücksichtigt werden. - `systemd-resolved` wird nur gestoppt/deaktiviert, **nicht deinstalliert oder maskiert**. - Bei fehlgeschlagenem Rollback nicht mehrfach blind ausführen: Ausgabe und gesichertes Backup-Verzeichnis überprüfen. ## 9. Quellen - [systemd-resolved – Modes für /etc/resolv.conf](https://www.freedesktop.org/software/systemd/man/latest/systemd-resolved.service.html) - [nss-resolve – NSS-Reihenfolge und systemd-resolved](https://www.freedesktop.org/software/systemd/man/latest/nss-resolve.html) - [Debian: resolvconf-Kompatibilitätsmodus von resolvectl](https://manpages.debian.org/trixie/systemd-resolved/resolvconf.1.en.html)