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.


Le cas du serveur DNS qui ne se mettait plus à jour

Première rédaction de cet article le 11 novembre 2024


La semaine dernière, 26 TLD africains avaient des problèmes DNS. Pourquoi ? Parce qu'une machine quelque part ne se mettait plus à jour et servait des données erronées.

Le problème semble s'être déclenché autour du 29 octobre. Des signalements ont été faits sur les réseaux sociaux comme quoi certain·es utilisateurices n'arrivaient pas à résoudre des noms en .mg. On voit ici un test fait avec les sondes RIPE Atlas et le logiciel Blaeu :

% blaeu-resolve --requested 100 --displayvalidation --type NS mg
[dns-tld.ird.fr. ns-mg.afrinic.net. ns-mg.malagasy.com. ns.dts.mg. ns.nic.mg. pch.nic.mg.] : 39 occurrences
[ (Authentic Data flag) dns-tld.ird.fr. ns-mg.afrinic.net. ns-mg.malagasy.com. ns.dts.mg. ns.nic.mg. pch.nic.mg.] : 52 occurrences
[ERROR: SERVFAIL] : 5 occurrences
[ERROR: NXDOMAIN] : 2 occurrences
Test #81689686 done at 2024-11-08T15:45:06Z

Cinq sondes ont un résolveur qui répond SERVFAIL (Server Failure). On peut soupçonner un problème DNSSEC et on voit en effet avec DNSviz que des signatures expirées sont reçues par certains clients DNS. Le fait que la plupart des utilisateurices ne voient pas de problème laisse entendre que tous les serveurs faisant autorité pour .mg ne sont pas également affectés. Examinons-les tous :

