Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

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.


RFC 9549: Internationalization Updates to RFC 5280

Date de publication du RFC : Mars 2024
Auteur(s) du RFC : R. Housley (Vigil Security)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lamps
Première rédaction de cet article le 22 novembre 2024


Ce court RFC ajoute aux certificats PKIX du RFC 5280 la possibilité de contenir des adresses de courrier électronique dont la partie locale est en Unicode. Et il modifie légèrement les règles pour les noms de domaine en Unicode dans les certificats. Il remplace le RFC 8399, avec peu de changements.

Les certificats sur l'Internet sont normalisés dans le RFC 5280, qui décrit un profil de X.509 nommé PKIX (définir un profil était nécessaire car la norme X.509 est bien trop riche et complexe). Ce RFC 5280 permettait des noms de domaine en Unicode (sections 4.2.1.10 et 7 du RFC 5280) mais il suivait l'ancienne norme IDN, celle des RFC 3490 et suivants. Depuis, les IDN sont normalisés dans le RFC 5890 et suivants, et notre nouveau RFC 9549 modifie très légèrement le RFC 5280 pour s'adapter à cette nouvelle norme de noms de domaines en Unicode. Les noms de domaine dans un certificat peuvent être présents dans les champs Sujet (titulaire du certificat) et Émetteur (AC ayant signé le certificat) mais aussi dans les contraintes sur le nom (une autorité de certification peut être limitée à des noms se terminant en example.com, par exemple).

Notez que, comme avant, ces noms sont exprimés dans le certificat en Punycode (RFC 3492, xn--caf-dma.fr au lieu de café.fr), appelé A-label dans notre RFC. C'est un bon exemple du fait que les limites qui rendaient difficiles d'utiliser des noms de domaine en Unicode n'avaient rien à voir avec le DNS (qui n'a jamais été limité à ASCII, contrairement à ce qu'affirme une légende courante). En fait, le problème venait des applications (comme PKIX), qui ne s'attendaient pas à des noms en Unicode. Un logiciel qui traite des certificats aurait été bien étonné de voir des noms de domaines non-ASCII, et aurait peut-être planté. D'où ce choix du Punycode (A-label) par opposition à la forme plus lisible du U-label.

Nouveauté plus importante du RFC 8399, mis à jour par notre RFC 9549, les adresses de courrier électronique en Unicode (EAI pour Email Address Internationalization). Elles étaient déjà permises par la section 7.5 du RFC 5280, mais seulement pour la partie domaine (à droite du @). Désormais, elles sont également possibles dans la partie locale (à gauche du @). Le RFC 8398 donne tous les détails sur ce sujet.

Reste à savoir quelles AC acceptent Unicode. En 2018, j'avais testé avec Let's Encrypt (avec le client Dehydrated, en mettant le Punycode dans domains.txt) et ça marchait, regardez le certificat de https://www.potamochère.fr/. Le voici, affiché par GnuTLS :

% gnutls-cli www.potamochère.fr
...
- subject `CN=www.xn--potamochre-66a.fr', issuer `CN=R10,O=Let's Encrypt,C=US', serial 0x03a34cfc017b4311da0b21797cd250ebd3c0, RSA key 4096 bits, signed using RSA-SHA256, activated `2024-11-01 05:26:59 UTC', expires `2025-01-30 05:26:58 UTC', pin-sha256="6y…
    

D'autres AC acceptent ces noms en Unicode : Gandi le fait aussi, par exemple. On notera que le célèbre service de test de la qualité des configurations TLS, SSLlabs, gère bien les IDN : ssllabs-potamochere.png

Enfin, le registre du .ru a participé au développement de logiciels pour traiter l'Unicode dans les certificats.

