Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

Les RFC (Request For Comments) sont les documents de référence de l'Internet. Produits par l'IETF pour la plupart, ils spécifient des normes, documentent des expériences, exposent des projets...

Leur gratuité et leur libre distribution ont joué un grand rôle dans le succès de l'Internet, notamment par rapport aux protocoles OSI de l'ISO organisation très fermée et dont les normes coûtent cher.

Je ne tente pas ici de traduire les RFC en français (un projet pour cela existe mais je n'y participe pas, considérant que c'est une mauvaise idée), mais simplement, grâce à une courte introduction en français, de donner envie de lire ces excellents documents. (Au passage, si vous les voulez présentés en italien...)

Le public visé n'est pas le gourou mais l'honnête ingénieur ou l'étudiant.


RFC 9991: Domain-Based Message Authentication, Reporting, and Conformance (DMARC) Failure Reporting

Date de publication du RFC : Mai 2026
Auteur(s) du RFC : S. Jones (DMARC.org), A. Vesely (Tana)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dmarc
Première rédaction de cet article le 20 mai 2026


DMARC (RFC 9989) permet de demander l'envoi, par les destinataires des messages, de rapports indiquant les éventuels problèmes notés, afin de diminuer le nombre de faux positifs (messages légitimes incorrectement considérés comme invalides). Cette demande de rapports se fait en ajoutant l'option ruf à l'enregistrement DMARC. Ce RFC décrit ces rapports.

Il y a au moins deux raisons de demander ces rapports :

  • Comprendre pourquoi certains des messages qu'on envoie sont classés comme invalides alors qu'ils ne devraient pas l'être. On va donc analyser des rapports concernant des messages qu'on a réellement envoyés.
  • Détecter les tentatives d'usurpation du domaine. On va donc analyser des rapports concernant des messages qu'on ne connaissait pas, et qu'un méchant a envoyés.

Notez qu'il existe aussi des rapports agrégés (RFC 9990, avec un format très différent, fondé sur XML) et qu'on demande parfois des rapports individuels parce qu'on note dans les rapports agrégés qu'il y a beaucoup d'erreurs et qu'on voudrait comprendre leur origine.

Le format normalisé ici dérive du format ARF (Abuse Reporting Format, RFC 6591), qui décrivait les rapports pour les problèmes SPF et DKIM. L'option ruf dans l'enregistrement DMARC (RFC 9989, section 4.7) indique à quelle adresse de courrier le rapport doit être envoyé. Voici par exemple l'enregistrement DMARC de afnic.fr :

dig +short _dmarc.afnic.fr TXT
"v=DMARC1; p=quarantine; pct=100; ruf=mailto:dmarc-feedback@afnic.fr; rua=mailto:dmarc-feedback@afnic.fr; fo=1"

Vous voyez le ruf ? Il indique que les rapports doivent être envoyés à dmarc-feedback@afnic.fr. Attention, j'ai écrit « doivent » mais, évidemment, les récepteurs de courrier ne sont pas obligés d'envoyer ces rapports, qui peuvent leur coûter des ressources et poser des problèmes de vie privée.

Pour DMARC, notre RFC ajoute au format du RFC 6591 les champs (section 4, ils sont listés dans un registre IANA) :

  • Identity-Alignment:, qui liste les mécanismes d'authentification où il n'y a pas d'alignement avec l'expéditeur,
  • Delivery-Result:,
  • DKIM-Domain:, et quelques autres au sujet de DKIM,
  • SPF-DNS:.

Il y a un autre piège avec les rapports, c'est la possibilité d'indiquer dans ruf l'adresse de quelqu'un d'autre, pour l'embêter avec beaucoup de rapports qui ne le concernent pas. La section 4 du RFC 9990 explique les précautions que devrait prendre un receveur de courrier avant d'envoyer un rapport vers une adresse qui n'est pas dans le domaine concerné, comme de tester le sous-domaine _report._dmarc. (Dans l'exemple afnic.fr plus haut, il n'y avait pas de problème, le destinataire des rapports est dans le domaine concerné.)

J'ai mentionné un peu plus haut la question de la vie privée. Les rapports détaillés, contrairement à leurs copains agrégés du RFC 9990, peuvent être très indiscrets, notamment parce qu'ils contiennent souvent des données personnelles, par exemple dans les champs indiquant l'expéditeur et le destinataire. Et il ne suffit pas de se dire « Bon, de toute façon, le gestionnaire du système envoyeur avait accès au message quand il est parti de son système » car le message a pu être transmis et re-transmis et le rapport donnera des informations sur des destinataires finaux. Une section 7, trés détaillée, couvre donc ce problème. Elle note par exemple que beaucoup de gros receveurs de courrier n'envoient pas du tout de rapport individuel, seulement des rapports agrégés. Et elle recommande que, même si on envoie les rapports, on en supprime les éléments les plus sensibles (voir le RFC 6590).

Enfin, à envoyer un rapport par message, on noiera l'expéditeur supposé sous des rapports qui concerneront des spams envoyés en nombre. Donc, prudence.

Un point amusant, que je vois pour la première fois dans un RFC : ce RFC 9991 recommande de modifier les URL présents dans les rapports en remplaçant http par hxxp. Cette convention est assez courante dans le monde de la sécurité Internet, pour éviter qu'un humain ne clique trop vite sur un lien malveillant.

L'annexe A du RFC donne un exemple de rapport, je ne montre ici que la partie MIME qui concerne le rapport proprement dit¸:

   --=_mime_boundary_
   Content-Type: message/feedback-report
   Content-Transfer-Encoding: 7bit

   Feedback-Type: auth-failure
   Version: 1
   User-Agent: DMARC-Filter/1.2.3
   Auth-Failure: dmarc
   Authentication-Results: gen.example;
     dmarc=fail header.from=consumer.example
   Identity-Alignment: dkim
   DKIM-Domain: consumer.example
   DKIM-Identity: @consumer.example
   DKIM-Selector: epsilon
   Original-Envelope-Id: 65E1A3F0A0
   Original-Mail-From: author=gen.example@forwarder.example
   Source-IP: 192.0.2.2
   Source-Port: 12345
   Reported-Domain: consumer.example
  

Le message prétend venir de consumer.example mais aucune signature DKIM n'est valide, sans doute suite à des modifications chez forwarder.example ou bien parce que la clé DKIM n'a pu être récupérée dans le DNS.

Apparemment, OpenDKIM est capable de générer ces rapports, mais je n'ai pas testé.


Téléchargez le RFC 9991


L'article seul

RFC 9989: Domain-based Message Authentication, Reporting, and Conformance (DMARC)

Date de publication du RFC : Mai 2026
Auteur(s) du RFC : T. Herr (Valimail), J. Levine (Standcore)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dmarc
Première rédaction de cet article le 20 mai 2026


DMARC est une technique d'authentification du courrier électronique qui permet à un domaine d'indiquer quelle est sa politique de sécurité vis-à-vis des messages dont l'expéditeur (le champ From: de l'en-tête) indique ce domaine. Il donne au gérant du domaine la possibilité d'annoncer sa politique de sécurité « tous les messages de ce domaine sont authentifiés (via SPF ou DKIM) ». Typiquement, DMARC est le couronnement d'une démarche de sécurité du courrier, ce qu'on annonce quand on a bien tout authentifié. Par contre, attention, en authentifiant la donnée visible par les utilisateurs et pas les données techniques, il casse certains usages du courrier. DMARC était à l'origine normalisé dans le RFC 7489, que ce nouveau RFC remplace. Mais rassurez-vous si vous avez déjà déployé DMARC : les changements ne sont pas radicaux. Le principal est le nouvel algorithme pour trouver l'enregistrement DMARC pertinent (celui à l'apex du domaine enregistré).

Revenons sur les problèmes de sécurité du courrier électronique. Un message typique, tel que normalisé par le RFC 5322, comprend dans son en-tête ce genre d'informations :


Date: Wed, 18 Mar 2026 17:28:36 +0800
From: Jiankang Yao <yaojk@cnnic.cn>
To: 125attendees@ietf.org
Subject: [125attendees] Wednesday 8:00 pm, Shenzhen light show for IETF 125
X-Mailer: iPhone Mail (21D61)
[et bien d'autres]    

  

Une qui nous intéresse particulièrement est l'expéditeur. Cette notion est plus compliquée qu'il n'y parait (il y a plusieurs définitions possibles de « expéditeur ») mais pour DMARC, c'est simple : le champ qui nous intéresse est uniquement le From: (section 3.6.2 du RFC 5322). C'est en effet celui qui est typiquement affiché par les MUA, et c'est celui que DMARC va protéger. On l'appelle souvent RFC5322-From pour le distinguer de celui qui apparait dans l'enveloppe du courrier, le RFC5321-From (et qui n'est pas montré dans mon exemple).

Les techniques d'authentification existantes avant DMARC, SPF (RFC 7208) et DKIM (RFC 6376), n'authentifient pas ce champ mais d'autres (le RFC5321-From pour SPF et le domaine indiqué dans la signature pour DKIM), qui ne sont pas en général affichés à l'utilisateurice final·e. DMARC va permettre d'utiliser ces deux techniques, SPF et DKIM, pour les appliquer à l'expéditeur (RFC5322-From). Un test DMARC réussi signifie que SPF ou DKIM a réussi mais aussi que le domaine authentifié par SPF ou DKIM est le même que celui présent dans le From: ; on parle d'alignement du nom de domaine. Cela ne va pas de soi car il y a de nombreux usages légitimes du courrier où ces domaines ne sont pas alignés, et DMARC casse donc ces usages.

Dans les exemples de messages reçus après traitement par DMARC, on va regarder les champs Authentication-Results. Normalisés dans le RFC 8601, ils sont ajoutés par le récepteur et indiquent le résultat d'une technique d'authentification. Ici, un exemple où SPF et DKIM ont marché (tous les exemples ici sont réels, issus de mes boites aux lettres):


Authentication-Results: mail.bortzmeyer.org; dmarc=pass (p=quarantine dis=none) header.from=afnic.fr
Authentication-Results: mail.bortzmeyer.org;
        dkim=pass (2048-bit key; secure) header.d=afnic.fr header.i=@afnic.fr header.a=rsa-sha256 header.s=afnic-20240601
        header.b=bdGM6W8o;
        dkim-atps=neutral
Authentication-Results: mail.bortzmeyer.org; spf=pass (sender SPF authorized) smtp.mailfrom=afnic.fr
        (client-ip=2001:67c:2218:10::51:1; helo=mx1.nic.fr; envelope-from=quelqu.un@afnic.fr; receiver=bortzmeyer.org)

Le domaine afnic.fr a bien été authentifié, à la fois par SPF et par DKIM, et DMARC passe donc (le champ From: n'est pas montré ici mais il indiquait bien une adresse @afnic.fr).

Il est également important de se souvenir que DMARC ne fait qu'authentifier le domaine, il ne garantit pas que le message soit sincère, sûr, utile ou quoi que ce soit d'autre. Si on reçoit un message de Trump, on peut prouver qu'il vient bien de whitehouse.gov mais il sera quand même certainement mensonger. C'est pour cela qu'il est absurde, comme on le lit dans certains forums, de dire « je ne comprends pas, j'ai bien mis un enregistrement DMARC et mes messages finissent quand même dans la boite Spam » : les spammeurs font du DMARC, eux-aussi.

L'inverse est vrai aussi, un message légitime et désiré peut parfaitement échouer au test DMARC, d'autant plus, que, comme indiqué plus haut, DMARC casse plusieurs usages légitimes du courrier. Il vaut donc mieux ne pas refuser un message uniquement sur la base d'un échec DMARC mais traiter cet échec comme une indication parmi d'autres. Ce RFC 9989 insiste sur ce point (notamment sa section 7), en mentionnant également le RFC 7960, qui détaille les problèmes venant de l'utilisation de DMARC.

La section 2 du RFC détaille le cahier des charges de DMARC. Comme avec toutes les solutions de sécurité, il faut garder en tête ce cahier des charges lorsqu'on évalue DMARC. Aucune solution de sécurité n'est parfaite : elles collent simplement plus ou moins bien à leur cahier des charges. Celui-ci, en résumé, est :

  • Permettre aux gérants de noms de domaine d'annoncer leur politique d'authentification du courrier et leurs souhaits quant au traitement du courrier qui ne passerait pas cette authentification.
  • Fonctionner dans le contexte de l'Internet (donc, sans autorité centrale).
  • Traiter uniquement les cas où le message malveillant copie exactement un nom de domaine qu'on gère. En d'autres termes, les usurpations utilisant des noms qui ressemblent (goog1e.com au lieu de google.com) sont hors-sujet.
  • Authentifier uniquement le nom de domaine qui est dans l'adresse (RFC 5322, section 3.4). En d'autres termes, dans un From: « Emmanuel Macron <emmanuel5561@gmail.com>, DMARC ne se préoccupe que du gmail.com, pas du emmanuel5561.
  • Authentifier uniquement l'adresse, pas le nom affiché (« Emmanuel Macron » dans l'exemple ci-dessus). La section 11.4 rappelle ce point très important.

Un bon cahier des charges a une autre section très importante : celle des non-objectifs, des choses qu'on n'essaie pas de faire. (Regardez les documents commerciaux : ils n'ont jamais l'honnêteté de lister ce qu'ils ne font pas.) Pour DMARC :

  • Il ne dit évidemment rien sur les domaines qui ont choisi de ne pas avoir d'enregistrement DMARC dans le DNS. Dit autrement, DMARC est opt-in.
  • Il n'essaie pas de s'occuper des autres informations présentes dans l'en-tête (comme Reply-To: ou Date:).
  • Il ne s'occupe pas des tricheries sur le nom affiché, comme dans l'exemple « Emmanuel Macron » plus haut (ou bien, tiré de ma boite Spam From: "amendes.gouv.fr" <amendes-gouv-nepasrepondre.C9717A5D-EA39-D865-765A6C98B4A0BB03@therugest.com>). Tant pis pour ceux et celles qui s'obstinent à utiliser un logiciel qui, par défaut, n'affiche que ce nom (Outlook fait encore ça). Relisez la section 11.4 du RFC.
  • Et naturellement, DMARC ne s'occupe pas du contenu du message, qu'il soit mensonger (« je suis l'ex-ministre des finances du Nigéria ») ou malveillant (logiciel qui va tenter d'exploiter une faille de sécurité pour prendre le contrôle de votre ordinateur).

Par exemple, voici un spam, prétendant venir de l'ANTAI mais qui passe tous les tests (le nom de domaine dans l'adresse n'a rien à voir avec l'ANTAI mais beaucoup d'utilisateurs n'y feront pas attention, et ce nom avait bien un enregistrement DMARC) :


Authentication-Results: mail.bortzmeyer.org; dmarc=pass (p=quarantine dis=none) header.from=rtm.gov.my
Authentication-Results: mail.bortzmeyer.org;
        dkim=pass (2048-bit key; secure) header.d=rtm.gov.my header.i=@rtm.gov.my header.a=rsa-sha256 header.s=rtm
        header.b=MaKApt+s;
        dkim-atps=neutral
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=rtm.gov.my; s=rtm; t=1775231898; x=1775836698; darn=bortzmeyer.org;
        h=content-transfer-encoding:mime-version:subject:message-id:to:from
        :date:from:to:cc:subject:date:message-id:reply-to;
        bh=L6c3f6fDBrQyBjkO1RiiF3vHHNmYjLDd4A1urn+cNJg=;
        b=MaKApt+s0vgkVsgh3VoFE0/MgCt8ilWkghyQKUbj2NnhgInADkR8G3aW0UbklkuDDV
	…
Authentication-Results: mail.bortzmeyer.org; spf=pass (sender SPF authorized) smtp.mailfrom=rtm.gov.my
        (client-ip=2607:f8b0:4864:20::f64; helo=mail-qv1-xf64.google.com; envelope-from=antai.gouv.fr@rtm.gov.my;
        receiver=bortzmeyer.org)
Subject: ACTION REQUISE SOUS 24H
From: "Antai.gouv.fr" <Antai.gouv.fr@rtm.gov.my>

La section 3 du RFC décrit les termes utilisés par DMARC, entre autres :

  • Domaine de l'auteur : ce qui est après l'arobase dans l'adresse indiquée par le champ From: de l'en-tête (rappel : pas celui de l'enveloppe).
  • Domaine DKIM : celui indiqué par le paramètre d= dans la signature DKIM (rappel : le domaine DKIM peut n'avoir aucun rapport avec l'adresse de l'en-tête ou avec celle de l'enveloppe).
  • Domaine SPF : ce qui est après l'arobase dans l'adresse indiquée par le champ From de l'enveloppe (rappel : pas celui de l'en-tête). Dans le contexte de DMARC, ce terme ne s'applique pas au domaine indiqué dans la commande EHLO (ou HELO) de SMTP.
  • Titulaire du domaine : la personne physique ou morale qui décidé d'enregistrer un nom de domaine et qui le gère ensuite.
  • Domaine organisationnel : le domaine au sommet du sous-arbre qui a la même administration (le RFC 5598 est une bonne lecture ici). Ainsi, bortzmeyer.org est le domaine organisationnel de mail.bortzmeyer.org. En pratique, c'est souvent le domaine enregistré du RFC 9499, domaine qui a été enregistré auprès d'un registre.
  • Suffixe public : domaine où le public peut enregistrer un sous-domaine, par exemple .fr ou eu.org. Ainsi, dans mail.foobar.eu.org, foobar.eu.org est le domaine organisationnel et eu.org le suffixe public, ou domaine d'enregistrement.

Armé de cela (mais il y a d'autres termes, que je présenterai au fur et à mesure), on peut passer à la section 4, qui explique les concepts importants.

DMARC permet à un titulaire de domaine d'annoncer sa politique d'authentification d'un domaine de l'auteur d'un courrier. On n'authentifie donc que le domaine, pas toute l'adresse (je l'ai déjà dit mais c'est important). Et DMARC ne s'intéresse qu'à ce qu'il appelle le domaine de l'auteur, donc le From: dans l'en-tête (également appelé « RFC5322.From »). DMARC annonce juste une politique, l'authentification est faite avec SPF (RFC 7208) ou DKIM (RFC 6376).

Un concept essentiel dans DMARC est celui d'alignement. Il y a alignement quand le domaine authentifié par SPF (celui de l'enveloppe, le « RFC5321.From ») ou par DKIM (celui indiqué dans le d= de la signature) coïncide avec le domaine de l'auteur (celui du From: de l'en-tête). Plus précisément, il peut y avoir un alignement strict (les deux noms de domaine sont identiques) ou relâché (les deux noms sont dans le même domaine organisationnel). Le choix se fait dans l'enregistrement DMARC publié.

Justement, on le publie où ? Via le DNS, dans un enregistrement de type TXT, publié dans le sous-domaine _dmarc, par exemple :

% dig +short _dmarc.proton.me TXT
"v=DMARC1; p=quarantine; fo=1; aspf=s; adkim=s;"
  

On bénéficie ainsi de toute l'infrastructure, très fiable et éprouvée, du DNS. Ce sous-domaine _dmarc figure dans le registre IANA des noms commençant par un trait bas, créé par le RFC 8552.

Au passage, si vous voulez voir (ou enregistrer), sur un serveur DNS faisant autorité, uniquement les requêtes DNS pour le sous-domaine _dmarc, dnscap permet de le faire facilement :

% dnscap -g -x _dmarc   
  

(Je triche un peu, le -x attrape en effet davantage que cela mais ça suffit en première approximation.)

Le format exact de l'enregistrement DMARC utilise des doublets clé=valeur, comme celui de DKIM. (Sa description formelle, en ABNFRFC 5234 - est dans la section 4.8.) Les clés possibles figurent dans un registre IANA. Les plus courantes sont :

  • v : c'est obligatoirement le premier doublet clé=valeur et il indique la version de DMARC, actuellement DMARC1.
  • p : c'est la clé la plus importante, celle qui indique la politique à appliquer aux messages qui ne passent pas la validation DMARC. Une valeur reject indique que le titulaire du domaine recommande le rejet des messages invalides (cela ne peut être qu'une recommandation, car le récepteur du courrier reste évidemment libre de sa politique). quarantine recommande une mise en attente quelque part (un dossier « peut-etre-spam » par exemple). Enfin, none indique qu'on recommande de ne rien faire. Cela peut être utilisé quand on craint les conséquences de DMARC sur certains usages (cf. RFC 7960) mais qu'on pense que certains récepteurs vont mal traiter les messages des domaines sans DMARC. Ou bien cela peut être utile dans certains audits « de sécurité » qui demandent un enregistrement DMARC, n'importe lequel. Enfin, un p=none peut être utilisé lors d'un déploiement progressif de DMARC, quand on veut juste tester, avant de publier une politique plus fasciste. Comme DMARC permet de solliciter l'envoi de rapports d'erreur, un p=none peut être accompagné d'une telle sollicitation.
  • sp : comme p mais pour les sous-domaines du domaine qui a l'enregistrement DMARC. Les valeurs possibles sont les mêmes que pour p.
  • np : nouveauté, initialement décrite dans le RFC 9091. C'est le traitement à appliquer aux sous-domaines non-existants du domaine pour lequel une politique DMARC est publiée. Les valeurs possibles sont les mêmes que pour p.
  • ruf : c'est ainsi qu'on sollicite l'envoi de rapports d'erreur. On indique les URI où envoyer ces rapports (souvent des URI de plan mailto:, pour demander des rapports par courrier). Le format des rapports est spécifié dans les RFC 9991, RFC 6651 et RFC 6552. ruf demande un rapport par message invalide, rua permet de demander des rapports agrégés. Leur format figure dans le RFC 9990.
  • psd : nouveauté de notre RFC, s'il a la valeur y, il indique que le domaine est un suffixe public (PSD : Public Suffix Domain), c'est-à-dire un domaine dont les sous-domaines peuvent être délégués à d'autres entités (comme c'est le cas de .re ou eu.org).
  • fo : diverses options pour la génération de rapports d'erreur.
  • adkim et adpf : tous les deux peuvent prendre la valeur s (strict) ou r (relâché, ou laxiste). Ils indiquent si l'alignement avec l'identificateur authentifié par DKIM ou SPF doit être strict (les deux identificateurs sont rigoureusement identiques) ou relâché (l'identificateur authentifié peut se contenter d'être dans le même domaine enregistré que celui qui a un enregistrement DMARC). Par défaut, DMARC est laxiste. Notez que cela permet à quelqu'un qui peut utiliser un sous-domaine de se faire authentifier comme étant dans l'apex (section 11.8 du RFC). Demander un alignement strict résout ce problème (mais impose que vous controliez bien les sous-domaines).

Les clés inconnues doivent être ignorées, ce qui permet d'en ajouter de nouvelles sans tout casser. La politique pour un éventuel ajout est « Spécification nécessaire » (RFC 8126).

