DNS-Caching und Split-DNS unter Linux
Auf den meisten aktuellen Linux Distributionen läuft DNS-Auflösung heute standardmäßig über systemd-resolved statt direkt über die im Kernel oder in glibc verankerte Namensauflösung. Für Admins, die zwischen internem VPN-Netz, Docker-Containern und öffentlichem Internet jonglieren, ist das Verständnis dieses Stub-Resolvers keine Kür mehr, sondern Voraussetzung dafür, dass DNS-Auflösung in gemischten Netzwerkumgebungen überhaupt zuverlässig funktioniert.
Inhaltsverzeichnis
- 1. Wie systemd-resolved als lokaler Stub-Resolver funktioniert
- 2. Grundkonfiguration über resolved.conf
- 3. Split-DNS für VPN-Szenarien einrichten
- 4. Debugging mit resolvectl
- 5. Zusammenspiel und Konflikte mit NetworkManager
- 6. Der resolv.conf Symlink und seine Fallstricke
- 7. DNSSEC-Validierung und DNS over TLS
- 8. Mehrere DNS-Server und Fallback-Verhalten verstehen
- 9. Troubleshooting häufiger Probleme
- 10. Zusammenfassung
- 11. FAQ
1. Wie systemd-resolved als lokaler Stub-Resolver funktioniert
systemd-resolved ist ein eigenständiger Systemdienst, der als lokaler DNS-Stub-Resolver auf der Loopback-Adresse 127.0.0.53 lauscht. Anwendungen auf dem System schicken ihre DNS-Anfragen nicht mehr direkt an einen externen Nameserver, sondern an diesen lokalen Stub, der die Anfrage entgegennimmt, gegebenenfalls aus dem Cache beantwortet und andernfalls an den konfigurierten upstream Resolver weiterreicht.
Dieses Design bringt zwei entscheidende Vorteile mit sich: Erstens werden Antworten systemweit zwischengespeichert, sodass wiederholte Anfragen an dieselbe Domain nicht erneut über das Netzwerk laufen müssen. Zweitens kann systemd-resolved pro Netzwerkschnittstelle unterschiedliche Resolver und sogar unterschiedliche Domains verwenden, was mit einem einzigen globalen /etc/resolv.conf in der klassischen Architektur schlicht nicht abbildbar war.
2. Grundkonfiguration über resolved.conf
Die globale Konfiguration liegt in /etc/systemd/resolved.conf, ergänzt um Drop-in Dateien in /etc/systemd/resolved.conf.d/, die eine sauberere Trennung zwischen Distributions-Defaults und eigenen Anpassungen erlauben. Die wichtigsten Direktiven sind DNS= für die primären Resolver, FallbackDNS= für Resolver, die nur greifen, wenn keine anderen konfiguriert sind, und Domains= für die Suchliste bei unqualifizierten Hostnamen.
Die Einstellung DNSSEC= steuert, ob Antworten kryptografisch gegen Manipulation validiert werden, während Cache= das systemweite Caching aktiviert oder deaktiviert. In den meisten produktiven Serverumgebungen ist DNSSEC=no nach wie vor der pragmatische Standard, weil viele interne Zonen keine gültigen DNSSEC-Signaturen liefern und ein zu strenger Modus sonst legitime interne Auflösungen blockiert.
# /etc/systemd/resolved.conf.d/custom.conf
[Resolve]
DNS=1.1.1.1 9.9.9.9
FallbackDNS=8.8.8.8
Domains=~.
DNSSEC=no
Cache=yes
DNSStubListener=yes
3. Split-DNS für VPN-Szenarien einrichten
Split-DNS bedeutet, dass bestimmte Domains gezielt über einen bestimmten Resolver aufgelöst werden, während alle anderen Anfragen den regulären Weg nehmen. Das ist typisch für VPN-Verbindungen: Interne Domains wie internal.mironsoft.local sollen über den unternehmensinternen DNS-Server laufen, während die Auflösung öffentlicher Domains weiterhin über den regulären Resolver erfolgt, statt unnötig durch den VPN-Tunnel geleitet zu werden.
systemd-resolved implementiert das über sogenannte Routing-Domains, die mit einer Tilde eingeleitet werden. Eine Domain-Angabe wie ~internal.mironsoft.local auf einer bestimmten Netzwerkschnittstelle sorgt dafür, dass ausschließlich Anfragen für diese Zone über die zugehörigen DNS-Server dieser Schnittstelle geleitet werden, während die globale Suchliste unberührt bleibt.
# Split-DNS für die VPN-Schnittstelle tun0 setzen
resolvectl dns tun0 10.8.0.1
resolvectl domain tun0 "~internal.mironsoft.local"
# Aktuelle Zuordnung von Domains zu Schnittstellen prüfen
resolvectl domain
4. Debugging mit resolvectl
Das Kommandozeilenwerkzeug resolvectl ist der zentrale Anlaufpunkt für alles rund um systemd-resolved. resolvectl status zeigt pro Schnittstelle die aktuell verwendeten DNS-Server, die konfigurierten Domains und den aktiven DNSSEC-Modus, was bei widersprüchlichen Konfigurationen aus mehreren Quellen, etwa NetworkManager und statischer resolved.conf, sofort sichtbar macht, welche Einstellung tatsächlich aktiv ist.
Für gezielte Fehlersuche löst resolvectl query einen bestimmten Hostnamen auf und zeigt zusätzlich an, über welche Schnittstelle und welchen Resolver die Antwort kam, während resolvectl statistics Cache-Trefferquote und Anzahl der Transaktionen liefert. Bei hartnäckigen Problemen hilft ein resolvectl flush-caches, um veraltete oder fehlerhafte gecachte Einträge gezielt zu entfernen, ohne den Dienst komplett neu zu starten.
# Vollständigen DNS Status aller Schnittstellen anzeigen
resolvectl status
# Gezielte Auflösung mit Angabe der genutzten Quelle
resolvectl query shop.mironsoft.de
# Cache leeren, ohne den Dienst neu zu starten
resolvectl flush-caches
5. Zusammenspiel und Konflikte mit NetworkManager
NetworkManager kann DNS-Einstellungen auf zwei grundlegend unterschiedliche Arten verwalten: Im Modus dns=systemd-resolved reicht NetworkManager die per DHCP oder VPN erhaltenen DNS-Server direkt an systemd-resolved weiter, das dann die gesamte Auflösung übernimmt. Im Modus dns=default schreibt NetworkManager dagegen selbst in /etc/resolv.conf, wodurch systemd-resolved umgangen wird und Split-DNS-Funktionalität schlicht verloren geht.
Der häufigste Konfigurationsfehler entsteht, wenn beide Dienste gleichzeitig versuchen, /etc/resolv.conf zu verwalten. Das äußert sich in scheinbar zufällig wechselndem DNS-Verhalten nach jedem Verbindungswechsel, weil je nach Reihenfolge der Dienste unterschiedliche Konfigurationen gewinnen. Die zuverlässige Lösung ist, sich für genau einen Verwalter zu entscheiden und diesen in /etc/NetworkManager/NetworkManager.conf explizit festzulegen.
# /etc/NetworkManager/conf.d/dns.conf
[main]
dns=systemd-resolved
6. Der resolv.conf Symlink und seine Fallstricke
systemd-resolved stellt mehrere Varianten von resolv.conf zur Verfügung, die sich in /run/systemd/resolve/ befinden. stub-resolv.conf zeigt auf den lokalen Stub-Resolver 127.0.0.53 und ist die empfohlene Standardeinstellung, während resolv.conf direkt die tatsächlich konfigurierten upstream Server auflistet, ohne den lokalen Cache und die Split-DNS-Logik zu nutzen.
Ein häufiger Fehler ist ein manuell erstelltes, statisches /etc/resolv.conf, das den erwarteten Symlink überschreibt. Dadurch funktioniert die Auflösung zwar zunächst noch, aber jegliche Split-DNS-Konfiguration und der lokale Cache werden komplett umgangen, ohne dass dies auf den ersten Blick erkennbar wäre. Ein Blick mit ls -la /etc/resolv.conf zeigt sofort, ob tatsächlich noch der erwartete Symlink vorliegt.
# Pruefen, ob /etc/resolv.conf noch korrekt auf systemd-resolved zeigt
ls -la /etc/resolv.conf
# Symlink auf den empfohlenen Stub Resolver zuruecksetzen
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
7. DNSSEC-Validierung und DNS over TLS
Neben klassischer Namensauflösung unterstützt systemd-resolved sowohl DNSSEC-Validierung als auch DNS over TLS für den verschlüsselten Transport zum upstream Resolver. Die Einstellung DNSOverTLS=opportunistic versucht zunächst eine verschlüsselte Verbindung und fällt bei fehlender Unterstützung des Resolvers automatisch auf unverschlüsseltes DNS zurück, was Kompatibilität und Sicherheit sinnvoll ausbalanciert.
Der strikte Modus DNSOverTLS=yes verweigert dagegen jede unverschlüsselte Verbindung, was in Umgebungen mit unzuverlässiger DNS over TLS Unterstützung einzelner Resolver zu kompletten Auflösungsausfällen führen kann. Für produktive Server empfiehlt sich deshalb, den opportunistischen Modus zu verwenden oder DNS over TLS ganz bewusst zu deaktivieren, statt im strikten Modus unerwartete Ausfälle zu riskieren.
[Resolve]
DNSOverTLS=opportunistic
DNSSEC=allow-downgrade
8. Mehrere DNS-Server und Fallback-Verhalten verstehen
Werden unter DNS= mehrere Server angegeben, verwendet systemd-resolved standardmäßig nicht stur den ersten Eintrag, sondern testet fortlaufend, welcher der konfigurierten Server tatsächlich am zuverlässigsten und schnellsten antwortet, und bevorzugt diesen für nachfolgende Anfragen. Dieses sogenannte Feature-Level-Probing merkt sich außerdem, ob ein Server bestimmte Fähigkeiten wie EDNS0 unterstützt, um unnötige Fallback-Versuche bei jeder einzelnen Anfrage zu vermeiden.
Antwortet der aktuell bevorzugte Server über einen längeren Zeitraum nicht, wechselt systemd-resolved automatisch zum nächsten konfigurierten Server in der Liste, ohne dass eine manuelle Intervention nötig wäre. Für produktive Setups empfiehlt es sich deshalb, mindestens zwei unabhängige Resolver unter DNS= einzutragen, damit ein einzelner ausgefallener Server nicht die gesamte Namensauflösung des Systems blockiert.
# Aktuell als bevorzugt erkannten Server pro Schnittstelle anzeigen
resolvectl status | grep -A2 "Current DNS Server"
9. Troubleshooting häufiger Probleme
Ein klassisches Symptom sind Timeouts beim Auflösen, obwohl resolvectl status korrekte Resolver anzeigt. In vielen Fällen liegt die Ursache in einer Firewall, die ausgehende Anfragen auf Port 53 blockiert, oder in einem VPN-Client, der die Netzwerkschnittstelle zwar aktiviert, aber keine gültigen DNS-Server über DHCP oder eine eigene Konfigurationsschnittstelle bereitstellt.
Ein weiteres häufiges Problem betrifft Docker-Container: Läuft systemd-resolved auf dem Host, zeigt /etc/resolv.conf im Container auf 127.0.0.53, eine Adresse, die innerhalb des isolierten Container-Netzwerks nicht erreichbar ist. Docker löst das normalerweise automatisch, indem es beim Erstellen des Containers stattdessen die tatsächlichen upstream Server aus /run/systemd/resolve/resolv.conf einträgt, was bei eigenen Netzwerk-Setups mit network_mode: host jedoch explizit geprüft werden sollte.
| Datei | Zeigt auf | Nutzt lokalen Cache | Empfohlen für |
|---|---|---|---|
| stub-resolv.conf | 127.0.0.53, lokaler Stub | Ja | Standard-Setup mit vollem Funktionsumfang |
| resolv.conf (resolved) | Tatsächliche upstream Server | Nein | Anwendungen ohne systemd-resolved Unterstützung |
| Statisches /etc/resolv.conf | Manuell eingetragene Server | Nein | Nicht empfohlen, umgeht Split-DNS |
| uplink-resolv.conf | Upstream Server für andere resolved Instanzen | Nein | Container mit eigenem systemd-resolved |
Mironsoft
Server-Administration, Docker-Hosts und Performance-Tuning
Linux-Server, die niemand im Team richtig versteht?
Wir übernehmen Setup, Absicherung und Performance-Tuning von Linux-Servern und Docker-Hosts für Magento-Deployments, dokumentiert und nachvollziehbar statt gewachsen und unklar.
Server-Audit
Bestehende Server-Konfiguration auf Sicherheitslücken und Performance-Bremsen prüfen.
Docker-Host-Setup
Produktionsreife Docker-Umgebungen für Magento sauber aufsetzen und absichern.
Monitoring & Tuning
Ressourcenverbrauch messen und Systemd, Kernel und Dienste gezielt optimieren.
10. Zusammenfassung
systemd-resolved
Stub Adresse
127.0.0.53, lokaler DNS Cache pro System
Kernbefehl
resolvectl status, query und flush-caches
Split-DNS
Routing-Domains mit Tilde-Präfix pro Schnittstelle
Häufigster Fehler
Statisches resolv.conf überschreibt den erwarteten Symlink