[BIND (Berkeley Internet Name Daemon)](https://www.isc.org/downloads/bind/) est le serveur [DNS](https://fr.wikipedia.org/wiki/Domain_Name_System) historique écrit au début des années 1980, c'est encore le plus utilisé sur Internet. Il est développé par l'[ISC](https://www.isc.org/) qui développe aussi [ISC DHCP](HowtoDHCP). BIND peut être à la fois serveur **récursif** (résoudre n'importe quel enregistrement DNS pour certaines machines) ou serveur **faisant autorité** (renvoyer au monde entier les enregistrements DNS d'un nom de domaine spécifique).
Lorsque BIND est utilisé en serveur DNS récursif pour une ou plusieurs machines, on conseille d'activer la résolution DNS inverse pour les zones RFC1918 dans le fichier `/etc/bind/named.conf.local` (c'est important car de nombreux outils vérifient les [reverses DNS](#Reverse-DNS)) :
> *Note* : dans l'exemple, BIND n'écoute que pour la machine locale. Si l'on veut l'interroger avec d'autres machines, on ajustera les options `listen-*` et `allow-recursion` (on pourra notamment utiliser [l'ACL `localnets`](#acl)
Lorsque BIND est utilisé en serveur DNS faisant autorité, on conseille de le sécuriser en [l'enfermant dans un chroot](#chroot) (c'est notamment indispensable pour la configuration ci-dessous qui va rotater `/var/log/bind_queries.log` et qui échouera donc si Bind n'est chrooté comme conseillé).
On peut ensuite ajouter ses domaines pour lesquels BIND fait autorité dans le fichier `/etc/bind/named.conf.local`, par exemple pour _example.com_ avec un serveur replica dans l'ACL _foo_ :
*`allow-transfer` : spécifie les adresses des serveurs replica ou clefs [TSIGs](/Glossaire.md#tsig) autorisées à faire des requêtes AXFR (transfert de zone). Par défaut, toutes les adresses sont autorisées, il est impératif de restreindre les autorisations.
*`allow-update` : spécifie les adresses ou clefs [TSIGs](/Glossaire.md#tsig) autorisées à mettre à jour dynamiquement des informations dans leur zone. Par défaut, aucune adresse n'est autorisée.
*`update-policy` : spécifie finement les droit de modification des entrées pour les adresses ou clefs [TSIGs](/Glossaire.md#tsig) autorisées via une liste d'ACL, **Attention** : on ne peut pas définir à la fois `allow-update` et `update-policy`. voir [Configuration update-policy](/HowtoBind#configuration-update-policy)
Pour enfermer BIND dans une prison _chroot_ nous utilisons le script [chroot-bind.sh](https://gitea.evolix.org/evolix/chroot-bind/src/branch/master/chroot-bind.sh) :
AppArmor protège par défaut les chemins utilisés par la version distribuée par Debian, il faut ajouter les chemins effectivement utilisés dans le chroot.
~~~ { .sh }
# cat /etc/apparmor.d/local/usr.sbin.named
/var/chroot-bind/etc/bind/** r,
/var/chroot-bind/var/** rw,
/var/chroot-bind/dev/** rw,
/var/chroot-bind/run/** rw,
/var/chroot-bind/usr/** r,
~~~
Il faut relancer apparmor et bind9 après ces ajouts.
~~~ { .sh }
# systemctl daemon-reload
# systemctl apparmor restart
# systemctl apparmor bind9
~~~
Sinon vous aurez des erreurs `open: /etc/bind/named.conf: permission denied` et `audit: type=1400 audit(1689581621.287:26): apparmor="DENIED" operation="open" profile="/usr/sbin/named" name="/var/chroot-bind/etc/bind/named.conf" pid=3205399 comm="named" requested_mask="r" denied_mask="r" fsuid=115 ouid=115` dans `/var/log/syslog`.
Depuis Bookworm, des points de montage sont nécessaires pour un fonctionnement normal de systemd et journald (sinon l’unité systemd ne renvoie jamais de signal après un redémarrage correct).
À chaque mise à jour du paquet _bind9_ ou de l'une de ses dépendances (_libc6_, _libcap2_, _libssl_, etc.) vous devrez relancer le script _chroot-bind.sh_ et BIND ensuite.
> *Note* : la rotation du fichier `/var/chroot-bind/var/log/bind_queries.log` est assurée par BIND sous réserve d'avoir bien précisé l'option `versions` dans les paramètres de logging
Il est aussi possible de faire la rotation du fichier de statistique (`/var/run/named.stats` ou `/var/chroot-bind/var/run/named.stats` avec chroot) avec logrotate:
~~~
/var/run/named/named.stats
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
su bind bind
}
~~~
La rotation du fichier de statistiques n'affecte ni Munin, ni BIND.
* Si on édite manuellement la configuration du master (plutôt que d'utiliser le DNS dynamique avec `nsupdate`), il faut absolument mettre `request-ixfr no;` dans la configuration de Bind sur les secondaires (dans les options générales, ou dans un bloc `server`).
* Pour en savoir plus, voir [la documentation de Bind](https://bind9.readthedocs.io/en/v9.16.20/advanced.html#incremental-zone-transfers-ixfr).
* Pour avoir le fichier de zone en clair sur le serveur secondaire (ce qui est pratique notamment en cas d'incident avec le serveur primaire), il faut s'assurer d'avoir l'option `masterfile-format text;` dans la configuration de Bind.
Pour savoir si le primaire renvoie bien la zone DNSà jour, à partir du serveur DNS secondaire, faire une requête de [transfert de zone incrémental](https://fr.wikipedia.org/wiki/Transfert_de_zone_DNS) avec `dig` :
La mise à jour dynamique permet de mettre à jour une zone avec des demandes de mise à jour
"Dynamic Updates" envoyés par le réseau au server authoritaire pour ajouter ou supprimer des champs :
* Il n'y a plus besoin de se connecter au serveur authoritaire pour changer le fichier de zone
* La syntaxe d'une demande est vérifiée avant d'être envoyé pour éviter d'ajouter des entrées incorrectes.
* Le serial SOA est incrémenté automatiquement.
* Dans une zone DNSSEC, le changement est immédiatement signé.
* On peut facilement scripter ces mises à jours ( certbot par exemple )
Pour faire la mise à jour dynamique, Bind génère un fichier de journal `.jnl` binaire du même nom que la zone, contenant l'historique des modifications apportées à la zone.
Il est possible de mettre à jour le fichier de zone directement mais ce n'est pas recommandé car on va devoir temporairement désactiver la mise à jour dynamique "freeze".
Comme cela est compliqué et risqué, il est préférable d'utiliser un outil comme nsdiff avec nsvi qui va nous permettre d'éditer la zone comme si on l'edite à la main, mais va envoyer les changements par demande de mise à jour.
Voir : https://dotat.at/prog/nsdiff/ (documentation à venir)
> *Note* : la synchronisation avec le fichier réel de zone n'est pas faite en temps réel, cela se fait toutes les 15 minutes en général, on peut forcer la synchronisation avec :
Créer le répertoire `/etc/bind/dnssec/db.$domain` (qui servira aussi à conserver les clefs et fichiers de zones dynamiques) et y déplacer le fichier de zone (un lien symbolique depuis son emplacement précédent permet de continuer à pouvoir l’éditer comme avant). Prendre garde à ce que tous les fichiers et répertoires appartiennent bien à bind.
Mettre en place une paire de clefs de zone (ZSK) et de signature (KSK)
~~~
# cd /etc/bind/dnssec/$domain
# sudo -u bind dnssec-keygen -a ECDSAP256SHA256 -n ZONE $domain
# sudo -u bind dnssec-keygen -a ECDSAP256SHA256 -n ZONE -f KSK $domain
~~~
Modifier le fichier de zone dans `/etc/bind/named.conf.local` pour ajouter les trois dernières options suivantes (et modifier le chemin vers le fichier de zone).
~~~
zone "$domain" {
type master;
file "/etc/bind/dnssec/$domain/db.$domain";
allow-query { any; };
allow-transfer { "foo"; };
inline-signing yes;
auto-dnssec maintain;
key-directory "/etc/bind/dnssec/$domain";
};
~~~
Puis recharger la configuration de bind et la zone sera automatiquement signé.
Il est important de configurer les reverses DNS, car ils sont souvent vérifiés par les serveurs SMTP, et certains logiciels les vérifient également (Postfix, MySQL, CUPS, SSH, etc.). Sur un réseau avec des adresses privées, il également important de renvoyer au minimum une réponse DNS _NXDOMAIN_ ce qui peut être fait facilement grâce au fichier `/etc/bind/zones.rfc1918`.
À noter que [les DNS de l'IANA répondent tout de même pour ces demandes... mais sans garantie de bon fonctionnement !](http://www.iana.org/abuse/answers)
Le plugin *bind9_rndc* s'appuie sur le fichier `/var/run/named.stats` (option _statistics-file_ de BIND) et *bind9* s'appuie un fichier de logs (channel *query_logging* dans les logs BIND). Il donc s'assurer d'avoir bien configuré ces deux fichiers puis on indique à Munin via `/etc/munin/plugin-conf.d/bind9` :
* Depuis Buster (Debian 10) le [patch geoip](http://code.google.com/p/bind-geoip/) a été intégré a Bind. Le principe est de faire une recherche suivant un arbre binaire (binary search tree) sur la base de données de MaxMind. Cela n'impacte pas les temps de réponse mais nécessite de maintenir un Bind patché avant Buster;
* en se basant sur le système de vue de Bind. Le principe est de récupérer les plages d'adresses par pays auprès de [MaxMind](https://www.maxmind.com/) et de générer des fichiers d'ACL à l'aide de ce [script](http://phix.me/geodns/). Les performances sont en théorie moins bonnes (mais cette différence n'est pas vraiment constatée dans la pratique), mais l'installation est bien plus simple à maintenir.
zone example.com/IN: loading from master file /etc/bind/bak.example.com failed: not implemented
zone example.com/IN: unable to load from '/etc/bind/bak.example.com'; renaming file to '/etc/bind/db-5GoiCpdc' for failure analysis and retransferring.
Si malheureusement vous n'avez pas d'IPv6 sur votre serveur ou alors si la qualité de votre connexion IPv6 est insuffisante, vous devez forcer Bind à ne pas écouter en IPv6 ainsi :
L'enregistrement `SOA ns-hidden-master.example.com ...` doit bien pointer vers le master caché, dans ce cas `ns-hidden-master.example.com`
sinon les NOTIFY ne fonctionneront pas correctement.
### refresh: timeout retrying without EDNS master
Cela signifie que les requêtes EDNS ne fonctionnent pas vers le master, cela peut notamment être causé par un firewall qui tronque les paquets EDNS qui sont volumineux. On peut notamment contourner cela en désactivant EDNS vers le serveur concerné via `named.conf.options` :
*`name` la règle match exactement avec le nom de l'entrée `name`
*`subdomain` match avec tous le sous-domaine et le domaine de l'entrée `name`
*`zonesub` match tous les sous-domaines de la zone contenant la configuration, il ne faut pas préciser d'entrée `name`
*`wildcard` match toute les [expansions wildcard](https://en.wikipedia.org/wiki/Wildcard_DNS_record) valides de l'entrée `name`
*`self` permet de faire correspondre `identity` directement avec le nom d'une entrée, il ne faut pas préciser d'entrée `name` ou sinon y mettre `.` ou la même valeur que `identity`. On peut aussi mettre directement `*` pour `identity` si le nom est bien le même que celui d'une entrée (cela permet de matcher automatiquement les clefs avec les noms d'entrées)
*`selfsub` fonctionne comme self *et* permet de mettre à jour aussi les sous-domaine du nom d'une entrée
*`selfwild` fonctionne comme self *mais* permet de mettre à jour *uniquement* les sous-domaine du nom d'une entrée
### Problèmes de rafraîchissement des DNS secondaires
Si on modifie les zones du primaire à la main, les secondaires doivent [désactiver les requêtes IXFR](#dns-primaires-et-secondaires), en faveur de l'AXFR.
L'IXFR fonctionne bien seulement avec les mises-à-jour DNS dynamiques (`nsupdate`).