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.


Fiche de lecture : Concealing for freedom

Auteur(s) du livre : Ksenia Ermoshina, Francesca Musiani
Éditeur : Mattering Press
Publié en 2022
Première rédaction de cet article le 25 mai 2022


Le chiffrement est depuis longtemps un sujet de controverses. Indispensable pour assurer la sécurité des communications sur les réseaux informatiques (donc, tous les réseaux, y compris le téléphone), il est régulièrement attaqué par des politiciens qui l'accusent de permettre aux délinquants et aux criminels de dissimuler leurs communications. Mais il n'y a pas que ces attaques grossières, il y a aussi beaucoup de débats autour du chiffrement et de la meilleure façon de protéger les communications de M. et Mme Toutlemonde. Ce livre de deux chercheuses en sociologie explore de manière très claire mais aussi très approfondie ces débats. En bref, le chiffrement est nécessaire mais pas forcément suffisant. Ce livre est très recommandé à toutes les personnes qui veulent comprendre ce difficile problème.

Notez tout de suite avant d'acheter la version papier du livre qu'il est également gratuitement disponible en ligne. Même si vous achetez la version papier, la version numérique vous intéressera peut-être, par exemple pour rechercher un mot, ou pour copier-coller une citation.

Les informaticien·nes ont parfois tendance à avoir une approche strictement technique du chiffrement. On chiffre, et on est protégé, et les seuls débats concernent des points tels que « dois-je utiliser ECDSA ou EdDSA ? ». Mais les auteures montrent bien que bien d'autres questions se posent, et peuvent affecter la sécurité des communications. Par exemple, le livre contient une analyse du modèle de menaces. On veut se cacher de qui ? Le problème d'une militante féministe en Russie n'est pas forcément le même que celui d'un journaliste qui couvre des manifestations aux États-Unis ou que celui d'une femme qui veut se protéger d'un mari violent. L'adversaire n'a pas les mêmes moyens, et le niveau de risque est différent à chaque fois. Ainsi, de manière peut-être contre-intuitive, il peut être plus prudent d'utiliser un logiciel moins sûr, mais plus répandu, pour ne pas attirer l'attention. (Ce chapitre, comme d'autres dans le livre, est repris d'un précédent article des auteures.)

Le livre s'appuie sur beaucoup d'ateliers et de formations où les auteures ont participé. Ici, un dessin du modèle de menaces par une militante russe lors d'un de ces ateliers, montrant les différents ennemis : modele-menace.jpg

Dans bien des cas, le choix du système le plus sûr n'a pas de solution évidente, d'autant plus que bien des critères de choix se bousculent. Un chapitre est ainsi consacré au débat centralisation/décentralisation. Un système de communication centralisé est-il plus sûr ? La réponse n'est pas simple. Un système décentralisé a l'avantage de ne pas avoir de point de contrôle unique, susceptible d'être piraté, corrompu, ou soumis à des pressions financières ou juridiques. Utilisant des techniques standardisées, il est indépendant de tout fournisseur. Il règle de manière élégante la question du pouvoir et de ses abus en limitant la quantité de pouvoir dont dispose chaque acteur. Mais il a aussi des inconvénients : difficulté à faire évoluer techniquement (exemple du courrier électronique, réseau social décentralisé bien antérieur aux réseaux centralisés des GAFA, mais qui a du mal à déployer massivement des techniques de sécurité nouvelles), difficulté pour les utilisateurs à comprendre à qui il faut faire confiance (l'administrateur d'un serveur décentralisé n'est pas forcément « meilleur » que Gmail), risque d'invasion par des parasites contre lesquels il sera difficile de lutter (pensez au spam). Les auteures ne disent évidemment pas qu'il faut préférer les systèmes centralisés, simplement que le choix de la sécurité n'est pas toujours simple. (Une bonne partie du chapitre est consacrée aux controverses autour de Signal et du discours très pro-centralisation de son créateur, mais il parle aussi de systèmes moins connus comme Briar.) Et les arguments techniques cachent souvent des volontés de contrôle. Et parfois c'est la technique qui rend certaines solutions difficiles (faire du chiffrement de bout en bout est plus difficile si on veut des communications de groupe, faire de la distribution de message sans serveur est plus difficile si on veut épargner les batteries, etc).

La fédération (telle qu'utilisée par le fédivers) est souvent présentée comme la solution au problème du contrôle de la communication par quelques géants. Mais elle aussi pose ses propres problèmes, comme l'ont montré les difficultés de XMPP et Matrix à vaincre les messageries instantanées privatrices.

En parlant de messageries instantanées, un des chapitres les plus intéressants concerne l'analyse qu'avait publiée l'EFF pour aider les utilisateurices à choisir une messagerie instantanée sûre. La première version avait suscité de nombreuses critiques (pas toutes innocentes, et pas toutes intelligentes), portant par exemple sur la prépondérance excessive de critères purement techniques, ou s'inquiétant du fait de résumer un choix aussi complexe à un simple tableau de critères. Les auteurs détaillent longuement ces débats, et comment ils ont mené à une sérieuse réflexion sur la meilleure manière d'informer les utilisateurices.

Le livre est clairement écrit, et les auteures connaissent leur sujet (j'ai apprécié que le fédivers ne soit pas juste appelé Mastodon et que Pleroma soit aussi cité). Si vous croyez que le problème est simple, et que vous vous exprimez sèchement à ce sujet sur les réseaux sociaux, c'est le livre à lire d'abord.


L'article seul

RFC 9234: Route Leak Prevention and Detection Using Roles in UPDATE and OPEN Messages

Date de publication du RFC : Mai 2022
Auteur(s) du RFC : A. Azimov (Qrator Labs & Yandex), E. Bogomazov (Qrator Labs), R. Bush (IIJ & Arrcus), K. Patel (Arrcus), K. Sriram (USA NIST)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 25 mai 2022


Vous savez sans doute que l'Internet repose sur le protocole de routage BGP et que ce protocole a été cité dans des accidents (voire des attaques) spectaculaires, par exemple lorsqu'un routeur BGP annonçait ou réannonçait des routes qu'il n'aurait pas dû annoncer (ce qu'on nomme une fuite de routes). Si BGP lui-même est pair-à-pair, en revanche, les relations entre les pairs ne sont pas forcément symétriques et des règles sont largement admises ; par exemple, on n'est pas censé annoncer à un transitaire des routes apprises d'un autre transitaire. Ce RFC étend BGP pour indiquer à l'ouverture de la session le type de relations qu'on a avec son pair BGP, ce qui permet de détecter plus facilement certaines fuites de routes.

La solution proposée s'appuie sur un modèle des relations entre opérateurs, le modèle « sans vallée » (valley-free, même si ce terme n'est pas utilisé dans le RFC). On le nomme aussi modèle Gao-Rexford. Ce modèle structure ces relations de telle façon à ce que le trafic aille forcément vers un opérateur aussi ou plus important (la « montagne »), avant de « redescendre » vers la destination ; le trafic ne descend pas dans une « vallée », sauf si elle est la destination finale. Le but est de permettre un routage optimum et d'éviter boucles et goulets d'étranglement, mais ce modèle a aussi une conséquence politico-économique, maintenir la domination des gros acteurs (typiquement les Tier-1). Les relations entre participants à une session BGP sont de type Client-Fournisseur ou Pair-Pair, et le trafic va toujours dans le sens du client vers le fournisseur, sauf pour les destinations finales (on n'utilise donc pas un pair pour du transit, c'est-à-dire pour joindre d'autres réseaux que ceux du pair).

En raison de ce modèle, un routeur BGP n'est pas censé annoncer à un transitaire des routes apprises d'un autre transitaire, ou annoncer à un pair des routes apprises d'un transitaire, ou bien apprises d'un autre pair (RFC 7908). Une fuite de routes est une annonce qui viole cette politique (qu'elle soit explicite ou implicite).

Traditionnellement, on empêche ces fuites par des règles dans la configuration du routeur. Par exemple, le client d'un transitaire va bloquer l'exportation par défaut, puis lister explicitement les routes qu'il veut annoncer. Et le transitaire va bloquer l'importation par défaut, et lister ensuite les routes qu'il acceptera de son client. Ce nouveau RFC ajoute un autre mécanisme, où la relation entre les deux partenaires BGP est explicitement marquée comme Client-Fournisseur ou Pair-Pair, facilitant la détection des fuites. Un concept qui était auparavant purement business, le type de relation entre acteurs BGP, passe ainsi dans le protocole.

Le RFC utilise donc ces termes, pour désigner la place d'un acteur BGP dans le processus de routage :

  • Fournisseur (Provider) : peut envoyer n'importe quelle route (un transitaire est un Fournisseur).
  • Client (Customer) : ne peut envoyer que ses propres routes, ou bien celles apprises d'un de ses clients (l'opérateur qui est Client pour une relation BGP peut être Fournisseur pour une autre).
  • Serveur de routes (Route Server) : peut envoyer toutes les routes qu'il connait à ses clients.
  • Client d'un serveur de routes (Route Server Client) : ne peut envoyer au serveur de routes que ses propres routes, ou bien celles apprises d'un de ses clients.
  • Pair (Peer) : ne peut envoyer à un de ses pairs que ses propres routes, ou bien celles apprises d'un de ses clients.

Une violation de ces règles est une fuite de routes (RFC 7908). Le RFC précise qu'il s'agit de relations « techniques », qu'elles n'impliquent pas forcément une relation business mais, en pratique, l'échange entre pairs est souvent gratuit et la relation Client-Fournisseur payante. Le RFC précise aussi qu'il peut exister des cas plus complexes, comme une relation Client-Fournisseur pour certains préfixes IP et Pair-Pair pour d'autres.

Bon, assez de politique et de business, place à la technique et au protocole. Le RFC définit une nouvelle capacité (RFC 5492) BGP, Role, code 9 et dont la valeur, stockée sur un octet, indique un des rôles listés ci-dessus (0 pour Fournisseur, 3 pour Client, 4 pour Pair, etc). D'autres rôles pourront être ajoutés dans le futur (politique « Examen par l'IETF », cf. RFC 8126). Ce rôle indique la place de l'AS et est configuré avec la session BGP (rappelez-vous qu'un AS peut être Client d'un côté et Fournisseur de l'autre). À l'ouverture de la connexion, les routeurs vérifient la compatibilité des rôles (si tous les deux annoncent qu'ils sont Fournisseur, c'est un problème, d'où un nouveau code d'erreur BGP, Role mismatch).

Une fois que les deux routeurs sont d'accord sur les rôles respectifs de leurs AS, les routes annoncées peuvent être marquées avec un nouvel attribut, OTC (Only To Customer, code 35), dont la valeur est un numéro d'AS. Une route ainsi marquée ne sera acceptée que si elle vient d'un Fournisseur, ou d'un pair dont le numéro d'AS coïncide. Autrement, elle sera considérée comme résultant d'une fuite.

Ah, et pour les cas compliqués dont on a parlé plus haut, comme les rôles différents pour chaque préfixe ? Dans ce cas-là, le mécanisme des rôles de ce RFC n'est pas adapté et ne doit pas être utilisé.

Ce système des rôles est apparemment mis en œuvre dans des patches (non encore intégrés ?) pour FRRouting et BIRD. Par exemple, pour FRRouting, on configurerait :

neighbor 2001:db8:999::1 local-role customer
  

Pour BIRD, cela serait :

configuration
    ...
    protocol bgp {
        ...
        local_role customer;
    }
  

Et la gestion des rôles devrait être bientôt dans BGPkit. Par contre, je ne sais pas pour Cisco ou Juniper. Si quelqu'un a des informations…


Téléchargez le RFC 9234


L'article seul

Fiche de lecture : Concealing for freedom

Auteur(s) du livre : Ksenia Ermoshina, Francesca Musiani
Éditeur : Mattering Press
Publié en 2022
Première rédaction de cet article le 25 mai 2022


Le chiffrement est depuis longtemps un sujet de controverses. Indispensable pour assurer la sécurité des communications sur les réseaux informatiques (donc, tous les réseaux, y compris le téléphone), il est régulièrement attaqué par des politiciens qui l'accusent de permettre aux délinquants et aux criminels de dissimuler leurs communications. Mais il n'y a pas que ces attaques grossières, il y a aussi beaucoup de débats autour du chiffrement et de la meilleure façon de protéger les communications de M. et Mme Toutlemonde. Ce livre de deux chercheuses en sociologie explore de manière très claire mais aussi très approfondie ces débats. En bref, le chiffrement est nécessaire mais pas forcément suffisant. Ce livre est très recommandé à toutes les personnes qui veulent comprendre ce difficile problème.

Notez tout de suite avant d'acheter la version papier du livre qu'il est également gratuitement disponible en ligne. Même si vous achetez la version papier, la version numérique vous intéressera peut-être, par exemple pour rechercher un mot, ou pour copier-coller une citation.

Les informaticien·nes ont parfois tendance à avoir une approche strictement technique du chiffrement. On chiffre, et on est protégé, et les seuls débats concernent des points tels que « dois-je utiliser ECDSA ou EdDSA ? ». Mais les auteures montrent bien que bien d'autres questions se posent, et peuvent affecter la sécurité des communications. Par exemple, le livre contient une analyse du modèle de menaces. On veut se cacher de qui ? Le problème d'une militante féministe en Russie n'est pas forcément le même que celui d'un journaliste qui couvre des manifestations aux États-Unis ou que celui d'une femme qui veut se protéger d'un mari violent. L'adversaire n'a pas les mêmes moyens, et le niveau de risque est différent à chaque fois. Ainsi, de manière peut-être contre-intuitive, il peut être plus prudent d'utiliser un logiciel moins sûr, mais plus répandu, pour ne pas attirer l'attention. (Ce chapitre, comme d'autres dans le livre, est repris d'un précédent article des auteures.)

Le livre s'appuie sur beaucoup d'ateliers et de formations où les auteures ont participé. Ici, un dessin du modèle de menaces par une militante russe lors d'un de ces ateliers, montrant les différents ennemis : modele-menace.jpg

Dans bien des cas, le choix du système le plus sûr n'a pas de solution évidente, d'autant plus que bien des critères de choix se bousculent. Un chapitre est ainsi consacré au débat centralisation/décentralisation. Un système de communication centralisé est-il plus sûr ? La réponse n'est pas simple. Un système décentralisé a l'avantage de ne pas avoir de point de contrôle unique, susceptible d'être piraté, corrompu, ou soumis à des pressions financières ou juridiques. Utilisant des techniques standardisées, il est indépendant de tout fournisseur. Il règle de manière élégante la question du pouvoir et de ses abus en limitant la quantité de pouvoir dont dispose chaque acteur. Mais il a aussi des inconvénients : difficulté à faire évoluer techniquement (exemple du courrier électronique, réseau social décentralisé bien antérieur aux réseaux centralisés des GAFA, mais qui a du mal à déployer massivement des techniques de sécurité nouvelles), difficulté pour les utilisateurs à comprendre à qui il faut faire confiance (l'administrateur d'un serveur décentralisé n'est pas forcément « meilleur » que Gmail), risque d'invasion par des parasites contre lesquels il sera difficile de lutter (pensez au spam). Les auteures ne disent évidemment pas qu'il faut préférer les systèmes centralisés, simplement que le choix de la sécurité n'est pas toujours simple. (Une bonne partie du chapitre est consacrée aux controverses autour de Signal et du discours très pro-centralisation de son créateur, mais il parle aussi de systèmes moins connus comme Briar.) Et les arguments techniques cachent souvent des volontés de contrôle. Et parfois c'est la technique qui rend certaines solutions difficiles (faire du chiffrement de bout en bout est plus difficile si on veut des communications de groupe, faire de la distribution de message sans serveur est plus difficile si on veut épargner les batteries, etc).

