Installer son serveur DNS faisant autorité avec NSD

Publié le 16/01/2020

Quand on a réservé un nom de domaine auprès d'un bureau d'enregistrement ce dernier propose souvent d'utiliser ses serveurs DNS pour faire autorité sur la zone. Mais servir sa zone avec ses propres serveurs DNS est bien plus amusant et c'est ce que nous allons faire aujourd'hui à l'aide du logiciel NSD.

Quand il s'agit d'installer un serveur DNS, que ce soit un résolveur ou un serveur faisant autorité, les yeux se tournent systématiquement vers Bind. C'est souvent un choix fait "par défaut" ou parce que c'est celui qui est enseigné en cours et qu'il fait à la fois résolveur et serveur faisant autorité. Cependant il existe bien d'autres logiciels pour servir des zones comme Knot, PowerDNS ou NSD et c'est ce dernier que j'utilise.

Dans cet article je vais prendre pour exemple la zone lithio.fr.

Les glue records

Pour commencer il faut dire à la zone parent qui sont les serveurs DNS faisant autorité sur notre zone en créant des Glue Records.

Parler de Glue Record dans un cours c'est en général un bon moyen de voir si les étudiant⋅e⋅s suivent. On énonce :

"Et donc la zone parent annonce que le DNS faisant autorité pour example.com est ns1.example.com"

et on voit ce qui se passe. Il y en a en général un⋅e pour dire :

"Mais si le parent dit que le DNS qui fait autorité pour example.com c'est ns1.example.com alors il faut résoudre le nom de ns1.example.com, sauf que c'est justement ns1.example.com qui a cette info !"

Et c'est vrai, c'est un problème de l'œuf et de la poule et on résout ça dans le DNS en mettant quand même dans la zone parent les enregistrement A et AAAA des serveurs DNS faisant autorité sur notre zone, en plus des enregistrements NS.

Cela se passe souvent dans l'interface du bureau d'enregistrement où on renseigne les noms et IP dans des champs Glue Record.

Installer le serveur primaire

Nous installons NSD :

# apt install nsd

Nous modifions la configuration principale dans /etc/nsd/nsd.conf :

server:
  ip-address: 198.51.200.1
  ip-address: 2001:db8::1

  port: 53

  server-count: 1

  hide-version: yes

  identity: "ns1.lithio.fr"

  zonesdir: "/var/lib/nsd/zones"

  logfile: "/var/log/nsd.log"
  pidfile: "/run/nsd/nsd.pid"

  include: "/etc/nsd/nsd.conf.d/*.conf"

Cette configuration indique les adresses IP et ports sur lesquelles le serveur doit écouter, le nombre de threads ou encore le dossier qui contient les fichiers de zones.

Gérer ses zones

Pour chaque zone que nous gérons nous allons créer un fichier de configuration dans /etc/nsd/nsd.conf.d/.

Nous éditons le fichier /etc/nsd/nsd.conf.d/lithio.fr.conf :

zone:
    name: lithio.fr
    zonefile: lithio.fr

On indique que l'on crée une zone dont le nom est lithio.fr et dont le fichier de zone se nomme aussi ainsi relativement au chemin indiqué par zonesdir dans la configuration principale de NSD.

Autoriser les serveurs secondaires

Avoir un seul serveur DNS faisant autorité n'est vraiment pas une bonne idée car si ce dernier vient à tomber en panne ou à être inaccessible par exemple alors il devient impossible d'obtenir des réponses pour notre zone.

On fait donc attention à avoir des serveurs secondaires (Les siens, ceux d'amis, etc) qui vont se mettre à jour régulièrement en récupérant le fichier de zone auprès du serveur primaire. Pour cela il suffit de dire dans la partie zone quelles sont les IP et ports des serveurs secondaires que l'on souhaite notifier lors d'un changement dans la zone et qu'on autorise à faire du XFR.

On ajoute donc les champs notify et provide-xfr :

zone:
    name: lithio.fr
    zonefile: lithio.fr
    notify: 198.51.100.1@53 NOKEY
    provide-xfr: 198.51.100.1 NOKEY

On remarque que j'ai ajouté un NOKEY à la fin de ces lignes car il est aussi possible (et c'est recommandé) d'ajouter de l'authentification entre les primaires et les secondaires en utilisant une clé commune.

On ajoute une section key à notre configuration et on y crée une clé en précisant l'algorithme et le secret :

zone:
    name: lithio.fr
    zonefile: lithio.fr
    notify: 198.51.100.2@53 friend_key
    provide-xfr: 198.51.200.1 friend_key

key:
    name: "friend_key"
    algorithm: hmac-sha256
    secret: "4zzNa5Hsd3qr8MBrh65xYnfOPWW+PRhQC/T5T1NDqLc="

Le secret est encodé en base64, par exemple avec cette commande :

dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64

Devenir serveur secondaire

Quand on veut du coup configurer ses serveurs secondaires ou être serveur secondaire d'une zone, il faut déclarer sa zone de la même manière mais en précisant qui sont les serveurs primaires.

