TP4 : Mise en place et sécurisation du DNS public

Introduction

A présent que vous disposez de ressources matérielles permettant l’hébergement de services publics, nous allons pouvoir commencer la mise en place de ces derniers au bénéfice de l’entreprise fictive WoodyToys. Nous allons démarrer par un service essentiel : un serveur de nom pour la zone DNS publique de l’entreprise. En effet, c’est grâce à lui que les autres services pourront être rendus disponibles aux utilisateurs. Nous verrons également comment le sécuriser, et mettrons notamment en place le DNSSEC pour authentifier les ressources records

A la fin de ce TP, vous devez être capable de :

  • Définir un fichier de zone pour les services publics de l’entreprise WoodyToys
  • Configurer un serveur de nom qui fera autorité sur cette zone
  • Sécuriser la zone en mettant en place le DNSSEC.

Lectures préalables

Les éléments théoriques liés à ce TP sont présentés dans le chapitre 5 : Gestion et sécurisation d’une zone dNS publique du support de cours.

1. Installation et configuration de Bind en tant que serveur autoritaire sur un VPS

1.1. Préparation

Mise en place de l’environnement de travail.

Organisation du VPS

Pour commencer, définissez ensemble votre cadre de travail sur vos VPS :

Quelle sera votre hiérarchie de répertoires?

Nous vous conseillons de vous définir un utilisateur unix non privilégié avec lequel tout le groupe pourra travailler (vous pouvez l’associer à plusieurs clés publiques pour l’accès). Pour vous faciliter la vie et éviter de taper un mot de passe root à chaque commande docker, ajoutez cet utilisateur au groupe docker.

Votre repository Github et son Wiki

N’oubliez pas non plus de mettre en place un repository Github pour votre groupe, pour stocker vos configurations et écrire votre documentation.

Quelle structure allez-vous donner au repository et au wiki ?

  • Pensez bien à “commiter” votre travail à chaque fois que vous obtenez une version fonctionnelle de vos services.
  • N’oubliez pas non plus que chaque étudiant doit participer à ce repository et au wiki avec son propre nom d’utilisateur : les commits sont utilisés comme indicateurs d’implication dans les travaux de groupe.

Méthode de configuration

Enfin, définissez votre mode de fonctionnement pour la mise en place de la configuration. Il peut être intéressant de travailler en plusieurs étapes :

  1. Mise en place de la configuration : Vous allez devoir probablement tâtonner et ajuster votre configuration plusieurs fois avant d’arriver au résultat souhaité. Plusieurs options sont possibles :
    • Lancer un container Bind, ouvrir une session bash dessus et ajuster la configuration manuellement. C’est rapide à mettre en place, mais attention à bien garder une copie de vos configs sur vos machines personnelles!
    • On pourrait également imaginer établir un Bind Mount sur le répertoire /etc/bind, ce qui permettrait d’éditer les fichiers de config directement sur le VPS. Attention cependant : un Bind Mount écrase les fichiers déjà existant au chemin spécifié sur le container. Il vaut mieux faire un Bind Mount directement sur les fichiers visés plutôt que sur l’ensemble du répertoire.
  2. Mise en production de la configuration : Une fois votre configuration Bind fonctionnelle, vous n’aurez probablement plus besoin d’y toucher. Il est donc envisageable de la “figer” dans une image Docker personnalisée. Par contre, votre fichier de zone va évoluer au fur et à mesure du semestre. Un “Bind Mount” peut être une bonne idée dans ce cas de figure (en n’oubliant pas de backuper le fichier de zone régulièrement).

Quelle procédure de gestion des configurations votre groupe a-t’il choisi ?

Nom de domaine