La section 1.2 résume les changements depuis le RFC 8399. Notamment :

  • Le RFC 8399 ne les mentionnait pas mais les emojis ne sont pas autorisés dans les noms de domaine (ils appartiennent à la catégorie Unicode So, « Autres symboles », que le RFC 5890 n'inclut pas). Comme le rappelle notre RFC 9549, un nom comme ♚.example ne serait pas légal. Ce point est désormais explicite.
  • Si le RFC 8399 prescrivait certains traitements à faire sur la forme Unicode (U-label) des noms, désormais, tout se fait sur la forme en Punycode (A-label, donc xn--potamochre-66a.fr et pas potamochère.fr). Cela permet d'éviter de déclencher certaines failles de sécurité.

Téléchargez le RFC 9549


L'article seul

RFC 9682: Updates to the CDDL grammar of RFC 8610

Date de publication du RFC : Novembre 2024
Auteur(s) du RFC : C. Bormann (Universität Bremen TZI)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF cbor
Première rédaction de cet article le 19 novembre 2024


Voici une légère mise à jour de la grammaire du langage de description de schéma CDDL (Concise Data Definition Language), originellement normalisé dans le RFC 8610. Pas de gros changement.

Il y avait juste quelques errata à traiter, et des ambiguités concernant notamment les chaines de caractères. Il était devenu nécessaire de modifier l'ABNF. CDDL a été décrit dans le RFC 8610, puis étendu par le RFC 9165. Il vise à décrire un schéma pour des fichiers CBOR ou JSON. Depuis quatre ans qu'il est normalisé, plusieurs erreurs ont été relevées dans la norme. (Dont une, c'est amusant, causée par le traitement du source du RFC, traitement qui avait fait disparaitre accidentellement des barres obliques inversées.)

Donc, notre RFC 9682 modifie l'ABNF qui décrit les littéraux pour les chaines de caractères, ABNF qui était trop laxiste (section 2 du RFC). Il change également la grammaire générale (section 3) pour autoriser (au niveau syntaxique) des schémas vides (ils restent interdits au niveau sémantique). Ainsi, l'ancienne règle :

cddl = S 1*(rule S)
  

devient :

cddl = S *(rule S)        
  

Téléchargez le RFC 9682


L'article seul

RFC 9649: WebP Image Format

Date de publication du RFC : Novembre 2024
Auteur(s) du RFC : J. Zern, P. Massimino, J. Alakuijala (Google)
Pour information
Première rédaction de cet article le 19 novembre 2024


Un RFC sur un format d'image : il décrit le format WebP et enregistre officiellement le type image/webp.

Bon, des images au format WebP, vous en avez forcément vu un peu partout sur le Web. Mais le format n'était pas encore documenté par un organisme de normalisation. C'est désormais fait. WebP s'appuie sur le format RIFF. Plus précisément, RIFF est un cadre générique qui peut se décliner en divers formats. C'est pour cela que les fichiers WebP commencent par les quatre codes ASCII correspondant à "RIFF".

WebP permet de la compression avec perte ou sans perte, et, d'une manière générale, tout ce qu'on attend d'un format graphique. C'est donc un concurrent de JPEG, PNG (RFC 2083), GIF… L'encodage lors de la compression avec perte est celui de VP8 (RFC 6386), produisant des images plus petites que ses prédécesseurs, ce qui est bon pour le réseau. La compression sans perte est faite en LZ77 et Huffman. WebP permet également le stockage de métadonnées codées en EXIF ou en XMP. Ah, et WebP permet des animations.

Cette image, sur un sujet politique qui est toujours d'actualité, est au format WebP : how-do-you-like-it-wrapped.webp

La section 2 du RFC décrit le format en détail. Les trois premiers champs sont la chaine "RIFF", la taille du fichier en binaire et la chaine "WEBP", chacun sur quatre octets. Affichons ces trois champs :

% dd if=how-do-you-like-it-wrapped.webp bs=4 count=3
RIFFXWEBP
3+0 records in
3+0 records out
12 bytes copied…

La section 3 décrit ensuite le stockage des pixels sans perte.

Comme avec tout format, les logiciels qui lisent les fichiers WebP (qu'on télécharge souvent depuis l'Internet, via des sources pas forcément de confiance) doivent être prudents dans l'analyse des fichiers. Les fichiers peuvent être invalides, par accident ou délibérément, et mener le logiciel négligent à lire en dehors d'un tableau ou déréférencer un pointeur invalide. La paranoïa est recommandée quand on lit ces fichiers. Plusieurs failles ont touché la libwebp, l'implémentation de référence, dont la grave CVE-2023-4863 en 2023 qui avait fait, à juste titre, beaucoup de bruit.

Toujours question sécurité, WebP n'a pas de contenu exécutable (contrairement à, par exemple, TrueType). Mais les métadonnées EXIF ou en XMP peuvent poser des problèmes de sécurité et doivent donc être interprétées avec prudence.

Si on regarde des fichiers WebP, on a ce genre d'informations :

% file resolution-dns.webp
resolution-dns.webp: RIFF (little-endian) data, Web/P image

% file --mime-type resolution-dns.webp
resolution-dns.webp: image/webp
   

Pour finir, produisons un peu d'images WebP pour voir. Si on utilise Asymptote, c'est facile :

%  asy -f webp -o resolution-dns.webp resolution-dns.asy
  

On peut aussi convertir depuis les formats existants, ici avec ImageMagick :

% convert -verbose resolution-dns.png resolution-dns.webp
resolution-dns.png PNG 823x508 823x508+0+0 8-bit sRGB 31713B 0.020u 0:00.011
resolution-dns.png=>resolution-dns.webp PNG 823x508 823x508+0+0 8-bit sRGB 16580B 0.040u 0:00.047
  

Si on fait des graphiques depuis ses programmes en Python avec Matplotlib, il suffit, depuis la version 3.6, de :

plot.savefig(fname="test.webp") # No need to indicate the format, it
                                  # is taken from the file extension.
  

(Voir aussi ce beau résultat sur Wikimedia Commons.)


Téléchargez le RFC 9649


L'article seul

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 dhcp-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 TCP, est de détecter si la machine en face est toujours là. Par défaut, TCP 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 TCP 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 TCP 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 TCP 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 tcpdump 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 tcpdump. D'ailleurs, ce programme a une option pour afficher le code BPF produit :


% sudo tcpdump -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é. Comme me le fait remarquer Pierre Lebeaupin, il y a une bogue dans le source ci-dessus : l'incrémentation du compteur n'est pas atomique et donc, si on a plusieurs CPU, on risque de perdre certaines incrémentations. La solution de ce problème est laissé à la lectrice.

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 pcpu 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 tcp_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 TCP/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 (legal@ietf.org) 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'abusent 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 BCP 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 BCP 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

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.