zone:
    name: lithio.fr
    zonefile: lithio.fr
    allow-notify: 198.51.100.1 friend_key
    request-xfr: AXFR 198.51.100.1@53 friend_key

key:
    name: "friend_key"
    algorithm: hmac-sha256
    secret: "4zzNa5Hsd3qr8MBrh65xYnfOPWW+PRhQC/T5T1NDqLc="

Cette fois-ci avec un allow-notify pour renseigner les IP autorisées à nous notifier d'un changement dans une zone.

On oublie pas de recharger la configuration de NSD une fois modifié :

# systemctl reload nsd

Éditer le fichier de zone

Comme vu plus haut notre fichier de zone est /var/lib/nsd/zones/lithio.fr, en voici un exemple :

$ORIGIN lithio.fr.
$TTL 3600
@               IN      SOA ns1.lithio.fr. contact.lithio.fr. (
                        2020010807      ; serial
                        86400           ; refresh
                        3600            ; retry
                        3600000         ; expire
                        3600            ; ttl
                )

; NS Servers
@               IN      NS      ns1.lithio.fr.
@               IN      NS      ns2.lithio.fr.

; A Records
@               IN      A       51.254.121.3
ns1             IN      A       51.254.121.3
ns2             IN      A       80.67.176.37
toutetrien      IN      A       51.254.121.3

; AAAA Records
@               IN      AAAA    2001:41d0:401:3000::b8a
ns1             IN      AAAA    2001:41d0:401:3000::b8a
ns2             IN      AAAA    2001:910:1025:1::1
toutetrien      IN      AAAA    2001:41d0:401:3000::b8a

Chaque ligne (ou ensemble de ligne quand il y a des parenthèses) est un enregistrement qui s'écrit de la manière suivante :

Nom     TTL     Classe  Type    Taille  Donnée

Tout cela est expliqué dans la section 3 du RFC 1035, on retrouve généralement :

  • nom : Un nom de domaine relatif au $ORIGIN de la zone ou un FQDN.
  • TTL (Time To Live) (facultatif) : La durée en seconde durant laquelle l'enregistrement devrait être conservé dans le cache d'un résolveur ("devrait" car les administrateur⋅ice⋅s de résolveurs peuvent choisir de changer cela).
  • Classe : Il en existe plusieurs mais c'est majoritairement IN pour INternet qui est utilisé (Cf. Section 3.2 du RFC 6895).
  • Type : Indique le type de l'enregistrement, il en existe plusieurs.
  • Taille (facultatif) : La taille en octets du champs Donnée.
  • Donnée : L'information que l'on souhaite associer au champ et qui dépend du Type (Du texte, une adresse IPv4 ou IPv6, un nom, etc)

Pour expliquer rapidement ce que l'on voit au début du fichier (Cf section 5 du RFC 1035) :

  • $ORIGIN : C'est le FQDN de la zone (qui nous permet d'écrire des noms relatifs à celui-ci par la suite).
  • $TTL : Le TTL par défaut s'il n'est pas précisé dans un enregistrement.

Donc pour mettre à jour notre zone DNS il nous suffit de modifier le fichier puis de dire à NSD de recharger la zone, avec la commande :

$ nsd-control reload lithio.fr

Le serial

Vous avez surement remarqué que dans l'enregistrement SOA de notre zone la troisième valeur se nomme serial. Il s'agit du numéro de version de notre fichier de zone, il faut donc l'incrémenter à chaque modification du fichier.

Il ne faut surtout pas oublier de le faire sans quoi les serveurs secondaires ne voudront pas récupérer la nouvelle version de la zone.

Quant à quoi mettre comme serial, la section 2.2 du RFC 1912 recommande d'utiliser la date du jour suivie d'un nombre (YYYYMMDDnn).

Tester

On peut facilement tester que tel ou tel serveur réponde bien avec un outil comme Drill :

$ drill @ns1.lithio.fr A lithio.fr
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 38363
;; flags: qr aa rd ; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 4 
;; QUESTION SECTION:
;; lithio.fr.   IN  A

;; ANSWER SECTION:
lithio.fr.  3600    IN  A   51.254.121.3

;; AUTHORITY SECTION:
lithio.fr.  3600    IN  NS  ns1.lithio.fr.
lithio.fr.  3600    IN  NS  ns2.lithio.fr.

;; ADDITIONAL SECTION:
ns1.lithio.fr.  3600    IN  A   51.254.121.3
ns2.lithio.fr.  3600    IN  A   80.67.176.37
ns1.lithio.fr.  3600    IN  AAAA    2001:41d0:401:3000::b8a
ns2.lithio.fr.  3600    IN  AAAA    2001:910:1025:1::1

;; Query time: 21 msec
;; SERVER: 51.254.121.3
;; WHEN: Fri Jan 17 14:47:53 2020
;; MSG SIZE  rcvd: 167

Conclusion

Au final malgré la quantité d'informations, gérer ses serveurs DNS faisant autorité est plutôt simple. La partie plus complexe arrive quand on souhaite ajouter de la sécurité avec DNSSEC (ce qu'il faut faire) mais ça fera l'objet d'un prochain article.

Publié dans informatique dns


captcha