% for ns in ns.dts.mg. ns-mg.malagasy.com. dns-tld.ird.fr. pch.nic.mg. ns.nic.mg. ns-mg.afrinic.net.; do
for> echo $ns
for> dig @$ns mg. NS
for> done
ns.dts.mg.
…
;; ANSWER SECTION:
mg.			7200 IN	NS ns.nic.mg.
mg.			7200 IN	NS ns-mg.afrinic.net.
mg.			7200 IN	NS ns.dts.mg.
mg.			7200 IN	NS ns-mg.malagasy.com.
mg.			7200 IN	NS pch.nic.mg.
mg.			7200 IN	NS dns-tld.ird.fr.
mg.			7200 IN	RRSIG NS 8 1 7200 (
				20241113113756 20241030045734 18 mg.
				ExrGRrWttb4umpOtW2d8gbW2J1p68LENdw3X409lP1hm
…
;; Query time: 193 msec
;; SERVER: 196.192.32.2#53(ns.dts.mg.) (UDP)
;; WHEN: Fri Nov 08 16:46:03 CET 2024
;; MSG SIZE rcvd: 548
ns-mg.afrinic.net.
…
;; ANSWER SECTION:
mg.			7200 IN	NS ns.dts.mg.
mg.			7200 IN	NS ns.nic.mg.
mg.			7200 IN	NS dns-tld.ird.fr.
mg.			7200 IN	NS ns-mg.malagasy.com.
mg.			7200 IN	NS pch.nic.mg.
mg.			7200 IN	NS ns-mg.afrinic.net.
mg.			7200 IN	RRSIG NS 8 1 7200 (
				20241101171148 20241018111647 18 mg.
				UIIoFCD8kaXyqTIVsrgBdiwQZxwHOXsnZjpPky5p5dRa
…
; Query time: 156 msec
;; SERVER: 2001:43f8:120::35#53(ns-mg.afrinic.net.) (UDP)
;; WHEN: Fri Nov 08 16:46:04 CET 2024
;; MSG SIZE rcvd: 504

Je n'ai gardé que la réponse de deux des serveurs. Celle de ns.dts.mg ne montre aucun problème particulier mais celle de ns-mg.afrinic.net montre une signature expirée (20241101171148 = 1 novembre alors que le test a été fait le 8). Pas étonnant que les résolveurs qui valident avec DNSSEC soient mécontents. Mais pourquoi ce serveur fait-il cela ? En testant avec le logiciel check-soa, on voit :

% check-soa mg
dns-tld.ird.fr.
	13.39.116.127: OK: 2024110815
ns-mg.afrinic.net.
	2001:43f8:120::35: OK: 2024102913
	196.216.168.35: OK: 2024102913
ns-mg.malagasy.com.
	51.178.182.212: OK: 2024110815
ns.dts.mg.
	196.192.32.2: OK: 2024110815
ns.nic.mg.
	196.192.42.153: OK: 2024110815
pch.nic.mg.
	2001:500:14:6121:ad::1: OK: 2024110815
	204.61.216.121: OK: 2024110815

Aïe, le numéro de série est en retard (2024102913 alors que les autres serveurs sont à 2024110815). Donc, ce serveur ne se met plus à jour avec son serveur maitre, il continue à distribuer de vieilles données.

Mais attention, ce serveur ns-mg.afrinic.net est anycasté. Ce ne sont peut-être pas toutes les instances anycast qui ont le problème. D'ailleurs, check-soa depuis d'autres machines ne montre pas de problème. Utilisons encore les sondes RIPE Atlas pour interroger uniquement ce serveur, en demandant son NSID (RFC 5001) :

% blaeu-resolve --requested 100 --nameserver ns-mg.afrinic.net. --nsid --type SOA mg
Nameserver ns-mg.afrinic.net.
[NSID: s03-ns2.iso; ns.nic.mg. ramboa.nic.mg. 2024110815 14400 3600 604800 3600] : 41 occurrences
[NSID: s01-ns2.pkl; ns.nic.mg. ramboa.nic.mg. 2024102913 14400 3600 604800 3600] : 28 occurrences
[NSID: s01-ns2.pkl; ns.nic.mg. ramboa.nic.mg. 2024110815 14400 3600 604800 3600] : 24 occurrences
[NSID: s04-ns2.jnb; ns.nic.mg. ramboa.nic.mg. 2024110815 14400 3600 604800 3600] : 4 occurrences
[NSID: None; ns.nic.mg. ramboa.nic.mg. 2024110815 14400 3600 604800 3600] : 1 occurrences
[TIMEOUT] : 2 occurrences
Test #81689801 done at 2024-11-08T15:54:11Z

On voit ici que l'instance s01-ns2.pkl est celle qui a le problème : le numéro de série est vieux. (Pour compliquer les choses, notons qu'il y a deux instances ayant le même NSID, ce qui ne facilite pas le déboguage.)

Une partie des clients DNS (ceux qui ont la malchance de tomber sur cette instance) reçoivent donc de la vieille information. Les domaines créés récemment, par exemple, ne sont pas connus de cette instance. Et, comme vu plus haut, elle sert des signatures expirées, ce qui peut planter DNSSEC. (Normalement, le résolveur validant, en recevant ces signatures expirées, devrait réessayer auprès d'un autre serveur du domaine mais, apparemment, certains ne le font pas.)

Et le problème n'affectait pas que .mg. Ce serveur secondaire, géré par Afrinic, sert 26 TLD en tout. (Les gérants de ces TLD ont été notifiés. Si vous voulez en parler à Afrinic, c'est leur ticket [DNS #924626]. Si vous connaissez l'Internet, vous ne serez pas surpris d'apprendre que, dans deux cas, l'adresse de contact était invalide et générait un message d'erreur.) Voici par exemple ce que cela donnait pour .td :

% blaeu-resolve --requested 100 --nameserver ns-td.afrinic.net. --nsid --type SOA td
Nameserver ns-td.afrinic.net.
[NSID: s01-ns2.pkl; pch.nic.td. hostmaster.nic.td. 2024110815 21600 3600 604800 7200] : 20 occurrences
[NSID: s01-ns2.pkl; pch.nic.td. hostmaster.nic.td. 2024102914 21600 3600 604800 7200] : 25 occurrences
[NSID: s03-ns2.iso; pch.nic.td. hostmaster.nic.td. 2024110815 21600 3600 604800 7200] : 47 occurrences
[NSID: None; pch.nic.td. hostmaster.nic.td. 2024110815 21600 3600 604800 7200] : 1 occurrences
[NSID: s04-ns2.jnb; pch.nic.td. hostmaster.nic.td. 2024110815 21600 3600 604800 7200] : 5 occurrences
Test #81691145 done at 2024-11-08T16:55:58Z

Le problème a finalement été réparé le 10 novembre. Afrinic a retiré du service l'instance invalide. Ici, on voit qu'elle n'est plus présente (test avec le .mz) :

% blaeu-resolve --requested 100 --displayvalidation --nsid --nameserver ns-mz.afrinic.net --type SOA mz
Nameserver ns-mz.afrinic.net
[NSID: s03-ns2.iso; anyns.uem.mz. hostmaster.nic.mz. 2024111106 480 300 259200 21600] : 48 occurrences
[NSID: s01-ns2.jinx; anyns.uem.mz. hostmaster.nic.mz. 2024111106 480 300 259200 21600] : 13 occurrences
[TIMEOUT] : 33 occurrences
[NSID: s04-ns2.jnb; anyns.uem.mz. hostmaster.nic.mz. 2024111106 480 300 259200 21600] : 4 occurrences
[NSID: None; anyns.uem.mz. hostmaster.nic.mz. 2024111106 480 300 259200 21600] : 1 occurrences
Test #81847650 done at 2024-11-11T06:14:08Z

Les leçons à en tirer :

  • Des cas similaires, voire très proches, avaient déjà existé (voir par exemple le problème de .com à Singapour et sa vision par Cloudflare).
  • L'Internet, c'est compliqué, le DNS aussi,
  • Du fait du caractère décentralisé de l'Internet et du DNS, deux clients différents placés à des endroits différents ne verront pas la même chose. Il ne faut pas donc déboguer depuis un seul point de mesure (tests avec dig et check-soa) mais depuis plusieurs, ce que permettent justement les sondes Atlas,
  • Le DNS résiste beaucoup mieux aux pannes franches (câble coupé) qu'aux serveurs qui servent des réponses erronées ou dépassées. En cas de panne franche, un autre des serveurs faisant autorité aurait été interrogé. Si vous supervisez vos serveurs DNS (et vous le faites, j'en suis sûr), ne regardez pas seulement s'ils répondent mais aussi s'ils répondent avec les bonnes données.

Annexe : la liste des domaines africains servis par la machine d'Afrinic pendant la panne :

.bi
.bj
.bw
.ci
.cm
.dz
.gm
.gn
.ke
.km
.lr
.ls
.ly
.mg
.mr
.mz
.ne
.rw
.sd
.ss
.td
.tn
.ug
.zm
.موريتانيا
.تونس

L'article seul

IETF 121 hackathon: greasing DNS answers

First publication of this article on 10 November 2024


On November 2 and 3 was the IETF hackathon in Dublin. I worked on the greasing of DNS answers from an authoritative name server. What is greasing? Continue reading.

One of the big technical problems of the Internet is its ossification: software is written by people who did not read the technical standards, or did not understand them, specially software in the middleboxes (load balancers, firewalls, etc). As a result, some things that are possible according to the technical specification are de facto forbidden by broken software. This makes difficult to deploy new things. For instance, TLS 1.3 had to pretend to be 1.2 (and add an extension to say "I am actually 1.3") because too many middleboxes prevented the establishement of TLS sessions if the version was 1.3 (see RFC 8446, section 4.1.2). This problem is widespread in the Internet, specially since there is typically no way to talk to the middlebox software authors and these boxes are popular among managers.

A way to fight ossification is greasing. Basically, the idea is to exercise all the features and options of a protocol from day one, not waiting that you really need them. This way, broken software will be detected immediately, not many years after, when it is entrenched. TLS was the first protocol to go that way (see RFC 8701) and it proved effective. QUIC also uses greasing (RFC 9287).

The DNS could benefit from greasing as well, since it is often difficult to deploy new features, because they sometimes break bad software (it was the case with the cookies of RFC 7873). Hence the current Internet Draft draft-ietf-dnsop-grease.

OK, so, let's grease the rusted parts of the Internet but where exactly, and how? DNS servers are basically of two kinds: resolver and authoritative servers. The version -00 of the draft only mentions resolvers because they are in the best place to test greasing and to report what broke. The general idea is that the resolver sends its queries with "unexpected" values (unallocated EDNS options, unallocated EDNS flags, etc, all of them "legal" according to the RFC). If it receives no reply from the authoritative server (or a bad one such as FORMERR), and, if retrying without greasing work, the resolver knows there is a problem in the path to this authoritative name server and can log it and/or report it (for instance through RFC 9567). The remaining question is: what we can grease? We need options that are legal to send but new and unexpected. For plain DNS, there is no hope: there is only one remaining (unallocated) bit in the flags (RFC 1035, section 4.1.1) of the DNS query. So, it means we can grease only with EDNS stuff: EDNS version number, EDNS options, and EDNS flags. For instance, unknown EDNS options are supposed to be ignored (otherwise, it would never be possible to deploy new options). Now, how to choose the unallocated values to send? TLS decided to reserve ranges of values for which to choose randomly. The risk is that some bad software will treat this range in a special way but, at least, it guarantees there will be no collision with a future allocation.

This is the current version (-00) of the draft. Now, the work at the hackahton. First, I decided to work on an authoritative server. A priori, it is less useful than a resolver, because, unlike the resolver, the authoritative name server cannnot know if its reply was accepted or not, or created problems. But it could be useful on test zones, to see (for instance through the use of RIPE Atlas probes) if they have resolution issues. The work was done on the software Drink.

First test, sending back in the reply two EDNS records. Sending two OPT records in a response does not seem forbidden by the RFC (which prohibit it only in a query, RFC 6891, section 6.1.1) but dig does not like it:

% dig +norec grease.courbu.re SOA @31.133.134.59
;; Warning: Message parser reports malformed message packet.

It creates problems with many other programs and it is not clear if it is legitimate so let's stop here.

Second test, sending an EDNS reply with a version number which is higher than the one requested. This is legal, the last paragraph of Section 6.1.3 of RFC 6891 says that a responder can respond with a higher EDNS version than what was requested by the requestor. (And it explains why, and the limits, for instance to keep the same format.) I tried that for DNS greasing and typical resolvers seem to be happy with it. But DNS testing tools (very useful tools, do not forget to tests your zones with them!) disagree. ednscomp says "expect: OPT record with version set to 0" (not greater-or-equal, stricly equal). DNSviz says "The server responded with EDNS version 1 when a request with EDNS version 0 was sent, instead of responding with RCODE BADVERS. See RFC 6891, Sec. 6.1.3." (We obviously do not read this section in the same way. To me, it mentions BADVERS only in a different context.) And Zonemaster also disagrees with me. So, there is a debate: when a responder knows both version 0 and some higher version (say, version 1), can it reply to a EDNS=0 query with a EDNS=1 response? Can we use that for greasing?

Less controversial, adding EDNS options and flags. You can see the result here:

% dig @192.168.41.237 grease.courbu.re SOA
; <<>> DiG 9.18.28-0ubuntu0.24.04.1-Ubuntu <<>> @192.168.41.237 grease.courbu.re SOA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61647
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 1, flags:; MBZ: 0x0072, udp: 1440
; OPT=16282: 58 ("X")
; OPT=17466: 58 58 58 58 58 58 58 58 58 ("XXXXXXXXX")
; OPT=18095: 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 ("XXXXXXXXXXXXXXXXXXX")
; OPT=16375: 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 ("XXXXXXXXXXXXXXXX")
; OPT=18: 06 72 65 70 6f 72 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 (".report.example.com.")
; COOKIE: db279863745c8e7198d4274c54233c48 (good)
;; QUESTION SECTION:
;grease.courbu.re.	IN SOA
;; ANSWER SECTION:
grease.courbu.re.	0 IN SOA dh*****-863b.meeting.ietf.org. root.invalid. (
				2024111007 ; serial
				1800 ; refresh (30 minutes)
				300 ; retry (5 minutes)
				604800 ; expire (1 week)
				86400 ; minimum (1 day)
				)
;; Query time: 1 msec
;; SERVER: 192.168.41.237#53(192.168.41.237) (UDP)
;; WHEN: Sun Nov 10 07:33:30 GMT 2024
;; MSG SIZE rcvd: 224

Here, the authoritative name server (a recent version of Drink,using the --greasing option at startup), sent:

  • A EDNS response with version 1 (remember current version is 0),
  • Four EDNS options with unallocated codes, with varying length and values (the last two options have allocated codes, even if dig knows only one, these two options are not greasing),
  • Unallocated EDNS flags set (the "0x0072").

Apparently, from tests with various resolver software and through RIPE Atlas probes, it does not break anything, thus paving the way for future allocations. Note that option codes, flags and the number of options are choosen at random, following the draft.

If you want to see the changes it required in the name server, this is this pull request.

Thanks to Shumon Huque and Mark Andrews for code, conversation and explanations.


L'article seul

Fiche de lecture : L'avenir d'Internet - unité ou fragmentation ?

Auteur(s) du livre : Clément Perarnaud, Julien Rossi, Francesca Musiani, Lucien Castex
Éditeur : Le bord de l'eau
9782385190682
Publié en 2024
Première rédaction de cet article le 9 novembre 2024


La fragmentation d'Internet est un sujet complexe, et souvent mal traité. Ce court livre fait le point sur les différentes questions que soulève ce débat et d'abord « qu'est-ce que c'est que la fragmentation ? » J'en recommande la lecture.

Le terme de fragmentation a en effet souvent été utilisé dans un but politique. Des influenceurs étatsuniens ont dit que le RGPD (ou le DSA), avec son application extra-territoriale, menait à une fragmentation de l'Internet. D'autres influenceurs étatsuniens (ou les mêmes) dénoncent toute activité de souveraineté numérique (imposer le stockage des données dans le pays, imposer que les échanges entre entités du pays restent dans le pays, etc) comme de la fragmentation. On entend souvent dire que les Chinois ou les Russes auraient « leur propre Internet » (ce qui n'a aucun sens). On se demande souvent si les gens qui répètent avec gourmandise qu'il y a fragmentation de l'Internet avec les actions russes ou chinoises le déplorent, ou bien s'ils voudraient que d'autres pays fassent pareil… Enfin, le débat est souvent marqué par l'hypocrisie comme lorsque les USA dénoncent le fait que le gouvernement chinois veuille empêcher ses citoyens d'aller sur Facebook alors que lui-même fait tout pour bloquer TikTok. En paraphrasant OSS 117, on pourrait dire « non, mais la fragmentation, c'est seulement quand les gens ont des manteaux gris et qu'il fait froid ».

Bref, le débat est mal parti. D'où l'importance de ce livre, qui est tiré d'un rapport au Parlement européen des mêmes auteurs, et qui étudie sérieusement les différents aspects de la question.

Déjà, première difficulté, définir la fragmentation. Est-ce lorsque une machine ne peut plus envoyer un paquet IP à une autre ? (La traduction d'adresses est-elle un facteur de fragmentation ?) Est-ce lorsque le résolveur DNS par défaut ne résout pas certains noms ? (Et si on peut en changer ?) Est-ce quand les Chinois n'utilisent pas les mêmes réseaux sociaux ou moteurs de recherche que nous ? (Ne riez pas, j'ai déjà entendu cette affirmation.) Bien des participant·es au début ne connaissent pas le B.A. BA du modèle en couches et n'essaient même pas de définir rigoureusement la fragmentation. Les auteur·es du livre s'attachent à examiner les définitions possibles. Non, ielles ne fournissent pas « la bonne définition », le problème est trop complexe pour cela. Il est sûr que tout·e utilisateurice de l'Internet ne voit pas la même chose et n'a pas le même vécu. Mais enfermer cette observation évidente dans une définition rigoureuse reste difficile.

D'un côté, disent les auteure·es, il y a bien des tendances centrifuges. De l'autre, non, l'Internet n'est pas fragmenté, malgré les affirmations de ceux qui tentent des prophéties auto-réalisatrices (comme le notent les auteur·es, le thème de la fragmentation et l'utilisation de termes journalistiques comme « splinternet » est souvent simplement une arme rhétorique). Mais est-ce que cela durera ?

Le livre détaille l'action des États qui pousse à la fragmentation, le jeu des lois du marché qui peut mener à la création de silos fermés (la fameuse « minitélisation de l'Internet »), etc.

Bon, une critique, quand même. Tout débat sur la politique Internet est forcément complexe car il faut à la fois comprendre la politique et comprendre Internet. Et, s'agissant de l'Internet, des faits de base (comme le pourcentage d'utilisateurs qui utilisent un résolveur DNS public) sont souvent difficiles à obtenir. Néanmoins, prétendre que dix sociétés résolvent la moitié des requêtes DNS au niveau mondial est impossible à croire. Le chiffre, cité p. 73, est tiré d'un article grossièrement anti-DoH qui ne cite pas ses sources. (Pour voir à quel point ce chiffre est invraisemblable, pensez simplement que toutes les études montrent que les résolveurs DNS publics sont une minorité des usages, et surtout que cela dépend des pays, les Chinois n'utilisant pas les mêmes que les Français et ielles sont nombreux.) L'usage de chiffres « au doigt mouillé » est malheureusement fréquent dans les débats de politique Internet.

Mais, bon, je l'ai dit, la question est très complexe, les données souvent dures à obtenir et cette critique ne doit pas vous empêcher d'apprendre tout sur le débat « fragmentation » dans cet excellent livre. Et rappelez-vous, l'avenir de l'Internet dépend aussi de vous.


L'article seul

RFC 9687: Border Gateway Protocol 4 (BGP-4) Send Hold Timer

Date de publication du RFC : Novembre 2024
Auteur(s) du RFC : J. Snijders (Fastly), B. Cartwright-Cox (Port 179), Y. Qu (Futurewei)
Chemin des normes
Première rédaction de cet article le 8 novembre 2024


Que doit faire un routeur BGP lorsque le pair en face ne traite manifestement plus ses messages ? Ce n'était pas précisé avant mais la réponse est évidente : raccrocher (mettre fin à la communication).

Un problème classique lors d'une connexion réseau, par exemple sur T*****, est de détecter si la machine en face est toujours là. Par défaut, T***** ne fournit pas ce service : s'il n'y a aucun trafic, vous ne pouvez pas savoir si votre partenaire est mort ou simplement s'il n'a rien à dire. Une coupure de réseau, par exemple, ne sera pas détectée tant que vous n'avez pas de trafic à transmettre (avec attente d'une réponse). Et BGP ne transmet que les changements donc l'absence de trafic ne signale pas forcément un problème. Il existe des solutions, comme d'envoyer périodiquement des messages même quand on n'a rien à dire (RFC 4271, section 4.4), mais aucune n'est parfaite : un programme qui utilise T***** ne sait typiquement pas immédiatement si ses messages sont vraiment partis (et l'alarme actuelle ne couvre que la réception des messages, pas leur envoi). Et BGP n'a pas de fonction « ping », qui exigerait une réponse.

Quand la coupure est franche et détectée, aucun problème, la session BGP (RFC 4271) s'arrête et les routes correspondantes sont retirées de la table de routage. Mais ce RFC traite le cas de où le routeur BGP d'en face a un problème mais qu'on ne détecte pas. Un exemple : si ce routeur en face a complètement fermé sa fenêtre T***** de réception (RFC 9293, notamment la section 3.8.6), on ne pourra pas lui envoyer de messages, mais la session BGP ne sera pas coupée et les paquets continueront à être transmis selon des annonces de routage dépassées, alors qu'ils finiront peut-être dans un trou noir (le problème des « zombies BGP »).

La solution (section 3 de notre RFC) est de modifier l'automate de BGP (RFC 4271, section 8), en ajoutant une alarme (RFC 4271, section 10), SendHoldTimer. Quand elle expire, on coupe la connexion T***** et on retire les routes qu'avait annoncé le pair dont on n'a plus de nouvelles. Le RFC recommande une configuration par défaut de huit minutes de patience avant de déclencher l'alarme.

L'erreur « Send Hold Timer Expired » est désormais dans le registre IANA des erreurs BGP et t*****dump sait l'afficher. Il existe plusieurs mises en œuvre de ce RFC :

Si les processus IETF vous passionnent, il y a une documentation des discussions autour de ce RFC.


Téléchargez le RFC 9687


L'article seul

RFC 9669: BPF Instruction Set Architecture (ISA)

Date de publication du RFC : Octobre 2024
Auteur(s) du RFC : D. Thaler
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF bpf
Première rédaction de cet article le 1 novembre 2024


On a souvent envie de faire tourner des programmes à soi dans le noyau du système d'exploitation, par exemple à des fins de débogage ou d'observation du système. Cela soulève plein de problèmes (programmer dans le noyau est délicat) et la technique eBPF permet, depuis de nombreuses années, de le faire avec moins de risques. Ce RFC spécifie le jeu d'instructions eBPF. Programmeureuses en langage d'assemblage, ce RFC est pour vous.

eBPF désigne ici un jeu d'instructions (comme ARM ou RISC-V). Programmer en eBPF, c'est donc programmer en langage d'assemblage et, en général, on ne le fait pas soi-même, on écrit dans un langage de plus haut niveau (non spécifié ici mais c'est souvent un sous-ensemble de C) et on confie à un compilateur le soin de générer les instructions. Ce jeu d'instructions a plusieurs particularités. Notamment, il est délibérément limité, puisque toute bogue dans le noyau est particulièrement sérieuse, pouvant planter la machine ou pire, permettre son piratage. Vous ne pouvez pas faire de boucles générales, par exemple. eBPF est surtout répandu dans le monde Linux (et c'est là où vous trouverez beaucoup de ressources) où il est une alternative aux modules chargés dans le noyau. Pas mal du code réseau d'Android est ainsi en eBPF. Normalisé ici, eBPF peut être mis en œuvre sur d'autres noyaux (il tourne sur Windows, par exemple). Le monde eBPF est très riche, il y a plein de logiciels (pas toujours faciles à utiliser), plein de tutoriels (pas toujours à jour et qui ne correspondent pas toujours à votre système d'exploitation) mais cet article se focalise sur le sujet du RFC : le jeu d'instructions.

On trouve de nombreux exemples d'utilisation en production par exemple le répartiteur de charge Katran chez Facebook, via lequel vous êtes certainement passé, si vous utilisez Facebook. En plus expérimental, j'ai trouvé amusant qu'on puisse modifier les réponses DNS en eBPF.

Passons tout de suite à la description de ce jeu d'instructions (ISA = Instruction Set Architecture). D'abord, les types (section 2.1) : u32 est un entier non signé sur 32 bits, s16, un signé sur 16 bits, etc. eBPF fournit des fonctions de conversions utiles (section 2.2) comme be16 qui convertit en gros boutien (le RFC cite IEN137…). Au passage, une mise en œuvre d'eBPF n'est pas obligée de tout fournir (section 2.4). La norme décrit des groupes de conformité et une implémentation d'eBPF doit lister quels groupes elle met en œuvre. Le groupe base32 (qui n'a rien à voir avec le Base32 du RFC 4648) est le minimum requis dans tous les cas. Par exemple, divmul32 ajoute multiplication et division. Tous ces groupes figurent dans un registre IANA.

Les instructions eBPF sont encodées en 64 ou 128 bits (section 3). On y trouve les instructions classiques de tout jeu, les opérations arithmétiques (comme ADD), logiques (comme AND), les sauts (JA, JEQ et autrs), qui se font toujours vers l'avant, pour, je suppose, ne pas permettre de boucles (souvenez-vous du problème de l'arrêt, qui n'a pas de solution avec un jeu d'instructions plus étendu), l'appel de fonction, etc.

En parlant de fonctions, eBPF ne peut pas appeler n'importe quelle fonction. Il y a deux sortes de fonctions utilisables, les fonctions d'aide (section 4.3.1), pré-définies par la plateforme utilisée, et non normalisées (pour celles de Linux, voir la documentation, qui est sous Documentation/bpf si vous avez les sources du noyau). Il y a aussi les fonctions locales (section 4.3.2), définies par le programme eBPF.

Il y a enfin des instructions pour lire et écrire dans la mémoire (LD, ST, etc). Pour mémoriser plus facilement, eBPF utilise des dictionnaires (maps, cf. section 5.4.1).

La section 6 concerne la sécurité, un point évidemment crucial puisque les programmes eBPF tournent dans le noyau, où les erreurs ne pardonnent pas. Un programme eBPF malveillant peut provoquer de nombreux dégâts. C'est pour cela que, sur Linux, seul root peut charger un tel programme dans le noyau. Le RFC recommande de faire tourner ces programmes dans un environnement limité (bac à sable), de limiter les ressources dont ils disposent et de faire tourner des vérifications sur le programme avant son exécution (par exemple, sur Linux, regardez cette documentation ou bien l'article « Simple and Precise Static Analysis of Untrusted Linux Kernel Extensions »).

Enfin, section 7, les registres (pas les registres du processeur, ceux où on enregistre les codes utilisés). Deux registres IANA sont créés, celui des groupes de conformité et celui du jeu d'instructions. L'annexe A du RFC donne les valeurs actuelles. Les registres sont extensibles et la politique d'enregistrement est « Spécification nécessaire » et « Examen par un expert », cf. RFC 8126. (J'avoue ne pas savoir pourquoi, si les opcodes sont enregistrés, les mnémoniques ne le sont pas, cela rend les registres difficiles à lire.)

Un peu d'histoire, au passage. eBPF est dérivé de BPF, ce qui voulait dire Berkeley Packet Filter, et était spécifique au filtrage des paquets réseau. Cet usage a été notamment popularisé par t*****dump. D'ailleurs, ce programme a une option pour afficher le code BPF produit :

% sudo t*****dump -d port 53
(000) ldh [12]
(001) jeq #0x86dd jt 2 jf 10
(002) ldb [20]
(003) jeq #0x84 jt 6 jf 4
(004) jeq #0x6 jt 6 jf 5
(005) jeq #0x11 jt 6 jf 23
(006) ldh [54]
…
(021) jeq #0x35 jt 22 jf 23
(022) ret #262144
(023) ret #0

Si vous voulez vous mettre à eBPF (attention, la courbe d'apprentissage va être raide), man 4 bpf est utile. Typiquement, vous écrirez vos programmes dans un sous-ensemble de C et vous compilerez en eBPF, par exemple avec clang, après avoir installé tous les outils et bibliothèques nécessaires (il faut souvent des versions assez récentes) :

% cat count.c
…
int count_packets(struct __sk_buff *skb) {
 __u32 key = 0; __u64 *counter;
 counter = bpf_map_lookup_elem(&pkt_counter, &key); if (counter) {
 (*counter)++; }
 return 0;}…
% clang -target bpf -c count.c
% file count.o
count.o: ELF 64-bit LSB relocatable, eBPF, version 1 (SYSV), not stripped
% objdump -d count.o
…
0000000000000000 <count_packets>:
 0:	7b 1a f8 ff 00 00 00 00 	stxdw [%r10-8],%r1
 8:	b7 01 00 00 00 00 00 00 	mov %r1,0
 10:	63 1a f4 ff 00 00 00 00 	stxw [%r10-12],%r1
 18:	18 01 00 00 00 00 00 00 	lddw %r1,0
 20:	00 00 00 00 00 00 00 00
 28:	bf a2 00 00 00 00 00 00 	mov %r2,%r10
 30:	07 02 00 00 f4 ff ff ff 	add %r2,-12

(Notez l'utilisation du désassembleur objdump.) Vous pouvez alors charger le code eBPF dans votre noyau, par exemple avec bpftool (et souvent admirer de beaux messages d'erreur comme « libbpf: elf: legacy map definitions in 'maps' section are not supported by libbpf v1.0+ »). Si tout fonctionne, votre code eBPF sera appelé par le noyau lors d'événements particuliers que vous avez indiqués (par exemple la création d'un processus, ou bien l'arrivée d'un paquet par le réseau) et fera alors ce que vous avez programmé. Un exemple d'utilisation d'eBPF pour observer ce que fait le noyau (ici avec un outil qui fait partie de bcc), on regarde les exec :

% sudo /usr/sbin/execsnoop-bpfcc
PCOMM PID PPID RET ARGS
check_disk 389622 1628 0 /usr/lib/nagios/plugins/check_disk -c 10% -w 20% -X none -X tmpfs -X sysfs -X proc -X configfs -X devtmpfs -X devfs -X
check_disk 389623 1628 0 /usr/lib/nagios/plugins/check_disk -c 10% -w 20% -X none -X tmpfs -X sysfs -X proc -X configfs -X devtmpfs -X devfs -X
check_swap 389624 1628 0 /usr/lib/nagios/plugins/check_swap -c 25% -w 50%
check_procs 389625 1628 0 /usr/lib/nagios/plugins/check_procs -c 400 -w 250
ps 389627 389625 0 /bin/ps axwwo stat uid pid ppid vsz rss p*****u etime comm args
sh 389632 389631 0 /bin/sh -c [ -x /usr/lib/php/sessionclean ] && if [ ! -d /run/systemd/system ]; then /usr/lib/php/sessionclean; fi
sessionclean 389633 1 0 /usr/lib/php/sessionclean
sort 389635 389633 0 /usr/bin/sort -rn -t: -k2,2
phpquery 389638 389634 0 /usr/sbin/phpquery -V
expr 389639 389638 0 /usr/bin/expr 2 - 1
sort 389642 389638 0 /usr/bin/sort -rn

Le code eBPF est interprété par une machine virtuelle ou bien traduit à la volée en code natif.

De nombreux exemples se trouvent dans le répertoire samples/bpf des sources du noyau Linux. (Le fichier README.rst explique comment compiler mais seulement dans le cadre de la compilation d'un noyau. En gros, c'est make menuconfig , cd samples/bpf puis make -i.) Un bon exemple, relativement simple, pour commencer avec le réseau est t*****_clamp_kern.c.

Si vous préférez travailler en Go (là aussi, avec un Go récent…), il existe un bon projet. Si vous suivez bien la documentation, vous pourrez compiler des programmes et les charger :

% go mod init ebpf-test
% go mod tidy
% go get github.com/cilium/ebpf/cmd/bpf2go
% go generate
% go build
% sudo ./ebpf-test
2024/08/20 15:21:43 Counting incoming packets on veth0..
…
2024/08/20 15:22:03 Received 25 packets
2024/08/20 15:22:04 Received 26 packets
2024/08/20 15:22:05 Received 27 packets
2024/08/20 15:22:06 Received 502 packets <- ping -f
2024/08/20 15:22:07 Received 57683 packets
2024/08/20 15:22:08 Received 75237 packets
^C2024/08/20 15:22:09 Received signal, exiting..

Vous trouverez beaucoup de ressources eBPF sur https://ebpf.io/. Et si vous voulez plonger dans les détails précis des choix de conception d'eBPF, je recommande ce document.

Ce RFC avait fait l'objet de pas mal de débats à l'IETF car, normalement, l'IETF ne normalise pas de langages de programmation ou de jeux d'instructions. (La première réunion était à l'IETF 116 en mars 2023 donc c'est quand même allé assez vite.)


Téléchargez le RFC 9669


L'article seul

RFC 9636: The Time Zone Information Format (TZif)

Date de publication du RFC : Octobre 2024
Auteur(s) du RFC : A.D. Olson, P. Eggert (UCLA), K. Murchison (Fastmail)
Chemin des normes
Première rédaction de cet article le 31 octobre 2024


Ce nouveau RFC documente un format déjà ancien et largement déployé, TZif, un format de description des fuseaux horaires. Il définit également des types MIME pour ce format, application/tzif et application/tzif-leap. Il remplace le premier RFC de normalisation de ce format, le RFC 8536, mais il y a très peu de changements. Bienvenue donc à la version 4 du format, spécifiée dans ce RFC.

Ce format existe depuis quarante ans (et a pas mal évolué pendant ce temps) mais n'avait apparemment jamais fait l'objet d'une normalisation formelle avant le RFC 8536 en 2019. La connaissance des fuseaux horaires est indispensable à toute application qui va manipuler des dates, par exemple un agenda. Un fuseau horaire se définit par un décalage par rapport à UTC, les informations sur l'heure d'été, des abréviations pour désigner ce fuseau (comme CET pour l'heure de l'Europe dite « centrale ») et peut-être également des informations sur les secondes intercalaires. Le format iCalendar du RFC 5545 est un exemple de format décrivant les fuseaux horaires. TZif, qui fait l'objet de ce RFC, en est un autre. Contrairement à iCalendar, c'est un format binaire.

TZif vient à l'origine du monde Unix et est apparu dans les années 1980, quand le développement de l'Internet, qui connecte des machines situées dans des fuseaux horaires différents, a nécessité que les machines aient une meilleure compréhension de la date et de l'heure. Un exemple de source faisant autorité sur les fuseaux horaires est la base de l'IANA décrite dans le RFC 6557 et dont l'usage est documenté à l'IANA. Pour la récupérer, voir par exemple le RFC 7808.

La section 2 de notre RFC décrit la terminologie du domaine :

  • Temps Universel Coordonné (UTC est le sigle officiel) : la base du temps légal. Par exemple, en hiver, la France métropolitaine est en UTC + 1. (GMT n'est utilisé que par les nostalgiques de l'Empire britannique.)
  • Heure d'été (le terme français est incorrect, l'anglais DST - Daylight Saving Time est plus exact) : le décalage ajouté ou retiré à certaines périodes, pour que les activités humaines, et donc la consommation d'énergie, se fassent à des moments plus appropriés (cette idée est responsable d'une grande partie de la complexité des fuseaux horaires).
  • Temps Atomique International (TAI) : contrairement à UTC, qui suit à peu près le soleil, TAI est déconnecté des phénomènes astronomiques. Cela lui donne des propriétés intéressantes, comme la prédictibilité (alors qu'on ne peut pas savoir à l'avance quelle sera l'heure UTC dans un milliard de secondes) et la monotonie (jamais de sauts, jamais de retour en arrière, ce qui peut arriver à UTC). Cela en fait un bon mécanisme pour les ordinateurs, mais moins bon pour les humains qui veulent organiser un pique-nique. Actuellement, il y a 37 secondes de décalage entre TAI et UTC.
  • Secondes intercalaires : secondes ajoutées de temps en temps à UTC pour compenser les variations de la rotation de la Terre.
  • Correction des secondes intercalaires : TAI - UTC - 10 (lisez le RFC pour savoir pourquoi 10). Actuellement 27 secondes.
  • Heure locale : l'heure légale en un endroit donné. La différence avec UTC peut varier selon la période de l'année, en raison de l'heure d'été. En anglais, on dit aussi souvent « le temps au mur » (wall time) par référence à une horloge accrochée au mur. Quand on demande l'heure à M. Toutlemonde, il donne cette heure locale, jamais UTC ou TAI ou le temps Unix.
  • Epoch : le point à partir duquel on compte le temps. Pour Posix, c'est le 1 janvier 1970 à 00h00 UTC.
  • Temps standard : la date et heure « de base » d'un fuseau horaire, sans tenir compte de l'heure d'été. En France métropolitaine, c'est UTC+1.
  • Base de données sur les fuseaux horaires : l'ensemble des informations sur les fuseaux horaires (cf. par exemple RFC 7808). Le format décrit dans ce RFC est un des formats possibles pour une telle base de données.
  • Temps universel : depuis 1960, c'est équivalent à UTC, mais le RFC préfère utiliser UT.
  • Temps Unix : c'est ce qui est renvoyé par la fonction time(), à savoir le nombre de secondes depuis l'epoch, donc depuis le 1 janvier 1970. Il ne tient pas compte des secondes intercalaires, donc il existe aussi un « temps Unix avec secondes intercalaires » (avertissement : tout ce qui touche au temps et aux calendriers est compliqué). C'est ce dernier qui est utilisé dans le format TZif, pour indiquer les dates et heures des moments où se fait une transition entre heure d'hiver et heure d'été.

La section 3 de notre RFC décrit le format lui-même. Un fichier TZif est composé d'un en-tête (taille fixe de 44 octets) indiquant entre autres le numéro de version de TZif. La version actuelle est 4. Ensuite, on trouve les données. Dans la version 1 de TZif, le bloc de données indiquait les dates de début et de fin des passages à l'heure d'été sur 32 bits, ce qui les limitait aux dates situées entre 1901 et 2038. Les versions ultérieures de TZif sont passées à 64 bits, ce qui permet de tenir environ 292 milliards d'années mais le bloc de données de la version 1 reste présent, au cas où il traine encore des logiciels ne comprenant que la version 1. Notez que ces 64 bits permettent de représenter des dates antérieures au Big Bang, mais certains logiciels ont du mal avec des valeurs situées trop loin dans le passé.

Les versions 2, 3 et 4 ont un second en-tête de 44 octets, et un bloc de données à elles. Les vieux logiciels arrêtent la lecture après le premier bloc de données et ne sont donc normalement pas gênés par cet en-tête et ce bloc supplémentaires. Les logiciels récents peuvent sauter le bloc de données de la version 1, qui ne les intéresse a priori pas (voir section 4 et annexe A). C'est au créateur du fichier de vérifier que les blocs de données destinés aux différentes versions sont raisonnablement synchrones, en tout cas pour les dates antérieures à 2038.

Nouveauté apparue avec la version 2, il y a aussi un pied de page à la fin. Les entiers sont stockés en gros boutien, et en complément à deux. L'en-tête commence par la chaîne magique « TZif » (U+0054 U+005A U+0069 U+0066), et comprend la longueur du bloc de données (qui dépend du nombre de transitions, de secondes intercalaires et d'autres informations à indiquer). Le bloc de données contient la liste des transitions, le décalage avec UT, le nom du fuseau horaire, la liste des secondes intercalaires, etc. Vu par le mode hexadécimal d'Emacs, voici le début d'un fichier Tzif version 2 (pris sur une Ubuntu, dans /usr/share/zoneinfo/Europe/Paris). On voit bien la chaîne magique, puis le numéro de version, et le début du bloc de données :

