nsd
, un serveur DNS (Domain Name Server) comme maître avec deux esclaves sous nsd
et bind9 (named)
Cette fiche opérationnelle (FICOP) décrit l'installation et la configuration d'un serveur de noms de domaines (DNS
) sous nsd
. En l'espèce nous utiliserons le domaine SCALAIRE.XYZ
.
A la différence de bind
/named
, nsd
ne fait que papa c'est-à-dire qu'il n'assure que la fonction de DNS d'autorité et ce pour les seules zones (domaines) déclarées sous sa responsabilité dans sa configuration, tandis que bind
peut faire à la fois papa et maman, c'est-à-dire qu'il peut, en sus et en même temps, servir n'importe quelle zone en allant interroger ses DNS d'autorité s'il n'en est pas directement responsable. Ce mélange des genres n'est pas nécessairement le plus heureux en terme de sécurité.
nsd
a été conçu pour être sûr et fiable, simple à configurer et à faible empreinte mémoire.
Naturellement, pour mieux le protéger, nsd
peut aussi être utilisé comme maître « caché » depuis une machine non publiée ou non directement accessible depuis l'internet, qui alimentera les DNS « officiels », ceux publiés dans les enregistrements NS
de la zone. Ainsi, seuls les serveurs esclaves connus seront exposés.
Nous préférons désormais nsd
plutôt que bind
. La fonction maman peut être réalisée par unbound
développé exclusivement pour ce seul rôle dans le même esprit que nsd
.
L'intégration de DNSSEC (DNS « sécurisé ») est traitée dans une autre FICOP.
On rappelle que la norme recommande (i) au moins deux DNS, (ii) situés sur deux sous-réseaux distincts, avec malheureusement encore une adresse IPv4 nécessaire et heureusement une adresse IPv6 possible, (iii) IPs qui doivent aussi se résoudre vers leurs noms par un enregistrement PTR
du « reverse DNS ».
Nous utiliserons les ingrédients suivants :
SCALAIRE.XYZ
, le domaine à servir, avec GoDaddy comme registrar ; Note : il s'agit d'un domaine de test qui, à tout moment, peut fonctionner (parfois), disfonctionner (souvent) ou ne plus fonctionner (presque toujours — son état stable au sens de la mécanique statistique) ;
NS.SCALAIRE.FR
, sous nsd
, IPs 2001:41d0:305:2100::9e91
et 51.178.28.184
NS.SCALAIRE.COM
, sous bind9
, IPs 2001:41d0:1008:26d8::53
et 151.80.26.216
.
sing.scalaire.fr
, maître, sous nsd
, IPv6 2406:da18:fa7:9200::5353
;
Ici GoDaddy, il suffit d'indiquer ns.scalaire.com
et ns.scalaire.fr
comme DNS ; la « glue » indiquant leurs adresses IP n'est pas nécessaire s'agissant de machines définies dans d'autres domaines que SCALAIRE.XYZ
.
En revanche, en plus de leurs noms, il faudrait fournir les IPs des DNS se trouvant dans la zone qu'ils doivent servir afin de trancher le nœud gordien « pour accéder au domaine il faut d'abord l'IP de son DNS mais pour obtenir cette IP il faut d'abord pouvoir accéder à ce domaine ».
(La machine est une Debian 10 « Buster »)
apt-get install haveged nsd
haveged
est un démon qui accumule de l'entropie afin de ne pas bloquer /dev/random en cas de forte consommation d'aléas. Nous générons un secret qui sera partagé par les serveurs (/dev/urandom
n'est pas bloquant)
dd if=/dev/random count=1 bs=40 2> /dev/null | base64Créer un répertoire pour centraliser les zones (ici nous préparons la ségrégation avec de futures zones signées en DNSSEC). Y créer la zonemopUXiaeBBNoQYwybGuu8hhTZW1zEm6btRYC+gVaqHtGNbqsdn3ZEg==
SCALAIRE.XYZ
, ici minimaliste.
Note : les $
sont protégés contre leur interprétation par le shell par un \
. En cas de copier/coller dans le fichier, il faudra les enlever.
mkdir /etc/nsd/unsigned_zones chown nsd:nsd /etc/nsd/unsigned_zones chmod 0700 /etc/nsd/unsigned_zones F=/etc/nsd/unsigned_zones/SCALAIRE.XYZ cat > $F <<EOD................. \$TTL 3600 \$ORIGIN scalaire.xyz. @ IN SOA ns.scalaire.com. postmaster.scalaire.com. ( 2018101101 ; Serial 1H ; Refresh 600 ; Retry 4W ; Expires 3H ) ; Min NS ns.scalaire.com. NS ns.scalaire.fr. ; NS sing.scalaire.fr -- hidden master MX 10 smtp.scalaire.com. myself A 127.17.12.4 ; AWS Singapour 08/10/2018 base A 18.141.110.96 ouebe AAAA 2406:da18:fa7:9200::8080 EOD................. chown nsd:nsd $FEditer le fichier de configuration de
nsd
, normalement vide à l'installation. Un mécanisme de « macro » permet de factoriser des données dans un pattern:
qui seront rappelées par son name:
.
cat /etc/nsd/nsd.confserver: debug-mode: yes verbosity: 2 # logfile: "/dev/stderr" # default to syslog# server-count: 3 # multi-cores/CPUs : nums - 1 ip-address: 2406:da18:fa7:9200::5353 # usefull for multi-IPs servers # ip-transparent: yes # should the IPs go up only after nsd startup reuseport: yes # identity: "sing.scalaire.fr" # overwrite /etc/hostname (multi-IPs server) hide-version: yes zonesdir: "/etc/nsd/unsigned_zones"
key: # dd if=/dev/urandom count=1 bs=40 2> /dev/null | base64 name: "ploof" algorithm: hmac-sha256 secret: "mopUXiaeBBNoQYwybGuu8hhTZW1zEm6btRYC+gVaqHtGNbqsdn3ZEg=="
pattern: name: "slaves-of-this-master" outgoing-interface: 2406:da18:fa7:9200::5353 # NS.SCALAIRE.FR notify: 2001:41d0:305:2100::9e91 ploof provide-xfr: 2001:41d0:305:2100::9e91 ploof # NS.SCALAIRE.COM notify: 2001:41d0:1008:26d8::53 ploof provide-xfr: 2001:41d0:1008:26d8::53 ploof
zone: name: "SCALAIRE.XYZ" # case sensitive for the %s filename zonefile: "%s" include-pattern: "slaves-of-this-master"
Créer le fichier du secret partagé
F=/etc/bind/ploof.key cat > $F <<EOD................. key "ploof" { algorithm hmac-sha256 ; secret "mopUXiaeBBNoQYwybGuu8hhTZW1zEm6btRYC+gVaqHtGNbqsdn3ZEg==" ; }; EOD................. chown bind:bind $F chmod 0640 $Fet rajouter une zone esclave à la configuration en adaptant éventuellement le chemin du fichier de stockage automatique de la zone esclave
F=/etc/bind/named.conf.local cat >> $F <<EOD................. zone "scalaire.xyz" { type slave; file "/var/cache/bind/scalaire.xyz"; masters { 2406:da18:fa7:9200::5353 key "ploof" ; }; }; EOD.................Si cet esclave gére d'autres zones reçues de ce même maître, on peut canoniser la clef en rajoutant cette section dans
named.conf.options
server 2406:da18:fa7:9200::5353 { keys { "ploof" ; }; };et la charger dans
named.conf
par un include "/etc/bind/ploof.key";
et alors se contenter d'un masters { 2406:da18:fa7:9200::5353 ; };
S'assurer que named.conf.options
contienne une section
options { ... listen-on-v6 { ...; 2001:41d0:1008:26d8::53; }; ...avec une adresse identique à celle autorisée dans le maître
nsd
.
Avec nsd
tout tient dans un seul fichier
F=/etc/nsd/nsd.conf cat >> $F <<EOD................. key: name: "ploof" algorithm: hmac-sha256 secret: "mopUXiaeBBNoQYwybGuu8hhTZW1zEm6btRYC+gVaqHtGNbqsdn3ZEg==" zone: name: "scalaire.xyz" outgoing-interface: 2001:41d0:305:2100::9e91 # should this server have multiple public IPs # hidden master allow-notify: 2406:da18:fa7:9200::5353 ploof request-xfr: AXFR 2406:da18:fa7:9200::5353 ploof EOD.................
Relancer les serveurs sur toutes les machines en terminant par le maître qui doit envoyer les notification aux esclaves, lesquels ouvrent en retour une connexion pour le transfert de la zone.
systemctl restart bind9
ou
systemctl restart nsd
En cas d'erreur utiliser journalctl -xe
, consulter les journaux et/ou vérifier la gousse d'ail.
Note : entre deux pairs nsd
on peut ignorer les erreurs suivantes
daemon.err nsd[15479]: xfrd: zone scalaire.xyz received error code NOT IMPL from 2406:da18:fa7:9200::5353indiquant un protocole « not implemented », et sur le maître
daemon.info nsd[21934]: axfr for scalaire.fr. from 2001:41d0:305:2100::9e91 daemon.err nsd[21934]: failed reading from 2001:41d0:305:2100::9e91 tcp: Connection reset by peerconfirmant un AFXR (transfert de la zone complète, vs un transfert incrémental IXFR) ainsi que la coupure de connexion (par un RST/TCP).
Depuis une machine tierce,
dig @2406:da18:fa7:9200::5353 scalaire.xyz soa
,
On doit obtenir une en-tête du style
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20321 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5 ;; WARNING: recursion requested but not availableoù
aa
indique une « Authoritative Answer »
Sur le maître, on peut aussi effectuer une mise à jour en incrémentant le serial de la SOA de la zone, ici à 2019122002, puis en rechargeant nsd
systemctl reload nsd ; tail -f /var/log/syslog | grep -F nsd
Dec 20 08:03:08 sing nsd[26748]: new control connection from 127.0.0.1 Dec 20 08:03:08 sing nsd[26748]: control cmd: reload Dec 20 08:03:08 sing nsd[26759]: zone SCALAIRE.XYZ read with success Dec 20 08:03:08 sing nsd[26759]: zone SCALAIRE.XYZ written to db Dec 20 08:03:08 sing nsd-control[31283]: ok Dec 20 08:03:08 sing systemd[1]: Reloaded Name Server Daemon. Dec 20 08:03:08 sing nsd[31285]: axfr for scalaire.xyz. from 2001:41d0:305:2100::9e91 Dec 20 08:03:09 sing nsd[31285]: axfr for scalaire.xyz. from 2001:41d0:1008:26d8::53
Dec 20 09:03:08 ns named[10549]: client 2406:da18:fa7:9200::5353#59579/key ploof: received notify for zone 'scalaire.xyz': TSIG 'ploof' Dec 20 09:03:08 ns named[10549]: zone scalaire.xyz/IN: notify from 2406:da18:fa7:9200::5353#59579: serial 2019122002 Dec 20 09:03:08 ns named[10549]: zone scalaire.xyz/IN: Transfer started. Dec 20 09:03:09 ns named[10549]: transfer of 'scalaire.xyz/IN' from 2406:da18:fa7:9200::5353#53: connected using 2001:41d0:1008:26d8::53#39548 Dec 20 09:03:09 ns named[10549]: transfer of 'scalaire.xyz/IN' from 2406:da18:fa7:9200::5353#53: resetting Dec 20 09:03:09 ns named[10549]: transfer of 'scalaire.xyz/IN' from 2406:da18:fa7:9200::5353#53: connected using 2001:41d0:1008:26d8::53#39030 Dec 20 09:03:09 ns named[10549]: zone scalaire.xyz/IN: transferred serial 2019122002: TSIG 'ploof' Dec 20 09:03:09 ns named[10549]: transfer of 'scalaire.xyz/IN' from 2406:da18:fa7:9200::5353#53: Transfer status: success Dec 20 09:03:09 ns named[10549]: transfer of 'scalaire.xyz/IN' from 2406:da18:fa7:9200::5353#53: Transfer completed: 1 messages, 8 records, 347 bytes, 0.179 secs (1938 bytes/sec) Dec 20 09:03:09 ns named[10549]: zone scalaire.xyz/IN: sending notifies (serial 2019122002)La dernière ligne indique que
bind
propage la notification de la modification aux autres NS, voir ci-après
191220 09:03:08 daemon.info nsd[13722]: notify for scalaire.xyz. from 2406:da18:fa7:9200::5353 serial 2019122002 191220 09:03:08 daemon.info nsd[13712]: xfrd: zone scalaire.xyz committed "received update to serial 2019122002 at 2019-12-20T09:03:08 from 2406:da18:fa7:9200::5353 TSIG verified with key ploof" 191220 09:03:08 daemon.info nsd[13713]: zone scalaire.xyz. received update to serial 2019122002 at 2019-12-20T09:03:08 from 2406:da18:fa7:9200::5353 TSIG verified with key ploof of 269 bytes in 0.000213 seconds 191220 09:03:08 daemon.info nsd[13712]: zone scalaire.xyz serial 2019122001 is updated to 2019122002. 191220 09:03:09 daemon.info nsd[13778]: notify for scalaire.xyz. from 2001:41d0:1008:26d8::53 refused, no acl matches. 191220 09:03:10 daemon.info nsd[13778]: notify for scalaire.xyz. from 151.80.26.216 refused, no acl matches. 191220 09:03:10 daemon.info nsd[13778]: notify for scalaire.xyz. from 2001:41d0:1008:26d8::53 refused, no acl matches
Les lignes refused, no acl matches
indiquent les tentatives de bind
d'envoyer des notifications. En effet, par défaut ou par configuration, celui-ci cherche toujours à informer les autres NS de la zone, et ce à partir de toutes ses IPs (d'où, ici, celle en IPv4 151.80.26.216
obligatoire de part la norme), or notre esclave n'est configuré que pour les accepter de la part de son maître, pas de ses pairs.
Si l'on souhaite réduire ces « erreurs justes » :
bind
, on peut agir globalement, avec effet de bord sur les autres zones, via named.conf.options
options { ... notify no;ou spécifiquement sur la zone dans
named.conf.local
zone "scalaire.xyz" { // general TEST domain type slave; // of the non published master sing.scalaire.fr file "/var/cache/bind/scalaire.xyz"; masters { 2406:da18:fa7:9200::5353 ; }; // see global server{key "ploof";}; notify no; };
nsd
, placer des allow-notify: ...
sur toutes les adresses des autres pairs bind
.
nsd
réduire éventuellement le niveau de verbiage au minimum de production
sed -i -e 's/^\s*verbosity/#&/' -e 's/^\s*debug-mode/#&/' /etc/nsd/nsd.conf systemctl reload nsd(ou bien, après chaque modification de
nsd.conf
: nsd-control reconfig
)
nsd-control -h
; p.ex. sur le maître nsd-control reload SCALAIRE.XYZ
après sa modification ; nsd-control force_transfer SCALAIRE.XYZ
etc...