Bind9

De Justine's wiki
Aller à la navigation Aller à la recherche

Anciennes notes

Ces notes datent de mon BTS. Elles ne sont peut-être pas à jour. fd

<pdf>Fichier:Tutoriel_DNS.pdf</pdf>

<pdf>Fichier:Tuto_DNS2.pdf</pdf>

<pdf>Fichier:Split-dns.pdf</pdf>

DNSSEC

DNSSEC ? C’est quoi ça ?

Récemment, j’ai décidé de reprendre à mon compte les serveurs dns de mon domaine (afin de me passer de l’horrible interface OVH). Le tout s’est fait sur un cluster bind9 relativement classique (à l’exception de la mise en place du split-dns, que j’ai fait pour mon domaine interne). Et puisque nous sommes à une époque où tout doit passer à la moulinette de la cryptographie asymétrique, j’ai décidé de m’intéresser à DNSSEC.

Présentation du principe global

Le protocole DNS, en lui-même, n’est pas sécurisé. Il date des années 80, alors qu’internet n’était pas ce qu’il est aujourd’hui. Quand un résolveur envoie une requête vers un serveur faisant autorité, il n’as aucun moyen de vérifier son identité ou l’authenticité de la réponse. De plus, il peut alors se retrouver à mettre une réponse erronnée en cache : l’attaquant aura alors empoisonné le cache de celui-ci.

Des extensions de sécurité ont alors créées par l’IETF à partir des années 90, appellées DNSSEC. Ce système renforce l’authentification du DNS en utilisant des signatures numériques, sur le principe de la cryptographie à clefs publiques.

Chaque zone DNS a une paire de clefs. L’admin de la zone utilise la clef privée de la zone pour signer les données DNS dans la zone et générer des signatures numériques. La clef publique est publiée dans la zone même afin de pouvoir être facilement extraite. Ensuite, tout client recevant des données d’un résolveur peut aller vérifier la légitimité des données en vérifiant la signature auprès de la zone d’origine.

Je ne suis pas très forte en schémas, mais l’idée est là. (draw.io, c’est la vie)

Du coup, les données sont authentifiées, et on préserve leur intégrité; et en plus de ça, on s’assure de leur origine. Bon.

La clef publique d’une zone est publiée, mais pour lui faire confiance, il lui faut un petit mot de sa maman. Soit, il faut que la zone mère (fr pour squi.fr, son TLD quoi) la signe. Elle même est signée par la zone racine, et on a ainsi une “chaîne de confiance”.

Dans la pratique, DNSSEC est peu déployée; la faute peut-être à son implémentation qui est un peu prise de tête, contrairement au HTTPS, par exemple. Par exemple, sur 138 millions de site dans le TLD .com, seulement 4.5 sont en DNSSEC. Soit 6,2%. De nombreux “gros” sites ne sont pas en DNSSEC, comme par exemple wikimedia.

Voilà. Maintenant qu’on a une petite base, on va pouvoir passer à la pratique. Préparez l’aspirine.

Mise en place du DNSSEC sur un cluster bind9

Ici, ma zone DNS est organisée de la façon suivante : * Ma zone est squi.fr. Son SOA est dns1.squi.fr, son secondaire dns2.squi.fr * Celle-ci est divisée en deux vues à cause du split DNS. Ici, seule ma vue externe (external) m’intéresse : je ne vais pas faire de DNSSEC dans mon LAN. * Mes fichiers de zone sont dans /var/cache/bind, qui appartient à root:bind * Ma version de bind9 est la 9.16.22 * Mes fichiers de zone sont versionnés avec le temps unix wikipedia

Toute les opérations sont à faire sur le serveur master, sauf mention contraire.

Création des clefs

Je commence par créer un dossier où ranger mes clefs.

<syntaxhighlight lang="bash">mkdir /var/cache/bind/keys chown -R bind:bind /var/cache/bind/keys</syntaxhighlight> On va ensuite créer les clefs dans le dossier.

