BIND9 : une configuration qui semble correcte mais provoque des NXDOMAIN intermittents

Cet article vous a aidé ?

Les NXDOMAIN intermittents sont le type de panne qui fait commencer les opérateurs aguerris à dire « c’est hanté » lors de réunions sérieuses. Une minute votre nom se résout ; la minute suivante la même requête depuis le même client renvoie NXDOMAIN, et vos outils de supervision ressemblent à un sismographe.

Ce n’est généralement pas « le DNS est en panne ». C’est le DNS qui fait exactement ce que vous lui avez accidentellement demandé. BIND9 est particulièrement performant pour ça : une configuration peut sembler propre, passer named-checkconf, servir la plupart des requêtes correctement, et pourtant produire des NXDOMAIN par rafales — parce que le cache, les vues, les forwarders et DNSSEC ont tous un état dont on sous-estime l’importance.

Ce que signifient réellement les NXDOMAIN intermittents

NXDOMAIN est une déclaration spécifique : « le nom n’existe pas ». Ce n’est pas « je ne peux pas atteindre un upstream ». Ce n’est pas « timeout ». Ce n’est pas « votre paquet a été perdu ». C’est pourquoi le NXDOMAIN intermittent est si révélateur : quelque chose, quelque part, a eu suffisamment confiance pour affirmer la non-existence.

Quand BIND renvoie NXDOMAIN, c’est généralement dans l’une de ces catégories :

  • NXDOMAIN autoritatif : BIND est autoritatif pour la zone et le nom n’existe réellement pas (ou votre fichier de zone indique qu’il n’existe pas).
  • Réponse négative mise en cache : BIND a appris auparavant NXDOMAIN (ou NODATA) et l’a mis en cache. Maintenant il le répète.
  • NXDOMAIN généré par une politique : Response Policy Zones (RPZ), vues, ACL ou logique spéciale provoquent un résultat de type NXDOMAIN.
  • NXDOMAIN fourni par un forwarder : votre forwarder renvoie NXDOMAIN et BIND lui fait confiance (parfois trop).
  • Comportement lié à DNSSEC : typiquement les échecs DNSSEC sont SERVFAIL, mais des interprétations erronées et le comportement des upstreams peuvent mener à des résultats ressemblant à NXDOMAIN, surtout quand vous mélangez validation et forwarders.

La partie « intermittent » provient typiquement d’un changement d’état sous vos pieds :

  • Entrées négatives du cache expirant à des moments différents (SOA MINIMUM / TTL négatif, comportement RFC 2308).
  • Plusieurs résolveurs ou nœuds anycast avec des contenus de cache divergents.
  • Vues sélectionnant des données différentes selon l’IP source, EDNS Client Subnet ou la clé TSIG.
  • Forwarders renvoyant des réponses incohérentes (ou un forwarder est défaillant et est choisi parfois).
  • Propagation DNS ou différences de timing de transfert de zone.
  • Différences de taille de paquet/fragmentation affectant seulement les réponses signées DNSSEC, poussant certaines requêtes sur TCP pour certains clients et pas pour d’autres.

Si vous essayez de « réparer les NXDOMAIN intermittents » en redémarrant named jusqu’à ce que ça s’arrête, vous ne réparez rien — vous jouez à la roulette du cache. C’est un de ces problèmes où soit vous instrumentez et raisonnez, soit vous donnez du temps au vide.

Playbook de diagnostic rapide

Faites ces étapes dans l’ordre. N’improvisez pas. L’objectif est d’identifier rapidement l’origine du NXDOMAIN : autoritatif, cache, politique ou upstream.

1) Confirmez ce que vous recevez réellement (et d’où)

  • Interrogez le résolveur suspect directement (pas via votre stub OS).
  • Capturez les drapeaux de réponse : aa, ra, ad, et la SOA dans la section authority.
  • Comparez avec un résolveur connu sain (un autre récursif ou une autre instance BIND).

2) Décidez : autoritatif ou récursif ?

  • Si le serveur répond avec aa, vous êtes en mode autoritatif : contenu de zone, transferts et vues.
  • Si la réponse ne contient pas aa mais contient ra, vous êtes en mode récursif : cache, forwarders, validation DNSSEC et politiques.

3) Vérifiez le cache négatif et la politique avant de toucher DNSSEC

  • Le cache négatif est la principale cause du « ça vient et part ».
  • Les incohérences RPZ/vues peuvent apparaître aléatoires quand les clients viennent de pools NAT différents ou d’adresses IPv6.

4) Validez le chemin upstream

  • Si vous utilisez des forwarders, testez chaque forwarder individuellement pour le nom en échec.
  • Exécutez dig +trace depuis une machine qui ne forwarde pas pour voir ce que le reste du monde renvoie.

5) Ensuite seulement, creusez DNSSEC/EDNS/MTU

  • Si les échecs se corrèlent avec des zones signées DNSSEC et la taille UDP, suspectez la fragmentation ou des middleboxes défaillants.

Idée paraphrasée de Werner Vogels (CTO d’Amazon) : « Vous le construisez, vous l’exploitez. » Si le DNS est « celui de quelqu’un d’autre », vous continuerez d’hériter d’échecs mystérieux.

La configuration qui semble correcte (et pourquoi elle trompe)

