Quand une zone BIND9 ne se charge pas, la portée des dégâts est rarement discrète. La moitié de vos services tombe « au hasard », quelqu’un accuse le réseau, et votre téléphone d’astreinte commence à développer des troubles de personnalité.
Bonne nouvelle : la plupart des incidents « zone ne se charge pas » proviennent d’un petit nombre d’erreurs de syntaxe, de problèmes de fichiers/permissions et de quelques pièges spécifiques à BIND. Meilleure nouvelle : vous pouvez les diagnostiquer rapidement si vous arrêtez de deviner et commencez à lire ce que named vous dit.
Mode opératoire de diagnostic rapide (premier/deuxième/troisième)
Ceci est la séquence qui trouve le goulet d’étranglement le plus vite. Elle est orientée triage en production : obtenir le signal, arrêter l’hémorragie, puis polir.
Premier : confirmer si la zone est chargée et quelle version est en service
- Demandez à BIND ce qu’il pense :
rndc zonestatusetrndc status. Si BIND n’a jamais chargé la zone, vous cherchez un problème de fichier ou une erreur de syntaxe, pas un souci de cache. - Interrogez le serveur directement :
dig @127.0.0.1pour SOA et NS. Si vous obtenezSERVFAILou pas le drapeau autoritatif, vous ne servez pas ce que vous pensez.
Deuxième : lisez l’erreur que BIND a déjà imprimée
- Journald ou syslog :
journalctl -u named(ou-u bind9) vous indique l’échec de parsing exact, le numéro de ligne et souvent le token qui a cassé le fichier. - Cherchez les lignes « loading » : vous voulez le nom de la zone, le chemin du fichier et une raison. Si le log dit « permission denied », n’ouvrez pas Vim — corrigez la propriété et SELinux/AppArmor.
Troisième : validez hors ligne avec les outils de vérification
named-checkconf: détecte les problèmes au niveau de la config (mauvaise view, zone dupliquée, syntaxe ACL incorrecte, include manquant).named-checkzone: détecte les problèmes de syntaxe de zone (noms de propriétaires invalides, SOA cassé, combinaisons CNAME illégales, données hors zone).
Si la production est en feu
- Rollback rapide : restaurez le dernier fichier de zone connu bon, augmentez le serial, reload. Le DNS n’est pas l’endroit pour faire du debug en direct avec un pager qui hurle.
- Gardez une trace : copiez la zone cassée à part pour pouvoir en tirer des enseignements plus tard. Après l’incident vous ne vous souviendrez pas quelle « petite modification » a tout fait imploser.
Ce que « la zone ne se charge pas » signifie réellement dans BIND9
« Zone ne se charge pas » est un mensonge pratique que l’on se raconte. Dans BIND9 cela signifie généralement une des situations suivantes :
- BIND ne peut pas lire le fichier de zone : mauvais chemin, permissions, confinement SELinux/AppArmor, chroot mal configuré, ou include manquant.
- BIND peut le lire mais ne peut pas l’analyser : erreurs de syntaxe, combinaisons d’enregistrements illégales, noms de propriétaires/TTL/classe cassés.
- BIND le charge, puis le rejette : données hors zone, enregistrements requis manquants (SOA), ou politiques d’intégrité qui refusent la zone, particulièrement dans les builds durcis et les nouveaux réglages par défaut.
- BIND charge une version plus ancienne que celle que vous avez modifiée : vous avez édité le mauvais fichier, la mauvaise view, ou la zone est générée et écrasée par l’automatisation.
- BIND la charge, mais les clients échouent toujours : parce que la zone est chargée mais incorrecte — délégations cassées, NS manquants, glue incorrecte, wildcard qui ne couvre pas, ou échecs DNSSEC provoquant des problèmes de validation.
Opérationnellement, votre travail est de déterminer dans quelle classe d’échec vous êtes en moins de cinq minutes. Le reste est de l’exercice de doigts.
Faits et contexte intéressants (parce que le DNS a du baggage)
- BIND est plus ancien que la plupart de vos outils : il est né à l’UC Berkeley dans les années 1980 et est devenu le serveur DNS de facto au début d’internet.
- Les fichiers de zone sont faits pour être édités à la main : leur format ligne-par-ligne précède YAML, JSON et l’attente moderne de schémas stricts et parseurs aimables.
- Le point final n’est pas de la décoration : en DNS il signifie « nom absolu ». Sans lui, les noms sont relatifs à l’origine courante, et c’est ainsi qu’on se retrouve avec
ns1.example.com.example.com. - Les numéros de série sont une poignée de main protocolaire : le serial SOA pilote les transferts de zone (AXFR/IXFR). Des serials incorrects n’embêtent pas seulement — ils laissent les secondaires sur des données anciennes.
- La mise en cache négative est une fonctionnalité : le RFC 2308 rend NXDOMAIN cacheable en utilisant le minimum/TTL négatif du SOA. Vous pouvez « corriger » un enregistrement et voir encore des échecs tant que les caches n’ont pas expiré.
- Le TTL a été conçu pour un monde plus lent : c’est un bouton de réglage grossier d’une époque où tout le monde s’attendait à ce que la mise en cache économise bande passante et CPU.
- DNSSEC a amplifié les pannes : sans DNSSEC, beaucoup d’erreurs se dégradaient en « mauvaise réponse ». Avec DNSSEC, elles peuvent devenir
SERVFAILchez les résolveurs validants. - Les messages d’erreur de BIND se sont améliorés avec les décennies : les versions anciennes étaient cryptiques ; BIND moderne indique généralement le numéro de ligne et le token. Les gens ne lisent juste pas.
- Les views compliquent le dépannage : le DNS à horizon splitté est utile, mais cela signifie aussi que « la zone est correcte » peut être vrai dans une view et faux dans une autre.
Tâches pratiques : commandes, sorties et décisions (12+)
Ce sont de vraies commandes que vous pouvez exécuter durant un incident. Chacune inclut ce que la sortie signifie et la décision suivante.
Task 1: Check service health and which unit name you’re dealing with
cr0x@server:~$ systemctl status bind9 --no-pager
● bind9.service - BIND Domain Name Server
Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2025-12-31 08:10:22 UTC; 1h 12min ago
Docs: man:named(8)
Main PID: 1321 (named)
Tasks: 12 (limit: 9456)
Memory: 98.3M
CGroup: /system.slice/bind9.service
└─1321 /usr/sbin/named -f -u bind
Signification : BIND est en cours d’exécution. « Zone ne se charge pas » n’est pas « le démon est arrêté ».
Décision : allez aux logs et au statut de la zone ; ne perdez pas de temps à redémarrer à moins que vous n’ayez besoin de forcer un reload après une correction.
Task 2: Pull the last errors from journald
cr0x@server:~$ journalctl -u bind9 -n 60 --no-pager
Dec 31 09:14:02 server named[1321]: zone example.com/IN: loading from master file /etc/bind/zones/db.example.com failed: file not found
Dec 31 09:14:02 server named[1321]: zone example.com/IN: not loaded due to errors.
Dec 31 09:14:02 server named[1321]: managed-keys-zone: loaded serial 0
Signification : Ce n’est pas la syntaxe. C’est un problème de chemin. BIND ne peut pas ouvrir le fichier.
Décision : vérifiez le bloc de zone dans named.conf et le chemin filesystem ; contrôlez le chroot et les chemins d’include.
Task 3: Validate named configuration first (fast, cheap, decisive)
cr0x@server:~$ sudo named-checkconf -z
/etc/bind/named.conf.local:24: zone 'example.com': master file /etc/bind/zones/db.example.com: file not found
Signification : La config référence un fichier qui n’existe pas à cet emplacement.
Décision : corrigez le chemin du fichier ou placez-y le fichier. N’éditez pas encore le contenu de la zone.
Task 4: Confirm the file exists where BIND expects it
cr0x@server:~$ ls -la /etc/bind/zones/db.example.com
ls: cannot access '/etc/bind/zones/db.example.com': No such file or directory
Signification : Il n’y est vraiment pas (ou vous êtes dans la mauvaise racine si chrooté).
Décision : localisez le fichier réel, corrigez le déploiement ou mettez à jour la stanza de zone avec le bon chemin.
Task 5: Find where the zone file actually lives (common in “helpful” automation)
cr0x@server:~$ sudo find /etc/bind -maxdepth 3 -type f -name "db.example.com" -print
/etc/bind/master/db.example.com
Signification : Quelqu’un a déplacé ou généré le fichier dans un autre répertoire.
Décision : alignez la config et le filesystem. Préférez faire référence au chemin réellement géré plutôt que de dupliquer les fichiers.
Task 6: Check permissions and ownership (BIND runs as a user for a reason)
cr0x@server:~$ namei -l /etc/bind/master/db.example.com
f: /etc/bind/master/db.example.com
drwxr-xr-x root root /
drwxr-xr-x root root etc
drwxr-xr-x root root bind
drwx------ root root master
-rw-r----- root root db.example.com
Signification : Le répertoire /etc/bind/master est en 0700, donc l’utilisateur bind ne peut pas y accéder.
Décision : corrigez les permissions du répertoire (ou déplacez le fichier). Ne « lancez pas named en root » sauf si vous aimez rédiger des rapports d’incident.
Task 7: Fix permissions safely and reload
cr0x@server:~$ sudo chgrp bind /etc/bind/master
cr0x@server:~$ sudo chmod 0750 /etc/bind/master
cr0x@server:~$ sudo chgrp bind /etc/bind/master/db.example.com
cr0x@server:~$ sudo chmod 0640 /etc/bind/master/db.example.com
cr0x@server:~$ sudo rndc reload example.com
server reload successful
Signification : Le reload a réussi au niveau du canal de contrôle. Cela ne garantit pas que la zone est chargée ; cela signifie que BIND a accepté la commande.
Décision : confirmez le statut de la zone et interrogez SOA/NS pour vous assurer que la zone est bien en mémoire.
Task 8: Ask BIND directly whether the zone is loaded
cr0x@server:~$ sudo rndc zonestatus example.com
name: example.com
type: master
files: /etc/bind/master/db.example.com
serial: 2025123101
nodes: 29
last loaded: Tue, 31 Dec 2025 09:22:11 GMT
secure: no
Signification : La zone est chargée, et BIND utilise le fichier attendu avec un serial précis.
Décision : passez aux vérifications de cohérence (SOA/NS, glue, réponses) plutôt qu’aux problèmes de parser.
Task 9: Validate a zone file offline before touching production again
cr0x@server:~$ sudo named-checkzone example.com /etc/bind/master/db.example.com
zone example.com/IN: loaded serial 2025123101
OK
Signification : Vérifications de syntaxe et sémantiques de base passées.
Décision : si les clients échouent encore, regardez la délégation, les views, DNSSEC ou le caching. Cessez d’accuser le parser de la zone.
Task 10: Catch the classic “missing dot” and origin confusion with a failing checkzone
cr0x@server:~$ sudo named-checkzone example.com /etc/bind/master/db.example.com
/etc/bind/master/db.example.com:18: NS 'ns1.example.com.example.com' has no address records (A or AAAA)
zone example.com/IN: loaded serial 2025123101
OK
Signification : La zone se charge, mais BIND avertit que votre nom NS a été étendu relativement à l’origine. C’est généralement un point final manquant sur un FQDN.
Décision : corrigez le nom cible NS (ajoutez le point ou utilisez un nom relatif volontairement) et assurez-vous qu’il existe des enregistrements A/AAAA pour les serveurs de noms dans la zone.
Task 11: Query the authoritative server locally (cut caching out of the story)
cr0x@server:~$ dig @127.0.0.1 example.com SOA +norecurse
; <<>> DiG 9.18.24-1-Debian <<>> @127.0.0.1 example.com SOA +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; ANSWER SECTION:
example.com. 3600 IN SOA ns1.example.com. hostmaster.example.com. 2025123101 3600 900 1209600 300
;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Dec 31 09:24:20 UTC 2025
;; MSG SIZE rcvd: 98
Signification : Réponse autoritative (aa) et champs SOA cohérents. La zone est servie.
Décision : si les clients externes voient des échecs, vérifiez le pare-feu/ACL, les views ou la délégation chez le parent.
Task 12: Verify NS set and glue expectations
cr0x@server:~$ dig @127.0.0.1 example.com NS +norecurse
; <<>> DiG 9.18.24-1-Debian <<>> @127.0.0.1 example.com NS +norecurse
;; Got answer:
;; ->HEADER<<- opcode: QUERY, status: NOERROR, id: 22222
;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; ANSWER SECTION:
example.com. 3600 IN NS ns1.example.com.
example.com. 3600 IN NS ns2.example.com.
Signification : La zone publie deux serveurs de noms autoritatifs.
Décision : assurez-vous que ces noms NS se résolvent. S’ils sont dans la zone, publiez les glue A/AAAA dans la zone. S’ils sont hors zone, assurez-vous que les noms externes sont résolubles.
Task 13: Confirm you didn’t create an illegal CNAME mix
cr0x@server:~$ sudo named-checkzone example.com /etc/bind/master/db.example.com
/etc/bind/master/db.example.com:42: 'www.example.com' CNAME and other data
zone example.com/IN: loading from master file /etc/bind/master/db.example.com failed: CNAME and other data
zone example.com/IN: not loaded due to errors.
Signification : Un nom propriétaire a à la fois un CNAME et un autre type d’enregistrement (A/AAAA/TXT/MX/etc.). C’est interdit.
Décision : choisissez : soit CNAME, soit « enregistrements réels ». Si vous avez besoin d’un comportement semblable à l’apex, envisagez ALIAS chez le fournisseur (pas une norme DNS) ou repensez votre conception.
Task 14: Check whether views are the real culprit
cr0x@server:~$ sudo named-checkconf -p | sed -n '1,120p'
acl "internal-nets" { 10.0.0.0/8; 192.168.0.0/16; };
view "internal" {
match-clients { "internal-nets"; };
zone "example.com" { type master; file "/etc/bind/master/db.example.com.internal"; };
};
view "external" {
match-clients { any; };
zone "example.com" { type master; file "/etc/bind/master/db.example.com.external"; };
};
Signification : Deux fichiers différents servent la même zone selon la source client.
Décision : vérifiez que vous avez édité le bon fichier pour les clients qui échouent. « Ça marche sur mon laptop » est souvent « ça marche dans la view interne ».
Task 15: Validate DNSSEC-related files if you’re signed
cr0x@server:~$ journalctl -u bind9 -n 30 --no-pager
Dec 31 09:30:11 server named[1321]: zone example.com/IN: loaded serial 2025123101
Dec 31 09:30:11 server named[1321]: zone example.com/IN: signing with keys in key repository
Dec 31 09:30:11 server named[1321]: zone example.com/IN: DNSKEY RRset is not signed
Dec 31 09:30:11 server named[1321]: zone example.com/IN: not loaded due to errors.
Signification : Vous avez des exigences DNSSEC (inline-signing ou politiques), mais les données/cles de la zone ne les satisfont pas.
Décision : déterminez si DNSSEC est requis pour cette zone. Si oui, corrigez le matériel de clés/politique et re-signez. Sinon, désactivez les fonctionnalités DNSSEC pour la zone afin de restaurer le service.
Task 16: Confirm what the outside world sees (authoritative answers, not cache)
cr0x@server:~$ dig @ns1.example.com example.com SOA +norecurse
; <<>> DiG 9.18.24 <<>> @ns1.example.com example.com SOA +norecurse
;; Got answer:
;; ->HEADER<<- opcode: QUERY, status: SERVFAIL, id: 33333
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
Signification : Le serveur autoritatif renvoie SERVFAIL. C’est généralement un problème côté serveur (zone non chargée, cassure DNSSEC, erreurs runtime), pas un problème de cache client.
Décision : retournez aux logs du serveur et au statut de la zone ; ne perdez pas de temps à vider les résolveurs.
Blague #1 : Le DNS est le seul système où ajouter un point peut réparer la production. Dans la plupart des autres endroits, ajouter de la ponctuation ne fait que créer du drame sur Slack.
Erreurs courantes : symptôme → cause racine → correction
Cette section est volontairement spécifique. Si vous voulez des conseils vagues, il existe déjà plein de billets de blog qui font mal ce travail.
1) Symptom: “zone not loaded due to errors” after reload
Cause racine : Vous avez fait confiance à rndc reload pour vous dire que la zone était chargée. Il vous dit seulement que la commande a été acceptée.
Correction : Faites toujours suivre par rndc zonestatus example.com et named-checkzone. Si ça échoue, vous aurez l’erreur de parsing exacte et le numéro de ligne.
2) Symptom: “file not found” but you swear the file exists
Cause racine : Mauvais chemin dans la stanza de zone, mismatch d’un include, ou BIND tourne en chroot et vous regardez le filesystem hôte, pas la jail.
Correction : Utilisez named-checkconf -z pour afficher ce que BIND tente d’ouvrir. Si chrooté, vérifiez que le fichier existe sous le répertoire chroot. Confirmez avec ls -la à l’intérieur de cette racine.
3) Symptom: “permission denied” loading a zone file
Cause racine : Droits de traversée de répertoire manquants (le sournois), mauvaise propriété, ou politique MAC qui bloque (SELinux/AppArmor).
Correction : Lancez namei -l /path/to/zone. Corrigez les bits de mode des répertoires afin que l’utilisateur bind puisse traverser. Si SELinux, vérifiez les refus AVC et appliquez le contexte approprié.
4) Symptom: “CNAME and other data”
Cause racine : Un nom a à la fois un CNAME et un autre RRset (A/AAAA/TXT/MX/NS, etc.). Fréquent quand on veut que www pointe quelque part mais qu’on garde aussi un TXT pour vérification.
Correction : Supprimez les enregistrements en conflit. Si vous avez besoin d’un TXT au même nom, n’utilisez pas de CNAME là. Utilisez A/AAAA, ou déplacez la vérification sur un autre label.
5) Symptom: “out of zone data”
Cause racine : Vous avez mis des enregistrements pour un autre domaine dans le fichier (souvent à cause d’un point final manquant ou d’un collage depuis une autre zone).
Correction : Assurez-vous que les noms de propriétaire appartiennent à l’origine de la zone. Utilisez $ORIGIN avec précaution. Ajoutez des points finaux aux noms absolus.
6) Symptom: Zone loads, but secondaries never update
Cause racine : Le serial SOA n’a pas changé, ou il a reculé (serial basé sur la date avec une erreur de frappe), ou vous avez édité le mauvais fichier/view.
Correction : Incrémentez le serial. Utilisez un schéma monotone. Puis rndc notify example.com et vérifiez les logs de transfert sur les secondaires.
7) Symptom: NXDOMAIN persists after you “fixed” the record
Cause racine : Mise en cache négative selon le minimum/negative TTL du SOA. Également possible : vous avez changé la view interne mais les clients interrogent la view externe.
Correction : Vérifiez le champ minimum du SOA ; réduisez-le avant les changements lors de migrations planifiées. Vérifiez quelle view répond à votre client de test en interrogeant depuis le même chemin réseau.
8) Symptom: “bad owner name (check-names)”
Cause racine : Caractères illégaux dans les noms propriétaire (underscores dans des hostnames, espaces, etc.) ou règles strictes de vérification.
Correction : Corrigez le nom. Les underscores sont autorisés dans certains contextes d’enregistrements (comme certains labels SRV) mais pas comme noms d’hôtes généraux. Ne « corrigez » pas en désactivant globalement les vérifications sauf si vous aimez les bugs subtils.
9) Symptom: Zone loads locally, but external resolvers get SERVFAIL
Cause racine : Échecs de validation DNSSEC (signatures expirées, DS manquant, mauvais état NSEC/NSEC3), délégation incomplète, ou blocage pare-feu pour UDP/TCP 53.
Correction : Confirmez l’autorité depuis plusieurs points de vue. Vérifiez l’état de la chaîne DNSSEC et la fraîcheur des signatures. Assurez-vous que TCP 53 fonctionne (les grandes réponses DNSSEC en ont souvent besoin).
10) Symptom: “unexpected end of input” / parse stops mid-file
Cause racine : Parenthèse fermante manquante dans un SOA multi-lignes, guillemets non fermés dans un TXT, ou un copier/coller ayant supprimé la dernière newline ou parenthèse.
Correction : Lancez named-checkzone et allez au numéro de ligne. Puis scannez vers le haut pour trouver les structures non fermées ; le parser indique souvent où il a remarqué l’erreur, pas où elle a commencé.
11) Symptom: “ignoring out-of-zone data” warnings and missing records
Cause racine : Le propriétaire de l’enregistrement s’est étendu vers le mauvais nom à cause de labels relatifs et de changements de $ORIGIN.
Correction : Soyez explicite : utilisez des noms complets avec point final pour tout ce qui n’est pas sous l’origine courante, et évitez de parsemer des changements de $ORIGIN sauf si la zone est vraiment complexe.
12) Symptom: Reload works, but answers are still old
Cause racine : Vous avez édité un fichier que BIND n’utilise pas (mauvaise view, mauvais include, fichier généré écrasé). Ou BIND a refusé de charger la nouvelle version et a conservé l’ancienne en mémoire.
Correction : rndc zonestatus pour voir le chemin du fichier et le serial actuellement chargés. Comparez cela avec ce que vous avez édité. Si décalage, corrigez votre processus de déploiement/automation, pas la syntaxe de la zone.
Trois micro-récits d’entreprise depuis le terrain
Mini-story 1: The incident caused by a wrong assumption
L’équipe migravait une application client d’un load balancer à un autre. Le plan semblait propre : ajouter un nouvel enregistrement A, garder un TTL faible, et basculer le trafic en mettant à jour un seul nom. Ils ont édité la zone, incrémenté le serial, fait rndc reload, et suivi leurs checks synthétiques. Vert.
Puis les appels ont commencé. Les utilisateurs externes ne pouvaient pas résoudre le nom ; les employés internes oui. La première hypothèse était prévisible : « le DNS public met en cache l’ancienne réponse ». Quelqu’un a proposé de purger les caches (toujours adorable), un autre a suggéré d’attendre.
Le vrai problème était le DNS à horizon splitté. Il y avait deux views : interne et externe. L’ingénieur a mis à jour le fichier de la view interne, car c’est ce que son laptop atteignait via le VPN. La view externe pointait toujours vers l’ancien load balancer, déjà drainé et à moitié désactivé. Dans leur modèle mental, il y avait « la zone ». Dans BIND, il y avait deux zones du même nom.
La correction fut techniquement triviale — mettre à jour le bon fichier, incrémenter le serial, recharger. La partie difficile fut sociale : expliquer pourquoi le changement « fonctionnait en test » alors qu’il cassait la prod pour les clients. La leçon : testez toujours depuis la perspective client qui compte. Pour le DNS, cela signifie interroger le serveur autoritatif depuis le bon réseau et vérifier dans quelle view vous êtes.
Après l’incident, ils ont ajouté une étape au runbook : named-checkconf -p pour afficher la config active, et une paire de commandes dig exécutées depuis un hôte interne et un point de vue externe. Cela a empêché le prochain « mais ça marchait chez moi ».
Mini-story 2: The optimization that backfired
Un groupe plateforme a décidé que les fichiers de zone étaient « trop lents » à recharger et a voulu une optimisation : les générer avec des changements $ORIGIN agressifs et omettre des points finaux « inutiles » pour réduire la taille des fichiers et simplifier les templates. Ils ont aussi activé une composition par includes pour que plusieurs équipes contribuent des fragments.
Le résultat fut un fichier de zone élégant pour les humains qui savaient déjà comment il fonctionnait — et incompréhensible pendant les incidents. Un point final manquant sur une cible NS s’est tranquillement étendu vers le mauvais nom, et comme ce n’était pas dans la zone, il n’avait pas d’enregistrements d’adresse. Quelques résolveurs le toléraient ; d’autres peinaient. Pendant ce temps, les chemins d’include différaient entre environnements. Staging chargeait ; production échouait avec file-not-found car la disposition des répertoires n’était pas identique.
La panne n’était pas spectaculaire ; elle était pire. Elle provoquait des échecs intermittents de résolution et des timeouts sporadiques. Les tickets rebondissaient entre réseau, SRE et applis parce que personne ne voyait un état « down » clair. Les logs BIND contenaient des avertissements, mais personne ne les lisait parce que « les warnings sont normaux ».
La correction fut ennuyeuse et efficace : arrêter d’être trop malin. Ils se sont mis d’accord sur des FQDN explicites avec points finaux pour tout ce qui n’était pas manifestement relatif, ont minimisé les changements de $ORIGIN, et ont fait en sorte que le générateur produise un seul fichier canonique par zone et par view. Le fichier a grossi. Le temps de reload n’a pas posé de problème. Le temps moyen pour comprendre a fortement diminué.
Blague #2 : Si votre zone DNS a besoin d’un générateur pour être lisible, vous n’avez pas construit de l’automatisation — vous avez construit une énigme.
Mini-story 3: The boring but correct practice that saved the day
Une entreprise régulée avait une règle de gestion des changements : chaque modification DNS doit passer named-checkzone et named-checkconf dans le CI, et le système de déploiement refusait de publier des fichiers qui ne validaient pas. Les ingénieurs râlaient, bien sûr.
Un vendredi, un changement de routine a ajouté un enregistrement TXT pour une vérification de domaine. L’ingénieur a accidentellement placé le TXT sur un nom qui avait déjà un CNAME (parce que le marketing voulait des « noms jolis »). Dans un environnement plus décontracté, la zone aurait échoué à se charger et emporté un lot d’enregistrements non liés — car la zone est atomique du point de vue de BIND.
Au lieu de cela, le CI a bloqué le commit avec une erreur claire « CNAME and other data », incluant le numéro de ligne exact. Ils l’ont corrigé, déplacé la vérification sur un label différent, et ont déployé en sécurité. Personne n’a été appelé. Personne ne s’en est souvenu le lundi.
La pratique était peu glamour : valider avant reload, déployer depuis une source de vérité unique, et logger les changements de serial. Ce n’est pas innovant, mais c’est ce qui évite d’expliquer à la direction pourquoi « un enregistrement TXT » a causé une panne.
Listes de contrôle / plan étape par étape
Checklist incident : la zone ne se charge pas maintenant
- Confirmer l’impact : est-ce un nom, une zone, ou toutes les zones ? Interrogez SOA/NS localement et depuis au moins une perspective externe.
- Vérifier la santé de BIND : service en cours, CPU/mémoire raisonnables, pas de crash loops.
- Lire les 100 dernières lignes de log : trouvez la première erreur liée à la tentative de chargement de la zone ; ne poursuivez pas le bruit en aval.
- Exécuter
named-checkconf -z: corriger includes manquants, chemins de fichiers erronés, zones dupliquées, problèmes de view. - Exécuter
named-checkzone: corriger erreurs de syntaxe, conflits CNAME, format SOA, noms de propriétaires, données hors zone. - Corriger l’accès filesystem : permissions, propriété, SELinux/AppArmor. Valider avec
namei -l. - Recharger et vérifier :
rndc reload zone, puisrndc zonestatus, puisdig @127.0.0.1SOA/NS. - Si toujours en erreur depuis l’extérieur : vérifiez views, pare-feu, délégation, état DNSSEC.
Checklist de changement : éditer une zone en sécurité (pour éviter le pager)
- Choisir la fenêtre de changement selon le TTL : si vous avez besoin d’un déploiement/rollback rapide, baissez les TTL en amont.
- Éditer avec garde-fous : utilisez un linter ou au moins un formatage cohérent. Le SOA multi-lignes est acceptable ; gardez juste les parenthèses équilibrées.
- Incrémentez toujours le serial SOA : et assurez-vous qu’il augmente de manière monotone sur tous les chemins de déploiement.
- Validez hors ligne :
named-checkzonepour le fichier de zone,named-checkconfsi vous avez modifié includes/views. - Reload ciblé :
rndc reload example.complutôt que de recharger tout le serveur. - Vérifiez les réponses autoritatives : interrogez le serveur directement pour SOA/NS et le nom modifié. Confirmez le drapeau
aa. - Vérifiez le transfert/propagation : si vous avez des secondaires, confirmez qu’ils ont récupéré le nouveau serial.
- Notez ce que vous avez changé : une ligne dans le ticket. Le vous du futur est un inconnu moins reposé.
Checklist renforcement : rendre les échecs de chargement rares et courts
- Validation CI : bloquez les merges qui échouent
named-checkzone/named-checkconf. - Source de vérité unique : générez un fichier canonique par zone/view, déployez atomiquement.
- Logger les serials : traitez les changements de serial comme des versions de release.
- Séparer les responsabilités : ne mélangez pas modifications manuelles et fragments générés sauf si vous aimez jouer les détectives.
- Utiliser des secondaires : et testez-les. Un bon secondaire est un filet de sécurité et un outil de surveillance.
- Alerter sur « zone not loaded » : analysez les logs ou utilisez des checks basés sur
rndc.
FAQ
1) Why does rndc reload say “successful” when the zone still isn’t loaded?
rndc rapporte que BIND a accepté la commande de contrôle, pas que le parsing a réussi. Vérifiez toujours rndc zonestatus et les logs.
2) What’s the fastest way to find the exact syntax error line?
Exécutez named-checkzone example.com /path/to/zone. Il imprime le fichier et le numéro de ligne, généralement avec le token fautif.
3) I fixed a record but clients still see NXDOMAIN. Is BIND broken?
Probablement pas. NXDOMAIN est mis en cache (mise en cache négative). Vérifiez le minimum/negative TTL du SOA et attendez — ou planifiez en baissant ce TTL avant les changements.
4) Do I really need the trailing dot on FQDNs in zone files?
Si vous voulez que le nom soit absolu, oui. Sans le point final, BIND le traite comme relatif à l’origine courante. C’est ainsi que l’on fabrique des noms absurdes.
5) Can I have a CNAME and a TXT record on the same name?
Non. Un CNAME ne peut pas coexister avec d’autres données au même nom propriétaire. Déplacez le TXT sur un label différent ou n’utilisez pas de CNAME.
6) Why do secondaries not pick up my changes even though the primary serves them?
Le plus souvent, le serial SOA n’a pas augmenté. Les secondaires comparent les serials ; si aucune augmentation (ou une diminution), ils conservent l’ancienne zone.
7) The zone loads, but external resolvers get SERVFAIL. What now?
Vérifiez DNSSEC en premier si vous l’utilisez. Vérifiez aussi la reachabilité TCP/53 et la correction de la délégation. SERVFAIL d’un autoritatif est un signal d’alerte.
8) How do views change troubleshooting?
Les views créent plusieurs versions d’une « même » zone. Vous devez confirmer à quelle view un client correspond et valider le fichier de zone correspondant.
9) What’s a safe SOA serial format?
Le format basé sur la date YYYYMMDDnn fonctionne si vous ne revenez jamais en arrière. Un entier monotone fonctionne aussi. Choisissez-en un et appliquez-le dans vos outils.
10) Should I disable check-names to get rid of warnings?
En général non. Corrigez les noms. Désactiver les vérifications échange un avertissement évident aujourd’hui contre une panne confuse demain.
Étapes pratiques suivantes
Quand BIND9 ne charge pas une zone, n’utilisez pas « redémarrer » comme trait de personnalité. Faites la chose disciplinée :
- Demandez à BIND ce qu’il a chargé :
rndc zonestatus, et interrogez SOA/NS directement. - Lisez les logs comme s’ils vous payaient (c’est le cas).
- Validez hors ligne avec
named-checkconfetnamed-checkzoneavant de toucher à la production. - Corrigez d’abord les trucs ennuyeux : chemins, permissions et points finaux.
- Institutionnalisez la victoire : ajoutez des checks CI et une checklist de déploiement pour que cela devienne un non-événement.
Et un mantra d’exploitation fiable, paraphrase d’une idée de W. Edwards Deming : la qualité vient de l’amélioration du processus, pas du blâme des individus. Les pannes DNS aiment les processus faibles.