La fédération (telle qu'utilisée par le fédivers) est souvent présentée comme la solution au problème du contrôle de la communication par quelques géants. Mais elle aussi pose ses propres problèmes, comme l'ont montré les difficultés de XMPP et Matrix à vaincre les messageries instantanées privatrices.

En parlant de messageries instantanées, un des chapitres les plus intéressants concerne l'analyse qu'avait publiée l'EFF pour aider les utilisateurices à choisir une messagerie instantanée sûre. La première version avait suscité de nombreuses critiques (pas toutes innocentes, et pas toutes intelligentes), portant par exemple sur la prépondérance excessive de critères purement techniques, ou s'inquiétant du fait de résumer un choix aussi complexe à un simple tableau de critères. Les auteurs détaillent longuement ces débats, et comment ils ont mené à une sérieuse réflexion sur la meilleure manière d'informer les utilisateurices.

Le livre est clairement écrit, et les auteures connaissent leur sujet (j'ai apprécié que le fédivers ne soit pas juste appelé Mastodon et que Pleroma soit aussi cité). Si vous croyez que le problème est simple, et que vous vous exprimez sèchement à ce sujet sur les réseaux sociaux, c'est le livre à lire d'abord.


L'article seul

RFC 9250: DNS over Dedicated QUIC Connections

Date de publication du RFC : Mai 2022
Auteur(s) du RFC : C. Huitema (Private Octopus), S. Dickinson (Sinodun IT), A. Mankin (Salesforce)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dprive
Première rédaction de cet article le 22 mai 2022


Ce nouveau RFC complète la série des mécanismes de protection cryptographique du DNS. Après DoT (RFC 7858) et DoH (RFC 8484), voici DoQ, DNS sur QUIC. On notera que bien que QUIC ait été conçu essentiellement pour les besoins de HTTP, c'est le DNS qui a été la première application normalisée de QUIC.

Fonctionnellement, DoQ est très proche de ses prédécesseurs, et offre les mêmes services de sécurité, confidentialité, grâce au chiffrement, et authentification du serveur, via le certificat de celui-ci. L'utilisation du transport QUIC permet quelques améliorations, notamment dans le « vrai » parallélisme. Contrairement à DoT (RFC 7858) et DoH (RFC 8484), DoQ peut être utilisé pour parler à un serveur faisant autorité aussi bien qu'à un résolveur.

Notez que le terme de DoQ (DNS over QUIC) n'apparait pas dans le RFC de terminologie DNS, le RFC 8499. Il sera normalement dans son successeur.

Logiquement, DoQ devrait faire face aux mêmes problèmes politiques que ceux vécus par DoH (voir aussi mon article dans Terminal) mais cela n'a pas été encore le cas. Il faut dire qu'il y a peu de déploiements (ne comptez pas installer DoQ comme serveur ou client tout de suite, le code est loin d'être disponible partout).

Le cahier des charges de DoQ est (sections 1 et 3 du RFC) :

  • Protection contre les attaques décrites dans le RFC 9076.
  • Même niveau de protection que DoT (RFC 7858, avec notamment les capacités d'authentification variées du RFC 8310). Rappelez-vous que QUIC est toujours chiffré (actuellement avec TLS, cf. RFC 9001).
  • Meilleure validation de l'adresse IP source qu'avec le classique DNS sur UDP, grâce à QUIC.
  • Pas de limite de taille des réponses, quelle que soit la MTU du chemin.
  • Diminution de la latence, toujours grâce à QUIC et notamment ses possibilités de connexion 0-RTT (RFC 9000, section 5), ses procédures de récupération en cas de perte de paquets (RFC 9002) et la réduction du head-of-line blocking, chaque couple requête/réponse étant dans son propre ruisseau.

En revanche, DoQ n'esssaie pas de :

  • Contourner le blocage de QUIC que font certaines middleboxes (DoH est meilleur, de ce point de vue). La section 3.3 du RFC détaille cette limitation de DoQ : il peut être filtré trop facilement, son trafic se distinguant nettement d'autres trafics.
  • Ou de permettre des messages du serveur non sollicités (pour cela, il faut utiliser le RFC 8490).

DoQ utilise QUIC. QUIC est un protocole de transport généraliste, un concurrent de TCP. Plusieurs protocoles applicatifs peuvent utiliser QUIC et, pour chacun de ces protocoles, cela implique de définir comment sont utilisés les ruisseaux (streams) de QUIC. Pour HTTP/3, cela sera fait dans un futur RFC et, ironiquement, le DNS est donc le premier protocole à être normalisé pour une utilisation sur QUIC. Notez qu'une autre façon de faire du DNS sur QUIC est de passer par DoH et HTTP/3 (c'est parfois appelé DoH3, terme trompeur) mais cette façon n'est pas couverte dans notre RFC, qui se concentre sur DoQ, du DNS directement sur QUIC, sans HTTP.

La spécification de DoQ se trouve en section 4. Elle est plutôt simple, DoQ étant une application assez directe de QUIC. Comme DoQ utilise QUIC, il y a forcément un ALPN, en l'occurrence via l'identificateur doq.

Le port, quant à lui, est par défaut 853, également nommé domain-s. C'est donc le même que DoT, et aussi le même que le DNS sur DTLS (RFC 8094, protocole expérimental, jamais vraiment mis en œuvre et encore moins déployé, et qui est de toute façon distinguable du trafic QUIC, cf. section 17.2 du RFC 9000). Bien sûr, un client et un serveur DNS majeurs et vaccinés peuvent toujours se mettre d'accord sur un autre port (mais pas 53, réservé au DNS classique). Cette utilisation d'un port spécifique à DoQ est un des points qui le rend vulnérable au filtrage, comme vu plus haut. Utiliser 443 peut aider. (Le point a été chaudement discuté à l'IETF, entre défenseurs de la vie privée et gestionnaires de réseau qui voulaient pouvoir filtrer facilement les protocoles de leur choix. Si on utilise le port 443, il faut se rappeler que l'ALPN est pour l'instant en clair, la lutte de l'épée et de la cuirasse va donc continuer.)

Plus important, la question de la correspondance entre les messages DNS et les ruisseaux QUIC. La règle est simple : pour chaque requête DNS, un ruisseau est créé. La première requête sur une connexion donnée sera donc sur le ruisseau 0 (RFC 9000, section 2.1), la deuxième sur le ruisseau 4, etc. Si les connexions QUIC sont potentiellement de longue durée, en revanche, les ruisseaux ne servent qu'une fois. Le démultiplexage des réponses est assuré par QUIC, pas par le DNS (et l'identificateur de requête DNS est donc obligatoirement à zéro, puisqu'inutile). Le parallélisme est également fourni par QUIC, client et serveur n'ont rien de particulier à faire. Il est donc recommandé de ne pas attendre une réponse pour envoyer les autres questions. Les messages DNS sont précédés de deux octets indiquant leur longueur, comme avec TCP.

Comme avec TCP, client et serveur ont le droit de garder un œil sur les ruisseaux et les connexions inactifs, et de les fermer d'autorité. La section 5.5 donne des détails sur cette gestion de connexion, mais le RFC 7766 est également une bonne lecture (voir aussi le RFC 9103 pour le cas des transferts de zones).

DoQ introduit quelques codes d'erreur à lui (RFC 9000, section 20.2), comme DOQ_INTERNAL_ERROR (quelque chose s'est mal passé), DOQ_PROTOCOL_ERROR (quelqu'un n'a pas lu le RFC, par exemple l'identificateur de requête était différent de zéro) ou DOQ_EXCESSIVE_LOAD (trop de travail tue le travail).

Un des gros avantages de QUIC est le 0-RTT, où des données sont envoyées dès le premier paquet, ce qui réduit nettement la latence. Cela implique que le client ait déjà contacté le serveur avant, mémorisant les informations qui seront données au serveur pour qu'il retrouve la session à reprendre. C'est cool, mais cela pose d'évidents problèmes de vie privée (ces informations mémorisées sont une sorte de cookie, et permettent le suivi à la trace d'un client). D'ailleurs, en parlant de vie privée, le RFC signale aussi (section 5.5.4) que la possibilité de migrer une connexion QUIC d'une adresse IP à l'autre a également des conséquences pour la traçabilité.

Autre piège avec le 0-RTT, il ne protège pas contre le rejeu et il ne faut donc l'utiliser que pour des requêtes DNS idempotentes comme QUERY (le cas le plus courant) ou NOTIFY (qui change l'état du serveur, mais est idempotent). Bon, de toute façon, un serveur peut toujours être configuré pour ne pas accepter de 0-RTT, et répondre alors REFUSED (avec un code d'erreur étendu - RFC 8914 - Too Early).

La section 5 du RFC liste les exigences auxquelles doivent se soumettre les mises en œuvre de DoQ. Le client doit authentifier le serveur (cf. RFC 7858 et RFC 8310, mais aussi RFC 8932, sur les bonnes pratiques). Comme tous les serveurs ne géreront pas DoQ, en tout cas dans un avenir prévisible, les clients doivent être préparés à ce que ça échoue et à réessayer, par exemple en DoT.

QUIC ne dissimule pas forcément la taille des messages échangés, et celle-ci peut être révélatrice. Malgré le chiffrement, la taille d'une requête ou surtout d'une réponse peut donner une idée sur le nom demandé. Le RFC impose donc l'utilisation du remplissage, soit par la méthode QUIC générique de la section 19.1 du RFC 9000, soit par la méthode spécifique au DNS du RFC 7830. La première méthode est en théorie meilleure car elle dissimule d'autres métadonnées, et qu'elle tient compte de davantage d'éléments, mais les bibliothèques QUIC n'exposent pas forcément dans leur API de moyen de contrôler ce remplissage. Le RFC recommande donc aux clients et serveurs DoQ de se préparer à faire le remplissage eux-mêmes (en relisant bien le RFC 8467 avant).

Un petit retour sur la protection de la vie privée en section 7. Cette section rappele l'importance de lire et suivre le RFC 8932 si vous gérez un service de résolution DNS sécurisé (DoQ ou pas DoQ). Et elle insiste sur le fait que des fonctions de QUIC très pratiques pour diminuer la latence à l'établissement de la connexion, notamment le 0-RTT, ont des conséquences pour la vie privée, en permettant de suivre un même utilisateur (plus exactement une même machine). Et cela marche même si la machine a changé d'adresse IP entretemps. On peut aussi dire que le problème de QUIC est de permettre des sessions de très longue durée (que ce soit une vraie session unique, ou bien une « session virtuelle », formée en reprenant une session existante avec le 0-RTT) et que de telles sessions longues, excellentes pour les performances, le sont forcément moins pour l'intimité.

Les mises en œuvre de DoQ, maintenant. La société AdGuard a produit du code, dont un serveur et un client en Go, dnslookup. (Regardez l'exposé du directeur technique de cette société à l'OARC.) Voici un exemple de compilation, puis d'utilisation de dnslookup :


% git clone https://github.com/ameshkov/dnslookup.git
%  cd dnslookup
% make
% ./dnslookup www.bortzmeyer.org quic://dns.adguard.com

On utilisait le serveur DoQ public d'AdGuard. Officiellement, NextDNS en a également un mais je n'arrive pas à l'utiliser :

% ./dnslookup www.bortzmeyer.org quic://3e4935.dns.nextdns.io
...
2022/05/22 08:16:33 Cannot make the DNS request: opening quic session to quic://3e4935.dns.nextdns.io:853: timeout: no recent network activity
  

Notez que si vous voulez utiliser dnslookup avec un serveur dont le certificat n'est pas valide, il faut mettre la variable d'environnement VERIFY à 0 (cela ne semble pas documenté).

Il existe une autre mise en œuvre de DoQ, quicdoq, écrite en C. Elle dépend de la bibliothèque QUIC picoquic qui, à son tour, dépend de picotls, dont la compilation n'est pas toujours évidente. D'une manière générale, les bibliothèques QUIC sont souvent récentes, parfois expérimentales, et ne marchent pas toujours du premier coup. Mais si vous arrivez à compiler les dépendances de quicdoq, vous pouvez lancer le serveur ainsi :

% ./quicdoq_app -p 8053 -d 9.9.9.9
  

Puis le client :

% ./quicdoq_app ::1 8053 foobar:SOA bv:NS www.bortzmeyer.org:AAAA
  

Le logiciel de test de performances Flamethrower, écrit en C++ a une branche DoQ en cours de développement.

Le logiciel en Python aioquic ne semble pouvoir interagir qu'avec lui-même. Vu les messages d'erreur (quelque chose à propos de not enough bytes), je soupçonne qu'il utilise l'encodage des débuts de DoQ, quand il n'y avait pas encore le champ de deux octets au début des messages. Même avec lui-même, il a des exigences pénibles en matière de certificat (pas de certificats auto-signés, obligation que le nom du serveur soit dans le SAN - Subject Alternative Name, pas seulement dans le sujet).

Pour PowerDNS, il n'y a pour l'instant qu'un ticket. Et pour Unbound, c'est en cours d'analyse.

Dans les bibliothèques DNS, un travail est en cours pour go-dns.

Pour finir, vous pouvez regarder la présentation de DoQ par une des auteures du RFC au RIPE 84. Et un des premiers articles de recherche sur DoQ est « One to Rule them All? A First Look at DNS over QUIC ».


Téléchargez le RFC 9250


L'article seul

Métavers… où ?

Première rédaction de cet article le 14 mai 2022


J'ai eu le plaisir aujourd'hui de donner une conférence au sujet du métavers à la médiathèque Marc Ferro à Saint-Germain-en-Laye.

Voici les supports de la conférence en PDF (ou son source en LaTeX).

Merci à Kim-Minh Kaplan pour avoir retrouvé et numérisé le vieux numéro de Clone (journal tellement oublié qu'il n'a pas de page Wikipédia). Et à Marc Fontana pour l'invitation et l'organisation (belle médiathèque, avec beaucoup d'animations, n'hésitez pas à venir ; c'est le mai numérique).

L'annonce de Facebook citée est visible en ligne. Quelques liens intéressants :

Les tweets copiés sur les supports sont :


L'article seul

RFC 9239: Updates to ECMAScript Media Types

Date de publication du RFC : Mai 2022
Auteur(s) du RFC : M. Miller, M. Borins (GitHub), M. Bynens (Google), B. Farias
Pour information
Réalisé dans le cadre du groupe de travail IETF dispatch
Première rédaction de cet article le 11 mai 2022


Ce RFC documente les types de médias pour le langage de programmation JavaScript (dont le nom officiel est ECMAScript, qu'on retrouve dans le titre de ce RFC). Il remplace le RFC 4329 et le principal changement est que le type recommandé est désormais text/javascript et non plus application/javascript.

Si vous voulez vous renseigner en détail sur JavaScript, notre RFC recommande de lire la norme ECMA, en https://262.ecma-international.org/12.0/. Cette norme est développée en dehors de l'IETF et le choix des types de médias (aussi appelés types MIME, cf. RFC 2046) n'est donc pas forcément en accord avec les règles de l'IETF (RFC 6838). C'est pour cela que l'IESG a ajouté une note d'avertissement au RFC. Mais, bon, ce n'est pas trop grave en pratique. Le type recommandé est donc désormais text/javascript. D'autres types existent, application/ecmascript, application/javascript, etc, mais ils sont maintenant considérés comme dépassés.

Il existe plusieurs versions de la norme JavaScript et d'autres apparaitront peut-être dans le futur. Mais le type officiel n'indique pas de version (il a existé des propositions comme text/javascript1.4) et compte que toutes ces versions sont suffisamment compatibles pour qu'on ne gère pas la complexité d'avoir plusieurs types. Normalement, ECMA s'engage à ne pas bouleverser le langage.

Le choix de text/ est contestable car la définition originale de text/ dans le RFC 2045 prévoyait plutôt application/ pour les programmes. Le RFC 4329 enregistrait les types text/javascript et application/javascript, et recommandait le application/javascript (en accord avec ce que dit le RFC 6838). Aujourd'hui, c'est le contraire, text/javascript est le préféré. D'une manière générale, application/ n'a guère été utilisé (pas seulement dans le cas de JavaScript). (Personnellement, cela me convient très bien : pour moi, si ça peut s'afficher avec cat et s'éditer avec vi, c'est du texte.)

JavaScript est donc officiellement du texte, et la section 4 de notre RFC précise : du texte en UTF-8. Le paramètre charset est donc facultatif (même si le RFC 6838 dit le contraire). Si vous aimez les détails d'encodage, la section 4 vous ravira (c'est l'un des points qui a suscité le plus de discussion à l'IETF).

Le type text/javascript est enregistré à l'IANA ; les types comme application/javascript sont marqués comme dépassés. Même chose pour text/ecmascript. Le nom officiel de JavaScript est ECMAscript, puisque normalisé à l'ECMA mais personne n'utilise ce terme. (Il faut quand même noter que JavaScript est un terme publicitaire mensonger puisqu'il avait été choisi par le marketing pour profiter de la popularité - à l'époque - de Java, un langage avec lequel il n'a rien à voir.) Enfin, les types comme text/x-javascript qu'on voit parfois trainer datent d'avant le RFC 6648, qui abandonnait les identificateurs semi-privés commençant par x-.

La section 5 couvre les questions de sécurité. Elle est très longue car l'envoi de JavaScript à un programme qui l'exécutera (ce qui est très courant sur le Web) pose plein de problèmes de sécurité. Le RFC rappelle que l'exécution automatique d'un programme fourni par un tiers est évidemment intrinsèquement dangereuse, et doit se faire dans un bac à sable. Parmi les dangers (mais il y en a beaucoup d'autres !) le déni de service puisque JavaScript est un langage de Turing et permet donc, par exemple, des boucles infinies.

L'annexe B du RFC résume les changements depuis le RFC 4329 : le principal est bien sûr l'abandon de application/javascript au profit de text/javascript. Il y a aussi l'ajout de quelques détails comme une faille de sécurité nouvelle, et le cas des modules JavaScript.

Ah, un point de détail cité au détour d'un paragraphe du RFC : il n'y a pas de norme pour les identificateurs de fragments dans un URI pointant vers une ressource de type text/javascript. Si https://code.example/js/foreach.js#l23 pointe vers du JavaScript, la signification du #l23 (l'identificateur de fragment) n'est pas spécifiée.


Téléchargez le RFC 9239


L'article seul

RFC 9229: IPv4 Routes with an IPv6 Next Hop in the Babel Routing Protocol

Date de publication du RFC : Mai 2022
Auteur(s) du RFC : J. Chroboczek (IRIF, University of Paris)
Expérimental
Réalisé dans le cadre du groupe de travail IETF babel
Première rédaction de cet article le 11 mai 2022


Voici une extension sympathique qui réjouira tous les amateurs de routage IP. Elle permet à un routeur qui parle le protocole de routage Babel d'annoncer un préfixe IPv4 où le routeur suivant pour ce préfixe n'a pas d'adresse IPv4 sur cette interface.

Un petit rappel de routage : les annonces d'un routeur qui parle un protocole de routage dynamique comme Babel (RFC 8966) comprennent un préfixe IP (comme 2001:db8:543::/48) et l'adresse IP du routeur suivant (next hop dans la langue de Radia Perlman). Traditionnellement, le préfixe et l'adresse du routeur suivant étaient de la même version (famille) : tous les deux en IPv4 ou tous les deux en IPv6. Mais, si on veut router IPv6 et IPv4, cela consomme une adresse IP par interface sur chaque routeur, or les adresses IPv4 sont désormais une denrée très rare. D'où la proposition de ce RFC : permettre des annonces d'un préfixe IPv4 avec une adresse de routeur suivant en IPv6. (Notez que cela ne concerne pas que Babel, cela pourrait être utilisé pour d'autres protocoles de routage dynamique.)

La section 1 du RFC résume ce que fait un protocole de routage. Son but est de construire des tables de routage, où chaque entrée de la table est indexée par un préfixe d'adresses IP et a une valeur, l'adresse du routeur suivant. Par exemple :

   destination                      next hop
2001:db8:0:1::/64               fe80::1234:5678%eth0
203.0.113.0/24                  192.0.2.1    
  

Lorsqu'un routeur doit transmettre un paquet, il regarde dans cette table et trouve l'adresse du routeur suivant. Il va alors utiliser un protocole de résolution d'adresses (ARPRFC 826 - pour IPv4, NDRFC 4861 - pour IPv6) pour trouver l'adresse MAC du routeur suivant. Rien dans cette procédure n'impose que le préfixe de destination et l'adresse du routeur suivant soient de la même version d'IP. Un routeur qui veut transmettre un paquet IPv4 vers un routeur dont il ne connait que l'adresse IPv6 procède à la résolution en adresse MAC, puis met simplement le paquet IPv4 dans une trame portant l'adresse MAC en question (l'adresse IPv6 du routeur suivant n'apparait pas dans le paquet).

En permettant des annonces de préfixes IPv4 avec un routeur suivant en IPv6, on économise des adresses IPv4. Un réseau peut fournir de la connectivité IPv4 sans avoir d'adresses IPv4, à part au bord. Et comme les adresses IPv6 des routeurs sont des adresses locales au lien allouées automatiquement (cf. RFC 7404), on peut avoir un réseau dont le cœur n'a aucune adresse statique, ce qui peut faciliter sa gestion.

Notre RFC documente donc une extension au protocole Babel (qui est normalisé dans le RFC 8966), nommée v4-via-v6. (Comme dit plus haut, le principe n'est pas spécifique à Babel, voir le RFC 5549 pour son équivalent pour BGP.)

Bon, le concret, maintenant. Les préfixes annoncés en Babel sont précédés de l'AE (Address Encoding), un entier qui indique la version (famille) du préfixe. Ce RFC crée un nouvel AE, portant le numéro 4, qui a le même format que l'AE 1 qui servait à IPv4. Une annonce d'un préfixe ayant l'AE 4 devra donc contenir un préfixe IPv4 et un routeur suivant en IPv6. Un routeur qui sait router IPv4 mais n'a pas d'adresse IPv4 sur une de ses interfaces peut donc quand même y annoncer les préfixes connus, en les marquant avec l'AE 4 et en mettant comme adresse l'adresse IPv6 pour cette interface. (Cet AE est uniquement pour les préfixes, pas pour l'indication du routeur suivant.)

Les routeurs qui ne gèrent pas l'extension v4-via-v6 ignoreront cette annonce, comme ils doivent ignorer toutes les annonces portant un AE inconnu (RFC 8966). Pour cette raison, si un routeur a une adresse IPv4 sur une interface, il faut qu'il utilise des annonces traditionnelles, avec l'AE 1, pour maximiser les chances que son annonce soit acceptée.

Arrivé ici, mes lectrices et mes lecteurs, qui sont très malins, se demandent depuis longtemps « mais un routeur doit parfois émettre des erreurs ICMP (RFC 792), par exemple s'il n'a pas d'entrée dans sa table pour cette destination ». Comment peut-il faire s'il n'a pas d'adresse sur l'interface où il a reçu le paquet coupable ? Ne rien émettre n'est pas acceptable, certains protocoles en dépendent. C'est par exemple le cas de la découverte de la MTU du chemin, documentée dans le RFC 1191, qui a besoin des messages ICMP Packet too big. Certes, il existe un algorithme de découverte de cette MTU du chemin qui est entièrement de bout en bout, et ne dépend donc pas des routeurs et de leurs messages (RFC 4821). Mais ICMP sert à d'autres choses, on ne peut pas y renoncer.

Si le routeur Babel a une adresse IPv4 quelque part, sur une de ses interfaces, il peut l'utiliser comme adresse IP source pour ses messages ICMP. S'il n'en a pas, il peut toujours utiliser 192.0.0.8 comme suggéré par la section 4.8 du RFC 7600. Bien sûr, si tout le monde le fait, des outils d'administration du réseau très pratiques comme traceroute seront moins utiles.

La nouvelle extension peut soulever des questions de sécurité (section 6 du RFC). Par exemple, si l'administrateur réseaux croyait que, parce que les routeurs n'avaient pas d'adresse IPv4 sur une interface, les paquets IPv4 ne seraient pas traités sur cette interface, cette supposition n'est plus vraie. Ainsi, une île de machines IPv4 qui se croyaient séparées de l'Internet IPv4 par un ensemble de routeurs qui n'avaient pas d'adresse IPv4 de leur côté peut se retrouver subitement connectée. Si ce n'est pas ce qu'on veut, il faut penser à ne pas se contenter du protocole de routage pour filtrer, mais aussi à filtrer explicitement IPv4.

Question mise en œuvre, cette extension figure dans babeld (voir ici un compte-rendu d'expérience) à partir de la version 1.12, ainsi que dans BIRD.


Téléchargez le RFC 9229


L'article seul

RFC 9116: A File Format to Aid in Security Vulnerability Disclosure

Date de publication du RFC : Avril 2022
Auteur(s) du RFC : E. Foudil, Y. Shafranovich (Nightwatch Cybersecurity)
Pour information
Première rédaction de cet article le 28 avril 2022


Lorsqu'on repère un problème de sécurité sur un site Web ou, plus généralement, dans l'informatique d'une organisation, de deux choses l'une : soit on est un méchant et on exploite l'information à son profit, soit on fait partie des bons et on va essayer de faire en sorte que le problème soit résolu. Une solution évidente est de signaler le problème à l'organisation qui gère le site Web. Mais comment ? Entre le formulaire de contact cassé qui refuse votre adresse de courrier en prétendant qu'elle est illégale, et le message envoyé à un humain sous-payé et sous-qualifié qui cliquera tout de suite sur « Problème résolu » pour faire grimper ses chiffres de résolution, prévenir quelqu'un de compétent et de responsable est souvent un parcours du combattant ! D'où le choix de ce RFC de proposer encore une nouvelle méthode : un fichier à un endroit bien connu sur le site Web, au format structuré, et contenant les informations essentielles, le security.txt.

Comme beaucoup de techniques utilisées sur l'Internet, ce format a été déployé bien avant d'être officiellement décrit dans un RFC. On trouve aujourd'hui de tels fichiers sur plusieurs sites, y compris sur ce blog (regardez-le tout de suite si vous voulez avoir une idée de ce qu'on y met).

La section 1 du RFC décrit plus en détail le problème. Toute personne qui a déjà essayé de signaler un problème de sécurité à une organisation reconnaitra ses propres mésaventures. Le RFC commence par rappeler que trouver un contact, quoique très difficile, n'est pas tout : il faut aussi s'informer sur la politique de traitement des signalements de cette organisation, car plus d'un citoyen ayant voulu signaler une vulnérabilité s'est retrouvé accusé d'être un vilain pirate, et a parfois réellement été poursuivi en justice. Et enfin il faut s'informer sur les moyens de communications sécurisés puisque, par définition, on va transmettre des informations délicates. Est-ce qu'on peut utiliser PGP (RFC 4880), par exemple ? Pour ce qui est des contacts, il existe en théorie plusieurs solutions :

  • Le RFC 2142 exige un certain nombre d'adresses de courrier pour chaque domaine, comme security@LE-DOMAINE pour les signalements de sécurité. Il y a peu d'organisations où cette adresse fonctionne techniquement et, même quand c'est le cas, elle n'est pas forcément lue.
  • Les RFC 3013 (section 2), RFC 2350 (section 3.2) et RFC 2196 (section 5.2) prévoient des adresses de contact pour différents types d'acteurs. (Même remarque que sur le point précédent.)
  • Les bases des registres (de noms de domaine et d'adresses IP) contiennent également des adresses de contacts, en général accessibles via whois (cf. RFC 7485) ou RDAP. (Même remarque que sur le point précédent, en ajoutant que ces bases sont purement déclaratives, que leur exactitude est faible et baisse avec le temps.)
  • Aucune de ces solutions ne donne facilement accès à la politique de divulgation de l'organisation. Et, surtout, même si le RFC garde un silence poli sur la question, toute personne qui a essayé de contacter une organisation sait bien que ces adresses de contact sont souvent erronées, dépassées, ou bien arrivent chez des gens qui s'en f...ent.

Le dernier point est à la fois une motivation important pour créer une nouvelle solution et une des principales critiques qui avaient été formulées à l'encontre du projet security.txt lors de la discussion à l'IETF : pourquoi est-ce que ça serait mieux avec un nouveau format ? Si une organisation est assez négligente pour ne pas tenir à jour les informations présentes chez le registre de son nom de domaine, comment espérer qu'elle tienne à jour son security.txt ? Il n'y a évidemment pas de certitude à ce sujet, juste l'espoir qu'un autre format, et surtout un autre mécanisme de mise à jour augmentera les chances que l'information soit correcte.

Le security.txt est un fichier analysable par un programme (mais quand même lisible par un humain), et qui permet d'indiquer tout ce qui est nécessaire, par exemple au chercheur de vulnérabilités qui a trouvé quelque chose. Il vise à signaler les vulnérabilités (pas encore exploitées), pas les incidents (car un attaquant qui a réussi a peut-être modifié le fichier security.txt).

La spécification, maintenant (section 2 du RFC). Le security.txt est un simple fichier texte qui doit être déposé à un endroit précis du site Web, /.well-known (RFC 8615, et security.txt a été enregistré dans le registre des URL bien connus). Son type doit être text/plain et il doit être accessible en HTTPS, pour d'évidentes raisons de sécurité. Il doit être en Unicode, utilisant le profil du RFC 5198. Analysable par un programme, il doit se conformer à la grammaire spécifiée dans le RFC. Il comporte plusieurs champs, chacun sur une ligne, et ayant un nom et une valeur. La plupart des champs sont optionnels. Le champ le plus connu est Contact, qui est obligatoire, et voici un exemple :

Contact: mailto:stephane%2Bsecurity@bortzmeyer.org
  

(Vous avez reconnu l'encodage de l'URI spécifié dans la section 2.1 du RFC 3986. %2B est le signe plus.) Les lignes commençant par un croisillon sont des commentaires.

Le RFC recommande que les security.txt soient signés avec OpenPGP (RFC 4880). Naturellement, comme avec n'importe quelle signature, sa valeur dépend de si le vérificateur connait de manière certaine la clé publique qui a été utilisée.

Un certain nombre de champs sont définis aujourd'hui, la plupart optionnels. Parmi eux :

  • Acknowledgments : un lien vers une page des remerciements, pour que la personne ayant l'intention de signaler un problème sache qu'elle pourra être remerciée publiquement. Question carotte pour les chercheurs de vulnérabilités, il y a aussi un champ Hiring ☺.
  • Canonical : l'URL officiel de ce security.txt. Cela peut permettre de détecter certaines erreurs de configuration (security.txt copié sur le mauvais site).
  • Contact : sans doute le champ le plus important, et un des rares qui soit obligatoire. Il contient un URI indiquant comment contacter quelqu'un de responsable, à qui confier le problème de sécurité. L'intérêt de définir la valeur de ce champ comme un URI est que cela permet de ne pas se limiter à une méthode de contact particulière. Puisque c'est un URI, les adresses de courrier électronique doivent être mises sous forme d'URI mailto: (RFC 6068). Pareil pour les numéros de téléphone (RFC 3966). Le champ Contact peut être répété, afin d'avoir plusieurs mécanismes de signalement (dans ce cas, l'ordre est important, la méthode recommandée est la première).
  • Encryption : indique la clé de chiffrement à utiliser pour contacter. C'est encore un URI (qui peut être un URI de plan dns:, pour les clés stockées dans le DNS du RFC 7929).
  • Expires : ce champ est obligatoire et indique (au format du RFC 3339) la date limite d'utilisation de ce security.txt (pour éviter que de vieux fichiers pas maintenus restent utilisés).
  • Policy : un lien vers la page décrivant la politique de l'organisation en matière de signalement de vulnérabilités. Rappelez-vous qu'un problème de beaucoup de personnes qui ont détecté une vulnérabilité est le risque que le signalement de celle-ci leur vaille des ennuis juridiques, en raison de la politique de beaucoup d'organisations qui est de nier les problèmes et de poursuivre devant les tribunaux ceux qui les signalent.
  • Preferred-Languages : des étiquettes de langue (RFC 5646) indiquant dans quelles langues on préfère recevoir les rapports (et là, je pense à cet informaticien étatsunien qui s'était étonné publiquement qu'un webmestre chinois ne répondait pas à ses signalements de vulnérabilité faits en anglais…).

Les champs figurent dans un registre IANA. D'autres champs pourront être rajoutés à ce registre dans le futur, en suivant la politique « Examen par un expert » (RFC 8126). Pour faciliter ces futurs ajouts, il faut ignorer les champs qu'on ne connait pas. Un exemple réel de security.txt ? Regardez celui de ce blog.

Le security.txt est publié via le site Web mais ne s'applique pas forcément qu'au Web, il peut aussi servir pour l'organisation en général. Par contre, il ne s'applique pas aux sous-domaines : un security.txt sur eu.org n'est pas valable pour exodus-privacy.eu.org.

Vu le but de ce security.txt, il n'est pas étonnant que la section 5 du RFC, consacrée à la sécurité, soit si détaillée, d'autant plus qu'elle a fait l'objet de vigoureuses discussions à l'IETF. Je n'en cite ici qu'une partie, n'hésitez pas à lire toute cette section 5. D'abord, l'objection la plus évidente : si le site Web a été piraté, le security.txt ne peut plus être considéré comme digne de confiance. Les signalements risquent d'être perdus ou même envoyés à l'attaquant qui aura mis son adresse dans le security.txt. C'est vrai, mais c'est le cas de toutes les informations de contact. Par exemple, si le compte de l'organisation auprès du BE a été piraté (comme dans l'attaque moyen-orientale de 2018), les informations attachées au nom de domaine, et récupérées par whois ou RDAP, sont également suspectes. Le RFC recommande que les organisations qui ont un security.txt le supervisent automatiquement et vérifient notamment le champ Canonical. Et, bien sûr, que le security.txt soit signé. Les personnes qui signalent une vulnérabilité ont tout intérêt à vérifier le security.txt. Et puis surtout, security.txt est conçu pour la réponse à vulnérabilité, pas la réponse à incident. L'utiliser pour signaler « vous avez une faille » est raisonnable, s'en servir pour signaler « vous êtes piraté » l'est moins.

Comme toutes les informations mises en ligne (cf. l'exemple des informations sociales sur un nom de domaine…), le security.txt peut être faux, soit dès le début, soit parce qu'il n'a pas été maintenu correctement. En tapant cet article, je regardais le security.txt d'une entreprise française de sécurité informatique et le champ Encryption contenait un URL qui pointait… vers un 404. Dans une très grosse entreprise française travaillant sur de la haute technologie, notamment en sécurité, un URL dans le security.txt donne… 403 ! Au même endroit, la signature du security.txt est incorrecte… Le champ Expires permet de détecter les security.txt trop vieux et pas maintenus mais le problème est vaste et on peut s'attendre à se casser souvent le nez sur des informations incorrectes. Comme pour toutes les informations en ligne, les organisations qui publient un security.txt devraient s'assurer, dans leurs procédures, qu'il est maintenu à jour.

Certains croient qu'ils ont le droit de se livrer à des tests d'attaques sur tout site Web trouvé sur l'Internet. C'est évidemment faux, de même qu'on n'a pas le droit dans le rue de tenter de crocheter toutes les serrures pour voir lesquelles sont vulnérables. Même l'existence d'un security.txt ne vaut pas autorisation de tester le site. Le champ Policy peut indiquer si des tests d'attaque sont autorisés et dans quelles conditions. Sinon, on doit se limiter aux failles découvertes dans le cours de l'utilisation normale du site (ceci n'est pas un conseil juridique : la loi est compliquée et dépend du pays).

Naturellement, comme toujours lorsqu'on publie une adresse de courrier, elle va recevoir du spam. Plus gênant, le fait que le security.txt soit analysable par un programme pourrait amener certains bots qui font des soi-disant tests de sécurité à envoyer des messages automatiques de faible valeur. (Par exemple, j'ai vu un bot qui regardait la version d'Apache et envoyait automatiquement un courrier si la version lui semblait trop vieille. Ce genre d'avertissements mécaniques n'a aucune valeur, notamment parce que certains systèmes d'exploitation bouchent les failles de sécurité sans changer la version et, surtout, parce qu'il y a peu de chance qu'un logiciel puisse faire avec succès quelque chose d'aussi délicat qu'une analyse de sécurité ; les logiciels sont utiles pour une première reconnaissance, mais il ne faut pas envoyer de message d'avertissement avant qu'un humain compétent n'ait vérifié.)

Voilà, nous avons fait le tour du RFC. Si vous êtes responsable de la sécurité d'une organisation, à vous de vous mettre au travail pour concevoir et documenter une politique de signalement des failles de sécurité (c'est le gros du travail), de rédiger un security.txt (c'est trivial) et de faire en sorte qu'il soit maintenu (ce n'est pas évident). Si vous avez trouvé une faille de sécurité dans un site Web ou ailleurs chez une organisation, pensez à regarder si elle a un security.txt mais ne l'utilisez pas aveuglément, comparez avec d'autres sources d'information. Pour vous instruire, vous pouvez regarder le site Web du projet. Il comprend notamment un bon formulaire pour aider à fabriquer son security.txt (mais rappelez-vous que ce qui est difficile, c'est l'élaboration de la politique). Ce site contient également une liste de logiciels qui peuvent aider. Le moteur de recherche Shodan lit les security.txt et les affiche proprement mais, avec le virtual hosting, comme Shodan travaille par adresse IP, ça ne marche pas souvent. Sinon, YesWeHack fournit une extension aux navigateurs Web pour afficher le security.txt (pas très utile, je trouve, elle se contente d'afficher le fichier tel quel, sans vraie valeur ajoutée).

Le security.txt est-il obligatoire ? Cela dépend de votre environnement. Le DHS étatsunien le recommande pour les organismes qui dépendent de lui. En France, l'arrêté du 18 septembre 2018 portant approbation du cahier des clauses simplifiées de cybersécurité, dans son article 6.4, dit que « Afin que ces signalements soient effectifs et efficaces, les conventions d'usage en cybersécurité sont respectées (security.txt, abuse@). Dans tous les cas, il faut moins d'une minute pour trouver le point d'entrée approprié du signalement. ».

Terminons par un tour des security.txt existants (mes commentaires concernent l'état de ce fichier en août 2021 ; il a pu changer depuis). Commençons par un exemple très simple, mais correct, celui de la société Cyberzen :

% curl https://www.cyberzen.com/.well-known/security.txt
Contact: contact@cyberzen.com
Expires: Sun, 31 Dec 2023 23:59 +0200
Preferred-Languages: fr, en
  

Ensuite le registre de .be a un très bon security.txt, très complet, avec commentaires :

%  curl https://www.dnsbelgium.be/.well-known/security.txt
# Our security address
Contact: mailto:csirt@dnsbelgium.be?subject=rdp_dnsbelgium.be
# Our OpenPGP key
Encryption: https://www.dnsbelgium.be/.well-known/pgp-key.txt
# Canonical URL
Canonical: https://www.dnsbelgium.be/.well-known/security.txt
# Our security policy
Policy: https://www.dnsbelgium.be/responsible-disclosure-policy
Preferred-Languages: en, nl, fr
Expires: Mon, 1 Nov 2021 00:00:00 +0100
  

Autre exemple, Google a un security.txt :

Contact: https://g.co/vulnz
Contact: mailto:security@google.com
Encryption: https://services.google.com/corporate/publickey.txt
Acknowledgements: https://bughunter.withgoogle.com/
Policy: https://g.co/vrp
Hiring: https://g.co/SecurityPrivacyEngJobs
  

Le champ Expires, pourtant obligatoire, manque encore (il a été ajouté dans les dernières révisions du projet de spécification).

En France, la Sécu en a un et, contrairement à celui de Google, il est signé avec OpenPGP :

% curl https://www.ameli.fr/.well-known/security.txt  
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Contact: mailto:abuse@assurance-maladie.fr
Encryption: https://raw.githubusercontent.com/AssuranceMaladieSec/abuse/master/abuse-gpg-public-key.txt
Policy: https://assurancemaladiesec.github.io/abuse/reporting/
Acknowledgments: https://assurancemaladiesec.github.io/abuse/thanks/
Preferred-Languages: fr,en
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEDSx9bqnSlmkiIRXbSDqGYCymPFIFAl4V9/cACgkQSDqGYCym
PFIB7Q/9EI7fNOfyoCqnEH4chiTIW8fx32ldnlaE6WTgdMeQJmkyJrhd2osPAV/j
...
  

Ah, profitons-en pour vérifier la signature (la clé publique, curieusement, est hébergé chez un tiers, GitHub) :

% wget https://www.ameli.fr/.well-known/security.txt                                           
...
2020-04-08 18:41:10 (6.87 MB/s) - ‘security.txt’ saved [1189]

% wget https://raw.githubusercontent.com/AssuranceMaladieSec/abuse/master/abuse-gpg-public-key.txt
...
2021-08-12 09:03:52 (11,1 MB/s) - ‘abuse-gpg-public-key.txt’ saved [3159/3159]

% gpg --import abuse-gpg-public-key.txt 
gpg: key 483A86602CA63C52: public key "Abuse Assurance Maladie <abuse@assurance-maladie.fr>" imported
gpg: Total number processed: 1
gpg:               imported: 1
 
% gpg --verify security.txt 
gpg: Signature made Wed Jan  8 16:40:39 2020 CET
gpg:                using RSA key 0D2C7D6EA9D29669222115DB483A86602CA63C52
gpg: Good signature from "Abuse Assurance Maladie <abuse@assurance-maladie.fr>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 0D2C 7D6E A9D2 9669 2221  15DB 483A 8660 2CA6 3C52
  

C'est parfait, tout fonctionne (et c'est documenté). Autre exemple en France, le service Flus, dont le security.txt est décrit dans un bon article. Voici le fichier :

% curl https://flus.fr/.well-known/security.txt
Contact: https://flus.fr/contact
Contact: security@flus.io
Expires: Fri, 01 Apr 2022 00:00 +0000
Policy: https://flus.fr/securite
Acknowledgments: https://flus.fr/securite
Canonical: https://flus.fr/.well-known/security.txt
Preferred-Languages: fr, en

OpenSSL a bien sûr un security.txt. À une époque, la signature PGP était incorrecte…

% gpg --verify security.txt.asc  security.txt
gpg: Signature made Thu Jan  4 04:22:26 2018 CET
gpg:                using RSA key EFC0A467D613CB83C7ED6D30D894E2CE8B3D79F5
gpg: BAD signature from "OpenSSL OMC <openssl-omc@openssl.org>" [unknown]
  

Cela illustre un problème commun à tous les mécanismes de publication d'information de contact : l'information n'est pas facile à maintenir et tend à se dégrader avec le temps.

Quelques lectures supplémentaires qui peuvent être intéressantes :


Téléchargez le RFC 9116


L'article seul

RFC 9151: Commercial National Security Algorithm (CNSA) Suite Profile for TLS and DTLS 1.2 and 1.3

Date de publication du RFC : Avril 2022
Auteur(s) du RFC : D. Cooley (NSA)
Pour information
Première rédaction de cet article le 26 avril 2022


Le choix est vaste parmi les algorithmes de cryptographie. Des protocoles comme TLS offrent de l'agilité cryptographique, c'est-à-dire la possibilité d'avoir différents algorithmes pour un même protocole. Pour l'administrateur système qui n'est pas un ou une expert en cryptographie, lesquels choisir ? Pour l'aider, les agences de sécurité nationales font souvent des documents synthétisant leur analyse des bons algorithmes du moment. C'est le cas du RGS en France, par exemple. Ce RFC définit le profil TLS de CNSA (Commercial National Security Algorithm), les bons algorithmes recommandés par la NSA.

C'est d'ailleurs le deuxième RFC écrit par un employé de cette agence étatsunienne, après le RFC 5903 mais il est évidemment possible que certains auteurs aient été discrets sur leur affiliation.

Ce profil CNSA (Commercial National Security Algorithm) est destiné à être utilisé dans le cadre de TLS, plus exactement ses versions 1.2 (RFC 5246) et 1.3 (RFC 8446). Le cadre réglementaire étatsunien est SP 80059. Un rappel : il s'agit d'un profil, une restriction des algorithmes possibles, il ne définit pas de nouvel algorithme, il liste juste ceux à utiliser, par exemple ceux des RFC 5288 et RFC 5289. C'est en effet une de missions de la NSA que de conseiller l'État et les entreprises en matière de cryptographie. (La NSA a également une mission offensive, qui va en sens inverse, les encourageant par exemple à garder secrètes des vulnérabilités, pour qu'elle puisse les exploiter.) Cette suite CNSA n'a rien de très novateur, elle est dans la continuation des précédentes, le prochain grand changement, estime la NSA, sera le passage aux algorithmes post-quantiques. (Notez que l'analyse de la NSA sur les mesures à prendre en attendant les calculateurs quantiques est très discutée.)

Après ces préliminaires, la suite CNSA elle-même (section 4). Elle inclut les grands classiques, Diffie-Hellman avec les corps finis, les courbes elliptiques du NIST et encore RSA, les signatures avec les courbes elliptiques (ECDSA seulement) et RSA, et l'algorithme de chiffrement symétrique AES en intègre avec GCM (ChaChaRFC 8439, sans doute pas assez officiel, n'est pas cité). CNSA impose des tailles minimales de clés, par exemple 3 072 bits pour une signature avec RSA. Pour la condensation, c'est SHA-384 seulement (j'ignore pourquoi SHA-256 et les autres ne sont pas cités).

Pour la version de TLS, la section 5 de notre RFC impose au minimum 1.2 (c'est un des points où le blog que vous êtes en train de lire n'est pas conforme aux recommandations de la NSA…). Si on utilise une courbe elliptique (cf. RFC 8422), cela doit être la P-384 du NIST. (Saviez-vous d'ailleurs qu'il existe une courbe elliptique française, « FRP256 », publiée au Journal officiel ?) Et au passage, les certificats doivent suivre le profil du RFC 8603.

Pour TLS 1.3 (RFC 8446), CNSA impose de tirer profit de certaines nouveautés de cette version, comme l'extension signature_algorithms. Par contre, il faut refuser early_data (les raisons sont dans la section 2.3 du RFC 8446).


Téléchargez le RFC 9151


L'article seul

RFC 9224: Finding the Authoritative Registration Data Access Protocol (RDAP) Service

Date de publication du RFC : Mars 2022
Auteur(s) du RFC : M. Blanchet (Viagenie)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 25 avril 2022


Le protocole RDAP d'accès à l'information sur les objets (noms de domaines, adresses IP, etc) stockés dans un registre fonctionne en interrogeant le serveur en HTTP. Encore faut-il trouver le serveur à interroger. Comment le client RDAP qui veut des informations sur 2001:67c:288::2 sait-il à quel serveur demander ? Ce RFC décrit le mécanisme choisi. En gros, l'IANA gère des « méta-services » qui donnent la liste de serveurs RDAP, mais il peut aussi y avoir redirection d'un serveur RDAP vers un autre. Ce RFC remplace le premier RFC sur le sujet, le RFC 7484, avec très peu de changements.

Le protocole RDAP est décrit entre autres dans le RFC 7480 qui précise comment utiliser HTTP pour transporter les requêtes et réponses RDAP. Comme indiqué plus haut, il ne précise pas comment trouver le serveur RDAP responsable d'un objet donné. Le prédécesseur de RDAP, whois, avait exactement le même problème, résolu par exemple en mettant en dur dans le logiciel client tous les serveurs whois connus. En pratique, beaucoup de gens font simplement une requête Google et accordent une confiance aveugle auu premier résultat venu, quel que soit sa source. Au contraire, ce RFC vise à fournir un mécanisme pour trouver la source faisant autorité.

Avant d'exposer la solution utilisée, la section 1 de notre RFC rappelle comment ces objets (noms de domaine, adresses IP, numéros d'AS, etc) sont alloués et délégués. L'IANA délégue les TLD aux registres de noms de domaines, des grands préfixes IP et les blocs de numéros d'AS aux RIR. Il est donc logique que RDAP suive le même chemin : pour trouver le serveur responsable, on commence par demander à l'IANA, qui a déjà les processus pour cela, et maintient les registres correspondants (adresses IPv4, adresses IPv6, numéros d'AS et domaines).

Pour permettre à RDAP de fonctionner, ce RFC demande donc à l'IANA quelques fichiers supplémentaires, au format JSON (RFC 8259), dont le contenu dérive des registres cités plus haut. Et l'IANA doit aussi prévoir des serveurs adaptés à servir ces fichiers, nommés RDAP Bootstrap Service, à de nombreux clients RDAP.

Le format de ces fichiers JSON est décrit dans la section 3 de notre RFC. Chaque bootstrap service contient des métadonnées comme un numéro de version et une date de publication, et il contient un membre nommé services qui indique les URL où aller chercher l'information (la syntaxe formelle figure en section 10). Voici un extrait d'un des fichiers actuels :

 
% curl https://data.iana.org/rdap/ipv4.json
  "description": "RDAP bootstrap file for IPv4 address allocations",
  "publication": "2019-06-07T19:00:02Z",
  "services": [
    [
      [
        "41.0.0.0/8",
        "102.0.0.0/8",
        "105.0.0.0/8",
        "154.0.0.0/8",
        "196.0.0.0/8",
        "197.0.0.0/8"
      ],
      [
        "https://rdap.afrinic.net/rdap/",
        "http://rdap.afrinic.net/rdap/"
      ]
    ],
    ...

On voit que le contenu est un tableau donnant, pour des objets donnés, les URL des serveurs RDAP à contacter pour ces objets indiqués, par exemple pour l'adresse IP 154.3.2.1, on ira demander au serveur RDAP d'AfriNIC en https://rdap.afrinic.net/rdap/.

Le membre publication indique la date de parution au format du RFC 3339. Les URL indiqués se terminent par une barre oblique, le client RDAP a juste à leur ajouter une requête formulée selon la syntaxe du RFC 9082. Ainsi, cherchant des informations sur 192.0.2.24, on ajoutera ip/192.0.2.24 à l'URL de base.

Pour les adresses IP (section 5), les entrées sont des préfixes, comme dans le premier exemple montré plus haut et la correspondance se fait avec le préfixe le plus spécifique (comme pour le routage IP). Les préfixes IPv4 suivent la syntaxe du RFC 4632 et les IPv6 celle du RFC 5952. Voici un exemple IPv6 (légèrement modifié d'un cas réel) :

   [
      [
        "2001:200::/23",
        "2001:4400::/23",
        "2001:8000::/19",
        "2001:a000::/20",
        "2001:b000::/20",
        "2001:c00::/23",
        "2001:e00::/23",
        "2400::/12"
      ],
      [
        "https://rdap.apnic.net/"
      ]
    ],
    [
      [
        "2001:200:1000::/36"
      ],
      [
        "https://example.net/rdaprir2/"
      ]

Si on cherche de l'information sur le préfixe 2001:200:1000::/48, il correspond à deux entrées dans le tableau des services (2001:200::/23 et 2001:200:1000::/36) mais la règle du préfixe le plus long (le plus spécifique) fait qu'on va utiliser 2001:200:1000::/36, et la requête finale sera donc https://example.net/rdaprir2/ip/2001:200:1000::/48.

Pour les domaines (section 4), les entrées des services sont des noms de domaine :

...
       "services": [
         [
           ["net", "com", "org"],
           [
             "https://registry.example.com/myrdap/"
           ]
         ],
         [
           ["foobar.org", "mytld"],
           [
             "https://example.org/"
           ]
         ],
...

L'entrée sélectionnée est la plus longue (en nombre de composants du nom, pas en nombre de caractères) qui correspond. Dans l'exemple ci-dessus, si on cherche des informations sur foobar.org, on ira voir le serveur RDAP en https://example.org/, si on en cherche sur toto.org, on ira en https://registry.example.com/myrdap/. (En pratique, aujourd'hui, le tableau des serveurs RDAP ne contient que des TLD.)

Pour les numéros d'AS (section 5.3), on se sert d'intervalles de numéros et de la syntaxe du RFC 5396 :

"services": [
         [
           ["2045-2045"],
           [
             "https://rir3.example.com/myrdap/"
           ]
         ],
         [
           ["10000-12000", "300000-400000"],
           [
             "http://example.org/"
           ]
         ],
...

Les entités (section 6 de notre RFC) posent un problème particulier, elles ne se situent pas dans un espace arborescent, contrairement aux autres objets utilisable avec RDAP. (Rappel : les entités sont les contacts, les titulaires, les BE…) Il n'existe donc pas de bootstrap service pour les entités (ni, d'ailleurs, pour les serveurs de noms, cf. section 9). En pratique, si une requête RDAP renvoie une réponse incluant un handle pour une entité, il n'est pas idiot d'envoyer les requêtes d'information sur cette entité au même serveur RDAP mais il n'est pas garanti que cela marche.

Notez (section 7) que le tableau services ne sera pas forcément complet et que certains objets peuvent ne pas s'y trouver. Par exemple, dans un tableau pour les TLD, les registres n'ayant pas encore de serveur RDAP ne seront logiquement pas cités. On peut toujours tenter un autre serveur, en espérant qu'il utilisera les redirections HTTP. Par exemple, ici, on demande au serveur RDAP de l'APNIC pour une adresse RIPE. On est bien redirigé avec un code 301 (RFC 7231, section 6.4.2) :


%  curl -v http://rdap.apnic.net/ip/2001:67c:288::2
...
> GET /ip/2001:67c:288::2 HTTP/1.1
> User-Agent: curl/7.38.0
> Host: rdap.apnic.net
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Date: Wed, 01 Apr 2015 13:07:00 GMT
< Location: http://rdap.db.ripe.net/ip/2001:67c:288::2
< Content-Type: application/rdap+json
...

La section 8 couvre quelques détails liés au déploiement de ce service. C'est que le Bootstrap Service est différent des autres registres IANA. Ces autres registres ne sont consultés que rarement (par exemple, lors de l'écriture d'un logiciel) et jamais en temps réel. Si le serveur HTTP de l'IANA plante, ce n'est donc pas trop grave. Au contraire, le Bootstrap Service doit marcher en permanence, car un client RDAP en a besoin. Pour limiter la pression sur les serveurs de l'IANA, notre RFC recommande que les clients RDAP ne consultent pas ce service à chaque requête RDAP, mais qu'au contraire ils mémorisent le JSON récupéré, en utilisant le champ Expires: de HTTP (RFC 7234, section 5.3) pour déterminer combien de temps doit durer cette mémorisation. Néanmoins, l'IANA a dû ajuster ses serveurs HTTP et louer les services d'un CDN pour assurer ce rôle relativement nouveau.

Le client RDAP doit d'autre part être conscient que le registre n'est pas mis à jour instantanément. Par exemple, si un nouveau TLD est ajouté par le gouvernement états-unien, via Verisign, TLD dont le registre a un serveur RDAP, cette information ne sera pas disponible immédiatement pour tous les clients RDAP.

Comme son ancêtre whois, RDAP soulève plein de questions de sécurité intéressantes, détaillées plus précisement dans le RFC 7481.

La section 12 de notre RFC détaille les processus IANA à l'œuvre. En effet, et c'est une autre différence avec les registres IANA habituels, il n'y a pas de mise à jour explicite des registres du bootstrap service, ils sont mis à jour implicitement comme effet de bord des allocations et modifications d'allocation dans les registres d'adresses IPv4, adresses IPv6, numéros d'AS et domaines. Il a juste fallu modifier les procédures de gestion de ces registres existants, pour permettre d'indiquer le serveur RDAP. Ainsi, le formulaire de gestion d'un TLD par son responsable a été modifié pour ajouter un champ "serveur RDAP" comme il y avait un champ "serveur Whois".

Aujourd'hui, les fichiers de ce service sont :

  • https://data.iana.org/rdap/dns.json
  • https://data.iana.org/rdap/ipv4.json
  • https://data.iana.org/rdap/ipv6.json
  • https://data.iana.org/rdap/asn.json

Voici, par exemple, celui d'IPv6 (notez le champ Expires: dans la réponse) :


%  curl -v https://data.iana.org/rdap/ipv6.json
...
* Connected to data.iana.org (2606:2800:11f:bb5:f27:227f:1bbf:a0e) port 80 (#0)
> GET /rdap/ipv6.json HTTP/1.1
> Host: data.iana.org
> User-Agent: curl/7.68.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Expires: Tue, 26 Apr 2022 12:30:52 GMT
< Last-Modified: Wed, 06 Nov 2019 19:00:04 GMT
...
{
  "description": "RDAP bootstrap file for IPv6 address allocations",
  "publication": "2019-11-06T19:00:04Z",
  "services": [
    [
      [
        "2001:4200::/23",
        "2c00::/12"
      ],
      [
        "https://rdap.afrinic.net/rdap/",
        "http://rdap.afrinic.net/rdap/"
...

Et celui des TLD :


% curl -v http://data.iana.org/rdap/dns.json
...
  "description": "RDAP bootstrap file for Domain Name System registrations",
  "publication": "2022-04-22T16:00:01Z",
  "services": [
    [
      [
        "nowruz",
        "pars",
        "shia",
        "tci",
        "xn--mgbt3dhd"
      ],
      [
        "https://api.rdap.agitsys.net/"
      ]
    ],

Testons si cela marche vraiment :

% curl -v https://api.rdap.agitsys.net/domain/www.nowruz
...
 "nameservers": [
    {
      "objectClassName": "nameserver",
      "ldhName": "ns1.aftermarket.pl.",
      "unicodeName": "ns1.aftermarket.pl."
    },
    {
      "objectClassName": "nameserver",
      "ldhName": "ns2.aftermarket.pl.",
      "unicodeName": "ns2.aftermarket.pl."
    }
  ]

Parfait, tout marche.

Il y a très peu de changements depuis le RFC précédent, le RFC 7484, quelques nettoyages seulement, et un changement de statut sur le chemin des normes.

Si vous aimez lire des programmes, j'ai fait deux mises en œuvre de ce RFC, la première en Python est incluse dans le code utilisé pour mon article « Récupérer la date d'expiration d'un domaine en RDAP ». Le code principal est ianardap.py mais vous noterez que, contrairement à ce que demande le RFC dans sa section 8, la mémorisation du bootstreap registry n'utilise pas le champ HTTP Expires:. La deuxième, en Elixir, est plus correcte et est disponible dans find-rdap-elixir.tar. Lorsque la constante @verbose est vraie, le programme affiche les étapes. S'il n'a pas mémorisé de données :

% mix run find_rdap.exs quimper.bzh
Starting
No expiration known
Retrieving from https://data.iana.org/rdap/dns.json
Updating the cache
RDAP bootstrap file for Domain Name System registrations published on 2022-04-22T16:00:01Z
RDAP server for quimper.bzh is https://rdap.nic.bzh/
Retrieving RDAP info at https://rdap.nic.bzh/domain/quimper.bzh
{"rdapConformance":["rdap_level_0","...
  

S'il en a mémorisé :

% mix run find_rdap.exs quimper.bzh
Starting
Expiration is 2022-04-26 12:44:48Z
Using the cache ./iana-rdap-bootstrap.json
RDAP bootstrap file for Domain Name System registrations published on 2022-04-22T16:00:01Z
RDAP server for quimper.bzh is https://rdap.nic.bzh/
Retrieving RDAP info at https://rdap.nic.bzh/domain/quimper.bzh
{"rdapConformance":["rdap_level_0", ...

Mais il existe évidemment une mise en œuvre de ce RFC dans tous les clients RDAP comme :

  • L'application de Viagenie,
  • Celle de l'ICANN (application Web),
  • L'ARIN a un service de redirection, https://rdap-bootstrap.arin.net/bootstrap, qui lit la base IANA et envoie les redirections appropriées, quand un client RDAP l'interroge.

Téléchargez le RFC 9224


L'article seul

RFC 9233: IDNA2008 and Unicode 12.0.0

Date de publication du RFC : Mars 2022
Auteur(s) du RFC : P. Faltstrom (Netnod)
Chemin des normes
Première rédaction de cet article le 24 avril 2022


La norme pour les noms de domaine en Unicode, dite « IDNA 2008 », prévoit une révision à chaque nouvelle version d'Unicode pour éventuellement s'adapter à des changements dus à ces nouvelles versions. Ce processus de révision a pas mal cafouillé (euphémisme), et ce RFC doit donc traiter d'un coup les versions 6 à 12 d'Unicode.

Le fond du problème est que l'ancienne norme sur les IDN (RFC 3490) était strictement liée à une version donnée d'Unicode et qu'il fallait donc une nouvelle norme pour chacune des versions annuelles d'Unicode. Vu le processus de publication d'une norme à l'IETF, ce n'était pas réaliste. La seconde norme IDN, « IDN 2 » ou « IDN 2008 » (bien qu'elle soit sortie en 2010) remplaçait les anciennes tables fixes de caractères autorisés ou interdits par un algorithme, à faire tourner à chaque sortie d'une version d'Unicode pour produire les tables listant les caractères qu'on peut accepter dans un nom de domaine internationalisé (le mécanisme exact, utilisant les propriétés des caractères listées dans la norme Unicode, figure dans le RFC 5892). En théorie, c'était très bien. En pratique, malgré les règles de stabilité d'Unicode, il se produisait parfois des problèmes. Comme le documente le RFC 8753, un caractère peut ainsi passer d'interdit à autorisé, ce qui n'est pas grave mais aussi dans certains cas d'autorisé à interdit ce qui est bien plus embêtant : que faire des noms déjà réservés qui utilisent ce caractère ? En général, il faut ajouter une exception manuelle, ce qui justifie un mécanisme de révision de la norme IDN, mis en place par ce RFC 8753. Ce nouveau RFC 9233 est le premier RFC de révision. Heureusement, cette fois, aucune exception manuelle n'a été nécessaire.

La précédente crise était due à Unicode version 6 qui avait créé trois incompatibilités (RFC 6452). Une seule était vraiment gênante, le caractère , qui, autorisé auparavant, était devenu interdit suite au changement de ses propriétés dans la norme Unicode. Le RFC 6452 avait documenté la décision de ne rien faire pour ce cas, ce caractère n'ayant apparemment jamais été utilisé. Unicode 7 a ajouté un autre problème, le , qui était un cas différent (la possibilité de l'écrire de plusieurs façons), et la décision a été prise de faire désormais un examen formel de chaque nouvelle version d'Unicode. Mais cet examen a été souvent retardé et voilà pourquoi, alors qu'Unicode 13 est sorti (ainsi qu'Unicode 14 depuis), ce nouveau RFC ne traite que jusqu'à la version 12.

Passons maintenant à l'examen des changements apportés par les versions 7 à 12 d'Unicode, fait en section 3 du RFC :

  • À part le cas du cité plus haut, Unicode 7 n'a pas apporté de changements gênants pour IDN (par exemple, U+17B4 (caractère non visible) a changé de propriétés mais il était interdit pour IDN et le reste),
  • Unicode 8, Unicode 9 et Unicode 10 n'ont appporté aucun changement gênant,
  • Unicode 11 a changé les propriétés de certains caractères existants mais le résultat pour IDN ne change pas (par exemple, 𑨇, qui était autorisé, le reste),
  • Et Unicode 12 ? Rien de problématique.

En Unicode 11, 𑇉 qui passe d'interdit à autorisé, était un cas peu gênant. Le RFC prend donc la décision de ne pas ajouter d'exception pour ce caractère peu commun.

Voilà, arrivé ici, vous pensez peut-être que cela fait beaucoup de bruit pour rien puisque finalement les différentes versions d'Unicode n'ont pas créé de problème. Mais c'est justement pour s'assurer de cela que cet examen était nécessaire.

Pour compliquer davantage les choses, on notera qu'il existe encore sans doute (section 2.3 du RFC) des déploiements d'IDN qui en sont restés à la première version (celle du RFC 3490) voire qui sont un mélange des deux versions d'IDN, en ce qui concerne l'acceptation ou le refus des caractères.

En avril 2022, le travail pour Unicode 13 ou Unicode 14 n'a apparemment pas encore commencé…


Téléchargez le RFC 9233


L'article seul

RFC 9150: TLS 1.3 Authentication and Integrity-Only Cipher Suites

Date de publication du RFC : Avril 2022
Auteur(s) du RFC : N. Cam-Winget (Cisco Systems), J. Visoky (ODVA)
Pour information
Première rédaction de cet article le 22 avril 2022


Ce nouveau RFC normalise des algorithmes pour le protocole de sécurité TLS, qui ne fournissent pas de chiffrement (seulement authentification et intégrité). C'est évidemment une option très contestée et l'IETF ne suggère pas d'utiliser ces algorithmes mais, bon, certaines personnes y voient une utilité.

La section 1 du RFC décrit des scénarios d'usage (souvent tirés du monde de l'IoT) où cela peut avoir un sens de ne pas chiffrer. Le premier exemple est celui d'un bras robotique commandé via un protocole TCP/IP. L'authentification est importante mais la confidentialité ne l'est peut-être pas, ce qui rendrait acceptable l'absence de chiffrement. Autre exemple, des rapports météo, ou bien l'envoi de signaux d'horloges, qu'il faut évidemment authentifier mais qui ne sont pas secrets. Le RFC cite aussi des exemples de communication avec des trains ou des avions, où l'intégrité des données est cruciale, mais pas leur confidentialité. Mais attention avant de jeter le chiffrement à la poubelle, le RFC dit bien qu'il faut faire une analyse soignée de la menace. Pour reprendre l'exemple du bras robotique, l'écoute des messages pourrait permettre la rétro-ingénierie, ce qu'on ne souhaite pas forcément.

Mais pourquoi se passer de chiffrement, d'ailleurs, alors qu'il est plus simple de l'utiliser systématiquement ? Parce que dans certains cas, il coûte cher, notamment en latence. En outre, certains équipements, notamment du genre objets connectés, ont des capacités de calcul très limitées. Bref, si le chiffrement systématique et par défaut reste la politique de l'IETF, ce RFC présente quelques façons de s'en passer, si on sait ce qu'on fait (si vous ne savez pas, continuez à chiffrer !).

Les algorithmes sans chiffrement sont présentés dans la section 4. Ils se nomment TLS_SHA256_SHA256 et TLS_SHA384_SHA384, et sont évidemment dans le registre IANA. Ils utilisent une fonction de condensation comme SHA-256 pour faire du HMAC, protégeant ainsi l'intégrité des communications.

Rappelez-vous bien : aucun chiffrement n'est fourni. Les certificats client, par exemple, qui sont normalement chiffrés depuis TLS 1.3, seront envoyés en clair.

Publier un tel RFC n'a pas été facile, la crainte de beaucoup étant que des gens qui ne comprennent pas bien les conséquences utilise ces algorithmes sans mesurer les risques. Le RFC demande (section 9) donc qu'ils ne soient pas utilisés par défaut et qu'ils requièrent une configuration explicite. Et rappelez-vous que ce RFC n'est que « pour information » et ne fait pas l'objet d'un consensus à l'IETF.


Téléchargez le RFC 9150


L'article seul

RFC 9147: The Datagram Transport Layer Security (DTLS) Protocol Version 1.3

Date de publication du RFC : Avril 2022
Auteur(s) du RFC : E. Rescorla (RTFM), H. Tschofenig (Arm Limited), N. Modadugu (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 22 avril 2022


Pour sécuriser vos applications TCP sur l'Internet, vous utilisez TLS, pas vrai ? Et si vos applications préfèrent UDP, par exemple pour faire de la voix sur IP ? La solution est alors DTLS, dont la nouvelle version, la 1.3, est normalisée dans ce RFC 9147. Elle a vocation à remplacer l'ancienne version 1.2, qui était dans le RFC 6347.

DTLS fournit normalement les mêmes services de sécurité que TLS, notamment la confidentialité (via un chiffrement du trafic) et l'authentification (via une signature). Les seuls services TLS que DTLS ne peut pas rendre sont la protection de l'ordre des messages (ce qui est logique pour UDP) et, selon les options choisies, la protection contre le rejeu. DTLS a été conçu pour être aussi proche que possible de TLS, pour pouvoir réutiliser le code et s'appuyer sur des propriétés de sécurité déjà établies. DTLS 1.0 et 1.2 (il n'y a jamais eu de 1.1) avaient été normalisés sous forme de différences avec la version de TLS correspondante. De même, DTLS 1.3, objet de notre RFC, est défini en décrivant les différences avec TLS 1.3. Il faut donc lire le RFC 8446 avant. À propos de lectures, il faut aussi lire le RFC 9146, pour le concept d'identificateur de connexion (Connection ID).

La section 3 du RFC pose le problème : on veut un truc comme TLS mais qui marche sur un service de datagrammes, en général UDP (RFC 768). Un service de datagrammes ne garantit pas l'ordre d'arrivée, ni même que les datagrammes arrivent. DTLS ajoute de la sécurité au service de datagrammes mais ne change pas ses propriétés fondamentales : une application qui utilise DTLS ne doit pas s'étonner que les messages n'arrivent pas tous, ou bien arrivent dans le désordre. C'est un comportement connu des applications de diffusion vidéo ou de jeu en ligne, qui préfèrent sauter les parties manquantes plutôt que de les attendre.

Pourquoi un protocole distinct, DTLS, plutôt que de reprendre TLS ? C'est parce que TLS ne marche que si le service de transport sous-jacent garantit certaines propriétés qu'UDP ne fournit pas. TLS a besoin de :

  • Une numérotation croissante des données. Ces numéros ne sont pas explicites dans TLS, ils sont déduits de l'ordre d'arrivée. DTLS les rend explicites.
  • L'établissement d'une association TLS nécessite un échange fiable, où les messages arrivent dans l'ordre d'émission. Là aussi, DTLS doit ajouter des numéros de séquence explicites pour pouvoir remettre dans l'ordre les messages d'établissement d'association (cf. section 4.2).
  • Certains messages TLS n'ont pas d'accusé de réception explicite, TLS compte sur les messages suivants pour savoir si son message a été reçu. Avec DTLS, ces messages doivent avoir un accusé de réception puisque la couche transport ne nous dit plus si le message a été perdu.
  • Certains messages TLS peuvent être de grande taille (chaines de certificats, par exemple), supérieure à celle du datagramme (qui est typiquement de 1 500 octets) et DTLS doit donc être capable de les fragmenter et de les réassembler (la fragmentation IP étant hélas souvent bloquée par des équipements réseau mal programmés et/ou mal configurés).
  • Tout protocole utilisant les datagrammes doit se méfier des attaques par réflexion, où l'attaquant ment sur son adresse IP. TCP protège contre cela, mais DTLS, ne pouvant compter sur TCP, doit avoir son propre mécanisme de test de réversibilité.

La section 4 présente la couche Enregistrements de DTLS, c'est-à-dire le format des paquets sur le réseau. Les messages sont transportés dans des enregistrements (record) TLS, et il peut y avoir plusieurs messages dans un seul datagramme UDP. Le format des messages est différent de celui de TLS (ajout d'un numéro de séquence) et de celui de DTLS 1.2 :

struct {
           ContentType type;
           ProtocolVersion legacy_record_version;
           uint16 epoch = 0
           uint48 sequence_number;
           uint16 length;
           opaque fragment[DTLSPlaintext.length];
       } DTLSPlaintext;

struct {
           opaque unified_hdr[variable];
           opaque encrypted_record[length];
} DTLSCiphertext;
  

La première structure est en clair, la seconde contient des données chiffrées. Un message dans un datagramme est, soit un DTLSPlaintext (ils sont notamment utilisés pour l'ouverture de connexion, quand on ne connait pas encore le matériel cryptographique à utiliser) ou bien un DTLSCiphertext. La partie chiffrée du DTLSCiphertext est composée d'un :

struct {
            opaque content[DTLSPlaintext.length];
            ContentType type;
            uint8 zeros[length_of_padding];
} DTLSInnerPlaintext;

Comme pour TLS 1.3, le champ legacy_record_version est ignoré (il n'est là que pour tromper les middleboxes). Le unified_hdr contient notamment l'identificateur de connexion (Connection ID), concept expliqué dans le RFC 9146 (comme avec QUIC, ils peuvent augmenter la traçabilité). Les détails de la structure des messages figurent dans l'annexe A du RFC.

À l'arrivée d'un datagramme, c'est un peu compliqué, vu la variété de formats. La section 4.1 suggère un mécanisme de démultiplexage, permettant de déterminer rapidement si le message était du DTLSPlaintext, du DTLSCipherext, ou une erreur. Un datagramme invalide doit être silencieusement ignoré (c'est peut-être une tentative d'un méchant pour essayer d'injecter des données ; couper la connexion au premier datagramme invalide ouvrirait une facile voie d'attaque par déni de service).

Qui dit datagramme dit problèmes de MTU, une des plaies de l'Internet. Normalement, c'est l'application qui doit les gérer, après tout le principe d'un service de datagrammes, c'est que l'application fait tout. Mais DTLS ne lui facilite pas la tâche, car le chiffrement augmente la taille des données, « dans le dos » de l'application. Et, avant même que l'application envoie ses premières données, la poignée de main DTLS peut avoir des datagrammes dépassant la MTU, par exemple en raison de la taille des certificats. Et puis dans certains cas, le système d'exploitation ne transmet pas à l'application les signaux indispensables, comme les messages ICMP Packet Too Big. Bref, pour aider, DTLS devrait transmettre à l'application, s'il la connait, la PMTU (la MTU du chemin complet, que la couche Transport a peut-être indiqué à DTLS). Et DTLS doit gérer la découverte de la PMTU tout seul pour la phase initiale de connexion.

La section 5 du RFC décrit le protocole d'établissement de l'association entre client et serveur (on peut aussi dire connexion, si on veut, mais pas session, ce dernier terme devrait être réservé au cas où on reprend une même session sur une connexion différente). Il est proche de celui de TLS 1.3 mais il a fallu ajouter tout ce qu'UDP ne fournit pas, la détection de la MTU (Path MTU, la MTU du chemin complet), des accusés de réception explicites et la gestion des cas de pertes de paquets. Voici l'allure d'un message DTLS d'établissement de connexion :

 enum {
     client_hello(1),
     server_hello(2),
     new_session_ticket(4),
     end_of_early_data(5),
     encrypted_extensions(8),
     certificate(11),
     certificate_request(13),
     certificate_verify(15),
     finished(20),
     key_update(24),
     message_hash(254),
     (255)
 } HandshakeType;

 struct {
     HandshakeType msg_type;    /* handshake type */
     uint24 length;             /* bytes in message */
     uint16 message_seq;        /* DTLS-required field */
     uint24 fragment_offset;    /* DTLS-required field */
     uint24 fragment_length;    /* DTLS-required field */
     select (msg_type) {
         case client_hello:          ClientHello;
         case server_hello:          ServerHello;
         case end_of_early_data:     EndOfEarlyData;
         case encrypted_extensions:  EncryptedExtensions;
         case certificate_request:   CertificateRequest;
         case certificate:           Certificate;
         case certificate_verify:    CertificateVerify;
         case finished:              Finished;
         case new_session_ticket:    NewSessionTicket;
         case key_update:            KeyUpdate;
     } body;
 } Handshake;
 

Le message ClientHello, comme en TLS 1.3, a un champ legacy_version qui sert à faire croire aux middleboxes (et aux serveurs bogués qui ne gèrent pas correctement la négociation de version) qu'il s'agit d'un TLS ancien.

Un établissement de connexion DTLS typique est :

  • Le client envoie un ClientHello,
  • le serveur répond avec un HelloRetryRequest qui contient le cookie,
  • le client renvoie le ClientHello, cette fois avec le cookie (le serveur est désormais certain que le client ne ment pas sur son adresse IP),
  • le serveur peut alors transmettre son ServerHello,
  • le client peut alors envoyer un message Finished et transmettre des données.

Il existe également, comme en TLS 1.3, un mode rapide, quand le client a déjà contacté ce serveur et obtenu du matériel cryptographique qu'il peut ré-utiliser. (C'est ce qu'on appelle aussi le « 0-RTT » ou la « reprise de session », et ça existe aussi dans des protocoles comme QUIC.) Tous les paquets pouvant se perdre, DTLS doit avoir un mécanisme de réémission.

Les risques d'attaques par déni de service sont très élevés dans le cas où on utilise des datagrammes. Un méchant peut envoyer des demandes de connexion répétées, pour forcer le serveur à faire des calculs cryptographiques et surtout à allouer de la mémoire pour les connexions en attente. Pire, il peut utiliser un serveur DTLS pour des attaques par réflexion où le méchant ment sur son adresse IP pour que le serveur dirige ses réponses vers une victime innocente. Les attaques par réflexion sont encore pires lorsqu'elles sont combinées à une amplification, quand la réponse est plus grosse que la question.

Pour éviter ces attaques, DTLS reprend, comme vu plus haut, le principe des cookies sans état de Photuris (RFC 2522) et IKE (RFC 7296).

L'extension connection_id (cf. RFC 9146) peut être mise dans le ClientHello. Notez qu'une nouveauté par rapport au RFC 9146 est la possibilité de changer les identifiants de connexion pendant une association.

En section 7, une nouveauté de DTLS 1.3, et qui n'a pas d'équivalent dans TLS, les accusés de réception (ACK), nécessaires puisqu'on fonctionne au-dessus d'un service de datagrammes, qui ne garantit pas l'arrivée de tous les paquets. Un ACK permet d'indiquer les numéros de séquence qu'on a vu. Typiquement, on envoie des ACK quand on a l'impression que le partenaire est trop silencieux (ce qui peut vouloir dire que ses messages se sont perdus). Ces accusés de réception sont facultatifs, on peut décider que la réception des messages (par exemple un ServerHello quand on a envoyé un ClientHello) vaut accusé de réception. Ils servent surtout à exprimer son impatience « allô ? tu ne dis rien ? »

Dans sa section 11, notre RFC résume les points importants, question sécurité (en plus de celles communes à TLS et DTLS, qui sont traitées dans le RFC 8446). Le principal risque, qui n'a pas vraiment d'équivalent dans TLS, est celui de déni de service via une consommation de ressources déclenchée par un partenaire malveillant. Les cookies à la connexion ne sont pas obligatoires mais fortement recommandés. Pour être vraiment sûrs, ces cookies doivent dépendre de l'adresse IP du partenaire, et d'une information secrète pour empêcher un tiers de les générer.

À noter d'autre part que, si DTLS garantit plusieurs propriétés de sécurité identiques à celle de TLS (confidentialité et authentification du serveur), il ne garantit pas l'ordre d'arrivée des messages (normal, on fait du datagramme…) et ne protège pas parfaitement contre le rejeu (sections 3.4 et 4.5.1 du RFC si vous voulez le faire).

Les sections 12 et 13 résument les principaux changements depuis DTLS 1.2 (seulement les principaux car DTLS 1.3 est très différent de 1.2) :

  • n'accepte désormais que du chiffrement intègre,
  • le mécanisme de reprise de session est différent, et la terminologie a changé (on parle désormais de PSK, Pre-Shared Key pour désigner les données stockées chez le client),
  • la négociation de version a changé, pour tenir compte des nombreuses middleboxes boguées,
  • les numéros de séquence sont chiffrées (sans cela, corréler deux échanges utilisant des adresses IP différentes serait trivial). En fait, c'est plus compliqué que cela, il y a le numéro de séquence complet dans la partie chiffrée, et un numéro réduit à ses derniers bits en clair.

Si jamais vous vous lancez dans la programmation d'une bibliothèque DTLS, lisez l'annexe C, qui vous avertit sur quelques pièges typiques de DTLS.

En octobre 2021, il n'y avait pas encore de DTLS 1.3 dans GnuTLS (ticket en cours), BoringSSL ou dans OpenSSL (ticket en cours).

Merci à Manuel Pégourié-Gonnard pour sa relecture attentive.


Téléchargez le RFC 9147


L'article seul

Qu'est-ce que l'Internet et quand est-on « coupé de l'Internet » ?

Première rédaction de cet article le 20 avril 2022


Mais c'est vrai, ça, c'est quoi, l'Internet ? Pour M. Toutlemonde, ça semble évident, c'est le truc auquel on se connecte via son FAI. Mais pour un pays, que veut dire « être connecté à l'Internet » ? Par exemple, si tous les câbles sous-marins entre l'Europe et l'Amérique étaient soudainement mis hors service, qui serait « coupé de l'Internet » ? Cet article de recherche « What Is The Internet? (Considering Partial Connectivity) » examine la question et tente de lui donner une réponse quantitative.

J'avais regardé cette question dans le contexte militaro-géopolitique dans mon article « Quelles conséquences si les câbles avec les USA étaient coupés ? ». Le point de départ était l'apparition d'articles médiatiques sensationalistes sur l'hypothèse d'une attaque russe contre les câbles sous-marins. Une erreur commune à tous ces médiocres articles était de ne rien comprendre à l'Internet. Ce dernier n'est pas un service auquel on se connecte, c'est un réseau de réseaux. Si les câbles transatlantiques sont attaqués, l'Europe n'est pas « coupée de l'Internet », elle continue à faire fonctionner ses réseaux pendant que l'Amérique le fait de son côté. Mais, alors, où est l'Internet, puisque ce n'est pas un objet physique situé à un endroit précis ? La décentralisation de l'Internet rend la question difficile. Pour reprendre une vieille blague britannique, en cas de coupure de la navigation sur la Manche, c'est l'Europe qui est isolée. 🤣

John Heidemann et Guillermo Baltra s'attaquent à cette question dans un article de 2021, « What Is The Internet? (Considering Partial Connectivity) » (arXiv:2107.11439v1). Ils notent qu'évidemment il y a plusieurs définitions possibles de l'Internet (après tout, certains utilisateurs disent bien que l'Internet est en panne lorsque c'est juste Facebook qui est arrêté). Les débats très confus (comme souvent en politique) sur le thème de la « fragmentation de l'Internet » (ou « Splinternet » pour faire chic) achoppent souvent sur ce point ; par exemple, à partir de quel niveau de filtrage / censure / problèmes techniques est-on réellement déconnecté de l'Internet ? Est-ce qu'une machine qui n'a pas d'adresse IP publique et est donc forcée de passer par un système de traduction d'adresses est bien « connectée à l'Internet » ? Et, s'il y a fragmentation en N morceaux, quel morceau est « l'Internet » ?

Les auteurs tranchent clairement la question : ils proposent de dire que l'Internet est l'ensemble connecté des adresses IP publiques qui peuvent joindre plus de la moitié des adresses IP publiques actives. Il y a, en plus de l'Internet ainsi défini, des iles (des réseaux connectés entre eux mais qui ne peuvent pas joindre l'Internet) et des péninsules (des réseaux qui peuvent joindre certaines des machines de l'Internet mais pas toutes).

La définition des auteurs fait qu'il n'y aura pas d'ambiguité : si un réseau a plus de 50 % des adresses IP publiques actives, il sera l'Internet. Si aucun réseau n'atteint ce seuil, on considérera qu'il n'y a plus d'Internet.

Les auteurs notent qu'aucun pays n'a à lui seul plus de la moitié des adresses IP publiques (même les États-Unis en sont loin) et que toute sécession d'un pays le laisserait donc en dehors de l'Internet ainsi défini. Ah, et en cas de coupure de tous les câbles sous-marins laissant d'un côté un bloc Amérique et de l'autre un bloc Eurasie, c'est ce dernier qui serait l'Internet, il aurait bien la majorité des adresses.

Les problèmes de joignabilité, qui créent iles et péninsules, peuvent avoir de nombreuses causes. Il peut s'agir d'une panne (et l'ile ou la péninsule sont alors temporaires), d'un conflit commercial entre deux opérateurs qui refusent de s'appairer (et cela peut durer longtemps) ou bien d'une action délibérée, par exemple d'un État qui veut priver sa population d'information. (Mais attention à ce qu'on lit dans les médias, c'est souvent plus compliqué que ce qu'ils racontent.)

L'article d'Heidemann et Baltra va ensuite partir à la recherche de ces iles et péninsules en utilisant les données de Trinocular. Trinocular a plusieurs points de mesure (VP, pour vantage point), ce qui est évidemment essentiel pour les mesures Internet, puisqu'une machine peut être joignable depuis certains endroits mais pas d'autres. Mais il ne couvre pas tout et peut donc prendre une péninsule pour une ile, par exemple. L'article décrit ensuite les iles et péninsules observées, et leur durée.

Bref, un excellent article, très concret et détaillé, apportant de l'information précise au débat.


L'article seul

Fiche de lecture : Une auberge dans la tempête

Auteur(s) du livre : Gee
Éditeur : Ptilouk.net
9-782493-727008
Publié en 2022
Première rédaction de cet article le 18 avril 2022


Vous connaissez peut-être Gee pour ses dessins pour Framasoft. Mais il fait aussi des romans comme ce livre à mystère.

Il y a en effet une grosse énigme (que se passe-t-il dans cette curieuse auberge où Nathalie est arrivée par hasard ?) et plein d'autres questions qui viennent successivement. L'héroïne est informaticienne mais ce n'est pas pour cela que j'ai aimé, c'est pour le style, l'humour, les innombrables choses bizarres à comprendre et le dénouement. Pas de sang ni de violence, cela repose de certains polars.

Le livre est sous une licence libre et vous pouvez le télécharger (ou bien acheter l'édition papier).


L'article seul

RFC 9210: DNS Transport over TCP - Operational Requirements

Date de publication du RFC : Mars 2022
Auteur(s) du RFC : J. Kristoff (Dataplane.org), D. Wessels (Verisign)
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 15 avril 2022


Ce nouveau RFC décrit les exigences opérationnelles pour le DNS, plus précisement pour son protocole de transport TCP. Le RFC 7766 décrivait la norme technique, et s'imposait donc aux programmeur·ses, ce RFC 9210 est plus opérationnel et concerne donc ceux et celles qui installent et configurent les serveurs DNS et les réseaux qui y mènent.

Les messages DNS sont historiquement surtout transportés sur UDP. Mais le DNS a toujours permis TCP et, de nos jours, il est fréquemment utilisé notamment en conjonction avec TLS (cf. RFC 7858). Il est d'autant plus important que TCP marche bien qu'il est parfois nécessaire pour certains usages, par exemple pour des enregistrements de grande taille (ce qui arrive souvent avec DNSSEC). Une mise en œuvre du DNS doit donc inclure TCP, comme clarifié par le RFC 7766 (les RFC précédents n'étaient pas sans ambiguité). Mais cela ne signifiait pas forcément que les serveurs DNS avaient activé TCP ou que celui-ci marchait bien (par exemple, une stupide middlebox pouvait avoir bloqué TCP). Ce nouveau RFC 9210 ajoute donc que l'obligation d'avoir TCP s'applique aussi aux serveurs effectifs, pas juste au logiciel.

DNS sur TCP a une histoire compliquée (section 2 du RFC). Franchement, le fait que le DNS marche sur TCP aussi bien que sur UDP n'a pas toujours été clairement formulé, même dans les RFC. Et, en dehors de l'IETF, beaucoup de gens ont raconté n'importe quoi dans des articles et des documentations, par exemple que TCP n'était utile qu'aux transferts de zone, ceux normalisés dans le RFC 5936. Cette légende a été propagée par certains auteurs (comme Cheswick et Bellovin dans leur livre Firewalls and Internet Security: Repelling the Wily Hacker) ou par des gens qui ne mesuraient pas les limites de leurs compétences DNS comme Dan Bernstein. Pourtant, TCP a toujours été nécessaire, par exemple pour transporter des données des grande taille (que DNSSEC a rendu bien plus fréquentes). Le RFC 1123, en 1989, insistait déjà sur ce rôle. Certes, EDNS (RFC 6891) permettait déjà des données de taille supérieure aux 512 octets de la norme originelle. Mais il ne dispense pas de TCP. Par exemple, des données de taille supérieure à 1 460 octets (le maximum qui peut tenir avec le MTU typique) seront fragmentées et les fragments, hélas, ne passent pas partout sur l'Internet. (Cf. le « DNS Flag Day » de 2020 et lire « DNS XL » et « Dealing with IPv6 fragmentation in the DNS ».) Et la fragmentation pose également des problèmes de sécurité, voir par exemple « Fragmentation Considered Poisonous ».

Bon, en pratique, la part de TCP reste faible mais elle augmente. Mais, trop souvent, le serveur ne répond pas en TCP (ou bien ce protocole est bloqué par le réseau), ce qui entraine des tas de problèmes, voir par exemple le récit dans « DNS Anomalies and Their Impacts on DNS Cache Servers ».

Notons enfin que TCP a toujours permis que plusieurs requêtes se succèdent sur une seule connexion TCP, même si les premières normes n'étaient pas aussi claires qu'il aurait fallu. L'ordre des réponses n'est pas forcément préservé (cf. RFC 5966), ce qui évite aux requêtes rapides d'attendre le résultat des lentes. Et un client peut envoyer plusieurs requêtes sans attendre les réponses (RFC 7766). Par contre, la perte d'un paquet va entrainer un ralentissement de toute la connexion, et donc des autres requêtes (QUIC résout ce problème et il y a un projet de DNS sur QUIC).

Vous pouvez tester qu'un serveur DNS accepte de faire passer plusieurs requêtes sur une même connexion TCP avec dig et son option +keepopen (qui n'est pas activée par défaut). Ici, on demande à ns4.bortzmeyer.org les adresses IP de www.bortzmeyer.org et mail.bortzmeyer.org :

% dig +keepopen +tcp @ns4.bortzmeyer.org www.bortzmeyer.org AAAA mail.bortzmeyer.org AAAA
  

Vous pouvez vérifier avec tcpdump qu'il n'y a bien eu qu'une seule connexion TCP, ce qui ne serait pas le cas sans +keepopen.

Les exigences opérationnelles pour le DNS sur TCP figurent dans la section 3 du RFC. Il est désormais obligatoire non seulement d'avoir la possibilité de TCP dans le code mais en outre que cela soit activé partout. (En termes du RFC 2119, on est passé de SHOULD à MUST.)

La section 4 discute de certaines considérations opérationnelles que cela pourrait poser. D'abord, certains serveurs ne sont pas joignables en TCP. C'était déjà mal avant notre RFC mais c'est encore pire maintenant. Mais cela arrive (ce n'est pas forcément la faute du serveur, cela peut être dû à une middlebox boguée sur le trajet). Les clients doivent donc être préparés à ce que TCP échoue (de toute façon, sur l'Internet, tout peut toujours échouer). D'autre part, diverses attaques par déni de service sont possibles, aussi bien contre le serveur (SYN flooding, contre lequel la meilleure protection est l'utilisation de cookies, cf. RFC 4987), que contre des machines tierces, le serveur étant utilisé comme réflecteur.

Aussi bien le client DNS que le serveur n'ont pas des ressources illimitées et doivent donc gérer les connexions TCP. Dit plus brutalement, il faut être prêt à couper les connexions qui semblent inutilisées. Bien sûr, il faut aussi laisser les connexions ouvertes suffisamment longtemps pour amortir leur création sur le plus grand nombre de requêtes possibles, mais il y a des limites à tout. (Le RFC suggère une durée maximale dans les dizaines de secondes, pouvant être abaissée à quelques secondes pour les serveurs très chargés.)

TCP est particulièrement intéressant pour le DNS quand TLS est inséré (RFC 7858). Mais il va alors consommer davantage de temps de CPU et, dans certains cas, l'établissement de connexion sera plus lent.

Le RFC donne quelques conseils quantitatifs (à ne pas appliquer aveuglément, bien sûr). Un maximum de 150 connexions TCP simultanées semble raisonnable pour un serveur ordinaire, avec un maximum de 25 par adresse IP source. Un délai de garde après inactivité de 10 secondes est suggéré. Par contre, le RFC ne propose pas de valeur maximale au nombre de requêtes par connexion TCP, ni de durée maximale à une connexion.

Les fanas des questions de sécurité noteront que les systèmes de journalisation et de surveillance peuvent ne pas être adaptés à TCP. Par exemple, un méchant pourrait mettre la requête DNS dans plusieurs segments TCP et donc plusieurs paquets IP. Un système de surveillance qui considérerait qu'une requête = un paquet serait alors aveugle. Notez qu'un logiciel comme dnscap a pensé à cela, et réassemble les paquets. Mais il est sans doute préférable, de nos jours, de se brancher sur le serveur, par exemple avec dnstap, notamment pour éviter de faire le réassemblage deux fois. (Ceux qui lisent mes articles depuis longtemps savent que je donnais autrefois le conseil inverse. Mais le déploiement de plus en plus important de TCP et surtout de TLS impose de changer de tactique.)


Téléchargez le RFC 9210


L'article seul

Implementation of the bioctal number format

First publication of this article on 14 April 2022


I just wrote an implementation of the bioctal number format, which is specified in RFC 9226 (RFC published on 1st April 2022).

The RFC standardizes a number format called "bioctal". I let you read the RFC to understand the rationale of this format. The implementation is written in the Elixir programming language and is available in the file bioctal.ex. It provides:

  • Sigils (Elixir's way to use literals in various formats; sigils start with a tilde) for input,
  • A formatting of numbers in bioctal for output.

An example of input:

IO.puts(~b{23cj}) # Thanks to the sigil ~b, "23cj" will be read as 9097
  

And an example of output:

IO.puts(format(9097)) # Will print "23cj"
  

L'article seul

RFC 9228: Delivered-To Email Header Field

Date de publication du RFC : Avril 2022
Auteur(s) du RFC : D. Crocker (Brandenburg InternetWorking)
Expérimental
Première rédaction de cet article le 14 avril 2022


Le courrier électronique est souvent plus compliqué et plus varié que ne le croient certains utilisateurs. Par exemple, rien ne garantit que l'adresse à laquelle un message est livré soit listée dans les champs de l'en-tête (RFC 5322) comme To: ou Cc:. Cette adresse de destination est en effet séparément gérée, dans le protocole SMTP (RFC 5321) et ses comandes RCPT TO. Et puis un message peut être relayé, il peut y avoir plusieurs livraisons successives. Bref, quand on a un message dans sa boite aux lettres, on ne sait pas forcément quelle adresse avait servi. D'où ce RFC expérimental qui propose d'élargir le rôle du champ Delivered-To: pour en faire un bon outil d'information.

Ce champ existe déjà et on le voit parfois apparaitre dans les en-têtes, par exemple dans un message que je viens de recevoir :

Delivered-To: monpseudo@sources.org
  

Mais il n'est pas vraiment normalisé, son contenu exact peut varier et, en pratique, lorsqu'il y a eu plusieurs délivrances successives suivies de transmissions à une autre adresse, il ne reste parfois qu'une occurrence de ce champ, la plus récente. Difficile donc de compter dessus.

Mais c'est quoi, la livraison d'un message ? Comme définie par le RFC 5598, dans sa section 4.3.3, c'est un transfert de responsabilité d'un MTA vers un MDA comme procmail. Il peut y avoir plusieurs délivrances successives par exemple si le MDA, au lieu de simplement écrire dans la boite aux lettres de l'utilisateur, fait suivre le message à une autre adresse. Un exemple typique est celui d'une liste de diffusion, où le message va être délivré à la liste puis, après transmission par le logiciel de gestion de listes, à chaque utilisateur (dont les MDA renverront peut-être le message, créant de nouvelles livraisons).

Pourquoi est-il utile d'avoir de l'information sur ces livraisons successives ? Outre la curiosité, une motivation importante est le débogage. S'il y a des problèmes de livraison, la traçabilité est essentielle à l'analyse. Une autre motivation est la détection automatique de boucles, un problème souvent compliqué.

On l'a dit, Delivered-To: existe déjà, même s'il n'était normalisé dans aucun RFC, bien qu'il soit cité dans des exemples, comme dans le RFC 5193. Ce RFC 9228 enregistre le champ (selon la procédure du RFC 3864), et prévoit d'étendre son application. (Une tentative de normalisation est en cours dans draft-duklev-deliveredto.) Du fait de cette absence de normalisation, il existe de nombreuses variations dans l'utilisation de Delivered-To:. Par exemple, si la plupart des logiciels mettent comme valeur une adresse de courrier et rien d'autre, certains ajoutent des commentaires. Notons que le champ Received: est souvent utilisé de la même façon, via sa clause for. On peut ainsi trouver (regardez le for) :

    
Received: from bendel.debian.org (bendel.debian.org [82.195.75.100])
        (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
        key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256)
        (No client certificate requested)
        by ayla.bortzmeyer.org (Postfix) with ESMTPS id 6D245A00D9
        for <monpseudo@sources.org>; Wed, 16 Feb 2022 13:22:03 +0100 (CET)

  

Là encore, il n'y a pas de normalisation et il semble qu'on ne puisse pas compter sur cette clause for. Par exemple, elle n'indique pas forcément une livraison mais peut être utilisée pour une simple transmission d'un serveur à un autre.

Venons-en à la définition de l'utilisation de Delivered-To: proposée par notre RFC dans sa section 4 :

  • Le champ Delivered-To: est ajouté uniquement lors d'une livraison,
  • sa valeur est l'adresse de courrier utilisée pour cette livraison (une adresse unique, jamais de liste),
  • si une réécriture de l'adresse est faite, on rajoute un Delivered-To: avec l'adresse réécrite,
  • comme il peut y avoir plusieurs Delivered-To: (en cas de livraisons multiples), le logiciel qui en ajoute un doit le mettre en haut (comme pour les autres champs de trace de l'en-tête, par exemple Received:, cf. RFC 5321, section, 4.1.1.4), l'ordre chronologique des Delivered-To: sera donc de bas en haut,
  • et donc les logiciels ne doivent pas réordonner les Delivered-To: ou en supprimer, sous peine de casser cette chronologie.

En conséquence, si un logiciel qui va ajouter un Delivered-To: avec une certaine adresse voit un Delivered-To: avec la même adresse, il peut être sûr qu'il y a une boucle. Voici un exemple de deux Delivered-To: différents, en raison du passage par une liste de diffusion (le message comportait évidemment bien d'autres champs dans son en-tête). La liste a été la première à traiter le message, la livraison finale ayant eu lieu après (donc plus haut dans le message, cf. section 5 du RFC) :

Delivered-To: monpseudo@sources.org
Delivered-To: lists-debian-user-french@bendel.debian.org
  

Le RFC donne un exemple imaginaire mais plus détaillé (j'ai raccourci les exemples du RFC, référez-vous à lui pour avoir les Received: et autres détails). D'abord, le message est émis par Ann :


From: Ann Author <aauthor@com.example>
Date: Mon, 25 Jan 2021 18:29:00 -0500
To: list@org.example
Subject: Sending through a list and alias
Sender: Ann Author <aauthor@com.example>   

  

Ce message a été envoyé à une liste de diffusion. Il est donc désormais :


Delivered-To: list@org.example
From: Ann Author <aauthor@com.example>
Date: Mon, 25 Jan 2021 18:29:06 -0500
To: list@org.example
Subject: Sending through a list and alias

  

Un des abonnés à la liste est alumn@edu.example. Chez lui, le message sera :


Delivered-To: alumn@edu.example
Delivered-To: list@org.example
From: Ann Author <aauthor@com.example>
Date: Mon, 25 Jan 2021 18:29:06 -0500
To: list@org.example
Subject: Sending through a list and alias

Et cet abonné fait suivre automatiquement son courrier à theRecipient@example.net. Le message, dans son état final, sera :

  

Delivered-To: theRecipient@example.net
Delivered-To: alumn@edu.example
Delivered-To: list@org.example
From: Ann Author <aauthor@com.example>
Date: Mon, 25 Jan 2021 18:29:06 -0500
To: list@org.example
Subject: Sending through a list and alias

Voilà, vous savez tout désormais sur l'extension proposée de l'utilisation de Delivered-To:. La section 6 attire toutefois notre attention sur quelques risques. Delivered-To: a comme valeur une donnée personnelle. Donc, attention, cela peut poser des questions de vie privée. Par exemple, la liste des adresses par lesquelles est passé un message peut en révéler plus que ce que le destinataire connaissait. Le problème risque surtout de se poser si quelqu'un fait suivre manuellement un message en incluant tous les en-têtes.

Autre problème potentiel, certains systèmes stockent les messages identiques en un seul exemplaire. Si on écrit à alice@example.com et bob@example.com, le serveur d'example.com pourrait décider de ne stocker qu'un seul exemplaire du message, avec des liens depuis les boites aux lettres d'Alice et Bob. Ce serait évidemment incompatible avec Delivered-To: (et pas question de mettre deux Delivered-To:, on ne veut pas révéler à Alice que Bob a reçu le message et réciproquement).


Téléchargez le RFC 9228


L'article seul

Mon atelier Elixir aux JDLL

Première rédaction de cet article le 3 avril 2022


Le 2 avril, j'ai eu le plaisir d'animer un atelier de découverte du langage de programmation Elixir aux JDLL. Voici le support de cet atelier.

C'était bien un atelier et pas un cours magistral. Les participant·es utilisaient les PC pré-configurés et installés de la salle, ou bien leur propre ordinateur portable qu'ielles avaient apporté, je leur donnais l'URL de l'atelier et je répondais aux questions, c'est tout. Le support contenait quelques indications, des liens vers des documentations, les exercices et une solution proposée. Ce système, à l'usage, me semble avoir très bien marché, notamment parce qu'il permettait à chacun·e d'avancer à son rythme (les niveaux en programmation étaient très différents), sans être frustré·e par un cours trop lent ou trop rapide.

Le support de l'atelier. Notez qu'il est évidemment bien trop long pour les deux heures de l'atelier, le but était que les participant·es puissent continuer par eux et elles-mêmes ensuite.

Merci aux organisateurices des JDLL pour un évènement toujours passionnant, et aux participant·es de mon atelier pour leur enthousiasme. Parmi les autres sujets que j'ai noté aux JDLL :

  • Une très intéressante conférence de l'association InfoClimat, l'OpenStreetMap des données météorologiques. Ils récoltent des données météo un peu partout, en partie de leurs propres stations (1 000 € pour une station météo sérieuse), en partie de stations gérées par d'autres (mais pas de Météo-France, qui ne donne pas grand'chose, au contraire) et publient le tout librement. Activité évidemment très utile vu l'importance de la météo. En outre, ils ne font pas que publier des données brutes mais fournissent également des logiciels pour les manipuler. Et il y a une base de photos météo. Leur exposé ne portait pas que sur le résultat de leur activité mais aussi sur les conditions du processus de production des données. Il faut notamment gérer des humains. Comment faire avec un bénévole qui avait installé une station dans un coin où il y avait peu de données mais qui, tout à coup, la déplace à l'ombre, faussant les mesures ? Diplomatie et pédagogie sont nécessaires. Ils ont beaucoup insisté sur le fait que le qualité des mesures est plus importante que leur quantité. Une station avec des instruments grand public, ou bien placée près d'arbres dont le feuillage, en dehors de l'hiver, gène les mesures, ne sert pas à grand'chose. Ils ont maintenant un peu d'argent et vont embaucher leur premier permanent, notamment pour s'occuper du logiciel (pas distribué publiquement car trop… trop illisible). Un excellent article de NextInpact détaille les activités de l'association, ainsi qu'un article sur le Framablog.
  • Une autre conférence passionnante de l'UCL sur les rapports entre le librisme et le courant libertaire. Leur conférence a couvert plein de sujets comme l'achat de publicité ciblée sur Facebook pour un parti politique, ou comme le problème de la présence en ligne pour des organisations libertaires. Si une seule personne a le mot de passe du WordPress, est-ce bien conforme aux principes d'horizontalité et d'action collective ? Si on choisit de s'auto-héberger plutôt que d'aller chez les GAFA, est-ce qu'on n'accroit pas la verticalité puisque peu de gens dans l'organisation auront les compétences nécessaires ?
  • Plus technique, il y a eu une excellente présentation de l'association 42l sur leurs serveurs et comment ils fonctionnent. 42l est un CHATON et gère quelques services, parfois publics, parfois réservés aux adhérents, sur deux VPS (l'association n'a pas encore le moyen d'avoir ses propres locaux avec ses machines dedans). Il y a entre autres un service DoH et un service Nitter (qui a un trafic nettement supérieur à celui de DoH). Chaque service est dans son propre conteneur Docker. Le service le plus gourmand en temps humain est le raccourcisseur de liens, en raison de liens de hameçonnage, qu'il faut supprimer.
  • L'équipe de l'Établi numérique a parlé de l'accompagnement émancipateur au numérique. L'idée de base est qu'il ne suffit pas d'être compétent et techniquement correct quand on accompagne des personnes au numérique, encore faut-il que cet accompagnement débouche sur un enpouvoirement (émancipation) de la personne accompagnée. Les orateurs prennent l'exemple de quelqu'un qui demande à ce qu'on l'aide à résoudre un problème Windows. Lui dire sèchement « Windows, c'est nul, il faudrait utiliser Linux » n'aide pas la personne (surtout, évidemment, si c'est formulé de manière méprisante). Si elle ne suit pas ce conseil, elle n'aura pas progressé. Si elle le suit, elle risque de se retrouver fort désarmée si un autre problème survient alors qu'elle n'a pas forcément de compétences Linux disponibles. Les orateurs estiment qu'il faut répondre aux demandes des utilisateurs. Cela semble de pur bon sens mais je ne suis que partiellement d'accord avec cet argument. En effet, il y a bien des questions inadaptées ou fausses, qui méritent une analyse critique. Lorsqu'un webmestre débutant demande comment améliorer son SEO, lui donner quelqus trucs pour gagner un peu de place dans le classement de Google ne va pas l'aider, par rapport à une critique de sa section et du danger d'une course à l'audience fondée sur ce qu'on croit savoir de l'algorithme de Google. (Cas réel, où la personne m'avait reproché de ne pas l'aider.) Pour reprendre l'exemple des orateurs, s'il est en effet préférable d'aider l'utilisateurice Windows (j'aurais personnellement du mal, vu mes compétences, mais je peux, comme suggéré par les orateurs, chercher avec elle), c'est quand même une marque de respect que de lui expliquer que certains problèmes n'ont pas de solution satisfaisante avec Windows. Lui cacher son opinion, sous couvert d'aide, ne serait pas honnête.

Et il y a plein de photos sympas en ligne.


L'article seul

RFC 9221: An Unreliable Datagram Extension to QUIC

Date de publication du RFC : Mars 2022
Auteur(s) du RFC : T. Pauly, E. Kinnear (Apple), D. Schinazi (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF quic
Première rédaction de cet article le 1 avril 2022


Le protocole QUIC fournit, comme son concurrent TCP, un canal fiable d'envoi de données. Mais certaines applications n'ont pas impérativement besoin de cette fiabilité et se contenteraient très bien d'un service de type datagramme. Ce nouveau RFC ajoute donc un nouveau type de trame QUIC, DATAGRAM, pour fournir un tel service.

Dit comme cela, évidemment, ça semble drôle, de bâtir un service non fiable au-dessus du service fiable que rend QUIC. Mais cela permet plusieurs choses très intéressantes, notamment si deux machines qui communiquent ont besoin des deux types de service : elles pourront utiliser une seule session QUIC pour les deux.

Un petit rappel (mais relisez le RFC 9000 pour les détails) : dans une connexion QUIC sont envoyés des paquets et chaque paquet QUIC contient une ou plusieurs trames. Chaque trame a un type et ce type indique si la trame sera retransmise ou non en cas de perte. Le service habituel (utilisé par exemple par HTTP/3) se sert de trames de type STREAM, qui fournissent un service fiable (les données perdues sont retransmises par QUIC). Mais toutes les applications ne veulent pas d'une telle fiabilité ou, plus précisement, ne sont pas prêtes à en payer le coût en termes de performance. Ces applications sont celles qui préféraient utiliser UDP (RFC 768) plutôt que TCP. Pour rajouter de la sécurité, elles utilisaient DTLS (RFC 6347). Si QUIC remplace TCP, comment remplacer UDP+DTLS ?

D'ailleurs, faut-il le remplacer ? La section 2 du RFC donne les raisons suivantes :

  • Les applications qui ont besoin à la fois d'un canal fiable et d'un canal qui ne l'est pas (par exemple une application de communication qui veut un canal fiable pour la signalisation et un pas forcément fiable pour les données multimédia) peuvent avec QUIC n'avoir qu'une seule session (et donc ne « payer » l'établissement de la session qu'une fois, ce qui diminuera la latence),
  • QUIC a un meilleur mécanisme de récupération des pertes que DTLS, lors de l'établissement de la connexion,
  • contrairement à UDP+DTLS, QUIC a un mécanisme de contrôle de la congestion, ce qui simplifie la tâche de l'application (cf. RFC 8085).

Ces raisons sont particulièrement importantes pour le streaming audio/vidéo, pour les jeux en ligne, etc. Les datagrammes dans QUIC peuvent aussi être utiles pour un service de VPN. Là aussi, le VPN a besoin à la fois d'un canal fiable pour la configuration de la communication, mais peut se satisfaire d'un service de type datagramme ensuite (puisque les machines connectées via le VPN auront leur propre mécanisme de récupération des données perdues). Permettre la création de VPN au-dessus de QUIC est le projet du groupe de travail MASQUE.

Bien, normalement, maintenant, vous êtes convaincu·es de l'intérêt des datagrammes au-dessus de QUIC. Pour en envoyer, il faut toutefois que les deux parties qui communiquent soient d'accord. C'est le rôle du paramètre de transport QUIC max_datagram_frame_size, à utiliser lors de l'établissement de la session. (Ce paramètre est enregistré à l'IANA.) S'il est absent, on ne peut pas envoyer de datagrammes (et le partenaire coupe la connexion si on le fait quand même). S'il est présent, il indique la taille maximale acceptée, typiquement 65 535 octets. Sa valeur peut être stockée dans la mémoire d'une machine, de façon à permettre son utilisation lors du 0-RTT (commencer une session QUIC directement sans perdre du temps en négociations). Un paquet QUIC 0-RTT peut donc inclure des trames de type DATAGRAM.

Ah, justement, ce type DATAGRAM. Désormais enregistré à l'IANA parmi les types de trames QUIC, il sert à indiquer des trames qui seront traitées comme des datagrammes, et qui ont la forme suivant :

DATAGRAM Frame {
     Type (i) = 0x30..0x31,
     [Length (i)],
     Datagram Data (..),
}
  

Le champ de longueur est optionnel, sa présence est indiquée par le dernier bit du type (0x30, pas de champ Longueur, 0x31, il y en a un). S'il est absent, la trame va jusqu'au bout du paquet QUIC (rappelons qu'un paquet QUIC peut contenir plusieurs trames).

Maintenant qu'on a des datagrammes comme QUIC, comment les utilise-t-on (section 5 du RFC) ? Rien d'extraordinaire, l'application envoie une trame DATAGRAM et l'application à l'autre bout la recevra. Si la trame n'est pas arrivée, l'émetteur ne le saura pas. La trame peut se retrouver avec d'autres trames (du même type ou pas) dans un même paquet QUIC (et plusieurs paquets QUIC peuvent se retrouver dans un même datagramme IP). La notion de ruisseau (stream) n'existe pas pour les trames-datagrammes, si on veut pouvoir les démultiplexer, c'est à l'application de se débrouiller. (Une version préliminaire de cette extension à QUIC prévoyait un mécanisme de démultiplexage, finalement abandonné.) Comme toutes les trames QUIC, les trames DATAGRAM sont protégées par la cryptographie. Le service est donc équivalent à celui d'UDP+DTLS, pas UDP seul.

Un service de datagrammes est non fiable, des données peuvent se perdre. Mais si les trames de type DATAGRAM ne sont pas réémises (pas par QUIC, en tout cas), elles entrainent néanmoins l'émission d'accusés de réception (RFC 9002, sections 2 et 3). Une bibliothèque QUIC peut ainsi (mais ce n'est pas obligatoire) notifier l'application des pertes. De la même façon, elle a la possibilité de dire à l'application quelles données ont été reçues par le QUIC à l'autre bout (ce qui ne garantit pas que l'application à l'autre bout les aient bien reçues, si on a besoin d'informations sûres, il faut le faire au niveau applicatif).

Comme l'émetteur n'estime pas crucial que toutes les données arrivent, une optimisation possible pour QUIC est que l'accusé de réception d'un paquet ne contenant que des trames DATAGRAM ne soit pas émis tout de suite, il peut attendre le paquet suivant.

Cette extension existe déjà dans plusieurs mises en œuvre de QUIC, mais je ne l'ai pas testée.


Téléchargez le RFC 9221


L'article seul

Articles des différentes années : 2022  2021  2020  2019  2018  2017  2016  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.