Voici le piège : BIND a suffisamment de réglages pour que deux modèles mentaux différents puissent tous deux « coller » à la même config. Une personne pense avoir construit un résolveur purement récursif. Une autre pense que c’est un « cache avec forwarding ». Quelqu’un d’autre croit que les vues servent seulement pour des zones split-horizon internes. Et quelqu’un a discrètement ajouté RPZ pour la « sécurité ».

Tout peut paraître fonctionner — jusqu’à ce que quelques noms vacillent.

Une configuration classique qui « semble correcte » mais favorise des NXDOMAIN intermittents contient ces ingrédients :

  • Forwarders au comportement mixte : un forwarder est un appliance corporate qui réécrit le DNS, un autre est un résolveur standard. BIND bascule ou fait du failover.
  • Vues : les clients internes obtiennent une vue, les clients VPN en obtiennent une autre, et les clients IPv6 tombent accidentellement dans la vue « par défaut ».
  • Cache négatif activé (comme prévu) avec un TTL négatif long à cause du SOA MINIMUM d’une zone ou d’une mauvaise lecture des sémantiques RFC 2308.
  • Paramètres de cache obsolètes (ou leur absence) provoquant des réponses différentes lors de dégradations upstream.
  • RPZ ou « listes de blocage » produisant des NXDOMAIN pour un sous-ensemble de requêtes selon le QNAME, le sous-réseau client ou la vue.
  • Multiples instances named derrière un VIP/anycast avec des caches et des timings de mise à jour non coordonnés.

BIND est déterministe. Votre environnement ne l’est pas.

Blague 1 : Le DNS est le seul système où « non-existant » peut être mis en cache comme fonctionnalité de performance. La réalité, mais avec des TTL.

Modes de panne qui produisent des NXDOMAIN intermittents

1) Cache négatif : NXDOMAIN qui persiste après correction de l’enregistrement

Le cache négatif n’est pas un bug d’implémentation ; c’est une partie du DNS. Quand un résolveur apprend que foo.example.com n’existe pas, il peut mettre ce fait en cache. Pour combien de temps ? Selon le SOA de la zone et les règles de cache négatif de la RFC 2308. En pratique, les opérateurs se font surprendre quand :

  • Ils créent un enregistrement peu après l’avoir interrogé (ou après qu’un contrôle automatisé l’ait interrogé avant que le provisioning ne soit terminé).
  • Le résolveur a mis en cache NXDOMAIN avec un TTL négatif plus long que prévu.
  • Ils n’ont « corrigé » qu’un seul serveur autoritatif, et un autre renvoie encore parfois NXDOMAIN.

L’intermittence vient de l’instance de résolveur ou du cache que vous atteignez, ou du fait que le TTL négatif expire à des moments différents dans une flotte.

2) Vues : bonnes données de zone, mauvais clients

Les vues sont puissantes et tranchantes. Elles sélectionnent des données et options de zone différentes selon l’identité du client (IP source, TSIG, correspondance ACL). Une défaillance subtile : les clients IPv6 ne correspondent pas aux ACL prévues et tombent dans une vue par défaut qui n’a pas la zone interne chargée. Ils obtiennent NXDOMAIN. L’IPv4 semble correct. Cela peut paraître intermittent quand les clients dual-stack basculent entre v4 et v6, ou quand des pools NAT répartissent les clients sur plusieurs plages sources.

3) Forwarders : « forward first » masquant des bizarreries upstream

Si vous utilisez forward first;, BIND essaiera les forwarders et, s’ils échouent (timeout/REFUSED), il retombera sur la récursion complète. Ça semble résilient. C’est aussi une source d’incohérence :

  • Si un forwarder renvoie NXDOMAIN rapidement (même à tort), BIND l’accepte et ne va pas recourir à la récursion.
  • Si un forwarder fait timeout, BIND peut recourir à la récursion et trouver la bonne réponse.
  • Donc le même nom peut alterner entre NXDOMAIN et NOERROR selon la santé du forwarder.

Dans les environnements régulés, les forwarders peuvent aussi appliquer des suffixes de recherche « utiles », du split-horizon, ou des listes de blocage. Si cette politique change, votre BIND devient le messager, et il est blâmé.

4) RPZ : des NXDOMAIN de politique difficiles à remarquer

RPZ peut réécrire les réponses en NXDOMAIN, NODATA, CNAME vers une page d’avertissement, ou autre. Si RPZ est appliquée seulement dans une vue, seuls certains clients verront NXDOMAIN. Si les mises à jour RPZ sont récupérées de manière asynchrone, un sous-ensemble de vos résolveurs peut avoir la politique chargée tandis que d’autres ne l’ont pas. Félicitations : NXDOMAIN intermittent.

5) Incohérence autoritative : propagation partielle, transferts cassés ou hypothèses de « master caché »

Si BIND est autoritatif (ou si vous avez des serveurs autoritatifs ailleurs), les NXDOMAIN intermittents signifient souvent que tous les serveurs autoritatifs ne sont pas d’accord. Causes courantes :

  • Un secondaire ne transfert pas les mises à jour (mismatch TSIG, pare-feu, problèmes de notify).
  • Les numéros de série ne sont pas incrémentés de manière fiable.
  • Les mises à jour dynamiques (DDNS) écrivent sur un seul serveur, mais les secondaires ne les récupèrent pas, ou les vues segmentent le chemin de mise à jour.

