Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

Ce blog n'a d'autre prétention que de me permettre de mettre à la disposition de tous des petits textes que j'écris. On y parle surtout d'informatique mais d'autres sujets apparaissent parfois.


RFC 9075: Report from the IAB COVID-19 Network Impacts Workshop 2020

Date de publication du RFC : Juillet 2021
Auteur(s) du RFC : J. Arkko (Ericsson), S. Farrell (Trinity College Dublin), M. Kühlewind (Ericsson), C. Perkins (University of Glasgow)
Pour information
Première rédaction de cet article le 23 juillet 2021


La pandémie de Covid-19 en 2020 a affecté de nombreux aspects de notre vie. Concernant plus spécifiquement l'Internet, elle a accru l'utilisation d'outils de communication informatiques. Quels ont été les effets de ces changements sur l'Internet ? Un atelier de l'IAB fait le point sur ces effets et en tire des leçons. Je vous le dis tout de suite : contrairement à certains discours sensationnalistes, l'Internet n'a pas subi de conséquences sérieuses.

De janvier à mars 2020, de nombreux pays ont imposé un confinement plus ou moins strict. Des activités comme le travail ou l'éducation devaient se faire à distance, en utilisant les outils numériques. Certains politiciens ont tenu des discours dramatisants, prétendant que, si on ne renonçait pas à regarder ses vidéos favorites, l'Internet allait s'écrouler. Même si aucun professionnel des réseaux n'a repris ce discours, cela ne veut pas dire qu'il ne s'est rien passé. L'IAB a donc organisé en novembre 2020 un atelier (évidemment tenu en ligne car il n'y avait pas le choix) pour étudier les effets de ces confinements sur l'Internet, comprendre ce qui est arrivé et peut-être formuler des recommandations.

Donc, pendant le confinement et l'augmentation du télétravail qui en a résulté, le trafic Internet a changé. Il n'a pas toujours augmenté (les travailleurs utilisaient également Internet quand ils étaient au bureau, et les gens regardaient déjà Netflix avant la pandémie) mais il s'est déplacé : trafic de type différent, à des heures différentes, etc. Et, dans la plupart des pays, c'est arrivé assez soudainement, laissant peu de temps pour l'adaptation. La sécurité a été également très affectée, les mesures de sécurité conçues sur la base d'un lieu physique n'ayant plus de sens. Tout à coup, il a fallu autoriser beaucoup d'accès distants, avec tous les risques que cela impliquait. L'atelier lui-même a été différent des précédents ateliers de l'IAB, qui étaient fondés sur une participation physique pendant deux jours continus. Cette fois, l'atelier s'est fait en trois sessions à distance, avec respiration et réflexion entre les sessions.

Qu'ont observé les acteurs de l'Internet ? À l'atelier, certains FAI ou gérants de points d'échange Internet ont signalé des accroissements de 20 % du trafic. C'est à la fois beaucoup et peu. C'est beaucoup car c'est survenu soudainement, sans être étalé sur une période permettant le déploiement de nouvelles ressources, et c'est peu, car la croissance de l'utilisation des réseaux est un phénomène permanent : il faut toujours augmenter la capacité (20 % représente une augmentation annuelle typique, mais qui fut concentrée en quelques semaines). On voit ici le trafic sur le point d'échange Internet de Francfort (la source est ici). S'il y a bien une brusque montée début 2020 avec le démarrage du confinement, il faut noter qu'elle s'inscrit dans une augmentation du trafic Internet sur le long terme : decix-covid-2020.png

Cette montée du trafic lors du confinement est également relativisée sur les statistiques de trafic au point d'échange parisien (la source est ici) : franceix-covid-2020.png

De même, l'article « Measurement of congestion on ISP interconnection links » mesure des moments de congestion limités aux États-Unis en mars. Cette croissance était très inégalement répartie selon les services. Vous ne serez pas surpris d'apprendre que certains opérateurs de services de vidéo-conférence ont vu leur activité tripler, voire décupler. Une intéressante conclusion est que, contrairement à ce que certains discours sensationnalistes comme ceux de Thierry Breton prétendaient, l'Internet n'a pas connu de problème généralisé. Comme toujours dans ce réseau mondial, les problèmes sont restés localisés, ralentissements à certains endroits, baisse automatique de la qualité des vidéos à d'autres, mais pas de problème systémique. Ce bon résultat n'a pas été obtenu uniquement par la capacité du réseau existant à encaisser la montée en charge. Il y a eu également de nombreuses actions prises par les différents acteurs du réseau, qui ne sont pas restés les bras croisés face au risque. Bref, vu du point de vue scientifique, c'était une expérience intéressante, qui montre que l'Internet peut résister à des crises, ce qui permet de penser que les problèmes futurs ne seront pas forcément fatals.

[L'atelier portait bien sur l'Internet, sur l'infrastructure, pas sur les services hébergés. Il est important de faire la distinction car certains services (comme ceux de l'Éducation Nationale en France) ont été incapables de résister à la charge et se sont vite écroulés. Mais ce n'était pas une défaillance de l'Internet, et renoncer à regarder des vidéos n'aurait pas protégé le CNED contre ces problèmes. Notons qu'il n'y avait pas de fatalité à ces problèmes des services : Wikipédia et Pornhub, deux services très différents dans leur utilisation et leur gestion, ont continué à fonctionner correctement.]

Voyons maintenant les détails, dans la section 3 du RFC. On commence avec la sous-section 3.1, les mesures. Que s'est-il passé ? Comme on pouvait s'y attendre, le trafic résidentiel a augmenté (en raison du travail à la maison), tandis que celui des réseaux mobiles chutait (on se déplaçait moins). Le trafic vers les opérateurs de services de vidéo-conférence (comme Zoom) a augmenté, ainsi que celui des services de distraction (VoD) pendant la journée. Mais il y a eu surtout un gros déplacement des pics d'activité. En semaine, l'activité Internet était très liée au rythme de la journée, avec des trafics très différents dans la journée et le soir. Pendant les confinements, on a vu au contraire une activité plus étalée dans le temps chez les FAI résidentiels, et une activité de la semaine qui ressemble à celle des week-ends. Là encore, pas de conséquences graves, bien que certains FAI aient signalé des ralentissements notamment en mars 2020. Bref, l'Internet sait bien résister aux sautes de trafic qui, il est vrai, font partie de son quotidien depuis sa création.

Parmi les articles soumis pour l'atelier, je vous recommande, sur la question des mesures, le très détaillé « A view of Internet Traffic Shifts at ISP and IXPs during the COVID-19 Pandemic ». Les auteurs ont observé le trafic chez plusieurs opérateurs et points d'échange (le seul nommé est le réseau académique de Madrid). Par exemple, en utilisant diverses heuristiques (le port seul ne suffit plus, tout le monde étant sur 443), les auteurs ont des chiffres concernant diverses applications (vidéo-conférence, vidéo à la demande, jeux en ligne, etc). Moins détaillé, il y a le « IAB COVID-19 Workshop: Interconnection Changes in the United States » (à l'origine publié dans un Internet-Draft, draft-feamster-livingood-iab-covid19-workshop).

Un exemple de changement du trafic est donné par le Politecnico de Turin qui a vu son trafic sortant multiplié par 2,5, en raison de la diffusion de ses 600 cours en ligne par jour, alors que le trafic entrant était divisé par 10. Dans les universités, le trafic entrant est typiquement bien plus gros que le sortant (les étudiants et enseignants sont sur le campus et accèdent à des ressources distantes) mais cela a changé pendant le confinement, les ressources externes étant accédées depuis la maison. (Une entreprise aurait pu voir des effets différents, si les employés accèdent à ces ressources externes via le VPN de l'entreprise.) Le REN REDIMadrid a vu également de gros changements dans son trafic. Effet imprévu, les communications avec les AS d'Amérique latine a augmenté, probablement parce que les étudiants hispanophones américains profitaient des possibilités de cours à distance pour suivre les activités des universités de l'ex-métropole.

Comme dit plus haut, les réseaux mobiles, 4G et autres, ont vu leur activité baisser. L'article « A Characterization of the COVID-19 Pandemic Impact on a Mobile Network Operator Traffic » note une mobilité divisée par deux en Grande-Bretagne et un trafic diminué d'un quart. (Certaines personnes ne sont plus mobiles mais utilisent la 4G à la maison, et il y a bien d'autres phénomènes qui rendent compliquée l'analyse.) L'observation des signaux envoyés par les téléphones (le réseau mobile sait où vous êtes…) a également permis de mesurer l'ampleur de la fuite hors des grandes villes (10 % des londoniens).

Et dans la connexion des FAI avec les services sur le cloud ? Les liens d'interconnexion entre FAI et fournisseurs de services ont-ils tenu ? Pas de congestion persistante mais des moments de tension, par exemple aux États-Unis vers les petits FAI, qui n'avaient pas toujours une interconnexion suffisante pour encaisser tout le trafic accru. Comme toujours sur l'Internet, malgré le caractère mondial de la pandémie, il y a peu d'observations valables partout et tout le temps, vu la variété des capacités des liaisons. Malgré l'observation générale « globalement, ça a tenu », il y a toujours des endroits où ca rame à certains moments.

En effet, le bon fonctionnement de l'Internet mondial ne signifiait pas que tous les M. Toutlemonde de la Terre avaient une bonne qualité de connexion. L'article « The Impact of COVID-19 on Last-mile Latency » (plus de détails sur le blog de l'auteur) rend compte de mesures faites avec les sondes RIPE Atlas, qui trouvent une congestion plus fréquente sur le « premier kilomètre » (le lien entre la maison de M. Toutlemonde et le premier POP de son FAI) pendant le confinement). Cela dépend évidemment beaucoup du FAI et du pays, le Japon ayant été particulièrement touché. La situation s'est toutefois améliorée au fur et à mesure, notamment en raison des déploiements de capacité supplémentaire par les opérateurs (et, au Japon, des investissements qui étaient prévus pour les Jeux Olympiques). L'Internet se retrouve donc plus robuste qu'avant. Le RFC cite même Nietzsche « Ce qui ne me tue pas me rend plus fort ».

On l'a dit, le trafic n'a pas seulement changé quantitativement mais aussi qualitativement. La vidéo-conférence a, fort logiquement, crû. Le trafic très asymétrique de certains FAI grand public (beaucoup plus de trafic entrant vers les consommateurs que de trafic sortant) s'est un peu égalisé, en raison des flux vidéos sortants. NCTA et Comcast signalent plus de 30 % de hausse de ce trafic sortant, Vodafone 100 %. Un rapport d'Ericsson sur les utilisateurs signale :

  • Une augmentation de l'utilisation de l'Internet par 9 utilisateurs sur 10 (le dixième était peut-être déjà connecté tout le temps ?) et des usages nouveaux par 1 utilisateur sur 5 (des gens comme moi qui se mettent à la vidéo-conférence alors qu'ils détestaient cela avant).
  • Peu de plaintes concernant les performances.
  • Évidemment un changement dans les applications utilisées, les applications de vidéo-conférence voient leur usage s'accroitre, celles liées à la location d'hôtels ou de restaurants (ou, note le RFC, celles permettant la recherche d'une place de parking) le voient diminuer.

Ces changements sont-ils permanents ? Resteront-ils dans le « monde d'après » ? Le RFC estime que le télétravail s'est désormais installé et restera ; on peut donc prévoir que l'utilisation intensive d'outils de réunion à distance persistera (cf. le rapport « Work-At-Home After Covid-19—Our Forecast »).

Après ces observations, la section 3 du RFC continue avec des considérations sur les problèmes opérationnels constatés. D'abord, un point de fracture numérique. Aux États-Unis, et probablement dans bien d'autres pays, le débit entrant chez les utilisateurs est corrélé au niveau de vie. Mais on a constaté pendant la pandémie une réduction de l'écart entre riches et pauvres (l'étude ne portait pas sur des foyers individuels mais sur des zones géographiques identifiées par leur code postal, un bon indicateur de niveau de vie, au moins aux USA). Cette réduction de l'écart n'était pas forcément liée à un changement de comportement des utilisateurs mais l'était peut-être au fait que certains FAI comme Comcast ont étendu la capacité liée à des abonnements bon marché, par souci de RSE pendant la crise. L'écart entre riches et pauvres était donc peut-être dû à une différence dans les abonnements souscrits, pas à une différence d'utilisation de l'Internet.

Les applications vedettes des confinements ont évidemment été les outils de réunion en ligne, gros services privateurs et capteurs de données personnelles comme Microsoft Teams ou Zoom, ou bien services reposant sur des logiciels libres comme BigBlueButton (dont le RFC, qui reflète un point de vue surtout étatsunien, ne parle pas). D'autres outils de distribution de vidéo, comme YouTube ont vu également leur trafic augmenter soudainement. Certains acteurs, comme justement YouTube, ont délibérement réduit la qualité des vidéos pour diminuer la charge sur le réseau, mais il n'est pas évident que cela ait eu un effet majeur. Autre catégorie d'applications qui a vu son utilisation augmenter, les jeux en ligne. Souvent très consommateurs de ressources, ils ont la particularité de demander à la fois une forte capacité (en raisons des contenus multimédias riches à télécharger) et une faible latence (quand on tire sur le zombie, il doit tomber tout de suite). La mise à jour d'un jeu très populaire a un effet très net sur le réseau des FAI ! Mais il faut noter que ce n'est pas un phénomène spécifique au confinement. Les opérateurs ont déjà dû faire face à des évènements soudains, comme une nouvelle version d'un logiciel très utilisé ou comme une nouvelle mode, par exemple une application qui connait un succès rapide, ce qui est assez fréquent sur l'Internet. Outre ces « effets Slashdot », il y a aussi les attaques par déni de service, qui nécessitent de suravitailler (mettre davantage de capacité que strictement nécessaire). Les opérateurs ont donc déjà de l'expérience dans ce domaine mais, note le RFC, cette expérience n'est pas toujours partagée.

Une discussion lors de l'atelier a porté sur la possibilité de gérer ce genre de problèmes par des mesures discriminatoires, de type qualité de service (un terme propagandiste, il faut le noter : si on discrimine, certains auront une meilleure qualité et d'autres une moins bonne). Marquer le trafic « pas essentiel » (qui décidera de ce qui n'est pas essentiel ?) avec DSCP pour le faire passer par les chemins les plus lents aurait-il aidé ? Compte-tenu du caractère très brûlant de ce débat, il n'est pas étonnant qu'aucun consensus n'est émergé de l'atelier. Le RFC se réjouit qu'au moins les engueulades ont été moins graves que d'habitude.

Une bonne partie de cet atelier était consacré à l'étude de faits : qu'ont vu les opérateurs ? Or, ils n'ont pas vu la même chose. Cela reflète les différences de situation mais aussi les différences dans les outils d'observation. La métrologie n'est pas une chose facile ! Par exemple, les applications de vidéo-conférence ou de distribution de vidéo à la demande ont des mécanismes de correction d'erreur et de gestion de la pénurie très élaborés. L'application s'adapte en permanence aux caractéristiques du réseau, par exemple en ajustant son taux de compression. C'est très bien pour l'utilisateur, cela permet de lui dissimuler une grande partie des problèmes, mais cela complique l'observation. Et quand il y a un problème, il est difficile à analyser. L'autre jour, sans que cela ait de rapport avec un confinement, je regardais une vidéo sur Netflix et la qualité de l'image était vraiment médiocre, gâchant le plaisir. Mais où était le problème ? Mon PC était trop lent ? Le Wifi était pourri ? Le réseau de Free surchargé ? L'interconnexion entre Free et Netflix était-elle encombrée ? Les serveurs de Netflix ramaient-ils ? C'est très difficile à dire, et cela dépend de beaucoup de choses (par exemple, deux utilisateurs de Netflix ne tombent pas forcément sur le même serveur chez Netflix et peuvent donc avoir des vécus différents). Et puis, globalement, on manque de capacités d'observation sur l'Internet. Le client ne voit pas ce qui se passe sur le serveur, le serveur ne sait pas grand'chose sur le client, et peut-être qu'aucun des deux n'a pas visibilité sur l'interconnexion. Chacun connait bien son réseau, mais personne ne connait l'Internet dans son ensemble. Le RFC note que, paradoxalement, la Covid-19 a amélioré les choses, en augmentant le niveau de coopération entre les acteurs de l'Internet.

Et la sécurité ? Elle a aussi été discutée à l'atelier car le passage brusque de tant de gens au télétravail a changé le paysage de la sécurité. On ne pouvait plus compter sur le pare-feu corporate et sur les machines du bureau soigneusement verrouillées par la DSI. Au lieu de cela, tout le monde utilisait des VPN pas toujours bien maitrisés (cf. l'article « IAB COVID-19 Network Impacts »). Et la pandémie a été l'occasion de nombreuses escroqueries (décrites dans le même article). À propos de sécurité, le RFC en profite pour vanter les résolveurs DNS menteurs et critiquer DoH (qui n'est pour rien dans ces escroqueries).

En conclusion, le RFC note que le bon fonctionnement de l'Internet pendant la pandémie n'était pas dû uniquement à ses qualités intrinsèques, mais aussi à l'action de nombreux acteurs. Comme d'autres professions, les techniciens et techniciennes de l'Internet étaient une des lignes de défense face à l'épidémie et cette ligne était très motivée, et a tenu. Ces techniciennes et techniciens méritent donc de chaudes félicitations. Mais on peut quand même améliorer les choses :

  • En continuant à étudier le fonctionnement de l'Internet. Le caractère critique de l'Internet pour tant d'activités humaines justifie qu'on continue à analyser ses caractéristiques et ses faiblesses.
  • Le partage d'informations et la communication sont essentiels et doivent être accrus.
  • La lutte contre la fracture numérique doit se poursuivre, puisqu'en période de confinement, être coupé du réseau, ou y accéder dans de mauvaises conditions (accès lent, matériel inadapté, manque de littératie numérique), aggrave encore l'isolement.

Et le RFC se conclut par un bilan de cet atelier qui, contrairement aux ateliers précédents de l'IAB, a été fait entièrement en ligne. Les participants ont été plutôt contents, notamment du fait que le travail à distance a permis de changer le format : au lieu de deux jours complets de discussions, l'atelier a pu se tenir en alternant des moments de discussion et du travail chez soi, pour approfondir et critiquer les discussions. Toutefois, le RFC note que cela a bien marché car la quasi-totalité des présents se connaissaient bien, étant des participants de longue date à l'IETF. Il n'est pas du tout évident que cela aurait aussi bien marché avec des gens nouveaux, le présentiel étant crucial pour créer des liens informels.

L'ensemble des articles écrits par les participants à l'atelier (pour participer, il fallait avoir écrit un texte) est disponible en ligne (en bas de la page).


Téléchargez le RFC 9075


L'article seul

Les problèmes gris dans les réseaux informatiques

Première rédaction de cet article le 21 juillet 2021


Une passionnante discussion sur la liste NANOG vient de porter sur les « problèmes gris ». Qu'est-ce qu'un problème gris en matière de réseaux informatiques ?

Les réseaux ne sont pas fiables, toute personne qui a déjà vu un message « Connection time out » peut en témoigner. De l'erreur de configuration chez un opérateur à l'attaque d'une pelleteuse sur une fibre, en passant par une bogue dans les routeurs, les causes de panne ne manquent pas. Ces pannes sont typiquement binaires : soit toutes les communications passent, soit aucune ne passe. À défaut d'être faciles à prévenir, ou même à réparer, ces pannes sont triviales à détecter : la supervision couine et les utilisateurs râlent. Mais il y a aussi des pannes « grises ». C'est quand ça déconne mais pas de manière binaire : la grande majorité du trafic passe (et on peut donc ne s'apercevoir de rien) mais le problème gris frappe une petite minorité des paquets, selon des critères qui ne sont pas évidents à première vue. Par exemple, le réseau laisse passer tous les paquets, sauf ceux qui ont telle combinaison d'options. Ou bien il laisse passer 99,99 % des paquets mais jette les autres (en dehors du cas de congestion, où il est normal de jeter les paquets). Dans la discussion sur NANOG, un ingénieur citait un cas qu'il avait rencontré où une line card défaillante jetait tous les paquets IPv6 où le 65e bit de l'adresse de destination était à 1 (ce qui est apparemment assez rare). Le terme a été utilisé dans d'autres contextes que le réseau (par exemple cette étude de Microsoft).

La discussion sur la liste NANOG avait été lancée dans le contexte d'une étude de l'École polytechnique de Zurich, étude qui commençait par un sondage auprès des opérateurs pour leur demander s'ils géraient les problèmes gris et comment.

D'abord, une constatation peu originale mais qu'il est important de rappeler. Même en dehors de la congestion, aucun réseau ne transporte 100 % des paquets. Il y a toujours des problèmes, les réseaux étant des objets physiques, soumis aux lois de la physique et aux perturbations diverses (comme les rayons cosmiques). Aucune machine n'est idéale, l'électronique n'est pas virtuelle et est donc imparfaite, la mémoire d'un routeur ne garde pas forcément intact ce qu'on lui a confié. Et, non, FCS et ECC ne détectent pas tous les problèmes. Comme le notait un observateur : « De ma longue expérience, j'en ai tiré une analyse (très pertinente) : en informatique il y a entre 1 % et 2 % de magie. C'est faux, mais ça soulage parfois de se dire qu'on est peut être la cible d'un sortilège vaudou ou sous la coupe d'une bonne fée. » Si un opérateur prétendait sincèrement ne pas avoir de problèmes gris, cela indiquerait une absence de recherche plutôt qu'une absence de problème. Fermer les yeux permet de dormir mieux :-)

Les problèmes gris sont très difficiles à détecter. Supposons que, comme tout bon ingénieur, vous avez un système de supervision automatique qui fonctionne, mettons, en envoyant des messages ICMP de type Echo et en attendant une réponse. Si vous envoyez trois paquets par test, et que le réseau jette 1 % des paquets (un chiffre très élevé) au hasard, vous n'avez qu'une chance sur un demi-million de détecter le problème. Bien sûr, on ne se contente pas de ce genre de tests. On regarde par exemple les compteurs attachés aux interfaces des routeurs et on regarde si les compteurs d'erreur grimpent. Mais si c'est l'électronique des routeurs qui est défaillante, les compteurs ne seront pas fiables.

Les problèmes gris sont parfois déterministes (comme dans l'exemple du bit 65 plus haut) mais pas toujours et, s'ils ne sont pas reproductibles, le problème est encore pire. Même s'ils sont déterministes, l'algorithme n'est pas forcément évident. Si les paquets sont aiguillés à l'intérieur d'un équipement selon des critères complexes, et qu'un seul des circuits est défaillant, vous ne trouverez pas forcément tout de suite pourquoi, des fois, ça passe et, des fois, ça ne passe pas.

Est-ce grave pour l'opérateur ? Dans la discussion sur NANOG, un participant a dit franchement que les problèmes gris étaient fréquents mais tellement difficiles à traiter (par exemple parce qu'ils impliquent souvent de longues et difficiles négociations avec les vendeurs de matériel) qu'il valait mieux les ignorer, sauf si un client râlait. Mais, justement, le client ne râle pas toujours si le problème est rare, et difficile à pointer du doigt avec précision. Et puis les systèmes modernes comportent tellement de couches superposées que le client a le plus grand mal à trouver l'origine d'un problème. Ainsi, dans le cas d'un problème spécifique à IPv6, comme celui cité plus haut, le fait que le navigateur Web typique se rabatte automatiquement et rapidement en IPv4 n'aide pas au diagnostic (même si c'est certainement mieux pour le bonheur de l'utilisateur).

Pour donner une idée de la subtilité des problèmes gris, un participant à NANOG citait un cas d'un commutateur qui perdait 0,00012 % des paquets, un nombre difficile à repérer au milieu des erreurs de mesure. Le problème avait été détecté lors du remplacement des anciens tests (genre les trois messages ICMP cités plus haut) par des tests plus violents.

Bref, quand vous (enfin, votre navigateur Web) avez récupéré cet article, peut-être un problème gris a-t-il perturbé cette récupération. Peut-être n'a-t-il même pas été détecté et le texte que vous lisez n'est pas le bon…


L'article seul

RFC 9065: Considerations around Transport Header Confidentiality, Network Operations, and the Evolution of Internet Transport Protocols

Date de publication du RFC : Juillet 2021
Auteur(s) du RFC : G. Fairhurst (University of Aberdeen), C. Perkins (University of Glasgow)
Pour information
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 20 juillet 2021


La couche Transport n'est pas celle qui suscite le plus de passions dans l'Internet. Mais la récente normalisation du protocole QUIC a mis cette couche en avant et l'usage du chiffrement par QUIC a relancé le débat : quelles sont les conséquences d'un chiffrement de plus en plus poussé de la couche Transport ?

Traditionnellement, la couche Transport ne faisait pas de chiffrement (cf. RFC 8095 et RFC 8922). On chiffrait en-dessous (IPsec) ou au-dessus (TLS, SSH). IPsec ayant été peu déployé, l'essentiel du chiffrement aujourd'hui sur l'Internet est fait par TLS. Toute la mécanique TCP est donc visible aux routeurs sur le réseau. Ils peuvent ainsi mesurer le RTT, découvrir début et fin d'une connexion, et interférer avec celle-ci, par exemple en envoyant des paquets RST (ReSeT) pour mettre fin à la session. Cela permet de violer la vie privée (RFC 6973), par exemple en identifiant une personne à partir de son activité en ligne. Et cette visibilité de la couche Transport pousse à l'ossification : de nombreux intermédiaires examinent TCP et, si des options inhabituelles sont utilisées, bloquent les paquets. Pour éviter cela, QUIC chiffre une grande partie de la couche 4, pour éviter les interférences par les intermédiaires et pour défendre le principe de bout en bout et la neutralité du réseau. Comme souvent en sécurité, cette bonne mesure de protection a aussi des inconvénients, que ce RFC examine. Notons tout de suite que ce qui est un inconvénient pour les uns ne l'est pas forcément pour les autres : pour un FAI, ne pas pouvoir couper les connexions TCP de BitTorrent avec RST est un inconvénient mais, pour l'utilisateur, c'est un avantage, cela le protège contre certaines attaques par déni de service.

On ne peut pas sérieusement aujourd'hui utiliser des communications non-chiffrées (RFC 7258). Personne n'ose dire publiquement le contraire. Par contre, on entend souvent un discours « je suis pour le chiffrement, mais » et, comme toujours avec ce genre de phrase, c'est ce qui est après le « mais » qui compte. Ce RFC essaie de documenter les avantages et les inconvénients du chiffrement de la couche Transport, mais, en pratique, est plus détaillé sur les inconvénients, ce qui était déjà le cas du RFC 8404.

La section 2 du RFC explique quel usage peut être fait des informations de la couche Transport par les équipements intermédiaires. En théorie, dans un modèle en couches idéal, il n'y en aurait aucun : la couche Transport est de bout en bout, les routeurs et autres équipements intermédiaires ne regardent rien au-dessus de la couche Réseau. Mais en pratique, ce n'est pas le cas, comme l'explique cette section. (Question pour mes lecteurices au passage : vous semble-t-il légitime de parler de DPI quand un routeur regarde le contenu de la couche Transport, dont il n'a en théorie pas besoin, ou bien doit-on réserver ce terme aux cas où il regarde dans la couche Application ?)

