Linux commando: dig
Vroeg of laat blijkt elk websiteprobleem een DNS-probleem te zijn. De site laadt bij jou maar niet bij de klant, de nieuwe server draait maar de oude blijft antwoorden, de mail komt na een verhuizing niet meer aan. In al die gevallen heb je een manier nodig om het domeinnaamsysteem precies te vragen wat het denkt, zonder browser, cache of controlepaneel ertussen. Dat gereedschap is dig.
1. De basis
De taak van dig is smal en precies: het stuurt een DNS-vraag naar een naamserver en drukt het volledige antwoord af, precies zoals het over het netwerk terugkwam. Er wordt niets samengevat, niets verborgen en niets voor je uitgelegd.
Juist die smalheid is het punt. Een browser zegt "deze site is niet bereikbaar", en dat kan van alles betekenen. dig vertelt je dat de naamserver NXDOMAIN antwoordde, of dat hij het IP-adres van je vorige hostingprovider teruggaf, of dat hij helemaal niet antwoordde. Dat zijn drie verschillende problemen met drie verschillende oplossingen.
Twee eigenschappen maken dig het gereedschap bij uitstek voor DNS-werk. Ten eerste is het alleen-lezen. Het stelt vragen; het verandert nooit een zone, een record of een cache. Je kunt het zonder enig risico op je eigen servers en op die van anderen loslaten. Ten tweede is het eerlijk. Het laat de responscodes, de vlaggen en de tijden zien die andere gereedschappen stilletjes inslikken.
Een vraag, een server en het onbewerkte antwoord. Al het andere in dit artikel is een variatie op die drie dingen.
Het juiste mentale model:
digvertelt je niet "hoe mijn computer deze naam opzoekt". Het vertelt je "wat deze specifieke server op deze specifieke vraag antwoordt, op dit moment". Dat zijn heel verschillende uitspraken, en ze door elkaar halen veroorzaakt de meeste DNS-verwarring.
1.1 dig geïnstalleerd krijgen
Op veel distributies staat dig niet meer standaard geïnstalleerd, omdat het in hetzelfde pakket zit als de andere BIND-clientgereedschappen:
$ sudo apt install bind9-dnsutils # Debian, Ubuntu
$ sudo dnf install bind-utils # Fedora, RHEL, Rocky, AlmaLinux
$ sudo pacman -S bind # Arch Linux
Hetzelfde pakket geeft je nslookup en delv, die allebei verderop in dit artikel voorbijkomen. Op Debian en Ubuntu zit host in een apart pakket bind9-host. Controleer je versie met dig -v; elk voorbeeld hier is gedraaid tegen de versie hieronder, en het gedrag is al jaren stabiel.
$ dig -v
DiG 9.18.39-0ubuntu0.24.04.6-Ubuntu
Naar boven2. Waar komt de naam vandaan?
Decennialang gaf de handleiding dig een betekenis: domain information groper.
dig = Domain Information Groper
Het werkt op twee niveaus. Letterlijk tast het programma in het domeinnaamsysteem rond naar informatie. En als werkwoord graaf je (dig) naar iets wat begraven ligt, wat een aardige omschrijving is van het najagen van een verouderd record door drie lagen caching heen.
De betekenis stond decennialang in de handleiding. In 2017 is die stilletjes verwijderd, dus op een modern systeem noemt man dig het simpelweg een "DNS lookup utility". De naam is nu gewoon een naam, wat uiteindelijk met de meeste goede afkortingen gebeurt.
3. Een korte geschiedenis
Om te begrijpen waarom dig zich gedraagt zoals het doet, helpt het te weten dat het gebouwd is door de mensen die de DNS-serversoftware zelf schreven. Het is geen omhulsel van een derde partij; het is het eigen debuggereedschap van de referentie-implementatie.
| Jaar | Mijlpaal |
|---|---|
| 1983 | Paul Mockapetris beschrijft het domeinnaamsysteem in RFC 882 en RFC 883 |
| 1986 | nslookup, een studieproject van Andrew Cherenson in Berkeley, verschijnt in 4.3-Tahoe BSD |
| 1987 | RFC 1034 en RFC 1035 vervangen de originelen en bepalen DNS tot op vandaag |
| Eind jaren tachtig | Steve Hotz schrijft de eerste dig |
| 1990 | dig wordt meegeleverd als onderdeel van BIND 4 |
| 2000 | BIND 9 verschijnt met een door Michael Sawyer herschreven dig; dit is de versie die je vandaag draait |
| 2004 | ISC draait het plan om nslookup uit te faseren terug, in BIND 9.3 |
| 2017 | De betekenis "domain information groper" verdwijnt uit de handleiding |
| Vandaag | Onderhouden door het Internet Systems Consortium; spreekt DNS over UDP, TCP, TLS en HTTPS |
3.1 De familie opzoekgereedschappen
Je komt verschillende commando's tegen die hetzelfde lijken te doen. Dat doen ze niet, en weten welke welke is scheelt tijd.
| Commando | Waar het voor is |
|---|---|
dig |
Volledige DNS-diagnostiek. Toont het hele antwoord, elke vlag en elke tijd. |
host |
Een kort, vriendelijk antwoord op een regel. Prima voor een snelle controle, zwak voor debuggen. |
nslookup |
De oudste van de drie, met een interactieve modus. Wordt nog ondersteund, maar de uitvoer verbergt details. |
delv |
Zoals dig, maar het valideert DNSSEC-handtekeningen echt in plaats van ze alleen te tonen. |
getent hosts |
Vraagt het besturingssysteem, niet DNS. Dit is wat je andere programma's werkelijk gebruiken. |
resolvectl |
Op systemd-systemen: welke bovenliggende servers ingesteld zijn, en wat er in de lokale cache zit. |
kdig, drill |
Alternatieven van Knot DNS en ldns. Zelfde idee, iets andere uitvoer en opties. |
Nog even over nslookup. Een tijdlang wilden de BIND-ontwikkelaars het verwijderen, en een generatie handleidingen herhaalt nog steeds "nslookup is verouderd". Dat besluit is in 2004 teruggedraaid. Het wordt volledig ondersteund. De eerlijke reden om dig te verkiezen is niet dat nslookup uitsterft, maar dat dig je de responscode en de vlaggen laat zien, en nslookup niet.
4. Eenvoudige toepassingen
4.1 De eenvoudigst mogelijke vraag
Typ dig gevolgd door een domeinnaam. In de voorbeelden hieronder is de regel die met $ begint wat jij typt; de rest is wat het systeem terugdrukt.
$ dig petermartin.nl
; <<>> DiG 9.18.39-0ubuntu0.24.04.6-Ubuntu <<>> petermartin.nl
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 89
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;petermartin.nl. IN A
;; ANSWER SECTION:
petermartin.nl. 349 IN A 23.88.98.40
;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Fri Aug 21 11:58:20 CEST 2026
;; MSG SIZE rcvd: 59
Dat is veel uitvoer voor een IP-adres, en beginners grijpen meteen naar +short om het weg te krijgen. Doe dat nog even niet. Bijna elk veld in dit blok beantwoordt een vraag die je vroeg of laat gaat stellen.
Twee standaardinstellingen zijn het waard om meteen te benoemen. Als je geen recordtype opgeeft, vraagt dig om een A-record. Als je geen server noemt, gebruikt het de eerste bruikbare server in /etc/resolv.conf.
4.2 De uitvoer lezen, blok voor blok
Het antwoord wordt altijd in dezelfde volgorde afgedrukt. Leer de blokken een keer en je leest elke dig-uitvoer in een oogopslag.
| Blok | Wat het je vertelt |
|---|---|
; <<>> DiG ... <<>> |
Je dig-versie en het exacte commando dat je draaide. Handig als je uitvoer in een ticket plakt. |
HEADER |
Het veld status:. Dit is het belangrijkste woord in de hele uitvoer. |
flags: |
Welke bits de server in zijn antwoord gezet heeft, plus hoeveel records er in elke sectie zitten. |
OPT PSEUDOSECTION |
EDNS-details: het grootste UDP-antwoord waar beide kanten het over eens zijn, en DNSSEC- of cookie-opties. |
QUESTION SECTION |
De vraag zoals de server hem begrepen heeft. Kijk hier als eerste als het antwoord je verrast. |
ANSWER SECTION |
De records waar je om vroeg. Dit is wat mensen bedoelen met "het antwoord". |
AUTHORITY SECTION |
Welke naamservers verantwoordelijk zijn voor de zone. Vaak zichtbaar als er geen antwoord is. |
ADDITIONAL SECTION |
Extra records die de server ongevraagd meestuurde, meestal de adressen van die naamservers. |
Query time |
Hoe lang het antwoord duurde. 0 msec betekent bijna altijd een treffer in een lokale cache. |
SERVER |
Welke server werkelijk antwoordde. Lees deze regel elke keer. |
WHEN, MSG SIZE |
Tijdstempel en antwoordgrootte in bytes. De grootte doet ertoe als pakketten te groot worden voor UDP. |
De regel SERVER verdient bijzondere aandacht. In het voorbeeld hierboven staat er 127.0.0.53, en dat is de lokale stub-resolver op een systemd-systeem, geen publieke DNS-server. De helft van alle meldingen "mijn DNS-wijziging werkt niet" komt voort uit het lezen van een antwoord dat een lokale cache produceerde.
4.3 Een enkel record lezen
Elk record in een antwoord is een regel met vijf velden, altijd in dezelfde volgorde. Zodra je ze kunt benoemen, wordt elke DNS-uitvoer leesbaar:
petermartin.nl. 349 IN A 23.88.98.40
| | | | |
name TTL class type data
| Veld | Voorbeeld | Betekenis |
|---|---|---|
| Naam | petermartin.nl. |
De naam waar dit record bij hoort, voluit geschreven |
| TTL | 349 |
Seconden dat dit record gecachet mag worden. Sectie 5.6 legt uit waarom het verandert |
| Klasse | IN |
Kort voor Internet. In de praktijk altijd IN |
| Type | A |
Het soort record. Sectie 5.2 somt de types op die je tegenkomt |
| Data | 23.88.98.40 |
De waarde zelf. De vorm hangt af van het type |
Het klasseveld is een overblijfsel uit de jaren tachtig. DNS was ontworpen om ook andere netwerken te bedienen, en dig accepteert nog steeds -c CH voor Chaosnet en -c HS voor Hesiod. Je zult je hele loopbaan IN lezen, maar weten wat die kolom is haalt hem weg uit de ruis.
Kijk nu naar de punt aan het eind van petermartin.nl., die je makkelijk voor een typefout aanziet. Dat is het niet. DNS-namen vormen een hiërarchie die bij de wortel eindigt, en die wortel wordt geschreven als een leeg label na een laatste punt. Een naam met die punt is volledig gekwalificeerd: hij betekent precies deze naam en niets anders. Aan een naam zonder punt kan degene die hem opzoekt nog een zoekdomein plakken. dig drukt de punt altijd af, omdat het altijd de volledige naam afdrukt.
4.4 De statusregel: vier woorden die je moet kennen
Het veld status: in de header is het oordeel van de server. Vier waarden dekken bijna alles wat je tegenkomt.
| Status | Betekenis | Wat je moet doen |
|---|---|---|
NOERROR |
De vraag is gelukt. Let op: dit belooft geen antwoordsectie. | Controleer de teller ANSWER:. NOERROR met ANSWER: 0 betekent dat de naam bestaat maar geen record van dat type heeft. |
NXDOMAIN |
De naam bestaat helemaal niet. | Zoek naar een typefout, een ontbrekend record of een verlopen domein. |
SERVFAIL |
De server heeft het geprobeerd en is mislukt. Heel vaak een mislukte DNSSEC-validatie. | Vraag het een andere resolver, en vraag daarna de autoritatieve server rechtstreeks om te vinden waar het misgaat. |
REFUSED |
De server kan antwoorden maar wil dat niet, voor jou. | Je vraagt het een server die deze zone niet bedient, of die geen recursie aanbiedt aan jouw IP. |
Het onderscheid in die eerste rij zet mensen voortdurend op het verkeerde been. Vergelijk deze twee antwoorden. Het eerste vraagt een gezond domein om een recordtype dat het niet heeft: de status is NOERROR en de antwoordteller staat op nul.
$ dig petermartin.nl SRV
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13851
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 7
;; AUTHORITY SECTION:
petermartin.nl. 85897 IN NS chelsea.ns.cloudflare.com.
Het tweede vraagt om een naam die er simpelweg niet is. Nu verandert de status zelf:
$ dig this-does-not-exist-pm.nl
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 32259
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
Beide leveren een lege antwoordsectie op, en +short drukt in geen van beide gevallen iets af. Alleen het statuswoord vertelt je of het domein verkeerd ingesteld is of niet bestaat, en dat vraagt om heel verschillende oplossingen.
Een moderne kanttekening verpest de nette regel, en het is goed om die te kennen voordat hij je in verwarring brengt. Sommige grote DNS-providers geven op ondertekende zones helemaal geen NXDOMAIN meer terug. Kijk hoe dezelfde ontbrekende naam op twee manieren beantwoord wordt:
$ dig @elliott.ns.cloudflare.com nosuch.example.com | grep status
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 48273
$ dig @elliott.ns.cloudflare.com +dnssec nosuch.example.com | grep status
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55148
+dnssec toevoegen veranderde een ontbrekende naam in NOERROR. Dit heet compact denial of existence, met als bijnaam "black lies". Bewijzen dat een naam niet bestaat vereist ondertekende records, en de eerlijke manier om dat te doen laat iedereen de hele zone naam voor naam aflopen. Daarom verzint de server ter plekke een record dat zegt "deze naam bestaat, maar heeft geen gegevens", wat goedkoper te ondertekenen is en niets weggeeft.
Omdat publieke resolvers bij elke vraag DNSSEC opvragen, is dit wat je normaal gesproken ziet:
$ dig @1.1.1.1 nosuch.example.com | grep status # Cloudflare-hosted zone
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14782
$ dig @1.1.1.1 nosuch-x.debian.org | grep status # a zone that does not do this
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 24703
Bij een groot deel van de echte domeinen meldt een naam die werkelijk niet bestaat dus NOERROR met nul antwoorden. Lees dat niet als "het recordtype ontbreekt" zonder het te controleren. Vraag de autoritatieve server zonder +dnssec, zoals in het eerste voorbeeld hierboven, en de gewone NXDOMAIN komt terug. dig heeft zelfs een optie voor het mechanisme, +coflag, die de vlag voor compact denial of existence in de vraag zet.
4.5 De vlaggenregel
De vlaggen zijn afkortingen van twee letters voor bits in de header van het DNS-bericht. Je hoeft ze niet allemaal te kennen, maar deze zes kom je dagelijks tegen.
| Vlag | Staat voor | Waarom het uitmaakt |
|---|---|---|
qr |
Query response | Dit is een antwoord, geen vraag. Altijd aanwezig in de uitvoer. |
rd |
Recursion desired | Je hebt de server gevraagd het werk van het opzoeken te doen. |
ra |
Recursion available | De server is bereid dat voor je te doen. Ontbreekt op servers die alleen autoritatief zijn. |
aa |
Authoritative answer | Het antwoord komt van de bron, niet uit een cache. Dit is de vlag die je wilt zien als je een wijziging controleert. |
ad |
Authentic data | De resolver heeft de DNSSEC-handtekeningen gecontroleerd en die waren in orde. |
cd |
Checking disabled | Je hebt de resolver gevraagd DNSSEC-validatie over te slaan. Handig om aan te tonen dat een SERVFAIL met DNSSEC te maken heeft. |
De praktische regel: als aa ontbreekt, lees je een gecachete kopie. Wat er ook staat, het kan minuten of uren verouderd zijn.
4.6 De ruis wegsnijden: +short
Zodra je de volledige uitvoer begrijpt, is +short de vlag die je het vaakst typt. Het drukt de antwoordgegevens af en verder niets:
$ dig +short petermartin.nl
23.88.98.40
$ dig +short example.com
172.66.147.243
104.20.23.154
Dat tweede resultaat is op zichzelf al een nuttige herinnering: een naam kan meerdere adressen hebben, en de volgorde verschilt per vraag. "Het" IP-adres van een drukke site bestaat niet.
+short is perfect voor scripts en voor een snelle bevestiging. Het is het verkeerde gereedschap zodra er iets stuk is, want het gooit de status, de vlaggen en de serverregel weg, en dat is precies de informatie waar een mislukte lookup van afhangt.
4.7 Om een specifiek recordtype vragen
Zet het recordtype achter de naam. Hoofdletters maken niet uit, en dig is soepel over de volgorde van zijn argumenten:
$ dig +short petermartin.nl MX
0 fallback.axc.eu.
$ dig +short petermartin.nl NS
chelsea.ns.cloudflare.com.
finley.ns.cloudflare.com.
$ dig mx joomla.org +short # type first also works
5 alt2.aspmx.l.google.com.
1 aspmx.l.google.com.
10 alt3.aspmx.l.google.com.
10 alt4.aspmx.l.google.com.
5 alt1.aspmx.l.google.com.
Kijk goed naar die MX-lijst. De getallen zijn prioriteiten, waarbij lager de voorkeur heeft, en de regels staan duidelijk niet op volgorde. dig drukt records af in de volgorde waarin de server ze stuurde, en servers husselen ze bewust door elkaar. Sorteren is het werk van de mailserver, niet van de weergave, dus lees de eerste regel niet als "de belangrijkste mailserver".
Wil je expliciet zijn, en in scripts hoor je dat te zijn, gebruik dan -t voor het type en -q voor de naam. Dat haalt alle dubbelzinnigheid weg, wat uitmaakt bij namen die botsen met type- of klassewoorden:
$ dig -t MX -q petermartin.nl +short
0 fallback.axc.eu.
4.8 Kiezen wie er antwoordt: @
Zet @ gevolgd door een server voor de naam, en dig vraagt het die server in plaats van die uit /etc/resolv.conf. Dit ene teken maakt van dig een diagnosegereedschap in plaats van een opzoekgereedschap:
$ dig @1.1.1.1 +short petermartin.nl # Cloudflare's public resolver
$ dig @8.8.8.8 +short petermartin.nl # Google's public resolver
$ dig @9.9.9.9 +short petermartin.nl # Quad9
$ dig @192.168.1.1 +short petermartin.nl # your own router
$ dig @chelsea.ns.cloudflare.com +short petermartin.nl # the authoritative source
Twee van die antwoorden vergelijken vertelt je veel meer dan welke enkele lookup ook. Zegt de autoritatieve server het ene en een publieke resolver het andere, dan wacht je gewoon tot een cache verloopt. Zijn ze het eens en wijkt jouw eigen machine af, dan zit het probleem aan jouw kant van de kabel.
Naar bovenNegentig procent van praktisch DNS-onderzoek is een vraag die je twee keer stelt: een keer aan een cache, en een keer aan de autoritatieve naamserver. Het verschil tussen die twee antwoorden is het probleem.
5. Gemiddelde toepassingen
5.1 De weergavevlaggen: +noall +answer
Tussen de muur van volledige uitvoer en de kale gegevens van +short zit de combinatie waar de meeste beheerders bij uitkomen. Die werkt door elke weergavesectie uit te zetten en er daarna een weer aan te zetten:
$ dig +noall +answer petermartin.nl
petermartin.nl. 349 IN A 23.88.98.40
Het is de moeite waard het mechanisme te snappen, want het is algemeen toepasbaar. Elke sectie van de uitvoer heeft zijn eigen schakelaar, en +all of +noall zet ze allemaal tegelijk om:
| Optie | Bepaalt |
|---|---|
+[no]cmd |
De versie- en commandobanner bovenaan |
+[no]comments |
De headerregel, de vlaggenregel en de sectietitels |
+[no]question |
De vraagsectie |
+[no]answer |
De antwoordsectie |
+[no]authority |
De autoriteitssectie |
+[no]additional |
De aanvullende sectie |
+[no]stats |
De vraagtijd, server, tijdstempel en berichtgrootte |
+[no]all |
Alle bovenstaande in een keer |
+noall +answer betekent dus "laat me niets zien, behalve het antwoord, met de recordvelden intact". Zet er weer bij wat je verder wilt:
$ dig +noall +answer +authority petermartin.nl MX # answer plus who serves the zone
$ dig +noall +comments example.com # only the header and flags
$ dig +noall +answer +stats petermartin.nl # the answer plus which server gave it
Houd +short voor scripts die een waarde nodig hebben, en +noall +answer voor alles wat je met je eigen ogen leest.
5.2 De recordtypes die je echt tegenkomt
DNS kent tientallen recordtypes. In website- en mailbeheer komt steeds dezelfde handvol terug.
| Type | Doel |
|---|---|
A |
Een IPv4-adres voor een naam |
AAAA |
Een IPv6-adres. Zo genoemd omdat het vier keer zo groot is als een A-record |
CNAME |
Een alias: "zoek deze andere naam op" |
MX |
Mail exchanger: waar e-mail voor het domein bezorgd moet worden |
TXT |
Vrije tekst. In de praktijk: SPF, DKIM, DMARC en verificatiecodes van diensten |
NS |
De autoritatieve naamservers voor de zone |
SOA |
Start of authority: het serienummer en de timers van de zone |
CAA |
Welke certificaatautoriteiten certificaten voor dit domein mogen uitgeven |
SRV |
Een dienst op een host en poort, gebruikt door SIP, XMPP en mailverzending |
PTR |
De omgekeerde weg: een adres terug naar een naam |
DS, DNSKEY, RRSIG |
De DNSSEC-records: delegation signer, publieke sleutel en handtekening |
Hier is een echt domein, type voor type bekeken. Let op hoeveel je met vier commando's over een hostingopzet te weten komt:
$ dig +noall +answer petermartin.nl A
petermartin.nl. 349 IN A 23.88.98.40
$ dig +noall +answer petermartin.nl AAAA
petermartin.nl. 589 IN AAAA 2a01:4f8:c0c:6848::1
$ dig +noall +answer petermartin.nl NS
petermartin.nl. 7052 IN NS chelsea.ns.cloudflare.com.
petermartin.nl. 7052 IN NS finley.ns.cloudflare.com.
$ dig +noall +answer www.petermartin.nl
www.petermartin.nl. 349 IN CNAME petermartin.nl.
petermartin.nl. 349 IN A 23.88.98.40
Die laatste laat belangrijk gedrag zien. Je vroeg om een A-record voor www, en de server gaf je twee records: de alias, en daarna het adres waar die naar wijst. dig toont de hele keten, en zo zie je een CNAME die naar een naam wijst die niet meer bestaat.
Een TXT-lookup is de snelste manier om mailauthenticatie te controleren. SPF staat op het domein zelf, DMARC op het subdomein _dmarc, en DKIM op een selector die je zelf kiest:
$ dig +short petermartin.nl TXT
"google-site-verification=Cb25YjPnzwZBEfXrkDteEOOkHC_1xv9XCXhTeCOBPzg"
$ dig +short _dmarc.example.com TXT # the DMARC policy
$ dig +short mail._domainkey.example.com TXT # a DKIM public key
En CAA vertelt je welke certificaatautoriteiten voor het domein mogen uitgeven, wat een verrassend aantal mislukte certificaatvernieuwingen verklaart:
$ dig +short petermartin.nl CAA
0 issue "letsencrypt.org"
0 issue "digicert.com; cansignhttpexchanges=yes"
0 issuewild "letsencrypt.org"
5.3 Records reizen in sets
DNS werkt eigenlijk niet met losse regels. Elk record dat dezelfde naam, klasse en type deelt vormt een eenheid die een resource record set heet, of RRset. De twee adressen van example.com zijn geen twee antwoorden; ze zijn een RRset met twee leden:
$ dig +noall +answer example.com
example.com. 67 IN A 172.66.147.243 } one RRset,
example.com. 67 IN A 104.20.23.154 } two records
Dit is geen detail voor protocolpuristen. Drie dingen die je tegenkomt volgen er rechtstreeks uit:
- De hele set deelt een TTL. Je kunt het ene adres niet eerder laten verlopen dan het andere, want een cache bewaart en verwijdert de set als geheel.
- DNSSEC ondertekent de set, niet het record. Daarom toont een zone met twee
A-records er nog steeds maar eenRRSIG Anaast. Verander een lid en de handtekening over de hele set wordt opnieuw berekend. - De volgorde betekent niets. Een server mag de leden in willekeurige volgorde teruggeven, en veel servers wisselen ze bewust af om de last te spreiden. Dit is hetzelfde effect als bij de ongesorteerde
MX-lijst hierboven, en de reden om op te passen met scripts die de eerste regel pakken en als "het" antwoord behandelen.
De regel verklaart ook een beperking waar mensen bij het inrichten van een zone tegenaan lopen. Een CNAME mag niet naast andere records op dezelfde naam staan, want dan zouden er twee verschillende types staan waar het protocol een alias verwacht die voor alles staat. Sectie 9.2 komt hierop terug als de valkuil van de zone-apex.
5.4 Omgekeerde lookups met -x
Een omgekeerde lookup maakt van een IP-adres weer een naam. Met de hand betekent dat de octetten omdraaien en er in-addr.arpa achter plakken, en dat wil niemand twee keer doen. De vlag -x bouwt die naam voor je en zet het type op PTR:
$ dig -x 8.8.8.8 +short
dns.google.
$ dig -x 8.8.8.8 +noall +question
;8.8.8.8.in-addr.arpa. IN PTR
De vraagsectie laat precies zien wat -x gebouwd heeft. IPv6-adressen werken hetzelfde, uitgeschreven per hexcijfer onder ip6.arpa.
Omgekeerde DNS doet er het meest toe voor mailservers. Veel ontvangende systemen controleren of het verzendende IP een PTR-record heeft en of de naam die dat teruggeeft weer naar hetzelfde adres verwijst. Een ontbrekend PTR-record is een veelvoorkomende reden dat mail in de spam belandt.
5.5 Meerdere vragen in een commando
dig accepteert meerdere lookups op een regel. Het voert ze op volgorde uit en drukt elk antwoord af:
$ dig +noall +answer petermartin.nl A petermartin.nl MX
petermartin.nl. 497 IN A 23.88.98.40
petermartin.nl. 600 IN MX 0 fallback.axc.eu.
Dit brengt een subtiliteit met zich mee in hoe opties toegepast worden. Opties die je voor de eerste naam zet zijn globaal en gelden voor elke lookup. Opties achter een naam gelden alleen voor die lookup. Daarmee vergelijk je twee servers in een enkel commando:
$ dig +short petermartin.nl @1.1.1.1 petermartin.nl @chelsea.ns.cloudflare.com
23.88.98.40
23.88.98.40
Verschillen de twee regels, dan houdt een cache een oude waarde vast.
5.6 De TTL-kolom, en waarom dat getal blijft veranderen
De tweede kolom van elk record is de TTL, de time to live, in seconden. Het is de houdbaarheidsdatum van het antwoord: hoeveel langer een resolver dit record in zijn cache mag houden voordat hij het opnieuw vraagt.
Draai dezelfde vraag twee keer en kijk:
$ dig +noall +answer petermartin.nl
petermartin.nl. 408 IN A 23.88.98.40
$ dig +noall +answer petermartin.nl # three seconds later
petermartin.nl. 405 IN A 23.88.98.40
Het getal telt af. Dat is het duidelijkst mogelijke bewijs dat je een gecachet antwoord leest: de cache vertelt je hoeveel van zijn leven er nog over is. Vraag het in plaats daarvan de autoritatieve server en je krijgt de ingestelde waarde van de zone, die elke keer hetzelfde blijft.
Dit aftellen is ook het eerlijke antwoord op "hoe lang duurt DNS-propagatie". Er is geen propagatie. Er is alleen een verzameling caches, die elk een record vasthouden tot hun eigen TTL afloopt.
Daarom verlaag ik, als ik weet dat er een DNS-wijziging aankomt, de TTL een dag van tevoren en laat ik hem verder met rust. Het voelt alsof je niets doet, en dat is precies de bedoeling: tegen de tijd dat ik de echte wijziging doorvoer, heeft elke cache die ertoe deed zijn langlevende kopie al weggegooid en vervangen door een die na vijf minuten verloopt. De omschakeling duurt dan minuten in plaats van een dag, en ik heb het zien gebeuren in plaats van gehoopt dat het gebeurde.
De volgorde doet er meer toe dan het getal. De TTL verlagen op hetzelfde moment dat je het record wijzigt levert niets op, want de caches die het oude antwoord vasthouden kregen de oude TTL mee en houden die hoe dan ook de volle termijn aan. De nieuwe korte waarde bereikt ze pas als die termijn afloopt.
De wachttijd wordt dus bepaald door de waarde die je vervangt, niet door de waarde waar je naartoe gaat. Kijk waar je werkelijk mee te maken hebt voordat je de dag inplant:
$ dig @chelsea.ns.cloudflare.com petermartin.nl +noall +answer
petermartin.nl. 300 IN A 23.88.98.40
Vraag het de autoritatieve server, niet een cache, anders lees je een getal dat al aan het aftellen is. Een zone op 3600 heeft een uur nodig voordat de lage TTL overal staat, en een dag is een comfortabele marge. Een zone die nog op de traditionele 86400 staat heeft een volle dag nodig, dus "de dag ervoor" betekent precies dat, en een paar uur extra kost niets.
Twee losse dingen bepalen hoe snel een wijziging live gaat, en het helpt ze uit elkaar te houden. Het eerste is hoe snel je DNS-provider de wijziging over zijn eigen naamservers publiceert. Het tweede is hoe lang elke cache ter wereld het vorige antwoord mag vasthouden, en dat is de TTL. Het tweede beheers je zelf; het eerste is aan de provider.
Die eerste helft is de reden dat ik de meeste domeinen die ik beheer bij Cloudflare onderbreng. Een wijziging staat binnen seconden op hun autoritatieve servers in plaats van te wachten op een zone-transfercyclus, en al die servers antwoorden vanaf hetzelfde anycast-adres, dus er is geen moment waarop de ene naamserver de wijziging heeft en de andere niet. Hun standaard-TTL is ook kort: de 300 seconden uit de controle hierboven is waarmee elk Cloudflare-domein in dit artikel antwoordt.
Vijf minuten is een comfortabele standaard, en die haalt het planningsprobleem uit de vorige alinea's stilletjes weg. Een zone die al op 300 staat heeft niets om een dag van tevoren te verlagen, dus een ongeplande wijziging, het soort dat je doet omdat er iets stuk is en niet omdat het ingepland stond, is nog steeds klaar in de tijd die het kost om koffie te zetten. Elke provider die snel publiceert en een verstandige standaard-TTL heeft doet dit werk; het punt is dat je weet op welke van de twee je wacht als een wijziging traag lijkt. Sectie 6.4 laat zien hoe je die eerste helft zelf controleert, door elke autoritatieve server om zijn serienummer te vragen.
Zijn seconden lastig te lezen, vraag dan om eenheden:
$ dig +ttlunits +noall +answer petermartin.nl
petermartin.nl. 8m17s IN A 23.88.98.40
5.7 Wat moet de TTL nu eigenlijk zijn?
Dit is de vraag die me over DNS vaker gesteld wordt dan welke andere ook, en de meeste antwoorden zijn folklore. Met dig vervang je die folklore door metingen. Vraag een handvol goed beheerde domeinen wat zij publiceren, rechtstreeks bij hun eigen autoritatieve servers:
$ ns=$(dig +short google.com NS | head -1)
$ dig @$ns google.com A +noall +answer
google.com. 300 IN A 192.178.25.206
Het adres dat je terugkrijgt zal van het mijne verschillen, want Google antwoordt met wat het dichtstbij is. De tweede kolom niet: dat is een gepubliceerde instelling, en daar is het ons om te doen.
Herhaal dat voor een paar domeinen en er tekent zich een duidelijk patroon af. Dit zijn echte waarden, gemeten bij de bron:
| Domein | A | NS | MX | TXT |
|---|---|---|---|---|
google.com |
300 | 345600 | 300 | 300 |
wikipedia.org |
180 | 172800 | 300 | 600 |
github.com |
60 | 3600 | 300 | 300 |
nu.nl |
20 | 3600 | 3600 | 900 |
joomla.org |
300 | 86400 | 300 | 300 |
Twee dingen springen eruit. Niemand gebruikt nog een lange TTL op een adresrecord: de hele kolom zit tussen twintig seconden en vijf minuten. En NS-records zijn juist het omgekeerde, gemeten in dagen, met Google op vier dagen. Er is dus geen enkele beste TTL. Het getal hangt af van wat dat specifieke record moet kunnen.
Een hoge TTL koopt weerbaarheid. Dit is het voordeel dat mensen vergeten. Vallen je autoritatieve naamservers uit, dan blijft elke resolver met een gecachete kopie antwoorden tot die verloopt, dus een lange TTL is een buffer tegen storingen. Het scheelt ook aanvragen, wat uitmaakt als je provider per aanvraag rekent, en het bespaart een nieuwe bezoeker een recursieve lookup.
Een lage TTL koopt controle. Je kunt een site verhuizen, uitwijken naar een reserveserver of een fout terugdraaien en het internet volgt binnen minuten. Het is wat uitwijken op basis van healthchecks en geografische verdeling uberhaupt laat werken, en het beperkt de schade als je iets fout doet.
De afweging is in de loop der jaren verschoven. DNS is goedkoop en wordt vanaf anycast-netwerken geleverd, dus de aanvraagkosten van een lage TTL zijn voor een gewone site vrijwel verwaarloosbaar. Wat je werkelijk opgeeft is de storingsbuffer. RFC 8767 uit 2020 verzacht zelfs dat, door resolvers verlopen records te laten serveren als de bron onbereikbaar is, al doet niet elke resolver dat.
Dit is wat ik instel, en waarom:
| Record | TTL | Reden |
|---|---|---|
A, AAAA |
300 | Vijf minuten. Wendbaar genoeg voor een ongeplande verhuizing, en dezelfde waarde die het merendeel van de tabel hierboven gebruikt |
NS |
86400 | Houd lang. Ze veranderen bijna nooit, en hier betaalt de storingsbuffer zich echt uit |
MX |
3600 | Verzendende servers proberen het uren opnieuw, dus een korte TTL levert weinig op |
TXT (SPF, DKIM, DMARC) |
3600 | Wijzigingen zijn gepland, nooit urgent |
CAA |
3600 | Wordt gelezen bij het uitgeven van een certificaat, niet bij elk bezoek |
SOA minimum |
300 tot 900 | De negatieve TTL. Houd hem laag, anders blokkeert een gecachet "nee" een record dat je net aangemaakt hebt, zoals sectie 5.10 uitlegt |
| Tijdens een migratie | 300, of 60 | Zet hem een dag van tevoren, verhuis, en zet hem daarna terug |
Twee uitzonderingen zijn het benoemen waard. Wijzen je records naar een proxy of CDN, dan doet de TTL er nauwelijks toe, want het adres dat je publiceert blijft hetzelfde en de routeringsbeslissingen vallen boven DNS. En draai je uitwijk die van DNS afhangt, dan heb je 60 seconden of minder nodig, met de aantekening dat clients en tussenliggende resolvers zich daar niet allemaal aan houden.
Tot slot wat perspectief op het advies dat je elders vindt. RFC 1912, uit 1996, adviseert een TTL van een tot vijf dagen, en beschrijft de routine om hem vooraf te verlagen bijna woordelijk: zet de waarde omlaag, wacht de vorige uit, voer de wijziging door, en zet hem daarna weer omhoog. De procedure is dertig jaar oud en nog steeds precies goed. De getallen zijn dat niet, althans voor adresrecords, en de tabel hierboven is het bewijs. Noemt een stuk DNS-advies een waarde, kijk dan wat het internet werkelijk doet voordat je het volgt.
5.8 Het aftellen volgen met watch
Dit is de gewoonte waar ik na het wijzigen van een record het meest op leun, en die van wachten iets maakt dat je echt kunt zien. Het commando watch draait elk commando met een vast interval opnieuw en tekent het scherm opnieuw, dus richt je het op dig, dan krijg je een live beeld van de cache die leegloopt:
$ watch -n 5 dig +noall +answer petermartin.nl
De -n 5 zet het interval op vijf seconden. Voeg -d toe (kort voor differences) en watch markeert wat er sinds het vorige beeld veranderd is, waardoor de bewegende TTL uit de regel springt.
Zo zien die beelden eruit, hier achter elkaar afgedrukt zodat je de hele gebeurtenis op de pagina ziet:
12:34:18 petermartin.nl. 11 IN A 23.88.98.40
12:34:23 petermartin.nl. 6 IN A 23.88.98.40
12:34:28 petermartin.nl. 1 IN A 23.88.98.40
12:34:33 petermartin.nl. 600 IN A 23.88.98.40 <- expired, fetched again
12:34:38 petermartin.nl. 594 IN A 23.88.98.40
Die sprong omhoog is het moment waarop de gecachete kopie verliep en de resolver het opnieuw ging vragen. Heb je net een domein naar een nieuwe server laten wijzen, dan is dat precies het beeld waarin het oude IP-adres door het nieuwe vervangen wordt. In plaats van een browser te verversen en je af te vragen wat er gebeurt, kijk je hoe het getal naar nul zakt, en weet je precies wanneer je moet controleren.
Let op een detail in die beelden, want dit is het soort ding dat mensen een middag kost. Het record kwam terug met 600, maar de zone is gepubliceerd met een TTL van 300:
$ dig @chelsea.ns.cloudflare.com petermartin.nl +noall +answer # the source
petermartin.nl. 300 IN A 23.88.98.40
$ dig @1.1.1.1 petermartin.nl +noall +answer # a public resolver
petermartin.nl. 300 IN A 23.88.98.40
$ dig +noall +answer petermartin.nl # my own router
petermartin.nl. 556 IN A 23.88.98.40
De router op mijn eigen bureau deelt antwoorden uit met een langere levensduur dan de zone vroeg. Consumentenrouters en sommige resolvers van providers doen dit, en houden records langer vast dan hun opgegeven TTL om zichzelf werk te besparen. Je zorgvuldig verlaagde TTL is een verzoek, geen garantie, en het laatste kastje tussen jou en het internet kan hem stilletjes negeren. Sectie 7.5 behandelt de truc die ik gebruik om precies hier omheen te komen.
Een kwestie van beleefdheid: kies een verstandig interval. watch gebruikt standaard twee seconden, en dat een uur lang op andermans autoritatieve naamservers richten is niet netjes. Vijf of tien seconden vertelt je alles wat je nodig hebt.
5.9 Een SOA-record leesbaar maken: +multiline
Het SOA-record propt twee namen en vijf getallen op een regel, en niemand onthoudt de volgorde:
$ dig +noall +answer petermartin.nl SOA
petermartin.nl. 1800 IN SOA chelsea.ns.cloudflare.com. dns.cloudflare.com. 2411557357 10000 2400 604800 1800
De optie +multiline klapt records uit in een becommentarieerde, ingesprongen vorm. Voor SOA is dat een verademing:
$ dig +multiline +noall +answer petermartin.nl SOA
petermartin.nl. 1789 IN SOA chelsea.ns.cloudflare.com. dns.cloudflare.com. (
2411557357 ; serial
10000 ; refresh (2 hours 46 minutes 40 seconds)
2400 ; retry (40 minutes)
604800 ; expire (1 week)
1800 ; minimum (30 minutes)
)
Het serienummer is het getal om te onthouden. Elke keer dat een zone verandert moet het serienummer omhoog, en secundaire naamservers gebruiken het om te bepalen of ze een verse kopie moeten ophalen. Heb je een record gewijzigd en serveren de secundaire servers nog steeds de oude gegevens, vergelijk dan eerst de serienummers over de servers heen. Sectie 6.4 laat zien hoe je dat in een commando doet.
Het tweede veld, dns.cloudflare.com., ziet eruit als een hostnaam maar is een e-mailadres waarbij de eerste punt de plaats van de @ inneemt. Het is een stukje syntaxis uit de jaren tachtig waar iedereen precies een keer over struikelt.
5.10 "Het bestaat niet" wordt ook gecachet
Het laatste SOA-veld, minimum, verdient een eigen alinea, want de naam is misleidend. Vroeger betekende het een minimale TTL voor de zone. Sinds RFC 2308 uit 1998 betekent het iets heel anders: het is de negatieve cache-TTL, de tijd dat een resolver mag onthouden dat iets niet bestaat.
Je kunt dat zien gebeuren. Een negatief antwoord heeft geen antwoordsectie, dus zet de server in plaats daarvan het SOA van de zone in de autoriteitssectie, en de TTL van dat record is hoe lang het "nee" geldig is:
$ dig @1.1.1.1 nosuch.example.com +noall +comments +authority
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13792
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; AUTHORITY SECTION:
example.com. 1800 IN SOA elliott.ns.cloudflare.com. dns.cloudflare.com. 2411783310 10000 2400 604800 1800
Die 1800 aan het eind is het veld minimum, dus dit "nee" mag dertig minuten gecachet worden. Dat het SOA in de autoriteitssectie opduikt is op zichzelf het signaal: zie je het daar staan met een leeg antwoord, dan kijk je naar een negatief antwoord en krijg je te horen hoe lang het blijft plakken.
Het praktische gevolg zet mensen voortdurend op het verkeerde been, en het is het spiegelbeeld van het TTL-probleem uit de vorige sectie. Je voegt een record toe dat ontbrak, je vraagt het op, en het ontbreekt nog steeds. Er is niets stuk: een resolver vroeg het op voordat jij de wijziging doorvoerde, cachete het "nee", en vraagt het pas opnieuw als de negatieve TTL afloopt. Het bewijs kost een commando, want de autoritatieve server heeft geen cache om te raadplegen:
$ dig @chelsea.ns.cloudflare.com newrecord.petermartin.nl +short # the source
$ dig @1.1.1.1 newrecord.petermartin.nl +short # a cache
Antwoordt de eerste wel en de tweede niet, dan zit je een gecachet negatief antwoord uit en ben je geen record aan het repareren. Dit is ook waarom het aanmaken van het DNS-record voordat er iets naar vraagt de kleine moeite waard is: niets kan een "nee" cachen voor een naam die nog niemand opgevraagd heeft.
Naar boven6. Gevorderde toepassingen
6.1 De delegatie volgen: +trace
Normaal vraag je het een resolver en doet die al het werk. Met +trace doet dig het werk zelf: het begint bij de rootservers en loopt de delegatieketen af, waarbij het elke stap afdrukt. Het is het leerzaamste dat je op een domein kunt loslaten.
$ dig +trace petermartin.nl
. 39987 IN NS b.root-servers.net.
. 39987 IN NS f.root-servers.net.
;; Received 239 bytes from 127.0.0.53#53(127.0.0.53) in 14 ms
nl. 172800 IN NS ns1.dns.nl.
nl. 172800 IN NS ns3.dns.nl.
nl. 172800 IN NS ns4.dns.nl.
nl. 86400 IN DS 17153 13 2 C5DFDDC91E75...
;; Received 596 bytes from 170.247.170.2#53(b.root-servers.net) in 15 ms
petermartin.nl. 3600 IN NS chelsea.ns.cloudflare.com.
petermartin.nl. 3600 IN NS finley.ns.cloudflare.com.
;; Received 275 bytes from 185.159.199.200#53(ns4.dns.nl) in 10 ms
petermartin.nl. 300 IN A 23.88.98.40
;; Received 169 bytes from 162.159.38.177#53(chelsea.ns.cloudflare.com) in 6 ms
Lees het als een verhaal in vier stappen. Een rootserver verwijst door naar de servers voor .nl. Het .nl-register verwijst door naar Cloudflare. Cloudflare antwoordt met het adres. Elke regel ;; Received noemt de server die het blok erboven geproduceerd heeft.
Hier worden delegatieproblemen zichtbaar. Wijzen de NS-records bij het register naar naamservers die de zone niet hosten, dan stopt de trace daar, en helpt geen enkele wijziging bij je nieuwe provider.
Twee details zie je makkelijk over het hoofd. +trace zet +dnssec automatisch aan, en daarom verschijnen er DS- en RRSIG-records. En de allereerste stap gebruikt nog steeds je eigen resolver om de rootservers te vinden; alles daarna is dig dat rechtstreeks met de autoritatieve servers praat.
6.2 Glue-records en de twee sets NS-records
De trace hierboven sloeg iets over. Toen de .nl-servers de naamservers van Cloudflare noemden, hoe vindt een resolver die dan? Meestal door ze op te zoeken, en dat gaat prima als ze in een andere zone staan. Maar denk aan een domein waarvan de naamservers in zichzelf staan:
google.com. NS ns1.google.com.
Om ns1.google.com te bereiken moet je de servers voor google.com vragen, en om die te vinden moet je ns1.google.com bereiken. Dat is een cirkel, en DNS doorbreekt hem met glue-records: adresrecords die de bovenliggende zone samen met de delegatie meegeeft, puur zodat de keten door kan lopen. Vraag het een .com-server en je ziet ze binnenkomen:
$ dig @a.gtld-servers.net google.com NS +noall +authority +additional
google.com. 172800 IN NS ns2.google.com.
google.com. 172800 IN NS ns1.google.com.
google.com. 172800 IN NS ns3.google.com.
google.com. 172800 IN NS ns4.google.com.
ns2.google.com. 172800 IN A 216.239.34.10
ns1.google.com. 172800 IN A 216.239.32.10
ns3.google.com. 172800 IN A 216.239.36.10
ns4.google.com. 172800 IN A 216.239.38.10
De NS-records zijn de delegatie; de A-records eronder zijn de glue. Het echte antwoord bevat ook een AAAA-record per server, hier weggelaten om ruimte te sparen. Vergelijk nu een domein waarvan de naamservers elders staan. Er is geen cirkel te doorbreken, dus stuurt de bovenliggende zone helemaal geen glue mee:
$ dig @ns1.dns.nl petermartin.nl NS +noall +authority +additional
petermartin.nl. 3600 IN NS finley.ns.cloudflare.com.
petermartin.nl. 3600 IN NS chelsea.ns.cloudflare.com.
Beide antwoorden zijn correct. Glue is geen kwaliteitssignaal; het verschijnt alleen als het nodig is. Verouderde glue is echter een echt en vervelend probleem: hernummer je een naamserver die in zijn eigen zone staat en werk je het record bij zonder het register te informeren, dan blijft de bovenliggende zone het oude adres uitdelen en blijft een deel van het internet aankomen bij een server die er niet meer is.
Dit leidt tot de controle die de meeste delegatieraadsels oplost. Er zijn twee sets NS-records, een bij de bovenliggende zone en een in de zone zelf, en niets dwingt ze het eens te zijn. Vraag beide kanten apart:
$ dig @ns1.dns.nl petermartin.nl NS +noall +authority # what the parent says
petermartin.nl. 3600 IN NS finley.ns.cloudflare.com.
petermartin.nl. 3600 IN NS chelsea.ns.cloudflare.com.
$ dig @chelsea.ns.cloudflare.com petermartin.nl NS +short # what the zone says
chelsea.ns.cloudflare.com.
finley.ns.cloudflare.com.
Lees ze als sets, niet als lijsten: de volgorde verschilt tussen de twee antwoorden en betekent niets, precies zoals sectie 5.3 beschreef.
Deze twee zijn het eens, en dat is wat je wilt. Zijn ze het niet eens, dan wint de lijst van de bovenliggende zone voor de rest van de wereld, want dat is de lijst die resolvers volgen. Een zone kan dus perfect ingericht zijn en toch onbereikbaar zijn voor de helft van de bezoekers, en geen enkele wijziging bij de DNS-provider verandert dat. De oplossing ligt bij de registrar.
Een domein heeft twee antwoorden op "welke naamservers?": dat van de bovenliggende zone en dat van zichzelf. Elk verwarrend delegatieprobleem zit ergens in het gat daartussen, en met
digzie je ze allebei.
6.3 De autoritatieve server rechtstreeks vragen
Dit is de controleprocedure die ertoe doet. Vraag eerst wie autoritatief is, vraag daarna een van die servers, en let op de vlag aa in het antwoord:
$ dig +short petermartin.nl NS
chelsea.ns.cloudflare.com.
finley.ns.cloudflare.com.
$ dig @chelsea.ns.cloudflare.com petermartin.nl +noall +comments +answer
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38772
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; ANSWER SECTION:
petermartin.nl. 300 IN A 23.88.98.40
De aa in de vlaggenregel is waar het om gaat. Dat antwoord kwam van de bron, zonder cache ertussen, dus het is de waarheid van dit moment. De TTL van 300 is de ingestelde waarde van de zone en geen aftelling.
Negeer de waarschuwing. Die verschijnt omdat dig standaard om recursie vraagt en deze server, die alleen autoritatief is, dat niet aanbiedt. Zo hoort een autoritatieve naamserver zich precies te gedragen.
Je kunt stoppen met vragen, met +norecurse, dat de bit "recursion desired" wist en de waarschuwing laat verdwijnen. Naar een autoritatieve server gestuurd zegt het "antwoord alleen uit je eigen zones, ga het niet opzoeken". Naar een resolver die niet voor jou bedoeld is, legt het dat botweg bloot:
$ dig +norecurse +noall +comments example.com
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 28371
;; flags: qr ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
Dit is ook de nette manier om een cache te bekijken. Omdat de vraag nooit een lookup uitlokt, betekent een antwoord dat het record al gecachet was, en geen antwoord dat dat niet zo was.
6.4 Staan al mijn naamservers gelijk? +nssearch
Een zone staat meestal op meerdere naamservers, en die horen identieke gegevens te bevatten. De optie +nssearch zoekt elke autoritatieve server voor een domein en vraagt ze allemaal om hun SOA-record:
$ dig -4 +nssearch petermartin.nl
SOA chelsea.ns.cloudflare.com. dns.cloudflare.com. 2411557357 10000 2400 604800 1800 from server 162.159.38.177 in 6 ms.
SOA chelsea.ns.cloudflare.com. dns.cloudflare.com. 2411557357 10000 2400 604800 1800 from server 108.162.195.58 in 6 ms.
SOA chelsea.ns.cloudflare.com. dns.cloudflare.com. 2411557357 10000 2400 604800 1800 from server 172.64.35.58 in 6 ms.
Vergelijk de serienummers. Identieke serienummers betekenen dat de servers het eens zijn. Loopt een server achter, dan mislukt een zone-transfer, en deelt die server verouderde records uit aan de bezoekers die er toevallig terechtkomen. Dat levert het tergende symptoom "het werkt bij sommige mensen wel" op.
De -4 in dat commando dwingt IPv4 af. Zonder die vlag probeert dig ook de IPv6-adressen van elke naamserver, en op een machine zonder werkend IPv6 krijg je een scherm vol meldingen network unreachable voordat de nuttige uitvoer komt.
6.5 DNSSEC: +dnssec
DNSSEC ondertekent DNS-records zodat een resolver kan bewijzen dat er niet met een antwoord geknoeid is. De optie +dnssec zet de DO-bit (DNSSEC OK), die de server vraagt de handtekeningen mee te sturen:
$ dig @1.1.1.1 +dnssec +noall +comments +answer cloudflare.com
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33698
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; ANSWER SECTION:
cloudflare.com. 300 IN A 104.16.132.229
cloudflare.com. 300 IN A 104.16.133.229
cloudflare.com. 300 IN RRSIG A 13 2 300 20260822105534 20260820085534 34505 cloudflare.com. BHEr7q0Tdn...
Drie dingen bevestigen dat DNSSEC werkt: flags: do in de EDNS-regel betekent dat de vraag erom vroeg, het RRSIG-record is de handtekening zelf, en ad in de headervlaggen betekent dat deze resolver de handtekening gecontroleerd heeft en dat die klopte.
Draai hetzelfde commando zonder @1.1.1.1 op een gewone desktop en de vlag ad en het RRSIG-record kunnen allebei ontbreken. Dat is geen kapot domein; dat is de lokale stub-resolver die niet valideert en de records niet doorgeeft. Noem bij het testen van DNSSEC altijd een resolver waarvan je weet dat hij valideert.
Een mislukte DNSSEC heeft een kenmerkend symptoom: SERVFAIL van validerende resolvers, en een volstrekt normaal antwoord van de autoritatieve server. Er is een domein dat permanent kapot gehouden wordt om te testen:
$ dig @1.1.1.1 +short dnssec-failed.org
# nothing at all
$ dig @1.1.1.1 dnssec-failed.org | grep status
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 64920
$ dig @1.1.1.1 +cd +short dnssec-failed.org # +cd = checking disabled
96.99.227.255
Dat laatste commando is de diagnostische truc. Levert +cd een antwoord op waar de gewone vraag SERVFAIL geeft, dan zit het probleem in de DNSSEC-validatie en niet in de records zelf. Noem een validerende resolver expliciet, zoals hierboven: een lokale stub die niet valideert heeft niets uit te schakelen, en +cd verandert daar niets.
Voor het laatste woord gebruik je delv. Waar dig handtekeningen alleen toont, controleert delv ze en zegt dat op de eerste regel:
$ delv @1.1.1.1 cloudflare.com
; fully validated
cloudflare.com. 300 IN A 104.16.132.229
cloudflare.com. 300 IN RRSIG A 13 2 300 20260822110511 ...
$ delv @1.1.1.1 dnssec-failed.org
;; resolution failed: failure
De woorden fully validated zijn de bevestiging die je wilt zien nadat je DNSSEC op een zone aangezet hebt. Voeg +rtrace toe om elke ophaalactie te volgen die delv onderweg doet.
6.6 Zone-transfers: AXFR
Een zone-transfer kopieert een hele zone in een verzoek. Zo komen secundaire naamservers aan hun gegevens, en een correct ingestelde server staat het alleen toe vanaf de adressen die hij kent:
$ dig @chelsea.ns.cloudflare.com petermartin.nl AXFR
; Transfer failed.
Die weigering is het juiste en verwachte resultaat. Een publieke zone-transfer geeft een aanvaller elke hostnaam die je hebt, inclusief de namen waarvan je dacht dat ze privé waren, dus het is de moeite waard je eigen naamservers hierop te testen. Er is een domein dat het bewust toestaat, voor lesdoeleinden:
$ dig @nsztm1.digi.ninja zonetransfer.me AXFR +noall +answer
zonetransfer.me. 7200 IN SOA nsztm1.digi.ninja. robin.digi.ninja. 2019100801 172800 900 1209600 3600
zonetransfer.me. 7200 IN MX 0 ASPMX.L.GOOGLE.COM.
zonetransfer.me. 301 IN TXT "google-site-verification=tyP28J7JAUHA9fw..."
Zone-transfers gebruiken altijd TCP, omdat een hele zone zelden in een UDP-pakket past. dig wisselt het transport voor je om.
6.7 Als UDP niet genoeg is: +tcp en afkapping
DNS-vragen reizen normaal over UDP, dat snel is maar beperkt in omvang. Is een antwoord te groot, dan zet de server de vlag tc (truncated), en probeert dig het automatisch opnieuw over TCP. Je ziet dit bij grote verzamelingen TXT-records, forse DNSKEY-records en DNSSEC-antwoorden.
$ dig +tcp +noall +answer +stats example.com
example.com. 215 IN A 172.66.147.243
example.com. 215 IN A 104.20.23.154
;; Query time: 7 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (TCP)
;; MSG SIZE rcvd: 491
Het transport staat tussen haakjes op de regel SERVER, dus je kunt altijd zien welke gebruikt is. Met twee andere opties experimenteer je met de groottelimieten:
$ dig +bufsize=512 +ignore example.com # small buffer, do not retry over TCP
$ dig +bufsize=1232 example.com # the size most resolvers use today
De optie +ignore vertelt dig niet terug te vallen op TCP, zodat je het afgekapte antwoord zelf kunt zien. Met deze combinatie betrap je een firewall die DNS over UDP-poort 53 toestaat maar TCP-poort 53 blokkeert. Die verkeerde instelling werkt jarenlang prima en breekt dan op de dag dat je DNSSEC aanzet, omdat de antwoorden ineens groter worden.
6.8 Time-outs en pogingen
Standaard wacht dig vijf seconden per poging en doet het drie pogingen, en dat is lang wachten als een server gewoon dood is. Beide zijn instelbaar:
$ dig +time=2 +tries=1 @192.0.2.1 example.com # give up quickly
;; communications error to 192.0.2.1#53: timed out
Gebruik dit in monitoringscripts, waar snel falen nuttiger is dan langzaam falen. Let op het verschil tussen +tries (totaal aantal UDP-pogingen, standaard 3) en +retry (pogingen na de eerste, standaard 2). Ze beschrijven hetzelfde vanuit twee invalshoeken.
6.9 Zien wat een bezoeker elders ziet: +subnet
Contentdistributienetwerken en geografisch verdeelde opstellingen antwoorden anders afhankelijk van waar de bezoeker zit. Met de optie EDNS Client Subnet vraag je namens een ander netwerk:
$ dig @8.8.8.8 +subnet=145.53.0.0/24 +noall +comments +answer example.com
; CLIENT-SUBNET: 145.53.0.0/24/24
example.com. 300 IN A 104.20.23.154
Dit beantwoordt de vraag "waarom krijgt de klant in een ander land een ander IP-adres dan ik" zonder dat je iemand hoeft te vragen commando's voor je te draaien. Niet elke resolver honoreert de optie, en een volledig adres meegeven in plaats van een netwerk verraadt meer over de client dan je waarschijnlijk bedoelt, dus gebruik een /24.
6.10 Batchmodus en je eigen standaardinstellingen
De vlag -f (kort voor file) leest een lijst lookups uit een bestand, een per regel, precies geschreven zoals je ze zou typen:
$ cat domains.txt
petermartin.nl A
joomla.org MX
$ dig -f domains.txt +noall +answer
petermartin.nl. 483 IN A 23.88.98.40
joomla.org. 600 IN MX 1 aspmx.l.google.com.
joomla.org. 600 IN MX 5 alt1.aspmx.l.google.com.
Wil je altijd dezelfde opties, zet ze dan in ~/.digrc, een per regel of allemaal op een. dig past ze toe voordat het naar je opdrachtregelargumenten kijkt:
$ cat ~/.digrc
+noall +answer +ttlunits
Dat is handig en het is een valkuil. Elk script dat je schrijft erft die standaardinstellingen op jouw machine en gedraagt zich anders op een server zonder dat bestand. Scripts horen daarom -r mee te geven, waarmee dig ~/.digrc volledig negeert.
6.11 Versleutelde transporten: +tls en +https
Klassiek DNS reist in platte tekst, dus iedereen op het pad kan het lezen en aanpassen. Modern dig spreekt beide versleutelde alternatieven:
$ dig +tls @1.1.1.1 +short example.com # DNS over TLS, port 853
$ dig +https @1.1.1.1 +short example.com # DNS over HTTPS, port 443
Die zijn voor twee dingen nuttig: aantonen dat een resolver de versleutelde dienst die hij adverteert werkelijk aanbiedt, en controleren of een netwerk hem blokkeert. Voeg +tls-ca toe om het certificaat van de server te valideren in plaats van de verbinding alleen te versleutelen.
6.12 Uitvoer voor machines: +yaml
De normale uitvoer van dig met awk ontleden werkt tot de dag dat een recordtype zich anders opmaakt. Voor alles wat betrouwbaar moet zijn, vraag je om YAML:
$ dig +yaml example.com
- type: MESSAGE
message:
type: RECURSIVE_RESPONSE
message_size: 72b
socket_protocol: UDP
response_address: "127.0.0.53"
response_port: 53
response_message_data:
opcode: QUERY
status: NOERROR
id: 57077
flags: qr rd ra
Elk veld van het antwoord is een benoemde sleutel, inclusief de status en de vlaggen die +short weggooit. Gecombineerd met een gereedschap als yq maakt dit van dig een betrouwbare gegevensbron voor monitoring.
7. Iets wat de meeste gebruikers niet weten
7.1 dig ANY is bewust gestopt met werken
Oudere handleidingen stellen dig example.com ANY voor om alle records tegelijk te zien. Probeer het vandaag eens:
$ dig @8.8.8.8 +noall +answer example.com ANY
example.com. 321 IN HINFO "RFC8482" ""
Dat is geen fout en het domein is niet kapot. RFC 8482, gepubliceerd in 2019, staat een server toe ANY-vragen met een enkel minimaal record te beantwoorden in plaats van de zone uit te storten. Grote providers namen het snel over, omdat ANY-vragen enorme antwoorden op piepkleine verzoeken opleverden, wat ze tot een geliefde versterker voor denial-of-service-aanvallen maakte.
Het antwoord hierboven is de beleefde moderne weigering, en het record noemt zelfs de RFC die zichzelf uitlegt. Het praktische gevolg: om alle records te zien vraag je elk type bij naam op, of gebruik je een zone-transfer als je de server beheert.
Dit ene detail dateert een stuk DNS-advies onmiddellijk. Beveelt een handleiding ANY aan voor een overzicht, dan is die van voor 2019 en kan hij ook op andere punten verouderd zijn.
7.2 dig leest /etc/hosts nooit
Dit verrast mensen die al jaren Linux gebruiken. dig spreekt het DNS-protocol met een DNS-server. Het gebruikt de name service switch niet, dus /etc/hosts, mDNS, LDAP en elke andere bron die je systeem raadpleegt zijn er onzichtbaar voor.
Je browser, curl, ping en elke gewone toepassing gebruiken de volledige opzoekvolgorde. dig gebruikt daar precies een stap van. Daarom kan een naam overal werken en volgens dig toch "niet bestaan":
$ getent hosts xps # the operating system's answer
127.0.1.1 xps
$ dig @1.1.1.1 +short xps # a real DNS server's answer
# nothing: this name exists only in /etc/hosts
Er is een rimpel die het beeld vertroebelt. Op systemen met systemd-resolved leest de stub-resolver op 127.0.0.53 zelf /etc/hosts en antwoordt daaruit. Omdat die stub de standaardserver in /etc/resolv.conf is, lijkt een gewone dig de regels uit hosts toch te zien. Noem met @ een andere server en de illusie verdwijnt.
Als een naam wel voor je toepassing werkt maar niet voor
dig, of andersom, heb je geen DNS-fout gevonden. Je hebt het verschil gevonden tussen het besturingssysteem vragen en een naamserver vragen.getent hostsbeantwoordt de eerste vraag;digde tweede.
7.3 De exitcode betekent niet wat je aanneemt
Een shellscript test vanzelfsprekend of een commando geslaagd is. Bij dig is die test vrijwel betekenisloos:
$ dig this-does-not-exist-pm.nl > /dev/null
$ echo $?
0 # NXDOMAIN is still a successful query
$ dig dnssec-failed.org > /dev/null
$ echo $?
0 # so is SERVFAIL
De handleiding is er duidelijk over. Een nul betekent "er is een DNS-antwoord ontvangen", niet "de naam bestaat":
| Code | Betekenis |
|---|---|
0 |
Er is een antwoord ontvangen, inclusief NXDOMAIN |
1 |
Gebruiksfout |
8 |
Kon het batchbestand niet openen |
9 |
Geen antwoord van de server |
10 |
Interne fout |
Test in een script dus de uitvoer of de status, nooit alleen de exitcode:
$ if [ -n "$(dig +short example.com A)" ]; then echo "resolves"; fi
$ dig +noall +comments example.com | grep -q "status: NOERROR" && echo ok
De eerste vorm heeft zijn eigen randgeval: +short is leeg zowel voor een naam die niet bestaat als voor een naam die bestaat zonder dat recordtype. Maakt het verschil uit, lees dan de status.
7.4 dig negeert de zoeklijst, en al het andere gebruikt hem
Staat er in /etc/resolv.conf een regel search, dan kan ping server1 gewoon server1.internal.example.com bereiken, omdat de resolver het zoekdomein eraan plakt. dig doet dat bewust niet: de handleiding stelt dat de zoeklijst standaard niet gebruikt wordt.
$ dig +short server1 # asks for "server1" as a top-level name
$ dig +search +short server1 # now the search list is applied
Dat is een verstandige standaard voor een diagnosegereedschap, omdat je meestal precies de naam wilt testen die je getypt hebt. Het verklaart ook een specifieke verwarring op interne netwerken: de korte naam werkt overal behalve in dig. Voeg +search toe, of typ gewoon de volledige naam.
7.5 Andermans cache lenen met een VPN
Alles tot nu toe gaat ervan uit dat je de resolver met @ kunt kiezen. Dat dekt DNS, maar niet de vraag die een klant na een verhuizing meestal stelt: "werkt de site nu voor een gewone bezoeker?" Een browser doet meer dan een lookup, en jouw machine, jouw router en jouw provider hebben het oude antwoord allemaal gecachet zolang het ze uitkwam.
De truc die ik gebruik is een VPN aanzetten en de site gewoon laden. Een VPN verplaatst niet alleen je verkeer; hij geeft je machine meestal ook een andere resolver aan de andere kant van de tunnel, in een ander netwerk, met een cache die nog nooit naar jouw domein gevraagd is. Zo krijg je een werkelijk koude lookup en een echte pagina, in een browser, zoals een bezoeker het ervaart. Controleer waar je daadwerkelijk naartoe geschakeld bent:
$ resolvectl status | grep -A2 'Current DNS Server'
Current DNS Server: 192.168.1.1
DNS Servers: 192.168.1.1
$ dig +noall +stats petermartin.nl | grep SERVER
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
Draai die voor en na het verbinden. Veranderen de adressen niet, dan heeft de VPN je routering overgenomen maar DNS met rust gelaten, en lees je nog steeds dezelfde cache waaraan je probeerde te ontsnappen.
Dit is het praktische antwoord op het routerprobleem in sectie 5.8. Als het kastje op mijn eigen bureau een TTL van 300 seconden oprekt naar 600, laat geen enkele dig op die machine me zien wat de rest van de wereld ziet, want de verouderde kopie zit tussen mij en al het andere in. Een VPN stapt er volledig omheen.
Twee eerlijke beperkingen. Een VPN geeft je een extra uitkijkpunt, geen wereldwijd beeld, en zijn uitgang zit vaak in een groot datacenter in plaats van op een consumentenverbinding zoals je bezoekers hebben. En laat de VPN-client DNS naar je lokale resolver wijzen, een situatie die men een DNS-lek noemt, dan heb je helemaal niets veranderd. Controleer de regel SERVER voordat je conclusies trekt.
7.6 Weten waar dig ophoudt
Een deel van vakmanschap is weten welk gereedschap het overneemt. dig beantwoordt vragen over DNS, en houdt daar op.
| Wat je nodig hebt | Gebruik | Waarom |
|---|---|---|
| Hoe deze machine een naam opzoekt | getent hosts |
Gebruikt de echte opzoekvolgorde, inclusief /etc/hosts |
| Welke bovenliggende servers in gebruik zijn | resolvectl status |
DNS-servers per interface, DNSSEC-modus en de lokale cache |
| Of DNSSEC echt valideert | delv |
Voert de validatie zelf uit en legt de mislukking uit |
| Een snel antwoord, verder niets | host |
Korter te typen als je niet aan het debuggen bent |
| Of de dienst achter de naam werkt | curl, openssl s_client |
Een correct DNS-antwoord zegt niets over de webserver |
| Wat er over de lijn gaat | tcpdump port 53 |
Toont de vragen die je toepassingen stellen, en dat kan dig niet |
| Wat de wereld ziet | Een publieke controledienst | Vraagt vanuit veel landen tegelijk, en dat kan een machine niet |
Die laatste rij doet ertoe tijdens verhuizingen. Jouw machine en de drie publieke resolvers die je getest hebt zijn samen nog steeds maar vier uitkijkpunten van de duizenden.
Naar boven8. Best practices
- Lees altijd de regel
SERVER. Voordat je iets over een domein concludeert, moet je weten welke server het antwoord dat je leest geproduceerd heeft. De meeste verkeerde conclusies beginnen hier. - Vraag het twee keer: een cache en de bron. Stel de vraag aan een publieke resolver en aan de autoritatieve naamserver. Zijn ze het oneens, dan wacht je op een TTL en ben je geen record aan het repareren.
- Let op de vlag
aaals je een wijziging controleert. Zonder die vlag lees je een gecachete kopie, hoe vers die er ook uitziet. - Leer
+noall +answeren gebruik+shortalleen in scripts. Zodra er iets stukgaat, heb je de status en de vlaggen nodig die+shortweggooit. - Kijk naar het statuswoord voor je naar het antwoord kijkt.
NOERRORmet nul antwoorden,NXDOMAINenSERVFAILzijn drie verschillende problemen die er allemaal uitzien als "geen resultaat". - Stel elke TTL in op wat dat record moet kunnen. 300 voor adressen, 86400 voor
NS, 3600 voor mail- en tekstrecords. Een hoge TTL koopt weerbaarheid als je naamservers uitvallen; een lage koopt de mogelijkheid om je te bedenken. - Verlaag de TTL voor een migratie, niet tijdens. Zet hem een dag van tevoren op 300 seconden, verhuis, en zet hem daarna weer omhoog. Dit is de effectiefste DNS-gewoonte die er is.
- Kijk naar de omschakeling in plaats van te gokken.
watch -n 5 -d dig +noall +answer example.comlaat de TTL naar nul zakken en het nieuwe antwoord binnenkomen. Het maakt van "is het al veranderd?" iets dat je kunt zien. - Weet op welke helft je wacht. Publicatiesnelheid is van je DNS-provider, cachelevensduur is van je TTL. Bevestig de eerste met
-4 +nssearchvoordat je de tweede de schuld geeft. - Ga van je eigen netwerk af voordat je iets kapot verklaart. Een VPN, of een telefoon op mobiele data, geeft je een resolver die je oude antwoord nooit gecachet heeft. Je router kan een record ver voorbij zijn TTL vasthouden.
- Gebruik
+traceals een domein zich vreemd gedraagt. Delegatieproblemen zijn onzichtbaar in een gewone lookup en overduidelijk in een trace. - Controleer na elke verhuizing beide sets
NS-records. Vraag het de bovenliggende zone en vraag het de zone zelf. Resolvers volgen de bovenliggende zone, dus een verschil is onzichtbaar bij je DNS-provider en zeer zichtbaar voor je bezoekers. - Vergelijk serienummers met
-4 +nssearchals maar een deel van de bezoekers problemen heeft. Een achterlopende secundaire server levert precies dat symptoom op. - Maak een record aan voordat er iets naar vraagt. Niets kan een negatief antwoord cachen voor een naam die nog niemand opgevraagd heeft, en zo omzeil je de negatieve TTL volledig.
- Vertrouw nooit op de exitcode van
dig. Test in plaats daarvan de uitvoer of het statuswoord, en geef in scripts-rmee zodat een persoonlijke~/.digrchet resultaat niet kan veranderen. - Test je eigen naamservers op open zone-transfers.
dig @jouwserver jouwdomein AXFRhoort te mislukken. Lukt het wel, repareer het dan vandaag. - Grijp naar de documentatie. De handleiding is grondig, en geeft in zijn eigen BUGS-sectie eerlijk toe dat er waarschijnlijk te veel query-opties zijn.
$ man dig # the full manual page
$ dig -h # every flag and query option, on one screen
$ man resolv.conf # what dig reads when you do not name a server
$ man delv # the DNSSEC validating companion
Naar boven9. Veelgemaakte fouten
9.1 Veelvoorkomende misverstanden
| Misverstand | Werkelijkheid |
|---|---|
"dig laat zien hoe mijn computer een naam opzoekt." |
Het laat zien wat een DNS-server antwoordt. Je toepassingen gebruiken ook /etc/hosts en andere bronnen die dig volledig overslaat. Gebruik getent hosts voor die vraag. |
"Een lege +short betekent dat het domein niet bestaat." |
Het betekent ook SERVFAIL, of een naam die bestaat zonder dat recordtype. Alleen de statusregel maakt het onderscheid. |
"dig ANY toont alle records." |
Sinds RFC 8482 antwoorden de meeste grote providers met een enkel record HINFO "RFC8482". Vraag elk type bij naam op. |
| "De TTL in de uitvoer is de TTL van de zone." | Van een resolver is het de resterende tijd in die cache, aftellend. Vraag de autoritatieve server om de ingestelde waarde. |
| "DNS-propagatie duurt 24 tot 48 uur." | Er propageert niets. Caches verlopen, elk volgens de TTL die hij meekreeg. Een TTL van 300 seconden betekent vijf minuten. |
"NXDOMAIN is hoe een ontbrekende naam altijd gemeld wordt." |
Niet op ondertekende zones die compact denial of existence gebruiken. Een validerende resolver meldt dan NOERROR met nul antwoorden. Vraag de autoritatieve server zonder +dnssec om de echte NXDOMAIN te zien. |
| "Alleen positieve antwoorden worden gecachet." | Negatieve antwoorden ook, voor het aantal seconden in het SOA-veld minimum. Een record dat je net aangemaakt hebt kan nog steeds als ontbrekend gelezen worden. |
| "De naamservers bij mijn DNS-provider zijn degene die de wereld gebruikt." | De wereld volgt de NS-records in de bovenliggende zone, ingesteld bij je registrar. De twee lijsten kunnen verschillen, en de bovenliggende wint. |
"nslookup is verouderd, gebruik het dus nooit." |
ISC draaide dat plan in 2004 terug met BIND 9.3. Het wordt ondersteund. dig is beter voor debuggen omdat het statuscodes en vlaggen toont, niet omdat nslookup verdwijnt. |
"Als dig het juiste IP teruggeeft, werkt de site." |
DNS is een stap. De webserver, het certificaat, de firewall en de virtual host komen er allemaal nog achteraan. |
"dig stopt met een foutcode als een naam niet bestaat." |
Het stopt met 0, want er is een antwoord ontvangen. NXDOMAIN is een geslaagde vraag met een negatief antwoord. |
9.2 Valkuilen om te vermijden
@vergeten na een wijziging. Je resolver houdt de oude waarde vast voor de rest van zijn TTL. Vraag het de autoritatieve server voordat je concludeert dat de wijziging mislukt is.- Een kale hostnaam testen.
digpast desearch-lijst niet toe, dus een korte interne naam die in een browser werkt levert niets op. Gebruik de volledige naam of+search. - Een
TXT-record met aanhalingstekens kopieren.digdrukt SPF- en DKIM-waarden tussen aanhalingstekens af omdat dat het formaat op de lijn is. Lange waarden komen aan als meerdere stukken tussen aanhalingstekens die een resolver aan elkaar plakt, dus plak de aanhalingstekens niet in een controlepaneel. - Alleen het eerste blok van
+tracelezen. De interessante fout zit meestal in het midden, waar een niveau delegeert naar naamservers die niet antwoorden. - Een
CNAMEop de zone-apex zetten. De standaarden verbieden eenCNAMEnaast andere records, en de apex heeft altijdSOAenNS. Providers bieden in plaats daarvanALIASof CNAME-flattening aan, endiglaat je als resultaat een gewoonA-record zien. - Het domein de schuld geven van een
SERVFAIL. Probeer het opnieuw met+cdtegen een validerende resolver zoals@1.1.1.1. Verschijnt het antwoord, dan gaat het om DNSSEC-validatie, en dat betekent een gebroken vertrouwensketen en geen ontbrekend record. - Split horizon negeren. Een bedrijfsresolver kan een privé-antwoord serveren voor dezelfde naam die een publieke resolver anders beantwoordt. Beide zijn correct; het zijn verschillende zichten.
~/.digrclaten doorlekken naar scripts. Jouw standaardinstellingen staan niet op de server. Geef-rmee voor voorspelbaar gedrag.- Tijdens een migratie op een uitkijkpunt vertrouwen. Controleer meerdere publieke resolvers, en bedenk dat het nog steeds een minuscule steekproef van het internet is.
- Op IPv6-time-outs wachten. Hangt een commando met veel naamservers, voeg dan
-4toe. Op een machine zonder werkend IPv6 maakt dat alleen al van een minuut een seconde.
10. Samenvatting
Het commando dig heeft een smalle taak en voert die volledig uit: een vraag, een server, het hele antwoord. Dat is precies wat DNS-onderzoek vraagt.
digstaat voor domain information groper, een betekenis die in 2017 uit de handleiding verdween. Steve Hotz schreef de eerste versie eind jaren tachtig; het werd in 1990 met BIND 4 meegeleverd en in 2000 voor BIND 9 herschreven.- Het stuurt een DNS-vraag naar een naamserver en drukt het onbewerkte antwoord af. Het is alleen-lezen, dus je kunt het vrijuit op elk domein loslaten.
- Het woord
status:is het oordeel:NOERROR,NXDOMAIN,SERVFAILofREFUSED.NOERRORmetANSWER: 0betekent dat de naam bestaat maar geen record van dat type heeft. - De vlag
aabetekent dat het antwoord van de autoritatieve bron kwam en niet uit een cache. Kijk ernaar als je een wijziging controleert. - Lees altijd de regel
SERVER.127.0.0.53is de stub-resolver van je eigen machine, niet het internet. @serverkiest wie er antwoordt. Een publieke resolver vergelijken met de autoritatieve naamserver lost de meeste DNS-raadsels in twee commando's op.+shortis voor scripts,+noall +answeris om te lezen. De weergaveopties zijn vrij te combineren om precies de secties te tonen die je wilt.- Een recordregel bestaat uit vijf velden: naam, TTL, klasse, type, data. De klasse is vrijwel altijd
IN, en de punt aan het eind markeert een volledig gekwalificeerde naam. - Records met dezelfde naam, klasse en type vormen een RRset. Ze delen een TTL, DNSSEC ondertekent de set en niet elke regel, en hun volgorde betekent niets.
- De TTL-kolom telt af binnen een cache, en daarom verandert het getal tussen twee vragen. De TTL verlagen voor een migratie is de gewoonte die omschakelingen pijnloos maakt.
- Er is geen enkele beste TTL. Adressen willen 300,
NS-records willen een dag, mail- en tekstrecords willen een uur. Een hoge TTL houdt een site bereikbaar als de naamservers uitvallen; een lage laat je snel van gedachten veranderen. - Combineer
digmetwatchom een omschakeling te zien gebeuren:watch -n 5 -d dig +noall +answer example.comlaat de TTL naar nul zakken en het nieuwe antwoord het oude vervangen. - Een TTL is een verzoek, geen garantie. Consumentenrouters en sommige resolvers van providers houden records langer vast dan de zone vroeg, dus een VPN of een ander netwerk is de eerlijke manier om te zien wat bezoekers krijgen.
- Negatieve antwoorden worden ook gecachet. Het
SOAin de autoriteitssectie is het signaal, en het veldminimumis hoeveel seconden het "nee" blijft staan. - Glue-records zijn adressen die de bovenliggende zone meegeeft als een naamserver in de zone staat die hij zelf bedient, waarmee de cirkelvormige lookup doorbroken wordt. Er verschijnt geen glue als de naamservers elders staan.
- Een domein heeft twee sets
NS-records, die van de bovenliggende zone en die van zichzelf. Resolvers volgen die van de bovenliggende zone, dus vergelijk ze allebei als een delegatie zich misdraagt. - Op zones die compact denial of existence gebruiken meldt een ontbrekende naam
NOERRORin plaats vanNXDOMAINaan elke resolver die om DNSSEC vraagt. +traceloopt de delegatie vanaf de root af en legt problemen bloot die geen gewone lookup laat zien.-4 +nssearchvergelijktSOA-serienummers over alle autoritatieve servers.+dnssectoont de handtekeningen en de vlagad;+cdbewijst of eenSERVFAILeen validatiefout is;delvlegt uit waarom.dig ANYstort geen zone meer uit. RFC 8482 laat servers antwoorden met een enkel recordHINFO "RFC8482".digleest/etc/hostsnooit en past desearch-lijst niet toe.getent hostsbeantwoordt de vraag "hoe zoekt deze machine de naam op".- De exitcode is
0, zelfs bijNXDOMAIN. Test in scripts de uitvoer of het statuswoord, en voeg-rtoe zodat~/.digrcer niet tussen kan komen. - Twijfel je, draai dan
dig -hvoor de optielijst, ofman digvoor de details.
Dit is de snelle referentie die het bewaren waard is:
dig example.com full answer, with header and flags
dig +short example.com just the data
dig +noall +answer example.com the answer section, nicely readable
dig example.com MX a specific record type
dig -t MX -q example.com the same, unambiguous for scripts
dig -x 8.8.8.8 reverse lookup, address to name
dig @1.1.1.1 example.com ask a specific resolver
dig +short example.com NS who is authoritative
dig @ns1.example.com example.com ask the source, then look for the aa flag
dig +norecurse example.com is this already in the cache?
dig +trace example.com follow the delegation from the root
dig @a.gtld-servers.net example.com NS +noall +authority +additional
what the PARENT says, plus any glue
dig @ns1.example.com example.com NS +short
what the ZONE says; the two must agree
dig -4 +nssearch example.com compare SOA serials on every name server
dig +multiline example.com SOA the SOA timers, with labels
dig +ttlunits +noall +answer x.com TTLs in minutes and hours
ns=$(dig +short example.com NS | head -1); dig @$ns example.com +noall +answer
the TTL as published, not as cached
watch -n 5 -d dig +noall +answer example.com
watch the TTL count down to the cutover
dig +dnssec @1.1.1.1 example.com request signatures, check for the ad flag
dig +cd example.com skip validation, to identify a DNSSEC SERVFAIL
dig @ns1.example.com example.com AXFR zone transfer; this should fail
dig +tcp example.com force TCP
dig +time=2 +tries=1 example.com fail fast, for monitoring
dig -f domains.txt +noall +answer a list of lookups from a file
dig +yaml example.com structured output for scripts
dig -r ... ignore ~/.digrc
DNS-problemen hebben de naam mysterieus te zijn, maar het grootste deel van dat mysterie is caching plus een gereedschap dat de details verbergt. Zodra je de statusregel, de vlaggen en de serverregel leest, houden de antwoorden op dubbelzinnig te zijn.
Een domein dat overal hetzelfde wordt opgezocht, zijn mail bezorgt en zijn certificaten vernieuwt zonder dat iemand eraan denkt is geen geluk: dat is DNS met opzet ingericht. DNS is ook waar een verrassende hoeveelheid downtime stilletjes begint: de migratie die de helft van de bezoekers nooit gezien heeft, de mail die niet meer aankwam na een wijziging die niemand opgeschreven had, het certificaat dat niet vernieuwd wordt vanwege een CAA-record dat jaren geleden ingesteld is.
Geen van die dingen kondigt zichzelf aan, en ze zijn stuk voor stuk van buitenaf zichtbaar met de commando's uit dit artikel. Heeft een van je domeinen een delegatie die niemand sinds de laatste verhuizing gecontroleerd heeft, mailrecords die ooit eenmalig ingeplakt zijn en nooit meer bekeken, of een TTL die van elke wijziging een dag wachten maakt, dan loont het de zone van buitenaf te lezen voor de volgende wijziging in plaats van tijdens, zodat het antwoord overal ter wereld hetzelfde is.
Naar boven

Peter is Joomla specialist en Linux admin voor snelle, veilige en schaalbare websites.