Les résolveurs choisissent différents serveurs autoritatifs selon le RTT et le cache. Vous voyez « parfois NXDOMAIN ». Ce n’est pas « parfois » : c’est « depuis ce serveur-là ».

6) Domaines de recherche + ndots : le problème « je n’ai pas demandé ce nom »

Beaucoup de NXDOMAIN sont auto-infligés par les clients. Avec des domaines de recherche et ndots, une requête pour api peut se transformer en api.corp.example, api.prod.corp.example, et enfin api. Le résolveur peut mettre en cache des réponses négatives pour ces expansions. Si votre application ne journalise que le nom court, vos logs DNS montrent un nom différent. Le rapport d’incident résultant ressemble parfois à une pièce surréaliste.

7) DNSSEC/EDNS/MTU : pas un générateur direct de NXDOMAIN, mais un amplificateur de chaos

Les échecs DNSSEC apparaissent habituellement comme SERVFAIL sur des résolveurs validants. Mais DNSSEC affecte les tailles de payload et le comportement du transport. Certains clients retentent en TCP ; d’autres non. Certains middleboxes suppriment des fragments. Un forwarder peut dégrader son comportement et renvoyer des réponses ressemblant à NXDOMAIN pour certains noms si son moteur de validation ou de politique est confus. L’aspect intermittent se corrèle souvent avec :

  • Quelques réseaux seulement ayant PMTUD cassé ou réassemblage de fragments défaillant.
  • Quelques noms seulement étant signés DNSSEC ou ayant de grandes réponses (beaucoup d’enregistrements, longues chaînes RRSIG).
  • Anycast ou flottes multi-résolveurs où seuls certains nœuds ont le chemin dégradé.

Tâches pratiques : commandes, sorties et décisions (12+)

Voici les actions que je veux vraiment que les gens exécutent pendant un incident. Chaque tâche inclut : la commande, ce que la sortie signifie, et la décision suivante à prendre.

Task 1: Query the resolver directly and read the flags

cr0x@server:~$ dig @127.0.0.1 www.example.com A +noall +answer +authority +comments
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NXDOMAIN, id: 53188
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; AUTHORITY SECTION:
example.com.	300	IN	SOA	ns1.example.net. hostmaster.example.com. 2026020401 3600 600 1209600 300

Sens : Statut NXDOMAIN, récursion disponible (ra), pas autoritatif (aa absent). C’est une réponse récursive (ou forwardée) et la SOA vous indique quelle zone a affirmé la non-existence.

Décision : Traitez d’abord comme un problème de cache/forwarder/politique. Si aa était présent, pivotez vers les données autoritatives et les transferts de zone.

Task 2: Compare against a known-good resolver

cr0x@server:~$ dig @9.9.9.9 www.example.com A +noall +answer +comments
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NOERROR, id: 4821
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

www.example.com.	60	IN	A	203.0.113.10

Sens : Le résolveur public obtient NOERROR avec un enregistrement A. Votre BIND qui renvoie NXDOMAIN n’est pas « Internet ». C’est votre pile.

Décision : Enquêtez sur le cache négatif, les vues, RPZ et les forwarders. Ne touchez pas encore à la zone autoritative.

Task 3: See whether your BIND is forwarding and to whom

cr0x@server:~$ sudo named-checkconf -p | sed -n '1,160p'
options {
	directory "/var/cache/bind";
	recursion yes;
	allow-recursion { 10.0.0.0/8; 192.168.0.0/16; };
	forwarders { 10.10.10.10; 10.10.10.11; };
	forward first;
	dnssec-validation auto;
};

zone "corp.example" IN {
	type master;
	file "/etc/bind/zones/db.corp.example";
};

Sens : Vous forwardez d’abord vers deux forwarders internes. Ça peut créer des différences intermittentes si les forwarders ne sont pas d’accord ou si l’un est malsain.

Décision : Testez chaque forwarder directement pour le nom en échec (tâche suivante). Si les forwarders renvoient NXDOMAIN, BIND n’est que le livreur.

Task 4: Query forwarders individually

cr0x@server:~$ dig @10.10.10.10 www.example.com A +noall +answer +authority +comments
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NXDOMAIN, id: 30211
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

example.com.	600	IN	SOA	ns1.example.net. hostmaster.example.com. 2026020401 3600 600 1209600 600
cr0x@server:~$ dig @10.10.10.11 www.example.com A +noall +answer +comments
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NOERROR, id: 6114
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

www.example.com.	60	IN	A	203.0.113.10

Sens : Vos forwarders sont en désaccord. Avec forward first, votre BIND peut parfois accepter le NXDOMAIN d’un forwarder et parfois obtenir la bonne réponse de l’autre.

Décision : Réparez ou retirez le forwarder défaillant. Si vous ne pouvez pas, envisagez forward only; (pour une politique stricte) ou supprimez le forwarding et effectuez la récursion vous-même (pour la justesse), mais ne mélangez pas « parfois politique » et « parfois réalité ».

Task 5: Check if the NXDOMAIN is being cached (negative cache)

cr0x@server:~$ sudo rndc dumpdb -cache
Dumping caches.
cr0x@server:~$ sudo grep -n "www.example.com" /var/cache/bind/named_dump.db | head
21483;www.example.com.	300	negative
21484;www.example.com.	300	IN	SOA	example.com. hostmaster.example.com. 2026020401 3600 600 1209600 300