Première utilisation de la couche Transport par des intermédiaires : identifier des flots de données (une suite d'octets qui « vont ensemble »). Pourquoi en a-t-on besoin ? Il y a plusieurs raisons possibles, par exemple pour la répartition de charge, où on veut envoyer tous les paquets d'un flot donné au même serveur. Cela se fait souvent en prenant un tuple d'informations dans le paquet (tuple qui peut inclure une partie de la couche Transport, comme les ports source et destination) et en le condensant pour avoir un identificateur du flot. Si la couche Transport est partiellement ou totalement chiffrée, on ne pourra pas distinguer deux flots différents entre deux machines. En IPv6, l'étiquette de flot (RFC 6437) est une solution possible (RFC 6438, RFC 7098), mais je n'ai pas l'impression qu'elle soit très utilisée.

Maintenant, passons à la question de l'identification d'un flot. Était-ce un transfert de fichiers, de la vidéo, une session interactive ? Il faut déduire cette identification à partir des informations de la couche Transport (voir le RFC 8558). Mais pourquoi identifier ces flots alors que l'opérateur doit tous les traiter pareil, en application du principe de neutralité ? Cela peut être dans l'intérêt de l'utilisateur (mais le RFC ne donne pas d'exemple…) ou bien contre lui, par exemple à des fins de surveillance, ou bien pour discriminer certains usages (comme le réclament régulièrement certains politiciens et certains opérateurs), voire pour les bloquer complètement. Autrefois, on pouvait souvent identifier un service uniquement avec le numéro de port (43 pour whois, 25 pour le courrier, etc, cf. RFC 7605) mais cela n'a jamais marché parfaitement, plusieurs services pouvant utiliser le même port et un même service pouvant utiliser divers ports. De toute façon, cette identification par le numéro de port est maintenant finie, en partie justement en raison de cette discrimination selon les usages, qui pousse tout le monde à tout faire passer sur le port 443. Certains services ont un moyen simple d'être identifié, par exemple par un nombre magique, volontairement placé dans les données pour permettre l'identification, ou bien simple conséquence d'une donnée fixe à un endroit connu (RFC 3261, RFC 8837, RFC 7983…). Lors de la normalisation de QUIC, un débat avait eu lieu sur la pertinence d'un nombre magique permettant d'identifier du QUIC, idée finalement abandonnée.

Si les équipements intermédiaires indiscrets n'arrivent pas à déterminer le service utilisé, le flot va être considéré comme inconnu et le RFC reconnait que certains opérateurs, en violation de la neutralité de l'Internet, ralentissent ces flots inconnus.

L'étape suivante pour ceux qui veulent identifier à quoi servent les données qu'ils voient passer est d'utiliser des heuristiques. Ainsi, une visio-conférence à deux fera sans doute passer à peu près autant d'octets dans chaque sens, alors que regarder de la vidéo à la demande créera un trafic très asymétrique. Des petits paquets UDP régulièrement espacés permettent de soupçonner du trafic audio, même si on n'a pas pu lire l'information SDP (RFC 4566). Des heuristiques plus subtiles peuvent permettre d'en savoir plus. Donc, il faut se rappeler que le chiffrement ne dissimule pas tout, il reste une vue qui peut être plus ou moins précise (le RFC 8546 décrit en détail cette notion de vue depuis le réseau).

Autre motivation pour analyser la couche Transport, l'amélioration des performances. Inutile de dire que le FAI typique ne va pas se pencher sur les problèmes de performance d'un abonné individuel (si ça rame avec Netflix, appeler le support de son FAI ne déclenche pas de recherches sérieuses). Mais cela peut être fait pour des analyse globales. Là encore, les conséquences peuvent être dans l'intérêt de l'utilisateur, ou bien contre lui. Le RFC note que les mesures de performance peuvent amener à une discrimination de certains services (« QoS », qualité de service, c'est-à-dire dégradation de certains services). Que peut-on mesurer ainsi, qui a un impact sur les performances ? Il y a la perte de paquets, qu'on peut déduire, en TCP, des retransmissions. Dans l'Internet, il y a de nombreuses causes de pertes de paquets, du parasite sur un lien radio à l'abandon délibéré par un routeur surchargé (RFC 7567) en passant par des choix politiques de défavoriser certains paquets (RFC 2475). L'étude de ces pertes peut permettre dans certains cas de remonter aux causes.

On peut aussi mesurer le débit. Bon, c'est facile, sans la couche Transport, uniquement en regardant le nombre d'octets qui passent par les interfaces réseaux. Mais l'accès aux données de la couche Transport permet de séparer le débit total du débit utile (goodput, en anglais, pour le différencier du débit brut, le throughput, cf. section 2.5 du RFC 7928, et le RFC 5166). Pour connaitre ce débit utile, il faut pouvoir reconnaitre les retransmissions (si un paquet est émis trois fois avant enfin d'atteindre le destinataire, il ne contribue qu'une fois au débit utile). Une retransmission peut se voir en observant les numéros de séquence en TCP (ou dans d'autres protocoles comme RTP).