Pour pouvoir disposer d’un DNS public, il faut avant tout disposer d’un nom de domaine. Nous utiliserons comme domaine parent le domaine ephec-ti.be, et chacun de votre groupe disposera de son propre sous-domaine, nommé selon le pattern suivant : [l|m][1|2]-[#groupe].ephec-ti.be. Par exemple, le groupe 2TL1-1 disposera du nom de domaine l1-1.ephec-ti.be.

1.2. Mise en place du serveur autoritaire

Pour cela, vous pouvez construire votre Dockerfile au départ d’une image avec Bind9 pré-installé, comme par ex. l’image internetsystemsconsortium/bind9 (l’Internet Systems Consortion (ISC) est l’organisme en charge du développement de Bind, il s’agit donc d’une image “officielle”). Jetez un oeil sur la documentation de cette image : nous partirons de là pour construire notre serveur autoritaire.

1.2.1 Premier test du container

Voici la commande Docker à utiliser pour démarrer un container Bind destiné à devenir serveur autoritaire.

docker run \
		-d \
        --name=dns \
        -p 53:53/udp \
        -p 53:53/tcp \
        internetsystemsconsortium/bind9:9.18

Cette commande va mapper les ports DNS du container sur les ports 53 du VPS.

Testez-le depuis votre VPS :

dig @localhost www.google.com

Qu’observez-vous comme comportement pré-défini dans ce serveur Bind? Indiquez vos observations et vos conclusions.

1.2.2. Configuration du mode autoritaire

La résolution de noms n’est pas le mode souhaité pour notre container, puisque nous voulons un serveur de noms pour notre zone. Notre serveur DNS doit plutôt être configuré avec les fonctionnalités suivantes :

  • Interdiction de la récursion et de la mise en cache
  • Requêtes acceptées depuis tout l’Internet (nous souhaitons définir une zone publique)
  • Définition du serveur en tant que maître de la zone, en lui indiquant le fichier de zone à utiliser.
    Nous n’avons actuellement qu’un seul serveur autoritaire (serveur primaire). Il faut donc désactiver le transfert de zone puisqu’il n’y a pas de serveur secondaire.

Voici un exemple de fichier named.confqui remplit ce cahier des charges :

options {
  directory "/var/cache/bind";
  // version statement for security to avoid hacking known weaknesses
  // if the real version number is revealed
  version "not currently available";
  allow-query { any; };
  allow-query-cache { none; };
  recursion no;
};

zone "<your-zone>.ephec-ti.be." {
  type master;
  file "/etc/bind/<yourzone>.zone";
  allow-transfer {
    none;
  };
};
  • Pour chacune des trois fonctionnalités listées plus haut, quelle(s) instruction(s) permet sa mise en oeuvre?
  • Pourquoi interdit-on la récursion ?
  • Devez-vous configurer une zone inverse pour votre sous-domaine ? Pourquoi ?
  • Adaptez ce fichier à vos besoins et transférez-le sur votre VPS dans votre répertoire de travail.
  • Créez également un fichier de zone, en spécifiant le RR SOA, le NS et deux ou trois records A.
  • N’oubliez pas d’incrémenter le serial number à chaque modification de ce dernier!

Vous pouvez à présent tester vos configs en les montant dans votre container :

docker run \
		-d \
        --name=dns \
        -p 53:53/udp \
        -p 53:53/tcp \
        --mount type=bind,source=<host directory>/named.conf,target=/etc/bind/named.conf \
        --mount type=bind,source=<hostdirectory>/<zonefile>.zone,target=/etc/bind/<zonefile>.zone \
        internetsystemsconsortium/bind9:9.18

Validation

Pour vérifier si votre container fonctionne, testez-le avec dig :

  • dig @localhost www.google.com ne devrait plus donner la même réponse qu’à l’étape précédente.
  • dig@localhost www.\<your-zone>.ephec-ti.bedevrait vous donner une réponse correcte.

Si ce n’est pas le cas :

  • Utilisez netstat pour vérifier si le mapping des ports a été effectué.
  • Pour obtenir plus d’informations sur l’état de Bind, vous pouvez vous connecter sur le container (docker exec -it dns /bin/bash).
    • Vous pouvez vérifier les fichiers de config et de zone avec named-checkconfet named-checkzone.
    • Si le processus Bind n’a pas démarré, vous pouvez le faire manuellement : bind -g -u bindvous permettra de visualiser les logs directement dans le terminal grâce à l’option -g.
  • Notez qu’actuellement, docker logs dnsne nous fournit aucune information sur l’état de Bind dans le container. C’est parce que dans l’image de base, Bind est lancé en arrière plan alors que Docker collecte les logs envoyés sur stdout/stderr. Il est possible de contourner cela en modifiant la commande de lancement de Bind dans le docker run. Vous pourrez alors consulter les logs depuis docker logs dns.

1.2.3. Construction d’une image pour votre serveur autoritaire

Une fois que votre serveur autoritaire a l’air de fonctionner comme attendu, vous pouvez “figer” la configuration dans une image dédiée.

Voici une proposition de Dockerfile qui peut réaliser cela. Notez qu’on a écrasé la commande CMD disponible dans l’image de départ en changeant le -fen -g, afin de rediriger les logs sur stderr et ainsi permettre à Docker de collecter les logs.

FROM internetsystemsconsortium/bind9:9.18

ADD named.conf /etc/bind/named.conf
ADD <your-zone>.zone /etc/bind/<your-zone>.zone
RUN chown -R bind:bind /etc/bind/

CMD ["/usr/sbin/named", "-g", "-c", "/etc/bind/named.conf", "-u", "bind"]
  • Créez votre Dockerfile
  • Testez-le pour en valider le bon fonctionnement.

1.3. Délégation de la zone

Pour le moment, votre serveur de noms peut fournir les ressources records de la zone à condition de le consulter directement. Cela signifie qu’il faut connaitre l’adresse IP du serveur de nom pour pouvoir l’interroger. Pour rendre cette information publique, il faut se baser sur la structure du DNS, et demander à la zone parente de rediriger les requêtes vers notre serveur. Il s’agit d’une délégation de zone.

Pour effectuer cela, il faut envoyer deux Resource Records au domaine parent :

  • Le Resource Record de type NS pour indiquer le nom du serveur responsable de votre zone.
  • Le Resource Record de type A pour donner l’IP de votre serveur de nom (ce RR s’appelle le Glue Record)

Dans notre cas, le domaine parent est le domaine ephec-ti.be, dont la zone est gérée par l’équipe enseignante.

Voici à quoi devrait ressembler les ressources records que vous devrez envoyer pour la délégation :

lx-y    IN    NS    ns.lx-y.ephec-ti.be. 
ns.lx-y IN    A     1.2.3.4

Attention à la notation utilisée : si vous utilisez des noms relatifs (comme ci-dessous), rappelez-vous que, dans ce cas, il s’agit de ressource records destinés à la zone parente et nom à votre zone. En cas de doute, utilisez plutôt les noms absolus (FQDN).

  • Envoyez vos Resource Records par mail à votre professeur de TP. Comptez quelques jours de délai pour que ce soit réalisé.
  • Vérifiez que l’encodage a été correctement réalisé en interrogeant le serveur OVH sur laquelle la zone parente est hébergée : dig @ns110.ovh.net lx-y.ephec-ti.be devrait vous donner le RR NS et le Glue Record.

Si cette étape est fonctionnelle, vous devriez à présent pouvoir utiliser vos noms de domaines. Vous pouvez alors tester depuis n’importe quelle machine :

ping www.lx-y.ephec-ti.be

1.4. Validation du serveur autoritaire

Pour vérifier si votre zone est correctement configurée, il existe des outils en ligne qui vérifient plusieurs critères, comme par exemple Zonemaster. Testez votre domaine à l’aide de Zonemaster. .

  • Indiquez le screenshot avec l’état de validation de votre zone sur Zonemaster.
  • Expliquez avec vos mots ce que signifie chaque test
  • Faites le bilan de cette validation sur votre zone : quels sont les points d’amélioration ? Si vous pouvez les réaliser, documentez les changements réalisés et montrez bien les screenshots du test de validation avant et après les modifications.

1.5. Pour aller plus loin [facultatif]

Si vous êtes à l’aise avec cette procédure, vous pouvez explorer les pistes suivantes :

  • Configurer un serveur DNS secondaire sur un second VPS
  • Mettre en place le support de l’IPv6 dans votre DNS

2. Sécurisation DNSSEC

2.1. Génération des clés et signature de la zone

La sécurisation DNSSEC a été présentée lors du cours théorique. Le DNSSEC consiste, en résumé, à fournir, pour chaque Resource Record de la zone, une signature cryptographique (RRSIG) pour s’assurer :

  • Que le ressource record n’a pas été modifié (grâce le hash fourni dans la signature),
  • Qu’il est bien issu de la zone indiquée, grâce au chiffrement du hash avec la clé privée de la zone. Le hash peut être déchiffré avec la clé publique, accessible via le record DNSKEY. Notez qu’une chaîne de confiance est nécessaire pour authentifier cette clé publique : la validation de cette dernière s’effectue avec un record DS inséré dans la zone parente.

Bind9 peut se charger de la génération de clés pour la zone, et de la signature des Resources Records.
Pour cela, il suffit d’indiquer les deux lignes suivantes dans votre zone :

  inline-signing yes;
  dnssec-policy default;

La première ligne indique que les signatures seront stockées dans un fichier séparé du fichier de zone original, sous le nom <filezone>.signed. Notez qu’il faut donc que le répertoire de la zone doit être accessible en écriture au processus Bind!

La seconde ligne indique que Bind va utiliser la politique par défaut pour le DNSSEC. Une politique DNSSEC consiste en l’ensemble de paramètres utilisés (ex : algorithme cryptographique, type de clés, durée de vie de la clé, …). La politique par défaut convient dans la plupart des cas. Notez que la durée de vie de la clé principale est illimitée. Si une autre valeur est indiquée, Bind génère alors une autre clé au bout du temps imparti, et se charge de tous les changements associés (à l’exception du DS record dans la zone parente).

Nous ne nous pencherons pas ici sur cette problématique de changement des clés, mais sachez que c’est une procédure non triviale pour laquelle il vaut mieux être bien formé. Cela sort du cadre de ce cours.

Pour en savoir plus sur la politique DNSSEC par défaut de Bind: https://kb.isc.org/docs/dnssec-key-and-signing-policy

  • Configurez le DNSSEC dans votre zone. N’oubliez pas de redémarrez votre serveur DNS.
  • Analysez les résultats de cette configuration.

2.2. Validation de la clé publique via la zone parente

Pour garantir la validité de la clé publique, il faut, comme déjà mentionné plus haut, utiliser une chaîne de confiance. Le DNSSEC se base sur la structure hiérarchique du DNS pour cela : la racine du DNS sera la racine de la chaîne de confiance. La racine se portera garante des TLDs en fournissant une signature validant leurs clés publiques dans un RR de type DS. Les TLDs, quant à eux, contiendront, dans leur fichier de zone, des records DS pour leurs sous-domaines, et ainsi de suite.

Dans le cadre de votre projet, vous devez donc fournir un RR DS à votre domaine parent.

Pour obtenir un resource-record DS au départ de la clé DNSSEC publique, Bind propose l’outil dnssec-dsfromkey. Pour l’utiliser, identifiez le fichier de clé KSK dans votre répertoire de travail Bind, et donnez-le en paramètre à l’outil.

Créez le Record DS au départ de la clé KSK

Ensuite, vous devriez normalement transmettre ce record à votre zone parente, en l’occurrence ephec-ti.be, gérée par les professeurs. Malheureusement, le fournisseur de nom de domaine ne donne pas la possibilité d’ajouter un DS dans la zone. Nous vous demandons donc simplement d’indiquer ce DS record dans votre page Wiki Github dédiée à votre configuration DNS.

2.3. Tester la sécurisation d’une zone DNS

Pour tester la sécurisation DNSSEC d’une zone DNS, plusieurs options existent :

  1. Ces outils en ligne (https://dnssec-analyzer.verisignlabs.com/ et https://dnsviz.net) vous permettront de vérifier la configuration DNSSEC de votre zone. Normalement, tout devrait être “OK”, à l’exception du RR DS dans la zone parente, pour les raisons mentionnées ci-dessus.
  2. Vous pouvez également utiliser Dig pour valider le DNSSEC (voir par exemple ce tuto):
    • Vérifiez avec dig si votre RR pour www est signé en récupérant son RRSIG en même temps que son record A. Vérifiez les flags de la réponses : la présence de ad indique que la validation dnssec a réussi. Son absence montre qu’il y a eu un souci de validation. La requête ci-dessous vous montre une requête DNSSEC validée.
    • Récupérez avec dig la clé publique de votre zone (Record DNSKEY)
    • Vérifiez la chaîne de confiance : Depuis la racine jusqu’à votre parent, pouvez-vous trouver les records DS?
  3. Enfin, notez que l’outil delv permet de rapidement vérifier la validité d’un record ou d’un domaine.
# ~$ dig @1.1.1.1 +dnssec www.nixcraft.com

; <<>> DiG 9.11.5-P4-5.1+deb10u10-Debian <<>> @1.1.1.1 +dnssec www.nixcraft.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48221
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232

;; QUESTION SECTION:
;www.nixcraft.com. IN A

;; ANSWER SECTION:

www.nixcraft.com. 1 IN A 54.184.50.208
www.nixcraft.com. 1 IN RRSIG A 13 3 1 20240220232858 20240220212857 47309 nixcraft.com. JS2HP/njLvZt4j2wkjS96PMRE4NkHrckHe6sBI1kM/heuMzCBkM+vbIp 6+09J2BKnQ06Hjq0Yy4MzXFBRlwdaw==

;; Query time: 17 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Feb 20 22:28:57 UTC 2024
;; MSG SIZE  rcvd: 169
# ~$ delv www.nixcraft.com

; fully validated
www.nixcraft.com. 1 IN A 54.184.50.208
www.nixcraft.com. 1 IN RRSIG A 13 3 1 20240220233505 20240220213504 47309 nixcraft.com. jUu7QEBb/7Z/aNUNFaB56gNDk2RsUO2s638xP1R+tEGFxlUIMiV/iCBm 8KEl0Sft8omY4CKgut1fkVR8EC6jNQ==

Utilisez les trois outils ci-dessous pour valider votre configuration DNSSEC, documentez et commentez les résultats obtenus.

2.4. Configurer un résolveur pour valider le DNSSEC

Fournir des signatures DNSSEC dans les serveurs autoritaires est essentiel, mais si personne ne prend la peine de les vérifier, le mécanisme n’apportera pas la sécurisation espérée.

Si, ultérieurement, vous êtes amenés à mettre en place un résolveur DNS, il faudra le configurer de manière à ce qu’il effectue de la validation DNSSEC. Notez que, dans ses versions les plus récentes, Bind9 active la validation DNSSEC par défaut. De la sorte, lorsqu’il reçoit une réponse DNSSEC non valide lors d’une résolution, il répondra au client par un message d’erreur “SERVFAIL” plutôt que de lui transmettre des informations DNS malicieuses.

Quelle(s) instruction(s) Bind permettent de contrôler si un résolveur effectue une validation DNSSEC ou non?

Pour aller plus loin (facultatif)

  • Mettre en place un résolveur DNS public avec DNSSEC activé, uniquement réservé à vos VPS.
  • [Exploratoire] Mettre en place DNS over TLS ou DNS over HTTPS dans
    • DoT : ce tuto vous donne quelques indications de configuration
    • DoH : Voir par exemple ce tuto de l’ISC. Attention, si vous utilisez DoH, les ports Web devront être utilisés par Bind. Evitez dans ce cas de faire tourner votre serveur Web sur le même VPS que votre serveur DNS. Ou alors, il faudra changer les ports utilisés pour DoH.