Sens : BIND a une entrée négative mise en cache pour www.example.com avec 300 secondes restantes.

Décision : Si vous savez que le nom existe maintenant, videz-le pour arrêter de servir un NXDOMAIN obsolète, puis corrigez la cause upstream qui a injecté le NXDOMAIN.

Task 6: Flush a single name (surgical, not “flush everything”)

cr0x@server:~$ sudo rndc flushname www.example.com
flushed

Sens : Supprime les données mises en cache pour ce nom (y compris le cache négatif), forçant une nouvelle résolution.

Décision : Requêtez immédiatement. Si NXDOMAIN revient, ce n’est pas du « cache obsolète » — c’est upstream ou politique.

Task 7: Check if the NXDOMAIN is being rewritten by RPZ

cr0x@server:~$ sudo named-checkconf -p | grep -n "response-policy" -n
42:	response-policy { zone "rpz-block"; };
cr0x@server:~$ dig @127.0.0.1 www.example.com A +noall +answer +authority
example.com.	300	IN	SOA	ns.rpz.local. hostmaster.rpz.local. 2026020401 3600 600 1209600 300

Sens : La SOA dans la section authority provient d’un domaine lié à RPZ, pas de example.com. C’est une preuve accablante : la politique a généré ce « NXDOMAIN ».

Décision : Inspectez le contenu de la zone RPZ et la pipeline de mise à jour. Décidez si ce nom doit être bloqué. Sinon, corrigez le flux RPZ ou ajoutez des exceptions.

Task 8: Validate whether views are selecting different zone data

cr0x@server:~$ sudo named-checkconf -p | sed -n '1,220p' | grep -n "view\|match-clients\|zone \"corp.example\""
61:view "internal" {
62:	match-clients { 10.0.0.0/8; 192.168.0.0/16; };
80:	zone "corp.example" { type master; file "/etc/bind/zones/db.corp.example"; };
95:};
97:view "external" {
98:	match-clients { any; };
112:	zone "corp.example" { type master; file "/etc/bind/zones/db.corp.example.external"; };
130:};

Sens : Des clients différents peuvent obtenir des versions différentes de la même zone. Ce n’est pas automatiquement incorrect. C’est automatiquement risqué.

Décision : Confirmez quels clients correspondent à quelle vue (tâches suivantes) et si le fichier de zone « externe » omet intentionnellement des noms dont ont besoin les clients VPN/cloud.

Task 9: Query from different source addresses to reproduce view selection

cr0x@server:~$ dig @10.0.0.53 app.corp.example A +noall +answer +comments
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NOERROR, id: 15054
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

app.corp.example.	30	IN	A	10.20.30.40
cr0x@server:~$ dig @198.51.100.53 app.corp.example A +noall +answer +comments
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NXDOMAIN, id: 4490
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

Sens : Même logiciel de résolveur, adresse/chemin différent, réponse différente. C’est généralement des vues ou de la politique, pas de la « randomisation DNS ».

Décision : Décidez si app.corp.example doit être visible depuis l’extérieur. Si oui, corrigez la zone de la vue externe ou les règles match-clients.

Task 10: Verify authoritative consistency with +trace

cr0x@server:~$ dig +trace www.example.com A
; <>> DiG 9.18.24 <>> +trace www.example.com A
;; Received 811 bytes from 127.0.0.1#53(127.0.0.1) in 0 ms

example.com.	172800	IN	NS	ns1.example.net.
example.com.	172800	IN	NS	ns2.example.net.
;; Received 525 bytes from 192.0.2.53#53(a.root-servers.net) in 19 ms

www.example.com.	60	IN	A	203.0.113.10
;; Received 116 bytes from 203.0.113.53#53(ns1.example.net) in 24 ms

Sens : Le chemin autoritatif renvoie NOERROR. Si votre résolveur renvoie NXDOMAIN, le problème se situe entre votre résolveur et l’autorité : forwarders, cache, politique, ou chemin de résolution cassé.

Décision : Si des forwarders sont impliqués, réparez-les. Sinon, inspectez les logs du résolveur et le comportement du cache.

Task 11: Turn on targeted query logging (temporarily) to see the source of NXDOMAIN

cr0x@server:~$ sudo rndc querylog
query logging is now on
cr0x@server:~$ sudo journalctl -u bind9 -n 20 --no-pager
Feb 04 11:12:01 dns1 named[1234]: client @0x7f2a1c0 10.1.2.3#55214 (www.example.com): query: www.example.com IN A +E(0)K (10.10.10.10)
Feb 04 11:12:01 dns1 named[1234]: client @0x7f2a1c0 10.1.2.3#55214 (www.example.com): forwarding failed, response NXDOMAIN from 10.10.10.10

Sens : Le log montre explicitement le forwarding et l’upstream qui a renvoyé NXDOMAIN.

Décision : Arrêtez les débats. Réparez 10.10.10.10 ou retirez-le. Puis désactivez le query logging ; c’est bruyant en production.

Task 12: Check for SERVFAILs masked by client retries (and transport issues)

cr0x@server:~$ dig @127.0.0.1 dnskey example.com +dnssec +noall +comments +answer
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NOERROR, id: 38712
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