La couche Transport peut aussi nous dire quelle est la latence. Cette information est cruciale pour évaluer la qualité des sessions interactives, par exemple. Et elle influe beaucoup sur les calculs du protocole de couche 4. (Voir l'article « Internet Latency: A Survey of Techniques and their Merits ».) Comment mesure-t-on la latence ? Le plus simple est de regarder les accusés de réception TCP et d'en déduire le RTT. Cela impose d'avoir accès aux numéros de séquence. Dans TCP, ils sont en clair, mais QUIC les chiffre (d'où l'ajout du spin bit).

D'autres métriques sont accessibles à un observateur qui regarde la couche Transport. C'est le cas de la gigue, qui se déduit des observations de la latence, ou du réordonnancement des paquets (un paquet qui part après un autre, mais arrive avant). L'interprétation de toutes ces mesures dépend évidemment du type de lien. Un lien radio (RFC 8462) a un comportement différent d'un lien filaire (par exemple, une perte de paquets n'est pas forcément due à la congestion, elle peut venir de parasites).

Le RFC note que la couche Réseau, que les équipements intermédiaires ont tout à fait le droit de lire, c'est son rôle, porte parfois des informations qui peuvent être utiles. En IPv4, ce sont les options dans l'en-tête (malheureusement souvent jetées par des pare-feux trop fascistes, cf. RFC 7126), en IPv6, les options sont après l'en-tête de réseau, et une option, Hop-by-hop option est explicitement prévue pour être examinée par tous les routeurs intermédiaires.

Outre les statistiques, l'analyse des données de la couche Transport peut aussi servir pour les opérations (voir aussi le RFC 8517), pour localiser un problème, pour planifier l'avitaillement de nouvelles ressources réseau, pour vérifier qu'il n'y a pas de tricheurs qui essaient de grapiller une part plus importante de la capacité, au risque d'aggraver la congestion (RFC 2914). En effet, le bon fonctionnement de l'Internet dépend de chaque machine terminale. En cas de perte de paquets, signal probable de congestion, les machines terminales sont censées réémettre les paquets avec prudence, puisque les ressources réseau sont partagées. Mais une machine égoïste pourrait avoir plus que sa part de la capacité. Il peut donc être utile de surveiller ce qui se passe, afin d'attraper d'éventuels tricheurs, par exemple une mise en œuvre de TCP qui ne suivrait pas les règles habituelles. (Si on utilise UDP, l'application doit faire cela elle-même, cf. RFC 8085. Ainsi, pour RTP, comme pour TCP, un observateur extérieur peut savoir si les machines se comportent normalement ou bien essaient de tricher.)

Autre utilisation de l'observation de la couche Transport pour l'opérationnel, la sécurité, par exemple la lutte contre les attaques par déni de service, l'IDS et autres fonctions. Le RFC note que cela peut se faire en coopération avec les machines terminales, si c'est fait dans l'intérêt de l'utilisateur. Puisqu'on parle de machines terminales, puisque le chiffrement d'une partie de la couche Transport est susceptible d'affecter toutes les activités citées plus haut, le RFC rappelle la solution évidente : demander la coopération des machines terminales. Il y a en effet deux cas : soit les activités d'observation de la couche Transport sont dans l'intérêt des utilisateurs, et faites avec leur consentement, et dans ce cas la machine de l'utilisateur peut certainement coopérer, soit ces activités se font contre l'utilisateur (discrimination contre une application qu'il utilise, par exemple), et dans ce cas le chiffrement est une réponse logique à cette attaque. Bien sûr, c'est la théorie ; en pratique, certaines applications ne fournissent guère d'informations et de moyens de déboguage. Les protocoles de transport qui chiffrent une bonne partie de leur fonctionnement peuvent aussi aider, en exposant délibérement des informations. C'est par exemple ce que fait QUIC avec son spin bit déjà cité, ou avec ses invariants documentés dans le RFC 8999.

Autre cas où le chiffrement de la couche Transport peut interférer avec certains usages, les réseaux d'objets contraints, disposant de peu de ressources (faible processeur, batterie qu'il ne faut pas vider trop vite, etc). Il arrive dans ce cas d'utiliser des relais qui interceptent la communication, bricolent dans la couche Transport puis retransmettent les données. Un exemple d'un tel bricolage est la compression des en-têtes, courante sur les liens à très faible capacité (cf. RFC 2507, RFC 2508, le ROHC du RFC 5795, RFC 6846, le SCHC du RFC 8724, etc). Le chiffrement rend évidemment cela difficile, les relais n'ayant plus accès à l'information. C'est par exemple pour cela que le RTP sécurisé du RFC 3711 authentifie l'en-tête mais ne le chiffre pas. (Je suis un peu sceptique sur cet argument : d'une part, les objets contraints ne vont pas forcément utiliser des protocoles de transport chiffrés, qui peuvent être coûteux, d'autre part un sous-produit du chiffrement est souvent la compression, ce qui rend inutile le travail des relais.)

Un dernier cas cité par le RFC où l'observation du fonctionnement de la couche Transport par les machines intermédiaires est utile est celui de la vérification de SLA. Si un contrat ou un texte légal prévoit certaines caractéristiques pour le réseau, l'observation de la couche 4 (retransmission, RTT…) est un moyen d'observer sans avoir besoin d'impliquer les machines terminales. (Personnellement, je pense justement que ces vérifications devraient plutôt se faire depuis les machines terminales, par exemple avec les sondes RIPE Atlas, les SamKnows, etc.)

La section 3 du RFC décrit un autre secteur qui est intéressé par l'accès aux données de transport, la recherche. Par exemple, concevoir de nouveaux protocoles doit s'appuyer sur des mesures faites sur les protocoles existants, pour comprendre leurs forces et leurs faiblesses. C'est possible avec un protocole comme TCP, où l'observation passive permet, via notamment les numéros de séquence, de découvrir le RTT et le taux de perte de paquets. (Passive : sans injecter de paquets dans le réseau. Voir le RFC 7799.) Mais ces mêmes informations peuvent aussi servir contre l'utilisateur. Même s'il n'y a pas d'intention néfaste (par exemple de discrimination contre certains usages), toute information qui est exposée peut conduire à l'ossification, l'impossibilité de changer le protocole dans le futur. Une des motivations des protocoles chiffrés comme QUIC est en effet d'éviter l'ossification : une middlebox ne pourra pas prendre de décisions sur la base d'informations qu'elle n'a pas. QUIC affiche des données au réseau seulement s'il le veut (c'est le cas du spin bit). D'où également le choix délibéré de graisser, c'est-à-dire de faire varier certaines informations pour éviter que des programmeurs de middleboxes incompétents et/ou paresseux n'en déduisent que cette information ne change jamais (le graissage est décrit dans le RFC 8701).

La bonne solution pour récolter des données sans sacrifier la vie privée est, comme dit plus haut, de faire participer les extrémités, les machines terminales, ce qu'on nomme en anglais le endpoint-based logging. Actuellement, malheureusement, les mécanismes de déboguage ou de récolte d'information sur ces machines terminales sont trop réduits, mais des efforts sont en cours. Par exemple, pour QUIC, c'est la normalisation du format « qlog » d'enregistrement des informations vues par la couche Transport (Internet-Draft draft-ietf-quic-qlog-main-schem) ou bien le format Quic-Trace. Mais le RFC note que la participation des machines terminales ne suffit pas toujours, notamment si on veut déterminer , dans le réseau, se produit un problème.

Après qu'on ait vu les utilisations qui sont faites de l'analyse de la couche Trnsport par les équipements intermédiaires, la section 4 du RFC revient ensuite sur les motivations du chiffrement de cette couche. Pourquoi ne pas se contenter de ce que font TLS et SSH, qui chiffrent uniquement la couche Application ? L'une des premières raisons est d'empêcher l'ossification, ce phénomène qui fait qu'on ne peut plus faire évoluer la couche Transport car de stupides équipements intermédiaires, programmés avec les pieds par des ignorants qui ne lisent pas les RFC, rejettent les paquets légaux mais qui ne correspondent pas à ce que ces équipements attendaient. Ainsi, si un protocole de transport permet l'utilisation d'un octet dans l'en-tête, mais que cet octet est à zéro la plupart du temps, on risque de voir des middleboxes qui jettent les paquets où certains bits de ce champ sont à un car « ce n'est pas normal ». Tout ce qui est observable risque de devenir ossifié, ne pouvant plus être modifié par la suite. Chiffrer permet de garantir que les équipements intermédiaires ne vont pas regarder ce qui ne les regarde pas. Le RFC donne plusieurs exemples édifiants des incroyables comportements de ces logiciels écrits par des gens qui ne comprenaient qu'une partie d'un protocole :

  • Pendant le développement de TLS 1.3 (qui mènera au RFC 8446), il a fallu concevoir 1.3 de manière à ce qu'il ressemble à 1.2, car certaines middleboxes rejettaient du TLS légal, mais différent de ce qu'elles attendaient.
  • MPTCP (RFC 8684) a également dû être modifié pour tenir compte de boitiers intermédiaires qui observaient le fonctionnement de la fenêtre TCP et se permettaient de couper les connexions qui leur semblaient anormales.
  • D'une manière générale, tout protocole qui permet des options est confronté à des middleboxes qui interfèrent dès qu'on utilise des options nouvelles. C'est le cas par exemple de TCP Fast Open (RFC 7413).
  • Encore pire, si c'est possible, on a vu des équipements intermédiaires qui changeaient les numéros de séquence TCP, ce qui cassait les accusés de réception SACK (RFC 2018).

Il n'est donc pas étonnant que les concepteurs de protocole cherchent désormais à chiffrer au maximum, pour éviter ces interférences. Le RFC 8546 rappelle ainsi que c'est la vue depuis le réseau (wire image), c'est-à-dire ce que les équipements intermédiaires peuvent observer, pas la spécification écrite du protocole, qui détermine, dans le monde réel, ce qu'un intermédiaire peut observer et modifier. Il faut donc réduire cette vue au strict minimum ; tout ce qui n'est pas chiffré risque fortement d'être ossifié, figé. Et le RFC 8558 affirme lui qu'on ne doit montrer au réseau que ce qui doit être utilisé par le réseau, le reste, qui ne le regarde pas, doit être dissimulé.

Une autre motivation du chiffrement de la couche Transport est évidemment de mieux protéger la vie privée (RFC 6973). L'ampleur de la surveillance massive (RFC 7624) est telle qu'il est crucial de gêner cette surveillance le plus possible. Le RFC note qu'il n'y a pas que la surveillance passive, il y a aussi l'ajout de données dans le trafic, pour faciliter la surveillance. Du fait de cet « enrichissement », il peut être utile, quand un champ doit être observable (l'adresse IP de destination est un bon exemple), d'utiliser quand même la cryptographie pour empêcher ses modifications, via un mécanisme d'authentification. C'est ce que fait TCP-AO (RFC 5925, mais qui semble peu déployé), et bien sûr le service AH d'IPsec (RFC 4302).

Comme on le voit, il y a une tension, voire une lutte, entre les opérateurs réseau et les utilisateurs. On pourrait se dire que c'est dommage, qu'il vaudrait mieux que tout le monde travaille ensemble. Cela a été discuté à l'IETF, avec des expressions comme « un traité de paix entre machines terminales et boitiers intermédiaires ». Pour l'instant, cela n'a pas débouché sur des résultats concrets, en partie parce qu'il n'existe pas d'organisations représentatives qui pourraient négocier, signer et faire respecter un tel traité de paix. On en reste donc aux mesures unilatérales. Les machines terminales doivent chiffrer de plus en plus pour maintenir le principe de bout en bout. Comme dans tout conflit, il y a des dégâts collatéraux (le RFC 8922 en décrit certains). Le problème n'étant pas technique mais politique, il est probable qu'il va encore durer. La tendance va donc rester à chiffrer de plus en plus de choses.

À noter qu'une autre méthode que le chiffrement existe pour taper sur les doigts des boitiers intermédiaires pénibles, qui se mêlent de ce qui ne les regarde pas, et s'en mêlent mal : c'est le graissage. Son principe est d'utiliser délibérément toutes les options possibles du protocole, pour habituer les middleboxes à voir ces variations. Le RFC 8701 en donne un exemple, pour le cas de TLS.

Déterminer ce qu'il faut chiffrer, ce qu'il faut authentifier, et ce qu'il vaut mieux laisser sans protection, autorisant l'observation et les modifications, n'est pas une tâche facile. Autrefois, tout était exposé parce qu'on avait moins de problèmes avec les boitiers intermédiaires et que les solutions, comme le chiffrement, semblaient trop lourdes. Aujourd'hui qu'on a des solutions réalistes, on doit donc choisir ce qu'on montre ou pas. Le choix est donc désormais explicite (cf. RFC 8558).

Au passage, une façon possible d'exposer des informations qui peuvent être utiles aux engins intermédiaires est via un en-tête d'extension. Par exemple en IPv6, l'en-tête Hop-by-hop (RFC 8200, section 4.3) est justement fait pour cela (voir un exemple dans le RFC 8250, quoiqu'avec un autre type d'en-tête). Toutefois, cet en-tête Hop-by-hop est clairement un échec : beaucoup de routeurs jettent les paquets qui le portent (RFC 7872), ou bien les traitent plus lentement que les paquets sans cette information. C'est encore pire si cet en-tête porte des nouvelles options, inconnues de certaines middleboxes, et c'est pour cela que le RFC 8200 déconseille (dans sa section 4.8) la création de nouvelles options Hop-by-hop.

Mais, bon, le plus important est de décider quoi montrer, pas juste comment. Le RFC rappelle qu'il serait sympa d'exposer explicitement des informations comme le RTT ou le taux de pertes vu par les machines terminales, plutôt que de laisser les machines intermédiaires le calculer (ce qu'elles ne peuvent de toute façon plus faire en cas de chiffrement). Cela permettrait de découpler l'information de haut niveau des détails du format d'un protocole de transport. Pourquoi une machine terminale ferait-elle cela, au risque d'exposer des informations qu'on peut considérer comme privées ? Le RFC cite la possibilité d'obtenir un meilleur service, sans trop préciser s'il s'agit de laisser les opérateurs offrir un traitement préférentiel aux paquets portant cette information, ou bien si c'est dans l'espoir que l'information exposée serve à l'opérateur pour améliorer son réseau. (Comme le note le RFC 8558, il y a aussi le risque que la machine terminale mente au réseau. Au moins, avec le chiffrement, les choses sont claires : « je refuse de donner cette information » est honnête.)

Dernière note, cet ajout d'informations utiles pour l'OAM peut être faite par la machine terminale mais aussi (section 6 du RFC) par certains équipements intermédiaires.

En conclusion ? La section 7 du RFC reprend et résume les points importants :

  • Le chiffrement et l'authentification dans la couche de Transport sont une bonne chose. Personne n'ose dire ouvertement qu'il faudrait rester à des protocoles de transport non sécurisés. C'est un point sur lequel le document a beaucoup évolué. Dans les versions antérieures, comme le notait Christian Huitema, « Much of the draft reads like a lamentation of the horrible consequences of encrypting transport headers », reflétant unilatéralement le point de vue des opérateurs réseau, et des vendeurs de middleboxes. Une relecture par Christopher Wood au début du projet avait déjà pointé ce problème, notant que le document était très anti-chiffrement. Cette question a, fort logiquement, été le principal point de discussion à l'IETF.
  • Le RFC, officiellement, ne tranche pas sur la pertinence et l'éthique des pratiques qu'il décrit, il explique juste ce qui se fait. (Le même argument, que je trouve un peu hypocrite, avait été utilisé pour le très contestable RFC 8404.)
  • Comme souvent en sécurité, il n'y a pas de solution idéale, il faudra trouver un compromis, par exemple entre la vie privée et l'OAM. Le RFC cite le spin bit de QUIC, qui avait été très chaudement discuté, comme un exemple de compromis, en tout cas par le sérieux de l'analyse de ses coûts et de ses bénéfices.
  • Le RFC reconnait que tout ce qui est exposé au réseau s'ossifiera et deviendra une spécification de fait, qu'on ne pourra plus changer. Qu'un protocole choisisse d'exposer beaucoup ou au contraire très peu, il doit de toute façon faire ce choix explicitement.
  • Même le chiffrement de la couche Transport ne cache pas tout, et les couches inférieures exposent toujours des métadonnées. Un surveillant déterminé n'est donc pas désarmé. (Même si des organisations comme Interpol prétendent que le chiffrement rend la police « aveugle ».)
  • Les opérationnels se sont habitués depuis longtemps à disposer de certaines informations, que le chiffrement de la couche Transport peut rendre inutilisables. Il faudra donc changer certaines pratiques et certains outils, par exemple avec davantage de coopération des machines terminales (sinon, les opérations seront affectées).
  • Le RFC rappelle aussi qu'il existe différents types de réseaux, et qui n'ont pas forcément les mêmes contraintes et les mêmes buts. Entre le réseau d'une entreprise qui veut contrôler tout ce que font les employés et le réseau d'un FAI qui doit respecter (en théorie…) le principe de neutralité, il n'est pas du tout sûr qu'on puisse trouver des solutions qui plaisent à tout le monde. (A priori, l'IETF travaille et normalise pour l'Internet ouvert, pas forcément pour chaque réseau connecté à l'Internet avec ses règles spécifiques.)
  • L'Internet est un réseau partagé et son bon fonctionnement dépend donc du respect de certaines règles par tous. Par exemple, un protocole de transport doit penser aux autres, en ne noyant pas le réseau sous les paquets de retransmission. Si un fournisseur de logiciels était tenté de développer un protocole de transport égoïste, qui tente d'obtenir plus que sa part de la capacité du réseau, la tricherie pourrait se détecter en observant le fonctionnement de ce protocole. Le chiffrement de la couche Transport rend évidemment la vérification plus complexe.
  • Le bon fonctionnement de l'Internet sur le long terme dépend également d'une activité de recherche et développement, qui s'appuie sur des mesures, que le chiffrement de la couche Transport peut gêner. (C'est bien, de se préoccuper des chercheurs.)

Téléchargez le RFC 9065


L'article seul

RFC 8984: JSCalendar: A JSON Representation of Calendar Data

Date de publication du RFC : Juillet 2021
Auteur(s) du RFC : N. Jenkins, R. Stepanek (Fastmail)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF calext
Première rédaction de cet article le 20 juillet 2021


Beaucoup d'applications gèrent des agendas, avec des réunions à ne pas oublier, des évènements récurrents, des rendez-vous précis. Le format traditionnel d'échange de ces applications est iCalendar, normalisé dans le RFC 5545 (ou, dans sa déclinaison en JSON, jCal, dans le RFC 7265). Ce RFC propose une syntaxe JSON mais, surtout, un modèle de données très différent, JSCalendar. Le but est de remplacer iCalendar.

Les principes de base ? Simplicité (au moins dans les cas simples, car les calendriers sont des bêtes compliquées…), uniformité (autant que possible, une seule façon de représenter un évènement), tout en essayant de permettre des conversions depuis iCalendar (RFC 5545 et RFC 7986), donc en ayant un modèle de données compatible. JSCalendar, comme son nom l'indique, utilise JSON, plus exactement le sous-ensemble i-JSON, normalisé dans le RFC 7493.

Bon, mais pourquoi ne pas avoir gardé iCalendar ? Parce qu'il est trop complexe avec plusieurs formats de date, parce que ses règles de récurrence sont ambigües et difficiles à comprendre, parce que sa syntaxe est mal définie. jCal n'a pas ce dernier problème mais il garde tous les autres. On voit même des logiciels utiliser leur propre représentation en JSON des données iCalendar au lieu d'utiliser jCal. Bref, JSCalendar préfère repartir, sinon de zéro, du moins d'assez loin.

Voici un exemple très simple et très minimal de représentation d'un évènement en JSCalendar :

{
     "@type": "Event",
     "uid": "a8df6573-0474-496d-8496-033ad45d7fea",
     "updated": "2020-01-02T18:23:04Z",
     "title": "Some event",
     "start": "2020-01-15T13:00:00",
     "timeZone": "America/New_York",
     "duration": "PT1H"
}
  

Comme avec iCalendar, les données JSCalendar peuvent être échangées par courrier ou avec n'importe quel autre protocole de son choix comme JMAP ou WebDAV.

Avant d'attaquer ce format JSCalendar, rappelez-vous qu'il utilise JSON et que la terminologie est celle de JSON. Ainsi, on nomme « objet » ce qui, selon le langage utilisé, serait un dictionnaire ou un tableau associatif. Ensuite, outre les types de base de JSON, JSCalendar a des types supplémentaires (section 1), notamment :

  • Id, un identificateur, pour que les objets aient un nom simple et unique (c'est une chaîne de caractères JSON). On peut par exemple utiliser un UUID (RFC 4122). Dans l'exemple ci-dessus, le membre uid de l'objet est un Id.
  • UTCDateTime, une date-et-heure (un instant dans le temps) au format du RFC 3339 dans une chaîne de caractères JSON, est obligatoirement en UTC. Un tel type est intéressant pour les évènements internationaux comme une vidéoconférence. Dans l'exemple ci-dessus, le membre updated est de ce type.
  • LocalDateTime, une date-et-heure selon le fuseau horaire local. Un tel type est utile pour les évènements locaux, comme un pique-nique. Dans l'exemple ci-dessus, qui concerne une réunion en présentiel, start est de ce type. On a besoin des deux types, à la fois parce que les évènements en distanciel et en présentiel n'ont pas les mêmes besoins, et aussi parce que le décalage entre les deux peut varier. Les calendriers, c'est compliqué et le RFC cite l'exemple de la LocalDateTime 2020-10-04T02:30:00 qui n'existe pas à Melbourne car le passage à l'heure d'été fait qu'on saute de 2h à 3h, mais qui peut apparaitre dans les calculs (start + une durée) ou bien si les règles de l'heure d'été changent.
  • Duration est une durée, exprimée comme en iCalendar (PT1H pour « une heure » dans l'exemple ci-dessus, ce serait P1Y pour une année). Gag : une journée (P1D) ne fait pas forcément 24 heures, par exemple si on passe à l'heure d'été pendant cette journée.
  • SignedDuration, une durée qui peut être négative.
  • TimeZoneId, un identifiant pour un fuseau horaire, pris dans la base de l'IANA, par exemple Europe/Paris.
  • PatchObject est un pointeur JSON (ces pointeurs sont normalisés dans le RFC 6901) qui permet de désigner un objet à modifier.
  • Relation est un objet, et plus un simple type scalaire comme les précédents. Il permet d'indiquer une relation entre deux objets, notamment vers un objet parent ou enfant..
  • Link est également une relation et donc un objet, mais vers le monde extérieur. Il a des propriétés comme href (dont la valeur est, comme vous vous en doutez, un URI) ou cid qui identifie le contenu vers lequel on pointe, dans la syntaxe du RFC 2392.

Les types de JSCalendar figurent dans un registre IANA, qu'on peut remplir avec la procédure « Examen par un expert » du RFC 8126.

Bien, maintenant que nous avons tous nos types, construisons des objets. Il y en a de trois types (section 2) :

  • Event (l'exemple ci-dessus, regardez sa propriété @type) est un évènement ponctuel, par exemple une réunion professionnelle ou une manifestation de rue. Il a une date-et-heure de départ, et une durée.
  • Task est une tâche à accomplir, elle peut avoir une date-et-heure limite et peut avoir une durée estimée.
  • Group est un groupe d'évènements JSCalendar.

JSCalendar n'a pas de règles de canonicalisation (normalisation) générales, car cela dépend trop de considérations sémantiques que le format ne peut pas connaitre. Par exemple, JSON permet des tableaux, et JSCalendar utilise cette possibilité mais, quand on veut décider si deux tableaux sont équivalents, doit-on tenir compte de l'ordre des éléments ([1, 2] == [2, 1]) ? Cela dépend de l'application et JSCalendar ne fixe donc pas de règles pour ce cas. (Un cas rigolo et encore pire est celui des valeurs qui sont des URI puisque la canonicalisation des URI dépend du plan - scheme.)

Quelles sont les propriétés typiques des objets JSCalendar (section 4) ? On trouve notamment, communs aux trois types d'objets (évènement, tâche et groupe) :

  • @type, le type d'objet (Event dans l'exemple ci-dessus, un des trois types possibles).
  • uid (a8df6573-0474-496d-8496-033ad45d7fea dans l'exemple), l'identificateur de l'objet (il est recommandé que ce soit un des UUID du RFC 4122).
  • prodID, un identificateur du logiciel utilisé, un peu comme le User-Agent: de HTTP. Le RFC suggère d'utiliser un FPI.
  • updated, une date-et-heure de type UTCDateTime.
  • title et description, des chaînes de caractères utiles.
  • locations (notez le S) qui désigne les lieux physiques de l'évènement. C'est compliqué. Chaque lieu est un objet de type Location qui a comme propriétés possibles un type (tiré du registre des types de lieux créé par le RFC 4589), et une localisation sous forme de latitude et longitude (RFC 5870).
  • Tous les évènements ne sont pas dans le monde physique, certains se produisent en ligne, d'où le virtualLocations, qui indique des informations comme l'URI (via la propriété du même nom). Ainsi, une conférence en ligne organisée par l'assocation Parinux via BigBlueButton aura comme virtualLocations {"@type": "VirtualLocation", "uri": "https://bbb.parinux.org/b/ca--xgc-4r3-n8z", …}.
  • color permet de suggérer au logiciel une couleur à utiliser pour l'affichage, qui est une valeur RGB en hexadécimal ou bien un nom de couleur CSS.

Et je suis loin d'avoir cité toutes les propriétés possibles, sans compter celles spécifiques à un type d'objet.

Pour le cas de locations, le RFC fournit un exemple de vol international (quand il était encore possible de prendre l'avion) :

   {
     "...": "",
     "title": "Flight XY51 to Tokyo",
     "start": "2020-04-01T09:00:00",
     "timeZone": "Europe/Berlin",
     "duration": "PT10H30M",
     "locations": {
       "418d0b9b-b656-4b3c-909f-5b149ca779c9": {
         "@type": "Location",
         "rel": "start",
         "name": "Frankfurt Airport (FRA)"
       },
       "c2c7ac67-dc13-411e-a7d4-0780fb61fb08": {
         "@type": "Location",
         "rel": "end",
         "name": "Narita International Airport (NRT)",
         "timeZone": "Asia/Tokyo"
       }
     }
   }
  

Notez les UUID pour identifier les lieux, et le changement de fuseau horaire entre le départ et l'arrivée. Si l'évènement a lieu à la fois en présentiel et en distanciel (ici, le concert est dans un lieu physique identifié par ses coordonnées géographiques, mais aussi diffusé en ligne), cela peut donner :

{
  "...": "",
  "title": "Live from Music Bowl: The Band",
  "description": "Go see the biggest music event ever!",
  "locale": "en",
  "start": "2020-07-04T17:00:00",
  "timeZone": "America/New_York",
  "duration": "PT3H",
  "locations": {
    "c0503d30-8c50-4372-87b5-7657e8e0fedd": {
      "@type": "Location",
      "name": "The Music Bowl",
      "description": "Music Bowl, Central Park, New York",
      "coordinates": "geo:40.7829,-73.9654"
    }
  },
  "virtualLocations": {
    "1": {
      "@type": "VirtualLocation",
      "name": "Free live Stream from Music Bowl",
      "uri": "https://stream.example.com/the_band_2020"
    }
    },
    ...
  

Les fournisseurs de logiciel peuvent ajouter des propriétés définies par eux. Dans ce cas, le RFC recommande fortement qu'ils les nomment en les faisant précéder d'un nom de domaine identifiant le fournisseur. Si celui-ci a example.com et veut une propriété toto, il la nommera example.com:toto. C'est évidemment une solution temporaire, les fournisseurs ont tout intérêt à enregistrer ces propriétés pour qu'elles puissent servir à tout le monde. Le mécanisme d'enregistrement de nouvelles propriétés est « Examen par un expert » (RFC 8126) et les propriétés sont dans un registre IANA.

Passons maintenant à un aspect compliqué mais indispensable des calendriers : les règles de récurrence, comme « Réunion de service tous les premiers lundis du mois à 10 h, sauf jour férié ». Il est important de maintenir ces évènements récurrents sous forme de règles, et de ne pas de les instancier immédiatement, car l'application des règles peut donner des résultats différents dans le futur. JSCalendar permet une propriété recurrenceRules qui décrit ces règles de récurrence et évidemment une excludedRecurrenceRules car s'il n'y a pas d'exceptions, ce n'est pas drôle. Exprimer les règles n'est pas facile. L'idée est de spécifier la récurrence sous forme d'une série de règles, chacune indiquant une fréquence (annuelle, mensuelle, etc), à chaque fois à partir de la propriété start, le calendrier utilisé (qui doit être un des calendriers disponibles dans CLDR), la marche à suivre quand une règle produit une date invalide dans ce calendrier (annuler l'évènement, le mettre avant, le mettre après), et plein d'autres propriétés optionnelles comme le jour du mois (« réunion tous les 6 du mois »), de la semaine (« tous les mercredis »), etc. Il faut ensuite plusieurs pages au RFC pour expliquer la façon subtile dont les règles sont appliquées, et se combinent. Les exceptions de la excludedRecurrenceRules fonctionnent de la même façon, et sont ensuite soustraites des dates-et-heures sélectionnées par les règles.

Le RFC fournit cet exemple de récurrence : le premier avril arrive tous les ans (et dure une journée, notez le duration) :

    {
     "...": "",
     "title": "April Fool's Day",
     "showWithoutTime": true,
     "start": "1900-04-01T00:00:00",
     "duration": "P1D",
     "recurrenceRules": [{
       "@type": "RecurrenceRule",
       "frequency": "yearly"
     }]
   }
  

Alors qu'ici, on fait du yoga une demi-heure chaque jour à 7 h du matin :

   {
     "...": "",
     "title": "Yoga",
     "start": "2020-01-01T07:00:00",
     "duration": "PT30M",
     "recurrenceRules": [{
       "@type": "RecurrenceRule",
       "frequency": "daily"
     }]
   }
  

Bon, ensuite, quelques détails pour aider le logiciel à classer et présenter les évènements. Un évènement peut avoir des propriétés comme priority (s'il y a deux réunions en même temps, laquelle choisir ?), freeBusyStatus (est-ce que cet évènement fait que je doive être considéré comme occupé ou est-il compatible avec autre chose ?), privacy (cet évènement peut-il être affiché publiquement ?), participationStatus (je viendrai, je ne viendrai pas, je ne sais pas encore…), et plein d'autres encore.

Il y a aussi des propriétés concernant d'autres sujets, par exemple l'adaptation locale. Ainsi, la propriété localizations indique la ou les langues à utiliser (leur valeur est une étiquette de langue du RFC 5646).

Toutes les propriétés vues jusqu'à présent étaient possibles pour tous les types d'objets JSCalendar (évènement, tâche et groupe). D'autres propriétés sont spécifiques à un ou deux types :

  • Les évènements (Event) peuvent avoir entre autres un start (un LocalDateTime qui indique le début de l'évènement) et un duration (la durée de l'évènement).
  • Les tâches (Task) peuvent avoir un start mais aussi un due qui indique la date où elles doivent être terminées, et un percentComplete (pour les chefs de projet…).
  • Les groupes (Group) ont, par exemple, entries, qui indique les objets qui sont membres du groupe.

Les fichiers à ce format JSCalendar sont servis sur l'Internet avec le type application/jscalendar+json.

Pour terminer, voyons un peu la sécurité de JSCalendar (section 7). Évidemment, toutes les informations stockées dans un calendrier sont sensibles : rares sont les personnes qui accepteraient de voir la totalité de leur agenda être publiée ! Celui-ci permet en effet de connaitre le graphe social (les gens qu'on connait), les lieux où passe la personne, ses habitudes et horaires, bref, que des choses personnelles. Toute application qui manipule des données JSCalendar doit donc soigneusement veiller à la confidentialité de ces données, et doit les protéger.

Le risque d'accès en lecture n'est pas le seul, la modification non autorisée de l'agenda serait également un problème, elle pourrait permettre, par exemple, de faire déplacer une personne en un lieu donné. D'autres conséquences d'une modification pourraient toucher la facturation (location d'une salle pendant une certaine durée) ou d'autres questions de sécurité (activer ou désactiver une alarme à certains moments). L'application qui manie du JSCalendar doit donc également empêcher ces changements non autorisés.

Notez que ces problèmes de sécurité ne concernent pas le format à proprement parler, mais les applications qui utilisent ce format. Rien dans JSCalendar, dans ce RFC, ne le rend particulièrement vulnérable ou au contraire protégé, tout est dans l'application.

Les règles de récurrence sont complexes et, comme tout programme, elles peuvent entrainer des conséquences imprévues, avec consommation de ressources informatiques associées. Un exemple aussi simple que la session de yoga quotidienne citée plus haut pourrait générer une infinité d'évènements, si elle était mise en œuvre par une répétition systématique, jusqu'à la fin des temps. Les programmes doivent donc faire attention lorsqu'ils évaluent les règles de récurrence.

L'un des buts d'un format standard d'évènements est évidemment l'échange de données. Il est donc normal et attendu qu'une application de gestion d'agenda reçoive des objets JSCalendar de l'extérieur, notamment via l'Internet. On voit souvent du iCalendar en pièce jointe d'un courrier, par exemple. Il ne faut pas faire une confiance aveugle à ces données venues d'on ne sait où, et ne pas tout intégrer dans le calendrier du propriétaire. L'authentification du courrier (par exemple avec DKIM, RFC 6376) aide un peu, mais n'est pas suffisante.

Les fuseaux horaires sont une source de confusion sans fin. Un utilisateur qui n'est pas attentif, lorsqu'on lui dit qu'un évènement a lieu à 10h30 (UTC-5) peut croire que c'est 10h30 de son fuseau horaire à lui. (Et encore, ici, j'ai indiqué le fuseau horaire de manière lisible, contrairement à ce que font la plupart des Étatsuniens, qui utilisent leurs sigles à eux comme PST, ou ce que font les Français qui n'indiquent pas le fuseau horaire, persuadés qu'ils sont que le monde entier est à l'heure de Paris.) Cette confusion peut être exploitée par des méchants qui utiliseraient les fuseaux horaires de manière délibérement peu claire pour tromper quelqu'un sur l'heure d'un évènement. (Dans la série Mad Men, les hommes qui ne supportent pas l'arrivée d'une femme dans le groupe lui donnent des informations trompeuses sur les heures de réunion, pour qu'elle manque ces évènements.)

Où trouve-t-on du JSCalendar à l'heure actuelle ? Mobilizon ne l'a pas encore (l'action « Ajouter à mon agenda » exporte du iCalendar). Fastmail annonce qu'ils gèrent JSCalendar (mais apparemment seulement dans les échanges JMAP, pas avec l'import/export normal). Cyrus l'a aussi (si vous avez des détails, ça m'intéresse). Pour le cas des récurrences, vous avez une intéressante mise en œuvre en Python. Attention, il y a aussi plein de logiciels qui s'appellent « jscalendar » (notamment des widgets JavaScript pour afficher un calendrier dans un formulaire Web) mais qui n'ont aucun rapport avec ce RFC.


Téléchargez le RFC 8984


L'article seul

RFC 9063: Host Identity Protocol Architecture

Date de publication du RFC : Juillet 2021
Auteur(s) du RFC : R. Moskowitz (HTT Consulting), M. Komu (Ericsson)
Pour information
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 15 juillet 2021


Ce RFC propose d'aborder l'architecture de l'Internet en utilisant un nouveau type d'identificateur, le Host Identifier (HI), pour beaucoup d'usages qui sont actuellement ceux des adresses IP. Il remplace le RFC 4423, qui était la description originale du protocole HIP, mais il n'y a pas de changements fondamentaux. HIP était un projet très ambitieux mais, malgré ses qualités, la disponibilité de plusieurs mises en œuvre, et des années d'expérimentation, il n'a pas percé.

Une adresse IP sert actuellement à deux choses : désigner une machine (l'adresse IP sert par exemple à distinguer plusieurs connexions en cours) et indiquer comment la joindre (routabilité). Dans le premier rôle, il est souhaitable que l'adresse soit relativement permanente, y compris en cas de changement de FAI ou de mobilité (actuellement, si une machine se déplace et change d'adresse IP, les connexions TCP en cours sont cassées). Dans le second cas, on souhaite au contraire une adresse qui soit le plus « physique » possible, le plus dépendante de la topologie. Ces deux demandes sont contradictoires.

HIP résout le problème en séparant les deux fonctions. Avec HIP, l'adresse IP ne serait plus qu'un identifiant « technique », ne servant qu'à joindre la machine, largement invisible à l'utilisateur et aux applications (un peu comme une adresse MAC aujourd'hui). Chaque machine aurait un HI (Host Identifier) unique. Contrairement aux adresses IP, il n'y a qu'un HI par machine multi-homée mais on peut avoir plusieurs HI pour une machine si cela correspond à des usages différents, par exemple une identité publique, et une « anonyme ».

Pour pouvoir être vérifié, le nouvel identificateur, le HI sera (dans la plupart des cas) une clé publique cryptographique, qui sera peut-être allouée hiérarchiquement par PKI ou plutôt de manière répartie par tirage au sort (comme le sont les clés SSH ou PGP aujourd'hui, ce qui serait préférable, question vie privée). Ces identificateurs fondés sur la cryptographie permettent l'authentification réciproque des machines (contrairement à IP, où il est trivial de mentir sur son adresse), et d'utiliser ensuite IPsec (RFC 7402) pour chiffrer la communication (HIP n'impose pas IPsec, plusieurs encapsulations des données sont possibles, et négociées dynamiquement, mais, en pratique, la plupart des usages prévus reposent sur IPsec).

L'authentification permet d'être sûr du HI de la machine avec qui on parle et, si le HI était connu préalablement à partir d'une source de confiance, d'être sûr qu'on parle bien à l'interlocuteur souhaité. (Si on ne connait pas le HI à l'avance, on dit que HIP est en mode « opportuniste ».)

Cette séparation de l'identificateur et du localisateur est un sujet de recherche commun et d'autres propositions que HIP existent, comme LISP (RFC 6830) ou ILNP (RFC 6740). Dans tous les cas, les couches supérieures (comme TCP) ne verront que l'identificateur, permettant au localisateur de changer sans casser les sessions de transport en cours. (Un mécanisme ressemblant est le Back to My Mac du RFC 6281.) L'annexe A.1 de notre RFC rappelle les avantages de cette approche. Et l'annexe A.2, lecture très recommandée, note également ses défauts, l'indirection supplémentaire ajoutée n'est pas gratuite, et entraine des nouveaux problèmes. Notamment, il faut créer un système de correspondance - mapping - entre les deux, système qui complexifie le projet. Il y a aussi la latence supplémentaire due au protocole d'échange initial, qui est plus riche. Comparez cette honnêteté avec les propositions plus ou moins pipeau de « refaire l'Internet en partant de zéro », qui ne listent jamais les limites et les problèmes de leurs solutions miracle.

Ce HI (Host Identifier) pourra être stocké dans des annuaires publics, comme le DNS (RFC 8005), ou une DHT (RFC 6537), pour permettre le rendez-vous (RFC 8004) entre les machines.

Notez que ce n'est pas directement le Host Identifier, qui peut être très long, qui sera utilisé dans les paquets IP, mais un condensat, le HIT (Host Identity Tag).

HIP intègre les leçons de l'expérience avec IP, notamment de l'importance d'authentifier la machine avec qui on parle. C'est ce qui est fait dans l'échange initial qui permet à un initiateur et un répondeur de se mettre à communiquer. Notamment, il y a obligation de résoudre un puzzle cryptographique, pour rendre plus difficile certaines attaques par déni de service. Voir à ce sujet « DOS-Resistant Authentication with Client Puzzles » de Tuomas Aura, Pekka Nikander et Jussipekka Leiwo, « Deamplification of DoS Attacks via Puzzles » de Jacob Beal et Tim Shepard ou encore « Examining the DOS Resistance of HIP » de Tritilanunt, Suratose, Boyd, Colin A., Foo, Ernest, et Nieto, Juan Gonzalez.

La sécurité est un aspect important de HIP. Les points à garder en tête sont :

  • Protection contre certaines attaques par déni de service via le puzzle cryptographique à résoudre.
  • Protection contre les attaques de l'homme du milieu si le HI a été obtenu par un mécanisme sûr. Cela ne marche évidemment pas en mode opportuniste, où l'initiateur ne connait pas le HI de son correspondant, et le découvre une fois la connexion faite.
  • Le mode opportuniste peut être renforcé, question sécurité, par le TOFU (RFC 7435).
  • Tout mécanisme de séparation de l'identificateur et du localisateur ouvre de nouveaux problèmes : que se passe-t-il si le correspondant ment sur son localisateur ? Est-ce que cela permet des attaques par réflexion ? C'est pour éviter cela que les systèmes à séparation de l'identificateur et du localisateur prévoient, comme HIP, un test de l'existence d'une voie de retour (Cf. RFC 4225).
  • Enfin, on peut évidemment mettre des ACL sur des HI mais leur structure « plate » fait qu'il n'y a pas d'agrégation possible de ces ACL (il faut une ACL par machine avec qui on correspond).

Au sujet du TOFU, le RFC cite «  Leap-of-faith security is enough for IP mobility » de Miika Kari Tapio Komu et Janne Lindqvist, « Security Analysis of Leap-of-Faith Protocols » de Viet Pham et Tuomas Aura et « Enterprise Network Packet Filtering for Mobile Cryptographic Identities » de Janne Lindqvist, Essi Vehmersalo, Miika Komu et Jukka Manner.

Notre RFC ne décrit qu'une architecture générale, il est complété par les RFC 7401, qui décrit le protocole, RFC 7402, RFC 8003, RFC 8004, RFC 8005, RFC 8046 et RFC 5207. Si des implémentations expérimentales existent déjà et que des serveurs publics utilisent HIP, aucun déploiement significatif n'a eu lieu (cf. l'article « Adoption barriers of network layer protocols: The case of host identity protocol de T. Leva, M. Komu, A. Keranen et S. Luukkainen). Comme le disait un des relecteurs du RFC, « There's a lot of valuable protocol design and deployment experience packed into this architecture and the associated protocol RFCs. At the same time, actual adoption and deployment of HIP so far appears to have been scarce. I don't find this surprising. The existing Internet network/transport/application protocol stack has already become sufficiently complicated that considerable expertise is required to manage it in all but the simplest of cases. Teams of skilled engineers routinely spend hours or days troubleshooting operational problems that crop up within or between the existing layers, and the collection of extensions, workarounds, identifiers, knobs, and failure cases continues to grow. Adding a major new layer--and a fairly complicated one at that--right in the middle of the existing stack seems likely to explode the already heavily-strained operational complexity budget of production deployments. ». L'annexe A.3 décrit les questions pratiques liées au déploiement. Elle rappelle le compte-rendu d'expérience chez Boeing de Richard Paine dans son livre « Beyond HIP: The End to Hacking As We Know It ». Elle tord le cou à certaines légendes répandues (que HIP ne fonctionne pas à travers les routeurs NAT, ou bien qu'il faut le mettre en œuvre uniquement dans le noyau.)

Ah, question implémentations (RFC 6538), on a au moins HIP for Linux et OpenHIP qui ont été adaptés aux dernières versions de HIP, et des protocoles associés.

Les changements depuis le RFC 4423 sont résumés en section 14. Il n'y en a pas beaucoup, à part l'intégration de l'expérience, acquise dans les treize dernières années (et résumée dans le RFC 6538) et des améliorations du texte. La nouvelle annexe A rassemble plein d'informations concrètes, notamment que les questions pratiques de déploiement de HIP, et sa lecture est très recommandée à tous ceux et toutes celles qui s'intéressent à la conception de protocoles. La question de l'agilité cryptographique (RFC 7696) a également été détaillée.


Téléchargez le RFC 9063


L'article seul

Récupérer la date d'expiration d'un domaine en RDAP

Première rédaction de cet article le 4 juillet 2021
Dernière mise à jour le 7 juillet 2021


C'est dimanche, il ne fait pas beau, pas question de pique-nique, on va donc faire un peu de JSON. Un des problèmes les plus courants avec les noms de domaine est l'expiration accidentelle du nom. « Nous avons oublié de le renouveler » et paf plus rien ne marche. Pourtant, la date à laquelle le domaine expire est publiquement annoncée, via des protocoles comme whois ou RDAP. Comment utiliser RDAP pour récupérer cette date dans un programme, par exemple un programme d'alerte qui préviendra si l'expiration approche ?

Un peu de contexte d'abord ; un certain nombre (mais pas tous) de registres de noms de domaine exigent un renouvellement périodique du nom, avec paiement et parfois acceptation de nouvelles conditions. L'oubli de ce renouvellement est un gag très fréquent. On ne paie pas, et, à la date d'expiration, le domaine disparait ou bien est mis en attente, plus publié dans le DNS, ce qui fait que tous les services associés cessent de fonctionner. Dans le premier cas, le pire, le domaine a été supprimé, et un autre peut l'enregistrer rapidement. Il est donc crucial de ne pas laisser le domaine expirer. Un des outils indispensables quand on gère un domaine important est donc une supervision automatique de l'approche de l'expiration. L'information est diffusée par le registre, via plusieurs protocoles. Le traditionnel whois, normalisé dans le RFC 3912 a plusieurs inconvénients notamment le fait que le format de sortie n'est pas normalisé. Il est donc difficile d'écrire un programme qui analyse l'information retournée (il existe quand même des solutions comme, en Perl, Net::DRI). Au contraire, le plus moderne RDAP a un format de sortie normalisé (dans le RFC 9083). Utilisons-le, en prenant comme exemple le domaine de ce blog, bortzmeyer.org.

RDAP utilise HTTPS et produit du JSON (RFC 8259). D'autre part, pour interroger le bon serveur RDAP (celui du registre), il faut connaitre son nom, ce qui se trouve dans un registre IANA qui associe le TLD à son serveur RDAP. On apprend ainsi que les informations concernant .org sont à demander à https://rdap.publicinterestregistry.net/rdap/org/. Utilisant le RFC 9082 pour former une requête RDAP correcte, on va utiliser curl pour poser la question sur bortzmeyer.org :

% curl -s https://rdap.publicinterestregistry.net/rdap/org/domain/bortzmeyer.org
  

On récupère un gros JSON compliqué, que je ne vous montre pas ici. On veut juste la date d'expiration du domaine. On va se servir pour cela de l'excellent outil jq :

% curl -s https://rdap.publicinterestregistry.net/rdap/org/domain/bortzmeyer.org | \
       jq '.events | map(select(.eventAction == "expiration"))[0] | .eventDate' 
"2021-08-29T09:32:04.304Z"
  

OK, j'ai triché, ça m'a pris plus de quelques secondes pour écrire le programme jq qui extrait cette information, et j'ai dû vérifier dans le RFC 9083. Expliquons donc.

Partons du haut de l'objet JSON retourné. Il contient un membre nommé events (RFC 9083, section 4.5) qui indique les évènements passés ou futurs pertinents, comme la création du domaine ou comme sa future expiration. On doit donc commencer par demander au programme jq de filtrer sur ce membre, d'où le .events au début. Ensuite, on veut ne garder, parmi les évènements, que l'expiration. On applique donc (map) un test (.eventAction == "expiration") à chaque élement du tableau events et on ne garde (select) que celui qui nous intéresse. Oui, « celui » et pas « ceux » car il n'y a normalement qu'un évènement d'expiration, donc on ne garde que le premier élement ([0]) du tableau produit. Ce premier élément, comme tous ceux qui composent le tableau events est un évènement (RFC 9083, section 4.5), un objet qui a ici deux membres, eventAction, son type (celui sur lequel on filtre, avec .eventAction == "expiration" et eventDate, l'information qu'on recherche. On termine donc par un filtre du seul eventDate, date qui est au format du RFC 3339. Et voilà. On peut ensuite traiter cette date comme on veut. Par exemple, le programme GNU date peut vous traduire cette date en secondes écoulées depuis l'epoch :

% date --date=$(curl -s https://rdap.publicinterestregistry.net/rdap/org/domain/bortzmeyer.org | \
                jq -r '.events | map(select(.eventAction== "expiration"))[0] | .eventDate') \
    +%s 
1630229524
  

Abandonnons maintenant curl et jq pour un programme écrit en Python. On utilise la bibliothèque Requests pour faire du HTTPS et les bibliothèques standard incluses dans Python pour faire du JSON, du calcul sur les dates, etc. Récupérer le JSON est simple :

response = requests.get("%s/%s" % (SERVER, domain))
if response.status_code != 200:
    raise Exception("Invalid RDAP return code: %s" % response.status_code)
  

Le transformer en un dictionnaire Python également :

rdap = json.loads(response.content)
  

On va ensuite y chercher la date d'expiration, qu'on transforme en une belle date-et-heure Python sur laquelle il sera facile de faire des calculs :

for event in rdap["events"]:
    if event["eventAction"] == "expiration":
        expiration = datetime.datetime.strptime(event["eventDate"], RFC3339)
        now = datetime.datetime.utcnow()
        rest = expiration-now
  

Et on peut ensuite mettre les traitements qu'on veut, ici prévenir si l'expiration approche :


if rest < CRITICAL:
            print("CRITICAL: domain %s expires in %s, HURRY UP!!!" % (domain, rest))
            sys.exit(2)
elif rest < WARNING:
            print("WARNING: domain %s expires in %s, renew now" % (domain, rest))
            sys.exit(1)
else:
            print("OK: domain %s expires in %s" % (domain, rest))
            sys.exit(0)

  

Le code complet est disponible (il faut aussi ce module). Notez qu'il n'est pas tellement robuste, il faudrait prévoir davantage de traitement d'erreur. Python fait toutefois en sorte que la plupart des erreurs soient détectées automatiquement (par exemple s'il n'existe pas de membre events dans le résultat) donc, au moins, vous n'aurez pas de résultats erronés. Et puis, par rapport au programme curl+jq plus haut, un grand avantage de ce programme Python est qu'il utilise le registre IANA des serveurs (décrit dans le RFC 7484) et qu'il trouve donc tout seul le serveur RDAP :

% ./expiration-rdap.py bortzmeyer.org                   
OK: domain bortzmeyer.org expires in 55 days, 18:54:01.281920

% ./expiration-rdap.py quimper.bzh
WARNING: domain quimper.bzh expires in 6 days, 18:17:25.919080, renew now
  

Une version plus élaborée de ce programme Python, utilisable depuis des logiciels de supervision automatique comme Nagios, Icinga ou Zabbix est disponible.

Notez qu'un tel outil n'est qu'un élément parmi tout ce qu'il faut faire pour bien gérer l'éventuelle expiration de votre domaine. Il faut aussi mettre les dates de renouvellement dans votre agenda, il est recommandé d'activer l'auto-renouvellement ou, mieux, chez les registres qui le permettent, de louer pour plusieurs années. Je vous recommande également la lecture du « Guide du Titulaire Afnic » ou des « Bonnes pratiques pour l'acquisition et l'exploitation de noms de domaine de l'ANSSI ».


L'article seul

RFC 9039: Uniform Resource Names for Device Identifiers

Date de publication du RFC : Juin 2021
Auteur(s) du RFC : J. Arkko (Ericsson), C. Jennings (Cisco), Z. Shelby (ARM)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF core
Première rédaction de cet article le 1 juillet 2021


Voici un nouvel espace de noms pour des URN, dev, afin de stocker des identificateurs pour des équipements matériels, par exemple pour les inventaires.

Les URN, un sous-ensemble des URI, et des cousins des URL, sont normalisés dans le RFC 8141. On peut placer des URN partout où on peut mettre des URI, par exemple comme noms dans SenML (RFC 8428). Pour des objets contraints, les URN risquent d'être un peu longs par rapport à, par exemple, une adresse IPv4, mais ils sont plus souples. Un URN commence par le plan urn:, suivie d'un espace de noms. Ces espaces sont stockés dans un registre IANA. Ce nouveau RFC crée un nouvel espace de noms, dev. On pourra donc désormais avec des URN comme urn:dev:os:32473-123456 (qui identifie la machine 123456 de l'organisation 32473). Ces identificateurs de machines pourront être utilisés toutes les fois où on a besoin de désigner une machine, dans les données du RFC 8428, dans des inventaires, etc.

Passons au concret maintenant, avec la section 3 du RFC, qui donne la définition formelle de l'espace de noms dev. Ces URN sont évidemment conformes à la norme des URN, le RFC 8141. Comme tous les URN, ceux sous urn:dev: ne sont pas prévus pour être résolus automatiquement. Contrairement aux URL, ils ne fournissent pas de moyen d'accès à une ressource. Bien sûr, si on les met dans une base de données, d'inventaire de ses machines, par exemple, on pourra retrouver l'information, mais ce RFC ne spécifie aucun mécanisme de résolution standard (section 3.6 du RFC).

Après le urn:dev:, ces URN prennent un composant supplémentaire, qui identifie le type d'identificateur dont dérive l'URN. Cela peut être :

  • mac, où l'identificateur est une adresse MAC, enregistrée selon les procédures IEEE, au format EUI-64. C'est par exemple urn:dev:mac:acde48234567019f (pour l'adresse MAC ac:de:48:23:45:67:01:9f). Si vous faites varier l'adresse MAC, par exemple pour protéger votre vie privée, l'URN n'est plus un identifiant stable.
  • ow, qui s'appuie sur 1-Wire, un système privateur.
  • org, avec des identificateurs spécifiques à une organisation, identifiée par son PEN (les PEN sont normalisés dans le RFC 2578). Les PEN sont enregistrés à l'IANA. Prenons comme exemple celui d'une entreprise dont j'étais un co-fondateur, 9319. Si cette entreprise utilise des noms pour ses machines, la machine marx aurait comme URN urn:dev:org:9319-marx.
  • os, comme les org mais plutôt prévus pour des numéros de série. Si cette entreprise numérote toutes ses machines en partant de 1, un URN serait urn:dev:os:9319-1. (Notez que des versions précédentes des URN dev utilisaient os pour les identificateurs LwM2M.) Ainsi, le RIPE-NCC qui a le PEN 15854 pourrait nommer ses sondes Atlas d'après leur numéro unique et donc la sonde 6593 pourrait être désignée par urn:dev:os:15854-6593. Notez qu'on pourrait avoir ici une intéressante discussion sur l'intérêt respectif des URN (urn:dev:os:15854-6593) et des URL (https://atlas.ripe.net/probes/6593/).
  • ops, qui ressemble à l'os, mais avec un identificateur de produit entre le PEN et le numéro de série, par exemple urn:dev:ops:9319-coffeemachine-2 pour la deuxième machine à café de l'organisation. (Comme os, il avait été utilisé pour l'Open Mobile Alliance.)
  • Un autre type, qui sera défini dans le futur (cf. section 7 du RFC). En attendant, on peut utiliser example pour des exemples, comme urn:dev:example:1234.

Enfin, une machine identifiée par un de ces URN peut avoir une partie particulière de la machine désignée par une chaine de caractères après un tiret bas. Ainsi, urn:dev:os:9319-1_alimentation serait l'alimentation de la machine urn:dev:os:9319-1.

Notez que l'équivalence de deux URN est sensible à la casse donc attention, par exemple, à la façon dont vous écrivez les adresses MAC. Le RFC recommande de tout mettre en minuscules.

Idéalement, on veut bien sûr qu'un URN dev identifie une machine et une seule. Mais, en pratique, cela peut dépendre du type d'identificateurs utilisé. Ainsi, les adresses MAC ne sont pas forcément uniques, entre autres parce que certains fabricants ont déjà réutilisé des adresses.

Petit avertissement sur la vie privée : les identificateurs décrits dans ce RFC sont prévus pour être très stables sur le long terme (évidemment, puisque leur but est de garder trace d'une machine) et leur utilisation imprudente (par exemple si on envoie un de ces URN avec les données d'un utilisateur anonyme) peut permettre une surveillance accrue (sections 3.4 et 6.1 du RFC). Le RFC 7721 détaille les risques de ces identificateurs à longue durée de vie.

Le RFC note (section 1) qu'il existe d'autres catégories d'identificateurs qui, selon le cas, pourraient concurrencer nos URN de l'espace de noms dev. C'est le cas par exemple des condensats du RFC 6920, des IMEI du RFC 7254, des MEID du RFC 8464 et bien sûr des UUID du RFC 4122. Tous peuvent se représenter sous forme d'URI, et parfois d'URN. Ils ont leurs avantages et leurs inconvénients, le choix est vaste.

Pour les gens qui utiisent le SGBD PostgreSQL, notez qu'il n'a pas de type de données « URI » donc, si on veut stocker les URN de notre RFC dans PostgreSQL, il faut utiliser le type TEXT, ou bien installer une extension comme pguri. Selon ce qu'on veut faire de ces URN, on peut aussi prendre une solution plus simple qui ne nécessite pas d'installer d'extension, ici pour une organisation qui met toutes ces machines en urn:dev:os:9319-… :

CREATE DOMAIN urndev AS text CHECK (VALUE ~ '^urn:dev:os:9319-[0-9]+(_[a-z0-9]+)?$');
COMMENT ON DOMAIN urndev IS 'URN DEV (RFC 9039) for our devices';
CREATE TABLE Devices (id SERIAL, urn urndev UNIQUE NOT NULL, comments TEXT);
INSERT INTO Devices (urn, comments) VALUES ('urn:dev:os:9319-2', 'No comment');
INSERT INTO Devices (urn) VALUES ('urn:dev:os:9319-1_alimentation');
INSERT INTO Devices (urn, comments) VALUES ('urn:dev:os:9319-666', 'Beast');
  

Téléchargez le RFC 9039


L'article seul

Une « monnaie numérique de banque centrale », c'est quoi ?

Première rédaction de cet article le 27 juin 2021


Dès qu'il s'agit de monnaie, on lit n'importe quoi dans les médias, et on entend n'importe quoi aux tribunes des colloques. Songeons par exemple à tous les gens qui ont péroré sur le Bitcoin ou sur les cryptomonnaies sans rien y connaitre. De même quand on parle de « monnaie numérique de banque centrale », la confusion règne. Notons donc un excellent article d'analyse écrit pour la banque centrale suisse (mais qui n'exprime pas la politique officielle de cette institution) expliquant à quoi pourrait ressembler une MNBC (monnaie numérique de banque centrale) et proposant une solution spécifique.

Lorsqu'on parle de « monnaie électronique » (ou numérique), la confusion règne. Parfois, le terme désigne toute monnaie qui n'est pas en pièces ou en billets (à ce compte, toutes les monnaies sont électroniques depuis longtemps). Parfois, on ne le dit que pour les cryptomonnaies ou que pour celles qui tournent sur une chaine de blocs. Ici, on va utiliser le terme pour une monnaie qui a certaines propriétés de l'argent liquide (notamment une certaine protection de la vie privée) tout en étant entièrement numérique. Ainsi, la carte Visa n'entre pas dans cette définition, car elle n'offre aucune vie privée.

L'article dont je parlais au début est « Comment émettre une monnaie numérique de banque centrale ». Oui, l'avantage des études faites pour un organisme officiel suisse, c'est qu'il y a une traduction de qualité en français. Ses auteurs sont David Chaum (celui de DigiCash), Christian Grothoff (celui de GNUnet) et Thomas Moser, des gens qui connaissent leur sujet, donc.

Pour résumer leur article (mais je vous en recommande la lecture complète), leur cahier des charges est celui d'une monnaie émise et gérée par une banque centrale (un cahier des charges, donc, très différent de celui du Bitcoin, qui vise à se passer de banque centrale), garantissant un minimum d'anonymat pour ceux qui paient avec cette monnaie (« la préservation d’une propriété clé de la monnaie physique: la confidentialité des transactions »), mais pas pour ceux qui la reçoivent. Les revenus des commerçants ne sont donc pas dissimulés, ce qui permet de lutter contre la fraude fiscale. La définition même de monnaie ne fait pas consensus mais les auteurs se focalisent sur un rôle, le moyen d'échange (il y en a d'autres rôles à la monnaie, par exemple unité de mesure ou stockage de valeur). De plus, les auteurs veulent appliquer les principes de KYC (connaissance du client), d'AML (lutte contre le blanchiment) et de CFT (lutte contre le financement du terrorisme), oui, il y en a, des sigles, dans le secteur bancaire. On voit que les objectifs mis en avant sont distincts de ceux de Bitcoin et, a fortiori, de Zcash puisque que, comme le note l'article, « La détection de fraude requiert cependant une capacité d’identification du payeur et le traçage des clients, ce qui est incompatible avec le respect de la confidentialité de la transaction. ». Le fait d'avoir un cahier des charges clair est un des intérêts de cette étude. Par exemple, d'innombrables articles ont été écrits sur des projets comme Diem ou le « yuan électronique » alors que leur cahier des charges reste vague. Le problème est d'autant plus grave qu'il y a souvent de la mauvaise foi dans certains discours. Ainsi, les projets de numérisation ont souvent pour but réel d'en finir avec l'argent liquide pour avoir une traçabilité complète des transactions et une surveillance permanente des acheteurs.

Comment les auteurs de l'article voient-ils leur système de MNBC (monnaie numérique de banque centrale) ? Étant donné qu'il n'y a qu'un émetteur, nul besoin d'une chaine de blocs. (La quasi-totalité des projets de « chaine de blocs privée » ou de « chaine de blocs à permission » n'ont aucun sens : comme le dit l'article « La DLT est une architecture intéressante lorsqu’il n’existe pas d’acteur central ou si les parties prenantes ne souhaitent pas s’accorder sur un acteur central de confiance. Ce qui n’est cependant pratiquement jamais le cas pour une monnaie numérique de détail émise par une banque centrale. [...] Recourir à un registre distribué [réparti, plutôt] ne fait qu’augmenter les coûts de transaction; cela n’apporte aucun avantage dans une mise en place par une banque centrale »). Leur système repose à la place sur GNU Taler (développé par un des auteurs) et les signatures en aveugle de Chaum. La sécurité du système dépend donc de ces techniques logicielles. (D'autres propositions font appel à des systèmes physiques spécifiques, mais « les fonctions physiques non clonables ne peuvent pas s’échanger sur Internet (éliminant de fait l’usage principal de la MNBC » et « les tentatives précédentes de verrous matériels pour empêcher la copie ont été compromises de façon répétée », voir les DRM.) Comme la monnaie numérique de banque centrale envisagée dans cet article a beaucoup de propriétés communes avec l'argent physique (le liquide), elle a également une sécurité proche : possession fait loi, ce qui veut dire que, si l'appareil sur lequel vous gardez vos pièces est détruit, vous perdez votre argent. Cette solution, comme l'argent liquide, n'est raisonnable que pour des sommes relativement faibles. Si l'acheteur n'est pas identifiable, le vendeur l'est car il ne peut pas réutiliser directement les « pièces », il doit les remettre à la banque. C'est nécessaire au mécanisme de protection contre la double dépense. Autre nécessité, la banque centrale doit être connectée en permanence, ce qui impose des exigences nouvelles pour les banques centrales (« La détection de doubles dépenses en ligne élimine ce risque mais rend donc les transactions impossibles si la connexion Internet de la banque centrale est indisponible. ») Je ne vous détaille pas les protocoles cryptographiques ici, je n'ai pas le niveau, lisez l'article. Notez qu'ils sont assez complexes, ce qui peut être un obstacle à l'adoption : la plupart des utilisateurs ne peuvent pas comprendre cette solution, ils devront faire confiance à la minorité qui a compris et vérifié. (Ceci dit, dès aujourd'hui, peu de gens comprennent le système monétaire.)

Quelles sont les chances qu'une banque centrale, avec ses messieurs sérieux en costume-cravate, reprenne cette idée et se lance dans un projet de monnaie numérique protégeant la vie privée ? Personnellement, je dirais qu'elles sont à peu près nulles. Les auteurs notent à juste titre que « une MNBC de détail devrait être basée sur un logiciel libre ou ouvert. Imposer une solution propriétaire qui entraînerait une dépendance à un fournisseur spécifique pourrait vraisemblablement constituer dès le départ un obstacle à son adoption. » Mais cette condition suffirait à faire rejeter le projet par toute banque centrale (déjà, le mot « libre »…). Tous ces dirigeants politiques et financiers passent du temps à critiquer le Bitcoin « qui permet la fraude fiscale et le financement du terrorisme » mais ils ne font aucun effort pour développer des alternatives. Le projet décrit dans cet article est sympathique mais n'a aucune chance. Il essaie de plaire aux banques centrales mais celles-ci n'en voudront jamais, attachées qu'elles sont à des solutions fermées, privatrices, et facilitant la surveillance.


L'article seul

RFC 9057: Email Author Header Field

Date de publication du RFC : Juin 2021
Auteur(s) du RFC : D. Crocker (Brandenburg InternetWorking)
Expérimental
Première rédaction de cet article le 23 juin 2021


Qui est l'auteur d'un message reçu par courrier électronique ? La réponse semblait autrefois simple, c'est forcément la personne ou l'organisation indiquée dans le champ From:. Sauf que des changements récents (et pas forcément bien inspirés) dans le traitement des messages ont amené à ce que le From: soit parfois modifié, par exemple par certaines listes de diffusion. Il ne reflète donc plus le vrai auteur. D'où ce RFC qui crée un nouvel en-tête, Author:, qui identifie le vrai émetteur.

La norme pertinente est le RFC 5322, qui définit des en-têtes comme From: (auteur d'un message) ou Sender: (personne ou entité qui n'a pas écrit le message mais réalise l'envoi, par exemple parce que l'auteur n'avait pas le temps, ou bien parce que le message a été relayé par un intermédiaire). Les amateurs d'archéologie noteront que le courrier électronique est très ancien, plus ancien que l'Internet, cette ancienneté étant la preuve de son efficacité et de sa robustesse. Le premier RFC avec la notion formelle d'auteur d'un message était le RFC 733.

Une particularité du courrier électronique est que le message ne va pas toujours directement de la machine de l'auteure à celle du lecteur (cf. le RFC 5598, sur l'architecture du courrier). Il y a souvent des intermédiaires (mediators) comme les gestionnaires de listes de diffusion, qui prennent un message et le redistribuent aux abonnées. En raison du problème du spam, plusieurs mécanismes de protection ont été développés, qui peuvent poser des problèmes pour ces intermédiaires. SPF (RFC 7208), contrairement à une légende tenace, n'affecte pas les listes de diffusion. (C'est en raison de la distinction entre enveloppe et en-tête d'un message. Si vous entendez quelqu'un pontifier sur SPF et la messagerie, et qu'il ne connait pas la différence entre l'émetteur indiqué dans l'enveloppe et celui marqué dans l'en-tête, vous pouvez être sûre que cette personne est ignorante.) En revanche, DKIM (RFC 6376), surtout combiné avec DMARC (RFC 7489), peut poser des problèmes dans certains cas (le RFC 6377 les détaille). Pour gérer ces problèmes, certaines listes de diffusion choisissent de carrément changer le From: du message et d'y mettre, par exemple (ici tiré de l'utile liste outages, informant des pannes Internet) :


From: Erik Sundberg via Outages <outages@outages.org>

  

Alors que le message avait en fait été écrit par « Erik Sundberg <ESundberg@nitelusa.com> ». C'est une mauvaise idée, mais elle est commune. Dans ce cas, la liste s'est « approprié » le message et on a perdu le vrai auteur, privant ainsi la lectrice d'une information utile (dans le cas de la liste Outages, il a toutefois été préservé dans le champ Reply-To:). [Personnellement, il me semble que l'idéal serait de ne pas modifier le message, préservant ainsi les signatures DKIM, et donc les vérifications DMARC. Dans les cas où le message est modifié, DMARC s'obstine à vérifier le From: et pas le Sender:, ce qui serait pourtant bien plus logique.]

Maintenant, la solution (section 3 du RFC) : un nouvel en-tête, Author:, dont la syntaxe est la même que celle de From:. Par exemple :


Author: Dave Crocker <dcrocker@bbiw.net>

  

Cet en-tête peut être mis au départ, par le MUA, ou bien ajouté par un intermédiaire qui massacre le champ From: mais veut garder une trace de sa valeur originale en la recopiant dans le champ Author:. Cela n'est possible que s'il n'y a pas déjà un champ Author:. S'il existe, il est strictement interdit de le modifier ou de le supprimer.

À la lecture, par le MUA de réception, le RFC conseille d'utiliser le champ Author:, s'il est présent, plutôt que le From:, pour afficher ou trier sur le nom de l'expéditrice.

Comme dans le cas du champ From:, un malhonnête peut évidemment mettre n'importe quoi dans le champ Author: et il faut donc faire attention à ne pas lui accorder une confiance aveugle.

Author: a été ajouté au registre des en-têtes.

On notera qu'une tentative précédente de préservation de l'en-tête From: original avait été faite dans le RFC 5703, qui créait un Original-From: mais uniquement pour les intermédiaires, pas pour les MUA.


Téléchargez le RFC 9057


L'article seul

Traiter des options EDNS nouvelles dans un programme

Première rédaction de cet article le 18 juin 2021


Le protocole DNS permet d'attacher des métadonnées aux questions ou aux réponses par le biais de l'extension EDNS, normalisée dans le RFC 6891. Un certain nombre d'options sont déjà normalisées et peuvent être manipulées depuis un programme, via une bibliothèque DNS. Mais s'il s'agit d'une option EDNS nouvelle, pas encore traitée par la bibliothèque ?

On va voir cela avec l'option « RRSERIAL » actuellement en cours de discussion à l'IETF, dans le draft draft-ietf-dnsop-rrserial. Son but est de récupérer le numéro de série de la zone correspondant à une réponse. Elle est très simple, la valeur associée étant vide dans la question, et uniquement un entier sur 32 bits dans la réponse. Un serveur expérimental existe utilisant cette option, 200.1.122.30.

Déjà, on peut tester sans programmer avec dig, et son option +ednsopt. Les options EDNS ont un code, enregistré à l'IANA. RRSERIAL n'en a pas encore, donc le serveur de test utilise le code temporaire 65024 :

% dig +ednsopt=65024 @200.1.122.30 dateserial.example.com
...
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; OPT=65024: 78 49 7a 79 ("xIzy")
  

Ça marche, on a obtenu une réponse. dig ne sait pas la formater proprement (« xIzy » est la représentation de 78 49 7a 79 interprété comme de l'ASCII, alors qu'il s'agit d'un entier, le nombre 2018081401), mais c'est déjà ça. (Le draft précise que l'option RRSERIAL a une valeur nulle dans la requête, seule sa présence compte. S'il avait fallu donner une valeur, dig permet de le faire avec +ednsopt=CODE:VALEUR.) Donc, le serveur fonctionne bien. Maintenant, on voudrait faire mieux et donc utiliser un client DNS adapté (d'autant plus qu'il y a des cas à traiter comme la réponse NXDOMAIN, où le numéro de série de la zone est dans un enregistrement SOA, pas dans l'option EDNS). On va donc programmer.

Commençons en Python avec la bibliothèque dnspython. On peut fabriquer l'option dans la requête avec la classe GenericOption :

opts = [dns.edns.GenericOption(dns.edns.RRSERIAL, b'')]
...
message = dns.message.make_query(qname, qtype, options=opts)
  

(Le b'' indique une valeur binaire vide.) Pour lire l'option dans la réponse :

    
for opt in response.options:
   if opt.otype == dns.edns.RRSERIAL:
      print("Serial of the answer is %s" % struct.unpack(">I", opt.data)[0])

  

On a donc juste à convertir la valeur binaire en chaine (le >I signifie un entier gros-boutien). Le code Python complet est en test-rrserial.py.

Pour Go, on va utiliser la bibliothèque godns. Créer l'option et l'ajouter à la requête DNS (m dans le code) se fait ainsi :

m.Question = make([]dns.Question, 1)
// Tout pseudo-enregistrement EDNS a pour nom "." (la racine)
o.Hdr.Name = "."
o.Hdr.Rrtype = dns.TypeOPT
o.SetUDPSize(4096)
// Option EDNS générique
e := new(dns.EDNS0_LOCAL)
e.Code = otype
// Requête vide
e.Data = []byte{}
o.Option = append(o.Option, e)
// Extra est la section Additionnelle
m.Extra = append(m.Extra, o)
  

Et pour lire le résultat :

opt := msg.IsEdns0()
for _, v := range opt.Option {
    // Merci à Tom Thorogood pour le rappel qu'il faut forcer le type
    // et donc avoir une nouvelle variable v (le ':=').
    switch v := v.(type) {
        case *dns.EDNS0_LOCAL:
            if v.Option() == otype {
                serial := binary.BigEndian.Uint32(v.Data)
                fmt.Printf("EDNS rrserial found, \"%d\"\n", serial)
            ...
  

Le code Go complet est en test-rrserial.go.


L'article seul

RFC 9082: Registration Data Access Protocol (RDAP) Query Format

Date de publication du RFC : Juin 2021
Auteur(s) du RFC : S. Hollenbeck (Verisign Labs), A. Newton (AWS)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 16 juin 2021


Le protocole d'information RDAP, qui vise à remplacer whois, est décrit dans un ensemble de RFC. Celui présenté ici normalise la façon de former les requêtes RDAP. Celles-ci ont la forme d'une URL, puisque RDAP repose sur l'architecture REST. Ce RFC remplace l'ancienne norme sur les requêtes RDAP, qui était dans le RFC 7482, mais il n'y a pas de changement significatif.

RDAP peut être utilisé pour beaucoup de sortes d'entités différentes mais ce RFC ne couvre que ce qui correspond aux usages actuels de whois, les préfixes d'adresses IP, les AS, les noms de domaine, etc. Bien sûr, un serveur RDAP donné ne gère pas forcément tous ces types d'entités, et il doit renvoyer le code HTTP 501 (Not implemented) s'il ne sait pas gérer une demande donnée. Ce RFC ne spécifie que l'URL de la requête, le format de la réponse est variable (JSON, XML...) et le seul actuellement normalisé, au-dessus de JSON, est décrit dans le RFC 9083. Quant au protocole de transport, le seul actuellement normalisé pour RDAP (dans le RFC 7480) est HTTP. D'autre part, ces RFC RDAP ne décrivent que le protocole entre le client RDAP et le serveur, pas « l'arrière-cuisine », c'est-à-dire l'avitaillement (création, modification et suppression) des entités enregistrées. RDAP est en lecture seule et ne modifie pas le contenu des bases de données qu'il interroge.

Passons aux choses concrètes. Une requête RDAP est un URL (RFC 3986). Celui-ci est obtenu en ajoutant un chemin spécifique à une base. La base (par exemple https://rdap.example.net/) va être obtenue par des mécanismes divers, comme celui du RFC 7484, qui spécifie un registre que vous pouvez trouver en ligne. On met ensuite un chemin qui dépend du type d'entité sur laquelle on veut se renseigner, et qui indique l'identificateur de l'entité. Par exemple, avec la base ci-dessus, et une recherche du nom de domaine internautique.fr, on construirait un URL complet https://rdap.example.net/domain/internautique.fr. Il y a cinq types d'entités possibles :

  • ip : les préfixes IP (notez qu'on peut chercher un préfixe en donnant juste une des adresses IP couvertes par ce préfixe),
  • autnum : les numéros de systèmes autonomes,
  • domain : un nom de domaine (notez que cela peut être un domaine dans in-addr.arpa ou ipv6.arpa),
  • nameserver : un serveur de noms,
  • entity : une entité quelconque, comme un bureau d'enregistrement, ou un contact identifié par un handle.

La requête est effectuée avec la méthode HTTP GET (les méthodes permettant de modifier le contenu du registre n'ont pas de sens ici, les modifications dans le registre sont plutôt faites avec EPP). Pour juste savoir si un objet existe, on peut aussi utiliser la méthode HEAD. Si on n'obtient pas de code 404, c'est que l'objet existe.

Pour ip, le chemin dans l'URL est /ip/XXXXXX peut être une adresse IPv4 ou IPv6 sous forme texte. Il peut aussi y avoir une longueur de préfixe à la fin donc /ip/2001:db8:1:a::/64 est un chemin valable. Ainsi, sur le service RDAP du RIPE-NCC, https://rdap.db.ripe.net/ip/2001:4b98:dc0:41:: est un URL possible. Testons-le avec curl (le format de sortie, en JSON, est décrit dans le RFC 9083, vous aurez peut-être besoin de passer le résultat à travers jq pour l'afficher joliment) :

% curl https://rdap.db.ripe.net/ip/2001:4b98:dc0:41:: 
{
  "handle" : "2001:4b98:dc0::/48",
  "startAddress" : "2001:4b98:dc0::/128",
  "endAddress" : "2001:4b98:dc0:ffff:ffff:ffff:ffff:ffff/128",
  "ipVersion" : "v6",
  "name" : "GANDI-HOSTING-DC0",
  "type" : "ASSIGNED",
  "country" : "FR",
  "rdapConformance" : [ "rdap_level_0" ],
  "entities" : [ {
    "handle" : "GAD42-RIPE",
    "vcardArray" : [ "vcard", [ [ "version", { }, "text", "4.0" ], [ "fn", { }, "text", "Gandi Abuse Department" ], [ "kind", { }, "text", "group" ], [ "adr", {
      "label" : "63-65 Boulevard Massena\n75013 Paris\nFrance"
...

J'ai utilisé curl mais, notamment pour formater plus joliment la sortie de RDAP, les vrais utilisateurs se serviront plutôt d'un client RDAP dédié comme RDAPBrowser sur Android, ou nicinfo. Voici une vue de RDAPbrowser: rdapbrowser.png

Pour autnum, on met le numéro de l'AS après /autnum/ (au format « asplain » du RFC 5396). Toujours dans l'exemple RIPE-NCC, https://rdap.db.ripe.net/autnum/208069 permet de chercher de l'information sur l'AS 208069 :

% curl https://rdap.db.ripe.net/autnum/208069
{
  "handle" : "AS208069",
  "name" : "ATAXYA",
  "type" : "DIRECT ALLOCATION",
  "entities" : [ {
    "handle" : "mc40833-RIPE",
    "roles" : [ "administrative", "technical" ],
    "objectClassName" : "entity"
  }, {
...

Pour les noms de domaines, on met le nom après /domain/. Ainsi, sur le serveur RDAP d'Afilias, https://rdap.afilias.net/rdap/info/domain/rmll.info nous donnera de l'information sur le domaine rmll.info. On peut mettre un nom en Unicode donc https://rdap.example.net/domain/potamochère.fr est valable, mais il devra être encodé comme l'explique la section 6.1, plus loin (en gros, UTF-8 en NFC). Si on ne veut pas lire cette information sur l'encodage, on peut aussi utiliser la forme Punycode, donc chercher avec https://rdap.example.net/domain/xn--potamochre-66a.fr. Un exemple réel, en Russie :

% curl https://api.rdap.nic.рус/domain/валфекс.рус
...
         {
      "eventAction": "registration",
      "eventDate": "2018-12-26T07:53:41.776927Z"
    },
    ...
                "adr",
            {
              "type": "Registrar Contact"
            },
            "text",
            [
              "",
              "",
              "125476, g. Moskva, ul. Vasilya Petushkova, dom 3, str. 1",
              "",
              "",
              "",
              "RU"
            ]
          ]
...
  

(Attention, le certificat ne sera accepté par curl que si curl a été compilé avec l'option « IDN ».)

On peut aussi se servir de RDAP pour les noms de domaines qui servent à traduire une adresse IP en nom :

% curl https://rdap.db.ripe.net/domain/1.8.a.4.1.0.0.0.0.d.1.4.1.0.0.2.ip6.arpa
{
  "handle" : "0.d.1.4.1.0.0.2.ip6.arpa",
  "ldhName" : "0.d.1.4.1.0.0.2.ip6.arpa",
  "nameServers" : [ {
    "ldhName" : "dns15.ovh.net"
  }, {
    "ldhName" : "ns15.ovh.net"
  } ],
  "rdapConformance" : [ "rdap_level_0" ],
  "entities" : [ {
    "handle" : "OK217-RIPE",
    "roles" : [ "administrative" ]
  }, {
    "handle" : "OTC2-RIPE",
    "roles" : [ "zone", "technical" ]
  }, {
    "handle" : "OVH-MNT",
    "roles" : [ "registrant" ]
  } ],
  "remarks" : [ {
    "description" : [ "OVH IPv6 reverse delegation" ]
  } ],
...

Pour un serveur de noms, on met son nom après /nameserver donc, chez Afilias :

% curl https://rdap.afilias.net/rdap/info/nameserver/rmll1.rmll.info
{
...
   "ipAddresses": {
      "v4": [
         "80.67.169.65"
      ]
   }, 
   "lang": "en", 
   "ldhName": "rmll1.rmll.info", 
...

Pour entity, on indique juste un identificateur. Voici un exemple :

% curl  http://rdg.afilias.info/rdap/entity/81
{
   "handle": "81", 
   "lang": "en", 
...
   "roles": [
      "registrar"
   ], 
   "vcardArray": [
      "vcard", 
      [
         [
            "version", 
            {}, 
            "text", 
            "4.0"
         ], 
         [
            "fn", 
            {}, 
            "text", 
            "Gandi SAS"
         ], 
         [
            "adr", 
            {}, 
            "text", 
            [
               "", 
               "", 
               "63-65 boulevard Massena", 
               "Paris", 
               "", 
               "F-75013", 
               "FR"
            ]
...
  

Certains registres, qui stockent d'autres types d'objets, pourront ajouter leurs propres requêtes, en prenant soin d'enregistrer les préfixes de ces requêtes dans le registre IANA. Par exemple, le logiciel de gestion de registres FRED permet d'interroger le registre sur les clés DNSSEC avec les requêtes /fred_keyset (la syntaxe des requêtes locales est identificateur du préfixe + tiret bas + type cherché).

Dernière possibilité, un chemin spécial indique qu'on veut récupérer de l'aide sur ce serveur RDAP particulier. En envoyant help (par exemple https://rdap.example.net/help), on obtient un document décrivant les capacités de ce serveur, ses conditions d'utilisation, sa politique vis-à-vis de la vie privée, ses possibilités d'authentification (via les mécanismes de HTTP), l'adresse où contacter les responsables, etc. C'est l'équivalent de la fonction d'aide qu'offrent certains serveurs whois, ici celui de l'AFNIC :

% whois -h whois.nic.fr  -- -h
...
%% Option   Function
%% -------  -------------------------------------
%% -r       turn off recursive lookups
%% -n       AFNIC output format
%% -o       old fashioned output format (Default)
%% -7       force 7bits ASCII output format
%% -v       verbose mode for templates and help options
%%          (may be use for reverse query)
%% -T type  return only objects of specified type
%% -P       don't return individual objects in case of contact search
%% -h       informations about server features
%% -l lang  choice of a language for informations (you can specify US|EN|UK for
%%          english or FR for french)
%%
...

Pour RDAP, voyez par exemple https://rdap.nic.bzh/help (qui renvoie de l'HTML), ou, plus austères et se limitant à un renvoi à une page Web, http://rdap.apnic.net/help ou https://rdap.nic.cz/help.

Toutes les recherches jusque-là ont été des recherches exactes (pas complètement pour les adresses IP, où on pouvait chercher un réseau par une seule des adresses contenues dans le réseau). Mais on peut aussi faire des recherches plus ouvertes, sur une partie de l'identificateur. Cela se fait en ajoutant une requête (la partie après le point d'interrogation) dans l'URL et en ajoutant un astérisque (cf. section 4.1). Ainsi, https://rdap.example.net/domains?name=foo* cherchera tous les domaines dont le nom commence par la chaîne de caractères foo. (Vous avez noté que c'est /domains, au pluriel, et non plus /domain ?) Voici un exemple d'utilisation :

% curl  https://rdap.afilias.net/rdap/info/domains\?name=rm\*
...
  "errorCode": 422,
  "title": "Error in processing the request",
  "description": [
    "WildCard search is not supported on sub-zone or tld"
  ]
...

Eh oui, les requêtes ouvertes comme celle-ci posent à la fois des problèmes techniques (la charge du serveur) et politico-juridiques (la capacité à extraire de grandes quantités de la base de données). Elles sont donc typiquement utilisables seulement après une authentification.

On peut aussi chercher un domaine d'après ses serveurs de noms, par exemple https://rdap.example.net/domains?nsLdhName=ns1.example.com chercherait tous les domaines délégués au serveur DNS ns1.example.com. Une telle fonction peut être jugée très indiscrète et le serveur RDAP est toujours libre de répondre ou pas mais, ici, cela marche, on trouve bien le domaine qui a ce serveur de noms :

% curl  https://rdap.afilias.net/rdap/info/domains\?nsLdhName=ns0.abul.org 
...
"domainSearchResults": [
    {
      "objectClassName": "domain",
      "handle": "D10775367-LRMS",
      "ldhName": "rmll.info",
...
  

Deux autres types permettent ces recherches ouvertes, /nameservers (comme dans https://rdap.example.net/nameservers?ip=2001:db8:42::1:53, mais notez qu'on peut aussi chercher un serveur par son nom) et /entities (comme dans https://rdap.example.net/entities?fn=Jean%20Dupon*) :

% curl  http://rdg.afilias.info/rdap/entities\?fn=go\*     
{
   "entitySearchResults": [
      {
         "fn": "Go China Domains, Inc.", 
...
         "fn": "Gotnames.ca Inc.", 
...

Notez que ce type de recherche peut représenter un sérieux danger pour la vie privée (comme noté dans le RFC, par exemple en section 4.2) puisqu'elle permet, par exemple de trouver tous les titulaires prénommés Jean. Elle est donc parfois uniquement accessible à des clients authentifiés, et de confiance.

La section 4 détaille le traitement des requêtes. N'oubliez pas qu'on travaille ici sur HTTP et que, par défaut, les codes de retour RDAP suivent la sémantique HTTP (404 pour un objet non trouvé, par exemple). Il y a aussi quelques cas où le code à retourner est moins évident. Ainsi, si un serveur ne veut pas faire une recherche ouverte, il va répondre 422 (Unprocessable Entity).

Vous avez noté plus haut, mais la section 6 le rappelle aux distraits, que le nom de domaine peut être exprimé en Unicode ou en ASCII. Donc, https://rdap.example.net/domain/potamochère.fr et https://rdap.example.net/domain/xn--potamochre-66a.fr sont deux requêtes acceptables.

Enfin, la section 8 rappelle quelques règles de sécurité comme :

  • Les requêtes ouvertes peuvent mener à une forte consommation de ressources sur le serveur. Le serveur qui ne vaut pas se faire DoSer doit donc faire attention avant de les accepter.
  • Les requêtes RDAP, et surtout les requêtes ouvertes, peuvent soulever des questions liées à la vie privée. Les serveurs RDAP doivent donc réfléchir avant de renvoyer de l'information. Rappelez-vous que RDAP, contrairement à whois, peut avoir un mécanisme d'authentification, donc peut envoyer des réponses différentes selon le client.
  • Et, corollaire du précédent point, les gérants de serveurs RDAP doivent définir une politique d'autorisation : qu'est-ce que je renvoie, et à qui ?

Les changements depuis le RFC 7482 sont peu nombreux et sont surtout de clarification.


Téléchargez le RFC 9082


L'article seul

RFC 9083: JSON Responses for the Registration Data Access Protocol (RDAP)

Date de publication du RFC : Juin 2021
Auteur(s) du RFC : S. Hollenbeck (Verisign Labs), A. Newton (AWS)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 16 juin 2021


Dans l'ensemble des normes sur le protocole RDAP, ce RFC est destiné à décrire le format de sortie, celui des réponses envoyées par le serveur d'information RDAP. Ce format est basé sur JSON et, pour utiliser RDAP en remplacement de whois, il faudra donc se munir de quelques outils pour traiter le JSON. Ce RFC remplace le RFC 7483 mais il y a très peu de changements.

JSON est normalisé dans le RFC 8259 et représente aujourd'hui le format de choix pour les données structurées c'est-à-dire analysables par un programme. (L'annexe E de notre RFC explique en détail le pourquoi du choix de JSON.) Une des caractéristiques importantes de whois est en effet que son format de sortie n'a aucune structure, c'est du texte libre, ce qui est pénible pour les programmeurs qui essaient de le traiter (mais, d'un autre côté, cela ralentit certains usages déplorables, comme la récolte d'adresses de courrier à des fins de spam, jouant ainsi un rôle de semantic firewall). L'utilisation typique de RDAP est en HTTP (RFC 7480) avec les requêtes exprimées dans la syntaxe des URL du RFC 9082. Voici tout de suite un exemple réel, avec la réponse JSON :

% curl https://rdap.afilias.net/rdap/info/domain/kornog-computing.info
...
{
   "entities": [
...
         "objectClassName": "entity", 
         "roles": [
            "technical", 
            "billing", 
            "administrative"
         ], 
         "vcardArray": [
            "vcard", 
            [
               [
                  "version", 
                  {}, 
                  "text", 
                  "4.0"
               ], 
               [
                  "fn", 
                  {}, 
                  "text", 
                  "KORNOG computing"
               ], 
               [
		    "adr",
		    {
		      "cc": "FR"
		    },
		    "text",
		    {}
	      ]
...
   "events": [
      {
         "eventAction": "registration", 
         "eventDate": "2007-08-14T17:02:33Z"
      }, 
      {
         "eventAction": "last changed", 
         "eventDate": "2014-08-14T01:54:07Z"
      }, 
      {
         "eventAction": "expiration", 
         "eventDate": "2015-08-14T17:02:33Z"
      }
   ], 
   "handle": "D19378523-LRMS", 
   "lang": "en", 
   "ldhName": "kornog-computing.info", 
...
   "nameservers": [
      {
         "ldhName": "ns1.kornog-computing.net", 
         "objectClassName": "nameserver", 
         "remarks": [
            {
               "description": [
                  "Summary data only. For complete data, send a specific query for the object."
               ], 
               "title": "Incomplete Data", 
               "type": "object truncated due to unexplainable reasons"
            }
         ]
      }, 
      {
         "ldhName": "ns2.kornog-computing.net", 
         "objectClassName": "nameserver", 
         "remarks": [
            {
               "description": [
                  "Summary data only. For complete data, send a specific query for the object."
               ], 
               "title": "Incomplete Data", 
               "type": "object truncated due to unexplainable reasons"
            }
         ]
      }
   ], 
   "notices": [
      {
         "description": [
            "Access to AFILIAS WHOIS information is provided to assist persons in determining the contents of a domain name registration record in the Afilias registry database. The data in this record is provided by Afilias Limited for informational purposes only, and Afilias does not guarantee its accuracy. [...]"
         ], 
         "title": "TERMS OF USE"
      }
   ], 
   "objectClassName": "domain", 
...
   "rdapConformance": [
      "rdap_level_0"
   ], 
   "secureDNS": {
      "zoneSigned": false
   }, 
   "status": [
      "clientDeleteProhibited -- http://www.icann.org/epp#clientDeleteProhibited", 
      "clientTransferProhibited -- http://www.icann.org/epp#clientTransferProhibited"
   ]
}

La section 1.2 présente le modèle de données de RDAP. Dans les réponses, on trouve des types simples (comme des chaînes de caractères), des tableaux JSON, et des objets JSON qui décrivent les trucs sur lesquels on veut de l'information (noms de domaine, adresses IP, etc). Ces objets peuvent comporter des tableaux ou d'autres objets et, lorsqu'une réponse renvoie plusieurs objets (cas des recherches ouvertes, cf. RFC 9082, section 3.2), peuvent eux-même être regroupés en tableaux. Il existe plusieurs classes de ces objets. D'abord, les classes communes aux registres de noms de domaine et aux RIR (registres d'adresses IP) :

  • Domaines (oui, même pour les RIR, pensez à in-addr.arpa et ip6.arpa),
  • Serveurs de noms,
  • Entités diverses, comme les handles, les identificateurs des contacts, genre GR283-FRNIC.

Deux classes sont spécifiques aux RIR :

On verra peut-être apparaître d'autres classes avec le temps, si l'usage de RDAP se répand.

La section 2 de notre RFC décrit comment JSON est utilisé. Le type MIME renvoyé est application/rdap+json. La section 2 commence par un rappel que le client RDAP doit ignorer les membres inconnus dans les objets JSON, afin de préserver la future extensibilité. (Cette règle ne s'applique pas au jCard - cf. RFC 7095 - embarqué.) Si un serveur veut ajouter des membres qui lui sont spécifiques, il est recommandé qu'il préfixe leur nom avec un identificateur court suivi d'un tiret bas. Ainsi, cet objet RDAP standard :

{
     "handle" : "ABC123",
     "remarks" :
     [
       {
         "description" :
         [
           "She sells sea shells down by the sea shore.",
           "Originally written by Terry Sullivan."
         ]
       }
     ]
   }

S'il est servi par le « registre de la Lune » (registre imaginaire qui fournit les exemples de ce RFC), celui-ci, lorsqu'il voudra ajouter des membres, les précédera de lunarNIC_ :

{
     "handle" : "ABC123",
     "lunarNic_beforeOneSmallStep" : "TRUE THAT!",
     "remarks" :
     [
       {
         "description" :
         [
           "She sells sea shells down by the sea shore.",
           "Originally written by Terry Sullivan."
         ]
       }
     ],
     "lunarNic_harshMistressNotes" :
     [
       "In space,",
       "nobody can hear you scream."
     ]
   }

(Je vous laisse décoder les références geeks dans l'exemple.)

La section 3 s'occupe des types de données de base. On utilise du JSON normal, tel que spécifié dans le RFC 8259, avec ses chaînes de caractères, ses booléens, son null... Un handle (l'identifiant unique - par registre - d'un contact, parfois nommé NIC handle ou registry ID) est une chaîne. Les adresses IP se représentent également par une chaîne de caractères (ne pas oublier le RFC 5952 pour IPv6). Les pays sont identifiés par le code à deux lettres de ISO 3166. Les noms de domaines peuvent être sous une forme ASCII ou bien en Unicode. Les dates et heures suivent le RFC 3339, et les URI le RFC 3986.

Les informations plus complexes (comme les détails sur un contact) utilisent jCard, normalisé dans le RFC 7095.

Que trouve-t-on dans les objets JSON renvoyés par un serveur RDAP ? Une indication de la version de la norme :

"rdapConformance" :
   [
     "rdap_level_0"
   ]

(Éventuellement avec d'autres identificateurs pour les extensions locales.) Et des liens vers des ressources situées ailleurs, suivant le cadre du RFC 8288 :

         "links": [
            {
               "href": "http://rdg.afilias.info/rdap/entity/ovh53ec16bekre5", 
               "rel": "self", 
               "type": "application/rdap+json", 
               "value": "http://rdg.afilias.info/rdap/entity/ovh53ec16bekre5"
            }

On peut aussi avoir du texte libre, comme dans l'exemple plus haut avec le membre remarks. Ce membre sert aux textes décrivant la classe, alors que notices est utilisé pour le service RDAP. Un exemple :

   "notices": [
      {
         "description": [
            "Access to AFILIAS WHOIS information is provided to assist persons in determining the contents of a domain name registration record in the Afilias registry database. The data in this record is provided by Afilias Limited for informational purposes only, and Afilias does not guarantee its accuracy. [...]"
         ], 
         "title": "TERMS OF USE"
      }
   ], 

Contrairement à whois, RDAP permet l'internationalisation sous tous ses aspects. Par exemple, on peut indiquer la langue des textes avec une étiquette de langue (RFC 5646) :

   "lang": "en", 

Enfin, la classe (le type) de l'objet renvoyé par RDAP est indiquée par un membre objectClassName :

   "objectClassName": "domain", 

Ces classes, justement. La section 5 les décrit. Il y a d'abord la classe Entity qui correspond aux requêtes /entity du RFC 9082. Elle sert à décrire les personnes et les organisations. Parmi les membres importants pour les objets de cette classe, handle qui est un identificateur de l'instance de la classe, et roles qui indique la relation de cette instance avec l'objet qui la contient (par exemple "roles": ["technical"] indiquera que cette Entity est le contact technique de l'objet). L'information de contact sur une Entity se fait avec le format vCard du RFC 7095, dans un membre vcardArray. Voici un exemple avec le titulaire du domaine uba.ar :

% curl https://rdap.nic.ar/entity/30546666561
...
  "objectClassName": "entity",
  "vcardArray": [
    "vcard",
    [
      [
        "version",
        {},
        "text",
        "4.0"
      ],
      [
        "fn",
        {},
        "text",
        "UNIVERSIDAD DE BUENOS AIRES"
      ]
    ]
  ],
...

(jCard permet de mentionner plein d'autres choses qui ne sont a priori pas utiles pour RDAP, comme la date de naissance ou le genre.)

La classe Nameserver correspond aux requêtes /nameserver du RFC 9082. Notez qu'un registre peut gérer les serveurs de noms de deux façons : ils peuvent être vus comme des objets autonomes, enregistrés tels quel dans le registre (par exemple via le RFC 5732), ayant des attributs par exemple des contacts, et interrogeables directement par whois ou RDAP (c'est le modèle de .com, on dit alors que les serveurs de noms sont des « objets de première classe »). Ou bien ils peuvent être simplement des attributs des domaines, accessibles via le domaine. Le principal attribut d'un objet Nameserver est son adresse IP, pour pouvoir générer des colles dans le DNS (enregistrement DNS d'une adresse IP, pour le cas où le serveur de noms est lui-même dans la zone qu'il sert). Voici un exemple avec un des serveurs de noms de la zone afilias-nst.info :

% curl https://rdap.afilias.net/rdap/info/nameserver/b0.dig.afilias-nst.info 
...
  "ipAddresses": {
    "v4": [
      "65.22.7.1"
    ],
    "v6": [
      "2a01:8840:7::1"
    ]
  },
...

Notez que l'adresse IP est un tableau, un serveur pouvant avoir plusieurs adresses.

La classe Domain correspond aux requêtes /domain du RFC 9082. Un objet de cette classe a des membres indiquant les serveurs de noms, si la zone est signée avec DNSSEC ou pas, l'enregistrement DS si elle est signée, le statut (actif ou non, bloqué ou non), les contacts, etc. Voici un exemple :

% curl http://rdg.afilias.info/rdap/domain/afilias-nst.info  
...
   "nameservers": [
      {
         "ldhName": "a0.dig.afilias-nst.info", 
...
  "secureDNS": {
    "delegationSigned": false
  },
  ...
  "status": [
    "client transfer prohibited",
    "server delete prohibited",
    "server transfer prohibited",
    "server update prohibited"
  ],
...

La classe IP network rassemble les objets qu'on trouve dans les réponses aux requêtes /ip du RFC 9082. Un objet de cette classe ne désigne en général pas une seule adresse IP mais un préfixe, dont on indique la première (startAddress) et la dernière adresse (endAddress). Personnellement, je trouve cela très laid et j'aurai préféré qu'on utilise une notation préfixe/longueur. Voici un exemple :

% curl https://rdap.db.ripe.net/ip/131.111.150.25    
...
{
  "handle" : "131.111.0.0 - 131.111.255.255",
  "startAddress" : "131.111.0.0/32",
  "endAddress" : "131.111.255.255/32",
  "ipVersion" : "v4",
  "name" : "CAM-AC-UK",
  "type" : "LEGACY",
  "country" : "GB",
...

La dernière classe normalisée à ce stade est autnum (les AS), en réponse aux requêtes /autnum du RFC 9082. Elle indique notamment les contacts de l'AS. Pour l'instant, il n'y a pas de format pour indiquer la politique de routage (RFC 4012). Un exemple d'un objet de cette classe :

% curl  https://rdap.db.ripe.net/autnum/20766 
{
  "handle" : "AS20766",
  "name" : "GITOYEN-MAIN-AS",
  "type" : "DIRECT ALLOCATION",
...
    "handle" : "GI1036-RIPE",
    "vcardArray" : [ "vcard", [ [ "version", { }, "text", "4.0" ], [ "fn", { }, "text", "NOC Gitoyen" ], [ "kind", { }, "text", "group" ], [ "adr", {
      "label" : "Gitoyen\n21 ter rue Voltaire\n75011 Paris\nFrance"
    }, "text", null ], [ "email", { }, "text", "noc@gitoyen.net" ] ] ],
...

Comme, dans la vie, il y a parfois des problèmes, une section de notre RFC, la section 6, est dédiée aux formats des erreurs que peuvent indiquer les serveurs RDAP. Le code de retour HTTP fournit déjà des indications (404 = cet objet n'existe pas ici, 403 = vous n'avez pas le droit de le savoir, etc) mais on peut aussi ajouter un objet JSON pour en indiquer davantage, objet ayant un membre errorCode (qui reprend le code HTTP), un membre title et un membre description. Voici un exemple sur le serveur RDAP de l'ARIN :

% curl -v http://rdap.arin.net/registry/autnum/99999
< HTTP/1.0 404 Not Found
< Mon, 10 May 2021 09:07:52 GMT
< Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips
...
{
...
  "errorCode" : 404,
  "title" : "AUTNUM NOT FOUND",
  "description" : [ "The autnum you are seeking as '99999' is/are not here." ]

Plus positive, la possibilité de demander de l'aide à un serveur RDAP, en se renseignant sur ses capacités, avec la requête /help. Son résultat est décrit dans la section 7 mais tous les serveurs RDAP actuels n'utilisent pas cette possibilité. En voici un où ça marche, à l'ARIN :

%  curl -s https://rdap.arin.net/registry/help 
{
  "rdapConformance" : [ "rdap_level_0" ],
  "notices" : [ {
    "title" : "Terms of Service",
    "description" : [ "By using the ARIN RDAP/Whois service, you are agreeing to the RDAP/Whois Terms of Use" ],
    "links" : [ {
      "value" : "https://rdap.arin.net/registry/help",
      "rel" : "about",
      "type" : "text/html",
      "href" : "https://www.arin.net/resources/registry/whois/tou/"
    } ]
  }, {
    "title" : "Whois Inaccuracy Reporting",
    "description" : [ "If you see inaccuracies in the results, please visit: " ],
    "links" : [ {
      "value" : "https://rdap.arin.net/registry/help",
      "rel" : "about",
      "type" : "text/html",
      "href" : "https://www.arin.net/resources/registry/whois/inaccuracy_reporting/"
    } ]
  }, {
    "title" : "Copyright Notice",
    "description" : [ "Copyright 1997-2021, American Registry for Internet Numbers, Ltd." ]
  } ]
}

Et les résultats des recherches ouvertes (section 3.2 du RFC 9082), qui peuvent renvoyer plusieurs objets ? Ce sont des tableaux JSON, dans des membres dont le nom se termine par Results. Par exemple, en cherchant les noms de domaines commençant par ra (ce test a été fait sur un serveur expérimental qui ne marche plus depuis) :

% curl http://rdg.afilias.info/rdap/domains\?name=ra\*|more           
   "domainSearchResults": [
      {
         "ldhName": "RAINSTRAGE.INFO", 
         ...
         "objectClassName": "domain", 
         "remarks": [
            {
               "description": [
                  "Summary data only. For complete data, send a specific query for the object."
               ], 
               "title": "Incomplete Data", 
               "type": "object truncated due to unexplainable reasons"
            }
...
         "ldhName": "RADONREMOVAL.INFO", 
...
         "ldhName": "RANCONDI.INFO", 
...

Les vrais serveurs RDAP en production ne répondent pas forcément à ces requêtes trop coûteuses et qui peuvent trop facilement être utilisées pour le renseignement économique :

%  curl https://rdap.afilias.net/rdap/info/domains\?name=ra\*
...
"errorCode": 422,
  "title": "Error in processing the request",
  "description": [
    "WildCard search is not supported on sub-zone or tld"
  ]
  

Vous avez peut-être noté dans le tout premier exemple le membre events (section 4.5 du RFC). Ces événements comme created ou last-changed donnent accès à l'histoire d'un objet enregistré. Ici, nous apprenons que le domaine kornog-computing.info a été enregistré en 2007.

Certaines valeurs qui apparaissent dans les résultats sont des chaînes de caractères fixes, stockées dans un nouveau registre IANA. Elles sont conçues pour être utilisées dans les notices, remarks, status, roles et quelques autres. Parmi les remarques, on trouvera le cas où une réponse a été tronquée (section 9 du RFC), comme dans l'exemple ci-dessus avec la mention Incomplete Data. Parmi les statuts, on trouvera, par exemple validated (pour un objet vérifié, par exemple un nom de domaine dont on a vérifié les coordonnées du titulaire), locked (pour un objet verrouillé), obscured (qui n'est pas un statut dans le base du données du registre mais simplement la mention du fait que le serveur RDAP a délibérement modifié certaines informations qu'il affiche, par exemple pour protéger la vie privée), etc. Pour les rôles, on trouvera registrant (titulaire), technical (contact technique), etc.

Pour ceux qu'intéressent les questions d'internationalisation, la section 12 contient d'utiles mentions. L'encodage des données JSON doit être de l'UTF-8. Et, comme indiqué plus haut, les IDN peuvent être sous la forme Punycode ou bien directement en UTF-8.

Et la vie privée, un problème permanent avec whois, où il faut toujours choisir entre la distribution de données utiles pour contacter quelqu'un et les risques pour sa vie privée ? La section 13 revient sur cette question. Un point important : RDAP est un protocole, pas une politique. Il ne définit pas quelles règles suivre (c'est de la responsabilité des divers registres) mais il fournit les outils pour mettre en œuvre ces règles. Notamment, RDAP permet de marquer des parties de la réponse comme étant connues du registre, mais n'ayant délibérement pas été envoyées (avec les codes private et removed) ou bien comme ayant été volontairement rendues peu ou pas lisibles (code obscured).

Vous avez vu dans les exemples précédents que les réponses d'un serveur RDAP sont souvent longues et, a priori, moins lisibles que celles d'un serveur whois. Il faudra souvent les traiter avec un logiciel qui comprend le JSON. Un exemple très simple et que j'apprécie est jq. Il peut servir à présenter le résultat de manière plus jolie :

% curl -s https://rdap.centralnic.com/pw/domain/centralnic.pw  | jq .
...
{
  "objectClassName": "domain",
  "handle": "D956082-CNIC",
  "ldhName": "centralnic.pw",
  "nameservers": [
    {
      "objectClassName": "nameserver",
      "ldhName": "ns0.centralnic-dns.com",
...

(Essayez ce même serveur RDAP sans jq !)

Mais on peut aussi se servir de jq pour extraire un champ particulier, ici le pays :

% curl -s  https://rdap.db.ripe.net/ip/131.111.150.25 | jq ".country"
"GB"

% curl -s  https://rdap.db.ripe.net/ip/192.134.1.1 | jq ".country"
"FR"

Il y a évidemment d'autres logiciels que jq sur ce créneau, comme JSONpath, jpath ou, pour les programmeurs Python, python -m json.tool.

Un dernier mot, sur le choix de JSON pour le format de sortie, alors que le protocole standard d'avitaillement des objets dans les bases Internet, EPP (RFC 5730) est en XML. L'annexe E de notre RFC, qui discute ce choix, donne comme principaux arguments que JSON est désormais plus répandu que XML (cf. l'article « The Stealthy Ascendancy of JSON ») et que c'est surtout vrai chez les utilisateurs (EPP étant utilisé par une population de professionnels bien plus réduite).

Quels changements depuis le RFC 7483 ? La plupart sont mineurs et sont de l'ordre de la clarification. D'autres sont des corrections d'erreurs, par exemple une coquille qui avait mis registrant là où il aurait fallu dire registrar (la proximité des mots en anglais entraine souvent des erreurs, même chez les professionnels). Il y a une certaine tendance au durcissement des règles, des éléments qui étaient optionnels dans le RFC 7483 sont devenus obligatoires comme, par exemple, rdapConformance (dont le statut optionnel avait causé des problèmes).

Et question logiciels qui mettent en œuvre RDAP ? Beaucoup de logiciels de gestion de registre le font aujourd'hui, notamment ceux sous contrat avec l'ICANN, puisqu'ils n'ont pas le choix. Mais les logiciels ne sont pas forcément publiquement disponibles. Parmi ceux qui le sont, il y a RedDog, Fred, celui de l'APNIC


Téléchargez le RFC 9083


L'article seul

QUIC et le suivi des utilisateurs par le serveur

Première rédaction de cet article le 12 juin 2021


Suite à mes articles sur le protocole QUIC, on a parfois attiré mon attention sur un problème potentiel de vie privée : certes, QUIC protège bien contre la surveillance exercée par un acteur extérieur à la communication, grâce à son chiffrement systématique. Mais qu'en est-il de la surveillance exercée par le serveur sur lequel on se connecte ? Penchons-nous sur la complexité de la conception des protocoles Internet, quand on est soucieux de vie privée.

Au contraire du cas de la surveillance par un tiers, très longuement traité dans les RFC sur QUIC (voir par exemple le RFC 9000, section 9.5), le cas du suivi d'un utilisateur par le serveur auquel il se connecte est absent. Et ce alors que les grosses entreprises capitalistes qui forment un partie très visible du Web d'aujourd'hui sont connues pour pratiquer la surveillance de masse. Mais qu'en est-il exactement ?

Voyons d'abord le principe de l'éventuel problème de suivi d'un utilisateur par le serveur. Les connexions QUIC peuvent être longues, peut-être plusieurs heures, voire jours, et elles survivent même aux changements d'adresses IP, QUIC permettant la migration d'une adresse à une autre. Le serveur peut donc facilement déterminer que la demande de /truc.html à 9 h est faite par le même utilisateur que la demande de /machin.html à 16 h, puisque c'est la même connexion QUIC. Indiscutablement, ce problème de suivi de l'utilisateur existe. Mais est-ce spécifique à QUIC et est-ce un vrai problème en pratique ?

D'abord, le problème est ancien. Si le vieil HTTP original n'envoyait qu'une requête par connexion, cette limitation a disparu il y a longtemps. Ainsi, HTTP/2 (RFC 7540) privilégiait déjà les connexions de longue durée, posant les mêmes problèmes. Toutefois, QUIC, avec sa capacité de survivre aux changements d'adresse IP, étend encore la durée de ces connexions, ce qui peut être vu comme aggravant le problème. (Des techniques assez rares, comme multipath TCP, RFC 8684, fonctionnaient également à travers les changements d'adresses IP.)

Mais surtout, dans l'utilisation typique du Web aujourd'hui, il existe bien d'autres méthodes de suivi de l'utilisateur par le serveur. Il y a évidemment les cookies du RFC 6265. Même si on n'est pas connecté à un service comme YouTube, des cookies sont placés. Et ces cookies, contrairement à la connexion de longue durée de QUIC, permettent un suivi inter-serveurs, via Google Analytics et les boutons de partage des GAFA que tant de webmestres mettent sur leurs pages sans réfléchir. Et il n'y a pas que les cookies, le fingerprinting du navigateur peut également permettre d'identifier un visiteur unique, par toutes les informations que le très bavard HTTP transmet, comme le montre bien le test de l'EFF. Bref, à l'heure actuelle, le serveur indiscret qui veut pister ses utilisateurs a bien des moyens plus puissants à sa disposition.

En revanche, si on utilise un système tout orienté vie privée, tel le Tor Browser, qui débraye beaucoup de services du Web trop indiscrets, et fait tout passer par Tor, alors, la durée des connexions QUIC pourrait devenir le maillon faible de la vie privée.

Pour Tor, le problème est à l'heure actuelle purement théorique puisque Tor ne transmet que TCP et que QUIC utilise UDP. Mais il pourrait se poser dans le futur, le projet Tor a d'ailleurs déjà réfléchi à cela dans le contexte de HTTP/2 (qui s'appelait SPDY à ses débuts).

Un client QUIC soucieux de ne pas être suivi à la trace peut donc, une fois qu'il a géré les problèmes bien plus énormes que posent les cookies et le fingerprinting, envisager des solutions comme de ne pas laisser les connexions QUIC durer trop longtemps et surtout ne pas utiliser la migration (qui permet de maintenir la connexion lorsque l'adresse IP change). Cela peut se faire en raccrochant délibérement la connexion, ou simplement en ne prévoyant pas de réserve de connection IDs (RFC 9000, section 5.1.1). Ceci dit, c'est plus facile à dire qu'à faire car une application n'est pas forcément informée rapidement d'un changement d'adresse IP de la machine. Et, évidemment, cela aura un impact négatif sur les performances totales.

La longue durée des connexions QUIC n'est pas le seul mécanisme par lequel un serveur pourrait suivre à la trace un client. QUIC permet à un client de mémoriser des informations qui lui permettront de se reconnecter au serveur plus vite (ce qu'on nomme le « 0-RTT »). Ces informations (qui fonctionnent exactement comme un cookie HTTP) permettent évidemment également au serveur de reconnaitre un client passé. Cette possibilité et ses conséquences parfois néfastes sont détaillées dans le RFC 9001, sections 4.5 et 9.1. Notez que cela existe également avec juste TLS (ce qu'on nomme le session resumption, RFC 8446, section 2.2) et avec le TCP Fast Open (RFC 7413), avec les mêmes conséquences sur la possibilité de suivi d'un client par le serveur. Le client QUIC qui voudrait protéger sa vie privée doit donc faire attention, quand il démarre une nouvelle connexion, à ne pas utiliser ces possibilités, qui le trahiraient (mais qui diminuent la latence ; toujours le compromis).

Comme souvent en sécurité, on est donc face à un compromis. Si on ne pensait qu'à la vie privée, on utiliserait Tor tout le temps… Les navigateurs Web, par exemple, optimisent clairement pour la vitesse, pas pour la vie privée.


L'article seul

L'Internet était-il en panne aujourd'hui ?

Première rédaction de cet article le 8 juin 2021


Aujourd'hui, entre 1015 et 1110 UTC, le CDN Fastly était en panne, provoquant des dysfonctionnements divers sur quelques sites Web connus. Je ne sais pas ce qui s'est passé, donc je ne vais pas vous l'expliquer mais je voudrais revenir sur la façon dont cet incident a été présenté dans les médias.

Car les titres sensationnalistes n'ont pas manqué, annonçant une panne massive du Web, voire de tout l'Internet ou au moins d'une grande partie. Des gens ont ricané en reprenant la légende comme quoi l'Internet avait été conçu pour résister à une attaque nucléaire ou déploré que l'Internet soit trop centralisé, ce qu'il n'est justement pas. La tonalité générale dans les médias était qu'il s'agissait d'une panne majeure de ce réseau informatique dont tant de choses dépendent. La réalité est très différente : l'Internet a très bien tenu, l'écrasante majorité des sites Web marchaient, quelques gros sites Web commerciaux avaient une drôle d'allure. Voici par exemple celui du Monde : fastly-outage-lemonde.png

L'Internet est le réseau informatique sous-jacent à toutes nos activités en ligne. Si des pannes partielles et localisées l'affectent souvent, il n'a jamais connu de panne généralisée, ou visible à l'échelle mondiale. Pendant l'incident avec Fastly, le courrier électronique passait comme d'habitude, les nœuds Bitcoin se tenaient au courant des transactions financières, les téléchargements BitTorrent se poursuivaient, les informaticiens se connectaient en SSH, les gens continuaient à bavarder sur Signal ou Matrix, et les utilisateurs de Gemini regardaient du contenu en ligne.

Et le Web ? Si l'Internet est l'infrastructure sous-jacente, le Web est l'application la plus connue, et même la seule connue de la plupart des gens qui ont le monopole de l'accès aux médias officiels. En tout cas, le Web marchait comme d'habitude. Des millions de sites Web (comme celui que vous visitez en ce moment) n'ont eu aucun problème. Une infime minorité, ceux qui avaient du contenu sur le CDN Fastly était, soit inaccessible, soit affichait une apparence curieuse car, si le code HTML était bien chargé par le navigateur, les feuilles de style ou le JavaScript ne suivaient pas. C'est pour cela que la page d'accueil de GitHub était bizarre : fastly-outage-github.png

D'accord, ces gros sites Web commerciaux étaient souvent des sites visibles et connus. Mais même comme cela, Fastly n'est pas le seul fournisseur de CDN et beaucoup d'autres sites continuaient à fonctionner. Il faut arrêter cette présentation erronée comme quoi une poignée de sites Web connus sont « l'Internet » comme cela a souvent été dit.

Des gens ont reproché à ces sites de n'avoir pas de redondance, de dépendre entièrement d'un seul CDN. Mais c'est un détail. Le point important est que les pannes arrivent. On ne peut pas les empêcher toutes. Ce qu'il faut, c'est éviter qu'elles aient des conséquences trop étendues. Il ne faut pas se poser la question de la robustesse de GitHub, il faut au contraire faire en sorte que toute l'activité de programmation mondiale ne cesse pas quand GitHub est en panne. Il faut des milliers de GitLab ou de Gitea, un système réellement décentralisé, où il n'y aura aucun site qui concentrera toute une activité.

Le lendemain, Fastly a publié une explication (sommaire) sur la panne. Notons qu'en attendant cette explication, les médias n'ont pas hésité à avancer des théories fumeuses comme France Inter qui a mis en cause « les serveurs DNS » alors qu'il n'y avait jamais eu aucune indication en ce sens.

Pour se détendre, Natouille avait lancé sur le fédivers (tiens, encore un système décentralisé et qui n'a donc pas eu de problème global) le mot-croisillon « #ExpliqueLaPanneInternet ». Vous pouvez consulter les très amusantes « explications » de la panne sur n'importe quelle instance du fédivers.


L'article seul

Fiche de lecture : Cosmogonies

Auteur(s) du livre : Julien d'Huy
Éditeur : La Découverte
978-2-348-05966-7
Publié en 2020
Première rédaction de cet article le 3 juin 2021


Il y a longtemps que les folkloristes et les ethnologues ont remarqué des ressemblances troublantes entre des contes et des mythes chez des peuples très lointains. De nombreuses explications ont été proposées. L'auteur, dans ce gros livre très technique, détaille une de ces explications : les mythes ont une origine commune, remontant parfois à des milliers d'années. Il explique ensuite comment étayer cette explication avec des méthodes proches de celles de la phylogénie.

Un exemple frappant est donné par le récit que vous connaissez peut-être grâce à l'Odyssée. Le cyclope Polyphème garde des troupeaux d'animaux. Ulysse et ses compagnons sont capturés par lui et dévorés un à un. Ulysse réussit à aveugler le cyclope en lui brûlant son œil puis s'échappe de la grotte où il était prisonnier en se cachant sous un mouton. Des récits très proches se trouvent chez des peuples qui n'ont aucun lien avec les Grecs de l'Antiquité, notamment chez des Amérindiens, complètement séparés des Européens bien avant Homère. On peut penser à une coïncidence mais de telles ressemblances sont quand même bien fréquentes. On peut aussi se dire que l'unicité physique de l'espèce humaine se traduit par une mentalité identique, et donc une unité des mythes. Mais si les ressemblances sont fréquentes, il y a aussi des différences. Par exemple, lorsqu'on fait des catalogues de mythes, l'Afrique est souvent à part. Si on a un peu bu, on peut aussi imaginer que des extra-terrestres ou bien un être surnaturel ont raconté les mêmes mythes à tous les humains. L'auteur part d'une autre hypothèse : les mythes actuels sont le résultat de l'évolution de mythes très anciens, qui ont divergé à partir d'une souche commune.

La théorie elle-même est ancienne. Mais comment l'étayer ? On peut remarquer que, pour les différentes versions d'un même mythe, des sous-groupes semblent se dessiner. par exemple, dans le mythe de Polyphème, les variantes américaines sont proches les unes des autres, et assez distinctes des variantes eurasiatiques (par exemple, en Amérique, le cyclope est remplacé par un corbeau). Cela évoque fortement un arbre évolutif.

À partir de là, l'auteur utilise une méthode proche de la phylogénie. Les mythes sont découpés en éléments, un peu comme les gènes qu'on utilise en biologie, et on utilise les outils de la phylogénie pour établir des arbres phylogénétiques, dont on étudie ensuite la vraisemblance. Par exemple, les grands mouvements migratoires se retrouvent bien dans cette analyse, avec des mythes amérindiens qui forment un groupe distinct, mais néanmoins souvent rattaché à des mythes qu'on trouve en Asie. De même, les variations génétiques de l'espèce humaine se retrouvent souvent dans les arbres des mythes, non pas évidemment parce que tel ou tel gène dicterait les mythes qu'on raconte, mais parce que les humains font souvent de l'endogamie et que gènes et mythes se transmettent ensemble, au sein des mêmes groupes humains. La place particulière de l'Afrique s'expliquerait par l'ancienneté : Homo sapiens est sorti d'Afrique il y a longtemps et les mythes qu'il avait à ce moment ont tellement évolué qu'on ne les reconnait plus aujourd'hui. Bien, sûr, je schématise beaucoup. Comme souvent en sciences humaines, la situation est plus compliquée que cela, et vous devrez lire le livre pour en apprécier les nuances. D'autant plus que les sujets ethnologiques sont toujours politiquement sensibles, par exemple lorsque l'auteur explique le mythe assez commun du matriarcat originel par un mythe commun, pas par une réalité historique (les mythes ne disent pas la vérité, ils racontent une histoire…).

Un autre exemple de mythe courant est celui de la femme-oiseau. En gros, un homme (un mâle) surprend, souvent au bain, une femme-animal (souvent un oiseau), et cache sa part animale (son manteau de plumes, par exemple). Il peut ainsi la garder près de lui, jusqu'au jour où elle remet la main sur son plumage et peut ainsi se sauver. Là encore, on peut isoler ses élements (les « gènes »), les abstraire (femme-animal au lieu de femme-oiseau car, dans certaines variantes, l'animal est une chèvre ou un éléphant) et les mettre dans le logiciel de phylogénie qui va alors sortir un arbre. Comme toujours, en phylogénie, beaucoup dépend de certaines hypothèses (les paramètres donnés au logiciel) et il est donc important de regarder ensuite les résultats de la reconstruction phylogénétique à la lumière de la génétique, de la connaissance qu'on a des migrations humaines, et des découvertes archéologiques. Dans certains cas, on peut même retrouver la racine de l'arbre, c'est-à-dire le mythe originel.

Le livre n'est pas toujours facile à lire, à pas mal d'endroits, c'est davantage une exposition de résultats de recherche récents qu'un ouvrage de vulgarisation. Avoir fait de la bio-informatique et notamment de la phylogénie, et/ou des statistiques peut aider. Mais les mythes eux-mêmes sont fascinants puisque chacun est un moyen de plonger dans l'esprit de peuples lointains ou même disparus.

(J'ai reçu un message détaillant des critiques sévères à propos de ce livre. Je précise donc que je ne suis moi-même ni folkloriste, ni ethnologue, et que je ne faisais que rendre compte de ce que j'avais compris du livre lu. De toute façon, en sciences humaines, il est rare qu'il existe des consensus, même sur les choses les plus basiques. Je n'ai donc pas modifié mon article.)


L'article seul

RFC 8903: Use cases for DDoS Open Threat Signaling

Date de publication du RFC : Mai 2021
Auteur(s) du RFC : R. Dobbins (Arbor Networks), D. Migault (Ericsson), R. Moskowitz (HTT Consulting), N. Teague (Iron Mountain Data Centers), L. Xia (Huawei), K. Nishizuka (NTT Communications)
Pour information
Réalisé dans le cadre du groupe de travail IETF dots
Première rédaction de cet article le 31 mai 2021


Le travail autour de DOTS (DDoS Open Threat Signaling) vise à permettre la communication, pendant une attaque par déni de service, entre la victime et une organisation qui peut aider à atténuer l'attaque. Ce nouveau RFC décrit quelques scénarios d'utilisation de DOTS. Autrement, DOTS est normalisé dans les RFC 8811 et ses copains.

Si vous voulez un rappel du paysage des attaque par déni de service, et du rôle de DOTS (DDoS Open Threat Signaling) là-dedans, je vous recommande mon article sur le RFC 8612. Notre RFC 8903 ne fait que raconter les scénarios typiques qui motivent le projet DOTS.

Par exemple, pour commencer, un cas simple où le fournisseur d'accès Internet d'une organisation est également capable de fournir des solutions d'atténuation d'une attaque. Ce fournisseur (ITP dans le RFC, pour Internet Transit Provider) est sur le chemin de tous les paquets IP qui vont vers l'organisation victime, y compris ceux de l'attaque. Et il a déjà une relation contractuelle avec l'utilisateur. Ce fournisseur est donc bien placé, techniquement et juridiquement, pour atténuer une éventuelle attaque. Il peut déclencher le système d'atténuation, soit à la demande de son client qui subit une attaque, soit au contraire contre son client si celui-ci semble une source (peut-être involontaire) d'attaque. (Le RFC appelle le système d'atténuation DMS pour DDoS Mitigation Service ; certains opérateurs ont des noms plus amusants pour le DMS comme OVH qui parle d'« aspirateur ».)

Dans le cas d'une demande du client, victime d'une attaque et qui souhaite l'atténuer, le scénario typique sera qu'une machine chez le client (un pare-feu perfectionné, par exemple), établira une session DOTS avec le serveur DOTS inclus dans le DMS du fournisseur d'accès. Lorsqu'une attaque est détectée (cela peut être automatique, avec un seuil pré-défini, ou bien manuel), la machine du client demandera l'atténuation. Pendant l'atténuation, le client pourra obtenir des informations de la part du DMS du fournisseur. Si l'attaque se termine, le client pourra décider de demander l'arrêt de l'atténuation. Notez que la communication entre le client DOTS (chez la victime) et le serveur DOTS (chez le fournisseur d'accès) peut se faire sur le réseau « normal » (celui qui est attaqué) ou via un lien spécial, par exemple en 4G, ce qui sera plus cher et plus compliqué mais aura l'avantage de fonctionner même si l'attaque sature le lien normal.

Ce scénario simple peut aussi couvrir le cas du réseau domestique. On peut imaginer une box disposant de fonctions de détection d'attaques (peut-être en communiquant avec d'autres, comme le fait la Turris Omnia) et d'un client DOTS, pouvant activer automatiquement l'atténuation en contactant le serveur DOTS du FAI.

Le second cas envisagé est celui où le fournisseur d'accès n'a pas de service d'atténuation mais où le client (mettons qu'il s'agisse d'un hébergeur Web), craignant une attaque, a souscrit un contrat avec un atténuateur spécialisé (de nombreuses organisations ont aujourd'hui ce genre de services, y compris sans but lucratif). Dans ce cas, il faudra « détourner » le trafic vers cet atténuateur, avec des trucs DNS ou BGP, qui sont sans doute hors de portée de la petite ou moyenne organisation. L'accord avec l'atténuateur doit prévoir la technique à utiliser en cas d'attaque. Si c'est le DNS, la victime va changer ses enregistrements DNS pour pointer vers les adresses IP de l'atténuateur (attention au TTL). Si c'est BGP, ce sera à l'atténuateur de commencer à annoncer le préfixe du client (attention aux règles de sécurité BGP, pensez IRR et ROA), et au client d'arrêter son annonce. Le reste se passe comme dans le scénario précédent.


Téléchargez le RFC 8903


L'article seul

RFC 9038: Extensible Provisioning Protocol (EPP) Unhandled Namespaces

Date de publication du RFC : Mai 2021
Auteur(s) du RFC : J. Gould (VeriSign), M. Casanova (SWITCH)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 30 mai 2021


Le protocole EPP, qui sert notamment lors de la communication entre un registre (par exemple de noms de domaine) et son client, est extensible : on peut rajouter de nouveaux types d'objets et de nouvelles informations. Normalement, le serveur EPP n'envoie au client ces nouveautés que si le client a annoncé, lors de la connexion, qu'il savait les gérer. Et s'il ne l'a pas fait, que faire de ces données, ces unhandled namespaces ? Ce nouveau RFC propose de les envoyer quand même, mais dans un élément XML prévu pour des informations supplémentaires, et qui ne devrait donc rien casser chez le client.

Le but est de rester compatible avec l'EPP standard, tel que normalisé dans le RFC 5730. Prenons l'exemple de l'extension pour DNSSEC du RFC 5910. Comme toutes les extensions EPP, elle utilise les espaces de noms XML. Cette extension particulière est identifiée par l'espace de noms urn:ietf:params:xml:ns:secDNS-1.1. À l'établissement de la connexion, le serveur annonce les extensions connues :

    
<greeting 
    <svcMenu>
       ...
         <svcExtension>
            <extURI>urn:ietf:params:xml:ns:secDNS-1.1</ns0:extURI>

  

Et le client annonce ce qu'il sait gérer :


<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
 <command>
   <login>
...
    <svcs>
      <svcExtension><extURI>urn:ietf:params:xml:ns:secDNS-1.1</extURI></svcExtension>
...

  

(<svcExtension> est décrit dans le RFC 5730, sections 2.4 et 2.9.1.1). Ici, le serveur a annoncé l'extension DNSSEC et le client l'a acceptée. Tout le monde va donc pouvoir envoyer et recevoir des messages spécifiques à cette extension, comme l'ajout d'une clé :


   <extension>
      <update xmlns="urn:ietf:params:xml:ns:secDNS-1.1"> 
         <add xmlns="urn:ietf:params:xml:ns:secDNS-1.1">
            <dsData xmlns="urn:ietf:params:xml:ns:secDNS-1.1">
               ...
              <digest xmlns="urn:ietf:params:xml:ns:secDNS-1.1">076CF6DA3692EFE72434EA1322177A7F07023400E4D1A1F617B1885CF328C8AA</digest>
    ...

  

Mais, si le client ne gère pas une extension (et ne l'a donc pas indiquée dans son <login>), que peut faire le serveur s'il a quand même besoin d'envoyer des messages spécifiques à cette extension inconnue du client, ce unhandled namespace ? C'est particulièrement important pour la messagerie EPP (commande <poll>) puisque le serveur peut, par exemple, mettre un message dans la boite sans connaitre les capacités du client, mais cela peut affecter également d'autres activités.

La solution de notre RFC est d'utiliser un élément EPP déjà normalisé (RFC 5730, secton 2.6), <extValue>, qui permet d'ajouter des informations que le client ne pourra pas analyser automatiquement, comme par exemple un message d'erreur lorsque le serveur n'a pas pu exécuter l'opération demandée. Notre RFC étend cet <extValue> au cas des espaces de noms non gérés. Le sous-élément <value> contiendra l'élément XML appartenant à l'espace de noms que le client ne sait pas gérer, et le sous-élément <reason> aura comme contenu un message d'information dont la forme recommandée est NAMESPACE-URI not in login servicesNAMESPACE-URI est le unhandled namespace. Par exemple, le RFC cite un cas où le registre ne gère pas l'extension DNSSEC du RFC 5910 et répond :


<response>
   ...
      <extValue>
        <value>
           <secDNS:infData
               xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1">
             <secDNS:dsData>
                   ...
                   <secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest>
             </secDNS:dsData>
           </secDNS:infData>
        </value>
        <reason>
           urn:ietf:params:xml:ns:secDNS-1.1 not in login services
        </reason>
      </extValue>

  

(Le RFC a aussi un autre exemple, avec l'extension de rédemption du RFC 3915.)

Ce RFC ne change pas le protocole EPP : il ne fait que décrire une pratique, compatible avec les clients actuels, pour leur donner le plus d'informations possible. Toutefois, pour informer tout le monde, cette pratique fait l'objet elle-même d'une extension, urn:ietf:params:xml:ns:epp:unhandled-namespaces-1.0, que le serveur va inclure dans son <greeting> et que le client mettra dans sa liste d'extensions acceptées. (Cet espace de nom a été mis dans le registre IANA créé par le RFC 3688. L'extension a été ajoutée au registre des extensions EPP introduit par le RFC 7451.) De toute façon, le client a tout intérêt à inclure dans sa liste toutes les extensions qu'il gère et à regarder s'il y a des <extValue> dans les réponses qu'il reçoit (même si la commande EPP a été un succès) ; cela peut donner des idées aux développeurs sur des extensions supplémentaires qu'il serait bon de gérer. Quant au serveur, il est bon que son administrateur regarde s'il y a eu des réponses pour des unhandled namespaces et prenne ensuite contact avec l'administrateur du client pour lui signaler ce manque.

Notez que ce RFC s'applique aux extensions portant sur les objets manipulés en EPP (par exemple les noms de domaine) et à celles portant sur les séquences de commandes et de réponses EPP, mais pas aux extensions portant sur le protocole lui-même (cf. RFC 3735).

Question mises en œuvre de ce RFC, le SDK de Verisign inclut le code nécessaire (dans le fichier gen/java/com/verisign/epp/codec/gen/EPPFullExtValuePollMessageFilter.java). D'autre part, le registre du .ch utilise ce concept d'espaces de noms inconnus pour indiquer au BE les changements d'un domaine provoqués par l'utilisation du CDS du RFC 7344, puisque ces changements ne sont pas passés par EPP.


Téléchargez le RFC 9038


L'article seul

RFC 9022: Domain Name Registration Data (DNRD) Objects Mapping

Date de publication du RFC : Mai 2021
Auteur(s) du RFC : G. Lozano (ICANN), J. Gould, C. Thippeswamy (VeriSign)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 30 mai 2021


Le RFC 8909 normalisait un format générique pour les séquestres d'objets enregistrés dans un registre. Ce nouveau RFC 9022 précise ce format pour le cas spécifique des registres de noms de domaine (dont les objets enregistrés sont les noms de domaine, les contacts, les serveurs de noms, etc).

Rappelons que le but d'un séquestre est de permettre à un tiers de reprendre les opérations d'un registre (par exemple un registre de noms de domaine) en cas de défaillance complète de celui-ci. Pas juste une panne matérielle qui fait perdre des données, non, une défaillance grave, par exemple une faillite, qui fait que plus rien ne marche. Le registre doit donc envoyer régulièrement des données à l'opérateur de séquestre qui, au cas où la catastrophe survient, enverra ces données au nouveau registre, qui sera en mesure (en théorie…) de charger les données dans une nouvelle base et de reprendre les opérations. Sous quel format sont envoyées ces données ? Car il faut évidemment un format ouvert et documenté, pour que le nouveau registre ait pu développer un programme d'importation des données. C'est le but du RFC 8909 et de notre nouveau RFC 9022. Ils spécifient un format à base de XML (avec possibilité de CSV).

Par rapport au format générique du RFC 8909, notre RFC ajoute les objets spécifiques de l'industrie des noms de domaine (il est recommandé de réviser la terminologie du RFC 8499) :

  • Les noms de domaine, tels que manipulés en EPP selon le RFC 5731.
  • Les serveurs de noms (pour les registres où ils sont enregistrés comme objets séparés, ce qui n'est pas obligatoire), tels que gérés via EPP selon le RFC 5732.
  • Les contacts (le titulaire du nom de domaine, le contact technique avec qui on verra les problèmes DNS, etc), selon le modèle utilisé en EPP par le RFC 5733.
  • Les BE (Bureaux d'Enregistrement). Le cas est un peu différent car ils ne sont typiquement pas gérés via EPP puisque les sessions EPP sont justement établies par un BE, qui a donc dû être créé par un autre moyen.
  • Les noms spéciaux, qui sont des noms de domaine qui ne sont pas des noms de domaines habituels mais, par exemple, des gros mots dont l'enregistrement est interdit. En anglais, le sigle officiel est NNDN, qui veut récursivement dire NNDN's Not a Domain Name.
  • Les tables liées à IDN, pour les registres qui maintiennent des informations restreignant l'usage de ces noms de domaine en Unicode (cf. RFC 6927).
  • Certains paramètres de configuration des serveurs EPP du registre.
  • Des compteurs du nombre d'objets enregistrés.
  • Des objets qui sont importants pour le registre mais pas assez répandus pour avoir fait l'objet d'une normalisation.

Le format concret du séquestre se décline en deux « modèles », un en XML et un en CSV (RFC 4180), mais j'ai l'impression que le XML est nettement plus utilisé. Dans tous les cas :

  • Les dates sont au format du RFC 3339.
  • Les noms des pays sont les identificateurs à deux lettres de ISO 3166.
  • Les numéros de téléphone sont au format E.164.
  • Les adresses IP doivent suivre le format du RFC 5952. Pour IPv4, le RFC est vague, car il n'y a pas de format standard (vous ne verrez pas une seule adresse IP dans le RFC 791, que cite notre RFC…).

Pour CSV, chaque fichier CSV représente une table (les noms de domaine, les contacts, les serveurs de noms…) et chaque ligne du fichier un objet. Le modèle de données est décrit plus précisément en section 4.6. Voici un exemple d'une ligne extraite du fichier des noms de domaine, décrivant le domaine domain1.example, créé le 3 avril 2009, et dont le titulaire a pour identificateur (handle) registrantid :

domain1.example,Ddomain2-TEST,,,registrantid,registrarX,registrarX,clientY,2009-04-03T22:00:00.0Z,registrarX,clientY,2009-12-03T09:05:00.0Z,2025-04-03T22:00:00.0Z 
  

Les contacts seraient mis dans un autre fichier CSV, avec un fichier de jointure pour faire le lien entre domaines et contacts.

Et pour XML ? Il s'inspire beaucoup des éléments XML échangés avec EPP, par exemple pour la liste des états possibles pour un domaine. Voici un exemple (RDE = Registry Data Escrow, et l'espace de noms correspondant rdeDom est urn:ietf:params:xml:ns:rdeDomain-1.0) :


<rdeDom:domain>
      <rdeDom:name>jdoe.example</rdeDom:name>
      <rdeDom:roid>DOM03-EXAMPLE</rdeDom:roid>
      <rdeDom:status s="ok"/>
      <rdeDom:registrant>IZT01</rdeDom:registrant>
      <rdeDom:contact type="tech">IZT01</rdeDom:contact>
      <rdeDom:contact type="billing">IZT01</rdeDom:contact>
      <rdeDom:contact type="admin">IZT01</rdeDom:contact>
      <rdeDom:ns>
        <domain:hostObj>ns.jdoe.example</domain:hostObj>
      </rdeDom:ns>
      <rdeDom:clID>RAR03</rdeDom:clID>
      <rdeDom:crRr>RAR03</rdeDom:crRr>
      <rdeDom:crDate>2019-12-26T14:18:40.65647Z</rdeDom:crDate>
      <rdeDom:exDate>2020-12-26T14:18:40.509742Z</rdeDom:exDate>
</rdeDom:domain>

  

On voit que cela ressemble en effet beaucoup à ce qui avait été envoyé en EPP pour créer le domaine (cf. RFC 5731). Si vous voulez un exemple complet et réaliste, regardez les sections 14 et 15 du RFC.

Et voici un exemple de contact (RFC 5733) :

    
<rdeContact:contact>
      <rdeContact:id>IZT01</rdeContact:id>
      <rdeContact:status s="ok"/>
      <rdeContact:postalInfo type="loc">
        <contact:name>John Doe</contact:name>
        <contact:addr>
          <contact:street>12 Rue de la Paix</contact:street>
          <contact:city>Paris</contact:city>
          <contact:pc>75002</contact:pc>
          <contact:cc>FR</contact:cc>
        </contact:addr>
      </rdeContact:postalInfo>
      <rdeContact:voice>+33.0353011234</rdeContact:voice>
      <rdeContact:email>john.doe@foobar.example</rdeContact:email>
      <rdeContact:clID>RAR03</rdeContact:clID>
      <rdeContact:crRr>RAR03</rdeContact:crRr>
      <rdeContact:crDate>2019-12-26T13:47:05.580392Z</rdeContact:crDate>
      <rdeContact:disclose flag="0">
        <contact:name type="loc"/>
        <contact:addr type="loc"/>
        <contact:voice/>
        <contact:fax/>
        <contact:email/>
      </rdeContact:disclose>
</rdeContact:contact>

  

On notera l'élement <disclose> qui indique qu'on ne doit pas diffuser le nom, l'adresse ou d'autres éléments sur le contact (normal, il s'agit d'une personne physique, et la loi Informatique & Libertés s'applique, cf. section 14 du RFC). La jointure avec les domaines dont il est contact (comme le jdoe.example plus haut), se fait sur l'identificateur (élément <id>, dit aussi handle). L'information sur l'adresse a le type loc, ce qui veut dire qu'elle peut utiliser tout le jeu de caractères Unicode. Avec le type int, elle serait restreinte à l'ASCII (une très ancienne erreur fait que EPP appelle loc - local, ce qui est internationalisé et int - international ce qui est restreint aux lettres utilisées en anglais).

Et enfin, un objet représentant un serveur de noms (RFC 5732) :


<rdeHost:host>
      <rdeHost:name>ns1.foobar.example</rdeHost:name>
      <rdeHost:status s="ok"/>
      <rdeHost:addr ip="v6">2001:db8:cafe:fada::53</rdeHost:addr>
      <rdeHost:clID>RAR02</rdeHost:clID>
      <rdeHost:crRr>RAR02</rdeHost:crRr>
      <rdeHost:crDate>2020-05-13T12:37:41.788684Z</rdeHost:crDate>
</rdeHost:host>         

  

Ce format de séquestre permet aussi de représenter des objets qui n'ont pas d'équivalent en EPP, comme les bureaux d'enregistrement, qui ne peuvent pas être créés en EPP puisque la session EPP est liée au client du registre, donc au bureau d'enregistrement. Un exemple de BE (Bureau d'Enregistrement) :


<rdeRegistrar:registrar>
      <rdeRegistrar:id>RAR21</rdeRegistrar:id>
      <rdeRegistrar:name>Name Business</rdeRegistrar:name>
      <rdeRegistrar:status>ok</rdeRegistrar:status>
      <rdeRegistrar:postalInfo type="loc">
        <rdeRegistrar:addr>
          <rdeRegistrar:street>1 rue du Test</rdeRegistrar:street>
          <rdeRegistrar:city>Champignac</rdeRegistrar:city>
          <rdeRegistrar:cc>FR</rdeRegistrar:cc>
        </rdeRegistrar:addr>
      </rdeRegistrar:postalInfo>
      <rdeRegistrar:voice>+33.0639981234</rdeRegistrar:voice>
      <rdeRegistrar:fax>+33.0199001234</rdeRegistrar:fax>
      <rdeRegistrar:email>master-of-domains@namebusiness.example</rdeRegistrar:email>
</rdeRegistrar:registrar>    
 
  

On peut aussi mettre dans le séquestre des références vers ses tables IDN (que l'ICANN exige mais qui n'ont aucun intérêt). Plus intéressant, la possibilité de stocker dans le séquestre les listes de termes traités spécialement, par exemple interdits ou bien soumis à un examen manuel. Cela se nomme NNDN pour « NNDN's not domain name », oui, c'est récursif. Voici un exemple :


<rdeNNDN:NNDN>
     <rdeNNDN:uName>gros-mot.example</rdeNNDN:uName>
     <rdeNNDN:nameState>blocked</rdeNNDN:nameState>
     <rdeNNDN:crDate>2005-04-23T11:49:00.0Z</rdeNNDN:crDate>
   </rdeNNDN:NNDN>

  

Tous les registres n'ont pas les mêmes règles et le RFC décrit également les mécanismes qui permettent de spécifier dans le séquestre les contraintes d'intégrité spécifiques d'un registre. L'opérateur de séquestre, qui reçoit le fichier XML ou les fichiers CSV, est censé vérifier tout cela (autrement, il ne joue pas son rôle, s'il se contente de stocker aveuglément un fichier). La section 8 de notre RFC décrit plus en profondeur les vérifications recommandées, comme de vérifier que les contacts indiqués pour chaque domaine sont bien présents. Pour vérifier un séquestre, il faut importer beaucoup de schémas. Voici, la liste, sous forme d'une commande shell :

for schema in contact-1.0.xsd  host-1.0.xsd		rdeDomain-1.0.xsd     rdeIDN-1.0.xsd	    rgp-1.0.xsd domain-1.0.xsd	 rde-1.0.xsd		rdeEppParams-1.0.xsd  rdeNNDN-1.0.xsd	    secDNS-1.1.xsd epp-1.0.xsd	 rdeContact-1.0.xsd	rdeHeader-1.0.xsd     rdePolicy-1.0.xsd   eppcom-1.0.xsd	 rdeDnrdCommon-1.0.xsd	rdeHost-1.0.xsd       rdeRegistrar-1.0.xsd); do
   wget https://www.iana.org/assignments/xml-registry/schema/${schema}
done   
  

Ensuite, on importe (fichier escrow-wrapper.xsd) et on utilise xmllint sur l'exemple de séquestre de la section 14 du RFC (fichier escrow-example.xml) :

% xmllint --noout --schema wrapper.xsd escrow-example.xml                            
escrow-example.xml validates
  

Ouf, tout va bien, le registre nous a envoyé un séquestre correct.

Enfin, la syntaxe formelle de ce format figure dans la section 9 du RFC, dans le langage XML Schema.

Ce format est mis en œuvre par tous les TLD qui sont liés par un contrat avec l'ICANN. 1 200 TLD envoient ainsi un séquestre une fois par semaine à l'ICANN.

Le concept de séquestre pose de sérieux problèmes de sécurité car le ou les fichiers transmis sont typiquement à la fois confidentiels, et cruciaux pour assurer la continuité de service. Lors du transfert du fichier, le registre et l'opérateur de séquestre doivent donc vérifier tous les deux l'authenticité du partenaire, et la confidentialité de la transmission. D'autant plus qu'une bonne partie du fichier est composée de données personnelles.


Téléchargez le RFC 9022


L'article seul

Le spin bit de QUIC

Première rédaction de cet article le 28 mai 2021


Une bonne partie du travail à l'IETF sur le protocole QUIC avait tourné autour d'un seul bit de l'en-tête QUIC, le spin bit. Pourquoi ?

Ce bit intéressant apparait dans les paquets QUIC à en-tête court (cf. le RFC 9000), et a agité énormément d'électrons lors des discussions à l'IETF. Pour comprendre ces polémiques, il faut voir à quoi sert ce bit. Avec TCP, quelqu'un qui surveillait le réseau pouvait calculer un certain nombre de choses sur la connexion TCP, comme le RTT, par exemple, en observant le délai entre un octet et l'accusé de réception couvrant cet octet. Cela peut être utilisé pour régler le réseau de manière à améliorer les performances (mais ne rêvez pas : contrairement à ce qui a parfois été prétendu, aucun FAI ne va vous informer de la santé de vos connexions individuelles, ni vous aider à les optimiser). Mais c'est également un problème de vie privée (toute information que vous envoyez sur le réseau peut être utilisée à mauvais escient). L'une des idées fortes de QUIC est de réduire la vue présentée au réseau (RFC 8546) et donc de chiffrer au maximum ; avec QUIC, on ne peut plus trouver le RTT en examinant les paquets qui passent. Cela peut être un problème si on souhaite justement informer le réseau et les gens qui le gèrent. Le spin bit a donc pour but de donner un minimum d'informations explicitement (alors qu'avec TCP, on donne plein d'informations sans s'en rendre compte). Ce spin bit est public (il n'est pas dans la partie chiffrée du paquet) et est inversé par l'initiateur de la connexion à chaque aller-retour (section 17.4 du RFC). Cela permet donc d'estimer le RTT. Cette utilisation est par exemple mise en œuvre dans le programme spindump.

Ce spin bit est optionnel, puisqu'on a vu qu'il pouvait être mal utilisé. Le RFC précise qu'une mise en œuvre de QUIC doit permettre sa désactivation, globalement ou par connexion. Il ajoute que, même si le spin bit est activé, QUIC doit le débrayer pour au moins une connexion sur seize, choisie au hasard, pour que les gens qui veulent être discrets et donc coupent le spin bit ne soient pas trop séparables des autres. C'est un principe classique en protection de la vie privée : il ne faut pas se distinguer. Pendant une enquête de police, les gens qui ont éteint leur ordiphone peu avant les faits seront les premiers suspects…

Cet unique bit a suscité beaucoup de discussions pour sa petite taille. Si vous voulez en apprendre d'avantage, vous pouvez consulter l'Internet-Draft draft-andersdotter-rrm-for-rtt-in-quic (une technique compliquée mais qui contient une bonne explication du spin bit), ou bien le draft-martini-hrpc-quichr qui, globalement, était très enthousiaste en faveur de QUIC mais suggèrait la suppression du spin bit. Merci d'ailleurs à leurs auteurs, pour leurs explications qui m'ont beaucoup aidé. Il y a également l'article « Three Bits Suffice: Explicit Support for Passive Measurement of Internet Latency in QUIC and TCP » (la version finale du spin bit est différente mais l'article explique bien le principe).


L'article seul

Le protocole QUIC désormais normalisé

Première rédaction de cet article le 28 mai 2021


Le protocole de transport QUIC vient d'être normalisé, sous la forme de plusieurs RFC. QUIC, déjà largement déployé, peut changer pas mal de choses sur le fonctionnement de l'Internet, en remplaçant, au moins partiellement, TCP.

Je vais décrire les RFC en question plus longuement dans des articles spécifiques à chacun mais cet article est consacré à une vision de plus haut niveau : c'est quoi, QUIC, et à quoi ça sert ?

QUIC n'est pas un protocole d'application comme peuvent l'être HTTP ou SSH. Les utilisateurs ordinaires ne verront pas la différence, ils se serviront des mêmes applications, via les mêmes protocoles applicatifs. QUIC est un protocole de transport, donc un concurrent de TCP, dont il vise à résoudre certaines limites, notamment dans le contexte du Web. Quelles limites ? Pour comprendre, il faut revenir à ce à quoi sert la couche de transport (couche 4 du traditionnel modèle en couches). Placée entre les datagrammes d'IP, qui peuvent arriver ou pas, dans l'ordre ou pas, et les applications, qui comptent en général sur un flux d'octets ordonnés, où rien ne manque, la couche transport est chargée de surveiller l'arrivée des paquets, de signaler à l'émetteur qu'il en manque, qu'il puisse réémettre, et de mettre dans le bon ordre les données. Dit comme ça, cela semble simple, mais cela soulève beaucoup de problèmes intéressants. Par exemple, il ne faut pas envoyer toutes les données sans réfléchir : le réseau n'est peut-être pas capable de les traiter, et un envoi trop brutal pourrait mener à la congestion. De même, en cas de pertes de paquet, il faut certes ré-émettre, mais aussi diminuer le rythme d'envoi, la perte pouvant être le signal que le réseau est saturé. C'est à la couche transport de gérer cette congestion, en essayant de ne pas la déclencher, ou en tout cas de ne pas l'aggraver. En pratique, la couche transport est donc très complexe, comme le montre le nombre de RFC sur TCP. Si la norme de base reste le vieux RFC 793, de nombreux autres RFC sont également à prendre en compte (le RFC 7414 vous fournit une liste commentée, mais qui n'est plus à jour).

Maintenant que nous avons révisé les tâches de la couche transport, quelles sont ces limites de TCP dont je parlais, et qui justifient le développement de QUIC ? Notez d'abord qu'elles ont surtout été mentionnées dans le contexte du Web. Celui-ci pose en effet des problèmes particuliers, notamment le désir d'une faible latence (quand on clique, on veut une réponse tout de suite) et le fait que l'affichage d'une seule page nécessite le chargement de plusieurs ressources (images sans intérêt, vidéos agaçantes, code JavaScript pour faire bouger des trucs, CSS, etc). La combinaison de TCP et de TLS n'est pas satisfaisante question latence, puisqu'il faut d'abord établir la connexion TCP, avant de pouvoir commencer la négociation qui mènera à l'établissement de la session TLS (il existe des solutions partielles comme le TCP Fast Open du RFC 7413, mais qui n'est pas protégé par la cryptographie, ou la session resumption du RFC 8446, section 2.2). Ensuite, TCP souffre du manque de parallélisme : quand on veut récupérer plusieurs ressources, il faut soit ouvrir plusieurs connexions TCP, qui ne partageront alors plus d'information (RTT, taux de perte, etc) ou de calculs (cryptographie…), et consommeront potentiellement beaucoup de ports, soit multiplexer à l'intérieur d'une connexion TCP, ce que fait HTTP/2 (RFC 7540) mais, alors, on risque le head-of-line blocking, où la récupération d'une ressource bloque les suivantes, et le fait que la perte d'un seul paquet va faire ralentir tous les téléchargements. Cela ne veut pas dire que TCP est complètement dépassé : largement testé au feu depuis de nombreuses années, il déplace chaque jour d'innombrables octets, pour des connexions qui vont de la courte page HTML à des fichiers de plusieurs giga-octets.

Quels sont les concepts de base de QUIC ? QUIC gère des connexions entre machines, comme TCP. Par contre, contrairement à TCP, ces connexions portent ensuite des ruisseaux (streams) séparés, ayant leur propre contrôle de congestion, en plus du contrôle global à la connexion. Les ruisseaux peuvent être facilement et rapidement créés. Ce n'est pas par hasard que le concept ressemble à celui des ruisseaux de HTTP/2 (RFC 7540), dans les deux cas, le but était de s'adapter au désir des navigateurs Web de charger toutes les ressources d'une page en parallèle, sans pour autant « payer » l'établissement d'une connexion pour chaque ressource.

Avec QUIC, le chiffrement est obligatoire. Il n'y a pas de version de QUIC en clair. Non seulement les données applicatives sont chiffrées, comme avec TLS ou SSH mais une bonne partie de la couche transport l'est également. Pourquoi ?

  • En raison de la prévalence de la surveillance massive sur l'Internet (RFC 7258) ; moins on expose de données, moins il y a de risques.
  • Afin d'éviter que les middleboxes ne se croient capables d'analyser le fonctionnement de la couche transport, et ne se croient autorisées à y intervenir, ce qui mène à une ossification de l'Internet. Si tout est chiffré, on pourra faire évoluer le protocole sans craindre l'intervention de ces fichus intermédiaires.
  • Certains FAI ont déjà exploité le caractère visible de TCP (RFC 8546) pour des attaques, par exemple en envoyant des paquets RST (ReSeT) pour couper le trafic BitTorrent. TLS et SSH ne protègent pas contre ce genre d'attaques. (Mais QUIC ne protège pas complètement ; le problème est difficile car il faut bien permettre aux machines terminales de réclamer une coupure de la connexion.)
  • L'observation de la couche transport peut permettre d'identifier les services utilisés et d'en dé-prioritiser certains. Le chiffrement du transport peut donc aider à préserver la neutralité du réseau.

On peut prévoir que les habituels adversaires du chiffrement protesteront d'ailleurs contre QUIC, en l'accusant de gêner la visibilité (ce qui est bien le but). Voir par exemple le RFC 8404 et même le RFC 9065. On voit ainsi un fabricant de produits de sécurité qui conseille carrément de bloquer QUIC. Qu'est-ce que vont dire ces adversaires du chiffrement lorsqu'on aura des VPN sur QUIC, comme ce sur quoi travaille le bien nommé groupe MASQUE !

QUIC utilise le classique protocole TLS (RFC 8446) pour le chiffrement mais pas de la manière habituelle. Normalement, TLS fait la poignée de main initiale, l'échange des clés et le chiffrement des données. Avec QUIC, TLS ne fait que la poignée de main initiale et l'échange des clés. Une fois les clés obtenues, QUIC chiffrera tout seul comme un grand, en utilisant les clés fournies par TLS.

Puisqu'on a parlé des middleboxes : déployer un nouveau protocole de transport dans l'Internet d'aujourd'hui est très difficile, en raison du nombre d'équipements qui interfèrent avec le trafic (les routeurs NAT, par exemple). Conceptuellement, QUIC aurait pu tourner directement sur IP. Mais il aurait alors été bloqué dans beaucoup de réseaux. D'où le choix de ses concepteurs de le faire passer sur UDP. (Le protocole de transport SCTP avait eu ce problème et a dû se résigner à la même solution, cf. RFC 6951.) QUIC utilise UDP comme il utiliserait IP. On lit parfois que QUIC, ce serait « HTTP au-dessus d'UDP », mais c'est une grosse incompréhension. QUIC est une couche de transport complète, concurrente de TCP, dont le fonctionnement sur UDP n'est qu'un détail nécessaire au déploiement. QUIC n'a aucune des propriétés d'UDP. Par exemple, comme TCP, mais contrairement à UDP, QUIC teste la réversibilité du trafic, ce qui empêche l'usurpation d'adresses IP et toutes les attaques UDP qui reposent dessus.

QUIC est parfois présenté comme « tournant en mode utilisateur et pas dans le noyau (du système d'exploitation) ». En fait, ce n'est pas spécifique à QUIC. Tout protocole de transport peut être mis en œuvre en mode utilisateur ou noyau (et il existe des mises en œuvre de TCP qui fonctionnent en dehors du noyau). Mais il est exact qu'en pratique la plupart des mises en œuvre de QUIC ne sont pas dans le noyau du système, l'expérience prouvant que les mises à jour du système sont souvent trop lentes, par rapport au désir de faire évoluer en permanence la couche transport. Ceci dit, la norme ne l'impose pas et n'en parle même pas. (On peut ajouter aussi que, dans beaucoup de systèmes d'exploitation, il est plus facile à un programme utilisateur de tourner sur UDP que directement sur IP. Par exemple, sur Unix, tourner directement sur IP nécessite d'utiliser les prises brutes et donc d'être root.) Et puis, sur Windows, Google n'aime pas dépendre de Microsoft pour les performances de son navigateur.

Pour résumer les différences entre QUIC et TCP (rappelez-vous qu'ils assurent à peu près les mêmes fonctions) :

  • QUIC est systématiquement chiffré,
  • QUIC permet un vrai multiplexage ; la requête lente ne bloque pas la rapide, et la perte d'un paquet ne ralentit pas tous les ruisseaux multiplexés,
  • QUIC fusionne transport et chiffrement, ce qui permet notamment de diminuer la latence à l'établissement de la connexion,
  • QUIC permet la migration d'une connexion en cas de changement d'adresse IP (je n'en ai pas parlé ici, voir RFC 9000).

Les RFC normalisant QUIC sont :

  • RFC 9000 est la norme principale, décrivant le socle de base de QUIC,
  • RFC 9001 normalise l'utilisation de TLS avec QUIC,
  • RFC 9002 spécifie les mécanismes de récupération de QUIC, quand des paquets sont perdus et qu'il faut ré-émettre, sans pour autant écrouler le réseau,
  • RFC 8999 est consacré aux invariants de QUIC, aux points qui ne changeront pas dans les nouvelles versions de QUIC.

J'ai dit que QUIC, comme TCP, est un protocole de transport généraliste, et qu'on peut faire tourner plusieurs applications différentes dessus. En pratique, QUIC a été conçu essentiellement en pensant à HTTP mais dans le futur, d'autres protocoles pourront profiter de QUIC, notamment s'ils ont des problèmes qui ressemblent à ceux du Web (désir de faible latence, et de multiplexage).

Pour HTTP, la version de HTTP qui tourne sur QUIC se nomme HTTP/3 et sera normalisée plus tard. Comme HTTP/2 (RFC 7540), HTTP/3 a un encodage binaire mais il ne fait plus de multiplexage, celui-ci étant désormais assuré par QUIC. Pour d'autres protocoles, les curieux pourront s'intéresser à SMB (déjà géré par Wireshark), au DNS (draft-ietf-dprive-dnsoquic) ou SSH (draft-bider-ssh-quic). En moins sérieux, il y a même eu des discussions pour mettre IRC sur QUIC, mais ce n'est pas allé très loin.

QUIC a eu une histoire longue et compliquée. À l'origine, vers 2012, QUIC était un projet Google (documenté dans « QUIC: Multiplexed Transport Over UDP », article qui ne reflète pas le QUIC actuel). Si les motivations étaient les mêmes que celles du QUIC actuel, et que certains concepts étaient identiques, il y avait quand même deux importantes différences techniques : le QUIC de Google utilisait un protocole de cryptographie spécifique, au lieu de TLS, et il était beaucoup plus marqué pour son utilisation par HTTP uniquement. Et il y a aussi bien sûr une différence politique, QUIC était un protocole privé d'une entreprise particulière, il est maintenant une norme IETF. Le travail à l'IETF a commencé en 2016 à la réunion de Séoul. Les discussions à l'IETF ont été chaudes et prolongées, vu l'importance du projet. Après tout, il s'agit de remplacer, au moins partiellement, le principal protocole de transport de l'Internet. C'est ce qui explique qu'il se soit écoulé plus de quatre ans entre le premier projet IETF et ces RFC. Vous pouvez avoir une idée de ce travail en visitant le site Web du groupe de travail ou en admirant les milliers de tickets traités.

Questions mises en œuvre de QUIC (elles sont nombreuses), je vous renvoie à mon article sur le RFC 9000. Le déploiement de QUIC a commencé il y a longtemps puisque Google l'avait déjà mis dans Chrome et ses services. En 2017, Google annonçait que QUIC représentait déjà 7 % du trafic vers ses serveurs. Bon, c'était le QUIC de Google, on va voir ce que cela va donner pour celui de l'IETF, mais le point important est que le déploiement n'a pas attendu les RFC.

Quelques lectures sur QUIC :


L'article seul

Articles des différentes années : 2021  2020  2019  2018  2017  2016  2015  Précédentes années

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

Un article de ce blog au hasard.