Nameservers op Linux: van `/etc/resolv.conf` tot `resolvectl`
```bash sudo apt update sudo apt install -y dnsutils ldnsutils bind9-utils ```
Op RHEL-achtigen gebruik je `sudo dnf install bind-utils ldns bind`. Zonder deze tools kun je niet zien wat er onder water gebeurt; met alleen `ping` weet je dat er iets werkt, niet wat.
1. Bekijk wat je systeem nu als resolver gebruikt
Voordat je iets verandert, wil je weten wie de DNS-query's op dit moment afhandelt. Op moderne systemen is dat zelden `/etc/resolv.conf` direct.```bash resolvectl status ```
Je krijgt per interface de gebruikte DNS-servers, het zoekdomein en of DNSSEC actief is. Staat er `Current DNS Server: 127.0.0.53`, dan luistert `systemd-resolved` lokaal en stuurt hij je queries door naar de upstream-servers die daaronder vermeld staan.
Draait er geen `systemd-resolved`, dan is `/etc/resolv.conf` je enige bron:
```bash cat /etc/resolv.conf ```
Let op de eerste regel. Staat er `nameserver 127.0.0.53`, dan is het bestand een stub die door systemd wordt beheerd — handmatig aanpassen heeft dan geen effect, en dat verrast mensen vaak genoeg om er een aparte alinea aan te wijden.
2. Begrijp waarom `/etc/resolv.conf` vaak een symlink is
`/etc/resolv.conf` is op veel systemen een symlink naar `/run/systemd/resolve/stub-resolv.conf`. Systemd herschrijft dat bestand bij elke netwerkwissel.```bash ls -l /etc/resolv.conf ```
Zie je een pijl naar `/run/systemd/resolve/`, dan is je resolv.conf vluchtig. Elke handmatige edit verdwijnt bij de volgende reboot of DHCP-renew. Wil je toch een vaste DNS-server instellen, dan doe je dat via `systemd-resolved` zelf (stap 3), niet door het bestand te overschrijven.
De verleiding is groot om de symlink te vervangen door een echt bestand. Dat werkt — tot je netwerkbeheer de volgende keer zijn gang gaat en je oude bestand terugzet. Dan zit je 's ochtends met een resolver die naar een server wijst die je vorige week hebt uitgezet.
3. Stel een vaste upstream DNS-server in via systemd-resolved
Systemd-resolved leest zijn configuratie uit `/etc/systemd/resolved.conf` en de drop-in map `/etc/systemd/resolved.conf.d/`. Gebruik de drop-in; die overleeft package-updates netter.```bash sudo mkdir -p /etc/systemd/resolved.conf.d/ sudo tee /etc/systemd/resolved.conf.d/pixzo-dns.conf > /dev/null <<'EOF' [Resolve] DNS=9.9.9.9 149.112.112.112 FallbackDNS=1.1.1.1 8.8.8.8 DNSSEC=allow-downgrade DNSOverTLS=opportunistic EOF ```
`9.9.9.9` en `149.112.112.112` zijn Quad9. `FallbackDNS` wordt alleen gebruikt als de primaire servers onbereikbaar zijn. `DNSSEC=allow-downgrade` valideert als de upstream het ondersteunt en valt terug als dat niet zo is — strenger (`yes`) betekent dat je hele internet stukgaat zodra één upstream geen DNSSEC doet. `DNSOverTLS=opportunistic` versleutelt de query als de server het kan, zonder te weigeren als het niet kan.
Herlaad daarna:
```bash sudo systemctl restart systemd-resolved ```
De kosten van deze aanpak: je verkeer gaat via Quad9 in plaats van via je provider. Sneller of langzamer, dat verschilt per regio. Privacy-technisch is het een verbetering, tenzij je provider zelf al valideert en je die vertrouwt.
4. Query's debuggen met `dig`
`dig` uit BIND 9.18 stuurt een query rechtstreeks naar de nameserver die je opgeeft, zonder de lokale resolver te gebruiken. Dat is precies wat je wil bij het debuggen: je wilt weten wat de autoritatieve server zegt, niet wat je cache ervan gemaakt heeft.```bash dig pixzo.nl A +short dig pixzo.nl MX +short dig pixzo.nl TXT +short ```
Voor een volledig antwoord met timing en de gebruikte server:
```bash dig pixzo.nl A ```
In de `ANSWER SECTION` zie je het record en de TTL. In de `Query time`-regel staat hoeveel milliseconden het duurde. Bij een cache-hit is dat vaak 0 of 1 ms; bij een volledige lookup 20–80 ms afhankelijk van afstand.
Wil je een specifieke nameserver bevragen en de lokale cache omzeilen:
```bash dig @9.9.9.9 pixzo.nl A +norecurse ```
Met `+norecurse` vraag je niet om recursie. Een autoritatieve server antwoordt dan meteen; een recursor weigert. Zo zie je direct met wat voor server je praat.
Voor DNSSEC-validatie:
```bash dig pixzo.nl A +dnssec ```
Verschijnt er een `RRSIG`-record in de answer, dan is de zone ondertekend. Zie je `ad` in de flags, dan heeft je resolver de signature ook gevalideerd.
5. `drill` als alternatief voor DNSSEC-debugging
`drill` komt uit `ldns` en is gemaakt met DNSSEC in het achterhoofd. Waar `dig` je de records toont, loopt `drill` desgewenst de hele validatieketen langs.```bash drill pixzo.nl A drill -S pixzo.nl A ```
De `-S`-flag vraagt om chasenaamvalidatie: drill loopt van de root zone via de TLD naar de autoritatieve server en controleert onderweg elke signature. Dat is trager dan `dig`, maar je ziet precies waar de keten breekt als er iets mis is met een DS-record of een verlopen RRSIG.
Voor wie alleen wil weten of een zone überhaupt ondertekend is, is `dig +dnssec` sneller. `drill -S` gebruik je als je moet uitzoeken waarom validatie faalt.
6. Een BIND-nameserver herladen met `rndc`
Draai je zelf een BIND 9.18, dan beheer je hem op afstand met `rndc`. Het commando stuurt een ondertekend bericht over TCP naar poort 953; de server controleert de handtekening tegen `rndc.key`.```bash sudo rndc status sudo rndc reload sudo rndc flush ```
`rndc reload` leest de zonebestanden opnieuw in zonder de service te herstarten — bestaande verbindingen blijven staan. `rndc flush` leegt de cache. Dat laatste is nuttig als je net een record hebt gewijzigd en wil testen zonder op de TTL te wachten, maar het kost je ook alle gecachte antwoorden: je server moet daarna alles opnieuw ophalen.
Standaard luistert `rndc` alleen op `127.0.0.1`. Wil je vanaf een andere host beheren, dan pas je `controls` aan in `named.conf` én zet je een firewallregel. Doe dat alleen over een VPN of een beheernetwerk; `rndc` op het publieke internet is een slecht idee.
7. Testen met `ldns-testns`
Soms wil je een client testen tegen een nameserver die precies doet wat jij voorschrijft — inclusief foute antwoorden. `ldns-testns` is een minimale server die vooraf gedefinieerde antwoorden terugstuurt.Maak een datafile:
```bash cat > /tmp/testns.data <<'EOF' pixzo.nl. 3600 IN A 192.0.2.1 pixzo.nl. 3600 IN TXT "test" EOF ```
Start de server:
```bash sudo ldns-testns -p 5353 -f /tmp/testns.data ```
In een tweede terminal:
```bash dig @127.0.0.1 -p 5353 pixzo.nl A +short ```
Je krijgt `192.0.2.1` terug, ongeacht wat de echte DNS zegt. Handig om te controleren hoe je applicatie omgaat met onverwachte antwoorden, timeouts of NXDOMAIN. Draai deze server nooit op een publiek bereikbaar adres — hij valideert niets en antwoordt op alles.
Verificatie
Controleer of je resolver de nieuwe upstream gebruikt:```bash resolvectl status | grep -A2 "Current DNS Server" ```
Er moet nu `9.9.9.9` of `149.112.112.112` staan, niet meer je provider.
Controleer of queries werken:
```bash resolvectl query pixzo.nl dig pixzo.nl A +short ```
Beide commando's moeten hetzelfde IP-adres teruggeven. Krijg je bij `resolvectl query` een andere uitkomst dan bij `dig`, dan praat je met twee verschillende resolvers — meestal omdat `dig` langs `/etc/resolv.conf` gaat en `resolvectl` via D-Bus.
Controleer of DNSSEC werkt:
```bash dig pixzo.nl A +dnssec | grep -E "flags:|RRSIG" ```
Zie je `ad` in de flags en een `RRSIG`-record, dan is de keten rond.
Veelgestelde problemen
`resolvectl status` toont `127.0.0.53` als enige DNS-server. Dat is normaal: `systemd-resolved` luistert lokaal en proxyt naar de upstream-servers die eronder in dezelfde output staan. Kijk naar de `DNS Servers:`-regel per interface, niet naar `Current DNS Server`. Wil je de stub uitzetten, zet dan `DNSStubListener=no` in `/etc/systemd/resolved.conf.d/` — maar dan moet je `/etc/resolv.conf` zelf beheren, en dat is precies het onderhoud dat je wilde vermijden.Wijzigingen in `/etc/resolv.conf` verdwijnen na een reboot. Het bestand is een symlink naar `/run/systemd/resolve/stub-resolv.conf` en wordt bij elke netwerkwissel herschreven. Zet je DNS-instellingen in `/etc/systemd/resolved.conf.d/` in plaats van het bestand zelf aan te passen.
`rndc reload` geeft `connection refused`. De BIND-service draait niet, of `rndc` probeert een andere poort dan waar `named` op luistert. Check met `sudo ss -tlnp | grep 953` of de control-poort open is, en vergelijk het `controls`-blok in `named.conf` met de `default-port` in `/etc/bind/rndc.conf`. Klopt de poort, dan is meestal het `key`-bestand niet leesbaar voor de gebruiker die `rndc` aanroept.
DNS is een van die dingen die je nooit opmerkt tot het misgaat, en dan op het slechtst denkbare moment.