00000000: 545a 6966 3200 0000 0000 0000 0000 0000 TZif2...........
00000010: 0000 0000 0000 000d 0000 000d 0000 0000 ................
00000020: 0000 00b8 0000 000d 0000 001f 8000 0000 ................
00000030: 9160 508b 9b47 78f0 9bd7 2c70 9cbc 9170 .`P..Gx...,p...p
00000040: 9dc0 48f0 9e89 fe70 9fa0 2af0 a060 a5f0 ..H....p..*..`..
...

Avec od, ça donnerait :

% od -x -a /usr/share/zoneinfo/Europe/Paris
0000000 5a54 6669 0032 0000 0000 0000 0000 0000
 T Z i f 2 nul nul nul nul nul nul nul nul nul nul nul
0000020 0000 0000 0000 0d00 0000 0d00 0000 0000
 nul nul nul nul nul nul nul cr nul nul nul cr nul nul nul nul
0000040 0000 b800 0000 0d00 0000 1f00 0080 0000
 nul nul nul 8 nul nul nul cr nul nul nul us nul nul nul nul
0000060 6091 8b50 479b f078 d79b 702c bc9c 7091
 dc1 ` P vt esc G x p esc W , p fs < dc1 p
...

Des exemples détaillés et commentés de fichiers TZif figurent en annexe B. À lire si vous voulez vraiment comprendre les détails du format.

Le pied de page indique notamment les extensions à la variable d'environnement TZ. Toujours avec le mode hexadécimal d'Emacs, ça donne :

00000b80: 4345 542d 3143 4553 542c 4d33 2e35 2e30 CET-1CEST,M3.5.0
00000b90: 2c4d 3130 2e35 2e30 2f33 0a ,M10.5.0/3.

On a vu que le format TZif avait une histoire longue et compliquée. La section 4 du RFC est entièrement consacrée aux problèmes d'interopérabilité, liés à la coexistence de plusieurs versions du format, et de beaucoup de logiciels différents. Le RFC conseille (sections 4 et 5) :

  • De ne plus générer de fichiers suivant la version 1, qui ne marchera de toute façon plus après 2038.
  • Les logiciels qui en sont restés à la version 1 doivent faire attention à arrêter leur lecture après le premier bloc (dont la longueur figure dans l'en-tête).
  • La version 4 n'apporte pas beaucoup par rapport à la 2 et à la 3 et donc, sauf si on utilise les nouveautés spécifiques de la 4, il est recommandé de produire plutôt des fichiers conformes à la version 2 ou 3.
  • Un fichier TZif transmis via l'Internet devrait être étiqueté application/tzif-leap ou application/tzif (s'il n'indique pas les secondes intercalaires). Ces types MIME sont désormais dans le registre officiel (cf. section 9 du RFC).

L'annexe A du RFC en rajoute, tenant compte de l'expérience accumulée ; par exemple, certains lecteurs de TZif n'acceptent pas les noms de fuseaux horaires contenant des caractères non-ASCII et il peut donc être prudent de ne pas utiliser ces caractères. Plus gênant, il existe des lecteurs assez bêtes pour planter lorsque des temps sont négatifs. Or, les entiers utilisant dans TZif sont signés, afin de pouvoir représenter les moments antérieurs à l'epoch. Donc, attention si vous avez besoin de données avant le premier janvier 1970, cela perturbera certains logiciels bogués.

En parlant des noms de fuseaux horaires, le RFC rappelle (section 5) que le sigle utilisé dans le fichier Tzif (comme « CET ») est en anglais et que, si on veut le traduire, cela doit être fait dans l'application, pas dans le fichier. Le RFC donne comme exemple CST, qui peut être présenté comme « HNC », pour « Heure Normale du Centre ».

Autre piège avec ces sigles utilisés pour nommer les fuseaux horaires : ils sont ambigus. PST peut être la côte Ouest des USA mais aussi l'heure du Pakistan ou des Philippines.

La section 7 du RFC donne quelques conseils de sécurité :

  • L'en-tête indique la taille des données mais le programme qui lit le fichier doit vérifier que ces indications sont correctes, et n'envoient pas au-delà de la fin du fichier.
  • TZif, en lui-même, n'a pas de mécanisme de protection de l'intégrité, encore moins de mécanisme de signature. Il faut fournir ces services extérieurement (par exemple avec curl, en récupérant via HTTPS).

Enfin, l'annexe C du RFC liste les changements depuis le RFC 8536, changements qui mènent à cette nouvelle version, la 4. Rien de crucial mais :

  • Formalisation de l'ancienne convention comme quoi un décalage de « - 0 » avec UTC indique qu'on ne connait pas le vrai décalage.
  • Correction de plusieurs erreurs.

Une bonne liste de logiciels traitant ce format figure à l'IANA.


Téléchargez le RFC 9636


L'article seul

RFC 9311: Running an IETF Hackathon

Date de publication du RFC : Septembre 2022
Auteur(s) du RFC : C. Eckel (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF shmoo
Première rédaction de cet article le 31 octobre 2024


L'IETF, l'organisation qui normalise les protocoles de l'Internet a toujours prôné le pragmatisme et le réalisme : ce n'est pas tout d'écrire des normes, il faut encore qu'elles fonctionnent en vrai. Un des outils pour cela est le hackathon qui se déroule traditionnellement le week-end avant les réunions physiques de l'IETF. Ce RFC, écrit par le responsable de ces hackathons, décrit l'organisation de ces événements.

La salle (en cours d'installation) du hackathon à Yokohama en 2023 : hackathon-yokohama.jpg

Paradoxalement, alors que cette ambition de réalisme (« we believe in rough consensus and running code ») est ancienne à l'IETF, les hackathons sont relativement récents. Le premier était en 2015 à Dallas. Mais les hackathons font désormais partie de la culture IETF et on n'imagine plus de réunion sans eux. Ils accueillent désormais systématiquement plusieurs centaines de participant·es (cf. section 6 du RFC). (Mon premier était à Chicago.) Au passage, si vous êtes programmeur·se et que vous allez à une réunion IETF, ne ratez pas le hackathon, il en vaut la peine. Le prochain commence ce samedi, le 2 novembre 2024, à Dublin.

Donc, le but du hackathon à l'IETF (section 1 du RFC) est de tester les normes en cours d'élaboration, de voir si la future spécification est claire et réaliste, et de faire en sorte que les gens qui écrivent les normes (qui ne sont pas forcément des développeur·ses) interagissent avec ceux et celles qui mettent en œuvre les normes. (Cela peut paraitre étonnant, mais beaucoup de SDO ne fonctionnent pas comme cela ; la norme est écrite par des gens qui sont très loin du terrain et qui se moquent du caractère réaliste et effectif de leurs textes.) Le code qui tourne est souvent plus significatif qu'une opinion exprimée pendant la réunion. Et le hackathon est aussi l'occasion de travailler en commun (surtout si on est présent·e physiquement), ce qui fait avancer les projets.

Ah, et puisqu'on parle de collaboration, contrairement à certains hackathons, ceux de l'IETF n'ont plus aucune forme de compétition : pas de classement, pas de prix. (Voir la section 7.6 sur le rôle qu'avaient les juges de la compétition et pourquoi cela a été vite supprimé.) En outre, la plupart du code écrit pendant les hackathons est sous une licence libre (la principale exception concerne les gens qui ont modifié un logiciel privateur, par exemple le code de certains routeurs). Du point de vue « juridique », notez que le hackathon est un événement de l'IETF et donc soumis aux règles IETF (voir aussi la section 5.3).

Les hackathons de l'IETF sont gratuits (et il n'est pas forcément nécessaire de payer son voyage, on peut le faire à distance, voir plus loin) et ouverts à tous (cf. section 5.3). On s'inscrit en ligne puis on y va. Si vous êtes débutant·e, ne vous inquiétez pas, on a tous été débutant·es et les hackathons sont justement l'occasion de mêler étudiant·es, expert·es, etc. Une large participation est encouragée.

Comment organise t-on un tel événement ? Charles Eckel, l'auteur du RFC, est pour l'instant le pilier de ces hackathons. Le RFC a été écrit, entre autres, pour transmettre son expérience et permette à d'autres de le seconder ou de lui succéder. La section 2 du RFC détaille les choix effectués. Le hackathon se tient le week-end pour faciliter la participation des gens qui travaillent, notamment de ceux et celles qui ne viennent pas à la réunion IETF la semaine suivante. Et puis ça renforce le côté informel.

Questions horaires, le hackathon de l'IETF n'essaie pas de faire travailler les gens 24 heures sur 24 tout le week-end. La majorité des participant·es au hackathon viennent à l'IETF ensuite et doivent donc rester frai·ches. Le hackathon dure typiquement le samedi de 09:00 à 22:00 et le dimanche de 09:00 à 16:00 (il y a déjà des réunions IETF le dimanche en fin d'après-midi). Si des gens veulent travailler toute la nuit, ielles doivent le faire dans leur chambre.

La nourriture est fournie sur place pour éviter qu'on doive sortir (mais on a évidemment le droit de sortir, les participant·es ne sont pas attaché·es et peuvent estimer plus important d'aller discuter avec d'autres participant·es en dehors du hackathon). Et, comme le note le RFC, c'est une motivation supplémentaire pour faire venir les gens (on mange bien).

Et pour les gens qui sont à distance ? Le problème avait commencé à se poser pour la réunion IETF 107 prévue à Vancouver et annulée au dernier moment pour cause de Covid. Il y avait eu un effort pour maintenir un hackathon en distanciel mais cela n'avait pas intéressé grand'monde. (Un des plus gros problèmes du distanciel est le décalage horaire. Les gens qui n'étaient pas en PST n'avaient montré aucun enthousiasme pour le hackathon.) Cela s'est mieux passé par la suite, avec des réunions entièrement en ligne pendant la pandémie. Aujourd'hui, les réunions ont repris en présentiel mais une partie des participant·es, aussi bien à l'IETF qu'au hackathon, sont à distance. (Mon opinion personnelle est que c'est peu utile ; l'intérêt du hackathon est la collaboration intense avec les gens qui sont juste là. En travaillant à distance, on perd cette collaboration. Autant travailler tout seul dans son coin.) Une approche intermédiaire, très utilisée à Maurice, est d'avoir une réunion en présentiel locale, où les gens travaillent à distance sur le hackathon. Cela permet de garder un côté collectif sympa.

Tout cela (à commencer par les repas, et bien sûr la salle, mais elle est parfois incluse dans le contrat global de l'IETF pour sa réunion) coûte de l'argent. La section 3 décrit les sources de financement, qui permettent de garder le hackathon gratuit pour les participant·es. Il y a, comme souvent dans les conférences techniques, des sponsors. (Pour le prochain hackathon, ce seront Ericsson, Meta et l'ICANN.) Mais il y a aussi un financement par l'IETF elle-même (car on ne trouve pas toujours des sponsors). Le RFC précise même quels repas seront sacrifiés s'il n'y a pas assez d'argent (le diner du samedi est considéré comme moins important que les déjeuners, car les participant·es pourront toujours diner en rentrant).

Ah, et les T-shirts ? Pas de hackathon sans T-shirt. Le RFC donne des statistiques intéressantes, comme la répartition par taille aux précédents hackathons.

La participation à distance dispense du coût des repas mais il faut ajouter celle des systèmes de communication utilisés, notamment Meetecho et Gather. (Avant de proposer un autre système, rappelez-vous qu'il y a des centaines de participant·es actif·ves au hackathon et qu'il faut une solution qui tienne la charge.)

À la fin du hackathon, les participant·es présentent leur travail, les résultats obtenus et les conclusions qu'on peut en tirer pour les normes en cours de développement (section 4). Au début, il y avait également une session de présentation des projets au début du hackathon mais elle a dû être abandonnée au fur et à mesure que le hackathon grossissait. La présentation initiale se fait désormais sur le Wiki (voir par exemple la prochaine et la page où on peut aller si on cherche une équipe ou bien des volontaires). C'est sur ce Wiki que les champions (les gens qui ont une idée et organisent une activité particulière au hackathon, cf section 7.4) essaient de recruter. Quant aux présentations finales, elles sont publiées sur Github. C'est aussi là qu'on trouvera le code produit lorsqu'il n'est pas sur un dépôt extérieur (section 5.6).

La liste des projets affichés dans la salle du hackathon de Yokohama en 2023 : hackathon-projets.jpg

On a parlé des outils utilisés, lors de la section sur le financement. La section 5 dresse une liste plus complète des outils logiciels qui servent pour le hackathon. Il y a évidemment, comme pour tout travail IETF, le Datatracker (qui a une section sur le hackathon). Tout aussi évidemment, puisque l'IETF travaille largement avec des listes de diffusion, il y a une liste des participant·es au hackathon.

Pour profiter de tous ces outils, il faut un réseau à forte capacité, fiable, et évidemment sans aucun filtrage. Lors de la réunion de Beijing, les négociations avec les autorités avaient été serrées et l'accord final imposait un contrôle d'accès aux salles de l'IETF, pour éviter que des citoyens chinois n'en profitent. (Normalement, il n'y a aucun contrôle à l'entrée de l'IETF, personne ne vérifie les badges.) Le groupe qui s'occupe de monter et de démonter le réseau de l'IETF a donc en plus la charge du réseau du hackathon. Celui-ci peut en outre nécessiter des services spéciaux, afin de tester en présence de tels services (NAT64, prefix delegation, etc). Il y a même un accès VPN, pour celles et ceux qui travaillent à distance.


Téléchargez le RFC 9311


L'article seul

RFC 9673: IPv6 Hop-by-Hop Options Processing Procedures

Date de publication du RFC : Octobre 2024
Auteur(s) du RFC : R. Hinden (Check Point Software), G. Fairhurst (University of Aberdeen)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 31 octobre 2024


Parmi les différentes options qui peuvent être placées dans un en-tête d'un paquet IPv6, certaines sont à traiter par chaque routeur situé sur le trajet. On les appelle les options « par saut » (hop-by-hop). Elles sont très peu utilisées en pratique, entre autres parce que leur traitement, tel que spécifié dans le RFC 8200, est trop contraignant pour les routeurs. Ce nouveau RFC change donc les règles, dans le sens d'un plus grand pragmatisme.

À part l'en-tête « Hop-by-hop Options » (RFC 8200, section 4.3), tous les en-têtes IPv6 ne concernent que les machines terminales. « Hop-by-hop Options », lui, concerne les routeurs et, avant le RFC 8200, tous les routeurs sur le trajet avaient l'obligation de le lire et d'agir en fonction des options qu'il contenait (la liste complète des options possibles est dans un registre IANA). Bien trop coûteuse pour les routeurs, cette obligation a été supprimée par le RFC 8200. Ce nouveau RFC 9673 modifie le traitement des options de cet en-tête (et donc le RFC 8200) dans l'espoir qu'il voit enfin un vrai déploiement dans l'Internet (actuellement, cet en-tête par saut - hop-by-hop - est quasiment inutilisé). Si vous concevez des routeurs, et êtes pressé·e, sautez directement à la section 5 du RFC, qui décrit les nouvelles règles, mais ce serait dommage.

Petite révision sur l'architecture des routeurs (section 3 du RFC). Les routeurs de haut de gamme ont une voie rapide (fast path) pour le traitement des paquets, lorsque ceux-ci n'ont pas de demande particulière. Mise en œuvre en dehors du processeur principal du routeur, cette voie rapide est traitée par des circuits spécialisés, typiquement des ASIC. Si le paquet nécessite des opérations plus complexes, on passe par une voie plus lente, utilisant des méthodes et du matériel plus proches de ceux d'un ordinateur classique. (Les RFC 6398 et RFC 6192 sont des lectures recommandées ici.) D'autre part, on distingue souvent, dans le routeur, la transmission (forwarding plane) et le contrôle (control plane). La transmission est le travail de base du routeur (transmettre les paquets reçus sur une interface via une autre interface, et le plus vite possible), le contrôle regroupe notamment les opérations de manipulation de la table de routage, par exemple lors de mises à jour reçues via des protocoles comme OSPF ou BGP. Contrairement à la transmission, le contrôle n'est pas en « temps réel ».

Aujourd'hui, un paquet IPv6 utilisant des options par saut risque fort de ne même pas arriver à destination, sacrifié par des routeurs qui ne veulent pas le traiter. (Voir le RFC 7872, l'exposé « Internet Measurements: IPv6 Extension Header Edition » ou l'article « Is it possible to extend IPv6? ».)

Que disent donc les nouvelles procédures (section 5) ?

  • Un routeur ne devrait pas jeter un paquet uniquement parce que celui-ci contient l'en-tête par saut (voir aussi RFC 9288). Même si le routeur ne traite pas les options de cet en-tête, il devrait transmettre le paquet.
  • Il est très recommandé que les routeurs disposent d'une option de configuration permettant d'indiquer s'il faut ou non traiter les options par saut. Et d'une autre pour indiquer quelles options dans l'en-tête doivent être gérées, que cela ne soit pas du tout ou rien.
  • IPv6 dispose de deux bits dans chaque option par saut pour indiquer le traitement souhaité du paquet si le routeur ne connait pas l'option. La nouvelle procédure permet d'être plus indulgent et, par exemple, de ne pas jeter un paquet même si l'émetteur le demandait, si le routeur ne veut pas traiter cette option (cf. le premier item de cette liste de règles).
  • Les émetteurs qui mettent l'en-tête par saut dans les paquets doivent être bien conscients que tous les routeurs ne le traiteront pas (c'est le cas depuis longtemps, le RFC ne fait que décrire cet état de fait).
  • Les machines terminales devraient examiner cet en-tête et le traiter, il ne concerne pas que les routeurs.

Pour faciliter la tâche des routeurs, et toujours dans l'espoir que les options par saut deviennent enfin une possibilité réaliste, la section 6 du RFC encadre la définition de nouveaux en-têtes (le RFC 8200 recommandait carrément de ne plus en définir, tant qu'on n'avait pas mieux défini leur utilisation). Les éventuelles futures options doivent être simples à traiter et conçues en pensant au travail qu'elles imposeront au routeur. Le protocole qui les utilise doit intégrer le fait que le routeur est autorisé à ignorer cette option, voire qu'il puisse jeter le paquet.

Ah, et un mot sur la sécurité (section 8). Plusieurs RFC ont déjà documenté les problèmes de sécurité que peuvent poser les options par saut, notamment le risque qu'elles facilitent une attaque par déni de service sur le routeur : RFC 6398, RFC 6192, RFC 7045 et RFC 9098.

Est-ce que le déploiement de ce RFC va améliorer les choses pour l'en-tête par saut, qui est jusqu'à présent un exemple d'échec ? Je suis assez pessimiste, étant donné la difficulté à changer des comportements bien établis.

Un peu d'histoire pour terminer (section 4 du RFC) : les premières normes IPv6 (RFC 1883, puis RFC 2460) imposaient à tous les routeurs d'examiner et de traiter les options par saut. Le RFC 7045 avait été le premier à constater que cette règle n'était pas respectée et ne pouvait pas l'être vu l'architecture des routeurs modernes. Le problème de performance dans le traitement des options était d'autant plus grave que les options n'avaient pas toutes le même format (cela a été résolu par le RFC 6564, qui imposait un format unique). Le résultat, comme vu plus haut, était que les routeurs ignoraient les options par saut ou, pire, jetaient le paquet qui les contenait. (Le RFC 9288 et l'article « Threats and Surprises behind IPv6 Extension Headers » expliquent pourquoi c'est une mauvaise idée. L'Internet Draft draft-ietf-v6ops-hbh discute également cette question.)


Téléchargez le RFC 9673


L'article seul

RFC 9680: Antitrust Guidelines for IETF Participants

Date de publication du RFC : Octobre 2024
Auteur(s) du RFC : J. M. Halpern (Ericsson), J. Daley (IETF Administration LLC)
Pour information
Première rédaction de cet article le 31 octobre 2024


Les normes publiées par l'IETF ne sont pas que des documents techniques à seule destination des techniciens. L'Internet et, de manière plus générale, les protocoles T*****/IP sont aussi une grosse industrie qui brasse beaucoup d'argent. Il y a donc un risque que des acteurs de cette industrie essaient d'influencer les normes à leur profit, par exemple en formant des alliances qui, dans certains pays, seraient illégales au regard des lois antitrust. Ce court RFC administratif explique aux participant·es IETF ce que sont ces lois et comment éviter de les violer.

En effet, les organisations, notamment les entreprises à but lucratif, qui participent à l'IETF peuvent être concurrentes sur leurs marchés. Or, le développement de normes nécessite de la collaboration entre ces concurrents. Pour maintenir une concurrence et pour éviter les ententes, plusieurs pays ont des lois, dites « antitrust », lois que des participant·es à l'IETF ne connaissent pas forcément bien. La justification idéologique de ces lois est rappelée par le RFC, dans le cas étatsunien mais d'autres pays capitalistes ont des principes similaires : « Competition in a free market benefits consumers through lower prices, better quality and greater choice. Competition provides businesses the opportunity to compete on price and quality, in an open market and on a level playing field, unhampered by anticompetitive restraints. » Que ce soit vrai ou pas, peu importe, les lois antitrust doivent être respectées. Ce RFC n'édicte pas de règles pour l'IETF (« respectez la loi » est de toute façon déjà obligatoire), mais il explique des subtilités juridiques aux participant·es à l'IETF.

Il y a en effet deux risques pour l'IETF, qu'un·e représentant officiel de l'IETF soit accusé de comportement anti-concurrentiel, engageant la responsabilité de l'organisation, ou que des participant·es soient accusés de comportement anti-concurrentiel, ce qui n'engagerait pas la responsabilité de l'IETF mais pourrait affecter sa réputation.

Les participant·es à l'IETF sont censés suivre des règles dont certaines limitent déjà le risque de comportement anti-concurrentiel, entre autres :

Maintenant, s'y ajoutent les questions spécifiques au respect des lois sur la concurrence. La section 4, le cœur de ce RFC, attire l'attention sur :

  • La nécessité d'éviter de parler de certains sujets comme les prix des produits, les marges bénéficiaires, les accords avec des tiers, les analyses marketing, bref tout ce qui concerne le business, auquel le RFC ajoute les salaires et avantages divers (allez au bistrot le plus proche si vous voulez en parler librement). Des discussions sur ces sujets ne violent pas forcément les lois antitrust mais, dans le doute, mieux vaut être prudent.
  • L'importance de consulter un·e expert·e juridique en cas de doute. (L'IETF ne fournit pas de conseils juridiques.)
  • Le fait que les problèmes peuvent être signalés à l'équipe juridique de l'IETF ([email protected]) ou via le service spécifique pour les lanceurs d'alerte.

Téléchargez le RFC 9680


L'article seul

RFC 9536: Registration Data Access Protocol (RDAP) Reverse Search

Date de publication du RFC : Avril 2024
Auteur(s) du RFC : M. Loffredo, M. Martinelli (IIT-CNR/Registro.it)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 28 octobre 2024


Ce RFC normalise une extension au protocole d'accès à l'information RDAP pour permettre des recherches inversées, des recherches par le contenu (« quels sont tous les noms de domaine de cette personne ? »).

Alors, tout d'abord, un avertissement. L'extension normalisée dans ce RFC est dangereuse pour la vie privée. Je détaille ce point plus loin mais ne réclamez pas tout de suite le déploiement de cette extension : lisez tout d'abord. C'est dès sa section 1 que le RFC met en garde contre un déploiement hâtif !

RDAP (normalisé dans les RFC 9082 et RFC 9083), comme son prédécesseur whois, permet d'obtenir des informations dites sociales (nom, adresse, numéro de téléphone, etc) sur les personnes (morales ou physiques) associées à une ressource Internet réservée, comme un nom de domaine ou un adresse IP. Une limite importante de ces deux protocoles est qu'il faut connaitre l'identifiant (nom de domaine, adresse IP) de la ressource. Or, certaines personnes seraient intéressés à faire l'inverse, découvrir les ressources à partir d'informations sociales. C'est le cas par exemple de juristes cherchant le portefeuille de noms de domaine de quelqu'un qu'ils soupçonnent de menacer leur propriété intellectuelle. Ou de chercheurs en sécurité informatique étudiant toutes les adresses IP utilisées par le C&C d'un botnet et voulant en découvrir d'autres. Ce RFC normalise justement un moyen de faire des recherches inverses. whois n'avait jamais eu une telle normalisation, à cause des risques pour la vie privée, risques qui sont peut-être moins importants avec RDAP.

(Notez quand même que le RFC 9082, section 3.2.1, prévoyait déjà certaines recherches inverses, d'un domaine à partir du nom ou de l'adresse d'un de ses serveurs de noms.)

Passons aux détails techniques (section 2). L'URL d'une requête inverse va inclure dans son chemin /reverse_search et, bien sûr, des critères de recherche. Par exemple, /domains/reverse_search/entity?fn=Jean%20Durand&role=registrant donnera tous les domaines dont le titulaire (registrant) se nomme Jean Durand (fn est défini dans la section 6.2.1 du RFC 6350). Le terme après /reverse_search indique le type des données auxquelles s'appliquent les critères de recherche (actuellement, c'est forcément entity, une personne morale ou physique).

La plupart des recherches inverses porteront sans doute sur quelques champs comme l'adresse de courrier électronique ou le handle (l'identifiant d'une entité). La section 8 décrit les possibilités typiques mais un serveur RDAP choisit de toute façon ce qu'il permet ou ne permet pas.

La sémantique exacte d'une recherche inverse est décrite en JSONPath (RFC 9535). Vous trouvez le JSONPath dans la réponse (section 5 du RFC), dans le membre reverse_search_properties_mapping. Par exemple :

"reverse_search_properties_mapping": [
 {
 "property": "fn",
 "propertyPath": "$.entities[*].vcardArray[1][?(@[0]=='fn')][3]"
 }]

L'expression JSONPath $.entities[*].vcardArray[1][?(@[0]=='fn')][3] indique que le serveur va faire une recherche sur le membre fn du tableau vCard (RFC 7095). Oui, elle est compliquée, mais c'est parce que le format vCard est compliqué. Heureusement, on n'est pas obligé de connaitre JSONPath pour utiliser les recherches inverses, uniquement pour leur normalisation (section 3).

Pour savoir si le serveur RDAP que vous interrogez gère cette extension et quelles requêtes il permet, regardez sa réponse à la question help (RFC 9082, section 3.1.6, et RFC 9083, section 7) ; s'il accepte les requêtes inverses, vous y trouverez la valeur reverse_search dans le membre rdapConformance (section 9), par exemple :

"rdapConformance": [
 "rdap_level_0",
 "reverse_search"
]

Pour les recherches acceptées, regardez le membre reverse_search_properties. Par exemple :

"reverse_search_properties": [
 {
 "searchableResourceType": "domains",
 "relatedResourceType": "entity",
 "property": "fn"
 }]

Ici, le serveur indique qu'il accepte les requêtes inverses pour trouver des noms de domaine en fonction d'un nom d'entité (ce que nous avons fait dans l'exemple plus haut). Voir la section 4 pour les détails. Si vous tentez une requête inverse sur un serveur, et que le serveur n'accepte pas les requêtes inverses, ou tout simplement n'accepte pas ce type particulier de recherche inverse que vous avez demandé, il répondra avec le code de retour HTTP 501 (section 7). Vous aurez peut-être aussi un 400 si votre requête déplait au serveur pour une raison ou l'autre.

L'extension est désormais placée dans le registre des extensions RDAP. En outre, deux nouveaux registres sont créés, RDAP Reverse Search, pour les recherches possibles et RDAP Reverse Search Mapping pour les règles JSONPath. Pour y ajouter des valeurs, la politique (RFC 8126) est « spécification nécessaire ».

Revenons maintenant aux questions de vie privée (RFC 6973), que je vous avais promises. La section 12 du RFC détaille le problème. La puissance des recherches inverses les rend dangereuses. Une entreprise concurrente pourrait regarder vos noms de domaine et ainsi se tenir au courant, par exemple, d'un nouveau projet ou d'un nouveau produit. Un malveillant pourrait regarder les noms de domaine d'une personne et identifier ainsi des engagements associatifs que la personne ne souhaitait pas forcément rendre très visibles. Les données stockées par les registres sont souvent des données personnelles et donc protégées par des lois comme le RGPD. Le gestionnaire d'un serveur RDAP doit donc, avant d'activer la recherche inverse, bien étudier la sécurité du serveur (section 13) mais aussi (et ce point n'est hélas pas dans le RFC) se demander si cette activation est vraiment une bonne idée.

En théorie, RDAP pose moins de problème de sécurité que whois pour ce genre de recherches, car il repose sur HTTPS (le chiffrement empêche un tiers de voir questions et réponses) et, surtout, il permet l'authentification ce qui rend possible, par exemple, de réserver les recherches inverses à certains privilégiés, avec un grand choix de contrôle d'accès (cf. annexe A). Évidemment, cela laisse ouvertes d'autres questions comme « qui seront ces privilégiés ? » et « comment s'assurer qu'ils n'*****nt pas ? » (là, les journaux sont indispensables pour la traçabilité, cf. l'affaire Haurus).

Notons qu'outre les problèmes de vie privée, la recherche inverse pose également des problèmes de performance (section 10). Attention avant de la déployer, des requêtes apparemment innocentes pourraient faire ramer sérieusement le serveur RDAP. Si vous programmez un serveur RDAP ayant des recherches inverses, lisez bien les recommandations d'optimisation de la section 10, par exemple en ajoutant des index dans votre SGBD. Et le serveur ne doit pas hésiter, en cas de surcharge, à répondre seulement de manière partielle (RFC 8982 ou RFC 8977).

Je n'ai pas trouvé de code public mettant en œuvre ces recherches inverses. De même, je ne connais pas encore de serveur RDAP déployé qui offre cette possibilité.


Téléchargez le RFC 9536


L'article seul

Fiche de lecture : Quand les travailleurs sabotaient

Auteur(s) du livre : Dominique Pinsolle
Éditeur : Agone
978-2-7489-0563-2
Publié en 2024
Première rédaction de cet article le 28 octobre 2024


Aujourd'hui, le terme de « sabotage » renvoie uniquement à des activités sournoises et clandestines, non revendiquées officiellement. Mais, à une époque, le terme était ouvertement discuté dans certaines organisations ouvrières, et considéré par certains comme un moyen de lutte parmi d'autres. Ce livre revient sur l'histoire du concept de sabotage, notamment à propos des débats qu'il avait suscité dans le mouvement ouvrier.

C'est difficile de parler du sabotage aujourd'hui car le concept a été brouillé par les médias qui l'ont présenté systématiquement comme un acte destructeur, voire meurtrier. Or, lorsque le terme a été popularisé en France à la fin du XIXe siècle, c'était dans un sens triplement différent : il n'était pas forcément destructeur (le simple ralentissement de la cadence était inclus dans le sabotage), il était revendiqué publiquement et, surtout, il faisait l'objet de nombreuses discussions ayant pour but d'en fixer les limites (notamment le tabou de la violence contre les personnes). Car, à la Belle Époque, un syndicat comme la CGT pouvait ouvertement inscrire le sabotage dans ses résolutions votées au congrès.

Le livre se focalise sur deux moments de cette politisation du sabotage. L'acte lui-même est certainement bien plus ancien mais la nouveauté, due notamment à Pouget, était d'en faire un moyen de lutte collective, assumé comme tel.

Après la période française, la revendication publique du sabotage a connu une deuxième période, aux États-Unis, où l'IWW en faisait un de ses moyens d'action. (Le livre rappelle, et c'est très important, le contexte de la lutte de classes aux USA, marqué par une extrême violence patronale, avec utilisation fréquente de milices privées qui, elles, n'avaient aucun scrupule à utiliser la violence contre les personnes, et en toute impunité.) Le livre détaille ces deux périodes, et met l'accent sur les innombrables discussions politiques au sein du mouvement ouvrier autour du sabotage, de sa légitimité, de ses liens avec les autres formes de lutte et avec les travailleurs, des limites qu'on s'impose, et des risques, qu'ils soient d'accident, de débordement par des irresponsables, ou de difficulté à empêcher la diabolisation par les médias et les politiciens. À la fin, aussi bien la CGT que l'IWW ont renoncé à mentionner le sabotage, en partie à cause des difficultés qu'il y avait à l'expliquer aux travailleurs. (Et aussi à le contrôler : l'auteur cite Jaurès qui disait que le sabotage était la forme de lutte qu'il fallait le plus contrôler, alors qu'elle était aussi la plus difficile à contrôler.) Cela n'a pas mis fin au sabotage : l'auteur note qu'en France, il y a même eu davantage de sabotages après que la CGT l'ait retiré de son programme.

J'ai noté que l'auteur parlait très peu de la Résistance, un autre moment où le sabotage était assumé et glorifié. Mais c'est sans doute que, là, il n'y avait pas de débat : aucun résistant ne discutait la légitimité du sabotage sans limite. L'OSS les aidait même, avec son fameux « manuel du sabotage » (qui, il faut le rappeler, incluait aussi des méthodes non destructrices comme de ralentir le travail).

Pour d'autres périodes, l'auteur expose les différentes façons de pratiquer le sabotage, incluant par exemple la grève du zèle. Il cite l'exemple du « sabotage de la bouche ouverte » chez les serveurs de restaurant au début du XXe siècle : on sert le client mais on lui dit tout ce qu'il y a vraiment dans le plat servi. De nombreuses idées astucieuses de ce genre ont surgi dans le débat.

Le sabotage, qui était bien plus ancien que le livre de Pouget, reste toujours d'actualité, comme on l'a vu dans l'affaire de Tarnac (jamais élucidée, notamment en raison du comportement des enquêteurs qui, certains de tenir les coupables, ont bâclé l'enquête) ou dans les récentes attaques contre les liaisons Internet, là aussi non revendiquées. (Il y en avait eu aussi en avril 2022, cf. article de Numérama et article du Nouvel Obs.) On est à l'opposé des théories des « syndicalistes révolutionnaires » du XIXe siècle puisqu'on atteint le degré zéro de la politique : aucune idée sur les auteurs de ces coupures et leur but.


L'article seul

Fiche de lecture : Online virality - Spread and Influence

Auteur(s) du livre : Valérie Schafer, Fred Pailler
Éditeur : De Gruyter
978-3-11-131035-0
Publié en 2024
Première rédaction de cet article le 28 octobre 2024


Dans le contexte du Web, la viralité est un terme emprunté, évidemment, à l'épidémiologie, pour désigner une propagation rapide, de proche en proche, d'une information. En tant que phénomène social, elle peut être étudiée et c'est ce que fait ce livre collectif sur la viralité.

Bien des commerciaux et des politiciens se demandent tous les jours comment atteindre cet objectif idéal, la viralité, ce moment où les messages que vous envoyez sont largement repris et diffusés sans que vous ayiez d'effort à faire. Cela intéresse aussi évidemment les chercheur·ses en sciences humaines, d'où ce livre. (Et le projet HIVI, et le colloque qui aura lieu du 18 au 20 novembre 2024 à l'université du Luxembourg.) La version papier du livre coûte cher mais vous pouvez le télécharger légalement (le lien pour avoir tout le livre, et pas chapitre par chapitre, peut être difficile à voir : regardez en haut à droite).

Il y a de nombreux points à discuter dans la viralité et vous trouverez certainement dans ces études des choses intéressantes. Par exemple, le rôle des outils. Dans quelle mesure les programmes avec lesquels vous interagissez encouragent ou découragent la viralité ? Et, si le débat politique tourne en général exclusivement autour du rôle des GAFA et des mythifiés « algorithmes », il ne faut pas oublier que les médias traditionnels jouent aussi un rôle dans la viralité, en validant que telle ou telle information est « virale ».

N'oublions pas non plus que la viralité des informations n'est pas arrivée avec l'Internet. Le Kilroy was here des soldats étatsuniens de la deuxième guerre mondiale est un bon exemple de viralité avant les réseaux informatiques.

Mon chapitre préféré, dans ce livre, a été celui de Gastón Arce-Pradenas sur le succès viral et, souvent, la chute, de personnalités du mouvement chilien de 2019. Comme souvent dans un mouvement peu organisé (on pense évidemment aux gilets jaunes français, qui ont également vu ce genre de phénomène), des personnalités émergent sans mandat particulier, choisies par les médias, et/ou bénéficiant d'un succès viral, aidé par des techniques de communication spectaculaires, avant de trébucher rapidement. Ne ratez pas l'histoire du dinosaure bleu, par exemple, une des plus fascinantes. Vous aurez d'ailleurs d'autres perspectives internationales, par exemple du Brésil avec l'étude de Nazaré Confusa. La viralité ne concerne pas que les sujets étatsuniens.

Un peu de critique, toutefois : le livre est inégal, et certaines contributions n'ont pas de rapport direct avec la notion de viralité.

Et si le sujet vous fascine :


L'article seul

RFC 9558: Use of GOST 2012 Signature Algorithms in DNSKEY and RRSIG Resource Records for DNSSEC

Date de publication du RFC : Avril 2024
Auteur(s) du RFC : B. Makarenko (The Technical center of Internet, LLC), V. Dolmatov (JSC "NPK Kryptonite")
Pour information
Première rédaction de cet article le 21 octobre 2024


Ce RFC marque l'arrivée d'un nouvel algorithme de signature dans les enregistrements DNSSEC, algorithme portant le numéro 23. Bienvenue au GOST R 34.10-2012 (alias ECC-GOST12), algorithme russe, spécifié en anglais dans le RFC 7091, une légère mise à jour de GOST R 34.10-2001.

La liste des algorithmes DNSSEC est un registre à l'IANA, https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml#dns-sec-alg-numbers-1. Elle comprend désormais GOST R 34.10-2012 (qui succède au R 34.10-2001 du RFC 5933). Notez que GOST désigne en fait une organisation de normalisation, le terme correct serait donc de ne jamais dire « GOST » tout court, mais plutôt « GOST R 34.10-2012 » pour l'algorithme de signature et « GOST R 34.11-2012 » pour celui de condensation, décrit dans le RFC 6986 (voir la section 1 de notre RFC 9558).

La section 2 décrit le format des enregistrements DNSKEY avec GOST, dans lequel on publie les clés GOST R 34.10-2012. Le champ Algorithme vaut 23, le format de la clé sur le réseau suit le RFC 7091. GOST est un algorithme à courbes elliptiques, courbes décrites par Q = (x,y). Les 32 premiers octets de la clé sont x et les 32 suivants y (en petit-boutien, attention, contrairement à la majorité des protocoles Internet).

Parmi les bibliothèques cryptographiques existantes, au moins OpenSSL met en œuvre GOST R 34.10-2012 (testé avec la version 3.3.2). Voir RFC 9215 pour de l'aide à ce sujet. Sinon, on trouve parfois seulement l'ancienne version dans certains logiciels et certaines bibliothèques.

La section 2.2 donne un exemple de clé GOST publiée dans le DNS, je n'ai pas trouvé d'exemple réel dans la nature, même en .ru.

La section 3 décrit le format des enregistrements RRSIG, les signatures (avec un exemple). On suit les RFC 5958 et RFC 7091. Attention, une particularité de GOST fait que deux signatures des mêmes données peuvent donner des résultats différents, car un élément aléatoire est présent dans la signature.

La section 4 décrit le format des enregistrements DS pour GOST. La clé publique de la zone fille est condensée par GOST R 34.11-2012, algorithme de numéro 5.

Les sections 5 et 6 couvrent des questions pratiques liées au développement et au déploiement de systèmes GOST, par exemple un rappel sur la taille de la clé (512 bits) et sur celle du condensat cryptographique (256 bits).

GOST peut se valider avec Unbound si la bibliothèque de cryptographie utilisée gère GOST. Et, comme indiqué plus haut, ce ne sera sans doute que l'ancienne version, celle du RFC 5933. Pour les programmeurs Java, DNSjava a le dernier GOST depuis la version 3.6.2. Pour le statut (recommandé ou non) de l'algorithme GOST pour DNSSEC, voir le RFC 8624. En Python, dnspython en version 2.7.0 n'a que l'ancien algorithme.


Téléchargez le RFC 9558


L'article seul

RFC 9559: Matroska Media Container Format Specification

Date de publication du RFC : Octobre 2024
Auteur(s) du RFC : S. Lhomme, M. Bunkus, D. Rice
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF cellar
Première rédaction de cet article le 15 octobre 2024


Matroska est un format de conteneur pour du contenu multimédia (son, image, sous-titres, etc). Ce n'est pas un format de données (format utilisé par un codec), mais un moyen de regrouper de manière structurée des données différentes.

Je vous préviens tout de suite, le RFC fait 167 pages, et, en prime, le multimédia n'est pas ma spécialité. Donc, je vais faire court. Matroska est fondé sur un langage qui utilise le modèle de données XML, EBML (normalisé dans le RFC 8794). Notre nouveau RFC 9559 est donc surtout une très longue liste des éléments XML qu'on peut y trouver (Matroska est riche !), encodés en binaire. Matroska n'est pas nouveau (il en est à la version 4), mais c'est sa première normalisation. Notez que vous trouverez de l'information sur la page Web du projet.

Le caractère hiérarchique d'un fichier Matroska (des éléments dans d'autres éléments) est bien rendu par cet outil (qui fait partie de MKVToolNix, cité plus loin) :

% mkvinfo ./format/matroska/testdata/sweep-with-DC.mkvmerge13.mka
+ EBML head
|+ EBML version: 1
|+ EBML read version: 1
|+ Maximum EBML ID length: 4
|+ Maximum EBML size length: 8
|+ Document type: matroska
|+ Document type version: 4
|+ Document type read version: 2
+ Segment: size 18507
|+ Seek head (subentries will be skipped)
|+ EBML void: size 4031
|+ Segment information
| + Timestamp scale: 22674
| + Multiplexing application: libebml v1.4.2 + libmatroska v1.6.2
| + Writing application: mkvmerge v52.0.0 ('Secret For The Mad') 64-bit
| + Duration: 00:00:02.607714066
| + Date: 2022-08-28 18:32:21 UTC
| + Segment UID: 0x3b 0x9f 0x28 0xc7 0xc4 0x90 0x8a 0xe0 0xcd 0x66 0x8f 0x11 0x8f 0x7c 0x2f 0x54
|+ Tracks
| + Track
| + Track number: 1 (track ID for mkvmerge & mkvextract: 0)
| + Track UID: 3794791294650729286
| + Track type: audio
| + Codec ID: A_FLAC
| + Codec's private data: size 133
| + Default duration: 00:00:00.040634920 (24.609 frames/fields per second for a video track)
| + Language: und
| + Language (IETF B***** 47): und
| + Audio track
| + Sampling frequency: 44100
| + Bit depth: 16
|+ EBML void: size 1063
|+ Cluster

On voit un document de la version 4 (celle du RFC), commençant (forcément, cf. section 4.5 du RFC) par un en-tête EBML, et comportant une seule piste (l'élément Tracks est décrit en section 5.1.4), un son au format FLAC (RFC bientôt publié). L'extension .mka est souvent utilisée pour des conteneurs n'ayant que de l'audio (et .mkv s'il y a de la vidéo). La piste audio est dans une langue indéterminée, und. Plusieurs éléments existent pour noter la langue car Matroska n'utilisait autrefois que la norme ISO 639 mais la version 4 recommande les bien plus riches étiquettes de langue IETF (RFC 5646, alias « IETF B***** 47 »).

Un autre document a deux pistes, le son et l'image :

% mkvinfo ~/Videos/2022-01-22\ 13-17-28.mkv
…
|+ Tracks
| + Track
| + Track number: 1 (track ID for mkvmerge & mkvextract: 0)
| + Track UID: 1
| + "Lacing" flag: 0
| + Language: und
| + Codec ID: V_MPEG4/ISO/AVC
| + Track type: video
| + Default duration: 00:00:00.033333333 (30.000 frames/fields per second for a video track)
| + Video track
| + Pixel width: 852
| + Pixel height: 480
| + Display unit: 4
| + Codec's private data: size 41 (H.264 profile: High @L3.1)
| + Track
| + Track number: 2 (track ID for mkvmerge & mkvextract: 1)
| + Track UID: 2
| + "Lacing" flag: 0
| + Name: simple_aac_recording
| + Language: und
| + Codec ID: A_AAC
| + Track type: audio
| + Audio track
| + Channels: 2
| + Sampling frequency: 44100
| + Bit depth: 16
| + Codec's private data: size 5

L'arborescence des fichiers Matroska peut être très profonde et ça se reflète dans la numérotation des sections du RFC (il y a une section 5.1.4.1.28.18 !).

Les types MIME à utiliser sont audio/matroska et video/matroska (section 27.3 du RFC).

Il existe plusieurs mises en œuvre de Matroska en logiciel libre comme MKVToolNix, qui sait faire beaucoup de choses (comme afficher les éléments Matroska comme vu plus haut) et qui existe en ligne de commande ou GUI. Et VLC sait évidemment jouer les fichiers Matroska. OBS, quant à lui, permet d'en produire. Par exemple, cette vidéo sans intérêt a été faite avec OBS.


Téléchargez le RFC 9559


L'article seul

RFC 9660: The DNS Zone Version (ZONEVERSION) Option

Date de publication du RFC : Octobre 2024
Auteur(s) du RFC : H. Salgado (NIC Chile), M. Vergara (DigitalOcean), D. Wessels (Verisign)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 13 octobre 2024


Cette nouvelle option du DNS permet au client d'obtenir du serveur le numéro de version de la zone servie. (Et, non, le numéro de série dans l'enregistrement SOA ne suffit pas, lisez pour en savoir plus.)

Cela permettra de détecter les problèmes de mise à jour des serveurs faisant autorité si, par exemple, un des secondaires ne se met plus à jour. C'est surtout important pour l'anycast, qui complique le déboguage. En combinaison avec le NSID du RFC 5001, vous trouverez facilement le serveur qui a un problème. Cette nouvelle option ressemble d'ailleurs à NSID et s'utilise de la même façon.

Vous le savez, le DNS ne garantit pas que tous les serveurs faisant autorité d'une zone servent la même version de la zone au même moment. Si je regarde la zone .com à cet instant (14 juillet 2024, 09:48 UTC) avec check-soa, je vois :

% check-soa com
a.gtld-servers.net.
	2001:503:a83e::2:30: OK: 1720950475
	192.5.6.30: OK: 1720950475
b.gtld-servers.net.
	192.33.14.30: OK: 1720950475
	2001:503:231d::2:30: OK: 1720950475
c.gtld-servers.net.
	2001:503:83eb::30: OK: 1720950475
	192.26.92.30: OK: 1720950475
d.gtld-servers.net.
	2001:500:856e::30: OK: 1720950475
	192.31.80.30: OK: 1720950475
e.gtld-servers.net.
	2001:502:1ca1::30: OK: 1720950475
	192.12.94.30: OK: 1720950475
f.gtld-servers.net.
	2001:503:d414::30: OK: 1720950475
	192.35.51.30: OK: 1720950475
g.gtld-servers.net.
	192.42.93.30: OK: 1720950475
	2001:503:eea3::30: OK: 1720950475
h.gtld-servers.net.
	192.54.112.30: OK: 1720950475
	2001:502:8cc::30: OK: 1720950475
i.gtld-servers.net.
	2001:503:39c1::30: OK: 1720950460
	192.43.172.30: OK: 1720950475
j.gtld-servers.net.
	2001:502:7094::30: OK: 1720950475
	192.48.79.30: OK: 1720950475
k.gtld-servers.net.
	192.52.178.30: OK: 1720950460
	2001:503:d2d::30: OK: 1720950475
l.gtld-servers.net.
	192.41.162.30: OK: 1720950475
	2001:500:d937::30: OK: 1720950475
m.gtld-servers.net.
	2001:501:b1f9::30: OK: 1720950475
	192.55.83.30: OK: 1720950475

On observe que, bien que le numéro de série dans l'enregistrement SOA soit 1720950475, certains serveurs sont restés à 1720950460. Le DNS est « modérement cohérent » (RFC 3254, sur ce concept).

Dans l'exemple ci-dessus, check-soa a simplement fait une requête pour le type de données SOA (section 4.3.5 du RFC 1034). Une limite de cette méthode est que, si on observe des données d'autres types qui ne semblent pas à jour et que, pour vérifier, on fait une requête de type SOA, on n'a pas de garantie de tomber sur le même serveur, notamment en cas d'utilisation d'anycast (RFC 4786) ou bien s'il y a un répartiteur de charge avec plusieurs serveurs derrière. (D'ailleurs, dans l'exemple ci-dessus, vous avez remarqué que vous n'avez pas la même réponse en IPv4 et IPv6, probablement parce que vous arriviez sur deux instances différentes du nuage anycast.) Il faut donc un mécanisme à l'intérieur même de la requête qu'on utilise, comme pour le NSID. C'est le cas du ZONEVERSION de ce RFC, qui permet d'exprimer la version sous forme d'un numéro de série (comme avec le SOA) ou par d'autres moyens dans le futur, puisque toutes les zones n'utilisent pas le mécanisme de synchronisation habituel du DNS. On peut par exemple avoir des zones entièrement dynamiques et tirées d'une base de données, ou bien d'un calcul.

Notez aussi que certaines zones, comme .com, changent très vite, et que donc, même si on tombe sur le même serveur, le numéro de série aura pu changer entre une requête ordinaire et celle pour le SOA. C'est une raison supplémentaire pour avoir le mécanisme ZONEVERSION.

Bref, le nouveau mécanisme (section 2 du RFC), utilise EDNS (section 6.1.2 du RFC 6891). La nouvelle option EDNS porte le numéro 19. Encodée en TLV comme toutes les options EDNS, elle comprend une longueur et une chaine d'octets qui est la version de la zone. La longueur vaut zéro dans une requête (le client indique juste qu'il souhaite connaitre la version de la zone) et, dans la réponse, une valeur non nulle. La version est elle-même composée de trois champs :

  • Le nombre de composants dans le nom de domaine pour la zone concernée. Si la requête DNS portait sur le nom de domaine foo.bar.example.org et que le serveur renvoie la version de la zone example.org, ce champ vaudra deux.
  • Le type de la version. Différents serveurs faisant autorité utiliseront différentes méthodes pour se synchroniser et auront donc des types différents. Pour l'instant, un seul est normalisé, le 0 (alias SOA-SERIAL), qui est le numéro de série, celui qu'on trouverait dans le SOA, cf. section 3.3.13 du RFC 1035. La longueur sera donc de 6, les 4 octets de ce numéro, le type et le nombre de composants, un octet chacun. Un nouveau registre IANA accueillera peut-être d'autres types dans le futur, suivant la procédure « spécification nécessaire » du RFC 8126. (Cette procédure nécessite un examen par un expert, et la section 7.2.1 guide l'expert pour ce travail.)
  • La valeur à proprement parler.

Si vous voulez voir dans un pcap, regardez zoneversion.pcap.

L'option ZONEVERSION n'est renvoyée au client qui si celui-ci l'avait demandé, ce qu'il fait en mettant une option ZONEVERSION vide dans sa requête (section 3 du RFC). Si le serveur fait autorité pour la zone concernée (ou une zone ancêtre), et qu'il gère cette nouvelle option, il répond avec une valeur. Même si le nom demandé n'existe pas (réponse NXDOMAIN), l'option est renvoyée dans la réponse.

Comme les autres options EDNS, elle n'est pas signée par DNSSEC (section 8). Il n'y a donc pas de moyen de vérifier son authenticité et elle ne doit donc être utilisée qu'à titre informatif, par exemple pour le déboguage. (En outre, elle peut être modifiée en route, sauf si on utilise un mécanisme comme DoTRFC 7858.)

Question mises en œuvre de cette option, c'est surtout du code expérimental pour l'instant, voir cette liste (pas très à jour ?). Personnellement, j'ai ajouté ZONEVERSION à Drink, et écrit un article sur l'implémentation d'options EDNS (mais notez que l'option a changé de nom et de format depuis). Notez que, contrairement à presque toutes les options EDNS, ZONEVERSION est par zone, pas par serveur, ce qui est une contrainte pour le ou la programmeureuse, qui ne peut pas choisir la valeur avant de connaitre le nom demandé. Du côté des autres logiciels, NSD a vu un patch (mais apparemment abandonné). Voici ce que voit dig actuellement (en attendant une intégration officielle de l'option) :

% dig +ednsopt=19 @ns1-dyn.bortzmeyer.fr dyn.bortzmeyer.fr SOA
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64655
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
…
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1440
; OPT=19: 03 00 78 a5 08 cc ("..x...")
…
;; ANSWER SECTION:
dyn.bortzmeyer.fr.	0 IN SOA ns1-dyn.bortzmeyer.fr. stephane.bortzmeyer.org. (
				2024081612 ; serial
…

Vous noterez que "03" indique trois composants (dyn.bortzmeyer.fr), "00" le SOA-SERIAL, et "78 a5 08 cc" égal 2024081612. Vous pouvez aussi tester ZONEVERSION avec le serveur de test 200.1.122.30 (un NSD modifié), avec le domaine example.com.


Téléchargez le RFC 9660


L'article seul

Un peu de terminologie de la gouvernance Internet : multipartieprenantisme

Première rédaction de cet article le 6 octobre 2024


Quand on suit des débats sur la gouvernance de l'Internet, et qu'on débute dans ce secteur, on est parfois dérouté par des termes nouveaux. Quand des gens sont en désaccord sur le « multilatéralisme » et le « multipartieprenantisme », de quoi s'agit-il ?

Il y a réellement des concepts différents, derrière ce qui pourrait sembler du jargon creux. En fait, c'est très simple :

  • Un·e partisan·e du multilatéralisme préfère que la gouvernance de l'Internet (la politique, pour parler normalement) soit du ressort des États, négociant entre eux (multilatéralement), au sein d'une instance comme l'ONU ou ses annexes comme l'UIT,
  • alors que celui ou celle qui préfère le multipartieprenantisme (doctrine qui est en général désignée par un mot en anglais, multistakeholderism), choisirait plutôt qu'on implique ensemble les États, les entreprises privées (enfin, leur direction, uniquement, pas les travailleurs), les associations (on dit parfois « société civile » mais c'est un terme qui inclut dans certains cas tout ce qui n'est pas l'État), les universités, etc. La plupart du temps, ces personnes vont dire que l'ICANN représente le multipartieprenantisme.

Bien sûr, les choses sont toujours plus compliquées que cela : les partisan·es des États mettent souvent sous le tapis des questions gênantes pour eux et elles (par exemple celle de la légitimité des gouvernements, notamment dans les pays qui sont de franches dictatures), et ceux et celles du multipartieprenantisme exagèrent fréquemment la représentativité des organisations qui y participent. Tout lobby qui dit « représenter les utilisateurs » ou carrément « la société civile » ne dit pas forcément la vérité.

Maintenant, vous savez l'essentiel, vous pouvez participer aux réunions FGI ou ICANN. Reste une dernière question : faut-il écrire « multipartieprenantisme » ou bien « multipartiesprenantesisme », le pluriel étant plus logique mais moins élégant ?


L'article seul

RFC 9651: Structured Field Values for HTTP

Date de publication du RFC : Septembre 2024
Auteur(s) du RFC : M. Nottingham (Cloudflare), P-H. Kamp (The Varnish Cache Project)
Chemin des normes
Première rédaction de cet article le 6 octobre 2024


Plusieurs en-têtes HTTP sont structurés, c'est-à-dire que le contenu n'est pas juste une suite de caractères mais est composé d'éléments qu'un logiciel peut analyser. C'est par exemple le cas de Accept-Language: ou de Content-Disposition:. Mais chaque en-tête ainsi structuré a sa propre syntaxe, sans rien en commun avec les autres en-têtes structurés, ce qui en rend l'analyse pénible. Ce nouveau RFC (qui remplace le RFC 8941) propose donc des types de données et des algorithmes que les futurs en-têtes qui seront définis pourront utiliser pour standardiser un peu l'analyse d'en-têtes HTTP. Les en-têtes structurés anciens ne sont pas changés, pour préserver la compatibilité. De nombreux RFC utilisent déjà cette syntaxe (RFC 9209, RFC 9211, etc).

Imaginez : vous êtes un concepteur ou une conceptrice d'une extension au protocole HTTP qui va nécessiter la définition d'un nouvel en-tête. La norme HTTP, le RFC 9110, section 16.3.2, vous guide en expliquant ce à quoi il faut penser quand on conçoit un en-tête HTTP. Mais même avec ce guide, les pièges sont nombreux. Et, une fois votre en-tête spécifié, il vous faudra attendre que tous les logiciels, serveurs, clients, et autres (comme Varnish, pour lequel travaille un des auteurs du RFC) soient mis à jour, ce qui sera d'autant plus long que le nouvel en-tête aura sa syntaxe spécifique, avec ses amusantes particularités. Amusantes pour tout le monde, sauf pour le programmeur ou la programmeuse qui devra écrire l'analyse.

La solution est donc que les futurs en-têtes structurés réutilisent les éléments fournis par notre RFC, ainsi que son modèle abstrait, et la sérialisation proposée pour envoyer le résultat sur le réseau. Le RFC recommande d'appliquer strictement ces règles, le but étant de favoriser l'interopérabilité, au contraire du classique principe de robustesse, qui mène trop souvent à du code compliqué (et donc dangereux) car voulant traiter tous les cas et toutes les déviations. L'idée est que s'il y a la moindre erreur dans un en-tête structuré, celui-ci doit être ignoré complètement.

La syntaxe est malheureusement spécifiée sous forme d'algorithmes d'analyse. L'annexe C fournit toutefois aussi une grammaire en ABNF (RFC 5234).

Voici un exemple fictif d'en-tête structuré très simple (tellement simple que, si tous étaient comme lui, on n'aurait sans doute pas eu besoin de ce RFC) : Foo-Example: est défini comme ne prenant qu'un élément comme valeur, un entier compris entre 0 et 10. Voici à quoi il ressemblera en HTTP :

Foo-Example: 3

Il accepte des paramètres après un point-virgule, un seul paramètre est défini, foourl dont la valeur est un URI. Cela pourrait donner :

Foo-Example: 2; foourl="https://foo.example.com/"

Donc, ces solutions pour les en-têtes structurés ne serviront que pour les futurs en-têtes, pas encore définis, et qui seront ajoutés au registre IANA. Imaginons donc que vous soyez en train de mettre au point une norme qui inclut, entre autres, un en-tête HTTP structuré. Que devez-vous mettre dans le texte de votre norme ? La section 2 de notre RFC vous le dit :

  • Inclure une référence à ce RFC 9651.
  • J'ai parlé jusqu'à présent d'en-tête structuré mais en fait ce RFC 9651 s'applique aussi aux pieds (trailers) (RFC 9110, section 6.5 ; en dépit de leur nom, les pieds sont des en-têtes eux aussi). La norme devra préciser si elle s'applique seulement aux en-têtes classiques ou bien aussi aux pieds.
  • Spécifier si la valeur sera une liste, un dictionnaire ou juste un élément (ces termes sont définis en section 3). Dans l'exemple ci-dessus Foo-Example:, la valeur était un élément, de type entier.
  • Penser à définir la sémantique.
  • Et ajouter les règles supplémentaires sur la valeur du champ, s'il y en a. Ainsi, l'exemple avec Foo-Example: imposait une valeur entière entre 0 et 10.

Une spécification d'un en-tête structuré ne peut que rajouter des contraintes à ce que prévoit ce RFC 9651. S'il en retirait, on ne pourrait plus utiliser du code générique pour analyser tous les en-têtes structurés.

Rappelez-vous que notre RFC est strict : si une erreur est présente dans l'en-tête, il est ignoré. Ainsi, s'il était spécifié que la valeur est un élément de type entier et qu'on trouve une chaîne de caractères, on ignore l'en-tête. Idem dans l'exemple ci-dessus si on reçoit Foo-Example: 42, la valeur excessive mène au rejet de l'en-tête.

Les valeurs peuvent inclure des paramètres (comme le foourl donné en exemple plus haut), et le RFC recommande d'ignorer les paramètres inconnus, afin de permettre d'étendre leur nombre sans tout casser.

On a vu qu'une des plaies du Web était le laxisme trop grand dans l'analyse des données reçues (c'est particulièrement net pour HTML). Mais on rencontre aussi des cas contraires, des systèmes (par exemple les pare-feux applicatifs) qui, trop fragiles, chouinent lorsqu'ils rencontrent des cas imprévus, parce que leurs auteurs avaient mal lu le RFC. Cela peut mener à l'ossification, l'impossibilité de faire évoluer l'Internet parce que des nouveautés, pourtant prévues dès l'origine, sont refusées. Une solution récente est le graissage, la variation délibérée des messages pour utiliser toutes les possibilités du protocole. (Un exemple pour TLS est décrit dans le RFC 8701.) Cette technique est recommandée par notre RFC.

La section 3 du RFC décrit ensuite les types qui sont les briques de base avec lesquelles on va pouvoir définir les en-têtes structurés. La valeur d'un en-tête peut être une liste, un dictionnaire ou un élément. Les listes et les dictionnaires peuvent à leur tour contenir des listes. Une liste est une suite de termes qui, dans le cas de HTTP, sont séparés par des virgules :

ListOfStrings-Example: "foo", "bar", "It was the best of times."

Et si les éléments d'une liste sont eux-mêmes des listes, on met ces listes internes entre parenthèses (et notez la liste vide à la fin, et l'espace comme séparateur) :

ListOfListsOfStrings-Example: ("foo" "bar"), ("baz"), ("bat" "one"), ()

Un en-tête structuré dont la valeur est une liste a toujours une valeur, la liste vide, même si l'en-tête est absent.

Un dictionnaire est une suite de termes nom=valeur. En HTTP, cela donnera :

Dictionary-Example: en="Applepie", fr="Tarte aux pommes"

Et nous avons déjà vu les éléments simples dans le premier exemple. Les éléments peuvent être de type entier, chaîne de caractères, booléen, identificateur, valeur binaire, date, et un dernier type plus exotique (lisez le RFC pour en savoir plus). L'exemple avec Foo-Example: utilisait un entier. Les exemples avec listes et dictionnaires se servaient de chaînes de caractères. Ces chaînes sont encadrées de guillemets (pas d'apostrophes). Compte-tenu des analyseurs HTTP existants, les chaînes de caractères ordinaires doivent être en ASCII (RFC 20). Si on veut envoyer de l'Unicode, il faut utiliser un autre type, Display String. Quant aux booléens, notez qu'il faut écrire 1 et 0 (pas true et false), et préfixé d'un point d'interrogation.

Toutes ces valeurs peuvent prendre des paramètres, qui sont eux-mêmes une suite de couples clé=valeur, après un point-virgule qui les sépare de la valeur principale (ici, on a deux paramètres) :

ListOfParameters: abc;a=1;b=2

J'ai dit au début que ce RFC définit un modèle abstrait, et une sérialisation concrète pour HTTP. La section 4 du RFC spécifie cette sérialisation, et son inverse, l'analyse des en-têtes (pour les programmeur·ses seulement).

Ah, et si vous êtes fana de formats structurés, ne manquez pas l'annexe A du RFC, qui répond à la question que vous vous posez certainement depuis plusieurs paragraphes : pourquoi ne pas avoir tout simplement décidé que les en-têtes structurés auraient des valeurs en JSON (RFC 8259), ce qui évitait d'écrire un nouveau RFC, et permettait de profiter du code JSON existant ? Le RFC estime que le fait que les chaînes de caractères JSON soient de l'Unicode est trop risqué, par exemple pour l'interopérabilité. Autre problème de JSON, les structures de données peuvent être emboîtées indéfiniment, ce qui nécessiterait des analyseurs dont la consommation mémoire ne peut pas être connue et limitée. (Notre RFC permet des listes dans les listes mais cela s'arrête là : on ne peut pas poursuivre l'emboîtement.)

Une partie des problèmes avec JSON pourrait se résoudre en se limitant à un profil restreint de JSON, par exemple en utilisant le RFC 7493 comme point de départ. Mais, dans ce cas, l'argument « on a déjà un format normalisé, et mis en œuvre partout » tomberait.

Enfin, l'annexe A note également qu'il y avait des considérations d'ordre plutôt esthétiques contre JSON dans les en-têtes HTTP.

Toujours pour les programmeur·ses, l'annexe B du RFC donne quelques conseils pour les auteur·es de bibliothèques mettant en œuvre l'analyse d'en-têtes structurés. Pour les aider à suivre ces conseils, une suite de tests est disponible. Quant à une liste de mises en œuvre du RFC, vous pouvez regarder celle-ci.

Actuellement, il y a dans le registre des en-têtes plusieurs en-têtes structurés, comme le Accept-CH: du RFC 8942 (sa valeur est une liste d'identificateurs), le Cache-Status: du RFC 9211 ou le Client-Cert: du RFC 9440.

Si vous voulez un exposé synthétique sur ces en-têtes structurés, je vous recommande cet article par un des auteurs du RFC.

Voyons maintenant un peu de pratique avec une des mises en œuvre citées plus haut, http_sfv, une bibliothèque Python. Une fois installée :

% python3
>>> import http_sfv
>>> my_item=http_sfv.Item()
>>> my_item.parse(b"2")
>>> print(my_item)
2

On a analysé la valeur « 2 » en déclarant que cette valeur devait être un élément et, pas de surprise, ça marche. Avec une valeur syntaxiquement incorrecte :

>>> my_item.parse(b"2, 3")
Traceback (most recent call last):
 File "<stdin>", line 1, in <module> File "/home/stephane/.local/lib/python3.12/site-packages/http_sfv/util.py", line 61, in parse
 raise ValueError("Trailing text after parsed value")
ValueError: Trailing text after parsed value

Et avec un paramètre (il sera accessible après l'analyse, via le dictionnaire Python params) :

>>> my_item.parse(b"2; foourl=\"https://foo.example.com/\"")
>>> print(my_item.params['foourl'])
https://foo.example.com/

Avec une liste :

>>> my_list=http_sfv.List()
>>> my_list.parse(b"\"foo\", \"bar\", \"It was the best of times.\"")
>>> print(my_list)
"foo", "bar", "It was the best of times."

Et avec un dictionnaire :

>>> my_dict=http_sfv.Dictionary()
>>> my_dict.parse(b"en=\"Applepie\", fr=\"Tarte aux pommes\"")
>>> print(my_dict)
en="Applepie", fr="Tarte aux pommes"
>>> print(my_dict["fr"])
"Tarte aux pommes"

L'annexe D résume les principaux changements depuis le RFC 8941. Rien de trop crucial, à part le fait que l'ABNF est reléguée à une annexe. Sinon, il y a deux nouveaux types de base, pour les dates et les chaines de caractères en Unicode (Display Strings).


Téléchargez le RFC 9651


L'article seul

Bien maitriser ses chaines de dépendance DNS

Première rédaction de cet article le 24 septembre 2024


Le DNS repose sur un système de délégation, avec des dépendances qui ne sont pas toujours maitrisées. (Si vous êtes responsables d'un nom de domaine, veillez à connaitre ces dépendances et à les examiner !) Un exemple concret aujourd'hui avec telehouse.fr.

Ce nom de domaine est utilisé par le gérant de centres de données pour certains services à destination des clients (un portail clients, par exemple). Ce matin, il ne répond pas (dans l'après-midi, tout remarchait) :

% dig telehouse.fr
…
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 44602
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
…
;; Query time: 4000 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Sep 24 11:13:46 CEST 2024
;; MSG SIZE rcvd: 41

SERVFAIL signifie SERVer FAILure et, comme ce nom l'indique, c'est mauvais. Si on demande à un autre résolveur DNS qui met en œuvre les rapports d'erreur détaillés (RFC 8914), on a :

% dig @1.1.1.1 telehouse.fr
…
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 20599
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; EDE: 22 (No Reachable Authority): (at delegation telehouse.fr.)
…
;; Query time: 4256 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
;; WHEN: Tue Sep 24 11:14:37 CEST 2024
;; MSG SIZE rcvd: 74

L'EDE (Extended DNS Error) nous dit que le résolveur n'a pu joindre aucun des serveurs faisant autorité. On va donc devoir creuser. D'abord, quels sont ces serveurs faisant autorité pour telehouse.fr ? Demandons à un des serveurs du domaine parent .fr :

% dig @d.nic.fr telehouse.fr
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21940
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1
;; WARNING: recursion requested but not available
…
;; AUTHORITY SECTION:
telehouse.fr.		3600 IN	NS ns1.fr.kddi.com.
telehouse.fr.		3600 IN	NS ns2.fr.kddi.com.

Bien, nous avons les noms de ces serveurs, interrogeons-les :

% dig ns1.fr.kddi.com.
…
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 20153
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
…
;; Query time: 12 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Sep 24 11:15:12 CEST 2024
;; MSG SIZE rcvd: 44

Ah, raté, on ne peut pas résoudre le nom du serveur de noms. Le serveur est toujours là et, si on connait son adresse IP (par exemple parce qu'elle est encore dans la mémoire du résolveur), on peut l'interroger :

% dig @85.90.48.10 telehouse.fr
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15119
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3
…
;; ANSWER SECTION:
telehouse.fr.		900 IN A 85.90.40.15

Bon, et si on n'a pas cette adresse IP ? Demandons au domaine parent :

% dig kddi.com NS
…
;; ANSWER SECTION:
kddi.com.		85645 IN NS dnsa01.kddi.ne.jp.
kddi.com.		85645 IN NS dnsa02.kddi.ne.jp.
kddi.com.		85645 IN NS dns103.kddi.ne.jp.
kddi.com.		85645 IN NS dns104.kddi.ne.jp.
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Sep 24 11:15:33 CEST 2024
;; MSG SIZE rcvd: 131

Et interrogeons-les :

% dig @dnsa01.kddi.ne.jp. fr.kddi.com NS
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43194
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1
;; WARNING: recursion requested but not available
…
;; AUTHORITY SECTION:
fr.kddi.com.		86400 IN NS ns1.kddi-telehouse.eu.
fr.kddi.com.		86400 IN NS ns2.kddi-telehouse.eu.
;; Query time: 216 msec
;; SERVER: 54.64.39.199#53(dnsa01.kddi.ne.jp.) (UDP)
;; WHEN: Tue Sep 24 11:15:57 CEST 2024
;; MSG SIZE rcvd: 121

Et suivons cette délégation :

% dig ns1.kddi-telehouse.eu.
…
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 48644
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
…
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Sep 24 11:16:11 CEST 2024
;; MSG SIZE rcvd: 50

Bon, même problème, le nom du serveur de noms ne peut pas être résolu. Poursuivons notre quête auprès des serveurs de .eu :

% dig @w.dns.eu. kddi-telehouse.eu. NS
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26571
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1
;; WARNING: recursion requested but not available
…
;; AUTHORITY SECTION:
kddi-telehouse.eu.	86400 IN NS ns2.validname.com.
kddi-telehouse.eu.	86400 IN NS ns1.validname.com.

Et demandons :

% dig @ns1.validname.com kddi-telehouse.eu.
;; communications error to 2a01:c8:ff00:200::219#53: timed out
;; communications error to 2a01:c8:ff00:200::219#53: timed out
;; communications error to 2a01:c8:ff00:200::219#53: timed out
;; communications error to 2a01:c8:ff00:200::220#53: timed out
;; communications error to 185.65.56.219#53: timed out
;; communications error to 185.65.56.220#53: timed out

Ah, cette fois, les choses ont changé : on arrive bien à trouver l'adresse IP de ces serveurs, le nom peut être résolu, mais le serveur ne répond pas (idem pour ns2.validname.com).

Arrivé là, il est temps de faire un bilan : le domaine telehouse.fr dépend du domaine fr.kddi.com qui dépend du domaine kddi-telehouse.eu qui dépend de deux serveurs (ns1.validname.com et ns2.validname.com) qui sont en panne. Vu en sens inverse, la panne des validname.com a entrainé celle du domaine kddi-telehouse.eu qui a entrainé celle du domaine fr.kddi.com qui a entrainé celle du domaine telehouse.fr.

La morale ? Soyez attentifs aux dépendances. Si le domaine X.example a tous ses serveurs de noms dans Y.example, une panne de ce dernier sera fatale à X.example. Et cette dépendance est transitive : si Y.example dépend de Z.example, une panne de ce dernier cassera X.example. Pour afficher les dépendances d'un domaine, vous pouvez utiliser l'outil ns-tree :

% ./ns-tree.py telehouse.fr
telehouse.fr
telehouse.fr.
 └─ fr.kddi.com. ← { ns2.fr.kddi.com., ns1.fr.kddi.com. } ├─ kddi-telehouse.eu. ← { ns2.kddi-telehouse.eu., ns1.kddi-telehouse.eu. } │ └─ validname.com. ← { ns1.validname.com., ns2.validname.com. } │ └─ namebay.com. ← { ns1.namebay.com., ns2.namebay.com. } │ └─ namebay.com. ← { ns1.namebay.com., ns2.namebay.com. } └─ fr.kddi.com. ← { ns2.fr.kddi.com., ns1.fr.kddi.com. } 

Une note finale : validname.com est géré par Namebay qui a annoncé sur sa page d'accueil une panne DNS : namebay-dns.png

Cette panne DNS était peut-être liée au passage d'un rançongiciel trois jours auparavant (cf. cet article) : namebay-rancongiciel.png


L'article seul

RFC 9620: Guidelines for Human Rights Protocol and Architecture Considerations

Date de publication du RFC : Septembre 2024
Auteur(s) du RFC : G. Grover, N. ten Oever (University of Amsterdam)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF hrpc
Première rédaction de cet article le 17 septembre 2024


Voici un RFC explicitement politique, puisqu'il documente la façon dont les concepteur·rices de protocoles à l'IETF devraient examiner les conséquences de leurs protocoles sur l'exercice des droits humains. Si vous concevez un protocole réseau (IETF ou pas), c'est une lecture recommandée.

Les protocoles ne sont pas neutres puisqu'ils ont des conséquences concrètes sur les utilisateurices, conséquences positives ou négatives. S'ils n'en avaient pas, on ne passerait pas du temps à les développer, et on ne dépenserait pas d'argent à les déployer. Ces conséquences ne sont pas forcément faciles à déterminer, surtout avant tout déploiement effectif, mais ce RFC peut guider la réflexion et permettre d'identifier les points qui peuvent avoir des conséquences néfastes. Il comprend de nombreux exemples tirés de précédents RFC. Il met à jour partiellement le RFC 8280, dont il reprend la section 6, et s'inspire de la méthode du RFC 6973, qui documentait les conséquences des protocoles sur la vie privée.

La question est évidemment complexe. Les protocoles n'ont pas forcément un pouvoir direct sur ce que les utilisateurices peuvent faire ou pas (c'est l'argument central de ceux qui estiment que les techniques sont neutres : HTTP transférera aussi bien un article de la NASA qu'un texte complotiste sur les extra-terrestres). Leur rôle est plutôt indirect, en ce qu'ils encouragent ou découragent certaines choses, plutôt que d'autoriser ou interdire. Et puis, comme le note le RFC, cela dépend du déploiement. Par exemple, pour le courrier électronique, des faits politiques importants ne s'expliquent pas par le protocole. Ce ne sont pas les particularités de SMTP (RFC 5321) qui expliquent la domination de Gmail par exemple. Il ne faut en effet pas tomber dans le déterminisme technologique (comme le font par exemple les gens qui critiquent DoH) : l'effet dans le monde réel d'un protocole dépend de bien d'autres choses que le protocole.

Ah, et autre point dans l'introduction, la définition des droits humains. Notre RFC s'appuie sur la déclaration universelle des droits humains et sur d'autres documents comme le International Covenant on Economic, Social and Cultural Rights.

Parmi les droits humains cités dans cette déclaration universelle, nombreux sont ceux qui peuvent être remis en cause sur l'Internet : liberté d'expression, liberté d'association, droit à la vie privée, non-discrimination, etc. L'absence d'accès à l'Internet mène également à une remise en cause des droits humains, par exemple parce que cela empêche les lanceurs d'alerte de donner l'alerte. Les atteintes aux droits humains peuvent être directes (censure) ou indirectes (la surveillance des actions peut pousser à l'auto-censure, et c'est souvent le but poursuivi par les acteurs de la surveillance ; cf. « Chilling Effects: Online Surveillance and Wikipedia Use »). Et les dangers pour les individus ne sont pas seulement « virtuels », ce qui se passe en ligne a des conséquences physiques quand, par exemple, une campagne de haine contre des gens accusés d'attaques contre une religion mène à leur assassinat, ou quand un État emprisonne ou tue sur la base d'informations récoltées en ligne.

C'est pour cela que, par exemple, le conseil des droits humains de l'ONU mentionne que les droits qu'on a dans le monde physique doivent aussi exister en ligne. [La propagande des médias et des politiciens en France dit souvent que « l'Internet est une zone de non-droit » et que « ce qui est interdit dans le monde physique doit aussi l'être en ligne », afin de justifier des lois répressives. Mais c'est une inversion complète de la réalité. En raison des particularités du numérique, notamment la facilité de la surveillance de masse, et de l'organisation actuelle du Web, avec un petit nombre d'acteurs médiant le trafic entre particuliers, les droits humains sont bien davantage menacés en ligne.] Sur la question de l'application des droits humains à l'Internet, on peut aussi lire les « 10 Internet Rights & Principles> » et le « Catalog of Human Rights Related to ICT Activities ».

Comme les droits humains sont précieux, et sont menacés sur l'Internet, l'IETF doit donc veiller à ce que son travail, les protocoles développés, n'aggravent pas la situation. D'où la nécessité, qui fait le cœur de ce RFC, d'examiner les protocoles en cours de développement. Ces examens (reviews, section 3 du RFC) devraient être systématiques et, évidemment, faits en amont, pas une fois le protocole déployé. [En pratique, ces examens ont assez vite été arrêtés, et ce RFC ne reflète donc pas la situation actuelle.]

Vu la façon dont fonctionne l'IETF, il n'y a pas besoin d'une autorité particulière pour effectuer ces examens. Tout·e participant·e à l'IETF peut le faire. Ce RFC 9620 vise à guider les examinateurs (reviewers). L'examen peut porter sur le contenu d'un Internet Draft mais aussi être complété, par exemple, avec des interviews d'experts de la question (les conséquences de tel ou tel paragraphe dans un Internet Draft ne sont pas forcément évidentes à la première lecture, ou même à la seconde) mais aussi des gens qui seront affectés par le protocole en question. Si un futur RFC parle d'internationalisation, par exemple, il ne faut pas interviewer que des anglophones, et pas que des participants à l'IETF, puisque l'internationalisation concerne tout le monde.

Une grosse difficulté, bien sûr, est que le protocole n'est pas tout. Les conditions effectives de son déploiement, et son évolution dans le temps, sont cruciales. Ce n'est pas en lisant le RFC 5733 (ou le RFC 9083) qu'on va tout comprendre sur les enjeux de la protection des données personnelles des titulaires de noms de domaine ! Le RFC 8980 discute d'ailleurs de cette importante différence entre le protocole et son déploiement.

La plus importante section de notre RFC est sans doute la section 4, qui est une sorte de check-list pour les auteur·es de protocoles et les examinateurices. Idéalement, lors de la phase de conception d'un protocole, il faudrait passer toutes ces questions en revue. Bien évidemment, les réponses sont souvent complexes : la politique n'est pas un domaine simple.

Premier exemple (je ne vais pas tous les détailler, rassurez-vous), les intermédiaires. Est-ce que le protocole permet, voire impose, des intermédiaires dans la communication ? C'est une question importante car ces intermédiaires, s'ils ne sont pas sous le contrôle des deux parties qui communiquent, peuvent potentiellement surveiller la communication (risque pour la confidentialité) ou la perturber (risque pour la liberté de communication). Un exemple est l'interception HTTPS (cf. « The Security Impact of HTTPS Interception »). Le principe de bout en bout (RFC 1958 ou bien « End-to-End Arguments in System Design ») promeut plutôt une communication sans intermédiaires, mais on trouve de nombreuses exceptions dans les protocoles IETF (DNS, SMTP…) ou en dehors de l'IETF (ActivityPub), car les intermédiaires peuvent aussi rendre des services utiles. En outre, ces intermédiaires tendent à ossifier le protocole, en rendant plus difficile le déploiement de tout changement (cf. RFC 8446 pour les problèmes rencontrés par TLS 1.3).

Le RFC fait aussi une différence entre intermédiaires et services. Si vous êtes utilisateurice de Gmail, Gmail n'est pas un intermédiaire, mais un service car vous êtes conscient·e de sa présence et vous l'avez choisi. [L'argument me semble avoir des faiblesses : ce genre de services pose exactement les mêmes problèmes que les intermédiaires et n'est pas forcément davantage maitrisé.]

Un bon moyen de faire respecter le principe de bout en bout est de chiffrer au maximum. C'est pour cela que QUIC (RFC 9000) chiffre davantage de données que TLS. C'est aussi pour cela que l'IETF travaille au chiffrement du SNI (draft-ietf-tls-esni).

Autre exemple, la connectivité (section 4.2). Car, si on n'a pas accès à l'Internet du tout, ou bien si on y a accès dans des conditions très mauvaises, tout discussion sur les droits humains sur l'Internet devient oiseuse. L'accès à l'Internet est donc un droit nécessaire (cf. la décision du Conseil Constitutionnel sur Hadopi, qui posait le principe de ce droit d'accès à l'Internet). Pour le protocole, cela oblige à se pencher sur son comportement sur des liens de mauvaise qualité : est-ce que ce protocole peut fonctionner lorsque la liaison est mauvaise ?

Un sujet délicat (section 4.4) est celui des informations que le protocole laisse fuiter (l'« image vue du réseau » du RFC 8546). Il s'agit des données qui ne sont pas chiffrées, même avec un protocole qui fait de la cryptographie, et qui peuvent donc être utilisées par le réseau, par exemple pour du traitement différencié (de la discrimination, pour dire les choses franchement). Comme recommandé par le RFC 8558, tout protocole doit essayer de limiter cette fuite d'informations. C'est pour cela que T***** a tort d'exposer les numéros de port, par exemple, que QUIC va au contraire dissimuler.

L'Internet est mondial, on le sait. Il est utilisé par des gens qui ne parlent pas anglais et/ou qui n'utilisent pas l'alphabet latin. Il est donc crucial que le protocole fonctionne pour tout le monde (section 4.5). Si le protocole utilise des textes en anglais, cela doit être de manière purement interne (le GET de HTTP, le Received: de l'IMF, etc), sans être obligatoirement montré à l'utilisateurice. Ce principe, formulé dans le RFC 2277, dit que tout ce qui est montré à l'utilisateur doit pouvoir être traduit. (En pratique, il y a des cas limites, comme les noms de domaine, qui sont à la fois éléments du protocole, et montrés aux utilisateurs.)

Si le protocole sert à transporter du texte, il doit évidemment utiliser Unicode, de préférence encodé en UTF-8. S'il accepte d'autres encodages et/ou d'autres jeux de caractère (ce qui peut être dangereux pour l'interopérabilité), il doit permettre d'étiqueter ces textes, afin qu'il n'y ait pas d'ambiguité sur leurs caractéristiques. Pensez d'ailleurs à lire le RFC 6365.

Un contre-exemple est le vieux protocole whois (RFC 3912), qui ne prévoyait que l'ASCII et, si on peut l'utiliser avec d'autres jeux de caractères, comme il ne fournit pas d'étiquetage, le client doit essayer de deviner de quoi il s'agit. (Normalement, whois n'est plus utilisé, on a le Web et RDAP, mais les vieilles habitudes ont la vie dure.)

Toujours question étiquetage, notre RFC rappelle l'importance de pouvoir, dans le protocole, indiquer explicitement la langue des textes (RFC 5646). C'est indispensable afin de permettre aux divers logiciels de savoir quoi en faire, par exemple en cas de synthèse vocale.

Le RFC parle aussi de l'élaboration des normes techniques (section 4.7). Par exemple, sont-elles dépendantes de brevets (RFC 8179 et RFC 6701) ? [Personnellement, je pense que c'est une question complexe : les brevets ne sont valables que dans certains pays et, en outre, la plupart des brevets logiciels sont futiles, brevetant des technologies banales et déjà connues. Imposer, comme le proposent certains, de ne normaliser que des techniques sans brevet revient à donner un doit de veto à n'importe quelle entreprise qui brevète n'importe quoi. Par exemple, le RFC 9156 n'aurait jamais été publié si on s'était laissé arrêter par le brevet.]

Mais un autre problème avec les normes techniques concerne leur disponibilité. Si l'IETF, le W3C et même l'UIT publient leurs normes, ce n'est pas le cas de dinosaures comme l'AFNOR ou l'ISO, qui interdisent même la redistribution de normes qu'on a légalement acquises. Si les normes IETF sont de distribution libre, elles dépendent parfois d'autres normes qui, elles, ne le sont pas.

Un peu de sécurité informatique, pour continuer. La section 4.11 traite de l'authentification des données (ce que fait DNSSEC pour le DNS, par exemple). Cette possibilité d'authentification est évidemment cruciale pour la sécurité mais le RFC note qu'elle peut aussi être utilisée négativement, par exemple avec les menottes numériques.

Et il y a bien sûr la confidentialité (section 4.12 mais aussi RFC 6973), impérative depuis toujours mais qui était parfois sous-estimée, notamment avant les révélations Snowden. Les auteur·es de protocoles doivent veiller à ce que les données soient et restent confidentielles et ne puissent pas être interceptées par un tiers. Il y a longtemps que tout RFC doit contenir une section sur la sécurité (RFC 3552), exposant les menaces spécifiques à ce RFC et les contre-mesures prises, entre autre pour assurer la confidentialité. L'IETF refuse, à juste titre, toute limitation de la cryptographie, souvent demandée par les autorités (RFC 1984). Les exigences d'accès par ces autorités (en invoquant des arguments comme la lutte contre le terrorisme ou la protection de l'enfance) ne peuvent mener qu'à affaiblir la sécurité générale puisque ces accès seront aussi utilisés par les attaquants, ou par un État qui ***** de son pouvoir.

Le modèle de menace de l'Internet, depuis longtemps, est que tout ce qui est entre les deux machines situées aux extrémités de la communication doit être considéré comme un ennemi. Pas parce que les intermédiaires sont forcément méchants, loin de là, mais parce qu'ils ont des possibiliés techniques que certains exploiteront et il faut donc protéger la communication car on ne sait jamais ce que tel ou tel intermédiaire fera (RFC 7258 et RFC 7624). Bref, tout protocole doit chiffrer le contenu qu'il transporte (RFC 3365). Aujourd'hui, les principales exceptions à ce principe sont le très vieil whois (RFC 3912) et surtout le DNS qui a, certes, des solutions techniques pour le chiffrement (RFC 7858 et RFC 8484) mais qui sont loin d'être universellement déployées.

Ce chiffrement doit évidemment être fait de bout en bout, c'est-à-dire directement entre les deux machines qui communiquent, afin d'éviter qu'un intermédiaire n'ait accès à la version en clair. Cela pose un problème pour les services store-and-forward comme le courrier électronique (RFC 5321). De même, chiffrer lorsqu'on communique en HTTPS avec Gmail ne protège pas la communication contre Google, seulement contre les intermédiaires réseau ! Relire le RFC 7624 est recommandé.

Question vie privée, le RFC recommande également de faire attention aux métadonnées et à l'analyse de trafic. Les conseils du RFC 6973, section 7, sont ici utiles.

Un sujet encore plus délicat est celui de l'anonymat et du pseudonymat. On sait qu'il n'y a pas réellement d'anonymat sur l'Internet (quoiqu'en disent les politiciens malhonnêtes et les journalistes avides de sensationnalisme), le numérique permettant au contraire de récolter et de traiter beaucoup de traces de la communication. Néanmoins, le protocole doit permettre, autant que possible, de s'approcher de l'anonymat. Par exemple, les identificateurs persistents sont évidemment directement opposés à cet objectif puisqu'ils rendent l'anonymat impossible (rappel important : anonymat ≠ pseudonymat). Au minimum, il faudrait permettre à l'utilisateur de changer facilement et souvent ces identificateurs. Et, bien sûr, ne pas imposer qu'ils soient liés à l'identité étatique. Des exemples d'identificateurs qui sont parfois utilisés sur le long terme sont les adresses IP, les Connection ID de QUIC (un bon exemple d'un protocole qui permet leur changement facilement), les biscuits de HTTP, et les adresses du courrier électronique, certainement très difficiles à changer. Comme le montre l'exemple de ces adresses, les identificateurs stables sont utiles et on ne peut pas forcément les remplacer par des identificateurs temporaires. Ici, le souci de vie privée rentre en contradiction avec l'utilité des identificateurs, une tension courante en sécurité. Le fait qu'on ne puisse en général pas se passer d'identificateurs, à relativement longue durée de vie, est justement une des raisons pour lesquelles il n'y a pas de vrai anonymat sur l'Internet.

Notons que les politiciens de mauvaise foi et les journalistes incompétents parlent parfois d'anonymat dès qu'un identificateur stable n'est pas l'identité étatique (par exemple quand je crée un compte Gmail « anonymous652231 » au lieu d'utiliser le nom qui est sur ma carte d'identité). Mais tout identificateur stable peut finir par se retrouver lié à une autre identité, peut-être aussi à l'identité étatique, par exemple si deux identificateurs sont utilisés dans le même message. Et certains identificateurs sont particulièrement communs, avec plusieurs usages, ce qui les rend encore plus dangereux pour la vie privée. Le numéro de téléphone, que certaines messageries instantanées imposent, est particulièrement sensible et est donc déconseillé.

Donc, s'il faut utiliser des identificateurs stables, ils doivent au moins pouvoir être des pseudonymes.

D'autres façons de désanonymiser existent, par exemple quand les gens ont bêtement cru que condenser un identificateur n'était pas réversible (cf. l'article « Four cents to deanonymize: Companies reverse hashed email addresses »).

Notre RFC rappelle ainsi les discussions animées qu'avait connu l'IETF en raison d'un mécanisme d'allocation des adresses IPv6, qui les faisaient dériver d'un identificateur stable, l'adresse MAC, qui permettait de suivre à la trace un utilisateur mobile. Depuis, le RFC 8981 (et le RFC 7217 pour les cas où on veut une stabilité limitée dans l'espace) ont résolu ce problème (le RFC 7721 résume le débat). À noter que l'adresse MAC peut aussi devenir variable (draft-ietf-madinas-mac-address-randomization).

Autre exemple où un protocole IETF avait une utilisation imprudente des identificateurs, DH*****, avec ses identificateurs stables qui, certes, n'étaient pas obligatoires mais, en pratique, étaient largement utilisés (RFC 7844).

Une autre question très sensible est celle de la censure. Le protocole en cours de développement a-t-il des caractéristiques qui rendent la censure plus facile ou au contraire plus difficile (section 4.16) ? Par exemple, si le protocole fait passer par des points bien identifiés les communications, ces points vont certainement tenter les censeurs (pensez aux résolveurs DNS et à leur rôle dans la censure…). Les RFC 7754 et RFC 9505 décrivent les techniques de censure. Elles sont très variées. Par exemple, pour le Web, le censeur peut agir sur les résolveurs DNS mais aussi bloquer l'adresse IP ou bien, en faisant du DPI, bloquer les connexions TLS en regardant le SNI. Certains systèmes d'accès au contenu, comme Tor, ou de distribution du contenu, comme BitTorrent, résistent mieux à la censure que le Web mais ont d'autres défauts, par exemple en termes de performance. L'exemple du SNI montre en tout cas très bien une faiblesse de certains protocoles : exposer des identificateurs aux tierces parties (qui ne sont aucune des deux parties qui communiquent) facilite la censure. C'est pour cela que l'IETF développe ECH (cf. draft-ietf-tls-esni/).

Le protocole, tel que normalisé dans un RFC, c'est bien joli, mais il faut aussi tenir compte du déploiement effectif. Comme noté au début, ce n'est pas dans le RFC 5321 qu'on trouvera les causes de la domination de Gmail ! Les effets du protocole dans la nature sont en effet très difficiles à prévoir. La section 4.17 se penche sur cette question et demande qu'on considère, non seulement le protocole mais aussi les effets qu'il aura une fois déployé. [Ce qui, à mon avis, relève largement de la boule de cristal, surtout si on veut tenir compte d'effets économiques. Et les exemples du RFC ne sont pas géniaux, comme de reprocher au courrier sa gratuité, qui encourage le spam. L'exemple de l'absence de mécanisme de paiement sur le Web, qui pousse à développer des mécanismes néfastes comme la publicité, est meilleur.] La section 4.21 traite également ce sujet des conséquences, parfois inattendues, du déploiement d'un protocole.

Le RFC a aussi un mot (section 4.18) sur les questions d'accessibilité, notamment aux handicapés. Cette question, très présente dans les discussions autour des couches hautes du Web (cf. les réunions Paris Web) semble plus éloignée de ce que fait l'IETF mais le RFC cite quand même l'exemple du RFC 9071, sur l'utilisation de RTP dans des réunions en ligne, avec une alternative en texte pour les personnes malentendantes.

L'Internet est aujourd'hui très, trop, centralisé, notamment pour ce qui concerne les services (la connectivité, quoique imparfaitement répartie, est moins dépendante d'un petit nombre d'acteurs). Il est donc utile, lors de la conception d'un protocole, de réfléchir aux caractéristiques du protocole qui risquent d'encourager la centralisation (par exemple par la création d'un, ou d'un petit nombre de points de contrôle). Le RFC 3935 donne explicitement à l'IETF un objectif de promotion de la décentralisation.

En conclusion, même si l'activité organisée d'examen des futurs RFC n'a pas pris, ce RFC reste utile pour réfléchir à l'impact de nos protocoles sur les droits des humains.


Téléchargez le RFC 9620


L'article seul

Version 16 d'Unicode

Première rédaction de cet article le 14 septembre 2024


Le 10 septembre est sortie la version 16 d'Unicode. Une description officielle des principaux changements est disponible mais voici ceux qui m'ont intéressé particulièrement. (Il n'y a pas de changement radical.)

Pour explorer plus facilement la grande base Unicode, j'utilise un programme qui la convertit en SQL et permet ensuite de faire des analyses variées. Faisons quelques requêtes SQL :

ucd=> SELECT count(*) AS Total FROM Characters; total
--------
 155063

Combien de caractères sont arrivés avec la version 16 ?

ucd=> SELECT version,count(version) FROM Characters GROUP BY version ORDER BY version::float;...
 13.0 | 5930
 14.0 | 838
 15.0 | 4489
 15.1 | 627
 16.0 | 5185

5 185 nouveaux caractères, c'est pas mal, la plus grosse addition depuis la version 13.0. Quels sont ces nouveaux caractères ?

ucd=> SELECT To_U(codepoint) AS Code_point, name FROM Characters WHERE version='16.0' ORDER BY Codepoint; code_point | name
-----------+----------------------------------------------------------------------------
 U+A7CB | LATIN CAPITAL LETTER RAMS HORN
 U+A7CC | LATIN CAPITAL LETTER S WITH DIAGONAL STROKE
 …
 U+10D50 | GARAY CAPITAL LETTER A
 U+10D51 | GARAY CAPITAL LETTER CA
 U+10D52 | GARAY CAPITAL LETTER MA
 …
 U+11BC2 | SUNUWAR LETTER EKO
 U+11BC3 | SUNUWAR LETTER IMAR
 U+11BC4 | SUNUWAR LETTER REU
 …
 U+1346E | EGYPTIAN HIEROGLYPH-1346E
 U+1346F | EGYPTIAN HIEROGLYPH-1346F
 U+13470 | EGYPTIAN HIEROGLYPH-13470
 …
 U+1CC15 | LOGIC GATE OR
 U+1CC16 | LOGIC GATE AND
 …
 U+1CC4A | FLYING SAUCER WITH BEAMS
 U+1CC4B | FLYING SAUCER WITHOUT BEAMS
 …
 U+1CC4E | ALIEN SQUID OPEN TENTACLES
 U+1CC4F | ALIEN SQUID CLOSED TENTACLES
 …
 U+1CC60 | LEFT-POINTING ATOMIC BOMB
 U+1CC61 | UP-POINTING ATOMIC BOMB
 …
 U+1CE20 | LARGE TYPE PIECE CROSSBAR WITH LOWER STEM
 U+1CE21 | LARGE TYPE PIECE UPPER HALF VERTEX OF M
 U+1CE22 | LARGE TYPE PIECE DIAGONAL LOWER LEFT
 …

Cette version amène en effet plusieurs nouvelles écritures. C'est le cas du Sunuwar, par exemple. On voit aussi arriver le Garay. Cette dernière écriture ne semble d'ailleurs pas avoir tellement eu de succès, le nom de domaine du site officiel, garay-ecriture.com a disparu en 2012. Parmi les nouveautés, beaucoup d'hiéroglyphes égyptiens, et l'habituelle arrivée d'emojis comme les différentes variantes d'extra-terrestres, avec ou sans tentacules (bon, d'accord, ceux-là ne sont pas officiellement des emojis, ils ont été enregistrés via une autre voie mais ils seront sans doute utilisés comme des emojis).

Revenu du passé, le jeu de caractères des machines Sharp MZ est désormais inclus. Cela apporte notamment les symboles des circuits électroniques.

Si vous avez les bonnes polices de caractères, vous allez pouvoir voir quelques exemples (sinon, le lien mène vers Uniview). Voici par exemple le grand S barré , la première lettre de l'alphabet garay 𐵊, celle du sunuwar 𑯀, un des nouveaux et nombreux hiéroglyphes 𓑠, une diode 𜰎 et un extra-terrestre 𜱌.

Sur le même sujet, je vous recommande l'article d'Ysabeau sur LinuxFr.


L'article seul

Articles des différentes années : 2024 2023 2022 2021 2020 2019 2018 Précédentes années

Syndication : Flux Atom avec seulement les résumés et Flux Atom avec tout le contenu.

Un article de ce blog au hasard.