Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

RFC 9824: Compact Denial of Existence in DNSSEC

Date de publication du RFC : Septembre 2025
Auteur(s) du RFC : S. Huque (Salesforce), C. Elmerot (Cloudflare), O. Gudmundsson
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 12 décembre 2025


Plus fort que le chat de Schrödinger qui était à la fois mort et vivant, ce RFC permet à un nom de domaine d'être à la fois existant et non-existant. Plus précisément, il permet de fournir une preuve cryptographique avec DNSSEC, prouvant que le nom existe (alors qu'il n'existe pas) mais n'a pas les données demandées. Cette technique (autrefois connue sous le nom de « black lies », et largement déployée) est particulièrement adaptée au cas des signatures générées dynamiquement, mais a l'inconvénient de « mentir » sur l'existence du nom.

Pour comprendre, il faut revenir à un problème agaçant pour DNSSEC : le déni d'existence. Ce terme désigne le fait de prouver qu'un nom, ou qu'un certain type de données pour un nom, n'existe pas. Car DNSSEC fonctionne en signant les données. Mais en cas de non-existence, il n'y a rien à signer. DNSSEC a donc ajouté un type d'enregistrement nommé NSEC qui encadre le nom manquant. Et ces enregistrements, eux, sont signés. Un enregistrement NSEC affirme « ce nom n'existe pas » en donnant le nom précédent et le nom suivant (ici, la réponse d'un serveur racine à qui on a demandé www.trump alors que le TLD .trump n'existe pas) :


;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 65362
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1
…
travelersinsurance.	86400	IN	NSEC	trust. NS DS RRSIG NSEC

On obtient un NXDOMAIN (ce nom n'existe pas), zéro réponse (la section Answer est vide) et l'enregistrement NSEC nous dit qu'il n'y a rien entre travelersinsurance et trust. Comme il est signé (je n'ai pas montré les signatures), nous avons une preuve de non-existence.

Et si le nom existe, mais n'a pas de données du type demandé ? J'interroge mon résolveur sur la localisation associée au nom www.iis.se :


% dig +dnssec www.iis.se LOC
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39872
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
…
www.iis.se.		480	IN	NSEC	xmpp01.iis.se. A AAAA RRSIG NSEC
…

  

Le NOERROR est normal (le nom existe) mais la section Answer est vide (puisqu'il n'y a pas d'enregistrement de type LOC) et le NSEC nous dit que le nom existe bien (le nom suivant étant xmpp01.iis.se.) mais n'a comme type d'enregistrement que A, AAAA, RRSIG et NSEC. On a donc prouvé que le LOC n'existe pas.

Bon, tout ça, c'est du DNSSEC classique, tel que normalisé dans les RFC 4034 et RFC 4035. Ça marche, mais cela a des inconvénients, notamment pour les signatures générées dynamiquement. Cela nécessite plusieurs NSEC (il faut aussi montrer qu'il n'y a pas de joker), avec leurs signatures.

CDE (Compact Denial of Existence, alias black lies) fonctionne (section 3 du RFC) en calculant un intervalle minimal entre les noms, comme le faisaient les white lies du RFC 4470. Mais, contrairement à eux, CDE fait partir cet intervalle du nom demandé. Par exemple, si on demande foobar.example et que ce nom n'existe pas, les white lies fabriqueront un NSEC allant de ~.foobaq~.example à foobar!.example alors que les black lies de notre RFC feront un NSEC allant de foobar.example à \000.foobar.example. Cet intervalle démarrant au nom de domaine demandé, il ne faut plus jamais renvoyer de NXDOMAIN, uniquement des NODATA (NOERROR mais avec une section Answer vide).

Voici un exemple de black lie chez Cloudflare (qui a déployé CDE il y a longtemps) :


% dig +dnssec doesnotexistcertainly.cloudflare.com                           
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43853
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
…
;; AUTHORITY SECTION:
doesnotexistcertainly.cloudflare.com. 300 IN NSEC \000.doesnotexistcertainly.cloudflare.com. RRSIG NSEC TYPE128
…
;; Query time: 14 msec
;; SERVER: 192.168.2.254#53(192.168.2.254) (UDP)
;; WHEN: Fri Dec 12 14:10:39 CET 2025
;; MSG SIZE  rcvd: 400

  

Mais puisqu'on ne renvoie jamais de NXDOMAIN, comment distinguer un nom qui n'existe pas d'un nom qui n'a simplement pas le type demandé ? La section 2 du RFC présente le type NXNAME (enregistré avec le numéro 128, d'où le TYPE128 ci-dessus). Sa présence dans le NSEC indique que le nom n'existe pas. Comparez la réponse ci-dessus avec celle-ci, où le nom existe, mais pas le type (hex.pm est chez Cloudflare et n'a pas d'adresse IPv6 associée à son nom) :


% dig +dnssec hex.pm AAAA
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5431
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
…
hex.pm.			1800	IN	NSEC	\000.hex.pm. A NS SOA HINFO MX TXT LOC SRV NAPTR CERT SSHFP RRSIG NSEC DNSKEY TLSA SMIMEA HIP CDS CDNSKEY OPENPGPKEY SVCB HTTPS URI CAA

  

La longue liste de types dans le NSEC (mais sans le NXNAME/TYPE128) est due au fait que le serveur, qui génère des NSEC (et des signatures) dynamiquement ne connait pas la vraie liste donc il met tout ce qu'il connait.

Un résolveur qui connait les NXNAME peut donc refabriquer un code de retour NXDOMAIN et l'envoyer à ses clients (section 5 du RFC). Un nouveau booléen dans la question envoyée aux serveurs faisant autorité, le CO (Compact Answers OK) peut être utilisé pour dire au serveur faisant autorité qu'il peut répondre avec un NXDOMAIN, le client DNS qui met le CO indique qu'il saura lire et interpréter le NXNAME. (Le CO a été enregistré à l'IANA, le premier booléen d'une requête EDNS à être enregistré depuis DO il y a vingt-quatre ans.) Cette possibilité de rétablissement du NXDOMAIN ne semble pas très souvent mise en œuvre actuellement.

Notez (section 4) qu'on peut utiliser CDE avec NSEC3 mais que cela n'a aucun intérêt, vu que la compacité de l'intervalle des noms empêche déjà l'énumération des noms.

Enfin, si vous aimez les détails, l'annexe A du RFC discute des raisons des choix faits, et des alternatives étudiées (et même testées dans la nature), mais non retenues.

CDE est largement déployé aujourd'hui, notamment chez Cloudflare, déjà cité, mais aussi chez d'autres hébergeurs utilisant la signature dynamique, comme NS1. En logiciel libre, Knot permet le CDE. Il y a aussi une implémentation (mais qui n'a pas été maintenue synchrone avec le RFC) dans mon serveur Drink. Elle fut développée lors d'un hackathon IETF. Elle n'est pas activée par défaut, il faut changer un paramètre dans le source (lib/drink/dnssec.ex).


Téléchargez le RFC 9824

Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)

Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)