Sens : ad indique des données validées (quand le client l’a demandé et que le résolveur valide). Si vous ne voyez jamais ad là où vous l’attendez, la validation peut être désactivée ou échouer.

Décision : Si DNSSEC est en jeu et que les échecs se corrèlent avec des réseaux spécifiques, inspectez la taille EDNS et le fallback TCP (tâches suivantes). Même si ce n’est pas directement NXDOMAIN, ça peut déclencher un comportement de retry différent qui ressemble à de l’intermittence.

Task 13: Check EDNS UDP size and force TCP to test fragmentation hypotheses

cr0x@server:~$ dig @127.0.0.1 www.example.com A +dnssec +bufsize=4096 +noall +comments
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NOERROR, id: 19640
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
cr0x@server:~$ dig @127.0.0.1 www.example.com A +tcp +noall +comments +answer
;; Got answer:
;; ->>>HEADER<<<- opcode: QUERY, status: NOERROR, id: 28640
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

www.example.com.	60	IN	A	203.0.113.10

Sens : Si UDP échoue parfois mais TCP fonctionne toujours, vous avez probablement un problème de path MTU / fragmentation quelque part entre les clients et le résolveur, ou entre le résolveur et l’upstream.

Décision : Réduisez la taille UDP annoncée par le résolveur (ou corrigez le réseau). Ne « réglez » pas ça en désactivant DNSSEC partout à moins d’aimer les incidents futurs.

Task 14: Inspect BIND statistics for spikes in NXDOMAIN/negative answers

cr0x@server:~$ sudo rndc stats
Statistics dump file written to /var/cache/bind/named.stats
cr0x@server:~$ sudo sed -n '1,120p' /var/cache/bind/named.stats
+++ Statistics Dump +++
++ Incoming Requests ++
               18452 QUERY
++ Outgoing Requests ++
               10211 QUERY
++ Name Server Statistics ++
                1423 NXDOMAIN
                 211 SERVFAIL

Sens : Des comptes NXDOMAIN élevés peuvent être normaux (fautes de frappe, domaines de recherche), ou bien être votre incident. Associez cela au query logging ou à un filtre qname pour voir quels noms dominent.

Décision : Si les pics NXDOMAIN concernent un domaine/service unique, concentrez-vous là-dessus. S’ils sont larges, suspectez forwarder/politique/vues.

Task 15: Verify zone file correctness if authoritative

cr0x@server:~$ sudo named-checkzone corp.example /etc/bind/zones/db.corp.example
zone corp.example/IN: loaded serial 2026020401
OK

Sens : La zone se parse et se charge ; le serial est visible.

Décision : Si des NXDOMAIN intermittents se produisent et que vous êtes autoritatif, comparez les serials sur toutes les autorités. Un secondaire en retard est un coupable fréquent.

Task 16: Confirm secondaries have the same serial (authoritative consistency)

cr0x@server:~$ dig @ns1.corp.example corp.example SOA +noall +answer
corp.example.	300	IN	SOA	ns1.corp.example. hostmaster.corp.example. 2026020401 3600 600 1209600 300
cr0x@server:~$ dig @ns2.corp.example corp.example SOA +noall +answer
corp.example.	300	IN	SOA	ns1.corp.example. hostmaster.corp.example. 2026020317 3600 600 1209600 300

Sens : ns2 est en retard (serial plus ancien). Les résolveurs qui frappent ns2 peuvent obtenir NXDOMAIN pour des noms ajoutés récemment.

Décision : Réparez les transferts de zone (TSIG, allow-transfer, notify, pare-feu). Ne camouflez pas ça avec des TTL bas ; ça ne fait qu’accélérer l’arrivée de la douleur.

Erreurs courantes : symptôme → cause racine → correction

Cette section vous semblera familière en plein incident, parce que vous en avez déjà vu au moins deux dans votre carrière. Si ce n’est pas le cas, félicitations pour votre vie chanceuse.

1) « Ça se résout pour moi mais pas pour les utilisateurs »

Symptôme : Le personnel IT sur le réseau corp obtient NOERROR ; les utilisateurs distants/VPN/mobile obtiennent NXDOMAIN.

Cause racine : Vues ou split-horizon. Les utilisateurs distants tombent dans une vue différente (souvent dû aux adresses IPv6 ou aux pools NAT), qui n’a pas l’enregistrement ou a RPZ appliquée.

Correction : Auditez les ACL match-clients pour IPv4 et IPv6, et assurez-vous que les zones/politiques correctes existent dans toutes les vues prévues. Testez depuis des réseaux sources représentatifs, pas seulement depuis le serveur DNS lui-même.

2) « Nous avons ajouté l’enregistrement, mais c’est encore parfois NXDOMAIN »

Symptôme : Après provisionnement, certains clients obtiennent encore NXDOMAIN pendant des minutes à des heures.

Cause racine : Cache négatif. Le NXDOMAIN a été appris et mis en cache avant que l’enregistrement existe, et le TTL négatif est plus long que vous ne le pensiez.

Correction : Videz des noms spécifiques sur les résolveurs récursifs (rndc flushname) lors de bascules urgentes. À plus long terme : réduisez les TTL négatifs en concevant consciemment le SOA MINIMUM/TTL négatif, et évitez les vérifications préalables qui interrogent les noms avant qu’ils n’existent (ou isolez ces vérifications vers des résolveurs de staging).

