<?xml version="1.0" encoding="utf-8"?>
<rfcdesc title="Clarifications on CDS/CDNSKEY and CSYNC Consistency"
	 num="9975" status="standards" wg="dnsop">
  <authors><author>P. Thomassen (SSE - Secure Systems
  Engineering)</author></authors>
  <rfcdate><month>May</month><year>2026</year></rfcdate>
  <date>2026-05-28</date>
<content>
  <p>Pour compléter un processus de sécurisation des <wikipedia
  name="Nom de domaine">noms de domaine</wikipedia> avec <wikipedia
  name="Domain Name System Security Extensions">DNSSEC</wikipedia>, il
  faut transmettre au domaine parent votre <wikipedia
  name="Cryptographie asymétrique">clé publique</wikipedia>. Le faire
  manuellement via l'interface Web du <wikipedia name="Bureau
  d'enregistrement">BE</wikipedia> n'est pas pratique donc il existe
  un moyen d'automatiser cela, les CDS/CDNSKEY, moyen décrit dans le
  <rfc num="7344" local="true"/>. Mais attention à la sécurité ! Ce
  moyen n'est sûr que si on suite quelques précautions, décrites dans
  ce nouveau <wikipedia name="Request for
  comments">RFC</wikipedia>.</p>
  <p>Bon, je sais, j'ai simplifié, on ne transmet pas forcément au
  domaine parent sa clé publique mais parfois un
  <wikipedia name="Fonction de hachage cryptographique">condensat</wikipedia> de celle-ci. (Le domaine parent
  publiera ensuite un enregistrement DS, contenant un condensat que
  vous aurez donné ou bien qu'il aura calculé à partir de la clé.) Ça
  ne change pas grand'chose en pratique. Le <rfc num="7344"
  local="true"/> décrit comment automatiser le changement de clé en
  publiant dans <emphasis>son</emphasis> domaine des enregistrements
  CDS et/ou CDNSKEY, qui informent le parent. (Et le <rfc num="9615"
  local="false"/> permet de le faire pour la configuration initiale,
  pas juste pour un changement.) Avec une technique proche, les
  enregistrements CSYNC du <rfc num="7477" local="true"/>, on peut
  aussi automatiser le changement des <link
  local="serveur-dns-faisant-autorite">serveurs de noms faisant
  autorité</link>.</p>
  <p>À partir de là, le gestionnaire du domaine parent (typiquement un
  <wikipedia name="Registre de noms de domaine">registre de noms de domaine</wikipedia>) va récupérer ces
  enregistrements et agir (modifier les enregistrements DS et NS dans
  son domaine). La façon la plus simple de récupérer les CDS, CDNSKEY
  et CSYNC est de faire une bête requête <wikipedia name="Domain Name
  System">DNS</wikipedia> classique, donc via son <link
  local="resolveur-dns">résolveur</link> par défaut :
  <code>
<![CDATA[
% dig turris.cz CDS    
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16850
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
turris.cz.		5	IN	CDS	53148 13 2 9A0E997A2992D4089CE39C1976DC65C00C9D20A6C36187F897E71D6E 23368E6E

;; Query time: 24 msec
;; SERVER: 192.168.2.254#53(192.168.2.254) (UDP)
;; WHEN: Fri Jan 09 11:15:20 CET 2026
;; MSG SIZE  rcvd: 86

% dig alatienne.fr CDNSKEY
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53877
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
alatienne.fr.		3600 IN	CDNSKEY	257 3 13 (
				mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+Gq
				JxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==
				) ; KSK; alg = ECDSAP256SHA256 ; key id = 2371

;; Query time: 52 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Thu Feb 05 16:35:32 CET 2026
;; MSG SIZE  rcvd: 229
]]>
  </code>
  Mais cette méthode n'est pas très sûre et nous allons voir pourquoi,
  et comment arranger les choses.</p>
  <p>Ici, la réponse CDS était signée par <wikipedia name="Domain Name
  System Security Extensions">DNSSEC</wikipedia> (le
  <foreign>flag</foreign> <computer>ad</computer>, pour
  <foreign>Authentic Data</foreign>). Mais ce n'est pas toujours le
  cas (avec les CSYNC, ou tout simplement lors de la configuration
  initiale de DNSSEC, cf. <rfc num="8078" local="true"/>).  Le fond du
  problème est que les <link
  local="serveur-dns-faisant-autorite">serveurs faisant
  autorité</link> pour le domaine qui publie CDS, CDNSKEY ou CSYNC
  peuvent être en désaccord. (Ou bien, mais le RFC ne semble pas le
  mentionner, il y a eu empoisonnement de la mémoire du résolveur.) Ce
  désaccord peut être dû à un piratage d'un des serveurs (ou à une
  malveillance de ses opérateurs) mais il peut être aussi le résultat
  d'un <link local="dns-afrinic-stale">cafouillage technique</link>
  (un serveur ne se synchronisant plus) ou organisationnel, les
  serveurs n'étant pas forcément gérés par la même entité. Sans
  compter le risque d'une délégation boiteuse (<foreign>lame
  delegation</foreign>) où un des serveurs listés dans l'ensemble NS
  n'est pas censé être serveur pour ce domaine. D'ailleurs, même
  DNSSEC ne protège pas dans tous les cas, s'il y a plusieurs signeurs
  (<rfc num="8901" local="true"/>), ils peuvent aussi déconner
  séparement. Avec le comportement par défaut du résolveur typique
  (accepter la réponse du premier serveur faisant autorité qui
  répond), un seul des serveurs faisant autorité peut déclencher un
  changement de configuration dans le domaine parent. Le cœur de notre
  nouveau <wikipedia name="Request for comments">RFC</wikipedia> est
  de dire que le logiciel qui récupère CDS/CDNSKEY/CSYNC doit
  s'assurer que les serveurs faisant autorité sont
  <emphasis>cohérents</emphasis>, qu'ils renvoient tous la même
  réponse.</p>
  <p>Cela ne peut pas se faire via un résolveur typique, je n'en
  connais pas qu'on puisse configurer pour faire cela, il faut donc
  interroger directement les serveurs faisant autorité. Par exemple,
  pour la requête <wikipedia name="Dig (programme
  informatique)">dig</wikipedia> ci-dessus, un moyen de le faire
  serait, par exemple en <wikipedia name="Shell Unix">shell</wikipedia> :
  <code>
