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.


Developing and running an Internet crawler

First publication of this article on 23 December 2020


I've just developed and now runs an Internet crawler. Yes, the sort of bots that goes around and gather content. But not a Web crawler. This is for Gemini. Here are a few lessons learned.

If you don't know Gemini, there is no Wikipedia page yet, so you have to go to the official site. Basically, Gemini is born from a disenchantment: the Web is technically too complicated, it is now impossible to write a browser from scratch and because of that the competition is very limited. This technical complexity does not even serve the interests of the users: it creates distractions (such as videos automatically starting), it encourages Web sites authors to focus on the look, not on the content, and it adds a lot of opportunities for surveillance. Gemini relies on a simpler protocol, with no extensions, and a simpler format.

Today, the "geminispace" is quite small. This makes easy and reasonable to write a crawler to explore it completely. This is what I did with the Lupa program, which is now live on one of my machines. The goal of this crawler is not to be used for a search engine (unlike the crawler used in the Gemini search engine gus.guru) but to do statistics and to survey the geminispace. You can see the results on Gemini at the URI gemini://gemini.bortzmeyer.org/software/lupa/stats.gmi. If you don't have a Gemini client yet, here is what it looks like, seen with the Lagrange client : stats-lagrange.png

Now, what is the current state of the geminispace?

  • 506 capsules (a Gemini capsule is a single host, a bit like a Web site) are known but Lupa could reach only 415 of them. (Gemini is quite experimental and many capsules are short-lived. Also, some links are examples and point to non-existing capsules.)
  • The biggest capsule, both by the number of URIs it hosts and by the number of bytes it contains, is gemini.spam.works. Its content is mostly old files, some distributed on Usenet a long time ago. The second capsule by the number of bytes is my own gemini.bortzmeyer.org because it contains a mirror of RFCs.
  • The question of certificates is touchy. Gemini suggests the use of self-signed certificates, augmented with TOFU, but not everyone agrees. Today, 17 % of the known capsules use a certificate issued by Let's Encrypt, the rest being probably self-signed.
  • As it is for the Web, a same machine, with one IP address can host several "virtual hosts", several capsules. We observed 371 different IP addresses, among which 17 % use a modern protocol, IPv6. The IP address with the greatest number of "virtual hosts" is at Linode and is used for public hosting of Gemini capsules, hence its huge number of virtual hosts.
  • Each capsule is identified by a domain name. Which TLD are used for these names? The most popular is .online but this is because the same very common Gemini hosting service hosts many capsules under its name in .online, which skews the results. After that, the most popular TLDs are .com, .org, .net and .space.
  • 64,000 URIs are known but we got only 50,000 of them. Lupa follows the robots.txt exclusion system (more on that later) which means that some capsules or some parts of capsules cannot be crawled. Also, Lupa has a limit on how many URIs to get from a single capsule.
  • The most common media types (60 % of the total) is of course text/gemini alias "gemtext", the reference format for Gemini. Plain text comes after, with 30 %. Remember that Gemini is young and a lot of content has been produced by mirroring existing content, which is often in plain text. There are even 2 % of the URIs which are in HTML, which is surprising. Only 0.3 % are in Markdown, which should be more in the Gemini spirit than HTML.
  • The Gemini protocol allows servers to tag the resources with the language they're written in. The vast majority of the resources does not use this feature, maybe because they're written in English and assume it is the world's default? Among the tagged resources, the most common language is English, then French, then (but far after) Spanish.

Keep in mind that no crawler could explore everything. If there are capsules out here which are not linked from the capsules we know, they won't be retrieved.

What are the issues when running a crawler on the geminispace? Since bots can create a serious load on some servers, a well-behaved bot is supposed to limit itself, and to follow the preferences expressed by the server. Unfortunately, there is no proper standard to express these preferences. The Web uses robots.txt but it is not really standardized. The original specification is very simple (may be too simple), and many robots.txt files use one or another form of extensions, such as the Allow: directive or globbing. (IETF is currently trying to standardize robots.txt.) Because of that, you can never be sure that your robots.txt will be interpreted as you want. This is even worse in the geminispace where it is not clear or specified if robots.txt apply and, if so, which variant.

Another big problem when running a bot is the variety of network problems you can encounter. The simplest case is when a server replies with some Gemini error code (51 for "resource not found", the equivalent of the famous HTTP 404) or when it rejects Gemini connections right away (TCP RST for instance). But many servers react in much stranger ways: timeout when connecting (no response, not even a rejection), accepting the TCP connection but no response to the start of the TLS negotiation, accepting the TLS session but no response afterwards to the Gemini request, etc. A lot of network operations can leave your bot stuck forever, or make it run in an endless loop (for instance never-ending redirections). It is very important to use defensive programming and to plan for the worst. And to set a limit to everything (size of the resources, number of resources per capsule, etc). It is a general rule of programming that a simple implementation which does 90 % of the job will be done quickly (may be 10 % of the total time of the project), but a real implementation able to handle 100 % of the job will take much longer. This is even more so when managing a crawler.


L'article seul

RFC 8970: IMAP4 Extension: Message Preview Generation

Date de publication du RFC : Décembre 2020
Auteur(s) du RFC : M. Slusarz (Open-Xchange)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF extra
Première rédaction de cet article le 19 décembre 2020


Le protocole IMAP d'accès aux boites aux lettres (RFC 3501) continue à évoluer et reçoit de nouvelles extensions. Celle normalisée dans ce RFC permet au client IMAP, le MUA, de ne récupérer qu'une partie du message, afin d'afficher un avant-gout de celui-ci à l'utilisateur humain, qui pourra ainsi mieux choisir s'il veut lire ce message ou pas.

Il y a déjà des clients de messagerie qui présentent le début du message mais, sans l'extension de ce RFC, cela nécessite de tout récupérer (un FETCH BODYSTRUCTURE pour savoir quelle partie MIME récupérer, suivi d'un FETCH BODY, et sans possibilité de les exécuter en parallèle) avant de ne sélectionner qu'une partie. Au contraire, avec l'extension PREVIEW (« avant-gout »), c'est le serveur IMAP qui va sélectionner cet avant-gout. Avantages : une présélection qui est identique sur tous les clients, moins de travail pour le client et surtout moins de données transmises. Avant, le client était forcé de récupérer beaucoup de choses car il ne pouvait pas savoir à l'avance combien d'octets récolter avant de générer l'avant-gout. Si le message était du texte brut, OK, mais si c'était de l'HTML, il pouvait être nécessaire de ramasser beaucoup d'octets de formatage et de gadgets avant d'en arriver au vrai contenu. (Ou bien, il fallait procéder progressivement, récupérant une partie du message, puis, si nécessaire, une autre, ce qui augmentait la latence.)

Donc, concrètement, comment ça se passe ? La section 3 de notre RFC décrit l'extension en détail. Elle a la forme d'un attribut PREVIEW qui suit la commande FETCH (RFC 3501, section 6.4.5). Voici un exemple, la commande étant étiquetée MYTAG01 :

Client :    
MYTAG01 FETCH 1 (PREVIEW)

Serveur :
* 1 FETCH (PREVIEW "Bonjour, voulez-vous gagner plein d'argent rapidement ?")
MYTAG01 OK FETCH complete.
  

Idéalement, le serveur renvoie toujours le même avant-gout pour un message donné (mais le RFC ne l'impose pas car cela peut être difficile dans certains cas, par exemple en cas de mise à jour du logiciel du serveur, qui change l'algorithme de génération des avant-gouts).

La syntaxe formelle de l'attribut PREVIEW est en section 6 du RFC.

Le format de l'avant-gout est forcément du texte brut, encodé en UTF-8, et ne doit pas avoir subi d'encodages baroques comme Quoted-Printable. Sa longueur est limitée à 256 caractères (caractères Unicode, pas octets, attention si vous programmez un client et que votre tampon est trop petit).

Le contenu de l'avant-gout est typiquement composé des premiers caractères du message. Cela implique qu'il peut contenir des informations privées et il ne doit donc être montré qu'aux clients qui sont autorisés à voir le message complet.

Parfois, le serveur ne peut pas générer un avant-gout, par exemple si le message est chiffré avec OpenPGP (RFC 4880) ou bien si le message est entièrement binaire, par exemple du PNG. Dans ces cas, le serveur est autorisé à renvoyer une chaîne de caractères vide.

Si le serveur génère un avant-gout lui-même (du genre « Image de 600x600 pixels, prise le 18 décembre 2020 », en utilisant les métadonnées de l'image), il est recommandé qu'il choisisse la langue indiquée par l'extension LANGUAGE (RFC 5255).

Comme l'avant-gout n'est pas forcément indispensable pour l'utilisateur, le RFC suggère (section 4) de le charger en arrière-plan, en affichant la liste des messages sans attendre tous ces avant-gouts.

Le serveur IMAP qui sait générer ces avant-gouts l'annonce via la capacité PREVIEW, qui est notée dans le registre des capacités. Voici un exemple :

Client :
MYTAG01 CAPABILITY

Serveur :
* CAPABILITY IMAP4rev1 PREVIEW
MYTAG01 OK Capability command completed.

Client :
MYTAG02 FETCH 1 (RFC822.SIZE PREVIEW)

Serveur :
* 1 FETCH (RFC822.SIZE 5647 PREVIEW {200}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Curabitur aliquam turpis et ante dictum, et pulvinar dui congue.
ligula nullam
)
MYTAG02 OK FETCH complete. 
  

Attention si vous mettez en œuvre cette extension, elle nécessite davantage de travail du serveur, donc un client méchant pourrait surcharger ledit serveur. Veillez bien à authentifier les clients, pour retrouver le méchant (section 7 du RFC).

Cette extension est déjà mise en œuvre dans Dovecot et Cyrus.


Téléchargez le RFC 8970


L'article seul

RFC 8953: Coordinating Attack Response at Internet Scale 2 (CARIS2) Workshop Report

Date de publication du RFC : Décembre 2020
Auteur(s) du RFC : K. Moriarty (Dell Technologies)
Pour information
Première rédaction de cet article le 17 décembre 2020


Voici le compte-rendu de la deuxième édition de l'atelier CARIS (Coordinating Attack Response at Internet Scale), un atelier de l'ISOC consacré à la défense de l'Internet contre les différentes attaques possibles, par exemple les dDoS. Cet atelier s'est tenu à Cambridge en mars 2019. Par rapport au premier CARIS, documenté dans le RFC 8073, on note l'accent mis sur les conséquences du chiffrement, désormais largement répandu.

Les problèmes de sécurité sur l'Internet sont bien connus. C'est tous les jours qu'on entend parler d'une attaque plus ou moins réussie contre des infrastructures du réseau. Ainsi, Google a été victime d'une grosse attaque en 2017 (mais qui n'a été révélée que des années après). Mais, pour l'instant, nous n'avons pas de solution miracle. L'idée de base des ateliers CARIS est de rassembler aussi bien des opérateurs de réseau, qui sont « sur le front » tous les jours, que des chercheurs, des fournisseurs de solutions de défense, et des CSIRT, pour voir ensemble ce qu'on pouvait améliorer. Pour participer, il fallait avoir soumis un article, et seules les personnes dont un article était accepté pouvait venir, garantissant un bon niveau de qualité aux débats, et permettant de limiter le nombre de participants, afin d'éviter que l'atelier ne soit juste une juxtaposition de discours.

La section 2 du RFC présente les quatorze papiers qui ont été acceptés. On les trouve en ligne.

Le but de l'atelier était d'identifier les points sur lesquels des progrès pourraient être faits. Par exemple, tout le monde est d'accord pour dire qu'on manque de professionnel·le·s compétent·e·s en cybersécurité mais il ne faut pas espérer de miracles : selon une étude, il manque trois millions de personnes dans ce domaine et il n'y a simplement aucune chance qu'on puisse les trouver à court terme. Plus réaliste, l'atelier s'est focalisé sur le déploiement du chiffrement (TLS 1.3, normalisé dans le RFC 8446, le futur - à l'époque - QUIC, et pourquoi pas le TCPcrypt du RFC 8548), déploiement qui peut parfois gêner la détection de problèmes, et sur les mécanismes de détection et de prévention. Une importance particulière était donnée au passage à l'échelle (on ne peut plus traiter chaque attaque individuellement et manuellement, il y en a trop).

Bon, maintenant, les conclusions de l'atelier (section 4). Première session, sur l'adoption des normes. C'est une banalité à l'IETF que de constater que ce n'est pas parce qu'on a normalisé une technique de sécurité qu'elle va être déployée. Beaucoup de gens aiment râler contre l'insécurité de l'Internet mais, dès qu'il s'agit de dépenser de l'argent ou du temps pour déployer les solutions de sécurité, il y a moins d'enthousiasme. (J'écris cet article au moment de la publication de la faille de sécurité SadDNS. Cela fait plus de dix ans qu'on a une solution opérationnelle contre la famille d'attaques dont SadDNS fait partie, DNSSEC et, pourtant, DNSSEC n'est toujours pas déployé sur la plupart des domaines.) Commençons par un point optimiste : certaines des technologies de sécurité de l'IETF ont été largement déployées, comme SSL (RFC 6101), remplacé il y a quinze ans par TLS (RFC 8446). L'impulsion initiale venait clairement du secteur du commerce électronique, qui voulait protéger les numéros des cartes de crédit. Lié à TLS, X.509 (RFC 5280) est aussi un succès. Cette fois, l'impulsion initiale est plutôt venue des États. (X.509 doit être une des très rares normes UIT survivantes sur l'Internet.)

Moins directement lié à la sécurité, SNMP (RFC 3410) est aussi un succès, même s'il est en cours de remplacement par les techniques autour de YANG comme RESTCONF. Toujours pour la gestion de réseaux, IPfix (RFC 7011) est également un succès, largement mis en œuvre sur beaucoup d'équipements réseau.

Par contre, il y a des semi-échecs et des échecs. Le format de description d'incidents de sécurité IODEF (RFC 7970) ne semble pas très répandu. (Il a un concurrent en dehors de l'IETF, STIX - Structured Threat Information eXpression, qui ne semble pas mieux réussir.) IODEF est utilisé par des CSIRT mais souffre de son niveau de détail (beaucoup d'opérationnels veulent des synthèses, pas des données brutes) et, comme toutes les techniques d'échange d'information sur les questions de sécurité, souffre également des problèmes de confiance qui grippent la circulation de l'information. Autre technique de sécurité excellente mais peu adoptée, DANE (RFC 7671). Malgré de nombreux efforts de promotion (comme https://internet.nl, le blog que vous lisez a une note de 93 %, car la configuration TLS est tolérante) et même avec une reconnaissance légale partielle en Allemagne, DANE reste très minoritaire.

Un autre cas fameux de non-succès, même s'il n'est pas directement lié à la sécurité, est IPv6 (RFC 8200).

Deuxième session, les protocoles nouveaux. L'atelier s'est penché sur le format MUD (Manufacturer Usage Description, RFC 8520) qui pourrait aider à boucher une petite partie des trous de sécurité de l'Internet des objets. Il a également travaillé l'échange de données et les problèmes de confiance qu'il pose. Comme à CARIS 1, plusieurs participants ont noté que cet échange de données reste gouverné par des relations personnelles. La confiance ne passe pas facilement à l'échelle. L'échange porte souvent sur des IOC et un standard possible a émergé, MISP.

Une fois le problème détecté, il reste à coordonner la réaction, puisque l'attaque peut toucher plusieurs parties. C'est encore un domaine qui ne passe guère à l'échelle. L'Internet n'a pas de mécanisme (technique mais surtout humain) pour coordonner des centaines de victimes différentes. Des tas d'obstacles à la coordination ont été mentionnés, des outils trop difficiles à utiliser en passant par les obstacles frontaliers à l'échange, les obligations légales qui peuvent interdire l'échange de données, et bien sûr le problème récurrent de la confiance. Vous vous en doutez, pas plus qu'au premier atelier, il n'y aura eu de solution parfaite découverte pendant les sessions.

La session sur la surveillance a vu plusieurs discussions intéressantes. Ce fut le cas par exemple du problème de la réputation des adresses IP. Ces adresses sont souvent des IOC et on se les échange souvent, ce qui soulève des questions liées à la vie privée. (Un des papiers de l'atelier est « Measured Approaches to IPv6 Address Anonymization and Identity Association », de David Plonka et Arthur Berger , qui explique la difficulté de l'« anonymisation » des adresses IP si on veut qu'elles restent utiles pour les opérationnels.) L'exploitation correcte de ces adresses IP nécessite de connaitre les plans d'adressage utilisés (si une adresse IPv6 se comporte mal, faut-il bloquer tout le préfixe /64 ? Tout le /48 ?). Il n'y a pas de ressources publiquement disponibles à ce sujet, qui permettrait de connaitre, pour une adresse IP donnée, l'étendue du préfixe englobant. (Je ne parle évidemment pas du routage, pour lequel ces bases existents, mais de la responsabilité.) Une des suggestions était d'étendre les bases des RIR. Une autre était de créer une nouvelle base. Le problème est toujours le même : comment obtenir que ces bases soient peuplées, et correctement peuplées ?

Une des questions amusantes lorsqu'on essaie de déboguer un problème de communication entre deux applications est de savoir quoi faire si la communication est chiffrée. Il n'est évidemment pas question de réclamer une porte dérobée pour court-circuiter le chiffrement, cela créerait une énorme faille de sécurité. Mais alors comment faire pour savoir ce qui se dit ? On a besoin de la coopération de l'application. Mais toutes les applications ne permettent pas facilement de journaliser les informations importantes et, quand elles le font, ce n'est pas dans un format cohérent. D'où une suggestion lors de l'atelier de voir s'il ne serait pas envisageable de mettre cette fonction dans les compilateurs, pour avoir un mécanisme de journalisation partout disponibles.

Pendant qu'on parle de chiffrement, une autre question est celle de l'identification d'une machine ou d'un protocole par le fingerprinting, c'est-à-dire en observant des informations non chiffrées (taille des paquets, temps de réponse, variations permises par le protocole, etc). Le fingerprinting pose évidemment des gros risques pour la vie privée et beaucoup de travaux sur des protocoles récents (comme QUIC) visaient à limiter son efficacité.

Pour résumer l'atelier (section 6 du RFC), plusieurs projets ont été lancés pour travailler sur des points soulevés dans l'atelier. À suivre, donc.


Téléchargez le RFC 8953


L'article seul

RFC 8949: Concise Binary Object Representation (CBOR)

Date de publication du RFC : Décembre 2020
Auteur(s) du RFC : C. Bormann (Universität Bremen TZI), P. Hoffman (ICANN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF cbor
Première rédaction de cet article le 5 décembre 2020


Il existait un zillion de formats binaires d'échange de données ? Et bien ça en fera un zillion plus un. CBOR (Concise Binary Object Representation) est un format qui utilise un modèle de données très proche de celui de JSON, mais est encodé en binaire, avec comme but principal d'être simple à encoder et décoder, même par des machines ayant peu de ressources matérielles. Normalisé à l'origine dans le RFC 7049, il est désormais spécifié dans ce nouveau RFC. Si le texte de la norme a changé, le format reste le même.

Parmi les autres formats binaires courants, on connait ASN.1 (plus exactement BER ou DER, utilisés dans plusieurs protocoles IETF), EBML ou MessagePack mais ils avaient des cahiers des charges assez différents (l'annexe E du RFC contient une comparaison). CBOR se distingue d'abord par sa référence à JSON (RFC 8259), dont le modèle de données sert de point de départ à CBOR, puis par le choix de faciliter le travail des logiciels qui devront créer ou lire du CBOR. CBOR doit pouvoir tourner sur des machines très limitées (« classe 1 », en suivant la terminologie du RFC 7228). Par contre, la taille des données encodées n'est qu'une considération secondaire (section 1.1 du RFC pour une liste prioritisée des objectifs de CBOR). Quant au lien avec JSON, l'idée est d'avoir des modèles de données suffisamment proches pour qu'écrire des convertisseurs CBOR->JSON et JSON->CBOR soit assez facile, et pour que les protocoles qui utilisent actuellement JSON puissent être adaptés à CBOR sans douleur excessive. CBOR se veut sans schéma, ou, plus exactement, sans schéma obligatoire. Et le but est que les fichiers CBOR restent utilisables pendant des dizaines d'années, ce qui impose d'être simple et bien documenté.

La spécification complète de CBOR est en section 3 de ce RFC. Chaque élément contenu dans le flot de données commence par un octet dont les trois bits de plus fort poids indiquent le type majeur. Les cinq bits suivants donnent des détails. Ce mécanisme permet de programmeur un décodeur CBOR avec une table de seulement 256 entrées (l'annexe B fournit cette table et l'annexe C un décodeur en pseudo-code très proche de C). Pour un entier, si la valeur que codent ces cinq bits suivants est inférieure à 24, elle est utilisée telle quelle. Sinon, cela veut dire que les détails sont sur plusieurs octets et qu'il faut lire les suivants (la valeur des cinq bits codant la longueur à lire). Selon le type majeur, les données qui suivent le premier octet sont une valeur (c'est le cas des entiers, par exemple) ou bien un doublet {longueur, valeur} (les chaînes de caractères, par exemple). L'annexe A de notre RFC contient de nombreux exemples de valeurs CBOR avec leur encodage.

Quels sont les types majeurs possibles ? Si les trois premiers bits sont à zéro, le type majeur, 0, est un entier non signé. Si les cinq bits suivants sont inférieurs à 24, c'est la valeur de cet entier. S'ils sont égaux à 24, c'est que l'entier se trouve dans l'octet suivant l'octet initial, s'ils sont égaux à 25, que l'entier se trouve dans les deux octets suivants, et ainsi de suite (31 est réservé pour les tailles indéterminées, décrites plus loin). L'entier 10 se représentera donc 00001010, l'entier 42 sera 00011000 00101010, etc. Presque pareil pour un type majeur de 1, sauf que l'entier sera alors signé, et négatif. La valeur sera -1 moins la valeur encodée. Ainsi, -3 sera 00100010. Vous voulez vérifier ? L'excellent terrain de jeu http://cbor.me vous le permet, essayez par exemple http://cbor.me?diag=42.

Le type majeur 2 sera une chaîne d'octets (principal ajout par rapport au modèle de données de JSON). La longueur est codée d'abord, en suivant la même règle que pour les entiers. Puis viennent les données. Le type 3 indique une chaîne de caractères et non plus d'octets. Ce sont forcément des caractères Unicode, encodés en UTF-8 (RFC 3629). Le champ longueur (codé comme un entier) indique le nombre d'octets de l'encodage UTF-8, pas le nombre de caractères (pour connaître ce dernier, il faut un décodeur UTF-8). Vous voulez des exemples ? Connectez-vous à http://www.cbor.me/?diag=%22lait%22 et vous voyez que la chaîne « lait » est représentée par 646c616974 : 64 = 01100100, type majeur 3 puis une longueur de 4. Les codes ASCII suivent (rappelez-vous qu'ASCII est un sous-ensemble d'UTF-8). Avec des caractères non-ASCII comme http://www.cbor.me/?diag=%22caf%C3%A9%22, on aurait 65636166c3a9 (même type majeur, longueur 5 octets, puis les caractères, avec c3a9 qui code le é en UTF-8).

Le type majeur 4 indique un tableau. Rappelez-vous que CBOR utilise un modèle de données qui est très proche de celui de JSON. Les structures de données possibles sont donc les tableaux et les objets (que CBOR appelle les maps). Un tableau est encodé comme une chaîne d'octets, longueur (suivant les règles des entiers) puis les éléments du tableau, à la queue leu leu. La longueur est cette fois le nombre d'éléments, pas le nombre d'octets. Les éléments d'un tableau ne sont pas forcément tous du même type. Les tableaux (et d'autres types, cf. section 3.2) peuvent aussi être représentés sans indiquer explicitement la longueur ; le tableau est alors terminé par un élément spécial, le break code. Par défaut, un encodeur CBOR est libre de choisir la forme à longueur définie ou celle à longueur indéfinie, et le décodeur doit donc s'attendre à rencontrer les deux.

Le type majeur 5 indique une map (ce qu'on appelle objet en JSON et dictionnaire ou hash dans d'autres langages). Chaque élément d'une map est un doublet {clé, valeur}. L'encodage est le même que pour les tableaux, la longueur étant le nombre de doublets. Chaque doublet est encodé en mettant la clé, puis la valeur. Donc, le premier scalaire est la clé de la première entrée de la map, le deuxième la valeur de la première entrée, le troisième la clé de la deuxième entrée, etc.

Les clés doivent être uniques (une question problématique en JSON où les descriptions existantes de ce format ne sont ni claires ni cohérentes sur ce point).

Je passe sur le type majeur 6, voyez plus loin le paragraphe sur les étiquettes. Le type majeur 7 sert à coder les flottants (encodés ensuite en IEEE 754) et aussi d'autres types scalaires et le break code utilisé dans le paragraphe suivant. Les autres types scalaires, nommés « valeurs simples » (simple values) sont des valeurs spéciales comme 20 pour le booléen Faux, 21 pour le Vrai, et 22 pour le néant. Elles sont stockées dans un registre IANA.

Dans la description ci-dessus, les types vectoriels (tableaux, chaînes, maps) commencent par la longueur du vecteur. Pour un encodeur CBOR, cela veut dire qu'il faut connaître cette longueur avant même d'écrire le premier élément. Cela peut être contraignant, par exemple si on encode au fil de l'eau (streaming) des données en cours de production. CBOR permet donc d'avoir des longueurs indéterminées. Pour cela, on met 31 comme « longueur » et cette valeur spéciale indique que la longueur n'est pas encore connue. Le flot des éléments devra donc avoir une fin explicite cette fois, le break code. Celui-ci est représenté par un élément de type majeur 7 et de détails 31, donc tous les bits de l'octet à 1. Par exemple, http://cbor.me/?diag=%28_%20%22lait%22%29 nous montre que la chaîne « lait » ainsi codée (le _ indique qu'on veut un codage en longueur indéterminée) sera 7f646c616974ff. 7f est le type majeur 3, chaîne de caractères, avec la longueur 31, indiquant qu'elle est indéterminée. Puis suit la chaîne elle-même (les chaînes indéterminées en CBOR sont faites par concaténation de châines de longueur déterminée), puis le break code ff.

La même technique peut être utilisée pour les chaînes d'octets et de caractères, afin de ne pas avoir à spécifier leur longueur au début. Cette possibilité de listes de longueur indéterminée a été ajoutée pour faciliter la vie du streaming.

Revenons au type majeur 6. Il indique une étiquette (tag), qui sert à préciser la sémantique de l'élément qui suit (cf. section 3.4). Un exemple typique est pour indiquer qu'une chaîne de caractères est un fait une donnée structurée, par exemple une date ou un numéro de téléphone. Un décodeur n'a pas besoin de comprendre les étiquettes, il peut parfaitement les ignorer. Les valeurs possibles pour les étiquettes sont stockées dans un registre IANA, et on voit que beaucoup ont déjà été enregistrées, en plus de celles de ce RFC (par exemple par le RFC 8746 ou par le RFC 8782).

Quelques valeurs d'étiquette intéressantes ? La valeur 0 indique une date au format du RFC 3339 (une chaîne de caractères). La valeur 1 étiquette au contraire un entier, et indique une date comme un nombre de secondes depuis le 1er janvier 1970. Les valeurs négatives sont autorisées mais leur sémantique n'est pas normalisée (UTC n'est pas défini pour les dates avant l'epoch, surtout quand le calendrier a changé).

Les valeurs 2 et 3 étiquettent une chaîne d'octets et indiquent qu'on recommande de l'interpréter comme un grand entier (dont la valeur n'aurait pas tenu dans les types majeurs 0 ou 1). Les décodeurs qui ne gèrent pas les étiquettes se contenteront de passer à l'application cette chaîne d'octets, les autres passeront un grand entier.

Autre cas rigolos, les nombres décimaux non entiers. Certains ne peuvent pas être représentés de manière exacte sous forme d'un flottant. On peut alors les représenter par un couple [exposant, mantisse]. Par exemple, 273,15 est le couple [-2, 27315] (l'exposant est en base 10). On peut donc l'encoder en CBOR sous forme d'un tableau de deux éléments, et ajouter l'étiquette de valeur 4 pour préciser qu'on voulait un nombre unique.

D'autres étiquettes précisent le contenu d'une chaîne de caractères : l'étiquette 32 indique que la chaîne est un URI, la 34 que la chaîne est du Base64 (RFC 4648) et la 36 que cela va être un message MIME (RFC 2045). Comme l'interprétation des étiquettes est optionnelle, un décodeur CBOR qui n'a pas envie de s'embêter peut juste renvoyer à l'application cette chaîne.

Une astuce amusante pour finir les étiquettes, et la spécification du format : l'étiquette 55799 signifie juste que ce qui suit est du CBOR, sans modifier sa sémantique. Encodée, elle sera représentée par 0xd9d9f7 (type majeur 6 sur trois bits, puis détails 25 qui indiquent que le nombre est sur deux octets puis le nombre lui-même, d9f7 en hexa). Ce nombre 0xd9d9f7 peut donc servir de nombre magique. Si on le trouve au début d'un fichier, c'est probablement du CBOR (il ne peut jamais apparaître au début d'un fichier JSON, donc ce nombre est particulièrement utile quand on veut distinguer tout de suite si on a affaire à du CBOR ou à du JSON).

Maintenant que le format est défini rigoureusement, passons à son utilisation. CBOR est conçu pour des environnements où il ne sera souvent pas possible de négocier les détails du format entre les deux parties. Un décodeur CBOR générique peut décoder sans connaître le schéma utilisé en face. Mais, en pratique, lorsqu'un protocole utilise CBOR pour la communication, il est autorisé (section 5 du RFC) à mettre des restrictions, ou des informations supplémentaires, afin de faciliter la mise en œuvre de CBOR dans des environnements très contraints en ressources. Ainsi, on a parfaitement le droit de faire un décodeur CBOR qui ne gérera pas les nombres flottants, si un protocole donné n'en a pas besoin.

Un cas délicat est celui des maps (section 5.6). CBOR ne place guère de restrictions sur le type des clés et un protocole ou format qui utilise CBOR voudra souvent être plus restrictif. Par exemple, si on veut absolument être compatible avec JSON, restreindre les clés à des chaînes en UTF-8 est souhaitable. Si on tient à utiliser d'autres types pour les clés (voire des types différents pour les clés d'une même map !), il faut se demander comment on les traduira lorsqu'on enverra ces maps à une application. Par exemple, en JavaScript, la clé formée de l'entier 1 est indistinguable de celle formée de la chaîne de caractères "1". Une application en JavaScript ne pourra donc pas se servir d'une map qui aurait de telles clés, de types variés.

On a vu que certains éléments CBOR pouvaient être encodés de différentes manières, par exemple un tableau peut être représenté par {longueur, valeurs} ou bien par {valeurs, break code}. Cela facilite la tâche des encodeurs mais peut compliquer celle des décodeurs, surtout sur les machines contraintes en ressources, et cela peut rendre certaines opérations, comme la comparaison de deux fichiers, délicates. Existe-t-il une forme canonique de CBOR ? Pas à proprement parler mais la section 4.1 décrit la notion de sérialisation favorite, des décodeurs étant autorisés à ne connaitre qu'une sérialisation possible. Notamment, cela implique pour l'encodeur de :

  • Mettre les entiers sous la forme la plus compacte possible. L'entier 2 peut être représenté par un octet (type majeur 0 puis détails égaux à 2) ou deux (type majeur 0, détails à 24 puis deux octets contenant la valeur 2), voire davantage. La forme recommandée est la première (un seul octet). Même règle pour les longueurs (qui, en CBOR, sont encodées comme les entiers).
  • Autant que possible, mettre les tableaux et les chaînes sous la forme {longueur, valeurs}, et pas sous la forme où la longueur est indéfinie.

Tous les encodeurs CBOR qui suivent ces règles produiront, pour un même jeu de données, le même encodage.

Plus stricte est la notion de sérialisation déterministe de la section 4.2. Là encore, chacun est libre de la définir comme il veut (il n'y a pas de forme canonique officielle de CBOR, rappelez-vous) mais elle ajoute des règles minimales à la sérialisation favorite :

  • Trier les clés d'une map de la plus petite à la plus grande. (Selon leur représentation en octets, pas selon l'ordre alphabétique.)
  • Ne jamais utiliser la forme à longueur indéfinie des tableaux et chaînes.
  • Ne pas utiliser les étiquettes si elles ne sont pas nécessaires.

Autre question pratique importante, le comportement en cas d'erreurs. Que doit faire un décodeur CBOR si deux clés sont identiques dans une map, ce qui est normalement interdit en CBOR ? Ou si un champ longueur indique qu'on va avoir un tableau de 5 éléments mais qu'on n'en rencontre que 4 avant la fin du fichier ? Ou si une chaîne de caractères, derrière son type majeur 3, n'est pas de l'UTF-8 correct ? D'abord, un point de terminologie important : un fichier CBOR est bien formé si sa syntaxe est bien celle de CBOR, il est valide s'il est bien formé et que les différents éléments sont conformes à leur sémantique (par exemple, la date après une étiquette de valeur 0 doit être au format du RFC 3339). Si le document n'est pas bien formé, ce n'est même pas du CBOR et doit être rejeté par un décodeur. S'il n'est pas valide, il peut quand même être utile, par exemple si l'application fait ses propres contrôles. Les sections 5.2 et 5.3 décrivent la question. CBOR n'est pas pédant : un décodeur a le droit d'ignorer certaines erreurs, de remplacer les valeurs par ce qui lui semble approprié. CBOR penche nettement du côté « être indulgent avec les données reçues » ; il faut dire qu'une application qui utilise CBOR peut toujours le renforcer en ajoutant l'obligation de rejeter ces données erronées. Un décodeur strict peut donc s'arrêter à la première erreur. Ainsi, un pare-feu qui analyse du CBOR à la recherche de contenu malveillant a tout intérêt à rejeter les données CBOR incorrectes (puisqu'il ne sait pas trop comment elles seront interprétées par la vraie application). Bref, la norme CBOR ne spécifie pas de traitement d'erreur unique. Je vous recommande la lecture de l'annexe C, qui donne en pseudo-code un décodeur CBOR minimum qui ne vérifie pas la validité, uniquement le fait que le fichier est bien formé, et l'annexe F, qui revient sur cette notion de « bien formé » et donne des exemples.

Comme CBOR a un modèle de données proche de celui de JSON, on aura souvent envie d'utiliser CBOR comme encodage efficace de JSON. Comment convertir du CBOR en JSON et vice-versa sans trop de surprises ? La section 6 du RFC se penche sur ce problème. Depuis CBOR vers JSON, il est recommandé de produire du I-JSON (RFC 7493). Les traductions suivantes sont suggérées :

  • Les entiers deviennent évidemment des nombres JSON.
  • Les chaînes d'octets sont encodées en Base64 et deviennent des chaînes de caractères JSON (JSON n'a pas d'autre moyen de transporter du binaire).
  • Les chaînes de caractères deviennent des chaînes de caractères JSON (ce qui nécessite d'en échapper certains, RFC 8259, section 7).
  • Les tableaux deviennent des tableaux JSON et les maps des objets JSON (ce qui impose de convertir les clés en chaînes UTF-8, si elles ne l'étaient pas déjà).
  • Etc.

En sens inverse, de JSON vers CBOR, c'est plus simple, puisque JSON n'a pas de constructions qui seraient absentes de CBOR.

Pour les amateurs de futurisme, la section 7 discute des éventuelles évolutions de CBOR. Pour les faciliter, CBOR a réservé de la place dans certains espaces. Ainsi, le type majeur 7 permettra d'encoder encore quelques valeurs simples (cela nécessitera un RFC sur le chemin des normes, cf. RFC 8126 et la section 9.1 de notre RFC). Et on peut ajouter d'autres valeurs d'étiquettes (selon des règles qui dépendent de la valeur numérique : les valeurs les plus faibles nécessiteront une procédure plus complexe, cf. section 9.2).

CBOR est un format binaire. Cela veut dire, entre autres, qu'il n'est pas évident de montrer des valeurs CBOR dans, mettons, une documentation, contrairement à JSON. La section 8 décrit donc un format texte (volontairement non spécifié en détail) qui permettra de mettre des valeurs CBOR dans du texte. Nulle grammaire formelle pour ce format de diagnostic : il est prévu pour l'utilisation par un humain, pas par un analyseur syntaxique. Ce format ressemble à JSON avec quelques extensions pour les nouveautés de CBOR. Par exemple, les étiquettes sont représentées par un nombre suivi d'une valeur entre parenthèses. Ainsi, la date (une chaîne de caractères étiquetée par la valeur 0) sera notée :

0("2013-10-12T11:34:00Z")

Une map de deux éléments sera notée comme en JSON :

{"Fun": true, "Amt": -2}  

Même chose pour les tableaux. Ici, avec étiquette sur deux chaînes de caractères :

[32("http://cbor.io/"), 34("SW5zw6lyZXogaWNpIHVuIMWTdWYgZGUgUMOicXVlcw==")]

L'annexe G du RFC 8610 ajoute quelques extensions utiles à ce format de diagnostic.

Lors de l'envoi de données encodées en CBOR, le type MIME à utiliser sera application/cbor. Comme l'idée est d'avoir des formats définis en utilisant la syntaxe CBOR et des règles sémantiques spécifiques, on verra aussi sans doute des types MIME utilisant la notation plus du RFC 6839, par exemple application/monformat+cbor.

Voici par exemple un petit service Web qui envoie la date courante en CBOR (avec deux étiquettes différentes, celle pour les dates au format lisible et celle pour les dates en nombre de secondes, et en prime celles du RFC 8943). Il a été réalisé avec la bibliothèque flunn. Il utilise le type MIME application/cbor :

% curl -s https://www.bortzmeyer.org/apps/date-in-cbor  | read-cbor -
...
Tag 0
	String of length 20: 2020-11-16T15:02:24Z
Tag 1
	Unsigned integer 1605538944
	...
  

(Le programme read-cbor est présenté plus loin.)

Un petit mot sur la sécurité (section 10) : il est bien connu qu'un analyseur mal écrit est un gros risque de sécurité et d'innombrables attaques ont déjà été réalisées en envoyant à la victime un fichier délibérement incorrect, conçu pour déclencher une faille de l'analyseur. Ainsi, en CBOR, un décodeur qui lirait une longueur, puis chercherait le nombre d'éléments indiqué, sans vérifier qu'il est arrivé au bout du fichier, pourrait déclencher un débordement de tampon. Les auteurs de décodeurs CBOR sont donc priés de programmer de manière défensive, voire paranoïaque : ne faites pas confiance au contenu venu de l'extérieur.

Autre problème de sécurité, le risque d'une attaque par déni de service. Un attaquant taquin peut envoyer un fichier CBOR où la longueur d'un tableau est un très grand nombre, dans l'espoir qu'un analyseur naïf va juste faire malloc(length) sans se demander si cela ne consommera pas toute la mémoire.

Enfin, comme indiqué plus haut à propos du traitement d'erreur, comme CBOR ne spécifie pas de règles standard pour la gestion des données erronées, un attaquant peut exploiter cette propriété pour faire passer des données « dangereuses » en les encodant de telle façon que l'IDS n'y voit que du feu. Prenons par exemple cette map :

{"CodeToExecute": "OK",
 "CodeToExecute": "DANGER"}

Imaginons qu'une application lise ensuite la donnée indexée par CodeToExecute. Si, en cas de clés dupliquées, elle lit la dernière valeur, elle exécutera le code dangereux. Si un IDS lit la première valeur, il ne se sera pas inquiété. Voilà une bonne raison de rejeter du CBOR invalide (les clés dupliquées sont interdites) : il peut être interprété de plusieurs façons. Notez quand même que ce problème des clés dupliquées, déjà présent en JSON, a suscité des discussions passionnées à l'IETF, entre ceux qui réclamaient une interdiction stricte et absolue et ceux qui voulaient laisser davantage de latitude aux décodeurs. (La section 5.6 est une bonne lecture ici.)

Pour les amateurs d'alternatives, l'annexe E du RFC compare CBOR à des formats analogues. Attention, la comparaison se fait à la lumière du cahier des charges de CBOR, qui n'était pas forcément le cahier des charges de ces formats. Ainsi, ASN.1 (ou plutôt ses sérialisations comme BER ou DER, PER étant nettement moins courant puisqu'il nécessite de connaître le schéma des données) est utilisé par plusieurs protocoles IETF (comme LDAP) mais le décoder est une entreprise compliquée.

MessagePack est beaucoup plus proche de CBOR, dans ses objectifs et ses résultats, et a même été le point de départ du projet CBOR. Mais il souffre de l'absence d'extensibilité propre. Plusieurs propositions d'extensions sont restées bloquées à cause de cela.

BSON (connu surtout via son utilisation dans MongoDB) a le même problème. En outre, il est conçu pour le stockage d'objets JSON dans une base de données, pas pour la transmission sur le réseau (ce qui explique certains de ses choix). Enfin, MSDTP, spécifié dans le RFC 713, n'a jamais été réellement utilisé.

Rappelez-vous que CBOR prioritise la simplicité de l'encodeur et du décodeur plutôt que la taille des données encodées. Néanmoins, un tableau en annexe E.5 compare les tailles d'un même objet encodé avec tous ces protocoles : BSON est de loin le plus bavard (BER est le second), MessagePack et CBOR les plus compacts.

Une liste des implémentations est publiée en https://cbor.io/. Au moins quatre existent, en Python, Ruby, JavaScript et Java. J'avais moi-même écrit un décodeur CBOR très limité (pour un besoin ponctuel) en Go. Il est disponible ici et son seul rôle est d'afficher le CBOR sous forme arborescente, pour aider à déboguer un producteur de CBOR. Cela donne quelque chose du genre :

% ./read-cbor test.cbor
Array of 3 items
	String of length 5: C-DNS
	Map of 4 items
		Unsigned integer 0
 => 		Unsigned integer 0
		Unsigned integer 1
 => 		Unsigned integer 5
		Unsigned integer 4
 => 		String of length 70: Experimental dnstap client, IETF 99 hackathon, data from unbound 1.6.4
		Unsigned integer 5
 => 		String of length 5: godin
	Array of indefinite number of items
		Map of 3 items
			Unsigned integer 0
 => 			Map of 1 items
				Unsigned integer 1
 => 				Array of 2 items
					Unsigned integer 1500204267
					Unsigned integer 0
			Unsigned integer 2
 => 			Map of indefinite number of items
				Unsigned integer 0
 => 				Array of 2 items
					Byte string of length 16
					Byte string of length 16
...

L'annexe G de notre RFC résume les changements depuis le RFC 7049. Le format reste le même, les fichiers CBOR d'avant sont toujours du CBOR. Il y a eu dans ce nouveau RFC des corrections d'erreurs (comme un premier exemple erroné, un autre, et encore un), un durcissement des conditions d'enregistrement des nouvelles étiquettes pour les valeurs les plus basses, une description plus détaillée du modèle de données (la section 2 est une nouveauté de notre RFC), un approfondissement des questions de représentation des nombres, etc. Notre RFC 8949 est également plus rigoureux sur les questions de sérialisation préférée et déterministe. L'étiquette 35, qui annonçait qu'on allait rencontrer une expression rationnelle a été retirée (le RFC note qu'il existe plusieurs normes pour ces expressions et que l'étiquette n'est pas définie de manière assez rigoureuse pour trancher).


Téléchargez le RFC 8949


L'article seul

Fiche de lecture : The trojan war

Auteur(s) du livre : Eric Cline
Éditeur : Oxford University Press
978-0-19-976027-5
Publié en 2013
Première rédaction de cet article le 4 décembre 2020


Vous voulez tout savoir sur la guerre de Troie mais n'avez pas envie de parcourir un livre d'universitaire de 800 pages, avec dix notes de bas de page par page ? Ce livre vous résume ce qu'on sait de cette guerre en 110 pages (écrites petit, il est vrai).

La guerre de Troie a-t-elle eu lieu ? Entre ceux qui prennent au pied de la lettre le récit d'Homère et ceux qui pensent que tout est inventé, il y a de la place pour de nombreuses nuances. Disons pour résumer qu'on a bien trouvé le site physique, qu'il y a bien des signes de guerre et de pillage, que les dates collent plus ou moins avec le bouquin, mais c'est à peu près tout. On n'est pas sûr de l'existence d'Achille, d'Hélène, ou même qu'un cheval ait été utilisé.

Ce livre fait partie de la collection VSI (Very Short Introduction), qui essaie de documenter en un livre court, écrit par un spécialiste, tout ce qu'on sait sur un sujet donné. La guerre de Troie n'est pas un sujet facile, car la légende prend beaucoup plus de place que la réalité. Le livre est en trois parties, chacune apportant un éclairage différent sur ce sujet :

  • L'histoire elle-même, pour celles et ceux qui ont réussi à ne pas en entendre parler, malgré les cours de grec et les adaptations au cinéma.
  • L'analyse des textes, à commencer par l'Iliade. Mais attention, il n'y a pas que l'Iliade.
  • L'analyse archéologique. Si on creuse le sol, que trouve t-on ?

L'histoire, d'abord. Contrairement à ce qu'on pourrait penser, l'Iliade ne contient qu'une petite partie du récit mythique. Il n'y a même pas l'histoire du cheval ! Ce sont d'autres textes (pas forcément écrits par Homère) qui nous content le reste (dont l'Odyssée, qui revient sur certaines évènements de la guerre). On peut donc dresser une version « officielle » à peu près cohérente.

Ensuite, l'analyse des textes, en se rappelant qu'on n'a pas en général le manuscrit original ! Déjà, la guerre est censée se passer bien avant la vie d'Homère. Est-ce cohérent avec le texte ? Oui, sur plusieurs points, Homère décrit des vétements, des armes ou des coutumes qui ne sont pas de son époque (il était plutôt âge du fer quand la guerre a eu lieu à l'âge du bronze). Donc, on ne sait pas si le récit est vrai, mais il est réaliste : Homère reprend bien une histoire qui était déjà ancienne pour lui. Il y a juste quelques erreurs et anachronismes mais rien qui indique que l'Iliade soit un récit complètement légendaire.

Évidemment, il reste des éléments invraisemblables comme les dieux. Et le fait que toute la Grèce soit venue au secours de Ménélas juste pour l'aider à reprendre sa femme ? Bien sûr, on ne ferait pas la guerre pour une seule personne, mais il est toujours possible qu'Hélène ait été un prétexte commode pour une guerre décidée pour d'autres raisons.

Mais il n'y a pas que les textes grecs ! Une des parties les plus intéressantes de l'analyse nous rappelle que nous avons aussi des textes hittites, et que Troie était sans doute une ville vassale ou alliée des Hittites. Est-ce qu'on peut retrouver la guerre de Troie dans ces récits hittites, vérifiant ainsi le récit homérique ? Ce n'est pas facile, déjà parce que les noms propres ne sont pas les mêmes. La ville de Wilusa, souvent citée dans ces textes hittites, est-elle vraiment Troie ? Son roi Alaksandu est-il Pâris, que les textes grecs nomment parfois Alexandre ? Les Ahhiyawa sont-ils bien les Grecs ? Ils ne sont pas vraiment décrits par les Hittites mais tous les autres peuples avec qui les Hittites étaient en contact ont bien été identifiés, il ne manque que les Grecs, qui doivent donc être ces Ahhiyawa, avec qui les Hittites étaient en contact, pas toujours pacifique, sur la côte de l'Anatolie.

Bon, et après s'être pris la tête sur des vieux textes pas très lisibles, et sans index, est-ce qu'on ne peut pas tout simplement creuser et voir si on retrouve bien la cité détruite ? Ça laisse des traces, une bataille ! C'est la troisième partie du livre, sur l'archéologie. On a trouvé un site qui colle mais mais mais il y a plusieurs villes successives, empilées, chaque ville bâtie au-dessus de la précédente, brûlée ou abandonnée. Laquelle de ces couches correspond à la Troie de l'Iliade ? Le niveau VI a le bon âge et pourrait correspondre à la description de la ville par Homère mais rien n'indique une destruction par la guerre. Le niveau VIIa, lui, a bien vu une armée ennemie tout détruire (beaucoup de pointes de flèches ont été découvertes, par exemple) mais sur d'autres points, il ne correspond pas au récit.

En conclusion, non, on ne sait pas, la guerre de Troie a peut-être eu lieu, peut-être à peu près comme Homère l'a raconté, mais on ne peut pas être sûr. Ce n'est pas grave, on peut apprécier le mythe sans certitude de son existence historique.

Et si après avoir lu ce livre, vous cherchez d'autres ressources sur la guerre de Troie, je recommande, de manière tout à fait subjective :

  • La série Les grands mythes d'Arte, avec un excellent mélange d'un dessin animé au style très spécial, et d'œuvres d'art inspirées de ces mythes.
  • L'opéra La Belle Hélène (qui se passe avant la guerre), très drôle et très vivant. (Voyez l'un des airs les plus fameux, Au mont Ida.)

L'article seul

RFC 8958: Updated Registration Rules for URI.ARPA

Date de publication du RFC : Décembre 2020
Auteur(s) du RFC : T. Hardie
Première rédaction de cet article le 3 décembre 2020


Le domaine uri.arpa a été créé par le RFC 3405 pour stocker dans le DNS des règles gouvernant la résolution d'URI via des enregistrements NAPTR. Ce nouveau RFC introduit un très léger changement des procédures d'enregistrement dans ce domaine uri.arpa.

À titre d'exemple de ces règles, vous pouvez regarder la règle pour les URN.

En effet, le RFC 3405 parlait d'un IETF tree qui avait été créé par le RFC 2717 (dans sa section 2.2) mais supprimé par le RFC 4395. Notre RFC 8958 prend simplement acte de cette suppression et retire les mentions IETF tree du RFC 3405.


Téléchargez le RFC 8958


L'article seul

RFC 8947: Link-Layer Addresses Assignment Mechanism for DHCPv6

Date de publication du RFC : Décembre 2020
Auteur(s) du RFC : B. Volz (Cisco), T. Mrugalski (ISC), CJ. Bernardos (UC3M)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dhc
Première rédaction de cet article le 2 décembre 2020


L'utilisation de DHCP pour attribuer des adresses IP est bien connue. Ce nouveau RFC spécifie comment utiliser DHCP pour attribuer des adresses MAC.

Dans quels cas est-ce utile ? La principale motivation vient des environnements virtualisés où on crée des quantités industrielles de machines virtuelles. C'est le cas chez les gros hébergeurs, par exemple, ou bien dans les organisations qui ont d'immenses fermes de machines. Si les adresses MAC de ces machines sont attribuées au hasard, le risque de collision est important, d'autant plus qu'il n'y a pas de protocole de détection de ces collisions. (Sur le risque de collision, notamment en raison du paradoxe de l'anniversaire, voir le RFC 4429, annexe A.1.) Bien sûr, les adresses MAC n'ont pas besoin d'être uniques au niveau mondial, mais la taille de certains réseaux L2 fait que la collision est un réel problème. Un autre scénario est celui des objets connectés (RFC 7228), où leur nombre pourrait menacer l'espace d'adressage OUI. L'idée est donc de récupérer ces adresses MAC auprès d'un serveur DHCP, ce qui évitera les collisions.

En effet, le protocole DHCP, normalisé pour sa version IPv6 dans le RFC 8415, ne sert pas qu'à attribuer des adresses IP. On peut s'en servir pour n'importe quel type de ressources. Et il offre toutes les fonctions nécessaires pour gérer ces ressources, et de nombreuses mises en œuvre déjà bien testées. Notre RFC va donc s'appuyer dessus pour les adresses MAC de 48 bits (EUI-48) d'IEEE 802 (et peut-être dans le futur pour d'autres types d'adresses).

Dans ces adresses de 48 bits, un bit nous intéresse particulièrement, le U/L. Comme son nom l'indique (U = universal, L = local), il indique si l'adresse suit le mécanisme d'allocation de l'IEEE (et est donc a priori unique au niveau mondial) ou bien si l'adresse est gérée selon des règles locales. Les adresses allouées via DHCP seront en général des adresses à gestion locale. Étant purement locales (aucune garantie quant à leur unicité), elles ne doivent pas être utilisées pour fabriquer le DUID - DHCP Unique Identifier - de DHCP (cf. RFC 8415, section 11). Notez aussi que la norme IEEE 802c découpe l'espace local en quatre parties (détails dans l'annexe A du RFC ou, pour les courageuses et les courageux, dans la norme 802c). Pendant qu'on parle de l'IEEE, leur norme 802 1CQ prévoit un mécanisme d'affectation des adresses MAC, qui peut être un concurrent de celui de ce RFC. Le RFC 8948 fournit un moyen de choisir l'un de ces quadrants.

Un peu de terminologie est nécessaire pour suivre ce RFC (section 3). Un bloc d'adresses est une suite consécutive d'adresses MAC. IA_LL désigne une Identity Association for Link-Layer Address et c'est une option DHCP (code 138) qui va beaucoup servir. Autre option DHCP, LLADDR (code 139) qui est l'option qui va servir à transporter les adresses MAC.

La section 4 du RFC présente les principes de déploiement de la solution. Il y a notamment deux scénarios envisagés :

  • Le mode relais, où le client DHCP ne sera pas le destinataire final des adresses MAC. Par exemple, dans le cas de la virtualisation, le client DHCP sera l'hyperviseur qui demandera un bloc d'adresses qu'il attribuera ensuite aux machines virtuelles qu'il crée. Le serveur DHCP verra donc un client très gourmand, demandant de plus en plus d'adresses MAC.
  • Le mode direct, où le client DHCP sera la machine utilisatrice de l'adresse MAC. C'est notamment le mode envisagé pour l'IoT, chaque objet demandant son adresse MAC. Comme il faudra bien une adresse MAC pour faire du DHCP afin de demander une adresse MAC, les objets utiliseront les adresses temporaires normalisées dans IEEE 802.11. Comme l'adresse MAC changera une fois allouée, il faut veiller à ne pas utiliser des commutateurs méchants qui bloquent le port en cas de changement d'adresse.

Bon, sinon, le fonctionnement de l'allocation d'adresses MAC marche à peu près comme celui de l'allocation d'adresses IP. Le client DHCP envoie un message Solicit incluant une option IA_LL qui contient elle-même une option LLADDR qui indique le type d'adresse souhaitée et peut aussi inclure une suggestion, si le client a une idée de l'adresse qu'il voudrait. Le serveur répond avec Advertise contenant l'adresse ou le bloc d'adresses alloué (qui ne sont pas forcément ceux suggérés par le client, comme toujours avec DHCP). Si nécessaire, il y aura ensuite l'échange habituel Request puis Reply. Bref, du DHCPv6 classique. Le client devra renouveler l'allocation au bout du temps indiqué dans le bail (le serveur peut toujours donner l'adresse sans limite de temps, cf. RFC 8415, section 7.7). Le client peut explicitement abandonner l'adresse, avec un message Release. On l'a dit, ça se passe comme pour les adresses IP.

Les fanas du placement exact des bits liront la section 10, où est décrit l'encodage de l'option IA_LL et de la « sous-option » LLADDR. C'est là qu'on trouvera l'indication des blocs d'adresses MAC, encodés par la première adresse puis la taille du bloc (-1). Ainsi, 02:04:06:08:0a / 3 indique un bloc qui va de 02:04:06:08:0a à 02:04:06:08:0d. Pendant qu'on parle de bits, notez que les bits indiquant diverses caractéristiques de l'adresse MAC figurent dans le premier octet, et que la transmission se fait en commençant par le bit le moins significatif (IEEE 802 est petit-boutien pour les bits). Ainsi, l'adresse citée plus haut, 02:04:06:08:0a a un premier octet qui vaut 2, soit 00000010 en binaire, ce qui sera transmis comme 01000000. Le premier bit est le M, qui indique ici qu'il s'agit d'une adresse unicast, le second est U/L, indiquant ici que c'est bien une adresse locale, les deux bits suivants sont une nouveauté de IEEE 802c et indiquent le quadrant des adresses (cf. annexe A du RFC, puis le RFC 8948).

Quelques conseils pour les administrateurs des serveurs DHCP qui feront cette allocation d'adresses MAC figurent en section 11 du RFC. Par exemple, il ne faut allouer que des adresses locales (bit U/L à 1).

Les deux nouvelles options, IA_LL et LLADDR ont été mises dans le registre IANA.

Pour finir, l'annexe A du RFC résume la norme IEEE 802c. Dans la norme IEEE 802 originale, il y avait, comme indiqué plus haut, un bit U/L qui disait si l'adresse était gérée selon des règles locales (et n'était donc pas forcément unique au niveau mondial). 802c ajoute à ces adresses locales la notion de quadrant, découpant l'espace local en quatre. Après le bit M (unicast ou groupe) et le bit U/L (local ou pas). deux bits indiquent dans quel quadrant se trouve l'adresse :

  • 01 est Extended Local, des adresses qui comportent un identifiant de l'organisation, le CID (Company ID), et qui sont donc apparemment garanties uniques à l'échelle de la planète,
  • 11 est Standard Assigned, elles sont affectées par le protocole IEEE concurrent de celui du RFC,
  • 00 est Administratively Assigned, ce sont les « vraies » adresses locales, attribuées comme on veut (comme l'était la totalité de l'espace des adresses locales autrefois, les adresses d'exemple plus haut (02:04:06:08:0a et suivantes sont dans ce quadrant),
  • 10 est réservé pour un usage futur.

Un mécanisme de sélection du quadrant est normalisé dans le RFC 8948.

Pour l'instant, je ne connais pas de mise en œuvre de ce RFC que ce soit côté client ou serveur.


Téléchargez le RFC 8947


L'article seul

RFC 8948: Structured Local Address Plan (SLAP) Quadrant Selection Option for DHCPv6

Date de publication du RFC : Décembre 2020
Auteur(s) du RFC : CJ. Bernardos (UC3M), A. Mourad (InterDigital)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dhc
Première rédaction de cet article le 2 décembre 2020


Les adresses MAC sur 48 bits, normalisées par l'IEEE, ont un bit qui indique si l'adresse découle d'un plan mondial et est donc globalement unique, ou bien si elle a été allouée via une méthode locale. Plus récemment, l'IEEE a découpé l'espace local en quatre quadrants, pouvant avoir des poltiques différentes. Depuis qu'on peut allouer ces adresses MAC locales par DHCP (RFC 8947), il serait intéressant de choisir son quadrant. C'est ce que permet la nouvelle option DHCP QUAD normalisée dans ce nouveau RFC.

Tout·e étudiant·e en réseaux informatiques a appris le découpage des adresses MAC de 48 bits via le bit U/L (Universal/Local). Les adresses avec ce bit à 1 sont gérées localement (et donc pas forcément uniques au niveau mondial). En 2017, l'IEEE a ajouté un nouveau concept, le SLAP (Structured Local Address Plan). L'espace des adresses locales est découpé en quadrants, identifiés par deux bits (troisième et quatrième position dans l'adresse) :

  • 01 Extended Local Identifier où l'adresse commence par le CID (Company ID), qui identifie l'organisation,
  • 11 Standard Assigned Identifier où l'adresse est allouée en suivant un protocole normalisé par l'IEEE (qui, à ma connaissance, n'est pas encore publié, il se nommera IEEE P802.1CQ: Multicast and Local Address Assignment),
  • 00 Administratively Assigned Identifier où l'adresse est entièrement gérée localement, sans préfixe ou protocole standard (avant SLAP, toutes les adresses locales étaient gérées ainsi),
  • 10 est réservé pour des idées futures.

De son côté, l'IETF a, dans le RFC 8947, normalisé une option de DHCPv6 qui permet d'obtenir des adresses MAC par DHCP.

Or, dans certains cas, une machine pourrait vouloir choisir le quadrant dans lequel son adresse MAC se situe. Le RFC cite l'exemple d'objets connectés qui voudraient une adresse dans le quadrant ELI (Extended Local Identifier) pour avoir l'identifiant du fabricant au début de l'adresse, sans pour autant que le fabricant ne soit obligé d'allouer à la fabrication une adresse unique à chaque objet. Par contre, des systèmes qui changeraient leur adresse MAC pour éviter la traçabilité préféreraient sans doute un adresse dans le quadrant AAI (Administratively Assigned Identifier). L'annexe A du RFC est très intéressante de ce point de vue, décrivant plusieurs scénarios et les raisons du choix de tel ou tel quadrant.

Notre nouveau RFC ajoute donc une option au protocole DHCP que normalisait le RFC 8415. Elle se nomme QUAD et repose sur l'option LLADDR du RFC 8947. Le client met cette option QUAD dans la requête DHCP, pour indiquer son quadrant favori. Le serveur ne l'utilise pas dans la réponse. Soit il est d'accord pour allouer une adresse MAC dans ce quadrant et il le fait, soit il propose une autre adresse. (Rappelez-vous qu'en DHCP, le client propose, et le serveur décide.) Le client regarde l'adresse renvoyée et sait ainsi si sa préférence pour un quadrant particulier a été satisfaite ou pas.

La section 4 décrit les détails de l'option QUAD. Elle permet d'exprimer une liste de quadrants, avec des préférences associées. L'option est désormais enregistrée à l'IANA (code 140).

Pour l'instant, je ne connais pas de mise en œuvre de ce RFC que ce soit côté client ou serveur.


Téléchargez le RFC 8948


L'article seul

RFC 8952: Captive Portal Architecture

Date de publication du RFC : Novembre 2020
Auteur(s) du RFC : K. Larose (Agilicus), D. Dolson, H. Liu (Google)
Pour information
Réalisé dans le cadre du groupe de travail IETF capport
Première rédaction de cet article le 1 décembre 2020


Les portails captifs sont ces insupportables pages Web vers lesquels certains réseaux d'accès en WiFi vous détournent pour vous faire laisser des données personnelles avant d'avoir accès à l'Internet. Très répandus dans les hôtels et aéroports, ils utilisent pour ce détournement des techniques qui sont souvent celles des attaquants, et ils posent donc de graves problèmes de sécurité, sans parler de l'utilisabilité. Le groupe de travail CAPPORT de l'IETF travaille à définir des solutions techniques qui rendent ces portails captifs un peu moins pénibles. Ce RFC décrit l'architecture générale du système, d'autres RFC décrivant les solutions partielles.

Vu de l'utilisateurice, la connexion à l'Internet sur pas mal de hotspots se fait ainsi : on accroche le réseau WiFi, on se rend à une page Web quelconque et, au lieu de la page demandée, on est détourné vers une page des gérants du hotspot, qui vous montre de la publicité, exige des données personnelles (et parfois une authentification) et l'acceptation de conditions d'utilisation léonines, avant de continuer. Si la page que vous vouliez visiter était en HTTPS, ce qui est le cas le plus courant aujourd'hui, vous aurez probablement en outre un avertissement de sécurité. Certains systèmes d'exploitation, comme Android, ou certains navigateurs, comme Firefox, détectent automatiquement la captivité, suspendent leurs autres activités, et vous proposent d'aller directement à une page du portail. Mais ça reste pénible, par exemple parce que c'est difficile à automatiser. (Un exemple d'automatisation en shell avec curl que j'ai récupéré en ligne est hotel-wifi.sh. Un autre en Go et utilisant Chrome est captive-browser.)

Techniquement, la mise en œuvre du concept de portail captif se fait en général actuellement en détournant le trafic HTTP (via un transparent proxy) ou avec un résolveur DNS menteur, qui donne l'adresse IP du portail en réponse à toute requête. L'annexe A du RFC résume les mises en œuvre actuelles de portails captifs, et les méthodes utilisées pour pouvoir se connecter le moins mal possible. La machine qui veut savoir si elle est derrière un portail captif va typiquement faire une requête HTTP vers un URL connu et contrôlé par le fournisseur de l'application ou du système d'explication. Cet URL est appelé le canari. (Au lieu ou en plus de HTTP, on peut faire un test DNS sur un nom de domaine où on connait le résultat, au cas où le portail captif fonctionne avec un résolveur menteur. Attention, DNS et HTTP peuvent donner des résultats différents, détournement DNS mais pas HTTP, ou bien le contraire.) Notez que toutes les techniques avec un canari peuvent mener à des faux négatifs si le canari est connu et que le gardien derrière le portail captif le laisse passer, via une règle spécifique.

Notre RFC choisit d'être positif et donne une liste des exigences auxquelles essaie de répondre les solutions développées dans le groupe de travail. Ces exigences peuvent aussi être lues comme une liste de tous les inconvénients des portails captifs actuels. Un échantillon de ces exigences :

  • Ne pas détourner les protocoles standards de l'Internet comme HTTP, et, d'une manière générale, ne pas se comporter comme un attaquant (alors que les portails actuels violent systématiquement la sécurité en faisant des attaques de l'intermédiaire).
  • Ne pas détourner non plus le DNS, puisque la solution doit être compatible avec DNSSEC, outil indispensable à la sécurité du DNS.
  • Travailler au niveau IP (couche 3) et ne pas être dépendant d'une technologie d'accès particulière (cela ne doit pas marcher uniquement pour le WiFi).
  • Les machines terminales doivent avoir un moyen simple et sûr d'interroger leur réseau d'accès pour savoir si elles sont captives, sans compter sur le détournement de protocoles Internet, sans avoir besoin de « canaris », d'URI spéciaux qu'on tester, comme le detectportal.firefox.com de Firefox.
  • Les solutions déployées ne doivent pas exiger un navigateur Web, afin d'être utilisable, par exemple, par des machines sans utilisateur humain (les portails actuels plantent toutes les applications non-Web, comme la mise à jour automatique des logiciels). Ceci dit, le RFC se concentre surtout sur le cas où il y a un utilisateur humain.

L'architecture décrite ici repose sur :

  • L'annonce aux machines clients d'un URI qui sera l'adresse de l'API à laquelle parler pour en savoir plus sur le portail captif. Cette annonce peut se faire en DHCP (RFC 8910) ou en RA (même RFC). Mais elle pourra aussi se faire avec RADIUS ou par une configuration statique.
  • L'information donnée par le portail captif à la machine cliente, lui disant notamment si elle est en captivité ou pas.

Plus concrètement, le RFC liste les composants du problème et donc des solutions. D'abord, la machine qui se connecte (user equipment, dans le RFC). Pour l'instant, la description se limite aux machines qui ont un navigateur Web, même si elles sont loin d'être les seules, ou même les plus nombreuses. Pour que tout marche comme il faut, cette machine doit pouvoir récupérer l'URI de l'API du portail captif (par exemple, elle doit avoir un client DHCP), doit pouvoir gérer le fait que certaines de ses interfaces réseaux sont derrière un portail captif et pas les autres (RFC 7556), doit pouvoir notifier l'utilisateur qu'il y a un tel portail (et attention au hameçonnage !), et ce serait bien qu'il y a ait un moyen de dire aux applications « on est encore en captivité, n'essayez pas de vous connecter tout de suite ». Un exemple de cette dernière demande est fournie par Android où l'utilisation du réseau par défaut ne passe de la 4G au WiFi qu'une fois qu'Android a pu tester que l'accès WiFi n'était pas en captivité. Enfin, si la machine gère l'API des portails captifs, elle doit évidemment suivre toutes les règles de sécurité, notamment la validation du certificat.

Ensuite, deuxième composant, le système de distribution d'informations dans le réseau (provisioning service), DHCP ou RA. C'est lui qui va devoir envoyer l'URI de l'API à la machine qui se connecte, comme normalisé dans le RFC 8910.

Troisième composant, le serveur derrière l'API. Il permet de se passer des « canaris », des tests du genre « est-ce que j'arrive à me connecter à https://detectportal.example ? », il y a juste à interroger l'API. Cette API (RFC 8908) doit permettre au minimum de connaitre l'état de la connexion (en captivité ou pas), et d'apprendre l'URI que l'humain devra visiter pour sortir de captivité (« j'ai lu les 200 pages de textes juridiques des conditions d'utilisation, les 100 pages du code de conduite et je les accepte inconditionnellement »). Elle doit utiliser HTTPS.

Enfin, il y a le composant « gardien » (enforcement) qui s'assure qu'une machine en captivité ne puisse effectivement pas sortir ou en tout cas, ne puisse pas aller en dehors des services autorisés (qui doivent évidemment inclure le portail où on accepte les conditions). Il est typiquement placé dans le premier routeur. L'architecture présentée dans ce RFC ne change pas ce composant (contrairement aux trois premiers, qui devront être créés ou modifiés).

Parmi ces différents composants qui interagissent, l'un d'eux mérite une section entière, la section 3, dédiée à la machine qui se connecte (user equipment) et notamment à la question de son identité. Car il faut pouvoir identifier cette machine, et que les autres composants soient d'accord sur cette identification. Par exemple, une fois que le portail captif aura accepté la connexion, il faudra que le système « gardien » laisse désormais passer les paquets. Pour cette identification, plusieurs identificateurs sont possibles, soit présents explicitement dans les paquets, soit déduits d'autres informations. On peut imaginer, par exemple, utiliser l'adresse MAC ou l'adresse IP. Ou bien, pour les identificateurs qui ne sont pas dans le paquet, l'interface physique de connexion. Le RFC liste leurs propriétés souhaitables :

  • Unicité,
  • Difficulté à être usurpé par un attaquant (sur ce point, les adresses MAC ou IP ne sont pas satisfaisantes, alors que l'interface physique est parfaite ; diverses techniques existent pour limiter la triche sur l'adresse IP comme le test de réversibilité),
  • Visibilité pour le serveur derrière l'API (selon la technique de développement utilisée, l'adresse MAC peut être difficile ou impossible à récupérer par ce serveur ; idem pour l'interface physique),
  • Visibilité pour le gardien.

Notons que l'adresse IP a l'avantage d'être un identificateur qui n'est pas local au premier segment de réseau, ce qui peut permettre, par exemple, d'avoir un gardien qui soit situé un peu plus loin.

Armé de tous ces éléments, il est possible de présenter le traitement complet (section 4). Donc, dans l'ordre des évènements, dans le monde futur où ces différents RFC auront été déployés :

  • La machine de l'utilisateur se connecte au réseau, et obtient des informations en DHCP ou RA,
  • Parmi ces informations, l'URI de l'API du portail captif (options du RFC 8910),
  • La machine parle à cette API en suivant le RFC 8908, ce qui lui permet d'apprendre l'URI de la page du portail captif prévue pour les humains,
  • L'utilisateur humain lit les CGU (ah, ah) et les accepte,
  • Le gardien est prévenu de cette acceptation et laisse désormais passer les paquets,
  • L'utilisateur peut enfin regarder Joséphine, ange gardien sur Salto.

Si tout le monde joue le jeu, et que les techniques conformes à l'architecture décrite dans ce RFC sont déployées, les portails captifs, quoique toujours pénibles, devraient devenir plus gérables. Hélas, il est probable que beaucoup de déploiements ne soient jamais changé, notamment dans les environnements où le client est… captif (hôtels, aéroports) et où il n'y a donc aucune motivation commerciale pour améliorer les choses. Les logiciels vont donc devoir continuer à utiliser des heuristiques de type canari pendant une très longue période, car ils ne pourront pas compter sur des portails captifs propres.

Tout cela laisse ouvert quelques problèmes de sécurité, que la section 6 étudie. D'abord, fondamentalement, il faut faire confiance au réseau d'accès. Via DHCP et RA, il peut vous conduire n'importe où. (Le RFC 7556 discute de cette difficulté à authentifier le réseau d'accès.) Des protections comme l'authentification du serveur en TLS limitent un peu les dégâts mais ne résolvent pas tout. Ceci dit, c'est pour cela que notre RFC impose l'utilisation de HTTPS pour accéder à l'API. Mais, d'une manière générale, le réseau d'accès, et le portail captif qu'il utilise, a tous les pouvoirs. Il peut par exemple vous bloquer l'accès à tout ou partie de l'Internet, même après que vous ayez accepté les conditions d'utilisation.

Il y a aussi des questions de vie privée. L'identificateur de la machine qui se connecte peut être détourné de son usage pour servir à surveiller un utilisateur, par exemple. Les bases de données utilisées par les différents composants de cette architecture de portail captif doivent donc être considérées comme contenant des données personnelles. L'utilisateur peut changer ces identificateurs (pour l'adresse MAC, avec un logiciel comme macchanger) mais cela peut casser son accès Internet, si le gardien utilise justement cet identificateur.


Téléchargez le RFC 8952


L'article seul

RFC 8945: Secret Key Transaction Authentication for DNS (TSIG)

Date de publication du RFC : Novembre 2020
Auteur(s) du RFC : F. Dupont (ISC), S. Morris (ISC), P. Vixie (Farsight), D. Eastlake 3rd (Futurewei), O. Gudmundsson (Cloudflare), B. Wellington (Akamai)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 1 décembre 2020


Le DNS a des vulnérabilités à plusieurs endroits, notamment des risques d'usurpation, qui permettent de glisser une réponse mensongère à la place de la bonne. Il existe plusieurs solutions pour ces problèmes, se différenciant notamment par leur degré de complexité et leur facilité à être déployées. TSIG (Transaction SIGnature), normalisé dans ce RFC (qui remplace le RFC 2845), est une solution de vérification de l'intégrité du canal, permettant à deux machines parlant DNS de s'assurer de l'identité de l'interlocuteur. TSIG est surtout utilisé entre serveurs DNS maîtres et esclaves, pour sécuriser les transferts de zone (aujourd'hui, presque tous les transferts entre serveurs faisant autorité sont protégés par TSIG).

TSIG repose sur l'existence d'une clé secrète, partagée entre les deux serveurs, qui sert à générer un HMAC permettant de s'assurer que le dialogue DNS a bien lieu avec la machine attendue, et que les données n'ont pas été modifiées en route. L'obligation de partager une clé secrète le rend difficilement utilisable, en pratique, pour communiquer avec un grand nombre de clients. Mais, entre deux serveurs faisant autorité pour la même zone, ce n'est pas un problème (section 1.1 du RFC). On peut gérer ces secrets partagés manuellement. Même chose entre un serveur maître et un client qui met à jour les données par dynamic update (RFC 2136).

Bien sûr, si tout le monde utilisait DNSSEC partout, le problème de sécuriser le transfert de zones entre serveurs faisant autorité serait moins grave (mais attention, DNSSEC ne signe pas les délégations et les colles, cf. la section 10.2 de notre RFC). En attendant un futur lointain « tout-DNSSEC », TSIG fournit une solution simple et légère pour éviter qu'un méchant ne se glisse dans la conversation entre maître et esclave (par exemple grâce à une attaque BGP) et ne donne à l'esclave de fausses informations. (Il existe aussi des solutions non-DNS comme de transférer la zone avec rsync au dessus de SSH. Notez d'autre part que TSIG peut servir à d'autres choses que le transfert de zones, comme l'exemple des mises à jour dynamiques cité plus haut. Par contre, pour sécuriser la communication entre le client final et le résolveur, il vaut mieux utiliser DoTRFC 7858 - ou DoHRFC 8484.)

Comment fonctionne TSIG ? Les sections 4 et 5 décrivent le protocole. Le principe est de calculer, avec la clé secrète, un HMAC des données transmises, et de mettre ce HMAC (cette « signature ») dans un pseudo-enregistrement TSIG qui sera joint aux données, dans la section additionnelle. À la réception, l'enregistrement TSIG (obligatoirement le dernier de la section additionnelle) sera extrait, le HMAC calculé et vérifié.

Pour éviter des attaques par rejeu, les données sur lesquelles portent le HMAC incluent l'heure. C'est une des causes les plus fréquentes de problèmes avec TSIG : les deux machines doivent avoir des horloges très proches (section 10, qui recommande une tolérance - champ Fudge - de cinq minutes).

Le format exact des enregistrements TSIG est décrit en section 4. L'enregistrement est donc le dernier, et est mis dans la section additionnelle (voir des exemples plus loin avec dig et tshark). Le type de TSIG est 250 et, évidemment, ces pseudo-enregistrements ne doivent pas être gardés dans les caches. Plusieurs algorithmes de HMAC sont possibles. Un est obligatoire et recommandé, celui fondé sur SHA-256 (que j'utilise dans les exemples par la suite). On peut toujours utiliser SHA-1 et MD5 (avant que vous ne râliez : oui, SHA-1 et MD5 ont de gros problèmes mais cela n'affecte pas forcément leur utilisation en HMAC, cf. RFC 6151). Un registre IANA contient les algorithmes actuellement possibles (cf. aussi section 6 du RFC).

Le nom dans l'enregistrement TSIG est le nom de la clé (une raison pour bien le choisir, il inclut typiquement le nom des deux machines qui communiquent), la classe est ANY, le TTL nul et les données contiennent le nom de l'algorithme utilisé, le moment de la signature, et bien sûr la signature elle-même.

Le fait que la clé soit secrète implique des pratiques de sécurité sérieuses, qui font l'objet de la section 8. Par exemple, l'outil de génération de clés de BIND crée des fichiers en mode 0600, ce qui veut dire lisibles uniquement par leur créateur, ce qui est la moindre des choses. Encore faut-il assurer la sécurité de la machine qui stocke ces fichiers. (Voir aussi le RFC 2104).

Voyons maintenant des exemples concrets où polly (192.168.2.27) est un serveur DNS maître pour la zone example.test et jadis (192.168.2.29) un serveur esclave. Pour utiliser TSIG afin d'authentifier un transfert de zone entre deux machines, commençons avec BIND. Il faut d'abord générer une clé. Le programme tsig-keygen, livré avec BIND, génère de nombreux types de clés (d'où ses nombreuses options). Pour TSIG, on veut du SHA-256 (mais tsig-keygen connait d'autres algorithmes) :

% tsig-keygen -a HMAC-SHA256  polly-jadis 
key "polly-jadis" {
	algorithm hmac-sha256;
	secret "LnDomTT+IRf0daLYqxkstFpTpmFfcOvyxtRaq2VhHSI=";
};

(Avant BIND 9.13, le programme à utiliser était dnssec-keygen, qui ne fait désormais plus que du DNSSEC.) On a donné à la clé le nom des deux machines entre lesquelles se fera la communication (le nom est affiché dans le journal lors d'un transfert réussi, et à plusieurs autres endroits, donc il vaut mieux le choisir long et descriptif), plus un chiffre pour distinguer d'éventuelles autres clés. La clé est partagée entre ces deux machines. On met alors la clé dans la configuration de BIND, sur les deux machines (tsig-keygen produit directement de la configuration BIND). Naturellement, il faut transférer la clé de manière sécurisée entre les deux machines, pas par courrier électronique ordinaire, par exemple. Sur le serveur maître, on précise que seuls ceux qui connaissent la clé peuvent transférer la zone :

zone "example.test" { 
         type master;  
         file "/etc/bind/example.test";
         allow-transfer {  key polly-jadis; };
};

Les autres clients seront rejetés :

Apr  6 17:45:15 polly daemon.err named[27960]: client @0x159c250 192.168.2.29#51962 (example.test): zone transfer 'example.test/AXFR/IN' denied

Mais, si on connait la clé, le transfert est possible (ici, un test avec dig) :


% dig -y hmac-sha256:polly-jadis:LnDomTT+IRf0daLYqxkstFpTpmFfcOvyxtRaq2VhHSI= @polly.sources.org AXFR example.test 

; <<>> DiG 9.16.1-Debian <<>> -y hmac-sha256 @polly.sources.org AXFR example.test
; (1 server found)
;; global options: +cmd
example.test.		86400	IN	SOA	polly.sources.org. hostmaster.sources.org. 2020040600 7200 3600 604800 43200
example.test.		86400	IN	NS	polly.sources.org.
example.test.		86400	IN	SOA	polly.sources.org. hostmaster.sources.org. 2020040600 7200 3600 604800 43200
polly-jadis.		0	ANY	TSIG	hmac-sha256. 1586195193 300 32 pJciUWLOkg1lc6J+msC+dzYotVSOr8PSXgE6fFU3UwE= 25875 NOERROR 0 
;; Query time: 10 msec
;; SERVER: 192.168.2.27#53(192.168.2.27)
;; WHEN: Mon Apr 06 17:46:33 UTC 2020
;; XFR size: 3 records (messages 1, bytes 267)


On voit que dig affiche fidèlement tous les enregistrements, y compris le pseudo-enregistrement de type TSIG qui contient la signature. Un point de sécurité, toutefois (merci à Jan-Piet Mens pour sa vigilance) : avec ce -y, quiconque a un compte sur la même machine Unix peut voir la clé avec ps. Il peut être préférable de la mettre dans un fichier et de dire à dig d'utiliser ce fichier (dig -k polly-jadis.key …).

Maintenant que le test marche, configurons le serveur BIND esclave :

// To avoid copy-and-paste errors, you can also redirect tsig-keygen's
// output to a file and then include it in named.conf with 'include
// polly-jadis.key'.
key "polly-jadis" {
    algorithm hmac-sha256;
              secret "LnDomTT+IRf0daLYqxkstFpTpmFfcOvyxtRaq2VhHSI=";
              };

zone "example.test" {
       type slave;
       masters {192.168.2.27;};
       file "example.test";
};

server 192.168.2.27 {
        keys {
          polly-jadis;
        };
};

et c'est tout : l'esclave va désormais utiliser TSIG pour les transferts de zone. Le programme tshark va d'ailleurs nous afficher les enregistrements TSIG :

    Queries
        example.test: type AXFR, class IN
            Name: example.test
            [Name Length: 12]
            [Label Count: 2]
            Type: AXFR (transfer of an entire zone) (252)
            Class: IN (0x0001)
    Additional records
        polly-jadis: type TSIG, class ANY
            Name: polly-jadis
            Type: TSIG (Transaction Signature) (250)
            Class: ANY (0x00ff)
            Time to live: 0
            Data length: 61
            Algorithm Name: hmac-sha256
            Time Signed: Apr  6, 2020 19:51:36.000000000 CEST
            Fudge: 300
            MAC Size: 32
            MAC
                [Expert Info (Warning/Undecoded): No dissector for algorithm:hmac-sha256]
                    [No dissector for algorithm:hmac-sha256]
                    [Severity level: Warning]
                    [Group: Undecoded]
            Original Id: 37862
            Error: No error (0)
            Other Len: 0

Et si l'esclave est un nsd et pas un BIND ? C'est le même principe. On configure l'esclave :

key:
    name: polly-jadis
    algorithm: hmac-sha256
    secret: "LnDomTT+IRf0daLYqxkstFpTpmFfcOvyxtRaq2VhHSI="

zone:
    name: "example.test"
    zonefile: "example.test"
    allow-notify: 192.168.2.27 NOKEY
    request-xfr: 192.168.2.27 polly-jadis

Et le prochain nsd-control transfer example.test (ou bien la réception de la notification) déclenchera un transfert, qui sera ainsi enregistré :

Apr 07 06:46:48 jadis nsd[30577]: notify for example.test. from 192.168.2.27 serial 2020040700
Apr 07 06:46:48 jadis nsd[30577]: [2020-04-07 06:46:48.831] nsd[30577]: info: notify for example.test. from 192.168.2.27 serial 2020040700
Apr 07 06:46:48 jadis nsd[30565]: xfrd: zone example.test written received XFR packet from 192.168.2.27 with serial 2020040700 to disk
Apr 07 06:46:48 jadis nsd[30565]: [2020-04-07 06:46:48.837] nsd[30565]: info: xfrd: zone example.test written received XFR packet from 192.168.2.27 with serial 2020040700 to disk

Pour générer des clés sans utiliser BIND, on peut consulter mon autre article sur TSIG.

On l'a vu, TSIG nécessite des horloges synchronisées. Une des erreurs les plus fréquentes est d'oublier ce point. Si une machine n'est pas à l'heure, on va trouver dans le journal des échecs TSIG comme (section 5.2.3 du RFC), renvoyés avec le code de retour DNS NOTAUTH (code 9) et un code BADTIME dans l'enregistrement TSIG joint :

Mar 24 22:14:53 ludwig named[30611]: client 192.168.2.7#65495: \
         request has invalid signature: TSIG golgoth-ludwig-1: tsig verify failure (BADTIME)

Ce nouveau RFC ne change pas le protocole du RFC 2845. Un ancien client peut interopérer avec un nouveau serveur, et réciproquement. Seule change vraiment la procédure de vérification, qui est unilatérale. Une des motivations pour la production de ce nouveau RFC venait de failles de sécurité de 2016-2017 (CVE-2017-3142, CVE-2017-3143 et CVE-2017-11104). Certes, elle concernaient des mises en œuvre, pas vraiment le protocole, mais elles ont poussé à produire un RFC plus complet et plus clair.

Le débat à l'IETF au début était « est-ce qu'on en profite pour réparer tout ce qui ne va pas dans le RFC 2845, ou bien est-ce qu'on se limite à réparer ce qui est clairement cassé ? » Il a été tranché en faveur d'une solution conservatrice : le protocole reste le même, il ne s'agit pas d'un « TSIG v2 ».


Téléchargez le RFC 8945


L'article seul

Expliquer le fonctionnement de l'Internet en quarante minutes

Première rédaction de cet article le 30 novembre 2020


Le 26 novembre 2020, j'ai participé à une formation à l'UTC où il fallait expliquer le fonctionnement de l'Internet à des étudiants en développement Web. Pas facile.

Si vous voulez voir si j'ai réussi, la vidéo est en ligne. (L'interruption vers 12:24 est due à une coupure accidentelle de courant chez moi pendant l'installation d'une nouvelle chaudière.) Il y en a aussi une copie sur PeerTube (mais qui a un problème avec les supports). Et voici la présentation de cette formation, celle de ce cours, et mes supports de présentation :

Merci à Stéphane Crozat pour l'invitation et l'organisation.


L'article seul

Le protocole Gemini, revenir à du simple et sûr pour distribuer l'information en ligne ?

Première rédaction de cet article le 29 novembre 2020
Dernière mise à jour le 2 décembre 2020


Comme beaucoup de gens, je trouve que le Web, tout en étant un immense succès, souffre de plusieurs défauts. Tous ne proviennent pas de la technique, mais certains peuvent quand même être reliés à des choix lors de la conception des protocoles et formats. C'est par exemple le cas des problèmes de vie privée, car HTTP et HTML fournissent trop de moyens de pister les utilisateurs, et des problèmes stratégiques autour des navigateurs : aujourd'hui, écrire un navigateur Web complet, disons l'équivalent de Firefox, est une tâche colossale, réservée à de très grosses équipes très pointues. Cela limite la concurrence : seuls trois ou quatre navigateurs vraiment différents existent et encore moins de moteurs de rendu. (Et je n'ai pas encore mentionné le désir de davantage de sobriété numérique et d'empreinte environnementale réduite.) Le projet Gemini s'attaque à ce problème en définissant un nouveau protocole et un nouveau format, délibérement très simples et non extensibles, afin de rendre plus difficile l'apparition des mêmes problèmes que dans le Web.

Gemini est donc très simple. Il utilise :

  • Un protocole à lui, qui ressemble un peu à la version 0.9 de HTTP (en mieux, quand même),
  • Un format à lui, une sorte de version simplifiée et uniformisée de Markdown,
  • Les URL que nous connaissons,
  • Le TLS que nous connaissons.

Un point important et délibéré de Gemini est son absence d'extensibilité. Le but est d'éviter ce qui est arrivé au Web, où un protocole simple et sûr du début a évolué en un gros machin compliqué et dangereux. Ainsi, Gemini n'a pas d'en-têtes de requêtes ou de réponses. Y ajouter un outil de flicage comme les cookies sera donc difficile et c'est exprès.

Si vous êtes intéressé par ce projet, consultez le site Web pour avoir une première idée. Si vous avez des questions (notamment si vous en êtes au stade « ah, les cons, pourquoi ils n'ont pas tout simplement utilisé X et/ou fait comme Y ? »), il est probable que la FAQ très détaillée y répondra. Si vous êtes d'humeur à lire l'actuelle spécification, elle est aussi sur le Web. Mais beaucoup d'autres ressources à propos de Gemini ne sont évidemment pas sur le Web, mais dans le « geminispace ».

Comme ce « geminispace » ne peut pas se visiter avec un navigateur Web classique, il va falloir un client Gemini. Il en existe beaucoup. La plupart sont assez sommaires mais les lectrices et lecteurs de mon blog sont des gens avertis et qui savent qu'il ne faut pas juger un système de publication à ses interfaces actuelles. Déjà, je vais commencer par supposer que vous ne voulez pas installer un Nième logiciel sur votre machine mais que vous voudriez quand même jeter un coup d'œil. Ça tombe bien, plusieurs clients Gemini sont disponible sur un serveur SSH public. Connectez-vous en SSH à kiosk@gemini.circumlunar.space et essayez le client de votre choix. Personnellement, j'utilise Amfora. Vous pouvez visiter les liens de la page d'accueil en tapant espace puis leur numéro. À la place d'un numéro, vous pouvez aussi indiquer un URL Gemini comme gemini://gemini.bortzmeyer.org/. Si vous voulez tester plus loin, vous pouvez installer Amfora ou bien un des autres clients. Sur Arch Linux, c'est aussi simple que de taper pacman -S amfora. Comme vous vous en doutez, il n'y a pas encore beaucoup de contenu disponible mais ça grossit tous les jours.

Comme dit plus haut, il y a de nombreux autres clients Gemini. Par exemple, les fans d'Emacs vont apprécier Elpher, un client Gopher et Gemini pour Emacs. Voici son apparence : elpher.png

Et, ici, avec le client graphique Lagrange : lagrange.png

En plus sommaire, et si on aime la ligne de commande, récupérer un fichier avec Gemini est aussi simple que :

% echo -n  "gemini://purexo.mom/\r\n" | gnutls-cli -p 1965  purexo.mom  
  

(gnutls-cli fait partie de GnuTLS.)

Et si vous voulez un serveur, pour distribuer vos idées géniales au monde entier ? Il existe plusieurs serveurs en logiciel libre, mais pas de page Web pour les présenter, il faut aller dans le geminispace en gemini://gemini.circumlunar.space/software/. J'ai choisi de commencer avec Agate. Agate est écrit en Rust donc on l'installe en général par la méthode Rust habituelle, cargo install agate. Ensuite, il nous faut un certificat car Gemini impose TLS (notez qu'il semble que pas mal de serveurs Gemini n'aient qu'un certificat auto-signé). Demandons à Let's Encrypt :

# certbot certonly -n --standalone --domain gemini.bortzmeyer.org
  

Et je copie certificat et clé privée dans un répertoire à moi, pour ne pas exécuter Agate en étant root. (Pour le renouvellement du certificat, dans trois mois, il faudra que je trouve une solution plus pérenne.) Ensuite, je lance le serveur :

% ~/.cargo/bin/agate gemini.bortzmeyer.org:1965 /var/gemini fullchain.pem privkey.pem gemini.bortzmeyer.org
  

(Pourquoi le port 1965 est-il le port par défaut ? Je vous laisse chercher un peu.)

Mais il reste à ajouter du contenu, dans le répertoire /var/gemini qu'on a indiqué au serveur. Ce contenu est dans un format spécifique à Gemini, qui ressemble à Markdown, en plus limité. Je vous le dis tout de suite : il n'y a pas d'images ! Finies, les photos de chats mignons ! Voici le source de la page d'accueil de mon serveur :

% cat index.gmi 
# First Gemini test

No actual content yet

=> https://www.afnic.fr/ AFNIC Web site
  

Vous noterez :

  • Le titre (équivalent du <h1> de HTML) s'écrit comme en Markdown.
  • Le texte s'écrit sans marques particulières.
  • Les liens sont forcément sur une ligne. On ne peut pas faire d'hypertexte. (En prime, j'ai mis un lien Web, ce qui n'est pas très géministe et ne marchera pas avec les clients Gemini non-Web.)

Voilà, je vais essayer de mettre un peu plus de contenu que ce premier exemple mais ne comptez pas sur une publication de mon blog en Gemini : l'absence d'hypertexte nécessiterait de réécrire sérieusement les articles.

Je reviens un peu au choix des serveurs. On a vu qu'il y avait une liste en gemini://gemini.circumlunar.space/software/ mais elle n'est pas éditée, c'est juste un vrac tous les serveurs possibles, alors que certains sont très sommaires, voire déjà abandonnés. Voici donc une liste personnelle de ceux que j'ai testés, en commençant (oui, c'est subjectif), par ceux que je trouve les plus « prêts pour la prod' » (avec des liens Web à chaque fois, pour faciliter la vie de celles et ceux qui n'ont pas encore de client Gemini) :

  • Molly-brown : le serveur de référence. Parfait en tout, mais n'a pas de virtual hosts.
  • Gemserv : très bon serveur également, et il dispose de virtual hosts.
  • Agate : simple mais marche bien.
  • Twins : sans doute le plus riche en fonctions.
  • geminid : écrit en C, donc seulement si vous n'avez pas peur des débordements. Mais il marche bien.
  • Net-gemini : pas très documenté, mais j'ai l'impression que c'est plutôt une bibliothèque pour développer des serveurs adaptés à un usage particulier, par exemple la génération de pages dynamiques.
  • Northstar : même remarque.
  • GeGoBi : plutôt pour les gens qui ont déjà du contenu Gopher et veulent le servir rapidement sur Gemini.
  • Pollux : très limité, il sert un seul fichier, et ne semble plus développé.
  • Shavit : pour l'instant, il ne peut communiquer qu'avec des clients locaux à la machine.
  • Blizanci : aucun développement depuis six mois.

Conclusion ? Ne me demandez pas si Gemini sera un succès ou pas, je suis mauvais pour les pronostics. Je dis juste que je suis content de voir que des gens ne se résignent pas à déplorer les problèmes du Web mais qu'ils essaient de les résoudre.


L'article seul

Fiche de lecture : Paris démasqué

Auteur(s) du livre : Quentin Gérard, Louis Moulin
Éditeur : Arkhê
978-29-18682-592
Publié en 2019
Première rédaction de cet article le 28 novembre 2020


Le citadin arrogant peut imaginer que les légendes, les monstres, les histoires irrationnelles ne naissent qu'à la campagne, chez des ruraux mal dégrossis, les seuls à croire à ces récits fantastiques. Mais les villes ont aussi leurs contes fabuleux, leurs angoisses et leurs mythes. Les auteurs s'attaquent ici à quelques histoires étonnantes qui prennent place à Paris, et en profitent pour analyser l'inconscient des concentrations urbaines.

Ce livre cite vingt mythes très différents. Mythes car, quoi qu'un bon nombre parte d'évènements et de personnages réels, ce qui intéresse les auteurs, c'est ce qu'en a fait la psychologie collective. Prenons quelques exemples.

Il y a des histoires inspirées par les crimes et la répression de ces crimes, répression souvent aussi horrible que le crime lui-même. Un chapitre du livre rappelle ainsi l'histoire du gibet de Montfaucon, à l'époque où on assassinait légalement (« nous fûmes occis par justice », dit François Villon) aux quatre coins de Paris, là où on ne trouve aujourd'hui que des gentilles boulangeries bio. Montfaucon était conçu pour être visible et pour faire peur et le gibet, scène d'horreur, a en effet marqué les imaginations pour de nombreux siècles.

Un autre chapitre est consacré aux grands drames collectifs qui ont frappé la ville. Il y a par exemple l'angoisse des rats (vous connaissiez le terme de musophobie, qui n'est même pas dans le Wiktionnaire ?) Cette angoisse se base sur des faits réels (le rôle des rats dans des maladies comme la peste) mais a souvent dérivé vers l'irrationnel, voire le racisme. Les auteurs citent le « les rats sont coupables, les rastas ne sont pas innocents » [dans la presse de l'époque, « rasta » est un étranger oriental], du journaliste d'extrême-droite José Germain, qui rappelle que les temps d'épidémie sont propices aux délires et aux mensonges.

Il y a bien sûr aussi un chapitre sur les récits politiques. La sainte patronne de Paris, sainte Geneviève, est un personnage historique réel. Mais elle a fait l'objet d'un gros travail de mythification. C'était une aristocrate, dirigeante politique habile dans des temps très troublés, mais on en a fait une humble bergère, avant de la considérer comme un symbole de la monarchie et de l'Église pendant la Révolution, où ses restes ont été détruits. Puis de nos jours on met davantage en avant son intelligence politique, plutôt que sa piété. Chaque époque met Geneviève à sa sauce.

En parlant de politique, le chapitre sur les « spectres et maléfices » évoque entre autres les pétroleuses. Là encore, il s'agit d'un phénomène historique réel (la participation des femmes à la Commune, pas les incendiaires se promenant avec leur bidon de pétrole) mais qui a été transformé par la presse versaillaise : les pétroleuses n'étaient pas simplement dépeintes comme des adversaires politiques mais comme des monstres inhumains. (Et c'est l'occasion de rappeler que, en deux mille et quelques années d'une histoire souvent troublée, le plus grand massacre qui ait jamais eu lieu à Paris a été commis par l'armée française.)

Paris n'est pas isolée, il y a la banlieue tout autour. Ah, la banlieue, comme objet de fantasmes et de peurs… Cela ne date pas d'aujourd'hui : la forêt de Bondy a ainsi droit à une place, car pendant longtemps, c'était le coupe-gorge qui faisait peur à tous les Parisiens. Dans les mythes, le danger est toujours à l'extérieur…

Je ne vais pas résumer toutes les histoires que contient ce livre. Juste terminer en disant que j'ai été très ému, par le rappel dans le chapitre sur les épreuves collectives subies par la ville, des attentats djihadistes de janvier et novembre 2015. Le récit se termine par un message d'espoir : Paris n'a pas cédé.


L'article seul

Le service MySocket, pour donner un accès Internet à ses développements locaux

Première rédaction de cet article le 25 novembre 2020


Le service MySocket vient d'être lancé. À quoi ça sert ? À plusieurs choses mais le scénario d'utilisation le plus évident est le cas où vous avez un service TCP/IP sur une machine de développement et vous voudriez que des gens dans le vaste monde l'essaient. Mais, pour des raisons diverses, cette machine de développement n'est pas accessible depuis l'Internet. MySocket est un relais qui va prendre les connexions des gens extérieurs et les apporter à votre service.

Il y a beaucoup de cas où la machine sur laquelle vous êtes en train de travailler ne peut pas être contactée par des clients situés sur l'Internet. Le plus évident est celui où vous êtes coincé sur un réseau attardé qui n'a pas IPv6 (ou bien que vos clients n'ont pas IPv6) et que le NAT empêche ces connexions entrantes. (Ou, encore pire, le service est dans un conteneur Docker double-NATé…) MySocket va agir comme un mini-Cloudflare, il va fournir une prise réseau à laquelle vos clients se connecteront et, derrière, cela viendra chez vous. C'est très pratique pour des essais, du développement, etc.

MySocket a été présenté dans cet article. Mais vous avez une documentation complète en ligne. Pratiquer est un bon moyen de voir en quoi ce service consiste concrètement, donc allons-y.

MySocket se pilote via son API. Il ne semble pas y avoir d'interface Web pour les utilisateurs en ce moment. Pour parler à l'API, vous pouvez écrire votre propre programme ou, plus simple, utiliser le client mysocketctl développé par MySocket. (Son source est disponible.) C'est un script Python donc on l'installe de manière pythonienne :

%   pip3 install --user mysocketctl 
...
Successfully installed mysocketctl-0.3
  

La connexion entre MySocket et votre service se fera forcément en SSH. Donc, il faut une clé SSH. Ici, je vais en créer une dédiée à ce service MySocket :

% ssh-keygen -t ed25519 -f ~/.ssh/id_mysocket
...
Your public key has been saved in /home/stephane/.ssh/id_mysocket.pub.

%  ssh-add ~/.ssh/id_mysocket
  

On peut maintenant se créer un compte sur le service MySocket (je me répète mais il n'y a pas d'interface Web pour cela) :

% mysocketctl account create \
    --name "Stéphane Bortzmeyer" \
    --email "foobar@example.com" \
    --password "Plein de caractères" \
    --sshkey "$(cat ~/.ssh/id_mysocket.pub)"
Congratulation! your account has been created. A confirmation email has been sent to foobar@example.com
Please complete the account registration by following the confirmation link in your email.
...
  

Une fois reçu le message de confirmation envoyé par courrier, vous suivez le lien et votre adresse est confirmée. Note amusante : la réponse du serveur Web sera en JSON (oui, oui, avec le type application/json), et composée de la chaîne "You have confirmed your account. Thanks!".

Les opérations de gestion des prises réseau nécessiteront un jeton d'authentification que l'on crée avec la commande login, et qui est valable quelques heures (après, vous aurez un Login failed) :

% mysocketctl login \
    --email "foobar@example.com" \
    --password "Plein de caractères" 

Logged in! Token stored in /home/stephane/.mysocketio_token

(À l'heure actuelle, ce fichier .mysocketio_token est créé avec les permissions par défaut. Vous aurez peut-être besoin de durcir ses permissions.)

Voilà, à ce stade, vous avez un compte, vous avez un jeton d'authentification, on peut créer une prise. mysocketctl permet de le faire de manière simple, ou de manière plus compliquée mais permettant davantage de choses. Commençons par la manière simple :

% mysocketctl connect \
    --port 8080 \
    --name "Youpi"

+--------------------------------------+--------------------------------+-------+
|              socket_id               |            dns_name            |  name |
+--------------------------------------+--------------------------------+-------+
| 3d66b504-677f-4e68-85a7-bb63da251007 | shy-bush-6765.edge.mysocket.io | Youpi |
+--------------------------------------+--------------------------------+-------+

Connecting to Server: ssh.mysocket.io
...
Youpi - https://shy-bush-6765.edge.mysocket.io 
...

(Si vous récupérez un Permission denied (publickey), vérifier que la clé SSH a bien été chargée dans l'agent avec ssh-add.) Et voilà, une prise a été créée et elle est accessible du monde extérieur via le nom shy-bush-6765.edge.mysocket.io. Par défaut, c'est une prise HTTPS et les clients sont donc censés s'y connecter avec l'URL indiqué https://shy-bush-6765.edge.mysocket.io. Notez bien que vous ne choisissez pas le nom de domaine, il est attribué par MySocket et vous êtes donc dépendant d'eux, y compris dans le nom publié. On l'a déjà dit : MySocket est surtout conçu pour du développement, du temporaire, pas pour le site e-commerce de votre entreprise.

Maintenant, un client, par exemple un navigateur Web, va essayer de se connecter à cet URL. Et paf, on a un 502 Bad Gateway. Qu'est-ce que cela veut dire ? Tout simplement qu'on a créé la prise, qu'on l'a connectée au port 8080 de notre machine mais que rien n'écoute sur ce port (d'où l'erreur 502, RFC 7231, section 6.6.3). Il nous faut développer un petit service. Ici, on va utiliser le module http.server de Python :

#!/usr/bin/env python3

import http.server

server_address = ('', 8080)
httpd = http.server.HTTPServer(server_address,
                               http.server.SimpleHTTPRequestHandler)
httpd.serve_forever()
  

Simple, non ? Cela crée un serveur HTTP (rappelez-vous que par défaut mysocketctl crée une prise HTTP), écoutant sur le port 8080 et traitant les requêtes avec la classe SimpleHTTPRequestHandler. Cette classe contient du code pour les méthodes HTTP comme GET et, par défaut, elle crée un petit serveur de fichier qui sert les fichiers locaux. Exécutons ce serveur :

% ./test-mysocket.py    
...
127.0.0.1 - - [25/Nov/2020 18:13:06] "GET / HTTP/1.0" 200 -
  

Ça marche, le client HTTP reçoit cette fois le code de retour 200 indiquant que tout va bien, et il voit la liste des fichiers locaux. La ligne commençant par 127.0.0.1 est le journal qu'affiche par défaut le module http.server. Le premier champ est l'adresse IP du client, ici 127.0.0.1, l'adresse de la machine locale, car c'est le client MySocket, lancé par mysocketctl qui s'est connecté à ce service. Si on veut voir la vraie adresse du client, il faut regarder le journal de mysocketctl :

192.0.2.106 - - [25/Nov/2020:17:13:06 +0000] "GET / HTTP/1.1" 200 432 "-" "curl/7.64.0" response_time="0.032 secs"
  

C'est pratique, on a la vraie adresse IP du client. Elle est également disponible dans les en-têtes de la requête HTTP, champs X-Real-IP: et X-Forwarded-For: (mais hélas pas avec l'en-tête standard du RFC 7239).

Pendant que tout marche et que le bonheur coule à flot, regardons d'un peu plus près le service que fournit MySocket. Je crée une prise, et on m'obtient le nom purple-surf-7070.edge.mysocket.io. Ce nom a une adresse IP (IPv4 seul, hélas) :

% dig A purple-surf-7070.edge.mysocket.io
...
;; ANSWER SECTION:
purple-surf-7070.edge.mysocket.io. 300 IN A 75.2.104.207
  

Mais cette adresse IP ne correspond pas à une seule machine : MySocket utilise l'anycast pour que cette adresse IP soit toujours proche de vous. (Évidemment, seul MySocket est anycasté, votre service ne tourne toujours que sur une seule machine.) Pour réaliser cela, MySocket tourne sur un service d'AWS (Global Accelerator) qui n'a hélas pas IPv6. Testons l'adresse IP avec les sondes RIPE Atlas :

% blaeu-reach -r 200 75.2.104.207
197 probes reported
Test #28277168 done at 2020-11-25T17:23:21Z
Tests: 584 successful tests (98.8 %), 0 errors (0.0 %), 7 timeouts (1.2 %), average RTT: 19 ms
  

On voit un RTT moyen très court, montrant bien l'intérêt de l'anycast.

Je n'ai pas utilisé cette possibilité, mais notez que MySocket permet également de créer des prises protégées (avec l'option --protected). Pour HTTP, ce sera avec l'authentification simple du RFC 7235. mysocketctl connect --help si vous voulez des détails, je n'ai personnellement pas testé.

J'ai dit qu'il y avait deux manières de gérer les prises, une simple et une plus compliquée. On vient de tester la simple, avec mysocketctl connect qui crée la prise, y connecte votre service, et nettoie lorsqu'il se termine. Maintenant, on va procéder en deux temps, d'abord en créant la prise, sans y connecter notre service :

% mysocketctl socket create --name "Youpi" 
+--------------------------------------+-----------------------------------+---------+------+-------+
|              socket_id               |              dns_name             | port(s) | type |  name |
+--------------------------------------+-----------------------------------+---------+------+-------+
| c5d771fe-1ae8-4254-a8bd-fb8b1f4c293e | lively-rain-9509.edge.mysocket.io |  80 443 | http | Youpi |
+--------------------------------------+-----------------------------------+---------+------+-------+
  

On dispose désormais d'une prise « permanente » (qui ne disparait pas quand on a cessé de se connecter). mysocketctl socket ls me donnera la liste de ces prises. Pour utiliser la prise, il faut créer un tunnel :

% mysocketctl tunnel create --socket_id c5d771fe-1ae8-4254-a8bd-fb8b1f4c293e 
+--------------------------------------+--------------------------------------+---------------+------------+
| socket_id                            | tunnel_id                            | tunnel_server | relay_port |
+--------------------------------------+--------------------------------------+---------------+------------+
| c5d771fe-1ae8-4254-a8bd-fb8b1f4c293e | ace4b7bf-78f5-4373-992c-e7854b917b45 |               | 6150       |
+--------------------------------------+--------------------------------------+---------------+------------+
  

Puis on se connecte à MySocket :

% mysocketctl tunnel connect \
    --socket_id c5d771fe-1ae8-4254-a8bd-fb8b1f4c293e \
    --tunnel_id ace4b7bf-78f5-4373-992c-e7854b917b45     --port 8080
                                                    
Connecting to Server: ssh.mysocket.io
...
Youpi - https://lively-rain-9509.edge.mysocket.io 
  

Et on peut s'en servir, à l'URL indiqué.

Quelques petits points divers, avant de montrer deux services actuellements disponibles via MySocket :

  • Je n'ai pas creusé la question du modèle d'affaires de MySocket. Pour l'instant, tout est gratuit, fonctionnant au mieux (sans garantie). Je suppose qu'il y aura un service payant avec davantage de possibilités et de garanties, mais je n'en sais rien. Notez que le créateur de MySocket est Andree Tonk, créateur de BGPmon, donc a priori, c'est sérieux.
  • Ceci dit, MySocket est une solution cloud, c'est-à-dire tournant sur d'autres ordinateurs que le vôtre. Si la communication entre votre service et MySocket est chiffrée avec SSH, et que celle entre le client et MySocket l'est en général avec TLS, le trafic est en clair sur les serveurs de MySocket (qui sont des machines Amazon). Donc, attention si vous manipulez des données importantes.
  • Pensez aussi à la sécurité de votre service. MySocket permet à tout l'Internet (sauf si vous utilisez le mode protégé, avec --protected) d'appeler un service qui tourne sur votre machine. Un serveur mal écrit et des tas de choses ennuyeuses peuvent se passer. Il est recommandé d'utiliser un langage de programmation sûr (Python plutôt que C…) et de faire tourner le service dans un bac à sable, par exemple un conteneur.
  • Un des avantages de MySocket est que votre service apparaitra aux yeux du monde comme sécurisé avec TLS, sans que vous ayiez le moindre effort de programmation ou de configuration à faire, ce qui est très sympa. (Le certificat de MySocket est un Let's Encrypt.)

Et pour finir, voici deux services qui tournent actuellement via MySocket. Tous les deux sont hébergés sur un Raspberry Pi 1 (oui, le premier modèle). Ces deux services sont évidemment sans garantie de fiabilité ou de pérennité, c'est juste pour vous montrer et que vous puissiez tester. Le premier utilise une prise de type HTTPS, comme dans les exemples plus haut. Il indique la température du Raspberry Pi et le nombre de paquets et d'octets passés sur son interface Ethernet. Il est accessible en https://frosty-butterfly-737.edge.mysocket.io/. Le source du service est disponible.

Le second utilise un autre type de prise, TLS, ce qui permet de faire tourner des protocoles non-HTTP. Pour créer une telle prise, on utilise l'option --type TLS. À noter qu'un port est alloué pour ce service, pensez à le noter, les clients devront utiliser ce port. Ce service compte simplement le nombre d'octets dans la chaîne de caractères que vous lui envoyer. Il est en misty-violet-3591.edge.mysocket.io:41106. Comme c'est du TLS, on ne peut pas utiliser telnet ou netcat comme client, donc on va se servir de gnutls-cli :

 % gnutls-cli -p 41106 misty-violet-3591.edge.mysocket.io
 ...
 - Status: The certificate is trusted. 
- Description: (TLS1.2)-(ECDHE-SECP256R1)-(RSA-SHA256)-(AES-256-GCM)
...
- Simple Client Mode:

toto
4 bytes

Et mysocketctl va montrer la connexion :

192.0.2.106 [25/Nov/2020:19:19:50 +0000] TCP 200 bytes_sent:8 bytes_received:5 session_time: 1.899 

Le source du service est disponible.

Comme la demande pour un tel service est forte, il y a d'autres solutions possibles (je ne les ai pas testées) :


L'article seul

RFC 8961: Requirements for Time-Based Loss Detection

Date de publication du RFC : Novembre 2020
Auteur(s) du RFC : M. Allman (ICSI)
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 24 novembre 2020


Vous savez certainement que l'Internet fait circuler les données sous forme de paquets indépendants, et qu'un paquet peut toujours être perdu, par exemple parce qu'un rayon cosmique agressif est passé à ce moment-là ou, moins spectaculaire, parce que les files d'un routeur étaient pleines et qu'il a dû se résigner à laisser tomber le paquet. Des protocoles existent donc pour gérer ces pertes de paquets, ce qui implique de les détecter. Et comment sait-on qu'un paquet a été perdu ? C'est plus complexe que ça n'en a l'air, et ce RFC tente d'établir un cadre générique pour la détection de pertes.

Ne tournons pas autour du pot : la seule façon fiable de savoir si un paquet a été perdu, c'est d'attendre qu'il arrive (ce que le RFC nomme, dans son titre, time-based loss detection) et, s'il n'arrive pas, de le déclarer perdu. Plus précisément, pour l'émetteur (car le récepteur ne sait pas forcément qu'on lui a envoyé un paquet), on émet un paquet et on attend une confirmation qu'il a été reçu (avec TCP, cette confirmation sera le ACK, avec le DNS sur UDP, ce sera la réponse DNS). Si la confirmation n'a pas été reçue, s'il y a timeout, c'est qu'un paquet (la demande, ou bien l'accusé de réception) n'est pas arrivé. Mais attendre combien de temps ? Si on attend peu de temps (mettons 100 millisecondes), on risque de considérer le paquet comme perdu, alors que le voyage était simplement un peu long (en 100 ms, vous ne pouvez même pas faire un aller-retour entre la France et les Philippines, ne serait-ce qu'à cause de la limite de la vitesse de la lumière). Et si on attend longtemps (mettons 5 secondes), on ne pourra pas réagir rapidement aux pertes, et la latence perçue par l'utilisateur sera insupportable (la sensation de « vitesse » pour l'utilisateur dépend davantage de la latence que de la capacité). Il faut donc faire un compromis entre réactivité et justesse.

Il existe d'autres méthodes que l'attente pour détecter des pertes, par exemple TCP et SCTP utilisent aussi les accusés de réception sélectifs (RFC 2018, RFC 4960 dans sa section 3.3.4 et RFC 6675) mais aucune de ces autres méthodes ne détecte toutes les pertes, et la détection par absence de réponse reste donc indispensable.

L'Internet, vous le savez, est un ensemble compliqué de réseaux, reliés par des câbles très variés (et quelques liens radio), avec des débits bien différents et changeant d'un moment à l'autre. Tout chemin d'une machine à l'autre va avoir un certain nombre de propriétés (qui varient dans le temps) telles que la latence ou la capacité. Et le taux de perte de paquets, qui nous intéresse ici. (Voir aussi le RFC 7680.)

Notre RFC suppose que la perte de paquets est une indication de congestion (RFC 5681). Ce n'est pas vrai à 100 %, surtout sur les liens radio, où des paquets peuvent être détruits par des perturbations électro-magnétiques sans qu'il y ait congestion, mais c'est quand même proche de la vérité.

Et, au fait, pourquoi détecter la perte de paquets ? Pourquoi ne pas tout simplement ignorer le problème ? Deux raisons :

  • Pour pouvoir envoyer des données de manière fiable, il faut détecter les paquets manquants, afin de pouvoir demander leur retransmission. C'est ce que fait TCP, par exemple, sans quoi on ne pourrait pas transmettre un fichier en étant sûr qu'il arrive complet.
  • Puisque la perte de paquets signale en général qu'il y a congestion, détecter cette perte permet de ralentir l'envoi de données et donc de lutter contre la congestion.

Résultat, beaucoup de protocoles ont un mécanisme de détection de pertes : TCP (RFC 6298), bien sûr, mais aussi SCTP (RFC 4960), SIP (RFC 3261), etc.

Le RFC cite souvent l'article de Allman, M. et Paxson V, « On Estimating End-to-End Network Path Properties » donc vous avez le droit d'interrompre votre lecture ici pour lire cet article avant de continuer.

Reprenons, avec la section 2 du RFC, qui explique les buts et non-buts de ce RFC :

  • Ce RFC ne change aucun protocole existant, les RFC restent les mêmes, vous n'avez pas à réapprendre TCP,
  • Ce RFC vise surtout les RFC futurs, qui auraient intérêt à se conformer aux principes énoncés ici (c'est par exemple le cas si vous développez un nouveau protocole au-dessus d'UDP et que vous devez donc mettre en œuvre la détection de pertes),
  • Ce RFC n'impose pas des règles absolues, il donne des principes qui marchent dans la plupart des cas, c'est tout.

Nous arrivons maintenant à la section 4 du RFC, qui liste les exigences auxquelles doivent obéir les mécanismes de détection de pertes. (En pratique, les mécanismes existants collent déjà à ces exigences mais elles n'avaient pas été formalisées.) Un petit retour sur la notion de latence, d'abord. On veut savoir combien de temps attendre avant de déclarer un paquet perdu. Cette durée se nomme RTO (Retransmission TimeOut). Les latences dans l'Internet étant extrêmement variables, il serait intéressant de faire dépendre le RTO de la latence. Mais quelle latence ? Le temps d'aller-retour entre deux machines est le temps qu'il faut à un paquet IP pour aller de la machine A à la machine B plus le temps qu'il faut à un paquet IP pour aller de B à A. On ne peut pas mesurer directement ce temps, car le temps de traitement dans la machine B n'est pas forcément connu. Dans le cas de l'ICMP Echo utilisé par ping, ce temps est considéré comme négligeable, ce qui est assez correct si l'amer est une machine Unix dont le noyau traite l'ICMP Echo. Cela l'est moins si l'amer est un routeur qui traite les réponses ICMP à sa plus basse priorité. Et cela l'est encore moins si un client DNS essaie d'estimer la latence vers un résolveur. Si le résolveur avait la réponse dans sa mémoire, le temps de traitement est faible. S'il devait demander aux serveurs faisant autorité, ce temps peut être bien supérieur à la latence. Le RFC distingue donc RTT (Round-Trip Time), la vraie latence, et FT (Feedback Time) qui est ce qu'affichent ping, dig et autres outils. La machine qui veut savoir combien de temps attendre une réaction de la machine en face, avant de déclarer qu'un paquet est perdu, a tout intérêt à avoir une idée du FT.

Certaines des exigences du RFC sont quantitatives. Ainsi, tant qu'on n'a pas mesuré le FT (au début de la session), le RFC requiert que le RTO soit d'au moins une seconde, pour ne pas surcharger le réseau avec des réémissions, et parce que la perte étant interprétée comme un signe de congestion, un RTO trop faible amènerait à réduire la quantité de données qu'on peut envoyer, diminuant ainsi la capacité effective. Sans compter le problème de l'ambiguïté. Si on a réémis un paquet, et qu'une réponse revient, était-elle pour le paquet initial ou pour la réémission ? Dans le doute, il ne faut pas utiliser le temps mesuré pour changer son estimation du RTO. Et c'est une des raisons pour lesquelles il faut prendre son temps pour les premières mesures. Ah, au fait, pourquoi une seconde et pas 0,75 ou 1,25 ? Cela vient d'une analyse quantitative des RTT typiques de l'Internet, exposée dans l'annexe A du RFC 6298.

Après plusieurs mesures, on connait mieux le FT et on peut abaisser le RTO. Il n'y a pas de durée minimale, donc on peut s'approcher de zéro tant qu'on veut.

Le RFC dit aussi que le RTO (Retransmission TimeOut, le délai d'attente) doit se mesurer à partir de plusieurs observations du FT, pour éviter une mesure faussée par un cas extrême. Et il faut refaire ces observations souvent car le réseau change ; les vieilles mesures n'ont pas d'intérêt. C'est ce que fait TCP avec son smoothed RTT, utilisant la moyenne mobile exponentielle (RFC 6298).

L'Internet étant ce qu'il est, il est recommandé de s'assurer qu'un méchant ne puisse pas facilement fausser cette mesure en injectant des faux paquets. Pour TCP, cette assurance est donnée par le caractère imprévisible du numéro de séquence initial, si l'attaquant n'est pas sur le chemin (RFC 5961). Si on veut une protection contre un attaquant situé sur le chemin, il faut de la cryptographie.

Le RFC recommande de refaire l'évaluation du RTO au moins une fois par RTT et, de préference, aussi souvent que des données sont échangées. TCP le fait une fois par RTT et, si on utilise le RFC 7323, à chaque accusé de réception.

Le RFC rappelle qu'en l'absence d'indication du contraire, une perte de paquets doit être considérée comme un indicateur de congestion, et qu'il faut donc ralentir (RFC 5681, pour le cas de TCP).

Et, dernière exigence, en cas de perte de paquets, le RTO doit croitre exponentiellement, pour s'ajuster rapidement à la charge du réseau. On pourra réduire le RTO lorsqu'on aura la preuve que les paquets passent et qu'on reçoit des accusés de réception et/ou des réponses. Dans tous les cas, le RFC limite le RTO à 60 secondes, ce qui est déjà énorme (je n'ai jamais vu une réponse revenir après une durée aussi longue).

Enfin, la section 5 discute des exigences posées et de leurs limites. La tension entre le désir de réactivité (un RTO faible) et celui de mesures correctes (un RTO plus important, pour être raisonnablement sûr de ne pas conclure à tort qu'il y a eu une perte) est une tension fondamentale : on n'aura jamais de solution parfaite, juste des compromis. Il existe des techniques qui permettent de mieux détecter les pertes (l'algorithme Eifel - RFC 3522, le F-RTO du RFC 5682, DSACK - RFC 2883 et RFC 3708…) mais elles ne sont pas complètes et l'attente bornée par le RTO reste donc nécessaire en dernier recours.

Le noyau Linux a mis en œuvre plusieurs techniques non normalisées (par exemple des modifications du RFC 6298) sans que cela ne crée apparemment de problèmes. D'une manière générale, les algorithmes de détection de pertes de TCP, SCTP ou QUIC sont largement compatibles avec les exigences de ce RFC.


Téléchargez le RFC 8961


L'article seul

RFC 8943: Concise Binary Object Representation (CBOR) Tags for Date

Date de publication du RFC : Novembre 2020
Auteur(s) du RFC : M. Jones (Microsoft), A. Nadalin (Independent), J. Richter (pdv Financial Software GmbH)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF cbor
Première rédaction de cet article le 21 novembre 2020


Le format de données CBOR, normalisé dans le RFC 8949, possède un certain nombre de types de données de base, et un mécanisme d'extensions, les étiquettes (tags). Ce RFC spécifie deux nouvelles étiquettes, pour indiquer des dates.

Le RFC 8949 déclarait déjà deux types pour les estampilles temporelles, l'étiquette 0 pour une chaîne de caractères dont le contenu est une estampille au format du RFC 3339 (avec la date et l'heure), et l'étiquette 1 pour une estampille sous la forme d'un nombre de secondes depuis l'epoch. Dans ce nouveau RFC sont ajoutées deux étiquettes, 100 pour un entier qui va stocker le nombre de jours depuis l'epoch, et 1004 pour une date seule (sans heure) au format du RFC 3339. L'epoch est celle de la norme Posix 1 / IEEE Standard 1003.1, le 1 janvier 1970. Dans les deux cas, comme on ne stocke pas l'heure, des considérations comme le fuseau horaire ou les secondes intercalaires sont inutiles. Quant au calendrier utilisé, c'est le grégorien.

Dans ce calendrier, John Lennon (je reprends l'exemple du RFC…) est né le 9 octobre 1940 et mort le 8 décembre 1980. (Les dates utilisées dans ce RFC n'incluent pas l'heure.) Pour la première étiquette, 100, qui indique le nombre de jours depuis l'epoch, l'auteur d'I Am the Walrus est né le -10676. C'est un nombre négatif puisque l'epoch utilisée est le 1 janvier 1970, après sa naissance. Lennon est mort le 3994. Pour le cas de la deuxième étiquette, 1004, il est né le 1940-10-09 et mort le 1980-12-08, suivant le format du RFC 3339. Le jour (lundi, mardi, mercredi…) est explicitement non mentionné, si on en a besoin, il faut le recalculer.

Les deux formats, en nombre de jours depuis l'epoch, et en RFC 3339 ont l'avantage que les comparaisons de date sont triviales, une simple comparaison d'entiers dans le premier cas, de chaînes de caractères dans le suivant, suffit.

Petit piège des dates indiquées sans l'heure, un même événement peut survenir à deux dates différentes selon le fuseau horaire. Ainsi, une vidéoconférence qui a lieu, à Tokyo, le 12 octobre à 10h00 sera considérée par les habitants d'Honolulu comme se tenant le 11 octobre à 15h00.

Les deux étiquettes ont été enregistrées à l'IANA. La valeur 100 pour la première a été choisie car 100 est le code ASCII de 'd' (pour date).

Si vous voulez un fichier CBOR utilisant ces deux étiquettes, vous pouvez appeler le service https://www.bortzmeyer.org/apps/date-in-cbor qui vous renvoie un tableau avec les quatre façons de servir une date en CBOR, les deux standards du RFC 8949, et les deux de notre RFC. Ici, on utilise le programmme read-cbor pour afficher plus joliment :

% wget -q -O - https://www.bortzmeyer.org/apps/date-in-cbor | ./read-cbor -
Array of 5 items
...
        Tag 0
                String of length 20: 2020-11-21T06:44:33Z
        Tag 1
                Unsigned integer 1605941073
        Tag 100
                Unsigned integer 18587
        Tag 1004
                String of length 10: 2020-11-21
  

Téléchargez le RFC 8943


L'article seul

RFC 8950: Advertising IPv4 Network Layer Reachability Information (NLRI) with an IPv6 Next Hop

Date de publication du RFC : Novembre 2020
Auteur(s) du RFC : S. Litkowski, S. Agrawal, K. Ananthamurthy (Cisco), K. Patel (Arrcus)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF bess
Première rédaction de cet article le 20 novembre 2020


Le protocole de routage BGP annonce des préfixes qu'on sait joindre, avec l'adresse IP du premier routeur à qui envoyer les paquets pour ce préfixe. (Ce routeur est appelé le next hop.) BGP a une extension, BGP multi-protocoles (RFC 4760) où les préfixes annoncés (NLRI pour Network Layer Reachability Information) ne sont plus forcément de la même famille que les adresses utilisées dans la session BGP. On peut donc annoncer des préfixes IPv6 sur une session BGP établie en IPv4 et réciproquement. Notre RFC, qui succède au RFC 5549 avec quelques petits changements, étend encore cette possibilité en permettant que le next hop ait une adresse de version différente de celle du préfixe.

Normalement, BGP multi-protocoles (RFC 4760) impose la version (IPv4 ou IPv6) du next hop via l'AFI (Address Family Identifier) et le SAFI (Subsequent Address Family Identifier) indiqués dans l'annonce (cf. la liste actuelle des AFI possible et celle des SAFI). Ainsi, un AFI de 1 (IPv4) couplé avec un SAFI valant 1 (unicast), lors de l'annonce d'un préfixe IPv4, impose que l'adresse du routeur suivant soit en IPv4. Désormais, cette règle est plus libérale, le routeur suivant peut avoir une adresse IPv6. Cela peut faciliter, par exemple, la vie des opérateurs qui, en interne, connectent des ilots IPv4 au-dessus d'un cœur de réseau IPv6 (cf. RFC 4925). Notez que cela ne règle que la question de l'annonce BGP. Il reste encore à router un préfixe IPv4 via une adresse IPv6 mais ce n'est plus l'affaire de BGP.

Il y avait déjà des exceptions à la règle comme quoi le préfixe et l'adresse du routeur suivant étaient de la même famille. Ainsi, le RFC 6074 permettait cela pour le couple AFI 25 (L2VPN) / SAFI 65 (VPLS). Mais le couple AFI 2 / SAFI 1 (IPv6 / unicast) ne permet pas de telles exceptions (RFC 2545). Une astuce (RFC 4798 et RFC 4659) permet de s'en tirer en encodant l'adresse IPv4 du next hop dans une adresse IPv6. (Oui, ::192.0.2.66 est une adresse IPv4 encodée dans les seize octets d'IPv6, cf. RFC 4291, section 2.5.5.2.) Quant au cas inverse (AFI IPv4, routeur suivant en IPv6), elle fait l'objet de notre RFC.

Lorsque l'adresse du next hop n'est pas de la famille du préfixe, il faut trouver la famille, ce qui peut se faire par la taille de l'adresse du next hop (quatre octets, c'est de l'IPv4, seize octets, de l'IPv6). C'est ce que propose le RFC 4684.

L'extension permettant la liberté d'avoir des next hop dans une famille différente du préfixe est spécifiée complètement en section 4. Elle liste les couples AFI / SAFI pour lesquels on est autorisé à avoir un next hop IPv6 alors que le préfixe est en IPv4. Le routeur BGP qui reçoit ces annonces doit utiliser la longueur de l'adresse pour trouver tout seul si le next hop est IPv4 ou IPv6 (la méthode des RFC 4684 et RFC 6074).

L'utilisation de cette liberté nécessite de l'annoncer à son pair BGP, pour ne pas surprendre des routeurs BGP anciens. Cela se fait avec les capacités du RFC 5492. La capacité se nomme Extended Next Hop Encoding et a le code 5. Cette capacité est restreinte à certains couples AFI / SAFI, listés dans l'annonce de la capacité. Par exemple, le routeur qui veut annoncer une adresse IPv6 comme next hop pour de l'unicast IPv4 va indiquer dans le champ Valeur de la capacité 1 / 1 (le couple AFI /SAFI) et le next hop AFI 2.

La section 2 du RFC résume les changements depuis le RFC 5549, que notre RFC remplace. L'encodage de l'adresse du next hop change dans le cas des VPN, et, pour les VPN MPLS, extension de l'exception au multicast. Bref, rien de bien crucial.


Téléchargez le RFC 8950


L'article seul

RFC 8726: How Requests for IANA Action Will be Handled on the Independent Stream

Date de publication du RFC : Novembre 2020
Auteur(s) du RFC : A. Farrel (Independent Submissions Editor)
Pour information
Première rédaction de cet article le 20 novembre 2020


Tous les RFC ne viennent pas de l'IETF. Certains sont publiés sur la voie indépendante, sous la responsabilité de l'ISE (Independent Submissions Editor). Certains de ces RFC « indépendants » créent ou modifient des registres IANA. Comment traiter ces demandes à l'IANA ?

Ce travail de l'ISE (Independent Submissions Editor, actuellement Adrian Farrel, l'auteur de ce RFC, et également des contes « Tales from the wood ») est documenté dans le RFC 4846. Cet ancien RFC (il date d'avant la création de l'ISE, qui avait été faite par le RFC 5620, puis précisée par le RFC 6548 puis enfin le RFC 8730) ne donne que peu de détails sur les relations avec l'IANA, nécessaires si le RFC « indépendant » demande la création d'un nouveau registre, ou la modification d'un registre existant. Ces registres IANA sont en https://www.iana.org/protocols, les politiques possibles pour leur avitaillement sont dans le RFC 8126.

Pour les registres existants (section 2 du RFC), l'ISE est évidemment tenu par ce RFC 8126. Si un RFC de la voie indépendante ajoute une entrée à un registre IANA, il doit suivre la politique qui avait été définie pour ce registre. Cela va de soi. D'autre part, un RFC « indépendant » ne représente pas, par définition, l'IETF, et ne peut donc pas créer d'entrées dans un registre dont la politique est « Examen par l'IETF » ou « Action de normalisation ». Pour la même raison, un RFC de la voie indépendante ne peut pas changer la politique d'un registre qui n'avait pas été créé par un RFC de la voie indépendante (section 3).

Et la création de nouveaux registres (section 4 de notre RFC) ? En général, un RFC « indépendant » ne devrait pas le faire, puisqu'il s'agit de documents qui n'ont pas bénéficié du même examen que les RFC de la voie IETF. La seule exception est la possibilité de créer un sous-registre s'il existe un registre à la politique « ouverte » (« Spécification nécessaire », « Examen par un expert », « RFC nécessaire » ou « Premier Arrivé, Premier Servi ») et que le sous-registre correspond à une entrée ajoutée par le RFC indépendant. L'une des raisons de ce choix est d'éviter de donner trop de travail à l'IANA, en multipliant les registres.

Certaines politiques d'allocation dans un registre IANA nécessitent un expert. La section 5 de notre RFC précise que la voie indépendante ne nommera pas d'expert et que donc aucun des sous-registres éventuellement créés n'aura la politique « Examen par un expert ».

Enfin, la section 6 traite le cas du transfert du contrôle d'un registre. Il n'y aura jamais de transfert depuis la voie IETF vers la voie indépendante (une fois qu'un registre est « officiel », il le reste) mais l'inverse peut arriver, par exemple si un protocole initialement décrit dans un RFC « indépendant » passe finalement sur le chemin des normes.


Téléchargez le RFC 8726


L'article seul

À propos de l'enseignement de l'arabe et du pouvoir des langues

Première rédaction de cet article le 18 novembre 2020


Il y a un débat récurrent en France sur l'enseignement de la langue arabe à l'école. Ce débat a resurgi début octobre avec un discours d'Emmanuel Macron promettant de promouvoir cet enseignement. L'un des arguments serait l'influence de la langue sur la pensée. Creusons un peu.

Comme à chaque fois qu'on propose de développer l'enseignement de l'arabe en France, la droite extrême et l'extrême-droite protestent avec des arguments amalgamant langue arabe et islamisme, voire langue arabe et djihadisme. Selon leurs arguments, enseigner l'arabe reviendrait à promouvoir ces idéologies. (Ces arguments reposent en partie sur des ignorances répandues en France, comme de confondre arabe et musulman.) Les partisans de l'enseignement de l'arabe répliquent en général en niant le lien entre langue et idéologie, en notant que l'apprentissage de l'anglais ne fait pas de vous un loyal sujet d'Élisabeth II. Ou bien, si on n'a pas peur du point Godwin, en notant qu'apprendre l'allemand ne vous transforme pas en nazi.

Je suis bien convaincu que les arguments de type « apprendre l'arabe va encourager l'islamisme » sont faux, et certainement de mauvaise foi. Mais dire exactement le contraire, prétendre que la langue n'a aucune influence sur la pensée, est trop simpliste. Depuis que la linguistique existe, les linguistes débattent de cette influence de la langue sur la pensée. Dans sa forme extrême, celle qu'on appelle l'hypothèse de Sapir-Whorf, cette influence est supposée forte. Mais d'autres sont plus prudents (cf. le livre de Deutscher, « Through the language glass ») et estiment qu'il y a certes un rôle joué par la langue dans les pensées mais qu'il est complexe et certainement pas grossièrement déterministe du genre « dès qu'on apprend le nahuatl, on va essayer de reconstruire l'empire aztèque ».

Comme le dit Barbara Cassin (interview dans le numéro de novembre 2020 de la Recherche) « Chaque langue est une manière de dire le monde ». La langue qu'on utilise n'est pas neutre (et Cassin en tire argument pour prôner le multilinguisme, pour avoir plusieurs perspectives).

C'est justement parce que la langue n'est pas neutre que la France dépense baucoup d'argent pour promouvoir la francophonie, ou que la Chine a son réseau des instituts Confucius. Et les États-Unis utilisent également leur langue comme outil de soft power, par exemple via leur domination culturelle. Donc, oui, la langue compte.

Est-ce que cela veut dire qu'il ne faut pas enseigner l'arabe ? Évidemment non. C'est une langue importante, par le nombre de locuteurs et par la quantité de textes existants. Cette langue doit donc être proposée à l'école, comme le russe ou le chinois. Elle doit évidemment être proposée à toutes et tous, pas uniquement à des enfants qui seraient assignés à perpétuité « issu de l'immigration ». Mais il faut faire attention à certains arguments utilisés en faveur de cet enseignement : ils ne sont pas toujours solides.

Trois points pour terminer. Décider d'enseigner l'arabe va forcément amener à la question « lequel ? », vu la grande variété des langues qu'on regroupe sous ce terme. Je ne vais pas trancher ici, c'est un débat compliqué. Ensuite il faut parler des moyens matériels car, en France, on aime bien les grandes postures idéologiques, déconnectées des problèmes pratiques. Or, la promotion de toute matière à l'école suppose 1) des choix, car le nombre d'heures n'est pas extensible 2) de l'argent pour recruter des enseignants. Ce deuxième point a souvent été oublié dans les débats après le discours de Macron. Et le troisième et dernier point concerne l'amalgame souvent fait entre langue arabe et immigration. Je vous recommande l'article de Tassadit Yacine, Pierre Vermeren et Omar Hamourit, « La langue maternelle des immigrés n’est pas l’arabe ». La langue arabe doit être proposée à l'école pour son intérêt propre, pas parce qu'on pense à tort qu'elle est celle des immigrés.


L'article seul

RFC 8909: Registry Data Escrow Specification

Date de publication du RFC : Novembre 2020
Auteur(s) du RFC : G. Lozano (ICANN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 14 novembre 2020


Prenons un registre, par exemple un registre de noms de domaine. Des tas de gens comptent sur lui. Si ce registre disparait en emportant sa base de données, ce serait une catastrophe. Il est donc nécessaire de garder les données à part, ce qu'on nomme un séquestre (escrow). Ce RFC décrit un format standard pour les données de séquestre, indépendant du type de registre (même si la demande prioritaire est pour les registres de noms de domaine). Il s'agit d'un format générique, qui sera complété par des spécifications pour les différents types de registre, par exemple le RFC 9022 pour les registres de noms de domaine.

L'idée (section 1 du RFC) est donc que le registre dépose à intervalles réguliers une copie de sa base de données auprès de l'opérateur de séquestre. Il ne s'agit pas d'une sauvegarde. La sauvegarde est conçue pour faire face à des accidents comme un incendie. Le séquestre, lui, est conçu pour faire face à une disparition complète du registre, par exemple une faillite si le registre est une entreprise commerciale. Ou bien une redélégation complète du domaine à un autre registre. Les sauvegardes, non standardisées et liées à un système d'information particulier, ne peuvent pas être utilisées dans ces cas. D'où l'importance d'un format standard pour un séquestre, précisément ce que normalise notre RFC. Lors d'une défaillance complète de l'ancien registre, l'opérateur de séquestre transmettra les données de séquestre au nouveau registre, qui pourra l'importer dans son système d'information, qui sera alors prêt à prendre le relais. Pour un registre de noms de domaine, le dépôt des données de séquestre devra comprendre la liste des noms, les titulaires et contacts pour chacun des noms, les serveurs de noms, les enregistrements DS (utilisés pour DNSSEC), etc. Par contre, certaines informations ne pourront pas être incluses, comme les parties privées des clés utilisées pour DNSSEC (qui sont peut-être enfermées dans un HSM) et le nouveau registre aura donc quand même un peu de travail de réparation.

Ainsi, la convention entre l'État et l'AFNIC pour la gestion du .fr prévoit dans sa section 5 que « L'Office d'enregistrement [sic] s'engage à mettre en place et à maintenir sur le sol français un séquestre de données quotidien ». Même chose pour les TLD sous contrat avec l'ICANN. Le Base Registry Agreement impose un séquestre dans sa spécification 2 « DATA ESCROW REQUIREMENTS ». Elle dit « Deposit’s Format. Registry objects, such as domains, contacts, name servers, registrars, etc. will be compiled into a file constructed as described in draft-arias-noguchi-registry-data-escrow, see Part A, Section 9, reference 1 of this Specification and draft-arias-noguchi-dnrd-objects-mapping, see Part A, Section 9, reference 2 of this Specification (collectively, the “DNDE Specification”). ». [Le document draft-arias-noguchi-registry-data-escrow est devenu ce RFC 8909.] L'ICANN reçoit actuellement 1 200 séquestres, pour chaque TLD qu'elle régule, les dépôts ayant lieu une fois par semaine.

Ces exigences sont tout à fait normales : la disparition d'un registre de noms de domaine, s'il n'y avait pas de séquestre, entrainerait la disparition de tous les noms, sans moyen pour les titulaires de faire valoir leurs droits. Si .org disparaissait sans séquestre, bortzmeyer.org n'existerait plus, et si un registre prenait le relais avec une base de données vide, rien ne me garantit d'obtenir ce nom, l'adresse de ce blog devrait donc changer. Cette question de continuité de l'activité de registre, même si des organisations disparaissent, est la motivation pour ce RFC (section 3).

Un exemple de service de « registre de secours » (third-party beneficiary, dans la section 2 du RFC, on pourrait dire aussi backup registry) est l'EBERO (Emergency Back-End Registry Operator) de l'ICANN, décrit dans les « Registry Transition Processes ».

Ce RFC ne spécifie qu'un format de données. Il ne règle pas les questions politiques (faut-il faire un séquestre, à quel rythme, qui doit être l'opérateur de séquestre, qui va désigner un registre de secours, etc).

Passons donc à la technique (section 5). Le format est du XML. L'élément racine est <deposit> (dépôt). Un attribut type indique si ce dépôt est complet (la totalité des données) ou bien incrémental (différence avec le dépôt précédent). L'espace de noms est urn:ietf:params:xml:ns:rde-1.0, enregistré à l'IANA (voir la section 8). RDE signifie Registry Data Escrow. Parmi les éléments obligatoires sous <deposit>, il y a :

  • <watermark> qui indique le moment où ce dépôt a été fait, au format du RFC 3339 (section 4). On peut traduire watermark par jalon, point de synchronisation, point d'étape ou marque.
  • <rdeMenu>, diverses métadonnées.
  • <contents> contient les données (rappelez-vous que ce RFC est générique, le format exact des données, qui dépend du type de registre, sera dans un autre RFC).
  • <deletes> ne sert que pour les dépôts incrémentaux, et indique les objets qui ont été détruits depuis la dernière fois.
  • Eh non, il n'y a pas d'élément <adds> ; dans un dépôt incrémental, les éléments ajoutés sont sous <contents>.

Voici un exemple très partiel d'un dépôt complet :


<?xml version="1.0" encoding="UTF-8"?>
<d:deposit xmlns:d="urn:ietf:params:xml:ns:rde-1.0"
	   xmlns:myobj="urn:example:my-objects-1.0"
	   type="FULL" id="20201006" resend="0">
  <d:watermark>2020-10-06T13:12:15Z</d:watermark>
  <d:rdeMenu>
    <d:version>1.0</d:version>
    <d:objURI>urn:example:my-objects-1.0</d:objURI>
  </d:rdeMenu>
  <d:contents>
    <myobj:object>
      <myobj:value>42</myobj:value>
    </myobj:object>
  </d:contents>  
</d:deposit>

Dans cet exemple, le fichier XML contient un dépôt complet, fait le 6 octobre 2020, et dont le contenu est un seul élément, de valeur 42. (Pour un vrai dépôt lors d'un séquestre d'un registre de noms de domaine, on aurait, au lieu de <myobj:object>, les domaines, leurs titulaires, etc.) Vous avez des exemples un peu plus réalistes dans les sections 11 à 13 du RFC.

Attention si vous utilisez des dépôts incrémentaux, l'ordre des <contents> et <deletes> compte : il faut mettre les <deletes> en premier.

La syntaxe complète est décrite dans la section 6 du RFC, en XML Schema. Du fait de l'utilisation de XML, l'internationalisation est automatique, on peut par exemple mettre les noms des contacts en Unicode (section 7).

Le format décrit dans ce RFC est seulement un format. Des tas de questions subsistent si on veut un système de séquestre complet, il faut par exemple spécifier un mécanisme de transport des données entre le registre et l'opérateur de séquestre (par exemple avec SSH, ou bien un POST HTTPS). Pour l'ICANN, c'est spécifié dans l'Internet-Draft draft-lozano-icann-registry-interfaces.

Il faut également se préoccuper de tout ce qui concerne la sécurité. La section 9 du RFC rappelle que, si on veut que les données de séquestre soient confidentielles (pour un registre de noms de domaine, les coordonnées des titulaires et contacts sont certainement en bonne partie des données personnelles, cf. section 10), il faut chiffrer la communication entre le registre et l'opérateur de séquestre. Et il faut bien sûr tout authentifier. L'opérateur de séquestre doit vérifier que le dépôt vient bien du registre et n'est pas un dépôt injecté par un pirate, le registre doit vérifier qu'il envoie bien le dépôt à l'opérateur de séquestre et pas à un tiers. Comme exemple des techniques qui peuvent être utilisées pour atteindre ce but, l'ICANN cite OpenPGP (RFC 4880) : « Files processed for compression and encryption will be in the binary OpenPGP format as per OpenPGP Message Format - RFC 4880, see Part A, Section 9, reference 3 of this Specification. Acceptable algorithms for Public-key cryptography, Symmetric-key cryptography, Hash and Compression are those enumerated in RFC 4880, not marked as deprecated in OpenPGP IANA Registry, see Part A, Section 9, reference 4 of this Specification, that are also royalty-free. ».

Comme le séquestre ne servirait qu'en cas de terminaison complète du registre, on peut penser que le registre actuel n'est pas très motivé pour assurer ce service (et c'est pour cela qu'il doit être imposé). Il y a un risque de négligence (voire de malhonnêté) dans le production des dépôts. Voici pourquoi l'opérateur de séquestre doit tester que les dépôts qu'il reçoit sont corrects. Au minimum, il doit vérifier leur syntaxe. Ici, on va se servir de xmllint pour cela. D'abord, on utilise un schéma pour les données spécifiques de notre type de registre. Ici, il est très simple, uniquement des données bidon :


% cat myobj.xsd                                
<?xml version="1.0" encoding="utf-8"?>

<schema targetNamespace="urn:example:my-objects-1.0"
	xmlns:myobj="urn:example:my-objects-1.0"
	xmlns:rde="urn:ietf:params:xml:ns:rde-1.0"
	xmlns="http://www.w3.org/2001/XMLSchema"
	elementFormDefault="qualified">

    <annotation>
      <documentation>
        Test
      </documentation>
    </annotation>
    
    <element name="object" type="myobj:objectType" substitutionGroup="rde:content"/>

    <complexType name="objectType">
      <complexContent>
	<extension base="rde:contentType">
	  <sequence>
	    <element name="value" type="integer"/>
	  </sequence>
      </extension>
      </complexContent>
    </complexType>
 
</schema>

  

Ensuite, on écrit un petit schéma qui va importer les deux schémas, le nôtre (ci-dessus), spécifique à un type de registre, et le schéma du RFC, générique :


% cat wrapper.xsd                              
<?xml version="1.0" encoding="utf-8"?>

<schema targetNamespace="urn:example:tmp-1.0"
	xmlns="http://www.w3.org/2001/XMLSchema">

  <import namespace="urn:ietf:params:xml:ns:rde-1.0" schemaLocation="rde.xsd"/>
  <import namespace="urn:example:my-objects-1.0" schemaLocation="myobj.xsd"/>

</schema>

  

Ensuite, on produit le dépôt :

  
% cat test.xml                                 
<?xml version="1.0" encoding="UTF-8"?>
<d:deposit xmlns:d="urn:ietf:params:xml:ns:rde-1.0"
	   xmlns:myobj="urn:example:my-objects-1.0"
	   type="FULL" id="20201006" resend="0">
  <d:watermark>2020-10-06T13:12:15Z</d:watermark>
  <d:rdeMenu>
    <d:version>1.0</d:version>
    <d:objURI>urn:example:my-objects-1.0</d:objURI>
  </d:rdeMenu>
  <d:contents>
    <myobj:object>
      <myobj:value>42</myobj:value>
    </myobj:object>
  </d:contents>  
</d:deposit>

  

Et on n'a plus qu'à valider ce dépôt :

    
% xmllint --noout --schema wrapper.xsd test.xml
test.xml validates

  

Si les données étaient incorrectes (dépôt mal fait), xmllint nous préviendrait :

% xmllint --noout --schema wrapper.xsd test.xml
test.xml:12: element value: Schemas validity error : Element '{urn:example:my-objects-1.0}value': 'toto' is not a valid value of the atomic type 'xs:integer'.
test.xml fails to validate
  

Idéalement, il faudrait même que l'opérateur de séquestre teste un chargement complet des données dans un autre logiciel de gestion de registre (oui, je sais, c'est beaucoup demander). Bon, s'il vérifie la syntaxe, c'est déjà ça.


Téléchargez le RFC 8909


L'article seul

Quand les gens déconnent, faut-il déréférencer leurs œuvres passées ?

Première rédaction de cet article le 13 novembre 2020
Dernière mise à jour le 14 novembre 2020


J'ai parlé plusieurs fois positivement, sur ce blog, des livres des Pinçon-Charlot. Maintenant que Monique Pinçon-Charlot a tenu des propos délirants dans le documentaire complotiste « Hold-up », que faire ?

Je donne tout de suite la réponse : rien. Je ne vais pas changer les articles en question. Pas seulement parce qu'il serait irréaliste (et peut-être néfaste) de tenir à jour tous les articles passés. Mais surtout parce que les gens évoluent. Ce n'est pas parce que quelqu'un dit des choses fausses ou parce qu'il a changé d'idées que sa production passée est automatiquement à jeter.

Sur les faits : si vous ne voulez pas vous taper les deux heures quarante du documentaire, l'extrait avec Monique Pinçon-Charlot est en ligne. Et on peut trouver aussi une bonne analyse de Daniel Schneidermann.

Il est triste que Pinçon-Charlot ait ainsi déconné. Et insupportable que la droite extrême complotiste l'utilise comme caution de gauche dans son documentaire. Mais cela ne change pas ce qu'elle a écrit de bien autrefois. Comme le dit Denis Colombi, « il serait faux de juger le jour en fonction du soir ». Je sépare donc la femme d'aujourd'hui de la chercheuse du passé, et je continue à recommander les livres des Pinçon-Charlot.

Une mise à jour du lendemain : sur le compte Twitter officiel des Pinçon-Charlot (je ne sais pas qui le gère), une série de tweets exprimait le regret d'avoir participé à ce documentaire. Personnellement, je trouve l'analyse du problème bienvenue, mais insuffisante, par exemple parce ce qu'elle mélange la défiance (justifiée) vis-à-vis des autorités avec la croyance aveugle dans les complots les plus délirants. Et l'argument « on m'avait dit que je pourrais visionner le documentaire avant » a ses limites. Les auteurs du documentaire sont des complotistes connus, et leur faire confiance montrait une certaine naïveté, qu'on peut pardonner au gilet jaune de base, mais pas à une intellectuelle qui a l'habitude des médias (aurait-elle donné un interview à Valeurs actuelles si ce journal avait « promis » qu'elle pourrait vérifier avant publication ?).


L'article seul

Fiche de lecture : Une nuit @thecallcenter

Auteur(s) du livre : Chetan Bhagat
Éditeur : Stock
978-2-234-06023-4
Publié en 2007
Première rédaction de cet article le 12 novembre 2020


Un roman de Chetan Bhagat très drôle et très vivant, mais sur un sujet pas forcément amusant, celui des travailleurs de l'ombre du call center en Inde.

Les héros travaillent dans une de ces entreprises, désormais bien connues (cf. le film Slumdog Millionaire) qui répondent en permanence à des appels d'utilisateurs perdus, qui ne savent pas faire fonctionner un des équipements compliqués qu'on nous vend. En l'occurrence, pour les personnages du roman, l'électroménager, d'où, par exemple, une client qui a démonté le four électrique pour faire rentrer la dinde de Thanksgiving et qui se plaint d'avoir reçu une décharge électrique.

On suit tous les problèmes de bureau, le chef incompétent et ses idées idiotes, la vision qu'ont les Indiens du reste du monde, la collègue avec qui le héros a une liaison, les conseils du formateur, les clients (« il y a dix mecs intelligents aux États-Unis ; les autres nous appellent ») et, une nuit, pendant une panne du système téléphonique, un appel inhabituel qui va tout changer. Je ne vous raconte pas, mais je vous recommande la lecture. C'est à la fois plein d'humour, et ça parle pourtant de choses sérieuses.

(J'ai lu la traduction française, l'original, écrit en anglais, était One night @ the call center, avec des espaces.)


L'article seul

RFC 8927: JSON Type Definition

Date de publication du RFC : Novembre 2020
Auteur(s) du RFC : U. Carion (Segment)
Expérimental
Première rédaction de cet article le 7 novembre 2020


Il existe plusieurs langages pour décrire la structure d'un document JSON. Aucun ne fait l'objet d'un clair consensus. Sans compter les nombreux programmeurs qui ne veulent pas entendre parler d'un schéma formel. Ce nouveau RFC décrit un de ces langages, JTD, JSON Type Definition. Une de ses particularités est que le schéma est lui-même écrit en JSON. Son cahier des charges est de faciliter la génération automatique de code à partir du schéma. JTD est plus limité que certains langages de schéma, afin de faciliter l'écriture d'outils JTD.

On l'a dit, il n'existe pas d'accord dans le monde JSON en faveur d'un langage de schéma particulier. La culture de ce monde JSON est même souvent opposée au principe d'un schéma. Beaucoup de programmeurs qui utilisent JSON préfèrent l'agilité, au sens « on envoie ce qu'on veut et le client se débrouille pour le comprendre ». Les mêmes désaccords existent à l'IETF, et c'est pour cela que ce RFC n'est pas sur le chemin des normes, mais a juste l'état « Expérimental ».

JSON est normalisé dans le RFC 8259. D'innombrables fichiers de données sont disponibles au format JSON, et de très nombreuses API prennent du JSON en entrée et en rendent en sortie. La description des structures de ces requêtes et réponses est typiquement faite en langage informel. C'est par exemple le cas de beaucoup de RFC qui normalisent un format utilisant JSON comme le RFC 9083, les RFC 8620 et RFC 8621, le RFC 7033, etc. Une des raisons pour lesquelles il est difficile de remplacer ces descriptions en langue naturelle par un schéma formel (comme on le fait couramment pour XML, par exemple avec Relax NG) est qu'il n'y a pas d'accord sur le cahier des charges du langage de schéma. JTD (JSON Type Definition) a des exigences bien précises (section 1 du RFC). Avant de comparer JTD à ses concurrents (cf. par exemple l'annexe B), il faut bien comprendre ces exigences, qui influent évidemment sur le langage :

  • Description sans ambiguïté de la structure du document JSON (d'accord, cette exigence est assez banale, pour un langage de schéma…),
  • Possibilité de décrire toutes les constructions qu'on trouve dans un document JSON typique,
  • Une syntaxe qui doit être facile à lire et à écrire, aussi bien pour les humains que pour les programmes,
  • Et, comme indiqué plus haut, tout faire pour faciliter la génération de code à partir du schéma, la principale exigence de JTD ; l'idée est que, si un format utilise JTD, un programme qui analyse ce format soit en bonne partie générable uniquement à partir de la description JTD.

Ainsi, JTD a des entiers sur 8, 16 et 32 bits, qu'un générateur de code peut traduire directement en (le RFC utilise des exemples C++) int8_t, int16_t, etc, mais pas d'entiers de 64 bits, pourtant admis en JSON mais peu portables (cf. annexe A.1). JTD permet de décrire les propriétés d'un objet (« objet », en JSON, désigne un dictionnaire) qu'on peut traduire en struct ou std::map C++.

Les fans de théorie des langages et de langages formels noteront que JTD n'est pas lui-même spécifié en JTD. Le choix ayant été fait d'un format simple, JTD n'a pas le pouvoir de se décrire lui-même et c'est pour cela que la description de JTD est faite en CDDL (Concise Data Definition Language, RFC 8610).

La syntaxe exacte est spécifiée en section 2, une fois que vous avez (re)lu le RFC 8610. Ainsi, la description de base, en CDDL, d'un membre d'un objet JSON est :

properties = (with-properties // with-optional-properties)

with-properties = (
     properties: { * tstr => { schema }},
     ? optionalProperties: { * tstr => { schema }},
     ? additionalProperties: bool,
     shared,
   )
  

Ce qui veut dire en langage naturel que le schéma JTD peut avoir un membre properties, lui-même ayant des membres composés d'un nom et d'un schéma. Le schéma peut être, entre autres, un type, ce qui est le cas dans l'exemple ci-dessous. Voici un schéma JTD trivial, en JSON comme il se doit :

{
  "properties": {
    "name": {
      "type": "string"
    },
    "ok": {
      "type": "boolean",
      "nullable": true
    },
    "level": {
      "type": "int32"
    }
  }
}
  

Ce schéma accepte le document JSON :

{
  "name": "Foobar",
  "ok": false,
  "level": 1
}
  

Ou bien ce document :

{
  "name": "Durand",
  "ok": null,
  "level": 42
}
  

(L'élément nullable peut valoir null ; si on veut pouvoir omettre complètement un membre, il faut le déclarer dans optionalProperties, pas properties.) Par contre, cet autre document n'est pas valide :

{
  "name": "Zig",
  "ok": true,
  "level": 0,
  "extra": true
}
  

Car il y a un membre de trop, extra. Par défaut, JTD ne le permet pas mais un schéma peut comporter additionalProperties: true ce qui les autorisera.

Ce document JSON ne sera pas accepté non plus :

{
  "name": "Invalid",
  "ok": true
}
  

Car la propriété level ne peut pas être absente.

Un exemple plus détaillé, et pour un cas réel, figure dans l'annexe C du RFC, en utilisant le langage du RFC 7071.

JTD ne permet pas de vrai mécanisme d'extension mais on peut toujours ajouter un membre metadata dont la valeur est un objet JSON quelconque, et qui sert à définir des « extensions » non portables.

Jouons d'ailleurs un peu avec une mise en œuvre de JTD. Vous en trouverez plusieurs ici, pour divers langages de programmation. Essayons avec celui en Python. D'abord, installer le paquetage :

% git clone https://github.com/jsontypedef/json-typedef-python.git
% cd json-typedef-python
% python setup.py build
% python setup.py install --user
  

(Oui, on aurait pu utiliser pip install jtd à la place.) Le paquetage n'est pas livré avec un script exécutable, on en crée un en suivant la documentation. Il est simple :

#!/usr/bin/env python3

import sys
import json

import jtd

if len(sys.argv) != 3:
    raise Exception("Usage: %s schema json-file" % sys.argv[0])

textSchema = open(sys.argv[1], 'r').read()
textJsonData = open(sys.argv[2], 'r').read()

schema = jtd.Schema.from_dict(json.loads(textSchema))
jsonData = json.loads(textJsonData)

result = jtd.validate(schema=schema, instance=jsonData)
print(result)
  

Si le fichier JSON correspond au schéma, il affichera un tableau vide, sinon un tableau contenant la liste des erreurs :

% ./jtd.py myschema.json mydoc1.json 
[]
  

(myschema.json contient le schéma d'exemple plus haut et mydoc1.json est le premier exemple JSON.) Si, par contre, le fichier JSON est invalide :

 % ./jtd.py myschema.json mydoc3.json
[ValidationError(instance_path=['extra'], schema_path=[])]
  

(mydoc3.json était l'exemple avec le membre supplémentaire, extra.)

Une particularité de JTD est de normaliser le mécanisme de signalement d'erreurs. Les erreurs doivent être formatées en JSON (évidemment…) avec un membre instancePath qui est un pointeur JSON (RFC 6901) indiquant la partie invalide du document, et un membre schemaPath, également un pointeur, qui indique la partie du schéma qui invalidait cette partie du document (cf. le message d'erreur ci-dessus, peu convivial mais normalisé).

JTD est spécifié en CDDL donc on peut tester ses schémas avec les outils CDDL, ici un outil en Ruby :

% gem install cddl --user
  

Ensuite, on peut valider ses schémas :

% cddl jtd.cddl validate myschema.json 
%
  

Si le schéma a une erreur (ici, j'ai utilisé le type char, qui n'existe pas) :

% cddl jtd.cddl validate wrongschema.json
CDDL validation failure (nil for {"properties"=>{"name"=>{"type"=>"char"}, "ok"=>{"type"=>"boolean", "nullable"=>true}, "level"=>{"type"=>"int32"}}}):
["char", [:text, "timestamp"], nil]
["char", [:text, "timestamp"], null]
  

(Oui, les messages d'erreur de l'outil cddl sont horribles.)

Et avec l'exemple de l'annexe C, le reputon du RFC 7071 :

% cddl jtd.cddl validate reputon.json
% 
  

C'est parfait, le schéma du RFC est correct, validons le fichier JSON tiré de la section 6.4 du RFC 7071 :

% ./jtd.py reputon.json r1.json 
[]
  

Si jamais il y a une erreur (ici, on a enlevé le membre rating) :

% ./jtd.py reputon.json r1.json
[ValidationError(instance_path=['reputons', '0'], schema_path=['properties', 'reputons', 'elements', 'properties', 'rating'])]
  

Une intéressante annexe B fait une comparaison de JTD avec CDDL. Par exemple, le schéma CDDL :

root = "PENDING" / "DONE" / "CANCELED"
  

accepterait les mêmes documents que le schéma JTD :

{ "enum": ["PENDING", "DONE", "CANCELED"]} 
  

Et celui-ci, en CDDL (où le point d'interrogation indique un terme facultatif) :

root = { a: bool, b: number, ? c: tstr, ? d: tdate }
  

reviendrait à ce schéma JTD :

{
  "properties": {
    "a": {
      "type": "boolean"
    },
    "b": {
      "type": "float32"
    }
  },
  "optionalProperties": {
    "c": {
      "type": "string"
    },
    "d": {
      "type": "timestamp"
    }
  }
}
  

Merci à Ulysse Carion pour sa relecture.


Téléchargez le RFC 8927


L'article seul

Fiche de lecture : The weather machine

Auteur(s) du livre : Andrew Blum
Éditeur : Vintage
978-1-784-70098-0
Publié en 2019
Première rédaction de cet article le 6 novembre 2020


C'est vrai, ça, comment on prédit le temps ? On va sur le site Web de son choix qui présente la météo des jours suivants, on bien on a une application qui récupère ça et affiche dans un coin de votre écran soleil ou nuages. Mais, derrière, que se passe-t-il ? Andrew Blum a consacré un livre à la question de cette « machine du temps ». Comment fonctionne-t-elle ?

Bob Dylan chantait « vous n'avez pas besoin d'un météorologiste pour savoir dans quel sens le vent souffle ». Mais pour prévoir comment il va souffler dans deux, quatre ou six jours, là, vous avez besoin de météorologistes. Et d'observateurs, et d'ordinateurs et de théoriciens qui bossent sur les modèles. Andrew Blum, l'auteur de Tubes, où il explorait la matérialité de l'Internet, va cette fois se pencher sur la météo. Car c'est une machine complexe que celle qui sert à prédire le temps. Déjà, il faut des observations. Ensuite, il faut les transmettre assez vite pour qu'elles soient encore utiles. La météo n'a donc vraiment commencé qu'avec le télégraphe. Ensuite, il faut faire quelque chose de ces observations (faites d'abord à terre, puis, de nos jours, via des satellites), ensuite soit on a des experts qui regardent ces données et en déduisent le temps qu'il fera, soit, aujourd'hui, on a des ordinateurs qui calculent sur la base de modèles. Et il faut partager les observations, y compris entre pays qui ne s'aiment pas, car la météo ignore les frontières. Cela a nécessité quelques conférences internationales, et pas mal de réunions. (En parlant de géopolitique, j'ai appris dans ce livre que la météo avait été la raison de l'unique débarquement nazi en Amérique pendant la Seconde Guerre mondiale).

Comme dans Tubes, l'auteur va sur le terrain et nous raconte ses visites. (Mais le livre est plus mince que Tubes et je suis un peu resté sur ma faim.) On visite donc la station d'observaton d'Utsira, les bureaux d'EUMETSAT et l'ECMWF. Une bonne occasion de regarder tout ce qui se passe « derrière », tout ce qui fait qu'on sait à l'avance s'il fera beau ou pas.


L'article seul

RFC 8905: The 'payto' URI scheme for payments

Date de publication du RFC : Octobre 2020
Auteur(s) du RFC : F. Dold (Taler Systems SA), C. Grothoff (BFH)
Pour information
Première rédaction de cet article le 26 octobre 2020


Le paiement de services ou de biens est un problème crucial sur l'Internet. En l'absence de mécanisme simple, léger et respectant la vie privée, on n'a aujourd'hui que des solutions centralisées dans des gros monstres, comme Amazon pour vendre des objets physiques, ou YouTube pour monétiser ses vidéos. Ce RFC ne propose pas de solution magique mais il spécifie au moins une syntaxe pour indiquer un mécanisme de paiement : le plan d'URI payto:, qui permettra peut-être un jour de faciliter les paiements.

Le paysage d'aujourd'hui est le suivant. Si vous êtes un créateur (d'articles, de vidéos, de dessins, peu importe) et que vous voulez être payé pour vos créations (ce qui est tout à fait légitime), vous n'avez comme solutions que de faire appel à du financement participatif (style Liberapay ou Ulule) ou bien de passer par une grosse plate-forme comme YouTube, qui imposera ses règles, comme la captation de données personnelles. Sans compter le contrôle du contenu, qui fait qu'une vidéo parlant de sujets sensibles sera démonétisée. (Voyez par exemple cette vidéo de Charlie Danger où, à partir de 10:45 et surtout 11:45, elle explique comment YouTube n'a pas aimé sa vidéo sur l'IVG et ce qui en est résulté.) Mais cette solution d'hébergement sur un GAFA est sans doute la plus simple pour le créateur, et elle ne dépend pas de la bonne volonté des lecteurs/spectacteurs. Lorsqu'on discute avec un·e vidéaste de son hébergement chez Google et qu'on lui propose d'utiliser plutôt un service libre et décentralisé fait avec PeerTube, la réponse la plus fréquente est « mais je perdrais la monétisation, et je ne peux pas vivre seulement d'amour et d'eau fraîche ». Je l'ai dit, il n'existe pas encore de solution parfaite à ce problème. Pour un cas plus modeste, celui de ce blog, j'ai tenté Flattr et Bitcoin mais avec très peu de succès.

Ce nouveau RFC ne propose pas une solution de paiement, juste un moyen de faire des URI qu'on pourra mettre dans ces pages Web pour pointer vers un mécanisme de paiement. Par exemple, payto://bitcoin/1HtNJ6ZFUc9yu9u2qAwB4tGdGwPQasQGax?amount=BITCOIN:0.01&message="Ce%20blog%20est%20super" va indiquer qu'il faut envoyer 10 milli-bitcoins à cette adresse (c'est la mienne), avec un gentil message. Si votre navigateur Web gère le plan d'URI payto: (ce qu'aucun ne fait à l'heure actuelle), que vous cliquez puis confirmez, je recevrai 0,01 bitcoin. (Notez qu'il existe une syntaxe spécifique à Bitcoin, pour un paiement, décrite dans le BIP 0021, et qui ressemble beaucoup à celle du RFC.)

Un peu de technique maintenant : les plans d'URI (scheme) sont définis dans le RFC 3986, section 3.1. Vous connaissez certainement des plans comme http: ou mailto:. Le plan payto: est désormais dans le registre IANA des plans. Après le plan et les deux barres se trouve l'autorité. Ici, elle indique le type de paiement. Notre RFC en décrit certains (comme bitcoin montré dans l'exemple) et on pourra en enregistrer d'autres. L'idée est de pouvoir présenter à l'utilisateur un mécanisme uniforme de paiement, quel que soit le type de paiement. (À l'heure actuelle, si vous acceptez les paiements par Flattr et PayPal, vous devez mettre deux boutons différents sur votre site Web, et qui déclencheront deux expériences utilisateur très différentes. Sans compter les traqueurs qu'il y a probablement derrière le bouton de Paypal.)

Question interface utilisateur, le RFC recommande que le navigateur permette ensuite à l'utilisateur de choisir le compte à utiliser, s'il en a plusieurs et, bien sûr, lui demande clairement une confirmation claire. Pas question qu'un simple clic déclenche le paiement ! (Cf. section 8 du RFC, qui pointe entre autres le risque de clickjacking.) Notez aussi que le RFC met en garde contre le fait d'envoyer trop d'informations (par exemple l'émetteur) dans le paiement, ce qui serait au détriment de la vie privée.

On peut ajouter des options à l'URI (section 5 du RFC). Par exemple la quantité à verser (amount, cf. l'exemple Bitcoin plus haut, le code de la monnaie, s'il a trois lettres, devant être conforme à ISO 4217, le Bitcoin n'ayant pas de code officiel, j'ai utilisé un nom plus long), receiver-name et sender-name, message (pour le destinataire) et instruction, ce dernier servant à préciser le traitement à faire par l'organisme de paiement.

Voici un autre exemple d'URI payto:, après Bitcoin, IBAN (ISO 20022) : payto://iban/DE75512108001245126199?amount=EUR:200.0&message=hello. L'exemple est tiré du RFC. Je n'ai pas mis mon vrai numéro IBAN car je ne suis pas expert en sécurité des IBAN et je ne sais pas s'il n'y a pas des inconvénients à le rendre public. Un expert pour confirmer ? À part ça, avec le type iban, l'option message correspond à ce que SEPA appelle unstructured remittance information et instruction au end to end identifier.

Puisqu'il y a une option permettant d'envoyer un message, la section 6 du RFC note qu'il n'y a pas de vrai mécanisme d'internationalisation, entre autres parce qu'on ne peut pas garantir de manière générale comment ce sera traité par les établissements de paiement.

Outre Bitcoin et IBAN, déjà vus, notre RFC enregistre plusieurs autres types de mécanismes de paiement. ACH, BIC/Swift et UPI appartiennent au monde bancaire classique. Le type ilp vient, lui, du monde Internet, comme Bitcoin, est pour les paiements via InterLedger, s'appuyant sur les adresses InterLedger. Et il y a aussi un type void, qui indique que le paiement se fera en dehors du Web, par exemple en liquide.

Cette liste n'est pas fermée, mais est stockée dans un registre évolutif, registre peuplé selon la politique « Premier arrivé, premier servi ». Vous noterez que ce registre n'est pas géré par l'IANA mais par GANA.

La section 7 indique les critères d'enregistrement souhaitables d'un nouveau type (les enregistrements existants peuvent servir d'exemple) : fournir des références précises, trouver un nom descriptif, préférer un nom neutre à celui d'un organisme particulier, etc. J'ai regardé ces critères pour le cas de PayPal, mécanisme de paiement très répandu sur l'Internet, mais ce n'était pas évident. Même si on spécifie des URI du genre payto://paypal/smith@example.com, il ne serait pas évident pour le navigateur de les traduire en une requête PayPal (PayPal privilégie l'installation de son propre bouton actif, ou bien le système PayPal.me). Bref, je n'ai pas continué mais si quelqu'un de plus courageux veut enregistrer le type paypal, il n'est pas nécessaire d'être représentant officiel de PayPal, et ce n'est pas trop difficile. Idem pour d'autres systèmes de paiement par encore spécifiés comme Liberapay. Notez que le système conçu par les auteurs du RFC, Taler, n'est pas encore enregistré non plus.


Téléchargez le RFC 8905


L'article seul

RFC 8932: Recommendations for DNS Privacy Service Operators

Date de publication du RFC : Octobre 2020
Auteur(s) du RFC : S. Dickinson (Sinodun IT), B. Overeinder (NLnet Labs), R. van Rijswijk-Deij (NLnet Labs), A. Mankin (Salesforce)
Réalisé dans le cadre du groupe de travail IETF dprive
Première rédaction de cet article le 25 octobre 2020


Vous gérez un résolveur DNS qui promet de protéger la vie privée des utilisateurs et utilisatrices ? Alors, vous serez certainement intéressé par ce nouveau RFC qui rassemble les bonnes pratiques en matière de gestion d'un tel résolveur, et explique comment documenter la politique du résolveur, les choix effectués. On y trouve une bonne analyse des questions de sécurité, une discussion de ce qui doit être dans une politique, une analyse comparée des politiques, et même un exemple de politique.

Depuis la publication du RFC 7626, les risques pour la vie privée posés par l'utilisation du DNS sont bien connus. Par exemple, un de ces risques est que le trafic DNS entre une machine terminale et le résolveur est en clair et peut donc trivialement être écouté, ce qui est d'autant plus gênant que ce trafic inclut toutes les informations (il n'y a pas de minimisation possible de la question, par exemple). Un autre risque est que le gérant du résolveur voit forcément tout le trafic, même si on chiffre le trafic entre la machine terminale et lui. Il peut abuser de cette confiance qu'on lui fait. Une des solutions possibles face à ces risques est d'utiliser, non pas le résolveur annoncé par le réseau d'accès à l'Internet mais un résolveur extérieur, à qui vous faites confiance, et avec qui vous communiquez de manière chiffrée. De tels résolveurs existent. Certains sont publics (accessibles à tous), gérés par des GAFA comme Cloudflare (avec son résolveur 1.1.1.1) ou gérés par des associations ou bien des individus (vous trouverez une liste partielle à la fin du README de ce logiciel). D'autres de ces résolveurs sont réservés à tel ou tel groupe ou organisation.

Le problème pour l'utilisateur est celui du choix : lequel prendre ? Pour cela, il faut déjà que ceux et celles qui gèrent le résolveur aient documenté leurs pratiques et qu'on leur fasse confiance pour respecter leurs promesses. C'est l'un des buts de ce RFC : fournir un cadre général de description des pratiques d'un résolveur « vie privée », pour faciliter la tâche des rédacteurs et rédactrices de ces documents, dans l'esprit du RFC 6841, qui faisait la même chose pour DNSSEC. Notre RFC n'impose pas une politique particulière, il décrit juste les choix possibles, et ce qu'il ne faut pas oublier de mettre dans son RPS, son Recursive operator Privacy Statement.

Optimiste, notre RFC estime que des promesses formelles de strict préservation de la vie privée des utilisateurs seraient même un avantage pour les résolveurs ayant de tels engagements, leur apportant davantage d'utilisateurs. L'expérience du Web avec le succès des GAFA, entreprises capitalistes captatrices de données personnelles, même lorsqu'une alternative libre et respectueuse de la vie privée existe, me fait douter de ce pronostic.

Notez que la question du choix d'un résolveur est une question complexe. Le RFC cite par exemple le fait qu'avoir un résolveur stable, utilisé pour toutes les connexions d'une machine mobile, peut permettre à ce résolveur de vous suivre, lorsque vous changez de réseau d'accès.

La section 2 décrit le domaine d'applicabilité de ce document : il vise les gérants de résolveurs DNS, pas les utilisateurs finaux, ni les gérants de serveurs faisant autorité. Suivant les principes des RFC 6973 et RFC 7626, il va se pencher sur ce qui arrive aux données en transit sur l'Internet, aux données au repos sur un des serveurs (journaux, par exemple) et aux données transmises pour effectuer le travail (requêtes envoyées par un résolveur aux serveurs faisant autorité, lorsque la réponse n'est pas déjà dans la mémoire du résolveur).

La section 5 est le cœur de notre RFC, elle décrit les recommandations concrètes. Pour illustrer ces recommandations, je dirai à chaque fois comment elles ont été mises en œuvre sur le résolveur sécurisé que je gère, dot.bortzmeyer.fr & https://doh.bortzmeyer.fr/. Non pas qu'il soit le meilleur, le plus rapide, le plus sûr ou quoi que ce soit d'autre. Mais parce qu'il met en œuvre les recommandations de ce RFC, et que je sais qu'il respecte sa politique affichée. Ces notes sur mon résolveur apparaitront entre crochets.

D'abord, en transit, les communications faites en clair peuvent être écoutées par un surveillant passif et, pire, modifiées par un attaquant actif (section 5.1 du RFC). La première recommandation va de soi, il faut chiffrer. Un résolveur DNS public qui n'aurait pas de chiffrement (comme ceux actuellement proposés par certaines associations) n'a guère d'intérêt du point de vue de la vie privée. Pour ce chiffrement, deux techniques normalisées, DoT (DNS sur TLS, RFC 7858 et RFC 8310) et DoH (DNS sur HTTPS, RFC 8484). [Mon résolveur les déploie toutes les deux.] Il existe aussi un DNS sur DTLS (RFC 8094) mais qui n'a eu aucun succès, et des techniques non normalisées comme DNSCrypt, ou une forme ou l'autre de VPN vers le résolveur. Le RFC note que le chiffrement protège le canal, pas les données, et qu'il ne dispense donc pas de DNSSEC (cf. section 5.1.4). [Évidemment mon résolveur valide avec DNSSEC.] Un avantage des canaux sécurisés créés avec DoT ou DoH est qu'il y a beaucoup moins de risque que DNSSEC soit bloqué (cf. RFC 8027).

[Beaucoup de techniciens ont tendance à limiter la protection de la vie privée au chiffrement. C'est un exemple de fascination pour une technique complexe, au détriment d'autres mesures moins geek, qui sont présentées plus loin. Le chiffrement est nécessaire mais certainement pas suffisant.]

Chiffrer n'est pas très utile si on n'a pas authentifié celui avec qui on communique. Un attaquant actif peut toujours tenter de se faire passer pour le serveur qu'on essaie de joindre, par exemple par des attaques BGP ou tout simplement en injectant dans son réseau les routes nécessaires (comme le cas turc). Il faut donc authentifier le résolveur. DoT ne présentait guère de solutions satisfaisantes à l'origine, mais ça s'est amélioré avec le RFC 8310. Un résolveur DoT doit donc présenter un certificat qui permette son authentification ou bien publier sa clé publique (SPKI Subject Public Key Info, mais son utilisation est aujourd'hui déconseillée, car elle rend difficile le changement de clé). Le certificat peut contenir un nom ou une adresse IP. S'il contient un nom, il faut que le client connaisse ce nom, pour l'authentifier (un résolveur DNS traditionnel n'était connu que par son adresse IP). Ainsi, le certificat du résolveur Quad9 contient nom(s) et adresse(s) IP :

% openssl s_client -showcerts -connect 9.9.9.9:853 | openssl x509 -text
...
        Subject: C = US, ST = California, L = Berkeley, O = Quad9, CN = *.quad9.net
...
            X509v3 Subject Alternative Name: 
                DNS:*.quad9.net, DNS:quad9.net, IP Address:9.9.9.9, IP Address:9.9.9.10, IP Address:9.9.9.11, IP Address:9.9.9.12, IP Address:9.9.9.13, IP Address:9.9.9.14, IP Address:9.9.9.15, IP Address:149.112.112.9, IP Address:149.112.112.10, IP Address:149.112.112.11, IP Address:149.112.112.12, IP Address:149.112.112.13, IP Address:149.112.112.14, IP Address:149.112.112.15, IP Address:149.112.112.112, IP Address:2620:FE:0:0:0:0:0:9, IP Address:2620:FE:0:0:0:0:0:10, IP Address:2620:FE:0:0:0:0:0:11, IP Address:2620:FE:0:0:0:0:0:12, IP Address:2620:FE:0:0:0:0:0:13, IP Address:2620:FE:0:0:0:0:0:14, IP Address:2620:FE:0:0:0:0:0:15, IP Address:2620:FE:0:0:0:0:0:FE, IP Address:2620:FE:0:0:0:0:FE:9, IP Address:2620:FE:0:0:0:0:FE:10, IP Address:2620:FE:0:0:0:0:FE:11, IP Address:2620:FE:0:0:0:0:FE:12, IP Address:2620:FE:0:0:0:0:FE:13, IP Address:2620:FE:0:0:0:0:FE:14, IP Address:2620:FE:0:0:0:0:FE:15
...
  

[Mon résolveur, lui, utilise Let's Encrypt, qui ne permet pas encore (cf. RFC 8738) de mettre une adresse IP dans le certificat. Il n'y a donc que le nom. On peut aussi l'authentifier avec sa clé publique (SPKI), qui vaut eHAFsxc9HJW8QlJB6kDlR0tkTwD97X/TXYc1AzFkTFY=.] Puisqu'on parle de certificats : le RFC note à juste titre que les opérateurs de serveurs DNS ne sont pas forcément experts en la matière, sauf à demander de l'aide à leurs collègues HTTP qui gèrent ces certificats depuis longtemps. Le RFC recommande donc d'automatiser (par exemple avec ACME, cf. RFC 8555), et de superviser les certificats (c'est le B A BA, mais combien d'administrateurs système ne le font toujours pas ?).

Le RFC a également des recommandations techniques sur les protocoles utilisés. En effet :

Il est donc conseillé de suivre les recommandations TLS du RFC 7525, de n'utiliser que des versions récentes de TLS. Un rappel, d'ailleurs : les services comme SSLabs.com peuvent parfaitement tester votre résolveur DoH. [J'ai une bonne note.] ssllabs-doh.png

Il est également conseillé de faire du remplissage (RFC 7830 et RFC 8467 ou bien, pour DoH, avec le remplissage HTTP/2), et de ne pas imposer des fonctions qui sont dangereuses pour la vie privée comme la reprise de session TLS (RFC 5077), ou comme les cookies (DNS, RFC 7873 ou HTTP, RFC 6265). [Le logiciel que j'utilise pour mon résolveur, dnsdist, semble faire du remplissage DNS, mais je n'ai pas testé.]

Question non plus de sécurité mais de performance, le RFC recommande de gérer les requêtes en parallèle, y compris de pouvoir donner des réponses dans le désordre (RFC 7766) et de maintenir les sessions TLS ouvertes (RFC 7766 et RFC 7828, voire RFC 8490). [Le logiciel utilisé sur mon résolveur, dnsdist, ne sait pas encore générer des réponses dans un ordre différent de celui d'arrivée.]

Le résolveur DNS est un composant crucial de l'utilisation de l'Internet. S'il est en panne, c'est comme si tout l'Internet est en panne. La disponibilité du résolveur est donc une question cruciale. Si les pannes sont trop fréquentes, les utilisateurs risquent de se rabattre sur des solutions qui ne respectent pas leur vie privée, voire sur des solutions non sécurisées. Le risque est d'autant plus élevé qu'il y a des attaques par déni de service visant les résolveurs DNS (cf. cet article de l'AFNIC). Le RFC recommande donc de tout faire pour assurer cette disponibilité. [Mon propre résolveur, étant un projet personnel, et installé sur un VPS ordinaire, n'est certainement pas bien placé de ce point de vue.]

Bien sûr, il faut fournir aux utilisateurs des services qui protègent la vie privée les mêmes options qu'aux autres visiteurs : résolveur non menteur, validation DNSSEC, etc. (Il existe des services où les choix sont exclusifs et où, par exemple, choisir un résolveur non menteur prive de DNSSEC.)

La protection de la vie privée ne plait pas à tout le monde. Les partisans de la surveillance ont défendu leur point de vue dans le RFC 8404 en réclamant de la visibilité sur le trafic, justement ce que le chiffrement veut empêcher. Ce RFC 8932 essaie de ménager la chèvre et le chou en signalant aux opérateurs de résolveurs chiffrants qu'ils ont toujours accès au trafic en clair, en prenant les données après leur déchiffrement, sur le résolveur. C'est ce que permet, par exemple, la technologie dnstap. Après tout, TLS ne protège qu'en transit, une fois arrivé sur le résolveur, les données sont en clair. [Mon résolveur ne copie pas le trafic en clair, qui n'est jamais examiné. Le logiciel utilisé est capable de faire du dnstap, mais a été compilé sans cette option.] Notez que ce RFC 8932 reprend hélas sans nuances les affirmations du RFC 8404 comme quoi il est légitime d'avoir accès aux données de trafic.

Une technique courante pour mettre en œuvre un résolveur avec TLS est de prendre un résolveur ordinaire, comme BIND, et de le placer derrière un relais qui terminera la session TLS avant de faire suivre au vrai résolveur, typiquement situé sur la même machine pour des raisons de sécurité. Des logiciels comme stunnel, haproxy ou nginx permettent de faire cela facilement, et fournissent des fonctions utiles, par exemple de limitation du trafic. Mais cela ne va pas sans limites. Notamment, avec cette méthode, le vrai résolveur ne voit pas l'adresse IP du client, mais celle du relais. Cela interdit d'utiliser des solutions de sécurité comme les ACL ou comme RRL (Response Rate Limiting). [Mon résolveur utilise un relais, mais avec un logiciel spécialisé dans le DNS, dnsdist. dnsdist peut résoudre le problème de la mauvaise adresse IP en utilisant le PROXY protocol mais je n'utilise pas cette possibilité.]

Nous avons vu jusqu'à présent le cas des données en transit, entre le client et le résolveur DNS. La réponse principale aux problèmes de vie privée était le chiffrement. Passons maintenant au cas des données « au repos », stockées sur le résolveur, par exemple dans des journaux, ou dans des pcap (ou équivalent) qui contiennent le trafic enregistré (section 5.2). Évidemment, pour qu'un service puisse se prétendre « protecteur de la vie privée », il faut qu'une telle rétention de données soit très limitée, notamment dans le temps (c'est un des principes du RGPD, par exemple). Si on garde de telles données pour des raisons légitimes (statistiques, par exemple), il est recommandé de les agréger afin de fournir un peu d'anonymisation. (La lecture recommandée sur ce point est le RFC 6973.) Pour des problèmes à court terme (analyser et comprendre une attaque par déni de service en cours, par exemple), le mieux est de ne pas stocker les données sur un support pérenne, mais de les garder uniquement en mémoire. [Mon résolveur n'enregistre rien sur disque. Des statistiques fortement agrégées sont possibles mais, à l'heure actuelle, ce n'est pas fait.]

Si le chiffrement est le principal outil technique dont on dispose pour protéger les données lorsqu'elles se déplacent d'une machine à l'autre, il est moins utile lorsque des données sont enregistrées sur le serveur. Ici, l'outil technique essentiel est la minimisation des données. C'est le deuxième pilier d'une vraie protection de la vie privée, avec le chiffrement, mais elle est très souvent oubliée, bien que des textes juridiques comme le RGPD insistent sur son importance. Mais attention, minimiser des données n'est pas facile. On a fait de gros progrès ces dernières années en matière de ré-identification de personnes à partir de données qui semblaient minimisées. Comme le note le RFC, il n'y a pas de solution générale, largement acceptée, qui permette de minimiser les données tout en gardant leur utilité. C'est pour cela que quand un décideur sérieux et sûr de lui affirme bien fort « Ne vous inquiétez pas de cette base de données, tout est anonymisé », vous pouvez être raisonnablement sûr qu'il est soit malhonnête, soit incompétent ; réellement anonymiser est très difficile.

Cela fait pourtant quinze ou vingt ans qu'il y a des recherches actives en « anonymisation », motivées entre autre par la volonté de partager des données à des fins de recherches scientifiques. Mais le problème résiste. Et les discussions sont difficiles, car les discoureurs utilisent souvent une terminologie floue, voire incorrecte (par mauvaise foi, ou par ignorance). Notre RFC rappelle donc des points de terminologie (déjà abordés dans le RFC 6973) :

  • Anonymiser, c'est faire en sorte qu'on ne puisse plus distinguer un individu d'un autre individu. C'est une propriété très forte, difficile à atteindre, puisqu'il s'agit de supprimer toute traçabilité entre différentes actions. En général, il faut supprimer ou tronquer une bonne partie des données pour y arriver.
  • Pseudonymiser, c'est remplacer un identificateur par un autre. (Le RFC parle de remplacer la « vraie » identité par une autre mais il n'existe pas d'identité qui soit plus vraie qu'une autre.) Ainsi, remplacer une adresse IP par son condensat SHA-256 est une pseudonymisation. Avec beaucoup de schémas de pseudonymisation, remonter à l'identité précédente est possible. Ici, par exemple, retrouver l'adresse IP originale est assez facile (en tout cas en IPv4).

Quand un politicien ou un autre Monsieur Sérieux parle d'anonymisation, il confond presque toujours avec la simple pseudonymisation. Mais la distinction entre les deux n'est pas toujours binaire.

Dans les données d'un résolveur DNS, l'une des principales sources d'information sur l'identité de l'utilisateur est l'adresse IP source (cf. RFC 7626, section 2.2). De telles adresses sont clairement des données personnelles et il serait donc intéressant de les « anonymiser ». De nombreuses techniques, de qualité très variable, existent pour cela, et le RFC les présente dans son annexe B, que je décris à la fin de cet article. Aucune de ces techniques ne s'impose comme solution idéale marchant dans tous les cas. (À part, évidemment, supprimer complètement l'adresse IP.) Notez qu'il existe d'autres sources d'information sur le client que son adresse IP, comme la question posée (s'il demande security.debian.org, c'est une machine Debian) ou comme le fingerprinting des caractéristiques techniques de sa session. Le problème est évidemment pire avec DoH, en raison des innombrables en-têtes HTTP très révélateurs que les navigateurs s'obstinent à envoyer (User-Agent:, par exemple). Dans certains cas, on voit même des équipements comme la box ajouter des informations précises sur le client.

Ces données stockées sur le résolveur peuvent parfois rester uniquement dans l'organisation qui gère le résolveur, mais elles sont parfois partagées avec d'autres. (Méfiez-vous des petites lettres : quand on vous promet que « nous ne vendrons jamais vos données », cela ne veut pas dire qu'elles ne seront pas partagées, juste que le partageur ne recevra pas directement d'argent pour ce partage.) Le partage peut être utile pour la science (envoi des données à des chercheurs qui feront ensuite d'intéressants articles sur le DNS), mais il est dangereux pour la vie privée. Comme exemple d'organisation qui partage avec les universités, voir SURFnet et leur politique de partage. [Mon résolveur ne partage avec personne.]

Après les données qui circulent entre le client et le résolveur, puis le cas des données stockées sur le résolveur, voyons le cas des données envoyées par le résolveur, pour obtenir la réponse à ses questions (section 5.3 du RFC). Bien sûr, cela serait très bien si le résolveur chiffrait ses communications avec les serveurs faisant autorité, mais il n'existe actuellement pas de norme pour cela (des propositions ont été faites, et des tests menés, mais sans résultat pour l'instant).

Et, de toute façon, cela ne protègerait que contre un tiers, pas contre les serveurs faisant autorité qui enregistrent les questions posées. Face à ce risque, la principale recommandation du RFC est d'utiliser la QNAME minimisation (RFC 7816) pour réduire ces données, en application du principe général « ne pas envoyer plus que ce qui est nécessaire ». [Mon résolveur DoT/DoH fait appel à un résolveur qui fait cela.] Seconde recommandation, respecter les consignes ECS (RFC 7871) : si le client demande à ce que les données ECS soient réduites ou supprimées, il faut lui obéir. [Mon résolveur débraye ECS avec la directive dnsdist useClientSubnet=false.] (Notez que, par défaut, cela permet toujours au résolveur de transmettre aux serveurs faisant autorité l'adresse de son client…)

Deux autres façons, pour le résolveur, de limiter les données qu'il envoie aux serveurs faisant autorité :

  • Générer des réponses à partir de sa mémoire (RFC 8020 et RFC 8198),
  • avoir une copie locale de la racine, privant les serveurs racine d'informations (RFC 8806).

[Sur mon résolveur DoH/DoT, le vrai résolveur qui tourne derrière, un Unbound, a les options harden-below-nxdomain et aggressive-nsec, qui mettent à peu près en œuvre les RFC 8020 et RFC 8198.] On peut aussi imaginer un résolveur qui envoie des requêtes bidon, pour brouiller les informations connues du serveur faisant autorité, ou, moins méchamment, qui demande en avance (avant l'expiration du TTL) des données qui sont dans sa mémoire, sans attendre une requête explicite d'un de ses clients, pour casser la corrélation entre un client et une requête. Pour l'instant, il n'existe pas de recommandations consensuelles sur ces techniques. Enfin, un résolveur peut aussi faire suivre toutes ses requêtes à un résolveur plus gros (forwarder), au-dessus d'un lien sécurisé. Cela a l'avantage que le gros résolveur, ayant une mémoire plus importante, enverra moins de données aux serveurs faisant autorité, et que sa base de clients plus large rendra plus difficile la corrélation. Évidemment, dans ce cas, le danger peut venir du gros résolveur à qui on fait tout suivre, et le choix final n'est donc pas évident du tout. [Mon résolveur ne fait pas suivre à un gros résolveur public, aucun ne me semblant satisfaisant. Comme il a peu de clients, cela veut dire que les données envoyées aux serveurs faisant autorité peuvent être un problème, question vie privée.]

Une fois que cette section 5 du RFC a exposé tous les risques et les solutions possibles, la section 6 parle de la RPS, Recursive operator Privacy Statement, la déclaration officielle des gérants d'un résolveur à ses clients, exposant ce qu'ils ou elles font, et ce qu'elles ou ils ne font pas avec les données. (Au début du développement de ce RFC, la RPS se nommait DROP - DNS Recursive Operator Privacy statement, ce qui était plus drôle.) Notre RFC recommande très fortement que les opérateurs d'un résolveur DNS publient une RPS, l'exposition de leur politique. Le but étant de permettre aux utilisateurs humains de choisir en toute connaissance de cause un résolveur ayant une politique qu'ils acceptent. Évidemment, il y a des limites à cette idée. D'abord, les utilisateurs ne lisent pas forcément les conditions d'utilisation / codes de conduite et autres textes longs et incompréhensibles. (Le RFC propose des recommandations sur la rédaction des RPS, justement pour diminuer ce problème, en facilitant les comparaisons.) [Mon résolveur a une RPS publique, accessible en https://doh.bortzmeyer.fr/policy. Rédigée bien avant la publication de ce RFC, elle y est pourtant relativement conforme.]

Le RFC propose un plan pour la RPS. Rien n'est évidemment obligatoire dans ce plan, mais c'est une utile liste pour vérifier qu'on n'a rien oublié. Le but est de faire une RPS utilisable, et lisible, et le plan ne couvre pas donc d'éventuelles questions financières (si le service est payant), et ne prétend pas être un document juridique rigoureux, puisqu'elle doit pouvoir être lue et comprise.

Parmi les points à considérer quand on écrit une RPS :

  • Le statut des adresses IP : bien préciser qu'elles sont des données personnelles,
  • le devenir des données : collectées ou non, si elles sont collectées, partagées ou non, gardées combien de temps,
  • si les données sont « anonymisées », une description détaillée du processus d'anonymisation (on a vu que la seule proclamation « les données sont anonymisées », sans détail, était un signal d'alarme, indiquant que l'opérateur se moque de vous),
  • les exceptions, car toute règle doit permettre des exceptions, par exemple face à une attaque en cours, qui peut nécessiter de scruter avec tcpdump, même si on se l'interdit normalement,
  • les détails sur l'organisation qui gère le résolveur, ses partenaires et ses sources de financement,
  • et l'éventuel filtrage des résultats (« DNS menteur ») : a-t-il lieu, motifs de filtrage (noms utilisés pour la distribution de logiciel malveillant, par exemple), loi applicable (« nous sommes enregistrés en France donc nous sommes obligés de suivre les lois françaises »), mécanismes de décision internes (« nous utilisons les sources X et Y de noms à bloquer »)…

L'opérateur du résolveur qui veut bien faire doit également communiquer à ses utilisateurs :

  • Les écarts par rapport à la politique affichée, s'il a fallu en urgence dévier des principes,
  • les détails techniques de la connexion (est-ce qu'on accepte seulement DoH, seulement DoT, ou les deux, par exemple), et des services (est-ce qu'on valide avec DNSSEC ?),
  • les détails de l'authentification du résolveur : nom à valider, clé publique le cas échéant.

Un autre problème avec ces RPS est évidemment le risque de mensonge. « Votre vie privée est importante », « Nous nous engageons à ne jamais transmettre vos données à qui que ce soit », il serait très naïf de prendre ces déclarations pour argent comptant. Le RFC est réaliste et sa section 6.2 du RFC parle des mécanismes qui peuvent permettre, dans le cas idéal, d'augmenter légèrement les chances que la politique affichée soit respectée. Par exemple, on peut produire des transparency reports où on documente ce qu'on a été forcés de faire (« en raison d'une injonction judiciaire, j'ai dû ajouter une règle pour bloquer machin.example »). Des vérifications techniques peuvent être faites de l'extérieur, comme l'uptime, le remplissage ou la minimisation des requêtes. De tels outils existent pour la qualité TLS des serveurs, comme SSLlabs.com, déjà cité, ou Internet.nl. [Opinion personnelle : beaucoup de tests d'Internet.nl ne sont pas pertinents pour DoH.] Plus fort, on peut recourir à des audits externes, qui augmentent normalement la confiance qu'on accorde à la RPS, puisqu'un auditeur indépendant aura vérifié sa mise en œuvre. [Mon avis est que c'est d'une fiabilité limitée, puisque l'auditeur est choisi et payé par l'organisation qui se fait auditer… Et puis, même si vous êtes root sur les machines de l'organisation auditée, ce qui n'arrive jamais, s'assurer que, par exemple, les données sont bien détruites au bout du temps prescrit est non-trivial.] Cloudflare est ainsi audité (par KPMG) et vous pouvez lire le premier rapport (très court et sans aucun détail sur le processus de vérification).

L'annexe A du RFC liste les documents, notamment les RFC, qui sont pertinents pour les opérateurs de résolveurs promettant le respect de la vie privée. On y trouve les normes techniques sur les solutions améliorant la protection de l'intimité, mais aussi celles décrivant les solutions qui peuvent diminuer la vie privée, comme ECS (RFC 7871), les cookies DNS (RFC 7873), la reprise de sessions TLS (RFC 5077, un format pour stocker des données sur le trafic DNS (RFC 8618, mais il y a aussi le traditionnel pcap), le passive DNS (RFC 8499), etc.

L'annexe C du RFC cite une intéressante comparaison, faite en 2019, de diverses RPS (Recursive operator Privacy Statement, les politiques des gérants de résolveurs). Comme ces RPS sont très différentes par la forme, une comparaison est difficile. Certaines font plusieurs pages, ce qui les rend longues à analyser. Aujourd'hui, en l'absence de cadres et d'outils pour éplucher ces RPS, une comparaison sérieuse par les utilisateurs n'est pas réaliste. Quelques exemples réels : la RPS de mon résolveur (la seule en français), celle de PowerDNS, celle de Quad9, celle de CloudflareMozilla a développé, pour son programme TRR (Trusted Recursive Resolve), une liste de critères que les résolveurs qui veulent rejoindre le programme doivent respecter. Une sorte de méta-RPS. [Apparemment, le seul truc qui me manque est le transparency report annuel.]

L'annexe D du RFC contient un exemple de RPS. Elle ne prétend pas être parfaite, et il ne faudrait surtout pas la copier/coller directement dans une vraie RPS mais elle peut servir de source d'inspiration. Notez également qu'elle est écrite en anglais, ce qui ne conviendra pas forcément à un service non-étatsunien. Parmi les points que j'ai notés dans cette RPS (rappelez-vous qu'il s'agit juste d'un exemple et vous n'avez pas à l'utiliser telle quelle) :

  • L'engagement à ne pas conserver les données en mémoire stable utilise un terme technique (does not have data logged to disk) pour parler d'un type de support stable particulier, ce qui peut encourager des trucs comme d'enregistrer sur un support stable qui ne soit pas un disque.
  • Cette déclaration liste la totalité des champs de la requête DNS qui sont enregistrés. L'adresse IP n'y est pas (remplacée par des données plus générales comme le préfixe annoncé dans BGP au moment de l'analyse).
  • La RPS s'engage à ne pas partager ces données. Mais des extraits ou des agrégations des données peuvent l'être.
  • Des exceptions sont prévues, permettant aux administrateurs de regarder les données de plus près en cas de suspicion de comportement malveillant.
  • Le résolveur est un résolveur menteur, bloquant la résolution des noms utilisés pour des activités malveillantes (C&C d'un botnet, par exemple). Hypocritement, la RPS d'exemple affirme ensuite ne pas faire de censure.
  • La RPS promet que l'ECS ne sera pas envoyé aux serveurs faisant autorité.

On a dit plus haut que l'« anonymisation » d'adresses IP était un art très difficile. L'annexe B de notre RFC fait le point sur les techniques existantes, leurs avantages et inconvénients. C'est une lecture très recommandée pour ceux et celles qui veulent réellement « anonymiser », pas juste en parler. Un tableau résume ces techniques, leurs forces et leurs faiblesses. Le problème est de dégrader les données suffisamment pour qu'on ne puisse plus identifier l'utilisateur, tout en gardant assez d'informations pour réaliser des analyses. À bien des égards, c'est la quadrature du cercle.

Pour mettre de l'ordre dans les techniques d'« anonymisation », le RFC commence par lister les propriétés possibles des techniques (cf. RFC 6235). Il y a entre autres :

  • Maintien du format : la donnée « anonymisée » a la même syntaxe que la donnée originale. Ainsi, ne garder que les 64 premiers bits d'une adresse IP et mettre les autres à zéro préserve le format (2001:db8:1:cafe:fafa:42:1:b53 devient 2001:db8:1:cafe::, qui est toujours une adresse IP). Par contre, condenser ne garde pas le format (le condensat SHA-256 de cette adresse deviendrait 98a09452f58ffeba29e7ca06978b3d65e104308a7a7f48b0399d6e33c391f663).
  • Maintien du préfixe : l'adresse « anonymisée » garde un préfixe (qui n'est pas forcément le préfixe original, mais qui est cohérent pour toutes les adresses partageant ce préfixe). Cela peut être utile pour les adresses IP mais aussi pour les adresses MAC, où le préfixe identifie le fabricant.

Pour atteindre nos objectifs, on a beaucoup de solutions (pas forcément incompatibles) :

  • Généralisation : sans doute l'une des méthodes les plus efficaces, car elle réduit réellement la quantité d'information disponible. C'est réduire la précision d'une estampille temporelle (par exemple ne garder que l'heure et oublier minutes et secondes), approximer une position (en ne gardant qu'un carré de N kilomètres de côté), remplacer tous les ports TCP et UDP par un booléen indiquant simplement s'ils sont supérieurs ou inférieurs à 1 024, etc.
  • Permutation : remplacer chaque identificateur par un autre, par exemple via un condensat cryptographique.
  • Filtrage : supprimer une partie des données, par exemple, dans une requête DNS, ne garder que le nom demandé.
  • Et bien d'autres encore.

L'annexe B rentre ensuite dans les détails en examinant plusieurs techniques documentées (rappelez-vous que les responsables des données sont souvent très vagues, se contentant d'agiter les mains en disant « c'est anonymisé avec des techniques très avancées »). Par exemple, Google Analytics permet aux webmestres de demander à généraliser les adresses IP en mettant à zéro une partie des bits. Comme le note le RFC, cette méthode est très contestable, car elle garde bien trop de bits (24 en IPv4 et 48 en IPv6).

Plusieurs des techniques listées ont une mise en œuvre dans du logiciel publiquement accessible, mais je n'ai pas toujours réussi à tester. Pour dnswasher, il faut apparemment compiler tout PowerDNS. Une fois que c'est fait, dnswasher nous dit ce qu'il sait faire :

% ./dnswasher -h
Syntax: dnswasher INFILE1 [INFILE2..] OUTFILE
Allowed options:
  -h [ --help ]           produce help message
  --version               show version number
  -k [ --key ] arg        base64 encoded 128 bit key for ipcipher
  -p [ --passphrase ] arg passphrase for ipcipher (will be used to derive key)
  -d [ --decrypt ]        decrypt IP addresses with ipcipher
  

dnswasher remplace chaque adresse IP dans un fichier pcap par une autre adresse, attribuée dans l'ordre. C'est de la pseudonymisation (chaque adresse correspond à un pseudonyme et un seul), le trafic d'une adresse suffit en général à l'identifier, par ses centres d'intérêt. Traitons un pcap de requêtes DNS avec ce logiciel :

% ./dnswasher ~/tmp/dns.pcap ~/tmp/anon.pcap
Saw 18 correct packets, 1 runts, 0 oversize, 0 unknown encaps

% tcpdump -n -r ~/tmp/anon.pcap
15:28:49.674322 IP 1.0.0.0.41041 > 213.251.128.136.53: 51257 [1au] SOA? toto.fr. (36)
  

L'adresse 1.0.0.0 n'est pas la vraie, c'est le résultat du remplacement fait par dnswasher. En revanche, 213.251.128.136 est la vraie adresse. dnswasher ne remplace pas les adresses quand le port est 53, considérant que les serveurs n'ont pas de vie privée, contrairement aux clients.

Dans l'exemple ci-dessus, on n'avait pas utilisé de clé de chiffrement, et dnswasher remplace les adresses IP avec 1.0.0.0, 1.0.0.1, etc. En rajoutant l'option -p toto où toto est notre clé (simpliste) :

15:28:49.674322 IP 248.71.56.220.41041 > 213.251.128.136.53: 51257 [1au] SOA? toto.fr. (36)

L'adresse est remplacée par une adresse imprévisible, ici 248.71.56.220. Cela marche aussi en IPv6 :

15:28:49.672925 IP6 b4a:7e80:52fe:4003:6116:fcb8:4e5a:b334.52346 > 2001:41d0:209::1.53: 37568 [1au] SOA? toto.fr. (36)
  

(Une adresse comme b4a:7e80:52fe:4003:6116:fcb8:4e5a:b334.52346 ne figure pas encore dans les plages d'adresses attribuées.)

TCPdpriv, lui, préserve le préfixe des adresses IP. À noter qu'il n'est pas déterministe : les valeurs de remplacement seront différentes à chaque exécution.

On peut aussi chiffrer l'adresse IP, en utilisant une clé qu'on garde secrète. Cela a l'avantage qu'un attaquant ne peut pas simplement faire tourner l'algorithme sur toutes les adresses IP possibles, comme il le peut si on utilise une simple condensation. C'est ce que fait Crypto-PAn.

Comme chaque logiciel a sa propre façon de remplacer les adresses IP, cela peut rendre difficile l'échange de données et le travail en commun. D'où le projet ipcipher. Ce n'est pas du code, mais une spécification (avec des pointeurs vers des logiciels qui mettent en œuvre cette spécification). Au passage, je vous recommande cet article à ce sujet. La spécification ipcipher peut être mise en œuvre, par exemple, avec le programme ipcrypt, qui traite des fichiers texte au format CSV :

% cat test2.csv
foo,127.0.0.1
bar,9.9.9.9
baz,204.62.14.153
sha,9.9.9.9

% ./ipcrypt test2.csv 1 e
foo,118.234.188.6
bar,142.118.72.81
baz,235.237.54.9
sha,142.118.72.81
  

Notez le déterminisme : 9.9.9.9 est toujours remplacé par la même adresse IP.

Enfin, des structures de données rigolotes peuvent fournir d'autres services. C'est ainsi que les filtres de Bloom peuvent permettre de savoir si une requête a été faite, mais sans pouvoir trouver la liste des requêtes. Un exemple d'application aux données DNS est l'article « Privacy-Conscious Threat Intelligence Using DNSBLOOM ».


Téléchargez le RFC 8932


L'article seul

RFC 8914: Extended DNS Errors

Date de publication du RFC : Octobre 2020
Auteur(s) du RFC : W. Kumari (Google), E. Hunt (ISC), R. Arends (ICANN), W. Hardaker (USC/ISI), D. Lawrence (Oracle + Dyn)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 24 octobre 2020


Un problème classique du DNS est qu'il n'y a pas assez de choix pour le code de retour renvoyé par un serveur DNS. Contrairement à la richesse des codes de retour HTTP, le DNS est très limité. Ainsi, le code de retour SERVFAIL (SERver FAILure) sert à peu près à tout, et indique des erreurs très différentes entre elles. D'où ce nouveau RFC qui normalise un mécanisme permettant des codes d'erreur étendus, ce qui facilitera le diagnostic des problèmes DNS.

Ces codes de retour DNS (RCODE, pour Response CODE) sont décrits dans le RFC 1035, section 4.1.1. Voici un exemple de requête faite avec dig. Le code de retour est indiqué par l'étiquette status:. Ici, c'est REFUSED, indiquant que le serveur faisant autorité pour google.com ne veut pas répondre aux requêtes pour mon .org :


% dig @ns1.google.com AAAA www.bortzmeyer.org 

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> @ns1.google.com AAAA www.bortzmeyer.org
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 4181
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
;; QUESTION SECTION:
;www.bortzmeyer.org.	IN AAAA

;; Query time: 7 msec
;; SERVER: 2001:4860:4802:32::a#53(2001:4860:4802:32::a)
;; WHEN: Sat Jun 20 11:07:13 CEST 2020
;; MSG SIZE  rcvd: 47

  

Codés sur seulement quatre bits, ces codes de retour ne peuvent pas être très nombreux. Le RFC 1035 en normalisait six, et quelques autres ont été ajoutés par la suite, mais sont rarement vus sur le terrain. En pratique, les plus fréquents sont NOERROR (pas de problème), NXDOMAIN (ce nom de domaine n'existe pas) et SERVFAIL (la plupart des autres erreurs). Notez que le RFC 1034 n'utilisait pas ces sigles à l'origine ils ont été introduits après.

On l'a dit, ces codes de retour sont insuffisants. Lorsqu'un client DNS reçoit SERVFAIL, il doit essayer de deviner ce que cela voulait dire. Lorsqu'on parle à un résolveur, le SERVFAIL indique-t-il un problème de validation DNSSEC ? Ou bien que les serveurs faisant autorité sont injoignables ? Lorsqu'on parle à un serveur faisant autorité, le SERVFAIL indiquait-il que ce serveur n'avait pas pu charger sa zone (peut-être parce que le serveur maître était injoignable) ? Ou bien un autre problème ?

L'un des scénarios de déboguage les plus communs est celui de DNSSEC. Au moins, il existe un truc simple : refaire la requête avec le bit CD (Checking Disabled). Si ça marche (NOERROR), alors on est raisonnablement sûr que le problème était un problème DNSSEC. Mais cela ne nous dit pas lequel (signatures expirées ? clés ne correspondant pas à la délégation ?). DNSSEC est donc un des principaux demandeurs d'erreurs plus détaillées.

Alors, après cette introduction (section 1 du RFC), la solution (section 2). Les erreurs étendues sont transportées via une option EDNS (RFC 6891) dans la réponse. Cette option comporte un type (numéro 15) et une longueur (comme toutes les options EDNS) suivis d'un code d'information (sur deux octets) et de texte libre, non structuré (en UTF-8, cf. RFC 5198, et attention à ne pas le faire trop long, pour éviter la troncation DNS). Les codes d'information possibles sont dans un registre à l'IANA. En ajouter est simple, par la procédure « Premier Arrivé, Premier Servi » du RFC 8126. Cette option EDNS peut être envoyée par le serveur DNS, quel que soit le code de retour (y compris donc NOERROR). Il peut y avoir plusieurs de ces options. La seule condition est que la requête indiquait qu'EDNS est accepté par le client. Le client n'a pas à demander explicitement des erreurs étendues et ne peut pas forcer l'envoi d'une erreur étendue, cela dépend uniquement du serveur.

Les codes d'information initiaux figurent en section 4 du RFC. Le RFC ne précise pas avec quels codes de retour les utiliser (ce fut une grosse discussion à l'IETF…) mais, évidemment, certains codes d'erreur étendus n'ont de sens qu'avec certains codes de retour, je les indiquerai ici. Voici quelques codes d'erreur étendus :

  • 0 indique un cas non prévu, le texte qui l'accompagne donnera des explications.
  • 1 signale que le domaine était signé, mais avec uniquement des algorithmes inconnus du résolveur. Il est typiquement en accompagnement d'un NOERROR pour expliquer pourquoi on n'a pas validé (en DNSSEC, un domaine signé avec des algorithmes inconnus est considéré comme non signé).
  • 3 (ou 19, pour le NXDOMAIN) indique une réponse rassise (RFC 8767). Voir aussi le 22, plus loin.
  • 4 est une réponse fabriquée de toutes pièces par un résolveur menteur. Notez qu'il existe d'autres codes, plus loin, de 15 à 17, permettant de détailler les cas de filtrage. 4 est typiquement en accompagnement d'un NOERROR puisqu'il y a une réponse.
  • 6 vient avec les SERVFAIL pour indiquer que la validation DNSSEC a déterminé un problème (signature invalide ou absente). Plusieurs autres codes traitent des problèmes DNSSEC plus spécifiques.
  • 7 vient également avec SERVFAIL pour le cas des signatures expirées (sans doute un des problèmes DNSSEC les plus fréquents).
  • Trois codes viennent pour les cas où le résolveur refuse de répondre pour ce domaine, et le dit (au lieu, ou en plus, de fabriquer une réponse mensongère). Ce sont 15 (réponse bloquée par une décision de l'administrateur du résolveur), 16 (réponse bloquée par une décision extérieure, typiquement l'État, et il ne sert donc à rien de se plaindre à l'administrateur du résolveur, c'est de la censure) et 17 (réponse bloquée car le client a demandé qu'on filtre pour lui, par exemple parce qu'il a choisi de bloquer les domaines liés à la publicité). 16 est donc à peu près l'équivalent du 451 de HTTP, normalisé dans le RFC 7725. Gageons que les résolveurs menteurs en France se garderont bien de l'utiliser…
  • 18 accompagne en général REFUSED et indique au client qu'il n'est pas le bienvenu (par exemple une requête à un résolveur venue de l'extérieur du réseau local).
  • 22 indique qu'un résolveur n'a pas pu joindre aucun des serveurs faisant autorité. Ce code peut accompagner une réponse rassise ou bien un SERVFAIL. J'en profite pour vous rappeler que, si vous gérez une zone DNS, attention à sa robustesse : évitez les SPOF. Ayez plusieurs serveurs faisant autorité, et dans des lieux séparés (et de préférence dans des AS distincts).

Le client DNS qui reçoit un code d'erreur étendu est libre de l'utiliser comme il le souhaite (les précédentes versions de ce mécanisme prévoyaient des suggestions faites au client mais ce n'est plus le cas). Le but principal de cette technique est de fournir des informations utiles pour le diagnostic. (Une discussion à l'IETF avait porté sur des codes indiquant précisément si le problème était local - et devait donc être soumis à son administrateur système - ou distant, auquel cas il n'y avait plus qu'à pleurer, mais cela n'a pas été retenu. Notez que la différence entre les codes 15 et 16 vient de là, du souci d'indiquer à qui se plaindre.)

Attention à la section 6 du RFC, sur la sécurité. Elle note d'abord que certains clients, quand ils reçoivent un SERVFAIL, essaient un autre résolveur (ce qui n'est pas une bonne idée si le SERVFAIL était dû à un problème DNSSEC). Ensuite, les codes d'erreur étendus ne sont pas authentifiés (comme, d'ailleurs, les codes de retour DNS habituels), sauf si on utilise, pour parler au serveur, un canal sécurisé comme DoT (RFC 7858) ou DoH (RFC 8484). Il ne faut donc pas s'y fier trop aveuglément. Enfin, ces codes étendus vont fuiter de l'information à un éventuel observateur (sauf si on utilise un canal chiffré, comme avec DoT ou DoH) ; par exemple, 18 permet de savoir que vous n'êtes pas le bienvenu sur le serveur.

Et, désolé, je ne connais pas de mise en œuvre de cette option à l'heure actuelle. J'avais développé le code nécessaire pour Knot lors du hackathon de l'IETF à Prague en mars 2019 (le format a changé depuis donc ce code ne peut pas être utilisé tel quel). La principale difficulté n'était pas dans le formatage de la réponse, qui est trivial, mais dans le transport de l'information, depuis les entrailles du résolveur où le problème était détecté, jusqu'au code qui fabriquait la réponse. Il fallait de nouvelles structures de données, plus riches.

Sinon, le RFC mentionne le groupe Infected Mushroom. Si vous voulez voir leurs clips


Téléchargez le RFC 8914


L'article seul

RFC 8884: Research Directions for Using Information-Centric Networking (ICN) in Disaster Scenarios

Date de publication du RFC : Octobre 2020
Auteur(s) du RFC : J. Seedorf (HFT Stuttgart - Univ. of Applied Sciences), M. Arumaithurai (University of Goettingen), A. Tagami (KDDI Research), K. Ramakrishnan (University of California), N. Blefari Melazzi (University Tor Vergata)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF icnrg
Première rédaction de cet article le 24 octobre 2020


Si vous aimez les films catastrophe, voici un RFC pour vous ; il explore l'utilisation de l'ICN lors de grands désastres. N'espérez pas trouver de solutions, c'est un travail purement théorique. (Comme beaucoup de choses qui touchent à l'ICN.)

L'ICN (Information Centric Networking) ? C'est quoi ? Il s'agit d'une approche des réseaux informatiques où tout est vu comme du contenu, auquel les clients veulent accéder. Les routeurs ICN vont donc se charger de récupérer l'information, sans se soucier d'où elle vient. L'ICN est décrit dans des documents comme le RFC 7476 et le RFC 7927.

Parmi tous les RFC, il n'y a pas que l'ICN qui peut apporter des idées neuves en matière de robustesse lors de grandes catastrophes. Le DTN (RFC 5050), réseau acceptant les déconnexions fréquentes, est également une bonne approche. En effet, en cas de désastre, il est sûr que le réseau sera affecté, et le concept « stocke et réessaie » de DTN est donc un outil utile. Mais ICN offre des possibilités supplémentaires. D'ailleurs, le RFC 7476 (section 2.7.2) citait déjà cette possibilité d'utiliser l'ICN en cas de catastrophe. L'idée est que la couche réseau peut aider à partiellement contourner les problèmes post-catastrophe. Les applications ont leur rôle à jouer également, bien sûr, mais ce n'est pas l'objet de ce RFC.

La section 2 du RFC liste des cas d'usage. Comme déjà le RFC 7476, on commence par le tremblement de terre de Tohoku, qui avait détruit une partie importante de l'infrastructure, notamment en ce qui concerne la fourniture d'électricité. Or, après une telle catastrophe, il y a une grosse demande de communication. Les autorités veulent envoyer des messages (par exemple par diffusion sur les réseaux de téléphonie mobile), transmettre des informations, distribuer des consignes. Les habitants veulent donner des nouvelles à leurs proches, ou bien en recevoir. Les victimes veulent savoir où se trouvent les secours, les points de ravitaillement, etc.

Les gens de l'ICN étant toujours à la recherche de subventions, ils citent fréquemment les thèmes à la mode, qui promettent l'attention des pouvoirs publics. C'est ainsi que la liste des cas d'usage inclus évidemment le terrorisme (pourquoi pas la cyberguerre, tant qu'on y est ?). Dans ce cas, des difficultés supplémentaires surviennent : les attaquants peuvent effectuer des attaques par déni de service pour empêcher l'utilisation du réseau, si l'attaque elle-même ne l'a pas arrêté, ils peuvent surveiller l'utilisation du réseau pour, par exemple, découvrir des cibles intéressantes pour une nouvelle attaque, ils peuvent envoyer des messages mensongers pour créer une panique, etc. Le problème est donc plus difficile que celui d'une catastrophe naturelle.

Aujourd'hui, les réseaux existants ne permettent pas forcément de traiter les cas de catastrophes, même « simplement » naturelles. La section 3 du RFC liste les principaux défis qu'il faudrait traiter pour cela :

  • On s'attend à ce que le réseau soit fragmenté par la catastrophe. Certains composants seront alors inaccessibles. Pensez à l'accès aux serveurs DNS racine si on est dans un îlot où il n'existe aucune instance de ces serveurs. Tous les systèmes centralisés seront inutilisables si on est du mauvais côté de la coupure. Par exemple, les systèmes de téléphonie mobile existants dépendent souvent de composants centraux comme le HLR. Un réseau utilisable pendant les catastrophes doit donc pouvoir fonctionner même en cas de fragmentation.
  • Un service qui est très souvent centralisé est celui de l'authentification. Même quand le système peut marcher en pair-à-pair, la possibilité de l'utiliser dépend souvent d'une authentification centrale. Même quand il y a décentralisation, comme avec une PKI, il peut être nécessaire de passer d'abord par une ou plusieurs racines, qui peuvent être injoignables pendant la catastrophe. Créer un système d'authentification décentralisé est un sacré défi. Le RFC note que la chaîne de blocs n'est pas une solution, puisque celle-ci ne fonctionne plus s'il y a fragmentation (ou, plus exactement, chaque groupe de participants risque de voir sa portion de la chaîne invalidée lorsque le réseau sera à nouveau complètement connecté).
  • En cas de catastrophe, il sera peut-être nécessaire de donner une priorité à certains messages, ceux liés à la coordination des secours, par exemple. C'est d'autant plus important à réaliser que la capacité du réseau sera réduite et que les arbitrages seront donc difficiles.
  • Dans un réseau sérieusement endommagé, où la connectivité risque fort d'être intermittente, il ne sera pas toujours possible d'établir une liaison de bout en bout. Il faudra, beaucoup plus qu'avec l'Internet actuel, compter sur le relayage de machine en machine, avec stockage temporaire lorsque la machine suivante n'est pas joignable. C'est justement là où DTN est utile.
  • Enfin, dans la situation difficile où se trouveront tous les participants, l'énergie sera un gros problème ; peu ou pas de courant électrique, pas assez de fuel pour les groupes électrogènes, et des batteries qui se vident vite (comme dans le film Tunnel, où le héros doit surveiller en permanence la batterie de son ordiphone, et économiser chaque joule).

Bon, ça, ce sont les problèmes. Maintenant, en quoi est-ce que l'ICN peut aider ? Plusieurs arguments sont avancés par le RFC (dont certains, à mon avis, plus faibles que d'autres) :

  • L'ICN, c'est une de ses principales caractéristiques, route en fonction du nom du contenu convoité, pas en fonction d'une adresse IP. Cela peut permettre, dit le RFC, de survivre lorsque le réseau est coupé. (L'argument me semble douteux : il suppose qu'en cas de fragmentation, le contenu sera présent des deux côtés de la coupure. Mais on peut en dire autant des adresses IP. Contrairement à ce que racontent toujours les promoteurs de l'ICN, il y a bien longtemps que les adresses IP n'ont plus de rapport avec un lieu physique). C'est d'autant plus vrai si le système de résolution des noms est complètement décentralisé. (Là encore, ICN et système classique sont à égalité : l'un et l'autre peuvent utiliser un système centralisé, un système décentralisé, ou un système pair-à-pair pour la résolution de noms).
  • Un point fort de l'ICN est que l'authentification et l'intégrité ne sont pas assurés par la confiance dans le serveur d'où on a obtenu le contenu, mais par une certification portée par l'objet (typiquement une signature). Certains mécanismes de nommage mettent même l'intégrité dans le nom (cf. RFC 6920). Cela permet de récupérer du contenu n'importe où, ce qui est utile si le serveur d'origine est injoignable mais que des copies circulent. On peut ainsi vérifier l'authenticité de ces copies.
  • ICN utilise beaucoup les caches, les mémoires dans lesquelles sont stockées les objets. Avec l'ICN, chaque routeur peut être un cache. Là aussi, cela peut aider beaucoup si le serveur d'origine n'est plus joignable.
  • Et ICN est bien adapté aux techniques à base de DTN (cf. par exemple RFC 5050), où il n'y a pas besoin de connectivité permanente : on transmet simplement le contenu en mode « stocke et fais suivre ».

En parlant de DTN, notons que DTN seul manque de certaines fonctions que pourrait fournir l'ICN. C'est le cas par exemple du publish/subscribe. Dans certains cas, ces fonctions pourraient être ajoutées au DTN, comme présenté dans « Efficient publish/ subscribe-based multicast for opportunistic networking with self-organized resource utilization » (par Greifenberg, J. et D. Kutscher) ou bien « A Socio-Aware Overlay for Publish/Subscribe Communication in Delay Tolerant Networks » (par Yoneki, E., Hui, P., Chan, S., et J. Crowcroft).

La section 4 du RFC précise ensuite les scénarios d'usage, et les exigences qui en découlent. Par exemple, pour le scénario « diffuser de l'information aux gens », la question de l'authentification est cruciale, de fausses informations diffusées par un malveillant ou par un plaisantin pourraient avoir des conséquences graves.

Est-ce que l'ICN peut assurer ces missions, là, aujourd'hui ? Clairement non, et la section 5 du RFC décrit tout ce qu'il reste à faire (rappelez-vous que l'ICN, c'est de la recherche fondamentale). Par exemple, dans le contexte envisagé, celui d'une vraie catastrophe, il est possible que les données doivent être transportées par des « mules », des porteurs physiques (on peut penser au RFC 1149 mais aussi, plus sérieusement, à UUCP où les messages étaient parfois transportés ainsi, notamment dans les pays du Sud). Cette proposition est envisagée dans l'article de Tagami, A., Yagyu, T., Sugiyama, K., Arumaithurai, M., Nakamura, K., Hasegawa, T., Asami, T., et K. Ramakrishnan, « Name-based Push/Pull Message Dissemination for Disaster Message Board ».

Enfin, la section 5 du RFC décrit ce qui reste à faire (l'ICN est aujourd'hui incapable d'assurer les missions décrites au début de ce RFC). La première chose serait d'évaluer en vrai les solutions ICN existantes. Un test à la prochaine catastrophe ?

À noter que le travail ayant mené à ce RFC a été fait en partie dans le cadre du projet GreenICN.


Téléchargez le RFC 8884


L'article seul

Usages de la 5G : est-ce le problème ?

Première rédaction de cet article le 23 octobre 2020


Dans les débats, souvent confus, sur la 5G, on a souvent cité l'argument des usages. D'un côté, on vend du rêve « la 5G va permettre la télémédecine et les voitures connectées, ainsi que la protection des gentilles brebis contre les loups », de l'autre du scepticisme, voire de la négation, « la 5G ne sert à rien, on n'a pas besoin d'une telle capacité, ça ne servira qu'au porno dans l'ascenseur ». A priori, parler des usages plutôt que de la technologie est raisonnable. On déploie une nouvelle infrastructure pour ses usages, pas pour faire plaisir aux techniciens, non ? Cela semble de bon sens mais cela oublie un gros problème : prévoir les usages d'une technologie d'infrastructure n'est pas facile.

En effet, la 5G est une technologie d'infrastructure. L'infrastructure, c'est ce qu'on ne voit pas, ce qui est loin de l'utilisatrice ou de l'utilisateur. Cela peut servir à plusieurs usages très différents. Ainsi, l'infrastructure routière peut servir à aller travailler le matin. (D'accord, pour la biosphère, il vaudrait mieux prendre les transports en commun. Mais ils ont souvent été supprimés dans les régions. Et ne me parlez pas de télétravail, vous croyez qu'un infirmier ou une ouvrière du BTP peuvent télétravailler ?) Mais la même infrastructure peut aussi servir à partir en vacances. Quel que soit le jugement de valeur (« les vacances, ce n'est pas vraiment utile ») qu'on ait sur ces usages, il est important de se rappeler que l'infrastructure ne se limite pas à tel ou tel usage.

Un point important avec l'infrastructure est que, quand on commence à la déployer, on ne connait pas réellement ses usages. Quand on a conçu l'Internet, personne n'envisageait le Web. Quand on a conçu le Web, personne n'envisageait Facebook, Gmail et Wikipédia. Les usages sont peu prévisibles et il ne faut pas forcément compter sur eux pour trancher en faveur ou en défaveur d'une technique d'infrastructure. L'argument de gros bon sens « avant d'investir dans un déploiement d'une infrastructure, il faut se demander si c'est vraiment utile » est trop court, car l'infrastructure (si elle est bien conçue) n'impose pas un usage unique. Faisons une expérience de pensée. Imaginons que, comme certains le proposent pour la 5G, un comité, une commission ou une agence ait été chargée, avant le déploiement de l'Internet, de peser ses usages et de décider si le jeu en valait la chandelle. Ce comité n'aurait pas connu le bon (Wikipédia, Sci-Hub, les appels vocaux à très bas prix entre continents) ou le mauvais (la surveillance massive) de l'Internet. Comment aurait-il pu prendre une bonne décision ?

Et est-il à craindre qu'il n'y ait tout simplement pas ou peu d'usage, que la nouvelle technologie qui a coûté si cher à déployer ne serve finalement à rien ? S'agissant d'une technologie de communication, comme l'Internet, il n'y a pas de risque : l'être humain est très communiquant, et toutes les technologies de communication, depuis l'aube de l'humanité, ont été des grands succès. On pouvait donc parier sans risque de l'Internet en serait un.

Autrefois, certains opérateurs ont pourtant essayé de contrôler les usages. À une époque lointaine, les opérateurs téléphoniques (AT&T et France Télécom, par exemple), avaient essayé d'interdire les modems, considérés comme un détournement du réseau téléphonique. Le même France Télécom, lorsque le RNIS est apparu en France, avait essayé de promouvoir des applications spécifiques au RNIS. (Voyez un exemple d'application liée au réseau dans cet amusant article de 2004.) Et ceci alors que l'Internet promouvait au contraire l'idée d'un réseau neutre, sur lequel de nombreuses applications, pas forcément développées ou encouragées par l'opérateur, seraient possibles. (Notez que les opérateurs issus de la téléphonie classique n'ont jamais vraiment renoncé à ce contrôle. Les ordiphones sont ainsi beaucoup plus fermés que les PC.) Comme le dit Joël Mau « Les infrastructures ne doivent pas être un frein mais un facilitateur ».

Ce « détournement » ou tout simplement, pour parler comme Zittrain, cette générativité, sont des qualités qu'on retrouve dans de nombreuses technologies, et qui permettent l'innovation. Après tout, lorsque Gutenberg a inventé sa presse, il n'avait pas non plus imaginé tous les usages. Et lorsque le Minitel a été conçu, personne ne pensait aux messageries, son grand usage. Ce phénomène est connue en sociologie de l'innovation d'assez longue date : les utilisatrices et utilisateurs ne sont pas des consommateurs passifs d'« usages » décidés d'en haut, elles et ils développent des usages surprenants, qui peuvent influer sur l'innovation. On peut lire par exemple « Les utilisateurs, acteurs de l’innovation », de Madeleine Akrich, qui contient beaucoup d'exemples amusants. Notez que très peu des exemples de cet article concernent le numérique, ce qui indique que cette générativité des techniques, et cette initiative des utilisateurs, ne sont pas une spécificité du monde numérique. (En anglais, on peut aussi citer les travaux d'Eric von Hippel.)

Revenons aux usages et à leur utilisation dans le cadre de controverses socio-techniques. Outre la difficulté à prédire les usages effectifs d'une technologie nouvelle, un des problèmes du « pilotage par les usages » est la question des opinions. Reprenons l'exemple du « porno dans l'ascenseur » cité plus haut. La pornographie est légale en France. Le politicien puritain qui a utilisé cet exemple voulait manifestement pointer que le porno était un « mauvais usage », pas digne qu'on investisse pour lui. On peut imaginer que les défenseurs de l'usage de la pornographie ne vont pas se mettre en avant et l'argument était donc bien calculé pour ne pas être contestable. (Pourtant, on peut noter qu'en période de confinement et de couvre-feu, la frustration sexuelle est un vrai problème, même si le porno n'est pas forcément la solution.) Mais passons du porno à d'autres usages. La diffusion de matches de football en haute définition est-elle utile ? Comme je ne m'intéresse pas du tout au football, ma réponse serait non. D'autres personnes auront un autre avis. On voit bien là l'un des problèmes fondamentaux du « pilotage par les usages » : comment déterminer les usages « légitimes » et selon quels critères ?

En conclusion, et notamment dans le cadre du débat sur la 5G, je pense qu'il faut manier l'argument des usages avec prudence. Lorsque j'entends cet argument, j'ai tout de suite envie de creuser la question avec celui qui le présente :

  • Comment allez-vous prévoir les usages futurs ?
  • Qui va décider de quels usages sont légitimes ou pas ?

[Article réalisé avec la participation de Francesca Musiani].


L'article seul

RFC 8922: A Survey of the Interaction Between Security Protocols and Transport Services

Date de publication du RFC : Octobre 2020
Auteur(s) du RFC : T. Enghardt (TU Berlin), T. Pauly (Apple), C. Perkins (University of Glasgow), K. Rose (Akamai Technologies), C.A. Wood (Cloudflare)
Pour information
Réalisé dans le cadre du groupe de travail IETF taps
Première rédaction de cet article le 22 octobre 2020


Quels sont les services de sécurité fournis par les protocoles de transport existants ? Ce nouveau RFC fait le point et examine ces services de sécurité pour un certain nombre de ces protocoles, comme TLS, QUIC, WireGuard, etc. Cela intéressera tous les gens qui travaillent sur la sécurité de l'Internet.

Ce RFC est issu du groupe de travail IETF TAPS, dont le projet est d'abstraire les services que rend la couche Transport pour permettre davantage d'indépendance entre les applications et les différents protocoles de transport. Vous pouvez en apprendre plus dans les RFC 8095 et RFC 8303.

Parmi les services que fournit la couche Transport aux applications, il y a la sécurité. Ainsi, TCP (si le RFC 5961 a bien été mis en œuvre et si l'attaquant n'est pas sur le chemin) protège assez bien contre les usurpations d'adresses IP. Notez que le RFC utilise le terme de « protocole de transport » pour tout ce qui est en dessous de l'application, et utilisé par elle. Ainsi, TLS est vu comme un protocole de transport, du point de vue de l'application, il fonctionne de la même façon (ouvrir une connexion, envoyer des données, lire des réponses, fermer la connexion), avec en prime les services permis par la cryptographie, comme la confidentialité. TLS est donc vu, à juste titre, comme un protocole d'infrastructure, et qui fait donc partie de ceux étudiés dans le cadre du projet TAPS.

La section 1 du RFC explique d'ailleurs quels protocoles ont été intégrés dans l'étude et pourquoi. L'idée était d'étudier des cas assez différents les uns des autres. Des protocoles très répandus comme SSH (RFC 4251), GRE (avec ses extensions de sécurité du RFC 2890) ou L2TP (RFC 5641) ont ainsi été écartés, pas parce qu'ils sont mauvais mais parce qu'ils fournissent à peu près les mêmes services que des protocoles étudiés (par exemple SSH vs. TLS) et ne nécessitaient donc pas d'étude séparée. Plus animée, au sein du groupe de travail TAPS, avait été la discussion sur des protocoles non-IETF comme WireGuard ou MinimaLT. Ils ne sont pas normalisés (et, souvent, même pas décrits dans une spécification stable), mais ils sont utilisés dans l'Internet, et présentent des particularités suffisamment importantes pour qu'ils soient étudiés ici. En revanche, les protocoles qui ne fournissent que de l'authentification, comme AO (RFC 5925) n'ont pas été pris en compte.

Comme c'est le cas en général dans le projet TAPS, le but est de découvrir et de documenter ce que les protocoles de transport ont en commun, pour faciliter leur choix et leur utilisation par l'application. Par contre, contrairement à d'autres cas d'usage de TAPS, il n'est pas prévu de permettre le choix automatique d'un protocole de sécurité. Pour les autres services, un tel choix automatique se justifie (RFC 8095). Si une application demande juste le service « transport d'octets fiable, j'ai des fichiers à envoyer », lui fournir TCP ou SCTP revient au même, et l'application se moque probablement du protocole choisi. Mais la sécurité est plus compliquée, avec davantage de pièges et de différences subtiles, et il est donc sans doute préférable que l'application choisisse explicitement le protocole.

La section 2 du RFC permet de réviser la terminologie, je vous renvoie à mon article sur le RFC 8303 pour la différence entre fonction (Transport Feature) et service (Transport Service).

Et la section 3 s'attaque aux protocoles eux-mêmes. Elle les classe selon qu'ils protègent n'importe quelle application, une application spécifique, l'application et le transport, ou bien carrément tout le paquet IP. Le RFC note qu'aucune classification n'est parfaite. Notamment, plusieurs protocoles sont séparés en deux parties, un protocole de connexion, permettant par exemple l'échange des clés de session, protocole utilisé essentiellement, voire uniquement, à l'ouverture et à la fermeture de la session, et le protocole de chiffrement qui traite les données transmises. Ces deux protocoles sont plus ou moins intégrés, de la fusion complète (tcpcrypt, RFC 8548) à la séparation complète (IPsec, où ESP, décrit dans le RFC 4303, ne fait que chiffrer, les clés pouvant être fournies par IKE, spécifié dans le RFC 7296, ou par une autre méthode). Par exemple, TLS décrit ces deux protocoles séparement (RFC 8446) mais on les considérait comme liés… jusqu'à ce que QUIC décide de n'utiliser qu'un seul des deux.

Bon, assez d'avertissements, passons à la première catégorie, les protocoles qui fournissent une protection générique aux applications. Ils ne protègent donc pas contre des attaques affectant la couche 4 comme les faux paquets RST. Le plus connu de ces protocoles est évidemment TLS (RFC 8446). Mais il y a aussi DTLS (RFC 6347).

Ensuite, il y a les protocoles spécifiques à une application. C'est par exemple le cas de SRTP (RFC 3711), extension sécurisée de RTP qui s'appuie sur DTLS.

Puis il y a la catégorie des protocoles qui protègent le transport ce qui, par exemple, protège contre les faux RST (ReSeT), et empêche un observateur de voir certains aspects de la connexion. C'est le cas notamment de QUIC, normalisé depuis. QUIC utilise TLS pour obtenir les clés, qui sont ensuite utilisées par un protocole sans lien avec TLS, et qui chiffre y compris la couche Transport. Notons que le prédécesseur de QUIC, développé par Google sous le même nom (le RFC nomme cet ancien protocole gQUIC pour le distinguer du QUIC normalisé), n'utilisait pas TLS.

Toujours dans la catégorie des protocoles qui protègent les couches Transport et Application, tcpcrypt (RFC 8548). Il fait du chiffrement « opportuniste » (au sens de « sans authentification ») et est donc vulnérable aux attaques actives. Mais il a l'avantage de chiffrer sans participation de l'application, contrairement à TLS. Bon, en pratique, il n'a connu quasiment aucun déploiement.

Il y a aussi MinimaLT, qui intègre l'équivalent de TCP et l'équivalent de TLS (comme le fait QUIC).

Le RFC mentionne également CurveCP, qui fusionne également transport et chiffrement. Comme QUIC ou MinimaLT, il ne permet pas de connexions non-sécurisées.

Et enfin il y a les protocoles qui protègent tout, même IP. Le plus connu est évidemment IPsec (RFC 4303 et aussi RFC 7296, pour l'échange de clés, qui est un protocole complètement séparé). Mais il y a aussi WireGuard qui est nettement moins riche (pas d'agilité cryptographique, par exemple, ni même de négociation des paramètres cryptographiques ; ce n'est pas un problème pour des tunnels statiques mais c'est ennuyeux pour un usage plus général sur l'Internet). Et il y a OpenVPN, qui est sans doute le plus répandu chez les utilisateurs ordinaires, pour sa simplicité de mise en œuvre. On trouve par exemple OpenVPN dans tous des systèmes comme OpenWrt et donc dans tous les routeurs qui l'utilisent.

Une fois cette liste de protocoles « intéressants » établie, notre RFC va se mettre à les classer, selon divers critères. Le premier (section 4 du RFC) : est-ce que le protocole dépend d'un transport sous-jacent, qui fournit des propriétés de fiabilité et d'ordre des données (si oui, ce transport sera en général TCP) ? C'est le cas de TLS, bien sûr, mais aussi, d'une certaine façon, de tcpcrypt (qui dépend de TCP et surtout de son option ENO, normalisée dans le RFC 8547). Tous les autres protocoles peuvent fonctionner directement sur IP mais, en général, ils s'appuient plutôt sur UDP, pour réussir à passer les différentes middleboxes qui bloquent les protocoles de transport « alternatifs ».

Et l'interface avec les applications ? Comment ces différents protocoles se présentent-ils aux applications qui les utilisent ? Il y a ici beaucoup à dire (le RFC fournit un tableau synthétique de quelles possibilités et quels choix chaque protocole fournit aux applications). L'analyse est découpée en plusieurs parties (les services liés à l'établissement de la connexion, ceux accessibles pendant la session et ceux liés à la terminaison de la connexion), chaque partie listant plusieurs services. Pour chaque service, le RFC dresse la liste des différents protocoles qui le fournissent. Ainsi, la partie sur l'établissement de connexion indique entre autres le service « Extensions au protocole de base accessibles à l'application ». Ce service est fourni par TLS (via ALPN, RFC 7301) ou QUIC mais pas par IPsec ou CurveCP. De même le service « Délégation de l'authentification » peut être fourni par IPsec (par exemple via EAP, RFC 3748) ou tcpcrypt mais pas par les autres.

La section 7 rappelle que ce RFC ne fait qu'analyser les protocoles existants, il ne propose pas de changement. D'autre part, cette section note que certaines attaques ont été laissées de côté (comme celle par canal secondaire ou comme l'analyse de trafic).

La section 8 sur la vie privée rappelle ces faiblesses ; même si l'un des buts principaux du chiffrement est d'assurer la confidentialité, la plupart des protocoles présentés laissent encore fuiter une certaine quantité d'information, par exemple les certificats en clair de TLS (avant la version 1.3).


Téléchargez le RFC 8922


L'article seul

RFC 8923: A Minimal Set of Transport Services for End Systems

Date de publication du RFC : Octobre 2020
Auteur(s) du RFC : M. Welzl, S. Gjessing (University of Oslo)
Pour information
Réalisé dans le cadre du groupe de travail IETF taps
Première rédaction de cet article le 22 octobre 2020


Ce nouveau RFC s'incrit dans le travail en cours à l'IETF pour formaliser un peu plus les services que la couche transport offre aux applications. Le RFC 8095 décrivait tous les services possibles. Ce nouveau RFC 8923 liste les services minimums, ceux à offrir dans presque tous les cas.

Comme le note le RFC 8095, les applications tournant sur la famille de protocoles TCP/IP ne peuvent en général pas aujourd'hui exprimer les services attendus de la couche transport. Elles doivent choisir un protocole de transport (comme TCP ou UDP), même si ce protocole ne convient pas tout à fait. Toute l'idée derrière le travail du groupe TAPS de l'IETF est de permettre au contraire aux applications d'indiquer des services (« je veux un envoi de données fiable et dans l'ordre, avec confidentialité et intégrité ») et que le système d'exploitation choisisse alors la solution la plus adaptée (ici, cela pourrait être TCP ou SCTP avec TLS par dessus, ou bien le futur QUIC). De la même façon qu'un langage de programmation de haut niveau utilise des concepts plus abstraits qu'un langage de bas niveau, on pourrait ainsi avoir une interface de programmation réseau de plus haut niveau que les traditionnelles prises normalisées par Posix. Ce RFC ne normalise pas une telle API, il décrit seulement les services attendus. La liste des services possibles est dans le RFC 8095, et les protocoles qui les fournissent sont documentés dans le RFC 8303 et RFC 8304. Le cœur de notre nouveau RFC 8923 est la section 6, qui liste les services minimum attendus (je vous en dévoile l'essentiel tout de suite : établissement de connexion, fin de connexion, envoi de données, réception de données).

Ce RFC ne spécifie pas une API précise, cela sera éventuellement fait dans un autre document, draft-ietf-taps-interface.

À noter que les services minimums exposés ici peuvent être mis en œuvre sur TCP, et, dans certains cas, sur UDP. TCP offre un ensemble de services qui est quasiment un sur-ensemble de celui d'UDP, donc, sur le seul critère des services, on pourrait n'utiliser que TCP. (Exercice : quelle(s) exception(s) trouvez-vous ?) Comme il s'agit de services de la couche transport aux applications, l'implémentation peut être faite d'un seul côté (il n'est pas nécessaire que les deux partenaires qui communiquent le fassent).

Et, si vous lisez le RFC, faites attention à la section 2 sur la terminologie, section qui reprend le RFC 8303 : une fonction (Transport Feature) est une fonction particulière que le protocole de transport va effectuer, par exemple la confidentialité, la fiabilité de la distribution des données, le découpage des données en messages, etc, un service (Transport Service) est un ensemble cohérent de fonctions, demandé par l'application, et un protocole (Transport Protocol) est une réalisation concrète d'un ou plusieurs services.

Comment définir un jeu minimal de services (section 3 du RFC) ? D'abord, il faut définir les services « sémantiques » (functional features) que l'application doit connaitre. Par exemple, l'application doit savoir si le service « distribution des données dans l'ordre » est disponible ou pas. Et il y a les services qui sont plutôt des optimisations comme l'activation ou la désactivation de DSCP ou comme l'algorithme de Nagle. Si l'application ignore ces services, ce n'est pas trop grave, elle fonctionnera quand même, même si c'est avec des performances sous-optimales.

La méthode utilisée par les auteurs du RFC pour construire la liste des services minimums est donc :

  • Catégorisation des services du RFC 8303 (sémantique, optimisation…) ; le résultat de cette catégorisation figure dans l'annexe A de notre RFC,
  • Réduction aux services qui peuvent être mis en œuvre sur les protocoles de transport qui peuvent passer presque partout, TCP et UDP,
  • Puis établissement de la liste des services minimum.

Ainsi (section 4 du RFC), le service « établir une connexion » peut être mis en œuvre sur TCP de manière triviale, mais aussi sur UDP, en refaisant un équivalent de la triple poignée de mains. Le service « envoyer un message » peut être mis en œuvre sur UDP et TCP (TCP, en prime, assurera sa distribution à l'autre bout, mais ce n'est pas nécessaire). En revanche, le service « envoyer un message avec garantie qu'il soit distribué ou qu'on soit notifié », s'il est simple à faire en TCP, ne l'est pas en UDP (il faudrait refaire tout TCP au dessus d'UDP).

La section 5 du RFC discute de divers problèmes quand on essaie de définir un ensemble minimal de services. Par exemple, TCP ne met pas de délimiteur dans le flot d'octets qui circulent. Contrairement à UDP, on ne peut pas « recevoir un message », seulement recevoir des données. Certains protocoles applicatifs (comme DNS ou EPP) ajoutent une longueur devant chaque message qu'ils envoient, pour avoir une sémantique de message et plus de flot d'octets. TCP n'est donc pas un strict sur-ensemble d'UDP.

Pour contourner cette limitation, notre RFC définit (section 5.1) la notion de « flot d'octets découpé en messages par l'application » (Application-Framed Bytestream). Dans un tel flot, le protocole applicatif indique les frontières de message, par exemple en précédant chaque message d'une longueur, comme le fait le DNS.

Autre problème amusant, certains services peuvent être d'assez bas niveau par rapport aux demandes des applications. Ainsi, le RFC 8303 identifie des services comme « couper Nagle », « configurer DSCP » ou encore « utiliser LEDBAT ». Il serait sans doute plus simple, pour un protocole applicatif, d'avoir une configuration de plus haut niveau. Par exemple, « latence minimale » désactiverait Nagle et mettrait les bits qui vont bien en DSCP.

Nous arrivons finalement au résultat principal de ce RFC, la section 6, qui contient l'ensemble minimal de services. Chaque service est configurable via un ensemble de paramètres. Il est implémentable uniquement avec TCP, et d'un seul côté de la connexion. Dans certains cas, TCP fournira plus que ce qui est demandé, mais ce n'est pas un problème. Je ne vais pas lister tout cet ensemble minimal ici, juste énumérer quelques-uns de ses membres :

  • Créer une connexion, avec des paramètres comme la fiabilité demandée,
  • Mettre fin à la connexion,
  • Envoyer des données, sans indication de fin de message (cf. la discussion plus haut),
  • Recevoir des données.

Pour l'envoi de données, les paramètres sont, entre autres :

  • Fiabilité (les données sont reçues à l'autre bout ou, en tout cas, l'émetteur est prévenu si cela n'a pas été possible) ou non,
  • Contrôle de congestion ou non, sachant que si l'application ne demande pas de contrôle de congestion au protocole de transport, elle doit faire ce contrôle elle-même (RFC 8085),
  • Idempotence,
  • Etc.

Pour la réception de données, le service est juste la réception d'octets, un protocole applicatif qui veut des messages doit utiliser les « flots d'octets découpés par l'application » décrits en section 5.1.

On notera que la sécurité est un service, également, ou plutôt un ensemble de services (section 8 du RFC). Dans les protocoles IETF, la sécurité est souvent fournie par une couche intermédiaire entre la couche de transport et la couche application à proprement parler. C'est ainsi que fonctionne TLS, par exemple. Mais la tendance va peut-être aller vers l'intégration, avec QUIC.


Téléchargez le RFC 8923


L'article seul

Fiche de lecture : Histoire de la Mésopotamie

Auteur(s) du livre : Véronique Grandpierre
Éditeur : Gallimard
978-2-07-039605-4
Publié en 2010
Première rédaction de cet article le 21 octobre 2020


Voici un livre utile pour les gens qui, comme moi, ne connaissent de la Mésopotamie que le démon Pazuzu dans les aventures d'Adèle Blanc-Sec. Une histoire complète de la région où est née la civilisation, région qui a vu beaucoup de cultures différentes, et sur une longue période. De quoi faire rêver (royaumes disparus, mythologie passionnante, épopées héroïques, travaux intellectuels…)

La perception de la Mésopotamie en Europe occidentale est ambigüe. D'un côté, c'est le Croissant fertile, où la civilisation a commencé. De l'autre, l'influence des Hébreux, via la Bible, en a fait l'empire du mal, notamment via la figure de Babylone, accusée de tous les vices, de la sexualité débridée à l'orgueil en passant par l'oppression et l'esclavage. On connait sans doute mieux l'Égypte antique que la Mésopotamie. L'auteure va s'occuper à corriger cela, à expliquer que la Mésopotamie, c'est vaste, avec des royaumes bien distincts, et que les nombreux siècles (en très gros, de -3500 à -500) pendant lesquels on parle de « Mésopotamie » ont vu d'innombrables changements. D'où la taille du livre (417 pages dans l'édition de poche, parue en 2019, sans les annexes).

L'auteure nous parle donc des rois, des villes (c'est en Mésopotamie que sont apparues les premières villes), de la famille (l'inégalité n'était pas qu'entre rois et sujets, elle était aussi présente dans la famille), de l'écriture (également inventée en Mésopotamie), des sciences, de la religion (et on rencontre Pazuzu, chef des démons).

Ah, et comme dans tous les livres qui parlent d'archéologie en Mésopotamie, on croise Agatha Christie, qui a son entrée dans l'index. Sinon, si vous aimez les images, Wikimedia Commons a beaucoup de photos sur la Mésopotamie. Je vous mets d'ailleurs une image (source) de l'épopée de Gilgameš, l'une des plus anciennes légendes écrites (en cunéiforme…) Si vous avez la bonne configuration technique, le héros se nomme 𒄑𒂆𒈦.

La tablette : 512px-Tablet_V_of_the_Epic_of_Gilgamesh.jpg


L'article seul

Fiche de lecture : Digging up Armageddon

Auteur(s) du livre : Eric Cline
Éditeur : Princeton University Press
978-0-691-16632-2
Publié en 2020
Première rédaction de cet article le 18 octobre 2020


Ceux et celles qui ont lu la Bible savent qu'Armaguédon est le lieu du combat final entre le Bien et le Mal. Mais c'est aussi une ville réelle où plusieurs batailles historiques ont eu lieu, et où l'architecture a laissé beaucoup de témoignages. C'est donc un endroit parfait pour des fouilles, et ce livre nous raconte de manière détaillée la campagne de fouilles de l'université de Chicago qui a eu lieu pendant l'entre-deux-guerres.

Vous n'y apprendrez pas forcément beaucoup de choses sur les civilisations qui se sont succédé ici. Ce livre, qui se fonde notamment sur les lettres et les rapports des membres de la longue expédition, privilégie le récit des fouilles, les personnages qui s'y sont illustrés, leurs succès et leurs affrontements. Car l'archéologie n'est pas une discipline désincarnée menée par des êtres parfaits. Les tiraillements, voire les conflits ouverts ont été nombreux. Les fouilles de cette époque étaient financés par Rockfeller et le directeur distant, Breasted, doit toujours prendre soin de garder les faveurs du financier, en apportant régulièrement des résultats spectaculaires. Toute fouille en terre biblique doit forcément rapporter des artefacts mentionnés dans le livre sacré. Cette culture du résultat entraine évidemment des tensions et cela se reflète dans le recrutement et les licenciements brutaux des équipes sur le terrain, qui se renouvellent rapidement. D'autant plus que, sur place, les difficiles conditions matérielles et les difficultés du travail aggravent les tensions, et les appels à la direction à Chicago pour qu'elle tranche des conflits de personne. (Sans compter les lettres anonymes !)

Ces tensions ont au moins un avantage : elles tiennent l'équipe à l'écart de tout ce qui se passe dans le pays où ils travaillent. La lutte contre le colonialisme britannique, les pogroms, et les affrontements avec les sionistes ne semblent pas marquer le quotidien des archéologues, tout occupés à fouiller et à s'engueuler. Cette isolement des troubles est d'autant plus fort que, pour éviter que les ouvriers du chantier ne sympathisent avec d'éventuels mouvements locaux, tous ces ouvriers sont amenés d'Égypte

Les archéologues ont pourtant des opinions. Reflet d'une autre époque, elles sont souvent racistes. Alors même qu'ils mettent en avant les réalisations de rois juifs qu'ils extraient du sol, certains tiennent des propos contre les juifs. Le directeur des fouilles a épousé une juive, et ses subordonnés ne manquent pas de le critiquer pour cela. On imagine que cela n'améliore pas l'ambiance. Et on s'étonne qu'un chercheur puisse faire preuve d'un racisme aussi crasse alors qu'il fait l'éloge des réalisations de Salomon… On voit ainsi un archéologue nouvellement arrivé écrire à ses parents, moins de 24 h après être venu en Palestine, pour y décrire doctement comment tout est de la faute des juifs. D'autres archéologues préfèrent accuser les Arabes, décrits comme attardés, barbares, sales, et autres clichés. Bref, la science n'empêche pas d'être un imbécile ou un salaud, on le savait déjà. Ce livre ne dissimule pas les défauts de ses personnages.

Mais il montre aussi leurs succès : cette longue campagne de fouilles a permis d'innombrables découvertes spectaculaires, sur un terrain qui est occupé par les humains depuis très longtemps. Si les interprétations des découvertes ont parfois été marqués par le sensationnalisme (le soldat tué en défendant l'aqueduc, qui était en fait enterré dans une tombe civile, plus tard percée par le creusement de l'aqueduc…) elles n'en sont pas moins remarquables. Le film « The human adventure » tourné en partie à Armaguédon durant ces fouilles est aujourd'hui visible sur YouTube. S'il a sérieusement vieilli, sur la forme comme sur le fond, il reste un intéressant témoignage des fouilles de l'époque, y compris l'usage du ballon à cette époque où on n'avait pas de drone. (La partie sur la Palestine commence vers 29'05'' et celle sur Meggido vers 30'25''.) La scène qui commence vers 47'06'' (sur un autre site) donne une bonne idée des relations entre les chefs et les travailleurs locaux…

Eric Cline est également l'auteur de « 1177 b.c. the year the civilization collapsed ».


L'article seul

RFC 8937: Randomness Improvements for Security Protocols

Date de publication du RFC : Octobre 2020
Auteur(s) du RFC : C. Cremers (CISPA Helmholtz Center for Information Security), L. Garratt (Cisco Meraki), S. Smyshlyaev (CryptoPro), N. Sullivan, C. Wood (Cloudflare)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF cfrg
Première rédaction de cet article le 17 octobre 2020


Tout le monde sait désormais que la génération de nombres aléatoires (ou, plus rigoureusement, de nombres imprévisibles, pseudo-aléatoires) est un composant crucial des solutions de sécurité à base de cryptographie, comme TLS. Les failles des générateurs de nombres pseudo-aléatoires, ou bien les attaques exploitant une faiblesse de ces générateurs sont les problèmes les plus fréquents en cryptographie. Idéalement, il faut utiliser un générateur sans défauts. Mais, parfois, on n'a pas le choix et on doit se contenter d'un générateur moins satisfaisant. Ce nouveau RFC décrit un mécanisme qui permet d'améliorer la sécurité de ces générateurs imparfaits, en les nourrissant avec des clés privées.

Un générateur de nombres pseudo-aléatoires cryptographique (CSPRNG, pour Cryptographically-Strong PseudoRandom Number Generator) produit une séquence de bits qui est indistinguable d'une séquence aléatoire. Un attaquant qui observe la séquence ne peut pas prédire les bits suivants.

On les nomme générateur pseudo-aléatoires car un générateur réellement aléatoire devrait être fondé sur un phénomène physique aléatoire. Un exemple classique d'un tel phénomène, dont la théorie nous dit qu'il est réellement aléatoire, est la désintégration radioactive. Des exemples plus pratiques sont par exemple des diodes forcées de produire un bruit blanc (comme dans le Cryptech). (Ou alors un chat marchant sur le clavier ?) Mais, en pratique, les ordinateurs se servent de générateurs pseudo-aléatoires, ce qui suffit s'ils sont imprévisibles à un observateur extérieur.

Beaucoup de solutions de sécurité, même en l'absence de cryptographie, dépendent de cette propriété d'imprévisibilité. Ainsi, TCP, pour protéger contre un attaquant aveugle (situé en dehors du chemin du paquet), a besoin de numéros de séquence initiaux qui soient imprévisibles (RFC 5961). Et la cryptographie consomme énormément de ces nombres pseudo-aléatoires. Ainsi, TLS (RFC 8446) se sert de tels nombres à de nombreux endroits, par exemple les numniques utilisés dans le ClientHello, sans compter les nombres pseudo-aléatoires utilisés lors de la génération des clés de session. La plupart des autres protocoles de chiffrement dépendent de tels nombres que l'attaquant ne peut pas prévoir.

Réaliser un générateur pseudo-aléatoire sur une machine aussi déterministe qu'un ordinateur n'est pas facile, en l'absence de source quantique comme un composant radioactif. (Cf. RFC 4086.) La solution adoptée la plus simple est d'utiliser une fonction qui calcule une séquence de nombres pseudo-aléatoires d'une manière que, même en observant la séquence, on ne puisse pas deviner le nombre suivant (la mathématique fournit plusieurs fonctions pour cela). Comme l'algorithme est en général connu, et que l'ordinateur est déterministe, s'il connait le premier nombre, la graine, un observateur pourrait calculer toute la séquence. La graine ne doit donc pas être connue des observateurs extérieurs. Elle est par exemple calculée à partir d'éléments qu'un tel observateur ne connait pas, comme des mouvements physiques à l'intérieur de l'ordinateur, ou bien provoqués par l'utilisateur.

De tels générateurs pseudo-aléatoires sont très difficiles à réaliser correctement et, en cryptographie, il y a eu bien plus de failles de sécurité dues à un générateur pseudo-aléatoire que dues aux failles des algorithmes de cryptographie eux-mêmes. L'exemple le plus fameux était la bogue Debian, où une erreur de programmation avait réduit drastiquement le nombre de graines possibles (l'entropie). Un autre exemple amusant est le cas du générateur cubain qui oubliait le chiffre 9.

Mais le générateur pseudo-aléatoire peut aussi être affaibli délibérement, pour faciliter la surveillance, comme l'avait fait le NIST, sur ordre de la NSA, en normalisant le générateur Dual-EC avec une faille connue.

Obtenir une graine de qualité est très difficile, surtout sur des appareils ayant peu de pièces mobiles, donc peu de mouvements physiques qui pourraient fournir des données aléatoires. Un truc avait déjà été proposé : combiner la graine avec la clé privée utilisée pour la communication (par exemple en prenant un condensat de la concaténation de la graine avec la clé privée, pour faire une graine de meilleure qualité), puisque la clé privée est secrète. L'idée vient du projet Naxos. (Cela suppose bien sûr que la clé privée n'ait pas été créée par la source qu'on essaie d'améliorer. Elle peut par exemple avoir été produite sur un autre appareil, ayant davantage d'entropie.) Le problème de cette approche avec la clé privée, est que les clés privées sont parfois enfermées dans un HSM, qui ne les laisse pas sortir.

La solution proposée par notre RFC est de ne pas utiliser directement la clé secrète, mais une signature de la graine. C'est une valeur qui est imprévisible par un observateur, puisqu'elle dépend de la clé privée, que l'attaquant ne connait pas. Ainsi, on peut obtenir une séquence de nombres pseudo-aléatoires que l'observateur ne pourra pas distinguer d'une séquence réellement aléatoire, même si la graine initiale n'était pas terrible.

L'algorithme exact est formulé dans la section 3 du RFC. Le Nième nombre pseudo-aléatoire est l'expansion (RFC 5869, section 2.3) de l'extraction (RFC 5869, section 2.2) d'un condensat de la signature d'une valeur qui ne change pas à chaque itération de la séquence, ce qui fait que cet algorithme reste rapide. (J'ai simplifié, il y a d'autres paramètres, notamment la valeur « normale » de la séquence, initiée à partir de la graine.) La signature doit évidemment être secrète (sinon, on retombe dans le générateur pseudo-aléatoire d'avant ce RFC). La fonction de signature doit être déterministe (exemple dans le RFC 6979). La « valeur qui ne change pas à chaque itération » peut, par exemple (section 4 du RFC) être l'adresse MAC de la machine mais attention aux cas de collisions (entre VM, par exemple). Une autre valeur constante est utilisée par l'algorithme et peut, par exemple, être un compteur, ou bien l'heure de démarrage. Ces deux valeurs n'ont pas besoin d'être secrètes.

Une analyse de sécurité de ce mécanisme a été faite dans l'article « Limiting the impact of unreliable randomness in deployed security protocols ». Parmi les points à surveiller (section 9), la nécessité de bien garder secrète la signature, ce qui n'est pas toujours évident notamment en cas d'attaque par canal auxiliaire.

À propos de générateurs pseudo-aléatoires, je vous recommande cet article très détaillé en français sur la mise en œuvre de ces générateurs sur Linux.

Merci à Kim Minh Kaplan pour une bonne relecture.


Téléchargez le RFC 8937


L'article seul

RFC 8925: IPv6-Only-Preferred Option for DHCPv4

Date de publication du RFC : Octobre 2020
Auteur(s) du RFC : L. Colitti, J. Linkova (Google), M. Richardson (Sandelman), T. Mrugalski (ISC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dhc
Première rédaction de cet article le 17 octobre 2020


Si une machine a IPv6 et est ravie de n'utiliser que ce protocole, pas la peine pour un serveur DHCP de lui envoyer une des rares adresses IPv4 restantes. Ce nouveau RFC décrit une option de DHCP-IPv4 qui permet au client de dire au serveur « je n'ai pas vraiment besoin d'IPv4 donc, s'il y a IPv6 sur ce réseau, tu peux garder les adresses IPv4 pour les nécessiteux ».

Idéalement, l'administrateur réseaux qui configure un nouveau réseau voudrait le faire en IPv6 seulement, ce qui simplifierait son travail. Mais, en pratique, c'est difficile (le RFC 6586 décrit une telle configuration). En effet, beaucoup de machines ne sont pas encore entrées dans le XXIe siècle, et ne gèrent qu'IPv4 ou, plus exactement, ont besoin d'IPv4 pour au moins certaines fonctions (comme des versions de Windows qui avaient IPv6 mais ne pouvaient parler à leur résolveur DNS qu'au-dessus d'IPv4). Il faut donc se résigner à gérer IPv4 pour ces machines anciennes. Mais, vu la pénurie d'adresses IPv4, il est également souhaitable de ne pas allouer d'adresses IPv4 aux machines qui n'en ont pas besoin.

La solution la plus courante à l'heure actuelle est de mettre les machines antédiluviennes et les machines modernes dans des réseaux séparés (VLAN ou SSID différents, par exemple, comme c'est fait aux réunions IETF ou RIPE), le réseau pour les ancêtres étant le seul à avoir un serveur DHCPv4 (RFC 2131). Cela a plusieurs inconvénients :

  • Cela complique le réseau et son administration,
  • Le risque d'erreur est élevé (utilisateur sélectionnant le mauvais SSID dans le menu des réseaux Wi-Fi accessibles, par exemple).

L'idéal serait de n'avoir qu'un réseau, accueillant aussi bien des machines IPv6 que des machines IPv4, sans que les machines IPv6 n'obtiennent d'adresse IPv4, dont elles n'ont pas besoin. On ne peut pas demander aux utilisateurs de débrayer complètement IPv4, car les machines mobiles peuvent en avoir besoin sur des réseaux purement IPv4 (ce qui existe encore). La machine IPv6 ne sachant pas, a priori, si le réseau où elle se connecte est seulement IPv4, seulement IPv6 ou accepte les deux, elle va donc, logiquement, demander une adresse IPv4 en DHCP, et bloquer ainsi une précieuse adresse IPv4. Retarder cette demande pour voir si IPv6 ne suffirait pas se traduirait par un délai peu acceptable lorsque le réseau n'a pas IPv6.

Notre RFC résout ce problème en créant une nouvelle option pour les requêtes et réponses DHCP v4 : dans la requête, cette option indique que le client n'a pas absolument besoin d'une adresse IPv4, qu'il peut se passer de ce vieux protocole, si le réseau a de l'IPv6 bien configuré et, dans la réponse, cette option indique que le réseau fonctionne bien en « IPv6 seulement ». Et comment fait-on si on veut joindre un service IPv4 depuis un tel réseau ? Il existe des techniques pour cela, la plus répandue étant le NAT64 du RFC 6146, et la réponse du serveur DHCP indique également qu'une de ces techniques est présente.

La section 1.2 précise quelques termes importants pour comprendre les choix à effectuer pour le client et pour le serveur DHCP :

  • Capable de faire de l'IPv6 seule (IPv6-only capable host) : une machine terminale qui peut se débrouiller sans problème sans adresse IPv4,
  • Nécessite IPv4 (IPv4-requiring host) : le contraire,
  • IPv4 à la demande (IPv4-on-demand) : le scénario, rendu possible par ce RFC, où le même réseau accueille des machines capables de faire de l'IPv6 seul, et des machines qui nécessitent IPv4 ; ce réseau se nomme « Essentiellement IPv6 » (IPv6-mostly network), et fournit NAT64 (RFC 6146) ou une technique équivalente,
  • En mode seulement IPv6 (IPv6-only mode) : état d'une machine capable de faire de l'IPv6 seule et qui n'a pas reçu d'adresse IPv4,
  • Réseau seulement en IPv6 (IPv6-only network) : un réseau qui ne fournit pas du tout d'IPv4 et ne peut donc pas accueillir les machines qui nécessitent IPv4 (c'est un tel réseau qui sert de base à l'expérience du RFC 6586),
  • Notez que le cas d'un réseau qui non seulement serait seulement en IPv6 mais en outre ne fournirait pas de technique comme celle de NAT64 (RFC 6146) n'apparait pas dans le RFC. Un tel réseau ne permettrait pas aux machines terminales de joindre les services qui sont restées en IPv4 seulement comme MicrosoftHub ou l'Élysée.

La section 2 du RFC résume ensuite les bonnes raisons qu'il y a pour signaler au réseau, via l'option DHCP, qu'on se débrouille très bien avec IPv6 seul :

  • Il semble logique que la nouvelle option, qui veut dire « je n'ai pas réellement besoin d'IPv4 » soit envoyée via le protocole qui sert à demander les adresses IPv4,
  • Tout le monde a déjà DHCP v4 et, surtout, utiliser le protocole existant n'introduit pas de nouvelles vulnérabilités (permettre à un nouveau protocole de couper IPv4 sur les machines terminales serait un risque de sécurité important),
  • Comme il faut ajouter explicitement l'option aux requêtes et aux réponses, IPv4 ne sera coupé que si le client et le serveur DHCP sont tous les deux d'accord pour cela,
  • Ce système n'ajoute aucun retard à la configuration via DHCP, le client qui envoie l'option alors que le réseau ne permet pas IPv6 seul, aura son adresse IPv4 aussi vite qu'avant (pas d'aller-retours de négociation),
  • DHCP permet des résultats qui dépendent du client, donc, sur un même réseau, le serveur DHCP pourra économiser les adresses IPv4 en en n'envoyant pas aux machines qui peuvent s'en passer, tout en continuant à en distribuer aux autres.

La section 3 du RFC présente l'option elle-même. Elle contient le code 108 (IPv6-only Preferred), enregistré à l'IANA (cf. section 5), la taille de l'option (toujours quatre, mais précisée car c'est l'encodage habituel des options DHCP, cf. RFC 2132) et la valeur, qui est, dans la réponse, le nombre de secondes que le client peut mémoriser cette information, avant de redemander au serveur DHCP.

Le logiciel client DHCP doit donc offrir un moyen à son administrateur pour activer « je me débrouille très bien en IPv6 », et cela doit être par interface réseau. Dans ce cas, le client DHCP doit envoyer l'option décrite dans notre RFC. La décision d'activer le mode « IPv6 seul » peut aussi être prise automatiquement par le système d'exploitation, par exemple parce qu'il détecte que 464XLAT (RFC 6877) fonctionne. De même, des objets connectés qui ne parlent qu'à des services accessibles en IPv6 pourraient être livrés avec l'option « IPv6 seul » déjà activée.

Outre le côté « je suis un bon citoyen, je ne gaspille pas des ressources rares » qu'il y a à ne pas demander d'adresse IPv4, cette option permet de couper un protocole réseau inutile, diminuant la surface d'attaque de la machine.

Côté serveur DHCP, il faut un moyen de configurer, pour chaque réseau, si on accepte l'option « IPv6 me suffit ». Si elle est activée, le serveur, lorsqu'il recevra cette option dans une requête (et uniquement dans ce cas), la mettra dans sa réponse, et n'attribuera pas d'adresse IPv4. On voit donc que les vieux clients DHCP, qui ne connaissent pas cette option et ne l'inclueront donc pas dans leurs requêtes, ne verront pas de changement, ils continueront à avoir des adresses IPv4 comme avant (s'il en reste…).

A priori (section 4 du RFC), l'administrateurice du serveur DHCP ne va pas activer cette option si son réseau ne fournit pas un mécanisme permettant aux machines purement IPv6 de joindre des services purement IPv4 (par exemple le mécanisme NAT64 du RFC 6146). En effet, on ne peut pas s'attendre, à court terme, à ce que tous les services Internet soient accessibles en IPv6. Activer l'option « IPv6 seul » sans avoir un mécanisme de traduction comme NAT64 n'est réaliste que sur des réseaux non-connectés à l'Internet public.

Un petit mot sur la sécurité, juste pour rappeler que DHCP n'est pas vraiment sécurisé et que l'option « v6 seul » a pu être mise, retirée ou modifiée suite aux actions d'un attaquant. Cela n'a rien de spécifique à cette option, c'est un problème général de DHCP, contre lequel il faut déployer des protections comme le DHCP snooping.

À l'heure actuelle, je ne connais pas encore de mise en œuvre de cette option (qui ne devrait pas être trop dure à ajouter, elle n'a rien de très nouveau ou d'extraordinaire).

Un dernier mot : le RFC 2563 prévoyait une option pour couper l'auto-configuration des adresses IPv4. Elle peut être utilisée en même temps que l'option de notre RFC, qu'elle complète assez bien.


Téléchargez le RFC 8925


L'article seul

Fiche de lecture : Le mandat

Auteur(s) du livre : Ousmane Sembène
Éditeur : Présence africaine
978-2-7087-0170-0
Publié en 1966
Première rédaction de cet article le 14 octobre 2020


Ce petit livre rassemble deux longues nouvelles de Sembène, « Le mandat » et « Véhi-Ciosane », toutes les deux situées dans le Sénégal des années 1960.

Dans « Le mandat », le héros, qui est pauvre, reçoit de l'argent et tout de suite, plein de parasites essaient d'en obtenir une part. La nouvelle fait défiler toute une galerie de personnages de Dakar et voit le héros se confronter à la difficulté de toucher un mandat quand on n'est pas déjà bancarisé. De nombreux rebondissements tragi-comiques ponctuent l'histoire.

La nouvelle « Véhi-Ciosane » (« Blanche Genèse ») se passe par contre à la campagne et est un portrait assez cruel de certaines mœurs.

L'auteur a dû ajouter une préface d'explication parce que certains lui reprochaient de donner une mauvaise image de l'Afrique. En Afrique comme ailleurs, il y a des gens qui ne comprennent pas que, parce qu'un personnage de roman est négatif, cela ne veut pas dire que l'auteur déteste tout son pays ou tout son continent. Reprocher à Sembène Ousmane de donner une mauvaise image des Africains serait tout aussi absurde que de reprocher à Maupassant (le monde de « Véhi-Ciosane » me fait beaucoup penser à Maupassant) de donner une mauvaise image des Français !

Les deux nouvelles ont été adaptées au cinéma par l'auteur, « Véhi-Ciosane » sous le titre de « Niaye » et « Le mandat » sous le même titre, mais je n'ai pas eu l'occasion de voir ces films.


L'article seul

Fiche de lecture : The infinite machine

Auteur(s) du livre : Camila Russo
Éditeur : Harper Collins
978-0-06-288614-9
Publié en 2020
Première rédaction de cet article le 7 octobre 2020


Ce livre est une passionnante histoire d'Ethereum, la plus importante chaîne de blocs en nombre de nœuds (oui, devant Bitcoin, qui est plus concentré). Ethereum permet non seulement la circulation de monnaie, mais également l'exécution de programmes (d'où le titre du livre). La journaliste Camila Russo, qui a écrit de nombreux articles sur les cryptomonnaies, connait bien le monde Ethereum qu'elle suit depuis longtemps, et était donc toute désignée pour ce premier livre d'histoire d'Ethereum, une histoire toute récente puisque la plupart des événements cités se sont déroulés entre 2014 et 2018.

Il se trouve que je possède moi-même quelques ethers (la monnaie d'Ethereum) et que j'ai suivi de près certaines étapes du développement d'Ethereum (comme l'attaque contre The DAO), donc j'ai pu comparer certaines parties du livres avec ce que j'avais vu passer. Même si le ton journalistique est parfois un peu agaçant, le livre est bien documenté, l'auteure connait son sujet et je recommande donc le livre. On y croise plein de personnages pittoresques, à commencer par l'étonnant Vitalik Buterin, le principal concepteur d'Ethereum. On pense forcément au film The Social Network (ah, les descriptions people de la maison à Zoug où tout le monde travaillait ensemble en fumant des joints…). Le livre parlera surtout à tous les gens intéressés par l'innovation technologique et ses conséquences sociales.

Car, dès qu'il s'agit de cryptomonnaies, il est difficile de séparer la technique et la politique. Si toute technologie a des conséquences politiques, dans le cas des cryptomonnaies, la politique est souvent explicite. L'auteure a des sympathies claires pour le capitalisme (elle a travaillé chez Bloomberg, média d'information orienté business) et, parlant des crises économiques en Argentine, elle répète que c'est à cause de politiques « populistes », c'est-à-dire sociales. Mais, indépendamment des opinions politiques de l'auteure, le livre est l'occasion de réfléchir sur la monnaie et l'État. Les acteurs d'Ethereum sont très divisés, de ceux qui veulent plutôt changer le monde à ceux qui veulent juste gagner de l'argent, et, parmi les premiers, il ne manque pas de diversité. L'auteure les estime moins à droite que les acteurs du monde Bitcoin (« dans les réunions Bitcoin, c'est plutôt carnivore, dans celles d'Ethereum, davantage végétarien ») mais c'est compliqué. Une partie du développement d'Ethereum a été fait dans des squats anarchistes, une autre partie dans les garages chers aux startupeurs. Il serait bien difficile de classer politiquement tout le monde Ethereum (et l'auteure n'aide pas toujours en confondant parfois anarchiste et libertarien).

Comme beaucoup de projets sur la chaîne de blocs, ou d'ailleurs comme beaucoup de projets innovants, Ethereum a connu des hauts très hauts et des bas très bas, passant de moments d'euphorie où de nombreux développeurs géniaux étaient prêts à travailler gratuitement sans limite de temps, à des moments de déprime où les discours négatifs semblaient prendre le dessus. Le sommet avait sans doute été les nombreuses ICO de 2016-2018 où l'argent coulait à flot vers Ethereum, alors que certaines de ces ICO étaient des pures escroqueries, et que beaucoup d'autres étaient complètement irréalistes dans leurs prévisions. Aujourd'hui, Ethereum tourne toujours, a des projets, et suscite moins d'intérêt ce qui peut être vu comme un avantage : on bosse mieux sans pression. Le livre se termine donc sur une non-conclusion.

J'ai parlé d'Ethereum dans plusieurs articles, en voici la liste.


L'article seul

RFC 8886: Secure Device Install

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : W. Kumari (Google), C. Doyle (Juniper Networks)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsawg
Première rédaction de cet article le 6 octobre 2020


Quand vous êtes opérateur réseau et que vous avez à installer une nouvelle machine, par exemple un routeur, dans un centre de données lointain, vous avez deux solutions : envoyer un employé faire l'installation sur place, ce qui peut être coûteux, ou bien demander à la société qui gère le centre de données de le faire pour vous, ce qui n'est pas forcément génial question sécurité, puisque, selon la façon dont c'est fait, ils auront peut-être la possibilité de regarder ou de bricoler la configuration de la machine. Ce nouveau RFC propose un moyen simple d'améliorer la sécurité dans le deuxième cas, en chiffrant un fichier de configuration avec la clé publique de la machine. Celle-ci pourra le déchiffrer après téléchargement, en utilisant sa clé privée. (Cette solution nécessitera donc un changement des équipements pour que chacun ait une paire clé publique / clé privée.)

Précisons la question à résoudre. Ce problème est une variante d'un problème bien classique en informatique, celui du bootstrap. Par exemple, si la nouvelle machine est protégée par un mot de passe, il faut bien rentrer ce mot de passe la première fois. Si c'est un employé du centre de données qui le fait, il connaitra le mot de passe. Et si on le change juste après ? Rien ne dit qu'il n'aura pas laissé une porte dérobée. Il n'y a pas de solution générale et simple à ce problème. Notre RFC se contente d'une solution partielle, qui améliore la sécurité.

On va donc s'imaginer à la place de la société Machin, un gros opérateur réseau dont l'essentiel des équipes est à Charleville-Mézières (pourquoi pas ?). La société a des POP dans beaucoup d'endroits, et la plupart du temps dans ces centres de données qu'elle ne contrôle pas, où elle loue juste de l'espace. Comme les équipements réseau tombent parfois en panne, ou, tout simplement, ne parviennent plus à gérer le trafic toujours croissant, la société doit de temps en temps installer de nouveaux matériels, routeurs, commutateurs, etc. Si le centre de données où il faut installer est proche de Charleville-Mézières, tout va bien : un employé de l'opérateur Machin se rend sur place, le fabricant du routeur a déjà livré la nouvelle machine, il n'y a plus qu'à la racker et à la configurer (« Enter the password for the administrative account ») ou, en tout cas, faire une configuration minimale qui permettra de faire ensuite le reste via SSH, RESTCONF (RFC 8040) ou une autre technique d'administration à distance.

Mais supposons que la machine à installer, mettons que ce soit un gros routeur, doive être placé chez un centre de données éloigné, mettons Singapour (exemple choisi parce que c'est vraiment loin). Même avant la pandémie de Covid-19, un voyage à Singapour n'était guère raisonnable, du point de vue du temps passé, et du point de vue financier. Mais les centres de données ont tous un service d'action à distance (remote hands) où un employé de la société qui gère le centre peut appuyer sur des boutons et taper des commandes, non ? C'est en effet très pratique, mais ce service est limité à des cas simples (redémarrer…) et pas à une configuration complète. Celle-ci poserait de toute façon un problème de sécurité car l'employé en question aurait le contrôle complet de la machine pendant un moment.

(Une autre solution, apparemment non mentionnée dans le RFC, est que le fabricant du routeur livre à Charleville-Mézières l'appareil, qui soit alors configuré puis envoyé à Singapour. Mais cela impose deux voyages.)

Bon, et une solution automatique ? La machine démarre, acquiert une adresse IP, par exemple par DHCP (RFC 2131 et RFC 8415), et charge sa configuration sous forme d'un fichier récupéré, par exemple avec TFTP (RFC 1350). Mais cette configuration peut contenir des informations sensibles, par exemple des secrets RADIUS (RFC 2865). TFTP n'offre aucune sécurité et ce n'est pas très rassurant que de laisser ces secrets se promener en clair dans le centre de données singapourien. Il existe des contournements variés et divers pour traiter ces cas, mais aucun n'est complètement satisfaisant.

Bref, le cahier des charges de notre RFC est un désir de confidentialité des configurations du nouveau routeur. (Il y a une autre question de sécurité importante, l'authenticité de cette configuration, mais elle n'est pas traitée dans ce RFC. Des solutions, un peu complexes, existent, comme SZTP - RFC 8572 ou BRSKI - RFC 8995.) La solution présentées dans notre RFC n'est pas complète. Elle améliore les procédures d'installation (voir par exemple la documentation de celle de Cisco) mais ne prétend pas résoudre tout le problème.

Ce RFC ne spécifie pas un protocole, mais décrit une méthode, que chaque constructeur d'équipements réseau devra adapter à ses machines et à leurs particularités. Cette méthode est conçue pour ces équipements (routeurs et commutateurs, notamment), mais pourrait être adaptée à des engins comme les serveurs. Mais en attendant, ce RFC se focalise sur le matériel réseau.

La section 2 du RFC résume la solution. Elle nécessite que la machine à configurer ait un mécanisme de démarrage automatique de l'installation (autoinstall ou autoboot dans les documentations), permettant d'obtenir une adresse IP (typiquement avec DHCP) puis de récupérer un fichier de configuration (typiquement avec TFTP mais cela peut être HTTP ou un autre protocole de transfert de fichiers, les options DHCP 66 - Server-Name - ou 150 - TFTP server address pouvant être utilisées pour indiquer le serveur). Le nom du fichier est par exemple issue de l'option DHCP 67 - Bootfile-Name.

La méthode nécessite un identificateur, comme le numéro de série ou bien l'adresse MAC de l'équipement réseau qui est en cours d'installation. (Rien n'interdit d'utiliser un autre identificateur, par exemple un UUIDRFC 4122, mais l'avantage du numéro de série est qu'il est en général marqué sur la machine et facilement accessible, donc la personne dans le centre de données à Singapour peut le lire et le transmettre à la société Machin.)

Le RFC donne un exemple concret. La société Machin commande un nouveau routeur à un fabricant de routeur, mettons Truc, en indiquant l'adresse de livraison à Singapour. Truc doit indiquer à Machin le numéro de série de l'engin. Et il faut qu'une paire clé publique / clé privée spécifique à cet engin soit générée, la clé publique étant communiquée à l'acheteur (Machin). [Cette étape est l'une des deux seules que ne font pas les routeurs actuels.] Pendant que le routeur voyage vers Singapour, un employé de Machin prépare la configuration du routeur, et la chiffre avec la clé publique de ce routeur particulier. Puis il la place sur le serveur de fichiers, indexée par le numéro de série. Les employés du centre de données mettent le routeur dans l'armoire et le câblent. Le routeur démarre et voit qu'il n'a pas encore été configuré. Il récupère une adresse IP puis contacte le serveur de fichiers. Il récupère la configuration, la déchiffre [deuxième étape qui n'est pas encore mise en œuvre dans un routeur typique d'aujourd'hui] et l'installe. Désormais, le routeur est autonome. Les équipes de l'opérateur Machin peuvent le contacter par les moyens habituels (SSH, par exemple). Un éventuel attaquant pourra regarder le trafic ou, plus simplement, demander le fichier de configuration au serveur de fichiers, mais il ne pourra pas le déchiffrer.

Cette solution ne nécessite que peu de changements aux mécanismes d'aujourd'hui. La section 3 du RFC décrit ce que les fabricants de routeurs devront faire, pour qu'elle soit disponible. Le routeur devra disposer d'une paire clé publique / clé privée, générée lors de sa fabrication. Et le fabricant doit pouvoir accéder à cette clé facilement (les clés cryptographiques ne peuvent typiquement pas être affichées sur un petit écran LCD…), afin de la communiquer à l'acheteur. (On peut aussi envisager le RFC 7030 ou bien le RFC 8894.) Le fabricant de routeurs doit avoir un mécanisme de communication de ces clés au client. (Comme il s'agit de clés publiques, il n'est pas indispensable que ce soit un mécanisme confidentiel, mais il faut évidemment qu'un tiers ne puisse pas y ajouter des clés de son choix.) Le RFC recommande X.509 (RFC 5280) comme format pour ces clés, même s'il n'y a pas forcément besoin des méta-données de X.509 comme la date d'expiration.

Et le client, l'acheteur du routeur ? La section 4 décrit ce qu'il doit faire. Il faut réceptionner et transmettre le numéro de série du routeur (typiquement, cela veut dire une communication entre le service Achats et les Opérations, ce qui n'est pas toujours facile), puis récupérer la clé publique. Et enfin, il faut chiffrer la configuration (le RFC suggère S/MIMERFC 5751).

Quelques détails supplémentaires figurent en section 5. Par exemple, si le routeur le permet (il faut du haut de gamme…), la clé privée peut être stockée dans un TPM. (Le RFC suggère également de jeter un œil à la Secure Device Identity de la norme IEEE Std 802-1AR.)

Et la section 7 du RFC revient sur la sécurité de ce mécanisme. Il sera de toute façon toujours préférable à la solution actuelle, qui est de transmettre la configuration en clair. Mais cela ne veut pas dire que tout soit parfait. Ainsi, un attaquant qui a un accès physique à la machine pendant son trajet, ou bien une fois qu'elle est arrivée dans le centre de données, peut extraire la clé privée (sauf si elle est stockée dans un TPM) et déchiffrer à loisir.

On a dit au début que le but de ce RFC n'était pas de trouver un moyen d'authentifier la configuration. (Une signature ne serait pas réaliste, car il y a peu de chances que le fabricant mette les clés publiques de chaque opérateur dans le routeur.) Un attaquant qui contrôle, par exemple, le réseau sur lequel se trouve l'équipement réseau qui se configure, peut donc diriger les requêtes TFTP vers un serveur de son choix et envoyer une configuration « pirate » à cet équipement. (Il peut même la chiffrer puisque la clé publique de l'équipement sera sans doute facilement accessible publiquement, pour faciliter la tâche du client.)

Et, bien sûr, rien ne protège contre un vendeur malhonnête. Si le fabricant du routeur ou du commutateur est malveillant (ou piraté par un de ses employés, ou par un pirate extérieur), il peut tout faire. C'est le problème de la supply chain en sécurité, et il est très difficile à résoudre. (Cf. les craintes concernant les pratiques de Huawei mais il serait naïf de penser que seuls les fabricants chinois soient malhonnêtes. Voyez aussi mon article sur les portes dérobées dans les routeurs.)

Si vous aimez le concret, l'annexe A du RFC donne les commandes OpenSSL pour effectuer les différentes manipulations décrites par ce RFC. (J'ai modifié les commandes du RFC, qui ne marchaient pas pour moi.) Le fabricant du routeur va d'abord générer la paire de clés sur le routeur, la clé publique étant ensuite emballée dans un certificat (SN19842256 étant le numéro de série du routeur), et auto-signer :

%  openssl req  -new -nodes -newkey rsa:2048 -keyout key.pem -out SN19842256.csr 
...
Common Name (e.g. server FQDN or YOUR name) []:SN19842256
...

%  openssl req -x509 -days 36500 -key key.pem -in SN19842256.csr  -out SN19842256.crt
  

L'opérateur réseau va fabriquer un fichier de configuration (ici, trivial) :

% echo 'Test: true' > SN19842256.cfg
  

Ensuite, récupérer la clé (SN19842256.crt) et chiffrer la configuration :

%  openssl smime -encrypt -aes-256-cbc -in SN19842256.cfg  -out SN19842256.enc -outform PEM SN19842256.crt

% cat SN19842256.enc
-----BEGIN PKCS7-----
MIIB5gYJKoZIhvcNAQcDoIIB1zCCAdMCAQAxggGOMIIBigIBADByMFoxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
...
  

On copie ensuite la configuration chiffrée sur le serveur de fichiers.

Lorsque le routeur démarre, il charge ce fichier et exécute une commande de déchiffrement :

%  openssl smime -decrypt -in SN19842256.enc  -inform PEM -out config.cfg -inkey key.pem

% cat config.cfg 
Test: true
  

Pour l'instant, aucun fabricant de routeur ne semble avoir annoncé une mise en œuvre de ce RFC. Comme le RFC décrit un mécanisme générique, et pas un protocole précis, les détails dépendront sans doute du vendeur.


Téléchargez le RFC 8886


L'article seul

La question de la 5G mérite-t-elle autant de passions ?

Première rédaction de cet article le 1 octobre 2020


Dans une société démocratique, les controverses ne manquent pas. Dans l'espace public, on discute de plein de sujets, et chacun a son opinion, qui est légitime par définition, dans une démocratie. Cette variété d'opinions sur un même sujet a souvent été remarquée, analysée et discutée. Mais il y a eu moins de temps consacré à analyser pourquoi, sur certains sujets de controverse socio-technique, la machine politico-médiatique se met en marche, en accentuant et en caricaturant à la fois le sujet et les arguments déployés, alors que pour d'autres sujets, tout aussi importants, et où les positions ne sont pas moins diverses et reposant sur des arguments variés, cette machine se met peu ou pas en marche et le sujet reste l'apanage de cercles spécifiques d'acteurs.

Pourtant, on sait bien que, parfois, ce ne sont pas les réponses proposées (et divergentes) qui sont vraiment importantes, mais les questions. Ainsi, avoir des controverses sur « l'immigration » plutôt que, par exemple, sur « le chômage » n'est pas neutre. Quelles que soient les réponses données à ces questions, le fait d'avoir posé le débat sur un de ces terrains plutôt que sur l'autre est déjà un choix politique. Ce « choix » n'est pas forcément délibéré, il peut être le résultat de dynamiques que les acteurs eux-mêmes ne maitrisent pas. Mais il a des conséquences pratiques : en matière de temps disponible, bien sûr, d'autant plus que les sujets complexes nécessitent de passer du temps à lire, à réfléchir, à discuter. Si un sujet est mis en avant, cela fera forcément moins de temps pour décider démocratiquement des autres. Et il y a aussi des conséquences en matière de visibilité. Si un citoyen ou une citoyenne ne sait pas trop quels sont les sujets importants du jour, il considérera forcément les « grands sujets », âprement débattus publiquement, comme étant les seuls qui valent la peine. Enfin, la seule mise en avant d'un sujet de controverse a déjà des conséquences idéologiques, en avalisant les présupposés derrière ce sujet (par exemple, sur l'immigration, le fait que les immigrés soient un problème).

Ce raisonnement peut aussi s'appliquer au débat actuel sur l'ensemble des techniques de réseau mobile connues sous le nom de « 5G ». Ne discutons pas ici de savoir si le déploiement de la 5G est une bonne ou une mauvaise chose. Intéressons-nous plutôt à « pourquoi ce débat ? » Pourquoi est-ce que la machine de la « grande controverse » s'est mise en route pour la 5G ?

Pas question de considérer ce débat comme inutile ou néfaste parce qu'il a une forte composante technique. Cet aspect technique crucial nécessite certes que les participantes et participants fassent un effort d'éducation et de compréhension du problème. Mais il n'élimine pas la légitimité de tous et toutes à y participer : les techniques jouent un rôle crucial dans l'infrastructure de notre société, et ont certainement vocation à être débattues publiquement et démocratiquement. Mais on pourrait dire la même chose de plein d'autres techniques qui jouent un rôle crucial aujourd'hui. Alors, pourquoi la 5G ?

Certains pourraient dire que c'est parce que c'est une technique révolutionnaire, qui va changer en profondeur de nombreux aspects de notre société. Cet argument du caractère profondément disruptif de la 5G est souvent mis en avant par ses promoteurs commerciaux et, curieusement, souvent accepté sans critique par les détracteurs de la 5G. La vérité est que la 5G ne va pas être une révolution. C'est juste une technique d'accès au réseau, les applications sont les mêmes (regarder Netflix, lire Wikipédia, y contribuer…). Ainsi, les performances supérieures (en latence et en capacité) ne se traduiront pas forcément par un gain pour les usages, puisque le goulet d'étranglement n'est pas forcément l'accès radio. Toute personne étant passé de la 3G à la 4G (ou de l'ADSL à la fibre) a pu constater que le gain dans le réseau d'accès n'est pas forcément très visible lorsqu'on interagit avec des services Internet lointains et/ou lents.

Ainsi, beaucoup d'arguments entendus contre la 5G n'ont en fait rien de spécifique à la 5G :

  • les risques pour la vie privée ne changent pas : qu'on accède à Facebook en 4G ou en 5G, cette entreprise récoltera autant de données,
  • les caméras de vidéosurveillance existent déjà, sans avoir besoin de la 5G,
  • les objets connectés, qui envoient massivement à leur fabricant des données personnelles sur les utilisateurs, existent également depuis un certain temps, la 5G ne va pas les multiplier,
  • quant aux risques écologiques et environnementaux, on ne peut hélas pas dire qu'ils sont apparus avec la 5G.

Mais peut-être un changement quantitatif (performances supérieures, même si elles ne le seront pas autant que ce que raconte le marketing) va-t-il déclencher un changement qualitatif en rendant trivial et/ou facile ce qui était difficile avant ? Peut-être. De tels sauts se sont déjà produits dans l'histoire des systèmes socio-techniques. Mais souvent, également, la montagne a accouché d'une souris. Les tendances lourdes de l'Internet, bonnes ou mauvaises, n'ont pas été bouleversées par le déploiement de la fibre optique, par exemple.

Il est curieux, par contre, de constater que les vraies nouveautés de la 5G sont en général absentes du débat. Ainsi, le « network slicing », qui permet d'offrir plusieurs réseaux virtuels sur un accès physique, est un changement important. Ses conséquences peuvent être sérieuses, notamment parce qu'il peut faciliter des violations de la neutralité de l'Internet, avec une offre de base, vraiment minimale, et des offres « améliorées » mais plus chères. Mais ce point ne semble jamais mentionné dans les débats sur la 5G, alors que la neutralité du réseau est à la fois un élément crucial pour le citoyen utilisateur de l'Internet, et qu'elle est menacée en permanence.

Bien sûr, chacun est libre de trouver que tel sujet est plus important que tel autre. De même qu'il ne peut pas y avoir d'unanimité sur les réponses, il n'y aura pas d'unanimité sur les questions. Néanmoins, il est frappant de constater que certains sujets semblent plus porteurs, sans qu'on puisse trouver une base objective à l'importance qu'ils ont dans le débat public. Tout homme (ou femme) politique en France aujourd'hui se sent obligé d'avoir un avis sur la 5G, qu'il ou elle ait étudié le sujet ou pas. On voit l'argument de la vie privée être avancé, alors que la 5G ne change pas grand'chose à cette question, par des personnes qui ne s'étaient pas signalées jusqu'à présent par une grande sensibilité à cette question, pourtant cruciale sur l'Internet.

Alors, pourquoi est-ce que le thème de la 5G est un tel succès ? Si on était d'humeur complotiste, on pourrait penser que c'est parce qu'il est bien pratique pour éviter des débats gênants sur la neutralité de l'Internet, la vie privée sur le Web, la surveillance et l'érosion des libertés. Mais on pourrait aussi mettre l'accent sur des facteurs liés au récit : « les ondes » font peur, la propagande pro-5G, par son côté ridicule et exagéré (les opposants assimilés aux Amish…), a braqué beaucoup de monde, la tentation de simplifier les problèmes complexes à une seule cause (la 5G cause le cancer, le réchauffement planétaire, et fait disparaitre la vie privée) est toujours forte. Ce sont probablement des raisons de ce genre qui expliquent le « succès » de la controverse sur la 5G. La 4G avait suscité le même genre de controverses, bien oubliées aujourd'hui, et sans doute pour les mêmes raisons.

D'autres sujets ont vu des controverses animées, mais pas forcément aussi spectaculaires. Si la technologie de la chaîne de blocs a connu un certain succès médiatique, c'était en bonne partie à cause de la réputation sulfureuse du Bitcoin, réputation soigneusement entretenue par les médias. On n'a toutefois pas vu, contrairement au cas de la 5G, de manifestations de rue ou de déclarations de députés sur la chaîne de blocs.

Encore moins de succès pour des sujets pourtant cruciaux comme la domination de certains acteurs privés du logiciel sur des services publics essentiels. C'est ainsi que les différents accords étatiques avec Microsoft, pour l'éducation, la santé ou pour les armées n'ont suscité que l'intérêt d'une poignée de militants libristes alors que ces accords structurent le fonctionnement de l'État. Mais ces controverses sont moins spectaculaires et permettent moins de postures « humanistes ».

[Article réalisé avec la participation de Francesca Musiani].


L'article seul

RFC 8915: Network Time Security for the Network Time Protocol

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : D. Franke (Akamai), D. Sibold, K. Teichel (PTB), M. Dansarie, R. Sundblad (Netnod)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ntp
Première rédaction de cet article le 1 octobre 2020


Ce nouveau RFC spécifie un mécanisme de sécurité pour le protocole de synchronisation d'horloges NTP. Une heure incorrecte peut empêcher, par exemple, de valider des certificats cryptographiques. Ou fausser les informations enregistrées dans les journaux. Ce mécanisme de sécurité NTS (Network Time Security) permettra de sécuriser le mode client-serveur de NTP, en utilisant TLS pour négocier les clés cryptographiques qui serviront à chiffrer le trafic NTP ultérieur..

La sécurité n'était pas jugée trop importante au début de NTP : après tout, l'heure qu'il est n'est pas un secret. Et il n'y avait pas d'application cruciale dépendant de l'heure. Aujourd'hui, les choses sont différentes. NTP est un protocole critique pour la sécurité de l'Internet. NTP a quand même un mécanisme de sécurité, fondé sur des clés secrètes partagées entre les deux pairs qui communiquent. Comme tout mécanisme à clé partagée, il ne passe pas à l'échelle, d'où le développement du mécanisme « Autokey » dans le RFC 5906. Ce mécanisme n'a pas été un grand succès et un RFC a été écrit pour préciser le cahier des charges d'une meilleure solution, le RFC 7384. La sécurité de l'Internet repose de plus en plus que l'exactitude de l'horloge de la machine. Plusieurs systèmes de sécurité, comme DNSSEC ou X.509 doivent vérifier des dates et doivent donc pouvoir se fier à l'horloge de la machine. Même criticité de l'horloge quand on veut coordonner une smart grid, ou tout autre processus industriel, analyser des journaux après une attaque, assurer la traçabilité d'opérations financières soumises à régulation, etc. Or, comme l'explique bien le RFC 7384, les protocoles de synchronisation d'horloge existants, comme NTP sont peu ou pas sécurisés. (On consultera également avec profit le RFC 8633 qui parle entre autre de sécurité.)

Sécuriser la synchronisation d'horloge est donc crucial aujourd'hui. Cela peut se faire par un protocole extérieur au service de synchronisation, comme IPsec, ou bien par des mesures dans le service de synchronisation. Les deux services les plus populaires sont NTP (RFC 5905) et PTP. Aucun des deux n'offre actuellement toutes les fonctions de sécurité souhaitées par le RFC 7384. Mais les protocoles externes ont un inconvénient : ils peuvent affecter le service de synchronisation. Par exemple, si l'envoi d'un paquet NTP est retardé car IKE cherche des clés, les mesures temporelles vont être faussées. Le paquet arrivera intact mais n'aura pas la même utilité.

Les menaces contre les protocoles de synchronisation d'horloge sont décrites dans le RFC 7384. Les objectifs de notre RFC sont d'y répondre, notamment :

  • Permettre à un client d'authentifier son maître, via X.509 tel que l'utilise TLS,
  • Protéger ensuite l'intégrité des paquets (via un MAC).
  • En prime, mais optionnel, assurer la confidentialité du contenu des paquets.
  • Empêcher la traçabilité entre les requêtes d'un même client (si un client NTP change d'adresse IP, un observateur passif ne doit pas pouvoir s'apercevoir qu'il s'agit du même client).
  • Et le tout sans permettre les attaques par réflexion qui ont souvent été un problème avec NTP.
  • Passage à l'échelle car un serveur peut avoir de très nombreux clients,
  • Et enfin performances (RFC 7384, section 5.7).

Rappelons que NTP dispose de plusieurs modes de fonctionnement (RFC 5905, section 3). Le plus connu et sans doute le plus utilisé est le mode client-serveur (si vous faites sur Unix un ntpdate ntp.nic.fr, c'est ce mode que vous utilisez). Mais il y aussi un mode symétrique, un mode à diffusion et le « mode » de contrôle (dont beaucoup de fonctions ne sont pas normalisées). Le mode symétrique est sans doute celui qui a le plus d'exigences de sécurité (les modes symétriques et de contrôle de NTP nécessitent notamment une protection réciproque contre le rejeu, qui nécessite de maintenir un état de chaque côté) mais le mode client-serveur est plus répandu, et pose des difficultés particulières (un serveur peut avoir beaucoup de clients, et ne pas souhaiter maintenir un état par client). Notre RFC ne couvre que le mode client-serveur. Pour ce mode, la solution décrite dans notre RFC 8915 est d'utiliser TLS afin que le client authentifie le serveur, puis d'utiliser cette session TLS pour générer la clé qui servira à sécuriser du NTP classique, sur UDP. Les serveurs NTP devront donc désormais également écouter en TCP, ce qu'ils ne font pas en général pas actuellement. La partie TLS de NTS (Network Time Security, normalisé dans ce RFC) se nomme NTS-KE (pour Network Time Security - Key Exchange). La solution à deux protocoles peut sembler compliquée mais elle permet d'avoir les avantages de TLS (protocole éprouvé) et d'UDP (protocole rapide).

Une fois qu'on a la clé (et d'autres informations utiles, dont les cookies), on ferme la session TLS, et on va utiliser la cryptographie pour sécuriser les paquets. Les clés sont dérivées à partir de la session TLS, suivant l'algorithme du RFC 5705. Quatre nouveaux champs NTP sont utilisés pour les paquets suivants (ils sont présentés en section 5), non TLS. Dans ces paquets se trouve un cookie qui va permettre au serveur de vérifier le client, et de récupérer la bonne clé. Les cookies envoyés du client vers le serveur et en sens inverse sont changés à chaque fois, pour éviter toute traçabilité, car ils ne sont pas dans la partie chiffrée du paquet. Notez que le format des cookies n'est pas spécifié par ce RFC (bien qu'un format soit suggéré en section 6). Pour le client, le cookie est opaque : on le traite comme une chaîne de bits, sans structure interne.

On a dit que NTS (Network Time Security) utilisait TLS. En fait, il se restreint à un profil spécifique de TLS, décrit en section 3. Comme NTS est un protocole récent, il n'y a pas besoin d'interagir avec les vieilles versions de TLS et notre RFC impose donc TLS 1.3 (RFC 8446) au minimum, ALPN (RFC 7301), les bonnes pratiques TLS du RFC 7525, et les règles des RFC 5280 et RFC 6125 pour l'authentification du serveur.

Passons ensuite au détail du protocole NTS-KE (Network Time Security - Key Establishment) qui va permettre, en utilisant TLS, d'obtenir les clés qui serviront au chiffrement symétrique ultérieur. Il est spécifié dans la section 4 du RFC. Le serveur doit écouter sur le port ntske (4460 par défaut). Le client utilise ALPN (RFC 7301) pour annoncer qu'il veut l'application ntske/1. On établit la session TLS, on échange des messages et on raccroche (l'idée est de ne pas obliger le serveur à garder une session TLS ouverte pour chacun de ses clients, qui peuvent être nombreux).

Le format de ces messages est composé d'un champ indiquant le type du message, de la longueur du message, des données du message, et d'un bit indiquant la criticité du type de message. Si ce bit est à 1 et que le récepteur ne connait pas ce type, il raccroche. Les types de message actuels sont notamment :

  • Next Protocol Negotiation (valeur 1) qui indique les protocoles acceptés (il n'y en a qu'un à l'heure actuelle, NTP, mais peut-être d'autres protocoles comme PTP suivront, la liste est dans un registre IANA),
  • Error (valeur 2) qui indique… une erreur (encore un registre IANA de ces codes d'erreur, qui seront sans doute moins connus que ceux de HTTP),
  • AEAD Algorithm Negotiation (valeur 3) ; NTS impose l'utilisation du chiffrement intègre (AEAD pour Authenticated Encryption with Associated Data) et ce type de message permet de choisir un algorithme de chiffrement intègre parmi ceux enregistrés,
  • New Cookie (valeur 5), miam, le serveur envoie un cookie, que le client devra renvoyer (sans chercher à la comprendre), ce qui permettra au serveur de reconnaitre un client légitime ; le RFC recommande d'envoyer plusieurs messages de ce type, pour que le client ait une provision de cookies suffisante,
  • Server Negotiation (valeur 6) (et Port Negotiation, valeur 7), pour indiquer le serveur NTP avec lequel parler de façon sécurisée, serveur qui n'est pas forcément le serveur NTS-KE.

D'autres types de message pourront venir dans le futur, cf. le registre.

Une fois la négociation faite avec le protocole NTS-KE, tournant sur TLS, on peut passer au NTP normal, avec le serveur indiqué. Comme indiqué plus haut, quatre champs supplémentaires ont été ajoutés à NTP pour gérer la sécurité. Ils sont présentés dans la section 5 de notre RFC. Les clés cryptographiques sont obtenues par la fonction de dérivation (HKDF) du RFC 8446, section 7.5 (voir aussi le RFC 5705). Les clés du client vers le serveur sont différentes de celles du serveur vers le client (ce sont les clés c2s et s2c dans l'exemple avec ntsclient montré plus loin).

Les paquets NTP échangés ensuite, et sécurisés avec NTS, comporteront l'en-tête NTP classique (RFC 5905, section 7.3), qui ne sera pas chiffré (mais sera authentifié), et le paquet original chiffré dans un champ d'extension (cf. RFC 5905, section 7.5, et RFC 7822). Les quatre nouveaux champs seront :

  • L'identifiant du paquet (qui sert à détecter le rejeu), il sera indiqué (cf. section 5.7) dans la réponse du serveur, permetant au client de détecter des attaques menées en aveugle par des malfaisants qui ne sont pas situés sur le chemin (certaines mises en œuvre de NTP utilisaient les estampilles temporelles pour cela, mais elles sont courtes, et en partie prévisibles),
  • Le cookie,
  • La demande de cookies supplémentaires,
  • Et le principal, le champ contenant le contenu chiffré du paquet NTP original.

On a vu que le format des cookies n'était pas imposé. Cela n'affecte pas l'interopérabilité puisque, de toute façon, le client n'est pas censé comprendre les cookies qu'il reçoit, il doit juste les renvoyer tels quels. La section 6 décrit quand même un format suggéré. Elle rappelle que les cookies de NTS sont utilisés à peu près comme les cookies de session de TLS (RFC 5077). Comme le serveur doit pouvoir reconnaitre les bons cookies des mauvais, et comme il est préférable qu'il ne conserve pas un état différent par client, le format suggéré permet au serveur de fabriquer des cookies qu'il pourra reconnaitre, sans qu'un attaquant n'arrive à en fabriquer. Le serveur part pour cela d'une clé secrète, changée de temps en temps. Pour le cas un peu plus compliqué où un ou plusieurs serveurs NTP assureraient le service avec des cookies distribués par un serveur NTS-KE séparé, le RFC recommande que les clés suivantes soient dérivées de la première, par un cliquet et la fonction de dérivation HKDF du RFC 5869.

Quelles sont les mises en œuvre de NTS à l'heure actuelle ? La principale est dans chrony (mais dans le dépôt git seulement, la version 3.5 n'a pas encore NTS). chrony est écrit en C et comprend un client et un serveur. NTS est compilé par défaut (cela peut être débrayé avec l'option --disable-nts du script ./configure), si et seulement si les bibliothèques sur lesquelles s'appuie chrony (comme la bibliothèque cryptographique nettle) ont tout ce qu'il faut. Ainsi, sur une Ubuntu stable, ./configure n'active pas l'option NTS alors que ça marche sur une Debian instable (sur cette plate-forme, pensez à installer les paquetages bison et asciidoctor, ./configure ne vérifie pas leur présence). Cela se voit dans cette ligne émise par ./configure (le +NTS) :

%  ./configure
   ...
   Checking for SIV in nettle : No
   Checking for SIV in gnutls : Yes
   Features : +CMDMON +NTP +REFCLOCK +RTC -PRIVDROP -SCFILTER -SIGND +ASYNCDNS +NTS +READLINE +SECHASH +IPV6 -DEBUG
  

Autre serveur ayant NTS, NTPsec. (Développement sur Github.) Écrit en C. C'est ce code qui est utilisé pour deux serveurs NTS publics, ntp1.glypnod.com:123 et ntp2.glypnod.com:123 (exemples plus loin).

Il y a également une mise en œuvre de NTS en FPGA. La même organisation gère deux serveurs NTP publics, nts.sth1.ntp.se:4460 et nts.sth2.ntp.se:4460.

Dernier serveur public ayant NTS, celui de Cloudflare, time.cloudflare.com. Il utilise sans doute nts-rust, écrit par Cloudflare (en Rust).

Les autres mises en œuvre de NTS semblent assez expérimentales, plutôt de la preuve de concept pas très maintenue. Il y a :

Voici un exemple avec ntsclient et les serveurs publics mentionnés plus haut. Vérifiez que vous avez un compilateur Go puis :

% git clone https://gitlab.com/hacklunch/ntsclient.git
% make
% ./ntsclient --server=ntp1.glypnod.com:123 -n     
Network time on ntp1.glypnod.com:123 2020-07-14 09:01:08.684729607 +0000 UTC. Local clock off by -73.844479ms.
   

(Le serveur devrait migrer bientôt vers le port 4460.) Si on veut voir plus de détails et toute la machinerie NTS (le type de message 4 est AEAD, le type 5 le cookie, l'algorithme 15 est AEAD_AES_SIV_CMAC_256) :

% ./ntsclient --server=ntp1.glypnod.com:123 -n --debug  
Conf: &main.Config{Server:"ntp1.glypnod.com:123", CACert:"", Interval:1000}
Connecting to KE server ntp1.glypnod.com:123
Record type 1
Critical set
Record type 4
Record type 5
Record type 5
Record type 5
Record type 5
Record type 5
Record type 5
Record type 5
Record type 5
Record type 0
Critical set
NTSKE exchange yielded:
  c2s: ece2b86a7e86611e6431313b1e45b02a8665f732ad9813087f7fc773bd7f2ff9
  s2c: 818effb93856caaf17e296656a900a9b17229e2f79e69f43f9834d3c08194c06
  server: ntp1.glypnod.com
  port: 123
  algo: 15
  8 cookies:
  [puis les cookies]

Notez que les messages de type 5 ont été répétés huit fois, car, conformément aux recommandations du RFC, le serveur envoie huit cookies. Notez aussi que si vous voulez analyser avec Wireshark, il va par défaut interpréter ce trafic sur le port 123 comme étant du NTP et donc afficher n'importe quoi. Il faut lui dire explicitement de l'interpréter comme du TLS (Decode as...). On voit le trafic NTS-KE en TCP puis du trafic NTP plus classique en UDP.

Enfin, la section 8 du RFC détaille quelques points de sécurité qui avaient pu être traités un peu rapidement auparavant. D'abord, le risque de dDoS. NTS, décrit dans notre RFC, apporte une nouveauté dans le monde NTP, la cryptographie asymétrique. Nécessaire pour l'authentification du serveur, elle est bien plus lente que la symétrique et, donc, potentiellement, un botnet pourrait écrouler le serveur sous la charge, en le forçant à faire beaucoup d'opérations de cryptographie asymétrique. Pour se protéger, NTS sépare conceptuellement l'authentification (faite par NTS-KE) et le service NTP à proprement parler. Ils peuvent même être assurés par des serveurs différents, limitant ainsi le risque qu'une attaque ne perturbe le service NTP.

Lorsqu'on parle de NTP et d'attaques par déni de service, on pense aussi à l'utilisation de NTP dans les attaques par réflexion et amplification. Notez qu'elles utilisent en général des fonctions non-standard des serveurs NTP. Le protocole lui-même n'a pas forcément de défauts. En tout cas, NTS a été conçu pour ne pas ajouter de nouvelles possibilités d'amplification. Tous les champs envoyés par le serveur ont une taille qui est au maximum celle des champs correspondants dans la requête du client. C'est par exemple pour cela que le client doit envoyer un champ de demande de cookie, rempli avec des zéros, pour chaque cookie supplémentaire qu'il réclame. Cela peut sembler inutile, mais c'est pour décourager toute tentative d'amplification.

Cette section 8 discute également la vérification du certificat du serveur. Bon, on suit les règles des RFC 5280 et RFC 6125, d'accord. Mais cela laisse un problème amusant : la date d'expiration du certificat. Regardons celui des serveurs publics cités plus haut, avec gnutls-cli :

% gnutls-cli ntp1.glypnod.com:123
Processed 126 CA certificate(s).
Resolving 'ntp1.glypnod.com:123'...
Connecting to '104.131.155.175:123'...
- Certificate type: X.509
- Got a certificate list of 2 certificates.
- Certificate[0] info:
 - subject `CN=ntp1.glypnod.com', issuer `CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US', serial 0x04f305691067ef030d19eb53bbb392588d07, RSA key 2048 bits, signed using RSA-SHA256, activated `2020-05-20 02:12:34 UTC', expires `2020-08-18 02:12:34 UTC', pin-sha256="lLj5QsLH8M8PjLSWe6SNlXv4fxVAyI6Uep99RWskvOU="
	Public Key ID:
		sha1:726426063ea3c388ebcc23f913b41a15d4ef38b0
		sha256:94b8f942c2c7f0cf0f8cb4967ba48d957bf87f1540c88e947a9f7d456b24bce5
	Public Key PIN:
		pin-sha256:lLj5QsLH8M8PjLSWe6SNlXv4fxVAyI6Uep99RWskvOU=

- Certificate[1] info:
 - subject `CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US', issuer `CN=DST Root CA X3,O=Digital Signature Trust Co.', serial 0x0a0141420000015385736a0b85eca708, RSA key 2048 bits, signed using RSA-SHA256, activated `2016-03-17 16:40:46 UTC', expires `2021-03-17 16:40:46 UTC', pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="
- Status: The certificate is trusted. 
- Description: (TLS1.3-X.509)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
- Options:
- Handshake was completed    
  

On a un classique certificat Let's Encrypt, qui expire le 18 août 2020. Cette date figure dans les certificats pour éviter qu'un malveillant qui aurait mis la main sur la clé privée correspondant à un certificat puisse profiter de son forfait éternellement. Même si la révocation du certificat ne marche pas, le malveillant n'aura qu'un temps limité pour utiliser le certificat. Sauf que la vérification que cette date d'expiration n'est pas atteinte dépend de l'horloge de la machine. Et que le but de NTP est justement de mettre cette horloge à l'heure… On a donc un problème d'œuf et de poule : faire du NTP sécurisé nécessite NTS, or utiliser NTS nécessite de vérifier un certificat, mais vérifier un certificat nécessite une horloge à l'heure, donc que NTP fonctionne. Il n'y a pas de solution idéale à ce problème. Notre RFC suggère quelques trucs utiles, comme :

  • Prendre un risque délibéré en ne vérifiant pas la date d'expiration du certificat,
  • Chercher à savoir si l'horloge est correcte ou pas ; sur un système d'exploitation qui dispose de fonctions comme ntp_adjtime, le résultat de cette fonction (dans ce cas, une valeur autre que TIME_ERROR) permet de savoir si l'horloge est correcte,
  • Permettre à l'administrateur système de configurer la validation des dates des certificats ; s'il sait que la machine a une horloge matérielle sauvegardée, par exemple via une pile, il peut demander une validation stricte,
  • Utiliser plusieurs serveurs NTP et les comparer, dans l'espoir qu'ils ne soient pas tous compromis (cf. RFC 5905, section 11.2.1).

Comme toujours avec la cryptographie, lorsqu'il existe une version non sécurisée d'un protocole (ici, le NTP traditionnel), il y a le risque d'une attaque par repli, qui consiste à faire croire à une des deux parties que l'autre partie ne sait pas faire de la sécurité (ici, du NTS). Ce NTP stripping est possible si, par exemple, le client NTP se rabat en NTP classique en cas de problème de connexion au serveur NTS-KE. Le RFC recommande donc que le repli ne se fasse pas par défaut, mais uniquement si le logiciel a été explicitement configuré pour prendre ce risque.

Enfin, si on veut faire de la synchronisation d'horloges sécurisée, un des problèmes les plus difficiles est l'attaque par retard (section 11.5 du RFC). Le MAC empêche un attaquant actif de modifier les messages mais il peut les retarder, donnant ainsi au client une fausse idée de l'heure qu'il est réellement (RFC 7384, section 3.2.6 et Mizrahi, T., « A game theoretic analysis of delay attacks against time synchronization protocols », dans les Proceedings of Precision Clock Synchronization for Measurement Control and Communication à ISPCS 2012). Ce dernier article n'est pas en ligne mais, heureusement, il y a Sci-Hub (DOI 10.1109/ISPCS.2012.6336612).

Les contre-mesures possibles ? Utiliser plusieurs serveurs, ce que fait déjà NTP. Faire attention à ce qu'ils soient joignables par des chemins différents (l'attaquant devra alors contrôler plusieurs chemins). Tout chiffrer avec IPsec, ce qui n'empêche pas l'attaque mais rend plus difficile l'identification des seuls paquets de synchronisation.

Revenons au mode symétrique de NTP, qui n'est pas traité par notre RFC. Vous vous demandez peut-être comment le sécuriser. Lors des discussions à l'IETF sur NTS, il avait été envisagé d'encapsuler tous les paquets dans DTLS mais cette option n'a finalement pas été retenue. Donc, pour le symétrique, la méthode recommandée est d'utiliser le MAC des RFC 5905 (section 7.3) et RFC 8573. Et le mode à diffusion ? Il n'y a pas pour l'instant de solution à ce difficile problème.

Et la vie privée (section 9) ? Il y a d'abord la question de la non-traçabilité. On ne veut pas qu'un observateur puisse savoir que deux requêtes NTP sont dues au même client. D'où l'idée d'envoyer plusieurs cookies (et de les renouveler), puisque, autrement, ces identificateurs envoyés en clair trahiraient le client, même s'il a changé d'adresse IP.

Et la confidentialité ? Le chiffrement de l'essentiel du paquet NTP fournit ce service, les en-têtes qui restent en clair, comme le cookie, ne posent pas de problèmes de confidentialité particuliers.

Un petit mot maintenant sur l'historique de ce RFC. Le projet initial était plus ambitieux (cf. l'Internet-Draft draft-ietf-ntp-network-time-security). Il s'agissait de développer un mécanisme abstrait, commun à NTP et PTP/IEEE 1588 (alors que ce RFC 8915 est spécifique à NTP). Un autre groupe de travail IETF TICTOC continue de son côté mais ne fait plus de sécurité.

Si vous voulez des bonnes lectures sur NTS, autres que le RFC, il y a un article sur la sécurité NTP à la conférence ISPCS 17, « New Security Mechanisms for Network Time Synchronization Protocols ») (un des auteurs de l'article est un des auteurs du RFC). C'est un exposé général des techniques de sécurité donc il inclut PTP mais la partie NTP est presque à jour, à part la suggestion de DTLS pour les autres modes, qui n'a finalement pas été retenue). Les supports du même article à la conférence sont sur Slideshare. Et cet article est résumé dans l'IETF journal de novembre 2017, volume 13 issue 2. Il y a aussi l'article de l'ISOC, qui résume bien les enjeux.


Téléchargez le RFC 8915


L'article seul

Fiche de lecture : Mikrodystopies

Auteur(s) du livre : François Houste
Éditeur : C&F Éditions
9-782376-620112
Publié en 2020
Première rédaction de cet article le 30 septembre 2020


Beaucoup de gens sur Twitter ont déjà lu les Mikrodystopies, ces très courtes histoires d'un futur techniquement avancé mais pas forcément très heureux. Les voici réunies dans un livre, le premier livre de fiction publié chez C&F Éditions.

Des exemples de Mikrodystopies ? « Le robot de la bibliothèque municipale aurait été l'assistant idéal s'il n'avait pas pris l'initiative de censurer certains ouvrages de science-fiction qu'il jugeait offensants. » Ou bien « La licence du logicielle était claire : pour chaque faute d'orthographe corrigée, le romancier devait reverser une partie de ses droits d'auteur à la société qui avait créé ce traitement de texte. » Ou encore, en temps de pandémie, « Les robots de l'entreprise firent valoir leur droit de retrait, invoquant les pare-feu insuffisants du réseau informatique. ». Oui, je l'avais dit, ce sont des courtes histoires, qui se tiennent dans les limites du nombre de caractères que permet Twitter, mais je trouve chacune d'elles pertinente, et mettant bien en évidence un problème de notre société et de son rapport avec la technique.

Fallait-il publier ces histoires que tout le monde peut lire sur Twitter ? Je vous laisse en juger mais, moi, cela m'a beaucoup plu de les découvrir ou de les redécouvrir sur mon canapé. Et en plus le livre est beau comme l'explique Nicolas Taffin.


L'article seul

Fiche de lecture : Technologies partout, démocratie nulle part

Auteur(s) du livre : Irénée Régnauld, Yaël Benayoun
Éditeur : FYP Éditions
978-2-36405-202-4
Publié en 2020
Première rédaction de cet article le 27 septembre 2020


La question de la démocratie face aux choix techniques est une question cruciale pour nos sociétés où la technique joue un rôle si important. À une extrémité, il y a des gens qui défendent l'idée que le peuple est vraiment trop con et qu'il faudrait le priver de tous les choix techniques. À une autre, des archaïques qui sont contre toute nouveauté par principe. Et le tout dans une grande confusion où les débats ayant une forte composante technique sont noyés dans des affirmations non étayées, voire franchement fausses, ou même carrément ridicules. Faut-il jeter l'éponge et en déduire qu'il ne pourra jamais y avoir de vrai débat démocratique sur un sujet technique ? Les auteurs de ce livre ne sont pas de cet avis et estiment qu'il est possible de traiter démocratiquement ces sujets. Reste à savoir comment, exactement.

Il y a trois parties importantes dans ce livre : une dénonciation d'une certaine propagande « pro-progrès » qui essaie de saturer l'espace de débat en répétant en boucle qu'on ne peut pas s'opposer au progrès technique, puis une analyse critique des solutions qui sont souvent proposées pour gérer de manière démocratique les débats liés aux sujets techniques, et enfin une exploration des solutions possibles dans le futur. Commençons par la première partie, c'est la plus facile et celle avec laquelle je suis le plus d'accord. En effet, les technolâtres ou techno-béats pratiquent une propagande tellement grossière qu'il serait difficile d'être en sympathie avec eux. Cette propagande avait été magnifiquement illustrée par la sortie raciste d'un président de la république qui avait estimé que tout opposant était forcément un Amish. (Et puis ce n'est pas risqué de s'en prendre à eux : les Amish ne feront pas de fatwa contre ceux qui critiquent leur religion.) Le livre donne plusieurs exemples amusants de ce discours non seulement anti-démocratique, mais également anti-politique puisqu'il prétend qu'il n'y a pas le choix, que le déploiement de telle ou telle technologie n'est tout simplement pas discutable. Les cas de tel discours « on n'arrête pas le progrès » sont innombrables, parfois matinés de « il faut rattraper notre retard » (qui semble indiquer qu'on peut arrêter le progrès, après tout, ce qu'ont hélas bien réussi les ayant-tous-les-droits avec le pair-à-pair).

En pratique, quel que soit le discours des technolâtres, il y a toujours eu des oppositions et des critiques. Mais, attention, les auteurs du livre mettent un peu tout dans le même sac. Quand des salariés travaillant dans les entrepôts d'Amazon protestent contre leurs conditions de travail, cela n'a pas grand'chose à voir avec la technique, l'Internet ou le Web : ce sont des travailleurs qui luttent contre l'exploitation, point. Le fait que leur entreprise soit considérée comme étant de la « tech » n'y change rien. De même les luddites ne luttaient pas tant contre « la machine » que contre le chômage et la misère qui allaient les frapper (le progrès technique n'étant pas toujours synonyme de progrès social). Assimiler les anti-Linky et les chauffeurs d'Uber qui demandent à être reconnus comme salariés (ce qu'ils sont, de facto), c'est mettre sous un même parapluie « anti-tech » des mouvements très différents.

À noter aussi que, paradoxalement, les auteurs traitent parfois la technique comme un être autonome, en affirmant que telle ou telle technique va avoir telles conséquences. La relation d'une technique avec la société où elle va être déployée est plus complexe que cela. La société crée telle ou telle technique, et elle va ensuite l'utiliser d'une certaine façon. La technique a sa propre logique (on ne pourra pas faire des centrales nucléaires en circuit court et gérées localement…) mais personnaliser une technique en disant qu'elle va avoir telle ou telle conséquence est dangereux car cela peut dépolitiser le débat. La voiture ne s'est pas déployée toute seule, ce sont des humains qui ont décidé, par exemple, de démanteler les lignes de chemin de fer au profit du tout-voiture.

Dans une deuxième partie, les auteurs examinent les réponses qui sont souvent données face aux critiques de la technologie. Par exemple, on entend souvent dire qu'il faut « une tech éthique ». L'adjectif « éthique » est un de ces termes flous et vagues qui sont mis à toutes les sauces. Toutes les entreprises, même les plus ignobles dans leurs pratiques, se réclament de l'éthique et ont des « chartes éthiques », des séminaires sur l'éthique, etc. Et, souvent, les discussions « éthiques » servent de rideau de fumée : on discute sans fin d'un détail « éthique » en faisant comme si tout le reste du projet ne pose aucun problème. Les auteurs citent l'exemple des panneaux publicitaires actifs qui captent les données personnelles des gens qui passent devant. Certes, il y a eu un débat sur l'éthique de ce flicage, et sur sa compatibilité avec les différentes lois qui protègent les données personnelles, mais cela a servi à esquiver le débat de fond : ces panneaux, avec leur consommation énergétique, et leur attirance qui capte l'attention de passants qui n'ont rien demandé sont-ils une bonne idée ? (Sans compter, bien sûr, l'utilité de la publicité dans son ensemble.)

Un autre exemple d'un débat éthique qui sert de distraction est celui des décisions de la voiture autonome au cas où elle doive choisir, dans la fraction de seconde précédant un accident, quelle vie mettre en danger s'il n'y a pas de solution parfaite. Les auteurs tombent d'ailleurs dans le piège, en accordant à ce problème du tramway, bien plus d'attention qu'il n'en mérite. Déjà, le problème n'existe pas pour les humains qui n'ont, en général, pas asez d'informations fiables pour peser le pour et le contre de manière rationnelle dans les instants avant l'accident. Pour cela, le problème du tramway n'est qu'une distraction de philosophe qui va le discuter gravement en prétendant qu'il réfléchit à des problèmes importants. (Comme le dit un T-shirt « I got 99 problems and the trolley problem ain't one ».) Même pour la voiture, qui a sans doute davantage d'informations que le conducteur, et peut réfléchir vite et calmement avant l'accident, dans quel cas aura-t-on vraiment un dilemme moral aussi simple et bien posé ? Discuter longuement et gravement de ce problème artificiel et irréaliste ne sert qu'à distraire des questions posées par l'utilisation de la voiture. (Je vous recommande l'excellente partie du roman « First Among Sequels » (dans la série des aventures de Thursday Next), où l'héroïne est à bord du bateau nommé « Moral Dilemma ».)

C'est également dans cette partie que les auteurs discutent le plus longuement du cas de la 5G, tarte à la crème des débats politico-techniques du moment. Je regrette que cette partie ne discute pas sérieusement les arguments présentés (à part celui de la santé, écarté à juste titre), et reprenne l'idée que la 5G va être « un sujet majeur qui engage toute la société », point de vue partagé par les partisans et les adversaires de la 5G, mais qui est contestable.

Enfin, une dernière partie du livre est consacrée aux solutions, et aux pistes pour dépasser l'injonction à déployer tout changement présenté comme « le progrès ». C'est à la fois la plus intéressante du livre et la plus délicate. Car si beaucoup de gens (comme moi) trouvent ridicule la propagande technobéate à base de blockchain digitale avec de l'IA et des startups, il y aura moins de consensus pour les solutions. D'autant plus qu'il ne s'agit pas de retourner au Moyen-Âge mais au contraire d'inventer du nouveau, sans pouvoir s'appuyer sur un passé (souvent mythifié, en prime). D'abord, les auteurs plaident pour une reprise de la confiance en soi : face à la saturation brutale du discours politique par des fausses évidences martelées en boucle (« il n'y a pas le choix », « on ne va pas retourner à la bougie quand même », « les citoyens sont trop cons pour décider »), les auteurs plaident pour une réaffirmation de l'importance mais aussi de la possibilité de la démocratie. Changer le monde est possible, la preuve, c'est déjà arrivé avant. (Un rappel que j'aime bien : la Sécurité sociale a été instaurée en France dans un pays ruiné par la guerre. Et aujourd'hui, alors que la guerre est loin et qu'on a fait d'innombrables progrès techniques depuis, elle ne serait plus réaliste ?).

Ensuite, il faut débattre des technologies et de leur intérêt. Il ne s'agit pas de tout refuser par principe (ce qui serait intellectuellement plus simple) mais de pouvoir utiliser son intelligence à dire « ça, OK, ça, j'hésite et ça je n'en veux pas ». Les auteurs estiment qu'il faut évaluer si une nouvelle technologie, par exemple, va favoriser les tendances autoritaires ou au contraire la démocratie.

Et, là, c'est un problème. Car les conséquences du déploiement d'une technologie sont souvent surprenantes, y compris pour leurs auteurs. Et elles varient dans le temps. Il n'est pas sûr du tout que des débats effectués avant le déploiement de l'Internet, par exemple, aient prévu ce qui allait se produire, d'autant plus que rien n'est écrit d'avance : le Facebook d'aujourd'hui, par exemple, n'était pas en germe dans l'Internet des années 1980.

Les auteurs mettent en avant l'expériences des « conférences citoyennes », où on rassemble un certain nombre de citoyens autour d'une thématique précise. Dans certains cas, ces citoyens sont tirés au sort. Si ce principe peut faire ricaner bêtement, il a l'avantage que les personnes choisies ont la possibilité d'apprendre sur le sujet traité.

En effet, je pense qu'une des principales limites de la démocratie représentative est le fait qu'il y a le même droit de vote pour la personne qui a pris le temps de se renseigner sur un sujet, de discuter et d'apprendre, que pour la personne qui n'a même pas vu une vidéo YouTube sur le sujet. Cette limite est particulièrement gênante dans le cas des questions ayant une forte composante technique. C'est pour cela que des sondages comme « pensez-vous que la chloroquine soit efficace contre la Covid-19 ? » (un tel sondage a bien eu lieu…) sont absurdes, pas tant parce que les sondés ne sont pas médecins que parce qu'on n'avait aucune information sur les efforts qu'ils avaient fait pour apprendre. Une décision, ou même simplement une discussion, sur un sujet technique, nécessite en effet, pas forcément d'être professionnel du métier (ce serait verser dans la technocratie) mais au moins qu'on a acquis des connaissances sur le sujet. Il me semble que cette exigence de savoir, très importante, est absente de ce livre. Ce manque de connaissances de base se paie lourdement, par exemple dans les débats sur la 5G, où on lit vraiment n'importe quoi (dans les deux camps, d'ailleurs). Je précise d'ailleurs qu'à mon avis, ce n'est pas seulement un problème chez les citoyens, c'est aussi le cas chez les professionnels de la politique. Notons que pour le cas particulier des protocoles Internet, le RFC 8890 couvre en détail cette question. Il faut évidemment que les citoyens décident, mais comment ?

Cette partie sur les propositions concrètes se termine avec cinq intéressants récits d'expériences réelles de participation de citoyens et de citoyennes à la délibération sur des sujets techniques. De quoi montrer que le futur n'est pas décidé d'avance et qu'il dépend de nous.


L'article seul

Fiche de lecture : La guerre des Russes blancs

Auteur(s) du livre : Jean-Jacques Marie
Éditeur : Tallandier
979-10-2102280-5
Publié en 2017
Première rédaction de cet article le 26 septembre 2020


Une étude détaillée d'un des camps de la Guerre civile russe, les blancs. Qui étaient-ils, qu'ont-ils fait, et pourquoi ont-ils perdu ?

Après la révolution bolchevique, qui a vu relativement peu de violences, une guerre civile impitoyable démarre entre les Rouges (les bolcheviques) et les Blancs (les tsaristes). Évidemment, c'est plus compliqué que cela : il y a plus que deux camps, et tous les camps sont eux-mêmes divisés. Le terme « les Blancs » regroupe des organisations, des individus et des idéologies différentes, sans compter les groupes difficiles à classer comme celui de Makhno ou comme les Verts (qui n'ont rien à voir avec les écologistes d'aujourd'hui). Le livre est donc épais, car l'auteur a beaucoup à dire.

Les Blancs avaient dès le début un problème politique considérable : fallait-il affirmer qu'on luttait pour la démocratie, voire la république, ou au contraire assumer ses origines tsaristes et motiver ses troupes par des références au passé ? Les Blancs n'ont jamais vraiment réussi à trancher nettement. Leurs soutiens impérialistes comme la France insistaient pour que les chefs blancs tiennent un discours moderniste, rejetant la restauration pur et simple du tsarisme, et prétendant vouloir construire démocratie et élections libres. Et les paysans russes refusaient le retour des grands propriétaires terriens et, pour les gagner à la cause blanche, il ne fallait pas tenir de discours trop rétrograde. Des chefs blancs comme Dénikine tenaient en public un discours raisonnablement progressiste et présentaient des programmes tout à fait acceptables. Sincérité ou tactique ? Car, d'un autre coté, l'écrasante majorité des officiers blancs étaient très réactionnaires et ne voulaient que le retour intégral au système politique d'avant la révolution de février. Et de toute façon, beaucoup de chefs blancs étaient des aventuriers indisciplinés, qui voulaient juste de la baston et du pillage, et ne tenaient aucun compte de ce que pouvaient dire Dénikine ou Wrangel. Les Blancs n'ont donc jamais eu une politique claire et cohérente. Une même impossibilité de trancher est apparue au sujet des questions nationales, comme l'indépendance de la Finlande ; pris entre le désir d'avoir un maximum d'alliés, et leur nostalgie d'une Russie impériale « prison des peuples », les Blancs n'ont pas su utiliser les sentiments nationaux qui auraient pu être dirigés contre les Rouges.

Et puis il n'y avait pas un parti et une armée unique. Chaque groupe blanc avait son chef, ses troupes, ses sources de financement jalousement gardées. Comme dans le roman « La garde blanche » de Mikhaïl Boulgakov ou dans la BD « Corto Maltese en Sibérie » d'Hugo Pratt, les Blancs ont passé plus de temps à se déchirer, voire à se combattre, qu'à lutter contre les Rouges.

Rapidement, les pays impérialistes qui soutenaient les Blancs ont compris qu'il n'y avait pas d'espoir qu'ils triomphent, et ont petit à petit abandonné leurs alliés. Churchill, dont le rôle pendant la Seconde Guerre mondiale ne doit pas faire oublier que dans le reste de sa carrière politique, il a toujours été ultra-réactionnaire, et a commis d'innombrables erreurs graves de jugement, insiste pour que la Grande-Bretagne continue à s'obstiner à aider les Blancs, mais sans résultat. (J'ai appris dans ce livre que plusieurs officiers blancs, devenus « soldats de fortune », encadreront l'armée paraguayenne dans la guerre du Chaco.) La défaite des Blancs étant sans doute inévitable. Ce livre vous expliquera pourquoi, dans un excellent chapitre final de synthèse. (Les divisions des Blancs et leur manque de programme cohérent ne sont pas les seules explications.)


L'article seul

RFC 8883: ICMPv6 Errors for Discarding packets Due to Processing Limits

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : T. Herbert (Intel)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 25 septembre 2020


Dans l'Internet, un routeur est toujours autorisé à jeter un paquet quand il ne peut pas le traiter, parce que ses files d'attente sont pleines, par exemple. Après tout, à l'impossible, nul n'est tenu, et les protocoles de transport et d'application savent à quoi s'attendre, et qu'ils devront peut-être gérer ces paquets perdus. Mais un routeur peut aussi jeter un paquet parce que des caractéristiques du paquet rendent impossible le traitement. Dans ce cas, il serait sympa de prévenir l'émetteur du paquet, pour qu'il puisse savoir que ses paquets, quoique légaux, ne peuvent pas être traités par certains routeurs. Notre nouveau RFC crée donc plusieurs nouveaux messages ICMP pour signaler à l'émetteur d'un paquet IPv6 qu'il en demande trop au routeur, par les en-têtes d'extension IPv6 qu'il ajoute.

La section 1 du RFC commence par lister les cas où un routeur peut légitimement jeter des paquets IPv6, même si les ressources matérielles du routeur ne sont pas épuisées :

  • Voyons d'abord le cas des en-têtes d'extension pris individuellement. IPv6 permet d'ajouter aux paquets une chaîne d'en-têtes successifs (RFC 8200, section 4). Ces en-têtes peuvent être de taille variable (c'est le cas de Destination Options, qui peut contenir plusieurs options). Il n'y a pas de limite absolue à leur nombre, uniquement la contrainte qu'ils doivent tenir dans un datagramme, donc la taille de cette chaîne doit être inférieure à la MTU du chemin. Normalement, les routeurs ne regardent pas ces en-têtes (sauf Hop by Hop Options) mais certains équipements réseau le font (cf. RFC 7045). Si, par exemple, l'équipement a, dans son code, une limite du genre « maximum 100 octets par en-tête et au plus trois options dans les en-têtes à options », alors, il jettera les paquets excédant ces limites. (S'il n'a pas de limites, cela peut augmenter sa vulnérabilité à certaines attaques par déni de service.)
  • Il peut aussi y avoir une limite portant sur la taille totale de la chaîne, pour les mêmes raisons, et avec les mêmes conséquences.
  • Dans certains cas, les routeurs qui jettent le paquet ont tort, mais cela ne change rien en pratique : comme ils vont continuer à le faire, autant qu'ils puissent signaler qu'ils l'ont fait, ce qui est le but de ce RFC.

La section 2 du RFC définit donc six nouveaux codes pour indiquer les problèmes, à utiliser avec le type ICMP 4 (Parameter Problem, cf. RFC 4443, section 3.4). Petit rappel : les messages ICMP ont un type (ici, 4) et les messages d'erreur d'un même type sont différenciés par un code qui apporte des précisions. Ainsi, le type 1, Destination Unreachable, peut servir par exemple pour des messages d'erreur ICMP de code 1 (filtrage par décision délibérée), 4 (port injoignable), etc. Les codes de notre RFC sont dans le registre IANA. Les voici :

  • 5, en-tête suivant inconnu (Unrecognized Next Header type encountered by intermediate node) : normalement, les routeurs ne doivent pas rejeter les en-têtes inconnus, juste les passer tel quels mais, s'ils le font, qu'au moins ils l'indiquent, avec ce code. (On a vu que l'approche de ce RFC est pragmatique.)
  • 6, en-tête trop gros (Extension header too big).
  • 7, chaîne d'en-têtes trop longue (Extension header chain too long).
  • 8, trop d'en-têtes (Too many extension headers).
  • 9, trop d'options dans un en-tête (Too many options in extension header) : à envoyer si le nombre d'options dans, par exemple, l'en-tête Hop-by-hop options, est trop élevé. Petit rappel : certains en-têtes (Destination Options et Hop-by-hop Options) sont composites : ils comportent une liste d'une ou plusieurs options.
  • 10, option trop grosse (Option too big) : à envoyer si on rencontre une option de taille trop importante dans un en-tête comme Destination options.

Et la section 3 définit un nouveau code pour le type d'erreur Destination Unreachable, le code 8, en-têtes trop longs (Headers too long). Il a également été mis dans le registre IANA. Les messages utilisant ce code suivent le format du RFC 4884.

Et que fait-on quand on envoie ou reçoit des erreurs ICMP liées au traitement des en-têtes ? La section 4 du RFC rappelle les règles. D'abord, il faut évidemment suivre le RFC 4443, par exemple la limitation du rythme d'envoi des erreurs (RFC 4443, section 2.4f). Et, à la réception d'un message d'erreur ICMP, il est crucial de le valider (n'importe quelle machine sur l'Internet a pu générer ce message, en mentant sur son adresse IP source). Pour cela, on peut utiliser la portion du paquet original qui a été incluse dans le message d'erreur : il faut vérifier qu'elle correspond à une conversation en cours (connexion TCP existante, par exemple). Ensuite, il y a des règles spécifiques aux erreurs de ce RFC :

  • On n'envoie qu'une erreur ICMP, même si plusieurs problèmes étaient survenus pendant le traitement d'un paquet (par exemple trop d'en-têtes et un total trop long). La section 4.1 donne la priorité à suivre pour savoir quelle erreur privilégier.
  • À la réception, on peut ajuster son comportement en fonction de l'erreur signalée, par exemple envoyer moins d'en-têtes si l'erreur était le code 8, Too many extension headers. Si les en-têtes IPv6 ont été gérés par l'application, il faut la prévenir, qu'elle puisse éventuellement changer son comportement. Et s'ils ont été ajouté par le noyau, c'est à celui-ci d'agir différemment.

La section 5 rappelle un point d'ICMP qu'il vaut mieux garder en tête. ICMP n'est pas fiable. Les messages d'erreur ICMP peuvent se perdre, soit, comme tout paquet IP, parce qu'un routeur n'arrivait pas à suivre le rythme, soit parce qu'une middlebox sur le trajet jette tous les paquets ICMP (une erreur de configuration fréquente quand les amateurs configurent un pare-feu cf. RFC 8504). Bref, il ne faut pas compter que vous recevrez forcément les messages indiqués dans ce RFC, si vos paquets avec en-têtes d'extension ne sont pas transmis.

La même section 5 explique les motivations pour ce RFC : on constate une tendance à augmenter le nombre et la taille des en-têtes d'extension IPv6. Cela peut être pour faire du routage influencé par la source, pour de l'OAM, ou pour d'autres innovations récentes.

Comme indiqué au début, cette augmentation peut se heurter aux limites des routeurs. La section 5.2.3 donne des exemples concrets. Les routeurs ne sont pas du pur logiciel, beaucoup de fonctions sont mises dans du matériel spécialisé. Ainsi, les circuits de traitement des paquets peuvent ne pas avoir de notion de boucle. Pour traiter les en-têtes d'extension ou les options dans un en-tête, la solution évidente qu'est la boucle n'est pas disponible, et on fait donc un petit nombre de tests suivis d'un saut. Le nombre maximal de tests est donc limité.

Enfin, la section 6 de notre RFC discute des questions de sécurité. Il y a le problème du filtrage par les pare-feux (voir le RFC 4890) mais aussi le risque (assez lointain, je trouve) que l'observation de la génération de ces nouveaux messages d'erreur donnent des indications à un observateur sur le logiciel utilisé. C'est un problème commun à tous les choix optionnels. En tout cas, le RFC recommande que l'envoi de ces messages d'erreur soit configurable.

Actuellement, il ne semble pas qu'il existe déjà de mise en œuvre de ce RFC.


Téléchargez le RFC 8883


L'article seul

RFC 8901: Multi-Signer DNSSEC Models

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : S. Huque, P. Aras (Salesforce), J. Dickinson (Sinodun), J. Vcelak (NS1), D. Blacka (Verisign)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 25 septembre 2020


Aujourd'hui, il est courant de confier l'hébergement de ses serveurs DNS faisant autorité à un sous-traitant. Mais si vous avez, comme c'est recommandé, plusieurs sous-traitants et qu'en prime votre zone, comme c'est recommandé, est signée avec DNSSEC ? Comment s'assurer que tous les sous-traitants ont bien l'information nécessaire ? S'ils utilisent le protocole standard du DNS pour transférer la zone, tout va bien. Mais hélas beaucoup d'hébergeurs ne permettent pas l'utilisation de cette norme. Que faire dans ce cas ? Ce nouveau RFC explique les pistes menant à des solutions possibles.

Pourquoi est-ce que des hébergeurs DNS ne permettent pas d'utiliser la solution normalisée et correcte, les transferts de zone du RFC 5936 ? Il peut y avoir de mauvaises raisons (la volonté d'enfermer l'utilisateur dans un silo, en lui rendant plus difficile d'aller voir la concurrence) mais aussi des (plus ou moins) bonnes raisons :

  • Si l'hébergeur signe dynamiquement les données DNS,
  • Si l'hébergeur produit dynamiquement des données DNS (ce qui implique de les signer en ligne),
  • Si l'hébergeur utilise des trucs non-standards, par exemple pour mettre un CNAME à l'apex d'une zone.

Dans ces cas, le transfert de zones classique n'est pas une solution, puisqu'il ne permet pas de transmettre, par exemple, les instructions pour la génération dynamique de données.

Résultat, bien des titulaires de noms de domaine se limitent donc à un seul hébergeur, ce qui réduit la robustesse de leur zone face aux pannes… ou face aux conflits commerciaux avec leur hébergeur.

La section 2 de notre RFC décrit les modèles possibles pour avoir à la fois DNSSEC et plusieurs hébergeurs. Si aucune des trois raisons citées plus haut ne s'applique, le cas est simple : un hébergeur (qui peut être le titulaire lui-même, par exemple avec un serveur maître caché) signe la zone, et elle est transférée ensuite, avec clés et signatures, vers les autres. C'est tout simple. (Pour information, c'est par exemple ainsi que fonctionne .fr, qui a plusieurs hébergeurs en plus de l'AFNIC : les serveurs dont le nom comprend un « ext » sont sous-traités.)

Mais si une ou davantage des trois (plus ou moins bonnes) raisons citées plus haut s'applique ? Là, pas de AXFR (RFC 5936), il faut trouver d'autres modèles. (Et je vous préviens tout de suite : aucun de ces modèles n'est géré par les logiciels existants, il va falloir faire du devops.) Celui présenté dans le RFC est celui des signeurs multiples. Chaque hébergeur reçoit les données non-signées par un mécanime quelconque (par exemple son API) et les signe lui-même avec ses clés, plus exactement avec sa ZSK (Zone Signing Key). Pour que tous les résolveurs validants puissent valider ces signatures, il faut que l'ensemble des clés, le DNSKEY de la zone, inclus les ZSK de tous les hébergeurs de la zone. (Un résolveur peut obtenir les signatures d'un hébergeur et les clés d'un autre.) Comment faire en sorte que tous les hébergeurs reçoivent les clés de tous les autres, pour les inclure dans le DNSKEY qu'ils servent ? Il n'existe pas de protocole pour cela, et le problème n'est pas purement technique, il est également que ces hébergeurs n'ont pas de relation entre eux. C'est donc au titulaire de la zone d'assurer cette synchronisation. (Un peu de Python ou de Perl avec les API des hébergeurs…)

Il y a deux variantes de ce modèle : KSK unique (Key Signing Key) et partagée, ou bien KSK différente par hébergeur. Voyons d'abord la première variante, avec une seule KSK. Elle est typiquement gérée par le titulaire de la zone, qui est responsable de la gestion de la clé privée, et d'envoyer l'enregistrement DS à la zone parente. Par contre, chaque hébergeur a sa ZSK et signe les données. Le titulaire récupère ces ZSK (par exemple via une API de l'hébergeur) et crée l'ensemble DNSKEY, qu'il signe. (Le RFC note qu'il y a un cas particulier intéressant de ce modèle, celui où il n'y a qu'un seul hébergeur, par exemple parce que le titulaire veut garder le contrôle de la KSK mais pas gérer les serveurs de noms.)

Deuxième variante du modèle : chaque hébergeur a sa KSK (et sa ZSK). Il ouvre son API aux autres hébergeurs pour que chacun connaisse les ZSK des autres et puisse les inclure dans l'ensemble DNSKEY. Le titulaire doit récolter toutes les KSK, pour envoyer les DS correspondants à la zone parente. Le remplacement d'une KSK (rollover) nécessite une bonne coordination.

Dans ces deux modèles, chaque serveur faisant autorité connait toutes les ZSK utilisées, et un résolveur validant récupérera forcément la clé permettant la validation, quel que soit le serveur faisant autorité interrogé, et quelle que soit la signature que le résolveur avait obtenue (section 3 du RFC). À noter qu'il faut que tous les hébergeurs utilisent le même algorithme de signature (section 4 du RFC) puisque la section 2.2 du RFC 4035 impose de signer avec tous les algorithmes présents dans l'ensemble DNSKEY.

En revanche, les hébergeurs ne sont pas forcés d'utiliser le même mécanisme de déni d'existence (NSEC ou NSEC3, cf. RFC 7129). Chacun peut faire comme il veut (section 5 de notre RFC) puisqu'une réponse négative est toujours accompagnée de ses NSEC (ou NSEC3). Évidemment, si un hébergeur utilise NSEC et un autre NSEC3, le gain en sécurité de NSEC3 sera inutile.

Comme signalé plus haut, le remplacement (rollover) des clés, déjà une opération compliquée en temps normal, va être délicat. La section 6 du RFC détaille les procédures que l'on peut suivre dans les cas « une seule KSK » et « une KSK par hébergeur ».

La discussion plus haut supposait qu'il y avait deux clés, la KSK et la ZSK, ce qui est le mode le plus fréquent d'organisation des clés. Mais ce n'est pas obligatoire : on peut avec n'avoir qu'une seule clé (baptisée alors CSK, pour Common Signing Key). Dans ce cas, il n'y a qu'un seul modèle possible, chaque hébergeur a sa CSK. Cela ressemble au modèle « une KSK par hébergeur » : le titulaire de la zone doit récolter toutes les CSK et envoyer les DS correspondants à la zone parente (section 7 du RFC).

Cette configuration DNSSEC à plusieurs signeurs peut fonctionner avec les enregistrements CDS et CDNSKEY des RFC 7344 et RFC 8078 (section 8 de notre RFC). Dans le premier modèle « une seule KSK », le titulaire de la zone crée CDS et/ou CDNSKEY qu'il envoie à tous les hébergeurs avec les autres données. Dans le deuxième modèle « une KSK par hébergeur », il faut échanger les CDS et/ou CDNSKEY pour que chaque hébergeur ait les enregistrements des autres.

On voit que dans cette configuration, il est nécessaire de communiquer, au moins entre le titulaire de la zone et ses hébergeurs. Ces hébergeurs doivent fournir une API, typiquement de type REST. Notre RFC ne normalise pas une telle API mais sa section 9 indique les fonctions minimum qu'elle doit fournir :

  • Permettre de récupérer les enregistrements DNSKEY (pour obtenir la ZSK),
  • Pour le premier modèle (une seule KSK), permettre d'indiquer l'ensemble DNSKEY complet et signé,
  • Pour le deuxième modèle, permettre d'indiquer les ZSK des autres hébergeurs,
  • Et idem pour les CDS et CDNSKEY.

Autre problème pratique avec la co-existence de plusieurs hébergeurs DNS, qui signent eux-mêmes la zone, la taille des réponses. Comme il faut inclure toutes les ZSK dans l'ensemble DNSKEY, les réponses aux requêtes DNSKEY vont forcément être d'assez grande taille (section 10). Le RFC fait remarquer que les algorithmes cryptographiques utilisant les courbes elliptiques ont des clés plus courtes et que cela peut aider.

Enfin, dans la section 12, dédiée aux questions de sécurité restantes, le RFC note que ces mécanismes à plusieurs signeurs nécessitent d'avoir confiance dans chacun des signeurs. Au contraire, le système où le maître signe tout et transfère ensuite aux serveurs esclaves ne demande aucune confiance dans les hébergeurs.

Allez, un joli dessin pour terminer (trouvé ici) : dnssec-multi-provider.jpg.


Téléchargez le RFC 8901


L'article seul

RFC 8877: Guidelines for Defining Packet Timestamps

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : T. Mizrahi (Huawei Smart Platforms iLab), J. Fabini (TU Wien), A. Morton (AT&T Labs
Pour information
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 24 septembre 2020


De nombreux protocoles Internet contiennent un champ où se trouve une estampille temporelle (timestamp en anglais), une indication de date et d'heure. Mais chaque protocole a défini le format de cette estampille de son côté, il n'y a pas de format standard. Ce nouveau RFC essaie de mettre un peu d'ordre là-dedans en proposant aux concepteurs de futurs protocoles :

  • Trois formats standards, parmi lesquels choisir, pour avoir un format tout fait,
  • Des conseils pour les cas où un protocole définirait (ce qui est sans doute une mauvaise idée) un nouveau format.

Dans quels cas des protocoles contiennent dans leurs données une estampille temporelle ? Cela peut être bien sûr parce que le protocole est voué à distribuer de l'information temporelle, comme NTP (RFC 5905). Mais cela peut être aussi parce que le protocole a besoin d'indiquer le moment d'un événement, par exemple pour mesurer une latence (OWAMP, RFC 4656 ou les extensions à TCP du RFC 7323). La section 6 du RFC présente une liste non exhaustive de protocoles qui utilisent des estampilles temporelles, ce qui fournit d'autres exemples comme MPLS (RFC 6374), IPFIX (RFC 7011), TRILL (RFC 7456), etc. Il serait souhaitable que les formats de ces estampilles soient normalisés. Ainsi, utiliser le format de NTP dans un autre protocole permettrait facilement d'utiliser le temps NTP, sans perte de précision. Et la standardisation des formats permettait de les mettre en œuvre dans du matériel, comme les horloges. Bref, si vous concevez des protocoles réseau et qu'ils intègrent une information temporelle, lisez ce RFC.

Pour suivre la suite du RFC, il faut un peu de vocabulaire, rappelé en section 2. Notamment :

  • Erreur sur l'estampille : la différence entre une estampille et une horloge de référence. Elle est de zéro quand tout est parfaitement à l'heure, ce qui n'arrive évidemment jamais dans le monde réel.
  • Exactitude de l'estampille : la moyenne des erreurs.
  • Précision de l'estampille : l'écart-type des erreurs.
  • Résolution temporelle de l'estampille : le temps minimal qu'un format permet de représenter. Si on a un format texte HH:MM:SS (heures:minutes:secondes), la résolution sera de une seconde.
  • Période de bouclage : le temps au bout duquel on reviendra à la valeur de départ. C'est la fameuse bogue de l'an 2000 : si on stocke les années sur deux chiffres, la période de bouclage vaut cent ans. Si on stocke les estampilles sous forme d'un entier de 32 bits signé, et que la résolution est d'une seconde, cette période de bouclage est de 68 ans.

Les formats recommandés par le RFC sont décrits en section 4. Pourquoi trois formats plutôt qu'un seul ? Parce que tous les protocoles réseau n'ont pas forcément les mêmes contraintes en terme de taille du champ, de résolution temporelle, ou d'intégration avec d'autres protocoles (sur un système d'exploitation conçu pour des PC connectés à l'Internet, utiliser le format de NTP est sans doute le plus raisonnable, mais pour du matériel de métrologie complexe, celui de PTP peut être une meilleure idée).

D'abord, le grand classique, le format de NTP (RFC 5905, section 6). Il est très répandu sur l'Internet, et utilisé dans de nombreux protocoles (RFC 6374, RFC 4656, RFC 5357, et bien d'autres). Il stocke l'estampille sous forme d'un entier de 32 bits pour les secondes depuis l'epoch 1900, et d'un autre entier de 32 bits pour les fractions de seconde. Sa taille totale est de 64 bits, sa résolution de 2 puissance -32 seconde, soit 0,2 milliardièmes de seconde. Et sa période de bouclage est de 136 ans.

NTP a un autre format, sur seulement 32 bits, pour les cas où la taille compte, par exemple des objets contraints. Dans ce cas, le nombre de secondes et la fraction de seconde sont sur 16 bits chacun. Cela lui donne une période de bouclage très courte, seulement 18 heures.

Et le troisième format standard proposé est celui de PTP, dans sa version « tronquée » à 64 bits. Ce format est utilisé dans les RFC 6374, RFC 7456 ou RFC 8186. Il est surtout intéressant lorsqu'il faut interagir avec de l'instrumentation utilisant PTP. Sa résolution est d'une nanoseconde, sa période de bouclage est la même que celle de NTP mais comme son epoch est en 1970, cela remet le prochain bouclage à 2106.

(Vous noterez que notre RFC ne parle que des formats binaires pour représenter les estampilles temporelles. Il existe également des formats texte, notamment celui du RFC 3339, utilisé par exemple dans les RFC 5424, RFC 5646, RFC 6991, ou RFC 7493. Les formats de HTTP - en-têtes Date: et Last-Modified: - ainsi que l'Internet Message Format - IMF, RFC 5322 - n'utilisent hélas pas le RFC 3339.)

Deux exemples d'utilisation de ces formats binaires standards sont donnés dans notre RFC, aux sections 6.1 et 6.2, si vous êtes un ou une concepteur(trice) de protocoles qui veut inclure une estampille temporelle.

Mais, si, malgré les sages conseils du RFC, vous êtes l'auteur(e) d'un protocole et vous voulez quand même créer votre propre format binaire pour indiquer date et heure, y a-t-il des règles à suivre ? (À part la règle « ne le faites pas ».) Oui, la section 3 du RFC donne des indications (la plupart sont assez évidentes) :

  • Bien documenter les raisons pour lesquelles vous tenez absolument à votre format à vous,
  • indiquer évidemment la taille de chaque champ et la boutianité (ce sera du gros boutien par défaut),
  • indiquer les unités utilisées, et l'epoch,
  • documenter le moment du bouclage, et les solutions prévues pour quand il sera atteint,
  • et ne pas oublier de gérer les secondes intercalaires.

À propos de secondes intercalaires, que vous utilisiez un format à vous, ou bien la méthode recommandée d'un format existant, pensez aux aspects liés à la synchronisation des horloges entre elles (section 5 du RFC), sauf pour les cas d'horloges complètement isolées (mais les RFC sont écrits pour l'Internet, donc il est prévu de communiquer). Quel(s) protocole(s) utiliser, quelle référence de temps (UTC ? TAI ?), et comment gérer ces fameuses secondes intercalaires. Que faut-il faire si l'horloge recule, faut-il faire un changement brusque ou bien du smearing (cf. RFC 8633), etc.

Un avant-dernier détail : parfois, le format de l'estampille temporelle, et ses propriétés, sont décrits dans le protocole, ou dans un modèle formel, par exemple en YANG. C'est ce que fait OWAMP (RFC 4656) avec le champ donnant une estimation de l'erreur de mesure (section 4.1.2 du RFC 4656). Notre RFC nomme ces « méta » champs « champs de contrôle » et donne quelques règles à suivre quand on les utilise : extensibilité (on aura toujours besoin d'autre chose), taille (assez gros mais pas trop…), importance (obligatoire ou optionnel), catégorie (statique ou dynamique).

Enfin, il y a évidemment la question de la sécurité (section 9). Il est bien sûr obligatoire dans la description d'un protocole de fournir une analyse de sa sécurité (RFC 3552). Cela doit inclure les conséquences des estampilles temporelles sur la sécurité. Par exemple, de telles estampilles, si elles sont transmises en clair, peuvent renseigner un observateur sur les performances d'un réseau. Et, si elle ne sont pas protégées contre les modifications non autorisées (ce qui peut se faire, par exemple, avec un MAC), un attaquant peut fausser sérieusement le fonctionnement d'un protocole en changeant la valeur des estampilles.

Autre problème de sécurité, un attaquant actif qui retarderait délibérement les messages. Cela perturberait évidemment tout protocole qui utilise le temps. Et, contrairement à la modification des estampilles, cela ne peut pas se résoudre avec de la cryptographie. Enfin, la synchronisation des horloges est elle-même exposée à des attaques (RFC 7384). Si on déploie NTP sans précautions particulières, un attaquant peut vous injecter une heure incorrecte.


Téléchargez le RFC 8877


L'article seul

RFC 8906: A Common Operational Problem in DNS Servers: Failure To Communicate

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : M. Andrews (ISC), R. Bellis (ISC)
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 23 septembre 2020


Normalement, le protocole DNS est très simple : le client écrit au serveur, posant une question, et le serveur répond. Il peut répondre qu'il ne veut pas ou ne sait pas répondre, mais il le dit explicitement. Cela, c'est la théorie. En pratique, beaucoup de serveurs DNS bogués (ou, plus fréquemment, situés derrière une middlebox boguée) ne répondent pas du tout, laissant le client perplexe se demander s'il doit réeessayer différemment ou pas. Ce nouveau RFC documente le problème et ses conséquences. Il concerne surtout la question des serveurs faisant autorité.

(Cette absence de réponse est en général due, non pas aux serveurs DNS eux-même, qui sont la plupart du temps corrects de ce point de vue, mais plutôt à ces middleboxes codées avec les pieds et mal configurées, que certains managers s'obstinent à placer devant des serveurs DNS qui marcheraient parfaitement sans cela. Ainsi, on voit des pare-feux inutiles mis parce que « il faut un pare-feu, a dit l'auditeur » et qui bloquent tout ce qu'ils ne comprennent pas. Ainsi, par exemple, le pare-feu laissera passer les requêtes de type A mais pas celles de type NS, menant à une expiration du délai de garde. La section 4 de notre RFC détaille ces erreurs communes des middleboxes.)

Voici un exemple d'un service DNS bogué. Le domaine mabanque.bnpparibas est délégué à deux serveurs mal configurés (ou placés derrière une middlebox mal faite), sns6.bnpparibas.fr et sns5.bnpparibas.net :


% dig @sns6.bnpparibas.fr A mabanque.bnpparibas 

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @sns6.bnpparibas.fr A mabanque.bnpparibas
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57381
;; flags: qr aa rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;mabanque.bnpparibas.		IN	A

;; ANSWER SECTION:
mabanque.bnpparibas.	30	IN	A	159.50.187.79

;; Query time: 24 msec
;; SERVER: 159.50.105.65#53(159.50.105.65)
;; WHEN: Wed Jun 17 08:21:07 CEST 2020
;; MSG SIZE  rcvd: 53



% dig @sns6.bnpparibas.fr NS mabanque.bnpparibas 

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @sns6.bnpparibas.fr NS mabanque.bnpparibas
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

  

Face à un service aussi mal fait, le client DNS est très désarmé. Est-ce que le serveur a ignoré la requête ? Est-ce que le paquet a été perdu (c'est l'Internet, rien n'est garanti) ? Dans le deuxième cas, il faut réessayer, dans le premier, cela ne servirait à rien, qu'à perdre du temps, et à en faire perdre à l'utilisateur. Le client peut aussi supposer que l'absence de réponse est due à telle ou telle nouveauté du protocole DNS qu'il a utilisé, et se dire qu'il faudrait réessayer sans cette nouveauté, voire ne jamais l'utiliser. On voit que ces services grossiers, qui ne répondent pas aux requêtes, imposent un coût conséquent au reste de l'Internet, en délais, en trafic réseau, et en hésitation à déployer les nouvelles normes techniques.

Il n'y a aucune raison valable pour une absence de réponse ? Notre RFC en note une : une attaque par déni de service en cours. Dans ce cas, l'absence de réponse est légitime (et, de toute façon, le serveur peut ne pas avoir le choix). En dehors d'une telle attaque, le serveur doit répondre, en utilisant un des codes de retour DNS existants, qui couvrent tous les cas possibles (de NOERROR, quand tout va bien, à REFUSED, le refus délibéré, en passant par SERVFAIL, l'impossibilité de produire une réponse sensée). Ici, un cas où je demande à un serveur de .fr des informations sur un .com, qu'il n'a évidemment pas, d'où le refus explicite (cf. le champ status:) :


 % dig @d.nic.fr A www.microsofthub.com

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @d.nic.fr A www.microsofthub.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 4212
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1432
; COOKIE: 452269774eb7b7c574c779de5ee9b8e6efe0f777274b2b17 (good)
;; QUESTION SECTION:
;www.microsofthub.com.		IN	A

;; Query time: 4 msec
;; SERVER: 2001:678:c::1#53(2001:678:c::1)
;; WHEN: Wed Jun 17 08:32:06 CEST 2020
;; MSG SIZE  rcvd: 77

  

Le RFC note qu'il n'y a pas que l'absence de réponse, il y a aussi parfois des réponses incorrectes. Ainsi, certains serveurs (ou, là encore, la middlebox placée devant eux) copient le bit AD de la requête dans la réponse au lieu de déterminer par eux-mêmes si ce bit - qui signifie Authentic Data - doit être mis dans la réponse.

Donc, ne pas répondre, c'est mal, et égoïste. Mais quelles sont les conséquences exactes de cette absence de réponse ? Parmi elles :

  • Pendant longtemps, les résolveurs DNS, face à une absence de réponse, réessayaient sans EDNS, ce qui résolvait parfois le problème, mais a sérieusement gêné le déploiement d'EDNS.
  • Même problème avec les nouvelles utilisations d'EDNS.
  • Un comportement fréquent des pare-feux est de bloquer les requêtes demandant des types de données qu'ils ne connaissent pas. La liste connue de ces pare-feux est toujours très réduite par rapport à la liste officielle, ce qui se traduit par une grande difficulté à déployer de nouveaux types de données DNS. C'est une des raisons derrière l'échec du type SPF (cf. RFC 6686). Cela encourage l'usage de types de données fourre-tout comme TXT.
  • Même problème pour le déploiement de DANE et de son type TLSA.
  • Le RFC ne cite pas ce cas, mais ne pas répondre peut aussi dans certains cas faciliter des attaques par empoisonnement d'un résolveur, cf. l'attaque SLIP.

Quels sont les cas où il est particulièrement fréquent qu'il n'y ait pas de réponse, ou bien une réponse erronée ? La section 3 en décrit un certain nombre (et le RFC vient avec un script qui utilise dig pour tester une grande partie de ces cas). Elle rappelle également les réponses correctes attendues. Par exemple, une requête de type SOA (Start Of Authority) à un serveur faisant autorité pour une zone doit renvoyer une réponse (contrairement aux serveurs de BNP Paribas cités plus haut, qui ne répondent pas). Même si le type de données demandé est inconnu du serveur, il doit répondre (probablement NOERROR s'il n'a tout simplement pas de données du type en question).

On voit parfois également des serveurs (ou plutôt des combinaisons serveur / middlebox boguée située devant le serveur) qui achoppent sur les requêtes utilisant des options (flags) DNS spécifiques. Ici, l'option Z fait que le serveur de la RATP ne répond plus :


% dig @193.104.162.15 +noedns +noad +norec +zflag soa ratp.fr  
; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @193.104.162.15 +noedns +noad +norec +zflag soa ratp.fr
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

  

Alors qu'il marche parfaitement sans cette option :


  % dig @193.104.162.15 +noedns +noad +norec soa ratp.fr  

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> @193.104.162.15 +noedns +noad +norec soa ratp.fr
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30635
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 2

;; QUESTION SECTION:
;ratp.fr.			IN	SOA

;; ANSWER SECTION:
ratp.fr.		3600	IN	SOA	ns0.ratp.fr. hostmaster.ratp.fr. 2020051201 21600 3600 4204800 300
...
;; ADDITIONAL SECTION:
ns0.ratp.fr.		3600	IN	A	193.104.162.15
ns1.ratp.fr.		3600	IN	A	193.104.162.14

;; Query time: 6 msec
;; SERVER: 193.104.162.15#53(193.104.162.15)
;; WHEN: Mon May 18 17:42:33 CEST 2020
;; MSG SIZE  rcvd: 213

  

Autre exemple, l'option AD (Authentic Data) dans la requête, qui indique que le client espère une validation DNSSEC, déclenche parfois des bogues, comme de ne pas répondre ou bien de répondre en copiant aveuglément le bit AD dans la réponse. La section 6 du RFC détaille un cas similaire, celui des serveurs qui réutilisent une réponse déjà mémorisée, mais pour des options différentes dans la requête.

Et les opérations (opcodes) inconnus ? Des opérations comme NOTIFY ou UPDATE n'existaient pas au début du DNS et d'autres seront encore ajoutées dans le futur. Si le serveur ne connait pas une opération, il doit répondre NOTIMP (Not Implemented). Ici, avec l'opération 1 (IQUERY, ancienne mais abandonnée par le RFC 3425) :


% dig @d.nic.fr +opcode=1 toto.fr

; <<>> DiG 9.11.5-P4-5.1+deb10u1-Debian <<>> @d.nic.fr +opcode=1 toto.fr
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: IQUERY, status: NOTIMP, id: 20180
;; flags: qr; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1432
; COOKIE: 71f9ced2f29076a65d34f3ed5ef2f718bab037034bb82106 (good)
;; Query time: 4 msec
;; SERVER: 2001:678:c::1#53(2001:678:c::1)
;; WHEN: Wed Jun 24 08:47:52 CEST 2020
;; MSG SIZE  rcvd: 51

  

Au contraire, voici un serveur qui répond incorrectement (REFUSED au lieu de NOTIMP) :


% dig  @ns3-205.azure-dns.org. +noedns +noad +opcode=15 +norec microsoft.com                        

; <<>> DiG 9.11.5-P4-5.1+deb10u1-Debian <<>> @ns3-205.azure-dns.org. +noedns +noad +opcode=15 +norec microsoft.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: RESERVED15, status: REFUSED, id: 41518
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;microsoft.com.			IN	A

;; Query time: 22 msec
;; SERVER: 2a01:111:4000::cd#53(2a01:111:4000::cd)
;; WHEN: Wed Jun 24 09:16:19 CEST 2020
;; MSG SIZE  rcvd: 31

  

Soyons positifs : c'était bien pire il y a encore seulement cinq ou dix ans, malgré des tests techniques obligatoires dans certains registres comme Zonecheck pour .fr. Des efforts comme le DNS Flag Day ont permis d'arranger sérieusement les choses.

Bien sûr, les serveurs DNS doivent accepter les requêtes venant sur TCP et pas seulement sur UDP. Cela a toujours été le cas, mais le RFC 7766 rend cette exigence encore plus stricte. Il y a fort longtemps, l'outil de test Zonecheck de l'AFNIC testait ce fonctionnement sur TCP, et avait attrapé beaucoup d'erreurs de configuration, suscitant parfois des incompréhensions de la part d'administrateurs système ignorants qui prétendaient que le DNS n'utilisait pas TCP.

Et il y a bien sûr EDNS (RFC 6891). Introduit après la norme originale du DNS, mais quand même ancienne de plus de vingt ans, EDNS est toujours mal compris par certains programmeurs, et bien des middleboxes déconnent toujours sur des particularités d'EDNS. Déjà, un serveur doit répondre aux requêtes EDNS (même si lui-même ne connait pas EDNS, il doit au moins répondre FORMERR). Ensuite, s'il connait EDNS, il doit gérer les numéros de version d'EDNS (attention, la version actuelle est la 0, il n'y a pas encore eu de version 1 mais, pour qu'elle puisse être déployée un jour, il ne faut pas que les serveurs plantent sur les versions supérieures à zéro). EDNS permet d'indiquer des options (la liste complète est dans un registre IANA) et les options inconnues doivent être ignorées (autrement, on ne pourrait jamais déployer une nouvelle option).

Pour tester si vos serveurs gèrent correctement tous ces cas, le RFC (section 8) vient avec une série de commandes utilisant dig, dont il faudra analyser le résultat manuellement en suivant le RFC. J'en ai fait un script de test, check-dns-respond-rfc8906.sh. Si vous testez vos serveurs avec ce script, faites-le depuis l'extérieur (pour intégrer dans le test les éventuelles middleboxes, cf. section 4). Un exemple d'exécution du test :

%  ./check-dns-respond-rfc8906.sh cyberstructure.fr 2001:4b98:dc0:41:216:3eff:fe27:3d3f >& /tmp/mytest.txt

Et il vous reste à lire le fichier des résultats et à comparer avec les résultats attendus.


Téléchargez le RFC 8906


L'article seul

RFC 8908: Captive Portal API

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : T. Pauly (Apple), D. Thakore (CableLabs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF capport
Première rédaction de cet article le 22 septembre 2020


Un des nombreux problèmes posés par les portails captifs est l'interaction avec le portail, par exemple pour accepter les CGU et continuer. Ces portails ne sont en général prévus que pour une interaction avec un humain. Ce RFC décrit une API ultra-simple qui permet à des programmes, au moins de savoir s'il y a un portail, quelles sont ses caractéristiques et comment sortir de captivité.

L'API suit les principes du RFC 8952. Elle permet donc de récupérer l'état de la captivité (est-ce que j'ai un accès à l'Internet ou pas), et l'URI de la page Web avec laquelle l'humain devra interagir.

Comment est-ce que la machine qui tente de se connecter a appris l'existence de l'API et son URI d'entrée ? Typiquement via les options de DHCP ou de RA décrites dans le RFC 8910. On accède ensuite à l'API avec HTTPS (RFC 2818). Il faudra naturellement authentifier le serveur, ce qui peut poser des problèmes tant qu'on n'a pas un accès à l'Internet complet (par exemple à OCSP, RFC 6960, et à NTP, RFC 5905, pour mettre l'horloge à l'heure et ainsi vérifier que le certificat n'a pas encore expiré). De même, des certificats intermédiaires qu'il faut récupérer sur l'Internet via Authority Information Access (AIA, section 5.2.7 du RFC 5280) peuvent poser des problèmes et il vaut mieux les éviter.

L'API elle-même est présentée en section 5 du RFC. Le contenu est évidement en JSON (RFC 8259), et servi avec le type application/captive+json. Dans les réponses du serveur, l'objet JSON a obligatoirement un membre captive dont la valeur est un booléen et qui indique si on on est en captivité ou pas. Les autres membres possibles sont :

  • user-portal-uri indique une page Web pour humains, avec laquelle l'utilisateur peut interagir,
  • venue-info-url est une page Web d'information,
  • can-extend-session, un booléen qui indique si on peut prolonger la session, ce qui veut dire que cela peut être une bonne idée de ramener l'humain vers la page Web user-portal-uri lorsque la session va expirer,
  • seconds-remaining, le nombre de secondes restant pour cette session, après quoi il faudra se reconnecter (si can-extend-session est à Vrai),
  • bytes-remaining, la même chose mais pour des sessions limitées en quantité de données et plus en temps.

Ces réponses de l'API peuvent contenir des données spécifiques au client, et donc privées. Auquel cas, le serveur doit penser à utiliser Cache-control: private (RFC 7234) ou un mécanisme équivalent, pour éviter que ces données se retrouvent dans des caches.

Un exemple complet figure en section 6 du RFC. On suppose que le client a découvert l'URL https://example.org/captive-portal/api/X54PD39JV via un des mécanismes du RFC 8910. Il envoie alors une requête HTTP :

GET /captive-portal/api/X54PD39JV HTTP/1.1
Host: example.org
Accept: application/captive+json
  

Et reçoit une réponse :

HTTP/1.1 200 OK
Cache-Control: private
Date: Mon, 02 Mar 2020 05:07:35 GMT
Content-Type: application/captive+json

{
      "captive": true,
      "user-portal-url": "https://example.org/portal.html"
}    
  

Il sait alors qu'il est en captivité, et que l'utilisateur doit aller en https://example.org/portal.html pour accepter des CGU léonines, s'authentifier, etc. Une fois que c'est fait, il peut continuer à faire des requêtes à l'API et avoir, par exemple :

{
      "captive": false,
      "user-portal-url": "https://example.org/portal.html",
      "venue-info-url": "https://flight.example.com/entertainment",
      "seconds-remaining": 326,
      "can-extend-session": true
}   
  

D'autres membres de l'objet JSON pourront apparaitre, selon la procédure « Spécification nécessaire » (RFC 8126), un registre IANA a été créé pour les stocker.

Un peu de sécurité pour finir (section 7 du RFC). Le protocole de notre RFC impose l'utilisation de HTTPS (donc de TLS) ce qui règle pas mal de problèmes, notamment de confidentialité et d'authentification. À noter donc (mais cela en vaut la peine) que cela complique un peu les choses pour l'administrateur du portail captif, qui ne peut pas se contenter de HTTP en clair, et qui doit avoir un certificat valide. (Cet argument de la complexité avait été mentionné lors des discussions à l'IETF, où certains trouvaient notre RFC trop exigeant.) Combien de fois ai-je vu des portails captifs avec un certificat auto-signé et/ou expiré !

Mais attention, TLS va seulement sécuriser le fait qu'on se connecte bien au serveur indiqué via les méthodes du RFC 8910. Or, comme ces méthodes ne sont pas elle-mêmes très sûres, la sécurité du portail captif ne doit jamais être surestimée.

Le protocole décrit dans le RFC 8910 et dans ce RFC a été testé lors de réunions IETF, sur le grand réseau de ces réunions. En dehors de cela, il n'y a pas encore de déploiement. Je crains que, vu la nullité technique de la plupart des points d'accès WiFi, vite installés, mal configurés et plus maintenus après, il ne faille attendre longtemps un déploiement significatif.


Téléchargez le RFC 8908


L'article seul

RFC 8910: Captive-Portal Identification in DHCP and Router Advertisements (RAs)

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : W. Kumari (Google), E. Kline (Loon)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF capport
Première rédaction de cet article le 22 septembre 2020


Les portails captifs sont une des plaies de l'accès à l'Internet. À défaut de pouvoir les supprimer, ce nouveau RFC propose des options aux protocoles DHCP et RA pour permettre de signaler la présence d'un portail captif, au lieu que la malheureuse machine ne doive le détecter elle-même. Il remplace le RFC 7710, le premier à traiter ce sujet. Il y a peu de changements de fond mais quand même deux modifications importantes. D'abord, il a fallu changer le code qui identifiait l'option DHCP en IPv4 (du code 160 au 114). Et ensuite l'URI annoncé sur le réseau est désormais celui de l'API et pas une page Web conçue pour un humain.

On trouve de tels portails captifs en de nombreux endroits où de l'accès Internet est fourni, par exemple dans des hôtels, des trains ou des cafés. Tant que l'utilisateur ne s'est pas authentifié auprès du portail captif, ses capacités d'accès à l'Internet sont très limitées. Quels sont les problèmes que pose un portail captif ?

  • Le plus important est qu'il détourne le trafic normal : en cela, le portail captif est une attaque de l'Homme du Milieu et a donc de graves conséquences en terme de sécurité. Il éduque les utilisateurs à trouver normal le fait de ne pas arriver sur l'objectif désiré, et facilite donc le hameçonnage. Au fur et à mesure que les exigences de sécurité augmentent, ces portails captifs seront, on peut l'espérer, de plus en plus mal vus.
  • Le portail captif ne marche pas ou mal si la première connexion est en HTTPS, ce qui est, à juste titre, de plus en plus fréquent. Là encore, il éduque les utilisateurs à trouver normaux les avertissements de sécurité (« mauvais certificat, voulez-vous continuer ? »).
  • Le portail captif n'est pas authentifié, lui, et l'utilisateur est donc invité à donner ses informations de créance à un inconnu.
  • En Wifi, comme l'accès n'est pas protégé par WPA, le trafic peut être espionné par les autres utilisateurs.
  • Spécifique au Web, le portail captif ne marche pas avec les activités non-Web (comme XMPP). Même les clients HTTP non-interactifs (comme une mise à jour du logiciel via HTTP) sont affectés.

Pourquoi est-ce que ces hôtels et cafés s'obstinent à imposer le passage par un portail captif ? On lit parfois que c'est pour authentifier l'utilisateur mais c'est faux. D'abord, certains portails captifs ne demandent pas d'authentification, juste une acceptation des conditions d'utilisation. Ensuite, il existe une bien meilleure solution pour authentifier, qui n'a pas les défauts indiqués plus haut. C'est 802.1X, utilisé entre autres dans eduroam (voir RFC 7593). La vraie raison est plutôt une combinaison d'ignorance (les autres possibilités comme 802.1X ne sont pas connues) et de désir de contrôle (« je veux qu'ils voient mes publicités et mes CGU »).

L'IETF travaille à développer un protocole complet d'interaction avec les portails captifs, pour limiter leurs conséquences. En attendant que ce travail soit complètement terminé, ce RFC propose une option qui permet au moins au réseau local de signaler « attention, un portail captif est là, ne lance pas de tâches - comme Windows Update - avant la visite du portail ». Cette option peut être annoncée par le serveur DHCP (RFC 2131 et RFC 8415) ou par le routeur qui envoie des RA (RFC 4861).

Cette option (section 2 du RFC) annonce au client qu'il est derrière un portail captif et lui fournit l'URI de l'API à laquelle accéder (ce qui évite d'être détourné, ce qui est grave quand on utilise HTTPS). Les interactions avec l'API de ce serveur sont spécifiées dans le RFC 8908.

Les sections 2.1, 2.2 et 2.3 de notre RFC donnent le format de l'option en DHCP v4, DHCP v6 et en RA. Le code DHCP v4 est 114 (un changement de notre RFC), le DHCP v6 est 103 et le type RA est 37. Pour la création d'options DHCPv6 avec des URI, voir le RFC 7227, section 5.7.

Un URI spécial, urn:ietf:params:capport:unrestricted est utilisé pour le cas où il n'y a pas de portail captif. (Cet URI spécial est enregistré à l'IANA, avec les autres suffixes du RFC 3553.)

Bien que la première version de ce RFC date de plus de quatre ans, la grande majorité des réseaux d'accès avec portail captif n'annoncent toujours pas la présence de ce portail et il faudra encore, pendant de nombreuses années, que les machines terminales « sondent » et essaient de détecter par elles-même s'il y a un portail captif ou pas. Elles font cela, par exemple, en essayant de se connecter à une page Web connue (comme http://detectportal.firefox.com/ avec Firefox). Ici, en cas de vrai accès Internet :

%  curl http://detectportal.firefox.com/
success
  

Et ici lorsqu'il y a un portail captif qui détourne le trafic :


% curl -v http://detectportal.firefox.com/
> GET / HTTP/1.1
> Host: detectportal.firefox.com
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 302 Moved Temporarily
< Server: nginx
< Date: Mon, 27 Jul 2020 18:29:52 GMT
...
< Location: https://wifi.free.fr/?url=http://detectportal.firefox.com/
< 
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

  

La section 5 de notre RFC étudie les conséquences de cette option pour la sécurité. Elle rappelle que DHCP et RA ne sont pas sécurisés, de toute façon. Donc, un méchant peut envoyer une fausse option « il y a un portail captif, allez à cet URI pour vous authentifier » mais le même méchant peut aussi bien annoncer un faux routeur et ainsi recevoir tout le trafic... Si on n'utilise pas des précautions comme le RA Guard (RFC 6105) ou le DHCP shield (RFC 7610), on ne peut de toute façon pas se fier à ce qu'on a obtenu en DHCP ou RA.

Il est même possible que cette option nouvelle améliore la sécurité, en n'encourageant pas les utilisateurs à couper les mécanismes de validation comme la vérification des certificats, contrairement à ce que font les portails captifs actuels, qui se livrent à une véritable attaque de l'Homme du Milieu.

Pour DHCP, la plupart des serveurs permettent de servir une option quelconque, en mettant ses valeurs manuellement et une future mise à jour ne servira donc qu'à rendre l'usage de cette option plus simple. (Pour RA, c'est plus complexe, cf. l'expérience lors d'une réunion IETF.) Autrement, je ne connais pas encore de mise en œuvre côté clients DHCP ou RA, mais il semble (je n'ai pas testé personnellement) que ça marche sur iOS à partir de la version 14.

L'annexe B de notre RFC cite les changements depuis le RFC 7710. Les principaux :

  • L'ajout de l'URN urn:ietf:params:capport:unrestricted pour le cas où il n'y a pas de portail captif,
  • le changement de l'option DHCP en IPv4, suite à la collision avec les produits Polycom,
  • l'URI envoyée désigne désormais une API et plus una page Web ordinaire (contrairement à ce que dit l'annexe B de notre RFC, il ne s'agit pas d'une clarification mais d'un vrai changement),
  • les noms (et plus seulement les adresses IP) sont acceptés dans l'URI,
  • et plusieurs éclaircissements et précisions.

Téléchargez le RFC 8910


L'article seul

Mesurer la consommation d'électricité de ses appareils à la maison

Première rédaction de cet article le 19 septembre 2020


On parle beaucoup, en ce moment, de la consommation électrique du secteur du numérique. C'est à juste titre, vu les dangers qui nous attendent. Malheureusement ces débats ne sont pas toujours appuyés sur des arguments solides. Pour discuter, il faut savoir, et pour savoir, il faut mesurer. Je présente donc ici l'usage d'un simple wattmètre pour mesurer la consommation électrique de ses appareils.

Quelques petits rappels simples, pour commencer. La consommation électrique instantanée (à un instant T), la puissance, se mesure en watts (notés W). La consommation sur une période donnée, l'énergie, se mesure en joules (notés J) mais, en pratique, on l'exprime plus souvent en kilowattheures (notés kWh). Un kWh vaut 3,6 MJ joules (millions de joules).

La consommation électrique d'un appareil est souvent écrite dessus, sur son alimentation électrique, ou dans sa fiche technique mais attention, c'est en général sa consommation maximale (en théorie).

L'appareil qui mesure cette consommation électrique est donc un wattmètre. Les wattmètres bas de gamme sont peu coûteux et disponibles facilement. J'ai utilisé le Chacon 54365 (disponible sur Amazon, et, si vous n'aimez pas Amazon, on peut trouver cet appareil sur le site du fabricant - je n'ai pas testé leurs livraisons -, ou dans d'autres boutiques comme Cdiscount). Il m'a coûté 19 € mais je vois que le prix a augmenté depuis. Il se branche dans une prise électrique, et on branche ensuite l'appareil ou l'ensemble d'appareils à mesurer dessus. Sur cette photo, le wattmètre est en haut, son écran à gauche : wattmetre-petit.jpg (Image agrandie.)

Pourquoi ai-je choisi ce modèle ? La principale raison est son écran séparé. Le wattmètre doit souvent être installé dans des endroits peu accessibles (derrière le frigo, par exemple) et un écran qui peut se placer loin de la prise est vraiment important. Second avantage : ce wattmètre ne dépend pas de piles (ce qui est apparemment le cas de certains modèles). Un tel engin bon marché est évidemment assez grossier, et il ne faut pas en attendre une parfaite précision. (Déjà, si on était sérieux, on l'étalonnerait avec un appareil de puissance connue.)

Autre considération méthodologique : si vous voulez vous faire une idée du coût énergétique de votre usage du numérique, attention, mesurer chez soi ne suffit pas. Si, comme la plupart des gens, votre usage du numérique fait un fort appel aux réseaux, plus spécialement à l'Internet, il faudra aussi tenir compte de la consommation de tout le matériel en dehors de chez vous. Sur la consommation énergétique de ce matériel, il est difficile d'obtenir des informations fiables et sourcées. Des chiffres sont parfois publiés mais leur crédibilité me semble faible. En attendant, mesurons ce qui est sous notre contrôle immédiat.

Commençons avec un engin simple, un PC. Le premier testé, tournant sous Windows, consomme environ 45 W. Cela passe à 52 si on allume l'imprimante/numériseur. Cette consommation dépend de l'activité du PC (les chiffres ici sont pour une machine au repos). Un PC portable, lui, prend 30 W quand son capot est fermé et qu'il se charge, 45 W quand il est allumé et jusqu'à 60 lorsqu'il travaille (affichage d'un film). On voit que, contrairement aux routeurs et serveurs de l'Internet, la consommation dépend de l'usage. (Mais pas du stockage et c'est pour cela que le conseil souvent lu « supprimez vos emails pour diminuer l'empreinte carbone » est absurde.) Un autre PC, tournant sous Debian (mais ce n'est pas le même matériel, donc une comparaison directe n'est pas possible) prend 72 W lorsqu'il est inactif, et 92 lorsqu'il travaille (mais cela tombe à 47 quand son écran se met en veille ; les écrans, ça consomme).

Un engin, très différent, un Raspberry Pi (modèle 1, donc très ancien), consomme, lui, moins de 3 W (mais il ne rend évidemment pas les mêmes services).

J'ai dit plus haut qu'il ne fallait pas regarder que la consommation des machines terminales mais aussi celle du reste de l'Internet. À la maison, je note qu'un adaptateur CPL et un commutateur Ethernet bas de gamme sifflent 8 W. Quant à l'armoire où se trouvent la box, le routeur Turris Omnia, le Raspberry Pi et la base DECT, elle prend 33 W. C'est moins que n'importe quel PC, mais ces équipements, eux, restent allumés bien plus longtemps donc l'énergie totale consommée peut être plus grande. (La box est une Freebox, la mesure a été faite avec le Server allumé et le Player éteint.)

En effet, rappelez-vous de la différence entre puissance (consommation instantanée) et énergie (consommation sur une certaine période). Un équipement qui consomme 3 W en permanence aura avalé 2,2 kWh en un mois alors qu'un équipement qui nécessite une puissance de 70 W mais qui n'est branché qu'une heure par jour avalera un peu moins (2,1 kWh) en un mois. Le wattmètre Chacon 54365 permet de mesurer l'énergie consommée mais c'est très limité : il accumule les mesures mais on ne peut pas lui demander « combien d'énergie depuis la dernière remise à zéro ? », juste la consommation énergétique de la dernière semaine, du dernier mois, et de la dernière année, ce qui manque de souplesse. (Le manuel en français est téléchargeable, si vous voulez essayer.)

Par exemple, pour mon poste de travail (un PC, un commutateur, les enceintes audio), après un mois de télétravail, j'ai consommé 14 kWh.

Revenons aux écrans. Si j'allume la deuxième boîte fournie par Free, le Freebox Player, et la télévision, avec son bel écran, cela fait 95 W de plus. La télé, ça consomme !

Et si on quitte le monde du numérique ? 10 W pour un halogène, 620 W pour l'aspirateur. Le nettoyage consomme mais rappelez-vous la différence entre puissance et énergie : on ne laisse pas l'aspirateur fonctionner pendant des heures. Plus difficile à mesurer, le réfrigérateur. Il fonctionne par cycles, gardant le froid grâce à son isolation entre deux périodes d'activité. Sa consommation est quasiment nulle la plupart du temps (mais elle passe à 13 W si j'ouvre la porte, ce qui allume la lumière) et est d'environ 92 W quand le moteur tourne. Le frigo est donc typiquement un appareil pour lequel il faut mieux faire des mesures sur une certaine période, pas des mesures instantanées (17 kWh en un mois, ce qui me semble beaucoup).

Quelles leçons en tirer ? D'abord, si vous êtes soucieux d'écologie, il est clairement intéressant d'éteindre les machines quand on peut. Comme on n'y pense pas toujours, les dispositifs qui le font automatiquement sont très utiles (on a vu qu'éteindre automatiquement l'écran inutilisé diminuait sérieusement la puissance requise). Ensuite, on note qu'il n'est pas forcément nécessaire d'utiliser des engins très consommateurs pour toutes les fonctions. Un simple Raspberry Pi ou équivalent, avec sa faible consommation, est recommandé s'il faut laisser une machine allumée en permanence (par exemple pour la supervision). Enfin, n'oubliez pas que la difficulté est de bien prendre en compte toutes les sources de « coût » écologique, pas uniquement celles qui sont bien visibles. Ainsi, dans le numérique, une source importante est la fabrication des machines. Il vaut souvent plus la peine de garder les machines longtemps, évitant leur remplacement, que de les éteindre un peu plus souvent. Le Raspberry Pi 1 cité plus haut fonctionne depuis 2012

Et pour finir, si vous aimez les calculs et les détails, je vous recommande l'article de Pierre Beyssac.


L'article seul

RFC 8904: DNS Whitelist (DNSWL) Email Authentication Method Extension

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : A. Vesely
Pour information
Première rédaction de cet article le 18 septembre 2020


Le RFC 8601 décrit un en-tête pour le courrier qui indique le résultat d'une tentative d'authentification. Cet en-tête Authentication-Results: permet plusieurs méthodes d'authentification, telles que SPF ou DKIM. Notre nouveau RFC 8904 ajoute une nouvelle méthode, dnswl (pour DNS White List), qui indique le résultat d'une lecture dans une liste blanche, ou liste d'autorisation via le DNS. Ainsi, si le client SMTP avait son adresse IP dans cette liste, un en-tête Authentication-Results: d'authentification positive sera ajouté.

Accéder via le DNS à des listes blanches (autorisation) ou des listes noires (rejet) de MTA est une pratique courante dans la gestion du courrier. Elle est décrite en détail dans le RFC 5782. Typiquement, le serveur SMTP qui voit une connexion entrante forme un nom de domaine à partir de l'adresse IP du client SMTP et fait une requête DNS pour ce nom et le type de données A (adresse IP). S'il obtient une réponse non-nulle, c'est que l'adresse IP figurait dans la liste (blanche ou noire). On peut aussi faire une requête de type TXT pour avoir du texte d'information. Ensuite, c'est au serveur SMTP de décider ce qu'il fait de l'information. La liste (noire ou blanche) lui donne une information, c'est ensuite sa responsabilité de décider s'il accepte ou rejette la connexion. La décision n'est pas forcément binaire, le serveur peut décider d'utiliser cette information comme entrée dans un algorithme de calcul de la confiance (« il est listé dans bl.example, 20 points en moins dans le calcul »).

Les plus connues des listes sont les listes noires (liste de clients SMTP mauvais) mais il existe aussi des listes blanches (liste de clients SMTP qu'on connait et à qui on fait confiance), et elles font l'objet de ce RFC. Il crée une nouvelle méthode pour l'en-tête Authentication-Results:, permettant ainsi d'enregistrer, dans un message, le fait qu'il ait été « authentifié » positivement via une liste blanche. On peut après se servir de cette « authentification » pour, par exemple, vérifier que le nom de domaine annoncé dans l'enregistrement TXT correspondant soit celui attendu (dans l'esprit de DMARCRFC 7489 - ce qui est d'ailleurs très casse-gueule mais c'est une autre histoire).

Et le RFC fait un rappel utile : se servir d'une liste (noire ou blanche) gérée à l'extérieur, c'est sous-traiter. Cela peut être pratique mais cela peut aussi avoir des conséquences néfastes si la liste est mal gérée (comme le sont la plupart des listes noires, adeptes du « on tire d'abord et on négocie après »). Comme le dit le RFC, « vous épousez la politique du gérant de la liste ». Lisez aussi le RFC 6471, au sujet de la maintenance de ces listes.

La nouvelle méthode d'authentification (dnswl, section 2 de notre RFC) figure désormais dans le registre IANA des méthodes d'authentification, spécifié dans le RFC 8601 (notamment section 2.7). Notre RFC 8904 décrit également les propriétés (RFC 8601, section 2.3 et RFC 7410) associées à cette authentification.

La méthode dnswl peut renvoyer pass (cf. le RFC 8601 pour ces valeurs renvoyées), qui indique que l'adresse IP du client est dans la liste blanche interrogée, none (client absent de la liste), ou bien une erreur (si la résolution DNS échoue). Contrairement à d'autres méthodes, il n'y a pas de résultat fail, ce qui est logique pour une liste blanche (qui liste les gentils et ne connait pas les méchants). Les principales propriétés possibles sont :

  • dns.zone : le nom de domaine de la liste blanche,
  • policy.ip : l'adresse IP renvoyée par la liste blanche, elle indique de manière codée les raisons pour lesquelles cette adresse est dans la liste,
  • policy.txt : l'enregistrement TXT optionnel, peut indiquer le nom de domaine associé à ce client SMTP,
  • dns.sec : indique si la requête DNS a été validée avec DNSSEC (yes si c'est le cas, no si la zone n'est pas signée, na si le résolveur ne sait pas valider).

Le type dns pour les propriétés est une nouveauté de ce RFC, désormais enregistrée à l'IANA.

La section 3 de notre RFC décrit l'enregistrement de type TXT qui donne des explications sur la raison pour laquelle l'adresse IP est dans la liste blanche (cf. RFC 5782, sections 2.1 et 2.2). Par exemple, il permet d'indiquer le domaine concerné (ADMD, ADministrative Management Domain, cf. RFC 8601 pour ce concept).

Tiré de l'annexe A du RFC, voici un exemple d'un message qui a reçu un Authentication-Results:, qui contient les quatre propriétés indiquées plus haut :

Authentication-Results: mta.example.org;
     dnswl=pass dns.zone=list.dnswl.example dns.sec=na
     policy.ip=127.0.10.1
     policy.txt="fwd.example https://dnswl.example/?d=fwd.example"   
  

Il se lit ainsi : le MTA mta.example.org estime son client authentifié par la méthode dnswl (DNS White List) de ce RFC. La liste blanche a renvoyé la valeur 127.0.10.1 (sa signification exacte dépend de la liste blanche) et le TXT associé disait que le client SMTP appartenait au domaine fwd.example.

Dans l'exemple plus détaillé du RFC, le message avait été retransmis d'une manière qui cassait SPF et n'aurait donc pas été accepté sans la liste blanche, qui certifie que fwd.example est un retransmetteur connu et légitime.

Enfin, la section 5 du RFC traite de sécurité. Notamment, elle insiste sur le fait que le DNS n'est pas, par défaut, protégé contre diverses manipulations et qu'il est donc recommandé d'utiliser DNSSEC (ce que ne fait pas la liste blanche d'exemple citée plus loin).

Voyons maintenant des exemples avec une liste blanche réelle, https://www.dnswl.org/. Prenons le serveur de messagerie de l'AFNIC, 2001:67c:2218:2::4:12. On inverse l'adresse (par exemple, avec ipv6calc -a 2001:67c:2218:2::4:12) et on fait une requête sous list.dnswl.org :


% dig A 2.1.0.0.4.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.8.1.2.2.c.7.6.0.1.0.0.2.list.dnswl.org
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1634
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 8, ADDITIONAL: 11
...
;; ANSWER SECTION:
2.1.0.0.4.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.8.1.2.2.c.7.6.0.1.0.0.2.list.dnswl.org.	7588 IN	A 127.0.9.1
...
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Jul 04 09:16:37 CEST 2020
;; MSG SIZE  rcvd: 555

  

Que veut dire la valeur retournée, 127.0.9.1 ? On consulte la documentation de la liste et on voit que 9 veut dire Media and Tech companies (ce qui est exact) et 1 low trustworthiness. Il s'agit de la confiance dans le classement, pas dans le serveur. Pour le même serveur, la confiance est plus grande en IPv4 (3 au lieu de 1) :

    
% dig A 12.4.134.192.list.dnswl.org
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 266
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
12.4.134.192.list.dnswl.org. 10788 IN A	127.0.9.3
...
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Jun 20 12:31:57 CEST 2020
;; MSG SIZE  rcvd: 72

  

Et les enregistrements TXT ? Ici, il valent :

% dig TXT 2.1.0.0.4.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.8.1.2.2.c.7.6.0.1.0.0.2.list.dnswl.org
...
;; ANSWER SECTION:
2.1.0.0.4.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.8.1.2.2.c.7.6.0.1.0.0.2.list.dnswl.org.	8427 IN	TXT "nic.fr https://dnswl.org/s/?s=8580"
  

En visant l'URL indiquée, on peut avoir tous les détails que la liste blanche connait de ce serveur. (Je n'ai pas investigué en détail mais j'ai l'impression que certains serveurs faisant autorité pour le domaine dnswl.org renvoient des NXDOMAIN à tort, par exemple sur les ENT - Empty Non-Terminals - ce qui pose problème si votre résolveur utilise une QNAME minimisationRFC 7816 - stricte.)

Pour utiliser cette liste blanche depuis votre MTA favori, vous pouvez regarder la documentation de dnswl.org. par exemple, pour Courier, ce sera :

   -allow=list.dnswl.org 
  

(Tous les détails dans la documentation de Courier). Pour Postfix, voyez la section dédiée dans la documentation de dnswl.org. SpamAssassin, quant à lui, utilise dnswl.org par défaut.


Téléchargez le RFC 8904


L'article seul

RFC 8808: A YANG Data Model for Factory Default Settings

Date de publication du RFC : Août 2020
Auteur(s) du RFC : Q. Wu (Huawei), B. Lengyel (Ericsson), Y. Niu (Huawei)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF netmod
Première rédaction de cet article le 17 septembre 2020


Ce RFC décrit un modèle YANG pour permettre la « remise aux réglages d'usine » d'un équipement, quand celui-ci est trop bizarrement configuré pour qu'il y ait une autre solution que l'effacement radical.

YANG (RFC 6020) est un langage de description des équipements réseau et de leurs capacités, afin de permettre de la gestion automatisée de ces équipements via des protocoles comme NETCONF (RFC 6241) ou RESTCONF (RFC 8040).

Ce RFC définit un nouveau RPC, factory-reset, qui va remettre tous les réglages de la machine aux réglages qu'elle avait à la sortie d'usine. C'est l'équivalent YANG de manipulations physiques comme « appuyez sur les boutons Power et VolumeDown simultanément pendant cinq secondes » ou bien « insérez un trombone dans ce petit trou ».

La section 2 du RFC décrit plus précisément ce que veut dire « retourner aux réglages d'usine ». Les entrepôts (datastore, cf. RFC 6020, RFC 7950 et RFC 8342) comme <running> reprennent les valeurs qu'ils contenaient lorsque l'équipement a quitté l'usine. Toutes les données générées depuis sont jetées. Cela inclut (le RFC utilise des exemples de répertoires Unix, que je reprends ici, mais ce sont juste des exemples, l'équipement n'utilise pas forcément Unix) les certificats (/etc/ssl), les journaux (/var/log), les fichiers temporaires (/tmp), etc. Par contre, il faut garder des informations qui étaient spécifiques à cet engin particulier (et différent des autres du même modèle) mais qui ont été fixés avant le premier démarrage, par exemple des identificateurs uniques ou des clés privées (RFC 8995) ou mots de passe générées automatiquement au début du cycle de vie. Les données sensibles doivent être effacées de manière sûre, par exemple en écrivant plusieurs fois sur leur emplacement (cf. section 6). À noter que cette remise au début peut couper la communication avec la machine de gestion : l'équipement se comportera comme s'il sortait du carton, ce qui peut nécessiter une configuration nouvelle.

Notre RFC normalise également un nouvel entrepôt (datastore), factory-default, qui contient ces réglages d'usine et permet donc à un client NETCONF ou RESTCONF de savoir en quoi ils consistent. Appeler factory-reset revient donc à appliquer factory-default. Cet entrepôt suit les principes du RFC 8342, annexe A, et est en lecture seule.

La section 4 présente le module complet, qui est disponible en ietf-factory-default.yang. Il s'appuie sur le module du RFC 8342 et sur celui du RFC 8341.

L'URN de ce RFC, urn:ietf:params:xml:ns:yang:ietf-factory-default a été enregistré à l'IANA (registre du RFC 3688), et le module ietf-factory-default dans le registre des modules.

Quelques mots sur la sécurité pour terminer. Comme le but de ce module est de permettre à des clients NETCONF ou RESTCONF d'appeler ce RPC factory-reset, et que ce RPC a des conséquences… sérieuses pour l'équipement, il faut comme d'habitude veiller à ce que les accès NETCONF et RESTCONF soient bien sécurisés (par exemple via SSH, cf. RFC 6242 et via les contrôles d'accès du RFC 8341).


Téléchargez le RFC 8808


L'article seul

RFC 8891: GOST R 34.12-2015: Block Cipher "Magma"

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : V. Dolmatov (JSC "NPK Kryptonite"), D. Baryshkov (Auriga)
Pour information
Première rédaction de cet article le 15 septembre 2020


Ce RFC décrit un algorithme russe de chiffrement symétrique, « GOST R 34.12-2015 », surnommé Magma. N'attendez pas de ma part des conseils sur l'utilisation ou non de cet algorithme, je résume juste le RFC.

GOST est le nom des normes de l'organisme de normalisation officiel en Russie (et, par abus de langage, leurs algorithmes sont souvent cités sous le nom de « GOST » tout court). Cet organisme a normalisé plusieurs algorithmes de chiffrement symétrique dont Kuznyechik (décrit dans le RFC 7801) et l'ancien « GOST 28147-89 » (RFC 5830). Ce dernier est remplacé par « GOST R 34.12-2015 », qui fait l'objet de ce RFC. (La norme russe officielle est disponible en ligne mais, de toute façon, le russe plus la cryptographie, ce serait trop pour moi). Comme d'autres algorithmes de cryptographie normalisés par GOST, Magma a été développé en partie par le secteur public (Service des communications spéciales et d'information du Service fédéral de protection de la Fédération de Russie) et par le secteur privé (InfoTeCS). Le décret n° 749 du 19 juin 2015, pris par l'Agence fédérale pour la régulation technique et la métrologie en a fait un algorithme russe officiel.

Du fait de ce caractère officiel, si vous vendez des produits ou des prestations de sécurité en Russie, vous serez probablement obligés d'inclure les algorithmes GOST.

Je vous laisse lire le RFC pour la description de l'algorithme (ou l'original russe, si vous lisez le russe). Notez que, contrairement à son prédécesseur (cf. RFC 5830, sections 5 à 7), il ne décrit pas les modes utilisables, chacun choisit celui qui lui semble adapté.

Question mises en œuvre, il y en a une compatible avec WebCrypto, ou bien une pour OpenSSL.


Téléchargez le RFC 8891


L'article seul

RFC 8899: Packetization Layer Path MTU Discovery for Datagram Transports

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : G. Fairhurst, T. Jones (University of Aberdeen), M. Tuexen, I. Ruengeler, T. Voelker (Muenster University of Applied Sciences)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 12 septembre 2020


Ce RFC qui vient d'être publié décrit une méthode pour découvrir la MTU d'un chemin sur l'Internet (Path MTU, la découverte de la MTU du chemin se nommant PMTUD pour Path MTU Discovery). Il existe d'autres méthodes pour cette découverte, comme celle des RFC 1191 et RFC 8201, qui utilisent ICMP. Ici, la méthode ne dépend pas d'ICMP, et se fait avec les datagrammes normaux de la couche 4 (ou PL, pour Packetization Layer). Elle étend la technique du RFC 4821 à d'autres protocoles de transport que TCP (et SCTP).

Mais, d'abord, pourquoi est-ce important de découvrir la MTU maximale du chemin ? Parce que, si on émet des paquets qui sont plus gros que cette MTU du chemin, ces paquets seront jetés, au grand dam de la communication. En théorie, le routeur qui prend cette décision devrait fragmenter le paquet (IPv4 seulement), ou bien envoyer à l'expéditeur un message ICMP Packet Too Big mais ces fragments, et ces messages ICMP sont souvent bloqués par de stupides pare-feux mal gérés (ce qu'on nomme un trou noir). On ne peut donc pas compter dessus, et ce problème est connu depuis longtemps (RFC 2923, il y a vingt ans, ce qui est une durée insuffisante pour que les administrateurs de pare-feux apprennent leur métier, malgré le RFC 4890). La seule solution fiable est de découvrir la MTU du chemin, en envoyant des paquets de plus en plus gros, jusqu'à ce que ça ne passe plus, montrant ainsi qu'on a découvert la MTU.

Le RFC donne aussi quelques raisons plus subtiles pour lesquelles la découverte classique de la MTU du chemin ne marche pas toujours. Par exemple, s'il y a un tunnel sur le trajet, c'est le point d'entrée du tunnel qui recevra le message ICMP Packet Too Big, et il peut faillir à sa tâche de le faire suivre à l'émetteur du paquet. Ou bien, en cas de routage asymétrique, le message ICMP peut être jeté car il n'y a pas de route de retour.

Et ce n'est pas tout que le message ICMP revienne à l'émetteur, encore faut-il que celui-ci l'accepte. Les messages ICMP n'étant pas authentifiés, une machine prudente va essayer de les valider, en examinant le paquet originel contenu dans le message ICMP, et en essayant de voir s'il correspond à du trafic en cours. Si le routeur qui émet le message ICMP n'inclut pas assez du paquet original (malgré ce que demande le RFC 1812) pour que cette validation soit possible, le message ICMP « Vous avez un problème de taille » sera jeté par l'émetteur du paquet original. Et il peut y avoir d'autres problèmes, par exemple avec le NAT (cf. RFC 5508). Autant de raisons supplémentaires qui font que la découverte de la MTU du chemin ne peut pas compter sur les messages ICMP.

Notre RFC utilise le terme de couche de découpage en paquets (Packetization Layer, PL). Il désigne la couche où les données sont séparées en paquets qui seront soumis à IP. C'est en général la couche de transport (protocoles TCP, DCCP, SCTP, etc) mais cela peut aussi être fait au-dessus de celle-ci. Ce sigle PL donne naissance au sigle PLPMTUD, Packetization Layer Path MTU Discovery. Contrairement à la classique PMTUD (Path MTU Discovery) des RFC 1191 et RFC 8201, la PLPMTUD ne dépend pas des messages ICMP. C'est la PL, la couche de découpage en paquets qui se charge de trouver la bonne taille, en envoyant des données et en regardant lesquelles arrivent. La PLPMTUD est plus solide que la traditionnelle PMTUD, qui est handicapée par le blocage fréquent d'ICMP (cf. RFC 4821, qui a introduit ce terme de PLPMTUD, et RFC 8085).

La découverte de la MTU du chemin par le PL est ancienne pour TCP (RFC 4821). Et pour les autres protocoles de transport ? C'est l'objet de notre RFC. Pour UDP, le RFC 8085 (section 3.2) recommande d'utiliser une telle procédure (sauf si les couches inférieures fournissent l'information). Et, pour SCTP, la section 10.2 du RFC 4821 le recommandait également mais sans donner de détails, désormais fournis par notre nouveau RFC.

Un peu de vocabulaire avant de continuer la lecture du RFC (section 2) : un trou noir est un endroit du réseau d'où des paquets ne peuvent pas sortir. Par exemple, parce que les paquets trop gros sont jetés, sans émission de messages ICMP, ou bien avec des messages ICMP filtrés. Un paquet-sonde est un paquet dont l'un des buts est de tester la MTU du chemin. Il est donc de grande taille, et, en IPv4, a le bit DF (Don't Fragment), qui empêchera la fragmentation par les routeurs intermédiaires. Ceci étant défini, attaquons-nous au cahier des charges (section 3 du RFC). Le RFC 4821 était très lié à TCP, mais la généralisation de la PLPMTUD qui est dans notre nouveau RFC va nécessiter quelques fonctions supplémentaires :

  • Il faut évidemment qu'on puisse envoyer des paquets-sonde, donc mettre le bit DF à 1 (en IPv4).
  • Surtout, il faut un mécanisme de notification de la bonne arrivée du paquet. En TCP (ou SCTP, ou QUIC), il est inclus dans le protocole, ce sont les accusés de réception (ACK). Mais pour UDP et des protocoles similaires, il faut ajouter ce mécanisme de notification, ce qui implique en général une coopération avec l'application (par exemple, pour le DNS, le client DNS peut notifier le PL qu'il a reçu une réponse à sa question, prouvant ainsi que le datagramme est passé).
  • Les paquets-sonde peuvent se perdre pour d'autres raisons que la MTU, la congestion, par exemple. La méthode de PLPMTUD doit donc savoir traiter ces cas, par exemple en réessayant. (D'autant plus que le paquet-sonde ne sert pas forcément qu'à la PLPMTUD, il peut aussi porter des données utiles.)
  • Et, même si la PLPMTUD ne dépend pas d'ICMP, il est quand même recommandé d'utiliser les messages PTB (Packet Too Big) si on en reçoit (cf. section 4.6). Attention toutefois à faire des efforts pour les valider : rien n'est plus facile pour un attaquant que d'envoyer de faux PTB pour réduire la MTU et donc les performances. Une solution sûre est de ne pas changer la MTU en recevant un PTB, mais d'utiliser ce PTB comme indication qu'il faut re-tester la MTU du chemin tout de suite.

En parlant de validation, cela vaut aussi pour les paquets-sonde (section 9 du RFC) : il faut empêcher un attaquant situé hors du chemin d'injecter de faux paquets. Cela peut se faire par exemple en faisant varier le port source (cf. section 5.1 du RFC 8085), comme le fait le DNS.

La section 4 du RFC passe ensuite aux mécanismes concrets à utiliser. D'abord, les paquets-sonde. Que doit-on mettre dedans, sachant qu'ils doivent être de grande taille, le but étant d'explorer les limites du chemin ? On peut utiliser des données utiles (mais on n'en a pas forcément assez, par exemple les requêtes DNS sont toujours de petite taille), on peut utiliser uniquement des octets bidons, du remplissage (mais c'est ennuyeux pour les protocoles qui doivent avoir une faible latence, comme le DNS, qui n'ont pas envie d'attendre pour envoyer les vraies données), ou bien on peut combiner les deux (des vraies données, plus du remplissage). Et, si on utilise des données réelles, il faut gérer le risque de perte, et pouvoir réémettre. Le RFC ne donne pas de consigne particulière aux mises en œuvre de PLPMTUD, les trois stratégies sont autorisées.

Ensuite, il faut évidemment un mécanisme permettant de savoir si le paquet-sonde est bien arrivé, si le protocole de transport ne le fournit pas, ce qui est le cas d'UDP, ce qui nécessite une collaboration avec l'application.

Dans le cas où le paquet-sonde n'arrive pas, il faut détecter la perte. C'est relativement facile si on a reçu un message ICMP PTB mais on ne veut pas dépendre uniquement de ces messages, vu les problèmes d'ICMP dans l'Internet actuel. Le PL doit garder trace des tailles des paquets envoyés et des pertes (cf. le paragraphe précédent) pour détecter qu'un trou noir avale les paquets de taille supérieure à une certaine valeur. Il n'est pas facile de déterminer les seuils de détection. Si on réduit la MTU du chemin au premier paquet perdu, on risque de la réduire trop, alors que le paquet avait peut-être été perdu pour une tout autre raison. Si on attend d'avoir perdu plusieurs paquets, on risque au contraire de ne pas réagir assez vite à un changement de la MTU du chemin (changement en général dû à une modification de la route suivie).

(J'ai parlé de MTU du chemin mais PLMTUD détecte en fait une valeur plus petite que la MTU, puisqu'il y a les en-têtes IP.)

Si vous aimez les détails des protocoles, les machines à état et la liste de toutes les variables nécessaires, la section 5 du RFC est pour vous, elle spécifie complètement la PLMTUD pour des protocoles utilisant des datagrammes. Cette section 5 est générique, et la section 6 décrit les détails spécifiques à un protocole de transport donné.

Ainsi, pour UDP (RFC 768) et UDP-Lite (RFC 3828), le protocole de transport n'a tout simplement pas les mécanismes qu'il faut pour faire de la PLPMTUD ; cette découverte de la MTU du chemin doit être faite par l'application, dans l'esprit du RFC 8085. L'idéal serait que cette PLPMTUD soit mise en œuvre dans une bibliothèque partagée, pour éviter que chaque application ne la réinvente mal. Mais je ne connais pas actuellement de telle bibliothèque.

Le RFC insiste sur le fait que l'application doit, pour effectuer cette tâche, pouvoir se souvenir de quels paquets ont été envoyés, donc mettre dans chaque paquet un identificateur, comme le Query ID du DNS.

Pour SCTP (RFC 4960), c'est un peu plus facile, puisque SCTP, comme TCP, a un système d'accusé de réception. Et les chunks de SCTP fournissent un moyen propre d'ajouter des octets au paquet-sonde pour atteindre la taille souhaitée (cf. RFC 4820), sans se mélanger avec les données des applications.

Pour le protocole QUIC, la façon de faire de la PLMTUD est spécifiée dans le RFC 9000. DCCP, lui, n'est pas spécifiquement cité dans cette section.

Ah, et quelles mises en œuvre de protocoles font déjà comme décrit dans ce RFC ? À part divers tests, il parait (mais je n'ai pas vérifié personnellement) que c'est le cas pour SCTP dans FreeBSD, et dans certains navigateurs Web pour WebRTC (WebRTC tourne sur UDP et rappelez-vous qu'en UDP, il faut une sérieuse coopération par l'application pour faire de la PLPMTUD). Côté QUIC, il y a lsquic, qui gère les techniques de notre RFC.


Téléchargez le RFC 8899


L'article seul

RFC 8900: IP Fragmentation Considered Fragile

Date de publication du RFC : Septembre 2020
Auteur(s) du RFC : R. Bonica (Juniper Networks), F. Baker, G. Huston (APNIC), R. Hinden (Check Point Software), O. Troan (Cisco), F. Gont (SI6 Networks)
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 12 septembre 2020


Un concept important d'IP est la fragmentation, le découpage d'un paquet trop gros en plusieurs fragments, chacun acheminé dans un datagramme différent. Excellente idée sur le papier, la fragmentation est handicapée, dans l'Internet actuel, par les nombreuses erreurs de configuration de diverses middleboxes. Ce nouveau RFC constate la triste réalité : en pratique, la fragmentation marche mal, et les machines qui émettent les paquets devraient essayer de faire en sorte qu'elle ne soit pas utilisée.

Rappelons d'abord ce qu'est la fragmentation, dans IP. Tout lien entre deux machines a une MTU, la taille maximale des datagrammes qui peuvent passer. C'est par exemple 1 500 octets pour l'Ethernet classique. Si le paquet IP est plus grand, il faudra le fragmenter, c'est-à-dire le découper en plusieurs fragments, chacun de taille inférieure à la MTU. En IPv4, n'importe quel routeur sur le trajet peut fragmenter un paquet (sauf si le bit DF - Don't Fragment - est mis à un dans l'en-tête IP), en IPv6, seule la machine émettrice peut fragmenter (tout ce passe comme si DF était systématiquement présent).

Ces fragments seront ensuite réassemblés en un paquet à la destination. Chacun étant transporté dans un datagramme IP différent, ils auront pu arriver dans le désordre, certains fragments ont même pu être perdus, le réassemblage est donc une opération non-triviale. Historiquement, certaines bogues dans le code de réassemblage ont même pu mener à des failles de sécurité.

Une légende urbaine s'est constituée petit à petit, racontant que les fragments, en eux-mêmes, posaient un problème de sécurité. C'est faux, mais ce genre de légendes a la vie dure, et a mené un certain nombre d'administrateurs de pare-feux à bloquer les fragments. Le RFC 7872 faisait déjà le constat que les fragments, souvent, n'arrivaient pas à destination. Outre ce RFC, on peut citer une étude très ancienne, qui montre que le problème ne date pas d'aujourd'hui, « "Fragmentation Considered Harmful (SIGCOMM '87 Workshop on Frontiers in Computer Communications Technology) ou, pour le cas spécifique du DNS, la plus récente « IPv6, Large UDP Packets and the DNS ».

La section 2 de notre RFC explique en grand détail la fragmentation IP. Notez par exemple qu'IPv4 impose (RFC 791, section 3.2) une MTU minimale de 68 octets mais, en pratique, on a toujours au moins 576 octets (ou, sinon, une autre fragmentation/réassemblage, dans la couche 2). IPv6, lui, impose (RFC 8200), 1 280 octets. Il a même été suggéré de ne jamais envoyer de paquets plus grands, pour éviter la fragmentation. Un Ethernet typique offre une MTU de 1 500 octets, mais elle peut être réduite par la suite en cas d'utilisation de tunnels.

Chaque lien a sa MTU mais ce qui est important, pour le paquet, c'est la MTU du chemin (Path MTU), c'est-à-dire la plus petite des MTU rencontrées sur le chemin entre le départ et l'arrivée. C'est cette MTU du chemin qui déterminera si on fragmentera ou pas. (Attention, le routage étant dynamique, cette MTU du chemin peut changer dans le temps.) Il est donc intéressant, pour la machine émettrice d'un paquet, de déterminer cette MTU du chemin. Cela peut se faire en envoyant des paquets avec le bit DF (Don't Fragment, qui est implicite en IPv6) et en regardant les paquets ICMP renvoyés par les routeurs, indiquant que la MTU est trop faible pour ce paquet (et, depuis le RFC 1191, le message ICMP indique la MTU du lien suivant, ce qui évite de la deviner par essais/erreurs successifs.) Cette procédure est décrite dans les RFC 1191 et RFC 8201. Mais (et c'est un gros mais), cela suppose que les erreurs ICMP « Packet Too Big » arrivent bien à l'émetteur et, hélas, beaucoup de pare-feux configurés par des ignorants bloquent ces messages ICMP. D'autre part, les messages ICMP ne sont pas authentifiés (RFC 5927) et un attaquant peut générer de fausses erreurs ICMP pour faire croire à une diminution de la MTU du chemin, affectant indirectement les performances. (Une MTU plus faible implique des paquets plus petits, donc davantage de paquets.)

Quand une machine fragmente un paquet (en IPv4, cette machine peut être l'émetteur ou un routeur intermédiaire, en IPv6, c'est forcément l'émetteur), elle crée plusieurs fragments, dont seul le premier porte les informations des couches supérieures, comme le fait qu'on utilise UDP ou TCP, ou bien le numéro de port. La description détaillée figure dans le RFC 791 pour IPv4 et dans le RFC 8200 (notamment la section 4.5) pour IPv6.

Voici un exemple où la fragmentation a eu lieu, vu par tcpdump (vous pouvez récupérer le pcap complet en dns-frag-md.pcap). La machine 2605:4500:2:245b::bad:dcaf a fait une requête DNS à 2607:5300:201:3100::2f69, qui est un des serveurs faisant autorité pour le TLD .md. La réponse a dû être fragmentée en deux :

% tcpdump -e -n -r dns-frag-md.pcap                         
16:53:07.968917 length 105: 2605:4500:2:245b::bad:dcaf.44104 > 2607:5300:201:3100::2f69.53: 65002+ [1au] ANY? md. (43)
16:53:07.994555 length 1510: 2607:5300:201:3100::2f69 > 2605:4500:2:245b::bad:dcaf: frag (0|1448) 53 > 44104: 65002*- 15/0/16 SOA, RRSIG, Type51, RRSIG, RRSIG, DNSKEY, DNSKEY, RRSIG, NS dns-md.rotld.ro., NS nsfr.dns.md., NS nsb.dns.md., NS ns-ext.isc.org., NS nsca.dns.md., NS ns-int.dns.md., RRSIG (1440)
16:53:07.994585 length 321: 2607:5300:201:3100::2f69 > 2605:4500:2:245b::bad:dcaf: frag (1448|259)
  

Le premier paquet est la requête, le second est le premier fragment de la réponse (qui va des octets 0 à 1447), le troisième paquet est le second fragment de cette même réponse (octets 1448 à la fin). Regardez les longueur des paquets IP, et le fait que seul le premier fragment, qui porte l'en-tête UDP, a pu être interprété comme étant du DNS.

Notez que certaines versions de traceroute ont une option qui permet d'afficher la MTU du lien (par exemple traceroute -n --mtu IP-ADDRESS.)

Les couches supérieures (par exemple UDP ou TCP) peuvent ignorer ces questions et juste envoyer leurs paquets, comptant qu'IP fera son travail, ou bien elles peuvent tenir compte de la MTU du chemin, par exemple pour optimiser le débit, en n'envoyant que des paquets assez petits pour ne pas être fragmentés. Cela veut dire qu'elles ont accès au mécanisme de découverte de la MTU du chemin, ou bien qu'elles font leur propre découverte, via la procédure PLPMTUD (Packetization Layer Path MTU Discovery) du RFC 4821 (qui a l'avantage de ne pas dépendre de la bonne réception des paquets ICMP).

Bon, maintenant qu'on a vu la framentation, voyons les difficultés qui surviennent dans l'Internet d'aujourd'hui (section 3 du RFC). D'abord, chez les pare-feux et, d'une manière générale, tous les équipements intermédiaires qui prennent des décisions en fonction de critères au-dessus de la couche 3, par exemple un répartiteur de charge, ou un routeur qui enverrait les paquets à destination du port 443 vers un autre chemin que le reste des paquets. Ces décisions dépendent d'informations qui ne sont que dans le premier fragment d'un datagramme fragmenté. Décider du sort des fragments suivants n'est pas évident, surtout si on veut le faire sans maintenir d'état. Un pare-feu sans état peut toujours essayer d'accepter tous les fragments ultérieurs (ce qui pourrait potentiellement autoriser certaines attaques) ou bien tous les bloquer (ce qui arrêterait du trafic légitime fragmenté). Et les pare-feux avec état ne sont pas une solution idéale, puisque stocker et maintenir cet état est un gros travail, qui plante souvent, notamment en cas d'attaque par déni de service.

Certains types de NAT ont également des problèmes avec la fragmentation. Ainsi, les techniques A+P (RFC 6346) et CGN (RFC 6888) nécessitent toutes les deux que les fragments soient réassemblés en un seul paquet, avant de traduire.

Qui dit fragmentation dit réassemblage à un moment. C'est une opération délicate, et plusieurs programmeurs se sont déjà plantés en réassemblant sans prendre de précautions. Mais il y a aussi un problème de performance. Et il y a les limites d'IPv4. L'identificateur d'un fragment ne fait que 16 bits et cela peut mener rapidement à des réutilisations de cet identificateur, et donc à des réassemblages incorrects (les sommes de contrôle de TCP et UDP ne sont pas toujours suffisantes pour détecter ces erreurs, cf. RFC 4693). IPv6, heureusement, n'a pas ce problème, l'identificateur de fragment faisant 32 bits.

On l'a dit plus haut, la fragmentation, et surtout le réassemblage, ont une longue histoire de failles de sécurité liées à une lecture trop rapide du RFC par le programmeur qui a écrit le code de réassemblage. Ainsi, les fragments recouvrants sont un grand classique, décrits dans les RFC 1858, RFC 3128 et RFC 5722. Normalement, le récepteur doit être paranoïaque, et ne pas faire une confiance aveugle aux décalages (offset) indiqués dans les paquets entrants, mais tous les programmeurs ne sont pas prudents. Il y a aussi le risque d'épuisement des ressources, puisque le récepteur doit garder en mémoire (le réassemblage implique le maintien d'un état) les fragments pas encore réassemblés. Un attaquant peut donc épuiser la mémoire en envoyant des fragments d'un datagramme qui ne sera jamais complet. Et il y a des identificateurs de fragment non-aléatoires, qui permettent d'autres attaques, documentées dans le RFC 7739 ou dans des articles comme « Fragmentation Considered Poisonous de Herzberg et Shulman (cf. aussi mon résumé). Enfin, la fragmentation peut aider à échapper au regard des IDS (cf. « Insertion, Evasion and Denial of Service: Eluding Network Intrusion Detection »).

Un autre problème très fréquent avec la fragmentation est causé par la configuration erronée de pare-feux. Souvent, des administrateurs réseau incompétents bloquent les messages ICMP Packet Too Big, nécessaires pour la découverte de la MTU du chemin. C'est de leur part une grosse erreur (expliquée dans le RFC 4890) mais cela arrive trop souvent. Résultat, si la MTU du chemin est inférieure à la MTU du premier lien, la machine émettrice envoie des paquets trop gros, et ne sait pas que ces paquets n'ont pas pu passer. On a donc créé un trou noir (les paquets disparaissent sans laisser de trace).

Ce bloquage injustifié des messages ICMP peut également être dû à des causes plus subtiles. Par exemple, si un pare-feu laisse sortir tous les paquets mais, en entrée, n'autorise que les paquets dont l'adresse IP source a été utilisée comme destination récemment, alors, les erreurs ICMP, émises par des routeurs intermédiaires et ayant donc une adresse IP source jamais vue, seront jetées. Notre RFC note que cette bogue dans les pare-feux est apparemment assez fréquente dans les boxes.

Toujours côté mauvaise configuration, le RFC cite aussi le problème des routeurs qui jettent les paquets ayant options ou extensions qu'ils ne connaissent pas, ce qui peut inclure les fragments. L'analyse du RFC 7872, ou celle dans l'article de Huston « IPv6, Large UDP Packets and the DNS », montre bien que ce problème est fréquent, trop fréquent. Ainsi, même si la découverte de la MTU du chemin se passe bien, les fragments n'arriveront pas à destination. Pourquoi cette mauvaise configuration ? C'est évidemment difficile à dire, cela peut aller de logiciels bogués jusqu'à un choix délibéré d'un administrateur réseau ignorant qui a vaguement entendu une légende urbaine du genre « les fragments sont un risque de sécurité ».

Dans les cas précédents, la perte du message ICMP Packet Too Big était clairement de la faute d'un humain, l'administrateur du pare-feu. Mais il peut y avoir des obstacles plus fondamentaux au bon fonctionnement de la découverte de la MTU du chemin. Par exemple, si un serveur DNS anycasté envoie un paquet trop gros, et qu'un routeur intermédiaire envoie le message Packet Too Big, ledit message ira vers l'adresse anycast du serveur, et atterrira peut-être vers une autre instance du serveur DNS, si le routeur qui a signalé le problème n'est pas dans le même bassin d'attraction que le client original. Le message ICMP ne sera donc pas reçu par l'instance qui aurait eu besoin de l'information. Le problème est d'autant plus génant que le DNS est le plus gros utilisateur d'UDP, et est donc particulièrement sensible aux problèmes de fragmentation (TCP gère mieux ces problèmes, avec la négociation de MSS).

Une variante du problème anycast survient lorsque le routage est unidirectionnel. Si l'émetteur n'est pas joignable, il ne recevra pas les messages ICMP. (Le cas est cité par le RFC mais me semble peu convaincant ; il y a peu de protocoles où l'émetteur peut se passer de recevoir des réponses. Et beaucoup de routeurs jettent les paquets pour lesquels ils n'ont pas de voie de retour, cf. RFC 3704.)

Maintenant qu'on a présenté en détail les problèmes liés à la fragmentation IP dans l'Internet actuel, quelles sont les approches possibles pour traiter ce problème ? La section 4 du RFC les présente. D'abord, les solutions situées dans la couche Transport. Comme indiqué plus haut, TCP peut éviter la fragmentation en découpant les données en segments dont chacun a une taille inférieure à la MTU du chemin (paramètre MSS, Maximum Segment Size). Cela suppose que la MSS soit réglée à une telle valeur (cf. mon article). Cela peut être manuel (si on sait qu'on va toujours passer par un tunnel avec faible MTU, on peut toujours configurer sa machine pour réduire la MSS), cela peut utiliser la procédure classique de découverte de la MTU du chemin ou bien cela peut utiliser la découverte de MTU sans ICMP du RFC 4821. D'autres protocoles que TCP peuvent fonctionner ainsi, comme DCCP (RFC 4340) ou SCTP (RFC 4960). À noter qu'UDP, lui, n'a pas de tel mécanisme, même si des travaux sont en cours pour cela.

Pour TCP, la méthode manuelle se nomme TCP clamping et peut se faire, par exemple avec Netfilter en mettant sur le routeur :

%  iptables -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN \
          -j TCPMSS --clamp-mss-to-pmtu
  

La méthode avec ICMP, on l'a vu, est fragile car les messages ICMP peuvent être bloqués. La méthode sans ICMP consiste pour TCP, en cas de détection de perte de paquets, à envoyer des paquets plus petits pour essayer de s'ajuster à la MTU du chemin. (Bien sûr, des paquets peuvent se perdre pour d'autres raisons que la MTU trop basse, et la mise en œuvre de cette technique est donc délicate.)

Autre solution, plutôt que d'impliquer la couche Transport, faire appel à la couche Application. Le RFC 8085 conseille aux applications qui font de l'UDP d'essayer d'éviter la fragmentation. Par exemple, si vous gérez un serveur DNS avec NSD, cela peut se faire en mettant dans le fichier de configuration :

   ipv4-edns-size: 1432
   ipv6-edns-size: 1432
  

Vous pouvez voir le résultat sur, par exemple, un des serveurs faisant autorité pour .bostik :

    
% dig +ignore @d.nic.fr DNSKEY bostik

; <<>> DiG 9.11.5-P4-5.1-Debian <<>> +ignore @d.nic.fr DNSKEY bostik
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12029
;; flags: qr aa tc rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1432
; COOKIE: ef8669d08e2d9b26bb1a8ab85e21830a8931f9ab23403def (good)
;; QUESTION SECTION:
;bostik.			IN DNSKEY

;; Query time: 2 msec
;; SERVER: 2001:678:c::1#53(2001:678:c::1)
;; WHEN: Fri Jan 17 10:48:58 CET 2020
;; MSG SIZE  rcvd: 63

  

Vous voyez que le serveur n'envoie pas de réponses de taille supérieure à 1 432 octets (la OPT PSEUDOSECTION). Au moment du test, la réponse faisait 1 461 octets, d'où le flag tc (TRuncated). Normalement, un client DNS, voyant que la réponse a été tronquée, réessaie en TCP (j'ai mis l'option +ignore à dig pour empêcher cela et illustrer le fonctionnement du DNS.)

En parlant du DNS, la section 5 du RFC liste des applications pour lesquelles la fragmentation joue un rôle important :

  • Le DNS utilise encore largement UDP (malgré le RFC 7766) et, notamment avec DNSSEC, les réponses peuvent nettement excéder la MTU typique. C'est en général le premier protocole qui souffre, quand la fragmentation ne marche pas, d'autant plus que la grande majorité des échanges sur l'Internet commence par des requêtes DNS. Le client DNS peut limiter la taille des données envoyées, via EDNS (RFC 6891) et le serveur peut également avoir sa propre limite. Le serveur qui n'a pas la place de tout mettre dans la réponse peut, dans certains cas, limiter les données envoyées (en omettant les adresses de colle, par exemple) et si ça ne suffit pas, indiquer que la réponse est tronquée, ce qui doit mener le client à réessayer avec TCP (que tout le monde devrait gérer mais certains clients et certains serveurs, ou plutôt leurs réseaux, ont des problèmes avec TCP, comme illustré dans « Measuring ATR »). L'importance de la fragmentation pour le DNS fait que le DNS Flag Day de 2020 est consacré à ce sujet.
  • Le protocole de routage OSPF utilise également UDP mais le problème est moins grave, car c'est un protocole interne, pas utilisé sur l'Internet public, l'administrateur réseau peut donc en général s'assurer que la fragmentation se passera bien. Et, de toute façon, la plupart des mises en œuvre d'OSPF limitent la taille de leurs messages pour être sûr de rester en dessous de la MTU.
  • L'encapsulation des paquets IP (pas vraiment la couche Application mais quand même un usage répandu) peut également créer des problèmes avec la fragmentation (cf. RFC 4459.) Cela concerne des protocoles comme IP-in-IP (RFC 2003), GRE (RFC 2784 et RFC 8086), et d'autres. Le RFC 7588 décrit une stratégie générale pour ces protocoles.
  • Le RFC note que certains protocoles, pour des raisons de performance, assument tout à fait d'envoyer de très grands paquets et donc de compter sur une fragmentation qui marche. Ce sont notamment des protocoles qui sont conçus pour des milieux très particuliers, comme LTP (RFC 5326) qui doit fonctionner en présence d'énormes latences.

Compte-tenu de tout ceci, quelles recommandations concrètes donner ? Cela dépend évidemment du public cible. La section 6 de notre RFC donne des conseils pour les concepteurs et conceptrices de protocoles et pour les différents types de développeurs et développeuses qui vont programmer des parties différentes du système. D'abord, les protocoles, sujet principal pour l'IETF. Compte-tenu des importants problèmes pratiques que pose la fragmentation dans l'Internet actuel, le RFC prend une décision douloureuse : plutôt que de chercher à réparer l'Internet, on jette l'éponge et on ne conçoit plus de protocoles qui dépendent de la fragmentation. De tels protocoles ne seraient raisonnables que dans des environnements fermés et contrôlés. Comme souvent à l'IETF, le choix était difficile car il faut choisir entre les principes (la fragmentation fait partie d'IP, les composants de l'Internet ne doivent pas l'empêcher) et la réalité d'un monde de middleboxes mal programmées et mal gérées. Comme pour la décision de faire passer beaucoup de nouveaux protocoles sur HTTPS, le choix ici a été de prendre acte de l'ossification de l'Internet, et de s'y résigner.

Pour ne pas dépendre de la fragmentation, les nouveaux protocoles peuvent utiliser une MTU suffisamment petite pour passer partout, ou bien utiliser un système de découverte de la MTU du chemin suffisamment fiable, comme celui du RFC 4821. Pour UDP, le RFC renvoie aux recommandations de la section 3.2 du RFC 8085.

Ensuite, les conseils aux programmeurs et programmeuses. D'abord, dans les systèmes d'exploitation. Le RFC demande que la PLPMTUD (RFC 8899) soit disponible dans les bibliothèques proposées aux applications.

Ensuite, pour ceux et celles qui programment les middleboxes, le RFC rappelle quand même qu'elles doivent respecter les RFC sur IPv4 (RFC 791) et IPv6 (RFC 8200). Pour beaucoup de fonctions assurées par ces boitiers (comme le filtrage), cela implique de réassembler les paquets fragmentés, et donc de maintenir un état. Les systèmes avec état sont plus compliqués et plus chers (il faut davantage de mémoire) ce qui motive parfois à préférer les systèmes sans état. Ceux-là n'ont que deux choix pour gérer la fragmentation : violer les RFC ou bien jeter tous les fragments. Évidemment, aucune de ces deux options n'est acceptable. Le RFC demande qu'au minimum, si on massacre le protocole IP, cela soit documenté. (Ces middleboxes sont souvent traitées comme des boites noires, installées sans les comprendre et sans pouvoir déboguer les conséquences.)

Enfin, les opérateurs des réseaux doivent s'assurer que la PMTUD fonctionne, donc émettre des Packet Too Big si le paquet est plus gros que la MTU, et ne pas bloquer les paquets ICMP. Notre RFC permet toutefois de limiter leur rythme (RFC 1812 et RFC 4443). En tout cas, comme le rappelle le RFC 4890, filtrer les paquets ICMP Packet Too Big est mal !

De la même façon, le RFC rappelle aux opérateurs réseau qu'on ne doit pas filtrer les fragments. Ils sont utiles et légitimes.

Notez que les recommandations de ce RFC peuvent sembler contradictoires : on reconnait que la fragmentation marche mal et qu'il ne faut donc pas compter dessus mais, en même temps, on rappelle qu'il faut se battre pour qu'elle marche mieux. En fait, il n'y a pas de contradiction, juste du réalisme. L'Internet n'ayant pas de Chef Suprême qui coordonne tout, on ne peut pas espérer qu'une recommandation de l'IETF soit déployée immédiatement partout. On se bat donc pour améliorer les choses (ne pas bloquer les fragments, ne pas bloquer les messages ICMP Packet Too Big) tout en étant conscient que ça ne marchera pas à 100 % et que les administrateurs système et réseau doivent en être conscients.


Téléchargez le RFC 8900


L'article seul

Exposé sur les RFC au FGI Bénin

Première rédaction de cet article le 10 septembre 2020


Le 9 septembre, dans le cadre du Forum de la Gouvernance de l'Internet au Bénin, j'ai fait (en ligne, bien sûr) un exposé sur les RFC. C'est quoi, ça sert à quoi, qui les écrit ?

L'évènement « École de la gouvernance de l'Internet » était organisé par le FGI Bénin. Merci à Muriel Alapini pour l'organisation. Plusieurs autres exposés très intéressants étaient présentés, afin de fournir à ceux et celles qui participent aux discussions sur la gouvernance de l'Internet les bases nécessaires pour comprendre l'Internet. Par exemple, félicitations à Yazid Akanho pour son exposé très complet et très bien expliqué sur le système de serveurs de noms de la racine.

Voici les supports de mon exposé :


L'article seul

Outils pour obtenir des informations BGP publiques

Première rédaction de cet article le 4 septembre 2020
Dernière mise à jour le 9 septembre 2020


Cette page (que j'espère maintenir à jour) rassemble les outils existants pour obtenir de l'information sur les annonces BGP, même si on n'a pas d'accès à des routeurs BGP.

Le protocole de routage BGP est sans doute le système le plus crucial pour le bon fonctionnement de l'Internet. Contrairement à des protocoles applicatifs comme HTTP, il n'est pas prévu que tout le monde puisse parler BGP : seule une partie des routeurs le fait et, sauf si vous travaillez chez un acteur important de l'Internet, vous n'avez probablement pas accès à un routeur BGP, encore moins un routeur de la DFZ. D'où l'intérêt de divers outils et services qui permettent d'obtenir des informations BGP sans avoir cet accès privilégié.

D'ailleurs, même si vous avez accès à un ou plusieurs routeurs BGP, cela n'est pas forcément suffisant. Vu la façon dont fonctionne BGP, tous les routeurs ne voient pas la même chose (même les routeurs de la DFZ) et de tels outils sont donc utiles même pour les professionnels du réseau. Attention, certains de ces outils sont simples à utiliser, d'autres plus complexes mais dans tous les cas, comprendre ce qu'ils affichent nécessitent des compétences dans le fonctionnement de l'Internet, et dans le protocole BGP.

Cet article regroupe les outils que j'utilise. Vous pouvez m'en suggérer d'autres (ou bien corriger des erreurs) mais cette liste est forcément incomplète et subjective. Alors, commençons tout de suite par le principal outil dont je me sers, RIPEstat. RIPEstat est une interface Web notamment vers les données récoltées par le RIS (Routing Information Service), un ensemble de centaines de machines parlant BGP et qui s'appairent avec tout le monde pour récolter le plus d'informations BGP possibles. En échange d'une adresse IP, d'un préfixe ou d'un AS, vous pouvez obtenir plein d'informations. On va se concentrer sur celles liées au routage. Prenons par exemple le préfixe 2a01:e30::/28, utilisé pour les clients de Free. (Si vous ne connaissez pas le préfixe, entrez l'adresse IP, RIPEstat trouvera le préfixe englobant le plus spécifique.) Voici ce qu'affiche l'onglet « Routage » de RIPEstat, en https://stat.ripe.net/2a01%3Ae34%3A%3A%2F28#tabId=routing : ripe-stat-free-routing.png

(Une minorité de routeurs du RIS voit ce préfixe ; il n'est sans doute pas annoncé à tout le monde, et il existe un /26 plus générique. Rappelez-vous ce que j'ai dit que tout les routeurs BGP ne voient pas la même chose.) Ce Routing status n'est qu'un des widgets disponible, plus bas dans la page vous trouverez de nombreuses autres informations. J'aime bien le widget historique qui permet de voir comment a été annoncé ce préfixe dans le passé : ripe-stat-free-history.png

Et aussi le rythme des mises à jour, souvent indicatifs d'un problème. Ici, par exemple, le widget BGP update activity montre la panne de Level 3/CenturyLink du 30 août 2020. On a donné comme ressource à voir l'AS 3356 (celui de Level 3) et zoomé pour n'avoir que la partie intéressante. On voit alors le gros surcroit d'activité BGP engendré par le problème chez Level 3. C'est toujours visitable aujourd'hui, grâce aux URL intégrant la date : https://stat.ripe.net/widget/bgp-update-activity#w.starttime=2020-08-19T09%3A00%3A00&w.endtime=2020-09-02T09%3A00%3A00&w.resource=AS3356. ripe-stat-level3.png

Du fait qu'il existe un URL stable pour les informations de RIPEstat, on peut facilement embarquer du RIPEstat dans ses pages Web, ses outils de supervision, etc.

RIPEstat est très gourmand en ressources, vu son utilisation massive de plein de JavaScript. Vous avez intérêt à avoir une machine riche en RAM et, même ainsi, vous verrez souvent l'avertissement (ici de Firefox) comme quoi un script ralentit la machine : ripe-stat-slow.png

Il est de toute façon bon de ne pas dépendre d'un seul service, même géré par une organisation sans but lucratif et fondée sur un projet commun comme l'est le RIPE-NCC. Tout service peut disparaitre ou tomber en panne précisement au moment où on en a besoin (si on veut investiguer un problème en cours, par exemple). Une alternative intéressante est bgp.tools. C'est plus léger que RIPEstat (mais beaucoup moins riche) et cela se concentre sur des informations essentielles, donc cela peut être pratique pour des utilisateurs moins familiers de BGP. (Je ne trouve pas sur quelles données ils s'appuient pour afficher leurs informations : rappelez-vous que les informations BGP ne sont pas les mêmes partout, d'où l'importance d'avoir un grand nombre de routeurs situés un peu partout, comme le RIS. Je ne connais pas la représentativité des collecteurs d'informations de bgp.tools.)

Voici par exemple ce que voit bgp.tools sur le préfixe 2a01:e30::/28 cité plus haut (URL https://bgp.tools/prefix/2a01:e30::/28) : bgptools-prefix-specific.png

Et sur l'AS associé : bgptools-as.png

Vous avez noté que dans les informations sur le préfixe, la rubrique Upstreams (transitaires) était vide. bgp.tools ne l'affiche pas lorsqu'il y a un préfixe plus général et visible plus globalement, ce qui est le cas ici (rappelez-vous que le 2a01:e30::/28 n'est pas annoncé partout). Avec le préfixe général, on a bien l'information : bgptools-prefix-generic.png

En prime, bgp.tools nous prévient que Free n'a qu'un seul transitaire en IPv6, Cogent et que celui-ci refuse de s'appairer avec Hurricane Electric, ce qui prive les abonnés Free d'une partie de l'Internet.

Dans la série « sites Web pour récupérer des informations BGP », beaucoup de gens utilisent https://bgp.he.net/ qui donne, par exemple : he-bgp-free.png

Jusqu'ici, je n'ai listé que des outils Web. Et si on n'aime pas le Web ? Les mêmes informations sont souvent disponibles par d'autres protocoles, par exemple whois. (RIPEstat a également une API, que je n'utilise personnellement pas.) Le RIS est ainsi interrogeable par whois :

% whois -h riswhois.ripe.net 2a01:e30::/28
...
route6:       2a01:e30::/28
origin:       AS12322
descr:        PROXAD Free SAS, FR
lastupd-frst: 2020-04-13 01:00Z  2001:7f8:20:101::208:223@rrc13
lastupd-last: 2020-09-02 07:37Z  2001:7f8:20:101::209:93@rrc13
seen-at:      rrc00,rrc01,rrc03,rrc04,rrc05,rrc07,rrc10,rrc11,rrc12,rrc13,rrc15,rrc20,rrc21,rrc23
num-rispeers: 156
source:       RISWHOIS

Il y a évidemment moins d'information que par le Web mais cela peut suffire. Si on veut juste une correspondance entre une adresse IP et l'AS qui l'annonce, Team Cymru propose plusieurs outils comme whois :

% whois -h whois.cymru.com 80.67.169.12
AS      | IP               | AS Name
20766   | 80.67.169.12     | GITOYEN-MAIN-AS The main Autonomous System of Gitoyen (Paris, France)., FR

Mais aussi une passerelle DNS. Celle-ci nécessite d'inverser les différents composants de l'adresse IP. Par exemple, pour 204.62.14.153, il faudra interroger 153.14.62.204.origin.asn.cymru.com. Ça peut s'automatiser avec awk :

% dig +short  TXT $(echo 204.62.14.153 | awk -F. '{print $4 "." $3 "." $2 "." $1 ".origin.asn.cymru.com" }')
"46636 | 204.62.12.0/22 | US | arin | 2008-12-24"
   

Pour IPv6, cette inversion peut se faire avec le programme ipv6calc. On peut créer une fonction shell pour se faciliter la vie :

% which bgproutednscymru
bgproutednscymru () {
	address=$1
	if echo $address | fgrep -q : -; then
	    domain=$(echo $1 | ipv6calc --addr2ip6_arpa | sed 's/ip6\.arpa\.$/origin6.asn.cymru.com./') 
	else
	    domain=$(echo $1 | awk -F. '{print $4 "." $3 "." $2 "." $1 ".origin.asn.cymru.com" }')
	fi
	dig +short TXT $domain
}

% bgproutednscymru 80.67.169.12
"20766 | 80.67.160.0/19 | FR | ripencc | 2001-05-21"

% bgproutednscymru 2001:910:800::12
"20766 | 2001:910::/32 | FR | ripencc | 2002-09-24"

Le service RouteViews a également une passerelle DNS, mais uniquement pour IPv4, avec le domaine aspath.routeviews.org. Elle indique le chemin d'AS (vers le collecteur de RouteViews), pas uniquement l'origine. Avec une fonction analogue à celle ci-dessus, on obtient :

% which bgproutednsrouteviews
...
	dig +short TXT `echo $1 | awk -F. '{print $4 "." $3 "." $2 "." $1 ".aspath.routeviews.org" }'` | \
              awk -F\" '{print "AS path: " $2 "\nRoute: " $4 "/" $6}'
}

% bgproutednsrouteviews 80.67.169.12
AS path: 53767 3257 1299 20766
Route: 80.67.160.0/19
   

Un exemple de son utilisation figure dans mon article sur un opérateur nord-coréen.

Plus original, il existe un bot sur le fédivers (documenté ici) pour récupérer l'AS d'origine d'une adresse IP : fediverse-bgp-free.png.

J'ai parlé d'API à propos de RIPEstat. Personnellement, j'utilise l'API de QRator. Il faut s'enregistrer sur le site (la plupart des services présentés ici ne nécessitent pas d'enregistrement) pour obtenir une clé d'API puis lire la documentation (l'API produit évidemment du JSON). J'ai fait une fonction shell pour me faciliter la vie :

bgpqrator () {
    if [ -z "$1" ]; then
	echo "Usage: bgpqrator IP-address"
	return 1
    fi
    curl -s -X GET "https://api.radar.qrator.net/v1/lookup/ip?query=$1" \
	 -H  "accept: application/json" -H "QRADAR-API-KEY: $(cat ~/.qrator)" | \
	jq .
}
  

Et cela me permet de faire :

% bgpqrator 2a01:e30::/28
{
  "meta": {
    "status": "success",
    "code": 200
  },
  "data": [
    {
      "id": "12322",
      "name": "PROXAD",
      "short_descr": "Free SAS",
      "prefix": "2a01:e00::/26",
      "as_num": "12322",
      "found_ips": "{2a01:e30::/28}"
    },
    {
      "id": "12322",
      "name": "PROXAD",
      "short_descr": "Free SAS",
      "prefix": "2a01:e30::/28",
      "as_num": "12322",
      "found_ips": "{2a01:e30::/28}"
    }
  ]
}
  

Un point important de BGP aujourd'hui est la possibilité de signer les informations pour améliorer la sécurité, avec l'infrastructure nommée RPKI. Pour vérifier ces signatures, on peut installer son propre validateur comme Routinator (après tout, toutes les données de la RPKI sont publiques) mais c'est un peu compliqué à faire et surtout à maintenir, donc il peut être plus intéressant d'utiliser des services en ligne. Par exemple, https://bgp.he.net fait cette vérification et vous affiche le résultat (cf. la copie d'écran plus haut). De même, RIPEstat affiche la validité d'une annonce comparée aux IRR et aux ROA : ripe-stat-rpki.png

Et si on veut obtenir cette information autrement que via le Web, il y a le serveur whois de BGPmon :

% whois -h whois.bgpmon.net 80.67.169.12 
...
Prefix:              80.67.160.0/19
Prefix description:  Route to Gitoyen
Origin AS:           20766
Origin AS Name:      GITOYEN-MAIN-AS The main Autonomous System of Gitoyen (Paris, France)., FR
RPKI status:         ROA validation successful
First seen:          2019-02-23
Last seen:           2020-08-29
Seen by #peers:      37

Notez que je ne connais pas encore de moyen simple de récupérer les ROA sur un site Web. Les services ci-dessus indiquent juste le résultat de la validation, pas le ROA d'origine.

Jusqu'à présent, on a vu des techniques qui indiquaient une vue « globale », supposant qu'on avait à peu près le même résultat sur tous les routeurs BGP. En pratique, on sait que ce n'est pas vrai, les différents routeurs ne voient pas exactement la même chose, et il est souvent utile de regarder ce que voit un routeur particulier. C'est le rôle des Looking Glasses. Il en existe beaucoup, mais pas toujours là où on voudrait. (Pour un problème récent, je cherchais un looking glass chez Algérie Télécom, sans en trouver.) Bref, il faut utiliser les annuaires comme http://www.traceroute.org/#Looking%20Glass et ils ne sont évidemment jamais à jour, on a des mauvaises surprises. C'est un cas où il faut parfois compter sur les moteurs de recherche.

Aux joies du Web moderne avec tous ses gadgets et son interactivité graphique, et même aux outils plus techniques qu'on vient de voir, on peut souhaiter préférer l'analyse qu'on fait soi-même à partir de données brutes. On télécharge des fichiers rassemblant les données BGP (soit l'état de la RIB du routeur, soit les annonces BGP) et on les analyse avec le programme de son choix. Un format standard existe même pour ces fichiers, MRT, normalisé dans le RFC 6396. Un exemple d'utilisation de ces fichiers figure dans mon article sur une panne à Saint-Pierre-et-Miquelon.

Où peut-on trouver de tels fichiers ? RouteViews en fournit, une archive qui remonte à 2001… Chose amusante, la seule taille de ces fichiers peut indiquer un problème car les perturbations de l'Internet se traduisent en général par une augmentation importante des mises à jour BGP. Ainsi, la panne de Level 3/CenturyLink du 30 août 2020 se voit très bien (à partir de 10:00 h UTC) : routeviews-level3.png

On peut aussi avoir de telles données via le RIS, cf. la documentation. C'est sur ces fichiers issus du RIS que s'appuie le bot fédivers cité plus haut.


L'article seul

RFC 8880: Special Use Domain Name 'ipv4only.arpa'

Date de publication du RFC : Août 2020
Auteur(s) du RFC : S. Cheshire (Apple), D. Schinazi (Google)
Chemin des normes
Première rédaction de cet article le 1 septembre 2020


La technique NAT64 pour permettre à des machines d'un réseau purement IPv6 d'accéder à des services toujours uniquement en IPv4 repose sur un préfixe IPv6 spécial, utilisé pour donner l'impression aux machines IPv6 que le service archaïque a de l'IPv6. Dans certains cas, il est pratique que toutes les machines du réseau connaissent ce préfixe. Une technique possible a été proposée dans le RFC 7050, utilisant un nom de domaine prévu à cet effet, ipv4only.arpa. Mais ce nom de domaine n'avait pas été documenté rigoureusement comme nom de domaine spécial. C'est désormais fait, avec ce nouveau RFC.

Le NAT64 est normalisé dans le RFC 6146, et la découverte, par une machine, du préfixe IPv6 utilisé, est dans le RFC 7050. Ce dernier RFC avait créé le nom de domaine ipv4only.arpa, mais sans préciser clairement son statut, et notamment sans demander son insertion dans le registre des noms de domaine spéciaux. (Cette bavure bureaucratique est d'ailleurs mentionnée dans le RFC 8244.) Le but de notre nouveau RFC 8880 est de réparer cet oubli et de documenter proprement le nom de domaine spécial ipv4only.arpa.

Un petit rappel si vous n'avez pas le courage de lire le RFC 7050 : le problème qu'on cherche à résoudre est celui d'une machine qui voudrait bénéficier de NAT64 mais sans utiliser systématiquement le résolveur DNS64 (RFC 6147). Pour cela, elle émet une requête DNS de type AAAA (adresse IPv6) pour le nom ipv4only.arpa. Comme son nom l'indique, ce nom n'a que des données de type A (adresses IPv4). Si on récupère des adresses IPv6, c'est que le résolveur DNS faisait du DNS64, et on peut déduire le préfixe IPv6 utilisé de la réponse. Sans DNS64, on aura une réponse normale, rien sur IPv6, et deux adresses stables en IPv4 :


% dig AAAA ipv4only.arpa
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18633
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
ipv4only.arpa.		3600 IN	SOA sns.dns.icann.org. noc.dns.icann.org. (
				2020040300 ; serial
				7200       ; refresh (2 hours)
				3600       ; retry (1 hour)
				604800     ; expire (1 week)
				3600       ; minimum (1 hour)
				)

;; Query time: 95 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu May 07 15:22:20 CEST 2020
;; MSG SIZE  rcvd: 127

% dig A ipv4only.arpa
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2328
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 14, ADDITIONAL: 27
...
;; ANSWER SECTION:
ipv4only.arpa.		86400 IN A 192.0.0.170
ipv4only.arpa.		86400 IN A 192.0.0.171
...
;; Query time: 238 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu May 07 14:24:19 CEST 2020
;; MSG SIZE  rcvd: 1171

    

En quoi est-ce que ce nom ipv4only.arpa est « spécial » (section 2 du RFC) ? D'abord, il n'y a aucune raison de le visiter en temps normal, il n'a aucune ressource utile, et ses deux adresses IP sont stables et bien connues. Paradoxalement, si on l'interroge, c'est qu'on espère un mensonge, l'apparition d'adresses IPv6 qui ne sont pas dans la zone originale. Ce nom de domaine permet en fait une communication de la machine terminale vers un intermédiaire (le résolveur DNS), pour savoir ce qu'il fait. C'est en cela que ipv4only.arpa est spécial.

Mais, rappelez-vous, le RFC 7050 avait oublié de déclarer ipv4only.arpa comme étant spécial. Résultat, les différents logiciels qui traitent des noms de domaine le traitent de la manière normale et, comme le note la section 3 de notre RFC, cela a quelques conséquences ennuyeuses :

  • Si la machine NAT64 utilise un résolveur DNS différent de celui du réseau local, par exemple un résolveur public, ipv4only.arpa peut ne pas donner le résultat attendu,
  • Les résolveurs DNS64 doivent faire une résolution normale ipv4only.arpa alors qu'ils devraient avoir le droit de tout gérer localement et de fabriquer des réponses directement.

Bref, il fallait compléter le RFC 7050, en suivant le cadre du RFC 6761. Ce RFC 6761 impose de lister, pour chaque catégorie de logiciel, en quoi le nom de domaine est spécial. C'est fait dans la section 7 de notre RFC, qui indique que :

  • Pour les utilisateurs finaux, pour les applications, pour les serveurs faisant autorité, et pour les résolveurs qui ne font que faire suivre à un résolveur plus gros (ce qui est typiquement le cas de celui des boxes), rien de particulier, ils et elles peuvent traiter ipv4only.arpa comme un domaine normal. Si elles le désirent, les applications peuvent résoudre ce nom ipv4only.arpa et apprendre ainsi si un résolveur DNS64 est sur le trajet, mais ce n'est pas obligatoire.
  • Les bibliothèques qui gèrent la résolution de noms (comme la libc sur Unix) doivent par contre considérer ipv4only.arpa comme spécial. Notamment, elles doivent utiliser le résolveur configuré par le réseau (par exemple via DHCP) pour résoudre ce nom. Le demander à un résolveur public n'aurait en effet pas de sens.
  • Les résolveurs qui ne font pas de DNS64 traitent ipv4only.arpa comme normal, et leurs clients apprendront donc ainsi que leur résolveur ne fait pas de DNS64.
  • Les résolveurs DNS64 vont synthétiser des adresses IPv6 en réponse aux requêtes de type AAAA pour ipv4only.arpa, et leurs clients apprendront donc ainsi que leur résolveur fait du DNS64, et sauront quel préfixe IPv6 est utilisé. Ils n'ont pas besoin de consulter les serveurs faisant autorité, qui ne pourraient rien leur apprendre qui n'est pas déjà dans le RFC. L'annexe A du RFC donne un exemple de configuration pour BIND pour attendre cet objectif.

À noter qu'outre ipv4only.arpa, notre RFC réserve deux autres noms spéciaux, 170.0.0.192.in-addr.arpa et 171.0.0.192.in-addr.arpa, pour permettre la « résolution inverse ». Contrairement à ipv4only.arpa, ils ne sont pas actuellement délégués, et un résolveur normal, qui ne connait pas DNS64, répondra donc NXDOMAIN (ce nom n'existe pas).

Sinon, la section 5 de notre RFC est dédiée à la sécurité et note notamment que les noms synthétisés ne peuvent évidemment pas être validés avec DNSSEC. C'est pour cela que la délégation de ipv4only.arpa n'est même pas signée. (C'est un changement depuis le RFC 7050, qui demandait au contraire une zone signée, ce que ipv4only.arpa avait été au début.)

Vu par les sondes RIPE Atlas, voici les réponses de résolveurs à ce domaine spécial :

% blaeu-resolve -r 1000 -q AAAA ipv4only.arpa 
[] : 986 occurrences 
[64:ff9b::c000:aa 64:ff9b::c000:ab] : 4 occurrences 
[2a01:9820:0:1:0:1:c000:aa 2a01:9820:0:1:0:1:c000:ab] : 1 occurrences 
[2a0a:e5c0:0:1::c000:aa 2a0a:e5c0:0:1::c000:ab] : 1 occurrences 
Test #24069173 done at 2020-02-24T14:49:43Z
      

Sur mille sondes Atlas, la grande majorité ne trouve pas d'adresse IPv6 pour ipv4only.arpa ce qui, comme le nom de domaine l'indique, est le comportement par défaut. Quelques sondes sont derrière un résolveur DNS64, utilisant en général le préfixe bien connu du RFC 7050 (les réponses 64:ff9b::…), mais parfois d'autres préfixes (NSP - Network-Specific Prefix - dans la terminologie du RFC 7050).


Téléchargez le RFC 8880


L'article seul

RFC 8874: Working Group GitHub Usage Guidance

Date de publication du RFC : Août 2020
Auteur(s) du RFC : M. Thomson (Mozilla), B. Stark (AT&T)
Pour information
Réalisé dans le cadre du groupe de travail IETF git
Première rédaction de cet article le 29 août 2020


De nombreux groupes de travail de l'IETF utilisent GitHub pour coordonner leur travail dans cet organisme de normalisation. Ce nouveau RFC donne des règles et des conseils à suivre dans ce cas. Personnellement, je déplore qu'il ne contienne pas de mise en garde contre l'utilisation d'un service centralisé extérieur à l'IETF.

L'IETF développe des normes pour l'Internet, notamment la plupart des RFC. Ce travail met en jeu des documents, les brouillons de futurs RFC, des discussions, des problèmes à résoudre. Les discussions sont assez complexes, durent souvent des mois, et nécessitent de suivre pas mal de problèmes, avec beaucoup d'éléments à garder en tête. Bref, des outils informatiques peuvent aider. Mais attention, l'IETF a des particularités (cf. RFC 2418). D'abord, tout doit être public, le but étant que le développement des normes soit aussi transparent que possible. Et il ne s'agit pas que de regarder, il faut que tous les participants (l'IETF est ouverte) puissent intervenir. Ensuite, tout doit être archivé, car il faudra pouvoir rendre compte au public, même des années après, et montrer comment l'IETF est parvenue à une décision. (D'autres SDO, comme l'AFNOR, sont bien plus fermées, et n'ont pas ces exigences d'ouverture et de traçabilité.)

Traditionnellement, l'IETF n'avait que peu d'outils de travail en groupe et chacun se débrouillait de son côté pour suivre le travail tant bien que mal. Mais les choses ont changé et l'IETF a désormais une importante série d'outils, aussi bien les « officiels », maintenus par un prestataire extérieur, AMSL, que des officieux, disponibles sur https://tools.ietf.org/ et maintenus par des volontaires. Les outils officiels de l'IETF, mis à la disposition de tous, comportent notamment :

Il n'y a pas par contre de VCS (dans les outils officieux, il y a un service Subversion) ou de mécanisme de suivi de tickets (il y a un Trac officieux en https://trac.ietf.org/, il est très peu utilisé).

Un VCS est pourtant un outil très utile, et pas seulement pour les programmeurs. Travaillant en général sur des fichiers texte quelconques, il permet de coordonner le travail de plusieurs personnes sur un document, que celui-ci soit du code source ou bien un Internet-Draft. C'est le cas par exemple du VCS décentralisé git, très utilisé aujourd'hui.

On peut utiliser git tout seul, d'autant plus que le fait qu'il doit décentralisé ne nécessite pas d'autorité de coordination (c'est ainsi qu'est développé le noyau Linux, par exemple). Mais beaucoup de programmeurs (ou d'auteurs d'Internet Drafts) utilisent une forge complète, intégrant un VCS mais aussi un système de gestion de rapports, un wiki et d'autres fonctions. La plus connue de ces forges est GitHub, propriété de Microsoft. Comme souvent avec les réseaux sociaux (GitHub est le Facebook du geek), la taille compte : plus il y a de gens sur le réseau social, plus il est utile. C'est pour cela qu'il y a des fortes pressions à la centralisation, et une difficulté, en pratique, à partir, sauf à perdre les possibilités de coopération (c'est pour cela que prétendre qu'il y a consentement des utilisateurs aux pratiques déplorables des réseaux sociaux centralisés est une farce : on n'a pas le choix). L'utilisation de GitHub n'est évidemment pas obligatoire à l'IETF mais elle est répandue. Regardez par exemple le groupe de travail QUIC, celui sur HTTP, ou celui sur les portails captifs. GitHub est également utilisé en dehors des groupes de travail, par exemple pour les résultats et présentations des hackathons. Le but de ce RFC est de fournir quelques règles utiles (mais facultatives) pour les groupes qui travailleront sur GitHub. Un autre RFC, le RFC 8875, est plus concret, donnant des règles précises de configuration de GitHub pour un groupe de travail.

L'introduction du RFC rappelle juste en passant qu'il existe d'autres forges comme Bitbucket et du logiciel libre qui permet d'installer diverses forges locales. Ainsi, le logiciel de GitLab permet d'installer des forges indépendantes comme FramaGit. (J'ai récemment migré tous mes dépôts vers un GitLab.) C'est FramaGit qui est utilisé pour le développement de la future norme sur la QNAME minimisation, qui remplacera le RFC 7816. Mais GitHub est de loin le plus utilisé et, par exemple, pour le successeur du RFC 7816, quasiment tous les contributeurs avaient été obligés de se créer un compte sur FramaGit, ils n'en avaient pas avant. Le RFC ne rappelle même pas les dangers qu'il y a à utiliser un service centralisé, géré par une entreprise privée. Si GitLab est mentionné dans le RFC, la possibilité d'une instance IETF (gérée par l'actuel prestataire qui administre les ressources IETF, AMSL) n'apparait pas. Simple question d'argent ou problème plus fondamental ?

Bon, au boulot, maintenant, quelles sont les règles listées par ce RFC ? (Rappel : ce RFC reste à un haut niveau, les instructions précises sont dans le RFC 8875.) D'abord, comment décider d'utiliser (ou non) GitHub (section 3 du RFC) ? Fondamentalement, ce sont les présidents du groupe qui décident, après consultation avec les directeurs de la zone (une zone regroupe plusieurs groupes de travail). Ils vont également définir les conditions d'utilisation (par exemple, décider d'utiliser le système de rapports - issues - ou pas). Notez que, même si le groupe en tant que tel n'utilise pas GitHub, certains contributeurs peuvent évidemment s'en servir pour leurs besoins propres. D'une manière générale, le travail fait sur GitHub n'a pas d'autorité particulière, c'est juste un élément parmi d'autres pour le groupe. Ainsi, ce n'est pas parce qu'un ticket est fermé sur GitHub que le groupe de travail est lié par cette fermeture et ne peut plus discuter le point en question.

Le groupe peut ensuite créer un dépôt par document, ce qui est recommandé (c'est ce que fait le groupe capport) ou bien, s'il préfère, un seul dépôt pour tous les documents du groupe (sans aller jusque là, le groupe QUIC met tous les documents de base du protocole dans le même dépôt).

Les documents sont a priori en XML, format standard des documents IETF (cf. RFC 7991) mais on a le droit d'utiliser Markdown (cf. RFC 7328). Par contre, les formats doivent être du texte, pas de binaire comme avec LibreOffice, binaire qui passerait mal avec git (pas moyen de voir les différences d'une version à l'autre).

Ensuite, un peu de paperasserie (section 2 du RFC), avec les règles administratives. Le RFC recommande de créer une organisation dans GitHub pour chaque groupe de travail qui utilise GitHub (il n'y a pas d'organisation « IETF »). Les propriétaires de cette organisation doivent être les directeurs de la zone dont fait partie le groupe, et les présidents ou présidentes du groupe. Les auteurs des documents doivent évidemment avoir un accès en écriture. Les dépôts du groupe de travail sur GitHub doivent être clairement documentés, indiquant la charte du groupe, sa politique, sa gestion des contributeurs (fichier CONTRIBUTING, que GitHub met en avant), etc. Et il faut évidemment pointer sur la politique générale de l'IETF, le Note Well (qui est tout le temps cité dans les réunions physiques, mais qui doit également être connu des gens qui n'interagissent que via GitHub). En sens inverse, le dépôt GitHub doit être clairement indiqué sur les pages du groupe sur le site de l'IETF, et sur les Internet-Drafts produits.

Un des intérêts d'une forge comme GitHub est qu'on dispose de plusieurs moyens de contribuer à un projet. Lesquels utiliser pour des documents IETF (section 4 du RFC) ? Il y a d'abord le système de suivi des questions. Il permet de noter les questions en cours et les décisions prises peuvent être inscrites dans le ticket, avant de le fermer. D'un coup d'œil, on peut voir facilement le travail en cours, et ce qui reste à faire. Dans chaque ticket, on peut voir l'ensemble des éléments liés à une question. Le système de suivi de questions (issue tracker) de GitHub permet bien d'autres choses, comme l'affectation d'un ticket à une personne. Un service très utile est l'étiquetage des questions (« rédaction » pour un texte mal écrit, « technique » pour un problème technique, etc). Comme dans la plupart des cas, le RFC n'impose pas une politique de gestion des étiquettes, seulement le fait qu'il y ait une politique et qu'elle soit communiquée aux participants. Même chose pour la politique de fermeture des tickets (un sujet parfois sensible).

Une fonction qui a beaucoup contribué à la popularité du GitHub est la possibilité de pull request (qui a une bonne traduction en français ? Alexis La Goutte suggère « demande d'intégration »), c'est-à-dire d'enregistrer une série de modifications qui sont collectivement soumises à l'approbation ou au rejet d'un responsable. Cela permet de proposer une contribution sans avoir l'autorisation d'écriture dans le dépôt, tout en permettant une grande traçabilité des contributions. C'est la méthode conseillée par le RFC pour soumettre des contributions significatives, notamment en raison de cette traçabilité. Par contre, il n'est pas conseillé de discuter de questions complexes dans les commentaires de la pull request ; comme la requête peut être modifiée, les commentaires risquent de devenir décalés par rapport au dernier état de la pull request.

GitHub permet d'avoir un flux de syndication pour les dépôts. C'est ce que j'utilise personnellement pour suivre les activités des dépôts qui m'intéressent. Mais il existe d'autres méthodes comme l'outil github-notify-ml, très utilisé à l'IETF.

J'ai dit plusieurs fois que ce RFC n'imposait pas une façon d'utiliser GitHub pour un groupe de travail IETF. Il y a plusieurs politiques possibles, chaque groupe de travail peut faire différemment, l'important étant que les participants au groupe soient au courant. Pour faciliter le choix, la section 5 du RFC propose un jeu de politiques typiques, parmi lesquelles on peut choisir. Elles sont classées de la plus élémentaire, à celle qui utilise le plus les possibilités de GitHub :

  • Dans le cas le plus simple, le groupe travaille comme avant, il ne se sert que GitHub que pour stocker les documents, notamment les Internet-Drafts et leur historique.
  • Plus élaborée, une politique avec utilisation du système de suivi des questions, mais où les discussions ont toujours lieu ailleurs que sur GitHub, les tickets ne stockant que les questions en cours et leur résolution. (Comme le note le RFC, c'est difficile à garantir, les discussions s'invitent souvent sur les tickets.)
  • Encore plus githubienne, la politique où cette fois la discussion a officiellement lieu sur les tickets GitHub. La liste de diffusion (le principal outil officiel des groupes de travail IETF) a le dernier mot mais le gros du travail a été fait sur le système de gestion de tickets. Attention : cela veut dire qu'une bonne partie des explications et justifications à un RFC vont rester sur une plate-forme privée, qui peut changer sa politique à sa guise, ce qui pourrait faire perdre à l'IETF une partie de son histoire (la section 10 du RFC revient sur cette question). Le RFC ne contient pas de mise en garde à ce sujet, alors que le problème s'est déjà produit.

La section 5 discute également des politiques de nommage pour les étiquettes. Au minimum, il faut des étiquettes pour différencier les détails (« coquille dans le deuxième paragraphe ») des questions de fond. Ensuite, les étiquettes peuvent être utilisées pour :

  • L'état d'un ticket (« en discussion », « consensus approximatif », « repoussé à une future version du protocole »).
  • La partie du protocole concernée.
  • Ou d'autres cas comme par exemple le marquage des tickets considérés comme complètement hors-sujet.

Une notion importante à l'IETF est celle de consensus. L'IETF ne vote pas (dans une organisation sans adhésion explicite, qui aurait le droit de vote ?) et prend normalement ses décisions par consensus (cf. RFC 2418). Pour estimer s'il y a consensus ou pas, les présidents du groupe de travail peuvent utiliser tous les moyens à leur disposition (section 7 du RFC) dont GitHub, mais doivent s'assurer, sur la liste de diffusion officielle du groupe, qu'il s'agit bien d'un consensus. (Certains participants ou participantes peuvent ne pas utiliser GitHub, et il faut quand même tenir compte de leur avis.)

Le RFC note aussi (section 8) que, parmi les fonctions de GitHub, l'intégration continue peut être très utile. Par exemple, si les documents rédigés comportent des extraits dans un langage formel (comme YANG ou Relax NG), mettre en place un système d'intégration continue permet de détecter les erreurs rapidement, et de présenter automatiquement la dernière version, automatiquement vérifiée, des documents.

La section 9 du RFC donne quelque conseils aux auteurs (editors dans le RFC car le concept d'auteur est délicat, pour des documents collectifs). Avec GitHub, il y aura sans doute davantage de contributions extérieures (par exemple sous forme de pull requests), puisque le processus de soumission est plus facile pour les gens qui ne sont pas à l'IETF depuis dix ans. C'est bien l'un des buts de l'utilisation d'une forge publique. Mais cela entraine aussi des difficultés. Des tickets vont être dupliqués, des pull requests être plus ou moins à côté de la plaque, etc. Les auteurs doivent donc se préparer à un travail de tri important.

Enfin, la section 10, consacrée à la sécurité, détaille plusieurs des problèmes que pose l'utilisation de GitHub. D'abord, il y a la dépendance vis-à-vis d'une plate-forme extérieure à l'IETF ; si GitHub est en panne, perturbant le fonctionnement d'un ou plusieurs groupes de travail, l'IETF ne peut rien faire. (Le caractère décentralisé de git limite un peu l'ampleur du problème.) Ensuite, il y a la nécessité de faire des sauvegardes, y compris des tickets (qui ne sont pas, eux, gérés de manière décentralisée). Le RFC 8875 donne des consignes plus précises à ce sujet. Et il y a le risque de modifications non souhaitées, si un participant ayant droit d'écriture se fait pirater son compte. Le fait que tout soit public à l'IETF, et que git permette assez facilement de revenir en arrière sur des modifications, limitent l'importance de cette menace mais, quand même, il est recommandé que les auteurs sécurisent leur compte (par exemple en activant la MFA). En revanche, un autre risque n'est pas mentionné dans le RFC, celui du blocage par GitHub des méchants pays. GitHub bloque ou limite l'accès à certains pays et ne s'en cache d'ailleurs pas.

Dernier problème avec GitHub, non mentionné dans le RFC (merci à Alexis La Goutte pour l'observation) : l'IETF travaille de nombreuses années à développer et promouvoir IPv6 et GitHub n'a toujours que les adresses de la version du siècle précédent.


Téléchargez le RFC 8874


L'article seul

RFC 8875: Working Group GitHub Administration

Date de publication du RFC : Août 2020
Auteur(s) du RFC : A. Cooper (Cisco), P. Hoffman (ICANN)
Pour information
Réalisé dans le cadre du groupe de travail IETF github
Première rédaction de cet article le 29 août 2020


Certains groupes de travail IETF, ou bien certains participant·e·s à la normalisation au sein de cette organisation, utilisent le service GitHub de Microsoft pour gérer le processus de production des normes. Ce RFC donne des conseils pratiques aux groupes de travail qui utilisent GitHub. Il suit les principes généraux énoncés dans le RFC 8874, en étant plus concret, davantage orienté « tâches ».

Il s'agit cependant juste de conseils : des groupes peuvent parfaitement faire différemment, des individus peuvent utiliser GitHub (ou un service libre équivalent, ce que le RFC ne mentionne guère) en suivant d'autres méthodes. Le RFC concerne surtout les groupes de travail qui se disent que GitHub pourrait être intéressant pour eux, mais qui ne sont pas sûr de la meilleure manière de faire. Les groupes plus expérimentés qui utilisent GitHub parfois depuis des années savent déjà.

La section 2 du RFC décrit le processus recommandé pour le cycle de vie du groupe de travail. Ce processus peut s'automatiser, GitHub ayant une API documentée. Je ne sais pas si à l'heure actuelle cette automatisation est réellement utilisée par l'IETF Secretariat, mais le RFC suggère l'usage d'outils comme ietf-gh-scripts ou comme i-d-template.

Le RFC demande que l'interface utilisée par les directeurs de zones IETF et les présidents des groupes de travail dans le DataTracker permette de créer une organisation GitHub. Elle doit être nommée ietf-wf-NOMDUGROUPE (en pratique, cette convention semble rarement suivie), les directeurs de la zone doivent en être les propriétaires et les présidents du groupe doivent avoir le statut d'administrateur (voyez par exemple les membre du groupe GitHub QUIC). Elle est ensuite indiquée depuis le DataTracker (cf. par exemple pour le groupe capport). Il n'est pas possible actuellement d'associer clairement les identités GitHub aux identités IETF (ça a été demandé mais l'identité sur l'Internet est un sujet complexe).

De même qu'il faudrait pouvoir créer facilement une organisation dans GitHub, il serait bien de pouvoir créer facilement un nouveau dépôt, et de le peupler avec les fichiers minimaux (LICENSE - en suivant ces principes, README, CONTRIBUTING - en s'inspirant de ces exemples, etc). L'outil i-d-template fait justement cela.

Une fois organisation et dépôt(s) créés, le groupe peut se mettre à travailler (section 3 du RFC). Un des points importants est la sauvegarde. Il est crucial de sauvegarder tout ce qui est mis dans GitHub au cas où, par exemple, Microsoft déciderait tout à coup de limiter l'accès ou de le rendre payant. Les listes de diffusion de l'IETF sont archivées via MailArchive, mais tout ce qui se passe sur GitHub doit l'être également. Pour les documents, c'est facile, git est un VCS décentralisé, avoir une copie complète (avec l'historique) du dépôt est le comportement par défaut. L'IETF n'a donc qu'à faire un git fetch toutes les heures pour stocker une copie.

Il reste les tickets et les pull requests. Ils (elles ?) ne sont pas gérés par git. Il faut alors utiliser l'API de GitHub pour les sauvegarder.

Ce risque de pertes, si on ne fait pas de sauvegarde, fait d'ailleurs partie des risques mentionnés dans la section 4, sur la sécurité. Par contre, ce RFC ne mentionne pas les risques plus stratégiques liés à la dépendance vis-à-vis d'un système centralisé. C'est pour cela que certains documents sont développés en dehors de GitHub, par exemple le successeur du RFC 7816 est sur un GitLab, FramaGit.


Téléchargez le RFC 8875


L'article seul

RFC 8890: The Internet is for End Users

Date de publication du RFC : Août 2020
Auteur(s) du RFC : M. Nottingham
Pour information
Première rédaction de cet article le 28 août 2020


Ah, mais c'est une excellente question, ça. L'Internet est pour qui ? Qui sont les « parties prenantes » et, parmi elles, quelles sont les plus importantes ? Plus concrètement, la question pour l'IETF est « pour qui bossons-nous ? » Quels sont les « clients » de notre activité ? Ce RFC de l'IAB met les pieds dans le plat et affirme bien haut que ce sont les intérêts des utilisateurs finaux qu'il faut considérer avant tout. Et explique aussi comment prendre en compte ces intérêts, en pratique. C'est donc un RFC 100 % politique.

Il y a encore quelques personnes à l'IETF qui ne veulent pas voir les conséquences de leur travail (« la technique est neutre ») ou, pire, qui ne veulent en retenir que les conséquences positives. Mais les activités de l'IETF, comme la production des RFC, est en fait politique, affirme ce document. Car l'Internet est aujourd'hui un outil crucial pour toute la vie sociale, il a permis des changements importants, il a enrichi certains et en a appauvri d'autres, il a permis l'accès à un savoir colossal librement accessible, et il a facilité le déploiement de mécanismes de surveillance dont Big Brother n'aurait jamais osé rêver. Et toute décision apparemment « purement technique » va avoir des conséquences en termes de ce qui est possible, impossible, facile, ou difficile sur le réseau. Compte-tenu de leur impact, on ne peut pas dire que ces décisions ne sont pas politiques (section 1 du RFC).

Une fois qu'on reconnait que ce qu'on fait est politique, se pose la question : pour qui travaille-t-on ? Dresser la liste des « parties prenantes », les intéressé·e·s, les organisations ou individus qui seront affectés par les changements dans l'Internet est une tâche impossible ; c'est quasiment tout le monde. Le RFC donne une liste non limitative : les utilisateurs finaux, les opérateurs réseau, les écoles, les vendeurs de matériel, les syndicats, les auteurs de normes (c'est nous, à l'IETF), les programmeurs qui vont mettre en œuvre les normes en question, les ayant-droits, les États, les ONG, les mouvements sociaux en ligne, les patrons, la police, les parents de jeunes enfants… Tous et toutes sont affectés et tous et toutes peuvent légitimement réclamer que leurs intérêts soient pris en compte. Ce n'est pas forcément au détriment des autres : un changement technique peut être bénéfique à tout le monde (ou, en tout cas, être bénéfique à certains sans avoir d'inconvénients pour les autres). Mais ce n'est pas toujours le cas. Pour prendre un exemple classique (mais qui n'est pas cité dans ce RFC), voyons le chiffrement : l'écriture du RFC 8446, qui normalisait la version 1.3 de TLS, a remué beaucoup de monde à l'IETF car le gain en sécurité pour les utilisateurs finaux se « payait » par de moindres possibilités de surveillance pour les États et les patrons. Ici, pas question de s'en tirer en disant que tout le monde serait heureux : il fallait accepter de faire des mécontents.

Bon, là, c'étaient les grands principes, maintenant, il faut devenir un peu concret. D'abord, qui sont ces « utilisateurs finaux » ? Si on veut donner la priorité à leurs intérêts, il faudrait les définir un peu plus précisément. La section 2 explique : ce sont les humains pour qui l'Internet rend un service. Cela n'inclut donc pas les professionnels qui font marcher le réseau : les utilisateurs finaux du protocole BGP ne sont pas les administrateurs réseau, qui configurent les routeurs BGP, mais les gens à qui le réseau en question permet de communiquer.

Le RFC note que ces utilisateurs finaux ne forment donc pas un groupe homogène. Ils ont des intérêts différents et des opinions différentes. (Je suis personnellement très agacé par les gens qui, dans les réunions de « gouvernance Internet », plastronnent qu'ils représentent « les utilisateurs ». Comme la mythique « société civile », les utilisateurs ne sont pas d'accord entre eux.) Parfois, le désaccord est au sein du même individu, lorsqu'il occupe plusieurs rôles. Même dans un seul rôle, l'utilisateur final peut être le siège de tensions, par exemple entre la protection de sa vie privée et la facilité d'utilisation du réseau, deux objectifs honorables mais qui sont parfois difficiles à concilier.

Le RFC note aussi que l'utilisateur final peut… ne pas être un utilisateur, ou en tout cas pas directement. Si on prend une photo de moi et qu'on la met sur le Web avec un commentaire, je suis concerné, même si je n'utilise pas du tout l'Internet. Même chose si j'entre dans un magasin truffé de capteurs qui détectent mes mouvements et les signalent. Les utilisateurs finaux, au sens de ce RFC, peuvent donc être des utilisateurs indirects.

Une fois qu'on sait qui sont les utilisateurs finaux, pourquoi faudrait-il prioriser leurs intérêts ? La section 3 rappelle d'abord que l'IETF a une longue histoire d'affirmation de cette priorité. Le tout premier RFC, le RFC 1, disait déjà « One of our goals must be to stimulate the immediate and easy use by a wide class of users. » (Bon, le RFC 1 parlait d'accessibilité et de facilité d'usage plutôt que de politique, mais c'est une jolie référence.) La charte de l'IETF, dans le RFC 3935, est plus précise : « The IETF community wants the Internet to succeed because we believe that the existence of the Internet, and its influence on economics, communication, and education, will help us to build a better human society. ». Et, encore plus explicite, « We embrace technical concepts such as decentralized control, edge-user empowerment and sharing of resources, because those concepts resonate with the core values of the IETF community. These concepts have little to do with the technology that's possible, and much to do with the technology that we choose to create. ». Bref, le but est le bonheur de l'humanité, et celle-ci est composée des utilisateurs finaux.

(Pour ne fâcher personne, le RFC oublie de signaler l'existence d'autres RFC qui au contraire donnent explicitement la priorité à d'autres parties prenantes, par exemple les gérants du réseau dans le RFC 8404.)

Le RFC note que le progrès quantitatif (davantage de machines connectées, une capacité réseau plus importante, une latence plus faible) n'est pas un but en soi car l'Internet peut être utilisé pour des mauvaises causes (surveiller les utilisateurs, exercer un pouvoir sur eux). La technique pouvant être utilisée pour le bien comme pour le mal, les améliorations techniques (comme présentées en couleur rose par les techno-béats, par exemple les promoteurs de la 5G) ne doivent pas être considérées comme forcément positives.

Après ces arguments humanistes, le RFC mentionne aussi des arguments plus internes au réseau. D'abord, d'un point de vue égoïste, l'IETF a tout intérêt à garder la confiance de ces utilisateurs finaux, car l'IETF perdrait sa pertinence et son rôle si elle se mettait, par exemple, uniquement à la remorque des vendeurs de matériel ou de logiciel. (Ou même si elle était simplement vue comme se mettant à cette remorque.)

On pourrait même voir les utilisateurs se détourner massivement, non seulement du travail de l'IETF, mais aussi de l'Internet en général, si leurs intérêts ne sont pas mis en premier. Prioriser les utilisateurs finaux aide aussi à lutter contre certaine formes de technophobie.

Maintenant, on a défini les utilisateurs finaux, affirmé qu'il fallait penser à eux et elles en premier, et expliqué pourquoi. Il reste le comment. C'est bien joli de dire, dans une grande envolée « nous pensons avant tout à M. et Mme Toutlemonde » mais, concrètement, cela veut dire quoi ? La section 4 du RFC décortique les conséquences pratiques du choix politique.

D'abord, déterminer ce qui est bon pour les utilisateurs n'est pas évident. Paradoxalement, le fait que les participants à l'IETF connaissent et comprennent très bien le fonctionnement de l'Internet n'aide pas, au contraire ; cela rend plus difficile de se mettre à la place des utilisateurs finaux. Pourtant, on l'a vu, l'IETF se réclame depuis longtemps d'une vague « Internet community » mais sans trop savoir qui elle est. Une solution évidente au problème « quels sont les intérêts des utilisateurs finaux ? » serait de leur demander. C'est plus facile à dire qu'à faire, mais c'est en effet la première chose à envisager : se rapprocher des utilisateurs.

Cela ne va pas de soi. Déjà, le travail de l'IETF est très pointu techniquement, et nécessite une forte expertise, sans compter la nécessité de se familiariser avec la culture spécifique de l'IETF. les utilisateurs finaux qu'on veut prioriser ne sont pas des experts techniques. Pire, les connaissances qu'ils ont sur l'Internet ne sont pas seulement insuffisantes, elles sont souvent fausses. Bref, inviter M. ou Mme Toutlemonde sur les listes de diffusion de l'IETF n'est pas la bonne approche.

Les États sont prompts à dire « pas de problème, les utilisateurs ont une représentation, et c'est nous ». Il suffirait donc que les envoyés de ces États participent à l'IETF et on aurait donc automatiquement accès à « la voix des utilisateurs ». Il y a déjà de ces envoyés qui participent à l'IETF. (À chaque réunion, il y a au moins une personne avec un badge NSA, sans compter ceux qui n'ont pas le badge, mais ont le même employeur.) La question de leur représentativité (l'envoyé du gouvernement français est-il vraiment le porte-parole des soixante millions d'utilisateurs français ?) a été une des questions essentielles lors des discussions menant à ce RFC. Chaque gouvernement prétend qu'il est représentatif. C'est clairement faux pour les dictatures mais cela ne veut pas dire que les démocraties sont parfaites, sans compter la difficulté de classer les pays dans l'une ou l'autre catégorie. Bref, personne n'a envie de transformer l'IETF en un organisme multi-gouvernemental paralytique, comme l'ONU. (Les experts en « gouvernance Internet » noteront que l'ICANN a le même genre de problèmes, et son GAC - Governmental Advisory Committee - ne satisfait personne.)

À ce sujet, bien que cela ne soit pas mentionné explicitement dans le RFC, il faut aussi dire que les envoyés des États sont en général contraints par un processus de décision interne très rigide, et ne peuvent pas s'exprimer librement. Cela ne colle évidemment pas avec le mécanisme de discussion très ouvert et très vif de l'IETF. Je me souviens d'une réunion où deux personnes portant la mention FBI sur leur badge étaient venus me parler de problèmes avec un des documents sur lesquels je travaillais. Lorsque je leur ai fait remarquer que leurs analyses, assez pertinentes, devraient être faites dans la réunion officielle du groupe de travail et pas juste dans les couloirs, ils m'avaient répondu que leurs supérieurs ne les y autorisaient pas. Difficile d'envisager une participation effective des États dans ces conditions.

Bon, si on ne fait pas appel aux États, à qui ? Le RFC mentionne la classique « société civile » dont personne ne sait trop en quoi elle consiste, mais à qui tout le monde rend hommage. Selon l'interlocuteur, « société civile » peut vouloir dire « tout le monde sauf l'État » (incluant, par exemple, le MEDEF), ou bien « tous les individus » ou encore « tous les individus organisés (associations, syndicats, etc) » sans compter ceux qui disent « société civile » pour « les gens qui sont d'accord avec moi ». (Disons franchement les choses : l'un des problèmes de fond de la « gouvernance de l'Internet » est qu'il n'y a que peu ou pas de représentation des utilisateurs. Tout le monde parle pour eux et elles, mais ielles n'ont pas de voix propre. Ce syndrome « tout le monde se réclame de l'utilisateur final » avait été très net, par exemple, lors des débats sur DoH, mais aussi dans d'autres questions de gouvernance.)

Mais le RFC note à juste titre qu'il existe des organisations qui ont sérieusement travaillé les sujets politiques liés à l'Internet, et qui connaissent donc bien les problèmes, et les conséquences des choix techniques. (En France, ce serait par exemple La Quadrature du Net, Framasoft et certainement plusieurs autres.) Bien que rien ne garantisse leur représentativité, note le RFC, ces organisations sont sans doute le premier canal à utiliser pour essayer de comprendre les intérêts des utilisateurs finaux. La recommandation est donc d'essayer d'identifier ces groupes et de travailler avec eux.

L'accent est mis sur la nécessité d'aller les voir, de ne pas juste leur dire « venez participer à l'IETF » (ils n'ont pas forcément le temps ou les moyens, et pas forcément envie de se lancer dans ce processus). Outre ses réunions formelles et ses listes de diffusion, l'IETF a quelques canaux de communication plus adaptés mais certainement très peu connus (« venez à la Bar BoF, on en parlera autour d'une bière »). Idéalement, c'est l'IETF qui devrait prendre l'initiative, et essayer d'aller vers les groupes organisés d'utilisateurs, par exemple en profitant des réunions existantes. Le RFC recommande de faire davantage d'efforts de sensibilisation, faire connaitre le travail de l'IETF, ses enjeux, etc. (Mon expérience est qu'il est très difficile de faire s'intéresser les gens à l'infrastructure de l'Internet, certes moins sexy qu'une page d'accueil colorée d'un site Web. Après tout, on ne peut pas faire boire un âne qui n'a pas soif.)

Le RFC donne un exemple d'un atelier ayant réuni des participants à l'IETF, et des gens qui n'ont pas l'habitude d'aller à l'IETF, sur un sujet assez chaud politiquement, la réunion ESCAPE, documentée dans le RFC 8752.

On peut aussi penser que cette tâche de sensibilisation à l'importance de la normalisation, et à ses conséquences politiques, ne devrait pas revenir entièrement à l'IETF, qui n'est pas forcément bien préparée à cela. Le RFC cite à juste titre l'Internet Society, qui fait en effet un important travail dans ce domaine.

Le RFC continue avec une section sur le concept de systèmes centrés sur l'utilisateur. Il part de l'exemple du Web, certainement un des plus gros succès de l'Internet. Dans le Web, l'IETF normalise le protocole HTTP (le W3C faisant le reste). La norme HTTP, le RFC 7230 décrit explicitement le rôle du client HTTP, appelé user agent dans la norme (et c'est de là que vient l'en-tête HTTP User-Agent:). À noter que le RFC mélange client HTTP et navigateur Web : le client d'un serveur HTTP n'est pas forcément un navigateur. Quoi qu'il en soit, la discussion continue sur le navigateur : celui-ci sert d'intermédiaire entre l'utilisateur et le serveur Web. Au lieu d'un client spécifique d'un service, et qui a accès à toute la machine de l'utilisateur pour faire sa tâche, le passage par cet intermédiaire qu'est le navigateur permet de créer un bac à sable. Quelles que soient les demandes faites par le serveur Web, il ne sera pas possible de sortir du bac à sable et, par exemple, de lire et d'écrire arbitrairement des fichiers sur la machine de l'utilisateur.

Au contraire, les services sur le Web qui exigent l'installation d'un client local demandent à l'utilisateur une confiance aveugle : ces clients peuvent faire des choses que le navigateur bloquerait normalement. Ce n'est pas par hasard que les sites des médias demandent si souvent l'installation de leur « app » quand on navigue depuis un ordiphone : ces clients locaux ont bien plus de possibilité, notamment de pistage et de surveillance que ce qui est possible via le navigateur.

(Le RFC ne mentionne pas un autre moyen de créer la confiance : le logiciel libre. La totalité de ces « apps » sont du logiciel privateur. Si le logiciel est sous une licence libre, il y a nettement moins de craintes à avoir lorsqu'on l'installe.)

Le RFC estime que le fait d'avoir défini explicitement le user agent et ses propriétés a facilité le succès du Web, en permettant la création de cet intermédiaire de confiance qu'est le navigateur Web, un exemple de système « centré sur l'utilisateur ». Bien sûr, cette vision est très contestable. Le RFC note par exemple que, à vouloir tout faire passer par le Web, on aboutit à des navigateurs qui sont devenus très complexes, ce qui se paie en sécurité et en performances. En outre, cette complexité diminue la concurrence : il n'y a que très peu de navigateurs et beaucoup de composants cruciaux, comme WebKit sont communs à plusieurs navigateurs, diminuant la diversité et le choix. Aujourd'hui, créer un nouveau navigateur en partant de zéro semble impossible, ce qui a de lourdes conséquences sur la distribution du pouvoir dans le Web.

Mais le RFC estime que c'est quand même une meilleure approche que celle, par exemple, de l'Internet des objets, où il n'y a pas de norme d'interaction entre l'utilisateur et le système, pas de « système centré sur l'utilisateur », ce qui fait que l'utilisateur doit faire une confiance aveugle à des systèmes opaques, dont la mauvaise qualité (notamment en sécurité) et la mauvaise éthique ont déjà été largement montrées.

On a dit plus haut que, dans le meilleur des cas, le travail de l'IETF menait à des solutions qui étaient positives pour tout le monde. L'IETF peut alors laisser les différentes parties prenantes interagir (cf. l'article « Luttes dans l'Internet », même si, aujourd'hui, je traduirais tussle par un terme moins violent que lutte). Mais ce cas idéal n'est pas systématique. Parfois, les solutions techniques normalisées dans les RFC ne sont positives que pour certains, et neutres pour d'autres (ne leur apportent aucun avantage). Et parfois, c'est pire, les solutions sont négatives pour certains. Dans le monde réel, fait de différences d'opinion et d'intérêts (et de lutte des classes, ajouterait un marxiste), il ne faut pas être naïf : on ne va pas plaire à tout le monde. Conformément aux principes établis plus haut, le RFC affirme que, si une solution envisagée a forcément des conséquences négatives, il faut faire en sorte que ces conséquences négatives ne soient pas supportées par les utilisateurs finaux, mais par d'autres parties prenantes.

L'IETF a déjà été confrontée à de tels choix, et a documenté cette décision, par exemple dans les RFC 7754 (sur le filtrage), RFC 7258 et RFC 7624 (sur la surveillance), RFC 7288 (sur les pare-feux des machines terminales) et enfin RFC 6973 (sur la vie privée).

Le RFC note aussi que certaines décisions politiques de l'IETF peuvent être correctes mais insuffisantes. Ainsi, le RFC 3724 insiste sur l'importance du modèle de bout en bout. Mais cela ne suffit pas si c'est la machine avec qui on communique qui trahit. Chiffrer grâce à HTTPS quand on parle avec un GAFA n'est une protection que contre les tiers, pas contre le GAFA.

Au sujet des GAFA, le RFC note que la concentration des services dans les mains d'un petit groupe de sociétés est un problème pour les utilisateurs. Il affirme aussi que cela peut être encouragé par des propriétés du protocole IETF. (C'est nettement plus contestable : quelles sont les caractéristiques de SMTP qui expliquent la concentration du courrier chez Gmail et Outlook.com ? Cet argument semble plutôt une allusion maladroite aux débats sur DoH.)

Comme indiqué au début, les utilisateurs finaux ne forment pas un groupe homogène. Ils n'ont ni les mêmes intérêts, ni les mêmes opinions. Cela peut entrainer des difficultés pour l'application du principe « les utilisateurs d'abord ». Par exemple, dans un cas hypothétique où une solution technique entrainerait des conséquences positives pour les utilisateurs d'un pays et négatives dans un autre pays, que faire ? Le RFC suggère de privilégier l'évitement des conséquences négatives. Dans certains cas, il ne sera pas possible de les éviter complètement, et il faudra vraiment faire des compromis. Mais, au moins, il ne faudra pas cacher le problème sous le tapis, et bien documenter ce compromis.

Le principe « les utilisateurs d'abord » s'applique aussi à l'IETF elle-même. Le RFC se termine en affirmant qu'il ne faut pas que l'IETF privilégie ses propres besoins. Ainsi, s'il faut compliquer la tâche des auteurs de RFC pour mieux préserver les intérêts de l'utilisateur, eh bien il faut le faire. De même, dit le RFC, la beauté de l'architecture technique n'est pas un but en soi, elle doit passer après les intérêts des utilisateurs finaux.

En anglais, vous pouvez aussi lire la synthèse qu'avait publié l'auteur du RFC, où il s'exprime plus librement que dans le RFC, par exemple sur DoH. Un article de synthèse, allant plus loin que le RFC a été écrit par Vesna Manojlovic. D'autre part, la norme HTML (du W3C) a une mention qui va dans le même esprit que ce RFC : « In case of conflict, consider users over authors over implementors over specifiers over theoretical purity. » (les mauvaises langues pourront faire remarquer que ce mépris de la « theoretical purity » explique le b...l technique qu'est le Web). Ou, en sens opposé, un article qui s'était vigoureusement opposé à cet empouvoirement des utilisateurs.


Téléchargez le RFC 8890


L'article seul

Fiche de lecture : Un trou dans la toile

Auteur(s) du livre : Luc Chomarat
Éditeur : Payot / Rivages
9-782743-636319
Publié en 2016
Première rédaction de cet article le 19 août 2020


Un peu de lecture de vacances ? Ce livre n'est pas vraiment (malgré la collection où il est publié) un roman policier. C'est plutôt une satire de notre société, de sa dépendance aux outils numériques mais pas uniquement.

Le seul lien avec un polar, c'est qu'il y a un mystère, un inconnu qu'on recherche. Sans divulgâcher, je peux vous dire tout de suite que ce n'est pas cet inconnu qui est important, il est juste un prétexte pour dénoncer l'absurdité du monde, la « communication » érigée en valeur suprême, la perte de sens et la dissimulation de la dureté de l'entreprise capitaliste derrière les mots à la mode. Le livre suit un héros qui est à la fois bien intégré dans la société (il est « créatif » dans une agence de publicité) et décalé (il n'utilise pas les réseaux sociaux et, d'une manière générale, ne comprend pas trop la société dans laquelle il vit).

Le monde du numérique n'occupe en fait qu'une partie du roman, malgré le titre, et malgré la couverture ridicule, avec 0 et 1 qui défilent et hacker à capuche. Pas de piratage ou de cyberconneries dans ce livre (juste un ou deux clichés idiots, par exemple sur le darknet). Mais beaucoup d'humour, pas mal de désespoir aussi (« nous sommes des hommes du siècle dernier, nous essayons de nous adapter, mais nous n'en avons pas vraiment envie »). Contrairement aux milliers de livres réacs publiés sur le thème « l'Internet, c'est la fin de la civilisation, à cause des réseaux sociaux, les gens ne se parlent plus en vrai », ce roman ne met pas tout sur le dos du numérique, et considère que le problème vient de notre société.

Je recommande sa lecture. Si vous êtes comme moi, vous allez souvent rire, et parfois réfléchir.


L'article seul

RFC 8811: DDoS Open Threat Signaling (DOTS) Architecture

Date de publication du RFC : Août 2020
Auteur(s) du RFC : A. Mortensen (Forcepoint), T. Reddy (McAfee), F. Andreasen (Cisco), N. Teague (Iron Mountain), R. Compton (Charter)
Pour information
Réalisé dans le cadre du groupe de travail IETF dots
Première rédaction de cet article le 18 août 2020


Ce nouveau RFC décrit l'architecture du système DOTS (Distributed-Denial-of-Service Open Threat Signaling), un ensemble de mécanismes pour permettre aux victimes d'attaques par déni de service de se coordonner avec les fournisseurs de solution d'atténuation. C'est juste l'architecture, les protocoles concrets sont dans d'autres RFC, comme le RFC 8782.

Il n'y a pas besoin d'expliquer que les attaques par déni de service sont une plaie. Tout le monde en a déjà vécu. Une des approches pour atténuer l'effet d'une de ces attaques est de sous-traiter votre trafic à un tiers, l'atténuateur (« Victor, atténuateur ») qui va recevoir les données, les classer, et jeter ce qui est envoyé par l'attaquant. Cette approche nécessite de la communication entre la victime et l'atténuateur, communication qui se fait actuellement de manière informelle (téléphone…) ou via des protocoles privés. L'idée de DOTS (Distributed-Denial-of-Service Open Threat Signaling) est d'avoir des protocoles normalisés pour ces fonctions de communication. Les scénarios typiques d'utilisation de DOTS sont décrits dans le RFC 8903.

Dans le cas le plus fréquent, DOTS sera utilisé entre des organisations différentes (la victime, et le fournisseur de solutions anti-dDoS). A priori, ils auront une relation contractuelle (du genre contrat, et paiement) mais cette question ne fait pas l'objet du RFC, qui mentionne seulement l'architecture technique. Mais en tout cas, ce caractère multi-organisations va nécessiter des mécanismes d'authentification sérieux (le cahier des charges complet de DOTS est le RFC 8612).

La section 1 de notre RFC rappelle également que DOTS, par définition, sera utilisé dans des moments difficiles, pendant une attaque (RFC 4732), et qu'il est donc conçu en pensant à des cas où les ressources sont insuffisantes (les paquets ont du mal à passer, par exemple). Parfois, il y aura un lien intact entre le client DOTS et le serveur, ou bien un réseau dédié pour cette communication, ou encore une qualité de service garantie pour les échanges DOTS, mais on ne pourra pas toujours compter dessus. DOTS doit fonctionner sur l'Internet normal, possiblement affecté par l'attaque. C'est un élément à systématiquement garder en tête lorsqu'on examine le protocole DOTS, et qui explique bien des choix, comme UDP pour le protocole de signalisation du RFC 8782.

D'autre part, les RFC sur DOTS décrivent des techniques, pas des politiques. Comment on définit une attaque DoS, à partir de quand on déclenche l'atténuation, comment on choisit un atténuateur, toutes ces questions dépendent de la victime, chacun peut faire des choix différents.

Ceci étant posé, place à la description de haut niveau de DOTS, en section 2. Dans le cas le plus simple, il y a :

  • La victime, qui héberge un client DOTS,
  • L'atténuateur, qui héberge un serveur DOTS.

Et client et serveur DOTS communiquent avec les deux protocoles DOTS, celui de signalisation (RFC 8782) et celui de données (RFC 8783). Il y a donc deux canaux de communication. DOTS permet également des schémas plus complexes, par exemple avec plusieurs serveurs, à qui le client demande des choses différentes, ou bien avec des serveurs différents pour la signalisation et pour les données. Notez bien que DOTS est uniquement un protocole de communication entre la victime et l'atténuateur qui va essayer de la protéger. Comment est-ce que l'atténuateur filtre, ou comment est-ce qu'on lui envoie le trafic à protéger, n'est pas normalisé. De même, DOTS ne spécifie pas comment le serveur répond aux demandes du client. Le serveur peut refuser d'aider, par exemple parce que le client n'a pas payé. (Pour l'envoi du trafic à protéger, il y a deux grandes techniques, fondées sur BGP ou sur DNS. Le trafic une fois filtré est ensuite renvoyé à la victime. Une autre solution est d'avoir le mitigateur dans le chemin en permanence.)

On a vu qu'il y avait deux canaux de communication. Celui de signalisation, normalisé dans le RFC 8782 sert surtout à demander à l'atténuateur une action de protection, et à voir quelles réponses l'atténuateur donne. C'est ce canal qui devra fonctionner au plus fort de l'attaque, ce qui lui impose des contraintes et des solutions particulières. Le canal de données, spécifié dans le RFC 8783, n'est pas en toute rigueur indispensable à DOTS, mais il est quand même pratique : il sert à envoyer des informations de configuration, permettant au client de spécifier plus précisement ce qu'il veut protéger et contre qui. Par exemple, il va permettre de donner des noms à des ressources (une ressource peut être, par exemple, un ensemble de préfixes IP), envoyer une liste noire d'adresses d'attaquants à bloquer inconditionnellement, une liste blanche de partenaires à ne surtout pas bloquer, à définir des ACL, etc. En général, ce canal de données s'utilise avant l'attaque, et utilise des protocoles habituels, puisqu'il n'aura pas à fonctionner pendant la crise.

Le RFC note aussi que DOTS n'a de sens qu'entre partenaires qui ont une relation pré-existante (par exemple client / fournisseur payant). Il n'y a pas de serveur DOTS public. L'authentification réciproque du client et du serveur est donc nécessaire, d'autant plus qu'on utilise DOTS pour faire face à des attaques et que l'attaquant peut donc chercher à subvertir DOTS.

Le serveur DOTS doit non seulement authentifier le client mais aussi l'autoriser à demander une mitigation pour telle ou telle ressource (préfixe IP ou nom de domaine). Par exemple, le serveur DOTS peut utiliser les IRR pour déterminer si son client est vraiment légitime pour demander une intervention sur telle ressource. Mais il pourrait aussi utiliser ACME (RFC 8738).

Typiquement, le client établit une session de signalisation avec le serveur, qu'il va garder pendant l'attaque. Il n'y a pas actuellement de norme sur comment le client trouve le serveur DOTS. On peut supposer qu'une fois l'accord avec le serveur fait, le gérant du serveur communique au client le nom ou l'adresse du serveur à utiliser.

La section 3 du RFC détaille certains points utiles. À lire si vous voulez comprendre toute l'architecture de DOTS, notamment les configurations plus complexes, que j'ai omises ici.

Et si vous vous intéressez aux mises en œuvre de DOTS, elles sont citées à la fin de mon article sur le RFC 8782.


Téléchargez le RFC 8811


L'article seul

RFC 8810: Revision to Capability Codes Registration Procedures

Date de publication du RFC : Août 2020
Auteur(s) du RFC : J. Scudder (Juniper Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 18 août 2020


Un petit RFC purement bureaucratique : un léger changement, dans le sens de la libéralisation, des procédures d'enregistrement d'une capacité BGP dans le registre IANA de ces capacités.

Les routeurs BGP ont des capacités optionnelles que ne partagent pas forcément leurs pairs, comme par exemple la gestion du redémarrage en douceur (RFC 4724) ou bien la configuration du filtrage sortant (RFC 5291). Il est donc utile de pouvoir annoncer formellement ce qu'on sait faire et ce qu'on ne sait pas faire. L'annonce des capacités BGP est normalisée dans le RFC 5492. Elle se fait en envoyant un code numérique, d'un octet. La liste des codes possibles figure dans un registre IANA. Une partie des codes, allant de 128 à 255, était réservée pour l'utilisation locale. Cette plage est désormais éclatée en trois, en utilisant la terminologie de politiques d'enregistrement du RFC 8126 :

  • De 128 à 238 : « Premier Arrivé, Premier Servi », la politique d'enregistrement la plus libérale qui soit,
  • De 239 à 254 : « Utilisation à des fins expérimentales », ce qui est proche de l'ancien « Utilisation privée » mais en insistant sur le côté temporaire de l'utilisation,
  • 255 : réservé pour un usage futur, par exemple pour indiquer une indirection vers un code étendu, si on a un jour besoin de plus de 255 capacités BGP (un octet, c'est peu, mais il n'y a actuellement que 25 capacités enregistrées).

Les deux autres plages, de 1 à 63 (« Examen par l'IETF ») et de 64 à 127 (« Premier Arrivé, Premier Servi ») ne changent pas depuis le RFC 5492.

Lorsqu'on change une politique d'enregistrement, il faut se demander quoi faire des utilisations précédentes. Puisque la plage considérée était utilisable en privé, des gens ont pu légitimement s'en servir et annoncer des codes de capacité. En 2015, les auteurs de ce RFC avaient cherché les utilisations de cette plage et trouvé une liste (pas forcément complète), souvent composée de codes qui ont reçu un « vrai » numéro après, liste qui est présentée dans le RFC, et ajoutée au registre IANA. Et, bien sûr, comme avec tout registre, il y a toujours le risque de squatteurs s'appropriant tel ou tel code sans suivre les procédures (cf. RFC 8093).


Téléchargez le RFC 8810


L'article seul

L'Internet, ça ne marche pas de partout

Première rédaction de cet article le 13 août 2020
Dernière mise à jour le 16 août 2020


Lorsqu'une panne survient et empêche l'accès à une ressource sur l'Internet, il y a parfois discussion car certaines personnes disent « mais non, pour moi, ça marche », alors que la victime originelle insiste « je te dis que c'est cassé ». Les deux peuvent avoir simultanément raison. Les pannes peuvent dépendre d'où vous vous trouvez, mais elles dépendent surtout de votre réseau d'accès à l'Internet. Voyons un exemple concret avec une panne affectant Algérie Télécom et qui empêche, par exemple, les abonnés d'Orange en France d'accéder à http://cetic.dz/.

Avant de tester depuis plusieurs endroits, il faut s'assurer qu'on dispose d'un moyen fiable de tester. Beaucoup de gens font une confiance aveugle à la commande ping mais ils ont tort : les paquets ICMP de type Echo qu'elle utilise peuvent être bloqués par un pare-feu hargneux, sans que les autres services soient affectés. Dans le cas de cetic.dz, le signalement initial portait sur un problème DNS et on aurait donc pu tester avec des requêtes DNS mais, ici, ce n'est pas la peine : les machines en cause, 193.251.169.83 et 193.251.169.84 répondent en ICMP Echo :

% ping -c 3 193.251.169.83

PING 193.251.169.83 (193.251.169.83) 56(84) bytes of data.
64 bytes from 193.251.169.83: icmp_seq=1 ttl=50 time=81.2 ms
64 bytes from 193.251.169.83: icmp_seq=2 ttl=50 time=79.2 ms
64 bytes from 193.251.169.83: icmp_seq=3 ttl=50 time=79.3 ms

--- 193.251.169.83 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 79.184/79.875/81.183/0.953 ms
  

Depuis un réseau où ça ne marche pas :

% ping -c 3 193.251.169.83
PING 193.251.169.83 (193.251.169.83) 56(84) bytes of data.

--- 193.251.169.83 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2052ms
  

Bon, nous avons un problème variable : à certains endroits, ça marche, à d'autres pas. Dans des cas comme cela, lorsque les gens discutent sur un forum quelconque du problème, ceux et celles qui ont compris que le problème dépendait du point de mesure précisent souvent leur expérience en indiquant leur ville (« depuis Marseille, ça marche »). C'est une erreur car ce n'est en général pas la localisation géographique qui compte mais plus souvent le réseau d'accès, donc le FAI ou plus exactement l'AS. Il est curieux que même sur une liste de diffusion de professionnels du réseau comme NANOG, les gens qui signalent une panne indiquent plus souvent leur ville que leur AS… Pour M. Toutlemonde, comme il ne connait pas en général son AS, indiquer le FAI est plus utile.

Donc, ici, on a une panne qui dépend de l'endroit. Comment la tester ? J'ai utilisé des comptes sur deux machines différentes, connectées à des opérateurs différents. Mais si on n'a pas des comptes partout, on fait comment ? Eh bien le plus simple est d'utiliser les sondes RIPE Atlas, ces petits boitiers installés par des volontaires un peu partout et qui peuvent effectuer des mesures actives, créés par exemple via le logiciel Blaeu. Demandons à cent sondes Atlas de pinguer 193.251.169.84 :

% blaeu-reach --requested 100 193.251.169.84
98 probes reported
Test #26682471 done at 2020-08-13T12:10:32Z
Tests: 245 successful tests (83.6 %), 0 errors (0.0 %), 48 timeouts (16.4 %), average RTT: 111 ms
  

On aurait dû avoir à peu près 100 % de succès mais on n'a que 84 %. Et, surtout, cela dépend du réseau. Si on essaie depuis Orange (AS 3215) :

% blaeu-reach --requested 100 --as 3215 193.251.169.84
96 probes reported
Test #26682501 done at 2020-08-13T12:12:04Z
Tests: 3 successful tests (1.0 %), 0 errors (0.0 %), 285 timeouts (99.0 %), average RTT: 139 ms   
  

On a cette fois quasiment uniquement des échecs. Depuis un autre opérateur (ici, Free), tout marche :

% blaeu-reach --requested 100 --as 12322 193.251.169.84
98 probes reported
Test #26683832 done at 2020-08-13T14:08:11Z
Tests: 293 successful tests (99.7 %), 0 errors (0.0 %), 1 timeouts (0.3 %), average RTT: 52 ms
  

Mais pourquoi est-ce que ça marche depuis Free et pas depuis Orange ? La première tentation est de suspecter un problème BGP, le protocole qui distribue les routes sur l'Internet. Le service RIPE Stat nous permet de voir le routage du préfixe concerné et, pour citer RIPE Stat, « At 2020-08-13 00:00:00 UTC, 193.251.169.0/24 was 100% visible (by 321 of 321 RIS full peers). ». Bref, le préfixe 193.251.169.0/24 est visible partout, et ne semble pas massivement filtré.

Mais attention, le RIS, réseau de routeurs sur lequel se base RIPE Stat n'est pas présent partout. Et, notamment, il ne semble pas présent chez OpenTransit, transitaire d'Orange et membre du même groupe. On notera en effet qu'un préfixe IP plus général, 193.251.160.0/20, est annoncé par la société OpenTransit. Et, en regardant le looking glass d'OpenTransit on ne voit que