wiki/HowtoBind.md

851 lines
28 KiB
Markdown
Raw Normal View History

2017-07-22 12:38:15 +02:00
---
categories: web system
title: Howto BIND
2017-07-22 12:38:15 +02:00
...
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
* Documentation : <https://www.isc.org/downloads/bind/doc/bind-9-10/>
* DNS et BIND : <http://www.zytrax.com/books/dns/>
2023-12-06 10:45:25 +01:00
* Rôle Ansible : <https://gitea.evolix.org/evolix/ansible-roles/src/branch/stable/bind>
2016-12-29 11:25:39 +01:00
[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).
2017-07-22 12:38:15 +02:00
## Installation
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
# apt install bind9
$ /usr/sbin/named -V
BIND 9.10.3-P4-Debian <id:ebd72b3>
built by make with '--prefix=/usr' '--mandir=/usr/share/man' '--libdir=/usr/lib/x86_64-linux-gnu' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--with-python=python3' '--localstatedir=/' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-gost=no' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-geoip=/usr' '--with-atf=no' '--enable-ipv6' '--enable-rrl' '--enable-filter-aaaa' '--enable-native-pkcs11' '--with-pkcs11=/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so' '--with-randomdev=/dev/urandom' 'CFLAGS=-g -O2 -fdebug-prefix-map=/build/bind9-iBGKO7/bind9-9.10.3.dfsg.P4=. -fstack-protector-strong -Wformat -Werror=format-security -fno-strict-aliasing -fno-delete-null-pointer-checks -DNO_VERSION_DATE -DDIG_SIGCHASE' 'LDFLAGS=-Wl,-z,relro -Wl,-z,now' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
compiled by GCC 6.3.0 20170516
compiled with OpenSSL version: OpenSSL 1.0.2l 25 May 2017
linked to OpenSSL version: OpenSSL 1.0.2l 25 May 2017
compiled with libxml2 version: 2.9.4
linked to libxml2 version: 20904
2016-12-29 11:25:39 +01:00
~~~
2017-07-23 00:12:14 +02:00
Sous Debian 8, l'unité [systemd](HowtoSystemd) ne gère pas les options dans `/etc/default/bind9`, il faut corriger l'unité en copiant :
~~~
# cp -a /lib/systemd/system/bind9.service /etc/systemd/system/
~~~
et ajuster la section _[Service]_ :
~~~
EnvironmentFile=-/etc/default/bind9
ExecStart=/usr/sbin/named -f $OPTIONS
~~~
puis :
~~~
# systemctl daemon-reload
~~~
2017-07-22 12:38:15 +02:00
## Configuration
2016-12-29 11:25:39 +01:00
2023-07-17 10:00:33 +02:00
Les options de BIND sont dans `/etc/default/named` (`/etc/default/bind9` avant Bullseye).
2016-12-29 11:25:39 +01:00
Fichiers de configuration :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
/etc/bind
├── bind.keys
├── db.0
├── db.127
├── db.255
├── db.empty
├── db.local
├── db.root
├── named.conf
├── named.conf.default-zones
├── named.conf.local
├── named.conf.options
├── rndc.key
└── zones.rfc1918
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
### serveur DNS récursif
2016-12-29 11:25:39 +01:00
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)) :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
include "/etc/bind/zones.rfc1918";
~~~
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
Puis ajuster les options via `/etc/bind/named.conf.options` :
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
~~~
options {
directory "/var/cache/bind";
version "Bingo";
auth-nxdomain no;
listen-on-v6 { ::1; };
listen-on { 127.0.0.1; };
allow-recursion { ::1; 127.0.0.1; };
2017-07-22 13:44:47 +02:00
};
2016-12-29 11:25:39 +01:00
logging {
2017-07-22 12:38:15 +02:00
category default { default_file; };
channel default_file {
2016-12-29 11:25:39 +01:00
file "/var/log/bind.log";
2017-07-22 12:38:15 +02:00
severity info;
2016-12-29 11:25:39 +01:00
};
};
2017-07-22 12:38:15 +02:00
~~~
2017-07-23 00:55:58 +02:00
> *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)
2017-07-22 12:38:15 +02:00
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
### serveur DNS faisant autorité
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é).
2017-07-22 12:38:15 +02:00
On va ensuite configurer via le fichier `/etc/bind/named.conf.options` :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
acl "foo" {
::ffff:192.0.2.21; 192.0.2.21;
2001:db8::21;
2016-12-29 11:25:39 +01:00
};
2017-07-22 12:38:15 +02:00
options {
directory "/var/cache/bind";
version "Bingo";
auth-nxdomain no;
masterfile-format text;
statistics-file "/var/run/named.stats";
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
listen-on-v6 { any; };
listen-on { any; };
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
allow-query { localhost; };
allow-recursion { localhost; };
allow-transfer { localhost; };
};
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
logging {
category default { default_file; };
category queries { query_logging; };
channel default_file {
file "/var/log/bind.log";
severity info;
};
channel query_logging {
file "/var/log/bind_queries.log" versions 2 size 128M;
print-category yes;
print-severity yes;
print-time yes;
};
};
2016-12-29 11:25:39 +01:00
~~~
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_ :
2016-12-29 11:25:39 +01:00
~~~
zone "example.com" {
type master;
file "/etc/bind/db.example.com";
allow-query { any; };
2017-07-22 12:38:15 +02:00
allow-transfer { "foo"; };
2016-12-29 11:25:39 +01:00
};
~~~
2017-07-22 12:38:15 +02:00
Puis enfin les fichiers de zone, exemple avec un `/etc/bind/db.example.com` simple :
2016-12-29 11:25:39 +01:00
~~~
$TTL 1800
2017-07-22 12:38:15 +02:00
@ IN SOA ns1.example.net. dnsmaster.example.com. (
2017072107 ; serial
2h ; rafraichissement replica->master
2016-12-29 11:25:39 +01:00
1h ; en cas d'echec du refraichissement, nouvel essai
5w ; expiration des enregistrements en cache par les serveurs replica
2016-12-29 11:25:39 +01:00
10m ) ; TTL negatif
2017-07-22 12:38:15 +02:00
A 192.0.2.80
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
NS ns1.example.net.
NS ns2.example.org.
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
MX 0 .
TXT "v=spf1 -all"
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
www CNAME @
ftp CNAME ftp.example.net.
~~~
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
> *Note* : on s'assurera que les fichiers de zone sont lisibles par l'utilisateur _bind_ en faisant `chown bind:bind /etc/bind/db.example.com`
2016-12-29 11:25:39 +01:00
### Options de configuration
* `allow-query` : spécifie les adresses autorisées à faire des requêtes DNS. Par défaut, toutes les adresses sont autorisées
2023-12-04 12:20:45 +01:00
* `allow-transfer` : spécifie les adresses des serveurs replica ou TSIGs 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-recursion` : spécifie les adresses autorisées à faire des requêtes DNS récursives. À restreindre impérativement également.
2023-12-04 12:20:45 +01:00
* `allow-update` : spécifie les adresses ou TSIGs 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 TSIGs 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)
2017-07-22 12:38:15 +02:00
## chroot
2023-12-06 10:45:25 +01:00
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) :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
# cd /root
2023-12-06 10:45:25 +01:00
# wget https://gitea.evolix.org/evolix/chroot-bind/raw/branch/master/chroot-bind.sh
2017-07-22 12:38:15 +02:00
# sh chroot-bind.sh
2016-12-29 11:25:39 +01:00
~~~
2023-07-17 10:00:33 +02:00
Puis ajoutez `-t /var/chroot-bind` dans la variable OPTIONS du fichier `/etc/default/named` (`/etc/default/bind9` avant Bullseye) :
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
~~~
RESOLVCONF=no
OPTIONS=" -u bind -t /var/chroot-bind"
~~~
2016-12-29 11:25:39 +01:00
2023-11-13 11:57:10 +01:00
### bind mount à partir de Bookworm (Debian 12)
Depuis Bookworm, des points de montage sont nécessaires pour un fonctionnement normal de systemd et journald (sinon lunité systemd ne renvoie jamais de signal après un redémarrage correct).
`/etc/fstab` doit contenir les lignes suivantes.
~~~
/run/systemd/journal/socket /var/chroot-bind/run/systemd/journal/socket none bind 0 0
/run/systemd/journal/stdout /var/chroot-bind/run/systemd/journal/stdout none bind 0 0
/run/systemd/notify /var/chroot-bind/run/systemd/notify none bind 0 0
~~~
Puis les points de montages doivent être créés et montés.
~~~ { .sh }
# mkdir -p /var/chroot-bind/run/systemd/journal
# touch /var/chroot-bind/run/systemd/{journal/s{ocket,tdout},notify}
# chown -R bind: /var/chroot-bind/run/
# systemctl daemon-reload
# mount -a
~~~
### Relancer bind
Vous devez alors relancer BIND :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
# systemctl restart bind9
2016-12-29 11:25:39 +01:00
~~~
À 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.
2017-07-22 12:38:15 +02:00
2022-03-18 11:54:04 +01:00
### Problèmes de permissions avec chroot
* Si erreur : `named: chroot(): Permission denied`, vérifier que `/var/chroot-bind` est en `750`.
2022-03-18 11:57:56 +01:00
* [Debian >= 10] Dans `/etc/apparmor.d/usr.sbin.named`, dupliquer toutes les règles contenant des chemins, et y ajouter le préfixe `/var/chroot-bind`. Puis redémarrer le service AppArmor et 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`.
2022-03-24 11:59:45 +01:00
* Si `/var/log/bind_queries.log` n'existe pas, il faut créer le lien symbolique : `ln -s /var/chroot-bind/var/log/bind_queries.log /var/log/bind_queries.log`
2022-03-18 11:54:04 +01:00
2016-12-29 11:25:39 +01:00
## Rotation des logs
2017-07-22 12:38:15 +02:00
On utilise [logrotate](HowtoLogrotate) pour la rotation des logs.
2019-07-23 10:03:42 +02:00
Voici le fichier `/etc/logrotate.d/bind9` que l'on utilise pour un serveur récursif :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
/var/log/bind.log {
2016-12-29 11:25:39 +01:00
weekly
missingok
2017-07-22 12:38:15 +02:00
rotate 8
2016-12-29 11:25:39 +01:00
create 640 bind bind
sharedscripts
postrotate
rndc reload > /dev/null
endscript
}
~~~
2017-07-22 12:38:15 +02:00
Pour un serveur faisant autorité, on doit préciser le path des fichiers dans le _chroot_ :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
/var/chroot-bind/var/log/bind.log {
weekly
missingok
rotate 52
create 640 bind bind
sharedscripts
postrotate
rndc reload > /dev/null
endscript
}
2016-12-29 11:25:39 +01:00
~~~
2017-07-23 00:55:58 +02:00
> *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
2016-12-29 11:25:39 +01:00
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.
2017-07-22 12:38:15 +02:00
## ACL
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
<http://www.zytrax.com/books/dns/ch7/address_match_list.html>
2016-12-29 11:25:39 +01:00
2017-07-23 00:55:58 +02:00
Au sein des différentes directives `allow-*` on peut utiliser des ACLs.
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
Par défaut, les ACLs suivantes sont prédéfinies :
2016-12-29 11:25:39 +01:00
2017-07-23 00:55:58 +02:00
* `none` : aucune adresse IP
* `any` : toutes les adresses IP
* `localhost` : toutes les adresses IP de la machine (127.0.0.1 mais aussi les adresses configurées sur les différentes interfaces réseau)
* `localnets` : tous les sous-réseaux dans lesquels la machine possède une adresse IP
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
On peut également définir ses propres ACLs :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
acl "bar" {
::ffff:192.0.2.21; 192.0.2.21;
::ffff:192.0.2.42; 192.0.2.42;
2001:db8::21; 2001:db8::42;
};
2016-12-29 11:25:39 +01:00
~~~
## DNS primaires et secondaires
2016-12-29 11:25:39 +01:00
Il est possible de répliquer la configuration des zones DNS d'un serveur DNS primaire vers plusieurs secondaires.
2016-12-29 11:25:39 +01:00
Cela n'empêche pas les secondaires d'être primaires pour d'autres zones.
Si l'on reprend le cas de la zone suivante sur le primaire :
2016-12-29 11:25:39 +01:00
~~~
zone "example.com" {
type master;
file "/etc/bind/db.example.com";
allow-query { any; };
allow-transfer { <SLAVE1_IP>; <SLAVE2_IP>; ... | "<ACL1>"; "<ACL2>"; ... };
2016-12-29 11:25:39 +01:00
};
~~~
Sur le secondaire, on spécifiera l'adresse IP du primaire ainsi qu'un fichier pour sauvegarder la zone en local :
2016-12-29 11:25:39 +01:00
~~~
zone "example.com" {
type slave;
2017-07-22 12:38:15 +02:00
file "/etc/bind/bak.example.com";
2016-12-29 11:25:39 +01:00
allow-query { any; };
masters { <MASTER_IP>; };
2016-12-29 11:25:39 +01:00
};
~~~
Notes :
* Attention aux IPv4 / IPv6.
* 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.
2016-12-29 11:25:39 +01:00
### Debugger
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` :
~~~
dns-secondaire$ dig -b <IP_OUT> <DOMAIN> IXFR=1 @<PRIMARY_DNS_IP>
~~~
Options :
* `-b <IP_OUT>` : si on a plusieurs IPs de sortie, force bind à faire sa requête à partir de `IP_OUT`.
* `IXFR=1` : récupère les changements de la zone depuis le serial 1.
2017-07-22 12:38:15 +02:00
## Mise à jour dynamique
2016-12-29 11:25:39 +01:00
Pour faire la mise à jour dynamique, Bind génère un ficher de journal `.jnl` binaire du même nom que la zone contenant l'historique des modifications apportées à la zone.
2017-07-22 12:38:15 +02:00
Il est possible de mettre à jour une zone DNS sans éditer le fichier avec `nsupdate`.
~~~
$ rndc freeze domain.tld
[Modification manuelle de la zone]
$ rndc thaw domain.tld
$ rndc reload domain.tld
~~~
2016-12-29 11:25:39 +01:00
> *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 : il faut donc faire attention si l'on veut éditer le fichier de zone, il faudra forcer la synchronisation ainsi :
~~~
$ rndc sync [nom_zone]
~~~
2023-12-04 12:20:45 +01:00
### Petit guide TSIG
On peut utiliser nsupdate, ou n'importe quel client, pour mettre à jour la zone en s'authentifiant avec une clef TSIG.
Pour mettre celle-ci en place, il faut ...
Générer une clef TSIG avec tsig-keygen si disponible ou avec dnssec-keygen sinon
~~~
2023-12-04 12:26:02 +01:00
$ tsig-keygen -a hmac-sha512 nomclef
$ dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST nomclef
2023-12-04 12:20:45 +01:00
~~~
Ajouter celle-ci à la configuration de bind...
2023-12-04 12:26:02 +01:00
2023-12-04 12:20:45 +01:00
~~~
2023-12-04 12:26:02 +01:00
$ vim /etc/bind/named.conf.tsigkeys
2023-12-04 12:20:45 +01:00
key "happydomain" {
algorithm HMAC-SHA512;
secret "3JtiVQEBFXtQeU/3PorKpCV7jM1bZEEzkdD1zb9emvwaBZFSgYxOXV41OdSeeHb5dcud+SvNo47jEf5yRwfSkQ==";
};
~~~
> Ne pas oublier d'inclure named.conf.tsigkeys dans `/etc/bind/named.conf`
2023-12-04 12:26:02 +01:00
2023-12-04 12:20:45 +01:00
On peut maintenant recharger la configuration et vérifier que notre clef est bien présente:
~~~
named-checkconf /etc/bind/named.conf && rndc reload
rndc tsig-list
~~~
2016-12-29 11:25:39 +01:00
2023-12-11 15:27:58 +01:00
## DNSSEC
### Ajouter la gestion DNSSEC
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.
~~~
# sudo -u bind mkdir -p /etc/bind/dnssec/$domain
# mv /etc/bind/db.$domain /etc/bind/dnssec/$domain/
# ln -s dnssec/$domain/db.$domain /etc/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é.
~~~
# systemctl reload bind9
~~~
NSEC3 peut être ajouté à la zone signée.
~~~
# rndc signing -nsec3param 1 0 10 `cat /dev/urandom | tr -dc 'A-F0-9' | fold -w 8 | head -n 1` $domain
~~~
### Modification de la zone
Attention le serial de la zone signée et du fichier original non signé peuvent différer (mise à jour dynamique).
Deux commandes pour savoir où en est le serial :
~~~
$ host -t soa $domain 127.0.0.1
# named-compilezone -j -i none -f raw -F text -o - $domain $domain.signed
~~~
Une fois le bon serial récupéré on peut modifier la zone en incrémentant le serial trouvé.
~~~
# Modifier le domaine example.org
domain=example.org
# Vérification du SOA pour le mettre à jour dans le fichier.
host -t soa $domain
# Arrêt (gel) de la mise à jour dynamique
rndc freeze $domain
# Mise à jour de la zone en pensant au SOA.
vim /etc/bind/db.$domain
# Vérification de la configuration.
named-checkzone $domain /etc/bind/db.$domain
named-checkconf
# Relance de la mise à jour dynamique
rndc thaw $domain
~~~
La zone sera automatiquement resigné.
2023-12-11 15:29:01 +01:00
### Rotation de la ZSK
2023-12-11 15:27:58 +01:00
On génère une nouvelle clé comme vu [plus haut](#ajouter-la-gestion-dnssec).
Le temps d'inactivation de l'ancienne clé ainsi que la date de suppression doit être indiqué.
~~~
# La clé doit être retirée dans 2 jours
dnssec-settime -I +2d OLD_ZSK.key
# La clé doit être supprimée dans 6 jours
dnssec-settime -D +6d Kexample.tld.+008+25266.key
~~~
Bind fera tout seul la prébublication et le rollover.
Les 2 jours et les 6 jours sont à modifier en fonction du ttl de la zone, il faut à minima :
* 2 ttl avant que la OLD_ZSK soit inactivé ;
* durant ces 2 ttl, il y a 1 ttl où la OLD_ZSK est activée et la NEW_ZSK est publiée ;
* à la fin des 2 ttl la NEW_ZSK est activée et la OLD_ZSK peut être supprimée.
2017-07-22 12:38:15 +02:00
## Reverse DNS
2016-12-29 11:25:39 +01:00
2017-07-22 18:25:37 +02:00
Un reverse DNS est un nom de domaine associé à une adresse IP. Le nom de cet enregistrement est *PTR*. Exemples :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
$ dig -x 31.170.8.43
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
;; QUESTION SECTION:
;43.8.170.31.in-addr.arpa. IN PTR
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
;; ANSWER SECTION:
43.8.170.31.in-addr.arpa. 43200 IN PTR hosting.evolix.net.
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
$ dig -x 2a01:9500::3
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
;; QUESTION SECTION:
;3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.5.9.1.0.a.2.ip6.arpa. IN PTR
;; ANSWER SECTION:
3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.5.9.1.0.a.2.ip6.arpa. 43200 IN PTR forge.evolix.net.
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
Cela fonctionne avec un nom de domaine "virtuel" : `.in-addr.arpa` en IPv4 et `.ip6.arpa` en IPv6 !
2016-12-29 11:25:39 +01:00
2017-07-22 18:27:22 +02:00
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`.
2016-12-29 11:25:39 +01:00
2017-07-22 18:37:03 +02:00
À 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)
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
## Monitoring
### dnstop
L'outil **dnstop** permet de surveiller en direct l'activité DNS en analysant les paquets réseau qui circulent :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
# apt install dnstop
# dnstop -l3 eth0
s - Sources list
d - Destinations list
t - Query types
o - Opcodes
r - Rcodes
1 - 1st level Query Names ! - with Sources
2 - 2nd level Query Names @ - with Sources
3 - 3rd level Query Names # - with Sources
4 - 4th level Query Names $ - with Sources
5 - 5th level Query Names % - with Sources
6 - 6th level Query Names ^ - with Sources
7 - 7th level Query Names & - with Sources
8 - 8th level Query Names * - with Sources
9 - 9th level Query Names ( - with Sources
^R - Reset counters
^X - Exit
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
### Munin
Pour activer les plugins Munin pour BIND :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
# cd /etc/munin/plugins
# ln -s /usr/share/munin/plugins/bind9_rndc
# ln -s /usr/share/munin/plugins/bind9
~~~
2016-12-29 11:25:39 +01:00
2019-07-23 10:03:42 +02:00
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` :
2017-07-22 12:38:15 +02:00
~~~
[bind*]
user root
env.logfile /var/chroot-bind/var/log/bind_queries.log
env.querystats /var/chroot-bind/var/run/named.stats
env.MUNIN_PLUGSTATE /var/lib/munin
timeout 120
~~~
2016-12-29 11:25:39 +01:00
[comment]: <> (*pour vim)
2017-07-22 12:38:15 +02:00
### Log2mail
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
Pour être alerté en cas de fichiers de zone incorrect, on peut rajouter ceci dans la conf de [Log2mail](HowtoLog2mail) :
2016-12-29 11:25:39 +01:00
~~~
2017-07-22 12:38:15 +02:00
file = /var/chroot-bind/var/log/bind.log
pattern = "not loaded due to errors"
mailto = alert@example.com
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
file = /var/log/syslog
pattern = "fatal error"
mailto = alert@example.com
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
pattern = "loading configuration: failure"
mailto = alert@example.com
~~~
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
## géolocalisation
2016-12-29 11:25:39 +01:00
BIND peut répondre une réponse différente selon l'adresse IP qui l'interroge, on peut faire cela de deux façons :
2017-01-03 11:20:35 +01:00
* 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 ;
2017-07-22 18:37:03 +02:00
* 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.
2016-12-29 11:25:39 +01:00
2017-07-22 12:38:15 +02:00
### À l'aide de vues
* On récupère le script [GeoIP.py](http://phix.me/geodns/GeoIP.py) et on installe les dépendances nécessaires :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
# apt install python-mpmath
~~~
* exécuter le script. Il générera un fichier `GeoIP.acl`, avec une ACL par pays :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
$ ./GeoIP.py MaxMind
~~~
* Configurer Bind pour servir une zone différente en fonction des pays :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
include "/etc/bind/GeoIP.acl";
view "europe" {
match-clients { FR; };
recursion no;
zone "example555.com" {
type master;
file "/etc/bind/db.example555-europe.db";
allow-query { any; };
};
};
view "north_america" {
match-clients { US; CA; MX; };
recursion no;
zone "example555.com" {
type master;
file "/etc/bind/db.example555-north-america.db";
allow-query { any; };
};
};
view "other" {
match-clients { any; };
recursion no;
zone "example555.com" {
type master;
file "/etc/bind/db.example555-other.db";
allow-query { any; };
};
};
~~~
Le script peut être mis en cron pour conserver des ACL à jour.
2017-07-22 12:38:15 +02:00
2016-12-29 11:25:39 +01:00
## FAQ
### journal out of sync
Si vous avez une erreur du type :
~~~
journal out of sync with zone
~~~
Lancer la commande :
~~~
# named -g
~~~
Voir <http://www.thedumbterminal.co.uk/?action=showArticle&articleId=168>
2017-07-22 18:32:38 +02:00
### ran out of space
2016-12-29 11:25:39 +01:00
Si vous avez une erreur du type (par exemple pour des enregistrements TXT ou SPF) :
~~~
2017-07-22 18:32:38 +02:00
ran out of space
2016-12-29 11:25:39 +01:00
~~~
Vous devez spliter vos champs, voir <http://www.jeoffrey54.com/article144/dns-sous-bind-ran-out-of-space>
### received control channel command 'stop'
En lançant votre démon, celui-ci est stoppé immédiatement avec un simple message d'arrêt :
~~~
received control channel command 'stop'
~~~
2017-07-23 00:55:58 +02:00
…vérifiez si vous n'avez pas oublié l'option `-f` tout en utilisant systemd.
2016-12-29 11:25:39 +01:00
### Zone replica avec Bind 9.9
2016-12-29 11:25:39 +01:00
À partir de Bind 9.9, le stockage des zones répliquées se fait en binaire.
2017-07-22 12:38:15 +02:00
Avec une ancienne configuration vous aurez des erreurs :
2016-12-29 11:25:39 +01:00
~~~
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.
~~~
2017-07-22 12:38:15 +02:00
Pour conserver l'ancien comportement il faut ajouter dans la configuration :
~~~
masterfile-format text;
~~~
2016-12-29 11:25:39 +01:00
Voir <http://geekdom.wesmo.com/2014/06/05/bind9-dns-slave-file-format/>
2017-01-11 17:23:38 +01:00
### Vérifier la configuration
2021-11-16 11:09:38 +01:00
* Globalement :
2017-11-29 16:44:10 +01:00
2017-01-11 17:23:38 +01:00
~~~
# named-checkconf /etc/bind/named.conf
~~~
2017-05-10 20:56:03 +02:00
2021-11-16 11:09:38 +01:00
* Pour une zone en particulier :
2017-11-29 16:44:10 +01:00
~~~
# named-checkzone example.com /etc/bind/db.example.com
~~~
2021-11-16 11:09:38 +01:00
* Pour un reverse :
~~~
# named-checkzone $reversed_IP.in-addr.arpa. /etc/bind/db.reverse.ripe$subnet
~~~
### Forcer un transfer sur le replica
2017-05-10 20:56:03 +02:00
Sur le replica :
2017-05-10 20:56:03 +02:00
~~~
# rndc reload example.com
zone refresh queued
~~~
2017-07-22 12:38:15 +02:00
### Pas d'IPv6 ou souci d'IPv6
2017-07-23 00:12:14 +02:00
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 :
2017-07-22 12:38:15 +02:00
~~~
listen-on-v6 { none; };
~~~
2023-07-17 10:00:33 +02:00
Et via le fichier `/etc/default/named` (`/etc/default/bind9` avant Bullseye) vous allez le forcer à n'effectuer des requêtes qu'en IPv4 :
2017-07-22 12:38:15 +02:00
~~~
OPTIONS="-u bind -4 -t /var/chroot-bind"
~~~
### master "caché"
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` :
~~~
options {
...
}
logging {
...
}
server 192.0.2.53 { edns no; };
~~~
### délai de transfert de zones
Voir <https://kb.isc.org/docs/aa-00726>
2022-02-23 11:40:45 +01:00
### Mise a jour du serial
Vous devez repérer un pattern unique sur la ligne du serial, par exemple `; serial`
On peut ainsi mettre à jour le serial d'une zone :
~~~
$ serial=$(date "+%Y%m%d%H")
$ sed -i "s/^\([ \t]*\)[0-9]\{10\}\([ \t]*; serial\)/\1$serial\2/" db.example.com
~~~
Si l'on doit automatiser, on utilisera les commandes suivantes pour prendre en compte plusieurs modifications le même jour :
~~~
zonefile=db.example.com
serial=$(grep -E '[ \t]*[0-9]{10}\s*; serial' $zonefile | sed "s/[ \t]*\([0-9]\{10\}\)[ \t]*; serial/\1/")
if [ `date "+%Y%m%d%H"` -gt $serial ]; then serial=$(date "+%Y%m%d%H"); else serial=$(( $serial + 1 )); fi
sed -i "s/^\([ \t]*\)[0-9]\{10\}\([ \t]*; serial\)/\1$serial\2/" $zonefile
~~~
2023-12-04 12:20:45 +01:00
### Configuration update-policy
Dans `update-policy`, les régles ACLs prennent la forme `( grant | deny ) identity ruletype name types`
> La première règle qui match un requête sera utilisé
* `identity` correspond à un fqdn ou le nom la clef TSIG
* `name` le nom de l'entrée dans la zone
* `types` le ou les types de l'entrée(s) dans la zone
* `ruletype` est le type de règle utilisé, il en existe une vingtene de valeurs, les plus importantes sont (WIP)
2022-02-23 11:40:45 +01:00
2023-12-04 12:20:45 +01:00
**Les `ruletype`s pricipaux** :
2023-12-04 12:20:45 +01:00
* `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
2023-12-04 12:26:02 +01:00
* Liste complète: <https://bind9.readthedocs.io/en/v9_18_2/reference.html#dynamic-update-policies>
### 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`).