Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

Les RFC (Request For Comments) sont les documents de référence de l'Internet. Produits par l'IETF pour la plupart, ils spécifient des normes, documentent des expériences, exposent des projets...

Leur gratuité et leur libre distribution ont joué un grand rôle dans le succès de l'Internet, notamment par rapport aux protocoles OSI de l'ISO organisation très fermée et dont les normes coûtent cher.

Je ne tente pas ici de traduire les RFC en français (un projet pour cela existe mais je n'y participe pas, considérant que c'est une mauvaise idée), mais simplement, grâce à une courte introduction en français, de donner envie de lire ces excellents documents. (Au passage, si vous les voulez présentés en italien...)

Le public visé n'est pas le gourou mais l'honnête ingénieur ou l'étudiant.


RFC 7999: BLACKHOLE Community

Date de publication du RFC : Octobre 2016
Auteur(s) du RFC : T. King, C. Dietzel (DE-CIX Management), J. Snijders (NTT), G. Doering (SpaceNet AG), G. Hankins (Nokia)
Pour information
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 20 octobre 2016


Lorsqu'on est soumis à une sérieuse attaque par déni de service volumétrique, il faut parfois sacrifier la machine qui en est la cible, afin de préserver le reste des ressources réseau. On demande alors à son opérateur de jeter le trafic à destination de cette machine, avant qu'il n'emprunte la liaison qu'on veut préserver. Cela peut se faire manuellement mais c'est évidemment plus rapide et moins risqué si on le fait automatiquement, via une annonce BGP vers le préfixe visé. Pour cela, on marque l'annonce BGP avec une communauté (RFC 1997) qui veut dire « poubelle donc tout ce trafic ». Ce nouveau RFC normalise une communauté standard, « bien connue », pour cela, BLACKHOLE (0xFFFF029A). Ainsi, il n'y aura plus besoin d'utiliser une communauté différente pour chaque opérateur.

Cette méthode consistant à envoyer le trafic destiné à la victime vers un « trou noir » (blackholing) est décrite dans les RFC 3882 et RFC 5635. Comme elle agit au niveau IP, elle ne nécessite pas d'équipements spéciaux, et elle est très rapide, ne prenant que peu de ressources chez les routeurs. Par contre, elle est peu subtile : tout le trafic à destination d'un préfixe donné (préfixe en général réduit à une seule adresse IP, celle de la machine attaquée) est jeté, qu'il fasse partie de l'attaque ou pas. Quel est l'intérêt de couper tout le trafic ? Cela réalise l'objectif de l'attaquant, non ? C'est en effet une mesure désespérée mais rationnelle : son but est de préserver les ressources réseau pour que les autres machines fonctionnent. Si vous êtes connecté à l'Internet par une liaison à 10 Gb/s, et qu'une attaque de 20 Gb/s frappe votre opérateur, votre ligne va être complètement inutilisable. Aucune action de votre côté n'y changerait rien, dès que les paquets sont arrivés chez vous, c'est trop tard. Ce RFC traite le cas où on demande à l'opérateur de jeter le trafic avant qu'il ne soit envoyé sur la ligne entre l'opérateur et vous.

Le problème (section 1 du RFC) est qu'il existait plusieurs méthodes pour déclencher cet envoi dans un trou noir, ce qui compliquait la tâche des équipes réseau, une annonce BGP marquée avec une certaine communauté, une annonce BGP avec un certain next hop, et des méthodes non-BGP (dont le coup de téléphone au NOC). D'où la solution de notre RFC, définir une communauté standard. Plus besoin de se poser de question (à part celle de savoir si votre opérateur accepte cette commande, voir les sections 3.3 et 4). Au passage, les communautés BGP sont décrites dans le RFC 1997.

Une communauté BLACKHOLE est donc définie (section 2) et mise dans le registre IANA des communautés bien connues. Sa valeur est 0xFFFF029A. Le 666 à la fin vient de la Bible et était déjà couramment employé par les opérateurs. Notez donc que ce RFC n'invente pas une nouvelle technique (demander à son pair de jeter certains paquets est une technique très ancienne), il lui donne juste une communauté standard.

Voilà, c'est tout, juste une réservation d'un nom et d'une valeur. Si vous êtes intéressés par les détails pratiques, la section 3 est consacrée aux problèmes opérationnels. D'abord, un point essentiel : accepter des annonces BGP étiquetées BLACKHOLE est un choix local. Aucun opérateur n'est obligé de respecter cette demande et, dans ce cas, ladite communauté est ignorée. Lorsqu'on se connecte à un nouveau pair BGP, il peut donc être prudent de lire leur documentation ou de leur poser la question. N'utilisez BLACKHOLE qu'entre des adultes consentants. (Notez que cet avertissement du RFC est un peu contradictoire avec l'avantage proclamé de la normalisation de BLACKHOLE : en pratique, on est toujours obligé de savoir ce que fait son pair, on ne peut pas compter sur une méthode standard qui marcherait partout.) Une liste des opérateurs et points d'échange qui acceptent BLACKHOLE est disponible en ligne.

Si tout le monde accepte BLACKHOLE, on s'en sert comment ? Lorsqu'une attaque DoS est en cours, on annonce un préfixe qui couvre l'adresse IP visée, et on y ajoute cette communauté. On peut aussi utiliser BLACKHOLE pour les annonces du RFC 5635 (mais pas avec celles du RFC 5575).

Attention à ne pas propager ces annonces ! En effet, étant en général très spécifiques (souvent une seule adresse IP), elles seraient préférées, si elles étaient insérées dans une table de routage. Leur effet est prévu pour être strictement local et, donc, les annonces doivent être marquées avec la communauté NO_EXPORT (ou NO_ADVERTISE).

En parlant de spécificité, quelle doit être la longueur des préfixes annoncés avec un BLACKHOLE attaché ? Souvent, l'attaque ne vise qu'une seule adresse et, donc, les annonces BLACKHOLE seront souvent des /32 (en IPv4) et /128 (en IPv6), afin de ne sacrifier que le strict minimum de son réseau. Si vous avez une politique BGP de n'accepter que des préfixes plus généraux, c'est un point à modifier. Aujourd'hui (RFC 7454, section 6.1.3), les préfixes plus spécifiques que /24 (IPv4) et /48 (IPv6) sont rarement acceptés. Il faut donc faire des exceptions pour les trous noirs.

Lorsqu'un opérateur reçoit une de ces annonces « envoie-moi tout ça dans un trou noir », que doit-il vérifier ? Comme le résultat de cette annonce est de jeter tout le trafic, une attaque avec une annonce mensongère, ou bien une erreur d'un opérateur maladroit, pourrait avoir de sérieuses conséquences. Notre RFC recommande donc un certain nombre de tests de vraisemblance : vérifier que le pair est autorisé à annoncer un préfixe couvrant celui qu'il annonce avec BLACKHOLE, et vérifier que BLACKHOLE avec ce pair a été spécifiquement permis (le RFC recommande plus loin que ce ne soit pas permis par défaut). Même chose s'il y a des serveurs de route (RFC 7947) sur le trajet.

Par contre, il faut, pour le cas spécifique des annonces BLACKHOLE, débrayer les techniques de validation comme celle du RFC 6811. Par exemple, si un ROA (Route Origin Authorisation, RFC 6482) autorise une longueur maximale de préfixe de /48, l'annonce BLACKHOLE de longueur /128 doit quand même être acceptée.

À des fins de traçabilité, pour faciliter l'analyse a posteriori d'une attaque, et du traitement qu'elle a reçu, le RFC recommande de journaliser toutes les annonces BLACKHOLE. (Cela permettra, par exemple, de repérer les pairs qui abusent du mécanisme, cf. section 6.)

Si vous travaillez chez un éditeur de logiciels pour routeurs, n'oubliez pas les conseils de la section 4, destinés aux programmeurs. D'abord, l'acceptation des annonces « trou noir » ne devrait pas être faite par défaut. Le RFC demande qu'une action explicite de l'administrateur réseau soit nécessaire. D'autre part, pour ne pas avoir à taper la valeur numérique de cette communauté, le RFC suggère de permettre une valeur texte à indiquer, par exemple blackhole.

Quelques petits points sur la sécurité pour finir (section 6). D'abord, bien se rappeler que BGP n'a par défaut aucun mécanisme pour empêcher ou détecter les modifications des annonces. Si un attaquant actif retire ou ajoute la communauté BLACKHOLE, ça ne se voit pas. Même le futur BGPSec ne l'empêchera pas, puisqu'il ne protège pas les communautés. Il y a donc des possibilités d'attaques par déni de service de ce côté.

C'est entre autre pour cela que le RFC demande qu'on vérifie qu'un pair qui annonce un préfixe avec BLACKHOLE est autorisé à le faire (RFC 7454, section 6.2.1.1.2).


Téléchargez le RFC 7999


L'article seul

RFC 7998: "xml2rfc" Version 3 Preparation Tool Description

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : P. Hoffman (ICANN), J. Hildebrand (Cisco)
Pour information
Première rédaction de cet article le 16 décembre 2016


Depuis la sortie du RFC 7990, le format canonique des RFC est le format XML. C'est un texte écrit en XML, selon le vocabulaire du RFC 7991 qui sera la version de référence, archivée et faisant autorité, pour tous les RFC. Comme les auteurs enverront souvent un XML imparfait, un outil de préparation sera nécessaire, pour compléter ce XML imparfait et permettre au RFC Editor de travailler sur une base sérieuse. Ce nouveau RFC décrit ce futur outil de préparation.

Ainsi, les outils qui travailleront sur le format canonique des RFC (par exemple les outils qui produiront le PDF, le HTML, etc) pourront compter sur un document complet et n'auront pas à gérer les écarts des auteurs : seul l'outil de préparation devra s'en soucier.

Cet outil de préparation servira aux RFC une fois qu'ils seront soumis au RFC production center (cf. RFC 8728) mais aussi aux Internet-Drafts pendant leur élaboration.

Dans le second cas (section 3 de notre RFC), le futur outil de préparation prendra un Internet-Draft en entrée et produira un document complet (par exemple avec addition des boilerplates).

Et ce sera à peu près la même chose lorsque le RFC sera presque fini. On passera la version finale dans l'outil de préparation, qui résoudra les références externes et ajoutera les éléments obligatoires manquants.

Bon, et en quoi vont consister exactement ces modifications ? Elle sont décrites dans la section 5, qui forme le gros de ce RFC. Contrairement à l'outil actuel idnits qui se contente de vérifier les Internet-Drafts, le nouvel outil va également corriger le texte, ajoutant des éléments, et changeant les valeurs erronées.

C'est ainsi que l'outil de préparation va traiter les éléments XInclude, les remplaçant par la valeur incluse. Il va traiter les DTD pour les supprimer ensuite (donc, remplacer les entités par leur valeur, et inclure les fichiers inclus par ce mécanisme). Ces deux actions peuvent aujourd'hui être faites par l'outil xmllint, avec xmllint --xinclude --noent --dropdtd NOMDUFICHIER.xml.

Outre ces mécanismes d'inclusion de XML, l'outil de préparation va aussi traiter les inclusions spécifiques au vocabulaire du RFC 7991. Ainsi, <artwork> a un attribut src indiquant la source du graphique, et l'outil de préparation va donc inclure ce graphique. (Idem avec <sourcecode> pour inclure le code source.)

Les instructions XML (PI, Processing Instructions) seront supprimées (ça, je ne sais pas le faire avec xmllint).

L'outil va valider le résultat produit, en utilisant la grammaire Relax NG du RFC 7991. Ça peut aujourd'hui se faire avec xmllint mais aussi avec rnv :

% rnv rfc-v3.rnc rfc-v3-sample.xml
rfc-v3-sample.xml
    

ou bien avec jing :

% java -jar ./jing-20091111/bin/jing.jar  -c rfc-v3.rnc rfc-v3-sample.xml
    

Parmi les nombreuses transformations possibles, citons l'ajout (s'il n'était pas déjà présent) de l'élément <seriesInfo> qui indique s'il s'agit d'un Internet-Draft ou d'un RFC, l'ajout d'un élément <date> s'il manque (sa valeur étant la date du traitement), changement de l'ancien attribut title en name, le retrait des commentaires XML...

Il est fréquent dans les Internet-Drafts de voir des paragraphes qui ne devront pas être inclus dans le futur RFC. C'est le cas s'ils contiennent des exemples réels qui risquent de ne pas être éternels (les RFC peuvent durer longtemps et ne sont jamais modifiés). C'est également le cas s'il s'agit de l'état actuel des mises en œuvre d'un RFC, comme décrit dans le RFC 7942. Dans le système actuel, ces paragraphes sont marqués par un texte en langue naturelle. Dans le nouveau vocabulaire du RFC 7991, ce sera fait avec un attribut removeInRFC. L'outil de préparation pourra enlever automatiquement ce paragraphe quand il préparera un RFC.

L'outil de prépartion devra également arranger le XML. Cela peut se faire aujourd'hui avec xmllint (ses options --format ou bien --pretty). Par contre, il n'est pas prévu de mettre le XML sous sa forme canonique.

Il y aura d'autres opérations faites par l'outil de préparation, voir le RFC pour les détails.

L'outil n'est pas encore développé, un appel d'offres a été lancé et les gagnants ont été les sociétés SeanTek et Elf Tools.


Téléchargez le RFC 7998


L'article seul

RFC 7997: The Use of Non-ASCII Characters in RFCs

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : H. Flanagan (RFC Editor)
Pour information
Première rédaction de cet article le 16 décembre 2016


Les RFC sont forcément écrits en anglais, qui restera la langue officielle (cf. RFC 7322). L'anglais peut s'écrire avec uniquement les caractères ASCII (avec quelques exceptions : resume et résumé ne sont pas le même mot). Mais on pourra désormais inclure des caractères non-ASCII, par exemple pour le nom des auteurs (chic, je pourrais écrire correctement mon prénom dans les RFC). Cette possibilité permettra aussi aux exemples de protocoles Internet utilisant Unicode (la grande majorité) d'être plus lisibles.

Cette nouvelle possibilité fait partie de celles qu'offre le nouveau format des RFC, décrit dans le RFC 7990. Il n'y a quand même pas d'autorisation générale d'inclure n'importe quel caractère Unicode dans les RFC, à n'importe quel endroit. Le RFC Editor pourra toujours refuser tel ou tel caractère, par exemple parce qu'il n'existe pas de police permettant de l'afficher. Et le « non-ASCII » n'est autorisé que dans certains cas, décrits plus loin. La grande majorité du texte sera donc du pur ASCII (RFC 20).

L'encodage de ces caractères sera bien sûr UTF-8.

Il ne suffit pas de proclamer « on a droit à Unicode ». Il faut aussi adapter les outils. Par exemple, notre RFC impose (section 2) que les outils de recherche dans les RFC gèrent correctement la recherche Unicode. (C'est pour traiter le cas des outils imparfaits que le RFC demande aussi que les noms d'auteurs en Unicode soient accompagnés d'une version en ASCII.) Et que le RFC soit affichable correctement sur un bon nombre de plate-formes (d'où la possibilité de rejeter les caractères les plus rares).

Ce problème du repli (vers une version en ACSII pur) est souvent cité dans le RFC. Ainsi, lorsqu'on veut mentionner un caractère Unicode (mettons le thorn islandais), le RFC permet désormais de l'afficher proprement, mais il demande qu'on l'accompagne du numéro du point de code, et, si possible, de son nom Unicode. Cela donnerait, par exemple « For instance, U+00FE, "LATIN SMALL LETTER THORN", þ, is interesting because... ». Notez que cette façon de désigner des caractères Unicode que tout le monde n'arrivera pas forcément à afficher n'est pas vraiment standardisée. Dans les RFC actuels, on trouve des variantes (voir cette discussion). Le RFC contient plusieurs exemples sur la façon d'écrire la phrase « Temperature changes in the Temperature Control Protocol are indicated by the U+2206 character (∆, "INCREMENT") », tous acceptés (le nom Unicode n'est pas obligatoire, il peut être placé avant ou après le caractère lui-même, etc.) Autre cas, ce texte du RFC 8264, « For example, the characters U+13DA U+13A2 U+13B5 U+13AC U+13A2 U+13AC U+13D2 from the Cherokee block look similar to the ASCII characters "STPETER" » deviendrait « For example, the characters U+13DA U+13A2 U+13B5 U+13AC U+13A2 U+13AC U+13D2 (ᏚᎢᎵᎬᎢᎬᏒ) from the Cherokee block look similar to the ASCII characters "STPETER" ». Des tables comme celles des identificateurs et mots de passe Unicode légaux (RFC 8265) seraient ainsi bien plus lisibles.

Pour les noms, par exemple ceux des auteurs. On aurait du « non-ASCII » et un texte de repli, comme (en utilisant le vocabulaire XML du RFC 7991) :

    
<author fullname="רוני אבן" asciiFullname="R. Even"/>
<author fullname="吴钦" asciiFullname="Q. Wu"/>
<author fullname="J. Smith" asciiFullname="J. Smith"/> <!-- Oui, dans
ce cas, il faut le dire deux fois -->

  

Cela permettra enfin d'écrire correctement les noms des auteurs de RFC.

La bibliographie d'un RFC est également un bon endroit où mettre des caractères Unicode, par exemple lorsqu'on cite des textes non-anglo-saxons. Ainsi, la bibliographie du RFC 5933 pourrait inclure :

[GOST3410] "Information technology. Cryptographic data security.
           Signature and verification processes of [electronic]
           digital signature.", GOST R 34.10-2001, Gosudarstvennyi
           Standard of Russian Federation, Government Committee of
           Russia for Standards, 2001. (In Russian)

           "Информационная технология. Криптографическая защита
           информации. Процессы формирования и проверки
           электронной цифровой подписи", GOST R 34.10-2001,
           Государственный стандарт Российской Федерации, 2001.

Le second texte étant l'original russe.

Les règles exactes figurent dans la section 3. D'abord, on peut mettre du « non-ASCII » comme on veut quand il fait partie d'un exemple. Ainsi, la communication XMPP pourrait être décrite de manière plus naturelle. Au lieu de cet exemple de communication en tchèque (RFC 6121) :

  
   <message
       from='juliet@example.com/balcony'
       id='z94nb37h'
       to='romeo@example.net'
       type='chat'
       xml:lang='en'>
     <body>Wherefore art thou, Romeo?</body>
     <body xml:lang='cs'>
        Pro&#x010D;e&#x017D; jsi ty, Romeo?
      </body>
   </message>

On pourra écrire la forme lisible :

  
   <message
       from='juliet@example.com/balcony'
       id='z94nb37h'
       to='romeo@example.net'
       type='chat'
       xml:lang='en'>
     <body>Wherefore art thou, Romeo?</body>
     <body xml:lang='cs'>
        PročeŽ jsi ty, Romeo?
      </body>
   </message>

Ensuite, on peut utiliser le « non-ASCII » pour les cas cités plus haut (noms d'auteurs, textes non-anglophones dans la bibliographie, etc). Pour les exemples utilisant un langage de programmation, notre RFC spécifie qu'il faut suivre les règles du langage en question. Ainsi, Python 3 autorisant l'Unicode même dans les noms de variables, on peut écrire :

    
a = "chocolat" 
b = "café"       # Accentué
ç = "lait"
print(a+b+ç)

  

Enfin, un petit mot sur la normalisation Unicode, pour rappeler que le format des RFC ne garantit rien à ce sujet (on aurait pu décider que NFC serait systématiquement utilisée...) et que les auteurs de RFC ne doivent donc pas compter dessus.

Le premier RFC publié avec des caractères Unicode a été le RFC 8187, en septembre 2017.


Téléchargez le RFC 7997


L'article seul

RFC 7996: SVG Drawings for RFCs: SVG 1.2 RFC

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : N. Brownlee (University of Auckland)
Pour information
Première rédaction de cet article le 16 décembre 2016


Dans la longue liste de RFC décrivant le nouveau format des RFC (commencez par le RFC 7990), ce document décrit l'utilisation de SVG pour faire (enfin) des graphiques dans les RFC.

Traditionnellement, en effet, seul le texte était possible dans les RFC. (On pouvait toutefois faire des graphiques en art ASCII, dont on imagine bien que ce n'était ni très pratique à écrire - malgré l'excellent mode Emacs picture-mode, ni très facile à lire.) Il y avait de bonnes raisons à cet état de fait, notamment le manque d'un format d'images ouvert et largement répandu. Je parle bien sûr d'images vectorielles car, a priori, dans un RFC, il y aura beaucoup plus de schémas que de photos.

Le processus de décision a été long et compliqué. En 2013, le RFC 6949 notait déjà la décision de permettre des images, en indiquant « Graphics may include ASCII art and a more complex form to be defined, such as SVG line art ». C'est désormais possible. Au fait, c'est quoi, SVG ? Il s'agit d'une norme d'un format d'images vectoriel, gérée par le W3C, et fondée sur XML. Voici un exemple d'un simple dessin en SVG :


<svg xmlns="http://www.w3.org/2000/svg" version="1.2">
  <rect x="25" y="25" width="200" height="200" fill="white" stroke-width="4" stroke="black" />
  <circle cx="125" cy="125" r="75" fill="black" />
  <polyline points="50,150 50,200 200,200 200,100" stroke="black" stroke-width="4" fill="none" />
  <line x1="50" y1="50" x2="200" y2="200" stroke="white" stroke-width="4" />
</svg>

Et voici son rendu : simple-rfc-picture

Les RFC n'utiliseront qu'un sous-ensemble de SVG, spécifié ici. Il existe d'autres sous-ensembles de SVG comme SVG Tiny, prévu pour des équipements contraints, genre smartphones. Ce SVG Tiny a servi de base au SVG des RFC, sous-ensemble limité car on n'attend pas de dessins artistiques et compliqués dans les RFC.

SVG RFC est donc SVG Tiny moins les éléments permettant le multimédia et l'animation (pas de vidéos dans les RFC), l'interaction (pas d'interface utilisateur active dans un RFC), l'utilisation de langages de programmation (pas de JavaScript actif dans un RFC). Plusieurs autres restrictions ont été apportées : pas de couleur (RFC 6949, section 3.2), pas d'IRI, seulement des URI, et pas de choix arbitraire de police.

Comment on écrit du SVG ? S'il est évidemment possible de le faire entièrement à la main avec un éditeur ordinaire, gageons que peu de gens le tenteront. Notre RFC cite des éditeurs graphiques, produisant du SVG, comme les logiciels libres Inkscape et Dia. (Et, si on aime programmer en Python, il y a svgwrite, que je présente plus en détail à la fin.) Attention, Inkscape et Dia produisent du SVG généraliste, pas du SVG RFC, qui est plus restreint. (Je ne connais personnellement pas d'outil pour produire du SVG RFC, ou pour « réduire » un fichier SVG généraliste en enlevant tout ce qui n'appartient pas à SVG RFC. Un tel outil était prévu mais je ne sais pas où il en est. C'était une des fonctions attendues du futur svgcheck.)

Et l'accessibilité (section 4) ? Il est crucial que les RFC soient accessibles à tou·te·s, non seulement que que soit le matériel utilisé, mais également quels que soient les handicaps dont souffre leur propriétaire. C'est bien joli de vouloir ajouter des tas de choses dans les RFC mais encore faut-il ne pas creuser ainsi davantage le fossé entre les utilisateurs. Ainsi, accepter de la couleur (le RFC 6949 limite les futurs RFC au noir et blanc) fait courir le risque que les daltoniens ne puissent pas comprendre un RFC. De même, les graphiques, qui ont l'air comme ça d'être une bonne idée, peuvent aggraver la situation des malvoyants. Le texte seul peut toujours être lu à voix haute par un synthétiseur de parole mais pas le graphique. Comme le note le RFC avec humour, « lire le source SVG à voix haute ne va pas le faire ».

Le texte « Tips for Creating Accessible SVG » donne des bons conseils pour faire du SVG accessible. Et il y a bien sûr la norme ARIA, dont il existe une introduction et de bons exemples. (Désolé, je n'ai pas suivi ces excellents principes dans les exemples ci-dessous, mais j'accepte les patches.)

Si vous voulez voir des exemples concrets, regardez https://www.cs.auckland.ac.nz/~nevil/SVG_RFC_1.2/. Ainsi, l'exemple de schéma d'un en-tête TCP donnera : tcp-header Et le schéma de la communication SIP du RFC 4321 fera rfc4321-fig3.svg

L'annexe A de notre RFC donne un schéma complet (formulé en Relax NG) du SVG des RFC. Il est extrait ici dans le fichier svg-rfc.rnc, que vous pouvez utiliser pour tester la conformité de vos SVG. Par exemple, avec rnv :

% rnv files/svg-rfc.rnc files/tcp-header.svg  
files/tcp-header.svg
    

En revanche, avec du SVG trop « riche » (ici, utilisant les couleurs), on aurait :

% rnv files/svg-rfc.rnc /tmp/test1.svg 
...
/tmp/test1.svg:2:267: error: attribute ^fill with invalid value "red"
required:
	value ^token "none"
	value ^token "black"
	value ^token "white"
	value ^token "#000000"
	value ^token "#FFFFFF"
	value ^token "#ffffff"
	value ^token "inherit"
    

Une alternative, pour tester la validité des SVG conformes à ce profil, sera svgcheck quand il sera développé.

Avec Inkscape, il faut veiller à sauver le fichier en Plain SVG (autrement, on a des ennuis avec les éléments spécifiques d'Inkscape, ex-Sodipodi). Mais il reste malgré cela deux ou trois trucs à corriger manuellement, avant que le document produit par Inkscape soit accepté. Pour Dia, il faut utiliser l'action Export (par défaut, Dia n'enregistre pas en SVG), mais Dia produit alors un document avec une DTD. Si on la retire (manuellement, ou bien avec xmllint --dropdtd), tout se passe bien, le document SVG est alors conforme au profil demandé pour les RFC.

Autre solution que j'aime bien pour faire du SVG, dès qu'on a des éléménts répétitifs et qu'on veut donc automatiser (en Python), svgwrite. Ce schéma en art ASCII :

 +--------------+				     +----------------+
 |  Alice       |------------------------------------|      Bob	      |
 | 2001:db8::1  |                                    |   2001:db8::2  |
 +--------------+				     +----------------+
    

aurait pu être créé avec svgwrite avec network-schema-svgwrite.py, qui donne network-schema-svgwrite

Bien sûr, pour un schéma aussi simple, le gain n'est pas évident, mais il le devient pour les schémas comportant beaucoup d'éléments récurrents. Mais notez que svgwrite ne connait pas le profil « SVG pour RFC » et, par défaut, peut donc produire des SVG invalides (par exemple avec de la couleur). Le programmeur doit donc faire attention.


Téléchargez le RFC 7996


L'article seul

RFC 7995: PDF Format for RFCs

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : T. Hansen (AT&T Laboratories), L. Masinter, M. Hardy (Adobe)
Pour information
Première rédaction de cet article le 16 décembre 2016


Parmi les nombreux formats de publication des RFC prévus suite à l'adoption du nouveau format (RFC 7990), ce RFC décrit l'utilisation de PDF. On pourra donc, en suivant ces règles, avoir une jolie version papier des RFC.

Actuellement, les RFC peuvent bien sûr être imprimés mais c'est un peu tristoune (cf. annexe A). Avec le nouveau cadre de gestion des RFC, le format canonique du RFC sera du XML (RFC 7991), à partir duquel seront produits automatiquement (par des outils qui ne sont pas encore développés) divers formats. HTML sera sans doute le principal pour une publication en ligne (RFC 7992), mais il y a des partisans de PDF, surtout pour l'impression sur le bon vieux papier. Ce RFC 7995 décrit donc l'utilisation de PDF comme format de sortie pour les RFC. À noter que ce format, créé et piloté par une entreprise privée n'est pas à proprement parler un « format Internet » et est sans doute moins connu des participants à l'IETF que ne l'est HTML.

La norme PDF est déposée à l'ISO (ISO 32000-1) mais l'archaïque ISO ne distribue toujours pas librement ces documents. Si on veut apprendre PDF, il faut donc le télécharger sur le site d'Adobe.

Première question (section 2 de notre RFC), quelle version de PDF choisir ? PDF a évolué dans le temps, chaque version ajoutant de nouvelles fonctions. C'est aujourd'hui un format très complexe, difficile à mettre en œuvre complètement. C'est pour cela qu'il existe des profils de PDF, restreignant ce format pour des usages spécifiques. Ainsi, PDF/X est conçu pour l'échange de fichiers avec l'imprimeur. Pour les RFC, documents souvent normatifs, et à longue durée de vie, les exigences principales sont l'accessibilité et la stabilité. C'est ce que fournissent les profils PDF/UA (accessibilité) et PDF/A-3 (archivage à long terme).

Pour les RFC, les profils choisis sont la version 1.7 de PDF, suffisamment ancienne pour être gérée par la plupart des logiciels, le profil PDF/A-3 pour limiter le nombre de fonctions à gérer, et PDF/UA pour l'accessibilité.

La section 3 de notre RFC détaille ensuite toutes les exigences particulières des RFC, pour le format de sortie PDF. Je ne les commente pas toutes ici, seulement celles qui me semblent importantes. Par exemple, la délicate question des polices. PDF permet d'inclure une police dans le document, ou bien de se référer simplement à une police par son nom. Dans ce dernier cas, si le logiciel qui lit le PDF ne trouve pas exactement cette police, il se rabat sur une police « proche », avec un résultat qui n'est pas forcément satisfaisant. De toute façon, PDF/A, le profil « archivage » impose d'inclure la police utilisée, pour éviter de dépendre de logiciels futurs. À noter que cela peut impliquer de payer : peu de polices sont gratuites pour l'auteur. L'annexe C.4 discute des polices acceptables. Il y a les gratuites, mais sans support Unicode complet, comme Source Sans Pro, Source Serif Pro ou Source Code Pro. Bien meilleure du point de vue de la couverture Unicode, mais payante, est Skolar. L'idéal sera peut-être la nouvelle police Noto. Les RFC ayant maintenant le droit d'utiliser des caractères non-ASCII, mais avec des restrictions (cf. RFC 7997), il est possible que des caractères soient refusés par le RFC Editor uniquement parce qu'ils ne sont pas présents dans les polices utilisées.

Le choix des caractéristiques des polices (chasse fixe ou variable, empattement ou pas) devra suivre les mêmes règles que pour HTML et CSS, règles qui figurent dans le RFC 7993. À propos de HTML, notons d'ailleurs que notre RFC sur PDF demande que le PDF ressemble visuellement autant que possible au document HTML. Si vous écrivez un logiciel qui produit le PDF pour un RFC et que vous hésitez sur tel ou tel aspect graphique, consultez le RFC 7992 sur la sortie HTML.

Parmi les autres exigences pour la production de PDF, notre RFC demande qu'on évite les césures.

PDF permet de mettre des liens hypertextes. L'intérêt est faible puisque PDF est surtout utilisé pour le papier (si on regarde sur un écran PDF n'a aucun avantage par rapport au format bien plus ouvert qu'est HTML), mais le RFC prévoit quand même cette possibilité. Il y aura donc des liens, à la fois externes (vers des URL, y compris vers d'autres RFC et, dans ce cas, le RFC 7322 requiert que cela soit vers la page d'information officielle du RFC Editor) et internes (une section du RFC référençant une autre). Les liens internes sont parfois produits automatiquement (par exemple depuis la table des matières vers les sections du texte).

Un problème délicat est celui de la façon dont le texte est stocké dans le document PDF. PDF permet en effet plusieurs façons de réaliser ce stockage. Elles donnent le même résultat visuel mais se comportent différemment pour des fonctions comme la recherche de texte. Ainsi, le mot « IETF » peut être stocké comme une image, comme quatre lettres positionnées indépendamment, ou comme un mot unique. Le stockage en image posera évidemment des problèmes aux outils comme pdftotext (mais ce n'est pas forcément grave pour les RFC, on a toujours le source XML) ou aux outils de synthèse vocale, nécessaires aux malvoyants. Pour la recherche de texte, la solution du mot unique est certainement meilleure, même si elle ne permet pas une typographie aussi subtile. Mais il y a aussi le placement des phrases. La phrase « The IETF supports the Internet » peut être stockée comme cinq mots différents stockés indépendamment (y compris dans un ordre différent de celui de la phrase) et positionnés ensuite, ou bien comme un objet unique.

Notre RFC recommande d'au moins garder les mots dans l'ordre du texte (PDF/UA l'impose).

Pour les images, si le source XML contenait à la fois de l'art ASCII et du SVG, notre RFC impose bien sûr qu'on utilise le SVG pour produire le PDF. Le texte alternatif aux images, indispensable pour l'accessibilité, doit être mis dans le PDF (dans la propriété /Alt).

Les métadonnées (noms des auteurs, date, etc) sont très utiles pour l'indexation et la recherche et doivent donc être mises dans le PDF. PDF a plusieurs façons d'embarquer des métadonnées, et la recommandation est d'utiliser XMP.

Parmi les zillions de fonctions de PDF, il peut agir en container d'autres fichiers (oui, comme tar ou AVI). Tous les logiciels PDF ne savent pas extraire ces fichiers embarqués dans le PDF mais c'est une fonction utile, au cas où. Le RFC recommande donc que des fichiers utiles soient ainsi embarqués : le source XML du RFC, les codes sources (dans les éléments <sourcecode> du RFC), les images (dont les sources SVG)...

Dernier point, les éventuelles signatures. Pour l'instant, il n'y a pas de mécanisme standard pour signer les RFC et en garantir l'authenticité mais, lorsque ce sera le cas, PDF permettra d'inclure une signature dans le fichier produit. (Cette fonction existe dans PDF depuis longtemps.)

Le RFC contient aussi trois annexes intéressantes. L'annexe A est un historique de la relation compliquée entre les RFC et PDF. Depuis longtemps, une version PostScript du RFC était acceptée par le RFC Editor et publiée, même si très peu d'auteurs en ont profité. Cela concernait surtout les RFC ayant des images ou des formules mathématiques comme les RFC 1119 ou RFC 1142. Le PDF produit par le RFC Editor pour tous les RFC (ou par https://tools.ietf.org/) n'était, lui, qu'une simple « impression » du RFC en texte brut.

L'annexe B rappelle ce que doit faire un bon logiciel de production de contenu imprimé, avec découpage en pages. C'est plus dur que cela n'en a l'air, car il faut gérer les veuves et les orphelines, ne pas couper juste après le titre d'une section, ne pas couper les dessins en art ASCII, placer les tableaux intelligemment, etc.

Enfin, l'annexe C décrit une partie des outils disponibles pour le producteur de documents PDF. Si les logiciels de visualisation sont nombreux, il faut noter que tous n'ont pas la totalité des fonctions qu'utilise le format de sortie des RFC (par exemple les liens hypertexte). Du côté des imprimantes (le papier étant le but final de la plupart des documents PDF), certaines savent même gérer le PDF directement (dans les autres cas, ce sera au logiciel de visualisation de produire le format attendu par l'imprimante, souvent PostScript).

Et pour produire le PDF à partir du XML des RFC ? Une solution possible, puisqu'il existe une feuille de style XSLT (disponible en ligne) est de produire du FO qui sera ensuite transformé en PDF, par exemple avec FOP (je n'ai personnellement eu que des expériences décevantes avec FO). Mais il existe plein de bibliothèques qui produisent du PDF, et qui pourraient être utilisées.

Comme notre RFC impose l'utilisation de profils de PDF comme PDF/A, un outil important est le logiciel de vérification qui s'assure que le résultat est bien conforme aux exigences de ce profil. Pour l'instant, il semble qu'il n'existe pas grand'chose dans ce domaine. Il faudra donc compter sur l'outil de production de PDF pour qu'il fasse un travail correct.


Téléchargez le RFC 7995


L'article seul

RFC 7994: Requirements for Plain-Text RFCs

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : H. Flanagan (RFC Editor)
Pour information
Première rédaction de cet article le 16 décembre 2016


Dans la grande série des nombreux RFC spécifiant le nouveau format de ces documents (avec XML étant désormais la référence), ce court RFC décrit le format de publication « texte brut » des RFC.

En effet, si le format « texte brut » n'est plus la référence des RFC, ce format reste toujours utile. Dans le nouveau mécanisme (RFC 7990), il y a désormais plusieurs formats de publication, obtenus à partir du format canonique (celui qui est en XML). Le texte brut est l'un d'eux. Ce format, historiquement le seul utilisé par les RFC, ne disparait pas, mais perd de son importance. Il n'est plus qu'un des formats de publication parmi d'autres (comme HTML, voir le RFC 7992). Le RFC 6949 expliquait ce choix.

À noter que les RFC produits avant ce changement ne sont pas affectés : leur format de référence reste le texte brut (et en ASCII seul).

Bon, désormais, on aura un format de sortie (parmi d'autres) en « texte seul » ou « texte brut ». Mais c'est quoi, le texte brut ? Notre RFC reprend la définition du consortium Unicode : « du texte encodé pour les ordinateurs composé uniquement de points de code d'une norme donnée, sans instructions de format ou de structure ». Bref, les caractères indiqués ne valent que pour eux-mêmes, ils n'indiquent jamais de formatage ou de style. Selon cette définition, HTML, LaTeX et Markdown (RFC 7763) ne sont donc pas du texte brut. (La définition n'est pas 100 % parfaite. La norme Unicode, par exemple, inclut des caractères qui influencent le format.) Le texte brut est donc ce qui est le plus portable : tous les acteurs qui connaissent la norme de jeu de caractères sous-jacente (aujourd'hui, quasiment toujours Unicode) peuvent lire et écrire du texte brut. C'est d'ailleurs une des raisons pour lesquelles les RFC ont si longtemps gardé ce format comme format canonique.

Mais si le texte brut n'est pas idéal comme format de référence, il reste un format de sortie très utile, notamment pour son interopérabilité, ou en raison de l'existence de nombreux outils qui peuvent le traiter (à commencer par grep...) Désormais, donc, le format canonique est le XML décrit dans le RFC 7991 et le texte brut sera produit automatiquement par les nouveaux outils. Mais ce texte brut a des règles qui sont légèrement différentes du texte brut original (« RFC canal historique ») et notre RFC 7994 les décrit. Il est très court, car le format « texte brut » est un format simple.

D'abord, le jeu de caractères (section 2). Ce sera bien sûr Unicode, mais avec les restrictions indiquées dans le RFC 7997. En pratique, là où les caractères non-ASCII ne sont pas autorisés, il faudra utiliser l'ASCII équivalent, donné dans les attributs XML prévus à cet effet (ascii, RFC 7991 en section 2.23.1, asciiFullname en 2.7.1, etc). L'encodage sera obligatoirement UTF-8 (RFC 3629). Curieusement, il est prévu de mettre une BOM au début du document.

Que faire avec les graphiques, désormais autorisés par le RFC 7990, et écrits en SVG (RFC 7996) ? Ces graphiques sont, dans le source XML, à l'intérieur d'un élément <artwork>. Comment les rendre dans du texte brut (section 3 de notre RFC) ? D'abord, si le graphique n'est pas en SVG mais dans le traditionnel art ASCII (indiqué par type=ascii-art), on utilise cet art ASCII. Autrement, notre RFC ne propose pas de solution générale. Il est recommandé aux auteurs de diagrammes et schémas de prévoir une alternative en art ASCII, même quand ils font du SVG.

Enfin, la section 4 du RFC couvre le problème de la « mise en page ». Un caractère de fin de page (U+000C) sera inclus automatiquement toutes les 58 lignes (les outils auront probablement une option pour ne pas inclure de telles marques). L'outil devra gérer le délicat problème des veuves et des orphelines. Les lignes feront 72 caractères, suivies de deux caractères marquant la fin (U+000D U+000A).

Les textes de début du RFC (RFC 5741) seront automatiquement mis comme avant, mais les en-têtes et pieds de page disparaissent. Autre disparition, il n'y aura plus, dans le format de sortie en texte brut, de numéros de pages dans la table des matières (dommage, je trouve, mais c'est au nom de la cohérence avec les autres formats de sortie).


Téléchargez le RFC 7994


L'article seul

RFC 7993: Cascading Style Sheets (CSS) Requirements for RFCs

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : H. Flanagan (RFC Editor)
Pour information
Première rédaction de cet article le 16 décembre 2016


Le nouveau format des RFC, décrit dans le RFC 7990, prévoit un format canonique, XML, à partir duquel seront automatiquement produits des versions texte brut, PDF, etc. Il y aura évidemment la possibilité de produire une version HTML (RFC 7992) et celle-ci sera bien sûr « stylée » avec CSS. Ce RFC décrit donc le cahier des charges de la feuille de style CSS à développer, avec tous les mots-clés du moment (comme responsive design).

Cette future feuille de style sera le style par défaut (le lecteur pourra toujours la redéfinir). Son but (section 2 du RFC) est de respecter le contenu du RFC (ceux-ci sont parfois des normes : pas question de toucher au texte !) tout en permettant une accessibilité maximale, pour tous les lecteurs, quelle que soit la machine qu'ils utilisent pour accéder au Web.

Plus précisément, la section 3 exige de :

  • Coller aux marquages sémantiques du RFC 7992,
  • Permettre l'accessibilité même aux gens en situation de handicap, comme décrit dans les « Best Practices for Authoring HTML »,
  • Permettre l'utilisation de petits écrans (ce qu'on appelle à tort les mobiles, alors que certains mobiles ne posent aucun problème particulier, car ils ont de grands écrans). Normalement, depuis le tout début du Web, c'est fait automatiquement, car le Web a toujours été prévu pour spécifier un contenu, pas une apparence. Mais certains pratiques ont mené à des pages Web très encombrées, difficiles à réduire automatiquement, ce qui a mené au mouvement du responsive design,
  • Permettre l'utilisation d'écritures diverses, pas juste l'alphabet latin, les RFC permettant désormais des caractères non-ASCII (cf. RFC 7997).

La section 4 donne ensuite les principes de présentation à suivre. Je ne vais pas les reprendre ici dans leur intégralité mais on y trouve :

  • Le code source et les exemples de déroulement d'un protocole réseau seront en chasse fixe, ainsi que l'art ASCII,
  • Le texte devra se réagencer selon la taille de l'écran (ce qui devrait quand même aller de soi quand il s'agit de Web !),
  • Les paragraphes auront un identificateur qui devra être affiché lorsque le pointeur (par exemple la souris) passe au-dessus d'eux,
  • La police par défaut pour l'écran sera sans empattement, inclura Unicode, et sera disponible pour tous les navigateurs importants, avec une licence la rendant disponible.

Il y aura également une feuille de style pour l'impression (comme pour le blog que vous êtes en train de lire, d'ailleurs.) La police par défaut sera cette fois avec empattement.

Enfin, la section 7 et l'annexe A de notre RFC font la liste des classes CSS employées. Par exemple, .pilcrow sera utilisé pour les marques de paragraphe, qui ne seront affichées que lorsque le pointeur passera dessus. .url servira à marquer les URL de manière visuellement distinctive. La classe .cref ne servira que dans les Internet-Drafts, pour afficher les commentaires, mais pas dans les RFC (où les commentaires des auteurs sont supprimés).

La merveilleuse feuille de style qui met en œuvre ces exigences n'est pas encore finie. Un appel d'offres a eu lieu (après relecture). Et on peut voir la feuille temporaire en ligne (pour le développement et les commentaires, c'est sur Github).


Téléchargez le RFC 7993


L'article seul

RFC 7992: HTML Format for RFCs

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : J. Hildebrand (Cisco Systems), P. Hoffman (ICANN)
Pour information
Première rédaction de cet article le 16 décembre 2016


Depuis la sortie du RFC 7990 et ses copains, le format canonique (le format de référence) des RFC n'est plus le texte seul mais un langage XML, normalisé dans le RFC 7991. Les formats « de publication » seront produits automatiquement à partir de ce XML. C'est ainsi que notre RFC 7992 décrit la sortie HTML, qui permettra de publier des beaux RFC sur le Web.

HTML, trop riche et trop mouvant, est en effet mal adapté à l'écriture et à la maintenance de documents. Il n'était donc pas envisageable de le choisir comme format canonique. En revanche, il est incontournable comme format de publication. C'est en effet le langage du Web, et il y a donc logiquement une forte demande pour pouvoir lire les RFC en HTML. Avant, lorsque le format canonique était le texte brut, des versions non officielles étaient publiées en HTML (voir un exemple) mais, le texte brut n'ayant pas de formatage précis, ces versions n'avaient pas vraiment l'air de vraies pages Web...

(Notez que ce blog que vous êtes en train de lire est produit par un mécanisme analogue à celui que les RFC suivront désormais : tapé en XML, avec le HTML produit automatiquement.)

La section 1 de notre RFC résume les principes de l'HTML utilisé. D'abord, ce sera un sous-ensemble de HTML (HTML a bien trop de fonctions). Ensuite, la présentation sera largement délégué à une feuille de style CSS, dont les caractéristiques sont mentionnées dans le RFC 7993.

La section 2, elle, est le « cahier des charges » du HTML des RFC. Elle précise les exigences du RFC 6949. Elle concerne les auteurs du ou des logiciels de production des RFC (pour ces logiciels, voir le RFC 7998). Les auteurs de RFC, eux, n'ont pas à s'en soucier, ils écrivent du XML, et le HTML sera produit par les outils.

Le but principal est que l'HTML produit soit parfaitement lisible sur la grande majorité des navigateurs utilisés. Pas question bien sûr d'ajouter une de des ridicules mentions « optimisé pour Internet Explorer » qui étaient si communes sur les sites Web d'amateurs, dans les années 2000. Notre RFC mentionne explicitement l'exigence que les textes soient lisibles avec au moins un navigateur « texte », comme Lynx, certaines personnes accédant au Web ainsi (par obligation ou par goût). C'est l'une des raisons de la décision de ne pas accepter la totalité de HTML.

Le fichier HTML devra être autonome (ne pas dépendre de fichiers extérieurs), de manière à pouvoir être transmis facilement par des mécanismes tels que rsync ou le courrier électronique.

Le JavaScript est accepté mais à condition qu'il ne modifie en aucun cas le texte du RFC. (Il peut, par exemple, ajouter des éléments de navigation, ou afficher des métadonnées.)

On l'a dit, CSS sera utilisé pour la présentation, mais le cahier des charges exige qu'on puisse facilement remplacer la feuille de style par une de son choix, pour s'adapter aux goûts locaux.

Le Web étant fondé sur la notion de lien hypertexte, il y aura évidemment des liens, aussi bien ceux mis explicitement par l'auteur (« ce point est développé en section N »), que ceux ajoutés automatiquement (de la table des matières vers les différentes sections, par exemple).

Un point crucial est évidemment l'accessibilité. Comme le savent tous ceux et toutes celles qui vont régulièrement à Paris Web, c'est un point essentiel mais souvent oublié. Notre RFC note donc que les publications en HTML des futurs RFC devront être accessibles aux malvoyants, aux daltoniens, et aux utilisateurs de petits écrans, par exemple les smartphones. (Note personnelle : ce dernier point ne devrait pas être dans une section sur l'accessibilité. Le Web est prévu - contrairement aux formats du monde du papier, comme PDF - pour être visible sur tous les périphériques.)

Au fait, quelle version de HTML sera utilisée (section 3 de notre RFC) ? Ce sera HTML5 (et pas, et je le déplore, XHTML ; l'inconvénient, souvent cité contre XHTML, de la difficulté à l'écrire n'a pas de sens ici, puisque le HTML sera produit automatiquement).

La section 4 précise la syntaxe utilisée (rappelez-vous qu'on n'accepte pas la totalité de HTML5) : encodage en UTF-8, sauts de ligne en style Unix (un U+000A et rien d'autre), pas de caractères de contrôle comme la tabulation (U+0009). Les éventuels commentaires du source XML ne seront pas mis dans le HTML (l'idée est qu'ils sont pour les auteurs, pas pour les lecteurs).

Il y a des objets divers qu'on retrouve souvent dans le source XML. Ils sont rassemblés dans la section 5. Par exemple, on trouve les identificateurs qui seront mis comme valeur des attributs id dans le HTML produit. Ce sont parfois des identificateurs mis explicitement par l'auteur, et parfois des identificateurs produits par le logiciel, par exemple pour que les entrées de la table des matières pointent vers la section correspondante.

Autre objet récurrent, la marque de paragraphe (pilcrow pied-de-mouche, caractère Unicode U+00B6, celui-ci : ¶), qui sera mise automatiquement derrière chaque paragraphe, mais pas affiché par défaut (il faudra promener le pointeur dessus pour le voir).

Maintenant, attaquons les différentes parties du RFC rendu en HTML. D'abord (section 6), les premiers objets HTML qu'on rencontrera, notamment les métadonnées du RFC. Il y aura évidemment un DOCTYPE identifiant le document comme du HTML5. L'élément racine sera <html>, avec une étiquette de langue qui sera bien sûr en, l'anglais. L'élément <head> qui suivra contiendra une déclaration de jeu de caractère, un titre, et diverses métadonnées :

    

   <meta charset="utf-8">
   <title>The Mother of all RFCs</title>
   <meta name="author" content="Joe Hildebrand">
   <meta name="author" content="Heather Flanagan">
   <meta name="description" content="This document defines...">
   <meta name="generator" content="xmljade v0.2.4">
   <meta name="keywords" content="html,css,rfc">

(Rappelez-vous que le HTML produit n'est hélas pas du XHTML donc il est normal que les <meta> ne soient pas explicitement fermés.) Il y aura aussi un lien vers la licence des RFC, en utilisant le cadre général des liens (RFC 8288) :


   <link rel="license" href="https://www.rfc-editor.org/copyright/">

   

Cette première partie du RFC produit contiendra aussi une feuille de style, ainsi qu'un lien vers une éventuelle feuille locale, au cas où un lecteur souhaiterait lire le RFC selon un style différent :


   <style>
     body {}
     ...
   </style>
   <link rel="stylesheet" type="text/css" href="rfc-local.css">

    

Le début de la partie visible du RFC sera composée d'une <dl> pour les métadonnées affichées, et d'une table des matières. Les métadonnées seront donc du genre :


   <dl id="identifiers">
     <dt>Workgroup:</dt>
       <dd class="workgroup">rfc-interest</dd>
     <dt>Series:</dt>
       <dd class="series">Internet-Draft</dd>
     <dt>Status:</dt>
       <dd class="status">Informational</dd>
     <dt>Published:</dt>
       <dd><time datetime="2014-10-25"
                 class="published">2014-10-25</time></dd>
     ...

    

La partie principale du RFC sera, elle, rendue selon les principes décrits en section 9 pour chacun des éléments XML qui composent le source.

La dernière partie du RFC incluera un index (si le source XML avait un attribut indexInclude dans l'élément <rfc>), les adresses des auteurs (formatées en hCard), et les métadonnées considérées comme les moins importantes (les autres ayant été mises au début).

La section 9 de notre RFC est particulièrement longue car elle décrit le rendu en HTML de tous les éléments du vocabulaire XML du RFC 7991. Je ne vais pas tout décrire ici, juste donner quelques exemples. Ainsi, <artwork> sera rendu dans un élément HTML <pre>, si le schéma était en art ASCII, sera inclus tel quel dans le HTML si le schéma était en SVG (RFC 7996), et sera mis sous forme d'un <img> (avec contenu de plan data:) dans les autres cas. <sourcecode>, lui, est toujours restitué sous forme d'un <pre> HTML.

La traduction de certains éléments en HTML est plus directe. Par exemple, <em> est simplement rendu par le même élément HTML.

Et, pour finir, un petit mot sur la sécurité (section 11) : comme les RFC en HTML ne sont pas forcément téléchargés depuis le Web mais peuvent être lus depuis un fichier local (après, par exemple, synchronisation via rsync), on ne bénéficie pas forcément des protections du navigateur. Donc, prudence.


Téléchargez le RFC 7992


L'article seul

RFC 7991: The "xml2rfc" Version 3 Vocabulary

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : P. Hoffman (ICANN)
Pour information
Première rédaction de cet article le 16 décembre 2016


Contrairement à beaucoup de SDO, l'IETF n'avait pas de format standard pour l'écriture de ses documents. Désormais, avec le nouveau cadre décrit dans le RFC 7990, c'est fait. XML, avec le vocabulaire décrit dans ce nouveau RFC, est le format canonique des RFC.

Vous voulez écrire un RFC ? Il est fortement recommandé d'utiliser dès le début le format standard XML, fondé sur un vocabulaire spécifique aux RFC, et mis en œuvre dans la future version de l'outil xml2rfc. Voici donc le vocabulaire « XML2RFC version 3 », succédant à deux versions qui n'étaient pas officiellement standard (les changements depuis la v2, spécifiée dans le RFC 7749, ne sont pas énormes). Notez que le vocabulaire XML et les outils continuent à évoluer, donc ce RFC n'est pas éternel. Et que la version 2 restera sans doute en service pendant encore des années : cela prend du temps de changer les habitudes !

Voici le squelette d'un Internet-Draft écrit avec ce XML :

      
    
<?xml version="1.0" encoding="utf-8"?>
<rfc docName="draft-ietf-dnsop-qname-minimisation-09" submissionType="IETF"
     ipr="trust200902">
<front>
<title abbrev="Qname minimisation">DNS query name minimisation to improve privacy</title>
...
<middle>
<section anchor="intro" title="Introduction and background">
<t>The problem statement is described in <xref
target="RFC7626"/>. [...]
...
</back>
</rfc>

    

Sur ce squelette simple, on voit l'élément racine (<rfc>), l'utilisation des attributs (comme submissionType qui indique la voie prise par le document, ici, l'IETF, cf. RFC 7841), la séparation en trois parties, <front>, qui regroupe les métadonnées, <middle>, qui est le texte principal, et <back>, où se trouvent la bibliographie, les annexes, etc.

Parmi les attributs de cet élément racine <rfc>, notez ipr, qui indique les conditions légales d'utilisation de ce RFC. Dans cet example, la valeur est la plus couramment utilisée : trust200902 (cf. l'annexe A.1) indique les règles de l'IETF Trust datant de 2009 (qui disent en gros que le texte du RFC peut être librement copié, reproduit, distribué et mis en œuvre dans des programmes). L'annexe A de notre RFC détaille ce qu'on appelle le boilerplate, ces textes juridiques obligatoires qui sont ajoutés automatiquement par le logiciel xml2rfc. Ainsi, si on met ipr="trust200902" dans l'élément <rfc>, xml2rfc va automatiquement ajouter « Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved. \ This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents [...] »...

Le gros morceau du RFC est la section 2, qui donne la liste des éléments XML acceptés. Je ne vais pas reproduire ici cette liste, juste parler de quelques éléments qui me semblent rigolos.

<section> contient une partie du RFC. Cet élément est hiérarchique : on crée des sous-sections en les mettant sous les sections existantes, et ainsi de suite, récursivement. (Contrairement à ce qui se passe avec HTML, où on indique explicitement le niveau de la section, <h1>, <h2>, etc.) On a aussi <abstract>, qui indique le résumé au début du RFC.

<t> contient un paragraphe et est donc l'équivalent du <p> de HTML.

<artwork> permet de spécifier du texte qui sera représenté comme tel, sans aucune justification, mise à la ligne, etc. (Les tabulations sont interdites, ce qui règle le vieux débat « tabs vs. spaces ».) <artwork> permet de mettre de l'art ASCII dans un RFC, mais la méthode préférée pour les images est désormais SVG, voir le RFC 7996. Le SVG peut être mis directement dans le source XML ou bien inclus par différentes méthodes, dont l'attribut src. Cet attribut src permet de spécifier un fichier externe, l'art ASCII ne servant alors que de solution de secours, pour le format en texte seul. Un attribut type permet d'indiquer le type du dessin (par exemple svg pour les images en SVG). La liste des types possibles sera en ligne. Voici un exemple d'art ASCII :


<artwork type="ascii-art">
 +--------------+				     +----------------+
 |  Alice       |------------------------------------|      Bob	      |
 | 2001:db8::1  |                                    |   2001:db8::2  |
 +--------------+				     +----------------+
</artwork>

    

Le code source, lui, se fait avec l'élément <sourcecode>, un attribut type permettant d'indiquer le langage utilisé (une liste des valeurs possibles sera en ligne). Voici un exemple :

      
<sourcecode type="python">
	  print("Hello, world")
</sourcecode>
      
    

Comme le langage utilisé peut utiliser des caractères qui sont spéciaux pour XML (comme < ou &), il est souvent préférable de mettre le code source dans une section CDATA.

<eref> permet de faire un lien hypertexte vers l'extérieur :


      <t>More text and a <eref
      target="http://www.rfc-editor.org/">lien vers le site du RFC Editor</eref>.</t>
    
    

<ul> permet de représenter les traditionnelles listes à puces :


<t>There are three sorts of DNS requests being issued:</t>
<ul>
<li>Primary request: [...]</li>
<li>Secondary requests: [...]</li>
<li>Tertiary requests: [...]</li>
</ul>
    
    

<references> permet d'indiquer une bibliographie. Il y en a typiquement deux dans un RFC (cf. la section 4.8.6 du RFC 7322), la bibliographie normative (ce qu'il faut absolument avoir lu et compris car le RFC en dépend) et l'informative (ce qu'on peut sauter si on est pressé). Pour aider, le RFC Editor distribue des fichiers XML contenant les références aux RFC publiés, comme http://www.rfc-editor.org/refs/bibxml/reference.RFC.7626.xml.

Le nom d'un auteur de RFC se met avec l'attribut <author>. Comme il peut être en caractères non-ASCII, des attributs permettent d'indiquer une variante en ASCII seul. Par exemple :

      
<author fullname="Patrik Fältström" asciiFullname="Patrik Faltstrom">
	 <organization>Netnod</organization>
</author>

    

Ce format de RFC s'appuie sur XML et il faut donc suivre les règles de XML, notamment sur les caractères spéciaux. Ainsi, le chevron ouvrant doit être remplacé par une séquence d'échappement (&lt; au lieu de <). Si cette contrainte est trop forte, on peut aussi enclore les parties à « échapper » dans une section CDATA.

Le format des RFC permet d'autres caractères que ceux du jeu ASCII, mais avec certaines restrictions (voir RFC 7997).

Le format actuel permet l'inclusion d'autres documents, via des attributs comme l'attribut src pour le code source :

      
<sourcecode type="python" src="hello.py"/>

    

On peut aussi utiliser les mécanismes génériques d'inclusion de XML, comme XInclude (cf. annexe B.1) ou les entités, et c'est souvent utilisé pour la bibliographie :


   <!DOCTYPE rfc [
     <!ENTITY rfc7830 PUBLIC
     "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7830.xml">
   ]>

[...]
     <references>
       &rfc7830;
     </references>
	     
    

À noter qu'il existe un type MIME pour les sources XML de RFC, application/rfc+xml (section 8 de notre RFC).

Si vous voulez voir le schéma XML complet, il est en annexe C (j'en ai exporté une version utilisable telle quelle, sans les sauts de page des RFC, en rfc-v3.rnc). Comme il est écrit en Relax NG, il permet l'utilisation de tous les outils Relax NG, comme le mode emacs nxml-mode et comme rnv. Ainsi, une fois le fichier rfc-v3.rnc chargé dans emacs (menus XML puis Set schema puis File), on dispose de fonctions d'édition bien pratiques (par exemple, on tape un < puis une tabulation et emacs propose de compléter uniquement avec les éléments autorisés à cet endroit). Cela évite bien des erreurs.

À noter que ce RFC ne décrit que les éléments et attributs XML, pas de processing instructions (PI), qui ne sont plus acceptées.

Avec un logiciel comme rnv, on peut tester la syntaxe (uniquement la syntaxe : certaines contraintes dans le RFC ne sont pas exprimables dans le schéma, il a fallu les formuler en langue naturelle dans le texte du RFC) :

% rnv rfc-v3.rnc rfc-v3-sample.xml 
rfc-v3-sample.xml
    

Parfait, ici, tout est bon. S'il y avait eu une erreur :

% rnv rfc-v3.rnc rfc-v3-sample-wrong.xml      
rfc-v3-sample-wrong.xml
rfc-v3-sample-wrong.xml:9:6: error: element ^t not allowed
required:
	element ^section
rfc-v3-sample-wrong.xml:11:2: error: unfinished content of element ^middle
required:
	element ^section
error: some documents are invalid
    

Si le RFC contient des références externes (que rnv ne sait pas traiter), on peut utiliser xmllint pour les remplacer :

%  xmllint --dropdtd --noent draft-dupont-my-protocol.xml | rnv rfc-v3.rnc 
    

On peut aussi utiliser Jing (annexe C.1). Mode d'emploi très court, on télécharge :

% wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jing-trang/jing-20091111.zip
% unzip jing-20091111.zip
% java -jar ./jing-20091111/bin/jing.jar  -c rfc-v3.rnc draft-dupont-my-protocol.xml
%
     

Les changements depuis le texte précédent, le RFC 7749, qui décrivait la version 2 (notre RFC est la version 3), sont décrits dans l'annexe D et résumés en section 1.3. L'idée était notamment d'avoir un vocabulaire plus facile à utiliser, sans pour autant trop changer par rapport au format v2, qui était bien connu des auteurs.

Le changement le plus spectaculaire concerne les listes, qui sont désormais faites, comme en HTML, avec des <dl>, <ul> et <ol>. Dans une liste, le contenu est marqué par <li> et plus <t>. Autre inspiration HTML, l'apparition des tables, avec <table> (et éléments associés comme <tr> et <td>). D'autre part, de nouveaux éléments apparaissent pour marquer du texte, par exemple s'il est important (<em>, qui n'avait pas d'équivalent en v2, dont le seul format de sortie était le texte brut). Il y a aussi un <blockquote> pour les citations. Bien que l'IETF se vante souvent de pratiquer le culte du « running code », il n'y avait pas d'élément XML particulier pour indiquer du code source dans un RFC (on se contentait d'<artwork>). C'est désormais fait avec <sourcecode>. Quelques autres éléments XML nouveaux (je ne les cite pas tous, le RFC fait 159 pages !) : <displayreference> pour associer un chouette texte aux références, <link> pour les liens externes (contrairement à <eref>, qui existait déjà, <link> est spécifique à certains types de documents, par exemple les Internet-Drafts) ou encore <br> pour forcer des sauts de ligne (mauvaise idée que de mettre des éléments de présentation, si vous voulez mon avis).

Il y a aussi de nouveaux attributs XML aux éléments existants. Pour remplacer les PI (processing instructions comme <?rfc toc="yes"?>), on a tocInclude et tocDepth dans l'élément <rfc>, afin de contrôler la table des matières. De même, pour gérer l'internationalisation, il y a désormais un attribut ascii pour les éléments qui acceptent du contenu non-ASCII, afin de fournir une alternative pour les anglophones. Il y a aussi des attributs plus orientés présentation comme keepWithNext ou keepWithPrevious, attributs de <t>, qui expriment un souhait de garder ce paragraphe avec le suivant ou le précédent, pour mieux contrôler la pagination.

En revanche, certains éléments et attributs sont retirés de la circulation. Ils seront encore acceptés par les outils, mais temporairement. <list> subit ce trist sort (remplacé par les éléments HTMLisant comme <ul> et <ol>). <facsimile> disparait également, victime des évolutions technologiques. Parmi les attributs, title disparait (il était utilisé dans des éléments comme <section>) au profit de name (changement assez gratuit, je trouve).

Les autres changements sont bien sûr l'acceptation de caractères non-ASCII, et plein de modifications de détail.

Question mise en œuvre, il faudra patienter. S'il y a déjà eu des mises en œuvre expérimentales et partielles, les vrais logiciels officiels ne sont pas encore, en octobre 2016, développés.


Téléchargez le RFC 7991


L'article seul

RFC 7990: RFC Format Framework

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : H. Flanagan (RFC Editor)
Pour information
Première rédaction de cet article le 16 décembre 2016


Voici enfin la série de RFC décrivant le nouveau format des RFC. Ce projet a commencé il y a plusieurs années, mais les discussions ont été longues. Ce nouveau RFC et les huit autres qui l'accompagnent, marquent un changement important dans ces « textes sacrés » de l'Internet : l'ancien format « texte brut » n'est plus le format de référence. Désormais, tout RFC sera fait en XML, format d'où seront produits automatiquement des versions texte brut, HTML, PDF, etc.

Les RFC sont des documents cruciaux pour l'Internet. C'est sous forme de RFC que sont publiées les normes techniques de la famille de protocoles TCP/IP. Et il y a bien d'autres RFC qui ne sont pas forcément des normes (cf. RFC 1796). Librement disponibles en ligne (contrairement aux normes techniques des organisations traditionnelles du mésozoïque), dans un format ouvert, la disponibilité des RFC est l'une des raisons du succès de l'Internet.

Parlons de format, justement. Les RFC, jusqu'à maintenant, étaient sous forme de texte brut, et en ASCII seul. (Certes, des versions PDF et HTML non-officielles étaient diffusées mais on voyait bien qu'elles avaient été produites à partir du texte brut... Certes, il était possible depuis dix ans d'écrire les RFC en XML, cf. RFC 2629, mais ce n'était pas le format de référence.) Pourquoi donc se limiter à ce format ? Il y avait plusieurs bonnes (et d'autres moins bonnes) raisons mais il ne faut pas de cacher qu'une des raisons les plus importantes était qu'il est difficile de faire changer un processus de production bien établi, même s'il comprend des archaïsmes, comme l'utilisation de troff pour traiter des documents. L'actuelle éditrice des RFC, Heather Flanagan, a donc eu bien du mérite à faire aboutir ce projet de changement. Il a fallu beaucoup de discussions, dans une communauté souvent divisée. (Que les informaticiens pensent aux grands débats du genre « vi ou emacs ? »)

Le projet de réforme des RFC avait sérieusement commencé en 2013 avec le RFC 6949, le véritable cahier des charges du nouveau format. La décision formelle de migrer vers le nouveau format, et donc de décider que le format de référence serait désormais le XML et non plus le texte brut a été prise en mai 2013. Avant et pendant cette décision, d'innombrables messages ont été échangés sur la liste de diffusion rfc-interest.

Il est important de noter que cette discussion portait sur le processus de publication des RFC terminés. L'élaboration des Internet-Drafts, la décision de les publier ou pas (qui dépend de chaque voie, cf. RFC 8729) ne sont pas concernées.

La section 2 de notre RFC résume le problème que veut résoudre le nouveau format. Le monde a bien changé depuis que seuls une poignée de Californiens anglophones venait aux réunions IETF. Les participants viennent aujourd'hui de 45 pays, situés dans le monde entier, les lecteurs des RFC sont plus divers que jamais, utilisent des engins très variés, et il est toujours aussi crucial que les RFC soient largement disponibles et accessibles, et sur une très longue période (mon favori est le RFC 768, publié en 1980 et toujours d'actualité). Le format de référence en texte ASCII brut ne permettait clairement pas cela.

Mais choisir un successeur n'était pas facile : notre RFC insiste sur le fait qu'il y a aujourd'hui plusieurs groupes qui utilisent les RFC (pas seulement des techniciens, juristes et chefs accèdent aujourd'hui à des RFC), et sur le fait qu'il fallait un compromis entre les besoins actuels et l'importance d'une disponibilité à long terme (par exemple, adopter le format à la mode du moment pourrait se payer cher plus tard lorsque ce format n'intéressera plus personne).

Un peu de terminologie (section 3) est nécessaire pour bien comprendre le choix effectué :

  • Format canonique : le format de référence, archivé, utilisé en cas de conflit (XML, donc). Il est important d'en avoir un, au cas où une bogue dans les logiciels change une partie d'un RFC.
  • Formats de publication : les divers formats sous lesquels est publié le RFC (détaillés en section 7). Peu de gens liront le RFC en XML (quoique cela soit possible, une propriété qui est importante pour la conservation à long terme). Ils liront de l'HTML, du PDF, voire du texte seul pour les traditionnalistes. Tous ces formats seront produits (de préférence automatiquement) à partir du format canonique. Chacun a ses avantages et inconvénients (section 5). Par exemple, HTML avec JavaScript fournit des capacités de navigation bien meilleures que le texte brut.
  • Format révisable : le format que le RFC Editor utilisera pour son travail interne. Ce sera XML.
  • Format de soumission : le format sous lequel le texte sera transmis initialement par les auteurs au RFC Editor. Aujourd'hui, le texte brut est obligatoire, le XML autorisé en prime. Demain, ce sera du XML, mais avec des exigences moins strictes que pour le format canonique.

Et aussi un terme important : texte réagencable (ou réajustable, reflowable text). C'est du texte qui s'ajuste automatiquement à la largeur du dispositif de lecture. C'est banal dans le monde HTML, où c'est fait automatiquement depuis toujours. Mais c'était un des principaux inconvénients de l'ancien format des RFC : le texte avait une largeur fixe.

Quel sera donc exactement le format canonique ? La section 6 répond à cette question :

  • Le langage sera du XML avec le vocabulaire spécifié dans le RFC 7991 (nommé « v3 »). Il est normalement meilleur que les précédents vocabulaires utilisés depuis le RFC 2629.
  • Les auteurs pourront envoyer leur draft en suivant le format dit « v2 » (celui du RFC 7749), voire en texte brut, mais il sera ensuite converti dans le format v3 ci-dessus.
  • Le SVG sera autorisé dans le source XML.
  • Comme en v2, DTD est abandonné, la description officielle du schéma XML est en Relax NG.
  • Les textes obligatoires (RFC 5741) seront automatiquement insérés.
  • Le source XML du format canonique sera autonome. Cela veut dire qu'il n'aura pas de références à des sources extérieures. Ainsi, si un auteur référence un code source externe avec <sourcecode src="[un URI externe]"... (RFC 7991, section 2.48), le code en question sera inclus dans la version canonique. Idem si l'auteur a utilisé XInclude.
  • Il n'y aura pas de commentaires ou de processing instructions dans le source XML. Si l'auteur en a mis, ils seront retirés.

Notez donc que les images (en SVG) seront désormais possibles (voir le RFC 7996).

Le guide du style des RFC (RFC 7322) avait été révisé pour tenir compte de ce nouveau format. Notamment, il se concentre désormais sur le contenu du texte, ne demandant plus aux auteurs des efforts de présentation. (La section 5 résume les changements importants pour les auteurs.)

Enfin, la section 7 décrit les formats de publication. À partir du source XML, seront automatiquement produits HTML, PDF, texte brut et peut-être plus tard d'autres. Le HTML est évidemment la cible évidente. Son utilisation pour les RFC est décrite dans le RFC 7992. Le résultat sera certainement bien meilleur que les versions HTML non-officielles actuelles, qui sont produites à partir du texte brut, qui ne contient pas assez de structure pour faire du bon HTML. La mise en page sera évidemment assurée par CSS (RFC 7993), il y aura une feuille de style standard, que chacun sera bien sûr libre de remplacer. Le SVG sera inclus dans l'HTML (il faudra donc un navigateur qui gère bien SVG). Il y aura même du JavaScript mais avec de sévères restrictions. Notamment, le code JavaScript ne devra pas changer le texte, ou supprimer du texte.

PDF, quant à lui, est spécifié dans le RFC 7995. Il devra suivre le profil PDF/A-3, spécialement prévu pour de l'archivage à long terme, et pour pouvoir être relu par des logiciels PDF n'ayant pas tous les derniers gadgets.

Naturellement, le texte brut n'est pas abandonné. Comme indiqué dans le RFC 7994, il y aura une version en texte brut produite automatiquement à partir du XML, même si elle ne sera plus la version canonique. Parmi les nouveautés par rapport à l'ancien format, UTF-8 sera désormais autorisé, même si c'est de façon limitée (voir les limitations dans le RFC 7997). Il pourra y avoir une variante non découpée en pages.

Dans le futur, il est possible que le format EPUB soit ajouté à cette liste.

Au passage, comment a été décidé cet important changement dans le format des RFC ? La section 4 résume cette histoire. Comme indiqué plus haut, cela a pris très longtemps et nécessité beaucoup de discussions, qui ont notamment eu lieu sur la liste de diffusion rfc-interest, et au cours des réunions physiques de l'IETF. Le cahier des charges a été formalisé en 2013 dans le RFC 6949. Une fois le cahier des charges décidé, une équipe spécialisée a été désignée par le RFC Editor pour mettre au point les détails, notamment en adaptant le langage XML utilisé, partant de la dernière version (RFC 7749), pour arriver au futur langage, RFC 7991. Des éditeurs professionnels ont également été consultés, ainsi d'autres SDO et même des juristes (oui, car aux États-Unis, rien n'est désormais à l'abri d'actions en justice, même pas les RFC, le choix du format de sortie PDF/A-3 venait en partie de la nécessité de répondre aux subpoenas). Le tout était bien sûr fait sous la supervision du RFC Series Oversight Committee. Certaines décisions furent consensuelles, les autres tranchées par le RFC Editor (cf. RFC 8728). Le tout a été approuvé par l'IAB en août 2016.

Après ce tour du passé, le futur. Comment se fera la transition vers le nouveau système (section 10) ? C'est qu'il va falloir créer de nouveaux outils (cf. RFC 7998). L'appel d'offres pour leur développement a été fait en septembre 2016. La description des outils est une très intéressante lecture (l'appel d'offres formel est sur la page des Request For Proposal). L'appel d'offres a été gagné par les sociétés SeanTek et Elf Tools.

Pendant une période intermédiaire, le texte seul sera toujours utilisé comme format canonique, mais les nouveaux RFC passeront également par le nouveau workflow, pour vérifier que tout se passe bien et que le résultat est correct. Double travail, donc, mais nécessaire pour s'assurer que tout est en place.

Notez que, même une fois la transition finie, les auteurs ne seront pas forcés de soumettre leur document sous forme d'un fichier XML (ils seront simplement très fortement encouragés à le faire). S'ils envoient le texte seul comme avant, le RFC Editor devra produire le XML lui-même, et c'est ce XML qui sera la version canonique. Rappelez-vous que beaucoup de RFC sont des documents normatifs et que chaque mot, voire chaque virgule peut compter ! Voici pourquoi il faudra s'assurer que tout est parfait, même si, au début, cela entrainera certainement des retards dans la publication.

Dans le cas où l'auteur envoie du XML suivant le RFC 7991, il y aura moins de travail pour le RFC Editor, juste convertir ce XML au XML canonique (résoudre les références extérieures, par exemple) et passer ce XML canonique dans les nouveaux outils.

Notez que le RFC Editor maintient une FAQ très utile sur toutes les questions que pose le nouveau format. Et la RFC Editor avait fait un très drôle Pecha Kucha à Séoul en novembre 2016, sur le cahier des charges du nouveau format.

Le premier RFC au nouveau format a été le RFC 8651, sorti en octobre 2019.


Téléchargez le RFC 7990


L'article seul

RFC 7979: Response to the IANA Stewardship Transition Coordination Group (ICG) Request for Proposals on the IANA Protocol Parameters Registries

Date de publication du RFC : Août 2016
Auteur(s) du RFC : E. Lear, R. Housley
Pour information
Réalisé dans le cadre du groupe de travail IETF ianaplan
Première rédaction de cet article le 30 août 2016


Un certain nombre de fonctions administrativo-politico-techniques dans l'Internet sont assurées par un service nommé l'IANA (Internet Assigned Numbers Authority). Cela va du spectaculaire (l'instruction des demandes d'ajout ou de suppression des TLD) jusqu'au routinier (la gestion des innombrables registres techniques que l'IANA maintient pour le compte de l'IETF). L'IANA est un service de l'ICANN et l'ICANN est sous tutelle du gouvernement états-unien pour effectuer ce travail, dit « fonction IANA ». Le gouvernement états-unien a annoncé en 2014 qu'il envisageait peut-être dans le futur de diminuer la dépendance de l'ICANN et a demandé, en attendant, aux parties intéressées, de soumettre des propositions. L'ICANN, toujours ravie qu'on propose des discussions et des réunions, a créé le ICG (IANA stewardship transition Coordination Group) qui a à son tour sollicité des commentaires. Ce nouveau RFC est la réponse de l'IETF à cet appel, ne concernant que la gestion des registres techniques. La gestion des noms de domaine et des adresses IP, bien plus politicienne et bien plus brûlante (surtout pour les noms de domaine) n'y figure pas. Voici donc « la position de l'IETF concernant l'avenir de la gestion des registres IANA, dans l'hypothèse où le gouvernement états-unien relâcherait son emprise ». Pour résumer cette position : la gestion des registres des paramètres des protocoles fonctionne actuellement bien et, quelles que soient les manœuvres autour de l'évolution du rôle du gouvernement US, il ne faut pas la changer. Ce RFC a été terminé en janvier 2015 mais n'est publié que maintenant, après l'approbation du plan de transition par l'ICANN en mars 2016 à sa réunion de Marrakech, et après l'accord du gouvernement états-unien en août.

L'agence du gouvernement états-unien chargée de superviser l'ICANN se nomme NTIA, dépendant du ministère du commerce (notez la vision de l'Internet que cela implique). Notez que cette supervision n'est pas le seul levier direct de ce gouvernement sur la gestion de ressources critiques de l'Internet. Il y a aussi la gestion de la racine du DNS, effectuée via Verisign. En mars 2014, génée par les révélations de Snowden, la NTIA a annoncé un projet d'évolution du statut de l'ICANN, passant du gouvernement états-unien à quelque chose de nouveau, encore à discuter. La NTIA a posé ses conditions (par exemple que le quelque chose de nouveau ne devait pas être multi-gouvernemental), et annoncé que, s'il n'y avait pas de plan satisfaisant (satisfaisant pour la NTIA) proposé, le projet serait abandonné ou redéfini.

C'est là qu'a été créé l'ICG (IANA Stewardship Coordination Group) dont la charte figure en annexe B de ce RFC. C'est cet ICG qui a émis l'appel aux commentaires (qui figure en annexe C du RFC). Cet appel demande entre autre de préciser si les réponses concernent la partie « noms de domaine », la partie « adresses IP » ou bien la partie « paramètres des protocoles » du travail de l'IANA (ce RFC concerne la troisième partie). Les réponses sont disponibles en ligne.

La section 2 de ce RFC est la réponse formelle de l'IETF, suivant le plan de l'appel à commentaires de l'ICG. D'abord, l'IETF répond à la question « l'IANA sert à quoi, pour vous ? » Bien des protocoles conçus ou gérés par l'IETF ont besoin de registres pour des paramètres du protocole. Par exemple, le protocole HTTP (RFC 7231) a des codes de retour des opérations (comme le célèbre 404) qui sont stockés à l'IANA. Ajouter un tel code (par exemple 451 pour « contenu censuré ») ne nécessite donc pas de modifier la norme HTTP. Ou bien, pour prendre un exemple nettement moins connu, le protocole PCP (RFC 6887) dispose d'un certain nombre d'options, qui ne sont pas fixées une fois pour toutes dans la norme mais sont notées dans un registre IANA, ce qui permet d'en ajouter facilement de nouvelles.

Pour que l'Internet fonctionne, il faut que ces paramètres des protocoles soient utilisés de la même manière par tous. Par exemple, cela signifie que les développeurs de logiciels Internet doivent utiliser les mêmes registres, en l'occurrence, ceux de l'IANA. Ainsi, un serveur HTTP peut renvoyer le code 403 en sachant bien que cela sera interprété par tous les clients comme signifiant « Accès interdit », car le code 403 figure dans le registre IANA avec cette définition. Ce rôle de l'IANA pour l'IETF est documenté dans le RFC 5226.

L'IANA gère également le TLD .arpa, qui est considéré comme un des registres de paramètres (RFC 3172).

Ce travail de l'IANA pour le compte de l'IETF est effectué en application du RFC 2860 (voir aussi ses déclinaisons concrètes), qui est le « contrat » entre les deux activités.

La question suivante est « qui êtes-vous ? » L'IETF se présente donc, SDO internationale, ouverte et dont la mission est décrite dans le RFC 3935. L'IETF fait les normes techniques de l'Internet « de la couche 3 jusqu'au bas de la couche 7 ». C'est elle qui est responsable d'IP de BGP, du DNS, de HTTP, etc. (Oui, tous les lecteurs de ce blog savent cela mais la réponse de l'IETF est conçue pour être lue par un public plus large.) Le côté ouvert de l'IETF est précisé dans le RFC 6852, le processus de création des normes dans le RFC 2026.

Une question difficile dans l'appel à commentaires était « quels recouvrements y a-t-il entre votre activité et celles d'autres organisations ou groupes ? » D'abord, la réponse met en avant le fait que les participants à l'IETF sont souvent membres d'autres organisations. (On parle de « participants » car l'IETF n'a pas de mécanisme d'adhésion formel.)

Ensuite, l'IETF a évidemment des activités qui s'approchent de très près de celles d'autres groupes, avec parfois des discussions sur la frontière. Ainsi, le RFC 6761, qui fait l'objet de beaucoup de débats en ce moment, prévoit un mécanisme d'enregistrement de noms de domaine par l'IETF, alors que certains voudraient que cela soit un monopole de l'ICANN. C'est aussi le cas des adresses IP (mais cela suscite bien moins d'intérêt car c'est plus important mais moins spectaculaire). Ainsi, si l'IANA gère l'espace d'adressage IP, l'IETF alloue également des portions de cet espace (RFC 7020, RFC 7249, et un exemple concret, les ULA du RFC 4193). Il y a aussi bien sûr des recouvrements envers ce que fait l'IETF, et le travail des opérationnels qui décident (ou pas) de déployer les protocoles normalisés. Par exemple, la gestion des serveurs racine du DNS est à la fois un secteur de l'IETF (RFC 7720) et des opérateurs de ces serveurs.

Les activités de l'IETF concernant IP et le routage l'amènent par contre du côté des RIR (par exemple lorsque l'IETF a ses propres allocations d'adresse, comme dans le RFC 6890). Un changement de norme technique peut impacter les opérationnels (nouvelles choses à gérer) et les RIR. Ainsi, l'extension de la taille des numéros d'AS de deux à quatre octets (RFC 6793) imposait évidemment aux RIR de changer leur logiciel et leur politique, pour allouer ces nouveaux numéros.

Pour tous ces points, le RFC insiste sur l'importance de la coordination entre ces acteurs, et sur les nombreux contacts que l'IETF maintient avec toutes ces communautés.

L'appel à commentaires de l'ICG demande ensuite comment les politiques sont décidées et comment les conflits sont gérés. Pour l'IETF, les principes figurent dans les RFC 6220 et RFC 5226. En gros, quelqu'un qui veut changer la politique de l'IETF, par exemple modifier le RFC 5226 (c'est justement en cours de discussion) va écrire un premier document, un Internet Draft, essayer de susciter de l'intérêt, en général le faire adopter par un des groupes de travail (à moins qu'un groupe soit créé spécialement), la proposition doit réunir un consensus (RFC 7282) et c'est souvent l'IESG qui prend la décision finale. Le tout est scandé par des last calls où les organisateurs demandent aux participants un dernier avis avant que le document n'avance. (Pour le fonctionnement des groupes de travail, on peut lire le RFC 2418, mais il n'est plus complètement à jour.)

Et les conflits ? Ils sont normalement réglés dans les groupes de travail mais, si c'est grave, la section 6.5 du RFC 2026 décrit un mécanisme d'appels successifs.

Un concept souvent cité en ce moment dans les discussions autour de l'ICANN et celui de redevabilité (accountability). L'organisation est-elle redevable à quelqu'un, ou bien est-ce un clan mafieux fermé qui décide de tout en interne et ne rend de comptes à personne (comme le CIO ou la FIFA) ? L'appel à commentaires demande donc de la documentation sur les mécanismes de redevabilité du répondeur. Pour l'IETF, c'est l'IAB qui joue ce rôle, en confirmant (ou pas) les nominations et en traitant les appels mentionnés un peu plus haut. C'est aussi l'IAB qui gère les canaux de communication (liaisons) avec les autres organisations. Et c'est l'IAB qui décide quel opérateur gère les registres de paramètres de protocole, actuellement l'ICANN via sa fonction IANA. L'IAB est officiellement décrite dans le RFC 2850. Elle est elle-même redevable devant les participants à l'IETF, par son mécanisme de désignation (RFC 3777).

Quel est le degré de formalisation de votre relation avec l'IANA, demande ensuite l'appel à commentaires ? Un MoU existe (RFC 2860). Son suivi quotidien est assuré par l'IAD (IETF Administrative Director), lui-même sous contrôle de l'IAOC (IETF Administrative Oversight Committee, cf. RFC 4071). Une de leurs tâches est de suivre les rapports de l'IANA sur ses résultats.

En théorie, si un conflit grave surgissait entre l'IETF et l'IANA, l'IETF pourrait mettre fin au travail en commun et choisir un nouvel opérateur pour ses registres (et ce RFC serait alors sans objet). Mais cela ne s'est jamais produit et une telle perspective semble peu probable.

L'appel à commentaires demande aussi à ceux qui répondent d'indiquer de quelle juridiction ils dépendent et quelles sont les lois qui leur sont applicables. L'IETF répond que son activité est mondiale (ce qui est vrai) et que les textes entre l'IANA et l'IETF ne spécifient pas de juridiction (ce qui est exact mais incomplet : l'IETF étant une activité de l'ISOC, l'IETF dépend de la juridiction états-unienne, comme le montrent, par exemple, les injonctions reçues).

Commencent ensuite les questions sensibles, par exemple les demandes de suggestions concernant les mécanismes futurs qui remplaceraient la NTIA. La réponse du RFC est qu'aucun changement n'est demandé par l'IETF : le système actuel avec l'IETF, l'ICANN, l'IAB, etc, a bien fonctionné, sans implication du NTIA, et n'a donc aucun besoin d'être remplacé ou « amélioré ». Les RFC 2860 et RFC 6220 fournissent un cadre satisfaisant et le résultat l'est également.

Cette partie de la réponse contient quand même quelques souhaits, pas forcément de changement mais de points importants à garder en tête :

  • Les registres des paramètres de protocole sont dans le domaine public (ils sont un « bien commun ») et doivent le rester, quels que soient les changements futurs.
  • S'il y a un changement, il faudra que l'ICANN et le nouvel opérateur travaillent ensemble à rendre la transition la plus invisible possible.

Et le RFC réaffirme les principes que l'IAB avait posé en mars 2014 :

  • La « communauté technique Internet » se débrouille très bien à l'heure actuelle et n'a pas besoin d'intervention extérieure.
  • L'enregistrement des paramètres techniques des protocoles doit reposer sur l'ouverture, la transparence et la redevabilité.
  • Tout changement devrait respecter les textes et les accords existants (jolie façon de dire qu'aucun changement n'est souhaité).
  • Les registres des paramètres techniques des protocoles et les autres registres (comme les RIR pour les adresses IP) sont essentiels, et fonctionnent aujourd'hui correctement.
  • L'IETF va continuer dans son rôle.
  • La gestion des registres des paramètres techniques est un service public.

J'avais signalé plus haut que la NTIA avait posé un certain nombre d'exigences pour accepter un éventuel plan de transition. La suite de l'appel à commentaires rappelle ces exigences et demande dans quelle mesure les propositions faites sont conformes à ces oukases. D'abord, la NTIA demande de « continuer avec le modèle multi-partiesprenantes » (ne me demandez pas de définir ce modèle...) L'IETF répond qu'en tant qu'organisation ouverte à tous, elle suit déjà ce modèle (même réponse à la demande de la NTIA que le futur éventuel système « conserve l'ouverture de l'Internet »). Ensuite, la NTIA exige de préserver « la sécurité et la stabilité du DNS » (une des phrases les plus citées dans les milieux de la gouvernance Internet...) L'IETF ne proposant pas de changement, la stabilité est certainement préservée. Puis le gouvernement états-unien veut que les propositions « satisfassent les utilisateurs et répondent à leurs besoins ». Le RFC estime que l'utilisation massive dans le monde des protocoles TCP/IP et donc des registres de l'IANA montre clairement que les utilisateurs sont contents. Dernier ordre de la NTIA : que la solution future ne soit pas multi-gouvernementale (rappelons que le mécanisme actuel de supervision de l'ICANN est mono-gouvernemental). L'IETF réplique que l'IAB n'est pas une organisation gouvernementale et que l'ordre est donc suivi.

L'appel à commentaires de l'ICG demande également par quel processus la réponse a été élaborée, une bonne façon de vérifier que le répondant a appliqué ses beaux principes, y compris lors de la conception de sa réponse. L'IETF explique que la réponse a été développée par le groupe de travail IANAPLAN, qui, comme tous les groupes de travail de l'IETF, était ouvert à tous et faisait tout son travail publiquement (cf. les archives de la liste de diffusion du groupe). Pour le montrer, comme le demande l'appel à commentaire, l'IETF cite de nombreux documents publiquement accessibles :

Le RFC estime que tout ce processus montre un net consensus de l'IETF en faveur de cette réponse. Quelques points sont restés contentieux jusqu'au bout (comme la demande que le nom de domaine iana.org soit transféré à l'IETF Trust).

Quelques lectures supplémentaires sur cette opération de transition :


Téléchargez le RFC 7979


L'article seul

RFC 7971: Application-Layer Traffic Optimization (ALTO) Deployment Considerations

Date de publication du RFC : Octobre 2016
Auteur(s) du RFC : M. Stiemerling (Hochschule Darmstadt, S. Kiesel (University of Stuttgart), M. Scharf (Nokia), H. Seidel (BENOCS), S. Previdi (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF alto
Première rédaction de cet article le 22 novembre 2016


Il est fréquent aujourd'hui sur l'Internet qu'une application cherche à accéder à un contenu (mettons un film, ou bien la mise à jour d'un gros logiciel) qui est disponible à plusieurs endroits. Dans ce cas (qui est notamment fréquent pour le téléchargement en pair-à-pair), quelle source utiliser ? La « meilleure », bien sûr, mais comment la connaître ? Le but du protocole ALTO est de permettre de distribuer de l'information sur la topologie du réseau, afin que les applications puissent choisir la source la plus proche d'elles. ALTO est déjà normalisé (RFC 7285), ce nouveau RFC sert juste à décrire les scénarios d'usage et à donner des conseils pratiques de déploiement (déploiement qui semble très limité pour l'instant).

Outre le RFC décrivant le protocole (RFC 7285), il peut être utile de lire la description du problème qu'ALTO veut résoudre, le RFC 5693, et le cahier des charges, dans le RFC 6708.

La section 2 de notre RFC résume le fonctionnement d'ALTO. C'est un protocole client-serveur, le serveur ALTO connait l'information (la topologie du réseau, qui est connecté à qui, par quel genre de liens), le client est l'application qui veut accéder au contenu, il connait un ensemble potentiel de sources, et il veut savoir quelle est la « meilleure ». Par exemple, dans le cas de BitTorrent, le client a les adresses IP de l'essaim, il veut savoir à laquelle ou lesquelles demander les bouts de fichier (chunks) qui forment le contenu. Le client ALTO peut être un processus séparé, tournant en permanence, ou bien une bibliothèque liée à l'application. Il doit évidemment parler le protocole ALTO, donc connaitre HTTP et JSON.

Pour déployer ALTO, il y a donc quatre entités logiques à considérer :

  • L'origine de l'information (celle qui a compilé les informations de topologie, par exemple en commençant par lister les préfixes IP connus),
  • Le serveur ALTO, qui va distribuer cette information,
  • Le client ALTO, qui va la récupérer,
  • L'application (resource consumer, dans le RFC), qui va en faire quelque chose d'utile.

Ces entités sont typiquement gérées par des organisations différentes. Un exemple typique (mais ce n'est pas la seule possibilité) est que le FAI soit à l'origine de l'information (il connait son réseau), et la mette dans un serveur ALTO qu'il gère, ses abonnés ayant installé une application de partage de fichiers qui inclut un client ALTO. Dans ce cas, il y aurait deux organisations, le FAI gérant les deux premières entités et l'abonné les deux dernières. Mais d'autres répartitions peuvent exister.

Les organisations qui peuvent être impliquées sont en effet multiples : FAI et opérateurs réseau, bien sûr, utilisateurs, évidemment (agissant, soit seuls, soit en groupes se répartissant le travail), mais aussi des tiers, spécialisés dans la collecte et la distribution de cette information (par exemple des CDN). On pourrait même voir apparaitre des sociétés qui ne font que de l'ALTO.

Tout ceci a des conséquences sur le déploiement. Par exemple, un utilisateur peut faire confiance à un FAI mais pas à des tiers. Un FAI peut souhaiter distribuer de l'information à ses abonnés mais pas à tout l'Internet. ALTO définit un protocole, pas une politique : ce protocole permet différents modèles, y compris celui de serveurs ALTO spécialisés et payants. Autre conséquence de l'utilisation de telle ou telle répartition du travail, on pourrait avoir des serveurs ALTO partiels, qui ne contiennent de l'information que sur certains réseaux.

Dans tous les cas, le RFC rappelle qu'ALTO est juste une optimisation : une application doit fonctionner même si elle ne trouve aucun serveur ALTO, ou bien s'ils sont en panne.

Un petit rappel utile sur ALTO : il existe deux modes de fonctionnement différents, qui ont tous les deux des conséquences importantes, notamment sur la confidentialité. Dans le premier mode, le serveur ALTO fournit l'information qu'il a (sous forme de maps, des ensembles de données sur le réseaux, les liens, leur coût, etc) et le client cherche dedans ce qui l'intéresse. Ce mode préserve la vie privée du client (qui ne dit pas au serveur ce qui l'intéresse) mais pas celle du serveur (qui doit tout envoyer). Il n'est pas évident que beaucoup de FAI acceptent cela. Dans le second mode, le serveur permet des interrogations sur un point particulier (« qui est le plus proche de moi ? 192.0.2.87, 203.0.113.122 ou bien 198.51.100.20 ? »). Ce mode évite au serveur de tout divulguer mais oblige en revanche le client à révéler ses intentions (ici, les adresses IP des pairs potentiels, ce qui peut intéresser des organisations répressives comme la HADOPI). Notez que la fuite d'informations du serveur existe aussi dans le second mode : plusieurs clients ALTO peuvent coopérer pour poser beaucoup de questions et extraire ainsi une partie substantive de la base.

La partie 3 de notre RFC en vient aux conseils concrets pour les FAI. On considère que l'objectif du FAI est de minimiser ses coûts, donc a priori de garder le maximum de trafic en local (il y a des exceptions, que liste le RFC). Le serveur ALTO que gère le FAI va donc annoncer des coûts plus faibles pour les liens locaux.

Mais, d'abord, le FAI doit « remplir » le serveur ALTO avec de l'information. Cette étape d'avitaillement commence par la récolte d'informations sur le réseau. A priori, le FAI connait son propre réseau, et n'a donc pas de mal à récolter ces informations. Outre sa propre documentation interne, le FAI peut aussi utiliser de l'information issue d'autres sources, par exemple les protocoles de routage comme BGP (cf., entre autres, le RFC 7752) ou bien des mesures actives ou passives (cf. entre autres, le RFC 7491). Rappelez-vous qu'ALTO est uniquement un protocole permettant d'accéder à de l'information sur la topologie. Comment cette information a été récoltée et agrégée n'est pas de la responsabilité d'ALTO, de même que le protocole HTTP ne se soucie pas de comment est fabriquée la page HTML qu'il sert.

Le FAI doit ensuite appliquer ses critères (coût, performance, etc) à la topologie. Ces critères sont forcément imparfaits. Le client ALTO ne doit pas s'attendre à ce que l'information qui lui est donnée soit idéale dans tous les cas. Par exemple, le serveur ALTO peut indiquer un lien rapide et pas cher mais qui, au moment où le téléchargement commencera, sera saturé par un trafic intense (ALTO ne prétend pas être temps-réel). Et il y a bien d'autres choses qui ne seront pas connues de ceux qui ont compilé l'information, ou bien qui n'auront pas été incluses dans la base de données du serveur ALTO (« la carte n'est pas le territoire »). Les données distribuées par ALTO, les maps, sont supposées être relativement statiques. Mais, dans le monde réel, les choses changent et le client recevra donc peut-être une information légèrement dépassée.

Si vous trouvez le concept de map un peu abstrait, la section 3.5 du RFC donne plusieurs exemples. Par exemple, dans le cas le plus simple, celui d'un petit FAI ayant un seul opérateur de transit, les adresses dudit FAI seront dans le PID (Provider-defined IDentifier, cf. RFC 7285, section 5.1) 1, tout le reste de l'Internet étant le PID 2. Cela donnera une map (syntaxe décrite dans le RFC 7285, section 9.2) :

       {
       ...
        "network-map" : {
          "PID1" : {
            "ipv4" : [
              "192.0.2.0/24",
              "198.51.100.0/25"
            ],
            "ipv6" : [
              "2001:db8:100::/48"
            ]
          },
          "PID2" : {
            "ipv4" : [
              "0.0.0.0/0"
            ],
            "ipv6" : [
              "::/0"
            ]
          }
        }
      }

Un FAI plus gros, et à la topologie plus complexe, a plein de possibilités. Par exemple, ses propres réseaux peuvent être dans des PID différents, s'il veut pouvoir garder le trafic local à un de ses réseaux. Un exemple est celui où le même FAI a des abonnés fixes et mobiles, et où on souhaite limiter les transferts des abonnés fixes vers les mobiles, pour réduire l'utilisation des liens hertziens.

Reste ensuite à effectuer le déploiement des serveurs ALTO. Il existe plusieurs mises en œuvre logicielles d'ALTO et des compte-rendus d'expérience figurent dans les Internet-Drafts draft-seidel-alto-map-calculation et draft-lee-alto-chinatelecom-trial et dans le RFC 6875 (ainsi que, pour un protocole antérieur à ALTO, dans le RFC 5632). Cette expérience montre que certaines façons de collecter l'information peuvent être coûteuses : si un FAI a plusieurs liens avec l'Internet, et reçoit un flux BGP complet, et veut mettre chaque préfixe de la DFZ dans ses maps, il doit prévoir des machines assez costaud pour traiter cette information importante et assez changeante. Et le résultat serait une map qu'il serait difficile d'envoyer à tous les clients, vu sa taille. Il faut donc prévoir, dans ce cas extrême, de l'agrégation vigoureuse des préfixes IP.

La section 4 de notre RFC couvre ensuite l'utilisation d'ALTO, une fois qu'il est déployé. Normalement, tout le monde a intérêt à ce que ALTO soit utilisé : le FAI veut que les utilisateurs épargnent les liens réseaux les plus lents et les plus coûteux et les utilisateurs veulent les meilleures perfomances. En théorie, tout le monde trouvera son intérêt à utiliser ALTO.

Un exemple est celui de BitTorrent. Si les pairs BitTorrent incluent un client ALTO, chaque pair, quand il reçoit une liste d'adresses IP de l'essaim, peut alors interroger le serveur ALTO et trouver les « meilleurs » pairs. Ils peuvent même échanger cette information entre eux (PEX, Peer EXchange, dans le monde BitTorrent). Mais une autre possibilité est que ce ne soient pas les pairs qui interrogent le serveur ALTO mais le tracker (pour les essaims fonctionnant avec une machine qui sert de tracker, ce qui n'est pas toujours le cas). Ainsi, il n'est pas nécessaire de mettre un client BitTorrent dans chaque pair, c'est le tracker qui, grâce à l'information ALTO, choisit les meilleurs pairs pour chacun, et ne leur envoie que cela.

Le RFC se conclut pas une section 7 sur la sécurité. Parmi les problèmes à considérer, il y a le fait qu'un serveur ALTO malveillant, ou bien un serveur se faisant passer pour un serveur ALTO légitime, peut empoisonner le client avec de fausses données.


Téléchargez le RFC 7971


L'article seul

RFC 7970: The Incident Object Description Exchange Format Version 2

Date de publication du RFC : Novembre 2016
Auteur(s) du RFC : R. Danyliw (CERT)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mile
Première rédaction de cet article le 1 décembre 2016


Pour rendre plus facilement analysables les innombrables rapports d'incidents de sécurité qui circulent sur Internet tous les jours, ce RFC spécifie un format standard XML, nommé IODEF, pour décrire ces incidents. Ici, il s'agit de la version 2 de ce format IODEF, la version 1 était dans le RFC 5070.

Tous les jours, des organisations comme les CERT et CSIRT, mais aussi les OIV, envoient et reçoivent des rapports détaillés concernant une attaque sur un réseau informatique ou un serveur. Ces rapports sont longs et détaillés mais, la plupart du temps, ce n'est pas une attaque isolée qui est intéressante, c'est l'image qui apparait lorsqu'on synthétise tous les rapports, et qu'on voit alors les tendances, par exemple l'arrivée d'un nouveau ver ou bien une attaque concertée contre un pays donné. D'où l'importance de pouvoir analyser automatiquement ces rapports, ce qui impose un modèle de données et un format standard, ce que fournit ce RFC.

Le modèle de données est proche des modèles objet, par exemple dans la descriptions des classes d'objets manipulés (comme la classe Incident en section 3.2, avec la cardinalité des attributs). Ces classes sont composés avec des données élémentaires (booléens, entiers, dates) décrites dans la section 2. Par exemple, parmi les attributs de la classe Incident, on trouve l'heure de début et de fin de l'incident, l'heure de détection, etc. Le schéma XML complet, écrit en W3C Schema, figure dans la section 8.

On trouve énormément de choses dans ce schéma (le RFC fait plus de 160 pages), pour traiter tous les cas prévus. Par exemple, on peut exprimer une liste de ports comprenant à la fois des ports individuels et des intervalles : 22,53,80,1024-2047. De nombreuses classes existent pour utiliser ces informations élémentaires. Ainsi, la classe Discovery, une nouveauté de la version 2, permet d'indiquer comment l'incident a été découvert (avec un attribut source qui a vingt valeurs possibles, comme avantivirus, os-logjournal, passive-dns - un système comme DNSdb, etc). Et BusinessImpact permet de décrire les conséquences de l'incident sur l'activité (breach-privacy, loss-of-service, theft-financial, etc). Ça peut même se quantifier financièrement avec la classe MonetaryImpact. Si on met les incidents de sécurité dans une base de données (ça s'appelle un SIEM, comme Prelude), on peut donc imaginer de regarder d'abord les incidents qui ont coûté le plus cher...

Voici un exemple d'un rapport d'incident, tiré du RFC (section 7), et qui décrit et qui décrit les systèmes de C&C (quatre serveurs) d'une campagne donnée (dans le RFC 5070, l'exemple était une simple reconnaissance avec nmap...). Cet exemple a l'avantage d'illustrer la classe IndicatorData, une nouveauté de la version 2 :


   <?xml version="1.0" encoding="UTF-8"?>
   <!-- A list of C2 domains associated with a campaign -->
   <IODEF-Document version="2.00" xml:lang="en"
      xmlns="urn:ietf:params:xml:ns:iodef-2.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation=
      "https://www.iana.org/assignments/xml-registry/schema/
       iodef-2.0.xsd">
     <Incident purpose="watch" restriction="green">
       <IncidentID name="csirt.example.com">897923</IncidentID>
         <RelatedActivity>
           <ThreatActor>
             <ThreatActorID>
             TA-12-AGGRESSIVE-BUTTERFLY
             </ThreatActorID>
             <Description>Aggressive Butterfly</Description>
           </ThreatActor>
           <Campaign>
             <CampaignID>C-2015-59405</CampaignID>
             <Description>Orange Giraffe</Description>
           </Campaign>
         </RelatedActivity>
         <GenerationTime>2015-10-02T11:18:00-05:00</GenerationTime>
         <Description>Summarizes the Indicators of Compromise
           for the Orange Giraffe campaign of the Aggressive
           Butterfly crime gang.
         </Description>
         <Assessment>
           <BusinessImpact type="breach-proprietary"/>
         </Assessment>
         <Contact type="organization" role="creator">
           <ContactName>CSIRT for example.com</ContactName>
           <Email>
             <EmailTo>contact@csirt.example.com</EmailTo>
           </Email>
         </Contact>
         <IndicatorData>
           <Indicator>
             <IndicatorID name="csirt.example.com" version="1">
             G90823490
             </IndicatorID>
             <Description>C2 domains</Description>
             <StartTime>2014-12-02T11:18:00-05:00</StartTime>
             <Observable>
               <BulkObservable type="fqdn">
               <BulkObservableList>
                 kj290023j09r34.example.com
                 09ijk23jfj0k8.example.net
                 klknjwfjiowjefr923.example.org
                 oimireik79msd.example.org
               </BulkObservableList>
             </BulkObservable>
           </Observable>
         </Indicator>
       </IndicatorData>
     </Incident>
     </IODEF-Document>

Le RFC note sagement que le partage d'informations n'est pas uniquement une question technique, mais qu'elle dépend aussi des procédures bureaucratiques de chaque organisation, des contraintes légales, de la confiance (ou de l'absence de confiance, souvent justifiée) et enfin de la simple bonne ou mauvaise volonté. (Mon opinion personnelle est que, en France, le partage d'informations précises sur les incidents de sécurité est très insuffisant.)

Les changements depuis la version 1 (celle du RFC 5070) sont listés dans la section 1.4. Beaucoup de détails, beaucoup d'ajouts, parmi lesquels je note :

  • Meilleure internationalisation (voir à ce sujet la section 6 du RFC), comme le fait que la classe Contact permette désormais d'indiquer une adresse postale en un jeu de caractères quelconque,
  • Nouvelles classes (comme IndicatorData ou Discovery cités plus haut, ou comme DomainData, pour des informations sur un nom de domaine), et nouveaux attributs dans les classes existantes (par exemple, Incident y gagne observable-id, un identificateur qui peut être utilisé dans des références croisées).

Si l'ajout de nouvelles classes ne rendent pas les anciennes descriptions IODEF incorrectes, en revanche, certains changements cassent la compatibilité et un fichier IODEF version 1 parfait ne sera pas forcément légal pour la version 2 (cf. section 4.4). Par exemple, la sous-classe NodeRole (qui permet de décrire si on est attaqué par une caméra de vidéosurveillance ou bien par un routeur) a changé de classe parente.

Et les mises en œuvre d'IODEF ? Un résumé de l'état de ces mises en œuvre figure dans l'Internet-Draft draft-ietf-mile-implementreport, et qui référence une liste des programmes IODEF (j'ai aussi trouvé celle-ci). Parmi d'autres, on peut noter la bibliothèque de Prelude (et qui a une version pour l'IODEF v2 de notre RFC), un module Perl, un autre en PHP, et un troisième en Python. On trouve aussi des moyens de connecter IODEF à des logiciels existants par exemple au logiciel de suivi de tâche Mantis, avec ce connecteur.

Pour des articles ou présentations sur IODEF, vous pouvez voir la Rump (session rapide) de Thomas Andrejak au SSTIC 2016 (vidéo en ligne).

Notez en France l'existence du projet SECEF (SECurity Exchange Format) qui a pour objectif de promouvoir et de faciliter l’usage des deux formats de fichier IDMEF (RFC 4765) et IODEF. Vous pouvez consulter leur Wiki, et leur tutoriel IODEF. Il y a aussi un article de synthèse sur SECEF, et un compte-rendu d'une de leurs réunions (mais vite fait et avec des erreurs). Enfin, le RFC 8274 donne quelques conseils sur la mise en œuvre d'IODEF.


Téléchargez le RFC 7970


L'article seul

RFC 7962: Alternative Network Deployments: Taxonomy, Characterization, Technologies, and Architectures

Date de publication du RFC : Août 2016
Auteur(s) du RFC : J. Saldana (University of Zaragoza), A. Arcia-Moret (University of Cambridge), B. Braem (iMinds), E. Pietrosemoli (The Abdus Salam ICTP), A. Sathiaseelan (University of Cambridge), M. Zennaro (The Abdus Salam ICTP)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF gaia
Première rédaction de cet article le 17 septembre 2016


On pourrait croire que la seule façon d'accéder à l'Internet est via un FAI commercial, géré hiérarchiquement (avec directeur, plein de sous-directeurs, etc), dont les utilisateurs paient pour bénéficier de l'accès (mais sans avoir leur mot à dire sur le fonctionnement du FAI), et disposant de grands moyens financiers et techniques. C'est certainement la vision dominante et elle arrange bien les gens des médias et des gouvernements, qui se retrouvent dans une situation connue, avec un petit nombre d'acteurs « professionnels ». Heureusement, l'Internet n'est pas comme cela : c'est une confédération de réseaux très variés, certains effectivement gérés comme indiqué plus haut, mais d'autres fonctionnant sur des modèles très différents, ayant fait des choix techniques, de gouvernance et de financement très différents et très variés. Cet excellent RFC décrit et classe les réseaux « alternatifs ».

Il a été écrit dans le cadre du groupe de recherche GAIA (Global Access to the Internet for All) de l'IRTF. GAIA vise à documenter ces déploiements « alternatifs » et à faciliter le partage d'expérience. Outre le simple rappel de l'existence de ces réseaux « alternatifs », son mérite est de proposer une taxonomie de ces réseaux (forcément imparfaite, vu leur variété) et de donner une idée de la variété des technologies qu'ils utilisent.

Ces techniques sont en effet souvent différentes de celles utilisées dans les réseaux « officiels » (mainstream). Ces réseaux « alternatifs » visent en général des situations difficiles, comme la connexion de lieux lointains, où l'argent ne coule pas à flots. À part cela, ces réseaux n'ont rien en commun, ni leur organisation, ni leurs buts. Qu'est-ce qui motive leur création ? (Au passage, le RFC fait comme si ces réseaux « alternatifs » étaient une création récente ; certains sont au contraire aussi vieux que l'Internet.) Les raisons de ces projets sont elles aussi très diverses : absence pure et simple de FAI commercial, insatisfaction vis-à-vis des FAI officiels existants, désir d'essayer quelque chose d'autre...

Passons au difficile jeu des définitions. Le RFC (section 1.1) définit le réseau « officiel » (mainstream) ainsi :

  • De grande taille, par exemple à l'échelle d'un pays,
  • Gestion du réseau centralisée : tout part d'en haut,
  • Gros investissements dans l'infrastructure,
  • Les utilisateurs sont de purs consommateurs : ils n'ont absolument pas leur mot à dire, et, la plupart du temps, ils ne reçoivent aucune information, ils ne savent pas ce qui se passe dans le réseau qu'ils utilisent.

Et les réseaux « alternatifs », comment se définissent-ils (section 1.2) ? C'est plus difficile car il en existe de nombreuses variantes :

  • En général de petite taille, par exemple à l'échelle d'une région,
  • La gestion du réseau n'est pas forcément centralisée,
  • Les frais d'infrastructure peuvent être très répartis (les utilisateurs en paient parfois un bout, des infrastructures publiques peuvent être utilisées, etc),
  • Les utilisateurs ne sont pas forcément de purs consommateurs, ils peuvent être partie prenante à la gouvernance du réseau, et/ou à son fonctionnement technique.

Ce problème des définitions est évidemment très présent dans tout le RFC. Par exemple, comment parler des pays qui ne sont pas les membres de l'OCDE (et encore, l'OCDE compte deux ou trois membres « intermédiaires ») ? Le Tiers-Monde ? Le Sud ? Les pays pauvres ? Les sous-développés ? Les « en voie de développement » ? La section 2 du RFC propose des définitions :

  • Nord et Sud (« global north » et « global south ») sont utilisés pour parler, d'une part des pays riches (même si certains, comme l'Australie, sont au Sud) et des autres. Ce ne sont pas des termes parfaits mais aucun ne l'est.
  • Fracture numérique : la différence d'accès à l'Internet entre les favorisés et les autres. Elle n'est pas seulement entre pays, elle peut aussi être à l'intérieur d'un pays.
  • Zones « rurales » et « urbaines » : les définitions officielles vont varier selon les pays mais, en gros, il est plus difficile de convaincre les opérateurs à but lucratif de venir dans les zones à faible densité de population (zones « rurales »).
  • « Réseau libre » (Free Network) : c'est un terme délicat, car politiquement chargé, mais notre RFC reprend la définition de la Free Network Foundation. Dans un réseau libre, on peut utiliser le réseau librement (la liberté s'arrêtant évidemment là où commence la liberté des autres, donc pas le droit de faire des DoS par exemple), comprendre comment il marche (pas de secrets) et on peut soi-même fournir des services au-dessus de ce réseau.

Maintenant, les cas où on déploie ces réseaux « alternatifs » (section 3 du RFC). Il y aurait actuellement 60 % de gens sur Terre sans connectivité Internet. Et la répartition est très inégale (20 % sans connexion au « Nord », 69 % au « Sud »). Parmi les facteurs qui vont intervenir :

  • La disponibilité de connexions internationales (ce n'est pas tout de se connecter entre soi, il faut aussi se relier au reste du monde), et de matériel,
  • Les problèmes d'alimentation électrique,
  • Le contexte légal. Ici, le RFC reprend telle quelle l'idéologie répandue à l'ISOC comme quoi la régulation, c'est mal, et qu'il faut tout privatiser.

Dans les zones rurales, on a vu que c'était souvent pire. Johnson, D., Pejovic, V., Belding, E., et G. van Stam, dans leur article « Traffic Characterization and Internet Usage in Rural Africa » (In Proceedings of the 20th International Conference Companion on World Wide Web) rapportent des latences mesurées à plusieurs secondes. Les problèmes des zones rurales sont souvent cruciaux : faible revenu monétaire, manque d'infrastructures de base comme l'électricité et les routes, densité de population réduite, manque de compétences (les techniciens compétents quittent rapidement ces zones pour aller en ville), etc.

La section 4 de notre RFC s'attaque ensuite au difficile problème de la classification de ces réseaux « alternatifs ». Sur quels critères faire cette classification ? Les auteurs du RFC en trouvent cinq. D'abord, quelle organisation gère le réseau ? Un groupe plus ou moins formel d'utilisateurs ? Une collectivité publique ? Une société privée ? Un organisme de recherche ou d'enseignement ? (En France, on aurait ajouté « Une association loi 1901 ? »)

Second critère de classification, le but de la création de ce réseau : fournir un accès qui n'existerait pas du tout autrement ? Fournir une alternative bon marché ? Expérimenter et tester ? S'attaquer à d'autres problèmes de fracture numérique (comme la littératie numérique) ? Fournir un accès d'urgence suite à une catastrophe ? Ou bien un but plus politique, par exemple des mécanismes de gouvernance différents, une approche davantage « bien commun » ? Ou fournir un accès libre et neutre, contrairement à ce que font la quasi-totalité des FAI ? (Ce dernier point est présenté de manière très modérée dans le RFC qui, globalement, évite de parler des choses qui fâchent, comme la politique.)

Bien sûr, un réseau alternatif peut avoir plusieurs de ces mobiles. Et ceux-ci peuvent être plus ou moins explicites, et ils évoluent dans le temps. Le réseau Redhook avait commencé plutôt comme outil local, avant de devenir le seul réseau à fonctionner après Sandy.

Un autre critère, proche du premier, est celui du modèle de gouvernance : très ouvert, avec une participation active des utilisateurs, ou bien plus traditionnelle, avec une organisation centrale qui s'occupe de tout ? (On peut avoir un réseau qui est la propriété d'un groupe d'utilisateurs mais qui, en pratique, est géré par une petite organisation structurée.)

Autre critère, qui va plaire aux techniciens, quelles sont les techniques employées dans ce réseau ? Wi-Fi traditionnel ? Wi-Fi modifié pour les longues distances (WiLD) ? WiMAX ? Espaces blancs de la télévision (cf. RFC 7545) ? Satellite comme dans le projet RIFE ? Voire des fibres optiques terrestres ?

Enfin, dernier critère de classification, le contexte : zone rurale ou urbaine, Nord ou Sud.

Avec ces critères, on peut maintenant procéder à la classification (section 5 du RFC). Notre RFC distingue (un peu arbitrairement) six catégories, caractérisées par les réponses à ces cinq critères. Première catégorie, les réseaux d'un groupe local (community networks). Géré par un groupe de citoyens proches, ils ont typiquement un fonctionnement très ouvert et participatif. Leur croissance est en général non planifiée et non organisée : les premiers membres se connectent puis d'autres volontaires les rejoignent. Le mécanisme de décision est la plupart du temps très décentralisé. En général, ils utilisent le Wi-Fi et chaque membre contribue donc à la croissance du réseau « physique » sous-jacent. Plusieurs exemples de tels réseaux sont décrits dans l'article de Braem, B., Baig Vinas, R., Kaplan, A., Neumann, A., Vilata i Balaguer, I., Tatum, B., Matson, M., Blondia, C., Barz, C., Rogge, H., Freitag, F., Navarro, L., Bonicioli, J., Papathanasiou, S., et P. Escrich, « A case for research with and on community networks », et une analyse technique détaillée d'un réseau d'un groupe local figure dans Vega, D., Baig, R., Cerda-Alabern, L., Medina, E., Meseguer, R., et L. Navarro, « A technological overview of the guifi.net community network ».

Seconde catégorie, les WISP (Wireless Internet Service Providers). Cette fois, le réseau est géré par une société traditionnelle, mais il est « alternatif » par le public visé (typiquement des régions rurales mal desservies, où l'infrastructure est minimale, et où les FAI traditionnels ne vont pas). C'est par exemple le cas de la société Airjaldi en Inde, ou d'EveryLayer.

Troisième catégorie de réseaux alternatifs, l'infrastructure partagée (Shared Infrastructure model). L'infrastructure du réseau est partagée entre un opérateur traditionnel et les utilisateurs. C'est le cas lorsque les utilisateurs détiennent le matériel (par exemple femtocell) mais que la gestion est assurée par un FAI. Les utilisateurs sont payés, soit directement par le FAI qui leur loue l'infrastructure, soit indirectement par l'accès à l'Internet qu'ils obtiennent via ce FAI. Dans pas mal de régions rurales dans le monde, la 3G a été déployée ainsi, via les femtocells. Prévue à l'origine pour fournir une meilleure couverture dans les bâtiments, cette technologie peut aussi être utilisée pour fournir des accès aux téléphones mobiles sans que l'opérateur ait eu à supporter de gros investissements.

Un exemple d'infrastructure partagée est le projet TUCAN3G, en utilisant WiLD Ce projet est décrit par Simo-Reigadas, J., Morgado, E., Municio, E., Prieto-Egido, I., et A. Martinez-Fernandez dans « Assessing IEEE 802.11 and IEEE 802.16 as backhaul technologies for rural 3G femtocells in rural areas of developing countries » et par Simo-Reigadas, J., Municio, E., Morgado, E., Castro, E., Martinez-Fernandez, A., Solorzano, L., et I. Prieto- Egido dans « Sharing low-cost wireless infrastructures with telecommunications operators to bring 3G services to rural communities ».

Autre catégorie possible, les approches « foule de volontaires » (Crowdshared approaches) où des utilisateurs qui ne se connaissent pas forcément mettent la main au portefeuille pour participer à un projet commun, qui sera géré par une une société ou par eux-mêmes. Typiquement, les utilisateurs mettent à la disposition de tous une partie de leur capacité réseau, et l'entité qui gère le réseau est une simple coordination, elle ne possède rien. C'est ce que promeut le mouvement OpenWireless. Parmi les exemples, on peut citer des sociétés comme FON, les projets municipaux comme décrit dans l'article de Heer, T., Hummen, R., Viol, N., Wirtz, H., Gotz, S., et K. Wehrle, « Collaborative municipal Wi-Fi networks- challenges and opportunities », ou les réseaux Wi-Fi de Sathiaseelan, A., Crowcroft, J., Goulden, M., Greiffenhagen, C., Mortier, R., Fairhurst, G., et D. McAuley, « Public Access WiFi Service (PAWS) ».

Il y a aussi des réseaux montés par des coopératives en milieu rural, ce qui forme la cinquième catégorie identifiée. Ce genre de coopératives fournissant un service local est courant et ancien. Le RFC cite l'exemple des États-Unis où l'électricité en milieu rural est souvent fournie ainsi, et ce depuis les années 1930. Ces coopératives peuvent même passer leurs propres fibres optiques (« CO-MO'S D.I.Y. model for building broadband »). Des partenariats sont possibles avec ceux qui fournissent d'autres services que l'Internet, comme l'électricité dans l'exemple ci-dessus. Deux exemples sont donnés dans l'article de Mitchell « Broadband at the Speed of Light: How Three Communities Built Next-Generation Networks » ou dans le guide « Broadband Guide for Electric Utilities ».

Enfin, dernière catégorie de réseau alternatif, ceux créés à des fins de recherche. Par exemple, le réseau est créé par une université pour explorer une technique et/ou des usages (comme Bernardi, B., Buneman, P., et M. Marina, « Tegola tiered mesh network testbed in rural Scotland »).

Après cette catégorisation des réseaux alternatifs, penchons-nous sur les technologies utilisées (section 6 du RFC). Le cas de réseaux filaires est rare mais existe (comme à Lowenstedt ou dans certains endroits de Guifi.net). La plupart du temps, les réseaux alternatifs utilisent l'hertzien. Les normes techniques en œuvre sont en général celles du groupe IEEE 802.

La plus connue est évidemment Wi-Fi (802.11). Mais on trouve aussi du GSM (une norme ETSI) par exemple dans un village mexicain ou dans le projet Village Base Station. Il y a même du GSM en logiciel libre, dans les projets OpenBTS ou OpenBSC. Ces projets sont en train de migrer vers des technologies plus rapides (mais, ce que le RFC oublie de dire, bien moins libres, notamment car pourries de brevets) comme la 4G.

On a signalé plus haut que certains réseaux peuvent utiliser les espaces blancs laissés par la télévision, découvrant les fréquences utilisables via une base de données (RFC 7545) ou bien en regardant le trafic existant pour voir si l'espace est vraiment blanc.

Le Wi-Fi est limité en portée, et certains réseaux utilisent des techniques plus adaptées aux longues distances comme WiMAX (IEEE 802.16) ou bien 802.22, qui utilise justement ces espaces blancs.

Et dans les couches au-dessus de ces couches 1 et 2, quelles techniques utilisent les réseaux alternatifs ? La section 7 du RFC décrit rapidement les divers choix. D'abord, la couche 3. La plupart des réseaux n'utilisent qu'IPv4 et, ne pouvant pas obtenir suffisamment d'adresses IP des RIR sans gros efforts, se limitent aux adresses IP privées du RFC 1918. (Avant l'épuisement des adresses IPv4, obtenir des adresses des RIR était plus simple que beaucoup de gens ne le croyaient, mais il fallait quand même se taper une bureaucratie complexe et des règles difficiles.)

Pour la plupart des réseaux alternatifs, IPv6 était déjà normalisé depuis longtemps lorsqu'ils ont démarré leur projet. Mais peu l'utilisent (ninux.org est une exception), probablement essentiellement par ignorance. (Le questionnaire « Questionnaire based Examination of Community Networks » incluait des questions sur IPv6).

Pour le routage, les choix dépendent souvent de la structure du réseau alternatif. Certains sont de type mesh, avec peu ou pas d'autorité centrale, d'autres sont plus structurés. Il y a donc des protocoles de routage traditionnels comme OSPF (le RFC cite aussi BGP, ce qui me surprend pour un réseau alternatif).

Mais il y a aussi des protocoles prévus pour des réseaux moins structurés, comme ceux utilisés dans les MANET. On peut trouver de l'OLSR (RFC 3626), parfois dans des versions modifiées (ce qui est le cas de http://olsr.org/), ou parfois sa récente version 2 (RFC 7181). D'autres réseaux utilisent du BATMAN. Le RFC cite l'excellent Babel (RFC 8966) mais n'indique pas s'il est très employé sur le terrain (il semble moins connu, dans un milieu où l'information circule mal).

Et la couche au-dessus, la couche transport ? L'un des problèmes que doit traiter cette couche est celui de la congestion : il faut assurer le partage de la capacité réseau entre plusieurs acteurs. Dans les réseaux alternatifs, pas forcément gérés centralement, et aux frontières pas toujours nettement délimitées, le défi est encore plus important. Il peut donc être intéressant d'enourager des protocoles « raisonnables » (RFC 6297), qui cèdent le pas systématiquement aux autres protocoles, afin que les activités non-critiques ne rentrent pas en compétition avec le trafic « important ».

Enfin, les utilisateurs ne s'intéressent typiquement qu'à une seule chose, les services, et il est donc utile de se demander ce que ces réseaux alternatifs proposent. Il y a bien sûr tous les services de base, notamment le Web. Certains services très répandus (vidéo haute définition, par exemple), peuvent être très coûteux pour les ressources souvent limités du réseau alternatif. Leur utilisation peut donc être restreinte. Et il y a aussi des services spécifiques des réseaux alternatifs : des VPN comme IC-VPN, des portails d'intérêt local comme Tidepools, des télévisions ou radios locales, des systèmes de relais de VoIP pour permettre des appels bon marché, des réseaux de capteurs permettant de la citizen science, etc.

Voilà, c'est terminé, cet article était long mais le RFC est plus long encore, et il se termine par une impressionnante bibliographie dont je n'ai cité que quelques extraits : plein de choses passionnantes à lire.


Téléchargez le RFC 7962


L'article seul

RFC 7960: Interoperability Issues between Domain-based Message Authentication, Reporting, and Conformance (DMARC) and Indirect Email Flows

Date de publication du RFC : Septembre 2016
Auteur(s) du RFC : F. Martin (LinkedIn), E. Lear (Cisco Systems), T. Draegen (dmarcian), E. Zwicky (Yahoo), K. Andersen (LinkedIn)
Pour information
Réalisé dans le cadre du groupe de travail IETF dmarc
Première rédaction de cet article le 11 octobre 2016


Le mécanisme DMARC permet d'indiquer dans le DNS la politique d'un domaine concernant l'authentification du courrier. Si je reçois un message prétendant venir de ma-banque.example, et qu'il n'est pas authentifié (ni SPF, ni DKIM, ni autre chose), comment savoir si c'est parce que ma banque est nulle en sécurité du courrier, ou bien parce que le message est un faux ? DMARC (normalisé dans le RFC 7489) permet de répondre à cette question en publiant un enregistrement qui indique si le courrier est censé être authentifié ou pas. Comme toutes les techniques de sécurité, ce mécanisme est imparfait et il pose notamment des problèmes avec les messages indirects. Par exemple, si vous avez une adresse à votre ancienne université, alice@univ.example et que le courrier qui lui est adressé est automatiquement transmis à votre adresse professionnelle, alice@evilcorp.example, comment DMARC va-t-il réagir avec cette indirection ? C'est ce qu'explore ce RFC.

Voici la politique DMARC de Gmail. Elle est tolérante (p=none, accepter les messages non authentifiés) :

    
% dig TXT _dmarc.gmail.com
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59294
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
_dmarc.gmail.com.	600 IN TXT "v=DMARC1; p=none; rua=mailto:mailauth-reports@google.com"
...

_dmarc.paypal.com.	300 IN TXT "v=DMARC1; p=reject; rua=mailto:d@rua.agari.com; ruf=mailto:dk@bounce.paypal.com,mailto:d@ruf.agari.com"

La question de départ de l'administrateur système est « si je mets une politique DMARC restrictive (genre p=reject), vais-je perdre des courriers légitimes, à cause d'indirections comme les listes de diffusion ? » (section 1 du RFC). Il est d'autant plus difficile de répondre à cette question que l'architecture du courrier électronique est complexe et mal spécifiée (RFC 5598). Bien des logiciels ne suivent pas les règles, d'autant plus que beaucoup de ces règles n'ont pas été explicites dès le début. (Un bon exemple : avec un .forward, le serveur de courrier doit-il garder l'expéditeur indiqué dans l'enveloppe du message ? Essayez de trouver un RFC qui spécifie cela !)

La section 2 de notre RFC décrit les causes des problèmes DMARC. Si un message est légitime (le destinataire veut le recevoir), et qu'il est en outre techniquement correct, un problème, au sens de ce RFC, est quand la politique de DMARC (qui peut être de rejet) est appliquée à ce message, parce qu'il a été transmis indirectement. C'est injuste. Évidemment, si la politique DMARC est p=none (ne rien faire), ce n'est pas un vrai problème. Mais un p=reject peut être très ennuyeux.

Première cause de problèmes, des différences entre les identificateurs utilisés. DMARC n'authentifie pas directement, il dépend de SPF (RFC 7208) et DKIM (RFC 6376) pour cela. Ce qui intéresse l'utilisateur, évidemment, c'est le nom dans le champ From: (RFC 5322) du message. Pour lui, c'est ça l'expéditeur. Mais DKIM, et surtout SPF, n'ont pas la même conception : ils peuvent utiliser d'autres identificateurs. DMARC considère que l'accord (alignment, cf. RFC 7489, section 3.1) entre les identificateurs authentifiés par SPF et DKIM, et le champ From: du message peut être strict ou laxiste. « Strict » indique une correspondance parfaite, laxiste se limite à vérifier que le nom de domaine est le même.

Le principal identificateur utilisé par SPF est celui donné par la commande MAIL FROM dans la session SMTP (RFC 5321). C'est la principale cause de désaccord : si SPF authentifie cet identificateur et qu'il est différent de l'adresse utilisée dans le champ From: de l'en-tête du message, que faire ?

Deuxième cause de problème, le relayage d'un message. Si Bob bob@isp.example écrit à alice@univ.example, et qu'elle (ou son administrateur système) a demandé un relayage automatique vers alice@evilcorp.example, les serveurs de courrier de evilcorp.example verront un message prétendant être de isp.example, mais transmis par les serveurs de univ.example... SPF sera content ou pas, selon la façon exacte dont a été fait le relayage (en préservant le MAIL FROM ou pas). DMARC ne sera jamais content car, si le MAIL FROM a été changé (reflétant le relais), SPF authentifiera mais il n'y aura plus d'accord entre les identificateurs.

Évidemment, si le message est modifié en cours de route, c'est encore pire. SPF ne protège pas l'intégrité du message, mais DKIM le fait. Mais qui diantre se permet de modifier les messages ? Hélas, pas mal de gestionnaires de listes de diffusion le font. DKIM a une option (déconseillée... voir la section 8.2 du RFC 6376) pour ne signer que le début du message, évitant ainsi que la signature soit invalidée par l'ajout, par exemple, d'un paragraphe final. Cela ne couvre que le cas des messages simples, sans MIME, où la modification est un simple ajout à la fin. Autre possibilité de DKIM pour éviter d'invalider les signatures en cas de modification du message, le mode relaxed de canonicalisation du contenu, qui permet de supporter des modifications triviales comme la transformation de N espaces consécutifs en un seul.

Reprenant le vocabulaire du RFC 5598 (relisez-le d'abord !), la section 3 de notre RFC liste les différents composants de la messagerie qui peuvent jouer un rôle dans les transmissions indirectes, et les problèmes qu'elles posent. D'abord, le MSA (Message Submission Agent.) C'est la première ligne de vérification : il fait respecter les règles d'une organisation (ADMD, ADministrative Management Domain). S'il accepte un message où le champ From: du RFC 5322 n'est pas dans un domaine contrôlé par l'ADMD, il y a des chances que DMARC râle par la suite. Le RFC cite plusieurs cas d'usage où cela se produit : la fonction « envoyer cet article à un ami » de certains sites Web, par exemple, puisque le message va partir avec le domaine du lecteur de l'article, pas avec celui du site Web. On peut trouver de nombreux autres exemples, comme un service de gestion d'agenda qui envoie des courriers de rappel, en utilisant comme expéditeur l'adresse de l'utilisateur, ce qui est plutôt une bonne chose (pour des messages du genre « l'heure de la réunion a changé ») mais peut gêner DMARC. (Mon exemple préféré est le cas où on a une adresse de courrier mais pas de moyen de soumettre du courrier via cette organisation, ce qui est fréquent avec les adresses de fonction. Par exemple, on est membre d'une organisation qui fournit des adresses à ses membres et/ou responsables, ce qui permet de recevoir du courrier, mais on n'a pas de MSA pour en envoyer, on doit donc utiliser celui d'une autre organisation.)

Et les MTA, eux, quel est leur rôle dans les problèmes DKIM ? S'il change l'encodage (par exemple en passant du « 8 bits » à l'abominable Quoted-Printable), il va invalider les signatures DKIM (la canonicalisation de DKIM ne prévoit pas des transformations aussi radicales, même si elles ne modifient pas le message final). Idem si le MTA corrige les en-têtes du message pour les rendre conformes (une tâche qui relève plutôt du MSA, le MTA devant lui, transmettre fidèlement les messages qu'il a choisi d'accepter) : cela sort également du champ de la canonicalisation DKIM et cela invalide donc les éventuelles signatures. Enfin, le changement ou la suppression de certaines parties MIME (par exemple l'élision d'un document ZIP attaché, pour des raisons de protection contre les logiciels malveillants transmis par courrier) va évidemment également rendre les signatures invalides.

Et le MDA ? Peut-il casser des choses, également ? Oui, s'il passe les messages par Sieve (RFC 5228), qui a la possibilité d'ajouter ou de retirer des en-têtes, voire de modifier le corps (extension Sieve du RFC 5703). Si les tests DMARC sont faits après le passage de Sieve, ou bien si le message est ensuite réinjecté dans le système de courrier, des problèmes peuvent se produire.

Reste le cas des intermédiaires (mediators). Ce sont les entités qui prennent un message, puis le ré-expédient (parfois après modification). Un exemple est l'alias. Via une entrée dans /etc/aliases ou bien via un .forward, ou bien via le redirect de Sieve, ou encore via encore une autre méthode, un message initialement destiné à une adresse est finalement transmis à une autre. C'est par exemple courant pour les adresses « ancien élève », que fournissent certaines universités, et qui permettent de garder à vie une adresse dans le domaine de l'établissement où on a fait ses études. Un certain nombre d'associations professionnelles fournissent un service équivalent. En général, ces intermédiaires ne cassent pas DKIM (ils ne modifient pas le message) mais, selon la façon dont ils redirigent, peuvent invalider l'autorisation SPF.

Un autre exemple d'intermédiaire classique est le gestionnaire de listes de diffusion. En plus de rediriger un message (ce qui fait que le message écrit par alice@univ.example n'est pas émis par les serveurs de courrier de l'université), ces logiciels changent souvent le message, par exemple en ajoutant une inutile étiquette [Ma jolie liste] aux sujets des messages, en ajoutant un texte à la fin (instructions de désabonnement, pourtant déjà possibles avec l'en-tête List-Unsubscribe:), en retirant des pièces jointes, ou bien (surtout dans les théocraties comme les États-Unis) en remplaçant des gros mots par des termes plus acceptables.

Toutes ces modifications vont probablement invalider les signatures DKIM (cf. RFC 6377) et faire que les messages envoyés par certains participants à la liste (ceux qui ont une politique DMARC p=reject) ne seront pas reçus par les destinataires qui testent cette politique. (Si un avis de non-remise est transmis, le logiciel de gestion de la liste peut en déduire que l'adresse n'existe pas, et désabonner d'autorité le destinataire.)

Et les filtres ? Certaines organisations insèrent dans le réseau des dispositifs qui vont analyser le courrier, par exemple à la recherche de logiciel malveillant. Souvent, ils vont modifier les messages, afin de supprimer ces contenus indésirables. Ces modifications vont évidemment invalider les signatures. Idem si on change ou supprime des URL contenus dans le message et considérés « dangereux ». Même chose avec un système anti-spam qui ajouterait un [SPAM] dans le sujet.

En revanche, le courrier reçu d'un serveur secondaire (MX de secours), qui a pris le relais pendant une panne du primaire, puis expédié le courrier quand le primaire remarche, ne pose pas de problèmes. Bien sûr, les tests SPF échoueront mais, normalement, on ne fait pas ces tests sur le courrier qui vient de son propre serveur secondaire.

Bon, voici le tour d'horizon complet de tout ce qui peut marcher mal. Mais que faire ? La section 4 du RFC s'attaque aux solutions. Elles sont nombreuses et très différentes. Mais attention : DMARC est là pour rejeter des messages considérés comme invalides. On peut arranger les choses pour que certains de ces messages « passent » mais cela va contre le but de DMARC. Si les messages sont de grande valeur (transactions financières, par exemple), il vaut mieux ne pas chercher de solutions, et simplement se contenter de messages transmis directement, ne subissant pas de traitements qui vont invalider SPF ou DKIM.

C'est d'autant plus vrai que l'écosystème du courrier électronique est très complexe. On trouve un zillion de logiciels différents, plus ou moins bien écrits. Par exemple, des gens utilisent encore Qmail, qui n'a plus eu une seule mise à jour depuis 1998. Certaines des mesures ou contre-mesures utilisées pour la sécurité du courrier sont parfaitement légales, mais vont casser tel ou tel logiciel qui est utilisé à certains endroits.

Assez d'avertissements, les solutions. D'abord, du côté de l'expéditeur. Celui-ci (ou son premier MTA) peut faire des efforts pour améliorer l'accord entre les identificateurs. Un logiciel sur info.example qui envoie du courrier pour le compte de bob@univ.example peut ainsi décider d'utiliser un en-tête From: qui ne posera pas de problème, celui du vrai envoyeur, et de mettre l'adresse de Bob dans un Reply-To:. Comme la plupart des solutions présentées dans cette section 4, elle est imparfaite (le destinataire peut se demander qui est cet envoyeur qu'il ne connait pas). Le RFC fournit de nombreux autres exemples de désaccord entre identités, qui peuvent être réparés en changeant un peu le processus d'envoi du message. Comme le disait ma grand-mère, « il y a toujours une solution, pour peu que chacun y mette du sien ».

Les envoyeurs peuvent aussi limiter le risque de modifications invalidantes, en ne signant pas trop d'en-têtes avec DKIM, ou en envoyant des messages parfaitement formés (pour éviter aux serveurs ultérieurs la tentation de les « réparer »).

Les receveurs peuvent aussi agir mais leurs possibilités sont plus limitées, note le RFC.

Entre les expéditeurs et les receveurs, il y a tous les intermédiaires qui prennent un message et le ré-expédient. Ce sont souvent eux qui causent le problème, et ils sont donc souvent en position de le réparer. Par exemple, ils peuvent changer le From: du message pour mettre le leur, ce qui permettrait à peu près n'importe quelle modification, et serait plus « franc » (puisque le message n'est plus tout à fait l'original, autant changer l'auteur...) Évidemment, dans ce cas, assez violent, il faut au minimum garder l'information sur l'émetteur originel, avec l'en-tête Original-From: (RFC 5703). Le problème est que le récepteur humain sera sans doute déconcerté par cet expéditeur (d'autant plus qu'Original-From: est peu ou pas affiché).

Comme les modifications invalident les signatures, les ré-expéditeurs pourraient les éviter, par exemple en ajoutant des en-têtes au lieu de modifier les existants, lorsqu'ils veulent ajouter un contenu (du genre « ceci est un spam »). Il serait peut-être préférable, dans certains cas, de rejeter les messages plutôt que de les modifier, ce qui cassera la vérification de signatures plus loin.

Et, en parlant des ré-expéditeurs, les listes de diffusion, pas vraiment prévues par DKIM, que faire pour elles ? Le RFC 6377 a déjà traité leur cas. Une technique courante est de modifier le champ From: pour mettre l'adresse de la liste, réduisant l'auteur original à un commentaire dans cet en-tête (avis personnel : je déteste ça). Comme cela rend difficile de répondre en privé au vrai auteur d'un message, l'ajout d'un Reply-To: peut aider. Une autre solution est d'emballer le message original dans une partie MIME message/rfc822. Cette partie resterait intact et le message emballant aurait comme expéditeur la liste. Mais peu de MUA savent afficher proprement ce genre de messages (spécialement dans le monde des mobiles).

Encore plus fasciste, le gestionnaire de liste pourrait interdire l'abonnement des gens utilisant une adresse où il y a une politique DMARC autre que p=none. (Le RFC oublie de parler du cas où une politique p=reject n'existait pas au moment de l'abonnement mais a été rajoutée après.)

Enfin, il existe aussi des solutions qui sont encore en cours de discussion à l'IETF, et dont le RFC décourage l'usage dans un environnement de production. Ce sont entre autres des extensions au modèle du RFC 8601 pour créer une chaîne d'authentification où chaque acteur important signerait le message en route. Ou, plus radical, des mécanismes stockant l'état initial d'un message avant transformation, pour pouvoir retrouver cet état original et vérifier la signature.

Bref, le problème n'est pas résolu...


Téléchargez le RFC 7960


L'article seul

RFC 7958: DNSSEC Trust Anchor Publication for the Root Zone

Date de publication du RFC : Août 2016
Auteur(s) du RFC : J. Abley (Dyn), J. Schlyter (Kirei), G. Bailey (Microsoft)
Pour information
Première rédaction de cet article le 1 septembre 2016


Le mécanisme d'authentification des informations DNS nommé DNSSEC repose sur la même structure arborescente que le DNS : une zone publie un lien sécurisé vers les clés de ses sous-zones. Un résolveur DNS validant n'a donc besoin, dans la plupart des cas, que d'une seule clé publique, celle de la racine. Elle lui servira à vérifier les clés des TLD, qui serviront à valider les clés des domaines de deuxième niveau et ainsi de suite. Reste donc à configurer la clé de la racine dans le résolveur : c'est évidemment crucial, puisque toute la sécurité du système en dépend. Si un résolveur est configuré avec une clé fausse pour la racine, toute la validation DNSSEC est menacée. Comment est-ce que l'ICANN, qui gère la clé principale de la racine, publie cette clé cruciale ? Six ans après la signature de la racine du DNS, c'est enfin documenté, dans ce RFC.

Cela donne une idée de la vitesse des processus ICANN, organisation qui produit beaucoup de papier. Notez que ce nouveau RFC documente l'existant, déjà mis en œuvre, et ne prétend pas décrire la meilleure méthode. Notez aussi que ce format et cette méthode de distribution pourraient changer à l'avenir.

Si vous voulez réviser DNSSEC d'abord, outre les RFC de base sur ce système (RFC 4033, RFC 4034, RFC 4035...), notez surtout le RFC 6781, qui décrit les questions opérationnelles liées au bon fonctionnement de DNSSEC.

Les clés publiques configurées dans les résolveurs qui valident avec DNSSEC, sont appelées « points de départ de la confiance » trust anchors. Un point de départ de la confiance est une clé dont l'authenticité est admise, et non pas dérivée d'une autre clé, via une chaîne de signatures. Il en faut au moins un, celui de la racine, bien que certains résolveurs en ajoutent parfois deux ou trois pour des zones qu'ils veulent vérifier indépendamment. Lorsque le résolveur recevra une réponse de la racine, signée, il l'authentifiera avec la clé publique de la racine (le point de départ de la confiance). S'il veut vérifier une réponse d'un TLD, il l'authentifiera avec la clé publique du TLD, elle-même signée (et donc authentifiée) par la clé de la racine. Et ainsi de suite même pour les zones les plus profondes.

(Notez qu'il existe deux clés pour la plupart des zones, la KSK - Key Signing Key, et la ZSK - Zone Signing Key, mais on ne s'intéresse ici qu'aux KSK, c'est elles qui sont signées par la zone parente, et configurées comme points de départ de la confiance.)

La gestion de la clé de la racine par l'ICANN est décrite dans leur DNSSEC Practice Statement.

Le RFC rappelle aussi qu'il y a d'autres possibilités d'installation d'un point de départ de la confiance. Par exemple, si un tel point a été configuré une fois, ses remplacements éventuels peuvent être faits via le RFC 5011.

La section 2 du RFC décrit le format des clés publiées par l'IANA. Les trois formats, en fait :

Voici un exemple du fichier XML (à ne pas prendre comme s'il faisait autorité, évidemment) :


<TrustAnchor id="AD42165F-3B1A-4778-8F42-D34A1D41FD93" source="http://data.iana.org/root-anchors/root-anchors.xml">
 <Zone>.</Zone>
 <KeyDigest id="Kjqmt7v" validFrom="2010-07-15T00:00:00+00:00">
  <KeyTag>19036</KeyTag>
  <Algorithm>8</Algorithm>
  <DigestType>2</DigestType>
  <Digest>
  49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
  </Digest>
 </KeyDigest>
</TrustAnchor>

    

L'élément <KeyTag> indique l'identifiant de la clé, actuellement 19036, comme on peut le voir avec dig :

      
% dig +multi +nodnssec DNSKEY .
...
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
.			147724 IN DNSKEY 257 3 8 (
				AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQ
				bSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh
                                ...
				) ; KSK; alg = RSASHA256; key id = 19036
...

    

L'attribut id de l'élément <KeyDigest> sert à identifier un condensat particulier, et est utilisé pour nommer les autres fichiers. Par exemple, le certificat PKIX va se trouver dans le fichier Kjqmt7v.crt.

Pour produire un enregistrement DS à partir de ce fichier XML, il suffit de mettre <KeyTag>, <Algorithm>, <DigestType> et <Digest> bout à bout. Par exemple, avec le fichier XML ci-dessus, cela donnerait :

    
.  IN   DS   19036  8   2  49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5

(Des résolveurs comme Unbound acceptent ce format, pour le point de confiance de départ.)

Quant aux certificats, ils sont encodés en DER et signés par l'ICANN et leur champ SubjectPublicKeyInfo est la clé publique DNSSEC. Voici ce qu'en voit OpenSSL :

% openssl x509 -text -inform DER -in Kjqmt7v.crt 
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 7 (0x7)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: O=ICANN, CN=ICANN DNSSEC CA/emailAddress=dnssec@icann.org
        Validity
            Not Before: Jun 11 18:43:20 2014 GMT
            Not After : Jun 10 18:43:20 2017 GMT
        Subject: O=ICANN, OU=IANA, CN=Root Zone KSK 2010-06-16T21:19:24+00:00/1.3.6.1.4.1.1000.53=. IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
	    ...
            X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier: 
                keyid:8F:B2:42:69:C3:9D:E4:3C:FA:13:B9:FF:F2:C0:A4:EF:D8:0F:E8:22
            X509v3 Subject Key Identifier: 
                41:1A:92:FA:1B:56:76:1E:62:2B:71:CD:1A:FD:BB:43:99:5F:09:C9
    Signature Algorithm: sha256WithRSAEncryption
    ...
    

Comment récupérer le fichier XML de manière à être sûr de son authenticité ? C'est ce que spécifie la section 3 du RFC : on utilise HTTPS. L'URL est https://data.iana.org/root-anchors/root-anchors.xml.

Une autre solution (section 4) est de le récupérer en HTTP et de le vérifier avec une des signatures fournies : l'une est en CMS (RFC 5652) - son URL est https://data.iana.org/root-anchors/root-anchors.p7s, l'autre est en PGP (RFC 9580) - son URL est https://data.iana.org/root-anchors/root-anchors.asc. Cette signature PGP devrait être abandonnée à l'avenir.

Pour les amateurs d'histoire, l'annexe A rappelle que la clé actuelle, la 19036, a été générée au cours d'une cérémonie à Culpeper, le 16 juin 2010. Elle a été publiée dans le DNS pour la première fois le 15 juillet 2010.

Sinon, l'ISOC a écrit un bon article sur ce RFC, moins technique.


Téléchargez le RFC 7958


L'article seul

RFC 7955: Management Guidelines for the Locator/ID Separation Protocol (LISP) Endpoint Identifier (EID) Block

Date de publication du RFC : Septembre 2016
Auteur(s) du RFC : L. Iannone (Telecom ParisTech), R. Jorgensen (Bredbandsfylket Troms), D. Conrad (Virtualized, LLC), G. Huston (APNIC)
Intérêt historique uniquement
Réalisé dans le cadre du groupe de travail IETF lisp
Première rédaction de cet article le 23 septembre 2016


Le RFC 7954 réservait un préfixe IP, 2001:5::/32, pour les identificateurs du protocole expérimental LISP. Ce RFC 7955 décrit les mécanismes d'allocation à l'intérieur de ce préfixe. Ils sont simples et légers : un peu de documentation et on a son sous-préfixe.

Le RIPE-NCC assure la gestion de ce préfixe. La politique d'enregistrement est simple (sections 4 et 9 de notre RFC) :

  • Ce préfixe est expérimental et les allocations sont donc temporaires. N'espérez pas garder éternellement votre joli préfixe sous 2001:5::/32. Si l'expérience se termine et que le 2001:5::/32 cesse d'être utilisé, tous ses sous-préfixes disparaitront aussi.
  • Les allocations doivent être renouvelées tous les ans, afin de s'assurer que le titulaire est toujours actif dans le banc de test LISP. (C'est bien un renouvellement, pas une nouvelle allocation, on conserve le même préfixe.)
  • Les préfixes abandonnés ne sont pas réutilisés, autant que possible, ou alors en attendant au moins une semaine.
  • Une organisation peut avoir plusieurs sous-préfixes.
  • Premier arrivé, premier servi.

Quelles sont les règles que suivra le registre de 2001:5::/32 (section 5) ?

  • Suivre les règles habituelles des registres d'adresses IP : collecter et archiver l'information envoyée par le titulaire, et la rendre accessible (par exemple via whois).
  • Gérer les noms de domaine dans ip6.arpa correspondants au préfixe géré.
  • Allouer un sous-préfixe à quiconque le demande, sous seule condition qu'il fournisse les informations demandées dans la section suivante.

La section 6, en effet, contient les informations demandées aux titulaires (ce sont à peu près les mêmes que pour obtenir un numéro d'organisation privé). On y trouve les grands classiques, nom de l'organisation qui demande, adresse, informations de contact, taille du préfixe demandé, raisons de la demande...

Comme indiqué plus haut, c'est le RIPE-NCC qui gérera le préfixe. Normalement, tout est déjà en place mais pas encore annoncé (cela sera mis en ligne après la publication du RFC).


Téléchargez le RFC 7955


L'article seul

RFC 7954: Locator/ID Separation Protocol (LISP) Endpoint Identifier (EID) Block

Date de publication du RFC : Septembre 2016
Auteur(s) du RFC : L. Iannone (Telecom ParisTech), D. Lewis (Cisco), D. Meyer (Brocade), V. Fuller
Intérêt historique uniquement
Réalisé dans le cadre du groupe de travail IETF lisp
Première rédaction de cet article le 23 septembre 2016


Le protocole expérimental LISP a besoin d'identificateurs pour les machines qui participent à l'expérimentation. Comme les identificateurs LISP sont pris dans le même espace de nommage que les adresses IP, il était préférable d'avoir un préfixe IP spécifique. C'est désormais chose faite, avec ce RFC, qui demande et obtient le préfixe 2001:5::/32. Si vous voyez quelque chose qui ressemble à une adresse IP et qui emploie ce préfixe, c'est qu'il s'agit d'un identificateur LISP.

En effet, LISP (RFC 6830) repose sur le principe de la séparation de l'identificateur et du localisateur. Les identificateurs sont stables et servent à... identifier une machine, les localisateurs sont liés aux connexions qu'on a au réseau et servent au routage. Les deux ont la forme physique d'une adresse IP, et on ne peut donc pas les distinguer par leur syntaxe. Les identificateurs sont formellement nommés EID (Endpoint IDentifier) et c'est pour eux que 2001:5::/32 a été réservé (section 1 du RFC).

La section 3 explique les raisons de cette réservation :

  • Identifier facilement le fait qu'une destination est accessible via LISP, et qu'on peut donc chercher son localisateur dans les tables de correspondance (RFC 9301). Actuellement, on ne peut pas savoir à l'avance, il faut demander au système de correspondance, peut-être pour rien.
  • Ainsi, si un routeur gère à la fois des destinations LISP et non-LISP (par exemple pour faire de l'ingénierie de trafic), cela lui permettra de ne pas pénaliser le trafic non-LISP, qui pourra être transmis immédiatement.
  • Si on souhaite traiter différemment le trafic LISP et le trafic non-LISP, cela dispensera d'utiliser du DPI pour le reconnaitre.
  • L'avantage précédent s'applique aussi au cas où on veut filtrer/bloquer l'un des deux trafics.
  • Cela facilitera la numérotation des réseaux qui sont mixtes : le ou les préfixes alloués pour l'IP traditionnel ne seront pas affectés, le réseau qui voudra faire du LISP prendra ses identificateurs dans 2001:5::/32 au lieu de devoir découper une partie de son espace d'adressage.
  • Conséquence : moins de fragmentation de l'espace d'adressage, et moins de routes dans la DFZ.

D'où cette réservation d'un préfixe dédié, en suivant les règles du RFC 3692.

Les réseaux qui utiliseront ce préfixe ne doivent évidemment pas annoncer de routes dans la DFZ (section 4 du RFC), ce préfixe ne servant qu'à des identificateurs et pas aux localisateurs. Pour la communication entre un réseau LISP numéroté avec le nouveau préfixe, et un réseau IP traditionnel, il faut utiliser les techniques d'interconnexion des RFC 6832 et RFC 7215. Le préfixe complet pourra être annoncé (comme un tout, ou comme des sous-préfixes très généraux, pour ne pas surcharger la table de routage) par des routeurs d'interconnexion (section 8 du RFC). Pour les routeurs non-LISP, ce sera un préfixe comme un autre, et il n'y a aucune raison de lui appliquer un traitement particulier.

Notre RFC exige également que ce nouveau préfixe 2001:5::/32 ne soit utilisé que par configuration explicite et ne soit donc pas mis en dur dans le logiciel des routeurs, d'abord parce que LISP pourra en utiliser d'autres dans le futur, ensuite parce que des réseaux feront quand même du LISP avec leurs propres adresses.

Pourquoi un préfixe de 32 bits ? Pourquoi pas plus spécifique ou moins spécifique (cela a été une grosse discussion dans le groupe de travail) ? La section 5 donne les raisons de ce choix :

  • Cela fait assez de préfixes pour le réseau de test LISP actuel (qui a environ 250 sous-préfixes /48), et pour ce qu'on peut envisager dans les prochaines années.
  • C'est cohérent avec des expériences comme celle du RFC 3056.

Le préfixe 2001:5::/32 est alloué pour trois ans, ce qui est suffisant pour l'expérimentation (sections 6 et 7). À la fin de celle-ci, le préfixe sera rendu ou bien transformé en allocation permanente (qu'il faudra justifier et documenter, cf. RFC 2860, section 4.3). L'allocation, faite en octobre 2015, est notée dans le registre IANA.

L'allocation des préfixes à l'intérieur de 2001:5::/32 est décrite dans le RFC 7955.


Téléchargez le RFC 7954


L'article seul

RFC 7950: The YANG 1.1 Data Modeling Language

Date de publication du RFC : Août 2016
Auteur(s) du RFC : M. Bjorklund (Tail-f Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF netmod
Première rédaction de cet article le 10 octobre 2016


Le protocole standard Netconf (normalisé dans le RFC 6241) permet de configurer un équipement réseau (par exemple un commutateur) à distance. Netconf fonctionne par des RPC dont les paramètres sont des actions à faire effectuer par l'équipement configuré, ou bien les nouvelles valeurs que peut prendre telle ou telle des variables de configuration de cet équipement. Mais comment savoir quelles actions sont possibles, quelles variables existent, et quelles valeurs elles peuvent prendre ? Jusqu'à présent, cela pouvait se spécifier uniquement dans une documentation en langue naturelle fournie avec l'équipement. Désormais, il est possible de spécifier ces informations dans un langage formel, YANG. La première version de YANG était normalisée dans RFC 6020, ce nouveau RFC normalise la nouvelle version, la 1.1, qui a peu de changements, mais certains cassent la compatibilité ascendante.

Ce RFC 7950 est très détaillé, plus de deux cents pages. Et je n'ai pas personnellement d'expérience pratique avec YANG. Donc, je ne donne ici qu'un très bref résumé. Un tel survol se trouve également dans la section 4 du RFC : YANG modélise les données (configuration et état) qui seront utilisées par Netconf. Ces données sont représentées sous forme arborescente. YANG est modulaire (section 5.1 du RFC), un module YANG pouvant se référer à d'autres modules. YANG définit un ensemble de types pour décrire les données (section 9 et RFC 6991). Il permet également d'indiquer les contraintes que doivent respecter les données. YANG, langage de haut niveau, ne décrit pas l'encodage utilisé sur le câble.

Notez que YANG peut être utilisé avec d'autres protocoles que Netconf, comme RESTCONF (décrit dans le RFC 8040).

YANG a donc bien des points communs avec le SMI des RFC 2578 et RFC 2579. Avant Netconf, beaucoup de gens pensaient que toute la gestion des équipements réseau se ferait en SNMP, en s'appuyant sur ce modèle SMI. Si, pour la lecture des variables, SNMP s'est largement imposé, force est de constater que, pour l'écriture de variables et pour les actions, SNMP reste très peu utilisé, au profit de toute une galaxie de mécanismes privés (Web, REST, SSH + CLI, etc), galaxie que Netconf vise à remplacer. Une MIB du SMI peut donc être traduite en YANG, l'inverse n'étant pas vrai (YANG étant plus riche).

La syntaxe de YANG utilise des groupes emboîtés, délimités par des accolades. Mais une syntaxe équivalente, en XML, existe, sous le nom de Yin. Tout module YANG peut être traduit en Yin sans perte et réciproquement (voir la section 13 pour plus de détails sur Yin).

Donc, un engin donné, routeur ou autre équipement qu'on veut gérer, est décrit par des modules YANG. Lorsqu'un serveur Netconf à bord dudit engin met en œuvre un module YANG, cela veut dire qu'il permet de modifier, via Netconf, les variables décrites dans le module (le serveur typique met en œuvre plusieurs modules). Voici le début d'un module possible :

     // Only an example, not a real module. 
     module acme-system {
         namespace "http://acme.example.com/system";
         prefix "acme";

         organization "ACME Inc.";
         contact "joe@acme.example";
         description
             "The module for entities implementing the ACME system.";

         revision 2010-08-05 {
             description "Initial revision.";
         }
...

On l'a dit, YANG est arborescent. Les feuilles de l'arbre (section 4.2.2.1 du RFC) contiennent une valeur particulière, par exemple, ici, le nom de l'engin géré :

       leaf host-name {
           type string;
           description "Hostname for this system";
       }

Ici, leaf est un mot-clé de YANG qui indique une feuille de l'arbre (plus de nœuds en dessous), host-name est le nom que l'auteur du module a donné à une variable, de type « chaîne de caractères ». Lorsqu'un serveur Netconf enverra cette information à un client (ou réciproquement), elle sera encodée en XML ainsi (Netconf utilise XML pour l'encodage des messages mais d'autres encodages sont possibles, cf. RFC 7951) :


       <host-name>my-router.example.com</host-name>

Donc, pour résumer, YANG modélise ce qu'on peut lire ou modifier, Netconf permet de le lire ou de le modifier effectivement.

Par contre, si un nœud de l'arbre YANG n'est pas une feuille, il est désigné par le mot-clé container. Par exemple, il y a ici deux containers emboîtés et une feuille :

     container system {
         container login {
             leaf message {
                 type string;
                 description
                     "Message given at start of login session";
             }
         }
     }

Lorsque Netconf utilise cette donnée, cela ressemblera, sur le câble, à ceci :


     <system>
       <login>
         <message>Good morning</message>
       </login>
     </system>

YANG dispose d'un certain nombre de types pour représenter les données (section 4.2.4 et RFC 6991), mais on peut aussi créer ses types (sections 4.2.5 et 7.3) par exemple ainsi :

     typedef percent {
         type uint8 {
             range "0 .. 100";
         }
         description "Percentage";
     }

     leaf completed {
         type percent;
     }

On a ajouté un intervalle de validité au type prédéfini uint8. Autre exemple, en indiquant une valeur par défaut, et en dérivant d'un type défini dans le module inet :

     typedef listen-ipv4-address {
         type inet:ipv4-address;
         default "0.0.0.0";
     }

YANG a bien d'autres possibilités, décrites en détail dans les sections suivantes. Par exemple, dans un monde idéal, tous les engins mettant en œuvre un module YANG donné géreraient la totalité des variables du module. Mais, comme ce n'est pas forcément le cas, YANG permet des déviations (sections 5.6.3 et 7.20.3). Prenons l'exemple du RFC, un routeur BGP qui suit un module YANG BGP. Le module ne donne pas de limite au nombre de pairs BGP mais un routeur bas de gamme pourrait avoir une limite, disons à 16 pairs. Un client Netconf qui tenterait de configurer un dix-septième pair recevrait donc une erreur. Le mot-clé YANG deviation permettrait audit client de savoir à l'avance en quoi ce routeur particulier dévie du modèle BGP général. Le client Netconf n'aurait donc pas à essayer pour voir, il pourrait savoir à l'avance que l'opération de configuration du dix-septième pair ne marchera pas.

La syntaxe formelle de YANG est décrite en section 6. Elle ressemble à celle de langages de programmation comme C ou à celle de SMIng du RFC 3780 (RFC qui n'a pas eu de succès). Cette syntaxe favorise la lisibilité par des humains, le cahier des charges étant de privilégier les lecteurs, pas les auteurs de modules, ni les programmeurs d'outils YANG. À noter que, comme dans toutes les normes modernes, YANG n'est pas limité à l'ASCII et peut utiliser tout Unicode.

Bien que YANG n'utilise pas XML, il réutilise un langage de ce monde, XPath (sections 6.4 et 7.5.3). XPath sert à indiquer les dépendances entre nœuds de l'arbre.

YANG permet en effet de définir des contraintes (section 8) que doivent respecter les variables, avec la directive must. Par exemple :

         must "ifType != 'ethernet' or " +
              "(ifType = 'ethernet' and ifMTU = 1500)" {
             error-message "An ethernet MTU must be 1500";
         }

Voici un exemple de requête Netconf complète, correspondant à une variable YANG. Soit un équipement muni d'un serveur SSH et d'un serveur Netconf pour sa configuration. Disons que le serveur Netconf met en œuvre la variable YANG port, définie ainsi :

     leaf port {
         type inet:port-number;
         default 22;
         description "The port which the SSH server listens to"
     }

La requête Netconf <edit-config> (RFC 6241, section 7.2) qui configure le serveur SSH pour écouter sur le port 2022 serait :


     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="http://example.com/schema/config">
             <services>
               <ssh>
                 <port>2022</port>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

Le choix de YANG comme langage standard pour la description des capacités d'un serveur Netconf ne s'était pas fait sans mal. Plusieurs concurrents avaient été envisagés notamment Relax NG, un choix logique puisque Netconf utilise XML. Un langage de description de schémas comme Relax NG semblait donc un choix raisonnable. Parmi les discussions à ce sujet, citons par exemple le débat qui avait eu lieu sur la liste du secteur Applications de l'IETF. Les raisons du choix de YANG, telles que vues par les concepteurs de YANG, sont décrites sur le site officiel du projet mais je trouve cette comparaison très unilatérale.

Un bon tutoriel Netconf, couvrant également YANG, est disponible en http://www.aims-conference.org/issnsm-2008/06-netconf-yang.pdf.

Quelles sont les mises en œuvre de YANG ? Il en existe une liste sur le site officiel. Voyons par exemple l'outil pyang, qui sert à valider des schémas YANG (y compris de la nouvelle version 1.1 décrite dans ce RFC) et à les convertir dans d'autres formats. Il ne semble pas trop maintenu mais, bon, il marche. Il peut produire du XSD et du RelaxNG - enfin du DSDL mais c'est presque pareil. Voici un exemple de test d'un schéma invalide (leaf a été tapé laf) :


% pyang test.yang
test.yang:11: error: unexpected keyword "laf"

Et, si on corrige :

% pyang test.yang
% 

Maintenant, convertissons en Yin :


% cat test.yang
 module acme-foo {
         namespace "http://acme.example.com/foo";
         prefix "acfoo";

         list interface {
             key "name";
             leaf name {
                 type string;
             }

             leaf mtu {
                 type uint32;
                 description "The MTU of the interface.";
             }
         }
     }

% pyang -fyin test.yang
<?xml version="1.0" encoding="UTF-8"?>
<module name="acme-foo"
        xmlns="urn:ietf:params:xml:ns:yang:yin:1"
        xmlns:acfoo="http://acme.example.com/foo">
  <namespace uri="http://acme.example.com/foo"/>
  <prefix value="acfoo"/>
  <list name="interface">
    <key value="name"/>
    <leaf name="name">
      <type name="string"/>
    </leaf>
    <leaf name="mtu">
      <type name="uint32"/>
      <description>
        <text>The MTU of the interface.</text>
      </description>
    </leaf>
  </list>
</module>

Et voici une conversion du même code en DSL :


% pyang -fdsdl test.yang
<?xml version='1.0' encoding='UTF-8'?>
<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
	 ns="http://acme.example.com/foo"
	 xmlns="http://relaxng.org/ns/structure/1.0"
	 xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
	 xmlns:acfoo="http://acme.example.com/foo"
	 xmlns:dc="http://purl.org/dc/terms"
	 xmlns:dsrl="http://purl.oclc.org/dsdl/dsrl"
	 xmlns:nm="urn:ietf:params:xml:ns:netmod:dsdl-attrib:1"
	 xmlns:sch="http://purl.oclc.org/dsdl/schematron">
  <dc:source>YANG module 'acme-foo' (automatic translation)</dc:source>
<start>
   <zeroOrMore>
      <element name="interface" nm:key="name">
	  <element name="name">
	     <data type="string"/>
	  </element>
	  <optional>
	     <element name="mtu"><a:documentation>The MTU of the interface.</a:documentation>
		<data type="unsignedInt"/>
	     </element>
	  </optional>
       </element>
   </zeroOrMore>
</start>
</grammar>

Outre pyang, il y a bien entendu même un mode Emacs, yang-mode.

Le site officiel du projet, http://www.yang-central.org/, contient beaucoup d'autre information sur YANG.

Notez que l'ancien YANG, 1.0, décrit dans le RFC 6020, n'est pas abandonné. L'ancien RFC reste d'actualité pour décrire la version 1.0, qui restera en usage un certain temps. Les principaux changements apportés par la version 1.1 de YANG sont décrits dans la section 1.1 du RFC. La liste est très longue, mais la plupart ne sont que des points de détail. Parmi les changements qui peuvent rendre illégaux des modèles YANG qui étaient légaux avant, il y a par exemple le changement d'interprétation des échappements dans les chaînes de caractères, ou bien le fait qu'une chaîne de caractères qui n'est pas encadrée par des apostrophes ou des guillemets n'a plus le droit de contenir des apostrophes ou guillemets (section 6.1.3). De même, les clés (identificateurs uniques) ne peuvent plus être conditionnelles (instructions when ou if-feature) ce qui est logique, mais rend également invalide certains anciens modèles YANG.


Téléchargez le RFC 7950


L'article seul

RFC 7948: Internet Exchange BGP Route Server Operations

Date de publication du RFC : Septembre 2016
Auteur(s) du RFC : N. Hilliard (INEX), E. Jasinska (Netflix), R. Raszuk (Mirantis), N. Bakker (Akamai Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 9 septembre 2016


Les points d'échange Internet sont un des maillons essentiels du bon fonctionnement de l'Internet, permettant des connexions faciles et relativement bon marché entre opérateurs. Une fois physiquement connecté au point d'échange, l'opérateur Internet doit encore établir une connexion BGP (RFC 4271) avec ses pairs. Si ceux-ci sont nombreux, établir N connexions bilatérales représente un coût administratif important. Il est souvent préférable d'établir une seule connexion multilatérale, par l'intermédiaire d'un serveur de routes (route server). Celui-ci récolte les annonces BGP de tous ses pairs et les redistribue. Ainsi, il suffit à l'opérateur d'une seule connexion, avec le serveur de routes. Ce nouveau RFC documente les questions opérationnelles liées aux serveurs de routes.

Le principe et le fonctionnement d'un serveur de routes sont expliqués dans le RFC 7947, produit par un autre groupe de travail IETF. Ce RFC 7948 se consacre aux détails opérationnels. Un serveur de routes est l'équivalent, pour le BGP externe (eBGP) de ce qu'est un « réflecteur de routes » (route reflector, RFC 4456) pour le BGP interne (iBGP). Le serveur de routes, lorsqu'il existe, est un composant crucial du point d'échange. Par exemple, s'il tombe en panne, les sessions BGP sont coupées, les annonces retirées et, même si les commutateurs et le réseau du point d'échange continuent à fonctionner, plus aucun trafic ne passe (à part si des sessions BGP bilatérales existent également). D'où l'importance d'une bonne gestion de ce composant.

Les sections 2 et 3 de notre RFC rappelent la différence entre sessions BGP bilatérales et multilatérales à un point d'échange. Si on ne fait que des sessions bilatérales (pas de serveur de routes), avec seulement quatre routeurs BGP sur le point d'échange, il faudra six sessions BGP pour une connectivité complète. Avec dix routeurs, il en faudrait quarante-cinq ! Établir, superviser et maintenir toutes ces sessions représente du travail. Les sessions multilatérales, via un serveur de routes, sont une bien meilleure solution. Avec dix routeurs au point d'échange, il n'y a plus besoin que de dix sessions BGP, chacun des dix routeurs ne faisant que BGP qu'avec le serveur de routes.

Le serveur de routes doit juste veiller à ne pas toucher à l'attribut BGP NEXT_HOP (RFC 4271, section 5.1.3), qui ne doit pas indiquer le serveur de routes, mais le routeur qui a annoncé la route (le serveur de routes n'est pas un routeur, et ne fait pas de transmission du trafic IP). Pour le point d'échange typique, il n'y a pas besoin de faire de la résolution récursive (utiliser un protocole de routage pour trouver comment joindre le routeur suivant) du NEXT_HOP : tous les routeurs sont sur le même réseau L2 et sont donc joignables directement. Par exemple, si je regarde le looking glass du France-IX et que lui demande les routes vers 194.0.9.0/24, il me montre :

194.0.9.0/24       via 37.49.236.20 on eth1 [RS1_PAR 2016-08-11 from 37.49.236.250] * (100) [AS2484i]
                   via 37.49.236.21 on eth1 [RS1_PAR 2016-08-11 from 37.49.236.250] (100) [AS2486i]
...

(L'AFNIC est connectée sur deux points de présence de ce point d'échange, d'où les deux routeurs.) Les NEXT_HOP sont les adresses des routeurs dans le point d'échange, 37.49.236.0/23.

La section 4, le gros morceau de notre RFC, décrit ensuite divers points que le serveur de routes doit garder en tête, pour faire un bon travail.

D'abord, le cas où on n'envoie pas exactement les mêmes informations à tous les clients. Sauf si le client BGP coopère, cela implique que le serveur garde une base des routes par groupe de clients, un groupe étant composé de tous les clients pour qui on applique la même politique de filtrage. Attention, cela consomme pas mal de mémoire (autant de base que de groupes) et de processeur (il faut faire tourner les algorithmes de sélection BGP pour tous les groupes) mais heureusement, en pratique, on utilise rarement ces politiques différentes. Traiter tous les clients de la même façon permet de garder une consommation de ressources raisonnable.

Qu'en est-il du risque de fuite de préfixes ? Si un routeur connecté au serveur de routes fuit et envoie, par exemple, la totalité de la DFZ au serveur de routes, celui-ci va-t-il transmettre tous ces préfixes à ses infortunés clients ? Cela serait très ennuyeux car tout le trafic partirait alors vers le routeur fautif, qui ne serait peut-être pas capable de le gérer. Il est donc très recommandé que le serveur de routes prenne des précautions contre les fuites. Au minimum, imposer un nombre maximal de préfixes à chaque client, et, idéalement, filtrer les préfixes autorisés pour chaque client. C'est moins grossier que la simple limite quantitative, mais c'est aussi plus dur à maintenir (on ne peut pas espérer que tous les clients tiennent à jour leurs préfixes dans les IRR...). Il est certainement préférable que les administrateurs des clients et du serveur de routes regardent le journal de leur routeur pour repérer les différences entre ce qui est théoriquement annoncé et ce qu'il l'est réellement.

Question fiabilité, notre RFC recommande que le serveur de routes soit redondant : s'il n'est composé que d'une seule machine, et qu'elle plante, le point d'échange ne servira plus. Il faut donc au moins deux machines, et prendre soin qu'elles soient configurées de manière à annoncer les mêmes routes. (C'est trivial si les machines sont identiques, il suffit qu'elles aient la même configuration, cela l'est moins si, pour augmenter la redondance, on choisit des machines ayant des logiciels différents.)

Autre précaution à prendre, côté client, ne pas vérifier que le chemin d'AS est cohérent. Par exemple, le serveur de routes ne va pas mettre son propre AS tout à gauche du chemin d'AS (RFC 7947, section 2.2.2) et le client ne doit donc pas vérifier que son pair, le serveur de routes, a un chemin d'AS incluant l'AS du pair BGP.

Comment contrôler l'exportation des routes vers certains clients ? La section 4.6 liste plusieurs méthodes :

  • Demander aux clients d'étiqueter les routes avec une communauté ordinaire (RFC 1997) ou bien une communauté étendue (RFC 4360). Attention, la taille limitée des valeurs des communautés ne permet pas d'y mettre deux numéros d'AS si ceux-ci sont sur quatre octets (RFC 4893). Comme exemple, regardez la politique des communautés BGP au France-IX.
  • Utiliser les politiques de distribution exprimées en RPSL (RFC 2622) dans les IRR.
  • Utiliser un IRR local au point d'échange, avec son interface spécifique pour y enregistrer des politiques. Cette posibilité est mentionnée par le RFC, mais quelqu'un connait un point d'échange qui fonctionne comme cela ? (Peut-être VIX et AMS-IX, à vérifier.)

On a vu que la grande majorité des points d'échange travaillaient au niveau 2. Normalement, toute machine connectée au réseau du point d'échange peut donc joindre n'importe quelle autre. Mais, en pratique, on a déjà vu des bogues dans un commutateur qui menaient à des communications non transitives. Par exemple, les routeurs A et B peuvent tous les deux joindre le serveur de routes mais ne peuvent pas se joindre mutuellement. Dans ce cas, A reçoit bien les routes de B (et réciproquement) mais, lorsqu'il essaie de transmettre des paquets à B, ceux-ci finissent dans un trou noir. Ce problème est spécifique aux serveurs de route : lorsqu'on a une connexion bilatérale, les paquets de contrôle (ceux envoyés en BGP) suivent en général le même chemin que ceux de données (les paquets IP transmis) et partagent donc le même sort, bon ou mauvais.

La solution à ce problème passe peut-être par des solutions comme BFD (RFC 5881), pour tester la connectivité entre les deux routeurs. Mais BFD nécessite une configuration bilatérale entre les deux routeurs et il n'existe actuellement aucun protocole pour faire cette configuration automatiquement. On retombe donc dans les problèmes de configuration manuelle d'un grand nombre de connexions bilatérales. Même si un protocole de configuration automatique existait, il resterait le problème d'informer le serveur de routes. En effet, un échec BFD indiquerait à A qu'il ne peut pas joindre B, et lui ferait marquer les routes vers B comme invalides mais le serveur de routes, n'étant pas au courant, continuerait à n'envoyer à A que la route invalide (un pair BGP ne transmet que la meilleure route vers une destination donnée).

Dernier piège, le détournement de NEXT_HOP. On a vu que le fonctionnement normal d'un serveur de routes est de ne pas se mettre comme « routeur suivant » mais au contraire de relayer aveuglément les NEXT_HOP indiqués en BGP par ses clients. Un client malveillant pourrait annoncer des routes au serveur de routes en indiquant comme « routeur suivant » le routeur d'un concurrent, pour lui faire acheminer son trafic, par exemple ou, pire, pour faire une attaque par déni de service en annonçant des préfixes très populaires avec le concurrent comme routeur suivant. Contrairement au problème précédent, celui-ci n'est pas spécifique aux serveurs de route, il existe aussi avec des sessions BGP bilatérales. Mais il peut faire davantage de dégâts lorsqu'on utilise un serveur de routes, tous les clients croyant l'annonce mensongère. Pour empêcher cela, il faudrait que les serveurs de route vérifient que l'attribut BGP NEXT_HOP corresponde à l'adresse IP du client. (Les clients ne peuvent pas faire ce test, ils doivent croire le serveur de routes, qui annonce des NEXT_HOP qui ne sont pas son adresse IP.)

Et pour finir, une sortie complète du looking glass du route server du France-IX concernant un serveur racine du DNS, M.root-servers.net (et, au passage, attention en anglais à ne pas confondre route server et root server) :

RS1 show route for 202.12.27.33/32 all - View the BGP map

202.12.27.0/24     via 37.49.237.106 on eth1 [RS1 2015-08-21 from 37.49.236.250] * (100) [AS7500i]
	Type: BGP unicast univ
	BGP.origin: IGP
	BGP.as_path: 7500
	BGP.next_hop: 37.49.237.106
	BGP.med: 500
	BGP.local_pref: 100
	BGP.atomic_aggr: 
	BGP.aggregator: 192.50.45.1 AS7500
	BGP.community: (51706,51706) (51706,64601) (51706,64650)

Les pages de présentation de quelques serveurs de route :

Merci à Arnaud Fenioux pour sa relecture et ses ajouts et corrections.


Téléchargez le RFC 7948


L'article seul

RFC 7947: Internet Exchange BGP Route Server

Date de publication du RFC : Septembre 2016
Auteur(s) du RFC : E. Jasinska (BigWave IT), N. Hilliard (INEX), R. Raszuk (Bloomberg LP), N. Bakker (Akamai)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 9 septembre 2016


Ce nouveau RFC spécifie le comportement des serveurs de routes des points d'échange Internet. Un serveur de route collecte avec BGP les routes envoyées par ses pairs et les redistribue. Cela nécessite quelques ajustements du protocole BGP, expliqués ici. Un autre RFC, le RFC 7948, décrit le côté opérationnel.

Un point d'échange Internet connecte un certain nombre d'acteurs (opérateurs, hébergeurs, FAI, etc) à un réseau commun, en général au niveau de la couche 2, et avec Ethernet. Chacun de ces acteurs gère son ou ses routeurs, connecté au·x commutateur·s commun·s. Pour savoir à quel pair envoyer des paquets IP, ces routeurs ont besoin de s'informer mutuellement des préfixes IP qu'ils gèrent. Cela se fait avec le protocole BGP (RFC 4271).

Si le point d'échange rassemble N acteurs, connecter tout le monde nécessiterait N*(N-1)/2 sessions BGP. À chaque fois qu'un participant arriverait, il faudrait qu'il négocie N-1 accords de peering. Et, en fonctionnement quotidien, il devrait superviser N-1 sessions BGP. L'idée de base du serveur de routes est d'introduire un intermédiaire (le serveur de routes, route server), qui reçoit les routes de chacun et les redistribue à tous. Ainsi, il n'y a qu'une seule session BGP à établir, avec le serveur de routes. Il est en général géré par l'opérateur du point d'échange. (Sur la plupart des points d'échange, l'usage de ce serveur de routes n'est pas obligatoire, et il y a donc également des sessions BGP directes entre les participants, pour des raisons variées.)

Le serveur de routes parle BGP avec ses pairs (les routeurs des participants au point d'échange) mais lui-même n'est pas un routeur : il ne transmet pas les paquets IP. Il travaille sur le plan de contrôle, pas sur celui des données.

Un serveur de routes est donc très proche d'un réflecteur (RFC 4456). La différence est que le réflecteur de routes travaille à l'intérieur d'un AS (protocole iBGP), alors que le serveur de routes travaille entre AS différents (protocole eBGP).

Un serveur de routes ressemble aussi à un collecteur de routes, comme ceux du RIS. La différence est que le collecteur ne redistribue pas d'information à ses pairs BGP, il collecte des données, pour analyse, affichage, etc.

La section 2 du RFC forme le cœur de ce document. Elle rassemble les modifications du protocole BGP qui sont nécessaires pour le bon fonctionnement du serveur de routes. D'abord, le serveur ne doit pas modifier sans bonne raison les annonces qu'il reçoit : son but est de distribuer de l'information, pas de la bricoler. Le RFC demande ainsi que les attributs BGP bien connus (comme AS_PATH) ne soient pas modifiés, sauf très bonne raison. Ainsi, l'attribut NEXT_HOP qui indique l'adresse IP du routeur à qui faire suivre les paquets, ne doit pas être changé (ce que demandait la section 5.1.3 du RFC 4271) : le serveur de routes n'est pas un routeur, c'est à l'annonceur original qu'il faut transmettre les paquets. Idem pour AS_PATH cité plus haut : le serveur de routes ne doit pas mettre son propre numéro d'AS dans le chemin. De même, MULTI_EXIT_DISC (qui sert à choisir entre plusieurs routeurs d'un même AS voisin) doit être propagé aux clients du serveur de routes (normalement, il n'est pas propagé aux autres AS). Et, enfin, les communautés BGP (RFC 1997) indiquées dans une annonce ne doivent pas être changées, sauf évidemment si elles sont destinées au serveur de routes lui-même. On trouve des exemples de communautés destinées au serveur de routes dans la documentation du serveur de routes d'AMS-IX ou bien dans celle de celui de Netnod, alors que celle de France-IX se trouve dans un objet RIPE. Il y a aussi des serveurs de routes (comme ceux du France-IX qui étiquettent les annonces apprises avec une communauté indiquant où la route a été apprise (dans quel POP.)

Par défaut, toutes les routes de tous les clients sont distribuées à tous les autres clients. C'est le but d'un serveur de routes. Mais on peut souhaiter parfois une certaine restriction à cette redistribution. Cela peut être mis en œuvre par le serveur de routes (puisque le routeur original de l'annonce parle au serveur de routes, pas au client final). Idéalement, le serveur de routes devrait donc maintenir une base de routes, et un processus de décision BGP, pour chacun de ses clients. Cela permet de coller au mode de fonctionnement normal de BGP. Et cela ne nécessite aucun changement chez les clients. Mais c'est plus coûteux en ressources pour le serveur de routes. (Pour BIRD, voir l'option secondary, qui réduit l’usage mémoire et CPU de manière importante, expliquée dans cet exposé.)

Les autres solutions à ce problème d'un filtrage par client nécessitent des extensions à BGP, comme le Diverse path du RFC 6774 ou comme la future option ADD-PATH.

L'annexe de ce RFC consacrée aux remerciements résume un peu d'histoire des serveurs de routes. La première description de ce système date de 1995, dans le RFC 1863 (depuis reclassé comme « d'intérêt historique seulement », cf. RFC 4223).

Plusieurs mises en œuvre de serveurs de route existent évidemment, conformes à ce RFC. C'est par exemple le cas chez Cisco, BIRD et Quagga (voir le rapport technique sur ces programmes).

Merci à Arnaud Fenioux pour sa relecture et ses ajouts et corrections.


Téléchargez le RFC 7947


L'article seul

RFC 7942: Improving Awareness of Running Code: The Implementation Status Section

Date de publication du RFC : Juillet 2016
Auteur(s) du RFC : Y. Sheffer (Intuit), A. Farrel (Juniper)
Première rédaction de cet article le 23 juillet 2016


L'IETF se vante souvent de ne pas croire au blabla des marketeux, mais uniquement au code qui tourne. Comme le dit fièrement sa devise, « We believe in rough consensus and running code ». Mais, en pratique, les normes produites et publiées en RFC ne contiennent pas toujours la mention d'une mise en œuvre effective de cette norme. Parfois, c'est parce qu'il n'y en a pas (contrairement à une légende tenace, ce n'est nullement une obligation pour la publication d'un RFC). Parfois, c'est parce qu'elle n'est pas mentionnée. Avant la publication d'un RFC, lorsque le document est encore un simple Internet-Draft, la mention de l'existence de programmes mettant en œuvre le protocole ou le format décrit est facultative. Ce RFC propose de formaliser et d'encourager cette mention. Son prédecesseur, le RFC 6982 avait lancé l'idée, comme une expérimentation. Elle a été un grand succès et ce nouveau RFC passe donc au stade supérieur : publier l'état des implémentations d'un draft est désormais une Bonne Pratique (BCP, « Best Common Practice »).

Cela ne concerne que les Internet-Drafts, pas les RFC. En effet, les RFC sont stables (jamais modifiés) alors que les URL pointant vers un programme ne le sont pas : un programme peut être abandonné, plus maintenu, on peut se retrouver avec des 404, etc. Donc, un RFC n'est pas le bon endroit pour stocker un catalogue de mises en œuvre d'un protocole. Ce RFC 7942 ne vise que les Internet-Drafts, afin d'aider à l'évaluation d'une proposition. La section décrivant les mises en œuvre est donc typiquement supprimée lors de la publication du RFC. Comparez par exemple le draft-ietf-dnsop-qname-minimisation (dont la section 8 décrit les mises en œuvre existantes) avec le RFC 7816 (qui n'a plus cette section).

Le concept de running code est décrit dans le Tao (cf. RFC 4677 et RFC 6722). Il synthétise l'approche pragmatique de l'IETF : une norme qui n'est pas mise en œuvre ne sert à rien. Malgré cela, bien des RFC n'ont jamais connu la moindre mise en œuvre. En effet, ce principe général du running code n'a jamais été traduit dans une exigence formalisée et globale pour les auteurs de RFC. Il existe par contre des règles locales. Ainsi, la Routing Area de l'IETF (les groupes de travail qui normalisent les protocoles de routage) a longtemps demandé (RFC 1264) au moins une mise en œuvre avant la publication d'un RFC sur le chemin des normes. Le RFC 4794 a supprimé cette règle, qui reste appliquée par certains groupes de la Routing Area comme IDR. À noter qu'avant le RFC 6982, il y avait déjà des compte-rendus de mise en œuvre (implementation reports) qui étaient des documents séparés, racontant des expériences concrètes de développement.

Notre RFC 7942 n'impose pas une règle (la section Implementation Status reste facultative), mais il encourage fortement à formaliser une section dans les Internet-Drafts, qui permettra de documenter les mises en œuvre connues. L'idée est que les Internet-Drafts ayant cette section seront examinés avec plus de bienveillance, sans toutefois qu'elle soit obligatoire.

La section 4 du RFC fait la liste de tous les avantages qu'il y a à indiquer ces mises en œuvre dans l'Internet-Draft : meilleure information pour la prise de décision (aussi bien sur la publication de l'Internet-Draft que sur le statut du futur RFC), encouragement aux tests d'interopérabilité, possibilité (lorsque le code est publié) de mieux comprendre le protocole (beaucoup de programmeurs préfèrent lire le source plutôt que le RFC mais attention, la référence doit rester le RFC, le code n'est pas une spécification), et enfin assurance que telle fonction du RFC peut effectivement être mise en œuvre. C'est en effet souvent le cas (par exemple lors de la discussion qui a mené au RFC 5155) que certaines personnes affirment que la technologie envisagée est tout simplement trop complexe pour être programmée. L'existence d'un programme qu'on peut tester permet de d'assurer que, si, la technologie est réaliste (bien d'autres SDO produisent sans hésiter des technologies impossible à programmer dans des conditions raisonnables).

Cette section, « Implementation status » est décrite en section 2 de ce RFC. Elle est située vers la fin (comme l'actuelle - et obligatoire, elle - « Security considerations ») et peut comporter les points suivants :

  • Une description du programme,
  • L'organisation qui a développé le programme,
  • Un URL pour le téléchargement du programme, et les conditions de la licence (comme tous les points situés ici, il est facultatif : toutes ces mises en œuvre d'une norme IETF ne seront pas forcément en logiciel libre, ni même publiquement accessibles),
  • Le niveau de maturité du programme (une preuve que ça marche, vite faite en un week-end pour tester l'Internet-Draft, n'est pas la même chose qu'une version 1.0 testée et polie),
  • Le taux de couverture de la spécification par le programme (des mises en œuvre expérimentales peuvent sauter les parties les plus difficiles de la spécification...).

Cette section peut aussi indiquer l'expérience tirée de cette mise en œuvre, ainsi que des informations sur l'interopérabilité, au cas où plusieurs mises en œuvre existent. Les présidents des groupes de travail sont explicitement chargés de vérifier que cette section ne dégénère pas en simple marketing pour le produit d'un vendeur. Notre RFC propose aussi un texte standard d'avertissement (« boilerplate ») à inclure au début de cette section « Implementation status ».

D'autres endroits que l'Internet-Draft lui-même auraient pu être utilisés pour informer sur les mises en œuvre existantes. Le RFC suggère (section 3) de passer au wiki de l'IETF lorsque la liste des programmes devient trop longue, lorsqu'il semble préférable que cette liste soit maintenue par les implémenteurs plutôt que par les auteurs de l'Internet-Draft, lorsque le groupe de travail maintient activement un wiki, ou enfin lorsque la liste en question semble utile, même après la publication en RFC (pour indiquer le niveau d'adoption par les programmeurs). Dans tous ces cas, il est bon d'indiquer l'URL du wiki en question dans l'Internet-Draft.

De très nombreux Internet-Drafts incluent désormais une telle section Implementation Status, « bien trop pour qu'on puisse les compter », note l'IESG dans son approbation de ce document. Quelques exemples d'Internet-Drafts qui incluent actuellement cette section : draft-ietf-dnsop-nxdomain-cut ou draft-ietf-dane-openpgpkey.

Le principal changement par rapport au RFC précédent, le RFC 6982 est un changement de statut. On passe de « expérimental » à « Bonne Pratique », reflétant le succès de cette expérience. Autrement, il n'y a que des changements de rédaction, rien de crucial.


Téléchargez le RFC 7942


L'article seul

RFC 7940: Representing Label Generation Rulesets Using XML

Date de publication du RFC : Août 2016
Auteur(s) du RFC : K. Davies (ICANN), A. Freytag (ASMUS)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lager
Première rédaction de cet article le 29 août 2016


Lorsqu'on a des identificateurs en Unicode (par exemple pour les noms de domaine internationalisés), on souhaite souvent limiter le nombre de caractères autorisés, et avoir des possibilités de variante (par exemple, dire que deux chaînes de caractères Unicode sont en fait équivalentes sémantiquement). Il faut donc rédiger ces règles, et un langage formel est certainement utile pour cela. C'est ce que propose ce nouveau RFC, qui normalise un langage XML pour décrire les règles d'enregistrement de ces identificateurs Unicode.

Le terme utilisé par le RFC est LGR, pour Label Generation Ruleset. Label est le composant de base d'un nom de domaine, et Ruleset fait référence à l'ensemble des règles décrites en XML et qui permettront de savoir si un composant est valide, et quelles transformations éventuellement effectuer avant de l'enregistrer. C'est un concept qui vient de l'ICANN, qui a toujours présenté les IDN comme une chose dangereuse (bien à tort), nécessitant des variant tables ou autres algorithmes compliqués. Donc, si vous ne travaillez pas avec l'ICANN, il n'est pas nécessaire de connaitre ce RFC.

Le langage présenté dans ce RFC est assez complexe, mais le problème est complexe. Ceci dit, dans les cas « simples » (alphabet latin), les règles LGR seront également simples. Si on veut juste dire que é, è et ë sont autorisés dans les noms, et avec e comme variante, c'est trivial à faire, à peine plus compliqué que les tables du RFC 4290.

Notez que l'algorithme décrit par un LGR ne suffit pas comme règle d'enregistrements des noms de domaine : il existe d'autres règles (comme la priorité aux entreprises titulaires de propriété intellectuelle) qui ne sont pas exprimables par ces algorithmes.

Avant ce RFC, les règles concernant les IDN étaient publiées en langue naturelle, ou parfois dans le langage formel des RFC 3743 et/ou RFC 4290. Le langage décrit ici a vocation à les remplacer. Il est structuré, donc lisible par un programme, et permet de dériver automatiquement les programmes de vérification d'un nom (par exemple ceux qui sont lancés par un serveur EPP recevant un ordre <domain:create>, RFC 5731, section 3.2.1).

Le format est relativement simple si on a une politique simple mais permet le cas échéant de mettre en œuvre des politiques très complexes (qui sont utiles pour certaines écritures asiatiques, par exemple). Il est conçu pour les IDN mais peut être utilisé si on a à enregistrer des identificateurs Unicode dans un autre contexte.

Le cahier des charges du format des LGR figure en section 2 du RFC :

  • Doit pouvoir être programmé de manière raisonnablement directe (je n'ai pas essayé...)
  • Doit pouvoir être validé (l'ICANN, qui exige l'envoi d'une politique IDN pour les TLD qu'elle régule, peut ainsi tester automatiquement la validité de celles-ci). Notez aussi qu'un LGR sera développé pour la racine du DNS.
  • Doit pouvoir exprimer la notion de variantes (équivalence entre deux caractères, ou chaînes de caractère, par exemple entre les sinogrammes traditionnels et les simplifiés).
  • Doit pouvoir exprimer la notion de contexte (un caractère n'est valable que dans un certain contexte par exemple le sigma final grec, U+03F1 (ϱ) qui ne peut apparaître qu'en fin de mot).
  • Etc

Un point important de ce RFC est qu'il décrit un format, pas une politique : le RFC ne dit pas si le caractère Unicode U+00E8 (è) doit être considéré comme une variante du U+0065 (e) : il fournit juste le moyen d'exprimer cette équivalence, si on le décide.

La section 4 du RFC spécifie le format exact. (Le schéma formel - en Relax NG - est dans l'annexe D.) Un ensemble de règles LGR est mise dans un élément XML <lgr>. Il contient quelques métadonnées, dont la date et la langue ou l'écriture pour lesquels ce LGR est prévu. Comme l'ICANN, dans ses politiques IDN, mélange très souvent langue et écriture (par exemple en parlant de « domaines multilingues », ce qui est absurde), il faut préciser que la plupart des politiques portent sur des écritures (un nom de domaine n'a pas de langue : coca-cola.com est-il de l'anglais ?) La valeur de l'élément XML <language> est une étiquette du RFC 5646, avec la langue marquée comme « non définie » (und pour undeterminate). Un exemple pour une politique consacrée à l'alphabet cyrillique : <language>und-Cyrl</language>.

Les règles elle-mêmes sont en section 5. La plus simple est celle qui autorise un caractère donné, ici le tiret (cp = Code Point Unicode, ici U+002D) :

      
<char cp="002D"/>

    

On peut aussi autoriser un intervalle, ici tous les chiffres arabes :

      
<range first-cp="0030" last-cp="0039"/>

    

Comme on le voit, les caractères sont identifiés par leur point de code Unicode, écrit sans le « U+ » initial. Bien que XML permettre de représenter nativement tous les caractères Unicode, cette possibilité n'est pas exploitée par ce RFC (cf. Unicode Standard Annex #42).

Voici maintenant un exemple de règle qui précise que le point médian U+00B7 n'est autorisé qu'entre deux l (c'est le cas en catalan mais notez qu'en français, il est aussi utilisé dans une perspective féministe). Cela se fait en indiquant une séquence :

      
<char cp="006C 00B7 006C" comment="Catalan middle dot"/>

    

Et voici une règle contextuelle plus complexe. On veut n'autoriser le gluon de largeur nulle U+200D qu'après un virāma. Si une règle follows-virama (non montrée ici) a été définie, on peut écrire :

      
  <char cp="200D" when="follows-virama" />

    

Et les variantes ? Voici d'abord comment exprimer que le é est une simple variante du e (non pas que je recommande cette politique : c'est juste un exemple) :

      
 <char cp="00E8">
           <var cp="0065"/>
 </char>

    

Et une variante où un caractère (œ) est mis en correspondance avec deux caractères (oe) :

      
 <char cp="00F6">
           <var cp="006F 0065"/>
 </char>

    

Ces règles portaient sur des caractères qui formaient une partie d'un composant d'un nom. Mais il y a aussi des règles qui portent sur la totalité du composant (section 6 du RFC). Pour cela, d'abord un petit mot sur la notion de classe. On définit une classe de caractères à partir de propriétés Unicode. Ici, on a la classe des virāma, définie à partir de la propriété Unicode CCC (Canonical Combining Class) :

      
<class name="virama" property="ccc:9" />

    

On peut ensuite combiner les classes par intersection, union, etc.

Les règles permettent aussi d'utiliser des opérateurs booléens. Voici par exemple la règle traditionnelle des noms de machines (et pas des noms de domaine, contrairement aux bêtises qu'on lit souvent), autorisant lettres ASCII, chiffres et tiret. Elle utilise <choice>, qui fait un OU logique entre les termes :

      
       <rule name="ldh">
          <choice count="1+">
              <class by-ref="letter"/>
              <class by-ref="digit"/>
              <char cp="002D" comment="literal HYPHEN"/>
          </choice>
       </rule>

    

Des exemples plus réalistes et plus détaillés figurent dans l'annexe A.

Le document XML complet a le type MIME application/lgr+xml.

Quelques petits mots sur la sécurité (section 12 du RFC). Le RFC part du préjugé (qui est faux) comme quoi les noms en Unicode poseraient des problèmes de sécurité. La section 12 note ensuite (si on accepte cette prémisse) que les règles de ce RFC ne résolvent pas complètement le problème (qui est largement imaginaire). Il reste possible de faire des noms « trompeurs » même avec les règles les plus strictes. Outre question de sécurité à garder en tête : les règles de ce RFC peuvent permettre de concevoir des politiques LGR très complexes, qui peuvent épuiser les ressources de la machine qui tenterait de les évaluer.

Si vous voulez pratiquer avec vos propres LGR, l'ICANN a fait développer un outil qui est accessible en ligne (lisez la documentation pour connaitre le mot de passe) ou bien en source sur GitHub : lgr-core et lgr-django pour l'interface Web en Django.


Téléchargez le RFC 7940


L'article seul

RFC 7937: Content Distribution Network Interconnection (CDNI) Logging Interface

Date de publication du RFC : Août 2016
Auteur(s) du RFC : F. Le Faucheur, G. Bertrand, I. Oprescu, R. Peterkofsky (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF cdni
Première rédaction de cet article le 16 septembre 2016


Ce RFC fait partie de la série qui normalise les interactions entre un CDN amont (celui choisi par le client) et un CDN aval (celui auquel, pour une raison ou pour une autre, une partie du trafic est délégué). Il traite la question de la journalisation : comment est-ce que le CDN aval remonte au CDN amont le journal d'activité ?

Cette idée d'interconnexion standard des CDN est expliquée dans le RFC 6707, le cadre général est dans le RFC 7336, dont la section 4.4 identifie le besoin d'un mécanisme de journalisation, et le cahier des charges est dans le RFC 7337, la journalisation étant couverte dans sa section 8.

Notre nouveau RFC décrit d'abord (section 2) le modèle de la journalisation. Certains des aspects de celle-ci (comme la possibilité pour le CDN amont de configurer ce que le CDN aval va journaliser ou pas) sont considérés comme hors-sujet. Dans le modèle, la seule activité normalisée est la remontée des journaux depuis le CDN aval. Cela permettra au CDN amont de faire de jolies statistiques, de payer son CDN aval selon son activité, etc.

Après, on descend dans le concret : la section 3 décrit le format des journaux. Il est très inspiré du format ELF. Un fichier journal est composé d'enregistrements, chacun composé de champs. Voici un exemple d'une requête HTTP (où <HTAB> désigne une tabulation horizontale) :


2013-05-17<HTAB>00:39:09.145<HTAB>15.32<HTAB>FR/PACA/NCE/06100<HTAB>GET<HTAB>http://cdni-ucdn.dcdn-1.example.com/video/movie118.mp4<HTAB>HTTP/1.1<HTAB>200<HTAB>15799210<HTAB>"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.127 Safari/533.4"<HTAB>"host1.example.com"<HTAB>1

    

Mais attention en lisant cet exemple, le format effectif peut être modifié par des directives placées au début du fichier. (La liste des directives figure dans un registre IANA.)

Le fichier journal peut être transmis par divers protocoles (sections 4 et 5 du RFC) mais celui décrit dans ce RFC est fondé sur Atom (RFC 4287). Le CDN aval publie un flux Atom où le CDN amont trouvera les noms des fichiers à télécharger, a priori en HTTP (et même plutôt HTTPS puisque ces journaux sont confidentiels, cf. section 7.3).


Téléchargez le RFC 7937


L'article seul

RFC 7934: Host address availability recommendations

Date de publication du RFC : Juillet 2016
Auteur(s) du RFC : L. Colitti (Google), V. Cerf (Google), S. Cheshire (Apple), D. Schinazi (Apple)
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 24 juillet 2016


Combien d'adresses IPv6 faut-il permettre à une machine qui se connecte ? « Une » est évidemment le minimum mais est-ce suffisant ? Non, explique ce RFC qui recommande aux opérateurs et FAI de permettre aux machines de s'allouer autant d'adresses IPv6 qu'elles en ont besoin.

IPv6 est juste une nouvelle version d'IP. Ce n'est pas un nouveau protocole. Néanmoins, la taille bien plus importante de son espace d'adressage a des conséquences qui sont souvent oubliées par les administrateurs de réseaux. Ainsi, il est fréquent que la gestion des réseaux soit faite en limitant chaque machine à une seule adresse IPv6. En IPv4, il n'y a évidemment pas d'autre choix possible, en raison de la pénurie d'adresses publiques. Mais en IPv6, il n'y a aucune raison de se limiter, et beaucoup de raisons de permettre davantage d'adresses. Bref, bien qu'IPv6 ne soit pas complètement nouveau, cela ne veut pas dire que les bonnes pratiques IPv4 s'appliquent directement à IPv6.

Il est banal de faire remarquer que les adresses IPv6 sont, en pratique, illimitées. Un simple lien réseau (numéroté avec un préfixe de 64 bits) offre quatre milliards de fois plus d'adresses que tout l'Internet IPv4 ! Il n'est donc pas du tout obligatoire de rationner. IPv6 est conçu depuis le début (section 2 de notre RFC) avec l'idée que chaque machine (et même chaque interface réseau de chaque machine) aura plusieurs adresses IP (par exemple, une adresse locale au lien, une adresse publique stable, et au moins une adresse temporaire du RFC 8981). Et toutes les mises en œuvre d'IPv6 existantes gèrent cela correctement.

Mais quel est l'intérêt de permettre plusieurs adresses ? La section 3 de ce RFC répond à la question :

Et quels sont les problèmes si on ne fait pas ce que recommande ce RFC ? La section 4 les liste. Évidemment, si ajouter des adresses IP est complètement impossible, on est fichus. Et si la connexion au réseau permet d'ajouter des adresses IPv6 mais que cela nécessite une action explicite (par exemple via l'interface Web de l'hébergeur) ? Cela entraine :

  • Délai supplémentaire avant de déployer un nouveau service sur la machine,
  • Risque qu'un problème survienne au cours de l'opération (tiens, c'était juste le jour où l'interface Web a un problème),
  • Complexité car il faut gérer une action en plus (pour laquelle il n'y a pas de mécanisme normalisé.)

Pourquoi les opérateurs restreindraient-ils ainsi l'obtention d'adresses IPv6 supplémentaires ? Par pur sadisme ? Non, il peut y avoir des raisons objectives :

  • Limites du matériel (TCAM limité en taille),
  • Souhait de garder une cohérence avec le style IPv4 (une adresse IP par machine, qui peut servir d'identificateur simple),
  • Volonté de faire payer par tous les moyens possibles, y compris par adresse IPv6 supplémentaire.

Avec le temps, il faut espérer que les limites matérielles reculent et que la raison business (faire payer) soit rejetée par les utilisateurs (ils peuvent la contourner, par exemple en faisant du NAT, ce qui serait un comble pour IPv6).

À propos de NAT, est-ce que c'est une bonne stratégie pour résoudre le problème d'un opérateur qui ne laisserait pas assez d'adresses IPv6 à ses clients (section 5 du RFC) ? Les problèmes et limites du NAT sont bien connus (RFC 2993). Les applications sont plus complexes (car leurs programmeurs doivent déployer des trésors d'ingéniosité pour contourner le NAT), la gestion de la durée de vie des correspondances entre adresses dans le routeur NAT est pénible (quel intervalle entre les paquets d'entretien de la connexion ?), etc. C'est pour cela que le NAT sur IPv6 est très déconseillé (RFC 5902).

Ce n'est pas faute de mises en œuvre (le NAT66 est dans Linux depuis 2012...), un vendeur de virtualisation l'a aussi développé, précisement pour contourner ce manque d'adresses IPv6 allouées, mais il n'est pas souhaitable que cela continue. Le but d'IPv6 est d'avoir une vraie connectivité de bout en bout, qui ne soit limitée que par des choix délibérés (Alice ne veut plus parler à Bob), pas par des limites techniques inutiles.

Et si l'opérateur du réseau où se connecte la machine a été convaincu par ce RFC, et veut permettre à ses clients d'allouer les multiples adresses IPv6 dont ils ont besoin, quels sont les mécanismes techniques dont il dispose pour cela ? La section 6 les couvre :

  • Naturellement, le moyen le plus simple est d'utiliser SLAAC (RFC 4862) : les routeurs annoncent les préfixes IP publics et chaque machine forme des adresses à volonté en utilisant ces préfixes. Comme SLAAC impose de détecter les éventuelles collisions, avant d'utiliser une adresse (RFC 4862, section 5.4), le risque que deux machines se retrouvent avec la même adresse est nul. C'est évidemment encore mieux si chaque machine a son propre préfixe /64, elle n'a même plus à tester les collisions.
  • On peut utiliser DHCP (RFC 8415). Le protocole permet de continuer à réclamer des adresses.
  • Et il y a aussi la délégation de préfixes IPv6 via DHCP (RFC 8415). Cela permet d'envoyer un /64 à chaque client, dont il fera ce qu'il voudra.

Un tableau à la fin de la section 6 résume les forces et faiblesses de chaque solution.

Au fait, combien d'adresses exactement peut-on s'attendre à voir sur une seule machine ? La section 7 se lance dans la spéculation. Les adresses « vie privée » du RFC 8981 peuvent consommer jusqu'à huit adresses en même temps. Avec une demi-douzaine de services réseau, et une demi-douzaine de machines virtuelles (ou de containers) hébergés, avoir vingt adresses sur une seule machine peut donc être raisonnable. Mais, bien sûr, il est difficile de prévoir les usages futurs et, en pratique, ce sera peut-être bien plus.

Allez, c'est presque fini, la section 8 du RFC synthétise les recommendations officielles :

  • Il est recommandé que les hébergeurs et FAI qui déploient IPv6 permettent aux client d'avoir plusieurs adresses IP par machine.
  • Il est également recommandé qu'il n'y ait pas de limite stricte au nombre d'adresses utilisables.
  • Il est recommandé que cette allocation d'adresses supplémentaires puisse se faire sans requête explicite à l'hébergeur ou FAI.

Ces recommandations, si elles sont suivies, auront quelques conséquences pratiques (section 9). Par exemple, elles ne permettent pas de garder trace de quelles adresses sont utilisées par quelle machine. (Alors qu'avec une demande d'allocation explicite, par exemple par le biais d'une nouvelle interface virtuelle, comme c'est le cas actuellement chez Gandi, ce suivi est possible.) C'est ennuyeux si on veut remonter d'une adresse IP qui pose un problème (par exemple parce qu'il a téléchargé Les tortues Ninja) à son propriétaire. Une solution de remplacement est de superviser le réseau et de relever les réponses NDP, permettant ainsi de se constituer une base de la relation entre les adresses IP et les adresses MAC. Le logiciel NDPMon permet de faire cela. (On peut aussi interroger les commutateurs en SNMP, pour avoir un résultat analogue.) Les auteurs du RFC notent que tous leurs employeurs ont déjà un tel système en place, et ils citent plusieurs gros campus universitaires qui font de même, ce qui montre le caractère réaliste de la proposition.

Puisqu'on parle de sécurité, il faut noter que de ne pas permettre officiellement aux machines de s'attribuer des adresses IP supplémentaires ne signifiera pas qu'elles ne le feront pas. Si on n'a pas de sécurité dans la couche 2 (cf. RFC 7039), les machines peuvent toujours se configurer ce qu'elles veulent. En outre, si le mode d'allocation est DHCP, les efforts actuels pour améliorer la vie privée des utilisateurs de DHCP (RFC 7844) vont de toute façon diminuer l'intérêt de DHCP pour la sécurité.

Autre problème pratique pour les administrateurs réseau, les limites du matériel. Si un commutateur connecte mille machines, sa table de correspondance adresses IP <-> adresses MAC aura mille entrées. Si chaque machine s'alloue dix adresses, cette table devra stocker dix mille entrées. Le commutateur a-t-il cette capacité ? S'il ne l'a pas, on risque des pertes de connectivité. Certes, le matériel va évoluer. Mais il existe une autre solution, suggérée par notre RFC : utiliser un préfixe IP par machine. Ainsi, le commutateur n'aura à gérer qu'une seule entrée par machine, quel que soit son nombre d'adresses. Évidemment, cela consommera davantage d'adresses IPv6, et cela compliquera un peu la gestion des adresses. Cette proposition est donc légèrement plus sujette à controverse que la principale (permettre plusieurs adresses par machine) qui, elle, est largement reconnue comme justifiée.


Téléchargez le RFC 7934


L'article seul

RFC 7929: DNS-Based Authentication of Named Entities (DANE) Bindings for OpenPGP

Date de publication du RFC : Août 2016
Auteur(s) du RFC : P. Wouters (Red Hat)
Expérimental
Réalisé dans le cadre du groupe de travail IETF dane
Première rédaction de cet article le 25 août 2016
Dernière mise à jour le 12 décembre 2017


Un problème classique du système de cryptographie OpenPGP, normalisé dans le RFC 9580 est de vérifier les clés publiques des correspondants. Les trouver, c'est relativement facile : le correspondant pense à vous les envoyer ou bien on se sert tout simplement d'un serveur de clés. Mais ceux-ci ne garantissent rien sur la clé. N'importe qui peut créer une clé marquée flotus@whitehouse.gov et la mettre sur les serveurs de clé, même si cette clé n'a rien à voir avec la Maison-Blanche. Avant la solution de ce nouveau RFC, il n'existait pas de mécanisme sécurisé pour récupérer une clé publique PGP. Que propose ce RFC ? De mettre les clés dans le DNS (nouveau type d'enregistrement OPENPGPKEY), dans le domaine de la partie droite de l'adresse de courrier, sécurisée par DNSSEC. En gros, il s'agit de faire pour le courrier et PGP ce que fait déjà DANE (RFC 6698) pour le Web/TLS.

Les serveurs de clés utilisent le protocole HKP (jamais décrit dans un RFC). Ils fournissent un service très utile en permettant de chercher une clé, par son identificateur, ou par l'adresse de courrier associé. Voici un exemple par identificateur :

    
% gpg --recv-key  0xF3396311465F8E5D
gpg: requesting key 465F8E5D from hkps server hkps.pool.sks-keyservers.net
gpg: key 465F8E5D: public key "Amaelle G <amaelle.guiton@techn0polis.net>" imported
...
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
      
    

et un par adresse (notez que les adresses sont probablement toutes fausses) :


% gpg --search-key elysee.fr      
gpg: searching for "elysee.fr" from hkps server hkps.pool.sks-keyservers.net
(1)	hollande (flamby) <hollande@elysee.fr>
	  2048 bit RSA key CF22758A, created: 2014-01-06
(2)	jacques chirac (ancienne adresse) <jacques-chirac@elysee.fr>
	  2048 bit RSA key 2A97F759, created: 2007-11-15, expires: 2007-11-16 (expired)
(3)	kaziwan <kaziwan@elysee.gouv.fr>
	  1024 bit DSA key AA7FD67C, created: 2005-11-28
(4)	Gerard Calestroupat <gerard.calestroupat@elysee.fr>
	  1024 bit DSA key 82F02C73, created: 2003-08-05, expires: 2003-08-08 (expired)
(5)	Toto Berlingo <T.Berlingo@Elysee.fr>
	  1024 bit DSA key E9E920B7, created: 1999-06-10
    

Ces serveurs n'offrent aucune garantie : n'importe qui peut y publier une clé, avec n'importe quelle adresse et certaines clés sont clairement mensongères. L'usage normal est de récupérer la clé et ses signatures, puis de vérifier les signatures. Si elles sont faites par des gens qu'on a validés (directement, ou bien transitivement, jusqu'à une certaine profondeur), on estime la clé correcte (c'est ce qu'on nomme le web of trust). Autrement, la clé ne vaut rien. En outre, le seul système de révocation est de signer une révocation avec sa clé privée : si on l'a perdue, on ne pourra jamais retirer la clé des serveurs de clé. Pour ces deux raisons (fausses clés, et clés devenues inutilisables), il est donc difficile d'utiliser automatiquement, depuis un MUA ou un MTA, ces serveurs.

La solution proposée dans ce RFC est, comme souvent aujourd'hui, d'utiliser le DNS, qui a montré sa fiabilité et son ubiquité. Tout le monde peut faire des requêtes DNS, même coincé derrière un pare-feu, et tout le monde peut les valider, grâce à DNSSEC (RFC 4035).

On va donc publier dans sa zone DNS des enregistrements de type OPENPGPKEY, indexés par la partie gauche de l'adresse de courrier (c'est un peu plus compliqué, car elle peut contenir des caractères qui sont spéciaux pour le DNS ; voir plus loin). Le correspondant qui veut envoyer du courrier à quelqu'un cherchera cet enregistrement dans le DNS, et, s'il en trouve un, le validera avec DNSSEC et récupérera ainsi une clé PGP relativement sûre. La révocation d'une clé se fait simplement en retirant l'enregistrement du DNS.

La solution de ce RFC rend envisageable de récupérer et de vérifier automatiquement une clé avant l'envoi d'un message. Mais le RFC note bien qu'elle ne remplace pas complètement le web of trust, qui reste nécessaire si on veut une vérification sérieuse.

Ce RFC a le statut « Expérimental ». Il s'agit de tester l'idée et de voir si elle marche bien, et n'a pas trop d'inconvénients (par exemple de taille des zones DNS pour les domaines gérant beaucoup de comptes de courrier, surtout vu la taille des enregistrements OPENPGPKEY). Si le nombre de messages chiffrés avec OpenPGP augmente significativement suite à ce RFC, ce sera bon signe.

Notez qu'une expérience ressemblant à celle-ci avait déjà été faite avec le type d'enregistrement DNS CERT du RFC 4398. Ce fut un échec (peu de déploiement, peut-être en raison de la complexité du type CERT).

La section 2 de notre RFC décrit le format du nouveau type d'enregistrement DNS. Chaque enregistrement contient une et une seule clé. Si un utilisateur a plusieurs clés, il doit créer plusieurs enregistrements. Le type est 61 (et enregistré à l'IANA depuis août 2014). La partie droite de l'enregistrement (les données) contient la clé et au moins un ID et une auto-signature. Les clés PGP complètes, avec des tas de signatures, peuvent être grosses, trop pour le DNS ; le RFC recommande de ne publier que des clés minimales (pas trop de signatures, par exemple, et évidemment pas les photos qu'on peut inclure dans un attribut de la clé, cf. RFC 9580, section 5.12.1). Avec GnuPG, regardez l'exportation de ma clé avec toutes ses méta-données, et en exportation minimale (l'annexe A du RFC décrit les commandes GnuPG à utiliser) :

%  gpg --export CCC66677 > key.pgp 
% ls -lh key.pgp 
-rw-r--r-- 1 bortzmeyer bortzmeyer 86K Aug 25 17:17 key.pgp

%  gpg --export --export-options export-minimal,no-export-attributes CCC66677 > key.pgp
% ls -lh key.pgp                                                                       
-rw-r--r-- 1 bortzmeyer bortzmeyer 5.8K Aug 25 17:18 key.pgp   
    

Le format utilisé est celui du RFC 9580, section 10.1. C'est donc du binaire qui circule sur le réseau (rappelez-vous bien que, dans le DNS, le format de présentation, celui des fichiers de zone, et de la sortie de dig, n'a rien à voir avec le format binaire utilisé sur le réseau.) Les formats « texte » d'OpenPGP (« ASCII armor ») ne sont pas utilisés sur le réseau. (Donc, avec GnuPG, pas d'option --armor.)

Le format de présentation (celui des fichiers de zone et de la sortie de dig) encode la clé en Base64.

Et la partie gauche de l'enregistrement DNS ? Quel est le nom de domaine utilisé ? La section 3 du RFC fixe les règles :

  • Le domaine de l'adresse de courrier (partie droite de l'adresse de courrier) est celui où on met les enregistrements DNS OPENPGPKEY. La clé pour l'adresse stephane+chose@trucmachin.example sera donc dans la zone trucmachin.example.
  • Le nom de domaine sera la concaténation d'un condensat de la partie gauche de l'adresse de courrier (stephane+chose, dans l'exemple ci-dessus), et du composant _openpgpkey, avec le domaine de l'adresse de courrier (trucmachin.example dans l'exemple ci-dessus). Le condensat est tronqué à 28 octets. (Le nom de domaine n'est pas utilisé dans le condensat, pour faciliter la vie des opérateurs qui proposent la même adresse dans différents domaines.)
  • En fait, la règle est plus compliquée en raison des équivalences entre certains caractères (voir les exemples plus loin). Une correspondance est donc faite pour certains caractères. (Ce fut l'un des points les plus discutés dans le groupe de travail à l'IETF.)
  • Par exemple, les guillemets (oui, "jipoune le meilleur"@example.com est une adresse de courrier légale) sont retirés.
  • La condensation de la partie gauche de l'adresse de courrier est faite en SHA-256 (RFC 5754). Cela permet une protection limitée (cf. section 7.4) de la vie privée : même si un méchant met la main sur tout le fichier de zone, il ne trouvera pas facilement toutes les adresses (qui sont des données personnelles). Mais le but principal de cette condensation est de résoudre le problème de certains caractères qui sont permis dans la partie locale d'une adresse de courrier, mais qui posent des problèmes dans le DNS.

Ainsi, si l'adresse de l'utilisateur est hugh@example.com, la requête OPENPGPKEY devra chercher c93f1e400f26708f98cb19d936620da35eec8f72e57f9eec01c1afd6._openpgpkey.example.com. Voici comment calculer cela avec les outils du shell Unix (28 octets = 56 caractères dans la représentation en hexadécimal) :

    
% echo -n hugh | sha256sum | cut -c -56
c93f1e400f26708f98cb19d936620da35eec8f72e57f9eec01c1afd6

Une des difficultés pour trouver le bon nom de domaine est que les applications doivent traiter la partie gauche des adresses de courrier comme opaque (pas le droit d'analyser sa structure) et qu'elles ne connaissent pas les règles de canonicalisation qu'appliquera le domaine de destination, comme d'ignorer la casse de la partie locale (ce qui est souvent fait, mais pas toujours). Par exemple, Gmail ignore les points dans les adresses (donc foobar@gmail.com et foo.bar@gmail.com arrivent dans la même boîte aux lettres). L'émetteur qui ne connait pas cette règle va chercher la clé dans un domaine qui ne sera pas le bon. Idem avec les sous-adresses utilisées par certains domaines (en général avec le séparateur plus, comme stephane+blog, stephane+ietf, etc). Le RFC rappelle que l'émetteur ne peut pas se permettre de deviner ces règles locales, et qu'elles peuvent changer à tout moment. C'est au destinataire de se débrouiller, en publiant la clé à plusieurs noms, et en faisant attention aux variantes qu'il publie.

L'internationalisation des adresses de courrier complique évidemment encore un peu les choses (voir par exemple la section 10.1 du RFC 6530).

La section 6 du RFC se penche sur un problème pratique qu'on rencontre parfois avec le DNS : la difficulté à recevoir des réponses au-delà d'une certaine taille (il y a trois limites fréquemment rencontrées, la très ancienne limite de 512 octets du DNS, largement dépassée de nos jours, la limite de la MTU à 1 500 octets, au-delà de laquelle peut commencer la fragmentation, et la limite par défaut de la plupart des clients DNS à 4 096 octets). Les clés PGP peuvent être grosses, et le RFC recommende donc si possible de les récupérer sur TCP, pas UDP.

La section 7 de notre RFC analyse les questions de sécurité liées à cette technique. Elle rappelle que DNSSEC doit être utilisé : les enregistrements OPENPGPKEY récupérés ne doivent être utilisés que s'ils sont signés, et que la signature est valide. (Autrement, il serait trop facile à un attaquant de répondre avec une fausse clé.) Mais si DNSSEC est nécessaire, il n'est pas suffisant et la validation habituelle des clés PGP reste nécessaire si on veut un haut niveau de confidentialité. Ceci dit, comme souvent en sécurité, le mieux est l'ennemi du bien, et il vaut mieux une clé pas très vérifiée plutôt que d'envoyer le message en clair, comme le fait presque tout le monde aujourd'hui.

Et, évidemment, la sécurité DNSSEC doit être équivalente à la sécurité PGP puisqu'un attaquant qui aurait cassé la clé DNSSEC pourrait remplacer toutes les clés PGP du domaine. Il faut donc une cohérence dans les politiques de sécurité entre PGP et DNSSEC (section 7.6).

Autre problème de sécurité, cette fois lié à la vie privée : les requêtes DNS révèlent avec qui on veut communiquer de manière sécurisée par courrier (RFC 7626). Le fait que le nom de domaine utilisé soit un condensat de la partie locale de l'adresse de courrier limite un peu les risques, mais pas suffisamment (si on soupçonne qu'Alice écrit à bob@example.com mais qu'on n'en est pas sûr, il suffit de construire le nom où se trouve l'enregistrement OPENPGPKEY et de vérifier que ce nom est demandé, cf. section 7.4). C'est d'autant plus grave que les clients DNS actuels envoient en général le nom de domaine complet à tous les serveurs, même ceux qui n'en ont pas besoin. La minimisation de la requête (RFC 9156) limite ce problème. Le chiffrement des requêtes DNS (RFC 7858) peut faire le reste. Le cache du DNS limite un peu les risques et il est donc essentiel de ne pas faire une requête DNS externe à chaque fois qu'on envoie un message PGP à quelqu'un, cela ferait fuiter bien trop d'informations (section 7.5).

Pour limiter les risques qu'un attaquant récolte toutes les adresses de courrier du domaine, le RFC recommande de signer la zone en utilisant NSEC3 (RFC 5155).

À l'inverse de ce souci de protection de la vie privée, si une organisation veut lire le courrier de ses employés, la solution est qu'elle publie une clé d'organisation dans le DNS, pour pouvoir déchiffrer les messages entrants.

Un autre problème de sécurité est le risque d'utilisation dans des attaques par amplification. La taille importante des enregistrements OPENPGPKEY (surtout avec les clés RSA) aggrave ce risque. Le RFC suggère de n'envoyer ces enregistrements via UDP que si l'adresse IP source de la requête a été vérifiée, par exemple avec les petits gâteaux du RFC 7873.

Où en sont les mises en œuvre de ce RFC ? GnuPG contient le code pour gérer ces clés dans le DNS depuis la version 2.1.9. Même chose pour openpgp-milter.

L'outil hash-slinger permet quant à lui de générer et de vérifier des enregistrements OPENPGPKEY :

% openpgpkey --fetch --uid paul@nohats.ca  paul@nohats.ca
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: paul@nohats.ca key obtained from DNS
Comment: key transfer was protected by DNSSEC
Version: GnuPG v1

mQENBFaJkKsBCADDSwQawRsKYqY/DuxWZjNNn39f14tDaswbpuF+PorNnt0MrepI
0yVY28NQ+5P09j75Os1jlqksK06aAVBtkJvr+T1ip85AxPUdTjD3U3zhM5/YATMi
...

On peut alors enregistrer la clé dans le trousseau PGP :


% openpgpkey --fetch --uid paul@nohats.ca  paul@nohats.ca | gpg --import
gpg: key BBAE5D31: public key "Paul Wouters (online key) <paul@nohats.ca>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

   

Voici un exemple de récupération de ma clé :


% openpgpkey  --fetch --uid 'stephane@bortzmeyer.org' stephane@bortzmeyer.org |gpg  

pub  4096R/CCC66677 2014-02-08 Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>
uid                            Stéphane Bortzmeyer <stephane@sources.org>
uid                            Stéphane Bortzmeyer (Work address) <bortzmeyer@nic.fr>
uid                            TextSecure fingerprint (05 d6 3b dc b7 e4 d7 69 2f f6 24 d5 51 31 88 2f a5 59 ae 96 e0 fb a5 75 ab e6 6c 64 ca e9 bb 6a 77) <BdY73Lfk12kv9iTVUTGIL6VZrpbg+6V1q+ZsZMrpu2p3@base64>
sub  4096R/96A4A254 2014-02-09 [expires: 2018-01-10]
sub  4096R/57F02AA1 2014-02-09 [expires: 2017-01-10]

Mais comment ai-je fait pour que ça marche ? hash-slinger permet de créer la clé directement au bon format :

% openpgpkey --create stephane@bortzmeyer.org                                 
; keyid: 555F5B15CCC66677                                   
28182f0a278161989f90f090dabd6cab331663d8509ddbae617bb1e7._openpgpkey.bortzmeyer.org. IN OPENPGPKEY mQINBFL2VNABE...

Il n'y a plus qu'à la mettre dans le fichier de zone, et à re-signer. Mais, car il y a un mais, cela ne marche que si on a des logiciels récents, qui connaissent le type 61 (OPENPGPKEY). Si ce n'est pas le cas, le signeur refusera de signer, ou le serveur de recharger la zone. C'était mon cas, en raison d'une trop vieille version d'OpenDNSSEC. Trois solutions, commençons par la plus simple, demander à hash-slinger de générer un enregistrement DNS à la syntaxe générique (« types inconnus », du RFC 3597) :

% openpgpkey --create stephane@bortzmeyer.org --output generic
; keyid: 555F5B15CCC66677
28182f0a278161989f90f090dabd6cab331663d8509ddbae617bb1e7._openpgpkey.bortzmeyer.org. IN TYPE61 \# 5874 99020d0452f654d001100096b30513d96c42e697fd06674b1...

Et c'est cet enregistrement à la syntaxe générique qu'on met dans le fichier de zone. Sinon, si on aime bien faire l'encodage soi-même, utilisons xxd :

% openpgpkey --create stephane@bortzmeyer.org > key.zone
[Edit to keep the zone data]

% base64 -d key.zone > key.bin
[wc -c key.bin to know what number to put in the zone file]

% xxd -p key.bin > key.hex

Et on met le contenu de key.hex dans le fichier de zone. Sinon, l'annexe A du RFC fournit une variante de cette solution, utilisant hexdump.

Voici la récupération de cette clé dans le DNS, avec un dig récent, qui connait ce type OPENPGPKEY et sait formater le résultat :

% dig OPENPGPKEY   28182f0a278161989f90f090dabd6cab331663d8509ddbae617bb1e7._openpgpkey.bortzmeyer.org  
;; Truncated, retrying in TCP mode.
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36368
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 9, ADDITIONAL: 13
...
;; ANSWER SECTION:
28182f0a278161989f90f090dabd6cab331663d8509ddbae617bb1e7._openpgpkey.bortzmeyer.org. 85841 IN OPENPGPKEY ( mQINBFL2VNABEACWswUT2WxC5pf9BmdLHzPeXzHZfvik
				ExJHaQ7LHPRVjAQtBiBN0vI3Uh0VgFzjA+0H2sqTduJY
				tqd8mrTh9clDnCbrMU8svc7MeWxkW21ogjqBYL8puA3d
                                ...         

Notez le « Truncated, retrying in TCP mode ». L'enregistrement est trop gros pour les paquets UDP qu'accepte dig par défaut (il fait huit kilo-octets, dig accepte quatre par défaut). Notez aussi le bit AD (Authentic Data) dans la réponse : celle-ci a bien été validée par DNSSEC.

Avec un dig ancien, qui ne connait pas ce nouveau type (et, cette fois, on demande directement en TCP, comme le recommande le RFC) :

% dig +tcp -t TYPE61 28182f0a278161989f90f090dabd6cab331663d8509ddbae617bb1e7._openpgpkey.bortzmeyer.org 
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19989
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 9, ADDITIONAL: 29
...
;; ANSWER SECTION:
28182f0a278161989f90f090dabd6cab331663d8509ddbae617bb1e7._openpgpkey.bortzmeyer.org. 86206 IN TYPE61 \# 5874 ( 99020D0452F654D001100096B30513D96C42E697FD06
				674B1F33DE5F31D97EF8A4131247690ECB1CF4558C04
				2D06204DD2F237521D15805CE303ED07DACA9376E258
				B6A77C9AB4E1F5C9439C26EB314F2CBDCECC796C645B
                                ...

Sur ce sujet, vous pouvez aussi lire l'article de Johannes Weber, qui détaille une utilisation de l'outil de Shumon Huque.


Téléchargez le RFC 7929


L'article seul

RFC 7927: Information-Centric Networking (ICN) Research Challenges

Date de publication du RFC : Juillet 2016
Auteur(s) du RFC : D. Kutscher (NEC), S. Eum (NICT), K. Pentikousis (EICT), I. Psaras (UCL), D. Corujo (Universidade de Aveiro), D. Saucez (INRIA), T. Schmidt (HAW HAmburg), M. Waehlisch (FU Berlin)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF icnrg
Première rédaction de cet article le 25 août 2016


Quels sont les défis qui attendent l'ICN (Information-Centric Networking), ce paradigme où le composant de base du réseau n'est pas la machine ou l'interface réseau mais l'unité d'information ? Le concept est à la mode depuis pas mal d'années mais ne progresse guère sur plusieurs points importants. Ce RFC de synthèse fait le point sur ce qui ne marche pas ou pas parfaitement dans l'ICN, et les axes de recherche souhaitables.

L'idée de base de l'ICN (également nommé CCN pour Content-Centric Networking) est de considérer que le réseau sert surtout à accéder à du contenu (un point de vue Minitel 2.0 très contestable) et qu'il faut donc architecturer le réseau autour de cet accès au contenu. Une unité d'information a un nom et le réseau permet avant tout d'accéder à cette unité d'information, en échange de ce nom (get(NOM)...) L'unité d'information est parfois nommée NDO pour Named Data Object. On voit que la localisation de l'information (que ce soit dans l'espace physique, ou dans celui défini par la topologie du réseau Internet) n'est pas prise en compte. Cette approche permettrait, en théorie, une meilleure efficacité (la mise en cache par les composants du réseau améliorerait les performances), un meilleur passage à l'échelle (la réplication de données populaires serait simple), et une meilleure résilience (le contenu serait à plusieurs endroits). Cette idée est décrite plus longuement dans le RFC 7476 (lecture recommandée, avant ce RFC 7927), et j'en ai déjà écrit une critique.

Pour la mettre en œuvre, on peut envisager une couche supplémentaire « accès au contenu » au-dessus de l'Internet actuel, ou bien une approche « table rase » où on remplace IP par un protocole orienté ICN. Notez qu'il existe déjà des mécanismes pour accéder à du contenu par son nom, en ne se souciant pas de la localisation, mécanismes qui fournissent la rapidité, le passage à l'échelle et la robustesse dont on parlait plus haut. Le plus évident est bien sûr BitTorrent mais on notera que les promoteurs de l'ICN n'en parlent quasiment jamais...

D'abord, une synthèse des problèmes avec l'approche actuelle, vus du point de vue des partisans de l'ICN (section 2 du RFC). Cette approche, qualifiée de host-centric, met au centre du réseau la machine. Identifiée par des noms de domaine et/ou des adresses IP, c'est l'unité de base du réseau. On peut bien sûr bâtir une couche ICN (ou para-ICN) au-dessus de cette approche (un CDN est un exemple partiel) mais, comme le réseau n'est pas au courant, cela entraine des limitations :

  • La circulation du trafic n'est pas optimale, puisque l'infrastructure du réseau (le routage, par exemple) ne peut pas optimiser pour le trafic des unités d'information,
  • Les capacités du réseau, par exemple en diffusion, ne sont pas ou peu utilisées,
  • Il n'est pas évident pour le réseau de savoir ce qu'il peut garder dans un cache local (le Web doit recourir à des CDN explicitement configurés),
  • La validation des données (la vérification de leur authenticité et de leur intégrité) n'est pas assurée par le réseau et doit utiliser d'autres mécanismes.

Pour ce dernier point, celui de la validation, je suis personnellement toujours stupéfait que le Web n'ait toujours pas un mécanisme standard pour authentifier une page qu'on a récupéré. À l'heure actuelle, il faut toujours se contenter de mécanismes ad hoc, comme une signature PGP détachée du fichier qu'on veut valider. (Non, HTTPS n'est pas une solution, d'abord parce qu'il ne fonctionne qu'en transfert, pas après, donc on ne peut pas valider quelque chose qui stationne dans un cache, et ensuite parce qu'il est incompatible avec des miroirs, sauf à distribuer une clé privée à plein d'autres acteurs.)

Avant d'aller plus loin, la section 3 du RFC nous apporte une petite révision des termes et concepts essentiels en ICN. Pour les termes, il faut se souvenir de :

  • NDO (Named Data Object) : une unité de données ayant un nom,
  • Demandeur (requestor) : l'entité qui demande un NDO, en indiquant son nom,
  • Éditeur (publisher) : l'éditeur qui publie un NDO, le met en ligne. L'éditeur n'est pas forcément le créateur du NDO.

Une fois armé de cette terminologie, on peut expliquer le concept central de l'ICN : un réseau dont l'objet de base est le NDO (pas le paquet, pas la machine), et dont le service de base est d'envoyer des NDO aux demandeurs.

Ceux qui ont assisté à mon exposé à Pas Sage En Seine 2016 ont pu voir un exemple d'ICN mis en œuvre sur la chaîne de blocs (exemple FindByHash).

Sur le papier, c'est très joli, mais voyons maintenant les défis que cela pose (section 4 du RFC, le gros morceau de ce texte). D'abord, le nommage et l'authentification (les deux sont en général liés dans l'ICN). Nommer un NDO est aussi crucial dans l'ICN que de donner une adresse IP à une machine dans l'Internet classique. Et comme l'objet nommé peut être récupéré à partir de divers endroits dans le réseau ICN, vérifier l'authenticité par le biais de l'origine marche encore moins que dans le Web actuel. Il y a des tas de solutions possibles, résumées dans des études comme « Naming in Content-Oriented Architectures » de Ghodsi, A., Koponen, T., Rajahalme, J., Sarolahti, P., et S. Shenker ou bien « A Survey of Information-Centric Networking » de Ahlgren, B., Dannewitz, C., Imbrenda, C., Kutscher, D., et B. Ohlman.

Il y a deux grandes façons d'organiser le nommage dans l'ICN : espace de nommage hiérarchique, ou bien espace de nommage plat. Par exemple, un nommage hiérarchique pourrait produire des noms comme pays/éditeur/date/NDO. Cette façon de nommer simplifie nettement le routage et le passage à l'échelle. La structure des noms permet de faire une structure identique pour la PKI qui servira à authentifier le contenu (ainsi, une AC pour un éditeur donné ne pourra pas signer des certificats d'un autre éditeur, contrairement à ce qu'on voit sur le Web aujourd'hui, où la structure arborescente des noms de domaine n'est pas utilisée pour limiter les dégâts que peut faire une AC.) Cette structure hiérarchique peut aussi permettre de faire des noms lisibles par des humains. (Par contre, le RFC oublie de noter que de tels noms suscitent d'innombrables disputes de gouvernance : tout le monde veut être à la racine, veut tel nom, etc.)

Autre solution, l'espace de nommage plat. Typiquement, le NDO est désigné par un condensat cryptographique de son contenu. Cela permet l'authentification de manière évidente : on récupère le contenu, on calcule le condensat, et on doit retrouver le nom. Et un tel système peut être complètement réparti, sans autorité jouant un rôle particulier. Par contre, l'absence de structure dans le nom nécessitera un système de résolution adapté (comme une DHT). Une telle solution est même déjà décrite dans un RFC, le RFC 6920.

Aucune des deux façons de gérer l'espace de nommage n'est parfaite (cf. le triangle de Zooko). Par exemple, les condensats cryptographique ne sont pas maniables par un humain, mais les noms hiérarchiques ne peuvent pas être alloués de manière complètement pair-à-pair.

Les sujets de recherche existants sur le nommage sont :

  • Le nommage d'objets qui n'existent pas encore (un flux vidéo filmé en temps réel, par exemple). On ne peut donc pas utiliser de condensat cryptographique. Mais peut-être un mécanisme à deux étapes, un structure de données non-cryptographique décrivant le contenu, qui serait elle-même condensée ?
  • La protection de la vie privée. Avec de l'ICN ordinaire, tout le monde voit à quel contenu vous accédez. Cela concerne même les équipements intermédiaires, puisque le but est justement que le réseau voit tout.
  • Nommer les nouvelles versions d'un objet. Un principe de base de l'ICN est que le nom désigne le contenu. On change une virgule à un texte, il faut un nouveau nom (c'est particulièrement évident pour les noms fondés sur un condensat cryptographique). Comment gérer la notion de « nouvelle version, légèrement modifiée » ? Une possibilité serait d'avoir des noms incluant un numéro de version, ce qui nécessiterait un mécanisme de résolution adapté (pour des opérations comme « je veux la dernière version »).
  • Restreindre l'accès dans certains cas. Le paradigme de l'ICN est que tout le monde a accès, ce qui permet aux éléments du réseau eux-même d'avoir accès à tout et, par exemple, de le mettre en cache. Si on veut des NDO à accès restreint, comment faire ? Les solutions de sécurité du monde réel, comme le chiffrement de bout en bout sont incompatibles avec le paradigme de l'ICN.

En parlant de restriction d'accès, la sécurité, dans son ensemble est un difficile problème pour l'ICN (section 4.2). C'est le cas de la plupart des solutions miracles qui sont proposées pour l'Internet : une idée simple qui semble bien marcher, puis, dès qu'on creuse les détails pratiques, les ennuis surgissent puis, dès qu'on arrive à la sécurité, l'idée simple s'effondre. Dans le cas de l'ICN, le RFC suggère plusieurs pistes de travail. D'abord, l'authentification des données, sans doute la partie la plus facile à réaliser (et celles, on l'a vu, où le Web actuel est défaillant). Comme on peut récupérer un NDO depuis n'importe où, pas forcément depuis le serveur d'origine, il est crucial de l'authentifier. Évidemment, si le nom de l'objet est un condensat de son contenu, comme c'est le cas avec le RFC 6920, la vérification de l'intégrité est facile : on récupère l'objet, on condense et on regarde si on tombe bien sur la même valeur. Pour des objets générés dynamiquement, cette solution ne fonctionne pas et il faut donc signer l'objet avec de la cryptographie asymétrique. D'ailleurs, cette cryptographie est nécessaire dans tous les cas : vérifier le nom-qui-est-un-condensat prouve l'intégrité de l'objet, pas que l'objet vient bien de l'auteur attendu. Ici, une signature cryptographique est donc également nécessaire. Comme toujours avec la cryptographie à clés publiques, cela laisse ouvert l'énorme problème de la distribution des clés... (cf. RFC 5280 pour une approche possible).

Pour l'utilisateur normal, vérifier que l'objet 148aec5042e7c05df755d9ce8adec80a1e9c10b1557194fd94e45146416a0de8 a bien un contenu qui correspond à ce condensat n'a qu'un intérêt limité. M. Michu voudrait une authentification plus forte, vérifier qu'il s'agit bien du guide de sécurité Java de l'ANSSI ou que c'est bien la série télé qu'il cherchait. Et, là, le problème est difficile. Les défenseurs du pair-à-pair prétendent par exemple souvent que BitTorrent est pair-à-pair, qu'il fonctionne sans centre mais, pour la très grande majorité des usages, c'est faux. M. Michu utilise un moteur de recherche centralisé, comme The Pirate Bay ou comme isoHunt. Il récupère alors un magnet (qui contient un condensat du fichier convoité), et, ensuite, on est vraiment en pair-à-pair : on télécharge, on vérifie le condensat et on s'installe dans son fauteuil pour regarder. Mais l'étape du moteur de recherche, avec ses pubs mensongères, était tout, sauf pair-à-pair.

En ICN, comment lier un NDO à une identité du monde extérieur, par exemple un acteur connu et de confiance ? C'est un problème essentiel mais non encore résolu.

Le contrôle d'accès, on l'a vu, est également un problème difficile. Comment faire si je veux vendre du contenu sans permettre aux destinataires de le redistribuer ? Il n'y a pas de solution évidente. Les approches intégrées sont celles où l'entité qui publie utilise des mesures pour limiter la redistribution (typiquement des menottes numériques), les approches séparées comptent sur une tierce-partie qui gère les accès (je vous laisse imaginer les conséquences en terme de liberté de choix de son logiciel par M. Michu...) On peut bien sûr chiffrer le contenu qu'on va distribuer (ah, Canal+...) mais il reste à distribuer les clés ensuite.

La cryptographie n'est pas éternelle, les algorithmes de cryptographie finissant par être affaiblis, puis cassés. Ce n'est pas un problème si on publie du contenu à courte durée de vie mais, si le contenu est encore utile et payant dans dix ans, l'efficacité de la cryptographie devient incertaine : comment garantir que l'algorithme utilisé sera toujours incassé ? L'idéal serait un mécanisme de re-signature et de re-chiffrement mais cela pose encore le problème de la gestion des clés privées.

Autre conséquence de la mise en cache et de la distribution à partir de plusieurs endroits, l'auteur d'un contenu n'aura plus de statistiques d'accès fiables. De la même façon, retirer un contenu publié sera encore plus difficile que sur le Web actuel (un contenu populaire est davantage répliqué et donc plus dur à supprimer).

Autre problème de sécurité avec l'ICN, le risque d'attaque par déni de service via le cache. Un des buts de l'ICN est de permettre, et même d'encourager, la mise en cache automatique du contenu par les éléments du réseau, comme les routeurs. Cela ouvre une possibilité d'attaque où le méchant téléchargerait plein de choses sans intérêt juste pour remplir les caches. Pire : comme l'ICN renonce explicitement au principe de bout en bout, ces éléments intermédiaires mantiennent un état et peuvent également être attaqués par ce biais. Par exemple, en annonçant plein de contenus divers, on pourrait remplir la table de routage.

Après la sécurité, le routage dans l'ICN pose également des défis intéressants. Le terme n'a pas tout à fait le même sens dans l'ICN que dans l'Internet actuel. L'ICN permet d'obtenir un contenu (le NDO, Named Data Object) en échange d'un nom. Cela nécessite trois étapes : la première est de résoudre le nom en un localisateur, plus concret. La deuxième est d'envoyer la demande de contenu à cet endroit. La troisième est d'obtenir la réponse (le NDO). Ces trois étapes peuvent être faites de différentes manières, catégorisées comme routage par nom (route-by-name), recherche par nom (lookup-by-name) et hybride.

Le routage par nom consiste à ne pas avoir la première étape, celle de résolution, ce qui simplifie le modèle : le réseau comprend directement les noms. Il faut donc une « table de routage » dont la taille permette de stocker tous les NDO. Comme on envisage entre 10^15 et 10^22 NDO, le défi technique est colossal. Sans compter qu'il faut aussi identifier la source de la requête, puisqu'il faudra bien lui envoyer le contenu demandé (c'est ce que fait l'algorithme des miettes de pain, cf. Rosensweig, E. et J. Kurose, « Breadcrumbs: Efficient, Best-Effort Content Location in Cache Networks »). Les sujets de recherche sur le routage par nom comportent donc, entre autres :

  • Les mécanismes d'agrégation permettant de réduire le nombre d'entrée dans la table de routage,
  • Si on utilise des noms hiérarchiques (par exemple /IETF/IRTF/ICN/Research challenges pour ce RFC) afin de permettre l'agrégation, comment permettre aux utilisateurs d'utiliser des noms plus simples ? (Se servir d'un moteur de recherche serait de la triche, puisqu'on voulait se dispenser de l'étape de résolution.)

La catégorie « recherche par nom » regroupe les mécanismes de routage qui, eux, ont une étape de résolution explicite. On résout le nom (qui est pratique pour un humain, et stable) en un localisateur (qui est pratique pour le réseau et qui pourrait être une simple adresse IP). C'est par exemple ainsi que fonctionne le système « MDHT: A hierarchical name resolution service for information-centric networks ». Les défis techniques à relever sont l'accès rapide au localisateur (en se rappelant que le contenu peut être à plusieurs endroits) et la mise à jour efficace (car le contenu peut changer de localisation, c'est même un des buts de l'ICN). Notez que les gens de l'ICN aiment bien réinventer la roue et que le DNS n'est même pas mentionné.

Enfin, il y a les solutions de la catégorie hybride. Par exemple, on fait du routage par le nom en local mais on résout le nom en un localisateur dès qu'on sort de ce domaine local.

Vous aimez les défis techniques et la liste n'est pas encore assez longue pour vous ? Il reste plusieurs problèmes à affronter. Par exemple, le contrôle de congestion. Il n'a pas à être de bout en bout puisque, dans l'ICN, la communication peut se faire via des éléments intermédiaires (voir par exemple « ConTug: A Receiver-Driven Transport Protocol for Content-Centric Networks »).

On a vu qu'un des intérêts principaux de l'ICN était de permettre la mise en cache automatique par des éléments du réseau, et l'accès au contenu à partir de ces caches. La bonne utilisation de ceux-ci soulève plusieurs questions :

  • Placer ces caches sur le chemin des données (on-path caching), ou bien à côté, avec une redirection, comme avec les CDN actuels (off-path caching) ? Le cache sur le chemin est plus conforme aux principes d'architecture de l'ICN, mais il suppose des équipements capables de suivre tout le trafic, donc très rapides. Et ces équipements seront-ils rentabilisés ? Bien des contenus sont peu accédés et le cache ne servira donc pas autant qu'on ne pouvait l'espérer.
  • Combien d'équipements capable de gérer un cache faut-il placer ?
  • Comment gérer l'obsolescence ? Un contenu populaire va se trouver stocké dans de nombreux caches distribués un peu partout. Lorsque le contenu est modifié, ces caches auront une information obsolète. Il y a plusieurs approches pour ce problème. On les classe en général en approches directes, où l'information est stockée dans le NDO lui-même (par exemple une date d'expiration, après laquelle il faudra virer le contenu du cache), et approches indirectes, où on re-valide la fraicheur du contenu auprès du serveur original (ce qui suppose que son identité soit marquée dans le NDO). Les approches indirectes permettent de gérer le cas où la date d'expiration n'est pas connue à l'avance. Notez qu'un système où le nom change avec le contenu (comme les ni: du RFC 6920) ne résout pas le problème : il faut maintenant un mécanisme pour informer les clients du nouveau nom.

Les administrateurs réseau sont habitués à des outils comme ping et traceroute pour tester et déboguer leur réseau. Comment feront-ils avec l'ICN ? C'est un autre défi. Étant donné que ping et traceroute ne sont apparus que de nombreuses années après IP, on peut prévoir que, pendant un certain temps, les administrateurs des réseaux ICN souffriront du manque d'outils adaptés.

Quelles applications utiliseront l'ICN, si tous ces défis sont relevés, et avec succès ? Le RFC se termine par une liste d'applications potentielles (cf. RFC 7476) :

  • Le Web semble un candidat évident, le paradigme « tout n'est qu'accès à du contenu » collant à peu près à une partie des usages du Web (en gros, les utilisations de la méthode HTTP GET). Les noms des NDO remmplaceront-ils les URI ? Il n'est pas évident que tous les usages du Web (POST, PUT, et autres méthodes utilisées par les applications REST) s'adaptent aussi bien à l'ICN.
  • La vidéo est typiquement un domaine où la pure consommation (on se contente d'accéder à du contenu) est très répandue. Elle semble donc un autre bon candidat pour l'ICN. Un autre document du groupe de recherche ICN de l'IRTF, le RFC 7933, étudie plus en détail cette application.
  • Et l'Internet des Objets ? L'article de Baccelli, E., Mehlis, C., Hahm, O., Schmidt, T., et M. Waehlisch, « Information Centric Networking in the IoT: Experiments with NDN in the Wild » étudie ses liens avec l'ICN. Par exemple, bien des applications IoT reposent sur un modèle PUSH, où l'objet envoie des données à son rythme, pas en réponse à une requête. Un tel modèle ne s'adapte pas bien à l'ICN.

Une conclusion personnelle ? Il y a plein d'idées intéressantes dans l'ICN, et c'est donc un sujet de recherche utile, malgré la prémisse de départ (« tout est accès au contenu ») qui est fausse.


Téléchargez le RFC 7927


L'article seul

RFC 7925: Transport Layer Security (TLS) / Datagram Transport Layer Security (DTLS) Profiles for the Internet of Things

Date de publication du RFC : Juillet 2016
Auteur(s) du RFC : H. Tschofenig (ARM), T. Fossati (Nokia)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dice
Première rédaction de cet article le 20 juillet 2016


Dans le futur, nous répètent les consultants, il y aura partout dans nos maisons, bureaux et usines, des petits objets électroniques connectés à l'Internet. C'est le fameux Internet des Objets. Ces choses serviront à mesurer le monde et à le modifier et poseront donc des problèmes de sécurité. Par exemple, sans précautions particulières, un capteur dans une usine qui envoie en Wi-Fi les informations qu'il récolte permettrait à un écoutant indiscret, même situé en dehors de l'usine, de surveiller l'activité de celle-ci. Il va donc de soi qu'il faut utiliser de la cryptographie dans ces objets. Mais celle-ci est parfois coûteuse en ressources machine, et ce nouveau RFC propose donc des profils du protocole TLS, limitant les options possibles de façon à économiser les ressources des objets.

Ces objets sont en effet contraints au sens du RFC 7228. Un TLS complet serait trop pour eux. Bien sûr, on pourrait concevoir des protocoles cryptographiques spécialement conçus à leur intention mais il faudrait développer, valider et déboguer ces protocoles et l'expérience de la cryptographie sur l'Internet montre que c'est beaucoup plus difficile que ça n'en a l'air. D'où le choix d'utiliser TLS (RFC 5246), protocole connu et éprouvé.

Notons au passage que, contrairement à ce que dit le RFC, le principal danger que pose l'Internet des Objets ne vient pas forcément d'un tiers inconnu : presque toute la domotique actuelle fonctionne avec le cloud, toutes les données récoltées étant envoyées sur les serveurs du vendeur, qui peut en faire ce qu'il veut. Chiffrer le trafic entre l'objet et ces serveurs ne comble pas cette énorme faille de sécurité.

Les profils de TLS (et de DTLS, son équivalent pour UDP, cf. RFC 6347) spécifiés dans ce RFC peuvent s'appliquer aux communications utilisant CoAP (RFC 7252) comme à celles utilisant d'autres protocoles applicatifs. Ce sont des profils, des restrictions de TLS, et ils n'introduisent donc pas un nouveau protocole, ni même de nouvelles extensions à ces protocoles.

Par exemple (section 4.4), ce RFC impose que, si on authentifie avec un certificat, les certificats X.509 utilisent ECDSA uniquement. (Gérer tous les algorithmes possibles dans un objet contraint serait trop coûteux, par exemple en occupation de la flash.) Au revoir, RSA, donc.

Toujours sur les certificats, le profil abandonne OCSP (RFC 6960) et les CRL (qui ne marchent guère, en pratique) : la révocation des certificats devra se faire uniquement par le biais d'une mise à jour du logiciel de l'objet.

Toujours concernant la cryptographie, ce RFC impose (section 13) de n'utiliser que des suites de chiffrement intègres (AEAD) comme TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 (AES avec CCM, cf. RFC 7251).

Comme l'utilisation de TLS dans ces objets contraints est récente, il n'y a pas trop à se préoccuper de la base installée. On peut donc décider de ne jamais gérer des trucs trop anciens. C'est ainsi que la version minimale de TLS acceptée dans les profils de ce RFC est la 1.2 (section 18).

Il y a quelques points où ce RFC rend obligatoire des fonctions qui étaient optionnelles dans TLS, parce qu'elles sont cruciales pour des objets contraints. C'est le cas de la reprise de session TLS précédente, qui permet d'éviter de refaire des opérations cryptographiques coûteuses à chaque démarrage. Par contre, certaines fonctions sont déconseillées, comme la compression, coûteuse et sans doute inutile dans l'Internet des Objets où les protocoles sont déjà optimisés pour réduire la taille des données échangées. (En outre, il existe de bonnes raisons de sécurité de couper la compression TLS, RFC 7525, section 3.3.) Idem pour la renégotiation du RFC 5746, qui est exclue.

Un problème courant en cryptographie est celui de la génération de nombres aléatoires (TLS en utilise plusieurs). Il est encore plus aigu dans l'Internet des Objets car ces objets n'ont souvent pas beaucoup de sources d'entropie (section 12 du RFC). Pas de disque dur mobile, pas de clavier, pas de souris dont les mouvements sont partiellement aléatoires. Il y a donc un risque élevé que tous les objets identiques génèrent les mêmes nombres « aléatoires ». Bref, il faut que les développeurs fassent très attention aux conseils du RFC 4086.

Autre manque des objets contraints, celui d'une horloge fiable. Pour des opérations comme la validation de la non-expiration d'un certificat, cela peut être très gênant.

Les objets contraints sont... contraints de bien d'autre façon, comme en puissance du processeur. Cela peut rendre certaines opérations cryptographiques irréalistes en logiciel. La section 19 du RFC donne des conseils sur la mise en œuvre matérielle de ces opérations :

  • Les rendre accessibles au programmeur, pas uniquement au système de base, de manière à ce que la mise en œuvre de TLS puisse bénéficier, par exemple, de l'AES présent dans le matériel, au lieu de devoir le réécrire en moins efficace.
  • Mais être souple, car un même algorithme cryptographique peut être utilisé de plusieurs façons. Ainsi, certaines mises en œuvre matérielles d'AES-CCM sont conçues pour Bluetooth avec un numnique de taille fixe, qui n'est pas celle utilisée par TLS, ce qui interdit leur réutilisation.
  • Penser à l'agilité cryptographique (la possibilité de changer d'algorithme cryptographique, pour suivre les progrès de la cryptanalyse). Par exemple, il faut se demander comment permettre à ChaCha20 (RFC 8439 et RFC 7905) de remplacer AES dans le futur.

Toujours en cryptographie, la section 20 donne des recommendations sur la longueur des clés. Un point important, et spécifique aux objets, est que les engins déployés restent souvent sur le terrain très longtemps, par exemple dix ans. On ne remplace pas les capteurs, ou l'ordinateur embarqué dans une machine, comme on change d'iPhone ! La longueur des clés doit donc être prévue pour les attaques du futur, pas pour celles d'aujourd'hui.

Les objets dont on parle dans ce RFC sont souvent déployés dans des environnements où les contraintes de vie privée sont fortes. Cela peut être une usine qui ne veut pas que ses processus soient espionnés, ou bien une maison dont les habitants ne veulent pas être surveillés (section 22 du RFC). TLS ne protège pas contre tout et certaines fuites d'information persistent même quand il est utilisé. Elles peuvent venir du protocole TLS lui-même (la reprise de session utilise des informations qui permettent de suivre une machine à la trace) ou bien provenir de métadonnées diverses. Par exemple, s'il existe un capteur de présence qui envoie un message lorsque quelqu'un rentre dans l'appartement, chiffrer ce message ne fait pas gagner grand'chose : une fois qu'un observateur a identifié le capteur de présence, le seul envoi du message suffit à l'informer d'une arrivée. Une vraie protection de la vie privée peut donc nécessiter des méthodes additionnelles comme l'envoi de trafic bidon.

Le RFC se termine en rappelant qu'il est crucial de fournir un mécanisme de mise à jour simple des engins. Les objets de l'Internet des Objets sont souvent de type « je pose et puis j'oublie », sans aucun moyen de mettre à jour leur logiciel. Or, la sécurité peut nécessiter une telle mise à jour, soit pour corriger une bogue dans la bibliothèque TLS, soit pour révoquer des clés et en mettre d'autres. Un exemple d'un mécanisme de mise à jour adapté est LWM2M.

Si vous voulez rire un peu, l'annexe A du RFC précise comment faire tourner DTLS sur... SMS.


Téléchargez le RFC 7925


L'article seul

RFC 7920: Problem Statement for the Interface to the Routing System

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : A. Atlas (Juniper), T. Nadeau (Brocade), D. Ward (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF i2rs
Première rédaction de cet article le 21 juillet 2016


Autrefois, la configuration des routeurs était relativement statique. On indiquait la politique de routage (le coût de tel ou tel lien, par exemple), les préfixes IP, les pairs BGP, parfois des routes statiques, et le routeur parlait avec ses copains routeurs, construisant ses tables qu'il allait ensuite utiliser pour la transmission des paquets. La configuration n'était pas modifiée tous les jours et quand c'était nécessaire, on se connectait à tous les routeurs qu'il fallait changer et on modifiait la config. Dans les organisations plus modernes, on édite la config, on la commite dans un VCS et on la pushe vers les routeurs avec Ansible ou un truc équivalent. Aujourd'hui, même cela ne suffit pas, on voudrait être plus agile. On voudrait modifier la configuration des routeurs à peu près en temps réel, pour répondre à des considérations de business (créer un nouveau service pour un client, profiter de variations de prix chez les transitaires...) ou à des problèmes de sécurité (déployer des filtres subtils). Cette exigence nécessite une interface vers le routeur, utilisable par des programmes. C'est le projet I2RS, Interface To the Routing System. Ce premier RFC du groupe de travail décrit précisement le problème qu'on essaie de résoudre. (Notez que le buzzword SDN n'apparait pas une seule fois dans ce RFC...)

C'est que les réseaux modernes sont grands et complexes : il n'est plus possible de faire les choses à la main en se connectant sur chaque routeur isolément. Il faut donc automatiser, et il faut donc qu'un programme puisse se connecter aux routeurs et changer leurs configurations. Cela se fait bien sûr depuis longtemps (cf. Rancid et l'exposé de Joe Abley à NANOG et l'annexe A de notre RFC qui liste les solutions existantes), mais, en l'absence d'interface normalisée, c'était assez pénible à programmer et maintenir. Il s'agit donc de standardiser ce qui existe déjà, ce qui ne devrait pas être une tâche insurmontable.

La terminologie utilisée par I2RS est décrite dans un autre RFC, le RFC 7921. Pour le résumer (section 2 du RFC) : le routeur contient un agent I2RS, qui sait parler aux différents composants du routeur (sa base de données indiquant les différents liens connectés, son système de gestion de la configuration, sa base de routes - RIB, etc). Le logiciel qui pilote les changements est le client I2RS. Il y aura sans doute un seul client pour beaucoup d'agents, installé dans le système de gestion du réseau. Entre le client et l'agent, le protocole I2RS, qui sera normalisé dans les futurs RFC du groupe de travail I2RS. A priori, le client sera juste un intermédiaire pour des applications qui piloteront le routage (le but du découplage client/application étant d'éviter que chaque application doive parler I2RS : elles pourront interagir avec le client au-dessus d'un protocole plus classique comme REST).

Pour que le client puisse parler intelligemment à l'agent, il devra avoir en tête un modèle de données décrivant le routeur, ce qu'il sait faire, ce qu'on peut lui demander.

La section 3 de notre RFC présente la nécessité de ce modèle de données. Un tel modèle avait déjà été développé pour le projet ForCES (RFC 3746), en se focalisant sur la transmission, alors que I2RS est surtout intéressé par le routage (le plan de contrôle, accès à la RIB, etc).

Comme le note la section 4, un logiciel qui voudrait vraiment donner des instructions au routeur devrait apprendre la topologie du réseau, quels sont les liens physiques ou virtuels auxquels le routeur est connecté, leur état, etc. C'est évidemment le routeur qui connait le mieux cette information et il est donc nécessaire de lui demander.

L'application aura souvent besoin de connaitre en outre le trafic réellement échangé. IPFIX (RFC 5470) est certainement utilisable pour cela, si l'application peut le configurer dynamiquement.

Enfin, la section 5 rassemble les « points divers ». Elle rappelle qu'I2RS n'impose pas forcément le développement d'un nouveau protocole ; si un protocole, ou un ensemble de protocoles existant(s) suffit, c'est parfait (l'annexe A du RFC propose des pistes en ce sens). Mais la solution doit penser à :

  • Permettre des opérations asynchrones : pas question d'attendre la fin d'une opération avant de commencer la suivante.
  • Bonne granularité des opérations ; si on veut changer la configuration pour un préfixe IP, il ne faut pas verrouiller tout le routeur.
  • Possibilité que plusieurs clients parlent au routeur en même temps, avec le minimum de coordination entre eux.
  • Débit maximum élevé ; 10 000 opérations par seconde ne devraient pas être un problème.
  • Faible latence ; les opérations simples devraient pouvoir se faire en bien moins qu'une seconde (contrairement à, par exemple, un changement de configuration du routeur avec l'interface CLI des routeurs actuels, où le commit peut être très long).
  • Possibilité de filtrer l'information au départ du routeur, pour que l'application n'ait pas à tout récupérer avant le traitement.
  • Et, bien sûr, sécurité ; un système mettant en œuvre I2RS va pouvoir modifier la configuration du routeur, ce qui est potentiellement très dangereux. Il faut donc pouvoir authentifier et autoriser les accès.

Voici pour le cahier des charges. L'annexe A propose quelques pistes qui vont en ce sens. À l'heure actuelle, l'interface la plus générale des routeurs est la CLI. Elle permet d'apprendre l'état du routeur et de changer sa configuration. Voici un exemple sur un Juniper :

bortzmeyer@MX-1> show interfaces

...
      
Physical interface: ge-1/1/9, Enabled, Physical link is Up
  Interface index: 177, SNMP ifIndex: 531
  Description: To infinity and beyond
  Link-level type: Ethernet, MTU: 1514, MRU: 1522, Speed: 1000mbps, BPDU Error: None,
  MAC-REWRITE Error: None, Loopback: Disabled, Source filtering: Disabled, Flow control: Enabled,
  Auto-negotiation: Enabled, Remote fault: Online
  Pad to minimum frame size: Disabled
  Device flags   : Present Running
  Interface flags: SNMP-Traps Internal: 0x0
  Link flags     : None
  CoS queues     : 8 supported, 8 maximum usable queues
  Current address: 5c:5e:ab:0e:4b:f1, Hardware address: 5c:5e:ab:0e:4b:f1
  Last flapped   : 2016-02-12 11:31:56 CET (22w5d 23:10 ago)
  Input rate     : 672 bps (1 pps)
  Output rate    : 672 bps (1 pps)
  Active alarms  : None
  Active defects : None
  Interface transmit statistics: Disabled

  Physical interface: xe-0/0/2, Enabled, Physical link is Up
  Interface index: 156, SNMP ifIndex: 510
  Link-level type: Ethernet, MTU: 1514, MRU: 1522, LAN-PHY mode, Speed: 10Gbps, BPDU Error: None,
  MAC-REWRITE Error: None, Loopback: None, Source filtering: Disabled, Flow control: Enabled
  Pad to minimum frame size: Disabled
  Device flags   : Present Running
  Interface flags: SNMP-Traps Internal: 0x0
  Link flags     : None
  CoS queues     : 8 supported, 8 maximum usable queues
  Current address: 5c:5e:ab:0e:4b:72, Hardware address: 5c:5e:ab:0e:4b:72
  Last flapped   : 2016-07-07 14:28:31 CEST (1w6d 21:11 ago)
  Input rate     : 0 bps (0 pps)
  Output rate    : 0 bps (0 pps)
  Active alarms  : None
  Active defects : None
  PCS statistics                      Seconds
    Bit errors                             0
    Errored blocks                         1
  Interface transmit statistics: Disabled

...
    

Ce shell n'est pas normalisé : chaque marque de routeur a le sien. Comme l'information retournée n'est pas structurée, si on veut la traiter depuis un programme, il faut faire du scraping, ce qui est pénible et peu gratifiant (d'autant plus que le « format » peut changer sans prévenir lors de la sortie d'une nouvelle version du système d'exploitation du routeur).

Les routeurs ont aussi des interfaces reposant sur un protocole et des données structurées. La plus connue est SNMP. SNMP est très utilisé pour récupérer de l'information (état des interfaces, quantité de trafic qui passe) mais, bien qu'il permette en théorie la configuration des équipements réseau, en pratique, cette possibilité a été très peu utilisée. Les raisons de cette non-utilisation sont nombreuses (complexité, absence de sémantiques avancées comme le regroupement de plusieurs changements dans une « transaction » unique, sur laquelle on peut revenir globalement, etc). SNMP ne semble donc pas envisageable pour I2RS.

Enfin, cette annexe A cite Netconf comme étant sans doute la solution disponible la plus proche, même si elle n'est pas parfaite et aurait besoin d'être complétée (voir les travaux en cours dans le RFC 7921).


Téléchargez le RFC 7920


L'article seul

RFC 7915: IP/ICMP Translation Algorithm

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : C. Bao, X. Li (CERNET Center/Tsinghua University), F. Baker (Cisco Systems), T. Anderson (Redpill Linpro), F. Gont (Huawei Technologies)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 22 juillet 2016


Parmi les nombreuses techniques de coexistence d'IPv4 et IPv6, l'ex-groupe de travail Behave développait un mécanisme de traduction permettant à une machine IPv6 de communiquer avec une machine v4 et réciproquement. Une des pièces de ce mécanisme (désormé transféré au groupe de travail v6ops) est l'algorithme de traduction, présenté dans ce RFC 7915. (Il remplace l'ancien RFC 6145, avec assez peu de changements.)

Ce nouveau mécanisme de traduction entre IPv4 et IPv6 s'inscrit dans le cadre décrit dans le RFC 6144. Il vise à remplacer « NAT-PT » (RFC 2765 et RFC 2766), officiellement retiré, après n'avoir eu aucun succès.

Plus spécifiquement, notre RFC 7915 est la version sans état du traducteur, c'est-à-dire que le traducteur peut traiter chaque paquet indépendamment des autres. Le traducteur n'a pas de table des flots en cours. S'il redémarre et perd toute mémoire, pas de problème, il peut immédiatement reprendre son travail. Cette technique permet notamment le passage à l'échelle : un traducteur d'adresses peut gérer un très grand nombre de clients sans épuiser sa mémoire. Et on peut mettre plusieurs traducteurs en parallèle, sans coordination entre eux : les paquets d'un même flot peuvent passer par des traducteurs différents. Mais cette technique a aussi quelques inconvénients comme le fait que les fragments ICMP ne seront pas traduits. Il existe donc également une version avec état du nouveau mécanisme, normalisée dans le RFC 6146. La section 1.3 discute plus en détail ces deux possibilités, avec ou sans état.

Donc, le NAT64 (son nom non officiel) vise à traduire des adresses IP entre deux réseaux, l'un v4 et l'autre v6. Comme notre RFC 7915 ne traite que le cas sans état, les adresses doivent être converties de manière purement algorithmique, sans référence à leur histoire (cf. RFC 6052, et la section 6 de ce RFC, pour ces algorithmes).

Dit comme ça, cela a l'air simple mais la traduction entre deux protocoles différents porte pas mal de pièges. Ainsi, les en-têtes de paquet n'ont pas la même taille en v4 (20 octets ou plus) et en v6 (40 octets, fixe), ce qui fait que des problèmes de MTU peuvent se poser (section 1.4). Le traducteur doit se comporter comme un routeur, donc fragmenter les paquets trop gros (en IPv4) ou retourner un message ICMP « Packet too big ».

La section 4 du RFC décrit en détail les opérations que doit faire le traducteur depuis IPv4 vers IPv6 (rappelez-vous que la traduction des adresses v4 en v6 est essentiellement dans le RFC 6052, section 2). Il y a des détails que ne connaissent pas les routeurs NAT44, qui se contentent de changer adresses et ports. En effet, ici, il faut traduire tout l'en-tête. Je ne vais pas résumer complètement cette section, juste pointer quelques pièges possibles. Ainsi, les en-têtes n'étant pas les mêmes en v4 et en v6, notre RFC doit spécifier quoi en faire. Certains cas sont évidents (comme le champ Longueur), d'autres moins. Ainsi, le champ TOS de IPv4 doit être copié verbatim dans le champ Traffic Class de IPv6. Mais le traducteur doit aussi offrir une option pour ignorer le TOS et mettre systématiquement zéro comme Traffic Class. Le champ TTL de IPv4 doit être copié dans Hop limit mais après avoir été décrémenté (rappelez-vous que le traducteur est un routeur).

La vraie difficulté n'est pas tellement dans la traduction d'IP que dans celle d'ICMP. En effet, le paquet ICMP contient le début du paquet IP qui a motivé son envoi, et ce début de paquet doit être traduit, également, sans quoi le destinataire du paquet ICMP n'y comprendra rien (par exemple, sans traduction ICMP, il recevrait en IPv6 un paquet ICMP dont le contenu est un paquet IPv4...). Notre RFC détaille donc les traductions à faire pour tous les modèles de paquets ICMP.

Le traducteur doit aussi veiller au champ Type d'ICMP, dont les valeurs sont différentes entre IPv4 et IPv6 (par exemple, Echo Reply est 0 en v4 et 129 en v6). Certains types n'ont pas d'équivalent (comme les types Timestamp ou Address Mask d'ICMPv4, absents d'ICMPv6) et le paquet ICMP doit donc être abandonné.

Enfin, le traducteur doit aussi prendre en charge les en-têtes de la couche 4 car la traduction des adresses peut ne pas être neutre pour la somme de contrôle (section 4.5) et il peut donc être nécessaire de recalculer cette dernière.

Et en sens inverse ? La section 5 décrit la traduction d'IPv6 vers IPv4. On retrouve TOS et Traffic Class, les problèmes de MTU et de fragmentation, et la traduction des messages ICMP.

La section 6 de notre RFC, une nouveauté depuis le RFC 6145, revient sur les algorithmes de correspondance entre les adresses IPv4 et IPv6. Les algorithmes obligatoires sont décrits dans le RFC 6052, mais un traducteur peut en ajouter d'autres.

Les problèmes de MTU et de fragmentation sont des cauchemars habituels sur l'Internet, notamment en raison d'équipements intermédiaires (typiquement des pare-feux) programmés avec les pieds par des anonymes, ou bien configurés n'importe comment, et qui bloquent les paquets ICMP, voire les modifient, en ignorant complètement le RFC 4890. Les traducteurs v4<->v6 auront donc ce problème, comme tant d'autres techniques utiles. La section 7 doit donc se pencher sur le traitement des paquets ICMP Packet too big qui signalent normalement que la MTU est plus réduite que ne le croit l'émetteur et qu'il faut fragmenter. Comme ces paquets sont parfois interceptés, voire modifiés, par des machines gérées par des incompétents, le traducteur doit donc parfois faire des efforts spécifiques. Si les paquets sont interceptés, la détection de la MTU du chemin n'est plus possible (RFC 2923) et il ne restera plus que la solution du RFC 4821 (faire faire le travail par les couches supérieures).

Rien n'étant parfait en ce bas monde, les traducteurs NAT64 vont aussi introduire de nouvelles questions de sécurité. La section 8 tente de prévoir lesquelles mais reste optimiste en considérant que la plupart des problèmes existent déjà dans IPv4 ou dans IPv6. Ainsi, comme avec le NAT traditionnel, l'authentification des paquets par IPsec (RFC 4302) ne marchera pas.

Pour les gens qui aiment bien les exposés concrets, avec des 0 et des 1, l'annexe A explique en grand détail le processus de traduction avec un réseau simple d'exemple, connectant le réseau traditionnel 198.51.100.0/24 et le réseau nouveau 2001:db8::/32, via un traducteur. Deux machines, H4 et H6, Alice et Bob du NAT64, vont tenter de communiquer. Le traducteur utilise le préfixe 2001:db8:100::/40 pour représenter les adresses IPv4 et 192.0.2.0/24 pour représenter les adresses IPv6. Ainsi, H6, qui a l'adresse 2001:db8:1c0:2:21:: est représenté en v4 par 192.0.2.33. H4 a l'adresse 198.51.100.2. behave-xlate-stateless Une fois le routage correctement configuré pour passer par le traducteur, suivez le RFC pour voir le trajet des paquets et les opérations qu'ils subissent, dans le cas où c'est H6 qui initie la connexion, et dans le cas inverse.

Au moins deux mises en œuvre existent déjà, faite par Ecdysis/Viagénie (avec état) et Tayga (sans état, mais nettement plus simple, d'après ses utilisateurs). Pour compenser l'absence de traduction avec état chez Tayga, on peut, sur Linux, le coupler avec SNAT/MASQUERADE (merci à Guillaume Leclanché pour sa suggestion).

Quels sont les changements entre ce mécanisme et celui du RFC 6145 ? Rien de dramatique. Ils sont résumés en section 2. Certains traitent les bogues détectées dans l'ancien RFC. D'autres changements tiennent compte du conseil actuel qui est de ne plus compter sur les « fragments atomiques » du RFC 6946 (ils ont même été franchement abandonnés avec le RFC 8021.)

Pour réfléchir à la grande question « avec état ou sans état », un article « pro-état » : « Stateless NAT64 is useless ».


Téléchargez le RFC 7915


L'article seul

RFC 7914: The scrypt Password-Based Key Derivation Function

Date de publication du RFC : Août 2016
Auteur(s) du RFC : C. Percival (Tarsnap), S. Josefsson (SJD AB)
Pour information
Première rédaction de cet article le 29 août 2016


À quoi ça sert, une fonction de dérivation de clé ? Comme leur nom l'indique, elles permettent d'obtenir des clés cryptographiques (ou autre matériel cryptographique) à partir des données qu'on leur fournit. Une utilisation courante est de fabriquer une clé pour un algorithme de chiffrement, à partir d'une phrase de passe. Cela permet d'obtenir une clé (longueur fixe, format donné) pour les opérations cryptographiques tout en laissant l'utilisateur manipuler uniquement des textes mémorisables. Par exemple, pour chiffrer un disque dur, l'utilisateur va indiquer une phrase de passe, mais le disque sera chiffré à partir de la clé obtenue en appliquant la fonction de dérivation de clé (KDF, pour Key Derivation Function) à cette phrase. Une autre utilisation est pour transformer un mot de passe qu'on doit stocker dans un fichier en une information inutilisable pour un attaquant qui mettrait la main dessus. Pour se connecter, on tape le mot de passe, on refait tourner la KDF et on vérifie qu'on obtient bien le résultat stocké.

Problème de cette méthode, l'ennemi peut tenter de faire lui-même la dérivation : il essaie des tas de mots de passe et regarde s'il obtient le résultat stocké. C'est pour cela qu'une des qualités d'une bonne fonction de dérivation est, paradoxalement, d'être lente : les gens qui connaissent le mot de passe ne seront pas gênés (ils ne font qu'un seul essai) alors que l'attaquant par force brute qui essaie des milliards de mots sera ralenti. Idéalement, on voudrait une fonction qui ne puisse pas facilement être mise en œuvre dans des ASIC, pour qu'un attaquant riche ne puisse pas investir dans une « machine à deviner les mots de passe ». C'est l'un des avantages de scrypt. (Les fanas de chaîne de blocs noteront que des chaînes comme Litecoin utilisent scrypt justement pour cette raison : rendre le minage plus accessible à tous en contrariant les ASIC.)

Pourquoi encore ajouter des fonctions de dérivation de clés (section 1 du RFC) ? Il y en a eu plein dans l'histoire, de la vénérable crypt à PBKDF2 (RFC 2898) puis aux récents bcrypt et Argon2. On en imagine souvent de nouvelles, par exemple celle-ci qui n'utilise pas du tout de chiffrement, juste de la condensation. Pour résister aux attaques par force brute (que la loi de Moore rend plus efficace chaque année), certaines ont un nombre d'itérations variables. On applique plusieurs fois l'opération de dérivation, si les machines deviennent plus rapides, on augmente ce nombre d'itérations. Cela ne marche bien que si l'attaquant utilise les mêmes logiciels que les utilisateurs normaux. Mais si la fonction de dérivation est facilement programmable dans des circuits matériels spécialisés, l'attaquant pas trop pauvre pourra s'acheter une ferme de cassage de mots de passe, remplie de circuits conçus spécifiquement, et travaillant en parallèle (les circuits deviennent plus rapides mais aussi plus petits : on peut en entasser davantage). Il ne joue alors plus dans la même catégorie que les utilisateurs légitimes.

C'est là que scrypt intervient : l'algorithme a été délibérement conçu pour être difficile à mettre dans un ASIC. scrypt a été publié en 2009 (voir l'article original qui fut présenté à USENIX). Ce RFC a commencé en 2013 et a eu une longue gestation. Il ne décrit pas scrypt, renvoyant au papier original, mais se contente de préciser les points qui sont nécessaires pour des mises en œuvre interopérables.

La section 2 du RFC décrit les paramètres de la fonction. Le plus évident est la phrase de passe, souvent choisie par un humain. Il y a aussi un sel, en général choisi aléatoirement (RFC 4086), et divers paramètres techniques, permettant notamment d'ajuster l'algorithme aux caractéristiques des machines dont on dispose. Une taille de bloc de 8 et un facteur de parallélisation de 1 conviennent bien à l'heure actuelle, mais vont sans doute augmenter dans le futur.

scrypt dépend de la fonction de condensation Salsa20 Core, plus exactement de sa version simplifiée Salsa20/8 Core (section 3 du RFC). Une mise en œuvre en C est incluse dans le RFC. (Voir la description originelle et la spécification de Salsa20.)

scrypt est un « chef d'orchestre », qui dépend de plusieurs autres algorithmes comme BlockMix (section 4), ROMix (section 5), le PBKDF2 du RFC 2898 et le HMAC-SHA-256 du RFC 6234. L'algorithme de scrypt, qui fait fonctionner ensemble tout cela, figure en section 6.

Si vous êtes programmeur et que vous mettez en œuvre scrypt, les sections 8 à 13 du RFC contiennent des vecteurs de test pour les différents algorithmes utilisés. Par exemple, avec la phrase de passe pleaseletmein, le sel SodiumChloride (exemple contestable, ce sel n'a pas été généré aléatoirement), le facteur CPU/mémoire à 16384, la taille de bloc 8 et le facteur de parallélisation 1, la clé dérivée par scrypt sera 70 23 bd cb 3a fd 73 48 46 1c 06 cd 81 fd 38 eb fd a8 fb ba 90 4f 8e 3e a9 b5 43 f6 54 5d a1 f2 d5 43 29 55 61 3f 0f cf 62 d4 97 05 24 2a 9a f9 e6 1e 85 dc 0d 65 1e 40 df cf 01 7b 45 57 58 87. Si vous trouvez une autre valeur, vérifiez votre programme.

Lisez aussi la section 14, consacrée aux questions de sécurité. Par exemple, scrypt peut consommer beaucoup de mémoire (c'est fait exprès, cela fait partie des techniques qui rendent difficile sa mise en œuvre en ASIC) et il y a donc un risque de déni de service si on accepte d'exécuter scrypt avec des paramètres quelconques, fournis depuis l'extérieur.

scrypt est, entre autres, présents dans OpenSSL depuis le 1.1.0, officiellement publiée juste après le RFC.


Téléchargez le RFC 7914


L'article seul

RFC 7908: Problem Definition and Classification of BGP Route Leaks

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : K. Sriram, D. Montgomery (US NIST), D. McPherson, E. Osterweil (Verisign), B. Dickson
Pour information
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 8 juillet 2016


Il est bien connu que le protocole de routage BGP connait fréquemment des « fuites de route » (route leaks). Les forums où les opérateurs discutent sont plein de discussions et d'alertes sur la dernière fuite en cours, il existe un compte Twitter dédié pour les alertes automatiques de fuites, le rapport sur la résilience de l'Internet en France en parle longuement. Bref, le sujet est bien connu. Curieusement, il n'y a pas de définition simple et consensuelle de ce qu'est une fuite. Il en existe en fait plusieurs sortes, et ce nouveau RFC tente de faire le point et de définir rigoureusement les différents types de fuite.

La fuite est en effet un sérieux problème : des routeurs vont recevoir des routes incorrectes et, s'ils les acceptent, le routage normal peut être perturbé, menant à des pannes, ou à du tromboning (paquets IP routés par un chemin bien plus long que l'optimum).

La liste des incidents de routage médiatiquement connus est longue : le détournement de YouTube par Pakistan Telecom, la fuite venue de Malaisie, et bien d'autres décrites dans l'abondante bibliographie de notre RFC (cf. section 1 du RFC). L'IETF travaille depuis longtemps à des solutions techniques à ce problème (notamment via son groupe de travail SIDR) mais, pour résoudre un problème, il vaut mieux bien le comprendre. C'est le travail de ce nouveau RFC, qui tente une taxonomie des fuites.

Donc, d'abord, une (tentative de) définition (section 2 du RFC). Une fuite est la propagation de l'annonce d'une route au-delà de la portée prévue. Ce n'est donc pas la seule annonce qui est le problème, c'est sa propagation. Si le Pakistan veut annoncer les routes de YouTube dans le pays, à des fins de censure, ce n'est pas une fuite de route, mais un détournement délibéré (comme celui de Google Public DNS en Turquie). La fuite a commencé quand Pakistan Telecom a bêtement laissé se propager cette annonce au monde entier.

La définition s'appuie donc sur une politique de routage qui définit « ce qui est prévu ». La politique de routage est décidée par chaque acteur (l'Internet n'a pas de Chef, chacun est maître de sa politique) et mise en œuvre dans la configuration des routeurs, sous forme de règles disant ce qui est accepté et ce qui est refusé. Si les opérateurs ne commettaient jamais d'erreurs, on pourrait dire que ces règles suffiraient à décrire la politique de routage. Mais ils en commettent (par exemple, le transitaire de Pakistan Telecom aurait dû n'accepter de son client qu'un ensemble fini de routes, celles correspondant aux préfixes alloués à Pakistan Telecom et à ses clients). Une fuite de route est donc l'équivalent pour les opérateurs réseau de ce qu'est une bogue pour les programmeurs : « ce n'est pas ce que je voulais, mais c'est ce que j'ai dit ».

La définition de la politique de routage dépend des relations entre acteurs (on n'accepte pas la même chose d'un client, d'un transitaire, d'un pair...) Le RFC cite (section 2) plusieurs études expliquant ces relations compliquées.

Au fait, on a supposé que les « fuites de routes » étaient mauvaises et qu'il fallait les combattre. Mais pourquoi ? Parce qu'elles peuvent mener à des pannes (la route annoncée à tort ne fonctionne pas) ou à des chemins sous-optimaux (un long détour). Cela concerne les fuites accidentelles, de loin les plus nombreuses (il y a davantage de maladroits que de malveillants). Mais il y a aussi des fuites délibérées, provoquées pour faire une attaque par déni de service, ou bien pour forcer le trafic à passer en un point où il pourra être plus facilement surveillé.

C'est pour cela que les gens qui ne chiffrent pas leurs communications avec des arguments du genre « non, mais ça ne sort pas du pays, de toute façon », ont gravement tort. La vulnérabilité du routage fait que leur trafic peut soudainement partir bien plus loin.

Voyons maintenant la classification des fuites (section 3). Le RFC les classe en différents types, identifiés par un numéro. Le type 1 est « virage en épingle à cheveux avec un préfixe complet ». C'est ce qui se produit quand un AS de bordure apprend un préfixe d'un de ses transitaires et le ré-annonce à un autre transitaire (d'où l'épingle à cheveux). Le second transitaire, s'il ne filtre pas les préfixes que peut annoncer son client, risque fort d'accepter la route (préférence donnée aux routes des clients sur celles des fournisseurs) et le trafic sera donc envoyé à l'AS de bordure (qui pourra ou pas le gérer). Ce fut le cas de l'incident Dodo, ainsi que de la fuite en Malaisie citée plus haut.

Le type 2, lui, est « fuite latérale ». Un acteur reçoit une route d'un pair et la transmet à un autre pair. (Voir la conférence de Jared Mauch à NANOG, où il observe qu'il n'est pas facile de détecter automatiquement ces fuites, car les relations entre acteurs peuvent être compliquées.)

L'incident de type 3, lui, se produit lorsque un AS apprend d'un transitaire des routes qu'il annonce à son pair (normalement, on n'annonce à un pair que ses routes à soi). L'exposé de Mauch en cite également des exemples.

Le type 4 est l'inverse : un pair laisse fuir les préfixes d'un pair vers un transitaire. Ce fut le cas de l'incident Moratel contre Google, ou d'un problème frappant Amazon.

Le type 5 se nomme « ré-origination ». L'AS maladroit annonce les routes comme si elles venaient de lui, et c'est son numéro d'AS qui apparait comme origine (le début du chemin d'AS). Ce fut le cas lors de grande fuite chinoise de 2010, ou pendant le curieux détournement islando-biélorusse (un des rares cas où le shunt semblait volontaire).

Le type 6 est la « fuite de préfixes plus spécifiques ». Un AS typique annonce dans son IGP des préfixes bien plus spécifiques que ce qu'il annonce publiquement, afin de contrôler plus finement le routage interne. Une erreur (redistribution de l'IGP dans l'EGP...) et paf, les préfixes spécifiques fuient. Étant plus spécifiques que le préfixe « normal », ils seront préférés lors de la transmission des paquets. Le cas le plus spectaculaire fut celui de l'AS 701.

Le RFC ne discute pas des solutions possibles, ce n'est pas son but. Les curieux pourront regarder du côté des systèmes d'alerte ou de RPKI/ROA.


Téléchargez le RFC 7908


L'article seul

RFC 7905: ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS)

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : A. Langley (Google), W. Chang (Google), N. Mavrogiannopoulos (Red Hat), J. Strombergson (Secworks Sweden), S. Josefsson (SJD)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 8 juillet 2016


Ce court RFC ajoute les algorithmes de cryptographie ChaCha20 et Poly1305 à la liste de ceux utilisables dans le protocole TLS.

ChaCha20 (dérivé de l'ancien Salsa20) est un algorithme de chiffrement symétrique et Poly1305 un authentificateur. Tous les deux ont été conçus par Dan Bernstein et sont décrits dans le RFC 8439. (Ce nouveau RFC ne fait que de les adapter à leur usage dans le cas spécifique de TLS.) ChaCha a été utilisé dans BLAKE, la version de ce RFC, ChaCha20 doit son nom au fait qu'il exécute 20 tours (rounds). Quant à Poly1305, c'est un authentificateur de Wegman-Carter. Que fait un authentificateur ? Il prend une clé, un message et fabrique une étiquette. Un attaquant n'a qu'une probabilité infime de produire une étiquette valide.

Les deux algorithmes ont été conçus en pensant surtout à une mise en œuvre en logiciel (AES restant sans doute plus rapide quand on peut utiliser du matériel spécialisé. On trouve des mesures de performance dans cet article de Google ou cet article de Cloudflare.)

Les algorithmes potentiellement concurrents ont des faiblesses : risques de sécurité pour AES-CBC ou RC4 (cf. RFC 7465), problèmes de performance pour les autres algorithmes AEAD comme AES-GCM. Comme RC4, ChaCha20 est un algorithme à flot continu, mais il n'a pas ses failles de sécurité.

Pour le cas de TLS (section 2 du RFC), ChaCha20 et Poly1305 sont utilisés ensemble, pour former un algorithme AEAD (RFC 5116). Son identifiant TLS est AEAD_CHACHA20_POLY1305 et il peut s'utiliser avec les différents algorithmes d'authentification utilisés dans TLS. Par exemple, on peut avoir une session TLS dont la cipher suite est TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 ce qui veut dire :

Ces identifiants ont été ajoutés dans le registre IANA pour TLS.

Quel est le niveau de sécurité du nouvel algorithme ? Son prédécesseur Salsa20 a bénéficié d'analyses de sécurité sérieuses (Salsa20 security et The eSTREAM Portfolio). ChaCha20 traite les failles connues de Salsa. Et il était utilisé dans un des finalistes du concours SHA-3, ce qui lui a valu d'autres examens de près.

Si, en plus de ChaCha20 et Poly1305, on utilise Curve25519 pour la cryptographie asymétrique, on aura une cryptographie tout-Bernstein, ce qui peut aussi amener à se poser des questions.

Et les mises en œuvre ? ChaCha20 est dans OpenSSL depuis la version 1.1.0 (pas encore officiellement publiée, et qui semble encore peu répandue) et dans GnuTLS depuis la 3.4.0. Il existe une liste apparemment à jour des mises en œuvre.


Téléchargez le RFC 7905


L'article seul

RFC 7901: CHAIN Query Requests in DNS

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : P. Wouters (Red Hat)
Expérimental
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 24 juin 2016


Lorsqu'un client DNS parle à un résolveur, il pose une question et obtient une réponse. Avant DNSSEC, ce mode de fonctionnement simple était souvent satisfaisant. Mais, avec DNSSEC, il est beaucoup plus fréquent de devoir faire plusieurs requêtes pour obtenir toute l'information nécessaire pour valider les réponses. (Il faut les clés de toutes les zones situées entre la racine et la zone visée.) Cela coûtait cher en latence. Cette extension EDNS expérimentale permet au client DNS de demander au résolveur de chercher et de renvoyer toutes les réponses d'un coup.

Cette extension est particulièrement utile pour le cas de machines terminales hébergeant leur propre résolveur validant (ce qui est la meilleure configuration, question confiance et sécurité). Ce n'est donc pas un hasard si l'auteur du RFC travaille chez Red Hat, système qui est livré par défaut avec une telle configuration. Mais, lorsqu'un tel résolveur validant veut vérifier les informations obtenues sur foo.bar.example, il devra (en supposant qu'il y a une zone par composant du nom de domaine) obtenir la délégation sécurisée de example (dig @la-racine DS example), la clé de example (dig @ns-example DNSKEY example), la délégation sécurisée de bar.example, etc (la clé de la racine, elle, est en dur dans le résolveur, il faut bien partir de quelque part). À faire séquentiellement, cela serait beaucoup de requêtes, donc du temps passé à attendre les réponses. Sur des liens à latence élevée (ce qui arrive souvent aux machines terminales), cela peut être pénible, même si le cache DNS aidera, pour les requêtes suivantes.

L'idée de cette extension (sections 1 et 3 du RFC) est donc que le résolveur validant local ait un forwarder (attention, le RFC utilise un vocabulaire erroné, en donnant à forwarder un sens différent de celui qu'il a dans les RFC 2308 et RFC 8499 ; j'utilise, moi, la terminologie standard). Le résolveur validant local va demander à ce forwarder, grâce à la nouvelle extension EDNS CHAIN, d'envoyer tout d'un coup (tous les DS et DNSKEY nécessaires). Bien sûr, le forwarder, lui, devra faire toutes les requêtes mais, a priori, il a un plus gros cache et sera mieux connecté.

Cette nouvelle extension est donc conçue pour des résolveurs, et est ignorée par les serveurs faisant autorité. Notez que le résolveur validant local peut être un démon autonome (Unbound tournant sur mon portable Unix) ou bien une partie d'une application qui embarquerait ses propres fonctions de résolution de noms.

Le format de l'extension est décrit en section 4 du RFC. C'est une option EDNS (RFC 6891), encodée, comme les autres options EDNS, en TLV. Le type (le code) est 13. La valeur est composée d'un seul champ, l'ancêtre le plus proche (Closest Trust Point) dont on connaisse les informations nécessaires à la validation. Le résolveur validant local a en effet certaines informations (dans sa configuration ou dans son cache) qu'il n'est pas nécessaire de lui envoyer. Dans l'exemple plus haut, si le résolveur validant local connait déjà la clé DNSSEC de example, il mettra dans le champ Closest Trust Point ce nom de domaine, indiquant au forwarder qu'il peut se contenter des informations situées plus bas, dans l'arbre du DNS. Ce nom est encodé dans le format habituel du DNS (qui n'est pas le format texte avec les points).

La section 5 du RFC décrit comment utiliser cette extension au DNS. Si on veut tester les capacités du résolveur qu'on interroge, on peut utiliser une option CHAIN vide (longueur nulle). Si le serveur à qui on a envoyé cette option répond avec la même option nulle, c'est bon. Attention, les serveurs récursifs qui mettent en œuvre CHAIN n'accepteront des requêtes « réelles » (longueur non nulle) qu'au-dessus d'un transport où l'adresse IP source est vérifiée. Le but est d'éviter les attaques par réflexion avec amplification (voir aussi la section 7.2). Pour vérifier l'adresse IP source (ce qui ne se fait normalement pas en UDP), il y a plusieurs solutions, notamment TCP (RFC 7766) et les gâteaux (RFC 7873).

Une fois qu'on a un tel transport, et que le client DNS a testé que le serveur qu'il interroge gère bien CHAIN, on peut y aller. Le client met l'ancêtre le plus proche (dont il a les clés) du nom demandé dans le champ Closest Trust Point. Dans le cas le plus courant (résolveur validant configuré avec une seule clé, celle de la racine), le résolveur « froid », qui vient de démarrer et dont le cache est vide, il commencera par mettre la racine en Closest Trust Point puis, au fur et à mesure qu'il se « réchauffera » (que son cache se peuplera), il pourra mettre des noms plus proches du nom demandé (et donc plus éloignés de la racine). Par exemple, si le résolveur validant local est configuré avec la clé de la racine, et qu'il a appris par les réponses précédentes la clé de example, mais pas celle de bar.example, et qu'il veut des informations sur le nom foo.bar.example, son option CHAIN vaudra {type = 13, longueur = 9, valeur = 0x07 0x65 0x78 0x61 0x6d 0x70 0x6c 0x65 0x00} (la longueur est celle de la partie « valeur » uniquement, le nom example est encodé selon la norme DNS). S'il connaissait également la clé de bar.example, son option CHAIN vaudrait {type = 13, longueur = 13, valeur = 0x03 0x62 0x61 0x72 0x07 0x65 0x78 0x61 0x6d 0x70 0x6c 0x65 0x00}. D'autres exemples figurent en section 9 du RFC.

Faut-il envoyer l'option CHAIN à chaque requête ? On peut mais il est recommandé de se souvenir de quels serveurs la gèrent et de n'envoyer qu'à ceux-ci (autrement, non seulement on fait du travail inutile mais on renseigne des serveurs extérieurs sur l'état de son cache). Comme il existe des middleboxes boguées sur certains trajets, la stratégie de repli du RFC 6891, section 6.2.2 peut être utile.

Et le serveur interrogé, que fait-il ? S'il accepte de répondre à une requête contenant l'extension CHAIN, il doit :

  • Ajouter à la réponse, dans la section Autorité, les enregistrements DNSSEC nécessaires (DS, DNSKEY et NSEC),
  • Mettre une CHAIN dans la réponse, avec la valeur Closest Trust Point mise au nom le plus bas (le plus éloigné de la racine) pour lequel ces informations sont nécessaires. (C'est surtout utile lorsque le serveur n'envoie pas une chaîne complète, par exemple pour économiser le réseau.)

Évidemment, si la question avait une erreur de syntaxe (taille de la partie Valeur inférieure à la Longueur, par exemple), le serveur répond FORMERR (FORmat ERRor).

La section 7 sur la sécurité étudie quelques programmes que peut poser cette extension au DNS. D'abord, mettre en œuvre cette option fatigue davantage le serveur interrogé, en terme de travail et de capacité du réseau. Un serveur est donc toujours libre d'ignorer les options CHAIN et de s'en tenir au service minimum.

Ensuite, comme vu plus haut, les réponses suivant une question qui utilise CHAIN vont être évidemment plus grosses que les réponses DNS habituelles. Il y a donc un risque d'attaques par réflexion avec amplification, si un attaquant usurpe l'adresse IP de sa victime. C'est pour cela que notre RFC impose de ne répondre avec une chaîne complète que si l'adresse IP du client a été vérifiée (par exemple parce qu'il utilise TCP, ou bien les cookies du RFC 7873).

CHAIN a aussi quelques effets sur la vie privée. Le résolveur validant local va indiquer à son forwarder (et à tout espion qui surveille le trafic) comment il est configuré et ce qu'il y a dans son cache.

Il ne semble pas qu'il existe de mise en œuvre de cette option CHAIN pour l'instant, même si c'est en projet pour Go.

Si vous vous intéressez à la conception des protocoles réseaux, notez que cette extension a fait l'objet d'une discussion pour savoir s'il ne valait pas mieux, pour réduire la latence, envoyer toutes les requêtes possibles en parallèle (cette idée a finalement été rejetée).


Téléchargez le RFC 7901


L'article seul

RFC 7890: Concepts and Terminology for Peer to Peer SIP

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : D. Bryan (Cogent Force), P. Matthews (Alcatel-Lucent), E. Shim (Samsung Electronics), D. Willis (Softarmor Systems), S. Dawkins (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF p2psip
Première rédaction de cet article le 19 juillet 2016


Le mécanisme de signalisation d'appels SIP, largement utilisé pour la téléphonie sur IP, dépend de serveurs stables et connectés en permanence (proxies, registrars, etc), pour la mise en relation des participants. Une solution entièrement pair-à-pair est en cours de développement, P2PSIP (peer to peer SIP). Ce nouveau RFC décrit ses concepts et le vocabulaire qu'elle emploie.

C'est en effet le cœur du problème de toute solution pair-à-pair sur l'Internet : le rendez-vous. Comment deux machines pas toujours allumées, pas toujours connectées, coincées derrière des équipements qui leur interdisent les connexions entrantes, peuvent-elles rentrer en relation ? Si Alice appelle Bob via des téléphones SIP, comment faire sonner la machine de Bob, bloquée derrière son routeur NAT ? La solution classique de SIP (RFC 3261) est de d'abord faire correspondre une adresse SIP (appelée AoR pour Address of Record) avec un ou plusieurs URI, qui indiquent les machines à contacter. Ces machines sont des intermédiaires, reliés à l'Internet en permanence, et qui peuvent donc tout le temps recevoir le message INVITE d'établissement de connexion (cf. RFC 3263). L'idée de base du SIP pair-à-pair, P2PSIP, est de remplacer ces intermédiaires, ces relais, par un réseau P2P.

Le mécanisme exact, nommé RELOAD, est spécifié dans le RFC 6940 (notez que le protocole RELOAD peut servir à d'autres applications que SIP). Les machines des utilisateurs s'enregistrent dans une DHT, où les appelants vont trouver le moyen de les contacter. (Par défaut, la DHT utilisée est Chord.)

La section 2 de notre RFC donne une présentation générale de la solution complète. Un réseau pair-à-pair overlay sert à établir la correspondance entre adresses (AoR) et les URI indiquant les moyens de connexion. Ce même réseau sert également à acheminer les messages SIP, si les machines d'Alice et Bob n'arrivent pas à se parler directement (un problème fréquent dans l'Internet ossifié et fermé d'aujourd'hui). Ce réseau overlay de pairs stocke les correspondances, et les duplique sur plusieurs nœuds (comme dans tout réseau pair-à-pair, chaque machine peut faire défection à tout moment). Ce sont les services de base de l'overlay, ceux qui sont absolument indispensables au bon fonctionnement de P2PSIP. Mais certains pairs peuvent accepter de participer à d'autres services, comme un service de répondeur audio, pour les cas où Bob a éteint sa machine (cf. RFC 7374). De même, certains pairs peuvent assurer des services de proxy ou de registrar SIP traditionnel, pour permettre aux clients SIP anciens de se connecter via P2PSIP.

On n'est pas obligé d'être un pair dans ce réseau P2PSIP. Un softphone SIP peut être un simple client, utilisant les services de l'overlay sans y contribuer.

Notez qu'il existe d'autres moyens de faire du SIP sans l'appareil traditionnel des serveurs relais centraux. Ces moyens sont en général limités au réseau local (par exemple les RFC 6762 et RFC 6763).

Le cœur du RFC est sa section 4, qui regroupe les définitions. Je ne vais pas les reprendre ici. La plupart sont classiques dans le monde du pair-à-pair (overlay, peer...). À noter les termes de Node ID (l'identificateur unique d'un pair - RFC 6940, section 4.1) et de peer admission (le mécanisme par lequel on admet un nouveau pair : RELOAD permet un réseau fermé, où il faut montrer patte blanche à un serveur d'inscription avant de rentrer - RFC 6940, section 11.3.)


Téléchargez le RFC 7890


L'article seul

RFC 7874: WebRTC Audio Codec and Processing Requirements

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : JM. Valin (Mozilla), C. Bran (Plantronics)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF rtcweb
Première rédaction de cet article le 21 juin 2016


Ce très court RFC expose les exigences en matière de codec audio pour WebRTC. Opus et G.711 sont ainsi obligatoires.

WebRTC permet de communiquer (texte, audio et vidéo) entre deux machines, typiquement via les navigateurs Web (ainsi, Firefox et Chrome sont tous les deux capables de faire du WebRTC.) On sait qu'il existe un grand nombre de moyens de représenter les sons sous forme d'un flux de données numériques et, pour que la communication puisse se faire, il faut que les participants aient au moins un de ces moyens en commun. C'est le but de ce RFC. D'autres codecs peuvent évidemment être gérés par le logiciel mais ceux-ci sont obligatoires (section 3 du RFC) :

  • Opus (RFC 6716), avec le format du RFC 7587.
  • G.711, avec le format de la section 4.5.14 du RFC 3551.
  • La gestion du bruit de fond du RFC 3389. (Sauf pour Opus, qui a sa propre gestion.)
  • Le format audio/telephone-event du RFC 4733 (DTMF), qui permet d'envoyer les indispensables signaux « si vous voulez de la musique d'attente pendant une heure, tapez 1, si vous voulez parler à un incompétent sous-payé qui ne comprendra pas votre problème, tapez 2 ».

Les autres codecs facultatifs sont décrits dans le RFC 7875, ce qui a permis à chacun de faire citer son codec favori.

Notre RFC spécifie également le niveau sonore (section 4). Contrairement aux recommandations UIT G.169 et G.115, il n'est pas constant car il dépend de la bande passante.

Il y a aussi une mention de la suppression d'écho (section 5 du RFC), mais sans solution unique imposée.


Téléchargez le RFC 7874


L'article seul

RFC 7873: Domain Name System (DNS) Cookies

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : Donald Eastlake (Huawei), Mark Andrews (ISC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 10 juin 2016


La grande majorité des requêtes DNS passent aujourd'hui sur UDP. Ce protocole ne fournit aucun mécanisme permettant de vérifier un tant soit peu l'adresse IP source de la requête. Contrairement à ce qui arrive avec TCP, il est trivial de mentir sur l'adresse IP source, sans être détecté. Cela permet des comportements négatifs, comme les attaques par réflexion. Ce nouveau RFC propose un mécanisme simple et léger pour s'assurer de l'adresse IP source du client : des petits gâteaux, les cookies.

Le principe est le même que pour les cookies de HTTP (décrits dans le RFC 6265) : le serveur DNS génère un nombre imprévisible qu'il transmet au client. Celui-ci renvoie ce nombre à chaque requête, prouvant qu'il recevait bien les réponses, et n'avait donc pas triché sur son adresse IP. (Notez une grosse différence avec les cookies du Web : ils changent quand l'adresse IP du client change et ils ne peuvent donc pas être utilisés pour suivre à la trace un client mobile.)

Bien sûr, une autre solution serait d'utiliser TCP (comme proposé dans le RFC 7766) ou bien DTLS (RFC en cours de discussion). Mais les petits gâteaux se veulent une solution moins radicale, de déploiement peut-être plus facile. Ils ne sont pas forcément utilisés seuls, ils peuvent être combinés avec d'autres mesures anti-usurpation, comme celles du RFC 5452.

Comme avec toute technique de sécurité, il faut regarder en détail les menaces auxquelles elle répond (section 2 du RFC). En usurpant l'adresse IP source, un méchant peut effectuer des attaques par déni de service, et il peut empoisonner un cache. Voyons ces deux cas.

D'abord, l'attaque par déni de service : en usurpant l'adresse IP source, on peut effectuer une attaque par réflexion. Dans ces attaques, le méchant envoie un paquet à un tiers, le réflecteur, en mentant sur son adresse IP source : le méchant met celle de la victime. Lorsque le réflecteur répondra, il enverra un message à la victime. Cette attaque est surtout intéressante lorsqu'elle est combinée avec l'amplification. Si la réponse est plus grosse que la question (ce qui est en général le cas avec le DNS), le méchant aura frappé la victime avec davantage d'octets que ce qu'il a lui-même envoyé.

Avec les cookies, cette attaque ne serait pas possible, la réponse à une requête ayant un cookie erroné étant plus petite que la question.

Notez que les cookies ne protègent pas contre un attaquant situé sur le chemin (on-path attacker) et qui peut lire le trafic réseau : voyant les paquets, il verra le cookie et pourra le transmettre. Les cookies n'empêchent donc pas toutes les attaques. D'autre part, si l'attaquant matraque directement le serveur DNS (sans réflexion), les cookies n'empêcheront pas l'attaque mais ils permettent de s'assurer que l'adresse IP source est exacte, ce qui autorisera de remonter à la source de l'attaque.

Le déni de service peut aussi viser le serveur DNS (au lieu de simplement l'utiliser comme réflecteur dans une attaque par réflexion). Chaque requête DNS va donner du travail au serveur et un nombre excessif peut dépasser ses capacités (comme dans l'attaque dafa888). Le problème est surtout aigu pour les serveurs récursifs, qui ont nettement plus à faire lorsqu'une requête arrive. Et ceux qui ont le plus de travail sont les serveurs récursifs qui valident avec DNSSEC : lors de la réception d'une réponse, il faut faire des calculs cryptographiques pour cette validation. Ces attaques par déni de service, au contraire de celles faites par réflexion, n'imposent pas de tricher sur l'adresse IP source mais, en le faisant, l'attaquant a l'avantage de rendre plus difficile son identification. Et cela peut lui permettre de faire traiter des requêtes qui seraient normalement refusées. Par exemple, si un résolveur n'accepte de requêtes que de son réseau (ce qui est la bonne pratique, cf. RFC 5358), et si on a oublié de filtrer en entrée les requêtes prétendant venir du réseau local, une attaque reste possible, en usurpant les adresses IP locales (une telle attaque est décrite dans l'exposé de Lars Nøring).

Après les attaques par déni de service, voyons les attaques visant à faire accepter de fausses réponses, ce qui peut mener à empoisonner le cache. Le principe est de répondre à la place du vrai serveur faisant autorité, en usurpant son adresse IP. Si le méchant est plus rapide, sa réponse peut, dans certains cas, être acceptée par un résolveur (qui la mettra peut-être dans son cache, ce qui sera encore pire). L'attaque Kaminsky est une version améliorée de cette vieille attaque. Les cookies sont une bonne protection contre ce genre d'attaques.

Après les attaques, voyons les défenses. Il n'y a pas que les cookies dans la vie. D'abord, il y a DNSSEC (RFC 4034 et RFC 4035). DNSSEC permet d'authentifier les réponses DNS, résolvant ainsi complètement les attaques par empoisonnement. Par contre, il ne résout pas les attaques par déni de service et, pire, les calculs cryptographiques qu'il impose et la taille des réponses plus élevées peuvent dans certains cas aggraver une partie de ces attaques. (Le RFC ne le note pas, mais DNSSEC a une autre limite, que les cookies résolvent : s'il empêche l'empoisonnement, il ne permet pas pour autant d'obtenir la réponse DNS correcte. DNSSEC protège bien du hameçonnage, beaucoup moins de la censure.)

Autre solution de sécurité, TSIG (RFC 8945). TSIG est meilleur que les cookies dans la mesure où il permet de vérifier cryptographiquement l'identité de la machine avec qui on parle DNS. Mais il est non trivial à déployer : reposant sur de la cryptographie symétrique, il impose un partage des clés préalable. Cela le limite à des usages entre parties qui se connaissent bien (typiquement pour sécuriser les transferts de zone). On note aussi que, comme DNSSEC, mais contrairement aux cookies, il nécessite des horloges synchronisées.

Pour résoudre ce problème de déployabilité, on peut envisager le mécanisme de distribution de clés TKEY (RFC 2930) ou bien passer à de la cryptographie asymétrique avec SIG(0) (RFC 2931). Mais aucune de ces deux techniques n'a connu de déploiement significatif.

Bref, les solutions de sécurité existantes ne résolvent pas réellement les problèmes que veulent traiter les cookies. Mais assez parlé de la « concurrence », venons-en aux cookies, comment marchent-ils (section 4 de notre RFC) ? Les cookies s'appuient sur EDNS (RFC 6891). Ils sont donc une option dans l'enregistrement EDNS. L'option cookie de EDNS porte le numéro 10. Comme toutes les options EDNS, elle est codée en TLV : le type 10, la longueur et la valeur, qui comprend un ou deux cookies. S'il n'y a que le cookie client, la longueur est fixe, de 8 octets. S'il y a en plus le cookie serveur, la longueur peut aller de 16 à 40 octets.

Le cookie client est normalement le résultat d'une fonction non-prévisible des adresses IP du client et du serveur, et d'un secret connu du client (par exemple, généré aléatoirement en suivant le RFC 4086, et changé de temps en temps). Cette fonction est, par exemple, une condensation mais le client prend ce qu'il veut : il est le seul à avoir besoin d'interpréter ses propres cookies, ils sont opaques pour tout autre acteur. L'adresse IP du client est incluse dans les paramètres de la fonction notamment pour des raisons de vie privée : empêcher le client d'être reconnu s'il change d'adresse IP (le but de nos cookies DNS n'est pas du tout le même que celui des fameux cookies du Web).

Le cookie serveur prend comme paramètres de sa propre fonction (qui n'est pas forcément la même) l'adresse IP de son client, un secret (mêmes propriétés que chez le client), et le cookie du client (et pourquoi le cookie client ne se sert pas du cookie serveur ? Voyez la section 6.) Voilà comment on fabrique les gâteaux.

Mais comment les utilise-t-on ? La section 5 l'explique. Le client qui gère les gâteaux fabrique un cookie client qu'il envoie dans ses requêtes DNS. S'il n'a jamais parlé au serveur, il envoie une option cookie de forme courte, ne comprenant qu'un seul cookie, le sien. S'il a déjà parlé au serveur et mémorisé le cookie de celui-ci, il fabrique une option EDNS cookie longue, incluant les deux cookies.

Si le serveur ne comprend rien aux cookies, il ne met pas l'option dans la réponse, et le client sait alors qu'il s'agit d'un vieux serveur, sans gestion des cookies. (Ou bien c'était une attaque par repli ; le cas ne semble pas traité dans le RFC, la solution est sans doute que le client mémorise les serveurs cookie-capable, pour détecter ces attaques.)

Si, par contre, le serveur gère les cookies, il y a cinq possibilités :

  • Si c'est le client qui est vieux, il n'envoie pas de cookie. Le serveur répond alors comme aujourd'hui. Les cookies ne posent donc pas de problème d'interopérabilité : vieux et récents logiciels peuvent cohabiter.
  • Si l'option EDNS cookie est présente, mais invalide (longueur inférieure à 8 octets, par exemple), le serveur répond FORMERR (FORmat ERRor).
  • Si la requête ne contient qu'un cookie client (client qui ne connaissait pas encore ce serveur), le serveur décide alors, selon sa politique à lui, de laisser tomber la requête (c'est violent, et cela implique de configurer le serveur avec les cookies des clients), d'envoyer un code d'erreur BADCOOKIE (valeur 23), incluant le cookie du serveur, ou enfin de répondre normalement, en ajoutant son cookie. En effet, dans ce cas, le client n'est pas « authentifié ». On n'a pas vérifié son adresse IP source. Il peut donc être justifié de ne pas donner la réponse tout de suite (le BADCOOKIE) ou bien, par exemple, de limiter le trafic de ce client (comme on le fait aujourd'hui, avant les cookies, puisqu'on n'est jamais sûr de l'adresse IP du client).
  • Il y a deux cookies dans la requête mais le cookie serveur est incorrect, par exemple parce que le secret utilisé par le serveur a changé. C'est parfaitement normal et cela n'indique, ni une erreur, ni une attaque, simplement qu'on ne peut pas authentifier le client. On répond donc comme dans le cas précédent (avec trois choix, dont seuls les deux derniers sont réalistes).
  • Il y a deux cookies dans la requête et le cookie serveur est correct. On a donc une certitude raisonnable que le client n'a pas usurpé son adresse IP (puisqu'il a reçu le bon cookie du serveur) et on va donc lui répondre. Les mesures de méfiance comme la limitation de trafic peuvent être débrayées pour cette requête.

Lorsqu'il reçoit une réponse, le client doit mémoriser le cookie du serveur. C'est particulièrement important la première fois, lorsque le client n'est pas encore authentifié. Si la réponse était BADCOOKIE, cela veut dire qu'on a affaire à un serveur grognon qui ne veut pas répondre sans qu'on lui donne un cookie correct : on retransmet alors la requête, cette fois en incluant le cookie transmis par le serveur.

Voilà, c'est tout. Avec ce système, on a une authentification légère et simple de l'adresse IP du client. Dans la vraie vie, il y aura peut-être quelques problèmes pratiques, que couvre la section 6 de notre RFC. Par exemple, si le client est derrière du NAT (RFC 3022), un méchant situé sur le même réseau local que lui pourrait faire une requête au serveur, obtenir le cookie du serveur et envoyer ensuite des requêtes en usurpant l'adresse IP locale du client légitime. Le serveur ne peut pas distinguer ces deux clients, le bon et le méchant. C'est pour cela que le cookie serveur inclut dans les paramètres de sa fonction le cookie du client. Ainsi, les deux machines, la gentille et la méchante auront des cookies serveur différents.

Un problème du même genre (plusieurs machines derrière une même adresse IP) pourrait survenir côté serveur, par exemple en raison de l'anycast. Mais on ne peut pas appliquer la même solution : si le cookie serveur dépend du cookie client et le cookie client du cookie serveur, on a une boucle sans fin. Le serveur doit donc se débrouiller : soit avoir le même secret (et donc les mêmes cookies) sur toutes les machines (c'est l'approche la plus simple, et c'est celle recommandée par le RFC), soit faire en sorte qu'un client donné arrive toujours sur la même machine.

D'autres considérations pratiques figurent en section 7, notamment sur le remplacement d'un secret (ce qui invalidera les cookies précédemment distribués).

Et quelques discussions sur la sécurité, pour finir (section 9 du RFC). L'« authentification » fournie par les cookies est faible : elle ne protège pas contre un attaquant situé sur le chemin de communication entre client et serveur, lorsqu'il peut lire le trafic. Dans ce cas, l'attaquant a en effet accès au cookie et peut facilement le rejouer. Par exemple, si on est connecté à un réseau Wi-Fi public sans sécurité (pas de WPA), n'importe quel client du même réseau peut voir passer les cookies. Néanmoins, les cookies réduisent quand même sérieusement l'ampleur du problème. Une attaque (l'usurpation d'adresse IP) que tout l'Internet pouvait faire est maintenant restreinte à un sous-ensemble de l'Internet. Si cela est encore trop, il faut passer à une sécurisation cryptographique comme celle que fournit le RFC 7858.

L'algorithme utilisé pour calculer les cookies est évidemment crucial. Il n'a pas besoin d'être normalisé, puisque seule la machine qui émet le cookie original a besoin de le comprendre. Mais il doit garantir des cookies très difficiles à prévoir par un attaquant. On peut par exemple utiliser SHA-256 (RFC 6234, mais il n'y a pas forcément besoin de cryptographie top canon, les cookies n'étant qu'une authentification faible, de toute façon). Depuis la parution de notre RFC, le RFC 9018 a décrit un algorithme recommandé si des serveurs veulent être compatibles, par exemple s'ils font partie du même service anycast.

Des exemples d'algorithmes figurent dans les annexes A et B (mais le RFC 9018 en a abandonné certains). Pour le client DNS, un algorithme simple serait d'appliquer la fonction simple et rapide FNV-64 à la concaténation des adresses IP du client et du serveur, et du secret. Un algorithme plus compliqué, mais plus sûr, serait de remplacer FNV par SHA-256, plus coûteux.

Pour le serveur, l'algorithme simple serait un FNV-64 de la concaténation de l'adresse IP du client, du cookie du client, et du secret. Pour l'algorithme compliqué, on peut tirer profit de la longueur plus grande du cookie serveur pour y mettre davantage d'informations : par exemple, huit octets calculés comme dans l'algorithme simple suivis de l'heure de génération du cookie (pour détecter plus facilement les vieux cookies, avant même toute opération cryptographique).

Et les mises en œuvre ? Les cookies sont gérés par BIND à partir de la version 9.11 (pas encore officiellement publiée). Ils sont activés par défaut. Et Wireshark sait les afficher. Ici, un client nouveau (il ne connait pas encore le cookie serveur) :


No.     Time           Source                Destination           Protocol Length Info
      1 0.000000       192.168.2.9           192.168.2.7           DNS      97     Standard query 0x0000 SOA foobar.example OPT
...
Domain Name System (query)
...
    Additional records
        <Root>: type OPT
...
        Data length: 12
            Option: COOKIE
                Option Code: COOKIE (10)
                Option Length: 8
                Option Data: fb40ce9a68a6f1f0
                Client Cookie: fb40ce9a68a6f1f0
                Server Cookie: <MISSING>


No.     Time           Source                Destination           Protocol Length Info
      2 0.003910       192.168.2.7           192.168.2.9           DNS      200    Standard query response 0x0000 SOA foobar.example SOA ns1.foobar.example NS ns1.nic.fr NS ns2.nic.fr OPT
...
      Additional records
        <Root>: type OPT
...
        Data length: 28
            Option: COOKIE
                Option Code: COOKIE (10)
                Option Length: 24
                Option Data: fb40ce9a68a6f1f0727e7501575acc5977ced0351ad20d56
                Client Cookie: fb40ce9a68a6f1f0
                Server Cookie: 727e7501575acc5977ced0351ad20d56

L'algorithme de condensation peut être choisi mais, apparemment, uniquement à la compilation (avec --with-cc-alg=ALGALG vaut aes|sha1|sha256).

Le dig livré avec cette version de BIND peut passer des cookies :

% dig +cookie @192.168.2.7 foobar.example
...
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; COOKIE: 51648e4b14ad9db8eb0d28c7575acbdde8f541a0cb52e2c2 (good)
;; QUESTION SECTION:
;foobar.example.                IN A
...
     

Pour les programmeurs en Go, la bibliothèque Go DNS gère désormais les cookies. Un exemple de code Go pour les envoyer :

     
	m := new(dns.Msg)
	m.Question = make([]dns.Question, 1)
	c := new(dns.Client)
	m.Question[0] = dns.Question{zone, dns.TypeSOA, dns.ClassINET}
	o := new(dns.OPT)
	o.Hdr.Name = "."
	o.Hdr.Rrtype = dns.TypeOPT
	o.Hdr.Class = 4096
	e := new(dns.EDNS0_COOKIE)
	e.Code = dns.EDNS0COOKIE
	e.Cookie = "fb40ce9a68a6f1f0"
	o.Option = append(o.Option, e)
	m.Extra = make([]dns.RR, 1)
	m.Extra[0] = o

Téléchargez le RFC 7873


L'article seul

RFC 7872: Observations on the Dropping of Packets with IPv6 Extension Headers in the Real World

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : F. Gont (SI6 Networks / UTN-FRH), J. Linkova (Google), T. Chown (University of Southampton), W. Liu (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 5 juillet 2016


Normalement, l'Internet est un monde idéal où la machine d'Alice peut envoyer à celle de Bob les paquets qu'elle veut, Bob les recevra intacts (s'il le veut). Dans la réalité, pas mal de machines intermédiaires ne respectent pas ce principe de bout en bout. Il est fréquent que les paquets « inhabituels » soient jetés en route. Cela peut être le résultat d'une politique délibérée (pare-feu appliquant le principe « dans le doute, on jette ») ou bien, souvent, de l'incompétence des programmeurs qui n'ont pas lu les RFC et ne connaissent pas telle ou telle option. Par exemple, IPv6 permet d'ajouter au paquet, entre l'en-tête proprement dit et la charge utile du paquet, un ou plusieurs en-têtes d'extension. C'est rare en pratique. Est-ce que les programmeurs des middleboxes ont fait attention à cette possibilité ? Les paquets ayant ces en-têtes d'extension ont-ils de bonne chances d'arriver au but ? Ce nouveau RFC est un compte-rendu de mesures effectuées dans l'Internet pour essayer de quantifier l'ampleur exacte du problème.

Un point important du travail effectué par les auteurs du RFC est qu'ils ne sont pas contentés de chercher si les paquets étaient jetés mais également ils étaient jetés. La différence est politiquement cruciale. Si le paquet IPv6 portant un en-tête d'extension est jeté par la machine de Bob, car Bob n'aime pas ces en-têtes et il a configuré son Netfilter pour les envoyer vers DROP, pas de problème : Bob est libre d'accepter ou de refuser ce qu'il veut. Si, par contre, le paquet a été jeté par le FAI d'Alice ou de Bob, ou, encore pire, par un opérateur de transit entre les deux FAI, c'est grave, c'est une violation de la neutralité du réseau, violation qui empêche deux adultes consentants de s'envoyer les paquets qu'ils veulent. Le mécanisme de mesure cherche donc à trouver dans quel AS le paquet a disparu.

Les mesures ont été faites en août 2014 et juin 2015. Le RFC détaille suffisamment la façon dont elles ont été faites (annexe A) pour qu'une autre équipe puisse recommencer les mesures à une date ultérieure, pour voir si la situation s'améliore.

Les en-têtes d'extension IPv6 sont décrits dans le RFC 2460, section 4. Ils sont de deux plusieurs sortes, entre autre :

  • L'en-tête de fragmentation, qui doit pouvoir passer si on veut que les paquets IP fragmentés arrivents (les principaux émetteurs de paquets IPv6 fragmentés sont sans doute les serveurs DNS, notamment avec DNSSEC, car UDP ne négocie pas la MSS).
  • L'en-tête « Options pour la destination » (Destination Options) qui, comme son nom l'indique, ne doit pas être examiné par les routeurs sur le chemin. Il contient des informations pour la machine terminale de destination.
  • L'en-tête « Options pour chaque intermédiaire » (Hop-by-Hop Options) qui, comme son nom l'indique, doit être examiné par les routeurs sur le trajet, il contient des informations pour eux.

Outre la fragmentation, un exemple d'utilisation de ces en-têtes est le protocole CONEX (RFC 7837). Si vous voulez ajouter des options pour la destination dans un paquet IPv6, vous pouvez regarder mon tutoriel.

Quelles sont les chances de survie des paquets portant ces en-têtes d'extension dans le sauvage Internet ? Des études comme « Discovering Path MTU black holes on the Internet using RIPE Atlas », « Fragmentation and Extension header Support in the IPv6 Internet » ou bien « IPv6 Extension Headers in the Real World v2.0 » s'étaient déjà penchées sur la question. Les mesures de ce RFC détaillent et complètent ces résultats préliminaires, notamment sur la différenciation entre perte de paquet près de la destination, et perte du paquet en transit. La conclusion est, qu'hélas, les paquets IPv6 portant des en-têtes d'extension font effectivement l'objet d'une discrimination négative (« entêtophobie » ?).

Donc, qu'est-ce que ça donne dans l'Internet réel (section 2) ? Deux listes de serveurs IPv6 ont été utilisées, celle du World IPv6 Launch Day et le premier million d'Alexa. De ces listes de domaines ont été extraits les adresses IP des sites Web (dig AAAA LE-DOMAINE et, oui, je sais que c'est un sérieux raccourci de supposer que tout domaine a un serveur Web à l'apex), des relais de messagerie (dig MX LE-DOMAINE puis obtenir l'adresse IPv6 des serveurs), et des serveurs de noms (dig NS LE-DOMAINE). Les adresses absurdes (::1...) ont été retirées. Ensuite, pour chaque adresse ainsi obtenue, trois types de paquets ont été envoyés :

  • Un avec en-tête d'extension Destination Options,
  • Un avec en-tête d'extension Hop-by-hop Options,
  • Un fragmenté en deux fragments d'à peu près 512 octets.

Les paquets étaient tous du TCP à destination d'un port correspondant au service (25 pour les serveurs de messagerie, par exemple).

Un point très important et original de cette expérience était la recherche d'information sur se produisait l'éventuelle perte de paquets (dans quel AS). L'hypothèse de base est qu'une élimination du paquet dans l'AS de destination peut être acceptable, parce qu'elle résulte d'une décision consciente du destinataire. En tout cas, il sera plus facile de changer la politique de l'AS de destination. En revanche, une élimination dans un AS intermédiaire est inacceptable : elle indique filtrage ou erreur de configuration dans un réseau qui devrait être neutre. Notez que l'hypothèse n'est pas parfaite : si un particulier héberge un serveur chez lui et que son FAI filtre les paquets IPv6 avec en-tête d'extension, c'est quand même inacceptable, et c'est difficile pour le particulier de le faire corriger.

Comment identifier l'AS qui jette le paquet ? L'idée est de faire l'équivalent d'un traceroute (en fait, deux, un avec l'en-tête de destination et un sans, pour comparer : cf. annexe B.1) et de voir quel est le dernier routeur qui a répondu. C'est loin d'être idéal. Des routeurs ne répondent pas, pour d'autres, il est difficile d'évaluer à quel AS ils appartiennent (dans un lien de peering entre deux acteurs A et B, les adresses IP utilisées ont pu être fournies par A ou bien par B ; cf. annexe B.2). Et l'absence d'un routeur dans le résultat de traceroute ne prouve pas que le routeur n'a pas transmis le paquet juste avant. La mesure indique donc deux cas, l'optimiste, où on suppose, en l'absence de preuve opposée, que les paquets manquant ont été jetés par l'AS de destination et le pessimiste où on fait la supposition inverse.

Les résultats complets des mesures figurent dans le RFC. Je résume ici une partie. Pour les serveurs Web de la liste du World IPv6 Launch Day :

  • 12 % des serveurs n'ont pas reçu le paquet envoyé avec un en-tête Destination Options. Entre 18 % (optimiste) et 21 % (pessimiste) de ces pertes se sont produites avant l'AS de destination.
  • 41 % des serveurs n'ont pas reçu le paquet envoyé avec un en-tête Hop-by-hop Options. Entre 31 % (optimiste) et 40 % (pessimiste) de ces pertes se sont produites avant l'AS de destination.
  • 31 % des serveurs n'ont pas reçu le paquet fragmenté. Entre 5 % (optimiste) et 7 % (pessimiste) de ces pertes se sont produites avant l'AS de destination.

Les résultats ne sont guère différents pour les autres services (comme SMTP), indiquant que le problème, quand il est présent, est bien dans la couche 3. Idem avec le jeu de données Alexa : peu de différences.

On voit que les paquets utilisant l'en-tête d'extension « Options pour chaque intermédiaire » sont ceux qui s'en tirent le plus mal (c'est un peu logique, cet en-tête étant censé être examiné par tous les routeurs intermédiaires). Les fragments passent assez mal également. Enfin, on note qu'un pourcentage significatif des paquets sont jetés par un AS de transit, qui viole ainsi massivement le principe de bout en bout. Triste état de l'Internet actuel, pourri de middleboxes qui se permettent tout.

Si vous voulez refaire l'expérience vous-même, pour contrôler les résultats, ou bien pour mesurer l'évolution dans quelque temps, l'annexe A vous donne les éléments nécessaires. Vous aurez besoin du toolkit de SI6. Les données d'Alexa sont disponibles en ligne. L'outil script6 dans le toolkit SI6 permet d'obtenir les adresses IP nécessaires. Par exemple :

% cat top-1m.txt | script6 get-mx | script6 get-aaaa
    

Et on obtient ainsi les adresses IP des relais de messagerie. Pour supprimer les adresses incorrectes (par exemple ::1), on utilise l'outil addr6 du toolkit :

%  cat top-1m-mail-aaaa.txt | addr6 -i -q -B multicast -B unspec -k global     
    

Il n'y a plus maintenant qu'à envoyer les paquets portant les en-têtes d'extension, ou fragmentés. Ici, les serveurs de messagerie avec l'en-tête Destination Options (« do8 ») :

% cat top-1m-mail-aaaa-unique.txt | script6 trace6 do8 tcp 25      
    

L'annexe B de notre RFC contient quelques avertissements méthodologiques.

Un traceroute ordinaire ne suffit pas à faire les mesures décrites plus haut pour identifier le routeur responsable d'une perte de paquet (le traceroute ordinaire ne permet pas d'ajouter l'en-tête d'extension aux paquets utilisés). Il faut utiliser un outil spécial comme le path6 du toolkit SI6. Encore plus simple, dans le même paquetage, l'outil blackhole6. Voyons d'abord path6 pour comprendre les détails :

% sudo path6  -d yeti.ipv6.ernet.in 
Tracing path to yeti.ipv6.ernet.in (2001:e30:1c1e:1::333)...

  1 (2001:4b98:dc0:41::250)   1.1 ms   0.5 ms   0.4 ms
  2 (2001:4b98:1f::c3d3:249)   1.2 ms   3.5 ms   3.4 ms
  3 (2001:7f8:54::173)   1.1 ms   0.8 ms   0.6 ms
  4 (2001:1a00:1:cafe::e)  141.3 ms  140.7 ms  140.6 ms
  5 (2001:1a00:1:cafe::145)  118.8 ms  118.8 ms  119.5 ms
  6 (2001:1a00:1:cafe::141)  140.7 ms  137.2 ms  137.3 ms
  7 (2001:1a00:1:cafe::10b)  144.0 ms  144.3 ms  144.1 ms
  8 (2001:1a00:1:cafe::212)  140.5 ms  140.5 ms  140.5 ms
  9 (2001:1a00:1:cafe::207)  137.0 ms  137.0 ms  136.9 ms
 10 (2001:1a00:acca:101f::2)  136.5 ms  136.4 ms  136.5 ms
 11 (2001:4528:ffff:ff04::1)  152.2 ms  152.1 ms  152.2 ms
 12 (2001:4528:fff:c48::1)  163.6 ms  163.7 ms  163.6 ms
 13 (2001:e30:1c1e::1)  162.6 ms  162.3 ms  162.2 ms
 14 (2001:e30:1c1e:1::333)  174.5 ms  175.1 ms  175.2 ms
    

OK, on arrive à joindre la machine en Inde. Maintenant, ajoutons l'en-tête Hop-by-Hop Options :

% sudo path6 --hbh-opt-hdr 8 -d yeti.ipv6.ernet.in
Tracing path to yeti.ipv6.ernet.in (2001:e30:1c1e:1::333)...

  1 (2001:4b98:dc0:41::250)  20.9 ms  20.0 ms  19.0 ms
  2 (2001:4b98:1f::c3d3:249)  20.8 ms  20.2 ms  18.5 ms
  3 (2001:4b98:1f::c3c4:3)  20.7 ms  20.4 ms  18.5 ms
  4 (2001:1a00:1:cafe::e)  154.3 ms  14.4 ms  152.1 ms
  5 (2001:1a00:1:cafe::e)  151.0 ms  129.6 ms  148.9 ms
  6 (2001:1a00:1:cafe::141)  151.2 ms  126.2 ms  148.8 ms
  7 (2001:1a00:1:cafe::141)  156.5 ms  156.8 ms  158.6 ms
  8 (2001:1a00:1:cafe::212)  153.6 ms  191.2 ms  151.4 ms
  9 (2001:1a00:1:cafe::212)  155.3 ms  151.1 ms  157.7 ms
 10 (2001:1a00:1:cafe::207)  *  155.619995 ms *
 11 ()   *  *  *
 12 ()   *  *  *
 13 ()   *  *  *
 ...
    

Aïe, ça n'arrive plus. Le routeur situé après 2001:1a00:1:cafe::207 a jeté le paquet. En comparant les deux path6, on peut voir que le coupable est 2001:1a00:acca:101f::2 (Flag, désormais une marque de Reliance). L'outil blackhole6 fait tout ce travail automatiquement (EH = Extension Header, HBH 8 = Hop-by-Hop, size 8) :

% sudo blackhole6 yeti.ipv6.ernet.in hbh8         
SI6 Networks IPv6 Toolkit v2.0 (Guille)
blackhole6: A tool to find IPv6 blackholes
Tracing yeti.ipv6.ernet.in (2001:e30:1c1e:1::333)...

Dst. IPv6 address: 2001:e30:1c1e:1::333 (AS2697 - ERX-ERNET-AS Education and Research Network, IN)
Last node (no EHs): 2001:e30:1c1e:1::333 (AS2697 - ERX-ERNET-AS Education and Research Network, IN) (14 hop(s))
Last node (HBH 8): 2001:1a00:1:cafe::207 (AS15412 - FLAG-AS Flag Telecom Global Internet AS, GB) (10 hop(s))
Dropping node: 2001:1a00:acca:101f::2 (AS15412 - FLAG-AS Flag Telecom Global Internet AS, GB || AS Unknown - Unknown)
    

Sur ce sujet et ces tests, on peut aussi regarder l'exposé de Mehdi Kouhen au symposium Polytechnique/Cisco, ou bien celui d'Eric Vyncke à Protosec à Buenos Aires.


Téléchargez le RFC 7872


L'article seul

RFC 7871: Client Subnet in DNS Queries

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : C. Contavalli, W. van der Gaast (Google), D. Lawrence (Akamai Technologies), W. Kumari (Google)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 20 juin 2016
Dernière mise à jour le 13 juin 2022


Ce nouveau RFC décrit une option EDNS qui permet à un client DNS d'indiquer au serveur l'adresse IP d'origine de la requête DNS. Pourquoi diable ferait-on cela, au prix de la vie privée ? Cette option est surtout utile dans le cas de l'utilisation d'un gros résolveur DNS public (comme Google Public DNS) et d'un CDN.

Pour comprendre pourquoi, il faut se rappeler que le DNS ne fonctionne pas de bout en bout. La machine de M. Michu émet des requêtes DNS à un résolveur (en général fourni par le FAI ou par le réseau local, mais certaines personnes, victimes du marketing, préfèrent les résolveurs publics comme OpenDNS, plus lointains et plus lents). Ce résolveur, à son tour, interroge les serveurs faisant autorité. Si M. Michu voulait se connecter à un site Web pour voir des vidéos de chats, il est possible qu'un nouvel acteur soit présent, le CDN (comme Akamai) qui héberge les dites vidéos. Les serveurs DNS faisant autorité pour le CDN renvoient souvent une adresse IP différente selon l'adresse IP du résolveur qui les interroge. Si l'adresse IP du client est au Sénégal, l'adresse IP du serveur de vidéos qui sera renvoyée sera celle du centre de données le plus « proche » du Sénégal. En temps normal, cela fonctionne plus ou moins. Bien sûr, le serveur DNS faisant autorité pour le CDN ne voit pas le « vrai » client, M. Michu, il voit le résolveur DNS utilisé mais les deux sont proches : si M. Michu est en Colombie, son résolveur DNS le sera aussi. Voici un exemple, vu avec les sondes RIPE Atlas, où on demande, au Sénégal (SN) puis en Colombie (CO) l'adresse IP de www.elysee.fr, hébergé sur un CDN états-unien :

% blaeu-resolve --country SN www.elysee.fr
[207.123.59.254 209.84.7.126 8.27.7.254] : 1 occurrences 
[209.84.7.126 8.253.3.254 8.27.7.254] : 1 occurrences 
[4.26.233.254 4.26.236.126 8.254.119.126] : 1 occurrences 
[207.123.59.254 209.84.7.126 8.253.3.254] : 1 occurrences 
[207.123.59.254 8.26.223.254 8.27.7.254] : 1 occurrences 
Test #4106632 done at 2016-06-15T22:52:44Z

% blaeu-resolve --country CO www.elysee.fr
[192.221.116.253] : 3 occurrences 
[205.128.71.253 4.27.25.125 8.27.155.126] : 1 occurrences 
[206.33.52.253 209.84.20.126 8.253.16.126] : 1 occurrences 
Test #4106633 done at 2016-06-15T22:52:46Z
  

On voit qu'on a obtenu des adresses IP très différentes et, espérons-le, adaptées à chaque pays.

Autre exemple, avec un service de PowerDNS, qui renvoyait (il semble ne plus marcher) une géolocalisation du client. Ici, j'utilise dig depuis deux machines différentes, une en France et l'autre aux États-Unis :

%  dig +short -t txt www.geo.powerdns.com 
"bonjour france 2a01:db8:8bd9:85cb:21e:8cff:fe76:29b6/26"

% dig +short -t txt www.geo.powerdns.com 
"hello USA 204.62.14.153/22"

On voit que le résolveur que j'utilise (qui, à chaque fois, était sur le réseau local de la machine cliente), a bien été géolocalisé. Si j'utilise un résolveur public :

%  dig @8.8.8.8 +short -t txt www.geo.powerdns.com  
"bonjour france XX.YY.152.0/11"

Ici, cela a marché car Google Public DNS a des serveurs en France. Si cela n'avait pas été le cas, j'aurais été géolocalisé... quelque part ailleurs.

Tout change (section 1 du RFC) si on utilise un résolveur DNS public comme Verisign Public DNS ou bien Yandex DNS. Dans ce cas, l'adresse IP du résolveur, vue par le serveur faisant autorité pour le CDN, n'a plus grand'chose à voir avec celle du vrai client, elle peut être très lointaine. Les serveurs DNS faisant autorité risquent donc de renvoyer une adresse IP de serveur Web qui ne soit pas optimale. Certes, tout marchera quand même mais ça sera plus lent alors qu'officiellement, le but des CDN est d'accélerer l'arrivée de la vidéo du chat (non, de François Hollande).

On voit que ce RFC résout donc un problème que n'a pas tout le monde. Seuls ceux qui se servent d'un résolveur public lointain, et qui visitent des sites Web hébergés sur un CDN (en général les gros sites commerciaux) auront le problème. C'est une des raisons qui expliquent que ce RFC a pas mal trainé (voyez cet article, qui date de plusieurs années) à l'IETF : son intérêt n'est pas évident, et il y avait beaucoup de contestation. Mais l'IETF a finalement choisi de documenter cette option (qui est effectivement déployée), sans forcément la recommander.

Donc, comment est-ce que cela résout le problème décrit plus haut ? L'idée est de standardiser une option EDNS que les résolveurs publics ajouteront dans leur requête aux serveurs faisant autorité, et qui indiquera la « vraie » adresse IP d'origine (section 5 du RFC). Imaginons que M. Michu ait pour adresse IP 192.0.2.56 et qu'il utilise Google Public DNS. Ce dernier va transmettre la requête au CDN et ajoutera l'option Client Subnet (ce n'est donc pas M. Michu qui le fera). Le serveur DNS du CDN verra une requête arriver de, mettons, 74.125.17.1. L'option EDNS Client Subnet contiendra le préfixe de l'adresse IP de M. Michu, 192.0.2.0/25. Il saura alors qu'il doit adapter ses réponses, non pas au préfixe 74.125.17.0/24 (son client direct) mais au préfixe 192.0.2.0/25 (le vrai client). C'est donc une option entre résolveur et serveur faisant autorité, pas entre machine terminale et résolveur.

Le format de l'option est décrite dans la section 6 du RFC. Comme toutes les options EDNS (RFC 6891), elle est encodée en TLV : le type est 8, la valeur est composée de :

  • La famille d'adresses utilisée (IPv4 ou IPv6, l'exemple ci-dessus utilisait IPv4),
  • La longueur du préfixe indiqué dans la requête DNS (25 bits dans l'exemple ci-dessus),
  • La longueur significative du préfixe dans la réponse DNS (elle est mise à zéro dans les requêtes),
  • Le préfixe lui-même (192.0.2.0 dans l'exemple plus haut).

La section 7 du RFC décrit les détails du protocole. Le résolveur va mettre dans son cache les réponses du serveur faisant autorité. Normalement, l'information dans le cache est indexée par le nom de domaine (et le type de données demandé, mais je simplifie). Avec ECS (EDNS Client Subnet), l'information est indexée par le couple {nom de domaine, préfixe IP}. En effet, deux requêtes pour le même nom peuvent avoir donné des résultats différents selon le préfixe IP (c'est bien le but !).

Le résolveur qui met cette option doit choisir la longueur du préfixe envoyé. Il tient compte de deux choses :

  • La capacité de son cache : si le préfixe est trop spécifique, le cache devra stocker davantage de données (imaginons en IPv6 une réponse différente par adresse IP : le cache pourrait avoir à stocker 2^128 réponses par nom de domaine !)
  • La protection de la vie privée des utilisateurs. ECS la menace déjà, n'aggravons pas les choses. En utilisant un préfixe assez général, on limite l'indiscrétion.

Mais l'affaire est un peu plus compliquée : le client d'origine (la machine de M. Michu, le stub resolver) a pu mettre une option ECS elle-même (ce n'est pas courant aujourd'hui mais ça pourrait arriver). Dans ce cas, le résolveur doit en tenir compte et mettre comme longueur la plus courte entre celle demandée par le client (a priori pour protéger sa vie privée) et celle que le résolveur aurait choisi tout seul.

Si la requête reçue par le résolveur avait l'option ECS et une longueur de zéro, cela indique le souhait du client qu'on ne transmette pas son adresse IP du tout. Le résolveur doit évidemment respecter cette demande.

Et le serveur faisant autorité, que doit-il mettre dans sa réponse ? (S'il envoie des réponses différentes selon la source, et s'il gère l'option ECS, EDNS Client Subnet ; autrement, c'est simple, il ne fait rien de particulier.) Il met une option ECS dans la réponses, avec :

  • La famille, la longueur du préfixe demandé, et le préfixe identiques à celui de la requête,
  • Une longueur effective (scope prefix length) qui indique pour quel préfixe la réponse est valable. Cette longueur effective peut être supérieure à la longueur demandée (le préfixe était trop général, pense le serveur), ou inférieure (le préfixe était inutilement spécifique, le serveur ne varie pas ses réponses à ce point).

(Notez que le RFC est bien plus détaillé que ce résumé, car il y a plein de cas rigolos. Je me suis limité à une présentation générale, je n'essaie pas de traduire tout le RFC.)

En recevant cette réponse, le résolveur va la mettre dans son cache, en tenant compte de la longueur du préfixe (et, bien sûr, le résolveur transmet la réponse à son client). Une réponse valable pour 2001:db8:43:bef::/64 ne pourra pas être utilisée pour le client 2001:db8:43:bed::1. Quelle longueur sera utilisée pour indexer le cache ? Celle demandée ou bien celle effective ? Les régles exactes sont un peu complexes (il faut tenir compte de la longueur effective, mais aussi des limites du cache, qui ne veut pas stocker une réponse pour des préfixes trop spécifiques), je vous renvoie à la section 7.3.1 du RFC.

Les questions ultérieures des clients du résolveur pourront recevoir une réponse tirée du cache, sans repasser par les serveurs faisant autorité. Mais ECS impose d'organiser le cache différemment. Avec le DNS classique, si on a dans le cache la réponse à une question pour cat.example.com (je simplifie en ne tenant pas compte du type des données DNS), et qu'on reçoit une question pour ce nom, on peut répondre avec les données du cache. Avec ECS, le cache doit en plus tenir compte du préfixe stocké avec la réponse, et de l'adresse IP du client.

Et avec DNSSEC, ça se passe comment (section 9 du RFC) ? Les CDN ne signent pas leur zone en général. Mais s'ils s'y mettent (il le faudrait), il y aura quelques précautions à prendre.

Et avec le NAT ? Il n'y a normalement pas de problèmes, sauf évidemment si le résolveur est NATé et ne le sait pas : il mettrait, dans ce cas, une adresse privée dans l'option ECS, ce qui serait idiot.

Reste à regarder les problèmes de sécurité et notamment de vie privée. ECS diminue forcément votre vie privée. Il ajoute en effet une information qui n'était pas là sans lui (et le RFC 8165 dit bien que c'est mal). C'est pour limiter les dégâts que le RFC recommande aux résolveurs qui ajoutent une option Client Subnet de la limiter aux 24 premiers bits en IPv4 et aux 56 premiers en IPv6. Un résolveur qui connait bien la topologie de son réseau peut faire encore mieux : s'il sait que tous ses clients sont proches, et couverts par le même /20, il peut ainsi ne transmettre que les vingt premiers bits, sans diminuer l'intérêt du service.

Notez que, avec les clients DNS d'aujourd'hui, votre résolveur mettra votre adresse IP dans ses requêtes sortantes. On peut en sortir (opt-out en mettant une option ECS avec une longueur nulle) mais cela nécessite une action explicite (que ne permettent pas forcément les clients DNS actuels, notamment les stub resolvers, ceux qui sont intégrés dans le système d'exploitation). Le RFC recommande donc que cette option ECS soit désactivée par défaut, en raison de ces risques.

L'option ECS peut être vue par les serveurs faisant autorité, mais également par les tiers qui espionnent le trafic. Pour empêcher cela, il faudra déployer des solutions de chiffrement du trafic DNS, comme celles sur lesquelles travaille le groupe DPRIVE.

Un bon article sur les problèmes de vie privée liés à ECS est le « Understanding the Privacy Implications of ECS » de Panagiotis Kintis, Yacin Nadji, David Dagon, Michael Farrell et Manos Antonakakis. Un autre bon article sur cette question est celui de Frank Denis.

Voyons maintenant cette option ECS en action. Elle est par exemple utilisée par Google dont le résolveur public ajoute cette option avant de l'envoyer aux serveurs faisant autorité. Mais on trouve une liste d'utilisateurs plus détaillée sur le site de promotion de la technologie.

Parmi les logiciels libres qui la mettent en œuvre, on note la bibliothèque getdns. Ou bien le programme dig livré avec BIND. Voici un exemple avec la nouvelle option +subnet de dig (prise sur un BIND 9.11, l'option était déjà en 9.10) :

% dig +subnet=8.189.152.0/25 @ns-1568.awsdns-04.co.uk  A www.amazon.com 
...
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; CLIENT-SUBNET: 8.189.152.0/25/0
...
;; ANSWER SECTION:
www.amazon.com.         60 IN A 54.239.25.192
...

Et ce que voit le serveur faisant autorité ? On peut le savoir en faisant tourner tcpdump sur un serveur faisant autorité qu'on contrôle, mais il y a plus simple, utiliser un domaine dont les serveurs faisant autorité renverront l'information ECS qu'ils ont reçu. J'en connais trois, qui répondent aux requêtes DNS de type TXT :

  • _country.pool.ntp.org,
  • whoami​.​fastly​.​net et whoami​6.​fastly​.​net,
  • et mon ecs.dyn.bortzmeyer.fr (qui utilise le logiciel Drink).

Voici un exemple :


% dig ecs.dyn.bortzmeyer.fr TXT
...
;; ANSWER SECTION:
ecs.dyn.bortzmeyer.fr.	0 IN TXT "78.196.62.0/24"

;; Query time: 15 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: lun. juin 13 14:08:23 CEST 2022

    

Un service analogue, edns-client-sub.net renvoie sous forme d'un objet JSON les options ECS reçues, ainsi que la géolocalisation. Ici, mon résolveur n'envoie pas ECS :

% dig +short -t txt edns-client-sub.net
"{'ecs':'False','ts':'1447875683.94','recursive':{'cc':'FR','srcip':'XX.YY.152.187','sport':'37512'}}"

Mais Google, lui, le fait (et heureusement, sinon j'aurais été géolocalisé en Belgique, où se trouve le serveur de Google utilisé) :

% dig @8.8.8.8 +short -t txt edns-client-sub.net 
"{'ecs_payload':{'family':'1','optcode':'0x08','cc':'FR','ip':'XX.YY.152.0','mask':'24','scope':'0'},
     'ecs':'True','ts':'1447875689.25','recursive':{'cc':'BE','srcip':'74.125.47.152','sport':'41735'}}"

Mais ce service ne semble plus fonctionner, en juin 2022.

Enfin, voici un exemple de code Python qui coupe ECS chez le résolveur, pour protéger la vie privée de l'utilisateur. Il utilise la bibliothèque dnspython :

opt = dns.edns.ECSOption(address='', srclen=0) # Disable ECS (RFC 7871, section 7.1.2)
options = [opt]
message = dns.message.make_query(qname, dns.rdatatype.from_text(qtype),
       use_edns=True, options=options)
    

Téléchargez le RFC 7871


L'article seul

RFC 7858: Specification for DNS over Transport Layer Security (TLS)

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : Z. Hu, L. Zhu, J. Heidemann (USC/Information Sciences Institute), A. Mankin, D. Wessels (Verisign Labs), P. Hoffman (ICANN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dprive
Première rédaction de cet article le 18 mai 2016


Traditionnellement, les requêtes DNS voyageaient sur le réseau en clair, visibles par tous. Ce n'est évidemment plus acceptable, notamment depuis les révélations de Snowden, et ce RFC normalise donc un mécanisme, DoT (DNS over TLS) qui permet de chiffrer les requêtes DNS pour en assurer la confidentialité vis-à-vis d'un éventuel surveillant.

Le chiffrement est le deuxième pilier de la protection des données, après la minimisation des données (qui, pour le DNS, est spécifiée dans le RFC 9156). Ce chiffrement est motivé notamment par le développement de la surveillance de masse (RFC 7258), par le souci de protéger la vie privée (RFC 6973) et par la prise de conscience des risques spécifiques au DNS (RFC 7626).

Il y avait plusieurs choix possibles pour le groupe de travail DPRIVE qui a produit ce RFC. Il pouvait utiliser une technique extérieure à l'IETF comme DNSCrypt. Il pouvait s'appuyer sur un protocole existant comme IPsec ou TLS. Et il pouvait développer un nouveau protocole (plusieurs propositions avaient été faites en ce sens). Finalement, le choix s'est porté sur un protocole facile à déployer, bien connu, et éprouvé, TLS. D'où le surnom de DoT (DNS over TLS) pour ce protocole. Pour résumer techniquement ce RFC (section 1) : on met les requêtes DNS sur un canal TLS lui-même évidemment transporté sur TCP. (Le groupe DPRIVE travaille également sur une future solution utilisant DTLS et donc UDP.) Outre la confidentialité, TLS permet de protéger les données contre une modification en cours de route.

Notons au passage que DNSSEC ne résout pas ces problèmes : son but est d'authentifier les réponses, pas de protéger contre l'espionnage.

Il y a deux liens à protéger dans une requête DNS, celui entre la machine de l'utilisateur et le résolveur, et celui entre le résolveur et les serveurs faisant autorité. La charte du groupe DPRIVE précisait qu'il fallait d'abord s'attaquer au premier problème, plus facile (une machine ne parle qu'à peu de résolveurs, et elle a une relation avec eux, alors qu'un résolveur parle à beaucoup de serveurs faisant autorité, qu'il ne connait pas.)

La section 3 décrit la gestion des connexions TLS. TLS tourne sur TCP (un de ses copains, DTLS, tourne sur UDP), et il faut donc utiliser ce protocole (notez que l'évolution récente du DNS fait de plus en plus de place à TCP, cf. RFC 7766). DNS-sur-TLS tourne sur un port fixe, le port 853 (les premières versions de ce protocole utilisaient un protocole de négociation de TLS, comme pour SMTP mais, trop compliqué et trop dangereux, il a été abandonné). Le serveur DNS-sur-TLS écoute donc sur le port 853, le client se connecte à ce port, et démarre tout de suite une session TLS (RFC 5246). Ensuite, il y fait circuler le DNS, encodé comme sur TCP (le message DNS précédé de deux octets indiquant sa taille, cf. RFC 1035, section 4.2.2). Comme pour tout usage de DNS sur TCP (RFC 7766), le client et le serveur ne doivent évidemment pas couper la connexion après une seule requête. S'ils le faisaient, les performances seraient catastrophiques, vu le temps qu'il faut pour établir la connexion TCP et la session TLS. Au contraire, la session doit être réutilisée (section 3.4) pour les requêtes ultérieures (et le RFC demande aussi qu'un serveur traite les requêtes en parallèle, pas séquentiellement dans leur ordre d'arrivée, section 3.3.) Un autre moyen de gagner du temps lors de l'établissement d'une nouvelle connexion TCP, moyen recommandé par notre RFC, est d'utiliser TCP Fast Open (RFC 7413).

Notez bien la règle : jamais de contenu chiffré sur le port 53, jamais de contenu en clair sur le port 853. Si le serveur ne répond pas aux requêtes sur le port 853, cela peut être parce qu'une affreuse middlebox bloque tout le trafic vers le port 853, ou tout simplement parce que ce résolveur ne gère pas encore DNS sur TLS. Le client doit alors décider, selon sa politique de sécurité, s'il se rabat sur du trafic DNS en clair ou bien s'il renonce à communiquer. Le RFC recommande que le client se souvienne des serveurs qui répondent sur le port 853, pour détecter un filtrage récemment apparu.

À noter aussi que je n'ai pas parlé encore d'authentification du serveur. Comment être sûr qu'on parle bien au serveur à qui on veut parler et pas au terrible Homme du Milieu ? Pour l'instant, gardez la question de côté, on y reviendra.

Dit comme cela, c'est peut-être un peu compliqué, mais l'un des gros avantages du choix de TLS est qu'il existe déjà des bibliothèques toutes faites pour ce protocole. Ajouter TLS à un client ou un serveur existant est donc relativement simple. (Plus simple que la gestion du RFC 7766, qui est un pré-requis pour DNS-sur-TLS.)

Revenons à l'authentification. A priori, elle est indispensable. Si on n'authentifie pas, on risque d'envoyer ses requêtes DNS à un serveur qui n'est pas le bon, et, dans ce cas, le chiffrement n'aura servi à rien. Pour se faire passer pour le bon serveur DNS, les attaquants actifs ont bien des moyens à leur disposition, comme d'injecter des fausses routes, comme en Turquie. Un chiffrement sans authentification ne protégerait que contre des attaquants strictement passifs.

Oui, mais l'authentification, c'est difficile. Il y a plein de pièges, de problèmes possibles, et d'argent à dépenser (par exemple pour acheter un certificat). Imposer dès le début une authentification stricte dans tous les cas aurait tué le projet dans l'œuf. Le choix a donc été de prévoir un certain nombre de profils d'authentification, que le client choisit, en fonction du degré de sécurité souhaité. (Le serveur, lui, n'authentifie pas le client, en tout cas aucun mécanisme n'est prévu pour cela.) Notre RFC propose deux profils d'authentification (section 4), et d'autres ont décrits par la suite dans le RFC 8310.

Le premier profil est celui « opportuniste » (opportunistic privacy). Le client DNS qui utilise ce profil va tenter de chiffrer, il peut même essayer d'authentifier mais, si cela échoue, il continue quand même à envoyer des requêtes DNS, se disant qu'il est au moins protégé contre les attaques passives.

Le second profil est celui de l'« épinglage de clé » (out-of-band key-pinned »). La clé publique (SPKI pour Subject Public Key Info) du serveur DNS est connue du client (par un mécanisme non spécifié dans ce RFC), et il ne se connecte à un serveur DNS-sur-TLS que s'il utilise une des clés correspondant à son adresse. C'est un mécanisme analogue à l'épinglage HTTP du RFC 7469. Une syntaxe possible, pour un /etc/resolv.conf sur Unix serait, par exemple (l'annexe A propose une autre syntaxe) :

domain example.net
nameserver 2001:db8:90e:241a::1  NjAwZGI5YTVhMzBiY2EzOWY1OTY5YzM0ZGYzMTllYTVkNmYxNjAwYjJmNzZhOGFhYTNhMDEyMzU4MTIwNjNkMwo= 
  

Où le dernier champ est le condensat de la clé publique.

Au passage, si vous voulez trouver le condensat de votre clé, vous pouvez le faire avec gnutls-cli (cela dépend de comment est fait l'échange de clés) ou bien, si le certificat est dans le fichier tmp.pem, avec cette commande utilisant OpenSSL :

openssl x509 -pubkey -in tmp.pem | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64

Ce mécanisme est sûr, empêchant toute attaque de l'Homme du Milieu. Il est peut-être même trop sûr, par exemple pour les réseaux qui utilisent ces horribles portails captifs qui font des attaques de l'Homme du Milieu pour vous rediriger vers le portail. Il peut donc être préférable de ne pas activer ce profil avant de s'être authentifié auprès du portail. (dnssec-trigger utilise un mécanisme analogue.)

J'ai déjà parlé des performances au moment de l'établissement de la connexion, et des problèmes de latence qui peuvent survenir en raison de l'utilisation de TCP et de TLS. La section 5 revient sur ces histoires (il est également recommandé de lire le rapport « T-DNS: Connection-Oriented DNS to Improve Privacy and Security »). Évidemment, une connexion TCP plus une requête DNS, c'est plus coûteux qu'une requête DNS tout court. La requête et la réponse DNS nécessitent deux voyages entre client et serveur, l'etablissement de la connexion TCP en nécessite trois à lui seul, et TLS deux de plus. On pourrait en déduire que DNS-sur-TLS-sur-TCP aura une latence plus élevée de 250 %. On peut réduire ce coût avec des trucs TCP qui réduisent le temps d'établissement de la connexion, comme le TCP Fast Open du RFC 7413 et avec des trucs TLS comme la reprise de session du RFC 5077. Mais, de toute façon, ce calcul n'est vrai que si on établit une connexion TCP par requête DNS, ce qui n'est pas conseillé, la bonne méthode étant au contraire, dans l'esprit du RFC 7766, de réutiliser les connexions.

D'autre part, TCP nécessite de stocker un état dans le serveur. Pour éviter que beaucoup de clients n'écroulent celui-ci, il faut donc ajuster les délais d'inactivité, pour couper les connexions TCP inutilisées.

La section 7 de notre RFC intéressera les ingénieurs qui se demandent pourquoi les choses sont comme elles sont et pourquoi un autre choix n'a pas été fait. Elle est consacrée à l'évolution de la solution de chiffrement du DNS, au sein du groupe de travail DPRIVE. Comme indiqué plus haut, le premier projet prévoyait de tout faire passer sur le port 53, avec un passage en TLS à la demande du client, lorsqu'il envoyait une requête DNS « bidon » avec un nouveau bit EDNS, TO (TLS OK), mis à un, et avec le QNAME (Query NAME) STARTTLS (reprenant un mot-clé utilisé par SMTP, dans le RFC 3207).

Cette méthode avait des avantages : elle permettait par exemple à un serveur d'accepter TLS quand il n'était pas trop chargé, et de le refuser autrement. Et, réutilisant le port existant, elle ne nécessitait pas de changer les ACL sur les pare-feux. Mais elle avait aussi des inconvénients : les affreuses middleboxes ont une longue habitude d'interférence avec EDNS et il n'était pas du tout sûr qu'elles laissent passer le bit TO. Et puis, même si le RFC ne le mentionne pas, il y avait un risque qu'une middlebox trop zélée ne fasse du DPI sur le port 53, s'aperçoive que ce qui passe n'est pas du DNS, et coupe la communication. Mais le principal problème de cette approche était qu'elle rendait les attaques par repli triviales. Un attaquant actif n'avait qu'à supprimer le bit TO et le client n'avait alors plus aucun moyen de savoir si l'absence de TLS était due à un serveur trop ancien, à une middlebox boguée... ou bien à une attaque par repli.

Une proposition alternative amusante avait été de mêler le trafic chiffré et non chiffré sur le port 53 sans signalisation : la structure de l'en-tête TLS est telle qu'une machine interprétant le TLS comme étant du DNS en clair aurait vu une réponse DNS (bit QR à 1) et il n'y aurait donc pas eu de confusion avec le trafic DNS en clair. Astucieux mais évidemment très fragile.

La section 8 de notre RFC synthétise les questions de sécurité. D'abord, TLS n'est évidemment pas une formule magique. Il y a eu plein d'attaques contre TLS (par exemple pour forcer un repli vers des algorithmes de chiffrement faibles), ou contre ses mises en œuvre (on pense évidemment tout de suite à OpenSSL). Pour éviter cela, outre le respect des bonnes pratiques TLS (RFC 7525), le client prudent tâchera de se souvenir quels serveurs acceptaient DNS-sur-TLS. Si un serveur qui l'acceptait ne répond tout à coup plus sur le port 853, c'est peut-être qu'un attaquant tente de forcer un repli sur le port 53, en clair. Le client prudent peut ainsi détecter une attaque possible. Si c'est un nouveau serveur, que le client ne connait pas, la marche à suivre dépend de la politique du client (sécurisé ou laxiste).

Quant aux attaques non-TLS (comme le blocage du port 853 mentionné ci-dessus), c'est également au client, en fonction de son profil de sécurité, de décider ce qu'il va faire (renoncer à communiquer, essayer un mécanisme de résolution alternatif, s'en foutre et tout passer en clair, etc).

Revenons à TLS pour noter que ce protocole ne fait pas d'effort pour dissimuler la taille des paquets. Un attaquant passif peut donc, en observant cette taille, et d'autres informations comme le temps écoulé entre deux paquets, en déduire certaines informations, malgré le chiffrement. L'option de remplissage du RFC 7830 permet de remplir les paquets avec des données bidons, afin de rendre cette analyse plus difficile.

Pour un bilan d'étape du projet « DNS et vie privée » à l'IETF, vous pouvez regarder mon exposé State of the "DNS privacy" project: running code à l'OARC.

Question mises en œuvre de ce RFC, où en est-on ? Aujourd'hui, le résolveur Unbound a le code nécessaire depuis longtemps (depuis la version 1.4.14). On peut génerer les clés nécessaires avec OpenSSL ainsi :

openssl req -x509 -newkey rsa:4096 \
      -keyout privatekeyfile.key -out publiccertfile.pem \
      -days 1000 -nodes    
  

et configurer le serveur ainsi :

server:
  interface: 2001:db8:1::dead:beef@853
  ssl-service-key: "/etc/unbound/privatekeyfile.key"
  ssl-service-pem: "/etc/unbound/publiccertfile.pem"
  ssl-port: 853
  

Unbound va alors activer DNS sur TLS au démarrage et annoncer fièrement « setup TCP for SSL [sic] service ». Les clients pourront alors l'interroger en DNS sur TLS.

Bon, mais quel client utiliser ? Dans la bibliothèque getdns, le logiciel d'exemple getdns_query sait faire du DNS sur TLS :

% ./getdns_query @2001:db8:1::dead:beef -s -a -A -l L www.bortzmeyer.org
...
Response code was: GOOD. Status was: At least one response was returned
  

(C'est l'option -l L qui lui indique de faire du TLS.)

Si on capture le trafic entre getdns_query et Unbound, on peut afficher le résultat avec tshark :

% tshark -n -d tcp.port==853,ssl -r /tmp/dnstls.pcap    
 4   0.002996  2001:db8:1::63a:671 -> 2001:db8:1::dead:beef  SSL Client Hello
 6   0.594206  2001:db8:1::dead:beef -> 2001:db8:1::63a:671  TLSv1.2 Server Hello, Certificate, Server Key Exchange, Server Hello Done
 8   0.734094  2001:db8:1::63a:671 -> 2001:db8:1::dead:beef  TLSv1.2 Client Key Exchange
16   0.751614  2001:db8:1::dead:beef -> 2001:db8:1::63a:671  TLSv1.2 Application Data
17   0.759223  2001:db8:1::63a:671 -> 2001:db8:1::dead:beef  TLSv1.2 Application Data
  

On voit un trafic TLS classique, chiffré. Notez que tshark, par défaut, ne sait pas que c'est du TLS sur le port 853 (cela sera fait lors de la prochaine version majeure). On lui indique donc explicitement (-d tcp.port==853,ssl).

Et si j'ai la flemme d'installer un Unbound configuré pour TLS, est-ce que je peux quand même tester un client DNS-sur-TLS ? Oui, si les serveurs de test publics listés en https://portal.sinodun.com/wiki/display/TDNS/DNS-over-TLS+test+servers veulent bien répondre.

Question client, vous avez aussi le démon Stubby. Vous le lancez en indiquant le résolveur à qui il va tout relayer en DNS-sur-TLS :

%  sudo stubby @145.100.185.16 -L
  

Et vous pouvez alors l'utiliser comme résolveur (il écoute par défaut sur 127.0.0.1.)

Et vous pouvez aussi utiliser Unbound comme client ! Par rapport à Stubby, il a l'avantage d'être un vrai résolveur, validant et avec un cache, et l'inconvénient de ne pas savoir authentifier le résolveur auquel il va parler. Pour configurer Unbound en client DNS-sur-TLS (et non plus en serveur comme dans l'exemple précédent) :

server:
  ...
  ssl-upstream: yes

forward-zone:
  name: "."
  forward-addr: 2001:4b98:dc2:43:216:3eff:fea9:41a@853
  forward-first: no
  

Android a une mise en œuvre de DNS-sur-TLS (cf. ce commit).

Si vous préférez développer en Go, l'excellente bibliothèque GoDNS gère DNS sur TLS (depuis janvier 2016) et vous permet de faire vos propres programmes. Par exemple, ce code Go :

c := new(dns.Client)
c.Net = "tcp-tls"
if *insecure {
        c.TLSConfig = new(tls.Config)
        c.TLSConfig.InsecureSkipVerify = true
}
in, rtt, err := c.Exchange(m, net.JoinHostPort(myResolver, "853"))

va ouvrir une connexion avec le serveur myResolver, sur le port 853, et utiliser TLS. Par défaut, la bibliothèque TLS de Go vérifie le certificat, et que le nom (ou l'adresse IP) dans le certificat correspond bien (ce qui est la bonne approche). Mais cela peut être embêtant si on n'a pas acheté de certificat. D'où l'option (dangereuse !) pour débrayer la vérification (les trois lignes qui commencent par if *insecure). Voici un exemple d'utilisation (au fait, le programme est en dns-tls.go, -k active l'option dangereuse) :

%  ./dns-tls  my-resolver internautique.fr  
Error in query: x509: certificate signed by unknown authority

%  ./dns-tls -k my-resolver internautique.fr 
(time 43051 µs) 2 keys. TC=false    

Téléchargez le RFC 7858


L'article seul

RFC 7857: Network Address Translation (NAT) Behavioral Requirements Updates

Date de publication du RFC : Avril 2016
Auteur(s) du RFC : R. Penno (Cisco), S. Perreault (Jive Communications), M. Boucadair (Orange), S. Sivakumar (Cisco), K. Naito (NTT)
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 29 avril 2016


Le mécanisme de traduction d'adresses IPv4 connu sous le nom de NAT (et qui devrait plutôt être appelé NAPT pour Network Address and Port Translation, car il ne se contente pas de traduire les adresses IP) cause beaucoup de problèmes, car il casse le modèle normal de fonctionnement d'IP, modèle de bout en bout. Pour limiter les problèmes dus à ce mécanisme, plusieurs RFC posent certaines exigences que doivent respecter (en théorie) les routeurs NAT. Ce nouveau document met à jour certaines de ses exigences. Il met donc légèrement à jour les règles des RFC 4787, RFC 5382 et RFC 5508.

Ce RFC de maintenance ne s'applique qu'au « NAT44 » traditionnel, où une adresse IP publique n'est partagée que par les membres d'un même foyer, ou bien les employés d'une même entreprise. Pour le CGN, les exigences sont dans le RFC 6888.

D'abord, le suivi de connexions TCP (section 2 du RFC). Notre RFC formalise rigoureusement la machine à états que doit suivre un routeur NAT (elle est proche de celle du RFC 6146). Le RFC 5382 spécifiait bien des délais pour certains états mais sans décrire précisement la machine complète. Par exemple, l'exigence 5 du RFC 5382 donne un délai pour le temps minimum d'attente avant de considérer une connexion partiellement ouverte, ou fermée, comme abandonnée, mais il n'était pas clair si ces deux cas devaient avoir le même délai. Notre RFC tranche donc : le cas des connexions partiellement ouvertes et celui des connexions fermées sont différents et les délais devraient pouvoir être configurés différemment.

Et les paquets TCP RST (ReSeT), on en fait quoi ? Notre RFC précise clairement (suivant ce que faisait déjà le RFC 6146) qu'un paquet RST doit être considéré comme détruisant la connexion TCP et donc comme mettant fin à la correspondance dans le routeur NAT (après un délai, pour tenir compte du fait que le paquet RST a pu être reçu par le routeur NAT mais pas par la machine terminale). Attention, il faut d'abord vérifier que ce paquet RST correspond bien à une connexion existante, sinon, on permet des attaques par déni de service faciles (RFC 5961).

Les RFC 4787 et RFC 5382 précisaient qu'on pouvait utiliser le même couple {adresse IP externe, port externe} pour des connexions allant vers des machines extérieures différentes. Mais ils ne traitaient que du cas où il n'y avait qu'une machine interne qui allait vers ces machines extérieures. Désormais, on précise (section 3 de notre RFC) que cette utilisation est également valables si plusieurs machines internes se connectent. Sans cette règle, il faudrait beaucoup plus de ports externes disponibles, ce qui poserait un problème avec les environnements où le facteur de partage d'adresses est important (cf. RFC 6269).

Est-ce qu'un routeur NAT doit/peut utiliser les mêmes correspondances pour UDP et TCP (section 5 de notre RFC) ? Ce n'est pas précisé dans les RFC 4787 (exigence 1) et RFC 5382 (exigence 1). On fait une connexion TCP sortante, est-ce qu'un paquet UDP sortant va réutiliser la même correspondance ? La règle est désormais explicite : non, il ne faut pas ; par défaut, les correspondances doivent être spécifiques à un protocole (donc, différentes pour UDP et TCP).

Autre piège du NAT, le fait qui peut parfois changer une distribution aléatoire des ports en une distribution prévisible. Cela pose un problème pour certaines méthodes de sécurité qui dépendent du caractères imprévisible (par exemple le RFC 5452). Notre RFC reprend (section 9) une recommandation de la section 4 du RFC 6056 : un routeur NAT ne doit pas choisir les ports de sortie de manière prévisible ou régulière.

Comme d'habitude, la fragmentation est une source d'ennuis (section 10). Notre RFC rappelle donc qu'il faut suivre les règles de la section 5.3.1 du RFC 6864, notamment sur le caractère unique et imprévisible de l'identificateur de fragment.

Le routeur NAT voit parfois passer des paquets en « épingle à cheveux » (hairpinning). Cela désigne les paquets (section 12) qui, venus du réseau interne, y retournent, après être passés par le routeur. Si le réseau interne est 172.17.42.0/24, et qu'un serveur HTTP est sur la machine 172.17.41.1 et accessible de l'extérieur en 192.0.2.71, alors, une machine interne qui tente d'aller en http://192.0.2.71/ va envoyer des paquets qui iront au routeur NAT, prendront un virage en épingle à cheveux et reviendront dans le réseau interne, vers 172.17.41.1. Historiquement, pas mal de routeurs NAT étaient incapables de gérer ce cas. La situation est désormais meilleure mais il reste des cas limites. Ainsi, l'exigence 7 du RFC 5508 devait rappeler que le virage en épingle à cheveux était possible même en ICMP. Notre RFC insiste sur le respect de cette règle.

Enfin, la sécurité (section 13). Notre RFC estime que ses exigences renforcées vont améliorer la sécurité. Par exemple, des règles strictes (sections 7 et 11) sur la suppression des correspondances dans la table du routeur NAT évitent qu'un attaquant puisse garder ouvertes des correspondances qui devraient être fermées (et la mémoire récupérée). Les règles sur les ports sources imprévisibles de la section 9 rendront (entre autres) plus difficile le suivi des machines situées derrière un routeur NAT.

Notez enfin qu'il y a des gens qui prétendent avoir un brevet sur certaines de ces recommandations...


Téléchargez le RFC 7857


L'article seul

RFC 7855: Source Packet Routing in Networking (SPRING) Problem Statement and Requirements

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : S. Previdi, C. Filsfils (Cisco Systems), B. Decraene, S. Litkowski (Orange), M. Horneffer (Deutsche Telekom), R. Shakir (Jive Communications)
Pour information
Réalisé dans le cadre du groupe de travail IETF spring
Première rédaction de cet article le 22 juin 2016


Traditionnellement, la transmission d'un paquet IP au routeur suivant était faite uniquement sur la base de l'adresse de destination, sans tenir compte du reste du paquet. Et la décision est prise par chaque routeur, sur le trajet, en complète indépendance. Or, l'émetteur d'un paquet voudrait souvent décider de la route suivie ou, au minimum, l'influencer. C'est pour cela qu'il existe des mécanismes de routage par la source (source routing). Leurs défauts et leurs limites ont mené à la recherche d'une meilleure solution, dite SPRING (Source Packet Routing In NetworkinG). Ce RFC est la description du problème.

Notez que le terme « source » a, pour SPRING, un sens plus large que lorsqu'on parle habituellement de source routing. Dans ce dernier cas, la source était uniquement l'émetteur original. Pour SPRING, la source est l'endroit où on définit la politique de routage ultérieur, elle peut se situer au milieu du trajet.

Avant SPRING, il y avait plusieurs solutions permettant à la source de décider du routage mais aucune n'a été largement déployée (à part MPLS). C'est dû en partie à leur manque de souplesse, en partie à des problèmes de sécurité.

La future solution SPRING doit être un meilleur système (section 1 du RFC), et déployable de manière incréméntale (il ne serait évidemment pas réaliste de devoir changer tout l'Internet). En outre, l'état doit être maintenu dans le paquet lui-même, pas dans les routeurs intermédiaires. L'expérience de l'Internet a en effet largement montré que pour faire marcher un grand réseau complexe, il ne faut pas maintenir d'état dans les nœuds intermédiaires.

SPRING devra être assez général marcher avec plusieurs mécanismes de transmission des paquets (dataplanes, cf. section 2). Les principaux visés sont MPLS et IPv6 avec un nouvel en-tête de routage (cf. RFC 2460, section 4.4).

La section 3 présente plusieurs scénarios d'usage, pour montrer pourquoi un système tel que SPRING est utile. Il y a par exemple la création de tunnels pour faire des VPN (RFC 4364).

Il y a aussi le reroutage rapide de paquets (FRR, Fast ReRoute), et bien sûr l'ingéniérie de trafic. Pour ce dernier scénario, notre RFC demande que la future solution SPRING permette des options strictes (le paquet suit exactement le chemin spécifié) ou laxistes (le paquet suit à peu près le chemin spécifié), puisse fonctionner en centralisé (SDN) ou en décentralisé, etc.

Une des raisons du peu de déploiement des solutions de routage par la source est évidemment la sécurité (section 4 du RFC). SPRING met le chemin désiré dans le paquet (pour éviter de garder un état dans le réseau). Or, si on suit aveuglément les desiderata de chaque paquet, on ouvre la voie à des tas d'attaques. Par exemple, un paquet spécifie un détour considérable par un autre pays, et cela occupe pour rien les liaisons internationales. Un paquet spécifie un trajet qui boucle et les routeurs qui lui obéiraient feraient une attaque par déni de service contre eux-mêmes.

Le RFC impose donc que SPRING fournisse un mécanisme de « domaines de confiance » avec des frontières bien claires. Si un paquet vient d'un domaine de confiance, on lui obéit. S'il vient de n'importe où sur l'Internet, on ignore ses demandes (ou bien on vire ces options de routage par la source lorsque le paquet change de domaine).

La réalisation concrète de SPRING sur un système de transmission donné (comme MPLS ou IPv6) doit également documenter les risques spécifiques à ce dataplane. Par exemple, MPLS est en général utilisé uniquement à l'intérieur d'un domaine contrôlé et connu (le réseau d'un opérateur) alors qu'IPv6 est de bout en bout donc pose davantage de risques (mais il dispose de possibilités supplémentaires, comme la signature cryptographique des en-têtes).

Il faut maintenant attendre les RFC décrivant les solutions, ils sont en cours de développement dans le groupe SPRING.


Téléchargez le RFC 7855


L'article seul

RFC 7854: BGP Monitoring Protocol (BMP)

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : J. Scudder (Juniper Networks), R. Fernando (Cisco), S. Stuart (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 28 juin 2016


Ce nouveau protocole BMP (BGP Monitoring Protocol) va faciliter le travail des administrateurs réseaux qui font du BGP. Il permet d'obtenir sous une forme structurée les tables BGP. Avant, la solution la plus répandue était d'utiliser l'interface en ligne de commande du routeur (show ip bgp routes sur un Cisco), et d'analyser le résultat depuis son programme, une méthode qui est très fragile, le format de sortie ayant été conçu pour des humains et pas pour des programmes.

Les tables convoitées sont bien sûr la RIB mais aussi des informations comme les mises à jour de routes reçues. BMP donne accès à une table BGP nommée Adj-RIB-In, « Adjacent [peers] Routing Information Base - Incoming », définie dans le RFC 4271, section 1.1. Elle stocke les informations brutes (avant les décisions par le routeur) transmises par les pairs BGP.

BMP fonctionne (section 3) en établissant une connexion TCP avec le routeur convoité. Celui-ci envoie ensuite l'information qu'il veut. Il n'y a pas de négociation ou de discussion au début. Dès que la connexion est établie, le routeur transmet. Il envoie d'abord des messages Peer Up pour chacun de ses pairs, puis des messages Route Monitoring pour toute sa base de routes (la section 5 les décrit plus en détails). Une fois que c'est fait, le routeur transmet des messages indiquant les changements : Route Monitoring en cas d'annonce ou de retrait d'une route, Peer Up ou Peer Down s'il y a des changements chez les pairs. Autres messages possibles : Stats Report pour envoyer des statistiques globales (voir les sections 4.8 et 7), Initiation et Termination pour les débuts et fins de sessions, Route Mirroring pour envoyer verbatim les annonces BGP reçues (c'est une vision de plus bas niveau que Route Monitoring et cela permet, par exemple, d'analyser des annonces BGP syntaxiquement incorrectes, cf. section 6).

Le client BMP ne transmet jamais de message au serveur (au routeur), à tel point que le routeur peut parfaitement fermer la moitié de la connexion TCP, ou mettre sa fenêtre d'envoi à zéro (ou encore, jeter tous les messages qui seraient envoyés). Toute la configuration est dans le routeur.

Le format des messages est décrit en section 4. C'est du classique. On trouve dans le message un numéro de version (actuellement 1), la longueur du message, le type du message (la liste des types est indiquée plus haut) représentée par un entier (0 pour Route Monitoring, 1 pour Stats Report (ou Statistics Report), etc), puis les données. À noter que le type arrive après la longueur, alors que c'est en général le contraire (encodage TLV).

Pour la plupart des messages BMP, il y aura un second en-tête, rassemblant les informations sur le pair (son adresse IP, son AS, etc).

Les différents paramètres numériques sont désormais stockés dans un registre IANA.

Quelques petits mots sur la sécurité pour finir. Pour économiser ses ressources, le routeur peut évidemment (section 3.2) restreindre l'ensemble des adresses IP autorisées à se connecter en BMP à lui, tout comme il peut limiter le nombre de sessions BMP (par exemple, une au maximum par adresse IP, cinq au total). Il peut aussi y avoir des questions de confidentialité (section 11). Bien sûr, la liste des routes dans la DFZ est publique, mais ce n'est pas forcément le cas des peerings privés ou de VPN utilisant BGP comme ceux du RFC 4364. Donc, attention à bien restreindre l'accès.

BMP est en cours d'élaboration depuis pas mal de temps déjà. Résultat, des mises en œuvre ont eu le temps d'apparaitre. Wireshark sait analyser le BMP. Et il existe deux récepteurs (clients) libres, BMPreceiver et OpenBMP. Côté serveur (routeur), Cisco et Juniper savent envoyer du BMP.


Téléchargez le RFC 7854


L'article seul

RFC 7848: Mark and Signed Mark Objects Mapping

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : G. Lozano (ICANN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eppext
Première rédaction de cet article le 28 juin 2016


Les registres de noms de domaine ont parfois des règles d'enregistrement spéciales, pendant une période limitée, lorsqu'on ouvre un nouveau TLD, ou si on change radicalement ses règles d'enregistrement. Ces règles spéciales pour les périodes de « lever de soleil » (sunrise, lorsque le nouveau TLD est créé) servent en général à favoriser les détenteurs de marques ou autres titres de propriété intellectuelle. L'idée est que, pendant le lever de soleil, seuls ces détenteurs aient le privilège d'enregistrer un nom, les autres attendront. Pour que le registre puisse facilement vérifier la possession d'une marque déposée, il faut un format standard pour les décrire, et c'est ce que contient ce RFC. Il a été écrit par un employé de l'ICANN car il vise surtout un service de l'ICANN, la TMCH (Trade Mark Clearing House).

La TMCH est un registre de marques créé par l'ICANN (voir sa description officielle). Il a suscité d'innombrables débats (par exemple, de quel droit l'ICANN crée un registre mondial faisant autorité, excluant les marques qui n'ont pas voulu passer par ce processus ?) mais ce RFC ne concerne que la partie technique, le format de description de ces marques. Il s'applique a priori aux TLD ICANN comme .pizza ou .maif mais les autres sont libres de s'en servir également. Comme les objets décrits dans ce RFC peuvent être signés, il faut avoir une PKI. Dans le cas des TLD ICANN, elle est décrite dans le document officiel cité plus haut. Les objets eux-mêmes sont décrits en XML, pour pouvoir être utilisés dans le protocole EPP (RFC 5730).

Les objets sont dans les espaces de noms urn:ietf:params:xml:ns:mark-1.0 (abrégé en mark: dans ce RFC) et urn:ietf:params:xml:ns:signedMark-1.0 (abrégé en smd: dans ce RFC).

Les objets XML décrivant les marques incluent des informations sur les personnes ou entités qui gèrent les marques. Il y a ainsi des <mark:holder> et des <mark:contact>, qui comprennent des éléments classiques : nom, adresse postale (qui comprend elle-même ville, pays...), adresse de courrier électronique, etc.

Les marques sont décrites par un élément <mark:mark>. Celui-ci contient le nom de la marque, des références au registre initial (par exemple, en France, l'INPI), le contact et le titulaire (décrits au paragraphe précédent) et d'autres informations utiles aux juristes (comme les biens et services couverts par cette marque, puisque les marques, contrairement aux noms de domaine, sont normalement spécifiques).

Les objets décrivant une marque peuvent être signés, grâce à XML Signature. Voici un exemple (très simplifié, voir la section 2.3 du RFC pour le XML complet) d'une marque avec sa signature :


<?xml version="1.0" encoding="UTF-8"?>
 <smd:signedMark xmlns:smd="urn:ietf:params:xml:ns:signedMark-1.0" id="smd1">
   <smd:issuerInfo issuerID="65535">
     <smd:org>ICANN TMCH TESTING TMV</smd:org>
     <smd:email>notavailable@example.com</smd:email>
     ...
   </smd:issuerInfo>
   <mark:mark xmlns:mark="urn:ietf:params:xml:ns:mark-1.0">
     <mark:trademark>
       <mark:id>00052013734689731373468973-65535</mark:id>
       <mark:markName>Test &amp; Validate</mark:markName>
       <mark:holder entitlement="owner">
         <mark:org>Ag corporation</mark:org>
	 ...
	 <mark:jurisdiction>US</mark:jurisdiction>
         <mark:class>15</mark:class>
       <mark:label>testandvalidate</mark:label>
       ...
       <mark:regNum>1234</mark:regNum>
       <mark:regDate>2012-12-31T23:00:00.000Z</mark:regDate>
     </mark:trademark>
   </mark:mark>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
  ...
  <SignatureMethod
     Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
     ...
     <SignatureValue>
 jMu4PfyQGiJBF0GWSEPFCJjmywCEqR2h4LD+ge6XQ+JnmKFFCuCZS/3SLKAx0L1w
 ...
 </Signature>
 </smd:signedMark>

    

L'élement XML peut aussi être intégralement encodé en Base64 (RFC 4648), et ça sera alors un <smd:encodedSignedMark>.

La syntaxe exacte est spécifiée dans la section 3 du RFC, avec le langage W3C Schema.

Quelles sont les mises en œuvre de ce format ? Le kit de développement logiciel de Verisign l'intègre (il est disponible en ligne), et c'est aussi le cas de Net::DRI (dans Net::DRI::Protocol::EPP::Extensions::ICANN::MarkSignedMark, ouf). Côté serveur, le serveur EPP de Verisign pour des TLD comme .com. D'autres serveurs EPP peuvent utiliser ce format comme REngin, ou celui d'Uniregistry.


Téléchargez le RFC 7848


L'article seul

RFC 7844: Anonymity profile for DHCP clients

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : C. Huitema (Microsoft), T. Mrugalski (ISC), S. Krishnan (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dhc
Première rédaction de cet article le 29 mai 2016


Vous vous connectez à un réseau IP, vous obtenez la configuration via un serveur DHCP, mais vous voulez rester relativement anonyme, et vous n'avez pas envie que le serveur, ou que des indiscrets qui écoutent, sachent qui vous êtes ? C'est là que ce RFC est utile en proposant un profil de requête DHCP qui envoie le moins d'informations possibles.

C'est que DHCP, par défaut, est trop bavard. Comme l'expliquent bien les RFC 7819 et RFC 7824, une requête DHCP comporte pas mal de champs et d'options qui peuvent contenir des identificateurs stables, qui permettront au serveur DHCP, ou à des espions qui écoutent le trafic, de reconnaitre une machine. Un exemple d'une telle surveillance est celle effectuée dans les aéroports canadiens mais ce n'est certainement pas la seule. Un des buts de cette surveillance peut être, pour quelqu'un qui peut écouter en plusieurs endroits, de suivre à la trace les utilisateurs en déplacement, en reconnaissant les requêtes spécifiques de leur ordinateur portable ou smartphone. Bien sûr, DHCP n'est pas le seul outil pour faire cela. L'identificateur stable le plus évident est l'adresse MAC, mais c'est aussi le plus connu : les utilisateurs soucieux de leur vie privée prennent souvent des mesures pour la changer de temps en temps. Mais peu de gens pensent aux risques pour la vie privée associés à DHCP. Ceux-ci sont désormais bien établis, et documentés dans les RFC 7819 et RFC 7824.

Mais pourquoi en faire un RFC, une norme ? Après tout, on pourrait se contenter d'attendre que les différents fournisseurs de clients DHCP minimisent les informations envoyées. Le problème est qu'ils risquent de le faire légèrement différemment (certains supprimant une option de la requête que d'autres garderont, par exemple). Cette différence permettra une différenciation des utilisateurs, justement ce qu'on veut éviter (cf. la section 2.4). Au contraire, si tout le monde met en œuvre ce profil standard, tous les clients seront pareils, ce qui protège nettement mieux leur anonymat.

La section 2 de notre RFC détaille certains problèmes concrets. J'ai dit plus haut que l'identificateur le plus évident pour suivre une machine à la trace était l'adresse MAC. En Wi-Fi, n'importe qui peut la voir, même si le réseau utilise le chiffrement, puisqu'elle est dans la partie en clair du paquet. En la corrélant avec d'autres informations qu'on retrouve ailleurs, on peut remonter à l'individu qui utilise la machine en question. Le danger est donc réel.

La contre-mesure évidente est de changer l'adresse MAC, en la remplaçant par une valeur aléatoire, par exemple avec macchanger. Cela a fait d'ailleurs l'objets de tests en grand à la réunion IETF de Honolulu, ainsi que dans d'autres réunions. Il n'y a pas de norme technique décrivant cette « aléatoirisation ». Parmi les choix possibles :

  • Un tirage au hasard à chaque connexion à un réseau,
  • Un tirage au hasard pour chaque nouveau réseau mais on garde toujours la même adresse MAC pour un réseau donné,
  • Des changements de temps en temps, si on reste connecté sur des longues périodes. (Cela ne marchera pas en Wi-Fi où le changement d'adresse MAC nécessitera déconnexion/reconnexion donc peut-être changement d'adresse IP donc coupure des connexions TCP en cours.) Cette astuce n'est même pas forcément efficace : un observateur peut facilement noter le départ d'une machine et l'arrivée immédiate d'une autre, corrélant ces deux événements.

En tout cas, un changement de l'adresse MAC est nécessaire, sinon, le profil DHCP « anonyme » de ce RFC aura une utilité limitée. Mais, inversement, attention à ne pas se contenter de changer un seul identificateur. Si on change d'adresse MAC en gardant tout le reste, la tâche d'un surveillant est trop facile, et il déduira sans problème la nouvelle adresse MAC. Il faut changer l'adresse MAC, l'adresse IP et les identificateurs DHCP en même temps.

Notre RFC mentionne qu'il existe des techniques de plus bas niveau (couche 1) qui peuvent défaire tout le travail de protection de la vie privée. Par exemple, certains récepteurs radio permettent d'identifier des particularités d'un émetteur physique et, en observant le trafic Wi-Fi, on peut ainsi identifier une machine donnée quels que soient ses efforts pour ne pas laisser de traces (cf. « Wireless Device Identification with Radiometric Signatures »). Heureusement, tous les surveillants n'ont pas les moyens de placer ce genre de récepteurs. S'ils doivent se contenter de capter le trafic, sans pouvoir analyser le signal physique, les précautions recommandées plus loin dans ce RFC vont suffire.

Le profil d'« anonymat » décrit dans ce RFC n'est pas explicite. On ne peut pas distinguer les clients DHCP qui appliquent ce profil de ceux qui n'ont simplement pas mis en œuvre les options trop révélatrices. Il y avait eu une discussion à l'IETF sur une mention explicite, un bit dans la requête disant « je veux être anonyme et ne vous étonnez donc pas si je ne publie pas grand'chose ». Cette idée avait été rejetée avec l'idée que proclamer publiquement qu'on veut être anonyme peut être au contraire un excellent moyen de se distinguer, comme de sortir dans la rue avec un masque de Guy Fawkes. Au contraire, le vrai anonymat s'obtient en ne faisant rien de trop extraordinaire.

Enfin, comme toute mesure de sécurité, celles qui préservent la vie privée ont des inconvénients. La plus évidente est que l'« anonymat » va rendre plus difficile la gestion des réseaux. Si l'administrateur réseaux suit les machines sur le réseau local en les identifiant par leurs adresses MAC, il devra s'adapter. D'autre part, il y a un conflit entre la protection de la vie privée, qui requiert des changements fréquents d'adresse MAC, et le bon fonctionnement du réseau, qui demande qu'on limite le trafic DHCP (mais aussi ARP et NDP). Attention donc à ne pas changer d'adresse MAC « trop souvent ».

Autre inconvénient, le changement de l'identificateur DHCP par le client, s'il permet davantage de vie privée, empêchera d'obtenir des paramètres de connexion stables (comme l'adresse IP, cf. RFC 7618) dans le temps. On n'a rien sans rien !

Et la vie privée du serveur DHCP, on en parle ? On ne s'est préoccupé jusqu'à présent que du client. C'est parce que le RFC considère que c'est le client qui est aujourd'hui suivi à la trace, et c'est son cas qui nécessite des solutions urgentes. Pour le serveur, cela peut attendre (par exemple parce qu'un serveur qui veut être discret peut ne répondre qu'aux clients authentifiés au niveau 2).

Bien, assez de préliminaires, voyons maintenant le profil proposé. D'abord, pour IPv4 (section 3). Donc, le client qui veut minimiser la surveillance doit donc :

  • Dans le message DHCPDISCOVER, mettre les options « identificateur de client » et « paramètres demandés » mais rien d'autre. (Voir comme contre-exemple cette bogue de Tails.)
  • Dans un DHCPREQUEST, ajouter éventuellement la demande d'une adresse IP précise.

L'option « identificateur de client » (Client Identifier, RFC 2132, code 61) est, comme son nom l'indique, dangereuse pour la vie privée. Elle permet un suivi très efficace d'une machine, précisement ce qu'on voudrait empêcher. Ne pas la mettre n'est pas une solution car tous les clients DHCP l'incluent. Ne pas le faire serait se singulariser (voir la remarque sur Guy Fawkes plus haut). Notre RFC demande donc qu'on envoie cette option mais qu'on lui donne comme valeur l'adresse MAC (qui est déjà dans l'en-tête couche 2 du paquet). Cela contredit le RFC 4361, section 6.1, mais ce changement de politique reflète l'accent désormais mis sur la préservation de la vie privée. Si on n'a pas d'adresse MAC (cas de certaines liaisons point à point), on doit tirer au hasard (après avoir lu le RFC 4086 et la section 5 du RFC 7217) un identificateur.

Et l'autre option acceptable, la liste des paramètres demandés (Parameter Request List, RFC 2132, code 55) ? La liste doit être réduite au minimum, et ordonnée au hasard, pour éviter qu'on reconnaisse le type de client DHCP utilisé.

L'adresse MAC est indispensable, on ne peut pas ne pas la mettre dans le paquet, et, donc, il ne sert à rien de l'omettre du champ correspondant dans la requête DHCP, mais il est recommandé de la changer (et que le client DHCP utilise cette adresse dans son paquet, qu'il ne garde surtout pas l'ancienne).

Le champ « adresse IP du client » ne pose guère de problème de vie privée (puisque la même adresse IP figure dans l'en-tête IP du paquet) sauf si le client est nouveau sur ce réseau, l'adresse IP indiquée étant alors celle du précédent réseau. Donc : pensez à effacer l'adresse IP lorsque le matériel signale qu'on vient de changer de réseau. Pour la même raison, le profil anonyme ne comprend pas l'option « adresse IP souhaitée » (RFC 2132, code 50). Elle est certes bien pratique (permettant de conserver son adresse IP) mais très révélatrice.

Parmi les autres options, le nom de la machine (code 12) est très révélateur. Même si ce n'est pas un FQDN, il peut être très spécifique (« pc-de-jean-dupont »). Il ne doit pas être utilisé dans ce profil. Si on doit quand même le faire, le nom doit être choisi aléatoirement. Une méthode possible est de condenser un secret et l'adresse MAC, puis prendre la représentation en hexadécimal de six premiers octets (quelque chose comme echo -n "$SECRET" "$MACADDRESS" | sha256sum | cut -c 1-12 en shell Unix).

L'option Client FQDN (RFC 4702, code 81) est évidemment également à proscrire. Ou alors, il faut l'« anonymiser » avec la même méthode qu'au paragraphe précédent.

Le RFC 4578 décrit une option UUID, prévue pour PXE, et identifiant de manière unique un client DHCP. Normalement, on n'utilise PXE que dans des environnements contrôlés et sécurisés. Dans un cyber-café inconnu, télécharger son système d'exploitation serait une très mauvaise idée. Il ne faut donc utiliser cette option que dans un réseau que l'on sait sûr.

Enfin, les options indiquant le type de logiciel utilisé (comme Vendor Specific Information, code 43, ou Vendor Class, code 60 sont évidemment à rejeter.

Pour éviter le fingerprinting, le client ne devrait pas ajouter d'autres options, mêmes si celles-ci sont inoffensives du point de vue de la vie privée. En effet, si certains clients mettent telle option, quel que soit son contenu, ils diffusent une information. Et, si on envoie des options DHCP, leur ordre doit être tiré au hasard avant l'envoi, là encore, pour éviter de révéler le type de client utilisé (DHCP permet pas mal de choix, et le choix facilite le fingerprinting). Si on n'a pas de bon générateur de nombres aléatoires, un repli possible est d'envoyer toujours les options dans l'ordre de leur code : ainsi, tous les logiciels (qui sont dans ce cas) feront pareil.

La section 4 du RFC fait la même chose, mais pour IPv6. DHCP v6 a d'autres possibilités (comme l'existence de deux modes, avec ou sans état). Le profil est donc un peu plus compliqué mais bien des conseils sont identiques (par exemple ceux sur les options Client FQDN, sections 3.8 et 4.9), et je ne les répéterai donc pas ici. Dans le mode sans état, les clients configurent l'adresse avec d'autres mécanismes, comme le SLAAC et ne se servent de DHCP que pour récupérer des informations générales. Le choix entre les deux modes dépend d'options publiées dans les Router Advertisement (RFC 4861, section 4.2, les bits M et O).

Parmi les messages spécifiques à DHCP v6, Confirm (RFC 8415, section 16.5) est dangereux, car il contient de l'information sur le précédent réseau où on s'est connecté. En mode « anonyme », il ne faut pas l'envoyer, sauf si on est certains qu'on est toujours sur le même réseau (ce qui est une vérification pas toujours triviale, le RFC recommande d'utiliser 802.1X).

L'option Client Identifier (code 1) en DHCP v6 contient un identificateur unique, le DUID (DHCP Unique Identifier, RFC 8415, section 11). Elle rend donc le suivi d'un client très facile. Pour empêcher ce suivi, le profil demande d'utiliser le format 3, « adresse MAC », du DUID (RFC 8415, section 11.4), avec une adresses MAC changée comme indiquée plus haut. Dans les cas où cette option n'est pas exigée par le protocole (comme les Information-Request, RFC 8415, section 18.2.6, qui sont sans état), elle ne doit pas être envoyée.

DHCP v6 permet évidemment d'obtenir des adresses IPv6 (mais ce n'est pas le seul moyen, contrairement à ce qui se passe en IPv4). Une option semble intéressante pour la vie privée, la demande d'adresses temporaires (RFC 8415, section 13.2). Mais elle n'est pas si utile que ça : car peu de serveurs la mettent en œuvre (le client ne peut donc pas se reposer dessus), le renouvellement de ces adresses n'est pas spécifié, et le fait que le client doive la demander est déjà une fuite d'informations (« je veux être anonyme »). Elle est donc déconseillée.

Notre RFC met également en garde contre des options qui peuvent être amusantes mais qui sont rares : les utiliser revient, pour le client DHCP, à « sortir du lot ». C'est le cas par exemple de la demande de délégation de préfixe (RFC 8415), que le PC typique n'utilise pas.

Le RFC se termine par quelques considérations opérationnelles (section 5). La plus évidente, et la plus « gênante » est que l'application de ce profil va cache l'identité du client au serveur DHCP. C'est le but. Mais cela peut être ennuyeux. Des fonctions comme la publication de l'adresses du client dans le DNS, ou comme la relative stabilité des adresses IP (redonner la même adresse lorsqu'un client revient) ne seront plus possibles. On n'a rien sans rien.

D'autre part, les clients utilisant ce profil consommeront davantage de ressources. Par exemple, à chaque changement au niveau 2, ils réclameront une nouvelle adresse IP, alors que l'ancienne reste réservée, jusqu'à la fin du bail.

Et certains serveurs DHCP fascistes ne donnent une adresse IP qu'aux clients connus, interdisant ainsi l'anonymat. Pour ces raisons, le RFC recommande aux programmeurs de permettre la configuration du client DHCP, configuration allant jusqu'à permettre de débrayer l'anonymisation.

Ce profil a été mis en œuvre dans un client Microsoft, ce qui a donné lieu à un compte-rendu d'expérience à une réunion IETF.


Téléchargez le RFC 7844


L'article seul

RFC 7842: Requirements for Improvements to the IETF Email List Archiving, Web-Based Browsing, and Search Tool

Date de publication du RFC : Avril 2016
Auteur(s) du RFC : R. Sparks (Oracle)
Pour information
Première rédaction de cet article le 13 avril 2016


Un des gros avantages de travailler à l'IETF est qu'il existe un ensemble d'outils de travail en groupe très perfectionnés, permettant de gérer un grand nombre de documents qui changent tout le temps. Dans la plupart des SDO, ou organisations similaires, on a juste des piles de documents Word (ou, dans les dernières années, Google Docs) inexploitables. Comme le gros du travail IETF est fait sur des listes de diffusion, un des outils les plus cruciaux est le moteur de recherche dans ces listes de diffusion. Mais aucun outil n'est parfait et ce nouveau RFC est une liste de points à améliorer dans l'outil actuel, liste fondée sur l'expérience récente.

Ce https://mailarchive.ietf.org/ permet notamment de retrouver un ou plusieurs messages, parmi les centaines de messages échangés sur les listes IETF chaque jour. Voici un exemple de recherche de « tcp encryption eliot » (Eliot = Eliot Lear, auteur entre autres des RFC 1918, RFC 4192, RFC 6557...). On y voit la liste des messages correspondants en haut à droite, à gauche les noms des listes (en général, des groupes de travail IETF) où les messages apparaissent, en bas à droite l'URL stable du message en cours (ce qui permet des références précises lorsqu'on affirme « Brian Trammel a dit que ») : mailarchive-ietf-general.png

L'outil actuel avait eu comme cahier des charges le RFC 6778 et avait été déployé en janvier 2014. Notre nouveau RFC liste les améliorations souhaitées.

Par exemple, lorsqu'on choisit « Group by Thread », la liste résultante est plate, sans hiérarchie. Cela rend difficile de voir où un fil de discussion commence et où il finit : mailarchive-ietf-thread.png

Notre RFC demande que, dans les améliorations de l'outil, l'affichage montre la hiérarchie.

Autre problème, il n'y a pas actuellement de boutons de navigation (message suivant/précédent par date, ou suivant le fil de discussion), que cela soit dans la liste des messages affichés, ou bien lorsqu'on regarde un seul message. Le RFC demande que ces boutons soient ajoutés.

C'est en lisant ce RFC que j'ai appris qu'on pouvait changer la taille de la fenêtre où s'affiche la liste des messages. Je la croyais fixe, et c'était apparemment le cas de bien des utilisateurs. Le RFC demande donc qu'on rende cette possibilité d'agrandissement plus évidente (personnellement, je n'ai pas trouvé). En prime, la façon dont est faite la troncation aujourd'hui ne semble pas rationnelle. Ici, on voit bien que les sujets sont coupés (et la fin remplacée par des ellipses) sans vraiment de raison. mailarchive-ietf-ellipsis.png

Le service actuel est difficile à utiliser sur un petit écran, comme celui des phono sapiens puisque les divers éléments de l'interface sont toujours présents. Pour une interface riche, il vaudrait mieux être responsive, ce que demande le RFC (par exemple, on pourrait supprimer le menu des filtres quand l'écran est trop petit).

Par contre, sur des grands écrans, l'interface actuelle est au contraire trop économe et sous-utilise l'écran.

Enfin, notre RFC regrette que l'interface actuelle ne marche guère sans JavaScript. La prochaine version doit évidemment être capable de fonctionner sans JavaScript, quitte à accepter quelques fonctions en moins (comme les filtres appliquées dynamiquement).

Reste à développer, maintenant... Je n'ai pas encore vu d'appel d'offres.


Téléchargez le RFC 7842


L'article seul

RFC 7841: On RFC Streams, Headers, and Boilerplate

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : J. Halpern, L. Daigle, O. Kolkman (Internet Society), Internet Architecture Board (IAB)
Pour information
Première rédaction de cet article le 29 mai 2016


Les textes sacrés de l'Internet, les RFC, comprennent un certain nombre d'éléments obligatoires, souvent collectivement appelés boilerplates et comprenant, par exemple, les conditions légales d'utilisation du RFC. Ce RFC 7841 écrit par l'IAB les décrit et les précise.

Les éléments utilisés autrefois comme Category: Experimental ne suffisaient pas à transporter toute l'information nécessaire. Depuis la formalisation des voies dans le RFC 4844, les différents circuits de publication des RFC, il était devenu crucial de déterminer facilement de quelle voie venait un RFC. (Les anciens RFC étaient tous marqués comme provenant d'un mystérieux Network Working Group, cf. RFC 3.) Cela avait été fait dans le RFC 5741, que notre RFC 7841 remplace.

Donc, dans sa section 2, notre méta-RFC rappelle que, non seulement tous les RFC ne sont pas des normes (RFC 1796), mais que tous ne sont pas des documents issus de l'IETF, qui n'est qu'une voie parmi d'autres (quoique la plus prolifique). Ainsi, un RFC peut très bien être publié sans que l'IETF n'aie pu donner un avis sur des points comme la sécurité ou le contrôle de congestion, par le biais de procédures comme le IETF Last Call ou l'examen par l'IESG. En termes para-légaux, disons que l'IETF refuse toute responsabilité pour les RFC non-IETF. (À noter que, si tous les RFC ne sont pas des normes IETF, en revanche, toutes les normes IETF sont publiées sous forme d'un RFC.) Si vous tenez à tout connaitre sur les processus de l'IETF, et la publication des RFC, consultez les RFC 2026, RFC 8728, RFC 8729, RFC 5742, RFC 6410 et RFC 7127.

La section 3 liste les éléments qui forment la structure d'un RFC. Leur forme exacte, plus susceptible de changer, figure sur une page Web séparée. Il y a l'en-tête général (section 3.1) qui, pour notre RFC, est :

Internet Architecture Board (IAB)                        J. Halpern, Ed.
Request for Comments: 7841
Obsoletes: 5741                                           L. Daigle, Ed.
Updates: 7322
Category: Informational                                  O. Kolkman, Ed.
ISSN: 2070-1721
                                             Internet Architecture Board
                                                                   (IAB)
                                                              April 2016

indiquant qu'il est issu de la voie IAB, qu'il porte le numéro 7841, qu'il est de la catégorie « Pour information » (les catégories sont décrites dans le RFC 2026), etc. Les autres voies sont IETF, IRTF et « contribution indépendante ».

Après cet en-tête vient un paragraphe (section 3.2) qui décrit clairement la voie par laquelle ce RFC est passé. Par exemple, pour une soumission indépendante, le texte (qui est sujet à évolution, en synchronisation avec la définition des voies) actuel est « This is a contribution to the RFC Series, independently of any other RFC stream. The RFC Editor has chosen to publish this document at its discretion and makes no statement about its value for implementation or deployment. ».

Cet en-tête indique également les relations de ce RFC avec d'autres RFC. Par exemple, notre RFC 7841 indique :

Obsoletes: 5741

car il remplace le RFC 5741, qui n'a désormais plus qu'un un intérêt historique.

Je ne reprends pas ici tous les éléments, qui sont décrits dans cette section 3. Notons simplement le copyright, issu des RFC 5378 et RFC 8179, et l'ISSN des RFC, 2070-1721. Pour le reste du RFC, il faut utiliser le guide stylistique du RFC 7322.

Notre RFC ne décrit que les principes gouvernant ce boilerplate. Les détails, qui sont changeants, sont désormais sur une page Web dédiée à l'IAB. C'est l'un des gros changements depuis le RFC 5741. L'annexe A de notre RFC contient l'état initial de ces textes. Ainsi, un RFC de l'IETF sur le chemin des normes commencera par « This is an Internet Standards Track document. This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). »

Outre ce déplacement du texte effectif depuis le RFC (document rigide et stable) vers une page Web, le principal changement depuis le RFC 5741 est l'allègement de certaines règles de présentation, pour tenir compte du projet de réforme du format de publication des RFC (qui, dans le futur, ne seront plus publiés uniquement sous forme de texte brut).


Téléchargez le RFC 7841


L'article seul

RFC 7838: HTTP Alternative Services

Date de publication du RFC : Avril 2016
Auteur(s) du RFC : M. Nottingham (Akamai), P. McManus (Mozilla), J. Reschke (greenbytes)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF httpbis
Première rédaction de cet article le 15 avril 2016


Une nouveauté dans le monde HTTP : ce RFC décrit un mécanisme permettant d'indiquer des endroits alternatifs où trouver le contenu demandé. Ce n'est pas une classique redirection : l'URI reste le même, on découple simplement l'identificateur (l'URI) et le localisateur (l'endroit où chercher et le protocole à utiliser).

Ce concept est assez nouveau dans le monde HTTP (section 1 du RFC). En effet, le RFC 7230 tend à mélanger l'identificateur d'une ressource (http://www.example.com/foo/bar) et les moyens d'y accéder (la même ressource peut aussi être en https://www.example.com/foo/bar voire sur un miroir à un URL très différent). Le but du mécanisme de ce nouveau RFC 7838 est de séparer plus clairement identificateur et localisateur.

Quelques exemples pratiques sont donnés dans cette section 1 :

  • Le serveur d'origine peut vouloir rediriger vers un serveur de secours si lui-même est sous forte charge, ou bien s'il sait qu'il existe un serveur plus proche de ce client particulier.
  • Le serveur d'origine peut rediriger le client vers une connexion sécurisée (avec HTTPS, cf. RFC 8164) ou vers un protocole plus moderne (HTTP 2, cf. RFC 7540).
  • Le serveur d'origine peut renvoyer certains clients à des serveurs spécialisés, par exemple pour le cas de clients ne gérant pas certaines options comme SNI (RFC 6066, section 3).

Actuellement, ce genre de choses est fait par des redirections HTTP explicites (codes 301, 302, 307 ou 308, voir le RFC 7231, section 6.4). L'URL vers lequel on est redirigé est montré par le navigateur (ce qui n'est clairement pas une bonne idée dans le cas de redirections temporaires comme 307). Autre façon de faire, un relais, qui se connecte au serveur effectif, sans le dire du tout au client HTTP. Les « services alternatifs » de ce RFC 7838 sont situés entre les deux façons : annoncés au client HTTP mais pas mémorisés et pas montrés à l'utilisateur (l'URI ne change pas). Le contexte de sécurité n'est pas modifié (si l'URI commençait par le plan https://, le service alternatif devra donc présenter un certificat valide), le champ Host: de la requête HTTP contiendra toujours le nom original (notez qu'il existe désormais un champ Alt-Used: pour indiquer le nom alternatif, cf. section 5). Normalement, l'utilisateur ne verra donc pas qu'on utilise un service alternatif (ceci dit, comme son logiciel client, lui, est au courant, des options de débogage pourront permettre de l'afficher, contrairement à ce qui se passe avec un relais).

La solution est en deux parties : des concepts abstraits (section 2) puis des mécanismes concrets pour les différents protocoles, dans les sections 3 et 4. Commençons par le cadre abstrait. Un « service alternatif » existe lorsqu'un serveur d'origine (concept lui-même défini dans le RFC 6454, section 4) sait que ses ressources sont accessibles avec une combinaison {protocole, serveur, port} différente. Un tel service alternatif fait autorité (au sens du RFC 7230, section 9.1), ce n'est pas un simple miroir, ni un cache. Notez que la granularité est pour une origine complète (la combinaison {protocole, serveur, port}) : on ne peut pas faire un service alternatif qui couvrirait uniquement le chemin /foo de l'URI.

Un exemple de service alternatif ? Mettons que l'origine soit {http, www.example.com, 80} et que les mêmes ressources soient accessibles en HTTP 2 à {h2, new.example.com, 81}, alors on peut dire que ce {h2, new.example.com, 81} est un service alternatif de l'origine.

Notez que j'ai appelé « protocole » le premier membre du tuple. Ce n'est pas le plan (scheme) dans l'URI (plan que pas mal de gens appellent à tort protocole). En effet, cette valeur est plus spécifique que le plan, elle peut inclure des détails techniques supplémentaires (par exemple, lorsque le plan est http://, on peut y accéder avec les protocoles http ou h2, ce second désignant HTTP 2.) Le protocole, pour les services alternatifs, est un nom ALPN (RFC 7301 et le registre IANA ALPN).

Le tuple {protocole, serveur, port} peut être accompagné d'une durée de vie, indiquant combien de temps le client HTTP peut garder en mémoire l'information sur le service alternatif.

Au passage, un mot de sécurité : le client doit évidemment être conscient que, si la communication n'est pas sécurisée (par exemple par TLS), il peut être envoyé vers un faux service alternatif (section 9). Si le service d'origine n'a pas TLS mais que le service alternatif l'a, et présente un certificat au nom du service d'origine, c'est bon. Si aucun des deux n'a TLS, le risque d'avoir été trompé est bien plus élevé. Il n'est donc pas forcément prudent d'utiliser les services alternatifs sans TLS.

Notons enfin que les services alternatifs sont optionnels. Le client n'est pas obligé de les utiliser (d'autant plus que les clients HTTP actuels ne gèrent pas ces services et n'utiliseront donc pas les alternatives, tant qu'ils n'ont pas été mis à jour). Le serveur d'origine doit donc rester prêt à assurer les requêtes.

Maintenant, les mécanismes pour signaler ces services alternatifs. En HTTP 1, en utilise l'en-tête Alt-Svc: (section 3, et désormais dans le registre IANA). La réponse contient, par exemple :

Alt-Svc: h2="new.example.org:80"      
    

Cela indique que le client devrait plutôt aller voir avec le protocole h2 (HTTP 2), sur la machine new.example.org. Si on ne change que le protocole et le port, on pourrait avoir :

Alt-Svc: h2=":8000"
    

Il peut y avoir plusieurs valeurs, dans l'ordre des préférences décroissantes :

Alt-Svc: h2="alt.example.com:8000", h2=":443"
    

Par défaut, le service alternatif peut être mémorisé par le client pendant 24 h. Si on veut changer cette durée, on utilise le paramètre ma (Maximum Age, en secondes) :

Alt-Svc: h2=":443"; ma=3600
     

Si le serveur veut qu'on oublie tout ce qu'on a mémorisé sur les services alternatifs, et n'a pas envie d'attendre l'expiration des caches, il envoie la valeur spéciale clear :

Alt-Svc: clear
    

À part ce paramètre ma, et un autre paramètre persist (qui indique que, contrairement au comportement par défaut, le client HTTP ne devrait pas vider cette information de son cache si sa configuration réseau change), d'autres paramètres sont possibles dans le futur. Ils devront passer par le procédure « Examen par un expert » du RFC 5226 et seront mis dans le registre IANA.

Et si on utilise HTTP 2, où on est en binaire et plus en texte, et où les en-têtes sont représentés d'une façon complètement différente ? Dans ce cas, on se sert de trames du type ALTSVC (section 4). C'est une extension au protocole original. La trame ALTSVC a le type 0xa (10, dans le registre IANA) et contient un champ Longueur (de l'origine), l'origine, et le service alternatif sous une syntaxe identique à celle de la section précédente.

On l'a vu, le service alternatif fait normalement autorité et doit donc gérer les mêmes ressources. Que se passe-t-il si un serveur maladroit redirige vers une machine qui n'est pas configurée comme service alternatif ? Idéalement, cette machine ne faisant pas autorité doit répondre 421 (RFC 7540, section 9.1.2). Le client doit alors réessayer avec un autre service alternatif, s'il existe, ou bien avec le serveur d'origine. (Aujourd'hui, je crois qu'il est plus fréquent que la machine ne faisant pas autorité renvoie les ressources de sa configuration par défaut.)

Un petit mot d'histoire : ce système des services alternatifs vient d'une solution spécifique à Chrome qui se nommait Alternate-Protocol:. Un bon article de synthèse sur ces services alternatifs est celui de l'auteur du RFC.


Téléchargez le RFC 7838


L'article seul

RFC 7837: IPv6 Destination Option for Congestion Exposure (ConEx)

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : S. Krishnan (Ericsson), M. Kuehlewind (ETH Zurich), B. Briscoe (Simula Research Laboratory), C. Ralli (Telefonica)
Expérimental
Réalisé dans le cadre du groupe de travail IETF conex
Première rédaction de cet article le 15 mai 2016


Le mécanisme ConEx, normalisé dans le RFC 7713, permet d'informer les routeurs situés en aval qu'un flot de données se heurte à la congestion. Il y a plusieurs façons d'indiquer cette congestion, et ce RFC le fait par une option dans l'en-tête Destination Options d'IPv6.

En effet, le mécanisme décrit dans le RFC 7713 est abstrait : il spécifie des concepts, pas comment ils sont représentés sur le câble. Notre RFC 7837, au contraire, est concret : il indique comment mettre l'information ConEx dans des champs du paquet que les équipements réseau, notamment les routeurs, pourront lire. ConEx est actuellement un projet expérimental (et même très expérimental) et il n'est pas sûr qu'il soit déployé avec enthousiasme. En attendant, puisque c'est expérimental, le but est de récolter de l'information et, pour cela, il faut du code qui tourne, avec des paquets concrets (section 1 de notre RFC). Mettre l'information ConEx dans le champ Options d'IPv4 est délicat : ce champ est de taille limitée, et pose souvent des problèmes dans le réseau. L'idée est donc d'utiliser le protocole du futur, IPv6, et ses en-têtes d'extension (RFC 2460, section 4).

La section 3 détaille les choix techniques effectués et leurs raisons. Les sections 3.3 et 4 du RFC 7713 expliquent les contraintes d'encodage concret de ConEx dans les paquets. Ici, les exigences considérées ont été :

  • Les marques ConEx doivent être visibles par tous les nœuds ConEx du chemin (donc, pas question de les mettre tout au bout du paquet),
  • Pour que les paquets marqués arrivent à bon port, même en traversant les équipements actuels qui ne connaissent pas ConEx, il faut un mécanisme standard et déjà largement accepté (pas question de changer le format des paquets IP, cela empêcherait le déploiement incrémental),
  • La présence des marques ConEx ne doit pas ralentir le traitement des paquets (cf. section 5),
  • Les marques ConEx doivent pouvoir être protégées contre les manipulations ultérieures (exigence pas réellement satisfaite en pratique, sauf à utiliser IPsec).

Quatre solutions IPv6 avaient été envisagées par le groupe de travail à l'IETF :

  • Une option Hop-by-hop (RFC 2460, section 4.3).
  • Réutiliser le champ Flow label qui ne sert quasiment pas (cf. RFC 6437),
  • Créer un nouvel en-tête d'extension,
  • Une option Destination (RFC 2460, section 4.6), le choix qui a finalement été fait.

L'en-tête d'extension Hop-by-hop aurait été l'option logique puisqu'elle est examinée par chaque routeur, ce qui est bien ce qu'on veut pour ConEx. Elle aurait été conforme aux principes d'IPv6. Mais, dans les routeurs actuels, le traitement de cette option se fait de manière extrêmement lente (elle n'emprunte pas le chemin rapide dans le routeur, mis en œuvre en ASIC ou FPGA), ce qui viole la troisième exigence. Le choix de l'en-tête Destination, qui est normalement de bout en bout et que les intermédiaires ne sont pas censés regarder, est donc surprenant, mais justifié. Il viole un peu la première exigence (si le paquet est encapsulé, le routeur aura du mal à voir cet en-tête). Et, surtout, analyser la chaîne des en-têtes d'extension IPv6 est anormalement compliqué. Mais il n'y avait guère d'autre choix réaliste. En pratique, certains routeurs auront donc besoin d'un changement de leurs règles de traitement des en-têtes d'extension s'ils veulent voir les marques ConEx.

(Sur la survivabilité des en-têtes d'extension IPv6 dans l'Internet, voir l'étude de Mehdi Kouhen en février 2016 et le RFC 7872.)

La section 4 présente le format concret. La nouvelle option Destination se nomme CDO, pour ConEx Destination Option. Elle est mise dans un en-tête d'extension Destination Options (RFC 2460, section 4.6). Comme les autres options Destination, elle est encodée en TLV. Le type de l'option est 0x1E (30, valeur réservée aux expérimentations, non définitive), sa longueur est 1 (un seul octet, et encore, tous les bits ne sont pas utilisés) et sa valeur est composée de quatre bits (RFC 7713, notamment la section 2.1) : X (« je sais faire du ConEx »), L (« des paquets ont été perdus »), E (« de la congestion a été signalée par ECN ») et C (« pas (encore) de congestion, j'accumule des crédits »). Le dernier bit, C, est à utiliser avant qu'on détecte la congestion (RFC 7713, notamment la section 5.5).

Au passage, si vous écrivez des programmes en C qui veulent ajouter des options dans l'en-tête Destination, vous pouvez consulter mon article.

On a dit plus haut que la principale raison pour utiliser l'en-tête Destination et pas le Hop-by-Hop (qui aurait été plus logique), est le souci que les paquets restent sur le fast path des routeurs (le traitement fait par le matériel, par opposition au slow path, confié au processeur généraliste, bien plus lent). Mais le problème est que l'en-tête Destination, n'étant pas prévu pour être lu par les équipements réseau sur le chemin, peut se trouver n'importe où dans la chaîne des en-têtes (alors que l'en-tête Hop-by-hop est forcément au début, cf. RFC 2460, section 4.1). Et l'option CDO pourrait, en théorie, se trouver n'importe où dans l'en-tête Destination. Notre RFC est donc obligé de recommander (section 5) que l'option CDO soit la première dans l'en-tête Destination.

Reste à voir s'il sera effectivement possible de déployer cette option. L'ossification de l'Internet rend tout déploiement de ce type difficile (les en-têtes d'extension sont rares dans les paquets IPv6 actuels).


Téléchargez le RFC 7837


L'article seul

RFC 7835: Locator/ID Separation Protocol (LISP) Threat Analysis

Date de publication du RFC : Avril 2016
Auteur(s) du RFC : D. Saucez (INRIA), L. Iannone (Telecom ParisTech), O. Bonaventure (Université catholique de Louvain)
Pour information
Réalisé dans le cadre du groupe de travail IETF lisp
Première rédaction de cet article le 30 avril 2016


Le protocole LISP (à ne pas confondre avec le langage de programmation) est un protocole à séparation de l'identificateur et du localisateur. Ces protocoles présentent des défis de sécurité particuliers et ce RFC est donc consacré à une étude détaillée des menaces et risques associés à LISP.

LISP est normalisé dans le RFC 6830. Il peut être utilisé dans un réseau interne ou bien sur l'Internet public et ce RFC étudie sa sécurité dans ce dernier cas, évidemment plus difficile.

Le RFC est en trois parties : la section 2 détaille le modèle de menaces (qui est l'attaquant), la section 3 expose les techniques que peut utiliser l'attaquant, la section 5 décrit les solutions possibles. Il s'agit bien de regarder les attaques génériques contre LISP, pas celles contre une mise en œuvre particulière de LISP, qui peut évidemment avoir ses bogues spécifiques.

Commençons donc par le modèle de menace (section 2). On suppose un attaquant situé quelque part sur l'Internet, éventuellement en plusieurs points de celui-ci. Il peut être sur le chemin des paquets (on path) ou pas (off path). Le premier est évidemment le plus dangereux. S'il est attaquant actif, il peut modifier des paquets et même faire des attaques de l'Homme du Milieu. Si l'attaquant est en dehors du chemin, cela va être plus difficile pour lui. Il ne peut pas modifier les paquets échangés, il peut par contre envoyer des paquets mais, pour que ceux-ci soient acceptés, il faudra qu'ils correspondent à ce qu'attendent les parties légitimes, ce qui fait que l'attaquant devra souvent deviner des informations et compter sur la chance.

Autre façon de classer les attaquants, il y a ceux qui sont internes à un site LISP et ceux qui sont externes. Les attaquants de l'intérieur sont plus dangereux car la machine qu'ils contrôlent (suite à une trahison ou un piratage) est a priori jugée de confiance.

Il faut aussi distinguer les attaquants permanents (live) des attaquants ponctuels (time-shifted). L'attaquant permanent est celui qui reste actif pendant toute la durée de l'attaque. Dès qu'il est neutralisé, l'attaque stoppe. L'attaquant ponctuel peut lancer une attaque, puis se retirer et les effets de l'attaque vont continuer. Ce genre d'attaques est évidemment bien plus dangereux.

L'attaquant peut viser le système de contrôle (control plane) de LISP ou bien son système de transmission des données (data plane). Un exemple typique est le mécanisme de correspondance (mapping) qui permet aux routeurs LISP de trouver le localisateur (le RLOC) en échange de l'identificateur (l'EID). Ce mécanisme de correspondance fait partie du système de contrôle. Si un attaquant veut détourner les paquets, il n'est pas obligé de trouver une faille dans le routage lui-même : s'il arrive à modifier les correspondances, il obtiendra le même résultat. (Comme le ferait une attaque DNS dans l'Internet classique.)

Plusieurs types d'attaques peuvent être faites contre un protocole réseau comme LISP. Il y a les attaques par rejeu, où un attaquant capture des paquets légitimes pour les rejouer intacts plus tard. Ces attaques marchent souvent, même quand les paquets sont protégés par de la cryptographie (l'attaquant n'a pas besoin de modifier les paquets, ni même de les comprendre). Il y a les manipulations de paquets (l'attaquant prend un paquet légitime et le réinjecte). Il y a la suppression complète des paquets.

Plus complexe et plus vicieux, il y a l'usurpation (spoofing). L'attaquant injecte des paquets prétendant venir d'une autre machine. C'est quelque chose qu'on voit souvent sur l'Internet. LISP est une technologie de tunnel et l'usurpation peut donc porter sur deux endroits : l'adresse externe, celle que voient les routeurs IP ordinaires (c'est le RLOC), et l'adresse interne, celle du paquet encapsulé (c'est l'EID). Identifier un usurpateur est bien plus compliqué lorsque des tunnels sont en jeu !

L'attaquant n'est pas forcément un usurpateur. Il peut très bien dire la vérité sur son adresse (rogue attack) par exemple parce qu'il se moque d'être identifié, ou bien parce qu'il est un zombie.

Autre type d'attaque, évidemment, les attaques par déni de service, où l'attaquant ne cherche pas à prendre le contrôle du système, mais à le paralyser (ou à le ralentir).

Parfois, la cible immédiate de l'attaque n'est pas la principale victime : dans les attaques par réflexion, un attaquant utilise un tiers pour renvoyer ses paquets vers la vraie victime. C'est surtout utilisé en combinaison avec l'amplification : lorsque la réponse est plus grosse que la question, un attaquant peut amplifier son trafic. En outre, pour LISP, le système de transmission est certainement bien plus rapide que celui de contrôle et il y a donc en théorie une possibilité d'attaquer le second avec le premier.

Et, bien sûr, il y a les attaques d'espionnage passif, où des grandes oreilles écoutent votre trafic pour vous surveiller, sans eux-mêmes envoyer de paquets. Grâce à Edward Snowden, l'ampleur de ce type d'attaques par les États est désormais bien connu (RFC 7258).

Bon, assez de théorie, comment fait-on avec LISP quand on est un méchant et qu'on veut effectuer une des attaques en question ? Rentrons désormais dans les détails techniques (qui nécessitent de connaitre un peu LISP : relisez les RFC 6830, RFC 7215, RFC 6832, RFC 9301 et RFC 6834). D'abord, le « glanage » (gleaning), la collecte passive d'informations sur les correspondances identificateur->localisateur (RFC 6830, section 6). Il peut être utilisé pour empoisonner le cache des correspondances d'un routeur : le méchant envoie un paquet LISP fabriqué, les routeurs innocents l'observent et enregistrent la correspondance entre l'EID et le RLOC dans leur cache et paf, le méchant a pu détourner le trafic futur. C'est un exemple d'attaque ponctuelle : l'attaquant envoie juste un paquet puis plus rien, mais l'effet persiste pendant toute la durée de vie de l'information dans le cache (quelques secondes, si on suit fidèlement les conseils du RFC 6830, section 6.2).

Autre exemple d'empoisonnement d'un routeur LISP avec de fausses informations, le champ LSB (Locator Status Bits), qui indique l'état (joignable ou pas) des machines situées sur le site de départ du paquet (RFC 6830, section 6.3). En envoyant un paquet usurpé avec un faux LSB, on peut tromper des routeurs innocents. On peut par exemple mettre tous les bits à zéro (qui signifie que le préfixe est injoignable par ce routeur), menant à une attaque par déni de service ou bien les mettre tous à zéro sauf un, menant à une surcharge de cet unique routeur. C'est également une attaque ponctuelle : ses effets se feront sentir même si l'attaquant est neutralisé.

Un point important de LISP est le test de la « joignabilité » (reachability, RFC 6830, section 6.3). LISP vérifie que la machine qui prétend être joignable, et par tel routeur, l'est effectivement. Un des outils pour cela est un numnique envoyé à l'autre machine et qu'elle doit renvoyer. Un attaquant qui arriverait à tricher avec la joignabilité pourrait pousser un routeur LISP d'entrée du tunnel (un ITR) à changer de routeur de sortie (l'ETR) au profit d'un routeur qui ne marche pas. Cela réaliserait une attaque par déni de service. Même s'il n'arrive pas à faire changer de routeur, il pourrait perturber le routage en envoyant des tas de numniques différents. (Rassurez-vous, cette attaque est plus dure à réussir qu'il ne semble, voyez la section 5.)

LISP permet que plusieurs espaces d'adressage coexistent, différenciés par leur instance ID indiquée dans l'en-tête (RFC 6830, section 5.5). Elle n'est pas authentifiée et un attaquant peut donc envoyer des paquets à une autre instance ID que la sienne.

LISP permet de l'interconnexion avec des réseaux non-LISP (RFC 6832). Ces mécanismes ont des attaques très similaires à celles qu'on peut faire contre LISP lui-même. Par exemple, un paquet avec une adresse source usurpée peut être transmis sur l'Internet par la passerelle LISP.

Mais les pires attaques se situeront sans doute sur le système de correspondance (mapping). Le point central de tous les systèmes à séparation de l'identificateur et du localisateur est de découpler deux fonctions qui, dans IP, sont confondues. Cela suit un grand principe de l'informatique : « tout problème peut être résolu en ajoutant un degré d'indirection ». Sauf que cette séparation se paie en sécurité : il faut bien, à un moment, faire correspondre identificateur et localisateur et, là, cette nouvelle fonction, la correspondance, offre de nouvelles possibilités d'attaque.

Ainsi, les messages Map-Request (RFC 6830, section 6) peuvent être utilisés de plusieurs façons. Envoyés en masse, à un système de contrôle qui est bien moins rapide que le système de transmission, ils peuvent saturer les routeurs. Comme la réponse (Map-Reply) est plus grosse que la question, ils peuvent servir à des attaques par amplification.

Et si un attaquant réussit à fabriquer de fausses réponses (Map-Reply) et à les faire accepter ? Il devra pour cela mettre le numnique correct dans ses paquets. Comme il fait 64 bits, si on a suivi les bons principes du RFC 4086 pour le générer, un attaquant qui n'est pas sur le chemin (et doit donc deviner le numnique) n'a que peu de chances de réussir. Mais attention, le numnique n'est pas une signature : il indique juste que le paquet est bien une réponse à une question posée. Si l'attaquant peut modifier les paquets, il peut empoisonner le cache de correspondance du routeur. Variante de cette attaque, si le méchant est un routeur légitime (rogue attack), il peut répondre, mais avec de fausses réponses. Il ne peut pas annoncer des préfixes quelconques mais il peut annoncer des préfixes plus généraux que ceux qu'il gère réellement (par exemple annoncer qu'il gère 192.0.2.0/24 alors qu'il ne contrôle que 192.0.2.0/26), ce qui lui permet de détourner le trafic.

Enfin, il y a les Map-Register, ces messages envoyés par les routeurs aux serveurs de correspondance pour les informer des préfixes gérés (RFC 9301, section 4.2). Ils sont authentifiés donc, normalement, un attaquant quelconque ne peut pas les usurper. Mais il reste des attaques résiduelles comme l'annonce de préfixes plus généraux que les siens.

Au passage, un problème de sécurité qu'on oublie parfois est celui de la vie privée (section 4). Les correspondances LISP sont publiques (comme les tables BGP dans l'Internet classique) et il ne faut donc pas oublier qu'on ne peut pas participer à LISP discrètement.

Et pour finir, les solutions (section 5). Comment faire pour éviter ces menaces ? Le RFC donne des conseils très généraux (« déployer soigneusement », « appliquer les règles habituelles de sécurité ») mais aussi des indications plus précises et spécifiques à LISP. Clairement, le plan de contrôle est la partie la plus sensible. Il est donc important d'utiliser les techniques d'authentification décrites dans le RFC 9301 (voir notamment sa section 6). Des extensions de sécurisation de LISP sont en cours de développement.

D'autre part, les conseils de sécurité du RFC 6830 doivent être suivis. Par exemple, quand ce RFC écrit qu'il faut limiter le rythme des Map-Request, cela doit être appliqué.

L'information obtenue par examen des paquets (comme le glanage cité plus haut) n'est évidemment pas de confiance : à n'utiliser que pour le flot de données qui contenait cette information, ou alors à vérifier avant. (Voir aussi « How to mitigate the effect of scans on mapping systems ».)


Téléchargez le RFC 7835


L'article seul

RFC 7830: The EDNS(0) Padding Option

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : A. Mayrhofer (nic.at GmbH)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dprive
Première rédaction de cet article le 11 mai 2016


Ce nouveau RFC fait partie de la série de ceux qui tentent d'améliorer la situation du DNS pour tout ce qui concerne la protection de la vie privée. Parmi les efforts dans ce domaine, il y a une possibilité de chiffrement des communications DNS, dans le RFC 7858 (DNS-sur-TLS). Elle utilise le protocole TLS. Ce dernier ne fait rien pour dissimuler la longueur des requêtes et réponses DNS. Or, de telles métadonnées peuvent suffire à identifier les requêtes faites. Il est donc important de compléter le chiffrement avec un mécanisme de remplissage (padding). C'est ce que permet la nouvelle option EDNS normalisée dans ce RFC.

Trouver la requête effectuée uniquement à partir de la taille de la réponse est d'autant plus facile que les données DNS ne sont pas confidentielles. Un espion qui soupçonne que M. Michu fait des requêtes pour tel nom de domaine peut faire la même requête, noter la taille de la réponse chiffrée, et voir s'il trouve la même taille dans les réponses reçues par M. Michu. Voilà pourquoi il faut ajouter aux requêtes et aux réponses un certain nombre d'octets, pour rendre plus difficile cette analyse des métadonnées.

Ce RFC est court car le mécanisme est très simple (section 3 du RFC). Ce mécanisme utilise une nouvelle option EDNS (EDNS est normalisé dans le RFC 6891.) Cette option porte le numéro 12 et sa partie « données » porte le remplissage. (Comme toute option EDNS, elle est encodée en TLV : un champ indique le type de l'option, ici, 12, un champ indique la longueur de l'option, et le dernier contient les données.)

Que mettre comme remplissage ? Cette question a été la plus discutée lors de la création de ce RFC (qui a été plutôt calme et consensuelle, pour le reste.) Le RFC précise que l'émetteur d'un message DNS devrait remplir avec des octets nuls (0x00). Si l'émetteur craint que certains traitements (par exemple de la compression, voyez cependant la section 6 qui demande de ne pas l'utiliser) appliqués avant le chiffrement ne suppriment l'essentiel du remplissage, il est autorisé à mettre une autre valeur. De toute façon, le récepteur doit accepter n'importe quelle valeur, pour permettre les évolutions futures. En pratique, il doit donc ignorer le contenu des données de cette option.

Pourquoi n'avoir pas simplement dit que l'émetteur pouvait mettre ce qu'il voulait, dans ce cas ? Parce qu'il semblait possible, dans ce cas, que des programmeurs naïfs utilisent de la variable non initialisée, et laissent ainsi fuiter le contenu de leur mémoire (comme dans la faille Heartbleed.) Et pourquoi n'avoir pas spécifié un remplissage avec des données aléatoires ? Parce que ce n'est pas normalement nécessaire : pour un observateur, le contenu chiffré doit apparaitre aléatoire, quel que soit le texte en clair (si TLS ne fournissait pas cette propriété, des tas d'attaques seraient possibles, par exemple à base de texte en clair connu.)

Voilà, l'essentiel du RFC tient dans cette courte section 3. Mais quelques détails suivent. Par exemple, quelle quantité d'octets mettre dans la nouvelle option ? Le RFC ne fournit pas de guide à ce sujet, il rappelle juste qu'il ne faut pas aboutir à des messages plus gros que ce que le client spécifiait dans son champ Payload size EDNS (souvent 4 096 octets mais cela dépend du client.) Des règles plus précises sur la politique de remplissage ont été normalisées par la suite dans le RFC 8467. Le serveur DNS ne doit évidemment pas utiliser cette option si la requête ne contenait pas d'EDNS. Si elle contenait de l'EDNS sans cette option, le serveur est libre de remplir ou pas. Si la requête contenait de l'EDNS avec l'option Padding, alors, le serveur doit effectuer du remplissage.

Quelques trucs à ne pas oublier en section 6 : le remplissage augmente la taille des paquets (évidemment). Cela mènera donc à un accroissement du trafic. Dans l'Internet d'aujourd'hui, où tous les États qui en ont les moyens procèdent à une surveillance massive de leurs citoyens (RFC 7258), c'est un petit prix à payer, pour l'avantage de compliquer le travail des surveillants.

Autre piège, l'option de remplissage ne doit être utilisée que si le trafic DNS est chiffré. Autrement, non seulement elle ne servirait à rien, mais elle augmenterait le risque d'attaques avec amplification.

À noter que, comme plein d'autres champs des messages DNS (comme par exemple le QNAME, le Query Name), cette option peut servir de canal caché. Peut-être verra-t-on un jour une mise en œuvre d'IP-sur-DNS utilisant cette option ?

Notez que cette technique est indépendante du protocole de chiffrement sous-jacent, puisqu'elle est faite au niveau applicatif. DNScrypt pourrait l'utiliser (sauf qu'il a son propre système de remplissage.)

Et les mises en œuvre de cette technique ? A-t-on du code qui tourne ? getdns a le remplissage depuis sa version 0.5.1 (cf. le Changelog.) GoDNS y travaille. Wireshark peut analyser cette option. La page officielle sur cette option de remplissage liste d'autres mises en œuvre.

Depuis la sortie de ce RFC, les clients et serveurs DNS ont peu à peu intégré cette option de remplissage. Voyons ici kdig avec le serveur public de Cloudflare :

% kdig +dnssec +tls +padding @1.1.1.1 A chatons.org
...
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: do; UDP size: 1232 B; ext-rcode: NOERROR
;; PADDING: 301 B
    

Notez que 1.1.1.1 met du remplissage même si le client ne l'a pas demandé, ce que permet la section 4 du RFC.

Daniel Kahn Gillmor, qui avait programmé cette extension dans getdns, en a profité pour faire quelques statistiques :

Ethernet Frame sizes for packet containing DNS query

                Transport    |   query to   |     query to
                   used      |  example.com |  www.example.com
   --------------------------+--------------+-------------------
               cleartext UDP |   82 octets  |   86 octets
               cleartext TCP |  108 octets  |  112 octets
                TLS over TCP |  137 octets  |  141 octets
(padded to 512) TLS over TCP |  609 octets  |  609 octets
  

On voit que le remplissage brouille la différence de taille entre les deux requêtes. Mais restons prudents : le remplissage est une bonne technique pour rendre plus difficile l'analyse des métadonnées mais il n'est pas parfait. Lisez par exemple l'excellent « Peek-a-Boo, I Still See You : Why Efficient Traffic Analysis Countermeasures Fail ».


Téléchargez le RFC 7830


L'article seul

RFC 7828: The edns-tcp-keepalive EDNS0 Option

Date de publication du RFC : Avril 2016
Auteur(s) du RFC : P. Wouters (Red Hat), J. Abley (Dyn), S. Dickinson (Sinodun), R. Bellis (ISC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 11 avril 2016
Dernière mise à jour le 12 avril 2016


Historiquement, le DNS utilisait surtout UDP et le transport sur TCP ne servait qu'à des cas particuliers, comme lorsqu'un client DNS ré-essayait avec TCP de récupérer des données trop grosses pour UDP. Depuis le RFC 7766, ce n'est clairement plus le cas : TCP est désormais aussi utilisable qu'UDP pour le DNS. Mais les mises en œuvre typique du DNS sur TCP ont des restrictions, par exemple des délais maximum d'attente avant de « raccrocher » qui sont trop courtes, de l'ordre de quelques secondes lorsqu'il n'y a plus de trafic sur la connexion. Ce nouveau RFC propose un mécanisme EDNS permettant au client DNS de signaler au serveur qu'il souhaite garder la connexion ouverte, si le serveur est d'accord, s'il vous plait. (Notez qu'il existe une autre façon d'indiquer le temps pendant lequel on souhaite garder la session, celle des DSO du RFC 8490 ».)

Utiliser une connexion TCP par requête DNS serait en effet très inefficace, notamment question latence. Il faudrait effectuer la triple poignée de mains TCP à chaque requête. Le DNS sur TCP n'est envisageable que si les connexions restent ouvertes et que la même connexion peut servir pour plusieurs requêtes. Dans ce cas, lorsque la connexion a déjà été ouverte, la latence peut être aussi faible qu'avec UDP, voire meilleure (dans le cas de données de grande taille, par exemple avec DNSSEC, plus besoin d'essayer d'abord sur UDP). Reste une question pour le serveur DNS : faut-il laisser la connexion ouverte dès qu'il n'y a plus de requêtes à traiter ? Cette nouvelle option EDNS edns-tcp-keepalive permet au client DNS d'indiquer que, lui, il est prêt à réutiliser la connexion et qu'il souhaite qu'on la garde ouverte.

Le serveur souhaite économiser ses ressources (mémoire, notamment). Contrairement à UDP, TCP nécessite que le serveur garde un état. Imaginons que chaque connexion TCP prenne une entrée dans un grand tableau des connexions TCP en cours. Si c'était « open bar » pour les clients, qu'ils puissent ouvrir autant de connexions qu'ils veulent, et les garder éternellement ensuite, le tableau serait vite rempli, menant à un déni de service. (Et si vous pensez qu'à la place du tableau, une structure de données dynamique, grossissant automatiquement, résoudrait le problème, rappelez-vous que la mémoire du serveur est finie...) Le serveur choisit donc s'il garde les connexions ouvertes, et combien de temps.

Au passage, la section 1 du RFC rappelle aussi qu'UDP a des problèmes sérieux, notamment parce qu'il permet des attaques par réflexion et parce qu'il implique, pour les grosses données, de la fragmentation, qui est en général une source d'ennuis (voir par exemple «  Fragmentation Considered Poisonous de Herzberg et Shulman). D'où cet encouragement, depuis des années, à utiliser de plus en plus TCP.

La section 3 est la partie centrale du RFC, la spécification de la nouvelle option. Elle utilise EDNS (RFC 6891). Elle permet d'indiquer le délai d'attente avant la fermeture de la connexion, délai qui commence à courir lorsque la connexion devient inactive (« idle », cf. la section 3 du RFC 7766).

L'option se nomme edns-tcp-keepalive et a reçu le code 11 (stocké dans le registre des options EDNS). Elle prend un seul argument, encodé sur deux octets, TIMEOUT qui indique la durée du délai de garde, exprimée en unités de 100 millisecondes. Cette valeur n'apparait que dans les réponses du serveur, pas dans les requêtes du client. Si TIMEOUT vaut 600, cela signifie que les connexions restent ouvertes pendant une minute après la dernière requête reçue.

Ensuite, une fois cette option définie, comment on s'en sert ? Elle ne doit évidemment pas être utilisée sur UDP, où elle n'aurait aucune signification. Le client doit utiliser cette option pour signaler qu'il souhaiterait garder cette connexion ouverte (il ne doit pas indiquer de valeur pour TIMEOUT). Le serveur utilise cette option pour indiquer le temps pendant lequel il va garder la connexion (rappelez-vous que le client peut demander ce qu'il veut, c'est le serveur qui décide). Le client est censé « raccrocher » juste avant l'expiration de ce délai. Une valeur de 0 pour TIMEOUT signifie « raccroche tout de suite » (un serveur l'envoie, par exemple, lorsqu'il est soumis à un fort stress et n'a plus de ressources disponibles.)

Au passage, si le serveur n'a plus envie de supporter cette connexion, pourquoi ne raccroche-t-il pas lui-même, au lieu de demander au client de le faire ? C'est parce que le pair TCP qui ferme la connexion le premier passe ensuite en état TIME-WAIT (RFC 793, section 3.5) et que cela l'oblige à garder un état pendant deux fois la durée de vie maximale d'un segment TCP (soit quatre minutes en tout). Il vaut donc mieux demander au client de le faire. Par contre, après avoir envoyé le TIMEOUT=0, le serveur va avoir un délicat arbitrage à faire entre attendre que le client raccroche et fermer de lui-même la connexion (et donc garder une prise en état TIME-WAIT) quand le client n’obtempère pas suffisamment vite.

La section 5 du RFC recommande d'ailleurs aux serveurs de suivre l'activité de leurs clients et de « punir », d'une façon ou d'une autre, ceux qui violeraient ces règles, par exemple en continuant à envoyer des requêtes alors qu'on leur a demandé de raccrocher.

J'insiste mais cela vaut la peine d'être dit et répété : cette option edns-tcp-keepalive ne diminue pas la liberté des clients et des serveurs DNS. En cas de problème (tableau des connexions TCP en cours presque plein, par exemple), clients et serveurs sont libres de couper les connexions TCP plus tôt, ce qu'on appelle le « TCP session management ».

Comme d'habitude avec toute nouvelle option, on peut s'attendre à des problèmes avec les stupides middleboxes. Une requête contenant cette option peut ainsi être jetée alors qu'elle ne l'aurait pas été sans l'option. Une stratégie de repli comme celle de la section 6.2.2 du RFC 6891 peut donc être utile.

Merci à Kim-Minh Kaplan pour d'utiles précisions sur TCP.


Téléchargez le RFC 7828


L'article seul

RFC 7826: Real-Time Streaming Protocol Version 2.0

Date de publication du RFC : Décembre 2016
Auteur(s) du RFC : H. Schulzrinne (Columbia University), A. Rao (Cisco), R. Lanphier, M. Westerlund (Ericsson AB), M. Stiemerling (NEC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mmusic
Première rédaction de cet article le 28 décembre 2016


Voici la version 2 du protocole bien connu RTSP, protocole servant à accéder à des flux vidéo. Comme c'est ce que j'utilise pour regarder la télévision sur l'écran de mon PC, je suis ravi que l'IETF se préoccupe de l'améliorer.

Comme beaucoup de protocoles dans le monde du multimédia (SIP, par exemple), RTSP est en fait uniquement un protocole de contrôle, permettant de déclencher ou d'arrêter des flux audio ou vidéo. Ces flux peuvent être temps-réel ou bien avoir simplement été stockés sur le disque d'un serveur. Donc, RTSP est une zapette logicielle. RTSP fait le contrôle et plusieurs protocoles peuvent être utilisés pour le transport des données, UDP, TCP, RTP, etc. À noter la taille impressionnante de ce RFC, avec plus de 300 pages. Ce n'est pas que le protocole soit si compliqué que cela, mais il y a beaucoup d'options et de choix.

La section 2 du RFC résume le protocole : RTSP est client/serveur, le client RTSP se connecte au serveur, un certain nombre de choix techniques sont faits et ensuite l'envoi des données commence. Physiquement, les messages sont du texte (la syntaxe de RTSP ressemble beaucoup à celle d'HTTP) bien que du binaire soit parfois possible. La ressource convoitée est identifiée par un URI de plan rtsp (ou rtsps pour TLS) et cet URI contient le nom de la machine qui sera utilisée comme serveur. Par exemple, si je dis à mon logiciel RTSP d'utiliser rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=658&flavour=ld, la connexion RTSP sur TCP (ou TCP avec TLS) se fera avec mafreebox.freebox.fr. La requête RTSP inclus un certain nombre d'en-têtes comme dans HTTP, et parfois un corps (toujours comme en HTTP). Voici un exemple avec le client VLC. Je le lance avec vlc 'rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=897' et on voit (tcpdump ne sait pas apparemment décoder le RTSP mais Wireshark y arrive très bien) :

Internet Protocol Version 4, Src: 192.168.2.1 (192.168.2.1), Dst: 212.27.38.253  (212.27.38.253)
Transmission Control Protocol, Src Port: 45854 (45854), Dst Port: rtsp (554), Seq: 563, Ack: 873, Len: 204
Real Time Streaming Protocol
    Request: PLAY rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=897 RTSP/1.0\r\n
    CSeq: 5\r\n
    User-Agent: LibVLC/2.0.3 (LIVE555 Streaming Media v2012.05.17)\r\n
    Session: pokf6CQWbA8CUyC
    Range: npt=0.000-\r\n
    \r\n

Dans l'exemple ci-dessus, le protocole était RTSP version 1.0 (rappelez-vous que ce RFC décrit la version 2), la requête était PLAY (dont le nom dit bien ce qu'elle fait et vous ne serez pas surpris d'apprendre qu'il existe une commande PAUSE) et l'un des en-têtes, User-Agent: montre que j'utilise bien vlc.

Quand au trafic lui-même, on voit (ici avec tcpdump) d'abord du RTSP sur TCP puis un gros flux UDP :

21:34:36.179830 IP (tos 0x10, ttl 64, id 20888, offset 0, flags [DF], proto UDP (17), length 1356)
    212.27.38.253.46099 > 192.168.2.1.34324: [udp sum ok] UDP, length 1328
21:34:36.180040 IP (tos 0x10, ttl 64, id 20889, offset 0, flags [DF], proto UDP (17), length 1356)
    212.27.38.253.46099 > 192.168.2.1.34324: [udp sum ok] UDP, length 1328
21:34:36.180738 IP (tos 0x10, ttl 64, id 20890, offset 0, flags [DF], proto UDP (17), length 1356)
    212.27.38.253.46099 > 192.168.2.1.34324: [udp sum ok] UDP, length 1328

Les contenus auxquels on accède avec RTSP peuvent être de type très variés. Il faut donc une description formalisée des caractéristiques de ce contenu. RTSP peut utiliser plusieurs formats pour cela, le plus répandu étant sans doute SDP (RFC 4566). C'est en tout cas celui utilisé entre mon VLC et ma Freebox. La description peut inclure le nombre de flux (souvent un flux vidéo et plusieurs audios), le protocole de délivrance (RTPRFC 3550 - dans l'exemple ci-dessous), le format (MPEG-2 ici), etc :

    Session Description Protocol
        Session Description Protocol Version (v): 0
        Owner/Creator, Session Id (o): leCDN 1395332443 1395332443 IN IP4 kapoueh.proxad.net
...
        Media Description, name and address (m): video 0 RTP/AVP 33
            Media Type: video
            Media Port: 0
            Media Protocol: RTP/AVP
            Media Format: MPEG-II transport streams
        Media Attribute (a): control:rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=658&flavour=ld
            Media Attribute Fieldname: control
            Media Attribute Value: rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=658&flavour=ld

Quels sont les changements par rapport à RTSP version 1, la version du RFC 2326 ? Les deux versions, quoique identiques dans leurs principes, ne sont pas compatibles (par exemple, la commande PLAY n'a plus le même comportement, des en-têtes ont changé de syntaxe sans changer de nom, etc). C'est toujours un choix difficile que de casser la compatibilité d'un protocole mais, là, c'était nécessaire vu le nombre de modifications. En outre, RTSP 1 ne permettait pas de déployer facilement des extensions (en-têtes à la syntaxe trop rigide) et le modèle d'extension a changé. L'annexe I de notre RFC résume ce qu'il faut savoir sur ces différences : suppression des requêtes RECORD et ANNOUNCE, suppression de l'option qui permettait de faire passer RTSP (le contrôle, pas les données) sur UDP, gestion complète d'IPv6 (qui manquait en version 1), refactorisation du RFC (les en-têtes qui sont proches de ceux de HTTP sont désormais décrits par un texte spécifique, sans renvoyer au RFC HTTP), etc.

Il y a apparemment au moins une mise en œuvre de RTSP qui a la version 2, et plusieurs des nouveautés de la version 2 ont été mises en œuvre de manière séparée.


Téléchargez le RFC 7826


L'article seul

RFC 7824: Privacy considerations for DHCPv6

Date de publication du RFC : Mai 2016
Auteur(s) du RFC : S. Krishnan (Ericsson), T. Mrugalski (ISC), S. Jiang (Huawei Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF dhc
Première rédaction de cet article le 12 juin 2016


Le protocole DHCP sert à transmettre à une machine qui vient de se connecter au réseau, des informations utiles pour sa connexion. Il est surtout connu pour son utilisation avec IPv4 mais DHCP existe aussi pour IPv6 (il est normalisé dans le RFC 8415). Comme son équivalent IPv4, DHCP pour IPv6 pose un certain nombre de problèmes de vie privée, que ce RFC explore.

Il fait donc partie de la série de RFC développés après le RFC 6973 et, surtout, après les révélations de Snowden qui ont mené l'IETF à s'engager plus vigoureusement contre la surveillance massive. Ce RFC ne propose pas de solutions (elles sont décrites dans le RFC 7844), il décrit le problème.

Le problème fondamental est le même qu'en IPv4 (RFC 7819) : le client DHCP, lorsqu'il vient de se connecter à un réseau et émet des requêtes, publie des informations trop détaillées, dont certaines sont des véritables identificateurs stables (cf. section 2 de notre RFC), permettant au serveur DHCP, mais aussi à toute machine qui écoute le réseau, de suivre à la trace une machine donnée. Au contraire des solutions comme SLAAC, où le client est purement passif, DHCP impose au client d'annoncer son existence et de donner des informations. Bref, si vous avez déjà lu le RFC équivalent pour IPv4, le RFC 7819, vous n'apprendrez pas grand'chose de nouveau.

La section 3 du RFC donne une liste aussi complète que possible des options DHCPv6 qui peuvent servir à la surveillance. D'abord, l'adresse IP source. Bon, elle ne fait pas partie de DHCP à proprement parler et tout protocole va la publier, puisqu'elle apparait dans tous les paquets émis. (Dans le cas de DHCP, la requête du client est émise depuis une adresse locale au lien, link-local, celles qui commencent par fe80::.) Néanmoins, l'adresse IP source mérite une mention car certains mécanismes de génération d'une adresse IPv6 peuvent poser des problèmes de vie privée (cf. RFC 7721). Il faut donc utiliser des mécanismes comme ceux du RFC 8981 ou du RFC 7217.

L'exemple suivant est celui d'une option particulièrement dangereuse pour la vie privée, Client Identifier, qui envoie au serveur le DUID (DHCPv6 Unique Identifier, RFC 8415, section 11) du client. Comme son nom l'indique, il identifie chaque machine de manière unique et, par défaut, il est stable. La méthode la plus courante pour le générer est d'utiliser l'adresse MAC, elle-même un identificateur unique et stable. Même si on prend la précaution de changer l'adresse MAC, le DUID ne change pas. C'est donc un excellent moyen de suivre une machine, cassant complètement la sécurité de techniques comme celle du RFC 8981.

Également dangereuse, l'option Client FQDN (RFC 4704) qui envoie un FQDN.

Certaines options peuvent être moins clairement indiscrètes mais peuvent néanmoins révéler indirectement l'identité du client. C'est le cas de l'option Option Request qui dit au serveur quelles options on souhaiterait qu'il utilise. Cette liste de choix peut servir à distinguer entre plusieurs clients DHCP : toutes les fois où il y a un choix dans un protocole, il y a une possibilité de fingerprinting.

Certaines options n'envoient pas directement un identificateur unique mais envoient de l'information sur une classe à laquelle appartient la machine. Par exemple, les options Vendor Class et Vendor-specific Information (sections 21.16 et 21.17 du RFC 8415), ou encore l'option Client System Architecture (RFC 5970), indiquent le matériel et le logiciel du client.

On n'a vu ici que des options allant du client vers le serveur mais l'inverse existe aussi, et certaines options qu'un serveur peut envoyer sont révélatrices (par exemple Civic Location, RFC 4776). Mais les problèmes de vie privée du serveur sont moins graves que ceux du client et notre RFC passe donc rapidement (voir aussi la section 5.3).

En dehors des options DHCP, certains mécanismes utilisés dans le cadre de DHCP peuvent être bien indiscrets. C'est par exemple le cas de la demande d'adresses temporaires (RFC 8415, section 6.5), pourtant bien intentionnée. Le but était de pouvoir obtenir des adresses qui ne soient pas stables, pour minimiser justement les risques pour la vie privée. Le RFC détaille les nombreux problèmes et pièges que récèle ce mécanisme. Mais le principal problème est que la seule demande de ces adresses, visible par tout surveillant, est déjà très révélatrice ! Cela revient à sa promener avec une cagoule sur sa tête pour préserver sa vie privée.

Autre mécanisme qui peut être révélateur, la mise à jour du DNS que font certains serveurs DHCP. Si le nom utilisé est stable (cf. l'option Client FQDN mentionnée plus haut), tout surveillant ayant accès au DNS (c'est-à-dire tout le monde) pourra suivre les changements d'adresse IP de la machine, connaissant ainsi ses déplacements d'un réseau à l'autre.

Les stratégies d'allocation d'adresses du serveur DHCP peuvent également être dangereuses pour la vie privée. Le serveur DHCP dispose d'une certaine plage d'adresses. S'il alloue les adresses en commençant toujours par la plus basse adresse libre, les adresses attribuées vont être assez prévisibles, ce qui n'est en général pas bon pour la discrétion. (Et ce mécanisme, qui a certes l'avantage d'être simple et rapide, tend à concentrer les adresses allouées au début de la plage.) Autre possibilité, allouer des adresses fixes (le même client - identifié par une option comme Client Identifier - a toujours la même adresse IP). C'est évidemment très pratique pour l'administrateur du réseau local. Mais c'est la pire solution pour la vie privée, puisque cela oblige le client à divulguer son identité, et cela permet même aux serveurs extérieurs de le suivre à la trace lorsqu'il communique avec eux avec son adresse fixe. Pour la vie privée, la meilleure stratégie d'allocation est sans doute le tirage au sort parmi les adresses libres de la plage.

Maintenant qu'on a vu les vulnérabilités de DHCPv6, voyons ce qu'un attaquant peut en faire (section 5 du RFC). D'abord, il peut découvrir le type de machine chez le client (matériel et/ou logiciel), ce qui peut être utile, par exemple pour sélectionner une attaque spécifique à un système d'exploitation, ou bien, si le matériel/logiciel utilisé est rare, pour identifier un client particulier. Cette information sur le type de machine peut être trouvé dans l'adresse MAC (les premiers octets identifient le vendeur), dans les identificateurs dérivés de l'adresse MAC, ou dans les options comme Vendor Class.

L'espion peut également utiliser ces faiblesses de DHCPv6 pour identifier les réseaux visités précédemment (je n'en ai pas parlé plus haut, mais il existe une option qui indique la précédente adresse IP utilisée : elle est pratique pour obtenir une adresse stable, mais elle est indiscrète).

Plus généralement, le surveillant peut essayer de découvrir une identité stable, lui permettant de savoir combien de machines utilisent ce serveur DHCP, et lui permettant également de corréler deux machines sur deux réseaux, découvrant qu'il s'agit en fait de la même. Le DUID est particulièrement sensible ici.

Le surveillant peut ainsi suivre une machine, soit dans le temps (toutes ses activités en un réseau donné), soit dans l'espace (suivre à la trace un engin mobile).

Si le surveillant a les moyens d'une agence d'un État riche (par exemple si le surveillant est la NSA), il peut effectuer une surveillance massive très efficace (RFC 7258). Il est par exemple conceptuellement aisé de bâtir une liste de très nombreuses machines, en observant beaucoup de réseaux : les failles de sécurité de DHCPv6 citées dans ce RFC permettront de reconnaitre chaque machine individuelle. Ainsi, un organisme comme la NSA peut se faire une base de données permettant de répondre très vite à des questions du genre « où était 38:59:f9:7d:b6:47 la dernière fois qu'on l'a vu ? »

Enfin, la section 6 de notre RFC rappelle une triste réalité : en sécurité, il faut en général faire des compromis. Ici, le RFC note que toute authentification du client va à l'encontre du souhait de préserver la vie privée. Ce genre de choix (sécurité de son réseau, ou bien vie privée des utilisateurs) est bien embêtant pour l'administrateur système.


Téléchargez le RFC 7824


L'article seul

RFC 7819: Privacy considerations for DHCP

Date de publication du RFC : Avril 2016
Auteur(s) du RFC : S. Jiang (Huawei Technologies), S. Krishnan (Ericsson), T. Mrugalski (ISC)
Pour information
Réalisé dans le cadre du groupe de travail IETF dhc
Première rédaction de cet article le 3 mai 2016


Le protocole DHCP est bien connu : la grande majorité des machines « client » qui se connectent à l'Internet l'utilisent pour récupérer des éléments de configuration indispensables, comme l'adresse IP à utiliser. Mais peu de gens sont conscients que DHCP peut être dangereux pour la vie privée : le client DHCP n'est en effet pas passif, il envoie au serveur des informations qui peuvent permettre de suivre à la trace une machine mobile.

DHCP pour IPv4 est normalisé dans le RFC 2131. (Le RFC 7824 traite le cas de DHCP pour IPv6, qui pose des problèmes similaires.) Son principe de fonctionnement est simple : le client DHCP (la machine de M. Michu) envoie à la cantonade une requête pour demander des informations de configuration réseau, le serveur DHCP se reconnait, il répond avec ces informations. Voici une transaction DHCP, vue par tcpdump :

   21:32:13.284690 IP (tos 0x0, ttl 64, id 960, offset 0, flags [none], proto UDP (17), length 377)
    0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from b8:27:eb:84:35:e3, length 349, xid 0x4feaaa6f, Flags [none] (0x0000)
	  Client-Ethernet-Address b8:27:eb:84:35:e3
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message Option 53, length 1: Request
	    Client-ID Option 61, length 19: hardware-type 255, eb:84:35:e3:00:01:00:01:c7:92:bc:8a:b8:27:eb:ba:90:94
	    Requested-IP Option 50, length 4: 192.168.2.9
	    MSZ Option 57, length 2: 1500
	    Vendor-Class Option 60, length 46: "dhcpcd-6.9.0:Linux-4.4.8-2-ARCH:armv6l:BCM2708"
	    Hostname Option 12, length 5: "amour"
	    T145 Option 145, length 1: 1
	    Parameter-Request Option 55, length 14: 
	      Subnet-Mask, Classless-Static-Route, Static-Route, Default-Gateway
	      Domain-Name-Server, Hostname, Domain-Name, BR
	      NTP, Lease-Time, Server-ID, RN
	      RB, Option 119
	    END Option 255, length 0
21:32:13.299825 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 576)
    192.168.2.254.67 > 192.168.2.9.68: [udp sum ok] BOOTP/DHCP, Reply, length 548, xid 0x4feaaa6f, Flags [none] (0x0000)
	  Your-IP 192.168.2.9
	  Client-Ethernet-Address b8:27:eb:84:35:e3
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message Option 53, length 1: ACK
	    Server-ID Option 54, length 4: 192.168.2.254
	    Lease-Time Option 51, length 4: 43200
	    Subnet-Mask Option 1, length 4: 255.255.255.0
	    Default-Gateway Option 3, length 4: 192.168.2.254
	    Domain-Name-Server Option 6, length 8: 192.168.2.254,149.20.64.21
	    BR Option 28, length 4: 192.168.2.255
	    END Option 255, length 0
	    PAD Option 0, length 0, occurs 264   
    

Malheureusement, dans la requête du client se trouvent plein de détails sur la machine demanderesse (section 1 du RFC). Compte-tenu de la sensibilité aux problèmes de vie privée (RFC 6973) et de l'ampleur de la surveillance de masse exercée par les États (RFC 7258), il était nécessaire de limiter cette fuite d'informations. Ce premier RFC va décrire le problème, et proposer quelques pratiques qui le limitent. Le RFC 7844 détaille un profil DHCP qui limite sérieusement la fuite. Dans une prochaine étape, il y aura peut-être des modifications au protocole DHCP mais ce n'est pas encore fait.

Pour cette analyse de sécurité, la section 2 de notre RFC introduit la notion d'identificateur stable. Un identificateur stable (stable identifier) est une information envoyée par le client DHCP qui change peu ou pas dans le temps (et qui peut donc permettre de tracer une machine mobile). La stabilité peut dépendre de la mise en œuvre logicielle utilisée. Ainsi, une adresse MAC est typiquement un identificateur stable mais, si macchanger est utilisé, ce n'est plus le cas. Un identificateur stable n'est pas forcément mondialement unique.

Le gros de ce RFC est la section 3, qui liste les identificateurs envoyés par le client DHCP. Le plus évident, car il est prévu pour cela, est l'option DHCP Client Identifier (RFC 2131, section 2, et RFC 2132, section 9.14). Il est en général stable (le RFC 1533, prédécesseur du RFC 2132, recommandait même d'utiliser une adresse MAC, mais on voit parfois un nom de domaine, ou bien un DUID - décrit dans le RFC 4361). Même si on utilise un logiciel comme macchanger pour changer d'adresse MAC, pas mal de mises en œuvre de DHCP utiliseront la valeur initiale et la stockeront... pour toujours.

Moins spectaculaire, plusieurs champs de la requête transportent des identificateurs fondés sur une adresse. C'est le cas de yiadrr, qui indique l'adresse IP actuelle du client ou chaddr qui indique l'adresse MAC. Plusieurs options font de même comme la Requested IP Address (qui permet d'indiquer l'adresse IP qu'on souhaiterait recevoir).

Autre option qui envoie un identificateur stable, et souvent unique, l'option Client FQDN (RFC 4702) qui transmet au serveur le FQDN.

Après les adresses et les noms de domaine, un autre danger se présente avec les options qui permettent au client d'indiquer le logiciel qu'il utilise. C'est le cas de l'option Vendor class (RFC 2132, section 9.13, une sorte d'équivalent du User-Agent: de HTTP, dans l'exemple plus haut, elle indique une machine ARM sous Linux), du Vendor-Identifying du RFC 3925, et de toutes les options Vendor-specific information (RFC 2132, section 8.4), qui peuvent indiquer le numéro de version du logiciel utilisé, sa configuration spécifique, etc. Certes, elles ne sont pas uniques (elles ne désignent pas une machine particulière) mais elles font quand même fuiter de l'information sur le client et, combinées avec d'autres informations, elles peuvent mener à une identification unique. Une option analogue est Client System Architecture Type (RFC 4578) qui indique le type exact d'architecture pour les clients DHCP qui vont démarrer sur le réseau (par exemple avec PXE), en téléchargeant une version particulière du système d'exploitation. Si l'architecture utilisée est un peu rare, cette option donne des informations précieuses à un observateur.

En lisant cette liste, le paranoïaque peut se dire que la NSA a envoyé des gens à l'IETF pour faire normaliser le plus grand nombre possible d'extensions indiscrètes, de façon à être sûr d'identifier tous les clients DHCP observés. Il y a même une option pour indiquer l'adresse (civile, dans le monde physique, pas sur le réseau), Civic Location, dans le RFC 4776. Il est vrai que, contrairement à la plupart des options listées ici, elle est fournie par le serveur et pas par le client, et ne permet donc pas de suivre un client à la trace. Mais elle peut permettre à un observateur de savoir où, dans le monde physique, se situe le client.

Outre tous ces champs et ces options par lesquels une information souvent excessive est transmise, DHCP dispose de certains mécanismes qui peuvent être utilisés pour compromettre la vie privée (section 4 du RFC). Par exemple, l'option Client FQDN du RFC 4702, citée plus haut, sert souvent à faire des mises à jour dynamiques du DNS (RFC 2136), et, dans ce cas, l'adresse IP du client DHCP (qui peut indiquer sa localisation) et son nom, identificateur stable, sont publiés dans le DNS, que tout le monde peut consulter. On peut connaitre les déplacements d'une machine simplement en consultant ce DNS public, sans avoir besoin d'espionner des milliers de réseaux. L'observateur peut être très discret et, en toute légalité, vous suivre.

Autre mécanisme dangereux, la stratégie d'allocation du serveur DHCP. Lorsqu'un client DHCP réclame une adresse IP, le serveur peut la choisir de plusieurs façons, et certaines ont des conséquences pour la vie privée :

  • Allocation itérative : le serveur alloue les adresses IP dans l'ordre de la plage d'adresses dont il dispose. Elle est très simple et très rapide mais fournit des adresses IP qui sont très prévisibles. En outre, avec ce système, les premières adresses de la plage seront plus souvent utilisées, ce qui rendra encore plus facile des activités comme la reconnaissance d'un réseau avant une attaque.
  • Allocation fondée sur un identificateur : le serveur a une table et y cherche un des identificateurs transmis par le client, allouant l'adresse trouvée dans la table. C'est très pratique pour l'administrateur système, car une machine donnée aura toujours la même adresse IP. Mais c'est nettement moins bon pour la vie privée du client, qui sera ainsi trivialement pistable, par son adresse IP fixe.
  • Allocation aléatoire : le serveur DHCP prend au hasard une adresse IP libre. C'est sans doute la meilleure méthode, du point de vue de la protection de la vie privée.

La taille très restreinte de l'espace d'adressage IPv4 complique le problème, en limitant les possibilités du serveur d'utiliser certaines stratégies d'allocation, comme l'allocation fondée sur un identificateur (le serveur DHCP n'a pas forcément assez d'adresses IP pour tous ses clients potentiels.)

Bon, OK, le client DHCP envoie des tas d'identificateurs stables. Mais en quoi est-ce dangereux ? Qu'est-ce qu'un observateur indiscret peut en faire (section 5 du RFC) ? Déjà, il peut découvrir le type de machine qu'est le client (directement, via des options comme Vendor Class, ou indirectement, via l'adresse MAC (dont le préfixe, l'OUI, dépend en général du matériel utilisé). L'espion peut aussi trouver le système d'exploitation utilisé.

Il peut aussi apprendre les réseaux que le client avait visité précédemment. Le client met en effet dans l'option Requested IP Address la précédente adresse IP qu'il avait obtenue. Si c'est une adresse publique (pas issue du RFC 1918), cela renseigne sur le précédent réseau utilisé.

L'observateur peut facilement trouver un identificateur stable à partir d'une requête DHCP (en combinant les options comme Client FQDN). Cela lui permet, s'il a accès au trafic de plusieurs serveurs DHCP, de suivre les déplacements d'une machine (c'est ce qui se produit dans les cas de surveillance massive, cf. RFC 7258.)

Dans certains cas, l'observateur n'a même pas besoin d'être présent sur le réseau du serveur DHCP : si on fait des mises à jour dynamiques du DNS, il lui suffit de faire des requêtes DNS pour suivre les changements d'adresse IP (et donc de réseau) du client.

Bref, un client DHCP en dit en général trop à son serveur, et cela permet aux machines mobiles d'être facilement pistées. Notre RFC ne fournit pas de solutions immédiates, une solution est décrite dans le RFC 7844, d'autres feront l'objet d'un futur travail.


Téléchargez le RFC 7819


L'article seul

RFC 7816: DNS query name minimisation to improve privacy

Date de publication du RFC : Mars 2016
Auteur(s) du RFC : S. Bortzmeyer (AFNIC)
Expérimental
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 23 mars 2016


La meilleure façon de protéger les données contre la surveillance, c'est de ne pas avoir de données. Ce principe de base de la protection de la vie privée est souvent oublié. C'est pourtant un des deux piliers de la confidentialité, avec la protection technique des données. Le DNS a pendant longtemps transmis trop de données, et ce RFC décrit une technique qui va limiter les fuites, la QNAME minimisation, ou « réduction de la question posée ». (Il a depuis été remplacé par le RFC 9156.) Demandez à votre FAI ou à votre service informatique de l'activer !

Si vous regardez les vidéos sur le fonctionnement du DNS (comme celle-ci) ou lisez les textes expliquant « le DNS pour les nuls », vous y trouverez souvent une fausse explication de la résolution DNS, où les serveurs faisant autorité ne reçoivent que la question strictement nécessaire. Ainsi, dans la vidéo citée ci-dessus, le serveur de la racine reçoit une question où ne figure que le TLD. Mais la réalité du DNS, aujourd'hui, est tout autre : les serveurs faisant autorité reçoivent la totalité de question originale. Ainsi, si vous visitez www.alcooliques-anonymes.fr, la racine voit que vous vous intéressez à l'alcoolisme, alors que ce n'était nullement nécessaire pour son travail (puisqu'elle ne connait que les TLD). Si votre logiciel BitTorrent demande _bittorrent-tracker._tcp.domain.example, les serveurs faisant autorité pour .example sauront que vous faites du BitTorrent, alors qu'ils ne connaissaient que les domaines situés immédiatement sous .example. Le RFC 7626 décrit plus en détail les problèmes de vie privée liés au DNS.

Dans le dernier cas, pour que la résolution se passe bien, il aurait suffit de demander à la racine « quels sont les serveurs de noms de .example » et à ces serveurs « quels sont les serveurs de noms de domain.example ». C'est le principe de base de la QNAME minimisation.

Bien sûr, on pourrait chiffrer le trafic DNS (et le groupe de travail DPRIVE de l'IETF travaille précisément sur ce sujet). Mais cela ne protège que contre un tiers écoutant le réseau : les serveurs faisant autorité verraient quand même les données et pourraient en faire ce qu'ils veulent. C'est pour cela qu'un principe de base en matière de protection de la vie privée est de marcher sur deux jambes (RFC 6973) : minimiser les données envoyées et les protéger. Lorsqu'on parle de vie privée, pas mal d'informaticiens réagissent en criant « cryptographie ! » alors que celle-ci ne protège pas contre tout et notamment pas contre le serveur à qui on parle.

Et pourquoi est-ce que les résolveurs DNS envoyaient la question complète (full QNAMEQNAME veut dire Query NAME) ? Uniquement parce que la protection de la vie privée n'était pas tellement prise en compte à l'époque ? Pas uniquement : il y avait quelques raisons techniques spécifiques à l'époque (le RFC les détaille mais, surtout, il ne faut pas oublier que toutes les décisions concernant le DNS n'ont pas forcément été mûrement réfléchies).

La section 2 décrit la QNAME minimisation. Elle est mise en œuvre dans le résolveur DNS (aucun changement n'est fait dans le serveur faisant autorité, la QNAME minimisation ne change pas le protocole DNS). Avant, lorsqu'il recevait une requête demandant l'adresse IPv6 pour _foobar._tcp.sub.internautique.fr et qu'il connaissait les serveurs faisant autorité pour .fr, mais pas ceux faisant autorité pour internautique.fr, le résolveur envoyait à l'AFNIC une requête avec comme QNAME (Query NAME) le nom complet _foobar._tcp.sub.internautique.fr et comme QTYPE (Query TYPE) AAAA (indiquant une demande d'adresse IPv6). Désormais, le résolveur moderne qui met en œuvre la QNAME minimisation enverra une requête avec le QNAME internautique.fr et le QTYPE NS (demande des serveurs de noms). Plus rigoureusement, la requête est faite avec un QNAME qui est l'original, où on a retiré les premiers composants, jusqu'à un seul composant de plus que celui pour lequel on connait les serveurs faisant autorité.

Les experts en DNS ont noté un problème : il n'y a pas forcément un jeu de serveurs faisant autorité pour chaque composant. Si je prends www.st-cyr.terre.defense.gouv.fr, il n'y a par exemple aujourd'hui pas de serveurs de noms pour gouv.fr, ce sont ceux de .fr. En termes techniques, il n'y a pas de limite de zone (zone cut, cf. RFC 2181, section 6) à chaque composant. Dans le cas de ce dernier nom, il y a une limite de zone entre la racine et .fr, une autre entre fr et defense.gouv.fr mais pas entre .fr et gouv.fr. Un résolveur qui veut faire de la QNAME minimisation doit donc tenir compte des limites de zone. S'il valide avec DNSSEC, pas de problème, il les connait déjà, car leur connaissance est nécessaire au bon fonctionnement de DNSSEC. Sinon, il doit les trouver tout seul, par exemple avec l'algorithme de l'annexe A.

Est-ce un changement « légal » du fonctionnement du résolveur DNS ? La section 4 discute ce problème et conclut que oui. La QNAME minimisation est permise par les RFC existants (RFC 1034, section 5.3.3 et RFC 1035, section 7.2). C'est un changement unilatéral de la part du résolveur, ne nécessitant pas de changement dans les serveurs faisant autorité. Comme c'est un changement unilatéral, différents résolveurs pourront choisir de la mettre en œuvre de façon légèrement différente. L'annexe B décrit certaines de ces alternatives, comme d'utiliser des requêtes « traditionnelles » avec le nom de domaine complet, au démarrage du résolveur, attendant que le cache soit peuplé pour passer à la QNAME minimisation, qui préserve la vie privée mais peut nécessiter davantage de paquets.

La QNAME minimisation ne change pas le protocole DNS. Elle ne pose donc pas de problème avec les vieux serveurs. En théorie car, en pratique, il existe pas mal de serveurs incorrects qui ne suivent pas les règles et poseront quelques problèmes (section 3 du RFC, voir aussi un intéressant exposé et un « storify » d'une discussion.) Le problème n'est en général pas dû aux serveurs en logiciel libre sérieux qui forment l'essentiel de l'infrastructure du DNS (BIND, NSD, Knot...) mais plutôt aux appliances boguées que certains s'obstinent à placer devant des serveurs qui marcheraient parfaitement autrement.

C'est par exemple le cas de certains répartiteurs de charge qui répondent aux requêtes pour certains QTYPE mais qui échouent lorsque le QTYPE vaut NS (répondant, par exemple REFUSED). Pire, certains ne répondent pas du tout, comme ceux de www.ratp.fr. Il s'agit bien d'une bogue, et qui cause plein de problèmes, pas seulement à la QNAME minimisation.

Un autre problème est celui des serveurs bogués (comme djbns) qui ne réagissent pas correctement aux ENT. Qu'est-ce qu'un ENT ? Un Empty Non-Terminal (terme décrit dans le RFC 8499, section 7) est un domaine qui n'a pas d'enregistrements DNS mais qui a des sous-domaines qui en ont. gouv.fr, cité plus haut, est un ENT mais ceux-ci sont particulièrement fréquents sous ip6.arpa. Normalement, la bonne réponse à un ENT est le code NOERROR, sans enregistrements (ce qu'on appelle parfois NODATA, bien que ce dernier ne soit pas un code de retour explicite dans le DNS). Mais certains serveurs boguées répondent à la place NXDOMAIN, code qui indique normalement que le domaine n'existe pas (ce qui est faux). Voici ce que répond djbdns à une requête sur l'ENT temporary.cr.yp.to :


% dig A temporary.cr.yp.to
...
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 23636

    

C'est bien un ENT puisqu'il y a des noms en dessous (par exemple pairings.temporary.cr.yp.to). Le résolveur qui se fierait à ce NXDOMAIN croirait alors que sa recherche est terminée et que le nom demandé n'existe pas. C'est pour cela que les mises en œuvre existantes de la QNAME minimisation ont des comportements spécifiques pour les réponses NXDOMAIN, pour contourner cette bogue.

La protection de la vie privée fait qu'on enverra moins de données. C'est bien le but. Résultat, les serveurs faisant autorité et les sniffeurs recevront moins d'information. Cela peut gêner certains gros silos de données, qui exploitaient cette information.

Et les performances ? Elles seront parfois meilleures et parfois pires, avec la QNAME minimisation. Meilleures car le résolveur enverra moins de requêtes aux serveurs faisant autorité. Aujourd'hui, si un résolveur reçoit trois requêtes successives, pour A.example, B.example et C.example, les trois requêtes seront envoyées aux serveurs racine, et donneront toutes les trois un NXDOMAIN (puisque .example n'est pas délégué). Avec la QNAME minimisation, seule la première requête déclenchera une demande à la racine, pour le nom example. Cela suffira au résolveur.

Par contre, les performances peuvent se dégrader dans certains cas. Si un nom comporte beaucoup de composants (c'est fréquent dans ip6.arpa), la recherche initiale des limites de zone nécessitera bien plus de paquets. Ceci dit, cela ne durera que le temps de remplir le cache, tout ira plus vite après, une fois que le résolveur connaitra les limites de zone.

Ce RFC est issu du projet « DNS privacy », lancé initialement au CENTR, puis passé à l'IETF (le premier RFC de ce projet avait été le RFC 7626 ; comme lui, cette idée de QNAME minimisation était née dans un avion de la KLM).

À noter que Verisign a un brevet dont ils prétendent qu'il couvre la QNAME minimisation. Ils promettent une licence (attention, le diable est dans les détails) gratuite et non-discriminatoire. Ces brevets ont bien perturbé la réflexion du groupe de travail. Personnellement, je pense que ce brevet n'a pas de sens : l'idée de QNAME minimisation est évidente et avait déjà été discuté plusieurs fois, mais sans laisser de trace écrite précise, ce qui permet à Verisign de prétendre qu'il n'y a pas de prior art. Ce n'est sans doute pas un hasard si les deux premières mises en œuvre de la QNAME minimisation ont été faites en Europe, où il n'y a (normalement) pas de brevet logiciel. Ceci dit, lors des discussions sur la licence de ces brevets, en marge de la réunion IETF d'Honolulu, c'est Verisign qui a payé les boissons, reconnaissons-leur ce mérite.

La QNAME minimisation est mise en œuvre dans Unbound et dans le résolveur Knot (ce dernier n'étant pas encore officiellement publié). Pour Knot (qui le fait par défaut), voici le résultat vu par tcpdump d'une requête dig -x d'une adresse IPv6. Par exemple, le serveur racine n'a reçu qu'une demande pour .arpa. Notez aussi que Knot fait varier la casse (une protection contre certains empoisonnements) :

02:36:39.673268 IP6 2400:8900::f03c:91ff:fe69:60d3.54216 > 2001:e30:1c1e:1::333.53: 38773% [1au] NS? aRpA. (33)
02:36:40.114074 IP6 2400:8900::f03c:91ff:fe69:60d3.59934 > 2001:dc3::35.53: 22056% [1au] NS? Ip6.aRPa. (37)
02:36:40.428545 IP6 2400:8900::f03c:91ff:fe69:60d3.47793 > 2001:500:86::86.53: 43002% [1au] NS? 2.ip6.arPA. (39)
...

Pour se protéger contre les serveurs bogués dont je parlais plus haut (ceux qui répondent NXDOMAIN en cas d'ENT), Knot réessaie avec le QNAME complet lorsqu'il reçoit un NXDOMAIN (les deux dernières lignes). Mauvais pour la vie privée mais sans doute nécessaire aujourd'hui (ici, par la faute d'Akamai) :

02:34:45.050913 IP 106.186.29.14.51228 > 128.175.13.17.53: 24014% [1au] A? WwW.UpENn.edU. (42)
02:34:45.227102 IP 128.175.13.17.53 > 106.186.29.14.51228: 24014*- 2/0/1 CNAME www.upenn.edu-dscg.edgesuite.net., RRSIG (270)
02:34:45.228413 IP6 2400:8900::f03c:91ff:fe69:60d3.46525 > 2001:503:231d::2:30.53: 52576% [1au] NS? edGeSUItE.NEt. (42)
02:34:45.297319 IP6 2001:503:231d::2:30.53 > 2400:8900::f03c:91ff:fe69:60d3.46525: 52576- 0/17/15 (1034)
02:34:45.298284 IP 106.186.29.14.45604 > 23.61.199.64.53: 22228 [1au] NS? EdU-DScG.EdGesUITe.nET. (51)
02:34:45.373238 IP 23.61.199.64.53 > 106.186.29.14.45604: 22228 NXDomain*- 0/1/1 (114)
02:34:45.373795 IP 106.186.29.14.34320 > 72.246.46.66.53: 1355 [1au] A? WWW.UPenN.edu-dSCG.EdgESuItE.net. (61)

Un autre exemple de ce repli sur les requêtes classiques est donné ici, lorsque je demande www.long.verylong.detail.example. Comme le TLD .example n'existe pas, Knot débraye hélas la QNAME minimisation :

20:08:49.615421 IP6 2400:8900::f03c:91ff:fe69:60d3.51723 > 2001:1398:1:21::8001.53: 19881% [1au] NS? ExaMpLE. (36)
20:08:49.900009 IP6 2400:8900::f03c:91ff:fe69:60d3.59917 > 2001:6d0:6d06::53.53: 40708% [1au] AAAA? www.LONg.VeRylONG.DEtaIl.eXamPLE. (61)

Même chose avec un ENT où la réponse est pourtant correcte. Knot se méfie et réessaie sans QNAME minimisation :

20:14:15.479872 IP6 2400:8900::f03c:91ff:fe69:60d3.45418 > 2001:67c:1010:11::53.53: 18200% [1au] NS? gOUV.Fr. (36)
20:14:15.740424 IP 106.186.29.14.33850 > 194.0.36.1.53: 54260% [1au] A? www.ST-cYr.TerRE.DeFeNSe.GouV.fR. (61)

Lorsque le cache commence à être rempli, Knot a besoin de moins de requêtes. Ici, je lui ai demandé l'adresse de www.bortzmeyer.org, et il connaissait déjà les serveurs de .org, il passe donc directement à la question « quels sont les serveurs de noms de bortzmeyer.org ? » :

20:08:20.420757 IP 106.186.29.14.41889 > 199.249.120.1.53: 39126% [1au] NS? bOrtzMEYeR.oRg. (43)
20:08:20.941797 IP 106.186.29.14.35536 > 217.70.190.232.53: 33709% [1au] AAAA? Www.bOrtZmEyER.Org. (47)

Unbound a la QNAME minimisation depuis la version 1.5.7 (sortie en décembre 2015, cf. l'historique de ce travail). Ce n'est pas activé par défaut, il faut mettre dans la configuration :

server:
    qname-minimisation: yes

(Un pcap est disponible.) Pour vérifier si votre résolveur met bien en œuvre la QNAME minimisation, vous pouvez tester avec le domaine qnamemintest.internet.nl. Ici, le résolveur est un Unbound récent :

% dig +nodnssec +short TXT qnamemintest.internet.nl
a.b.qnamemin-test.internet.nl.
"HOORAY - QNAME minimisation is enabled on your resolver :)!"

Avec un résolveur traditionnel (ici, Verisign Public DNS, qui utilise Unbound mais une vieille version) :

% dig @64.6.64.6 +nodnssec +short TXT qnamemintest.internet.nl
a.b.qnamemin-test.internet.nl.
"NO - QNAME minimisation is NOT enabled on your resolver :("

À noter qu'à la réunion de l'OARC à Buenos Aires, Ralph Dolmans a présenté un très intéressant exposé technique sur la mise en œuvre de la QNAME minimisation dans Unbound.

Questions articles sur la QNAME minimisation, notez celui de Robert Graham.


Téléchargez le RFC 7816


L'article seul

RFC 7808: Time Zone Data Distribution Service

Date de publication du RFC : Mars 2016
Auteur(s) du RFC : M. Douglass (Spherical Cow Group), C. Daboo (Apple)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tzdist
Première rédaction de cet article le 1 avril 2016


Ah, les fuseaux horaires... Quelle source infinie de complications pour le programmeur, pour l'administrateur système de machines situées partout dans le monde, ou tout simplement pour le voyageur ou l'organisateur de télé-réunions internationales... Comme tout serait plus simple si, comme dans le roman d'Asimov « Les cavernes d'acier », les hommes vivaient en permanence sous terre, utilisant un temps uniforme. Mais, en attendant ce futur béni, il faut bien gérer les fuseaux horaires (time zones). Il existe une base de données officielle de ces fuseaux, il ne reste plus qu'à la distribuer efficacement, pour que toute machine connectée à l'Internet ait la même information. C'est le but du protocole normalisé dans ce RFC.

Que contient une base de données des fuseaux horaires (section 1 du RFC) ? Typiquement une liste de ces fuseaux avec, pour chacun d'entre eux, son décalage par rapport à UTC et ses règles concernant l'heure d'été. Les fuseaux ne suivent pas strictement le méridien, ils collent en général à des frontières inter ou intra-étatiques. Les fuseaux eux-même, et leurs décalages avec UTC, sont très stables. Mais les règles concernant l'heure d'été changent, elles, souvent. Il y a aussi le problème des secondes intercalaires, qui sont ajoutées (ou, en théorie, retirées) par l'IERS de manière imprévisible (car la rotation de la Terre n'est pas prévisible). La base actuelle représente un travail d'érudition formidable.

Au passage, un point de terminologie. Le RFC parle de « time zone » là où on dit en général en français « fuseau horaire ». Le terme français n'est pas idéal car il fait penser à un fuseau allant d'un pôle à l'autre (et englobant donc des pays différents, ayant des heures d'été différentes) alors qu'une time zone est plus restreinte. Il faut donc bien se rappeler qu'on parle ici de zones limitées à un pays, et ayant des règles (décalage avec UTC, heure d'été) uniformes. Il faut donc peut-être mieux dire « zone » ou « zone horaire » en français.

Cette information est essentielle pour les protocoles et les formats qui gèrent le temps, comme iCalendar (RFC 5545), ainsi que pour les systèmes d'exploitation. Il faut donc maintenir à jour la base de données et, jusqu'à ce RFC, il n'existait pas de mécanisme standard pour cela. Par exemple, pour un système d'exploitation comme Debian, la mise à jour se fait typiquement via le mainteneur d'un paquetage « base des fuseaux horaires » (chez Debian, le paquetage se nomme tzdata), qui introduit les changements dans son paquetage, paquetage qui est ensuite installé sur chaque machine lorsque l'administrateur système décide des mises à jour. Si le système est vieux et plus maintenu, ce sera à l'administratreur système local de « patcher » ses fichiers. Parfois, des paquetages viennent avec leur propre base des fuseaux horaires, distincte de celle du système, pour compliquer un peu les choses.

Au passage, signalons que ce RFC normalise le protocole mais qu'il faut également disposer d'une source de données de référence. Il en existe une à l'IANA, décrite dans le RFC 6557.

La section 2 décrit à grands traits l'architecture du système. Tout en amont, des contributeurs envoient des données sur les fuseaux horaires, elles sont agrégées par le fournisseur de référence (root provider, par exemple l'IANA citée plus haut). Ce fournisseur l'envoie ensuite aux clients (par exemple par le protocole de ce RFC). Le schéma du RFC est un peu plus compliqué, supposant que divers intermédiaires pourraient apparaitre. Notez que le protocole décrit ici est entre fournisseur et clients. En amont (entre contributeurs et fournisseur), il n'y a pas de mécanisme spécifié.

La section 3 de notre RFC définit la terminologie. Une zone (time zone) se caractérise donc par un ensemble de règles uniformes. La zone a un nom (utilisé par exemple dans la propriété TZID du RFC 5545) mais il n'existe pas de norme pour cela. Chaque fournisseur pourrait utiliser son schéma de nommage. Ainsi, la base IANA utilise un nom de région, une barre oblique et un nom de pays ou de ville comme Europe/Paris ou Indian/Cocos. En tout cas, il faut se méfier des abréviations ambigues, n'ayant souvent qu'une signification locale, comme PST (qui peut désigner trois zones différentes).

L'information sur les zones change (autrement, on n'aurait pas besoin d'un protocole pour télécharger les mises à jour) et il est donc important d'avoir un numéro de version permettant de savoir si on a bien la dernière version. Il peut être global à la base, ou bien spécifique à chaque zone.

Maintenant, le protocole lui-même (section 4 du RFC). Il repose, comme souvent de nos jours, sur le couple « HTTP (RFC 7230) et JSON (RFC 8259) », ce dernier servant à représenter les méta-données sur les zones. Les ressources auxquelles on accède en HTTP utilisent les gabarits d'URI du RFC 6570. Et les données elle-mêmes, les informations sur une zone horaire, en quoi sont-elles codées ? Le format par défaut est celui d'iCalendar (RFC 5545). Mais on peut aussi utiliser la représentation en XML du RFC 6321 ou celle en JSON du RFC 7265. La classique négociation de contenu de HTTP (RFC 7231, section 5.3.2) sert au client à choisir son format parmi ceux que le serveur veut bien fournir.

La base peut être assez grosse et les clients vouloir la toute dernière version. La charge sur le réseau des fournisseurs risquerait alors de devenir insupportable. C'est pourquoi il est possible de faire des requêtes conditionnelles, de façon à ne récupérer des données que si elles sont nouvelles. Là encore, c'est du classique HTTP avec les Etags (RFC 7232). Un client peut alors interroger le serveur du fournisseur une fois par jour (valeur recommandée par le RFC) sans risque de saturer le réseau.

Si le client reçoit uniquement le décalage avec UTC et les règles pour l'heure d'été, calculer une heure dans le futur peut être délicat car ces règles sont complexes. Le protocole prévoit donc la possibilité pour le client de demander au serveur de faire ces calculs et de lui envoyer les résultats.

Et si ça ne marche pas, que le serveur, pour une raison ou pour une autre, ne peut pas envoyer ce qui lui est demandé ? Il doit alors utiliser les erreurs structurées du RFC 7807 pour signaler ce qui ne va pas. (Les types d'erreurs possibles figurent dans un registre IANA.)

Comment est-ce qu'un client de ce protocole trouve le serveur ? Il doit de toute façon connaître le nom de domaine de son fournisseur, supposons ici example.net. Ensuite, il y a au moins deux méthodes :

  • Utiliser les enregistrements SRV (RFC 2782), en demandant _timezone._tcp.example.net. Il obtiendra ainsi le nom du serveur et le port à utiliser. Un enregistrement supplémentaire, sous le même nom que l'enregistrement SRV, de type TXT, indique un éventuel chemin à ajouter dans l'URI.
  • Ou bien utiliser les URI .well-known du RFC 8615, en faisant une requête HTTP pour la ressource timezone.

La section 5 du RFC décrit ensuite les actions que le serveur peut effectuer à la demande. Elles sont spécifiées en utilisant les gabarits du RFC 6570. Donc, par exemple, un gabarit {/service-prefix}/capabilities indique que le client doit ajouter /capabilities au préfixe de chemin découvert comme indiqué précédemment. Prenons un exemple complet : le client sait que son fournisseur de zones horaires est example.net. Il fait deux requêtes DNS et obtient deux enregistrements :

_timezone._tcp.example.net. SRV 0 1 8081 tz.example.com.
_timezone._tcp.example.net. TXT "path=/timezones"
    

S'il cherche à déterminer les capacités du serveur, il va alors faire une requête à l'URL http://tz.example.com:8081/timezones/capabilities.

C'est quoi, ces capabilities que je viens d'utiliser dans l'exemple ? C'est la première des actions possibles sur un serveur. Comme son nom l'indique, elle renverra un objet JSON contenant un membre actions qui sera la liste des actions possibles sur ce serveur (avec, pour chacune, le gabarit d'URI à utiliser). Une liste des actions standards possibles figure dans un registre IANA.

L'action list, elle, donne la liste des zones horaires connues du serveur. Et l'action get renvoie les données pour une zone précise. Son gabarit est {/service-prefix,data-prefix}/zones{/tzid}{?start,end} (tzid étant l'identificateur de la zone, par exemple Pacific/Noumea) et un exemple d'utilisation est :

[Requête]
      
GET /timezones/zones/America%2FNew_York HTTP/1.1
Host: tz.example.com:8081
Accept:text/calendar

[Réponse]

HTTP/1.1 200 OK
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: text/calendar; charset="utf-8"
Content-Length: xxxx
ETag: "123456789-000-111"

BEGIN:VCALENDAR
...
BEGIN:VTIMEZONE
TZID:America/New_York
...
END:VTIMEZONE
END:VCALENDAR      
    

Les codes d'erreur habituels de HTTP sont utilisés donc, par exemple, si on demande un tzid inconnu, on récupérera un beau 404, mais avec le corps de la réponse en JSON, suivant le RFC 7807 :

[Requête]
      
GET /timezones/zones/Atlantid%2FPlutopolis HTTP/1.1
Host: tz.example.com:8081
Accept:text/calendar

[Réponse]

HTTP/1.1 404 Not Found
Date: Wed, 4 Jun 2008 09:32:12 GMT
Content-Type: application/problem+json; charset="utf-8"
Content-Language: en
Content-Length: xxxx

{
     "type": "urn:ietf:params:tzdist:error:tzid-not-found",
     "title": "Time zone identifier was not found on this server",
     "status": 404
}

Il existe plusieurs autres actions, comme expand qui dit au serveur de faire les calculs d'heure d'été lui-même, ou find, qui permet de chercher une zone par une partie de son nom.

Notez bien qu'il n'y a pas d'URI fixe et pré-déterminé pour les actions : il faut utiliser les gabarits pour les générer.

Les détails des objets JSON qui peuvent être renvoyés en réponse à ces actions figurent en section 6 de notre RFC.

Et la sécurité ? Elle est cruciale car, si on peut changer la connaissance qu'une machine a de l'heure, plein d'attaques deviennent possibles (fausser les estampilles temporelles dans les journaux, activer ou désactiver un certificat, etc). Il faut donc prendre soin d'utiliser un fournisseur fiable, et de récupérer la base de manière sécurisée. (HTTPS, forcément, et avec vérification sérieuse de l'identité du serveur, en suivant le RFC 6125 ou bien le RFC 6698).

Il n'y a apparemment pour le moment qu'une mise en œuvre, dans le système de calendrier Bedework. Je ne connais pas encore de service disponible qui serve la base de données suivant ce protocole (c'est pour cela que je ne montre pas d'exemple réel). Notamment, l'IANA ne le fait pas (ce n'était pas demandé dans le RFC). Il existe des services qui distribue la base, mais avec un autre protocole, comme https://timezonedb.com/api.


Téléchargez le RFC 7808


L'article seul

RFC 7807: Problem Details for HTTP APIs

Date de publication du RFC : Mars 2016
Auteur(s) du RFC : M. Nottingham (Akamai), E. Wilde
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 1 avril 2016


Lorsqu'on fait une requête HTTP, on récupère un code à trois chiffres qui indique notamment si tout s'est bien passé (si le code commence par 2, c'est bon, s'il commence par 4 ou 5, c'est qu'il y a un problème). Ces codes ne sont pas toujours assez fins et bien des API de services REST (donc reposant sur HTTP) voudraient des précisions. Plutôt que de créer un nouveau code, ce RFC propose un mécanisme qui permet d'envoyer du JSON normalisé indiquant tous les détails sur le problème survenu. (Ce RFC a depuis été remplacé par le RFC 9457.)

Les codes de statut de HTTP sont définis dans la section 6 du RFC 7231. Parmi les plus célèbres, on note 200 (qui veut dire que tout s'est bien passé) ou 404 (qui indique que le serveur n'a pas trouvé la ressource demandée). Si le serveur veut fournir des détails, il envoie traditionnellement de l'HTML dans le corps de sa réponse. Le navigateur Web peut alors l'afficher. Mais si la requête n'était pas envoyée par un humain derrière son navigateur, si elle venait d'un client REST ? HTML ne convient alors pas et il faut passer à une information analysable par une machine. C'est ce que fait ce RFC, qui définit deux formats, un en JSON (RFC 8259) et un en XML. Le client REST va donc avoir un résumé simple (le code de statut) et tous les détails nécessaires s'il le souhaite. « Comprenant » l'erreur exacte, le client pourra même, dans certains cas, la corriger.

Le RFC utilise surtout des exemples avec l'erreur 403 Forbidden mais j'ai préféré me servir de 402 Payment required. Ce code n'a jamais été clairement documenté (il est marqué « réservé pour un usage futur » dans le RFC 7231, section 6.5.3) et c'est sans doute pour cela que notre RFC ne l'utilise pas, mais je le trouve plus rigolo. Voici par exemple une page Web payante :

% wget https://www.bortzmeyer.org/faut-vraiment-payer.html
--2016-03-26 15:54:00--  https://www.bortzmeyer.org/faut-vraiment-payer.html
Resolving www.bortzmeyer.org (www.bortzmeyer.org)... 2001:4b98:dc0:41:216:3eff:fece:1902, 2605:4500:2:245b::42, 204.62.14.153
Connecting to www.bortzmeyer.org (www.bortzmeyer.org)|2001:4b98:dc0:41:216:3eff:fece:1902|:443... connected.
HTTP request sent, awaiting response... 402 Payment Required
2016-03-26 15:54:00 ERROR 402: Payment Required.

On peut envisager plein de choses dans cette réponse analysable par une machine, comme un URI unique pour ce problème donné, qui pourrait être, par exemple, transmis au support pour faciliter la communication. Ou bien un URI d'un service REST de paiement permettant d'envoyer l'argent souhaité. Mais, naturellement, l'utilisation de cette réponse est facultative : parfois, le code de statut est suffisant et il n'y a rien à ajouter (c'est souvent le cas du 404), et parfois il vaut mieux utiliser un format spécifique à l'application utilisée (c'est d'ailleurs le cas pour toutes les API développées avant ce RFC). Ceci dit, pour les nouvelles applications, le mécanisme décrit dans ce RFC peut être très utile, pour doter toutes les applications d'un mécanisme commun de signalement des erreurs et problèmes.

Le modèle de données utilisé est celui de JSON et le type MIME est application/problem+json. Comme je l'ai dit plus haut, il y a aussi une version XML mais la référence est le JSON. La section 3 du RFC décrit ce modèle. Commençons par un exemple, une API qui demandait entre autres d'indiquer un âge et à qui on a envoyé un nombre négatif :

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
Content-Language: en

{
   "type": "https://example.net/validation-error",
   "title": "Your request parameters didn't validate.",
   "invalid-params": [ {
                         "name": "age",
                         "reason": "must be a positive integer"
                       }
                     ]
}
 

Ce message d'erreur est de type https://example.net/validation-error, une explication en langue naturelle est donnée par le membre title, et la liste des paramètres invalides est donnée dans le membre (une extension à la norme) invalid-params.

Quels sont les membres possibles de l'objet JSON renvoyé ?

  • type est un URI (il est donc unique) servant d'identificateur au problème, par exemple lorsqu'on va écrire au support. Il est recommandé qu'il soit déréférençable (c'est-à-dire qu'on puisse le visiter avec un navigateur Web et obtenir des informations sur le problème en question). S'il est absent, sa valeur par défaut est le très vide about:blank (RFC 6694, section 3).
  • title est un titre conçu pour des humains, par exemple pour les messages d'erreurs présentés à l'utilisateur. Étant en langue naturelle, il est, contrairement au type, ambigu. Il peut être adapté à la langue de l'utilisateur, via l'habituelle négociation de contenu de HTTP. detail (absent dans l'exemple ci-dessus) le complète éventuellement. Le RFC précise que detail est fait pour l'utilisateur, pas pour le programmeur qui a conçu le service. Il devrait donc contenir des informations aidant l'utilisateur à corriger sa requête, pas des informations de débogage (pas de pile d'appels Java, par exemple...) D'ailleurs, envoyer ces informations de débogage poserait un problème de sécurité (cf. section 5).
  • instance (absent dans l'exemple) est un URI qui, contrairement à type, n'identifie pas la classe du problème mais une instance particulière. Si http://example.com/not-enough-credit indique la classe « pas assez d'argent », https://example.com/account/12345/msgs/abc va indiquer le problème d'argent d'un compte particulier.

Notez que type et instance peuvent être des URI relatifs.

Voici maintenant un exemple sur mon blog (c'est conçu comme une application REST donc les résultats sont toujours en JSON et, en effet, ce n'est pas en HTTPS, ce serait intolérable en production) :


% curl -v https://www.bortzmeyer.org/apps/payme     
...
< HTTP/1.1 402 Payment required
...
< Content-Length: 253
< Content-Type: application/problem+json
< 
{
  "type": "http://errors.bortzmeyer.org/nopay", 
  "detail": "Bitcoin address 1HtNJ6ZFUc9yu9u2qAwB4tGdGwPQasQGax, Ethereum address 0xbe1f2ac71a9703275a4d3ea01a340f378c931740, Flattr https://flattr.com/profile/bortzmeyer", 
  "title": "You must pay"
}

% curl -v https://www.bortzmeyer.org/apps/payme\?pay=30
...
< HTTP/1.1 200 OK
< Content-Length: 36
< Content-Type: application/json
< 
{
  "title": "OK, 30 credits paid"
}

    

Le code Python WSGI correspondant est :

 def payme(start_response, environ):
    form = cgi.parse_qs(environ['QUERY_STRING'])
    response_headers = []
    amount = 0
    if form.has_key("pay"):
        try:
            amount = int(form["pay"][0])
        except ValueError: # Bad syntax
            amount = 0
    if amount > 0:
        status = '200 OK'
        response_headers.append(('Content-type', 'application/json'))
        output = json.dumps({"title": "OK, %i credits paid" % amount}, indent=2)
    else:
        status = '402 Payment required'
        response_headers.append(('Content-type', 'application/problem+json'))
        output = json.dumps({"type": "http://errors.bortzmeyer.org/nopay",
                             "title": "You must pay",
                             "detail": "Bitcoin address 1HtNJ6ZFUc9yu9u2qAwB4tGdGwPQasQGax, Ethereum address 0xbe1f2ac71a9703275a4d3ea01a340f378c931740, Flattr https://flattr.com/profile/bortzmeyer"},
                             indent=2)
    response_headers.append(('Content-Length', str(len(output))))
    start_response(status, response_headers)
    return [output]     
    

Si vous n'avez pas ce que vous voulez dans les membres prévus, vous pouvez étendre l'objet JSON. Les clients doivent donc ignorer les membres inconnus. C'est le cas du invalid-params dans l'exemple, qui n'est pas un membre standard.

Bien, maintenant, vous êtes programmeur dans une start-up, vous créez un nouveau service qui a une API, un nom de domaine en .io, un business plan pipeau et vous vous demandez si vous devez utiliser ce RFC et comment. La section 4 du RFC fournit quelques conseils. D'abord, je le répète, ce n'est pas un outil de débogage pour vous, ne serait-ce que pour des raisons de sécurité (cf. section 5). C'est un outil pour aider vos utilisateurs. Ensuite, si le problème est un problème classique et standard, il est inutile de se servir de ce RFC. Si l'utilisateur demande une ressource qui n'existe pas, le traditionnel et générique 404 (RFC 7231, section 6.5.4) convient parfaitement et je ne vois pas de raison d'ajouter des détails analysables par une machine (dans une page HTML d'erreur, c'est différent, on peut fournir des conseils aux visiteurs, mais rappelez-vous que ce RFC est pour les API, quand le client est un programme).

D'autre part, une application peut avoir de très bonnes raisons d'utiliser un format à elle pour décrire en détail les problèmes. (Sans compter les applications existantes qui ne vont évidemment pas modifier la définition de leur API juste pour coller à ce RFC.)

En revanche, une application nouvelle, qui n'a pas de format d'erreur établi, a tout intérêt à utiliser le cadre de ce RFC plutôt que de réinventer la roue. Dans ce cas, vous allez devoir définir :

  • L'URI qui servira de type (le seul type prédéfini est about:blank),
  • Le code de statut HTTP qui l'accompagne,
  • Les éventuelles extensions (comme le membre invalid-params plus haut).

Ces extensions peuvent utiliser les liens de HTTP (RFC 8288).

Le format principal décrit par ce RFC utilise JSON. Mais, comme il y a des goûts différents, il y a aussi une variante XML, décrite dans l'annexe A. Elle est spécifiée en Relax NG. Le modèle de données étant le même, cela donne à peu près :

   start = problem

   problem =
     element problem {
       (  element  type            { xsd:anyURI }?
        & element  title           { xsd:string }?
        & element  detail          { xsd:string }?
        & element  status          { xsd:positiveInteger }?
        & element  instance        { xsd:anyURI }? ),
       anyNsElement
     }
     

Et le résultat serait :


HTTP/1.1 400 Bad Request
Content-Type: application/problem+xml
Content-Language: en

<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:XXXX">
   <type>https://example.net/validation-error</type>
   <title>Your request parameters didn't validate.</title>
   <invalid-params><param><name>age</name><reason>must be a positive integer</reason></param></invalid-params>
</problem>

     

On a presque fini, quelques petits mots sur la sécurité en section 5 : attention à ne pas laisser fuiter de l'information qui pourrait aider un attaquant à préparer son attaque. Il faut notamment se méfier des détails de mise en œuvre (du genre afficher la requête SQL qui a échoué...)

Les deux nouveaux types MIME, application/problem+json et application/problem+xml figurent désormais dans le registre IANA.

Les développeurs d'API n'ont pas attendu ce RFC pour renvoyer des messages d'erreurs structurés, utilisant d'autres schémas (voici, par exemple, les erreurs possibles de l'API Github). Un concurrent sérieux à ce RFC est, par exemple, http://jsonapi.org/ qui a son propre mécanisme de signalement d'erreur.


Téléchargez le RFC 7807


L'article seul

RFC 7806: On Queuing, Marking, and Dropping

Date de publication du RFC : Avril 2016
Auteur(s) du RFC : F. Baker, R. Pan (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF aqm
Première rédaction de cet article le 21 avril 2016


Au cœur de l'Internet se trouvent les routeurs, et la façon dont ils traitent les paquets IP est cruciale pour le bon fonctionnement du réseau. C'est particulièrement important lorsque le trafic augmente et que les files d'attente dans les routeurs se remplissent. Que faire, alors ? Ce nouveau RFC discute des stratégies des routeurs confrontés à des files d'attente bien remplies.

Pas de « bonne » ou de « mauvaise » méthode dans ce RFC mais une discussion des possibilités. Il y a longtemps que le sujet est discuté, souvent avec des termes dangereux, car trop chargés, comme « juste » (qu'est-ce qui est juste ? Quels paquets jeter lorsque la file d'attente est pleine ? Les plus anciens ? Les plus gros ? Ceux venant de certains réseaux ?) Ainsi, le RFC 970 parle de gestion juste de la file d'attente... Le problème (à part la question de philosophie « qu'est-ce que la justice ? ») est que toute politique de gestion de la file d'attente peut entrainer des adaptations non souhaitées de la part des machines connectées au réseau (si on jette en priorité les paquets les plus gros, on encourage les machines à envoyer des paquets plus petits, comme dans le Silly Window Syndrome).

Sur la question de principe de l'équité ou de la justice, il faut toujours lire l'article de référence, « Flow Fairness: Dismantling a Religion ».

Historiquement, des modèles de trafic peu réalistes avaient été utilisés. Par exemple, certains modèles partent du débit moyen d'un flot tout au long de son existence et raisonnent là-dessus. Mais le trafic Internet est tout, sauf moyen. Il est plutôt en quanta, avec des sursauts brusques. Par exemple, une caméra va envoyer trente images par seconde et cela se traduira par beaucoup de données lorsqu'une nouvelle image est disponible, puis un silence d'un trentième de seconde avant l'image suivante.

Au passage, j'ai parlé de flot sans l'expliquer. Le terme est courant dans les discussions réseau mais souvent assez flou. Cela peut désigner une session du protocole de transport (identifiée par le fameux tuple à cinq éléments du RFC 2990), tous les paquets entre deux machines données, tous les paquets vers une machine donnée...

Autre question pratique dès qu'on discute d'équité entre les flots, comment est-ce qu'on la mesure, pour déterminer si elle est respectée ou pas ? Le RFC 7141, entre autres, se penche sur cette question.

Le gros du RFC est formé par la section 3, qui discute des outils habituels de gestion des paquets par les routeurs : mettre en file d'attente (queuing), marquer les paquets (marking) et les jeter (dropping). Tous ces outils sont indispensables (tant que la mémoire des routeurs sera finie, et donc les files d'attente n'auront pas une taille illimitée, il faudra parfois jeter des paquets) et sont interprétés par le reste du réseau comme des signaux indiquant l'approche ou le début de la congestion.

Ce RFC discute de divers concepts, il ne spécifie pas un algorithme. Pour un exemple d'algorithme récent de gestion des files d'attente des routeurs, voir FQ-Codel, même s'il ne suit pas forcément les avis du RFC (CoDel a été finalement publié dans le RFC 8289.)


Téléchargez le RFC 7806


L'article seul

RFC 7805: Moving Outdated TCP Extensions and TCP-related Documents to Historic and Informational Status

Date de publication du RFC : Avril 2016
Auteur(s) du RFC : A. Zimmermann (NetApp), W. Eddy (MTI Systems), L. Eggert (NetApp)
Pour information
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 11 avril 2016


Un peu de nettoyage dans l'imposante bibliothèque des RFC sur le protocole TCP. Bien des extensions à TCP n'ont jamais connu de déploiement réel dans la nature et d'autres, qui ont été déployées, ne sont plus utilisées depuis longtemps. Un grand nombre de RFC sont donc reclassifiés « intérêt historique seulement » ou bien « pour information ». Cela concerne surtout des vieux RFC, qui étaient bien oubliés de toute façon.

Le RFC 7414 (le guide des normes sur TCP) avait déjà fait cette classification mais sans mentionner le changement de statut dans la base de l'éditeur des RFC. C'est désormais chose faite. Il y a aussi des RFC très anciens qui n'avaient jamais été classés comme le RFC 675, la première norme TCP, à l'époque où les RFC n'avaient pas de statut clair. Remplacé par le RFC 793 (avec des modifications sérieuses du format des paquets), ce RFC 675 est désormais « intérêt historique seulement ». (À noter que le précédent grand nettoyage de TCP était dans le RFC 6247.)

Dans la liste, le RFC 1078 (TCPMUX) a suscité quelques controverses car il est apparemment mis en œuvre dans certains systèmes d'exploitation (la partie serveur, pas la partie client, qui semble absente). On ne peut donc pas le caractériser comme « non déployé ». Néanmoins, les failles, notamment de sécurité, de TCPMUX font que le RFC 1078 se retrouve lui aussi classé « intérêt historique seulement ». Notre RFC donne la liste des problèmes techniques qu'il pose.

Ce sort touche aussi des RFC récents comme le RFC 6013, proposition d'une ouverture de connexion TCP plus rapide et plus légère, publiée en 2011, implémentée, mais jamais déployée, et remplacée depuis par des RFC qui ont eu plus de succès comme le RFC 7413.

D'autres RFC sont seulement classés « pour information ». C'est le cas du RFC 700 car il ne décrivait pas un protocole mais était une analyse des premiers résultats du déploiement de TCP, ou du RFC 814, un important document de réflexion sur des concepts comme les adresses, les ports et les routes, toujours d'actualité, mais qui n'avait jamais reçu de classement auparavant. Parmi les autres RFC désormais classés, le RFC 889, qui était également un compte-rendu d'expérience sur la variation de certains paramètres numériques de TCP, comme le délai maximal d'attente. Faisons enfin une place à part pour le très utile RFC 1071 qui n'est pas abandonné, bien au contraire, juste classé comme « pour information ».


Téléchargez le RFC 7805


L'article seul

RFC 7801: GOST R 34.12-2015: Block Cipher "Kuznyechik"

Date de publication du RFC : Mars 2016
Auteur(s) du RFC : V. Dolmatov (Research Computer Center MSU)
Pour information
Première rédaction de cet article le 25 mars 2016


Encore un algorithme de cryptographie venu de l'Est, avec cette spécification sous forme de RFC d'un algorithme GOST, connu sous le petit nom de « Kuznyechik » (dans la transcription anglo-saxonne), et, plus formellement, sous celui de GOST R 34.12-2015. C'est un algorithme de chiffrement symétrique par blocs.

Comme d'autres algorithmes de