3) « Ça échoue seulement le lundi (ou aléatoirement), et redémarrer BIND aide »

Symptôme : NXDOMAIN intermittent qui « disparaît » après un redémarrage.

Cause racine : Le reset du cache masque l’incohérence upstream : forwarders en désaccord, flux RPZ mis à jour de façon incohérente, ou un autoritatif désynchronisé.

Correction : Arrêtez de redémarrer comme remède. Identifiez quel upstream a généré le NXDOMAIN via le query logging ou le test des forwarders. Réparez la source ; ensuite les resets de cache deviendront rares et inutiles.

4) « Seuls certains enregistrements d’une zone échouent, les autres fonctionnent »

Symptôme : Une poignée de noms renvoient NXDOMAIN ; d’autres de la même zone se résolvent.

Cause racine : Wildcards et nœuds non-terminaux vides, ou l’enregistrement n’existe que dans une vue/un autoritatif. Autre cause fréquente : vous avez créé des enregistrements de type _service._tcp mais les clients interrogent d’autres types et créent une confusion NODATA/NXDOMAIN.

Correction : Vérifiez directement les réponses autoritatives. Inspectez les fichiers de zone pour délégations, wildcards et nœuds manquants. Vérifiez que toutes les autorités ont le même serial et les mêmes données.

5) « Ça marche en IPv4, cassé en IPv6 »

Symptôme : Les clients dual-stack voient un NXDOMAIN intermittent selon la pile utilisée.

Cause racine : ACLs de vues oubliant IPv6, différences de reachability upstream, ou enregistrements AAAA/glue manquants entraînant des chemins de résolution différents.

Correction : Rendre les ACL de vues explicitement dual-stack. Assurez-vous que les forwarders et hints racine sont atteignables en IPv6 si vous servez des clients v6. Testez avec dig -6 et comparez.

6) « Ça arrive seulement pour certains domaines publics »

Symptôme : Un sous-ensemble de domaines externes renvoie NXDOMAIN depuis votre résolveur, mais le reste se résout.

Cause racine : RPZ, filtrage DNS upstream, ou un forwarder cassé qui remappe en NXDOMAIN pour des raisons de « sécurité ».

Correction : Identifiez si la SOA dans la réponse NXDOMAIN pointe vers la vraie zone ou une zone de politique. Si c’est la politique, corrigez la politique. Si c’est le forwarder, remplacez-le ou reconfigurez-le. N’acceptez pas « l’appliance de sécurité l’a dit » sans audit.

Trois micro-histoires d’entreprise issues du terrain

Mini-histoire 1 : L’incident causé par une mauvaise hypothèse

L’entreprise avait deux résolveurs internes derrière un load balancer. L’équipe supposait qu’ils étaient « identiques », car ils avaient été construits par la même automatisation. Cette supposition a tenu pendant des mois, comme les suppositions le font souvent.

Puis un nouveau service interne a été lancé avec un nom d’hôte qui n’existait pas avant que la pipeline de déploiement ne le crée. Un health check — lancé tôt — a interrogé le nom de façon répétée. Pendant une brève fenêtre, les résolveurs ont appris NXDOMAIN et l’ont mis en cache. Peu après, l’enregistrement est apparu et a commencé à se résoudre… parfois. Certains clients frappaient le résolveur A (toujours en cache négatif NXDOMAIN), d’autres le résolveur B (cache déjà expiré). L’astreinte a vu un déploiement d’application instable.

Ils ont redémarré le membre du pool du load balancer qui « semblait mauvais ». Les symptômes ont disparu. Le postmortem a presque pris fin là, ce qui explique pourquoi on garde le même incident en abonnement.

Une semaine plus tard, c’est arrivé de nouveau. Cette fois, quelqu’un a comparé les champs SOA MINIMUM pour leur zone interne. Un résolveur avait une version de zone plus ancienne avec un TTL négatif plus long dû à un transfert secondaire obsolète. Pas identiques. Pas du tout quand ça compte.

La correction n’a pas été héroïque. Ils ont réparé les transferts, standardisé les paramètres SOA/TTL négatif, et changé le health check de déploiement pour n’interroger qu’après la création de l’enregistrement ou pour interroger un résolveur de staging. La mauvaise hypothèse était « nœuds identiques ». DNS fait vite mentir cette hypothèse.

Mini-histoire 2 : L’optimisation qui s’est retournée contre eux

Une autre organisation était fière de son « DNS rapide ». Ils ont activé des forwarders vers une couche de cache interne promettant faible latence et « filtrage sécurité ». Ils ont aussi mis forward first pour que BIND recoure à la récursion si le forwarder avait des soucis. Le meilleur des deux mondes, non ?

Ça a fonctionné — jusqu’à ce que le vendeur du forwarder pousse une mise à jour de politique. Un ensemble de domaines a commencé à renvoyer NXDOMAIN à cause d’erreurs de catégorisation. Parallèlement, le cluster de forwarders était légèrement surchargé ; parfois il mettait timeout. Dans ces cas, BIND retombait sur la récursion et renvoyait la bonne réponse. Ainsi les utilisateurs voyaient des NXDOMAIN intermittents selon que le forwarder répondait rapidement (à tort) ou lentement (pas du tout).