<syntaxhighlight lang="bash">cd /var/cache/bind/keys dnssec-keygen -a RSASHA256 -b 2048 -f KSK squi.fr dnssec-keygen -a RSASHA256 -b 2048 squi.fr</syntaxhighlight> Ici, on découvre la commande génération des (paires de) clefs. Ces clefs n’ont pas de durée de vie, contraitement à des clefs SSL. * -a : L’algorithme utilisé est fiable selon l’IETF (“For most applications of DNSSEC, SHA-256 should be satisfactory and robust for the foreseeable future, and is therefore recommended for DS/CDS records.” ici. * -b : la clef est en 2048 bits, le maximum. * -f : pour flag. On va expliquer ça. Le flag “KSK” signifie “Key Signing Key”. En gros, il s’agit de la clef privée qui sera utilisée pour signer la clef authentifiant la zone. Cette clef est utilisée pour faciliter la validation des données chez les résolveurs. iana. La deuxième clef, sans flag donc, sera la “Zone Signing Key”, ou ZSK. Cette clef signera notre zone. On a donc nos deux paires de clefs. Elles doivent appartenir à bind.

<syntaxhighlight lang="bash">root@dns:/var/cache/bind/keys# ls Ksqui.fr.+008+04813.key Ksqui.fr.+008+04813.private Ksqui.fr.+008+22802.key Ksqui.fr.+008+22802.private root@dns:/var/cache/bind/keys# chown -R bind:bind .</syntaxhighlight>

Assurez-vous d’avoir une backup de ces clefs; si vous les perdez, vous devrez rechanger l’enregistrement que l’on fera auprès de la zone mère (et elle risque de prendre son temps, la vilaine).

Configuration de bind9

La configuration va ensuite se faire dans /etc/bind/named.conf.local, le fichier où j’ai la configuration de ma zone locale. Ici, je fais la configuration dans ma vue “external”; si vous n’avez pas de split-dns, vous pouver adapter, bien sûr. On va rajouter quatre lignes de configuration:

inline-signing yes;
auto-dnssec maintain;
serial-update-method unixtime; //Uniquement sur le serveur Maître
key-directory "/var/cache/bind/keys";
  • inline-signing : bind va signer sa zone tout seul. Cette option permet, par exemple, à un serveur slave de transférer la zone depuis son master et de la signer par lui-même. Il va également repérer les changements que l’on fera sur la zone (un ajout d’enregistrement CNAME par exemple) et resigner la zone.
  • auto-dnssec maintain : en plus de mettre à jour les clefs et de resigner la zone lorsquela commande “rndc sign mazone” est utilisée; et en plus de ça, ajuste les métadonnées temporelles des clefs. Ces métadonnées sont multiples, mais concernent en gros les dates de publication, activation, etc. des explications.
  • serial-update-method : la méthode que bind va utiliser pour mettre à jour les serials sur ses fichiers de zone (il en génère certains tous seuls). Ici j’utilise unixtime, soit le temps unix; il y’a d’autre possibilités (mais le temps unix, c’est cool). À mettre uniquement sur le master, puisque le slave ne change pas les serials lui-même !
  • key-directory : là où il va aller chercher ses clefs.

Au final, ma zone ressemble à ça:

    zone "squi.fr" {
        inline-signing yes;
        auto-dnssec maintain;
        serial-update-method unixtime;
        key-directory "/var/cache/bind/keys";
        type master;
        allow-transfer { 1.2.3.4; };
        file "/var/cache/bind/external.dns";
        };
};

Une fois fini, on peut reload et vérifier:

rndc reload
systemctl status bind9

Signature de la zone

Courage, on progresse. :p

On va dire à bind9 de signer sa zone.

rndc loadkeys squi.fr IN external

Ici, cette commande sert simplement à dire à bind de signer sa zone (il va alors générer des fichiers dans /var/cache/bind, avec l’extension .signed). Le “IN external” sert à préciser que je suis dans ma zone “external” (rappellez-vous, je fais du split-dns). Si vous n’avez pas de split, vous pouvez l’enlever.