On a parlé du domaine organisationnel, l'apex du domaine testé par DMARC. C'est en fait une notion administrative, pas technique, ce qui fait que ce domaine organisationnel n'est pas évident à identifier dans le DNS. Pour le trouver, l'ancien RFC, le RFC 7489, suggérait de faire appel à une liste de suffixes publics, comme la PSL (rappel : il n'existe pas de liste officielle). Notre nouveau RFC suggère une autre méthode, en remontant l'arbre des noms de domaine. On commence par le domaine qu'on veut authentifier, et, si on n'y trouve pas de politique DMARC, on essaie son domaine parent et ainsi de suite, jusqu'à ce qu'on trouve un enregistrement DMARC. Ainsi, pour truc.machin.example.com, on essaiera successivement _dmarc.truc.machin.example.com, _dmarc.machin.example.com, _dmarc.example.com et enfin _dmarc.com. La dernière requête permet donc au registre de .com de définir une politique DMARC qui s'appliquera à tous les domaines sans politique DMARC. C'est très dangereux, pour les raisons expliquées dans le RFC 1535 mais cela permet de se passer de liste de suffixes publics, et c'est plus souple pour le cas des grosses organisations, qui peuvent avoir des politiques DMARC dans des sous-domaines qui ne sont pas délégués.

Notez que l'éventuelle présence de la clé psd va compliquer les choses mais je n'ai pas vraiment le courage de détailler ici l'algorithme complet.

Maintenant, voyons quels sont les acteurs d'un déploiement de DMARC. D'abord, le titulaire du domaine qui envoie des messages. Il doit publier un enregistrement SPF à l'apex du domaine. Il doit signer les courriers sortants avec DKIM (ce qui implique de publier les clés publiques DKIM dans le DNS). Notez que DMARC n'a pas besoin de SPF et de DKIM, un seul des deux suffit mais, bon, autant tout faire. Il a intérêt à créer une boite dédiée pour recevoir les rapports sur les messages invalides. Le titulaire doit enfin publier dans le DNS l'enregistrement DMARC (celui qui commence par _dmarc). Au début, on utilise typiquement une politique indulgente (p=none). Puis on teste.

Comment teste t-on ? En lisant les rapports indiquant des messages invalides (RFC 9990 et RFC 9991). Les rapports agrégés sont du XML, assez lisibles par un humain mais, en pratique, on préférera typiquement utiliser un programme qui les synthétisera dans une forme plus lisible. (Je n'utilise pas actuellement un tel programme, car je n'en ai pas trouvé. Il faut qu'il tourne en local - pas question de confier les rapports à un tiers - et ne nécessite pas d'installer toute une batterie de cuisine PHP et MariaDB.) Une fois qu'on a trouvé les problèmes (une application oubliée dans un coin qui envoie des courriers sans passer par les serveurs centraux…) et qu'on les a corrigés, on peut durcir la politique (p=quarantine, par exemple). Il est raisonnable d'attendre plusieurs semaines, voire mois, pour être sûr d'avoir vu tous les problèmes.

(Et si vous êtes gérant d'un suffixe public - - un domaine sous lequel d'autres entités peuvent enregistrer des noms, demandez-vous si vous devez publier du DMARC avec psd=y. Ce n'est pas obligatoire, cf. section 5.2.)

Et le récepteur du courrier, que doit-il faire ? Il extrait du message le domaine de l'auteur. Il cherche s'il y a un enregistrement DMARC. Il exécute les tests SPF et DKIM. S'il récupère un ou plusieurs domaines authentifiés, il vérifie l'alignement (strict ou relâché). Si au moins un domaine authentifié est aligné avec le domaine de l'auteur, le test DMARC est un succès. Sinon, c'est un échec. Notez bien qu'il n'est pas nécessaire que SPF et DKIM réussissent tous les deux. Si le test DMARC se termine en échec, on applique un traitement, qui dépend de la politique suggérée dans l'enregistrement DMARC, et de la politique propre du receveur. Voici un exemple où DMARC dit que tout s'est bien passé :


From: "Projet Arcadie" <admin@projetarcadie.com>
Authentication-Results: mail.bortzmeyer.org; dmarc=pass (p=none dis=none) header.from=projetarcadie.com
Authentication-Results: mail.bortzmeyer.org;
        dkim=pass (2048-bit key; unprotected) header.d=projetarcadie.com header.i=@projetarcadie.com header.a=rsa-sha256 header.s=alternc
        header.b=plrnZlsJ;
        dkim=pass (2048-bit key) header.d=projetarcadie.com header.i=@projetarcadie.com header.a=rsa-sha256 header.s=alternc
        header.b=m84VgM5U;
        dkim-atps=neutral
Authentication-Results: mail.bortzmeyer.org; spf=pass (sender SPF authorized) smtp.mailfrom=projetarcadie.com (client-ip=91.194.60.11;
        helo=arcadieweb01.octopuce.fr; envelope-from=admin@projetarcadie.com; receiver=bortzmeyer.org)

  

Ici, il y avait un enregistrement SPF (qui autorise l'émetteur SMTP donc cela suffit), deux signatures DKIM, toutes les deux corrects, il y a alignement strict, et donc DMARC passe, il n'y a aucun doute que le domaine émetteur était bien projetarcadie.com. (La politique DMARC était p=none donc un éventuel échec n'aurait sans doute pas eu beaucoup de conséquences.)

Ici, DKIM a échoué (pourquoi ? mystère mais c'est peut-être la faute de SpamAssassin qui a modifié le sujet, il faudrait que je vérifie ma configuration) mais SPF réussit (le message vient bien de Gmail) donc DMARC est content (il s'agissait bien d'un spam, tentative d'escroquerie financière) :


Authentication-Results: mail.bortzmeyer.org;
        dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com
        header.a=rsa-sha256 header.s=20230601 header.b=K6F+sj7y;
        dkim-atps=neutral
Authentication-Results: mail.bortzmeyer.org; dmarc=pass (p=none dis=none) header.from=gmail.com
Authentication-Results: mail.bortzmeyer.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com
        (client-ip=2a00:1450:4864:20::133; helo=mail-lf1-x133.google.com; envelope-from=mrsbalex@gmail.com;
        receiver=sources.org)
From: "Mr. Mike Christopher" <mrsbalex@gmail.com>

Et ici, un échec, SPF est correct, il n'y a pas de signature DKIM et il n'y a pas d'alignement des domaines, la tentative du spammeur pour se faire passer pour saison.co.jp échoue :


From: 株式会社クレディセゾン <admin@saison.co.jp>
Authentication-Results: mail.bortzmeyer.org; dmarc=fail (p=none dis=none) header.from=saison.co.jp
Authentication-Results: mail.bortzmeyer.org; spf=pass (sender SPF authorized) smtp.mailfrom=zh-cht-jjb.com (client-ip=34.130.185.194;
        helo=zh-cht-jjb.com; envelope-from=admin@zh-cht-jjb.com; receiver=bortzmeyer.org)

  

Et ici, l'émetteur tente de faire croire qu'il vient de Gmail mais l'enregistrement SPF de Gmail se termine par un ~all, son adresse IP n'y est pas listée et il n'y a pas de signature DKIM dans le message. Même pas besoin de tester l'alignement puisqu'il n'y a pas de domaine authentifié du tout :


From: Axel.Bouvier <mailrmicro+Axel.Bouvier@gmail.com>
Authentication-Results: mail.internatif.org; dmarc=fail (p=none dis=none) header.from=gmail.com
Authentication-Results: mail.internatif.org; spf=softfail (domain owner discourages use of this host)
        smtp.mailfrom=gmail.com (client-ip=78.246.109.210; helo=gmail225.com;
        envelope-from=mailrmicro+axel.bouvier@gmail.com; receiver=internatif.org)

  

De nombreux autres exemples, avec succès ou échec, figurent dans l'annexe B du RFC.

C'est pas mal si le récepteur de courrier qui fait tourner DMARC en profite pour générer les rapports (RFC 9991), s'ils sont demandés (par un ruf ou un rua dans l'enregistrement DMARC de l'envoyeur). Néanmoins, le RFC note qu'il peut ne pas le faire, s'il craint pour la vie privée (cf. section 10) ou tout simplement si ça lui consomme trop de ressources.

D'ailleurs, le RFC insiste bien sur un point que j'avais déjà mentionné : la décision finale (de livrer le message, ou de le mettre dans le dossier Spam ou de le jeter) revient toujours au destinataire (section 5.4). Celui-ci applique la politique qu'il veut. Il serait ridicule de croire que, parce qu'on a SPF, DKIM et DMARC bien configurés, nos messages seraient systématiquement livrés. Après tout, un spammeur peut en faire autant.

À l'inverse, un récepteur peut parfaitement décider d'acheminer jusqu'à ses utilisateurices un message qui échoue aux testes DMARC, par exemple parce qu'il a lu le RFC 7960 (et la section 7.4 de notre RFC) et qu'il sait que DMARC échoue dans des cas d'usage pourtant légitimes, notamment les listes de diffusion. DMARC fournit de la traçabilité et de la responsabilité, il n'est pas un oracle tout-puissant sur l'authenticité du message.

La section 7 du RFC est surtout intéressante pour les historien·nes et pour les technicien·nes qui veulent comprendre les choix faits par DMARC. C'est un pot-pourri de diverses discussions.

D'abord, SPF. SPF a été conçu pour être utilisable pendant la session SMTP, parfois avant même que l'en-tête du message ait été transmis. Une politique SPF « dure » (se terminant en -all) peut amener au rejet du message avant que DMARC n'ait été évalué. Ainsi, si un message échoue en SPF mais réussit en DKIM, normalement, DMARC réussirait. Mais, si le test SPF mène à un rejet dès la session SMTP, le message n'arrivera pas. Attention donc en configurant vos enregistrements SPF. (Relisez les « M3AAWG Best Practices for Managing SPF Records » et « M3AAWG Email Authentication Recommended Best Practices ».)

Et à propos de rejet précoce (dans le cours de la session SMTP, avant d'avoir accepté le message) : le RFC recommande cette méthode car elle évite la génération d'un avis de non-remise (RFC 3464), avis qui irait sans doute à un innocent si l'adresse était usurpée. Deux façons de mettre en œuvre ce rejet précoce, en renvoyant un code d'erreur (commençant par 5 RFC 5321, section 4.2.5) au client SMTP, qui saura ainsi que son message a été refusé, ou, plus méchamment, en prétendant que le message a bien été reçu (code commençant par 2) mais en le jetant silencieusement. La deuxième solution est évidemment horrible (le serveur SMTP ment, l'émetteur ne sait pas ce qui s'est passé, le déboguage devient très difficile) mais elle est parfois nécessaire pour éviter le backscatter, l'envoi de messages d'erreur à un innocent, une des plaies du spam qui usurpe votre adresse. Et elle évite de donner des informations à quelqu'un qu'on estime être un usurpateur.

Contrairement à ce qu'on voit dans certains articles pro-DMARC imprudents qui promeuvent DMARC sans insister sur ses limites et ses faiblesses, notre RFC précise bien qu'il y a des cas où DMARC pose problème (sections 7.3 et 7.4). Par exemple, citant le RFC 7960, il rappelle que DMARC peut casser des cas d'usage légitimes comme les adresses d'anciens élèves que certaines universités fournissent (en faisant suivre automatiquement le courrier à l'adresse actuelle), comme des alias où le courrier vers une même adresse est distribuée à plusieurs personnes, qui ne sont pas forcément dans le même domaine, ou comme les listes de diffusion. Pour les deux premiers cas, des solutions relativement simples existent (réécrire l'enveloppe pour ne pas casser SPF, ce qui est de toute façon une bonne pratique car l'envoyeur du message ne saurait pas quoi faire si la vraie adresse finale ne marcherait pas) et ne pas du tout toucher au message, pour éviter de casser DKIM), pour les listes de diffusion, c'est plus délicat. En pratique, plusieurs gestionnaires de liste adoptent la solution très intrusive de réécrire le champ From: comme ici dans ce message envoyé à une liste de l'OARC (le vrai From: a été reporté en Reply-To:) :


Authentication-Results: nic.fr;
        spf=pass smtp.mailfrom=dns-operations-bounces@dns-oarc.net;
        dmarc=pass header.from=dns-oarc.net
Reply-To: Walter Russo <walter@secureme.it>
From: Walter Russo via dns-operations <dns-operations@dns-oarc.net>

Le problème est évidemment particulièrement sérieux si on a une politique DMARC restrictive (p=reject) et le RFC conseille fortement dans ce cas de systématiquement signer avec DKIM, pour éviter de compter sur le seul SPF (qui sera cassé par les serveurs qui font suivre un message sans réécrire l'enveloppe). Et il rappelle aux récepteurs de courrier qu'il est très imprudent de rejeter un message sur la seule base de DMARC. Ces consignes, qui ne sont pas toujours respectées par les serveurs actuels, sont cruciales pour le bon fonctionnement du courrier. Le RFC note bien ce problème de filtrage excessif et explique que c'est ce qui a mené plusieurs gestionnaires de liste à tripoter le champ From:, par exemple en changeant le vrai champ bob@example.com en un bob=example.com@user.somelist.example, où on peut toujours retrouver la vraie adresse. (On ajoute également parfois un Reply-To: indiquant la vraie adresse de l'expéditeur, comme dans l'exemple ci-dessus.) Le RFC n'approuve pas cette modification mais note qu'elle est répandue et qu'il faut faire avec. Il existe des solutions techniquement plus propres comme le ARC du RFC 8617 mais que presque personne n'utilise.

En résumé, pour faire du DMARC complet, l'émetteur du courrier devrait idéalement :

  • Produire des messages qui auront un identificateur SPF aligné avec le domaine de l'auteur (une exigence qui me parait très excessive),
  • produire des messages avec une signature DKIM valide et alignée,
  • configurer une boite aux lettres qui recevra les rapports,
  • publier l'enregistrement DMARC (je rajoute : après avoir soigneusement testé les trois points précédents),
  • ne pas compter sur le seul SPF.

Et le receveur devrait idéalement :

  • Tester s'il y a un enregistrement DMARC pour le domaine de l'auteur,
  • tester s'il y a des identificateurs authentifiés par SPF ou DKIM,
  • tester si au moins l'un d'entre eux est aligné avec le domaine de l'auteur,
  • déterminer ainsi si le résultat final est pass ou fail,
  • envoyer des rapports, si demandé,
  • ne pas rejeter des messages juste parce qu'il y a eu un échec DMARC, même si la politique de l'émetteur est p=reject.

La section 11 du RFC creuse les questions de sécurité. Que faut-il savoir pour utiliser DMARC de manière sûre ? D'abord, DMARC est évidemment dépendant des mécanismes d'authentification utilisés, SPF et DKIM (le groupe de travail IETF avait même envisagé de supprimer SPF, considéré comme trop permissif). Si vous publiez votre clé privée DKIM, DMARC ne pourra rien pour vous. Et SPF, DKIM et DMARC dépendent tous les trois du DNS donc il est crucial de gérer ses serveurs DNS sérieusement. Malheureusement, les RFC sur ces trois techniques n'imposent pas DNSSEC (RFC 9364) mais ils devraient : sans DNSSEC, l'envoi de fausses informations dans le DNS est plus facile. Compter sur SPF, DKIM et DMARC sans avoir DNSSEC me semble peu sérieux mais, bon, le vrai but de la cybersécurité est de réussir l'audit de conformité, pas d'améliorer la sécurité concrète. D'autre part, l'examen du trafic DNS (qui n'est pas limité aux deux parties qui s'envoient du courrier) donne des informations sur le trafic. Utiliser DoT (RFC 7858) ou DoH (RFC 8484) peut donc être une bonne idée.

Comme toujours en ingéniérie, d'autres solutions techniques auraient été possibles. L'annexe A de notre RFC examine certaines de ces alternatives et explique pourquoi elles n'ont pas été retenues. Ainsi, on aurait pu utiliser S/MIME (RFC 8551) pour signer le message, ajoutant cette technique à SPF et DKIM. Mais S/MIME a un cahier des charges différent de celui de DMARC, il vise plutôt à une authentification de bout en bout du message entier. Et puis il faut bien constater qu'en dehors de quelques environnements bureaucratiques fermés, personne n'utilise S/MIME. C'est en partie dû à la nécessité d'une PKI, dont le RFC note qu'elle a été souvent promise mais ne s'est jamais matérialisée. (Curieusement, le RFC ne cite pas OpenPGPRFC 9580 - qui est pourtant nettement plus utilisé que S/MIME.)

Une autre décision de conception cruciale de DMARC est le fait d'accepter n'importe quelle technique d'authentification ; SPF ou DKIM, c'est pareil pour lui. Il a pourtant été souvent proposé de permettre au titulaire du domaine de spécifier, dans l'enregistrement DMARC, de préciser qu'on ne veut que SPF, ou que DKIM. Mais DMARC est assez compliqué comme cela et la décision a finalement été de permettre l'une ou l'autre des méthodes d'authentification. Débrouillez-vous pour qu'au moins une (et de préférence les deux) fonctionne.

Un point essentiel de DMARC est qu'il authentifie l'expéditeur (plus exactement son alignement) en considérant que l'expéditeur est indiqué par le champ From: de l'en-tête. Cela casse bien des usages légitimes (comme les listes de diffusion). Ne serait-il pas préférable d'authentifier un champ plus technique comme Sender: (RFC 5322, section 3.6.2) ? Cela avait même été spécifié dans le RFC 4870, puis retiré. Finalement, le choix a été de se concentrer sur From: puisqu'il est le seul à être toujours montré à l'utilisateur. (SPF, comme DKIM, peuvent authentifier un identificateur que l'utilisateur ordinaire ne voit pas.)

Notre RFC 9989 introduit une nouvelle clé, np, qui spécifie la politique à appliquer aux sous-domaines non-existants du domaine authentifié. Cela soulève le problème de la définition de non-existant. Le RFC dit que cela inclut les réponses NXDOMAIN (No Such Domain), évidemment, mais pas forcément les réponses NOERROR où la section Réponses est vide, car le nom existe mais ne contient ni enregistrement MX, ni enregistrement d'adresse (A ou AAAA). Ce test de la présence de certains types d'enrgeistrement est déjà couramment utilisé en pratique (il n'y a aucune raison d'accepter du courrier d'un domaine qui ne permettrait pas les réponses) mais le RFC ne l'impose pas. Et, sinon, le RFC rappelle que, si une requête pour un domaine renvoie NXDOMAIN, tous ses sous-domaines n'existent pas non plus (RFC 8020).

Évidemment, un débat ancien et récurrent pour DMARC est celui des frontières organisationnelles. Comment sait-on si cis.cnrs.fr dépend de la même autorité que cnrs.fr (ou bien pick.eu.org et eu.org). Il n'y a pas de réel moyen de trouver cette information dans le DNS. (On peut trouver les frontières techniques en demandant l'enregistrement de type SOA. Mais cela ne donne pas les frontières administratives. gouv.fr n'est pas géré par la même organisation que fr, même s'ils sont dans la même zone.) Des efforts ont été faits à l'IETF pour résoudre ce problème mais sans résultat. L'ancien RFC DMARC, le RFC 7489 suggérait d'utiliser une liste de suffixes d'enregistrement mais notre RFC 9989 a finalement préféré une autre méthode, la « montée à l'arbre » (on grimpe l'arbre des noms de domaine, cherchant des enregistrements DMARC).

Passons à la pratique, maintenant. OpenDMARC est aujourd'hui très répandu, aussi bien côté envoyeur que côté récepteur, et apparait souvent dans les articles de marketing « comment s'assurer que votre spam pardon votre newsletter sera bien livrée partout ». Sur mon serveur de messagerie personnel, j'annonce une politique DMARC et, pour valider les messages entrants, j'utilise OpenDMARC (notez que son développement semble bien avoir stoppé et qu'il y a donc peu de chances qu'il prenne en compte les nouveautés de ce RFC). Ma configuration est très proche de celle par défaut :


Socket inet:54321
# Les autres ont leur valeur par défaut	 

  

Et Postfix le lance ainsi, juste après DKIM :

smtpd_milters = unix:run/opendkim.sock, inet:localhost:54321
  

Et c'est ainsi que sont produits les champs Authenticated-Results: que vous avez vus.

Pour apprendre DMARC, je recommande l'excellent et interactif https://www.learndmarc.com/. Pour tester votre configuration, comme d'habitude, il existe de nombreux services.

Le chemin vers ce RFC a été très long (plusieurs années). L'annexe C du RFC résume les changements depuis le précédent RFC, le RFC 7489. Les principaux sont :

  • Nouvel algorithme (« montée dans l'arbre » pour trouver le domaine organisationnel, au lieu de l'utilisation d'une liste de suffixes publics). C'est la suite du RFC 9091.
  • Introduction de nouveaux concepts comme le PSD (Public Suffix Domain) et le PSO (Public Suffix Operator).
  • Le RFC n'est plus seulement « Pour information », il passe sur le chemin des normes.
  • Plusieurs nouvelles clés sont possibles dans l'enregistrement DMARC : np, psd et t.
  • Mise à l'écart de certaines clés comme pct (partiellement remplacé par t).
  • Résolution des erreurs du précédent RFC.

Les articles suivants sont de bonnes lectures pour les nouveautés de DMARC :


Téléchargez le RFC 9989


L'article seul

RFC 9969: IAB AI-CONTROL Workshop Report

Date de publication du RFC : Mai 2026
Auteur(s) du RFC : M. Nottingham, S. Krishnan
Pour information
Première rédaction de cet article le 20 mai 2026


Ah, l'IA… Vaste sujet, et d'actualité. Une des questions qui reviennent souvent est celle de l'utilisation du contenu qu'on trouve sur le Web pour entrainer les grands modèles, sa légitimité, la charge qu'elle induit pour les serveurs, les moyens de la contrôler, etc. Un colloque avait été organisé par l'IAB en septembre 2024 sur ces questions et ce RFC en est le compte-rendu. Ce colloque avait lancé le projet IETF aipref.

Une petite précision politique d'abord : le RFC précise bien qu'il s'agit d'un compte-rendu et que l'IAB n'approuve pas forcément tout ce qui a été dit à ce colloque (section 1.2 du RFC). Je rajoute que j'ai aussi des opinions sur le sujet, donc je mettrais [entre crochets] ce qui est mon opinion, et ne vient pas du RFC. Le reste n'est donc pas de moi, j'en rends compte, c'est tout, ne me tapez pas.

Ce colloque fait partie de la série de colloques qu'organise régulièrement l'IAB pour explorer des tendances à plus ou moins long terme, sans les obligations de l'IETF de produire normes et documents.

Donc, les LLM (qui ne sont qu'une partie des techniques qu'on regroupe sous le terme marketing d'« IA ») fonctionnent en deux phases : on entraine le modèle en lui faisant ingérer une grande quantité de contenu (textes, images ou autres), puis il va pouvoir inférer du contenu à partir de ce qu'il a digéré pendant la phase d'entrainement, et d'une demande (dite prompt). Le contenu inféré n'est jamais tout à fait identique à celui utilisé pour l'entrainement (autrement, cela serait du plagiat, potentiellement illégal). Les LLM ne marchant bien, à l'heure actuelle, que si le corpus d'entrainement était énorme, ils sont très gourmands en données et une source évidente de contenu en grande quantité est le Web. Des bots ou crawlers parcourent donc le Web, ramassant du contenu. Voici par exemple un extrait du journal du serveur qui héberge ce blog, montrant le bot de Perplexity récoltant du contenu :

18.210.92.235:64884 - - [09/Jan/2026:07:26:15 +0000] "GET /images/TCP_state_diagram.jpg HTTP/1.1" 200 96551 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)" www.bortzmeyer.org TLS
18.97.9.103:64398 - - [09/Jan/2026:08:31:39 +0000] "GET /bitcoin-metamorphoses.html HTTP/1.1" 200 8982 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)" www.bortzmeyer.org TLS
18.97.9.101:57493 - - [09/Jan/2026:08:31:39 +0000] "GET /robots.txt HTTP/1.1" 404 3250 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)" www.bortzmeyer.org TLS
18.97.9.103:48122 - - [09/Jan/2026:08:47:36 +0000] "GET /nist-pq.pdf HTTP/1.1" 200 84543 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)" www.bortzmeyer.org TLS
18.97.9.96:25157 - - [09/Jan/2026:08:51:37 +0000] "GET /files/capitole-libre-2019-quic-pour-impression.pdf HTTP/1.1" 200 212507 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)" www.bortzmeyer.org TLS

Une des questions soulevées par cette récolte de données est qu'elle n'était pas prévue à l'origine. Certains webmestres qui mettent du contenu en ligne estiment donc qu'un nouvel usage (l'entrainement des LLM) justifie de nouvelles règles et de nouvelles possibilités de contrôle par le serveur Web. C'est par exemple ce que prévoit l'AI Act européen.

Le colloque (ou atelier) de l'IAB s'est tenu les 19 et 20 septembre 2024 (oui, le RFC met trop longtemps à sortir) et prévoyait de travailler sur tous les aspects liés à cette récolte de données (cf. l'appel à participation). Le colloque regroupait des personnes de divers horizons, experts techniques, entreprises d'IA, fournisseurs de contenu, décideurs politiques, etc. La liste figure dans l'annexe A.2. La règle suivie était celle de Chatham House (tout ce qui se dit est public mais sans le lier à un·e participant·e particulier·ère). D'ailleurs, le RFC note qu'au moins un participant n'a pas voulu que son identité soit dévoilée, juste qu'il était un représentant officiel d'un gouvernement. Et, comme déjà dit, le RFC rend compte des discussions, cela ne signifie pas que l'IAB approuve tout ce qui a été dit.

La section 2 du RFC résume les discussions (la totalité des soumissions sont en ligne). Aujourd'hui, les fournisseurs de contenu, les webmestres, peuvent exprimer leurs choix quant à la récolte de données par divers moyens. Il y a par exemple une solution technique existante, c'est le robots.txt, qui est décrit dans le RFC 9309. Notez que, en l'absence du fichier robots.txt, les bots peuvent tout récolter. C'est donc une solution opt-out. Il y a aussi des solutions non-techniques par exemple les conditions d'utilisation (ainsi, ce blog est sous licence GFDL et les contenus peuvent donc être réutilisés, à la condition que les destinataires jouissent des mêmes droits de réutilisation). Tiens, par contre, il n'y a pas de licence CC-BY-NoAI ? Pour revenir à la technique, le webmestres peuvent aussi bloquer les crawlers par leur adresse IP, ou leur User-Agent (RFC 9110, section 10.1.5), ou carrément tout mettre derrière un paywall.

Comme indiqué plus haut, ces solutions sont en général opt-out, donc par défaut, la récolte est autorisée. (Sur ce blog, et c'est apparemment le cas de la plupart des serveurs HTTP, plus de la moitié des requêtes sont faites par des bots, mais pas forcément liés à l'IA, c'était déjà le cas avant les LLM.) On constate (cf. l'exposé « Consent in Crisis: The Rapid Decline of the AI Data Commons ») une tendance à la fermeture : la récolte devient de plus en plus difficile car de nombreux serveurs bloquent les accès qu'ils pensent dûs à un bot. Le Web tend donc à se fermer.

[Le RFC n'est pas clair sur ce point mais, pour moi, il est important de faire la différence entre les problèmes techniques et opérationnels posés par certains bots qui, qu'ils travaillent pour l'IA ou pas, « matraquent » avec excès les serveurs, et les problèmes politiques et financiers liés à l'utilisation qui est faite des données récoltées. Les problèmes techniques et opérationnels causés par des « bots fous » existaient bien avant les LLM. Par contre, les problèmes politiques (légitimité à réutiliser le contenu) et financiers (perte de revenus pour les ayant-droits, comme mentionné dans le RFC) sont plus spécifiques de l'IA. Le RFC ne parle pas vraiment des problèmes opérationnels posés par l'agressivité de certains bots - pas forcément liés à l'IA, d'ailleurs - mais la réunion IETF 123 à Madrid avait vu de très intéressants exposés à ce sujet.]

À l'heure actuelle, il est difficile de savoir ce qui est permis, au delà des simples consignes du robots.txt. Les gérants des serveurs n'ont pas de moyen standard et automatiquement analysable de faire connaitre leurs conditions d'utilisation, et les bots n'ont donc pas non plus de moyen de savoir ce qui est permis. [Il va de soi qu'il y a des bots qui, de toute façon, s'en foutent. Le travail de normalisation à l'IETF ne pourra concerner que les bots honnêtes et ne dispensera pas de mesurs de sécurité contre les malhonnêtes.]

Le RFC creuse certain aspects de la question. Par exemple, en section 2.1, le problème de la différence entre le moment du ramassage des données et celui de leur utilisation. Les consignes du serveur (comme le robots.txt) sont lues au moment du ramassage mais certains responsables de contenu voudraient exprimer des choix concernant l'utilisation, or celle-ci se fait à un autre moment, décorrélé du premier. Certaines récoltes, comme celle faite par Common Crawl, peuvent servir à de multiples usages et des consignes concernant le ramassage ne sont donc pas appropriées. Autre exemple que Common Crawl, on peut avoir une organisation qui gère un moteur de recherche du Web et développe un LLM, et qui utilise le même crawler pour les deux usages. Certains webmestres estiment que la première utilisation ne pose pas de problème (au bout du compte, cela ramènera du trafic sur leur site Web) mais s'opposent à la seconde car elle n'apportera pas de trafic, le LLM donnant des réponses qui suffiront à l'utilisateur.

Du point de vue technique, il faut aussi noter que le principe d'entrainement d'un LLM fait qu'on utilise toutes les données et, qu'une fois le modèle créé, il n'y a pas d'étiquetage spécifique de la source de telle ou telle réponse du LLM. (C'est pour cela que les LLM ont du mal à indiquer leurs sources.) Un webmestre qui souhaiterait dire « d'accord pour servir à l'entrainement des IA mais pas pour que ces IA aient un usage militaire, ou bien pas un usage commercial » ne le peut pas, en raison de cette limite technique. Et même si ce moyen existait, le gérant du LLM serat obligé de faire N modèles, pour toutes les permutations des différents critères (ou tout simplement d'exclure tous les contenus ayant une licence restrictive, ce qui limiterait la représentativité du corpus d'entrainement du modèle).

Enfin, les préférences changent dans le temps et celles exprimées au moment de la récolte des données peuvent ne pas être à jour lorsque les données seront utilisées pour l'entrainement d'un LLM.

Le problème est déjà compliqué si on suppose que tous les acteurs sont de bonne foi et respectent les règles. Mais, évidemment, la confiance ne règne pas, et pour de bonnes raisons. [Les entreprises capitalistes trichent, que ce soit celles qui entrainent les LLM ou bien celles des ayant-droits.] Il n'y a pas de moyen facile de vérifier le respect des préférences exprimées par les gérants du contenu. Et c'est d'autant plus inquiétant que les entreprises de l'IA n'ont pas vraiment de motivation pour respecter les règles : aucun risque de sanction [surtout compte-tenu des déclarations de Trump contre tout projet de régulation de l'IA]. Cette absence de confiance entraine l'utilisation importante de moyens techniques de blocage, comme de bloquer les adresses IP des bots connus. Il y a même un bot qui suggère cette solution :

119.28.89.249:58834 - - [21/Jan/2026:15:32:02 +0000] "GET /5153.xml HTTP/1.1" 200 6891 "-" "Mozilla/5.0 (compatible; Thinkbot/0.5.8; +In_the_test_phase,_if_the_Thinkbot_brings_you_trouble,_please_block_its_IP_address._Thank_you.)" www.bortzmeyer.org TLS
  

L'atelier de l'IAB a passé du temps sur la question de l'attachement des préférences au contenu (section 2.3). Le robots.txt (RFC 9309) est très bien, très déployé et largement reconnu. Mais il manque de souplesse pour les gros sites qui souhaitent un système plus granulaire. Par exemple, si un site de vidéos souhaitait restreindre l'accès à certaines vidéos, la seule solution est de les placer dans un espace particulier (par exemple un répertoire distinct), et donc de devoir changer l'URL si la classification change. Et, comme le robots.txt est à la racine du site Web, il n'est pas sous le contrôle des créateurs de contenu qui ont accès à un espace dédié mais pas à la totalité du site. Si le CMS que vous utilisez permet des créations de contenu et des mises à jour décentralisées, où certaines personnes peuvent modifier une partie du site, regardez s'il permet à ces personnes d'influencer le robots.txt. Je suis preneur d'exemples.

Une autre solution (qui ne serait pas forcément exclusive du robots.txt mais complémentaire) serait d'inclure les préférences d'utilisation dans le contenu lui-même. C'est ce que permet l'élément HTML <meta> ou le format XMP pour les images. Des formats comme XML ou JSON permettraient certainement d'ajouter ces préférences d'utilisation, qui ont l'avantage de forcément voyager avec le contenu, contrairement au robots.txt. Évidemment, cela ne marchera pas si ces méta-données sont retirées par le programme de collecte (pas forcément pour des raisons malveillantes, cela peut être pour diminuer la taille des données). Et certains formats ne se prêtent pas à cette inclusion des préférences d'utilisation, comme le texte brut, ou comme les contenus qui ont plusieurs auteurs (pensez à un fil de discussion sur les réseaux sociaux).

Une autre solution serait de placer les préférences d'utilisation dans un registre, extérieur aux œuvres, comme cela se fait souvent pour, par exemple, la musique ou les photographies. C'est plus robuste que l'inclusion de métadonnées mais ça passe mal à l'échelle de l'Internet (les registres existants avaient été conçus pour des écosystèmes plus petits et relativement fermés).

Enfin, parmi les difficultés, il faut noter qu'exprimer préférences et conditions d'utilisation un peu fines nécessite de disposer d'un vocabulaire (par exemple pour décrire les différentes techniques qui sont regroupées sous le terme marketing et flou d'« IA ») et qu'il n'existe pas de vocabulaire standard. Ce serait un tâche difficile que d'en établir un (un travail est en cours, dans draft-ietf-aipref-vocab). Je me souviens d'une réunion IETF où il y avait eu un long débat sur la question de savoir si la traduction rentrait dans la catégorie « IA générative » (après tout, elle génère des textes…).

La section 3 du RFC, en conclusion, essaie de synthétiser et d'identifier les points sur lesquels l'IETF pourrait travailler. L'atelier avait un relatif consensus sur le fait que la situation actuelle est mauvaise et que le principal outil technique disponible, robots.txt, ne convient pas. Les pistes de travail discutées ont été :

  • Améliorer robots.txt ou bien développer un meilleur système d'attachement aux sites Web,
  • Définir des attachements pour les protocoles IETF (par exemple dans l'en-tête HTTP, HTML ou XML dépendant d'un autre organisme),
  • Définition d'un vocabulaire commun (le groupe de travail IETF aipref y travaille),
  • Description de comment les différentes techniques (attachées au site Web ou bien attachées au contenu) se combinent.

Par contre, le consensus était que les points suivants n'étaient pas du ressort de l'IETF ou ne pouvaient pas, pour l'instant, faire l'objet d'un travail concret :

Notez qu'un résumé de l'atelier avait été publié juste après. Et, sinon, vous pouvez regarder l'intéressant site Web « Dealing With Bots » et, sur les projets de contrôle de l'accès aux ressources et leurs risques, l'excellent article « No One Should Control the Internet After AI: Freedom to Build Cleopatra GPT ».


Téléchargez le RFC 9969


L'article seul

RFC 9959: Convergence of Congestion Control from Retained State

Date de publication du RFC : Mai 2026
Auteur(s) du RFC : N. Kuhn (Thales Alenia Space), E. Stephan (Orange), G. Fairhurst, R. Secchi (University of Aberdeen), C. Huitema (Private Octopus)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 12 mai 2026


Traditionnellement, les protocoles de transport comme QUIC ou TCP partaient de zéro à chaque connexion. On se connecte, on démarre prudemment (ne pas envoyer trop de données pour éviter de congestionner le réseau), puis on augmente le débit petit à petit. Mais c'est dommage de ne pas tenir compte des connexions précédentes, où on avait déjà suivi ce processus. Ne pourrait-on pas se souvenir des mesures précédentes pour aller plus vite la prochaine fois ? C'est justement ce que propose ce RFC.

Évidemment, si l'idée est simple, la réalisation soulève plein de problèmes, d'autant plus qu'on touche ici à une activité dangereuse : si on se trompe, on risque d'aggraver la congestion. Le RFC détaille donc plus précisément comment réutiliser ces mesures passées, pour ne pas faire s'écrouler le réseau. Tout protocole de transport doit utiliser un algorithme de contrôle de la congestion (RFC 2914) ou bien s'auto-modérer (RFC 8085). Mais concevoir un bon algorithme de contrôle de la congestion n'est pas trivial et, par exemple, le RFC 5783 notait que les algorithmes existants marchaient mal pour les liaisons avec un BDP élevé et/ou très variable, comme les liaisons satellite.

Pour comprendre pourquoi, revenons un peu au fonctionnement typique d'un algorithme de contrôle de la congestion. Il a typiquement deux phases. D'abord, au début de la connexion, on envoie moins de données que ce qu'on pourrait, afin de ne pas congestionner le réseau. Puis on augmente le débit, jusqu'au moment où des indicateurs comme la perte de paquets ou le rythme des accusés de réception (RFC 9406) signalent qu'on a atteint la capacité maximale pour ce flux de données. La dépasser (overshoot) congestionnerait le réseau ou, si les autres flux qui se partagent le réseau sont mieux élevés, entrainerait des diminutions de ressources pour ces autres, voire un écroulement du réseau sous la charge. Voilà pourquoi il faut démarrer lentement.

Au passage, le RFC note que, bien sûr, la connexion TCP ou QUIC qui réutiliserait les mesures d'une précédente connexion doit s'assurer qu'on compare ce qui est comparable : mêmes adresses IP source et destination, et peut-être même DSCP (Differentiated Services Code Point, cf. RFC 2474). On verra plus loin que ce n'est pas suffisant (les choses peuvent changer, le passé peut ne pas être un bon indicateur du présent), mais patientez encore un peu.

La méthode de notre RFC se nomme « reprise prudente » (careful resume) ou, en plus joli « partage temporel » (temporal sharing), puisqu'on reprend des mesures passées (mesures de la capacité, du RTT, etc). Ces mesures pouvant ne plus être d'actualité (trop vieilles et/ou le chemin suivi a changé), il faut en effet être prudent (cf. RFC 9000 et RFC 9040).

Dans quels cas cette reprise (prudente) de données d'une connexion précédente peut être utile ? La section 1.4 du RFC liste un certain nombre de cas d'usages. Entre autres, il y a le cas d'une application qui utilise plusieurs connexions, les connexions peuvent alors utiliser les données récupérées par la première d'entre elles. Ou bien lorsqu'une connexion a été violemment interrompue et repart tout de suite après. Et il y a aussi une autre utilisation, lorsque la latence du chemin utilisé est bien plus importante que dans une liaison Internet typique, ce qui est le cas des satellites lorsqu'ils ne sont pas en orbite basse. L'article « Google QUIC performance over a public SATCOM access  » note ainsi que sur une liaison via un satellite géostationnaire, avec l'algorithme classique, transférer 5,3 Mo prendra 9 secondes alors que le partage temporel, si on peut réutiliser les mesures d'une connexion précédente, prendra 4 secondes. (Si les 9 secondes vous semblent trop, compte-tenu de la capacité du lien, rappelez-vous que la capacité n'est pas le seul facteur limitant ; TCP, surtout au démarrage, n'utilise pas toute la capacité, et il met longtemps à converger si la latence est élevée.) Une autre présentation, à l'IETF « Feedback from using QUIC's 0- RTT-BDP extension over SATCOM public access », calcule une réduction du temps de transfert de 62 % pour faire voyager 1 Mo. Enfin, le RFC recommande la lecture de la synthèse « Careful Resumption of Internet Congestion Control from Retained Path State ».

Le récepteur des données peut avoir des informations que l'envoyeur n'a pas, et cela peut le pousser à vouloir désactiver la reprise que l'envoyeur croit prudente. Par exemple, le récepteur sait peut-être quelle quantité de données va être envoyée, ou bien il sait que le chemin sur le réseau a changé.

Toujours pour compliquer les choses, il faut aussi se souvenir que d'autres facteurs peuvent limiter la quantité de données qu'on envoie, par exemple le contrôle de flux, donc les fenêtres de TCP (RFC 9293, section 3.8.6) ou le système de crédit de QUIC (RFC 9000, section 4).

Prenant en compte tout cela, la section 1.5 du RFC résume les principes de la « reprise prudente » :

  • D'abord, s'assurer que les conditions n'ont pas changé depuis la dernière connexion ; le chemin est-il le même ? (La mesure du RTT donne une première bonne idée.) À l'issue de cette phase de reconnaissance, si les conditions ont changé, on utilise la méthode classique, on ne tient pas compte des mesures qui ont été sauvegardées.
  • Ensuite, OK, on va plus vite qu'avec la méthode classique mais pas aussi vite que ne l'indiquent les mesures sauvegardées. Après tout, la reconnaissance ne permet pas toujours d'identifier un changement dans les conditions.
  • Enfin, on se prépare à faire marche arrière, et à revenir à la méthode classique, si on s'aperçoit qu'on est en train de créer de la congestion. (Le RFC note qu'il faut la détecter rapidement, avant que les autres flots de données n'aient détecté la congestion et réduit leur débit.)

Un peu de terminologie avant de continuer (section 2) : le partenaire distant (remote endpoint) est l'ensemble des informations qui identifie à qui on envoie des données, typiquement l'identificateur d'une interface réseau locale couplé à l'adresse IP de la machine avec qui on parle et peut-être (c'est une décision locale, et forcément très dépendante du système d'exploitation utilisé) des informations comme DSCP. Si le partenaire distant change, on en déduit que le chemin a changé (l'inverse n'est pas vrai : le chemin peut changer alors que le partenaire distant est le même). Si on a une indication que le chemin a changé, on revient au mécanisme traditionnel, on n'utilise pas les paramètres gardés des précédentes connexions.

Le mécanisme de notre RFC a donc plusieurs phases (section 3, mais regardez aussi le joli tableau de l'annexe A, qui est peut-être plus clair) : celle de reconnaissance, où on cherche si les caractéristiques du chemin correspondent à un chemin connu, puis , selon son résultat, on passe à la phase dite normale, si on a reconnu un chemin déjà vu, ou bien à la phase non validée (chemin inconnu, on démarre prudemment), puis à la phase de validation (y a t-il un indicateur de congestion ou bien tout est-il beau et propre ?), ou bien à celle de retraite (on jette les informations enregistrées, la situation a changé, on retourne en mode traditionnel), avant de passer à la phase normale. (Des exemples détaillés figurent dans l'annexe B.)

La section 4 du RFC fournit des détails sur la mise en œuvre des principes de ce RFC. Par exemple, la détermination pratique d'un changement du chemin. Un bon indicateur est le RTT. Cette section conseille aussi, même en l'absence d'indications que le chemin a changé, de ne pas garder les paramètres sauvegardés trop longtemps : comme la détection d'un éventuel changement n'est pas parfaite, il vaut mieux avoir une durée de vie maximale pour les paramètres enregistrés. Le RFC suggère quelques heures, voire moins si on sait que le chemin est très dynamique.

Enfin, l'annexe B détaille à l'octet près des exemples de fonctionnement de l'algorithme de reprise prudente, pour différents cas.

Vous pouvez aussi avoir une introduction aux principes de ce RFC dans l'exposé d'un des auteurs à la Journée du Conseil Scientifique de l'Afnic en 2021 (avec les supports).

Merci à Nicolas Kuhn pour sa relecture.


Téléchargez le RFC 9959


L'article seul

RFC 9953: DNS over the Constrained Application Protocol (DoC)

Date de publication du RFC : Mars 2026
Auteur(s) du RFC : M. S. Lenders (TU Dresden), C. Amsüss, C. Gündoğan (NeuralAgent GmbH), T. C. Schmidt (HAW Hamburg), M. Wählisch (TU Dresden & Barkhausen Institut)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF core
Première rédaction de cet article le 1 avril 2026


Le protocole CoAP est un protocole léger, conçu pour les objets connectés. Ce RFC décrit comment faire du DNS au-dessus de CoAP. Si votre brosse à dents a besoin de faire du DNS, c'est ce RFC qu'il faut lire.

CoAP, normalisé dans le RFC 7252, ressemble à HTTP mais en plus simple. Il vise le marché des objets contraints (en mémoire, énergie, en capacité réseau, en puissance de calcul…, voir le RFC 7228). CoAP permet à un client d'envoyer des requêtes à un serveur, et notre tout neuf RFC 9953 explique comment utiliser CoAP pour faire des requêtes DNS et recevoir des réponses DNS. Comme CoAP peut être vu, de manière simplifiée, comme une variante légère de HTTP, ce DNS sur CoAP, alias DoC (DNS over CoAP), est très proche dans ses principes de DoH (RFC 8484). Les contraintes de l'Internet des objets empêchent votre tournevis ou votre ampoule électrique de faire du DoH (qui implique HTTPS), d'où ce DoC. Bien sûr, il y avait toujours la possibilité de faire du DNS sur DTLS, comme le décrit le RFC 8094, mais CoAP a plein de fonctions sympas pour les objets contraints (transferts par blocs - RFC 7959, qui résout les problèmes de MTU, relais CoAP, etc).

L'architecture générale de DoC est très proche de celle de DoH : le client DoC interroge un serveur DoC qui est lui-même un client DNS, parlant typiquement à un résolveur DNS. La communication entre le client DoC et le serveur DoC utilise CoAP, celle entre le serveur DoC et le résolveur utilise le DNS normal, sur UDP, TCP, TLS, etc.

Le serveur DoC sera a priori désigné par le chemin /. Le but est que les messages soient plus courts (DoH utilise souvent le chemin /dns-query). Au fait, comment le client DoC trouve-t-il le serveur (section 3 du RFC) ? Plusieurs méthodes sont admises, de la configuration manuelle (« le serveur DoC est en coaps://doc.foobar.example/ ») aux répertoires CORE (RFC 9176) en passant par les classiques DHCP ou RA ou bien par la découverte de résolveurs du RFC 9462. Ces différentes solutions sont plus ou moins sûres, et plus ou moins pratiques pour l'administrateur/utilisateur (et en général les plus pratiques sont les moins sûres).

Mais ce n'est pas tout : le serveur DoC peut aussi être trouvé via le DNS, avec un enregistrement SVCB (RFC 9460 et RFC 9461), si l'objet contraint a déjà un moyen d'interroger le DNS (la clé SVCB est docpath, numéro 10).

Une fois qu'on connait le serveur, on peut lui parler. La section 4 décrit les messages CoAP échangés. Ils sont étiquetés avec le type application/dns-message (valeur numérique 553).

La méthode CoAP utilisée est FETCH (RFC 8132), qui n'a pas d'équivalent HTTP, contrairement à la plupart des méthodes CoAP. DoC utilise le principe REST (RFC 6690). Le RFC recommande de ne pas oublier le champ Accept: pour indiquer le type de données accepté. Le type recommandé est application/dns-message. Dans la requête, le Query ID DNS devrait être à 0, CoAP se charge de mettre en correspondance requêtes et réponses donc cet identificateur n'est pas utile (c'est pareil pour DoH).

Et les réponses ? Là encore, comme pour DoH, les codes de retour CoAP indiquent si le serveur DoC a pu être joint et a pu faire son travail, pas si la requête DNS a eu une réponse satisfaisante. Autrement dit, tant que le serveur DoC fonctionne bien, il renvoie le code 2.05 (RFC 7252, section 5.9.1.5.) et c'est dans le message DNS qu'on saura si la résolution DNS a renvoyé NOERROR, SERVFAIL, NXDOMAIN, etc.

La mémorisation des réponses joue un rôle plus grand en CoAP qu'en HTTP (rappelez-vous que CoAP sert à des objets contraints). Le RFC demande donc que les TTL dans la réponse DNS soient constants, afin que l'ETag (RFC 7252, section 5.10.6), s'il est calculé via un condensat, ne change pas. Le serveur DoC doit par contre mettre un champ Max-Age: dans sa réponse (section 4.3.2).

Voici, tiré du RFC, un exemple de réponse CoAP, formaté en texte :


2.05 Content
Content-Format: 553 (application/dns-message)
Max-Age: 58719
Payload (human-readable):
    ;; ->>Header<<- opcode: QUERY, status: NOERROR, id: 0
    ;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;example.org.                 IN      AAAA
    ;; ANSWER SECTION:
    ;example.org.         79689   IN      AAAA    2001:db8:1:0:1:2:3:4

  

Et la sécurité ? Le RFC recommande de sécuriser la communication avec le système OSCORE du RFC 8613 (ou, sinon, le DTLS du RFC 9147, ce qui donne du CoAPS). Le RFC note que cela assure la sécurité de la communication entre le client DoC et le serveur DoC mais que, après, on ne sait pas ce que fait le serveur (la section 8 recommande évidemment que le serveur DoC valide avec DNSSEC).

Questions mises en œuvre de DoC, on trouve (mais je ne les ai pas testées, je ne fais pas d'Internet des Objets), par les auteurs du RFC, dans RIOT, un client en C (source sur Github) et un serveur en Python.

Si vous voulez allez plus loin que ce résumé sommaire, une bonne lecture est le papier de 2023 des auteurs, « Securing Name Resolution in the IoT: DNS over CoAP ».


Téléchargez le RFC 9953


L'article seul

RFC 9945: IETF Community Moderation

Date de publication du RFC : Février 2026
Auteur(s) du RFC : L. Eggert (Mozilla), E. Lear (Cisco Systems)
Réalisé dans le cadre du groupe de travail IETF modpod
Première rédaction de cet article le 2 mars 2026


Comme toute organisation humaine, l'IETF doit gérer le cas de personnes pénibles, qui font perdre du temps à tout le monde, mettent une mauvaise ambiance ou cherchent activement à perturber le travail commun. Ce RFC (qui remplace les RFC 3683 et RFC 3934) établit la politique de l'IETF vis-à-vis de ces gens : être patient mais pas trop.

Les principes de base de la gestion des abusifs sont les principes de l'IETF (RFC 3935 et RFC 7154). Il ne s'agit pas d'empêcher les désaccords (ils sont attendus et sains). L'IETF est une organisation très ouverte et ses participant·es sont divers·es. On recherche un consensus approximatif (RFC 7282) mais, bien sûr, s'opposer au consensus n'est pas en soi un problème. L'IETF n'est pas une religion. Mais certains vont « sortir des clous ». L'annexe B du RFC donne quelques exemples (messages hors-sujet sur un groupe, ton agressif, remise en cause permanente des décisions et une pratique que je ne connaissais pas, le sealioning). L'IETF devra réagir, en suivant ces lignes directrices :

  • Avoir une politique qui soit cohérente et équitable. Elle doit s'appliquer uniquement sur la base du comportement de la personne et pas, par exemple, selon le nombre de RFC qu'elle a écrit, ni selon son ancienneté.
  • Permettre des appels contre les décisions prises (le contrôle est une activité délicate et les décisions seront parfois difficiles).
  • Essayer de respecter la vie privée tout en maintenant une certaine transparence (exemple de problème : les sanctions doivent-elles être publiques ?).
  • Être flexible car il faudra pouvoir s'appliquer à des cas variés. (Notez la tension entre cet objectif et le premier cité…)

Le travail de contrôle reposera essentiellement sur l'équipe de contrôle (moderation team), décrite en section 2. Elle comportera au moins cinq personnes, nommées par l'IESG, qui devra essayer de respecter une certaine diversité. Ces personnes ne doivent pas être membres de l'IESG ou de l'IAB. La diversité souhaitée inclut celle des fuseaux horaires car l'équipe devra parfois réagir vite. L'IETF LLC, la structure administrative décrite dans le RFC 8711, se chargera de leur financer une formation.

Leur travail couvrira toutes les discussions publiques en ligne à l'IETF, qu'elles soient sur une liste de diffusion, un dépôt GitHub, etc. Le RFC distingue les administrateurs, qui gèrent un de ces lieux de discussion, de l'équipe de contrôle. Les administrateurs signalent les problèmes et appliquent les décisions de l'équipe de contrôle. Mais, évidemment, pour éviter de surcharger cette équipe, les administrateurs sont aussi censés gérer la plupart des problèmes localement. L'idée derrière l'équipe centrale (moderators) est d'avoir un groupe formé et qui pourra s'assurer d'une politique cohérente au niveau de l'IETF. Vu la taille de l'IETF, les contrôleurs ne pourront pas tout surveiller préventivement et dépendront donc beaucoup des signalements faits, par exemple par les administrateurs.

Vous ne l'avez peut-être pas noté plus haut mais le mot important est « publiques ». L'équipe de contrôle ne va pas gérer les communications privées. Par ailleurs, elle contrôle des comportements, pas le contenu (donc, pas la peine de lui demander de censurer telle ou telle partie d'un Internet-Draft). Quand au spam, il est effectivement un exemple de comportement perturbateur mais il y a déjà une politique à ce sujet.

Ce sera à l'équipe de contrôle de définir ses processus de fonctionnement et ses détails de politique, pour ce qui n'est pas déjà couvert dans ce RFC 9945. Tout cela devra évidemment être discuté au sein de l'IETF et, au bout du compte, approuvé par l'IESG et rendu public (mais pas forcément dans un RFC).

Qu'est-ce que pourra faire en pratique l'équipe de contrôle ? Le RFC donne quelques exemples (section 4) :

  • Faire passer les messages d'une personne par un système d'approbation explicite (par défaut, l'IETF n'a pas de contrôle a priori),
  • Engueuler quelqu'un, en privé ou en public,
  • Supprimer complètement le droit d'écriture à une personne.

Et l'équipe de contrôle devra évidemment garder trace de ces actions, pour en rendre compte. Et des appels sont possibles (RFC 2026, sections 6.5.1 et 6.5.4).

Il y a d'autres fonctions dans l'IETF qui ont un rapport avec cette nécessité de contrôler les débordements de certains participants (section 5). C'est le cas de l'ombudsteam et de l'incarnation administrative de l'IETF, la LLC (notamment si le comportement de certains entraine des risques juridiques pour l'IETF). Il y a aussi plein d'autres RFC à lire, comme le RFC 7776, sur les mesures contre le harcèlement ou le RFC 9245, sur la gestion des listes de diffusion (rappelez-vous que l'équipe de contrôle ne sera pas limitée à ces listes).

Le RFC remarque à juste titre (section 6) que toute politique peut être utilisée de manière abusive, par exemple à des fins de censure. La section 6 revient sur les différentes décisions décrites par le RFC et comment elles contribuent à minimiser ce risque.

Notez que ce RFC s'applique à l'IETF uniquement, et pas aux autres organisations proches comme l'IRTF.

Enfin, l'annexe A explique les motivations derrière ce RFC et le pourquoi des différents choix. Malgré la quantité de RFC et de décisions documentées, il n'était pas toujours évident de reconnaitre ce qui était un comportement perturbateur. Et les processus existants étaient trop lents, en partie parce qu'ils supposaient que tout le monde était de bonne foi. D'où ce nouveau RFC qui explique comment un meilleur mécanisme va être défini.


Téléchargez le RFC 9945


L'article seul

RFC 9935: Internet X.509 Public Key Infrastructure - Algorithm Identifiers for the Module-Lattice-Based Key-Encapsulation Mechanism (ML-KEM)

Date de publication du RFC : Mars 2026
Auteur(s) du RFC : S. Turner (sn3rd), P. Kampanakis, J. Massimo (AWS), B. E. Westerbaan (Cloudflare)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lamps
Première rédaction de cet article le 7 mars 2026


Ce RFC spécifie comment mettre des clés ML-KEM dans un certificat X.509. Vous allez me dire « Mais ML-KEM est un algorithme d'échange de clés, pas de signature, que fait-il dans un certificat ? » Et je vous répondrai que vous avez raison, d'ailleurs le RFC restreint sérieusement ce qu'on peut faire avec cet algorithme.

ML-KEM a l'intéressante propriété d'être résistant aux calculateurs quantiques. Il est normalisé dans FIPS 203. Ce RFC permet de l'utiliser dans les certificats normalisés dans le RFC 5280, et il décrit trois variantes, ML-KEM-512, ML-KEM-768 et ML-KEM-1024.

Comme indiqué plus haut, autant il était normal de permettre ML-DSA dans les certificats (RFC 9881), autant cela peut sembler surprenant pour ML-KEM. La section 1.1 de notre RFC explique les usages (limités) d'un algorithme d'échange de clés dans un certificat. C'est par exemple utile pour un protocole où vous avez besoin d'une clé publique, que vous allez tirer du certificat. Mais vous ne pourrez pas utiliser les certificats de ce RFC pour faire du TLS sur l'Internet public, aucune AC ne vous en produira, même si TLS le permet un jour. Pour la même raison, vous n'en trouverez pas dans les journaux Certificate Transparency.

Les trois algorithmes sont identifiés en suivant le RFC 5912, par un OID via le NIST ; Ce sont id-alg-ml-kem-512 (2.16.840.1.101.3.4.4.1), id-alg-ml-kem-768 (2.16.840.1.101.3.4.4.2) et id-alg-ml-kem-1024 (2.16.840.1.101.3.4.4.3).

La section 5 du RFC précise que les bits indiquant les utilisations possibles de ces certificats (RFC 5280, section 4.2.1.3) doivent indiquer uniquement le chiffrement d'une clé (et pas l'authentification, comme avec les certificats habituels).

Le module ASN.1 figure dans l'annexe A, si vous voulez implémenter ce RFC (il faut aussi importer les modules des RFC 5912 et RFC 9629). Le module est identifié par id-mod-x509-ml-kem-2025 et a l'OID 1.3.6.1.5.5.7.0.121. Le gros du RFC est constitué d'exemples de clés et de certificats ML-KEM (annexe C), dans l'encodage en texte du RFC 7468.

Allez, un peu de pratique avec OpenSSL 3.5 :

% openssl genpkey -algorithm ML-KEM-512 -out ml-kem-key.pem -outform PEM

% cat ml-kem-key.pem
-----BEGIN PRIVATE KEY-----
MIIGvgIBADALBglghkgBZQMEBAEEggaqMIIGpgRAOwWCnP71SklfOIuwiLrIddsm
Up4AlOMwvwjqCy4PHr8fSq5jRjFoP6XYXnl8IQCR9HhzSRVffI09hBezOUrmxgSC
…

# Analysons cette clé :
% openssl pkey -text -in ml-kem-key.pem 

# Demandons une signature du certificat :
% openssl req -new -key ml-kem-key.pem  -provider default -out req.csr 
…
40E7CEC0027F0000:error:03000096:digital envelope routines:do_sigver_init:operation not supported for this keytype:../crypto/evp/m_sigver.c:305:

Ah, là, c'est raté, et c'est logique. OpenSSL n'accepte pas de fabriquer un CSR pour ces clés « operation not supported for this keytype » puisque ML-KEM ne permet pas de signer. La solution :

# Extraire la clé publique :
% openssl pkey -in ml-kem-key.pem -pubout   -out mlkem.pub

# Fabriquer une clé ECDSA pour signer :
% openssl ecparam -out ec_key.pem -name secp256r1 -genkey 

# Signer :
% openssl x509 -new \
  -subj "/CN=test-mlkem" \
  -force_pubkey mlkem.pub \
  -signkey ec_key.pem \
  -days 365 \
    -out mlkem-cert.pem
Warning: Signature key and public key of cert do not match

L'avertissement est normal, puisqu'on a effectivement utilisé une autre clé, d'un autre algorithme, pour signer le certificat contenant notre clé publique ML-KEM. Mais tout s'est bien passé :

% openssl x509 -text -in mlkem-cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            69:33:f9:1e:e5:34:64:84:d9:f4:b2:15:3b:50:ec:36:db:0b:71:5c
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN=test-mlkem
        Validity
            Not Before: Feb 16 15:30:02 2026 GMT
            Not After : Feb 16 15:30:02 2027 GMT
        Subject: CN=test-mlkem
        Subject Public Key Info:
            Public Key Algorithm: ML-KEM-512
                ML-KEM-512 Public-Key:
                ek:
                    d8:d2:6c:c4:9b:96:48:23:0d:ce:f7:0d:b3:0b:85:
                    …
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                E7:B2:03:92:37:EC:C6:35:E4:F0:2E:AC:4E:1C:F2:81:67:F7:95:29
            X509v3 Authority Key Identifier: 
                15:E5:2A:5E:B1:C3:50:69:7E:E4:48:EA:0F:DD:3C:5C:90:4B:7C:CC
    Signature Algorithm: ecdsa-with-SHA256
  

Téléchargez le RFC 9935


L'article seul

RFC 9934: Privacy-Enhanced Mail (PEM) File Format for Encrypted ClientHello (ECH)

Date de publication du RFC : Mars 2026
Auteur(s) du RFC : S. Farrell (Trinity College Dublin)
Chemin des normes
Première rédaction de cet article le 5 mars 2026


La technique ECH (Encrypted Client Hello) permet de boucher une faille de TLS, la transmission en clair du nom du serveur demandé. Elle est normalisée dans le RFC 9849 mais il y manquait la description d'un format standard pour envoyer les données nécessaires à ECH. C'est désormais fait (et vous reconnaitrez le classique format PEM, cf. RFC 7468).

Le principe d'ECH est de chiffrer le nom du serveur demandé, avec la clé publique du serveur TLS. Pour configurer le serveur, il faut la clé privée correspondante et différents détails, la ECHConfig (RFC 9849, section 4). C'est pour ECHConfig que notre RFC normalise un format.

Le fichier PEM (RFC 7468) contient une ou plusieurs clés privées et des informations de configuration (pour un ou plusieurs serveurs), le tout en Base64 (section 4 du RFC 4648). Les informations publiques sont typiquement mises dans le DNS (RFC 9848), la clé privée, cela va sans dire (mais le RFC le dit quand même, on ne sait jamais) n'est pas publiée. Un fichier PEM contenant des clés privées doit évidemment être bien protégé.

Voici un exemple, tiré du RFC (la clé privée a donc déjà été publiée 😁) :

   -----BEGIN PRIVATE KEY-----
   MC4CAQAwBQYDK2VuBCIEICjd4yGRdsoP9gU7YT7My8DHx1Tjme8GYDXrOMCi8v1V
   -----END PRIVATE KEY-----
   -----BEGIN ECHCONFIG-----
   AD7+DQA65wAgACA8wVN2BtscOl3vQheUzHeIkVmKIiydUhDCliA4iyQRCwAEAAEA
   AQALZXhhbXBsZS5jb20AAA==
   -----END ECHCONFIG-----
  

Dans le DNS, la publication de la clé publique et de la configuration donnerait quelque chose du genre :

% dig +short HTTPS foo.example.com
1 . ech=AD7+DQA65wAgACA8wVN2BtscOl3vQheUzHeIkVmKIiydUhDCliA4iyQRwAEAAEAAQALZXhhbXBsZS5jb20AAA==    
  

Bien des logiciels reconnaissent cette syntaxe. Je ne les ai pas testés mais, apparemment :


Téléchargez le RFC 9934


L'article seul

RFC 9926: Prefix Registration for IPv6 Neighbor Discovery

Date de publication du RFC : Février 2026
Auteur(s) du RFC : P. Thubert
Chemin des normes
Première rédaction de cet article le 14 février 2026


Une addition sympa au mécanisme de découverte des voisins d'IPv6 (RFC 4861), utile pour les réseaux d'objets contraints, genre Internet des Objets mais aussi les réseaux à connectivité imparfaite, par exemple avec des hauts et des bas : la possibilité pour une machine qui est connectée à un réseau d'un préfixe donné d'enregistrer ce préfixe auprès des routeurs voisins. Ceux-ci sauront alors où envoyer les paquets pour ce préfixe. Cela ne remplace pas les protocoles de routage traditionnels, c'est plutôt une addition pour optimiser les protocoles spécialisés dans les réseaux contraints.

Le cœur de cible de ce RFC, ce sont les LLN (Low power and Lossy Networks, les réseaux « pauvres », avec pas beaucoup d'énergie et des liaisons pourries, cf. RFC 7102 et RFC 7228). La préoccupation principale est d'économiser l'énergie ; éviter de transmettre (la radio coûte cher) et s'endormir le plus souvent possible. Ces LLN utilisent des technologies comme 6LoWPAN (RFC 4919) et le protocole de routage RPL du RFC 6550. Les protocoles conçus pour les LLN n'utilisent donc pas d'émissions périodiques (comme le fait OSPF), qui consomment de l'énergie, et obligent tout le monde à écouter tout le temps, donc à ne pas dormir. L'idée de ce RFC est de compter sur quelques routeurs qui sont moins contraints (par exemple parce qu'ils sont connectés à une prise de courant) et que les autres signalent aux routeurs les préfixes connus, lorsqu'ils sont réveillés.

Autre exemple, les mécanismes IPv6 de découverte du voisin (RFC 4861 et RFC 4862) ont été conçus en pensant à des machines alimentées électriquement en permanence, sur des réseaux comme Ethernet, où diffuser à tout le monde est peu coûteux. Mais ils ne fonctionnent plus si, par exemple, certaines machines sont endormies, et ne répondent donc pas aux sollicitations. D'où des idées comme le RFC 6775, où une machine n'attend pas les sollicitations, elle profite de ses périodes d'éveil pour enregistrer son adresse auprès du routeur. Idem avec le projet draft-ietf-6man-ipv6-over-wireless. L'idée a ensuite été généralisée par le RFC 8505, sur lequel s'appuie notre nouveau RFC, qui permet d'enregistrer un préfixe IP entier. Notez bien que cette technique est indépendante de la manière dont la machine a reçu ce préfixe en allocation, et de la manière dont le routeur auprès duquel on s'enregistre va ensuite diffuser son préfixe dans son domaine de routage.

La section 3 du RFC donne une vision générale du nouveau mécanisme, je vous laisse la lire 😃.

Notez (section 11) que la machine qui enregistre un préfixe peut mentir et que cette technique doit donc être déployée en comprenant les caractéristiques spécifiques du réseau (par exemple, fermé ou au contraire ouvert sur l'Internet). Le RFC 8928 est ici une bonne lecture, ainsi que la section 9 de notre RFC.

Et merci à Pascal Thubert pour sa relecture. (Naturellement, je reste responsable des erreurs et approximations.)


Téléchargez le RFC 9926


L'article seul

RFC 9925: Unsigned X.509 Certificates

Date de publication du RFC : Février 2026
Auteur(s) du RFC : D. Benjamin (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lamps
Première rédaction de cet article le 27 février 2026


Un certificat est signé par une AC, normalement, ou à la rigueur auto-signé, ce qui ne sert pas à grand'chose mais est obligatoire dans X.509. Mais voici que ce RFC rend la signature facultative.

À ma connaissance, le seul intérêt d'auto-signer son certificat est de prouver qu'on a bien la clé privée correspondante (car un plaisantin peut toujours fabriquer un certificat avec la clé publique de quelqu'un d'autre) et, en prime, de vérifier l'intégrité. C'est pas crucial. Mais la norme X.509 (cf. RFC 5280) ne permet pas d'avoir un certificat sans signature. Notre RFC 9925 contourne cette obligation en enregistrant un nouvel algorithme, id-alg-unsigned, qui indique qu'il n'y a pas de signature du tout.

C'est parce que, parfois, on n'a pas besoin des signatures. Un exemple typique se trouve dans votre magasin d'AC : vous ne vérifiez pas les signatures (vous ne pouvez pas, puisque les AC sont à la racine de la validation, RFC 5280, section 6), la seule présence du certificat dans le magasin inspire la confiance. Les certificats des AC sont donc auto-signés, ce qui ne sert pas à grand'chose, à part à satisfaire les exigences syntaxiques du format X.509. Ici, le certificat d'une AC du magasin de ma machine Ubuntu ; Issuer est égal à Subject, le certificat est auto-signé :

% openssl x509 -text -in /etc/ssl/certs/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem
Certificate:
        Issuer: C = ES, CN = Autoridad de Certificacion Firmaprofesional CIF A62634068
        Subject: C = ES, CN = Autoridad de Certificacion Firmaprofesional CIF A62634068
	…
           X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:1
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
        …	

(Une autre solution serait le RFC 5914 mais il ne semble pas très courant.)

Un autre cas où on se moque de la signature du certificat est celui où le certificat est validé d'une autre façon, par exemple un serveur EPP sur TLS qui a une liste de tous les clients possibles, et des certificats que le registre a distribués à ses BE.

Donc, il y a des cas où la signature ne sert guère, voire pas du tout. Mais est-ce gênant ? Ce n'est pas dramatique mais, dans certains cas, c'est sous-optimal, par exemple :

  • Les signatures post-quantiques sont souvent de grande taille, donc cela rend les certificats plus gros pour rien.
  • La clé publique dans le certificat peut utiliser un algorithme qui ne permet pas la signature (comme ML-KEM, cf. le futur RFC draft-ietf-lamps-kyber-certificates).

La section 3 du RFC fournit les détails techniques. Dans le certificat, on met le champ signatureAlgorithm à id-alg-unsigned et le champ signatureValue à une chaine vide. Le champ issuer pourrait être vide puisque personne n'a signé le certificat, mais comme il était obligatoire, pour éviter de choquer les applications actuelles, il vaut mieux mettre un issuer égal au subject (comme pour un auto-signé). On a le droit de mettre plutôt un nom /id-rdna-unsigned= (en fait 1.3.6.1.5.5.7.25.1 mais je montre la représentation textuelle du RFC 4514). RDNA signifie Relative Distinguished Name Attribute et un nouveau registre, « SMI Security for PKIX Relative Distinguished Name Attribute », est créé pour accueillir id-rdna-unsigned et d'autres futurs noms (politique de Spécification nécessaire, cf. RFC 8126).

Quand une application rencontre un de ces certificats non signés, si elle valide les signatures, elle doit évidemment rejeter le certificat. Si elle est plus laxiste (ou bien a d'autres mécanismes de vérification), elle peut l'accepter (section 4). Les applications et bibliothèques existantes font déjà cela (elles rejettent les signatures d'algorithmes inconnus) donc l'introduction des certificats non signés ne devrait rien casser.

Quelques conseils de sécurité figurent en section 5, par exemple de ne pas réutiliser les clés dans des contextes différents. (X.509, jusqu'à présent, ignorait ce conseil pour les certificats auto-signés puisque la clé publiée servait aussi à signer. Plus de signature, plus de problème.)

Désolé, mais je n'ai pas trouvé comment générer aujourd'hui de tels certificats, que ce soit avec OpenSSL (c'est en cours) ou d'autres logiciels. Si vous trouvez, ça m'intéresse, je pourrais mettre des essais pratiques ici.


Téléchargez le RFC 9925


L'article seul

RFC 9923: The FNV Non-Cryptographic Hash Algorithm

Date de publication du RFC : Février 2026
Auteur(s) du RFC : G. Fowler (Google), L. Noll (Cisco Systems), K. Vo (Google), D. Eastlake (Independent), T. Hansen (AT&T)
Pour information
Première rédaction de cet article le 28 février 2026


L'algorithme de condensation FNV, présenté dans ce RFC n'est pas neuf (et certains disent même qu'il est dépassé). Mais il est utilisé par de nombreux logiciels alors qu'il n'avait jamais été spécifié « proprement ». Voilà qui est fait.

FNV a comme principal avantage ses performances : il est rapide et le code est court. Comme le précise le titre du RFC, il n'a pas les caractéristiques des algorithmes de condensation utilisés pour des services de sécurité. Mais cela ne l'empêche pas d'être déployé depuis de nombreuses années pour bien d'autres usages.

Le RFC fait 137 pages mais ne vous affolez pas, FNV est simple et l'essentiel de ces pages est composé de code mettant en œuvre FNV de diverses manières. J'emprunte au RFC, section 2 (avec les modifications de l'article de Wikipédia pour que ce soit plus clair) l'essentiel de l'algorithme, en pseudo-code :

algorithm fnv-1 is
    hash := FNV_offset_basis

    for each byte_of_data to be hashed do
        hash := hash × FNV_prime
        hash := hash XOR byte_of_data

    return hash 
  

C'est court et rapide, non ? Mais, et le RFC le rappelle plusieurs fois (car des critiques sérieuses du projet de RFC avait insisté sur cette question) : cet algorithme ne doit pas être utilisé pour le cas où on veut de la résistance aux attaques comme la pré-image (section 1.1 du RFC). Ainsi, Python utilisait FNV mais a arrêté.

Qu'est-ce qui fait que FNV se retrouve qualifié de « non-cryptographique » et pas utilisable pour la sécurité ? La section 1.3 liste les limites de FNV (voir aussi la section 6) comme le fait que chaque bit du condensat ne dépend pas de tous les bits de la donnée d'entrée ou comme le fait que FNV est trop rapide. Oui, pour la sécurité, cela peut être un problème : si on utilise une fonction pour condenser des mots de passe, on ne veut pas faciliter la tâche de l'attaquant qui va chercher un mot de passe ayant ce condensat, en essayant beaucoup de mots de passe possibles. Une fonction de condensation a donc intérêt à être lente, comme Argon 2 (RFC 9106).

Vous trouverez par contre du FNV un peu partout (la section 1.2 vous donne une liste), dès que ces questions de sécurité ne sont pas pertinentes. FNV est même cité dans des RFC, le RFC 7357 ou le RFC 7873 (les cookies du DNS) ou bien dans la norme IEEE 802.1Qbp.

FNV a une longue histoire (section 7 du RFC), ayant commencé en 1991. On notera que la définition de FNV inclut quelques valeurs largement arbitraires comme, par exemple, la chaine de caractères « chongo <Landon Curt Noll> /\../\ », dont le condensat fournit le paramètre offset_basis (section 2.2). Cette chaine était dans le .signature d'un des auteurs de FNV mais, c'est amusant, avait été mal recopiée.

Le gros (en nombre de pages) du RFC étant constitué de code source en C, avec des variantes selon le nombre de bits produits, plutôt que de tenter de l'extraire du RFC, utilisons cette archive tar que j'ai constituée :

% tar xzvf FNV-RFC.tar.gz

% cd FNV-RFC

% echo -n toto > tmp  

% make FNVhash

% ./FNVhash -t 64 -f tmp 
FNV-64 test of return values passed.  
FNV-64 Hash of contents of file 'tmp': ADC7B038EFF1F42F 

Et voilà, FNV marche. Il existe d'autres mises en œuvre. Celle de référence est présentée ici et est également sur Github :

 
% git  clone https://github.com/lcn2/fnv

% cd fnv 

% make

% ./fnv1a64 -s toto
0x2ff4f1ef38b0c7ad

[Oui, les octets ne sont pas affichés dans le même ordre qu'avec le code du RFC.]  

Vous avez aussi d'autres mises en œuvre (une des plus rigolotes est en Fortran). Et elle n'est pas listée mais il y a une mise en œuvre de FNV dans le langage Zig (notez son utilisation de comptime).

Et pour finir, si vous vous demandez quelle fonction de condensation utiliser, il y a une comparaison de FNV avec SHA-1 (RFC 3174) et SHA-256 (RFC 6234) dans l'annexe A.


Téléchargez le RFC 9923


L'article seul

RFC 9920: RFC Editor Model (Version 3)

Date de publication du RFC : Février 2026
Auteur(s) du RFC : P. Hoffman (ICANN), A. Rossi (RFC Series Consulting Editor)
Pour information
Réalisé dans le cadre de l'activité d'édition des RFC rswg
Première rédaction de cet article le 12 février 2026


Vous avez toujours voulu savoir qui s'occupait de publier les RFC et qu'est-ce que ce mystérieux « RFC Editor » ? Ce nouveau RFC décrit ce rôle et la façon dont il doit accomplir sa tâche. Il s'agit d'une légère mise à jour du RFC 9280, sans changement de version. (Parmi les nouveautés, la définition de la notion d'utilisateurice des RFC, avant, on ne parlait que des auteurices.)

Les RFC sont un ensemble de documents techniques au sujet de l'Internet, qui comprend notamment, mais pas uniquement, les normes TCP/IP. Les RFC sont librement accessibles en ligne et sont publiés depuis 1969 (cf. RFC 8700).

Il y a très longtemps, quand les dinosaures étaient petits, le rôle de RFC Editor s'incarnait bien dans une personne unique, Jon Postel. Aujourd'hui, c'est plus complexe et il n'y a plus, depuis la version 2 du modèle (qui était dans le RFC 8728), de RFC Editor unique. Ce rôle est désormais réparti en deux tâches principales, définir la politique, et la mettre en œuvre. La première tâche est du ressort du RSWG (RFC Series Working Group), pour discuter et proposer (tout le monde, et son chat, peut y participer), puis du RSAB (RFC Series Approval Board), pour décider (ce comité est plus fermé). La deuxième tâche, la mise en œuvre de la politique, est du ressort du RFC Production Center, typiquement une organisation privée sous contrat avec l'IETF LLC, l'organisation administrative derrière l'IETF (RFC 8711). Ce sont donc tous ces groupes ensemble qui composent le « RFC Editor ». Tout ceci, et quelques autres points, étaient déjà dans le RFC 9280, notre nouveau RFC 9920 n'apporte que des changements de détail.

Les RFC sont publiés par cinq voies (streams) différentes, dont une, la voie IETF, sert pour les normes (mais tous les RFC ne sont pas des normes). Chaque voie a une organisation ou une personne responsable du contenu des RFC (pour la voie IETF, le responsable est… l'IETF), la fonction RFC Editor ne gère pas le contenu (ou seulement la forme, mais pas le fond des documents) mais la publication. Le RFC 8729, dans sa section 5.1, décrit les quatre voies classiques (IETF, IRTF, IAB et indépendante). En plus, le RFC 9280 avait introduit la voie éditoriale, dédiée aux évolutions des RFC (les RFC parlant des RFC…). C'est via cette voie que seront publiés les propositions issues du RSWG et approuvées par le RSAB. Un exemple est le récent RFC 9896, dont vous pouvez suivre l'historique.

Dans les deux tâches décrites plus haut (la définition de la politique, et sa mise en œuvre), je n'ai pas mentionné un acteur supplémentaire (comme s'il n'y en avait pas déjà assez !), le RFC Series Consulting Editor, qui est un·e expert·e en édition, membre du RSAB.

Et donc, si vous avez des idées géniales pour améliorer les RFC, il faut faire comment pour qu'elles triomphent ? Lisez la section 3 et notamment la 3.2.2 :

  • Les propositions sont écrites (un Internet draft) et diffusées au RSWG (rappelez-vous : il est ouvert, tout le monde peut y participer),
  • Après un dernier appel dans le RSWG, puis plus large, s'il y a un consensus approximatif (RFC 2418),
  • Les propositions atterrissent au RSAB, qui décidera (avec des votes YES ou CONCERN, le second n'étant pas un NO mais une demande de discussion).

Chaque acteur est décrit ensuite plus en détail. Le RSWG est le groupe le plus ouvert du lot, vous vous abonnez à sa liste de diffusion et c'est parti, vous êtes membre. Et ceci que vous soyez déjà participant à l'IETF ou pas. Les développeur·ses qui mettent en œuvre les RFC, les auteurs de RFC, les auteurs de logiciels qui traitent les RFC, les gens qui citent les RFC dans leurs appels d'offres, tous ceux et toutes celles là sont les bienvenu·es. Les discussions sont publiques. Le RSWG peut aussi utiliser des outils en ligne comme MicrosoftHub (RFC 8874).

Le RSAB, lui, est relativement fermé, aussi bien dans sa composition (les membres avec droit de vote sont un représentant de chaque voie plus le RFC Series Consulting Editor, cf. section 5) que dans son travail (mais les comptes-rendus des réunions sont publics). Par contre, il n'est pas censé court-circuiter le RSWG : toutes les propositions doivent d'abord être discutées au RSWG.

Les boilerplates, ces textes rigides présents au début de chaque RFC et expliquant le statut de celui-ci, décrits dans le RFC 7841, sont décidés par chaque voie puis approuvés par le RSAB, le RFC Production Center et l'IETF Trust.

Le RPC (RFC Production Center) est décrit en section 4. C'est actuellement AMS. C'est ce RPC qui va écrire et maintenir le guide stylistique à respecter (RFC 7322 et documents en ligne), décider des formats acceptés (par exemple du profil restreint de SVG, cf. RFC 9896), et préciser les points que le RFC 7991 laissait libres. C'est aussi le RPC qui doit faire le travail de publication effectif :

  • Attribuer les numéros des RFC (qui sera le numéro 10 000 ?),
  • Relire et corriger les textes soumis, en respectant le sens technique,
  • Garder trace de toutes les modifications faites (des « corrections » peuvent accidentellement changer le fond du texte),
  • Assurer la communication avec les auteurs et avec des organisations comme l'IANA, quand le futur RFC leur donne un rôle, par exemple de créer un nouveau registre de paramètres, et archiver tous ces dialogues,
  • Demander le cas échéant au RSCE et/ou au RSAB, et leur faire des suggestions, fondées sur son expérience de publication des RFC,
  • Participer au RSWG,
  • Rendre compte à la communauté des auteurs et lecteurs de RFC, d'une part, et à l'IETF LLC d'autre part,
  • Mettre les RFC en ligne, veiller au serveur www.rfc-editor.org qui les distribue, archiver les RFC (RFC 8153), annoncer les publications (le RPC est sur le fédivers, voyez par exemple cette annonce, et il y a bien sûr un flux de syndication sur le site Web),
  • Maintenir le système d'errata (« Submit an issue »),
  • Et répondre aux demandes judiciaires car il y a parfois des procès impliquant un RFC.

Le RPC est choisi suite à un appel d'offres de l'IETF LLC, qui est chargée d'écrire le cahier des charges détaillé et de sélectionner le vainqueur. L'argent vient du budget de l'IETF LLC, qui paie le RPC (AMS, actuellement, comme indiqué plus haut).

Et le RSCE (RFC Series Consulting Editor) ? La section 5 le décrit plus en détail. C'est une personne expérimentée dans les questions d'édition. Il ou elle doit guider le RPC sur les questions techniques liées à la publication (la section 4 du RFC 8729 donne une liste complète de ces questions). La RSCE actuelle, depuis 2022, est Alexis Rossi, une des auteures de ce RFC.

Une des nouveautés du RFC 9280 était la voie éditoriale (Editorial Stream), la cinquième voie de création de RFC, consacrée aux RFC qui parlent des RFC. La section 6 de notre RFC la détaille. Cette voie est empruntée par les RFC discutés par le RSWG puis approuvés par le RSAB, comme ce RFC 9920 dont vous êtes en train de lire le résumé. Le statut de ces RFC est forcément « Pour information » (informational, cf. RFC 8729), mais ce sont bien des règles impératives pour les RFC qu'ils spécifient.

Et, pour finir, la section 7 de notre RFC liste les propriétés « historiques » des RFC qui, si elles n'ont pas forcément été mises par écrit, surtout au début, ont toujours été respectées et ne doivent pas être prises à la légère lors des propositions d'évolution :

  • Libre disponibilité des documents, que tout le monde peut télécharger, lire, redistribuer. (Ce n'est pas évident, puisque des organisations fermées comme l'AFNOR ou l'ISO ne fournissent toujours pas d'accès libre à leurs documents et, même si vous avez payé pour en avoir un, vous ne pouvez pas le redistribuer.)
  • Accessibilité (format texte d'abord, puis XML avec plusieurs formats de sortie), sans dépendance vis-à-vis de logiciels privateurs comme le font les organisations fermées.
  • En anglais (notez que la licence permet de faire une traduction sans demander d'autorisation). Opinion personnelle : ce n'est évidemment pas génial mais il n'y pas d'alternative réaliste : traduire des documents normatifs en N autres langues est très coûteux (chaque virgule compte et, par exemple, un texte en français tend facilement à être plus directif que le texte en anglais).
  • Diversité : tous les RFC ne sont pas des normes, il y a des informations, des discussions, de l'humour
  • Qualité des documents.
  • Stabilité et longévité : le contenu sémantique des RFC n'est jamais modifié, et les formats sont choisis pour garantir qu'ils seront toujours lisibles dans des dizaines d'années (formats standards, acceptés par de nombreux logiciels). À part le cas particulier du RFC 20, le RFC le plus ancien et qui est toujours applicable est le RFC 768, qui a presque un demi-siècle. L'archivage à long terme est un point crucial des RFC, à la fois pour les RFC anciens mais toujours d'actualité, et aussi pour les historien·nes de l'informatique.

La section 1.1 de notre RFC résume les changements depuis le RFC 9280, qui avait spécifié la version 3 du modèle « RFC Editor ». On reste en version 3 et les changements sont peu importants :

  • Précisions des responsabilités de développement des outils informatiques nécessaires. C'est au RFC Production Center de s'en occuper. Cela implique des choses comme les choix de formats ou bien les grammaires XML.
  • Définition de la notion d'utilisateur des RFC (consumer of RFCs, section 3.3), en se référant au RFC 3935, qui décrit la mission de l'IETF mais qui n'expliquait pas clairement cette notion. Les utilisateurs des RFC sont un ensemble plus large que celui des participants à l'IETF, et un RFC doit être utilisable par des gens qui ne connaissent rien à l'IETF.
  • En cohérence avec le RFC 9720, on précise désormais qu'un RFC, une fois publié, peut être modifié (sa forme, mais pas son fond).

La section 9, quant à elle, raconte les changements qu'il y avait eu depuis la version 2 du modèle (la version 1 du modèle était dans le RFC 5620 en 2009 et la version 2 dans le RFC 6635 en 2012) :

  • Éclatement de la fonction de RFC Editor en plusieurs acteurs (RSWG, RSAB, etc).
  • Fusion des fonctions RFC Production Center et RFC Publisher.
  • Suppression du RSOC (RFC Series Oversight Commitee).
  • Création de la voie éditoriale pour les RFC parlant des RFC.

Téléchargez le RFC 9920


L'article seul

RFC 9915: Dynamic Host Configuration Protocol for IPv6 (DHCPv6)

Date de publication du RFC : Janvier 2026
Auteur(s) du RFC : T. Mrugalski (ISC), B. Volz (Individual Contributor), M. Richardson (SSW), S. Jiang (BUPT), T. Winters (QA Cafe)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dhc
Première rédaction de cet article le 11 février 2026


IPv6 dispose de trois mécanismes principaux pour l'allocation d'une adresse IP à une machine. L'allocation statique, « à la main », le système d'« autoconfiguration » SLAAC du RFC 4862 et DHCP. DHCP pour IPv6 était normalisé dans le RFC 8415, que notre RFC met à jour. Le protocole n'a guère changé, le principal changement est la suppression de certaines fonctions peu utilisées.

DHCP permet à une machine (qui n'est pas forcément un ordinateur, ou plus exactement qui n'est pas perçue comme telle) d'obtenir une adresse IP (ainsi que plusieurs autres informations de configuration) à partir d'un serveur DHCP du réseau local. C'est donc une configuration « avec état », du moins dans son mode d'utilisation le plus connu. (Notre RFC documente également un mode sans état.) DHCP nécessite un serveur, par opposition à l'autoconfiguration du RFC 4862 qui ne dépend pas d'un serveur (cette autoconfiguration sans état peut être utilisée à la place de ou bien en plus de DHCP). Deux utilisations typiques de DHCP sont le SoHo où le routeur est également serveur DHCP pour les trois PC connectés et le réseau local d'entreprise où deux ou trois machines Unix distribuent adresses IP et informations de configuration à des centaines de machines.

Le principe de base de DHCP (IPv4 ou IPv6) est simple : la nouvelle machine annonce à la cantonade qu'elle cherche une adresse IP, le serveur lui répond, l'adresse est allouée pour une certaine durée, le bail, la machine cliente devra renouveler le bail de temps en temps.

L'administrateur d'un réseau IPv6 se pose souvent la question « DHCP ou SLAAC » ? Notez que les deux peuvent coexister, ne serait-ce que parce que certaines possibilités n'existent que pour un seul des deux protocoles. Ainsi, DHCP seul ne peut indiquer l'adresse du routeur par défaut. Pour le reste, c'est une question de goût.

Le DHCP spécifié par notre RFC ne fonctionne que pour IPv6, les RFC 2131 et RFC 2132 traitant d'IPv4. Les deux protocoles restent donc complètement séparés, le RFC 4477 donnant quelques idées sur leur coexistence. Il a parfois été question de produire une description unique de DHCPv4 et DHCPv6, ajoutant ensuite les spécificités de chacun, mais le projet n'a pas eu de suite (section 1.2 de ce RFC), les deux protocoles étant trop différents.

DHCP fonctionne par diffusion restreinte. Un client DHCP, c'est-à-dire une machine qui veut obtenir une adresse, diffuse (DHCP fonctionne au-dessus d'UDP, RFC 768, le port source est 546, le port de destination, où le serveur écoute, est 547) sa demande à l'adresse multicast locale au lien ff02::1:2. Le serveur se reconnait et lui répond. S'il n'y a pas de réponse, c'est, comme dans le DNS, c'est au client de réémettre (section 15). L'adresse IP source du client est également une adresse locale au lien.

(Notez qu'une autre adresse de diffusion restreinte est réservée, ff05::1:3 ; elle inclut également tous les serveurs DHCP mais, contrairement à la précédente, elle exclut les relais, qui transmettent les requêtes DHCP d'un réseau local à un autre.)

Le serveur choisit sur quels critères il alloue les adresses IP. Il peut les distribuer de manière statique (une même machine a toujours la même adresse IP) ou bien les prendre dans un pool d'adresses et chaque client aura donc une adresse « dynamique ». Le fichier de configuration du serveur DHCP Kea ci-dessous montre un mélange des deux approches.

Il faut bien noter (et notre RFC le fait dans sa section 22) que DHCP n'offre aucune sécurité. Comme il est conçu pour servir des machines non configurées, sur lesquelles on ne souhaite pas intervenir, authentifier la communication est difficile. Un serveur DHCP pirate, ou, tout simplement, un serveur DHCP accidentellement activé, peuvent donc être très gênants.

Outre l'adresse IP, DHCP peut indiquer des options comme les adresses des serveurs DNS à utiliser (RFC 3646).

Notre version IPv6 de DHCP est assez différente de la version IPv4 (et le RFC est plus de trois fois plus long). Par exemple, l'échange « normal » entre client et serveur prend quatre paquets IP (section 5) et non pas deux. (Mais il y a aussi un échange simplifié à deux paquets, cf. section 5.1.) L'encodage des messages est très différent, et il y a des différences internes comme l'IA (Identity Association) de la section 12. Il y a aussi des différences visibles à l'utilisateur comme le concept de DUID (DHCP Unique IDentifier), section 11, qui remplace les anciens client identifier et server identifier de DHCP v4. Les différences sont telles que le RFC précise que leur intégration avec DHCP pour IPv4 n'est pas envisagée.

À l'heure actuelle, il existe plusieurs mises en œuvre de DHCPv6, comme Kea (serveur seulement) et dhcpcd (client seulement). (Notez qu'une liste complète figurait dans le brouillon du RFC.) Pour celles et ceux qui utilisent une Freebox comme serveur DHCP, il semble qu'elle ait DHCPv6 depuis 2018 (je n'ai pas testé). Il parait que la Livebox le fait également. Je n'ai pas non plus essayé pour la Turris Omnia mais cela devrait marcher puisqu'elle utilise le serveur odhcpd, qui sait faire du DHCPv6 (ceci dit, je ne vois pas comment l'activer depuis les menus de Luci). Et il y a bien sûr des implémentations non-libres dans des équipements comme les Cisco. Notez que ces mises en œuvre de DHCPv6 n'ont pas forcément déjà intégré les modifications de notre RFC 9915.

Il existe aussi des programmes qui ne sont plus maintenus comme Dibbler (client et serveur), l'ancien programme de l'ISC (le nouveau est Kea), etc.

Voici un exemple d'utilisation de Dibbler, face à Kea, qui nous affiche les quatre messages (Solicit - Advertise - Request - Reply) :


% sudo dibbler-client run 
...
2026.02.11 08:28:04 Client Notice    DUID creation: Generating 14-bytes long link-local+time (duid-llt) DUID.
2026.02.11 08:28:04 Client Notice    DUID creation: generated using wlan0/4 interface.
2026.02.11 08:28:04 Client Info      My DUID is 00:01:00:01:31:1e:fa:14:f6:fc:69:10:65:09.
...
2026.02.11 08:28:04 Client Info      Creating SOLICIT message with 1 IA(s), no TA and 0 PD(s) on eth1/3 interface.
2026.02.11 08:28:04 Client Debug     Sending SOLICIT(opts:1 3 39 8 6 ) on eth1/3 to multicast.
2026.02.11 08:28:04 Client Info      Received ADVERTISE on eth1/3,trans-id=0x5ded1b, 5 opts: 1 2 3 23 39
2026.02.11 08:28:05 Client Info      Processing msg (SOLICIT,transID=0x5ded1b,opts: 1 3 39 8 6)
2026.02.11 08:28:05 Client Info      Creating REQUEST. Backup server list contains 1 server(s).
2026.02.11 08:28:05 Client Debug     Advertise from Server ID=00:01:00:01:31:19:db:68:38:f7:cd:ce:22:c6, preference=0.[using this]
2026.02.11 08:28:05 Client Debug     Sending REQUEST(opts:1 3 39 6 2 8 ) on eth1/3 to multicast.
2026.02.11 08:28:05 Client Info      Received REPLY on eth1/3,trans-id=0x6eb008, 5 opts: 1 2 3 23 39
2026.02.11 08:28:05 Client Notice    Address fc00:cafe:1234:4321:5678::2/128 added to eth1/3 interface.
2026.02.11 08:28:05 Client Debug     RENEW(IA_NA) will be sent (T1) after 1000, REBIND (T2) after 2000 seconds.
2026.02.11 08:28:08 Client Notice    FQDN: About to perform DNS Update: DNS server=2001:db8:2::dead:beef, IP=fc00:cafe:1234:4321:5678::2 and FQDN=grace
...

   

Le serveur en face était un Kea ainsi configuré :

"subnet6": [
        {
           "interface": "eth0",  // Ce n'est pas bien documenté mais
	   // cette option est cruciale, autrement le client reçoit
	   // des « Server could not select subnet for this client ».
           "subnet": "fc00:cafe:1234:4321::/64",
           "pools": [ { "pool": "fc00:cafe:1234:4321:5678::/80" } ],
...

Si vous voulez, le pcap de l'échange est disponible (capture faite avec tcpdump -w /tmp/dhcpv6-bis.pcap udp and \(port 546 or port 547\)). tcpdump voit le trafic ainsi :

09:28:04.624687 IP6 fe80::606d:ad11:58ca:6cab.546 > ff02::1:2.547: dhcp6 solicit
09:28:04.639479 IP6 fe80::6ee4:5672:da95:1018.547 > fe80::606d:ad11:58ca:6cab.546: dhcp6 advertise
09:28:05.652900 IP6 fe80::606d:ad11:58ca:6cab.546 > ff02::1:2.547: dhcp6 request
09:28:05.667843 IP6 fe80::6ee4:5672:da95:1018.547 > fe80::606d:ad11:58ca:6cab.546: dhcp6 reply
   

La requête est émise depuis une adresse lien-local (ici fe80::606d:ad11:58ca:6cab) pas depuis une adresse « tout zéro » comme en IPv4 (section 17 du RFC). On voit bien les quatre messages (Solicit - Advertise - Request - Reply), décrits section 5.2 (et la liste des types possibles est en section 7.3). Le serveur n'a pas répondu directement avec un Reply, parce que le client n'a pas inclut l'option Rapid Commit (section 21.14). Dans l'échange à quatre messages, le client demande à tous (Solicit), un(s) serveur(s) DHCP répond(ent) (Advertise), le client envoie alors sa requête au serveur choisi (Request), le serveur donne (ou pas) son accord (Reply). Avec l'option -vvv, tcpdump est plus bavard et montre qu'il analyse bien DHCPv6 :

09:28:04.624687 IP6 (flowlabel 0x51d28, hlim 1, next-header UDP (17) payload length: 99) fe80::606d:ad11:58ca:6cab.546 > ff02::1:2.547: [udp sum ok] dhcp6 solicit (xid=5ded1b (client-ID hwaddr/time type 1 time 824113684 f6fc69106509) (IA_NA IAID:1 T1:4294967295 T2:4294967295 (IA_ADDR :: pltime:4294967295 vltime:4294967295)) (Client-FQDN) (elapsed-time 0) (option-request DNS-server Client-FQDN))
09:28:04.639479 IP6 (flowlabel 0xf6846, hlim 64, next-header UDP (17) payload length: 140) fe80::6ee4:5672:da95:1018.547 > fe80::606d:ad11:58ca:6cab.546: [udp sum ok] dhcp6 advertise (xid=5ded1b (client-ID hwaddr/time type 1 time 824113684 f6fc69106509) (server-ID hwaddr/time type 1 time 823778152 38f7cdce22c6) (IA_NA IAID:1 T1:1000 T2:2000 (IA_ADDR fc00:cafe:1234:4321:5678::2 pltime:3000 vltime:4000)) (DNS-server 2001:db8:2::dead:beef 2001:db8:2::cafe:babe) (Client-FQDN))
09:28:05.652900 IP6 (flowlabel 0x51d28, hlim 1, next-header UDP (17) payload length: 117) fe80::606d:ad11:58ca:6cab.546 > ff02::1:2.547: [udp sum ok] dhcp6 request (xid=6eb008 (client-ID hwaddr/time type 1 time 824113684 f6fc69106509) (IA_NA IAID:1 T1:4294967295 T2:4294967295 (IA_ADDR fc00:cafe:1234:4321:5678::2 pltime:3000 vltime:4000)) (Client-FQDN) (option-request DNS-server Client-FQDN) (server-ID hwaddr/time type 1 time 823778152 38f7cdce22c6) (elapsed-time 0))
09:28:05.667843 IP6 (flowlabel 0xf6846, hlim 64, next-header UDP (17) payload length: 140) fe80::6ee4:5672:da95:1018.547 > fe80::606d:ad11:58ca:6cab.546: [udp sum ok] dhcp6 reply (xid=6eb008 (client-ID hwaddr/time type 1 time 824113684 f6fc69106509) (server-ID hwaddr/time type 1 time 823778152 38f7cdce22c6) (IA_NA IAID:1 T1:1000 T2:2000 (IA_ADDR fc00:cafe:1234:4321:5678::2 pltime:3000 vltime:4000)) (DNS-server 2001:db8:2::dead:beef 2001:db8:2::cafe:babe) (Client-FQDN))
   

Mais si vous préférez tshark, l'analyse de cet échange est également disponible.

Notez que certains clients DHCP dépendent de la présence d'un routeur qui envoie des RA (RFC 4861) avec le bit M - Managed - à 1 (RFC 4861, section 4.2). En l'absence de ces annonces, le client se contente de demander des informations diverses au serveur DHCP, mais pas d'adresse IP.

Et si vous voulez compiler dhcpcd vous-même, c'est simple :

wget https://github.com/NetworkConfiguration/dhcpcd/releases/download/v10.3.0/dhcpcd-10.3.0.tar.xz
dhcpcd-10.3.0.tar.xz 
tar xvf dhcpcd-10.3.0.tar 
dhcpcd-10.3.0
./configure
make
sudo make install
 

L'échange à deux messages (Solicit - Reply) est, lui, spécifié dans la section 5.1. Il s'utilise si le client n'a pas besoin d'une adresse IP, juste d'autres informations de configuration comme l'adresse du serveur NTP, comme décrit dans le RFC 4075. Même si le client demande une adresse IP, il est possible d'utiliser l'échange à deux messages, via la procédure rapide avec l'option Rapid Commit.

Tout client ou serveur DHCP v6 a un DUID (DHCP Unique Identifier, décrit en section 11). Le DUID est opaque et ne devrait pas être analysé par la machine qui le reçoit. La seule opération admise est de tester si deux DUID sont égaux (indiquant qu'en face, c'est la même machine). Il existe plusieurs façons de générer un DUID (dans l'exemple plus haut, Dibbler avait choisi la méthode duid-llt, adresse locale et heure) et de nouvelles pourront apparaitre dans le futur. Par exemple, un DUID peut être fabriqué à partir d'un UUID (RFC 6355).

Mais l'utilisation exclusive du DUID, au détriment de l'adresse MAC, n'est pas une obligation du RFC (le RFC, section 11, dit juste « DHCP servers use DUIDs to identify clients for the selection of configuration parameters », ce qui n'interdit pas d'autres méthodes). On peut utiliser l'adresse Ethernet. En combinaison avec des commutateurs qui filtrent sur l'adresse MAC, cela peut améliorer la sécurité.

Puisqu'on peut aussi attribuer des adresses statiquement à une machine, en la reconnaissant, par exemple, à son adresse MAC ou à son DUID, voici comment on peut configurer Kea pour donner une adresse IP fixe au client d'un certain DUID :

"reservations": [
  {
    "duid": "00:01:00:01:31:1e:fa:14:f6:fc:69:10:65:09",
    "ip-addresses": [ "fc00:cafe:1234:4321:b0f:1111::1" ]
  }
   

La section 6 de notre RFC décrit les différentes façons d'utiliser DHCPv6. On peut se servir de DHCPv6 en mode sans état (section 6.1), lorsqu'on veut juste des informations de configuration, ou avec état (section 6.2, qui décrit la façon historique d'utiliser DHCP), lorsqu'on veut réserver une ressource (typiquement l'adresse IP) et qu'il faut alors que le serveur enregistre (et pas juste dans sa mémoire, car il peut redémarrer) ce qui a été réservé. On peut aussi faire quelque chose qui n'a pas d'équivalent en IPv4, se faire déléguer un préfixe d'adresses IP entier (section 6.3). Un client DHCP qui reçoit un préfixe, mettons, /60, peut ensuite redéléguer des bouts, par exemple ici des /64. (Le RFC 7084 est une utile lecture au sujet des routeurs installés chez M. Toutlemonde.)

Le format détaillé des messages est dans la section 8. Le début des messages est toujours le même, un type d'un octet (la liste des types est en section 7.3) suivi d'un identificateur de transaction de trois octets. Le reste est variable, dépendant du type de message.

On a déjà parlé du concept de DUID plus haut, donc sautons la section 11 du RFC, qui parle du DUID, et allons directement à la section 12, qui parle d'IA (Identity Association). Une IA est composée d'un identifiant numérique, l'IAID (IA IDentifier) et d'un ensemble d'adresses et de préfixes. Le but du concept d'IA est de permettre de gérer collectivement un groupe de ressources (adresses et préfixes). Pour beaucoup de clients, le concept n'est pas nécessaire, on n'a qu'une IA, d'identificateur égal à zéro. Pour les clients plus compliqués, on a plusieurs IA, et les messages DHCP (par exemple d'abandon d'un bail) indiquent l'IA concernée.

Comme pour DHCPv4, une bonne partie des informations est transportée dans des options, décrites dans la section 21. Certaines options sont dans ce RFC, d'autres pourront apparaitre dans des RFC ultérieurs. Toutes les options commencent par deux champs communs, le code identifiant l'option (deux octets), et la longueur de l'option. Ces champs sont suivis par des données, spécifiques à l'option. Ainsi, l'option Client Identifier a le code 1, et les données sont un DUID (cf. section 11). Autre exemple, l'option Vendor Class (code 16) permet d'indiquer le fournisseur du logiciel client (notez qu'elle pose des problèmes de sécurité, cf. RFC 7824, et section 23 de notre RFC). Notez qu'il peut y avoir des options dans les options, ainsi, l'adresse IP (code 5) est toujours dans les données d'une option IA (les IA sont décrites en section 12).

Puisqu'on a parlé de sécurité, la section 22 du RFC détaille les questions de sécurité liées à DHCP. Le fond du problème est qu'il y a une profonde incompatibilité entre le désir d'une autoconfiguration simple des clients (le but principal de DHCP) et la sécurité. DHCP n'a pas de chiffrement et tout le monde peut donc écouter les échanges de messages, voire les modifier. Et, de toute façon, le serveur n'est pas authentifié, donc le client ne sait jamais s'il parle au serveur légitime. Il est trivial pour un méchant de configurer un serveur DHCP « pirate » et de répondre à la place du vrai, indiquant par exemple un serveur DNS que le pirate contrôle. Les RFC 7610 et RFC 7513 décrivent des solutions possibles à ce problème.

Des attaques par déni de service sont également possibles, par exemple via un client méchant qui demande des ressources (comme des adresses IP) en quantité. Un serveur prudent peut donc limiter la quantité de ressources accessible à un client.

Maintenant, les questions de vie privée. La section 23 rappelle que DHCP est très indiscret. Le RFC 7824 décrit les risques que DHCP fait courir à la vie privée du client (et le RFC 7844 des solutions possibles).

Les registres IANA ne changent pas par rapport à l'ancien RFC. Les différents paramètres sont en ligne.

L'annexe A de notre RFC décrit les changements depuis l'ancien RFC 8415. Rien d'essentiel n'a été changé. On notera :

  • Suppression de certains mécanismes optionnels (comme ils étaient de toute façon optionnels, cela n'affecte pas l'interopérabilité) qui étaient complexes et peu mis en œuvre : les adresses temporaires (IA_TA), il faut désormais relâcher explicitement celles qu'on veut temporaires, la possibilité de faire de l'unicast, et donc, logiquement, l'option qui forçait le multicast.
  • Correction de plusieurs erreurs signalées (certaines n'ont pas été corrigées puisqu'elles s'appliquaient à des options supprimées).
  • Texte plus précis sur les ports UDP utilisés.
  • Progression du RFC au statut de norme Internet complète (alors que le RFC 8415 était officiellement une proposition de norme).

Téléchargez le RFC 9915


L'article seul

RFC 9910: Registration Data Access Protocol (RDAP) Regional Internet Registry (RIR) Search

Date de publication du RFC : Janvier 2026
Auteur(s) du RFC : T. Harrison (APNIC), J. Singh (ARIN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 8 janvier 2026


Le protocole RDAP, successeur de whois, n'est pas utilisé que par les registres de noms de domaine. Il sert aussi chez les RIR, pour obtenir des informations sur les entités qui sont derrière une adresse IP (ou un AS). RDAP dispose dès le début de fonctions de recherche (regardez le RFC 9082) mais ce nouveau RFC ajoute des choses en plus.

Traditionnellement, les serveurs whois des RIR disposaient de fonction de recherche « avancées » comme la possibilité de chercher par valeur (« quels sont tous les préfixes IP de tel titulaire ? »). L'idée de ce RFC est de permettre la même chose en RDAP. RDAP de base permet les recherches des informations associées à une adresse IP :

% curl -s https://rdap.db.ripe.net/ip/2001:41d0:302:2200::180 | jq . 
{
  "handle": "2001:41d0::/32",
  "name": "FR-OVH-20041115",
  "country": "FR",
  "parentHandle": "2001:4000::/23",
  …
  "status": [
    "active"
  ],
  "entities": [
    {
      "handle": "OK217-RIPE",
      …
            "text",
            "Octave Klaba"
      …
  

En plus de ip, ce RFC ajoute ips (section 2.1) qui permet une recherche sur tous les préfixes dont le nom correspond à un certain motif (ici, tous ceux d'OVH) :

% curl -s https://rdap.db.ripe.net/ips\?name="FR-OVH-*" | jq '.ipSearchResults.[].handle'
"109.190.0.0 - 109.190.255.255"
"135.125.0.0 - 135.125.255.255"
"137.74.0.0 - 137.74.255.255"
"141.94.0.0 - 141.95.255.255"
"145.239.0.0 - 145.239.255.255"
"147.135.128.0 - 147.135.255.255"
"149.202.0.0 - 149.202.255.255"
"152.228.128.0 - 152.228.255.255"
"159.173.0.0 - 159.173.255.255"
"162.19.0.0 - 162.19.255.255"
…
  

J'ai utilisé ici curl et jq mais, évidemment, l'avantage de RDAP est que vous pouvez utiliser un client dédié ou bien n'importe quel logiciel qui sait faire du HTTP et du JSON (voyez plus loin un exemple en Python).

Et chez un autre RIR :

% curl -s https://rdap.arin.net/registry/ips\?name='CLOUDFLARE*' | \
       jq '.ipSearchResults.[].handle'
"NET-104-16-0-0-1"
"NET-108-162-192-0-1"
"NET-156-146-101-152-1"
"NET-162-158-0-0-1"
"NET-172-64-0-0-1"
"NET-173-245-48-0-1"
"NET-198-41-128-0-1"
"NET-199-27-128-0-1"
"NET6-2606-4700-1"
  

De la même façon, vous pouvez chercher par numéro d'AS :

% curl -s https://rdap.db.ripe.net/autnums\?name="*NIC-FR*" | \
          jq '.autnumSearchResults.[].handle'
"AS2483"
"AS2484"
"AS2485"
"AS2486"
  

La section 3 décrit ensuite des moyens de trouver les objets parents et enfants (puisque l'allocation des adresses IP est hiérarchique, toute adresse est dans un préfixe plus général et contient des préfixes plus spécifiques, cf. la section 3.2.1 du RFC) :

% curl -s https://rdap.db.ripe.net/ips/rirSearch1/rdap-up/2001:41d0:302:2200::180 | \
       jq '.handle'                   
"2001:41d0::/32"
  
% curl -s https://rdap.db.ripe.net/ips/rirSearch1/rdap-down/2001:4000::/23 | \
          jq '.ipSearchResults.[].handle'
"2001:4000::/32"
"2001:4010::/32"
"2001:4018::/29"
"2001:4020::/32"
…
  

Notez la relation (rdap-up et rdap-down). Notez aussi que rdap-up renvoie au maximum un objet alors que rdap-down peut en renvoyer plusieurs (cf. section 4.2), et c'est pour cela qu'il a fallu itérer en jq (le .[] parcourt le tableau). Quant au rirSearch1, le 1 indique la version de cette extension de recherche chez les RIR (désormais enregistrée à l'IANA).

Et en Python, ça donnerait :

#!/usr/bin/python

# Example of using search extensions to RDAP (RFC 9910)

# https://requests.readthedocs.io
import requests

# Standard library
import json
import sys

# Yes, we should use the registry documented in RFC 7484…
BASE_URL = "https://rdap.db.ripe.net/ips/rirSearch1/rdap-down"

if len(sys.argv) != 2:
    raise Exception("Usage: %s ip-prefix-at-ripe" % sys.argv[0])
arg = sys.argv[1]

response = requests.get("%s/%s" % (BASE_URL, arg))
if response.status_code != 200:
    raise Exception("Wrong HTTP return code from %s: %s" % (BASE_URL, response.status_code))
data = json.loads(response.text)
for prefix in data["ipSearchResults"]:
    print(prefix["handle"])
  

Et les recherches inverses, telles que décrites dans le RFC 9536 ? La section 5 du RFC les présente et voici un exemple qui marche (trouver tous les préfixes de Webflow) :

% curl -s 'https://rdap.arin.net/registry/ips/reverse_search/entity?handle=WEBFL' | \
            jq '.ipSearchResults.[].handle'
"NET-198-202-211-0-1"
"NET6-2620-CB-2000-1"
  

Un serveur RDAP qui gère les extensions de ce RFC doit le signaler dans ses réponses (section 6) :

…    
"rdapConformance" : [ "geofeed1", "rirSearch1", "ips", "cidr0",
       "rdap_level_0", "nro_rdap_profile_0", "redacted" ],
…
  

Mais aussi dans les liens donnés dans les réponses (ici, en réponse à une requête traditionnelle ip) :

  "links": [
    {
      "value": "https://rdap.db.ripe.net/ip/2001:41d0:302:2200::180",
      "rel": "rdap-up",
      "href": "https://rdap.db.ripe.net/ips/rirSearch1/rdap-up/2001:41d0::/32",
      "type": "application/rdap+json"
    },
  

Et bien sûr dans les réponses d'aide :

% curl -s https://rdap.arin.net/registry/help 
{
  "rdapConformance" : [ "nro_rdap_profile_0", "rdap_level_0", "cidr0", "nro_rdap_profile_asn_flat_0", "arin_originas0", "rirSearch1", "ips", "ipSearchResults", "autnums", "autnumSearchResults", "reverse_search" ],
  "notices" : [ {
    "title" : "Terms of Service",
    "description" : [ "By using the ARIN RDAP/Whois service, you are agreeing to the RDAP/Whois Terms of Use" ],
    "links" : [ {
      "value" : "https://rdap.arin.net/registry/help",
      "rel" : "terms-of-service",
      "type" : "text/html",
      "href" : "https://www.arin.net/resources/registry/whois/tou/"
    } ]
…
  

Les fonctions de recherche, c'est très bien mais c'est, par construction, indiscret. La section 8 de notre RFC détaille les risques de ces extensions de recherche pour la vie privée (relire le RFC 7481 est une bonne idée).

Les extensions de ce RFC, rirSearch1, ips, autnums, ipSearchResults et autnumSearchResults ont été enregistrées à l'IANA (section 10 du RFC). Les relations rdap-up, rdap-down, rdap-top et rdap-bottom sont dans le registre des liens (RFC 8288). Et le registre des recherches inverses inclut désormais fn, handle, email et role, avec leur correspondance en JSONPath.

Et question mise en œuvre et déploiement, on a quoi ? ARIN et RIPE ont annoncé avoir programmé les extensions de ce RFC mais elles ne sont pas forcément accessibles via le serveur RDAP public, entre autre pour les raisons de vie privée discutées dans la section 8. Aujourd'hui, comme vous le voyez dans les exemples ci-dessus, au moins ARIN et RIPE rendent une partie de ces extensions utilisables.


Téléchargez le RFC 9910


L'article seul

RFC 9896: SVG in RFCs

Date de publication du RFC : Janvier 2026
Auteur(s) du RFC : A. Rossi (RFC Series Consulting Editor), N. Brownlee, J. Mahoney (RFC Production Center), M. Thomson
Pour information
Réalisé dans le cadre de l'activité d'édition des RFC rswg
Première rédaction de cet article le 5 février 2026


Le RFC 7996 avait introduit la possibilité de mettre des images dans les RFC. Ce nouveau document le remplace, il décrit les règles pour inclure du SVG. Il est très court, se limitant aux principes, il n'a plus de mention d'un profil SVG particulier.

On peut donc mettre des images vectorielles car, a priori, dans un RFC, il y aura beaucoup plus de schémas que de photos. Donc, pas de bitmap.

Au fait, c'est quoi, SVG ? Il s'agit d'une norme d'un format d'images vectoriel, gérée par le W3C, et fondée sur XML. Voici un exemple d'un simple dessin en SVG :


<svg xmlns="http://www.w3.org/2000/svg" version="1.2">
  <rect x="25" y="25" width="200" height="200" fill="white" stroke-width="4" stroke="black" />
  <circle cx="125" cy="125" r="75" fill="black" />
  <polyline points="50,150 50,200 200,200 200,100" stroke="black" stroke-width="4" fill="none" />
  <line x1="50" y1="50" x2="200" y2="200" stroke="white" stroke-width="4" />
</svg>

  

Et voici son rendu : simple-rfc-picture

Ce RFC décrit des objectifs, une politique. Contrairement à son prédécesseur, le RFC 7996, il ne décrit pas de profil de SVG, il fixe des buts, pas les moyens de les atteindre. Ces buts sont :

  • Le schéma en SVG ne doit jamais être la seule représentation. Le RFC doit être compréhensible sans les schémas.
  • Le SVG ne doit pas inclure d'animations et ne doit pas être trop réactif (pas question de changer quand on tourne le téléphone).
  • Le but étant d'être vu et compris par le public le plus large possible, il ne faut pas utiliser les fonctions de SVG qui ne sont pas largement mises en œuvre. Pas de pointeurs vers des ressources externes, pas de script exécutable (pas de JavaScript actif dans un RFC…), attention portée à l'accessibilité, en suivant WAI. Pour la même raison, il ne faut pas de dépendance vis-à-vis des couleurs (RFC 6949, section 3.2) et pas de choix arbitraire de police.

Il est crucial que les RFC soient accessibles à tou·te·s, non seulement quel que soit le matériel utilisé, mais également quels que soient les handicaps dont souffre leur propriétaire. C'est bien joli de vouloir ajouter des tas de choses dans les RFC mais encore faut-il ne pas creuser ainsi davantage le fossé entre les utilisateurs. Ainsi, accepter de la couleur (le RFC 6949 limite les futurs RFC au noir et blanc) fait courir le risque que les daltoniens ne puissent pas comprendre un RFC. De même, les graphiques, qui ont l'air comme ça d'être une bonne idée, peuvent aggraver la situation des malvoyants. Le texte seul peut toujours être lu à voix haute par un synthétiseur de parole mais pas le graphique.

La traduction de ces principes en conseils techniques concrets, et l'application de ces règles seront du ressort du RFC Production Center. Il suivra peut-être les nombreux détails pratiques décrits dans le RFC 7996 mais il n'y est pas obligé.

Comment on écrit du SVG ? S'il est évidemment possible de le faire entièrement à la main avec un éditeur ordinaire, gageons que peu de gens le tenteront. Le RFC 7996 citait des éditeurs graphiques, produisant du SVG, comme les logiciels libres Inkscape et Dia. (Et, si on aime programmer en Python, il y a svgwrite, que je présente plus en détail à la fin.) Attention, Inkscape et Dia produisent du SVG généraliste, qui peut inclure des fonctions de SVG qui ne suivent pas les principes de notre RFC.

Autre solution, utiliser la bibliothèque Fletcher de Typst :

% typst compile --format svg essai-fletcher.typ
  

Le texte « Tips for Creating Accessible SVG » donne des bons conseils pour faire du SVG accessible. Et il y a bien sûr la norme ARIA, dont il existe une introduction et de bons exemples. (Désolé, je n'ai pas suivi ces excellents principes dans les exemples ci-dessous, mais j'accepte les patches.)

Avec Inkscape, il faut veiller à sauver le fichier en Plain SVG (autrement, on a des ennuis avec les éléments spécifiques d'Inkscape, ex-Sodipodi). Mais il reste malgré cela deux ou trois trucs à corriger manuellement, avant que le document produit par Inkscape soit accepté. Pour Dia, il faut utiliser l'action Export (par défaut, Dia n'enregistre pas en SVG), mais Dia produit alors un document avec une DTD. Si on la retire (manuellement, ou bien avec xmllint --dropdtd), tout se passe bien.

Si vous voulez voir des exemples concrets de RFC utilisant SVG, vous avez entre beaucoup d'autres, le RFC 8899, le RFC 9869 ou encore le RFC 9750. Ainsi, le RFC 8899 inclut un schéma qui a deux formes alternatives, en art ASCII :


<artwork type="ascii-art" name="" alt="" align="left" pn="section-4.4-2.1.2">
Any additional
  headers         .--- MPS -----.
         |        |             |
         v        v             v
  +------------------------------+
  | IP | ** | PL | protocol data |
  +------------------------------+

             &lt;----- PLPMTU -----&gt;
  &lt;---------- PMTU --------------&gt;
</artwork>

  

Et en SVG, que vous pouvez admirer dans le rendu HTML du RFC et son rendu en PDF.

Une alternative, pour tester les SVG est svgcheck. Ici avec le vrai source du RFC 9750 :

% svgcheck rfc9750.xml  
INFO: File conforms to SVG requirements.
  

Et si je tente de mettre des couleurs vives en modifiant le XML :

% svgcheck rfc9750.xml      
rfc9750.xml:438: The attribute 'stroke' does not allow the value 'red', replaced with 'black'
ERROR: File does not conform to SVG requirements
  

Autre solution que j'aime bien pour faire du SVG, dès qu'on a des éléments répétitifs et qu'on veut donc automatiser (en Python), svgwrite. Ce schéma en art ASCII :

 +--------------+				     +----------------+
 |  Alice       |------------------------------------|      Bob	      |
 | 2001:db8::1  |                                    |   2001:db8::2  |
 +--------------+				     +----------------+

aurait pu être créé avec svgwrite avec network-schema-svgwrite.py, qui donne network-schema-svgwrite

Bien sûr, pour un schéma aussi simple, le gain n'est pas évident, mais il le devient pour les schémas comportant beaucoup d'éléments récurrents. Mais notez que svgwrite, par défaut, peut donc produire des SVG non conformes aux règles du RFC (par exemple avec de la couleur). Le programmeur doit donc faire attention.


Téléchargez le RFC 9896


L'article seul

RFC 9881: Internet X.509 Public Key Infrastructure -- Algorithm Identifiers for the Module-Lattice-Based Digital Signature Algorithm (ML-DSA)

Date de publication du RFC : Octobre 2025
Auteur(s) du RFC : J. Massimo, P. Kampanakis (AWS), S. Turner (sn3rd), B. E. Westerbaan (Cloudflare)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lamps
Première rédaction de cet article le 18 février 2026


Vous reprendrez bien un peu de post-quantique ? Ce RFC normalise l'utilisation de signatures ML-DSA dans les certificats X.509.

ML-DSA est un des premiers gagnants du concours du NIST (il se nommait Dilithium à l'époque). Il est normalisé dans FIPS-204. Il utilise les réseaux euclidiens. C'est un algorithme de signature et il a donc toute sa place dans les certificats X.509, aux côtés des plus classiques RSA et ECDSA. Petit rappel de cryptographie post-quantique au passage : contrairement à RSA, ML-DSA ne sait faire que les signatures, pas l'échange de clés. Vous pouvez donc mettre des clés publiques ML-DSA dans un certificat, le signer avec ML-DSA mais, pour un protocole comme TLS, il faudra utiliser autre chose pour l'échange de clés (par exemple ML-KEM, autre vainqueur du concours NIST).

Mettre du post-quantique dans les certificats était moins urgent que dans l'échange de clés : ici, pas de risque qu'un attaquant prévoyant stocke des communications chiffrées, en attendant d'avoir un calculateur quantique pour les décrypter. Avec TLS, le risque est nul car la signature est au moment de la connexion, les calculateurs quantiques ne pourront usurper que les communications futures. Mais, bon, les certificats sont utilisés pour autre chose que TLS, et, comme il faut se préparer à un lent déploiement, il vaut mieux s'y prendre tout de suite.

Notez aussi qu'il n'y a pas que les certificats qui sont signés, les CRL le sont aussi, et ce RFC s'applique aussi à ces listes.

Des deux variantes normalisées dans FIPS-204, « pure » et « HashML-DSA », seule la première est utilisée dans notre RFC, pour les raisons qu'explique la section 8.3.

Le RFC utilise trois niveaux de sécurité différents, et les identificateurs pour les trois niveaux sont id-ml-dsa-44 (OID 2.16.840.1.101.3.4.3.17), id-ml-dsa-65 (OID 2.16.840.1.101.3.4.3.18) et id-ml-dsa-87 (OID 2.16.840.1.101.3.4.3.19). (Ces OID sont enregistrés par le NIST.) D'autre part, l'IANA a enregistré l'identificateur id-mod-x509-ml-dsa-2025 (OID 1.3.6.1.5.5.7.0.119) pour le module ML-DSA (annexe A).

Un certificat X.509 contient des indications sur les utilisations permises (section 4.2.1.3 du RFC 5280). Comme ML-DSA sait faire des signatures mais pas des échanges de clés, un certificat avec ML-DSA aura les utilisations de signature, comme keyCertSign mais pas celles d'échange de clés comme keyEncipherment.

Le format de la clé privée (section 6) a été un des sujets de discussions chauds à l'IETF (et chez les implémenteurs). Dans la norme FIPS-204, on peut définir une clé privée de deux façons, une optimisée (section 4 de la norme) où on ne stocke que la graine (notée ξ) ou bien une forme longue avec la graine, les éléments de la clé secrète, etc. On peut déduire la clé de la graine (section 6.1 de la norme), mais pas l'inverse donc si vous ne gardez pas la graine, vous pourrez toujours signer mais pas retrouver la graine. Le RFC permet de stocker la clé privée de trois façons, la graine seule (la méthode recommandée, cf. section 8.1), la clé seule (déconseillé) ou les deux (voir un exemple plus loin).

Je n'ai pas trouvé de certificat utilisant ML-DSA dans la nature. crt.sh ne permet pas de chercher par algorithme, même dans ses fonctions avancées. Il faudrait écrire son propre client d'examen des journaux Certificate Transparency (RFC 9162) et j'avais la flemme. Donc, on va utiliser OpenSSL 3.5 pour fabriquer des certificats (je n'ai pas testé pour voir s'ils étaient parfaitement conformes au RFC…).

% openssl req -new -newkey mldsa44 -keyout mldsa.key -out mldsa.csr -nodes -subj "/CN=test"
% openssl x509 -in mldsa.csr -out mldsa.crt -req -signkey mldsa.key -days 2001 
Certificate request self-signature ok
subject=CN=test
  

Et hop, nous voilà avec un beau certificat :

% openssl x509 -text -in mldsa.crt 
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            54:5b:c0:5d:0e:85:83:43:90:77:93:4f:53:83:e1:38:a2:12:9f:61
        Signature Algorithm: ML-DSA-44
        Issuer: CN=test
        Validity
            Not Before: Feb 17 15:01:53 2026 GMT
            Not After : Aug 11 15:01:53 2031 GMT
        Subject: CN=test
        Subject Public Key Info:
            Public Key Algorithm: ML-DSA-44
                ML-DSA-44 Public-Key:
                pub:
                    15:10:02:cc:d6:ec:53:12:bb:6d:34:23:82:65:ec:
                    …
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                6E:F9:AD:56:9C:AA:60:EF:ED:B7:A1:7B:70:F6:71:55:74:B8:68:B9
    Signature Algorithm: ML-DSA-44
…
  

Autre solution, de plus bas niveau, en découpant les étapes :

# Créer la clé privée
openssl genpkey -algorithm ML-DSA-44 -out private.pem

# Extraire la clé publique (mais on ne s'en servira pas ici)
openssl pkey -in private.pem -pubout -out public.pem

# Créer la demande de signature du certificat
openssl req -new -subj /CN=Test -key private.pem -out cert.csr

# (Auto-)Signer
openssl x509 -req -in cert.csr -signkey private.pem -out cert.pem
Certificate request self-signature ok
subject=CN=Test

# Vérifier
openssl x509 -text -in cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            7c:65:cb:17:5b:ed:ee:08:c9:1a:6b:a5:97:da:ac:b8:0e:6e:df:cd
        Signature Algorithm: ML-DSA-44
        Issuer: CN=Test
        Validity
            Not Before: Feb 18 13:24:05 2026 GMT
            Not After : Mar 20 13:24:05 2026 GMT
        Subject: CN=Test
        Subject Public Key Info:
            Public Key Algorithm: ML-DSA-44
                ML-DSA-44 Public-Key:
   …
   Signature Algorithm: ML-DSA-44
…

Et si vous voulez utiliser des extensions comme la restriction d'utilisation du certificat (ici, on se limite à la signature), remplacez la demande de signature et la signature par :

openssl req -new -subj /CN=Test -key private.pem -out cert.csr -addext "keyUsage=digitalSignature"
openssl x509 -req -in cert.csr -signkey private.pem -out cert.pem  -copy_extensions copy
  

Si vous voulez regarder ce qu'il y a dans la clé privée :

%  openssl pkey -text -in private.pem  
…
ML-DSA-44 Private-Key:
seed:
    48:c8:e4:e3:63:16:c0:e4:57:da:22:31:94:36:98:
    ..
priv:
    d9:0b:5b:8d:18:4f:61:8d:c0:8f:85:6c:97:28:46:
    …
  

Vous voyez que sont stockées graine et clé (et la clé publique, plus loin).

Pour wolfSSL, vous pouvez regarder ici.

Pour des « vrais » certificats, notez que Digicert en fait apparemment, ainsi que l'AC pour usage privé d'AWS. Vous connaissez d'autres AC qui permettraient ML-DSA ?

Sinon, l'annexe C du RFC comprend de nombreux exemples de clés et de signatures.


Téléchargez le RFC 9881


L'article seul

RFC 9874: Best Practices for Deletion of Domain and Host Objects in the Extensible Provisioning Protocol (EPP)

Date de publication du RFC : Septembre 2025
Auteur(s) du RFC : S. Hollenbeck (Verisign Labs), W. Carroll (Verisign), G. Akiwate (Stanford University)
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 5 octobre 2025


Dans un registre de noms de domaine, il existe une classe d'objets pour les domaines et parfois une pour les serveurs de noms (hosts). C'est en se basant sur les objets de ces classes que des informations sont ensuite publiées dans le DNS. Que se passe-t-il si on retire un objet de ces classes, alors que d'autres objets en dépendaient ? Va-t-on scier une branche sur laquelle quelqu'un est assis ? Ce RFC fait le point sur les solutions existantes, notant que certaines sont moins bonnes que d'autres, notamment pour la sécurité.

Prenons un exemple simple : le domaine monbeaudomaine.example est enregistré auprès du registre du TLD .example. Ses serveurs de noms sont ns1.domaine-d-un-copain.example et ns1.hébergeur.example et on va supposer que le registre de .example traite les serveurs de noms comme une classe distincte dans sa base de données. Maintenant, supposons que le domaine domaine-d-un-copain.example soit supprimé parce que son titulaire n'en voit plus l'utilité. Que va devenir le serveur de noms ns1.domaine-d-un-copain.example ? Il existe de nombreuses façons de traiter ce problème, et c'est le rôle de ce RFC de les analyser toutes.

Ainsi, la section 3.2.2 du RFC 5731 dit que ce n'est pas bien de détruire un domaine si des objets de type serveur de noms sont sous ce domaine. Dans l'exemple précédent, le registre de .example aurait refusé la suppression de domaine-d-un-copain.example. Mais cela laisse le problème entier : si le titulaire ne veut plus payer et donc veut supprimer le domaine, que faire ?

Un cas similaire se produit si on veut supprimer un serveur de noms. Si le client EPP demande au serveur EPP du registre de .example la suppression de l'objet ns1.domaine-d-un-copain.example, que doit faire le registre, sachant que ce serveur de noms est utilisé par monbeaudomaine.example ? La section 3.2.2 du RFC 5732 dit que le registre devrait refuser la suppression. C'est d'autant plus gênant que, dans le modèle RRR (Registrant-Registrar-Registry), domaine et serveur(s) peuvent être gérés par des BE différents, n'ayant pas le droit de toucher aux objets des autres BE.

Vous pouvez trouver des bonnes explications et des exemples réels dans les supports d'une présentation qui avait été faite à l'IETF.

Quelles sont donc les recommandations concrètes de ce RFC ? La section 6 les résume. Au choix :

  • Renommer les serveurs de noms vers le nom d'un serveur maintenu par le client EPP (le BE), comme décrit dans la section 5.1.3.4.
  • Demander au client EPP de supprimer les serveurs de noms mais avec possibilité de rétablissement (RFC 3915) comme décrit en section 5.2.2.3.
  • Renommer les serveurs de noms dans un nom de domaine spécial, dont il est garanti qu'il ne sera jamais utilisé, comme décrit en section 5.1.4.3. Pour éviter d'avoir à créer une nouvelle entrée dans le registre des noms de domaine spéciaux, le nom sacrificial.invalid, utilisant un TLD existant, est recommandé.

Le protocole EPP permet de changer le nom d'un serveur de noms (section 3.2.5 du RFC 5732). Une pratique déjà observée est donc de renommer les serveurs de noms. Dans l'exemple ci-dessus, recevant la demande de suppression de domaine-d-un-copain.example, le registre (ou le BE s'il le peut) renommerait ns1.domaine-d-un-copain.example en, mettons, ns1.domaine-d-un-copain.renamed.invalid. Ici, .invalid, TLD réservé par le RFC 6761, ne poserait pas vraiment de problème mais renommer dans un domaine ouvert à l'enregistrement pourrait créer un risque de sécurité, si le domaine de destination n'existe pas, un méchant pouvant alors l'enregistrer et être ainsi en mesure de répondre aux requêtes DNS.

La section 3 du RFC explique brièvement pourquoi les RFC 5731 et RFC 5732 déconseillent fortement de permettre la suppression d'un domaine tant que des serveurs de noms dans ce domaine existent. Il y a deux risques de sécurité si on détruisait le domaine en laissant les serveurs de noms tels quels dans la base de données du registre : un de déni de service (le nom ne se résout plus et le serveur va donc être inutile) et un de détournement (si un méchant peut ré-enregistrer le nom de domaine supprimé). Il y a aussi le problème de la colle orpheline, décrit dans le rapport du SSAC, « Comment on Orphan Glue Records in the Draft Applicant Guidebook ».

Si la clé qui identifie un serveur de noms est un numéro quelconque et pas son nom, on peut renommer le serveur sans changer les délégations, ce qui est particulièrement utile si le client EPP n'a pas le droit de changer des délégations qui appartiennent à un autre client du registre. Le nouveau nom ne va en général pas être associé à un serveur opérationnel : on sacrifie un serveur pour pouvoir supprimer le domaine parent. Mais cela entraine quelques risques (section 4 du RFC et l'article d' Akiwate, G., Savage, S., Voelker, G., et K. Claffy, « Risky BIZness: Risks Derived from Registrar Name Management »). Si on renomme vers un nom actuellement inexistant, le domaine peut être détourné si un malveillant enregistre ensuite ce domaine.

Compte tenu de tout cela, la section 5 du RFC étudie les différentes pratiques possibles, leurs avantages et leurs inconvénients. Pour les illustrer, je vais utiliser une base de données simple, décrite en SQL (les essais ont été faits avec PostgreSQL). Voici par exemple une création d'une telle base :

CREATE TABLE Domains (name TEXT UNIQUE);

-- Ici, la table Nameservers n'offre aucune valeur ajoutée par rapport
-- au fait de tout mettre dans Domains. Mais ce ne sera pas le cas par
-- la suite. 
CREATE TABLE Nameservers (name TEXT UNIQUE);

CREATE TABLE Delegation (domain TEXT REFERENCES Domains(name),
                         server TEXT REFERENCES Nameservers(name));

INSERT INTO Domains VALUES ('monbeaudomaine.example');
INSERT INTO Domains VALUES ('domaine-d-un-copain.example');

INSERT INTO Nameservers VALUES ('ns1.domaine-d-un-copain.example');
INSERT INTO Nameservers VALUES ('ns1.hébergeur.example');

INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.domaine-d-un-copain.example');
INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.hébergeur.example');
  

Dans ce premier cas très simple, la suppression du domaine domaine-d-un-copain.example est triviale :

registry=> DELETE FROM Domains WHERE name='domaine-d-un-copain.example';
DELETE 1
  

Mais elle laisse la possibilité de colle orpheline et surtout d'un détournement de monbeaudomaine.example si quelqu'un ré-enregistre domaine-d-un-copain.example. Ce premier essai n'est pas conforme aux exigences des RFC 5731 et RFC 5732. On va essayer de faire mieux.

Si on interdit (à juste titre) la suppression d'un domaine lorsque des serveurs de noms sont nommés dans ce domaine, on peut arriver à supprimer un domaine en supprimant d'abord les serveurs de noms qui sont nommés dans ce domaine (section 5.2) :

CREATE TABLE Domains (name TEXT UNIQUE);

-- Ajout d'une dépendance au domaine parent, pour éviter les suppressions. 
CREATE TABLE Nameservers (name TEXT UNIQUE, parent TEXT REFERENCES Domains(name));

CREATE TABLE Delegation (domain TEXT REFERENCES Domains(name),
                         server TEXT REFERENCES Nameservers(name));

INSERT INTO Domains VALUES ('monbeaudomaine.example');
INSERT INTO Domains VALUES ('domaine-d-un-copain.example');
INSERT INTO Domains VALUES ('hébergeur.example');

-- Pour une vraie base, on écrirait du code SQL qui extrait le parent
-- automatiquement.
INSERT INTO Nameservers VALUES ('ns1.domaine-d-un-copain.example', 'domaine-d-un-copain.example');
INSERT INTO Nameservers VALUES ('ns1.hébergeur.example', 'hébergeur.example');

INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.domaine-d-un-copain.example');
INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.hébergeur.example');

registry=> DELETE FROM Domains WHERE name='domaine-d-un-copain.example';
ERROR:  update or delete on table "domains" violates foreign key constraint "nameservers_parent_fkey" on table "nameservers"
DETAIL:  Key (name)=(domaine-d-un-copain.example) is still referenced from table "nameservers".
-- Ce comportement est ce que recommandent les RFC 5731 et 5732.

-- Cela oblige le client à supprimer les serveurs de noms d'abord, ce qui à
-- son tour nécessite potentiellement de changer les délégations :

registry=> DELETE FROM Delegation WHERE server = 'ns1.domaine-d-un-copain.example';
DELETE 1
registry=>  DELETE FROM Nameservers WHERE name='ns1.domaine-d-un-copain.example';
DELETE 1
registry=>  DELETE FROM Domains WHERE name='domaine-d-un-copain.example';
DELETE 1
  

Ici, il y a eu suppression explicite des serveurs de noms par le client (section 5.2.2.1). Cela peut poser des problèmes de permission, dans le cadre du système RRR, si tous les objets ne sont pas chez le même BE. Mais la suppression explicite est une des trois solutions recommandées, notamment si on ajoute la possibilité de rétablir l'état précédent (commande EPP <restore>, RFC 3915).

On peut aussi envisager une suppression implicite (section 5.2.1.1), le registre se chargeant du nettoyage (c'est le rôle de la directive SQL ON DELETE CASCADE) :

CREATE TABLE Domains (name TEXT UNIQUE);

CREATE TABLE Nameservers (name TEXT UNIQUE,
                          parent TEXT REFERENCES Domains(name) ON DELETE CASCADE);

CREATE TABLE Delegation (domain TEXT REFERENCES Domains(name) ON DELETE CASCADE,
                         server TEXT REFERENCES Nameservers(name) ON DELETE CASCADE);

INSERT INTO Domains VALUES ('monbeaudomaine.example');
INSERT INTO Domains VALUES ('domaine-d-un-copain.example');
INSERT INTO Domains VALUES ('hébergeur.example');

-- Pour une vraie base, on écrirait du code SQL qui extrait le parent
-- automatiquement.
INSERT INTO Nameservers VALUES ('ns1.domaine-d-un-copain.example', 'domaine-d-un-copain.example');
INSERT INTO Nameservers VALUES ('ns1.hébergeur.example', 'hébergeur.example');

INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.domaine-d-un-copain.example');
INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.hébergeur.example');

registry=> SELECT Domains.name,Nameservers.name FROM Domains,Delegation,Nameservers WHERE Delegation.domain=Domains.name AND Delegation.server=Nameservers.name;
          name          |              name               
------------------------+---------------------------------
monbeaudomaine.example | ns1.domaine-d-un-copain.example
monbeaudomaine.example | ns1.hébergeur.example
(2 rows)

registry=>  DELETE FROM Domains WHERE name='domaine-d-un-copain.example';
DELETE 1

-- Serveur de noms et délégation ont été détruits en cascade. Ce n'est
-- pas déraisonnable mais c'est quand même un peu effrayant.

registry=> SELECT Domains.name,Nameservers.name FROM Domains,Delegation,Nameservers WHERE Delegation.domain=Domains.name AND Delegation.server=Nameservers.name;
          name          |         name          
------------------------+-----------------------
monbeaudomaine.example | ns1.hébergeur.example
(1 row)
  

Cette solution est simple et efficace mais détruire implicitement des objets de la base de données peut inquiéter les responsables de cette base. Et cela peut laisser un domaine avec trop peu de serveurs de noms pour assurer sa continuité de service voire, dans le pire des cas, sans serveurs du tout. Et il serait bon de prévenir le client de cette suppression implicite, par exemple par le mécanisme de poll d'EPP (RFC 8590).

Si on interdit (à juste titre, le RFC le recommande) la suppression d'un domaine lorsque des serveurs de noms sont nommés dans ce domaine, une solution possible est de renommer les serveurs avant de supprimer le domaine (section 5.1). Le nouveau nom permet d'indiquer clairement la raison du renommage. Mais ce renommage laisse dans la base des « déchets » qu'il faudra nettoyer un jour. Cette catégorie contient de nombreuses variantes. Par exemple, on peut renommer dans un TLD spécial (RFC 6761), ici, .invalid :

CREATE TABLE Domains (name TEXT UNIQUE);

-- On introduit un identificateur du serveur de noms qui n'est *pas*
-- son nom, pour permettre le renommage.
CREATE TABLE Nameservers (id SERIAL UNIQUE, name TEXT UNIQUE,
                                 parent TEXT REFERENCES Domains(name));

CREATE TABLE Delegation (domain TEXT REFERENCES Domains(name),
                         server INTEGER REFERENCES Nameservers(id));

INSERT INTO Domains VALUES ('monbeaudomaine.example');
INSERT INTO Domains VALUES ('domaine-d-un-copain.example');
INSERT INTO Domains VALUES ('hébergeur.example');
-- Pour le renommage, un nom qui indique clairement le but :
INSERT INTO Domains VALUES ('renamed.invalid');

-- Pour une vraie base, on écrirait du code SQL qui extrait le parent
-- automatiquement.
INSERT INTO Nameservers (name, parent) VALUES ('ns1.domaine-d-un-copain.example', 'domaine-d-un-copain.example');
INSERT INTO Nameservers (name, parent) VALUES ('ns1.hébergeur.example', 'hébergeur.example');

INSERT INTO Delegation VALUES ('monbeaudomaine.example',
     (SELECT id FROM Nameservers WHERE name='ns1.domaine-d-un-copain.example'));
INSERT INTO Delegation VALUES ('monbeaudomaine.example',
     (SELECT id FROM Nameservers WHERE name='ns1.hébergeur.example'));

registry=> SELECT Domains.name,Nameservers.name FROM Domains,Delegation,Nameservers WHERE Delegation.domain=Domains.name AND Delegation.server=Nameservers.id;
          name          |              name               
------------------------+---------------------------------
monbeaudomaine.example | ns1.domaine-d-un-copain.example
monbeaudomaine.example | ns1.hébergeur.example
(2 rows)

registry=> UPDATE Nameservers SET name='ns1.domaine-d-un-copain.example.renamed.invalid', parent='renamed.invalid' WHERE id=1;
UPDATE 1
registry=> DELETE FROM Domains WHERE name='domaine-d-un-copain.example';
DELETE 1

registry=> SELECT Domains.name,Nameservers.name FROM Domains,Delegation,Nameservers WHERE Delegation.domain=Domains.name AND Delegation.server=Nameservers.id;
          name          |                      name                       
------------------------+-------------------------------------------------
monbeaudomaine.example | ns1.domaine-d-un-copain.example.renamed.invalid
monbeaudomaine.example | ns1.hébergeur.example
(2 rows)

Par contre, il ne faut pas utiliser .alt, qui est explicitement réservé aux protocoles non-DNS (RFC 9476). Notez que certains serveurs EPP peuvent tester le nom des serveurs de noms et refuser des TLD « inconnus ».

Dans la nature, on a pu observer d'autres pratiques, comme de renommer dans un sous-domaine de as112.arpa, nom garanti ne pas exister (RFC 7535), mais qui n'est pas censé servir à cela (RFC 6305). On a vu aussi des renommages vers des résolveurs DNS publics, ce qui est également une horreur, la délégation doit être faite vers des serveurs faisant autorité, pas des résolveurs.

Certains clients EPP maintiennent des serveurs de noms actifs qui servent pour le renommage. Cela fait davantage de travail mais cela protège contre le détournement. Le DNS va continuer à fonctionner normalement. On pourrait aussi imaginer des serveurs de noms actifs, répondant NXDOMAIN (« ce domaine n'existe pas »), qui soient gérés collectivement (section 5.1.4.4) ; un tel service serait certainement utile. On pourrait même créer un nom de domaine pour ce service (sacrificial.arpa ?) mais personne ne l'a encore fait. Pour l'instant, la solution des serveurs maintenus par le client EPP (section 5.1.3.4) fait partie des trois solutions recommandées. Le client prudent doit bien verrouiller le domaine dans lequel ces serveurs sont nommés (enregistrement multi-années, verrouillage par le registre, etc).

On peut aussi renommer les serveurs de noms vers un nom non-existant dans un TLD existant. Ça s'est déjà vu mais il ne faut surtout pas faire cela : un attaquant pourrait enregistrer le nom et capter ainsi le trafic (.invalid n'a pas ce problème). Idem si le nom n'est pas sous votre contrôle. Un exemple est donné par le domaine lenvol.re : ses serveurs de noms étaient ns.hostin.io, ns.hostin.mu et ns.hostin.re. Lors de la suppression de hostin.re en octobre 2024, le dernier serveur de noms a été renommé host1.renamedbyregistry.com (et, en dépit du nom, pas par le registre). Ce domaine renamedbyregistry.com étant enregistré, et par un autre BE, on voit le risque.

%  whois lenvol.re
domain:                        lenvol.re
status:                        ACTIVE
…
nserver:                       host1.renamedbyregistry.com
nserver:                       ns.hostin.io
nserver:                       ns.hostin.mu
  

D'autres noms qui utilisaient ce même serveur ont également le problème :

% dig @d.nic.fr savanna.re. NS       
…
;; AUTHORITY SECTION:
savanna.re.		3600	IN	NS	host1.renamedbyregistry.com.
savanna.re.		3600	IN	NS	ns.hostin.mu.
savanna.re.		3600	IN	NS	ns.hostin.io.

;; Query time: 8 msec
;; SERVER: 2001:678:c::1#53(d.nic.fr) (UDP)
;; WHEN: Tue Jun 24 14:33:32 CEST 2025

En lecture supplémentaire, notre RFC recommande le rapport « SSAC 125 "Report on Registrar Nameserver Management" », ainsi que l'article « Risky BIZness: Risks Derived from Registrar Name Management ».


Téléchargez le RFC 9874


L'article seul

RFC 9868: Transport Options for UDP

Date de publication du RFC : Octobre 2025
Auteur(s) du RFC : J. Touch, C. Heard
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 5 décembre 2025


Des protocoles de transport, comme TCP, ont le concept d'options, ajoutées à l'en-tête et permettant de régler divers paramètres. Ce RFC ajoute ce concept à UDP et standardise quelques options. Désormais, il y a des moyens standards de faire du « ping » en UDP.

Mais comment ajouter des options à un vénérable protocole (UDP a été normalisé en 1980, dans le RFC 768), qui n'a pas de place pour cela dans son en-tête très minimal ? L'astuce est que UDP indique une taille de paquet qui peut être différente de celle indiquée par IP. Si elle est supérieure, les octets ainsi disponibles peuvent stocker des options, à la fin du paquet. Ce sera donc un pied (trailer) et pas un en-tête.

Voici un paquet UDP simplifié (j'ai aussi mis une partie de l'en-tête IP) analysé par tshark :

Internet Protocol Version 6, Src: 2a04:cec0:10fc:5bd8:efd1:79bb:7356:4583, Dst: 2001:db8::1
    0110 .... = Version: 6
…
    Payload Length: 56
    Next Header: UDP (17)
    Hop Limit: 64
    Source Address: 2a04:cec0:10fc:5bd8:efd1:79bb:7356:4583
    Destination Address: 2001:db8::1
User Datagram Protocol, Src Port: 57560 (57560), Dst Port: domain (53)
    Source Port: 57560 (57560)
    Destination Port: domain (53)
    Length: 56
…
    UDP payload (48 bytes)
  

Vous avez vu ? Il y a deux champs qui indiquent la longueur du paquet UDP, un dans l'en-tête IP (Payload length) et un dans l'en-tête UDP (Length). Ici, les deux sont identiques, ce qui est le cas « normal ». Mais s'ils sont différents ? C'est le point de départ de ce RFC. Les options se nicheront dans la différence entre la longueur du paquet UDP et celle du paquet IP qui l'encapsule, dans une zone connue sous le nom de surplus (surplus area). Normalement, elles seront ainsi ignorées de tous les vieux programmes (mais il y a parfois eu des bogues).

Comme TCP (RFC 9293), les protocoles de transport SCTP (RFC 9260) et DCCP (RFC 4340) ont dans leur en-tête un espace réservé pour d'éventuelles options. Pas UDP. C'est ce manque que comble notre RFC. Comme UDP est un protocole sans connexion, ces options ne serviront que pour un seul paquet (alors que TCP peut les garder pour toute la connexion). Des options, dans les autres protocoles de transport, il y en a plein. Pour TCP, le RFC cite par exemple, la dilatation de fenêtres (RFC 7323), l'authentification (RFC 5925) et d'autres. On en trouve pour des protocoles avec état (comme TCP, où elles vont s'appliquer à toute la connexion) ou sans état (comme IP, où elles ne s'appliquent qu'au paquet qui les porte). Comme vu plus haut, seul UDP (RFC 768) n'avait pas le moyen d'ajouter des options.

(Notez que TeredoRFC 4380 - utilisait déjà un truc analogue.)

À quoi vont servir ces options (section 5 du RFC) ? À court terme, à permettre des mécanismes de fragmentation, de test (« ping UDP »), etc. À plus long terme (mais ce n'est pas encore normalisé), elles rendront possible d'ajouter de l'authentification ou du chiffrement à UDP (DTLS, RFC 9147 chiffre mais ne protège pas l'en-tête de la couche Transport). On pourra aussi faire de la découverte de la MTU du chemin, comme spécifié dans le RFC 9869. Et enfin, cela pourra permettre d'augmenter la taille des paquets DNS comme proposé dans draft-heard-dnsop-udp-opt-large-dns-responses.

La section 6 du RFC spécifie le cahier des charges de ces options UDP :

  • UDP est sans état (sans connexion) et doit le rester.
  • UDP est unidirectionnel et doit le rester. Les protocoles requête/réponse (comme le DNS) sont bâtis sur UDP mais doivent s'occuper de faire correspondre requêtes et réponses sans l'aide d'UDP.
  • Les options UDP n'ont pas de taille maximale (à part celle du paquet UDP lui-même, 65 536 octets).
  • Les options UDP ne visent pas à remplacer des protocoles existants. Le « ping UDP » ne cherche pas à être équivalent au ping utilisant ICMP. Après tout, UDP est fait pour être minimal, et il doit le rester.
  • Les options UDP ne constituent pas un protocole à elles seules : un protocole situé au-dessus d'UDP va devoir spécifier bien des détails (par exemple le RFC 9869 qui décrit le protocole PLPMTUD).
  • Tout le mécanisme est conçu pour qu'un logiciel ancien, qui ne connaisse pas ces options, fonctionne comme aujourd'hui.

Un peu de terminologie avant d'attaquer les détails, notamment (section 3) :

  • Option sûre (SAFE option) : option qui pourra être ignorée par un receveur qui ne la comprend pas. Elle ne modifie pas la compréhension du paquet.
  • Option non sûre (UNSAFE option) : option qui ne doit pas être ignorée, car elle modifie la compréhension du paquet (par exemple car elle indique qu'il est chiffré).

La description technique de l'emplacement des options figure en section 7 du RFC. Le champ Longueur de l'en-tête UDP, qui a toujours été redondant avec celui d'IP, peut désormais prendre une valeur inférieure à celle du champ dans IP (mais supérieure à huit, la taille de l'en-tête UDP). La différence entre les deux longueurs est la taille du surplus, la zone à la fin du paquet où se logent les options (qui ne sont donc pas dans l'en-être mais dans le pied). Notez qu'il n'y a pas d'obligation que le surplus soit aligné sur des multiples (2 ou 4) d'octets. Si les longueurs IP et UDP sont identiques, c'est qu'il n'y a pas d'options.

La structuration du surplus en options est dans la section 8. Le surplus commence avec un champ de deux octets qui est une somme de contrôle. Cet OCS (Option CheckSum) est une somme de contrôle Internet traditionnelle (RFC 791, section 3.1, et RFC 1071). Pourquoi cette somme de contrôle alors qu'UDP en a déjà une ? Pour détecter les cas où un autre mécanisme jouerait avec la différence des champs Longueur d'IP et d'UDP et aurait son propre pied, distinct de celui normalisé dans notre RFC. Simple somme de contrôle, l'OCS ne joue pas un rôle en sécurité, il ne sert qu'à vérifier que le surplus est bien utilisé conformément à la norme sur les options UDP. (Les options sont ignorées si l'OCS n'est pas correcte, voir la section 14.) La section 18 insiste sur ce point : comme cette distinction entre deux champs Longueur est ancienne, il est possible que certains s'en servaient et il faut donc faire face à la possibilité que des paquets UDP aient des champs Longueur différents sans pour autant avoir des options telles que normalisées ici. L'OCS est donc aussi une sorte de nombre magique mais en plus fort, puisqu'il n'est pas statique.

Comme toujours, il faut prévoir le cas de middleboxes boguées qui calculeraient la somme de contrôle UDP sur tout le paquet IP, au lieu de s'arrêter à la longueur indiquée dans l'en-tête UDP. L'OCS est conçu pour annuler l'effet d'une telle bogue (merveille des sommes de contrôle, qui n'ont pas de dispersion des résultats). La somme de contrôle UDP étant optionnelle (mais c'est évidemment très déconseillé), l'OCS l'est aussi (et peut donc valoir zéro). Rappelez-vous que ce qui marchait avant en UDP doit encore marcher avec les options donc, par défaut, même si l'OCS est incorrect, le paquet doit être transmis aux applications réceptrices.

À propos de middleboxes, le RFC précise aussi (section 16) que les options sont de bout en bout et ne doivent pas être modifiées par les équipements intermédiaires (mais cela risque de rester un vœu pieux). Des tests effectués ont montré que des systèmes d'exploitation courants (Linux, macOS, Windows) n'avaient pas de problème en recevant des paquets UDP contenant des options (section 18). Ils n'envoient à l'application que la partie du paquet indiquée par le champ Longueur d'UDP, et ignorent donc les options, qu'on peut donc envoyer sans craindre de perturber les systèmes pré-existants. Toutefois, au moins un objet connecté (non nommé par le RFC) passe tout le datagramme (y compris, donc, le surplus contenant les options) à l'application. Et au moins un IDS, l'Alcatel-Lucent Brick considère les paquets UDP ayant des options comme des attaques (les IDS sont un des facteurs importants de l'ossification de l'Internet car ils interprètent tout ce qui ne colle pas à leur vision étroite comme une attaque).

Les options suivent la somme de contrôle et la plupart sont encodées selon un classique schéma TLV, comme pour la plupart des options TCP (RFC 9293, section 3.1). Les deux exceptions à cet encodage TLV sont les options NOP (un seul octet, qui vaut un, cette option, comme son nom l'indique, ne sert à rien, à part éventuellement à aligner les données) et EOL (End Of Options, un seul octet, qui vaut zéro, elle indique la fin de la liste d'options). Autrement, les options sont en TLV, le premier octet indiquant le type, la longueur faisant un octet (un mécanisme existe pour des options faisant plus de 255 octets). Les options sûres ont un type de 0 à 191, les autres sont non sûres. Parmi les options sûres enregistrées par notre RFC, outre EOL et NOP, on trouve entre autres (section 11) :

  • APC (Additional Payload Checksum), type 2, qui ajoute une somme de contrôle plus forte (CRC32c, la même que celle utilisée dans iSCSI, RFC 3385 et SCTP).
  • FRAG (Fragmentation), type 3, qui permet une fragmentation au niveau UDP. Peut se combiner avec MDS (Maximum Datagram Size, type 4), qui indique la taille maximale qu'un récepteur peut accepter sans que le datagramme soit fragmenté.
  • REQ (Echo Request, type 6) et RES (Echo Response, type 7) permettent de faire un « ping UDP ». (Plus propre que les trucs abusivement baptisés « ping UDP » comme cet exemple ou celui-ci.)
  • TIME, type 8, permet d'envoyer et de recevoir l'heure, sous forme d'une estampille temporelle de quatre octets. C'est l'analogue de l'option TCP Timestamp (RFC 7323, section 3). UDP ne garantit pas que ces estampilles correspondent à l'heure officielle, juste qu'elles seront monotones (toujours croissantes).
  • AUTH (Authentication), n'est pas réellement spécifiée. Son type, 9, est réservé mais les autres points sont repoussés à un futur RFC, peut-être à partir de l'Internet-Draft draft-touch-tsvwg-udp-auth-opt.

Les options EOL, NOP et quelques autres doivent normalement être reconnues par toutes les mises en œuvres des options UDP (cf. section 14).

Et les options non sûres ? Rappelons que ce sont celles qui modifient l'interprétation du contenu du paquet. On y trouve (section 12 du RFC) entre autres :

  • UCMP (Unsafe Compression), type 192, pour des contenus comprimés.
  • UENC (Unsafe Encryption), type 193, pour des contenus chiffrés.

Ces deux options ne sont pas autrement spécifiées, seul un type est réservé. Le reste devra être précisé dans un RFC ultérieur.

De nouvelles options seront peut-être rajoutées dans le futur au registre des options (section 13 du RFC). La politique IANA (section 26) est « action de normalisation » ou « approbation par l'IESG », donc des procédures assez lourdes (RFC 8126) : il ne sera pas facile d'ajouter des options.

Question mise en œuvre, ce n'est pas forcément trivial à faire soi-même. Pour pouvoir lire et à plus forte raison écrire des options UDP, il faut actuellement court-circuiter UDP et écrire directement au-dessus d'IP (raw sockets) ou pire, dans certains cas, directement sur le réseau. Notre RFC propose des extensions à l'API socket pour lire et écrire les options (avec aussi des variables sysctl) mais je ne connais pas encore de système d'exploitation qui les intègre. Notez que ces API ne permettent pas d'influencer l'ordre des options, et c'est exprès.

Une difficulté supplémentaire vient du fait qu'UDP est sans état, sans connexion. D'une part, les options ne peuvent pas être négociées lors de l'établissement de la connexion (puisqu'il n'y a pas de connexion), d'autre part, elles doivent être répétées dans chaque paquet (puisqu'il n'y a pas d'état). Le RFC précise donc (section 19) qu'il faut ignorer les options qu'on ne connait pas (du moins celles marquées comme sûres). D'autre part il impose qu'on passe les données à l'application même si on ne comprend pas les options. Ah, et aussi, les options UDP sont conçues pour l'unicast essentiellement.

Et leurs conséquences pour la sécurité (section 25 du RFC) ? Fondamentalement, les options UDP ne posent pas plus (ou pas moins…) de problèmes de sécurité que les options TCP, qui sont normalisées depuis longtemps. Comme pour TCP, elles ne sont pas sécurisées par TLS (ici, DTLS, RFC 9147), TLS qui protège uniquement les données applicatives. Si vous voulez les protéger, il faudra attendre la spécification des futures options AUTH (qui fournira à peu près le même service que le AO de TCP, normalisé dans le RFC 5925) et UENC. Ou alors, protégez toute la couche transport avec IPsec (RFC 4301).

Mais il y a un autre danger, dans la façon dont vont être traitées les options UDP par le récepteur. Si celui-ci boucle imprudemment, en attendant juste l'option EOL, le risque de débordement est élevé. Ou si le récepteur alloue de la mémoire en utilisant le champ Longueur d'UDP puis y copie tout le paquet, les options faisant alors déborder son tampon.

Voilà, je n'ai pas tout détaillé, la section 25 est longue, lisez-la.

Un petit point d'histoire (section 4) : pourquoi diable UDP a-t-il ce champ Longueur, alors que celui d'IP suffisait, d'autant plus que l'en-tête UDP est de taille fixe ? Aucun autre protocole de transport ne fait cela (à part peut-être Teredo, RFC 6081). Le RFC note que des historiens de l'Internet ont été consultés mais sans résultat. Les raisons de ce choix (qu'on apprécie aujourd'hui mais qui est resté sans utilité pratique pendant 45 ans) restent mystérieuses. Permettre de placer plusieurs paquets UDP dans un seul datagramme IP ? Pour remplir les paquets de manière à ce qu'ils soient alignés sur des multiples d'octets ? Aucune explication ne semble satisfaisante et les archives sont muettes.

Notez aussi que d'autres propositions avaient été faites pour ajouter des options à UDP, comme celle décrite dans l'Internet Draft draft-hildebrand-spud-prototype.

Autre question que vous vous posez peut-être : et UDP-Lite (RFC 3828) ? Lui aussi jouait avec la différence des champs Longueur d'IP et d'UDP, pour indiquer la partie du paquet couverte par la somme de contrôle. De ce fait, le mécanisme d'options ne peut pas être utilisé pour UDP-Lite (section 17).

Et les mises en œuvre concrètes ? Il n'existe pas, à ma connaissance, de serveurs de test publics sur l'Internet. Mais vous avez une liste des programmes existants (je n'en ai pas vu en Python utilisant Scapy, ce qui serait pourtant une expérience intéressante).

D'autres lectures sur ces options UDP ? Vous avez l'article de Raffaele Zullo et les supports d'un de ses exposés, qui expliquent bien la question. Et, sinon ChatGPT, consulté s'en ne s'en est pas trop mal tiré, inventant un mécanisme qui ressemble à celui de TCP.


Téléchargez le RFC 9868


L'article seul

RFC 9861: KangarooTwelve and TurboSHAKE

Date de publication du RFC : Octobre 2025
Auteur(s) du RFC : B. Viguier (ABN AMRO Bank), D. Wong (zkSecurity), G. Van Assche (STMicroelectronics), Q. Dang (NIST), J. Daemen (Radboud University)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF cfrg
Première rédaction de cet article le 13 octobre 2025


Vous trouvez qu'il n'y a pas assez d'algorithmes en cryptographie ? En voici quatre de plus, ici pour condenser cryptographiquement des données, plus rapidement que les algorithmes existants.

Il s'agit de quatre fonctions, TurboSHAKE128 et TurboSHAKE256 (variantes de TurboSHAKE) ainsi que de KT128 et KT256 (variantes de Kangaroo Twelve qui est décrit dans cet article). Toutes sont des XOF (eXtendable Output Function), des fonctions dont le résultat peut être infiniment long (comme ce que produit un générateur pseudo-aléatoire), mais qu'on tronque à la valeur souhaitée (cf. section 2.1). Kangaroo Twelve (section 3) est bâti sur TurboSHAKE et apporte le parallélisme : il permet de répartir le travail sur plusieurs processeurs alors que SHA-3 et TurboSHAKE sont strictement séquentiels. TurboSHAKE (section 2), lui, est bâti sur Keccak (qui est aussi la base de SHA-3, la cryptographie, c'est compliqué). D'ailleurs, le logiciel qui met en œuvre les algorithmes de ce RFC est développé par l'équipe de Keccak.

Ne comptez pas sur moi pour des explications cryptographiques détaillées, je n'y connais rien, lisez les sections 2 et 3 du RFC. Mais Sakura, le système utilisé par Kangaroo Twelve pour répartir le travail semble intéressant (cf. l'article original).

En section 4 du RFC, vous trouverez comment utiliser Kangaroo Twelve pour faire un MAC (on condense le message puis on condense la concaténation de la clé et du résultat de la première condensation).

Et si vous voulez mettre en œuvre Kangaroo Twelve vous-même, la section 5 vous offre de nombreux vecteurs de test. Mais, avant, regardez l'annexe A qui vous offre du pseudo-code et rappelle qu'il y a une implémentation en C, XKCP (par l'équipe Keccak) et une en Python, décrite dans l'article «  KangarooTwelve: fast hashing based on Keccak-p » (les vecteurs de test du RFC viennent de là, normal, ce sont les mêmes auteurs). Enfin, une troisième est en Zig. Commençons en Python (j'ai fait une copie du code de l'article dans kangarootwelve.py et le programme de test est test-kangarootwelve.py). Si on prend ce vecteur de test dans le RFC :

  
      KT128(M=ptn(17 bytes), C=`00`^0, 32):
       `6B F7 5F A2 23 91 98 DB 47 72 E3 64 78 F8 E1 9B
        0F 37 12 05 F6 A9 A9 3A 27 3F 51 DF 37 12 28 88`

Le programme affiche :

% python test-kangarootwelve.py
6b f7 5f a2 23 91 98 db 47 72 e3 64 78 f8 e1 9b 0f 37 12 05 f6 a9 a9 3a 27 3f 51 df 37 12 28 88 

Ce qui est bien la bonne valeur.

Et avec XKCP, compilons la bibliothèque et le programme de test test-kangarootwelve.c :

git submodule update --init
make generic64/libXKCP.so
gcc -I ./bin/generic64/libXKCP.so.headers  -L ./bin/generic64   test-kangarootwelve.c -lXKCP
# ou
# gcc -I ./bin/generic64/libXKCP.so.headers test-kangarootwelve.c ./bin/generic64/libXKCP.so
LD_LIBRARY_PATH=./bin/generic64 ./a.out 
  

Et le programme affiche bien le vecteur de test indiqué dans le RFC.

Kangaroo Twelve a été ajouté au registre IANA, et les quatre algorithmes sont dans le registre de COSE (RFC 8152).


Téléchargez le RFC 9861


L'article seul

RFC 9859: Generalized DNS Notifications

Date de publication du RFC : Septembre 2025
Auteur(s) du RFC : J. Stenstam (The Swedish Internet Foundation), P. Thomassen (deSEC, Secure Systems Engineering), J. Levine (Standcore LLC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 5 octobre 2025


Vous le savez, le protocole DNS permet plusieurs sortes de messages, identifiés par un code d'opération. Si le classique QUERY, pour demander à résoudre un nom en informations pratiques, est le plus connu, il y a aussi le UPDATE (modifier les données), le DSO (DNS Stateful Operations) et quelques autres. Et puis il y a le NOTIFY, qui sert à indiquer à un serveur DNS qu'il y a quelque chose de nouveau et d'intéressant. NOTIFY est surtout connu pour son utilisation afin de… notifier un serveur secondaire que le primaire a une nouvelle version de la zone (c'est dans le RFC 1996). Ce nouveau RFC généralise le concept et permet d'utiliser NOTIFY pour d'autres choses comme un changement dans la liste des serveurs faisant autorité ou un changement de clé DNSSEC.

Si vous avez oublié à quoi servait initialement NOTIFY, relisez le RFC 1996. Il permettait de donner une indication (uniquement une indication, le NOTIFY ne fait pas autorité) comme quoi il faudrait envisager un nouveau transfert de zone (RFC 5936) pour mettre à jour un serveur. Cela permettait des mises à jour plus rapides qu'avec le système traditionnel où chaque serveur esclave devait de temps en temps demander à son maître s'il y avait du nouveau. Mais il y a d'autres cas où un serveur DNS voudrait dire à un autre qu'il y a quelque chose à regarder, par exemple si une nouvelle clé doit être utilisée. D'où l'extension d'utilisation que permet notre RFC 9859. Elle ne change pas le protocole, elle se contente d'utiliser plus largement une fonction existante.

Bon, mais c'est bien joli de dire qu'on peut notifier pour bien des choses mais on notifie qui ? Dans le cas traditionnel d'une nouvelle version de la zone, le primaire savait qu'il devait notifier ses secondaires, qu'il connait (après tout, il doit leur autoriser le transfert de zone et, dans le pire des cas, il peut toujours regarder l'ensemble d'enregistrements NS de sa zone). Mais si on généralise le NOTIFY, on peut ne pas savoir qui notifier (les autres mécanismes de notification, comme une API ou comme la mise à jour dynamique du RFC 2136, ont d'ailleurs le même problème). La section 3 du RFC couvre ce problème. La méthode recommandée est de publier un enregistrement de type DSYNC, normalisé dans notre RFC, section 2. Il se place sous le nom _dsync de la zone :

sousdomaine._dsync  IN DSYNC  CDS   NOTIFY 5359 cds-scanner.example.net.
  

Notez qu'un joker est possible, par exemple :

*._dsync  IN DSYNC  CDS   NOTIFY 5359 cds-scanner.example.net.
*._dsync  IN DSYNC  CSYNC NOTIFY 5359 cds-scanner.example.net.
  

Ce nom _dsync a été ajouté dans le registre des noms précédés d'un trait bas (RFC 8552). Voici un autre exemple d'enregistrement DSYNC :

_dsync.example.net.   IN DSYNC  CDS   NOTIFY 5359 cds-scanner.example.net.
  

Que dit-il ? Qu'example.net, a priori un hébergeur DNS, voudrait que ses clients, lorsqu'ils ont un nouvel enregistrement CDS (indiquant l'activation d'une nouvelle clé DNSSEC, cf. RFC 8078), notifient cds-scanner.example.net sur le port 5359. Ce nouveau type DSYNC a été ajouté au registre des types, avec la valeur 66.

La section 4.1 détaille comment on trouve le serveur à qui envoyer la notification en utilisant _dsync. Imaginons qu'on gère extra.sub.exodus-privacy.eu.org et qu'on veuille notifier la zone parente. On insère le composant _dsync après le premier composant (cela donne extra._dsync.sub.exodus-privacy.eu.org) et on fait une requête pour ce nom et le type DSYNC. Si ça marche, c'est bon, sinon, on utilise le SOA dans la réponse pour trouver la zone parente, et on met le _dsync devant. Si ça ne donne toujours rien, on retire les composants avant la zone parente et on recommence. Donc, on interrogera successivement (jusqu'au premier succès), extra._dsync.sub.exodus-privacy.eu.org, extra.sub._dsync.exodus-privacy.eu.org et _dsync.exodus-privacy.eu.org.

Et le NOTIFY dans l'enregistrement DSYNC d'exemple plus haut ? C'est le plan (scheme, à ne pas confondre avec le code d'opération - opcode - NOTIFY) car DSYNC, dans le futur, pourra servir à autre chose que les notifications. Pour l'instant, dans le nouveau registre des plans, il n'y a que NOTIFY mais dans le futur, d'autres pourront être ajoutés (suivant la politique « Examen par un expert » du RFC 8126).

Comment utiliser ce mécanisme de notification généralisé pour traiter les enregistrements CDS et CDNSKEY des RFC 7344, RFC 8078 et RFC 9615 ? Ces enregistrements servent à signaler à la zone parente la disponibilité de nouvelles clés DNSSEC. La section 4 de notre RFC détaille comment le mécanisme de notification permet d'indiquer qu'un CDS ou un CDNSKEY a changé. Cela évite au gestionnaire de la zone parente de balayer toute la zone ce qui, pour un TLD de plusieurs millions de noms comme .fr serait long et pénible. La solution de ce RFC 9859 est donc de chercher les DSYNC puis d'envoyer les NOTIFY, au moins deux, un pour le type CDS et un pour le type CDNSKEY (on ne sait pas forcément à l'avance lesquels utilisent la zone parente). La zone parente doit effectuer les mêmes vérifications que lorsqu'elle a détecté un nouveau CDS (ou CDNSKEY) : RFC 9615 si on active une zone signée pour la première fois et RFC 7344 et RFC 8078 autrement.

Les messages utilisant le code d'opération NOTIFY sont censés produire une réponse (RFC 1996, section 4.7). Si aucune réponse n'arrive avant l'expiration du délai de garde, on réessaie. Si on a trop réessayé, on peut signaler le problème avec la technique du RFC 9567.

Il est important de se souvenir qu'une notification n'est pas sérieusement authentifiée, et que le récepteur doit donc, s'il choisit d'agir sur une notification, être prudent. Dans le RFC 1996, rien de grave ne pouvait arriver, le récepteur du NOTIFY demandait juste le SOA de la zone puis, si nécessaire, un transfert de zone. Mais avec les CDS et CDNSKEY, des attaques plus sérieuses sont possibles et le destinataire de la notification doit donc effectuer davantage de vérifications (par exemple, si la zone est déjà signée, faire une requête pour le CDS ou le CDNSKEY et vérifier que la réponse est valide et sécurisée, si elle ne l'est pas, faire tous les contrôles du RFC 9615). La notification elle-même n'est pas un problème de sécurité (elle dit juste « tu devrais regarder cela »), c'est l'action qui en résulte qui doit être bien réfléchie. Voilà pourquoi les notifications, même généralisées, ne sont pas plus sécurisées que cela. (Voir aussi la section 5 du RFC, qui insiste sur ce point ; la notification peut accélérer les choses mais ne doit pas à elle-même changer quelque chose.) Il est quand même préférable de limiter le nombre de notifications qu'on traite, au cas où un client malveillant vous bombarde de notifications.

Ces notifications généralisées pourront aussi s'utiliser pour les CSYNC du RFC 7477.

Qui met en œuvre ce RFC à l'heure actuelle ? Des opérateurs comme deSEC ont annoncé que c'était en cours, côté client. Côté serveur, les registres de .ch et .se ont annoncé que c'était en cours, ou bien prévu.

Voici un exemple d'un client en Python (utilisant dnspython) qui notifie pour un nouveau CDS :

import dns.message
import dns.query    
import dns.opcode

notify = dns.message.make_query("bortzmeyer.fr", "CDS")
notify.set_opcode(dns.opcode.NOTIFY)
response = dns.query.udp(notify, "192.0.2.211")
print(response)
  

Et en C ? Vous pouvez utiliser le programme d'exemple generalized-notify.c, qui utilise l'excellente bibliothèque ldns. Compiler et exécuter :

% gcc -o generalized-notify -Wall generalized-notify.c -lldns 

% ./generalized-notify bortzmeyer.fr 192.0.2.211
Reply code: NOERROR
  

Je note à ce sujet que certains serveurs faisant autorité, lorsqu'ils ne font pas autorité pour le domaine signalé, répondent REFUSED, ce qui est logique, mais on voit aussi des FORMERR ou NXDIOMAIN (!), sans doute parce que le type CDS ne leur plait pas.

L'annexe A du RFC prend de la hauteur et décrit plus en détail le problème du balayage DNS. Comment savoir qu'il y a du nouveau, sans tout examiner (dans le cas du SOA, au rythme indiqué par le champ Refresh ; mais il n'y a pas de telle solution pour les CDS et CDNSKEY). Le DNS traditionnel ne marchait que sur un modèle pull (et c'est pour cela qu'il est faux de parler de propagation DNS) mais les NOTIFY du RFC 1996 introduisaient un peu de push. Heureusement car balayer .com à la recherche de nouveaux enregistrements serait lent (et attirerait probablement l'attention des IDS). Pour les CDS et CDNSKEY, cela serait d'autant plus agaçant qu'ils seront a priori peu nombreux et que la plupart des requêtes ne donneront donc rien.


Téléchargez le RFC 9859


L'article seul

RFC des différentes séries : 0  1000  2000  3000  4000  5000  6000  7000  8000  9000