Le vendeur a insisté sur le fait qu’il n’y avait « pas de panne ». Leurs systèmes étaient up. Vrai. Les noms des clients étaient indisponibles, de manière intermittente. L’équipe BIND a dû jouer les adultes et prouver, avec des logs, que « des réponses rapides et fausses » étaient pires que des « réponses lentes et correctes ».

Ils ont basculé temporairement sur forward only pour rendre le comportement cohérent pendant qu’ils escaladaient le problème de politique. La cohérence a réduit les tickets immédiatement, même si cela signifiait « bloqué en permanence » pour ces domaines jusqu’à correction. Après la résolution, ils ont réévalué la nécessité de cette couche.

Blague 2 : La seule chose pire qu’une réponse DNS lente est une réponse rapide qui a confiance en elle mais est fausse.

Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une société financière tenait le DNS autoritatif pour quelques zones internes et une zone publique pour des endpoints clients. Ils avaient une routine : chaque changement de zone nécessitait un bump de serial, named-checkzone, et une vérification rapide du serial SOA sur toutes les autorités. Pas d’exception. C’était impopulaire auprès de ceux qui pensaient que DNS n’était « qu’un fichier texte ».

Un après-midi, une demande de changement a ajouté un nouvel endpoint client. Le primaire s’est mis à jour correctement. Un secondaire ne l’a pas fait. Mais parce que l’équipe vérifiait toujours les serials SOA, ils l’ont détecté en quelques minutes. Ils n’avaient pas encore reçu de plainte client.

La cause racine était banale : une règle de pare-feu avait été « nettoyée » la nuit précédente, et TCP/53 pour les transferts de zone avait été supprimé entre le primaire et ce secondaire. Le secondaire continuait de servir l’ancienne zone. Si cela avait atteint les clients, ils auraient vu des NXDOMAIN intermittents selon le serveur autoritatif choisi par leur résolveur.

L’équipe a restauré la règle de pare-feu, confirmé le transfert, et l’enregistrement est devenu cohérent globalement. La pratique ennuyeuse — vérification des serials — a évité un incident client. En ops, l’ennuyeux est souvent un synonyme d’« efficace ».

Faits intéressants et contexte historique

  • NXDOMAIN est standardisé : c’est le RCODE 3, signifiant « Name Error », et il est distinct de « no data » (NOERROR avec réponse vide).
  • Le cache négatif n’a pas toujours été courant : RFC 2308 a formalisé le comportement de cache négatif pour réduire les requêtes répétées inutiles pour des noms inexistants.
  • SOA MINIMUM a été réutilisé : historiquement, SOA MINIMUM servait de TTL par défaut ; plus tard, il a été associé aux sémantiques du TTL négatif.
  • BIND a longtemps été l’implémentation de référence : le comportement de BIND a influencé les attentes opérationnelles de l’industrie, pour le meilleur et parfois pour « pourquoi fait-il ça ? ».
  • Le split-horizon DNS est plus ancien que le cloud : les entreprises utilisent les vues/split-horizon bien avant que Kubernetes n’oblige tout le monde à gérer la découverte de services à la dure.
  • RPZ a été conçu pour la politique à grande échelle : il permet d’injecter des modifications de réponse sans toucher aux zones autoritatives, ce qui est puissant et facile à abuser.
  • DNSSEC a alourdi les réponses : la validation ajoute des enregistrements (RRSIG, DNSKEY, DS) qui augmentent la taille des réponses et rendent les problèmes de transport/chemin plus visibles.
  • Les résolveurs préfèrent UDP tant que possible : le DNS commence souvent par UDP/53 ; le fallback TCP existe, mais les piles clients et les middleboxes varient beaucoup.
  • « Autoritatif » est par zone, pas par serveur : un serveur peut être autoritatif pour une zone et récursif pour tout le reste, ce qui complique le dépannage de manière classique.

Listes de contrôle / plan étape par étape

Checklist A: Déterminer d’où vient le NXDOMAIN

  1. Exécutez dig @your-resolver name type +noall +answer +authority +comments.
  2. Notez : statut, présence de aa, présence de ra, et le nom propriétaire de la SOA dans AUTHORITY.
  3. Si la SOA correspond à la vraie zone : probablement un NXDOMAIN autoritatif réel ou mis en cache depuis l’autorité.
  4. Si la SOA ressemble à une zone RPZ/politique : NXDOMAIN généré par la politique.
  5. Si vous utilisez des forwarders : interrogez chaque forwarder directement et comparez.

Checklist B: Corriger sans dégâts collatéraux

  1. Videz seulement les noms impactés sur les résolveurs récursifs : rndc flushname.
  2. Si incohérence autoritative : vérifiez les serials SOA sur tous les serveurs autoritatifs et réparez les transferts.
  3. Si vues : assurez-vous que l’enregistrement existe dans les vues souhaitées, et que les ACL incluent les plages client IPv4 et IPv6.
  4. Si les forwarders sont en désaccord : retirez le mauvais ou corrigez sa politique/zone. Ne laissez pas « parfois faux » en rotation.
  5. Si RPZ : confirmez s’il s’agit d’un blocage légitime ; ajoutez des exceptions si nécessaire ; corrigez la synchronisation des flux.