% for ns in $(dig +short turris.cz NS); do
  dig @$ns +short turris.cz CDS
done
53148 13 2 9A0E997A2992D4089CE39C1976DC65C00C9D20A6C36187F897E71D6E 23368E6E
53148 13 2 9A0E997A2992D4089CE39C1976DC65C00C9D20A6C36187F897E71D6E 23368E6E
53148 13 2 9A0E997A2992D4089CE39C1976DC65C00C9D20A6C36187F897E71D6E 23368E6E
  </code>
  Et il faudrait ensuite s'assurer que toutes les réponses sont
  identiques. Sinon, le domaine parent s'abstient d'agir. (Comme les
  lecteurs et lectrices de ce blog sont très fort·es en réseau, ielles
  ont certainement remarqué que j'avais simplifié : comme un serveur
  peut avoir plusieurs adresses IP, il faudrait les tester toutes. Des
  exemples de programmes plus perfectionnés figurent par la suite.)
  </p>
  <p>Ces nouvelles règles amènent à mettre à jour quelques RFC, qui ne
  les spécifiaient pas : les <rfc num="7344" local="true"/> et la
  section 3.1 du <rfc num="7477" local="true"/>, qui conseillait de ne
  demander qu'à un seul serveur faisant autorité (ce que fait le
  résolveur typique mais qui n'est pas assez sûr).</p>
  <p>La section 3 du RFC liste plus formellement les nouvelles
  exigences :
  <enum>
    <item>Tester la présence et le contenu des CDS/CDNSKEY/CSYNC via
    <emphasis>toutes</emphasis> les <wikipedia name="Adresse
    IP">adresses IP</wikipedia> des <link
    local="serveur-dns-faisant-autorite">serveurs faisant
    autorité</link>.</item>
    <item>Toutes les réponses <emphasis>doivent</emphasis> être
    identiques.</item>
    <item>On peut arrêter le test dès qu'au moins une des réponses
    correspond au DS/NS existant. Cela veut dire qu'au moins un des
    serveurs faisant autorité ne veut pas qu'on change.</item>
  </enum>
  Si et seulement si toutes les réponses sont identiques, et
  différentes de la situation actuelle, le gestionnaire du domaine
  parent peut envisager de modifier NS et DS.</p>
  <p>Notez que, si les serveurs faisant autorité utilisent
  l'<foreign><wikipedia>anycast</wikipedia></foreign>, le test ne sera
  pas complet, le vérificateur de cohérence ne testera qu'une seule
  instance d'un nuage <foreign>anycast</foreign>. Dans ce cas, il peut
  être intéressant de tester la cohérence depuis plusieurs points de
  mesure, pour avoir des chances de contacter plusieurs instances
  <foreign>anycast</foreign>.</p>
  <p>La même règle s'applique aux enregistrements CSYNC du <rfc
  num="7477" local="true"/>. La section 3.2 de notre RFC détaille
  comment traiter ces enregistrements, qui permettent notamment de
  synchroniser les enregistrements NS du domaine parent (et <link
  url="https://www.afnic.fr/observatoire-ressources/papier-expert/le-dns-ca-colle-ou-ca-ne-colle-pas/">la
  colle</link>) avec ceux du domaine fils. Il y a une petite nuance
  pour le numéro de série de la zone que contient l'enregistrement
  CSYNC (il doit être identique à celui du SOA du même serveur, pas
  forcément à ceux des CSYNC des autres serveurs faisant
  autorité).</p>
  <p>La section 5 de notre RFC discute les conséquences pour la
  sécurité. Si on ne fait pas les vérifications décrites ici, il y a
  un risque de copier dans la zone parente des données incorrectes,
  voire créées par un attaquant, par exemple parce qu'il a réussi à
  pirater un des serveurs faisant autorité ou bien parce qu'il gérait
  un de ces serveurs mais agissant sans autorisation du gérant de la
  zone (cas courant si on sous-traite certains de ses serveurs
  secondaires). Ce RFC privilégie donc l'intégrité des données, au
  risque, on peut le remarquer, qu'un changement souhaité prenne
  davantage de temps, si un des serveurs faisant autorité a des
  problèmes. Que faire si un de ces serveurs ne veut vraiment pas
  jouer le jeu et, par exemple, ne se synchronise plus et ne publie
  pas le nouveau CDS/CDNSKEY/CSYNC ? La section 5 dit qu'il faut donc
  maintenir un canal traditionnel (via le <wikipedia name="Bureau
  d'enregistrement">BE</wikipedia>, <link
  url="https://www.afnic.fr/observatoire-ressources/papier-expert/que-se-passe-t-il-quand-on-enregistre-un-nom-de-domaine/">par
  exemple</link>), pour pouvoir changer quand même les données
  publiées par la zone parente. C'est par exemple le rôle d'<wikipedia
  name="Extensible Provisioning Protocol">EPP</wikipedia> (<rfc
  num="5730" local="true"/>).</p>
  <p>Cette vérification de la cohérence a déjà été mise en œuvre dans
  les logiciels de <link
  url="https://www.knipp.de/it-es/tango">TANGO</link> et <link
  url="https://corenic.org/">CORE</link>, ainsi que déployée par
  <wikipedia name=".ch">le registre suisse</wikipedia>. <link
  url="https://zonemaster.fr/">Zonemaster</link> <link
  url="https://doc.zonemaster.net/latest/specifications/tests/DNSSEC-TP/dnssec15.html">fait