On va ensuite lui dire de générer les enregistrements DNS pour ce qui à trait à DNSSEC.

rndc signing -nsec3param 1 0 10 auto squi.fr IN external
  • signing sert à générer les “signing records”
  • nsec3 est un mécanisme qui permet d’éviter l’énumération d’une zone (voir cet article de Bortz Meyer qui est d’ailleurs très très fort en DNS).
  • le 1 0 10 signifie que l’on utilise du sha-1 pour nsec3, sans “opt-out”, et sur 10 itérations (j’ai pas tout compris non plus, mais en gros, ça va générer un salt). (DNSSEC, c’est compliqué).

Bind va donc signer la zone.

Sur le slave

Il n’y a rien à faire. Vraiment, rien. Au début, j’ai cru, mais non. Voilà.

Obtenir un enregistrement DS

L’enregistrement DS - pour Delegation Signer - est l’enregistrement qui se fait auprès de la zone mère pour que tout le monde puisse avoir confiance dans votre zone. Cela se fait généralement auprès de la boîte qui vous as vendu votre nom de domaine (OVH, dans mon cas).

Je vais donc, dans un premier temps, aller lire chacune des clefs ainsi générées, qui sont dans /var/cache/bind/keys. Je vais devoir trouver ma KSK. Il s’agit d’un fichier en “.key”, qui est public (les .private sont privés, comme leur nom l’indique).

Ma KSK, par exemple. C’est marqué dessus, à la première ligne.

; This is a key-signing key, keyid 1912, for squi.fr.
; Created: 20211127204701 (Sat Nov 27 20:47:01 2021)
; Publish: 20211127204701 (Sat Nov 27 20:47:01 2021)
; Activate: 20211127204701 (Sat Nov 27 20:47:01 2021)
squi.fr. IN DNSKEY 257 3 8 AwEAAd8ySxyfnJsEMFjtmk4JtX9DRAfn0fk5blablabla blabla etc

C’est la KSK que l’on va fournir. Elle signée par les autorités et signe ma ZSK, qui signe ma zone.

Chez OVH, il faut se connecter à l’interface web, cliquer sur sa zone et aller dans l’onglet “DS Records” et cliquer sur modifier, puis ajouter ma KSK. On me demande : * key-tag : c’est le “keyid” à la première ligne (4813 chez moi). * Flag : ici, j’ai le choix entre ZSK (256) et KSK (257). * Algorithme : J’ai fait mes clefs en RSASHA256. * La clef. C’est tout ce qu’il y’a après “256 3 8” dans l’exemple. Attention à virer les espaces qui peuvent se trouver dans la clef.

Plus qu’à attendre qu’OVH fasse son boulot (donc, vous avez le temps de boire une dizaine de cafés). Une fois fini on peut checker sa zone avec cet outil.

Vous pouvez voir clef DNS avec dig :

dig DNSKEY domaine.tld [@serveurdns]

Liens divers

J’ai dû faire pas mal de recherches, DNSSEC étant un problème compliqué. Quelques liens qui m’ont servi : * https://metebalci.com/blog/a-minimum-complete-tutorial-of-dnssec/ * https://linux.die.net/man/8/dnssec-keygen * https://www.verisign.com/en_US/company-information/verisign-labs/internet-security-tools/dnssec-scoreboard/index.xhtml * https://www.cyberciti.biz/faq/unix-linux-test-and-validate-dnssec-using-dig-command-line/ * https://manpages.ubuntu.com/manpages/xenial/man8/rndc.8.html

Troubleshooting

Erreur : journal rollforward failed: journal out of sync with zone (ou zone qui ne semble pas répondre)

Si la zone a été mise à jour tandis que le service bind9 était en train de tourner, il se peut que l'on rencontre l'erreur ci-dessus lors du restart; ou bien que la zone ne semble simplement pas répondre. Dans ce cas, il faut arrêter le service, et efface le fichier .jnl correspondant à notre zone, situé juste à côté de celle-ci, puis relancer le service.