Checklist C: Rendre la régression difficile

  1. Ajoutez une surveillance synthétique qui interroge chaque nœud résolveur directement, pas seulement le VIP.
  2. Alarmez sur les augmentations soudaines de NXDOMAIN pour des noms critiques spécifiques (pas sur le volume global NXDOMAIN).
  3. Surveillez la santé des forwarders indépendamment et retirez-les automatiquement s’ils retournent des absurdités pour un domaine canari.
  4. Pour les zones autoritatives, automatisez les vérifications de parité de serial SOA sur toutes les autorités.
  5. Gardez les définitions de vues minimales. Chaque vue est une branche dans votre arbre d’incident.

FAQ

1) Pourquoi les NXDOMAIN sont-ils intermittents au lieu d’être systématiquement faux ?

Parce que le DNS est distribué et mis en cache. Différents résolveurs, différents états de cache, différents upstreams, différentes vues. Votre système peut être « constamment incohérent ».

2) Comment savoir si BIND est autoritatif pour une zone ?

Interrogez et vérifiez le drapeau aa dans la réponse. Inspectez aussi named-checkconf -p pour la définition de zone. Si c’est type master ou type slave, il est autoritatif pour cette zone.

3) Quelle est la différence entre NXDOMAIN et NODATA ?

NXDOMAIN signifie que le nom n’existe pas du tout. NODATA est NOERROR mais réponse vide pour ce type (par exemple le nom existe mais n’a pas d’enregistrement A). Les deux peuvent être mis en cache négativement, et les deux peuvent casser des applications différemment.

4) DNSSEC peut-il provoquer des NXDOMAIN ?

Les échecs de validation DNSSEC produisent typiquement SERVFAIL sur des résolveurs validants. Mais DNSSEC augmente la taille des réponses et la complexité, ce qui peut déclencher des problèmes de transport ou des étrangetés de forwarder qui apparaissent comme des réponses erronées intermittentes, y compris des NXDOMAIN de moteurs de politique upstream.

5) Dois-je utiliser forward first ou forward only ?

Si vous avez besoin d’une application stricte de politique par les forwarders, utilisez forward only et acceptez que la politique soit la source de vérité. Si vous voulez la justesse et l’indépendance, ne forwardez pas du tout — effectuez la récursion directement. forward first peut créer un comportement incohérent quand les forwarders sont instables ou erronés.

6) Vider le cache est-ce une solution valide ?

Vider un nom spécifique est une atténuation valide quand le cache négatif est le problème immédiat. Vider tout le cache est un outil brutal qui masque les causes racines, augmente la charge upstream, et tend à aggraver la prochaine panne.

7) Comment prouver que c’est un problème RPZ ?

Regardez la SOA dans la section authority de la réponse NXDOMAIN ; un NXDOMAIN de politique pointe souvent vers une SOA contrôlée par RPZ. Vérifiez aussi la présence de response-policy dans la config effective et inspectez le contenu des zones RPZ.

8) Pourquoi seuls certains clients tombent dans la mauvaise vue ?

Parce que les ACL match-clients n’incluent souvent pas toutes les plages sources réelles (surtout IPv6), ou parce que le trafic passe par du NAT, pools VPN ou split tunneling. Des clients que vous pensez « internes » ne semblent peut-être pas internes au serveur DNS.

9) Quelle est la façon la plus rapide d’isoler un forwarder défaillant ?

Interrogez chaque forwarder directement pour un nom en échec et pour un nom canari sain, successivement. Si l’un renvoie NXDOMAIN tandis que les autres renvoient NOERROR, c’est le coupable. Confirmez ensuite avec le query logging sur BIND.

10) Comment empêcher que ce type d’incident se reproduise ?

Surveillez le comportement par nœud du résolveur, contrôlez les attentes sur les TTL négatifs, gardez les vues/politiques explicites et auditées, et testez les forwarders comme des dépendances — parce que c’en sont.

Conclusion : prochaines étapes concrètes

Les NXDOMAIN intermittents ne sont pas une humeur mystique du DNS. C’est presque toujours une des quatre choses : cache négatif, vues, forwarders ou politique (RPZ). DNSSEC et les problèmes de transport réseau sont des complices fréquents, rarement l’auteur initial du NXDOMAIN.

Étapes pratiques :

  1. Choisissez un nom en échec et reproduisez avec dig directement contre votre résolveur. Sauvegardez la sortie avec les drapeaux et la SOA.
  2. Interrogez chaque forwarder individuellement. S’ils sont en désaccord, vous avez trouvé votre « intermittent ».
  3. Vidangez le cache et confirmez si une entrée négative existe. Videz le nom spécifique pour atténuer.
  4. Inspectez les vues et la configuration RPZ dans la config rendue (named-checkconf -p), pas dans le modèle mental à moitié retenu de quelqu’un.
  5. Si vous êtes autoritatif, vérifiez la parité des serials SOA sur tous les serveurs autoritatifs avant d’accuser les résolveurs.
  6. Après l’incident : ajoutez des contrôles DNS par nœud et une requête canari qui ne doit jamais être NXDOMAIN, et alarmez quand elle l’est.

Faites cela, et la prochaine fois que quelqu’un dira « le DNS est instable », vous pourrez répondre avec des preuves, pas des impressions.

← Précédent
Windows Terminal comme un pro : profils, polices et raccourcis
Suivant →
ZFS : Les 3 métriques qui prédisent un plantage de pool avant qu’il n’arrive

Laisser un commentaire