ce test</link>.</p>
  <p>Enfin, l'annexe A du RFC décrit plus en détail des scénarios où
  l'incohérence entre les serveurs faisant autorité pour un domaine a
  eu des conséquences fâcheuses. Par exemple, si un domaine a une
  délégation boiteuse, vers un serveur qui n'existe pas, un
  malveillant peut créer le serveur en question, mettre un CSYNC en
  indiquant uniquement des serveurs qu'il contrôle et transformer une
  simple délégation boiteuse en un détournement complet du nom. Si le
  serveur non-existant était dans un nom de domaine non enregistré,
  l'attaquant n'a qu'à enregistrer ce nom (attaque flamant). Si le
  serveur non-existant était sur une adresse IP libre chez un
  hébergeur public, l'attaquant n'a qu'à créer des machines chez cet
  hébergeur jusqu'à tomber sur l'adresse en question (une variante de
  l'attaque des sous-domaines). Ce genre d'attaques est décrit dans
  des articles comme « <foreign><link
  url="https://dl.acm.org/doi/10.1145/3419394.3423623">Unresolved
  Issues: Prevalence, Persistence, and Perils of Lame
  Delegations</link></foreign> » ou « <foreign><link
  url="https://dl.acm.org/doi/10.1145/3487552.3487816">Risky BIZness:
  risks derived from registrar name
  management</link></foreign> ». Bon, si le domaine est signé avec
  <wikipedia name="Domain Name System Security
  Extensions">DNSSEC</wikipedia>, il est protégé, non ? Oui, sauf si
  l'attaquant peut changer la clé avec un CDS… D'où l'importance de la
  vérification de cohérence de ce RFC.</p>
  <p>Autre exemple d'accident possible (et qui n'est pas dû à une
  attaque délibérée), dans le cas où un domaine a plusieurs signeurs
  DNSSEC (<rfc num="8901" local="true"/>), si un des serveurs faisant
  autorité ne publie que ses propres clés dans un CDS. Sans
  vérification de cohérence, au lieu d'avoir plusieurs DS comme prévu,
  on n'en aura qu'une partie.</p>
  <p>Et si vous cherchez un programme simple qui fait à peu près ce
  que demande le RFC, vous avez <computer><file
  name="cds-consistency.py"/></computer> :
  <code>
% ./cds-consistency.py knot-resolver.cz      
knot-resolver.cz is consistent, data is "None"

% ./cds-consistency.py àlacon.fr 
àlacon.fr is consistent, data is "7177 13 2 fa99827c7aca1681b8905285e7fa33ec5adccb430393b4fa1e9f9aa3d9263709"
  </code></p>
  </content>
</rfcdesc>
