Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

echoping

Ève

Recherche dans ce blog :

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.

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


RFC 6608: Subcodes for BGP Finite State Machine Error

Date de publication du RFC : Mai 2012
Auteur(s) du RFC : J. Dong, M. Chen (Huawei Technologies), A. Suryanarayana (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 7 Mai 2012


Un très court RFC pour enrichir la liste des codes d'erreur qu'un routeur BGP peut envoyer à son pair en cas de problèmes dans l'automate à états finis du protocole. Cela devrait permettre d'améliorer les messages d'erreur vus par les opérateurs de routeurs.

La section 4.5 du RFC 4271 (qui normalise BGP), indique le mécanismes des codes d'erreur à envoyer à un pair en cas de problèmes. Il y a les codes (1 pour une erreur dans l'en-tête d'un paquet, 2 pour une erreur à l'ouverture d'une session, 3 pour une erreur lors du traitement d'une mise à jour des routes, etc) et les sous-codes, dont la signification dépend du code. Ainsi, lorsque le code vaut 2 (erreur lors d'une ouverture de session BGP entre deux pairs), un sous-code 2 indique que le numéro d'AS du pair n'est pas celui qui était configuré (tcpdump affiche cette erreur avec BGP (NOTIFICATION: error OPEN Message Error, subcode Bad Peer AS). Lorsque le code d'erreur est 3 (erreur lors d'un message UPDATE), le sous-code 2 veut dire, par contre, qu'un attribut BGP envoyé par le pair est inconnu.

Un des codes d'erreur est 5, problème dans l'automate à états finis : typiquement, un message a été reçu alors qu'il n'aurait pas dû l'être, vu l'état actuel de l'automate. Mais ce code 5 n'avait pas de sous-code (cf. RFC 4271, section 6.6) et il était donc difficile de connaître le problème exact. Ce RFC comble ce manque.

Les nouveaux sous-codes sont donc (la liste des états de l'automate est dans le RFC 4271, section 8.2) :

  • 0 : erreur non spécifiée (la situation actuelle).
  • 1 : message inattendu alors que l'envoyeur de l'erreur était dans l'état OpenSent. Par exemple, si un routeur est dans l'état OpenSent (message OPEN envoyé mais pas encore de réponse favorable) et reçoit un message UPDATE (mise à jour des routes, ne devrait être envoyé que si la session est opérationnelle), alors il renverra un message NOTIFICATION avec le code à 5 et le sous-code à 1.
  • 2 : message inattendu alors que l'envoyeur de l'erreur était dans l'état OpenConfirm,
  • 3 : message inattendu alors que l'envoyeur de l'erreur était dans l'état Established (session BGP opérationnelle). Ce serait le cas, par exemple, d'un message OPEN reçu dans cet état.

Ces sous-codes sont enregistrés à l'IANA et de nouveaux sous-codes ne pourront être ajoutés que via un RFC sur le chemin des normes (cf. RFC 5226).

L'annonce du RFC notait qu'il existait déjà deux mises en œuvre de ces sous-codes mais j'avoue ignorer desquelles il s'agit.


Téléchargez le RFC 6608


L'article seul

RFC 6605: Elliptic Curve Digital Signature Algorithm (DSA) for DNSSEC

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : P. Hoffman (VPN Consortium), W. Wijngaards (NLnet Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 13 Avril 2012


Le mécanisme de sécurité DNSSEC permet évidemment de choisir entre plusieurs algorithmes de signature cryptographique, à la fois pour pouvoir faire face aux progrès de la cryptanalyse et pour pouvoir choisir en fonction de critères particuliers (taille des clés, temps de signature et de vérification, etc). La palette de choix s'agrandit avec ce RFC qui normalise l'usage d'ECDSA, un algorithme à courbes elliptiques (le deuxième dans DNSSEC après le RFC 5933).

DNSSEC est normalisé dans le RFC 4033 et les suivants. Il permet d'authentifier les enregistrements DNS par une signature cryptographique et l'algorithme de loin le plus fréquent aujourd'hui est RSA, avec des clés de 1024 ou 2048 bits. Beaucoup de gens préfèrent les courbes elliptiques, décrites dans l'excellent RFC 6090. Notre RFC étend donc la liste des algorithmes disponibles à :

  • ECDSA avec la courbe P-256 et l'algorithme de condensation SHA-256. On considère généralement que cette courbe a à peu près la résistance de RSA avec des clés de 3072 bits.
  • ECDSA avec la courbe P-384 et l'algorithme de condensation SHA-384.

ECDSA est normalisé dans FIPS 186-3. Les paramètres des courbes sont pris dans le RFC 5114.

Les clés ECDSA et les signatures étant bien plus petites que celles de RSA, on peut espérer des économies sur la capacité réseau. Signer est également bien plus rapide avec ECDSA (20 fois plus dans certains tests). Par contre, vérifier les signatures est plus long (5 fois plus dans certains tests) et le processeur des résolveurs DNS validants va donc souffrir.

Au passage, notre RFC normalise aussi (section 2) l'utilisation de SHA-384 dans DNSSEC, ce qui n'avait pas été fait précédemment (mais n'a aucun rapport avec les courbes elliptiques). SHA-384 était déjà décrit dans le RFC 6234 et DNSSEC a juste eu à lui ajouter un numéro de code, 4. (La première personne qui voit un DS de numéro 4 dans la nature est priée de me le signaler, pour ma collection.)

La section 4 décrit les formats utilisés pour DNSSEC. Une clé publique ECDSA est juste une valeur, notée Q, qu'on met telle quelle dans l'enregistrement DNSKEY. La signature, elle, est faite de deux valeurs, r et s. On les concatène simplement avant de les mettre dans le RRSIG. Les codes enregistrés pour les deux nouveaux algorithmes sont 13 pour ECDSA Curve P-256 with SHA-256 et 14 pour ECDSA Curve P-384 with SHA-384. (Là encore, si quelqu'un en trouve dans la nature, je suis preneur...)

La section 6 fournit des exemples. Voici une clé et le DS correspondant, avec le premier algorithme (notez la petite taille par rapport aux DNSKEY RSA) :

example.net. 3600 IN DNSKEY 257 3 13 (
           GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb
           krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )

example.net. 3600 IN DS 55648 13 2 (
           b4c8c1fe2e7477127b27115656ad6256f424625bf5c1
           e2770ce6d6e37df61d17 )

Et les signatures qui l'utilisent (également toutes petites) :

www.example.net. 3600 IN A 192.0.2.1
www.example.net. 3600 IN RRSIG A 13 3 3600 (
           20100909100439 20100812100439 55648 example.net.
           qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA
           yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )

Question mises en œuvre, on notera qu'OpenSSL, bibliothèque utilisée par de nombreux programmes DNS, a ECDSA, avec nos deux courbes (au moins depuis la version 1.0.1, celle que j'ai testée). C'est apparemment activé par défaut (il faut faire un ./config no-ecdsa pour ne pas l'avoir). Voir le source dans crypto/ecdsa. Mais le code a été retiré de certains systèmes (comme Fedora) en raison des brevets, une infection fréquente pour les courbes elliptiques.

Dans les serveurs de noms, le seul à gérer déjà ECDSA semble être PowerDNS. BIND ne semble pas avoir encore ECDSA (version 9.9, la dernière officiellement publiée). Même chose pour Unbound dans sa version 1.4.16, la dernière. Enfin, pour Go-DNS, c'est en cours de développement. Il va donc falloir patienter un peu. Notez que certains des registres de noms de domaine ont une liste limitative des algorithmes acceptés et que cette liste ne comprend pas forcément déjà ECDSA.


Téléchargez le RFC 6605


L'article seul

RFC 6604: xNAME RCODE and Status Bits Clarification

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : Donald Eastlake 3rd (Huawei)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 14 Avril 2012


Ce RFC est très court car il avait juste à répondre à une question simple : le DNS a des mécanismes (le plus connu est l'enregistrement CNAME) permettant à un nom de domaine de pointer vers un autre. Si, en suivant cette chaîne de noms, on rencontre une erreur, que doit indiquer le code de retour dans la réponse DNS ? Le résultat de la première requête de la chaîne ou bien celui de la dernière ? Le RFC tranche dans le sens de la grande majorité des résolveurs DNS actuels : le rcode doit être celui de la dernière requête de la chaîne.

C'est tout bête, mais ce cas n'était pas clairement spécifié dans les précédents RFC sur le DNS. Si on a par exemple, dans le DNS :

www.foobar.example. IN CNAME www.nothere.example.

Alors une requête AAAA www.foobar.example rencontrera l'alias et le résolveur continuera en demandant www.nothere.example. Si www.nothere.example n'existe pas, alors qu'on a demandé de l'information sur www.foobar.example, le code de retour doit-il être NXDOMAIN (ce nom n'existe pas) ou bien NOERROR (on a bien trouvé un enregistrement, ici le CNAME et www.foobar.example existe) ? Même chose avec d'autres types d'enregistrement « alias » comme DNAME. (CNAME redirige un nom, DNAME redirige les noms situés en dessous de lui.) On parle alors de xNAME pour désigner globalement tous les types « alias ». Notez bien que, quoique cela soit déconseillé, il peut y avoir une chaine de plus de deux xNAME.

Avant de voir le cas du code de retour (rcode dans la terminologie DNS, pour return code), la section 2 règle celui des bits de statut. Le bit AA (Authoritative Answer) est décrit dans le RFC 1035, section 4.1.1. Il indique que la réponse vient d'un serveur faisant autorité (pas d'un cache). Dans le cas d'une chaîne de xNAME, les AA peuvent être différents à chaque étape. Mais le RFC 1035 disait clairement que le bit dans la réponse était pour le premier nom mentionné dans la section Réponse du paquet. Rien ne change ici, la spécification était claire dès le début.

Le bit AD (Authentic Data) est plus récent. Normalisé dans le RFC 4035, section 3.2.3, il indique que la réponse est correctement signée avec DNSSEC. Là encore, la règle était claire dès le début : ce bit n'est mis que si toutes les réponses dans la section Réponse (et la section Autorité) sont authentiques.

Mais le vrai problème concerne le rcode (RFC 1035, section 4.1.1) car, là, le RFC original (voir aussi RFC 1034, section 4.3.2 et bon courage pour le comprendre) n'était pas clair. Le RFC 2308, dans sa section 2.1, dit qu'il faut fixer le code de retour en fonction de la dernière étape de la chaîne, tout en notant que tous les serveurs ne le font pas. La section 3 fixe donc des règles précises : lorsqu'on suit une chaîne, les étapes intermédiaires n'ont pas d'erreur. Il ne sert donc à rien d'indiquer le résultat de la première étape. Le code de retour doit donc être mis en fonction de la dernière étape uniquement. Dans l'exemple plus haut, le résultat de la requête AAAA www.foobar.example doit donc être NXDOMAIN (domaine inexistant).

Voilà, vous pouvez arrêter la lecture ici, l'essentiel du RFC est le paragraphe précédent. Mais la section 4 apporte quelques détails sur la sécurité. Par exemple, elle rappelle que des bits comme AA ou AD ne sont pas protégés par DNSSEC. Un attaquant a donc pu les changer sans être détecté. Si on veut être sûr de leur intégrité, il faut protéger la communication avec le serveur, par exemple avec le TSIG du RFC 2845 (ou bien que le client ignore le bit AD et valide lui-même avec DNSSEC).

Si vous voulez tester vous-même que votre résolveur obéit bien aux règles de ce RFC, vous pouvez tester avec dangling-alias.bortzmeyer.fr qui existe mais pointe vers un nom qui n'existe pas. Vous devez donc obtenir un NXDOMAIN, ce qui est le cas avec la plupart des résolveurs actuels (la question de l'implémentation de ce RFC ne se pose pas, le RFC a pris acte du comportement très majoritaire des logiciels).

Voici un exemple avec un résolveur correct (un Unbound) :


% dig AAAA dangling-alias.bortzmeyer.fr
...
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 45331
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 6, ADDITIONAL: 1


Téléchargez le RFC 6604


L'article seul

RFC 6598: IANA-Reserved IPv4 Prefix for Shared Address Space

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : J. Weil (Time Warner Cable), V. Kuarsingh (Rogers Communications), C. Donley (CableLabs), C. Liljenstolpe (Telstra Corp), M. Azinger (Frontier Communications)
Première rédaction de cet article le 23 Avril 2012


Après beaucoup de discussions pas toujours sereines, l'IESG a finalement décidé de publier ce très controversé RFC. Il réserve un préfixe IPv4, 100.64.0.0/10, aux services de partage d'adresses IP entre utilisateurs, les CGN (Carrier-Grade NAT). Ce faisant, il légitime ce concept de CGN, ce qui a déclenché la colère de beaucoup.

Voyons d'abord le paysage : les adresses IPv4 sont à peu près épuisées. Mais le déploiement d'IPv6 a pris beaucoup de retard et il n'est pas, à l'heure actuelle, prêt à prendre le relais. Plusieurs FAI, notamment en Asie, ont donc commencé à déployer des systèmes où l'abonné de base n'a aucune adresse IPv4 publique. Avant cela, M. Toutlemonde n'avait certes qu'une seule adresse publique et devait faire du NAT pour donner à toutes ses machines une connectivité Internet partielle. Mais, au moins, le partage d'adresses ne se faisait qu'entre habitants du même foyer, Aujourd'hui, par manque d'adresses IPv4, les déploiements en cours repoussent le NAT dans le réseau de l'opérateur (d'où le nom de CGN, Carrier-Grade NAT, voir par exemple le RFC 6264) et le partage d'adresses publiques se fait désormais entre abonnés n'ayant rien en commun. Désormais, si votre voisin télécharge illégalement, c'est peut-être sur vous que l'HADOPI tombera...

Le partage d'adresses (documenté dans le RFC 6269) n'est pas le seul inconvénient des CGN. Ces gros routeurs NAT, gardant en mémoire l'état des flux pour des centaines ou des milliers d'abonnés, diminuent la résistance aux pannes : si on redémarre l'un d'eux, tous les abonnés perdent leurs sessions en cours. Voilà pourquoi l'idée même de CGN (qui met de l'« intelligence » dans le réseau et non pas aux extrêmités) hérisse tant de gens à l'IETF.

Si on fait quand même des CGN, se pose le problème de la numérotation des réseaux. Le réseau local de l'abonné (appelons-le M. Li car les CGN pour des accès Internet fixe sont aujourd'hui surtout répandus en Chine) est typiquement numéroté avec le RFC 1918. L'opérateur ne peut pas utiliser les adresses de ce même RFC pour son réseau, entre M. Li et le gros CGN, à cause du risque de conflit avec le réseau local de M. Li (sauf si l'opérateur contrôle ledit réseau, via ses boxes). Il ne peut pas utiliser des adresses IP publiques puisque, c'est le point de départ de toute l'histoire, celles-ci manquent. Il faut donc un « nouveau RFC 1918 ». C'est le rôle de ce RFC 6598, qui réserve un nouveau préfixe, 100.64.0.0/10, à cet usage. Il s'ajoute aux autres préfixes « spéciaux » du RFC 5735. Il servira aux machines entre le CPE (la box) et le routeur CGN et ne sera donc typiquement jamais vu sur l'Internet. À noter que ce préfixe n'a rien de particulier, à part son usage officiel : on pourrait parfaitement s'en servir pour autre chose que du CGN. Voici le nouveau préfixe, vu avec whois :

% whois 100.64.0.0 
NetRange:       100.64.0.0 - 100.127.255.255
CIDR:           100.64.0.0/10
OriginAS:
NetName:        SHARED-ADDRESS-SPACE-RFCTBD-IANA-RESERVED
NetHandle:      NET-100-64-0-0-1
Parent:         NET-100-0-0-0-0
NetType:        IANA Special Use
RegDate:        2012-03-13
Updated:        2012-03-15

Ah, pourquoi une longueur de 10 à ce préfixe ? Un préfixe plus court (comme un /8) aurait été difficile à trouver de nos jours, et un plus long (par exemple un /12), offrant moins d'adresses, aurait obligé les FAI, dans certaines régions très peuplées, à déployer des CGN emboités... Un /10, par exemple, suffit à desservir toute l'agglomération de Tokyo (un FAI japonais ne peut donc pas avoir un seul routeur CGN pour tous le pays).

La section 4 du RFC précise l'usage attendu : chaque FAI utilisera librement 100.64.0.0/10 et ce préfixe n'aura donc de signification que locale. Les adresses 100.64.0.0/10 ne doivent pas sortir sur l'Internet public (le mieux est de les filtrer en sortie et, pour les autres FAI, en entrée, car il y aura toujours des négligents). Ces adresses ne doivent pas non plus apparaître dans le DNS public. Les requêtes DNS de type PTR pour ces adresses ne doivent pas être transmises aux serveurs DNS globaux, comme celles pour les adresses du RFC 1918, elles doivent être traitées par les serveurs du FAI. Comme pour le RFC 1918, c'est sans doute un vœu pieux, et il faudra sans doute que l'AS112 (voir le RFC 6304) prenne en charge ces requêtes.

La section 3 décrit plus en détail les alternatives qui avaient été envisagées et les raisons de leur rejet. La solution la plus propre aurait évidemment été d'utiliser des adresses IPv4 globales, attribuées légitimement au FAI. Mais l'épuisement d'IPv4 rend cette solution irréaliste. Déjà, extraire un /10 des réserves n'a pas été facile.

La solution qui est probablement la plus utilisée à l'heure actuelle est celle d'utiliser un préfixe IPv4 usurpé, en se disant « de toute façon, ces adresses ne sortiront jamais sur l'Internet donc quel est le problème ? » Se servir sans demander est certainement plus rationnel, économiquement parlant, que de supplier la bureaucratie d'un RIR pour avoir des adresses. Autrefois, les FAI qui numérotaient ainsi leur réseau interne se servaient de préfixes non alloués (provoquant pas mal d'accidents au fur et à mesure de leur allocation ; même s'il n'y a pas de fuite de ces adresses, les abonnés du FAI peuvent être dans l'impossibilité de communiquer avec le détenteur légitime). Aujourd'hui, ils regardent quels sont les préfixes alloués mais non routés et les utilisent. Inutile de dire que le RFC condamne cette pratique incivique.

Le RFC 1918 n'est, on l'a vu, possible que si le FAI contrôle complètement le réseau local de M. Li et sait donc quels préfixes sont utilisés sur celui-ci, et peut ainsi choisir des préfixes qui ne rentrent pas en collision. (Cela peut aussi marcher si la box sait bien se débrouiller lorsque le même préfixe est utilisé en interne et en externe, ce qui est le cas de certaines.)

Bref, l'allocation d'un nouveau préfixe semblait la seule solution raisonnable.

La section 5 du RFC est consacrée à une longue mise en garde sur les dangers associés aux CGN. Certaines applications peuvent avoir des mécanismes pour découvrir l'adresse externe de la machine sur laquelle l'application tourne (l'adresse qu'on verra sur l'Internet) et, ensuite, faire des choses comme de demander à un pair d'envoyer des données à cette adresse. Avec le CGN, cela a encore moins de chances de marcher que d'habitude car les applications actuelles ne connaissent pas encore 100.64.0.0/10 et considéreront que ces adresses sont globalement utilisables.

Parmi les applications qui ont de fortes chances de mal marcher dans le contexte du CGN, citons les jeux en ligne (si deux abonnés essaient de se connecter alors qu'ils sont derrière le même CGN et ont la même adresse publique), le pair-à-pair, et bien sûr les applications de téléphonie avec SIP, la géo-localisation (le CGN sera trouvé, pas la vraie machine), certaines applications Web qui restreignent les connexions simultanées en provenance de la même adresse IP, etc. Pour les applications de type pair-à-pair (échange de fichier, SIP), les techniques habituelles d'ouverture manuelle d'un port sur le routeur (« tout ce qui est envoyé au port 4554, transmets le à 10.4.135.21 ») ne marchent pas avec le CGN, l'utilisateur résidentiel n'ayant typiquement pas de moyen de configurer le routeur CGN.

Enfin, quelques bons conseils de sécurité forment la section 6 : ne pas accepter les annonces de route pour 100.64.0.0/10 à l'entrée d'un site, les paquets depuis ou vers ces adresses ne doivent pas franchir les frontières d'un opérateur, etc.

Voilà, comme indiqué, cela ne s'était pas passé tout seul et l'IESG avait même dû faire une longue note détaillant le pourquoi de sa décision et expliquant que, certes, il n'y avait pas de consensus en faveur de ce projet mais qu'il n'y avait pas non plus de consensus contre. L'argument « pour » était :

  • Les opérateurs vont déployer du CGN de toute façon. S'ils n'ont pas un préfixe dédié à cet usage, ils utiliseront des mauvaises méthodes, comme des préfixe squattés.

Les arguments contre étaient :

  • Toute mesure qui prolonge au delà du raisonnable l'usage d'IPv4 ne fait que retarder le déploiement d'IPv6. Les efforts devraient se porter sur ce déploiement, pas sur l'acharnement thérapeuthique !
  • Les opérateurs se serviront du nouveau préfixe pour étendre le RFC 1918, et pas pour l'usage attendu.

Pour d'autres articles sur ce sujet, voir celui sur le bon blog de Chris Grundemann (en anglais) ou bien celui de Jérôme Durand (en français).


Téléchargez le RFC 6598


L'article seul

RFC 6596: The Canonical Link Relation

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : M. Ohye, J. Kupke
Pour information
Première rédaction de cet article le 9 Avril 2012


Depuis le RFC 5988, il existe un mécanisme standard pour exprimer les types des liens entre deux ressources sur le Web. Ce très court RFC spécifie un nouveau type de lien, canonical, qui permet d'indiquer quel est l'URI canonique d'une ressource Web.

Le but de ces liens est de permettre d'exprimer l'idée « Quel que soit l'URI que vous avez utilisé pour arriver sur cette ressource, sachez que l'URI canonique, la référence, est celui indiqué par ce lien. » Cela permet notamment à un moteur de recherche de n'indexer les ressources que sous l'URI canonique (au cas où du contenu soit dupliqué sous plusieurs URI). Cela permet également à un navigateur de ne mémoriser que l'URI canonique, sans d'éventuels paramètres (options d'affichage, identificateurs de session et autres trucs qui viennent souvent polluer les URI).

L'auteur qui place un lien canonical doit donc veiller à ce que l'URI canonique désigne bien une ressource qui mérite ce titre (identique à la ressource de départ, ou un sur-ensemble de celle-ci, ce dernier cas est explicitement autorisé par le RFC). Voir la section 5 qui donne de bons conseils aux auteurs.

Par contre, l'URI canonique ne doit notamment pas :

  • Être la source d'une redirection HTTP (sinon, par définition, il n'est pas canonique).
  • Ne doit pas spécifier un URI canonique autre que lui-même (en d'autres termes, pas le doit de faire des chaînes).
  • Ne doit évidemment pas renvoyer 404 lorsqu'on essaie d'y accéder.

La section 4 donne des exemples concrets. Si la version canonique d'une ressource est désignée par l'URI http://www.example.com/page.php?item=purse, alors les URI http://www.example.com/page.php?item=purse&category=bags ou http://www.example.com/page.php?item=purse&category=bags&sid=1234 qui sont des URI possibles de la même ressource peuvent indiquer http://www.example.com/page.php?item=purse comme canonique.

Pour cela, deux techniques, le classique lien HTML avec l'attribut rel :


<link rel="canonical"
           href="http://www.example.com/page.php?item=purse">

Il est également utilisable en version relative :


 <link rel="canonical" href="page.php?item=purse">

Et la deuxième technique (pratique notamment pour les ressources qui ne sont pas en HTML, une image, par exemple), l'en-tête HTTP (section 5 du RFC 5988) :


Link: <http://www.example.com/page.php?item=purse>; rel="canonical"

Le nouveau type canonical est désormais enregistré à l'IANA.

Petit avertissement de sécurité (section 7). Si une ressource est modifiée par un attaquant, il peut mettre un lien vers un URI canonique de son choix. Bien sûr, il pourrait aussi massacrer complètement la ressource. Mais le changement d'URI canonique est discret et risquerait de ne pas être noté par un humain, alors même que certaines implémentations en tiendraient compte, par exemple pour apport du trafic à l'URI de l'attaquant.

Qui gère aujourd'hui ce type de liens ? Chez les moteurs de recherche, Google le fait (voir leurs articles « Specify your canonical », « Supporting rel="canonical" HTTP Headers », l'article de conseils pratiques « About rel="canonical" » et enfin « Handling legitimate cross-domain content duplication »). Pareil chez Yahoo (« Fighting Duplication: Adding more arrows to your quiver ») et Bing (« Partnering to help solve duplicate content issues »). Par contre, je ne sais pas si les sites de bookmarking comme del.icio.us ou SeenThis font ce travail de canonicalisation.


Téléchargez le RFC 6596


L'article seul

RFC 6591: Authentication Failure Reporting using the Abuse Report Format

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : H. Fontana
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 13 Avril 2012


Le format ARF, normalisé dans le RFC 5965, permet d'envoyer des rapports structurés (analysables par un programme) à propos d'un message électronique abusif, spam ou hameçonnage, par exemple. Ce RFC 6591 spécifie une extension à ARF pour le cas où le problème avec le message est un échec d'un mécanisme d'authentification. On peut ainsi prévenir l'émetteur que quelqu'un essaie d'usurper son identité ou, plus fréquemment aujourd'hui, qu'il y a une erreur dans la configuration de ses mécanismes d'authentification.

Par exemple, si le message est authentifié par SPF (RFC 4408), il arrive assez souvent que l'émetteur se mette à utiliser un MTA non prévu et non listé dans l'enregistrement SPF. Si ce dernier se termine par un -all, l'usage de ce MTA va se traduire par une erreur d'authentification. L'extension ARF décrite ici permettra de transmettre un rapport à l'émetteur, pour qu'il corrige.

L'extension consiste en un nouveau type de rapport ARF, auth-failure (section 3.1), rejoignant les rapports existants (comme abuse ou fraud). Un rapport de ce type va comporter, dans sa seconde partie (celle qui est structurée, la première étant en langue naturelle et la troisième étant le message original), les champs suivants. À noter que certains étaient déjà définis par le RFC 5965 mais peuvent avoir des exigences différentes ici (par exemple, être obligatoires pour les rapports auth-failure alors qu'ils étaient optionnels pour les autres). Les nouveaux sont désormais dans le registre IANA. Commençons par les champs obligatoires :

  • Auth-failure: Nouveauté de ce RFC, il indique en un mot la raison de l'échec. Les valeurs possibles sont adsp (cf. RFC 5617), bodyhash (le condensat cryptographique du corps du message ne correspond pas à la signature), revoked (signature DKIM expirée), signature (signature DKIM invalide), spf (échec SPF).
  • Authentication-Results: Normalisé dans le RFC 5451, il indique les paramètres d'authentification et les raisons de l'échec.
  • Reported-Domain: Le nom de domaine annoncé par l'expéditeur.

D'autres champs sont recommandés ou simplement optionnels :

  • Original-Envelope-Id: Un identifiant unique pour la transaction SMTP (cf. section 2.2.1 du RFC 3464)
  • Original-Mail-From:
  • Source-IP:
  • Delivery-Result: Ce dernier indique la décision qui a été prise après l'échec de l'authentification (jeter le message, le distribuer quand même, etc)

Il peut en outre y avoir des champs spécifiques à certaines techniques d'authentification. Par exemple, pour DKIM (RFC 6376), les champs DKIM-Domain:, DKIM-Identity: et DKIM-Selector: ou pour SPF le champ SPF-DNS:..

Voici un exemple (annexe B du RFC) de rapport ARF sur un échec d'authentification DKIM, par suite d'une incohérence entre le contenu effectif et ce qu'indiquait la signature :


   Message-ID: <433689.81121.example@mta.mail.receiver.example>
   From: "SomeISP Antispam Feedback" <feedback@mail.receiver.example>
   To: arf-failure@sender.example
   Subject: FW: You have a new bill from your bank
   Date: Sat, 8 Oct 2011 15:15:59 -0500 (CDT)
   MIME-Version: 1.0
   Content-Type: multipart/report;
     boundary="------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg";
     report-type=feedback-report
   Content-Transfer-Encoding: 7bit

   --------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg
   Content-Type: text/plain; charset="us-ascii"
   Content-Disposition: inline
   Content-Transfer-Encoding: 7bit

   This is an authentication failure report for an email message
   received from a.sender.example on 8 Oct 2011 20:15:58 +0000 (GMT).
   For more information about this format please see [this memo].

   --------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg
   Content-Type: message/feedback-report
   Content-Transfer-Encoding: 7bit

   Feedback-Type: auth-failure
   User-Agent: Someisp!Mail-Feedback/1.0
   Version: 1
   Original-Mail-From: anexample.reply@a.sender.example
   Original-Envelope-Id: o3F52gxO029144
   Authentication-Results: mta1011.mail.tp2.receiver.example;
    dkim=fail (bodyhash) header.d=sender.example
   Auth-Failure: bodyhash
   DKIM-Canonicalized-Body: VGhpcyBpcyBhIG1lc3NhZ2UgYm9keSB0
     aGF0IGdvdCBtb2RpZmllZCBpbiB0cmFuc2l0LgoKQXQgdGhlIHNhbWU ...
   DKIM-Domain: sender.example
   DKIM-Identity: @sender.example
   DKIM-Selector: testkey
   Arrival-Date: 8 Oct 2011 20:15:58 +0000 (GMT)
   Source-IP: 192.0.2.1
   Reported-Domain: a.sender.example
   Reported-URI: http://www.sender.example/

   --------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg
   Content-Type: text/rfc822-headers
   Content-Transfer-Encoding: 7bit

   Authentication-Results: mta1011.mail.tp2.receiver.example;
    dkim=fail (bodyhash) header.d=sender.example;
    spf=pass smtp.mailfrom=anexample.reply@a.sender.example
   Received: from smtp-out.sender.example
    by mta1011.mail.tp2.receiver.example
    with SMTP id oB85W8xV000169;
    Sat, 08 Oct 2011 13:15:58 -0700 (PDT)
   DKIM-Signature: v=1; c=relaxed/simple; a=rsa-sha256;
    s=testkey; d=sender.example; h=From:To:Subject:Date;
    bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
    b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqOB
    4nujc7YopdG5dWLSdNg6xNAZpOPr+kHxt1IrE+NahM6L/LbvaHut
    KVdkLLkpVaVVQPzeRDI009SO2Il5Lu7rDNH6mZckBdrIx0orEtZV
    4bmp/YzhwvcubU4=
   Received: from mail.sender.example
    by smtp-out.sender.example
    with SMTP id o3F52gxO029144;
    Sat, 08 Oct 2011 13:15:31 -0700 (PDT)
   Received: from internal-client-001.sender.example
    by mail.sender.example
    with SMTP id o3F3BwdY028431;
    Sat, 08 Oct 2011 13:15:24 -0700 (PDT)
   Date: Sat, 8 Oct 2011 16:15:24 -0400 (EDT)
   Reply-To: anexample.reply@a.sender.example
   From: anexample@a.sender.example
   To: someuser@receiver.example
   Subject: You have a new bill from your bank
   Message-ID: <87913910.1318094604546@out.sender.example>

   --------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg--

Le but de l'authentification du courrier électronique étant d'améliorer la sécurité, il n'est pas étonnant que la section 6, considérée aux problèmes de sécurité, soit particulièrement détaillée. Quelques points à garder en tête, donc. Par exemple, les rapports ARF eux-même peuvent être des faux. Il ne faut agir de manière automatique sur un de ces rapports que s'ils ont été authentifiés d'une manière ou d'une autre. Ensuite, générer automatiquement des rapports ARF peut ouvrir une voie à l'attaque par déni de service : un méchant pourrait envoyer plein de messages délibèrement faux, pour déclencher l'émission massive de rapports ARF.

Il existe apparemment déjà au moins un générateur d'ARF qui gère cette extension. PayPal et Hotmail ont déjà annoncé leur intention de l'utiliser.


Téléchargez le RFC 6591


L'article seul

RFC 6590: Redaction of Potentially Sensitive Data from Mail Abuse Reports

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : J. Falk (Return Path), M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 8 Avril 2012


Il est fréquent qu'un message électronique contienne de l'information sensible ou personnelle, ne serait-ce que le nom des parties qui communiquent. Si ce message doit être transmis, comme faisant partie d'un rapport de problème, cette information doit être protégée. Ce RFC décrit un cadre général pour la retouche des messages. Le terme de « retouche » désigne l'opération d'occultation des parties confidentielles (notez que le redaction de l'original en anglais est un faux-ami, il ne signifie pas « rédaction »).

Le format ARF est normalisé dans le RFC 5965. Ce format standard permet de transmettre un rapport structuré (donc analysable automatiquement, par un programme) indiquant du spam, du hameçonnage ou tout autre abus. ARF permet également d'inclure dans le rapport le message qui a déclenché le processus de plainte. Mais ce message peut contenir des informations confidentielles, qu'on ne souhaite pas partager avec un tiers (sans compter les obligations légales comme, en France, la loi Informatique & Libertés). Le message est donc parfois retouché (redacted dans la langue de Katy Perry) avant d'être transmis. La section 8.5 du RFC 5965 décourage plutôt cette pratique (l'information occultée était peut-être nécessaire à la compréhension du rapport) mais cette approche « au diable la vie privée, la fin justifie les moyens » est très contestée et ce RFC 6590 adopte une vue plus raisonnable. L'occultation est désormais considérée comme justifiée.

L'important est donc plutôt de donner des conseils pratiques. Il y a des bonnes et des mauvaises façons d'occulter. Ainsi, remplacer toutes les parties locales des adresses (stephane+blog dans mon adresse stephane+blog@bortzmeyer.org) par la même chaîne de caractères (mettons xxxxx@bortzmeyer.org) fait perdre beaucoup d'information : on ne sait plus si deux rapports concernent le même utilisateur.

La section 3 de notre RFC conseille donc plutôt :

  • D'utiliser une transformation cohérente : deux chaînes identiques doivent donner le même résultat après occultation, et deux chaînes différentes doivent donner deux résultats différents.
  • De décider clairement quelles parties du message sont privées (par exemple, uniquement les parties locales des adresses, comme dans mon premier exemple) et de n'appliquer les transformations qu'à celles-ci.
  • De respecter la syntaxe des élements de protocole : si la transformation d'une partie locale d'une adresse donne une chaîne comportant un @ (caractère illégal dans une partie locale d'adresse), il faut l'encoder pour que l'adresse reste syntaxiquement légale, évitant ainsi de planter l'analyseur.

En appliquant ces règles, on a partiellement anonymisé le rapport, tout en permettant l'identification de tendances (par exemple, que le spam est plus souvent envoyé à certains utilisateurs).

Mais quelle opération de transformation utiliser ? Après la section 3 qui posait les principes, la section 4 s'occupe de technique. Ce RFC ne normalise pas une opération de transformation particulière. Si ROT13, qui est réversible, ne devrait pas être utilisé, les méthodes possibles incluent un hachage cryptographique (comme dans le RFC 2104) ou le remplacement des noms par un identifiant interne (numéro de client, par exemple).

Voici l'exemple qui figure dans l'annexe A du RFC. Le message de spam originel était :


From: alice@example.com
To: bob@example.net
Subject: Make money fast!
Message-ID: <123456789@mailer.example.com>
Date: Thu, 17 Nov 2011 22:19:40 -0500

Want to make a lot of money really fast?  Check it out!
http://www.example.com/scam/0xd0d0cafe

Ici, le récepteur, le FAI example.net est furieux et veut transmettre un rapport à example.com pour lui demander de faire cesser ces spams. example.net va occulter le nom du destinataire (son client), avec SHA-1 et la clé potatoes, qui sera concaténé au nom avant hachage, le résultat étant encodé en Base64. Cela donnera :

% echo -n potatoesbob | openssl sha1 -binary | openssl base64 -e 
rZ8cqXWGiKHzhz1MsFRGTysHia4=

On va pouvoir alors construire un rapport ARF incluant :


From: alice@example.com
To: rZ8cqXWGiKHzhz1MsFRGTysHia4=@example.net
Subject: Make money fast!
Message-ID: <123456789@mailer.example.com>
Date: Thu, 17 Nov 2011 22:19:40 -0500

Want to make a lot of money really fast?  Check it out!
http://www.example.com/scam/0xd0d0cafe

Attention, en pratique, il existe pas mal de pièges. Par exemple, comme le note la section 5.3, l'information confidentielle peut se trouver aussi à d'autres endroits et des techniques de corrélation peuvent permettre de retrouver l'information occultée. Globalement, les messages retouchés selon ce RFC ne fourniront pas une forte confidentialité. Ainsi, le champ Message-ID: peut permettre, en examinant le journal du serveur de messagerie (celui de example.com dans l'exemple précédent), de retrouver émetteur et destinataire. C'est pour cette raison que le RFC n'impose pas l'usage de la cryptographie : elle n'apporterait pas grand'chose en sécurité.

Même chose pour les informations non structurées, par exemple le texte du message : il peut contenir des indications permettant de remplir les cases occultées (section 6).

D'une manière générale, il faut garder en mémoire qu'il existe de puissantes techniques de désanonymisation comme illustré par exemple par les articles « A Practical Attack to De-Anonymize Social Network Users » de Gilbert Wondracek, Thorsten Holz, Engin Kirda et Christopher Kruegel ou bien « Robust De-anonymization of Large Sparse Datasets » de Arvind Narayanan et Vitaly Shmatikov.


Téléchargez le RFC 6590


L'article seul

RFC 6589: Considerations for Transitioning Content to IPv6

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : J. Livingood (Comcast)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 23 Avril 2012


Ce document rassemble un certain nombre d'analyses et de conseils sur la transition vers IPv6 pour les gens qui hébergent du contenu, typiquement les sites Web. Les gérants de ces sites souhaiteraient pouvoir rendre ce contenu accessible en IPv6, sans que cela entraîne de conséquences fâcheuses pour les lecteurs. Ce RFC décrit notamment la technique du whitelisting, qui consiste à ne renvoyer d'adresses IPv6 (les enregistrements AAAA du DNS) qu'à certains réseaux, identifiés comme mettant en œuvre correctement IPv6. Cette technique a été popularisée par Google mais elle est contestée. Le RFC estime qu'elle est acceptable et qu'il est utile d'informer, non pas les sites qui la pratiquent (ils connaissent déjà) mais la communauté Internet en général.

Bien sûr, ce RFC peut être utile à d'autres qu'aux gérants de sites Web. Mais il se focalise particulièrement sur leurs besoins. Un site Web se caractérise par un gros déséquilibre : au lieu de deux pairs qui veulent communiquer, on a un fournisseur de contenu, et des clients passifs, à qui on ne peut pas demander d'effectuer des réglages particuliers. Ça doit marcher, point. En outre, les sites Web à plus fort trafic sont souvent des entreprises commerciales, qui ne veulent pas prendre de risques et n'acceptent pas même un très faible pourcentage de clients pénalisés par IPv6.

Le but est donc de migrer de gros sites Web uniquement accessible en IPv4 (la grande majorité des gros sites Web à l'heure actuelle, la principale exception étant Google) vers un accès possible en IPv4 (protocole qui ne va pas disparaître de si tôt) et IPv6.

Mais quels sont les problèmes qu'IPv6 pourrait causer ? Le site Web typique publie son adresse dans le DNS. Pour l'adresse IPv4, il utilise un enregistrement de type A. Pour IPv6, de type AAAA. Ainsi, aujourd'hui, www.bortzmeyer.org annonce deux AAAA et un A :


% dig A www.bortzmeyer.org
...
;; ANSWER SECTION:
www.bortzmeyer.org.     42641   IN      A       204.62.14.153
...

% dig AAAA www.bortzmeyer.org
...
;; ANSWER SECTION:
www.bortzmeyer.org.     10222   IN      AAAA    2605:4500:2:245b::bad:dcaf
www.bortzmeyer.org.     10222   IN      AAAA    2001:4b98:dc0:41:216:3eff:fece:1902
...

Par contre, la très grande majorité des sites Web ne publient que des A, par exemple www.gouvernement.fr :


% dig A www.gouvernement.fr
...
;; ANSWER SECTION:
www.gouvernement.fr.    86383   IN      CNAME   www.premier-ministre.gouv.fr.
www.premier-ministre.gouv.fr. 86383 IN  CNAME   cdn2.cdn-tech.com.c.footprint.net.
cdn2.cdn-tech.com.c.footprint.net. 213 IN A     209.84.9.126
...

% dig AAAA www.gouvernement.fr 
...
;; ANSWER SECTION:
www.gouvernement.fr.    86358   IN      CNAME   www.premier-ministre.gouv.fr.
www.premier-ministre.gouv.fr. 86358 IN  CNAME   cdn2.cdn-tech.com.c.footprint.net.
...

Certains de ces sites sont simplement gérés par des incompétents ou des paresseux, qui ne peuvent pas ou n'envisagent pas de publier des enregistrements AAAA, qui permettraient à leur lecteurs d'accéder au contenu en IPv6. Mais, dans d'autres cas, l'administrateur du site Web connaît IPv6, a refléchi, et a décidé de ne pas publier le AAAA. Pourquoi ? Parce qu'il craint le problème du malheur des globes oculaires (eyeball misery ?). J'ai décrit ce problème dans un autre article et il fait en outre l'objet de deux autres RFC, les RFC 6555 et RFC 6556. En deux mots, le malheur des globes oculaires peut venir d'une connexion IPv6 cassée, ou simplement de qualité très inférieure. Si le site Web ne publie pas d'enregistrement AAAA, le client ne tentera pas de se connecter en IPv6 et sa connexion pourrie n'aura donc pas de conséquences négatives. Mais dès que le site Web publie son AAAA, patatras, l'expérience utilisateur se dégrade sérieusement et le pauvre client doit supporter des délais, voire des pannes.

Le problème n'arriverait pas si les administrateurs réseaux prenaient autant soin de la connexion IPv6 que de l'IPv4 mais ce n'est pas toujours le cas en pratique : quand un des deux protocoles marche nettement moins bien que l'autre, aujourd'hui, c'est presque toujours IPv6. Logiciels moins testés, surveillance moins sérieuse, moindre réactivité lors des pannes, sont la triste réalité d'IPv6 chez beaucoup d'opérateurs réseaux. Un autre problème est quantitatif : certaines bogues ne se déclenchent qu'à partir d'une certaine quantité de trafic et les tests en laboratoire ne les détectent donc pas. Si un gros site Web très populaire publie tout à coup des enregistrements AAAA, on peut imaginer que l'augmentation de trafic résultante plante des équipements réseaux qui marchaient l'instant d'avant. Ou, tout simplement, dépasse leur capacité (section 2.3 de notre RFC). Prenons l'exemple d'un FAI qui déploie 6rd (RFC 5969) et le fait tourner sur trois vieux PC avec Linux (le noyau Linux a désormais 6rd en standard), cela peut marcher très bien tant que les utilisateurs font un peu de ping6 et traceroute6, et ne pas suffire si tout à coup YouTube devient accessible en IPv6.

Bien sûr, tous les sites Web ne sont pas logés à la même enseigne, car ils n'ont pas tous le même public. http://www.ietf.org/ a un AAAA depuis très longtemps, sans problèmes. Mais son public, les gens qui suivent le travail de l'IETF, ne ressemble pas à celui de TF1 : il est nettement plus soucieux de la qualité de sa connexion et s'assure qu'elle marche en v4 et en v6. D'autres sites Web qui ont un public moins geek ne veulent pas prendre le moindre risque.

Quelle est l'ampleur de ce risque ? Quelques organisations ont fait des études sur le malheur des globes oculaires et trouvent jusqu'à 0,078 % de malheureux. C'est évidemment très peu mais cela fait encore trop de monde pour un gros site Web qui a des millions de visiteurs. (Voir les études « IPv6 & recursive resolvers: How do we make the transition less painful? », « Yahoo proposes 'really ugly hack' to DNS », « Evaluating IPv6 adoption in the Internet » et « Measuring and Combating IPv6 Brokenness ».) Le risque est donc jugé inacceptable par beaucoup de gérants de gros sites Web.

Bref, il faut trouver une solution. Sinon, le risque est que les gérants de sites Web les plus timides retardent éternellement la migration vers IPv6.

Alors, quelles sont les solutions possibles (section 4) ? Comme avec toutes les techniques de migration vers IPv6, il ne faut pas les appliquer toutes bêtement. Chacune a ses avantages et ses inconvénients et le choix de la meilleure technique dépend des caractéristiques du site Web qui veut se rendre accessible en v6. Première méthode, la plus satisfaisante techniquement, est de résoudre le problème à la source en s'assurant que tous les clients du site aient un IPv6 qui marche bien. C'est ainsi que cela fonctionne pour les sites Web qui visent un public technique, comme http://www.ietf.org/ : les problèmes sont discutés et résolus collecivement. C'est en effet la meilleure solution sauf qu'elle est souvent impossible : au contraire de ce qui se passe pour le site Web interne à une organisation, le site Web public typique n'a pas de contrôle sur la connectivité de ses clients, ni sur le logiciel utilisé (navigateur Web, par exemple). Toutefois, s'il s'agit d'un gros site très populaire, il peut influencer les utilisateurs en recommandant ou en déconseillant des logiciels, des FAI, ou des configurations, par exemple via une page Web d'aide sur le site.

Comme le problème, par exemple d'un FAI donné, a des chances de toucher tous les gros sites qui servent du contenu, ceux-ci peuvent aussi se coordonner pour faire pression sur le maillon faible. Ce genre de coordinations entre acteurs différents n'est jamais facile mais elle a eu lieu pour le World IPv6 Day . En deux mots, celle approche du problème est possible mais sans doute insuffisante.

Deuxième tactique possible, avoir des noms de domaine spécifiques à IPv6 (section 4.2). Par exemple, à la date d'écriture de cet article, Facebook n'a pas d'enregistrement AAAA pour www.facebook.com (attention, cela dépend du résolveur qui demande, pour les raisons expliquées plus loin) mais il en a un pour www.v6.facebook.com. Ainsi, l'utilisateur naïf ne risque pas d'avoir des problèmes IPv6 mais l'utilisateur plus tenté par la technique pourra essayer l'accès en IPv6 et aider au déboguage initial. Cela permet une transition progressive, au lieu d'ouvrir les vannes en grand d'un coup. Et cela permet de tester la connectivité v6 du site, celle de certains de ses clients, d'introduire IPv6 en production (si le nom en question bénéficie de la même surveillance et des mêmes exigences de qualité de service que les noms classiques).

Mais cette méthode ne permet pas d'aller très loin : comme il faut une action consciente de l'utilisateur pour se connecter en IPv6, le trafic restera très limité. Comme la population de testeurs n'est pas représentative, les logiciels ou FAI qui sont peu utilisés par les utilisateurs geeks ne seront pas réellement testés. Cette technique ne peut donc convenir qu'au tout début de la migration.

Une autre méthode, qui a été mise au point et popularisée par Google, et qui est la plus détaillée dans ce RFC, est le whitelisting (section 4.3). Il s'agit de configurer les serveurs DNS faisant autorité pour le domaine, afin de ne renvoyer d'enregistrements AAAA qu'aux clients dont on sait qu'ils ont de l'IPv6 correct, et qui ont été placés sur une liste blanche, indiquant les réseaux jugés corrects. Notez bien que la liste indique des réseaux, pas des machines individuelles. Non seulement il serait humainement impossible de gérer une liste de machines, mais en outre le serveur DNS faisant autorité ne voit pas la machine individuelle, il est interrogé par les résolveurs, typiquement des machines du FAI.

Cette technique ressemble donc à celle de certains systèmes de load-balancing ou de CDN (cf. sections 4.3.2 et 4.3.3, ainsi que le RFC 1794), qui eux-aussi renvoient une réponse DNS différente selon le client. Cela évoque donc aussi le split DNS (section 4.3.4) décrit dans la section 3.8 du RFC 2775. Le split DNS (conçu à l'origine pour renvoyer des réponses différentes au client du réseau local, par exemple des adresses RFC 1918) a toujours été très contesté. Les objections des sections 2.1 et 2.7 du RFC 2956 concernent surtout le fait que le FQDN n'est plus un identificateur stable, si la résolution DNS dépend du client. Cette fragmentation de l'espace de nommage est la principale raison pour laquelle beaucoup de gens n'aiment pas le whitelisting.

Déployé par Google, le whitelisting est documenté dans l'article de C. Marsan « Google, Microsoft, Netflix in talks to create shared list of IPv6 users » et dans celui de E. Kline « IPv6 Whitelist Operations ». Son principe est donc « plutôt que de résoudre le problème, masquons-le ».

Voici le whitelisting en action : je demande l'adresse IPv6 de google.com depuis Free, qui est whitelisté.


% dig AAAA google.com
...
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
google.com.             300     IN      AAAA    2a00:1450:4007:802::1005

Par contre, depuis Orange, on n'a pas de réponse.


% dig AAAA google.com
...
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...

Notez bien que le whitelisting est complètement indépendant du protocole utilisé pour le transport de la requête DNS. Le fait que le résolveur utilise IPv4 ou IPv6 pour interroger le serveur faisant autorité n'implique rien quant aux capacités v4 ou v6 de la machine cliente (celle sur laquelle tourne le navigateur Web). La liste blanche contient donc aussi bien des adresses IPv4 qu'IPv6.

Par définition, le fait d'être dans la liste blanche nécessite une évaluation du réseau client. Sa maintenance est donc non triviale et consomme des ressources humaines, nécessite des mesures, etc. Google peut se le permettre, mais ce n'est pas accessible à tout le monde.

Notez que cette technique nécessite d'avoir le contrôle de tous les serveurs faisant autorité sur le domaine, y compris les secondaires. Et qu'elle n'est pas toujours mise en œuvre dans les logiciels serveurs typiques, il faut donc se préparer à programmer un peu. Je n'ai pas testé mais je suppose qu'on peut mettre en œuvre le whitelisting sur BIND en utilisant les vues, avec deux fichiers de zone (un avec AAAA et un sans) et en définissant une ACL pour la liste blanche, dirigeant ses membres vers la vue ayant les AAAA :

acl v6-whitelist {
                192.0.2.0/24; 
                2001:db8:3003::/48;
};
...
view "with-aaa" {
   match-clients { v6-whitelist; };
   zone "example.com" {
        ...
        file "/etc/bind/example.com-with-aaaa";
   };
};
view "external" {
   match-clients { any; };
   zone "example.com" {
        ...
        file "/etc/bind/example.com-without-aaaa";
   };
};

La solution n'est pas parfaite : un réseau peut avoir correctement déployé IPv6 mais un utilisateur peut avoir un navigateur Web qui a des problèmes avec IPv6. La liste blanche stockant des réseaux, les globes oculaires de cet utilisateur seront malheureux quand même. Mais cela reste une des meilleures solutions existantes.

Aujourd'hui, on l'a vu, cette solution est manuelle : les réseaux qui veulent être whitelistés soumettent leur candidature, sont évalués (ce qui peut nécessiter une interaction qui consomme donc également des ressources humaines du côté du FAI), et mis (ou pas) dans la liste. Dans le futur, on verra peut-être une automatisation de la procédure, avec des tests faits de temps en temps. Autre évolution possible, le passage en mode « liste noire » où tous les clients DNS recevraient l'enregistrement AAAA, sauf ceux explicitement listés dans la liste noire (section 4.4). Cela sera intéressant le jour où la majorité des FAI auront un IPv6 qui marche, et où seuls quelques maillons faibles subsisteront.

Un résumé des inquiétudes sur le whitelisting figure dans l'article de Brzozowski, J., Griffiths, C., Klieber, T., Lee, Y., Livingood, J., et R. Woundy, « IPv6 DNS Resolver Whitelisting - Could It Hinder IPv6 Adoption? ». Outre la fragmentation de l'espace de nommage, la principale inquiétude concerne l'introduction d'une nouvelle composante dans le réseau, qui rend le déboguage plus compliqué (un principe cardinal de l'Internet est que les décisions « politiques » doivent être faites aux extrémités, pas dans des équipements intermédiaires, cf. RFC 3724 et l'article de Blumenthal, M. et D. Clark, « Rethinking the design of the Internet: The end to end arguments vs. the brave new world » et, sur le cas spécifique du DNS, la section 2.16 du RFC 3234.) Un bon exemple est donné par les résultats de dig cités plus haut : déboguer l'accès à Google va dépendre du réseau où on fait le dig. De beaux malentendus peuvent alors survenir. Mais le débat est complexe : s'il y a un large consensus sur l'importance de ne pas mettre trop d'état et de décisions dans les équipements intermédiaires (le principe « de bout en bout »), la discussion a toujours fait rage sur qu'est-ce qu'un équipement intermédiaire. Est-ce qu'un serveur DNS fait partie des middleboxes qui perturbent si souvent la connexion de bout en bout ?

Enfin, la dernière tactique de migration possible est le saut direct (section 4.5) : activer IPv6 sur le serveur, le tester, puis publier un AAAA normal. Cela n'est pas forcément si radical que ça car on peut le faire nom par nom (par exemple, pour static-content.example.com avant www.example.com) mais c'est quand même la méthode la plus audacieuse. À ne faire qu'une fois qu'on maîtrise bien IPv6. Relativisons tout de même les choses : des tas de sites Web vus par un public non technique (comme http://www.afnic.fr/) ont un AAAA depuis de nombreuses années et sans que cela crée de problèmes.

Si on est toutefois inquiets, on peut utiliser cette tactique, mais pendant une période limitée : on teste, on publie le AAAA pendant quelques heures, on arrête, on analyse les résultats, on corrige les éventuels problèmes et on recommence.

Pour les lecteurs pressés, la section 5 résume les étapes possibles d'un plan de transition. Là encore, pas question de l'appliquer aveuglément. Chacun doit l'adapter aux caractéristiques spécifiques de son réseau. Rappelez-vous en outre que le RFC cible les gros sites : la plupart des petits n'auront pas envie d'autant d'étapes. Voici ces étapes potentielles successives :

  • Uniquement IPv4 (malheureusement la situation de la grande majorité du Web aujourd'hui),
  • Activation d'IPv6 et publication par des noms spécifiques, genre www.ipv6.example.org,
  • Peut-être une étape de whitelisting avec gestion manuelle,
  • Peut-être suivi par une étape de whitelisting automatique,
  • Le whitelisting étant prévu pour être une étape temporaire, on va le couper, une fois les problèmes résolus. (Cela peut se faire lors d'une occasion un peu solennelle comme le World IPv6 Launch le 6 juin 2012.)
  • À partir de là, le site est complètement accessible en IPv6 (et en IPv4), avec le nom de domaine normal.
  • La section 6.3 discute du cas, très futuriste à l'heure actuelle, où certains auront une meilleur connectivité en IPv6 qu'en IPv4. Il faudra alors mettre au point des techniques de transition pour retirer l'accès IPv4 petit à petit.

Voici, vous connaissez maintenant l'essentiel. La section 6 du RFC liste quelques points de détail. Par exemple, contrairement à ce que certains pourraient croire au premier abord, le whitelisting est tout à fait compatible avec DNSSEC (section 6.1), puisqu'il se fait sur les serveurs faisant autorité. Ceux-ci peuvent donc parfaitement signer les deux versions de la réponse, avec ou sans AAAA, et ces deux réponses pourront être vérifiés comme authentiques.

Par contre, si un résolveur DNS s'avisait de faire des manipulations analogues au whitelisting, par exemple en retirant les réponses AAAA vers des clients qu'il sait ne pas gérer IPv6 correctement, alors, là, DNSSEC détecterait la manipulation comme une tentative d'attaque, et la réponse ne pourrait pas être validée.

On a vu que la gestion d'une liste blanche représentait un certain travail. Il est donc tentant de partager les résultats de ce travail entre plusieurs acteurs. Mais attention à le faire en respectant la vie privée (section 6.2). Il n'y a pas de problèmes avec les listes actuelles, dont la granularité ne descend pas jusqu'à l'individu, mais, si des listes plus précises devaient apparaître, ce problème est à garder en tête.


Téléchargez le RFC 6589


L'article seul

RFC 6586: Experiences from an IPv6-Only Network

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : J. Arkko, A. Keranen (Ericsson)
Pour information
Première rédaction de cet article le 22 Avril 2012


La plupart des RFC décrivent, de façon normative, un protocole ou un format qui sera ensuite déployé sur l'Internet. Mais ce document est différent : c'est un récit d'expérience, celle de deux courageux chercheurs qui, au péril de leur usage de Facebook et dans l'intérêt de la science, ont coupé IPv4 et n'ont accédé à l'Internet que via IPv6 pendant la durée de l'expérience. Les machines de l'expérience n'avaient plus du tout d'IPv4 et seule une fragile passerelle NAT64 les reliaient aux territoires barbares où régnait encore IPv4. Qu'est-ce qui marche dans ce cas ? Qu'est-ce qui ne marche pas ? Qu'est-ce qu'on peut améliorer ?

Deux réseaux ont été utilisés, un professionnel et un à la maison. Tous les deux étaient en double-pile (IPv4 et IPv6, cf. RFC 4213) depuis longtemps. Tous les deux avaient une connectivité IPv6 stable et correcte depuis des années. Il était donc temps de sortir de la « zone de confort » et d'essayer le grand large. Mais la majorité de l'Internet reste accessible en IPv4 seulement. C'est là qu'intervient NAT64 (RFC 6144), qui permet aux machines purement IPv6 d'accèder à des sites Web attardés en v4.

Ce n'est pas juste une expérience de démonstration pour montrer que les Vrais Hommes peuvent se passer du vieux protocole des mangeurs de yaourt. L'épuisement des adresses IPv4 fait que de plus en plus de FAI envisagent de déployer des réseaux uniquement IPv6, puisqu'ils n'ont plus la possibilité d'obtenir des adresses. Tester de tels réseaux en vrai est donc nécessaire. La conclusion est d'ailleurs que cela ne marche pas trop mal mais qu'il reste un certain nombre de petits problèmes qu'il serait bon de régler.

La section 3 du RFC explique l'environnement de l'expérience. Les deux réseaux (un à la maison et un au bureau) étaient un mélange classique de PC, d'appareils photos numériques, de gadgets électroniques divers et de petits routeurs du commerce, avec divers systèmes (Mac OS, Windows, Linux...). Les usages étaient également classiques, courrier, SSH, VoIP, jeu (pas dans le réseau de bureau, bien sûr), messagerie instantanée, un peu de domotique et bien sûr du Web. Il s'agissait de petits réseaux avec une dizaine d'utilisateurs au maximum.

Comme certains des utilisateurs des deux réseaux, des petits bras, avaient choisi de ne pas participer à l'expérience, il a fallu créer un réseau séparé pour celle-ci, avec un VLAN propre. Il n'y avait évidemment pas de serveur DHCP v4 sur ce réseau seulement des RA (Router Advertisment) v6.

On l'a vu, l'essentiel du Web aujourd'hui n'est accessible qu'en IPv4. Il a donc fallu mettre en place une passerelle NAT64 (RFC 6146). Elle incluait le serveur DNS64 (RFC 6147). L'installation et la configuration de cette passerelle étaient très simples pour un administrateur réseaux.

Le serveur DNS cité plus haut était publié via les RA (RFC 6106). (À noter que Windows écrit aussi à des serveurs DNS bien connus, fec0:0:0:ffff::1, fec0:0:0:ffff::2, et fec0:0:0:ffff::.) Trouver le serveur DNS dans un environnement IPv6 pur n'est pas trivial. Dans les environnements mixtes, il est fréquent que le résolveur DNS à utiliser par les clients ne soit publié qu'en v4, les clients demandant ensuite aussi bien les enregistrements A que les AAAA en IPv4. Ici, cette méthode n'était pas possible et les auteurs du RFC ont également testé avec DHCP v6 (RFC 3315). Un des charmes d'IPv6 est en effet qu'il existe deux façons de découvrir automatiquement le résolveur DNS local, via les RA ou bien via DHCP.

Le serveur DNS64 et la passerelle NAT64 fonctionnaient de la manière habituelle (RFC 6144) : si un client demandait un AAAA (adresse IPv6 dans le DNS) inexistant, le serveur DNS64 en synthétisait un , les paquets à destination de cette adresse étaient ensuite interceptés par la passerelle et NATés en IPv4 (la passerelle avait, elle, une adresse v4 publique). Les destinations ayant des AAAA étaient traitées normalement : la passerelle servait alors de simple routeur v6, le cas idéal d'une connectivité v6 complète.

Les résultats de l'expérience occupent le reste du RFC. La section 4 fournit une synthèse et la section 5 examine un par un les choses qui ont plus ou moins bien marché. Principale conclusion ; ça marche. Un des auteurs du RFC travaille dans un environnement IPv6 pur depuis un an et demi et est toujours vivant et en bonne santé. Certains points marchent particulièrement bien (aucun problème avec le Web). Sur un téléphone Symbian, toutes les applications ont marché (sur un Android, toutes les applications de base marchaient, mais après un bricolage pour permettre à la machine de trouver son résolveur DNS).

Les problèmes rencontrés se subdivisent en plusieurs catégories :

  • Les bogues pures et simples. Un logiciel gère théoriquement IPv6 mais, en pratique, on trouve des problèmes qui n'existent pas en v4. Ces bogues sont relativement fréquentes car trop peu de tests sont faits avec IPv6.
  • Pas d'IPv6 du tout, même en théorie. Cela arrive à des programmes antédiluviens (le RFC cite dict, un client RFC 2229) mais aussi, et là c'est inexcusable, à des programmes plus récents comme le logiciel privateur Skype, ou comme beaucoup de jeux.
  • Des problèmes liés au protocole. Dès que le protocole transmet des adresses IP, les ennuis commencent. La machine locale utilise IPv6, transmet l'adresse au pair v4 avec qui elle communique grâce au NAT64, pair qui n'arrive pas à répondre. Un exemple est fourni par certaines applications Web qui renvoient une page avec des URL utilisant des adresses IPv4 littérales (comme http://192.0.2.80/). Ce problème est rare mais très agaçant lorsqu'il se produit.
  • Problèmes situés quelque part dans la couche 3, le plus fréquent étant les problèmes de MTU causés par un pare-feu mal configuré.

Bref, aucun de ces problèmes n'était un problème fondamental d'IPv6 ou de NAT64, nécessitant de revisiter le protocole. C'était « uniquement » des questions de développement logiciel.

Maintenant, avec la section 5, voyons ces problèmes cas par cas. D'abord, ceux situés dans les systèmes d'exploitation. Par exemple, Linux ne jette pas l'information acquise par les RA lorsque la connectivité réseau change, il faut faire explicitement un cycle suspension/reprise. Ensuite, le démon rdnssd, censé écouter les annonces de résolveurs DNS faites en RA, n'était pas intégré par défaut sur Ubuntu et, de toute façon, ne semblait pas très fiable. Comme pas mal de problèmes rencontrés lors de cette expérience, il s'est résolu en cours de route, avec une nouvelle version du système. Mais tout n'est pas parfait, notamment le NetworkManager qui s'obstine à sélectionner un réseau sans-fil IPv4 qui n'a pas de connectivité externe, plutôt que le réseau IPv6 pur.

Les autres systèmes ont aussi ce genre de problèmes. Ainsi, avec Mac OS X, il faut dire explicitement au système qu'IPv4 est facultatif et qu'un réseau sans IPv4 ne doit pas être considéré comme cassé et à ignorer. Et passer d'un réseau v4 à v6 nécessite des manipulations manuelles.

Pour Windows 7, le problème était avec les résolveurs DNS : Windows les affichait mais ne les utilisait pas sans action manuelle.

Android a un problème analogue. Il peut faire de l'IPv6 mais il ne sait pas sélectionner les résolveurs DNS en IPv6. Par défaut, il lui faut donc un résolveur DNS v4. Heureusement, il s'agit de logiciel libre et les auteurs ont pu résoudre ce problème eux-même avec le nouveau logiciel DDD.

En conclusion, le RFC note que tous ces systèmes ont IPv6 à leur catalogue depuis des années, parfois de nombreuses années, mais tous ces problèmes donnent à penser qu'ils n'ont jamais été sérieusement testés.

La situation des langages de programmation et des API semble meilleure, par exemple Perl qui était un des derniers grands langages à ne pas gérer complètement IPv6 par défaut semble désormais correct.

C'est moins satisfaisant pour la messagerie instantanée et la voix sur IP. Les cris les plus perçants des utilisateurs impliqués dans l'expérience avaient été provoqués par Skype, qui ne marche pas du tout en IPv6 (il a fallu utiliser un relais SSH vers une machine distante). La légende comme quoi Skype marcherait toujours du premier coup en prend donc un... coup.

Parmi les autres solutions testées, celles passant par le Web marchaient (Gmail ou Facebook, par exemple), celles fondées sur XMPP également mais les solutions commerciales fermées comme MSN, WebEx ou AOL échouent toutes. Ces solutions sont mises en œuvre dans des logiciels privateurs (on ne peut donc pas examiner et corriger le source) mais l'examen du trafic réseau montre qu'il passe des adresses IPv4 entre machines, ce qui est incompatible avec NAT64.

Et pour les applications stratégiques essentielles, je veux dire les jeux ? Ceux utilisant le Web n'ont pas de problème, pour les autres, c'est l'échec complet. En outre, aucun des ces logiciels ne produit de messages de diagnostic utilisables et le déboguage est donc très difficile. Au moment des premiers tests, ni Battlefield, ni Age of Empires, ni Crysis ne fonctionnaient sur le nouveau réseau. Depuis, World of Warcraft est devenu le premier jeu majeur qui marchait en IPv6. Les jeux dont le source a été libéré (comme Quake) ont également acquis cette capacité. Les autres feraient bien d'utiliser une API réseau plus moderne... (Cf. RFC 4038.)

Pendant qu'on en est au divertissement, que devient la musique en ligne ? La plupart des boutiques reposent sur le Web et marchent donc, sauf Spotify qui réussit l'exploit d'être un des rares services accessibles via le Web qui ne fonctionne pas en IPv6.

Moins bonne est la situation des appliances comme les webcams. La plupart ne parlent pas IPv6 du tout, sourds que sont leurs constructeurs chinois aux sirènes de la modernité.

Enfin, les problèmes ne sont pas forcément avec les matériels et logiciels du réseau local. Parfois, le problème est situé chez le pair avec qui on veut communiquer comme lorsque bit.ly (le RFC cite ce cas mais sans mentionner le nom comme si l'information n'était pas déjà publique...) avait publié un enregistrement AAAA invalide : NAT64 ne peut rien dans ce cas puisque la passerelle pense que le service est accessible en IPv6. C'est l'occasion de rappeler qu'il vaut mieux ne pas publier de AAAA que d'en publier un erroné.

On l'a vu, une bonne partie de la connectivité externe des deux réseaux de test dépendait de NAT64, puisqu'une grande partie de l'Internet n'est hélas pas joignable en IPv6. La section 6 tire le bilan spécifique de ce protocole et il est très positif : pas de problèmes de fond, juste quelques bogues dans l'implémentation, corrigées au fur et à mesure.

Le cas des adresess IPv4 littérales dans les URL est irrémédiable (le DNS n'est pas utilisé donc DNS64 ne peut rien faire) mais rare. Les deux seuls cas bloquants concernaient certaines pages YouTube (tiens, pourquoi est-ce que les erreurs de bit.ly sont mentionnées sans indiquer son nom, alors que YouTube est désigné dans le RFC ?) et une page de réservation d'un hôtel qui renvoyait vers un URL contenant une adresse IPv4. Les auteurs du RFC ont mesuré les 10 000 premiers sites Web du classement Alexa et trouvé que 0,2 % des 1 000 premiers ont un URL IPv4 dans leur page (pour charger du JavaScript, du CSS ou autre), et que ce chiffre monte à 2 % pour les 10 000 premiers (ce qui laisse entendre que les premiers sont mieux gérés). Cette stupide erreur n'empêchait pas le chargement de la page, elle privait juste le lecteur d'un bandeau de publicité ou d'une image clignotante. Ce n'est donc pas un problème sérieux en pratique.

Les auteurs ont également testé avec wget le chargement des pages d'accueil de ces 10 000 sites en comparant un accès IPv4, un accès IPv6 sans NAT64 et le réseau de test, IPv6 pur mais avec NAT64. En IPv4 pur, 1,9 % des sites ont au moins un problème (pas forcément la page d'accueil elle-même, cela peut être un des composants de cette page), ce qui donne une idée de l'état du Web. Le RFC note toutefois que certains problèmes peuvent être spécifiques à ce test, si le serveur refuse à wget du contenu qu'il accepterait de donner à un navigateur Web. wget avait été configuré pour ressembler à un navigateur (le RFC ne le dit pas mais je suppose que cela veut dire des trucs comme --user-agent="Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:11.0) Gecko/20100101 Firefox/11.0"). Mais cela ne suffit pas dans des cas comme l'absence d'une adresse pour un nom de domaine, qui ne gène pas le navigateur qui ajoute www devant à tout hasard, chose que ne fait pas wget.

Avec le réseau IPv6 pur, 96 % des sites échouent (ce qui est logique, vu le nombre de sites Web accessible en v6). Les sites Google étaient une des rares exceptions.

Avec le réseau IPv6 aidé de la passerelle NAT64, le taux d'échec est de 2,1 %, quasiment le même qu'en IPv4 pur (la différence venant surtout des adresses IPv4 littérales).

Sur quoi doivent porter les efforts de mesure futurs (section 7) ? Le RFC estime important de mesurer plus précisement les phénomènes à l'œuvre lors d'une connexion utilisant NAT64. Certains utilisateurs ont signalé des ralentissements, mais qui ne sont pas confirmés par une analyse des paquets et des temps de réponse. S'il se passe quelque chose qui ralentit, c'est plus subtil, et cela devrait être investigué.

Compte-tenu de cette expérience, quelles conclusions en tirer (section 8) ? Comme indiqué plus haut, la principale est qu'un réseau purement IPv6 est viable. (Le RFC ne le précise pas mais je rajoute : s'il est géré par un informaticien compétent et disponible. Cette expérience n'est pas encore reproductible par M. Toutlemonde.)

Seconde grande conclusion : il reste du travail, trop de petites bogues sont encore présentes, et à beaucoup d'endroits.

Bref, aujourd'hui, il reste prudent d'utiliser plutôt la double-pile (IPv6 et IP4) pour un réseau de production. Un réseau IPv6 pur, à part pour le geek, est surtout intéressant pour des environnements très contrôlés, comme par exemple celui d'un opérateur de téléphonie mobile qui fournirait un modèle de téléphone obligatoire, permettant de s'assurer que tous les clients aient ce qu'il faut.

Comme tout ne s'arrangera pas tout seul, nos héroïques explorateurs revenant de la terre lointaine et mystérieuse où tout ne marche qu'en IPv6 suggèrent des actions à entreprendre pour se préparer à notre future vie dans ce monde :

  • La découverte du résolveur DNS reste un des points qui marchent le plus mal, probablement parce qu'elle fonctionne bien en double-pile, masquant les problèmes IPv6. Par exemple, l'utilisation des annonces RA du RFC 6106 devrait être systématique et c'est loin d'être le cas, par exemple dans les divers systèmes utilisant Linux.
  • Autre problème, les divers network managers, ces logiciels qui règlent le ballet des différentes composants de l'accès au réseau : même lorsque le système dispose de tous les composants qui marchent en IPv6, le network manager ne les utilise pas toujours correctement. En essayant Ubuntu, par exemple, il est clair que ce système n'a jamais été testé dans un environnement purement IPv6.
  • Les pare-feux ont souvent des capacités IPv6 inférieures à celles qu'ils ont en v4.
  • Plusieurs applications que les utilisateurs considèrent comme très importantes (les jeux vidéo, par exemple) ne marchent pas du tout en IPv6 : du travail pour les programmeurs, qui devraient au miminum utiliser des API qui sont indépendantes de la version d'IP.

Le RFC note que pratiquement aucune de ces actions ne nécessite d'action dans le champ de la normalisation. Cela veut dire que toutes les normes nécessaires sont là, l'IETF a terminé son travail et c'est maintenant aux programmeurs et aux administrateurs réseaux d'agir.


Téléchargez le RFC 6586


L'article seul

RFC 6585: Additional HTTP Status Codes

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : M. Nottingham (Rackspace), R. Fielding (Adobe)
Chemin des normes
Première rédaction de cet article le 1 Mai 2012


Le protocole HTTP, normalisé dans le RFC 2616, utilise des réponses numériques sur trois chiffres pour indiquer le résultat de la requête. Certains de ces codes sont devenus célèbres comme le 404 pour une ressource non trouvée. Et comme l'Internet fonctionne avec des LOLcats, il existe même un ensemble de photos des réponses HTTP avec des chats (d'où sont tirées les images de cet article). Mais la liste des réponses possibles n'est pas figée et de nouveaux codes sont ajoutés de temps en temps. Ce RFC normalise quatre de ces codes.

Ces nouveaux codes permettent de préciser le code utilisé autrefois, qui était en général moins précis. Ainsi, les limiteurs de trafic utilisaient souvent, lorsqu'un client demandait trop de ressources, le code 403 (Interdiction), qui pouvait servir à bien d'autres choses. Ils ont désormais un code à eux, 429. Les nouveaux codes sont enregistrés à l'IANA.

Rappelez-vous bien que le premier chiffre indique la classe de l'erreur (RFC 2616, section 6.1.1) et qu'un serveur HTTP qui utilise un code nouveau n'a pas de souci à se faire : un client qui ne connaîtrait pas ce nouveau code peut le traiter comme le code générique commençant par le même chiffre. Pour reprendre l'excellent résumé de Dana Contreras, « HTTP response codes for dummies. 5xx: we fucked up. 4xx: you fucked up. 3xx: ask that dude over there. 2xx: cool ».

Premier cité (section 3), 428 Precondition Required (pas de jolie image de chat pour ce code). Pour éviter le problème de la « mise à jour perdue » (un client récupère une ressource Web, la modifie et la renvoie au serveur pour mise à jour, alors que, pendant ce temps, un autre client a fait pareil : l'un des deux va perdre sa mise à jour), certains serveurs HTTP exigent que les requêtes soient conditionnelles (par exemple avec le If-Match: de la section 14.24 du RFC 2616). Si le client n'a pas utilisé de condition, le serveur l'enverra promener avec ce code 428 (qui doit normalement être accompagné d'un message clair indiquant le problème) :


HTTP/1.1 428 Precondition Required
Content-Type: text/html

<html>
 <head>
  <title>Precondition Required</title>
 </head>
 <body>
  <h1>Precondition Required</h1>
   <p>This request is required to be conditional;
      try using "If-Match".</p>
 </body>
</html>

Deuxième code, 429 Too Many Requests (section 4) Il était apparemment assez répandu dans la nature mais n'était pas encore normalisé. C'est désormais fait et les limiteurs de trafic peuvent donc désormais dire clairement à leurs clients qu'ils exagèrent :


HTTP/1.1 429 Too Many Requests
Content-Type: text/html
Retry-After: 3600

<html>
   <head>
      <title>Too Many Requests</title>
   </head>
   <body>
      <h1>Too Many Requests</h1>
      <p>I only allow 50 requests per hour to this Web site per
         logged in user. Try again soon.</p>
   </body>
</html>

C'est uniquement un indicateur d'une décision prise par le serveur : le RFC n'impose pas aux serveurs un mécanisme particulier pour prendre cette décision. De même, le serveur n'est pas obligé de renvoyer quelque chose (ce qui consomme des ressources), il a le droit d'ignorer purement et simplement les requêtes excessives (section 7.2).

Troisième code, en section 5, 431 Request Header Fields Too Large Le protocole HTTP n'impose pas de limite à la taille des en-têtes envoyés lors d'une requête mais un serveur donné peut avoir une telle limite. Si elle est dépassée, il peut répondre 431. Le même code peut dire « taille totale des en-têtes trop grande » ou « taille d'un en-tête trop grande ». Dans ce dernier cas, la réponse doit indiquer quel en-tête :


HTTP/1.1 431 Request Header Fields Too Large
Content-Type: text/html

<html>
   <head>
      <title>Request Header Fields Too Large</title>
   </head>
   <body>
      <h1>Request Header Fields Too Large</h1>
      <p>The "Example" header was too large.</p>
   </body>
</html>

Ces trois premiers codes n'ont pas suscité de controverses particulières. Ce n'était pas le cas de 511 Network Authentication Required (section 6, pas de jolie image de chat pour ce code) qui indique que le client aurait dû s'authentifier. Le problème est d'architecture : ce code est utilisé pour les portails captifs qui, tant qu'on n'est pas authentifié, redirigent d'autorité toutes les requêtes HTTP vers un serveur permettant de s'authentifier. (Après l'authentification, l'adresse MAC est mémorisée par le routeur, qui ne redirige plus.) De tels portails violent sérieusement les bons principes d'architecture du Web. Mais ils existent et il était donc préférable qu'ils puissent répondre avec un code sans ambiguité. La réponse 511 inclut donc le lien vers la page de login. Elle ne doit jamais être envoyée par un serveur normal, uniquement par le relais détourneur.

Le RFC dit donc que les portails captifs sont le Mal (surtout pour les clients HTTP qui ne sont pas des navigateurs) mais que le 511 permettra de limiter les dégats. Au moins, curl ou wget comprendront tout de suite ce qui s'est passé.

Un exemple de réponse (notez l'élément <meta> pour les navigateurs) :


HTTP/1.1 511 Network Authentication Required
Content-Type: text/html

<html>
   <head>
      <title>Network Authentication Required</title>
      <meta http-equiv="refresh"
            content="0; url=https://login.example.net/">
   </head>
   <body>
      <p>You need to <a href="https://login.example.net/">
      authenticate with the local network</a> in order to gain
      access.</p>
   </body>
</html>

Les réponses 511 ou, plus exactement, les redirections forcées posent des tas de problèmes de sécurité. Par exemple, elles ne viennent pas du serveur demandé, ce qui casse certains mécanismes de sécurité de HTTP comme les cookies du RFC 6265. Un problème analogue survient si on utilise TLS car le certificat X.509 ne correspondra pas au nom demandé. L'annexe B du RFC détaille les problèmes de sécurité des portails captifs et les façons de les limiter. Cela va de problèmes esthétiques (la favicon récupérée depuis le portail et qui s'accroche ensuite dans le cache du navigateur) jusqu'aux protocoles de sécurité qui risquent de prendre la réponse du portail pour l'information qu'ils demandaient (P3P, WebFinger, OAuth, etc). Ces protocoles sont souvent utilisés par des applications HTTP qui ne passent pas par un navigateur (Twitter, iTunes, le WebDAV du RFC 4918, etc). En détectant le code 511, ces applications ont une chance de pouvoir réagir proprement (en ignorant les réponses transmises avec ce code).

À l'heure actuelle, je ne pense pas qu'il y ait beaucoup de hotspots qui utilisent ce code mais cela viendra peut-être. Mais je n'en suis pas sûr, ces portails captifs étant en général programmés avec les pieds, par un auteur anonyme à qui on ne peut jamais signaler les bogues. Et je ne sais pas quels sont les clients HTTP qui le reconnaissent et agissent intelligement. Si un lecteur courageux veut enquêter...

Les images de chats citées plus haut sont également accessibles via une API REST simple.


Téléchargez le RFC 6585


L'article seul

RFC 6582: The NewReno Modification to TCP's Fast Recovery Algorithm

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : T. Henderson (Boeing), S. Floyd (ICSI), A. Gurtov (University of Oulu), Y. Nishida (WIDE Project)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 7 Avril 2012


Même les plus vieux protocoles, comme TCP, continuent à évoluer, dans l'environnement toujours changeant qu'est l'Internet. Pour lutter contre le principal ennemi d'un protocole de transport, la congestion, de nouveaux algorithmes sont régulièrement mis au point. Même des années après leur spécification, on trouve des choses à corriger ou améliorer. Ainsi, l'algorithme NewReno, originellement proposé par le RFC 2582 en 1999, puis normalisé par le RFC 3782 en 2004, voit avec ce nouveau RFC sa description évoluer très légèrement, pour répondre aux problèmes rencontrés.

La référence pour la lutte de TCP contre la congestion est le RFC 5681. Ce dernier spécifie quatre algorithmes possibles, et autorise des modifications limitées à ces algorithmes, par exemple en utilisant les accusés de réception sélectifs (SACK, RFC 2883) ou bien en utilisant les accusés de réception partiels (ceux qui ne couvrent pas la totalité des données encore en transit). C'est le cas de NewReno et ce RFC remplace l'ancienne définition de NewReno (celle du RFC 3782).

Un peu d'histoire de NewReno (section 1) : l'algorithme de retransmission rapide (Fast Recovery) de TCP avait d'abord été mis en œuvre dans une version de BSD connue sous le nom de Reno. (L'article original est toujours en ligne, ainsi qu'une comparaison des méthodes.) L'idée de base de la retransmission rapide est de retransmettre les accusés de réception lorsqu'arrivent des paquets dont les numéros de séquence sont supérieurs à ceux attendus (section 5 de notre RFC ; cette retransmission indique la perte de paquets intermédiaires). L'émetteur commence alors tout de suite à retransmettre, sans attendre l'expiration du délai de garde normal. Le problème est que l'émetteur ne sait pas exactement ce qu'il faut retransmettre. Par exemple, avec une MSS de 1460 octets et un numéro de séquence initial (ISN) de 67891, si un émetteur envoie cinq paquets, il sera satisfait lorsqu'il recevra un accusé de réception pour l'octet 75191. S'il reçoit des accusés de réception dupliqués pour l'octet 70811, cela veut dire que deux paquets sont arrivés, puis que le paquet n° 4 ou le n° 5 est arrivé, déclenchant l'émission des accusés de réception dupliqués. L'émetteur va alors retransmettre le paquet n° 3. Mais doit-il aussi renvoyer les n° 4 et n° 5 ? L'émetteur ne le sait pas, les accusés de réception n'indiquent pas les octets reçus hors-séquence, sauf à utiliser les SACK du RFC 2883. NewReno avait justement été conçu pour ce cas où on ne peut pas ou bien où on ne veut pas utiliser les accusés de réception sélectifs (SACK). Son principe est, pendant la retransmission rapide, de regarder si les accusés de réception couvrent tous les paquets transmis (accusé de réception pour l'octet 75191) ou bien seulement une partie (par exemple, accusé de réception pour l'octet 72271). Dans ce cas (accusés de réception partiels), on sait qu'il y a perte de plusieurs paquets et on peut retransmettre tout de suite (ici, le paquet n° 4).

NewReno est donc une légère modification, située uniquement chez l'émetteur, à l'algorithme de retransmission rapide (« OldReno » ?). Cette modification est déclenchée par la réception, une fois la retransmission rapide commencée, d'accusès de réception partiels. Elle consiste en la réémission de paquets supplémentaires, suivant le paquet qu'« OldReno » retransmettait déjà.

Si vous voulez tous les détails, la section 3 précise le nouvel algorithme. Comme il ne nécessite des modifications que chez l'émetteur des données, il n'affecte pas l'interopérabilité des mises en œuvre de TCP. Évidemment, SACK serait une meilleure solution, donnant à l'émetteur toute l'information nécessaire mais, en son absence, NewReno améliore les performances en évitant d'attendre inutilement l'expiration d'un délai de garde.

Il existe quelques variations à NewReno, moins importantes que la différence entre OldReno et NewReno. Ces variations possibles sont documentées dans l'ancien RFC, le RFC 3782 et citées dans l'annexe A.

NewReno est aujourd'hui bien établi et éprouvé. L'ancien RFC, le RFC 3782 contenait des éléments en sa faveur (notamment via des simulations), qui semblent inutiles aujourd'hui et ont donc été retirés.

Globalement, les principaux changements depuis le RFC 3782 sont le retrait de nombreuses parties qui n'apparaissent plus aussi importantes qu'à l'époque. Le lecteur qui veut approfondir le sujet, et pas uniquement programmer NewReno correctement, peut donc lire le RFC 3782 pour découvrir d'autres discussions. Autrement, les changements sont de détail, et résumés dans l'annexe B.

Merci à Didier Barvaux pour sa relecture.


Téléchargez le RFC 6582


L'article seul

RFC 6576: IPPM standard advancement testing

Date de publication du RFC : Mars 2012
Auteur(s) du RFC : R. Geib (Deutsche Telekom), A. Morton (AT&T Labs), R. Fardid (Cariden Technologies), A. Steinmitz (Deutsche Telekom)
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 26 Mars 2012


Pour déterminer si un protocole de communication est bien décrit dans les RFC qui le normalisent, l'IETF a une méthode simple, tester si les différentes mises en œuvre de ce protocole interopèrent proprement entre eux (par exemple, on vérifie qu'un client HTTP parle au serveur HTTP avec succès). Ce genre de tests est maintenant fréquent, et sert de base à l'avancement des RFC sur le chemin des normes (de simple proposition au statut de norme complète). Mais, lorsqu'un RFC spécifie, non pas un protocole mais une métrique, c'est-à-dire une grandeur mesurable, comment fait-on pour vérifier que le RFC est correct et est bien implémenté ? Ce nouveau RFC de l'inépuisable groupe de travail IPPM propose une solution : on mesure le même phénomène avec les différentes mises en œuvre et les chiffres obtenus doivent être identiques (ou suffisamment proches pour être statistiquement équivalents). Cette méthode permettra aux RFC décrivant les métriques d'avancer sur le chemin des normes : si les résultats sont les mêmes, on considérera que cela semble indiquer que la métrique est définie clairement et sans ambiguité. (Si les résultats sont différents, cela pourra être dû à une bogue dans l'un des systèmes, ou à un RFC confus, qui n'a pas été compris de la même façon par tous les développeurs.)

Le chemin des normes, qui comportait trois étapes du temps du RFC 2026, n'en a plus que deux depuis le RFC 6410. Un des critères d'avancement d'une norme est l'interopérabilité entre des mises en œuvre indépendantes. Cette interopérabilité devait autrefois se démontrer par des tests explicites (RFC 5657) mais, aujourd'hui, le simple déploiement massif suffit (nul besoin de tester HTTP pour voir tous les jours dans l'Internet que clients et serveurs se parlent...). Tout cela est très bien pour les protocoles de communication. Mais pour des métriques ? On peut avoir plusieurs mises en œuvre indépendantes, qui sont largement déployées, sans que cela ne prouve qu'elles soient cohérentes entre elles. La section 5.3 du RFC 5657 prévoit explicitement le cas des normes qui ne sont pas des protocoles de communication mais ne fournit guère de solutions. L'analyse du groupe IPPM est qu'il est quand même possible de tester explicitement des définitions de métriques et que l'identité (aux variations statistiques près) des chiffres obtenus par deux mesures du même phénomène réseau est l'équivalent de l'interopérabilité. (Notez qu'IPPM a aussi quelques protocoles à son actif, comme ceux du RFC 4656 et RFC 5357, dont l'interopérabilité peut être testée par des moyens classiques.)

Pour les métriques, l'idée va donc être de générer un phénomène réseau contrôlé, avant de le faire mesurer par les différents systèmes. (Mesurer un phénomène réel, non contrôlé, est plus difficile car cela implique que les différentes mesures soient parfaitement synchronisées, pour observer exactement la même chose. Tous les systèmes de mesure n'ont pas forcément ce mécanisme de synchronisation.) Un exemple complet figure dans l'annexe A, avec la métrique « délai d'acheminement », et c'est une lecture très recommandée si tout cela vous semble trop abstrait.

La section 2 détaille cette idée de base. Inspirée du RFC 2330, elle part du principe qu'une mesure doit être reproductible (on mesure le même phénomène deux fois, et les résultats doivent être identiques, aux fluctuations statistiques près). En pratique, mesurer exactement « le même phénomène » implique de prêter attention à de nombreux détails, par exemple à la stabilité des routes (sur l'Internet, le délai d'acheminement entre deux points peut varier brusquement, si BGP recalcule les routes à ce moment). D'autre part, si la métrique a des options, les deux mesures doivent évidemment utiliser les mêmes options. Et, en raison des variations du phénomène, l'échantillon mesuré doit être assez grand pour que la loi des grands nombres rende ces variations négligeables. La section 2 dit clairement qu'on n'envisage pas de mesurer des singletons (par exemple, pour le délai d'acheminement, le délai d'un seul paquet).

Une fois ces précautions comprises, comment détermine-t-on la conformité d'une mesure à la spécification de la métrique (section 3) ? D'abord, dans la grande majorité des cas, les critères de comparaison vont dépendre de la métrique, et doivent donc être définis spécifiquement pour chaque métrique (l'annexe A fournit un exemple complet). Ensuite, on va comparer deux mesures (qui peuvent avoir été faites dans le même laboratoire, ou bien dans des endroits différents.) La méthode statistique de comparaison recommandée est le test d'Anderson-Darling K. Entre deux mesures d'un même phénomène, on veut un niveau de confiance d'Anderson-Darling K d'au moins 95 %.

Selon l'environnement de test, il va falloir faire attention à des techniques comme la répartition de charge qui peuvent envoyer le trafic par des chemins distincts, une bonne chose pour les utilisateurs, mais une plaie pour les métrologues (cf. RFC 4928).

Compte-tenu de tous les pièges que détaille la section 3 (le gros du RFC), il est nécessaire de documenter soigneusement (RFC 5657 et section 3.5 de notre RFC) l'environnement de test : quelle était la métrique mesurée, quelle était la configuration de test, tous les détails sur le flot de paquets (débit, taille, type, etc).

Si on trouve des différences entre deux mesures de la même métrique, sur le même phénomène, alors il faudra se lancer dans un audit soigneux pour déterminer où était la racine du problème : bogue dans une implémentation ou manque de clarté de la spécification, cette seconde raison étant un bon argument pour ne pas avancer la métrique sur le chemin des normes et pour l'améliorer.

Si vous voulez en savoir plus que le test d'Anderson-Darling, il est documenté dans le rapport technique 81 de l'Université de Washington, par Scholz, F. et M. Stephens, « K-sample Anderson-Darling Tests of fit, for continuous and discrete cases ». Le test Anderson-Darling K est faisable en R : voir le paquetage « adk: Anderson-Darling K-Sample Test and Combinations of Such Tests ». Une implémentation d'Anderson-Darling K en C++ figure dans l'annexe B du RFC.

L'annexe A contient un exemple complet de test d'une métrique, en l'occurrence le délai d'acheminement d'un paquet, tel que défini par le RFC 2679 (le test complet sera documenté dans un futur RFC, actuellement l'Internet-Draft « Test Plan and Results for Advancing RFC 2679 on the Standards Track »). Par exemple, on met le délai d'attente maximum (une option de la métrique) à 2 secondes, on mesure un flot de paquets à qui on impose un délai d'une seconde, grâce à un dispositif qui introduit délibérement des problèmes réseaux (un impairment generator ; ce genre de traitement peut se faire sur un Unix courant), on vérifie qu'ils sont tous comptés, on passe le délai imposé à 3 secondes, et on vérifie qu'on n'obtient plus aucun résultat (la grandeur « délai d'acheminement » est indéfinie si le paquet n'arrive pas avant le délai maximum, RFC 2679, section 3.6).

Ce n'est évidemment pas le seul test. L'annexe A propose également de tester le délai d'acheminement (qui va jusqu'à la réception du dernier bit du paquet, RFC 2679, section 3.4) en faisant varier la taille des paquets, mettons à 100 et 1500 octets. Les implémentations testées doivent mesurer la même augmentation du délai d'acheminement (qui ne dépendra que du temps de transmission supplémentaire, que devra supporter le plus gros des paquets). Autre test, mesurer le délai, puis imposer un retard N, les différentes mesures doivent voir la même augmentation du délai.


Téléchargez le RFC 6576


L'article seul

RFC 6574: Report from the Smart Object Workshop

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : H. Tschofenig (Nokia Siemens Networks), J. Arkko (Ericsson)
Pour information
Première rédaction de cet article le 13 Avril 2012


Traditionnellement, les engins connectés à l'Internet étaient des ordinateurs généralistes, dotés de bonnes capacités de calcul et alimentés en courant électrique à volonté. Est-ce que la famille de protocoles TCP/IP convient toujours, lorsque les machines connectées sont des petits trucs avec un processeur ridicule, et alimentés par une batterie qu'il faut faire durer le plus longtemps possible ? C'était l'objet de l'atelier Interconnecting Smart Objects with the Internet qui s'est tenu à Prague le 25 mars 2011, à l'instigation de l'IAB. Le but était d'explorer cette question, de voir si la connexion à l'Internet de ces « objets malins » était triviale, possible avec quelques adaptations des protocoles ou, pourquoi pas, irréaliste sans des changements radicaux.

L'atelier a rassemblé près de cent participants (liste complète en annexe D), la plupart ayant déjà travaillé sur l'adaptation de TCP/IP à des objets contraints (en mémoire, en alimentation, etc). Ces objets peuvent être des capteurs, des actionneurs, etc. À côté d'eux, même un smartphone est riche en capacités CPU et en énergie électrique.

Rappelons que l'IAB, qui a produit ce RFC, est en charge du travail d'architecture à l'IETF. Ce comité ne s'occupe pas des protocoles individuels (dont le développement, dans les groupes de travail IETF, est piloté par l'IESG) mais du maintien et du développement d'une architecture saine pour l'Internet, avec une insistance sur le travail à long terme.

Une de ces questions à long terme est celle du passage d'un Internet composé uniquement d'ordinateurs à un Internet auquel sont attachés, entre autres, des engins qu'on qualifie du terme générique d'« objets » et qui ont en commun de sévères restrictions matérielles, rendant parfois difficile un attachement normal à l'Internet. Pour les développements liés à ces objets, les gens du marketing ont inventé le terme ridicule d'« Internet des objets » (IoT en anglais pour « Internet of Things »). Mais, même si le terme est grotesque, il y a une vraie question technique : l'Internet est-il accessible à des objets contraints en ressources ?

Connecter ces objets présente souvent des avantages (pour des capteurs, cela permet de les interroger à distance, alors qu'auparavant il fallait qu'un humain se déplace pour les lire), et certains le sont déjà, en utilisant des protocoles privés. Mais la tendance actuelle est de migrer vers les protocoles standard de l'Internet. Cela se reflète entre autres dans les groupes de travail IETF, dont plusieurs planchent sur cet Internet des Trucs : Constrained RESTful Environments (CoRE), IPv6 over Low power WPAN (6LowPAN), Routing Over Low power and Lossy networks (ROLL) ou Light-Weight Implementation Guidance (LWIG).

C'est que le travail d'ingéniérie n'est pas facile : il faut jongler entre des exigences contradictoires, la sécurité, le prix, l'utilisabilité, la protection de la vie privée (ces objets sont souvent liés à notre vie quotidienne), la longévité sous batterie, etc. (Le RFC cite, sur cette questions des exigences contradictoires, l'excellent article « Tussle in Cyberspace: Defining Tomorrow's Internet ».)

L'atelier de l'IAB partait de la constatation que les protocoles actuels de l'Internet, d'IPv4 à IPv6, d'UDP à TCP et jusqu'à bien sûr HTTP, fonctionnent même sur les objets contraints. Il en existe déjà dans la nature. Une première question était « quel bilan tirer de ces premiers déploiements ? ». Une autre était « quels sont les problèmes pas encore résolus ?  ».

En quoi ces objets sont-ils contraints ? Que leur manque-t-il exactement, par rapport à un ordinateur classique ? La section 2 détaille leurs propriétés :

  • Très limités en alimentation électrique, ces engins doivent se mettre en sommeil fréquemment. Cela fait un sérieux changement de paradigme pour les protocoles Internet, habitués aux ordinateurs toujours en marche.
  • Très limités en capacité réseau, ces objets ont souvent moins de 100 kb/s disponibles et parfois seulement 10 ou 20 ! En outre, leur connectivité est fréquemment affectée par des taux de pertes de paquets importants.
  • Très limités en mémoire, les appareils en question ne peuvent pas stocker du code ou des données compliquées. Par exemple, la carte Arduino n'a que 2 ko de RAM et 32 ko de mémoire flash.
  • Liée au problème de la consommation électrique, il y a aussi la faible capacité des processeurs. Pour moins consommer, ils sont souvent lents.
  • Peu ou pas d'interface utilisateur (encore moins qu'un routeur), et donc difficiles à configurer.
  • Enfin, il y a des limitations de taille physique. Si la traditionnelle carte ATX fait 305x244 mm, la CoreExpress, conçue pour l'embarqué, ne fait que 58x65 mm.

La loi de Moore, souvent citée pour relativiser ces limites, ne suffit pas. Les gains qu'elle permet sont souvent utilisés pour réduire coûts et consommation électrique, pas pour augmenter la puissance.

Place à l'atelier lui-même, maintenant. Avec 70 papiers acceptés (la liste complète figure en annexe B du RFC), il n'est pas facile à synthétiser. La section 3 de notre RFC essaie quand même d'indiquer les grands lignes de la réflexion. Quatre grandes questions structuraient l'atelier, les questions d'architecture, les points soulevés par les nœuds dormants, la sécurité et le routage. Commençons par l'architecture, section 3.1.

Première question d'architecture, parle-t-on de connecter ces objets contraints à l'Internet (singulier, et avec une majuscule, car c'est une entité unique comme l'Atlantique ou l'Himalaya) ou bien à des réseaux utilisant TCP/IP, mais qui ne sont pas forcément reliés à l'Internet ? Après tout, les capteurs et actionneurs dans une usine n'ont pas forcément besoin de se connecter à YouTube et, même si le RFC ne le rappelle pas, du point de vue sécurité, il est irresponsable de relier un SCADA à l'Internet. (Le RFC cite un cas moins grave, celui des fontaines devant l'hôtel Bellagio, à Las Vegas, fontaines qui sont électroniquement contrôlées à distance mais qui n'ont pas besoin d'être sur le même réseau que les clients dans leurs chambres, cf. l'exposé de B. Dolin à l'atelier.) Même chose pour les smart grids qui n'ont rien à gagner (et beaucoup à perdre) à être joignables depuis l'Internet. Bref, l'IETF doit-elle séparer clairement le cas des objets connectés à l'Internet et celui des objets reliés à TCP/IP ? Du point de vue purement économique, il est clair qu'il vaut mieux un seul réseau, comme l'a rappelé Cullen Jennings, qui prédisait que tour le monde serait connecté au même Internet, car c'était plus simple et moins coûteux.

Une autre question d'architecture fondamentale est celle des protocoles spécifiques à un domaine d'application. Prenons l'exemple d'une ampoule électrique du futur. Grâce aux normes, on la branche au réseau et elle acquiert une adresse IP (grâce à DHCP ou NDP), trouve un serveur DNS, on peut la pinguer. On peut même imaginer qu'elle ait un serveur HTTP et tout client HTTP peut alors s'y connecter. Mais pour une tâche simple pour laquelle elle est conçue, éclairer, il n'y a pas de norme. Une commande de base « allume-toi » n'est pas normalisée. Comment s'assurer que l'objet, non seulement sera connecté (ping), mais pourra interagir avec son environnement, selon ses capacités ? Les protocoles de couche 3, 4 et même 7 ne suffisent pas. Il va falloir mettre au point des modèles (des classes, dirait-on en programmation objet, dont le nom est bien adapté ici), pour exploiter ces objets « intelligents ».

Un des principes de base de l'Internet, qui est défié par l'arrivée massive des objets connectés, est celui comme quoi l'intelligence est uniquement aux extrêmités et le réseau fournit uniquement un service de base (faire passer les paquets). Avec des objets assez limités en ressources, on pourrait imaginer de revisiter ce principe et de mettre de l'« intelligence » dans le réseau. Parmi les services pour lesquels ce serait un bon endroit, on peut imaginer :

  • La localisation, à savoir indiquer à l'objet où il se trouve. Il ne s'agit pas uniquement des coordonnées GPS mais aussi de l'environnement (« tu es dans un hôpital », « tu es dehors »).
  • Routage fondé sur les noms, où les couches basses sauraient utiliser directement le nom d'une ressource (par exemple « Lampe »), sans passer par des résolutions en identificateurs de plus bas niveau. C'est relativement simple à faire pour un petit réseau local, où un contrôleur peut diffuser à tous « Lampe, allume-toi », et où la lampe se reconnait et s'exécute, mais bien plus complexe dans les grands réseaux. La question n'a pas fait l'objet d'un consensus à l'atelier, loin de là.

Deuxième grande question après l'architecture, le sommeil des objets (section 3.2). Pour économiser l'énergie, beaucoup de ces objets contraints s'endorment souvent. Pour qu'une pile AAA tienne des mois, il faut que l'objet dorme pendant 99, voire 99,9 % du temps. Chaque bit, chaque aller-retour sur le réseau, et chaque milli-seconde d'activité radio (une activité qui consomme beaucoup de courant) est précieux. Or, la plupart des protocoles TCP/IP sont conçus autour de l'idée que les machines sont allumées en permanence, qu'elles peuvent garder un état et répondre à tout moment à un paquet, même non sollicité. Mais, lorsque la simple attente d'un éventuel message consomme du courant, cette idée n'est plus valable : les objets contraints sont plus souvent endormis qu'éveillés, contrairement aux ordinateurs classiques.

Pire, lorsqu'un nœud se réveille après une période de sommeil, son adresse IP a pu être prise par un autre. Il va donc devoir se lancer dans une procédure coûteuse pour obtenir une adresse. Il peut toutefois économiser des efforts s'il met en œuvre les méthodes DNS (Detecting Network Attachment) des RFC 4436 et RFC 6059. Autre piège, si l'objet est mobile, après son réveil, il a pu bouger pour un tout autre endroit.

Pour gérer ces machines « Belle au bois dormant », les solutions envisagées lors de l'atelier étaient :

  • Ne plus considérer comme acquis que les machines sont toujours allumées, lorsqu'on conçoit un protocole. Prévoir une réduction des fonctions du protocole, ou bien des intermédiaires, toujours allumés, qui reçoivent les messages et les stockent (on nomme cela un sleep proxy, comme dans la norme ECMA-393). Autre solution, que les machines communiquent leurs heures de réveil à leurs pairs, comme dans 802.11.
  • Réduire le prix d'une connexion initiale au réseau. Actuellement, l'arrivée sur un nouveau réseau (et un nœud mobile, lorsqu'il se réveille, doit toujours supposer qu'il est sur un nouveau réseau) met en jeu des protocoles coûteux en énergie comme DHCP ou NDP. Peut-on réduire ce coût, surtout pour les machines qui savent qu'elles ne sont pas mobiles ?
  • Réduire le coût des échanges de messages. Préferer les protocoles qui limitent le bla-bla (plus le dialogue est long, plus il faut rester allumé longtemps), les encodages qui ne consomment pas trop d'octets (donc, attention à XML),
  • Penser au coût total en énergie : le RFC cite l'exemple de l'absurdité de la domotique où des ampoules allumées et éteintes par un contrôleur consomment soi-disant moins d'énergie... alors que le bilan global est négatif, à cause de la consommation du contrôleur et du réseau.

Troisième grande question explorée lors de l'atelier, la sécurité (section 3.3). Il faut évidemment la prendre en compte dès le début (RFC 3552 et RFC 4101). L'idéal est que la sécurité soit intégrée dans le début, au lieu d'être une option qu'on oublie d'activer. Mais les défis pour les objets contraints sont énormes. Les calculs qu'impose la cryptographie ne vont pas dans le sens de l'économie d'énergie. D'autre part, l'absence d'une interface utilisateur commode limite sérieusement la configuration qui peut être faite (pas moyen de demander à l'administrateur d'entrer un mot de passe compliqué). Les protocoles de sécurité de l'IETF permettent de gérer tous les cas, mais ils peuvent être trop riches et on peut défendre l'idée de profils, de restrictions ne gardant, par exemple, que certains algorithmes de cryptographie. Le choix ne sera pas évident car il existe des exigences contradictoires. Par exemple, les algorithmes à base de courbes elliptiques (RFC 6090) sont souvent moins consommateurs de ressources matérielles mais sont bien plus encombrés de brevets.

Enfin, les objets communiquants ayant vocation à être partout (à l'usine, au bureau, mais aussi à la maison et, pourquoi pas, dans notre propre corps), les questions de protection de la vie privée sont cruciales. Pas question qu'un sniffer puisse espionner la communication entre le frigo et le supermarché, apprenant ainsi mes habitudes, mes heures de présence, etc. (Dans ce cas, le principal danger pour la vie privée vient probablement du supermarché et, là, le chiffrement des communications n'aide pas.)

Mais l'algorithme de cryptographie n'est pas tout : l'expérience de l'usage de la cryptographie dans l'Internet a montré que les problèmes de gestion des clés cryptographiques étaient souvent bien pires.

Enfin, dernière grande question analysée à Prague, le routage (section 3.4). Les objets communiquants peuvent être trop loin les uns des autres pour se parler directement et il peut être nécessaire de passer par un routeur. Comment les objets et les routeurs vont-ils apprendre les routes disponibles ? Il existe deux approches, mesh-under et route-over. La première n'est pas vraiment du routage, elle consiste à résoudre le problème au niveau 2. Les objets ont ensuite tous l'impression d'être sur le même réseau local. L'autre approche, le route-over, met en place des vrais routeurs IP. Cela implique donc un protocole de routage et celui officiel à l'IETF pour cette tâche est le RPL du RFC 6550 (mais il en existe d'autres, comme le Babel du RFC 6126).

Les protocoles de routage pour les objets contraints font face à de nombreux défis. Par exemple, en filaire classique, les caractéristiques (latence, perte de paquets) sont les mêmes pour toutes les machines attachées au même lien. Ici, c'est par contre loin d'être le cas. Le groupe de travail roll avait été formé pour étudier ce problème (qui avait déjà été abordé par le RFC 3561) et il avait produit plusieurs RFC de débroussaillage et de définition du problème (RFC 5867, RFC 5826, RFC 5673, RFC 5548), avant de définir RPL. Notez que le problème suscite des controverses. Un RFC d'étude comparée des différents protocoles de routage avait été abandonné par le groupe roll (manque de consensus pour avancer). Et, à l'atelier, les polémiques n'ont pas manqué, comme la défense d'AODV par Thomas Clausen dans son article.

Alors, à la fin, peut-on faire une synthèse ? La section 4 s'y essaie. Premier thème décrit, la sécurité. La consommation de temps de processeur (et donc d'électricité) par la cryptographie est une sérieuse limite à la sécurisation des objets communicants. La difficulté de la gestion des clés en est une autre. Notre RFC 6574 recommande d'y travailler sérieusement sur ce dernier point, en donnant comme exemple le mécanisme d'appariement de Bluetooth qui combine harmonieusement sécurité et simplicité. Un groupe de travail de l'IETF avait été formé sur cette question, enroll, mais avait échoué. Peut-être le travail devra-t-il être repris par le nouveau groupe lwig.

Quant à la question des algorithmes cryptographiques « développement durable » (à consommation de ressources réduite), un groupe de recherche de l'IRTF existe, cfrg. Par exemple, le futur SHA-3 a prévu de prendre en compte ce problème (dont l'importance n'était pas perçue pour les algorithmes précédents de la famille).

Assurer l'interopérabilité n'est pas évident lorsque des objets ont une mémoire limitée et ne peuvent pas stocker le code correspondant à tous les algorithmes existants. Le RFC rappelle que plus de cent algorithmes de cryptographie sont définis pour TLS, dont certains sont officiellement déconseillés depuis cinq ou parfois dix ans, mais toujours répandus dans la nature : une mise en œuvre de TLS qui veut être sûre de pouvoir communiquer avec tout le monde a besoin de les connaitre. Les nouveaux algorithmes à consommation d'énergie réduite pourraient encore aggraver ce problème. Faut-il créer un nouvel algorithme, avec les problèmes d'appropriation intellectuelle, avec les difficultés de déploiement, juste pour économiser 20 % de la consommation électrique ? Le RFC laisse entendre que le gain de consommation devrait être nettement plus élevé pour que le jeu en vaille la chandelle.

Un autre thème choisi pour la conclusion est justement celui de la consommation électrique. Il existe une liste de discussion active pour cela, recipe, et l'article de Margaret Wasserman à l'atelier fournit un bon point de départ pour ceux qui veulent s'engager dans ce travail.

Quant à la question du réseau « centré sur le contenu », le RFC conclut que c'est encore bien trop nébuleux et qu'il n'y a pas de travail concret de normalisation à envisager. Il s'agit de recherche pure pour l'instant.

Sur l'architecture, le RFC plaide en faveur d'un futur document de synthèse de l'IAB expliquant comment tous les protocoles Internet marchent ensemble dans ce contexte des objets contraints et communiquants. Le RFC 6272 fournit un bon exemple d'un tel travail.

Dans la lignée de l'exemple de l'ampoule électrique, le RFC insiste aussi sur l'importance de développer des modèles de données (« Une ampoule a deux états, allumé et éteint ») permettant de créer des applications (ici, de contrôle de l'ampoule). La question est « est-ce bien le travail de l'IETF, puisqu'il faut à chaque fois une expertise spécifique d'un domaine ? ».

Pour la partie « découverte » de services ou de machines, le RFC recommande de travailler avec mDNS ou équivalent.

Pour le routage, notre section de conclusion suggérait de travailler entre autres sur la question des « sous-réseaux couvrant plusieurs liens » (RFC 4903). L'essentiel du travail sur le routage pour les objets communiquants continue au sein du groupe roll.

Notez enfin le récent groupe de travail homenet qui travaille sur les problèmes de domotique.

La liste des présentations à l'atelier figure dans l'annexe B. On trouve en ligne la page officielle de l'atelier, les articles présentés (une impressionnante masse de bons documents à lire), les supports des présentations, et les notes prises pendant l'atelier.


Téléchargez le RFC 6574


L'article seul

RFC 6573: The Item and Collection Link Relations

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : M. Amundsen
Pour information
Première rédaction de cet article le 7 Avril 2012


Depuis le RFC 5988, il existe un mécanisme standard pour exprimer les types des liens entre deux ressources sur le Web. Ce très court RFC documente deux types récemment ajoutés, permettant de dire qu'une ressource (une page HTML, un fichier, etc) est membre d'une collection de ressources ou, à l'inverse, qu'une ressource désigne une collection et indique quels sont ses membres.

Ces deux types, collection et item (l'un étant le réciproque de l'autre) sont d'ores et déjà largement utilisées par d'autres normes comme OpenSearch (section 4.5.4.1 de la norme), Maze ou Collection+JSON.

La section 2 définit complètement ces deux relations. item est utilisé dans une ressource qui représente une collection, pour identifier les membres de cette collection. Un exemple en HTML pour un catalogue de produits serait, avec l'attribut rel :


   <h1>Product Group X Listing</h1>
     ...
     <a href="..." rel="item">View Product X001</a>
     <a href="..." rel="item">View Product X002</a>
     ...
 

Ce code exprime le fait que chacun des produits est un élement (item) de la collection qu'est la page qui contieent ce code.

Comme l'indique le RFC 5988, les liens peuvent se représenter autrement qu'en HTML (toutes les ressources Web ne sont pas forcément des pages en HTML), par exemple avec l'en-tête HTTP Link:. On peut donc avoir dans une réponse HTTP :


HTTP/1.1 200 OK
...
Link: <...>; rel="item"; title="View Product X001"
Link: <...>; rel="item"; title="View Product X002"

En section 2.2, on trouve le deuxième type de lien celui qui, en sens inverse du précédent, va d'un élément vers la(les) collection(s) dont il est membre :


   <a href="..." rel="collection">Return to Product Group X</a>

Là aussi, on peut utiliser les en-têtes HTTP :


HTTP/1.1 200 OK
...
Link: <...>; rel="collection"; title="Return to Product Group X"

Les deux types ont été ajoutés au registre IANA.


Téléchargez le RFC 6573


L'article seul

RFC 6570: URI Template

Date de publication du RFC : Mars 2012
Auteur(s) du RFC : J. Gregorio (Google), R. Fielding (Adobe), M. Hadley (MITRE), M. Nottingham (Rackspace), D. Orchard (Salesforce.com)
Chemin des normes
Première rédaction de cet article le 28 Mars 2012


Beaucoup d'applications Web utilisent des URI (RFC 3986) qui peuvent être décrits par un gabarit (template), avec des variables qui seront incarnées pour produire l'URI final. Ce RFC, issu d'une coopération entre l'IETF et le W3C normalise un langage (déjà largement déployé) pour ces gabarits.

La section 1.1 du RFC fournit quelques exemples d'URI obéissant à un gabarit. Par exemple, des pages personnelles identifiées par le tilde :

http://example.com/~fred/
http://example.com/~mark/

ou des entrées d'un dictionaire :

http://example.com/dictionary/c/cat
http://example.com/dictionary/d/dog

ou encore un moteur de recherche :

http://example.com/search?q=cat&lang=en
http://example.com/search?q=chien&lang=fr

À chaque fois, le patron de conception sous-jacent est assez clair. Le langage décrit dans ce RFC 6570 permet d'abstraire ce patron dans un gabarit d'URI. Les trois exemples cités plus haut pourront être décrits :

http://example.com/~{username}/

http://example.com/dictionary/{term:1}/{term}

http://example.com/search{?q,lang}

Cela permet d'abstraire un URI, en montrant clairement au lecteur le processus de construction. Cela contribue donc à la création de beaux URL, qui ne sont pas simplement des identificateurs opaques, mais qui peuvent être compris par l'utilisateur du Web.

En dehors de l'intérêt intellectuel, quelle est l'utilité de ce système ? Il permet notamment la création automatique d'URI, à partir de gabarits et de valeurs pour les variables (comme la variable term dans le deuxième exemple ci-dessus). Les protocoles fondés sur REST en seront ravis. Ainsi, le gabarit http://www.example.com/foo{?query,number} combiné avec les variables {query: "mycelium", number: 100} va donner http://www.example.com/foo?query=mycelium&number=100. Si query n'était pas défini, cela serait simplement http://www.example.com/foo?number=100.

Pour prendre des exemples réels, on peut décrire les URL d'OpenStreetMap comme tirés du gabarit http://www.openstreetmap.org/?{lon,lat} et ceux de Wikipédia comme faits à partir de http://fr.wikipedia.org/wiki/{topic}.

La section 1.2 explique qu'il existe en fait plusieurs niveaux pour le langage de description de gabarits. Une mise en œuvre donnée s'arrête à un certain niveau, les premiers étant les plus simples. Le niveau 1 fournit simplement l'expansion des variables (qui sont placées entre accolades), avec échappement. Si var vaut "Bonjour le monde", l'expansion de {var} sera Bonjour%20le%20monde.

Le niveau 2 ajoute un opérateur + pour les variables pouvant contenir des caractères spéciaux, et le # pour les identificateurs de fragment. Si path vaut "/foo/bar", {path} est expansé en %2Ffoo%2Fbar alors que {+path} donnera /foo/bar. Et avec la variable var valant "Bonjour le monde", l'expansion de {#var} sera #Bonjour%20le%20monde permettant de construire des URI avec un identificateur pointant vers un point précis du document. Par exemple, les URL des Internet-Drafts dans la file d'attente de l'éditeur des RFC ont le gabarit http://www.rfc-editor.org/queue2.html{#draftname} avec, par exemple, draftname égal draft-ietf-lisp.

Au niveau 3, cela devient bien plus riche : on a plusieurs variables dans une expression (le gabarit map?{x,y} devient l'URI map?1024,768 si x=1024 et y=768). Et on gagne surtout les paramètres mutiples (séparés par &) si utilisées dans les formulaires Web : le gabarit {?x,y} devient ?x=1024&y=768.

Enfin, le niveau 4 ajoute des modificateurs après le nom de la variable. Par exemple, : permet d'indiquer un nombre limité de caractères (comme dans le term:1 que j'ai utilisé au début, qui indique la première lettre). Et le * indique une variable composite (une liste ou un dictionnaire) qui doit être elle-même expansée. Si la variable couleurs vaut la liste {rouge, bleu, vert}, le gabarit (de niveau 1) {couleurs} donnera rouge,bleu,vert alors que la gabarit de niveau 4 {?couleurs*} vaudra ?couleurs=rouge&couleurs=bleu&couleurs=vert.

Des mécanismes similaires à ces garabits existent dans d'autres langages comme OpenSearch ou WSDL. Par exemple, le gabarit décrivant les URL du moteur de recherche de mon blog a la forme http://www.bortzmeyer.org/search{?pattern} et, dans dans sa description OpenSearch, on trouve la même information (quoique structurée différemment).

Comme l'explique la section 1.3, cette nouvelle norme vise à unifier le langage de description de gabarits entre les langages, tout en restant compatible avec les anciens systèmes. Normalement, la syntaxe des gabarits d'URI est triviale à analyser, tout en fournissant la puissance expressive nécessaire. Il s'agit non seulement de générer des URI à partir d'un patron, mais aussi de pouvoir capturer l'essence d'un URI, en exprimant clairement comment il est construit.

La section 2 décrit rigoureusement la syntaxe. En théorie, un analyseur qui ne gère que le niveau 1 est acceptable. Toutefois, le RFC recommande que tous les analyseurs comprennent la syntaxe de tous les niveaux (même s'ils ne savent pas faire l'expansion), ne serait-ce que pour produire des messages d'erreurs clairs (« This feature is only for Level 3 engines and I'm a poor Level 2 program. » .

Cette section contient donc la liste complète des caractères qui ont une signification spéciale pour le langage de gabarits, comme +, ? ou &, ainsi que de ceux qui sont réservés pour les futures extensions (comme = ou @). En revanche, $ et les parenthèses sont exprèssement laissés libres pour d'autres langages qui voudraient décrire une part de l'URI.

Ensuite, la section 3 se consacre aux détails du processus d'expansion qui, partant d'un gabarit et d'un ensemble de valeurs, va produire un URI. Notez qu'une variable qui n'a pas de valeur ne donne pas un 0 ou un N/A ou quoi que ce soit de ce genre. Elle n'est pas expansée. Donc, le gabarit {?x,y} avec x valant 3 et y n'étant pas défini, devient ?x=3 et pas ?x=3&y=NULL. Si x n'était pas défini non plus, le résultat serait une chaîne vide (sans même le point d'interrogation).

Est-ce que ces gabarits peuvent poser des problèmes de sécurité ? La section 4 regarde cette question et conclus que cela dépend de qui fournit le gabarit, qui fournit les variables, et comment va être utilisé l'URI résultant (aujourd'hui, les mises en œuvre existantes les utilisent dans des contextes très variés). Par exemple, des variables contenant du code JavaScript peuvent être dangereuses si l'URI résultant est traité par ce langage. Des attaques de type XSS sont donc parfaitement possibles si le programmeur ne fait pas attention.

Pour les programmeurs, l'annexe A contient un ensemble de recommandations sur la mise en œuvre de ce RFC, ainsi qu'un algorithme possible pour cette mise en œuvre. Il existe plusieurs mises en œuvre de ce RFC. Malheureusement, toutes celles que j'ai essayées semblent limitées au niveau 1 et ne le disent pas clairement.

Le code Python en http://code.google.com/p/uri-templates/ (niveau 1 et un bout du niveau 2) :

import uritemplate
import simplejson
import sys

vars = {"foo": "bar/"}

def test_print(template):
    actual = uritemplate.expand(template, vars)
    print actual

test_print("http://www.example.org/thing/{foo}")
test_print("http://www.example.org/thing/{+foo}")

On obtient :

http://www.example.org/thing/bar%2F
http://www.example.org/thing/bar/

Avec le module Perl URI::Template (niveau 1), on peut écrire :

use URI::Template;
my $template = URI::Template->new( 'http://example.com/{foo}' );
my $uri      = $template->process( foo => 'Hello World/' );
print $uri, "\n";

Le code Haskell en http://hackage.haskell.org/cgi-bin/hackage-scripts/package/uri-template (niveau 1 seulement) écrit ainsi :

module Main(main) where

import Network.URI.Template

testEnv :: TemplateEnv
testEnv =
  addToEnv "foo" "Hello World/" $
    addToEnv "x" "1024" $
     addToEnv "y" "768" $
       newEnv

main :: IO ()
main = do
  putStrLn (expand testEnv "http://example.org/{foo}")
  return ()

Donne :

% runhaskell Test.hs
http://example.org/Hello%20World%2f

Téléchargez le RFC 6570


L'article seul

RFC 6569: Guidelines for Development of an Audio Codec Within the IETF

Date de publication du RFC : Mars 2012
Auteur(s) du RFC : JM. Valin (Mozilla), S. Borilin (SPIRIT DSP), K. Vos, C. Montgomery (Xiph.Org Foundation), R. Chen (Broadcom Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF codec
Première rédaction de cet article le 27 Mars 2012


Constatant l'absence d'un codec entièrement libre (pas plombé par des brevets, pas contrôlé par une société unique, implémentable en logiciel libre), l'IETF s'est lancée dans la spécification d'un codec satisfaisant. Le RFC 6366 donnait le cahier des charges technique du futur codec (le produit final) et ce nouveau RFC donne les considérations portant sur le processus de développement (processus déjà bien entamé) : méthodologie d'évaluation des propositions, mécanisme de vérification de la compatibilité des implémentations, questions de propriété intellectuelle. Une tâche difficile, accomplie dans une ambiance pas toujours sereine, les questions du multimédia étant toujours délicates.

Le développement d'un nouveau codec est une tâche d'ampleur, compte-tenu des exigences très strictes du RFC 6366 et du fait que le marché est déjà encombré de codecs complètement fermés, ou bien à moitié libres. L'IETF n'avait pas imposé que le codec libre soit entièrement nouveau : la sélection et/ou l'adaptation d'un codec existant sont des plans possibles. La section 2 du RFC résume le processus. Au moment où sort ce RFC, une partie des étapes a déjà été franchie. Les principales sont :

  • Documenter les exigences techniques (fait dans le RFC 6366, un document à lire, notamment pour se rappeler que l'économie de capacité réseau par la compression n'est qu'un des critères de qualité technique pour un codec, d'autres, comme la latence sont aussi importants),
  • Proposer des candidats répondant à ces exigences (voir par exemple l' Internet-Draft Definition of the Opus Audio Codec),
  • Compte-tenu de l'importance de l'appropriation intellectuelle dans ce secteur, pourri de brevets du sol au plafond, surveiller en permanence les divulgations de brevets, imposées par le RFC 3979, mais pas toujours respectées. Il est particulièrement important que ces divulgations soient faites à temps puisqu'elles peuvent sérieusement influencer les choix du groupe de travail.
  • Identifier forces et faiblesses de chaque proposition,
  • Créer le codec préféré, qui pourra incorporer des bouts des autres propositions,
  • Développer l'implémentation de référence et les mécanismes de tests permettant de s'assurer que toutes les mises en œuvre sont compatibles. (Ces mécanismes de test étaient un des points suscitant le plus de débats.)

Comment s'assurer, tout au long du développement, que le codec sera de qualité suffisante, pour ne pas avoir de mauvaise surprise à la fin du projet ? Il faudra tester le logiciel au fur et à mesure (section 3) en utilisant des méthodes comme PESQ (norme UIT P.862) et PEAQ (UIT BS.1387). Pour des changements plus fondamentaux, il faudra utiliser les méthodologies d'évaluation subjective comme MUSHRA (UIT BS.1534). Et, comme l'IETF travaille depuis toujours dans un environnement ouvert, il faudra bien sûr impliquer toute la communauté Internet dans ses essais (le code du codec Opus est donc librement accessible en http://git.xiph.org/?p=opus.git). C'est d'autant plus important que l'IETF n'a pas de « laboratoires de test » propres et que tous les tests devront être faits à l'extérieur (une raison de plus pour que l'implémentation de référence soit publiquement disponible).

La section 4 du RFC revient sur les détails de la spécification et sert de guide aux auteurs du futur RFC. Elle précise notamment ce que devrait imposer la spécification et ce qui devrait être laissé aux décisions des programmeurs. D'abord, la décision est prise que l'implémentation de référence aura le pas sur le texte de la spécification, en cas de désaccord. C'est inhabituel à l'IETF, où la règle est en général l'inverse, pour éviter que les particularités d'une implémentation ne figent la norme. Mais le monde des codecs est très complexe et la spécification complète et parfaite un art difficile. Au moins, en décrétant que « le code fait la loi », on est sûr d'avoir une référence précise en cas de litige.

Le principe général sera d'essayer de limiter les obligations dans la norme, donc de ne pas abuser des MUST du RFC 2119. En pratique, cela veut dire que seul le décodeur du flux audio aura besoin d'être rigoureusement défini, les encodeurs pourront s'améliorer avec le temps et faire des choix radicalement différents.

Avoir un programme comme description faisant autorité présente plusieurs risques. L'un d'eux est de « sur-spécification » : faudra-t-il qu'une implémentation compatible donne le même résultat, au bit près, que l'implémentation de référence ? Cela rendrait très difficile le travail des programmeurs pour certaines architectures (le couple CPU/DSP ne permet pas forcément de produire un résultat au bit près, en tout cas pas en gardant des performances maximales). Le principe est donc qu'il n'est pas nécessaire de faire exactement comme le programme de référence, mais de faire quelque chose qui n'est soit pas distinguable à l'oreille.

La section 5 est consacrée au problème douloureux mais, dans le secteur du multimédia, indispensable, de la propriété intellectuelle. Les effets néfastes de celle-ci sur la mise en œuvre et le déploiement des codecs audios sont bien connus. Par exemple, les coûts de licence des brevets éliminent les petits acteurs, qui sont souvent à l'origine de l'innovation. En outre, même si les conditions de la licence sont raisonnables financièrement, elles sont souvent incompatibles avec le logiciel libre (par exemple, exiger une licence pour la distribution, même si la licence est gratuite, empêche l'intégration du logiciel dans un logiciel libre, qui ne met aucune restriction à la distribution).

Bref, libre, c'est mieux que contraint. Des tas de codecs tout à fait valables techniquement posent des problèmes légaux, qui limitent leur déploiement. L'IETF rappelle donc dans ce RFC sa préférence pour des techniques non plombées par la propriété intellectuelle. Le problème est difficile à résoudre car à peu près tout a été breveté (les organismes de dépôt des brevets ne font aucun effort pour refuser les brevets futiles). Même si l'IETF adopte un codec qui semble non breveté, rien ne garantit qu'il ne sera pas frappé soudainement par un brevet sous-marin, un brevet auquel son détenteur ne donne aucune publicité, attendant qu'il soit déployé pour réclamer de l'argent.

Compte-tenu des brevets futiles (qui couvrent à peu près tous les algorithmes possibles et qu'on ne peut invalider que par un long et incertain procès), compte-tenu de l'état de l'art en matière de codec, compte-tenu du fait qu'une technologie peut être brevetée dans certains pays et pas d'autres, l'IETF ne promet donc pas de normaliser un codec complètement libre, ce qui serait une mission impossible (à part peut-être en se limitat à de très vieux codecs, conçus il y a tellement longtemps que tous les brevets ont forcément expiré). Mais elle promet de chercher sérieusement (même si les codecs libres ont de moins bonnes performances techniques) et, dans le pire des cas, de préférer les codecs où les licences des brevets sont gratuites (RF, pour royalty-free). Rappelez-vous toutefois que le plus gros problème pour obtenir une licence n'est pas forcément l'argent, cela peut être le processus bureaucratique de longues négociations avec un bataillon d'avocats qui ont beaucoup de temps libre et vous font lanterner. Il y a des licences gratuites qui coûtent très cher en temps passé !

Cela suppose évidemment que l'IETF soit au courant des brevets existants. Les participants à l'IETF doivent l'informer des brevets qu'ils connaissent (RFC 3979, section 6). Mais cette règle a déjà été violée. Par exemple, dans le cas du groupe de travail Codec, Huawei n'a publié son brevet US 8,010,351 que bien tard, en affirmant qu'il était dans le portefeuille d'une entreprise récemment acquise par Huawei.

D'autres SDO travaillent sur des codecs. Comment l'IETF doit-elle gérer ses relations avec ces organisations (section 6) ? On trouve dans la liste l'UIT (notamment le Study Group 16), le groupe MPEG de l'ISO, ETSI, 3GPP... L'IETF a déjà pris position nettement contre la concurrence des SDO et le développement non coordonné de protocoles, dans le RFC 5704. Ce RFC pose comme principe que, pour chaque protocole ou format, une et une seule SDO doit être responsable. Mais ce n'est pas un problème ici. Soit le groupe de travail codec approuve un codec existant, géré par une autre SDO et celle-ci continuera comme avant, l'IETF aura juste dit « le codec préféré de l'IETF est le codec XXX ». Soit l'IETF développe un nouveau codec (éventuellement dérivé, mais différent, d'un codec existant) et il n'y aura alors pas de concurrence. Les règles du RFC 5704 découragent le concurrence pour un même format ou protocole, pas pour une même catégorie (deux organisations peuvent travailler sur deux codecs différents, même si ces deux codecs visent le même « marché »).

L'IETF appelle bien sûr les experts en codecs audio des autres SDO à donner leur avis sur son travail mais considère que ce n'est pas indispensable : le groupe codec rassemble d'ores et déjà suffisamment de compétences. Cette participation éventuelle des autres SDO peut prendre la forme de contributions individuelles (un expert peut être membre à la fois du SG16 de l'UIT et du groupe codec de l'IETF), ou par le mécanisme plus formelle des liaisons. En tout cas, il existe des choses utiles chez les autres SDO (par exemple dans les mécanismes de test), comme documenté dans le RFC 3356.

Je l'ai indiqué, le groupe de travail codec a travaillé sous forte pression. Parmi les trolls des débats, je me souviens de la proposition que le problème du coût des licences soit relativisé, car un codec techniquement supérieur fait économiser de la capacité réseau (meilleure compression) et donc justifie de payer une licence...

Actuellement, dans la catégorie « nouveaux codecs », le groupe de travail n'a qu'un seul candidat, Opus (autrefois nommé Harmony). Si vous vous intéressez aux tests pratiques de ce codec, voir le document Summary of Opus listening test results

.

Téléchargez le RFC 6569


L'article seul

RFC 6568: Design and Application Spaces for 6LoWPANs

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : E. Kim (ETRI), D. Kaspar (Simula Research Laboratory), N. Chevrollier (TNO), JP. Vasseur (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6lowpan
Première rédaction de cet article le 1 Mai 2012


Vous ne connaissez pas encore le terme de LowPAN ? Ce n'est pas grave, c'est encore assez rare. Un LowPAN est un Low-Power Wireless Personal Area Network. En gros, c'est un ensemble de petites machines (très petites : pas des ordinateurs), disposant de peu de puissance électrique, connectées souvent sans fil, et cherchant à communiquer. Le groupe de travail IETF 6lowpan établit des normes de communication pour ces LowPAN, en utilisant IPv6 (d'où le 6 au début de son nom). Ce document est son quatrième RFC. Il explique les principes de base de son travail, à travers des scénarios d'utilisation des LowPAN.

Un LowPAN typique va être, dans une exploitation agricole, l'ensemble des capteurs qui mesurent l'humidité, et des actionneurs qui déclenchent l'arrosage. La section 1 explique les douleurs du LowPAN : machines ayant peu de ressources (processeur, mémoire, courant), et connectées par des liens lents et sujets aux parasites et aux coupures (WiFi, CPL). En général, on veut en prime que ces machines soient peu chères. Résultat :

  • Certaines machines du LowPAN peuvent n'avoir qu'un CPU 8-bits de 10 MHz. (Des plus chanceuses auront des CPU ARM de 32 bits à 50 MHz.)
  • Certaines n'auront que quelques kilo-octets de RAM et quelques dizaines de kilo-octets de ROM. Plus élaboré, le IMote a 64 ko de RAM et une Flash de 512 ko.
  • Fonctionnant souvent sur batterie, ces machines devront se limiter à une consommation de 10 à 30 mA pour la radio, limitant la puissance à 3 dBm et donc la portée à entre 30 et 100 mètres.
  • La capacité de ces liens radio peut être entre 20 et 250 kb/s.

Bref, on est très loin des ordinateurs portables ou même des smartphones. Et c'est pourtant dans ces machines qu'il va falloir faire tenir le code réseau. Deux bonnes lectures sur ces environnements si différents des machines sur lesquelles l'Internet a commencé : le RFC 4919 décrit plus en détail le monde des LowPAN, le RFC 4944 normalise l'utilisation d'IPv6 sur IEEE 802.15.4.

Il existe en fait beaucoup de LowPAN différents. Suivant le document «  The Design Space of Wireless Sensor Networks », la section 2 du RFC explique les axes sur lesquels se différencient les LowPAN : déploiement conçu dès le début ou bien incrémental, taille du réseau (10 machines ou 1000 ?), connectivité permanente ou intermittente (ce qui est courant lorsque les machines se déplacent), etc.

Bien, maintenant, assez de précautions, place au cœur du RFC, la section 3. Elle expose une partie des scénarios d'usage des LowPAN. Par exemple, en section 3.1, figure un usage souvent cité, la surveillance de bâtiments industriels. L'idée est que les capteurs dispersés un peu partout dans les bâtiments deviennent communiquants. Au lieu d'être relevés manuellement par un humain faisant sa ronde, ils transmettront d'eux-mêmes les résultats des mesures. De très nombreuses mesures peuvent être envisagées, comme les vibrations d'une machine (trop intenses, elles indiquent un problème) ou la température dans les entrepôts (attention à conserver la chaîne du froid). Les communications sans-fil sont ici cruciales car certaines parties de l'usine peuvent être difficiles à atteindre pour les câbles.

Comme exemple précis de ce type de surveillance, le RFC cite les salles de stockage d'un hôpital. Les globules rouges doivent être stockés entre 2 et 6°, les plaquettes entre 20 et 24°, et le plasma à -18°. Les capteurs de température sont disposés tous les 25 mètres environ, chaque emballage a une étiquette et des nœuds 6LowPAN sont placés dans les palettes. Par rapport aux axes de classification cités plus haut, on a un cas de déploiement planifié, avec un réseau de taille moyenne mais très dense, et peu de déplacements. Le débit attendu est faible mais les données peuvent être urgentes (alerte de réchauffement, par exemple). Les exigences de sécurité sont élevées. 6LowPAN peut-il convenir ? Oui, analyse cette section.

Autre cas, celui de la surveillance d'un bâtiment, pour veiller à son intégrité (section 3.2). Par exemple, un pont est construit et est truffé de capteurs et de machines LowPAN qui relèvent les capteurs et transmettent à un contrôleur. Le RFC part d'un pont de 1 000 m de long, avec 10 piliers. Chaque pilier a 5 capteurs pour mesurer le niveau de l'eau sont le pont et 5 autres qui mesurent les vibrations. Les machines LowPAN ne sont pas gênées par les murs du bâtiment, comme dans l'exemple précédent, et peuvent se voir à 100 m de distance. Tout est placé manuellement (attention à ne pas avoir un pilier dans la LoS) et ne bouge pas.

Le réseau est cette fois de petite taille, très statique. Mais sa sécurité est vitale. Dans ce cas simple, 6LowPAN convient bien (il faut juste faire attention aux placements des engins sur les piliers).

Pas d'article ou de document sur les LowPAN sans l'inévitable bla-bla sur la domotique et ses promesses d'un monde merveilleux où le réfrigérateur détectera la fin proche du stock de bières et en commandera d'autres. C'est le rôle ici de la section 3.3. Après la santé et les transports, où des vies humaines sont en jeu, cette section se penche sur le confort de l'occidental rose moyen, qui veut que sa maison high-tech s'occupe de tout pendant qu'il regarde le match de foot à la télé.

Il y a beaucoup de choses à mesurer dans une maison, la température, l'humidité, l'état des portes (ouvert ou fermé), la vidéo-surveillance (pendant qu'on est dans les délires de mauvaise science-fiction, transformons la maison en bunker avec caméra braquée sur les quartiers sensibles). En combinant avec l'idée de « Smart Grid » (réseau de distribution électrique doté de capacités de mesure et de transmission de l'information), on peut aussi imaginer de connecter ces informations avec celle du réseau électrique.

Du point de vue technique, les murs de la maison feront souvent obstacle aux communications sans fil. Le réseau devra donc permettre le routage, pour le cas où la machine qu'on veut joindre n'est pas directement visible (« Multi-hop routing »). Les fonctions de ce réseau de gadgets ne sont pas vitales, cette fois. Par contre, l'ergonomie est cruciale, le réseau devra être très simple à administrer.

Autre scénario d'usage, en section 3.4, l'assistance médicale. L'idée est de mettre les capteurs sur et dans le patient, de manière à pouvoir surveiller son état à tout moment. Pour une personne âgée à la maison, on peut imaginer quelques capteurs portés à même le corps et qui mesurent des choses commes les battements cardiaques, et d'autres capteurs dans la maison, captant les mouvements, par exemple pour pouvoir donner l'alerte en cas de chute. Les enjeux de sécurité, notamment de protection de la vie privée, sont très importants. Si le LowPAN est ici de petite taille, et que la mobilité est limitée, les contraintes de bon fonctionnement sont essentielles, puisqu'une vie humaine peut être en jeu.

Un scénario dans un univers plus technique est celui de l'automobile (section 3.5). Les nœuds LowPAN peuvent être inclus dans la route au moment de sa construction et surveiller les véhicules qui passent. Cela pose un sacré problème de durée de vie puisque les nœuds vont devoir durer autant que la route (typiquement, dix ans, avant la première réfection sérieuse qui permettra de les changer). Malgré cela, avec le temps, la densité des capteurs diminuera, au fur et à mesure des pannes. Les machines LowPAN de la route seront nombreuses mais statiques, celles des véhicules peu nombreuses mais très mobiles.

Enfin, le dernier exemple est un peu plus vert, puisqu'il concerne l'agriculture (section 3.6), celle qui, selon Jared Diamond, est à la base de la force des empires. L'idée est de mesurer à distance, via de nombreux capteurs, l'humidité, la température et l'état du sol, de manière à appliquer l'irrigation ou les pesticides au bon moment. Le RFC prend l'exemple d'une vigne de bonne taille (dans les huit hectares) où 50 à 100 machines de contrôle piloteront des centaines de capteurs. La principale difficulté, pour ces derniers, sera de résister à des conditions hostiles dehors (humidité, poussière, hommes et machines qui passent en permanence et font courir des gros risques aux fragiles capteurs), etc. Heureusement, les exigences de sécurité sont cette fois bien plus basses.

En parlant de sécurité, la section 4 y est entièrement consacrée. Elle rappelle que les machines d'un LowPAN sont souvent exposées dehors, et donc physiquement accessibles à un éventuel attaquant. Les méthodes de sécurisation doivent tenir compte de cela. La communication entre les machines du LowPAN est souvent par radio, médium qui n'offre aucune sécurité, permettant à l'attaquant de capter tout le trafic, voire d'injecter de fausses données. La cryptographie devient alors nécessaire.

Mais les machines d'un LowPAN ont des ressources, notamment d'énergie, très limitées. Elles sont donc vulnérables aux attaques par déni de service : des requêtes répétées et hop, la batterie est à plat. À cause de cela, les techniques de sécurité adoptées doivent être légères et ne pas abuser des ressources très limitées de ces petits engins. Par exemple, IPsec est probablement exagéré pour ces environnements, en raison des calculs qu'il entraîne. Cela doit évidemment s'adapter à l'usage envisagé : le nœud LowPAN qui allume une lampe n'a pas les mêmes contraintes de sécurité que celui qui contrôle un stimulateur cardiaque.


Téléchargez le RFC 6568


L'article seul

RFC 6564: An uniform format for IPv6 extension headers

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : S. Krishnan (Ericsson), j h. woodyatt (Apple), E. Kline (Google), J. Hoagland (Symantec), M. Bhatia (Alcatel-Lucent)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 10 Avril 2012


IPv6 permet l'insertion, entre l'en-tête de taille fixe du paquet, et les données de la couche 4, d'un ou plusieurs en-têtes d'extensions, qui modifient le comportement du paquet. L'analyse de ces en-têtes d'extension par un programme a toujours été difficile car ils n'ont pas un format cohérent. Ce RFC résoud le problème en décrétant que, au moins pour les futurs en-têtes, ils devront suivre un format identique, permettant de les sauter sans même en comprendre le contenu.

Ces en-têtes d'extension sont normalisés dans la section 4 du RFC 2460. La plupart suivent le schéma « un octet pour indiquer le type de l'en-tête suivant, un octet pour indiquer la longueur de cet en-tête, puis les données » mais pas tous (notamment, l'en-tête de fragmentation a une syntaxe différente). Si on veut écrire un programme d'analyse des paquets IPv6, on doit donc connaître tous les types d'en-tête (il n'y en a, après tout, pas beaucoup) et traiter chacun spécialement. Mais cela ne résoud pas le problème des futurs en-têtes : si un nouvel en-tête est créé (comme cela avait été le cas dans le RFC 5533), et qu'il commence à apparaître sur le réseau, les programmes d'analyse vont souffrir.

Outre les programmes d'analyse, on peut citer d'autres logiciels qui souhaitent regarder à l'intérieur des paquets, y compris avant que le paquet n'atteigne sa destination (section 1 du RFC). Par exemple les pare-feux veulent accéder à la couche transport, et ils doivent le faire à la vitesse du réseau physique (si on a un Ethernet 1 Gb/s, on veut que les paquets soient analysés au même rythme), ce qui implique le recours à des circuits électroniques relativement simples (les ASIC) qui n'ont pas la possibilité de faire tourner du code arbitrairement complexe. Or, aujourd'hui, tout nouvel en-tête IPv6 est à peu près sûr d'invalider ces pare-feux.

Ne peut-on pas s'en tirer en disant qu'il vaut mieux éviter de définir de nouveaux en-têtes d'extension ? C'est l'option que rappelle la section 3, qui note que l'en-tête Destination Options (section 4.6 du RFC 2460) est déjà très général : il permet d'inclure plusieurs options différentes, chacune identifiée par son type et encodée sous forme TLV. Le RFC recommande donc que les concepteurs de nouvelles idées pour IPv6 réutilisent l'en-tête Destination Options autant que possible. Au cas où un concepteur de protocole décide de créer un nouvel en-tête, il doit désormais expliquer en détail pourquoi l'en-tête Destination Options ne convient pas à son but.

Notez que l'en-tête Destination Options, comme son nom l'indique, ne doit normalement être traité que par la machine de destination (les routeurs, notamment, n'ont pas besoin de le gérer ou de le connaître, sauf à des fins de statistique). Si on veut transporter des options qui sont analysées par les routeurs, on a l'en-tête Hop-by-hop Options. En pratique, il n'est pas du tout évident que ce dernier fonctionne : comme chaque routeur du trajet doit en tenir compte, il ouvre une voie d'attaque possible et il semble que bien des routeurs l'ignorent complètement, voire jettent sans autre forme de procès les paquets qui le contiennent. Quoi qu'il en soit, notre RFC 6564 précise qu'il ne faut pas créer de nouveaux en-têtes ayant cette sémantique « examen par chaque routeur ». Non seulement la création d'en-têtes est déconseillée, mais elle ne doit se faire qu'avec la sémantique « examen par la destination seulement ».

Bien, maintenant qu'on a sérieusement refroidi les concepteurs de protocole qui auraient pensé à créer un nouvel en-tête, la section 4 fixe les règles à suivre au cas où on ne serait pas encore découragé. Les éventuels nouveaux en-têtes devront désormais tous suivre le modèle de la plupart des en-têtes existants et commencer par un octet indiquant l'en-tête suivant (typiquement, cela sera les données de la couche Transport, les valeurs possibles sont dans un registre), puis un octet indiquant la longueur de l'en-tête. Cela devrait rendre un peu plus facile l'analyse des futurs en-têtes, s'il y en a de créés.

Rappelez-vous que cela n'affecte que les futurs en-têtes. Pour analyser les existants (notamment l'en-tête Fragment qui ne suit pas ce schéma, cf. section 5), il faut garder le code existant. La section 6 rappele d'ailleurs que le traitement des en-têtes reste un problème pas complètement résolu pour les équipements intermédiaires, par exemple parce qu'il peut y avoir plusieurs en-têtes, chaînés, parce que leur ordre est important, et parce que le traitement des en-têtes peut influer celui de la charge utile. Personnellement, je pense que la première mise en œuvre d'IPv6 qui essaiera d'utiliser vraiment les en-têtes aura de vilaines surprises... Cela sera encore pire avec un nouvel en-tête, qui ne fait pas partie des anciens.

Notez aussi que tout le problème traité par ce RFC a une faible importance pratique : on ne trouve quasiment pas d'en-têtes d'extension dans les paquets IPv6 qui circulent aujourd'hui.

Donc, désormais, une implémentation d'analyse d'IPv6 (comme la mienne, que j'ai eu la flemme de modifier) peut adopter la stratégie suivante :

  • Si c'est un en-tête connu, le traiter selon sa spécification.
  • Si c'est un en-tête inconnu et que le next header est un en-tête connu ou bien un protocole de transport connu, sauter l'en-tête inconnu (en utilisant le second octet, qui indique la taille). C'est là la nouveauté de notre RFC 6564.
  • Si c'est un en-tête inconnu et que le suivant n'est pas connu non plus, le problème reste ouvert (tenter de suivre la chaîne ? C'est dangereux car on peut se retrouver au milieu d'un protocole de transport inconnu, pour lesquels les règles de notre RFC ne s'appliquent pas) et n'est pas modifié par notre RFC.

Téléchargez le RFC 6564


L'article seul

RFC 6563: Moving A6 to Historic Status

Date de publication du RFC : Mars 2012
Auteur(s) du RFC : S. Jiang (Huawei), D. Conrad (Cloudflare), B. Carpenter (Univ. of Auckland)
Pour information
Première rédaction de cet article le 13 Mars 2012


Un peu de rangement dans le DNS : en 2000, un nouveau type d'enregistrement DNS, le A6, avait été créé pour gérer plus facilement les adresses IPv6 dans le DNS. N'ayant finalement pas marché comme espéré, il vient d'être officiellement abandonné. Le RFC 2874, qui le normalisait, devient « intérêt historique seulement ».

Le type officiel pour représenter les adresses IPv6 dans le DNS était le AAAA, introduit par le RFC 1886 (aujourd'hui RFC 3596). Très proche du type A d'IPv4, il n'offrait pas de services particuliers, par exemple pour gérer la rénumérotation d'un réseau. Si on avait dans son fichier de zone :

www    IN   AAAA   2001:db8:33::1
mail   IN   AAAA   2001:db8:33::fada

et qu'on passe du réseau 2001:db8:33::/48 au 2001:db8:bad::/48, il fallait faire un rechercher/remplacer pour changer toutes les adresses. Le type A6, du RFC 2874, fournissait un système plus souple, découplant le préfixe et l'adresse.

Évidemment, le fait d'avoir deux types pour les adresses IPv6 a entraîné pas mal de confusion (section 2.5). Il est même possible que cela ait contribué au retard du déploiement d'IPv6. En 2002, les RFC 3363 et RFC 3364 critiquaient A6 et il était reclassé « expérimental ». Cela n'a apparemment pas suffit à éclaircir les choses et notre RFC 6563 met aujourd'hui A6 comme « d'intérêt historique seulement », ce qui devrait enlever toute ambiguité. Le seul type pour représenter les adresses IP dans le DNS est donc AAAA.

Mais que reprochait-on à A6, finalement ? La section 2 de ce RFC résume les principaux problèmes (le RFC 3363 donne davantage de détails) :

  • Latence accrue au moment de la résolution de noms (puisque A6 implique plusieurs requêtes DNS non-parallélisables, et sur des serveurs différents),
  • Probabilité d'échec plus élevée (il suffit qu'une des sous-requêtes de la chaîne échoue pour que la résolution soit impossible),
  • Difficultés associées au franchissement de frontières administratives : certes, le principe même d'A6 était de permettre de déléguer plus facilement, en mettant les différents enregistrements nécessaires dans des organisations différentes. Mais l'expérience d'A6 (comme celle des enregistrements de colle dans la zone parente, ou celle des PTR de in-addr.arpa) a montré qu'il était très difficile de synchroniser de tels enregistrements « trans-frontières » et qu'ils se prêtaient mal à l'automatisation,
  • Complexité de la maintenance puisque le changement d'un composant A6 peut affecter de nombreuses adresses IP, qu'on ne voit pas (le reste des données peut être dans une autre zone, et même avoir des TTL différents, rendant la prévision des résultats difficile),
  • Et enfin risques de sécurité, la résolution d'un nom en adresse IPv6 dépendant de davantage d'acteurs ; la compromission de l'un d'eux pouvait affecter beaucoup de monde.

La section 3 décrit l'usage effectif d'A6, depuis que certaines versions de BIND (de 9.0 à 9.2, puis abandonné dans les versions ultérieures) ont ajouté la gestion de ce type d'enregistrements. De même, certaines versions de la GNU libc ont fait des requêtes A6. Mais, aujourd'hui, l'analyse du trafic sur deux serveurs DNS de la racine montre très peu de trafic a6 Les statistiques sur les serveurs de .fr gérés par l'AFNIC montrent que A6 n'a pas disparu. Il ne fait certes que 0,2 % des requêtes (contre 8 % pour AAAA) mais il est le dixième type d'enregistrement demandé, devant des types comme SPF, SSHFP, NAPTR ou DNSKEY, normalement bien plus « officiels ». Cela illustre le conservatisme des administrateurs système (qui gardent en production de très vieilles versions de leurs logiciels).

La section 4 expose les conséquences de la reclassification de A6 comme n'ayant qu'un intérêt historique. Les gérants de zone DNS doivent retirer ces enregistrements (s'ils existaient encore), les clients DNS doivent arrêter de demander des A6 et les serveurs DNS doivent désormais traiter ce type comme inconnu (RFC 3597) lors de la réception d'une requête. (Le type A6 faisait partie de ceux pour lesquels le serveur DNS devait faire un traitement spécial.) Comme c'est déjà largement le cas, ce RFC n'aura sans doute pas de conséquence pratique.


Téléchargez le RFC 6563


L'article seul

RFC 6561: Recommendations for the Remediation of Bots in ISP Networks

Date de publication du RFC : Mars 2012
Auteur(s) du RFC : J. Livingood (Comcast), N. Mody (Comcast), M. O'Reirdan (Comcast)
Pour information
Première rédaction de cet article le 20 Mars 2012


Une des plus grosses menaces sur la sécurité de l'Internet réside dans les zombies, ces machines Windows contaminées par du logiciel malveillant et qui obéissent désormais à un maître qui leur ordonne, selon sa volonté, de lancer une dDoS, d'envoyer du spam, etc. Ce RFC documente le point de vue d'un gros FAI, Comcast, sur le problème. La partie que je trouve la plus riche est celle sur le difficile problème de la notification des utilisateurs.

Il n'existe pas de solution miracle contre les zombies. C'est comme cela que je lis ce document qui, malgré son nom, propose peu de remèdes. Et certaines des solutions relèvent plus d'une logique « business » (se débarrasser d'un problème) que d'une volonté d'améliorer l'Internet (le document se réclame du MAAWG, cartel de gros opérateurs très tentés par le nettoyage civilisateur).

Le RFC commence par un peu de terminologie (section 1). Bot est l'abrévation de robot et désigne dans ce RFC un zombie, une machine qui n'obéit plus à son propriétaire légitime mais au « maître des zombies » (bot master), qui les contrôle à distance. Le logiciel qui transforme une innocente machine en zombie a typiquement été installé en trompant l'utilisateur (« Click here to install over 200 000 HOT pictures of REAL CHICKS! »), ou bien en profitant d'une faille de sécurité de ses logiciels, ou encore en essayant plein de mots de passe jusqu'à en trouver un qui marche. Le RFC note qu'il existe des gentils robots (par exemple pour interagir automatiquement sur les canaux IRC) mais qu'il ne se consacre qu'aux méchants, aux robots malveillants. Petite colère au passage : le mot anglais malicious veut dire « malveillant » et pas « malicieux » comme on le voit souvent stupidement traduit.

Les bots sont ensuite regroupés en bandes, les botnets, un groupe de zombies obéissant au même maître. Les activités des botnets sont très variées, envoi de spam, de spim, de spit, dDoS, hébergement de relais ou de sites de hameçonnage, hébergement de contenu illégal, fraude aux clics, etc.

Pendant longtemps, le protocole de communication favori des bot herders (ceux qui créent les botnets et les entretiennent) était IRC (RFC 1459). Muni d'une seule machine maître (le C3C, Command and Control Center), le botnet était assez facile à neutraliser : une fois le maître déconnecté, les zombies ne savaient plus quoi faire. Aujourd'hui, les botnets sont plus perfectionnés : utilisation de protocoles plus variés (HTTP, plus discret et moins filtré, a remplacé IRC), souvent en pair à pair, le tout largement chiffré.

Quelles sont les conséquences des actions du botnet ? Pour les victimes (ceux qui reçoivent le spam ou qui sont attaqués par déni de service), elles sont évidentes (pour le spam, voir « Spamalytics: An Empirical Analysis of Spam Marketing Conversion »). Pour l'utilisateur de la machine, c'est surtout la consommation de ressources, qui diminue les performances attendues. Mais pour le FAI, ces zombies ont aussi un coût : capacité réseau utilisée mais aussi atteinte à la réputation du FAI. Ses adresses IP courent un risque élevé de se retrouver sur des listes noires dont il est difficile de sortir. Certaines des opérations du botnet peuvent mettre en danger des ressources Internet critiques (voir le « Emerging Cyber Threats Report for 2009 » et « Distributed Denial of Service Attacks: Explanation, Classification and Suggested Solutions" »).

Le FAI est évidemment bien situé pour détecter la présence de bots, et pour prévenir les utilisateurs. Notons toutefois que, le concept de neutralité du réseau étant tabou chez les FAI, les risques pour ladite neutralité si le FAI s'engage dans ce combat ne sont pas mentionnés dans le RFC.

Personne ne pense bien sûr que des solutions parfaites existent : la lutte entre les bot herders d'un côté, et les FAI et les utilisateurs de l'autre, n'est pas près de se terminer. Toutefois, affirme le RFC dans sa section 2, on peut espérer limiter les dégâts et réduire la taille des botnets, les rendant ainsi moins dangereux.

La section 3, consacrée à doucher les éventuels enthousiasmes, dit d'ailleurs bien que l'éradication des bots est une tâche difficile. Elle note que la seule méthode parfaite sur une machine est « Réinstallez votre système d'exploitation », un remède assez radical et donc peu susceptible d'être suivi... Et le RFC fait remarquer que même cette approche ne suffit pas (voir l'exposé « Persistent BIOS Infection », ou le cas d'engins fermés, comme certains smartphones ou consoles de jeu, où l'utilisateur n'a même pas la liberté d'installer le système d'exploitation).

Maintenant, place à l'action. La première étape est de détecter les zombies dans le réseau. Cela peut se faire par l'analyse passive du trafic, ou bien par les plaintes, même si peu de FAI les traitent. Idéalement, ces plaintes devraient être transmises sous un format structuré, permettant leur analyse automatique, comme les formats ARF (RFC 5965) ou IODEF (RFC 5070). Le document évoque aussi la possibilité de recherches actives, comme le permet un outil comme nmap, bien que de telles recherches ne soient pas forcément légales (cela dépend du pays, note le RFC). Le RFC déconseille néanmoins ces méthodes actives, pas tant sur leur caractère intrusif que sur leur inefficacité (le bot ne va pas forcément se signaler lors du balayage).

Le RFC insiste sur la nécessité de détecter vite, si nécessaire au détriment de la justesse des résultats (tirer d'abord, réflechir ensuite...)

Parmi les techniques passives disponibles, le document cite aussi l'analyse des flux Netflow (RFC 3954, mais depuis remplacé par le IPFIX du RFC 5470) ou bien les méthodes à base de DNS, très à la mode en ce moment, notamment grâce au travail des chercheurs de Georgia Tech (voir par exemple David Dagon, Wenke Lee, « Global Internet Monitoring Using Passive DNS », Cybersecurity Applications & Technology Conference for Homeland Security, 2009). Ces méthodes fondées sur l'observation du trafic DNS ont été utilisées dans le cas de Conficker (les zombies font des demandes de résolution pour les noms de domaine générés par l'algorithme de Conficker, ce dernier n'utilisant pas de noms câblés en dur, cf. l'excellent rapport « An Analysis of Conficker's Logic and Rendezvous Points »). Mais combien de FAI, qui n'arrivent déjà pas à fournir un service correct à leurs utilisateurs, ont les moyens, la compétence et le temps de mener ce genre d'études ?

Idéalement, le FAI devrait non seulement détecter mais également identifier l'infection spécifique, les remèdes pouvant varier.

La partie la plus intéressante du RFC, à mon avis, concerne la notification des utilisateurs. Comment les prévenir que leur machine, infectée, est devenue un zombie ? Et le faire de façon à ce qu'ils comprennent et agissent ? Toutes les techniques de communication possibles avec les utilisateurs sont soigneusement passées en revue, mais aucune ne semble parfaite.

Voici donc les principales techniques envisagées :

  • Courrier électronique. Un des problèmes est qu'il risque de ne pas être lu immédiatement. Un autre est qu'il soit classé comme spam. Enfin, les méchants peuvent essayer d'envoyer de faux messages pour brouiller les pistes (du genre « Nous avons reçu notification d'une alerte de sécurité sur votre compte, connectez-vous à http://igotyou.biz/phishing.asp pour indiquer vos coordonnées »...). Ce dernier point est notamment développé en section 9 : il est très difficile d'imaginer un système de notification qui ne puisse pas être détourné par les hameçonneurs.
  • Appel téléphonique. Ils coûtent cher (il n'y a pas que le prix de l'appel, il y a surtout celui de l'employé appelant, si on choisit de faire faire l'appel par des gens compétents). Ils peuvent être considérés comme du spam (par exemple, Bouygues Telecom appelle régulièrement ses clients pour proposer des offres commerciales nouvelles et sans intérêt, et le robot humain qui appelle, avec un fort accent étranger, n'est jamais capable de répondre à la moindre question concrète : de nombreux clients raccrochent donc dès la première minute de ces spams.). Pire, si l'utilisateur utilise un système de voix sur IP sur son ordinateur, le logiciel malveillant peut décider de ne pas répondre aux appels du FAI. Et puis, le téléphone est le plus mauvais média pour donner des instructions techniques complexes.
  • Courrier postal. Très cher et très lent.
  • Enfermement dans un jardin clos (walled garden). L'idée de base est de configurer les routeurs du FAI pour détourner automatiquement tout le trafic en provenance du bot. Les communications avec le port 80, celui de HTTP, sont alors transmises à un site Web portant le message de notification et les instructions pour remédier au problème. Le jardin peut être totalement clos ou bien laisser passer vers certains services externes (un exemple typique étant Windows Update). La méthode est très brutale mais efficace : l'utilisateur ne peut pas ne pas voir les messages et, en attendant, le bot ne peut plus faire grand mal. Mais, en raison de sa brutalité, elle soulève bien des problèmes. Par exemple, les services autres que le Web (pensons à la voix sur IP) sont coupés, sans avertissement possible. Si le FAI s'est trompé (et que la machine n'était pas réellement infectée), le client va être furieux, et à juste titre. On risque de devoir donc laisser passer certains services par la porte du jardin, et la maintenance de la liste de ces services va être coûteuse. Le FAI doit aussi décider sur quels critères il laissera l'utilisateur sortir du jardin clos. Sur sa simple parole ou bien après un examen (forcément très intrusif) de la machine (d'autant plus que l'utilisateur typique a plusieurs machines derrière le routeur NAT...) ? Et faut-il faire passer un test de Turing aux demandeurs pour vérifier que c'est bien l'utilisateur et pas le bot qui demande l'ouverture du jardin clos ?
  • Messagerie instantanée. C'est rapide et simple. Ce serait sans doute la méthode idéale si tous les utilisateurs utilisaient un tel service et y étaient connectés en permanence. Et il y a le risque de spim.
  • SMS. L'utilisateur lira probablement le message, et en peu de temps. Cela suppose que le FAI garde trace des numéros de téléphone de ses clients et que ceux-ci ne considèrent pas le message comme du spam. En outre, les contraintes de taille du SMS posent un drôle de défi au rédacteur du message.
  • Le RFC mentionne aussi la possibilité d'utiliser un canal public pour les notifications, par exemple d'utiliser un haut-parleur dans une gare ou un café pour crier « Votre attention, s'il vous plait, nous venons de découvrir que la machine 18:03:73:66:e5:68 est infectée par un logiciel malveillant. Son propriétaire est prié de la désinfecter de toute urgence. » Cela peut être utile dans ces environnements, où l'administrateur du réseau n'a pas de lien particulier avec ses utilisateurs et ne sait pas comment les contacter.

À noter que toutes ces méthodes ne produisent pas de bons résultats au cas, le plus fréquent aujourd'hui, où les adresses IP sont partagées. Dans une entreprise de 500 personnes, montrer la notification aux 500 utilisateurs alors que seul l'administrateur système peut agir est probablement contre-productif. Si le FAI connaît les coordonnées dudit administrateur, il vaut certainement mieux lui écrire directement.

Cette discussion (section 5) des difficultés à attirer l'attention de ses propres clients sur un problème sérieux est la plus concrète du document. Mais elle pose plus de questions qu'elle n'apporte de réponses. Vous vous demandez peut-être quelle solution a finalement retenue Comcast ? Décrite dans le RFC 6108, elle consiste à modifier le contenu des pages Web vues par l'utilisateur pour y insérer une fenêtre-polichinelle d'avertissement.

La seule section qui ait un rapport direct avec le titre (section 6), sur les remèdes est, par contre, très courte, peut-être à juste titre, étant donné la difficulté à traiter les zombies. On les a détecté, on a notifié l'utilisateur, maintenant, que faire ? Le RFC suggère aux FAI de créer un site Web dédié à cet usage, où utilisateurs et administrateurs système pourront accéder à diverses documentations et outils. Les textes visant les utilisateurs sont difficiles à écrire : il faut les motiver pour agir (le bot peut être très discret, et l'utilisateur n'a alors rien détecté de problématique pour lui), sans les paniquer, et il faut expliquer rapidement car l'utilisateur ne lira pas de longs textes. Le RFC cite comme exemple d'introduction pour capter l'attention : « What is a bot? A bot is a piece of software, generally installed on your machine without your knowledge, which either sends spam or tries to steal your personal information. They can be very difficult to spot, though you may have noticed that your computer is running much more slowly than usual or you notice regular disk activity even when you are not doing anything. Ignoring this problem is risky to you and your personal information. Thus, bots need to be removed to protect your data and your personal information. »

La tâche de désinfection peut être difficile (surtout sur des engins comme les consoles de jeu, qui ne donnent typiquement pas accès au système) et, dans tous les cas, l'utilisateur n'a en général pas de compétences techniques : les instructions de désinfection doivent donc être très concrètes et détaillées.

Donc, sous forme d'une liste, voici quelques-unes des étapes que le RFC recommande de ne pas oublier, dans les conseils donnés aux utilisateurs :

  • Faites des sauvegardes de vos fichiers (un bon avis, indépendamment de l'infection par le malware).
  • Mettez à jour votre système (Windows Update avec Microsoft Windows, par exemple).
  • Ne pas hésiter à demander l'aide d'un professionnel. Ce conseil du RFC est évidemment raisonnable (la tâche peut être trop complexe pour l'utilisateur ordinaire) mais me laisse perplexe : pour les soins aux machines de M. Toutlemonde, on trouve plein de gourous autoproclamés, dont les compétences en informatique sont en général à peine supérieures à celles de leurs clients. Ces derniers, ne connaissant pas le sujet, ne peuvent pas distinguer un vrai expert d'un Jean-Kevin Michu qui se prend pour un gourou parce qu'il a déjà installé une fois un Windows en partant de zéro. Ce problème me semble un des plus sérieux pour M. Toutlemonde « à qui faire confiance ? »
  • Si l'utilisateur a l'intention de porter plainte, il faut faire l'inverse : ne pas nettoyer la machine mais la laisser intacte pour l'enquête (comme la scène du crime entourée du ruban jaune, dans les séries policières états-uniennes). Aux États-Unis, l'organisme national en charge est l'Internet Crime Complaint Center. (Quel est l'équivalent en France ?) Le RFC note toutefois en termes diplomatiquement polis qu'il y a peu de chance que la police se dérange parce que M. Toutlemonde a un virus sur sa machine... (Et j'ajoute que c'est parce que la police est occupée avec des crimes plus graves comme par exemple le partage de la culture.)

Et si l'utilisateur ne peut pas ou ne veut pas réparer (section 7) ? Le RFC note que c'est évidemment un problème non-technique et a une approche très états-unienne, « shoot them » (supprimer l'abonnement et déconnecter l'utilisateur).

Le document rend aussi un hommage obligatoire à la nécessite de préserver la vie privée des utilisateurs (sections 4 et 10), sans trop s'attarder sur comment concilier surveillance rapprochée et respect de la vie privée. Un intéressant problème à la fois politique et légal. Voir aussi la section 8 sur les problèmes que pose le partage de données entre l'utilisateur, le FAI et éventuellement les autorités. L'annexe A donne une liste d'organisations privées qui peuvent être intéressés par ces données (liste de machines infectées, pour faire une liste noire, par exemple) et les publier.

À noter qu'une autre faiblesse de ce document est que, pour éviter de déchaîner les avocats de Microsoft, le fait que la quasi-totalité des zombies soient aujourd'hui des machines Windows est tout simplement absent...


Téléchargez le RFC 6561


L'article seul

RFC 6557: Procedures for Maintaining the Time Zone Database

Date de publication du RFC : Février 2012
Auteur(s) du RFC : E. Lear, P. Eggert
Première rédaction de cet article le 3 Mars 2012


Vous aviez peut-être suivi l'affaire il y a quelques mois : une société d'astrologie (!) a fait un procès au responsable de la base de données des fuseaux horaires, base utilisée ensuite par des tas de logiciels dans le monde (notamment les logiciels libres). La société prétendait qu'elle était propriétaire des données. Comme le responsable de la base, Arthur David Olson, est un simple individu, sans moyens financiers (la justice, c'est seulement pour les riches), il a cédé. Désormais, cette base est gérée par l'IANA, et ce RFC documente les procédures de gestion.

La solution trouvée, confier cette base à l'ICANN, permet au moins de se mettre à l'abri des trolls, l'ICANN ayant beaucoup d'argent et d'avocats. Au moins, les millions de dollars stockés par l'ICANN, à titre de précaution juridique en cas de procès vont servir à quelque chose d'utile. Mais, en attendant, c'est un nouveau pan de la gouvernance de l'Internet qui passe d'un volontaire bénévole, aidé par quelques internautes, à une grosse bureaucratie politicienne, très lente et très chère.

Le registre est donc désormais en ligne à l'IANA. La section 7 du RFC discute les questions de propriété intellectuelle associées.

Quelques articles sur le sujet :


Téléchargez le RFC 6557


L'article seul

RFC 6556: Testing Eyeball Happiness

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : F. Baker (Cisco)
Pour information
Première rédaction de cet article le 7 Avril 2012


Le problème du bonheur des globes oculaires (eyeball happiness) fait l'objet de recherches actives en ce moment. Il s'agit de s'assurer que, lorsqu'un service Internet (par exemple un site Web) est accessible à la fois en IPv4 et en IPv6, l'utilisateur (le propriétaire des globes oculaires) sera heureux (il verra le site très vite), que sa connectivité IPv6 fonctionne correctement ou pas. L'incertitude à ce sujet est la principale cause du très faible nombre de sites Web qui ont un enregistrement AAAA (adresse IPv6) dans le DNS aujourd'hui.

Ce RFC ne propose pas de solution : issu de travaux menés notamment au sein du groupe de travail benchmarks de l'IETF, il propose simplement de mesurer ce bonheur des globes oculaires, de manière à ce qu'on puisse comparer les solutions. On pourra alors retenir les meilleures, de manière à faire sauter ce qui est aujourd'hui un sérieux obstacle au déploiement d'IPv6.

La section 1 du RFC résume le problème de base : si on a une connectivité où plusieurs préfixes IP sont possibles (un IPv4 et un IPv6, ou bien plusieurs IPv6), et que l'application choisit comme source le « mauvais » (celui qui a la moins bonne connectivité, voire pas de connectivité du tout), quelles seront les conséquences pratiques ? L'établissement de la session en sera-t-il ralenti ? Comment TCP va-t-il réagir (RFC 5461) ?

L'algorithme naïf pour l'application est de récupérer une liste d'adresses possibles pour la destination, via getaddrinfo(), et d'essayer chaque adresse successivement. Si certaines timeoutent, le temps total d'établissement de la connexion (attendre l'expiration du délai de garde, puis essayer l'adresse suivante) va largement dépasser les capacités de l'utilisateur même le plus patient (cela peut dépasser la minute, la valeur exacte dépend de nombreux paramètres). Les globes oculaires seront malheureux.

C'est à cause de cela que, alors que plus de 40 % des zones dans .fr ont une adresse IPv6 pour leur service DNS (mesures faites en janvier 2012), seules moins d'1 % en ont une pour leur service Web. C'est parce que le DNS a été prévu pour résister aux pannes dès le début (le résolveur se souvient de quelles adresses marchent, pour une zone) et que l'ajout d'un AAAA cassé n'a pas de conséquences graves. Au contraire, le Web n'a pas de mécanisme natif pour assurer la haute disponibilité et un AAAA cassé se paie très cher en temps d'attente pour les clients. Beaucoup de gérants de sites Web préfèrent donc ne pas courir le risque, même s'il ne frapperait qu'une petite minorité de leurs clients.

L'idée de ce RFC, présentée en section 2, est de quantifier ce problème. Le but est d'aboutir à des chiffres indiquant, pour un système donné (nommé Alice), le temps qu'il met à ouvrir une session avec un service (nommé Bob) dont certaines adresses sont incorrectes. Plusieurs cas d'incorrection peuvent se présenter :

  • Un routeur jette les paquets mais transmet un message ICMP administratively prohibited ou bien destination unreachable,
  • Un routeur jette silencieusement les paquets (cible DROP dans iptables par exemple),
  • Un programme intermédiaire génère un RST (reset) TCP,
  • Un problème de MTU fait que les paquets au delà d'une certaine taille ne sont pas transmis. Normalement, la découverte de la MTU du chemin (RFC 1191, RFC 1981) fait que ce problème ne doit jamais se produire. En pratique, des configurations incorrectes (blocage aveugle de tout ICMP) font qu'il arrive quand même.

Le test doit être fait pour tous ces cas car rien ne dit que l'application réagira de la même façon à tous ces problèmes. Le plus important est sans doute celui de la perte silencieuse des paquets, car c'est le pire : si l'application réagit bien même dans ce cas, elle s'en tirera sans doute dans les autres. Si on n'en teste qu'un, cela doit donc être celui-ci. (C'est ce que dit le RFC. En pratique, le cas des problèmes de MTU est souvent aussi grave, et il ne se détecte qu'après l'ouverture de la session, lorsqu'on commence à envoyer de gros paquets.)

La section 2.2 explique la procédure, notamment le fait qu'on intègre le temps de la requête DNS préalable (ce que je trouve contestable, mais les raisons ne sont pas expliquées). Les métriques elle-mêmes sont en section 2.3. On mesure le temps entre la première requête DNS et la fin de l'établissement de la connexion TCP, qui est le moment où l'application peut commencer à travailler. Cela se nomme le Session Setup Interval. Si on garde les temps minimum (meilleur cas, probablement celui où la première tentative réussie) et maximum (pire cas, lorsqu'il aura fallu essayer toutes les adresses de la cible), on les nomme Minimum Session Setup Interval et Maximum Session Setup Interval. Le reste du RFC est composé de détails concrets pour qui voudrait effectuer cette mesure. Telle qu'elle est définie (avec des notions comme « l'arrivée du dernier but »), elle n'est pas triviale, voire pas possible à mettre en œuvre sur une machine Unix normale.

Il existe aussi une métrique « qualitative », où on décrit le trafic observé (Attempt Pattern). Cela peut être simple (« Un paquet TCP SYN est envoyé successivement à toutes les adresses, à des intervalles de X milli-secondes ») mais aussi très complexe. Mon article sur les algorithmes en donne quelques exemples.


Téléchargez le RFC 6556


L'article seul

RFC 6555: Happy Eyeballs: Success with Dual-Stack Hosts

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : D. Wing, A. Yourtchenko (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 7 Avril 2012


Une question récurrente qu'IPv6 pose aux développeurs d'application et aux administrateurs système qui déploieront ces applications ensuite est celle d'une machine accessible à la fois en IPv4 et IPv6. Si le pair cherchant à joindre cette machine croit avoir IPv6 mais que sa connectivité ne marche pas, ou mal, l'application arrivera-t-elle à se rabattre en IPv4 très vite ou bien imposera-t-elle à l'utilisateur un long délai avant de détecter enfin le problème ? Cette question est connue comme « le bonheur des globes oculaires » (les dits globes étant les yeux de l'utilisateur qui attend avec impatience la page d'accueil de YouPorn) et ce RFC spécifie les exigences pour l'algorithme de connexion du client, afin de rendre les globes oculaires le plus heureux possible.

La section 1 rappelle les données du problème : on veut évidemment que cela marche aussi bien en IPv6 qu'en IPv4 (pas question d'accepter des performances inférieures) or, dans l'état actuel du déploiement d'IPv6, bien des sites ont une connexion IPv6 totalement ou partiellement cassée. Si un serveur a IPv4 et IPv6 et que son client n'a qu'IPv4, pas de problème. Mais si le client a IPv6, tente de l'utiliser, mais que sa connexion est plus ou moins en panne, ses globes oculaires vont souffrir d'impatience. Certains fournisseurs (notamment Google) ont résolu le problème en n'annonçant leur connectivité IPv6 (via le DNS et les enregistrements AAAA) qu'à certains réseaux, configurés manuellement après examen de la qualité effective de leur connectivité. Cette approche, nommée « whitelisting » ne passe évidemment pas à l'échelle. Même pour Google, c'est un travail colossal que d'évaluer le réseau de tous les sites Internet.

(À noter que deux lecteurs m'ont fait remarquer que YouPorn n'est pas un bon exemple, puisqu'il ne publie pas d'adresse IPv6. C'est vrai et cela montre que mes lecteurs connaissent bien YouPorn.)

La bonne solution est donc que l'application elle-même gère le problème (ou, sinon l'application elle-même, la bibliothèque logicielle qu'elle utilise et où se trouve la fonction de connexion). Il existe plusieurs algorithmes pour cela, déjà largement déployés. Ce RFC normalise les caractéristiques que doivent avoir ces algorithmes. Si on suit ce RFC, le trafic (IP et DNS) va légèrement augmenter (surtout si la connectivité IPv6 marche mal ou pas du tout) mais la qualité du vécu de l'utilisateur va être maintenue, même en présence de problèmes, ce qui compense largement. Autrement, il existerait un risque élevé que certains utilisateurs coupent complètement IPv6, plutôt que de supporter ces problèmes de délai de connexion.

La section 3 revient dans l'histoire, pour montrer que le problème n'est pas nouveau. En 1994, le RFC 1671 disait « The dual-stack code may get two addresses back from DNS; which does it use? During the many years of transition the Internet will contain black holes. » (Au passage, cela montre la stupidité de la légende, fréquemment entendue, comme quoi les problèmes de la transition IPv4->IPv6 n'auraient pas été étudiés à l'avance.) Tout le reste de notre RFC 6555 est consacré à répondre à cette question. La cible principale est composée des protocoles de transport avec connexion (TCP, SCTP), les protocoles sans connexion comme UDP soulevant d'autres questions (s'ils ont une sémantique requête/réponse, comme dans ICE, les algorithmes de ce RFC peuvent être utilisés).

Le RFC rejette l'idée d'utiliser des noms différents pour les deux familles (comme www.ipv6.example.com), car cela complique le partage de noms (envoi d'un URL à un copain, par exemple).

Donc, on a un nom de machine qu'on veut contacter, mettons www.example.com, avec deux adresses associées, une par famille (voir les sections 5.3 et 5.4 pour le cas avec plus de deux adresses). Avec l'algorithme naïf qu'utilisent certains logiciels, et une connexion IPv6 qui marche mal, voici la séquence d'évenements :

  • L'initiateur de la connexion utilise le DNS pour demander les enregistrements A (adresse IPv4) et AAAA (IPv6). (Notez qu'il n'existe pas de type de requête DNS pour avoir les deux enregistrements d'un coup, il faut donc deux requêtes. Voir aussi la section 5.4.)
  • Il récupère 192.0.2.1 et 2001:db8::1.
  • Il tente IPv6 (sur Linux, l'ordre des essais est réglable dans /etc/gai.conf). L'initiateur envoie un paquet TCP SYN à 2001:db8::1.
  • Pas de réponse (connexion IPv6 incorrecte). L'initiateur réessaie, deux fois, trois fois, faisant ainsi perdre de nombreuses secondes.
  • L'initiateur renonce, il passe à IPv4 et envoie un paquet TCP SYN à 192.0.2.1.
  • Le répondeur envoie un SYN+ACK en échange, l'initiateur réplique par un ACK et la connexion TCP est établie.

Le problème de cet algorithme naïf est donc la longue attente lors des essais IPv6. On veut au contraire un algorithme qui bascule rapidementt en IPv4 lorsqu'IPv6 ne marche pas, sans pour autant gaspiller les ressources réseau en essayant par exemple toutes les adresses en même temps.

L'algorithme recommandé (section 4, cœur de ce RFC) aura donc la tête :

  • L'initiateur de la connexion utilise le DNS pour demander les enregistrements A (adresse IPv4) et AAAA (IPv6).
  • Il récupère 192.0.2.1 et 2001:db8::1. Il sait donc qu'il a plusieurs adresses, de famille différente.
  • Il tente IPv6. L'initiateur envoie un paquet TCP SYN à 2001:db8::1, avec un très court délai de garde.
  • Pas de réponse ? L'initiateur passe à IPv4 tout de suite. Il envoie un paquet TCP SYN à 192.0.2.1.
  • Le répondeur envoie un SYN+ACK en échange, l'initiateur réplique par un ACK et la connexion TCP est établie.

Si le répondeur réagit à une vitesse normale en IPv6, la connexion sera établie en IPv6. Sinon, on passera vite en IPv4, et l'utilisateur humain ne s'apercevra de rien. Naturellement, si le DNS n'avait rapporté qu'une seule adresse (v4 ou v6), on reste à l'algorithme traditionnel (« essayer, patienter, ré-essayer »).

La section 4 précise ensuite les exigences auxquelles doit obéir l'algorithme. D'abord, il est important de ne pas tester IPv4 tout de suite. Les premiers algorithmes « bonheur des globes oculaires » envoyaient les deux paquets SYN en même temps, gaspillant des ressources réseau et serveur. Ce double essai faisait que les équipements IPv4 du réseau avaient autant de travail qu'avant, alors qu'on aurait souhaité les retirer du service petit à petit. En outre, ce test simultané fait que, dans la moitié des cas, la connexion sera établie en IPv4, empêchant de tirer profit des avantages d'IPv6 (cf. RFC 6269). Donc, on doit tester en IPv6 d'abord, sauf si on se souvient des tentatives précédentes (voir plus loin la variante « avec état ») ou bien si l'administrateur système a délibérement configuré la machine pour préférer IPv4.

L'avantage de cet algorithme « IPv6 d'abord puis rapidement basculer en IPv4 » est qu'il est sans état : l'initiateur n'a pas à garder en mémoire les caractéristiques de tous ses correspondants. Mais son inconvénient est qu'on recommence le test à chaque connexion. Il existe donc un algorithme avec état, où l'initiateur peut garder en mémoire le fait qu'une machine (ou bien un préfixe entier) a une adresse IPv6 mais ne répond pas aux demandes de connexion de cette famille. Le RFC recommande toutefois de re-essayer IPv6 au moins toutes les dix minutes, pour voir si la situation a changé. De plus, un changement de connectivité (détecté par le DNA des RFC 4436 ou RFC 6059) doit entraîner un vidage complet de l'état (on doit oublier ce qu'on a appris, qui n'est plus pertinent).

Une conséquence de l'algorithme recommandé est que, dans certains cas, les deux connexions TCP (v4 et v6) seront établies (si le SYN IPv6 voyage lentement et que la réponse arrive après que l'initiateur de la connexion se soit impatienté et soit passé à IPv4). Cela peut être intéressant dans certains cas rares, mais le RFC recommande plutôt d'abandonner la connexion perdante (la deuxième). Autrement, cela pourrait entraîner des problèmes avec, par exemple, les sites Web qui lient un cookie à l'adresse IP du client, et seraient surpris de voir deux connexions avec des adresses différentes.

Voilà, l'essentiel du RFC est là. La section 5 donne quelques détails en plus. Par exemple, l'algorithme des globes oculaires heureux est astucieux, mais tend à masquer les problèmes. Si un site Web publie les deux adresses mais que sa connectivité IPv6 est défaillante, aucun utilisateur ne lui signalera puisque, pour eux, tout va bien. Il est donc recommandé que le logiciel permette de débrayer cet algorithme, afin de tester la connectivité avec seulement v4 ou seulement v6, ou bien que le logiciel indique quelque part ce qu'il a choisi, pour mieux identifier d'éventuels problèmes v6.

D'autre part, vous avez peut-être remarqué que j'ai utilisé des termes vagues (« un certain temps ») pour parler du délai entre, par exemple, le premier SYN IPv6 et le premier SYN IPv4. La section 5.5 donne des idées quantitatives en suggérant entre 150 et 250 ms entre deux essais (les navigateurs actuels sont plutôt du côté de 300 ms). C'est quasiment imperceptible à un utilisateur humain devant son navigateur Web, tout en évitant de surcharger le réseau inutilement. Les algorithmes avec état ont le droit d'être plus impatients, puisqu'ils peuvent se souvenir des durées d'établissement de connexion précédents.

Autre problème pratique, l'interaction avec la politique de sécurité des navigateurs Web (RFC 6454). Pour limiter les risques d'attaque par changement DNS (croire qu'on se connecte au même serveur HTTP alors que c'est en fait un autre), les navigateurs ne doivent pas changer de famille d'adresse (v4 en v6 ou réciproquement) une fois la session commencée.

Enfin, les implémentations. La section 6 donne les exemples de Firefox et Chrome, très proches de ce que décrit le RFC. D'autres possibilités sont disponibles en ligne, en Erlang ou en C. Une version pour Go avait été affichée en http://www.pastie.org/1528545 (en voici une sauvegarde locale).

Enfin, pour un exemple de test du malheur des globes oculaires, voir « Experiences of host behavior in broken IPv6 networks ».


Téléchargez le RFC 6555


L'article seul

RFC 6550: RPL: IPv6 Routing Protocol for Low power and Lossy Networks

Date de publication du RFC : Mars 2012
Auteur(s) du RFC : T. Winter, P. Thubert (Cisco Systems), A. Brandt (Sigma Designs), T. Clausen (LIX, École Polytechnique), J. Hui (Arch Rock Corporation), R. Kelsey (Ember Corporation), P. Levis (Stanford University), K. Pister (Dust Networks), R. Struik, JP. Vasseur (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF roll
Première rédaction de cet article le 26 Mars 2012


Il y a beaucoup d'intérêt en ce moment pour un (largement mythique) « Internet des objets » qui mèle des fantasmes domotiques éculés (le réfrigérateur qui commande tout seul des bières à Carrefour via l'Internet, lorsqu'il est vide), l'arrivée massive d'ordinateurs qui ne sont pas considérés comme des ordinateurs (smartphones, tablettes, télévisions connectées), la connexion à des réseaux TCP/IP d'équipements très modestes, et la diffusion de plus en plus large d'étiquettes RFID. Pour les ordinateurs (un smartphone, bien plus puissant que l'ordinateur qu'embarquait les vaisseaux Apollo, mérite tout à fait ce titre), un des enjeux de l'Internet des objets est le routage des paquets IP. Ces « objets » ont des ressources électriques limitées, et sont souvent connectés par des liens radio de qualité médiocre. Les protocoles de routage traditionnels ne sont pas très adaptés à cette situation. Le groupe de travail ROLL de l'IETF travaille sur ce problème et vient de produire son protocole « officiel », RPL (Routing Protocol for LLNs où un LLN est un Low power and Lossy Network, un réseau où mêmes les routeurs ont peu de courant et où pas mal de paquets se perdent en route). Le groupe ROLL a déjà produit plusieurs RFC détaillant les demandes de ces LLNs : RFC 5867, RFC 5826, RFC 5673 et RFC 5548. Il a également normalisé l'algorithme de distribution utilisé par RPL, Trickle (RFC 6206).

Un exemple de LLNs est un groupe de capteurs dispersés un peu partout dans un bâtiment industriel : ce sont des petites machines par rapport au smartphone typique, fonctionnant sur batteries ou sur piles, ils doivent faire attention à leur consommmation électrique. Connectés par radios, ils n'ont en général pas la possibilité de parler directement aux gros routeurs de la salle machines, située à des dizaines de mètres. Certains des objets doivent donc tenir le rôle de routeur, relayant les communications de leurs camarades (la distinction entre routeur et machine terminale est d'ailleurs assez floue dans RPL). Il leur faut donc un protocole de routage pour trouver les chemins possibles et les protocoles existants comme OSPF n'ont jamais été conçus pour ce genre de missions (par exemple, OSPF émet des messages même lorsqu'il n'y a pas de changements, ce qui peut vider une batterie rapidement). Le « public » visé est donc composé de machines avec des processeurs 16bits, quelques ko de RAM et de Flash, dans des réseaux où il peut y avoir des milliers de tels engins.

RPL est la solution technique à ce problème du routage. Je préviens tout de suite mes fidèles lecteurs que ce RFC est très long et que je n'ai pas tout suivi, loin de là. Il n'y aura donc pas ici de cours sur RPL mais juste la mise en évidence de certains points intéressants (si vous ne lisez qu'une partie du RFC, la section 3 est une description de haut niveau de RPL). Notez qu'il existe d'autres protocoles de routage répondant à peu près à ce cahier des charges, notamment Babel (RFC 6126).

Pour distribuer l'information sur les routes et les routeurs, RPL utilise l'algorithme Trickle (RFC 6206).

RPL essaie de construire un graphe acyclique, qui est lui-même divisé en sous-graphes acycliques, chacun enraciné dans une et une seule destination (RPL les nomme DODAG pour Destination-Oriented Direct Acyclic Graphs). Tout le trafic pour une destination donnée a ainsi la garantie de l'atteindre, sans boucler. Le graphe est orienté : les informations de routage indiquent si le paquet progressera « vers le haut » ou bien « vers le bas » et cette orientation joue un rôle essentiel dans la prévention des boucles (section 11.2). L'annexe A décrit en détail un exemple de fonctionnement.

Pour optimiser les routes, RPL est paramétré avec une fonction nommée OF (pour Objective Function). Des concepts comme celui de distance sont définis par cette fonction. Des réseaux différents peuvent utiliser des OF différents (une qui cherche le chemin le plus court, une qui cherche à ne pas utiliser comme routeur les machines n'ayant pas de connexion au courant électrique, etc), même s'ils utilisent tous RPL. Ces fonctions sont enregistrées à l'IANA (section 20.5). La section 14 décrit les règles auxquelles doivent obéir ces fonctions.

RPL nécessite des liens bidirectionnels. Ce n'est pas toujours évident d'avoir de tels liens dans le monde des ondes radio. RPL doit donc tester la bidirectionnalité des liens avec un potentiel routeur, par exemple en utilisant le protocole du RFC 5881. Comme tout bon protocole TCP/IP, RPL peut fonctionner sur un grand nombre de modèles de réseaux physiques (cf. RFC 3819). Les communications du protocole RPL utiliseront ensuite des paquets ICMP (RFC 4443) de type 155.

Conçu pour des réseaux de machines ayant peu de capacités, et qu'on ne peut pas aller toutes configurer à la main, RPL a par défaut peu de sécurité. Dans le mode de base, n'importe quelle machine peut se joindre au réseau et se faire désigner comme routeur. Dans le mode « pré-installé », les machines doivent connaître une clé pour joindre le réseau. Dans le mode de sécurité maximale, dit « authentifié », il y a deux clés, une pour devenir un nœud ordinaire, et une pour devenir un routeur. (Voir la section 10 pour tous les détails sur la sécurité.)

RPL est un protocole de routage (routing), c'est-à-dire de construction de routes. Il ne change pas le modèle de transmission (forwarding) d'IP, celui que suivent les nœuds une fois les routes connues. Néanmoins, la section 11 donne quelques conseils intéressants sur la façon dont les machines peuvent limiter les problèmes lors de la transmission des paquets. Par exemple, une machine peut faire partie de plusieurs réseaux RPL (on dit « plusieurs instances RPL ») et elle doit faire attention en routant des paquets entre deux instances car les protections contre les boucles ne s'appliquent plus. Une solution possible est d'ordonner les instances (on peut transmettre les paquets destinés à un réseau seulement vers un réseau dont le numéro d'instance est supérieur).

L'ingénieur réseaux qui devra installer et configurer un réseau utilisant RPL peut aller regarder tout de suite la section 18 : elle explique la gestion de ces réseaux et les paramètres qu'on peut avoir à configurer, dans l'esprit du RFC 5706. Évidemment, c'est toujours préférable lorsqu'il n'y a rien à configurer et que cela marche tout seul (RFC 1958, section 3.8). C'est particulièrement vrai pour le type de réseaux auxquels est destiné RPL, des réseaux composés de nombreuses machines planquées un peu partout. Néanmoins, si on veut configurer, il y a quelques boutons à tourner comme le choix du numéro d'instance RPL (section 18.2.3) qui permet d'avoir plusieurs réseaux RPL différents dans un même endroit.

Enfin, la section 19 est la traditionnelle section sur la sécurité. Comme résumé au début de cet article, RPL offre forcément peu de sécurité : les réseaux ad hoc pour lesquels il est prévu ne s'y prêtent guère (difficulté à configurer chaque machine, par exemple pour y indiquer une clé, ou bien ressources limitées des machines, ce qui limite l'usage de la cryptographie). RPL fournit néanmoins des mécanismes de sécurité mais il est à parier qu'ils ne seront pas souvent déployés.

Comme souvent de nos jours, une bonne partie des efforts du groupe de travail a été dépensé en discussions sur les différentes brevets plombant le protocole. Il a finalement été décidé de foncer mais les juristes peuvent regarder les différentes prétentions à l'appropriation qui pèsent sur RPL.

Quelles implémentations sont disponibles ? Selon le groupe de travail, elles seraient déjà plus de dix, mais je n'ai pas de liste. Ce qui est sûr, c'est que deux tests d'interopérabilité ont déjà eu lieu, sous la houlette de l'IPSO et du consortium Zigbee. La section 16 intéressera certainement les implémenteurs car elle récapitule les choses importantes qu'il faut savoir pour que toutes les mises en œuvre de RPL coopèrent.

Un résumé de synthèse sur RPL est « "The Internet of Things" takes a step forward with new IPv6 routing protocol », écrit par un employé de Cisco (entreprise qui a fondé l'alliance IPSO en septembre 2008).


Téléchargez le RFC 6550


L'article seul

RFC 6547: RFC 3627 to Historic Status

Date de publication du RFC : Février 2012
Auteur(s) du RFC : W. George (Time Warner Cable)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 1 Mars 2012


Un très court RFC qui se contente de déclarer formellement que le RFC 3627 n'a plus qu'un intérêt historique. La principale recommendation de ce vieux RFC, que les liens point-à-point ne soient pas numérotés en IPv6 avec un /127, a été annulée par le RFC 6164, qui recommande au contraire cette pratique.


Téléchargez le RFC 6547


L'article seul

RFC 6545: Real-time Inter-network Defense (RID)

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : Kathleen M. Moriarty (EMC)
Chemin des normes
Première rédaction de cet article le 22 Avril 2012


La sécurité, face aux innombrables attaques que connaissent les réseaux tous les jours, nécessite un échange d'information permanent. Ce RFC normalise donc un format permettant d'échanger et de traiter ce genre d'informations. Il sera donc peut-être un outil technique utile pour les CSIRT et les opérateurs.

La section 1 résume les problèmes de la sécurité des réseaux auxquels les opérateurs font face. Une fois l'attaque détectée, que ce soit un hameçonnage, une DoS ou une pénétration réussie dans un système connecté au réseau, il faut rédiger un rapport, transmettre à l'opérateur d'origine de l'attaque, demander à un opérateur amont de prendre des mesures pour limiter les dégâts, demander de continuer l'enquête en suivant la trace de l'attaquant, etc. Par exemple, si on veut suivre une trace de paquets dont l'adresse IP source est mensongère, et que le filtrage recommandé par le RFC 2827 n'est pas en place, il faut repérer par quel câble sont entrés ces paquets et envoyer ensuite à l'opérateur situé derrière une demande de continuation de l'enquête. Il n'y a pas de mécanisme formel pour cela. Ça se fait typiquement par téléphone ou par envoi d'un courrier en langue naturelle, ce qui augmente les coûts de traitement.

Le nouveau format, normalisé dans ce RFC 6545, se nomme RID pour Real-time Inter-network Defense et se base sur le format IODEF du RFC 5070, qui lui-même utilise XML. L'apport par rapport à l'IODEF de base est de cibler la circulation d'informations en « temps réel ». RID avait d'abord été spécifié dans le RFC 6045, que notre RFC met à jour. À part le changement de statut (RID est désormais sur le chemin des normes), les changements (résumés dans la section 1.1) sont de peu d'importance.

RID vise donc à permettre la réponse immédiate à une attaque. Par exemple, lorsqu'une dDoS est perpétrée par un botnet, il faut certes retrouver les zombies mais aussi identifier le contrôleur qui les commande. RID permet de demander un suivi de la trace des premiers, puis ensuite du second.

L'opérateur a typiquement un système de gestion centralisé de son réseau, un NMS. Le futur IHS (Incident Handling System) qui recevra et enverra les messages RID devra être intégré à ce NMS. La détection de l'attaque pourra se faire manuellement, ou via un IDS mais cette question est hors-sujet pour RID, qui se contente de permettre le signalement d'attaques, une fois celles-ci détectées.

Quelles sont les obstacles que rencontrent les tentatives de remonter à la source d'une attaque ? La section 2 en donne une liste, et c'est une lecture très recommandée pour comprendre la variété des problèmes auxquels fait face l'opérateur réseau lors d'une attaque. Par exemple, certaines attaques utilisent tellement peu de paquets qu'il est difficile de les répérer. D'autre part, pour prendre rapidement une « empreinte » des paquets utilisés pour l'attaque, les techniques à base d'une fonction de hachage ont souvent été utilisées (cf. « Hash-Based IP Traceback »). Or, certaines attaques ont un contenu des paquets qui varie énormément et il est difficile de trouver une « signature » qui permettrait de dire à l'opérateur précédent « Voici ce que je cherche ». Les nombreuses techniques de traceback pour IP ont été utilisées pour déterminer quelles étaient les informations importantes à inclure dans RID. Ainsi, il est essentiel d'inclure beaucoup d'informations dans le message RID car les champs significatifs et l'attaque, permettant de repérer les paquets, peuvent être n'importe lesquels. RID permet même d'envoyer la totalité du paquet, si nécessaire.

Une fois que le message RID est prêt, que fait-on pour la communication avec les autres opérateurs et avec les CSIRT ? Les sections 3.1 et 3.2 font remarquer que le courrier électronique n'est pas forcément adapté car il peut être trop lent. Mais, de toute façon, il faut prévoir plusieurs canaux de communication car, en cas d'attaque, certains deviendront peut-être inutilisables. Un réseau distinct de celui utilisé pour le trafic « normal » peut donc être nécessaire (voir plus loin le commentaire de la section 9). Le RFC suggère qu'on peut profiter des négociations qui précèdent un accord de peering pour mettre en place un canal de communication sécurisé.

Recommandation utile ou vœu pieux ? En tout cas, la section 3.1 rappelle également que RID ne devrait être utilisé que pour lutter contre des attaques, et pas pour perpétuer des sabotages (en dénonçant un innocent dans l'espoir qu'il se fasse filtrer) ou pour censurer.

Maintenant, place au format utilisé (section 4), fondé sur IODEF (RFC 5070). Il y a cinq messages RID possibles :

  • Request où on demande à un partenaire d'examiner son réseau pour voir d'où venait l'attaque (l'idée est que, partant de celui qui a détecté l'attaque, on envoit des Request successifs en remontant peu à peu vers la source de l'attaque). Le même message sert si on a déjà identifié la source et qu'on veut juste davantage d'information.
  • Report où on transmet de l'information, sans demander d'action immédiate.
  • Query où on demande des détails sur une attaque dont on a entendu parler (les deux derniers types de message sont typiquement pour la communication avec un CSIRT).
  • Acknowledgment et Result servent à porter les résultats intermédiaires ou finaux.

La section 4.2 décrit plus en détail chacun de ces types.

La section 7 fournit plusieurs jolis exemples, que j'ai simplifié ici. Par exemple, une Request envoyé par un CSIRT qui a détecté une DoS et qui demande à un opérateur réseau de tracer l'attaque. Le message est composé d'un document RID puis du document IODEF qui décrit l'attaque :


<iodef-rid:RID> <!-- Le schéma est enregistré en
http://www.iana.org/assignments/xml-registry/ns.html -->
  <iodef-rid:RIDPolicy MsgType="TraceRequest" 
                       MsgDestination="RIDSystem">
    <iodef:Node>
      <iodef:Address category="ipv4-addr">192.0.2.3</iodef:Address>
    </iodef:Node>
    <iodef-rid:TrafficType type="Attack"/>
    <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN">
      CERT-FOR-OUR-DOMAIN#207-1
    </iodef:IncidentID>
  </iodef-rid:RIDPolicy>
</iodef-rid:RID>
<!-- IODEF-Document accompanied by the above RID -->
<iodef:IODEF-Document>
  <iodef:Incident restriction="need-to-know" purpose="traceback">
    <iodef:DetectTime>2004-02-02T22:49:24+00:00</iodef:DetectTime>
    <iodef:StartTime>2004-02-02T22:19:24+00:00</iodef:StartTime>
    <iodef:ReportTime>2004-02-02T23:20:24+00:00</iodef:ReportTime>
    <iodef:Description>Host involved in DOS attack</iodef:Description>
    <iodef:EventData>
      <iodef:Flow>
        <iodef:System category="source">
          <iodef:Node>
            <iodef:Address category="ipv4-addr">192.0.2.35
...

Et la première réponse, qui indique que la demande de traçage a été approuvée :


<iodef-rid:RID>
  <iodef-rid:RIDPolicy MsgType="RequestAuthorization"
                       MsgDestination="RIDSystem">
    <iodef-rid:TrafficType type="Attack"/>
  </iodef-rid:RIDPolicy>
  <iodef-rid:RequestStatus AuthorizationStatus="Approved"/>
</iodef-rid:RID>

Et enfin la réponse finale :


<iodef-rid:RID>
  <iodef-rid:RIDPolicy MsgType="Result"
                       MsgDestination="RIDSystem">
    <iodef:Node>
      <iodef:Address category="ipv4-addr">192.0.2.67</iodef:Address>
    </iodef:Node>
    <iodef-rid:TrafficType type="Attack"/>
    <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN">
      CERT-FOR-OUR-DOMAIN#207-1
    </iodef:IncidentID>
  </iodef-rid:RIDPolicy>
  <iodef-rid:IncidentSource>
    <iodef-rid:SourceFound>true</iodef-rid:SourceFound>
    <iodef:Node>
      <iodef:Address category="ipv4-addr">192.0.2.37</iodef:Address>
    </iodef:Node>
  </iodef-rid:IncidentSource>
</iodef-rid:RID>
<!-- IODEF-Document accompanied by the above RID -->
<iodef:IODEF-Document>
  <iodef:Incident restriction="need-to-know" purpose="traceback">
    <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN">
      CERT-FOR-OUR-DOMAIN#207-1
    </iodef:IncidentID>
    <iodef:DetectTime>2004-02-02T22:49:24+00:00</iodef:DetectTime>
    <iodef:StartTime>2004-02-02T22:19:24+00:00</iodef:StartTime>
...
      <iodef:Expectation severity="high" action="rate-limit-host">
        <iodef:Description>
          Rate limit traffic close to source
        </iodef:Description>
      </iodef:Expectation>
      <iodef:Record>
        <iodef:RecordData>
          <iodef:Description>
            The IPv4 packet included was used in the described attack
          </iodef:Description>
          <iodef:RecordItem dtype="ipv4-packet">450000522ad9
          0000ff06c41fc0a801020a010102976d0050103e020810d9
          4a1350021000ad6700005468616e6b20796f7520666f7220
          6361726566756c6c792072656164696e6720746869732052
          46432e0a
          </iodef:RecordItem>
        </iodef:RecordData>
      </iodef:Record>
    </iodef:EventData>
    <iodef:History>
      <iodef:HistoryItem>
        <iodef:DateTime>2004-02-02T22:53:01+00:00</iodef:DateTime>
        <iodef:IncidentID name="CSIRT-FOR-OUR-DOMAIN">
          CSIRT-FOR-OUR-DOMAIN#207-1
        </iodef:IncidentID>
        <iodef:Description>
          Notification sent to next upstream NP closer to 192.0.2.35
        </iodef:Description>
      </iodef:HistoryItem>
      <iodef:HistoryItem action="rate-limit-host">
        <iodef:DateTime>2004-02-02T23:07:21+00:00</iodef:DateTime>
        <iodef:IncidentID name="CSIRT-FOR-NP3">
          CSIRT-FOR-NP3#3291-1
        </iodef:IncidentID>
        <iodef:Description>
          Host rate limited for 24 hours
        </iodef:Description>
      </iodef:HistoryItem>
    </iodef:History>
  </iodef:Incident>
</iodef:IODEF-Document>

L'entièreté du schéma XML, en xsd, figure en section 5.

Comme déjà noté, l'utilisation de ces messages RID ne va pas sans risques. La section 9 les analyse. D'abord, il faut évidemment un canal sécurisé pour les transmettre. Sécurisé au sens de :

  • Confidentiel, puisque les informations RID peuvent être très sensibles,
  • Fiable (disponible), puisque l'attaque rendra peut-être inutilisable les canaux normaux,
  • Authentifié, parce que ceux à qui on demande d'agir sur la base de messages RID voudront savoir à qui ils ont affaire.

Un canal physique dédié faciliterait l'obtention de ces propriétés mais n'est pas forcément réaliste. Le RFC recommande donc plutôt un tunnel chiffré. En combinant TLS sur le tunnel et les signatures XML du RFC 3275 sur le message, on atteint la sécurité désirée. Le protocole exact utilisé est normalisé dans un autre document, le RFC 6546. Bien qu'il utilise le chiffrement, RID ne repose pas uniquement sur la sécurité du canal et permet de chiffrer aussi le message par le chiffrement XML.

RID soulève aussi des questions liées à la protection de la vie privée et la section 9.5 les étudie. RID fournit le moyen de spécifier des détails comme l'extension du « domaine de confiance » à qui on peut envoyer les informations (élément PolicyRegion, section 4.3.3.3).


Téléchargez le RFC 6545


L'article seul

RFC 6544: TCP Candidates with Interactive Connectivity Establishment (ICE)

Date de publication du RFC : Mars 2012
Auteur(s) du RFC : J. Rosenberg (Skype), A. Keranen (Ericsson), B. Lowekamp (Skype), A. Roach (Tekelec)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mmusic
Première rédaction de cet article le 20 Mars 2012


Le protocole ICE, normalisé dans le RFC 5245, permet de traverser des obstacles comme les routeurs NAT, en essayant plusieurs techniques successives. ICE fonctionne en proposant une liste d'adresses candidates et en testant ensuite ces candidates (avec STUN, notamment) jusqu'à ce qu'on en trouve une qui passe. Dans le RFC originel sur ICE, ces candidates ne pouvaient être testées qu'en UDP. Désormais, notre RFC 6544 permet des candidates TCP (ainsi qu'un mélange des deux).

ICE vise surtout les applications pair-à-pair notamment pour le multimédia (par exemple, pour la télé-conférence). Pourquoi est-ce important de pouvoir faire du TCP ? La section 1 rappelle que certains protocoles ne marchent qu'avec TCP (comme le MSRP du RFC 4975) et que certains protocoles ont certes la possibilité d'utiliser UDP mais peuvent choisir TCP dans certains cas (RTP, RFC 4571, par exemple). C'est évidemment surtout utile dans le cas où on utilise TURN (RFC 5766), protocole qui est parfois le seul à passer certains routeurs NAT, en utilisant un relais TCP.

En général, pour les protocoles qui se servent d'ICE, UDP sera préférable (l'annexe A explique pourquoi). Dans les autres cas, ce nouveau RFC leur permet de faire enfin du TCP. (Et cette possibilité est désormais enregistrée à l'IANA.)

La section 3 résume les changements dans ICE liés à ce nouveau service. Mais c'est assez simple. Il y a trois sortes de candidats TCP, les actifs (qui vont ouvrir la connexion eux-mêmes), les passifs (qui attendent) et les S-O (Simultaneous Open) qui peuvent faire les deux. Dans la liste testée, le type du candidat est indiqué et ICE, pour tester une adresse, va évidemment les apparier en fonction du type (une adresse active avec une passive mais pas avec une autre active, par exemple). Le reste sera fait par de l'ICE normal, comme en UDP. Un petit piège : les messages STUN utilisés par ICE sont sur le même port que le trafic applicatif. Pour un protocole à messages comme UDP, il fallait donc marquer les messages pour les distinguer du trafic STUN. Pour un protocole à flot continu de données, comme TCP, il a fallu introduire un marquage, celui du RFC 4571 (conçu pour RTP mais qui peut être utilisé avec tout flot TCP).

Les détails de l'offre initiale figurent en section 4, par exemple la priorité accordée à UDP, lorsque le choix existe. S'il n'existe pas, on utilisera TCP, avec une adresse active, qui a plus de chances de pouvoir sortir du NAT.

Comme avec UDP, l'offre d'adresses candidates est encodée en SDP, avec un nouvel attribut pour différencier les adresses utilisées en TCP selon qu'elles soient actives ou passives. L'annexe C du RFC contient plusieurs exemples de descriptions SDP, par exemple, pour un appel audio :

   v=0
   o=jdoe 2890844526 2890842807 IN IP4 10.0.1.1
...
   m=audio 45664 TCP/RTP/AVP 0
...
   a=connection:new
   a=candidate:1 1 TCP 2128609279 10.0.1.1 9 typ host tcptype active
   a=candidate:2 1 TCP 2124414975 10.0.1.1 8998 typ host tcptype passive
   a=candidate:3 1 TCP 2120220671 10.0.1.1 8999 typ host tcptype so
...

Cet exemple ne montre que des candidats TCP, un de chaque sorte.

Et comment trouver toutes les adresses candidates possibles ? La section 5 donne quelques idées. Attention, plus il y a de candidates, et comme il faut tester chaque couple possible source/destination, plus les tests seront longs.

Les fanas de programmation noteront l'annexe B, qui explique que les opérations à effectuer avec ICE ne correspondent pas tout à fait à l'utilisation habituelle des sockets. Notamment, il s'agit, sur la même socket, d'initier des nouvelles connexions (vers le serveur STUN) et d'en recevoir (depuis les pairs distants). Le pseudo-code suivant est suggéré :

for i in 0 to MAX
      sock_i = socket()
      set(sock_i, SO_REUSEADDR)
      bind(sock_i, local) /* Réserver les "sockets" et les lier à un
      port */

   listen(sock_0)
   connect(sock_1, stun)
   connect(sock_2, remote_a)
   connect(sock_3, remote_b)

Téléchargez le RFC 6544


L'article seul

RFC 6541: DKIM Authorized Third-Party Signers

Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Kucherawy (Cloudmark)
Expérimental
Première rédaction de cet article le 1 Mars 2012


Depuis la sortie de la norme DKIM d'authentification du courrier électronique (originellement RFC 4871, désormais RFC 6376), il y a des incompréhensions sur ce que DKIM garantit réellement. Beaucoup d'utilisateurs croient que, lorsqu'un message prétend venir de joe@example.net et qu'il est signé par DKIM, on peut être sûr que le message vient de joe@example.net. Rien n'est plus faux. DKIM garantit tout autre chose. Il dit que l'identité du domaine signeur, dans le champ DKIM-Signature:, est correcte, et que ce domaine prend la responsabilité du message. Résultat, il y a un fossé entre ce qu'espère l'utilisateur et ce que DKIM livre effectivement. Ce RFC expérimental propose une solution pour combler ce fossé.

Voici une signature DKIM typique, envoyée par le service 23andme :


From: 23andMe Research Team <donotreply@23andme.com>
...
DKIM-Signature: v=1; q=dns/txt; a=rsa-sha256; c=relaxed/relaxed; s=132652; d=23andme.ccsend.com;
        h=to:subject:mime-version:message-id:from:date:sender:list-unsubscribe:reply-to;
        bh=87HtUCQR/Puz+14IeKPwOPzfeG32vY3BDJBMB74Kv+w=;
        b=Omftsz+Y3ZbbSbaPWZadKuy8aP35ttpXKTTPdjY4VGttx82q5igLb2r14U3sFI7a+9OXpKODHqOC3HKz1hPQ3GW1L...

On y voit que le domaine 23andme.ccsend.com prend la responsabilité de ce message (on peut vérifier l'authenticité de cette déclaration en vérifiant cryptographiquement la signature, qu'on a récupéré dans le DNS, pour le nom 132652._domainkey.23andme.ccsend.com) mais que le message dit avoir été envoyé par 23andme.com. Peut-on vérifier cette prétention ? Non, pas avec DKIM. Celui-ci ne fournit, et c'est un choix de conception délibéré, aucun mécanisme pour lier la signature à l'« identité » de l'émetteur (notez au passage que le concept d'identité d'un émetteur de courrier est déjà très flou).

Notre RFC 6541 propose un moyen de faire cette liaison : un domaine peut publier dans le DNS qu'il autorise des tiers à signer ses messages et à les garantir ainsi.

DKIM permettait déjà de déléguer la signature à des tiers (RFC 6376, sections 2.6 et 3.5) mais pas de dire « je fais entièrement confiance à tel domaine pour signer mes messages). C'est ce que fournit cette nouvelle norme, ATPS (Authorized Third-Party Signers).

Quels sont les parties en présence (sections 2 et 3) ?

  • L'émetteur du message est celui dont le domaine apparait dans le From: du message (RFC 5322).
  • Le signeur est un tiers autorisé à signer avec DKIM. Il met son propre domaine dans le champ d= de la signature.
  • Le vérificateur est le récepteur du message, qui voudrait bien vérifier que le message vient effectivement du domaine de l'émetteur.

Dans le monde réel, l'émetteur va par exemple être une entreprise avec une infrastructure de messagerie sommaire, ne permettant pas de signer, et le signeur ATPS va être son sous-traitant. Pour faire connaître cette relation d'affaires entre l'émetteur et son sous-traitant, ATPS permet à l'émetteur de publier dans le DNS un enregistrement TXT annonçant ce lien. Le vérificateur pourra alors récupérer cet enregistrement et se dire « le message est signé par provider.example, le message prétend être émis par customer.example, or le domaine customer.example contient bien un enregistrement ATPS désignant provider.example comme signeur autorisé  »

La section 4 contient les détails techniques du protocole. D'abord, quel va être le nom de l'enregistrement TXT dans le domaine émetteur ? (Au fait, l'annexe B explique pourquoi utiliser TXT et pas un nouveau type.) Il peut être directement le nom du domaine du signeur mais aussi une version encodée de ce nom. Ensuite, que contient la signature DKIM en cas d'utilisation d'ATPS ? Deux nouveaux champs, atps= et atpsh= (désormais dans le registre IANA) apparaissent. Si le champ d= contiendra, comme avant, le nom de domaine du signeur, le nouveau champ atps= contiendra le nom de domaine de celui pour lequel on signe, l'émetteur. Le vérificateur testera si la valeur d'atps= correspond à l'en-tête From: (ATPS est ignoré s'ils ne correspondent pas), fait une requête DNS pour le type TXT, et vérifie qu'on obtient bien une réponse positive.

Le nom de domaine interrogé pour le type TXT est, dans le cas le plus simple, le DOMAINE-SIGNEUR._atps.DOMAINE-ÉMETTEUR. Si atpsh= contient autre chose que none, alors DOMAINE-SIGNEUR est remplacé par un condensé de son nom.

S'il y a une réponse positive, c'est-à-dire un enregistrement TXT, c'est que c'est bon (pour plus de sécurité, l'enregistrement TXT doit contenir d=DOMAINE-SIGNEUR). Si on récupère NXDOMAIN (nom non existant) ou bien NOERROR mais pas d'enregistrement TXT, c'est que la vérification a échoué. Le signeur n'est en fait pas autorisé à signer pour l'émetteur (section 5). Le vérificateur peut prendre une décision comme de mettre un résultat d'authentification dans les en-têtes du message (cf. section 8.2 pour la création d'un nouveau type d'authentification, dkim-atps, mis dans le registre IANA créé par le RFC 5451).

Et les ADSP (Author Domain Signing Practices) du RFC 5617 ? Ce protocole permet à un domaine émetteur d'annoncer si ses messages sont signés ou non avec DKIM. La section 6 de notre RFC prévoit qu'ATPS doit être testé avant ADSP.

Ce RFC est seulement expérimental. L'idée même d'ATPS est fortement contestée (les questions de sécurité et de confiance sont toujours sensibles...) et le besoin s'est fait sentir d'un essai en vrai, pour déterminer si ATPS marche bien ou pas. ATPS est déjà mis en œuvre dans OpenDKIM (il faut configurer avec les options --enable-atps --enable-xtags), bibliothèque utilisée notamment par sendmail. Il inclut même un outil pour générer les enregistrements TXT. Les auteurs d'ATPS ont promis de tester et de décrire dans un document ultérieur le résultat de ces tests.

Quelques points particuliers de sécurité (section 9) :

  • La condensation des noms des domaines signeurs avant de faire la requête DNS ne vise pas à fournir la moindre confidentialité, mais simplement à obtenir des noms de taille fixe et connue, ce qui est plus pratique pour les requêtes DNS.
  • Et, naturellement, publier un enregistrement ATPS revient à sous-traiter une partie de sa sécurité au signeur. Comme toute sous-traitance, il faut donc bien vérifier à qui on fait confiance.

Notez que le RFC ne fournit pas un seul exemple complet de signature avec ATPS et je n'en ai pas encore trouvé dans ma boîte aux lettres.


Téléchargez le RFC 6541


L'article seul

RFC 6540: IPv6 Support Required for all IP-capable Nodes

Date de publication du RFC : Avril 2012
Auteur(s) du RFC : W. George (Time Warner Cable), C. Donley (Cablelabs), C. Liljenstolpe (Telstra), L. Howard (Time Warner Cable)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 13 Avril 2012


Il y a plusieurs façons de présenter ce RFC qui décrète que toute machine IP doit être capable de faire de l'IPv6. Le meilleur angle, je trouve, est de dire que c'est un RFC contre la publicité mensongère : dans l'Internet d'aujourd'hui, IP ne veut plus seulement dire IPv4. Vendre une machine ou un logiciel comme étant capable de parler IP, alors qu'elle ou il ne fait pas d'IPv6 est mensonger.

Bien sûr, en pratique, il est peu probable que ce RFC change grand'chose : les vendeurs continueront à fourguer des produits incapables de parler IPv6, protocole pourtant normalisé depuis seize ans, avec la sortie du RFC 1883 (depuis remplacé par le RFC 2460). Mais, au moins, ils ne pourront plus dire qu'il y avait une ambiguité et que certains RFC anciens parlent de « IP » pour désigner IPv4. Désormais, il est clair que « IP » veut dire IPv6 et (bien que le RFC ne le spécifie pas), si on est seulement IPv4, cela doit être annoncé comme tel et non pas sous l'étiquette « IP ».

Le succès d'IPv4 est incontestable. Il est désormais déployé absolument partout, malgré les vigoureuses oppositions des telcos traditionnels, relayés par pas mal de gouvernements (souvenez-vous des ridicules campagnes de promotion de l'ATM, censé barrer la route à IP). Mais c'est ce succès même qui a condamné IPv4. Le stock d'adresses disponibles est désormais épuisé. Un certain nombre de techniques ont été développées par acharnement thérapeutique, pour essayer de gagner encore quelques années, comme le NAT444. Toutes ont de sérieux inconvénients (cf. RFC 6269 pour un exemple).

La solution correcte, qui évite de fragiliser l'Internet par l'empilement de techniques de transition et/ou de coexistence est donc de déployer IPv6. Mais cela ne s'est pas fait tout seul. L'absence, ou la mauvaise qualité, de mise en œuvre d'IPv6 dans les logiciels a longtemps retardé ce protocole. Beaucoup de fournisseurs de logiciels se sont comportés comme si « IP » se réduisait à IPv4, IPv6 étant une addition possible mais facultative. Pendant de nombreuses années, Cisco exigeait une licence supplémentaire payante pour l'activation d'IPv6 dans IOS... Bref, des engins étaient vendus comme « IP » alors qu'ils n'étaient qu'« IPv4 ». Le problème continue aujourd'hui, empêchant la migration de progresser.

C'est particulièrement gênant dans le domaine des équipements proches du consommateur : ce dernier, à juste titre, ne se soucie pas de la version du protocole IP installé. IPv6 a été conçu justement pour ne pas changer le modèle de fonctionnement d'IP et il n'y a donc aucun avantage, pour M. Toutlemonde, à migrer vers IPv6. La migration, décision technique, ne devrait pas dépendre d'un choix explicite du consommateur, surtout si on le fait payer pour cela, comme le faisait Cisco. La migration devrait se faire au fur et à mesure que les vieilles machines et vieux logiciels sont remplacés, sans que M. Toutlemonde ne s'en rende compte.

À la décharge des vendeurs, il faut noter que tous les RFC, même ceux encore en vigueur, ne sont pas clairs là-dessus. Par exemple, le RFC 1812, qui établit les règles pour les routeurs IPv4, utilise souvent le terme IP pour désigner IPv4. Même chose pour le RFC 1122, qui normalise les machines terminales et ne mentionne pas IPv6. Aujourd'hui, le terme « IP », dans un RFC, peut indiquer IPv4 seul, IPv6 seul ou bien les deux.

À noter qu'IPv6 a aussi ses RFC de résumé des exigences, comme les RFC 4294 et RFC 6204.

La section 2 de notre RFC pose donc la règle : « IP implique IPv6 ». Plus précisément :

  • Les nouvelles mises en œuvre d'IP (ou les mises à jour majeures) doivent inclure IPv6.
  • La qualité du support IPv6 doit être égale ou supérieure à celle d'IPv4. On en est très loin aujourd'hui : poussés par des cahiers des charges qui exigent IPv6, certains vendeurs ajoutent un support minimum, permettant de cocher la case « IPv6 » lors de la réponse à un appel d'offres, mais en fournissant du logiciel bogué et lent.
  • L'activation ou la configuration d'IPv4 ne doit pas être nécessaire.

Évidemment, ce n'est qu'un RFC. Bien des vendeurs l'ignoreront. Espérons toutefois qu'il contribuera à une meilleure information des consommateurs.

Ce document était loin d'être consensuel à l'IETF. Beaucoup de gens critiquaient le principe même d'un document d'exhortation, qui risque fort de n'être qu'un rappel de plus. Toutefois, les partisans de ce document étaient actifs et les opposants ne voyaient pas d'inconvénients graves à la publication.


Téléchargez le RFC 6540


L'article seul

RFC 6538: HIP Experiment Report

Date de publication du RFC : Mars 2012
Auteur(s) du RFC : T. Henderson (Boeing), A. Gurtov (HIIT)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF hiprg
Première rédaction de cet article le 25 Mars 2012


Le protocole HIP, normalisé dans le RFC 4423, est maintenant stable depuis des années et a fait l'objet de plusieurs essais sur le terrain. Ce RFC de l'IRTF documente certains de ces essais concrets et indique les leçons à en tirer.

Le groupe de recherche hip de l'IRTF a travaillé sur ce sujet de 2004 à 2009. Pendant cette période, un certain nombre de mises en œuvre de HIP ont été programmées et plusieurs bancs de test ont été montés. La section 7 du RFC donne une liste exhaustive des expériences menées, notamment chez Boeing et dans le projet InfraHIP, qui gère des serveurs HIP publics. (Notez que, HIP fonctionnant au dessus d'IP, deux machines HIP peuvent communiquer au dessus de l'Internet public sans problème.) Ce RFC est le compte-rendu de ces expériences, sur les points suivants :

  • Implémenter HIP, qu'est-ce que ça coûte, comme efforts ?
  • Déployer HIP, quels sont les problèmes ?
  • Une fois que HIP marche, quelles conséquences pour les applications ?
  • Qu'en pensent les opérateurs ?
  • Et la vie privée, que va-t-elle devenir ?

D'abord, la mise en œuvre (section 2). HIP est un protocole pour les machines terminales, pas pour les routeurs. Implémenter HIP, c'est donc modifier Linux ou Windows, sans toucher à ses Cisco ou D-Link. Il existe aujourd'hui trois de ces modifications sous une licence libre :

L'expérience montre bien qu'implémenter un nouveau protocole n'est pas du yakafokon et que plein de pièges insoupçonnés se cachent dans le code. La section 2.1 résume ce qu'il faut modifier au noyau pour intégrer HIP. Les applications fonctionnent comme avant, un HIT (le condensat cryptographique d'une clé HIP) ayant la même forme qu'une adresse IPv6 (avec le préfixe ORCHID du RFC 4843). En section 2.2, c'est le cas d'une implémentation en dehors du noyau qui est couvert (notez que certaines mises en œuvre d'HIP sont mixtes, par exemple avec le traitement des paquets dans le noyau et la cryptographie dans un démon à part). Cela permet de faire fonctionner HIP sur des systèmes qu'on n'a pas le droit de modifier comme Microsoft Windows.

Dans tous les cas, quels ont été les problèmes rencontrés ? En l'absence de système de résolution, manipuler les HIT à la main, se les échanger, etc, a été pénible. Des systèmes de résolution existent désormais (mettre les HIT dans le DNS sous forme d'enregistrements AAAA, comme le propose le RFC 5205, utiliser une DHT dédiée à HIP, etc) et OpenHIP les a tous programmés. Et il y a aussi le mode opportuniste de HIP, où on se connecte sans connaître a priori le HIT du pair. Mais aucune solution n'est à 100 % parfaite.

Le mode opportuniste du RFC 5201, section 4.1.6 a posé des problèmes avec l'interface sockets, car le HIT du pair distant n'est pas encore connu au moment du connect(). De toute façon, ce mode a l'inconvénient de ne pas être très sécurisé (il fonctionne en mode TOFU - Trust On First Use - puisque, la première fois qu'on parle à un pair, on doit accepter son HIT en lui faisant une confiance aveugle). HIPL a mis en œuvre ce mode. OpenHIP également, avec une option explicite (-o), débrayée par défaut. Le problème de sécurité est particulièrement crucial lorsqu'il s'agit d'applications traditionnelles, qui ne connaissent pas HIP et ne peuvent donc pas formuler de souhaits, ou interactivement demander confirmation à l'utilisateur, ce que peuvent faire les applications récentes qui utilisent le RFC 6317.

Quant au DNS, certains administrateurs de zones DNS n'ont pas aimé qu'on mette des HIT sous le nom d'AAAA, arguant que c'était un détournement de la sémantique du AAAA.

Autre problème, lorsqu'on connait le HIT du pair (on ne fait donc pas de mode opportuniste) mais pas son adresse IP. Pour lui envoyer des paquets, il faudra alors une résolution, pour trouver cette adresse. Des essais ont été faits avec OpenDHT, ou bien avec le DNS. HIPL a même tenté, pour le cas particulier du LAN, d'envoyer un paquet de diffusion, un peu comme on fait en NDP. Cela a paniqué certains antivirus Windows qui considéraient toute diffusion avec un protocole inconnu comme un danger.

Parmi les nombreuses autres questions que décrit le RFC en tenant compte de l'expérience des programmeurs HIP, celui de la gestion des HI (Host Identifiers, l'identité d'une machine HIP, dont le HIT est le condensat cryptographique). Une machine peut avoir plusieurs identités (par exemple pour protéger la vie privée, voir plus loin), et laquelle doit-elle utiliser lorsqu'elle se connecte à un pair ? Dans quelle mesure le choix doit-il être fait par l'utilisateur ? (Intéressant problème d'interface.) Plus gênant, puisque HIP repose sur des clés cryptographiques, comment stocker les clés privées sur la machine ? Toutes les implémentations actuelles utilisent un fichier appartenant à root en mode 0600 (ce qui interdit la lecture par les utilisateurs ordinaires). Cela ne suffit pas si, par exemple, un attaquant a un accès physique à la machine. La solution serait alors de stocker les clés dans un TPM mais aucune mise en œuvre de HIP n'a encore tenté le coup.

Cette section comprend également un problème qui, à mon avis, est plutôt de déploiement que de programmation, l'interaction avec les pare-feux. HIP est un protocole (le numéro 139 des protocoles IP, TCP étant 6, UDP 17 et OSPF 89) marqué comme expérimental et qui est globalement peu connu. Il n'y a donc pas de règle pour lui dans les règles configurées par défaut et le pare-feu refusant tout ce qui n'est pas explicitement autorisé, les paquets HIP se retrouvent bloqués. Il n'est pas forcément trivial de modifier les règles sans tout casser (le RFC rapporte que celles par défaut de SUSE ont plus de cent entrées) et, de toute façon, l'utilisateur qui veut déployer HIP n'a pas forcément le contrôle du pare-feu. Heureusement, HIP peut tourner sur UDP (au lieu de directement sur IP) ce qui limite les problèmes.

Bien que HIP ait été surtout conçu pour IPv6, et que son déploiement massif ne semble pas devoir précéder celui d'IPv6, toutes les mises en œuvre de HIP ont choisi de gérer également IPv4. Comme on ne peut absolument pas faire rentrer un condensat cryptographique sérieux dans les 32 bits d'une adresse IPv4, il faut ajouter le concept de LSI (Local Scope Identifier), un alias local à la machine pour référencer un HI donné.

Plus amusant, HIP permet également de faire tourner des applications IPv6 sur un réseau IPv4 (et réciproquement), ce qui fonctionne sur tous les codes cités.

Bref, les programmeurs ont bien travaillé et HIP fonctionne sur plusieurs plate-formes. Quelles leçons peuvent être tirées ? Il n'y a pas eu beaucoup de tests de performances, notamment pour comparer les implémentations en mode noyau et en mode utilisateur. Il semble que, sur une machine généraliste et pour des usages typiques, le mode utilisateur (le plus lent) est acceptable.

Le choix entre les deux modes peut dépendre de bien d'autres choses. Par exemple, HIPL avait une mise en œuvre des fonctions de gestion de clés dans le noyau, mais les développeurs du noyau Linux l'ont rejeté, arguant que d'autres protocoles comme IKE faisaient cette gestion en mode utilisateur et qu'il n'y avait pas de raison de l'intégrer dans le noyau. (Il faut dire aussi que c'était un gros patch, qui touchait à beaucoup d'endroits du noyau.)

La section 3 aborde ensuite les points liés au déploiement, notamment à l'effet sur les infrastructures. La section sur le DNS (extensions HIP du RFC 5205) est curieusement incompréhensible (qu'est-ce qu'un binary blob format ?) mais, de toute façon, les serveurs DNS peuvent servir des types de données qu'il ne connaissent pas, donc peu de problèmes à attendre.

Plus sérieux, le cas des middleboxes. Les NAT sont hostiles à HIP comme à beaucoup de choses (problème décrit dans le RFC 5207). HIP peut par exemple chiffrer même la connexion initiale, empêchant le routeur NAT de comprendre ce qui se passe. Le mécanisme de rendez-vous du RFC 5204 pourrait aider à résoudre les problèmes du NAT mais il n'a pour l'instant été testé qu'en laboratoire.

Et l'infrastructure de résolution ? Une mise en œuvre de résolution de HIT en adresses IP via OpenDHT a été faite pour HIPL et OpenHIP. OpenDHT est désormais arrêté mais un nouveau projet a pris le relais, Hi3, qui tourne sur PlanetLab. Au cours des premiers essais, le déboguage s'est révélé très pénible, et les middleboxes qui bloquent tout une énorme source de frustration.

Une solution d'avenir pourrait être de mêler DNS (déploiement massif, compatibilité avec le logiciel existant) et DHT (bonne résistance aux pannes, bonne efficacité même dans un espace plat, celui des clés cryptographiques). Par exemple, une organisation ferait tourner une DHT pour stocker les HI ou les HIT de ses machines, connectée avec le DNS pour les clients extérieurs. Ensuite, ces DHT locales pourraient être interconnectées petit à petit. Un test a été fait en modifiant BIND pour qu'il interroge une DHT (Bamboo) pour les HIT. Les performances ont été plutôt mauvaises, et se dégradant vite avec la charge, donc des travaux supplémentaires sont nécessaires.

Et pour les applications  ? L'expérience du déploiement d'IPv6 a montré qu'il était plus facile de mettre à jour l'infrastructure que les applications. La section 4 explore les conséquences de HIP sur celles-ci. Il y a deux sortes d'applications : celles qui connaissent HIP et celles qui ne le connaissent pas (la quasi-totalité, aujourd'hui : le RFC 5338 explique comment faire tourner HIP avec les applications traditionnelles).

Par exemple, HIPL a testé une bibliothèque dynamique (chargée avec LD_PRELOAD) qui change le comportement du résolveur, permettant aux applications de se connecter à un pair HIP sans s'en rendre compte. Un Firefox et un Apache non modifiés ont ainsi pu se parler en HIP. L'avantage de cette méthode est de permettre de choisir, application par application, qui va faire du HIP (cette finesse de choix pouvant être considérée comme un avantage ou comme un inconvénient). Une autre solution serait de passer par des relais applicatifs mais elle ne semble pas avoir été testée encore.

HIP a même réussi à fonctionner avec des applications qui utilisent des références (passer son adresse IP au pair pour qu'il vous envoie ensuite des messages) comme FTP. D'autres applications seraient peut-être moins tolérantes mais, de toute façon, en raison du NAT, les applications qui se servent de références ont déjà beaucoup de problèmes dans l'Internet d'aujourd'hui.

Une des raisons pour lesquelles il peut être intéressant de mettre une gestion de HIP explicite dans les applications est la performance : l'établissement d'une connexion est plus long en HIP et certaines applications (par exemple un navigateur Web) peuvent être très sensibles à cette latence supplémentaire. Elles pourraient alors choisir de laisser tomber la sécurité de HIP au profit de la vitesse.

Continuons dans les problèmes concrets : quelle va être l'expérience de l'administrateur réseaux qui, le premier, tentera de déployer HIP ? Pour l'instant, aucun ne l'a fait mais. HIP peut tourner entièrement dans les machines terminales, sans que le réseau soit impliqué. Si celui-ci l'est, il aura peut-être les problèmes suivants (détaillés en section 5) :

  • Choix des HI (Host Identities). Celles-ci peuvent être générées par les machines toutes seules, et c'est comme cela que tout le monde fait aujourd'hui. Mais certains administrateurs pourraient préférer le faire eux-même, de manière à connaître les HI de leur réseau. Par exemple, ils généreraient les HI, les signeraient éventuellement avec leur PKI, et les mettraient dans une base AAA, exportant ensuite la configuration d'équipements comme les pare-feux.
  • Le monde étant ce qu'il est, la sécurité que fournit HIP, surtout en combinaison avec le mode ESP d'IPsec (qui est très intégrée à HIP) peut ne pas plaire à tout le monde. Si Big Brother veut espionner le trafic, que va pouvoir dire l'administrateur réseaux ? Le groupe de recherche HIP n'a pas trouvé de solution à ce dilemne.
  • Autre question posée par le chiffrement, celui de la consommation de ressources, notamment pour les engins les moins pourvus comme les smartphones. Toutefois, au cours d'essais HIP et ESP avec une tablette Nokia N770, les performances sont restées acceptables (3,27 Mb/s en WiFi contre 4,86 sans HIP ni ESP). Le RFC ne dit pas quelle a été la consommation électrique....
  • Autre problème typique d'administrateur réseaux, le filtrage. Aujourd'hui, le filtrage va souvent contre la sécurité, par exemple bien des pare-feux bloquent IPsec ou HIP. Normalement, HIP améliore la sécurité puisqu'on peut authentifier les HI (les identités des machines, celles-ci signant leurs paquets). Il ne reste plus qu'à configurer les ACL du pare-feu pour filtrer en fonction du HI. Notons que, contrairement aux adresses IP, celles-ci ne sont pas agrégeables en préfixes et il faut donc typiquement une ACL par machine. Quant au filtrage par nom et plus par HI, il dépend d'un enregistrement sécurisé des HI dans le DNS, qui n'est pas disponible à l'heure actuelle.
  • Ceci n'a pas empêché l'université de Technologie d'Helsinski de modifier iptables pour produire un pare-feu HIP. Cela nécessite un état car le pare-feu doit se souvenir de l'échange initial HIP pour reconnaître ensuite les paquets chiffrés liés à cette session (le SPI IPsec figure dans les paquets HIP I2 et R2).

La section 6 du RFC s'attaque ensuite à un difficile problème, celui de la vie privée des utilisateurs. HIP permet enfin de doter chaque machine sur l'Internet d'une véritable identité, indépendante de sa position dans le réseau, qu'on peut vérifier avec la cryptographie. Mais ce gain en sécurité peut se payer en terme de vie privée : si mon ordinateur portable a HIP, je me connecte à un site Web HIP depuis chez moi, et depuis l'hôtel et, sans cookies ou autres techniques de suivi Web, le serveur peut reconnaitre que c'est la même machine (les adresses autoconfigurées d'IPv6 avaient un problème du même genre, qui a été résolu par le RFC 4941).

Pire, dans certains cas, un tiers qui écoute le réseau peut apprendre l'identité des deux machines, même si le reste de la session est chiffré.

HIP permet d'utiliser des HIT non publiés (RFC 5201, sections 5.1.2 et 7) mais cela suppose que le destinataire les accepte (ce qui serait logique pour un serveur public, qui ne se soucie pas en général de l'identité de ses clients). Globalement, la protection de la vie privée dans HIP n'est pas encore suffisante mais des travaux sont en cours. Mon opinion personnelle est que la meilleure solution serait analogue à celle du RFC 4941 : des identificateurs jetables, créés pour une courte période (voire pour une seule session) et abandonnés après. Cela nécessite de faire attention aux autres identificateurs (comme l'adresse IP) qui doivent changer en même temps que le HI (sinon, l'attaquant pourrait faire le rapprochement). L'Université Technologique d'Helsinski a déjà une mise en œuvre expérimentale de cette idée.

HIP n'est pas la seule architecture de séparation du localisateur et de l'identificateur. La section 8 du RFC résume les autres expériences en cours. Il ne va pas de soi que cette séparation soit une bonne idée. C'est même un point de vue très controversé, comme l'avait montré l'échec du NSRG (Name Space Research group). Parmi les efforts récents :

  • Les groupes de travail multi6 et shim6 qui ont mené au RFC 5533, solution qui a des ressemblances avec HIP (d'ailleurs, OpenHIP implémente à la fois HIP et shim6), ce qui a permis de concevoir des API proches (RFC 6316 et RFC 6317).
  • Le groupe de recherche RRG a exploré de nombreuses solutions pour le routage de demain, comme LISP ou ILNP, documentant le résultat dans le RFC 6115.

Téléchargez le RFC 6538


L'article seul

RFC 6537: Host Identity Protocol Distributed Hash Table Interface

Date de publication du RFC : Février 2012
Auteur(s) du RFC : J. Ahrenholz (Boeing)
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF hiprg
Première rédaction de cet article le 1 Mars 2012


Dans tout protocole réseau séparant le localisateur et l'identificateur, il y a une grosse question : comment relier les deux ? Comment, lorsqu'on ne connait que l'identificateur d'une machine, trouver son localisateur afin de lui envoyer un paquet ? Le protocole HIP a plusieurs solutions possibles et ce RFC de l'IRTF en propose une nouvelle : faire appel à une DHT.

Dans HIP, l'identificateur est la partie publique d'une clé cryptographique, et le localisateur une adresse IP. Notre RFC 6537 propose de stocker la correspondance entre les deux dans une DHT. En outre, un second service est proposé, celui permettant de trouver l'identificateur à partir d'un nom de domaine. En fait, ce RFC ne décrit pas tellement la DHT, mais simplement l'interface entre la machine HIP et un service de résolution (qui pourrait aussi bien être mis en œuvre autrement ; le titre du RFC est donc trompeur).

Pourquoi, d'ailleurs, une DHT ? Comme l'expose la section 1, une des bonnes raisons est que l'espace de nommage des identificateurs est plat : il n'y a pas de hiérarchie permettant des résolutions efficaces comme avec le DNS. Les DHT permettent justement de résoudre des noms situés dans un espace plat aussi efficacement que les protocoles reposant sur des noms hiérarchiques.

Petit détail au passage, le protocole de ce RFC n'utilise pas directement les identificateurs (HI pour Host Identifier) mais leur condensat, le HIT (Host Identifier Tag). Il y a donc deux services, nom->HIT et HIT->adresses.

Le DNS est très optimisé depuis longtemps (et il existe un autre travail en cours pour résoudre les identificateurs HIP en localisateurs avec le DNS) mais explorer de nouvelles techniques est toujours intéressant. Il s'agit donc d'un travail plutôt expérimental, où plein de questions n'ont pas encore de réponse.

Une expérience concrète a été faite en utilisant la DHT Bamboo, écrite en Java, et qui formait la base du service OpenDHT (service qui tournait sur PlanetLab et a été fermé en 2009). Comme toute DHT, ou d'ailleurs comme toute table (les dictionnaires de Python, les hashes de Perl, les java.util.Dictionary de Java, etc), OpenDHT fournissait trois primitives, put, get et remove. La première permet de stocker une valeur, sous un certain index (on dit souvent « clé » mais je l'ai évité pour ne pas risquer une confusion avec les clés cryptographiques), la seconde de récupérer une valeur dont on connait l'index, et la troisième (rm dans la documentation) de supprimer une valeur. Dans OpenDHT, ces trois primitives étaient appelées via le protocole XML-RPC.

La section 2 décrit précisement cette interface XML-RPC. Elle avait été choisie parce qu'OpenDHT fournissait un service simple et gratuit accessible aux chercheurs. Les index pouvaient avoir jusqu'à 20 octets, les valeurs jusqu'à 1024. Toutes les entrées étaient temporaires, OpenDHT les supprimant au plus une semaine après leur insertion (un problème classique des DHT et du pair-à-pair en général est sa vulnérabilité aux méchants, ici à des machines insérant des quantités énormes de données pour faire une DoS).

Outre les paramètres cités plus haut (l'index et la valeur pour put, l'index pour get et rm), OpenDHT imposait quelques autres paramètres comme le TTL du précédent paragraphe, comme un identifiant de l'application, ou comme un mot de passe permettant de fournir un peu de sécurité.

Une fois qu'on a compris l'interface XML-RPC d'OpenDHT et ses paramètres, comment l'utilise-t-on pour HIP ? C'est l'objet de la section 3 et des suivantes. D'abord, on définit en section 3 une structure de données, le HDRR (HIP DHT Resource Record). Son format binaire est le même que celui d'un paquet HIP (RFC 5201, section 5, le HDRR a le numéro 20 dans le registre IANA), c'est-à-dire essentiellement une suite de paramètres encodés en TLV. Il n'a donc rien à voir avec le Resource Record DNS du RFC 5205.

Ces paramètres sont surtout des HI (Host Identifier, identificateurs), des HIT (rappelez-vous que c'est un condensat cryptographique du HI) et des localisateurs (les adresses IP, v4 ou v6). On peut aussi y trouver un certificat, au format du RFC 6253 ou une signature HIP. Ces deux derniers paramètres pourraient, dans une DHT spécialisée, être utilisée pour vérifier que la machine qui enregistre un localisateur pour un identificateur donné est bien autorisée à le faire (cd. RFC 4843, c'est une des forces de HIP, que d'avoir des clés cryptographique comme identificateur, cela permet de signer ses paquets et d'éviter ainsi l'usurpation). Toutefois, cela n'est pas mis en œuvre dans Bamboo, DHT généraliste qui ne sert pas qu'à HIP. Le problème de la DHT spécialisée en HIP est de toute façon plus complexe que cela : par exemple, les vérifications cryptographiques nécessaires faciliteraient une éventuelle attaque par déni de service contre la DHT (HIP évite ce problème par un protocole d'établissement de connexion conçu à cet effet, cf. RFC 5201, section 4.1.1).

Puis, la section 4 décrit le protocole de requête. Il fournit deux services :

  • Étant donné un nom, trouver le HIT. Le nom est typiquement un FQDN. Notez que le RFC 5205 fournit une autre solution à ce problème, en utilisant le DNS.
  • Étant donné un HIT, trouver le ou les localisateurs.

Il n'y a pas de requête directe du nom vers les localisateurs. La première correspondance, nom->HIT, est supposée relativement stable (une machine HIP n'a guère de raisons de changer d'identificateur). La seconde correspondance est typiquement variable, voire très variable en cas de mobilité (RFC 5206).

Le reste, ce sont des détails techniques. Par exemple, l'index utilisé pour la requête à la DHT dans le premier cas n'est pas réellement le nom mais un SHA-1 du nom car les index OpenDHT sont limités à vingt octets. Autre point qu'il a fallu régler, les HIT sont typiquement représentés comme des adresses IPv6 ORCHID (RFC 4843), et donc tous les HIT commencent par les mêmes 28 bits (la longueur du préfixe ORCHID). Pour une DHT, qui utilise un hachage des index pour trouver le nœud responsable du stockage des données correspondantes, cela risquerait de causer une répartition très inégale, certains pairs de la DHT étant plus chargés que d'autres. Lors de la deuxième requête (HIT->localisateurs), on n'utilise donc comme index que les 100 derniers bits du HIT.

Une fois ces détails de syntaxe réglés, la section 5 décrit la chorégraphie des requêtes. D'abord, pour trouver un identificateur (ou bien son HIT) à partir d'un nom de domaine, faut-il utiliser le DNS, comme le prévoit le RFC 5205 ou bien le service DHT décrit dans ce RFC 6537 ? La réponse dépend des cas. Tout le monde n'a pas forcément le contrôle des serveurs de noms du domaine souhaité et, même si c'est le cas, tous les serveurs de noms ne permettent pas forcément d'ajouter des enregistrements DNS de type HIP dans leur domaine (testez avec l'interface de votre hébergeur DNS pour voir...) Donc, la solution DHT est intéressante au moins dans ces cas.

On l'a vu, les localisateurs changent, c'est normal. Quand faut-il faire la requête HI->localisateur ? Si on la fait très à l'avance, les localisateurs seront peut-être usagés lorsqu'on s'en servira. Si on la fait au moment de la connexion, on peut ralentir celle-ci de manière intolérable. Le RFC suggère donc de faire les requêtes à l'avance, et, si la première tentative de connexion échoue, de refaire une requête de résolution avant de tenter la deuxième connexion.

Les informations enregistrées dans OpenDHT ont une durée de vie (le paramètre ttl de la requête, mais la DHT peut aussi supprimer les données avant l'expiration de celui-ci, par exemple s'il faut faire de la place). Une machine HIP doit donc penser à mettre à jour régulièrement ses entrées dans la DHT, pour s'assurer qu'il y a toujours quelque chose. Et, naturellement, si l'information change, la machine doit prévenir la DHT dès que possible.

La DHT étant globale, les adresses IP privées (RFC 1918) ne doivent pas être publiées dans la DHT. Si une machine HIP est coincée derrière un routeur NAT, elle doit, si elle veut être contactée, enregistrer l'adresse du serveur HIP de rendez-vous (RFC 5204).

OpenDHT présentait quelques particularités qui pouvaient surprendre la machine HIP tentant de stocker ses identificateurs et localisateurs. Par exemple, un put ne remplace pas la donnée précédente, il s'y ajoute. Et rien ne garantit que l'ordre dans lequel seront renvoyés les HDRR sera celui dans lequel ils ont été insérés. Il faut donc identifier le plus récent (le HDRR a un paramètre Update ID, dont je n'avais pas encore parlé, juste pour cela). Le mieux serait de penser à faire le ménage et virer explicitement ses vieilles informations.

Notez d'ailleurs que, le nom n'étant pas authentifié, on peut voir plusieurs machines s'enregistrer sous le même nom. En attendant un système d'authentification du nom (certificat X.509 portant ce nom en sujet ?), il est recommandé de tester et de choisir un autre nom, si celui qu'on voulait est déjà pris (ce qui ne devrait pas arriver, avec les noms de domaine, mais la DHT ne vérifie pas que celui qui enregistre www.google.com a le droit).

Autre problème pratique, le choix de la passerelle XML-RPC vers OpenDHT. Il en existait plusieurs, d'une fiabilité douteuse (OpenDHT était un projet de recherche, qui ne visait pas à fournir un service fiable à 100 %) et le client doit donc être prêt à détecter une panne et à passer sur une autre passerelle (OpenDHT fournissait un service anycast, opendht.nyuld.net, qui facilitait cette tâche.)

À propos de qualité de service, le RFC note aussi qu'OpenDHT ne garantissait pas de temps de réponse, et que les opérations put et get peuvent être lentes, ce à quoi les clients de la DHT doivent se préparer.

Pour approfondir davantage les questions de sécurité (point faible classique de toutes les DHT), la section 7 fait un examen complet des problèmes que pose cette solution. Concernant le contenu de l'information, l'attaque peut être menée par un client de la DHT qui enregistre délibérement des informations fausses, ou bien par un pair participant à la DHT qui modifie les informations avant de les rendre. En l'absence d'un mécanisme tiers d'authentification des données (la DHT de CoDoNS utilisait DNSSEC pour cela), il n'y a pas grand'chose à faire. On l'a dit, c'est un problème récurrent avec toutes les DHT. Le RFC dit que les paranoïaques n'ont pas d'autres solutions que d'échanger les HIT à la main (ensuite, même si la DHT renvoie de mauvais localisateurs, le protocole HIP permettra de vérifier qu'on ne se connecte pas à une machine pirate). Dans le futur, une solution serait peut-être d'utiliser des certificats numériques.

Je l'ai dit, le protocole HIP garantit au moins, par la signature des paquets échangés lors de la connexion, qu'on se connecte bien à la machine possédant l'identificateur voulu. Pour un attaquant, enregistrer dans la DHT de fausses correspondances HIT->localisateur ne permet donc pas de détourner vers une machine pirate. Pour ce stade, la seule possibilité de l'attaquant est d'enregistrer plein de correspondances bidons, pour faire une attaque par déni de service.

La seule solution à long terme à cette attaque serait que la DHT vérifie les données avant de les enregistrer, et donc connaisse HIP. Elle pourrait tester que la signature incluse dans la requête corresponde à la clé publique (l'identificateur). Cette vérification laisserait la DHT vulnérable à d'autres attaques par déni de service, où l'attaquant ferait beaucoup de requêtes et imposerait donc beaucoup de vérifications. Pour parer cela, on peut imaginer une DHT qui impose que ses clients la contactent en HIP, réutilisant ainsi les protections anti-DoS de HIP. Et cela permettrait de s'assurer que le client n'enregistre des localisateurs que pour lui.

À noter enfin que OpenLookup est un exemple d'un service fournissant la même interface qu'OpenDHT même si, derrière, ce n'est pas une DHT.


Téléchargez le RFC 6537


L'article seul

RFC 6534: Loss Episode Metrics for IPPM

Date de publication du RFC : Mai 2012
Auteur(s) du RFC : N. Duffield (AT&T Labs-Research), A. Morton (AT&T Labs), J. Sommers (Colgate University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 7 Mai 2012


Le RFC 2680 définissait une métrique (une grandeur mesurable et spécifiée rigoureusement) pour le taux de pertes de paquets entre deux points du réseau. Mais un certain nombre de logiciels ne sont pas sensibles uniquement à la moyenne du taux de pertes mais aussi à sa répartition. Sur un flot de cent paquets, ce n'est pas la même chose d'en perdre trois, répartis au hasard, et d'en perdre trois de suite, par exemple pour certains protocoles multimédia qui encodent les différences entre paquets. Ce nouveau RFC définit donc des métriques pour caractériser les épisodes, ces pertes consécutives de paquets.

Par exemple, au taux de pertes moyen du RFC 2680, il serait intéressant d'ajouter la durée maximale d'un épisode, ou bien la durée moyenne d'un épisode. Prenons les deux flots suivants, où OK indique un paquet arrivé et LOST un paquet perdu : OK - OK - LOST - LOST - LOST - OK - OK - OK - LOST - OK, puis LOST - OK - LOST - OK - LOST - OK - LOST - OK - OK - OK.Le taux de pertes moyen (Type-P-One-way-Packet-Loss-Average du RFC 2680) est de 0,4 (40 % de paquets perdus) dans les deux cas. Mais la longueur maximale d'un épisode est de 3 dans le premier cas et de 1 dans le second, ce qui peut être important pour certains protocoles, et n'apparaissait pas dans la moyenne. Ainsi, un flux MPEG comporte des trames plus importantes que les autres, les I-frames, et la perte de paquets immédiatement consécutifs à la perte d'une I-frame est peu importante (sans la I-frame, ils ne servent à rien).

Première leçon à tirer de ce simple exemple, la notion de perte de paquets est une notion complexe dans l'Internet, où le trafic connaît des pics brutaux. Le modèle trivial de Bernoulli, où chaque perte est indépendante des autres, est clairement inadapté. De la même façon, comme illustré au paragraphe précédent, la simple moyenne n'est pas une description quantitative suffisante du phénomène. Des modèles plus markoviens ont été proposés (voir section 7), avec la notion d'épisode (période pendant laquelle on perd tous les paquets), en modélisant par des transitions entre une période normale et un épisode de pertes. Des RFC comme le RFC 3357 ou le RFC 3611 avaient déjà exploré cette voie. Mais ces modèles ne semblent pas avoir démontré d'intérêt pratique. L'approche de notre RFC est plus empirique : observer et quantifier le phénomène, sans chercher à le modéliser. Plusieurs mesures ont déjà été proposées comme l'IDC (Index of Dispersion of Counts) mais avec peu de succès. Notre RFC représente donc une nouvelle tentative pour décrire ce phénomène.

Ce RFC 6534 utilise des paires de paquets, l'intervalle entre deux paquets indiquant la résolution temporelle de la mesure (les épisodes plus courts que cet intervalle ne seront pas vus). Première métrique définie, qui sert de base (section 2), Type-P-One-way-Bi-Packet-Loss. (Un Bi-Packet = une paire.) La mesure donne (0, 0) si les deux paquets sont arrivés, (1, 1) si les deux sont perdus, etc. (Ce n'est peut-être pas intuitif mais le chiffre binaire indique s'il y a eu une perte, donc 0 signifie le succès de la transmission.)

Ensuite, comme pour le RFC 2680, des métriques moins élémentaires et plus utiles sont spécifiées à partir de celle-ci. La section 3 définit Type-P-One-way-Bi-Packet-Loss-Stream, une suite de résultats de la métrique précédente. Pour le premier exemple de cet article, ce sera ((0, 0), (0, 1), (1, 1), (1, 1), (1, 0), (0, 0), (0, 0), (0, 1), (1, 0)). (0, 1) indique une transition vers un épisode de perte, (1, 0) la fin de cet épisode. La section 4 précise la même suite pour le cas où les intervalles de temps entre paquets forment une distribution géométrique.

Jusque là, l'intérêt pratique de ces définitions semble faible. Avec la section 5, on en arrive presque à des métriques utilisables (mais patientez encore un peu, le RFC parle de « proto-métriques » pour la section 5). Par exemple, Loss-Pair-Counts indique les fréquences de chaque paire (dans l'exemple précédent 2/9 - 22 % - de (1, 1), 3/9 de (0, 0), 2/9 de (1, 0) et 2/9 de (0, 1). Bi-Packet-Loss-Episode-Duration-Number, elle, caractérise la longueur des épisodes (2 ici, car on ne compte pas le premier paquet des épisodes de perte).

Et ensuite, en section 6, on définit les métriques de plus haut niveau, la Type-P-One-way-Bi-Packet-Loss-Geometric-Stream-Ratio pour le pourcentage de paquets perdus, la Type-P-One-way-Bi-Packet-Loss-Geometric-Stream-Episode-Duration pour la durée (en secondes) des épisodes, la Type-P-One-way-Bi-Packet-Loss-Geometric-Stream-Episode-Frequency la fréquence des épisodes de perte, etc.

Voilà, nous avons maintenant nos métriques (je vous ai épargné la définition rigoureuse, indispensable mais aride : lisez le RFC pour la connaître).

Ah, un mot pour les juristes : il y a même eu des requins pour breveter des métriques, et des bureaux des brevets pour l'accepter. Voir la déclaration #1354.


Téléchargez le RFC 6534


L'article seul

RFC 6533: Internationalized Delivery Status and Disposition Notifications

Date de publication du RFC : Février 2012
Auteur(s) du RFC : C. Newman (Sun Microsystems), A. Melnikov (Isode)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 18 Février 2012


Dans l'ensemble des RFC sur l'internationalisation des adresses de courrier électronique, ce document traite le cas des accusés de réception (MDN, pour Message Disposition Notification) et avis de non-remise (DSN pour Delivery Status Notification).

Puisque les RFC 6531 et RFC 6532 permettent désormais d'utiliser des adresses de courrier électroniques internationalisées, c'est-à-dire utilisant tout le jeu de caractères Unicode, il faut prévoir le cas où les courriers provoquent l'envoi d'avis de remise ou de non-remise (DSN pour Delivery Status Notification, RFC 3461 et RFC 3464) et d'accusés de réception (MDN, pour Message Disposition Notification, RFC 3798). C'est l'objet de ce RFC, qui met à jour les anciens documents qui limitaient ces accusés et avis au jeu ASCII. Il fait suite au RFC 5337, qui n'était qu'expérimental. Désormais, les adresses de courrier en Unicode font partie des normes de l'Internet.

Le format des DSN dans le RFC 3464 parle de « types d'adresse ». Les adresses en UTF-8 du RFC 6532 sont un nouveau type d'adresses. Si le serveur SMTP accepte l'extension SMTPUTF8 du RFC 6531 et l'extension DSN du RFC 3461, il doit permettre d'utiliser ce type dans le paramètre ORCPT (Original Recipient, section 4.2 du RFC 3461). Si le serveur n'accepte pas SMTPUTF8, l'adresse à utiliser dans les DSN doit être encodée en 7bits, selon les règles exposées dans cette section 3. Par exemple, stéphane@bortzmeyer.org peut s'écrire st\x{E9}phane@bortzmeyer.org. (La section 3 détaille plus complètement le traitement des adresses UTF-8, et notamment les différentes formes qu'elles peuvent prendre, et les encodages de certains caractères, comme l'espace ou la barre oblique inverse, normalisé par le RFC 3461.)

Une fois réglé le problème de la représentation des adresses, la section 4 traite les DSN en UTF-8. Les DSN traditionnels étaient composés d'un objet MIME de type multipart/report (RFC 6522) comportant trois objets décrivant le problème (un objet conçu pour être lu par un humain, un message/delivery-status et le message originel, message/rfc822). Pour le courrier internationalisé, de nouveaux types ont été créés :

  • message/global-delivery-status qui, contrairement à son prédécesseur message/delivery-status, accepte l'UTF-8 et permet donc de placer directement les adresses UTF-8, sans encodage en ASCII. En outre, il dispose d'un nouveau champ, Localized-Diagnostic, qui permet de stocker des messages lisibles par un humain. La langue de ces messages est indiquée par une étiquette de langue (RFC 5646). (Le champ Diagnostic-Code est désormais en UTF-8, mais dans la langue par défaut du système, cf. i-default dans le RFC 2277.)
  • message/global qui remplace message/rfc822 (dont le nom, hommage au vieux RFC 822, était de toute façon dépassé). À noter que le terme global (mondial) utilisé pour noter ce type avait fait l'objet de vives discussions et même d'un vote. Cet objet permet de transporter le message original (si on ne transporte que les en-têtes, on utilise message/global-headers).

On peut noter que la norme MIME (RFC 2046) interdisait l'usage de l'option Content-Transfer-Encoding pour les objets de type message/* mais cette règle a été assouplie par le RFC 5335.

La section 5 traite des MDN (Message Disposition Notification, RFC 3798). Ils ne sont pas très différents des DSN et ont un format très proche, avec un type MIME message/global-disposition-notification.

La section 6 traite des registres IANA. Le type « UTF-8 » est ajouté au registre des types d'adresses (section 6.1), et les nouveaux types MIME qui avaient été créés par les premiers RFC expérimentaux, comme message/global sont ajoutés au registre des types MIME (sections 6.3 à 6.5).

Enfin, la section 7 est dédiée aux questions de sécurité. Il y a les problèmes de sécurité classiques des DSN et des MDN : non authentifiés, ils permettent de faire croire qu'un message a échoué, alors qu'il a bien été délivré, ou le contraire. Et les DSN et MDN reçus sont souvent émis en réponse à des messages faux, qui n'avaient pas été émis par l'utilisateur. D'autre part, le RFC nous prévient que des DSN ou des MDN délibérement incorrects peuvent être envoyés par un attaquant dans l'espoir de profiter d'erreur dans la programmation des analyseurs, par exemple pour déclencher un débordement de tampon. Le risque est plus important s'il y a beaucoup d'encodage, le décodage pouvant faire varier la taille des données.

Quels sont les changements depuis le RFC expérimental, le RFC 5337 ? L'annexe A les résume, les principaux étant la suppression de tout ce qui concernait le mécanisme de repli (downgrade), mécanisme complexe qui avait été normalisé pour gérer les cas où un serveur sur le chemin ne pouvait pas transmettre les adresses en UTF-8. Trop délicat, ce mécanisme a été retiré de la version normalisée de ces adresses.


Téléchargez le RFC 6533


L'article seul

RFC 6532: Internationalized Email Headers

Date de publication du RFC : Février 2012
Auteur(s) du RFC : A. Yang (TWNIC), S. Steele (Microsoft), N. Freed (Oracle)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 18 Février 2012


Dans l'ensemble des RFC qui décrivent les adresses de courrier électronique internationalisées (c'est-à-dire pouvant utiliser tout le répertoire Unicode), celui-ci se consacre au nouveau format des en-têtes, complétant celui normalisé dans le RFC 5322.

Désormais, on peut avoir dans un message un en-tête comme :

From: Stéphane Bortzmeyer <stéphane@sources.org>

Oui, avec du vrai UTF-8, y compris dans l'adresse proprement dite, pas seulement dans les commentaires, et encore, à condition de les surencoder selon le RFC 2047 comme c'était le cas avant (méthode inélégante et inefficace). Cette possibilité d'utiliser directement UTF-8 avait été créée par le RFC 5335, qui n'avait que le statut « Expérimental ». Désormais, ce mécanisme est complètement normalisé, en partie parce que de plus en plus de logiciels savent traiter directement l'UTF-8.

L'un des éditeurs du RFC travaille à TWNIC, le registre chinois de .tw. Les Chinois ont, fort logiquement, été particulièrement actifs dans tout le processus EAI (Email Addresses Internationalization). Celui-ci visait à terminer l'internationalisation du courrier électronique, qui avait passé une étape décisive en novembre 1996, avec la sortie du RFC 2045 sur MIME. Mais cette norme MIME n'internationalisait que le corps des messages. EAI permet d'internationaliser également les en-têtes comme From:, Subject: ou Received: (mais pas, par exemple, Date:, qui restera en ASCII pur ; Date: est censé être analysé par le MUA et présenté ensuite à l'utilisateur dans sa langue).

EAI comprend plusieurs RFC, par exemple le RFC 6530 définit le cadre général, le RFC 6531, l'utilisation des adresses Unicode dans SMTP (avec l'extension SMTPUTF8), les RFC ou futurs RFC sur POP (RFC 5721) ou IMAP (RFC 5738) et notre RFC 6532, qui se concentre sur le format des messages. Il suppose que le transport sera « 8-bits clean », c'est-à-dire laissera passer les octets qui codent les données UTF-8 sans les modifier (le cas des vieux systèmes qui ne gèrent pas proprement les caractères non-ASCII est délibérement laissé de côté).

Concrètement, que change donc ce RFC ? La section 3 détaille ce qui est modifié, par extension de la grammaire du RFC 5322) :

  • La grammaire ABNF qui décrit les en-têtes est changée (sections 3.1 et 3.2) pour accepter des caractères UTF-8, de préférence normalisés en NFC (cf. RFC 5198). Déjà très complexe, cette grammaire devient ainsi réellement difficile.
  • L'en-tête Message-ID: est traité à part (section 3.3). Les caractères UTF-8 y sont autorisés mais déconseillés (le RFC rappelle que cet en-tête sert à former automatiquement d'autres en-têtes comme In-Reply-To:).
  • La syntaxe des adresses (telles qu'on les trouve dans des en-têtes comme From: ou To:) est modifiée pour accepter UTF-8. Pour les sites qui utilisent une adresse électronique comme identificateur, comme le fait Amazon.com, ce sera un intéressant défi !
  • Un nouveau type MIME est créé, message/global, pour permettre d'identifier un message EAI (section 3.7). Les messages de ce type ne doivent être transportés qu'avec des protocoles 8-bits clean comme celui du RFC 6531.
  • Les noms des en-têtes restent en ASCII seul, ce n'est que leur contenu qui peut être en UTF-8. Pour utiliser le vocabulaire du RFC 2277, les noms des en-têtes sont un élement de protocole, qui n'a pas besoin d'être exprimé dans la langue de l'utilisateur.

Parmi les conséquences pratiques de ce changement, il faut noter que les programmeurs qui écrivent des logiciels traitant le courrier doivent désormais gérer Unicode, même s'ils se contentent d'analyser les en-têtes... L'époque du courrier traité avec des scripts shell est bien passée.

Autre point important pour les programmeurs, les limites de taille des en-têtes (qui étaient de 998 caractères maximum et 78 recommandés) changent de sémantique (section 3.4) puisque, en UTF-8, un caractère ne fait plus forcément un octet. Les limites sont désormais de 998 octets et 78 caractères (cette seconde limite étant conçue pour tenir sur l'écran). Attention aussi à la section 4, qui rappelle le risque de débordement de tampons.

La section 4 liste également quelques conséquences pour la sécurité comme le fait qu'un mécanisme d'authentification devra être prêt à gérer plusieurs adresses pour la même personne (car, pendant un certain temps, plusieurs utilisateurs auront à la fois une adresse en Unicode et une en ASCII pur).

Les changements depuis le RFC 5335 sont résumés dans la section 6 du RFC 6530. Le principal est la suppression de la possibilité de repli (downgrading) automatique vers des adresses en ASCII pur.


Téléchargez le RFC 6532


L'article seul

RFC 6531: SMTP Extension for Internationalized Email

Date de publication du RFC : Février 2012
Auteur(s) du RFC : J. Yao (CNNIC), W. Mao (CNNIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 18 Février 2012


Dans la grande série des RFC décrivant les adresses de courrier internationalisées, ce document traite des modifications au protocole SMTP. Il succède au RFC 5336, qui avait créé ces modifications mais qui n'avait que le statut « Expérimental ». Désormais, ces extensions internationales sont sur le Chemin des Normes de l'IETF.

Plusieurs RFC composent la nouvelle norme EAI ou « Email Addresses Internationalized » (cf. RFC 6530). Les deux principaux concernent le format des messages (RFC 6532) et le dialogue entre deux serveurs de messagerie, suivant le protocole SMTP. Ce dernier cas est couvert dans notre RFC 6531.

Les adresses de courrier en Unicode ne sont pas en effet compatibles avec le SMTP « brut ». Ainsi, la commande RCPT TO qui permet d'indiquer le destinataire, ne prend en paramètre que de l'ASCII. Et les en-têtes du courrier peuvent désormais être en UTF-8 (RFC 6532). Il faut donc étendre SMTP (actuellement normalisé en RFC 5321) pour permettre de l'UTF-8 en paramètre de commandes comme MAIL FROM et RCPT TO. Cette extension se signale avec l'option SMTPUTF8 (l'ancien RFC, le RFC 5336, utilisait UTF8SMTP), dont l'usage permet de vérifier que le MTA situé en face comprend bien la nouvelle norme (sections 1 et 2 du RFC).

La section 3 forme le gros du RFC en spécifiant rigoureusement le nouveau protocole. Voyons d'abord un exemple de dialogue SMTP avec la nouvelle extension (C est le client - l'appelant - et S le serveur - l'appelé). Notre RFC 6531 ne modifie pas SMTP (RFC 5321), il l'étend :


S: 220 mail.example.org ESMTP Foobar (Debian/GNU)
C: EHLO mail.iloveunicode.example 
S: 250-mail.example.org
 250-ENHANCEDSTATUSCODES
 250-8BITMIME
 250-SMTPUTF8
 250 DSN
C: MAIL FROM:<stéphane@internet-en-coopération.fr> SMTPUTF8
S: 250 2.1.0 Ok
C: RCPT TO: <françoise@comptabilité.example.org> 
S: 250 2.1.5 Ok

Notez les deux adresses, chacune comprenant des caractères non-ASCII, à gauche et à droite du @.

Les serveurs qui mettent en œuvre l'extension SMTPUTF8 doivent également accepter la très ancienne extension 8BITMIME (RFC 6152) qui permet, depuis belle lurette, de ne pas se limiter à l'ASCII dans le contenu des messages, sans pour autant nécessiter des encodages comme Quoted-Printable (en dépit de ce que prétend une légende tenace).

Les sections 3.1 et 3.2 présentent la nouvelle extension, SMTPUTF8 (enregistrée à l'IANA, cf. section 4.1). Les extensions SMTP sont définies par le RFC 5321, section 2.2. Un MTA peut annoncer qu'il accepte SMTPUTF8, permettant à son pair, s'il l'accepte également, d'utiliser des adresses UTF-8. C'est également cette section qui définit ce que doit faire un MTA lorsqu'il tente de transmettre un message internationalisé à un ancien MTA qui ne gère pas cette extension. Trois solutions sont possibles, dont le rejet complet du message (retour à l'expéditeur) et un effort pour trouver une route alternative, passant par des serveurs plus modernes (le RFC 5336 avait un quatrième mécanisme, le repli - downgrade - qui a été abandonné après usage, car trop complexe et trop imprédictible).

La section 3.3 décrit la nouvelle syntaxe pour les adresses. L'ancienne était limitée à ASCII mais très permissive (bien qu'on trouve, notamment derrière les formulaires Web, énormément de logiciels de « vérification » bogués). En gros, la syntaxe est qu'une adresse est formée de deux parties, la partie locale et le nom de domaine, tous les deux séparés par l'arobase. La nouveauté est que les deux parties peuvent désormais être en Unicode, avec peu de restrictions sur la partie locale (le nom de domaine étant soumis aux restrictions du RFC 5890).

Il y a plein d'autres détails dans cette section 3, comme celui (section 3.7.1) que le paramètre de la commande EHLO (un nom de machine) doit être encodé en Punycode puisque, à ce stade, on ne sait pas encore si SMTPUTF8 est accepté ou pas.

Les changements depuis le RFC 5336 sont résumés dans la section 6 du RFC 6530. Le principal est la suppression de la possibilité de repli (downgrading) automatique vers des adresses en ASCII pur. Le paramètre ALT-ADDRESS disparait donc.

Cette extension de SMTP ne semble pas mise en œuvre dans les grands logiciels libres classiques comme sendmail ou exim. Pour Postfix, l'auteur a clairement exprimé son manque d'enthousiasme. Il existe des patches non-officiels développés en Chine, pour Postfix http://www.cdnc.org/gb/news/src-EAI.tar.gz (l'archive comprend également d'autres logiciels, d'où sa taille) et pour sendmail http://www.cdnc.org/gb/news/twnic.zip. La société chinoise Coremail est en train de travailler à un produit commercial basé sur ces patches.


Téléchargez le RFC 6531


L'article seul

RFC 6530: Overview and Framework for Internationalized Email

Date de publication du RFC : Février 2012
Auteur(s) du RFC : J. Klensin, Y. Ko (ICU)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 18 Février 2012


Parmi les protocoles utilisés sur Internet, presque tous sont internationalisés depuis longtemps. Le dernier gros manque concernait les adresses de courrier électronique, obligées de s'en tenir à stephane@internet-en-cooperation.fr alors qu'on voudrait pouvoir écrire à stéphane@internet-en-coopération.fr. Désormais, nous avons une solution standard, Internationalized Email Addresses.

Bien sûr, pour l'exemple ci-dessus, le gain n'est pas évident. Mais il l'est beaucoup plus si vous voulez écrire votre adresse avec l'écriture arabe ou chinoise. (Cf. section 3 pour la description du problème, section qui exprime clairement le fait qu'un Chinois a le droit d'avoir une adresse en sinogrammes, comme un Occidental jouit des avantages d'une adresse en caractères latins.)

Le contenu des courriers était internationalisé depuis longtemps, au moins depuis MIME (RFC 1341 à l'origine, en juin 1992). De même, certains en-têtes comme le sujet ou même comme le nom de l'expéditeur dans le champ From: - mais pas son adresse - pouvaient être internationalisés via MIME (RFC 2047). Mais les adresses ne l'étaient pas encore et ce manque de cohérence (possibilité d'utiliser des écritures non-latines à certains endroits mais pas à d'autres) rendait le courrier peu attirant pour M. Ali ou M. Wu. Notre RFC, qui remplace le RFC 4952 qui n'était qu'expérimental, décrit le cadre général de l'internationalisation des adresses de courrier. Il y avait depuis longtemps des messages internationaux, il y a désormais également des adresses internationales.

Il y a deux parties à l'adresse (décrites dans le RFC 5322) : la partie locale, à gauche du @ et le nom de domaine à droite. Si ce nom de domaine, depuis la sortie du RFC 3490, en mars 2003, peut s'écrire en Unicode (norme IDN), le courrier exigeait toujours un nom de domaine en ASCII donc un message de non-délivrance, par exemple, allait affichait la forme Punycode du nom. Ce n'était pas une vraie internationalisation.

Le cadre d'internationalisation du courrier couvre plusieurs aspects, couverts chacun par un RFC. Ce RFC expose l'architecture générale. La section 5 décrit le fonctionnement du nouveau système.

SMTP est modifié pour permettre une nouvelle extension, SMTPUTF8, indiquant le support du courrier internationalisé (RFC 6531).

Le format des messages (RFC 5322) est modifié pour permettre d'inclure de l'Unicode, encodé en UTF-8, directement dans les en-têtes, comme le champ To: (RFC 6532). Les autres charsets (comme UTF-32) ne sont pas prévus.

Le format des accusés de réception est modifié pour permettre des rapports de remise ou de non-remise lorsque l'expéditeur ou le destinataire avaient des adresses Unicode (RFC 6533).

Plusieurs autres protocoles « auxiliaires » seront également modifiés, par exemple pour les listes de diffusion (RFC 5983) ou pour IMAP et POP. Même chose pour des formats comme les IRI de plan mailto: (section 11.1 de notre RFC, RFC 3987 et RFC 6068).

Notons (section 11.2 du RFC) que les adresses de courrier sont utilisés en de nombreux endroits, par exemple comme identificateurs sur certains sites Web de commerce électronique, comme Amazon et que ces utilisateurs vont également devoir s'adapter. Quant on voit le nombre de sites, supposés professionnels, qui continuent à interdire des adresses de courrier légales, on mesure l'ampleur du travail. La section 10, elle aussi, décrit des questions liées à l'interface utilisateur. Par exemple, elle rappelle qu'il y a toujours eu des cas délicats dans la syntaxe, dont il est plus prudent de se tenir à l'écart. Ainsi, la partie gauche d'une adresse est sensible à la casse donc, en théorie, on pourrait avoir une adresse Stephane@bortzmeyer.fr et que le courrier bêtement envoyé à stephane@bortzmeyer.fr n'atteindrait pas. Inutile de dire que peu de MTA mettent en œuvre une telle distinction... Dans le cas des adresses internationalisées, il faut donc prendre garde à la canonicalisation Unicode. Au minimum, il faudrait accepter la canonicalisation en NFC de toute adresse, car cette canonicalisation aura peut-être lieu quelque part dans le chemin, qu'on le veuille ou pas.

Les changements par rapport à l'ancien cadre (RFC 4952 et ses copains) sont décrits dans les sections 6 et 12. La section 6 fait en outre le bilan de la phase expérimentale. Désormais, les adresses de courrier internationalisées ont le statut de norme et non plus de simple expérience. Le principal changement technique, de loin, est la suppression du repli. Le repli (downgrading, cf. RFC 5504 et RFC 5825) était prévu pour le cas où un émetteur internationalisé rencontrerait un récepteur qui ne l'est pas, nécessitant une modification des adresses en ASCII. En effet, contrairement à HTTP, le courrier ne fonctionne pas de bout en bout et le message est relayé par plusieurs serveurs, qu'on ne connaît pas forcément a priori.

Le repli était certainement la partie la plus complexe : modifier un message est toujours une opération délicate, notamment en présence de signatures cryptographiques (section 11.3), que le repli ne doit pas invalider ! Tellement complexe que sa mise en œuvre s'est avérée très délicate et que les différentes implémentations avaient du mal à interagir. En outre, l'expérience a montré que le fait de devoir gérer deux adresses (celle en Unicode et une en ASCII pour le repli), sans lien sécurisé entre les deux, était une belle source de problèmes. Résultat, par rapport aux RFC de la phase expérimentale, le repli a été abandonné. Désormais, un courrier internationalisé ne pourra tout simplement pas être transmis à travers les vieux serveurs, ce sera au MUA ou à l'utilisateur de trouver une solution de rechange (cf. section 8, qui détaille les solutions). On note que la phase expérimentale, dont beaucoup de RFC ne sortent jamais, a été ici utile, permettant, par la pratique, d'atteindre un très large consensus sur un point qui était précédemment fortement discuté.

Un deuxième changement technique important par rapport aux premiers RFC sur ce sujet est que, en SMTP, le client aussi bien que le serveur doit signaler sa volonté d'utiliser les nouvelles adresses.

La section 8 décrit plus en détail la marche à suivre si le serveur suivant ne gère pas les adresses Unicode (par exemple, on peut prévoir que certains administrateurs activeront les adresses Unicode sur le serveur de courrier principal du domaine et oublieront le MX secondaire). Elle n'est pas normative puisque c'est largement une question d'interface utilisateur, quelque chose que l'IETF ne fait pas normalement. Comme le note cette section, le meilleur repli est celui fait manuellement par l'utilisateur, car celui-ci est intelligent et motivé. Néanmoins, si on tient à faire du repli automatique, il peut être fait par le MUA, ou bien par une future extension au protocole de soumission (RFC 4409). Ça, c'était pour le cas où le serveur ancien était le premier de la chaîne. Et si le problème d'un serveur non-Unicode survient en cours de route, lorsqu'un MTA se rend compte que le MTA suivant ne convient pas ? La section 9 rappelle qu'il est désormais strictement interdit aux MTA de tripoter le message et il n'y a donc rien d'autre à faire que d'indiquer une erreur, qui sera remontée à l'utilisateur.

Et si le problème survient une fois le message délivré, parce que le protocole de récupération n'a pas été adapté aux adresses Unicode ? Le problème est là encore formellement en dehors du cadre, le RFC notant juste que le MDA peut faire un repli automatique s'il le juge utile.

Cette extension du courrier ne semble pas encore implémentée officiellement dans les logiciels classiques de courrier, malgré la longue période des RFC expérimentaux.


Téléchargez le RFC 6530


L'article seul

RFC 6528: Defending Against Sequence Number Attacks

Date de publication du RFC : Février 2012
Auteur(s) du RFC : F. Gont (SI6 Networks / UTN-FRH), S. Bellovin (Columbia University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 2 Février 2012


Ce court RFC spécifie les précautions que doit prendre une mise en œuvre de TCP pour éviter qu'un attaquant ne puisse deviner le numéro de séquence initial. Rien de nouveau, les précautions en question étant programmées dans TCP depuis de nombreuses années, juste un rappel et une mise à jour du précédent RFC sur ce sujet, le RFC 1948.

Pour comprendre le problème de sécurité des numéros de séquence, et les solutions présentées dans ce RFC, il vaut mieux revenir à l'attaque qui exploitait les anciennes vulnérabilités. C'est fait dans l'annexe A du RFC, que je reprends ici.

Le but de l'attaquant est de s'en prendre à un serveur qui autorise par adresse IP. À l'époque du RFC 1948, cela concernait rsh mais, de nos jours, SSH a complètement remplacé cet archaïque protocole. Aujourd'hui, ce serait plutôt un serveur DNS qui authentifie le transfert de zones ainsi, ou bien un serveur SMTP qui autorise seulement certaines adresses IP à passer par lui - même s'il ferait mieux de se servir du RFC 4954, ou encore un serveur HTTP qui ne permet l'invocation de certaines actions qu'aux utilisateurs de certaines adresses. En deux mots, dès que l'autorisation se fait par adresse IP uniquement, il faut s'assurer que vous utilisez un TCP qui mette en œuvre les recommandations de ce RFC 6528.

On le sait, il est trivial pour un attaquant d'envoyer des paquets avec une fausse adresse IP source (le RFC 2827, censé l'empêcher, n'étant quasiment pas déployé). Mais, dans ce cas, l'attaquant ne reçoit pas les réponses. Or, si on veut maintenir une connexion TCP avec sa victime, il faut lui envoyer des paquets avec les données qu'elle attend, notamment le numéro de port et les numéros de séquence. Sinon, la victime va jeter ces paquets TCP qui lui sembleront anormaux. Pour les numéros de port, le RFC 6056 s'en occupe. Pour les numéros de séquence, voyons ce qui se passe. Tout paquet TCP doit inclure ces numéros, un pour chaque sens de la conversation (RFC 793, section 3.3). Ce numéro identifie l'octet suivant à envoyer. Une ouverture de connexion TCP normale ressemble donc, pour le cas où Alice veut parler à Bob, à :

  • Alice->Bob: [SYN] ISNa, null (Alice envoie un paquet TCP où le bit SYN est mis, avec un numéro de séquence initial ISNa - ISN = Initial Sequence Number.)
  • Bob->Alice: [SYN] ISNb, ACK(ISNa+1) (Bob répond qu'il est d'accord, envoie son propre ISN - rappelez-vous qu'il y a deux séquences d'octets, une dans chaque direction - et accuse réception de l'ISN d'Alice.)
  • Alice->Bob: [] ISNa, ACK(ISNb+1) (Alice est d'accord et cela termine la «  triple poignée de mains » qui ouvre une connexion TCP.)

Voici d'ailleurs, vu par tcpdump, un exemple d'ouverture de connexion (vers le dépôt git de Linux) :

% tcpdump -S -n -r tmp/3wayhandshake.pcap
reading from file tmp/3wayhandshake.pcap, link-type EN10MB (Ethernet)
09:47:53.086347 IP 192.134.6.69.39859 > 149.20.4.72.9418: Flags [S], seq 3366079112, ...
09:47:53.242880 IP 149.20.4.72.9418 > 192.134.6.69.39859: Flags [S.], seq 3075029842, ack 3366079113, ...
09:47:53.242910 IP 192.134.6.69.39859 > 149.20.4.72.9418: Flags [.], ack 3075029843, ...

Le S entre crochets indique un paquet SYN. L'option -S est là pour indiquer à tcpdump d'afficher les numéros de séquence absolus, tels qu'ils sont envoyés sur le câble (par défaut, il montre des numéros relatifs, sauf pour les paquets SYN). On note aussi que tcpdump n'affiche pas le premier numéro de séquence s'il n'y a pas de données, et n'affiche pas le second si le bit ACK n'est pas mis.

Le deuxième paquet n'a été accepté par Alice que parce qu'il contenait un numéro de séquence attendu. Mëme chose pour le troisième. Un attaquant qui procéderait au hasard, envoyant des numéros de séquence quelconques, n'aurait aucune chance que ses paquets soient acceptés. Imaginons maintenant que l'attaquant puisse connaître les numéros de séquence utilisés. Bob fait confiance à Alice mais Mallory, l'attaquant, va se faire passer pour Alice. Mallory n'est pas situé sur le chemin entre Alice et Bob (sinon, cela serait trivial, il lui suffirait d'écouter le réseau) :

  • AliceM->Bob: [SYN] ISNa, null (Mallory, utilisant l'adresse source d'Alice, envoie un paquet TCP où le bit SYN est mis, avec un numéro de séquence initial ISNa.)
  • Bob->Alice: [SYN] ISNb, ACK(ISNa+1) (Bob répond qu'il est d'accord, envoie son propre ISN et accuse réception de l'ISN qu'il croit venir d'Alice. Mallory ne recevra pas ce paquet, qui ira à la vraie Alice. Mallory ne sait donc pas ce que vaut ISNb, et doit deviner. En cas de divination juste, son paquet suivant est accepté.)
  • AliceM->Bob: [] ISNa, ACK(ISNb+1) (Mallory, utilisant l'adresse source d'Alice, termine la triple poignée de mains. Bob croit qu'il est connecté à Alice alors qu'il va accepter les paquets de Mallory.)

Et comment Mallory a-t-il trouvé le numéro de séquence que va utiliser Bob ? Le RFC originel, le RFC 793 ne mettait pas du tout en garde contre cette attaque, inconnue à l'époque (1981). Il ne se préoccupait que du risque de collision accidentel entre deux connexions et suggérait donc un algorithme où l'ISN était simplement incrémenté toutes les quatre micro-secondes, ce qui le rendait très prévisible (l'attaquant ouvre une connexion, regarde l'ISN, et sait quel va être celui de la prochaine connexion). Le premier article décrivant une faiblesse dans les mises en œuvre de TCP, faiblesse permettant de trouver le prochain numéro de séquence, a été publié en 1985 (Morris, R., A Weakness in the 4.2BSD UNIX TCP/IP Software, CSTR 117, AT&T Bell Laboratories). À l'époque, elle était suffisante pour établir des sessions rsh avec la victime.

À noter qu'Alice, elle, reçoit l'accusé de réception de Bob, auquel elle ne s'attend pas. Elle va donc émettre un paquet RST qui va fermer la connexion. Diverses techniques permettent à l'attaquant de réussir quand même (par exemple en montant au même moment une attaque DoS contre Alice pour ralentir ses paquets, donnant à l'attaque le temps de réussir).

C'est pour répondre à cette attaque que le RFC 1948 avait été écrit en 1996, documentant la pratique qui était devenue courante, de générer des numéros de séquence, sinon aléatoires, en tout cas imprévisibles. (Un article plus récent et plus détaillé sur la vulnérabilité initiale était celui de Shimomura, T., Technical details of the attack described by Markoff in NYT, envoyé sur Usenet, en comp.security.misc, Message-ID: <3g5gkl$5j1@ariel.sdsc.edu>, en 1995.) Notre RFC 6528 met à jour ce RFC 1948. La section 2 expose les principes d'un bon algorithme de génération d'ISN (Initial Sequence Number), la section 3 décrit l'algorithme proposé. Commençons par celui-ci. Il tient en une formule :

ISN = M + F(localip, localport, remoteip, remoteport)

où M est un compteur qui s'incrémente toutes les quatre micro-secondes, et F une fonction pseudo-aléatoire, qui va prendre comme paramètre le tuple qui identifie une connexion TCP (adresse IP locale, port local, adresse IP distante, port distant). F ne doit pas être prévisible de l'extérieur et le RFC suggère une fonction de hachage cryptographique, comme MD5 (RFC 1321), hachant le tuple ci-dessus après l'avoir concaténé à une clé secrète. La sécurité reposera sur cette clé, l'algorithme de hachage utilisé étant sans doute connu. On peut envisager qu'elle soit générée aléatoirement (vraiment aléatoirement, en suivant le RFC 4086), ou configurée à la main (en espérant que l'ingénieur système ne choisira pas « toto »). Il est recommandé de la changer de temps en temps.

Notez que, bien que MD5 ait de nombreuses faiblesses cryptographiques pour d'autres utilisations, il est parfaitement sûr pour celle-ci (et bien plus rapide que ses concurrents).

La section 2, elle, définissait le cahier des charges : qu'attend t-on d'un algorithme de sélection de l'ISN ? D'abord, il n'est pas forcé d'empêcher des vieux paquets IP qui traînent dans le réseau d'être acceptés. Pour cela, il vaut mieux compter sur l'état TIME_WAIT de TCP (après la fin d'une connexion, garder l'état pendant deux MSL - Maximum Segment Life, cf. RFC 1323). Ça ne marche pas forcément si les connexions sont créées à un rythme très rapide mais c'est la seule solution sûre (mais consommant de la mémoire). On peut lire à ce sujet deux articles sur les générateurs d'ISN, leurs avantages et inconvénients, « Strange Attractors and TCP/IP Sequence Number Analysis » et « Strange Attractors and TCP/IP Sequence Number Analysis - One Year Later ».

Compte-tenu de ces risques, une génération aléatoire de l'ISN suffirait. Mais elle aurait l'inconvénient de de ne pas permettre de deviner si un nouveau paquet TCP appartient à une ancienne connexion ou pas. L'idée de base de ce RFC est donc de créer un espace de numéros de séquence par identificateur TCP (le tuple {adresse IP locale, port local, adresse IP distante, port distant}) et, dans chacun de ces espaces, de suivre les règles d'incrémentation progressive de l'ISN du RFC 793.

Pour ceux qui veulent pousser l'analyse de sécurité, la section 4 prend de la hauteur et rappelle quelques points importants. D'abord que la vraie solution serait évidemment de protéger les paquets IP par de la cryptographie comme le fait IPsec, ou au niveau TCP comme le fait le TCP-AO du RFC 5925 (TLS ou SSH ne suffisent pas, ils n'empêchent pas une attaque par déni de service avec des faux paquets TCP RST).

La section 4 fait aussi remarquer que rien n'est parfait et que l'algorithme proposé dans notre RFC a des effets de bord, comme de permettre le comptage du nombre de machines qui se trouvent derrière un routeur NAT, ce qui peut être une information qu'on souhaiterait garder privée.

Et, surtout, elle rappelle que toutes les précautions de notre RFC 6528 ne s'appliquent que si l'attaquant est en dehors du chemin entre les deux pairs TCP. S'il est sur le chemin et qu'il peut écouter le réseau, elles ne servent à rien.

Quels sont les changements depuis le RFC 1948 ? Il n'y a pas de changement sur le fond (l'algorithme est le même donc un TCP compatible avec le RFC 1948 l'est également avec le RFC 6528). Les changements sont résumés dans l'annexe B. Le statut du RFC a changé (désormais sur le chemin des normes), les exemples maintenant dépassés par l'évolution des techniques ont été mis à jour ou supprimés,

On l'a dit, les précautions décrites dans ce RFC sont présentes dans les implémentations depuis longtemps. Pour un exemple de mise en œuvre de cet algorithme, on peut regarder le code source de NetBSD. Il se trouve en sys/netinet/tcp_subr.c. Son comportement est contrôlé par la variable sysctl iss_hash. Mise à 1, elle indique qu'il faut utiliser l'algorithme ci-dessus. À 0, qu'il faut utiliser une valeur aléatoire. Prenons le premier cas, celui de notre RFC. On voit la génération du secret (un nombre aléatoire, issu de cprng_strong()) puis le hachage MD5 de l'identifiant de connexion avec le secret :


	/*
	 * If we haven't been here before, initialize our cryptographic
	 * hash secret.
	 */
	if (tcp_iss_gotten_secret == false) {
		cprng_strong(kern_cprng,
			     tcp_iss_secret, sizeof(tcp_iss_secret), 0);
		tcp_iss_gotten_secret = true;
	}

        /*
	 * Compute the base value of the ISS.  It is a hash
	 * of (saddr, sport, daddr, dport, secret).
	 */
	MD5Init(&ctx);
	MD5Update(&ctx, (u_char *) laddr, addrsz);
	MD5Update(&ctx, (u_char *) &lport, sizeof(lport));
	MD5Update(&ctx, (u_char *) faddr, addrsz);
	MD5Update(&ctx, (u_char *) &fport, sizeof(fport));
	MD5Update(&ctx, tcp_iss_secret, sizeof(tcp_iss_secret));
	MD5Final(hash, &ctx);
	memcpy(&tcp_iss, hash, sizeof(tcp_iss));

        return (tcp_iss);

Pour Linux (remerciements au passage à @ackrst), il faut regarder le net/core/secure_seq.c qui contient à peu près la même chose (la variable net_secret est initialisée au tout début de ce fichier) :


__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
				 __be16 sport, __be16 dport)
{
	u32 hash[MD5_DIGEST_WORDS];

	hash[0] = (__force u32)saddr;
	hash[1] = (__force u32)daddr;
	hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
	hash[3] = net_secret[15];

	md5_transform(hash, net_secret);


Téléchargez le RFC 6528


L'article seul

RFC 6522: The Multipart/Report Media Type for the Reporting of Mail System Administrative Messages

Date de publication du RFC : Janvier 2012
Auteur(s) du RFC : M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 17 Janvier 2012


Un court RFC pour un format simple : le type MIME multipart/report permet d'envoyer des rapports structurés au sujet d'un message. Ce RFC est la dernière version de la norme sur multipart/report, marquée par un léger allègement des règles d'utilisation.

Pas de grands changements, sinon. L'idée de base de multipart/report est de pouvoir faire des messages à propos des messages. Par exemple, un avis de non-remise (RFC 3461) est un message disant qu'un message n'a pu être remis, et intégrant le message originel. Un rapport ARF (RFC 5965) est un message disant qu'un message est abusif (spam, par exemple) et intégrant également le message originel. D'où l'idée d'avoir un type commun pour tous ces « messages sur les messages », et c'est multipart/report, normalisé dans notre RFC 6522, qui succède au RFC 3462 (qui succédait lui-même au RFC 1892). Ce type multipart/report est très largement utilisé depuis longtemps, et par de nombreux logiciels.

La présentation détaillée du type « rapport » figure en section 3. Voici d'abord un exemple d'un tel message, ici pour indiquer une non-délivrance, généré par un MTA Postfix :

Date: Wed, 11 Jan 2012 13:45:44 +0000 (UTC)
From: MAILER-DAEMON@bortzmeyer.org (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender
To: bortzmeyer@nic.fr
Auto-Submitted: auto-replied
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status;
        boundary="154CD3AC2C.1326289544/mail.bortzmeyer.org"
Content-Transfer-Encoding: 8bit

This is a MIME-encapsulated message.

--154CD3AC2C.1326289544/mail.bortzmeyer.org
Content-Description: Notification
Content-Type: text/plain; charset=us-ascii

[La première partie du rapport, lisible par un humain.]

This is the mail system at host mail.bortzmeyer.org.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

--154CD3AC2C.1326289544/mail.bortzmeyer.org
Content-Description: Delivery report
Content-Type: message/delivery-status

[La deuxième partie du rapport, conçue pour être analysée par des
programmes.]

Reporting-MTA: dns; mail.bortzmeyer.org
X-Postfix-Queue-ID: 154CD3AC2C
X-Postfix-Sender: rfc822; bortzmeyer@nic.fr
Arrival-Date: Wed, 11 Jan 2012 12:24:50 +0000 (UTC)

Final-Recipient: rfc822; nothere@nowhere.example
Action: failed
Status: 5.4.4
Diagnostic-Code: X-Postfix; Host or domain name not found. Name service error
    for name=nowhere.example type=AAAA: Host not found

--154CD3AC2C.1326289544/mail.bortzmeyer.org
Content-Description: Undelivered Message
Content-Type: message/rfc822
Content-Transfer-Encoding: 8bit

[Puis le message originel, dans la troisième partie du rapport.]

Notez le paramètre report-type, qui a ici la valeur delivery-status. (Cela serait feedback-report pour du ARF.)

Notez surtout le découpage en trois parties (la dernière est optionnelle) :

  • Une partie qui contient un message en format libre et en langue naturelle.
  • Une partie structurée (dans l'exemple ci-dessus, avec la syntaxe message/delivery-status du RFC 3464).
  • Le message originel.

Si on trouve le message originel trop gros, la troisième partie peut se composer uniquement des en-têtes du message. Elle aura alors le type message/rfc822-headers (section 4 de notre RFC).

Naturellement, les messages multipart/report ne sont pas plus authentifiés que les autres messages : il faut donc éviter d'agir automatiquement lors de leur réception (section 7).

Le seul changement de fond depuis le RFC 3462 concerne une ancienne restriction : multipart/report ne pouvait apparaître qu'au plus haut niveau du message (rappelez-vous que MIME est récursif, un message MIME peut contenir d'autres messages MIME). Cela interdisait, par exemple, de faire un multipart/report au sujet d'un multipart/report. Il semble bien que personne ne mettait en œuvre cette restriction et ce nouveau RFC 6522 l'a donc supprimé. (Voir section 1.)


Téléchargez le RFC 6522


L'article seul

RFC 6520: Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) Heartbeat Extension

Date de publication du RFC : Février 2012
Auteur(s) du RFC : R. Seggelmann, M. Tuexen (Muenster Univ. of Appl. Sciences), M. Williams
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 8 Février 2012


Le protocole de cryptographie TLS ne disposait pas en standard de mécanisme de « battement de cœur », permettant de tester qu'une connexion est toujours vivante. C'est désormais chose faite. Grâce à la nouvelle extension de TLS, normalisée dans ce RFC, deux pairs TLS peuvent s'assurer, par un mécanisme standard, que l'autre pair est bien là, et répond.

Savoir si l'autre partie de la connexion est toujours là est souvent utile en matière de réseau. Les sessions qui utilisaient TLS (RFC 5246) ou DTLS (RFC 6347) ne disposaient pas d'un moyen générique de tester si le cœur du pair battait toujours. Les applications devaient donc envoyer des données inutiles et attendre une réponse. Une autre solution était de faire une renégociation (RFC 5246, section 7.4.1) mais cette opération est coûteuse en calculs cryptographiques. C'était encore pire avec DTLS, qui est parfois utilisé dans des applications unidirectionnelles, où aucune réponse applicative n'est prévue.

Désormais, les mises en œuvre de TLS qui gèrent la nouvelle extension, Heartbeat, pourront envoyer des messages HeartbeatRequest, auxquels le pair devra répondre avec un HeartbeatResponse. Cette extension est spécifiée au moment de la négociation (section 2), dans les messages Hello (RFC 5246, section 7.4.1). Dans la syntaxe ASN.1 de TLS, la nouvelle extension est décrite par :

   enum {
      peer_allowed_to_send(1),
      peer_not_allowed_to_send(2),
      (255)
   } HeartbeatMode;

   struct {
      HeartbeatMode mode;
   } HeartbeatExtension;

Le mode peer_not_allowed_to_send est là pour indiquer qu'une machine veut utiliser l'extension pour tester son pair mais qu'elle-même ne répondra pas aux requêtes HeartbeatRequest. La nouvelle extension est enregistrée à l'IANA (numéro 15).

Une fois que les deux parties se sont mises d'accord, quel est le protocole pour l'utilisation de cette extension (section 3) ? Le test des battements de cœur fonctionne au dessus du Record Protocol de TLS, auquel il ajoute deux messages :

 enum {
      heartbeat_request(1),
      heartbeat_response(2),
      (255)
   } HeartbeatMessageType;

Un message HeartbeatRequest peut arriver à tout moment pendant une session, le pair doit alors répondre par un HeartbeatResponse. D'autres types que Requête et Réponse seront peut-être un jour créés, et enregistrés dans le nouveau registre IANA.

Lorsque la session protégée par TLS fonctionne au dessus d'un protocole fiable, comme TCP, c'est tout. La couche de transport se chargera des éventuelles retransmissions. Si la session TLS utilise un protocole non-fiable comme UDP, l'émetteur du HeartbeatRequest doit se préparer, en l'absence de réponse, à réemettre le message (RFC 6347, section 4.2.4).

Et le contenu des messages (section 4) ? Une charge utile est autorisée :

 struct {
      HeartbeatMessageType type;
      uint16 payload_length;
      opaque payload[HeartbeatMessage.payload_length];
      opaque padding[padding_length];
   } HeartbeatMessage;

Le contenu du champ payload est quelconque. La réponse doit inclure le même contenu (elle doit être un écho de la requête).

La section 5 du RFC décrit ensuite deux cas d'utilisation pratique de cette extension. Le premier est celui de la découverte de la MTU du chemin, pour laquelle DTLS n'avait pas de mécanisme (RFC 6347, section 4.1.1.1). La méthode, inspirée du RFC 4821, est simplement d'utiliser des HeartbeatRequest de plus en plus gros, jusqu'à ce qu'on n'obtienne plus de réponse, auquel cas on sait qu'on a trouvé la MTU maximale.

L'autre usage de cette extension est le test de bonne santé du pair, comme expliqué au début de cet article. Le RFC recommande de ne pas en abuser, et de n'émettre les HeartbeatRequest qu'à des intervalles de plusieurs fois le RTT.

Il existe déjà au moins une mise en œuvre de ce mécanisme de battement de cœur. OpenSSL l'aura à partir de la 1.0.1 (le code est déjà dans les versions de développement, l'extension - option heartbeats - est apparemment compilée par défaut). Pour GnuTLS, ce n'est encore qu'un projet.


Téléchargez le RFC 6520


L'article seul

RFC 6518: Keying and Authentication for Routing Protocols (KARP) Design Guidelines

Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Lebovitz, M. Bhatia (Alcatel-Lucent)
Pour information
Réalisé dans le cadre du groupe de travail IETF karp
Première rédaction de cet article le 2 Février 2012


Dans l'ensemble du travail engagé pour améliorer la sécurité du routage sur l'Internet, un sous-problème important est celui de la gestion des clés. En cryptographie, c'est souvent par une faiblesse dans cette gestion que les systèmes de sécurité sont compromis. Le groupe de travail KARP de l'IETF est occupé à améliorer les protocoles de gestion de clés et son premier RFC, ce RFC 6518, expose les propriétés attendues des futurs protocoles de gestion des clés des routeurs.

Prenons par exemple N routeurs OSPF qui veulent s'authentifier les uns les autres. La technique du RFC 2328 est d'avoir un secret partagé par tous les routeurs du même réseau local. Les messages OSPF sont concaténés avec ce secret, le résultat de la concaténation est ensuite condensé cryptographiquement, ce qui permettra au destinataire de s'assurer que l'émetteur connaissait bien le secret. Ce secret partagé est une clé cryptographique. Qui va la générer ? Comment la distribuer de façon sûre ? Comment la changer facilement et rapidement si le secret est compromis (ou, tout simplement, si un employé quitte l'entreprise) ? Ce genre de questions est la problématique de gestion de clés. Dans le cas d'OSPF, actuellement, la quasi-totalité des opérateurs de routeurs fait cela à la main (on se logue sur chaque routeur et on change le secret...) ou, à la rigueur, via un protocole général de configuration des routeurs. Peut-on faire mieux ? C'est en tout cas ce que va essayer de faire le groupe KARP.

C'est que les mécanismes actuels ne sont pas satisfaisants. Comme le rappelle la section 1 du RFC, lors d'un colloque en 2006 (cf. RFC 4948), les participants avaient dénoncé la vulnérabilité des routeurs aux tentatives de prise de contrôle et appelé à durcir leur sécurité. Quatre axes d'amélioration avaient été identifiés, améliorer la gestion des routeurs (groupe de travail OPSEC), améliorer les IRR, valider les annonces de route (groupe de travail SIDR), et enfin sécuriser les communications entre routeurs (groupe de travail KARP), ce qui fait l'objet de ce RFC. Les informations de routage sont échangées via un protocole et la protection de ce protocole se fait par la cryptographie. Qui dit cryptographie dit clés. Lorsqu'un routeur cherche une clé pour protéger un message, où demande-t-il ? Pour l'instant, il n'y a pas de mécanisme standard et KARP va essayer d'en développer un. Le plus courant aujourd'hui est la gestion manuelle des clés (l'opérateur configure les clés, les change à la main - lorsqu'il y pense, les communique via PGP, SCP voire sans aucune sécurité) mais le RFC estime que le futur est dans des mécanismes automatisés de gestion de clés, les KMP (pour Key Management Protocol). Un KMP, par exemple, change automatiquement les clés au bout d'une période pré-définie.

Compte-tenu de la variété des protocoles de routage, et du transport qu'ils utilisent, ce sera un mécanisme abstrait, pas un protocole précis (ce RFC 6518 n'a donc pas d'implémentation, il définit juste un cadre). Plus précisement, KARP va concevoir les interfaces abstraites entre le système de gestion de clés et le protocole de routage, puis, pour chaque protocole de routage, la correspondance entre cette interface abstraite et le protocole réel. Un projet ambitieux.

Maintenant, au boulot. Qu'est-ce qui est déjà fait dans ce RFC ? La section 2 classe les protocoles de routage selon leurs propriétés. L'idée est que les protocoles de routage qui partagent les mêmes propriétés pourront, avec un peu de chance, utiliser les mêmes mécanismes de gestion de clés. Première propriété, le type de message. Certains protocoles sont de type un-vers-un : les messages d'un routeur sont envoyés à un autre routeur. Les UPDATE BGP (RFC 4271) fonctionnent ainsi. Mais c'est aussi le cas de LDP (RFC 5036), de BFD (RFC 5880) et même d'OSPF (RFC 2328 dans certaines conditions (liens point -à-point). D'autres protocoles fonctionnent en un-vers-plusieurs. Un routeur diffuse sur le réseau local l'information de routage. C'est le mode de fonctionnement le plus courant d'OSPF et c'est aussi celui de RIP (RFC 2453). Enfin, il y a les protocoles utilisés pour le multicast.

Deuxième propriété pour classer les protocoles de routage, proche de la précédente mais pas identique, le fait que la clé soit par groupe ou par pair. Dans BGP ou LDP, les clés sont individuelles, on a une clé différente par pair. Dans OSPF, la clé est la même pour tous les pairs d'un groupe.

La section 3 liste ensuite les points auxquels il faut penser lorsqu'on envisage un protocole de gestion de clés, un KMP. Le RFC 4107 fournit les bases générales et notre RFC l'adapte aux protocoles de routage. Entre autres, il faudra penser aux paramètres à passer avec le système de gestion de clés, comme la durée de vie pour les clés, l'identificateur de l'association de sécurité (SPI dans IPsec, KeyID dans TCP-AO, etc), l'algorithme de chiffrement et plusieurs autres.

Deux points sont soulignés par le RFC, les questions particulières des clés asymétriques (section 3.1) et le cycle de vie des clés (section 3.2). Les clés asymétriques sont souvent une bonne solution aux problèmes de sécurité : déjà utilisées par les routeurs (lorsqu'ils sont administrés via SSH), générées sur le routeur, elles peuvent n'avoir jamais besoin de le quitter (le RFC ne le dit pas clairement mais on peut même imaginer un petit HSM dans le routeur). Générées aléatoirement, elles ne peuvent pas être devinées comme le sont tant de mots de passe choisis par des humains. Il faut juste faire attention à leur taille, pour limiter les risques des attaques par force brute (RFC 3766). L'algorithme classique pour ces clés est RSA mais les algorithmes à base de courbes elliptiques commencent à se répandre, et permettent d'utiliser des clés plus courtes.

Quant au cycle de vie des clés, notre RFC insiste surtout sur la nécessité d'avoir des remplacements (rollover) de clés qui soient discrets : un remplacement de clés ne devrait pas casser les sessions de routage existantes, car cela imposerait des recalculs lourds des tables de routage, se propageant dans tout le réseau, et entraînant parfois des perturbations dans la connectivité. (Le RFC ne le cite pas mais la traditionnelle authentification MD5 de BGP - RFC 2385 - n'a pas cette propriété. Changer la clé impose de relancer les sessions BGP. C'est sans doute une des raisons pour lesquelles ces clés ne sont jamais changées, même quand tout le monde les connait.)

Pourquoi, d'ailleurs, faut-il changer les clés de temps en temps ? Il peut y avoir des raisons cryptographiques (progrès de la cryptanalyse, mais le RFC note qu'en pratique, ce sont les cas les plus rares, des problèmes moins prestigieux scientifiquement sont bien plus communs), des raisons liées au personnel (départ d'un ingénieur qui connaissait les clés), des raisons plus urgentes (compromission d'une machine où étaient stockées des clés). Même s'il n'y a aucune raison immédiate de changer, un remplacement des clés de temps en temps peut être nécessaire pour s'assurer qu'un attaquant qui a obtenu une clé et l'utilise discrètement (de manière purement passive), ne puisse pas profiter de son butin éternellement.

Lorsque les procédures de changement de clés sont manuelles, les changements peuvent être en eux-mêmes une source de vulnérabilité (l'erreur est humaine...).

Après ces préliminaires, la section 4 dessine le travail futur. Il y a deux chantiers génériques (indépendants du protocole de routage) importants, le premier étant un pré-requis du second :

  • Doter tous les protocoles de routage de mécanismes leur permettant l'agilité des algorithmes (changer d'algorithme facilement, contrairement au RFC 2385, qui ne permettait que MD5) et celle des clés (changer de clés sans casser les sessions entre routeurs). À l'heure actuelle, c'est très loin d'être le cas.
  • Une fois ces mécanismes en place, développer un KMP, un Key Management Protocol permettant la gestion et le remplacement automatique des clés. Ce dernier protocole devrait être aussi indépendant du protocole de routage que possible.

Pour que les mécanismes nouveaux aient des chances de succès, ils doivent pouvoir être déployés sans ajouter de complexité par rapport à ce que font déjà les opérateurs (qui connaissent SSH, TCP-MD5, HTTPS et les certificats, etc). Le but n'est pas de faire un système qui empêche l'opérateur de faire une erreur (comme d'utiliser « foobar » comme mot de passe pour tous les systèmes) mais de faire un système qui soit utilisé dans le monde réel, et pour cela, la simplicité et la déployabilité sont des critères essentiels (mais très souvent oubliés par les experts en sécurité, qui se soucient d'avantage de faire des systèmes parfaits que des systèmes déployables, cf. section 6).

Avec une gestion manuelle des clés, on ne peut gérer de manière raisonnablement sûre que des petits réseaux. La deuxième étape sera donc de déployer le mécanisme de gestion automatique.

Le travail d'amélioration de chaque protocole de routage est décrit en section 4.2 sous forme d'une liste de tâches :

  • Analyser le protocole actuel pour déterminer de façon précise quels sont ses mécanismes de sécurité présents,
  • Déterminer ce qui lui manque pour atteindre le premier état de sécurité souhaité (agilité des algorithmes et possibilité de changer de clés en vol),
  • Analyse des étapes nécessaires pour aller du premier point au deuxième sans tout casser, en faisant particulièrement attention aux questions de déployabilité dans le monde existant,
  • Analyser le futur KMP (protocole de gestion de clés) pour ce protocole de routage particulier : a-t-il des demandes spécifiques ?
  • Déterminer ce qui manque pour atteindre le deuxième état de sécurité (gestion automatique des clés),
  • Normaliser l'adaptation du KMP à ce protocole et déployer le résultat.

On l'a vu en section 2, KARP classe les protocoles de routage en catégories selon leurs propriétés. La section 5 examine les points qui sont spécifiques à chaque catégorie. BGP, LDP et quelques autres sont dans la catégorie « messages un-vers-un et clés par pair ». BGP fonctionne toujours sur TCP, LDP parfois sur TCP et parfois sur UDP. Pour le cas de TCP, une bonne partie du travail a déjà été faite dans le groupe TCPM, avec la technique d'authentification AO (RFC 5925) qui a les propriétés voulues pour la première phase du travail de KARP (agilité des algorithmes et changement de clé facile). Il ne reste donc que le cas de LDP sur UDP.

Pour la catégorie « un-vers-plusieurs avec clés par groupe », qui comprend OSPF, IS-IS et RIP, rien de générique n'est fait. Le problème est ici bien plus difficile, d'autant plus que ces protocoles n'utilisent pas en général de protocole de transport standard, et ne peuvent donc pas réutiliser un mécanisme fourni par la couche 4 (comme peut le faire BGP avec AO). Ceci dit, le RFC 6506 fournit une méthode d'authentification pour OSPF qui, grâce à une indirection, fournit l'agilité de l'algorithme de chiffrement, qu'on eput changer en vol.

BFD est un cas à part et qui nécessitera sa propre équipe. Par exemple, il est beaucoup plus sensible aux délais que les autres. Pour lui, une milliseconde est très longue.

On l'a vu, ce RFC répète régulièrement qu'il est essentiel de prévoir un déploiement incrémental des nouveaux mécanismes de sécurité. Pas question d'ignorer l'existant. La section 6 insiste sur ce point. Contrairement à une attitude fréquente chez les experts en sécurité, qui est de chercher une solution parfaite, KARP va essayer de trouver des solutions qui puissent être déployées par étapes, sans casser le routage actuel, même si ces solutions ne sont pas les meilleures, question sécurité. Par exemple, les routeurs configurés avec les nouveaux mécanismes doivent pouvoir interagir sans ennuis avec les vieux routeurs non sécurisés.

Un des problèmes de sécurité les plus difficiles dans l'Internet est celui des attaques par déni de service (section 7). Ces attaques touchent aussi les routeurs et les protocoles de routage. Il ne faut donc pas que les nouvelles techniques conçues dans le cadre du groupe KARP aggravent le problème. Par exemple, les calculs cryptographiques peuvent être coûteux, surtout pour les ressources matérielles souvent limitées des routeurs, et les protocoles ne doivent donc pas permettre à un attaquant de faire faire au routeur une énorme quantité de ces calculs. Pour éviter cela, il faut permettre au routeur de faire des vérifications non-cryptographiques, donc bien plus légères, avant de se lancer dans les calculs compliqués. Par exemple, le RFC 5082 utilise le TTL du paquet entrant (quelque chose de trivial à vérifier) pour empêcher certaines attaques. Il est important, dans le cadre de KARP, de développer et de documenter de telles alternatives. D'autre part, le protocole doit être conçu de manière à ce que ce soit l'initiateur de la connexion (un attaquant potentiel) qui ait le plus de travail cryptographique à faire, et qui doive maintenir un état pendant ce temps.

La section 9 du RFC, la traditionnelle section sur la sécurité, détaille quelques points précis qui n'avaient pas trouvé leur place dans le reste du RFC. Par exemple, il est important de considérer aussi si le protocole de routage qu'on veut protéger est un IGP ou un EGP (certains protocoles peuvent être utilisés pour les deux, comme BGP avec son mode iBGP). Les deux sont sans doute aussi importants mais les menaces et les solutions ne seront pas forcément les mêmes. Un routeur purement interne et qui n'a aucun accès à l'Internet est ainsi sans doute moins menacé qu'un routeur BGP posé sur un point d'échange avec des dizaines d'autres routeurs inconnus.

Autre question transversale, celle des clés partagées ou uniques. Faut-il utiliser la même clé à plusieurs endroits ? Le débat est simple : c'est la sécurité (clés uniques !) contre la commodité (clés partagées). Actuellement, dans la grande majorité des environnements, les opérateurs ont choisi la commodité, réutilisant la même clé à plusieurs endroits. Les clés des routeurs sont stables dans l'espace (utilisées dans plusieurs routeurs) et dans le temps (on les change rarement, voire jamais et certains routeurs gardent la même clé toute leur vie). L'un des buts de KARP est de casser ce dilemne « sécurité ou commodité » en fournissant des mécanismes de gestion de clés qui soient sûrs (clés uniques) tout en étant faciles à déployer.

Enfin, la section 9.4 discute du dernier problème transversal, la distribution des clés. La méthode la plus courante aujourd'hui est un mécanisme « hors-bande », par exemple l'administrateur qui se connecte en SSH au routeur et entre manuellement les clés dans la configuration. Ça ne passe pas tellement à l'échelle (il faudrait automatiser les connexions SSH, par exemple avec Capistrano, pour faire l'opération sur N routeurs). Et changer toutes les clés en cas, par exemple de départ d'un administrateur (ou, pire, en cas de compromission de la clé) est trop lent. L'approche d'un KMP, protocole de gestion de clés, est donc préférée par KARP, comme nous l'avons déjà vu. Mais le RFC ne cache pas que le KMP a ses propres problèmes : lenteur au début (davantage de calculs cryptographiques) et surtout risques liés au manque de maturité des programmes, les KMP étant encore chose récente.

Une des possibilités envisagées est de réutiliser un KMP existant comme IKE, adapté au monde du routage, mais tournant en dehors du protocole de routage. L'autre possibilité est un nouveau KMP, embarqué dans le protocole de routage. Mais la décision n'est pas encore prise.


Téléchargez le RFC 6518


L'article seul

RFC 6506: Supporting Authentication Trailer for OSPFv3

Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Bhatia (Alcatel-Lucent), V. Manral (Hewlett Packard), A. Lindem (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ospf
Première rédaction de cet article le 14 Février 2012


La version 2 du protocole de routage OSPF avait un mécanisme d'authentification (annexe D du RFC 2328). Lors de la conception de la version 3 (qui permettait notamment d'ajouter IPv6), ce mécanisme avait été abandonné, l'idée étant que l'IETF avait déjà un mécanisme d'authentification plus général, IPsec, et qu'il « suffisait » de l'utiliser. Selon cette analyse, il n'y avait plus besoin de doter chaque protocole de son propre mécanisme d'authentification. C'était très bien sur le papier. Mais, en pratique, le déploiement d'IPsec est très limité, à la fois en raison de sa complexité et du caractère imparfait de ses implémentations. Résultat, les utilisateurs d'OPSFv3 n'ont, la plupart du temps, pas déployé de mécanisme de sécurité du tout. En voulant faire trop propre, on a donc diminué la sécurité du routage. Ce RFC corrige le tir en dotant enfin OSPFv3 d'un mécanisme d'authentification léger et réaliste.

OSPFv3 est normalisé dans le RFC 5340, dont le titre (« OSPF pour IPv6 ») est trompeur car, depuis le RFC 5838, OSPFv3 peut gérer plusieurs familles d'adresses et peut donc, en théorie, remplacer complètement OSPFv2. En pratique, toutefois, ce n'est pas encore le cas, notamment pour le problème de sécurité qui fait l'objet de ce RFC : contrairement aux autres protocoles de routage internes, OSPFv3 ne disposait d'aucun mécanisme d'authentification. N'importe quel méchant sur le réseau local pouvait se proclamer routeur et envoyer de fausses informations de routage. L'argument répété était « pas besoin de mécanisme spécifique à OSPFv3, utilisez les mécanismes IPsec, comme expliqué dans le RFC 4552 ». Mais on constate que cette possibilité a été très peu utilisée. Le RFC se contente de noter que c'est parce que IPsec est mal adapté à certains environnements comme les MANET mais il ne parle pas des autres environnements, où IPsec est simplement rejeté en raison de la difficulté à trouver une implémentation qui marche, et qu'un administrateur système normal arrive à configurer.

IPsec a également des faiblesses plus fondamentales pour des protocoles de routage comme OSPF. Ainsi, les protocoles d'échange de clés comme IKE ne sont pas utilisables tant que le routage ne fonctionne pas. Pour résoudre le problème d'œuf et de poule, et parce que les communications OSPF sont de type un-vers-plusieurs (et pas un-vers-un comme le suppose IKE), le RFC 4552 prône des clés gérées manuellement, ce qui n'est pas toujours pratique.

Enfin, l'absence de protection contre le rejeu affaiblit la sécurité d'IPsec dans ce contexte, comme le note le RFC 6039.

La solution proposée figure en section 2. L'idée est d'ajouter à la fin du packet OSPF un champ qui contienne un condensat cryptographique du paquet et d'une clé secrète, comme pour OSPFv2 (RFC 5709) (D'autres types d'authentification pourront être utilisés dans le futur, un registre IANA des types a été créé.) Les options binaires du paquet, au début de celui-ci (RFC 5340, section A.2), ont un nouveau bit, en position 13, AT (pour Authentication Trailer, désormais dans le registre IANA), qui indique la présence ou l'absence du champ final d'authentification (tous les paquets n'ont pas ce champ Options, donc le routeur devra se souvenir des valeurs de ce champ pour chaque voisin).

Pour chaque couple de routeurs ainsi protégés, il y aura un certain nombre de paramètres, qui forment ce qu'on nomme un accord de sécurité (security association, section 3) :

  • Un identifiant sur 16 bits, manuellement défini, le Security Association ID. L'émetteur le choisit et le récepteur le lit dans le paquet. Cette indirection va permettre de modifier des paramètres comme les clés cryptographiques (ou même l'algorithme cryptographique), tout en continuant le routage.
  • L'algorithme utilisé, par exemple HMAC-SHA1 ou HMAC-SHA512,
  • La clé,
  • Des paramètres temporels indiquant, par exemple, à partir de quand la clé sera valide.

Une fois qu'on a toutes ces informations, qu'est-ce qu'on met dans le paquet OSPF envoyé sur le câble ? La section 4 décrit le mécanisme. Le champ final d'authentification (Authentication Trailer) est composé notammen de l'identifiant d'un accord de sécurité (SA ID, décrit au paragraphe précédent, et qui permet au récepteur de trouver dans sa mémoire les paramètres cryptographiques liés à une conversation particulière), d'un numéro de séquence (qui sert de protection contre le rejeu ; il est augmenté à chaque paquet émis ; il comprend 64 bits, après une très longue discussion dans le groupe de travail, certains auraient préféré 32 bits) et du condensat cryptographique du paquet concaténé avec la clé (la section 4.5 décrit l'algorithme en détail et notamment quels champs du paquet sont inclus dans les données condensées).

Le routeur qui reçoit un paquet utilisant l'authentification (il le sait grâce au bit AT qui était notamment présent dans les paquets OSPF Hello) va accéder au champ d'authentification (le champ Longueur du paquet OSPF lui permet de savoir où commence le champ d'authentification, éventuellement en tenant compte du bloc Link-Local Signaling du RFC 5613, un routeur doit donc gérer au moins en partie ce dernier RFC s'il veut authentifier). Le récepteur refait alors le calcul cryptographique et vérifie si le champ final d'authentification est correct. Le calcul est très proche de celui du RFC 5709 à part l'inclusion de l'adresse IPv6 source.

Supposons que nous soyons administrateur réseaux et que nos routeurs gèrent tous ce nouveau RFC. Comment déployer l'authentification sans tout casser ? La section 5 recommande de migrer tous les routeurs connectés au même lien simultanément. Autrement, les routeurs qui n'utilisent pas l'authentification ne pourront pas former d'adjacences OSPF avec ceux qui l'utilisent. Le RFC prévoit un mode de transition, où le routeur envoie le champ final d'authentification mais ne le vérifie pas en entrée mais l'implémentation de ce mode n'est pas obligatoire.

La section 6 contient l'analyse de sécurité de cette nouvelle extension d'OSPF. Elle rappelle qu'elle ne fournit pas de confidentialité (les informations de routage seront donc accessibles à tout espion). Son seul but est de permettre l'authentification des routeurs, résolvant les problèmes notés par le RFC 6039. À noter que cette extension ne permet pas d'authentifier un routeur particulier mais simplement de s'assurer que l'émetteur est autorisé à participer au routage sur ce lien (tous les routeurs ont la même clé). La clé, rappelle cette section 6, devrait être choisie aléatoirement, pour ne pas être trop facile à deviner (cf. RFC 4552).

À ma connaissance, il n'existe pas encore d'implémentation de cette option dans le logiciel d'un routeur.


Téléchargez le RFC 6506


L'article seul

RFC 6497: BCP 47 Extension T - Transformed Content

Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Davis (Google), A. Phillips (Lab126), Y. Umaoka (IBM), C. Falk (Infinite Automata)
Pour information
Première rédaction de cet article le 23 Février 2012


Le RFC 5646, qui normalise les étiquettes de langue, prévoit un mécanisme d'extension pour ajouter à ces étiquettes des informations maintenues dans des registres extérieurs. Ces extensions sont identifiées par une lettre unique et une nouvelle extension est ajoutée par notre RFC 6497, « T » (pour transformation), qui permet d'indiquer les transformations qu'a subies un texte (par exemple une traduction), en se référant au registre CLDR.

Le RFC 5646 est également connu sous l'identificateur « BCP 47 » (BCP pour Best Common Practice), ce qui explique le titre de notre RFC 6497. Les transformations qu'on pourra noter dans une étiquette de langue sont notamment la translittération, la transcription et la traduction. Sans cette extension « T », on ne peut étiqueter que l'état actuel du document. Par exemple, pes-Latn désignerait un texte en persan dans l'alphabet latin (ce qui est inhabituel) ; l'extension « T » permettra d'écrire pes-Latn-t-pes-arab, indiquant que le texte persan a été translittéré ou transcrit depuis l'alphabet arabe. Autre exemple, donné dans le RFC, une carte d'Italie pour des japonais où les noms des villes ont été translittérés en Katakana. N'indiquer que ja (langue japonaise) pour ce texte serait insuffisant. Cette information sur la source, donnée par l'extension « T » est souvent importante, pour aider à comprendre certaines particularités du texte (comme des fautes lors de la traduction). Le mécanisme des variantes du RFC 5646 ne suffisait pas pour cela, d'où la nouvelle extension. C'est la deuxième enregistrée, après la « U » du RFC 6067. Le mécanisme d'extension est normalisé dans le RFC 5646, sections 2.2.6 et 3.7. Les extensions sont enregistrées dans le registre IANA.

Parfois, il existe des méthodes standard de translittération ou de transcription. C'est par exemple le cas de celles spécifiées par l'UNGEGN. La nouvelle extension « T » permet également d'indiquer comment et par quelle méthode standard un texte a été translittéré ou transcrit.

Maintenant, les détails techniques : l'extension est notée par un t suivi d'une étiquette de langue légale (section 2, notamment 2.2). Ainsi, es-t-pid signifie que le texte est en espagnol, traduit du piaroa. Mais, comme le texte après t peut être une étiquette de langue complète, on peut noter bien plus de détails, comme l'écriture utilisée (comme dans l'exemple du perse plus haut). Comme l'étiquette de langue doit comporter obligatoirement une langue en première position, si celle-ci n'est pas connue ou tout simplement pas pertinente (rappelez-vous que la différence principale entre translittération et transcription est que la première ne dépend pas de la langue, c'est une opération purement mécanique sur les caractères), on la note par und, ce qui veut dire « inconnue ». Ainsi, und-Latn-t-und-cyrl signifie que le texte a été translittéré de l'alphabet cyrillique vers le latin (par exemple par l'algorithme ISO 9), sans tenir compte des langues en jeu.

Enfin, il est possible d'indiquer le mécanisme de transformation, en utilisant le séparateur m0, puis l'organisme qui spécifie ces mécanismes, puis un identificateur d'un mécanisme particulier. Ainsi, und-Cyrl-t-und-latn-m0-ungegn-2007 est du texte en alphabet latin, transformé en cyrillique, suivant la spécification UNGEGN de 2007. D'autres séparateurs que m0 seront peut-être créés dans le futur.

Quels termes peut-on mettre après m0 ? Ce qui vous passe par la tête ? Non. Il faut suivre la section 3 du document Unicode UTR #35. C'est d'ailleurs le consortium Unicode qui est l'autorité gérant l'extension « T » (section 2.4). Cela a suscité de vigoureuses discussions (pourquoi pas l'IETF ?). La conséquence en a été la définition d'un mécanisme plus ouvert pour soumettre des propositions de changement. Si on veut enregistrer de nouvelles possibilités (section 2.6), cela se fait en créant un ticket en http://cldr.unicode.org/index/bug-reports/.

La liste complète des possibilités de mécanismes de transformation figure dans un fichier structuré (section 2.9), librement accessible en http://cldr.unicode.org/index/downloads. Ce point a suscité beaucoup de débats sur la liste de diffusion de l'ancien groupe de travail LTRU. En effet, le fichier officiel est un gros .zip rempli de tas de choses qui n'ont rien à voir. Il faut donc tout télécharger puis trier (les transformations sont dans le répertoire common/transforms).


Téléchargez le RFC 6497


L'article seul

RFC 6493: The RPKI Ghostbusters Record

Date de publication du RFC : Février 2012
Auteur(s) du RFC : R. Bush (Internet Initiative Japan)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


Les certificats de la RPKI, qui permettent de sécuriser le routage sur l'Internet en prouvant un droit à utiliser telle ou telle adresse IP, ne portent pas en clair de nom de titulaire. Cela peut être un problème dans certains cas opérationnels. Par exemple, une route reçue en BGP est refusée par le routeur, l'administrateur réseaux enquête, découvre un certificat qui a expiré, et voudrait prévenir le responsable qu'il a fait une boulette. Mais comment trouver le responsable ? Ou, selon la phrase culte du film Ghostbusters, « Who you gonna call? ». Ce RFC résoud le problème en permettant de mettre une vCard dans le certificat, indiquant qui contacter en cas de problème.

Il n'y a guère de doute que ce genre de problèmes sera fréquent. La RPKI permet de distribuer des certificats numériques disant « le titulaire de la clé privée de ce certificat est responsable du préfixe IP 2001:db8:137::/48 ». Ce certificat est ensuite utilisé pour signer les ROA (Route Origin Authorization) qui indiquent quel AS peut annoncer ce préfixe. Si on se fie à l'expérience du déploiement d'autres technologies à base de cryptographie dans l'Internet (par exemple DNSSEC), il y aura des problèmes : préfixes trop génériques, interdisant des annonces plus spécifiques, certificats expirés, oubli de créer un nouvel ROA lorsqu'on contracte avec un nouveau transitaire BGP, etc. Ceux et celles qui détecteront les problèmes auront donc besoin de contacter les responsables, dans l'espoir qu'ils agissent.

Or, les méta-données dans les certificats de la RPKI ne contiennent pas d'identificateurs utilisables par les humains (cf. RFC 6484). D'où l'idée de ce RFC, de mettre une vCard (plus exactement un profil restrictif des vCards du RFC 6350) dans un objet RPKI signé (la description de la syntaxe générique de ces objets est dans le RFC 6488).

Arrivé à ce stade, vous vous demandez peut-être « pourquoi un nouveau format au lieu d'utiliser les données des RIR, telles que publiées via whois ? ». La réponse est que l'enregistrement Ghostbusters identifie le responsable du certificat, qui n'est pas forcément le même que celui de la ressource (adresse IP ou numéro d'AS). Et puis, en pratique, les bases des RIR ne sont pas toujours correctes. Comme le chemin de mise à jour de l'enregistrement Ghostbuster est différent, peut-être sera-t-il parfois correct lorsque la base du RIR ne le sera pas ?

De toute façon, l'enregistrement Ghostbuster est facultatif. Un certificat peut en avoir zéro, un ou davantage. La section 3 du RFC fournit un exemple :

     BEGIN:VCARD
     VERSION:4.0
     FN:Human's Name
     ORG:Organizational Entity
     ADR;TYPE=WORK:;;42 Twisty Passage;Deep Cavern;WA;98666;U.S.A.
     TEL;TYPE=VOICE,TEXT,WORK;VALUE=uri:tel:+1-666-555-1212
     TEL;TYPE=FAX,WORK;VALUE=uri:tel:+1-666-555-1213
     EMAIL:human@example.com
     END:VCARD

En fait, cette vCard est embarquée dans un objet de la RPKI, qu'on peut lire avec des outils comme openssl. Voici un exemple sur un objet réel :

%  openssl asn1parse -inform DER \
          -in b-hiK-PPLhH4jThJ700WoJ3z0Q8.gbr
...
   60:d=5  hl=3 l= 139 prim: OCTET STRING      :BEGIN:VCARD
VERSION:3.0
EMAIL:michael.elkins@cobham.com
FN:Michael Elkins
N:Elkins;Michael;;;
ORG:Cobham Analytic Solutions
END:VCARD
...

Le sous-ensemble de vCard qui est accepté dans les chasseurs de fantômes est décrit en section 4. La définition est très restrictive : ne sont acceptées que les propriétés VERSION (qui doit valoir au moins 4, vous noterez que les enregistrements réels cités plus haut sont donc illégaux), FN, ORG, ADR, TEL et EMAIL (un enregistrement qui inclus N, comme ci-dessus, est donc illégal).

Ensuite (section 5), la vCard est embarquée dans un objet CMS signé (RFC 6488 ; la validation de ces enregistrements se fait de la même façon que pour les autres objets de la RPKI). Le type (OID) est 1.2.840.113549.1.9.16.1.35, ce qu'on voit dans la sortie d'openssl :

% openssl asn1parse -inform DER \
     -in owCgRbSAAkKS9W-MFbSAd7Bru2c.gbr 
...
   44:d=4  hl=2 l=  11 prim: OBJECT            :1.2.840.113549.1.9.16.1.35
   57:d=4  hl=3 l= 195 cons: cont [ 0 ]        
   60:d=5  hl=3 l= 192 prim: OCTET STRING      :BEGIN:VCARD
VERSION:3.0
ADR:;;5147 Crystal Springs;Bainbridge Island;Washington;98110;US
EMAIL:randy@psg.com
FN:Randy Bush
N:Bush;Randy;;;
ORG:RGnet\, LLC
TEL:+1 206 356 8341
END:VCARD

L'objet CMS est enfin mis dans un fichier d'extension .gbr. Fin 2011, on n'en trouvait que très peu dans les dépôts de la RPKI.

Attention, toutes ces données sont publiques. Comme le rappelle la section 8, sur la sécurité, publier ses informations dans un enregistrement Ghostbuster et vous risquez d'être harcelé par des commerciaux au téléphone ou bien spammé.

D'autre part, l'entité qui signe l'objet ne garantit nullement que les informations sont correctes. Elle garantit juste que ces informations ont bien été mises par le titulaire de la ressource (préfixe IP ou AS) correspondante. Celui-ci a pu mettre un numéro de téléphone ou une adresse de courrier bidon...


Téléchargez le RFC 6493


L'article seul

RFC 6492: A Protocol for Provisioning Resource Certificates

Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Huston, R. Loomans, B. Ellacott (APNIC), R. Austein (ISC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


La RPKI est l'infrastructure de création et de distribution de certificats pour les titulaires de ressources Internet (essentiellement les adresses IP), afin de sécuriser le routage sur l'Internet. Ce RFC normalise un protocole de communication pour réclamer ces certificats (avitaillement, ou provisioning). Il sera typiquement utilisé entre les RIR et les LIR.

Les termes exacts utilisés par le RFC sont Émetteur (Issuer), en général un RIR, qui va donc être une AC, et Destinataire (Subject), qui sera un FAI ou autre opérateur réseau. Le RIR distribue des INR (Internet Number Resource, ce sont les adresses IP et les numéros d'AS, collectivement nommés Ressources) et les certificats prouvant le droit du Destinataire à utiliser ces INR. Notez qu'un Destinataire peut être Émetteur pour des ressources qu'il redistribuera, par exemple à des opérateurs plus petits.

Le trafic attendu rend nécessaire d'automatiser l'avitaillement des certificats. Cela se fait avec un simple protocole (section 3), qui est une extension de HTTP. Le client HTTP fait une requête POST (RFC 2616, section 9.5), de type MIME application/rpki-updown. Le protocole est strictement requête/réponse (synchrone). Aussi bien le corps de la requête, que celui de la réponse du serveur, sont au format CMS (RFC 5652), encodé en DER. Le profil CMS est défini en section 3.1. CMS permet de transporter les signatures des différents objets (et les méta-données associées comme la date de signature) mais le gros du contenu est un élément XML stocké dans le CMS sous le nom de RPKIXMLProtocolObject.

Cet élément XML est forcément <message>. Il forme l'essentiel de la requête ou de la réponse. Sa grammaire est décrite en Relax NG en section 3.7.

Quelles sont les opérations possibles ? Elles sont indiquées par l'attribut type de la requête. Par exemple, le client peut demander une liste des ressources que lui a alloué le serveur, avec type="list". La réponse arrivera sous forme d'une séquence d'éléments <class>. Ou bien il peut demander un certificat pour une nouvelle ressources avec type="issue".

Naturellement, vu que tout le but de l'exercice est d'augmenter la sécurité du routage dans l'Internet, les implémenteurs et les utilisateurs de ce RFC devraient bien faire attention à la section 4, qui couvre la sécurité de ce protocole d'avitaillement. Le RFC précise que l'Émetteur et le Destinataire doivent s'authentifier (par les siognatures contenues dans les messages CMS), en utilisant des lettres de créance qu'ils ont échangé précédemment (par un moyen non spécifié). On note que TLS n'est pas utilisé par ce protocole (ce fut une chaude discussion au sein du groupe de travail), CMS fournissant tous les services de sécurité nécessaires.

Je ne connais pas encore de mise en œuvre publique de ce protocole mais plusieurs RIR ont annoncé qu'ils auraient des serveurs prêts pour la sortie du RFC.


Téléchargez le RFC 6492


L'article seul

RFC 6491: RPKI Objects issued by IANA

Date de publication du RFC : Février 2012
Auteur(s) du RFC : T. Manderson, L. Vegoda (ICANN), S. Kent (BBN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


La RPKI est le système de distribution de certificats et d'objets signés avec les clés de ces certificats, qui permet de poser les bases d'une sécurisation du routage dans l'Internet, en permettant aux titulaires des ressources (préfixes d'adresses IP, notamment), d'autoriser tel ou tel opérateur et uniquement ceux-ci, à utiliser ces ressources. Certains préfixes ne sont pas alloués à un utilisateur, ils dépendent directement de l'IANA et ce RFC 6491 est donc consacré à lister les tâches de l'IANA pour ces préfixes. Par exemple, l'IANA devra émettre et signer un objet disant « Personne ne peut annoncer de route vers 198.51.100.0/24 (ce préfixe étant réservé, par le RFC 5737, à la documentation) ».

Rappelons que les responsabilités de l'IANA vis-à-vis de l'IETF sont fixées par le RFC 2860. Pour le cas particulier de la RPKI (RFC 6480), l'IANA va devoir verrouiller l'usage des préfixes IP qu'elle gère (section 1). Ces préfixes sont utilisées pour la documentation ou réservés pour d'autres usages. Comme personne ne doit les router, l'IANA va émettre des ROA (RFC 6482) négatifs, c'est-à-dire prouvant que ces adresses ne sont pas routables. Un routeur BGP validant (RFC 6483) va alors pouvoir les rejeter, si jamais ils apparaissent dans des annonces de routes. Ces ROA négatifs sont officiellement appelés « AS0 ROA », le numéro d'AS zéro étant invalide (il ne doit jamais être dans un chemin d'AS). La section 4 du RFC 6483 détaille ce concept de désaveu de route.

Ce désaveu s'applique aux préfixes qui sont prévus pour ne jamais apparaître dans la table de routage globale (section 5), ainsi qu'à ceux qui ne sont pas actuellement alloués et donc toujours à l'IANA (aujourd'hui, cela ne concerne plus qu'IPv6, cf. section 6). Les adresses « spéciales » (section 7, voir aussi le RFC 5736) se divisent, elles, en deux : celles prévues pour être routées globalement, pour lesquelles l'IANA ne doit rien faire, et celles non prévues pour être routées, et pour lesquelles il y aura donc un AS0 ROA.

La liste des préfixes figure en annexe A du RFC. On y trouve les suspects habituels, le préfixe 169.254.0.0/16 ou fe80::/10 des adresses locales au lien, les préfixes privés des RFC 1918 et RFC 4193, les préfixes réservés à la documentation... Tous ceux-ci ne seront jamais routés sur l'Internet.

Avant de commencer à émettre ces ROA, l'IANA devra évidemment établir une CA (section 10). Cette CA devra utiliser les extensions à X.509 du RFC 3779. Elle devra aussi publier la liste de ses objets (j'avoue n'avoir pas trouvé où c'était documenté sur le site de l'IANA...).


Téléchargez le RFC 6491


L'article seul

RFC 6488: Signed Object Template for the Resource Public Key Infrastructure

Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Lepinski, A. Chi, S. Kent (BBN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


Le système de sécurisation de BGP et du routage sur l'Internet, qui tourne autour de la RPKI, utilise des objets numériques signés cryptographiquement pour représenter les autorisations d'annoncer telle ou telle route. Ces objets sont définis avec la syntaxe CMS et le profil que normalise ce RFC.

Le contenu typique de ces objets est une autorisation du genre « L'AS 64641 est autorisé à annoncer le préfixe 192.0.2.0/24 ». Ils sont ensuite signés avec les clés contenues dans les certificats qui identifient le titulaire de ces ressources (ici, seul le titulaire de 192.0.2.0/24 peut émettre l'autorisation ci-dessus). Ces certificats suivent le format du RFC 6487.

Les objets d'autorisation utilisent la syntaxe de CMS (RFC 5652), celle-ci permettant de réutiliser les nombreux outils CMS existants (dont plusieurs en logiciel libre, voir mon article sur les outils de la RPKI). Sur cette syntaxe CMS est bâti le gabarit présenté par ce RFC 6488, qui s'applique à tous les objets de la RPKI. Enfin, sur ce gabarit, est bâti la syntaxe précise de chaque type d'objet. Par exemple, les ROA (Route Origination Authorization), une classe particulière d'objets, sont normalisés dans le RFC 6482.

La syntaxe est décrit dans la section 2 du RFC. CMS utilisant ASN.1, le profil de notre RFC 6488 est décrit en ASN.1. On part de la définition SignedData du RFC 5652 :

      SignedData ::= SEQUENCE {
        version CMSVersion,
        digestAlgorithms DigestAlgorithmIdentifiers,
        encapContentInfo EncapsulatedContentInfo,
        certificates [0] IMPLICIT CertificateSet OPTIONAL,
        crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
        signerInfos SignerInfos }

et on y ajoute quelques restrictions ou précisions. Par exemple, le digestAlgorithm doit être un de ceux spécifiés dans le RFC 6485. Mëme méthode pour les méta-données de signature :

         SignerInfo ::= SEQUENCE {
           version CMSVersion,
           sid SignerIdentifier,
           digestAlgorithm DigestAlgorithmIdentifier,
           signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
           signatureAlgorithm SignatureAlgorithmIdentifier,
           signature SignatureValue,
           unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }

Les objets de la RPKI doivent être encodés en DER. La liste des règles sémantiques à respecter figure dans la section 3.

Je le rappelle, ce profil, bien que spécialisé par rapport à CMS, est encore très générique. Chaque classe d'objets signés va donc nécessiter son propre RFC, remplissant les blancs indiqués par la section 4 :

  • Indiquer un OID pour la classe en question (1.2.840.113549.1.9.16.1.24 pour les ROA ou 1.2.840.113549.1.9.16.1.26 pour les manifestes du RFC 6486),
  • Définir la syntaxe du champ encapContentInfo (qui contient les données effectivement signées),
  • Indiquer les règles spécifiques de validation (pour un ROA : que le certificat signeur ait été émis pour le préfixe indiqué dans le ROA), s'ajoutant aux règles génériques de CMS (validité de la signature).

Ces classes d'objets sont ensuite enregistrés à l'IANA (section 6).

Notez bien que la sécurité que fournissent ces objets signés est d'authentification et d'intégrité. Les données ne sont pas chiffrées et donc pas confidentielles (section 5). C'est logique, les tables BGP et les informations dans les IRR sont publiques.


Téléchargez le RFC 6488


L'article seul

RFC 6487: A Profile for X.509 PKIX Resource Certificates

Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Huston, G. Michaelson, R. Loomans (APNIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


La norme de certificats numériques X.509 est d'une telle complexité (comme beaucoup de productions des comités de l'UIT) qu'il est à peu près impossible de la mettre en œuvre complètement et correctement. La plupart de ses utilisations se font sur un profil de la norme, c'est-à-dire une restriction des usages possibles. De tels profils ont permis l'utilisation pratique de X.509, notamment sur l'Internet. Le profil décrit dans ce RFC a été conçu pour les certificats décrivant le « droit d'utilisation » des ressources Internet, ce qui veut dire, dans le monde du routage, les adresses IP et numéros d'AS (collectivement : les INR pour Internet Number Resources). Ces certificats ainsi profilés seront ensuite ceux utilisés pour la RPKI, afin de sécuriser le routage sur l'Internet.

Rappelons le principe : des certificats sont émis par une autorité, l'AC. Ces certificats suivent le profil décrit ici, qui est lui-même dérivé du profil PKIX du RFC 5280, de loin le plus répandu sur l'Internet. Ces certificats permettent à l'autorité de dire « le titulaire de ce certificat a le droit d'utiliser les adresses 2001:db8:f33::/48, par exemple de les annoncer en BGP », en utilisant les extensions INR du RFC 3779. L'engin qui va valider les routes (c'est typiquement une machine spécialisée, agissant pour le compte d'un routeur) fera une validation X.509 de la chaîne des certificats, plus quelques vérifications spécifiques aux INR (par exemple, dans certains cas, le certificat peut autoriser une route plus spécifique) et dira ensuite si la route est valide, ou bien si elle est émise par un attaquant (ou un maladroit qui a mal configuré BGP).

Donc, un certificat de la RPKI est un certificat PKIX. Les principaux points de notre nouveau profil (section 4) sont le fait que le sujet est un nom choisi par l'AC, la présence obligatoire des extensions INR (Internet Number Resources) du RFC 3779 (le certificat prouve le droit d'usage des préfixes IP indiqués dans ces extensions), et l'indication d'un dépôt accessible en rsync où se trouvent les CRL. Les sections 2 à 6 donnent tous les détails sur ces points.

Quant à la validation des certificats, elle fait l'objet de la section 7, qui précise les points généraux de la section 6 du RFC 5280. Notamment, un certificat peut être accepté même si le préfixe d'adresses présenté est plus spécifique (davantage de bits dans le masque).

La section 8 explique ensuite (et justifie) les principaux choix qui ont été faits lors de la conception de ce profil. Par exemple, notre profil ne permet pas d'utiliser des extensions X.509 autres que celles décrites dans ce RFC. Le but est d'utiliser les certificats dans un environnement bien défini, pour un usage limité, et il s'agit donc de limiter au maximum les risques de non-interopérabilité (un problème fréquent avec X.509, norme conçue par un comité et d'une très grande complexité ; bien des parties de la norme n'ont jamais été testées sur le terrain et nul ne sait comment réagiraient les implémentations). En outre, la RPKI est conçu pour être utilisée dans un contexte opérationnel (le routage sur l'Internet) et il était donc raisonnable de sacrifier l'extensibilité.

Quant au choix du nom du sujet, la RPKI n'étant pas centralisée, et n'ayant pas de système d'allocation arborescente des noms, on ne peut pas espérer avoir des noms uniques. Le RFC conseille donc aux AC (les RIR et les opérateurs réseau) d'adopter un schéma de nommage qui garantisse l'unicité au sein d'une même AC (rappelez-vous que, contrairement à l'utilisation de X.509 dans le cas de TLS, le nom du sujet n'est pas utilisé par la RPKI et n'est donc pas vérifié). Cela peut même être une valeur aléatoire comme un UUID.

L'annexe A du RFC fournit un exemple d'un certificat à ce profil. Mais on peut aussi l'obtenir en regardant un vrai certificat de la RPKI avec openssl (attention, il faut s'assurer qu'il ait été compilé avec l'option enable-rfc3779, ce qui n'est pas le cas chez Debian) :

% openssl x509 -inform DER -text -in \
    ./RPKI-repository/33/36711f-25e1-4b5c-9748-e6c58bef82a5/1/wdWccNZAgvBWFvBZNDJDWLtf-KQ.cer
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 78697736 (0x4b0d508)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=u75at9r0D4JbJ3_SFkZXD7C5dmg
        Validity
            Not Before: May 13 07:43:52 2011 GMT
            Not After : Jul  1 00:00:00 2012 GMT
        Subject: CN=wdWccNZAgvBWFvBZNDJDWLtf-KQ
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:99:d8:66:8b:26:15:22:fd:8e:45:c2:32:79:eb:
                    a4:36:d0:6d:47:18:34:d4:ad:17:bf:6f:82:d7:a3:
                    85:d9:80:ea:9f:59:31:6d:da:9f:b5:e0:36:67:e0:
                    f0:00:1b:96:2d:71:3e:5f:35:e0:f9:98:ee:fa:9f:
                    3e:6b:ab:9e:18:a6:ad:3c:fd:7a:50:6d:a5:42:4c:
                    bd:2d:02:f0:2a:7a:e6:66:bf:d5:b1:83:f1:19:02:
                    fe:90:21:d2:e3:b3:cc:91:a4:a6:6f:70:be:65:62:
                    7f:97:c1:43:2e:2c:a5:b2:14:79:e0:f5:5e:4b:c2:
                    aa:ed:13:d0:f2:4d:47:ac:53:fd:82:78:ef:c9:cd:
                    94:ea:52:10:56:88:80:bc:ca:ad:92:46:ef:4c:ae:
                    aa:ae:ae:02:d6:af:ae:2a:4e:dc:8b:c9:43:57:27:
                    84:1f:5a:82:ff:d7:24:ac:25:67:66:5f:70:d1:d6:
                    45:4b:a5:1d:c2:6f:bf:ae:14:3d:e4:2b:50:35:72:
                    ea:52:1c:b2:7d:15:12:15:07:d1:86:bb:2b:4b:ba:
                    47:1c:3e:37:b7:2c:ab:a6:4e:d3:16:54:84:96:92:
                    37:b6:6c:5c:3b:61:f1:73:9e:9c:9b:b8:ad:33:f8:
                    e0:19:9e:6a:dc:30:a6:45:90:f7:90:bb:d2:f9:65:
                    5b:53
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                C1:D5:9C:70:D6:40:82:F0:56:16:F0:59:34:32:43:58:BB:5F:F8:A4
            X509v3 Authority Key Identifier: 
                keyid:BB:BE:5A:B7:DA:F4:0F:82:5B:27:7F:D2:16:46:57:0F:B0:B9:76:68

            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            Authority Information Access: 
                CA Issuers - URI:rsync://rpki.ripe.net/ta/u75at9r0D4JbJ3_SFkZXD7C5dmg.cer

            Subject Information Access: 
                CA Repository - URI:rsync://rpki.ripe.net/repository/72/f82cc3-00a3-4229-92ff-e5992b4b3fad/1/
                1.3.6.1.5.5.7.48.10 - URI:rsync://rpki.ripe.net/repository/72/f82cc3-00a3-4229-92ff-e5992b4b3fad/1/wdWccNZAgvBWFvBZNDJDWLtf-KQ.mft

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:rsync://rpki.ripe.net/repository/33/36711f-25e1-4b5c-9748-e6c58bef82a5/1/u75at9r0D4JbJ3_SFkZXD7C5dmg.crl

            X509v3 Certificate Policies: critical
                Policy: 1.3.6.1.5.5.7.14.2

            sbgp-ipAddrBlock: critical
                IPv4:
                  81.27.128.0/20
                IPv6:
                  2a00:8980::/32

    Signature Algorithm: sha256WithRSAEncryption
        8f:03:51:23:44:85:92:42:54:37:a2:22:53:66:0a:ab:be:a7:
        ...
        2e:31:d5:0d
-----BEGIN CERTIFICATE-----
MIIFLDCCBBSgAwIBAgIEBLDVCDANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBt1
...
-----END CERTIFICATE-----

Voyez notamment :

  • Le sujet (nom du titulaire du certificat) unique, ici CN=wdWccNZAgvBWFvBZNDJDWLtf-KQ généré à partir d'un condensat cryptographique,
  • L'indication de l'endroit où on peut récupérer les CRL (rsync://rpki.ripe.net/repository/33/36711f-25e1-4b5c-9748-e6c58bef82a5/1/u75at9r0D4JbJ3_SFkZXD7C5dmg.crl),
  • Le certificat de l'AC (rsync://rpki.ripe.net/ta/u75at9r0D4JbJ3_SFkZXD7C5dmg.cer),
  • Les extensions du RFC 3779, ici le bloc mal nommé sbgp-ipAddrBlock, qui contient un préfixe IPv4 et un IPv6 (attention, pour les voir, il faut un openssl compilé avec la bonne option).

Téléchargez le RFC 6487


L'article seul

RFC 6483: Validation of Route Origination using the Resource Certificate PKI and ROAs

Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Huston (APNIC), G. Michaelson (APNIC)
Pour information
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


Ce document s'inscrit dans la longue liste des RFC sur la sécurisation du routage BGP. Il décrit la sémantique des ROA (Route Origin Authorization), ces objets qui expriment l'autorisation du titulaire d'un préfixe IP à ce que ce préfixe soit annoncé initialement par un AS donné. La syntaxe des ROA, elle, figure dans le RFC 6482.

Les ROA (Route Origin Authorization) sont issus de la RPKI, l'IGC du routage (RFC 6480). Ce sont des objets signés qu'un routeur BGP peut vérifier lorsqu'il reçoit une annonce. Ainsi, si un routeur BGP voit son pair lui dire « je connais un chemin vers 192.0.2.0/24 et son chemin d'AS est 64498 65551 65540 », le routeur peut vérifier que l'AS 65540 a bien été autorisé, par le titulaire du préfixe 192.0.2.0/24, à annoncer cette route (l'origine, le premier AS, est le plus à droite ; ce RFC ne permet de valider que l'origine, pas le chemin complet, donc on ne peut rien dire au sujet de la présence des AS 64498 et 65551). Les clés utilisées pour les signatures sont contenues dans des certificats X.509 suivant le format Internet standard (RFC 5280) avec des extensions pour stocker des informations comme les adresses IP (RFC 3779). Ces certificats permettent de vérifier que le signataire était bien titulaire de la ressource (ici, le préfixe 192.0.2.0/24). Quant au format des ROA, on l'a dit, il figure dans le RFC 6482.

Tout d'abord (section 2 du RFC), que se passe-t-il pendant la validation d'une annonce de route et quels sont les résultats possibles ? Une route est composée d'un ensemble de préfixes IP, d'un chemin d'AS et de quelques attributs. L'origine, la seule chose vérifiée par les ROA, est le premier AS du chemin (donc le plus à droite). S'il y a eu agrégation, et que le premier élément du chemin est un ensemble d'AS, l'origine est inconnue.

L'engin qui fait la validation (nommé RP, pour Relying Party, c'est le routeur BGP, ou bien une machine spécialisée à laquelle il a sous-traité ce travail) est supposé avoir accès à tous les ROA valides (ce RFC ne décrit pas comment, il n'existe pas encore de protocole standard de récupération des ROA, même s'il y en a un en développement, nommé RTR). Il cherche les ROA s'appliquant à l'annonce qu'il veut valider. Si un ROA correspond, l'annonce est valide. Un ROA pour un préfixe donné s'applique à tous les préfixes plus spécifiques (ceux où le masque est plus long). Ainsi, si un ROA dit « l'AS 65540 a le droit d'annoncer 192.0.2.0/24 », alors une annonce de 192.0.2.128/25 (plus spécifique) est invalide (même si l'origine est la même, cf. le tableau Route's validity state). Toutefois, l'utilisation du champ maxLength dans le ROA permet d'accepter des préfixes plus spécifiques (jusqu'à maxLength). Si une annonce ne correspond à aucun ROA, elle est dans l'état « inconnu » (également appelé « non trouvé »). Au début du déploiement, évidemment, la plupart des annonces seront dans l'état inconnu, puisque peu de ROA seront émis. Mais dès qu'un opérateur crée un ROA pour un de ses préfixes, tous les sous-préfixes non signés deviennent invalides (la RPKI suit le modèle hiérarchique des adresses IP). L'algorithme exact est décrit à la fin de la section 2. (Ceux qui ont suivi toute l'histoire de ce RFC avant sa publication noteront que l'algorithme initial était bien plus complexe.)

Maintenant, que faire de ce résultat ? La section 3 explique comment utiliser cet état (valide, invalide, inconnu) pour sélectionner une route (rappelez-vous qu'un routeur BGP typique reçoit plusieurs routes possibles pour chaque préfixe et qu'il doit choisir). En gros, le routeur doit préférer les routes valides, puis les inconnues. Mais la décision est locale : le RFC n'impose rien, notamment il ne dit pas si le routeur doit ignorer complètement les annonces invalides ou, a fortiori, les inconnues (la très grande majorité, au début du déploiement de ce système). Autre piège : la vitesse de propagation des ROA ne sera pas forcément celle des routes, et une annonce peut arriver avant le ROA correspondant.

Le problème est similaire à celui que connaissent les résolveurs DNS avec DNSSEC. Rejeter les réponses DNS non signées, aujourd'hui, reviendrait à rejeter la majorité des réponses. (Une autre expérience de DNSSEC est que les réponses invalides sont beaucoup plus souvent dues à des erreurs du gentil administrateur systèmes qu'à des attaques par les méchants.) Pour BGP, le problème est plus complexe car il est normal de recevoir plusieurs routes vers la même destination. Sans rejeter les annonces inconnues, le routeur peut donc décider de les faire passer après les valides. Et, s'il n'y a qu'une seule route pour une destination donnée, et que l'annonce est invalide, il vaut peut-être mieux l'accepter que de couper la communication avec le réseau concerné (la résilience de l'Internet le recommande).

Donc, pour résumer la section 3 : chaque administrateur réseaux configure son routeur comme il veut, pour décider du sort des annonces inconnues, et même pour celui des annonces invalides. Un exemple en syntaxe IOS serait :

route-map rpki permit 10
 match rpki invalid
 set local-preference 50

route-map rpki permit 20
 match rpki unknown
 set local-preference 100

route-map rpki permit 30
 match rpki valid
 set local-preference 200

Dans cet exemple, tous les états sont acceptés, mais avec des préférences différentes.

Il est également possible à un titulaire de préfixe d'interdire complètement l'utilisation de ce préfixe, en créant un ROA où le numéro d'AS est mis à zéro (section 4). L'AS 0 est réservé dans le registre IANA et ne doit jamais apparaître dans une annonce réelle.

Une fois une route validée, pendant combien de temps garde-t-elle son état ? Question facile à laquelle la section 5 répond : la durée de validité est celle du certificat qui a signé le ROA (rappelez-vous que les ROA indiquent l'AS d'origine, et que c'est une information relativement stable). Si on veut annuler un ROA avant, il faut révoquer le certificat qui l'a signé.

La section 6 rassemble les considérations de sécurité des ROA : d'abord, elle rappelle qu'il y a un risque réel de se tirer dans le pied. Si on publie un ROA pour un préfixe, les préfixes plus spécifiques deviennent aussitôt invalides. Si on a de ces préfixes plus spécifiques, il faut donc penser à leur créer un ROA avant de publier le ROA le plus général.

Voilà, si vous voulez mettre tout cela en pratique, lisez mon article sur les logiciels de la RPKI.


Téléchargez le RFC 6483


L'article seul

RFC 6482: A Profile for Route Origin Authorizations (ROAs)

Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Lepinski, S. Kent, D. Kong (BBN Technologies)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


Un nouveau sigle va devoir être appris par les administrateurs réseaux et sera sans doute souvent prononcé dans les discussions sur les listes de diffusion d'opérateurs : ROA, pour Route Origin Authorizations, ces objets signés cryptographiquement qui permettent à un routeur BGP de valider l'origine d'une route. Dans la très longue liste des RFC décrivant ce système de sécurité, notre court RFC 6482 décrit le format des ROA.

Ces ROA (Route Origin Authorizations) sont, à bien des égards, le cœur du système de sécurisation du routage de l'Internet (dont l'architecture générale est décrite dans le RFC 6480). Ils expriment des autorisations d'annonce, par exemple « L'AS 64641 est autorisé à annoncer le préfixe 192.0.2.0/24 » et sont signés par le titulaire de la ressource (ici, le titulaire du préfixe 192.0.2.0/24).

Le format des ROA est tiré de la norme CMS (RFC 5652), précisée par le profil générique des objets de la RPKI, dans le RFC 6488. Ce dernier RFC précise, dans sa section 4, les points spécifiques à normaliser pour chaque classe d'objets de la RPKI. Dans le cas des ROA, ces blancs sont remplis ainsi :

  • L'OID de la classe « ROA » est 1.2.840.113549.1.9.16.1.24 (section 2),
  • Le contenu du ROA est composé (section 3) d'un numéro d'AS (celui qui est autorisé à être à l'origine de la route) et d'un ou plusieurs préfixes IP (un seul dans l'exemple plus haut), qui sont les préfixes où cet AS peut être à l'origine,
  • Des règles de validation spécifiques au ROA sont indiquées (section 4).

Le contenu précis, tel qu'indiqué dans la section 3, est, en ASN.1 :

      RouteOriginAttestation ::= SEQUENCE { 
         version [0] INTEGER DEFAULT 0, 
         asID  ASID, 
         ipAddrBlocks SEQUENCE (SIZE(1..MAX)) OF ROAIPAddressFamily } 

asID est le numéro d'AS, et ipAddrBlocks la liste des préfixes. Les ROAIPAddressFamily sont composées de ROAIPAddress et celles-ci ont un attribut intéressant, maxLength, qui indique la longueur maximale des sous-préfixes que peut annoncer cet AS. Par exemple, en IPv6, un maxLength de 56 indiquera qu'on peut annoncer un /56 mais pas un /60. L'autre attribut d'une ROAIPAddress est le préfixe, représenté selon les règles du RFC 3779.

La section 4 décrit quant à elle les règles de validation spécifiques aux ROA : aux règles génériques des objets de la RPKI, elle ajoute l'obligation de vérifier que les adresses indiquées dans le ROA figurent bien dans le certificat signataire (c'est-à-dire que c'est bien le titulaire des adresses qui a émis le ROA). Mais il vaut mieux consulter le RFC 6483 pour avoir tous les détails.

À noter qu'on ne peut mettre qu'une seule signature par ROA. Une des vives discussions du groupe de travail SIDR avait porté sur la possibilité de signatures multiples, afin de gérer certaines relations complexes entre clients et opérateurs, mais cela avait finalement été rejeté.

On peut récupérer tous les ROA des préfixes RIPE en https://certification.ripe.net/certification/public/all-roas. Si on en télécharge un, on peut afficher ce contenu avec l'outil du même RIPE-NCC :

% certification-validator  --print -f  roa-5574190.roa
Content type: 1.2.840.113549.1.9.16.1.24                        
Signing time: 2011-01-11T19:04:18.000Z
ASN: AS559
Prefixes:
    193.5.26.0/23 [24]
    193.5.152.0/22 [24]
    193.5.168.0/22 [24]
    193.5.22.0/24
    193.5.54.0/23 [24]
    193.5.58.0/24
    193.5.60.0/24
    193.5.80.0/21 [24]

ou bien avec l'outil de l'ARIN, rcynic :

% print_roa /home/bortzmeyer/tmp/roa-5574190.roa
Certificates:   1
CRLs:           0
SignerId[0]:    b6:6f:5a:10:d5:7f:ed:6d:b1:62:96:2c:cb:92:35:bb:5d:f8:c3:ca [Matches certificate 0] [signingTime(U) 110111190418Z]
eContentType:   1.2.840.113549.1.9.16.1.24
version:        0 [Defaulted]
asID:           559
 addressFamily: 1
     IPaddress: 193.5.26.0/23-24
     IPaddress: 193.5.152.0/22-24
     IPaddress: 193.5.168.0/22-24
     IPaddress: 193.5.22.0/24
     IPaddress: 193.5.54.0/23-24
     IPaddress: 193.5.58.0/24
     IPaddress: 193.5.60.0/24
     IPaddress: 193.5.80.0/21-24

Comme les ROA sont en CMS, on peut aussi tenter sa chance avec des logiciels qui traitent du CMS générique. Ils ne comprendront pas tout mais pourront au moins afficher une partie de la structure :

% openssl asn1parse -inform DER -in RFZr0zO7xjc1bNCEVboVjI8JZlw.roa
    0:d=0  hl=2 l=inf  cons: SEQUENCE          
    2:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-signedData
...
 1340:d=7  hl=2 l=   9 prim: OBJECT            :contentType
 1351:d=7  hl=2 l=  13 cons: SET               
 1353:d=8  hl=2 l=  11 prim: OBJECT            :1.2.840.113549.1.9.16.1.24
 1366:d=6  hl=2 l=  28 cons: SEQUENCE          
 1368:d=7  hl=2 l=   9 prim: OBJECT            :signingTime
 1379:d=7  hl=2 l=  15 cons: SET               
 1381:d=8  hl=2 l=  13 prim: UTCTIME           :110406122632Z
 1396:d=6  hl=2 l=  47 cons: SEQUENCE          
...

De même, les outils génériques ASN/1 comme dumpasn1 peuvent permettre de récupérer une partie de l'information dans le ROA. D'autres outils pour jouer avec les ROA sont présentés dans mon article sur les logiciels de la RPKI.


Téléchargez le RFC 6482


L'article seul

RFC 6481: A Profile for Resource Certificate Repository Structure

Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Huston (APNIC), R. Loomans (APNIC), G. Michaelson (APNIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


La RPKI, cette infrastructure de certificats utilisée pour sécuriser le routage sur l'Internet, repose sur un certain nombre d'objets (certificats mais aussi révocations et surtout les objets signés qui expriment les autorisations, les ROA). Ce RFC décrit comment ils sont stockés dans les points de publication à partir desquels ils sont distribués au monde entier. Cela permet de consolider facilement les données obtenues auprès de plusieurs points de publication. (Il n'est pas obligatoire qu'une copie de la RPKI soit complète.)

Rappelez-vous en effet que les routeurs n'accèdent pas aux informations de la RPKI lorsqu'ils en ont besoin (ce qui ferait dépendre le routeur de serveurs extérieurs) mais à l'avance en chargeant dans un validateur la totalité des informations, que le validateur va ensuite vérifier avant de passer au routeur. Comment se présentent ces informations ? Chacun fait comme il veut mais il existe une forme recommandée, celle de notre RFC 6481.

Dans ce format recommandé, chaque objet va être un fichier. Ces fichiers vont être placés dans une arborescence de répertoires, référencée par un URI (typiquement de type rsync:).

Dans les exemples ci-dessous, j'utiliserai une copie locale de la RPKI obtenue au RIPE-NCC, avec les outils logiciels de ce même RIPE-NCC (voir mon article sur ces outils).

À chaque point de publication (typiquement, chaque AC, c'est-à-dire en pratique chaque opérateur réseau), on trouve un manifeste qui liste les objets publiés. Le fichier a l'extension .mft, le type MIME application/rpki-manifest (cf. section 7.1 du RFC) et son nom est un condensat cryptographique de la clé publique de l'AC (en suivant par exemple la section 2.1 du RFC 4387). Voici le contenu d'un tel manifeste, à un petit point de publication (seulement quatre ROA) :

% certification-validator -print -file Sxe2vn2-fqZLB5Q578V0Vzf_RfQ.mft
Serial: 39571085
Subject: CN=779caa1de4e5938149c831b097a86ee561bf12f3
Not valid before: 2011-10-31T03:42:07.000Z
Not valid after:  2011-11-01T03:42:07.000Z
...
Filenames and hashes:
    1c_GrZeKKzG5b9BI9Iu4fEEG-QU.roa 20aade4dd3e303103b7facb0d462d89e0cc74753c99bf35a8ff28d16e48f7e6a
    1sOqx9K6uCNTcCTMIe7f5P1bZX0.roa 7e9c4c0be54d180b05743abbd6163f0a812c43d4db59fe0550eb2446ceedbb7e
    4nKGhPF4_7JKjwwBrTCXgE_4YYg.roa f1f55d72eb6e66c36b6312c4c6484a83156d32b7e01067a6a3449327095e409f
    Sxe2vn2-fqZLB5Q578V0Vzf_RfQ.crl 39ec393db6b9a8ec6289304a5c1982ab17ef3bfc5feaffaf4a30174af9054966
    TZw7cXuBc5b9BOlBHqCtAEgTZ-w.roa bd7aa3efae357a8591a7b5d708ccb509ad30f791063ea6fe9aa53730d95cb680

On trouve également des révocations, dans des fichiers ayant l'extension .crl (et le type MIME application/pkix-crl qui vient du RFC 2585) :

% certification-validator -print -file Sxe2vn2-fqZLB5Q578V0Vzf_RfQ.crl
CRL type: X.509
CRL version: 2
Issuer: CN=Sxe2vn2-fqZLB5Q578V0Vzf_RfQ
Authority key identifier: Sxe2vn2-fqZLB5Q578V0Vzf_RfQ=
Number: 790
This update time: 2011-10-31T03:42:07.000Z
Next update time: 2011-11-01T03:42:07.000Z
Revoked certificates serial numbers and revocation time:
    32399600 2011-09-10T05:40:48.000Z

On trouve bien sûr les certificats, encodés au format DER et stockés dans des fichiers ayant l'extension .cer et le type MIME application/pkix-cert :

% certification-validator -print -file Fx2dYP3STZSiTUjLGrM8oDkK4Ys.cer
Serial: 18282008
Subject: CN=Fx2dYP3STZSiTUjLGrM8oDkK4Ys
Not valid before: 2011-01-12T02:39:31.000Z
Not valid after:  2012-07-01T00:00:00.000Z
Resources: 46.254.48.0/21

Notez qu'il s'agit d'un format standard donc OpenSSL peut l'afficher aussi (pour voir les ressources gérées, ici 46.254.48.0/21, il faut un OpenSSL compilé avec l'option RFC 3779) :

% openssl x509 -inform DER -text -in Fx2dYP3STZSiTUjLGrM8oDkK4Ys.cer
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 18282008 (0x116f618)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=u75at9r0D4JbJ3_SFkZXD7C5dmg
        Validity
            Not Before: Jan 12 02:39:31 2011 GMT
            Not After : Jul  1 00:00:00 2012 GMT
        Subject: CN=Fx2dYP3STZSiTUjLGrM8oDkK4Ys
...
            sbgp-ipAddrBlock: critical
                IPv4:
                  46.254.48.0/21

Et, bien sûr, le dépôt contient des autorisations d'annonces de route, les ROA (Route Origination Authorization), normalisés dans le RFC 6482. Elles sont contenues dans des fichiers d'extension .roa et ont le type MIME application/rpki-roa :

% certification-validator -print -file FiUGfSV6BgZqFlJnQ7SSq_700w8.roa 
Content type: 1.2.840.113549.1.9.16.1.24
Signing time: 2011-04-11T15:07:23.000Z
ASN: AS56595
Prefixes:
    46.226.0.0/21
    2a00:a600::/32

Le ROA ci-dessus autorise l'AS 56595 à annoncer des routes pour 46.226.0.0/21 et 2a00:a600::/32. À noter que la suite logicielle rcynic permet également l'affichage de ROA :

% print_roa FiUGfSV6BgZqFlJnQ7SSq_700w8.roa
Certificates:   1
CRLs:           0
SignerId[0]:    16:25:06:7d:25:7a:06:06:6a:16:52:67:43:b4:92:ab:fe:f4:d3:0f [Matches certificate 0] [signingTime(U) 110411150723Z]
eContentType:   1.2.840.113549.1.9.16.1.24
version:        0 [Defaulted]
asID:           56595
 addressFamily: 1
     IPaddress: 46.226.0.0/21
 addressFamily: 2
     IPaddress: 2a00:a600::/32

La section 3 décrit ensuite les caractéristiques souhaitées du serveur qui va publier toutes ces informations. Il doit notamment être très fiable : même si le serveur n'est évidemment pas accédé de manière synchrone, à chaque mise à jour BGP, il doit néanmoins être accessible la grande majorité du temps, puisque toute panne empêchera les mises à jour de la base et aura potentiellement des conséquencees opérationnelles sur le routage. C'est une tâche nouvelle, par exemple pour les RIR, qui n'avaient pas de rôle opérationnel avant.

Ce serveur doit utiliser rsync (cf. RFC 5781) et peut aussi utiliser d'autres protocoles en prime. Grâce à rsync, la commande :

% rsync -av rsync://rpki.ripe.net/repository /var/RPKI

va vous récupérer tous les objets décrits ici, tels qu'ils sont distribués par le RIPE-NCC, et les mettre dans le répertoire /var/RPKI. rsync travaillant de manière incrémentale, seules les nouveautés seront chargées, pas la totalité de la base (sauf la première fois).

Cette commande peut donc être placée dans le crontab de la machine qui fera la validation. Toutefois, la section 3 recommande des techniques plus subtiles, à base de copie dans un dépôt temporaire puis de renommage (ce que font automatiquement les outils de rcynic), avant d'éviter une incohérence si le rsync est interrompu et qu'on n'a récupéré qu'une partie de la base.

Cette copie locale de la RPKI dans le validateur (machine qui sera proche des routeurs qui l'interrogeront) permettra de fonctionner même en cas de panne des serveurs de distribution (cf. section 5).

Attention à la sécurité, nous avertit la section 6. Les informations de la RPKI sont publiques, il n'y a donc pas besoin de confidentialité, mais il est essentiel que leur intégrité soit préservée. Le protocole rsync utilisé plus haut ne fournit aucune garantie en ce sens. En fait, la protection des données est complètement assurée par les signatures faites avec les clés contenues dans les certificats. Il ne faut donc pas utiliser les informations RPKI récupérées avant d'avoir validé (vérifié les signatures). C'est ce que fait automatiquement rcynic en déplaçant les données validées dans un répertoire nommé authenticated :

% pwd   
/var/rcynic/data

% ls -lt
total 12
lrwxrwxrwx  1 rcynic rcynic   34 Oct 31 15:42 authenticated -> authenticated.2011-10-31T13:36:08Z
lrwxrwxrwx  1 rcynic rcynic   34 Oct 31 15:42 authenticated.old -> authenticated.2011-10-31T11:36:11Z
drwxr-xr-x 15 rcynic rcynic 4096 Oct 31 15:42 authenticated.2011-10-31T13:36:08Z
drwxr-xr-x 15 rcynic rcynic 4096 Oct 31 14:31 authenticated.2011-10-31T11:36:11Z
drwxr-xr-x 17 rcynic rcynic 4096 Oct 31 11:31 unauthenticated

Les extensions des différents fichiers stockés figurent dans un registre IANA.


Téléchargez le RFC 6481


L'article seul

RFC 6480: An Infrastructure to Support Secure Internet Routing

Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Lepinski, S. Kent (BBN Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 Février 2012


Les techniques de sécurisation de BGP du groupe de travail SIDR viennent d'être publiées. Elles reposent sur une infrastructure de clés publiques cryptographiques, la RPKI (Resource Public Key Infrastructure). Ce RFC décrit cette RPKI, fondation de tous les systèmes de sécurisation du routage dans l'Internet, ainsi que l'architecture générale du système.

Le principe est le suivant : le titulaire d'un préfixe IP a un certificat lui permettant de signer des objets, par lesquels il autorise tel ou tel AS à annoncer ce préfixe. Ces signatures peuvent être ensuite vérifiées par les routeurs, qui rejetteront les erreurs et les tentatives de piratage.

La section 1 résume les trois composants essentiels de la solution, qui permettra de protéger le routage BGP (RFC 4271) :

  • La RPKI, l'infrastructure de gestion de clés, dont la hiérarchie est plaquée sur l'actuelle hiérarchie d'allocation des adresses (IANA -> RIR -> LIR, etc),
  • Des objets numériques signés (par les clés contenues dans les certificats de la RPKI), les routing objects, qui expriment les autorisations de routage,
  • Le mécanisme de distribution de ces objets, pour que les routeurs y aient accès afin de valider les annonces BGP.

Dans un premier temps, cette solution permettra de valider l'origine des annonces BGP (le premier AS, cf. RFC 6483). Plus tard, elle pourra servir de base à des solutions plus globales, encore en cours de développement, comme soBGP ou Secure Border Gateway Protocol (Secure-BGP).

La correspondance entre le graphe des certificats et celui existant pour allouer des ressources comme les adresses IP évite de réinventer une nouvelle classe d'acteurs. Cela ne veut pas dire que les rapports de force ne vont pas être modifiés. Ainsi, à l'heure actuelle, un RIR peut toujours, techniquement, retirer un préfixe à un LIR, mais cela n'aura pas de conséquence pratique, le RIR n'ayant aucun rôle dans le routage. Demain, avec la RPKI, le RIR enverra une révocation et les routeurs considéreront la route comme invalide... Il y a donc bien renforcement des pouvoirs de la hiérarchie, comme l'analysait un article de l'IGP.

Techniquement, peu de protocoles ou de formats nouveaux sont développés. Ainsi, les certificats de la RPKI sont du X.509, avec les extensions déjà existantes de l'IETF, RFC 5280, plus celles permettant de représenter des ressources (adresses IP et numéros d'AS), normalisées dans le RFC 3779 et suivant le profil du RFC 6487. Les objets signés (cf. RFC 6488) utilisent quant à eux le format CMS (RFC 5652).

Le premier des trois composants, la RPKI (Resource Public Key Infrastructure), est décrit en section 2. L'idée est que c'est le titulaire d'une plage d'adresses IP qui décide comment elle peut être routée et par qui. Les certificats permettent donc d'attester que telle entité est bien le titulaire (ce qui se fait actuellement en consultant la base du RIR, par exemple via whois). L'IANA va donc signer les plages qu'elle alloue aux RIR (cette étape est optionelle, voir plus loin), les RIR signent les plages qu'ils allouent aux LIR et ainsi de suite si nécessaire (il y a des cas plus complexes, pour les NIR, ou bien pour les adresses PI, ou encore lorsqu'un titulaire sous-alloue une partie de ses adresses). Lorsqu'un certificat affirmera « je suis titulaire du 192.0.2.0/24 », il sera ainsi possible de remonter la chaîne, jusqu'à une référence de confiance (l'IANA ou bien l'ensemble des RIR) pour vérifier cette assertion. Donc, bien que le routage dans l'Internet ne soit pas hiérarchique, l'allocation l'est, et la RPKI s'appuie là-dessus.

Les exemples ci-dessus portent sur des adresses IP mais le raisonnement est le même pour les numéros d'AS, d'où ce nom collectif de ressources (adresses IP et numéros d'AS).

Il faut bien noter que ces certificats, s'ils sont techniquement des certificats X.509 comme les autres, ont une sémantique différente; Le fait qu'une CA signe un certificat ne dit pas qu'elle certifie l'identité contenu dans le certificat mais qu'elle certifie le lien entre une ressource et un titulaire. Ces certificats sont d'avantage d'autorisation que d'authentification. Le RFC recommande simplement de mettre comme nom (X.509 appelle cela le subject) un identificateur spécifique à la CA, par exemple un numéro de client.

Comme cette sémantique est différente, et qu'il n'y a pas les risques juridiques associés aux certificats d'authentification classiques, il n'y a donc pas de nécessiter d'utiliser les CA existantes, ni de raison d'hésiter, pour un opérateur, à devenir CA. Les certificats fournis aux entités intermédiaires (typiquement les LIR) doivent être des certificats CA, autorisant le titulaire à émettre lui-même des certificats (la signature de chaque objet nécessite la création d'un certificat pour cet objet, cf. section 2.2). Les sites terminaux, en général, n'auront pas besoin de certificats du tout (sauf s'ils sont multi-homés avec des adresses PI, cf. section 7.3.2).

Les certificats finaux (section 2.3), ceux qui n'auront pas besoin d'avoir le bit CA à un, servent pour signer les objets (l'intérêt de créer un certificat juste pour signer un objet est de permettre une révocation, en réutilisant les mécanismes existants de X.509).

Pour vérifier, les validateurs (les routeurs BGP, ou bien les machines à qui ces routeurs sous-traiteront le travail), auront besoin de certificats « racine ». Comme en général pour X.509, le choix de ces certificats est une question politique locale et n'est pas spécifiée par la norme. Le RFC évite ainsi (section 2.4) l'épineuse question politique de savoir s'il faut configurer le validateur avec le certificat de l'IANA (donnant à celle-ci un grand pouvoir) ou bien avec les certificats des cinq RIR (court-circuitant ainsi l'IANA).

La section 3, elle, décrit les objets qu'on va signer, les ROA (Route Origination Authorization). La RPKI va dire « il est le titulaire de 192.0.2.0/24 » et le ROA va ajouter « l'AS 64641 est autorisé à annoncer 192.0.2.0/24 » (le ROA n'autorise que l'origine, pas les AS ultérieurs qui relaieront l'annonce). Le ROA est donc tout au bout du graphe des autorisations. On pourrait donc avoir une chaîne comme :

  • IANA : « ARIN gère 192.0.0.0/8 »,
  • ARIN : « le FAI Example est titulaire de 192.0.2.0/24 »,
  • Example : « l'AS 64641 est autorisé à être l'origine d'une annonce de 192.0.2.0/24 » (cette dernière assertion étant un ROA).

Le format des ROA est décrit en RFC 6482 et leur utilisation dans la validation des annonces BGP en RFC 6483. Le format est une spécialisation du format générique des objets de la RPKI, décrit dans le RFC 6488, lui-même issu de CMS. Chaque ROA contient un numéro d'AS, un ou plusieurs préfixes que cet AS a l'autorisation d'« originer » et (facultativement) une longueur maximale des sous-préfixes. Notez bien qu'il n'y a qu'un AS. Si plusieurs AS ont le droit d'être à l'origine des annonces de ces préfixes, il faut créer plusieurs ROA. Il n'y a pas de durée de validité dans le ROA, la validité est celle du certificat.

La distribution des ROA se fait essentiellement par le système de dépôts décrit dans la section 4 mais pourrait se faire dans le futur par d'autres moyens, comme les messages BGP UPDATE. On l'a vu, la validation des routes suppose que les validateurs (les routeurs BGP eux-même, ou bien des machines spécialisées à qui les routeurs sous-traitent l'opération) aient accès à tous les ROA. (Ce n'est pas un nombre énorme, typiquement un seul par route visible mondialement.) Un mécanisme est proposé pour créer un dépôt distribué de ROA, accessible à la demande (les mécanismes où les ROA seraient poussés vers les validateurs, par exemple par BGP, ne sont pas encore définis). Le dépôt est décrit en détail dans le RFC 6481.

Le dépôt n'est pas spécialement « de confiance ». Ce sont les signatures sur les ROA qui comptent, pas l'endroit où ils ont été récupérés. C'est d'autant plus vrai que le RFC encourage à recopier le dépôt, pour faciliter l'accès.

Le dépôt pourra offrir un choix de protocoles d'accès (section 4.3). Notre RFC décrit juste les fonctions de ces protocoles :

  • Téléchargement en bloc de toutes les données (rappelez-vous que le validateur est supposé avoir une vue complète). Les données sont donc réellement publiques.
  • Ajout d'une donnée, ou modification d'une donnée existante.

Des tas de protocoles offrent ces fonctions (par exemple HTTP/REST, même s'il n'est pas cité). Pour éviter que chaque acteur du routage ne déploie un protocole d'accès différent, rendant la vie des clients infernale, notre RFC impose que chaque copie soit accessible en lecture avec rsync, garantissant ainsi un mécanisme toujours disponible. On désigne donc la copie avec un URI rsync (RFC 5781) et on y accède par :

% rsync -av rsync://rpki.ripe.net/repository /where/i/want/RPKI-repository

Les experts en sécurité ont peut-être noté un peu de hand waving dans les paragraphes précédents. J'ai dit que la sécurité du dépôt était peu importante puisque ce sont les signatures des ROA qui font foi et que l'endroit où on les a trouvé ne compte donc pas. Mais si un méchant arrive à modifier un dépôt et supprime un ROA ? La signature ne protège pas contre ce genre de problèmes. La RPKI a donc un système de manifestes, des listes d'objets signés, listes elle-même signées et mises dans le dépôt (section 5 et RFC 6486).

Le dépôt sera donc massivement distribué, et les validateurs encouragés à garder des copies locales. La section 6 décrit ce processus, où le validateur obtient la copie de tous les objets (ROA, certificats, manifestes, etc), valide la signature des manifestes, puis vérifie leur contenu, et vérifie la signature des objets indiqués dans le manifeste.

Comme avec tous les caches, cette copie pose le problème de la fraîcheur des informations. Le cache ne contient-il pas des informations dépassées ? La section 6 n'est pas très bavarde sur ce point. À l'heure actuelle, ces informations de routage sont assez stables (on ne change pas d'AS d'origine tous les mois) donc le problème n'est pas trop aigü.

La section 7 décrit la vie du dépôt, et les opérations courantes. Les acteurs du routage devront donc désormais penser à la mise à jour de ce dépôt. Dans le futur, l'émission de ces certificats se fera peut-être automatiquement, en même temps que l'allocation des ressources. Aujourd'hui, ce n'est pas encore le cas.

La section 7.3 décrit en détail les aspects pratiques de cette gestion des ROA. Il va falloir acquérrir de nouveaux réflexes, notamment celui de créer et signer des ROA lors de tout changement de la politique de routage. Comme l'absence d'un ROA pour une annonce donnée pourra être interprété comme un détournement, et mener à un refus de l'annonce BGP par les routeurs validants, il y aura plein de possibilité de « se tirer une balle dans le pied ». Les opérateurs devront donc appliquer le principe « make before break », c'est-à-dire créer le ROA signé bien avant d'annoncer la route (pour permettre à tous les dépôts et tous les caches d'être à jour) et, en sens inverse, arrêter l'annonce longtemps avant de signer la révocation du ROA correspondant (et s'assurer qu'il existe un autre ROA, pour la nouvelle annonce).

Cela ne s'applique qu'aux opérateurs, pas au client final. Le site qui a des adresses PA et est connecté à un seul opérateur, n'a rien à faire, les ROA seront émis par l'opérateur. Ce site ne participe donc pas à la RPKI. En revanche, un site multi-homé peut, dans certains cas, avoir à émettre des ROA. Par exemple, s'il a un préfixe PA qu'il fait relayer par deux opérateurs, il doit créer un ROA pour cela (et donc obtenir un certificat depuis l'opérateur qui lui a affecté le préfixe PA) ou demander à l'opérateur de le faire pour lui. Si les adresses sont PI, le site doit émettre un ROA avec son propre AS en origine, en utilisant le certificat reçu avec le préfixe PI.

Si vous souhaitez appronfondir la question, une liste d'articles à lire se trouve dans mon article général. Si vous voulez pratiquer et voir la RPKI en action, regardez mon article sur les logiciels.


Téléchargez le RFC 6480


L'article seul

RFC 6474: vCard Format Extensions : place of birth, place and date of death

Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : K. Li, B. Leiba (Huawei Technologies)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF vcarddav
Première rédaction de cet article le 24 Décembre 2011


Le format de carte de visite numérique vCard, normalisé dans le RFC 6350, est un des grands succès de l'Internet. On trouve ces cartes partout. Le format de base définit un jeu de données limité mais permet des extensions. Ce RFC est donc la première extension à vCard version 4 (ex-aequo avec celle du RFC 6473), et normalise des champs pour indiquer un lieu de naissance, un lieu de mort et une date de mort (la date de naissance, BDAY, est dans le format de base).

La section 2 décrit ces trois propriétés, toutes facultatives :

  • BIRTHPLACE indique le lieu de naissance. Il peut être indiqué en texte libre ou bien sous forme d'une URI, comme par exemple les URI de plan geo: du RFC 5870. Ainsi, Jésus-Christ pourrait avoir BIRTHPLACE: Dans une grange, Bethléem (Palestine) ou bien BIRTHPLACE;VALUE=uri:geo:31.7031,35.196.
  • DEATHPLACE indique le lieu de mort, par exemple DEATHPLACE: Colline du Golgotha, Jérusalem (le RFC fournit un exemple où la longitude et latitude indiqués sont celles du point où a coulé le Titanic).
  • DEATHDATE indique la date de la mort. Il avait longtemps été envisagé de la garder dans le format de base, comme BDAY mais elle avait finalement été retirée, suite à la réunion IETF de Pékin en 2010. Comme son homologue BDAY, le format préféré de DEATHDATE est celui d'ISO 8601 (cf. RFC 6350, section 4.3), par exemple DEATHDATE:00300501 (date mise un peu au hasard, vu le manque de sources fiables...). Mais on peut aussi utiliser du texte libre pour le cas où on doit utiliser des formules vagues comme « au début du treizième siècle ».

Un exemple complet d'une vCard avec ces trois propriétés est :

BEGIN:VCARD
VERSION:4.0
FN:Jeanne d'Arc
N:d'Arc;Jeanne;;;
UID:urn:uuid:4f660936-28d5-46bf-86c6-9720411ac02a
GENDER:F
KIND:individual
TITLE:Bergère
TITLE:Pucelle
TITLE:Sauveuse de la France
PHOTO:http://commons.wikimedia.org/wiki/File:Lenepveu,_Jeanne_d%27Arc_au_si%C3%A8ge_d%27Orl%C3%A9ans.jpg
LANG:fr
URL:http://fr.wikipedia.org/wiki/Jeanne_d%27arc
BDAY:14120106
BIRTHPLACE:Domrémy (Lorraine)
DEATHDATE:14310530
DEATHPLACE:Rouen (Normandie)
END:VCARD

Ces trois nouvelles propriétés sont désormais enregistrées dans le registre IANA.


Téléchargez le RFC 6474


L'article seul

RFC 6471: Overview of Email DNS-Based List (DNSBL) Best Practice

Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : C. Lewis (Nortel Networks), M. Sergeant (Symantec Corporation), J. Levine (Taughannock Networks)
Pour information
Première rédaction de cet article le 19 Janvier 2012


En raison de l'importance du problème du spam (et d'autres comportements tout aussi nuisibles), un grand nombre de sites utilisent des listes noires des gens avec qui on ne veut pas communiquer (DNSBL pour DNS-based Black List). Ces listes sont souvent distribuées via le DNS, et gérées par des organismes très divers, dont le niveau de sérieux et d'honnêteté est très variable. La question étant très polémique, documenter le comportement attendu de ces organismes n'a pas été une mince affaire. Ce RFC 6471 décrit donc ce qu'on espère d'un gérant de DNSBL.

Rien ne dit qu'il sera suivi, bien sûr. Mais l'espoir est que ce document serve à faire évoluer les choses dans le bon sens. À noter que le groupe en charge de ce RFC, l'Anti-Spam Research Group de l'IRTF, n'a pas toujours réussi à se mettre d'accord sur le comportement idéal de la DNSBL. Dans ces cas, ce RFC 6471 se contente d'indiquer des recommandations sur la forme (« le gérant de DNSBL devrait documenter ce qu'il fait » si le RFC ne peut pas dire ce qui devrait être fait). La section 1.4 rappelle d'ailleurs que les règles de l'IRTF n'imposent pas de consensus au sein du groupe avant publication. À noter que ce RFC ne parle pas de protocole, les questions purement techniques étant traitées dans le RFC 5782.

Le sujet est tellement polémique que je ne vais pas forcément me contenter d'un compte-rendu neutre, objectif et ennuyeux de ce RFC et que je risque de glisser quelques opinions personnelles, pour lesquelles je demande l'indulgence de mes lecteurs. C'est que les DNSBL sont un marécage de gens bizarres, de racketteurs (« pour être retiré de notre liste, il faut payer »), d'éradicateurs (« nous avons mis les trois-quarts de l'Afrique en liste noire ») et de quelques personnes sérieuses. Le groupe ASRG représente plutôt le point de vue des éradicateurs (« dans le doute, on filtre »).

La section 1 du RFC rappelle ce qu'est une DNSBL et comment elle fonctionne. Les détails techniques du fonctionnement de ce service sont exposés dans le RFC 5782. L'idée est de publier dans le DNS les noms de domaine des méchants, ou bien les adresses IP de leurs serveurs de messagerie. Le serveur qui reçoit du courrier peut alors, en consultant le DNS (ce qui est simple et rapide), prendre connaissance de la « note » attribuée au domaine ou à l'adresse IP par le gérant de la DNSBL. Sur la base de cette note, il peut alors décider de filtrer, de contrôler plus étroitement, etc. Rappelons-bien que c'est le destinataire qui décide quoi faire du courrier, pas le gérant de la DNSBL, qui se contente de publier une information. Au bout du compte, c'est le gérant du serveur de messagerie de destination qui est responsable de l'usage qu'il fait de cette information. Beaucoup sont irresponsables, et filtrent aveuglément sur la base de listes noires sur lesquelles ils n'ont même pas pris la peine de se renseigner.

Comme le DNS est une technique éprouvée, très fiable et rapide, cet usage original des DNSBL s'est étendu. On voit aujourd'hui des DNSWL (listes blanches, désignant ceux qui ont droit à un traitement de faveur), listes d'URI dont la présence dans un courrier indique un spam, etc. On voit aussi des changements dans l'usage de ces listes. Très binaire autrefois (l'adresse IP est présente dans la liste noire => on rejette le message), il est devenu plus souple, les résultats d'une recherche dans la liste noire étant souvent un facteur de décision parmi d'autres (SpamAssassin fonctionne ainsi). Poursuivant cette idée d'utiliser le DNS pour récupérer de l'information, on voit aussi des services de géolocalisation utilisant le DNS et d'autres encore plus techniques (je me sers beaucoup du domaine aspath.routeviews.org de Route Views, qui permet de récupérer les informations de routage d'une adresse). Enfin, les listes distribuées par le DNS sont désormais utilisées pour bien d'autres choses que le courrier, par exemple pour du contrôle d'accès à des serveurs IRC ou des formulaires Web. Bref, on peut tout faire avec le DNS, qui a cessé il y bien longtemps d'être uniquement un service qui « traduit des noms de domaine en adresses IP ».

Quelles sont les DNSBL aujourd'hui ? Il y a de tout, certaines sont privées, gérées par une organisation pour son besoin propre, d'autres publiques et gratuites, d'autres payantes (beaucoup de DNSBL sont gratuites en dessous d'un certain seuil d'utilisation et payantes ensuite). On estime qu'il existe plus de 700 listes publiques, la plus ancienne ayant été créée en 1997. À cette époque, les spammeurs utilisaient leurs propres machines et c'est en grande partie en raison des DNSBL, qui distribuaient rapidement les adresses de ces machines, que les spammeurs sont passés à d'autres tactiques (comme les relais de courrier ouverts), tactiques à lesquelles les DNSBL ont dû s'adapter.

Il n'y a pas que le statut juridique et administratif qui différencient les DNSBL actuelles. Elles se différencient également par leurs politiques (comment une entrée est-elle ajoutée à la base et, plus important, comment elle est retirée) et, comme le note pudiquement le RFC, les DNSBL se différencient aussi par le niveau d'honnêteté de leurs responsables.

Justement, cette politique (qui va être mis dans la liste noire, sur quels critères ?) est un point de controverse permanent. Des cow-boys qui vous blacklistent un /20 entier parce qu'une adresse a envoyé un spam, aux gens sérieux qui prennent beaucoup de temps et d'effort avant d'ajouter une adresse à la base, il y a un large spectre d'opinions. Ce RFC 6471 n'essaie pas de trancher entre ces opinions. Il ne dit pas quelle est la bonne politique, simplement que le gérant de la DNSBL doit documenter ses critères d'inclusion et d'exclusion, et faire ensuite réellement ce qu'il annonce (ce qui est très loin d'être le cas). C'est ensuite à l'utilisateur de la DNSBL (l'administrateur d'un serveur de messagerie qui décide d'interroger cette base avant d'accepter un message) de s'informer et de s'assurer que la politique de la DNSBL lui convient.

La section 1.2 fournit une bonne check-list pour ledit utilisateur, sous forme d'une série de questions à se poser avant d'utiliser une DNSBL. Par exemple (entre parenthèses, une étude de l'application de cette check-list à Spamhaus, pour sa liste SBL) :

  • Est-ce que les politiques d'inclusion et d'exclusion suivies par la liste sont nettement marquées sur son site Web ? Sont-elles claires ? (Pour la SBL, la réponse est oui, pour l'inclusion et l'exclusion.)
  • Existe-t-il une évaluation indépendante de cette liste, permettant de comparer la théorie et la pratique ? (Je n'en sais rien, pour la SBL.)
  • Qu'en pensent vos pairs, les collègues qui travaillent dans des conditions analogues aux vôtres ? Comme le note justement le RFC, les DNSBL baignent souvent dans un climat de rude controverse. Il faut bien vérifier que les opinions sur une liste sont formulées par des gens qui s'y connaissent, et pas par Jean-Kevin Boulet qui crie bien fort « Ouais, cette liste est super, marche trop bien ». (La SBL est une des listes les plus utilisées et Spamhaus une organisation ancienne et appréciée.)

Il faut en outre réviser ces questions de temps en temps, les listes évoluent et plus d'une a cessé tout fonctionnement.

Le RFC enfonce le clou à plusieurs reprises : c'est l'utilisateur qui est responsable, au final, pas la DNSBL. Certes, c'est un plaidoyer pour les gérants de DNSBL (« ce n'est pas nous qui filtrons », remarque courante des DNSBL face aux contestations) mais cela reflète la réalité. Filtrer avec une DNSBL, c'est sous-traiter une partie de sa sécurité, c'est confier les décisions à d'autres (la section 4 revient sur ce point et rappelle que des DNSBL ont déjà listé 0/0 c'est-à-dire tout l'Internet). Il est donc crucial d'évaluer les sous-traitants. Le postmaster responsable comprend ce point : la DNSBL exprime une opinion, mais c'est lui qui décide d'agir sur la base de cette opinion.

Bref, quels sont les conseils effectifs de ce RFC 6471 ? Ils commencent en section 2. D'abord, la transparence de l'offre. La DNSBL doit écrire noir sur blanc quels sont les critères pour être mis dans la liste noire et quels sont ceux pour être enlevés. Par exemple, une liste qui s'appuie sur un pot de miel peut avoir comme critère d'ajout « On ajoute toute adresse IP qui a envoyé au moins trois messages dans une semaine aux adresses du pot de miel » et comme critère de retrait « On retire toute adresse qui n'a rien écrit au pot de miel depuis deux mois ». Cette politique doit ensuite être suivie rigoureusement et honnêtement. Dans la jungle des DNSBL, on a déjà vu des gérants de liste qui ajoutaient à la liste noire les adresses IP des gens qui les critiquaient (spite listing)... Il y a des tas de politiques raisonnables, l'important est de se tenir à celle publiée. Si on prétend gérer une liste de relais de courrier ouverts, on ne doit pas y mettre des adresses IP pour une autre raison, même en rapport avec le spam.

La transparence n'empêche pas des politiques dingues, mais ouvertement assumées par le gérant de la liste. Un bel exemple est chez UCEprotect, qui menace directement les critiques « Should you want to contact us, you should keep this in mind and behave rationally and calmly in order not to aggravate your situation. [...] Applying legal action or other pressure against us will result in your IP address and/or your network range being listed in our database. ».

À noter que cette règle de transparence n'impose pas de donner tous les détails. Par exemple, l'opérateur de la liste ne va évidemment pas publier les adresses du pot de miel, cela détruirait complètement son efficacité.

Ensuite, la traçabilité. La DNSBL devrait maintenir un historique des ajouts et retraits, avec les raisons, et publier cet historique. Là encore, l'historique publié peut être expurgé mais il doit contenir suffisamment d'informations pour qu'un utilisateur (ou l'administrateur d'une machine listée dans la liste noire) puisse comprendre pourquoi. Si on prend (un peu au hasard), la liste CBL, on trouve juste : « IP Address X.Y.Z.170 is listed in the CBL. It appears to be infected with a spam sending trojan or proxy. It was last detected at 2011-12-17 12:00 GMT (+/- 30 minutes), approximately 4 hours ago. », ce qui est un peu court.

Beaucoup de gérants de DNSBL sont du genre « éradicateur » et n'hésitent pas devant les dommages collatéraux. Le RFC dit d'ailleurs franchement qu'on ne fait pas d'omelette sans casser d'œufs. Ainsi, il arrive que des listes répondent pour des adresses qui n'ont pas eu de comportement malveillant mais font partie du même préfixe (mettre dans la liste tout un /28 lorsqu'une seule adresse IPv4 de ce /28 a mal agi, par exemple). Le RFC recommande que cette pratique d'élargissement soit clairement documentée.

L'entrée dans la liste est une chose. Mais, avec la plupart des DNSBL, les problèmes sont encore pires pour sortir de la liste. Même quand l'entrée est correctement faite, et à juste titre, on peut avoir des difficultés incroyables pour se faire rayer de la liste. Par exemple, une machine Windows devient un zombie, crache du spam à tout va, et se retrouve « noirlistée », ce qui est normal. Ensuite, l'administrateur système prend les choses en main, reformate le disque, installe NetBSD à la place, et va tenter de « délister » la machine, désormais propre. Avec la plupart des DNSBL, il aura un mal fou. Être enregistré dans une liste est facile, la quitter est très très dur. C'est le même problème lorsqu'une organisation disparait et que ses adresses IP sont récupérées par une autre, qui va s'apercevoir, mais trop tard, que le RIR lui a passé des adresses plombées par une mauvaise réputation.

Le RFC demande donc que les gérants de liste changent de perspective. Au lieu de considérer le retrait comme une opération en soi, toute la liste devrait être considérée comme temporaire et la sortie devrait être automatique au bout d'un moment.

Quelle durée avant cette expiration automatique ? Cela dépend de comment est constituée la liste. Si elle est faite manuellement, sur la base d'informations relativement statiques, comme les allocations de préfixes IP, alors les durées de vie peuvent être longues. Si la détection est automatique (par exemple une liste noire de relais HTTP ouverts), alors une durée de vie très courte est plus raisonnable. Ainsi, la machine dont la configuration a été corrigée disparaîtra vite de la liste et la machine qui rechute sera vite réadmise dans la liste. Dans tous les cas, le RFC demande que la politique d'expiration soit elle aussi publiée. Des informations comme « dernière vérification le tant » sont très précieuses pour évaluer la qualité d'une entrée de la base.

Autre bonne pratique, la fourniture d'un canal privé pour demander le retrait d'une entrée dans la base. Il est nécessaire qu'un tel canal soit disponible. Cela peut être aussi simple qu'une adresse de courrier ou qu'un formulaire Web. Mais, en tout cas, une DNSBL ne devrait pas exiger de discussion publique de la demande de retrait. (Oui, certaines le font, comme forme de punition des administrateurs systèmes qui ont fait preuve de négligence, et laissé leur machine être utilisée pour le spam.)

Et, bien sûr, la DNSBL doit fournir un canal de communication qui ne soit pas lui-même bloqué par la DNSBL... Si l'administrateur de 192.0.2.25 veut demander le retrait de cette adresse de la liste, et que le canal des demandes de retrait est une adresse de courrier, sur un serveur qui utilise la DNSBL, on se retrouverait dans une situation très kafkaïenne. Bien sûr, ces adresses de demande de retrait reçoivent beaucoup de spam mais le filtrage qui les protège devrait être très prudent, pour ne pas rejeter des demandes légitimes.

Les réponses à ces demandes de retrait devraient être raisonnablement rapides. Le RFC suggère deux jours (et sept au grand maximum).

Certaines DNSBL n'acceptent de demandes de retrait de la liste noire que lorsqu'il y a eu une forme d'authentification que le demandeur est bien en charge de l'adresse en question (vérification de l'adresse de courrier dans les bases des RIR, par exemple). Cette pratique est déconseillée car une telle authentification est souvent très difficile à fournir dans l'Internet d'aujourd'hui.

Le RFC recommande même de sérieusement envisager la possibilité de retirer automatiquement les adresses incriminées, sur simple requête (politique dite « pas de question » car on ne demande rien au demandeur). Si l'inscription dans la liste est le résultat d'un test automatique, l'adresse IP « coupable » sera très vite remise, de toute façon. Si on craint une guerre d'ajout/retrait dans la base, il suffit de mettre une limitation au rythme des requêtes (par exemple, deux retraits maximum en vingt-quatre heures) ou de détecter ces guerres et de verrouiller alors l'adresse dans la base. Une telle politique « pas de question » permet de corriger très vite les erreurs dans la base, et ne diminue pas sensiblement l'efficacité globale de la DNSBL (qui ne dépend pas de quelques adresses). Enfin, cette politique permet de désamorcer les (nombreux) conflits entre les gérants de la DNSBL et les responsables des adresses noirlistées.

On l'a vu, ce RFC ne veut pas trancher la question de savoir si une politique d'ajout dans la liste est correcte ou pas. Par contre, la liste des bonnes pratiques demande qu'il y ait symétrie entre la politique d'ajout et celle de retrait. Normalement, si une adresse est ajoutée pour une raison X, et que X cesse d'être vrai, l'adresse devrait être retirée. Par exemple, si une DNSBL stocke les adresses IP des relais de courrier ouverts, elle devrait retirer les adresses qui ne sont plus de tels relais (parce que l'administrateur a réparé la configuration). Cette recommandation du RFC va à l'encontre de la pratique de certaines DNSBL de punir les gérants des machines en question, en demandant une autocritique publique, voire carrément de l'argent, pour être délisté.

Enfin, dernière bonne pratique dans la section 2, cette question du paiement. Le RFC explique qu'il est normal qu'une DNSBL fasse payer ses clients pour y accéder (la définition d'une DNSBL commerciale, après tout). Mais faire payer les administrateurs système, responsables des adresses listées, est, comme le dit le RFC avec euphémisme « proche du racket ». Pour convaincre les administrateurs de listes noires que cette pratique devrait être abandonnée, le RFC note que, même lorsqu'elle est faite avec les meilleures intentions du monde, elle est susceptible de déclencher des réactions négatives, et de mettre en péril le principe même des DNSBL.

Les points traités dans la section 2 étaients de nature plutôt politique. La section 3 touche plutôt aux questions techniques. Quelles sont les bonnes pratiques opérationnelles ? Il y en a plusieurs, par exemple l'importance de disposer d'un ensemble de serveurs de noms suffisant pour faire face à la charge. Il s'agit non seulement de la charge normale, mais également de celle, bien plus élevée, qui surviendra lors d'une dDoS (les spammeurs n'ont pas le sens de l'humour et les attaques par déni de service contre les listes noires ne sont pas rares). Pour être sûr que le nom de domaine « principal » de l'opérateur (mettons spamhaus.org) soit à l'écart des problèmes, le RFC conseille que la DNSBL soit dans un sous-domaine délégué, avec ses propres serveurs de noms :


% dig NS sbl-xbl.spamhaus.org

; <<>> DiG 9.7.3 <<>> NS sbl-xbl.spamhaus.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16914
;; flags: qr rd ra; QUERY: 1, ANSWER: 21, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;sbl-xbl.spamhaus.org.		IN	NS

;; ANSWER SECTION:
sbl-xbl.spamhaus.org.	86400	IN	NS	b.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	5.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	0.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	k.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	d.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	o.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	x.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	h.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	l.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	2.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	4.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	i.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	3.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	r.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	f.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	g.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	t.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	8.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	q.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	1.ns.spamhaus.org.
sbl-xbl.spamhaus.org.	86400	IN	NS	c.ns.spamhaus.org.

;; Query time: 341 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Dec 17 17:40:40 2011
;; MSG SIZE  rcvd: 388

Un des problèmes récurrents avec les DNSBL est que la plupart des administrateurs système ne testent jamais si leur configuration est toujours bonne, et lorsqu'une DNSBL cesse son activité, elle continue à être interrogée. Pour éviter cela, certaines DNSBL en fin de vie ont choisi la solution radicale de lister la totalité de l'Internet. À chaque adresse, elles répondaient qu'elle était listée. Pour détecter rapidement ce genre de problèmes, le RFC rappelle qu'on peut tester 127.0.0.1. Cette adresse ne devrait jamais apparaître dans une DNSBL. Si elle le fait, c'est que la liste a un gros problème et ne devrait plus être utilisée. Si la liste comprend des noms de domaines et pas des adresses IP, c'est le domaine invalid qui joue ce rôle. (Le RFC 5782 donne des détails sur ces conventions. D'autres domaines réservés par le RFC 2606 peuvent être utiles comme test.)

Néanmoins, la première responsabilité est celle du gérant de la liste : s'il arrête le service, il doit le faire proprement (prévenir sur son site Web au moins un mois à l'avance, etc) et surtout pas en se mettant soudain à lister tout l'Internet dans sa base. Il est important de garder le nom de domaine actif : si celui-ci était libéré, un méchant pourrait l'enregistrer et monter une fausse liste noire, qui serait utilisée par tous les clients distraits qui ont oublié de changer leur configuration.

Du point de vue technique, la méthode recommandée est de changer les serveurs de noms de la zone où se trouve la liste pour des adresses IP qui ne peuvent pas exister, par exemple celles réservées pour la documentation (RFC 5735). Ainsi, on est sûr que le domaine ne marchera pas et qu'aucun enregistrement ne sera retourné, montrant bien aux clients que la liste n'est plus en service. Par exemple, avec la syntaxe standard des fichiers de zone DNS :

dnsbl.example.com.  604800  IN  NS  u1.example.com.
                    604800  IN  NS  u2.example.com.
   
u1.example.com.     604800  IN  A   192.0.2.1
u2.example.com.     604800  IN  A   192.0.2.2

Le RFC a aussi des recommandations opérationnelles à faire pour le cas spécifiques des DNSBL qui listent les adresses IP de machines présentant une certaine vulnérabilité (relais SMTP ou HTTP ouverts, par exemple), détectée par un programme. D'abord, le programme ne devrait pas tester des machines préventivement (la question est controversée : certains défendent la légitimité de balayages systématiques de tout l'Internet, d'autres ne sont pas d'accord). Il ne devrait le faire que si quelque chose (un rapport d'envoi de spam, par exemple) attire l'attention sur des machines spécifiques.

Ensuite, une fois une adresse listée, les tests périodiques qui visent à évaluer si la machine est toujours vulnérable devraient être relativement espacés (pas plus d'une fois par jour). Et, bien sûr, le test ne doit pas avoir d'effet négatif (pas d'envoi de grandes quantités de données, par exemple).

Les logiciels qui sont derrière la DNSBL, comme tous les logiciels, ont des bogues. Et les utilisateurs d'une DNSBL peuvent faire des erreurs de configuration. Il est donc important que tout soit vérifié et testé et que des procédures soient en place pour faire face aux problèmes (par exemple, le gérant de la DNSBL doit être prêt à vider manuellement la base ou une partie de celle-ci, si une erreur entraîne le listage erronée d'adresses IP).

À noter que le Wikipédia anglophone a un intéressant tableau de comparaison des DNSBL.

Pour résumer, on a vu que ce RFC résultait d'un compromis entre ceux qui voulaient des listes noires opérant comme elles le voulaient et ceux qui souhaitaient les rendre un peu plus responsables. Le compromis a été de donner peu de recommandations concrètes excepté de documenter les choix effectués. À l'heure actuelle, le moins qu'on puisse dire est que la plupart des listes noires ne font même pas ce minimum...


Téléchargez le RFC 6471


L'article seul

RFC 6468: Sieve Notification Mechanism: SIP MESSAGE

Date de publication du RFC : Février 2012
Auteur(s) du RFC : A. Melnikov (Isode), B. Leiba (Huawei), K. Li (Huawei)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sieve
Première rédaction de cet article le 3 Mars 2012


Je vais peut-être décevoir certains lecteurs mais, dans cet article, je ne parlerai pas du contenu du RFC mais uniquement du scandale de brevets qui l'a accompagné. En violation des règles de l'IETF, Huawei avait dissimulé l'existence d'un brevet que cette compagnie détenait sur le sujet de ce RFC.

Techniquement, ce RFC est simple : c'est une extension au langage de filtrage de courrier Sieve (RFC 5228) pour notifier des destinataires de l'arrivée d'un message, en utilisant le protocole SIP (RFC 3261). Comme les organismes de dépôt des brevets acceptent tout et n'importe quoi, on peut breveter une idée aussi simple... (Le brevet ne semble pas avoir encore été publié mais nul doute qu'il ne le sera : je n'ai pas trouvé de serveur permettant de lire les brevets chinois comme ce CN 200710076523.4 mais une version états-unienne existe aussi, le US Patent 20090204681.)

Le problème n'est pas que la technologie soit brevetée. Les règles de l'IETF ne l'interdisent pas. Le problème est que Huawei a dissimulé ce brevet, pour être sûr que le RFC soit adopté malgré cette menace (c'est ce qu'on nomme un brevet sous-marin). Et cette dissimulation, elle, est interdite par l'IETF (RFC 3979). Mais les entreprises capitalistes n'ont manifestement pas peur des règles de l'IETF, celle-ci n'ayant pas de dents pour mordre les contrevenants...

Laissons Adam Roach résumer ce qui s'est passé (message envoyé à la liste de diffusion générale de l'IETF) : Just to make sure I understand the sequence of events:

  • 1. August 21, 2007: Huawei files a patent (CN 200710076523.4) on using SIP for SIEVE notifications. The inventor is listed as a single Huawei employee.
  • 2. August 30, 2007: That same Huawei employee and two additional authors publish an IETF draft ( draft-melnikov-sieve-notify-sip-message-00) on using SIP for SIEVE notifications.
  • 3. September 2007 - September 2011: The SIEVE working group discusses and improves the IETF draft.
  • 4. October 6, 2011: The IESG approves the IETF draft for publication as an RFC.
  • 5. December 14th, 2011: Huawei files an IPR disclosure with the IETF informing it of patent CN 200710076523.4

La publication du 14 décembre 2011 à laquelle il fait allusion est la #1658. Une version plus récente est la #1681.

Le 25 janvier 2012, l'IESG a relancé l'IETF (Second Last Call, un terme bien orwellien) pour demander un avis sur la publication du RFC, malgré la divulgation du brevet sous-marin. Suite à cela, le RFC a été publié. L'IETF n'avait aucun moyen de représailles, à part refuser le RFC (qui ne posait aucun problème technique).

Aucune sanction n'a été prise, l'IETF n'a pas de mécanisme pour cela. Une discussion est en cours autour d'un Internet-Draft, draft-farrresnickel-ipr-sanctions, dont le titre est Sanctions Available for Application to Violators of IETF IPR Policy. La section 4 de ce document examine les sanctions possibles à l'heure actuelle (de l'annonce publique de la tricherie, méthode du name and shame, jusqu'au retrait des Internet-Drafts des mains des tricheurs, en passant par la suspension de leur droit d'écriture dans les listes IETF, selon les principes du RFC 2418 et surtout du RFC 3683).

À noter que Huawei n'est pas la première société à agir ainsi, RIM en avait fait autant.


Téléchargez le RFC 6468


L'article seul

RFC 6462: Report from the Internet Privacy Workshop

Date de publication du RFC : Janvier 2012
Auteur(s) du RFC : A. Cooper (Center for Democracy and Technology)
Pour information
Première rédaction de cet article le 17 Janvier 2012


Après une très longue période d'ignorance quasi-complète des problèmes de protection de la vie privée, l'IETF a évolué et on n'entend plus gère ses participants écarter d'un revers de main ces questions, en disant « Nous, on fait juste de la technique, tout ça, c'est de la politique, ça ne nous concerne pas. » De nos jours, au contraire, la prise de conscience est nette et l'IETF a désormais une activité structurée autour de la notion de vie privée, activité qui se traduit par un programme dédié et une liste de diffusion. Faut-il aller plus loin ? C'était une des questions posées lors de l'Atelier « Internet Privacy Workshop 2010 », atelier qui s'est tenu du 8 au 9 décembre 2010 à Cambridge et dont ce RFC est le compte-rendu. (L'auteure travaille pour une ONG qui lutte pour les libertés sur l'Internet.)

Pas de décisions à attendre tout de suite, donc. On en est à un stade d'exploration. L'atelier de Cambridge était coorganisé par l'IETF, le MIT et le W3C pour voir ce que les SDO pouvaient faire en terme de protection de la vie privée. On est loin d'un accord unanime (et le résumé du RFC dit bien qu'aucun des organismes présents n'a de position officielle sur ces questions) mais au moins quelques pistes de travail émergent. L'IETF étant chargé de produire des spécifications concrètes, une bonne partie de l'atelier a porté, non pas sur des discours généraux sur la vie privée, mais sur les tâches envisageables.

La question de la protection de la vie privée sur l'Internet est immense et couvre beaucoup de domaines très différents. Certains problèmes apparaissent de manière récurrente, le fingerprinting (la détermination d'une identité à partir de traces numériques qui n'étaient a priori pas conçues pour cela), la fuite d'informations, la difficulté à distinguer les partenaires primaires (à qui on a donné directement de l'information) des tiers (qui ont eu de l'information sans qu'on interagisse explicitement avec eux), le manque d'informations des utilisateurs sur les avantages et inconvénients d'une meilleure protection, etc. (Notons que le RFC mentionne les faiblesses des utilisateurs, mais pas l'aggressivité avec laquelle les capitalistes collectent et revendent de l'information privée.) Le RFC note que la vie privée n'est pas un absolu et que, par exemple, la protéger peut influer négativement sur l'utilisabilité d'un service. Bref, il y a pour l'instant davantage de défis que de solutions (section 1).

Plus précisement, de quoi a-t-on parlé pendant l'atelier (les supports présentés sont disponibles en ligne) ? La section 2 résume tout cela. D'abord, une discussion technique (section 2.1). Commençons par l'adresse IP. Elle donne souvent bien trop d'informations (il est trivial de remonter d'une adresse IP à un utilisateur, ce qui explique pourquoi elle est considérée comme une donnée personnelle). Certains protocoles offrent des risques particuliers comme certaines techniques de mobilité, qui permettent de suivre un utilisateur à la trace.

C'est d'ailleurs dans le cas de l'adresse IP qu'on trouve un des rares exemples d'une technologie IETF spécialement développée pour répondre à des craintes concernant la vie privée : les adresses IP temporaires du RFC 4941, qui sont partiellement aléatoires, et regénérées de temps en temps, pour éviter le suivi de l'utilisateur.

Autre mécanisme bien connu pour empêcher le suivi par l'adresse IP : le routage en oignon, surtout connu grâce à Tor. Ce service route les paquets à travers plusieurs nœuds distincts, chiffrant leur contenu à chaque fois. Seuls les premiers et derniers nœuds voient le message en clair. Observer le trafic ne permet de trouver, au pire, que l'origine (si on espionne au début), ou bien que la destination (si on espionne à la fin).

Mais Tor n'est pas parfait : le contenu des messages peut donner des indications sur l'origine (cookies, par exemple, pour une requête HTTP). Si on veut vraiment être anonyme, utiliser Tor ne suffit pas : il faut aussi couper bien des choses sur son navigateur, à commencer par Flash et JavaScript, et certains peuvent considérer cela comme un problème. Comme souvent en sécurité, rien n'est gratuit. Protéger sa vie privée peut nécessiter des sacrifices.

Les participants à l'atelier ont également planché sur le mode private browsing qu'offrent certains navigateurs. C'est un mode dans lequel le navigateur ne stocke pas localement les identifiants de session (comme les cookies). Son but n'est pas de protéger contre un suivi de l'utilisateur par le serveur mais de protéger contre d'autres utilisateurs du même poste client. L'expérience indique que beaucoup d'utilisateurs ne comprennent pas la différence et croient que le private browsing leur procure une navigation sans flicage. C'est un exemple d'un autre problème courant en sécurité : les utilisateurs ne comprennent pas les risques.

Enfin, dernière discussion technique, sur les propositions Do Not Track, qui permettent à un utilisateur d'indiquer clairement aux sites Web qu'il ne veut pas être suivi à la trace. Pour l'instant, ce ne sont que des propositions, sans accord technique ou politique.

Après ces discussions techniques, l'atelier s'est demandé quel pouvait être le rôle des SDO dans cette histoire. Dans le passé, il n'y a pas eu d'appproche systématique de la vie privée dans les protocoles IETF. Cela ne veut pas dire que rien n'a été fait : certains RFC ont été entièrement conçus pour résoudre un problème de vie privée (comme le RFC 4941 pour IPv6 ou le RFC 3323 pour SIP). Certains services particulièrement sensibles ont bénéficié de davantage d'efforts, par exemple l'indication de présence (RFC 2778) ou bien sûr la géolocalisation (RFC 3693). Un protocole comme ALTO (RFC 5693) a également vu ses problèmes de vie privée étudiés dès le début. Le cas d'ALTO est difficile car le protocole est d'autant plus efficace que l'utilisateur révèle beaucoup de choses sur lui (en demandant à l'oracle « Je veux télécharger le fichier Serge Reggiani - Les Loups Sont Entrés Dans Paris.mp3 de taille 4732679 octets et de MD5 2d79e0d7e25c8c10c9879cefcef4102a et voici la liste complète des pairs BitTorrent qui l'ont » par rapport au plus discret mais moins efficace « je voudrais savoir si le pair 2001:db8:1::1 est plus ou moins rapide que le 2001:db8:67e::34a:1ff3 »).

La protection de la vie privée a pas mal de rapports avec la sécurité (la section 8 discute du rapprochement de ces deux concepts) et la sécurité est un bon exemple d'une préoccupation transverse (elle affecte tous les protocoles) qui était largement ignorée au début de l'IETF et a vu son rôle de plus en plus pris en compte. L'IETF a ainsi bâti une culture de la sécurité. Ainsi, depuis le RFC 1543, tous les RFC doivent inclure une section Security Considerations pour exposer l'analyse sécurité du protocole. Elle peut être vide mais elle doit être présente avec une mention expliquant pourquoi les auteurs du RFC ont consciemment laissé la section vide. Cette obligation bureaucratique n'est évidemment pas suffisante et l'IETF a ajouté une direction de la sécurité, un RFC dédié pour guider les auteurs de RFC (RFC 3552), de nombreux tutoriels pour auteurs de RFC aux réunions physiques, etc. La même méthode peut-elle être appliquée à la vie privée ? (Le RFC 2828, qui rassemble la terminologie IETF sur la sécurité, contient des termes liés à la protection de la vie privée.)

Le W3C a également procédé à un effort semblable. Un de ses premiers grands efforts a été P3P, un mécanisme pour permettre aux sites Web d'exprimer de manière formelle leur politique de gestion des données personnelles. P3P est un langage riche, qui permet d'indiquer des politiques complexes. Mais il a été très peu adopté en pratique. Opinion personnelle : comme pour la neutralité du réseau, tout le monde prétend que l'information du consommateur résoud tous les problèmes, qu'il suffit d'annoncer sa politique et que le marché choisira. Mais personne ne veut le faire réellement. P3P permettait d'exprimer les politiques de protection des données personnelles en des termes simples et non ambigus et c'était évidemment intolérable pour les e-commerçants, qui préfèrent infliger à l'utilisateur des privacy policies de vingt pages écrites en langage légal.

Après ce tour d'horizon du travail effectué et des acteurs en place, l'atelier s'est attaqué aux défis (section 3). Quels sont les grands problèmes à résoudre ?

D'abord, la trop grande facilité à identifier un utilisateur donné par les informations que donne le logiciel qu'il utilise : adresse IP, champs de la requête HTTP comme User-Agent: ou Accept-Language:, cookies (RFC 6265), et plein d'autres paramètres font qu'on peut identifier un utilisateur ou une machine bien trop souvent. C'est ce qu'on nomme le fingerprinting et c'est bien démontré par le Panopticlick.

Comme dans toute réunion de geeks, les participants à l'atelier ont évidemment pris plaisir à explorer en détail des techniques de fingerprinting particulièrement rigolotes comme d'envoyer du code JavaScript qui va transmettre au serveur la liste des polices installées dans le navigateur (elle est souvent unique).

Capturés par un simple script WSGI sur le serveur (testez-le en http://www.bortzmeyer.org/apps/env ; les variables d'environnement dont le nom commence par HTTP_ sont les en-têtes de la requête HTTP), voici une partie de ce qu'envoie un Firefox typique, depuis une machine Ubuntu :

HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7
HTTP_USER_AGENT: Mozilla/5.0 (Ubuntu; X11; Linux i686; rv:8.0) Gecko/20100101 Firefox/8.0
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_LANGUAGE: en-us,en;q=0.5
HTTP_ACCEPT_ENCODING: gzip, deflate

Cette combinaison d'options et de numéros de version est probablement unique, ou en tout cas rare sur le Web, et identifie donc assez bien une machine (sans même avoir besoin de cookie). Une telle combinaison a par exemple déjà été utilisée pour confondre un agresseur agissant pour le compte de l'industrie du divertissement.

Ces informations n'étaient pas prévues pour cet usage (par exemple, les adresses IP étaient prévues pour router les paquets, pas pour identifier une machine ou une personne). Mais remplacer ces informations par des mécanismes qui empêchent ou limitent le fingerprinting ne sera pas trivial. D'autant plus que pas mal de gens se sont habitués à les utiliser dans ce but et qu'il sera de plus en plus difficile de revenir en arrière. Ainsi, le fingerprinting est souvent utilisé pour détecter des fraudes, ou pour fournir du contenu adapté (et le RFC, qui est gentil et évite les sujets qui fâchent, ne cite pas les applications répressives du fingerprinting, pour identifier l'auteur d'un délit abominable, comme de partager des œuvres d'art). Il y aura probablement beaucoup de désaccords sur le compromis entre vie privée et service « amélioré » grâce au fingerprinting.

Au minimum, l'IETF et le W3C vont essayer de documenter les points qui, dans les protocoles courants (TCP, HTTP, SIP), facilitent le fingerprinting.

Un problème proche est celui de la fuite d'informations (section 3.2) : des mécanismes conçus pour des motifs tout à fait honorables transmettent néanmoins plus d'information qu'ils ne le devraient. Ainsi, le champ Referer: dans une requête HTTP permet de savoir d'où vient un visiteur Web (ce qui est utile) mais révèle également des choses comme les ID de session (lorsqu'ils sont mis dans l'URL), les termes de recherche utilisés, etc. Voici un exemple vu dans le journal de mon blog (les informations trop sensibles ont été modifiées). On voit les termes de recherche utilisés dans Google :

192.0.2.70 - - [16/Dec/2011:17:08:53 +0000] "GET /1383.html HTTP/1.0" 200 3291 "http://www.google.fr/url?sa=t&rct=j&q=aide+rfc+dns...

Le contrôle sur les données privées repose normalement sur la possibilité de distinguer les récepteurs primaires des données des tiers (section 3.3). Ainsi, si je me connecte sur SeenThis, ce site est récepteur primaire de mes données et je ne suis pas surpris qu'il récolte des informations sur moi. Il s'agissait d'un choix conscient et informé de ma part. Mais l'examen du code source de ce site montre qu'il fait appel au service Google Analytics et donc, sans l'avoir demandé, sans même le savoir, je transmets également des données à Google, un tiers qui peut alors récolter des données sans que je l'ai choisi.

Le cas ci-dessus est relativement simple. Mais dans le Web d'aujourd'hui, on trouve d'autres cas où la distinction entre destinataire primaire et tiers est moins évidente. Un utilisateur qui met un widget amusant sur une page peut le considérer comme primaire alors que le navigateur (par exemple pour retourner les cookies) le traitera comme un tiers, et l'inverse existe également.

Enfin, le dernier grand défi est celui de l'information de l'utilisateur (section 3.4). La plupart du temps, le flicage de ce dernier se fait discrètement, sans qu'il se rende compte de l'immense quantité de données qui est collectée à son insu. La seule information disponible est composée de « policy statements » écrits dans un jargon juridique délibérement confus, conçu pour protéger le patron de l'entreprise et pas pour informer l'utilisateur. Le RFC note que des informations cruciales (comme la durée de conservation des données) en sont souvent absentes. Opinion personnelle : c'est pour cela que les mécanismes du marché - l'entreprise publie sa politique et le consommateur est libre de continuer ou pas - ne fonctionnent pas et qu'il faut des lois comme la loi I&L. Le marche suppose une information parfaite et des acteurs symétriques, ce qui n'est pas du tout le cas ici.

Le problème est d'autant plus sérieux que, si le technicien se doute bien de tout ce que le site Web peut apprendre sur son visiteur, l'utilisateur ordinaire n'a souvent pas pas idée de la quantité de traces numériques qu'il laisse.

Il est donc nécessaire de travailler à une meilleure information. P3P était un bon effort dans ce sens. Mais comme c'était un langage riche, il était difficile de traduire une politique P3P de manière claire pour l'utilisateur. Les efforts actuels portent plutôt sur un nombre limité d'icônes qui pourraient devenir largement connues (un panneau « danger, ici votre vie privée est menacée »...) Un exemple est le projet Common Terms.

La section 4 étudie ensuite les défis liés au déploiement des bonnes pratiques. D'abord (section 4.1), le problème que les mesures techniques sont génériques, alors que les menaces effectives sont souvent spécifiques à un contexte donné. La vie privée n'est pas un concept binaire. Il y a d'autres stades que « complètement privé » et « public ». Mais il est très difficile de traiter cette complexité par des mesures techniques.

Par exemple, les solutions situées en couche 3 comme les adresses IP temporaires du RFC 4941 résolvent certes certains problèmes (le serveur qui reconnaît un visiteur récurrent uniquement sur son adresse) mais ne protège pas du tout contre un FAI ou un État qui essaie d'associer une adresse à un utilisateur. Selon la menace envisagée, ces adresses temporaires sont donc efficaces... ou pas du tout.

Il ne faut donc pas évaluer les solutions techniques en leur demandant de résoudre tous les problèmes possibles. Il ne serait pas raisonnable pour l'IETF d'exiger de ses protocoles qu'ils empêchent complètement toute atteinte à la vie privée. Il faut plutôt dire clairement quels sont les risques et qui (le programmeur, l'utilisateur, la loi) est chargé de les traiter.

Autre problème délicat de déploiement de solutions de protection de la vie privée : la tension entre l'utilisabilité et la protection (section 4.2). Comme souvent en matière de sécurité, il va falloir faire des choix douloureux. Les tenants du Roi Marché ont beau jeu de faire remarquer que les utilisateurs, lorsqu'ils ont le choix, vont vers les services qui violent le plus leur vie privée (Facebook, Google, etc) en échange d'applications sympas et qui brillent. La principale faiblesse de cet argument est qu'il suppose que l'utilisateur est parfaitement conscient des risques, et de ce qui peut lui arriver, ce qui est très optimiste.

Un bon exemple de ce compromis est donné par Tor. Celui-ci fournit une bonne protection mais complique et ralentit (en raison du nombre d'étapes de routage) la navigation. Résultat, il reste peu utilisé, en bonne partie parce que les utilisateurs font un calcul coût/bénéfice (peu informé, d'ailleurs) et décident que leur vie privée n'est pas assez importante pour justifier ce coût.

Avec Tor, le coût de la protection est élevé. Mais même des mesures bien plus légères ont des coûts. Supprimer l'en-tête Referer: des requêtes HTTP améliore certainement la protection. Mais certains sites Web proposent une vue différente selon la valeur de ce champ et, en le supprimant, on se prive de ce service. Reste à savoir qui va décider du compromis, et sur quelles informations : comment exposer ce choix (« Do not send Referer headers ») dans une interface utilisateur, de manière qui permette un choix raisonné ? Alors même que l'effet de ce choix va dépendre des sites (dans la plupart des cas, le Referer: est inutile au client Web.)

Ces problèmes d'utilisabilité sont cruciaux. Le RFC cite l'exemple de SIP, où un mécanisme normalisé de protection des requêtes contre l'écoute existe (RFC 3261, section 23) mais il n'est pas utilisé en pratique car trop contraignant.

Dernier obstacle au déploiement de techniques respectant davantage la vie privée, la difficulté à trouver les bonnes motivations (section 4.3). Les différents acteurs impliqués ne feront pas d'effort s'ils n'ont pas une motivation pour cela. Cela peut être la crainte du gendarme, la conviction que cela leur apportera plus de clients ou simplement le souci d'utiliser les meilleures techniques (ces trois motivations sont rarement présentes en même temps). La crainte du gendarme est discutée en section 4.3.1. Traditionnellement, beaucoup de services proposés sur l'Internet sont gratuits et la possibilité de vendre les données personnelles des utilisateurs est l'une des voies les plus évidentes pour gagner de l'argent. Comme l'illustre un dessin célèbre, « soit l'utilisateur est le client, soit il est la marchandise ». Dans un tel contexte, il n'y a pas de motivation économique à respecter la vie privée, bien au contraire. Les diverses autorités de régulation ont fini par froncer les sourcils, ce qui a mené les fournisseurs de ces services à publier de longues politiques d'utilisation des données sur leur site. Comme le note le RFC, ces politiques, écrites sans effort pédagogique, visent plutôt à protéger le fournisseur du service qu'à informer correctement et complètement l'utilisateur. Le RFC note à juste titre que ces problèmes ne se corrigeront pas tout seuls et qu'une approche régulatrice est nécessaire (cf. le rapport de la FTC de 2010 sur l'importance d'avoir des politiques publiques mieux écrites).

Le RFC soutient que cette tendance doit continuer : sans forte pression des régulateurs, de la loi, le patronat Internet va toujours essayer de concéder le moins de vie privée possible aux utilisateurs. Un exemple d'une telle pression est la directive européenne qui parle des cookies, indiquant qu'ils ne doivent pas être utilisés sans le consentement des utilisateurs.

Le cas de P3P, déjà cité, est un bon exemple de ce problème des motivations (section 4.3.2). L'idée de base était que les logiciels du côté du client allaient pouvoir lire et comprendre les politiques de protection de la vie privée et automatiquement réagir (par exemple en n'envoyant pas de cookies aux sites dont la politique était trop peu protectrice de la vie privée). C'est une idée très états-unienne : les acteurs libres s'informent mutuellement de leurs pratiques et décident ensuite librement, en adultes majeurs, informés et consentants, de poursuivre ou pas la relation. Si on croit qu'il y a égalité (d'information, de moyens de traitement, de pouvoir) entre le patron de Facebook et M. Michu, utilisateur de Facebook, cela peut marcher. Sinon, on préfère l'approche européenne où certaines pratiques sont interdites, qu'il y ait ou pas consentement de la marchandise, pardon, de l'utilisateur.

Donc, P3P permettait d'automatiser ce processus d'information et de décision. Microsoft a pris une décision importante en choisissant, dans Internet Explorer 6, de n'envoyer des cookies aux tiers que si ceux-ci avaient une politique P3P. Comme n'importe quelle politique, même outrageusement prédatrice, était acceptée par Internet Explorer, la plupart des sites Web se sont pliés à cette décision et ont copié/collé la première politique P3P qu'ils trouvaient (souvent l'exemple pris sur le site du W3C). Cette expérience menée grâce à Internet Explorer (les autres auteurs de navigateurs n'ont fait aucun effort et n'ont jamais intégré P3P) a permis de mettre en évidence une limite de P3P : le site qui publie sa politique peut mentir (« Nous ne vendons pas vos données personnelles »). Aucun mécanisme légal ou autre ne l'en empêche. (Voir par exemple l'article « Token Attempt: The Misrepresentation of Website Privacy Policies through the Misuse of P3P Compact Policy Tokens ».)

Le cas illustre bien la question des motivations : pour qu'ils reçoivent des cookies d'Internet Explorer, les sites devaient publier du P3P. Alors, ils l'ont fait (motivation technique). Il n'y avait pas de pression légale ou régulatrice pour dire la vérité dans ces politiques P3P, alors ils ne l'ont pas fait (pas de motivation légale). Les clients (en partie à cause de l'absence de gestion de P3P par les navigateurs) ne donnaient pas la préférence aux sites publiant du bon P3P, alors les sites n'ont pas cherché à l'améliorer (pas de motivation commerciale).

Il sera intéressant de voir si cela marche mieux en sens inverse : pour la géolocalisation, le RFC 4119 et le RFC 6280 fonctionnent de manière opposée à P3P, en permettant aux utilisateurs d'indiquer leurs choix en matière de protection des données personnelles. Ils sont normalement plus motivés que les entreprises capitalistes pour cela.

Bien sûr, on est ici très loin des questions techniques que se posent normalement les SDO. Mais la compréhension de ces enjeux économiques et légaux est nécessaire, si on veut que les futures techniques de protection de la vie privée aient plus de succès que P3P.

Conclusion, en section 5, quel est le plan d'action pour les SDO ? Pour l'IETF, la synthèse est que cela va être compliqué. L'IETF normalise des protocoles dans les couches basses, sans présupposer d'un usage particulier, alors que les menaces pour la vie privée sont très dépendantes du contexte. Il va donc être difficile de trouver des réponses générales, dans les protocoles IETF. Cela ne veut pas dire qu'il ne faut rien faire. Le travail a déjà commencé autour d'une série de recommandations pour les auteurs de RFC (rassemblées dans ce qui est aujourd'hui un Internet-Draft, draft-morris-privacy-considerations).

Les participants à l'atelier étaient tous d'accord sur la nécessité de poursuivre également le travail technique, par exemple sur les leçons apprises de Tor, ainsi que sur les capacités (plus fortes que prévues) de fingerprinting des protocoles existants.

Et le W3C ? Il est probablement mieux placé pour améliorer la protection de la vie privée, puisque les normes du W3C sont plus proches de l'utilisateur, et utilisées dans un contexte plus spécifique. Contrairement à l'IETF, le W3C peut se restreindre au Web.

L'annexe A résume quels sont les documents bruts disponibles pour ceux qui veulent approfondir leur connaissance des travaux de cet atelier :


Téléchargez le RFC 6462


L'article seul

RFC 6458: Sockets API Extensions for Stream Control Transmission Protocol (SCTP)

Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : R. Stewart (Adara Networks), M. Tuexen (Muenster University of Applied Sciences), K. Poon (Oracle Corporation), P. Lei (Cisco Systems), V. Yasevich (HP)
Pour information
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 12 Décembre 2011


Il n'y a pas de protocole qui réussit sans une API, c'est-à-dire une spécification d'une interface qui permet au programmeur d'utiliser le protocole en question. Le protocole de transport SCTP, normalisé dans le RFC 4960, n'avait pas jusqu'à présent d'API standard et les programmes ne fonctionnaient donc qu'avec une seule bibliothèque. Désormais, avec ce RFC, SCTP a des chances de voir le développement de programmes portables.

SCTP est le principal concurrent de TCP dans la catégorie « protocole de couche 4 fiable » (i.e. qui garantit l'acheminement des données, contrairement à UDP). Mais il est beaucoup moins utilisé que TCP, plus ancien, et qui a une API standard depuis longtemps, interface décrite dans la norme POSIX. Il y a aussi d'autres raisons au moindre déploiement de SCTP. Mais l'absence d'API jouait certainement un rôle : pas moyen de programmer avec SCTP sans devoir se limiter, non seulement à un système donné, mais en prime à une mise en œuvre particulière de SCTP. Les instructions d'installation devenaient donc pénibles à lire. C'est ce problème que résoud notre RFC.

L'API décrite dans ce RFC est longue (le RFC fait 113 pages) donc je résume plutôt sauvagement. Elle permet d'écrire des programmes qui font la même chose qu'avec TCP, comme des programmes qui tirent profit des fonctions spécifiques de SCTP. Car la sémantique de SCTP n'est pas exactement la même que celle de TCP, le remplacement de l'un par l'autre n'est pas entièrement invisible aux applications. Les points importants de cette nouvelle API :

  • Elle est basée sur la traditionnelle interface socket,
  • Elle permet le style de programmation un-vers-N (section 3). TCP ne permet que un-vers-un, UDP permet d'utiliser une prise (socket) pour du un-vers-N, et SCTP aussi. En termes SCTP, une prise permet de contrôler plusieurs associations. Par contre, pas de diffusion, que ne permet pas SCTP.
  • Elle permet également le style un-vers-un (section 4), familier aux programmeurs qui utilisent TCP. Avec ce style (une seule association par prise), les applications existantes qui se servent de TCP peuvent être portées en SCTP avec très peu d'efforts.

Ces deux styles ne sont pas compatibles dans le même programme, le programmeur devra choisir.

Notez que les efforts de conception d'une API SCTP sont anciens. Résultat, il traîne dans la nature des tutoriels, des Howto, des exemples de programme utilisant des mécanismes qui ne sont plus les mécanismes recommandés. Plusieurs éléments des API expérimentales qui ont précédé celle-ci sont repris dans ce RFC, en les notant comme dépassés et ne devant plus être utilisés pour de nouveaux programmes.

Un programme serveur typique qui utilise le style un-vers-N ressemble à :

socket(..., SOCK_SEQPACKET, IPPROTO_SCTP): /* Le type SOCK_SEQPACKET indique le
style 1-vers-n. Section 3.1.1 */
bind(...);
listen(...); /* Pas besoin de accept(). Les nouvelles associations
sont gérées automatiquement (si le serveur le veut, il est prévenu
lors des recvmsg(), évenement SCTP_ASSOC_CHANGE). Section 3.1.3 */
recvmsg(...);
sendmsg(...);
close(...); /* close() ferme tout. Pour ne fermer qu'une seule association, on utilise
sendmsg() avec SCTP_EOF. */

pendant que le client fera plutôt :

socket(..., SOCK_SEQPACKET, IPPROTO_SCTP):
sendmsg(...);
recvmsg(...);
close(...):

Toutes les associations du serveur seront représentées par une seule prise et distinguées par leur identificateur d'association, de type sctp_assoc_t. La section 3.3 fournit les détails pour ce cas. Par exemple, si le programme n'utilise qu'un seul tampon par prise réseau, une association qui traîne peut bloquer toutes les autres. Le RFC recommande d'utiliser des prises non-bloquantes.

Quant au style un-vers-un, c'est celui de TCP et il est familier à tous les programmeurs réseau. Il est présenté en section 4. L'idée est qu'une application d'aujourd'hui, qui utilise TCP, sera ainsi portée en très peu de temps.

La séquence de commandes pour le serveur est typiquement :

socket(..., SOCK_STREAM, IPPROTO_SCTP); /* Le protocole IPPROTO_SCTP
est la seule différence avec TCP. */
bind(...);
listen(...);
accept(...);
/* Ensuite, recv() et send() avec la nouvelle prise retournée par
accept(). */
close(...);

Et chez le client :

socket(..., SOCK_STREAM, IPPROTO_SCTP); 
connect(...);
/* Ensuite, recv()/recvmsg() et send()/sendmsg() */
close(...);

Voici pour le code. La section 5 présente ensuite les nouvelles structures de données, celles qui sont spécifiques à SCTP, lorsqu'on utilise recvmsg() et sendmsg() pour des opérations de contrôle (et pas seulement d'envoi et de récupération de données). Ces fonctions prennent un paramètre message de type msghdr (RFC 3542). On peut s'en servir pour définir des paramètres de la connexion (options SCTP_INIT et SCTP_SNDINFO), ou obtenir des informations supplémentaires lors de la réception de données (option SCTP_RCVINFO, par exemple le champ rcv_assoc_id indiquera par quelle association est venue le message).

Pendant la durée de vie d'une connexion SCTP, des tas d'évenements qui n'ont pas d'équivalent dans le monde TCP peuvent se produire : changement d'adresse IP d'un pair (SCTP_PEER_ADDR_CHANGE, section 6.1.2), établissement de nouvelles associations (ou arrêt des anciennes, cf. SCTP_ASSOC_CHANGE, section 6.1.1), etc. La section 6 décrit comment être informé de ces évenements. Quant aux options des prises spécifiques à SCTP, elles sont dans la section 8. Elles s'utilisent avec setsockopt() et getsockopt(). Par exemple, SCTP_ASSOCINFO permet d'obtenir (ou de modifier) les paramètres liés aux associations, SCTP_PRIMARY_ADDR d'obtenir l'adresse IP du pair pour une association donnée, etc.

Le RFC contient en annexe A deux exemples d'utilisation de cette API, un pour un serveur en un-vers-N et un pour un client en un-vers-un. Pour les raisons expliquées plus haut (retard à normaliser l'API et bibliothèque non standards développées en attedant), ces exemples ne compilent pas sur une Debian ou une Ubuntu récente :

% gcc sctp-sample-client.c
sctp-sample-client.c: In function 'main':
sctp-sample-client.c:40:25: error: storage size of 'info' isn't known
sctp-sample-client.c:97:54: error: 'SCTP_SENDV_SNDINFO' undeclared (first use in this function)
sctp-sample-client.c:97:54: note: each undeclared identifier is reported only once for each function it appears in

Je n'ai pas encore trouvé de système où ces exemples compilent. Il existe en effet plusieurs mises en œuvre de SCTP mais pas de cette API. Plus exactement, les implémentations de cette API sont ultra-récentes et ne sont pas encore arrivés chez l'utilisateur. On a :

Le RFC note que des implémentations de l'API standard existent sur Linux, FreeBSD et Solaris mais leur déploiement effectif est inconnu. Elles ont apparemment déjà servi à ajouter SCTP à Firefox et Chrome.

Le livre de référence sur la programmation réseau, celui de Stevens, ne parle pas de SCTP dans les deux premières éditions. C'est à partir de la troisième édition (réalisée par d'autres, après la mort de l'auteur) que SCTP apparaît.

En attendant, la bogue echoping #1676608 risque d'attendre longtemps (d'autant plus que je n'ai plus le temps de m'occuper d'echoping).


Téléchargez le RFC 6458


L'article seul

RFC 6455: The WebSocket protocol

Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : I. Fette (Google), A. Melnikov (Isode)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF hybi
Première rédaction de cet article le 12 Décembre 2011


Ce nouveau protocole, WebSocket, vise à résoudre un problème embêtant pour les développeurs d'applications réseau. L'architecture de l'Internet était conçue pour que le seul point commun réellement obligatoire soit le protocole de couche 3, IP. Ce protocole est simple et fournit peu de services. Les développeurs qui voulaient des choses en plus les mettaient dans leurs applications ou, la plupart du temps, comptaient sur les protocoles de transport comme TCP. Si aucun des protocoles de transport existant ne satisfaisaient leurs besoins, ils avaient parfaitement le droit d'en inventer un autre et de le déployer sans rien demander à personne (principe dit « de bout en bout »). Ce modèle ne marche plus guère aujourd'hui. Il est devenu très difficile de faire passer un autre protocole de transport que TCP à travers les innombrables obstacles du réseau (NAT et pare-feux, notamment), et même un protocole applicatif nouveau, tournant sur un port TCP à lui, risque d'avoir le plus grand mal à passer. D'où l'idée de base de WebSocket : faire un protocole de transport au dessus de HTTP, qui va être le seul à passer à peu près partout. WebSocket est donc l'aboutissement d'un processus, qui a mené à ce que le protocole d'unification ne soit plus IP mais HTTP. Bienvenue dans l'Internet d'aujourd'hui « Tout sur le port 80 ».

WebSocket n'est toutefois pas un protocole généraliste, il est conçu pour fonctionner essentiellement dans le cadre du navigateur Web qui charge du code inconnu (typiquement en JavaScript) et qui va ensuite l'exécuter. Ce code pourra utiliser le réseau, dans une certaine limite (vers la même origine, cf. RFC 6454) mais les possibilités de communication offertes précédemment étaient limitées. WebSocket donne à ce code JavaScript (ou écrit dans d'autres langages) les possibilités d'une vraie communication réseau bidirectionnelle.

Avant, les applications s'exécutant sur le navigateur n'avaient pas de moyen simple de faire de telles communications, équivalentes à ce qu'on fait en TCP. Des applications comme la messagerie instantanée, le partage d'un document en cours d'édition ou bien comme des jeux en commun souhaitaient un modèle d'interaction plus riche que le traditionnel GET du client vers le serveur. Bien sûr, elles auraient pu être extérieures au navigateur, ce qui était certainement plus propre du point de vue architectural. Mais elles se heurtent alors au problème de filtrage décrit plus haut. Et, dans le navigateur, elles dépendaient de XMLHttpRequest ou bien de <iframe> et de polling. Par exemple, un code tournant sur le navigateur qui voulait simplement se mettre en attente de donnés émises de manière asynchrone par le serveur n'avait pas d'autres solutions que d'interroger ce dernier de temps en temps. Ce problème est décrit en détail dans le RFC 6202. Il avait plusieurs conséquences fâcheuses comme un surcoût en octets (tout envoi de données nécessitait les en-têtes HTTP complets) ou comme un modèle de programmation peu naturel.

WebSocket vise à résoudre ce problème en transformant HTTP en un protocole de transport. Il réutilise toute l'infrastructure HTTP (par exemple les relais ou bien l'authentification). Passant sur les mêmes ports 80 et 443, on espère qu'il réussira à passer partout. Comme le note un observateur, « WebSocket est un protocole totalement alambiqué pour contourner la stupidité du monde ».

Le résultat n'est donc pas parfait (rappelez-vous que HTTP n'avait pas été conçu pour cela) et le RFC note qu'on verra peut-être un jour les services de WebSocket fonctionner directement sur TCP (personnellement, j'ai des doutes, puisqu'on pourrait aussi bien dans ce cas utiliser des protocoles de transport qui fournissent les mêmes services, comme SCTP - RFC 4960).

Une petite note avant d'attaquer le RFC : si vous avez l'habitude de lire des RFC, vous noterez que celui-ci a des notations originales (section 2.1) comme d'utiliser les tirets bas pour souligner les définitions, les barres verticales pour encadrer les noms d'en-têtes ou de variables et les barres obliques pour les valeurs des variables.

La section 1.2 résume le fonctionnement du protocole (le lecteur pressé du RFC peut d'ailleurs se contenter de la section 1, non normative mais qui contient l'essentiel sur WebSocket). Le principe de base est d'utiliser du HTTP normal (RFC 2616) mais le client ajoute un en-tête Upgrade: à une requête GET, pour indiquer sa volonté de faire du WebSocket :

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Le serveur répond alors par un code 101 et en indiquant upgrade dans l'en-tête Connection: et en ajoutant des en-têtes spécifiques à WebSocket :

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

Bien sûr, d'autres en-têtes HTTP sont possibles comme les petits gâteaux du RFC 6265. Une fois que le client a fait sa demande, et que le serveur l'a acceptée, il existe une connexion bidirectionnelle entre ces deux acteurs et on peut faire passer les données.

Contrairement à TCP (mais comme dans SCTP), la communication n'est pas un flot d'octets sans structure ; c'est une suite de messages, chacun composé d'une ou plusieurs trames. Les trames sont typées et toutes les trames d'un même message ont le même type. Par exemple, il existe un type texte, où les trames contiennent des caractères Unicode encodés en UTF-8. Il existe évidemment un type binaire. Et il existe des trames de contrôle, conçues pour l'usage du protocole lui-même.

La section 1.3 se focalise sur la poignée de main entre client et serveur qui lance le protocole (les détails complets étant en section 4). On l'a vu, le client doit ajouter l'en-tête Upgrade: websocket pour demander au serveur de basculer en WebSocket (RFC 2616, section 14.42 ; la valeur websocket pour cet en-tête est enregistrée à l'IANA, cf. section 11.2, et aussi le RFC 2817, section 7.2). Le client indique également des en-têtes spécifiques à WebSocket comme Sec-WebSocket-Protocol: qui permet d'indiquer un protocole applicatif au dessus de WebSocket (chat dans l'exemple plus haut). Ces protocoles applicatifs (section 1.9) sont normalement enregistrés à l'IANA pour assurer l'unicité de leurs noms. L'en-tête Origin: du RFC 6454 sert à indiquer quelle était l'origine de la page Web qui a chargé le script client. Quand à Sec-WebSocket-Key:, son rôle est de permettre de vérifier que la connexion était bien prévue pour être du WebSocket et pas des jeux faits par un programme malveillant qui enverrait des données ressemblant à du WebSocket sur le port 80, sans être passé par la poignée de main normale. Le serveur doit combiner la valeur de l'en-tête Sec-WebSocket-Key: avec un GUID (RFC 4122) fixe, 258EAFA5-E914-47DA-95CA-C5AB0DC85B11. Il passe le résultat par SHA-1 puis par Base64 et retourne ce résultat au client (dans un en-tête Sec-WebSocket-Accept:), qui peut alors être sûr que c'est bien ce serveur qui a reçu sa poignée de main. (Voir la section 1.6 sur ce point. Les en-têtes commençant par Sec ne peuvent pas être ajoutés via du code XMLHttpRequest normal et, donc, un client JavaScript ordinaire ne peut pas se comporter en client WebSocket.)

À noter que les en-têtes spécifiques de WebSocket ont été ajoutés au registre des en-têtes.

La réponse du serveur utilise le code HTTP 101 (qui avait été prévu de longue date par le RFC 2616, section 10.1.2), qui signifie que le serveur accepte le changement de protocole. Tout autre code indique que le serveur n'accepte pas WebSocket et que le client doit donc continuer en HTTP normal. Ainsi, un serveur HTTP normal refusera l'en-tête Upgrade: :

% telnet www.bortzmeyer.org http
Trying 2605:4500:2:245b::bad:dcaf...
Connected to www.bortzmeyer.org.
Escape character is '^]'.
GET / HTTP/1.1
Host: www.bortzmeyer.org
Upgrade: websocket

HTTP/1.1 400 Bad Request
Date: Tue, 29 Nov 2011 21:15:34 GMT
Server: Apache/2.2.16 (Debian)
Vary: Accept-Encoding
Content-Length: 310
Connection: close
Content-Type: text/html; charset=iso-8859-1

La section 1.4, elle, décrit la fermeture de la connexion (détails en section 7). Elle se fait par l'envoi d'une trame de contrôle ad hoc. Notez que la simple fermeture de la connexion TCP sous-jacente ne suffit pas forcément : en présence d'intermédiaires, par exemple les relais, elle peut être insuffisante.

Un peu de philosophie après ces détails ? La section 1.5 décrit les concepts à la base de WebSocket. Par exemple, l'un des buts était de garder au strict minimum le nombre de bits de tramage. La structure des données que permet WebSocket est donc réduite (séparation des trames, et typage de celles-ci) et toute structuration plus sophistiquée (par exemple pour indiquer des méta-données) doit être faite par l'application, au dessus de WebSocket.

Dans cette optique « ne pas trop en ajouter », cette section note que WebSocket ajoute à TCP uniquement :

  • Le modèle de sécurité du Web, fondé sur la notion d'origine du RFC 6454,
  • Un mécanisme de nommage permettant de mettre plusieurs applications sur le même port (c'est le chemin donné en argument de la commande GET),
  • Un système de tramage, que n'a pas TCP, qui ne connait que les flots d'octets sans structure,
  • Un mécanisme de fermeture explicite de la connexion (on l'a dit, TCP seul ne suffit pas, dans la jungle qu'est le Web d'aujourd'hui, truffé de middleboxes).

Et c'est tout. Le reste doit être fait par les applications. Compte-tenu des contraintes spécifiques du Web, WebSocket offre donc pratiquement le même service aux applications que TCP. Sans ces contraintes Web (de sécurité, de fonctionnement à travers les middleboxes), du TCP brut suffirait.

Voila, vous connaissez maintenant l'essentiel de WebSocket. Le reste du RFC précise les détails. La section 3 décrit les URI WebSocket. Ils utilisent le plan ws: (non chiffré, port 80 par défaut) ou le wss: (chiffré avec TLS, port 443 par défaut). La section 11 décrit l'enregistrement de ces plans dans le registre IANA. Par exemple ws://example.com/chat est un URI WebSocket (pour la connexion donnée en exemple au début de cet article), comme ws://www.3kbo.com:9090/servers/1/status ou wss://foobar.example/newsfeed.

Comment fonctionne le tramage, le découpage du flot de données en trames bien délimitées ? La section 5 le normalise avec précision. Une trame a un type, une longueur et des données. On trouve également quelques bits comme FIN qui indique la dernière trame d'un message, ou comme RSV1, RSV2 et RSV3, réservés pour de futures extensions du protocole. Une grammaire complète est donnée en section 5.2, en utilisant ABNF (RFC 5234. Les fanas d'ABNF noteront que cette grammaire ne décrit pas des caractères mais des bits, ce qui représente une utilisation originale de la norme.

Le type est nommé opcode et occupe quatre bits. Les valeurs de 0x0 à 0x7 indiquent une trame de données, les autres sont des trames de contrôle. 0x1 indique une trame de texte, 0x2 du binaire, 0x8 est une trame de contrôle signalant la fin de la connexion, 0x9 une demande d'écho (ping), 0xA une réponse (pong), etc. La sémantique des trames de contrôle figure en section 5.5. On y apprend par exemple que des échos non sollicités (pong non précédé d'un ping) sont légaux et peuvent servir à indiquer qu'une machine est toujours en vie.

On le sait, l'insécurité est une des plaies du Web, on trouve tout le temps de nouvelles manières de pirater les utilisateurs. Les problèmes viennent souvent de nouveaux services ou de nouvelles fonctions qui semblent super-cool sur le moment mais dont on découvre après qu'elles offrent plein de pièges. Il n'est donc pas étonnant que la section 10, sur la sécurité, soit longue.

D'abord, le serveur WebSocket doit se rappeler qu'il peut avoir deux sortes de clients (section 10.1) : du code « embarqué » par exemple du JavaScript exécuté par un navigateur et dont l'environnement d'exécution contraint sérieusement les possibilités. Par exemple, l'en-tête Origin: est mis par ce dernier, pas par le code Javascript, qui ne peut donc pas mentir sur sa provenance. Mais un serveur WebSocket peut aussi être appelé par un client plus capable, par exemple un programe autonome. Celui-ci peut alors raconter ce qu'il veut. Le serveur ne doit donc pas faire confiance (par exemple, il ne doit pas supposer que les données sont valides : il serait très imprudent de faire une confiance aveugle au champ Payload length, qu'un client malveillant a pu mettre à une valeur plus élevée que la taille de la trame, pour tenter un débordement de tampon).

WebSocket ayant été conçu pour fonctionner au dessus de l'infrastructure Web existante, y compris les relais, la section 10.3 décrit les risques que courent ceux-ci. Un exemple est l'envoi, par un client malveillant, de données qui seront du WebSocket pour le serveur mais qui sembleront un GET normal pour le relais. Outre le tramage, la principale protection de WebSocket contre ce genre d'attaques est le masquage des données avec une clé contrôlée par l'environnement d'exécution (l'interpréteur JavaScript, par exemple), pas par l'application (section 5.3 pour en savoir plus sur le masquage). Ainsi, un code JavaScript méchant ne pourra pas fabriquer des chaînes de bits de son choix, que WebSocket transmettrait aveuglément.

Un peu d'histoire et de politique, maintenant. WebSocket a une histoire compliquée. L'idée de pousser les informations du serveur vers le client (connue sous le nom de Comet) est ancienne. Le protocole WebSocket (dont l'un des buts est justement cela) a été créé par Ian Hickson (qui a aussi écrit les premiers projets de RFC mais n'apparait plus comme auteur). Le groupe de travail WHATWG a ensuite beaucoup participé. La plupart des mises en œuvre de WebSocket citent ce groupe ou bien les anciens Internet-Drafts, écrits avant la création du groupe de travail IETF HyBi en janvier 2010.

Le principe même de WebSocket a souvent été contesté. Pourquoi passer tant d'efforts à contourner les problèmes de l'Internet aujourd'hui (notamment les middleboxes abusives) plutôt qu'à les résoudre ? Un intéressant texte de justification a été écrit à ce sujet. Notez qu'il inclut des exemples de code. Le groupe HyBi a connu de vives discussions, avec menaces de scission (« À WHATWG, c'était mieux, on va quitter l'IETF si ça n'avance pas »). Un des points d'affrontement était par exemple les problèmes de sécurité (résolus par la solution du masquage). Cela s'est ensuite arrangé, début 2011.

Si vous voulez vous lancer dans la programmation d'applications WebSocket tournant dans le navigateur, regardez l'API. Aujourd'hui, on trouve des implémentations de WebSocket pour les différents serveurs (GlassFish, Jetty, Apache). Dans les environnements de développement, on trouve du WebSocket chez Django et bien d'autres. Chez les clients, Firefox l'a en théorie depuis la version 6, Chrome et Internet Explorer l'ont annoncé pour une version prochaine. Bon, en pratique, c'est compliqué, et la démo ne donne pas toujours les résultats attendus (elle me refuse mon Firefox 7 mais accepte un Chrome).

Attention si vous lisez les sources, pas mal d'implémentations ont été faites en suivant des vieilles versions de la spécification de WebSocket, antérieures à sa normalisation à l'IETF. Cela se sent par exemple dans les noms des variables utilisés. (Un terme comme « opcode » pour le type est dans le RFC mais pas toujours dans les programmes.)

En dehors du monde des navigateurs, si vous voulez programmer du WebSocket, vous avez, entre autres :

Si vous voulez jouer plutôt avec un programme client comme curl, vous avez un bon article qui explique comment faire du WebSocket avec curl.

Si vous cherchez des fichiers pcap de Websocket, on en trouve sur pcapr mais attention, la plupart concernent des mises en œuvres de versions antérieures du protocole. Mais Wireshark n'a pas l'air encore capable de décoder le framing Websocket.

Enfin, si vous voulez d'autres articles sur WebSocket, j'ai beaucoup apprécié celui de Brian Raymor.


Téléchargez le RFC 6455


L'article seul

RFC 6454: The Web Origin Concept

Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : A. Barth (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF websec
Première rédaction de cet article le 12 Décembre 2011


Chaque jour, plusieurs failles de sécurité sont annoncées frappant un site Web, ou, plus rarement, un navigateur. Ces failles proviennent souvent de l'exécution de code, par exemple Java ou JavaScript, téléchargé depuis un serveur qui n'était pas digne de confiance, et exécuté avec davantage de privilèges qu'il n'aurait fallu. Une des armes principales utilisées par la sécurité du Web, pour essayer d'endiguer la marée de ces attaques, est le concept d'origine. L'idée est que toute ressource téléchargée (notamment le code) a une origine, et que cette ressource peut ensuite accéder uniquement à ce qui a la même origine qu'elle. Ainsi, un code JavaScript téléchargé depuis www.example.com aura le droit d'accéder à l'arbre DOM de www.example.com, ou à ses cookies, mais pas à ceux de manager.example.net. Ce concept d'origine semble simple mais il y a plein de subtileries qui le rendent en fait très complexe et, surtout, il n'avait jamais été défini précisément. Ce que tente de faire ce RFC.

Pour comprendre l'importance de l'origine, revoyons un navigateur Web en action. Imaginons qu'il n'impose aucune limite au code (Java, JavaScript, Silverlight, etc) qu'il exécute. Un méchant pourrait alors mettre du code malveillant JavaScript sur son serveur, faire de la publicité (par exemple via le spam) pour http://www.evil.example/scarlet-johansson-pictures/, et attendre les visites. Le navigateur récupérerait l'HTML, puis le JavaScript inclus, et celui-ci pourrait faire des choses comme lancer une DoS par connexions HTTP répétées vers http://www.victim.example/. C'est pour éviter ce genre d'attaques que tous les navigateurs ont la notion d'origine. Le code récupéré sur le site du méchant va avoir l'origine www.evil.example, et le navigateur l'empêchera de faire des requêtes HTTP vers un autre serveur que www.evil.example. En gros, le principe traditionnel de sécurité est « Le contenu récupéré depuis l'origine X peut interagir librement avec les ressources ayant cette même origine. Le reste est interdit. » (section 1 du RFC, pour un résumé).

Mais ce principe très simple à énoncer et à comprendre dissimule pas mal de pièges. Ce RFC va donc essayer de les mettre en évidence. À noter qu'il ne fait que fournir un cadre, ce n'est pas un protocole, et il n'y a donc pas besoin de modifier les navigateurs pour obéir à ce texte. Les détails concrets du principe d'origine vont en effet dépendre du protocole utilisé et chacun (HTML, WebSockets du RFC 6455, etc) va donc devoir décliner ce principe selon ses caractéristiques propres. Par exemple, pour le futur HTML5, voici la définition.

Donc, on attaque avec la section 3, qui expose ce qu'est ce « principe de même origine » (Same Origin Policy). D'abord, la confiance (section 3.1) est exprimée sous forme d'un URI. Lorsque le serveur www.niceguy.example sert une page HTML https://www.niceguy.example/foo/bar.html qui contient :


   <script src="https://example.com/library.js"/>

Il annonce sa confiance envers l'URI https://example.com/library.js. Le code JavaScript téléchargé via cet URI sera exécuté avec les privilèges de https://www.niceguy.example/foo/bar.html, qui a choisi de lui faire confiance.

Cette idée de « confiance par URI » peut poser des problèmes dans certains cas. Par exemple, si on utilise le STARTTLS du RFC 2817, le fait d'utiliser TLS ou pas n'apparait pas dans l'URI et la page HTML ne peut donc pas exiger TLS. Les URI de plan https: n'ont pas ce défaut, l'exigence de TLS y est explicite.

Mais il y a une question plus sérieuse : dans https://www.niceguy.example/foo/bar.html, quelle est l'origine, celle dont vont dépendre les autorisations ultérieures (section 3.2) ? Est-ce tout l'URI ? Ou bien seulement le FQDN www.niceguy.example ? Réponse : aucune des deux.

Utiliser tout l'URL comme origine manquerait de souplesse. Un code venu de http://www.niceguy.example/foo ne pourrait pas interagir avec du contenu récupéré en http://www.niceguy.example/bar. Mais n'utiliser que le nom de domaine n'est pas génial non plus. Car cela permettrait à du code JavaScript récupéré par http://www.niceguy.example:8080/ de modifier un arbre DOM de https://www.niceguy.example/ (notez que la seconde est sécurisée avec HTTPS ; ne se servir que du nom de domaine comme origine permettrait à du contenu non sûr de manipuler du contenu sûr).

Et faut-il utiliser tout le FQDN ? Cela empêche http://portal.niceguy.example/ de jouer avec http://manager.niceguy.example/ alors que les deux sites sont sous la même autorité, celle de niceguy.example. Mais le problème est que la détermination de cette autorité est difficile. Contrairement à ce que croient les débutants, elle n'est pas forcément dans les deux derniers composants du nom de domaine. Par exemple, jones.co.uk et smith.co.uk ne sont pas sous la même autorité. Et, même lorsque c'est le cas, une Université ne souhaite pas forcément que http://students.example.edu/ (consacré aux pages personnelles des étudiants) aient des droits sur http://admin.example.edu/. Bien sûr, aucun système n'est parfait. Avec le FQDN, http://example.edu/students/~mark aura des droits sur http://example.edu/grades/admin. Mais ce modèle fondé sur le FQDN est maintenant trop ancien pour le changer (rappelez-vous qu'il a évolué informellement, notre RFC 6454 ne fait que le documenter a posteriori).

Donc, pour résumer le point important de la section 3.2 : une origine est un tuple {FQDN, plan, port}. Par exemple, http://example.com/, http://example.com:80 et http://example.com/toto.html ont tous les trois la même origine, le tuple {example.com, http, 80}. En revanche, http://example.com:81/ a une autre origine (port différent), de même que ftp://example.com (plan différent), ou http://www.example.com/ (nom différent).

Ce principe de même origine ne répond pas à tous les risques de sécurité. Il faut également intégrer la notion d'autorité (tel que ce terme est utilisé en sécurité, notez que le RFC 3986 utilise ce mot dans un autre sens). L'autorité est que le navigateur donne des droits différents selon le type de document. Une image n'a aucun droit, c'est du contenu passif (du moins pour les formats traditionnels : avec des formats comme SVG, l'analyse de sécurité est bien plus complexe). En revanche, un document HTML a le droit de déclencher le chargement d'autres ressources (styles CSS mais surtout code actif, par exemple JavaScript). Normalement, l'autorité dépend du type MIME indiqué (image/png pour une image, text/html pour l'HTML). Si ce type est déterminé par un utilisateur, de nouvelles vulnérabilités peuvent survenir (et certains navigateurs sont assez imprudents pour deviner le type MIME en examinant le contenu, une mauvaise pratique, connue sous le nom de content sniffing). Pire, si l'utilisateur peut insérer du contenu qu'il choisit dans des documents ayant une forte autorité (pages HTML), de nouveaux risques peuvent survenir. Par exemple, une attaque XSS débute par l'insertion de contenu dans une page HTML, contenu qui sera ensuite interprété par le navigateur, et exécuté avec l'origine de la page Web (cf. section 8.3). Or, ce cas est très fréquent (pensez à un moteur de recherche qui affiche la requête originale sans précaution, alorss qu'elle était choisie par un utilisateur extérieur). La protection contre les XSS est complexe mais le conseil de base est : modifiez tout contenu venu de l'extérieur avant de l'inclure dans un document ayant de l'autorité (comme une page HTML), de façon à ce qu'il ne puisse pas être interprété par le navigateur. Le plus simple pour cela est d'utiliser exclusivement un système de gabarit pour fabriquer les pages. Il se chargera alors des précautions comme de transformer les < en &lt;.

Une fois déterminée l'origine, il reste à décider des privilèges donnés aux objets de la même origine (section 3.4). Pour les objets récupérés, on l'a vu, la politique est typiquement de ne donner accès qu'aux objets de même origine que le code. Mais pour les accès à d'autres objets, tout est bien plus complexe et la sécurité rentre ici en conflit avec l'utilisabilité. Par exemple, une application stricte du principe de même origine aux accès aux ressources interdirait à une page Web de mener à une autre page, d'origine différente, alors que c'est évidemment une fonction essentielle du Web. Moins caricatural, le cas d'images ou autres contenus embarqués dans une page Web. Bien que cela pose des problèmes de sécurité (pensez aux Web bugs), aucun navigateur n'impose que les images aient la même origine que la page qui les charge... De même, aucun navigateur n'interdit complètement d'envoyer des données à une autre origine, même si c'est la base de nombreuses CSRF.

Voilà, l'essentiel des principes du RFC tient dans cette section 3. Le reste, ce sont les détails pratiques. La section 4 formalise la notion d'origine en en donnant une définition rigoureuse. Elle couvre des cas rigolos comme les URI de plan file: (autrefois, les navigateurs considéraient tous les fichiers locaux comme ayant la même origine, aujourd'hui, les plus paranoïaques font de chaque fichier une origine différente), ou bien explicite le cas des ports par défaut de certains plans (vous avez remarqué l'équivalence entre les URI http://example.com/, http://example.com:80, plus haut ?). La section 5 décrit d'autres pièges comme le cas des plans où n'apparaissent pas de noms de machine comme par exemple les data: du RFC 2397 (un cas amusant car deux URI data: complètement identiques, bit par bit, sont quand même d'origine différente). Et la section 6 explique la sérialisation d'un URI, à des fins de comparaison simples avec d'autres URI, pour déterminer s'ils ont la même origine. Par exemple, http://www.example.com:80/ et http://www.example.com/toto se sérialisent tous les deux en http://www.example.com. Pour les URI de type {scheme, host, port} (les plus fréquents), une simple comparaison de chaînes de caractères nous dira ensuite s'ils ont la même origine (ici, oui).

Si on revient au premier exemple JavaScript que j'ai donné, celui où https://www.niceguy.example/foo/bar.html charge https://example.com/library.js, on voit que l'origine n'est pas l'URI du script mais celle de la page qui le charge. Or, on peut imaginer que le serveur example.com voudrait bien connaître cette origine, par exemple pour appliquer des règles différentes. ou tout simplement pour informer le script du contexte dans lequel il va s'exécuter. C'est le rôle de l'en-tête HTTP Origin:, normalisé dans la section 7, et qui peut être ajouté aux requêtes. Ainsi, dans l'exemple ci-dessus, la requête HTTP ressemblerait à :

[Connexion à exemple.com...]
GET /library.js HTTP/1.1
Host: example.com
Origin: https://www.niceguy.example
...

On voit que l'origine indiquée est la forme sérialisée comme indiqué plus haut. Ce n'est donc pas l'équivalent de Referer: qui indique un URI complet.

Cet en-tête est désormais dans le registre des en-têtes (cf. section 9).

Comme tout ce RFC décrit un mécanisme de sécurité, il est prudent de bien lire la section 8, Security Considerations, qui prend de la hauteur et rappelle les limites de ce mécanisme. Historiquement, d'autres modèles que le « principe de même origine » ont été utilisés (à noter que le RFC ne fournit pas de référence), comme le taint tracking ou l'exfiltration prevention mais pas avec le même succès.

D'abord, la notion d'origine est une notion unique qui s'applique à des problèmes très différents et peut donc ne pas être optimisée pour tous les cas.

Ensuite, elle dépend du DNS (section 8.1) puisque la plupart des plans d'URI utilisent la notion d'host et que la politique de même origine considère que deux serveurs sont les mêmes s'ils ont le même nom. Si l'attaquant contrôle le DNS, plus aucune sécurité n'est possible (on croit parler au vrai www.example.com et on parle en fait à une autre machine).

À noter que le RFC prend bien soin de ne pas parler de la principale vulnérabilité de ce concept d'host : l'absence de notion générale d'identité d'une machine dans l'Internet (cette notion n'existe que pour certains protocoles spécifiques comme SSH). En l'absence d'une telle notion, des attaques sont possibles sans que l'attaquant ait eu à compromettre le DNS, comme par exemple le changement d'adresse IP.

Autre piège, le fait que le principe de même origine, ne soit pas apparu tout de suite et que certaines techniques de sécurité du Web utilisent une autre unité d'isolation que l'origine (section 8.2). Le Web n'a pas en effet de sécurité cohérente. C'est le cas des cookies (RFC 6265), qui se servent d'un autre concept, le « domaine enregistré ». Le navigateur essaie de trouver, lorsqu'il récupère un cookie, à quel « domaine enregistré » il appartient (l'idée étant que sales.example.com et it.example.com appartiennent au même domaine enregistré, alors qu'ils n'ont pas la même origine). Il enverra ensuite le cookie lors des connexions au même domaine enregistré. Pour déterminer ce domaine, notez que les cookies ne font pas de différence entre HTTP et HTTPS (sauf utilisation de l'attribut Secure) et qu'un cookie acquis de manière sûre peut donc être envoyé par un canal non sûr.

Notre RFC note que cette pratique d'utiliser le « domaine enregistré » est mauvaise et la déconseille. En effet :

  • Rien n'indique dans le nom lui-même où est le domaine enregistré. Sans connaître les règles d'enregistrement de JPRS, vous ne pouvez pas dire que a.co.jp et b.co.jp sont deux domaines enregistrés différents. Il existe des listes publiques de politiques d'enregistrement comme http://publicsuffix.org/ mais aucune n'est officielle et aucune n'est à jour.
  • Cette pratique dépend fortement du plan d'URI utilisé, certains n'ayant pas de domaine (donc pas de domaine enregistré).

Autre faiblesse du principe de même origine, l'autorité diffuse (section 8.3). L'autorité va dépendre de l'URI, pas du contenu. Or, un URI de confiance peut inclure du contenu qui ne l'est pas (pour le cas, fréquent, où une page Web inclut du contenu généré par l'utiisateur) et c'est alors un risque de XSS.

Résultat, le principe de même origine ne suffit pas à lui seul à protéger l'utilisateur (plusieurs attaques ont déjà été documentées.) Il faut donc ajouter d'autres pratiques de sécurité.

Notez que la question des mises en œuvre de ce RFC ne se pose pas, il a été réalisé après le déploiement du concept de même origine et tous les navigateurs Web utilisent aujourd'hui ce système. Toutefois, certains ne le font peut-être pas encore absolument comme décrit ici, par exemple en accordant au plan ou au port moins de poids qu'au host (il semble que cela ait été le cas de certaines versions d'Internet Explorer).

Une autre bonne lecture sur ce concept d'origine est l'article de Google pour les développeurs.


Téléchargez le RFC 6454


L'article seul

RFC 6452: The Unicode code points and IDNA - Unicode 6.0

Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : P. Faltstrom (Cisco), P. Hoffman (VPN Consortium)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 13 Novembre 2011


Une des exigences de la norme sur les IDN (RFC 5890) est la stabilité : si un caractère est autorisé dans les noms de domaine à un moment donné, il devrait l'être pour toujours, sous peine qu'une épée de Damoclès pèse sur les titulaires de noms, la crainte qu'un nom qu'ils utilisent devienne subitement invalide. Mais le mécanisme par lequel sont déterminés les caractères autorisés ou interdits rend inévitable de tels problèmes, heureusement dans des cas rares et marginaux. C'est ce qui vient de se produire avec la sortie de la norme Unicode version 6 : le caractère ᧚ (U+19DA), autrefois autorisé, est désormais interdit. S'il y avait eu des noms de domaine l'utilisant (ce n'était apparemment pas le cas), ils deviendraient subitement illégaux.

Vu que ce caractère est très rare, toute cette discussion n'est-elle pas une tempête dans un verre d'eau ? Pas complètement, parce que c'est la première fois que le problème se pose depuis la sortie de la version 2 de la norme IDN, et que la façon dont ce cas a été traité va servir de modèle pour des futurs problèmes qui pourraient être plus délicats.

Reprenons dès le début : dans la norme actuelle sur les IDN, dite « IDNAbis » (RFC 5890), les caractères Unicode peuvent être valides ou invalides dans un nom de domaine. Cette validité (qui était déterminée manuellement dans la première version d'IDN) découle d'un algorithme, normalisé dans le RFC 5892, qui prend en compte les propriétés que la norme Unicode attache à un caractère. Par exemple, si le caractère a la propriété « Est une lettre », il est valide. Ce système a l'avantage de remédier au principal inconvénient d'IDN version 1, le fait que le premier IDN était lié à une version particulière d'Unicode. Avec IDNAbis, au contraire, lorsque le consortium Unicode sort une nouvelle version de sa norme, il suffit de faire tourner à nouveau l'algorithme, et on a la liste des caractères valides dans cette nouvelle version.

Le problème que cela pose est que les propriétés d'un caractère Unicode peuvent changer d'une version à l'autre. Elles ne sont pas forcément couvertes par les engagements de stabilité du consortium Unicode. C'est ce qui s'est produit en octobre 2010, lors de la sortie de la version 6 d'Unicode. Trois caractères ont vu leur validité changer car leur GeneralCategory Unicode a changé. Pour les deux premiers, rien de très grave. ೱ (U+0CF1) et ೲ (U+0CF2), classés à tort comme des symboles, ont été reclassés comme lettres et sont donc devenus valides, alors qu'ils étaient invalides. Personne n'avait donc pu les utiliser et le changement ne va donc pas affecter les titulaires de noms de domaine.

Mais le troisième pose un problème épineux. Pas quantitativement. Ce caractère ᧚ (U+19DA), de l'écriture Tai Lue n'a apparemment jamais été utilisé dans un nom de domaine, en partie par ce que l'écriture dont il fait partie est peu répandue (et ses utilisateurs sont peu connectés à l'Internet). Mais, qualitativement, c'est ennuyeux car U+19DA (un chiffre) fait le chemin inverse. D'autorisé, il devient interdit. Potentiellement, il peut donc remettre en cause la stabilité des noms de domaine. Si on applique aveuglément l'algorithme du RFC 5892, U+19DA va devenir interdit. Alors, que faire ? Le RFC 5892 (section 2.7) prévoyait une table des exceptions, où on pouvait mettre les caractères à qui on désirait épargner le sort commun. Fallait-il y mettre le chiffre 1 du Tai Lue ?

La décision finalement prise, et documentée par ce RFC (décision pompeusement baptisée « IETF consensus », bien que la section 5 rappelle qu'elle a été vigoureusement discutée) a finalement été de laisser s'accomplir le destin. Aucune exception n'a été ajoutée pour ces trois caractères, l'algorithme normal s'applique et U+19DA ne peut donc plus être utilisé. L'argument principal est que ce caractère n'était quasiment pas utilisé. Les cas suivants mèneront donc peut-être à des décisions différentes (la section 2 rappelle bien que, dans le futur, les choses seront peut-être différentes).

Ce RFC 6452 documente donc cette décision. Bien qu'elle se résume à « ne touchons à rien », il était préférable de la noter, car un changement qui casse la compatibilité ascendante n'est pas à prendre à la légère.

Les deux autres caractères, utilisé en Kannada, ೱ (U+0CF1) et ೲ (U+0CF2) ne créent pas le même problème car ils ont changé en sens inverse (interdits autrefois, ils sont désormais autorisés).


Téléchargez le RFC 6452


L'article seul

RFC 6441: Time to Remove Filters for Previously Unallocated IPv4 /8s

Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : L. Vegoda (ICANN)
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 29 Novembre 2011
Dernière mise à jour le 5 Janvier 2012


Pour limiter certains risques de sécurité, des opérateurs réseaux filtraient en entrée de leur réseau les adresses IP non encore allouées (dites bogons). Les adresses IPv4 étant désormais totalement épuisées, cette pratique n'a plus lieu d'être et ce RFC demande donc que ces filtres soient démantelés.

L'idée était d'empêcher l'usage de ces préfixes IP non alloués. Ils représentaient des cibles tentantes, par exemple pour un spammeur qui voulait des adresses jetables et non traçables : on trouve un bloc non alloué, on l'annonce en BGP (puisqu'il n'est pas alloué, il n'y a pas de risque de collision), on envoie son spam et on arrête l'annonce BGP (voir les articles cités à la fin). Pour éviter cela, et d'autres attaques analogues, l'habitude s'est prise de filtrer les bogons, ces préfixes non alloués. Certains opérateurs rejetaient les annonces BGP pour ces bogons, d'autres bloquaient sur le pare-feu les paquets ayant une adresse source dans ces préfixes non alloués. Ces pratiques étaient largement documentées par exemple sur le site de référence sur les bogons.

Cette pratique a toujours posé des problèmes, notamment celui de la « débogonisation ». Lorsqu'un préfixe qui n'était pas alloué le devient, il faut toute une gymnastique pour le retirer des filtres existants, sachant que beaucoup de ces filtres ne sont que rarement mis à jour. On voit ainsi des messages sur les listes de diffusion d'opérateurs réseaux avertissant de l'arrivée prochaine d'un nouveau préfixe et demandant qu'il soit supprimé des filtres. Voici deux exemples de ces annonces en 2004 et en 2005. Pour permettre aux opérateurs de tester que tout va bien après cette suppression, les RIR mettent souvent un beacon, un amer, dans le préfixe, une adresse IP qu'on peut pinguer pour tester, comme le recommande le RFC 5943. Tout ce travail faisait donc que la chasse aux bogons était contestée depuis longtemps.

À noter (section 2) que le terme de bogon a été défini dans le RFC 3871, qui recommande leur blocage. Ce même RFC 3871 décrit en détail le problème que posent les bogons et la raison de leur éradication. Le terme de martien, plus flou (il vient du RFC 1208), est appliqué à toutes sortes de paquets dont l'adresse source est anormale (dans le DNS, il a un autre sens, celui de paquet de réponse à une question qui n'a pas été posée).

La section 3 représente le cœur du RFC : elle formule la nouvelle règle. Celle-ci, tenant compte de l'épuisement des adresses IPv4 est simple : tous les préfixes IPv4 sont désormais alloués ou réservés. Il ne faut donc filtrer que les réservés. Les autres peuvent désormais tous être une source légitime de trafic IP. La chasse aux bogons et les difficultés de la débogonisation faisant partie du folklore de l'Internet depuis très longtemps, c'est donc une page d'histoire qui se tourne. (Les adresses IPv6 sont, elles, loin d'être toutes allouées et ne sont donc pas concernées.)

La section 4 rappelle que l'autorité pour cette liste de préfixes réservés est le RFC 5735, ou son éventuel futur successeur. On y trouve par exemple les adresses privées du RFC 1918 ou bien les adresses réservées à la documentation du RFC 5737. Les listes de bogons qu'on trouve sur le réseau, comme celle de TeamCymru sont désormais réduites à ce groupe.

À noter que l'assertion « Tous les préfixes sont désormais alloués » ne vaut que pour les préfixes de longueur 8 (les « /8 ») distribués aux RIR. Certains peuvent filtrer à un niveau plus fin, en distinguant dans ces /8 les adresses que les RIR ont affectés de celles qui ne le sont pas encore. Comme le rappelle la section 3.2, cette pratique est risquée, les affectations par les RIR changeant vite. Le RFC demande donc que, si on a de tels filtres, ils soient changés au moins une fois par jour.

Pour en apprendre plus sur les bogons, on peut regarder la bonne analyse faite par BGPmon. On voit finalement peu d'annonces BGP de bogons (6 seulement en 2011), la plupart pour le préfixe 198.18.0.0/15 des mesures de performance (RFC 5735). Un bon résumé des bogons et de la débogonisation avait été fait par Dave Deitrich en 2005.

Quelques articles sur les trucs utilisés par des méchants (spammeurs, par exemple), en connexion avec les bogons :


Téléchargez le RFC 6441


L'article seul

RFC 6434: IPv6 Node Requirements

Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : E. Jankiewicz (SRI International), J. Loughney (Nokia), T. Narten (IBM Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 22 Décembre 2011


Il existe des tas de RFC qui concernent IPv6 et le programmeur qui met en œuvre ce protocole dans une machine risque fort d'en rater certains, ou bien d'implémenter certains qu'il aurait pu éviter. Ce RFC est donc un méta-RFC, chargé de dresser la liste de ce qui est indispensable dans une machine IPv6. Les deux points les plus chauds concernent la configuration (par DHCP ou par RA - Router Advertisment ?) et la gestion d'IPsec, désormais officiellement facultative.

Ce document remplace son prédécesseur, le RFC 4294. Il vise le même but, servir de carte au développeur qui veut doter un système de capacités IPv6 et qui se demande s'il doit vraiment tout faire (réponse : non). Ce RFC explique clairement quels sont les points d'IPv6 qu'on ne peut pas négliger, sous peine de ne pas pouvoir interagir avec les autres machines IPv6. Le reste est laissé à l'appréciation du développeur. La section 2 résume ce but.

Les deux gros changements par rapport au RFC 4294 sont :

  • DHCP monte en grade, bien que restant derrière les RA pour la configuration des machines IPv6,
  • IPsec n'est plus obligatoire.

Ce RFC s'applique à tous les nœuds IPv6, aussi bien les routeurs (ceux qui transmettent des paquets IPv6 reçus qui ne leur étaient pas destinés) que les machines terminales (toutes les autres).

Bien, maintenant, les obligations d'une machine IPv6, dans l'ordre. D'abord, la couche 2 (section 4 du RFC). Comme IPv4, IPv6 peut tourner sur des tas de couches de liaison différentes et d'autres apparaîtront certainement dans le futur. En attendant, on en a déjà beaucoup, Ethernet (RFC 2464), 802.16 (RFC 5121), PPP (RFC 5072) et bien d'autres, sans compter les tunnels.

Ensuite, la couche 3 (section 5 du RFC) qui est évidemment le gros morceau puisque c'est la couche d'IP. Le cœur d'IPv6 est normalisé dans le RFC 2460 et ce dernier RFC doit donc être intégralement implémenté, à l'exception de l'en-tête de routage de type 0, qui a été abandonné par le RFC 5095.

Comme IPv6, contrairement à IPv4, ne permet pas aux routeurs intermédiaires de fragmenter les paquets, la découverte de la MTU du chemin est particulièrement cruciale. La mise en œuvre du RFC 1981 est donc recommandée. Seules les machines ayant des ressources très limitées (genre où tout doit tenir dans la ROM de démarrage) sont dispensées. Mais le RFC se doit de rappeler que la détection de la MTU du chemin est malheuresement peu fiable dans l'Internet actuel, en raison du grand nombre de pare-feux configurés avec les pieds et qui bloquent tout l'ICMP. Il peut être donc nécessaire de se rabattre sur les techniques du RFC 4821).

Le RFC 2460 décrit le format des paquets et leur traitement. Les adresses y sont simplement mentionnées comme des champs de 128 bits de long. Leur architecture est normalisée dans le RFC 4291, qui est obligatoire.

Également indispensable à toute machine IPv6, l'autoconfiguration sans état du RFC 4862, ainsi que ses protocoles auxiliaires comme la détection d'une adresse déjà utilisée.

ICMP (RFC 4443) est évidemment obligatoire, c'est le protocole de signalisation d'IP (une des erreurs les plus courantes des administrateurs réseaux incompétents est de bloquer ICMP sur les pare-feux).

Dernier protocole obligatoire, la sélection de l'adresse source selon les règles du RFC 3484, pour le cas où la machine aurait le choix entre plusieurs adresses (ce qui est plus fréquent en IPv6 qu'en IPv4).

Le reste n'est en général pas absolument obligatoire mais recommandé (le terme a un sens précis dans les RFC, définie dans le RFC 2119 : ce qui est marqué d'un SHOULD doit être mis œuvre, sauf si on a une bonne raison explicite et qu'on sait exactement ce qu'on fait). Par exemple, la découverte des voisins (NDP, RFC 4861) est recommandée. Toutes les machines IPv6 en ont besoin, sauf si elles utilisent les liens ne permettant pas la diffusion.

Moins générale, la sélection d'une route par défaut s'il en existe plusieurs, telle que la normalise le RFC 4191. Elle est particulièrement importante pour les environnements SOHO (RFC 6204).

On a vu que l'autoconfiguration sans état (sans qu'un serveur doive se souvenir de qui a quelle adresse) était obligatoire. DHCP (RFC 3315), lui, n'est que recommandé.

Une extension utile (mais pas obligatoire) d'IP est celle des adresses IP temporaires du RFC 4941, permettant de résoudre certains problèmes de protection de la vie privée. Évidemment, elle n'a pas de sens pour toutes les machines (par exemple, un serveur dans son rack n'en a typiquement pas besoin). Elle est par contre recommandée pour les autres.

Encore moins d'usage général, la sécurisation des annonces de route (et des résolutions d'adresses des voisins) avec le protocole SEND (RFC 3971). Le déploiement effectif de SEND est très faible et le RFC ne peut donc pas recommander cette technique pour laquelle on n'a pas d'expérience, et qui reste simplement optionnelle.

L'une des grandes questions que se pose l'administrateur réseaux avec IPv6 a toujours été « autoconfiguration RA - Router Advertisment - ou bien DHCP ? » C'est l'un des gros points de ce RFC et la section 6 le discute en détail. Au début d'IPv6, DHCP n'existait pas encore pour IPv6 et les RA ne permettaient pas encore de transmettre des informations pourtant indispensables comme les adresses des résolveurs DNS (le RFC 6106 a résolu cela). Aujourd'hui, les deux protocoles ont à peu près des capacités équivalentes. RA a l'avantage d'être sans état, DHCP a l'avantage de permettre des options de configuration différentes par machine. Alors, quel protocole choisir ? Le problème de l'IETF est que si on en normalise deux, en laissant les administrateurs du réseau choisir, on court le risque de se trouver dans des situations où le réseau a choisi DHCP alors que la machine attend du RA ou bien le contraire. Bref, on n'aurait pas d'interopérabilité, ce qui est le but premier des normes Internet. Lorsque l'environnement est très fermé (un seul fournisseur, machines toutes choisies par l'administrateur réseaux), ce n'est pas un gros problème. Mais dans un environnement ouvert, par exemple un campus universitaire ou un hotspot Wifi, que faire ? Comme l'indiquent les sections 5.9.2 et 5.9.5, seul RA est obligatoire, DHCP ne l'est pas. RA est donc toujours la méthode recommandée si on doit n'en choisir qu'une, c'est la seule qui garantit l'interopérabilité. (Voir aussi la section 7.2 sur DHCP.)

Continuons à grimper vers les couches hautes. La section 7 est consacrée aux questions DNS. Une machine IPv6 devrait pouvoir suivre le RFC 3596 et donc avoir la possibilité de gérer des enregistrements DNS de type AAAA (les adresses IPv6) et la résolution d'adresses en noms grâce à des enregistrements PTR dans ip6.arpa. Les anciens enregistrements A6 (RFC 3363) ont été abandonnés mais on constate que ces enregistrements sont toujours très demandés lors des requêtes à des serveurs DNS faisant autorité, comme ceux de .fr (dans les 0,5 % des requêtes, soit davantage que SRV ou DS).

À noter qu'une machine IPv6, aujourd'hui, a de fortes chances de se retrouver dans un environnement où il y aura une majorité du trafic en IPv4 (c'est certainement le cas si cet environnement est l'Internet). La section 8 rappelle donc qu'une machine IPv6 peut avoir intérêt à avoir également IPv4 et à déployer des techniques de transition comme la double-pile du RFC 4213.

Encore juste une étape et nous en sommes à la couche 7, à laquelle la section 9 est consacrée. Si elle parle de certains détails de présentation des adresses (RFC 5952), elle est surtout consacrée à la question des API. En 2011, on peut dire que la grande majorité des machines a IPv6, côté couche 3 (ce qui ne veut pas dire que c'est activé, ni que le réseau le route). Mais les applications sont souvent en retard et beaucoup ne peuvent tout simplement pas communiquer avec une autre machine en IPv6. L'IETF ne normalise pas traditionnellement les API donc il n'y a pas d'API recommandée ou officielle dans ce RFC, juste de l'insistance sur le fait qu'il faut fournir une API IPv6 aux applications, si on veut qu'elles utilisent cette version d'IP, et qu'il en existe déjà, dans les RFC 3493 (fonctions de base) et RFC 3542 (fonctions avancées).

La sécurité d'IPv6 a fait bouger beaucoup d'électrons, longtemps avant que le protocole ne soit suffisamment déployé pour qu'on puisse avoir des retours d'expérience. Certains ont survendu IPv6 en prétendant que, contrairement à IPv4, il avait la sécurité intégrée dès le début et était donc plus sûr. Cette légende vient du fait qu'en théorie, IPsec était obligatoire pour toute mise en œuvre d'IPv6. Ce point n'a jamais été respecté par les implémentations (et puis, de toute façon, avoir IPsec est une chose, l'activer, avec sa complexe configuration, en est une autre). Désormais, depuis la sortie de notre RFC 6434, ce point n'est même plus vrai en théorie, IPsec (RFC 4301) est officiellement simplement recommandé.

Le RFC note donc bien que la sécurité est un processus complexe, qui ne dépend certainement pas que d'une technique magique (« IPsec est intégré donc il n'y a pas de problème de sécurité ») et qu'aucun clair gagnant n'émerge de la liste des solutions de sécurité (IPsec, TLS, SSH, etc). D'autant plus qu'IPv6 vise à être déployé dans des contextes comme « l'Internet des Trucs » où beaucoup de machines n'auront pas forcément les ressources nécessaires pour faire de l'IPsec.

Toutes les règles et recommandations précédentes étaient pour tous les nœuds IPv6. La section 12 expose les règles spécifiques aux routeurs. Ils doivent être capables d'envoyer les Router Advertisment et de répondre aux Router Solicitation du RFC 4861 et on suggère aux routeurs SOHO d'envisager sérieusement d'inclure un serveur DHCP (RFC 6204) et aux routeurs de réseaux locaux de permettre le relayage des requêtes DHCP.

Enfin, la section 13 se penche sur la gestion des réseaux IPv6 en notant que deux MIB sont obligatoires, celle du RFC 4292 sur la table de routage, et celle du RFC 4293 sur IP en général.

Les changements par rapport au RFC 4294 sont résumés dans l'annexe 16. Les deux plus importants, comme déjà noté, sont IPsec et DHCP, un qui descend, l'autre qui monte. Mais on y trouve aussi l'arrivée de SEND (mais en option), celle des options DNS du RFC 6106, et beaucoup de détails et de clarifications.


Téléchargez le RFC 6434


L'article seul

RFC 6430: Email Feedback Report Type Value : not-spam

Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : K. Li (Huawei), B. Leiba (Huawei)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 11 Novembre 2011


Il existe un format standard pour la transmission de rapports d'abus entre acteurs de l'Internet qui permet, par exemple, à des opérateurs de serveurs de messagerie de signaler un spam, et de traiter automatiquement ces rapports. Ce format se nomme ARF et est normalisé dans le RFC 5965. Chaque rapport ARF indique un type d'abus et ce nouveau RFC 6430 ajoute le type not spam, qui permet d'attirer l'attention sur un message classé à tort.

Le format ARF est conçu pour de gros opérateurs, traitant des millions de messages et d'innombrables rapports d'abus (spam mais aussi hameçonnage, distribution de logiciel malveillant, etc). Avec de tels volumes à traiter, l'automatisation est nécessaire et c'est ce que permet ARF. Le type abuse, documenté en section 7.3 du RFC 5965, permet de signaler un message comme n'étant pas désiré. Mais on a parfois besoin de l'inverse, signaler qu'un message n'est pas du spam, pour que le destinataire du rapport ajuste ses filtres. C'est ce qu'introduit notre RFC, suite à une demande de l'OMAMobile Spam Reporting Requirements », OMA-RD-SpamRep-V1_0 20101123-C).

Bien sûr, le destinataire du rapport est libre de l'action à entreprendre. Il peut par exemple attendre d'avoir plusieurs rapports équivalents, Si l'opérateur accepte des rapports envoyés directement par les utilisateurs (ceux-ci ne vont pas taper du ARF à la main mais ils peuvent avoir un MUA muni d'un bouton Report as non-spam qui le fait pour eux), il doit tenir compte du fait que les utilisateurs peuvent se tromper (cliquer trop vite) ou même tenter d'influencer le système (mais non, cette publicité n'est pas du spam, laissez-la passer...). La section 4 rappelle donc de traiter avec prudence ces rapports.

Les détails de syntaxe figurent en section 3 du RFC. Voici un exemple de rapport avec le Feedback-Type: à not-spam. abusedesk@example.com signale à abuse@example.net que le message de someone@example.net n'est pas, en dépit des apparences, du spam (mettons qu'il ait été envoyé en réponse à une sollicitation d'un médecin) :


From: <abusedesk@example.com>
Date: Thu, 8 Mar 2005 17:40:36 EDT
Subject: FW: Discount on pharmaceuticals
To: <abuse@example.net>
Message-ID: <20030712040037.46341.5F8J@example.com>
MIME-Version: 1.0
Content-Type: multipart/report; report-type=feedback-report;
     boundary="part1_13d.2e68ed54_boundary"

--part1_13d.2e68ed54_boundary
Content-Type: text/plain; charset="US-ASCII"
Content-Transfer-Encoding: 7bit

This is an email abuse report for an email message received
from IP 192.0.2.1 on Thu, 8 Mar 2005 14:00:00 EDT.
For more information about this format please see
http://tools.ietf.org/html/rfc5965
Comment: I sell pharmaceuticals, so this is not spam for me.

--part1_13d.2e68ed54_boundary
Content-Type: message/feedback-report

Feedback-Type: not-spam
User-Agent: SomeGenerator/1.0
Version: 1

--part1_13d.2e68ed54_boundary
Content-Type: message/rfc822
Content-Disposition: inline

Received: from mailserver.example.net
     (mailserver.example.net [192.0.2.1])
     by example.com with ESMTP id M63d4137594e46;
     Thu, 08 Mar 2005 14:00:00 -0400
From: <someone@example.net>
To: <Undisclosed Recipients>
Subject: Discount on pharmaceuticals
MIME-Version: 1.0
Content-type: text/plain
Message-ID: 8787KJKJ3K4J3K4J3K4J3.mail@example.net
Date: Thu, 02 Sep 2004 12:31:03 -0500

Hi, Joe.  I got a lead on a source for discounts on
pharmaceuticals, and I thought you might be interested.
[...etc...]
--part1_13d.2e68ed54_boundary--

Le type not-spam fait donc désormais partie du registre des types de rapport ARF.


Téléchargez le RFC 6430


L'article seul

RFC 6419: Current Practices for Multiple Interface Hosts

Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : M. Wasserman (Painless Security, LLC), P. Seite (France Telecom - Orange)
Pour information
Réalisé dans le cadre du groupe de travail IETF mif
Première rédaction de cet article le 22 Novembre 2011


Il fut une époque où la machine terminale connectée à l'Internet n'avait typiquement qu'une seule interface réseau. Seuls les routeurs avaient plusieurs interfaces et donc des décisions difficiles à prendre comme « quelle adresse source choisir pour le paquet que je génère ? » Aujourd'hui, les machines les plus ordinaires ont souvent, à leur tour, plusieurs interfaces réseau. Mon smartphone a une interface WiFi et une 3G. Mon ordinateur portable a une interface filaire, une 3G, une Wifi et une Bluetooth. Qui dit plusieurs interfaces dit décisions à prendre. Quel serveur DNS utiliser ? Celui appris via l'interface filaire ou bien celui appris en Wifi ? Par quelle interface envoyer un paquet qui sort de la machine ? La question est d'autant plus difficile que les différentes interfaces fournissent en général des services très différents, en terme de qualité et de prix. Le groupe de travail MIF de l'IETF travaille à normaliser le comportement des machines sur ce point. Son premier RFC (un autre, le RFC 6418, concerne l'exposé du problème) commence par examiner l'état de l'art : que font aujourd'hui les divers systèmes d'exploitation confrontés à cette question ?

Le RFC ne prétend pas couvrir tous les systèmes. Il se contente de ceux que les membres du groupe de travail connaissaient, ceux sur lesquels ils avaient de la documentation et des informations : Nokia S60, Windows Mobile, Blackberry, Android, Windows, et des systèmes à base de Linux.

Comment ces systèmes gèrent cette multiplicité des interfaces réseaux, se demande la section 2. Une première approche est de centraliser la gestion des connexions : ce n'est pas l'application qui choisit l'interface à utiliser, elle passe par un gestionnaire de connexions (en lui transmettant parfois quelques souhaits) qui choisit pour elle. Le gestionnaire peut choisir en fonction de la table de routages (si l'application veut écrire à 172.23.1.35 et qu'une seule interface a une route vers cette adresse, le choix est vite fait) mais elle ne suffit pas toujours (que faire si deux interfaces sont connectées à un réseau privé 172.23.0.0/16 ?). Le gestionnaire doit aussi tenir compte d'autres facteurs. Le coût est souvent le plus important (prix élevés de la 3G, surtout en itinérance, par rapport au Wifi ou au filaire, par exemple).

Une autre solution est que l'application choisisse elle-même, en fonction des informations qu'elle reçoit du système. Certaines applications ont des idées bien précises sur la connexion qu'elles veulent utiliser. Par exemple, sur Android, la plupart des clients SIP refusent par défaut d'utiliser les connexions 3G, les opérateurs y interdisant en général le trafix voix (en violation de la neutralité du réseau). Les deux méthodes (gestionnaire de connexions centralisé et choix par l'application) ne sont pas complètement exclusives. Comme indiqué, on peut aussi avoir un gestionnaire centralisé, mais qui permet aux applications d'indiquer des préférences (« essaie d'éviter la 3G »).

Certains choix sont par contre typiquement réglés par une troisième approche : le faire entièrement dans le système, sans demander à l'utilisateur ou aux applications (section 2.3). Le système rassemble des informations de sources diverses (DHCP, RA (Router Advertisment), configuration manuelle par l'administrateur système) et fait ensuite des choix qui sont globaux au système, ou bien spécifiques à chaque interface. Il n'y a aucune règle commune entre les différents systèmes d'exploitation sur ce plan, et aucun ne semble fournir une solution parfaite.

Par exemple, la configuration DNS voit certains systèmes permettre un jeu de résolveurs DNS différent par interface, avec des règles indiquant quel jeu est choisi. D'autres ont au contraire un seul jeu de résolveurs.

La sélection de l'adresse source est plus « standard ». L'application fournit l'adresse de destination et, lorsqu'elle n'a pas choisi une adresse source explicité (option -b de OpenSSH, par exemple), le système en sélectionne automatiquement une. Pour IPv6, il existe même une norme pour cela, le RFC 3484. Un grand nombre de systèmes d'exploitation ont adapté cette norme à IPv4 et l'utilisent donc pour toutes les familles d'adresses. En revanche, tous ne fournissent pas forcément un mécanisme permettant à l'administrateur système d'influencer cette sélection (le /etc/gai.conf sur Linux). Autre point où les systèmes diffèrent, certains choisissent l'interface de sortie avant l'adresse source, d'autres après.

La section 3 est ensuite l'exposé des pratiques des différents systèmes, à l'heure actuelle (une version future pourra changer leur comportement). Ainsi, le système S60 (qui tourne sur Symbian) introduit le concept d'IAP (Internet Access Point) ; un IAP rassemble toutes les informations sur une interface (physique ou virtuelle, dans le cas des tunnels). La machine a en général plusieurs IAP et l'application choisit une IAP au moment où elle a besoin du réseau. Ce choix est motivé par le fait que toutes les IAP ne fournissent pas forcément le service attendu par l'application. Par exemple, l'envoi d'un MMS nécessite l'usage d'un IAP qui donne accès à la passerelle MMS de l'opérateur, qui n'est en général pas joignable depuis l'Internet public. De même, une application qui accède aux serveurs privés d'une entreprise va choisir l'IAP qui correspond au VPN vers l'entreprise.

Ce concept d'IAP permet d'éviter bien des questions. Ainsi, le serveur DNS est indiqué dans l'IAP et, une fois celle-ci choisie, il n'y a pas à se demander quel serveur utiliser. (Reprenez l'exemple du VPN : cela garantira que l'application corporate utilisera un serveur DNS sûr et pas celui du hotspot où le téléphone est actuellement connecté.) De même, il existe une route par défaut par IAP et ce n'est donc pas un problème si deux interfaces de la même machine ont des plages d'adresses RFC 1918 qui se recouvrent (ou même si les deux interfaces ont la même adresse IP).

Comment l'application choisit-elle l'IAP ? Cela peut être fixé en dur dans le programme (cas de l'application MMS, en général), choisi par l'utilisateur au moment de la connexion, ou bien déterminé automatiquement par le système. La documentation de ce système figure en ligne.

Pour Windows Mobile et Windows Phone 7, tout dépend du Connection Manager. Celui-ci gère les connexions pour le compte des applications, en tenant compte de critères comme le coût ou comme la capacité du lien. Les applications peuvent l'influencer en demandant des caractéristiques particulières (par exemple une capacité minimale). Windows met en œuvre le RFC 3484 et l'administrateur système peut configurer des règles qui remplacent celles par défaut. Ce système est documenté en ligne.

Le Blackberry laisse les applications choisir la connexion qu'elles veulent, même s'il fournit un relais pour celles qui le désirent. Cela dépend toutefois de la configuration du réseau (l'utilisation obligatoire du Enterprise Server peut être choisie, par exemple). Les réglages comme le DNS sont par interface et non pas globaux au système. Plus de détails sont fournis dans la documentation.

Et Google Android ? Utilisant un noyau Linux, il partage certaines caractéristiques avec les autres systèmes Linux. Par défaut, il se comporte selon le modèle « machine terminale ouverte » (weak host model, cf. RFC 1122, section 3.3.4.2), mais peut aussi utiliser le modèle « machine strictement terminale » (strong host model). Dans le premier cas, les différentes interfaces réseaux ne sont pas strictement séparées, un paquet reçu sur une interface est accepté même si l'adresse IP de destination n'est pas celle de cette interface. Dans le second, la machine est stricte et refuse les paquets entrants si l'adresse IP de destination ne correspond pas à l'interface d'entrée du paquet.

La configuration DNS est globale (attention, Android ne la note pas dans /etc/resolv.conf, dont le contenu est ignoré). Cela veut dire que, dès qu'une réponse DHCP est reçue sur une interface, la configuration DNS de cette interface remplace la précédente.

Depuis Android 2.2, le RFC 3484 est géré. (Notez que, à l'heure actuelle, Android ne peut pas faire d'IPv6 sur l'interface 3G.)

La documentation figure dans le paquetage android.net. Les applications peuvent utiliser la classe ConnectivityManager si elles veulent influencer la sélection de l'interface. Pour cela, le système met à leur disposition la liste des interfaces et leurs caractéristiques. (Pour étudier un programme qui l'utilise, vous pouvez par exemple regarder les occurrences de ConnectivityManager dans le source Java de CSIPsimple.)

Le RFC se penche aussi sur un système moins connu, Arena, qui utilise également Linux et fournit un gestionnaire de connexions pour choisir les interfaces, avec indication des préférences par les applications. Il sera décrit dans un futur RFC.

Et sur les systèmes d'exploitation utilisés sur le bureau ? Windows est présenté mais sera décrit plus en détail dans un autre RFC. Les systèmes utilisant Linux (comme Ubuntu ou Fedora) partagent plusieurs caractéristiques :

  • Les informations comme l'adresse IP utilisée sont stockées par interface et sont obtenues par DHCP (ou RA).
  • Un certain nombre d'informations, notamment la route par défaut, les serveurs DNS ou les serveurs NTP sont globales au système. Bien que les clients DHCP utilisés, comme celui de l'ISC, permettent une configuration différente par interface, des paramètres comme la liste des résolveurs DNS, quelle que soit l'interface d'où ils viennent, effacent et remplacent globalement les paramètres précédemment obtenus.
  • La dernière interface configurée est donc forcément l'interface principale.

Les systèmes à base de BSD ont en gros les mêmes caractéristiques. Dans les deux cas, Linux ou BSD, certaines options permettent de passer outre les informations obtenues par DHCP. Par exemple, des option modifiers dans le client DHCP OpenBSD offrent la possibilité d'indiquer des valeurs à utiliser avant, ou bien à la place de, celles fournies par le serveur DHCP. Mëme chose pour des options comme -R du client DHCP Phystech (qui indique de ne pas modifier resolv.conf) ou comme nodns et nogateway dans les options de Pump, pour ignorer les résolveurs DNS et la route par défaut de certaines interfaces. D'autres systèmes disposent d'options similaires.

Enfin, même si le RFC ne le mentionne que très rapidement, il existe des systèmes de plus haut niveau (comme Network Manager, très pratique pour les machines qui se déplacent fréquemment) dont la tâche est d'orchestrer tout cela, de surveiller la disponibilité des interfaces, de lancer le client DHCP lorsque c'est nécessaire, d'accepter ou de passer outre ses choix, etc.

Voilà en gros la situation actuelle. Prochains efforts du groupe MIF : l'améliorer... Le RFC 6418 donne le cahier des charges de cet effort.


Téléchargez le RFC 6419


L'article seul

RFC 6417: How to Contribute Research Results to Internet Standardization

Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : P. Eardley (BT), L. Eggert (Nokia), M. Bagnulo (UC3M), R. Winter (NEC Europe)
Pour information
Première rédaction de cet article le 2 Novembre 2011


Nourri de la vaste expérience de ses auteurs (tous chercheurs et tous ayant écrit des RFC), ce document essaie de combler une partie du fossé entre la communauté des chercheurs et la normalisation, en encourageant ces chercheurs à participer à l'IETF, et en leur expliquant ce à quoi ils doivent s'attendre.

L'Internet est bien issu d'un projet de recherche, ARPANET, et a ensuite intégré un bon nombre de résultats de recherche. Normalement, le monde académique devrait se sentir à l'aise dans celui de la normalisation Internet. Mais ce n'est pas toujours le cas. Le chercheur isolé peut même trouver que l'IETF est une organisation mystérieuse et que le processus de normalisation y est très frustrant. C'est pour guider ces chercheurs que ce RFC leur explique ce nouveau (pour eux) monde.

Optimisme scientiste ou simplement désir de plaire aux lecteurs issus de la recherche ? En tout cas, le RFC commence par prétendre que le développement de nouvelles techniques est dû à la recherche scientifique. Après ce remontage de moral, la section 1 explique pourtant aux chercheurs candidats à un travail de normalisation à l'IETF qu'ils ne doivent pas s'attendre à un chemin de roses. Une SDO a d'autres motivations qu'une université. Dans la recherche, le plus important est qu'une solution soit correcte. Dans la normalisation, les problèmes à résoudre sont ceux du monde réel et le caractère pratique et réaliste de la solution a autant, voire plus d'importance, que sa parfaite correction.

Ainsi, l'IETF adopte souvent des solutions dont les limites, voire les défauts, sont connus, simplement parce que des alternatives « meilleures » ne semblent pas déployable sur le terrain. De même, une bonne solution à un problème intéressant peut être écartée, si ce problème ne se pose tout simplement pas dans l'Internet. Enfin, la normalisation progresse souvent par étapes incrémentales, nécessaires pour un déploiement effectif, et cela peut être jugé peu apétissant par des chercheurs qui veulent s'attaquer aux Grands Problèmes.

On voit ainsi régulièrement des malentendus, où des chercheurs arrivent à l'IETF avec des idées trop éloignées du domaine de l'IETF, ou bien trop générales pour qu'un travail concret (l'IETF normalise des bits qui passent sur le câble...) puisse commencer, des idées qui ne peuvent pas être déployées dans l'Internet d'aujourd'hui, ou encore des idées qui résolvent des problèmes qui ne sont pas, ou pas encore, d'actualité. Sans compter des problèmes moins techniques comme l'hésitation à passer leur bébé à l'IETF (perdant ainsi le contrôle de son évolution), la constatation que la normalisation est très chronophage, ou simplement l'impression qu'on ne les écoute pas réellement.

Cela ne veut pas dire que les chercheurs ne doivent même pas essayer. Bien au contraire, ce RFC doit leur permettre de mieux déterminer si et comment ils peuvent présenter leur travail à l'IETF. Il vient en complément de documents plus généraux sur l'IETF, notamment le fameux Tao (RFC 4677)).

Donc, première question à se poser (en section 2) : est-ce que l'IETF est le bon endroit pour ce travail ? Le RFC suggère deux questions simples aux candidats. Si votre travail était pris en compte :

  • Est-ce que l'Internet serait meilleur ?
  • Quelles machines devraient être mise à jour ?

La première question est une variante du classique « Quel problème essayez-vous de résoudre ? » Après tout, il y a déjà eu des tas de travaux (dont certains normalisés à l'IETF) qui n'ont jamais été déployés. Il est donc raisonnable de se demander si ce travail apportera un bénéfice. Un travail de recherche, même remarquable, n'est pas forcément dans ce cas.

La seconde question, sur les machines à mettre à jour en cas d'adoption de la technique, a pour but de pointer du doigt les problèmes de déploiement. Les chercheurs ont facilement tendance à les ignorer, préférant partir d'une table rase. Dans l'Internet d'aujourd'hui, utilisé par des milliards de personnes et pour qui des investissements colossaux ont été faits, cette approche n'est pas réaliste. Il est donc crucial de se demander « Est-ce que cette nouvelle technique pourra être déployée, et à quel coût ? » Par exemple, est-ce que la nouvelle technique nécessitera de mettre à jour seulement les routeurs, seulement les machines terminales, ou les deux ? Cette analyse est d'autant plus complexe qu'il faudra prendre en compte, non seulement les protocoles, mais également les pratiques opérationnelles et peut-être même certains modèles de business, qui pourraient être remis en cause.

Une fois cette analyse faite, si la conclusion est que le travail semble à sa place à l'IETF, comment convaincre celle-ci de s'y mettre (section 3) ? Il faut trouver le bon endroit dans l'IETF. Celle-ci n'est plus le petit groupe de travail du début, où tout le monde était impliqué dans tous les protocoles. C'est désormais un gros machin, avec des dizaines de groupes de travail différents (eux-même regroupés en zones - areas) et il faut trouver le bon. S'il existe, il faut le rejoindre (l'IETF n'a pas d'adhésion explicite, rejoindre un groupe, c'est simplement s'abonner à sa liste de diffusion). Et s'il n'existe pas ?

Alors, il va falloir construire une communauté d'intérêts autour de la nouvelle proposition. Après tout, la normalisation, contrairement à la recherche, nécessite un accord large et il va donc falloir se lancer dans le travail de persuasion. Le RFC note que cet effort aura des bénéfices, notamment celui d'améliorer la proposition technique, grâce aux remarques et commentaire des participants à l'IETF. Cela oblige également à documenter le protocole d'une manière compréhensible pour les autres (on peut s'inspirer du RFC 4101). C'est à ce stade qu'on peut tenir des réunions informelles (les Bar BoF) pendant les réunions physiques de l'IETF.

Si on n'a pas trouvé de groupe de travail qui convenait, que faut-il faire ? « En créer un ! », vont crier beaucoup de gens. Bonne idée, mais il faut d'abord lire la section 3.4, qui explique les étapes préalables, celles citées dans le paragraphe précédent, et la tenue recommandée d'une BoF (cf. RFC 5434).

Une fois que tout ceci est fait, la situation semble idyllique. L'IETF a accepté de travailler sur la nouvelle technique, un groupe de travail a été créé, il suffit d'attendre tranquillement son résultat ? Mais non. Comme le rappelle la section 4, il faut continuer à suivre le projet. Il faut prévoir pour cela des efforts importants, du temps et de la patience. Les gens qui n'ont jamais travaillé avec une SDO sont presque tous étonnés de la longueur et de la lourdeur du processus. Tout groupe de travail ne produit pas forcément de RFC et le succès va dépendre d'un travail continuel. Bien qu'en théorie, tout puisse se faire à distance, le RFC rappelle qu'une présence physique aux réunions va, en pratique, augmenter les chances de réussite (c'est comme pour les élections, il faut serrer des mains).

Pire, on a parfois l'impression que le processus s'enlise. L'IETF n'a pas de votes et encore moins de chefs qui décideraient tout. Un consensus relatif est nécessaire pour à peu près tout, et l'IETF n'est pas connue pour sa capacité à prendre des décisions... Bref, notre RFC prévient les candidats : deux ans au moins, depuis la création du groupe de travail. Si le projet de recherche qui a donné naissance à la nouvelle technique dure trois ans, cela veut dire qu'il faut commencer le travail de lobbying à l'IETF dès la première semaine du projet, si on veut que la nouvelle technique soit normalisée avant la fin du projet ! Il vaut donc mieux se préparer d'avance à ce que le projet ne soit pas complété par l'auteur lui-même, et soit terminé par d'autres.

Et c'est si tout se passe bien. Mais il y a parfois des chocs de cultures qui ralentissent le projet. Par exemple, le monde de la recherche privilégié la paternité (« l'algorithme X, décrit par Dupont et Durand dans leur article de 2008 ») alors que l'IETF privilégie le travail collectif. Une norme n'appartient pas à son auteur mais à toute la communauté. Il est donc préférable d'avoir une mentalité très ouverte avant de commencer.

Autre point sur lequel le choc des cultures est fréquent : la mise en œuvre de l'idée dans du vrai logiciel qui tourne. L'IETF accorde une grande importance à ce logiciel (le running code), qui montre que l'idée est viable, et que quelqu'un y a cru suffisamment pour dédier une partie de son précieux temps à sa programmation. C'est encore mieux si le programme connait un début de déploiement (le RFC suggère, pour un protocole réseau, d'essayer de le faire adopter dans le noyau Linux, par exemple). Si ces règles semblent contraignantes, il faut se rappeler qu'elles sont dues à de nombreuses expériences douloureuses, de protocoles déployés uniquement sur le papier, et qui avaient donc fait perdre du temps à tout le monde.

Pour rendre ces conseils plus concrets, le RFC contient une section d'exemples, la 5. On y trouve des résumés de l'incorporation dans le processus IETF de deux protocoles issus de la recherche « académique » :

  • Multipath TCP, issu du projet Trilogy, présenté à l'IETF pour la première fois en 2008, a donné naissance à un groupe de travail, MPTCP en 2009, dont les RFC ont été publiés en 2011.
  • Autre enfant de Trilogy, Congestion exposure a été présenté en 2009, mais le groupe de travail CONEX n'a été créé qu'en 2010, et avec une charte aux ambitions réduites.

Téléchargez le RFC 6417


L'article seul

RFC 6415: Web Host Metadata

Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : E. Hammer-Lahav, B. Cook
Chemin des normes
Première rédaction de cet article le 1 Novembre 2011


Ce court RFC spécifie une convention qui permet à un client Web de récupérer sur un serveur une description formelle de méta-données sur le site servi (par exemple l'auteur du site Web, ou bien la licence du contenu servi). Cela se fait en mettant ces méta-données au format XRD dans une ressource nommée /.well-known/host-meta.

Vous pouvez voir le résultat dans le /.well-known/host-meta de mon site, très inspiré de l'exemple de la section 1.1 du RFC. Il est vraiment minimal et n'inclut que des méta-données globales (le format XRD permet également de s'en servir pour des méta-données locales à une ressource, cf. section 4.2).

Notez que le vocabulaire peut être trompeur. Le RFC 3986 parle de host pour le example.com de http://example.com/truc/machin mais ce terme ne désigne pas du tout une machine. Finalement, le terme marketing flou de « site » est encore le moins mauvais.

Ce nouveau nom de host-meta a donc été le premier à être enregistré (cf. section 6.1) dans le registre des ressources bien connues qui avait été créé par le RFC 5785. (Deux ou trois autres sont venus juste après.)

Pour le client, par exemple un navigateur Web, récupérer les méta-données consiste juste donc à faire une requête GET sur le nom /.well-known/host-meta (section 2). Il obtient en échange un fichier XML au format XRD, servi avec le type application/xrd+xml.

Le contenu du document est détaillé dans la section 3. Ce vocabulaire XRD a été normalisé par OASIS et sert à beaucoup de choses très compliquées. Mais l'accent est mis ici sur son utilisation pour fournir des méta-données. Tout en gardant le modèle de données de XRD, le serveur peut envoyer du XML (la syntaxe habituelle) ou du JSON. Cette dernière syntaxe est normalisée dans l'annexe A, sous le nom de JRD. On peut l'obtenir (n'essayez pas sur mon site, il n'est pas configuré pour cela) en utilisant la négociation de contenu HTTP (champ Accept: application/json dans la requête) ou en demandant /.well-known/host-meta.json au lieu de simplement /.well-known/host-meta.

Qui utilise ou va utiliser ces méta-données ? Pour l'instant, les moteurs de recherche ne semblent pas y accéder mais cela viendra peut-être bientôt (Yahoo et Google ont annoncé travailler sur le sujet). La communauté WebFinger est également très impliquée dans ce projet.

Sinon, ce choix d'utiliser une ressource avec un nom spécial (le préfixe /.well-known a été normalisé dans le RFC 5785) est dû au fait qu'un serveur n'a pas d'URI qui le désigne globalement et on ne peut donc pas utiliser les techniques qui attachent les méta-données à une ressource (par exemple les en-têtes HTTP comme l'en-tête Link: du RFC 5988), sauf à utiliser des trucs contestables comme de considérer que /, la racine du site, désigne tout le site.


Téléchargez le RFC 6415


L'article seul

RFC 6410: Reducing the Standards Track to Two Maturity Levels

Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : R. Housley (Vigil Security), D. Crocker (Brandenburg InternetWorking), E. Burger (Georgetown University)
Première rédaction de cet article le 12 Octobre 2011


Ce très court RFC met fin (provisoirement ?) à un très long et très agité débat au sein de l'IETF. Après de longs efforts, il réussit à réformer une vache sacrée du processus de normalisation des protocoles TCP/IP. Les RFC spécifiant ces protocoles avaient trois étapes sur le chemin des normes. Il n'y en a désormais plus que deux.

D'innombrables documents, cours et articles ont expliqué le cheminement d'un RFC sur le chemin des normes, tel que le décrit le RFC 2026. Un premier point essentiel du RFC 2026 est que tous les RFC ne sont pas sur le chemin des normes. Ils peuvent être simplement « expérimentaux » ou bien « pour information ». Un deuxième point essentiel était que le chemin des normes comprenait trois étapes, chacune marquant une progression vers le statut de norme complète et achevée. L'étape atteinte par chaque RFC (pas encore adaptée à ce nouveau RFC) est visible en http://www.rfc-editor.org/category.html.

Ce schéma était simple et bien décrit. Mais il a été peu appliqué en pratique. D'abord, même parmi les participants à l'IETF, peu ont vraiment compris les subtiles nuances entre les trois étapes. A fortiori, à l'extérieur, peu de gens prenaient leurs décisions techniques en fonction des niveaux atteints sur le chemin des normes ! (Je me souviens de réunions d'un groupe de travail anti-spam où la lobbyiste d'AOL pouvait ergoter sans fin sur les niveaux de maturité de normes comme SMTP, uniquement pour donner un habillage pseudo-juridique aux décisions déjà prises par AOL.) Enfin, on constate qu'avancer sur ce chemin était trop pénible. Certaines normes l'ont fait, car elles étaient poussées par un acteur décidé qui avait intérêt à un statut le plus élevé possible mais, dans d'autres cas, personne ne s'en est occupé et des tas de normes très stables et très déployées sont restées à une étape intermédiaire. C'est ainsi que EPP, bien que récent, a atteint l'étape suprême avec le RFC 5730, simplement parce que VeriSign a poussé très fort, alors que HTTP (RFC 2616) est coincé en étape Projet-de-norme, parce que personne n'a le courage de lobbyer pour qu'il avance. Même chose pour SMTP (RFC 5321) qui, comme HTTP, est indubitablement largement déployé et avec succès ! Bref, l'état actuel de ses RFC sur le chemin des normes ne reflète que très peu la qualité, la stabilité, la popularité et la maturité d'un protocole.

L'IETF a donc, non sans douleur, réfléchi depuis plusieurs années à une simplification du processus, en réduisant le nombre d'étapes à deux. Il y a eu de nombreuses discussions à ce sujet, certains voulant en profiter pour faire une refonte complète du système de normalisation à cette occasion. C'est finalement un choix plus conservateur qui a été fait : le changement reste limité. C'est déjà bien qu'il ait lieu, certains commençaient même à être sceptiques quant aux capacités de l'IETF à réformer ses processus.

Le RFC 2026 réclamait, pour bouger de la première étape (proposition de norme), un rapport explicite sur l'interopérabilité des mises en œuvre de la norme. Et pour atteindre la troisième (norme tout court), un déploiement massif était nécessaire. Ces deux critères sont désormais fusionnés en un seul, qui permettra le passage de la nouvelle première étape, à la nouvelle deuxième (et dernière) étape. Il faudrait plutôt dire la seconde étape, d'ailleurs, si on suit les règles du français soutenu, où « deuxième » implique qu'il y a d'autres étapes ensuite.

Les règles précises figurent en section 2. Il n'y a désormais que deux niveaux sur l'échelle :

  • Proposition de norme (proposed standard). Il ne change pas de nom par rapport au premier niveau de l'ancien RFC 2026 car sa définition est exactement la même. Les critères pour atteindre ce niveau n'ont pas changé.
  • Norme Internet (Internet standard). C'est la fusion des deux anciens niveaux Projet de norme (Draft standard, on notera que ce nom mal choisi avait entraîné de nombreuses confusions avec les Internet-Drafts) et Norme tout court (Standard ou Full standard).

Lors de son passage de la première à la seconde étape, une norme peut être révisée de façon mineure (c'est bien l'un des buts de ce chemin des normes que de permettre l'amélioration des normes, à la lumière de l'expérience). Mais, si l'utilisation réelle montre des problèmes sérieux, qui nécessitent une révision plus fondamentale du protocole, il faudra repartir de la première étape.

Donc, désormais, pour avancer de la première à la seconde étape, il faudra :

  • Deux mises en œuvre indépendantes du protocole, qui interopèrent et sont effectivement déployées,
  • Pas d'errata enregistrés sur la norme, si les erreurs ainsi notées peuvent gêner l'interopérabilité,
  • Pas de fonctions inutilisées dans la norme, dans la mesure où cette mauvaise graisse accroît la complexité d'un protocole,
  • Si la technologie normalisée requiert l'usage de brevets (ce qui n'est pas interdit par les règles de l'IETF, cf. RFC 3979 et RFC 4879), alors il faut également démontrer qu'au moins deux implémenteurs ont réussi à obtenir une licence pour l'usage des parties brevetées (en pratique, indépendamment des coûts, l'obtention d'une licence est en effet souvent un cauchemar bureaucratique).

Et pour les RFC actuels, on fait quoi ? La section 2.3 traite de la transition et précise que les RFC à l'étape Norme-tout-court passent automatiquement à l'état Norme-Internet. Ceux à l'étape Proposition-de-norme y restent (rappelez-vous que cette étape n'a pas changé). Et ceux à l'étape (supprimée) Projet-de-norme y restent provisoirement, en attendant une reclassification par l'IESG (qui aura le droit, dans deux ans, de les passer tous, d'autorité, à l'état de Norme-Internet).

Ce RFC supprime également certaines obligations, bonnes sur le principe mais qui, en pratique, bloquaient certains RFC sur le chemin des normes, sans bonne raison (section 3). C'est ainsi qu'il n'est plus nécessaire :

  • De faire une revue annuelle des documents sur le chemin des normes pour voir s'ils peuvent avancer (cette revue n'a jamais eu lieu).
  • De publier un rapport d'interopérabilité formel pour montrer qu'il y a plusieurs implémentations qui peuvent agir ensemble. Dommage, c'était une institution sympathique et utile. De tels rapports restent possibles, quoique facultatifs, et le RFC 5657 contient plein d'informations concrètes à ce sujet.

Téléchargez le RFC 6410


L'article seul

RFC 6409: Message Submission for Mail

Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : R. Gellens (Qualcomm), J. Klensin
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF yam
Première rédaction de cet article le 16 Novembre 2011


Pendant longtemps, le système de courrier électronique de l'Internet ne faisait aucune différence entre le serveur de messagerie et le simple PC de l'utilisateur. Tous utilisaient le même protocole SMTP, spécifié dans le RFC 2821. Depuis le RFC 2476 et plus encore depuis le RFC 4409, précurseurs de notre RFC 6409, ce n'est plus vrai. Le simple PC doit désormais utiliser une autre solution, la soumission de message.

L'ancienne architecture était raisonnable à l'époque où toutes les machines connectées à l'Internet étaient de gros serveurs gérés par des professionnels. Ceux-ci pouvaient faire en sorte que tout soit correctement configuré. Et, donc les autres serveurs, les MTA pouvaient ériger en principe le "Pas touche" et ne jamais modifier ou contester un message reçu (section 1 du RFC ; en pratique, pas mal de MTA modifiaient quand même le contenu des messages, avec des conséquences négatives).

Aujourd'hui, avec le nombre de micro-ordinateurs non gérés qui sont connectés à Internet, cela n'est plus possible. Le RFC 2476 avait donc séparé les clients SMTP en deux catégories : les MTA qui se connectent au port traditionnel, le numéro 25 et les MUA qui, s'ils veulent envoyer en SMTP, doivent utiliser un autre service, nommé MSA, tournant en général sur le port 587 (section 3.1), et soumis à d'autres règles :

  • Le serveur est autorisé à modifier le message (par exemple en ajoutant des en-têtes comme Date ou Message-ID s'ils sont absents ou incorrects, sections 5, 6 et 8),
  • Une authentification est souvent requise, surtout si le port de soumission est accessible de tout l'Internet (sections 4.3 et 9).

Attention toutefois, la section 8 rappelle que les modifications du message soumis ne sont pas toujours inoffensives et qu'elles peuvent, par exemple, invalider les signatures existantes.

Notre RFC, qui remplace le RFC 4409, qui lui-même remplaçait le RFC 2476, pose en principe que, désormais, les machines des simples utilisateurs devraient désormais utiliser ce service.

La soumission de messages, telle que normalisée dans ce RFC est ses prédécesseurs, a été un grand succès depuis dix ans, notamment depuis trois ans. Le port 25 est de plus en plus souvent bloqué en sortie des FAI (pour limiter l'envoi de spam par les zombies), et la seule solution pour écrire sans passer par le serveur de son FAI est désormais le port 587. La norme technique est sortie il y a désormais treize ans et est particulièrement stable et mûre.

Si vous utilisez Postfix, vous pouvez lire un exemple de configuration de Postfix conforme (partiellement) à ce RFC.

Notre RFC a été développé par le groupe de travail YAM de l'IETF. Ce groupe est chargé de prendre toutes les normes IETF liées au courrier électronique et de les faire avancer sur le chemin des normes, si possible. La soumission de courrier est ainsi devenue « norme tout court » (Full Standard) avec ce RFC 6409. Les changements depuis le RFC 4409 sont décrits dans l'annexe A. Les principaux sont l'importance plus grande de l'internationalisation (section 6.5, qui précise que le MSA peut changer l'encodage), et une mise en garde plus nette contre les risques encourus en cas de modification de messages par le MSA.


Téléchargez le RFC 6409


L'article seul

RFC 6394: Use Cases and Requirements for DNS-based Authentication of Named Entities (DANE)

Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : R. Barnes (BBN Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF dane
Première rédaction de cet article le 28 Octobre 2011


Le projet DANE (DNS-based Authentication of Named Entities, anciennement KIDNS - Keys In DNS), vise à améliorer et/ou remplacer les certificats X.509 utilisés dans des protocoles comme TLS (RFC 5246). Ces certificats souffrent de plusieurs problèmes, le principal étant qu'une Autorité de Certification (AC) malhonnête ou piratée peut créer des certificats pour n'importe quelle entité, même si celle-ci n'est pas cliente de l'AC tricheuse. C'est ce qui s'est produit dans les affaires Comodo et DigiNotar et ces deux affaires ont sérieusement poussé aux progrès de DANE. Ce premier RFC du groupe de travail DANE établit les scénarios d'usage : quels problèmes veut résoudre DANE et selon quels principes ?

Revenons d'abord sur le fond du problème (section 1 du RFC) : lors de l'établissement d'une session TLS (par exemple en HTTPS), le client se connecte à un serveur dont il connait le nom (par exemple impots.gouv.fr, cf. RFC 6125), le serveur (et, plus rarement, le client) présente un certificat numérique à la norme X.509 (bien qu'un certificat PGP soit aussi possible, cf. RFC 6091). Ce certificat suit le profil PKIX, normalisé dans le RFC 5280, un sous-ensemble de X.509. Comme ce certificat peut avoir été présenté par un homme du milieu qui a intercepté la session (par exemple en jouant avec BGP ou OSPF), il faut l'authentifier, sinon TLS ne protégerait plus que contre les attaques passives, laissant ses utilisateurs à la merci des attaques actives. Cette authentification se fait typiquement aujourd'hui en vérifiant que le certificat a été signé par une des plusieurs centaines d'AC qui se trouvent dans le magasin de certificats de n'importe quel navigateur Web. Le point important, et qui est l'une des deux principales faiblesses de X.509 (l'autre étant son extrême complexité), est que n'importe laquelle de ces centaines d'AC peut signer un certificat. Ainsi, dans l'affaire DigiNotar, une AC néerlandaise était piratée, le pirate lui faisait générer des certificats pour *.google.com ou *.gmail.com (alors que Google n'est pas du tout client de DigiNotar) et ces certificats sont acceptés par tous les navigateurs. Le pirate a vendu ou donné les clés privées de ces certificats au gouvernement iranien, qui n'a plus eu qu'à monter une attaque de l'homme du milieu (facile lorsqu'on est un état policier et qu'on contrôle tous les FAI du pays) pour détourner les utilisateurs vers un faux Gmail, qui présentait un certificat acceptable. La dictature intégriste pouvait alors lire les messages et emprisonner ou tuer les opposants. (Le fait que l'attaque venait d'Iran est établi par les requêtes OCSP des victimes. Cf. le rapport sur l'opération Tulipe Noire.)

Identifiée depuis longtemps (mais niée par le lobby des AC ou par l'UIT, à l'origine de la norme X.509), cette vulnérabilité a mené au projet DANE. L'idée de base est qu'introduire un intermédiaire (l'AC) est en général une mauvaise idée pour la sécurité. Pour reprendre l'exemple ci-dessus, il vaudrait mieux permettre à Google de prouver sa propre identité. Comme quasiment toutes les transactions sur l'Internet commençent par une requête DNS, pourquoi ne pas utiliser la zone DNS google.com pour y mettre le certificat ? L'idée est ancienne, mais elle ne suscitait guère d'intérêt tant que le DNS lui-même n'était pas un tant soit peu sécurisé. Le déploiement rapide de DNSSEC, à partir de 2009, a changé la donne : mettre des clés cryptographiques ou des certificats dans le DNS devient réaliste. D'où la création, en février 2011, du groupe de travail DANE de l'IETF, chargé de trouver une technique de sécurité qui marche.

Ce RFC ne donne pas encore de solution (au moment de sa parution, celle-ci est très avancée et a des chances sérieuses d'être publiée en 2012). Il explique les scénarios d'usage, pour aider à évaluer la future solution. Pour décrire ces scénarios, on recourt évidemment aux personae traditionnels :

  • Alice gère le serveur alice.example.com,
  • Bob, le client, se connecte à ce serveur,
  • Charlie est l'AC,
  • Trent est un émetteur de certificats mais qui n'est pas dans les magasins de certificats d'AC typiques.

Trois scénarios sont ensuite décrits dans la section 3, le œur de ce RFC :

  • « Contrainte sur l'AC » (dit aussi « type 0 »),
  • « Contrainte sur les certificats » (« type 1 »),
  • « Certificats locaux » (« type 2 »),

Dans les deux premiers cas, DANE ne fait qu'ajouter de la sécurité à X.509 et on a toujours besoin de l'IGC actuelle. Le troisième est le plus novateur, permettant de remplacer complètement l'IGC, et ne gardant de X.509 que son format de certificats. (Notez que ces trois scénarios ne se retrouveront pas exactement dans le futur RFC sur le protocole qui, pour l'instant, en est à quatre types prévus et non pas trois.)

Voyons d'abord le premier scénario (section 3.1) , les contraintes sur l'AC. Dans un cas comme celui des piratages de Comodo ou de DigiNotar, Alice, qui est cliente d'une autre AC, Charlie, est inquiète du risque d'un faux certificat pour alice.example.com, émis par l'AC voyoute. Elle voudrait dire aux visiteurs de https://alice.example.com/ que les seuls certificats légitimes sont ceux émis par Charlie. En d'autres termes, elle voudrait que la vérification du certificat de son serveur parte du certificat de Charlie, pas de n'importe quel certificat d'AC du magasin.

Notez que, si Alice dispose d'un tel système, elle peut aussi s'en servir vis-à-vis de Charlie. Lorsqu'elle demande un certificat à ce dernier, il pourrait vérifier qu'Alice l'a bien listé comme AC.

Donc, Alice va mettre dans le DNS un enregistrement qui dit « je suis cliente de Charlie ». Cet enregistrement doit-il être sécurisé par DNSSEC ? La question est toujours très discutée au sein du groupe DANE. A priori, DNSSEC n'est pas impératif puisque cet enregistrement DNS n'est qu'une sécurité supplémentaire : le X.509 traditionnel fonctionne toujours en dessous. D'un autre côté, cette sécurité supplémentaire est très faible si on ne met pas DNSSEC : un attaquant qui peut monter une attaque de l'Homme du Milieu pour détourner vers son propre serveur peut probablement aussi supprimer les enregistrements DANE au passage. Notons aussi que le fait d'exiger la validation X.50 comme avant limite les possibilités d'attaque par un registre DNS. Avec le type 0 (contrainte sur l'AC), un attaquant devrait contrôler à la fois l'enregistrement DNS et l'Autorité de Cértification.

Second scénario, la contrainte sur le certificat (section 3.2), alias type 1. Alice est cliente de Charlie mais se demande si Charlie ne va pas émettre d'autres certificats pour alice.example.com, par exemple parce que les machines de Charlie ont été piratées. Elle voudrait donc indiquer aux visiteurs de https://alice.example.com/> que seul tel certificat est valable. Alice va donc mettre le certificat (ou un condensat cryptographique de celui-ci) dans le DNS. Comme avec le type 0, toute la validation classique de X.509 est ensuite appliquée. Dans ce mode, DANE ne fait qu'ajouter une vérification supplémentaire.

Bien plus « disruptive » est la possibilité de se passer complètement des AC et de dire dans le DNS « voici le certificat à utiliser », sans qu'il doit validé par d'autres mécanismes que DNSSEC. Cette possibilité (section 3.3), dite type 2, est l'équivalent des certificats auto-signés actuels, mais avec possibilité de les vérifier (grâce à DNSSEC). Alice se passe alors complètement de Charlie. (Notez que le cas où Alice est cliente de Trent est équivalent, le certificat de Trent n'étant quasiment dans aucun magasin. Alice va alors publier dans le DNS le certificat de Trent et non le sien.)

Notez que ce mécanisme n'empêche pas Bob d'avoir sa propre politique de validation. On pourrait imaginer un Bob suspicieux vis-à-vis de DNSSEC qui n'accepterait que les enregistrements DANE de type 0 ou 1. Ou un Bob qui aurait une liste noire des certificats à qui il ne fait pas confiance, DANE ou pas DANE.

Cette fois, avec le type 2, DNSSEC est absolument indispensable. Sans lui, il n'y a plus aucune validation du certificat. Ne publiez donc pas d'enregistrements de type 2 avant d'avoir vérifié que DNSSEC était correctement déployé et que vous le maîtrisez parfaitement. Pour la même raison, le type 2 est celui qui met le plus de responsabilités chez les opérateurs DNS. Si ceux-ci trahissent ou sont piratés, tout le système est en danger. Mais rappelez-vous que, contrairement à ce qui se passe pour X.509, le risque est uniquement dans les prestataires que vous choisissez. Si vous choisissez d'utiliser un nom de domaine en .org, vous savez qu'Afilias peut tout faire rater, mais que ni l'AFNIC, ni CNNIC n'ont ce pouvoir. Alors qu'avec X.509, même en choisissant soigneusement son AC, on peut être victime de n'importe quelle autre AC, qu'on n'a pas choisi. Donc, conseil pratique, choisissez bien vos prestataires (registre DNS, bureau d'enregistrement, hébergeur DNS, etc).

Mais il est clair que DANE donne plus de responsabilité (on peut même dire de pouvoir) aux acteurs du DNS. Ce point est souvent à la base de la plupart des critiques de DANE.

Autre point à garder en tête lorsqu'on évalue la sécurité de DANE : aujourd'hui, avec X.509, le contrôle de la zone DNS donne déjà souvent accès à des certificats (bien des AC ne font pas d'autres vérifications que l'envoi d'un courrier avec un cookie, ou la publication d'un certain enregistrement).

Voilà, vous connaissez l'essentiel sur DANE. la section 4 couvre toutefois d'autres points, moins centraux, sous forme d'une liste de souhaits pour le futur protocole :

  • Capacité à gérer des certificats différents pour une même machine, pour des services tournant sur des ports différents (par exemple un serveur HTTP et un serveur IMAP).
  • Pas de possibilité d'attaque par repli.
  • Possibilité de combiner plusieurs assertions (par exemple de type 1 et 2, la première servant pour les clients qui refusent de croire au type 2 et qui tiennent à faire une validation X.509 classique).
  • Le moins de dépendances possibles, à part bien sûr celle sur DNSSEC.
  • Le moins d'options possibles, pour faciliter l'analyse de sécurité (IPsec avait été beaucoup critiqué pour le trop grand nombre de choix qu'il offrait).

Le protocole qui mettra en œuvre ce cahier des charges n'est pas encore terminé. C'est en partie pour cela qu'il n'y a pas à proprement parler de mise en œuvre de DANE même si des expérimentations sont déjà faites.

Pour ceux qui souhaitent approfondir le sujet, j'ai fait un exposé sur la question (avec article détaillé) en novembre 2011 aux JRES à Toulouse.


Téléchargez le RFC 6394


L'article seul

RFC 6393: Moving RFC 4693 to Historic

Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : M. Yevstifeyev
Pour information
Première rédaction de cet article le 19 Septembre 2011


L'expérimentation des ION (IETF Operational Notes, une série de documents IETF plus légers que les RFC) ayant été abandonnée, ce RFC reclassifie officiellement le RFC 4693, qui créait les ION, comme n'ayant qu'un intérêt historique.

Ce nouveau RFC, de même que la décision d'abandon, ne s'étend guère sur les raisons de l'échec et ne tire pas de bilan.


Téléchargez le RFC 6393


L'article seul

RFC 6392: A Survey of In-network Storage Systems

Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : R. Alimi (Google), A. Rahman (InterDigital Communications), Y. Yang (Yale University)
Pour information
Réalisé dans le cadre du groupe de travail IETF decade
Première rédaction de cet article le 26 Octobre 2011


Cette intéressante étude des systèmes de stockage de données en ligne (le RFC n'utilise pas le terme de cloud, pourtant bien plus vendeur) fait le tour des principales solutions d'aujourd'hui. Son but est de préparer le travail ultérieur du groupe de travail IETF DECADE, dont le rôle est de normaliser une architecture pair à pair pour ce stockage en ligne. Ce RFC, le premier produit par DECADE, étudie l'offre existante, afin de voir dans quelle mesure elle est réutilisable pour DECADE.

Notons que tous les systèmes existants n'y sont pas : l'accent a été mis sur une sélection de systèmes typiques couvrant à peu près toutes les variantes possibles d'un tel service. C'est ainsi que, par exemple, Swift/OpenStack n'y figure pas. Par contre, le plus célèbre, le S3 d'Amazon est présent. Certains de ceux qui y figurent sont très expérimentaux, peu déployés, mais ont été ajoutés parce qu'ils illustrent un point important.

Il existe des tas de raisons pour stocker ses données dans le nuage. Cela peut être pour y accéder de partout, depuis n'importe quelle machine. Ou bien cela peut être pour rapprocher les données des utilisateurs. Si on distribue du contenu en pair à pair, il vaut mieux qu'il soit déjà dans le nuage, plus près des téléchargeurs, que sur une machine à la maison, connectée en ADSL, où le coût du dernier kilomètre à franchir est élevé.

La section 2 brosse un panorama historique du stockage en ligne. Par exemple, le goulet d'étranglement que représente le gros site Web, lorsqu'il a de très nombreux utilisateurs, a été partiellement levé avec l'introduction des CDN. Ceux-ci dupliquent le contenu statique des sites Web, et le rapprochent des utilisateurs, en plaçant des copies chez les principaux FAI. Mais les CDN ne sont pas accessibles à l'utilisateur normal. Si je voulais accélérer le temps de chargement des pages de http://www.bortzmeyer.org/, je ne pourrais certainement pas monter un CDN moi-même, un tel travail nécessite des moyens financiers et administratifs hors de ma portée.

Le pair à pair a ensuite fourni d'autres possibilités. Si on utilise les machines de tout le monde pour distribuer du contenu, pourquoi ne pas également s'en servir pour améliorer l'accès au contenu par une réplication et une copie proche des autres pairs ? Plusieurs systèmes de « caches P2P » ont ainsi été développés pour accélérer le pair à pair (cf. section 4.12). Malheureusement, tous sont spécifiques à une application particulière et ne peuvent donc pas servir aux nouvelles applications. Le monde du pair à pair évoluant vite, il ne peut donc pas bénéficier d'une infrastructure de stockage existante. Le but de DECADE est justement de permettre la création de cette infrastructure.

Pour pouvoir étudier de manière systématique les techniques existantes, la section 3 du RFC liste les composants d'une solution de stockage en ligne. Chaque technique sera alors décrite pour chacun de ces composants :

  • Une interface d'accès aux données, permettant les opérations de base, notamment lire et écrire,
  • Une interface de gestion des données, permettant des choses comme la suppression d'un bloc de données,
  • Une interface de recherche permettant de s'y retrouver dans ses données,
  • Un mécanisme de contrôle d'accès, permettant d'avoir des données publiques, des données restreintes à certains utilisateurs (par exemple seulement depuis certains pays), des données privées (accessibles uniquement à des clients identifiés, par exemple après paiement). L'accès peut dépendre de l'opération (lecture pour tous mais écriture seulement pour certains).
  • Un mécanisme de découverte des mécanismes d'accès (le mode d'emploi du service),
  • Un mode de stockage : les données sont-elles des fichiers (organisés en répertoires hiérarchiques), des objets (contrairement aux fichiers, ils ne sont pas organisés), ou simplement des blocs d'octets, comme le propose le disque dur local ?

Sur la base de ce découpage en composants, on peut décrire les systèmes existants (section 4, mais rappelez-vous que le RFC ne prétend pas les présenter tous et que je n'ai pas repris ici tous ceux listés dans le RFC). Notez que l'ordre de la présentation est celui du RFC, même s'il peut sembler incohérent. D'autre part, un bon nombre des descriptions ressemblent à du copier-coller depuis les descriptions officielles (y compris dans leur côté marketing).

Commençons par le plus connu, Amazon S3. Les utilisateurs créent des containers, les seaux (buckets) puis y déposent des objets. Les accès se font en REST.

Pour montrer les capacités de S3, testons un peu avec un client Unix en ligne de commande, s3cmd. On lui indique les clés avec s3cmd --configure puis on peut créer un seau (le nom est hiérarchique car un nom de seau doit être unique entre tous les utilisateurs ; on peut aussi préfixer avec l'ID Amazon) :

% s3cmd  mb s3://org-bortzmeyer-essais

(où mb signifie make bucket, créer un seau.) Puis on peut mettre un fichier dans ce seau :

% s3cmd  put tartiflette1.jpg s3://org-bortzmeyer-essais
/home/stephane/Downloads/tartiflette1.jpg -> s3://org-bortzmeyer-essais/tartiflette1.jpg  [1 of 1]
...
 35267 of 35267   100% in    0s    37.21 kB/s  done

Il est ensuite possible de récupérer cet objet, par exemple depuis une autre machine :

% s3cmd  get s3://org-bortzmeyer-essais/tartiflette1.jpg
...
s3://org-bortzmeyer-essais/tartiflette1.jpg -> ./tartiflette1.jpg  [1 of 1]
 35267 of 35267   100% in    0s    74.04 kB/s  done

On a donc vu les deux commandes les plus importantes, put et get (lire et écrire des objets).

S3 est devenu très populaire, entre autres en raison de sa simplicité. Pas d'espace de nommage hiérarchique, pas de possibilité de modifier les données existantes, accès en REST... L'interface d'accès permet de lire et d'écrire (les deux opérations illustrées plus haut), on peut détruire les objets, on peut lire le contenu d'un seau (c'est la seule possibilité de recherche), S3 fournit des mécanismes de contrôle d'accès riches, il n'y a pas de vraie découverte (l'utilisateur doit connaître l'URL où envoyer les requêtes, dans l'exemple ci-dessus, on utilise celle par défaut), et enfin, on l'a vu, S3 stocke des objets (aucun mécanisme de dossiers ou répertoires).

Il existe d'autres systèmes analogues à S3 comme Dropbox.

Un exemple d'un service très différent est le BranchCache de Windows, assez répandu en raison de la diffusion de ce système d'exploitation. Les accès ne sont pas explicites comme avec S3, BranchCache vise à stocker et récupérer les données automatiquement dans un cache. Il y arrive en se mettant sur le trajet des requêtes HTTP et SMB. Il intercepte la requête normale, et accède au fichier depuis le cache, si c'était une opération de lecture et que le fichier était déjà disponible.

Autre exemple très différent de S3, le CNF (Cache-and-Forward), une architecture de recherche visant à doter les réseaux d'un mécanisme efficace d'accès aux données. Dans CNF, les routeurs ne sont plus simplement des routeurs qui opèrent au niveau3 mais des moteurs d'accès des données (store and forward) qui font suivre les requêtes d'accès et gardent le résultat localement, pour les accès ultérieurs. Le contenu très populaire est ainsi petit à petit copié dans les routeurs les plus proches. Un mélange de Usenet et de cache opportuniste (tout le contenu n'est pas copié, contrairement à Usenet ou aux CDN, seulement celui qui est demandé).

Plus dans l'idée d'un accès explicite aux données, le standard CDMI vise à résoudre un problème récurrent du cloud : l'absence de normes pour l'accès aux données, qui font qu'une fois choisi un fournisseur, on en est prisonniers. Si vous bâtissez votre service autour d'un accès à S3, vous ne pouvez plus quitter Amazon. Certes, l'interface de S3 est tellement populaire qu'il existe désormais des offres compatibles (hébergées, ou bien à construire soi-même comme celle d'Eucalyptus) mais ces offres sont à la merci d'un changement unilatéral de l'interface S3 par Amazon. CDMI est donc une tentative pour concevoir et populariser, au sein d'un consortium industriel, la SNIA, une interface standard. Elle ressemble dans ses principes à S3 et repose sur les modes actuelles (REST et JSON).

Comme CDMI est indépendant d'un vendeur particulier, et repose sur des protocoles simples et bien connus comme HTTP, elle est une approche tentante pour le groupe DECADE.

J'ai déjà parlé des CDN. Ils représentent aujourd'hui une des approches les plus populaires, d'accès aux données en ligne. Un bon tour d'horison complet des CDN figure dans « A Taxonomy and Survey of Content Delivery Networks » de Pathan, A.K. et Buyya, R. Le principe est de copier à l'avance le contenu vers des serveurs situés chez les FAI et d'utiliser divers trucs (par exemple fondés sur le DNS) pour que les utilisateurs soient redirigés vers ces serveurs. Le plus connu des CDN est Akamai mais il en existe bien d'autres comme Limelight ou CloudFront. Pour DECADE, l'intérêt des CDN est que c'est une technique très répandue et éprouvée. Mais elle nécessite une relation d'affaires existante entre l'opérateur du CDN et le fournisseur de contenu (contrairement aux caches classiques).

Le CDN ne fournit typiquement d'accès qu'en lecture (l'écriture est réservée au fournisseur de contenu, via le mécanisme que lui offre l'opérateur du CDN).

Plus proche du CNF, le système DTN vise à créer un environnement adapté aux cas difficiles, notamment aux missions spatiales. Dans ces cas où la connectivité est très intermittente (une seule tempête solaire peut tout interrompre pendant des semaines), et où les délais sont énormes, les protocoles TCP/IP classiques ne conviennent plus. D'où le DTN, normalisé dans le RFC 4838, une architecture store and forward qui ressemble davantage à UUCP.

Le DTN repose sur le protocole Bundle (RFC 5050), qui permet de stocker les données en attendant que le destinataire soit à nouveau disponible. Bien sûr, IP est lui aussi store and forward dans la mesure où le routeur garde le paquet en mémoire avant de le passer au routeur suivant. Mais le temps de rétention des données dans IP est typiquement de quelques milli-secondes au maximum, alors qu'il atteint couramment plusieurs jours dans Bundle, imposant le recours à un stockage persistant (au cas où le routeur redémarre). Contrairement à IP, où le routeur a le droit de jeter des paquets, Bundle est plus proche du courrier électronique : le routeur doit prendre soin des données jusqu'à ce qu'il ait pu les transmettre. Il n'est donc pas exagéré de l'inclure dans cette liste des services de stockage en ligne.

Dans la catégorie futuriste, une autre famille de candidats intéressants est celle qu'on va appeler, pour simplifier. les « réseaux fondés sur les objets nommés » (c'est le nom de la première conférence scientifique sur le sujet). C'est une vaste famille, comprenant uniquement des projets de recherche fondamentale, qui ont en commun le fait que toute l'architecture du réseau repose sur des objets de données, ayant un nom, et que le réseau est conçu pour accéder rapidement et de manière sûre à ces objets. Cette famille privilégie donc l'accès au contenu. On y trouve des systèmes comme CCN, ou comme NDN (Named Data Networking) et NetInf (Network of Information), traités plus en détail dans ce RFC.

NDN est un tel système. Le réseau gère des objets nommés et signés cryptographiquement. Les routeurs qui transmettent ces objets ont la possibilité de les garder en cache. Les objets les plus demandés vont donc avoir plus de chance de se retrouver dans un cache proche, réalisant ainsi automatiquement ce que les CDN font manuellement. Comme les autres propositions de la famille Name-oriented networking, tout repose sur l'idée que « data delivery has become the primary use of the network ».

NetInf reprend les mêmes affirmations minitéliennes et y ajoute des fausses explications sur ce que représente un URL (le deuxième champ d'un URL, après le plan, n'identifie pas une machine).

Plus sérieux, OceanStore est une architecture où un ensemble de machines coopèrent en mettant en commun des espaces de stockage. OceanStore met l'accent sur la résilience et l'auto-organisation. Son intérêt pour DECADE est surtout cette capacité à résister aux pannes, et même à une certaine proportion de participants malhonnêtes (qui modifieraient les données, ou bien les effaceraient). OceanStore fournit une interface permettant lecture et écriture des objets mais reste encore très expérimental.

Un des domaines où il y a eu le plus d'utilisations du stockage en ligne est évidemment le partage de photos. Une section est donc consacrée à ce cas particulier, où on voit apparaître des noms connus comme Flickr ou ImageShack, sans compter des services qui, sans être spécialisés dans les photos, sont néanmoins largement utilisés pour cela, comme Tumblr. Une particularité de ces services est l'accent mis sur les fonctions de recherche (qui sont absentes de beaucoup de services de stockage), notamment par le biais d'étiquettes attachées aux photos. On peut ainsi retrouver, parmi des myriades de photos, celles qui concernaient saint-quentin-en-yvelines ou lascaux. Ces services ont en général également des moyens d'organisation des photos (en « albums » ou « galeries », analogues à ce que fournit un système de fichiers).

Ces services fournissent la plupart du temps des moyens de désigner les photos comme privées (personnelles) ou publiques et, dans certains cas, comme limitées à un ensemble de personnes. À noter que le RFC n'évoque pas un problème sérieux du stockage en ligne : le fait que rien n'est privé pour l'opérateur du service. On peut toujours marquer ses données comme privé, l'opérateur y a quand même accès (ainsi que la police et la justice de son pays).

Le RFC n'hésite pas à mélanger technologies très nouvelles (et souvent très expérimentales) et très anciennes. Usenet a ainsi sa section. C'est un système de distribution de messages, rangés hiérarchiquement par sujet (cf. RFC 5537). Ces messages sont automatiquement recopiés entre tous les serveurs Usenet qui participent à ce réseau. L'utilisateur final peut alors y accéder via un protocole comme NNTP. Usenet était donc du P2P longtemps avant que ce terme ne soit à la mode. Si Usenet semble nettement sur le déclin aujourd'hui, il reste un des plus importants exemples de distribution efficace de contenu sur le réseau.

En tant que système de stockage en ligne, Usenet permet de lire et d'écrire (on dit to post), et, dans une mesure très limitée, de détruire des messages (avec l'opération cancel).

S'il y a les caches pair à pair, un autre type de cache largement déployé est le cache Web, qui fait l'objet d'une analyse dans ce RFC. L'idée est surtout d'économiser de la capacité réseau (et de gagner en latence), et le cache Web est donc en général mis en œuvre par le FAI ou par les administrateurs du réseau local. Le protocole HTTP dispose de tout un tas d'options pour contrôler finement le niveau de « cachage ». Le logiciel libre le plus répandu pour cette tâche est Squid.

Ce service ne donne accès aux utilisateurs qu'en lecture, l'écriture est faite automatiquement, comme conséquence de la lecture.

Après ce long catalogue de systèmes très variés, la section 4.15 fait le point : est-ce que DECADE a trouvé ce qu'il cherchait ? La plupart de ces services sont nettement plus client-serveur que pair à pair. Et beaucoup sont spécifiques au « cachage », pas au stockage à long terme (un cache peut toujours perdre des données, par exemple, elles seront récupérées sur le site originel). Pour ces raisons et pour d'autres, il est probable que DECADE devra développer son propre service.

Après l'examen des services, la seection 5 du RFC porte sur un examen des protocoles. Quels protocoles existants pourraient être utiles pour DECADE ? Le premier examiné est bien sûr HTTP (RFC 2616). S'il est surtout connu pour ses fonctions de lecture (téléchargement de ressources Web), HTTP peut servir à bien d'autres choses, à développer des applications REST ou à écrire du contenu nouveau sur le serveur. Un des gros avantages de HTTP est évidemment que les logiciels clients sont déjà disponibles, du navigateur Web au programme en ligne de commande comme cURL, en passant par des bibliothèques pour tous les langages de programmation.

HTTP permet donc les fonctions d'accès aux données (opérations GET, PUT, etc), de gestion des données (le RFC fait une erreur en disant qu'il n'y en a pas, ce qui oublie DELETE, section 9.7 du RFC 2616) et de contrôle d'accès (accès public, ou accès restreint après authentification). Les données sont nommées « ressources » et sont souvent des fichiers. HTTP étant client-serveur, il ne convient pas parfaitement à DECADE, qui met plutôt l'accent sur le pair à pair.

HTTP a servi de base à d'autres protocoles. Pour l'accès aux données en ligne, on pense évidemment à WebDAV (RFC 4918). C'est une extension de HTTP qui lui ajoute des fonctions comme le verrouillage ou comme le regroupement des ressources en collections, qu'on peut gérer collectivement. Ces collections font que le modèle de données de WebDAV devient très proche de celui d'un modèle « système de fichiers ».

WebDAV a également une extension pour avoir des ACL, le RFC 3744. Par contre, il n'est pas évident que ce mécanisme de gestion des droits passe à l'échelle, dans le contexte de l'Internet entier.

Autre protocole d'accès à du stockage en ligne, iSCSI, normalisé dans le RFC 3720. En gros, il s'agit d'un protocole permettant l'envoi de commandes SCSI au dessus de TCP, vers des périphériques de stockage comme des disques durs. iSCSI est typiquement un outil pour réaliser des SAN, bien qu'il puisse aussi servir au dessus de l'Internet (par exemple avec les services de nommage du RFC 4171).

iSCSI fournit des opérations de lecture et d'écriture sur des blocs de données (qui correspondent en général aux blocs du disque dur). iSCSI est de très bas niveau et aucun développeur d'applications n'aurait envie de travailler directement avec ce protocole. En réseau local, on utilise plutôt NFS, dont les dernières versions (RFC 5661) disposent de ce qu'il faut pour travailler sur l'Internet.

NFS fournit des opérations de lecture, d'écriture, de gestion (destruction, renommage) de fichiers. Il a des mécanismes de contrôle d'accès qui se sont particulièrement perfectionnés avec sa version 4, qui a amené les ACL.

Par contre, il n'est pas du tout évident qu'il puisse servir dans un service pair à pair de grande taille, notamment vue la rigidité de certains de ses mécanismes de sécurité (même problème qu'avec WebDAV).

Le dernier protocole envisagé, OAuth (RFC 5849) n'est pas vraiment un protocole d'accès à du stockage en ligne. S'il est mentionné ici, c'est parce qu'il fournit un modèle intéressant pour le contrôle d'accès à ces services de stockage. Les modèles traditionnels n'avaient que deux acteurs, le client et le serveur. Le serveur autorisait (ou pas) le client à accéder aux données. OAuth introduit un troisième acteur, le titulaire des données. Celui-ci peut donner une autorisation d'accès à un client tiers, sans lui fournir pour autant toutes ses lettres de créance (mots de passe, clés privées, etc). OAuth permet donc de déléguer l'accès.

Que peut-on synthétiser de l'examen de ces protocoles ? Ils sont surtout conçus pour du client-serveur (bien que certains puissent être adaptés au pair à pair). Et HTTP est tellement répandu et bien connu qu'il peut fournir un bon point de départ à DECADE. Par contre, aucun de ces protocoles ne prend en compte la nécessité d'accès avec faible latence, qui est nécessaire pour la diffusion de vidéo en streaming.

Enfin, si presque tous les protocoles fournissent les mécanismes de base, comme lire et écrire, la grande majorité n'a aucun mécanisme de contrôle de l'allocation des ressources, un des objectifs de DECADE (il s'agit de permettre un accès à ses ressources, sans que les pairs ne puissent tout consommer).

Bref, résume la section 6, conclusion de ce RFC, s'il existe de nombreux systèmes de stockage en ligne, ils ont été conçus avec un cahier des charges très différent de celui de DECADE (l'exemple le plus net étant leur conception client-serveur et pas pair à pair). Aucun ne peut donc être choisi tel quel pour le projet.


Téléchargez le RFC 6392


L'article seul

RFC 6390: Guidelines for Considering New Performance Metric Development

Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : A. Clark (Telchemy Incorporated), B. Claise (Cisco Systems)
Réalisé dans le cadre du groupe de travail IETF pmol
Première rédaction de cet article le 6 Octobre 2011


Le groupe de travail IETF PMOL était chargé de travailler à la définition de métriques de haut niveau, proche de l'utilisateur (le groupe IPPM s'occupant, lui, des couches plus basses). Désormais fermé, il condense son expérience dans ce RFC, qui explique comment définir de nouvelles métriques, comme PMOL l'avait fait dans les RFC 5814 sur MPLS et RFC 6076 sur SIP. La section 3 résume ce but de ce RFC, définir un cadre utile.

La section 1 rappelle l'importance de la mesure, pour pouvoir améliorer les performances d'un système. Pour que ces mesures soient vraiment efficaces, il faut qu'elles s'appuient sur des métriques normalisées, une métrique étant une définition rigoureuse de la grandeur qu'on veut mesurer. Il faut aussi définir une méthode concrète pour faire la mesure et un format pour publier cette mesure. Pour les métriques « applicatives » de PMOL, ces mesures concernent des choses comme le temps de transfert d'un fichier, le temps de réponse d'un serveur DNS à une requête, etc (section 2.3).

Comme la plupart des RFC, on commence avec un peu de terminologie (section 2). D'abord, l'IETF aura désormais une Direction des Performances (Performance Metrics Directorate). C'est quoi ? Comme les autres Directions, c'est un organe transversal, composé d'experts du domaine, qui doit garder un œil sur tout travail IETF lié à la définition de métriques de performance. Ensuite, le RFC définit la qualité de service (QoS pour Quality of service) et la qualité du vécu (QoE pour Quality of Experience). J'ai déjà écrit sur la différence entre QoS et QoE et je trouve les définitions du RFC très embrouillées, et ne permettant pas de saisir la différence entre les deux concepts (la QoE vient d'une norme UIT, la E.800). Heureusement, la section 4 clarifie cette question. En gros, la QoS est une mesure scientifique de paramètres qui influencent le service rendu (par exemple, la latence ou la gigue), la QoE est la vision de l'utilisateur, qui peut être influencée par divers facteurs, y compris psychologiques. Bien sûr, la QoE va dépendre en partie de la QoS (par exemple, un taux de perte de paquets élevé va sérieusement baisser le débit TCP atteignable) mais le lien n'est pas évident (la norme UIT P.800 donne un exemple de reconstruction de QoE à partir de la QoS). Il y a aussi des facteurs techniques à la différence entre QoS et QoE, comme l'application utilisée : elle peut, indépendamment du bon ou mauvais comportement du réseau, influencer la QoE. Il y a enfin le contexte : tel problème de VoIP passera inaperçu pendant une communication de bavardage mais sera intolérable s'il s'agit d'un appel d'urgence.

La section 5 est le cœur du RFC, les conseils concrets sur la définition de nouvelles métriques. Premier point, déterminer le public visé (section 5.1). Qui va utiliser la métrique et pourquoi ? Est-elle destinée au laboratoire ou bien aux mesures sur des réseaux de production ? Quelle degré d'approxmation peut être accepté ? Et autres questions fondamentales.

Ensuite, la métrique elle-même (section 5.2). Pour qu'elle soit utile, il faut étudier si son absence causerait une sérieuse perte d'information, et si elle est corrélée au vécu de l'utilisateur (par exemple, un taux de pertes élevé - cf. RFC 2680 - entraine une baisse très nette de la capacité du « tuyau » TCP, attristant ainsi l'utilisateur). Mais certaines applications peuvent tolérer des pertes isolées tout en étant intolérantes à des moments de pertes massives. Dans ce cas, une meilleure métrique incluerait non seulement le taux de pertes moyen, mais sa distribution dans le temps (voir par exemple le RFC 3611).

Les grandeurs ne sont pas toujours mesurées, elles peuvent aussi être calculées à partir d'autres grandeurs (section 5.3). On trouve ainsi des compositions spatiales de métriques (RFC 5835, RFC 6049), comme lorsqu'on déduit le taux de pertes sur un chemin en faisant le produit du pourcentage de paquets qui passent, sur toutes les composantes du chemin. Il y a aussi des compositions temporelles (RFC 5835), par exemple le calcul d'un minimum en prenant le plus petit résultat d'une série de mesures.

Une fois qu'un a bien défini ce qu'on voulait, on peut écrire la spécification de la métrique (section 5.4). Il faut un nom (mais voir le RFC 6248 qui explique pourquoi il n'y a plus de registre de ces noms), une description (qui inclus les critères d'utilité présentés plus haut), une méthode de mesure, les unités de mesure, et des indications sur le choix des points de mesure (le temps de réponse à une requête SIP n'est pas le même sur l'UAC (logiciel client, le softphone) et l'UAS (logiciel serveur du fournisseur SI de l'abonné). La méthode de mesure doit permettre de répondre aux questions-pièges. Par exemple, la métrique « taux de perte de paquets » semble triviale à définir. On retire de 1 le résultat de la division du nombre de paquets arrivés par le nombre de paquets envoyés. Mais cette définition sommaire est insuffisante. Si des paquets sont dupliqués (c'est possible avec IP), comment les traite-t-on ? Et, pour compter le nombre de paquets arrivés, on les attend combien de temps ? Un retardataire est-il une perte (voir aussi la section 5.5.2) ? Un autre exemple est que la méthode de mesure peut décider délibérement d'éliminer les outliers, ces valeurs très éloignées de la moyenne, qui sont fréquentes sur les réseaux informatiques. C'est ainsi que les opérateurs Internet font en général payer leurs clients en « 95 percentile » (on élimine 5 % de valeurs qui sortent trop du rang, les outliers).

Outre ces points essentiels de la spécification, la définition d'une métrique peut aussi inclure une mise en œuvre (par exemple sous forme de code), des valeurs attendues pour certains cas (pour évaluer la qualité du résultat), etc. Plus délicat, la définition peut inclure des indications sur l'usage de la métrique, par exemple sur les valeurs « raisonnables ». Un utilisateur typique à qui on dit qu'il y a « 1 % de pertes » sur le réseau ne sait pas forcément quoi en faire. Lui dire que les performances de TCP commencent à baisser sérieusement dès 0,5 % de pertes, serait plus utile. De même, annoncer dans un système de transport de la voix un niveau sonore de -7 dBm0 n'est guère utile à l'utilisateur non expert en téléphonie si on n'ajoute pas que les valeurs normales sont entre -18 et -28 dBm0 et que le son est donc ici bien trop fort.

Notre RFC 6390 fournit un exemple complet de définition d'une métrique, en prenant le taux de perte du RFC 3611 comme exemple. Notez que cette définition est un peu floue quant au sort des paquets arrivant tardivement.

Dans le monde réel, aucune mesure n'est parfaite : divers problèmes limitent la qualité des mesures effectuées. La section 5.5 décrit ces problèmes : précision de l'horloge, présence ou non d'une middlebox (RFC 3303) qui fausse les résultats, etc.

Et enfin, la métrique ainsi normalisée doit préciser les différents paramètres utilisés, pour que les utilisateurs puissent comparer deux mesures différentes.

La section 6 est plutôt orientée vers le processus social de développement d'une nouvelle métrique : si on a une idée d'une métrique à normaliser, comment agir dans l'IETF pour augmenter les chances de succès ? Elle insiste par exemple sur la check-list des caractéristiques à vérifier (la métrique est-elle bien définie, par exemple) et sur la rôle de la Direction des Performances, qui va évaluer le futur RFC.

Un peu d'histoire (section 1.1): l'IETF avait déjà travaillé, dans des temps anciens, sur des métriques pour les applications. Ce furent le RFC 4710, centré sur les terminaux mobiles, ou les RFC 3611 ou RFC 6035 sur la téléphonie. Mais, pendant longtemps, les principales métriques développées étaient uniquement pour les couches 3 et 4. Notre RFC 6390 vise donc à élargir le bestiaire des métriques.


Téléchargez le RFC 6390


L'article seul

RFC 6386: VP8 Data Format and Decoding Guide

Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : J. Bankoski, J. Koleszar, L. Quillio, J. Salonen, P. Wilkins, Y. Xu (Google)
Pour information
Première rédaction de cet article le 11 Novembre 2011


Le monde des formats vidéo est très hostile pour ceux qui apprécient la liberté et l'ouverture : formats privés, non documentés, contrôlés par une seule compagnie, plombé de brevets tous plus futiles les uns que les autres... Aujourd'hui, il est à peu près impossible de regarder une vidéo, quelle qu'elle soit, avec du logiciel entièrement libre, et sans enfreindre une centaine de brevets. Ce RFC documente un des très rares codecs vidéos ouverts, qui puisse être mis en œuvre dans du logiciel libre sans trop de crainte juridique. Il a été produit par Google, documenté pour l'IETF et se nomme VP8.

Lorsqu'on configure une machine utilisant du logiciel libre aujourd'hui, si on s'en tient strictement à ses principes, et qu'on refuse d'intégrer les sources de logiciel que Debian ou Ubuntu marquent comme non-libres, on n'arrivera pas à voir beaucoup de films... Même si le format du container vidéo est relativement ouvert, les techniques de compression ne le sont pas et on constate vite que son MPlayer ou son vlc n'arrivent pas à lire grand'chose. (C'est particulièrement vrai pour les films achetés légalement, pour lesquels l'usage de formats fermés sert de DRM. Les films partagés gratuitement sur le réseau réservent en général moins de mauvaises surprises.) Le problème de la personne qui produit le film est le manque de formats ouverts dans ce domaine. Le principal est Ogg (avec le codec vidéo Theora) mais les experts lui reprochent des performances en compression et décompression qui ne sont pas extraordinaires. Google prétend avoir une solution, son format VP8 (avec le format de container WebM), supposé bien meilleur (il a été développé à l'origine par On2). Mais utiliser un format spécifique à Google n'est pas mieux qu'utiliser un format spécifique à Adobe. Alors, Google a produit un RFC, soumis à l'IETF (en termes IETF, c'est une « soumission indépendante », pas le résutat d'un groupe de travail IETF) et qui devient donc un format ouvert, libre de la compagnie qui lui a donné naissance. Ce RFC inclut également une mise en œuvre de référence du décodeur, distribuée sous une licence libre (la BSD, cf. section 20.26).

La question des brevets est traditionnellement une de celles qui plombent le plus les projets de codecs ouverts. La section 20.27 décrit en détail la situation pour VP8. Google promet une licence gratuite d'exploitation de ses brevets pour toute implémentation de VP8. Mais il n'est pas clair, pour un non-juriste, si cela couvre la possibilité de versions ultérieures de VP8, qui ne seraient pas approuvées par Google. En attendant, pas mal de requins pourraient attaquer VP8.

Ce RFC 6386 est essentiellement composé de code. VP8 est en effet défini par son implémentation de référence (la libvpx), le texte n'étant là que pour expliquer. Le RFC note bien (section 1) que, s'il y a une contradiction entre le code et le texte, c'est le code qui a raison (choix inhabituel à l'IETF). Avec ses 310 pages, c'est un des plus longs RFC existants. Je ne vais donc pas le traiter dans sa totalité, d'autant plus que les codecs vidéos ne sont pas ma spécialité.

Donc, en simplifiant à l'extrême, VP8 décompose chaque image d'un flux vidéo en une série de sous-blocs, chacun des sous-blocs étant composé de pixels. La compression d'un sous-bloc dépend des sous-blocs précédents, pour bénéficier de la redondance temporelle de la vidéo (sauf dans les films avec Bruce Willis, il y a relativement peu de changements d'une image à la suivante, et en général sur une partie de l'image seulement). Il y a aussi une redondance spatiale (des parties de l'image qui sont répétées, par exemple un grand ciel noir pour les scènes de nuit). La technique de compression se nomme transformée en cosinus discrète, mais VP8 utilise également à certains endroits une autre technique, la transformée de Walsh-Hadamard. VP8 ne permet pas de reconstituer exactement les pixels originaux, il compte sur la tolérance de l'œil humain (qui peut accepter certains changements sans tiquer).

Contrairement à son concurrent MPEG, VP8 encode et décode uniquement avec des nombres entiers et ne perd donc pas de précision dans les calculs en virgule flottante. Ces pertes peuvent parfois provoquer des effets surprenants, visibles à l'écran (rappelez-vous que, dans l'arithmétique en virgule flottante, il y a moins d'assertions vérifiables. Par exemple, 1 - x + x n'est pas forcément égal à 1).

La section 2 du RFC expose les grandes lignes du format : utilisation de l'espace YUV en 4:2:0 8bits, c'est-à-dire que chaque pixel dans les deux plans chromatiques (U et V) fait huit bits et correspond à un bloc de quatre pixels dans le plan de lumière Y. Les pixels sont ensuite transmis en lignes, de haut en bas, chaque ligne étant transmise de gauche à droite. Les informations permettant le décodage ne sont pas au niveau du pixel mais à celui de blocs de pixels. Dans l'implémentation de référence, la description du format se trouve dans le fichier d'en-tête vpx_image.h.

Une fois comprimées, il y a deux types de trames dans un flux VP8 (section 3) : les intratrames (ou trames clés, ce que MPEG appelle les trames-I) sont complètes et n'ont pas besoin d'autres trames pour être décodées. La première trame envoyée est évidemment une intratrame. Et le deuxième type sont les intertrame (trames-P chez MPEG), qui codent une différence par rapport à la précédente intratrame, et aux autres intertrames arrivées entre temps. La perte d'une intertrame empêche donc de décoder les suivantes, jusqu'à l'arrivée de la prochaine intratrame, qui permettra au décodeur de repartir d'un état connu.

À noter que, contrairement à MPEG, il n'y a pas de trame-B, trame permettant d'indiquer le futur. En revanche, VP8 a des « trames en or » et des « trames de référence de secours » qui sont des intertrames contenant suffisamment d'informations pour permettre de reconstituer les quelques trames suivantes. Elles permettent à VP8 d'être plus tolérant aux pertes de trame (normalement, lorsqu'un perd une intratrame, il n'y a rien d'autre à faire qu'à attendre la suivante).

Le format des trames compressées est décrit en section 4. Un en-tête (plus grand dans le cas des intratrames), et les données. Bon, en fait, c'est un peu plus compliqué que cela car, au sein des données, les macroblocs ont aussi leur en-tête. Pour décoder (section 5), le programme doit garder quatre tampons YUV : la trame actuellement en cours de reconstruction, la trame précédente (rappelez-vous que les intertrames sont uniquement des différences par rapport à la trame précédente, qu'il faut donc garder en mémoire), et les plus récentes trames en or et de référence de secours. Le principe est simple (on réapplique les différences à la trame de référence, obtenant ainsi la trame originale), mais il y plein de pièges, dûs par exemple à l'abondance du contexte à maintenir (puisque le décodage dépend du contexte en cours). Le code se trouve dans dixie.c dans le RFC (l'implémentation de référence a été réorganisée et ce fichier n'y figure plus). Une façon de simplifier l'écriture d'un décodeur est de commencer par ne programmer que le décodage des intratrames, avant d'ajouter celui des trames intermdiaires. C'est d'ailleurs le plan que choisit le RFC.

Le langage de l'implémentation de référence est le C. Comme le note la section 6, c'est en raison de sa disponibilité universelle et de sa capacité à décrire exactement la précision des calculs qu'il a été choisi. Notez que le code C dans le RFC n'est pas exactement celui de l'implémentation de référence (qui est, elle, disponible en http://www.webmproject.org/code/). Plusieurs raisons à cela, notamment le fait que l'implémentation de référence a été optimisée pour la performance, le code dans le RFC pour la lisibilité, Mais les deux codes produisent le même résultat. Rappelons enfin que VP8 n'utilise pas de flottants, seulement des entiers.

Le code commence en section 7, avec le décodeur booléen. L'idée est que l'encodage est fait en produisant une série de booléens, avec pour chacun une probabilité d'être à zéro ou à un. Si la probabilité était de 0,5, aucune compression ne serait possible (il faudrait indiquer explicitement tous les booléens) mais ici, les probabilités sont souvent très éloignées de 0,5 (en raison des cohérences spatiales et temporelles du flux vidéo) et VP8 consomme donc moins d'un bit par booléen. Travailler sur bits étant typiquement peu efficace sur la plupart des processeurs, le code en section 7.3 les regroupe en octets.

Le reste du RFC est essentiellement composé de code C avec commentaires. Je saute directement à la section 19 / annexe A qui donne la liste complète des données encodées, Tous les objets manipulés par VP8 sont là.

Notez que le projet parent, WebM, utilise actuellement Vorbis pour l'audio (VP8 ne faisant que la vidéo). L'IETF a un projet de développement d'un codec audio, les détails figurent dans le RFC 6366.

Pour plus d'information, on peut consulter le site officiel du projet WebM qui contient entre autres une liste des outils disponibles. Pour le déploiement de WebM, on peut voir la page du Wikipédia anglophone. Une analyse (critique) de VP8 a été faite par Jason Garnett-Glaser.

Parmi les autres mises en œuvre de VP8, un cas curieux, un décodeur en JavaScript...


Téléchargez le RFC 6386


L'article seul

RFC 6385: General Area Review Team (Gen-ART) Experiences

Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : M. Barnes (Polycom), A. Doria (Lulea University of Technology), H. Alvestrand (Google), B. Carpenter (University of Auckland)
Pour information
Première rédaction de cet article le 19 Octobre 2011


Comme souvent à l'IETF, les expériences les plus réussies ne sont pas documentées, ou alors le sont longtemps après. Les examens des Internet-Drafts par Gen-ART (General Area Review Team) ont commencé en 2004 mais viennent juste d'être formalisées. Gen-ART, dont l'expérience est décrite dans ce nouveau RFC, est un groupe d'experts volontaires qui regardent les Internet-Drafts lorsqu'ils sont prêts de devenir un RFC. Le terme de « Gen-ART » apparait de plus en plus souvent dans les discussions à l'IETF, mais que recouvre-t-il exactement ?

Les procédures de l'IETF sont loin d'être toutes documentées. Il y a la théorie, et la pratique. Par exemple, l'IESG est censée examiner les Internet-Drafts avant leur publication au cours de ses réunions à distance, les telechats. Mais la quantité de documents à examiner est telle que toute aide est la bienvenue. Un groupe de volontaires s'est donc constitué et s'est mis tout seul (rappellons que tout le processus IETF est public, il n'y a pas besoin d'une autorisation spéciale pour créer un groupe, lire des documents et publier les résultats) à lire les documents qui allaient passer à l'IESG, pour débrousailler le tas de papier. Ce RFC est le compte-rendu de l'expérience de ce groupe, qui prend désormais de plus en plus de place, au point que certains croient même qu'il s'agit d'un projet officiel.

La section 1 du RFC résume d'où vient Gen-ART, et insiste sur ce caractère non officiel. Gen-ART fait ce que tout le monde a le droit de faire : lire les Internet-Drafts (ils sont publics) et les commenter publiquement. Son autorité est purement morale, provenant de la qualité de ses examens et du prestige de ses membres.

La section 2 est consacrée à ces membres : un groupe d'experts auto-désignés, en général auteurs de plusieurs RFC, et expérimentés dans la normalisation IETF. La section 12 donne la liste actuelle (qu'on trouve aussi en ligne). Bien que le RFC n'en parle pas, on peut noter que la relecture est parfois faite par un autre membre de l'IETF, sur délégation d'un membre de Gen-ART (évidemment en toute transparence). C'est ainsi que j'ai fait ma première (et unique, pour l'instant) revue Gen-ART, en décembre 2010, comme délégué de Francis Dupont. Il s'agissait du document draft-cheshire-dnsext-dns-sd, très contesté (ma conclusion était peu favorable, et le document est toujours, aujourd'hui, en discussion). L'auteur avait répondu à mon analyse.

La section 3 résume ensuite le but poursuivi par Gen-ART : décharger l'IESG d'une partie du fardeau (parfois vingt Internet-Drafts en un seul telechat), de façon à ce que l'examen de l'IESG puisse se concentrer sur les quelques documents à problème, en ignorant la majorité qui va bien. Bien qu'il existe tout un tas de comités et de groupes à l'IETF, personne ne vise cette tâche à part Gen-ART.

La section 4 décrit comment fonctionne Gen-ART, quels documents sont relus, et qu'est-ce que produit Gen-ART. Le rapport final indique si l'Internet-Draft :

  • est prêt à devenir un RFC, et de quel type (expérimental, pour information, chemin des normes...),
  • ou bien est presque bon mais mérite quelques changements,
  • ou encore s'il va dans le bon sens mais a besoin d'être sérieusement revu,
  • ou, pourquoi pas, s'il est tellement catastrophique qu'il vaut mieux arrêter là.

Les critères pour décider sont ceux classiquement utilisés à l'IETF :

Gen-ART étant issu de la « zone générale » (General Area, celle qui s'occupe de tout ce qui ne rentre pas dans une catégorie particulière), le groupe de relecteurs fait notamment attention à tout ce qui n'est pas sous la responsabilité d'une autre zone. Par exemple, dans un Internet-Draft sur un nouveau protocole de routage, on peut supposer que la zone Routage (Routing Area) s'est occupé de la qualité technique du protocole. Cela laisse donc à vérifier, un tas de choses, certaines de haut niveau et d'autres triviales. Le RFC cite, entre autres :

La section 4 décrit ensuite le processus suivi lors des relectures. Il faut notamment noter que les RFC ne sont pas affectés aux relecteurs en fonction de leur spécialité : le but étant d'avoir un regard général, un expert en sécurité peut se retrouver avec un Internet-Draft sur le routage. Le processus bureaucratique, lui (maintien de la liste des relecteurs, détails très précis sur les conditions d'affectation d'un document à un relecteur), est en section 5.

Quels sont les résultats de Gen-ART ? La section 6 fait le bilan : environ 2 000 relectures ont été faites en sept ans, avec une équipe comportant environ douze relecteurs, chacun recevant plus d'un Internet-Draft par mois. Ces relectures ont permis de faire passer le pourcentage de documents considérés comme « prêts pour publication » au moment du telechat IESG de 25 % à 75 %.

Par delà les chiffres, quel est le ressenti des participants ? La section 7 rassemble tout un tas de témoignages très variés, notant par exemple que la qualité moyenne est bonne mais que Gen-ART a déjà servi à arrêter de très mauvais documents.

Mais le mécanisme des relectures Gen-ART est-il parfait ? La section 8 propose de l'améliorer, notant les points faibles. Le principal est l'absence presque complète d'automatisation. Gen-ART n'a actuellement pas d'outils spécialisés (un des buts de la section 5 était, en décrivant précisement le processus, de faciliter l'écriture d'un cahier des charges pour le développement de ces outils).

Vous pouvez aussi visiter le site Web de Gen-ART et prendre connaissance de sa FAQ.


Téléchargez le RFC 6385


L'article seul

RFC 6382: Unique Per-Node Origin ASNs for Globally Anycasted Services

Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : Danny McPherson, Ryan Donnelly, Frank Scalzo (Verisign)
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 25 Octobre 2011
Dernière mise à jour le 26 Octobre 2011


Ce court RFC propose un changement radical dans la gestion des annonces BGP par les services anycastés. Actuellement, ils utilisent presque tous un seul numéro d'AS pour tous les nœuds d'un nuage anycast. Notre RFC 6382, au contraire, suggère d'utiliser un numéro d'AS par nœud.

Comme l'explique la section 2 de notre RFC, l'anycast (RFC 4786) est désormais une technique banale. Elle permet notamment d'augmenter sérieusement la résistance aux dDoS. Dans le monde du DNS, l'anycast est particulièrement répandu (par exemple, .fr n'a plus que deux serveurs unicasts, tous les autres sont anycastés).

L'anycast fonctionnant en injectant la même route, via BGP, depuis des points différents du réseau, on peut se demander s'il faut que tous ces points annonçent le préfixe depuis le même AS, ou bien si chacun doit utiliser un AS différent ? Aujourd'hui, la quasi-totalité des services anycastés utilisent un seul numéro d'AS pour tous leurs points de présence (POP). VeriSign (la boîte des auteurs du RFC) est un des rares acteurs à le faire, pour certains de leurs serveurs. Cela a notamment l'avantage de préserver une ressource rare : les numéros d'AS n'étaient codés que sur seize bits. Cela facilite également la configuraion des routeurs. Et, aujourd'hui, cela évite des ennuis avec les systèmes d'alarme BGP, qui pourraient couiner en voyant le même préfixe avoir plusieurs AS d'origine. Hurricane Electric fournit ainsi une liste des préfixes annoncés par plusieurs AS. Même chose chez Cymru. Comme illustré par un exposé à NANOG en 2001, c'était plutôt considéré comme une erreur.

Mais cette politique a aussi des défauts : lorsqu'un routeur BGP voit arriver une annonce pour un préfixe anycasté, il ne sait pas exactement de quel nœud elle vient. Cela peut compliquer le déboguage des problèmes. Certains services ont un mécanisme pour identifier le serveur (RFC 5001 pour le DNS, ou bien le traditionnel quoique non normalisé hostname.bind dans la classe CH). Et, évidemment, on peut toujours utiliser traceroute pour trouver où se trouve telle instance anycast. Essayons avec un serveur DNS anycasté, d.nic.fr, depuis une machine située dans le Missouri :

% dig +nsid @d.nic.fr SOA fr.
...
; NSID: 64 6e 73 2e 6c 79 6e 32 2e 6e 69 63 2e 66 72  (d) (n) (s) (.) (l) (y) (n) (2) (.) (n) (i) (c) (.) (f) (r)
...

C'est donc dns.lyn2.nic.fr qui a répondu. Et on confirme (l'AFNIC utilise les Locodes pour nommer ses machines, donc LYN = Lyon) qu'on touche l'instance de Lyon (cette machine a surtout des instances en métropole et dans les DOM-TOM et aucune aux États-Unis) :

# tcptraceroute d.nic.fr 53
Selected device eth0, address 208.75.84.80, port 43778 for outgoing packets
Tracing the path to d.nic.fr (194.0.9.1) on TCP port 53 (domain), 30 hops max
 1  208.75.84.1  0.000 ms  0.000 ms  0.000 ms
 2  host123.datotel.com (208.75.82.123)  0.000 ms  0.000 ms  0.000 ms
 3  stl-c1-g1-15.datotel.com (208.82.151.29)  10.000 ms  0.000 ms  0.000 ms
 4  stl-e2-g0-2.datotel.com (208.82.151.13)  0.000 ms  0.000 ms  0.000 ms
 5  vlan100.car2.StLouis1.Level3.net (4.53.162.121)  0.000 ms  0.000 ms  0.000 ms
 6  ae-4-4.ebr2.Chicago1.Level3.net (4.69.132.190)  10.000 ms  9.999 ms  10.000 ms
 7  ae-5-5.ebr2.Chicago2.Level3.net (4.69.140.194)  0.000 ms  9.999 ms  9.999 ms
 8  ae-6-6.ebr2.Washington12.Level3.net (4.69.148.145)  10.000 ms  19.999 ms  19.999 ms
 9  ae-5-5.ebr2.Washington1.Level3.net (4.69.143.221)  19.999 ms  19.999 ms  29.998 ms
10  ae-44-44.ebr2.Paris1.Level3.net (4.69.137.61)  89.994 ms  99.994 ms  109.994 ms
11  ae-22-52.car2.Paris1.Level3.net (4.69.139.227)  109.994 ms  99.994 ms  99.994 ms
12  JAGUAR-NETW.car2.Paris1.Level3.net (212.73.207.162)  109.993 ms  99.995 ms  99.994 ms
13  dns.lyn2.afnic.cust.jaguar-network.net (78.153.224.126)  119.993 ms  119.993 ms  139.992 ms
14  d.nic.fr (194.0.9.1) [open]  109.994 ms  119.993 ms  109.993 ms

Les machines de l'AFNIC ayant un enregistrement DNS indiquant leur position physique (RFC 1876), on peut même être plus précis :

% dig LOC dns.lyn2.nic.fr
...
dns.lyn2.nic.fr.	172800	IN	LOC	45 43 20.568 N 4 51 39.816 E 1.00m 1m 10m 10m

et on sait alors où est la machine.

Autre essai, avec un serveur de la racine du DNS, L.root-servers.net, largement anycasté. Depuis un fournisseur en France :

% dig +nsid @l.root-servers.net SOA .
...
; NSID: 6c 79 73 30 31 2e 6c 2e 72 6f 6f 74 2d 73 65 72 76 65 72 73 2e 6f 72 67  (l) (y) (s) (0) (1) (.) (l) (.) (r) (o) (o) (t) (
-) (s) (e) (r) (v) (e) (r) (s) (.) (o) (r) (g)

On touche lys01.l.root-servers.org. Comme son opérateur, l'ICANN, utilise (comme beaucoup), les codes aéroport pour nommer les machines, on voit qu'elle est également à Lyon (LYS est l'aéroport de cette ville). Depuis une machine d'un autre FAI français, la même requête renvoie lux01.l.root-servers.org, ce qui situe le nœud anycast au Luxembourg. Et, en testant depuis la machine missourienne citée plus haut, on atteint lax12.l.root-servers.org soit Los Angeles.

Ces techniques sont toutefois imparfaites. Or, les services anycast ont des vulnérabilités paticulières. Par exemple, l'injection de routes pirates dans BGP par un méchant est plus difficile à détecter (cf. section 5). L'anycast a besoin d'outils de déboguage puissants, pour venir à bout des problèmes de routage, volontaires ou involontaires, qui peuvent se manifester. Pire, on peut avoir des cas où les différentes instances d'un même nuage anycast ne répondent pas exactement la même chose, et il est dans ce cas crucial de pouvoir identifier sans aucune ambiguïté celles qui sont différentes.

Avant la recommandation officielle, un petit détour de terminologie (section 1). Parmi les termes importants (lire le RFC 4786 pour plus de détails) :

  • Bassin d'attraction (catchment), terme emprunté à l'hydrographie (la zone dont toutes les eaux finissent dans une rivière donnée), désigne la partie de l'Internet qui envoie ses paquets à un nœud (une instance anycast) donné,
  • Nœud local, instance d'un service anycast qui ne publie son préfixe que dans une partie de l'Internet (typiquement, uniquement les participants à un point d'échange donné, en utilisant la communauté BGP no-export). La recommandation de ce RFC s'applique à tous les nœuds, locaux ou globaux,
  • Nœud global, instance qui annonce son préfixe à l'Internet entier.

Venons-en maintenant à la nouveauté de ce RFC. Il tient en une phrase (section 3), « Il faudrait utiliser un numéro d'AS différent par nœud ». Le but est de fournir un mécanisme discriminant les annonces. Si on a deux nœuds, un en Chine (AS 65536) et un en Europe (AS 65551), et qu'on voit le préfixe anycast 192.0.2.64/26 annoncé depuis l'AS 65536, on sait qu'on s'adressera à l'instance chinoise. On peut même filtrer sur l'AS d'origine pour éviter cela. L'utilisation de numéros d'AS différents permettra de choisir sa politique de routage.

Est-ce sans inconvénient ? Actuellement, le principal problème risque d'être les systèmes d'alarme qui s'inquiéteraient de ces différentes origines. Ainsi, BGPmon, par défaut, considère qu'une annonce depuis un autre AS que celui indiqué comme origine, est une attaque possible (possible hijack) et il alarme. Toutefois, le même BGPmon permet d'indiquer plusieurs AS d'origine supplémentaire, ce qui lui permet de gérer la nouvelle politique. (Une société comme PCH a environ soixante localisations physiques dans le monde, Netnod en a cent : les enregistrer toutes comme origine possible, auprès d'un système d'alarme BGP, pourrait être fastidieux. À noter que la fonction auto-detect de BGPmon simplifie cela : comme l'explique l'auteur « Just click on the prefix to edit it, then click on the little green icon next to the 'Additional Origin AS' section. It will then show a popup with all additional origin ASn's we have in our database. You can then copy paste that line into the 'Additional Origin AS' field. ». Un exemple est donné par un serveur de .com, m.gtld-servers.net.)

Autre inconvénient possible : la consommation excessive de numéros d'AS. Toutefois, depuis le RFC 4893, ceux-ci peuvent désormais être codés sur 32 bits et le risque d'épuisement disparait.

Après cette nouvelle recommandation de consommer un numéro d'AS par site, la section 4 du RFC rassemble divers conseils aux gérants de services anycast :

  • Publier des informations sur la localisation physique de la machine (la méthode n'est pas précisée mais on peut penser aux enregistrements LOC du RFC 1876, peut-être en les attachant au nom obtenu par la requête NSID),
  • Publier dans les IRR les informations sur les AS auxquels le nœud anycast s'interconnecte (par exemple en RPSL, RFC 4012).

Et la section 6 contient l'examen de divers points pratiques liés au déploiement de cette nouvelle politique. Les opérateurs de services anycast critiques ont été largement consultés avant la publication du RFC, ce qui ne veut pas dire qu'ils déploieront cette recommandation tout de suite (aucun n'a annoncé de plan précis et l'ISC a au contraire annoncé qu'ils ne le feraient pas, voir plus loin leur analyse). En gros, la nouvelle politique fera davantage de travail au début (obtenir les numéros d'AS - ce qui nécessitera probablement un changement dans la politique des RIR, ajouter une colonne pour le numéro d'AS dans la base de données des instances anycast, penser à indiquer le bon numéro d'AS lorsqu'on fait une demande de peering, changer les centaines de peerings existants, etc) mais simplifiera la surveillance du service, en permettant de trouver plus facilement l'origine d'une annonce.

Et pour finir, un exemple de ce que donne un excellent outil d'analyse existant, le RIS, avec le serveur de .com déjà cité (annoncé par trois AS) : http://www.ris.ripe.net/dashboard/192.55.83.0/24.

Une autre question n'est pas couverte dans le RFC mais mérite une mention (merci à Olivier Benghozi et Guillaume Barrot pour leurs explications) : pourquoi n'avoir pas utilisé plutôt les communautés BGP (RFC 1997), des étiquettes qu'on peut attacher aux annonces et qui sont transitives ? La raison principale est qu'elles sont fréquemment effacées en entrée des AS (sans compter les systèmes qui, par défaut, ne les transmettent pas du tout comme IOS, cf. un article sur leur utilisation). Même problème avec d'autres attributs facultatifs de BGP comme AGGREGATOR (qu'on aurait pu, en le détournant un peu, utiliser à ce but).

Merci à Jean-Philippe Pick pour sa relecture et pour les informations.


Téléchargez le RFC 6382


L'article seul

RFC 6377: DKIM And Mailing Lists

Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : M. Kucherawy (Cloudmark)
Réalisé dans le cadre du groupe de travail IETF dkim
Première rédaction de cet article le 22 Septembre 2011


La sécurité, c'est compliqué. Ce n'est pas tout de définir des normes techniques comme DKIM, pour sécuriser le courrier électronique. Il faut encore étudier leurs conséquences pour tous les cas. Le courrier électronique ayant débuté il y a très longtemps, et n'ayant pas vraiment été spécifié dans tous les détails (son architecture n'a été officiellement décrite qu'en 2009, avec le RFC 5598), il représente un défi particulier pour tous ceux qui essaient de le sécuriser a posteriori. C'est ainsi que ce nouveau RFC s'attaque au cas particulier des listes de diffusion et étudie comment elles réagissent avec le mécanisme d'authentification DKIM.

D'abord, à quoi sert DKIM ? Normalisé dans le RFC 6376, DKIM permet de signer un message électronique. Sans lui, il est trivial de fabriquer un faux message (prétendant venir de votre banque et vous demandant de saisir votre mot de passe sur un formulaire Web) et il n'y a aucun moyen d'acquérir des certitudes sur ce message, où (presque) tout peut être faux. Avec DKIM, un domaine de courrier peut signer le message et ainsi en prendre la responsabilité. Si le message est signé par mabanque.example, vous pouvez être sûr, pas forcément de sa véracité, mais en tout cas d'un lien avec votre banque. Contrairement à PGP, conçu pour authentifier une personne, DKIM permet d'authentifier un domaine qui a une responsabilité dans l'envoi de ce message.

Mais les listes de diffusion posent des problèmes spécifiques (section 1). DKIM avait été conçu avec l'idée que le message n'était pas modifié en cours de route. S'il l'est, c'est considéré comme une attaque qu'il faut détecter. Or, les gestionnaires de listes de diffusion ne respectent pas ce principe. Par exemple, il est fréquent (bien que ce soit une très mauvaise idée, cf. le RFC 4096) que le sujet soit modifié pour y inclure le nom de la liste entre crochets. De même, l'ajout d'instructions de désabonnement à la fin de chaque message est commun. De telles modifications sont peut-être honnêtes (dans l'esprit de celui qui les a décidés, ce ne sont pas des tentatives de fraude) mais, pour un logiciel de vérification, elles suffisent à invalider la signature.

Si les intermédiaires qui relaient un message le laissaient rigoureusement intact, ce serait non seulement une bonne idée pour les utilisateurs, mais cela permettrait à DKIM de continuer à fonctionner. Comme, parmi les intermédiaires, les MLM (Mailing List Managers) sont souvent les plus intrusifs, que peut faire DKIM pour gérer ce problème ?

  • Est-ce une bonne idée de signer avec DKIM un message envoyé à une liste de diffusion ?
  • Est-ce que le MLM devrait vérifier ces signatures en entrée ?
  • Est-ce que le MLM devrait retirer les signatures existantes ?
  • Et/ou mettre la sienne ?

Ce RFC ne normalise pas de réponse officielle à ces questions : il explique le problème et pointe du doigt les compromis à faire. La recommandation générale est « dans le cas typique, le MLM a intérêt à signer les messages qu'il relaie, et les vérificateurs à la destination ont intérêt à tenir compte de cette signature ». Le lecteur attentif aura noté que cette recommandation laisse plein de questions ouvertes...

Avant de détailler les problèmes, la fin de la section 1 rappelle quelques éléments importants sur le courrier électronique et les MLM (voir le RFC 5598 pour une présentation générale de l'architecture du courrier et sa section 5.3 sur les MLM). Les MLM (les gestionnaires de listes de diffusion) n'ayant jamais fait l'objet d'une normalisation officielle (le RFC 5598 a été écrit longtemps après), leur comportement varie énormément. Lorsqu'un MLM fait une opération, il est bien difficile de trouver un RFC qui dit noir sur blanc s'il est en droit de la faire ou non. Une notion aussi simple que celle d'identité (qui est l'auteur du message) n'est pas évidente et DKIM a donc sagement décidé de ne pas lier le domaine signant (celui qui est indiqué par d= dans une signature DKIM) avec une des « identités » présentes dans les en-têtes du message. Ainsi, le domaine signant n'est pas forcément celui présent dans le champ From:. Il peut refléter, par exemple, un domaine qui a relayé le courrier et, en le signant, a affirmé une certaine responsabilité pour ce message. Donc, si un MLM signe avec son domaine un message venu d'un autre domaine, cela ne pose pas de problème : c'est dans l'esprit de DKIM.

C'est l'interprétation qui va poser problème. Si j'écris un message sur la liste smtp-fr@cru.fr avec mon adresse professionnelle (bortzmeyer@nic.fr), qui est responsable ? L'« auteur », mentionné dans le champ From:, ou bien l'ex-CRU, qui gère le MLM, ou encore la personne mentionnée (ce terme est d'ailleurs malheureux) comme « propriétaire » de la liste smtp-fr (aujourd'hui, Christophe Wolfhugel). Selon le cas, un vérificateur sera plus intéressé par l'un ou l'autre des responsables.

Je l'ai dit, la normalisation des fonctions des MLM n'a été faite qu'a posteriori, n'est pas complète, et n'a pas été largement adoptée. C'est ainsi que des normes comme le champ List-ID: (RFC 2929) ou les en-têtes donnant les mécanismes de désabonnement (RFC 2369) ne sont que partiellement déployés.

Bref, que conseille ce RFC ? Avant d'en arriver aux conseils pratiques, en section 4 et 5, il faut encore bien se mettre à jour sur la terminologie (section 2) et les principes de fonctionnement des MLM (section 3). En section 2, il faut d'abord lire les RFC sur DKIM, le RFC 5585, qui sert d'introduction et le RFC 6376 sur la norme elle-même. Ensuite, notre RFC introduit quelques termes nouveaux comme « gentil avec DKIM » (DKIM-friendly), qui désigne un MLM dont les actions n'invalident pas les signatures DKIM. À noter que cela ne dépend pas que du logiciel mais aussi de sa configuration (si on lui fait ajouter un pied de page en bas de chaque message, les signatures portant sur le corps du message sont invalidées), et des options du signeur (si le MLM modifie le sujet mais que le signeur n'a pas signé le sujet, le MLM sera considéré comme gentil avec DKIM).

Alors, comment fonctionnent les MLM ? Le problème, note la section 3, est qu'il y en a plusieurs sortes. Les différents rôles qui décrivent les acteurs du système de messagerie (auteur, signeur, récepteur, etc) sont évidents lorsque le message est un envoi direct d'Alice à Bob. Mais le MLM perturbe ce bel ordonnancement théorique. Déjà, il y a quatre types de MLM :

  • Les alias, qui transmettent le message sans autre changement que l'ajout de quelques en-têtes de trace (comme Received:). La section 3.9.2 du RFC 5321 les mentionne. Ils ne changent que l'enveloppe SMTP, pas le message (en tout cas pas dans les parties signées). Les alias se mettent typiquement en œuvre sur Unix dans les fichiers aliases (directives alias_database et alias_maps de Postfix). Ces MLM sont gentils avec DKIM et n'invalident jamais les signatures (on notera que c'est le contraire avec SPF, RFC 4408, puisque ce dernier authentifie l'enveloppe et pas le message).
  • Les réexpéditeurs (resenders), qui reçoivent un message, lui font parfois subir quelques modifications, et renvoient ce message à la liste des abonnés. Ce sont les MLM typiques comme Mailman ou Sympa.
  • Les auteurs. Ce sont les MLM qui créent le message, plutôt que de renvoyer un message qu'on leur a transmis. Pensez à une newsletter, ou au spam. Ils n'ont guère de problème avec DKIM puisqu'ils contrôlent toute la chaîne, depuis la rédaction initiale.
  • Les synthétiseurs (digesters) qui prennent plusieurs messages reçus et les assemblent en un seul message, de type MIME multipart/digest (certains abonnés préfèrent lire ainsi). Cette synthèse est un nouveau message, mais composé à partir de messages pré-existants.

Dans les deux derniers cas, le MLM crée un nouveau message. Dans le second, le plus difficile, son rôle est moins clair. Si on veut approfondir ces nuances philosophiques, on peut consulter les sections 3.6.4 du RFC 5322 et 3.4.1 du RFC 5598.

Quels sont les effets exacts des MLM sur les messages signés ? La section 3.3 les détaille :

  • Le sujet (Subject:) est parfois modifié, pour ajouter le nom de la liste entre crochets. Cette pratique est très contestée (personnellement, je ne l'aime pas du tout, car elle modifie le message pour rien : si on veut trier le courrier, il est plus simple de le faire automatiquement via Sieve ou un système équivalent) mais, comme le note le RFC, contestée ou pas, elle ne va pas disparaître du jour au lendemain. Comme le sujet est un des éléments les plus importants de l'en-tête (c'est souvent ce que l'utilisateur regarde en premier) et qu'il est donc recommandé de le signer, ce comportement des MLM pose un problème.
  • En revanche, les en-têtes spécifiques aux listes de diffusion, comme le List-ID: du RFC 2929 ne posent a priori pas de problème, car ils sont rarement mis par les MUA et DKIM n'a pas de problème avec l'ajout de nouveaux champs.
  • Mais il peut aussi y avoir des changements dans le corps du message. Ils sont parfois mineurs (par exemple l'ajout de trois lignes d'instructions de désabonnement à la fin de chaque message). Mais cela suffit à rendre la signature DKIM invalide. DKIM permet de limiter la portée de la signature du corps (par exemple, de ne signer que les N premiers octets), ce qui permet l'ajout ultérieur de contenu (au prix d'une sérieuse baisse de sécurité). Si les changements sont plus significatifs (par exemple traduire le message HTML en texte seul), alors la signature sera invalide quoiqu'il arrive.
  • Enfin, certains MLM suppriment les fichiers attachés (présents dans une partie MIME du message), les remplaçant par exemple par l'URL d'un service d'hébergement où le fichier a été déposé. Cela cassera également la signature.

Bref, à l'heure actuelle, les MLM sont souvent méchants avec DKIM. Dans le futur, cela évoluera peut-être mais on ne peut pas en être sûr, notamment parce que DKIM n'est pas assez important pour que les programmeurs de MLM changent leurs pratiques juste pour lui.

Une fois ces pratiques des MLM étudiées, le RFC a deux parties de conseils. L'une est consacrée aux MLM qui ne connaissent pas DKIM. Cette section 4 fournit donc des conseils aux signeurs et aux validateurs pour le cas où le message est passé par un tel MLM. L'autre, la section 5, est composée de conseils aux MLM qui connaissent DKIM et veulent bien faire. Voyons d'abord la section 4. Si un message signé va passer par un MLM non-DKIM, que faire ?

Idéalement, si l'auteur sait qu'un message va passer par un MLM non-DKIM, il devrait décider de signer ou pas, selon le comportement du MLM. La signature est risquée car le MLM peut faire une des modifications citées plus haut, rendant la signature invalide et inquiétant les récepteurs. (En théorie, une signature invalide doit être ignorée - RFC 6376, section 6.1 - sauf si le domaine émetteur publie en ADSP une politique plus stricte.) Le problème de cette approche est que l'émetteur ne connaît pas forcément les détails de tous les MLM et autres logiciels par lesquels son message risque de passer. Les administrateurs système qui activent DKIM sur leur infrastructure vont donc devoir décider sans connaître toute l'information. Les politiques strictes de signature et de vérification n'ont donc de sens qu'en cas de contrôle complet de la chaîne entre l'émetteur et le récepteur (ce qui exclut les MLM). Ne mettez donc pas une politique ADSP discardable si le courrier de ce flux de messages risque de passer par un MLM.

Cette absence d'information sur les MLM et autres logiciels intermédiaires touche également les vérificateurs. Une solution possible est d'exclure de la vérification les courriers passés par les listes. Ce serait évidemment un gros travail, sans compter la maintenance d'un tel système (lorsqu'une nouvelle liste apparait). Les vérificateurs ont donc tout intérêt à respecter l'un des principes de base de DKIM : ne pas jeter un message simplement parce que sa signature est invalide.

Et pour les MLM modernes et qui gèrent DKIM ? Que doivent-ils faire ? La section 5 expose, dans l'ordre du voyage du message, les recommandations qui leur sont destinées. Ajouter des en-têtes (comme List-ID:) ne pose pas de problèmes. C'est un comportement gentil (sauf dans le cas où ces en-têtes étaient déjà présents et signés, ce qui est rare).

Par contre, ajouter un texte à la fin du message, on l'a vu, casse la signature. L'IETF n'a pas de politique officielle à ce sujet et il n'existe pas de RFC qui dise noir sur blanc « Thou SHALL NOT change the text, even by a single byte ». Même si un tel RFC existait, rien ne dit que les MLM suivraient ses consignes d'autant plus qu'il n'existe pas d'en-tête standard pour des informations telles que les conditions d'usage de la liste. DKIM a normalement une technique pour ce cas : l'option l= qui indique la portée de la signature (en nombre d'octets). L'ajout de texte après la valeur indiquée par l= n'invalide pas la signature. Mais cette méthode est déconseillée : un de ses inconvénients est qu'un attaquant peut, lui aussi, ajouter ce qu'il veut au message, sans craindre d'être détecté.

Notre RFC suggère donc, plutôt que d'ajouter à la fin de chaque message un texte comme « Le spam et les remarques désagréables sont prohibées sur cette liste. Les règles d'utilisation complètes sont présentées en http://www.example.com/lists/the-list/terms-of-use », d'envoyer de telles informations de temps en temps via un message automatique. Certes, ce sera ennuyeux (pensez à tous les messages de Mailman le premier du mois) mais cela pourra être filtré facilement.

Le problème d'ADSP (RFC 5617) est encore plus fort. ADSP permet de publier dans le DNS des directives de validation du genre « Je signe tout et correctement, vous pouvez jeter tout ce qui n'est pas bien signé ». Si un domaine publie une politique ADSP discardable, il interdit quasiment tout usage d'un MLM. Les seules solutions sont encore dans le futur. Par exemple, le RFC imagine des MLM qui connaissent ADSP et qui, lors de la réception d'une demande d'abonnement, testent la politique et, si elle est stricte, refusent l'abonnement. Mais la politique ADSP peut changer à tout moment, donc ce n'est pas une solution parfaite. Va-t-il falloir retester régulièrement ?

L'auteur d'un message signé est de toute façon toujours dans une position difficile : il ne sait pas ce qui va arriver à son message et il ne connaît pas les réglages des logiciels intermédiaires. La section 5.5 recommande donc de séparer le courrier en deux : celui qui sera forcément de bout-en-bout devrait être signé avec une identité et une clé différente du courrier général, qui sera peut-être relayé par un MLM. Ainsi, si mabanquecherie.example est le domaine d'une banque, le courrier envoyé directement au client ne devrait pas avoir le même d= que celui utilisé pour le travail quotidien des employés.

Et sur le MLM lui-même, s'il connaît DKIM, quelles sont les bonnes pratiques (section 5) ? La plupart des MLM procèdent à une forme d'authentification, souvent plutôt faible (par exemple, une vérification du From: vis-à-vis de la liste des abonnés). Avec DKIM, on pourrait avoir apparaître de nouvelles politiques, plus sûres (par exemple une exigence que le message soit signé et que le domaine indiqué par d= soit celui du champ From:). Évidemment, aujourd'hui, très peu de messages seront signés, donc le gérant du MLM va devoir décider quoi faire des autres. En tout cas, une vérification positive est bon signe et le RFC demande que le MLM ajoute dans ce cas un en-tête indiquant une authentification réussie (RFC 5451).

Et que faire des signatures DKIM existantes, déjà présentes lorsque le MLM reçoit le message original ? Si le MLM est sûr de ne rien changer au message, il peut laisser ces signatures, qui apportent une information intéressante. Mais s'il modifie le message, il est sans doute plus prudent de les supprimer, pour éviter tout risque qu'un message arrive au destinataire final avec une signature invalide (ce que certains destinataires considéreront, en violation de la norme DKIM, comme une incitation à jeter le message).

Ensuite, il reste une autre décision à prendre pour le MLM : doit-il apposer sa propre signature ? Le RFC le recommande fortement, afin de bien marquer que le gérant du MLM accepte sa responsabilité pour le message qu'il transmet. Le risque est évidemment que certains destinataires interprètent cette signature comme signifiant que le message a été authentifié dès le début. Toutefois, DKIM en lui-même ne peut rien faire dans ce cas : il y aura toujours des gens pour mal interpréter une signature et lui attribuer un poids qu'elle n'a pas.

Continuons le trajet du message : nous approchons de la fin avec les conseils aux vérificateurs. En gros, le RFC demande que ceux-ci traitent les messages des listes comme n'importe quel autre message (dans l'état actuel du déploiement des RFC 2919 et RFC 2369, il n'y a pas de moyen fiable de savoir si un message est passé par un MLM).

Les listes de diffusion de l'IETF signent tous les messages sortants, depuis juillet 2011, avec d=ietf.org (les signatures originelles sont apparemment retirées). Barry Leiba a bien résumé ce que cela apporte : « What it does is allow you to assure yourself that the message was, indeed, from an IETF mailing list (well, from an IETF email server), and that it wasn't that someone tried to spoof that. That, in turn, allows you to confidently increase your trust that the message is not spam in proportion to your confidence in the IETF's spam-filtering capabilities. ». Voici une telle signature :

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ietf.org; s=ietf1;
        t=1311614276; bh=qLpIZcZ8XeP5xTrgVPRjnXlZjXWiz9DqXpACtarsL0Q=;
        h=Date:From:To:Subject:Message-ID:MIME-Version:List-Id:
        List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe:
        Content-Type:Content-Transfer-Encoding:Sender;
        b=ppseQobrat1rQ+Brsy2LSpMAA79YgaFJ7PK2EG1N4w0zS2IZBqDQiXYHJxG/wv4wl
        GOd42GtThBVxB5BmBhkTn8M1Rqz+ZhW2pLPlcI1zHcmLmJHLMt1wC6R3wiCi4bipVd
        CszNeb58HSYGNDQmvnW9dAxi38pL/kjunJTpmVT4=

Le RFC mentionnait à plusieurs reprises les MLM qui comprennent DKIM. À ma connaissance, aujourd'hui, il n'y a que Sympa dans ce cas. DKIM y a été introduit dans la version 6.1. Quelqu'un connaît d'autres implémentations ?

Un bon article de fond en français sur la coexistence entre DKIM et les listes de diffusion est l'article de Serge Aumont aux JRES, « DKIM et les listes de diffusion ». Sinon, concernant les modifications d'en-tête par les MLM, un article toujours utile, quoique centré sur les modifications du Reply-To:, est « "Reply-To" Munging Considered Harmful ».

Merci à Serge Aumont pour sa relecture.


Téléchargez le RFC 6377


L'article seul

RFC 6376: DomainKeys Identified Mail (DKIM) Signatures

Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : D. Crocker (Brandenburg InternetWorking), T. Hansen (AT&T Laboratories), M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dkim
Première rédaction de cet article le 22 Septembre 2011


Le courrier électronique, on le sait, n'offre, en natif, aucun mécanisme d'authentification des utilisateurs. Il est donc assez facile d'envoyer un courrier prétendant venir de Bill.Gates@microsoft.com. DKIM, spécifié dans notre RFC, est la dernière tentative de combler ce manque. (La première version de DKIM était normalisée dans le RFC 4871. Cette nouvelle version n'apporte pas de changements cruciaux.)

Notons d'abord que, si le courrier électronique, tel que décrit dans les RFC 5321 ou RFC 5322, ou bien leurs prédécesseurs, n'offre pas d'authentification des utilisateurs, ce n'est pas parce que leurs concepteurs étaient imprévoyants ou trop confiants dans la nature humaine. C'est tout simplement parce que le problème est très complexe, ne serait-ce que parce qu'il n'existe pas de fournisseur d'identité unique sur Internet, qui pourrait jouer le rôle que joue l'État avec les papiers d'identité.

Mais l'absence d'authentification devient de plus en plus regrettable, d'autant plus qu'elle est activement exploitée par les spammeurs et les phisheurs pour leurs entreprises malhonnêtes. Non seulement il est difficile de retrouver le véritable envoyeur d'un message, mais une personne tout à fait innocente peut voir son identité usurpée. Ces problèmes de sécurité sont documentés dans le RFC 4686.

De nombreuses tentatives ont eu lieu pour tenter de traiter ce problème. Certaines ont connu un déploiement non négligeable comme PGP (normalisé dans le RFC 4880), surtout connu pour ses services de chiffrement mais qui peut aussi servir à l'authentification.

PGP est surtout utilisé dans des environnements à forte composante technique, au sein de groupes d'experts qui se connaissent. D'autres protocoles ont tenté de traiter le problème de l'authentification de la masse d'utilisateurs de Hotmail ou de Wanadoo.

SPF (normalisé dans le RFC 4408) a été condamné par l'hostilité de la plupart des gros acteurs.

DKIM aborde le problème différemment. Comme SPF, il vise surtout à authentifier le domaine dans l'adresse électronique, en d'autres termes à garantir que le courrier vient bien de microsoft.com, laissant à Microsoft le soin de dire si la partie gauche (Bill.Gates) est authentique ou pas. En deux mots, DKIM permet à un domaine de proclamer qu'il a une part de responsabilité dans un message, et donc que ce domaine peut répondre dudit message. On trouve une introduction générale à DKIM dans le RFC 5585 et une réfutation de beaucoup d'erreurs à propos de DKIM en « The truth about: Trust and DKIM ».

Mais, contrairement à SPF, DKIM ne procède pas par énumération des adresses IP des MTA autorisés à émettre du courrier pour le compte d'un domaine mais par signature cryptographique.

Le principe de DKIM est le suivant (les exemples sont tirés de l'excellente annexe A du RFC). Un message émis ressemble à :

   From: Joe SixPack <joe@football.example.com>
   To: Suzie Q <suzie@shopping.example.net>
   Subject: Is dinner ready?
   Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT)
   Message-ID: <20030712040037.46341.5F8J@football.example.com>

   Hi.

   We lost the game. Are you hungry yet?

   Joe.

DKIM (qui peut être installé dans le MUA mais sera en général plutôt dans le MTA, cf. section 2.1 et annexe B) le signe et ajoute un en-tête DKIM-Signature (section 3.5 pour sa syntaxe) :

   DKIM-Signature: v=1; a=rsa-sha256; s=brisbane; d=example.com;
         c=simple/simple; q=dns/txt; i=joe@football.example.com;
         h=Received : From : To : Subject : Date : Message-ID;
         bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
         b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqOB
           4nujc7YopdG5dWLSdNg6xNAZpOPr+kHxt1IrE+NahM6L/LbvaHut
           KVdkLLkpVaVVQPzeRDI009SO2Il5Lu7rDNH6mZckBdrIx0orEtZV
           4bmp/YzhwvcubU4=;
   Received: from client1.football.example.com  [192.0.2.1]
         by submitserver.example.com with SUBMISSION;
         Fri, 11 Jul 2003 21:01:54 -0700 (PDT)
   From: Joe SixPack <joe@football.example.com>
   To: Suzie Q <suzie@shopping.example.net>
   Subject: Is dinner ready?
   Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT)
   Message-ID: <20030712040037.46341.5F8J@football.example.com>

   Hi.

   We lost the game. Are you hungry yet?

   Joe.

L'en-tête en question spécifie l'algorithme de chiffrement utilisé (ici SHA-256 et RSA), le domaine signant (ici example.com), un sélecteur (ici brisbane) qui servira à sélectionner la bonne clé (section 3.1), les en-têtes effectivement signés (ici Received : From : To : Subject : Date : Message-ID, cf. la section 5.4 sur le choix des en-têtes à signer), la signature elle-même et l'identité de l'émetteur (ici joe@football.example.com). (La différence entre le domaine, identifié par d= et l'« identité » indiquée par i= est subtile.)

L'identité est indiquée dans la signature pour éviter les longs débats sur l'identité la plus pertinente parmi toutes celles présentes dans un message (cf. le RFC 4407 pour un des exemples d'algorithme qui croit naïvement qu'il existe une et une seule bonne identité). Le signeur n'est donc pas forcément l'émetteur (section 1.2). Notre RFC note que le MUA doit en tenir compte et doit afficher l'adresse qui est authentifiée, pas seulement celle qui se trouve dans le champ From: et qui peut être différente.

Le programme qui veut vérifier la signature (en général un MTA mais cela peut être le MUA) va devoir récupérer la clé de signature. DKIM ne souhaitant pas dépendre des lourdes et chères autorités de certification, la clé est récupérée via le DNS (section 3.6.2 ; d'autres méthodes que le DNS sont en cours de normalisation mais ça n'avance pas). Pour le message ci-dessus, la requête DNS sera brisbane._domainkey.example.com et un enregistrement DNS de type TXT contiendra la clé. Pour voir une clé réelle, vous pouvez taper dig TXT beta._domainkey.gmail.com. ou dig TXT ietf1._domainkey.ietf.org. DKIM n'impose pas d'utiliser DNSSEC et la sécurité de la clé ainsi ramassée peut être faible (cf. section 8.5 : DKIM ne prétend pas être aussi fort que PGP).

Un des problèmes difficiles en cryptographie est que les messages sont souvent modifiés en cours de route. Par exemple, un logiciel imposé par le direction de l'entreprise va ajouter automatiquement un stupide message pseudo-légal comme « Ce message e-mail et les pièces jointes sont transmis à l'intention exclusive de ses destinataires et sont confidentiels et/ou soumis au secret professionnel. Si vous recevez ce message par erreur, merci de le détruire et d'en avertir immédiatement l'expéditeur par téléphone ou par mail. Toute utilisation de ce message non conforme à sa destination, toute diffusion ou toute publication, totale ou partielle, est interdite, sauf autorisation. L'intégrité de ce message n'étant pas assurée sur Internet, nous ne pouvons être tenu responsables de son contenu. » (notons que le dernier point devient faux avec DKIM). Ou bien une liste de diffusion va mettre des instructions de désabonnement (pour ces listes, voir aussi le RFC 6377). DKIM traite ces problèmes avec deux méthodes : une canonicalisation (section 3.4 du RFC) du message (plusieurs algorithmes sont disponibles, plus ou moins violents) pour limiter les risques qu'une modification triviale ne fausse le calcul de la signature et l'option l= qui permet d'indiquer sur quelle distance le message est signé. Si on indique l=1000, seuls les mille premiers octets seront signés et une liste pourra ajouter un message automatiquement à la fin, cela n'invalidera pas la signature. (Cette technique est déconseillée, voir la section 8.2.)

Malheureusement, DKIM encourage également (section 5.3) à remplacer les caractères codés sur 8 bits (comme l'UTF-8 ou le Latin-1) par des horreurs comme le Quoted-Printable, pour limiter les risques qu'une conversion automatique en Quoted-Printable, comme le font certains MTA, n'invalide la signature. Des années d'efforts pour faire passer les caractères 8-bits dans le courrier sont ainsi négligées.

DKIM a nécessité la création de plusieurs registres à l'IANA (section 7) comme le registre des méthodes pour récupérer la clé (aujourd'hui, seulement le DNS).

Parmi les limites de DKIM (qui sont celles de beaucoup de solutions de sécurité, un domaine complexe où il faut faire beaucoup de compromis), il faut aussi se rappeler qu'un attaquant actif peut tout simplement retirer complètement une signature. Tant que les domaines ne publient pas leur politique de sécurité (en suivant le RFC 5617) et donc annoncent « Nous signons toujours », cette attaque passera inaperçue.

Quels sont les changements depuis la première version de DKIM, normalisée dans le RFC 4871 ? L'annexe E les résume. Premier point, les changements sont mineurs : comme le note l'annexe C.2, les anciennes et nouvelles implémentations de DKIM peuvent communiquer sans problèmes. Mais la sortie de ce nouveau RFC ne s'est pas faite sans mal. Il y avait des désaccords sérieux sur l'avis à donner en terme de quels en-têtes devraient être signés, sur le lien entre le domaine signant et les autres domaines de l'en-tête (typiquement celui dans le from:), la façon de traiter les attaques par ajout d'en-têtes (non couverts par la signature originale), etc. Beaucoup d'erreurs ont été détectées dans le RFC 4871 et corrigées ici, la plus grosse étant celle qui avait fait l'objet d'une mise à jour d'urgence dans le RFC 5672, désormais inutile. D'autre part, le nouveau RFC comporte davantage de texte d'introduction et d'architecture. Enfin, l'option de signature g= (qui contrôlait la granularité de la clé) a été abandonnée. Il y a aussi une différence complète entre les deux RFC, en ligne.

Aujourd'hui, tous les messages sortant de Gmail sont signés avec DKIM et des implémentations de DKIM existent pour plusieurs logiciels (comme le DKIM milter de sendmail). Le rapport d'implémentation du RFC 4871 en donne une bonne liste. Mais peu de domaines signent et encore moins de domaines vérifient les signatures aujourd'hui (le RFC 5863 discute les questions de déploiement).

Enfin, notons que DKIM est une technologie d'authentification, pas d'autorisation. Cette distinction est cruciale. DKIM peut prouver que le message vient bien de Nicolas.Sarkozy@elysee.fr (plus exactement, DKIM peut dire que le message a bien été approuvé par elysee.fr), il ne peut pas dire si la personne en question est digne de confiance ou si elle va réellement se préoccuper de « la France qui se lève tôt ».


Téléchargez le RFC 6376


L'article seul

RFC 6369: ForCES Implementation Experience Draft

Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : E. Haleplidis, O. Koufopavlou, S. Denazis (University of Patras)
Pour information
Première rédaction de cet article le 21 Septembre 2011


Le protocole ForCES (Forwarding and Control Element Separation) sert à la communication entre les éléments d'un même routeur. Il permet à la « tête » du routeur (le CE Control Element) de donner des instructions aux « jambes » (les FS Forwarding Element), par exemple de dire où envoyer le trafic pour 2001:db8::/32. Le fait que ce protocole soit normalisé pourrait permettre dans le futur d'acheter des routeurs en plusieurs parties, par exemple un PC avec du logiciel libre pour le CE et des ASIC matériels spécialisés pour les FE, le tout communiquant dans la joie. Ce RFC fait le court bilan d'une des équipes qui a le plus travaillé à la programmation de ForCES, à l'Université de Patras.

Le cahier des charges de ce système figure dans le RFC 3654. ForCES est normalisé dans le RFC 5810 et son architecture est décrite dans le RFC 3746. Il a déjà fait l'objet d'un rapport d'interopérabilité dans le RFC 6053, vérifiant que les trois mises en œuvre de ForCES coopéraient correctement. L'une de ces mises en œuvre était celle de l'Université de Patras. Les auteurs de cette implémentation tirent, dans ce nouveau RFC, les leçons de leur expérience, afin qu'elle puisse profiter à d'autres.

Petit rappel de ForCES (section 1) : le CE (Control Element) est la partie intelligente du routeur, celle qui fait tourner les protocoles compliqués comme OSPF. Le FE (Forwarding Element) peut être réalisé en logiciel mais, sur les routeurs haut de gamme, il s'agit plus souvent d'un circuit matériel, puisqu'il doit faire passer des millions de paquets à la seconde. Le LFB (Logical Function Block) est une fonction dans le FE, que le CE contrôle. Par exemple, la fonction « comptage des paquets » (à des fins de surveillance et de statistique) est un LFB. Un LFB fait partie d'une classe, qui a des instances (un routeur a souvent plusieurs exemplaires d'un LFB de chaque classe). Pour décrire un LFB, on utilise le modèle du RFC 5812. Le protocole ForCES gouverne la communication entre CE (le maître, qui donne des ordres) et FE (l'esclave, qui obéit). S'il y a des discussions entre CE ou bien entre FE, elles se font en dehors de ForCES. De même, le mécanisme par lequel sont configurés CE et FE n'est pas normalisé. Le protocole ForCES peut être transporté entre FE et CE de diverses manières, mais celle recommandée est le transport du RFC 5811.

Le RFC suit l'architecture de ForCES (section 3). La configuration initiale du FE et du CE (non spécifié par ForCES) doit permettre de fixer l'identificateur de chaque élément, le transport utilisé et l'adresse IP (si le transport se fait sur IP).

Le transport standard de ForCES, normalisé dans le RFC 5811, utilise SCTP. Lors des tests d'interopérabilité, ce transport avait même été utilisé entre un site en Chine et un en Grèce mais, évidemment, dans un routeur réel, les distances sont moins longues. (Comme ForCES permet de séparer FE et CE, ils ne sont pas forcément dans la même boîte, et il peut même y avoir des choses bizarres, comme un pare-feu entre eux.) Bien moins connu que son concurrent TCP, SCTP pose un problème au programmeur : les bibliothèques existantes ne permettent pas toujours de l'utiliser simplement. La section 4 contient un tableau des disponibilités pour C, C++ et Java. Par exemple, pour Java sur Windows, il n'y a pas grand'chose à attendre. (Les auteurs ont également eu des difficultés avec un autre problème Java, la gestion des types non signés, pour laquelle ils recommandent Java Unsigned Types.)

Le protocole n'est pas trivial à programmer. En effet, la liste des classes de LFB possibles n'est pas figée. De nouveaux LFB peuvent apparaître à tout moment. En outre, un message peut comporter plusieurs opérations, et plusieurs LFB par opération. C'est bien sûr une... force du protocole (il est très puissant et complet) mais cela le rend plus complexe. Il est donc très difficile de créer du code générique, capable de traiter tous les messages. C'est sans doute la principale difficulté que rencontre l'implémenteur de ForCES. La section 3.4 fournit des pistes possibles, ainsi que des algorithmes d'encodage et de décodage des messages. Les informations dans le message pouvant être emboîtées, l'utilisation de la récursion est recommandée.


Téléchargez le RFC 6369


L'article seul

RFC 6366: Requirements for an Internet Audio Codec

Date de publication du RFC : Août 2011
Auteur(s) du RFC : JM. Valin (Mozilla), K. Vos (Skype Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF codec
Première rédaction de cet article le 7 Septembre 2011


Début 2010, l'IETF avait lancé un travail pour la normalisation d'un codec libre pour l'Internet, c'est-à-dire qui ne serait pas plombé par des brevets ou autres appropriations intellectuelles et pourrait donc être utilisé par n'importe quel protocole Internet. Ce RFC est le premier produit par le groupe de travail, et contient le cahier des charges du futur codec.

Comme toujours avec ce groupe de travail, cela n'a pas été sans mal. Par exemple, le RFC mentionne des codecs « à battre », c'est-à-dire où le nouveau codec doit être meilleur que ceux-ci, pour être pris en considération. Certains demandaient que les codecs à battre soient uniquement ceux qui sont déjà à peu près libres, d'autres voulaient qu'on compare le nouveau codec avec tous ses concurrents, même plombés. Vue la difficulté de la tâche technique, une telle comparaison aurait sérieusement menacé le projet. Finalement, les codecs libres ont été pris comme référence, mais avec mention des autres, en demandant que, à défaut de les battre, le nouveau codec ne soit pas trop pire qu'eux (section 5.2).

Le but est donc d'avoir un codec libre pour les applications Internet, comme la téléphonie sur IP, la téléconférence, l'exécution de musique en temps réel (concert où les musiciens ne sont pas au même endroit), etc. La section 3 liste, pour chaque application envisagée, ses caractéristiques propres. Car certaines applications sont bien plus exigeantes que les autres. Commençons par l'ordinaire téléphonie à deux. Un codec à large bande (16 kHz) est nécessaire, mais le cahier des charges ajoute la possibilité de fonctionner avec seulement 8 kHz, par exemple pour les vieux téléphones. En large bande, la consommation de capacité réseau attendue va de 12 à 32 kb/s. La latence imposée par le codec doit rester inférieure à 40 ms, mais 25 ms sont souhaitées. (Pour des détails sur les bandes et les latences, voir la section 5.1 du RFC.) Pas besoin d'être haute-fidélité, encore que le RFC note que le codec ne doit pas massacrer les musiques d'attente au point de les rendre désagréables.

Plus exigeantes, la conférence (ou le bavardage en temps réel entre joueurs d'une même partie), où plusieur voix se mêlent. Comme ces applications ont en général davantage de capacité réseau, le codec doit cette fois fonctionner à plus de 24 kHz, pour un débit de 32 à 64 kb/s. Comme les participants à une conférence ont souvent les mains occupées par autre chose et ne tiennent pas le téléphone près de la bouche ou de l'oreille, les problèmes d'écho sont plus sévères qu'en conversation à deux. La latence doit donc être encore plus basse (moins de 30 ms, avec le souhait de descendre à 10), car elle influence la qualité de la suppression d'écho.

Mais, surtout, un système de conférence va mixer les voix de plusieurs participants. Le codec ne doit donc pas gêner le mixage.

Les applications dites de téléprésence sont encore plus demandeuses en terme de qualité, pour arriver à reproduire quelque chose qui ressemble à la présence physique.

Encore plus dur pour un codec, la téléopération (commande d'un robot à distance, par exemple). Si le retour d'information est par la voix (l'opérateur entend ce qui se passe près du robot), une très faible latence est nécessaire.

Et la diffusion de musique en train d'être jouée par plusieurs musiciens ? Des mesures faites avec des musiciens imposent une latence totale de moins de 25 ms (50 si on est prêt à accepter de sérieux problèmes de synchronisation dans l'orchestre). Compte tenu de la latence des autres composants (à commencer par le réseau), cela contraint la latence propre au codec à rester en dessous de 10 ms. Chaque milli-seconde gagnée dans le codec nous donne 200 km de distance en plus, compte-tenu de la vitesse de la lumière dans la silice de la fibre optique. On peut avoir un concert où les musiciens sont dans le même pays, mais pas s'ils sont dispersés aux quatres coins du monde. Et, pour cette application, il faut évidemment une grande qualité, donc un débit soutenu (facilement 128 kb/s).

Il y a bien sûr d'innombrables autres applications où un codec audio est utile mais ce tour d'horizon couvre bien les exigences essentielles.

Le futur codec est conçu avant tout pour être utilisé sur l'Internet. Il s'agit d'un environnement difficile pour un codec audio. La section 4 du RFC liste les contraintes qui découlent de cet environnement. D'abord, les pertes de paquets sont un phénomène normal sur l'Internet et le codec doit y réagir proprement (voir section 5.3). Notamment, lorsque les paquets recommencent à arriver après une ou plusieurs pertes :

  • Il faut que le codec puisse lire les paquets, sans avoir besoin d'informations contenues dans les paquets précédents (qui sont perdus), comme demandé par le RFC 2736,
  • Il faut que le décodeur puisse se resynchroniser rapidement.

Cela implique que la taille d'un paquet soit inférieure à la MTU (pour éviter la fragmentation : la perte d'un des fragments entraîne celle du paquet original tout entier), et qu'il n'y ait pas d'information implicite, car contenue dans un paquet précédent. Par exemple, si on change les paramètres d'encodage, les paquets suivants ne doivent pas considérer que le changement a été reçu : il pouvait être dans le paquet perdu. Les paramètres permettant le décodage doivent donc être dans chaque paquet (ou pouvoir être récupérés rapidement).

Cela n'interdit pas au décodeur de faire des prédictions sur les paquets suivants mais il doit pouvoir les corriger rapidement en cas de pertes. En gros, un codec résistant aux pertes de paquet doit être conçu comme un compromis entre l'efficacité (qui pousse à ne pas répéter les informations et à faire de chaque paquet un delta du précédent) et la robustesse (qui pousse à faire des paquets autonomes, pouvant être interprétés même si on a perdu les précédents).

Autre particularité de l'Internet, c'est un réseau qui fait « au mieux », et qui ne garantit pas la capacité réseau disponible. Le codec doit donc s'ajuster dynamiquement (augmentant et diminuant son débit), sans que cela ne s'entende après le décodage.

Les protocoles de la famille TCP/IP fournissent des mécanismes qui peuvent aider le codec à prendre ses décisions, comme l'ECN du RFC 3168, et il est donc recommandé des les utiliser.

Enfin, le nouveau codec arrivera dans un monde où il existe déjà des protocoles applicatifs qui ont besoin de lui, et il devra donc s'interfacer gentiment avec ces protocoles comme RTP (RFC 3550 et RFC 2736). Si le codec nécessite de négocier des paramètres entre les deux machines qui communiquent, cette négociation devra utiliser les protocoles de signalisation existants comme SDP (RFC 3261 et RFC 4566) dans le cas de SIP, et Jingle (XEP-O167) dans le cas de XMPP.

La section 5 en vient aux exigences détaillées. Le but est que le rapport entre la qualité du son et le débit utilisé soit meilleur qu'avec les codecs existants comme Speex, iLBC (RFC 3951) et G.722.1 (norme UIT du même nom). Ces trois codecs sont a priori implémentables sans payer de royalties mais seul Speex est vraiment libre et c'est donc le seul que le nouveau codec doit battre. En outre, il serait souhaitable que le nouveau codec fasse ex-aequo avec AMR-NB en bande étroite (8 à 16 kb/s) et AMR-WB en bande large (12 à 32 kb/s). Cette qualité doit être mesurée pour plusieurs langues, y compris les langues à tons pour lesquelles une bonne qualité de son est impérative.

À noter que la seule exigence est de faire mieux que ces codecs : le RFC ne demande aucune interopérabilité avec eux (section 6.10).

Concernant la résistance aux pertes de paquets, le codev devra bien se comporter jusqu'à 5 % de pertes et la voix rester compréhensible jusqu'à 15 % de pertes. Comme la qualité ne dépend pas que du pourcentage global de pertes, mais aussi de leur répartition (continue ou au contraire en brusques trous noirs), la qualité devra être évaluée avec des traces réelles, et avec des répartitions de pertes telles qu'on les observe dans un accès ADSL typique.

Les codecs peuvent être gourmands en ressources machines, par exemple exiger un processeur très rapide. Or, il devra être mis en œuvre sur une grande variété de machines (de l'ordinateur généraliste au petit téléphone), qui ne disposeront parfois pas de FPU et dont les éventuels DSP auront des caractéristiques très différentes. Le RFC demande donc que le codec puisse être implémentable en virgule fixe. Du point de vue quantitatif, notre RFC exige une limite à la consommation de processeur. Pour un x86 récent, l'encodage et le décodage d'un signal en mono ne devrait prendre que 40 MHz en bande étroite (soit 2 % du temps d'un cœur à 2 Hz), et 200 MHz en très large bande. Ces chiffres peuvent paraître bas mais il faut se rappeler que le codec va aussi tourner sur des machines dont le processeur est bien plus lent que celui du PC de bureau typique.

Il est facile d'ammonceler dans un cahier des charges des exigences irréalistes, et ensuite de laisser les pauvres implémenteurs se débrouiller. Ce problème est fréquent dans les SDO où les participants à la normalisation sont des bureaucrates et des politiciens qui ne feront pas le travail de mise en œuvre eux-mêmes. L'IETF se méfie traditionnellement de ce risque et une des méthodes utilisées pour s'en préserver est l'implémentation de référence, une mise en œuvre du logiciel réalisée pour s'assurer que c'est possible, et qui est souvent publiée en même temps que le RFC. Notre RFC encadre cette implémentation de référence du futur codec en lui interdisant de tirer profit de fonctions spécifiques de tel ou tel matériel : elle doit être le plus portable possible. Par exemple, le RFC interdit de dépendre de l'arithmétique saturée, pour pouvoir tourner sur les processeurs qui n'ont pas cette fonction comme certains ARM. Par contre, les « vraies » implémentations, elles, auront tout intérêt à exploiter à fond les particularités du matériel sur lesquelles elles tournent.

Outre la consommation de processeur, le nouveau codec ne doit pas être trop encombrant en mémoire (code et données), pour pouvoir être lancé sur des systèmes embarqués. Pour les données (l'état à garder en mémoire pour faire fonctionner le codec), le RFC met une limite à 2*R*C octets, où R est le taux d'échantillonage et C le nombre de canaux.

Et ce n'est qu'une petite partie des problèmes auxquels un codec sur l'Internet fait face. La section 6 charge la barque avec diverses considérations et des souhaits (les exigences précédentes étaient considérées comme impératives). Par exemple, s'il y a mixage (pour une téléconférence, par exemple), il serait bien de limiter le coût de l'opération. L'implémentation naïve du mixage est de décoder tous les flux audios, les mélanger et réencoder le résultat. Une approche où un décodage complet ne soit pas nécessaire est souhaitée. Autre souhait : un bon support de la stéréo, là encore en évitant l'approche naïve, qui consiste à encoder séparement les deux canaux. Comme ceux-ci ont probablement beaucoup de redondances, cette propriété devrait être utilisée pour limiter le débit utilisé. Il serait également très bien de gérer les erreurs dans les paquets (bits dont la valeur a changé). La plupart des applications Internet ne le font pas car le phénomène est rare. En général, un paquet arrive intact ou n'arrive pas. Mais des transformations non désirées se produisent parfois (avec des protocoles comme UDP Lite, il n'y a pas de somme de contrôle, cf. RFC 3828) et le RFC demande que la question soit étudiée, en insistant que, dans tous les cas, c'est la robustesse du codec aux pertes de paquets qui est prioritaire.

Plus rigolo, et pour les amateurs de polars, la section 6.9 demande que le codec n'élimine pas et ne dégrade pas le bruit de fond des appels : ce bruit peut servir à identifier l'origine d'un appel, et, dans le cas d'appels au 112, cela peut être crucial. Un bon exemple figure dans le génial film de Kurosawa, « Entre le ciel et l'enfer », où policiers et employés du tramway arrivent à reconnaître près de quelle ligne de tramway se trouve le criminel qui appelle, juste en écoutant le bruit de fond, et en remarquant un léger bruit, caractéristique d'un endroit où le câble est abîmé par un accident récent. (Les cinéphiles savent qu'il y a un exemple plus léger dans « La double vie de Véronique ».)

Restent les traditionnelles questions de sécurité : la section 7 rappelle l'évidence (le décodeur doit faire attention aux attaques par débordement de tampons) mais aussi l'importance d'avoir une consommation de ressources bornée : quels que soient les paquets entrants, le temps de processeur utilisé et la mémoire consommée ne doivent pas croître sans limites (autrement, une DoS serait possible en envoyant des paquets créés pour cela).

Plus subtil, le problème de la fuite d'informations lorsque la communication est normalement protégée par du chiffrement. Des attaques ont déjà été décrites où des informations importantes sur la conversation pouvaient être extraites d'un flux audio chiffré (« Spot me if you can: Uncovering spoken phrases in encrypted VoIP conversations » et « Phonotactic Reconstruction of Encrypted VoIP Conversations: Hookt on fon-iks »). Le codec peut compliquer certaines de ces attaques, par exemple en ayant un mode où le débit est constant, quelle que soit la conversation.


Téléchargez le RFC 6366


L'article seul

RFC 6365: Terminology Used in Internationalization in the IETF

Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : P. Hoffman (VPN Consortium), J. Klensin
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 12 Septembre 2011


L'internationalisation des protocoles développés par l'IETF est depuis quinze ans un des sujets chauds de cette organisation. Réussir à rendre tous les protocoles Internet adaptés aux différentes langues, écritures et cultures nécessite d'avoir un socle linguistique commun et c'est le rôle de ce RFC, qui décrit la terminologie en usage à l'IETF. Il remplace le RFC 3536 dans le rôle du texte « l'internationalisation pour les débutants ». Le texte est long car le sujet est complexe.

Cette terminologie est d'autant plus importante que les discussions sur le sujet sont souvent victimes d'un vocabulaire flou et mal utilisé. Ainsi, on voit parfois apparaître le terme de « caractère latin » sans que celui-ci soit bien défini. Seulement ASCII ou bien également les caractères composés, utilisés par exemple en français ? Autre exemple, à l'ICANN, les discussions sur les IDN sont souvent rendues incompréhensibles par une confusion fréquente entre des concepts aussi différents que « langue » et « écriture ». Si vous lisez dans un article ou un rapport des termes absurdes comme « noms de domaines multilingues », faites lire ce RFC 6365 à l'auteur de ce texte, il en a besoin...

Ce RFC est en anglais et fixe une terminologie anglophone. Dans mon article, je vais donner le terme anglais défini et la traduction française que j'utilise (sans consulter les normes officielles, qui ne sont pas toujours de grande qualité et souvent faites par des gens qui ignorent le domaine). Mais le lecteur doit bien être conscient du fait qu'il n'existe pas forcément de terminologie standard en français. Même en anglais, le consensus est loin d'exister sur tous ces termes, et le caractère ultra-sensible des questions de langue n'arrange rien.

Petit rappel de l'objectif poursuivi, en section 1 : comme le dit le RFC 2277, document fondateur, l'internationalisation concerne les humains, pas les protocoles. On ne va donc pas traduire le GET de HTTP. Par contre, lorsqu'un protocole manipule des chaînes de caractères qui vont être lues ou écrites par des humains, il faut que cela soit possible quelle que soit la langue ou l'écriture utilisée. Cette politique de l'IETF est donc différente de celle, qu'on entend souvent à l'ICANN, comme quoi tout le monde n'a qu'à parler anglais, langue internationale de toute façon.

Avoir un vocabulaire commun est évidemment essentiel pour les discussions au sein de l'IETF, et pour la qualité et l'homogénéité des documents produits (les RFC). Ce RFC 6365 sert aussi de tutoriel sur l'internationalisation en expliquant les concepts de base aux membres de l'IETF, un public d'ingénieurs qui n'est pas forcément très sensible à cette question. Notre RFC rappelle ainsi que, dans beaucoup de groupes de travail de l'IETF, lorsque quelqu'un soulève la question de l'internationalisation du protocole en cours de développement, les réponses « faut-il vraiment s'en préoccuper ? » sont souvent nombreuses. Il y a donc un certain fossé à combler.

Voyons maintenant les définitions générales (section 2). Le RFC ne pouvait pas tout couvrir et un des plus grands débats dans le groupe avait été l'étendue de la liste des termes à définir. Le choix a été fait de se restreindre, pour augmenter la probabilité que les non-spécialistes de l'internationalisation lisent le texte. Je ne reprends ici qu'une partie des termes, ceux que je trouve indispensables, ou bien dont la définition est mal connue.

Une langue (language) est une façon de communiquer entre humains, notamment par la parole ou l'écriture. Lorsqu'une forme écrite et une forme parlée existent pour une langue, elles sont parfois très proches... et parfois très distantes. Ce terme n'inclus pas les langages de programmation.

Une écriture (script) est un ensemble de caractères graphiques qui sont utilisés pour la forme écrite d'une ou de plusieurs langues. C'est le cas de l'écriture latine, cyrillique, arabe (attention dans ce cas, arabe est également le nom d'une langue) et han. L'IETF s'occupant surtout de l'écrit (la langue parlée peut être transmise par des protocoles comme RTP mais elle n'est typiquement pas interprétée par ces protocoles), presque toujours, les protocoles IETF s'occupent d'écritures, pas de langues. C'est ainsi que les IDN sont des noms de domaines multi-écritures et surtout pas multilingues. (Le RFC note explicitement que « multilingue » est un de ces termes flous et passe-partout, qu'il faut éviter.)

(La définition de l'internationalisation dans notre RFC est d'ailleurs modeste, « permettre ou améliorer l'utilisation de caractères non-ASCII dans les protocoles IETF », par rapport celle du W3C, plus ambitieuse, « permettre l'adaptation facile à n'importe quelle langue, écriture ou culture ».)

La relation entre les langues et les écritures est complexe : il y a beaucoup moins d'écritures que de langues et la plupart des écritures peuvent servir à plusieurs langues. D'autre part, si certaines langues n'ont jamais été écrites qu'avec une seule écriture (le français avec l'écriture latine, le russe avec la cyrillique), d'autres ont changé, comme le turc ou le vietnamien. L'effondrement de l'URSS a eu entre autres pour conséquence l'abandon du cyrillique par plusieurs langues comme le mongol. Autre exemple, le malais est passé récemment (et la transition n'est pas terminée) du jawi à l'alphabet latin.

On voit parfois le terme alphabet pour désigner une écriture mais, comme toutes ne sont pas alphabétiques (cf. section 4.1), ce terme est plutôt à éviter.

Un système d'écriture (writing system) est un ensemble de règles pour utiliser une écriture dans le cas d'un langage donné. Ainsi, le français et l'anglais utilisent la même écriture, mais avec des règles différentes (par exemple pour la ponctuation).

Un caractère (character) est un membre de l'ensemble des éléments qui servent à représenter les données écrites. Le terme est plus flou qu'il n'y parait car il existe des tas de cas qui défient la classification comme le digramme « ll » du catalan. En anglais, les informaticiens disent souvent char au lieu de character, vu que c'est le type de données utilisé dans plusieurs langages de programmation. En tout cas, un caractère n'est pas une représentation graphique, un glyphe. Par exemple, il n'y a qu'un seul caractère A alors qu'il en existe de nombreuses représentations possibles (il y a un excellent article sur ce sujet dans le livre de Hofstadter, « Metamagical Themas »).

En parlant de glyphe, sa définition dans le RFC est « l'image d'un caractère rendue sur une surface ». On aura donc un glyphe différent si on affiche avec une résolution différente. Unicode a une autre définition, basée plutôt sur l'encodage d'une police particulière, et où le glyphe est donc le même quel que soit le périphérique de sortie. Dans la définition d'Unicode, chaque glyphe a un code de glyphe, qui est un index dans une police donnée (et qui n'est pas standard : deux auteurs de polices peuvent utiliser des codes de glyphes différents).

Un jeu de caractères (repertoire) est simplement un ensemble de caractères, rigoureusement défini (c'est par exemple à ce stade qu'on décide si œ est un seul caractère ou deux).

Un jeu de caractères codé (Coded Character Set, CCS) est un ensemble de règles qui définissent un jeu de caractères et une représentation codée (typiquement, par un nombre entier unique par caractère). Unicode ou ISO-8859-6 définissent un CCS.

L'encodage (character encoding scheme) est la représentation en machine des caractères, c'est-à-dire la définition de quelle chaîne de bits représente tel caractère. Si des normes comme ISO 8859 ne définissent qu'un seul encodage possible, Unicode en a plusieurs (le plus connu étant UTF-8, qui est le protocole par défaut dans l'Internet, cf. RFC 2277).

Le transcodage (transcoding) est la traduction d'un encodage dans un autre, comme le font les outils Unix iconv ou recode.

Je laisse en anglais le terme charset car il est purement technique et n'est pas la même chose qu'un jeu de caractères tel que défini plus haut. Ce terme de charset est très utilisé dans les normes IETF (notamment MIME) et les charsets peuvent être enregistrés dans un registre IANA selon les règles du RFC 2978. Un charset est un moyen de passer d'une séquence d'octets à une chaîne de caractères abstraits. C'est donc la combinaison d'un jeu de caractères codé et d'un encodage. charset doit être considéré comme un mot-clé, à utiliser sans regarder de trop près son étymologie, et le RFC déconseille notamment de le remplacer par character set, qui peut avoir d'autres définitions en anglais. On va donc dire que charset est un néologisme spécifique à l'IETF.

La section suivante, la 3, liste les organismes de normalisation qui ont à voir avec l'internationalisation (ou plutôt une partie d'entre eux). Par exemple, l'ISO a une norme de jeu de caractères, ISO 10646, qui fait même partie des rares normes ISO disponibles gratuitement en ligne (dans sa version anglaise, uniquement, et après acceptation d'un long texte juridique menaçant, c'est pour cela que je ne mets pas de lien ici). Cette norme est synchronisée avec Unicode et il n'y a donc pas de raison de la lire, Unicode offre davantage de choses. Le groupe de travail SC2/WG2 qui produit la norme ISO a un site Web qui donne des aperçus du travail en cours.

D'autres normes ISO ont un rapport direct avec l'internationalisation comme ISO 639 qui gère un catalogue de langues, avec des codes alphabétiques (comme fr pour le français) ou ISO 3166 qui gère une liste de pays, avec leurs codes (comme fr pour la France). Ces normes forment la base des étiquettes de langue (cf. RFC 5646), utilisées par exemple dans le Web pour indiquer la langue d'une page.

Le consortium Unicode est un autre organisme de normalisation, qui gère le jeu de caractères du même nom, ainsi qu'un certain nombre de travaux qui lui sont liés, comme la définition d'expressions rationnelles pour Unicode. On l'a vu, Unicode et ISO 10646 sont synchronisées et, techniquement, on peut se référer à l'une ou l'autre norme, sans conséquences pratiques. Ce RFC 6535 ne le dit pas mais c'est pour des raisons politiciennes qu'ISO 10646 était plus souvent cité, l'ISO, organisation privée, tout comme le consortium Unicode, étant parfois considérée par certains comme plus ouverte (alors que l'essentiel de ses documents n'est pas distribué en ligne).

Le Web est une des applications où l'internationalisation est la plus avancée, ayant été prise en compte pratiquement dès le début. C'est le rôle du W3C, qui gère des normes comme XML (dont le modèle de caractères est Unicode depuis la première version).

Enfin, et c'est important dans le contexte de l'internationalisation, il existe aussi un certain nombres d'organismes nationaux qui ont parfois une activité touchant à ce sujet.

Comme le cœur de l'internationalisation des protocoles est la définition d'un jeu de caractères commun, la section 3.2 liste le vocabulaire spécifique d'Unicode. Il faut par exemple savoir ce que sont UCS-2, UTF-16 et UCS-4/UTF-32, que le BMP (Basic Multilingual Plane) est composé des 65 536 premiers caractères d'Unicode (qui sont traités à part par certains encodages), qu'UTF-8, normalisé dans le RFC 3629, est l'encodage recommandé pour tous les protocoles IETF, mais que l'IETF a un encodage spécifique pour les noms de domaines, Punycode, normalisé dans le RFC 3492. Encodant n'importe quel chaîne Unicode avec uniquement des caractères ASCII, Punycode peut sembler une solution tentante au problème d'internationalisation d'un vieux protocole, mais il vient aussi avec ses propres problèmes (cf. RFC 6055).

On l'a dit, il existe souvent des SDO nationales qui, avant l'avènement d'Unicode, ont souvent développé des jeux de caractères locaux, permettant de représenter les écritures utilisées dans leur pays. La section 3.3 rappelle ainsi que ces jeux de caractères sont encore souvent très utilisés, comme Shift-JIS pour le japonais.

Ce sont ces jeux de caractères, et leurs encodages (dans la plupart des définitions, le jeu de caractères et l'encodage sont intrinsèquement liés ; Unicode est une exception), qui sont enregistrés sous le nom de charsets à l'IANA, dans http://www.iana.org/assignments/character-sets. Cette liste n'est pas connue pour sa grande rigueur : beaucoup de noms ont été ajoutés au pifomètre. Elle ne s'appuie pas toujours sur des normes reconnues.

Le plus connu des charsets est évidemment US-ASCII, historiquement le jeu par défaut de l'Internet, depuis le RFC 20. Sa domination a officiellement pris fin lors de la sortie du RFC 2277, qui le remplaçait comme charset par défaut par son sur-ensemble UTF-8. À noter que la norme ASCII originale était uniquement un jeu de caractères, et que le terme « ASCII » utilisé à l'IETF lui ajoute un encodage spécifique aux protocoles Internet (champ de huit bits, le bit de plus fort poids toujours à zéro, les sept autres stockant le code ASCII) qui n'a été formellement décrit qu'avec le RFC 5198, bien plus tard...

Ces histoires de caractères font surgir plein d'autres problèmes de terminologie. D'où la section 4, qui lui est consacrée. Ainsi, un point de code (code point) est le numéro que la plupart des normes attribuent à chaque caractère, pour le référencer sans ambiguité. C'est en général un nombre entier strictement positif mais, dans la norme ASCII originale, c'était un couple de nombres, identifiant la ligne et la colonne d'une table. « A » était ainsi 4/1 (ligne 4, colonne 1), en ASCII, alors qu'il est 65 en décimal et U+0041 en Unicode.

Et connaissez-vous les caractères combinants (combining characters) ? Il s'agit d'une particularité d'Unicode, qui met en cause la définition typographique de « caractère » puisqu'un caractère combinant se... combine avec son prédécesseur (par exemple, U+0301 est l'accent aigu combinant, donc U+0065 suivi de U+0301 fait un « é »).

Autre concept important pour les chaînes de caractères, la canonicalisation (normalization ; notez que, en anglais, « canonicalization a un sens très précis dans Unicode, et distinct de celui de normalization, qui justifie l'emploi d'un mot séparé). C'est le processus par lequel une chaîne de caractères est mise sous une forme canonique, permettant les comparaisons (autrement, comparer U+00E9 avec U+0065 U+0301 pourrait échouer alors que, dans les deux cas, il s'agit d'un é).

Quant à la casse (case), c'est le fait pour un caractère d'exister en deux formes, une majuscule et une minuscule. Souvent, la correspondance entre les deux formes est un-un (chaque minuscule a une et une seule majuscule, et réciproquement) mais ce n'est pas toujours le cas. Pire, le changement de casse peut dépendre de la langue. Cette dépendance est mise en œuvre, par exemple, en Java et, outre qu'elle est très coûteuse en ressources, elle produit forcément des résultats différents selon la locale (voir section 8 pour ce terme).

Enfin, place au tri (sorting) et au classement (collation). Le classement est le fait de d'ordonner les caractères. C'est un sujet très vaste. Même en ASCII, il existe au moins deux classements distincts (un par les numéros, A, B, C, D..., a, b, c, et un selon l'ordre alphabétique, A, a, B, b, C, c...). En ISO 8859-1, le cas des caractères composés n'est pas traité de manière uniforme car le classement dépend de la langue (comparez un annuaire téléphonique en France et en Suède pour voir où sont placés les noms propres commençant par un caractère composé). Sans connaître la langue, on ne peut pas espérer classer les caractères Unicode d'une manière qui ne surprenne pas l'utilisateur. Quant au tri, c'est le processus effectif de mise des caractères dans l'ordre du classement. Il fait l'objet d'innombrables algorithmes qui ont fait la joie et le malheur de centaines de milliers d'étudiants en programmation.

Même les adjectifs utilisés pour les différents types de caractères ne sont pas toujours connus. La section 4.1 explique par exemple que le terme d'idéogramme ne décrit pas vraiment correctement les écritures comme la chinoise. Si U+260E est bien une icône (☎, un téléphone), beaucoup de caractères chinois sont utilises phonétiquement, sans coder une idée.

En tout cas, en français, une chose est sûre, on ne devrait pas parler de « caractère accentué » pour des signes comme ç qui n'ont pas d'accent. Le terme Unicode de diacritique (diacritic) convient mieux. Et, évidemment, il ne s'agit pas de caractères spéciaux.

Unicode soulève un autre problème intéressant : la liste des caractères est très longue et il est souvent utile d'en définir des sous-ensembles. Mais attention : contrairement à ASCII ou aux ISO 8859, qui étaient statiques, Unicode grossit tout le temps (la dernière version a été la 6). Un sous-ensemble défini en intension comme « toutes les lettres majuscules » grossira donc lui aussi à chaque nouvelle version d'Unicode (une question qu'il a fallu résoudre pour IDN, voir le RFC 5892).

On l'a dit, le but de l'internationalisation est d'aider les humains, de leur rendre la vie plus facile. Il faut donc un peu se pencher sur les interfaces utilisateur, même si celles-ci sont traditionnellement hors de la portée de l'IETF (qui normalise « au dessus du câble et en dessous de l'application »). En effet, certaines caractéristiques des interfaces utilisateur peuvent affecter les protocoles. D'où l'importance d'apprendre quelques nouveaux termes.

Une méthode d'entrée (input method) est un mécanisme qui permet d'envoyer du texte à une application. Le périphérique d'entrée est souvent un clavier mais les claviers ayant des tailles limitées, les différentes méthodes d'entrée fournissent des mécanismes pour saisir d'autres caractères. Le clavier sur lequel je suis en train de taper n'a pas de majuscules avec diacritiques donc, pour faire un É, je tape Compose (touche dite Windows, sur mon clavier) puis E puis ' (le signe sous le 4). Plus complexe, et ayant bien plus de caractères qu'il n'y a de touches sur un clavier, l'écriture chinoise peut être saisie par plusieurs méthodes différentes : taper les sons au clavier, par exemple.

Les protocoles IETF ont bien de la chance : ils n'échangent que des bits, sans se soucier de savoir comment les afficher. Un serveur HTTP, par exemple, n'a aucun besoin de connaître l'écriture arabe ou la chinoise (ou même de comprendre Unicode), il se contente d'envoyer les octets. Mais le navigateur Web, lui, va devoir afficher les textes pour l'utilisateur. Il s'appuie pour cela sur les règles de rendu (rendering rules), qui sont les algorithmes d'affichage du texte à l'écran. Avec certaines écritures, c'est encore relativement simple : chaque caractère est représenté par un glyphe dans une police de caractères et on pousse simplement ce glyphe vers le périphérique de sortie. Mais dans d'autres écritures, il faut modifier le caractère selon le contexte (par exemple, avec l'écriture arabe, selon qu'il est au début ou à la fin de la phrase). Et, bien sûr, une des choses les plus difficiles pour un moteur de rendu, est de gérer le bidi. Comme je l'ai dit, les protocoles IETF n'ont pas besoin de connaître ces subtilités (un serveur HTTP envoie des textes en alphabet arabe comme ceux en alphabet latin : dans l'ordre de saisie). Mais il est bon que leurs concepteurs soient au courant de ce qui attend les logiciels de l'utilisateur.

Après ces définitions indispensables, quelle est la situation actuelle du texte dans les protocoles IETF ? La section 6 étudie la question. Il n'y a pas de règle générale, car certains protocoles IETF étaient internationalisés depuis le début (comme XMPP), d'autres ne l'ont été qu'après un long et pénible processus (cas du courrier électronique, créé sans penser à l'internationalisation et largement déployé, donc difficile à changer, lorsqu'on a voulu l'adapter à un monde vaste et varié).

Il y a donc encore du vocabulaire à apprendre. Ainsi, les éléments de protocole (protocol elements) sont les éléments qui nomment une partie du protocole. Certains ne sont pas textuels, comme les numéros de port dans TCP, d'autres le sont (comme les commandes SMTP, par exemple EHLO et MAIL FROM) mais ne sont pas vus par l'utilisateur et donc, ne sont pas sujets à l'internationalisation (d'ailleurs, EHLO n'est pas de l'anglais non plus...).

Quant à l'encodage sur le câble (on-the-wire encoding), il désigne les bits qui passent effectivement sur le réseau. Cet encodage est souvent très différent de la forme texte que verront les humains.

Mais il ne pose pas de problèmes d'internationalisation, au contraire du texte analysé (parsed text) qui désigne le texte libre qu'un programme va analyser pour essayer d'y trouver des éléments de protocole. Le cas le plus connu est sans doute la convention d'ajouter un Re: (pour Reply) dans le sujet d'un message. Un tel système est clairement très fragile, la localisation de ce préfixe suffisant à empêcher l'analyse. Il ne devrait pas apparaître dans les protocoles récents.

Lorsqu'un protocole transporte du texte, et que la connaissance de la langue dans laquelle est écrit ce texte est importante (par exemple pour déterminer l'ordre de classement), il faut utiliser une identification de langue (language identification). C'est un mécanisme par lequel on indique la langue utilisée, en se servant des étiquettes de langue du RFC 5646. Ainsi, HTTP va utiliser l'en-tête Content-Language: gsw-FR dans la réponse, pour indiquer que le document servi est en alsacien.

Le texte contenu dans les échanges normalisés par un protocole IETF est souvent décrit par ASN.1. Ce langage permet plusieurs sortes de chaînes de caractère, de la traditionnelle IA5String, qui contient les caractères ASCII, à UTF8String qui, comme son nom l'indique, peut stocker tout Unicode. Ainsi, lorsque le RFC 5280 utilise ce type pour des champs d'un certificat X.509, il permet à ce format d'avoir des noms de CA ou d'utilisateurs complètement internationalisés.

Il existe également toute une terminologie spécifique aux IDN. On la trouve dans le RFC 5890 et résumée dans la section 7.

Plus nouveau est le problème des variantes (variants). Il date du RFC 3743 et peut se définir comme « des chaînes de caractères que certains humains, dans certaines conditions, considèrent comme équivalents ». Dans le RFC 3743, il ne s'agissait que de la différence entre les sinogrammes traditionnels et les sinogrammes simplifiés, pour lesquels une solution était recommandée dans le RFC 4713. Mais la question des variantes peut surgir dans bien d'autres cas :

  • Des caractères que l'œil peut confondre comme le 1 et le l de l'alphabet latin, ou comme le a latin et le а cyrillique.
  • Des caractères qui sont « le même » d'un certain point de vue, mais à qui Unicode a quand même affecté des numéros différents. Un exemple typique est le σ grec, qui s'écrit ς à la fin d'un mot, alors qu'il s'agit du même sigma. Autre exemple, le ي arabe (le yeh), qui est codé différemment dans d'autres langues, par exemple ی en persan.
  • Et bien sûr les variantes orthographiques. Est-ce que color et colour, ou bien theatre et theater sont le même mot en anglais ? Et strasse et straße en allemand ? Concrètement, un protocole Internet doit-il les considérer comme liés, comme faisant partie du même lot, l'un étant une variante de l'autre ?

La question des variantes a donc deux sous-questions : comment classer les caractères et les chaînes en lots (où les membres d'un lot sont considérés variantes l'un de l'autre) ? Et, surtout, le protocole doit-il intégrer cette notion, ou bien considérer plus traditionnellement que deux chaines de caractère sont différentes si elles ont des numéros Unicode différentes, point ?

Dernière section avec des définitions, la section 8 est consacrée aux termes divers. On y trouve, par exemple, le profil local (locale), qui est l'ensemble des informations qui varient selon le lieu ou la culture, et qui sont nécessaires pour que le programme, non seulement parle la langue de l'utilisateur, mais lui présente des informations comme la date ou la monnaie locale.

Les profils locaux sont une source de questions philosophiques sans fin. Par exemple, pour afficher un texte, faut-il utiliser le profil de l'auteur du texte ou bien celui du lecteur ? Et le profil doit-il dépendre de la personne, ou bien de sa localisation physique ? (Si je suis à Tokyo, je veux l'heure locale mais mes textes toujours en français.)

Autres termes utile, ceux de translittération (transliteration), de transcription (transcription) et de romanisation (romanization). La translittération est la conversion d'une écriture dans une autre, en général lettre par lettre. Elle est réversible, la plupart du temps, puisque chaque lettre a été convertie. Cela marche bien entre écritures alpabétiques. La transcription, elle, suit les sons (et non pas les lettres) et va donc être différente selon la langue cible. C'est c'est ainsi que le nom du fondateur du parti bolchevique russe, Ульянов, peut être translittéré Ul'yánov (le résultat exact dépend de la norme suivie car il existe plusieurs normes de translittération de cet alphabet) mais est transcrit Ulyanov en anglais et Oulianov en français. Avec les écritures comme le chinois, la translittération n'est en général pas possible et il n'y a que des transcriptions, comme le pinyin. On nomme romanisation une conversion (translittération ou transcription, même si le RFC n'indique que la première possibilité) vers l'alphabet latin.

Quels sont les changements depuis le précédent RFC, le RFC 3536 ? L'annexe C les résume. Il y a des clarifications, pas de retraits mais plusieurs ajouts, notamment sur la question des variantes. La section 7, sur la terminologie spécifique aux IDN, est toute nouvelle.

Il existe bien sûr d'autres documents qui ont développé un vocabulaire cohérent sur l'internationalisation, et qui ont donc inspiré ce RFC. On peut citer la norme Unicode, le « Character Model for the World Wide Web » du W3C, et les RFC 2277, RFC 5646 et RFC 5890. Patrick Andries a un excellent glossaire de l'internationalisation en français.

L'annexe A contient une bibliographie sur le sujet de l'internationalisation, où on trouve des ouvrages de référence comme la somme sur les écritures du monde, « The world's writing systems ». Sur le sujet d'Unicode, je recommande ces livres :

Enfin, on trouve plein de choses en français sur le site de Patrick Andries.


Téléchargez le RFC 6365


L'article seul

RFC 6360: Conclusion of FYI RFC Sub-Series

Date de publication du RFC : Août 2011
Auteur(s) du RFC : R. Housley (Vigil Security)
Pour information
Première rédaction de cet article le 22 Août 2011


Les RFC, textes sacrés de l'Internet, comportaient un sous-ensemble, dénommé FYI (For Your Information), qui visait un public plus large que les ingénieurs réseaux et les programmeurs. Cette sous-série n'a pas été un grand succès, malgré la qualité des documents produits, et est officiellement abandonnée.

Lancée par le RFC 1150 en 1990, la sous-série FYI visait à élargir le lectorat des RFC et à fournir de l'information utile et techniquement correcte (puisque écrite directement par les experts) à un large public, celui de tous les utilisateurs de l'Internet (les autres RFC n'étant lus que par des geeks barbus). Trente-huit RFC ont été publiés dans cette sous-série, chacun recevant un numéro FYI. Ainsi, le RFC 1178 (FYI 5) expliquait comment choisir un nom pour son ordinateur, le RFC 1359 (FYI 16) détaillait l'intérêt et les bénéfices de se connecter à l'Internet (tout le monde n'était pas encore convaincu), et le dernier de la sous-série, le RFC 3098 (FYI 38) expliquait à quel point c'était mal de spammer. Parfois, le RFC était mis à jour, son successeur héritant de son numéro de FYI. Rappelez-vous qu'un RFC n'est jamais modifié, donc le nom « RFC 1594 » désigne toujours le même document alors que le nom « FYI 4 » a désigné plusieurs RFC successivement, depuis le RFC 1325, intéressant document historique, puisque c'est une FAQ pour les nombreux nouveaux utilisateurs de l'Internet (le dernier RFC pointé par « FYI 4 » a été le RFC 2664).

Depuis 2001, aucun numéro de FYI n'avait été attribué et le groupe de travail qui les gérait ne s'est pas réuni. Ce RFC 6360 ne formule pas d'hypothèse sur cet arrêt mais on peut penser que les experts n'avaient pas forcément le temps ou la compétence d'écrire pour les utilisateurs, et que le modèle des RFC (documents très stables et accessibles sur le long terme) n'était pas forcément adapté à des publications de ce type dans un Internet changeant très vite. Bref, la sous-série a tourné court. Dans d'autres organisations, on aurait continué pendant longtemps la fiction mais l'IETF préfère (et parfois réussit) nettoyer. Ce RFC 6360 marque donc officiellement la fin des FYI. Les documents existants restent accessibles mais il n'y aura pas de nouveautés.

Pour ceux qui veulent accéder à ces excellents documents, la liste est disponible en http://www.rfc-editor.org/fyi-index.html.


Téléchargez le RFC 6360


L'article seul

RFC 6352: vCard Extensions to WebDAV (CardDAV)

Date de publication du RFC : Août 2011
Auteur(s) du RFC : C. Daboo (Apple)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF vcarddav
Première rédaction de cet article le 1 Septembre 2011


De même que le format de fichiers iCal, décrivant des événements, avait son protocole CalDav pour synchroniser des agendas entre machines, le format vCard décrivant des informations sur une personne a désormais son protocole CardDAV, pour synchroniser des carnets d'adresses.

Lorsque ce RFC sera largement déployé, on pourra donc sauvegarder, distribuer, partager son carnet d'adresses de manière standard. Cela se fait en définissant, comme pour CalDav, des extensions au protocole WebDAV (RFC 4918).

Ce n'est pas qu'on manquait de protocoles pour l'accès à un carnet. Comme le rappelle la section 1, on avait LDAP (RFC 4510), IMSP et ACAP (RFC 2244), ainsi que SyncML. Mais bâtir sur WebDAV (RFC 4918) permettait de récupérer les fonctions perfectionnées de ce protocole. Le nouveau CardDAV permet d'avoir plusieurs carnets d'adresses, d'en protéger l'accès par des autorisations (RFC 3744), de faire des recherches côté serveur (sans avoir besoin de récupérer tout le carnet d'adresses chez le client), etc. WebDAV étant lui-même bâti sur HTTP, on récupère aussi les fonctions de HTTP comme la sécurité avec TLS (RFC 2818). CardDAV utilise le format vCard. Ce format avait été normalisé dans le RFC 2426 et se trouve désormais dans la RFC 6350. CardDAV dépend de certaines extensions à WebDAV et tout serveur WebDAV ne conviendra pas forcément. La section 3 résume les exigences de CardDAV (serveur permettant de créer des collections avec MKCOLRFC 5689 et exemple d'usage en section 6.3.1, versionnement - RFC 3253, etc). Par contre, il n'y a pas encore dans le protocole CardDAV de mécanisme de notification asynchrone (« Machin a changé de numéro de téléphone »). Le RFC ne le précise pas mais il y a un inconvénient à utiliser WebDAV, la complexité. Notre RFC 6352 fait 56 pages, et il faut avoir compris WebDAV avant...

La section 4 du RFC explique le modèle de données utilisé pour le carnet : chaque carnet d'adresses est une collection WebDAV et chaque entrée dans le carnet est une ressource WebDAV, adressable et verrouillable séparement. En même temps que les carnets d'adresses, un serveur CardDAV peut aussi gérer avec WebDAV d'autres ressources (un exemple serait un serveur où le carnet d'adresses de Lisa serait en /addressbooks/lisa et son agenda, via CalDAV, en /calendars/lisa). Le serveur publie le fait qu'il gère CardDAV en ajoutant addressbook à la réponse à la requête HTTP OPTIONS.

La section 5 passe ensuite à ces ressources. Chacune d'elles est une entrée du carnet, typiquement exprimée en format vCard (le serveur peut gérer également d'autres formats).

Emprunté au RFC (section 6.1), voici un exemple de connexion à un serveur CardDAV :

(Le client demande)
OPTIONS /addressbooks/ HTTP/1.1
Host: addressbook.example.com

(Le serveur répond)
HTTP/1.1 200 OK
Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE
Allow: MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL
DAV: 1, 2, 3, access-control, addressbook
DAV: extended-mkcol
Date: Sat, 11 Nov 2006 09:32:12 GMT
Content-Length: 0

Le client sait désormais que le serveur gère CardDAV (le addressbook dans l'en-tête DAV).

Différentes propriétés WebDAV (RFC 4918, section 4 ; les propriétés sont les méta-données de WebDAV) permettent de se renseigner sur les carnets d'adresses. Elles sont formatées en XML. Ici, addressbook-description (section 6.2.1 ; son nom indique bien à quoi elle sert) peut valoir, par exemple (notez l'attribut xml:lang qui illustre les capacités d'internationalisation de CardDav) :


       <carddav:addressbook-description xml:lang="fr-CA"
          xmlns:carddav="urn:ietf:params:xml:ns:carddav">
         Adresses de Oliver Daboo
       </carddav:addressbook-description>


Et pour créer des entrées dans le carnet d'adresses, ce qui est quand même la tâche la plus importante de CardDAV ? CardDAV étant fondé sur HTTP, on utilise évidemment une requête PUT (de même que la lecture se ferait par un GET). La section 6.3.2 nous fournit un exemple, avec l'entrée au format vCard :

   PUT /lisa/addressbook/newvcard.vcf HTTP/1.1
   If-None-Match: *
   Host: addressbook.example.com
   Content-Type: text/vcard
   Content-Length: xxx

   BEGIN:VCARD
   VERSION:3.0
   FN:Cyrus Daboo
   N:Daboo;Cyrus
   ADR;TYPE=POSTAL:;2822 Email HQ;Suite 2821;RFCVille;PA;15213;USA
   EMAIL;TYPE=INTERNET,PREF:cyrus@example.com
   NICKNAME:me
   NOTE:Example VCard.
   ORG:Self Employed
   TEL;TYPE=WORK,VOICE:412 605 0499
   TEL;TYPE=FAX:412 605 0705
   URL:http://www.example.com
   UID:1234-5678-9000-1
   END:VCARD

Le If-None-Match dans la requête (RFC 2616, section 14.26) est là pour garantir qu'une ressource du même nom n'existe pas déjà. Cela évite d'effacer une ressource existante. Le .vcf à la fin de l'URL est l'extension commune des fichiers vCard.

Les carnets d'adresses sont évidemment des choses assez personnelles, on a donc des moyens de les protéger (section 7). Un serveur CardDAV permet de définir des ACL, comme normalisé dans le RFC 3744.

Récupérer un carnet d'adresses avec GET est simple mais ne laisse guère de choix. La section 8 présente des mécanismes plus sophistiqués. CardDAV a la méthode HTTP REPORT du RFC 3253 pour produire des extractions du carnet. Mais il a aussi des fonctions de recherche et de tri. Celles-ci posent le problème des règles de comparaison (rappelez-vous qu'un fichier vCard est de l'Unicode et peut contenir des caractères de toute sorte). La section 8.3 précise donc :

  • Ces règles sont exprimées en utilisant la terminologie du RFC 4790, qui fournit une liste de règles,
  • Parmi ces règles, le serveur doit accepter au moins les comparaisons ASCII i;ascii-casemap du RFC 4790 et les comparaisons Unicode i;unicode-casemap du RFC 5051,
  • Les opérations possibles sont au minimum le test d'égalité et le test de sous-chaîne (« strauss » doit trouver « strauss-kahn »), avec ses options « au début de la chaîne » et « à la fin de la chaîne ».

Voici un exemple de commande REPORT en ajoutant une condition pour ne sélectionner que les entrées du carnet dont le NICKNAME est exactement égal à « me » :


La requête :

   REPORT /home/bernard/addressbook/ HTTP/1.1
   Host: addressbook.example.com
   Depth: 1
   Content-Type: text/xml; charset="utf-8"
   Content-Length: xxxx

   <?xml version="1.0" encoding="utf-8" ?>
   <carddav:addressbook-query xmlns:dav="DAV:"
                     xmlns:carddav="urn:ietf:params:xml:ns:carddav">
     <dav:prop>
       <dav:getetag/>
       <carddav:address-data>
         <carddav:prop name="VERSION"/>
         <carddav:prop name="UID"/>
         <carddav:prop name="NICKNAME"/>
         <carddav:prop name="EMAIL"/>
         <carddav:prop name="FN"/>
       </carddav:address-data>
     </dav:prop>
     <carddav:filter>
       <carddav:prop-filter name="NICKNAME">
         <carddav:text-match collation="i;unicode-casemap"
                       match-type="equals">
            me
         </carddav:text-match>
       </carddav:prop-filter>
     </carddav:filter>
   </carddav:addressbook-query>

La réponse :

   HTTP/1.1 207 Multi-Status
   Date: Sat, 11 Nov 2006 09:32:12 GMT
   Content-Type: text/xml; charset="utf-8"
   Content-Length: xxxx

   <?xml version="1.0" encoding="utf-8" ?>
   <dav:multistatus xmlns:dav="DAV:"
                  xmlns:carddav="urn:ietf:params:xml:ns:carddav">
     <dav:response>
       <dav:href>/home/bernard/addressbook/v102.vcf</dav:href>
       <dav:propstat>
         <dav:prop>
           <dav:getetag>"23ba4d-ff11fb"</dav:getetag>
           <carddav:address-data>BEGIN:VCARD
   VERSION:3.0
   NICKNAME:me
   UID:34222-232@example.com
   FN:Cyrus Daboo
   EMAIL:daboo@example.com
   END:VCARD
   </carddav:address-data>
         </dav:prop>
         <dav:status>HTTP/1.1 200 OK</dav:status>
       </dav:propstat>
     </dav:response>
   </dav:multistatus>

Écrire un client CardDAV n'est pas trivial, pas seulement à cause de la longueur du RFC mais aussi parce qu'il existe plusieurs pièges. La lecture de la section 9 est donc recommandée. Elle rappelle par exemple que le client peut ne demander qu'une partie des données (dans l'exemple ci-dessus, le client demande à ne voir que VERSION, UID, NICKNAME, EMAIL et FN). Cela lui évite de devoir télécharger des données qui peuvent être de grande taille comme PHOTO ou SOUND. Par contre, cette astuce ne marche qu'en lecture, pas en écriture : un PUT doit transmettre la totalité de la vCard et le protocole ne fournit pas de moyen de ne mettre à jour qu'un seul champ. Le client doit donc récupérer toute la vCard, changer un champ et renvoyer toute la vCard modifiée.

Piège classique dans ce cas, la « mise à jour perdue ». Que se passe-t-il si les données ont été changées entre leur récupération et le renvoi ? Ce changement risque d'être écrasé. Pour éviter cela, le client a tout intérêt à utiliser l'option If-Match: de la requête HTTP, en indiquant comme paramètre un Etag récupéré précedemment (les Etags sont décrits dans les sections 3.11 et 14.19 du RFC 2616). Ainsi, dans le cas cité ci-dessus, le renvoi du vCard modifié sera refusé, préservant la mise à jour qui avait été faite parallèlement. (Emmanuel Saint-James me fait remarquer qu'on aurait aussi pu utiliser If-Unmodified-Since:, si le serveur CardDAV met les informations dans une base de données qui stocke la date de modification, par exemple le système de fichiers Unix ; cette possibilité n'est pas mentionnée par le RFC.)

Comment configure-t-on un client CardDAV (section 9.3) ? On a vu que l'URL utilisé était arbitraire, au choix de l'implémenteur. Le client doit donc être configuré avec cet URL. Il existe bien un mécanisme de découverte automatique, décrit dans le RFC 5397, mais qui n'est pas forcément présent partout.

Et le nom du serveur ? La section 11 décrit un enregistrement SRV pour le trouver. Le nom _carddav._tcp.domain.example permet donc de trouver le serveur CardDAV du domain domain.example (et _carddavs pour utiliser TLS). Si l'enregistrement SRV vaut :

_carddav._tcp     SRV 0 1 80 addressbook.example.com.

Cela indique que ce serveur est addressbook.example.com et qu'il est accessible sur le port 80. Si ces enregistrements SRV sont présents, et si la propriété current-user-principal-URL du RFC 5397 est utilisée, il n'y a plus à configurer que le nom de domaine, le nom de l'utilisateur et un mot de passe.

Et si on veut accéder au carnet d'un autre utilisateur, ce qui peut arriver en cas de carnets partagés ? La section 9.4 rappelle l'existence de la propriété principal-property-search du RFC 3744, qui peut permettre de demander un REPORT en cherchant le carnet sur divers critères. Ici, on cherche le carnet de Laurie :


   REPORT /home/bernard/addressbook/ HTTP/1.1
   Host: addressbook.example.com
   ...
   <dav:principal-property-search xmlns:dav="DAV:">
     <dav:property-search>
       <dav:prop>
         <dav:displayname/>
       </dav:prop>
       <dav:match>Laurie</dav:match>
     </dav:property-search>
     <dav:prop>
       <carddav:addressbook-home-set
          xmlns:carddav="urn:ietf:params:xml:ns:carddav"/>
       <dav:displayname/>
     </dav:prop>
   </dav:principal-property-search>

Notez que, CardDAV s'appuyant sur XML, il hérite de ses capacités d'internationalisation (section 12), notamment l'usage d'Unicode.

Et question sécurité ? Des failles dans CardDAV ? La section 13 tente de prévenir les problèmes : d'abord, CardDAV hérite des questions de sécurité de HTTP. Si on n'utilise pas HTTPS, les requêtes et réponses circulant sur le réseau peuvent être lues et/ou modifiées. C'est particulièrement important si on utilise l'authentification HTTP de base, avec envoi d'un mot de passe.

Ensuite, une fois les utilisateurs authentifiés, encore faut-il éviter qu'un utilisateur ne tripote les carnets des autres. L'extension « ACL » du RFC 3744 permet d'atteindre cet objectif. Elle permet d'avoir des carnets publics, partagés ou complètement privés. Le serveur doit ensuite veiller au respect de cette classification.

Le schéma XML complet pour les éléments CardDAV figure en section 10. Question implémentations, on peut regarder la liste gérée par les gens de Zimbra, celle de Trinity, celle de Wikipédia. Parmi les programmeurs qui gèrent CardDAV, citons le serveur Davical ou le client Kontact de KDE.


Téléchargez le RFC 6352


L'article seul

RFC 6350: vCard Format Specification

Date de publication du RFC : Août 2011
Auteur(s) du RFC : S. Perreault (Viagenie)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF vcarddav
Première rédaction de cet article le 1 Septembre 2011


vCard, désormais en version 4 avec ce RFC est le format standard de carnet d'adresses sur l'Internet. Tous les logiciels de gestion de carnet d'adresses peuvent (ou devraient pouvoir) lire et écrire du vCard. Ce RFC met à jour la norme vCard.

vCard est simplement un modèle de données (très léger) et une syntaxe pour représenter des données permettant de contacter des individus ou organisations. Par exemple, une entrée vCard pour mon employeur, l'AFNIC, pourrait être :

    BEGIN:VCARD
    VERSION:4.0
    FN:Association Française pour le Nommage Internet en Coopération
    KIND:org
    GENDER:N
    NICKNAME:AFNIC
    LANG;PREF=1:fr
    LANG;PREF=2:en
    ADR:;;Immeuble International;Saint-Quentin-en-Yvelines;;78181;France
    LOGO:http://www.afnic.fr/images/logo.png
    TEL;VALUE=uri:tel:+33-1-39-30-83-00
    EMAIL:afnic@afnic.fr
    GEO:geo:2.0455,48.7873
    BDAY:19980101
    TZ:Paris/Europe
    URL:http://www.afnic.fr/
    NOTE;LANGUAGE=en:@AFNIC on Twitter\,
     AFNIC on Facebook.
    END:VCARD

Ce texte peut ensuite être lu et interprété par les logiciels de gestion de carnet, être envoyé via l'Internet, etc. Un exemple courant est l'envoi d'une vCard dans le courrier, via MIME et le type text/vcard (section 10.1 pour l'enregistrement de ce type). Le cas échéant, il est relativement compréhensible par un humain (s'il comprend l'anglais et quelques sigles), ce qui justifie le type MIME text indiqué plus haut.

La version de vCard dans ce RFC est largement terminée depuis mi-2010. Mais de nombreux détails avaient été discutés jusqu'au dernier moment. Si la syntaxe ne pose guère de problèmes (on notera qu'il existe une variante XML normalisée, dans le RFC 6351), le modèle de données peut susciter des discussions sans fin.

Pour prendre des exemples de cette discussion, voici quelques sujets qui avaient été abordés lors de la réunion du groupe de travail à l'IETF de Pékin en 2010 :

  • La nouvelle propriété RELATED qui peut valoir spouse, friend, etc. Une jolie liste des valeurs possibles est http://gmpg.org/xfn/11. On pourra coder toutes les relations Facebook en vCard.
  • La longue discussion passionnée à propos du remplacement de l'ancien attribut SEX de vCard 3 par GENDER. La moitié des participants se sont exprimés, ce qui est rare à l'IETF. Le sexe est déterminé biologiquement et, en toute première approximation, peut être considéré comme binaire (homme ou femme). Le genre est construit socialement et peut prendre bien plus de valeurs. GENDER pourra donc être du texte libre (une des propositions discutées à Pékin avait été de créer un registre IANA des différents genres possibles...) et les exemples du RFC (avec des valeurs comme grrrl, intersex ou complicated) illustrent la difficulté du problème. Le changement dans vCard permet donc de mieux prendre en compte des cas comme celui des transsexuels ou, tout simplement, des gens qui ont une autre identité que celle que leur impose la biologie. L'ironie de la longue et animée discussion est qu'il n'y avait que des hommes dans la salle. (GENDER est désormais décrit en détail dans la section 6.2.7 du RFC, avec notamment sa façon subtile de combiner deux champs, un énuméré et un en texte libre.)
  • Plus triste, une discussion avait eu lieu sur la propriété DEATH permettant, si nécessaire, d'indiquer la date de la mort de l'entitée considérée. Elle a finalement été retirée. Mettre du vCard sur une pierre tombale aurait pourtant été curieux... Cela a finalement été possible quelque temps après, avec l'approbation du RFC 6474.
  • Et les adresses de courrier électronique en Unicode du RFC 6532 ont évidemment suscité bien de la perplexité. Finalement, la propriété EMAIL permettra de telles adresses (voir la section 6.4.2 pour les détails).

J'espère que cette liste amusante vous aura donné une idée des problèmes que pose la définition d'un modèle de données standard. Retournons maintenant à la technique. D'abord, le niveau lexical (sections 3.1 et 3.2) : les fichiers vCard sont en UTF-8 (la possibilité d'autres encodages a été retirée, avec cette version de vCard), et sont composés de lignes terminées par CRLF (c'est-à-dire les deux caractères U+000D et U+000A). Comme pour les en-têtes du courrier électronique, on peut continuer sur plusieurs lignes : si une ligne commence par un espace ou une tabulation, c'est une continuation (regardez la NOTE dans l'exemple plus haut). Du fait de ces continuations, un outil mono-ligne comme grep n'est pas bien adapté pour chercher dans des vCards.

Ensuite, la syntaxe (section 3.3). Elle est très simple et indiquée en ABNF (RFC 5234). Une « carte » commence par la ligne BEGIN:VCARD, continue par une ligne avec le numéro de version, puis par une ou plusieurs lignes comportant les données, et se termine avec END:VCARD. Les données sont composées de propriétés, chaque ligne étant un nom de propriété (insensible à la casse, même si la convention recommandée est de les mettre en majuscules), suivi d'un :, puis de la valeur de la propriété (celle-ci pouvant elle-même être structurée, comme dans l'ADR ci-dessus).

Certains caractères sont spéciaux, comme la virgule et, si on veut les avoir comme valeur, doivent subir un échappement avec la barre inverse (section 3.4).

Les données peuvent avoir des paramètres. La section 5 décrit ce concept. Un paramètre permet de préciser des méta-données sur une propriété. Par exemple, LANGUAGE permet d'indiquer la langue d'un texte. PREF permet de spécifier, lorsqu'il existe plusieurs exemplaires d'une propriété, laquelle est préférée (celle qui a la valeur la plus basse). Ainsi, dans l'exemple de l'AFNIC ci-dessus, c'est le français qui est la langue de contact préférée. SORT-AS permet de définir un tri entre les valeurs (un problème difficile pour les noms d'humains). TYPE permet d'indiquer, pour une ADR, si elle concerne la maison ou le travail. (vCard version 3 avait un mécanisme plus riche, qui aurait permis, dans l'exemple de l'AFNIC ci-dessus, d'indiquer la différence entre l'adresse postale - TYPE=postal et l'adresse physique - TYPE=parcel. Trop confus, il a été supprimé.) Et il existe plusieurs autres paramètres.

La sémantique est décrite dans la suite de cette section 3.3 et, pour chaque propriété, dans les sections 4, 5 et 6. Notons qu'une seule propriété est obligatoire (à part VERSION), FN, le nom de l'entité décrite dans la vCard. Pour chaque propriété, la section 4 indiquera si des valeurs multiples sont autorisées. Par exemple, on peut avoir plusieurs NICKNAME (surnom), mais un seul (facultatif) GENDER (genre).

Je ne vais évidemment pas lister toutes les propriétés que décrit la section 5 (voir le registre IANA pour une liste à jour). Pour chacune, elle donne son nom, sa cardinalité (zéro, zéro-ou-une, une, zéro-ou-plus, une-ou-plus occurrence) et son type. Pour ce dernier, il y a de nombreuses possibilités comme, par exemple, du texte libre, un URI, une date ou un temps (en utilisant la norme ISO 8601 et pas le plus simple RFC 3339), un booléen, un nombre entier, une langue (représentée selon le RFC 5646), etc.

À certains égards, la section 6 est la plus importante du RFC. C'est la liste de toutes les propriétés possibles actuellement, avec leurs caractéristiques. Quelques exemples, non limitatifs :

  • N indique le nom, sous forme d'une série de composants (dont la plupart sont facultatifs). Pour les humains, je rappelle surtout que le fait d'avoir Prénom + Nom est très loin d'être universel.
  • KIND indique quelle est la catégorie de l'entité décrite par cette « carte » (personne physique, organisation - comme dans l'exemple de l'AFNIC plus haut, etc).
  • PHOTO est l'URI (éventuellement de plan data:, c'est-à-dire fournissant directement le contenu) d'une photo de la personne. LOGO joue un rôle analogue pour les organisations.
  • BDAY est la date de naissance de l'entité.
  • IMPP indique le moyen de contacter l'entité par messagerie instantanée.
  • LANG permet d'indiquer, sous la forme d'une étiquette de langue comme fr ou pt-BR, la langue à utiliser pour contacter l'entité.
  • GEO est la localisation physique habituelle de l'entité, en suivant de préférence la syntaxe du RFC 5870. (Notez le « de préférence ». Analyser la syntaxe d'une vCard est très simple, mais accéder à la sémantique est bien plus complexe, en raison du choix qui est laissé pour le codage d'informations comme le numéro de téléphone ou la position physique.)
  • KEY permet de distribuer des clés cryptographiques (attention à comment on a récupéré le vCard avant de leur faire confiance...)

Notez que la liste n'est pas figée dans le temps (c'est une nouveauté de vCard version 4). Des propriétés ou paramètres nouveaux pourront être enregistrés, selon la procédure décrite dans la section 10.2. Il faudra d'abord les discuter sur la liste vcarddav@ietf.org, puis il y aura un examen par un expert. Si accepté, le nouvel élément sera enregistré à l'IANA.

Le reste du RFC est consacré à des points d'utilisation des vCard. Par exemple, la section 7 est consacrée à la synchronisation des vCards entre deux engins (par exemple l'ordinateur du bureau et le smartphone). Que faire si une entrée a été modifiée sur un carnet et détruite dans un autre ? Deux mécanismes sont fournis pour aider à une fusion intelligente des deux carnets, une propriété UID qui identifie de manière unique et non ambigüe une entité (de préférence en utilisant le RFC 4122) et PID qui identifie une propriété. Les section 7.1.1 et 7.1.2 détaillent l'algorithme à utiliser lorsqu'on synchronise deux carnets. Par exemple, si on a identifié, grâce à UID, une entrée dans les deux carnets, et qu'une propriété est différente entre les carnets, alors, si la cardinalité d'une propriété est de 1, ou bien si le PID est le même, les deux propriétés doivent être fusionnées. Sinon, le synchroniseur est libre de fusionner, ou tout simplement de mettre les deux propriétés côte-à-côte. La section 7.2 donne des exemples détaillés de fusions. À noter qu'il existe un protocole pour la synchronisation des cartes avec un serveur, CardDAV, normalisé dans le RFC 6352.

Le message d'enregistrement du type MIME text/vcard, qui commençait la procédure, avait été fait en août 2010.

Publier ainsi de l'information, parfois sensible, sur l'Internet, n'est pas sans conséquences. La section 9 couvre les risques de sécurité de vCard. Par exemple, la carte en elle-même n'offre aucune garantie d'authentification ou d'intégrité. Rien ne prouve qu'une carte indiquant FN:Theo de Raadt vient réellement de de Raadt. Et même si la carte était authentique au départ, rien n'indique qu'elle n'a pas été modifiée en cours de route, sauf si elle a été transportée de manière fiable (par exemple dans un message signé avec PGP). Bref, ne vous fiez pas aveuglément à n'importe quelle vCard trouvée sur l'Internet !

Autre risque, celui pour la vie privée. Ce n'est pas par hasard ou par oubli que vous ne trouverez pas BDAY ou ADR sur ma carte, un peu plus loin. Une carte doit donc ne comporter que des informations publiques, ou bien être uniquement transportée de manière sûre (par exemple via un canal chiffré) et vers des gens de confiance.

Les changements de vCard depuis la version 3 (qui était normalisée dans les RFC 2425 et RFC 2426) sont décrits dans l'annexe A. La liste est longue et pas facile à résumer (ce n'est qu'une accumulation de changements ponctuels). Le changement que je trouve le plus spectaculaire est la possibilité d'enregistrer de nouveaux éléments sans changer de RFC, juste par un processus d'enregistrement IANA. Sinon, voir la section 6.7.9 pour le rôle de la propriété VERSION pour gérer le fait que les cartes en circulation aient des versions différentes.

Si vous voulez en savoir plus sur vCard, le site Web du groupe de travail est très riche, quoique plutôt difficile d'accès (il est conçu pour le travail du groupe, pas pour la pédagogie).

Et du point de vue pratique, quels outils le programmeur a à sa disposition s'il veut lire et/ou écrire du vCard ? Il existe une bibliothèque pour les programmeurs C (le paquetage se nomme libvc-dev sur Debian), qui est utilisée dans des applications comme rolo. Elle n'est distribuée avec aucune documentation digne de ce nom et pas d'exemples. Pour les programmeurs Perl, il existe Text::vCard. Attention à son analyseur : très laxiste, il accepte des vCards bourrées d'erreurs de syntaxe.

Voici un exemple d'usage de cette bibliothèque Perl :

#!/usr/bin/perl

use Text::vCard::Addressbook;

for $file (@ARGV) {
    my $address_book = Text::vCard::Addressbook->new({
	'source_file' => $file});
    $number = 0;
    foreach my $vcard ($address_book->vcards()) {
	print "Got card for " . $vcard->fullname() . "\n";
	$number++;
    }
    if (!$number) {
	print "No correct vCard in $file\n";
    }
}

Ah, et si vous voulez me contacter, voici une carte pour moi :

BEGIN:VCARD
VERSION:4.0
FN:Stéphane Bortzmeyer
N:Bortzmeyer;Stéphane;;;
UID:urn:uuid:a06340f8-9aca-41b8-bf7a-094cbb33d57e
GENDER:M
KIND:individual
EMAIL:stephane+blog@bortzmeyer.org
TITLE:Indigène de l'Internet
PHOTO:http://www.bortzmeyer.org/images/moi.jpg
LANG;PREF=1:fr
LANG;PREF=2:en
IMPP;PREF=1:xmpp:bortzmeyer@dns-oarc.net
IMPP;PREF=2:xmpp:bortzmeyer@gmail.com
URL:http://www.bortzmeyer.org/
KEY:http://www.bortzmeyer.org/files/pgp-key.asc
END:VCARD

Merci à Simon Perreault pour sa relecture.


Téléchargez le RFC 6350


L'article seul

RFC 6349: Framework for TCP Throughput Testing

Date de publication du RFC : Août 2011
Auteur(s) du RFC : B. Constantine (JDSU), G. Forget (Bell Canada), R. Geib (Deutsche Telekom), R. Schrage (Schrage Consulting)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 22 Août 2011


La mesure des performances du réseau intéresse évidemment fortement les utilisateurs (combien de temps me faudra-t-il pour télécharger justin-bieber.flac ?) et les décideurs qui cherchent à savoir, par exemple, quelle capacité offre un FAI, s'il délivre bien le service promis, ou encore s'il limite artificiellement les débits. La plupart des métriques définies rigoureusement, et des outils qui les mettent en œuvre, concernent des phénomènes de bas niveau, comme le taux de perte de paquets (RFC 2680), C'est ainsi que, lorsqu'il existe des SLA formalisés, ils portent en général sur ces phénomènes proches du réseau. Ces métriques sont utiles et relativement faciles à mesurer objectivement, mais elles sont très éloignées de l'expérience ressentie par l'utilisateur final. Ce dernier voudrait plutôt savoir comment l'intégration de toutes ces métriques de bas niveau se traduit en un petit nombre de chiffres faciles à comprendre. Ce n'est pas une tâche triviale que de passer des métriques de base au ressenti utilisateur, et ce RFC est une première étape sur le chemin.

L'idée est de préciser les conditions de mesure de débit sur une connexion TCP, de bout en bout (donc tenant compte du comportement de tous les liens et équipements intermédiaires). Le débit mesuré en TCP donne une première idée de la capacité du réseau, qui est elle-même souvent la première métrique qui intéresse les utilisateurs (c'est en tout cas en général celle qui est mise en avant dans les publicités). Mais cette mesure contient de nombreux pièges et l'un des buts de ce RFC est de les lister. Au final, ce RFC ne permet pas de répondre simplement à la question de M. Toutlemonde « ça va moins ramer avec le fournisseur X qu'avec son concurrent Y ? », mais il avance quand même dans cette direction.

On grimpe donc d'une couche et on passe des mesures traditionnelles (taux de pertes, comme cité plus haut, ou bien capacité du lien au niveau 2) vers le niveau 4. Le désir de mesurer rigoureusement le débit atteignable avec TCP oblige à apporter quelques restrictions. Par exemple, le cadre de mesure décrit dans ce RFC se limite aux réseaux dont tous les aspects sont contrôlés par un fournisseur unique, avec des garanties explicites. Cela concerne donc plutôt la clientèle « entreprises ». La section 2 détaille tout ce qui n'est pas un objectif de ce RFC :

  • Le comportement de TCP en dehors de l'équilibre (voir plus loin),
  • La comparaison des mises en œuvre de TCP,
  • La mesure en continu d'un réseau de production (pour cela, il vaut mieux utiliser la MIB TCP du RFC 4898).

Le but est au contraire de pouvoir mesurer, de manière objective et reproductible, les performances TCP d'un chemin donné, en fonction d'un certain nombre de réglages, bien définis. Les outils existants comme iperf ou ttcp permettent d'ajuster ces réglages.

Passons maintenant à la technique (la section 1.1 liste la terminologie employée) : TCP utilise à tout moment deux fenêtres, une pour l'envoyeur (congestion windows) et une pour le récepteur (receive window). Le débit théorique est limité par la bande passante (capacité de la couche 2) et par le RTT. Leur produit, le BDP (Bandwidth*Delay Product), va déterminer la taille des tampons optimaux (le tableau en section 3.3.1 donne des valeurs numériques). Ce BDP est, en gros, le nombre d'octets qui peuvent se trouver en transit à un moment donné. Ensuite, la fenêtre de congestion sera ajustée pour tenir compte du taux de pertes. Le nombre d'octets en route à un moment donné dépendra de la fenêtre la plus petite (si on a une grande congestion window mais que l'autre partie annonce une petite receive window, le débit restera faible : un émetteur TCP n'est pas censé noyer son pair sous les octets non désirés).

Toutes ces variables vont déterminer le débit effectivement atteint. Avant de tenter de mesurer celui-ci, le RFC insiste bien sur le fait que les tests de bas niveau (couches 2 et 3) doivent quand même être faits, pour déterminer que le réseau fonctionne bien. Le RFC note qu'un taux de pertes de paquets de 5 %, ou bien une gigue dans le délai d'acheminement de 150 ms, sont trop élevées pour que les mesures de débit TCP aient un sens. La méthodologie du RFC 2544 (bien que conçue à l'origine pour un environnement de laboratoire) peut être utilisée pour ces tests de bon fonctionnement.

Ensuite, notre méthodologie ne concerne que les connexions TCP ayant atteint l'état d'équilibre (section 1.2). Rappelons qu'une connexion TCP établie peut avoir trois comportements par rapport à la congestion : l'état d'équilibre où TCP essaie de remplir le tuyau au maximum, le démarrage en douceur, utilisé au début de la connexion, où TCP commence à sonder prudemment le réseau, en augmentant doucement son débit, et le troisième comportement, la récupération en cas de pertes, où TCP réduit brusquement son débit, avant de repartir plus ou moins doucement. En pratique, un certain nombre de connexions utilisées pour HTTP, par exemple, n'atteindront jamais cet équilibre, car elles durent trop peu de temps. C'est un bon exemple de la distance entre les mesures techniques et le vécu de l'utilisateur !

Dans un réseau idéal, à l'équilibre, TCP devrait avoir un débit très proche de la bande passante offerte.

La section 3 du RFC présente la méthodologie de mesure détaillée, avant que la section 4 ne décrive les métriques utilisées. La mesure impose d'utiliser un équipement capable de saturer le lien (donc, pas un vieux PC). Les mesures à plus de 100 Mb/s peuvent donc exiger une machine dédiée. La mesure exige ensuite les étapes suivantes :

  • Déterminer la PMTU (en utilisant le RFC 4821, pour tenir compte des nombreux réseaux mal configurés qui bloquent ICMP) pour ensuite configurer le logiciel de test de manière à ce que les paquets soient assez petits pour éviter toute fragmentation (qui changerait drastiquement les performances). Par exemple, avec iperf (cité plus loin), l'option --mss permet de changer la taille des segments (des paquets TCP).
  • Déterminer le RTT minimum et la bande passante offerte par les couches basses. Cela servira à optimiser des paramètres comme le tampon d'envoi. Sur un réseau de production, cette mesure doit se faire aux heures creuses, pour être sûr d'obtenir vraiment la valeur « réelle ». Il existe plusieurs façons de mesurer le RTT. Le choix dépend de la précision souhaitée. Si on se contente de la milli-seconde, les paquets ICMP echo de ping conviennent (mais c'est quand même la technique la moins fiable, surtout s'il y a un traitement différencié pour ICMP dans le réseau, ou dans les machines de test). Si on veut se promener du côté de la micro-seconde, il faudra peut-être un dispositif de mesure spécialisé (voir section 5), et des protocoles comme celui du RFC 5357. Il y a aussi l'analyse des paquets capturés, avec un outil comme tcptrace, ou les statistiques gardées par TCP lui-même (RFC 4898). Quant à la mesure de la « bande passante » (un terme que je n'aime pas mais qui est utilisé par le RFC), elle devrait être faite suivant les règles du RFC 5136. Il ne faut pas oublier de la mesurer dans les deux directions, surtout avec les liens asymétriques comme l'ADSL.
  • En enfin, faire les tests avec TCP, après avoir configuré le logiciel de test. La section 5 recommande un test d'au moins trente secondes, pour lisser les variations du réseau (avec iperf, c'est l'option --time, avec ipmt, c'est -d). Compte-tenu de la variété des mécanismes de tripotage du réseau qui existent, il peut être prudent de faire plusieurs mesures (par exemple de voir si une seule connexion obtient bien N fois ce qu'obtenait chacune des connexions d'un groupe de N connexions simultanées, cf. section 5.1).

Les métriques utilisées sont définies dans la section 4 du RFC. Elles sont au nombre de trois. La première est le ratio du temps de transfert, soit le rapport entre le temps nécessaire pour transférer N octets par rapport à la situation idéale (compte-tenu de la bande passante). Le calcul exact de cette situation idéale figure en section 4.1.1. Par exemple, pour une ligne T3 à 44,21 Mb/s exploitée en PPP, une MTU de 1500 octets, vus les en-têtes TCP, on arrive à 42,8 Mbps. Si on mesure un débit maximal de 40 Mbps, le ratio sera donc de 1,07 (rappelez-vous que c'est un rapport des temps de transfert, pas des débits). Pour un Ethernet 1 Gb/s, le cas idéal, qu'aucune amélioration du logiciel ne permettra de dépasser, est de 949 Mbps. L'utilisation de jumbo frames permettrait bien sûr de faire mieux.

La seconde métrique est l'efficacité de TCP. C'est le pourcentage des octets qui n'ont pas été retransmis. Il vaut donc 1 en l'absence de pertes (ou de retards qui mèneraient TCP à croire à une perte de paquets).

Plus subtile, la troisième métrique est le retard dû aux tampons. C'est le rapport entre l'excès de RTT (par rapport au RTT minimum, celui imposé par les caractéristiques de la ligne) et le RTT minimum. Par exemple, si le RTT minimum (qui, sur les lignes à grande distance, est souvent dépendant essentiellement de la vitesse de la lumière) est de 25 ms, et qu'on observe un RTT moyen de 32 ms pendant un transfert TCP, le retard dû aux tampons est donc de 28 %.

La première métrique est celle qui est la plus directement pertinente pour l'utilisateur. Les deux autres fournissent surtout un moyen de diagnostic : si le ratio du temps de transfert est mauvais, l'examen de l'efficacité et du retard dû aux tampons nous indiquera peut-être pourquoi.

Voilà, la norme est définie. La section 5, elle, revient sur les conditions pratiques de mesure. Entre autres, elle expose les règles du choix entre une seule connexion TCP et plusieurs. Ce choix dépend des caractéristiques du réseau (si le produit bande passante * délai est de 2 Moctets, une seule connexion TCP ne pourra pas remplir le tuyau, cf. le tableau des valeurs numériques en section 5.1).

Reste l'interprétation des résultats (section 5.2). Les résultats devraient toujours être accompagnés de la valeur des paramètres indiqués plus haut (ce que font les outils existants, cf. plus loin). Le RFC demande évidemment que les valeurs des trois métriques citées plus haut soient affichées, ce qui n'est pas (encore ?) le cas avec les logiciels Unix de mesure existants. Une fois qu'on a ces valeurs, si elles ne correspondent pas aux valeurs idéales, on peut se livrer aux joies du déboguage : la congestion avec des tampons de petite taille dans les routeurs fera sans doute grimper les pertes de paquets, ce qui se traduira par une mauvaise efficacité TCP. Si les routeurs ont de quoi stocker les paquets en attente, c'est le RTT qui augmentera, ce qui se verra dans le retard dû aux tampons. Mais il peut aussi y avoir ralentissement délibéré par le réseau (policing), tampons trop petits sur les machines de test (qui ont, après tout, une mémoire limitée, qui peut être trop faible pour les réseaux à haute performance d'aujourd'hui). Les machines Unix ont de tels tampons aussi bien globalement pour tout le système que par socket. On peut fixer ces derniers (la valeur idéale est le BDP, le produit bande passante*délai) dans le programme, mais aussi les laisser s'ajuster automatiquement (service auto-tuning, qui existe dans Linux et FreeBSD ainsi que, depuis moins longtemps, Windows et Mac OS). Il faut également regarder du côté du mécanisme de window scaling (RFC 1323) sans lequel il est impossible d'exploiter les réseaux à très fort BDP qu'on trouve aujourd'hui. Et, bien sûr, émettre des paquets ayant la taille maximale possible sans fragmentation est aussi une bonne tactique.

Bien d'autres réglages de TCP sont possibles, comme l'option d'estampille temporelle (RFC 1323) qui permet à TCP de mieux calculer le RTT (et qui protège contre les numéros de séquence TCP qui reviennent à leur valeur initiale, un problème qui devient sérieux au delà de 100 Mb/s), les accusés de réception spécifiques (SACK) du RFC 2018, qui permettent de limiter les retransmissions, etc.

À titre d'exemple, voici des exemples de mesure, plus ou moins compatibles avec notre RFC, dans le cas de certains outils libres. Le premier est iperf. Existant sous forme de paquetage pour divers systèmes Unix (ici, Debian), il est facile à installer. On doit le lancer côté client et côté serveur (c'est un point commun entre tous ces outils : il faut un compte sur les deux machines ; on ne peut donc pas les utiliser pour tester son débit possible avec YouTube).

# Serveur
% iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)

# Client
% iperf --print_mss --client test.bortzmeyer.org
------------------------------------------------------------
Client connecting to test.bortzmeyer.org, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 192.0.2.69 port 46908 connected with 203.0.113.232 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec    173 MBytes    145 Mbits/sec
[  3] MSS size 1448 bytes (MTU 1500 bytes, ethernet)

On peut aussi changer la taille de la fenêtre TCP. Les 145 Mb/s obtenus ci-dessus sont probablement indépassables mais, parfois, ce changement améliore les performances. Il peut aussi les dégrader, ici, on choisit une fenêtre très petite :

% iperf --window 1K --client test.bortzmeyer.org 
...
TCP window size: 2.00 KByte (WARNING: requested 1.00 KByte)
------------------------------------------------------------
...
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  27.3 MBytes  22.9 Mbits/sec

Cet exemple illustre l'importance de documenter, lorsqu'on publie les résultats de la mesure, les options utilisées. Ici, on a divisé la capacité utile par sept... (Quant au message d'avertissement, il vient de l'habitude du noyau Linux de fixer la taille de la fenêtre à une valeur double de celle qui est demandée.) iperf permet théoriquement de faire fonctionner plusieurs sessions TCP simultanées (option --parallel) mais j'avoue n'avoir pas réussi à la faire fonctionner.

Un autre outil traditionnel est ttcp. Très ancien, il a depuis été remplacé par des versions plus récentes. Je vais utiliser nuttcp, également en paquetage dans tous les bons systèmes. Son serveur a la désagréable habitude de passer en arrière-plan immédiatement (et il ne semble pas y avoir d'option pour changer cela), et on risque donc facilement d'oublier un serveur qui tourne. Le mieux est donc de toujours le lancer avec l'option -1 qui ne permet qu'un seul test.

# Serveur
% nuttcp -1

# Client
% nuttcp -v -t 203.0.113.232    
nuttcp-t: v6.1.2: socket
nuttcp-t: buflen=65536, nstream=1, port=5001 tcp -> 203.0.113.232
nuttcp-t: time limit = 10.00 seconds
nuttcp-t: connect to 203.0.113.232 with mss=1448, RTT=2.173 ms
nuttcp-t: send window size = 16384, receive window size = 87380
nuttcp-t: available send window = 12288, available receive window = 65535
nuttcp-t: 166.5708 MB in 10.00 real seconds = 17056.72 KB/sec = 139.7286 Mbps
nuttcp-t: retrans = 0
nuttcp-t: 2666 I/O calls, msec/call = 3.84, calls/sec = 266.60
nuttcp-t: 0.0user 0.0sys 0:10real 0% 0i+0d 592maxrss 0+2pf 893+0csw

On note des chiffres proches de ceux de iperf, ce qui est rassurant. nuttcp a le même genre d'options que iperf (-l pour changer la taille des tampons, -w pour la fenêtre TCP, etc). Il peut utiliser plusieurs sessions TCP (option -N) mais ne semble pas permettre de fixer la MSS.

Un outil plus récent, encore un peu expérimental mais qui a bien marché sur mes machines est ipmt. On lance le serveur ainsi :

% tcptarget
IPv6 (and IPv4) protocol
Using port 13000
...

Et le client avec :

% ./tcpmt test2.bortzmeyer.org      
IPv4 protocol

Time         Packets    Total      |    Kbit/s  Avg 10  Avg
33496.429     486       486        |    5045    5045    5045
33497.345     179       665        |    2283    3805    3805
33498.467     134       799        |    1394    2950    2950
...

et les résultats sont affichés en continu (utile si le réseau change).

Enfin, le traditionnel Netpipe ne semble plus guère maintenu et fonctionne mal sur les Unix récents.

Le RFC mentionne aussi d'autres outils comme tcptrace, outil d'analyse des sessions capturées au format pcap et qui, avec ses options -r et -l, permet de calculer des choses comme le RTT.

Un petit avertissement de sécurité, pour finir (section 6). Les mesures de ce RFC sont des mesures actives, susceptibles de perturber sérieusement le réseau. Le principe étant d'occuper tout le tuyau, la mesure ressemble fort à une DoS. Soyez donc prudent (RFC 4656 et RFC 5357).


Téléchargez le RFC 6349


L'article seul

RFC 6347: Datagram Transport Layer Security version 1.2

Date de publication du RFC : Janvier 2012
Auteur(s) du RFC : E. Rescorla (RTFM), N. Modadugu (Stanford University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 21 Janvier 2012


Le protocole de cryptographie TLS, normalisé dans le RFC 5246, ne s'appliquait traditionnellement qu'à TCP. Les applications utilisant UDP, comme le fait souvent la téléphonie sur IP, ne pouvaient pas utiliser TLS pour protéger leur trafic contre l'écoute ou la modification des données. Mais cette limitation a disparu avec DTLS, qui permet de protéger du trafic UDP. Ce RFC met à jour DTLS (initialement normalisé dans le RFC 4347) pour TLS 1.2.

TLS ne tournait que sur TCP car il avait besoin d'un transport fiable, garantissant que les données arrivent toutes, et dans l'ordre. Le grand succès de TLS (notamment utilisé pour HTTP et IMAP) vient de sa simplicité pour le programmeur : rendre une application capable de faire du TLS ne nécessite que très peu de code, exécuté juste avant l'envoi des données. Par contre, cela laissait les applications UDP comme SIP non protégées (section 1 de notre RFC). Les solutions existantes comme IPsec ne sont pas satisfaisantes (cf. RFC 5406), notamment parce qu'elles n'offrent pas la même facilité de déploiement que TLS, qui tourne typiquement dans l'application et pas dans le noyau.

DTLS a été conçu pour fournir TLS aux applications UDP. Il offre les mêmes services que TLS : garantie de l'intégrité des données et confidentialité.

La section 3 explique les principes de DTLS : protégé ou pas par DTLS, UDP a la même sémantique, celle d'un service de datagrammes non fiable. D'autre part, DTLS est une légère modification de TLS : il en garde les principales propriétés, bonnes ou mauvaises.

Mais pourquoi ne peut-on pas faire du TLS normal sur UDP ? Parce que TLS n'a pas été conçu pour tourner au dessus d'un protocole non fiable. TLS organise les données en enregistrements (records) et il ne permet pas de déchiffrer indépendamment les enregistrements. Si l'enregistrement N est perdu, le N+1 ne peut pas être déchiffré. De même, la procédure d'association initiale de TLS (handshake) ne prévoit pas de perte de messages et ne se termine pas si un message est perdu.

Le premier problème fait l'objet de la section 3.1. La dépendance des enregistrements TLS vis-à-vis de leurs prédécesseurs vient du chaînage cryptographique (le chiffrement par chaînagestream cipher - est donc supprimé en DTLS) et de fonctions anti-rejeu qui utilisent un numéro de séquence, qui est implicitement le rang de l'enregistrement. DTLS résoud le problème en indiquant explicitement le rang dans les enregistrements.

Et la question de l'association initiale est vue dans la section 3.2. Pour la perte de paquets lors de l'association, DTLS utilise un système de retransmission (section 3.2.1) et pour l'éventuelle réorganisation des paquets, DTLS introduit un numéro de séquence (section 3.2.2). En prime, DTLS doit gérer la taille importante des messages TLS (souvent plusieurs kilo-octets), qui peut être supérieure à la MTU. DTLS permet donc une fragmentation des paquets au niveau applicatif, un message pouvant être réparti dans plusieurs enregistrements (section 3.2.3).

Enfin, l'anti-rejeu a été modifié pour tenir compte du fait que la duplication de paquets, en UDP, n'est pas forcément malveillante (sections 3.3 et 4.1.2.6).

La définition formelle du nouveau protocole est en section 4. DTLS étant une légère évolution de TLS, la définition se fait uniquement en listant les différences avec TLS. Il faut donc garder le RFC 5246 sous la main.

Dans le Record Protocol de TLS, l'enregistrement spécifié dans la section 6.2.1 du RFC 5246 gagne deux champs (section 4.1) :

  struct {
         ContentType type;
         ProtocolVersion version;
         uint16 epoch;                                    // NOUVEAU
         uint48 sequence_number;                          // NOUVEAU
         uint16 length;
         opaque fragment[DTLSPlaintext.length];
       } DTLSPlaintext;

notamment le numéro de séquence sequence_number (qui était implicite dans TLS, puisque TCP garantissait l'ordre des messages). Pour éviter la fragmentation et les ennuis associés, les mises en œuvre de DTLS doivent déterminer la MTU du chemin et n'envoyer que des enregistrements plus petits que cette MTU (section 4.1.1).

Contrairement à IPsec, DTLS n'a pas la notion d'identificateur d'association. Une machine qui reçoit du TLS doit trouver l'association toute seule, typiquement en utilisant le tuple (adresse IP, port).

En toute rigueur, DTLS n'est pas spécifique à UDP, il peut marcher sur n'importe quel protocole de transport ayant une sémantique « datagrammes ». Certains de ces protocoles, comme DCCP (cf. RFC 5238), ont leur propres numéros de séquence et ils font donc double emploi avec ceux de DTLS. Petite inefficacité pas trop grave.

Au niveau du Hanshake protocol, les modifications que DTLS apporte à TLS font l'objet de la section 4.2. Les trois principales sont :

  • L'ajout d'un gâteau pour limiter les risques de DoS,
  • Modification des en-têtes pour gérer les pertes ou réordonnancements des paquets (section 4.2.2),
  • Ajouts de minuteries pour détecter les pertes de paquets (section 4.2.4).

Les gâteaux de DTLS sont analogues à ceux de Photuris ou IKE (section 4.2.1). Le message ClientHello de la section 7.4.1.2 du RFC 5246 y gagne un champ :

 opaque cookie<0..32>;         // NOUVEAU

Évidemment, ils ne protègent pas contre un attaquant qui utilise sa vraie adresse IP, puisque celui-ci pourra lire la réponse.

OpenSSL gère DTLS depuis la version 0.9.8 (on peut aussi consulter le site Web du développeur). Un exemple d'utilisation se trouve dans http://linux.softpedia.com/get/Security/DTLS-Client-Server-Example-19026.shtml. Il me reste à inclure ce protocole dans echoping. GnuTLS a un support DTLS plus récent.

Et les nouveautés de DTLS 1.2 par rapport au 1.0 du RFC 4347 ? (Il n'y a pas eu de DTLS 1.1.) Elles sont résumées dans la section 8. La principale nouveauté est que DTLS est désormais défini par rapport à TLS 1.2 et non plus 1.0. Cela a notamment permis d'inclure les numéros de séquence explicites de TLS 1.1, nécessaires contre l'attaque BEAST (section 4.1.2.1). Une autre nouveauté est la section 4.1.2.7 qui discute le traitement des paquets invalides. Contrairement à TLS, DTLS peut fonctionner en présence de tels paquets, avec une sémantique proche de celle d'UDP : les laisser tomber et attendre que l'application se débrouille (en demandant leur réémission ou bien en passant à autre chose). Enfin, d'autres clarifications ont été apportées, par exemple à la détection de la PMTU ou bien à l'enregistrement dans les registres IANA.

Une très bonne description de la conception de Datagram TLS et des choix qui ont été faits lors de sa mise au point, se trouve dans l'article The Design and Implementation of Datagram TLS, écrit par les auteurs du RFC. C'est une lecture très recommandée.


Téléchargez le RFC 6347


L'article seul

RFC 6346: The A+P Approach to the IPv4 Address Shortage

Date de publication du RFC : Août 2011
Auteur(s) du RFC : R. Bush (Internet Initiative Japan)
Expérimental
Première rédaction de cet article le 28 Août 2011


Pendant longtemps, le problème technique posé à l'IETF par l'épuisement des adresses IPv4 était traité par la perspective d'une migration vers IPv6, et les efforts de l'IETF allaient vers la création de jolis mécanismes de transition vers ce nouveau protocole. Mais la migration est très loin d'être terminée (sur beaucoup de sites, elle n'a même pas réellement commencé) et, dans des régions comme l'Asie, les adresses IPv4 ne sont plus seulement difficiles à obtenir et chères, elles sont tout simplement toutes utilisées. Il faut donc maintenant, en urgence, mettre au point des mécanismes qui permettront de vivre pas trop mal en attendant le déploiement d'IPv6. C'est le cas du mécanisme A+P (Address plus Port) de ce RFC.

Tous ces mécanismes sont pour le court terme. À moyen et à long terme, la solution correcte, comme avant, reste le passage à IPv6. Toutefois, pour tous les paresseux et les irresponsables qui n'ont pas encore commencé cette migration, il est trop tard : même s'ils se réveillaient demain, ils n'auraient pas le temps de terminer leur transition vers IPv6 avant que le manque d'adresses IPv4 ne devienne un vrai blocage pour leur activité.

A+P, présenté dans ce RFC, propose une solution pour limiter les dégâts, chez les derniers utilisateurs d'IPv4. Cet article va être relativement court, par manque de temps pour explorer en détail cette technologie, mais aussi parce que je suis sceptique : c'est très gentil d'essayer de maintenir la tête des utilisateurs IPv4 hors de l'eau encore quelques mois ou quelques années, mais cela va coûter pas mal d'efforts, qui seraient mieux employés à leur apprendre à nager (à déployer IPv6).

Donc, quels sont les principes d'A+P ? Comme les miracles n'existent pas, l'idée de base est un compromis. On va sacrifier quelques bits du numéro de port pour les donner à l'adresse IP. Ce faisant, on réduit la capacité des applications à allouer beaucoup de connexions ouvertes (chacune nécessitant un port) mais il n'y a plus guère le choix. Comme le note le RFC, « the need for addresses is stronger than the need to be able to address thousands of applications on a single host » ou, en termes plus brutaux, « en cas de famine, on ne réclame pas d'assaisonnement sur tous les plats ».

Cette famine fait que le partage d'adresses IPv4, déjà largement réalisé au sein d'une même maison ou entreprise, va forcément s'étendre et que des clients différents, sans lieu entre eux, partageront la même adresse IP. L'idée d'A+P est que, même si l'adresse ne sera plus unique, le couple {adresse, partie du port} restera unique par client. Avec 65536 ports possibles, on peut mettre 65536 clients sur une même adresse IP (si chacun se contente d'un seul port), 256 (avec 256 ports chacun), ou un seul (avec le système actuel où le client a 65536 ports)... L'un des intérêts d'A+P est qu'il limite (sans toutefois le supprimer) le recours au NAT et à tous ses inconvénients.

En effet, une alternative à A+P serait de déployer des gros routeurs NAT (CGN, pour Carrier-grade NAT) dans les réseaux des FAI, routeurs qui traduiraient pour plusieurs clients (au contraire du routeur NAT typique d'aujourd'hui, qui n'opère que pour un seul client). La section 1.1 explique pourquoi c'est une mauvaise idée : le CGN ne maintient pas la connectivité de bout en bout, qui est au cœur d'Internet. Par exemple, le déploiement d'une nouvelle application qui échange des adresses serait bloqué tant que le routeur CGN (qui est sous le contrôle du FAI) n'est pas mis à jour avec un nouvel ALG. Les techniques qui permettent de rendre les routeurs NAT actuels un peu moins insupportables (configuration manuelle de la redirection de port, UPnP) ne marchent en effet pas sur un CGN. Enfin, les routeurs CGN stockent un état considérable (des centaines ou des milliers de clients) et sont donc un point de faiblesse du réseau : si un routeur CGN redémarre, tout est perdu.

La section 3 détaille les contraintes que s'impose A+P, afin d'éviter ces défauts :

  • Maintien, dans la mesure du possible, du principe de bout en bout (ne pas utiliser l'épuisement des adresses v4 comme excuse pour limiter l'usage que les utilisateurs peuvent faire de l'Internet),
  • Compatibilité avec l'existant, par exemple, les anciennes applications doivent marcher comme avant,
  • Ne pas garder trop d'état dans le réseau du FAI,
  • Traçabilité des utilisateurs, c'est-à-dire capacité à fliquer quel ordinateur a fait telle action,
  • Ne pas décourager la migration vers IPv6, comme, dit le RFC, le fait le NAT444 (ou « double-NAT »).

Ce cahier des charges est-il réaliste ? Le reste de la section 3 raconte comment fonctionne A+P. Il y a trois fonctions :

  • Traduction : pour gérer les anciennes applications, qui allouent des ports sans restriction, et tournent sur une machine qui imagine être la seule au monde à avoir cette adresse IP, il faudra une fonction de traduction analogue au NAT actuel,
  • Encapsulation et décapsulation : s'il y a des anciens routeurs sur le trajet, il faudra encapsuler les paquets. Ce sera le travail du PRR (Port Range Router),
  • Signalisation : les machines nouvelles (qui connaissent A+P), ont besoin de savoir quelle plage de ports leur a été allouée.

Le traducteur devra faire bien attention, contrairement au NAT actuel, à n'utiliser en sortie que des ports appartenant à la plage allouée.

La signalisation est le gros morceau (section 3.3.1). A+P peut utiliser plusieurs protocoles pour cela (à ma connaissance, tous sont encore au stade de brouillon). Le protocole doit permettre d'informer une machine A+P de l'adresse IPv4 publique à utiliser, des plages de ports réservées pour elle, de la durée pendant laquelle ces allocations restent valables, etc. L'allocation des ports peut être statique (« tu as de 20 000 à 31 000 ») ou dynamique par des nouveaux protocoles comme UpNPv2.

Si on a un site client réduit, avec une seule machine, qui connaît A+P, et un équipement A+P chez le FAI, et que l'adresse IPv4 publique donnée au site client est {192.0.2.1, ports 20 000 à 31 000}, un paquet sortant du site client est émis tel quel (la machine sait n'utiliser comme port source que ceux alloués) et le paquet rentrant est traité ainsi dans l'équipement A+P :

  • En regardant le port de destination, on trouve à quel client est destiné ce paquet (routage par le port, l'adresse IP ne suffisant plus, car elle est partagée entre plusieurs clients),
  • On lui transmet.

Dans ce cas, pas besoin de traduction. Évidemment, dans la réalité, ce sera plus compliqué : il y aura plusieurs machines sur le site du client et, surtout, ces machines ne connaîtront pas toutes A+P et émettront donc des paquets avec des ports source quelconques. Cette fois, on ne pourra pas se passer de traduction : une machine chez le client (et non pas chez le FAI) va alors traduire ces paquets pour mettre l'adresse source allouée et changer le port source pour un des ports alloués. Au retour, ce même traducteur fera l'opération inverse, très proche de celle des routeurs NAT d'aujourd'hui.

Est-ce que tout cela marche vraiment en pratique ? La section 3.4 rend compte des essais effectués à France Télécom. Les plus gros problèmes sont survenus avec des mises en œuvre de BitTorrent, qui veulent accepter des connexions entrantes sur un port précis mais, globalement, il n'y a pas eu trop de problèmes.

Si vous aimez les considérations pratiques, la section 5 est vouée aux problèmes de déploiement. Par exemple, pour des sites client en ADSL ou connectés par le câble, le modèle le plus logique est que les fonctions de traduction soient dans la box, le FAI allouant les plages de ports et les communiquant audit CPE. (Pour un réseau 3G, c'est plus complexe, car le smartphone ne peut pas forcément assurer beaucoup de fonctions.)

Comment le FAI décide-t-il de l'allocation des ports (section 5.2) ? Une solution évidente est de diviser équitablement. Si on met cent clients par adresse IP, chacun a 655 ports et se débrouille avec. Le risque de cette allocation statique est alors que les clients les plus gourmands soient limités, alors que les autres ont des ports libres. L'idéal serait donc que l'allocation soit dynamique, s'ajustant à la demande.

Comme avec le NAT, certains protocoles vont poser des problèmes particuliers. Ainsi, ICMP (section 5.3.2), n'ayant pas le concept de port, va être difficile à faire passer. Pour les messages d'erreur transportés par ICMP, comme ils incluent le début du paquet qui a provoqué l'erreur, on peut y trouver un numéro de port et router par ce biais. Pour les messages d'écho (ceux qu'utilise ping), il n'y a pas d'autre solution que de bricoler avec des champs comme l'identificateur du message ICMP, ou comme le numéro de séquence ICMP, en les utilisant comme numéros de port.

Parmi les autres problèmes concrets que devra résoudre la machine A+P, il y a enfin la fragmentation, source traditionnelle d'ennuis. Ici, le routage se faisant en fonction du port de destination, un réassemblage des fragments entrants est nécessaire, pour déterminer ledit port.

A+P, on l'a vu, est un système complexe. Il a quelques limitations, documentées en section 5.3.4. La principale est que les ports bien connus, notamment le célébrissime port 80, utilisé par les serveurs HTTP, ne seront pas forcément disponibles. Si le client qui a obtenu une plage de ports située au début (du côté des ports bien connus, en dessous de 1024) est heureux (et on peut même envisager de le faire payer plus cher pour ce « privilège »), les autres n'ont pas de solution, s'ils veulent faire tourner un serveur HTTP sur leur machine.

Enfin, A+P marche mal ou pas du tout avec IPsec, bien qu'il soit possible de contourner le problème avec les techniques du RFC 3715.

Et question sécurité, ça se passe comment ? La section 7 fait la liste des questions de sécurité liées à A+P. La première est la difficulté de suivre à la trace un utilisateur. Pour savoir qui a osé commettre un délit aussi grave que de partager de la culture, il faut que l'espion qui surveille le trafic ait noté le numéro de port source (cf. RFC 6302), et que l'équipement A+P ait enregistré qui avait la plage où se trouve ce numéro. A+P est donc plus efficace pour le flicage qu'un CGN ou qu'un NAT traditionnel, qui doit noter une information bien plus évanescente (qui avait ce port à ce moment-là). Reste à savoir si c'est un avantage...

Quel est l'état des implémentations de A+P au moment de la publication de ce RFC ? L'ISC a A+P dans son routeur logiciel (surtout connu pour DS-Lite) AFTR (qui ne semble actuellement pourvoir faire que de l'allocation de ports statique), France Télécom / Orange a également un logiciel libre en http://opensourceaplusp.weebly.com/, et il existe le logiciel 4RD de la société ipinfusion.com. Pour le futur, Iskratel et, dans une moindre mesure, Cisco et Juniper, ont indiqué qu'ils y travaillaient.


Téléchargez le RFC 6346


L'article seul

RFC 6336: IANA Registry for Interactive Connectivity Establishment (ICE) Options

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : M. Westerlund (Ericsson), C. Perkins (University of Glasgow)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mmusic
Première rédaction de cet article le 20 Juillet 2011


Le protocole de traversée des NAT, ICE (normalisé dans le RFC 5245), offre la possibilité d'ajouter des options, identifiées par un nom (section 14 du RFC 5245). Mais aucun registre n'existait pour stocker les noms de ces options et éviter des collisions. C'est désormais fait.

Il n'y a pas encore une seule option utilisée par les mises en œuvre d'ICE. Mais une est en cours de développement et cela a motivé la création de ce registre. Donc, une option a un nom, composé d'une série de caractères alphanumériques (on peut aussi utiliser le + et le /). Ce nom est enregistré en suivant la règle « spécification (écrite et publique) obligatoire » de la section 4.1 du RFC 5226, et en indiquant diverses méta-données comme les coordonnées de la personne ou de l'organisme qui enregistre.

Et c'est tout, le registre (actuellement vide) se trouve en http://www.iana.org/assignments/ice-options/ice-options.xml.


Téléchargez le RFC 6336


L'article seul

RFC 6335: Internet Assigned Numbers Authority (IANA) Procedures for the Management of the Transport Protocol Port Number and Service Name Registry

Date de publication du RFC : Août 2011
Auteur(s) du RFC : M. Cotton (ICANN), L. Eggert (Nokia), A. Mankin (Johns Hopkins Univ.), J. Touch (USC/ISI), M. Westerlund (Ericsson), S. Cheshire (Apple)
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 3 Septembre 2011


Ce RFC parle autant de gouvernance que de technique. Il refond considérablement les procédures utilisées pour enregistrer les numéros de port à l'IANA. Bien que moins médiatisé que l'enregistrement des noms de domaine, ou même que celui des adresses IP, cet enregistrement des ports a déjà suscité des conflits, et peut en faire encore plus maintenant qu'une des plages utilisées approche de la saturation. L'ancien mécanisme d'enregistrement était peu documenté, avait plusieurs limites techniques, et était éclaté entre plusieurs registres ayant des règles différentes. Le nouveau vise à unifier tout cela et à suivre de bons principes, soigneusement explicités.

D'abord, de quoi s'agit-il (section 3) ? Les ports sont des numéros, codés sur 16 bits, qui servent à démultiplexer les paquets IP entrant dans une machine (port de destination 62981 -> processus 7653, qui fait tourner dig, etc) et à identifier le protocole utilisé (port 80 -> HTTP, port 22 -> SSH, etc). Les noms de services, eux, sont des courts identificateurs alphabétiques, qui servent à s'abstraire du numéro de port, en permettant aux applications d'utiliser un nom de service pour récupérer dynamiquement un numéro de port (par exemple avec les enregistrements SRV du DNS, ou bien avec un appel à getservbyname()). Sur Unix, vous avez une liste (incomplète) de ces noms, avec le numéro de port correspondant, dans le fichier /etc/services. Pendant longtemps, les registres officiels stockaient à la fois un nom de service et un numéro de port. Désormais, ils pourront ne contenir qu'un nom de service.

Le port n'est pas indiqué dans l'en-tête IP mais dans celle du protocole de couche 4 au dessus. On peut donc techniquement utiliser le même numéro de port pour des applications différentes, si l'une utilise UDP et l'autre TCP. La procédure d'enregistrement, elle, est désormais la même pour tous les protocoles de transport.

Les en-têtes de couche 4 incluent deux ports, celui de source et celui de destination, et, avec les adresses IP source et destination et l'identificateur du protocole de transport, ils servent aussi à identifier une connexion de manière unique.

Du fait que l'ancien système d'enregistrement à l'IANA allouait en même temps un nom de service et un numéro de port, bien des applications savent utiliser ce nom de service. Par exemple, avec telnet, on peut se connecter à un serveur de courrier avec telnet mail.example.net 25 (le numéro de port) mais aussi avec telnet mail.example.net smtp (le nom du service). Le port ainsi enregistré est dit « bien connu » (80 pour HTTP...) Mais attention : de nos jours, il est courant de faire tourner une application sur un port autre que celui prévu à l'origine (parce que le pare-feu ne laisse passer que le port 80, pour échapper à la détection, ou encore parce qu'on veut faire tourner deux mises en œuvre différentes du protocole sur la même machine, ou derrière le même routeur NAT). Enfin, certaines applications n'ont pas de port fixe et comptent sur les enregistrements SRV du DNS (RFC 2782), ou bien sur d'autres méthodes (comme les trackers dans BitTorrent).

Un dernier points sur les numéros de port : comme ils sont stockés sur seulement 16 bits, il n'y a que 65 536 valeurs possibles. C'est très peu. La première plage, celle des ports bien connus, est déjà pleine à 76 %. Un des objectifs de la politique d'allocation des ports est donc d'épargner cette ressource limitée, notamment en conseillant fortement aux applications d'utiliser uniquement un nom de service, sans réserver de numéro de port.

Le plan du RFC commence par expliquer la situation actuelle et pourquoi elle n'est pas satisfaisante. Mais je préfère partir de la nouvelle situation, celle qui est désormais l'officielle, et parler du passé tout à la fin de cet article.

D'abord, les noms de services (section 5). Ce sont les clés d'accès au registre des services. Les applications les utilisent pour chercher un numéro de port, typiquement via les enregistrements SRV du RFC 2782. Il peut y avoir plusieurs services qui se partagent un numéro de port, par exemple :

  • Parce que l'un est une extension de l'autre (cas de TURNRFC 5766, qui est une extension de STUNRFC 5389 ; le fait d'avoir un service nommé turn permet à une application d'obtenir tout de suite un serveur ayant l'extension TURN, sans tester plusieurs serveurs STUN),
  • Par accident (un exemple typique est la coexistence de deux services www et http qui pointent vers le même port 80 ; seul http est correct, aujourd'hui),
  • Ou suite à la sortie de notre RFC qui introduisait des nouvelles règles de syntaxe pour les noms de services, rendant parfois nécessaire la création d'alias (l'ancien et le nouveau nom).

Les noms de services dans le registre sont enregistrés sur une base « premier arrivé, premier servi », tel que décrit dans le RFC 5226 (voir aussi la section 7.2). Contrairement aux numéros de port, il n'y a pas de pénurie et donc pas de raison de faire des économies, sauf si l'IANA détecte un problème (comme un enregistrement massif de noms) auquel cas elle peut passer au mécanisme Expert review, où un examen de fond est fait. Les noms doivent être courts (quinze caractères maximum) et informatifs, et éviter les redondances (comme de mettre protocole ou port dans le nom).

La syntaxe des noms (une nouveauté de ce RFC) est décrite en section 5.1. En résumé, seuls les lettres d'ASCII, les chiffres et le tiret sont admis. Il faut au moins une lettre, pour éviter des noms de service comme 23, qui pourrait être pris pour un numéro de port. 98 % des noms du registre étaient déjà conformes à cette syntaxe avant ce RFC, les 2 % restants ont dû changer de nom pour se plier à la nouvelle syntaxe. C'est ainsi que, par exemple, z39.50 (pour le protocole du même nom) est devenu z39-50.

Dans le cas le plus courant, l'application va traduire ces noms en numéro de port via une requête DNS. Prenons l'exemple de XMPP. Si le serveur de messagerie instantanée de Google Talk veut contacter un utilisateur dont l'adresse XMPP est martinedurand@dns-oarc.net, le serveur de Google va faire une requête SRV pour le service xmpp-server, protocole TCP (RFC 6120, section 3.2.1). Il trouvera :

% dig SRV _xmpp-server._tcp.dns-oarc.net
...
;; ANSWER SECTION:
_xmpp-server._tcp.dns-oarc.net.	3600 IN	SRV	0 0 5269 jabber.dns-oarc.net.

et saura donc qu'il doit se connecter au port 5269. (Le fait que le champ « service » du RFC 2782 doive être un nom de service enregistré n'était pas clair : c'est notre nouveau RFC qui impose cette règle.)

L'enregistrements des numéros de port est plus complexe, en raison du risque de pénurie (section 6). Il y a trois plages de numéros de port :

  • Les ports « système », dits aussi « bien connus », de 0 à 1023.
  • Les ports « utilisateur », de 1024 à 49151.
  • Et les ports « dynamiques », dits aussi « éphémères », de 49152 à 65535. Contrairement aux deux précédentes plages, ils ne font jamais l'objet d'un enregistrement à l'IANA.

Il y a trois statuts possibles pour un numéro de port :

  • Affecté : il apparaît alors dans le registre,
  • Non affecté,
  • Réservé : ils ne sont pas affectés et ne doivent normalement pas l'être. Par exemple, les ports extrêmes de la plage des bien connus, 0 et 1023, sont réservés, au cas où il faille un jour étendre cette plage ; on les utiliserait alors comme indiquant un échappement.

Aujourd'hui, 76 % des ports système et 9 % des ports utilisateur sont affectés.

Il existe aussi des ports voués à des usages expérimentaux (section 6.1, voir aussi le RFC 3692), les ports 1021 et 1022. Comme des tas de protocoles peuvent s'y bousculer, les applications qui utilisent ces ports doivent s'assurer qu'elles se connectent bien au service attendu (par exemple, le client peut vérifier que le serveur envoie un nombre magique caractéristique de l'application).

Comment enregistre-t-on un nouveau numéro de port ? La section 7 décrit les grands principes. Le plus important est la nécessité d'allouer lentement, pour éviter d'épuiser ce qui reste de cette ressource (si vous développez un nouveau protocole, rappelez-vous que la méthode recommandée est de ne pas réclamer de numéro de port du tout, mais d'utiliser un nom de service). Environ 400 ports par an sont affectés, et le chiffre est stable depuis des années. Cela devrait permettre de tenir jusqu'à la fin du 21ème siècle.

Compte-tenu de cela, les nouveaux principes, exposés en section 7.2 sont :

  • Un seul numéro de port par application : si celle-ci est composée de plusieurs services, l'application doit néanmoins tout mettre sur le même numéro de port et démultiplexer elle-même.
  • Même chose en cas de mise à jour d'un service : on n'alloue pas de nouveau numéro de port. La technique recommandée est que le service inclue un champ Version dans ses messages, pour qu'il puisse les séparer facilement.
  • Affectation uniquement pour le protocole de transport indiqué (c'est une grande nouveauté par rapport aux précédentes règles). Si l'application ne fonctionne que sur TCP, aucune allocation de port n'est faite pour UDP.
  • Rien n'est éternel et une allocation de numéro de port peut être reprise par l'IANA.

Les ports « repris » auront le statut Réservé (sur l'Internet, il n'est pas prudent de réallouer des ports trop tôt, on ne peut jamais être sûr de ce qui traîne dans des vieilles applications, cf. section 8.3). Le jour où une plage de numéros de port est épuisée, l'IANA pourra recycler ces vieux numéros en les affectant.

Tout le détail des procédures bureaucratiques est en section 8. Si on veut un numéro de port ou un nom de service, il faut remplir un formulaire (section 8.1.1) indiquant les coordonnées du demandeur (pour les normes au sens propre, ce demandeur sera l'IETF), une description du protocole prévu et le nom du protocole de transport (TCP, UDP, etc). Si on veut un numéro de port, on peut préciser lequel (et l'IANA le donnera, sauf bonne raison contraire). Les ports rigolos comme 42, 666 ou 1984 (utilisé par un logiciel de surveillance) sont déjà pris.

Rappelez-vous qu'il y aura une grosse différence entre demande d'un numéro de port et demande d'un simple nom de service. Les premiers feront l'objet d'une Expert Review (cf. RFC 5226), le seconds seront distribués sans trop de formalité. Pour les numéros de port, cela dépendra en outre de la plage visée. La plage dynamique ne permet pas de réservation du tout, la plage utilisateur est recommandée pour les nouvelles réservations, la plage système, celle des ports bien connus, est tellement pleine que l'enregistrement est découragé, un avis d'expert ne suffira pas, il faudra un IETF review et encore, après avoir expliqué en détail pourquoi ne pas utiliser un port de la plage utilisateur.

Nouveauté de notre RFC, il y a désormais des procédures explicites pour le retrait d'un enregistrement (section 8.2 ; cela concerne surtout les numéros de port, les noms de service peuvent rester enregistrés sans que cela ne gène personne). Le demandeur original peut demander un retrait, s'il n'a plus besoin de l'enregistrement. Mais l'IANA peut aussi le faire d'autorité, si cela semble vraiment nécessaire.

Dans tous les cas, l'IANA tentera de déterminer si le port est encore utilisé.

En revanche, le transfert d'un enregistrement (numéro de port ou nom de service) d'un protocole à un autre est formellement interdit (section 8.4), même entre adultes consentants. Pas de marché des numéros de port, qui aurait permis à ceux qui avaient déposé des numéros il y a longtemps de gagner de l'argent en les vendant maintenant qu'ils sont rares. Si on veut récupérer un numéro de port, il faut le faire désaffecter, puis candidater pour l'avoir.

Il y aura sans doute des désaccords et des crises (comme dans l'affaire CARP). La procédure habituelle de gestion des conlits à l'IETF (section 7 du RFC 5226) sera donc utilisée.

Un peu d'histoire, maintenant. Quels étaient les procédures avant notre RFC ? Les règles IANA étaient dans le RFC 2780 et notre RFC remplace ses sections 8 et 9. Il y avait aussi des règles spécifiques aux différents protocoles de transport : RFC 3828 pour UDP-Lite, RFC 4340 pour DCCP, et RFC 4960 pour SCTP. Mais elles n'étaient pas complètes (une partie de la procédure était également dans les formulaires Web de soumission à l'IANA, une autre partie était dans le texte du registre), et aussi bien l'IANA que ses « clients » se plaignaient de leur flou (section 1). La section 7.1 de notre RFC 6335 tente de résumer a posteriori les règles (largement informelles) qui étaient utilisées (affectation du port pour TCP et UDP simultanément, pas d'enregistrement des noms de service séparément des ports, SCTP et DCCP traités à part, etc).

En outre, les enregistrements SRV du RFC 2782 ajoutaient leurs propres concepts (nom de service, notion mal définie dans le RFC 2782) et leur propre registre. Ainsi, comme les procédures de l'IANA ne permettaient pas d'enregistrer un nom de service sans obtenir en même temps un numéro de port, on a vu apparaître un registre informel des noms de service (qui a fusionné avec l'officiel, cf. section 10). Un des changements importants de ce RFC 6335 est d'unifier les procédures d'enregistrement et les registres.

La syntaxe admissible pour les noms de service n'avait même jamais été spécifiée (section 2). Les formulaires de l'IANA donnaient une limite de longueur (arbitraire et, d'ailleurs, pas toujours respectée dans le registre) à 14 caractères, mais sans préciser si des caractères comme le + ou le / étaient autorisés. On trouvait donc des noms avec des caractères non-alphanumériques comme whois++ (RFC 2957) ou sql*net.

D'autre part, il n'existait aucune procédure écrite pour les opérations postérieures à l'enregistrement : changement, ou suppression (volontaire ou forcée).

PS : si vous vous intéressez aux questions d'enregistrement de paramètres pour les protocoles, voyez la nouvelle liste de discussion happiana.


Téléchargez le RFC 6335


L'article seul

RFC 6333: Dual-Stack Lite Broadband Deployments Following IPv4 Exhaustion

Date de publication du RFC : Août 2011
Auteur(s) du RFC : A. Durand (Juniper Networks), R. Droms (Cisco), J. Woodyatt (Apple), Y. Lee (Comcast)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF softwire
Première rédaction de cet article le 14 Août 2011


Il existe une myriade de techniques de coexistence entre l'ancien protocole IPv4 et le nouvel IPv6, à tel point qu'on peut même avoir du mal à faire son choix (voir mon exposé à ce sujet). Et le groupe de travail Soft Wires (réseaux virtuels variés) de l'IETF en invente de temps en temps des nouvelles. Pour ne pas s'affoler devant cette multitude, il faut se rappeler que chacune de ces techniques a un but bien précis et sert dans un cas donné. DS-Lite (Dual-Stack Lite), objet de ce RFC, vise les FAI récents, qui n'ont jamais eu d'adresses IPv4 publiques en quantité et dont le réseau interne est en IPv6 depuis le début.

Donc, DS-Lite est à l'opposé de, par exemple, 6rd (RFC 5969), qui vise les FAI existants qui n'ont pas le courage de mettre à jour leur réseau IPv4. DS-Lite vise un autre problème : si, en 2011, je crée un nouveau FAI en Asie (APNIC a été le premier RIR dont le stock d'adresses IP est tombé à zéro), je n'obtiendrai dans le meilleur des cas qu'une poignée d'adresses IPv4 publiques. Mais le reste de l'Internet (et même le réseau local de mes clients, et leurs applications) est majoritairement en IPv4. Mon beau réseau tout neuf, qui pourra être IPv6 depuis le début puisqu'il n'aura pas à porter le poids de l'héritage, ne me servira donc à rien (sauf à voir ce blog, qui est accessible en IPv6). Ce cas n'était pas prévu à l'origine ; il y a eu largement assez de temps pour faire une transition plus simple de IPv4 vers IPv6 mais beaucoup d'acteurs ont traîné les pieds, nous amenant à la situation actuelle, où il faut déployer IPv6 sans pouvoir compter sur des adresses v4 publiques en quantité suffisante. DS-Lite arrive alors à la rescousse.

Le principe de DS-Lite est donc de connecter à l'Internet IPv4 (et bien sûr aussi IPv6) des machines IPv4 (les machines des clients) au dessus d'un FAI v6, et sans avoir beaucoup d'adresses IPv4 publiques. (Les machines purement IPv6 ne sont donc pas concernées, elles ont une connexion native normale, seules les machines/applications qui utilisent encore IPv4 doivent passer par ce bricolage.) Le principe : le réseau local du client a des adresses privées v4. La box encapsule les paquets v4 au dessus du réseau v6 (tunnel IPv4-dans-IPv6) jusqu'à un NAT géant (CGN) qui traduit ces adresses en adresses publiques (il faut donc avoir au moins quelques adresses IPv4 publiques). DS-Lite réutilise donc deux techniques éprouvées, le tunnel et le NAT.

Pour suivre la description détaillée, un peu de vocabulaire (section 3). DS-Lite nécessite deux composants :

  • Le B4 (Basic Bridging Broadband element, le B4 étant un jeu de mots car il se prononce comme before, indiquant que ce composant est avant le tunnel), qui est dans le réseau de M. Toutlemonde, et tunnele les paquets IPv4 de ce M. Toutlemonde vers :
  • L'AFTR (Address Family Transition Router, ce qui se prononce comme after, indiquant que cet élément est après le tunnel), le CGN (routeur NAT géant) qui traduit des adresses IPv4 privées de M. Toutlemonde vers la poignée d'adresses IPv4 publiques qu'a pu obtenir le FAI.

Entre le B4 et l'AFTR, il n'y a qu'IPv6 : tous les paquets IPv4 doivent être tunnelés. Enfin, pour suivre ce RFC, il peut être utile de réviser le vocabulaire de la double-pile (RFC 4213) et du NAT (RFC 4787).

Voici un schéma d'une communication avec le serveur Web d'adresse 192.0.2.23. L'adresse IPv4 publique utilisée par l'AFTR est 203.0.113.201. Le réseau IPv6 du FAI utilise 2001:db8::32. Le réseau local reçoit des adresses en 10.0.0.0/24 :

La section 4 décrit plus en détail les scénarios envisageables pour DS-Lite. Rappelez-vous d'un des points les plus importants des techniques de transition/coexistence v4/v6 : on n'est pas obligés de les déployer toutes, bien au contraire. Chacune s'applique à des cas spécifiques. Les avantages essentiels de DS-Lite, vus par le RFC :

  • Une machine v4 ne communique qu'avec des machines v4 et une v6 qu'avec des v6. La traduction d'adresses se fait uniquement à l'intérieur d'une même famille (contrairement au NAT64 du RFC 6145).
  • DS-Lite découple le déploiement d'IPv6 dans chacun des trois réseaux : celui du client final, celui du FAI et celui de l'Internet global. Plus besoin d'attendre que quelqu'un d'autre commence ou s'y mette.
  • Le FAI n'a pas les limitations d'IPv4 dans son réseau interne (un vrai problème pour certains gros FAI, qui n'ont même pas assez d'adresses v4 pour leur propre réseau interne).
  • Le tunnel entre le B4 et l'AFTR peut être situé où le FAI le désire. Le mode le plus courant sera sans doute avec le B4 dans le CPE et l'AFTR en sortie du réseau du FAI mais ce n'est nullement obligatoire. Cette souplesse permet à la solution de grossir tranquillement. Par exemple, si seuls les clients d'une certaine région utilisent DS-Lite, on met l'AFTR dans cette région puis, si on étend la solution à tout le monde, on reporte simplement le ou les AFTR plus loin et plus près du centre du réseau (cf. annexe A).
  • Comme, du point de vue IPv4, les B4 sont directement connectés à l'AFTR, on peut envisager des techniques de contrôle du NAT par l'utilisateur (par exemple, réserver un port donné), peut-être avec le futur protocole PCP (Port Control Protocol).

J'ai indiqué qu'un déploiement typique mettrait le B4 dans le CPE, dans la box. Ce n'est pas la seule possibilité. Mais ce sera sans doute la plus fréquente (l'annexe B décrit les différentes architectures, avec le détail des adresses). La section 4.2 décrit les caractéristiques d'un CPE ayant une fonction DS-Lite : il inclut un serveur DHCP pour distribuer des adresses IPv4 privées (RFC 1918) sur le réseau local, il ne fait pas de NAT lui-même (contrairement aux CPE d'aujourd'hui), il n'a pas d'adresse IPv4 publique, et, en IPv6, il est simplement un routeur ordinaire, sans traduction, ni particularités (connexion IPv6 native pour les clients qui en sont capables).

S'il n'y a pas de CPE (cas typique d'un smartphone connecté à un réseau 3G), la section 4.3 prend le relais : dans ce cas, la machine connectée doit être son propre B4.

La section 5 décrit en détail la fonction B4. Elle comprend la tunnelisation des paquets IPv4 vers l'AFTR. Au fait, comment le B4 connait-il son AFTR (section 5.4) ? Il doit être configuré avec l'adresse IPv6 de celui-ci, ou bien la récupérer via DHCP avec l'option du RFC 6334.

Pour le service DNS, le B4 doit connaître les adresses IPv6 des serveurs récursifs du FAI (rappelez-vous que la machine qui fait le B4 n'a typiquement pas d'adresse IPv4 publique), par exemple via DHCPv6. Les machines du réseau local, n'ayant pas forcément IPv6, il faut leur fournir un serveur récursif v4. Le RFC recommande que le B4 joue ce role et s'annonce lui-même comme récurseur (et suive alors les recommandations du RFC 5625).

Enfin, le B4 a besoin d'une adresse IPv4 à lui, pour les paquets dont il est l'origine. La plage 192.0.0.0/29 a été réservée pour cela (cf. section 10), le 192.0.0.2 étant pour le B4.

La section 6 fait la même chose (décrire tous les détails) pour la fonction AFTR, qui est à la fois la terminaison du tunnel IPv4-and-IPv6 et le CGN (Carrier-Grade NAT). Par exemple, l'AFTR n'a pas de fonction DNS à assurer (le B4 fait la résolution sur IPv6). Il a lui aussi une adresse bien connue, 192.0.0.1, et c'est celle qu'on verra sans doute souvent lors des traceroute.

Pour que tout cela marche bien, il y a quelques détails techniques à régler. La section 7 couvre ceux qui concernent le réseau : notamment, le tunnel doit respecter les règles des RFC 2473 et RFC 4213. Et la section 8 couvre les détails liés au NAT : possibilité pour un AFTR d'avoir plusieurs plages d'adresses IPv4 publiques, pour des ensembles de B4 différents, conformité impérative aux RFC sur le NAT, comme les RFC 4787, RFC 5508 et RFC 5382, précisions sur la possibilité pour l'AFTR d'être aussi un ALG (découragée, vue le nombre de clients que sert un AFTR, et le nombre de protocoles applicatifs présents et futurs), rappel que tout partage d'adresses, que ce soit par DS-Lite ou une autre méthode, engendre des ennuis (RFC 6269), etc.

L'annexe A du RFC est particulièrement intéressant pour les administrateurs réseaux car il détaille les scénarios de déploiement possibles. Il couvre des questions comme le placement des AFTR dans le réseau, ou la fiabilité requise des AFTR (ils ont un état donc on ne peut pas juste en multiplier le nombre).

Comme tout nouveau protocole, DS-Lite va soulever des questions de sécurité nouvelles, qu'étudie la section 11 du RFC. En soi, les problèmes de sécurité liés au NAT sont bien connus (RFC 2663 et RFC 2993). Mais déplacer la fonction NAT depuis une machine située chez l'utilisateur vers le réseau du FAI crée des nouveaux défis. Par exemple, les adresses IPv4 publiques, qui n'étaient partagées qu'entre les membres d'une même famille ou les employés d'une même entreprise, vont désormais être partagées entre des clients du même FAI, clients qui ne se connaissent pas. Si la HADOPI voit 203.0.113.201 commettre un crime grave (par exemple partager des œuvres d'art), et qu'elle veut couper l'utilisateur de cette adresse, la probabilité de bavure devient bien plus élevée. Enregistrer les adresses IP ne suffit donc plus, il faut noter l'adresse IP et le port (RFC 6302) et que l'AFTR enregistre ses tables de correspondance (identité du tunnel, protocole, adresses et ports), comme précisé en section A.4.

Vu le partage intensif d'adresses (bien plus important qu'avec les NAT sur le CPE), le nombre de ports devient une ressource critique. L'AFTR doit donc faire attention à empêcher les utilisateurs de monter une DoS (volontairement ou par accident) en s'attribuant tous les ports possibles. Par exemple, l'AFTR peut limiter le rythme d'allocation des ports, ou bien mettre une limite absolue au nombre de ports qu'un B4 peut s'allouer.

Enfin, l'AFTR doit veiller à ne pas se transformer lui-même en un outil facilitant les DoS. Par exemple, il ne doit pas permettre à l'autre extrêmité du tunnel d'injecter des paquets IPv4 avec d'autres adresses sources que celles prévues (autrement, les réponses à ces paquets frapperaient un innocent).

Notre RFC ne mentionne pas les inconvénients et problèmes de DS-Lite : c'est un mécanisme complexe, avec plusieurs composants qui doivent travailler en bonne intelligence. DS-Lite dépend notamment d'un composant très sollicité, le CGN. Sera t-il suffisant lorsque des dizaines ou des centaines de réseaux locaux utiliseront le même AFTR ? En outre, comme indiqué plus haut, DS-Lite souffre des problèmes liés au partage d'adresses : les lois HADOPI ou LCEN ne seront pas contentes.

Si, à ce stade, vous êtes convaincu de l'intérêt de DS-Lite dans votre cas, où trouver des implémentations ? Il existe un AFTR en logiciel libre à l'ISC, disponible en http://www.isc.org/software/aftr. Comcast a aussi produit un code pour Linksys (apparemment pas très stable mais suffisant pour des tests) et un pour Mac OS (nommé ComcastDSLiteClient). L'ISC a rassemblé une documentation globale sur le B4. Enfin, les routeurs d'A10 ont la fonction d'AFTR. Verrons-nous bientôt la fonction de B4 dans tous les routeurs et boxes ? Impossible à dire pour l'instant.

Merci à Fabien Delmotte pour ses connaissances sur les mises en œuvre de DS-Lite.


Téléchargez le RFC 6333


L'article seul

RFC 6319: Issues Associated with Designating Additional Private IPv4 Address Space

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : M. Azinger (Frontier Communications), L. Vegoda (ICANN)
Pour information
Première rédaction de cet article le 20 Juillet 2011


Il y a bien longtemps que la pénurie d'adresses IPv4 est une réalité. Longtemps avant leur épuisement complet, ces adresses étaient très difficiles à obtenir, nécessitant un long processus bureaucratique (et le remplissage de nombreux documents), ou tout simplement l'abonnement à une offre qualifiée de « professionnelle » ou « gold » dont le seul intérêt était d'avoir quelques adresses de plus. Résultat, beaucoup d'organisations ont choisi des adresses IP privées et des systèmes de relais ou de traduction d'adresses pour se connecter à l'Internet. Si l'organisation ne grossit pas par la suite, tout va bien. Mais si elle devient plus importante et dépasse la taille permise par les plages d'adresses privées existantes, que se passe-t-il ?

La section 3 du RFC détaille les mécanismes utilisés pour se connecter à l'Internet malgré l'absence d'adresses IP publiques. La principale est sans doute le NAT (RFC 2993 et RFC 3022). Le NAT a de multiples inconvénients, notamment pour les applications pair-à-pair, même si certaines techniques (comme ICE, RFC 5245) permettent de contourner partiellement le problème.

On peut emboîter plusieurs niveaux de NAT, mettant par exemple un traducteur dans la maison ou le bureau et un autre sur le réseau du FAI (on nomme souvent ce double-NAT NAT444). Si le FAI contrôle le CPE et donc les adresses IP qu'il alloue (cas de la Freebox par défaut, par exemple), cela peut marcher. C'est bien plus délicat si le CPE alloue les adresses qu'il veut car, alors, rien ne garantit qu'elles ne seront pas en conflit avec celles utilisées dans le réseau interne du FAI. Bref, le NAT444 ajoute de la complexité et des problèmes. Enfin, toute traduction d'adresses effectuée hors du réseau local de l'abonné soulève les problèmes liés au partage d'adresses que le RFC 6269 documente.

Le plus large bloc privé est le 10.0.0.0/8 (cf. RFC 1918). Il a parfois été suggéré d'allouer de nouveaux blocs pour agrandir l'espace privé mais ce projet a très peu de chances de se matérialiser désormais, vu l'épuisement des adresses IPv4. Ce bloc 10.0.0.0/8 comprend 16 777 216 adresses IP. Qui peut en consommer autant ? Comme le résume la section 2 de notre RFC, les gros opérateurs, par exemple un câblo-opérateur national (comme Comcast, non cité mais qui est effectivement dans ce cas), un opérateur de téléphonie mobile 3G, un gros fournisseur VPN, l'intranet d'une grosse entreprise, peuvent tous se trouver à l'étroit dans ce /8.

Quelles sont les possibilités une fois les adresses du RFC 1918 épuisées ? La section 4 les passe en revue. La première (section 4.1) est évidemment de passer enfin à IPv6, ce qui aurait dû être fait depuis longtemps. Le RFC note à juste titre que déployer IPv6 sur un réseau dont la taille est telle qu'il arrive à épuiser un /8 entier n'est pas une opération triviale. Elle va prendre du temps et c'est pour cela que ces opérateurs auraient dû commencer il y a des années. Si cela n'a pas été fait, l'opérateur peut se trouver dans le cas où les adresses du RFC 1918 sont épuisées et où il n'a matériellement pas le temps de déployer IPv6.

Notons que les adresses IPv6 utilisées ne sont pas forcément globales, on peut aussi déployer IPv6 avec des ULA (RFC 4193). Toutefois, celles-ci ne sont que pseudo-uniques donc, dans des cas comme celui du fournisseur de VPN, le risque de collision existe.

Bon, et pour les administrateurs réseaux qui, en 2011, n'ont toujours pas déployé IPv6, quelles solutions ? La section 4.2 liste les solutions purement v4. Obtenir de nouvelles adresses était la solution classique. Mais ajourd'hui, où les RIR qui ont encore des adresses IPv4 les épuisent vite et passent à la politique d'allocation finale, cela ne parait pas très réaliste.

La seconde solution est d'acquérir des adresses IP d'autres organisations, comme l'avait fait Microsoft dans une opération fameuse. Cette opération peut désormais être légale vis-à-vis des RIR comme le montre l'étude comparée de leurs politiques de transfert. Les possibilités pratiques d'un tel transfert sont très incertaines. Y aura-t-il assez d'adresses sur ce « marché » ? Et à quel coût ? Personne ne le sait trop. Mais le RFC est pessimiste : on ne trouvera probablement pas de larges blocs d'adresses continus ainsi, il est plus probable qu'il n'y aura qu'une poussière de /24 et /23. (Le RFC discute aussi la possibilité de locations de tels blocs, encore pire car sans garantie sur ce qui arrivera au terme de la location.)

Il y a bien sûr une autre possibilité. Après tout, qui a dit qu'il fallait être honnête et respecter les règles de vie en société ? Comme le montre l'exemple d'innombrables hommes d'affaires, on réussit bien mieux en violant ces règles et en écrasant les autres. La section 4.2.2 du RFC est donc consacrée à la solution libérale : prendre ce qui vous intéresse sans se poser de questions, ici, utiliser des adresses IP non encore allouées, ou bien allouées à quelqu'un mais pas annoncées dans la table de routage mondiale. L'article de Duane Wessels montre bien que l'espace non alloué est déjà utilisé. C'est évidemment très mal de faire cela : les rares blocs non encore alloués vont l'être bientôt (et cela fera une collision avec ceux du voleur, avec des conséquences imprévisibles), et ceux qui ne sont pas annoncés dans la table de routage publique le seront peut-être demain. Même si ce n'est pas le cas, la collision est toujours possible (cela dépend de la façon dont est configuré le réseau qui utilisait ces adresses mais, par exemple, les adresses internes fuient souvent, par exemple dans les en-têtes de courrier). La section 2.3 du RFC 3879 discute plus en détail ce problème. Il y a aussi bien sûr des risques juridiques à jouer avec les adresses des autres. Cela peut expliquer pourquoi les voleurs d'adresses préfèrent utiliser des préfixes alloués à des opérateurs peu dangereux juridiquement, par exemple en Afrique.

Quelle solution pourrait-on développer ? La section 5 examine plusieurs possibilités : la première est d'agrandir le RFC 1918 en y ajoutant des préfixes actuellement marqués comme publics. Cela réduirait encore plus le stock d'adresses IPv4 disponibles. Plusieurs propositions avaient été faites de réserver, par exemple un /8 supplémentaire. Par exemple, le réseau 1.0.0.0/8 était tentant car son utilisation publique soulevait des problèmes. Comme indiqué plus haut, il est clair que cela se fait déjà, de manière officieuse. Aucune de ces propositions n'a été adoptée officiellement et leurs chances semblent désormais nulles. (Voir la discussion à NANOG.)

Il y a en effet pas mal de systèmes qui traitent les adresses du RFC 1918 de manière spéciale, et où ces adresses sont codées en dur. Il y a peu de chances de pouvoir mettre à jour tous ces systèmes. Déjà, dé-bogoniser les plages allouées est très difficile.

Dernière possibilité, réaffecter une plage réservée, 240.0.0.0/4, qui avait été mise de côté pour des usages futurs qui ne se sont jamais concrétisés. Le problème est que beaucoup de systèmes déployés traitent de manière spécifique ces adresses et qu'il y a peu de chance de pouvoir les changer tous. En pratique, elles seront donc largement inutilisables. Par exemple, sur Linux :

% sudo ifconfig eth1 240.0.0.1/24 
SIOCSIFADDR: Invalid argument

(Mais ça marche sur FreeBSD et NetBSD). L'Internet-Draft draft-fuller-240space documente ce problème pour quelques systèmes.)

Bref, même si le RFC ne le rappelle pas, il n'y a pas vraiment d'autre solution que de migrer vers IPv6.


Téléchargez le RFC 6319


L'article seul

RFC 6317: Basic Socket Interface Extensions for Host Identity Protocol (HIP)

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : M. Komu (Helsinki Institute for Information Technology), T. Henderson (The Boeing Company)
Expérimental
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 23 Juillet 2011


Il ne sert à rien de disposer d'un nouveau protocole si les applications ne s'en servent pas. Et, pour qu'il y ait une chance qu'elles s'en servent, il faut qu'elles aient une API standard pour cela. Ce RFC spécifie une possible API pour le protocole HIP (RFC 4423), un protocole qui sépare l'adresse IP de l'identité d'une machine. Celle-ci est désormais une clé cryptographique et l'API permet d'établir des connexions en connaissant la clé.

Cette API ne concerne pour l'instant que le langage C. Son utilité principale commence lorsque l'identificateur HIP a été obtenu (par exemple par le DNS, cf. RFC 5205) et lorsque l'adresse IP est connue. Elle prévoit toutefois d'autres cas. Spécifique à HIP, elles pourrait toutefois être étendue dans le futur à d'autres protocoles réalisant une séparation du localisateur et de l'identificateur, comme SHIM6 (RFC 5533). Notez que cette API utilise déjà certaines extensions créées pour SHIM6 et spécifiées dans le RFC 6316.

À quoi ressemblent les identificateurs que manipule cette API ? Nommés HIT pour Host Identity Tag, ce sont des résumés cryptographiques des clés publiques des machines (clés nommées HI pour Host Identity). Stockés sur 128 bits, ils sont, pour faciliter leur traitement, représentés sous forme d'adresses IPv6, en utilisant le préfixe ORCHID décrit dans le RFC 4843. Par exemple, 2001:10::1 est un HIT.

Certaines applications, ignorantes de ce qui se passe dans les couches basses, n'auront pas besoin d'être modifiées pour HIP (cf. RFC 5338). Les autres doivent suivre notre RFC, dont la section 1 expose les principes généraux :

  • Extension à l'interface socket telle que décrite dans le RFC 3493.
  • Nouvelle famille d'adresses, AF_HIP.
  • Possibilité de se connecter à un pair dont on connait l'identité mais aussi, en mode « opportuniste » à un pair inconnu (cf. section 4.1.6 du RFC 5201).

Bien, commençons par le commencement, la résolution de noms (section 3). D'abord, le cas où l'application a un résolveur à sa disposition (section 3.1). Celui-ci, en échange d'un nom de domaine, fournit les informations qu'il a trouvées, typiquement dans le DNS : HIT ou HI, adresses IP et peut-être des serveurs de rendez-vous (RFC 5204). L'application a donc uniquement à appeler getaddrinfo() et elle récupère des HIT, qu'elle utilise pour remplir les informations transmises à la prise. Le résolveur a fourni à HIP les informations auxiliaires comme la correspondance entre un HI et des adresses IP.

Et si on n'a pas de résolveur HIP (section 3.2) ? Cette API permet à une application, de fournir quand même tous les détails nécessaires pour réussir une connexion (notamment les adresses IP associées à un HI).

La section 4 définit formellement la nouvelle API. D'abord, les structures de données. Le nouveau type sockaddr est défini ainsi :

           typedef struct in6_addr hip_hit_t;

           struct sockaddr_hip {
                     uint8_t        ship_len;
                     sa_family_t    ship_family;
                     in_port_t      ship_port;
                     uint32_t       ship_flags;
                     hip_hit_t      ship_hit;
           };

Le résolveur prend des nouvelles options (section 4.2). La nouvelle famille AF_HIP, passée à getaddrinfo(), indique que l'application veut uniquement parler HIP et que toutes les sockaddr doivent donc être de ce type, quant à l'option AI_NO_HIT, elle indique au contraire que l'application ne veut pas entendre parler de HIP.

Une fois la connexion HIP établie, l'application peut se servir de getsockname() et getpeername() pour trouver des informations sur la machine paire (section 4.3). Elles permettent par exemple d'accéder au HIT de celle-ci (ce qui est utile si l'application acceptait n'importe quel HIT).

Si la machine dispose de plusieurs identités, le choix du HIT utilisé comme source est laissé à l'initiative du système. Si l'application veut l'influencer, elle peut se servir de mécanismes analogues à ceux du RFC 5014 : une option de setsockopt(), HIT_PREFERENCES (section 4.4), et deux valeurs possibles :

  • HIT_PREFER_SRC_HIT_TMP : donner la préférence aux HIT temporaires (dits aussi « anonymes », cf. sections 5.1.2 et 7 du RFC 5201),
  • HIT_PREFER_SRC_HIT_PUBLIC : donner la préférence aux HIT publics.

Si HIP_HIT_ANY signifiait qu'on exigeait une connexion HIP mais avec n'importe qui, HIP_ENDPOINT_ANY indiquait qu'on n'avait même pas cette préférence et que des connexions non-HIP étaient possibles. Mais, après coup, on veut parfois savoir ce qu'on a obtenu et la nouvelle fonction sockaddr_is_srcaddr() (section 4.5) permet de savoir si le pair avec lequel on s'était connecté utilisait HIP ou pas. (Il y a aussi une fonction hip_is_hit() qui teste simplement si une valeur de 128 bits est bien un HIT.)

On l'a vu, cette API permet, dans une large mesure, à une application de se connecter en HIP en ignorant presque tout de ce protocole : il suffit d'indiquer AF_HIP au lieu de AF_INET6 et ça roule. La traduction des HIT en localisateurs est notamment effectuée automatiquement, l'application ne se souciant pas de ces derniers. Toutefois, certaines applications peuvent vouloir davantage de contrôle, notamment sur le choix des localisateurs (les adresses IP). La section 4.6 est faite pour elles. Elle s'appuie sur les options SHIM6 du RFC 6316. Par exemple, l'option SHIM_LOC_PEER_PREF permet, avec setsockopt(), de définir le localisateur préféré et, avec getsockopt(), de découvrir le localisateur utilisé.

Quelques points sur la sécurité viennent compléter ce RFC, en section 6. Ainsi, l'option HIP_ENDPOINT_ANY dit explicitement qu'on accepte des pairs non-HIP, pour les connexions entrantes ou sortantes. On peut donc se retrouver sans la sécurité associée à HIP (notamment l'authentification du pair). Les applications soucieuses de sécurité devraient donc utiliser HIP_HIT_ANY et pas HIP_ENDPOINT_ANY.

Aujourd'hui, cette extension de l'API traditionnelle ne se retrouve pas encore dans Linux, ni dans un des BSD. Pour cela, un programme comme echoping n'a donc pas encore de possibilité d'utiliser HIP (cf. bogue #3030400.)


Téléchargez le RFC 6317


L'article seul

RFC 6314: NAT Traversal Practices for Client-Server SIP

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : C. Boulton (NS-Technologies), J. Rosenberg (Skype), G. Camarillo (Ericsson), F. Audet (Skype)
Pour information
Première rédaction de cet article le 23 Juillet 2011


Aujourd'hui, il est rare pour une machine individuelle (ordinateur de bureau, ordinateur portable, smartphone, tablette, etc) d'avoir un vrai accès Internet. Presque toujours, la malheureuse machine est limitée à une adresse IP privée et coincée derrière un NAT qui traduira cette adresse à la volée. Cela ne gêne pas trop certains protocoles (SSH sortant, par exemple) mais est beaucoup plus gênant pour d'autres, notamment le protocole de téléphonie sur IP SIP. Ce RFC décrit l'ensemble des techniques que doivent mettre en œuvre les clients SIP pour arriver à passer quand même. C'est la meilleure lecture pour commencer à se pencher sur le problème « pourquoi a-t-on si souvent des problèmes avec SIP ? ».

Pour comprendre pourquoi SIP (RFC 3261) est particulièrement affecté, il faut se rappeler qu'il utilise des références : le client SIP indique au serveur à quelle adresse répondre, par exemple à quelle adresse envoyer les paquets audio du protocole compagnon RTP (RFC 3550). En présence d'un NAT, la machine ne connait pas son adresse IP telle que vue de l'extérieur et, de toute façon, le NAT traditionnel (qui agit sur le port, pas seulement sur l'adresse en dépit de son nom) bloque les paquets entrants, ne sachant pas que le flux RTP est lié à la connexion SIP. Pire, les différents routeurs NAT ont des comportements différents et il est donc difficile de trouver une solution qui marche partout (RFC 4787).

Ces problèmes du NAT sont bien connus et documentés. L'essentiel du code réseau d'un client SIP est consacré à contourner le NAT. Des solutions partielles ont été développées comme STUN (RFC 5389), TURN (RFC 5766), ICE (RFC 5245) ou bien des solutions spécifiques à SIP comme le RTP symétrique (RFC 4961), ou le SIP sortant (RFC 5626). Toutes ces solutions sont partielles et il manquait un document de haut niveau, décrivant le mécanisme général. Ce RFC 6314 ne propose donc pas « encore un nouveau protocole » mais explique la marche à suivre et les bonnes pratiques pour passer outre les routeurs NAT.

SIP peut être utilisé dans des contextes très différents : ce RFC se focalise sur l'utilisation en « client-serveur » où un client SIP (par exemple un softphone) appelle un fournisseur SIP qui routera l'appel vers le destinataire. Le SIP pair-à-pair (actuellement expérimental) n'utilisera pas forcément les mêmes techniques.

La section 3 détaille le problème que rencontrent les clients SIP en présence du NAT. Si le routeur NAT contient un ALG, celui-ci peut interférer avec SIP, par exemple en interdisant les communications chiffrées, ou bien en imposant que le même chemin soit emprunté à l'aller et au retour. Comme documenté dans les RFC 4787, RFC 3424 et RFC 5245, les ALG sont donc une solution limitée.

Et s'il n'y a pas d'ALG ? Dans ce cas, voyons comment SIP établit une connexion avec son fournisseur, par défaut. Le client envoie une requête sur UDP et le serveur est censé répondre au couple {adresse, port} de l'en-tête Via: de cet en-tête. Mais, après le passage du routeur NAT, cette adresse et son port, mis là par le client original, ne correspondent plus à rien d'utile. Même si le paquet de réponse atteint le NAT, il sera typiquement jeté par lui. Même si le client SIP s'était connecté en utilisant TCP, les appels qu'il recevra (INVITE) ne seront pas routés sur cette connexion TCP mais envoyés à l'adresse indiqué ce qui, là encore, ne marchera pas (sans compter d'autres problèmes comme la fermeture automatique de la session par le NAT après un délai de garde).

Cela, c'était pour la signalisation, pour le protocole SIP lui-même. Mais un coup de téléphone complet nécessite aussi de faire passer les données, les paquets audio. Ceux-ci voyagent en général via la protocole RTP (RFC 3550, le protocole à utiliser, les ports où envoyer les données, etc, étant indiqués via SDP (RFC 4566) ou bien via une requête SIP spécifique (RFC 3264). Même si la session SIP a été bien établie, ces paquets RTP risquent fort de ne pas arriver, les adresses et les numéros de port qu'indiquent SDP ou SIP n'ayant pas de signification en dehors du réseau local.

Donc, pour résumer cette section 3, SIP a deux problèmes avec le NAT :

  • Pour la signalisation (SIP à proprement parler), requêtes entrantes et sortantes (pours des raisons différentes),
  • Et pour les données (en général SDP + RTP).

Soyons maintenant positifs et voyons les solutions (section 4). Pour la signalisation, la section 4.1 expose les méthodes possibles :

  • Pour les requêtes sortantes, la réponse symétrique, où la réponse est envoyée au port d'origine (comme le font d'autres protocoles UDP comme le DNS), port ouvert sur le NAT par l'envoi de la requête. Cette méthode est décrite dans le RFC 3581.
  • Pour les requêtes entrantes (RFC 5626), le fournisseur SIP doit garder trace du port utilisé et s'en servir pour acheminer les appels entrants.

Pour le transport des données, la section 4.2 cite :

  • Le RTP symétrique (RFC 4961) qui permet d'ouvrir un trou dans le NAT depuis l'extérieur, avant de demander au pair d'y envoyer le trafic.
  • RTCP (section 6 du RFC 3550) et le RFC 3605 pour indiquer le port à utiliser.
  • Et surtout la solution totale, la combinaison de STUN (RFC 5389) et TURN (RFC 5766), orchestrés par ICE (RFC 5245). STUN permet de découvrir l'adresse IP publique qui va être utilisée pour les communications externes, TURN va relayer le trafic pour les cas où le routeur NAT est particulièrement désagréable et empêche STUN de fonctionner (TURN est très coûteux en ressources puisque chaque paquet de données doit être ainsi relayé, mais il marche dans tous les cas), et ICE a pour rôle d'essayer successivement et intelligement plusieurs méthodes de traversée de NAT (STUN, TURN et d'autres) pour choisir la plus adaptée.

La section 5 illustre ensuite ces méthodes par divers exemples. En voici un très simple, pour la signalisation, où le client, 192.168.1.2 est derrière un NAT (qui réécrit son adresse en 172.16.3.4) et s'enregistre auprès d'un fournisseur SIP, Example.com. La requête est :


   REGISTER sip:example.com SIP/2.0
   Via: SIP/2.0/UDP 192.168.1.2;rport;branch=z9hG4bKnashds7
   Max-Forwards: 70
   From: Bob <sip:bob@example.com>;tag=7F94778B653B
   To: Bob <sip:bob@example.com>
   Call-ID: 16CB75F21C70
   CSeq: 1 REGISTER
   Supported: path, outbound
   Contact: <sip:bob@192.168.1.2 >;reg-id=1
       ;+sip.instance="<urn:uuid:00000000-0000-1000-8000-AABBCCDDEEFF>"
   Content-Length: 0

Le client SIP a utilisé le paramètre rport (RFC 3581) dans l'en-tête Via: pour indiquer que le serveur doit répondre au port d'où vient la requête (et que le routeur NAT a ouvert). La réponse est :


   SIP/2.0 200 OK
   Via: SIP/2.0/UDP 192.168.1.2;rport=8050;branch=z9hG4bKnashds7;
        received=172.16.3.4
   From: Bob <sip:bob@example.com>;tag=7F94778B653B
   To: Bob <sip:bob@example.com>;tag=6AF99445E44A
   Call-ID: 16CB75F21C70
   CSeq: 1 REGISTER
   Supported: path, outbound
   Require: outbound
   Contact: <sip:bob@192.168.1.2 >;reg-id=1;expires=3600
        ;+sip.instance="<urn:uuid:00000000-0000-1000-8000-AABBCCDDEEFF>"
   Content-Length: 0

et le paramètre received du champ Via: indique l'adresse IP source qu'avait vue le serveur. (Une autre solution aurait été d'utiliser TCP.) Les amateurs de scénarios plus complexes seront comblés, avec le reste de la longue section 5.

À noter qu'un argument souvent présenté en faveur de Skype, par rapport à SIP, est son meilleur comportement en présence de NAT hostiles (parfois très hostiles, par exemple ne laissant passer que HTTP). Il est amusant de noter que deux des auteurs du RFC travaillent chez Skype. Mais, surtout, si les clients SIP ont souvent moins de succès que Skype lors de la traversée de routeurs très fermés, c'est pour trois raisons :

  • Tous les logiciels SIP ne mettent pas encore en œuvre l'intégralité des recommandations résumées dans ce RFC 6314. La qualité des clients et serveurs SIP existants est très variable.
  • Skype utilise également des méthodes non-standard (par exemple il peut tunneler la voix sur HTTP, bricolage très contestable mais qui est parfois la seule voie restée ouverte),
  • Et Skype utilise également des méthodes de parasite, comme d'enrôler comme relais des machines qui n'ont rien demandé ce qui, à juste titre, suscite des protestations.

Téléchargez le RFC 6314


L'article seul

RFC 6305: I'm Being Attacked by PRISONER.IANA.ORG!

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : J. Abley (ICANN), W. Maton (NRC-CNRC)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 14 Juillet 2011


Un RFC très inhabituel, non seulement par son titre amusant mais aussi parce que le public visé n'est pas le programmeur qui va mettre en œuvre des normes, ni même l'administrateur réseaux qui s'occupe de grands réseaux complexes, mais un public bien plus large, celui des gens qui gèrent un petit réseau, ont installé comme pare-feu ou IDS une boîte noire à laquelle ils ne comprennent rien, et qui voient arriver des messages d'alerte comme quoi leur petit réseau serait attaqué par un mystérieux prisoner.iana.org. Ce RFC a été écrit pour fournir à l'IANA et aux opérateurs de serveurs de l'AS112 (décrit dans le RFC 6304) une réponse toute faite à envoyer à ces angoissés.

En effet, l'« attaque » en question n'est pas une attaque et ne vient pas de l'IANA ou de l'AS112. Elle est entièrement de la faute des administrateurs de ces réseaux soi-disant attaqués. Un certain nombre de petits réseaux utilisent, soit parce qu'il n'y a plus d'adresses IPv4 disponibles, soit parce qu'ils croient à tort que cela leur apporte une certaine sécurité, des adresses IP privées, tirées du RFC 1918. Ces adresses étant spécifiques à un certain réseau, n'ayant pas de signification globale, les requêtes DNS demandant les noms associés à ces adresses ne devraient jamais sortir du réseau local (section 2 du RFC) et être toujours traitées par un serveur DNS interne. Mais, en pratique, c'est loin d'être le cas, et les serveurs de in-addr.arpa, le domaine utilisé pour la résolution d'adresses IP en noms (section 3), reçoivent un trafic important et inutile. Pour le traiter sans charger ces serveurs, les domaines servant aux plages d'adresses du RFC 1918 sont déléguées à l'AS112 (RFC 6304) qui est chargé de répondre « ce domaine n'existe pas » à toutes ces requêtes.

Mais, comme les requêtes de ce type sont des erreurs (rappelez-vous qu'elles n'auraient normalement jamais dû sortir), les réponses qu'envoie l'AS112 sont souvent inattendues pour le réseau local. Et, si le pare-feu ou l'IDS sont bizarrement configurés (ce qui est fréquent sur ces réseaux mal gérés), la réponse DNS à leur question leur apparait comme une tentative d'attaque ! S'ils se plaignent, l'idée est de simplement leur renvoyer ce RFC 6305 à lire.

Ce RFC explique donc en termes simples ce que sont les adresses privées, ce qu'est la résolution d'adresses en noms, les raisons pour lesquelles est déployé l'AS112 (section 4 du RFC), et les noms et adresses des serveurs de l'AS112 (section 5) notamment le prisoner.iana.org qui donne son titre au RFC. Pour augmenter les chances que Google trouve cet article, je cite ici ces informations :

  • PRISONER.IANA.ORG (192.175.48.1),
  • BLACKHOLE-1.IANA.ORG (192.175.48.6),
  • Et BLACKHOLE-2.IANA.ORG (192.175.48.42).

La section 6 explique ensuite le mécanisme par lequel la fausse alerte est déclenchée : un résolveur DNS du réseau local envoie la requête, par exemple PTR 1.2.20.172.in-addr.arpa, elle arrive aux serveurs de l'AS112, qui répondent, mais leurs réponses sont, pour des raisons diverses, bloquées. Normalement, le pare-feu ne couine pas pour chaque paquet bloqué mais, ici, les requêtes étant souvent déclenchées automatiquement par un logiciel, elles peuvent être nombreuses, provoquant de fréquentes réponses, qui peuvent ressembler à une attaque. Deux autres phénomènes expliquent cette perception : si la réponse est bloquée, la machine à l'origine de la requête va réessayer, souvent très vite. Et si le résolveur DNS refait ces essais avec des numéros de port croissant régulièrement, les réponses ressembleront à un balayage de ports.

Que devrait donc faire l'administrateur du site au lieu de harceler l'IANA ou les opérateurs de l'AS112 ? La section 7 lui donne quelques pistes, pour résoudre le problème qu'il a causé :

  • Convaincre les machines terminales de ne pas chercher à résoudre les adresses en noms. Cela coupe le problème à la source, mais c'est évidemment assez difficile à faire dans un grand réseau, où l'administrateur du pare-feu ne contrôle pas forcément chaque machine. Par exemple, une bonne partie du trafic de l'AS112 provient des réseaux de téléphonie mobile et l'opérateur du pare-feu ne peut évidemment pas intervenir sur chaque téléphone.
  • Bloquer sur le pare-feu non pas les réponses de l'AS112 mais les questions envoyées à ce service. Cela résoudrait complètement le problème de l'AS112 mais, sur le site, les résolutions des adresses en noms se bloqueraient, ce qui pourrait avoir des conséquences gênantes.
  • Configurer les résolveurs du réseau local pour répondre avec autorité pour les zones correspondant aux adresses privées. C'est sans doute la solution la plus simple et le plus efficace à la fois. Elle est décrite avec plus de détails dans le RFC 6303.
  • Plus geek, mettre en place une instance locale de l'AS112 (RFC 6304).

Téléchargez le RFC 6305


L'article seul

RFC 6304: AS112 Nameserver Operations

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : J. Abley (ICANN), W. Maton (NRC-CNRC)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 14 Juillet 2011


Le système AS112, décrit dans ce RFC, est à la fois un utile composant du DNS, améliorant les performances et reduisant la charge du réseau, un banc d'essai pour des nouvelles techniques comme l'anycast, et une expérimentation sociale, celle d'un service 100 % acentré.

Comme beaucoup de bonnes choses sur l'Internet, la documentation arrive comme les carabiniers, longtemps après. Car l'AS112 tourne depuis des années. Pour comprendre son rôle, il faut d'abord se pencher sur le problème à résoudre.

Un certain nombre de sites connectés à l'Internet utilisent des adresses IP privées, tirées du RFC 1918. Bien des logiciels, lorsqu'ils voient passer un nouveau client, font une résolution DNS pour obtenir le nom du client en fonction de son adresse IP (résolution dite PTR). C'est par exemple le cas du serveur de courrier Postfix, chez qui ce comportement n'est pas débrayable. Lorsque l'adresse IP est privée, il ne sert à rien de poser la question au DNS public. Par définition, celui-ci ne peut pas savoir que MaPetiteEntreprise utilise 192.168.1.0/24 et a attribué 192.168.1.33 à posteclientX.mapetiteentreprise.com. La bonne pratique est donc que l'administrateur réseaux d'un site qui utilise ces adresses privées doit configurer des serveurs DNS pour répondre aux requêtes PTR (cf. RFC 6303). Pour voir cela, on peut utiliser l'option -x de dig, qui permet de faire automatiquement une résolution d'adresse en nom. Le domaine in-addr.arpa (RFC 5855) accueille la forme inversée des adresses (192.168.1.33 devient 33.1.168.192.in-addr.arpa). Testons ici une adresse publique :

% dig -x 192.134.4.20
...
;; ANSWER SECTION:
20.4.134.192.in-addr.arpa. 172800 IN    PTR     rigolo.nic.fr.

Mais beaucoup d'administrateurs réseaux sont négligents, surchargés de travail, incompétents ou les trois à la fois. Ils ne configurent pas ces serveurs DNS et, résultat, la requête PTR sort de leur réseau et va taper sur les serveurs DNS de la racine puis à ceux de in-addr.arpa. (Une bonne partie du trafic semble ainsi venir des réseaux 3G, où le smartphone ne reçoit qu'une adresse privée et où le résolveur DNS qui lui est indiqué ne connait pas les zones correspondantes.) Ceux-ci ont normalement autre chose à faire que de répondre à des requêtes qui sont, dès le départ, des erreurs. Ils délèguent donc à l'AS112, un ensemble de serveurs de noms qui est chargé de répondre « ce nom n'existe pas » à toutes ces requêtes parasites. L'AS112 est donc un puits où finissent les erreurs.

On peut voir la délégation de l'AS112 avec dig :


% dig NS 168.192.in-addr.arpa

; <<>> DiG 9.7.1 <<>> NS 168.192.in-addr.arpa
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56273
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;168.192.in-addr.arpa.          IN      NS

;; ANSWER SECTION:
168.192.in-addr.arpa.   300     IN      NS      blackhole-2.iana.org.
168.192.in-addr.arpa.   300     IN      NS      blackhole-1.iana.org.

;; ADDITIONAL SECTION:
blackhole-1.iana.org.   3500    IN      A       192.175.48.6
blackhole-2.iana.org.   3500    IN      A       192.175.48.42

;; Query time: 29 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Jul  6 12:34:19 2011
;; MSG SIZE  rcvd: 141

La délégation va être conservée dans les mémoires caches des résolveurs DNS et la racine ou in-addr.arpa ne seront donc plus embêtés, après la première requête.

Mais qui sont ces machines 192.175.48.6 et 192.175.48.42 ? Des très gros serveurs payés par un mécène et installées à un endroit bien connecté ? Pas du tout. C'est ici que rentre en jeu l'AS112. Ce dernier est composé d'un réseau informel de dizaines de machines un peu partout dans le monde et qui annoncent toutes être 192.175.48.6 et 192.175.48.42. Chacune de ces machines encaisse une partie de la charge. L'AS112 n'a pas de chef, juste un site Web et, depuis aujourd'hui, un RFC, ce RFC 6304.

L'AS112 doit son nom au numéro de système autonome qui lui a été attribué. Ses serveurs utilisent l'anycast (RFC 4786) pour distribuer la charge entre eux. Avant Global Anycast, c'était donc le premier projet d'anycast entre serveurs faiblement coordonnés.

Les détails pratiques, maintenant. La liste des zones servies figure en section 2.1. Elle comprend 10.in-addr.arpa pour le réseau 10.0.0.0/8, de 16.172.in-addr.arpa à 31.172.in-addr.arpa pour le 172.16.0.0/12, et 168.192.in-addr.arpa pour le 192.168.0.0/16, les préfixes du RFC 1918. Elle inclus aussi 254.169.in-addr.arpa pour le préfixe « local au lien » du RFC 5735. Pour aider à l'identification du nœud qui répond, les serveurs de l'AS112 servent également la zone hostname.as112.net, ici à Paris :


% dig +nsid TXT hostname.as112.net

; <<>> DiG 9.7.3 <<>> +nsid TXT hostname.as112.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1078
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 2, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;hostname.as112.net.            IN      TXT

;; ANSWER SECTION:
hostname.as112.net.     267     IN      TXT     "Unicast IP: 193.17.192.194"
hostname.as112.net.     267     IN      TXT     "See http://as112.net/ for more information."
hostname.as112.net.     267     IN      TXT     "See http://noc.hivane.net/cgi-bin/dsc-grapher.pl for local information."
hostname.as112.net.     267     IN      TXT     "Paris, FR"
hostname.as112.net.     267     IN      TXT     "Hivane Networks"

;; AUTHORITY SECTION:
hostname.as112.net.     267     IN      NS      blackhole-2.iana.org.
hostname.as112.net.     267     IN      NS      blackhole-1.iana.org.

;; ADDITIONAL SECTION:
blackhole-1.iana.org.   241     IN      A       192.175.48.6
blackhole-2.iana.org.   241     IN      A       192.175.48.42

;; Query time: 1 msec
;; SERVER: 217.70.184.225#53(217.70.184.225)
;; WHEN: Wed Jul  6 12:36:14 2011
;; MSG SIZE  rcvd: 348

On note que les préfixes IPv6 n'y figurent pas. Une des discussions les plus vives sur ce RFC, et qui explique le temps très long qu'il a mis à sortir, portait sur la délégation de préfixes d'ip6.arpa à l'AS112. Aucune décision n'a encore été prise et, pour l'instant, notre RFC 6304 décrit l'état actuel de l'AS112 (on peut avoir une liste à jour sur le site officiel).

La section 2.2 décrit les serveurs de noms qui reçoivent la délégation, joliment (mais incorrectement, puisqu'ils répondent) nommés blackhole-1.iana.org et blackhole-2.iana.org (en dépit de leurs noms, les serveurs de l'AS112 ne sont pas gérés par l'IANA, cf. section 7). Dans le champ MNAME du SOA de la zone déléguée, on trouve également prisoner.iana.org dont la tâche principale est de répondre aux mises à jour dynamiques (RFC 2136) que certaines machines envoient audit MNAME.

Ce RFC 6304 n'est pas seulement la description d'une technique mais également un HOWTO sur la configuration d'un serveur de l'AS112. De tels textes, prévus pour les administrateurs système, sont rares dans les RFC. La section 3 décrit ainsi tout ce que doit savoir le volontaire qui va créer un nouveau nœud. Il doit connaître BGP (RFC 4271), nécessaire pour l'anycast (RFC 4786) et la gestion d'un serveur DNS faisant autorité. Les serveurs de l'AS112 peuvent être situés n'importe où mais ils sont surtout utiles dans les endroits bien connectés, notamment les points d'échange. Ils peuvent être locaux (annonçant les routes avec la communauté BGP no-export, 0xFFFFFF01, cf. RFC 1997), ou globaux (servant le monde entier). Et naturellement, ils doivent se coordonner (via une liste de diffusion) avec les autres serveurs de l'AS112.

L'AS112 n'impose pas de système d'exploitation particulier (section 3.3) mais tous les serveurs existants semblent utiliser Unix et tous (c'est difficile à dire, puisque l'AS112 ne contrôle pas tout ce qui se passe sur les serveurs) se servent de BIND. Il est recommandé que la machine AS112 soit dédiée à cette tâche : ces serveurs reçoivent parfois un trafic intense qui pourrait perturber leurs autres activités.

Le serveur signale son existence et sa disponibilité en BGP. Il faut donc coupler le serveur de noms au serveur BGP, pour que l'arrêt du serveur DNS entraîne l'arrêt de l'annonce (le RFC ne fournit pas de script pour cela). Un exemple de comment cela peut se réaliser sur Linux, avec les adresses de l'AS112 attachées à une interface dummy, est (code utilisé sur un serveur anycast réel, quoique pas de l'AS112) :

# Load the variables (the machine is a RedHat)
. /etc/sysconfig/network-scripts/ifcfg-eth0

# Test if the name server actually works. Do not use ps: the server
may be there but unresponsive
TMP=(`dig +short +time=1 +tries=1 @${IPADDR} SOA example.`)
MASTER=${TMP[0]:=somethingwaswrong}

# Normal reply or not?
if test ${MASTER} != "nsmaster.nic.example."
then
    # Disable the interface: Quagga will stop announcing the route
    ifdown dummy0
    # Raise an alarm, send SMS, etc
fi

Le serveur BGP annonce le préfixe 192.175.48.0/24 qui couvre les adresses de tous les serveurs et l'origine est évidemment 112.

Les exemples du RFC supposent que le serveur BGP est Quagga mais cela peut évidemment marcher avec d'autres. Dans l'exemple ci-dessous, tiré du RFC (section 3.4), le router ID est 203.0.113.1 et le serveur BGP a deux pairs, 192.0.2.1 et 192.0.2.2. Voici un extrait du bgpd.conf (la version intégrale est dans le RFC) :

   hostname my-router
...
   router bgp 112
    bgp router-id 203.0.113.1
    network 192.175.48.0/24
    neighbor 192.0.2.1 remote-as 64496
    neighbor 192.0.2.1 next-hop-self
    neighbor 192.0.2.2 remote-as 64497
    neighbor 192.0.2.2 next-hop-self

En farfouillant sur le site officiel (pas très bien organisé, je trouve), on peut trouver d'autres exemples.

Le serveur AS112 a ensuite besoin d'un serveur DNS faisant autorité (section 3.5), évidemment compatible avec toutes les règles du DNS (RFC 1034). Les exemples de configuration du RFC sont fondés sur BIND. Voici un extrait du named.conf (la version intégrale est dans le RFC) :

   options {
     listen-on {
        ...
        // the following addresses correspond to AS112 addresses, and
        // are the same for all AS112 nodes
        192.175.48.1;      // prisoner.iana.org (anycast)
        192.175.48.6;      // blackhole-1.iana.org (anycast)
        192.175.48.42;     // blackhole-2.iana.org (anycast)
     };
     recursion no;        // authoritative-only server
   };

   // RFC 1918
   zone "10.in-addr.arpa" { type master; file "db.empty"; };
   ...

   // RFC 5735
   zone "254.169.in-addr.arpa" { type master; file "db.empty"; };

   // also answer authoritatively for the HOSTNAME.AS112.NET zone,
   // which contains data of operational relevance
   zone "hostname.as112.net" {
     type master;
     file "db.hostname.as112.net";
   };

Un exemple équivalent pour NSD (utilisé sur le nœud AS112 de Paris) est disponible en as112-nsd.conf. Pour simplifier son écriture, il a été produit à partir d'un source en M4, as112-nsd.conf.m4.

Que contiennent les fichiers de zone db.empty et db.hostname.as112.net ? Conformes à la syntaxe de la section 5 du RFC 1035, ils sont communs à BIND et NSD. Le premier, comme son nom l'indique, est un fichier de zone vide, puisque le serveur AS112 ne connait évidemment rien : il ne peut que répondre NXDOMAIN (ce nom n'existe pas) à toutes les requêtes. Il ne contient donc que les informations obligatoires à toute zone (SOA, avec une adresse de contact appropriée) et NS. L'autre zone sert au déboguage de l'AS112, lorsqu'on veut obtenir des informations sur le serveur AS112 courant. Un contenu typique est juste composé d'enregistrements TXT :

           TXT     "Human AS112 server" "Minas Tirith, Gondor"
           TXT     "Forbidden to orcs and nazguls."
           TXT     "See http://www.as112.net/ for more information."

et parfois d'une localisation (cf. RFC 1876). Le résultat sur un site réel étant :


% dig ANY hostname.as112.net.

; <<>> DiG 9.7.3 <<>> ANY hostname.as112.net.
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41528
;; flags: qr rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 2, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;hostname.as112.net.            IN      ANY

;; ANSWER SECTION:
hostname.as112.net.     604796  IN      LOC     37 58 22.590 N 23 44 43.890 E 100.00m 100m 10m 10m
hostname.as112.net.     604796  IN      TXT     "See http://as112.net/ for more information."
hostname.as112.net.     604796  IN      TXT     "Unicast IP: as112.grnet.gr"
hostname.as112.net.     604796  IN      TXT     "Greek Research & Technology Network" "Athens, Greece"
hostname.as112.net.     604796  IN      SOA     flo.gigafed.net. dns.ryouko.imsb.nrc.ca. 1 604800 60 604800 604800
hostname.as112.net.     604796  IN      NS      blackhole-2.iana.org.
hostname.as112.net.     604796  IN      NS      blackhole-1.iana.org.

;; AUTHORITY SECTION:
hostname.as112.net.     604796  IN      NS      blackhole-1.iana.org.
hostname.as112.net.     604796  IN      NS      blackhole-2.iana.org.

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Jul  6 12:51:53 2011
;; MSG SIZE  rcvd: 391

(La version intégrale des deux fichiers de zone figure dans le RFC.)

Une fois le nœud installé, il faut évidemment le tester (avec dig, par exemple). Si les réponses aux requêtes PTR sont correctes, mais pas celles aux requêtes pour le nom hostname.as112.net, c'est sans doute un problème de routage (on est envoyés sur un autre nœud de l'AS112) et il faut alors sortir traceroute et les looking glasses (section 3.6). Des tests dignes de ce nom doivent être faits depuis plusieurs FAI, et doivent tester les trois adresses IP de l'AS112.

Le bon fonctionnement de l'AS112 ne dépend pas uniquement de sa configuration initiale mais aussi de sa gestion et surveillance quotidiennes. La section 4 est consacrée aux questions opérationnelles. Le nœud doit être surveillé automatiquement, pour s'assurer qu'il répond toujours. S'il doit être arrêté (par exemple pour une maintenance prévue), il faut s'assurer que l'annonce BGP stoppe (autrement, BGP annonce un trou noir, d'où aucune réponse ne reviendra). Autre point important de la gestion opérationnelle d'un serveur de l'AS112, des statistiques, obtenues à partir d'outils comme DSC ou dnstop. Quelle est l'utilisation réelle de l'AS112 ? Ces statistiques n'étant pas consolidées globalement, c'est difficile à dire. Certains opérateurs publient leurs chiffres mais pas tous. Par exemple, le serveur d'Ottawa voit mille requêtes par seconde (cf. « AS112 Intro » par l'un des auteurs du RFC), celui géré par le RIPE-NCC dans les mille cinq cents, et celui à Paris deux fois plus (voir les graphiques), ce qui fait quand même quelques mégabits par seconde. La majorité des types demandés est évidemment du PTR mais il y a aussi un flux important de TXT, apparemment dus à la technologie SD (Service Discovery) d'Apple (voir des statistiques plus détaillées à la fin).

Le nouveau serveur peut alors être annoncé sur les listes appropriées (par exemple, chaque point d'échange a en général la sienne). Enfin, bien que chaque serveur de l'AS112 puisse fonctionner indépendemment des autres, il est évidemment préférable de se coordonner avec les petits camarades (section 5) en écrivant à la liste officielle.

Et dans le futur ? La section 6 explore l'avenir possible de l'AS112. Idéalement, il devrait disparaître petit à petit au fur et à mesure que les administrateurs réseaux prennent soin de ne pas laisser fuir les requêtes PTR pour les réseaux privés, comme recommandé dans le RFC 6303. Le déploiement de logiciels respectant ce principe dès le début pourrait aider. Toutefois, aujourd'hui, les opérateurs de l'AS112 n'observent pas de tendance à la baisse du trafic. Même des années après le déploiement de serveurs mettant en œuvre le RFC 6303, il est probable que le trafic de l'AS112 ne tombera pas à zéro et que ce service restera donc nécessaire.

Il pourrait même s'étendre à IPv6 : les serveurs pourraient répondre en IPv6 (et pas seulement en IPv4 comme aujourd'hui). Un préfixe a déjà été alloué pour cela, 2620:4f:8000::0/48 mais il n'est pas encore publié. Et les serveurs pourraient servir des données de ip6.arpa. Rien n'est encore décidé, gardez un œil sur http://www.as112.net/ si vous voulez être au courant. Un bon exposé du problème est « AS112-bis. » et un plan de déploiement IPv6 est en http://public.as112.net/node/26.

Enfin, qu'en est-il de la sécurité ? Comme le rappelle la section 8, les requêtes DNS auxquelles répond l'AS112 ne devraient jamais y arriver, normalement. Elles auraient dû rester sur le réseau local. En sortant, elles exposent de l'information interne, qui était peut-être privée (qu'il y ait un serveur qui y réponde ou pas ne change guère ce risque).

Plus rigolo, comme ces requêtes sont en général involontaires (comme indiqué, elles auraient dû rester privées), les réponses sont inattendues. Plus d'un IDS a donc crié que l'AS112 essayait d'attaquer le réseau. Le RFC 6305 a été écrit pour fournir une réponse toute faite aux administrateurs incompétents qui accusaient l'IANA ou l'AS112.

Comme l'AS112 n'a pas de chef et que l'anycast ne permet pas de limiter le nombre de participants, il est tout à fait possible de fantasmer sur l'hypothèse d'un nœud AS112 voyou, qui donnerait exprès de mauvaise réponses. Ce problème (purement théorique) n'a pas vraiment de solution. Signer les zones avec DNSSEC semble franchement excessif.

L'annexe A du RFC expose la longue histoire de l'AS112, de ses débuts en 2002 (les adresses IP privées datent de 1996) à son état actuel, après la redélégation en 2011 de in-addr.arpa, autrefois sur les serveurs de la racine (RFC 5855). L'AS112 a été le premier déploiement massif de l'anycast et a donc joué un rôle primordial dans l'évaluation de cette technologie.

On voit que neuf ans ont donc été nécessaires pour documenter ce projet. Une des raisons du retard était la longue discussion pour savoir si le RFC devait documenter l'état actuel de l'AS112 (ce qui a finalement été fait) ou son état souhaité (avec, par exemple, les nouvelles zones IPv6).

À noter que, d'après la liste officielle des sites, il existe au moins un serveur AS112 en France, chez Hivane, désormais (novembre 2011) connecté au France-IX. Malgré cela, les requêtes françaises pour les serveurs de l'AS112 voyagent souvent loin. C'est un problème banal comme le montrait l'excellente présentation « Investigating AS112 Routing and New Server Discovery ».

Voici quelques analyses sur le trafic de ce serveur français, faites avec DNSmezzo. Le fichier pcap fait 6,8 Go. Il y a 43 701 087 paquets DNS dont 21 858 845 sont des requêtes. Les données ont été prises un vendredi, de 13h40 à 15h30 (heure locale). Regardons d'abord les types de données demandés :

dnsmezzo=> SELECT (CASE WHEN type IS NULL THEN qtype::TEXT ELSE type END),
       meaning,                                                           
       count(results.id)*100/(SELECT count(id) FROM DNS_packets WHERE query) AS requests_percent FROM
             (SELECT id, qtype FROM dns_packets
                 WHERE query)  AS Results
          LEFT OUTER JOIN DNS_types ON qtype = value
              GROUP BY qtype, type, meaning ORDER BY requests_percent desc;


 type  |                meaning                 | requests_percent 
-------+----------------------------------------+------------------
 PTR   | a domain name pointer                  |               57
 TXT   | text strings                           |               35
 SOA   | marks the start of a zone of authority |                6
 CNAME | the canonical name for an alias        |                0
 MX    | mail exchange                          |                0
 AAAA  | IP6 Address                            |                0
 40    |                                        |                0
 DS    | Delegation Signer                      |                0
 ...

La première place des PTR est normale. Celle des TXT est plus surprenante. En regardant les noms utilisés (cf._dns-sd._udp.Y.X.243.10.in-addr.arpa...), on voit qu'ils sont dus à la technique Service Discovery d'Apple, un système normalement confiné au réseau local mais qui bave beaucoup à l'extérieur.

Et quels sont les domaines les plus populaires ?

dnsmezzo=> SELECT substr(registered_domain,1,46) AS domain, 
          count(id)*100/(SELECT count(id) FROM DNS_packets WHERE query) AS requests_percent  
       FROM dns_packets WHERE query GROUP BY registered_domain ORDER BY requests_percent DESC LIMIT 30;
      domain      | requests_percent 
------------------+------------------
 10.in-addr.arpa  |               78
 192.in-addr.arpa |               12
 172.in-addr.arpa |                7
 169.in-addr.arpa |                1
 151.in-addr.arpa |                0
 i~-addr.arpa     |                0
 83.in-addr.arpa  |                0
                  |                0
 gfi.private      |                0
 local.de         |                0
 grupofdez.com    |                0
....

On voit que le réseau 10.0.0.0/8 est nettement le plus populaire. On notera les trois derniers, sans doute des erreurs de configuration.

Et quels sont les résolveurs les plus actifs ? En agrégeant les préfixes IPv4 en /28 :

dnsmezzo=>  SELECT set_masklen(src_address::cidr, 28) AS client, count(id)*100/(SELECT count(id) FROM DNS_packets WHERE query) AS requests_percent                                                                  
     FROM dns_packets WHERE query GROUP BY set_masklen(src_address::cidr, 28)
           ORDER by requests_percent DESC LIMIT 30;
       client       | requests_percent 
--------------------+------------------
 CENSURE.160/28     |               29
 CENSURE.0/28       |               10
 CENSURE.16/28      |                8
 CENSURE.96/28      |                6
...

Oui, j'ai préféré ne pas donner les adresses. Je dirai simplement que ces quatre plus gros sont des opérateurs de téléphonie mobile, deux français et deux extrême-orientaux (les mystères du routage...).

Merci à Clément Cavadore pour les données et pour sa relecture.


Téléchargez le RFC 6304


L'article seul

RFC 6303: Locally-served DNS Zones

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : M. Andrews (ISC)
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 14 Juillet 2011


Autrefois, les serveurs DNS récursifs, ceux qui, installés sur un réseau local ou chez un FAI pour ses abonnés, répondent aux requêtes DNS des clients finaux, ne servaient par défaut aucune zone. Tout était demandé aux serveurs DNS faisant autorité, sauf des zones locales configurées à la main. Le problème est que certaines zones privées très répandues étaient oubliées, et que le récurseur allait alors embêter les serveurs faisant autorité avec ces requêtes qui auraient dû rester locales. Ce nouveau RFC demande donc que, par défaut, sans aucune configuration explicite, les récurseurs fassent autorité pour certaines zones locales.

Un exemple typique est celui d'un réseau local numéroté avec les adresses IP privées du RFC 1918, mettons 172.27.0.0/16. Les machines dudit réseau reçoivent en DHCP l'adresse d'un serveur DNS récursif local. Celui-ci, avant la sortie de notre RFC 6303, ne connaissait pas 27.172.in-adr.arpa, le domaine utilisé pour les résolutions d'adresses IP en noms. Il va donc transmettre ces requêtes aux serveurs publics, en l'occurrence ceux de l'AS112 (RFC 6304), les faisant travailler pour rien. La bonne pratique, depuis toujours, est que l'administrateur système local ajoute la zone 27.172.in-adr.arpa à son récurseur. Mais incompétence, manque de temps et négligence (quelqu'un d'autre paie...) se conjuguent pour faire que c'est rarement déployé. L'idée de notre RFC 6303 est donc de déplacer le travail depuis les nombreux administrateurs réseaux vers les nettement moins nombreux auteurs de logiciels serveurs.

La section 3 du RFC décrit le changement chez les résolveurs. Ceux-ci devront répondre avec autorité NXDOMAIN (code de réponse 3), indiquant que le nom demandé n'existe pas. Une façon triviale d'implémenter ce comportement est de servir des zones vides, plus exactement, ne contenant que des SOA et des NS (exactement ce que fait l'AS112, cf. RFC 6304). La valeur recommandée pour le SOA et pour les NS est le nom de la zone et, pour l'adresse de contact, nobody@invalid. Le SOA est nécessaire pour le cache des réponses négatives (et pour les machines qui tiennent à tenter des mises à jour dynamiques du DNS, qui ont également besoin des NS). Sous forme d'un fichier de zone standard, cela donne (avec un TTL de trois heures) :

   @ 10800 IN SOA @ nobody.invalid. 1 3600 1200 604800 10800
   @ 10800 IN NS @

Ce comportement doit être débrayable, de préférence zone par zone, pour le cas des sites qui utilisent les adresses privées et ont configuré leurs serveurs DNS pour résoudre ces adresses en noms.

La liste initiale des zones à servir figure en section 4. Elle sert de point de départ au registre IANA, http://www.iana.org/assignments/locally-served-dns-zones/locally-served-dns-zones.xml, qui est la source faisant autorité (les auteurs de logiciels devraient donc le consulter avant des nouvelles publications de leur logiciel). Le registre est mis à jour (cf. section 6) par le processus « IETF review » décrit dans le RFC 5226, avec un appel au conservatisme : une fois ajoutée au registre, une zone ne pourra jamais être retirée, puisqu'il faudrait mettre à jour tous les logiciels. Il faut donc réfléchir longtemps avant d'ajouter une zone.

Aujourd'hui, ce registre inclut notamment les zones in-addr.arpa correspondant au RFC 1918 et celles correspondant aux réseaux du RFC 5735 et RFC 5737 qui ne sont pas censés apparaître publiquement (comme les réseaux réservés pour la documentation). Il y a aussi des zones ip6.arpa (domaine utilisé pour la résolution d'adresses IPv6 en noms), comme celles des ULA du RFC 4193 (premier RFC à avoir normalisé cette pratique pour les résolveurs DNS, pour le domaine d.f.ip6.arpa), celles des adresses locales au lien (RFC 4291, section 2.5.6, un exemple étant 8.e.f.ip6.arpa), et celle du réseau réservé pour la documentation (RFC 3849).

En revanche, certaines zones ne sont pas incluses (section 5) comme les anciennes adresses locales au site d'IPv6 (RFC 4291, sections 2.4 et 2.5.7) ou comme des zones plus controversées comme les TLD numériques (pour traiter le cas des logiciels qui feraient des résolutions pour ces adresses, en les prenant pour des noms).

Suivre les recommandations de ce RFC peut-il avoir des effets négatifs ? La section 2 examine le cas. Comme les serveurs sont incités à ne servir les zones privées que si elles n'ont pas été configurées explicitement, les sites qui utilisent le RFC 1918 et ont peuplé les zones en in-addr.arpa ne devraient pas avoir de problème. La section 2 conclut que le problème ne se posera que dans un seul cas, les sites qui utilisent une délégation (typiquement depuis une racine locale, non connectée à l'Internet), sans que les résolveurs ne le voient. Ceux-ci devront explicitement reconfigurer leurs résolveurs pour ne pas servir les zones vides désormais installées par défaut.

Aujourd'hui, plusieurs récurseurs mettent déjà en œuvre ce RFC. C'est le cas par exemple d'Unbound (testé avec la 1.4.9). Un commentaire dans le fichier de configuration livré avec ce serveur dit :

	# defaults are localhost address, reverse for 127.0.0.1 and ::1
	# and nxdomain for AS112 zones. If you configure one of these zones
	# the default content is omitted, or you can omit it with 'nodefault'.

Le commentaire ne semble pas tout à fait correct, Unbound sert aussi par défaut des zones qui ne sont pas gérées par l'AS112 (comme les adresses réservées à la documentation). Voici sa réponse par défaut, lors d'une tentative de trouver le nom correspondant à l'adresse IP 172.27.1.1 :


% dig -x 172.27.1.1
...
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 8856
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; AUTHORITY SECTION:
27.172.in-addr.arpa.	10800	IN	SOA	localhost. nobody.invalid. 1 3600 1200 604800 10800

;; Query time: 67 msec
;; SERVER: ::1#53(::1)
;; WHEN: Fri Jul  8 17:47:21 2011
;; MSG SIZE  rcvd: 111

À noter que localhost est mis comme nom de serveur maître, pas 27.172.in-addr.arpa comme le demande le RFC (et je n'ai pas trouvé de moyen de le configurer). Pour le cas cité dans la section 2, où on veut interroger les serveurs faisant normalement autorité, on peut simplement mettre dans la configuration :

        local-zone: "27.172.in-addr.arpa" nodefault

et la zone 27.172.in-addr.arpa ne sera plus traitée comme spéciale, elle ne suivra plus ce RFC.

BIND (testé en version 9.8.0-P2) reconnait un certain nombre de zones automatiquement remplies et prévient au démarrage :

08-Jul-2011 19:43:59.410 automatic empty zone: 2.0.192.IN-ADDR.ARPA
08-Jul-2011 19:43:59.410 automatic empty zone: 100.51.198.IN-ADDR.ARPA
08-Jul-2011 19:43:59.410 automatic empty zone: 113.0.203.IN-ADDR.ARPA
...

Mais cette liste ne comprend pas encore les zones du RFC 1918. Voici le résultat en interrogeant les zones spéciales pour BIND :


% dig -x 192.0.2.1 
...
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 22522
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
2.0.192.in-addr.arpa.	86400	IN	SOA	2.0.192.in-addr.arpa. . 0 28800 7200 604800 86400

;; Query time: 1 msec
;; SERVER: ::1#53(::1)
;; WHEN: Fri Jul  8 19:45:03 2011
;; MSG SIZE  rcvd: 86

On note que BIND ne respecte pas encore le RFC (l'adresse de contact n'est pas nobody@invalid) et que sa liste de zones spéciales n'est pas encore celle du registre IANA. Toutefois, tout cela est modifiable. Regardez la section « Built-in Empty Zones » de l'ARM (Administrator Reference Manual). Par exemple, vous pouvez changer l'adresse de contact avec empty-contact nobody@invalid dans la section options. Vous pouvez désactiver le comportement spécial pour une zone avec disable-empty-zone 2.0.192.in-addr.arpa dans la même section (l'équivalent du nodefault d'Unbound). Et bien d'autres possibilités.


Téléchargez le RFC 6303


L'article seul

RFC 6302: Logging recommendations for Internet facing servers

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : A. Durand (Juniper Networks), I. Gashinsky (Yahoo! Inc.), D. Lee (Facebook), S. Sheppard (ATT Labs)
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 1 Juillet 2011


Ce court RFC prend position clairement en faveur d'un enregistrement, par les serveurs Internet, du numéro de port source du client, en plus de l'adresse IP. Cette recommandation est là pour tenir compte de la pratique de plus en plus répandue du partage d'adresses IP, notamment en raison de la pénurie des adresses IPv4.

En effet, depuis l'épuisement de ces adresses v4 début 2011, le partage d'adresses IP entre machines, par exemple via un routeur NAT, est de plus en plus fréquent. Or, de nombreux serveurs enregistrent dans un journal les adresses IP de leurs clients. Voici un exemple avec Apache :

2001:db8:1:4::1972 - - [29/Jun/2011:12:11:27 +0200] "GET /racine-dns-28-juin-2011.html HTTP/1.1" 200 9392 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30" www.bortzmeyer.org

et un avec Postfix :

Jun 29 12:04:30 aetius postfix/smtpd[29360]: connect from foo.bar.example[198.51.100.79]

(Les adresses ont été changées.)

Noter les adresses IP seules n'a guère de sens puisque ces adresses n'identifient plus une machine unique. Le RFC recommande donc que le port source soit également noté. Le processus de discussion qui a mené à ce RFC avait commencé au moins deux ans avant, à la réunion d'Hiroshima.

Évidemment, la meilleure solution au partage d'adresses serait le déploiement d'IPv6. Mais comme il va prendre des années, il faut bien gérer la situation existante. Cela implique des solutions comme le NAT44 (le NAT traditionnel, cf. RFC 3022 et mon article sur les différentes formes de NAT), le NAT64 (RFC 6146) ou bien DS-Lite (RFC pas encore paru). Ce partage d'adresses pose des tas de problèmes (documentés dans le RFC 6269) mais celui qui nous intéresse ici est le problème de l'enregistrement de l'adresse du client.

Prenons un NAT44 classique. Le client a une adresse privée (RFC 1918), mettons 192.168.42.1 et utilise le port source 52645. Il passe à travers un routeur NAT et ressort avec l'adresse publique 203.0.113.68 et le port source 61921. Le routeur a mémorisé l'association entre les deux tuples, interne {192.168.42.1, 52645} et externe {203.0.113.68, 61921}. Le serveur auquel se connecte ce client ne verra que le tuple externe. Si le serveur enregistre uniquement l'adresse 203.0.113.68, il ne pourra pas distinguer les requêtes faites par la machine 192.168.42.1 de celles faites par les autres machines situées derrière le même routeur NAT. Ce n'est pas forcément très grave pour du NAT fait à la maison (après tout, l'HADOPI coupera tout le monde, papa, maman et petit frère, si la fille aînée a téléchargé illégalement) mais c'est bien plus gênant pour du CGN, technique récente où plusieurs abonnés sans lien entre eux partagent une adresse IP.

Solution ? Que le serveur enregistre également le port source (ici, 61921). C'est désormais une recommandation officielle de l'IETF (voilà pourquoi ce document se nomme également « BCP 162 » pour Best Common Practices). Cette information, jointe à celle contenue dans le routeur NAT, permettra de retrouver le client original.

Notez le point mis en évidence : tout ceci n'a un sens que si le routeur NAT enregistre aussi les correspondances entre tuples {adresse, port} interne et externe. Le RFC prend soin de préciser que ses recommandations ne s'appliquent qu'aux serveurs, pas aux routeurs NAT qui, en pratique, à l'heure actuelle, n'enregistrent pas cette information (cf. section 3 sur ce point).

La recommandation exacte du RFC figure en section 2. Je la reprends ici :

  • Si (et c'est un gros si) le serveur enregistre l'adresse IP de ses clients, il doit aussi noter le port source,
  • Ainsi qu'une heure précise à la seconde près, et en utilisant une horloge qui soit synchronisée, par exemple via NTP (RFC 5905), et de préférence en UTC,
  • Et des informations comme le protocole de transport utilisé, au cas où le serveur en accepte plusieurs (les correspondances dans le routeur NAT dépendent en général du protocole de transport).

Vous avez bien noté que le RFC ne prend pas position sur la question de savoir si un serveur devrait enregistrer l'adresse IP de ses clients (note au passage : il existe des serveurs qui n'enregistrent pas cette adresse, justement pour éviter de « fliquer » leurs propres clients ; cela leur évite également la responsabilité d'un fichier sensible, puisque contenant des données à peu près nominatives). Il dit juste que, si le serveur le fait, il devrait également noter le port source et l'heure. Enregistrer l'adresse IP seule ne sert pas à grand'chose (sauf, je suppose, si le but est justement de ne pas garder de données trop nominatives. Au passage, un peu de publicité pour le service No Log.)

De la même façon, le RFC évite prudemment les questions de rétention des données (lesquelles, pour combien de temps). Chaque administrateur système doit consulter la loi locale (en France, la LCEN, loi liberticide qui contient des obligations très rigoureuses à ce sujet).

Enregistrer l'heure précise est nécessaire car le serveur ne sait évidemment pas à quel rythme sont réutilisés les numéros de port par le routeur NAT.

Voyons maintenant la mise en œuvre concrète de ces recommandations, avec les deux logiciels cités plus haut. Postfix a cette possibilité depuis assez longtemps (malgré les moqueries assez bêtes de son auteur au début) :

smtpd_client_port_logging = yes

Cela donne :

Jun 29 12:04:39 aetius postfix/smtpd[30055]: connect from foo.bar.example[198.51.100.79]:48525

Par contre, son concurrent sendmail ne semble pas avoir cette capacité (il faudrait peut-être modifier le source, en sendmail/srvrsmtp.c ou bien utiliser un milter smfi_connect, peut-être avec la macro ${client_port}. Et je n'ai pas d'informations sur d'autres serveurs comme exim.

Pour Apache, cela se fait en ajoutant un %{remote}p dans le LogFormat :

LogFormat "%h %{remote}p %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %v" combined

ce qui donnerait :

2001:db8:1:4::1972 42425 - - [29/Jun/2011:12:11:27 +0200] "GET /racine-dns-28-juin-2011.html HTTP/1.1" 200 9392 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30" www.bortzmeyer.org

(Le 42425 en deuxième champ.) Attention, si on analyse ses fichiers avec un programme de statistique comme analog, il faut changer également sa configuration, pour qu'il ne soit pas surpris par le champ supplémentaire.

J'ai montré un exemple avec une adresse IPv6. C'est sans doute inutile pour ce protocole (pas de traduction d'adresse/port en IPv6) mais c'est plus simple de mettre la même configuration pour les deux. Le paragraphe suivant présente un exemple où IPv4 et IPv6 sont traités différemment.

Si on veut faire plus joli, et écrire les adresses dans le style habituel des tuples {adresse, port} (adresse, deux-points, port dans le cas d'IPv4 et avec des crochets dans le cas d'IPv6, cf. RFC 3986), c'est plus compliqué. La solution que j'utilise (merci à @bitonio et @siddartha) passe par la définition d'une variable puis son utilisation dans la définition du format. (Une autre solution, due à @Grunt_, aurait été d'avoir un virtual host pour IPv4 et un pour IPv6.) Cela se configure ainsi :

LogFormat "[%h]:%{remote}p %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %v" combinedv6
LogFormat "%h:%{remote}p %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %v" combinedv4

SetEnvIf Remote_Addr : remote-v6
CustomLog /var/log/apache2/access.log combinedv6 env=remote-v6
CustomLog /var/log/apache2/access.log combinedv4 env=!remote-v6

Pour reconnaître une adresse IPv6, je cherche simplement la présence d'un deux-points. Si on veut faire mieux, il existe de jolies expressions rationnelles pour tester les familles d'adresses. Quoi qu'il en soit, le résultat est :

[2001:db8:1:4::1972]:42425 - - [29/Jun/2011:12:11:27 +0200] "GET /racine-dns-28-juin-2011.html HTTP/1.1" 200 9392 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30" www.bortzmeyer.org

192.0.2.202:53124 - - [01/Jul/2011:08:29:15 +0200] "GET /6269.html HTTP/1.1" 200 37392 "-" "Netvibes (http://www.netvibes.com)" www.bortzmeyer.org

Là aussi, il faut penser aux programmes d'analyse, dont la plupart ne sont pas capables de traiter des cas où le format varie d'une ligne à l'autre. La première solution, moins jolie, était peut-être plus raisonnable.


Téléchargez le RFC 6302


L'article seul

RFC 6301: A Survey of Mobility Support In the Internet

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : Z. Zhu (UCLA), R. Wakikawa (TOYOTA ITC), L. Zhang (UCLA)
Pour information
Première rédaction de cet article le 10 Juillet 2011
Dernière mise à jour le 12 Juillet 2011


Dans le monde des réseaux informatiques, on distingue en général le nomadisme (pouvoir changer d'endroit et avoir à peu près les mêmes services) et la mobilité (pouvoir changer d'endroit en maintenant les sessions existantes, comme si on n'avait pas bougé). Aujourd'hui, où beaucoup d'équipements sont mobiles (smartphone, tablette, ...), la mobilité suscite beaucoup d'intérêt. D'où ce RFC qui évalue l'état actuel du déploiement des techniques de mobilité sur l'Internet. (Disons-le tout de suite, il est très faible.)

Je vais me permettre de commencer par une polémique et des opinions personnelles : dans la famille de protocoles TCP/IP, la mobilité, c'est comme le multicast. Beaucoup de RFC, très peu de paquets. Le sujet passionne les experts, pose plein de problèmes techniques amusants, permet d'écrire des algorithmes rigolos... mais touche très peu les utilisateurs. Comment cela, les utilisateurs ne veulent pas se connecter à l'Internet depuis leur maison, puis continuer au bureau ? Si, ils le veulent, mais il n'est pas du tout évident que la mobilité au niveau IP soit nécessaire pour cela. Aujourd'hui, la technique de mobilité la plus courante est DHCP... La machine reçoit une nouvelle adresse IP et ce sont les applications qui gèrent les déconnexions/reconnexions. Prenons l'exemple du client de messagerie instantanée Pidgin et supposons que je me promène avec mon ordinateur portable, connecté via clé USB 3G dans le train, via le Wifi au Starbucks, puis via un câble Ethernet au bureau. J'aurai une adresse IP différente à chaque fois et les sessions IRC ou XMPP seront donc coupées lors des changements. Est-ce grave ? Pas tellement. Pidgin se reconnectera automatiquement à chaque fois et la seule conséquence pratique sera les messages de déconnexion et de reconnexion que verront les abonnés de chaque canal IRC / pièce XMPP. On a là un bon exemple du fait qu'une gestion de la mobilité par l'application cliente (section 5.5 de notre RFC) est suffisante et qu'il n'y a pas besoin d'un service réseau (compliqué et amenant des problèmes de sécurité) pour cela. Même chose avec une application Web : chaque requête HTTP peut utiliser une adresse source différente, l'utilisateur ne s'en rendra pas compte (à part éventuellement une obligation de se réauthentifier si le cookie est lié à l'adresse IP, ce qui se fait parfois pour limiter la réutilisation d'un cookie volé). Les applications qui reposent sur HTTP (les clients Twitter, par exemple) arrivent également à maintenir une « session » lors de changements d'adresse IP.

Bien sûr, une telle gestion par l'application ne couvre pas tous les cas. Un gros transfert de fichiers avec curl ou wget ne peut pas fonctionner ainsi, puisque ce transfert utilise une seule connexion TCP, donc dépend de l'adresse IP source utilisée au départ (cf. section 6.2). (Avec rsync, et un script qui le relance jusqu'à completion, ça marcherait.) Et, évidemment, les sessions SSH ne peuvent pas être maintenues lorsqu'on change d'adresse. Mais il reste quand même énormément de cas où il n'y a pas de vrai problème lié à la mobilité et cela explique largement, à mon avis, pourquoi les techniques de mobilité IP sont si peu déployées. J'arrête là les opinions personnelles et je reviens au RFC.

La section 1 explique que ce RFC est motivé par le fait que la mobilité est depuis longtemps un sujet de recherche actif à l'IETF et que, depuis quelques années, le déploiement des engins mobiles a explosé (smartphones, tablettes, etc). Le besoin est donc nettement plus marqué maintenant que dix ans auparavant, lorsqu'un ordinateur portable était un machin encombrant et lent. Pourtant, les solutions normalisées par l'IETF ont été peu déployées.

Ces solutions utilisent un vocabulaire rappelé en section 2 et dans le RFC 3753. Notons notamment les termes d'identificateur (identifier) qui indique une valeur qui ne change pas lors des déplacements, de localisateur (locator), qui, lui, change lorsqu'on se déplace (en IP classique, c'est le cas de l'adresse IP), de correspondance (mapping), la fonction qui permet de trouver un localisateur en connaissant l'identificateur, de correspondant (CN pour Correspondent Node, la machine avec laquelle l'engin mobile communique), etc.

La section 3 expose les principes de base de la gestion de la mobilité. Le CN doit pouvoir, dans l'Internet actuel :

  • trouver l'adresse IP actuelle du mobile (solutions dites de type 1),
  • ou bien connaître un identificateur du mobile et pouvoir lui envoyer des données en utilisant cet identificateur (solutions de type 2), nettement plus fréquentes.

Un exemple de solution de type 1 est d'utiliser le DNS. Si le mobile met à jour (par exemple par mise à jour dynamique, cf. RFC 2136) le DNS lorsqu'il se déplace, on utilise le nom de domaine comme identificateur, l'adresse IP comme localisateur et le DNS comme correspondance. Le CN peut donc toujours trouver l'adresse IP actuelle par un simple getaddrinfo(). La plupart des techniques normalisées par l'IETF sont, elles, de type 2. Dans celles-ci, l'adresse IP sert d'identificateur (permettant de maintenir les sessions TCP, par exemple dans le cas de SSH). Les paquets envoyés par le CN sont alors transmis à cette adresse IP stable, où un équipement doit ensuite les renvoyer au mobile, alors que les paquets émis par le mobile vers le CN voyagent directement. On parle de routage en triangle. Peu satisfaisant du point de vue des performances, il est en revanche excellent pour la protection de la vie privée : le CN, la machine avec laquelle correspond le mobile, ne sait pas où on est et ne sait pas si on bouge. (Notons que le RFC, et c'est plutôt choquant, ne mentionne pas une seule fois ces questions de protection de la vie privée, même pas dans la section 7 sur la sécurité.)

La section 4 présente ensuite les protocoles de mobilité existants. Je ne vais pas les reprendre tous ici (la liste en compte vingt-deux !) mais simplement en choisir arbitrairement quelques uns. On trouve dans cette liste des ancêtres comme le protocole Columbia de 1991, ou des protocoles plus récents comme le Mobile IP de 1996. Certains des protocoles étudiés n'ont pas été conçus uniquement pour la mobilité, mais la facilitent. C'est le cas de HIP (2003), ILNP (2005) ou LISP (2009).

Columbia, par exemple, le premier conçu, ne fournissait la mobilité qu'à l'intérieur du campus. Dans chaque cellule radio, un routeur spécial, le MSS (Mobile Support Station), assurait le routage des paquets dont l'adresse IP source appartenait au préfixe spécial « mobilité ». Le mobile gardait donc son adresse et les MSS s'arrangeaient entre eux pour acheminer le paquet.

Le principal protocole standard de mobilité est aujourd'hui Mobile IP, normalisé dans les RFC 3344, RFC 6275 et RFC 5454. Il fonctionne en IPv4 ou en IPv6, sur la base des mêmes principes. Chaque mobile a un Home Agent, qui ne bouge pas, et qui fournit au mobile une adresse stable (Home Address). Le mobile a aussi une adresse IP liée à son point d'attache actuelle, l'adresse CoA (Care-of Address). Le mobile prévient le Home Agent de tout changement de CoA. Le correspondant, le CN, écrit toujours à l'adresses Home Address, charge au Home Agent de faire suivre. Mobile IP est donc de type 2 et, par défaut, fait du routage en triangle (une optimisation permet de le supprimer dans certains cas). Il existe aujourd'hui de nombreuses mises en œuvre de Mobile IP, aussi bien pour les mobiles que pour les Home Agents mais très peu de déploiements.

Un exemple de protocole de type 1 est E2E. Dans ce cas, l'identificateur stable du mobile est un nom de domaine, et c'est une simple requête DNS qui indique au correspondant quelle adresse IP utiliser. Le mobile, lorsqu'il change d'adresse IP, utilise les mises à jour dynamiques du DNS pour modifier cette information.

HIP n'était pas conçu uniquement pour la mobilité. Toutefois, en séparant identificateur et localisateur, il facilite celle-ci (RFC 5206). Pour trouver une adresse IP à partir d'un HI (Host Identifier, les identificateurs stables des nœuds HIP), on peut utiliser le DNS mais aussi des « serveurs de rendez-vous » spécifiques à HIP (RFC 5204). La mobilité avec HIP nécessite que le CN soit un nœud HIP également. Lorsqu'un mobile HIP se déplace, il doit prévenir à la fois les CN et le serveur de rendez-vous (message HIP UPDATE, section 5.3.5 du RFC 5201).

Autre protocole de séparation de l'identificateur et du localisateur qui facilite la mobilité, LISP. Bien plus récent, il est encore peu déployé, et ses extensions de mobilité sont seulement sous forme d'un projet de RFC, draft-meyer-lisp-mn.

Armé de ces descriptions, le RFC, dans se section 5, explique les différents choix qui ont été faits pour chaque protocole. C'est la section la plus intéressante du RFC. (La section 6.3 examine plus en détail les avantages et inconvénients de chaque approche.) Par exemple, une approche était de réutiliser le routage, en gardant l'adresse IP fixe pour le mobile, et en comptant sur des protocoles proches de ceux de routage pour assurer l'acheminement du paquet jusqu'au bonne endroit. Le protocole Columbia fonctionnait ainsi. Mais de telles solutions ne marchent bien qu'en réseau local : pas question de changer les routes de l'Internet chaque fois qu'un mobile se déplace.

Deuxième approche : une fonction de correspondance entre un identificateur stable et l'adresse IP actuelle. Au lieu de prévenir le monde entier lorsque son adresse change, le mobile n'aurait plus à prévenir qu'un seul point (le serveur DNS, ou le serveur de rendez-vous, pour les solutions de type 1 ou bien le Home Agent, pour celles de type 2.) Si le CN n'est pas prévenu du changement (cas de Mobile IP, par défaut), on perd en performances (routage en triangle) mais on gagne en intimité et surtout on n'a pas besoin que le CN comprenne le protocole de mobilité (avec Mobile IP, le mobile peut parler à des machines IP normales, qui ignorent tout de ce protocole).

Ce dernier point, couvert en détail dans la section 5.2, est crucial : qui doit être mis au courant de la mobilité ? Il y a quatre parties concernées : le mobile, son correspondant (CN), le réseau (les routeurs) et le composant qui donne un coup de main (Home Agent, serveur DNS, etc). Si le CN doit être mis au courant (cas de HIP, par exemple), il faut mettre à jour toutes les machines avec qui le mobile est susceptible de communiquer, ce qui ne semble pas très réaliste (d'autant plus que les gros serveurs Internet auraient à garder un état considérable, pour se souvenir de tous leurs clients récents). La plupart des approches, à commencer par Mobile IP, gardent donc une adresse IP stable et le CN est une machine ordinaire, qui ne sait même pas qu'elle parle à un mobile. Il existe aussi quelques protocoles où ni le CN, ni le mobile, ne sont au courant et où le réseau fait tout. Dans le futur, toutefois, de plus en plus de machines seront mobiles et il est possible que le premier choix (rendre le CN conscient que son partenaire se déplace) redevienne attirant.

Autre choix à faire, la mobilité doit-elle être contrôlée par le réseau ou par l'utilisateur (section 5.3) ? Dans les réseaux de téléphonie mobile, le terminal ne gère pas la mobilité, le réseau fait tout pour lui, et ça marche. Mais cela prive l'utilisateur de tout contrôle sur la façon dont est gérée la mobilité. (Songez aux scandaleux tarifs d'itinérance, rendus possibles par le fait que l'utilisateur ne peut pas empêcher que tout passe par son opérateur habituel.)

Les différences entre les protocoles de mobilité s'expliquent aussi par le fait que certains visent une solution mondiale, qui doit marcher pour des centaines de millions de mobiles se déplaçant partout dans le monde (ce qui soulève de sérieux problèmes de scalability) alors que d'autres (comme Columbia, cité plus haut), ne cherchent qu'une mobilité locale, problème bien plus facile (section 5.4).

Enfin, les vingt-deux protocoles examinés dans ce RFC ne couvrent pas tout. On peut aussi baptiser « mobilité » des solutions simples comme un serveur OpenVPN - qui jouera un rôle équivalent à celui du Home Agent - plus un client OpenVPN sur chacune des machines de l'utilisateur, avec une adresse IP fixe chacune. Il existe aussi des approches radicalement différentes (section 5.5) comme GTP (qui ne marche qu'à l'intérieur d'un fournisseur donné) ou comme des solutions fondées sur les applications, comme je l'ai prôné au début de cet article. Par exemple, SIP dispose d'une extension pour gérer la mobilité (cf. Schulzrinne, H. et E. Wedlund, « Application-Layer Mobility Using SIP », dans Mobile Computing and Communications Review, 2010) où un nouveau message INVITE est envoyé lorsque le mobile change d'adresse IP pendant une communication.

Je l'ai dit, les protocoles spécifiques de mobilité sont pour l'instant un échec complet. Mais que prévoient les auteurs du RFC pour le futur ? La section 6 analyse d'abord cet échec (section 6.1). Peu ou pas de déploiement en production, donc. Mais pourquoi ? Le RFC estime que c'est en partie le résultat du fait que les machines mobiles ne sont devenues banales que depuis très peu de temps. Mais il reconnait aussi que les protocoles de mobilité sont des usines à gaz complexes et lentes. Certains suggèrent même de simplifier le problème en ignorant les questions de performance et de sécurité (cf. section 7 sur les problèmes de sécurité spécifiques à la mobilité) dans un premier temps (ce conseil vient directement de l'excellente section 3 du RFC 5218).

Puis la section 6 explore les pistes à suivre. Une très bonne lecture pour les concepteurs de protocoles et les étudiants en réseaux informatiques.

Pour la mobilité des téléphones et la fréquence des déconnexions, changements d'adresse IP, etc, je recommande le bon article « A Day in the Life of a Mobile Device ».


Téléchargez le RFC 6301


L'article seul

RFC 6297: A Survey of Lower-than-Best-Effort Transport Protocols

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : M. Welzl (University of Oslo), D. Ros (Institut Télécom / Télécom Bretagne)
Pour information
Réalisé dans le cadre du groupe de travail IETF ledbat
Première rédaction de cet article le 29 Juin 2011


Aujourd'hui, de nombreuses applications se battent pour accéder à une ressource critique, la capacité du réseau. Tout le monde veut télécharger plus vite et les applications tentent d'obtenir le meilleur débit possible pour recevoir le dernier épisode de Dr House ou bien la page de ses amis sur Facebook. Pourtant, il existe une catégorie d'applications plus philosophes, qui cherchent à être le moins dérangeantes possibles et à ne transférer des octets que lorsqu'absolument personne d'autre n'a besoin du réseau. Ce RFC examine les techniques utilisées par ces applications tranquilles.

Il existe bien des cas où il n'y a pas d'urgence à transférer des données. Des mises à jour quotidiennes de gros fichiers ou bases de données non critiques, le transport des nouvelles Usenet (cf. RFC 5537), du téléchargement qu'on laisse tourner tout le temps, par exemple. Ces transferts, même s'ils n'ont pas besoin d'être « temps-réel » rentrent actuellement en compétition avec les transferts pressés. Si on télécharge tranquillement, sans être pressé, un gros film, et qu'on a un besoin urgent d'un fichier pendant ce temps, le fichier n'aura, pendant son transfert, que la moitié de la capacité, l'autre étant prise par le film. Il serait donc intéressant d'avoir des applications gentilles, modestes, qui cèdent systématiquement la place aux applications normales, dès que le réseau est encombré. L'IETF a un groupe de travail pour ce sujet du trafic « d'arrière-plan », dit aussi « moins que au mieux » (le trafic normal dans l'Internet étant acheminé « au mieux » -best effort). Ce groupe se nomme LEDBAT (Low Extra Delay Background Transport), et voici son premier RFC, qui étudie les techniques existantes pour atteindre cet objectif.

On pourrait même imaginer des tarifs intéressants ou des conditions d'accès au réseau plus favorables pour ces applications. Après tout, l'essentiel des coûts d'un réseau sont fixes : une fois la fibre posée et allumée, une fois les routeurs et commutateurs installés et configurés, le coût d'exploitation est le même que des bits passent ou pas. Ce qui coûte cher, en exploitation, c'est la congestion, lorsque la capacité du réseau est trop faible, que le service commence à se dégrader, et que les clients réclament une mise à jour de l'infrastructure, qui ne sera pas gratuite. Par contre, si le réseau est inutilisé à certains moments, y faire passer nos transferts de données gentils ne coûte rien. Dans tous les cas, tarifs intéressants ou pas, avoir des applications modestes aideraient certains services gourmands (comme le transfert de fichiers en pair-à-pair) à se faire accepter : on n'hésitera plus à laisser tourner BitTorrent en permanence si on est sûr qu'il cédera toujours aux applications habituelles.

La référence pour le trafic normal est TCP, le protocole de transport qu'utilisent quasiment tous les transferts de données et qui fait au mieux pour utiliser toute la capacité du réseau, ou pour la partager équitablement si elle est insuffisante (RFC 5681). Notre RFC vise donc le trafic « moins que TCP » tel que, s'il y a compétition entre trafic normal et notre trafic d'arrière-plan, le trafic normal ait la part du lion.

Le trafic d'arrière-plan est nommé dans ce RFC LBE pour less than best-effort. Un système LBE doit donc réagir à la congestion plus vite que TCP, pour abaisser son débit. Il y a quatre catégories de systèmes LBE :

  • Ceux qui agissent uniquement au niveau de l'application, et utilisent donc un TCP normal. C'est plus difficile à faire que ça n'en a l'air, car, si on applique strictement le modèle en couches, les applications n'ont pas connaissance de la congestion. Mais ce sont aussi les plus faciles à déployer, puisqu'on a juste à installer une nouvelle application.
  • Ceux qui s'appuient sur un protocole de transport modifié. Il en existe deux catégories, ceux qui se basent sur les délais d'acheminement des paquets (et non sur le taux de pertes, comme le fait TCP), et les autres. Ces protocoles de transport peuvent éventuellement réutiliser une partie de TCP (par exemple son format d'en-tête), facilitant ainsi leur déploiement. (Plusieurs des exemples se nomment « TCP quelque chose » pour cette raison. Wikipédia a une bonne page sur les variantes de TCP.)
  • Ceux qui s'appuient sur le réseau. Ce sont évidemment les plus durs à déployer, car ils nécessitent que tous les routeurs du trajet soient modifiés.

Les sections suivantes fournissent divers exemples (je ne les reprends pas tous ici) de chaque catégorie.

Les solutions dans les applications font l'objet de la section 4. A priori, on pourrait croire que les solutions de shaping comme l'option --bwlimit de rsync atteignent notre objectif de « trafic d'arrière-plan », ne rentrant jamais en compétition avec TCP. Mais ce n'est pas le cas. Les solutions de shaping sont :

  • trop modestes lorsque le tuyau est inutilisé. Si je transfère avec rsync --bwlimit 64, le débit ne dépassera jamais 64 ko/s.
  • trop gourmandes si le tuyau est encombré. rsync essaiera d'avoir ses 64 ko/s dans tous les cas.

Bref, ces options ne sont pas réellement LBE (voir Crovella, M. et P. Barford, « The network effects of prefetching », Proceedings of IEEE INFOCOM 1998, pour une meilleure description d'une solution de limitation de débit) .

De même, essayer de faire tourner les applications LBE aux heures creuses ne convient pas à toutes les applications (par exemple le transfert de fichiers en pair-à-pair). Autre solution, le BITS de Windows, qui surveille en permanence le débit pour ralentir ces transferts de fichiers en arrière-plan si le débit devient trop important. (Le RFC ne fournit pas d'éléments d'évaluation précis de ce service.)

Comment réaliser une application modeste ? Une première possibilité (section 4.1) est d'agir sur la fenêtre de réception, sur la machine destinataire. Le récepteur diminue la fenêtre TCP, par exemple lorsque le délai d'acheminement des paquets augmente (sur Unix, cela doit être mis en œuvre dans le noyau, je ne crois pas que l'application ait accès à cette fenêtre, mais cela ne nécessite pas de modifier le protocole TCP, c'est juste un changement unilatéral de comportement). C'est par exemple ce qui est fait en Spring, N., Chesire, M., Berryman, M., Sahasranaman, V., Anderson, T., et B. Bershad, « Receiver based management of low bandwidth access links ».

Dans les deux catégories de nouveaux protocoles de transport, voyons d'abord ceux fondés sur le délai d'acheminement. Le principe est de mesurer le temps que mettent les paquets à faire le trajet. Si cette durée augmente, c'est sans doute parce que le réseau est encombré et que donc la congestion approche. On diminue donc le débit (TCP, lui, attend bien plus, que les paquets soient effectivement jetés). La section 2 cite comme exemple TCP Vegas, un des premiers à pouvoir partager un lien avec TCP en étant systématiquement moins gourmand que lui, même si, curieusement, ce n'était pas son but initial. TCP Vegas permet au contraire souvent un meilleur débit, lorsqu'il est seul. Cela illustre le fait que ce n'est pas en diminuant le débit (cf. la discussion sur rsync) qu'on atteint l'objectif de modestie.

TCP Vegas est toujours la référence dans ce domaine. Mais, depuis, il existe des améliorations comme TCP Nice (voir Venkataramani, A., Kokku, R., et M. Dahlin, « TCP Nice: a mechanism for background transfers », qui reprennent le même principe de diminuer le débit lorsque le RTT diminue (sans attendre que les pertes de paquets commencent). À noter que TCP Nice a une mise en œuvre dans Linux (citée dans l'article ci-dessus).

Autre cas de protocole fondé sur le délai, TCP-LP, qui utilise le délai en aller simple et pas le RTT comme les deux précédents. C'est normalement un meilleur indicateur (on n'est pas perturbé par le trafic de retour, qui peut n'avoir rien à voir puisque le chemin de retour peut être différent, et/ou moins congestionné) mais il est plus difficile à mesurer (TCP-LP utilise l'option d'estampillage temporel des paquets de TCP, cf. RFC 1323).

Tous ces schémas ont un défaut commun : les études (par exemple McCullagh, G. et D. Leith, « Delay-based congestion control: Sampling and correlation issues revisited ») montrent que le délai d'acheminement n'a qu'un faible rapport avec l'approche de la congestion. Le délai varie souvent pour des raisons qui n'ont rien à voir avec l'encombrement (les tampons devraient être bien plus grands pour mesurer ce délai sans ce bruit ; les liens radio vont varier le délai quel que soit l'encombrement ; etc). En outre, les horloges des machines sont souvent insuffisantes pour mesurer le délai avec une bonne précision, surtout sur un réseau local où les paquets voyagent vite et où l'essentiel du délai est dû au traitement dans les machines, pas au réseau. Enfin, certaines techniques d'optimisation de TCP faussent encore plus cette mesure.

En pratique, ces problèmes peuvent mener à réduire le débit sans raison. Ces « faux positifs » atteignent quand même l'objectif (être moins gourmand que TCP) mais les problèmes de mesure peuvent aussi mener à des faux négatifs, où le protocole de transport ne détecte pas une congestion bien réelle.

Enfin, tout protocole fondé sur le délai d'acheminement donne un avantage aux derniers arrivants : sur un tuyau déjà très encombré, le flot récent voit des délais importants dès le début et ne se rend donc pas compte de la congestion.

Il existe aussi des protocoles de transport LBE (modestes) n'utilisant pas le délai d'acheminement (section 3). Ils jouent sur le rythme d'envoi (qui dépend de la réception des accusés de réception) pour, par exemple, diminuer la fenêtre d'envoi plus vite que TCP. C'est le cas de 4CP ou de MulTFRC (une extension du TFRC du RFC 5348).

Enfin, il y a les solutions qui utilisent une assistance du réseau (section 5). Sur le papier, ce sont les plus efficaces (pas besoin de mesures indirectes, comme celle du délai d'acheminement, le routeur sait parfaitement si le réseau est encombré ou pas) mais aussi les plus dures à déployer car elles nécessitent une modification de tous les routeurs.

Un exemple d'une telle technique est NF-TCP (Arumaithurai, M., Fu, X., et K. Ramakrishnan, « NF-TCP: A Network Friendly TCP Variant for Background Delay- Insensitive Applications ») qui combine ECN (RFC 3168) et RED (RFC 2309) pour diminuer la priorité des flots NF-TCP dans les routeurs dès que la congestion menace.

Armé de la connaissance de toutes ces techniques (on voit que l'imagination des chercheurs et ingénieurs a été intense sur ce sujet), que va faire le groupe de travail LEDBAT ? La section 6 explique que LEDBAT a déjà un système, décrit dans l'Internet-Draft draft-ietf-ledbat-congestion, qui est de type « nouveau protocole de transport, fondé sur le délai d'acheminement » (ceux de la section 2). Ce n'est pas à proprement parler un protocole mais un algorithme, qui pourra être utilisé dans les protocoles concrets. Il est loin d'être terminé.


Téléchargez le RFC 6297


L'article seul

RFC 6296: IPv6-to-IPv6 Network Prefix Translation

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : M. Wasserman (Painless Security), F. Baker (Cisco Systems)
Expérimental
Première rédaction de cet article le 30 Juin 2011


Avec ce RFC, encore expérimental, IPv6 gagne la possibilité de faire de la traduction d'adresses, c'est-à-dire d'avoir dans un réseau local des adresses internes, qui seront dynamiquement traduites en adresses externes par le routeur de sortie, qui pourra également faire l'opération inverse (de l'extérieur vers l'intérieur).

Cette traduction est souvent nommée NAT (Network Address Translation) mais ce terme n'est pas correct : la traduction habituelle en IPv4, celle que tout le monde doit supporter pour sa connexion Internet à la maison et pour son accès 3G, NAT44, ne traduit pas uniquement l'adresse. Pour faire face à la pénurie d'adresses IPv4, elle met en correspondance plusieurs adresses internes (typiquement du RFC 1918), avec une adresse externe, en utilisant les numéros de port pour démultiplexer les paquets entrants. Cette technique devrait donc s'appeler NAPT (Network Address and Port Translation) et pas NAT. Elle a des tas d'inconvénients, décrits dans le RFC 6269.

En IPv6 au contraire, sujet de notre RFC, il n'y a pas de pénurie d'adresses et pas de raison de faire du NAPT. Le protocole de traduction proposé dans ce RFC 6296 mériterait donc, lui, de s'appeler NAT (ou peut-être NAT66), mais, comme ce terme est désormais très galvaudé, ses auteurs ont plutôt choisi NPT pour Network Prefix Translation. NPTv6 permet une correspondance univoque (1:1) entre les adresses internes et les adresses externes, évitant ainsi le partage d'adresses dont le RFC 6269 décrit les défauts. Pour diverses raisons (cf. RFC 2993 et section 5 de notre RFC), l'IETF n'encourage pas les systèmes de traduction mais, si un utilisateur tient à en faire, ce RFC lui fournit un protocole bien étudié. Il n'évite pas tous les problèmes de la traduction (RFC 4864, RFC 5902) mais les limite.

N'utilisant pas les ports, NPTv6 fonctionne donc avec tous les protocoles de transport, contrairement au NAT44 traditionnel (cf. section 6). Il est sans état (chaque paquet est traduit indépendemment des autres) donc le routeur qui fait la traduction n'a pas de problèmes comme le remplissage de la table (fréquent avec NAT44). Ainsi, un réseau peut être servi par deux traducteurs (par exemple pour la redondance) sans qu'ils aient à partager un état. Mais ce caractère sans état a aussi d'autres conséquences :

  • NPT est juste une technique de traduction, il ne fournit pas de filtrage, ce n'est pas un pare-feu (les routeurs NAT44 mélangent les deux fonctions de traducteur et de pare-feu avec état), si on veut un pare-feu, il faut donc le faire en plus (cf. RFC 6092),
  • il permet le maintien du principe de la connexion de bout en bout, y compris pour les connexions « entrantes », mais, comme toute technique de traduction, NPT a des problèmes avec les applications qui incluent les adresses IP dans les données,
  • même problème avec les services qui incluent l'adresse IP dans le calcul d'un MAC comme l'option d'authentification de TCP (RFC 5925).

Voilà pour un résumé très rapide des propriétés de NPT v6.

Mais pour quelles raisons peut-on avoir envie de déployer un système de traduction ? La section 1.1 de notre RFC propose de les résumer en un principe : indépendance vis-à-vis de l'adresse. Ce principe comprend plusieurs propriétés :

  • Les adresses internes au réseau local étant distinctes de celles du réseau extérieur, aucune nécessité de renuméroter si on change de FAI (RFC 5887).
  • Le site peut choisir son opérateur, sa connexion, ses opérateurs multiples, même (multi-homing sans BGP),
  • Pas besoin d'obtenir des adresses PI pour avoir des adresses à soi,
  • Et pour le FAI, pas besoin de BCP 38 (RFC 2827), les adresses annoncées étant traduites en ses adresses.

« Adresses internes + traduction » est donc potentiellement un « PI du pauvre ». En IPv4, beaucoup de sites utilisaient le NAT pour atteindre cette indépendance, même lorsqu'elles pouvaient obtenir suffisamment d'adresses IP. Le RFC 4864 décrit d'ailleurs un concept proche nommé « autonomie du réseau ».

NPTv6 est donc un mécanisme qui permet de réaliser cette indépendance du réseau. Meilleur que le NAT44 (pas de manipulation des ports, fonctionne donc avec tous les protocoles de transport, comme SCTP, permet les connexions entrantes, purement « algorithmique » donc sans état), il peut donc être un ajout intéressant à la boîte à outils de l'administrateur de réseaux IPv6.

Pour être tout à fait complet, il faut aussi rappeler ses inconvénients (RFC 2993) :

  • Comme il modifie l'en-tête IP, il est incompatible avec les techniques de sécurisation de cet en-tête comme l'AH d'IPsec (RFC 4302),
  • Comme toute traduction d'adresses, il ne marche pas avec les protocoles qui transmettent des adresses IP dans les données comme SIP ; ceux-ci auront besoin d'un ALG,
  • La configuration du DNS va être pénible car il faudra prévoir une vue externe et une interne (split DNS).

Bref, NPTv6 n'est pas une solution parfaite et c'est pour cela que ce RFC reste au statut Expérimental.

Si on décide de poursuivre cette voie, il faut choisir les adresses à utiliser en interne. Les ULA du RFC 4193 semblent la solution idéale, maximisant l'indépendance.

Voici pour les grands principes. Quelques détails pratiques maintenant. Prenons l'exemple simple de la section 2.1 : un réseau interne, utilisant un préfixe ULA, fd01:203:405:/48, est connecté à l'Internet via un unique FAI, et un routeur qui fait du NPTv6. Le préfixe PA alloué par le FAI et routable publiquement est 2001:0db8:1:/48 (notez que NPT n'impose pas que les deux préfixes aient la même longueur, cf. section 3.7). Lorsqu'un paquet « sort » (va du réseau local vers l'Internet), l'adresse IP source est remplacée par une adresse IP prise dans le préfixe du FAI. Les autres champs de l'en-tête IP ne sont pas modifiés. En sens inverse, lorsqu'un paquet « entre » (vient de l'Internet vers le réseau local), c'est l'adresse de destination qui est touchée, pour être remplacée par une adresse du réseau local.

La partie identifiant la machine sur le réseau local (80 bits dans cet exemple) n'est en général pas conservée telle quelle. Ainsi, si fd01:203:405:1::1234 écrit à 2a00:1450:8007::13, Gmail, le destinataire, verra le paquet venant de 2001:0db8:1:d550::1234

En effet, la traduction est neutre pour la somme de contrôle. Si on suit l'algorithme standard du RFC 1071, on veut obtenir la même somme de contrôle avant et après traduction. Les protocoles qui utilisent une somme calculée sur une partie de l'en-tête IP (c'est le cas de TCP) ne seront donc pas affectés. Astuce amusante, pour atteindre cet objectif de neutralité, 16 bits de l'adresse sont réservés pour pouvoir y faire les modifications qui annuleront les autres changements faits dans l'adresse. L'algorithme exact de calcul est dans les sections 3.1 et suivantes. Une mise en œuvre en C figure en annexe B. À noter qu'elle ne prétend pas être optimale, faisant par exemple les calculs de somme de contrôle avec du code portable et pas de l'assembleur adapté à une machine particulière.

On peut avoir des cas plus compliqués que ce simple réseau, par exemple du multi-homing, où le réseau local est connecté à deux FAI (section 2.4). Chacun de ces deux FAI alloue un préfixe PA différent. Les liens avec les deux FAI passent par deux routeurs NPT différents, tous les deux configurés avec le même préfixe interne mais différents préfixes externes. Une machine du réseau local ne pourra pas savoir sous quelle adresse elle apparaitra à l'extérieur, sauf à utiliser une technique comme STUN (RFC 5389). La décision de sortir par un FAI ou l'autre peut être prise comme on veut. Par contre, par rapport à du vrai multi-homing, avec adresses PI et BGP, un changement de FAI de sortie entraîne un changement de l'adresse IP vue par l'extérieur et coupe donc toutes les sessions en cours.

Continuons avec les considérations de déploiement et de configuration (section 4). Le plus probable est que NPTv6 sera mis en œuvre dans les routeurs, comme dans l'exemple ci-dessus, et, pour les particuliers et petites organisations dans le CPE. Les obligations du RFC 6204 s'appliquent donc à l'engin qui fait la traduction.

Cela implique entre autres que le traducteur NPT soit capable de faire des virages en épingle à cheveux (renvoyer vers le réseau local un paquet qui était à destination du réseau local, cf. RFC 4787), afin que des machines du réseau local puissent se parler en utilisant leurs adresses publiques. Comme NPT ne tripote pas les ports, la plupart des autres exigences des RFC du groupe BEHAVE ne s'appliquent pas à lui.

Et pour les applications, quelles sont les conséquences (section 5) ? Plusieurs des problèmes classiques de la traduction, qui avaient déjà été décrits dans le RFC 2993 sont toujours présents. Les applications ne verront pas les mêmes adresses, selon qu'elles sont situées d'un côté ou de l'autre du traducteur. Par exemple, si un ordinateur portable se déplace de part et d'autre du traducteur, il verra ses connexions s'interrompre, son adresse IP ayant changé. Mais les problèmes les plus fréquents et les plus sérieux seront pour les protocoles applicatifs qui utilisent des références, c'est-à-dire qui indiquent dans les données à quelle adresse IP envoyer les paquets. Les cas les plus connus sont FTP et SIP. Si un client SIP envoie à un autre son adresse interne, pour recevoir un flux RTP, cette adresse ne sera pas traduite, et le flux ne joindra pas la destination. Que peut-on faire pour limiter les dégâts ?

  • Comme avec le NAT44, les applications peuvent utiliser STUN pour apprendre leur adresse,
  • Dans le futur, un mécanisme de référence général, résistant aux traductions, sera peut-être développé.

Et la sécurité du NPTv6 ? La section 7 résume les points importants. Le principal est que, contrairement au NAT classique, avec état, NPT n'empêche pas les connexions entrantes. C'est une bonne chose mais cela peut dérouter certains administrateurs réseaux qui croyaient que la traduction les protégeait de l'extérieur. Ce n'est pas le cas avec NPTv6 et si on veut une telle protection, il faut installer un pare-feu explicite (alors que le NAT traditionnel mélange les deux rôles de traduction et de protection), comme décrit dans le RFC 6092.

Curieusement, cette idée de traduction d'adresses sans état, selon une cardinalité 1:1, est très ancienne. Si notre RFC 6296 semble être le premier RFC à la décrire, elle avait été à la base du projet GSE, auquel l'annexe A rend hommage. GSE, décrit dans le draft draft-ietf-ipngwg-gseaddr, était un des projets qui avaient été élaborés pour le successeur d'IPv4. Contrairement au projet retenu (le futur IPv6) qui conservait les concepts de base de son prédécesseur, GSE repensait nettement le problème de l'adressage dans l'Internet. Celui-ci était divisé en deux, les réseaux de transit et les réseaux de bordure. Dans GSE, seuls les réseaux de transit avaient des adresses publiques et annoncées dans la table de routage globale. Les réseaux de bordure avaient des adresses stables et uniques mais qui n'étaient pas routées. Les adresses étaient traduites lors du passage du réseau de bordure au réseau de transit et réciproquement. Le but était surtout de limiter la croissance de la table de routage (problème qu'IPv6 avait finalement décidé de ne pas traiter). En décembre 2010, sur l'Internet, il y a 36 000 systèmes autonomes dont 15 000 n'annoncent qu'un seul préfixe (et sont donc probablement des réseaux de bordure). Seuls 5 000 systèmes autonomes apparaissent dans des chemins (en dehors de l'origine) et sont donc des réseaux de transit.

Et les implémentations publiquement disponibles ? (Merci à François Romieu pour ses informations.) Il y a map66 et nfnat66 (NAT66 pour Netfilter), qui utilise netfilter et est présenté en français dans « l'exposé de Guy Leduc et plus en détail dans la thèse de Terry Moës, « IPv6 address translation in a Linux kernel ». Ne m'en demandez pas plus, je n'ai pas testé. (À noter qu'il en existe aussi pour des techniques de traduction IPv6<->IPv6 différentes, par exemple avec état.)


Téléchargez le RFC 6296


L'article seul

RFC 6293: Requirements for Internet-Draft Tracking by the IETF Community in the Datatracker

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : P. Hoffman (VPN Consortium)
Pour information
Réalisé dans le cadre du groupe de travail IETF genarea
Première rédaction de cet article le 24 Juin 2011


Une des particularités de l'IETF est son extrême ouverture. Tout le monde peut suivre le travail en cours, les documents de travail (les Internet Drafts) sont publiquement accessibles, l'état de chaque document dans le processus de publication peut être suivi sur le Web. Bref, sans avoir à se ruiner en déplacements physiques, le participant à l'IETF a accès à tout ce qu'il faut. Mais ce système a aussi ses insuffisances, notamment parce qu'il ne permet pas d'accès personnalisé et que seuls certains participants ont un accès en écriture. Ce RFC est donc le cahier des charges d'un nouveau système de suivi des Internet Drafts.

Le système actuel de suivi du travail de l'IETF repose sur un ensemble d'outils non-officiels maintenus par des volontaires, http://tools.ietf.org/, et par un site officiel de suivi, le « Datatracker » (http://datatracker.ietf.org/. Le Datatracker permet de s'identifier, pour certaines actions, mais cette possibilité n'est pas ouverte aux participants ordinaires, seulement à ceux chargés d'une tâche comme le pilotage d'un groupe de travail. (Notez que « participant IETF » = « public » puisque l'IETF n'a pas d'adhesion formelle, tout le monde en est membre dès qu'il participe, cf. section 1.3.)

Le Datatracker donne accès à plein d'informations sur les documents en cours (la section 1 résume les possibilités de l'actuel Datatracker). Prenons l'exemple de l'Internet Draft que demandait l'ICANN sur la syntaxe des noms de TLD, draft-liman-tld-names. On peut connaître son état en visitant http://datatracker.ietf.org/doc/draft-liman-tld-names/ : au 23 juin 2011, la version actuelle est la n° 5, datant du 12 avril, et il est en état I-D Exists, qui est l'état normal de tout Internet Draft. Il n'est donc pas en vue d'une publication comme RFC, juste en discussion. Si on veut suivre les évolutions du document, nul besoin de tout relire (comme c'est le cas dans d'autres organisations, où les diff ne sont pas fournies lors de la sortie d'un nouveau document), le Datatracker est serviable. Voici les différences entre les versions 4 et 5 : http://tools.ietf.org/rfcdiff?url1=draft-liman-tld-names-04&difftype=--html&submit=Go!&url2=draft-liman-tld-names-05 (dans ce cas précis, elles étaient purement administratives).

Si je m'intéresse plutôt au document sur le protocole de résolution de noms d'Apple appelé (bien à tort) Multicast DNS, je trouve l'information en http://datatracker.ietf.org/doc/draft-cheshire-dnsext-multicastdns/. Le document (actuellement en version 14) est approuvé par l'IESG mais a besoin d'une nouvelle version. Les opinions des membres de l'IESG sont accessibles en http://datatracker.ietf.org/doc/draft-cheshire-dnsext-multicastdns/ballot/ (Discuss signifiant une objection.).

Ce niveau de transparence est bien au delà de ce que font les autres SDO comme l'UIT ou l'AFNOR où tout le travail est fait derrière des portes closes, pour éviter que le public n'y participe. Mais on peut encore faire mieux.

Par exemple (section 1.1), on pourrait imaginer qu'un utilisateur veuille s'identifier pour retrouver les informations sur la liste des Internet Drafts qu'il suit, liste déterminée manuellement ou via une recherche. Il peut aussi vouloir recevoir une notification si une nouvelle version d'un de ces documents apparait.

La section 2 décrit plus précisement les exigences du futur Datatracker :

  • Possibilité de se créer un compte automatiquement (et pas manuellement sur demande, comme aujourd'hui, ce qui n'est pas très 2.0), et ses propres listes de documents à suivre,
  • Possibilité de modifier l'affichage dans le Datatracker (par exemple l'ordre de présentation des documents, la liste des attributs affichés, etc),
  • Gestion de grandes listes (des dizaines de documents suivis),
  • Définition des listes par des attributs comme « Tous les Internet Drafts du groupe de travail XXX », « Tous ls Internet Drafts écrits par Machin », « Tous les Internet Drafts qui citent le RFC yyyy », etc,
  • Publication sous forme de flux Atom, notification par courrier, peut-être demain notification des changements via XMPP.

D'autres idées, dont la mise en œuvre n'est pas requise pour la première phase, figurent dans les annexes A et B. Par exemple, suivi des changements dans les registres IANA (ça, cela me serait très utile).

Le cahier des charges est donc fini, il ne reste plus que le développement et le déploiement...


Téléchargez le RFC 6293


L'article seul

RFC 6286: AS-wide Unique BGP Identifier for BGP-4

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : E. Chen, J. Yuan (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 11 Octobre 2011


Un tout petit RFC pour régler un bête problème de définition dans le protocole BGP. L'identifiant d'un routeur BGP devait être une adresse IPv4. Avec l'épuisement de ces adresses, tous les routeurs n'en auront pas forcément une et ce RFC accepte explicitement comme identificateur n'importe quel numéro unique (à l'intérieur d'un AS).

Cet identifiant est défini par la norme BGP (RFC 4271, section 1.1) comme un nombre de 32 bits, qui doit être une des adresses IPv4 du routeur (cela assurait son unicité en réutilisant un nombre déjà alloué ; cette unicité est vérifiée lors de l'établissement de la connexion). La section 2.1 de notre RFC supprime l'obligation d'être une adresse IPv4, et ajoute celle que le numéro soit unique au sein de l'AS (ou, plus exactement, de la confédération, s'il y a plusieurs AS). Cette unicité par AS était nécessaire pour les cas où un routeur fait de l'agrégation de routes qu'il relaie (section 3).

Ce changement ne modifie donc pas le protocole BGP, ni le comportement de chacun des pairs BGP. Simplement, dans le cas d'un réseau purement IPv6, où aucun des routeurs n'avait d'adresse IPv4, ils pourront désormais prendre un nombre quelconque comme identifiant, sans violer de RFC.


Téléchargez le RFC 6286


L'article seul

RFC 6280: An Architecture for Location and Location Privacy in Internet Applications

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : R. Barnes, M. Lepinski (BBN Technologies), A. Cooper, J. Morris (Center for Democracy & Technology), H. Tschofenig (Nokia Siemens Networks), H. Schulzrinne (Columbia University)
Réalisé dans le cadre du groupe de travail IETF geopriv
Première rédaction de cet article le 24 Juillet 2011


Aujourd'hui, de nombreuses applications des réseaux informatiques dépendent de la localisation physique de l'appareil mobile. La récolte de ces données de localisation (« le 31 mai 2011, à 08:04, l'appareil était en 40,756° Nord et 73,982° Ouest, ±150m »), leur transmission à travers le réseau, et leur traitement par le service qui héberge l'application posent de graves questions de protection de la vie privée, surtout quand on lit les conditions d'utilisation de ces services (si on pouvait comprendre le jargon juridique, elles se résumeraient à « nous faisons ce que nous voulons, nous nous occupons de tout, ne vous inquiétez pas »). D'où ce RFC qui essaie de définir une architecture de gestion de la vie privée pour ces informations de localisation.

Un exemple d'une telle application est Pages Jaunes sur Android : elle permet d'obtenir des réponses qui dépendent du lieu, tel que l'a indiqué le téléphone. Ainsi, si on tape « pizzeria », on obtient en haut du classement les pizzerias les plus proches physiquement. Résultat, les Pages Jaunes savent où vous êtes et on imagine facilement les conséquences pour la vie privée de ce genre de suivi (« L'utilisateur est allé quatre fois dans une clinique spécialisée cette semaine. »). Outre les Pages Jaunes, plusieurs intermédiaires connaissent également votre position (l'opérateur du réseau, qui sait par quelle borne vous vous connectez, les tiers qui écoutent, si le trafic n'est pas chiffré, et le téléphone lui-même qui peut garder cette information très longtemps, comme le fait l'iPhone). À noter que cette information est collectée en permanence, sans action explicite de l'utilisateur (section 1.2). Dans les romans policiers, finies les longues filatures sous la pluie pour savoir où passe le suspect. Le cyber-policier moderne ne bouge plus de sa chaise et obtient via le réseau toutes les informations nécessaires, chaque citoyen emportant avec lui volontairement l'outil qui permet de le suivre à la trace.

Le RFC (section 1) ne prétend même pas qu'il va régler ce problème, qui est consubstantiel de la récolte et diffusion d'informations de localisation : il affirme juste qu'il tente de limiter les dégâts.

Il y a deux autres points importants à comprendre sur cette « architecture de protection de la vie privée » : d'abord, ce n'est qu'une architecture, pas un protocole, encore moins un logiciel. Elle définit un cadre et des principes, elle ne fournit pas de solutions clé en main. Ensuite, s'agissant d'un travail de l'IETF, elle ne traite que l'aspect technique. Si on suit ce RFC, et les standards futurs qui le développeront, on peut faire un système relativement protecteur de la vie privée. Mais la technique ne suffit pas : le respect du RFC ne garantit pas la sécurité, c'est une norme technique, pas une politique. Des lois de protection de la vie privée (et qui soient d'application générale, pas annulables par des conditions d'utilisation d'un service commercial), bien appliquées et une vigilance citoyenne permanente sont nécessaires si on veut empêcher la vie privée de devenir une marchandise comme les autres.

Ce RFC 6280, œuvre du groupe de travail Geopriv, qui travaille sur tous les problèmes situés à l'intersection de la localisation et de la vie privée, tourne autour de la notion d'« objet de localisation » (une bonne introduction à Geopriv est le RFC 3693). Cet objet stocke la localisation et les règles d'utilisation de cette information. Lorsque l'objet est transmis, les conditions d'utilisation voyagent avec lui (section 1.1). Ainsi, celui qui reçoit une information de localisation ne peut pas prétendre ignorer les règles qui s'y attachent. Ces règles sont, par exemple, « ne transmets ces données à personne » ou, plus subtil, « ne transmets les informations à mon entreprise que pendant les heures de travail ».

Lier les règles d'usage aux informations de localisation est contraignant mais permet de d'assurer que le destinataire a accès à ces règles. Le RFC cite l'exemple des licences libres comme Creative Commons, qui imposent une telle liaison. Il y a eu de nombreuses polémiques (par exemple au sujet de la GFDL), sur l'opportunité d'imposer l'inclusion du (long) texte de la licence dans chaque document couvert par cette licence mais le but est le même : couper court à toute tentative de jouer l'ignorance. Un autre exemple donné par le RFC est celui des classifications utilisées par les militaires (« Secret », « Confidentiel », etc). Tous le documents sont marqués avec leur niveau de sécurité et tout militaire qui les manipule sait donc exactement ce qu'il peut faire ou ne pas faire avec ce document. (Un exemple détaillé figure dans les règles de classification du ministère de la défense états-unien.)

La solution radicale serait évidemment d'arrêter la collecte et la transmission de ces informations. Mais, outre qu'elles peuvent permettre d'améliorer certains services (comme dans l'exemple des pizzérias plus haut), des systèmes comme le GSM ne peuvent pas fonctionner sans connaître la localisation de l'utilisateur (pas moyen de lui faire suivre un appel entrant si on ne sait pas quelle borne le dessert en ce moment). Comment limiter les dégâts ? Historiquement, les décisions en matière de vie privée étaient prises uniquement par le récepteur des données, qui en faisait à peu près ce qu'il voulait. Le seul choix de la personne concernée était de partager ses données ou pas, et ce choix binaire ne permettait pas d'indiquer ce qu'il acceptait qu'on fasse des données (section 1.3). Comme, évidemment, les intérêts des personnes ne coïncident pas avec ceux des entreprises privées et organisations étatiques qui reçoivent les données, les abus étaient inévitables. Par exemple, un utilisateur envoie volontairement son adresse électronique sur un site Web pour recevoir ensuite des informations, mais il ne pouvait jamais s'opposer à ce que cette adresse soit ensuite revendue à des spammeurs. (Aujourd'hui, il est courant de voir une case à cocher « J'accepte de recevoir du spam, pardon, que mon adresse soit revendue à des tiers » mais il faut noter que c'est le site Web destinataire qui définit les choix possibles, pas le titulaire de l'adresse.) Geopriv pose donc comme principe que l'utilisateur, pas le destinataire, définit les usages acceptables, et les indique avec les données. À noter que ce n'est qu'une indication. Il n'existe pas de moyen technique de s'assurer que ces choix de l'utilisateur seront respectés, une fois les données transmises. Sur un réseau distribué comme l'Internet, il n'y a pas de possibilité de concevoir un mécanisme technique de respect de ces règles. Celui-ci doit être assuré par des moyens autres, comme la loi (loi Informatique & Libertés, par exemple), des régulateurs efficaces et/ou le marché (note personnelle : pour des raisons idéologiques, le marché est mentionné par le RFC comme mécanisme possible de rétroaction sur les entreprises qui violeraient les usages spécifiés par l'émetteur ; l'expérience déjà ancienne de l'Internet en matière de protection de la vie privée montre bien la vanité de cette idée). Le mécanisme technique de Geopriv sert donc juste à s'assurer que le destinataire des données était conscient des règles et donc, s'il les a violées, qu'il était de mauvaise foi (ce qui est important pour d'éventuelles poursuites judiciaires).

Avec la section 3 commence la partie la plus technique du RFC : elle décrit l'architecture utilisée. Les deux objectifs de cette architecture sont :

  • S'assurer que les données de localisation ne soient distribuées qu'aux entités autorisées,
  • S'assurer que ces entités soient au courant des conditions d'usage.

Comme on l'a vu, s'assurer que les entités réceptrices ne peuvent pas techniquement violer les règles est un non-but : il n'est pas réalisable techniquement. Pour atteindre les deux objectifs, il y a deux classes de règles :

  • Les contrôles d'accès qui indiquent les entités autorisées,
  • Les règles d'usage, qui indiquent ce que celles-ci ont le droit de faire.

Un exemple figure en section 3.1, décrivant le « cycle de vie » des données. Alice se déplace. Son mobile apprend sa position (par le réseau de communication, ou bien par GPS) et elle veut partager cette information avec ses amis via un service de présence (un tiers, qu'on suppose de confiance). Avec cette information viennent les règles d'usage qu'Alice a définies, par exemple que les amis ne peuvent pas garder cette information plus de N jours. Si un ami, mettons Bob, veut transmettre l'information sur la localisation d'Alice à des amis à lui, il devra également vérifier si les règles d'usage lui permettent (rappelez-vous que ce RFC définit une architecture de sécurité, pas des moyens techniques de protection ; comme le savent ceux qui ont essayé de mettre en œuvre des DRM, il n'existe aucun moyen technique d'empêcher Bob de tricher et de faire suivre ces données à des gens non autorisés).

Décrire ensuite tout ce qui se passe nécessite un vocabulaire élaboré (section 3.2). On y trouve de nombreux rôle (un même acteur pouvant tenir plusieurs rôles) :

  • Le sujet (target) est la personne dont on veut protéger la vie privée (Alice, dans l'exemple précédent),
  • L'engin (device) est la machine que porte le sujet (par exemple son smartphone) ; techniquement, c'est lui qui est localisé, pas le sujet (pensez au nombre de films où un personnage jette son téléphone pour ne pas être repéré),
  • Le décideur (rule maker) est celui qui définit les règles d'usage ; c'est souvent le sujet, mais cela peut être le responsable sécurité de son entreprise,
  • Le localisateur (location generator) est le matériel ou logiciel qui détermine la localisation ; cela peut être un récepteur GPS ou bien la partie GSM de l'appareil, qui obtient sa localisation à partir du réseau GSM,
  • Les serveurs de localisation (location server), terme impropre : un serveur de localisation est une entité susceptible de transmettre l'information de localisation, en appliquant les règles d'usage. Dans l'exemple plus haut, Alice, le serveur de présence, et Bob connaissaient tous les trois la localisation d'Alice et étaient susceptibles de la transmettre (et donc étaient des serveurs de localisation potentiels),
  • Les destinataires de la localisation (location recipient) sont toutes les entités qui connaissent la localisation du sujet et s'en servent mais ne la transmettent pas forcément. Bob, le serveur de présence, les autres amis qui ne relayaient pas l'information, sont tous des destinataires de localisation.

J'ai simplifié en mettant un seul décideur et un seul localisateur mais il peut y avoir des cas plus complexes.

Pour mettre en œuvre l'architecture de sécurité Geopriv, on a besoin de deux formats de données :

  • Les objets de localisation (LO pour Location Object, cf. RFC 5491), qui stockent une position, exprimée en géodésique (geodetic, c'est-à-dire longitude, latitude, altitude) ou bien en civil (civic, comme 120, rue de la Gare, 75013, Paris..., voir par exemple le RFC 5139),
  • Les règles d'usage (PR pour Privacy Rules, et RFC 4745 pour un exemple de langage pour exprimer ces règles).

En utilisant cette terminologie, la section 4 du RFC décrit le cycle de vie de l'information de localisation. Elle passe par trois étapes :

  • Détermination de la localisation (un fix, dans la terminologie GPS),
  • Distribution de la localisation, par les serveurs de localisation,
  • Utilisation de la localisation, par les destinataires.

Les trois étapes sont ensuite étudiées une à une, chacune posant des problèmes spécifiques de protection de la vie privée.

La section 4.1 parle de la détermination. Elle peut être faite par l'engin lui-même (GPS, observation des étoiles et bien d'autres, y compris pour le cas trivial où l'utilisateur rentre manuellement l'information), par le réseau auquel il se connecte, ou bien via une coopération entre tous les deux. Dans le premier cas, guère de problème de sécurité dans cette étape, l'engin étant tout seul (les satellites GPS ne dialoguent pas avec l'engin, ils ne savent pas qui les utilise). Bien plus délicat est le cas où c'est le réseau qui détermine la position. C'est ce qui se produit en GSM (le réseau sait avec quelle base parle l'engin, et l'intensité du signal, ainsi que sa direction, peuvent donner une idée plus précise de la position de l'engin) mais évidemment aussi en connexion filaire, où le réseau sait exactement où on se trouve. Tout mécanisme du genre GeoIP est également un cas de détermination de la position par le réseau. Il n'y a pas forcément besoin d'un protocole réseau. Mais le point important est qu'un tiers (pas seulement le sujet) connait dès le début la position de l'engin. Enfin, le troisième cas est celui de la détermination assistée par le réseau. Par exemple, un engin va mesurer un certain nombre de choses comme la force du signal radio, l'adresse MAC obtenue, etc, et les envoyer à un localisateur qui en déduira une position précise. Cette fois, il y a un protocole réseau (entre l'engin et le localisateur), qu'il faut protéger, par exemple contre l'écoute.

L'étape de détermination est le premier endroit où on peut appliquer des mesures de protection, comme l'utilisation d'identificateurs qui ne permettent pas un lien simple avec l'utilisateur, et comme le chiffrement pour empêcher l'écoute, dans le cas où la détermination emploie un dialogue sur le réseau.

La deuxième étape est la distribution de l'information de localisation (section 4.2). C'est là que les règles d'usage commencent à jouer un rôle, en limitant la redistribution. Voici quelques exemples de règles :

  • Ne retransmettre cette information qu'aux machines dont le nom se termine en example.com,
  • Ne transmettre de l'adresse que la ville et le pays (pas la rue),
  • Dans la même idée de dégradation délibérée de la précision, ne transmettre de la longitude et latitude que des valeurs arrondies à la minute d'angle la plus proche (environ deux kilomètres)...

Les deux derniers exemples montrent qu'un serveur de localisation a deux armes à sa disposition, ne pas transmettre la localisation du tout, ou bien la transformer pour limiter les risques.

Pour cette étape de distribution, les choses les plus importantes sont de toujours transmettre les règles d'usage avec la localisation, et de respecter ensuite ces règles. Ces règles pouvant dépendre de l'identité de celui à qui on transmet, utiliser des techniques d'authentification fiables est donc impératif. De même, il faut veiller à ce qu'un tiers non-autorisé ne puisse pas accéder aux données qui circulent sur le réseau, donc le chiffrement est fortement souhaité. On est là dans un domaine plus traditionnel pour l'IETF, la conception de protocoles réseaux sûrs.

Enfin, la troisième étape du cycle de vie de l'information de localisation est l'utilisation de l'information (section 4.3). Le destinataire doit respecter les règles d'usage, qu'il a reçu avec l'objet de localisation. Normalement, ce respect est obligatoire et des mesures administratives ou légales doivent être déployées pour s'assurer que ce soit le cas. Cette étape ne comprend pas de transmission de l'information et ne nécessite donc pas de protocole réseau.

La section 6 du RFC fournit des exemples de scénarios concrets d'utilisation de cette information de localisation. Le premier scénario est très simple : un engin détermine sa position et la transmet à une application Web dans une requête HTTP de type POST ou bien une requête SIP de type INVITE. Le serveur fournit le service demandé, sans stocker l'information de localisation. Dans ce cas ultra-simple, pas de place pour les architectures compliquées, les rôles sont bien définis (le RFC oublie toutefois de rappeler que la connexion entre l'engin et le serveur doit être protégée contre l'écoute).

Plus complexe, en section 6.2, le cas où un navigateur Web qui fait appel à des API de détermination de sa position (comme la Geolocation API, dont l'implémentation fait souvent appel à l'aide du réseau d'accès) et exécute du code JavaScript qui va appeler des services d'assistance à la détermination de la position (voyez un bon tutoriel en « Geocoding A User's Location Using Javascript's GeoLocation API »). Notez qu'une partie des risques peut provenir d'une action du navigateur après avoir obtenu sa position. Par exemple, s'il demande à Google Maps une carte des environs, Google Maps, bien que n'étant pas partie lors de la détermination de la position, la connaîtra désormais. Il y a plus de deux acteurs, cette fois (notez que, même sur une machine unique, il peut y avoir plusieurs composants logiciels ne se faisant pas mutuellement confiance) et donc davantage de complexité.

Enfin, le troisième scénario est plus critique puisqu'il concerne un appel d'urgence, domaine très régulé, puisque beaucoup d'opérateurs ont l'obligation légale de fournir automatiquement la localisation de l'appel. Ici, la distribution de l'information se fera typiquement en utilisant LoST (RFC 5222).

Comme tout RFC, notre RFC 6280 inclut une section sur les problèmes de sécurité (section 5). Ici, elle sert surtout de rappel car tout le RFC est consacré à la sécurité. Parmi les rappels : le fait qu'il existe déjà des protocoles fournissant les fonctions de sécurité importantes (IPsec et TLS, par exemple) et que les solutions de localisation devraient les utiliser. Autre rappel : la sécurité de bout en bout est préférable à la sécurité transitive et il est donc recommandé qu'on sécurise l'ensemble du trajet, pas juste chaque étape (pensez au cas de Bob faisant suivre un objet de localisation : l'a-t-il modifié ?). Une bonne étude générale des problèmes de sécurité de Geopriv est dans le RFC 3694.


Téléchargez le RFC 6280


L'article seul

RFC 6274: Security Assessment of the Internet Protocol version 4

Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : F. Gont (UK CPNI)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 6 Juillet 2011


Le protocole IPv4, qui représente toujours la très grande majorité du trafic réseau sur l'Internet, n'avait jamais fait l'objet d'un rapport synthétique sur sa sécurité. Certes, il existe d'innombrables articles portant sur la sécurité d'IPv4, des avis des CSIRT, de très nombreuses mentions dans les RFC et ailleurs. Mais tout ceci était dispersé dans de nombreux documents, et pas forcément facilement accessible lorsqu'on se mettait à lire les normes. D'où ce RFC 6274 qui rassemble en un seul endroit tout ce qu'il faut savoir sur la sécurité d'IPv4. Pas de révélations dans ce document, les problèmes qui y sont décrits sont très classiques, souvent résolus depuis des années mais, comme ils n'avaient pas forcément été documentés dans un RFC, il y avait un risque sérieux qu'un programmeur, voulant mettre en œuvre IPv4 en partant de zéro, retombe dans des failles anciennes. Ce RFC vise donc à éviter toute régression. Avant sa publication, un programmeur qui ne lisait que les RFC était à peu près sûr de créer des failles de sécurité béantes.

Parfois, c'est même pire : des failles connues ne sont pas résolues dans certaines implémentations, ou bien le sont d'une manière qui rend le remède pire que le mal (beaucoup de programmeurs ne connaissent de la sécurité que de vagues notions et des légendes entendues et jamais contestées).

L'introduction (section 1) note qu'IPv4 avait été conçu dans un environnement très différent de ce qu'il est aujourd'hui. Toutefois, elle ne reprend pas l'idée courante mais fausse comme quoi les failles de sécurité d'IPv4 découleraient d'une vision optimiste et naïve de la nature humaine, d'une époque où seuls des bisounours utilisaient l'Internet et où il n'était donc pas nécessaire de prévoir des mécanismes de sécurité. En réalité, même si on refaisait l'Internet aujourd'hui en partant de zéro, une bonne partie des problèmes se poserait de la même façon : sécuriser un réseau multi-organisations et multi-national n'est pas de la tarte, que ce soit aujourd'hui, ou bien il y a vingt-cinq ans ! Quoi qu'il en soit, l'Internet est aujourd'hui une ressource critique, dont dépendent bien des choses dans le monde. Sa sécurité est donc un enjeu majeur.

À propos de légendes, le RFC prend position sur le récit « Internet a été conçu pour résister à une attaque nucléaire » en estimant que ce n'est pas exact, que la principale motivation n'était pas de fournir un système de communications invulnérable aux militaires, mais de partager l'accès à des mainframes (voir l'article de D. Clark, « The Design Philosophy of the DARPA Internet Protocols », Computer Communication Review Vol. 18, No. 4, 1988).

Les problèmes de sécurité découverts depuis ont parfois affecté une mise en œuvre particulière (c'est une loi générale du logiciel : « il y a des bogues ») et parfois les concepts de base du protocole, rendant bien plus difficile la solution. La bibliographie du RFC donne une idée des problèmes les plus importants.

Comme il n'est pas réaliste de couvrir tous les problèmes de sécurité de l'Internet, ce RFC se focalise (section 1.2) sur ceux d'IP lui-même, excluant les protocoles de transport comme TCP ainsi que les protocoles de routage comme BGP ou ceux de démarrage comme DHCP. Les RFC cruciaux pour cette évaluation de la sécurité sont donc :

La section 2 du RFC rappelle les concepts de base d'IP, inchangés depuis ses débuts (et parfois depuis l'époque d'Arpanet). Reprenant l'article fondateur de Clark cité plus haut, il cite les trois principes essentiels :

  • Pas d'état dans les routeurs, ceux-ci traitent chaque paquet sans tenir compte des paquets précédents,
  • Un service minimum au niveau IP, notamment sans garantie de délivrance (ce qui fait qu'une grande partie du travail doit être fournie par des protocoles situés au dessus, comme TCP),
  • Un service minimum fourni par les couches inférieures, auxquelles IP ne demande pas grand'chose, lui permettant de fonctionner sur n'importe quel réseau.

Maintenant, allons-y, avec deux longues sections, dont je ne transmets ici qu'une partie : la section 3 examine un par un les champs de l'en-tête du paquet IP et les différentes façons dont ils peuvent impacter la sécurité. La section 4 examine les différents mécanismes de traitement de paquets IP et ce qui peut en résulter.

La section 3 commence par rappeler le schéma du RFC 791 décrivant tous les champs qu'on trouve dans l'en-tête d'un paquet IP. En théorie, tous les paquets doivent obéir à certains invariants, le premier cité par le RFC étant que la taille du paquet doit être d'au moins vingt octets (la taille minimale d'un en-tête et donc d'un paquet). Mais, comme l'a observé toute personne qui a analysé du trafic réseau avec des dissecteurs mal écrits, on trouve de tout sur l'Internet et notamment plein de paquets mal formés. Notre RFC 6274 donne donc à chaque fois des conseils de tests de santé à faire sur chaque paquet avant de le traiter. Le premier test est donc longueur(paquet) >= 20. À chaque fois, si le test échoue, le paquet devrait être abandonné et un compteur de problèmes incrémenté. Allons-y maintenant pour les autres tests (oui, cela va être long), dans l'ordre des champs.

L'en-tête a un champ Version qui, pour IPv4, doit valoir... 4 (section 3.1). En théorie, on peut imaginer des techniques de couche 2 où les paquets de différentes versions d'IP soient démultiplexés par ce champ (une telle technique existe dans la section 3.2 du RFC 6214, publié le premier avril 2011). En pratique toutefois, tous les réseaux existants fournissent un autre moyen de démultiplexer (par exemple le champ EtherType dans Ethernet, qui vaut 0x0800 pour IPv4 et 0x86DD pour IPv6) et donc, une fois le paquet reçu par l'implémentation IPv4, le champ Version doit donc forcément valoir 4 et il faut vérifier cela. Oublier ce test permettrait certaines attaques où un méchant mettrait une autre valeur pour exploiter le fait que certains équipements accepteraient le paquet et d'autres (avec un peu de chance, les IDS) l'ignoreraient.

Champ suivant, IHL (Internet Header Length), la longueur de l'en-tête du paquet IP (contrairement à IPv6, celle-ci n'est pas constante, en raison de la présence possible d'options). Comme elle est exprimée en nombre de mots de quatre octets, le test de longueur minimale est cette fois longueur(en-tête) >= 5. Comme l'en-tête est forcément plus petit que le paquet, on doit aussi vérifier longueur(en-tête) * 4 <= longueur(paquet). Ces tests peuvent sembler un peu bêtes mais il y a déjà eu des attaques jouant sur des longueurs bizarres, pour forcer une implémentation à lire des zones mémoire où elle n'aurait pas dû aller. Là encore, en cas d'échec des tests, abandon du paquet et incrémentation du compteur des paquets invalides.

Tout est évidemment plus compliqué lorsqu'un champ a changé de sémantique, ce qui est le cas de l'ancien ToS (Type of Service) devenu DSCP avec le RFC 2474 (section 3.3). Normalement, toutes les mises en œuvre d'IP devraient traiter ce champ selon la nouvelle définition mais cela ne semble pas être le cas. Donc, une application peut mettre une valeur qui semblera inoffensive si elle est interprétée comme ToS mais lui donnera une priorité si cette même valeur est interprétée comme DSCP. Une protection possible est d'effacer ce champ lorsqu'un paquet arrive dans un domaine administratif (la qualité de service différenciée n'a de toute façon de sens qu'à l'intérieur d'un même domaine, au sein d'une même entreprise, par exemple).

Les bonnes intentions faisant parfois les belles failles de sécurité, la section 3.3.2.2 est consacrée à ECN (RFC 3168), une technique de lutte contre la congestion, qui peut dans certains cas être exploitée contre la sécurité (par exemple en faisant croire qu'on gère la congestion par cette technique, même si ce n'est pas vrai, simplement pour diminuer la probabilité de voir ses paquets jetés par les routeurs).

On a déjà parlé de longueur, de celle indiquée par la couche 2, de celle indiquée par le champ IHL pour indiquer la longueur de l'en-tête... Il y a aussi un champ Total Length qui indique la longueur du paquet (en-tête compris). Quels sont les pièges de sécurité liés à ce champ (section 3.4) ? D'abord, ce champ pouvant indiquer des tailles jusqu'à 65535 octets, les mises en œuvre d'IP doivent préparer des tampons d'entrée/sortie assez grands pour cela. Normalement, les correspondants ne doivent pas envoyer de paquets de plus de 576 octets avant qu'on leur ai signalé qu'on pouvait traiter plus (par exemple par le biais de l'option MSS de TCP, ou par l'EDNS du DNS). Mais il existe certains cas où les autres machines envoient des paquets plus grands sans prévenir (cas de NFS) et, de toute façon, un attaquant ne suivra pas forcément les règles.

Plus rigolo, un attaquant peut transmettre un paquet plus grand que la taille indiquée dans le champ Longueur, par exemple dans l'espoir d'obtenir un débordement de tampon. Si la couche 2 lui permet, il peut même envoyer des paquets plus grands que 65535 octets. Ce genre de paquets se trouve réellement dans la nature et peuvent être le résultat d'une programmation maladroite, ou bien d'une tentative d'attaque (comme celle citée en « US-CERT Vulnerability Note VU#310387: Cisco IOS discloses fragments of previous packets when Express Forwarding is enabled »). Le récepteur doit donc être paranoïaque. Allouer un tampon de la taille indiquée par le champ Longueur, puis y copier le paquet sans vérification serait très imprudent. Il faut utiliser au contraire la taille indiquée par la couche 2.

Le champ suivant la longueur, ID, identifie le fragment (section 3.5), pour permettre le réassemblage en cas de fragmentation. Sur certains systèmes, la façon dont est choisie ce nombre peut révéler bien des choses sur l'emetteur (voir « Idle scanning and related IP ID games »). Sur les systèmes anciens, l'ID était unique par paquet, choisi de manière incrémentale et donnait donc au récepteur une indication, par exemple sur le nombre de machines derrière un routeur NAT. Comment peut-on limiter ces risques de fuite d'information ? Une des solutions est de mettre le champ ID à zéro pour tout paquet qui a le bit DF (Don't Fragment). Ces paquets ne pouvant être fragmentés, le fait d'avoir tous le même ID n'est pas gênant. Linux a été le premier à faire cela. Mais certains équipements mal conçus (les affreuses middleboxes) fragmentaient quand même ces paquets, qu'on ne pouvait plus réassembler. Depuis, Linux (et Solaris) mettent un ID fixe, mais différent pour chaque adresse, ce qui limite les fuites d'information. En effet, l'ID n'a pas besoin d'être unique par machine, il suffit qu'il soit unique par tuple {source, destination, protocole}. Le mieux serait donc de générer aléatoirement (pour empêcher les fuites d'information) un ID unique par « session » pour chaque tuple. Attention à bien lire le RFC 4086 avant de choisir son générateur aléatoire. Ce problème de choix entre un identificateur prévisible (qui est donc indiscret) et un identificateur aléatoire (qui risque donc d'être réutilisé plus vite) est très proche de celui du choix du port source décrit dans le RFC 6056.

Le cas est plus complexe pour les protocoles sans connexion comme UDP (utilisé notamment pour le DNS qui, depuis le déploiement de DNSSEC, a plus souvent des paquets fragmentés). Dans certains cas, des paquets corrompus risquent d'être réassemblés et les protections des couches supérieures risquent de ne pas être suffisantes pour détecter cette corruption (pour le DNS, il faut au moins activer la somme de contrôle UDP, ce qui limite les risques).

Passons maintenant au champ Flags de l'en-tête (section 3.6). Il contient trois bits dont deux sont définis : DF (Don't Fragment) et MF (More Fragments). De manière amusante, le bit DF peut être utilisé pour empêcher la détection par un IDS. Si l'attaquant sait que, après l'IDS, la MTU baisse, il peut envoyer des paquets ayant le bit DF dont certains sont trop gros pour cette MTU. L'IDS va les lire mais la machine de destination ne les verra jamais, puisqu'ils ont été jetés par le routeur précédent (qui n'avait pas le droit de les fragmenter). L'IDS et la machine de destination verront alors des données différentes, ce qui peut permettre de rendre indétectable une charge utile malveillante. Si ce cas semble extrêmement tordu (depuis quand met-on des tunnels après les IDS ?), il faut préciser qu'il existe des variantes de cette attaque, basées sur les bogues de certains logiciels (par exemple qui jettent les paquets ayant à la fois MF et DF, alors que ces paquets peuvent atteindre la destination), qui permettent d'obtenir le même résultat.

Juste après, un autre champ lié au réassemblage, le champ Fragment Offset (section 3.7). Si certaines des attaques décrites dans ce RFC peuvent sembler purement théoriques, celles portant sur des jeux avec l'algorithme de réassemblage des fragments sont très courantes en pratique. Ce champ indique la position du fragment dans le datagramme original et les valeurs bizarres de ce champ sont fréquentes dans la nature. Par exemple, un fragment peut prétendre être situé plus loin que le 65535ème octet du paquet original (le champ est assez grand pour cela, on peut aller jusqu'à 131043 octets), ce qui peut mener à des débordements de tampon au cours du réassemblage. Cela a déjà été utilisé par exemple dans l'attaque nommée (bien à tort) ping of death (« CERT Advisory CA-1996-26: Denial-of-Service Attack via ping » et « The Ping of Death Page » en 1996. Cette attaque est très mal nommée parce qu'elle n'a rien à voir avec ping, ni même avec ICMP. un paquet IP de n'importe quel protocole peut convenir. Si vous faites un interview d'un candidat à un poste d'administrateur réseaux, c'est une bonne question à poser : « faut-il filtrer ICMP sur le pare-feu ? ». S'il répond « oui, à cause du ping of death », vous savez qu'il n'y connait pas grand'chose en sécurité des réseaux.

Et le bon vieux champ TTL (Time To Live, section 3.8), pose-t-il aussi des problèmes de sécurité ? Oui. Il peut transmettre de l'information (type de système d'exploitation à la source, puisque la valeur par défaut du TTL peut en dépendre, distance de la source, d'après la diminution observée, etc). Son rôle dans la découverte de la topologie du réseau est bien connu puisqu'elle est utilisée par l'outil traceroute (qui lance des paquets de TTL croissant, pour repérer les routeurs qui reçoivent un paquet de TTL nul et refusent donc de le transmettre).

Il peut, comme dans le cas de DF, être utilisé pour faire en sorte qu'un IDS et la machine de destination ne voient pas la même chose, par exemple en mettant un TTL plus bas aux paquets destinés seulement à l'IDS. S'il y a un routeur après l'IDS, ces paquets ne seront pas vus par la machine cible. L'outil Scrub d'OpenBSD peut aider contre cette attaque.

Mais le TTL a aussi des usages positifs en terme de sécurité. Par exemple, mis à la valeur maximale (255), il peut permettre de s'assurer qu'un paquet vient bien du réseau local, en vérifiant que le TTL est bien 255 à l'arrivée (cette technique est décrite en détail dans le RFC 5082).

Le champ suivant le TTL indique le protocole utilisé par les couches supérieures (UDP, TCP, SCTP, etc). Il n'a rien de dangereux mais certaines attaques dans le passé utilisaient ce champ avec des implémentations boguées (section 3.9).

Ensuite vient la somme de contrôle de l'en-tête. Là encore, on peut s'en servir pour échapper à certains contrôles faits par des équipements qui ne testent pas cette somme. En mettant délibérement une valeur invalide, on crée un paquet qui sera vu par certaines machines et pas par d'autres, trompant ainsi les IDS.

Puis viennent les adresses IP, les deux champs suivants, qui indiquent respectivement les adresses source et destination (section 3.11 et 3.12). Normalement, tout le monde connait leur principale faiblesse en matière de sécurité : elles ne sont pas authentifiées et l'émetteur du paquet (ou un intermédiaire) peut mettre ce qu'il veut, surtout dans la source. Les adresses identifient normalement une interface réseau (la notion d'« adresse IP d'une machine » n'existe pas en IP). Sauf que rien n'empêche de mettre ce qu'on veut. (Un rappel au passage : le logiciel le plus souple et le plus facile d'usage pour fabriquer de faux paquets, en bricolant les champs qu'on veut, est Scapy. Utilisez-le, vous en serez content.) Normalement, un filtrage est réalisé par le réseau d'accès (RFC 2827 et RFC 3704, mais aussi « NISCC Technical Note 01/2006: Egress and Ingress Filtering ») pour empêcher les mensonges les plus éhontés de sortir sur l'Internet mais, en pratique, très peu de fournisseurs d'accès font ce test. (Le Spoofer Project mesure ce pourcentage.) Une autre technique de protection est la surveillance des adresses utilisées sur le réseau local, par exemple avec arpwatch.

On a donc vu d'innombrables attaques où les adresses IP source des attaquants étaient fausses. Le RFC fournit quelques exemples comme « CERT Advisory CA-1996-01: UDP Port Denial-of-Service Attack », « CERT Advisory CA-1996-21: TCP SYN Flooding and IP Spoofing Attacks » ou « CERT Advisory CA-1998-01: Smurf IP Denial-of- Service Attacks ».

Cette absence d'authentification des adresses IP se retrouve à d'autres endroits que l'en-tête IP, par exemple, dans les paquets ICMP qui sont censés transporter une partie du paquet original : rien n'indique que cette information soit fiable (RFC 5927).

Conséquence pratique, il ne faut surtout pas authentifier une machine sur la seule base de l'adresse IP qu'elle présente. Par exemple, dans le cas d'une dDoS, on voit parfois des administrateurs réseaux naïfs croire qu'ils ont découvert l'origine de l'attaque lorsqu'ils ont fait un whois sur l'adresse IP source, sans penser une seconde qu'elle puisse être trompeuse...

À noter que le RFC ne rappelle pas qu'on peut « authentfier » une adresse IP si le protocole de transport impose des aller-retours, ce qui est en général le cas avec TCP (si les numéros de séquence initiaux sont bien choisis au hasard, l'attaquant doit recevoir ou voir passer les paquets de réponse, pour arriver à établir une connexion).

IPv4 a ensuite un champ Options, le dernier du paquet. Il est de taille variable car les options sont... optionnelles (section 3.13). Bien que plusieurs options aient été normalisées, elles sont très peu utilisées en pratique, en partie parce qu'elles ne passent pas partout, en partie parce que leur présence peut ralentir sérieusement le paquet (beaucoup de routeurs traitent le paquet « normal » en ASIC et transmettent les paquets ayant des options au processeur principal, bien plus lent : cela peut être exploité pour DoSer le routeur en envoyant plein de paquets avec options).

Les options étant de taille variable (le curieux lira avec amusement la section 3.1 du RFC 791, qui explique les deux méthodes d'encodage d'une option), il y a une nouvelle possibilité d'attaque par débordement de tampon, si l'indication de la longueur de l'option est fausse. Là encore, quelques tests sont indispensables, les options du cas 2 ont une longueur d'au moins deux octets (option-length >= 2), et cette longueur ne doit pas nous mener en dehors du paquet (option-offset + option-length <= IHL * 4). Si vous êtes étudiant, faites attention : écrire un analyseur de paquets IP est un TP classique et le professeur sadique risque fort d'envoyer à votre analyseur des paquets délibérement mal formés pour vous prendre en défaut.

Autre piège pour le code d'analyse, les types utilisés : certaines options ont des pointeurs, stockés sur un octet, et le RFC 791 ne précise pas si cet octet est signé ou non. Si on ne fait pas attention, on peut se retrouver avec des pointeurs négatifs.

Ça, c'était le problème des options en général. Après, certaines options spécifiques ont leurs propres problèmes de sécurité. LSSR (Loose Source and Record Route, option de numéro 13) permet de contourner le routage et donc certaines règles des pare-feux, permet de joindre des machines normalement injoignables (par exemple si elles ont une adresse IP privée et sont derrière un routeur NAT), etc. Ces risques sont tels, par rapport aux bénéfices de cette option, que notre RFC 6274 recommandent de jeter sans autre forme de procès tous les paquets ayant cette option, dans la configuration par défaut des équipements. Un exemple d'attaque contre OpenBSD est décrit dans « OpenBSD Security Advisory: IP Source Routing Problem ». Mêmes remarques, et même recommandation pour l'option SSSR (Strict Source and Record Source, numéro 137). Cette option a déjà été utilisé pour des attaques (par exemple « Microsoft Security Program: Microsoft Security Bulletin (MS99-038). Patch Available for "Spoofed Route Pointer" Vulnerability" ».

L'option Record Route (section 3.13.2.5) est encore pire puisque le routeur doit alors écrire dans le paquet lui-même. Comme avec les deux précédentes, il est vital de vérifier que les pointeurs ne pointent pas n'importe où. (Le problème touche d'autres protocoles qu'IP ; par exemple, lors du dévelopement de DNSmezzo ou de grong, j'ai pu constater que les pointeurs utilisés dans la compression des paquets DNS sont souvent invalides et ne doivent pas être suivis aveuglément.) En outre, cette option est indiscrète, puisqu'elle permet de réveler les routeurs par lesquels est passé un paquet. La taille très limitée du champ Options limite ce risque (on ne peut pas stocker plus de quelques routeurs) et rend cette option peu utile.

Un grand nombre de ces options peuvent être considérées comme n'étant que d'un intérêt historique (mais le code pour les traiter est parfois toujours là dans la pile IP et peut provoquer des problèmes de sécurité). C'est le cas de Timestamp (numéro 68, section 3.13.2.7), qui indique au routeur de marquer l'heure de passage du paquet dans le paquet. Comme Record Route, elle est indiscrète et devrait donc être ignorée par défaut. Comme Record Route, elle entraine une écriture dans le paquet, à l'endroit indiqué par un pointeur et il faut donc, si on a activé cette option, vérifier le pointeur.

Je passe sur un certain nombre d'options pittoresques pour arriver à DoD Basic security Option (numéro 130). Cette option militaire, normalisée dans le RFC 1108, indique le niveau de sécurité du paquet (« confidentiel », « secret », « très secret », etc). Contrairement à la plupart des options IPv4, elle est largement mise en œuvre et déployée. Par exemple, SELinux, Cisco IOS et Solaris l'ont et beaucoup de réseaux comptent dessus. Elle a même inspiré un équivalent IPv6, décrit dans le RFC 5570.

Après cette longue liste des champs de l'en-tête IP, la section 4 de notre RFC 6274 s'attaque aux mécanismes actifs de traitement des paquets. De nouvelles failles se cachent là. Les principales touchent le processus de fragmentation et réassemblage (section 4.1). Lorsqu'un paquet IPv4 est trop gros pour le lien qu'il va emprunter, l'émetteur, ou bien le routeur intermédiaire, fragmentent ce paquet en paquets plus petits. La machine de destination (pas les routeurs) va devoir réassembler un paquet entier. Historiquement, ce processus est à l'origine de très nombreuses failles de sécurité. En effet, le réassemblage est une opération très complexe et qui était mal normalisée. C'est une opération qui nécessite de maintenir un état (dans un protocole, IP, qui est normalement sans état), le réassembleur ne connait pas les caractéristiques du chemin suivi par les paquets et ne sait donc pas combien de temps il peut attendre des fragments manquants, et les fragments peuvent arriver dans le désordre.

Quelles sont les conséquences de sécurité de la fragmentation ? D'abord, l'allocation mémoire : la machine de destination ne sait pas combien de temps elle doit attendre les fragments manquants. Elle doit donc réserver un espace mémoire pour le paquet et le garder jusqu'à être sûr que les fragments manquants n'arriveront jamais. Le RFC 1122 conseille de rester ainsi pendant 60 à 120 secondes, ce qui est très long si on reçoit beaucoup de paquets et peut mener à un épuisement de la mémoire si un attaquant génère des paquets fragmentés et délibérement incomplets. C'est encore pire si on suit le conseil du RFC 815 qui est d'allouer de la mémoire suffisante pour le plus grand paquet possible (la taille du paquet n'est connue qu'avec le dernier fragment).

Autre problème, le champ ID et sa taille limitée : sur un lien à 1 Gb/s, un flot continu de paquets IP de 1 kb (ce qui peut arriver avec de la vidéo en temps réel), chacun fragmenté en deux, va mener à une réutilisation du champ ID en moyenne au bout de 0,65 secondes seulement. Il y aura donc collision entre les fragments de deux paquets différents et le réassemblage mènera à la corruption (dont on espère qu'elle sera détectée par les protocoles des couches supérieures). Si des paquets sont injectés par un attaquant, il peut ainsi facilement créer une DoS.

Certains des problèmes de sécurité des fragments proviennent d'erreurs ou d'ambiguités dans la spécification. Ainsi, il est possible d'avoir des fragments qui se recouvrent (un fragment va de l'octet 0 à l'octet 959 inclus, un autre fragment de 1200 à 1919 inclus et encore un autre fragment va de 960 à 1279. Pour les octets de 1200 à 1279, doit-on utiliser le deuxième ou le troisième fragment ? Différents mises en œuvre d'IP ont fait des choix différents et ce point a été exploité par des outils qui fragmentent le paquet afin qu'il échappe à l'IDS (en utilisant le fait que l'IDS et la machine de destination n'utiliseront pas la même stratégie.) Un exemple d'un tel outil est Frag.

La section 4.1.2 rassemble un ensemble de conseils sur la fragmentation. S'ils étaient appliqués, IP serait plus sûr :

  • Avoir deux espaces mémoire différents, pour le réassemblage et pour les paquets arrivant entiers, afin d'empêcher qu'une attaque par fragmentation ne bloque le service « normal » (Linux fait ceci),
  • Réduire le temps d'attente (les 60 à 120 secondes officielles sont beaucoup trop),
  • Jeter les fragments qui ont coupé l'en-tête du protocole de niveau supérieur (ces en-têtes sont assez petits pour ne jamais être fragmentés en temps normal, une telle coupure indique presque à coup sûr une tentative d'échapper au pare-feu ou à l'IDS),
  • Et bien d'autres.

Le RFC 1858 et son successeur RFC 3128 fournissent des détails sur ces points.

Autre grande question, la transmission des paquets IP par un routeur (section 4.2). Par définition, un routeur reçoit des paquets qui ne lui sont pas destinés et qu'il doit transmettre. Cela peut soulever des problèmes de sécurité. Par exemple (section 4.2.3) , si un routeur doit faire une requête ARP (RFC 826) pour trouver l'adresse MAC de la machine suivante, et qu'il garde le paquet à transmettre en attendant la fin de la résolution ARP, un attaquant peut épuiser les ressources du routeur en envoyant plein de paquets vers des destinations inexistantes. Il est donc suggéré de jeter immédiatement les paquets lorsqu'une résolution ARP est nécessaire, en espérant que l'émetteur les renverra, s'ils étaient importants.

Enfin, l'adressage IP peut aussi recéler des pièges (section 4.3). Ainsi, un préfixe est réservé à des fins expérimentales, le 240/4 (ancienne « classe E », section 4.3.4). Le RFC, suivant une vieille pratique, recommande de jeter sans hésitation les paquets dont l'adresse source est dans ce bloc. Ce conseil est d'ores et déjà largement suivi, et est la raison pour laquelle on ne peut pas espérer récupérer ces nombreuses adresses IPv4 pour faire face à l'épuisement.

Voilà, et on n'a couvert qu'IP et pas les autres protocoles de la famille. Reste maintenant à faire le même travail pour IPv6. Qui s'y colle ?

Si cette lecture peut donner l'impression qu'IPv4 est une incroyable erreur de sécurité, bourrée de vulnérabilités, il faut aussi se rappeler, comme l'analyse le RFC 5218, que ce sont certains raccourcis pris par IP qui ont permis ce succès. Aujourd'hui, il est certain qu'IPv4 ne serait pas accepté par l'IESG et c'est pourtant le protocole qui a fait décoller l'Internet.

À noter que ce RFC est très largement inspiré du rapport « Security Assessment of the Internet Protocol », du Centre for the Protection of National Infrastructure (CPNI) britannique. D'autre part, la bibliographie du RFC est recommandée, c'est un rappel de toutes les fameuses failles de sécurité d'IP.


Téléchargez le RFC 6274


L'article seul

RFC 6272: Internet Protocols for the Smart Grid

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : F. Baker, D. Meyer (Cisco Systems)
Pour information
Première rédaction de cet article le 22 Juin 2011


Le titre de ce RFC ne rend pas complèment compte de son but. Ce document est en fait une présentation complète de la suite de protocoles TCP/IP, celle qui fait tourner l'Internet. Conçu pour des ingénieurs qui viennent d'une autre culture que celle des barbus Unix, récapitulant tout ce qu'il faut savoir sur les protocoles de la famille, ce texte est utilisable comme base d'un cours, ou comme introduction à TCP/IP. Il a été conçu pour le projet Smart Grid.

En effet, ce projet de distribution de l'électricité en faisant appel à des équipements plus proches des ordinateurs que des traditionnels transformateurs et compteurs, équipements qui communiqueraient beaucoup entre eux, cherche une architecture réseau. Un certain nombre de consultants, souvent ignorants de ce qui s'est fait depuis trente ans sur l'Internet, prône le développement en partant de zéro de nouvelles techniques, non prouvées et coûteuses à créer, alors que TCP/IP fournit déjà tout ce qu'il faut. Ce RFC explique TCP/IP pour les débutants, et fournit une liste des protocoles, dont peut être tirée un futur profil Smart Grid (un profil étant un sous-ensemble adapté à une tâche donnée). Voir la section 1 à ce sujet.

Comme je ne connais pas assez Smart Grid, et que le RFC ne contient quasiment rien de spécifique à ce projet (l'annexe A rassemble les informations purement Smart Grid), je vais adopter une autre perspective en utilisant ce RFC comme moyen de présenter les protocoles d'Internet, à un ingénieur qui ne les connaîtrait pas. Ces protocoles sont désignés dans le RFC sous le nom d'IPS, Internet Protocol Suite. À partir d'ici, si vous connaissez déjà l'IPS, vous avez le droit de partir et d'aller voir un film (par exemple Le chat du rabbin) ou de lire un livre (par exemple Le chat du rabbin).

L'IPS est décrite dans les fameux RFC. Outre la normalisation des protocoles, certains RFC sont là pour décrire l'implémentation par exemple les RFC 1122 et RFC 1123 sur les machines terminales et le RFC 1812 sur les routeurs. (Avec une version des spécificités IPv6 dans le RFC 6434.) Une des particularités de l'IPS est qu'elle offre des choix : ainsi, il existe plusieurs protocoles de transport comme TCP (RFC 793) ou SCTP (RFC 4960) et même un « non-protocole », UDP (RFC 768), où l'application doit faire tout le travail de la couche 4. La section 2 de ce RFC va présenter l'architecture de l'IPS, la section 3 une liste de protocoles et la section 4 l'organisation non-technique de l'Internet (relations d'affaires, etc).

Donc, c'est parti, comment tous ces protocoles tiennent-ils ensemble ? L'Internet Protocol Suite suit la classique organisation en couches (section 2.1). Si le principe est celui du modèle OSI, le découpage des couches n'est pas forcément le même, ni la terminologie. Ainsi, l'OSI parle (en anglais) de end system lorsque l'IPS dit host (que je traduis par machine terminale) et l'OSI dit intermediate system où l'IPS dit router.

En partant du haut, de ce qui est le plus proche des utilisateurs, on trouve la couche Applications (section 2.1.1). L'IPS ne fait pas de distinction forte entre les couches 5, 6 et 7, considérant plutôt une seule couche Applications.

Ensuite, toujours en allant vers le bas, l'IPS a une couche de Transport (section 2.1.2). Le terme de transport est très galvaudé. Énormément d'ingénieurs l'utilisent pour dire « les couches du dessous qui ne m'intéressent pas ». Un concepteur d'un réseau optique va parler du transport pour la fibre sous-jacente, alors que le développeur d'une application Web va considérer que le protocole HTTP est le transport, pour son application. Mais dans l'IPS, « transport » a un sens bien précis, c'est la plus basse couche qui va de bout en bout. Des protocoles archi-connus comme TCP (RFC 793) ou très exotiques comme NORM (RFC 5740) mettent en œuvre ce transport. Comme plusieurs flots de données simultanés peuvent exister entre deux adresses IP, le démultiplexage se fait sur la base d'un numéro de port géré par la couche transport. Deux flots différentes auront ainsi des couples {port source, port destination} différents. Les différents protocoles de transport fournissent en outre des services tels que garantie de délivrance des données (ou pas), gestion de messages séparés (ou bien flot d'octets continu, ce que fait TCP), contrôle de la congestion.

Continuons à descendre vers les couches bases, la couche Réseau (section 2.1.3) vient ensuite. Au contraire du choix qui existe en couche Transport, il n'y a qu'un seul protocole de couche Réseau, IP (ou deux, si on considère IPv4 et IPv6 comme différents). IP fournit un service de datagrammes : chaque paquet est indépendant des autres, porte donc les adresses IP de source et de destination, et il n'y a pas besoin d'établir un circuit avant d'envoyer des données. IP fournit également un service de fragmentation, permettant de découper un paquet trop gros avant de le réassembler à la fin.

IP peut fonctionner sur d'innombrables protocoles de couche 2. L'IETF n'en normalise aucun (à l'exception possible de MPLS, RFC 4364, tout dépend comment on place ce protocole dans le modèle en couches). La plupart du temps, ces protocoles des couches basses (section 2.1.4) sont normalisés par l'IEEE : 802.3, 802.11, 802.16, etc. IP peut aussi tourner sur IP, via des tunnels comme GRE (RFC 2784).

La famille TCP/IP a souvent été critiquée pour son manque de sécurité (section 2.2). En fait, toute la sécurité dans l'Internet ne dépend pas de TCP/IP. Le hameçonnage, par exemple, est une question d'éducation et d'interface utilisateur, deux points très importants mais qui ne sont pas du ressort de l'IETF. D'autres problèmes (comme la faille BGP dite « attribut 99 ») ne relèvent pas non plus de la sécurité du protocole puisqu'ils sont causés par une bogue dans un programme mettant en œuvre le protocole.

D'autres questions de sécurité viennent de l'organisation de l'Internet, pas de ses protocoles. Ainsi, il n'existe pas de chef de l'Internet, qui pourrait ordonner que les vieilles versions des logiciels, versions ayant des bogues connues, soient immédiatement retirées du service. On constate qu'elles traînent souvent dans la nature. De même, les nouvelles techniques de sécurité ont souvent du mal à être déployées, puisqu'aucune autorité ne peut imposer leur emploi. Il faut au contraire convaincre chaque administrateur réseaux. (Des exemples de protocole de sécurité dont le déploiement a été faible sont SPFRFC 4408 et IPsecRFC 4301. Un exemple d'un protocole de sécurité qui a mis très longtemps à être déployé est DNSSECRFC 4033.)

Cela ne veut pas dire que l'IETF baisse les bras sur la sécurité. Chaque nouveau protocole doit inclure une analyse de sécurité, et le RFC 3552 guide les auteurs pour cette tâche.

Les problèmes de sécurité de la couche physique se traitent en général par des moyens physiques (enterrer et protéger les câbles, par exemple). Pour les autres couches, le problème est posé en termes de trois services : Confidentialité, Intégrité et Disponibilité. On souhaite que les conversations privées restent privées (Confidentialité), on souhaite que les données soient authentifiées au départ, puis arrivent sans modifications (Intégrité) et on souhaite que l'Internet marche (Disponibilité). Voici deux exemples :

  • Une attaque classique contre TCP est d'envoyer des faux paquets RST (ReSeT), faux car utilisant une adresse IP source fabriquée, pour casser la connexion en cours. Il existe plusieurs protections, comme l'authentification TCP (RFC 5925), ou bien une sécurité au niveau en dessous comme IPsec. (Le RFC laisse entendre que TLS est une autre solution mais il ne protège pas du tout contre ces attaques.)
  • Une autre attaque contre TCP est le SYN flooding où l'attaquant tente d'ouvrir suffisamment de connexions TCP pour épuiser les ressources de l'attaqué (la liste des connexions est typiquement de taille finie). Il existe aussi des protections comme les SYN cookies du RFC 4987.
  • Dans les deux cas précédents, l'attaque portait sur la Disponibilité. Un exemple d'attaque contre la Confidentialité serait un accès non autorisé au réseau.

Dans beaucoup de cas, une première étape vers la sécurisation est la création d'un canal sûr entre la source et la destination (TLS ou IPsec le permettent.) Mais attention, ce n'est pas suffisant de sécuriser la communication, car le pair peut lui-même être malveillant, délibérement ou à son insu.

Enfin, l'infrastructure de l'Internet compte également des protocoles qui sont officiellement dans les applications mais sont en pratique nécessaires au bon fonctionnement. La section 2.3.1 mentionne le DNS, système de correspondance entre un nom de domaine et des données (typiquement des adresses IP). Bien sûr, l'Internet peut fonctionner sans le DNS. Mais, en pratique, cela serait vite insupportable (contrairement à ce qu'on lit parfois, la plupart des sites Web ne sont pas accessibles via leur adresse IP, voir section 14.23 du RFC 2616). Et la section 2.3.2 mentionne les outils de gestion de réseau comme les deux protocoles de gestion SNMP et Netconf (RFC 4741). (Dans le projet français PREMIO, SNMP est utilisé.)

La section 3 du RFC attaque ensuite les protocoles spécifiques. L'idée, là encore, est d'utiliser pour la Smart Grid des protocoles bien conçus, éprouvés, et disposant de mises en œuvre nombreuses et de qualité, souvent en logiciel libre.

Cette section commence avec la sécurité, La section 3.1 se penche d'abord sur l'AAA. Dans le contexte de l'Internet, cela concerne les protocoles qui autorisent l'accès au réseau, Radius (RFC 2865 et Diameter (RFC 3588). Ces protocoles utilisent souvent un mécanisme d'authentification nommé EAP (RFC 4017 ; opinion personnelle, EAP est d'une grande complexité), qui permet à son tour plusieurs méthodes (RFC 5216, RFC 5433).

Une fois qu'on a accès au réseau, reste à protéger les communications. Au niveau 3, une solution générale est IPsec (RFC 4301), qui « cryptographie » tout le trafic IP, fournit intégrité et authentification, aussi bien que confidentialité (IPsec est une architecture, pas un protocole, donc la liste des services peut dépendre du protocole). Pour l'échange des clés cryptographiques, cela peut se faire à la main (sans doute la technique la plus courante aujourd'hui) ou bien via le protocole IKE (RFC 5996). À noter que notre RFC 6272, bien que se voulant pratique, mentionne rarement de choix lorsque plusieurs protocoles existent. Toutefois, pour IPsec, il note que ESP (RFC 4303) est de très loin le plus utilisé et qu'on peut oublier les autres.

La sécurité peut-elle être assurée dans la couche 4 ? Oui, grâce au très connu protocole TLS (RFC 5246). TLS chiffre toute la communication de l'application. Il ne protège pas contre les attaques situées plus bas, mais est bien plus simple à déployer qu'IPsec.

Enfin, la sécurité peut être appliquée au niveau des applications, où on a le maximum de souplesse. La famille TCP/IP a plusieurs mécanismes dans sa boîte à outils pour cela :

  • CMS (RFC 5652) est une syntaxe pour avoir des messages authentifiés et/ou confidentiels, en utilisant la cryptographie. Cette syntaxe peut ensuite être utilisée dans des applications comme les mises à jour de logiciels (RFC 4108) ou bien le courrier électronique (RFC 5751 sur S/MIME, à noter qu'il existe une syntaxe concurrent, celle d'OpenPGP, RFC 4880, non mentionnée par le RFC).
  • Si on préfère le format XML, le RFC 3275 décrit un moyen de signer XML.
  • L'authentification peut utiliser OAuth (RFC 5849).

Toujours dans la boîte à outils, la famille TCP/IP a aussi un protocole de connexion sécurisée à distance, SSH (RFC 4253), qui peut aussi servir de mécanisme pour faire des tunnels sûrs (en concurrent d'IPsec, donc).

Toute solution fondée sur la cryptographie a besoin d'un mécanisme de gestion des clés. L'IETF en a au moins deux, PKIX (RFC 5280), fondé sur X.509, et Kerberos (RFC 4120), le second étant plutôt limité au cas où tout les participants sont dans le même domaine administratif.

Après ces considérations sur la sécurité, place à la description des protocoles de couche 3. L'Internet en a actuellement deux, IPv4 et IPv6 (section 3.2). IPv4 est décrit en détail dans la section 3.2.2. Je passe rapidement, pour arriver à IPv6 en section 3.2.3. IPv6 est normalisé dans le RFC 2460. À noter que, pour le cas de la Smart Grid, dont certains équipements peuvent avoir des capacités et des connexions peu performantes, les RFC comme le RFC 4919 peuvent être également utiles.

Les adresses IPv6 sont décrites dans le RFC 4291. Elles peuvent être distribuées aux machines terminales via le protocole DHCP (RFC 3315) ou bien sans serveur par un système d'auto-configuration (RFC 4862). Deux machines IPv6 dans le même réseau se trouvent par le protocole NDP (RFC 4861).

Le routage des paquets IPv6 se fait d'abord par la distribution des informations entre routeurs, puis par l'utilisation de ces routes lors de la transmission de chaque paquet. La route la plus spécifique (le préfixe le plus long) est utilisée. Pour distribuer les routes, les routeurs peuvent utiliser divers protocoles comme OSPF (RFC 5340 et qui peut router IPv4 comme IPv6, grâce au RFC 5838) et BGP (RFC 2545). OSPF est utilisé à l'intérieur d'un domaine administratif et fait partie des protocoles « à état des liens » dont l'avantage est que chaque routeur a une vue complète du réseau (au lieu de router par « on-dits »). BGP est utilisé entre domaines administratifs et c'est donc lui qui lie les routeurs de l'Internet.

Il y a aussi des protocoles de routage spécifiques aux réseaux de capteurs, les équipements peu puissants dont je parlais plus haut. OSPF, où chaque routeur doit garder en mémoire tous les liens de tout le réseau, ne convient pas forcément pour cette tâche. Parmi les concurrents plus adaptés, on trouve par exemple AODV (RFC 3561) ou d'autres protocoles en cours de définition (voir le cahier des charges dans les RFC 5548, RFC 5673, RFC 5826 et RFC 5867).

Depuis l'épuisement des adresses IPv4, la migration vers IPv6 est nécessaire mais elle n'est pas instantanée et il faut donc gérer la coexistence entre les deux protocoles. Il existe plusieurs mécanismes pour cela mais tous ne sont pas recommandés (cf. RFC 6180). Le plus simple et le plus conseillé est la « double-pile » : le réseau et les machines ont à la fois IPv4 et IPv6, jusqu'à ce qu'on puisse éteindre la dernière adresse v4 (RFC 4213). Si on ne peut pas disposer d'une connectivité IPv6 native, l'approche recommandée est de tunneler le trafic v6 à travers l'Internet, par exemple par les techniques du RFC 5569. Enfin, si une des deux machines participant à la communication est purement v4 ou purement v6, il faut utiliser les techniques de traduction. Celles-ci recélant des pièges inattendus, le mieux est de préférer la traduction faite au niveau des applications (par des relais applicatifs). Sinon, l'IETF a normalisé un cadre général de traduction v4<-> v6 dans le RFC 6144, avec des déclinaisons dans des protocoles comme celui du RFC 6146.

Continuant à monter vers les couches hautes, la section 3.3 présente les protocoles de transport de l'IPS (Internet Protocol Suite). Le plus connu est TCP, responsable sans doute de la très grande majorité du trafic de l'Internet. TCP garantit aux applications qui l'utilisent la délivrance des octets, dans l'ordre et sans perte. Si le RFC qui le normalise date de trente ans, TCP a subi pas mal de travaux et de modifications et il vaut donc mieux commencer par lire le RFC 4614 pour tout savoir de ce protocole. Par exemple, pour la sécurité de TCP, le RFC 4987 est une bonne lecture.

Autre protocole de transport, UDP (RFC 768), un protocole minimal qui n'assure presque aucune fonction : l'application qui l'utilise doit tout prévoir, le contrôle de congestion (ne pas envoyer trop de paquets pour ne pas surcharger le réseau), la détection des pertes (et réessayer si nécessaire), etc. Le RFC 5405 guide les applications à ce sujet.

Il existe d'autres protocoles de transport qui n'ont guère eu de succès comme SCTP (RFC 4960) ou DCCP (RFC 4340), une sorte d'UDP avec contrôle de congestion.

Pour les protocoles d'infrastructure, la section 3.4 mentionne :

  • Le DNS : des noms hiérarchiques (www.example.com est un sous-domaine de example.com, lui-même sous-domaine de .com) et un protocole de résolution de noms en données (RFC 1034). Il existe un mécanisme de sécurisation, décrit par le RFC 4033.
  • DHCP (RFC 2131 en IPv4 et RFC 3315 en IPv6) permet d'attribuer des adresses IP (et de distribuer d'autres informations comme l'adresse du serveur de temps) aux différentes machines d'un réseau local depuis un point central. Il facilite donc beaucoup la vie de l'administrateur réseaux. Sans lui, lorsqu'on voudrait renuméroter les machines, il faudrait se connecter à chaque machine pour changer sa configuration. (Regardez comment on faisait en 1992.)
  • Je viens de parler du serveur de temps. Le protocole NTP (RFC 5905) permet justement de mettre à l'heure les horloges de toutes les machines de l'Internet et s'assurer qu'elles soient d'accord. C'est une tâche plus compliquée qu'elle n'en a l'air.

Et la gestion de réseaux (section 3.5) ? Les deux protocoles concurrents sont SNMP (RFC 3411 et RFC 3418) et Netconf (RFC 4741). Lequel choisir ? Notre RFC 6272 ne fournit pas d'indications à ce sujet... La seule information de comparaison donnée est que SNMP utilise l'encodage ASN.1 alors que Netconf utilise XML.

Une machine qui démarre a souvent besoin d'informations sur son environnement, par exemple les coordonnées d'une imprimante ou bien d'un serveur de courrier. C'est le domaine des protocoles de découverte (section 3.6). C'est depuis longtemps une faiblesse de la famille TCP/IP. Le problème n'est pas complètement résolu de manière standard. Le RFC cite un protocole comme SLP (RFC 2608, qui n'a jamais été très utilisé) ou comme le protocole d'Apple, Bonjour. D'autres protocoles sont en cours de développement comme le futur COAP (Constrained Application Protocol), qui utilise HTTP pour demander à un serveur ces informations, en utilisant les adresses « bien connues » du RFC 5785.

Enfin, le RFC 6272 cite également (section 3.7) un certain nombre d'applications, qui ne font pas partie de l'IPS à proprement parler, mais qui peuvent être utiles à des déploiements sur TCP/IP. Par exemple, la famille TCP/IP a un protocole standard d'établissement de sessions multimédia, SIP (RFC 3261 et beaucoup d'autres). SIP est surtout utilisé pour la téléphonie sur IP mais a d'autres usages. SIP ne fait que la signalisation (appeler, raccrocher, etc) et la description de la session (voix, vidéo, codecs utilisés, est faite avec le format SDP (RFC 4566). En pratique, SIP a pas mal de problèmes sur l'Internet, face à la fermeture croissante du réseau par des mécanismes comme le NAT (le RFC 2993 décrit le problème et le RFC 5626 propose des solutions).

Autre application qui peut servir, XMPP (RFC 6120), un protocole d'échange de données XML en temps réel dont l'utilisation la plus connue est pour la messagerie instantanée (RFC 6121). XMPP est très riche et dispose de nombreuses extensions (par exemple pour du dialogue à plusieurs, dans des « pièces » virtuelles).

Après cette longue présentation des différents protocoles de la famille, le RFC expose l'architecture non-technique de l'Internet, c'est-à-dire son organisation sociale. Rien de nouveau pour les professionnels de l'Internet mais rappelez-vous que ce RFC est conçu pour des gens d'une culture très différente. La section 4 explique donc que l'Internet est un réseau de réseaux (c'est en cela que son ancêtre, l'Arpanet, était très différent : il était mono-réseau). Ces réseaux s'interconnectent entre eux (sinon, un abonné d'un réseau ne pourrait pas joindre un abonné d'un autre, ce qui était courant avec les technologies pré-Internet). Cette interconnexion est le cœur de l'architecture sociale de l'Internet dont le but est que tout le monde puisse parler à tout le monde (note personnelle au passage : cette interconnexion généralisée semble une banalité aujourd'hui. Mais, dans les années 1990, il était fréquent d'entendre des messieurs sérieux expliquer qu'il n'était pas nécessaire qu'une entreprise doive se connecter à d'autres que ses sous-traitants.)

On peut présenter les différents réseaux qui composent l'Internet en disant qu'il y a une différence entre les réseaux de transit et les autres. Les réseaux de transit forment le cœur de l'Internet. Leur seule activité est de connecter les autres réseaux. Ils vendent ce service aux réseaux d'accès et réseaux d'organisations. Les réseaux d'accès sont ceux du FAI typique, qui connecte M. Toutlemonde (particuliers et petites organisations) moyennant un paiement de trente € par mois. L'accès se fait via ADSL, RTC, 3G ou bien d'autres techniques. Les réseaux d'organisation sont ceux des entreprises, associations, collectivités locales ou universités, qui fournissent de l'accès à leurs employés et étudiants.

Si je fais de chez moi (abonné à Free) un traceroute vers ce blog, je passe successivement par le réseau d'accès du groupe Iliad (Free et Proxad), puis par le réseau de transit Cogent, puis j'arrive chez Datotel, le réseau d'entreprise où le serveur est hébergé :

% traceroute www.bortzmeyer.org
traceroute to www.bortzmeyer.org (208.75.84.80), 30 hops max, 60 byte packets
 1  freebox (192.168.2.254)  5.984 ms  7.027 ms  7.068 ms
...
 4  cha75-6k-1-v906.intf.nra.proxad.net (78.254.255.197)  35.671 ms  35.726 ms                  35.766 ms
 5  bzn-crs16-1-be1502.intf.routers.proxad.net (212.27.58.65)  35.806 ms  37.060      ms  37.125 ms
 6  bzn-6k-2-po57.intf.routers.proxad.net (212.27.59.217)  38.222 ms * *
 7  th2-crs16-1-be1005.intf.routers.proxad.net (212.27.56.5)  39.893 ms  23.638                 ms *
 8  te4-8.330.ccr01.par04.atlas.cogentco.com (149.6.164.221)  44.829 ms  45.136                 ms  49.465 ms
 9  te0-1-0-4.mpd21.par01.atlas.cogentco.com (130.117.2.77)  55.562 ms 53.303 ms   54.986 ms
...
16  host46.datotel.com (208.82.151.46)  127.897 ms   127.465 ms  127.109 ms
17  stl-d2-g5-1.datotel.com (208.82.151.26)  128.295 ms  126.546 ms  127.575 ms
18  host125.datotel.com (208.75.82.125)  127.461 ms * *
...

(Les étoiles représentent des cas où un paquet a été perdu.) Notez que le routeur chez moi, la Freebox, avait une adresse privée (RFC 1918).

Le RFC ne parle pas des relations de peering entre réseaux. À ce sujet, un très intéressant document est le rapport de PCH.

À noter que le RFC n'expose que l'architecture sociale, pas la gouvernance de l'Internet, vaste sujet mais fort loin des problèmes opérationnels...

Souvent, les traceroutes sont interrompus subitement et plus rien n'est visible. C'est souvent le résultat d'un pare-feu mis sur le trajet. Notre RFC note que ces équipements sont très fréquents dans l'Internet d'aujourd'hui, mais aussi qu'ils sont très controversés. En effet, leur efficacité n'est pas prouvée, la plupart des attaques provenant de l'intérieur (soit parce qu'une personne située dans l'organisation mène l'attaque, soit parce qu'une machine interne a été infectée par un logiciel malveillant, le pare-feu ne protégeant souvent pas contre les attaques par « charge utile »). Bref, le pare-feu ne doit être utilisé que comme composante d'une solution de sécurité, pas comme l'alpha et l'oméga de la sécurité. Il existe plusieurs RFC ayant un rapport avec les pare-feux comme le RFC 2647 (mesures de performance), RFC 2979 (règles que doivent suivre les pare-feux), RFC 5207 (un exemple des problèmes que peuvent poser les pare-feux pour un nouveau protocole), etc.

Autre source de problèmes lorsqu'on circule dans l'Internet, les NAT. Cette technique a été inventée vers 1993 pour pallier le manque d'adresses IPv4 en traduisant des multiples adresses privées du réseau interne vers la seule adresse IP publique. En IPv6, le NAT est devenu inutile, vue l'abondance d'adresses. Mais comme certaines personnes s'imaginent que le NAT joue aussi un rôle pour la sécurité, en servant de pare-feu, il reste très présent et gêne souvent les communications. Les NAT sont décrits dans les RFC 2663 et RFC 3022, leurs conséquences néfastes pour les communications sont expliquées dans le RFC 3027, des idées pour les développeurs d'applications dans un monde où il y a beaucoup de NAT ont été rassemblées dans le RFC 3235, d'autres techniques de contournement sont dans le RFC 5128, quant à la position officielle de l'IAB sur les NAT, elle est dans le RFC 3424.

Sur le projet Smart Grid, si celui-ci n'a pas encore d'architecture réseau normalisée, il a déjà des documents. On peut consulter « Smart Grid Architecture Committee: Conceptual Model White Paper » (document uniquement en format privateur MS-Word, ce qui donne une idée de l'écart de culture avec l'Internet) et IEC 61850.


Téléchargez le RFC 6272


L'article seul

RFC 6270: The 'tn3270' URI Scheme

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : M. Yevstifeyev
Chemin des normes
Première rédaction de cet article le 6 Juin 2011


Ce RFC n'aura pas un grand intérêt pratique, vu le petit nombre de terminaux 3270 encore en service ! Mais il était nécessaire pour compléter la liste des plans (schemes) d'URI, qui le mentionnait sans vraiment le décrire.

En effet, le désormais dépassé RFC 1738 mentionnait la possibilité d'avoir des URL comme tn3270:mainframe.accounting.example mais sans expliquer leur syntaxe ou leur sémantique. 3270 est une référence aux vieux terminaux des mainframes IBM d'il y a très longtemps. Ces terminaux sont décrits dans les RFC 1041, RFC 1576 et RFC 2355.

Le RFC 1738 a été remplacé il y a longtemps, par le RFC 3986, qui décrit la syntaxe générique des URI. Mais ce petit point spécifique du tn3270: n'avait jamais été traité. Notre RFC 6270 comble donc le vide en spécifiant rigoureusement syntaxe et sémantique des URI tn3270:. La sémantique est très proche de celle des URI telnet: du RFC 4248. Le plan tn3270: est donc désormais, en suivant les règles du RFC 4395, enregistré dans le registre des plans d'URI.


Téléchargez le RFC 6270


L'article seul

RFC 6269: Issues with IP Address Sharing

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : M. Ford (Internet Society), M. Boucadair (France Telecom), A. Durand (Juniper Networks), P. Levis (France Telecom), P. Roberts (Internet Society)
Pour information
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 29 Juin 2011


Pour pas mal de raisons, il est fréquent aujourd'hui qu'une adresse IP soit partagée entre plusieurs machines. Le cas le plus typique est celui des N machines d'une petite entreprise, forcées d'utiliser une seule adresse IP publique, via un routeur NAT. Ce RFC est le premier document qui discute en détail de ce partage d'adresses, et de ses innombrables inconvénients.

Le RFC met surtout l'accent (section 1) sur une cause du partage d'adresses : l'épuisement de la réserve d'adresses IPv4, qui, n'étant pas compensée par un déploiement massif d'IPv6, mène à ce que le partage d'adresses soit très fréquent, et le sera sans doute davantage dans le futur (la plupart des solutions d'attente d'IPv6 utilisent intensivement ce partage). En fait, aujourd'hui, il est rare que M. Michu puisse bénéficier d'une vraie connexion Internet : il partage en général son adresse avec d'autres M. Michu ; par exemple, à la maison, M. Michu n'a aucune chance d'obtenir plus d'une adresse IPv4, même si plusieurs personnes vivent dans ce foyer et utilisent toutes des appareils connectés à l'Internet (ce qui est banal aujourd'hui dans les grandes villes du Nord). Le CPE fait office de routeur NAT et les machines de M. Michu et de sa petite famille sont contraintes de se contenter d'adresses IP privées (RFC 1918). Mais l'avenir (déjà réalisé en Europe sur les connexions ultra-civilisées de la 3G, et, en Asie, dès à présent sur toutes les connexions) nous réserve pire : le partage d'adresses IP, non pas au sein du foyer ou de la petite entreprise, mais entre abonnés, ce qu'on nomme parfois le CGN, pour Carrier-Grade NAT et qu'on pourrait qualifier de « partage d'adresses généralisé ». (L'annexe A résume les différents types de partage d'adresses.) Le « facteur multiplicatif » (annexe B) entre le nombre d'adresses privées et celui d'adresses publiques vaut typiquement entre 3 et 10 pour une maison européenne typique (une seule adresse publique mais plusieurs machines connectées, smartphones, ordinateurs, consoles de jeu, etc). Il pourrait dépasser 1000 avec les CGN (plusieurs adresses IP publiques mais des milliers d'abonnés se partageant ce mince gâteau).

Le RFC insiste sur le fait que le déploiement d'IPv6 est la seule solution correcte aux problèmes engendrés par le partage d'adresses. C'est vrai mais il faut noter que le partage d'adresses a commencé bien avant la famine, qu'il est pratiqué par des entreprises qui disposent de suffisamment d'adresses IPv4 (en général au nom de pseudo-arguments de « sécurité ») et qu'on le trouve pratiqué massivement en Afrique et en Asie alors que le continent africain est celui qui a la plus grande réserve d'adresses IPv4 officielles disponibles. Donc, le non-déploiement d'IPv6 n'est pas la seule raison de l'utilisation du partage d'adresses.

J'ai mentionné le NAT tout à l'heure. Si le partage d'adresses se fait en général (mais pas toujours) via le NAT, l'inverse n'est pas forcément vrai. On peut avoir du NAT sans partage d'adresses, si chaque adresse interne est mise en correspondance avec une et une seule adresse externe. Évidemment, en IPv4, c'est rare, vu le manque d'adresses, mais cela sera peut-être plus fréquent avec IPv6.

À noter que ce RFC ne discute que du problème : il ne propose pas de solution, celles-ci étant renvoyées à des documents ultérieurs (qui ne seront peut-être pas nécessaire si le déploiement d'IPv6 rend inutile ces solutions). Il ne se penche pas non plus sur les problèmes qui sont spécifiques à une technique utilisant le partage d'adresses, essayant au contraire de voir les questions communes à toutes ces techniques. Ainsi, qu'on utilise, pour gérer le passé en attendant le déploiement d'IPv6, NAT64, DS-Lite ou encore d'autres importe peu : toutes ont en commun les même défauts liés au partage d'adresses.

Des problèmes, notamment de sécurité, liés au partage d'adresses avaient déjà été discutés dans les RFC sur le NAT comme les RFC 2663 et RFC 2993 (section 2 de notre RFC). Mais le partage généralisé, entre utilisateurs n'ayant rien en commun, va aggraver ces problèmes. Cette situation se rencontre souvent aujourd'hui en Asie, et dans les hotspots WiFi publics. Mais elle sera hélas sans doute demain le lot de beaucoup d'utilisateurs.

Bien, arrivé à ce stade, vous avez le droit de penser que j'ai beaucoup répété qu'il y avait des problèmes, sans dire lesquels. Patientez encore un peu. L'analyse des problèmes qui commence en section 3 est faite en cherchant d'abord si le problème affecte l'organisation qui déploie le partage d'adresses (et donc ses abonnés ou employés), ou bien des tiers (comme la police par exemple ou bien comme un CDN qui essaie de distribuer du contenu en fonction de l'adresse). Le tout est stocké dans un grand tableau synthétique (figure n° 1) et détaillé dans les sections suivantes. Pour ne prendre que trois exemples de ce tableau, le fait que les requêtes DNS traduisant une adresse en nom perdent de leur signification affecte aussi bien l'utilisateur que les tiers (ceux qui traduisent une adresse IP entrante en nom). Par contre, la perte de traçabilité qui résulte du partage (si on détecte un comportement illégal lié à une adresse IP, on ne retrouve plus facilement la machine en cause) n'affecte que les tiers (les organisations répressives comme la HADOPI). Au contraire, la perte de fiabilité de la connexion (car l'engin qui fait les traductions d'adresses est un nouveau composant dans la connexion, qui peut avoir des bogues ou des pannes, cf. section 18) ne concerne que l'utilisateur, les tiers ne seront pas touchés.

Les sections suivantes du RFC détaillent successivement chacun de ces problèmes (je ne les présente pas dans l'ordre, j'essaie de mettre les plus importantes en premier). La section 5 s'attaque aux problèmes liés à l'allocation de port. Avec le partage d'adresses, plusieurs adresses « internes » sont mises en correspondance avec une seule adresse « externe ». Comment, dans ces conditions, différencier les paquets IP qui arrivent, à destination de cette adresse IP externe ? On utilise le numéro de port TCP ou UDP pour cela et c'est donc le couple {adresse, port} qui identifie la machine et non plus l'adresse seule. Ce numéro de port n'étant stocké que sur 16 bits, cela met une limite stricte à l'ampleur du partage. Si 500 machines partagent une adresse (facteur multiplicatif de 500), cela ne fait qu'un peu plus de 131 ports chacune (et même moins car certains doivent être réservés, cf. RFC 4787), ce qui est vite épuisé sur une machine un tant soit peu active, qui ouvre de nombreuses connexions (une seule page Web peut se traduire par l'ouverture de dizaines de connexions). D'autant plus que ce n'est pas le nombre de connexions actives qui compte, mais celui des connexions TCP dans l'état TIME-WAIT, celui dans lequel les connexions fermées restent pendant quatre minutes (RFC 1337).

Voyons les ports « sortants », ceux alloués pour les connexions initiées de l'intérieur (section 5.1). Les études (Alcock, S., « Research into the Viability of Service-Provider NAT ») semblent indiquer que la distribution de la consommation est très inégale : une minorité d'utilisateurs consomme beaucoup de ports. Cela encourage à répartir les numéros de port à partir d'un pool central, et pas à attribuer de manière fixe des plages de ports à chaque client (cf. annexe A). Mais la seconde solution serait bien plus simple et moins coûteuse. Et la première est vulnérable à une attaque DoS : une seule machine infectée par du malware et qui ouvre des connexions le plus vite possible peut épuiser le pool. Ceci dit, l'allocation statique de plages de ports a aussi ses risques (cf. RFC 6056). Tous ces problèmes existaient avec le partage limité à un foyer ou une entreprise mais sont évidemment plus graves en cas de partage généralisé puisqu'un utilisateur peut être bloqué par un autre utilisateur qu'il ne connait pas.

Et pour les ports des connexions entrantes (section 5.2) ? L'étude citée ci-dessus montre qu'elles sont fréquentes (la majorité des utilisateurs) mais consomment moins de ports. Comment négocier entre la machine de l'utilisateur et le routeur NAT l'allocation d'un port « entrant » ? Aujourd'hui, les méthodes les plus courantes sont l'allocation manuelle (la plupart des CPE permettent de configurer des ports entrants, du genre « toute connexion arrivant pour le port 80 de l'adresse publique doit être traduite vers 192.168.1.13:8080 ») ou bien un protocole comme UPnP. Le CGN complique sérieusement les choses puisqu'il n'est pas dédié à un utilisateur et qu'on doit donc sérieusement étudier sa sécurité avant de permettre à un utilisateur de se réserver les ports 22 ou 80 ! C'est encore pire si le CPE et le CGN doivent coopérer pour rendre le service, puisqu'il n'existe aucun protocole standard pour cela. Actuellement, sur l'abonnement 3G typique en Europe, on n'a pas accès à l'allocation de ports entrants et le smartphone ne peut donc pas héberger de serveur. Cet engin bien plus puissant que les ordinateurs des débuts de l'Internet est donc limité à un rôle de Minitel plus perfectionné.

Il existe des solutions potentielles à ces problèmes mais aucune n'est vraiment satisfaisante. À titre d'exemple, le RFC cite les enregistrements SRV qui pourraient permettre de faire savoir que tel service réside sur tel port de la machine coincée derrière le partage d'adresses. Parmi les limites de cette solution, notons qu'elle ne s'applique pas au protocole le plus demandé, HTTP, qui n'utilise pas les SRV...

Jusqu'à présent, j'ai surtout parlé du problème des applications « serveur », celles qui écoutent des connexions inattendues sur un port bien connu, un serveur SSH, par exemple. On peut se dire que de tel cas sont rares sur la machine de M. Michu, qui n'installe en général pas de serveur SSH, ni même HTTP. Mais il y a toute une catégorie d'applications qui a besoin d'écouter des connexions entrantes sans être pour autant un « serveur » à proprement parler. La section 6 est une bonne occasion de les mentionner. En effet, cette section examine tous les cas où le partage d'adresses gène les applications. Cela concerne bien sûr les serveurs traditionnels, vus en section 5.2, mais aussi, entre autres :

  • Les applications qui indiquent des adresses et des ports dans leur trafic, ce qui concerne typiquement FTP et SIP. Un ALG sera nécessaire pour les gérer.
  • Les applications qui n'utilisent pas du tout de port (ping...) et pour qui il faut donc trouver d'autres moyens de démultiplexage. Une section entière, la 9, détaille les problèmes posés à ICMP, puisque ce protocole n'a pas de notion de port. Outre ping, ce protocole est utilisé, par exemple par les applications pair-à-pair pour mesurer la « distance » avec un pair, ce qui ne marche plus dans le cas d'un partage généralisé.
  • Un cas analogue est celui des applications qui n'utilisent pas TCP ou UDP, mais, par exemple, SCTP ou encore le protocole 41 (encapsulation IPv6 dans IPv4, pour gérer le cas des réseaux qui n'ont toujours pas IPv6). Très rares sont les techniques de partage d'adresses qui gèrent d'autres protocoles que TCP et UDP. Ces techniques contribuent donc à l'ossification de l'Internet (la grande difficulté à déployer de nouveaux protocoles).
  • Les applications qui tiennent pour acquise l'unicité des adresses IP (voir aussi le RFC 6250). Par exemple, une application Web qui lie les cookies à une adresse IP, pour augmenter la sécurité, n'a pas de sens si cette adresse est partagée entre des dizaines d'utilisateurs qui ne se font pas forcément confiance.

Résultat, les applications passent aujourd'hui beaucoup de temps à mettre en œuvre des techniques de contournement, cherchant à récupérer leur connectivité que le NAT contrarie. Il suffit de regarder le code source de n'importe quelle application de téléphonie sur l'Internet pour voir le résultat : le code est plus complexe, et dépend de systèmes difficiles comme ICE (RFC 5245). Avis personnel : il est donc faux de dire que le NAT fait faire des économies. Le NAT est un déplacement de coûts, depuis les administrateurs réseaux vers les développeurs d'applications, contraints à des prodiges d'astuces pour assurer la connectivité.

Un des principaux problèmes que pose fondamentalement le partage d'adresses est la traçabilité (notez que ce n'est pas un problème pour tout le monde). Il est fréquent de suivre les actions d'une machine et de son propriétaire via l'adresse IP. 192.0.2.66 s'est connecté à www.anonymous.org. 203.0.113.13 a envoyé du spam. 198.51.100.254 a participé à une attaque DoS. Évidemment, si les adresses IP sont partagées, cette traçabilité n'existe plus. Aujourd'hui, avec le NAT local classique, on peut au moins relier une adresse IP à un foyer ou une entreprise. Avec du partage d'adresses généralisé, cela ne sera plus le cas (section 12). Actuellement, une requête de la police auprès d'un FAI pour obtenir l'identité d'un abonné dont la machine s'est fait repérer inclus l'adresse IP et l'heure (pour les cas d'adresses IP dynamiques, changeant régulièrement). Le partage généralisé oblige à inclure d'autres informations dans la requête, comme le numéro de port, que peu de serveurs enregistrent aujourd'hui. Attention, identifier un abonné à partir du couple {adresse IP, port} est délicat, car la table de correspondance change bien plus vite que les baux DHCP typiques. La requête doit donc inclure une heure très précise et, pour cela, s'appuyer sur une horloge bien synchronisée. Comme cela risque de ne pas suffire (et cette solution implique que le serveur enregistre le numéro de port source, ce qui est inhabituel aujourd'hui), faudra t-il que le routeur NAT enregistre également l'adresse IP de destination ? Cela étendrait le domaine du flicage très loin...

Et le FAI doit garder des journaux de taille colossale pour pouvoir répondre aux questions comme « Qui utilisait le couple {198.51.100.254, 23152} le 23 mai à 11:28:05 ? », les obligations légales de surveillance imposant en général de conserver ces données pendant six à douze mois. Cela ne sera probablement pas réaliste pour tous les FAI, sauf à créer des obligations légales qui acculeraient bien des opérateurs à la faillite. Noter l'adresse IP de destination aggraverait évidemment le problème.

Comment cela va t-il se passer alors ? Une solution est de baisser les bras et de ne pas divulguer l'identité de l'abonné. Cela peut poser des problèmes légaux au FAI, des lois comme la LCEN en France leur faisant obligation de surveiller leurs abonnés, comme un hôtelier des vieux films policiers surveillait les entrées et sorties de ses clients. Une autre solution est de divulguer les coordonnées de tous les abonnés qui avaient une session active à ce moment là et de laisser la police trier. On imagine le nombre d'innocents qui seront alors harcelés.

À noter que la situation décrite par cette section 12 ne sera pas forcément perçue comme un problème par tout le monde. Ainsi, certains utilisateurs pourraient trouver des avantages à un système qui rend plus compliquée la tâche des surveillants. Si, à cause du partage d'adresses, une société privée de surveillance comme TMG, qui collecte les adresses IP de partageurs de fichiers, a des problèmes, tant mieux, se diront-ils. Le partage d'adresses pourrait alors fournir, sinon l'anonymat, au moins un certain brouillage de pistes. Ce n'est pas faux mais c'est à mettre en rapport avec les inconvénients de ce partage d'adresses.

Le partage d'adresses perturbe une mesure importante pour le bon fonctionnement de l'Internet, celle de la MTU du chemin (section 10). Bien des systèmes mesurent cette MTU du chemin (RFC 1191) pour optimiser le transfert de données. Mais cette PMTU est en général stockée par adresse IP et le partage généralisé peut donc fausser les mesures : deux machines derrière la même adresse IP peuvent ne pas avoir la même PMTU. Cela peut permettre des attaques par déni de service où une des machines derrière l'adresse publique générerait des paquets ICMP packet too big (type 3 et code 4 d'ICMP) indiquant une taille ridiculement basse... qui sera utilisée pour tous les malheureux situés derrière la même adresse.

Il y a d'autres questions de sécurité liées au partage d'adresses. La section 13 les expose successivement. Par exemple, bien des mesures de sécurité sont prises sur la base de l'adresse IP. Un exemple est le logiciel fail2ban qui met automatiquement en liste noire (et donc filtre) les adresses IP qui sont à l'origine de comportements agressifs (comme des connexions SSH répétées). Si cette adresse IP est partagée, des innocents vont aussi se voir bloquer l'accès. Même chose pour les listes noires des expéditeurs de spam.

Des problèmes peuvent également survenir avec des logiciels qui estiment qu'une adresse IP identifie une machine (section 14). Un des exemples est l'optimisation TCP du RFC 2140, qui consiste à partager l'information entre toutes les connexions TCP vers la même machine. Cette optimisation ne fonctionnera plus si la même adresse IP sert à des machines connectées de manière très différente (avec le NAT résidentiel d'aujourd'hui, ce n'est pas trop un problème car toutes les machines de la même maison ont à peu près la même connectivité).

Autre conséquence négative du partage d'adresses : la géolocalisation (section 7). Les adresses IP sont souvent utilisées pour donner une idée (fort imparfaite) de la localisation d'une machine. C'est un système très contestable, déjà aujourd'hui, comme le note le RFC. Mais le partage généralisé d'adresses le rendra encore moins utile, puisque c'est l'adresse du routeur CGN qui sera vue par le serveur, et qu'elle peut n'avoir qu'un très lointain rapport avec le client. Bon, personnellement, je trouve qu'on en arrive à un fort niveau de pinaillage ici : les problèmes posés par le partage d'adresses sont assez graves pour qu'on ne charge pas la barque en mentionnant des conséquences négatives sur un système qui était déjà mal fichu, comme la géolocalisation. Même remarque pour la section 8, qui fait remarquer que le partage généralisé empêchera de compter le nombre d'utilisateurs uniques en comptant le nombre d'adresses IP - ce qui est déjà largement le cas, ou la 11 qui note que le fait d'utiliser le numéro de port pour démultiplexer les paquets arrivant dans le routeur NAT pose un problème avec la fragmentation, puisque seul le premier fragment contient le numéro de port.


Téléchargez le RFC 6269


L'article seul

RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : 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 6 Juin 2011


Le protocole HTTP ne sert pas qu'à récupérer des pages HTML qu'on va afficher à l'utilisateur. Une part importante de ses usages est la récupération de fichiers qu'on enregistrera sur le stockage local. Quel nom donner au fichier local ? HTTP dispose depuis longtemps d'un en-tête dans les réponses, Content-Disposition:, qui fournissait des suggestions de noms. Cet en-tête était imparfaitement normalisé et traité un peu à part. Ce nouveau RFC en fait un élément standard et rigoureusement défini de la panoplie HTTP.

Cet en-tête était donc décrit dans les RFC 2616 (section 19.5.1, qui prend des pincettes et affirme que cet en-tête n'est décrit que parce qu'il est largement mis en œuvre mais qu'il ne fait pas vraiment partie de la norme) et RFC 2183. La description était incomplète, notamment question internationalisation.

La grammaire formelle de cet en-tête est désormais décrite en section 4. Voici un exemple :

Content-Disposition: Attachment; filename=example.txt

Cette réponse HTTP demande que le fichier soit traité comme un attachement, à enregistrer, et que le nom suggéré est example.txt. Le premier terme se nomme le type (section 4.2) et à la place du Attachment qu'on a ici, on pourrait avoir Inline qui suggère au client HTTP d'afficher le fichier, plutôt que de l'enregistrer (c'est le comportement par défaut en l'absence de l'en-tête Content-Disposition). Les types et les noms de paramètres (ci-dessous) sont insensibles à la casse.

Après le type et un point-virgule, on trouve des paramètres. Ici, le paramètre filename était indiqué, pour proposer un nom de fichier. À noter que ce paramètre peut être complété par un filename*, doté de possibilités étendues, notamment celle de suggérer des noms comportant des caractères non-Latin1 (cf. RFC 5987, section 6 et annexe C). Ce filename* est plus récent et pas compris de tous les clients HTTP. L'idée est que le serveur moderne envoie les deux, le client ancien ne gardera que filename (qui est « sûr ») et le client nouveau n'utilisera que filename*. Voici un exemple suivant ces recommandations :

     Content-Disposition: attachment;
                          filename="EURO rates";
                          filename*=utf-8''%e2%82%ac%20rates

Ce fichier sera enregistré, par un client récent, sous le nom € rates.

J'ai utilisé à plusieurs reprises des verbes comme « suggérer » ou « proposer » car le client HTTP reste maître du choix du nom. Il est même important qu'il n'accepte pas aveuglément n'importe quel nom donné par le serveur (imaginez une machine Unix où le navigateur Web stockerait le fichier sous le nom /etc/passwd sans réfléchir). Plus précisement, insiste le RFC (sections 4.3 et 7), le client HTTP doit :

  • N'autoriser l'écriture du fichier que dans les dossiers ou répertoires choisis. Le mieux est d'ignorer complètement tout chemin inclus dans le nom (ne garder que le nom de fichier proprement dit).
  • Se méfier de l'extension (dans le premier exemple, .txt). Avec certains systèmes d'exploitation comme Windows, c'est cette extension (et pas le type MIMERFC 2046 - envoyé avec le fichier) qui détermine le comportement associé au fichier. Un nom se terminant en .exe peut donc avoir des conséquences ennuyeuses.
  • Certains caractères sont spéciaux pour le système d'exploitation qui va stocker le fichier (comme le point-virgule ou le tube sur Unix) et il vaut donc mieux les supprimer avant d'enregistrer. Même chose, bien que moins dangereux, pour des noms qui pourraient perturber l'interface utilisateur, comme les espaces pour Unix : ils sont légaux mais pas pratiques à gérer depuis le shell.

Un bon exemple de faille de sécurité provoquée par le non-respect de ces règles figure en en http://securitytracker.com/id?1024583.

La section 4.4 ajoute qu'il faut ignorer les paramètres inconnus (pour permettre l'extensibilité ultérieure). Les en-têtes invalides devraient être ignorés par les clients HTTP. De nombreux détails sur le traitement de Content-Disposition: par les clients figurent dans l'excellente page http://greenbytes.de/tech/tc2231/.

Les clients HTTP, par exemple les navigateurs Web, respectent-ils cette norme ? Actuellement, Firefox, Opera et Konqueror le font, ainsi que Chrome depuis sa version 9 (parait-il : ça ne marche pas chez moi) et Internet Explorer depuis sa version 9. Cela ne signifie pas qu'ils gèrent tout et notamment Firefox 3 semble ignorer le paramètre de nom de fichier international, filename* (bogue #588781). wget semble ignorer l'indication de nom de fichier par défaut. Il faut lui ajouter l'option --content-disposition pour que cela marche. C'est encore pire pour curl dont l'auteur refuse de gérer Content-Disposition: et fait semblant de croire que l'option --remote-name le remplace. lynx a une amusante bogue : il inclus le point-virgule qui suit (s'il y a un deuxième paramètre), dans le nom de fichier.

À noter que le registre des en-têtes (section 8.2) et celui des paramètres de Content-Disposition: (section 8.1) sont utilisés par d'autres protocoles que HTTP (cf. section 4.5).

L'annexe A résume les changements par rapport au RFC 2616, le premier qui mentionnait cet en-tête Content-Disposition: dans le cadre de HTTP. Le principal est l'ajout des capacités d'internationalisation du RFC 5987. Mais il y a aussi quelques détails, comme la suppression de la restriction qui limitait cet en-tête aux ressources de type application/octet-stream. L'annexe B, elle, résume les changements depuis le RFC 2183. Ils consistent essentiellement en l'abandon de paramètres intéressants mais qui, en pratique, n'ont jamais été mis en œuvre par les clients HTTP, comme creation-date ou size.

L'annexe C discute l'approche d'internationalisation utilisée dans ce RFC, en comparant avec les alternatives. Un peu d'histoire : les en-têtes HTTP sont historiquement limités à ISO 8859-1 (RFC 2616, section 2.2 ; j'ai bien dit ISO 8859-1 et pas ASCII ; c'est ainsi que ce blog émet un en-tête en ISO 8859-1, qui a planté quelques logiciels qui n'avaient pas bien lu le RFC 2616). C'est évidemment une limite unsupportable. La solution standard, depuis belle lurette (RFC 2231, en 1997) est d'encoder les caractères Unicode en « notation pourcent ». Le RFC 5987, plusieurs fois cité ici, est l'application de ce principe à HTTP. Mais les clients HTTP, notamment les navigateurs, ont très souvent essayé des approches non-standard. Pourquoi n'ont-elles pas été reconnues dans notre RFC 6266 ?

Par exemple, certains ont implémenté les encodages du RFC 2047, même si ce RFC précisait bien qu'ils ne devaient pas être utilisés dans les en-têtes. D'autres gèrent l'encodage pourcent (RFC 3986, section 2.1) dans le paramètre filename, ce qui encourage les serveurs à l'utiliser ainsi, semant la confusion chez les navigateurs. Ainsi, si le nom de fichier est caf%C3%A9.html, certaines navigateurs l'enregistreront sous le nom café.html et d'autres sont le nom caf%C3%A9.html. Plus rigolo, certains navigateurs pratiquent l'examen du nom du fichier et appliquent diverses heuristiques pour déterminer son contenu (« Hmmm, on dirait de l'UTF-8 encodé pour-cent... Je vais essayer ça. ») C'est évidemment très fragile. Le tableau « Test Result Summary » en http://greenbytes.de/tech/tc2231/ résume fort bien le comportement actuel des navigateurs Web.

Les programmeurs, enfin, ont tout intérêt à lire l'annexe D, qui rassemble les conseils pour les développeurs de serveurs HTTP et d'applications Web (en pratique, c'est souvent le framework de développement, pas le serveur HTTP, qui génère ces en-têtes). Parmi les conseils :

  • Inclure un paramètre filename si l'ASCII suffit (ce devrait être Latin-1 mais le RFC note qu'il n'est pas prudent de compter dessus, trop de programmeurs n'ont pas lu le RFC 2616 et ne gèrent pas correctement le non-ASCII),
  • Inclure un paramètre filename* si l'ASCII ne suffit pas, tout en sachant que bien des clients Web ne le cherchent pas et n'utiliserons que filename ; le RFC suffère donc de mettre les deux, une version dégradée du nom étant présente dans filename (cela est possible en français, voir l'exemple ci-dessous, mais pas tellement en arabe),
  • Utiliser uniquement UTF-8 comme encodage de filename*.

Notez que le moteur de recherche de mon blog produit des en-têtes « Content-Disposition: » en respectant, je l'espère, les conseils de cette annexe D...


% wget --server-response 'http://www.bortzmeyer.org/search?pattern=café chocolat&format=atom' 
...
  Server: Apache/2.2.9 (Debian) mod_wsgi/2.5 Python/2.5.2
  Content-Disposition: Inline; filename=bortzmeyer-search-caf--chocolat.atom; filename*=UTF-8''bortzmeyer-search-caf%C3%A9-or-chocolat.atom
  Content-Type: application/atom+xml; charset="utf-8"
...

(Si vous lisez le code source, c'est dans wsgis/search.py.)


Téléchargez le RFC 6266


L'article seul

RFC 6265: HTTP State Management Mechanism

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : A. Barth (UC Berkeley)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF httpstate
Première rédaction de cet article le 29 Avril 2011
Dernière mise à jour le 30 Avril 2011


Les cookies, ces célèbres gâteaux du Web ont déjà fait l'objet d'innombrables articles, par exemple pour critiquer les conséquences pour la vie privée d'un mécanisme qui permet de suivre l'utilisateur à la trace (voir par exemple l'introduction de la CNIL). Mais on connait moins leur spécification technique, ou plutôt le fait que, mal spécifiés dès le début, ces gâteaux ont été mis en œuvre de diverses manières et qu'il est très difficile de décrire intégralement leur fonctionnement. C'est la tâche de notre RFC 6265, d'être, normalement, la norme technique complète et faisant autorité sur les cookies, en capturant l'ensemble des points techniques sur les gâteaux en une seule norme. Les textes précédents étaient la description originale de Netscape (on notera avec ironie que cette spécification privée n'est plus accessible que via WebArchive), puis le RFC 2109, puis le RFC 2965, que notre RFC remplace et annule. Les documents précédents étaient loin de spécifier tous les aspects des petits gâteaux.

Le point de départ est que le protocole HTTP, le plus utilisé du Web est sans état. Lors d'une visite à un site Web, l'utilisateur clique successivement sur plusieurs liens, visite plusieurs pages, et chaque téléchargement d'une page est une requête HTTP séparée des autres, sans rien qui permette de les corréler (par exemple pour se souvenir des préférences exprimées par un utilisateur lors de l'arrivée sur la première page). Les gâteaux visent à combler ce manque. La norme définit deux en-têtes HTTP, Set-Cookie qui permet au serveur HTTP de déposer un gâteau sur l'ordinateur de l'utilisateur et Cookie qui permet au client HTTP (typiquement le navigateur) de renvoyer un gâteau préalablement déposé. Lorsque le serveur reçoit le gâteau, il le compare à ceux qu'il a envoyés et reconnait ainsi un utilisateur déjà vu. HTTP devient alors un protocole avec état.

Ce n'est pas que les gâteaux soient une solution géniale : imposés par un acteur du Web particulier, Netscape, ils n'avaient pas fait l'objet d'un examen sérieux par une SDO et ont des tas d'inconvénients techniques et politiques. Néanmoins, comme ils sont largement utilisés dans le Web, il était préférable qu'une documentation sérieuse de leur syntaxe et de leur comportement existe, et c'est le rôle de ce RFC 6265.

La section 1 de ce RFC résume le principe des gâteaux. Un gâteau inclus un certain nombre de méta-données qui permettent au client HTTP de savoir si et quand il doit retransmettre le cookie. Par exemple, on peut spécifier la période pendant laquelle le gâteau reste valable, les serveurs à qui on doit le renvoyer, etc. Du fait de leur spécification hâtive et non collective, les gâteaux ont bien des faiblesses techniques. Par exemple, l'attribut secure dans les méta-données ne fournit aucune garantie d'intégrité en dépit de ce que son nom pourrait faire croire. D'autre part, les gâteaux ne sont pas spécifiques à un port donné donc, si plusieurs serveurs tournent sur des ports différents de la même machine, ils peuvent se voler leurs gâteaux mutuellement. Mais, d'une manière générale, ce RFC n'essaie pas de réparer la situation, mais de documenter les gâteaux tels qu'ils sont réellement produits et consommés sur le Web.

Bien, assez râlé, qui doit lire ce RFC ? Il y a deux audiences, les développeurs d'applications côté serveurs (ou, plus exactement, des bibliothèques qui sont utilisées par ces applications) qui produisent et consomment des gâteaux, et les développeurs des logiciels clients, notamment les navigateurs Web. Pour maximiser les chances d'interopérabilité, les serveurs devraient se montrer très prudents et ne produire que des gâteaux parfaitement conformes à la norme (section 4 du RFC, qui décrit le profil restreint), alors que les clients doivent être plus tolérants et accepter la grande variété des gâteaux actuellement fabriqués (section 5, sur le profil libéral), car tous les serveurs ne suivent pas le profil restreint.

Avant de lire le gros du RFC, un petit détour par la norme HTTP, le RFC 2616, peut être utile, puisque notre RFC en reprend le vocabulaire.

La section 3 décrit les généralités sur les gâteaux. Ceux-si sont envoyés par un en-tête Set-Cookie dans la réponse HTTP, puis retournés dans un en-tête Cookie dans la requête suivante. L'état est donc stocké chez le client mais, en pratique, la taille des gâteaux étant limité, le serveur stocke l'essentiel de l'état et le gâteau ne sert que d'index pour retrouver une session particulière. Un serveur peut utiliser Set-Cookie dans n'importe quelle réponse (y compris les erreurs comme 404) et le client doit le gérer (sauf pour les réponses de type 1xx, qui sont seulement « pour information »). Plusieurs gâteaux peuvent être envoyés, chacun dans un en-tête Set-Cookie différent (le client, lui, peut utiliser un seul en-tête Cookie pour envoyer plusieurs gâteaux). Un exemple classique est l'envoi d'un identificateur de session (ici, SID, pour Session ID). Le serveur envoie :

Set-Cookie: SID=31d4d96e407aad42

et à la requête suivante, le client renverra :

Cookie: SID=31d4d96e407aad42

Le serveur peut réduire la portée du gâteau avec les attributs Path et Domain. Ici, par exemple, le gâteau doit être renvoyé pour tous les URL dans example.com :

Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com

Ici, un serveur prudent utilise en plus les attributs Secure et HttpOnly. En outre, il envoie deux gâteaux, SID et lang (chacun étant un doublet nom-valeur) :

Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly
Set-Cookie: lang=en-US; Path=/; Domain=example.com

Le client peut les renvoyer en un seul en-tête :

Cookie: SID=31d4d96e407aad42; lang=en-US

Ici, le serveur fixe une date d'expiration au gâteau :

Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT

Après ces exemples tirés du RFC, voici maintenant un exemple réel entre un site Web écrit en PHP et un navigateur. Le trafic a été capturé et formaté avec tshark :

# Le serveur envoie :
Set-Cookie: PHPSESSID=euk3daoldp4s3j90uocetas3a0; path=/\r\n

# Le client répond (d'autres gâteaux avaient été transmis) :
Cookie: __utma=85646793.1868252067.1190397623.1190397623.1190397623.1; \
     PHPSESSID=euk3daoldp4s3j90uocetas3a0; \
     culture=fr\r\n

Autre façon de voir les gâteaux, se servir du client en ligne de commande curl :

% curl -v http://twitter.com/ > /dev/null
...
< Set-Cookie: guest_id=130393513906128799; path=/; expires=Fri, 27 May 2011 20:12:19 GMT
< Set-Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCPc8l5gvAToHaWQiJWY3NTg3YTU1YTgwOWE2%250AODcxMTA5M2NiNzNiOWMxODRmIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--dd45d4b08ccac6e6f832ccb70af983e16a12df43; domain=.twitter.com; path=/; HttpOnly

curl permet même de renvoyer ces gâteaux au serveur :

% curl --cookie _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCPc8l5gvAToHaWQiJWY3NTg3YTU1YTgwOWE2%250AODcxMTA5M2NiNzNiOWMxODRmIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--dd45d4b08ccac6e6f832ccb70af983e16a12df43\;guest_id=130393513906128799 -v http://twitter.com/ > /dev/null     
...
> Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCPc8l5gvAToHaWQiJWY3NTg3YTU1YTgwOWE2%250AODcxMTA5M2NiNzNiOWMxODRmIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--dd45d4b08ccac6e6f832ccb70af983e16a12df43;guest_id=130393513906128799
...

La section 4 définit rigoureusement les obligations d'un serveur sérieux, qui ne cherche pas à exploiter les possibilités de la norme à fond et qui veut être sûr que tous les clients pourront traiter correctement ses gâteaux. Sa section 4.1.1 définit la syntaxe formelle à suivre, en ABNF. Les valeurs qui ne sont pas réduites à un strict sous-ensemble de caractères sûrs, pour maximiser les chances d'être transmises sans accident, sont encodées en Base64. Les dates s'expriment avec le format du RFC 1123 (mais certains serveurs non compatibles avec ce profil envoient des dates sur deux chiffres...). Certains clients stockent les dates dans un entier de seulement 32 bits donc il est possible que les choses se passent mal à partir de 2038.

Le serveur peut ajouter des attributs aux gâteaux. Ainsi, l'attribut Expires (section 4.1.2.1) permet de spécifier la date limite de consommation du gâteau (« À consommer avant le 29 avril 2011 ») et l'attribut Max-Age indique la durée de vie maximale (le RFC prévient que Max-Age est moins souvent mis en œuvre que Expires par les clients HTTP). Le gâteau peut durer moins longtemps que cela, par exemple parce que le navigateur Web a décidé de faire de la place, ou bien parce que l'utilisateur l'a détruit explicitement (chose que permettent tous les bons navigateurs, vues les conséquences négatives des gâteaux pour la vie privée).

Important pour la sécurité, l'attribut Domain permet d'indiquer le domaine des serveurs à qui le client doit renvoyer le gâteau. Attention, les sous-domaines de ce domaine sont également acceptés. Si le serveur envoie Domain=example.org lors du Set-Cookie, le client renverra le gâteau à, par exemple, www.example.org et mail.example.org. (Et si un serveur distrait met un gâteau avec Domain=com ? Il sera renvoyé à tous les domains en .com ? Cela dépend du navigateur ; beaucoup ignorent cet attribut Domain s'il correspond à un domaine d'enregistrement comme .fr ou .co.uk mais il n'existe pas de moyen officiel d'en connaître la liste donc ces navigateurs dépendent de listes incomplètes comme http://publicsuffix.org. Voir la section 5.3 pour une discussion complète. À noter que Konqueror utilise une méthode encore pire qui n'a jamais été corrigée.)

Le serveur peut restreindre encore plus l'utilisation du gâteau qu'il envoie avec l'attribut Path (section 4.1.2.4). Celui-ci indique quelle section du site Web a besoin du gâteau. Si on met Path=/accounting et que le domaine est www.example.com, seuls les URL commençant par http://www.example.com/accounting recevront le gâteau.

Enfin, deux autres attributs permettent d'améliorer la (faible) sécurité des gâteaux, Secure, qui impose au client de ne renvoyer le gâteau qu'au dessus d'une connexion « sûre » (typiquement HTTPS, pour éviter les attaques par FireSheep) et HttpOnly qui restreint le gâteau à ce protocole.

Une fois que le serveur a créé le gâteau et l'a envoyé avec les attributs qu'il juge utile, il doit être prêt à recevoir des gâteaux retransmis par le client. La section 4.2 décrit l'en-tête Cookie des requêtes HTTP, qui sert à cela. (Voir les exemples plus haut.)

La section 4 décrivait un profil réduit des gâteaux. Un client HTTP sérieux qui veut pouvoir comprendre tous les serveurs existants dans la nature, y compris ceux qui ne s'en tiennent pas à ce profil réduit, doit, lui, lire la section 5, qui décrit l'intégralité du très compliqué comportement des gâteaux. Cette section reprend le plan de la 4, en détaillant toutes les horreurs qu'on peut rencontrer dans le monde réel.

Par exemple, le format des dates (section 5.1.1), utilisées dans des attributs comme Expires, permet à peu près toutes les variations possibles. Écrire un analyseur complet n'est pas trivial, d'autant plus que le RFC ne décrit pas une grammaire indépendante du contexte mais un algorithme à état. (Si un pro de l'analyse syntaxique peut fournir une grammaire plus déclarative de cette syntaxe, je serais intéressé...)

De même, l'analyse du Set-Cookie en section 5 est plus complexe car le client doit accepter des Set-Cookie plus variés, par exemple avec des espaces en plus.

La section 5.3, qui n'a pas d'équivalent dans la section 4, décrit la façon dont les clients, les navigateurs Web, doivent stocker les gâteaux et les renvoyer. Elle rappelle la liste des attributs à stocker avec chaque gâteau (par exemple, s'il doit être renvoyé uniquement sur une connexion sécurisée ou bien si ce n'est pas nécessaire). Elle est très longue et le pauvre auteur de navigateur Web a donc bien du travail.

En parlant du programmeur, justement, la section 6 décrit les questions que pose l'implémentation de cette spécification. Parmi elles, la question de la taille du magasin où sont stockés les gâteaux. Le client Web n'est nullement obligé de fournir un magasin de taille infinie. Néanmoins, le RFC demande que le client accepte au moins quatre kilo-octets par gâteau, cinquante gâteaux par domaine et trois mille gâteaux en tout (ce qui permet déjà une belle indigestion). Conséquence de cette limite : un serveur doit s'attendre à ce qu'un client ne renvoie pas tous les gâteaux prévus. Certains ont pu être abandonnés par manque de place.

On l'a vu, la section 5, qui normalise le comportement du client, est très complexe. La section 4 l'est moins mais l'expérience a largement prouvé que les serveurs émettant des gâteaux avaient du mal à se tenir à un profil strict, et produisaient trop de variations. Une des raisons identifiées par la section 6.2 est le manque d'API. La plupart du temps, les applications font directement un printf "Set-Cookie: foobar=1234567; Expires=Wed, 06 Jun 2012 10:18:14 GMT\n" (ou équivalent) au lieu d'appeler une API plus abstraite dont l'implémentation se chargera de sérialiser proprement les objets complexes comme la date. Avec tant de liberté laissée au programmeur, il n'est pas étonnant qu'il y ait des variations non-standard.

Si le RFC ne propose pas de solution, il insiste sur l'importance pour les programmeurs d'utiliser des bibliothèques bien déboguées et de ne pas se croire capable d'écrire un Set-Cookie correct après cinq minutes de lecture de la norme. Un exemple d'une telle bibliothèque est, en Python, le couple cookielib et le module Cookie (qui assurent deux fonctions indépendantes). Leur documentation n'est pas évidente (si quelqu'un connait un bon tutoriel...) mais, d'encore plus haut niveau, dans le même langage, urllib2 gère les gâteaux toute seule.

Comme le respect de la vie privée est le principal problème des gâteaux, il est normal que cette question ait une section entière, la 7, qui détaille ce point. C'est inhabituel à l'IETF, où la vie privée ne génère en général que peu d'intérêt. Peu de RFC ont une section Privacy considerations. Que dit-elle ? Que les gâteaux sont effectivement une technologie sensible (bien qu'il existe d'autres moyens de suivre un utilisateur mais moins pratiques donc moins dangereux) et que les plus problématiques sont les gâteaux envoyés à un tiers (c'est-à-dire à une autre organisation que celle qui gère visiblement la page, par le biais d'une discrète image insérée, par exemple). Par exemple, un service de statistiques utilisé sur de nombreux sites Web, ou bien un service de placement de publicités, peuvent permettre à leur gérant de croiser les visites faites sur plusieurs sites différents et ceci sans que l'utilisateur n'ait fait de visite explicite aux services de cette indiscrète organisation. Certains navigateurs sont, à juste titre, davantage paranoïaques lorsque le gâteau est envoyé par un tiers, par exemple en les refusant par défaut. D'autres ne traitent pas ces gâteaux différemment des autres. La question étant essentiellement politique, notre RFC 6265 ne définit pas de comportement normalisé, se contentant d'attirer l'attention sur ce point.

Peut-on demander son avis à l'utilisateur ? C'est ce qu'expose la section 7.2, consacrée au contrôle par l'utilisateur. Le RFC recommande que les clients Web fournissent des mécanismes de contrôle des gâteaux permettant de :

  • Gérer les gâteaux stockés dans la magasin local, par exemple examiner les gâteaux en place, détruire tous ceux d'un certain domaine (voici comment faire dans Firefox), etc,
  • Refuser systématiquement les gâteaux,
  • Proposer à l'utilisateur de refuser ou d'accepter chaque gâteau reçu, même si cela nécessite un peu plus de travail lors de la navigation (mais cela a l'avantage de faire prendre conscience de la quantité de gâteaux mis par des tiers, sur des pages Web qui semblaient pourtant innocentes ; cette option existait dans Firefox mais semble avoir disparu du panneau de contrôle des dernières versions de Firefox 3 ; on peut toujurs la régler « à la main » dans about:config network.cookie.lifetimePolicy=1),
  • Traiter les gâteaux comme temporaires (et donc les détruire lorsqu'on quitte le programme), une option parfois nommée safe browsing (cf. « An Analysis of Private Browsing Modes in Modern Browsers ») ; dans Firefox, elle peut se configurer dans Privacy ; History ; Use custom setting for history.

Voici la liste des gâteaux stockés, telle que Firefox permet de l'examiner et de la modifier : Et la question que pose le même Firefox lorsqu'on l'a configuré avec about:config network.cookie.lifetimePolicy=1 : Et le dialogue de configuration dans Firefox 4, montrant l'option qui permet de demander à chaque gâteau si on l'accepte : À noter qu'il existe bien d'autres moyens de configurer la politique des gâteaux, si le navigateur ne fait pas ce qu'on veut, par exemple des extensions comme Cookie Monster, WebDeveloper (qui permet de voir tous les gâteaux de la page en cours, avec pour chacun « Éditer » ou « Supprimer ») ou Ghostery pour Firefox. Le navigateur Dillo, quant à lui, à un mécanisme très détaillé.

Même en dehors du cas de la vie privée, les gâteaux posent un certain nombre de problèmes de sécurité (section 8). L'utilisation de HTTPS, quoique évidemment souhaitable, ne protège pas complètement contre ces vulnérabilités.

Premier problème, l'autorité diffuse (ambient authority, section 8.2). Le gâteau utilisé pour l'authentification sépare la désignation (l'URL) de l'autorisation. Le client risque donc d'envoyer le gâteau pour une ressource Web qui était contrôlée par un attaquant, une technique connue sous le nom de CSRF (il existe plusieurs moyens de convaincre un navigateur de se prêter à cette attaque, une étude bien plus détaillée des CSRF, qui a parmi ses auteurs l'auteur de ce RFC, est « Robust Defenses for Cross-Site Request Forgery »). Une solution à ce problème serait de traiter les URL comme une capacité, donnant accès à une ressource. L'URL serait alors le secret à transmettre pour avoir accès (le RFC ne note malheureusement pas que les URL ne restent pas secrets longtemps, par exemple certains navigateurs ou extensions des navigateurs - la Google Toolbar - transmettent les URL consultés à leur maître).

Autre problème des gâteaux, leur envoi en texte clair (section 8.3). Si on n'utilise pas HTTPS, Set-Cookie et Cookie sont transmis en clair avec leur contenu, permettant à un espion de les copier et de les utiliser (c'est cette vulnérabilité qu'exploite un programme comme FireSheep). En outre, un attaquant actif peut modifier ces en-têtes. La solution recommandée est évidemment de chiffrer toute la session, et de mettre l'attribut Secure aux gâteaux envoyés, pour éviter qu'ils ne soient plus tard transmis sur une session non chiffrée. Beaucoup de gros services très populaires ne sont pas accessibles en HTTPS ou bien ne le mettent pas en œuvre par défaut (souvent pour des raisons de performance, facteur crucial pour ces services qui reçoivent beaucoup de visites). Dans le cas de Gmail, c'est l'option « Général : Connexion du navigateur ; Toujours utiliser le protocole https ». Dans celui de Twitter, c'est « Toujours utiliser le HTTPS ». L'EFF mène une campagne pour systématiser cette protection. À noter qu'on peut limiter (mais pas supprimer) la réutilisation du gâteau en liant celui-ci à l'adresse IP du client ; si le gâteau vient d'une autre adresse, il sera refusé. Cette méthode n'est pas si efficace qu'elle en a l'air en raison de la fréquence du partage d'adresses IP (via le NAT). Ainsi, dans un café avec WiFi, un attaquant qui utilise FireSheep n'aura pas de problèmes malgré cette protection car tous les clients sont probablement derrière la même adresse IPv4 (c'est sans doute pour cela que le RFC ne propose pas cette solution).

C'est encore pire si le gâteau contient directement de l'information utile. Par exemple, si le gâteau est lang=en-AU, l'espion qui écoute peut trouver la langue et le pays de l'utilisateur. En général, cette information est plutôt stockée sur le serveur et le gâteau ne contient qu'un identificateur de session, inutile si on n'a pas accès au serveur. Mais cette technique présente d'autres risques (section 8.4), par exemple celui du « choix de session » où l'attaquant se connecte au serveur, puis convainct la victime (par exemple par le biais d'un lien) d'utiliser l'identificateur de session et d'interagir avec le serveur (par exemple en y déposant des informations confidentielles). L'attaquant, qui a conservé l'identificateur de session, pourra alors continuer la session et récupérer ces informations. (Voir un exemple et un article complet.)

Autre problème de sécurité des gâteaux, la confidentialité (section 8.5) : comme les gâteaux ne sont pas spécifiques d'un port ou d'un plan (http, gopher, ftp, etc), un client risque toujours de transmettre les gâteaux d'un serveur à un autre. L'intégrité n'est pas non plus garantie (section 8.6). Si bar.example.com a mis un gâteau de domain de example.com, un autre serveur, foo.example.com peut parfaitement le remplacer. Path n'est pas une protection : il n'empêche pas le remplacement.

Enfin, les gâteaux dépendent du DNS et en héritent les vulnérabilités (section 8.7).

Une très bonne synthèse des failles de sécurité des gâteaux figure dans l'excellent article « HTTP cookies, or how not to design protocols ».

Voilà, c'est tout, il reste à enregistrer les deux en-têtes dans le registre des en-têtes, ce que fait la section 9.

Contrairement aux autres RFC qui remplacent un autre RFC, ce RFC 6265 ne contient pas de description des changements par rapport aux précédents documents. Les clarifications et précisions sont sans doute trop nombreuses pour former une liste intéressante.

Merci à Jean-Baptiste Favre, bohwaz et Ollivier Robert pour leurs remarques et suggestions.


Téléchargez le RFC 6265


L'article seul

RFC 6264: An Incremental Carrier-Grade NAT (CGN) for IPv6 Transition

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : S. Jiang, D. Guo (Huawei), B. Carpenter (University of Auckland)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 14 Juin 2011


Verra-t-on un jour la fin des RFC sur les plans de transition d'IPv4 vers IPv6 ? Sans doute pas tant que la transition traîne. En effet, la lenteur imprévue du déploiement d'IPv6 remet en cause les plans initiaux (qui reposaient sur l'idée qu'il resterait des adresses IPv4 pendant toute la phase de transition) et nécessite le développement de nouveaux plans, pour répondre à une situation différente.

Le plan présenté ici est une variante des plans reposant sur l'idée de CGN (Carrier-Grade NAT), ces routeurs NAT installés, non pas dans la box de M. Michu, pour son usage et celui de sa famille, mais installés chez le FAI, pour l'usage partagé de plusieurs clients du FAI. Le CGN a l'avantage de nécessiter zéro logiciel ou configuration chez l'utilisateur (qui n'a probablement pas le temps et l'envie de maîtriser ces mécanismes). Ces solutions reposant uniquement sur le travail du FAI sont donc tentantes pour répondre au problème de la trop lente migration chez les utilisateurs. (Toutefois, mon impression personnelle est que beaucoup de réseaux de M. Michu, plein de gadgets récents, sont plus avancés vers IPv6 que pas mal de réseaux de FAI, conçus il y a des années.)

La nouveauté par rapport aux autres plans reposant sur le CGN est l'introduction de mécanismes pour éviter que ce CGN ne se transforme en impasse, et pour le faire évoluer vers de l'IPv6 natif complet. En effet, dans la plupart des cas, le terme de CGN fait penser à un mécanisme pour retarder la transition, le NAT444, qui permet au FAI paresseux de continuer à utiliser IPv4 même alors qu'il ne peut plus distribuer ne serait-ce qu'une seule adresse IPv4 publique à ses clients. Ce CGN-là ne fait pas progresser vers IPv6 (section 1 du RFC).

D'où cette idée de proposer un plan de migration reposant sur le CGN mais prévoyant dès le début les moyens d'en sortir. Ce RFC ne contient pas de nouveaux protocoles, il ne fait que combiner les protocoles existants.

Dans un certain nombre de FAI, la situation est actuellement la suivante (section 2) :

  • Plus d'adresses IPv4 publiques,
  • Un réseau interne purement IPv4, par manque de proactivité du FAI (qui aurait dû déployer IPv6 depuis longtemps), et qu'on ne peut pas migrer en cinq minutes,
  • La prise de conscience qu'IPv6 est nécessaire, et à relativement court terme.

Dans d'autre cas, FAI ayant fait son travail à l'avance et ayant déployé IPv6 depuis longtemps, ou bien FAI tout récent et préférant l'approche radicale de déployer un réseau purement IPv6, avec NAT64 (RFC 6144, et section 2.6 de notre RFC) pour assurer la liaison avec le vieux protocole, ces hypothèses ne sont plus vraies et l'approche de ce RFC ne s'applique donc pas. Comme toujours avec la transition vers IPv6, il faut analyser son réseau et déterminer la ou les meilleures stratégies de transition : chacune s'applique à un cas bien particulier.

Le dessin n° 1 en section 2.1 résume bien l'approche « CGN progressif » (Incremental Carrier-Grade NAT). En partant de chez M. Michu (ou plutôt M. Li car le cas décrit est plus proche de ce que vivent les FAI asiatiques), on a :

  • Les machines de M. Li, certaines en IPv6 mais pas toutes,
  • Un nouveau composant, le HG (Home Gateway), une box capable d'assurer certaines fonctions comme de tunneler le trafic IPv6 vers le routeur NAT situé plus loin dans le réseau du FAI,
  • Le tunnel IPv6-sur-IPv4 qui commence à la HG et se termine au routeur CGN,
  • Le réseau purement IPv4 du FAI,
  • Le CGN, une très grosse boîte,
  • Des serveurs restés purement v4 sur le réseau du FAI (serveur Web du portail, par exemple),
  • L'accès à l'Internet, en IPv4 et en IPv6.

Les deux composants nouveaux, que n'a pas forcément le FAI aujourd'hui, sont le HG et le CGN. Le HG doit obéir au RFC 6204. Autrement, tous les équipements (routeurs classiques et machines terminales) ne changent pas (cf. section 2.5).

Quelle technique de tunnel choisir entre le HG et le CGN ? La section 2.2 rappelle les possibilités. Les tunnels configurés manuellement du RFC 4213 paraissent peu pratiques. Ceux du RFC 3053 peuvent ne pas être très utilisables par l'utilisateur résidentiel. Cela laisse 6rd (RFC 5969) et peut-être GRE (RFC 2784). Si le FAI a déjà une infrastructure MPLS, il peut aussi considérer RFC 4798, mais cela suppose que MPLS aille jusqu'au HG, ce qui est peu probable. Bref, le RFC recommande 6rd.

La section 2.3 peut alors décrire en détail le fonctionnement de la HG (Home Gateway, la box). Lorsqu'elle reçoit un paquet de l'intérieur :

  • Si c'est un paquet IPv4, elle le fait suivre sur l'infrastructure v4 normale du FAI (peut-être après traduction), jusqu'au CGN qui fera alors une traduction v4-v4 (il aura donc pu y avoir deux traductions),
  • Si c'est un paquet IPv6, elle l'encapsule pour l'envoyer, via le tunnel, jusqu'au CGN (le gros routeur/traducteur situé plus loin dans l'infrastructure du FAI).

Et le CGN (Carrier-Grade NAT, un routeur NAT qui sert plusieurs clients) ? La section 2.4 lui est consacrée. Lorsqu'il reçoit un paquet IPv4 venu d'une HG (rappelons que tout ce RFC est consacré au cas où l'infrastructure du FAI est purement IPv4), deux cas :

  • C'est un paquet v4 normal, et on le transmet après traduction (puisque le FAI n'a pas assez d'adresses IPv4 publiques, le paquet a certainement une adresse source privée) ; comme tout routeur NAT, le CGN mémorise la correspondance port<->adresse,
  • C'est un paquet IPv6 encapsulé dans du v4. Le CGN le décapsule, et le transmet.

Voilà, sur le papier, c'est tout simple. Quelles sont les conséquences pratiques ? La section 2.7 discute divers points. D'abord, comme toute solution à base de NAT, notre schéma a tous les inconvénients du partage d'adresses. Pire, comme le CGN est situé loin de l'utilisateur, et que celui-ci ne peut pas le configurer, des techniques permettant d'avoir des connexions entrantes comme les correspondances statiques ou comme UPnP ne fonctionnent plus. D'autre part, le tunnel v6-sur-v4 entre le HG et le CGN posera les habituels problèmes de MTU (dont le RFC se débarasse avec une pirouette).

L'originalité de l'approche de ce RFC est la possibilité de migrer de cette solution NAT complexe et fragile vers une solution IPv6 propre. Comment ? C'est ce que décrit la section 3, qui prévoit plusieurs étapes, en supposant :

  • On installe un CGN pour faire du NAT444. À court terme, cela réduit la demande en adresses IPv4 publiques. Mais cela n'aide pas en soi à migrer vers IPv6. Le HG doit être mis à jour pour utiliser le CGN.
  • On déploie 6rd (nouvelle mise à jour du logiciel du CGN),
  • On déploie alors tranquillement IPv6 sur le réseau du FAI. Dès que la zone desservie a un routage IPv6, on peut couper 6rd dans le HG, supprimant ainsi le tunnel v6-sur-v4 (IPv4 continuant à être envoyé au CGN). Cette coupure du tunnel peut se faire automatiquement, si le HG a été programmé pour détecter les RA (Router Advertisment) ou réponses DHCP IPv6.
  • Cette dernière possibilité suppose une forme de double-pile (v4 et v6) sur le réseau du FAI pendant un temps. Si celui-ci préfère n'avoir qu'un seul protocole à gérer, l'approche est au contraire de basculer du routage purement v4 du début à un routage purement v6. C'est alors IPv4 qui sera tunnelé, via DS-Lite. Le FAI sera alors arrivé jusqu'au bout, il sera purement IPv6.

Comme indiqué, le passage d'une étape à une autre peut être détecté automatiquement par le HG, la box, qui peut par exemple interroger le CGN pour noter les nouvelles fonctions disponibles. Cela éviterait une action explicite sur la HG.

Il reste à étudier les conséquences de ce schéma en terme de sécurité (section 4). Le NAT en général pose de nombreux problèmes de sécurité (RFC 2663 et RFC 2993). Le partage massif d'adresses, par exemple dans un CGN, crée des failles expliquées dans le projet de RFC draft-ietf-intarea-shared-addressing-issues. Les protocoles spécifiques utilisés ont également leurs propres questions de sécurité, documentées dans leur norme respective (par exemple, pour 6rd, dans la section 12 du RFC 5969).

Toutefois, le fait que ce schéma concerne uniquement des mécanismes utilisés à l'intérieur du réseau d'un FAI, la sécurité est simplifiée. On peut certes sécuriser les tunnels avec le RFC 4891 mais ce n'est peut-être pas nécessaire, à l'intérieur d'un réseau unique et géré.

Par construction, il n'y a pas d'implémentation complète de ce RFC, mais des implémentations de certaines des fonctions. Par exemple, DS-Lite est mis en œuvre dans AFTR.


Téléchargez le RFC 6264


L'article seul

RFC 6256: Using Self-Delimiting Numeric Values in Protocols

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : W. Eddy (MTI Systems), E. Davies (Folly Consulting)
Pour information
Première rédaction de cet article le 26 Mai 2011


Comment encoder des valeurs dans un protocole ? Il existe des tas de méthodes mais celle de ce RFC 6256, les « valeurs numériques auto-terminées » (SDNV pour Self-Delimiting Numeric Values) sont encore très peu connues et guère utilisées.

Soit un concepteur de protocoles réseau. Il doit indiquer dans les données qui circulent des valeurs, par exemple un gâteau qui identifie une session ou bien une durée ou une longueur ou bien une clé cryptographique ou des tas de choses encore. Comment transmettre ces valeurs (section 1.1) ? Une technique courante, très utilisée dans les protocoles « binaires » comme IP (RFC 791) ou bien le DNS (RFC 1035) est le champ de taille fixe. On décide que la longueur sera représentée sur 16 bits et les producteurs et les lecteurs de ce champ connaissent cette taille, qu'ils ont lu dans le RFC correspondant. Plus la taille est grande, plus on consomme de ressources réseaux pour la transmettre mais, plus elle est petite, et moins on pourra représenter de valeurs. Dans mon exemple, que fera t-on si les changements dans les techniques ou dans les usages nécessitent de stocker des longueurs supérieurs à 65 536 ? Le problème est fréquent car des protocoles sont souvent utilisés pour des dizaines d'années consécutives, années pendant lesquelles les hypothèses de base ont changé. Le RFC cite ainsi les exemples de la fenêtre TCP (RFC 793, la fenêtre est limitée à 16 bits, soit 65 kilo-octets, ce qui est bien trop peu pour les réseaux à 10 Gb/s d'aujourd'hui, et a nécessité le hack de l'échelle de fenêtre du RFC 1323) et du bien connu champ Adresse d'IPv4, qui s'est montré trop petit. Le RFC note bien que les deux décisions avaient semblé raisonnables à l'époque : sur une ligne spécialisé à 64 kb/s, la fenêtre maximale était de huit secondes, ce qui donnait largement aux accusés de réception le temps de revenir. Aujourd'hui, la même taille ne laisse que 50 microsecondes... Même problème pour les adresses IPv4, épuisées par le changement du modèle de l'ordinateur (de « un par entreprise » à « plusieurs par personnes ») et par le succès inespéré de l'Internet. Les SDNV permettent donc d'éviter de prendre des décisions (« 16 bits ? 32 bits ? Allons-y pour 16 bits, ça suffira bien. ») qu'on regrettera ensuite.

Une autre approche, commune à l'IETF, est d'utiliser TLV. C'est le mécanisme le plus souple, mais, pour des valeurs assez petites, il prend plus de place que SDNV.

Le groupe de recherche IRTF DTNRG, qui est occupé notamment à développer des protocoles réseau pour les vaisseaux spatiaux (cf. RFC 4838) a son idée sur la question (la section 4 présente une discussion des alternatives), et cela a donné ce RFC. Par exemple, dans l'espace, vu le RTT, les protocoles qui négocient des paramètres au début de la connexion (comme l'échelle de fenêtre TCP), et qui permettent ainsi d'avoir des champs de taille fixe et de choisir la taille au début de la connexion, ne sont pas envisageables. Mais le problème n'est pas spécifique aux réseaux « DTN » (Delay-Tolerant Networking, les réseaux où l'acheminement d'un bit prend un temps fou, ce qui est le cas dans l'espace où la vitesse de la lumière est une limite gênante, cf. RFC 5325) et on peut retrouver des ancêtres de SDNV dans des encodages ASN.1 ou bien dans certains protocoles UIT. Par contre, en dehors du projet DTN, il ne semble pas que les SDNV aient été utilisés par des protocoles IETF, peut-être parce que leur encodage et décodage est plus lent qu'avec des champs de taille fixe (le protocole WebSocket utilise les SDNV). À noter que notre RFC n'est pas la premier à normaliser SDNV, ceux-ci avaient déjà été décrits dans les RFC 5050 et RFC 5326 mais de manière sommaire. Un description plus complète n'était donc pas du luxe.

SDNV se limite à représenter des entiers positifs ou des chaînes de bits. Pour des types plus complexes, on peut utiliser les encodages d'ASN.1 ou bien MSDTP (décrit dans le RFC 713).

Après ces préliminaires, attaquons-nous à la définition d'un SDNV (section 2). Un SDNV est encodé sous forme d'une série d'octets en n'utilisant que sept bits de chaque octet. Le huitième indique si l'octet est le dernier du SDNV. Ce mécanisme impose un décodage strictement séquentiel, en examinant un octet après l'autre. Quelques exemples :

  • Le nombre 3 est représenté par 00000011. Le premier bit, ici à zéro, indique que ce premier octet est aussi le dernier.
  • Le nombre 130 est représenté par 1000001 00000010. Le premier bit du premier octet indique que cet octet n'est pas le dernier. Le dernier bit du premier octet est celui qui code 128. (On ne peut pas utiliser le premier bit du deuxième octet, réservé pour indiquer la fin de la série des octets.)

L'annexe A contient d'autres exemples et j'en montre certains à la fin de cet article. Il y a quelques détails pratiques comme les zéros initiaux : le premier nombre est-il 3 où 03 ? Le RFC explique que les zéros initiaux ne sont pas significatifs. Pour les nombres, cela ne change évidemment rien (3 = 03) mais si on voulait représenter des chaînes de bits, c'est plus compliqué et SDNV ne fournit pas de solution satisfaisante (le RFC suggère par exemple d'indiquer explicitement la longueur dans un autre champ, ce qui annule l'intérêt de SDNV ; une autre suggestion est de toujours mettre un bit à 1 au début de toute chaîne).

Les SDNV ont parfois été décrits sous le nom de Variable Byte Encoding (cf. le livre de Manning, Raghavan, et Schuetze, « Introduction to Information Retrieval », qui s'intéressait toutefois à la compression plutôt qu'à la souplesse). On peut remarquer qu'aucune valeur encodée en SDNV n'est un préfixe d'une valeur encodée en SDNV (SDNV est prefix-free, autre façon de dire que les données sont auto-terminées).

Comment encode et décode-t-on ces SDNV ? La section 3 décrit quelques algorithmes qui peuvent être utilisés à cette fin. La section 3.1 contient un algorithme d'encodage très simple en O(log(N)) où N est le nombre à encoder. Le décodage est plus sioux : on ne connait en effet pas la valeur du nombre avant de l'avoir décodé et on ne sait donc pas quel type on doit utiliser pour stocker le résultat. Même un type de grande taille, genre uint64_t peut être trop petit. La section 3.2 propose un algorithme de décodage récursif, qui évalue à chaque étape si le résultat est de taille suffisante et alloue une autre variable si nécessaire.

Cette histoire de taille de la variable qui stocke le résultat est un des problèmes pénibles de SDNV. On ne peut pas exiger de chaque implémentation qu'elle mette en œuvre un système d'entiers infinis (le RFC cite GNU MP comme exemple). La section 3.3 propose que chaque protocole qui utilise des SDNV fixe une taille maximale aux entiers stockés (retombant ainsi partiellement dans les problèmes des champs de taille fixe). Ainsi, le protocole Bundle (RFC 5050) fixe cette limite à la valeur maximale pouvant être représentée avec 64 bits. Le décodeur peut donc utiliser un uint64_t sans crainte.

Voilà, les SDNV sont donc très simples dans leur principe. Mais quels sont leurs avantages et leurs inconvénients ? La section 4 discute des alternatives : SDNV actuels, TLV, et l'ancien système de SDNV qui avait été utilisé dans des versions antérieures de certains protocoles DTN. En gros, le système le plus souple est TLV mais c'est aussi le moins efficace, en place et en temps. Un avantage de TLV est que, via le champ Type, la sémantique est connue, alors que les SDNV ne sont que des entiers non typés. Autre avantage : la taille du résultat est connue tout de suite et l'allocation mémoire pour le résultat tombe donc toujours juste (l'ancien SDNV avait un système analogue). Mais l'un des problèmes des TLV est que la représentation des champs Type et Longueur. S'ils sont de taille fixe, les TLV héritent certains des problèmes des champs de taille fixe. Notons qu'on peut combiner les techniques, par exemple utiliser SDNV pour le champ Longueur d'un TLV.

Bien que le RFC n'en discute guère, je me permets d'ajouter ici une comparaison essentiellement personnelle entre champs de taille fixe et SDNV. Les champs de taille fixe :

  • Sont bien plus faciles à encoder/décoder, dans un langage comme C, c'est même trivial. Ce n'est pas seulement un avantage pour le programmeur, c'est aussi une garantie de rapidité.
  • Ont pour principal inconvénient le fait qu'une mauvaise estimation de la taille nécessaire n'est pas corrigeable a posteriori (cas des fenêtres TCP et des adresses IPv4 cités plus haut). Si la capacité du réseau est grande (ce qui n'est typiquement pas le cas dans l'espace), une solution possible est de gaspiller, en utilisant systématiquement des champs très grands, genre 128 bits.
  • Ont une taille connue à l'avance (par définition), ce qui permet au programmeur de réserver la bonne taille (cf. section 3.3)
  • Sont très sensibles aux erreurs de transmission car les modifications sont indécelables. Au contraire, la modification d'un bit dans un SDNV peut entraîner une erreur de format, qui sera détecté au décodage.

Bref, je trouve personnellement que l'utilisation fréquente de champs de taille fixe dans les protocoles Internet n'est pas due au hasard.

Reparlons de décodage avec la question de la sécurité (section 5). Un décodeur SDNV doit faire attention aux valeurs qui dépassent ses limites, non seulement pour ne pas planter, mais aussi parce que cela peut avoir des conséquences de sécurité (débordement de tampon, par exemple). Autre piège, les entiers gérés par SDNV sont toujours positifs. Une implémentation ne doit donc pas les décoder vers un type signé, ce qui risquerait d'introduire des valeurs négatives dans un processus qui ne s'y attend pas. (TLV a le même problème si on place un champ Longueur dans une variable de type signé.)

Place aux implémentations. Le programme Python sdnv.py, qui utilise le code présent dans l'annexe A du RFC, permet de tester encodage et décodage. L'affichage (pas le calcul) nécessite l'excellent module bitstring :

# Encodage

% python sdnv.py -e 3    
3 -> 0b00000011

% python sdnv.py -e 130
130 -> 0b1000000100000010

% python sdnv.py -e 4598
4598 -> 0b1010001101110110

% python sdnv.py -e 46598           
46598 -> 0b100000101110110000000110

# Décodage

% python sdnv.py -d 00000000        
00000000 -> 0

% python sdnv.py -d 00000011
00000011 -> 3

% python sdnv.py -d 1000000100000010 
1000000100000010 -> 130

[Ajout d'un troisième octet, fait de bits nuls, _après_ le SDNV.]
% python sdnv.py -d 100000010000001000000000
100000010000001000000000 (only 2 bytes read) -> 130

À noter que les SDNV disposent d'une page Web officielle. En dehors du code Python du RFC, je n'ai pas vu d'autres implémentations mais on peut probablement en extraire du code DTN.


Téléchargez le RFC 6256


L'article seul

RFC 6255: Delay-Tolerant Networks (DTN) Bundle Protocol IANA Registries

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : M. Blanchet (Viagénie)
Pour information
Première rédaction de cet article le 26 Mai 2011


Le groupe de recherche DTN (Delay-Tolerant Networking, cf. RFC 4838) de l'IRTF a déjà produit plusieurs protocoles comme Bundle (RFC 5050) et Licklider (RFC 5326). Ces protocoles n'avaient pas jusqu'alors de registres officiels pour leurs paramètres, manque que notre RFC 6255 vient de combler.

Jusqu'à présent, les paramètres enregistrés étaient stockés sur le site Web du groupe. Ils sont désormais à l'IANA qui en assurera la maintenance: http://www.iana.org/assignments/bundle/bundle.xml.

Ces paramètres sont souvent encodés sous forme de SDNV (Self-Delimiting Numeric Values, RFC 6256 et section 2 de notre RFC). Pour le protocole Bundle (RFC 5050) les paramètres à enregistrer sont décrits en section 3. On peut citer par exemple les options de traitement (processing control flags, section 3.3), dont la liste peut évoluer, la seule contrainte pour l'enregistrement étant la disponibilité d'une spécification stable (pour les politiques d'enregistrement dans les registres IANA, voir le RFC 5226 ; cette politique particulière, « Specification required » est décrite en section 4.1). Ces options ont la forme de bits dans un tableau de taille 64, parmi lesquels le bit 2 indique que le lot (bundle) ne doit pas être fragmenté, le 5 qu'un accusé de réception est demandé, etc.

Autre exemple, les codes de réponse (status report flags, section 3.5) comme « lot accepté » ou « lot transmis ». Comme le tableau de bits est bien plus petit cette fois (huit bits dont seuls trois sont encore libres), les règles d'enregistrement sont plus strictes, un RFC (pas juste n'importe quelle spécification) est exigé.

Les autres protocoles comme Licklider n'ont pas encore leur registre.


Téléchargez le RFC 6255


L'article seul

RFC 6250: Evolution of the IP Model

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : D. Thaler (IAB)
Pour information
Première rédaction de cet article le 20 Mai 2011


Qu'offre l'Internet aux développeurs d'application et aux concepteurs de protocole ? Le modèle de service de l'Internet n'a pas toujours été bien documenté, et les préjugés et idées fausses abondent chez les programmeurs (l'essentiel du RFC est d'ailleurs composé de l'exposé des affirmations erronées sur le modèle Internet.) En outre, l'Internet ayant crû de manière analogue à un écosystème, sans suivre strictement un plan pré-établi, ce modèle a largement changé, sans que ce changement n'ait été intégré par les développeurs. D'où ce RFC, qui ambitionne de documenter le modèle de service de l'Internet tel qu'il est en 2011. Ce RFC devrait être lu par tous les développeurs d'applications, afin qu'ils apprennent le service que leur offre réellement l'Internet.

Tout le monde sait que l'Internet offre un service de niveau 3 (le protocole IP). Mëme si les applications y accèdent en général via un service de niveau 4 (typiquement TCP), bien des caractéristiques de la couche 3 apparaissent aux applications (comme les adresses IP). (Le RFC utilise d'ailleurs parfois le terme « application » pour parler de tout ce qui est au dessus de la couche 3.) Quelles sont exactement les propriétés de ce service ? Par exemple, les caractéristiques de la communication (latence, taux de perte de paquets, etc) mesurées au début sont-elles constantes (réponse : non) ? Quelle est la taille d'une adresse IP (ceux qui répondent « quatre octets » peuvent abandonner l'informatique pour l'élevage des chèvres en Lozère) ? Si 192.0.2.81 se connecte chez moi, pourrais-je me connecter à mon tour à cette machine (réponse : plutôt oui, à l'origine, malheureusement non aujourd'hui) ? Si certaines applications (par exemple une application qui inclus un simple client HTTP pour récupérer un fichier distant) peuvent ignorer sans problème ce genre de questions, pour d'autres (logiciel de transfert de fichiers pair-à-pair, client SIP, etc), ces questions sont cruciales et les développeurs ne connaissent pas forcément les bonnes réponses.

Revenons à l'histoire, comme le fait la section 1 du RFC. Le modèle original d'IP (et qui est encore souvent enseigné comme tel dans pas mal d'établissements d'enseignement) était partiellement documenté en 1978 dans l'IEN28 (les premières publications sur le TCP/IP actuel, les RFC 791 et RFC 793 ne sont venus qu'après). Un des principes était que les applications étaient très différentes mais que toutes tournaient sur IP, qui à son tour tournait sur tous les réseaux physiques possibles (modèle dit « du sablier », IP représentant le goulet d'écoulement du sablier). Ce modèle a nécessité plusieurs clarifications dans les RFC ultérieurs, par exemple le RFC 1122 en 1989 ou le RFC 3819. Résultat, aujourd'hui, il n'y a pas de document unique qui décrive le modèle de service, ce qu'offre IP aux applications.

Il est d'autant plus nécessaire de comprendre ce modèle qu'il est désormais difficile de le changer. Au début de l'Internet, on pouvait changer un concept et obtenir de tous les développeurs de toutes les applications de s'adapter. Aujourd'hui, la taille de l'Internet et son absence de centre rendent une telle opération impossible. L'Internet s'est ossifié.

Bon, en quoi consiste ce fameux « modèle de service » ? Il est décrit par la section 2. Un modèle de service est défini comme la description du service que rend une couche aux couches supérieures, ici le service que rend IP aux applications. Le schéma n° 1 résume cette notion de couches et la place d'IP dans l'architecture de l'Internet. Et le comportement d'IP ? Sa description officielle était dans la section 2.2 du RFC 791 : un service sans connexion (orienté paquets), acceptant des paquets de taille variable, et les délivrant (mais pas toujours) sans garantir leur ordre ou leur absence de duplication. Bref, un service qui « fait au mieux » (best effort dans la langue de Jack London). Les émetteurs n'ont pas besoin de se signaler aux destinataires ou au réseau avant d'émettre et les récepteurs n'ont pas besoin de signaler quoi que ce soit au réseau avant de recevoir.

On l'a dit, l'architecture réelle n'est plus vraiment celle du RFC 791, qui était de toute façon décrite de manière très brève dans ce RFC. D'autres documents ont approfondi la question comme le RFC 1958 ou comme le rapport « New Arch: Future Generation Internet Architecture » de 2004.

En fait, il est plus facile de décrire ce qu'il n'y a pas dans le modèle de service d'IP. La section 3, consacrée aux préjugés erronés, est donc beaucoup plus longue que la section 2. Je ne vais pas la répéter dans son entièreté mais simplement citer quelqu'uns de ces préjugés, en commençant par ceux concernant la connectivité.

Une des suppositions non dites les plus fréquentes dans les applications est que la possibilité d'envoyer un paquet (reachability) est symétrique (section 3.1.1). Un protocole comme FTP (RFC 959), avec sa notion de « voici mon adresse IP, rappelle-moi », repose largement là-dessus. Si la machine A peut envoyer un paquet à la machine B, le contraire est aussi vrai. Ce principe était largement vrai au début de l'Internet (attention, la possibilité d'envoyer était symétrique mais pas le chemin suivi) mais est tout à fait faux aujourd'hui. C'est même plutôt le contraire : la machine typique est coincée derrière un routeur NAT et un pare-feu qui empêchent tout envoi initié par l'extérieur. L'annexe A du RFC 5694 discute plus en détail ce problème et ses conséquences notamment pour les applications pair-à-pair. Bref, la seule chose que laquelle les applications peuvent relativement compter, est qu'une réponse à une requête initiée depuis l'intérieur a des chances d'arriver (c'est le modèle de HTTP). Les requêtes initiées de l'extérieur sont par contre impossibles dans le cas général (RFC 2993).

À noter que, même en l'absence de boîtiers intermédiaires qui bloquent les paquets, certains liens physiques ne sont pas symétriques, notamment en radio, comme l'illustre la section 5.5 du rapport « The mistaken axioms of wireless-network research ».

Autre supposition fréquente mais erronée, la transitivité. L'idée est que, si une machine A peut joindre B, et que b peut joindre C, alors A peut joindre C (section 3.1.2). Exactement comme pour la symétrie, ce principe était vrai au début, et ne l'est plus maintenant, en raison du NAT et des pare-feux, mais aussi de protocoles physiques comme 802.11 qui ne garantissent pas une telle transitivité.

Autre erreur que font certains développeurs d'applications, parce qu'ils confondent le modèle original de l'Internet et la triste réalité d'aujourd'hui, la conviction que les paquets signalant une erreur arriveront à l'émetteur du paquet qui a déclenché l'erreur (section 3.1.3). Ces paquets signalant une erreur sont typiquement portés par le protocole ICMP. Des exemples de leur usage ? La découverte de la MTU du chemin (RFC 1191 et RFC 1981) ou bien traceroute (RFC 1812).

Pourquoi ne peut-on plus compter sur ces messages ? D'abord, bien des routeurs ont été configurés pour limiter le rythme d'envoi, avant de rendre plus difficile leur utilisation dans une attaque DoS (RFC 2923, section 2.1. Ensuite, bien des pare-feux ont été stupidement configurés par des incompétents et bloquent tout l'ICMP (malgré les recommandations des RFC 2979, section 3.1.1, et RFC 4890). Résultat, il a fallu développer des mécanismes alternatifs pour la découverte de la MTU (RFC 4821).

Autre erreur : certaines applications croient qu'elles peuvent utiliser la diffusion IPv4 pour transmettre un message à toutes les machines (section 3.1.5). Autrefois, des adresses comme 10.1.255.255 (les seize derniers bits tous à un) envoyaient en théorie un message à toutes les machines du réseau 10.1.0.0/16, et les routeurs devaient faire suivre ce message au delà du lien local. Comme ce mécanisme facilitait trop les attaques par déni de service, il a été abandonné par le RFC 2644 en 1999. Depuis, la diffusion ne marche plus que sur le lien local. Et encore, car certains liens, dits NBMA, ne la permettent pas. Plus drôle, certains liens comme 802.11 en mode ad hoc autorisent la diffusion mais, en pratique, le message n'atteint pas toutes les machines du lien. Bref, si on veut écrire à toutes les machines d'un groupe, il vaut mieux le faire soi-même, sans compter sur la diffusion.

À ce sujet, la section 3.1.6 note que, contrairement à une croyance courante, un ensemble de paquets unicast n'est pas forcément plus coûteux ou moins rapide qu'un multicast ou qu'un broadcast. Sur les liens filaires traditionnels, un seul paquet multicast sera sans doute plus rapide. Ce n'est plus le cas sur les liens radio où le multicast devra être transmis au débit de base, même s'il existe des machines ayant une interface radio plus rapide, et qui a négocié un débit plus élevé.

Un problème subtil est causé par le cas où l'application compte sur la latence des paquets, par exemple pour faire de la visioconférence. Une application qui mesure cette latence peut avoir tendance à mesurer le premier paquet et à la considérer comme représentatif. Mais c'est souvent à tort (section 3.1.6). En effet, pour le premier paquet d'un flot de données, il y a souvent un temps d'établissement (dû à la résolution ARP, par exemple). Et ce sera pire avec les futurs systèmes de séparation de l'identificateur et du localisateur qui, tous, prévoient une forte latence pour le premier paquet, lorsqu'il faut résoudre l'identificateur en localisateur.

Autre caractéristique d'un chemin suivi par les paquets : le taux de réarrangement, qui mesure le fait que certains paquets arrivent avant des paquets partis plus tôt. Des études comme celle de Bennett, J., Partridge, C., et N. Shectman, « Packet reordering is not pathological network behavior » ou comme les RFC 2991 ou RFC 3819, section 15, montrent que le réarrangement a des conséquences pour les applications. Pour un programme de streaming, par exemple, il oblige à augmenter la taille des tampons. TCP voit ses performances se dégrader si les paquets n'arrivent pas dans l'ordre. Mais le réarrangement est un fait : des tas de raisons peuvent le causer (un routeur qui fait de la répartition de charges entre deux liens, par exemple) et les applications doivent s'y attendre.

Et le taux de pertes des paquets ? Sur quoi peut-on compter ? Beaucoup de gens pensent que les pertes sont rares, et probabilistiques (c'est-à-dire que le destin frappe un paquet au hasard, et qu'en reessayant, ça va marcher). Mais ce n'est pas forcément le cas (section 3.1.9). D'abord, si l'application a un comportement non-uniforme (des grands moments de silence, puis de brusques envois de nombreux paquets), les pertes se concentreront pendant ces envois, qui rempliront les files d'attente. Ensuite, il existe des phénomènes qui mènent à la perte préférentielle du premier paquet, comme ces routeurs de cœur qui, pour éviter une attaque DoS (envoi de paquets vers beaucoup d'adresses qui ne répondent pas), ne gardent pas en mémoire les paquets qui déclenchent une résolution ARP. Le premier paquet vers une nouvelle destination sera donc forcément perdu. Un autre exemple d'un comportement analogue est le Wake-on-LAN, où le paquet qui déclenche l'allumage de la machine n'est en général pas gardé.

L'Internet garantit-il qu'un chemin existe, à un moment donné, vers une destination (section 3.1.10) ? Oui, c'est toujours largement vrai. Mais cela cesse de l'être dans des réseaux exotiques comme les DTN (cf. RFC 4838) où deux machines pourront communiquer sans jamais être allumées en même temps. Avec humour, le RFC mentionne également le cas de réseaux où les paquets sont transportés par des animaux, peut-être une allusion au RFC 1149.

Pourquoi ces suppositions, qui étaient en général vraies autrefois, ont cessé de l'être (section 3.1.11) ? Il y a deux classes de raisons, une située dans les couches 1 et 2, et une autre placée dans la couche 3. Pour la première, le RFC 3819 donnait d'utiles conseils aux concepteurs de réseaux physiques. En gros, il indique une liste de services que doivent rendre les couches basses à IP et, si celles-ci ne le font pas, comment la couche d'adaptation à IP peut compenser. Ainsi, les RFC 3077 et RFC 2491 décrivent des mécanismes pour compenser l'absence d'atteignabilité symétrique et donc restaurer les services auquel s'attend IP. Mais toutes les couches basses ne le font pas : par exemple, il n'existe pas de moyen standard, lorsqu'une machine est connectée en WiFi ad hoc, de compenser le manque de symétrie dans les liens. Un mécanisme, situé sous IP, reste à élaborer.

Autre classe de causes pour lesquelles les suppositions d'autrefois ne sont plus forcément respectées, les raisons situées dans la couche 3 elle-même. Cela peut être une conséquence d'une politique de sécurité (RFC 4948), qui mène au filtrage. Cela peut être aussi à cause du NAT. Plusieurs applications font beaucoup d'efforts pour contourner ces problèmes. Cela semble une bonne application du principe de robustesse (« soyez strict dans ce que vous envoyez mais laxiste dans ce que vous acceptez »), et, en effet, les protocoles qui réussissent à contourner les limites de la couche 3 ont en général plus de succès que les autres (RFC 5218). Mais le principe de robustesse a aussi l'inconvénient de masquer les problèmes, et de diminuer la pression pour les résoudre. Par exemple (qui n'est pas dans le RFC), Skype réussit à passer via des hotspots où seul le port 80 fonctionne en sortie, donc les clients de ces hotspots ne râlent pas contre l'opérateur de ce dernier et celui-ci continue donc à fournir un service de daube. Le RFC suggère, pour sortir de ce dilemme, de fournir un mode spécial pour l'application, activable à la demande, où l'application n'utilisera que des techniques propres et officielles, permettant ainsi de déboguer les réseaux mal fichus, sans que leurs problèmes soient masqués.

Cela, c'était pour la connectivité. Et pour l'adresssage ? La section 3.2 rassemble les suppositions erronées les plus fréquentes sur ce sujet.

D'abord, bien des applications considèrent l'adresse IP comme stable sur une assez longue période (ce qui était vrai autrefois, où les adresses étaient toutes fixes et configurées manuellement). Cette supposition (section 3.2.1) se reflète dans l'API : par exemple, getaddrinfo() ne fournit pas d'indication sur la durée de validité de l'adresse récupérée. Même avec plein de bonne volonté, l'application ne peut pas savoir si l'adresse IP récupérée en échange du nom peut être conservée pour une minute, une heure ou un jour (la plupart des applications appelent getaddrinfo() et ne remettent jamais en cause son résultat, gardant l'adresse IP pendant toute leur durée de vie, un phénomène connu sous le nom d'épinglage - pinning - et qui peut avoir des conséquences pour la sécurité).

Or, aujourd'hui, avec des techniques comme DHCP, les adresses ne sont pas stables et changent, notamment lorsque la machine se déplace. Cela casse des applications comme SSH. Plusieurs protocoles ont été proposés pour conserver un identificateur stable même lorsque le localisateur change (par exemple HIP).

Encore plus répandue, l'idée comme quoi une adresse IP ferait quatre octets (section 3.2.2). Faites le test lors d'un entretien d'embauche : demandez au candidat à écrire un petit programme C qui gère des adresses IP. S'il déclare une variable de type uint32_t, cela montre qu'il ne connait pas IP (si la variable est de type int, cela montre qu'il ne connait pas C...). Cette idée était juste il y a douze ans, mais ne l'est plus depuis que l'Internet est redevenu multi-protocole, avec la coexistence d'IPv4 et IPv6 (dont les adresses font seize octets).

Plus subtile, la question du nombre d'adresses par interface. Pas mal de programmeurs tiennent pour acquis que « l'adresse IP identifie une interface » (ce qui est faux) et écrivent un code qui ne gère pas vraiment le cas d'adresses multiples. Ce préjugé n'a jamais été réellement justifié (le RFC 791 mentionne explicitement la possibilité d'avoir plusieurs adresses IP par interface) mais il l'est encore moins maintenant, où l'existence de plusieurs adresses IP sur une interface est devenue banale (surtout pour IPv6). On note que HIP, cité plus haut, donnerait raison au préjugé, s'il était déployé massivement : l'identificateur serait en effet unique (par machine virtuelle).

En parlant de l'idée d'une adresse IP par machine, si une machine peut avoir plusieurs adresses IP, est-ce qu'une adresse IP peut être utilisée par plusieurs machines ? Cela mène à la notion d'identité d'une machine. Ce concept n'existe pas réellement dans les protocoles TCP/IP mais pas mal d'applications font comme si (section 3.2.4). Par exemple, une ACL sur un pare-feu, bloquant une adresse IP, signifie que l'administrateur du pare-feu considère que l'ennemi peut être identifié par son adresse IP, ce qui n'est pourtant pas toujours le cas.

Parmi les évolutions technologiques qui empêchent ce préjugé d'être exact : l'anycast (RFC 4786), ou bien certaines solutions de haute disponibilité. Des RFC comme le RFC 2101 ou le RFC 2775 discutent de cette question de l'unicité de l'adresse.

Plus ridicule mais néanmoins fréquente, l'idée que l'adresse IP d'une machine identifie sa position géographique (section 3.2.5). C'est clairement faux aujourd'hui (pensez aux tunnels, par exemple).

Plus subtile, l'idée que l'adresse IP a un rapport avec le routage (section 3.2.6). Par exemple, une application qui déduirait de la proximité de deux adresses la proximité des machines. Avec des protocoles comme Mobile IPv6 ou HIP (déjà cité), cette supposition serait complètement fausse. D'une manière générale, tout système de séparation de l'identificateur et du localisateur casserait cette idée. Dans les textes originels (IEN019 ou IEN023),l'adresse IP était présentée comme un localisateur, alors que TCP, par exemple, l'utilise comme identificateur. C'est là la source de cette confusion d'aujourd'hui.

Ces erreurs sur l'adressage sont fréquentes. La section 3.2.10 fournit une perspective plus large, en partant du RFC 1958, dont la section 4.1 avait été le premier texte à insister sur l'importance d'utiliser des noms plutôt que des adresses (celles-ci ayant une sémantique trop floue). Notre RFC 6250 réinsiste fortement sur ce point : c'est bien à tort que des API comme getaddrinfo() exposent les adresses IP aux applications. La plupart du temps, celles-ci ne devraient pas avoir accès à ces adresses, ce qui éliminerait la tentation de les utiliser de manière incorrecte. Ceci dit, le conseil du RFC 1958 n'est pas possible à suivre intégralement aujourd'hui : bien des machines IP (au hasard, mon téléphone portable) n'ont pas de FQDN à elles.

On l'a vu, le terme « applications », dans ce RFC 6250 est utilisé de manière souple, pour décrire tout ce qui se trouve au dessus de la couche 3. la section 3.3 aborde les problèmes spécifiques à une partie de ces « applications », la couche transport (couche 4). Quelles sont les erreurs courantes à propos de cette couche 4 ?

D'abord, un certain nombre d'acteurs de l'Internet croient qu'il est possible d'ajouter de nouveaux protocoles de transport, des concurrents des classiques TCP et UDP (section 3.2.1), tels que ceux enregistrés à l'IANA. C'était certainement le but originel de l'architecture de TCP/IP. Mais, aujourd'hui, ce n'est plus vrai. L'Internet s'est terriblement ossifié et les nouveaux protocoles de transport ont très peu de chances de passer à travers toutes les middleboxes mal fichues qui abondent sur le réseau. Souvent, on doit même tout tunneler au dessus d'HTTP. C'est au point où le RFC suggère même de ne pas hésiter à normaliser cette utilisation de HTTP (quelque chose que, traditionnellement, l'IETF avait toujours refusé de faire, au nom de la qualité technique des normes). XMPP le fait, par exemple, dans son XEP 0124. SIP n'a pas de méthode standard pour cela, et ça lui a parfois été reproché, alors que le système fermé Skype n'hésite pas à détourner HTTP. Un groupe de travail de l'IETF, HyBi, travaille sur un mécanisme générique d'utilisation de HTTP pour contourner ces middleboxes stupides.

Bref, le point le plus étroit du sablier, celui par lequel tout devait passer, et qui était IP dans l'architecture originale, est de plus en plus souvent TCP, voire HTTP. C'est parfois fait au nom de la sécurité (par des gens qui ne connaissent pas forcément ce sujet). L'IETF continue ses efforts pour casser cette dangereuse évolution mais, au cas où ces efforts ne seraient pas couronnés de succès, il faut se préparer à s'adapter.

En parlant de sécurité, quelles sont les idées reçues sur la sécurité (section 3.4) ? Elles sont évidemment nombreuses (et une analyse plus complète figure dans le RFC 3552). Par exemple, bien des applications se comportent encore comme si les paquets n'étaient jamais modifiés en route, à part pour quelques champs bien définis comme le TTL. Le NAT change malheureusement cette situation. On peut parfois restaurer le comportement correct avec des tunnels (RFC 4380) ou avec IPsec en mode transport (RFC 4301).

À défaut d'être respectés dans leur intégrité, les paquets sont-ils au moins privés (section 3.4.2) ? Pas d'avantage. Il a toujours été possible d'écouter les communications et pourtant on trouve toujours des protocoles et des applications qui s'obstinent à envoyer des mots de passe en clair. Là encore, IPsec, s'il était déployé, pourrait fournir une solution générique, ne nécessitant pas de changer les applications.

Autre erreur que font souvent les débutants en sécurité : croire que, puisqu'un paquet prétend venir de 198.51.100.66, alors c'est vrai (section 3.4.3). La vérité est qu'il est relativement facile de mettre une fausse adresse IP source (la plupart des lecteurs de mon blog le savent depuis longtemps mais on trouve pourtant régulièrement des articles qui parlent d'une attaque par déni de service en disant « elle vient de tel pays » simplement parce que les adresses IP source indiquent ce pays). Il existe des mécanismes techniques qui pourraient permettre d'avoir des adresses sûres, par exemples les adresses cryptographiques du RFC 3972.

En conclusion, que faut-il retenir de ce RFC ? La section 5 fournit les points essentiels :

  • Vu le nombre d'applications qui dépendent de TCP/IP pour des travaux critiques, tout changement dans le modèle de service ne devrait être fait qu'avec les plus extrêmes précautions.
  • Les invariants (les concepts essentiels sur lesquels on peut compter) devraient être mieux documentés, au lieu de dépendre du savoir informel des vieux sages.
  • Chaque couche devrait expliciter clairement le service qu'elle fournit aux couches supérieures, et le service qu'elle attend des couches inférieures.
  • Et il faudra de toute façon recommencer le travail de temps en temps, l'évolution étant inévitable.

Téléchargez le RFC 6250


L'article seul

RFC 6248: RFC 4148 and the IPPM Registry of Metrics are Obsolete

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : A. Morton (AT&T Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 15 Avril 2011


Le progrès, c'est aussi de savoir reconnaître quand une idée était mauvaise et qu'il vaut mieux l'abandonner. Ce court RFC prend ainsi acte de l'échec du registre des métriques lancé par le RFC 4148 et décide d'y renoncer.

Le groupe de travail IPPM est chargé notamment de développer des métriques (définitions rigoureuses d'une grandeur qu'on peut mesurer) comme le taux de perte des paquets (RFC 2680). Dans le cadre de ce travail, il avait semblé intéressant, avec le RFC 4148 de créer un registre IANA des métriques existantes. En fait, aucun logiciel n'a été développé pour l'utiliser, aucun utilisateur de ce registre n'a pu être identifié après des mois de recherche (fin 2010), et le registre était donc déjà de facto abandonné avant que notre RFC 6248 le reconnaisse et ne le decrète dépassé. Un exemple montrant l'inutilisation du registre ? Le fait qu'il contenait une faute de syntaxe qui a mis huit mois (depuis la parution du RFC 5644) avant d'être signalée ! Cette décision d'abandon explicite est nécessaire pour éviter d'accumuler dans les registres IANA un grand nombre d'informations qui ne sont plus maintenues.

Notre RFC rappelle d'abord quelles étaient les motivations qui avaient mené à la création du registre : la grande variabilité des définitions de métriques, d'autant plus que certaines étaient modifiées et/ou enrichies par des RFC ultérieurs comme le RFC 3432. Stocker ces variations dans un registre semblait une bonne idée sauf que, en pratique, la structure du registre n'avait pas permis de stocker toute l'information.

Le registre ne sera donc plus mis à jour (le dernier RFC à l'avoir fait avait été le RFC 6049) même s'il continue à être distribué par l'IANA mais avec un texte montrant sans ambiguité son statut.


Téléchargez le RFC 6248


L'article seul

RFC 6247: Moving the Undeployed TCP Extensions RFC1072, RFC1106, RFC1110, RFC1145, RFC1146, RFC1379, RFC1644 and RFC1693 to Historic Status

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : L. Eggert (Nokia)
Pour information
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 17 Mai 2011


Grand nettoyage à l'IETF, plus précisement au sein du groupe de travail TCP Maintenance and Minor Extensions. Huit RFC sur le protocole TCP sont rangés dans la cave de l'IETF, en étant reclassés comme « Document d'intérêt historique seulement ».

La famille de protocoles TCP/IP est bien vivante. La preuve, il y a régulièrement des protocoles ou des extensions aux protocoles qui apparaissent. Mais, pour que l'évolution fonctionne, il faut aussi que certains disparaissent. C'est ce qui vient d'arriver à huit extensions du protocole TCP, qui avaient été normalisées, avaient parfois suscité beaucoup d'espoirs, mais ont ensuite été des échecs. Peu de déploiements, des sérieux problèmes identifiés a posteriori, et voici ces extensions vouées au statut « Historique ». La plus récente, le RFC 1693, datait de 1994... Ces huit RFC perdent donc tout droit au nom de « norme ». Les raisons de ce reclassement figurent en général dans la section 5 du RFC 4614, qui avait fait un tour d'horizon complet et critique de tous les RFC sur TCP.

Parmi les RFC ainsi rabaissés, notons le RFC 1644, qui normalisait l'extension T/TCP qui semblait à une époque pouvoir fournir un TCP léger et rapide, mais qui a montré de sérieuses failles de sécurité à l'usage.

Conséquence pour l'IANA, certaines options enregistrées dans le registre des options TCP, comme les options 6 et 7, du RFC 1072, sont désormais marquées comme « dépassées ».


Téléchargez le RFC 6247


L'article seul

RFC 6241: Network Configuration Protocol (NETCONF)

Date de publication du RFC : Juin 2011
Auteur(s) du RFC : R. Enns (Juniper Networks), M. Bjorklund (Tail-f Systems), J. Schoenwaelder (Jacobs University), A. Bierman (Brocade)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF netconf
Première rédaction de cet article le 1 Juillet 2011


Netconf est un protocole de configuration de matériel réseau (typiquement des routeurs ou des commutateurs). Ce RFC est la nouvelle version publiée par le groupe de travail IETF sur Netconf. (La precédente était le RFC 4741.)

Si on doit gérer un seul routeur, le faire à la main est raisonnable. Mais, si on doit en gérer des dizaines ou des centaines, cela devient impossible sans automatisation. Il existe depuis longtemps de nombreux outils pour gérer un grand nombre d'équipements réseaux, Rancid étant le plus connu. (L'excellent article de Joe Abley, Managing IP Networks with Free Software en donne un bon aperçu. Le RFC 3535 rend compte d'un atelier de l'IAB qui a discuté de ces questions en 2002.) Netconf vise à rendre l'écriture de ces outils plus simple.

Netconf spécifie donc un protocole de RPC permettant à un gérant (manager) de modifier la configuration de l'équipement (device) en lui envoyant du XML.

Le contenu exact de ce document XML n'est pas entièrement spécifié par Netconf car il dépend de l'équipement configuré (la section 1.2 de notre RFC explique ce point). Un langage de description des modèles, Yang (RFC 6020), existe pour décrire les possibilités.

Extrait du RFC, voici un exemple (hypothétique) où on fixe à 1500 octets la MTU de l'interface réseau eth0 :


    <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <top xmlns="http://example.com/schema/1.2/config">
             <interface>
               <name>eth0</name>
               <mtu>1500</mtu>
             </interface>
           </top>
         </config>
       </edit-config>
     </rpc>

Il est difficile de ne pas penser à l'acronyme NIH en lisant ce RFC. Netconf définit un protocole de RPC alors qu'il existe déjà SOAP et XML-RPC, Netconf définit en section 6, un mécanisme d'extraction de sous-arbres XML alors que XPath existe déjà...

Quels sont les changements depuis le RFC original ? L'annexe F les résume. Pas de grand changement, des bogues signalées contre le RFC 4741 et quelques ajouts : un malformed-message ajouté aux messages d'erreur possibles, une option remove ajoutée aux opérations possibles, l'ajout de la notion de « nom d'utilisateur », le schéma XSD de modélisation des opérations remplacé par un module YANG, etc.

À noter qu'un Wiki, http://trac.tools.ietf.org/wg/netconf/trac/wiki, fournit plein d'informations sur Netconf, notamment sur les mises en œuvre existantes du protocole, dont certaines en logiciel libre. Parmi les autres, les routeurs Juniper peuvent déjà être configurés avec Netconf (et une bibliothèque Java est fournie). Ça marche aussi sur un Cisco.


Téléchargez le RFC 6241


L'article seul

RFC 6235: IP Flow Anonymization Support

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : E. Boschi, B. Trammell (ETH Zurich)
Expérimental
Réalisé dans le cadre du groupe de travail IETF ipfix
Première rédaction de cet article le 14 Mai 2011


La question de la protection de la vie privée sur l'Internet est, à juste titre, une question très sensible et qui a déjà agité beaucoup d'électrons sur les blogs et autres sites Web, d'autant plus que de grosses et puissantes entreprises, comme Facebook et Google sont à l'œuvre pour réduire cette vie privée à pas grand'chose. Parmi toutes les problèmes pratiques que pose la protection de la vie privée, ce RFC se limite à celui des fichiers de trafic réseau, contenant des données sensibles et qu'on souhaite anonymiser. Le RFC se concentre sur le format IPFIX mais la plupart des problèmes exposés et des recommandations faites peuvent s'appliquer à d'autres formats comme les journaux de connexion ou comme les fichiers pcap. Un RFC utile, donc, pour tous les techniciens qui se soucient de la vie privée de leurs utilisateurs (et qui n'ont donc pas été embauchés par Facebook).

« Anonymiser » n'est pas un bon terme (mais je reprends celui du RFC). Tout le problème est qu'en effet les données ne sont pas réellement anonymes après cette opération : il est devenu simplement plus difficile de les relier à une personne ou une organisation donnée. Mais ce n'est pas impossible : de nombreux travaux de recherche ont montré qu'on pouvait reconstituer une bonne part des données manquantes dans un fichier « anonymisé ». Un exemple est l'excellent article de Bruce Schneier : « Why 'Anonymous' Data Sometimes Isn't » qui montre très bien à quel niveau de perfectionnement les outils de « désanonymisation » sont parvenus.

Avant d'attaquer le RFC lui-même, commençons par un exemple simple. Supposons qu'on ait enregistré le trafic réseau en un endroit donné et qu'on récupère donc un fichier pcap. On peut le dire avec divers outils comme tcpdump et voici un résultat typique :

% tcpdump -n -v -r MYFILE.pcap
... 
15:00:24.451549 IP (tos 0x0, ttl 64, id 17621, offset 0, flags [DF], proto TCP (6), length 1059)
    192.168.2.1.41949 > 193.159.160.51.80: Flags [P.], cksum 0xd268 (correct), seq 1029:2036, ack 247, win 108, options [nop,nop,TS val 2792071 ecr 1944126014], length 1007

On peut y voir que 192.168.2.1 interrogeait le serveur HTTP 193.159.160.51 (un des serveurs d'Akamai, qui héberge www.wired.com, le site cité précedemment). On sait que c'était de l'HTTP par le port de destination (80) mais on aurait aussi pu le déduire en examinant les données (que tcpdump n'affiche pas, mais qui sont bien dans le fichier pcap et qu'un outil comme Wireshark peut afficher de manière très lisible ; ces mêmes données auraient pu nous dire qu'elle était la page Web exacte qui avait été consultée). Autre exemple, le journal d'un serveur HTTP où on trouvera des choses comme :

2001:db8:33::dead:beef:1 - - [10/May/2011:19:49:57 +0200] "GET /aventures-jules.html HTTP/1.1" 200 5306 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1" www.bortzmeyer.org

qui nous indique que la machine d'adresse IP 2001:db8:33::dead:beef:1 a consulté la page aventures-jules.html de ce serveur. Ces informations sont-elles sensibles ? D'abord et avant tout sont-elles nominatives, ce qui, dans la loi Informatique & Libertés ne se limite pas aux informations comportant le nom d'une personne physique, mais inclut celles qui permettent de retrouver facilement cette personne (comme le « numéro de Sécu »). Ici, l'adresse IP source n'est pas la vraie (les données ci-dessus ont été anonymisées) mais, si elle l'était, elle permettrait assez facilement de retrouver l'auteur de cette visite à Wired et donc il est tout à fait justifié de considérer l'adresse IP comme nominative.

Et c'est embêtant pour les chercheurs et les analystes. Car de telles données de connexion sont très utiles et de nombreux articles scientifiques intéressants ont été produits à partir de données comme celles-ci, collectées dans des grandes opérations comme le DITL. De même, les opérateurs réseaux ont souvent besoin d'analyser ces données pour mieux comprendre ce qui se passe dans leur réseau et pour l'améliorer. Enfin, l'étudiant, le curieux, le programmeur qui met au point un nouvel outil d'analyse ont besoin de telles données (on trouve par exemple plein de fichiers pcap sur pcapr.net). Mais transmettre ces données, les rendre publiques, les envoyer dans un pays qui n'a aucune législation de protection de la vie privée, comme les États-Unis, pose des problèmes éthiques et légaux considérables.

Une façon courante de concilier ces deux demandes est d'anonymiser les données. Par exemple, si on supprime l'adresse IP, on a enlevé la donnée la plus sensible, tout en permettant encore plusieurs analyses (par exemple sur la taille des paquets, sur les ports - donc, souvent, les services - les plus fréquents, etc. Mais en faisant cela, on a interdit certaines analyses, comme par exemple la répartition du trafic (tout le monde consomme t-il pareil, ou bien certains gros consommateurs sont-ils « responsables » de la majorité du trafic ?) Bref, l'anonymisation sera toujours un compromis : plus on retire de données et mieux on a anonymisé. Et plus les données perdent de leur intérêt... Il faudra donc prendre une décision en fonction des risques et des bénéfices. L'IETF n'a évidemment pas le pouvoir de prendre une telle décision mais ce RFC pose au moins les bases techniques nécessaires pour comprendre les choix. Il insiste notamment sur les techniques de désanonymisation, qui font que certaines techniques d'anonymisation ne protègent guère la vie privée.

Pour prendre l'exemple des requêtes DNS, si on peut croire que l'adresse IP source (qui est celle du résolveur, par celle du client final) n'est pas une information bien sensible, il ne faut pas oublier que le contenu de la requête (le QNAME, pour Query NAME) peut en dire beaucoup. Par exemple, certains réseaux sociaux utilisent un sous-domaine qui a le nom de l'utilisateur.

Passons au RFC maintenant. Il a deux parts, une première générale sur les techniques d'anonymisation, leurs forces et leurs faiblesses et une seconde spécifique au format IPFIX (RFC 5101). La première partie intéresse tous les programmeurs et récolteurs de données. Le fait d'avoir un format standard, IPFIX, pour les échanges d'information sur les flots de données (pcap - un standard de fait - est limité aux paquets individuels, une information de plus bas niveau) est évidemment un avantage pour tous ceux qui font circuler de l'information mais cela augmente aussi les risques de divulgation. D'où l'importance particulière de ce problème pour IPFIX.

Commençons par une définition rigoureuse de l'anonymisation (qu'il faudrait normalement écrire entre guillemets à chaque fois, tellement on est loin du vrai anonymat). La section 1 la définit comme la suppression ou la transformation d'une information qui, sans cette suppression ou cette transformation, pourrait permettre d'identifier la personne ou de l'organisation à l'origine d'une communication. Il ne faut pas utiliser l'anonymisation seule (elle a des tas de limites, notamment en raison de la puissance des techniques de désanonymisation) mais elle peut être un outil utile dans un arsenal de mesures de protection de la vie privée.

La section 1.4 rappelle d'ailleurs que ce RFC a le statut « Expérimental » car il considère que toutes les techniques d'anonymisation sont encore peu fiables (voir Burkhart, M., Schatzmann, D., Trammell, B., et E. Boschi, « The Role of Network Trace Anonymization Under Attack »).

La première partie de ce RFC revient sur ces techniques, d'une manière indépendante du format des données (pcap, IPFIX, etc). D'abord, la section 3 classifie les techniques d'anonymisation. Toutes ont en commun de chercher à empêcher la traçabilité, tout en préservant les informations utiles à l'analyse. Elles fonctionnent par mise en correspondance de l'espace des vrais valeurs vers un autre espace, « anonyme », suivant une fonction bien définie. La mise en correspondance est récupérable si on peut inverser cette fonction (ce qu'on ne souhaite évidemment pas, pour l'anonymisation) et commensurable (ou mesurable) si les deux espaces ont la même taille (préservant ainsi toutes les analyses qui cherchent à compter, par exemple le nombre d'adresses IP distinctes). Ainsi, une fonction de généralisation qui ne garderait que les N premiers bits de l'adresse IP (pour empêcher l'identification d'un individu) ne serait pas commensurable (plusieurs adresses IP seraient mises en correspondance avec un préfixe unique). Lorsque la fonction est commensurable, la technique d'anonymisation est appelée une substitution (je change chaque adresse IP par une autre). Notez que la substitution est vulnérable aux attaques par force brute, même si l'attaquant ignore la fonction utilisée, s'il peut injecter le trafic qu'il veut et observer les résultats (une variante des attaques « par dictionnaire »).

L'anonymisation la plus radicale est de retirer complètement un champ des données (méthode du feutre noir, le black-marker, dit le RFC, du nom de l'outil des censeurs du courrier d'autrefois). Ni récupérable, ni commensurable, elle offre le maximum de sécurité mais peut faire perdre des informations précieuses.

Voyons maintenant chaque champ un à un. La section 4, qui détaille les techniques adaptées à chaque champ, commence évidemment par les adresses IP car c'est le champ le plus « nominatif ». Lorsqu'on parle d'anonymisation, on pense tout de suite à celle des adresses IP, et à juste titre (section 4.1). Le problème de leur anonymisation n'est pas simple. Par exemple, une adresse IP est structurée. Même si on supprime les N derniers bits, ceux qui restent, le préfixe, identifient encore un FAI ou une entreprise et donne donc des informations. Il y a quatre moyens d'anonymiser une adresse IP (sans compter évidemment le feutre noir) :

  • La troncation, qui supprime les N derniers bits de l'adresse (pour le programmeur, la troncation est un AND avec un nombre de M-N uns et N zéros). C'est ce que permet un logiciel comme Squid avec sa directive client_netmask, qui permet de préserver la vie privée des utilisateurs du cache en ne gardant dans le journal que le préfixe de leur adresse IP. La troncation est une généralisation (elle ne conserve pas le nombre d'adresses IP.)
  • La troncation inverse consiste au contraire à supprimer les N premiers bits. Ainsi, l'organisme (FAI ou entreprise) est masqué. C'est aussi une généralisation et deux machines sans lien entre elles (par exemple 192.0.2.57 et 203.0.113.57) vont être confondues (ici, si on supprime les 24 premiers bits). Attention, si le réseau sur lequel a été fait la collecte est connu, il n'est pas difficile de retrouver le préfixe des adresses de ce réseau.
  • La permutation consiste à remplacer chaque adresse IP par une autre. Elle conserve donc le nombre d'adresses IP (mais pas la structure des adresses : deux machines du même réseau local peuvent se retrouver très « loin » l'une de l'autre). La façon la plus fréquente de la réaliser est via une fonction de hachage de l'adresse IP. Attention, si cette fonction est connue, une attaque par force brute (tester toutes les adresses) devient possible, surtout en IPv4. Il est donc recommandé d'introduire un élément secret (par exemple un mot de passe concaténé à chaque adresse avant le hachage).
  • La pseudonymisation qui préserve le préfixe est le quatrième moyen. Elle garde les N premiers bits et fait une permutation sur les M derniers. Cela permet de garder l'information sur la « proximité » de deux adresses. Comme à chaque fois, garder de l'information permet de faire certaines études... mais augmente le risque de désanonymisation.

Les adresses MAC identifient également une machine. Elles ne sont pas toujours présentes dans les données collectées (si le point de capture est sur le réseau d'un gros opérateur, les adresses MAC de la source et de la destination ne sont pas disponibles) mais on peut les trouver dans des captures faites localement. Elles peuvent aussi apparaître comme partie d'un identificateur de couches hautes, par exemple dans certaines adresses IPv6 (cf. section 2.5.1 du RFC 4291, et RFC 4941 pour une solution). Donc, il faut également anonymiser ces adresses (section 4.2). Comme les adresses IP, elles ont une structure, mais plus simple (les 24 ou 40 premiers bits indiquent le constructeur). Comme pour les adresses IP, on peut utiliser la troncation (on ne garde typiquement que les bits qui identifient le constructeur), la troncation inverse, la permutation et la pseudonymisation structurée.

Les numéros de port et de protocole de couche 4 n'identifient pas une entité du monde réel (comme une personne) mais peuvent servir à classer les machines (par exemple, le choix des ports sources permet souvent d'identifier le système d'exploitation, cf. RFC 6056). Ils méritent donc parfois une anonymisation (section 4.5) par exemple par permutation. Le RFC ne le mentionne pas, mais il n'est pas sûr qu'une technique d'anonymisation, qu'elle qu'elle soit, puisse fonctionner avec la distribution typique des protocoles : le plus répandu sera forcément TCP (numéro 6).

Les traces de trafic réseau contiennent souvent des nombres (collectivement appelés compteurs) qui peuvent révéler des choses sur leurs émetteurs (section 4.4). On peut donc les anonymiser en diminuant leur précision ou en les quantifiant, c'est-à-dire en les répartissant dans un petit nombre d'intervalles (les corbeilles ou bin dans le texte original du RFC) et en ne gardant qu'une valeur par intervalle.

Plus étonnant, les estampilles temporelles que contiennent les traces (date de passage du paquet, dates de début et de fin du flot) peuvent être également indiscrètes (voir Murdoch, S. et P. Zielinski, « Sampled Traffic Analysis by Internet-Exchange-Level Adversaries »). Par exemple, le séquencement des paquets peut permettre d'identifier une activité (une communication téléphonique n'aura pas du tout la même répartition temporelle des paquets qu'un téléchargement donc, même sans DPI, on pourra identifier le type de trafic). On peut donc essayer d'anonymiser les indications temporelles mais la plupart des méthodes disponibles, à part bien sûr le feutre noir, sont assez faibles contre la désanonymisation (section 4.3). On peut diminuer la résolution des temps (comme on a fait pour les compteurs, par exemple arrondir à la seconde la plus proche), on peut utiliser l'énumération (méthode qui remplace chaque estampille temporelle par un chiffre croissant : elle préserve l'ordre des événements, qui peut être important mais pas les écarts, ce qui interdit de mesurer des grandeurs comme la gigue), etc.

Une fois qu'on a anonymisé les données, il faut indiquer au destinataire comment on l'a fait, pour qu'il puisse faire ses analyses (section 5). Par exemple, si les adresses IP ont été tronquées, le destinataire ne doit pas tenter d'étudier des distributions de trafic par machine, puisque plusieurs machines sont désormais regroupées dans le même préfixe. Il faudra donc indiquer si l'anonymisation était stable ou pas (la stabilité est la propriété de mise en correspondance d'une valeur de départ avec la même valeur d'arrivée ; une anonymisation instable, au contraire, peut diriger vers une autre valeur d'arrivée après un certain temps). Typiquement, un jeu de données est stable, sauf indication contraire, mais deux jeux de données peuvent ne pas l'être entre eux, donc il vaut toujours mieux l'indiquer explicitement.

S'il y a eu troncation, il faut évidemment indiquer la longueur qui a été conservée. S'il y a eu quantification, il faut donner la liste des valeurs et leurs intervalles. S'il y a eu permutation, il ne faut pas donner la fonction utilisée (ou alors, si une clé a été ajoutée, donner la fonction mais sans la clé), afin d'éviter les attaques par dictionnaire (traduire des valeurs et regarder le résultat obtenu).

L'anonymisation soulève d'autres questions de sécurité, décrites en section 9. Elle enfonce le clou que l'anonymisation n'est jamais parfaite (sauf à effacer toutes les données). Elle rappelle que l'anonymisation ne remplace pas la confidentialité. Si des données sensibles sont exportées vers un tiers de confiance, le chiffrement sur le trajet reste nécessaire, même si les données sont anonymisées.

Ici commencent maintenant les questions spécifiques à IPFIX. Si vous ne pratiquez pas ce format, vous pouvez décider d'arrêter là. Sinon, la section 1.1 offre un utile rappel des RFC 5470, RFC 5101 et RFC 5102. IPFIX permet d'envoyer des tuples TLV dont la sémantique est décrite dans un gabarit (Template). Plusieurs gabarits standards figurent dans le RFC 5102.

La section 6 décrit comment représenter les données anonymisées et les méta-informations (celles de la section 5 sur le mécanisme d'anonymisation) dans un flow IPFIX. Les données effacées par le feutre noir représentent le cas le plus simple : on ne les met pas du tout dans le flot. Pour les autres, il faut ajouter au flot un Anonymization Options Template qui décrira les fonctions d'anonymisation. Les détails de ce gabarit figurent en section 6.1 et 6.2. Par exemple, un champ anonymizationTechnique va indiquer l'absence d'anonymisation s'il vaut 1, la troncation (ou la dégradation de la précision, qui est à peu près la même chose) s'il vaut 2, l'énumération s'il vaut 4, etc (des exemples plus complets figurent en section 8).

Ces considérations d'encodage ont été inscrites dans les registres IANA d'IPFIX. anonymizationTechnique, par exemple, est identifié par le nombre 286.

L'anonymisation est typiquement effectuée dans un relais IPFIX (Mediator), en général situé à la frontière administrative du domaine (on n'anonymise pas si les données restent dans l'organisation d'origine). Attention : outre les données proprement dites, le flot contient souvent des méta-informations sur le processus de collecte qui peuvent si on ne prend pas soin de les modifier, casser en partie ou totalement l'anonymisation. Ainsi (section 7.2.3), le temps auquel a été fait l'observation peut permettre de retrouver les estampilles temporelles, même brouillées. L'identité du réseau où a été fait la mesure permet de retrouver une partie de l'adresse IP, même en cas de troncation inverse (cette identité a la même taille qu'une adresse IPv4 et il peut donc être tentant d'utiliser une adresse du réseau local comme identité).

Plus rigolo, la section 7.2.5 recommande de se méfier des adresses IP « spéciales » (RFC 5735 pour IPv4 et RFC 5156 pour IPv6). Ces adresses sont en effet souvent utilisées à des fins bien connues, qui font qu'on peut les retrouver, même anonymisées, en examinant leur activité. Cela fournit alors un point de départ au travail du désanonymisateur. Le RFC recommande donc d'exclure ces adresses des données exportées.

Les mises en œuvre d'IPFIX permettent-elles aujourd'hui cette anonymisation ? Je ne crois pas mais, en dehors du monde IPFIX, il existe un grand nombre d'outils d'anonymisation. Citons :


Téléchargez le RFC 6235


L'article seul

RFC 6234: US Secure Hash Algorithms (SHA and SHA based HMAC and HKDF)

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : Donald Eastlake (Huawei), Tony Hansen (AT&T Labs)
Pour information
Première rédaction de cet article le 7 Mai 2011


Ce long RFC (127 pages, dont la majorité est composé de code source C) est la mise à disposition de la communauté IETF du code de FIPS 180-2, décrivant les algorithmes de cryptographie de la famille SHA-2. Il remplace le RFC 4634.

Cette famille de fonctions de hachage cryptographiques normalisée par le NIST (et donc standard officiel aux États-Unis) a vocation à remplacer l'ancien SHA-1 (RFC 3174). Elle comprend SHA-224 (également décrit dans le RFC 3874), SHA-256, SHA-384 et SHA-512. Tous ont le même principe (section 1) : un document de longueur quelconque est transformé en un condensat cryptographique de longueur fixe (le nom de l'algorithme indique le nombre de bits du condensat), de telle manière qu'il doit extrêmement difficile de fabriquer un document ayant le même condensat qu'un document donné (ou même de fabriquer deux documents ayant le même condensat).

Notre RFC décrit également leur utilisation en HMAC (cf. RFC 2104), et en HKDF (HMAC-based Key Derivation Function, cf. RFC 5869). L'essentiel du RFC est tiré directement de la norme officielle et les assertions sur la sécurité de SHA-2 viennent donc directement du NIST et pas des éditeurs du RFC.

Les sections 2 à 7 du RFC résument le fonctionnement de ces algorithmes, et la section 8 est le code source C les mettant en œuvre.

La licence de ce code source figure dans le fichier sha.h, listé en section 8.1.1. C'est une licence BSD-3 (sans la clause de publicité), qui permet tout usage, commercial ou non, ainsi que toute modification et redistribution. Elle est donc adaptée au logiciel libre.

Comme copier/coller le code source depuis le RFC en éliminant les en-têtes et pieds de page n'est pas pratique, on peut récupérer une archive « propre » en http://www.pothole.com/~dee3/source/sha.tar. Il y en a plein d'autres mises en œuvre de SHA décrites en http://en.wikipedia.org/wiki/SHA-2#Implementations.

Les changements depuis le RFC 4634 sont résumés dans l'annexe. Le principal est l'ajout de HKDF (HMAC-based Key Derivation Function). Il y a aussi pas mal d'errata dans le code, détectés par le meilleur relecteur des RFC, Alfred Hoenes, et désormais réparés. La licence est nouvelle (BSD-3 désormais) et a nécessité de remplacer le code de getopt.


Téléchargez le RFC 6234


L'article seul

RFC 6227: Design Goals for Scalable Internet Routing

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : T. Li (Cisco)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 7 Mai 2011


Le problème fondamental du routage dans l'Internet est connu depuis longtemps : le système actuel a du mal à fournir certains services (multi-homing, mobilité, ingénierie de trafic, etc) d'une manière qui passe à l'échelle, c'est-à-dire qui puisse grandir au rythme de la croissance de l'Internet. Un groupe de travail IRTF, le Routing Research Group travaille donc sur ce sujet et ce RFC 6227 est le cahier des charges produit.

Il est très court : il est plus facile de spécifier le problème que de décrire les solutions. Le problème (les services difficiles à fournir tout en passant à l'échelle) a déjà été présenté par le RFC 4984. Reste à concevoir les solutions et, pour cela, à décrire les exigences auxquelles doit se plier la future architecture, et leurs priorités respectives. Logiquement, le cahier des charges s'écrit au début et est publié longtemps avant que le travail ne se termine mais, ici, cela n'a pas été le cas. Les conclusions du travail sur la nouvelle architecture sont déjà sorties (RFC 6115). Simplement, le cahier des charges avait bien été écrit au début mais il a été modifié et raffiné au fur et à mesure de l'avancement du travail et d'une meilleure compréhension du problème, pour n'être publié officiellement que maintenant.

Chaque exigence listée dans ce RFC a une priorité : requise, fortement souhaitée ou souhaitée, et les exigences avec leurs priorités sont résumées dans un tableau dans la section 3.11. D'autre part, les principes traditionnels de l'Internet, tels qu'explicités dans le RFC 1958 s'appliquent toujours (notamment le principe de bout-en-bout qui indique que les deux machines terminales qui communiquent doivent faire l'essentiel du travail, puisque ce sont elles qui doivent décider, par exemple des priorités de trafic).

La « liste au Père Noël » est en section 3. D'abord, compte-tenu de la croissance continue de la table de routage globale (cf. les rapports sur la croissance de la table BGP), il est fortement souhaité (section 3.1) que le nouvelle architecture permettre de séparer la croissance de l'Internet et celle de la table de routage. Actuellement, un nouvel utilisateur qui veut être « multi-homé » proprement ajoute une entrée BGP dans la table de routage globale, qui risque donc de devenir proportionnelle au nombre de tels utilisateurs. Ce n'est clairement pas souhaitable. Notez que le RFC est ambitieux : on ne parle pas de faire croître la table de routage moins vite que le nombre d'utilisateurs, mais de ne pas la faire croître du tout lorsque ce nombre d'utilisateurs augmente.

Autre exigence, concernant l'ingénierie de trafic, c'est-à-dire la possibilité d'envoyer le trafic sur tel ou tel chemin selon des critères qui ne sont pas ceux du système de routage classique, par exemple pour forcer le passage par un lien moins coûteux. Une méthode courante aujourd'hui est d'injecter dans la table de routage globale des préfixes d'adresses IP plus spécifiques. Cela augmente la taille de ladite table. Il est donc fortement souhaité qu'une meilleure solution soit trouvée (section 3.2).

Même chose pour le multi-homing, déjà cité : il est fortement souhaité qu'il puisse aussi passer à l'échelle (section 3.3).

Une bonne partie des problèmes de l'architecture actuelle de l'Internet vient de la confusion de deux rôles dans l'adresse IP : localisateur (indique un point d'attachement dans l'Internet) et identificateur (nomme une machine ou une interface). Il est depuis longtemps reconnu (cela se trouvait déjà dans l'IEN1) que cette confusion est dommageable. Il est donc souhaité qu'on sépare ces deux rôles (section 3.4).

Un certain nombre de gens (note au passage : je n'en fais pas partie) considèrent qu'il est essentiel qu'une machine terminale, voire un réseau entier, puisse se déplacer dans l'Internet, changer de fournisseur, etc, sans remettre en cause son adresse IP et les sessions existantes. Par exemple, une connexion SSH devrait rester intacte si mon smartphone passe du Wi-Fi chez moi avec Free, au 3G chez Bouygues, voire si je passe de Free à la maison à Paris à un accès Verizon en Californie. Comme ces deux scénarios entraînent un changement de l'adresse IP, la connexion SSH cassera. Les mécanismes existants pour permettre ces changements d'attachement sans casser les connexions en cours sont la mobilité IP (RFC 5944), avec introduction d'une machine relais, le home agent, ou bien l'injection de préfixes dans la table de routage lorsque la machine se déplace. Les deux solutions sont imparfaites (la seconde impacte sérieusement la table de routage globale) et on désire donc une meilleure solution pour la mobilité (section 3.5). Le mieux serait qu'elle sépare complètement la mobilité du routage.

Autre problème du système de routage : comme il est très difficile de rénuméroter un grand réseau (cf. RFC 5887), beaucoup d'organisations font tout pour garder des adresses IP à elles, ce qui impacte le système de routage (l'agrégation des préfixes devient plus difficile). Le RFC note bien qu'une rénumérotation complètement automatique est utopique, il estime néanmoins (section 3.6) qu'on peut abaisser sérieusement le coût de renumérotation (cf. RFC 4192) et que c'est fortement souhaitable.

Autre souhait fort : que le nouvelle architecture soit conçue de manière modulaire, de manière à ce qu'on puisse en utiliser seulement une partie et à ce que les différents composants de la solution ne soient pas excessivement couplés (par exemple, si la solution introduit un tunnel, la détermination de la PMTU devrait se faire par les moyens standard, sans introduire un nouveau mécanisme pour les machines terminales).

Ce n'est pas tout que les paquets arrivent : encore faut-il qu'ils arrivent vite. La qualité du chemin trouvé par le système de routage compte donc beaucoup. Il est donc fortement souhaité (section 3.8) que ce dernier trouve une route rapidement (convergence efficace), n'en change tout le temps (routes stables) et que les routes trouvées soient proches de l'idéal (faible élongation - stretch - cette dernière étant définie comme le rapport entre la longueur du chemin effectif et la longueur du chemin le plus court possible, cf. « A Trade-Off between Space and Efficiency for Routing Tables » de Peleg et Upfal).

Autre préoccupation importante, la sécurité (section 3.9). Il est requis que la nouvelle architecture ait une sécurité au moins équivalente à l'ancienne. C'est un des deux seuls points où l'exigence est requise. Les cyniques diront que celle-ci n'est pas trop difficile à atteindre, vu le niveau de sécurité existant.

Enfin, une dernière exigence, elle aussi requise, en section 3.10 : la déployabilité. Il ne sert à rien de concevoir une splendide architecture si celle-ci reste dans les cartons. Or, des expériences malheureuses comme celle d'IPv6 ont montré que déployer des nouvautés dans l'Internet était très difficile. Il faut notamment que le nouveau système soit déployable de manière incrémentale : les premiers adoptants doivent pouvoir l'installer, et même en tirer des bénéfices immédiats. Sinon, chacun attendra que l'autre fasse le premier pas et on n'avancera pas. (Il n'est évidemment pas question de repartir de zéro, vus les investissements réalisés.)

Voilà, il n'y a maintenant plus qu'à trouver des solutions correspondant à ce cahier des charges : le RFC 6115 résume les résultats de cette quête.


Téléchargez le RFC 6227


L'article seul

RFC 6220: Defining the Role and Function of IETF Protocol Parameter Registry Operators

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : Danny McPherson (IAB), Olaf M. Kolkman (IAB), John Klensin (IAB), Geoff Huston (IAB)
Pour information
Première rédaction de cet article le 15 Avril 2011
Dernière mise à jour le 6 Mai 2011


Voici un RFC officiel de l'IAB pour mettre solennellement par écrit le rôle de l'opérateur des registres des protocoles utilisé par l'IETF. Des tas de protocoles normalisés par cet organisme ont besoin de garder une trace des noms ou numéros réservés (par exemple les numéros de port de TCP ou UDP, les numéros d'options DHCP, etc) et le rôle de l'opérateur du registre qui garde ces réservations (aujourd'hui, essentiellement l'IANA) n'avait apparemment jamais été formalisé.

L'IETF n'assure en effet pas ce rôle d'opérateur du registre elle-même. Elle se focalise sur la production de normes (les RFC) et délègue la gestion du registre. Pourquoi les valeurs en question ne sont-elles pas directement mises dans les RFC ? Parce qu'elles évoluent plus vite que la norme elle-même. Ainsi, l'enregistrement d'un nouveau type d'enregistrement DNS est un processus bien plus souple que de modifier un RFC et la liste de tels types ne peut donc pas être figée dans un RFC (ceux-ci ne sont jamais modifiés, seulement remplacés, et cela n'arrive pas souvent).

Mais on ne peut pas non plus laisser chacun définir ses propres paramètres, car cela empêcherait toute interprétation commune. D'où cette idée d'un registre des paramètres. Les règles d'enregistrement dans ce registre, la politique suivie, sont décrites pour chaque norme dans la section IANA considerations du RFC, en utilisant le vocabulaire et les concepts du RFC 5226 (pour les types d'enregistrements DNS, cités plus haut, c'est dans le RFC 6195).

Plusieurs autres SDO suivent ce même principe de séparation entre la normalisation et l'enregistrement (en revanche, les groupes fermés d'industriels qui tentent d'imposer leur standard ne séparent pas en général ces deux fonctions). Par exemple, l'ISO définit, pour la plupart de ses normes, une Registration Authority ou bien une Maintenance Agency qui va tenir le registre. (Exemples : l'opérateur du registre de ISO 15924 est le consortium Unicode et celui du registre de ISO 639 est SIL. Contre-exemple : l'opérateur du registre de ISO 3166 est l'ISO elle-même.) Pourquoi cette séparation ? Les raisons sont multiples mais l'une des principales est la volonté de séparer la politique de base (définie dans la norme) et l'enregistrement effectif, pour gérer tout conflit d'intérêts éventuel. Un opérateur de registre séparé peut être plus indépendant, afin de ne pas retarder ou bloquer l'enregistrement d'un paramètre pour des raisons commerciales ou politiques. Notons aussi que bien d'autres fonctions liées à l'IETF sont également assurées à l'extérieur, comme la publication des RFC (cf. RFC 5620).

Contre-exemple, celui du W3C, qui utilise très peu de registres et pas d'opérateur de registre officiel séparé. En pratique, c'est l'IANA qui gère plusieurs registres Web, comme celui des URI bien connus (RFC 5785), celui des types de fichiers (comme application/pdf ou image/png), celui des en-têtes (utilisés notamment par HTTP), etc. En dehors de l'IANA, le W3C a quelques registres gérés en interne comme celui de Xpointer. Pour le reste, la politique du W3C est plutôt qu'un registre est un point de passage obligé et que de tels points ne sont pas souhaitables.

Dans le cas de l'IETF, les documents existants sont le RFC 2026, qui décrit le processus de normalisation mais pas celui d'enregistrement. Ce dernier est traditionnellement connu sous le nom de « fonction IANA » (d'où la section IANA considerations des RFC) même si, en pratique, ce n'est pas toujours l'IANA qui l'effectue. (Les registres de l'IANA sont en http://www.iana.org/protocols/.)

La section 2 du RFC expose donc le rôle et les responsabilités du(des) opérateur(s) de registres de paramètres. Celui(ceux)-ci, désormais nommés avec majuscules IETF Protocol Parameter Registry Operator, seront formellement choisis désormais par l'IAOC (RFC 4071). J'ai mis le pluriel car l'IANA n'assure pas actuellement la totalité du rôle : il existe d'autres opérateurs de registres, en général sur des tâches très secondaires comme par exemple le RIPE-NCC pour l'enregistrement en e164.arpa (ENUM, cf. RFC 6116 et lettre de l'IAB). Dans le futur, on pourrait imaginer un rôle moins exclusif pour l'IANA.

La section 2.1 est la (longue) liste des devoirs qu'implique le rôle d'opérateur de registre. Il y a bien sûr le tenue du registre à proprement parler mais ce n'est pas tout. En voici une partie :

  • Donner des avis sur les futurs RFC (concrètement, relire les sections IANA considerations à l'avance, pour voir si elles ne poseraient pas de problèmes insurmontables au registre).
  • Suivre les RFC : l'opérateur du registre n'est pas censé déterminer la politique mais l'appliquer. Si un RFC dit que l'enregistrement dans tel registre se fait sans contrainte, l'opérateur du registre ne peut pas refuser un enregistrement, par exemple. Chaque registre a une politique d'enregistrement, expliquée dans le RFC correspondant (les règles générales figurent dans le RFC 5226).
  • Bien indiquer dans chaque registre les références notamment le numéro du RFC qui normalise ce registre et pour chaque paramètre enregistré dans le registre, indiquer la source de ce paramètre et la date d'enregistrement.
  • En cas de désaccord ou de problème, se tourner vers l'IESG, seule habilitée à trancher.
  • Diffuser gratuitement les registres qui sont tous publics par défaut (contrairement à ce qui se passe chez l'ultra-dinosaure ISO). Un exemple est le registre de DHCP, en http://www.iana.org/assignments/bootp-dhcp-parameters/.
  • Maintenir les listes de diffusion spécifiées pour certains registres, par exemple lorsque l'enregistrement nécessite un examen par un expert, sous l'œil du public.
  • Produire des rapports réguliers à destination de l'IAB, suivant le RFC 2860 mais aussi suivant l'accord supplémentaire qui l'a complété, et à destination de toute l'IETF. Aujourd'hui, cela se fait sous la forme de l'exposé IANA qu'il y a à chaque plénière de l'IETF. Ces rapports incluent des points comme les performances de l'opérateur du registre (délai de traitement, par exemple).
  • Ne pas oublier que les droits de propriété intellectuelle sur ces registres sont gérés par l'IETF Trust (RFC 4748).

Après cette description des devoirs de l'opérateur du registre, la section 2 continue avec les devoirs des autres acteurs. En section 2.2, ceux de l'IAB, qui supervise l'opérateur du registre : l'IAB procède à la délégation formelle du registre, après que l'IAOC ait identifié les candidats. L'IAB décide, l'IAOC gère la relation avec l'opérateur.

En section 2.3, le rôle de l'IESG : celui-ci s'occupe de la partie technique, vérifier que les RFC comportent une bonne section IANA considerations, identifier les experts techniques si le RFC précise que l'enregistrement est précédé d'une évaluation technique (exemple : le RFC 5646, où l'enregistrement d'une langue dans le registre des langues est précédé d'une telle évaluation par un linguiste), répondre aux questions de l'opérateur du registre si celui-ci a un problème pratique.

En section 2.4, le rôle de l'IETF Trust (RFC 4748). Il gère la propriété intellectuelle de l'IETF donc est « propriétaire » du contenu des registres. Enfin, en section 2.5, le rôle de l'IAOC, bras administratif de l'IETF, qui est de gérer au quotidien les relations avec l'opérateur du registre.

Voilà, l'essentiel était là mais la section 3 rajoute quelques détails.


Téléchargez le RFC 6220


L'article seul

RFC 6206: The Trickle Algorithm

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : P. Levis (Stanford University), T. Clausen (LIX, Ecole Polytechnique), J. Hui (Arch Rock Corporation), O. Gnawali (Stanford University), J. Ko (Johns Hopkins University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF roll
Première rédaction de cet article le 29 Mars 2011
Dernière mise à jour le 30 Mars 2011


Dans le cadre des travaux sur l'Internet des objets, le groupe de travail ROLL de l'IETF s'occupe de définir des mécanismes de routage pour des réseaux d'engins aux capacités limitées, et connectés par des liens radio à faible portée et souvent brouillés. (Par exemple, cela peut décrire la situation de capteurs dans une usine.) Une brique de base pour beaucoup de protocoles utilisés dans ce contexte est un algorithme pour coordonner un état entre toutes les machines (cet état pouvant être par exemple la table de routage, mais aussi une configuration commune). Trickle (terme désignant un mince filet d'eau, par exemple celui coulant du robinet en cas de fuite) est l'algorithme utilisé et ce RFC est sa première normalisation. Il est notamment utilisé dans le protocole RPL du RFC 6550.

Vu le contexte très spécial, les protocoles classiques de distribution d'information ne convenaient pas forcément à ce type de réseau, où il est crucial d'économiser l'énergie, et de fonctionner malgré des liaisons physiques sommaires. Trickle atteint ces objectifs en ne diffusant l'information que lorsque elle a changé. L'idée de base est de permettre à deux nœuds de déterminer très rapidement s'ils ont la même version de l'information distribuée et, sinon, de se synchroniser. S'ils sont synchronisés, il n'y a plus beaucoup de communication. Lorsque de la nouvelle information apparait, le trafic reprend. Trickle repose entièrement sur les mécanismes de diffusion du réseau local et n'est donc pas routé. Le tout est simple et tient dans 50 à 200 lignes de code C (je n'ai pas trouvé de distribution officielle de référence de ce code miracle mais l'implémentation dans Contiki fait effectivement cette taille).

Trickle est un algorithme générique : conçu à l'origine pour distribuer du code (pour mettre à jour le programme sur les autres machines), il a pu être adapté pour distribuer n'importe quel type d'information, par exemple une table de routage. Pour un nouveau type d'information, il suffit de définir ce que veut dire « être synchrone » ou pas et la partie générique de Trickle fait le reste.

Assez de publicité, place à l'algorithme (sections 3 e 4 du RFC). Le travail de chaque nœud est de transmettre les données qu'il connait jusqu'à ce que, en entendant les autres nœuds, il se rende compte que ses transmissions sont inutiles (cela veut dire qu'un nœud Trickle isolé continuera à parler tout seul). Pour prendre l'exemple du protocole CTP (Collection Tree Protocol), quelques paquets par heure suffisent.

La transmission se fait à une adresse multicast locale. Par exemple, au dessus d'IPv6, Trickle va écrire à une adresse multicast locale au lien alors qu'en IPv4, il utiliser 255.255.255.255.

Lorsqu'un nœud reçoit les messages d'un autre, il y a deux cas :

  • Le message montre que celui dont on vient de recevoir des nouvelles a la même version de l'information,
  • Le message montre qu'un des deux nœuds, le récepteur ou l'émetteur, est en retard. Notons que Trickle ne fait pas trop de différence entre ces deux sous-cas : ils entraineront tous les deux une transmission de données.

L'un des principaux paramètres d'un algorithme spécifique utilisant Trickle est un moyen de déterminer cette notion de « être à jour ». Par exemple, supposons que l'information ait un numéro (comme le numéro de série des zones DNS). Alors, « être à jour » signifie avoir le même numéro que l'autre et « être en retard » avoir un numéro inférieur.

Pour décider ensuite de l'action exacte à entreprendre, les nœuds Trickle ont besoin de quelques paramètres :

  • la taille minimum de l'intervalle, Imin,
  • la taille maximum de l'intervalle, Imax,
  • la constante de redondance k.

et de quelques variables :

  • la taille actuelle de l'intervalle, I,
  • le moment de la transmission, t,
  • le compteur c.

Le nœud suit les règles suivantes :

  • Choisir I entre Imin et Imax. Commencer le premier intervalle.
  • Au début de l'intervalle, mettre c à zéro et t à une valeur située dans la deuxième moitié de l'intervalle.
  • À chaque message reçu pour lequel on est à jour, incrémenter c.
  • Au temps t, si c est inférieur à k, on transmet les données. (C'est la seule étape de l'algorithme où on transmet quelque chose.) c < k peut se traduire par « j'ai trop de voisins qui ne sont pas à jour par rapport à l'ensemble de mes voisins ». C'est par cette comparaison de c (nombre de voisins à jour) à k que Trickle s'adapte automatiquement à la densité du réseau (s'il y a plein de voisins à jour, pas la peine de se fatiguer à transmettre, un autre le fera).
  • À la fin de l'intervalle, doubler la taille de l'intervalle (en s'arrêtant à Imax).
  • Si on entend un message qui montre que quelqu'un (le nœud qui exécute cet algorithme ou bien son voisin) n'est pas à jour, on réduit l'intervalle à Imin. L'idée est de rendre l'algorithme plus dynamique lorsqu'il y a des nœuds qui sont en retard.

On note que Trickle ne réagit pas immédiatement en détectant un retard : il se contente de démarrer un nouvel intervalle. C'est fait exprès pour éviter une tempête de mises à jour, par exemple lorsqu'un nouveau nœud rejoint le réseau après une absence. Trickle privilégie donc l'économie de ressources, et ne cherche pas à être temps-réel.

Ça, c'était l'algorithme. Simple, non ? Maintenant, si vous êtes concepteur de protocoles et que vous voulez utiliser Trickle, que vous reste-t-il à faire ? La section 5 liste vos tâches :

  • Préciser des valeurs par défaut pour les paramètres Imin, Imax, k, etc. Notamment, Imin dépend de la latence du réseau utilisé.
  • Définir ce que signifie « être à jour » et « être en retard ».
  • Et quelques détails. Regardez le RFC 6550 pour un exemple de protocole de routage utilisant Trickle.

Il ne faut quand même pas oublier quelques considérations pratiques (section 6). D'abord, le bon fonctionnement de Trickle dépend d'un accord de tous les nœuds sur les paramètres à utiliser. En cas de différence, le résultat peut être sous-optimal voire faux dans certains cas. Par exemple, un nœud qui aurait une constante de redondance k supérieure aux autres pourrait se retrouver à émettre à chaque intervalle, vidant sa batterie. De même, un désaccord sur Imax pourrait mener certains nœuds à ne jamais transmettre, laissant les autres faire tout le travail. En outre, toutes les valeurs ne sont pas forcément raisonnables. Par exemple, la constante de redondance k mise à l'infini est théoriquement possible (Trickle travaillerait alors en mode bavard, n'économisant pas les transmissions) mais très déconseillée. Il faut donc trouver un moyen de distribuer la bonne configuration à toutes les machines.

Le pire problème serait évidemment une fonction de définition de la cohérence différente selon les nœuds, cela pourrait mener à une impossibilité de converger vers un état commun. C'est pour cela que le RFC demande qu'elle soit strictement définie pour un protocole donné, et non configurable.

L'auteur de protocole, ou le programmeur, pourraient vouloir « améliorer » Trickle en ajustant l'algorithme. Attention, avertit le RFC, cet algorithme a été soigneusement étudié et testé et la probabilité d'arriver à l'améliorer est faible. Il est conseillé de ne pas le toucher gratuitement. Trickle est extrêmement simple et la plupart des améliorations mèneraient à un code plus compliqué. Or, pour le genre de machines pour lesquelles Trickle est prévu, économiser en transmissions de paquets pour finir par faire davantage de calculs ne serait pas forcément optimal.

Enfin, question sécurité, c'est simple, Trickle n'en a pas (section 9). Un méchant peut facilement pousser tous les nœuds à transmettre, épuisant leurs ressources. Et il peut assez facilement empêcher le groupe de converger vers un état stable. Les protocoles qui utilisent Trickle doivent donc définir leurs propres mécanismes de sécurité.

Pour approfondir Trickle, notamment sur ses performances ou son implémentation, les articles recommandés sont « Trickle: a self-regulating algorithm for code propagation and maintenance in wireless sensor networks » et « The emergence of a networking primitive in wireless sensor networks ».

Plusieurs utilisations de Trickle sont mentionnées en section 6.8, avec références. Trickle est par exemple utilisé dans Contiki : http://www.sics.se/~adam/contiki/contiki-2.0-doc/a00543.html. Damien Wyart s'est attelé à la tâche de trouver d'autres mises en œuvre et voici ses résultats (je le cite).

« Dans les travaux qui parlent de Trickle, on voit souvent cité Maté, une sorte d'environnement qui permet de mettre en réseau des mini-machines virtuelles (si j'ai bien compris), et certains documents indiquent que Maté contient une implantation de Trickle. Maté est distribué principalement sous forme de RPM, ce qui n'aide pas sur Debian... Il ne semble plus évoluer depuis 2005 (mais l'auteur principal continue à travailler sur TinyOS et peut sans doute être contacté pour obtenir plus de détails sur les implantations de Trickle. De plus, Maté est intimement lié à TinyOS qui a depuis, semble-t-il, beaucoup évolué. »

« Par recoupements (c'est assez rare d'avoir à autant jouer les détectives entre fichiers RPM, confusion sur les versions et vieux dépôts CVS --- TinyOS a maintenant un SVN chez Google Code), je suis arrivé principalement au fichier http://tinyos.cvs.sourceforge.net/viewvc/tinyos/tinyos-1.x/tos/lib/VM/components/MVirus.nc?view=log. Sur une copie locale des deux sous-arborescences tinyos-1.x/tools/java/net/tinyos/script et tinyos-1.x/tos/lib/VM (citées dans http://www.eecs.berkeley.edu/~pal/mate-web/downloads.html), j'arrive à ceci (avec le bien pratique concurrent de grep, ack) :

 dw@brouette:/storage/sandbox/tinyos-1.x$ ack -ai trickle
 tos/lib/VM/components/MVirus.nc
 118:  MateTrickleTimer versionTimer;
 119:  MateTrickleTimer capsuleTimer;
 153:  void newCounter(MateTrickleTimer* timer) {

 tos/lib/VM/doc/tex/mate-manual.tex
 615:that has newer code will broadcast it to local neighbors. The Trickle
 635:Trickle's suppression operates on each type of packet (version,
 645:\subsubsection{Trickle: The Code Propagation Algorithm}
 647:The Trickle algoithm uses broadcast-based suppressions to quickly
 651:completes, Trickle doubles the size of an interval, up to
 662:Trickle maintains a redundancy constant $k$ and a counter

 tos/lib/VM/types/Mate.h
 168:typedef struct MateTrickleTimer {
 173:} MateTrickleTimer;

 tools/java/net/tinyos/script/VMFileGenerator.java
 524:    writer.println(" * MVirus uses the Trickle algorithm for code propagation and maintenance.");
 528:    writer.println(" * \"Trickle: A Self-Regulating Algorithm for Code Propagation and Maintenance");
 549:    writer.println("     the timer interval for Trickle suppression, and the redundancy constant");

Cela donne donc des pistes, la partie principale semblant bien être le fichier MVirus.nc. »


Téléchargez le RFC 6206


L'article seul

RFC 6204: Basic Requirements for IPv6 Customer Edge Routers

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : H. Singh, W. Beebee (Cisco), C. Donley (CableLabs), B. Stark (AT&T), O. Troan (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 28 Avril 2011


Ce RFC du groupe de travail v6ops, qui se consacre aux problèmes pratiques du fonctionnement d'IPv6 (sans modification des protocoles, donc), porte sur les CPE (Customer Premises Equipment), alias CER (Customer Edge Routers), alias home gateway, qui sont les boîtiers installés chez l'utilisateur domestique ou petite entreprise. Par exemple, en France, la Freebox ou la DartyBox sont des CPE. Certains d'entre eux gèrent le protocole IPv6 et ce RFC résume tout ce que doivent savoir les concepteurs de ces « boxes » pour faire de l'IPv6 proprement.

Le gros débat qui avait eu lieu à l'IETF lors de la conception de ce RFC portait sur une règle exprimée dans les premières versions de l'Internet-Draft qui avait précédé le RFC : cette règle disait qu'un CPE IPv6 devait, par défaut, bloquer les connexions entrantes. L'argument principal était que les CPE IPv4 font tous cela. Mais ils le font parce qu'en IPv4, la pénurie d'adresses oblige à des bricolages comme le NAT, et empêchent de toute façon les connexions entrantes. IPv6 permettant enfin de récupérer une adresse IP unique mondialement, et donc d'avoir à nouveau une connectivité de bout en bout, cette règle évoquait plus un « Minitel 2.0 » que l'Internet du futur.

Elle a donc été retirée de ce RFC, qui laisse ouverte la question de la sécurité, la déléguant à un autre document, le RFC 6092. En coupant les connexions entrantes, on bloque certaines attaques (par forcément les plus fréquentes : aujourd'hui, la plupart des attaques se font par le contenu des données transférées - importation de malware - et pas directement sur IP) mais on empêche les utilisateurs de profiter des services comme la téléphonie sur IP ou le pair-à-pair, qui dépendent souvent de cette possibilité de connexions entrantes.

Donc, en dehors de ce point, que contient ce RFC ? La section 1 résume les points importants : le RFC se focalise sur le cas où IPv6 est natif (pas de traduction d'adresses entre v4 et v6), et sur le cas simple où il n'y a qu'un seul CPE, qui récupère sa configuration sur le WAN, puis la distribue aux machines IPv6 locales, puis route leurs paquets. Le déploiement de l'IPv6 dans le réseau de l'opérateur n'est pas discuté (cf. RFC 4779). Ce RFC concerne uniquement le « foyer, doux foyer ».

D'abord, un rappel du fonctionnement d'un CPE IPv4 aujourd'hui. Ce fonctionnement n'est spécifié nulle part, il résulte d'une accumulation de choix par les auteurs anonymes des CPE existants. Ces choix sont souvent erronés. En l'absence de norme formelle, la section 3.1 décrit le CPE « typique » de 2010. Ce CPE typique a une (et une seule) connexion avec l'Internet, une seule adresse IP publique (et encore, parfois, il y a même du NAT dans le réseau de l'opérateur) et il sert de routeur NAT aux machines IPv4 situées sur le réseau local. Par défaut, en raison du NAT, il bloque toutes les connexions entrantes (c'est la seule allusion à cette question qui soit restée dans la version finale du RFC). Ouvrir des ports entrants (port forwarding) se fait par une configuration manuelle du CPE, via une interface Web (cas de la Freebox) ou bien par UPnP. C'est donc un vrai Minitel 2.0. Un avantage de ces adresses privées est toutefois d'assurer la stabilité des adresses internes : elles ne changent pas si on quitte son FAI.

L'architecture ci-dessus est largement déployée et correspond au cas de la plupart des abonnés à l'Internet à la maison. À quoi ressemblera t-elle en IPv6 ? On ne peut évidemment pas encore être sûr. mais la section 3.2, qui la décrit en termes très généraux, suppose qu'elle ne sera pas très différente, à part que la présence de plusieurs réseaux (et donc plusieurs préfixes IP) sera peut-être un cas plus fréquent qu'aujourd'hui. Quelles adresses IP seront utilisées à l'intérieur ? On pense immédiatement au RFC 5902, qui n'est toutefois pas cité. Le RFC 6204 présente la possibilité que des adresse locales, les ULA (RFC 4193) soient utilisées pour le réseau local. Le CPE devra bien alors fournir un mécanisme de traduction.

Alors, maintenant, quelles sont les exigences auxquelles devront se plier les futurs CPE IPv6 ? La section 4 est la liste de ces demandes. Elles sont nombreuses. Citons, parmi elles, l'obligation de d'abord se comporter en bon routeur, ce qui implique par exemple de mettre en œuvre ICMP (RFC 4443) correctement. Du côté du WAN, le CPE devra lui-même utiliser les protocoles standard de découverte d'un routeur (RFC 4861) pour trouver où envoyer les paquets, devra demander son préfixe avec DHCP (RFC 3633), devra bien sûr encapsuler IPv6 correctement (RFC 2464 pour Ethernet), etc. Du côté du LAN, il devra fournir des adresses globales ou des ULA (les adresses locales au lien ne suffisent pas et, de toute façon, pas besoin d'un routeur pour en acquérir). La gestion des ULA est désormais obligatoire, et le CPE doit pouvoir mémoriser le préfixe ULA, même en cas de redémarrage, de façon à fournir un préfixe stable (et, idéalement, configurable) au réseau dont il a la charge. Il doit évidemment pouvoir distribuer ce préfixe sur le réseau local avec SLAAC (Stateless Address Autoconfiguration, RFC 4862) ou avec DHCP (RFC 3315, ce protocole devient donc désormais obligatoire). Il doit fournir des options comme l'annonce des serveurs DNS (RFC 3646).

La sécurité, on l'a vu, est l'aspect délicat de ces machines, puisque le M. Michu qui les utilise pour connecter sa maison, ne connait pas le problème et n'a pas envie d'apprendre. Sur ce point controversé, la section 4.4 se contente de renvoyer à un autre RFC, le RFC 6092 en disant que ce serait bien de mettre en œuvre ses recommandations. Délibérement, la question de la configuration par défaut souhaitable (permettre les connexions entrantes ou pas) est laissée de côté.

Les CPE d'aujourd'hui mettent-ils en œuvre ces recommandations ? Difficile à dire, je ne connais pas d'étude systématique ayant été faite sur les capacités de ces engins (un projet est en cours), mais ce serait certainement très instructif. Des tests chez Free sur une Freebox v5 semblent indiquer que tout est correct (pas de filtrage bizarre, et merci à Ludovic Martin pour ses essais.)


Téléchargez le RFC 6204


L'article seul

RFC 6203: IMAP4 Extension for Fuzzy Search

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : T. Sirainen
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF morg
Première rédaction de cet article le 27 Mars 2011


Où s'arrêtera la liste des extensions au protocole IMAP d'accès aux boîtes aux lettres ? En tout cas, elle ne cesse de grossir. Ce RFC propose une extension aux fonctions de recherche d'IMAP pour permettre des recherches floues, par exemple pour que « hipothèse » puisse trouver « hypothèse ».

Beaucoup de systèmes de recherche disposent de mécanisme analogue, par exemple le moteur de recherche Google, lorsqu'on lui soumet la requête erronée citée plus haut propose « Essayez avec cette orthographe : hypothèse 2 premiers résultats affichés ». Mais IMAP n'avait qu'un service de recherche exact, via la commande SEARCH (RFC 3501, section 6.4.4). Notre RFC 6203 l'étend en permettant, via l'ajout du mot-clé FUZZY, des recherches floues. Il est important de noter que ce RFC ne spécifie qu'une syntaxe : la sémantique exacte d'une recherche est laissée à chaque mise en œuvre, et on peut penser qu'elle évoluera avec les progrès de la recherche floue. Ainsi, pour prendre un exemple, est-ce que « Penelope » trouvera les textes sur Pénélope ? Le RFC ne le spécifie pas, laissant chaque serveur IMAP ajouter les algorithmes de recherche floue qu'il préfère.

La syntaxe exacte figure en section 3. Un mot-clé, FUZZY, enregistré dans le registre IANA d'IMAP, préfixe le critère de recherche, comme dans, par exemple :

   C: MYTAG1 SEARCH FUZZY (SUBJECT "balade dames jadisse")
   S: * SEARCH 1 5 10
   S: MYTAG1 OK Search completed.

Et on trouvera peut-être (selon l'implémentation) un message dont le sujet était « La ballade des dames du temps jadis » (et merci à ma fille pour une intéressante discussion sur balade / ballade). Je répète que c'est le serveur qui décidera du niveau de flou acceptable, le RFC ne fournit pas de guide à ce sujet.

Le mot-clé FUZZY s'applique au critère qu'il préfixe, pas à toute la recherche. Donc :

   C: MYTAG2 SEARCH FUZZY (SUBJECT "balade dames jadisse") FROM francois@villon.fr
   S: * SEARCH 1 4
   S: MYTAG2 OK Search completed.

fera une recherche floue sur le sujet mais une recherche exacte sur l'auteur.

Les recherches floues vont évidemment renvoyer davantage de résultats que les recherches exactes et le tri de ces résultats, par pertinence, est donc essentiel. La section 4 décrit donc le mécanisme de pertinence. Le RFC recommande très fortement aux serveurs IMAP qui mettent en œuvre FUZZY d'affecter une grandeur entre 0 et 100 à chaque résultat, indiquant la pertinence. Si le serveur accepte également l'extension ESEARCH (RFC 4731), celle-ci peut servir à récupérer les valeurs de pertinence, avec la nouvelle option de RETURN, RELEVANCY :

   C: MYTAG3 SEARCH RETURN (RELEVANCY ALL) FUZZY TEXT "Bnjour"
   S: * ESEARCH (TAG "MYTAG3") ALL 1,5,10 RELEVANCY (4 99 42)
   S: MYTAG3 OK Search completed.

Les exemples ci-dessus utilisaient la recherche floue avec des chaînes de caractère. Mais la norme ne se limite pas à ces chaînes, comme le précise la section 5. Un serveur peut donc décider de permettre des recherches floues pour d'autres types de données et le RFC donne des indications sur les types pour lesquels c'est utile :

  • Les dates, pour permettre des recherches comme « il y a une semaine, à peu près », la pertinence décroissant lorsqu'on s'éloigne de la date indiquée,
  • Les tailles, pour chercher des messages d'« environ un Mo »,
  • Alors qu'en revanche les recherches par UID (RFC 3501, section 2.3.1.1) n'ont sans doute aucune raison d'être floues.

Le concept de pertinence s'applique aussi à la commande SORT (section 6). On peut donc trier les messages selon la pertinence :

   C: MYTAG4 SORT (RELEVANCY) UTF-8 FUZZY SUBJECT "Bjour"
   S: * SORT 5 10 1
   S: MYTAG4 OK Sort completed.

Si vous être programmeur et que vous ajoutez cette capacité de flou à un serveur IMAP existant, lisez bien la section 8 sur la sécurité. En effet, les recherches floues peuvent consommer bien plus de ressources du serveur et faciliter ainsi des attaques par déni de service.

D'autre part (comme, là encore, avec les moteurs de recherche du Web), les recherches floues peuvent être plus susceptibles d'empoisonnement par des méchants qui glisseraient dans les messages de quoi apparaître en tête du classement.

Et quelles sont les implémentations existantes de cette extension ? Il y en a apparemment au moins deux mais j'ai été trop paresseux pour chercher lesquelles, comptant sur les lecteurs pour me les signaler.


Téléchargez le RFC 6203


L'article seul

RFC 6195: Domain Name System (DNS) IANA Considerations

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : Donald E. Eastlake 3rd (Motorola)
Première rédaction de cet article le 29 Mars 2011


Un RFC un peu bureaucratique, pour détailler les mécanismes utilisés pour l'enregistrement dans les registres de l'IANA des paramètres liés au DNS. Il met très légèrement à jour son prédécesseur, le RFC 5395, qui avait libéralisé l'enregistrement de nouveaux paramètres.

Un certain nombre de paramètres, dans le DNS, sont enregistrés à l'IANA, afin de s'assurer d'une interprétation identique partout. C'est ainsi que l'IANA gère un registre des paramètres DNS où on trouve, entre autres, les types d'enregistrement (A, codé 1, pour une adresse IPv4, AAAA, codé 28, pour une adresse IPv6, LOC, codé 29, pour les positions géographiques du RFC 1876, SPF, codé 99, pour le RFC 4408, etc). Cet espace n'étant pas de taille infinie, il faut y enregistrer de nouveaux paramètres avec prudence, selon les règles qui étaient expliquées dans le RFC 2929, qui a été sérieusement réformé par le RFC 5395 avant de l'être, beaucoup plus légèrement, par notre RFC 6195.

En effet, les règles du RFC 2929 étaient bien trop strictes à l'usage. Notamment, le processus d'enregistrement d'un nouveau type d'enregistrement était tellement pénible que beaucoup de protocoles (comme SPF à ses débuts) préféraient utiliser le fourre-tout TXT pour y mettre leurs enregistrements. Ce goulet d'étranglement était souvent cité comme un exemple typique des blocages liés à l'IETF.

Le RFC 5395 avait donc assoupli les règles d'enregistrement des types de ressources DNS (les autres règles sont peu changées). Avant, il y avait deux solutions (voir le RFC 5226 pour plus d'explications), IETF Review (ex-IETF Consensus), un processus long et incertain imposant un RFC sur le chemin des normes, approuvé par l'IESG, ou Specification required, qui impose l'écriture d'une norme (pas forcément un RFC) « stable et permanente ».

Le nouveau système est plus léger (section 3.1.1) : il suffit désormais de remplir un formulaire décrivant le nouveau type d'enregistrement (un gabarit figure en annexe A), de le soumettre sur la liste dnsext@ietf.org et d'attendre le jugement d'un expert, désigné parmi les noms fournis par l'IESG, qui décidera, sur la base du formulaire soumis, d'allouer ou pas la requête. Un tel processus est utilisé pour d'autres enregistrements à l'IANA, par exemple pour les nouvelles étiquettes de langue.

Le nouveau processus a été testé pour la première fois pour le type d'enregistrement ZS (Zone Status) qui a été accepté, sous un autre nom, NINFO, et figure désormais sous le numéro 56 dans le registre IANA. Autre exemple, plus récent, le type URI, permettant de stocker des URI dans le DNS, enregistré en février 2011, sous le numéro 256. Mais tous les types ne réussissent pas forcément leur entrée dans le registre. CAA, qui sert à indiquer l'autorité de certification du domaine, est toujours en discussion.

Quels sont les changements entre le RFC 5395, qui avait marqué l'entrée dans la nouvelle ère, et notre RFC 6195 ? Ils sont minimes (voir annexe B). Le principal est le changement de nom de la liste de diffusion où se discutent les demandes. Autrement, ce sont surtout des petites corrections éditoriales.

Outre l'enregistrement de nouveaux types de ressources DNS, notre RFC mentionne également d'autres champs des messages DNS. Un changement ou une extension de leur sémantique continue à nécessiter une action plus lourde à l'IETF. Ainsi, le bit RD (Recursion Desired) n'a de signification que dans une question DNS. Dans une réponse, il est indéfini et son éventuelle utilisation future nécessitera un RFC sur le chemin des normes. Même chose pour le dernier bit qui reste libre dans les options, le bit Z. Quant aux opcodes qui indiquent le type du message (requête / notification / mise à jour dynamique / etc), un ajout à leur liste nécessitera le même chemin.

Les codes de réponse (rcodes), comme NXDOMAIN (nom inexistant) ou BADTIME (signature trop ancienne ou trop récente, cf. RFC 2845) sont tirés d'un espace plus vaste et la procédure est donc un peu plus libérale (section 2.3).


Téléchargez le RFC 6195


L'article seul

RFC 6186: Use of SRV Records for Locating Email Submission/Access services

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : C. Daboo (Apple)
Chemin des normes
Première rédaction de cet article le 31 Mars 2011


Les enregistrements DNS de type SRV ont été normalisés dans le RFC 2782 il y a dix ans, pour permettre de trouver la ou les machines rendant un service (par exemple de messagerie instantanée avec XMPP), en ne connaissant que le nom de domaine délégué, par exemple example.org ou apple.example. Ils ont été adoptés par la plupart des protocoles Internet, avec deux exceptions importantes : le Web ne les utilise toujours pas, ce qui mène à des bricolages contestables comme de mettre une adresse IP sur un nom de domaine délégué. Et le courrier électronique n'utilise pas non plus SRV car, pour trouver le serveur d'un domaine, il compte sur une technique plus ancienne, proche du SRV mais spécifique au courrier, le MX (les MX ne présentent aucun avantage spécifique et, si tout était à refaire de zéro, on utiliserait certainement les SRV aussi pour cela). Les enregistrements MX ne concernent toutefois que la transmission de courrier de MTA à MTA. Pour les autres logiciels de courrier, comment font-ils ?

Depuis ce RFC 6186, ils utilisent SRV à leur tour. Ainsi, un MUA qui cherche à quel serveur transmettre le courrier n'aura plus besoin d'être configuré explicitement (options Mail submission server, Mail retrieval server, ou quelque chose de ce genre). Il suffira d'indiquer l'adresse électronique de l'utilisateur (mettons jeanne@example.org) et le MUA pourra extraire le domaine (example.org) et chercher des enregistrements SRV qui lui indiqueront où trouver ces serveurs. (Une autre méthode ancienne était d'utiliser des conventions comme de mettre le serveur IMAP en imap.example.org mais elle est moins souple, les SRV permettent en effet d'indiquer plusieurs serveurs, de préciser leurs priorités, etc.)

Bien, commençons par l'introduction. Une liste (sans doute non limitative) des services de courrier est donnée par la section 1 :

Le premier cité de ces RFC, le RFC 5321 (section 5) normalise l'utilisation des enregistrements MX pour trouver le serveur de courrier suivant. Mais il ne dit rien des autres services. Par exemple, un MUA ne peut pas trouver dans les MX le serveur de soumission. Résultat, les MUA dépendent d'une configuration manuelle des serveurs à utiliser, parfois augmentée d'une série d'heuristiques (du genre, essayer l'IMAP sur le serveur de soumission, au cas où ce serait le même...). Ce système est complexe pour les utilisateurs (« Indiquez le numéro de port de votre serveur IMAP ; si vous ne le connaissez pas, écrivez à jenerepondsjamaisintelligemment@support.votre-fai.net »...)

Les différents noms SRV utilisés sont normalisés en section 3 :

  • submission (section 3.1) sert pour la soumission initiale de message, telle que décrite dans le RFC 6409. Ainsi, pour le domaine example.org, on pourrait voir un enregistrement _submission._tcp.example.org. SRV 0 1 9587 mail.example.NET. indiquant que les messages doivent être soumis à mail.example.NET, sur le port non-standard 9587. À noter que cet enregistrement couvre les connexions avec ou sans TLS, ce qui est une autre source de confusion lors de la configuration.
  • imap (section 3.2) et imaps servent pour trouver le serveur IMAP. Donc, par exemple, avec cette fois le port standard, _imap._tcp.example.org. SRV 0 1 143 imap.example.NET..
  • pop3 et pop3s servent à localiser le serveur POP3. Leur absence peut donc indiquer que ce vieux protocole n'est pas disponible pour un domaine.

Les enregistrements SRV indiqués ici utilisent évidemment la sémantique standard du RFC 2782. Ainsi, l'ensemble suivant :

$ORIGIN example.org.
 _imap._tcp     SRV 0 1 143 imap.example.net.
                SRV 10 1 143 imap.plan-B.example.

signifie, en raison du champ Priorité (mis à zéro pour le premier enregistrement et à 10 pour le second), que le client IMAP doit tenter d'abord de se connecter à imap.example.net et ne doit essayer imap.plan-B.example que si le premier est injoignable. Tout cela est ancien et bien connu. Mais le courrier présente un défi spécifique, l'existence de deux protocoles de récupération, IMAP et POP. Que doit faire le MUA si les deux sont annoncés dans le DNS ? La section 3.4 tranche : le MUA qui gère les deux protocoles devrait récupérer les enregistrements pour POP et IMAP et utiliser ensuite le champ Priorité, non seulement à l'intérieur d'un ensemble (POP ou IMAP) mais même pour choisir entre les deux protocoles. Ainsi, ces données :

$ORIGIN example.org.
_imap._tcp     SRV 10 1 143 imap.example.net.

_pop3._tcp      SRV 50 1 143 pop.example.net.

indiquent sans ambiguité que l'administrateur système voudrait qu'on utilise de préférence IMAP (champ Priorité plus petit, donc plus prioritaire).

Bien, maintenant, dans le futur (car, aujourd'hui, il n'y a à ma connaissance aucune mise en œuvre de ce RFC dans un logiciel), comment se comportera un MUA lorsque ce RFC sera déployé ? La section 4 expose le mode d'emploi. Il leur suffira d'interroger l'utilisateur sur son adresse électronique et tout le reste pourra être trouvé dans le DNS, en prenant la partie à droite du @ et en cherchant les SRV pour les différents services. Regardez par exemple le domaine bortzmeyer.fr comment c'est fait (enregistrements _submission._tcp, _imap._tcp et _imaps._tcp). Si la recherche des SRV ne donne rien, le MUA pourra alors, comme aujourd'hui, demander à l'utilisateur ces informations.

Notez toutefois que beaucoup d'hébergeurs DNS ne permettent pas, via le panneau de contrôle qu'ils proposent à leurs clients, d'ajouter un enregistrement SRV. Même lorsque cette possibilité existe, elle est souvent boguée comme chez Gandi où le formulaire ne permet pas d'indiquer proprement poids, priorité ou port (astuce : il faut les taper dans le champ Valeur, dans le bon ordre).

La partie de cette section concernant TLS est plus faible. Si on trouve un serveur IMAP, par exemple, le RFC demande de tenter la commande STARTTLS pour voir si elle marche. Les enregistrements SRV de notre RFC ne permettent pas d'indiquer que la gestion de TLS est obligatoire (chose que l'on peut configurer dans beaucoup de MUA) et, si TLS échoue, le MUA doit donc compter sur une configuration manuelle par l'utilisateur (du genre « Toujours utiliser TLS »). La section 6 détaille ce choix.

Notons aussi que l'utilisation des SRV peut compliquer la vérification de l'identité du serveur distant (si le domaine est mapetiteentreprise.example et que l'enregistrement SRV indique que le serveur IMAP est mail.grosfournisseur.example, l'identité du serveur dans le certificat ne sera pas mapetiteentreprise.example). La procédure du RFC 6125 doit impérativement être utilisée.

Lors de la connexion au serveur IMAP ou au serveur SMTP de soumission, il faut en général s'authentifier, ce qui implique qu'on puisse indiquer un nom d'utilisateur. Notre section 4 impose au MUA d'utiliser d'abord l'adresse électronique entière, puis la partie à gauche du @. Si ces deux tentatives échouent, il reste à demander à l'utilisateur (le nom pour la procédure d'authentification n'est en effet pas forcément dans l'adresse de courrier).

Les informations sur les serveurs peuvent être conservées pour éviter de demander au DNS à chaque fois. Mais, si la connexion a marché à un moment mais échoue par la suite, le MUA doit ré-interroger le DNS pour voir si les serveurs n'ont pas changé.

La section 4 conseillait les auteurs de MUA. La section 5 aide les fournisseurs de courrier. Le principal conseil est de permettre comme nom de connexion l'adresse électronique complète, vu que c'est la première chose que tenteront les MUA.

La section 6 est celle de la sécurité. En l'absence de signatures DNSSEC, la récupération des enregistrements SRV n'est pas sûre. Si un attaquant a réussi à empoisonner le cache du résolveur DNS, il peut rediriger le courrier vers n'importe quel serveur de son choix. Notez bien que c'est un des cas où l'argument des sceptiques sur DNSSEC « Il suffit d'utiliser TLS » ne tient pas. Sans DNSSEC pour sécuriser le SRV (le lien entre un nom de domaine et les noms des serveurs), TLS ne protégerait rien puisque les serveurs d'un attaquant peuvent parfaitement avoir un certificat valide et correspondant à leur nom.

La section 6 conseille, au cas où DNSSEC ne soit pas utilisé (ce qui est aujourd'hui le cas le plus fréquent), de vérifier que les serveurs sont dans le même domaine que le domaine de l'adresse de courrier et, sinon, de demander confirmation à l'utilisateur, procédure lourde qui annulerait une partie de l'intérêt de ce RFC (et qui n'est pas suivie dans l'exemple de bortzmeyer.fr donné plus haut).


Téléchargez le RFC 6186


L'article seul

RFC 6182: Architectural Guidelines for Multipath TCP Development

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : A. Ford (Roke Manor Research), C. Raiciu, M. Handley (University College London), S. Barre (Université catholique de Louvain), J. Iyengar (Franklin and Marshall College)
Pour information
Réalisé dans le cadre du groupe de travail IETF mptcp
Première rédaction de cet article le 23 Mars 2011


Plusieurs efforts ont déjà été déployés pour avoir un protocole de transport qui puisse utiliser plusieurs chemins simultanés, pour le cas où deux machines disposent de plusieurs moyens de se joindre. Le projet « Multipath TCP » dont voici le premier RFC se distingue par le fait que son trafic apparaîtra comme du TCP habituel, aussi bien aux applications qu'aux équipements intermédiaires situés sur le réseau.

L'idée de base de tous ces efforts est : il arrive qu'entre deux machines A et B, il existe plusieurs chemins possibles, par exemple si A et B sont tous les deux connectés à au moins deux FAI (cf. section 1.3). Utiliser simultanément ces deux chemins permettrait d'augmenter la capacité disponible (et donc le débit effectif) et d'augmenter la résilience (en cas de panne d'un chemin pendant la connexion, on utiliserait automatiquement l'autre). TCP ne permet pas cela, puisqu'il est lié à des adresses IP source et destination qui ne changent pas. Des protocoles de couche 4 comme SCTP (RFC 4960) ont déjà exploré cette voie. Mais ils souffrent d'un double problème : il faut parfois adapter les applications, qui s'attendent à la sémantique de TCP, et il faut être sûr que le chemin complet soit de l'IP propre. Or, cela est rare dans l'Internet aujourd'hui, que des incompétents ont truffé de boîtiers intermédiaires non transparents et qui rendent le déploiement de tout nouveau protocole très difficile.

Pourtant, pouvoir mettre en commun la capacité de plusieurs chemins est tellement tentant que d'autres projets ont vu le jour. C'est ainsi que le groupe de travail mptcp de l'IETF a été créé pour mettre au point une architecture, Multipath TCP et un protocole mettant en œuvre cette architecture, MPTCP (le RFC normalisant ce protocole étant encore en cours d'élaboration).

Comme son nom l'indique, l'idée de base est de ne pas trop s'éloigner du TCP actuel, afin d'assurer une compatibilité à la fois avec les applications actuelles et avec le réseau actuel, les deux points sur lesquels SCTP a largement achoppé. SCTP est donc plus propre, plus conforme à l'architecture originale de l'Internet mais Multipath TCP est peut-être plus réaliste. (Notre RFC 6182 ne cite pas SHIM6RFC 5533 - mais celui-ci possède pas mal de points communs avec SCTP, notamment un très faible déploiement dans l'Internet actuel.)

La section 2 précise les buts de l'architecture Multipath TCP. Du point de vue des fonctions, on voudrait :

  • Augmenter le débit, par l'utilisation simultanée de davantage de ressources réseaux. Plus formellement, l'utilisation de Multipath TCP doit mener à un débit au moins égal à celui du meilleur des chemins.
  • Augmenter la résistance aux pannes. La résistance totale de Multipath TCP doit être au moins aussi bonne que celle du chemin le plus fiable.

Notons que SCTP n'avait que le second but (SCTP ne permet pas actuellement d'envoyer des paquets sur différents chemins, cf. section 2.4). Naturellement, il faut en outre que le tout se fasse automatiquement : une machine MPTCP doit pouvoir trouver seule si son partenaire est également MPTCP et basculer automatiquement vers le nouveau protocole.

Mais, tout aussi importants que les fonctions sont les critères de compatibilité avec l'Internet d'aujourd'hui :

  • Compatibilité avec les applications : l'API doit rester la même et les services rendus à l'application doivent être les mêmes (délivrance des octets dans l'ordre, et sans perte). Ainsi, on doit pouvoir passer à Multipath TCP uniquement en mettant à jour le système d'exploitation, sans réécrire les applications. Il est souhaitable que l'API soit étendue pour permettre une utilisation (optionnelle) des fonctions spécifiques de Multipath TCP. Enfin, petite exception à cette compatibilité, une application qui s'attendrait à un débit très régulier peut être surprise par Multipath TCP, qui aura probablement des débits et des latences moins constants. La section 6 donne des détails sur les relations entre Multipath TCP et les applications.
  • Compatibilité avec le réseau : Multipath TCP devra fonctionner avec l'Internet tel qu'il est aujourd'hui. Or, comme l'illustrent très bien les figures 2 et 3 du RFC, l'architecture de l'Internet a changé, de fait. Elle était censée offrir un lien IP transparent, de façon à ce que la première couche « de bout en bout » soit la couche 4. En fait, l'Internet d'aujourd'hui est truffé de middleboxes qui ont souvent un rôle actif dans la couche 4 (terminaison de connexions, par exemple, ou bien filtrage des protocoles de couche 4 inconnus) et donc, de fait, la première couche de bout en bout aujourd'hui est la couche 7. La section 7 revient en détail sur cette interaction entre Multipath TCP et les middleboxes.
  • Compatibilité avec les utilisateurs existants : Multipath TCP ne doit pas « voler » de la capacité réseau aux utilisateurs du TCP normal (mais pas non plus être trop poli et les laisser tout prendre).

La deuxième exigence de compatibilité, celle avec le réseau, va donc être difficile à assurer. Mais elle est nécessaire pour le succès de Multipath TCP, les innombrables middleboxes programmées avec les pieds et configurées n'importe comment étant un puissant frein au déploiement de tout protocole de transport qui ne serait pas TCP ou UDP.

Multipath TCP a également des contraintes en terme de sécurité : la section 2.3 impose qu'il n'aggrave pas la situation par rapport à TCP.

Une fois les buts exposés, comment les atteindre ? la section 3 décrit l'architecture de Multipath TCP. En gros, Multipath TCP part des idées exposées dans « Breaking Up the Transport Logjam » de Ford & Iyengar : séparation de la couche transport en deux, une demi-couche haute « sémantique » (service aux applications, fonctionnant de bout en bout) et une demi-couche basse « flot et terminaison » (pas forcément de bout en bout, si des middleboxes sont présentes).

La section 4 de notre RFC descend ensuite dans le concret. On passe de l'architecture, Multipath TCP, au protocole, MPTCP. Le principe de base de MPTCP est de répartir chaque connexion TCP en plusieurs « sous-connexions », chacune d'entre elles apparaissant à un observateur extérieur comme une connexion TCP complète et normale (et aura donc de bonnes chances de passer à travers les NAT et autres horreurs). Les méta-informations spécifiques à MPTCP seront transportées à part. MPTCP aura les tâches suivantes :

  • Gérer les chemins : cela veut surtout dire les découvrir, essentiellement via la présence de plusieurs adresses IP sur une même machine. On pourra aussi utiliser ECMP (RFC 2992).
  • Gérer les paquets : les octets transmis par l'application doivent être répartis entre les différents chemins. Cela implique la remise dans l'ordre à la destination, puisque des paquets ont pu voyager par des chemins différents.
  • Gérer chaque sous-connexion : c'est relativement facile, chacune est une connexion TCP habituelle.
  • Contrôler qu'il n'y a pas de congestion.

La section 5 rappelle les choix techniques importants de MPTCP et leurs raisons. Ainsi de la façon de numéroter les octets. La section 5.1 explique qu'il y avait deux façons :

  • Un seul espace de numérotation, pour toute la connexion MPTCP. Cela aurait facilité le réassemblage des octets issus de chaque sous-connexion mais cela aurait rendu les sous-connexions bizarres, puisque les séquences auraient été incomplètes. Des engins comme les IDS auraient alors pu décider de couper ces connexions bizarres.
  • La solution choisie a donc été d'avoir un espace de numérotation par sous-connexion, de façon à ce que chacune de celles-ci ressemble vraiment parfaitement à une connexion TCP traditionnelle. Cela implique par contre de conserver (et de transmettre au pair) la correspondance entre les numéros de séquence de la sous-connexion et ceux de la connexion complète.

Autre choix délicat, les retransmissions en cas de perte. Chaque sous-connexion étant du TCP normal, elle a un système d'accusé de réception. Mais si des données sont perdues, par exemple lors du réassemblage des sous-connexions, on ne peut pas utiliser les mécanismes TCP normaux pour demander une réémission puisque ces données ont déjà fait l'objet d'un accusé de réception. Il y a donc également un système d'accusés de réception et de réémission au niveau de la connexion MPTCP globale.

Plusieurs des fonctions de MPTCP nécessitent donc un mécanisme de signalisation entre les deux pairs, par exemple au démarrage lorsqu'il faut signaler au pair TCP qu'on sait faire du MPTCP. La section 5.4 explore l'espace des choix : les options TCP (RFC 793, section 3.1) ont été retenues pour cette signalisation, de préférence à un encodage TLV dans les données. Les options sont la solution standard de TCP et la seule propre. Elle présentent toutefois une limitation, leur faible taille, et un risque : certaines middleboxes massacrent les options (section 7 et voir aussi par exemple l'excellente étude de Google Probing the viability of TCP extensions).

Et comment va t-on identifier une connexion MPTCP ? Traditionnellement, l'identificateur d'une connexion TCP était un quadruplet {adresse IP source, adresse IP destination, port source, port destination}. La connexion MPTCP, reposant sur plusieurs connexions TCP, ne peut pas utiliser un de ces identificateurs (puisqu'il risque de ne plus rien signifier si la connexion TCP associée casse). MPTCP devra donc développer un nouvel identificateur (section 5.6). Cela limitera d'ailleurs la compatibilité de MPTCP avec les anciennes applications, qui n'utiliseront comme identificateur celui de la première connexion TCP. Si celle-ci défaille ultérieurement, la connexion MPTCP entière pourra avoir un problème.

L'Internet étant ce qu'il est, tout nouveau protocole apporte un lot de nouveaux problèmes de sécurité (section 5.8). Le cas de la sécurité de Multipath TCP est traité plus en détail dans un futur RFC « Threat Analysis for TCP Extensions for Multi-path Operation with Multiple Addresses ». En attendant, les propriétés de sécurité essentielles attendues sont :

  • Permettre de vérifier que les pairs qui négocient une sous-connexion TCP sont bien les mêmes que ceux qui avaient négocié la première sous-connexion de la connexion MPTCP.
  • Avant d'ajouter une adresse à la liste, permettre de vérifier que le pair peut recevoir du trafic à cette adresse, pour éviter qu'un pair MPTCP ne vous fasse attaquer un tiers innocent.
  • Protéger contre le rejeu.

Atteindre ces objectifs ne va pas être facile pour MPTCP : le choix d'utiliser les options TCP limite sévèrement la quantité d'information qu'on peut transmettre et le choix de permettre qu'une middlebox s'interpose oblige à compter avec le fait que certains paquets seront modifiés en transit.

Revenons aux applications (section 6). Il y aura un certain nombre de points de détail qu'elles vont devoir gérer. Par exemple, si l'application se lie explicitement à une adresse particulière de la machine, MPTCP ne doit pas être utilisé (puisque l'application a marqué une préférence pour une adresse donnée).

L'interaction avec les équipements intermédiaires fait l'objet d'une étude plus approfondie en section 7. MPTCP ne sera pas déployé dans un réseau idéal, un réseau qui ne fournirait que de la délivrance de datagrammes IP. Au contraire, il opérera au milieu d'une jungle de middleboxes toutes plus mal programmées les unes que les autres : routeurs NAT, pare-feux, IDS, PEP, etc. Toutes ont en commun d'optimiser les applications d'aujourd'hui au détriment de celles de demain. En effet, violant la transparence du réseau, elles rendent très difficiles de déployer de nouvelles techniques qui font des choses inattendues. La section 7 donne une liste détaillées des différentes catégories de middleboxes et de leur influence possible. Ansi, certains pare-feux mélangent les numéros de séquence TCP (pour protéger les systèmes bogués qui ne choisissent pas le numéro initial au hasard). Si un tel équipement se trouve sur le trajet, l'émetteur TCP ne sait même pas quel numéro de séquence sera vu par le récepteur ! Quant aux IDS, ne connaissant pas MPTCP, ils trouveront peut-être suspect cet établissement de multiples connexions. À moins qu'ils ne comprennent pas que ces connexions sont reliées, ratant ainsi certaines informations transportées. (Imaginons une attaque transmise par MPTCP, où les différentes parties de l'attaque arrivent par des chemins séparés...).

Comme indiqué, MPTCP n'est pas encore complètement spécifié. Seule l'architecture générale est choisie. Il n'est donc pas étonnant qu'on n'en trouve pas encore d'implémentations officielle, que ce soit dans Linux ou dans FreeBSD. Néanmoins, le travail est déjà en cours sur Linux à l'Université de Louvain qu'on peut tester selon les instructions en http://mptcp.info.ucl.ac.be/.


Téléchargez le RFC 6182


L'article seul

RFC 6180: Guidelines for Using IPv6 Transition Mechanisms during IPv6 Deployment

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : J. Arkko (Ericsson), F. Baker (Cisco Systems)
Pour information
Première rédaction de cet article le 28 Mai 2011


IPv6 fait souvent peur aux administrateurs réseaux par le nombre de techniques de coexistence entre IPv4 et IPv6. Ces techniques sont variées, et inévitables, puisque la transition a pris un retard considérable, ce qui mène à devoir déployer IPv6 alors que les adresses IPv4 sont déjà épuisées. Ce RFC 6180 vise à simplifier la tâche dudit administrateur système en le guidant parmi les techniques existantes.

Il ne s'agit donc pas de normaliser le Nième protocole de transition et/ou de coexistence entre IPv6 et IPv4, plutôt de faire le point sur les protocoles existants, dont le nombre a de quoi effrayer. Mais il ne faut pas paniquer : selon le cas dans lequel on se situe, toutes ces techniques ne sont pas forcément pertinentes et il n'est donc pas nécessaire de les maîtriser toutes.

D'abord, notre RFC 6180 rappelle qu'il n'y a pas le choix : la réserve IPv4 de l'IANA a été épuisée en février 2011 et celle des RIR le sera fin 2011-début 2012. IPv6 est donc la seule solution réaliste. Le point sur la transition est fait dans le RFC 5211 et elle a commencé il y a longtemps, dans les organisations les mieux gérées. Un des points qui la freine est que l'administrateur réseaux normal, celui qui ne suit pas heure par heure les travaux de l'IETF, voit un grand nombre de techniques de coexistence IPv4/IPv6 (le Wikipédia anglophone a excellente page de synthèse sur ces techniques) et se demande « Dois-je donc déployer 6to4 et 6rd et DS-lite et NAT64 et donc maîtriser toutes ces techniques ? ». La réponse est non : selon son réseau, notre malheureux administrateur n'aura à gérer qu'une partie de ces méthodes.

Déjà, il faut comprendre ce que ces termes barbares veulent dire : la section 2 rappelle la terminologie, et les RFC à lire.

La section 3 décrit ensuite les principes suivis dans le RFC : le premier est de garder en tête le but, qui est de pouvoir continuer la croissance de l'Internet sans être gêné par des problèmes comme le manque d'adresses. Pour cela, le but final de la transition doit être le déploiement complet d'IPv6 natif dans tout l'Internet. Lorsque cela sera réalisé, toutes les techniques de transition et de coexistence pourront être abandonnées, simplifiant ainsi beaucoup la situation. Mais pour atteindre ce but lointain, il n'y a pas qu'une seule bonne méthode. Par contre, ces méthodes ont quelques points en commun. Il est par exemple essentiel de s'y prendre à l'avance : les adresses IPv4 sont déjà épuisées et une organisation qui n'aurait encore rien fait du tout, question IPv6, va avoir des problèmes. Donc, aujourd'hui, En tout cas, il n'existe pas de raison valable de retarder le déploiement d'IPv6. Ceux qui n'ont pas encore commencé devraient s'y mettre immédiatement.

Mais cela implique une longue période de coexistence avec IPv4. Pas pour tout le monde : il existe des réseaux un peu particuliers, des déploiements récents, contrôlés par une seule organisation, dans un environnement fermé (une usine, par exemple) et qui n'ont pas besoin d'échanger avec le reste du monde. Ceux-ci peuvent faire de l'IPv6 pur et ne pas lire ce RFC. Mais tous les autres doivent se poser la question « Qu'est-ce que je fais avec mes deux protocoles ? ».

Et cela va durer longtemps. Même si on peut espérer qu'un jour on éteigne la dernière machine IPv4, cela ne se produira pas avant de nombreuses années. Mëme si un réseau est entièrement IPv6, il faudra bien qu'il puisse communiquer avec des machines v4 à l'extérieur. (Le RFC ne mentionne pas le fait qu'actuellement, l'effort de la coexistence repose entièrement sur ceux qui veulent déployer IPv6. Une date importante sera celle où l'effort changera de camp et où ce sera ceux qui veulent continuer à utiliser IPv4 qui devront travailler pour cela. Cette date surviendra longtemps avant la disparition de la dernière machine IPv4.)

Ceux qui déploient IPv6 doivent donc choisir un modèle de déploiement. Le RFC 5218 rappelait, en s'inspirant de l'expérience de plusieurs protocoles, ce qui marche et ce qui ne marche pas. Certains de ces rappels semblent évidents (ne pas casser ce qui marche aujourd'hui, permettre un déploiement incrémental, puisqu'il n'y a aucune chance de faire basculer tout l'Internet d'un coup) mais sont toujours bons à garder en mémoire.

Voilà, après ces préliminaires, place aux techniques elle-mêmes, en section 4. Le début de cette section précise qu'elle n'est pas exhaustive : il existe d'autres mécanismes de coexistence/transition mais ils sont considérés comme relativement marginaux. Les techniques sont exposées dans l'ordre d'importance décroissante et les premières sont donc les plus recommandées.

Premier mécanisme de coexistence, et le plus recommandé, la double pile. Chaque machine a deux mises en œuvre des protocoles réseau, une pour IPv4 et une pour IPv6 et peut parler ces deux protocoles au choix. Ce modèle s'applique aussi bien sur la machine terminale (où les applications sont donc « bilingues ») que sur les routeurs du FAI (qui font tourner des protocoles de routage pour les deux familles, cf. RFC 6036 pour le point de vue du FAI). C'était le mécanisme de transition originellement envisagé. Le choix de la version d'IP dépend de la machine qui initie la connexion (RFC 3484), et de ce que la machine réceptrice a annoncé (par exemple dans le DNS). Ce mécanisme est simple et évite les problèmes qu'ont, par exemple, les tunnels, comme les problèmes de MTU. Comme le rappelle le RFC 4213, c'est la méthode recommandée.

Cela n'empêche pas ce modèle d'avoir des failles. D'abord, si l'adoption de ce modèle est une décision individuelle de chaque réseau, son utilisation nécessite que les deux réseaux qui communiquent aient adopté ce système. Si un client double-pile veut se connecter à un serveur en IPv6, celui-ci doit avoir une connectivité IPv6 (ce qui dépend de son FAI), doit avoir une application IPv6isée et doit avoir annoncé un AAAA dans le DNS. Autrement, on a IPv6, mais on n'observe guère de trafic. Inversement, lorsqu'un gros fournisseur de contenu active IPv6 (comme l'a fait YouTube en février 2010), le trafic IPv6 fait soudain un bond.

Une deuxième limite de l'approche double-pile est que certaines applications ne réagissent pas proprement lorsqu'un des protocoles fonctionne mais pas l'autre. De nos jours, c'est en général l'IPv6 qui a un problème et la double-pile peut alors entraîner une dégradation du service, l'application perdant bêtement du temps à tenter de joindre le pair en IPv6 au lieu de basculer tout de suite vers IPv4. Le code naïf de connexion d'un client vers un serveur est en effet (en pseudo-code) :

for Address in Addresses loop
    try
       connect_to(Address)
       exit loop
    except Timeout
       # Try the next one
    end try
end loop   

Cette approche purement séquentielle peut être pénible si les adresses IPv6 sont en tête de la liste Addresses et si le délai de garde est long. Car chaque connexion fera patienter l'utilisateur plusieurs secondes. (La durée exacte avant le Timeout dépend de la nature de la non-connectivité IPv6 - le routeur envoie-t-il un message ICMP ou pas, de ce que transmet la couche 4 à l'application, etc.) C'est pour cette raison que de nombreux gérants de gros services Internet hésitent à activer IPv6 (par exemple, ce dernier est disponible pour le service, mais n'est pas annoncé dans le DNS), de peur de pourrir la vie d'une partie, même faible, de leurs utilisateurs. C'est ainsi que www.google.com n'a d'enregistrement AAAA que pour certains réseaux, que Google estime suffisamment fiables en IPv6. Ce mécanisme de « liste blanche » où Google décide qui va pouvoir se connecter à eux en IPv6 est contestable mais n'oublions pas que les autres « gros » sites Internet ne font rien du tout.

Rendre les applications plus robustes vis-à-vis de ce problème pourrait aider (voir par exemple la technique proposée par l'ISC ou bien le très bon guide de programmation IPv6 d'Étienne Duble), surtout si ces mécanisme de connexion intelligents (tenter en parallèle les connexions v4 et v6) sont emballés dans des bibliothèques standard. Par exemple, la plupart des applications pair-à-pair gèrent relativement bien ce problème, habituées qu'elles sont à vivre dans un monde de connectivité incertaine et intermittente.

Ces défauts sont à garder en tête mais il n'en demeure pas moins que la double-pile reste la meilleure méthode, d'autant plus que de nombreux réseaux ont aujourd'hui IPv6 (le RFC cite les NREN comme Renater ou Internet2, complètement IPv6 depuis longtemps).

Une conséquence amusante de la double-pile est qu'elle nécessite une adresse IPv4 par machine. Cela ne semblait pas un problème au moment où ce mécanisme a été conçu, puisqu'il semblait possible de passer tout le monde en IPv6 avant l'épuisement des adresses v4. Comme cela ne s'est pas fait, on se retrouve aujourd'hui dans une situation où il n'y a plus d'adresses IPv4. La double pile est donc en général utilisée avec une adresse IPv6 publique et une IPv4 privée, NATée plus loin.

La double pile, c'est très bien mais que faire si on n'a pas de connectivité IPv6, et qu'on veut relier son réseau IPv6 au reste de l'Internet v6 ? La section 4.2 expose la solution des tunnels. L'intérêt des tunnels est qu'ils ne nécessitent aucune action sur les routeurs situés sur le trajet. On n'a pas à attendre que son FAI se bouge le postérieur et déploie IPv6. C'est une technique connue et éprouvée, qui est d'ailleurs utilisée pour bien d'autres choses qu'IPv6. L'inconvénient des tunnels est la complexité supplémentaire, et le fait qu'ils réduisent la MTU entraînant tout un tas de problèmes avec les sites qui bloquent stupidement l'ICMP.

Il existe plusieurs types de tunnels : les tunnels manuels du RFC 4213, des tunnels automatiques comme 6to4 (RFC 3056), les serveurs de tunnel présentés dans les RFC 3053 et RFC 5572, et bien d'autres, résumés dans le RFC 5565.

Lorsque le tunnel fait partie d'une solution gérée par un administrateur réseaux compétent, il ne pose pas de problème en soi. Mais certaines solutions techniques (comme 6to4) sont prévues pour être « non gérées » et elles ont toujours posé beaucoup de problèmes. Ainsi, elles peuvent donner aux applications l'impression qu'une connectivité IPv6 fonctionne alors qu'en fait les paquets ne reviennent pas. Beaucoup d'applications tentent alors de se connecter en IPv6 et mettent longtemps avant de s'apercevoir que cela ne marchera pas et qu'il vaut mieux se rabattre sur IPv4. 6to4 a donc beaucoup contribué à la réputation d'IPv6 comme technologie fragile et source d'ennuis. (La solution 6rd - RFC 5969, quoique dérivée de 6to4, n'a pas ces défauts.)

Pour l'instant, IPv6 est peu déployé et ce sont les gens qui veulent utiliser ce protocole qui doivent faire des efforts pour se connecter. Désormais que les adresses IPv4 sont épuisées, on commencera bientôt à voir des déploiements purement IPv6 et il faudra alors faire des efforts pour maintenir les vieux systèmes v4. Les sections 4.3 et 4.4 couvrent ces cas. En 4.3, la question est celle d'un nouvel entrant dans le monde des opérateurs qui n'a pas eu d'adresses IPv4 pour son beau réseau tout neuf et qui a donc déployé un cœur purement v6 ce qui, après tout, simplifie sa configuration. Mais ses clients, et les partenaires auxquels ses clients essaient de se connecter, sont restés en v4. Comment leur donner la connectivité qu'ils désirent ? Il va falloir cette fois tunneler IPv4 sur IPv6. Le modèle recommandé est DS-lite (Dual Stack Lite), dont le RFC n'est pas encore publié. Le principe est que le client recevra uniquement des adresses IPv4 privées, que le CPE fourni par le fournisseur d'accès encapsule les paquets IPv4 qu'émettrait un client, les tunnele jusqu'à un équipement CGN qui décapsulera, puis procédera au NAT44 classique. Le nouveau FAI aura donc quand même besoin de quelques adresses IPv4 publiques. Il existe déjà une mise en œuvre en logiciel libre de la fonction CGN, AFTR.

Autre cas, légèrement différent, est celui où le réseau local connecté à l'Internet n'a pas d'équipement IPv4 du tout. Tout beau, tout neuf, toutes ses machines (et les applications qu'elles portent) sont purement IPv6. Ce n'est pas aujourd'hui très réaliste avec des machines et des applications ordinaires mais cela pourrait arriver avec de nouveaux déploiements dans des environnements modernes. Le problème, décrit en section 4.4, est alors de se connecter quand même à d'éventuels partenaires restés v4. Une des solutions est le passage par un relais (j'en ai fait l'expérience lors d'un atelier de formation et Apache fait un très bon relais pour HTTP, permettant aux machines purement IPv6 de voir tout le ouèbe v4). Une autre solution est NAT64 (RFC 6144).

Puisqu'un certain nombre de trolls ont deversé du FUD sur la sécurité d'IPv6, la section 7, consacrée à ce sujet, est une bonne lecture. Elle rappelle que Ipv6 a en gros le même niveau de sécurité qu'IPv4, c'est-à-dire pas grand'chose et que ce sont les implémentations et les déploiements qui apportent des risques, plus que les spécifications. Par contre, chaque technique de transition a ses propres risques de sécurité, en plus de ceux d'IPv6 ou d'IPv4 mais notre RFC ne les détaille pas, renvoyant aux normes décrivant ces techniques.

Conclusion ? La section 5, après cette longue énumération de bricolages variés recentre le débat : l'essentiel est d'activer IPv6. Une fois ce principe posé, cette section rappelle des points mentionnés au début comme le fait qu'il ne faut pas appliquer aveuglément la même technique à tous les réseaux. Ainsi, un réseau tout neuf ne fera sans doute pas les mêmes choix qu'un réseau existant depuis vingt et ayant accumulé plein de technologies historiques.

La section 6 propose une bibliographie pour ceux qui veulent approfondir le sujet : plein de RFC dont les RFC 4213, RFC 4038, RFC 6036, etc. D'autre part, j'avais fait un exposé au GUILDE à Grenoble sur ces sujets (IPv6 et la transition), exposé dont les transparents sont disponibles.


Téléchargez le RFC 6180


L'article seul

RFC 6179: The Internet Routing Overlay Network (IRON)

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : F. Templin (Boeing Research & Technology
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 21 Mars 2011


Sous la houlette du groupe de travail RRG (Routing Research Group) de l'IRTF, un gros effort est en cours pour définir une nouvelle architecture de routage pour l'Internet. Cette future architecture doit permettre de poursuivre la croissance de l'Internet sans se heurter aux limites quantitatives des routeurs, et en autorisant des configurations qui sont actuellement peu pratiques comme le multi-homing. Cet effort a été synthétisé dans les recommandations du RFC 6115. La plupart des propositions d'architecture résumées dans le RFC 6115 seront sans doute publiées, chacune dans son RFC. Notre RFC 6179 ouvre la voie en décrivant le système IRON (Internet Routing Overlay Network).

IRON fait partie de la famille des architectures Map-and-Encap où les réseaux ont un identificateur indépendant de leur position dans le réseau et où les routeurs doivent utiliser un mécanisme de mapping, de correspondance entre l'identificateur connu et le localisateur cherché, avant d'encapsuler les paquets, pour qu'ils puissent atteindre leur destination via un tunnel. L'originalité d'IRON est de combiner mapping et routage pour distribuer l'information nécessaire aux routeurs. Comme les autres architectures Map-and-Encap (par exemple LISP), IRON ne nécessite pas de changement dans les machines terminales, ni dans la plupart des routeurs, mais seulement dans les routeurs d'entrée et de sortie des tunnels.

Comme IRON utilise une terminologie très spéciale, qu'on ne trouve pas dans les autres protocoles, cela vaut la peine, si on veut lire ce RFC, de bien apprendre la section 2, qui décrit le vocabulaire. IRON est donc un système d'overlay, c'est-à-dire de réseau virtuel fonctionnant au dessus d'un réseau « physique », l'Internet. Il part de RANGER RFC 5720 en le généralisant à tout l'Internet. En partant du bas (la description du RFC, c'est peut-être symptomatique, part du haut), chaque organisation connectée à IRON (un EUN pour End User Network) aurait un préfixe à elle, un identificateur, nommé le EP (EUN Prefix). Ces préfixes viennent de préfixes plus larges, les VP (Virtual Prefix), qui sont alloués par de nouvelles organisations, les VPC (Virtual Prefix Companies). Ces organisations n'ont pas d'équivalent dans l'Internet actuel : les VPC pourraient être des FAI mais ce n'est pas obligatoire. Le RFC ne donne aucun détail sur les points non-techniques de cette architecture (par exemple, comment une VPC gagnera sa vie ? Si on change de VPC, pourra t-on garder son préfixe ?) considérant que ces questions sont hors-sujet pour une spécification technique.

Les routeurs IRON se connectent entre eux par des liens NBMA qui sont simplement des tunnels au dessus de l'Internet existant.

Toujours dans le vocabulaire original (IRON n'utilise pas les termes d'ITR - Ingress Tunnel Router - et ETR - Egress Tunnel Router - probablement parce que son architecture ne colle pas bien à ce modèle), IRON repose sur trois types de routeurs (appelés collectivement agents) :

  • Le client est le routeur chez l'EUN, l'organisation terminale (entreprise, association, université, etc). Il connait les EP de l'organisation et se connecte au « réseau » IRON (éventuellement via du NAT). La section 3.1 détaille ces clients.
  • Le serveur appartient à la VPC et il reçoit les « connexions » des EUN qui hébergent les clients. La section 3.2 le décrit complètement.
  • Le relais appartient également à la VPC et assure l'interconnexion avec l'Internet actuel, pour les correspondants qui ne sont pas dans IRON. Il va donc parler BGP avec les routeurs actuels et utiliser les protocoles IRON avec les autres relais. Il est présenté complètement en section 3.3.

Les détails de l'architecture sont ensuite détaillés en sections 3 à 6. Les agents IRON (les trois sortes de routeurs présentées plus haut) forment des tunnels entre eux, en utilisant la technique VET (Virtual Enterprise Traversal, RFC 5558) et encapsulent selon le format SEAL (Subnetwork Encapsulation and Adaptation Layer, RFC 5320). Curieusement, l'auteur prend soin de préciser que SEAL permet de tunneler d'autres protocoles qu'IP et il cite CLNP, ce qui donne une idée de l'âge des idées qui sont derrière SEAL...

SEAL dispose d'un protocole d'échange d'informations sur les routes, les MTU, etc, SCMP (SEAL Control Message Protocol) et c'est lui qui permet à l'overlay IRON de fonctionner.

Chaque VPC représente donc un morceau d'un patchwork global. Les morceaux sont connectés entre eux via l'Internet public. Le client final, lui, doit se connecter à l'Internet puis acquérir une connectivité IRON auprès d'une VPC, et s'équiper d'un routeur client qui va relier son EUN (son réseau local) à la VPC.

Pour amorcer la pompe (section 5), chaque relais est configuré avec la liste des VP qu'il va servir, la liste des serveurs (les routeurs des VPC), et avec celle de ses voisins BGP. Avec ces derniers, il établit des liens comme aujourd'hui et annonce sur ces liens les VP. Avec les serveurs, le relais découvre la correspondance entre les EP, les identificateurs des réseaux IRON et les serveurs. (Rappelons que les identificateurs, EP et VP, ont la même forme que des adresses IP et peuvent donc être annoncés comme tels aux routeurs BGP actuels.)

Les serveurs, eux, sont nourris avec la liste des relais, auxquels ils vont transmettre les VP qu'il servent. Ils attendent ensuite les connexions des clients, apprenant ainsi petit à petit les EP connectés, que les serveurs transmettront aux relais.

Les clients, eux, auront besoin de connaître les serveurs de leur VPC, ainsi que leurs EP, et un moyen de s'authentifier.

Une fois tout ceci fait, les routeurs n'ont plus qu'à router les paquets comme aujourd'hui (section 6, qui décrit les différents cas, notamment selon que le destinataire du paquet est dans IRON ou pas ; par exemple, le cas du multi-homing est en section 6.5.2, qui précise qu'un client peut avoir plusieurs localisateurs pour un même EP).

Et d'une manière plus générale, comment cela va se passer en pratique ? La section 7 se lance dans certains détails concrets. Par exemple, comme le routage à l'intérieur d'IRON est souvent sous-optimal, mais qu'un mécanisme d'optimisation des routes permet de les raccourcir par la suite, le premier paquet de chaque flot aura sans doute un temps de trajet bien supérieur à celui de ses copains.

Et, comme toute solution utilisant des tunnels, IRON aura sans doute à faire face à des problèmes de MTU, que cette section mentionne, mais jette un peu rapidement à la poubelle.

Toujours pour ceux qui s'intéressent aux problèmes concrets, l'annexe B est une très bonne étude des propriétés de passage à l'échelle d'IRON.

IRON ne semble pas avoir été testé, même en laboratoire, même tout simplement dans un simulateur. Et mon avis personnel ? Je dois avouer n'avoir pas tout compris et avoir la sensation inquiétante que ce n'est pas uniquement une limite de mon cerveau, mais que l'architecture d'IRON reste encore insuffisamment spécifiée.


Téléchargez le RFC 6179


L'article seul

RFC 6177: IPv6 Address Assignment to End Sites

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : Thomas Narten (IBM), Geoff Huston (APNIC), Lea Roberts (Stanford University)
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 27 Mars 2011


Ce RFC vient remplacer le RFC 3177 et modifier assez sérieusement les recommandations en matière d'allocation d'adresses IPv6 aux sites situés aux extrêmités du réseau (entreprises, universités, particuliers, à l'exclusion des FAI et des opérateurs). Le RFC 3177 recommandait, en gros, de donner un préfixe de même longueur, un /48, à tout le monde. Ce nouveau RFC 6177 met un sérieux bémol à cette recommandation.

Le RFC 3177 avait été publié en 2001 et mis en œuvre par les RIR dans leurs politiques d'allocation d'adresses (celle du RIPE-NCC est en http://www.ripe.net/ripe/docs/ipv6policy.html). À partir de 2005, plusieurs critiques se sont fait jour (voir par exemple la proposition 2005-08), menant à une révision de ces politiques et à ce nouveau RFC 6177. Les critiques portaient aussi bien sur la technique (un /48 n'est-il pas excessif ?) que sur la politique (est-ce vraiment le rôle de l'IAB et de l'IETF de recommander des politiques d'allocation ?). Résultat, le « /48 pour tous » n'est plus la politique officielle.

La section 1 de notre nouveau RFC rappele les principaux changements par rapport au RFC 3177 :

  • La possibilité de distribuer des /128 (une seule adresse IPv6) est retirée, un site comprend forcément plusieurs machines,
  • Les valeurs numériques explicitement indiquées par le RFC 3177, /48, /64 et /128, ne sont plus mentionnées, de crainte qu'elles ne deviennent « sacrées » et soient, par exemple, codées en dur dans certaines mises en œuvre d'IPv6, ce qui n'avait pas été prévu,
  • Et, la plus spectaculaire, le retrait de la recommendation d'un /48 pour tous les sites. Il n'y a désormais plus de recommandation officielle de l'IETF, la taille des allocations devant être décidée par les RIR. (On notera que c'est un changement de gouvernance : les RIR, émanation des opérateurs réseau, sont moins favorables que l'IETF aux demandes des utilisateurs.) À titre d'exemple, voici la politique d'APNIC.

Mais alors, que reste-t-il du RFC 3177 ? Le principe comme quoi un site ne devrait pas avoir à geindre et à supplier pour avoir suffisamment d'adresses. En IPv4, la rareté des adresses justifiait les obstacles mis devant les utilisateurs mais, en IPv6, cet argument ne joue plus. Les sites devraient donc toujours avoir les adresses dont ils ont besoin, et ne jamais être contraints à utiliser des techniques comme le NAT pour économiser des adresses, ces économies étant tout à fait inutiles avec IPv6.

La question de l'allocation d'un /48 aux sites d'extrêmité est discutée dans la section 2. La recommandation du RFC 3177 était fondée sur trois motivations :

  • Garantir que ces sites auraient suffisamment d'adresses et donc décourager fortement les pratiques malthusiennes de certains FAI comme par exemple, celle de ne donner qu'une seule adresse IPv4, ce qui est compréhensible vue la pénurie mais gêne les sites qui ont plusieurs machines, ce qui est pourtant banal aujourd'hui, même chez le particulier. La plupart du temps, obtenir autant d'adresses IPv4 qu'on a de machines nécessite de passer à un abonnement beaucoup plus cher, sans que cela soit justifié par le coût de ces adresses.
  • La seconde motivation, et qui était souvent oublié par les adversaires du « /48 pour tous », était de faciliter le changement de FAI. Si certains FAI fournissent un /56 à un site et d'autres un /60, le passage du premier au second nécessitera de refaire les plans d'adressage (puisqu'il y a moins de sous-réseaux disponibles) alors que, si tout le monde propose un /48, le changement de fournisseur ne nécessite qu'un changement de préfixe (ce qui est en général très simple avec IPv6). Mëme chose pour l'administration du DNS, les zones dans ip6.arpa seront plus simples à gérer si on change juste de préfixe, sans avoir à réorganiser ses sous-réseaux. L'idée d'une même taille d'allocation pour tous (de la grande université au particulier) est donc une mesure de protection du client, de garantie qu'il n'y aura pas d'obstacle artificiel à un changement de fournisseur.
  • La troisième motivation de la recommandation du RFC 3177 était de faciliter la croissance des réseaux. Ceux-ci peuvent souvent dépasser les prévisions (une école connecte le bureau du directeur, puis une salle de classe, puis finalement on connecte tout) et les plans d'adressage prudents d'IPv4, conçus pour ne demander que le nombre d'adresses strictement nécessaire, ont souvent gêné la croissance d'un réseau.

Mais, alors, quels sont les problèmes perçus avec cette recommandation du « /48 pour tous » ? D'abord, certains trouvent qu'elle mène au gaspillage. (Je pense personnellement que c'est un argument subjectif, sans base scientifique : il existe 280 billions de /48 disponibles, ce qui fait qu'on n'épuisera pas IPv6 en en donnant un à chacun.) Les partisans de cet argument disent souvent qu'on pourrait ne donner qu'un /64 aux particuliers (ce que fait aujourd'hui un FAI comme Free), oubliant qu'une maison bien dotée en appareils numériques peut avoir besoin de plusieurs réseaux, pas seulement d'adresses, et que, avec l'auto-configuration des adresses IPv6, il faut un /64 par réseau. Notre RFC 6177 demande donc qu'on donne à tous davantage qu'un /64 (un /56 est cité comme possibilité).

Notons que notre RFC 6177 ne traite pas explicitement le cas des hébergeurs de serveurs dédiés comme Gandi ou OVH. Par exemple, Gandi ne permet apparemment qu'une seule adresse IPv6 par machine, rendant ainsi difficile d'y faire tourner plusieurs serveurs. (Pour OVH, l'information est en ligne, avec l'orthographe habituelle de ce fournisseur.)

Le RFC 3177 contenait d'autres points (section 3). Par exemple, il rappelait explicitement que la règle d'un /48 pour tous limitait le pouvoir des intermédiaires : sans avoir à demander, sans remplir de paperasserie, l'utilisateur avait droit à une quantité d'adresses suffisante. C'est hélas quelque chose qui sera différent désormais, l'utilisateur devra à nouveau affronter un bureau insensible pour avoir la quantité d'adresses nécessaire.


Téléchargez le RFC 6177


L'article seul

RFC 6175: Requirements to Extend the Datatracker for IETF WG Chairs and Authors

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : E. Juskevicius (TrekAhead)
Pour information
Première rédaction de cet article le 11 Mars 2011


Comme toute organisation qui manipule de grandes quantités de documents, et des processus formalisés complexes, l'IETF a besoin de logiciels qui mettent en œuvre ces processus. Le principal outil est le Datatracker et ce RFC 6175 est le cahier des charges pour une nouvelle extension du Datatracker.

Le Datatracker sert entre autres à suivre l'état des Internet-Drafts. Il était traditionnellement très détaillé pour la phase d'évaluation à l'IESG de ces documents, et nettement moins précis pour les autres phases. Ce service était très réclamé depuis longtemps. Ce cahier des charges demande donc que le Datatracker soit mis à jour pour gérer les états décrits par le RFC 6174.

Quelques rappels, en section 2, pour les gens qui ne suivent pas l'évolution du vocabulaire IETF. Tous les Internet-Drafts ne sont pas forcément liés à un groupe de travail de l'IETF. Ceux qui le sont, parce qu'un groupe a décidé de les adopter, sont qualifiés de WG draft. Leur nom est du type draft-ietf-wgname-.... Ces drafts, et ceux qui sont candidats à l'adoption mais n'ont pas encore été adoptés, sont ensemble les associated with a WG. Dans le cas où ils ne sont pas encore adoptés, leur nom inclus l'acronyme du groupe de travail mais ne commence pas par draft-ietf. Enfin, tous les autres Internet-Drafts sont qualifiés d' « individuels ».

Les exigences générales sur le « nouveau » Datatracker figurent en section 3. Chacune est numérotée. La première, R-001, est que le Datatracker doit permettre aux présidents des groupes de travail de l'IETF de saisir directement l'état des I-D, en suivant les états décrits dans le RFC 6174. Parmi les autres exigences (consultez le RFC pour une liste complète), le fait que tout changement doit être estampillé, lié à une personne précise (R-007) et que la date et l'heure de ce changement soient affichées. Le Datatracker doit étendre la machine à états existante (illustrée en https://datatracker.ietf.org/images/state_diagram.gif), pas la remplacer (R-011). Et les présidents d'un groupe de travail doivent pouvoir agir sur l'état d'un I-D, indépendemment de son statut à l'IESG (R-012).

La section 4 est consacrée aux questions d'autorisation. En lecture, le Datatracker est accessible à tous (R-013), l'IETF tirant une grande fierté de son ouverture au public (contrairement à la majorité des SDO, qui travaillent derrière des portes closes). Mais en écriture, les personnes qui peuvent modifier l'état d'un I-D doivent d'abord s'authentifier auprès du Datatracker (et inutile de dire que l'IETF n'utilise pas Facebook Connect). La section 11 note d'ailleurs les conséquences que cela peut avoir en matière de sécurité.

Les présidents des groupes de travail doivent avoir la possibilité (section 4.2) de modifier l'état de tous les Internet-Drafts de leur groupe, en restant dans la liste d'états pré-définie (cf. RFC 6174 et voir aussi la section 5.1), peuvent désigner jusqu'à trois délégués pour les aider, etc. Une autre population intéressante est celle des pasteurs (sheperds, cf. RFC 4858). Ceux-ci (section 4.4) sont chargés de suivre un document particulier et doivent donc pouvoir déposer le write-up, le formulaire rempli qui indique à l'IESG les points importants du document (voir aussi la section 5.3). Au sommet de cette série de personnes privilégiées, se trouvent évidemment les directeurs de secteurs (Area Directors), qui couvrent chacun plusieurs groupes de travail et doivent également pouvoir mettre à jour l'état des documents (section 4.5).

Certains états des documents posent des problèmes particuliers et la section 6 les énumère. Ainsi, un document peut être garé (parked document, section 6.4) lorsqu'il a perdu son auteur. Le directeur de secteur a alors des pouvoirs supplémentaires, comme de le transférer à un autre groupe de travail. Plus triste, un document peut aussi mourir (dead document, section 6.5) lorsque tout travail le concernant a été abandonné. Là encore, le directeur peut le transférer.

Jusqu'ici, on a parlé des changements manuels, comme lorsque le président d'un groupe de travail met à jour l'état d'un I-D (Internet-Draft). Y a-t-il aussi des changements automatiques ? Oui, et la section 7 liste les cas où le Datatracker doit agir seul. Par exemple, si une nouvelle version d'un document a un nom qui commence par draft-ietf, le document devient automatiquement document d'un groupe de travail (avant, c'était juste une convention : désormais, cela fait partie des règles mises en œuvre automatiquement).

Quelles sont les informations qui doivent être affichées par le Datatracker ? Les sections 8 et 9 les définissent. Par exemple, le Datatracker doit garder trace de l'historique complet du document puisqu'il doit pouvoir le montrer à quiconque a les droits d'écriture (la foule anonyme n'a droit qu'à l'affichage de l'état actuel).


Téléchargez le RFC 6175


L'article seul

RFC 6174: Definition of IETF Working Group Document States

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : E. Juskevicius (TrekAhead)
Pour information
Première rédaction de cet article le 11 Mars 2011


Le processus de production de normes au sein de l'IETF était historiquement informel et peu documenté. Petit à petit, il s'est formalisé (voire ossifié) et a même reçu l'aide de logiciels permettant de suivre l'avancement des travaux. Ce RFC de processus décrit des nouveaux états que peut avoir un document en cours de discussion à l'IETF.

Une des particularités de l'IETF est son ouverture. Tout le monde doit pouvoir suivre l'état d'avancement des travaux, via l'Internet. C'est ce que permet par exemple le Datatracker de l'IETF qui donne accès à l'état (en février 2011) du document sur la syntaxe des TLD (apparemment abandonné, et tant mieux), à celui de la documentation de l'AS 112 (adopté par un groupe, mais perdu dans les sables bureaucratiques depuis très longtemps), à celui sur l'enregistrement DNS CERT (pas adopté par un groupe de travail), ou à celui sur le protocole LISP (en plein développement par un groupe de travail).

Les informations affichées par le Datatracker n'étaient pas toutes documentées et certaines, non actuellement affichées, pourraient être nécessaires. Ce RFC 6174 documente donc les états possibles des documents.

Le Datatracker gère bien d'autres choses que les documents, puisqu'il donne aussi accès aux revendications d'appropriation intellectuelle, et à d'autres aspects de la vie de l'IETF. Concernant le document, la version du Datatracker en service fin 2010 ne permettait de suivre que les documents présentés à l'IESG pour évaluation. Avant cela, il ne savait pratiquement d'un document que le fait qu'il soit Active (en cours de discussion) ou Expired (les Internet-Drafts ont une durée de validité de six mois). Or le processus (décrit dans le RFC 4844 est bien plus riche.

Comme le rappelle la section 2 de notre RFC, un Internet-Draft peut être complètement individuel ou bien être un Working Group I-D si un groupe de travail IETF a décidé de l'adopter et de travailler sur ce document. Dans ce cas, sa vie au sein du groupe passe par plusieurs stades qui étaient ignorés du Datatracker.

La section 3 résume en effet l'état du Datatracker fin 2010. Si ce dernier connaissait tous les détails de l'évaluation à l'IESG, la vie du document avant son passage devant cet aréopage était nettement moins détaillé, le Datatracker ne prenant en compte que la disponibilité du document. La section 3.1 donne une liste complète. Celle-ci inclut, comme vu plus haut, Active et Expired, mais aussi des états comme Replaces et Replaced-by qui indique le remplacement d'un Internet-Draft par un autre, équivalent. Cela se produit typiquement lors de l'adoption d'un draft par un groupe de travail. Si le document était nommé draft-authorname-topic-nn, il devient alors draft-ietf-wgname-topic-00. À noter qu'il n'existe pas de moyen automatique pour identifier ce remplacement (les Internet-Drafts n'ont pas de méta-données structurées), le président du groupe de travail doit l'indiquer explicitement.

Une fois le document terminé par le groupe de travail, il passe à l'IESG pour évaluation. Cette phase est celle qui a suscité le plus de formalisation et celle-ci est décrite dans la section 3.2 (avec l'intégralité des états dans l'annexe A). Un Internet-Draft peut ainsi être, entre autres :

  • Publication requested, le premier stade, suivant les procédures de la section 7.5 du RFC 2418.
  • AD evaluation qui indique qu'un AD (un Area Director, la personne coresponsable d'une zone de travail de l'IESG comme le routage, la sécurité, les applications) est en train d'évaluer le document.
  • IESG evaluation qui indique que le document est désormais évalué par toute l'IESG, c'est-à-dire par tous les AD. Chacun peut émettre une objection bloquante, connue sous le nom (fort mal choisi) de DISCUSS.

Quels sont les nouveux états possibles pour un document, créé par ce RFC 6174 ? La section 4 les détaille et s'appuie pour cela sur une machine à états (figure 1). Ils sont déjà mis en œuvre dans le Datatracker et se trouvent simplement documentés ici, par exemple (ce n'est pas une liste complète) :

  • Call for adoption quand un document est encore individuel mais que son auteur a demandé qu'un groupe de travail l'adopte comme document de travail officiel du groupe,
  • Adopted, une fois que c'est fait ; le document prendra alors un nom du genre draft-ietf-workingroupname-topic-00,
  • Working Group document une fois que le travail du groupe a effectivement commencé,
  • Working Group Last Call ; le sigle WGLC apparît souvent dans les listes IETF car cet état est une partie importante (quoique optionnelle, cf. RFC 2418) du folklore de cette organisation. C'est le dernier moment où le groupe peut donner son avis avant que le document, transmis à l'IESG, ne lui échappe.
  • Working Group consensus, waiting for write-up, qui indique que le document fait l'objet d'un large consensus dans le groupe, et qu'il a juste besoin d'un write-up, le formulaire qui accompagne tout envoi à l'IESG et qui explique à celle-ci les points importants (comme l'existence de mises en œuvre, l'état effectif du consensus, les menaces d'appel, etc, voir RFC 4858),
  • Submitted to IESG, lorsque le travail du groupe est fini,

Outre ces états, qui sont mutuellement exclusifs, le document peut porter un certain nombre d'étiquettes indiquant des points importants du processus, parmi lesquelles :

  • Awaiting Expert Review/Resolution of Issues Raised qui indique qu'un examen du document par un expert du domaine est en cours (de tels examens existent, par exemple, pour toutes les MIB, qui sont vérifiées par un spécialiste ès-MIB),
  • Waiting for Referencing Document, le document dépend d'un autre document, pas encore prêt,
  • Revised I-D Needed - Issue raised by WGLC, lorsque le dernier appel à commentaires dans le groupe de travail a suscité des problèmes suffisamment sérieux pour justifier un nouvel ID (Internet-Draft).

Enfin, un autre champ est spécifié, en section 5. Tout document doit avoir un « niveau de normalisation visé » qui indique si le groupe de travail veut voir le futur RFC sur le chemin des normes, ou simplement « Pour information » ou encore purement « Expérimental ». (Ces niveaux sont expliqués dans le RFC 2026.)

La mise en œuvre de ces nouveaux états dans le Datatracker se fera suivant le cahier des charges contenu dans le RFC 6175.

Une lecture intéressante sur le sujet de la vie des Internet-Drafts est « Guidelines to Authors of Internet-Drafts ».


Téléchargez le RFC 6174


L'article seul

RFC 6168: Requirements for Management of Name Servers for the DNS

Date de publication du RFC : Mai 2011
Auteur(s) du RFC : W. Hardaker (Sparta)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 4 Mai 2011


Traditionnellement, les serveurs DNS étaient gérés par des mécanismes spécifiques au logiciel utilisé. BIND a son rndc, Unbound son unbound-control (voir des exemples à la fin), d'autres logiciels utilisent d'autres méthodes et on n'avait pas de moyen facile de gérer un ensemble hétérogène de serveurs. En outre, ces programmes n'étaient pas prévus pour des autorisations précises (modifier telle zone mais pas telle autre) et cela rendait difficile de déléguer la gestion d'une partie du service à un tiers. L'IETF est donc lancée depuis quelques années dans un effort pour mettre en place un mécanisme standard de gestion à distance des serveurs DNS et ce RFC 6168 en est le cahier des charges formel.

Car c'est un vieux projet ! Une des étapes avait été la publication, il y a plus de quatre ans, du brouillon « Requirments for the Nameserver Communication protocol ». Il y a eu ensuite un groupe de travail restreint, nommé DCOMA, dont j'ai fait partie. Le projet a avancé à une allure de tortue mais, au moins, il a désormais un cahier des charges figé. Avant même le document cité plus haut, un effort de normalisation avait mené à deux MIB, décrites dans les RFC 1611 et RFC 1612, qui n'avaient jamais été réellement déployées et ont été officiellement abandonnées par le RFC 3197.

L'annexe A rassemble quelques études de cas, pour illustrer à quoi pourrait servir un tel protocole. Par exemple, en A.1 se trouve le cas de zones locales non-standard comme un .prive ou .local. Si des TLD locaux sont une mauvaise idée, ils n'en sont pas moins très utilisés et des domaines purement locaux peuvent avoir un sens dans certains cas. Actuellement, pour qu'un tel système fonctionne, il faut mettre des directives stub ou forward dans tous les résolveurs de l'organisation, et garder ces résolveurs (qui peuvent être de marques différentes) synchronisés. D'une façon générale, gérer un pool de résolveurs DNS qui doivent avoir la même configuration (par exemple les mêmes clés DNSSEC, cf. annexe A.3) est une tâche courante pour un FAI et plutôt pénible. Le futur protocole de contrôle pourrait faciliter l'automatisation de cette tâche.

A.2 propose un autre cas, dans l'optique de résilience maximale d'une zone DNS : le RFC 2182 recommande à juste titre qu'une zone DNS soit servie par plusieurs serveurs de noms, ne partageant pas de SPOF. Une solution fréquente est l'hébergement réciproque des zones d'un partenaire. Par exemple (au 12 avril 2011), l'AFNIC héberge un serveur secondaire de .nl et SIDN (Stichting Internet Domeinregistratie Nederland) a un serveur secondaire de .fr. La configuration correspondante est actuellement maintenue à la main, ou par des logiciels ad hoc. Ainsi, si un TLD dont le serveur secondaire est à l'AFNIC, veut tout à coup autoriser le transfert de zones, ou au contraire le restreindre à certaines adresses IP, il doit envoyer un message et attendre qu'un technicien de l'AFNIC ait changé la configuration. De même, si deux hébergeurs DNS assurent réciproquement un service de secours en hébergeant les zones de l'autre, la création d'une nouvelle zone doit actuellement être automatisée par des moyens spécifiques du logiciel utilisé. À noter que ce cas nécessite des autorisations à grain fin, comme rappelé en section 4.4.

Ce cahier des charges concerne à la fois les serveurs faisant autorité (par exemple ceux de .FR) que les récurseurs (par exemple les résolveurs de votre FAI). La section 2.2 donne des détails sur les types de serveurs qui seront gérés (les maîtres, les esclaves, et les récurseurs). Les stub resolvers (la bibliothèque de résolution de noms sur votre machine) sont exclus du champ d'application de ce projet. De même, le futur protocole qui mettre en œuvre ces exigences ne s'occupera que de la configuration des serveurs, pas des données servies (pour lesquelles il existe déjà des protocoles standard de transmission, cf. RFC 2136 et RFC 5936).

Le RFC est écrit sous forme d'une suite d'exigences, chacune dans sa propre section. Donc, le numéro de section identifie l'exigence. Voyons les principales.

L'exigence 2.1.1 concerne la taille : parmi les serveurs faisant autorité, il y en a avec peu de zones mais beaucoup de données dans ces zones (les serveurs des TLD par exemple) et d'autres avec beaucoup de toutes petites zones (un hébergeur DNS qui accueille des centaines de milliers de mapetiteentreprise.com). La solution doit convenir pour toutes les tailles.

La solution pourra permettre la découverte automatique des serveurs de noms existant sur le réseau mais ce n'est pas obligatoire (exigence 2.1.2).

Elle devra fonctionner pour des serveurs dont la configuration change souvent (nombreuses zones ajoutées et retirées par heure, par exemple, exigence 2.1.3).

Pour contrôler quelque chose, il faut un modèle décrivant la chose en question. L'exigence 2.1.5 impose donc la création d'un modèle de données d'un serveur de noms. Enfin, 2.1.6 impose que la nouvelle solution n'interfère pas le service principal, le DNS lui-même.

La section 3 décrit les classes d'opérations de gestion à implémenter :

  • Contrôle (arrêter, redémarrer),
  • Configuration (ajouter une zone, ajouter une clé de confiance DNSSEC, etc),
  • Surveillance de l'état du serveur (pour intégrer dans des solutions comme Nagios),
  • Déclenchement d'alarmes.

Le futur protocole devra gérer toutes ces classes.

Quelles sont les opérations à faire sur un serveur de noms ? La section 3.1 liste les plus importantes :

  • Démarrer et arrêter le serveur,
  • Recharger la configuration,
  • Recharger une zone (ou toutes les zones),

À noter que l'opération « démarrer le serveur » est la seule qui ne puisse pas être mise en œuvre dans le serveur lui-même.

Comme certaines de ces opérations peuvent être très longues (la seule lecture du fichier de zone d'un gros TLD peut prendre du temps), la même section demande en outre que le futur protocole ait un mécanisme de notification asynchrone (« fais ça et préviens-moi quand c'est fini »).

Et question configuration, que doit-on pouvoir configurer ? La section 3.2 donne une liste :

  • Les zones à servir (pour un serveur maître) ; à noter qu'il existe déjà des protocoles standard pour transmettre les données contenues dans ces zones (RFC 5936, RFC 1995 et RFC 2136),
  • La liste des zones à servir ; on doit pouvoir ajouter et retirer des noms à cette liste (« tu fais maintenant autorité pour foobar.example et ton maître est 2001:db8:2011:04:11::53 »), ce qui n'est pas possible de manière standard actuellement,
  • Les clés de confiance utilisées dans des protocoles comme DNSSEC,
  • Les clés utilisées par TSIG (RFC 2845),
  • Les autorisations : qui a le droit de faire des mises à jour dynamiques (RFC 2136), qui a le droit de transférer le contenu de la zone, qui a le droit de faire des requêtes récursives, etc.

Le protocole, on l'a vu, doit également permettre la surveillance du bon fonctionnement du serveur. Des exemples de données utiles sont (section 3.3) :

  • État du serveur (« fonctionnement normal », « en cours d'arrêt », etc),
  • Statistiques de base, comme le nombre de requêtes traitées, le nombre d'erreurs, etc,
  • Liste des zones actuellement servies,
  • Alertes de sécurité.

Le serveur doit pouvoir transmettre ces informations à la demande du logiciel de surveillance, mais aussi pouvoir sonner des alarmes sans qu'on lui ait rien demandé (section 3.4) :

  • Changement d'état du serveur (« ça y est, je suis prêt » ou au contraire « plus de mémoire, j'arrête tout »),
  • Problème de sécurité (tentative de transfert d'une zone refusée, par exemple).

Un tel protocole, riche en fonctions, peut attirer l'attention des méchants : arrêter à distance un serveur de noms, sans avoir besoin de se connecter sur la machine, est tentant. D'où la section 4 qui pose les exigences de sécurité du protocole (voir aussi section 6). La plus importante est l'exigence d'une authentification mutuelle : le serveur de noms doit pouvoir authentifier le logiciel de gestion et réciproquement. Il est également nécessaire que le protocole soit confidentiel : des informations secrètes (comme les clés TSIG) seront parfois transmises par ce canal. Et, une fois l'authentification faite, le protocole doit permettre d'exprimer des autorisations détaillées : tel client peut ajouter des zones mais pas redémarrer le serveur, tel client peut lire toutes les informations mais n'en modifier aucune, etc.

La section 5 est ensuite un pot-pourri d'exigences supplémentaires pour le futur protocole de contrôle des serveurs de noms. On y trouve les grands classiques comme l'extensibilité dans le temps (futures fonctions) et dans l'espace, via des extensions spécifiques à un vendeur (un logiciel donné peut toujours avoir des fonctions très spéciales, trop spéciales pour être normalisées, mais qu'il serait intéressant de contrôler via le protocole).

Pour avoir une idée plus précise des fonctions d'un tel protocole, on peut regarder ce qui existe aujourd'hui. Comme exemple de serveur faisant autorité, essayons BIND. Son outil de contrôle à distance se nomme rndc. Il y a plusieurs moyens de le configurer (la plupart des paquetages binaires de BIND font tout cela automatiquement), ici, je vais générer une clé d'authentification et un fichier de configuration à la main. La clé est une clé secrète partagée, on la génère avec dnssec-keygen :

% dnssec-keygen -a hmac-md5 -n HOST -b 128 samplekey

Le fichier produit, ici Ksamplekey.+157+06915.private, contient le secret :

% cat Ksamplekey.+157+06915.private
...
Key: 7fCXQYhOXW+jkpEx9DuBdQ==
...

On va alors créer le fichier de configuration de rndc. Comme il contient un secret (la clé), il faudra s'assurer que ce fichier ait les bonnes protections :

options {
      default-server  localhost;
      default-key     samplekey;
};

server localhost {
      key             samplekey;
      addresses   { ::1 port 9153; };
};

key samplekey {
      algorithm       hmac-md5;
      secret          "7fCXQYhOXW+jkpEx9DuBdQ==";
};

Et il faut configurer le serveur de noms, dans son named.conf. Ici, le protocole de contrôle n'acceptera que localhost (::1) sur le port 9153 (la valeur par défaut est 953) :

key samplekey {
      algorithm       hmac-md5;
      secret          "7fCXQYhOXW+jkpEx9DuBdQ==";
};

controls {
     inet ::1 port 9153
             allow {::1;}
             keys {samplekey;};
};

Je me répète, attention à la sécurité. Car, s'il peut lire la clé, un utilisateur pourra arrêter BIND, supprimer des zones, etc.

Voyons maintenant des exemples d'utilisation :

% rndc status
version: 9.8.0
number of zones: 2
...
server is up and running

Cette commande était bien inoffensive. Mais on peut en faire d'autres comme :

  • Recharger une zone (rndc reload $MAZONE),
  • Arrêter le serveur (rndc stop),
  • Ajouter une nouvelle zone à servir (rndc addzone example.com '{ type master; file "example.com"; };'),
  • Et bien d'autres...

À la lumière du cahier des charges, que manque t-il à BIND ? Les grandes lignes y sont mais il manque pas mal de détails comme les notifications asynchrones, les changements d'ACL et peut-être la finesse des autorisations. rndc addzone nécessite une option spéciale dans named.conf mais elle s'applique à toutes les zones et, de toute façon, on ne peut pas la lier à certaines clés seulement. Une fois qu'on a un accès au serveur, c'est un accès total.

Comme exemple de serveur récursif, prenons Unbound. La configuration se fait dans le unbound.conf à peu près comme ceci (même adresse et port qu'avec BIND plus haut) :

remote-control:
	control-enable: yes
	control-interface: ::1
	control-port: 9153
	server-key-file: "unbound_server.key"
	server-cert-file: "unbound_server.pem"
	control-key-file: "unbound_control.key"
	control-cert-file: "unbound_control.pem"

Les certificats X.509 utilisés pour l'authentification peuvent facilement être créés avec unbound-control-setup. Le programme de contrôle du serveur utilise le même fichier de configuration unbound.conf (contrairement à BIND) :

% unbound-control status
version: 1.4.5
verbosity: 4
threads: 1
modules: 2 [ validator iterator ]
uptime: 206 seconds
unbound (pid 5315) is running...

et on peut faire plein de choses avec ce programme comme arrêter le serveur (unbound-control stop), afficher d'utiles statistiques (nombre de requêtes, nombre de succès et d'échecs de cache, etc, avec unbound-control stats), activer ou désactiver le relayage vers un autre serveur (unbound-control forward 2001:db8:42::53), vider le cache pour une zone donnée (unbound-control flush_zone example.com, notez qu'unbound_control a d'autres commandes de vidage, plus ou moins subtiles), etc.

Par rapport aux exigences de notre RFC 6168, on note que unbound-control ne permet pas de changer les clés de confiance utilisées par le serveur. Il ne peut pas non plus afficher les zones définies localement sur le récurseur (mais il permet d'en ajouter). Et la finesse des autorisations est insuffisante (la possibilité de créer des zones locales est ouverte à tous ceux qui ont un accès.) Autrement, il a une bonne partie de ce qu'il faut pour un récurseur.

Maintenant que le cahier des charges est fait, quelles sont les solutions pour le mettre en œuvre ? Historiquement, le protocole officiel de gestion des machines, à l'IETF, était SNMP. Comme on l'a vu, il y a même eu une tentative de s'en servir avec les serveurs DNS, tentative qui n'est pas allé loin. Aujourd'hui, la mode est plutôt à un autre protocole de gestion, Netconf (RFC 6241). Il existe une proposition, documentée dans l'Internet-Draft draft-dickinson-dnsop-nameserver-control, qui utilisera dans le futur Netconf (une version précédente de cette proposition incluait le protocole, et même une implémentation, mais la version actuelle se concentre sur le modèle de données). Voir la présentation au CENTR à Amsterdam en mai 2011.

Aux diverses réunions IETF sur le sujet, une alternative ne nécessitant pas un nouveau protocole avait souvent été proposée : se servir d'outils de gestion de configuration comme Chef ou Puppet. La principale limite de ces outils est qu'ils ne conviennent qu'à l'intérieur d'une même organisation et ne règlent pas facilement des problèmes multi-organisations.


Téléchargez le RFC 6168


L'article seul

RFC 6164: Using 127-Bit IPv6 Prefixes on Inter-Router Links

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : M. Kohno (Juniper Networks, Keio University), B. Nitzan (Juniper Networks), R. Bush, Y. Matsuzaki (Internet Initiative Japan), L. Colitti (Google), T. Narten (IBM Corporation)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 23 Avril 2011


Quelles adresses IP utiliser sur un lien point-à-point, lorsque les deux machines qui se parlent sont seules sur le lien ? Ce nouveau RFC recommande l'utilisation d'un préfixe de longueur /127 pour IPv6, ne permettant que deux adresses IP.

Cette recommandation existait déjà pour IPv4, dans le RFC 3021, qui recommande un /31. Pour IPv6, la norme, en l'occurrence le RFC 4291 préconisait au contraire un préfixe /64 pour tous les liens. Les adresses sous ce préfixe pouvaient alors être construites selon le format dérivé du EUI-64. Certains opérateurs avaient déjà ignoré cette norme et utilisaient des préfixes de longueur /127 (ne laissant qu'un seul bit pour identifier la machine), malgré l'avis du RFC 3627, qui mettait en avant le risque de confusion avec l'adresse anycast des routeurs. Notre RFC 6164 leur donne raison et officialise les préfixes /127.

Lorsqu'il n'y a que deux machines sur un lien (par exemple une liaison point-à-point, que ce soit parce qu'elle utilise un technologie purement point-à-point ou bien simplement parce qu'elle a été configurée ainsi), on peut aussi utiliser les adresses locales au lien (fe80::/10). Mais, comme le rappelle la section 2 de notre RFC, celles-ci ne sont pas toujours suffisantes : surveillance du réseau à distance, traceroute et BGP sont des exemples de bonnes raisons pour utiliser des adresses globales.

Quelles étaient les raisons pour se méfier des préfixes de longueur 127 ? La section 4 résume la principale : confusion possible avec l'adresse des routeurs du lien, définie en section 2.6.1 du RFC 4291. Or, non seulement l'expérience des opérateurs qui ont violé le RFC 3627 a été positive (pas de problèmes notés) mais on peut trouver des très bonnes raisons pour utiliser des préfixes plus spécifiques qu'un /64. La section 5 cite :

  • Risque de boucle de routage sur un préfixe plus général qu'un /127, si le lien n'utilise pas le NDP (c'est le cas de SONET).
  • Risque d'attaque par déni de service en épuisant le cache des voisins. Imaginons nos deux routeurs sur un Ethernet et étant configurés dans un préfixe /64. Tout paquet IP à destination d'une adresse de ce préfixe va faire l'objet d'une tentative de résolution par NDP (RFC 4861), et, pendant ce temps, le routeur devra garder une entrée dans sa table des voisins, avant de renoncer. Évidemment, aucune machine n'a une table des voisins de 2^64 entrées. Un méchant qui générerait des paquets à destination de toutes les adresses du préfixe /64 pourrait remplir cette table plus vite que l'expiration du délai de garde ne la vide. Notez que cette attaque n'est pas spécifique aux liens point-à-point mais ceux-ci sont souvent des liens vitaux, entre routeurs « importants ». Cette attaque peut être traitée en limitant le nombre de résolutions NDP en cours mais cela ne la résoud pas complètement, alors que l'usage d'un /127 la supprime.
  • Sensation de gaspillage des adresses si on bloque un /64 pour seulement deux machines. Vue la taille de l'espace d'adressage d'IPv6, c'est le moins convaincant des arguments.

Synthétisant tout cela, la section 6 de notre RFC conclut qu'il faut utiliser les /127. Le logiciel des routeurs doit accepter de tels préfixes. Les opérateurs doivent faire attention à ne pas utiliser certaines adresses, celles-ci ayant une signification particulière : adresses où les 64 bits les plus à droite sont nuls, ou bien adresses dont ces mêmes bits ont une des 128 plus grandes valeurs (réservées par le RFC 2526).

Pour un exemple des discussions récurrentes /64 vs. /127, voir « Point-to-point Links and /64s ». Le RFC 3627 a été officiellement déclaré « d'intérêt historique seulement » par le RFC 6547.


Téléchargez le RFC 6164


L'article seul

RFC 6156: Traversal Using Relays around NAT (TURN) Extension fo IPv6

Date de publication du RFC : Avril 2010
Auteur(s) du RFC : G. Camarillo, O. Novo (Ericsson), S. Perreault (Viagenie)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 Avril 2011


Le protocole TURN, qui permet à deux machines coincées derrière des routeurs NAT de communiquer en utilisant un relais tiers, a été normalisé dans le RFC 5766, dans une version minimale, uniquement pour IPv4 et seulement pour UDP, les services « incontestables », qui étaient pressés d'avoir une solution. Depuis, des extensions à TURN sont développées pour d'autres services. C'est ainsi que ce RFC 6156 permet d'utiliser TURN pour établir des liaisons en IPv6.

Cette extension permet de communiquer avec une machine IPv4 depuis une machine IPv6, avec une machine IPv6 depuis une autre machine IPv6 et enfin avec une machine IPv6 depuis une machine IPv4 (section 1 du RFC). C'est donc une véritable solution de communication entre les deux protocoles, travaillant dans la couche 7 (contrairement aux techniques comme le NAT qui travaillent dans la couche 3). Le serveur TURN relais la totalité des données entre les deux clients TURN.

On peut se demander si un tel service est bien nécessaire. Après tout, TURN avait été inventé pour le cas du NAT, qui lui-même était motivé par le faible nombre d'adresses IPv4 disponibles. En IPv6, le problème de la pénurie ne se pose pas et TURN semble inutile. Toutefois, comme le note le RFC 5902, il risque d'y avoir quand même des réseaux IPv6 NATés, peut-être avec des adresses ULA à l'intérieur, et TURN peut donc trouver sa place ici. Autre utilité : TURN peut aider les machines purement v4 (la majorité d'aujourd'hui) et les machines purement v6 (qui se répandront sans doute) à communiquer entre elles. Enfin, TURN peut aussi être utile pour un administrateur de pare-feu à état pour permettre aux utilisateurs d'ouvrir des ports afin de recevoir des connexions entrantes. TURN a été conçu pour qu'il soit très restreint dans ce qu'il accepte, de façon à ce que les administrateurs de pare-feux puissent lui faire confiance.

La nouvelle extension fonctionne avec un nouvel attribut TURN, REQUESTED-ADDRESS-FAMILY, valeur 0x0017 (section 3). L'attribut XOR-RELAYED-ADDRESS (RFC 5766, section 14.5, et section 4.2 de notre RFC) de la réponse contiendra une adresse de la famille demandée (v4 ou v6). La famille d'adresse du client est déterminée, elle, en regardant l'adresse utilisée pour contacter le serveur. À noter que chaque demande d'allocation TURN ne peut gérer qu'une seule adresse IP. Le client qui voudrait communiquer avec une adresse IPv4 et une v6 devra faire deux demandes d'allocation. Si le serveur ne veut ou ne peut pas gérer une famille donnée, il répondra 440 (Address Family not Supported).

La section 4 contient ensuite les détails concrets comme le format du nouvel attribut (section 4.1.1). Celui-ci a le numéro 0x0017, ce qui le met dans les plages des attributs dont la compréhension par le serveur est impérative. Un vieux serveur qui ne met pas en œuvre notre RFC ne peut donc pas ignorer cet attribut.

Un problème qui a toujours été très chaud dans le groupe Behave est celui de la traduction des paquets. Comme on dit en italien, « Traduttore, Traditore » (traducteur = traître). Lorsqu'un serveur TURN relaie des paquets, doit-il respecter toutes les options de l'en-tête IP ? La question est évidemment encore plus difficile pour une traduction entre IPv4 et IPv6. La section 8 fournit les règles. Par exemple, lors de la traduction de IPv4 vers IPv6 (section 8.1), que doit valoir le champ Traffic Class (RFC 2460, section 7) d'un paquet IPv6 sortant ? Le comportement souhaité est celui spécifié dans la section 3 du RFC 6145 (RFC qui décrit le mécanisme de traduction de IPv4 vers IPv6, notamment pour l'utilisation dans NAT64). Le comportement possible est d'utiliser la valeur par défaut de ce champ. Le Flow label (RFC 2460, section 6), lui, devrait être mis à zéro (il n'a pas d'équivalent IPv4). Et pour les en-têtes d'extensions IPv6 (RFC 2460, section 4) ? Aucun ne doit être utilisé, dans tous les cas (sauf la fragmentation).

Et si on relaie entre deux machines IPv6 ? Ce sont quasiment les mêmes règles, comme indiqué par la section 8.2. Par exemple, bien qu'il existe un Flow label des deux côtés, on considère que TURN, relais de la couche 7, ne devrait pas essayer de le copier : il y a deux flots différents de part et d'autre du serveur TURN.

Cette extension de TURN pose t-elle des problèmes de sécurité ? Potentiellement oui, répond la section 9. En effet, elle donne aux machines des capacités nouvelles. Ainsi, une machine purement IPv6 obtient, si elle a le droit d'accéder à un serveur TURN mettant en œuvre ce RFC 6156, la possibilité de parler aux machines purement IPv4, possibilité qu'elle n'avait pas avant. Comme il est recommandé de ne faire fonctionner TURN qu'avec une authentification préalable des clients, ce n'est sans doute pas une question sérieuse en pratique.

La section 10 décrit l'enregistrement à l'IANA des nouveaux paramètres (attribut REQUESTED-ADDRESS-FAMILY et codes d'erreur 440 et 443) dans le registre des paramètres STUN (rappelez-vous que TURN est défini comme une extension de STUN).

Question mise en œuvre, il en existe une côté serveur, non distribuée mais accessible vie le réseau (voir http://numb.viagenie.ca/), une libre qui a IPv6 depuis la version 0.5, mais apparemment rien encore côté client.

Merci à Simon Perreault pour sa relecture et ses remarques.


Téléchargez le RFC 6156


L'article seul

RFC 6151: Updated Security Considerations for the MD5 Message-Digest and the HMAC-MD5 Algorithms

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : S. Turner (IECA), L. Chen (NIST)
Pour information
Première rédaction de cet article le 7 Mars 2011


Ce RFC marque un peu l'enterrement officiel de MD5 dans les protocoles IETF. Cet algorithme de cryptographie, très répandu et très utilisé, décrit dans le RFC 1321, a connu de nombreuses attaques cryptanalytiques réussies et, pour plusieurs de ces usages, ne doit plus être considéré comme offrant une protection raisonnable. Une bonne partie de la sécurité de l'Internet reposait historiquement sur des protocoles utilisant MD5 et c'est donc un chapitre important qui se clot.

Peut-on dire aujourd'hui que MD5 est « cassé » et n'offre plus aucune protection ? La réponse doit en fait être plus nuancée et cela explique que ce très court RFC ait fait l'objet d'une aussi longue discussion à l'IETF, pour ne sortir que maintenant. En effet, si on voit souvent des affirmations hâtives de la part des ignorants, prétendant sans nuance que MD5 a été cassé, la réalité est plus complexe.

La section 1 rappelle en effet l'état de l'art. MD5 est utilisé pour deux choses :

Dans le premier cas, MD5 n'offre en effet plus une sécurité acceptable face à un attaquant (il reste utilisable lorsque le seul but est de détecter des erreurs produites par un processus aveugle, par exemple des parasites sur la ligne). Pour le second cas, c'est moins évident.

C'est qu'il existe plusieurs types d'attaques contre les fonctions de hachage cryptographiques comme MD5 (voir le RFC 4270). Par exemple, une attaque par collision consiste en la production de deux messages ayant le même condensat. Ce sont ces attaques auxquelles MD5 est le plus vulnérable. Si un document est signé via un condensat MD5, il est aujourd'hui simple de créer deux documents ayant le même condensat MD5, ce qui annule une bonne partie de l'intérêt des signatures.

Mais MD5 résiste bien mieux à d'autres attaques comme celles par pré-image, où un attaquant cherche à fabriquer un message ayant le même condensat qu'un message donné. C'est une tâche nettement plus complexe que la collision, où l'attaquant contrôle les deux messages. Donc, chaque protocole ou application qui utilise MD5 doit analyser si son usage de cette fonction est acceptable ou pas, compte-tenu de l'état de l'art en cryptographie.

Pour voir la différence entre ces deux problèmes, reprenons la commande md5sum. Soit un fichier toto.txt. md5sum calcule le condensat :

% md5sum /tmp/toto.txt 
0365023af92c568e90ea49398ffec434  /tmp/toto.txt

Une attaque par pré-image consisterait en la création d'un nouveau fichier ayant le même condensat 0365023af92c568e90ea49398ffec434 que toto.txt. Cela reste une tâche non-triviale. Une attaque par collision permet au contraire à l'attaquant de choisir le condensat à produire. Avec l'aide du paradoxe de l'anniversaire, c'est bien plus facile. Mais cela ne marche que si l'attaquant a le choix des données, ce qui est partiellement vrai pour les signatures mais pas pour HMAC. (Voir une bonne explication des différentes possibilités d'attaque, assez trapue mais originale, en « Meaningful Collisions (for SHA-1) ».)

La section 2 liste les attaques publiées contre MD5. Attention, en cryptanalyse, toutes les attaques réussies ne sont pas publiées, certains préférant les garder pour eux. Il faut donc toujours prévoir une marge en se disant que, si une attaque publiée permet de casser un algorithme de cryptographie en un mois, les attaques non publiées peuvent sans doute le faire en quelques jours, voire quelques heures.

Donc, les attaques par collision réussies contre MD5 ont été publiées pour la première fois en 1993. Les progrès ont été importants en 2004 avec « Cryptanalysis of HMAC/NMAC-MD5 and MD5-MAC » de Wang, Feng, Lai et Yu. En 2006, une attaque publiée descend à une seule minute de temps d'exécution sur un portable normal. En 2007, ce genre d'attaques a pu casser des certificats X.509. Il est donc clair que MD5 ne doit plus être utilisé pour la signature numérique. (En cherchant, vous trouverez probablement un certain nombre de sites Web qui ont toujours un certificat utilisant MD5.)

Au contraire, comme le note la section 2.2, les meilleures « attaques » pré-image publiées n'ont pas encore abouti. Quelles sont les conséquences pour HMAC (section 2.3) ? S'il y a eu plusieurs tentatives de casser HMAC-MD5 (tel qu'il est utilisé, par exemple, dans TSIG, RFC 2845), aucune de celles publiées n'a réussi. Il n'y a donc pas d'urgence à supprimer MD5 lorsqu'il est utilisé ainsi, néanmoins des remplaçants sont prêts (cf. RFC 4231) et peuvent être intégrés dans les nouvelles versions des protocoles (RFC 6039). Notez que les faiblesses de MD5 ne sont évidemment pas spécifiques aux protocoles Internet, voir par exemple la documentation de GnuPG.


Téléchargez le RFC 6151


L'article seul

RFC 6147: DNS64: DNS extensions for Network Address Translation from IPv6 Clients to IPv4 Servers

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : M. Bagnulo (UC3M), A. Sullivan (Shinkuro), P. Matthews (Alcatel-Lucent), I. van Beijnum (IMDEA Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 Avril 2011


Ce nouveau RFC est un composant indispensable de la nouvelle technique de traduction entre des machines IPv4 et IPv6 (dont une description générale se trouve dans le RFC 6144). Les machines purement IPv6 ne pouvant pas initier une communication avec des machines n'ayant qu'une adresse IPv4, il est nécessaire de les « tromper » en fabriquant dynamiquement des adresses IPv6. Les machines IPv6 tenteront alors de s'y connecter, leurs requêtes seront reçues par le traducteur d'adresses, qui pourra alors les convertir en IPv4 (cf. RFC 6145 et RFC 6146).

DNS64 n'est donc pas utilisable seul. Il doit se combiner à une machine, typiquement un routeur, qui fait la traduction d'adresses, dite NAT64. La configuration typique des utilisateurs de DNS64 sera un réseau local purement IPv6 (puisque le stock d'adresses IPv4 est épuisé), dont le routeur fait de la traduction NAT64, et qui est muni d'un résolveur DNS capable de fabriquer des adresses IPv6 à partir des adresses v4 des machines externes. En effet, le but du système NAT64 est de ne pas avoir à modifier les machines, seulement les équipements d'infrastructure (routeur et résolveur DNS). Les machines purement v6, ignorantes de la traduction qui se fait entre leur réseau et le monde extérieur, ne pourraient pas se connecter si elle ne connaissaient de leur pair qu'une adresse IPv4. NAT64 et son indispensable compagnon DNS64 rejoignent donc la boîte à outils des techniques permettant de faire coexister IPv4 et IPv6 (cf. RFC 6144).

Comment est-ce que le serveur DNS64 synthétise cette adresse IPv6 ? Supposons qu'une machine IPv6 du réseau local veuille se connecter à www.example.com et que celui-ci n'ait qu'une adresse v4, mettons 203.0.113.18. Le navigateur Web tournant sur le client va faire une requête DNS de type AAAA (adresse IPv6 ; puisqu'il n'a pas d'IPv4, les requêtes de type A n'auraient aucun intérêt). Le serveur DNS la reçoit, la relaie et récupère une réponse vide (le nom existe mais n'a pas d'enregistrement AAAA). Il tente alors une requête A, reçoit 203.0.113.18 en réponse et génère l'adresse v6 de manière purement algorithmique, sans état, en utilisant l'adresse v4 et les paramètres avec lesquels le serveur a été configuré (typiquement, un préfixe v6). Rappelez-vous donc bien que le serveur DNS64 et le traducteur doivent être configurés de manière cohérente (dans la plupart des cas, ils seront sans doute dans la même boîte mais, conceptuellement, ce sont deux services séparés.)

Pour le lecteur pressé qui veut juste une introduction à la norme, la section 2 est la meilleure lecture. Voici un exemple où une machine purement IPv6 tente de contacter Twitter, service purement IPv4 :

% telnet twitter.com 80
Trying 64:ff9b::80f2:f0f4...
Connected to twitter.com.
Escape character is '^]'.

C'est le serveur DNS64 qui a généré l'adresse 64:ff9b::80f2:f0f4 et c'est le traducteur qui changera les paquets IPv6 en IPv4 à l'aller et en sens inverse au retour. Twitter et le client purement IPv6 n'y verront que du feu. Pour le préfixe à utiliser, le serveur DNS64 et le traducteur ont le choix (cf. RFC 6052) entre un préfixe bien connu, réservé à la traduction d'adresse (celui utilisé dans l'exemple, qui avait été testé lors d'une réunion IETF à Pékin) ou bien un préfixe appartenant à l'opérateur réseau (NSP, pour Network-Specific Prefix). La seule contrainte est qu'il doit être configuré de manière identique dans le serveur DNS64 et dans le traducteur.

La norme elle-même fait l'objet de la section 5. Elle décrit avec précision le fonctionnement que j'ai résumé plus haut. Quelques petits points intéressants :

  • On ne synthétise d'enregistrements que s'il n'y avait pas déjà un AAAA (section 5.1.1).
  • Les erreurs (autres que NXDOMAIN - No Such Domain) doivent être traitées comme si le AAAA étai absent (section 5.1.2). Donc, par exemple, SERVFAIL (Server Failure) doit être traité comme un NOERROR,ANSWER=0, pour tenir compte des serveurs assez pourris pour ne pas répondre correctement aux requêtes AAAA (cf. RFC 4074). C'est une violation des normes du DNS, rendue nécessaire par le nombre de serveurs DNS (ou de middlewares placés devant eux) programmés avec les pieds.
  • La règle précédente, interdisant la synthèse d'enregistrements AAAA s'il en existe déjà, a quelques exceptions (section 5.1.4). Ainsi, les adresses IPv6 non utilisables globalement comme celles en ::ffff:0:0/96 doivent être ignorés et le AAAA de synthèse produit.
  • Si le AAAA n'existe pas ou est inutilisable (section 5.1.6), le serveur DNS64 demande un enregistrement A (adresse IPv4). S'il n'en trouve pas, il répond au client « Désolé, aucune réponse ». S'il en trouve un, il fabrique l'enregistrement AAAA correspondant (typiquement en concaténant le préfixe IPv6 avec l'adresse IPv4) et le renvoie (la réponse de type A, elle, n'est pas transmise). La section 5.1.7 donne les détails de cette synthèse.
  • Les deux requêtes, pour un enregistrement de type AAAA et pour un enregistrement de type A, peuvent être faites en parallèle (section 5.1.8). Certes, ce sera un gaspillage si l'enregistrement AAAA existe (puisque le A sera alors inutile) mais cela permettra de diminuer le temps total d'attente si le AAAA n'existe pas.

J'ai dit plus haut que l'adresse IPv6 de synthèse était fabriquée par concaténation du préfixe IPv6 (configuré à la main dans le serveur DNS64) et de l'adresse IPv4. Mais, en fait, le RFC n'impose pas l'utilisation d'un tel algorithme. La méthode utilisée n'a pas besoin d'être normalisée (elle n'est pas vue à l'extérieur) et doit seulement être la même sur le serveur DNS64 et sur le traducteur. La section 5.2 précise plus rigoureusement les exigences auxsquelles doit obéir cet algorithme. Le point le plus important est qu'il doit être réversible : en échange de l'adresse IPv6 de synthèse, le traducteur doit pouvoir retrouver l'adresse IPv4 originelle. Pour faciliter la vie des administrateurs réseau, un algorithme doit être obligatoirement présent dans les programmes (mais ce n'est pas forcément celui que l'administrateur choisira), celui décrit en section 2 du RFC 6052.

Et que doit faire le serveur DNS64 s'il reçoit des requêtes d'un autre type que A ou AAAA ? La section 5.3 couvre ce cas. En gros, il doit les traiter normalement sauf les requêtes de type PTR (résolution d'une adresse en nom). Dans ce cas, le serveur doit extraire l'adresse du nom en ip6.arpa (section 2.5 du RFC 3596), regarder si cette adresse correspond à un des préfixes qu'il gère et, si oui, le serveur DNS64 a deux possibilités :

  • Répondre immédiatement, avec autorité, en utilisant un nom adapté (qui peut être le même pour toutes les adresses, mettons locally-generated-ipv6-address-with-dns64.example.net). L'avantage est que les clients DNS verront bien que l'adresse avait été synthétisée, l'inconvénient est qu'on n'utilisera pas les informations qui pouvaient se trouver dans le DNS,
  • Synthétiser les enregistrements PTR à partir de données trouvées dans le DNS, comme il synthétise des enregistrements AAAA à partir des A récupérés dans le DNS. Dans ce cas, le serveur DNS64 traduit l'adresse IPv6 en IPv4, crée un nom dans in-addr.arpa, fait une requête PTR et renvoie le résultat au client.

La section 6, sur le déploiement, est consacrée aux problèmes pratiques qui pourront survenir lorsqu'on utilisera réellement DNS64. Par exemple, si une machine est multi-homée, il est possible que seulement certaines de ses connexions à l'Internet passent par un traducteur v4-v6. Il faudrait donc idéalement interroger des résolveurs DNS différents selon l'interface de sortie, et considérer les résultats comme locaux à l'interface.

Autre problème pratique, le cas d'une machine à double-pile qui utiliserait DNS64, passant ainsi par le traducteur même lorsque ce n'est pas nécessaire (section 6.3.2 et 6.3.3). Comme la configuration par défaut des systèmes d'exploitation est de préférer IPv6 à IPv4, le cas risque de se produire souvent. Il n'existe pas de moyen simple de le détecter puisque, pour le client, un serveur DNS64 semble un serveur comme un autre. Une machine double-pile (IPv4 et IPv6) ne devrait donc pas utiliser de résolveur DNS64. Mais il peut y avoir des cas où c'est nécessaire, par exemple si la machine double-pile n'a une connectivité IPv4 que partielle. Dans ces conditions, le serveur DNS64 doit exclure les préfixes IPv4 locaux de la synthèse. On peut donc prévoir quelques problèmes de déboguage amusants...

La section 7 décrit des exemples de déploiement, en utilisant les scénarios du RFC 6144. Par exemple, la section 7.1 cite le cas qui sera sans doute le plus fréquent au début, une machine H1 réseau purement IPv6 (parce que arrivé après l'épuisement des adresses IPv4) qui essaie de se connecter à un serveur H2 situé dans l'Internet v4 traditionnel. Le traducteur T et le serveur DNS sont configurés avec le préfixe bien connu 64:ff9b::/96. H1 va commencer par faire une requête AAAA pour h2.example.com. Le résolveur DNS ne trouve pas de AAAA pour ce nom, mais il récupère un enregistrement de type A, 192.0.2.1. Il fabrique alors le AAAA 64:ff9b::c000:201 (qui peut aussi légitimement s'écrire 64:ff9b::192.0.2.1). H1 va alors envoyer un paquet TCP SYN à 64:ff9b::c000:201. Le routeur/traducteur le voit passer, note le préfixe NAT64 avec lequel il a été configuré et le traduit en un paquet TCP/IPv4.

Autre exemple, en section 7.3. C'est à peu près l'inverse : une machine dans un Internet passé presque entièrement en IPv6 essaie de se connecter à un des derniers serveurs v4 existants. À noter que DNS64 n'est pas indispensable dans ce cas : on peut simplement affecter algorithmiquement une adresse IPv6 à toutes les adresses IPv4, les publier sur des serveurs DNS normaux, et donc n'utiliser que le traducteur. Toutefois, cette section cite quelques cas où DNS64 peut être utile, par exemple si les adresses IPv4 sont affectées dynamiquement.

Fondamentalement, un serveur DNS64 est un menteur : il fabrique des réponses qui n'existent pas (Twitter, utilisé dans l'exemple plus haut, n'a pas d'adresse IPv6 à ce jour...). Il a donc des problèmes avec DNSSEC, qui a justement été conçu pour détecter les mensonges. Toute la section 3 est consacrée à discuter ce problème. Bien sûr, le résolveur DNS64 ment pour la bonne cause. Mais DNSSEC est au delà du bien et du mal, il se moque des motivations, il ne regarde que le résultat. Plusieurs cas peuvent se poser (le RFC en identifie sept !) selon les options indiquées dans la requête DNS et selon la configuration DNSSEC utilisée. Rappelons que les deux options importantes pour DNSSEC dans une requête DNS sont le bit DO (DNSSEC OK, RFC 4035, section 3.2.1) qui indique si le client DNS comprend les enregistrements DNSSEC et le bit CD (Checking Disabled, RFC 4035, section 3.2.2) qui indique au résolveur que le client fera la validation lui-même et qu'il faut lui envoyer toute l'information, même si elle s'avère fausse.

Les différents cas sont donc (je ne les ai pas tous mentionnés, voir le RFC pour les détails) :

  • Un serveur DNS64 reçoit une requête où DO est à zéro (ce que font aujourd'hui la plupart des bibliothèques de résolution de noms, les stub resolvers). Aucun problème dans ce cas, le client ne comprend pas DNSSEC, le serveur DNS64 peut inventer tous les mensonges qu'il veut.
  • Un serveur DNS64 avec gestion de DNSSEC reçoit une requête avec DO et CD mis à zéro (c'est typiquement le cas - rare - d'un client qui veut valider lui-même). Dans ce cas, il doit passer au client toute l'information obtenue. DNS64 ne marchera pas ici, le client n'acceptera pas le AAAA synthétisé comme étant valide. La seule solution est que le client mette en œuvre DNS64 lui-même.
  • Un serveur DNS64 qui valide avec DNSSEC reçoit une requête avec DO à un et CD à zéro (ce sera sans doute le cas le plus courant dans le futur). Aucun problème, le serveur DNS64 valide les données récupérées et répond SERVFAIL (Server Failure) si cette validation échoue. Le AAAA synthétisé n'est pas validé avec DNSSEC mais le client ne le saura pas. Si le bit DO était mis à un, le serveur DNS64 a juste à mettre le bit AD (Authentic Data) à un dans sa réponse (un mensonge pour la bonne cause ; après tout, si le client DNS n'a pas mis CD à un, c'est qu'il fait complètement confiance au résolveur).

La section 5.5 donne les détails sur le fonctionnement de DNSSEC dans DNS64. La section 6.2 rappelle les problèmes pratiques de déploiement de DNS64 si on utilise déjà DNSSEC.

DNS64 pose t-il des problèmes de sécurité ? Pas beaucoup, dit la section 8. Comme indiqué (paragraphes précédents), il peut interférer avec DNSSEC. Et, surtout, il impose une coordination entre le serveur DNS64 et le traducteur. Si un attaquant peut modifier la valeur du préfixe du serveur DNS64, il peut envoyer les paquets où il veut. Donc, attention, la sécurité du serveur DNS64 est exactement aussi importante que celle du traducteur.

Enfin, l'annexe A explique des motivations pour générer un AAAA alors qu'il existe déjà. Il se peut que la meilleure route passe plutôt par le traducteur et donc, dans certains cas, un serveur DNS64 peut offrir à son administrateur la possibilité de permettre la synthèse d'enregistrements AAAA même quand un vrai existe.

BIND met en œuvre DNS64 depuis les versions 9.7.3 et 9.8.0. Voici un exemple de configuration de DNS64 avec une 9.8.0 :

acl me {
    ::1/128; 127.0.0.0/8;
};
acl rfc1918 { 
    10/8; 192.168/16; 172.16/12; 
};

options {
       ...
       dns64 64:ff9b::/96 { // The well-known prefix
              clients { me; };
              mapped { !rfc1918; any; }; // Never synthetize AAAA records
                     // for private addresses
              exclude { 64:ff9b::/96; ::ffff:0000:0000/96; }; // If the retrieved
              // AAAA record is in that range, do not send it back to the user,
              // synthetize a AAAA.
              //
              // suffix ::42; // Trailing bits. Require some free space (here, 
              // 96 + 32 bits leave no room for trailing bits).
        };

Le premier préfixe est celui des AAAA synthétisés (ici, le préfixe bien connu). La directive clients réduit le service DNS64 à certaines machines seulement (celles qui sont connectées via un traducteur NAT64, relisez les sections 6.3.2 et 6.3.3 du RFC). La directive mapped met en œuvre la règle d'exclusion des préfixes IPv4 locaux (ici, ceux du RFC 1918). La directive exclude implémente la règle d'exclusion des préfixes IPv6 qui ne devraient même pas être mis dans le DNS global. S'il existe un AAAA, mais qu'il pointe vers un des ces préfixes, il sera remplacé par un AAAA synthétique. Enfin, la directive suffix permet d'ajouter quelques bits à la fin du AAAA de synthèse (mais, ici, avec 96 bits pour le préfixe IPv6 et 32 pour l'adresse IPv4, il n'y a plus de place).

Voici l'effet du serveur ayant la configuration ci-dessus (il écoute sur le port 9053) :

[Adresse IPv6 déjà dans le DNS global.]
% dig +short -p 9053 @::1 AAAA www.ietf.org 
2001:1890:1112:1::20

[Pas d'adresse IPv6 dans le DNS global mais trois adresses IPv4.]
% dig +short -p 9053 @::1 AAAA facebook.com
64:ff9b::453f:bd0b
64:ff9b::453f:bd10
64:ff9b::453f:b50c

[Les requêtes PTR marchent bien, BIND synthétise un CNAME, une des
deux techniques permises par le RFC.]
% dig  -p 9053 @::1 -x 64:ff9b::453f:bd10      
...
;; QUESTION SECTION:
;0.1.d.b.f.3.5.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa. IN PTR

;; ANSWER SECTION:
0.1.d.b.f.3.5.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa. 600 IN CNAME 16.189.63.69.in-addr.arpa.
16.189.63.69.in-addr.arpa. 7172 IN      PTR     www-11-01-ash2.facebook.com.
...

[Ici, le nom a une adresse IPv4 mais privée. L'ACL 'rfc1918' va donc
la bloquer.]
% dig +short -p 9053 @::1 A ciel.administratif.prive.nic.fr                  
10.1.84.200

% dig  -p 9053 @::1 AAAA ciel.administratif.prive.nic.fr                         
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
                              ^^^^^^^^^

Pour comparer, voici une configuration BIND avec un préfixe du FAI (NSP pour Network-Specific Prefix). Plus court que le précédent, il dégage de la place pour le suffixe :

       dns64 2001:db8:666::/48 { // A Network-Specific Prefix (NSP).
              clients { me; };
              suffix ::42; // Trailing bits.
        };

Et voici les résultats :

% dig +short -p 9053 @::1 AAAA facebook.com
2001:db8:666:453f:bd:1000:0:42
2001:db8:666:453f:b5:c00:0:42
2001:db8:666:453f:bd:b00:0:42

Si vous voulez manipuler les adresses vous-même, voici un joli script awk dû à gbfo, pour traduire les adresses IPv6 en la v4 correspondant :

% echo 64:ff9b::453f:bd0b | \
        awk -F: '{h=strtonum("0x" $(NF-1));l=strtonum("0x" $NF);printf("%d.%d.%d.%d\n",h/256,h%256,l/256,l%256);}' 
69.63.189.11

Question mises en œuvre de DNS64, outre le cas de BIND, déjà présenté, il existe une rustine pour Unbound, chez Viagénie (avec un très ennuyeux système de formulaire à remplir pour l'obtenir). Cette rustine porte sur une version ancienne du protocole, et nécessiterait peut-être une mise à jour. Il y a aussi au même endroit un serveur DNS64 autonome, écrit en Perl. Ce dernier est très court et peut donc être un bon moyen de comprendre le protocole, pour ceux qui aiment lire le code source. Enfin, Cisco a désormais DNS64 sur ses produits.

Et mon opinion personnelle sur DNS64 ? Je dirais que, certes, c'est un hack, mais qu'on a vu pire et que ça traite un vrai problème. DNS64 semble bien pensé, rien n'est oublié et le RFC parle bien de tous les problèmes, notamment avec DNSSEC.

Pour un récit très détaillé, avec plein de technique, d'un test de NAT64 avec DNS64, voir l'article de Jérôme Durand « J'ai testé pour vous : Stateful NAT64 avec DNS64 ».


Téléchargez le RFC 6147


L'article seul

RFC 6146: Stateful NAT64: Network Address and Protocol Translation from IPv6 Clients to IPv4 Servers

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : M. Bagnulo (UC3M), P. Matthews (Alcatel-Lucent), I. van Beijnum (IMDEA Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 Avril 2011


Dans la grande série des techniques de coexistence entre IPv4 et IPv6, voici une normalisation de NAT64, une technique de traduction entre IPv6 et IPv4, permettant à une machine purement IPv6 de se connecter à une machine purement IPv4. Ce RFC fait partie de la série introduite par le document d'architecture générale RFC 6144.

Aujourd'hui, l'état de l'Internet est que la majorité des serveurs sont accessibles uniquement en IPv4. Or, les dernières adresses IPv4 disponibles à l'IANA ont été distribuées le 3 février 2011. Demain, les nouvelles machines recevront donc de plus en plus uniquement des adresses IPv6. Comment se connecteront-elles à ces serveurs purement v4 ? Une des solutions est de traduire automatiquement les paquets IPv6 du client en IPv4 pour les envoyer au serveur, et de faire la traduction inverse au retour. Cela se nomme NAT64 et notre RFC normalise la version « à état » de cette méthode. « À état » car le traducteur garde un souvenir des flux de données en cours et peut donc, pour la traduction, tenir compte d'un état, des paquets précédents (la version sans état est dans le RFC 6145).

Notez le titre de ce RFC : ses ambitions sont limitées, il ne s'agit pas, comme l'essayait le défunt NAT-PT (RFC 2766) de fournir une solution générale à tous les problèmes de communication v4-v6 mais seulement de permettre à des clients IPv6 de se connecter à des serveurs IPv4.

NAT64 ressemble beaucoup à l'actuel NAT44 (celui que tout le monde est obligé d'utiliser à l'hôtel, chez lui s'il a plusieurs machines, cf. RFC 3022) dans la mesure où il permet :

  • Aucune modification au client ou au serveur, tout est fait dans le routeur du réseau IPv6-pur,
  • Les communications client-serveur, comme le titre de notre RFC le précise,
  • Certaines communications pair-à-pair, en utilisant des techniques comme ICE (RFC 5245),
  • Des communications lancées depuis l'extérieur, si on a configuré statiquement le traducteur pour reconnaître certaines adresses.

Il s'en distingue par le fait qu'on ne se contente pas de traduire les adresses, il faut traduire tout l'en-tête du paquet, et par le fait que, pour que les applications tournant sur la machine purement IPv6 trouvent une adresse IPv6, un serveur DNS spécial, DNS64 (RFC 6147) est nécessaire. Vu la nécessité de faire plus de travail qu'en NAT44, la spécification ne fonctionne que pour certains protocoles des couches supérieures, pour l'instant uniquement ICMP, UDP et TCP. Ne comptez donc pas faire, par exemple, du SCTP.

Notre RFC s'appuie sur plusieurs autres documents, celui d'architecture (RFC 6144), celui sur la traduction des adresses (RFC 6052), et celui sur l'algorithme de traduction (RFC 6145).

Les équipements qui font faire le travail sont donc :

  • Le traducteur, qui sera typiquement embarqué dans le routeur (CPE, box, ou bien plus loin dans le réseau de l'opérateur),
  • Le résolveur DNS64, qui pourra être inclus dans le même routeur ou bien fourni séparement.

Normalement, les traducteurs qui suivront ce RFC seront conformes aux recommandations qu'avait édicté le groupe de travail Behave, dans sa première version, à savoir les RFC 4787, RFC 5382, RFC 5508... et ils permettront les techniques de passage au travers des NAT comme ICE (RFC 5245).

La norme elle-même commence en section 3 mais une gentille introduction, utilisable si vous ne connaissez pas grand'chose aux NAT, figure en section 1.2. Essayons de la résumer sommairement en prenant pas mal de raccourcis : le traducteur a donc deux interfaces, une vers le réseau IPv6-pur et une vers un réseau IPv4 (et peut-être aussi IPv6 mais, dans ce cas, pas besoin de traduction). Le traducteur doit donc avoir une adresse IPv4 publique. Lorsqu'il reçoit un paquet IPv6 dont l'adresse de destination indique qu'il doit être traduit, il le transforme en IPv4 (l'adresse IPv4 est encapsulée dans l'adresse IPv6), et l'envoie par l'interface IPv4. Au retour, c'est un peu plus dur car l'adresse IPv4 de destination est celle du traducteur et, pour retrouver l'adresse IPv6 du vrai destinataire, il doit consulter une table où il a stocké les clients IPv6 qui parlaient à l'extérieur. Comme en NAT44, le numéro de port est utilisé pour reconnaitre les clients locaux. La combinaison d'une adresse IP et d'un port est appelée « adresse de transport ». On le voit, cela ne marche bien que si c'est le réseau IPv6 qui initie la communication (mais diverses astuces permettent des communications un peu plus pair-à-pair).

Le NAT64 devrait donc être appelé NAPT (Network Address AND PORT Translation) car, dans l'écrasante majorité des cas, le traducteur n'aura pas assez d'adresses IPv4 pour tous les clients IPv6 qu'il sert (si on avait assez d'adresses v4, il n'y aurait guère de raison de migrer vers v6).

Comment le client IPv6 a-t-il trouvé l'adresse IPv6 de destination, puisque le serveur n'a qu'une adresse IPv4 ? C'est le rôle du serveur DNS64 qui ment (pour la bonne cause) en fabriquant un enregistrement DNS de type AAAA (adresse IPv6) à partir de l'enregistrement réel A (adresse IPv4). Les étapes complètes effectuées par le client sont décrites en section 1.2.2.

On a vu que cette opération nécessitait de réserver une partie de l'espace d'adressage IPv6 pour représenter les adresses IPv4. Cette partie peut être localement définie (après tout, seuls le traducteur et le résolveur DNS64 auront besoin de la connaître) ou bien on peut utiliser le préfixe standard 64:FF9B::/96. Ici, on voit un serveur DNS64 et un traducteur coopérer pour permettre à une machine purement IPv6 de communiquer avec www.example.com, qui n'a qu'une adresse IPv4 : .

Du fait que le traducteur a un état, tous les paquets IPv4 venus de l'extérieur ne sont pas acceptés. Seuls peuvent être transmis ceux qui correspondent à une correspondance existante, en suivant les règles des RFC 4787 et RFC 5382 (Endpoint-Independent Filtering et Address-Dependent Filtering ; suivre ces règles est important pour que les applications pair-à-pair fonctionnent).

Voilà pour l'introduction. Maintenant, pour lire la spécification elle-même, il faut d'abord bien apprendre la terminologie, en section 2. Quelques termes qui ne sont sans doute pas familiers à tous :

  • Un quintuplet est l'identificateur d'une session TCP ou UDP. Il est composé de {adresse IP source, port source, adresse IP destination, port destination, protocole de couche 4}.
  • La BIB (Binding Information Base) est la liste des communications actuellement en cours, pour un protocole de transport donné. Une liaison (binding) est faite entre une adresse de transport IPv4 et une IPv6, afin de déterminer à qui « appartient » un paquet entrant dans le traducteur. Les liaisons peuvent être établies automatiquement, lorsque le premier paquet passe, ou bien manuellement. Voir la section 3.1.
  • Un virage en épingle à cheveux désigne le cas où deux machines situées du même côté du traducteur communiquent via le traducteur, qui doit alors renvoyer le paquet par là d'où il est venu (cf. section 3.8).
  • Une adresse de transport est le doublet formé d'une adresse IP et d'un port. Comme le traducteur aura moins d'adresses IPv4 que de clients, l'ajout du port est nécessaire pour différencier les sessions, lorsqu'un paquet IPv4 arrive.

Vous avez bien retenu tout le vocabulaire ? Alors, vous pouvez lire la norme elle-même, à partir de la section 3. Quelques points importants à retenir :

  • NAT64 doit garder une table des sessions TCP et UDP en cours, pour pouvoir déterminer leur fin (et donc la suppression des liaisons associées).
  • Chaque entrée de la BIB peut être associée à plusieurs sessions et il ne faut donc la supprimer que lorsque la dernière session est finie.
  • La fragmentation pose des défis particuliers. Un traducteur NAT64 conforme à la norme doit gérer les fragments, même s'ils arrivent dans le désordre. Il doit donc faire du réassemblage (en limitant toutefois les ressources allouées à cette tâche, pour se protéger contre les attaques DoS ; voir les RFC 1858, RFC 3128 et RFC 4963). Le traducteur a aussi le droit d'ajouter quelques contraintes comme le fait que tout l'en-tête TCP doit être dans le premier fragment.
  • Comme le NAT64 avec état n'est défini que pour TCP, UDP et ICMP, le traducteur doit jeter les paquets des autres protocoles (en prévenant la source, via un paquet ICMP).
  • Le traducteur ayant une connaissance des sessions actives, il peut jouer un rôle de filtre en bloquant les paquets ne correspondant pas à une telle session.
  • Déterminer qu'une session est finie n'est pas forcément évident. Ainsi, si la fin d'une session TCP est facile à observer (échange des paquets FIN par les deux parties), que faire pour une « session » UDP puisqu'il n'y a pas de connexion et donc pas de fin explicite ? La solution est d'utiliser une minuterie, remise à zéro par chaque paquet, et qui se déclenche après un certain temps d'inactivité, coupant la session UDP.
  • Pour TCP, la section 3.5.2 décrit en détail les événements de la machine à états de TCP que le traducteur doit observer pour découvrir début et fin de la session. Elle est très longue et détaillée, j'espère que les programmeurs des routeurs bas de gamme à 60 dollars prendront le temps de la lire !
  • Les règles de conversion des adresses IPv4 en IPv6 et réciproquement sont celles du RFC 6052.

Vous avez noté qu'à plusieurs reprises, j'ai utilisé des termes vagues comme « un certain temps ». Les valeurs numériques recommandées pour les diverses constantes sont en section 4. Ainsi, avant de fermer une session UDP, le traducteur doit attendre (par défaut) au moins cinq minutes (cf. RFC 4787), le traducteur doit attendre les fragments manquants au moins deux secondes, etc.

Cette technique du NAT64 améliore-t-elle ou aggrave-t-elle les problèmes de sécurité ? D'abord, cette section note que toute solution de sécurité de bout en bout qui protège l'en-tête IP contre les modifications (par exemple l'AH d'IPsec) va être cassée par NAT64, qui modifie précisément l'en-tête. Si le NAT64 est obligatoire, IPsec peut, par exemple, utiliser l'encapsulation UDP (RFC 3948). La section 5 insiste d'autre part sur le fait qu'un traducteur n'est pas un pare-feu et que le filtrage réalisé par effet de bord de la gestion d'état n'est pas forcément adapté à la sécurité.

D'autre part, NAT64 a ses propres vulnérabilités. Les principales sont le risque d'attaques par déni de service. Par exemple, un attaquant situé à l'intérieur (côté IPv6) peut utiliser toutes les adresses (en général une seule) et ports disponibles et empêcher ainsi l'accès des autres utilisateurs. Une autre attaque possible est d'envoyer régulièrement des paquets de façon à maintenir une liaison active et d'empêcher le traducteur de relâcher des ressources. Une protection possible serait de ne remettre à zéro la minuterie que si le paquet qui passe vient de l'intérieur (supposé plus fiable).

Quelles implémentations existent aujourd'hui ? Viagénie en à une en logiciel libre, voir http://ecdysis.viagenie.ca/. Le terme de ecdysis désigne la mue des arthropodes puisque NAT64 permet à IP de muer vers un nouveau protocole... Voici un exemple d'installation et d'usage : c'est un module noyau, donc il faut installer les paquetages qui permettent la compilation de modules noyau. Sur une Debian version « squeeze » avec le noyau Linux 2.6.32-5 :

% sudo aptitude install linux-headers-2.6.32-5-686 linux-kbuild-2.6.32
...

% make
/bin/sh: [[: not found
make -C /lib/modules/2.6.32-5-686/build M=/home/stephane/tmp/ecdysis-nf-nat64-20101117 modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-5-686'
  CC [M]  /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64_main.o
  CC [M]  /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64_session.o
  CC [M]  /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64_config.o
  LD [M]  /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64.mod.o
  LD [M]  /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-5-686'

% sudo make install
...

# On peut éditer le script avant pour changer les paramètres...
% sudo ./nat64-config.sh

Ensuite, on peut vérifier que tout s'est bien passé en regardant la table de routage :

% netstat -r -n  -Ainet6
Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
64:ff9b::/96                   ::                         U    1024 0     0 nat64
...

Parfait, les paquets pour le préfixe NAT64 sont bien routés à part. Tentons notre chance :

% telnet 64:ff9b::453f:bd0b
Trying 64:ff9b::453f:bd0b...

Et on voit bien les paquets IPv6 sur l'interface nat64 :

21:18:58.910669 IP6 2a01:e35:8bd9:8bb0:304b:5a4b:3b8c:7b1c.37033 > \
         64:ff9b::453f:bd0b.23: Flags [S], seq 3580860303, win 5760, \
           options [mss 1440,sackOK,TS val 23731660 ecr 0,nop,wscale 6], length 0

Et les IPv4 sur l'interface normale :

21:19:09.263613 IP 192.168.2.1.37038 > \
         69.63.189.11.23: Flags [S], seq 4043093045, win 5760, \
           options [mss 1440,sackOK,TS val 23734248 ecr 0,nop,wscale 6], length 0

Un déploiement expérimental de NAT64 est celui du réseau de la recherche lituanien. Voir leur site Web.

Pour un récit très détaillé, avec plein de technique, d'un test de NAT64 avec DNS64, voir l'article de Jérôme Durand « J'ai testé pour vous : Stateful NAT64 avec DNS64 ».


Téléchargez le RFC 6146


L'article seul

RFC 6145: IP/ICMP Translation Algorithm

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : X. Li, C. Bao (CERNET Center/Tsinghua University), F. Baker (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 Avril 2011


Parmi les nombreuses techniques de coexistence d'IPv4 et IPv6, le groupe de travail Behave, dans sa version 2 (la 1 avait été consacrée aux techniques permettant de supporter le NAT) développe 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 est l'algorithme de traduction, présenté dans ce RFC 6145.

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 6145 est la version sans état du traducteur, c'est-à-dire que le traducteur peut traiter chaque paquet indépendemment 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. Mais elle a 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 6145 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 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.

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 6 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 (par exemple en modifiant la valeur de la MTU dans certains messages Packet too big).

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. 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 2765 ? Ils sont résumés en section 2. Outre une complète réorganisation des documents, il s'agit surtout de détailler bien davantage les opérations à effectuer.

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 6145


L'article seul

RFC 6144: Framework for IPv4/IPv6 Translation

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : F. Baker (Cisco), X. Li, C. Bao (CERNET Center/Tsinghua University), K. Yin (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 Avril 2011


Le groupe de travail Behave de l'IETF a travaillé pendant longtemps sur les mécanismes permettant de communiquer malgré la présence d'un routeur NAT sur le trajet. Ayant terminé ce travail avec succès, il a été muni d'une nouvelle charte pour travailler sur la transition IPv4 -> IPv6, notamment sur un mécanisme de traduction pour permettre à des machines purement v4 de parler à des machines purement v6 et réciproquement. Le groupe « Behave 2 », en ayant fini avec NAT44 s'est donc attaqué à cette tâche et ce RFC est le deuxième de cette nouvelle série (le premier avait été le RFC 6052), qui décrit NAT64.

Il ne décrit pas une technique ou un protocole mais fournit seulement le cadre général dans lequel vont s'inscrire les autres RFC du nouveau groupe Behave comme le RFC 6145 sur le protocole de traduction ou le RFC 6147 sur l'aide que lui apporte le DNS. La liste de ces documents est en section 3.3.

En effet, l'IETF avait déjà normalisé une technique de traduction d'adresses entre IPv4 et IPv6, le NAT-PT (RFC 2766), technique qui avait été abandonnée officiellement par le RFC 4966. La traduction d'adresses entre v4 et v6 n'était pas forcément considérée mauvaise en soi mais NAT-PT était vu comme une mauvaise solution, pour les raisons expliquées dans le RFC 4966.

Mais il est vrai que la traduction d'adresses a toujours été mal vue à l'IETF et que NAT-PT a du faire face à une forte opposition. Le modèle de transition d'IPv4 vers IPv6 promu par l'IETF (RFC 4213) a toujours été d'activer IPv6 au fur et à mesure, de laisser coexister IPv4 et IPv6 sur le réseau et les machines pendant un moment (stratégie de la « double pile ») puis, une fois qu'IPv6 était généralisé, de supprimer IPv4 petit à petit. Cette méthode était encore raisonnable en 2005, lorsque le RFC 4213 a été publié, mais, aujourd'hui, après des années de ratiocination, alors que l'épuisement des adresses IPv4 est effectif, elle n'est plus réaliste : nous n'avons tout simplement plus le temps de procéder à une telle migration ordonnée (cf. section 1.4). Des machines purement v6 vont apparaître, tout simplement parce qu'il n'y aura plus d'adresses v4, alors que les machines purement v4 existant aujourd'hui n'auront pas encore commencé à migrer. Les mécanismes de traduction d'adresses d'une famille à l'autre prennent donc tout leur intérêt (section 1 du RFC). Le RFC 5211 propose donc un autre plan de transition, faisant sa place à ces mécanismes.

La section 1.1 explique pourquoi considérer les mécanismes de traduction d'adresses, à côté des deux techniques du RFC 4213 (la double-pile mais aussi les tunnels). Si la traduction d'adresses est souvent utilisé pour de mauvaises raisons (par exemple parce qu'elle assurerait la sécurité des machines), elle présente aussi des avantages, notamment le fait qu'elle soit, avec les ALG (cf. section 3.1.5), la seule à permettre la communication entre des machines purement v4 et des machines purement v6. Elle a donc sa place dans les stratégies de transition à moyen terme.

La section 1.3 fixe les objectifs de la traduction d'adresses. Il ne s'agit pas de résoudre tous les problèmes (NAT-PT avait souffert d'objectifs irréalistes) mais d'attraper les fruits les plus bas. Il y a (en simplifiant beaucoup), deux types d'application : les client/serveur comme SSH, où le serveur attend les connexions d'un client, et les pair-à-pair comme SIP, où tout le monde initie et accepte des nouvelles connexions. Celles-ci de subdivisent à leur tour en pair-à-pair « d'infrastructure » (SIP, SMTP, ...) où les connexions sont typiquement d'assez courte durée et pair-à-pair « d'échange » comme avec BitTorrent, où on choisit ses pairs (le plus fiable, le plus rapide) et où on maintient de longues sessions avec eux. Quelles sont les conséquences pratiques de cette typologie ? Les applications client/serveur nécessitent des connexions d'un client v4 vers un serveur v6 (ou réciproquement), idéalement sans que les équipements de traduction d'adresses aient à garder un état. Les applications pair-à-pair nécessitent aussi de telles connexions, et dans les deux sens cette fois, mais elles seront sans doute moins nombreuses que celles d'un client vers un serveur, et les solutions avec état seront donc moins problématiques. Enfin, dans le cas de machines purement clientes (des Minitel), il n'est pas nécessaire d'ouvrir des connexions vers elles. Dans tous les cas, s'il faut garder un état pour la traduction, il est très nettement préférable qu'il soit entièrement dans les équipements réseaux (typiquement le routeur) et que la traduction ne nécessite aucune aide de la part de la machine aux extrêmités. NAT-PT exigeait de l'état dans deux endroits (le traducteur lui-même et le serveur DNS) et que ces états soient coordonnés. Un routeur NAT IPv4 actuel a un état mais qui est entièrement dans le routeur et qui ne nécessite aucune participation d'une autre machine.

Enfin, un problème de vocabulaire quasiment philosophique. Faut-il parler de « transition » vers IPv6 sachant que ce mot connote une idée d'achèvement (un jour, il n'y aura plus d'IPv4) alors que rien n'est moins sûr et que, de toute façon, cela prendra de nombreuses années ? Certains préfèrent dire que des mécanismes comme la traduction d'adresses sont des mécanismes de « coexistence » plutôt que de « transition » (section 1.4).

La section 2 du RFC s'attache ensuite à décrire les scénarios où les mécanismes de transition pourront être utiles. Par exemple, en 2.1, le scénario est celui d'un FAI récemment apparu dans un endroit où il est très difficile d'obtenir des adresses IPv4 (par exemple en Asie ou en Afrique) et qui est donc entièrement en IPv6. Ses clients veulent quand même se connecter à des services IPv4. Des techniques comme celles du RFC 6145 peuvent alors être utilisées (rappelez-vous que notre RFC 6144 ne décrit qu'un cadre, pas des techniques spécifiques). Le scénario de la section 2.4 représente le problème inverse : un réseau ancien et jamais mis à jour, entièrement en IPv4, et qui veut accéder aux services uniquement v6. Bien plus difficile à résoudre (le petit nombre d'adresse IPv4 ne permet pas de faire une traduction d'adresses efficace, on doit consommer également les ports et ils ne sont que 65536 par adresse IP), ce problème est considéré comme « hors-sujet ». On ne peut pas résoudre tous les malheurs du monde et ce réseau devra utiliser d'autres techniques (probablement des ALG, même si le RFC ne les cite pas ici).

Le cadre complet de ces solutions à base de traduction d'adresses est en section 3. La section 3.1 liste les composants du cadre :

  • La traduction d'adresses (section 3.1.1), comment une adresse v6 est traduite en v4 et réciproquement, ce qui implique un préfixe v6 et une méthode de dérivation des adresses v4 à partir de v6 et réciproquement. Le RFC 6052 donne les détails. Pour les traductions sans état, le même algorithme sert dans les deux sens (v4 vers v6 et l'inverse). Pour celles avec état, l'algorithme ne sert que dans un sens et la table des états est utilisée en sens inverse.
  • La modification des paquets IP rendue nécessaire par la traduction d'adresses (par exemple dans ICMP puisqu'un paquet ICMP d'erreur contient une partie du paquet original, avec des adresses IP). La section 3.1.2 renvoie au RFC 6145 qui couvre le cas sans état.
  • Le maintien d'un état pour les traductions avec état (section 3.1.3), traitée dans le RFC 6146.
  • L'aide que doit apporter le DNS à ces opérations (section 3.1.4), normalisée dans le RFC 6147, qui prévoit la génération automatique d'enregistrements AAAA lorsque seul un enregistrement A existe.
  • Les ALG (Application Layer Gateways, section 3.1.5) qui sont nécessaires pour certaines applications comme FTP (le RFC sur FTP64 n'est pas encore paru) qui inclus les adresses IP dans ses données.

Une fois les composants de la solution listés (on voit qu'il faut beaucoup de choses pour faire fonctionner l'Internet malgré le retard pris à migrer vers IPv6), la section 3.2 expose leurs modes de fonctionnement. La traduction sans état (section 3.2.1) passe mieux à l'échelle et maintient la transparence du réseau de bout en bout. Mais elle ne peut pas être utilisée pour tous les scénarios. La traduction avec état (section 3.2.2) peut alors prendre le relais.

Il n'existe pas de solution magique à tous les problèmes. Le déploiement bien trop lent d'IPv6 a laissé une situation peu satisfaisante, et qui ne pourra pas être complètement résolu par de nouveaux protocoles. La section 5 rappelle donc que certaines questions n'ont pas de solution présente. Mais le groupe Behave a dû travailler dans l'urgence, pour fournir des solutions avant l'épuisement d'IPv4 et s'est donc focalisé sur les problèmes les plus « faciles ». Peut-être dans de futurs RFC ?

À noter qu'un FAI britannique a déjà un tel service déployé sur son réseau.


Téléchargez le RFC 6144


L'article seul

RFC 6143: The Remote Framebuffer Protocol

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : T. Richardson, J. Levine (RealVNC)
Pour information
Première rédaction de cet article le 8 Mars 2011


Il est assez fréquent à l'IETF qu'un protocole ne soit documenté dans un RFC que longtemps après son déploiement. C'est le cas de RFB (Remote Framebuffer Protocol), le protocole utilisé dans le système VNC, système qui permet de transmettre via un réseau TCP/IP l'interface graphique d'une machine. VNC permet, par exemple, d'avoir sur son ordinateur le bureau d'une machine distante, se s'y loguer, etc, comme si on était physiquement devant. C'est donc un concurrent de X11 avec XDMCP ou bien de NX mais avec l'avantage sur ce dernier d'avoir désormais une spécification publique, et de nombreuses mises en œuvre. Je compte une quarantaine de clients, de serveurs et de bibliothèques VNC sur mon Ubuntu.

RFB se veut un protocole simple, bien plus simple que X11, basé sur l'idée d'un serveur, tournant sur la machine distante, qui écrit dans une mémoire graphique (le framebuffer) qui est en fait située sur la machine de bureau (le client ; notez que « client » et « serveur » ont des sens différents de celui de X11). Le système VNC, qui utilise ce protocole, est très largement utilisé pour l'accès distant à une machine, exactement dans les mêmes conditions que si on était présent devant cette machine (système de fenêtrage, accès à la souris, etc).

RFB travaille au niveau de la mémoire graphique et est donc compatible avec tous les systèmes de fenêtrage comme X11 ou comme celui de Windows. Le protocole se veut simple, surtout côté client, pour pouvoir être mis en œuvre sur de petites machines. Il existe même un widget VNC/RFB pour GTK, pour ceux qui veulent mettre un client VNC dans leurs programmes.

Le client est sans état et peut donc redémarrer à tout moment et reprendre la session là où il l'avait laissée. C'est le serveur qui maintient l'état de l'interface utilisateur. Cela permet par exemple de changer de client en cours de session.

RFB, je l'ai dit, a été implémenté avant d'être spécifié et a connu plusieurs versions. Ce RFC essaie donc de documenter l'état actuel du protocole.

Si les détails prennent parfois de la place, les principes sont simples et les premières sections du RFC sont donc courtes. La section 2 décrit les connexions entre le client et le serveur. Le mode normal de fonctionnement de VNC est que le serveur tourne pendant une longue période, gardant en mémoire l'état de la mémoire graphique, le ou les clients se connectant à loisir, pendant parfois seulement de courtes périodes. Cela ressemble donc, adapté au graphique, au principe de screen. Le client peut être n'importe où sur l'Internet et se connecte par défaut au port 5900.

Loin de la richesse du protocole de X11, RFB ne fournit qu'une seule primitive : « afficher un rectangle à la position X,Y indiquée » (section 3). Cela peut sembler très inefficace mais divers encodages subtils permettent de rendre ce protocole supportable. Les mises à jour (nouveaux rectangles à afficher) ne sont jamais envoyées par le serveur mais demandées par le client (message FramebufferUpdateRequest, section 7.5.3). Le protocole est donc adaptatif : un client lent ne demandera pas souvent des mises à jour et aura donc moins de travail. Si une même région de la mémoire graphique voit plusieurs modifications successives, le client lent peut donc parfaitement sauter les étapes intermédiaires.

Afficher des rectangles, c'est très joli mais un environnement graphique digne de ce nom doit aussi permettre à l'utilisateur de dire quelque chose, par exemple de taper au clavier ou de cliquer avec la souris. La section 4 résume le protocole d'entrée de RFB : ce dernier ne connait que clavier et souris (multi-boutons). Tout autre périphérique d'entrée doit donc être modélisé comme clavier ou comme souris.

Et les pixels, comment sont-ils modélisés ? La section 5 décrit le modèle. Il repose sur une négociation entre client et serveur, à l'ouverture de la connexion, où le client est roi. C'est lui qui choisit la représentation des pixels sur le réseau, et il peut donc choisir ce qui lui fait le moins de travail, tout reposant alors sur le serveur. Les deux formats les plus classiques sont le « couleurs réelles » où chaque pixel est un nombre sur 24 bits, chaque groupe de 8 bits indiquant l'intensité de rouge, de vert ou de bleu, ou bien le « table des couleurs » où chaque pixel est un nombre sur 8 bits indiquant une entrée d'une table où sont stockées les 256 couleurs possibles.

Plusieurs encodages sont ensuite possibles dans RFB, six étant définis par notre RFC 6143, permettant plus ou moins de compression.

En parlant de négociation, comme RFB existe depuis un certain temps et a connu plusieurs versions, la section 6 décrit la notion de version du protocole. Notre RFC 6143 normalise la version 3.8. Les versions précédentes résumées dans l'annexe A. Si une version 4.x apparaîtra peut-être un jour, la version actuelle, la 3.8, est extensible sans avoir besoin de changer de version. On peut ainsi introduire :

  • De nouveaux encodages en plus des six indiqués plus haut,
  • Des nouvelles fonctions du protocole (appelées « pseudo-encodages » car, dans le processus de négociation initial, elles sont représentées comme des encodages),
  • Des nouveaux mécanismes de sécurité.

Le protocole RFB lui-même figure dans la section 7. Elle est très longue, bien plus que les autres sections, mais pas forcément plus difficile, elle liste juste tous les messages possibles. RFB peut fonctionner sur n'importe quel protocole de transport fiable (comme TCP). La communication commence par une phase de négociation entre le client et le serveur, puis l'initialisation, puis l'envoi des messages de mise à jour de la mémoire graphique. La description des messages utilise quelques types de base comme U8 (entier de huits bits non signé), S16 (entier de seize bits signé, toujours en gros boutien), etc.

La section 7.1 décrit le protocole de négociation. Ainsi, le serveur commence par envoyer un message où il indique la version (message ProtocolVersion, ici, le serveur à l'autre bout est x11vnc) :

% nc ec2-xxx.eu-west-1.compute.amazonaws.com 5900
RFB 003.008

La sécurité se négocie ensuite (section 7.2). La phase d'initialisation est décrite en section 7.3. Par exemple, le message ServerInit contiendra la hauteur et la largeur de la mémoire graphique en nombre de pixels (tous les deux en UA16), ainsi que le format de représentation des pixels (décrit en section 7.4).

La représentation des caractères tapés au clavier du client (message KeyEvent, section 7.5.4) est complexe. La valeur utilisée est un keysym de X11 (même si ni le client, ni le serveur n'utilisent X11). Si vous avez une machine Unix où X11 est installé, le fichier /usr/include/X11/keysymdef.h vous donnera une idée des valeurs possibles. Cela aurait été plus simple si un point de code Unicode était envoyé... Mais il n'y a que pour ASCII que le keysym correspond au point de code. Le RFC va même jusqu'à préciser qu'il vaut mieux utiliser le keysymI traditionnel, même s'il y en a un pour le caractère Unicode. l faut dire que le protocole RFB ne transmet pas que des caractères mais aussi des états des touches (comme le fait que la touche Majuscule est pressée) et des touches non affectées à un caractère particulier (comme F1, F2, etc). Les règles d'interprétation des keysyms sont d'une grande complexité. Le lecteur curieux doit se munir d'aspirine avant de lire lui-même cette section.

Plus facile, le cas du « pointeur » (la souris) en section 7.5.5. Les événements sont simplement « bouton pressé » et « bouton relaché », les attributs étant la position X,Y et le numéro du bouton (huit boutons sont prévus, afin de pouvoir modéliser des dispositifs d'entrée plus complexes comme les roulettes).

Jusqu'à présent, je n'ai parlé que des messages envoyés par le client RFB au serveur. En sens inverse, le principal message est FramebufferUpdate (section 7.6.1) qui indique un changement dans la mémoire graphique. Il contient un certain nombre de rectangles et, pour chacun d'eux, sa position X,Y, sa hauteur et sa largeur, et le type d'encodage utilisé.

Les encodages sont définis en section 7.7. Les six standards à l'heure actuelle sont :

  • Raw : comme son nom l'indique, aucun effort, on envoie juste les pixels l'un après l'autre (largeur, puis hauteur).
  • CopyRect : le serveur indique les coordonnées d'un rectangle existant dans la mémoire du client. Cela sert, par exemple, lorsqu'une fenêtre est déplacée sur l'écran.
  • RRE encoding : officiellement abandonné.
  • Hextile encoding : officiellement abandonné.
  • TRLE encoding : Tiled Run-Length Encoding utilise un ensemble de techniques de compression dont le run-length encoding appliquée à des « tuiles » de 16x16 pixels.
  • ZRLE encoding : Zlib Run-Length Encoding utilise la compression Zlib (RFC 1950 et RFC 1951).

La normalisation du Remote Framebuffer Protocol a nécessité quelques nouveaux registres IANA, décrits en section 8 : celui des types de sécurité, celui des messages RFB, et celui des encodages, qui permettra d'étendre la liste de six encodages présentée plus haut.

Quelle est la sécurité de RFB ? Par défaut, inexistante : comme le note justement la section 9, l'authentification est faible et la confidentialité et l'intégrité sont nulles. RFB est traditionnellement utilisé avec une protection fournie par, par exemple, un VPN chiffré, seule façon de l'utiliser de manière sûre.

L'annexe A du RFC résume les différences entre cette version du protocole (la 3.8) et les précédentes. Ces différences sont concentrées dans la phase de négociation.

À l'heure d'aujourd'hui, je n'ai pas trouvé de connaissance de ce protocole dans tcpdump mais Wireshark, par contre, le décode, sous son ancien nom de VNC (qui est désormais uniquement le nom d'un logiciel). C'est aussi le nom à utiliser sur pcapr : http://www.pcapr.net/browse?proto=vnc&order=date.


Téléchargez le RFC 6143


L'article seul

RFC 6137: The Network Trouble Ticket Data Model

Date de publication du RFC : Février 2011
Auteur(s) du RFC : Dimitris Zisiadis (CERTH), Spyros Kopsidas (CERTH), Matina Tsavli (CERTH), Leandros Tassiulas (CERTH), Chrysostomos Tziouvaras (GRNET), Guillaume Cessieux (CNRS), Xavier Jeannin (CNRS)
Expérimental
Première rédaction de cet article le 19 Février 2011


Les centres qui gèrent les réseaux qui composent l'Internet, les NOC, ont régulièrement besoin d'échanger de l'information. Celle-ci, concernant les incidents, les nouveautés, les problèmes, circule souvent en quantités impressionnantes et est donc une bonne candidate pour l'automatisation. Ce RFC expérimental propose donc un format standard, basé sur XML, pour représenter l'information qui circule entre NOC, notamment ceux qui gèrent en commun une grande grille, ce qui est le cas d'EGEE, où travaillent les auteurs. Il est important pour de grosses infrastructures réseau comme les grilles de calculs, qui s'étendent sur plusieurs domaines administratifs, de pouvoir interpréter correctement les tickets avec un minimum de dépendance vis-à-vis de l'origine du ticket. L'effort de normalisation prend tout son sens dans ce contexte. Un ticket pourra donc être lu et compris sans avoir besoin de connaître les particularités et la terminologie du domaine d'origine.

Le but (section 1) n'est pas de remplacer les outils de gestion de tickets de chaque NOC mais d'avoir un format d'échange standard, suivant les souhaits du RFC 1297. Les tickets ainsi formatés pourront automatiquement être émis par un NOC, reçus par un autre, être analysés, etc. Ces outils de gestion de tickets seront ensuite utilisés pour analyser le problème, suivre son évolution et, d'une manière générale, assurer un bon fonctionnement du réseau.

On comprend mieux la taille du problème quant on voit que la grille de calcul EGEE qui utilise les NREN (vingt participants) pour sa connectivité, reçoit 800 tickets et 2500 messages par mois.

Notre RFC décrit un modèle de données en UML, puis un format concret de représentation en XML. Un problème classique que rencontrent toutes les tentatives de normalisation dans ce domaine est qu'il faut à la fois décrire de manière formelle l'incident, en énumérant de manière limitative les choix possibles, pour permettre son traitement automatique, tout en gardant des possibilités d'exprimer des problèmes nouveaux, ce qui impose de garder la possibilité de mettre du texte libre, non formaté.

Voyons d'abord les types de données utilisés (section 2). On y trouve plusieurs énumérés comme TT_TYPE qui indique si le ticket concerne un problème opérationnel, administratif, ou bien n'est là que pour information, TYPE qui indique si l'événement était prévu ou accidentel, TT_STATUS qui donne l'état du ticket (ouvert, résolu, annulé, fermé..., avec un diagramme de transition apparemment obligatoire). On trouve aussi bien sûr des chaînes de caractères (qui seront simplement le type W3C XML Schema xs:string) et des heures (au format du RFC 3339, alias xs:dateTime).

Armée de ces définitions, la section 3 détaille la longue liste des attributs d'un ticket. On y trouvera même un diagramme de classe UML en art ASCII... Parmi ces attributs, les grands classiques, comme l'identificateur unique du ticket (formé par la concaténation de l'identificateur du NOC et d'un identificateur local, ce qui permet d'allouer ces identificateurs uniques de manières décentralisée), l'état du ticket, sa date de création, l'identificateur du NOC qui est à l'origine du ticket (le RFC n'explique pas comment ses identificateurs, qui doivent être uniques, sont attribués et conservés), une description courte qui est sélectionnée à partir d'une liste pré-définie (pour permettre le traitement automatique) et une description longue qui est en texte libre (la langue utilisée peut être représenté dans le fichier XML par un attribut lang - pour des raisons que j'ignore, l'attribut standard XML xml:lang n'a pas été utilisé), les identificateurs de tickets ayant un rapport avec celui-ci, etc. Pour chaque attribut est indiqué s'il est obligatoire ou non.

La section 4 décrit l'approche utilisée pour l'internationalisation puisque les tickets seront échangés entre NOC de pays et de langues différents. Les champs formels (comme la description courte) n'ont pas besoin d'être adaptés (le logiciel de chaque NOC pourra les présenter comme il le voudra), les textes libres (comme la description longue de l'incident) peuvent être dans n'importe quelle langue (des systèmes de traduction automatique sont prévus pour EGEE dans le futur).

Si vous êtes impatients de voir à quoi ressemblent ces fameux tickets en XML, sautez directement à la section 5, qui présente les exemples. Voici un joli ticket indiquant une panne chez Forth en Grèce :


   <?xml version="1.0" encoding="UTF-8"?>
   <!-- This example describes a link failure that was detected -->
   <NTTDM-Document version="1.00" lang="el"
                   xmlns="urn:ietf:params:xml:ns:nttdm-1.0">
   <Ticket>
    <Original_ID>5985</Original_ID>
    <Partner_ID>01</Partner_ID>
    <TT_ID>01_5985</TT_ID>
    <TT_Title>Forth Link Failure</TT_Title>
    <TT_Type>Operational</TT_Type>
    <TT_Status>Closed</TT_Status>
    <TT_Open_Datetime>2008-12-16T10:01:15+02:00</TT_Open_Datetime>
    <TT_Short_Description>Core Line Fault</TT_Short_Description>
    <TT_Long_Description>Forth Link Failure</TT_Long_Description>
    <Type>Unscheduled</Type>
    <TT_Impact_Assessment>No connectivity</TT_Impact_Assessment>
    <Start_Datetime>2008-12-16T09:55:00+02:00</Start_Datetime>
    <TT_Last_Update_Time>2008-12-16T15:00:34+02:00</TT_Last_Update_Time>
    <Location>HERAKLION</Location>
    <History>Optical transmitter was changed</History>
    <TT_Close_Datetime>2008-12-16T15:05:00+02:00</TT_Close_Datetime>    
    <End_Datetime>2008-12-16T15:01:21+02:00</End_Datetime>
    <Network_Node>
     <Node>FORTH</Node>
    </Network_Node>
    <Network_Link_Circuit>
     <Link_Circuit>FORTH-2</Link_Circuit>
    </Network_Link_Circuit>
    <Open_Engineer>Dimitris Zisiadis</Open_Engineer>
    <Close_Engineer>Guillaume Cessieux</Close_Engineer>
    <Contact_Engineers>
     <Engineer>Spyros Kopsidas</Engineer>
     <Engineer>Chrysostomos Tziouvaras</Engineer>
    </Contact_Engineers>
    <TT_Priority>High</TT_Priority>
   </Ticket>
   </NTTDM-Document> 

On notera que l'exemple est imparfait : l'étiquette de langue el indique du grec mais le texte est entièrement en anglais.

Enfin, la section 6 contient le schéma complet, en langage W3C XML schema et la section 7 quelques avertissements de sécurité. Comme le contenu des tickets peut être sensible, il peut être utile de chiffrer et d'authentifier les tickets mais le RFC ne suggère pas de technique standard pour cela.

Merci à Xavier Jeannin pour sa relecture.


Téléchargez le RFC 6137


L'article seul

RFC 6129: The 'application/tei+xml' mediatype

Date de publication du RFC : Février 2011
Auteur(s) du RFC : L. Romary (TEI Consortium and INRIA), S. Lundberg (The Royal Library, Copenhagen)
Pour information
Première rédaction de cet article le 12 Février 2011


Petit à petit, de nombreux formats XML obtiennent un type MIME, comme indiqué dans le RFC 3023. Ces types permettent d'identifier un contenu de manière précise sur le réseau, et ont la forme application/XXX+xml où XXX indique le format précis. Ici, notre RFC concerne le type application/tei+xml, pour le format TEI, un format de documents très utilisé dans le monde des bibliothèques et dans les sciences humaines en général (le secteur de l'étude des documents anciens est un utilisateur très visible de TEI, mais ce n'est pas le seul).

En effet, TEI (Text Encoding and Interchange) est un format utilisé depuis longtemps, par les musées, les bibliothèques, et des chercheurs, par exemple pour encoder un manuscrit qu'on a réussi à déchiffrer. Nous sommes donc ici à l'intersection du monde des geeks et de celui d'Umberto Eco. Si vous voulez voir des exemples de documents TEI, on en trouve un peu partout, par exemple une version d'« Alice au pays des merveilles » issue du Projet Gutenberg et TEIsée. L'original est en http://www.gnutenberg.de/pgtei/0.5/examples/alice/alice.tei mais j'en ai fait une version légèrement modifiée pour en retirer ce qui était spécifique de Gutenberg.

Comme tout bon fichier XML, les documents TEI ont un namespace XML, ici http://www.tei-c.org/ns/1.0. Plusieurs éléments XML peuvent être utilisés pour être la racine d'un document TEI, mais les plus communs sont <TEI> et <teiCorpus>. On les trouve souvent sur l'Internet avec des extensions de fichier .tei et .teiCorpus. (À noter qu'une recherche Google des fichiers se terminant par .tei ne donne pas le résultat attendu en raison du nombre de chinois nommés Tei...)

Notre RFC est très court. TEI lui-même est spécifié dans des documents du consortium TEI (le format est du Relax NG et disponible en format XML ou en format compact) et ce RFC ne fait que spécifier le type MIME et donner quelques conseils. Armé de ces schémas, on peut valider avec rnv :

% rnv tei_all.rnc alice.tei
alice.tei

Par contre, la validation avec xmllint échoue en raison d'une boucle sans fin.

Enfin, le consortium TEI fournit divers outils permettant, par exemple, la traduction vers LaTeX ou HTML. À noter que le journal de ce consortium est sur revues.org.

À noter que la traditionnelle section sur la sécurité couvre des points inhabituels dans un RFC. Par exemple, les documents encodés en TEI peuvent être tellement anciens qu'ils sont montés dans le domaine public mais parfois ils sont au contraire encore plombés par des règles d'appropriation intellectuelle. Le format TEI permet de spécifier ces règles, avec une grande granularité (élément availability). Ces spécifications peuvent être utilisées pour mettre en œuvre un système de menottes numériques ou, plus simplement, pour permettre l'application du droit moral de l'auteur (citer correctement les auteurs de chaque partie d'un document TEI).

D'autre part, TEI a déjà été utilisé pour encoder des documents ayant un rôle légal, et qui peuvent être encore applicables des siècles plus tard. Il peut donc être nécessaire de prendre des précautions pour vérifier l'authenticité et l'intégrité de ces documents (TEI lui-même ne le fait pas).

Enfin, les documents encodés peuvent être confidentiels et, là encore, cette confidentialité peut devoir être respectée sur de longues périodes (des dizaines d'années, si des personnes physiques sont mentionnées). Regardez donc bien les règles pour les archives de votre pays avant de distribuer des documents TEI.

Merci à Laurent Romary et Sebastian Rahtz pour leurs relectures et pour m'avoir envoyé un autre exemple de document TEI, un encodage du « Conte de Noël » de Dickens. Le fichier carol.zip contient le source TEI et on peut en tirer automatiquement une version EPUB, qui est dans le fichier 3256.epub.


Téléchargez le RFC 6129


L'article seul

RFC 6126: The Babel Routing Protocol

Date de publication du RFC : Avril 2011
Auteur(s) du RFC : J. Chroboczek (PPS, University of Paris 7)
Expérimental
Première rédaction de cet article le 6 Avril 2011


La recherche sur les protocoles de routage ne désarme pas, motivée à la fois par les avancées de la science et par les nouvelles demandes (par exemple pour les réseaux ad hoc). Ainsi Babel est un nouveau protocole de routage, de la famille des protocoles à vecteurs de distance, qui vise notammment à réduire drastiquement les probabilités de boucle.

Il y a en effet deux familles de protocole de routage, ceux à vecteurs de distance comme l'ancêtre RIP et ceux à états des liens comme OSPF (RFC 2328). Ce dernier est aujourd'hui bien plus utilisé que RIP, et à juste titre. Mais les problèmes de RIP n'ont pas forcément la même ampleur chez tous les membres de sa famille, et les protocoles à vecteurs de distance n'ont pas dit leur dernier mot.

Babel s'inspire de protocoles de routage plus récents comme DSDV. Il vise à être utilisable, à la fois sur les réseaux classiques, où le routage se fait sur la base du préfixe IP et sur les réseaux ad hoc, où il n'y a typiquement pas de regroupement par préfixe, où le routage se fait sur des adresses IP « à plat » (on peut dire que, dans un réseau ad hoc, chaque nœud est un routeur).

L'un des principaux inconvénients du bon vieux protocole RIP est sa capacité à former des boucles lorsque le réseau change de topologie. Ainsi, si un lien entre les routeurs A et B casse, A va envoyer les paquets à un autre routeur C, qui va probablement les renvoyer à A et ainsi de suite (le champ « TTL » pour IPv4 et « Hop limit » dans IPv6 a précisement pour but d'éviter qu'un paquet ne tourne sans fin). Babel, lui, évitera les boucles la plupart du temps mais, en revanche, il ne trouvera pas immédiatement la route optimale entre deux points. La section 1.1 du RFC spécifie plus rigoureusement les propriétés de Babel.

Autre particularité de Babel, les associations entre deux machines pourront se faire même si elles utilisent des paramètres différents (par exemple pour la valeur de l'intervalle de temps entre deux « Hello » ; cf. l'annexe B pour une discussion du choix de ces paramètres). Le RFC annonce ainsi que Babel est particulièrement adapté aux environnements « sans-fil » où certaines machines, devant économiser leur batterie, devront choisir des intervalles plus grands.

Je l'ai dit, rien n'est parfait en ce bas monde, et Babel a des limites, décrites en section 1.2. D'abord, Babel envoie périodiquement toutes les informations dont il dispose, ce qui, dans un réseau stable, mène à un trafic total plus important que, par exemple, OSPF (qui n'envoie que les changements). Ensuite, Babel a des mécanismes d'attente lorsqu'un préfixe disparait, qui s'appliquent aux préfixes plus généraux. Ainsi, lorsque deux préfixes deviennent agrégés, l'agrégat n'est pas joignable immédiatement. Notre RFC a le statut « Expérimental » et l'usage découvrira peut-être d'autres faiblesses.

Comment Babel atteint-il ses merveilleux objectifs ? La section 2 détaille les principes de base du protocole, la 3 l'échange de paquets et la 4 l'encodage d'iceux. Commençons par les principes. Babel est fondé sur le bon vieil algorithme de Bellman-Ford, tout comme RIP. Tout lien entre deux points A et B a un coût (qui n'est pas forcément un coût monétaire, c'est un nombre qui a la signification qu'on veut, cf. section 3.5.2). Le coût est additif (la somme des coûts d'un chemin complet faisant la métrique du chemin, section 2.1 et annexe A), ce qui veut dire que Métrique(A -> C) - pour une route passant par B - = Coût(A -> B) + Coût(B -> C). L'algorithme va essayer de calculer la route ayant la métrique le plus faible.

Un nœud Babel garde trace de ses voisins nœuds en envoyant périodiquement des messages Hello et en les prévenant qu'ils ont été entendus par des messages IHU (I Heard You). Le contenu des messages Hello et IHU permet de déterminer le coût.

Pour chaque source (d'un préfixe, pas d'un paquet), le nœud garde trace de la métrique vers cette source (lorsqu'un paquet tentera d'atteindre le préfixe annoncé) et du routeur suivant (next hop). Au début, évidemment la métrique est infinie et le routeur suivant indéterminé. Le nœud envoie à ses voisins les routes qu'il connait. Si celle-ci est meilleure que celle que connait le voisin, ce dernier l'adopte (si la distance était infinie - route inconnue, toute route sera meilleure).

L'algorithme « naïf » ci-dessus est ensuite amélioré de plusieurs façons : envoi immédiat de nouvelles routes (sans attendre l'émission périodique), mémorisation, non seulement de la meilleure route mais aussi de routes alternatives, pour pouvoir réagir plus vite en cas de coupure, etc.

La section 2.3 rappelle un problème archi-connu de l'algorithme de Bellman-Ford : la facilité avec laquelle des boucles se forment. Dans le cas d'un réseau simple comme celui-ci  A annonce une route de métrique 1 vers S, B utilise donc A comme routeur suivant, avec une métrique de 2. Si le lien entre S (S = source de l'annonce) et A casse  comme B continue à publier une route de métrique 2 vers S, A se met à envoyer les paquets à B. Mais B les renvoie à A, créant ainsi une boucle. Les annonces ultérieures ne résolvent pas le problème : A annonce une route de métrique 3, passant par B, B l'enregistre et annonce une route de métrique 4 passant par A, etc. RIP résoud le problème en ayant une limite arbitraire à la métrique, limite qui finit par être atteinte et stoppe la boucle (méthode dite du « comptage à l'infini »).

Cette méthode oblige à avoir une limite très basse pour la métrique. Babel a une autre approche : les mises à jour ne sont pas forcément acceptées, Babel teste pour voir si elles créent une boucle (section 2.4). Toute annonce est donc examinée au regarde d'une condition, dite « de faisabilité ». Plusieurs conditions sont possibles. Par exemple, BGP utilise la condition « Mon propre numéro d'AS n'apparaît pas dans l'annonce. ». (Cela n'empêche pas les micro-boucles, boucles de courte durée en cas de coupure, cf. RFC 5715.) Une autre condition, utilisée par DSDV et AODV, repose sur l'observation qu'une boucle ne se forme que lorsqu'une annonce a une métrique supérieure à la métrique de la route qui a été retirée. En n'acceptant que les annonces qui diminuent la métrique, on peut donc éviter les boucles. Babel utilise une règle un peu plus complexe, empruntée à EIGRP, qui tient compte de l'histoire des annonces faites par le routeur.

Comme il n'y a pas de miracles en routage, cette idée de ne pas accepter n'importe quelle annonce de route a une contrepartie : la famine. Celle-ci peut se produire lorsqu'il existe une route mais qu'aucun routeur ne l'accepte (section 2.5). EIGRP résoud le problème en « rédémarrant » tout le réseau (resynchronisation globale des routeurs). Babel, lui, emprunte à DSDV une solution moins radicale, en numérotant les annonces, de manière strictement croissante, lorsqu'un routeur détecte un changement dans ses liens. Une route pourra alors acceptée si elle est plus récente (si elle a un numéro de séquence plus élevé).

À noter que tout se complique s'il existe plusieurs routeurs qui annoncent originellement la même route (section 2.7 ; un exemple typique est la route par défaut, annoncée par tous les routeurs ayant une connexion extérieure). Babel gère ce problème en associant à chaque préfixe l'identité du routeur qui s'est annoncé comme origine et considère par la suite ces annonces comme distinctes, même si le préfixe est le même. Conséquence : Babel ne peut plus garantir qu'il n'y aura pas de boucle (Babel essaie de construire un graphe acyclique mais l'union de plusieurs graphes acycliques n'est pas forcément acyclique). Par contre, il pourra détecter ces boucles a posteriori et les éliminer plus rapidement qu'avec du comptage vers l'infini.

Voilà pour les principes. Et le protocole ? La section 3 le décrit. Chaque routeur a une identité sur huit octets (le plus simple est de prendre l'adresse MAC d'une des interfaces). Les messages sont envoyés dans des paquets UDP et encodés en TLV. Le paquet peut être adressé à une destination unicast ou bien multicast.

Un routeur Babel doit se souvenir d'un certain nombre de choses (section 3.2) :

  • Le numéro de séquence, qui croît strictement,
  • La liste des interfaces réseau où parler le protocole,
  • La liste des voisins qu'on a entendus,
  • La liste des sources (routeurs qui ont été à l'origine de l'annonce d'un préfixe). Elle sert pour calculer les critères d'acceptation (ou de rejet) d'une route. Babel consomme donc plus de mémoire que RIP, qui ne connait que son environnement immédiat, alors qu'un routeur Babel connaît tous les routeurs du réseau.
  • Et bien sûr la table des routes, celle qui, au bout du compte, sera utilisée pour la transmission des paquets.

Les messages Babel ne bénéficient pas d'une garantie de délivrance (c'est de l'UDP, après tout), mais un routeur Babel peut demander à ses voisins d'accuser réception (section 3.3). La décision de le demander ou pas découle de la politique locale de chaque routeur. Si un routeur ne demande pas d'accusé de réception, l'envoi périodique des routes permettra de s'assurer que, au bout d'un certain temps, tous les routeurs auront toute l'information. Les accusés de réception peuvent toutefois être utiles en cas de mises à jour urgentes dont on veut être sûr qu'elles ont été reçues. (L'implémentation actuelle de Babel ne les utilise pas.)

Comment un nœud Babel trouve t-il ses voisins ? La section 3.4 décrit ce mécanisme. Les voisins sont détectés par les messages Hello qu'ils émettent. Les messages IHU (I Heard You) envoyés en sens inverse permettent notamment de s'assurer que le lien est bien bidirectionnel.

Les détails de la maintenance de la table de routage figurent en section 3.5. Chaque mise à jour envoyée par un nœud Babel est un quintuplet {préfixe IP, longueur du préfixe, ID du routeur, numéro de séquence, métrique}. Chacune de ces mises à jour est évaluée en regard des conditions de faisabilité : une distance de faisabilité est un doublet {numéro de séquence, métrique} et ces distances sont ordonnées en comparant d'abord le numéro de séquence (numéro plus élevée => distance de faisabilité meilleure) et ensuite la métrique (où le critère est inverse). Une mise à jour n'est acceptée que si sa distance de faisabilité est meilleure.

Si la table des routes contient plusieurs routes vers un préfixe donné, laquelle choisir et donc réannoncer aux voisins (section 3.6) ? La politique de sélection n'est pas partie intégrante de Babel. Plusieurs mises en œuvre de ce protocole pourraient faire des choix différents. Les seules contraintes à cette politique sont qu'il ne faut jamais réannoncer les routes avec une métrique infinie (ce sont les retraits, lorsqu'une route n'est plus accessible), ou les routes infaisables (selon le critère de faisabilité cité plus haut). Si les différents routeurs ont des politiques différentes, cela peut mener à des oscillations (routes changeant en permanence) mais il n'existe pas à l'heure actuelle de critères scientifiques pour choisir une bonne politique. On pourrait imaginer que le routeur ne garde que la route avec la métrique le plus faible, ou bien qu'il privilégie la stabilité en gardant la première route sélectionnée, ou encore qu'il prenne en compte des critères comme la stabilité du routeur voisin dans le temps. En attendant les recherches sur ce point, la stratégie conseillée est de privilégier la route de plus faible métrique, en ajoutant un petit délai pour éviter de changer trop souvent.

Une fois le routeur décidé, il doit envoyer les mises à jour à ses voisins (section 3.7). Ces mises à jour sont transportées dans des paquets multicast (mais peuvent l'être en unicast). Les changements récents sont transmis immédiatement, mais un nœud Babel transmet de toute façon la totalité de ses routes à intervalles réguliers. Petite optimisation : les mises à jour ne sont pas transmises sur l'interface réseau d'où la route venait, mais uniquement si on est sûr que ladite interface mène à un réseau symétrique (un Ethernet filaire est symétrique mais un lien WiFi ad hoc ne l'est pas forcément).

Un routeur Babel peut toujours demander explicitement des annonces de routes à un voisin (section 3.8). Il peut aussi demander une incrémentation du numéro de séquence, au cas où il n'existe plus aucune route pour un préfixe donné (problème de la famine, section 3.8.2.1).

La section 4 spécifie l'encodage des messages Babel sur le réseau. C'est un paquet UDP, envoyé à une adresse multicast (FF02:0:0:0:0:0:1:6 ou 224.0.0.111) ou bien unicast, avec un TTL de 1 (puisque les messages Babel n'ont jamais besoin d'être routés), et un port source et destination de 6697. En IPv6, les adresses IP de source et de destination unicast sont link-local et en IPv4 des adresses du réseau local.

Les données envoyées dans le message sont typées et la section 4.1 liste les types possibles, par exemple interval, un entier de 16 bits qui sert à représenter des durées en centisecondes (rappelez-vous que, dans Babel, un routeur informe ses voisins de ses paramètres temporels, par exemple de la fréquence à laquelle il envoie des Hello). Plus complexe est le type address, puisque Babel permet d'encoder les adresses par différents moyens (par exemple, pour une adresse IPv6 link-local, le préfixe fe80::/64 peut être omis).

Ensuite, ces données sont mises dans des TLV, eux-même placés derrière l'en-tête Babel, qui indique un nombre magique (42...) pour identifier un paquet Babel, un numéro de version (aujourd'hui 2) et la longueur du message. (La fonction babel_print_v1 dans le patch de tcpdump est un bon moyen de découvrir les différents types et leur rôle.) Chaque TLV, comme son nom l'indique, comprend un type (entier sur huit bits), une longueur et une valeur, le corps, qui peut comprendre plusieurs champs (dépendant du type). Parmi les types existants :

  • 0 et 1, qui doivent être ignorés (ils servent si on a besoin d'aligner les TLV),
  • 2, qui indique une demande d'accusé de réception, comme le Echo Request d'ICMP (celui qui est utilisé par la commande ping). Le récepteur doit répondre par un message contenant un TLV de type 3.
  • 4, qui désigne un message Hello. Le corps contient notamment le numéro de séquence actuel du routeur. Le type 5 désigne une réponse au Hello, le IHU, et ajoute des informations comme le coût de la liaison entre les deux routeurs ou comme la liste des voisins entendus (les amateurs d'OSPF noteront que, dans ce protocole, la liste des voisins détectés apparaît dans le Hello, ce qui augmente sa taille).
  • 6 sert pour transmettre l'ID du routeur.
  • 7 et 8 servent pour les routes elles-mêmes. 7 désigne le routeur suivant qui sera utilisé (next hop) pour les routes portées dans les TLV de type 8. Chaque TLV Update (type 8) contient notamment un préfixe (avec sa longueur), un numéro de séquence, et une métrique.
  • 9 est une demande explicite de route (lorsqu'un routeur n'a plus de route vers un préfixe donné ou simplement lorsqu'il est pressé et ne veut pas attendre le prochain message). 10 est la demande d'un nouveau numéro de séquence.

Quelle est la sécurité de Babel ? La section 6 dit franchement qu'elle est à peu près inexistante. Un méchant peut annoncer les préfixes qu'il veut, avec une faible métrique pour être sûr d'être sélectionné, afin d'attirer tout le trafic. Des extensions futures à Babel (par exemple telles que spécifiées dans le projet draft-ietf-ospf-auth-trailer-ospfv3) permettront peut-être de signer les messages mais ce n'est pas encore fait. (Notons que, en matière de routage, la signature ne résoud pas tout : c'est une chose d'authentifier un voisin, une autre de vérifier qu'il est autorisé à annoncer ce préfixe.)

En IPv6, une protection modérée est fournie par le fait que les adresses source et destination sont locales au lien. Comme les routeurs IPv6 ne sont pas censés faire suivre les paquets ayant ces adresses, cela garantit que le paquet vient bien du réseau local.

Vous pourrez trouver plus d'informations sur Babel en lisant le RFC, ou bien sur la page Web officielle.

Qu'en est-il des mises enœuvre de ce protocole ? Il existe une implémentation d'exemple, assez éprouvée pour être disponible en paquetage dans plusieurs systèmes, comme babeld dans Debian ou dans OpenWrt, plateforme très souvent utilisée pour des routeurs libres (cf. https://dev.openwrt.org/browser/packages/net/babel). Si vous voulez écrire vôtre implémentation, l'annexe C contient plusieurs conseils utiles, accompagnés de calculs, par exemple sur la consommation mémoire et réseau. Le RFC proclame que Babel est un protocole relativement simple et, par exemple, l'implémentation de référence contient environ 7300 lignes de C.

Néanmoins, cela peut être trop, une fois compilé, pour des objets (le RFC cite les fours à micro-ondes...) et l'annexe C décrit donc des sous-ensembles raisonnables de Babel. Par exemple, une mise en œuvre passive pourrait apprendre des routes, sans rien annoncer. Plus utile, une mise en œuvre « parasite » n'annonce que la route vers elle-même et ne retransmet pas les routes apprises. Ne routant les paquets, elle ne risquerait pas de créer des boucles et pourrait donc omettre certaines données, comme la liste des sources. (Le RFC liste par contre ce que la mise en œuvre parasite doit faire.)

Toujours côté programmes, il existe un patch à tcpdump pour aficher les paquets Babel et un en cours pour Wireshark. On commence à voir des traces Babel sur pcapr.net.

Si vous voulez approfondir la question des protocoles de routage, une excellente comparaison a été faite par David Murray, Michael Dixon et Terry Koziniec dans « An Experimental Comparison of Routing Protocols in Multi Hop Ad Hoc Networks » où ils comparent Babel (qui l'emporte largement), OLSR (RFC 3626) et Batman (ce dernier est dans le noyau Linux officiel). Notez aussi que l'IETF a un protocole standard pour ce problème, RPL, décrit dans le RFC 6550.

Merci beaucoup à Juliusz Chroboczek pour sa relecture et ses nombreux avis.


Téléchargez le RFC 6126


L'article seul

RFC 6125: Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : P. Saint-Andre (Cisco), J. Hodges (PayPal)
Chemin des normes
Première rédaction de cet article le 1 Avril 2011


Un RFC long et complexe pour un problème difficile. En résumant violemment, il s'agit de savoir quelle identité utiliser lorsqu'un client TLS s'assure de l'authenticité du serveur auquel il se connecte. Par exemple, si un MTA veut transmettre du courrier à bill@example.com, que doit contenir le certificat X.509 du MX d'example.com pour que l'authentification réussisse ? example.com ? D'autres noms, plus spécifiques à ce service, sont-ils possibles ? Ce cas particulier est mentionné dans la section 4.1 du RFC 3207 mais très peu détaillé, et renvoyé à des décisions locales. Comme de nombreux autres protocoles ont des problèmes de ce genre, l'idée avait germé de faire un RFC générique, définissant un cadre et des principes, RFC que les protocoles n'auraient plus qu'à citer. C'est notre RFC 6125.

Traditionnellement, l'identité du pair avec lequel on se connecte était indiqué dans le champ Subject du certificat X.509. openssl permet de l'afficher :

% openssl s_client -starttls smtp -connect mail.bortzmeyer.org:25
...
Certificate chain
 0 s:/C=FR/ST=Ile-de-France/L=Paris/O=Moi/OU=Maison/CN=mail.bortzmeyer.org/emailAddress=postmaster@b
ortzmeyer.org
...

Le champ Sujet est formet de doublets attribut-valeur (par exemple, l'attribut C veut dire Country, ici la France) notamment CN (Common Name), le plus utilisé. Mais l'identité pouvait aussi figurer dans une extension X.509, Subject Alternative Name (section 4.2.1.6 du RFC 5280). Cette extension est rare en pratique, bien que normalisée depuis de nombreuses années. Je ne sais pas comment l'afficher avec openssl. La seule solution que je connaissais était de copier/coller le certificat affiché par openssl s_client -connect www.example.com:443 puis de faire un openssl x509 -text -noout -in /le/certificat.pem, ici avec le serveur HTTPS www.digicert.com :

Certificate:
...
        Subject: businessCategory=V1.0, Clause 5.(b)/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Utah/serialNumber=5299537-0142,
              	C=US, ST=Utah, L=Lindon, O=DigiCert, Inc., 
                CN=www.digicert.com
...
        X509v3 extensions:
...
            X509v3 Subject Alternative Name: 
                DNS:www.digicert.com, DNS:www.origin.digicert.com, 
                       DNS:content.digicert.com, DNS:digicert.com
...

On peut aussi combiner les deux commandes (openssl s_client -connect www.digicert.com:443 | openssl x509 -text) voire n'afficher que la partie qui nous intéresse (openssl s_client -connect www.digicert.com:443 | openssl x509 -text | perl -n0777e 'print $1 if /(.*Subject Alternative Name:.*\n.*\n)/', merci à minimalist pour son aide). Mais les navigateurs Web permettent en général de montrer tout le certificat, y compris cette extension. Regardez par exemple sur https://www.cisco.com/ ou bien https://www.digicert.com/. Un Subject Alternative Name peut contenir un dNSName (un nom de domaine), mais aussi un uniformResourceIdentifier (un URI) et, par des extensions de l'extension (RFC 4985), un SRVName (un nom de service, tel que présent en partie gauche d'un enregistrement SRV).

Quel nom utiliser lorsque plusieurs sont présents ? C'est tout le but de ce RFC : lorsqu'un client TLS se connecte à un serveur TLS, et qu'une authentification X.509 prend place, le client a une idée sur l'identité du serveur (reference identity, identité de référence, dit le RFC) et le serveur présente un certificat contenant un certain nombre d'identités (presented identity, identité affichée). Comment comparer ? Aujourd'hui, la situation est plutôt confuse et deux approches sont largement utilisées :

  • Utiliser uniquement le CN (Common Name) du champ Sujet (subject field), puisque tout le monde doit le connaître, c'est le champ traditionnel,
  • Répéter l'identité du serveur à plusieurs endroits dans le certificat en se disant que le vérificateur en trouvera au moins un.

Une partie de la difficulté est que le déploiement d'une méthode propre et standard nécessite la copération de plusieurs acteurs. Ce nouveau RFC 6125 est surtout destiné à l'usage interne de l'IETF, aux concepteurs de protocoles (section 1.2). Mais les autres acteurs impliqués, par exemple ceux qui écrivent les logiciels ou bien qui gèrent une CA ont tout intérêt à le lire également. Ils ne s'amuseront pas forcément (ce RFC est long, complexe et très abstrait, la section 1.3 donne quelques pistes pour le lire sans trop souffrir) mais ils apprendront des choses utiles. Avant de se mettre à la lecture, il fraut s'assurer d'avoir lu et bien compris le RFC 5280, dont les règles demeurent actives. Il faut également garder en mémoire les RFC spécifiques d'un protocole applicatif particulier comme le RFC 2595 pour IMAP, RFC 2818 pour HTTP, RFC 2830 pour LDAP, RFC 3207 pour SMTP, RFC 6120 pour XMPP, et plusieurs autres encore (liste en section 1.6)...

Pour le lecteur pressé, la section 1.5 résume les recommandations essentielles de ce RFC 6125 :

  • Abandonner progressivement l'utilisation de noms de domaine dans le champ CN (Common Name) du sujet du certificat. Aujourd'hui, c'est un vœu pieux, à en juger par les certificats HTTPS existants. Ceux-ci, soucieux de compatibilité, mettent presque tous le nom de la machine dans ce champ CN.
  • Privilégier l'utilisation des champs de l'extension Subject Alternative Name du RFC 5280.
  • Encore mieux, utiliser de préférence, dans cette extension, les champs typés comme celui qui permet d'indiquer l'URI du service ou celle qui permet d'indiquer le nom SRV (RFC 4985) car ils sont plus spécifiques et évitent de faire des certificats « atttrape-tout ». (Personnellement, je n'ai jamais vu dans la nature des certificats d'un serveur HTTPS ou IMAP utilisant ces champs.)
  • Pour le même souci de spécificité, abandonner petit à petit les certificats incluant un joker (*.example.com), un conseil qui plaira aux CA, car il augmentera leur chiffre d'affaires.

Plusieurs points sont exclus de ce RFC (section 1.7) :

  • Les identités des clients finaux (comme l'adresse de courrier électronique représentée par l'identificateur rfc822Name), qui peuvent servir en cas de présentation d'un certificat client. Notre RFC ne considère que l'authentification du serveur.
  • Les identificateurs qui ne sont pas des noms de domaines (par exemple les adresses IP, théoriquement possibles mais, en pratique, très peu utilisées).
  • Les protocoles non-TLS, même si certains d'entre eux, comme IPsec, peuvent eux aussi utiliser X.509.
  • Les certificats non-X.509 comme ceux d'OpenPGP (RFC 4880 et RFC 6091).

Une fois éliminé ces « non-sujets », le lecteur doit ensuite passer un peu de temps sur la section de terminologie en 1.8, car X.509 utilise beaucoup de vocabulaire. Il faut également connaître le vocabulaire standard de la sécurité, exposé dans le RFC 4949. Parmi les sigles dont on aura le plus besoin ici :

  • CN-ID: un RDN (Relative Distinguished Name dans le champ sujet du certificat, qui contient une paire clé-valeur de type CN (Common Name) et qui ait la forme d'un nom de domaine. Par exemple, dans le certificat actuel de www.gmail.com (après redirection vers mail.google.com), le champ sujet est CN = mail.google.com, O = Google Inc, L = Mountain View, ST = California, C = US et le CN-ID est mail.google.com. C'est de très loin le type le plus fréquent aujourd'hui.
  • DNS-ID: un identificateur de type dNSName mis dans l'entrée subjectAltName du RFC 5280. Par exemple, dans le certificat actuel de www.digicert.com, le DNS-ID est www.digicert.com (le même que le CN-ID, ce qui est le cas de la quasi-totalité des certificats qu'on trouve sur l'Internet public).
  • SRV-ID et URI-ID: des identificateurs trouvés également dans l'entrée subjectAltName du RFC 5280 (plus le RFC 4985 pour le SRV-ID), de types respectifs SRVName et uniformResourceIdentifier. On ne les trouve quasiment jamais dans les certificats disponibles sur l'Internet public.

Puisqu'on parle de ce qu'on trouve en pratique ou pas, je précise que mes avis là-dessus sont surtout tirés de quelques explorations faites sans méthode. Ce qui serait cool, ce serait d'avoir un Google des certificats X.509. Un robot récolterait les certificats, les analyserait et un moteur de recherches permettrait de trouver « Des certificats avec Subject Alternative Name » ou bien « Des certificats avec un condensat MD5 » ou aussi « Des certificats expirant après 2014 » ou encore « Des certificats Comodo émis par la Iranian Cyber Army :-) » Il existe deux projets allant dans cette direction : SSLiverse, qui a la récolte mais pas le moteur de recherche. L'archive fait 12 Go et est disponible en torrent. Il ne reste plus qu'à fouiller dedans (ce qui peut s'avérer assez long), la liste de diffusion du projet devient utile dans ce cas (merci à Étienne Maynier pour ses conseils et informations). L'autre projet est Shodan qui, lui, dispose non seulement d'une telle base, mais d'une partie des fonctions de recherche souhaitées (mais pas celle qui me fallait, pour trouver les certificats avec Subject Alternative Name).

Maintenant, passons aux noms. Un certificat contient les noms de services comme www.example.org. Certains noms sont directs : ils ont été tapés par un être humain ou sélectionnés à partir d'une page Web. D'autres, indirects, ont été obtenus, par exemple via une résolution DNS. Ainsi, pour envoyer du courrier à sandra@example.com, une résolution DNS de type MX permettra de trouver le relais de courrier de example.com, mettons smtp.example.net. (On peut noter que, en l'absence de résolution sécurisée, par exemple par DNSSEC, c'est le premier nom qu'il faut chercher dans le certificat, le second peut être le résultat d'un empoisonnement DNS.)

Les noms peuvent également être restreints ou pas. Un nom restreint ne peut être utilisé que pour un seul service. Par exemple, une CA peut émettre un certificat qui ne sera utilisable que pour de l'IMAP.

On voit donc qu'un CN-ID ou un DNS-ID sont directs et non restreints, qu'un SRV-ID peut être direct ou indirect (mais il est indirect la plupart du temps) mais est restreint (le nom de l'enregistrement SRV indique un certain type de service), qu'un URI-ID est direct et restreint.

Et le nom de domaine lui-même, a-t-il plusieurs catégories possibles ? Oui, dit la section 2.2 qui sépare les noms en :

  • Traditionnels. Ce sont les noms historiques comme www.mabanque.example.
  • Internationalisés. Ce sont les noms de domaine en Unicode définis par le RFC 5890.

Au tout début de X.509, les noms étaient censés être tirés d'un grand Annuaire officiel X.500 mais ce projet s'est cassé la figure, comme la plupart des autres éléphants blancs de l'UIT et il ne reste que des certificats isolés (section 2.3). Pour assurer l'unicité des noms, la méthode la plus courante sur l'Internet a donc rapidement été de mettre un nom de domaine dans le CN (Common Name) du sujet du certificat, par exemple C=CA,O=Example Internetworking,CN=mail.example.net. Mais ce n'est qu'une convention : le CN n'est pas typé, il peut contenir n'importe quoi, par exemple un nom lisible par un humain comme CN=A Free Chat Service,O=Example Org,C=GB et, dans ce cas, la vérification automatique de ce nom par rapport à ce qu'attendait l'utilisateur n'est pas évidente. Voici pourquoi notre RFC 6125 recommande l'utilisation des champs typés de subjectAltName au lieu du CN (recommandation très peu suivie dans l'Internet d'aujourd'hui).

Ces (longs) préliminaires étant achevés, la section 3 commence enfin la partie pratique du RFC, destinée aux auteurs de protocoles. Ceux-ci doivent d'abord faire une petite liste des caractéristiques pertinentes de leur protocole : utilise-t-il les enregistrements SRV ? Utilise-t-il des URI ? A-t-il besoin de jokers dans les noms de domaine ? Armé de cette connaissance, le concepteur de protocoles peut passer à la section 4 qui définit les règles de production d'identité (les règles pour les autorités de certification, donc).

Il est donc recommandé de mettre dans les certificats un subjectAltName DNS-ID. Si le protocole utilise les SRV, il est recommandé de mettre un SRV-ID (même conseil évident pour les URI). J'aimerais bien savoir combien de CA permettent de mettre un tel identificateur. Je parierais bien qu'il n'y en a aucune. Le RFC conseille également de ne pas inclure de nom de domaine dans le CN, pour encourager la migration (notons que le premier exemple donné, en section suivante, ne suit pas ce conseil...).

Voyons quelques exemples concrets :

  • Pour un serveur HTTP, protocole qui n'utilise pas les SRV et n'a pas prévu de mettre des URI dans les certificats (cf. RFC 2818), le certificat pour www.example.com doit inclure un DNS-ID www.example.com et peut inclure un CN-ID www.example.com pour la compatibilité avec les vieilles implémentations.
  • Pour un serveur IMAP, qui sert user@example.net et se nomme mail.example.net, comme le protocole peut utiliser les SRV (cf. RFC 6186), il faudra mettre le SRV-ID _imap.example.net, ainsi que les DNS-ID example.net et mail.example.net (là encore, on pourra ajouter un nom de domaine dans le CN, si on tient à gérer les vieux clients IMAP).
  • C'est presque pareil pour XMPP, avec en prime l'extension X.509 spécifique à ce protocole, XmppAddr (section 13.7.1.4 du RFC 6120).
  • Pour un service SIP qui gère user@voice.example.edu, comme SIP peut utiliser des URI (cf. RFC 5922), il faudra au moins un URI-ID sip:voice.example.edu et un DNS-ID voice.example.edu.

Ces spécifications de la section 4 étaient pour les autorités de certification. Et les gérants des services sécurisés, que doivent-ils mettre dans leurs demandes de certificats (CSR, Certificate Signing Requests) ? La section 5 précise qu'ils doivent demander tous les identificateurs nécessaires (ce qui ne veut pas dire que la CA leur donnera...), donc, par exemple, le SRV-ID et le DNS-ID dans le cas de IMAP. Si le certificat sera utilisé pour des services différents, il vaut mieux ne demander que le DNS-ID (les autres étant restreints, rappelez-vous la section 2.1).

Les gérants des services ont demandé les certificats (section 6), les CA ont émis des certificats (section 5), reste à les vérifier dans le logiciel client (section 6, qui concerne donc surtout les programmeurs). Le principe est le suivant :

  • L'application construit une liste des identités de référence. Typiquement, c'est ce que l'utilisateur a tapé au clavier ou bien sélectionné explicitement. S'il a configuré son compte de messagerie comme étant thierry.breton@iloveemail.example, le nom iloveemail.example sera une identité de référence (rappelez-vous que notre RFC ne se préoccupe que d'authentifier des serveurs, pas des personnes, donc le nom de l'individu n'est pas pris en compte). Si l'utilisateur a sélectionné https://www.dns-oarc.net/ sur une page Web, www.dns-oarc.net est une identité de référence.
  • Le serveur TLS envoie un certificat, qui contient des identités affichées.
  • Le client TLS compare les identités de référence aux identités affichées, râlant s'il n'y a pas correspondance.

Le reste de la section 6 formalise cette méthode. Quelques points particuliers, par exemple :

  • Le client doit faire attention à ne pas dériver des identités à partir d'autres identités, sauf si cela peut être fait de façon sûre. Ainsi, analyser un URI, pour en extraire le nom de domaine, si c'est fait proprement, est une opération sûre. Résoudre un nom en un autre (par exemple le serveur de messagerie à partir du MX du domaine) via le DNS est non sûr. Si on utilise DNSSEC, cela redevient sûr.
  • Mais, d'une manière générale, le RFC décourage la dérivation : seuls les noms entrés directement par l'utilisateur sont vraiment fiables comme identité de référence puisque, par définition, ils expriment la volonté directe de l'utilisateur (« je veux communiquer avec gmail.com »). La règle n'est toutefois pas absolue car, par exemple, l'utilisateur a pu « épingler » un autre nom précédemment (« je sais que le serveur XMPP de example.org est jabber.toto.example, authentifie ce dernier nom », cf. section 7.1).
  • La liste des identités de référence doit comprendre un DNS-ID. S'il y a eu une résolution SRV, elle devrait comprendre un SRV-ID (même raisonnement pour les URI-ID).
  • On peut y ajouter un CN-ID, pour réussir l'authentification avec les vieux certificats (le RFC note bien que, en l'état actuel des choses, cette possibilité est de facto une obligation, les certifiats avec CN-ID étant largement dominants).

Le RFC donne quelques exemples : une requête Web pour https://www.dns-oarc.net/ produira une liste d'identités de référence comportant un DNS-ID, www.dns-oarc.net et un CN-ID optionnel identique. Une tentative de connexion IMAP pour le domaine example.net, dont l'enregistrement SRV indiquera que le serveur est mail.example.net, donnera une liste comportant les SRV-ID _imap.example.net et _imaps.example.net ainsi que les DNS-ID example.net et mail.example.net (sans compter le CN-ID) optionnel. Le RFC ne rappelle apparemment pas que l'étape de résolution DNS de example.net en mail.example.net n'est pas forcément sûre... Le fait qu'ils soient sous le même domaine example.net n'est pas une protection parfaite (car on ne connait pas les frontières des zones DNS) et, de toute façon, le serveur n'est pas forcément dans le même domaine que celui qu'il sert. Et le RFC semble avoir oublié ici son conseil précédent de se méfier des noms dérivés...

Ensuite, il reste à comparer les deux listes (section 6.3). Le principe est celui de la première correspondance. Dès qu'une identité présentée correspond à une des identités de référence, on s'arrête, on a authentifié le serveur (section 6.6.1) et cette identité authentifiée est celle qui doit pêtre montrée à l'utilisateur. (Le cas où on voudrait que toutes les identités correspondent est laissé à une future norme.) Attention, le CN-ID dans les identités de référence est traité un peu à part : il ne doit pas être utilisé si le certificat inclus d'autres identités (comme un DNS-ID).

Cette correspondance nécessite quelques précisions (section 6.4). Ainsi, le RFC rappelle que les noms de domaine traditionnels doivent être comparés de manière insensible à la casse (RFC 4343), que les noms de domaine internationalisés doivent être transformés en A-labels (cf. RFC 5890) avant comparaison, que les jokers (indiqués par le signe *) nécessitent de l'attention particulière (par exemple, ils ne sont considérés comme spéciaux que s'ils apparaissent seuls, dans le composant le plus à gauche du nom).

Pour les CN, il est rappelé qu'un CN dans la liste des identités de référence n'est là que pour pouvoir authentifier avec les « vieux » certificats et ne doit pas être utilisé avec un certificat moderne, incluant des DNS-ID, SRV-ID ou URI-ID. S'il n'y a pas le choix (pas de Subject Alternative Name dans le certificat), l'application peut comparer ses identités de référence au CN, en suivant les règles de comparaison des noms de domaine.

Bon, si l'authentification du serveur a réussi, on continue et on affiche à l'utilisateur, sur un joli fond vert, l'identité authentifiée. Et si ça a raté, que doit-on faire ? La section 6.6.4 propose des stratégies de repli : si le logiciel est interactif, avec un humain pas loin, la méthode recommandée est de mettre fin à la connexion, avec un message d'erreur (conseil que je trouve déplorable : vu le nombre de certificats invalides, cela diminuerait nettement l'utilisabilité du Web et cela encouragerait les sites à ne pas proposer HTTPS). La possibilité de permettre à l'utilisateur de passer outre le problème et de contnuer (ce que font tous les navigateurs Web, autrement ils perdraient tous leurs clients) est mentionnée mais très découragée.

Si l'application n'est pas interactive, la démarche recommandée est d'afficher un message d'erreur et de s'arrêter. Une option pour ignorer le certificat est possible mais ne doit pas être activée par défaut. C'est ainsi que wget, fidèle à cette règle, a son option --no-check-certificate, alors que fetchmail, qui ne suit pas le RFC, a son --sslcertck pour activer la vérification.

D'ailleurs, une section entière, la 7, est consacrée à la discussion détaillée de certains problèmes de sécurité. Ainsi, les jokers font l'objet de la section 7.2. Ils sont déconseillés (pour les raisons expliquées en « New Tricks for Defeating SSL in Practice » et « HTTPS Can Byte Me ») mais, s'ils sont présents dans un certificat, le client devrait se préparer à les gérer, avec prudence.

Autre cas complexe, celui où un même serveur est accédé par plusieurs noms (virtual hosting) par exemple un serveur IMAP qui hébergerait plusieurs domaines de messagerie, ce qui est courant. Il existe plusieurs méthodes pour gérer ce cas, comme de mettre tous les noms possibles dans le certificat (pas pratique...), ou bien d'utiliser SNI (Server Name Indication, section 3 du RFC 6066). Si on met plusieurs noms dans le certificat, le RFC recommande que ce soit plusieurs DNS-ID (ou SRV-ID ou URI-UID) pas plusieurs CN.

Voilà, arrivé ici, le concepteur d'un protocole utilisant l'authentification avec X.509 sait normalement tout ce qu'il faut savoir. Il ne lui reste plus qu'à inclure dans sa spécification le texte exact et, pour lui faciliter la vie, l'annexe A contient un tel texte (pris dans le RFC 6120, section 13.7.1.2), qui peut être copié/collé avant d'être adapté à ce protocole particulier. De nombreux RFC avaient des règles spécifiques, avant la publication de notre RFC 6125 et la variété de ces règles était justement une motivation pour le développement du nouveau RFC. L'annexe B rappelle et cite les principaux RFC qui avaient traité le sujet comme le RFC 2818 pour HTTPS ou le RFC 2830 pour LDAP.

Ce RFC 6125 avait été chaudement discuté à l'IETF, ce qui explique qu'il ait mis si longtemps à être publié. Le lecteur courageux doit relire toutes les archives de la liste certid pour suivre toutes ces discussions (je recommande celles de septembre 2010 et décembre 2010).

Quelques petits trucs techniques pour ajouter des extensions comme subject alternative name avec les logiciels existants (merci à Dany Mello et Christian Pélissier ; on peut aussi consulter mon article « Plusieurs noms dans un certificat X.509 »). Avec OpenSSL, on peut aussi utiliser un fichier texte où on place l'extension. Pour une extension de type IP, le fichier ext.txt contient :

subjectAltName="IP:1.1.1.1"

puis on ajoute l'argument -extfile dans la ligne de commande d'openssl :

% openssl x509 -req -days 7300 -in moncsr.csr -CA ca.crt -CAkey ca.key \
    -set_serial 01 -out moncrt.crt -extfile ext.txt

Avec l'utilitaire certpatch (qui ne semble pas très documenté) disponible dans le paquetage isakmpd, c'est :

% certpatch -t fqdn -i www.example.org -k /etc/ssl/private/ca.key \
    oldcert.crt nwcert.crt

Avec l'utilitaire certutil (des outils de sécurité NSS), c'est :

% certutil -R -s "cn=dapou.exemple.fr,ou=DI,o=Exemple,...,c=FR" \
         -a -o $CADIR/$host.$domain.pem.csr -d $CADIR \
         -8 "cn=ldap1.exemple.fr" \
         -z random -f password-file

ldap1.exemple.fr sera le nom alternatif.


Téléchargez le RFC 6125


L'article seul

RFC 6122: Extensible Messaging and Presence Protocol (XMPP): Address Format

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : P. Saint-Andre (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF xmpp
Première rédaction de cet article le 31 Mars 2011


Ce RFC normalise le format des adresses du protocole de messagerie instantanée XMPP, également connu sous son ancien nom de Jabber. Il s'agit d'un document transitoire, qui remplace une partie de l'ancien RFC 3920, en attendant le résultat de travaux plus poussés sur l'internationalisation de ces adresses.

Le protocole XMPP est le standard actuel de messagerie instantanée de l'IETF. Les utilisateurs sont identifiés par une adresse également connue, pour des raisons historiques, sous le nom de JID (Jabber IDentifier). Ces adresses ont une forme qui ressemble aux adresses de courrier électronique mais elles sont en fait complètement différentes. Ainsi, j'ai personnellement deux adresses XMPP, bortzmeyer@gmail.com (le service de messagerie Google Talk utilise en effet la norme XMPP), qui me sert surtout pour la distraction, et bortzmeyer@dns-oarc.net qui me sert pour le travail. Mais rien ne dit qu'un courrier envoyé à ces adresses fonctionnera : adresses XMPP et de courrier vivent dans des mondes différents.

Le format des adresses XMPP était spécifié à l'origine dans le document XEP-0029. Puis il a été normalisé dans la section 3 du RFC 3920. La norme XMPP ayant subi une refonte complète, qui a mené entre autre à un nouveau RFC, le RFC 6120, se posait la question du format d'adresses, dont l'internationalisation, compte-tenu de la nouvelle norme IDN, suscitait des débats. Ces débats n'étant pas terminés, la décision a été prise de sortir le format d'adresses du RFC principal, et d'en faire ce RFC 6122, jusqu'à ce qu'un consensus apparaisse sur le format « définitif ».

Donc, quels sont les points essentiels des adresses XMPP (section 2) ? Une adresse (ou JID) identifie une entité (un humain mais peut-être aussi un programme automatique). Elle comprend trois parties (donc une seule est obligatoire), la partie locale, le domaine et une ressource. Ainsi, dans bortzmeyer@gmail.com/Home, bortzmeyer est la partie locale, gmail.com le domaine et Home la ressource. Le @ et le / servent de séparateurs. Chacune des trois parties peut-être composée de caractères Unicode (cf. section 3), qui doivent être encodés en UTF-8. La partie locale doit être canonicalisée avec Nodeprep, le domaine avec le Nameprep du RFC 3491. Seul le domaine est obligatoire et bot.example.org est donc un JID valide.

Les adresses XMPP (ou JID) sont souvent représentées sous forme d'un IRI, selon le RFC 5122. En gros, un IRI XMPP est un JID préfixé par xmpp:. Mais ces IRI ne sont pas utilisés par le protocole XMPP. Dans les champs to et from des strophes (stanzas) XMPP, on ne trouve que des JID (sans le xmpp: devant). Les IRI ne servent que dans les liens dans les pages Web, comme xmpp:bortzmeyer@gmail.com (attention, ce lien ne marchera pas avec tous les navigateurs).

Le RFC détaille ensuite chaque partie. Le domaine, seule partie obligatoire, est dans la section 2.2. On peut le voir comme une identification du service auquel on se connecte (gmail.com = Google Talk), et la création de comptes et l'authentification se font typiquement en fonction de ce service. En théorie, une adresse IP est acceptable pour cette partie mais, en pratique, c'est toujours un FQDN. Ce nom de domaine peut être un IDN donc instantanée.nœud.example est un nom acceptable pour former un JID. Auquel cas, ce doit être un IDN légal (ce qui veut dire que toute chaîne de caractères Unicode n'est pas forcément un nom légal pour la partie domaine d'un JID). À noter que XMPP n'utilise pas l'encodage en ASCII des IDN (le Punycode).

Et la partie locale, celle avant le @ ? La section 2.3 la couvre. Elle est optionnelle et identifie en général une personne (mais peut aussi indiquer un programme ou bien un salon de conversation à plusieurs). Si elle est en Unicode, elle doit être canonicalisable avec le profil Nodeprep (Nodeprep est normalisé en annexe A de notre RFC).

Quant à la ressource, troisième partie du JID (après le /), également optionnelle, elle sert à distinguer plusieurs sessions par le même utilisateur (par exemple /Home et /Office). La section 2.4 la décrit en détail. Également en Unicode, elle est canonicalisée par le profil Resourceprep. Elle n'a pas de structure officielle. Un / dans une ressource (par exemple example.com/foo/bar) n'implique donc pas une hiérarchie. De même, si on y trouve quelque chose ressemblant à une adresse (par exemple joe@example.net/nic@host), cette ressource nic@host doit être traitée comme un identificateur opaque (et pas être analysée en « nom (at) machine »).

Quelles sont les conséquences de sécurité de ces adresses ? Il n'y en a guère mais, bon, il y a toujours des inquiets donc la section 4 examine en détail tous les risques, même très théoriques. Bien sûr, les adresses XMPP héritent des questions de sécurité de Stringprep (section 9 du RFC 3454) mais le RFC mentionne surtout les risques de triche sur les adresses. Il y en a de deux sortes, les usurpations et les imitations. Les usurpations (section 4.3.1) sont les cas où un méchant arrive à envoyer un message XMPP en trichant sur l'origine, par exemple si jean@example.net, une fois authentifié auprès de son propre serveur, arrive à transmettre un message prétendant venir de jeanne@jabber.example. Normalement, le protocole XMPP empêche cela, par l'authentification mutuelle des serveurs (sauf attaques un peu sophistiquées, par exemple sur le DNS). Cela dit, cette authentification n'empêche pas un serveur d'annoncer une autre partie locale (jeanne@example.net au lieu jean@example.net).

L'autre risque est celui d'imitation (section 4.3.2). Cette fois, il s'agit d'utiliser des JID légitimes et authentiques mais qui ressemblent à celui de la victime, par exemple fric@paypa1.com au lieu de fric@paypal.com (si vous ne voyez pas la différence, regardez mieux). Cette technique est souvent connue sous le nom de typejacking. Dans un accès de beaufitude, le RFC mentionne aussi le cas d'écritures « moins familières » que l'alphabet latin (moins familières pour qui ?) mais, comme le montre l'exemple du RFC ou bien celui cité plus haut, le problème arrive même en se limitant à ASCII. Si vous voulez un joli exemple avec Unicode (mais le résultat dépend de l'environnement avec lequel vous lisez cet article), le RFC cite ᏚᎢᎵᎬᎢᎬᏒ qui ressemble à STPETER mais est écrit en Cherokee. Comme un JID peut contenir à peu près n'importe quel caractère Unicode, il n'y a pas vraiment de prévention technique possible contre ce problème. Toutefois, contrairement à ce que prétend le RFC (qui évoque le spectre du hameçonnage), il est peu probable que cela ait des conséquences en pratique. Le RFC, qui exagère le risque, suggère que les serveurs XMPP qui servent une communauté homogène, linguistiquement parlant, peuvent réduire le jeu de caractères Unicode acceptés comme partie locale d'un JID (par exemple, à l'alphabet cyrillique pour un serveur russe). Une telle politique serait, je trouve, un gros recul dans l'internationalisation de l'Internet et, de toute façon, elle n'aiderait pas les serveurs internationaux comme jabber.org ou Google Talk. Une approche moins restrictive est aussi proposée par le RFC : le logiciel client XMPP pourrait prévenir visuellement l'utilisateur lorsqu'un JID utilise une écriture distincte de celle utilisée habituellement par l'utilisateur (et qui est déduisible de ses préférences).

Le RFC se termine par les annexes normalisant les profils Nodeprep et Resourceprep. Rappelons que Stringprep (RFC 3454) décrit un cadre général pour la canonicalisation de chaînes de caractères Unicode, afin de faciliter les comparaisons ultérieures. Stringprep laisse un grand nombre de choix ouverts et doit donc, avant utilisation, être réduit à un profil. Les profils normalisés sont enregistrés à l'IANA. Par exemple, Nodeprep précise que la normalisation Unicode utilisée doit être la NFKC et donne la liste des caractères interdits dans une partie locale (par exemple @, <, >, /, etc). Resourceprep, lui, est dans l'annexe B et n'est pas équivalent (par exemple, les caractères cités plus haut ne sont pas interdits dans la ressource d'un JID).

La liste complète des changements par rapport au RFC 3920 figure en annexe C. Rappelons que le RFC 3920 s'appuyait, pour les parties en Unicode, sur des profils Stringprep (RFC 3454) comme Nameprep. Ce Nameprep, décrit dans le RFC 3491, ayant été supprimé à l'occasion de la réforme IDNA bis, la question se posait de l'avenir des profils Stringprep. Un groupe de travail IETF, PRECIS, a été monté pour discuter de l'avenir des normes utilisant Stringprep. Son travail n'étant pas terminé, et le groupe de travail sur XMPP ne souhaitant pas retarder la sortie de la nouvelle norme (RFC 6120), la question du successeur de Nameprep a été remise à plus tard et notre RFC 6122 normalise donc le format d'adresses XMPP tel qu'il était avant IDNA bis. Le RFC note que les implémenteurs sont encouragés à utiliser dès maintenant IDNA bis, même avant la sortie du futur RFC sur le format d'adresses (à part la question de la canonicalisation avec Nameprep, les différences entre l'IDN original et IDNA bis sont de peu d'importance pratique).

Les autres changements sont limités : clarification sur l'utilisation d'adresses IPv6 littérales dans les JID (j'offre une bière au premier qui annonce un JID quelqun@[2001:db8::bad:dcaf:1] qui marche), correction de bogues dans la grammaire pour le cas de termes de longueur nulle, changements de terminologie (la partie locale se nommait node identifier, d'où le terme de Nodeprep, survivance de l'ancien vocabulaire), etc.


Téléchargez le RFC 6122


L'article seul

RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : P. Saint-Andre (Cisco
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF xmpp
Première rédaction de cet article le 7 Avril 2011


Le protocole XMPP, normalisé dans le RFC 6120, est souvent cité comme protocole de messagerie instantanée. Mais c'est en fait plus compliqué que cela : XMPP lui-même ne fournit qu'un service minimum de routage d'éléments XML, les vrais services devant être développés au dessus de XMPP. C'est ainsi que les services de messagerie instantanée et de présence sont normalisé dans ce RFC, le 6121. Il succède au premier RFC sur ces services, le RFC 3921.

Le protocole de base, décrit dans le RFC 6120, transmet des éléments XML, les strophes (stanzas, j'ai choisi cette traduction parce qu'elle maintenait la métaphore musicale), en temps réel ou presque. Sur ce protocole de base, des tas de services sont possibles. La messagerie instantanée est le plus connu. Décrite dans le RFC 2779, elle a aujourd'hui éclipsé la plupart des autres usages de XMPP.

XMPP a été développé vers 1999 sous le nom de Jabber. Le nom de XMPP lui est venu lors de son adoption par l'IETF en 2002, les premiers RFC sont sortis en 2004 et ils viennent d'être mis à jour par la sortie des RFC 6120 (le protocole de base), RFC 6121 (la messagerie instantanée, qui remplace le RFC 3921) et RFC 6122 (le format des adresses). De son histoire, qui s'est déroulée partiellement en dehors de l'IETF, XMPP a gardé plusieurs extensions qui ne sont pas spécifiées dans un RFC, mais dans des documents connus sous le nom de XEP (XMPP Extension Protocols) comme par exemple XEP-0160 pour le stockage des strophes si elles ne peuvent pas être délivrées immédiatement.

Qu'est-ce que la messagerie instantanée ? Vu de XMPP, ce sont une liste de connaissances (le carnet ou roster) et la possibilité d'envoyer entre ces connaissances des messages relativement courts, de manière quasi-instantanée. Contrairement au courrier électronique, dont la caractéristique principale est d'être asynchrone (on peut envoyer un message à quelqu'un qui est en vacances et qui le lira au retour), la messagerie instantanée (ou IM pour Instant Messaging ou chat ou clavardage si on veut parler comme l'Académie française) est synchrone : un message perd beaucoup de son intérêt s'il n'est pas lu tout de suite. Cela implique donc de gérer la présence : les correspondants ont besoin de savoir si le type en face est là ou pas. Comme cette information peut être considérée comme confidentielle, la présence n'est communiquée qu'à ceux qu'on a accepté comme correspondants (buddies, ce qu'un utilisateur de Facebook traduirait sans doute par ami).

Donc, les quatre fonctions :

  • Gérer le carnet,
  • Échanger des messages avec ses correspondants,
  • Informer de sa présence,
  • Gérer la liste des gens qu'on informe de sa présence.

résument très bien le RFC 2779, qui fut le cahier des charges de XMPP.

La section 1.4 de notre RFC détaille les dites fonctions. Le transport des données, la connexion au serveur, l'authentification, etc, sont des choses très importantes mais elles sont absentes de ce RFC, puisqu'elles sont déjà couvertes dans le RFC 6120. Pour résumer ce dernier : un client XMPP se connecte à un serveur XMPP et s'authentifie. La session XMPP ainsi ouverte (et qui dure typiquement des heures, voire des jours) permet de transmettre des strophes (l'élément de base d'une conversation XMPP), ces strophes pouvant être des messages lisibles par un humain (« Ça va ? Tu viens bouffer ? ») comme des messages de service comme ceux informant de la présence d'un correspondant. (Il y a aussi des messages entre serveurs, pour qu'un utilisateur puisse parler à un client d'un autre service. Contrairement à Facebook ou MSN, XMPP est un protocole Internet, donc ouvert) Une session typique est :

  • Récupération de son carnet, stocké sur le serveur,
  • Envoi de l'information de présence (« Je suis là »),
  • Échange de messages, mises à jour du carnet, réception des informations de présence des potes, etc, tout au long de la session.
  • Fin de la session quand on va se coucher le soir.

Notons que les utilisateurs ne sont pas forcément des humains, ils peuvent être des bots.

Terminées, les généralités, place au protocole. Ce RFC est très long (cent seize pages), mais la longueur vient surtout du nombre de types de messages possible, pas tellement de la complexité du protocole. Je ne vais pas détailler chaque fonction, seulement mettre en évidence quelques points.

La plus importante fonction est évidemment l'échange de messages, donc commençons par elle (alors que le RFC fait passer la gestion du carnet et celle de la présence d'abord). Elle figure en section 5. Le principe est que le client XMPP transmet au serveur des éléments <message>. Ceux-ci sont délivrés à un autre client connecté au même serveur, ou bien routés vers un autre serveur. XMPP fonctionne donc par push, pas par pull : l'information doit être délivrée tout de suite (la section 8.5.2.1.1 précise ce que doit faire un serveur si un serveur distant n'est pas disponible de suite).

L'usage le plus courant est sous la forme d'une session de discussion où plusieurs messages vont se suivre. Dans ces cas, l'élément <message> reçoit un attribut type dont la valeur est chat (section 5.2.2). Voici un exemple de message (vous noterez vite que tous les examples XMPP sont tirés de Roméo et Juliette ; je n'ai pas traduit le texte, que j'ai laissé dans la langue originale, celle de Shakespeare, pas celle des amants de Vérone, qui s'échangeaient plutôt des mots doux en italien).


   <message
       from='juliet@example.com/balcony'
       id='ktx72v49'
       to='romeo@example.net'
       type='chat'
       xml:lang='en'>
     <body>Art thou not Romeo, and a Montague?</body>
   </message>

Tiens, justement, question langues, XMPP permet d'avoir plusieurs versions du même message, en des langues différentes (section 5.2.3). Voici un exemple en anglais et en tchèque :

   <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>

La section 3 explique le mécanisme de gestion de la présence. Celle-ci n'est transmise qu'aux abonnés, pas au public. Pour s'abonner, on envoie une demande (ici de Roméo vers Juliette) :


<presence id='xk3h1v69'
                 to='juliet@example.com'
                 type='subscribe'/>

Cette demande est en général présentée à l'utilisateur pour qu'il l'approuve (section 3.1.3). Le serveur peut alors répondre :


<presence from='juliet@example.com'
                 id='xk3h1v69'
                 to='romeo@example.net'
                 type='subscribed'/>

Une fois qu'on est approuvé, un peut recevoir des informations de présence (section 4). Celles-ci indiquent si l'entité (la personne ou le programme mais, en général, les programmes ne s'absentent pas) est disponible ou pas. Les clients XMPP l'affichent alors par exemple en vert si le contact est disponible et en rouge autrement, ou bien avec du texte comme online et offline. Donc, lorsque je lance mon client XMPP, ou bien lorsque je change manuellement l'état (le menu en bas de la fenêtre des contacts, avec Pidgin), le client XMPP envoie au serveur :

 

<presence/>

et celui-ci le retransmet aux abonnés (section 4.2.2). Le client peut aussi marquer explicitement qu'il ne veut pas être dérangé :

 

<presence type='unavailable'/>

information à laquelle on peut ajouter une explication :

 

<presence type='unavailable' xml:lang='fr'>
         <status>Je suis en vacances.</status>
       </presence>

La section 2 concerne la gestion du carnet (roster). Le serveur le stocke et le transmet à l'utilisateur, ce qui permet à celui-ci de disposer de son carnet depuis n'importe quelle machine (rappelons que XMPP est un protocole ouvert et que n'importe qui peut installer un serveur : celui-ci n'est donc pas forcément une grosse entreprise anonyme dans le nuage, il peut être géré par votre entreprise, votre association, par un copain ou par vous-même). Cela ne se fait évidemment qu'après authentification (la liste de mes copains ne regarde que moi...). À noter qu'un des changements depuis le RFC 3921 est que le carnet peut désormais être stocké sur un autre serveur que celui où on se connecte.

En gros, pour avoir le carnet, le client envoie la strophe :


<iq from='juliet@example.com/balcony'
          id='bv1bs71f'
          type='get'>
       <query xmlns='jabber:iq:roster'/>
</iq>

et le serveur lui transmet (ici, seulement trois correspondants, pour ne pas rendre cet article trop long) :


<iq id='bv1bs71f'
          to='juliet@example.com/balcony'
          type='result'>
        <query xmlns='jabber:iq:roster' ver='ver11'>
          <item jid='romeo@example.net'
                name='Romeo'
                subscription='both'>
            <group>Friends</group>
          </item>
          <item jid='mercutio@example.com'
                name='Mercutio'
                subscription='from'/>
          <item jid='benvolio@example.net'
                name='Benvolio'
                subscription='both'/>
        </query>
</iq>

Dans la liste d'élements <item> renvoyés, l'attribut jid contient l'adresse XMPP formelle (JID = Jabber ID, voir le RFC 6122) et name un identificateur plus convivial. L'élément <subscription> indique si le correspondant est abonné à notre présence, nous à la sienne, ou bien les deux. Le schéma XML complet figure en annexe D, en utilisant le langage XSD.

La section 2 couvre également le cas des mises à jour du carnet (le client ajoute ces mises à jour dans son <query>). Notez que XMPP peut aussi utiiser des enregistrements au format vCard (RFC 6350) pour remplir le carnet (annexe C et XEP-0054). Un serveur comme ejabberd gère cette possibilité.

La section 7 fournit un exemple plus détaillé d'une session complète, avec quatre utilisateurs. Lecture nécessaire si vous voulez comprendre tous les détails de XMPP.

Comme nous vivons dans un monde cruel (regardez ce qui est arrivé de tragique à Roméo et Juliette), XMPP a besoin d'une section sur la sécurité, la numéro 11. Elle traite des points comme l'importance de ne pas répondre aux demandes de présence si le demandeur n'est pas autorisé (soit explicitement, soit via une politique générale, par exemple l'autorisation de tous pour tous dans une même entreprise).

Qu'est-ce qui a changé depuis le RFC 3921 ? L'annexe E résume les principales différences. La plupart sont très pointues et ne se rencontrent pas tous les jours.

XMPP étant un protocole ancien et éprouvé, il est très largement déployé et on trouve de nombreuses implémentations :

  • Des serveurs comme ejabberd ou jabberd, si on veut créer son propre service,
  • Des clients comme Pidgin ou Empathy sur Unix (j'ai écrit un article spécifique pour les clients sur Android),
  • Des serveurs gratuits comme jabber.org ou comme Google Talk (oui, c'est tout simplement du XMPP et un abonné de Google Talk peut interagir avec n'importe quel autre abonné d'un autre service XMPP).

Et enfin, si vous voulez m'écrire, mes adresses XMPP sont bortzmeyer@dns-oarc.net pour le travail et bortzmeyer@gmail.com (du Google Talk) pour le reste.


Téléchargez le RFC 6121


L'article seul

RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core

Date de publication du RFC : Mars 2011
Auteur(s) du RFC : Peter Saint-Andre (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF xmpp
Première rédaction de cet article le 13 Avril 2011


Jabber est le nom original, et XMPP le nom IETF d'un protocole d'échange d'informations encodées en XML, protocole surtout connu pour son utilisation dans la messagerie instantanée. Ce RFC 6120 met à jour la définition originale de XMPP, qui était dans le RFC 3920.

La messagerie instantanée est une application très populaire surtout chez les moins de dix ans. Elle permet d'échanger des messages sans prendre le temps de réfléchir et en général sans craindre qu'ils soient archivés (contrairement au courrier électronique où il faut réfléchir car ce que l'on écrit restera). Elle sert à de nombreux usages, discussions entre geeks, systèmes de surveillance avec notification des problèmes, etc. À l'exception du vénérable protocole IRC (décrit - insuffisamment - dans le RFC 2810 et suivants), les systèmes existants de messagerie instantanée sont tous basés sur des protocoles privés et fermés comme MSN. La normalisation qui fait le succès du courrier électronique n'a pas réussi ici.

D'où le vieux projet (RFC 2779) de développer un protocole moderne et ouvert, adapté à cette application. C'est ce qu'on fait les développeurs du protocole Jabber en 1999, projet adopté ultérieurement par l'IETF, rebaptisé XMPP en 2002 et normalisé désormais dans ce RFC. Notre RFC décrit un protocole généraliste, un RFC compagnon, le RFC 6121, normalise les aspects spécifiques à la messagerie instantanée. Il est donc objectivement incorrect de dire que XMPP est un protocole de messagerie instantanée (c'est en fait un protocole d'échange de données XML en temps réel) mais je suis sûr que mes lecteurs me pardonneront mes abus de langage. Ce RFC 6120 est très long (notons pour la petite histoire que dix RFC sont quand même encore plus longs, le détenteur du record étant le RFC 5661), avec plus de deux cents pages, mais il est surtout composé de longues listes de détails, les principes sont relativement simples. En dépit de la longueur de ce RFC, il ne spécifie pas tout XMPP de nombreuses extensions existent, certaines très populaires (comme la possibilité pour un client de créer un compte sur un serveur directement via XMPP) et elles sont en général décrites, non pas dans un RFC, mais dans les XEP (XMPP Extension Protocols) de la XMPP Standards Foundation.

Quels sont les principes de XMPP (section 1.3) ? Les données sont encodées en XML (avec quelques bémols notés en section 11 comme l'interdiction des commentaires XML, ou des encodages autres qu'UTF-8), dans des strophes (stanzas) qui sont des petits paquets d'information. Citons Wikipédia : « Les stances sont, dans les sujets graves et spirituels, ce que le couplet est dans les chansons et la strophe dans les odes ». Ces strophes sont transmises sur une connexion TCP (section 3) entre client et serveur, ou bien entre serveur et serveur (la section 2.5 contient une très intéressante présentation des concepts « réseau » de XMPP, notamment pour répondre à la question philosophique « XMPP est-il pair-à-pair ? »). Les entités qui communiquent (ce ne sont pas forcément des humains, Jabber ayant été conçu pour permettre également la communication entre programmes) sont identifiées par une adresse, qui a une forme syntaxique proche de celle du courrier électronique. Par exemple, mon adresse XMPP est bortzmeyer@gmail.com.

XMPP, comme le courrier électronique, fonctionne par le connexion de serveurs, chacun chargé d'un ou plusieurs domaines. Les clients se connectent à un serveur (par exemple talk.l.google.com. pour Google Talk, par exemple) et s'y authentifient, puis ils transmettent les messages aux serveurs, qui se chargent de les acheminer au serveur suivant (section 2.1 du RFC). Les serveurs sont trouvés en utilisant les enregistrements SRV (RFC 2782) du DNS (section 3.2) par exemple, pour un client de l'OARC :

% dig SRV _xmpp-client._tcp.dns-oarc.net
...
;; ANSWER SECTION:
_xmpp-client._tcp.dns-oarc.net. 3223 IN SRV     0 0 5222 jabber.dns-oarc.net.
...

L'usage de SRV fait que le numéro de port utilisé n'est pas toujours le même mais 5222 (pour les communications de client à serveur) et 5269 (pour celles de serveur à serveur) sont les valeurs les plus courantes (section 14.7).

Les adresses (JID pour Jabber Identifier) sont décrites dans un autre document, le RFC 6122. Outre le classique nom@domaine, elles peuvent comporter une ressource, indiquée après la barre oblique (par exemple bortzmeyer@gmail.com/AFNIC).

La représentation des données en XML est décrite dans la section 4. Un flux de données, un stream, est un élément XML <stream>, qui comporte une ou plusieurs strophes, <stanza>. Il existe de nombreux types de strophes (section 8) sans compter les messages d'erreur, décrits en 4.9. Voici un exemple classique d'un échange (C étant le client et S le serveur), avec des strophes de type message :


   C:   <message from='juliet@example.com'
                 to='romeo@example.net'
                 xml:lang='en'>
   C:     <body>Art thou not Romeo, and a Montague?</body>
   C:   </message>
   S:   <message from='romeo@example.net'
                 to='juliet@example.com'
                 xml:lang='en'>
   S:     <body>Neither, fair saint, if either thee dislike.</body>
   S:   </message>

Des exemples plus détaillés figurent en section 9.

Contrairement à beaucoup d'autres protocoles de messagerie instantanée, conçus uniquement pour jouer, XMPP, étant prévu aussi pour le travail, dispose de fonctions de sécurité très riches. La section 5 précise l'utilisation de TLS et la 6 celle de SASL. La section 13 détaille en profondeur tous les problèmes de sécurité de XMPP.

La section 8 détaille les types de strophes disponibles. Trois types sont définis dans ce RFC, <message>, <presence> et <iq>. <message>, dont la sémantique est décrite en section 8.2.1, transporte un... message, tandis que <iq> (section 8.2.3) est une interrogation (Info / Query). Ces éléments XML ont un certain nombre d'attributs par exemple l'attribut to, sections 4.7.2 et 8.1.1, qui spécifie l'adresse du destinataire (romeo@example.net dans la pemière strophe de l'exemple ci-dessus). La syntaxe complète, exprimée en W3C Schema, figure dans l'annexe A.

Du fait de l'utilisation de XML, des attributs standard comme xml:lang sont possibles (section 8.1.5) et on peut ainsi marquer un message en tchèque :

   <presence from='romeo@example.net/orchard' xml:lang='en'>
     <show>dnd</show>
     <status>Wooing Juliet</status>
     <status xml:lang='cs'>Dvořím se Julii</status>
   </presence

L'annexe D résume les changements depuis le RFC 3920, qui avait été fait en 2004. Le format des adresses a été sorti pour être dans un document à part, le RFC 6122, le vieux protocole de rappel (dialback) a été retiré des RFC, TLS est devenu obligatoire (section 13.8, il reste à voir si ce sera mis en œuvre : au moment de la sortie de notre RFC, très peu de clients XMPP Android avaient TLS), et le reste est un certain nombre de clarifications et de corrections : il ne s'agit donc pas d'une nouvelle version du protocole, juste d'une évolution inspirée par l'expérience.

XMPP est aujourd'hui mis en œuvre dans de nombreux logiciels. C'est ainsi que le service de messagerie instantanée Google Talk utilise XMPP. Le client XMPP (qui est aussi un client de nombreux autres protocoles) le plus populaire sur Unix est sans doute Pidgin (ex-Gaim). Côté serveurs, le plus pittoresque (et pas le moins utilisé) est sans doute ejabberd, écrit en Erlang. Mais il y en a d'autres comme Movim.

Les développeurs liront avec intérêt le livre Programming Jabber qui explique comment utiliser Jabber/XMPP dans ses propres programmes.


Téléchargez le RFC 6120


L'article seul

RFC 6115: Recommendation for a Routing Architecture

Date de publication du RFC : Février 2011
Auteur(s) du RFC : T. Li (Cisco)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF RoutingResearchGroup
Première rédaction de cet article le 22 Février 2011


Le mécanisme de routage dans l'Internet est une invention géniale. Bien qu'ayant été décrié par tous les experts des télécoms, unanimes dans leur appréciation comme quoi cela ne pourrait jamais marcher, ce mécanisme a permis la croissance d'un réseau de quatre machines aux États-Unis à des débuts, vers des centaines de millions aujourd'hui, réparties partout dans le monde. Néanmoins, rien n'est éternel en technologie. Tous les systèmes sont un jour remplacés, ne serait-ce que parce que de nouveaux besoins émergent et que de nouveaux problèmes apparaissent. Le groupe RRG (Routing Research Group) de l'IRTF est donc chargé d'explorer, pour le moyen et long terme, les solutions qui pourraient remplacer le routage actuel, notamment pour améliorer son passage à l'échelle, le cas des réseaux multihomés et la possibilité de faire de l'ingénierie de trafic. Ambitieux défi puisqu'il faut, non seulement concevoir un système meilleur que le système qui a assuré un tel succès, mais aussi le déployer, dans un réseau qui se méfie des nouveautés.

On ne s'étonnera donc pas que le RRG a à moitié échoué. Aucune idée géniale, créant un consensus par sa beauté, n'a émergé. De nombreuses propositions, souvent astucieuses, ont été présentées et discutées mais aucune n'a fait l'objet d'un consensus. Les présidents du groupe ont fini par publier le RFC tel quel, avec les différentes contributions, les points sur lesquels un accord s'est fait, et leur recommandation personnelle, qui est de partir de la proposition ILNP.

D'abord, un peu de contexte. Les documents sur lesquels se base le travail du RRG (Routing Research Group) n'ont pas tous été publiés en RFC encore. Parmi eux, le RFC 6227, cahier des charges du projet. Les autres sont seulement des Internet-Drafts. Le principal est l'exposé du problème, draft-narten-radir-problem-statement. Ces deux documents ont donné naissance à de nombreuses propositions. Attention en les lisant : il n'y a pas de censure à l'IRTF et toutes les propositions sont étudiées et discutées. Beaucoup provenaient d'une personne isolée et, s'il existe parfois des génies solitaires et incompris, les propositions individuelles sont plus souvent l'œuvre de gens assez déconnectés de la pratique. On trouvera donc de tout dans ce RFC, hommage à l'ouverture de l'IRTF, plus qu'à sa capacité de sélection...

Il y avait en effet pas mal de zozos au RRG, des fois même incapables de formater un message électronique correctement (erreurs dans les citations, par exemple). Plusieurs propositions n'ont ainsi pas encore (?) connu le moindre début de mise en œuvre.

À noter également que les bruyants partisans des solutions de type « table rase » comme John Day ou comme le projet Clean Slate n'ont pas participé du tout à cet effort. À leur décharge, il faut dire que la solution devait être déployable incrémentalement, ce qui contredisait leur postulat de départ, qui est d'ignorer l'existant. Mais cette non-participation reflète aussi leur difficulté à travailler sur des questions concrètes. Tant qu'on se contente d'interviews au New York Times, refaire l'Internet en partant de zéro est facile. S'il faut écrire de vraies normes, compréhensibles, et se confronter au jugement de ses pairs, il y a moins d'enthousiasme.

Je ne vais pas détailler chacune des nombreuses propositions, plutôt me servir de chacune pour exposer un défi particulier auquel est confronté l'architecte du futur réseau. Par manque de temps, j'ignorerai même complètement certaines des propositions.

Pour résumer ces documents de base, à quoi servait le groupe RRG (Routing Research Group) ? Il avait été établit pour trouver une nouvelle architecture de routage pour l'Internet, rien que ça. Il s'est réuni à chaque réunion IETF de 2007 à 2010, a beaucoup discuté via sa liste de diffusion, mais, comme indiqué, n'a pas atteint de consensus. Les présidents du groupe, Lixia Zhang et Tony Li, deux experts expérimentés et reconnus, ont donc fini par jeter l'éponge et décider de tout publier, en ajoutant leur recommandation personnelle en faveur d'ILNP. Chaque proposition d'architecture ou de protocole a bénéficié d'un résumé (en général par son auteur, et la plupart de ces résumés sont de lourdes publicités avec peu de détails pratiques), résumé qui inclus obligatoirement les avantages de la proposition, mais aussi de ses coûts (il n'y a pas de déjeûner gratuit...), d'une critique par un autre membre du groupe et, parfois, d'une réponse de l'auteur à cette critique. (En pratique, je trouve que certaines critiques pinaillent sur quelques détails de la proposition, et n'analysent pas assez ses grandes idées et principes.)

Mais tout n'a pas été un flop : s'il n'y a pas eu d'accord sur une proposition concrète, le groupe a quand même mis en évidence plusieurs points importants, qui n'étaient pas évidents au début, mais qui ont rencontré un large accord. Ces points étaient (section 1.2) parfois de simple terminologie, parfois portant sur des concepts plus profonds. Par exemple :

  • [terminologie] Un nœud est soit un routeur, soit une machine terminale (host).
  • [terminologie] Un nom est une suite de bits utilisée pour désigner quelque chose (c'est vague mais c'est bien pour indiquer que le terme « nom » est très générique, et qu'il existe des termes mieux définis). Il existe des noms à des tas d'endroits de la pile des couches. Dans cette définition, le nom n'est donc pas forcément lisible et mémorisable par un humain.
  • Une adresse est un nom qui mêle identification et indication de l'emplacement dans le réseau (évidemment pas dans l'espace physique). Les actuelles adresses IP sont dans cette catégorie.
  • Un localisateur est un nom qui ne sert pas à l'identification mais uniquement pour exprimer une position dans le réseau (sans être une route complète vers l'objet). Actuellement, il n'existe pas de vrais localisateurs dans l'architecture Internet.
  • Un identificateur est un nom qui ne contient pas d'information topologique (c'est-à-dire qu'il est complètement indépendant de la position du nœud, si on débranche une machine au Burkina Faso et qu'on la rebranche au Canada, ou si on passe de la connexion filaire avec le réseau local, à une connexion 3G, l'identificateur ne doit pas changer). Aujourd'hui, certains FQDN peuvent être considérés comme des identificateurs, selon cette définition. Même chose pour les clés SSH ou HIP.
  • L'intérêt de séparer les définitions des identificateurs et des localisateurs est qu'un des points consensuels du groupe RRG a été que la séparation de l'identificateur et du localisateur était à la fois faisable et souhaitable.
  • Un autre consensus s'est fait sur l'importance du multihoming, et qu'il soit possible à un coût raisonnable (la solution actuelle, avec adresses PI et BGP, ne passe pas tellement à l'échelle).

À propos de terminologie, je recommande au lecteur du RFC qui n'aurait pas suivi tous les travaux du RRG de bien lire la section 1.3, qui liste les sigles les plus courants. Tout le reste du RFC en fait une forte consommation et certains ne sont pas forcément familiers à l'ingénieur réseaux (comme ITR, Ingress Tunnel Router, qui désigne le point d'entrée d'un tunnel, pour les solutions à base de tunnel ou EID, Endpoint IDentifier, qui désigne l'identificateur de la machine de destination).

Maintenant, assez de préliminaires, place aux propositions concrètes. La première exposée est LISP, qui n'a rien à voir avec le langage de programmation du même nom et qui occupe la section 2. À noter que les « LISPiens » ont peu participé au RRG, ayant un groupe de travail IETF à eux et leur proposition étant de loin la plus avancée, puisque implémentée et déployée. Par contre, aucun RFC LISP n'a encore été publié.

LISP fait partie des propositions dites CES pour Core-Edge Separation, où une coupure très nette est faite entre le cœur de l'Internet (en gros, le monde de ceux qui ont aujourd'hui un routeur dans la DFZ) et les bords. Si LISP est largement déployé, seul le cœur aura encore des adresses IP globalement uniques et les bords auront des identificateurs uniques, qui ne seront pas des localisateurs. Un mécanisme d'annuaire (mapping) permettra de trouver l'adresse d'un routeur capable d'acheminer les paquets pour un identificateur donné et ce routeur sera le point d'entrée d'un système de tunnels, qui permettra de router ce paquet. Le tunnel n'est pas forcément fourni par le FAI, et on pourrait imaginer un nouveau métier dans l'Internet, celui de fournisseur de tunnels. Comme avec toutes les autres propositions de séparation identificateur-localisateur, les localisateurs, plutôt dépendants du FAI, sont fortement agrégeables, les identificateurs sont stables (on ne les change pas en changeant de FAI, ce que les LISPiens appellent PI for all). LISP ne nécessite aucune modification des machines terminales (c'est une solution purement dans les routeurs et encore, pas dans tous, uniquement les routeurs d'entrée et de sortie de tunnel). Ce type de solution est aussi appelée Map-and-Encap car on cherche d'abord une correspondance entre identificateur et localisateur (Map) puis on encapsule le paquet (Encap) pour la traversée du tunnel.

Notez que cette CES, cette séparation entre cœur et bords changerait le modèle classique de l'Internet, fondé sur le même protocole IP partout, du réseau local de M. Michu à celui du plus gros Tier-1. Cela rappelerait les réseaux des PTT où X.25 ne servait qu'à l'accès, d'autres protocoles (comme X.75) étant utilisés à l'intérieur du réseau de l'opérateur.

Et, comme toutes les solutions fondées sur la séparation entre identificateur et localisateur, LISP nécessite un système de correspondance (mapping) entre les deux, permettant de trouver, lorsqu'on cherche à joindre la machine d'identificateur X, à quel routeur Y il faut envoyer le paquet. Pour des raisons en partie idéologiques, LISP n'a pas considéré le DNS pour cette tâche et a plusieurs systèmes de correspondance possibles, le plus avancé se nommant ALT (pour ALternative Topology). La tâche serait relativement simple si le réseau ne changeait pas mais la réalité étant qu'il y a des pannes, des reconfigurations, etc, une bonne partie de la complexité de LISP et de sa fonction de correspondance va être dans la détection et le traitement des pannes (pas question d'envoyer des paquets à un ITR en panne). Ce problème, là encore, est commun à toutes les propositions de séparation de localisateur et d'identificateur.

C'est donc logiquement sur ces fonctions (correspondance entre identificateur et localisateur, et détection puis contournement de pannes) que se focalisent les critiques. Alors que LISP ne change pas énormément le modèle d'IP, le déploiement d'un tout nouveau système de correspondance, non testé, et qui doit encaisser d'énormes quantités d'information changeant souvent, est vu comme le plus gros risque de LISP. Parmi les problèmes posés : que va t-il advenir du premier paquet, celui pour lequel le routeur ne connait pas encore de localisateur ? Le temps que le système de correspondance l'obtienne (et une requête dans ALT peut avoir un long chemin à parcourir), le paquet va devoir attendre. Les gros routeurs, ne souhaitant pas gérer de longues files d'attente, abandonneront probablement immédiatement de tels paquets, comme ils le font aujourd'hui lorsqu'il n'y a pas d'entrée ARP pour le destinataire. La source finira par réemettre et, cette fois, la table aura été remplie et le second paquet sera acheminé. Certains protocoles pourraient mal supporter cette « perte du premier paquet » (qui n'est pas non plus un problème spécifique à LISP). La réponse des LISPiens est que le problème n'est pas si grave que cela, les caches des routeurs se peupleront vite de l'essentiel des correspondances, ne serait-ce que grâce aux pirates scannant le réseau. Quant à ALT, il n'est qu'une des propositions, LISP offre le choix de plusieurs systèmes de correspondance identificateur -> localisateur comme TREE. Le modèle de LISP ne repose pas sur une fonction de correspondance unique.

Quant à la complexité de détection des pannes, nécessitant des échanges spécifiques entre les ITR et les ETR (les routeurs d'entrée et de sortie des tunnels), elle est vue comme inévitable, et, comme LISP fonctionne déjà sur le terrain, l'argument massue des LISPiens est que « ça marche ».

Le second système présenté, RANGI (Routing Architecture for the Next Generation Internet, présenté par X. Xu), en section 3, est, au contraire de LISP, une solution basée sur les machines terminales et non plus sur les routeurs. Comme HIP, RANGI introduit un identificateur propre à la machine et les connexions TCP sont liées à cet identificateur et plus aux adresses IP. Mais, alors que l'identificateur de HIP est « plat », sans structure, ce qui le rend difficilement résolvable en localisateur (et difficilement filtrable par les pare-feux), celui de RANGI est hiérarchique, pour pouvoir être résolu en localisateur par les méthodes arborescentes qui ont fait leur preuve, par exemple avec le DNS (alors que HIP doit utiliser des techniques moins éprouvées comme les DHT).

Comme HIP, RANGI ne connait que la distinction entre routeurs et machines terminales et n'a pas de distinction entre le cœur du réseau et ses bords. On parle donc de solution CEE (Core-Edge Elimination). Comme toute solution « côté machines terminales », RANGI nécessitera une mise à jour de tous les systèmes d'exploitation. La question de savoir s'il vaut mieux modifier toutes les machines terminales (plus nombreuses, pas forcément gérées, mais moins sensibles et plus souvent changées pour une neuve) ou tous les routeurs (moins nombreux, gérés par des professionnels mais souvent difficiles à remplacer ou à mettre à jour) a été souvent discutée dans le RRG mais sans résultat ferme.

Comme toute solution de séparation de l'identificateur et du localisateur, RANGI nécessitera le déploiement du nouveau système de correspondance entre identificateur et localisateur. Mais, contrairement à LISP, RANGI envisage de réutiliser le DNS.

À noter que le RRG insistait sur la déployabilité incrémentale des solution, nécessaire pour éviter d'arrêter tout l'Internet pendant les années de la transition. RANGI la permet mais les premiers adoptants ne gagnent rien à le faire, ce qui conduit à s'interroger sur la possibilité d'un déploiement effectif. Après tout, HIP, solution élégante et sûre, normalisée depuis longtemps, implémentée pour Linux et FreeBSD, n'a jamais décollé, en partie à cause de ce problème de la « récompense initiale ».

Proposition suivante, en section 4, IVIP (Internet Vastly Improved Plumbing, dû à R. Whittle). Système de séparation cœur-bords, comme LISP, proche de LISP par beaucoup d'aspects, il s'en distingue notamment par le fait que les correspondances entre identificateurs et localisateurs sont poussées, plutôt que tirées, et que donc tous les routeurs d'entrée de tunnel ont un accès rapide à tout moment à une copie complète de la base. Cette mise à jour en temps réel élimine la nécessité pour les ITR (routeurs d'entrée des tunnels) de tester que l'ETR correspondant attend toujours les paquets à la sortie. En contrepartie, elle exige beaucoup de mémoire chez l'ITR, de l'ordre de dizaines de Go (cela semble énorme mais, d'ici à l'adoption massive, le moindre ordinateur de bureau aura autant de RAM que cela).

Cette base des correspondances, disponible en temps réel, malgré le taux de changement qu'imposent, par exemple, les machines et les réseaux mobiles, est évidemment la principale faiblesse d'IVIP. Certes, elle permet d'éliminer complètement plusieurs problèmes sérieux, concernant la mobilité ou la détection des pannes d'un ETR, mais est-elle réaliste ? Il n'y a aucun précédent développé et déployé avec succès... Le DNS ne fonctionne qu'en renonçant à la propagation instantanée des informations. DRTM (Distributed Real Time Mapping, le système de correspondance d'IVIP) fera-t-il mieux ? En tout cas, il est intéressant de voir ce que permet cette approche.

Autre point à noter : les solutions de séparation du cœur et des bords, comme LISP et IVIP, sont parmi les seules à ne pas avoir besoin de noms uniques et donc à pouvoir fonctionner avec les petites adresses IPv4. La plupart des autres solutions dépendent d'IPv6.

Mais IVIP et LISP peuvent fonctionner avec IPv6. Au contraire, hIPv4 est spécifique à IPv4. Il a souvent été dit que la séparation entre identificateur et localisateur était déjà réalisée dans l'Internet, via le NAT, où l'adresse privée est un identificateur et l'adresse publique est un localisateur. C'est bien sûr largement une boutade (par exemple, l'adresse privée n'est pas unique, une machine qui se déplace peut changer d'adresse privée, etc), mais cela peut inspirer des idées qui ont des points communs avec le NAT comme hIPv4 (protocole créé par Patrick Frejborg). L'idée de base est que chaque machine a un identificateur sous forme d'une adresse IPv4 et un localisateur de même syntaxe. Les deux noms seront insérés dans chaque paquet (une petite couche entre la couche 3 et la couche 4), les routeurs de bord du domaine faisant l'échange des noms, pour que les autres routeurs n'aient pas à être modifiés. Du fait que la machine terminale doive insérer ces deux noms (l'identificateur et le localisateur), son système d'exploitation doit être modifié et hIPv4 est donc une des rares solutions qui nécessitent des changements à la fois dans les machines terminales et dans certains routeurs. Autre problème, l'épuisement des adresses IPv4 fait qu'on peut se demander d'où viendront ces adresses... Ce problème, celui de la déployabilité, et la question (qu'on retrouve dans le NAT) des protocoles qui s'échangent directement des adresses IP (comme SIP) fait que hIPv4 fait partie des propositions qui sont explicitement rejetées.

Continuons, puisque l'imagination des participants au RRG est sans limites. La section 6 présente NOL (Name OverLay). Actuellement, dans l'Internet, les noms de domaine, gérés dans le DNS, sont complètement extérieurs à la machine elle-même. C'est au point qu'une machine n'a pas de moyen simple de connaître son propre nom de domaine (si elle en a un !) sans parler de l'idée de l'influencer ou de le changer. L'idée de base de NOL est d'ajouter une couche de gestion des noms de domaine à toutes les machines, et d'utiliser ces noms comme identificateurs. (Voir les Name-Based Sockets, en section 15, une idée qui présente de nombreuses similarités.) Il est difficile de la décrire en détail car, apparemment, aucune spécification écrite n'a été produite. Il n'est pas nécessaire de modifier le système d'exploitation mais il faudra modifier les bibliothèques utilisées habituellement pour la résolution de noms (sur Unix, la libc). NOL n'implique pas de modifier l'application des deux côtés (contrairement à NBS, name-based sockets, présenté plus loin) car des relais spéciaux traduisent les noms et les adresses IP (une sorte de routeur NAT étendu). NOL n'a pas bénéficié de critiques ou de jugements précis, peut-être en raison de son caractère trop exotique.

C'est seulement avec la section 12 qu'apparait ILNP (Identifier-Locator Network Protocol, fait par R. Atkinson & S. Bhatti, site officiel en http://ilnp.cs.st-andrews.ac.uk/, bons transparents d'introduction en à NANOG, projet de spécification en draft-rja-ilnp-intro), l'architecture qui a finalement eu les faveurs des présidents du groupe. Il repose sur une stricte séparation de l'identificateur et du localisateur, avec le DNS pour passer de l'un à l'autre. Pour gérer les changements de connectivité, ILNP fait donc un usage intensif de DNSSEC et des mises à jour dynamiques du DNS (RFC 2136 et RFC 3007). L'auteur semble d'ailleurs prêter trop de pouvoirs à DNSSEC, par exemple en disant que les requêtes PTR peuvent également être authentifiées. C'est vrai qu'on peut signer un enregistrement PTR mais, lorsque le PTR de 2001:db8::dead:beef pointe vers www.amazon.com, il n'y a aucun moyen de s'assurer qu'il en a le « droit », DNSSEC ou pas.

ILNP atteint plusieurs des objectifs du RFC 5887 mais pas tous. Ainsi, certains serveurs (ceux du DNS, par exemple) doivent toujours être décrits par un localisateur. Dans son état actuel, ILNP impose l'usage du DNS pour tout (plus de ping 2001:db8:1:3::cafe), ce qui ne convient pas forcément à toutes les applications. Il faudra donc sans doute étendre ILNP sur ce point.

Dernière architecture de routage envisagée dans notre RFC, IRON/RANGER (section 16) où IRON signifie Internet Routing Overlay Network (auteur : F. Templin, décrit dans le RFC 6179) et s'appuie sur l'architecture RANGER (Routing and Addressing in Networks with Global Enterprise Recursion, RFC 5720). RANGER est dérivé de ISATAP (RFC 5214) et fournit un système de tunnels automatiques pour transporter des paquets identifiés par un... identificateur à travers un cœur qui n'utilise que des localisateurs. À son tour, RANGER s'appuie sur le mécanisme SEAL (Subnetwork Encapsulation and Adaptation Layer, RFC 5320, qui gère notamment les questions de MTU, toujours cruciales avec les tunnels. La critique de ce mécanisme note que beaucoup de détails manquent, notamment la fonction de recherche de la correspondance entre un identificateur et un localisateur. Elle remarque aussi que SEAL empêcherait de déployer les jumbogrammes. Dans sa réponse à la critique, l'auteur note que IRON ne repose pas sur un système de mapping classique mais sur une combinaison du protocole de routage et d'un protocole spécifique de distribution des correspondances. Personnellement, cela me semble encore très flou.

Une autre architecture est présentée en section 14, Évolution. Conçue par Lixia Zhang, une vétéran de l'IETF, auteure de plus de trente RFC, Évolution propose une approche du passage à l'échelle du système de routage qui est assez originale. L'idée de base est de faire feu de tout bois, en agrégeant les routes partout où on peut, sans attendre le « Grand Soir » d'une nouvelle architecture. Évolution critique la tendance des autres propositions du RRG à considérer qu'on ne peut rien résoudre tant qu'on n'a pas changé tout le routage. Mais, comme le peu de déploiement de IPv6 l'a montré, les solutions qui aideront tout le monde, une fois que tout le monde les aura déployé, ont le plus grand mal à s'imposer sur l'Internet. Les solutions qui gagnent sont au contraire en général celles qui procurent un bénéfice immédiat et à court terme aux décideurs.

Évolution propose donc de commencer par le routeur seul : tout routeur pourrait déjà agréger massivement les routes qu'il connait, économisant ainsi sa mémoire. Cet effet est d'autant plus marqué que le routeur a peu de liens physiques possibles. Ensuite, au sein cette fois d'un système autonome, on pourrait désigner certains routeurs comme étant les seuls à avoir une connaissance complète des liens externes, la plupart des routeurs de l'AS pouvant alors se contenter de tunnels vers ces « super-routeurs », créant une sorte de schéma Map-and-Encap local. Une fois cette « agrégation virtuelle » réalisée à l'intérieur de plusieurs AS, ceux-ci pourraient annoncer ces super-routeurs via BGP, étendant leur bénéfice aux autres AS. Enfin, une séparation plus intense entre le contrôle des routes (fait par BGP, et qui limite l'agrégation puisqu'il faut pouvoir annoncer les routes aux autres) et la transmission effective des paquets (où le routeur peut se contenter d'une FIB bien plus petite que sa RIB) complèterait le dispositif. Le point important d'Évolution est que chaque étape apporte ses bénéfices, et qu'il n'est donc pas indispensable de faire miroiter des bénéfices lointains aux décideurs pour les convaincre. Chaque étape a sa récompense propre.

Mais Évolution a ses propres problèmes. Certaines des techniques d'agrégation perturbent les systèmes existants (par exemple, l'agrégation de N préfixes en un super-préfixe, qui couvre un espace plus grand que ne le faisaient les N sous-préfixes, crée des adresses routables qui n'existaient pas avant, ce qui peut entraîner de nouvelles boucles de routage, et peut gêner les systèmes de sécurité comme RPF - RFC 3704). D'autre part, l'agrégation virtuelle allonge le chemin pris par les paquets, et peut aussi gêner RPF. À noter qu'Évolution ne fournit pas de solution pour la mobilité, concept à la mode, mais dont il n'est pas évident qu'il doive être géré par le système de routage (plutôt que, par exemple, une combinaison de DHCP et de meilleures applications).

Une autre critique faite à Évolution est plus philosophique : en fournissant des bénéfices à court terme, n'encourage-t-on pas les rustines sur un système déjà pas mal rapiécé, au risque de détourner les gens d'une transition, certes coûteuse mais nécessaire ?

On l'a vu, un problème commun à toutes les propositions de séparation du localisateur et de l'identificateur est le système de correspondance (mapping) entre les deux. Cela a mené certains à concentrer leurs efforts sur ce problème et à travailler sur des systèmes de correspondance génériques, pouvant être utilisés pour plusieurs protocoles. C'est le cas de LMS (Layered Mapping System), en section 8. Comme le ALT de LISP, il repose sur une hiérarchie des noms (système de résolution bien plus éprouvé que les systèmes plats, qu'utilisent par exemple les DHT). Mais, contrairement à ALT, la correspondance entre noms est complètement déconnectée du routage : ce ne sont pas les FAI ou les opérateurs réseau qui font la résolution de noms.

Autre système de correspondance, le 2-phased mapping de la section 9. Ce système vise à trouver l'ETR (le routeur de sortie du tunnel, celui qui est le plus « proche » du réseau visé) correspondant à un préfixe donné, le préfixe contenant l'identificateur de la machine visée. Tout serait simple si cette correspondance préfixe -> ETR était relativement statique. Mais, évidemment, ce n'est pas le cas et 2-phased mapping considère qu'un système qui stockerait toutes les relations préfixe -> ETR de la planète ne tiendrait pas longtemps. Son idée centrale est d'intercaler un numéro de système autonome (AS) entre les deux, de façon à avoir une relation préfixe -> AS -> ETR. Les systèmes autonomes connaissent en effet certainement leurs clients et donc les ETR qui les desservent. Il ne reste donc qu'à créer un système pour que les AS puisse informer le système de résolution des préfixes qu'ils servent. On peut donc envisager de d'abord résoudre le préfixe en un numéro d'AS puis d'interroger ce dernier. Ce système en deux étapes (les résultats de chacune pouvant être mis en cache) passe certainement mieux à l'échelle. À noter que les deux étapes ne sont pas forcées d'utiliser les mêmes techniques (par exemple, la première pourrait être faite avec le DNS, ou bien avec un serveur centralisé, type whois, et la seconde avec une extension à BGP). L'idée n'a toutefois pas été assez développée pour être considérée sérieusement par le RRG.

On l'a vu, toutes les propositions soumises au RRG ne concernaient pas forcément une architecture de routage nouvelle, certaines présentaient une solution auxiliaire, qui allait aider les nouvelles architectures. C'est le cas des Name-based sockets de la section 15. L'idée de base est de ne manipuler, depuis les applications, que des noms et de laisser les couches basses gérer et stocker les adresses. Dans la proposition actuelle, ces name-based sockets permettraient aux applications d'initier et de recevoir des communications uniquement avec les noms. Il ne s'agit pas seulement de cacher les adresses IP dans une bibliothèque utilisée par l'application (comme le font, par exemple, les bibliothèques curl et neon pour les programmeurs C) mais de déplacer leur gestion bien plus bas, dans la pile IP elle-même, permettant ainsi des choses comme le changement d'adresse IP en cours de communication.

En quoi est-ce que cela aiderait le routage ? Eh bien, cela réduirait la nécessité de disposer d'adresses PI et transformerait l'adresse IP est un nom largement invisible, comme l'est l'adresse MAC aujourd'hui. La souplesse que cela apporterait permettrait, par exemple, d'agréger plus radicalement les préfixes. Les NBS (name-based sockets) ont bien d'autres propriétés intéressantes comme de rendre le NAT largement inoffensif (si l'application ne voit jamais d'adresses IP, leur changement par le routeur NAT n'aura pas de conséquence).

Les NBS sont donc une solution situéee dans la machine terminale, sans changement des routeurs. Leur déploiement suppose donc leur adoption par les systèmes d'exploitaion (rappelez-vous qu'il ne s'agit pas d'une simple couche pour aider le programmeur, les NBS doivent interagir fortement avec IP et donc être dans le noyau). NBS est plus longuement documenté dans l'article de Vogt, « Simplifying Internet Applications Development With A Name-Based Sockets Interface ».

Quelles sont les limites des NBS ? D'abord, certaines applications auront toujours besoin d'adresses IP, par exemple celles nécessaires au bootstrapping comme les serveurs DNS. Ensuite, un réseau ne pourra abandonner ses adresses PI que lorsque toutes ses machines auront migré vers NBS.

Où cela nous mène t-il ? Comme indiqué au début, aucune proposition n'a recueilli le consensus du groupe. La section 17 expose donc la seule recommandation des présidents du groupe. Ceux-ci exposent d'abord le contexte, celui d'un Internet faiblement coordonné, sans point de décision central, et où les changements ne peuvent être introduits que de manière incrémentale. Tout changement étant compliqué, il faut choisir avec soin les changements qu'on propose. L'Internet a tenu, et très bien, jusqu'à présent, grâce à un grand nombre de modifications partielles, faites au fur et à mesure que les problèmes se posaient. Mais l'accumumation de ces changements a fini par mener à un réseau excessivement complexe et difficiles à maintenir. Les présidents du RRG proposent donc à la fois des changements à court terme, pour traiter les cas les plus urgents et une « bonne » solution à long terme, dont ils reconnaissent qu'elle n'existe pas encore. La recommandation est donc de travailler sur trois techniques :

  • À court terme, une agrégation plus vigoureuse des préfixes, comme proposé dans le plan Évolution (section 14 et Internet-Draft draft-zhang-evolution).
  • À long terme, une nouvelle architecture fondée sur ILNP (Identifier-Locator Network Protocol, section 12).
  • À court et moyen terme, travailler à rendre la renumérotation des réseaux plus facile, pour diminuer la pression en faveur des adresses PI. Décrit dans le RFC 5887, cette question est désormais du ressort du futur groupe de travail Renum.

Pourquoi ces choix ? L'agrégation de Évolution parce qu'on a besoin de solutions à court terme. ILNP parce que c'est une solution architecturalement propre, qui sépare nettement identificateur et localisateur, et qui ne dépend pas de tunnels. Et la rénumérotation facilitée parce que, quelle que soit la solution finale choisie, on ne pourra pas éviter des rénumérotations de temps en temps.


Téléchargez le RFC 6115


L'article seul

RFC 6108: Comcast's Web Notification System Design

Date de publication du RFC : Février 2011
Auteur(s) du RFC : C. Chung (Comcast), A. Kasyanov (Comcast), J. Livingood (tComcast), N. Mody (Comcast), B. Van Lieu
Pour information
Première rédaction de cet article le 24 Février 2011


Soit un FAI avec beaucoup de clients résidentiels. La plupart utilisent une machine sous Windows. Beaucoup de ces machines sont infectées par un des innombrables virus ou vers qui existent pour cette plate-forme. Devenues des zombies, ces machines participent désormais à diverses opérations illégales comme les dDoS ou l'envoi de spam. Si le FAI détecte, par le comportement de ces machines, ou par des rapports qui lui sont envoyés, qu'un de ses clients a été zombifié, comment le prévenir ? Vues les marges financières existantes dans cette industrie, pas question d'envoyer un technicien compétent chez le client pour lui expliquer. Il n'est même pas possible de l'appeler et de passer une heure à répondre à ses questions idiotes, cela mangerait tout le profit retiré de l'abonnement de ce client. Ce RFC décrit le système utilisé par Comcast pour prévenir ses abonnés.

Il existe bien sûr d'autres méthodes, comme de couper purement et simplement la connexion Internet dudit client. Cette méthode est régulièrement réclamée par certains éradicateurs. Outre qu'elle n'est pas dans l'intérêt financier du FAI (le client arrêterait de payer s'il était coupé), elle n'est pas envisageable dans un État de droit (en France, le Conseil Constitutionnel avait cassé une version de la loi Hadopi car elle prévoyait une coupure de l'accès Internet sans jugement). Même dans un pays de cow-boys, cette mesure est largement jugée comme trop radicale (voir la description de la section 12, plus loin). En outre, l'utilisateur risque de ne pas la comprendre, de croire à une panne et d'embêter le support utilisateur. Comcast a donc choisi une autre approche, celle de la notification à l'utilisateur, dont on espère qu'il réagira et prendra des mesures pour éliminer le malware de sa machine.

Concevoir un tel système de notification n'est pas évident. Il n'existe (heureusement) pas de moyen technique standard permettant à un tiers, le FAI, de faire soudain apparaître des messages sur l'écran de l'utilisateur (un tel mécanisme serait vite détourné par des plaisantins). Envoyer un courrier est simple et automatisable mais rien ne garantit que l'utilisateur les lit (la plupart ne le liraient pas ou bien, peut-être à raison, considéreraient-ils qu'il s'agit de hameçonnage).

L'approche de Comcast est donc de profiter du fait que la plupart des utilisateurs passent beaucoup de temps à regarder des pages Web. Il « suffit » de détourner les pages HTML, d'y insérer le message et bingo ! Le message apparaîtra à l'écran. Voici une copie d'écran de http://www.example.com/, avec l'exemple de modification que donne le RFC en section 8. Cette modification consiste simplement en l'ajout d'un peu de JavaScript: (On note que la possibilité d'accuser réception, mentionnée plus loin dans le RFC, est absente de cet exemple. Notez aussi le commentaire dans le code CSS qui insiste sur l'importance de ne pas hériter des styles qui seraient déjà présents dans la page.)

Bref, ce mécanisme est une attaque de l'homme du milieu, réalisée pour la bonne cause. Les auteurs insistent beaucoup sur le fait que leur solution repose sur des normes ouvertes et n'utilise pas de DPI mais cela me semble tout à fait secondaire. Le point important est que le FAI joue un rôle plus actif dans la chasse aux zombies et, pour cela, s'insère dans les communications de son client. Ce n'est pas forcément une mauvaise idée mais c'est une modification sérieuse du modèle traditionnel (où le client était seul maître à bord, même si, la plupart du temps, il ne se rendait pas du tout compte de la responsabilité qu'il avait.) Pour l'instant, il n'existe pas de travail organisé à l'IETF sur ce problème des machines zombies et chacun en est donc conduit à expérimenter seul (cf. section 13 du RFC).

Les détails pratiques suivent. La solution décrite très en profondeur est spécifique à DOCSIS mais pourrait être adaptée assez facilement à d'autres types d'accès. Les techniques utilisées sont le protocole ICAP (RFC 3507) et HTTP, les logiciels étant Squid et Tomcat.

Voyons d'abord le cahier des charges exact. Il figure en section 3. Je ne vais pas répéter tous ses points ici, seulement les plus importants. D'abord, les principes généraux :

  • N'est utilisé que pour les notifications de problèmes sérieux (comme le recrutement dans un botnet), pas pour des publicités.
  • Tourne sur le port 80, celui de HTTP, car à peu près tous les utilisateurs s'en servent. Ne doit pas gêner les autres protocoles qui utiliseraient ce port. D'une manière générale, ne doit pas perturber ou casser des applications.
  • N'utilise pas de ReSeTs TCP comme le faisait Comcast pour démolir les connexions BitTorrent de ses utilisateurs (sauf erreur, c'est la première fois que Comcast reconnait officiellement qu'il utilisait cette méthode (RFC 3360), après l'avoir nié pendant longtemps).
  • Permet à l'utilisateur de dire « Oui, je sais  » et de faire ainsi cesser les notifications.
  • Respecte les pages Web existantes, n'en supprime pas du contenu et n'en insère pas (à vous de voir si l'exemple Javascript montré plus haut respecte ce principe). Le RFC note justement que toute modification des pages Web existantes susciterait une levée de boucliers.

Ensuite, ceux liés au relais HTTP :

  • Logiciel libre, avec un client ICAP (Squid a été choisi, entre autres pour cette gestion d'ICAP).
  • Possibilité d'ACL car les notifications ne doivent être envoyés qu'à certains utilisateurs, et que certaines pages Web ne doivent pas être affectées du tout.

Il y a aussi quelques exigences techniques pour le serveur ICAP (un protocole, normalisé dans le RFC 3507, permettant à un serveur ou relais de demander au serveur ICAP des changements à apporter au contenu qu'ils servent) et pour l'arrière-plan du système (la partie qui va noter les comportements bizarres des machines, ainsi que les actions de réparation des utilisateurs).

Armée de ces bons principes, les sections 4, 5, 6 et 7 présentent le système effectivement déployé. Le relais Squid... relaie les requêtes HTTP et, lorsqu'il reçoit une réponse, demande au serveur ICAP si et comment la modifier. Le serveur ICAP utilise GreasySpoon. Si la notification est nécessaire, il répond avec un bout de code Javascript à insérer dans les pages. Un serveur Tomcat garde les messages à envoyer aux utilisateurs (il peut y avoir plusieurs types de messages). Un équipement de load-balancing est utilisé pour séparer le trafic HTTP du reste (même s'il tourne sur le port 80) et pour n'aiguiller vers le relais Squid que les clients listés comme suspects. Le dessin n° 1 montre tous ces composants et leur interaction. Le dessin n° 2, plus concret, illustre les connexions réseau entre ces composants. À noter qu'il ne semble pas y avoir de protection contre un malware qui supprimerait la notification (après tout, il contrôle la  machine de l'utilisateur).

Voici pour le fonctionnement technique. Maintenant, quelques considérations de sécurité, en section 10. D'abord, la rédaction du message de notification doit être très soignée, notamment pour éviter que l'utilisateur ne la considère comme du hameçonnage. Le message ne doit pas mener à une page où l'utilisateur est invité à taper son mot de passe. Il doit fournir un moyen d'obtenir plus de détails, par exemple un numéro de téléphone ou tout autre mécanisme de validation indépendante.

Un tel système de modification des pages Web vues, à des fins de notification, est-il Bon ou Méchant ? La section 11 discute cette question philosophique. Certains peuvent penser que le changement, par un intermédiaire technique, le FAI, est un franchissement de la ligne rouge. Selon ce point de vue, les intermédiaires ne devraient jamais tripoter le contenu des communications. Le RFC ne répond pas réellement à ces objections (à part en affirmant que Comcast a de « good motivations » et par l'argument traditionnel de chantage que, si on refuse ce mécanisme, on aura pire, par exemple à base de DPI) mais note que, au minimum, l'existence de ce système doit être annoncée aux clients (actuellement, la plupart des FAI gardent un silence complet, vis-à-vis de leurs propres clients, sur les éventuelles opérations de « gestion du réseau » qu'ils effectuent).

Et, compte-tenu des objections que peut soulever ce système, fallait-il publier ce RFC ? C'est un débat traditionnel à l'IETF : lorsqu'une idée ne fait pas l'objet d'un consensus, mais est largement déployée sur l'Internet, faut-il la documenter dans un RFC (évidemment sans que celui-ci ait le statut de norme, cf. RFC 1796 et RFC 2026), au risque que des gens croient que l'idée bénéficie d'un soutien de l'IETF, ou bien l'ignorer, au risque que les RFC ne reflètent plus la réalité de l'Internet ? La section 11 répond également à ce débat de fond en considérant qu'il vaut mieux publier, ne serait-ce que pour aider aux futurs débats.

Le problème de ces notifications est d'autant plus complexe que le FAI n'est pas tout seul face aux décisions à prendre : de nombreux organismes, au gouvernement ou ailleurs, font lourdement pression sur les FAI pour que ceux-ci fassent quelque chose contre les machines zombies. Est cité Howard Schmidt, conseiller d'Obama pour la cybersécurité, qui dit « As attacks on home-based and unsecured networks become as prevalent as those against large organizations, the need for ISPs to do everything they can to make security easier for their subscribers is critical for the preservation of our nation's information backbone. » Le RFC dit clairement qu'un des buts de cette technique de notification est de satisfaire de telles demandes.

Mais, pour atteindre ce but, y a-t-il d'autres méthodes ? La section 12 présente une alternative possible, le jardin fermé. Dans un tel système, les clients détectés comme zombifiés sont limités à l'accès à un petit nombre de sites Web, par exemple ceux de sites liés la sécurité, ou à la mise à jour de leur système d'exploitation. De facto, cela notifie l'utilisateur qu'il y a un problème. On peut aussi rediriger toutes les autres connexions HTTP vers un serveur présentant un message d'alerte. Mais c'est beaucoup plus violent, en coupant l'accès à des services que l'utilisateur peut considérer comme essentiels, comme une conversation téléphonique qui serait alors brutalement interrompue. La responsabilité du FAI serait alors clairement engagée. Le RFC rappelle à juste titre qu'il n'y a pas que le Web ! Et rejette donc l'idée du jardin fermé.

Ah, et mon opinion personnelle ? Je pense que cette méthode est un compromis acceptable. Sur le principe, c'est une attaque de l'intermédiaire et une violation de la neutralité du réseau mais l'ampleur du problème des machines Windows infectées, qui attaquent ensuite les autres, est tel qu'il peut être justifié de prendre des mesures un peu dures. Après, tout dépendra des détails concrets de réalisation (taux de fausses alertes, par exemple).

Un article avait été fait à l'occasion des premiers tests, « Comcast to send infected-PC alerts ».


Téléchargez le RFC 6108


L'article seul

RFC 6106: IPv6 Router Advertisement Options for DNS Configuration

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : J. Jeong (Brocade/ETRI), S. Park (Samsung), L. Belœil (France Telecom R&D), S. Madanapalli (Ordyn)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 30 Novembre 2010
Dernière mise à jour le 22 Décembre 2010


Il existe deux méthodes pour configurer une machine IPv6 automatiquement, DHCP (RFC 3315) et RA (Router Advertisement, RFC 4862). Pendant longtemps, l'avantage de la première était de pouvoir indiquer d'autres informations que l'adresse IP, comme par exemple les adresses des serveurs DNS. Le RFC 5006 avait apporté cette possibilité à la configuration par RA. Mais son statut n'était qu'expérimental. Désormais, voici la même option mais sous la forme d'une vraie norme.

Si on gère un gros réseau, avec de nombreuses machines dont certaines, portables, vont et viennent, s'assurer que toutes ces machines ont les adresses IP des serveurs de noms à utiliser n'est pas trivial (section 1 du RFC). On ne peut évidemment pas utiliser le DNS, cela serait tenter de voler en tirant sur les lacets de ses chaussures. Et configurer à la main les adresses sur chaque machine (par exemple, sur Unix, en les écrivant dans le fichier /etc/hosts) est bien trop difficile à maintenir. Se passer du DNS est hors de question. Pour les machines bi-protocoles (IPv4 et IPv6), une solution possible était d'utiliser un serveur de noms en v4. Mais pour une solution purement v6 ?

La solution la plus populaire actuellement est DHCP (RFC 3315 et RFC 3646). Son principal inconvénient est qu'elle est à état : le serveur DHCP doit se souvenir des baux qu'il a attribué. Sur un gros réseau local, le nombre de requêtes à traiter, chacune nécessitant une écriture dans une base de données, peut devenir très lourd.

Une autre solution est sans état et repose sur une nouveauté d'IPv6, les RA (Router Advertisements, cette méthode est aussi appelée ND, pour Neighbor Discovery, les RA en étant un cas particulier), décrits dans le RFC 4862. Ce sont des messages envoyés à intervalles réguliers par les routeurs et qui informent les machines non-routeuses des caractéristiques essentielles du réseau, comme le préfixe utilisé (par exemple 2001:DB8:BEEF:42::/64). Le routeur diffuse ses messages et n'a pas besoin d'écrire quoi que ce soit sur son disque, ni de faire des traitements compliqués lors d'une sollicitation, il répond toujours par le même message RA.

Ces RA peuvent diffuser diverses informations, par le biais d'un système d'options. Le principe de notre RFC est donc d'utiliser ces RA pour transporter l'information sur les serveurs de noms récursifs utilisables sur le réseau local, via des nouvelles options notamment celle nommée RDNSS (le numéro 25 lui a été affecté par l'IANA).

La section 1.1 du RFC rappelle qu'il existe plusieurs choix, notre RFC 6106 n'étant qu'une possibilité parmi d'autres. Le RFC 4339 contient une discussion plus détaillée de ce problème du choix d'une méthode de configuration des serveurs de noms (notons qu'il existe d'autres méthodes comme l'anycast avec une adresse « bien connue »). La section 1.2 décrit ce qui se passe lorsque plusieurs méthodes (par exemple DHCP et RA) sont utilisées en même temps.

La méthode RA décrite dans notre RFC repose sur deux nouvelles options, RDNSS, déjà citée, et DNSSL, qui n'existait pas dans le RFC précédent (section 4). La première permet de publier les adresses des serveurs de noms, la seconde une liste de domaine à utiliser pour compléter les noms courts (formés d'un seul composant).

La première option, RDNSS, de numéro 25, est décrite en section 5.1. Elle indique une liste d'adresse IPv6 que le client RA mettra dans sa liste locale de serveurs de noms interrogeables.

La seconde option, DNSSL, de numéro 31, est en section 5.2 (les deux options sont enregistrées dans le registre IANA, cf. section 8). Elle publie une liste de domaines, typiquement ceux qui, sur une machine Unix, se retrouveront dans l'option search de /etc/resolv.conf.

Sur Linux, le démon rdnssd permet de recevoir ces RA et de modifier la configuration DNS. Pour FreeBSD, on peut consulter une discussion sur leur liste. Les CPE de Free, les Freebox, émettent de telles options dans leurs RA (apparemment, à la date de publication de notre RFC 6106, uniquement des RDNSS). Voici ce qu'affiche Wireshark :

...
Ethernet II, Src: FreeboxS_c3:83:23 (00:07:cb:c3:83:23), 
             Dst: IPv6mcast_00:00:00:01 (33:33:00:00:00:01)
...
Internet Control Message Protocol v6
    Type: 134 (Router advertisement)
...
    ICMPv6 Option (Recursive DNS Server)
        Type: Recursive DNS Server (25)
        Length: 40
        Reserved
        Lifetime: 600
        Recursive DNS Servers: 2a01:e00::2 (2a01:e00::2)
        Recursive DNS Servers: 2a01:e00::1 (2a01:e00::1)

et les serveurs DNS annoncés répondent correctement. (Vous pouvez récupérer le paquet entier sur pcapr.net.)

Autre mises en œuvre de ces options, dans radvd, qui a déjà l'option RDNSS et bientôt (en décembre 2010) la nouvelle DNSSL (ainsi que pour les logiciels auxiliaires). Quant à Wireshark, le code a déjà été écrit mais n'est pas encore intégré.

La section 6 de notre RFC donne des conseils aux programmeurs qui voudraient mettre en œuvre ce document. Par exemple, sur un système d'exploitation où le client RA tourne dans le noyau (pour configurer les adresses IP) et où la configuration DNS est dans l'espace utilisateur, il faut prévoir un mécanisme de communication, par exemple un démon qui interroge le noyau régulièrement pour savoir s'il doit mettre à jour la configuration DNS.

RA pose divers problèmes de sécurité, tout comme DHCP, d'ailleurs. Le problème de ces techniques est qu'elles sont conçues pour faciliter la vue de l'utilisateur et de l'administrateur réseau et que « faciliter la vie » implique en général de ne pas avoir de fonctions de sécurité difficiles à configurer. La section 7 traite de ce problème, par exemple du risque de se retrouver avec l'adresse d'un serveur DNS méchant qui vous redirigerait n'importe Dieu sait où (les RA ne sont pas authentifiés). Ce risque n'a rien de spécifique aux options DNS, toute la technique RA est vulnérable (par exemple, avec un faux Neighbor Advertisement). Donc, notre RFC n'apporte pas de risque nouveau. Si on considère cette faiblesse de sécurité comme insupportable, la section 7.2 recommande d'utiliser SEND (RFC 3971).

À noter que l'annexe A résume les changements depuis le RFC 5006. Passage sur le chemin des normes, ajout de la nouvelle option DNSSL (DNS Search List) plus diverses précisions sur le protocole.

Merci à Alexis La Goutte pour ses informations.


Téléchargez le RFC 6106


L'article seul

RFC 6105: IPv6 Router Advertisement Guard

Date de publication du RFC : Février 2011
Auteur(s) du RFC : E. Levy-Abegnoli, G. Van de Velde, C. Popoviciu (Cisco Systems), J. Mohacsi (NIIF/Hungarnet)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 24 Février 2011


Comme le décrit très bien le RFC 6104, la situation de la sécurité des RA (Router Advertisement, cf. RFC 4861) n'est pas satisfaisante. Les « faux RA », envoyés par un méchant ou par un maladroit, sont trop fréquents. Notre RFC 6105 propose donc une solution. Elle est bien plus légère que SEND et repose sur un filtrage au niveau deux.

Je vous renvoie à mon article sur le RFC 6104 pour d'avantage de détails sur le problème. Ici, je ne vais parler que de la solution. Elle fonctionne pour un réseau partagé où les participants doivent passer par un commutateur (on ne peut donc pas l'utiliser pour du WiFi ad hoc, cf. section 5) et elle nécessite que ledit commutateur mette en œuvre le système décrit dans ce RFC (cf. section 2 et sa figure 1).

Officiellement, SEND (RFC 3971), reste la solution de choix. Après l'obligatoire rappel que SEND résoudrait tous les problèmes, notre RFC rappelle qu'il n'est pas réaliste d'espérer un déploiement massif de SEND dans les années à venir. Pire, le RFC reconnait que certains équipements (on pense au célèbre grille-pain IPv6) n'auront jamais SEND. La solution proposé, RA Guard, est donc un système de filtrage des RA par le commutateur, suivant plusieurs méthodes possibles. Le commutateur sert donc de centre de contrôle, autorisant ou bloquant les RA selon plusieurs possibilités.

Quelles sont ces possibilités ? Les sections suivantes les décrivent. D'abord, le RA guard sans état (section 3). Dans ce mode, le commutateur examine les RA entrants et les bloque ou pas en ne tenant compte que du contenu du RA et de sa propre configuration. Il n'a donc pas de mémoire, pas d'état. Sur quelle base décider ? L'adresse MAC source du RA, le port sur lequel le RA a été reçu, l'adresse IP source, le ou les préfixes annoncés dans le RA… Le commutateur a pu être configuré pour autoriser ou interdire sur la base de ces informations. Une fois le RA considéré comme légitime, il est transmis sur toutes les interfaces, comme n'importe quel paquet. Le RFC présente par exemple une solution ultra-simple où l'administrateur du commutateur indique juste un port comme étant celui du routeur officiel, et les RA arrivant sur les autres ports seront donc simplement ignorés. Cette méthode a l'inconvénient de nécessiter une configuration manuelle.

Plus sophistiquée, le RA guard avec état (section 4). Le principe est d'apprendre automatiquement à quoi ressemblent les RA légitimes, avant de se mettre à bloquer les autres. Dans sa version la plus simple, le commutateur écoute pendant un moment (défini par l'administrateur), notant qui envoie les RA, puis considère que, après ce laps de temps, tout autre RA est illégitime. Cela protège donc contre les RA anormaux survenant après cette période d'apprentissage. Si un nouveau routeur légitime arrive, on recommence l'apprentissage de zéro.

La section 4.1 décrit les détails. Au début, le commutateur est dans l'état LEARNING où il écoute les RA. Fait-il suivre tous les RA pendant cette phase, ou bien les bloque-t-il tous ? C'est configurable selon le degré de paranoïa de l'administrateur. Une fois cette phase terminée, les interfaces passent dans l'état BLOCKING ou FORWARDING selon qu'elles recevaient des RA acceptables ou non. (Le RFC ne mentionne donc que la possibilité d'apprendre les interfaces où se trouve un routeur légitime, pas celles d'apprendre son adresse MAC.) La section 7 suggère fortement que l'administrateur jette un coup d'œil à la liste des interfaces à RA légitimes, pour vérifier… Par contre, elle ne rappelle pas que le mécanisme est mis en danger si un routeur illégitime est présent dès la phase d'apprentissage. Normalement, ce cas est traité par le fait que cette technique est combinée avec des filtres manuels comme ceux de la section précédente.

Encore plus ambitieux, la possibilité pour le commutateur d'être un mandataire SEND (section 4.2). L'un des problèmes de SEND est que chaque machine du réseau, grille-pain et frigidaire inclus, doit faire de la cryptographie (parfois compliquée, par exemple s'il faut récupérer des certificats intermédiaires) et être configurée avec un certificat. Avec le mandataire SEND, seul le commutateur va valider les annonces signées par SEND. Il les fera suivre ou les bloquera en fonction du résultat de la validation.

Je ne connais pas de liste d'implémentations officielles de ce service. Apparemment, certains le déploieraient déjà, si on en croit des témoignages. Fin 2011, Juniper annonçait RA Guard pour les versions 12.x, Cisco a déjà cette fonction dans des engins comme le Cisco 3750g avec « advanced enterprise featureset » (voir un bon article sur le sujet). Brocade n'a rien communiqué. Une technique permettant de contourner le RA guard a déjà été décrite.


Téléchargez le RFC 6105


L'article seul

RFC 6104: Rogue IPv6 Router Advertisement Problem Statement

Date de publication du RFC : Février 2011
Auteur(s) du RFC : T. Chown (University of Southampton), S. Venaas (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 24 Février 2011


Il y a une tension permanente en sécurité des réseaux, entre la sécurité et la facilité d'usage (quelqu'un a une meilleure traduction pour convenience ? « ergonomie » ?). Ainsi, le protocole IPv6 permet l'autoconfiguration sans état des machines, par le biais d'annonces, les RA (Router Advertisement) diffusées par les routeurs. C'est très pratique et IPv4 n'a rien de tel. Mais qui dit que la machine qui diffuse est un vrai routeur légitime ? Rien. Les « RAcailles » (mauvaise traduction de rogue RA), ces annonces envoyées à tort, sont très fréquents dans la réalité. Avant que des solutions soient proposées et discutées, ce court RFC spécifie précisément le problème.

Le mécanisme des RA (Router Advertisement) est décrit dans le RFC 4861. Le principe est que le ou les routeurs officiels du réseau local diffusent des informations telles que le préfixe à utiliser sur ce lien (ce qui permet l'autoconfiguration du RFC 4862) ou l'adresse IP du routeur à utiliser par défaut. Les « RAcailles » sont des annonces RA envoyées par un engin qui n'est pas routeur officiel. Cela peut être dû à une attaque délibérée, ou tout simplement à une erreur de configuration, par exemple une machine configurée pour monter un hotspot WiFi avec réseau ad hoc et qui diffuse donc des RA, se croyant le routeur officiel. Ce phénomène est fréquent sur les réseaux sans-fil partagés (on le voit à chaque réunion IETF, dont les participants sont pourtant censés être des experts, et il faut des annonces répétées au micro pour que les machines émettant des RAcailles se taisent ; un exemple à la réunion d'Hiroshima est décrit dans ce message). Mais on le voit aussi dans des réseaux filaires, par exemple les résidences d'étudiants.

Sur un réseau sans-fil partagé, il n'y a guère de moyen de repérer le coupable, dont on ne connait que l'adresse MAC. Encore aujourd'hui, la solution la plus courante (décrite en section 3.7) est de filtrer les RA, sur la base de l'adresse attendue (liste blanche), ou sur celle des adresses repérées comme erronées (liste noire). Mais cela diminue évidemment sérieusement l'intérêt de l'autoconfiguration (toujours cette tension entre sécurité et facilité d'usage). Sur Linux, cela serait quelque chose comme :

% ip6tables -A INPUT -m mac --mac-source 00:1b:77:bc:a4:e6 -j DROP

(Exercice pour le lecteur : cette commande bloque absolument tout le trafic en provenance de 00:1b:77:bc:a4:e6. Comment ne bloquer que les RA ? Benjamin Bachelart suggère ip6tables -A INPUT -m mac --mac-source 00:1b:77:bc:a4:e6 -p icmpv6 --icmpv6-type router-advertisement -j DROP qui semble correct mais je ne l'ai pas testé.)

Quel problème posent ces RAcailles ? La section 1 les résume : si les machines présentes les croient, et utilisent les informations qu'ils contiennent, elles peuvent se trouver partiellement ou totalement coupées du réseau. Par exemple, si elles changent l'adresse IP du routeur par défaut, pour celle indiquée dans le RAcaille, tous les paquets qui ne sont pas envoyés au réseau local sont transmis à un routeur voyou, qui peut les transmettre... ou pas.

Un point important de ce RFC est qu'il se focalise surtout sur les RAcailles accidentels, ceux provoqués par une erreur de configuration, qui sont de loin les plus fréquents aujourd'hui (les méchants sont plus habiles mais les maladroits sont beaucoup plus nombreux...). En outre, si les RAcailles sont émis par un attaquant conscient de ce qu'il fait, protéger contre eux serait très insuffisant : s'il peut émettre des faux RA, il peut aussi bien interférer avec le protocole ND.

Donc, première question (section 2), quel phénomène peut mener à l'envoi de RAcailles par une machine ? Il y en a trois :

  • La traditionnelle erreur commise par l'administrateur réseaux (qui tape les mauvaises commandes sur le routeur, ou bien sélectionne la mauvaise option dans un cliquodrome),
  • L'erreur commise par un utilisateur qui n'est pas l'administrateur réseaux (comme dans l'exemple du réseau ad hoc cité plus haut, par exemple suite à l'activation de ICS, qui transformera également la machine en un serveur DHCP IPv4, ou bien dans le cas d'un portable configuré pour un réseau isolé et connecté ensuite à un autre réseau),
  • L'attaque délibérée par le méchant, prélude à une DoS ou bien à une attaque de l'intermédiaire. Notons bien que ce genre d'attaques est rarement signalé (alors que les récits de RAcailles accidentels abondent). Le RFC relègue donc ce problème pour de futures études et se concentre sur le problème le plus fréquent.

Et quelles sont les solutions possibles ? La plupart seront détaillées dans d'autres RFC comme le RFC 6105 mais la section 3 du nôtre donne quelques pistes. La plus évidente est de laisser tomber l'autoconfiguration et de revenir aux solutions à configuration manuelle. Sûr mais pas forcément enthousiasmant pour l'administrateur du réseau. D'autant plus que cela n'éliminera pas les erreurs... Pour être cohérente, une telle solution implique, outre la configuration manuelle de l'adresse IP et du routeur, d'ignorer les éventuels RA (avec Linux, il faut mettre la variable sysctl net.ipv6.conf.all.accept_ra à 0).

Autre solution, profiter de ce que les RA soient diffusés à tous pour les observer et détecter ainsi rapidement les RAcailles. C'est ce que fait NDPMon, par exemple. Fait dans le commutateur, comme le propose le RFC 6105, cela pourrait permettre le blocage des RAcailles en temps réel. Le filtrage par les commutateurs peut aussi être configuré manuellement, par le biais d'ACL. Après tout, l'administrateur réseaux sait sur quel(s) port(s) du commutateur se trouvent les routeurs légitimes et il peut donc bloquer les RA sur les autres (quelqu'un a des exemples concrets avec des commutateurs réels ? Je n'ai jamais essayé.) Notez que cela marche seulement si toutes les communications passent par le commutateur, ce qui est typiquement le cas aujourd'hui des réseaux filaires. Avec un réseau sans-fil ad hoc, il faudra trouver autre chose.

De plus haute technologie, il y a aussi l'inévitable solution utilisant la cryptographie, SEND (RFC 3971), où les annonces des routeurs légitimes sont signées. SEND est très peu déployé en pratique, sans doute en raison de sa complexité, et du fait qu'il faille configurer chaque machine avec le certificat de la CA. Du point de vue sécurité, SEND est la solution idéale (cf. section 6), mais il est probablement peu adapté aux environnements assez ouverts, comme un campus ou bien un café avec WiFi, où chacun administre sa machine. Le principal avantage de SEND est qu'il fonctionne aussi en cas d'attaque délibérée et intelligente et il convient donc bien aux environnements qui exigent un haut niveau de sécurité.

D'autres solutions techniques ? Mais oui, l'imagination des experts étant inépuisable. Par exemple, puisque le RFC 4191 ajoute une option Préférence aux RA, pourquoi ne pas mettre cette option à la valeur maximale pour les routeurs légitimes, en espérant que les accidentels la laissent à une valeur plus faible ? Mais le RFC n'indique pas si cette option est souvent reconnue par les clients. Autre idée, se servir des protections de la couche 2 (par exemple 802.1X) pour limiter l'accès au réseau. Le problème est qu'authentification n'est pas autorisation. Une machine peut avoir légitimement un accès, sans être pour autant autorisée à envoyer des RA. Il reste le filtrage au niveau de la machine, déjà mentionné. Son principal inconvénient est qu'il faut manuellement maintenir à jour les ACL, ce qui supprime une bonne partie de l'intérêt de l'autoconfiguration.

Et la contre-attaque ? Si une machine envoie des RAcailles sans y être autorisée, on n'a pas de raison d'avoir des scrupules à la faire taire. Une autre solution aux RA non autorisés est donc de surveiller le trafic (comme avec NDPMon) et de générer des faux RA, ayant la même adresse source que les RAcailles, avec une durée de vie de zéro. Cet empoisonnement devrait donc masquer le RAcaille par le RA à durée de vie nulle (et qui ne sera donc pas utilisé par les machines). Cette technique est mise en œuvre dans la suite logicielle KAME et a déjà été déployée lors de réunions IETF. On peut télécharger le source en http://ramond.sourceforge.net. À noter qu'un tel outil pourrait aussi parfaitement être utilisé pour lancer une belle attaque par déni de service (cf. section 7).

Enfin, dernière solution proposée par notre RFC, configurer les machines pour n'utiliser que DHCPv6 et renoncer à l'autoconfiguration sans état. DHCP peut allouer les adresses. Une nouvelle option, en cours de normpalisation, lui permettra d'indiquer également le routeur à utiliser. DHCP présente de nombreux avantages pour l'administrateur réseaux, notamment d'un meilleur contrôle de la configuration des machines. Mais on n'a fait que déplacer le problème. Comme le montre l'expérience d'IPv4, les serveurs DHCP non autorisés sont un problème, autant que les RA non autorisés... Le seul avantage serait que le problème est mieux connu avec DHCP (voir aussi la section 5.2).

Les différentes solutions, avec leur domaine d'application, sont résumées dans un tableau en section 4. La section 5 discute ensuite d'autres problèmes liés à celui des RAcailles. Par exemple, un RA n'est pas forcément envoyé par diffusion, il peut être transmis directement à une machine et, dans ce cas, a des chances de ne pas être détecté par d'éventuels outils de surveillance. Les RAcailles accidentels seront sans doute en multicast mais un attaquant, lui, choisira peut-être donc l'unicast.

La section 5.2 compare les menaces de RA par rapport à celles de DHCP. De même que les RA peuvent être protégés avec SEND, DHCP peut être protégé par des options d'authentification (RFC 3315, section 21). Mais ne nous voilons pas la face : personne n'utilise ces options de sécurité. Elles sont bien trop contraignantes, alors qu'on choisit justement RA ou DHCP pour se simplifier la vie.

L'importance d'une surveillance du réseau, avec un logiciel comme NDPMon, est rappelée dans la section 5.4. Si cette recommandation est appliquée, l'administrateur réseaux saura au moins ce qui se passe. Actuellement, il est probable que la plupart de ces administrateurs ne savent même pas si le problème existe dans leur réseau.

Toujours dans la série « guérir si on n'a pas pu prévenir », la section 5.5 est consacrée aux conséquences. Si les RAcailles existent et que certaines machines en ont tenu compte, que faire ? Le comportement de la machine touchée est très imprévisible (plusieurs adresses, plusieurs routes par défaut, et, avec SHIM6, la machine peut même croire qu'elle est réellement connectée à plusieurs réseaux). Aujourd'hui, il n'y a pas de moyen simple, une fois les RAcailles supprimés, de ramener ces machines à la normale, on risque d'attendre jusqu'à deux heures (RFC 4862, section 5.5.3) avant que la machine n'oublie le RAcaille.

Quelques documents à lire sur ce sujet et des logiciels à essayer :


Téléchargez le RFC 6104


L'article seul

RFC 6094: Summary of Cryptographic Authentication Algorithm Implementation Requirements for Routing Protocols

Date de publication du RFC : Février 2011
Auteur(s) du RFC : M. Bhatia (Alcatel-Lucent), V. Manral (IP Infusion)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 3 Février 2011


Plusieurs protocoles de routage utilisent de la cryptographie pour l'authentification. C'est le cas par exemple d'OSPFv2 (RFC 2328), IS-IS (RFC 1195) et RIP (RFC 2453). Limitée au début à MD5, la liste des algorithmes utilisées croît petit à petit mais dans le désordre. L'idée de ce RFC est de spécifier le minimum d'algorithmes qu'un routeur sérieux doit gérer, de manière à garantir l'interopérabilité. Il faut être sûr que tous les routeurs aient au moins un algorithme en commun.

La section 1 détaille le problème. Lorsque qu'un protocole de routage (prenons comme exemple OSPFv2, RFC 2328, annexe D) permet d'authentifier ses pairs, il peut le faire par un mot de passe passé en clair, ou bien par un condensat cryptographique du mot de passe et d'autres informations. (D'autres protocoles sous-traitent l'authentification à une couche inférieure, comme OSPFv3 - RFC 5340 - qui la délègue à IPsec mais ils sont hors-sujet pour ce RFC. Depuis le RFC 6506, OSPFv3 a de toute façon une authentification à lui.) Le mot de passe en clair offre peu de sécurité puisque n'importe quel sniffer peut le capter. Ce mot de passe n'est vraiment efficace que contre les accidents, pas contre les attaques délibérées. La protection par condensat cryptographique n'a pas cet inconvénient. Elle fonctionne en résumant un message composé d'un secret partagé (le mot de passe) et d'autres informations connues des routeurs. Ainsi, le mot de passe ne circule jamais en clair.

Traditionnellement, la fonction de hachage utilisée était MD5 (RFC 1321) mais des attaques cryptographiques réussies contre MD5 mènent à son abandon progressif. L'avantage de MD5 était que tout le monde le connaissait et l'utilisait, alors que la migration vers de nouveaux algorithmes fait courir un risque de babelisation. Il faut noter que les attaques connues contre MD5 (RFC 4270) ne s'appliquent pas forcément à l'utilisation qu'en font les protocoles de routage et que la vulnérabilité de MD5 est donc encore dans le futur. Néanmoins, il est plus prudent de prévoir son remplacement dès aujourd'hui. Les remplaçants envisagés sont en général de la famille SHA. Ceux-ci seront sans doute à leur tour remplacés dans le futur, la cryptanalyse ne cessant jamais de progresser. L'ancienne normalisation, qui indiquait « en dur » la fonction de hachage dans la spécification du protocole de routage, n'est donc plus adaptée. Les sections suivantes du RFC détaillent la situation pour les principaux protocoles de routage cherchant, pour chacun d'eux, comment éliminer MD5 tout en ayant un algorithme commun.

Commençons par la section 2, consacrée à IS-IS. Si la norme ISO originelle ne permettait que le mot de passe en clair, le RFC 5304 a ajouté la possibilité de cryptographie, d'abord avec MD5 puis, dans le RFC 5310, d'autres algorithmes comme la famille SHA. L'avantage de l'authentification par mot de pass en clair est que, normalisée dès le début, elle fonctionne avec toutes les mises en œuvre de IS-IS. Sa sécurité est très mauvaise (il est trivial d'écouter le réseau pour découvrir le mot de passe). Il est donc recommandé d'utiliser les solutions cryptographiques, mais cela implique des algorithmes communs. Si un routeur ne connait que SHA-256 et l'autre que SHA-1, ils ne pourront pas s'authentifier mutuellement. Or, même si les deux routeurs mettent en œuvre le RFC 5310, cette situation est possible.

Notre RFC ne fait pas de choix mais demande que les futurs RFC sur IS-IS choisissent au moins un algorithme obligatoire, qui sera donc connu de tous les routeurs, et qui ne soit pas MD5.

L'autre grand protocole de routage interne, OSPF, fait l'objet de la section 3. Si OSPFv3 reposait entièrement sur IPsec et n'avait pas de mécanisme d'authentification propre (cela a changé avec le RFC 6506), OSPFv2 (de très loin le plus utilisé) a son mécanisme à lui. Ce dernier, dans la norme originale (RFC 2328), permettait le mot de passe en clair ou bien de la cryptographie avec MD5. Le RFC 5709 ajoutait la possibilité d'utiliser la famille SHA. Mais les seuls mécanismes d'authentification obligatoires sont ceux de l'ancien RFC (y compris le plus simple, « pas d'authentification »). Comme avec IS-IS, il est donc nécessaire qu'une nouvelle norme dise clairement quel est l'algorithme standard et sûr que doivent mettre en œuvre tous les logiciels OSPF.

Quant à OSPFv3 (section 4), du fait qu'il utilise IPsec, ses algorithmes communs sont ceux d'IPsec, ESP (RFC 4522) qui lui même utilise SHA-1 (RFC 2404). Ce dernier sera sans doute remplacé bientôt par AES (qui avait été introduit dans le RFC 3566).

Et le bon vieux RIP, dans sa version RIPv2 (section 5) ? Sa norme actuelle est le RFC 2453, qui ne prévoyait comme authentification que le mot de passe en clair. Le RFC 2082 ajoutait MD5 que le RFC 4822 a remplacé par SHA. Toutefois, comme les deux autres protocoles cités, RIP n'a pas d'algorithme unique garanti et une nouvelle norme est donc nécessaire, pour éviter que les routeurs ne se rabattent sur MD5 (ou, pire, sur le mot de passe en clair) pour pouvoir interopérer.

La version RIPng, elle (section 6), comme OSPFv3, se repose entièrement sur IPsec et donc sur les mêmes algorithmes.

La section 7 résume et rappelle les problèmes de sécurité abordés. D'abord, tous les mécanismes étudiés ici ne fournissent que l'authentification. Si on désire en plus de la confidentialité, il faut chercher ailleurs (par exemple IPsec avec ESP). D'autre part, les experts en cryptographie conseillent généralement de changer les clés régulièrement, diverses attaques cryptanalytiques prenant du temps. Il ne faut donc pas en donner à l'ennemi. Or, aucun de ces protocoles de routage ne fournit de mécanisme pour un remplacement coordonné des clés, il faut tout gérer à la main.


Téléchargez le RFC 6094


L'article seul

RFC 6092: Recommended Simple Security Capabilities in Customer Premises Equipment for Providing Residential IPv6 Internet Service

Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : J. Woodyatt (Apple)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 25 Janvier 2011


Ah, la sécurité informatique... Sujet de polémiques sans fin, à l'IETF comme ailleurs. Faut-il des pare-feux ? Faut-il protéger le PC de M. Michu par défaut ? Vaut-il mieux la liberté ou bien la sécurité (réponse en un paragraphe, de préférence) ? Il est très difficile de réunir un consensus sur ce thème et, après avoir essayé, le groupe de travail v6ops de l'IETF a décidé de produire uniquement des recommandations sur la configuration d'un pare-feu pour les CPE (les « boxes ») IPv6, sans s'engager sur la question de savoir s'il fallait un pare-feu ou pas...

Le CPE (Customer Premises Equipment) est le petit boîtier qui connecte le réseau du client résidentiel (M. Michu) au FAI. Parfois fourni par le FAI, parfois acheté en supermarché, il est typiquement laissé tel quel, sans changement de la configuration, et sa configuration par défaut a donc une grande importance. Aujourd'hui, où le principal protocole de l'Internet est IPv4, le CPE a en général une configuration par défaut qui inclut l'allocation d'adresses IP privées (RFC 1918) aux machines du réseau local, et une connexion au FAI, par laquelle arrivera une adresse IP publique. Certaines personnes croient que le fait que les machines « internes » ont une adresse IP privée leur assure une certaine sécurité. C'est largement faux mais, ce qui est sûr, c'est que le mécanisme de traduction d'adresses entre l'intérieur et l'extérieur empêche l'ouverture de connexion à la demande des machines extérieures. Si une imprimante a un serveur HTTP pour sa configuration, le monde extérieur ne peut pas s'y connecter par des moyens normaux (il existe plusieurs moyens « anormaux » comme le changement DNS, et c'est pour cela que le bénéfice en terme de sécurité est douteux). Parfois, on est content de ce barrage (qui empêche les méchants barbares de se connecter à notre innocente imprimante, qui n'est probablement pas configurée de manière très sûre, avec son mot de passe d'usine jamais changé), parfois on le regrette (quand le transfert de fichiers en pair-à-pair échoue ou bien quand un coup de téléphone SIP s'établit mais que la voix ne passe pas). Ce filtrage de fait peut en effet frapper aussi bien les applications légitimes que les autres.

Et en IPv6 ? Le NAT s'est imposé pour IPv4 car, de toute façon, vu le manque d'adresses IPv4, il n'y avait pas le choix. Mais en IPv6, on revient à l'abondance. Chaque machine du réseau local a une adresse IP unique au niveau mondial et redevient donc contactable. La sécurité largement illusoire que fournissait le NAT disparait. Que faut-il mettre à la place ? Un pare-feu ? Et, si oui, configuré comment à sa sortie d'usine ? (Rappelez-vous que M. Michu ne changera probablement jamais la configuration. La règle d'ergonomie que rappelle notre RFC est que le réglage de la sécurité dans le CPE doit être facile à faire et encore plus facile à ignorer.)

Notre RFC 6092 ne répond pas à toutes les questions sur la sécurité d'IPv6. Il vise le cas où on veut fournir une sécurité simple dans un environnement simple, celui de l'accès Internet résidentiel. Les cas plus complexes, par exemple celui d'un réseau d'une entreprise, avec des ingénieurs compétents, sont délibérement laissés de côté (section 1 et RFC 4864). Ici, ce RFC propose un compromis jugé raisonnable dans ce contexte, entre la sécurité et le respect du principe de connexion de bout en bout, qui est à la base du succès d'Internet.

Chaque virgule de ce RFC a été négociée avec acharnement. Ainsi, le statut de ce document est « pour information » mais il utilise le vocabulaire normatif du RFC 2119, tout en précisant en section 1.2 que c'est uniquement pour la précision du discours.

La section 2 du RFC décrit le modèle de réseau considéré. Le CPE est un engin simple (on ne peut donc pas lui demander des services complexes), routeur par défaut du réseau local (RFC 6434), et n'ayant typiquement qu'une seule interface avec l'extérieur, celle qui mène au FAI, plus un petit nombre d'interfaces vers l'intérieur (par exemple Ethernet et WiFi). Pour ce qui concerne la sécurité, leur vision du monde est également très simple : un univers rassurant et civilisé du côté du réseau local, un monde hostile et dangereux de l'autre côté. Le RFC 4864 résume les services de sécurité attendus : filtrer les paquets clairement anormaux (comme les paquets venant de l'extérieur mais prétendant avoir une adresse IP source interne, ou comme les paquets martiens du RFC 4949), ne pas permettre de paquets entrants sans qu'une « connexion » ait d'abord été initiée de l'interieur, permettre des exceptions manuellement configurées (sur la base des adresses IP et ports source). En IPv4, un routeur NAT fournissait plusieurs de ces services sans même y penser, comme effet de bord de la traduction d'adresses (qui, en IPv4, impose de garder un état, donc de se souvenir des connexions ouvertes). En IPv6, routage et filtrage sont nettement séparés. Le RFC 4864 proposait donc de répondre au besoin des utilisateurs (qui s'attendent au même niveau de protection en IPv4 et IPv6) en ayant par défaut un pare-feu à état, qui bloque les connexions entrantes.

Il faut noter que certaines applications voudraient bien autoriser les connexions entrantes, au moins depuis certaines adresses. Il n'existe pas actuellement de mécanisme normalisé pour qu'une application puisse dire au CPE « je veux bien recevoir des connexions sur mon port 443, s'il te plait, laisse-les passer ». Plusieurs projets ont été discutés à l'IETF mais sans résultat consensuel pour l'instant.

Autre point à garder en tête, le CPE est un routeur et doit donc se comporter comme tel (RFC 6434, sur les obligations des routeurs). Il doit également (section 2.1) bloquer certains paquets dangereux, comme les usurpateurs ou les martiens cités plus haut, ainsi que ceux ayant l'en-tête de routage 0 (RFC 5095). En revanche, le CPE ne doit pas empêcher le développement de nouveaux services et applications sur l'Internet. Il ne faut donc pas qu'il bloque aveuglément les paquets IPv6 ayant des en-têtes de sécurité ou de routage.

Au niveau 3, le CPE va devoir bloquer par défaut les tunnels, sauf ceux d'IPsec (car il serait paradoxal qu'un pare-feu, censé améliorer la sécurité, bloque par défaut un protocole qui permet de sécuriser le trafic). Pour la même raison, HIP doit être autorisé.

Et au niveau 4 (section 2.3) ? Le principe posé est celui d'une fermeture par défaut : pas de paquets TCP ou UDP entrants s'ils n'ont pas été sollicités de l'intérieur, par une application se connectant à l'extérieur. C'est cette simple règle, qui prend juste une phrase du RFC, qui a suscité le plus de tempêtes de discussions autour de ce document, puisqu'elle revient à renoncer, par écrit, au principe de la connectivité de bout en bout.

La section 3 du RFC transforme ensuite ces principes généraux en recommandations concrètes. Si on est pressé, on peut lire à la place la section 4, qui est un résumé de ces recommandations. Les recommandations sont identifiées par un numéro unique et je vais reprendre ici la syntaxe du RFC, qui les désigne par REC-N où N est le numéro. Dans ses recommandations, cette section s'appuie sur la classification des paquets et des flots (ensemble de paquets liés à la même « connexion ») :

  • Un paquet va vers l'extérieur s'il est issu d'une machine interne, à destination d'une machine externe et vers l'intérieur si c'est le contraire.
  • Pour les flots, c'est plus complexe. Si une machine interne fait une connexion TCP vers le port 80 d'une machine externe, la majorité des octets sera de l'extérieur (le serveur HTTP) vers l'intérieur alors qu'on considérerait plutôt cette connexion comme allant vers l'extérieur. La définition d'un flot allant vers l'extérieur considère donc que c'est le premier paquet qui détermine la direction du flot. Notons que c'est très simpliste et que cette définition ne couvre pas des cas comme SIP/RTP où l'appelant peut demander à recevoir des paquets sur une toute autre « connexion ».

La section 3.1 traite ensuite du cas du filtrage le plus simple, le filtrage sans état, où chaque paquet est examiné uniquement pour son contenu, indépendamment de tout contexte. Il ne s'agit donc que de filtrage de paquets, sans considérer les flots. Ce filtrage sans état devrait éliminer les usurpateurs (REC-5, REC-6, RFC 2827 et RFC 3704). De même, les adresses IPv6 appartenant à des services obsolètes (RFC 3879) ou non admises sur l'Internet public (RFC 5156) devraient être rejetées (REC-3). Les requêtes DNS de l'extérieur devraient être rejetées (REC-8).

Les sections 3.2 et 3.3 traitent ensuite du cas du filtrage avec état, où le CPE filtrant se souvient des paquets précédents et peut donc reconstituer des flots. Le cas facile (section 3.3) est celui où le protocole de couche 4 a une sémantique de connexion. Le pare-feu peut alors savoir exactement quand la connexion est ouverte et quand elle se termine (ce qui permet de libérer les ressources allouées pour le filtrage). Parmi les protocoles dans ce cas, TCP, SCTP mais aussi tous les futurs protocoles de transport à connexion. Un problème typique des pare-feux avec état est en effet qu'ils regardent l'établissement et la fermeture de la connexion et que cela implique qu'ils connaissent le protocole de transport utilisé (beaucoup de pare-feux de bas de gamme ne connaissent pas SCTP et le bloquent donc aveuglément, ce qui rend difficile le déploiement de ce « nouveau » protocole).

Commençons par TCP, le cas le plus simple (section 3.3.1). REC-31 demande que les CPE qui gèrent TCP le gèrent complètement et de manière conforme à la machine à états du RFC 793, y compris dans ses aspects moins connus comme l'ouverture simultanée (les deux pairs envoyant un SYN presque en même temps). C'est quand même un comble qu'il faille un RFC pour dire que les autres RFC doivent être respectés et cela donne une idée des problèmes auquel est confronté l'Internet aujourd'hui. Afin de maximiser les chances qu'une application nouvelle fonctionne correctement, REC-33 demande que le filtrage ait un comportement indépendant de la destination, c'est-à-dire que l'adresse de destination ne soit pas prise en compte pour mettre en correspondance un paquet avec un flot. Le comportement dépendant de l'adresse peut être adopté si on souhaite contrôler davantage. Voir le RFC 5382 pour plus de détails sur la gestion de TCP dans un CPE.

Autre demande de notre RFC qui ne correspond pas à l'état actuel de la plupart des CPE : REC-34 exige que, par défaut, les paquets TCP SYN entrants bloqués suscitent l'envoi d'un message ICMP Destination unreachable. Aujourd'hui, il est probable que la grande majorité des CPE avalent silencieusement le paquet TCP, sans prévenir l'envoyeur.

Et les délais de garde ? A priori, pour les protocoles orientés connexion comme TCP, ils ne sont pas nécessaires, puisque la fin d'une connexion sera toujours explicite, avec les paquets FIN (ou RST). Mais, en pratique, le CPE peut rater la fin d'une connexion (par exemple parce qu'un des pairs TCP a été éteint et n'a donc pas pu terminer proprement la connexion). Pour gérer ce cas, tous les équipements intermédiaires qui gèrent les états des connexions TCP ajoutent un délai de garde et, si aucun paquet n'est passé pendant ce délai, ils suppriment l'état, ce qui empêchera les paquets ultérieurs de passer. C'est souvent un problème pour les applications comme SSH, qui peuvent laisser passer des heures sans envoyer de paquets (avec OpenSSH, la directive ServerAliveInterval permet d'envoyer des paquets pour maintenir la connexion ouverte). Il existe aussi des mécanismes pour envoyer des paquets TCP sans réel contenu, uniquement chargés de maintenir une connexion ouverte (RFC 1122, qui spécifie une durée par défaut de deux heures, bien trop longue pour la plupart des CPE). REC-35 demande donc un délai de garde minimal par défaut de deux heures et quatre minutes (voir le RFC 5382 pour les raisons de ce choix), bien plus long que celui des CPE d'aujourd'hui.

Comme TCP a besoin d'ICMP (notamment pour découvrir la MTU du chemin), REC-36 rappelle que, si un équipement transmet du TCP, il doit aussi transmettre les messages ICMP essentiels, Destination unreachable et Packet too big. A contrario (REC-37), le passage d'un paquet ICMP ne doit pas entraîner le CPE à supprimer les états des connexions TCP (décider, lors de la réception d'un paquet ICMP, si on coupe la connexion TCP associée est un processus complexe, voir le RFC 5927).

TCP est très répandu et relativement bien connu. On peut espérer (même si c'est illusoire) que tous les CPE le gèrent bien. Mais qu'en est-il de SCTP, son concurrent bien moins connu (section 3.3.2) ? D'abord, il faut noter que SCTP a des particularités, notamment le fait qu'une même connexion puisse utiliser plusieurs adresses IP. Cela rend le modèle simple de notre RFC 6092 inapplicable puisqu'il faudrait que les différents routeurs qui voient passer les paquets d'une même connexion se coordonnent (ce qui ne serait pas « simple »). Toutefois, les applications SCTP qui n'exploitent pas toutes les fonctions de ce protocole peuvent quand même s'en tirer. Si tous les paquets passent au même endroit (un seul routeur) et que cet endroit suit le RFC 4960, comme indiqué par REC-38, alors tout peut bien se passer. En pratique, SCTP souffre bien plus du fait que beaucoup de CPE bloquent tous les protocoles inconnus, ce qui signifie en général tous ceux ayant été créés il y a moins de vingt ans (les boxes sont très conservatrices).

La section 3.2, elle, s'occupe du cas moins facile où, contrairement à ce qui se passe avec TCP ou SCTP, il n'y a pas de connexion explicite. Le CPE ne peut pas savoir quand une « session » se termine. La seule solution générale est d'attendre un certain temps après le dernier paquet vu. Autrement, il faut que le CPE connaisse le protocole applicatif utilisé (et sache ainsi, par exemple, qu'une « session » DNS, c'est typiquement seulement deux datagrammes UDP, un de requête et un de réponse). La section 3.2.2 avertit que cette méthode ne doit pas mener à une interdiction de fait des applications nouvelles, donc inconnues du CPE.

Pour ICMPv6, les recommandations concernant son filtrage figurent dans le RFC 4890 (pour le résumer : il ne faut surtout pas filtrer aveuglément la totalité d'ICMP). La règle ajoutée par notre RFC 6092 est de vérifier, avant de faire suivre un paquet ICMP, que les données de la couche transport qu'il contient correspondent à une session en cours (section 3.2.1).

Pour les autres protocoles, afin de maximiser les chances qu'une application nouvelle ou un protocole de couche 4 nouveau fonctionnent correctement, la section 3.2.2 recommande fortement que le filtrage ait un comportement indépendant de la destination (REC-11, endpoint independent filter), c'est-à-dire que l'adresse de destination ne soit pas prise en compte pour mettre en correspondance un paquet avec un flot. Le comportement dépendant de l'adresse peut être adopté si on souhaite une sécurité plus fasciste, peut-être via une option de configuration du pare-feu.

Le cas spécifique d'UDP (rappelons qu'il existe d'autres protocoles de transport que TCP et UDP) est traité en section 3.2.3. Le RFC 4787 donnait déjà des règles pour le comportement attendu d'un routeur NAT avec UDP. Ces règles s'appliquent toujours dans le cas de notre CPE IPv6. Par exemple, REC-14 demande un délai de garde minimum, avant de détruire l'état associé à un flot, de deux minutes (moins si les ports sont dans la zone bien connue, cf. REC-15). Beaucoup d'applications avaient en effet souffert de CPE qui détruisaient l'état trop tôt, empêchant les paquets ultérieurs de passer.

Et IPsec ? Il est en section 3.2.4. Comme son utilisation permet d'améliorer sérieusement la sécurité de l'Internet, il serait paradoxal qu'un équipement assurant des fonctions de sécurité le bloque. REC-21 et REC-22 demandent donc qu'IPsec passe par défaut. Même chose pour HIP avec REC-26. Notons que de telles recommandations laissent de côté le cas de futurs protocoles de sécurité, dont le déploiement risque d'être bloqué par un CPE qui interdit trop de choses par défaut.

Enfin, les applications de gestion font l'objet de la section 3.5. La plupart des CPE ne verront jamais leur configuration par défaut modifiée et, si c'est le cas, celui ou celle qui change la configuration ne sera en général pas un expert. Le RFC ne donne pas plus de détails, à part l'insistance sur le fait que ces fonctions de configuration ne doivent pas être accessibles depuis l'Internet, seulement depuis le réseau local.

On l'a vu, le comportement par défaut d'un CPE qui suit ce RFC est d'interdire les connexions entrantes. Or, certaines applications souhaiteraient pouvoir en recevoir (section 3.4), soit parce qu'elle jouent un rôle de serveur, soit parce que le fonctionnement du protocole sous-jacent implique que l'application se mette en écoute (c'est le cas de SIP). Il n'existe pas de mécanisme normalisé pour l'application de dire au pare-feu « laisse entrer les paquets RTP en provenance de 2001:db8:1010::47:1 », même s'il existe des solutions non-standard comme UPnP. Avec les CPE traditionnels, gérant de l'IPv4 NATé, les applications se servent typiquement de STUN pour « ouvrir (indirectement) une brèche » dans le pare-feu. Et en IPv6 ? Même s'il n'y a pas de NAT, les recommandations de notre RFC 6092 ont le même résultat d'empêcher les connexions entrantes. L'idéal serait un mécanisme standard équivalent à UPnP ou à des propositions comme l'Application Listener Discovery Protocol. Mais il n'existe pas et l'état actuel des discussions à l'IETF ne permet pas de penser qu'il apparaitra bientôt, bien que des propositions existent comme une extension des RFC 5189 ou RFC 4080.

En attendant, les recommendations pour les CPE sont d'offrir un mécanisme pour permettre aux applications de solliciter l'ouverture du pare-feu (REC-48) et de permettre, via une action de l'administrateur, de couper le pare-feu ou de changer sa politique pour laisser entrer les connexions (REC-49). Bien sûr, ce dernier mode impose que les machines sur le réseau local soient proprement sécurisées (le RFC utilise une formulation plus restrictive, en demandant que les machines aient leur propre pare-feu, alors que ce n'est qu'une solution de sécurisation parmi d'autres) mais il est nécessaire que cette option soit présente, car c'est la seule qui permet l'accès à toutes les potentialités de l'Internet. Sans elle, le CPE n'est pas un point d'accès à l'Internet mais un Minitel amélioré.

La section 7, consacrée spécifiquement à la sécurité, prend de la hauteur et rappelle quelques bons principes de sécurité. Elle note ainsi que le RFC ne prétend pas que la politique par défaut proposée (qu'on peut résumer par « zéro connexion entrante par défaut ») soit effective, simplement qu'elle assure le même niveau de sécurité ou d'insécurité que celui fourni par un routeur NAT d'aujourd'hui. Comme le rappelle le RFC 2993, cette politique peut même diminuer la sécurité (par exemple par l'« illusion du limes », ce qui fait qu'on se fie aveuglément à la protection qu'elle offre et qu'on oublie de sécuriser l'intérieur). Les bonnes pratiques de sécurité, et des protections comme celles recommandées dans le RFC 4864 sont donc toujours d'actualité. Après tout, les attaques ne viennent pas que de l'extérieur. Même quand l'attaquant humain n'a pas accès au réseau local, il peut trouver un moyen (via du malware, par exemple) de l'attaquer de l'intérieur.

Cette section sur la sécurité note que la grande majorité des ordinateurs dont le système d'exploitation gère IPv6 ont également un mécanisme de filtrage compatible IPv6. Ce n'est toutefois pas forcément le cas pour les autres machines, comme les imprimantes.

Petite exception au principe comme quoi la sécurité d'un réseau situé derrière un CPE IPv6 conforme à ce RFC est à peu près la même que celle d'un réseau NATé : IPsec n'est pas, par défaut, autorisé par le CPE typique actuel. De toute façon, le dernier paragraphe du RFC, écrit dans le pur style juridique états-unien, note bien que l'IETF n'est responsable de rien et ne garantit pas que les règles énoncées dans ce RFC améliorent la sécurité... C'est une innovation dans un RFC : verra-t-on le RFC sur TCP dire « L'IETF ne promet pas que vous échapperez à la congestion si vous suivez cet algorithme » et celui sur SMTP affirmera-t-il « Attention, utiliser le courrier vous expose au spam » ?


Téléchargez le RFC 6092


L'article seul

RFC 6091: Using OpenPGP Keys for Transport Layer Security (TLS) Authentication

Date de publication du RFC : Février 2011
Auteur(s) du RFC : N. Mavrogiannopoulos (KUL), D. Gillmor
Pour information
Première rédaction de cet article le 3 Février 2011


Le protocole TLS, permettant de chiffrer et d'authentifier des communications sur Internet n'utilisait qu'un seul type de certificats, ceux à la norme X.509 (cf. RFC 5280). Désormais, on peut aussi se servir de certificats PGP. Ce RFC 6091 met à jour la première spécification de « PGP dans TLS », qui était dans le RFC 5081 et la fait passer du statut « expérimental » à « pour information ».

Pour authentifier l'autre partie, lors d'une communication TLS (utilisée par exemple avec HTTP ou bien avec SMTP), on doit signer ses messages avec sa clé privée. Le correspondant doit connaitre la clé publique pour vérifier cette signature. Avec l'ancien protocole SSL et avec son successeur TLS (normalisé dans le RFC 5246), cela se faisait en présentant un certificat X.509. X.509 a plusieurs limites, notamment le fait qu'il dépende d'une autorité de certification. Tout le monde n'a pas envie de payer une telle autorité, pour un gain de sécurité contestable. Il était donc important d'avoir une alternative.

Celle-ci est déjà mise en œuvre dans GnuTLS (pour l'instant, le seul logiciel à le faire).

Techniquement, notre RFC dépend du mécanisme d'extension TLS spécifié dans le RFC 5246. Ces extensions permettent d'annoncer le type de certificat utilisé (extension cert_type, numéro 9 dans le registre des extensions), et donc de choisir X.509 ou bien PGP (PGP est normalisé dans le RFC 4880). Le RFC précise que ces extensions ne doivent pas être utilisées si on ne gère que des certificats X.509, pour interopérer plus facilement avec les vieilles implémentations. Sinon, si le client propose du PGP et que le serveur ne connait pas, ce dernier répond unsupported_certificate. Un registre des types de certificats possibles permettra d'ajouter plus tard autre chose que X.509 ou PGP. L'algorithme de chiffrement de la session, lui, est indépendant du fait qu'on utilise X.509 ou PGP.

Notre RFC utilise le terme de clé pour parler des clés PGP actuelles et de certificat lorsque les mêmes clés sont utilisées pour l'authentification (cf. section 2). La clé PGP est envoyée encodée en binaire, ou bien peut être récupérée sur le réseau, si celui qui veut s'authentifier indique uniquement l'empreinte de la clé (de la même façon qu'un certificat X.509 peut être récupéré sur le réseau, si celui qui veut s'authentifier indique l'URL de son certificat, cf. RFC 6066, section 5). Attention, contrairement à l'option équivalente pour X.509, la possibilité de récupérer le certificat sur le réseau ne permet pas d'indiquer le nom ou l'URL d'un serveur de certificats. Celui-ci doit être connu du serveur (qui vérifiera ensuite que les empreintes cryptographiques correspondent.)

Les changements par rapport au RFC 5081 sont résumés dans l'annexe A. Le principal, de loin, est un changement dans la sémantique du message indiquant le certificat (Client Certificate et Server Certificate) qui fait que les mises en œuvre de l'ancien RFC et celles de notre nouveau RFC 6091 ne peuvent pas interopérer. Comme l'ancien RFC n'avait que le statut « expérimental » et qu'il n'a jamais été largement déployé, ce n'est pas un trop gros problème en pratique.


Téléchargez le RFC 6091


L'article seul

RFC 6090: Fundamental Elliptic Curve Cryptography Algorithms

Date de publication du RFC : Février 2011
Auteur(s) du RFC : D. McGrew (Cisco Systems), K. Igoe, M. Salter (National Security Agency)
Pour information
Première rédaction de cet article le 4 Février 2011


Dans l'arsenal des algorithmes de cryptographie utilisés sur l'Internet, on trouve de plus en plus d'algorithmes basées sur les courbes elliptiques (par exemple les RFC 4754, RFC 5289, RFC 5656 et RFC 5753, sans compter les normes d'autres SDO). Mais il n'existait apparemment pas de texte de synthèse sur cette famille d'algorithmes, utilisable comme référence pour des RFC. Ce manque est désormais comblé avec ce RFC 6090 qui résume ce que tout participant à l'IETF devrait connaître des courbes elliptiques et de leur utilisation en cryptographie. Ainsi, RSA et la factorisation en nombres premiers ne restera pas la seule méthode de cryptographie asymétrique sur laquelle faire reposer la sécurité des communications à travers l'Internet.

Ce RFC nécessite donc un peu plus de connaissances en mathématiques que la moyenne. Le débutant pourra commencer par l'excellent article d'un des développeurs de OpenSSL, Adam Langley, sur son blog Imperial Violet, « Elliptic curves and their implementation ». Il apprendra que les courbes elliptiques n'ont rien à voir avec les ellipses (en mathématiques, lorsqu'on classe des objets en deux types on appelle souvent l'un le type pair, le type impair ; lorsqu'on tombe sur trois types, on qualifie souvent les trois types de parabolique, elliptique et hyperbolique, en référence aux coniques), il verra de jolies images : (toutes les images de cet article ont été volées à l'article sur Imperial Violet). Il devra aussi réviser quelques notions de maths (cf. section 2 du RFC) comme celle de groupe (section 2.2 du RFC). En effet, les points de la courbe elliptique, plus une opération d'addition sur la courbe (qu'on peut aussi représenter visuellement, voir l'image plus loin), qui a un élément neutre (un zéro), forment un groupe. (À noter que le RFC, lui, sans donner de nom à cette opération, la note * qui est d'habitude réservé, en informatique, à la multiplication, voir annexe E pour une discussion de ces deux notations possibles.)

Une fois qu'on a l'addition, on définit la multiplication par un nombre entier positif (qui consiste juste à répéter l'addition). Pour tout point de la courbe, on peut donc relativement facilement le multiplier par un nombre quelconque (ce nombre sera la clé privée). Mais l'inverse est extrêmement dur : étant donné un point résultat, et le point de départ, comment trouver le nombre qui a servi à la multiplication ? Dans le groupe formé par les nombres entiers et l'addition usuelle, c'est trivial (c'est une simple division euclidienne). Sur la courbe elliptique, c'est au contraire une tâche herculéenne. Et c'est là son intérêt pour la cryptographie. De méme que RSA reposait sur le fait qu'une composition des facteurs premiers est triviale mais que la décomposition est très difficile, la cryptographie par courbes elliptiques repose sur le fait que la multiplication sur la courbe est simple, la division très difficile. On a donc la base de la cryptographie asymétrique, une opération mathématique très difficile à inverser.

J'ai dit que la multiplication sur la courbe elliptique était simple mais tout est relatif. L'essentiel de l'article d'Imperial Violet est consacré à la mise en œuvre logicielle et beaucoup d'optimisations sont nécessaires, pour pouvoir multiplier un point en un temps raisonnable, sachant que le facteur de multiplication est un très grand nombre. L'article devient nettement plus chevelu ici, à réserver aux fanas de l'algorithmique.

Après ce petit détour par les maths, revenons au RFC. Il utilise le sigle ECC pour parler de l'ensemble des techniques de Elliptic Curve Cryptography. Ce sont donc des techniques de clé publique, qui peuvent servir à mettre en œuvre des techniques comme Diffie-Hellman ou ElGamal. Bien qu'assez ancienne, ECC est toujours relativement peu déployé, alors qu'elle fournit en général une meilleure sécurité et des performances plus importantes. Notre RFC note que c'est sans doute en partie par manque de documents normatifs facilement disponibles (un problème que notre RFC vise justement à traiter) mais aussi en raison de problèmes d'appropriation intellectuelle (la plupart des techniques ECC sont pourries de brevets jusqu'au trognon, cf. section 9).

Le RFC fournit d'abord un arrière-plan mathématique nécessaire, en section 2. Comme il n'est pas facile de lire des formules mathématiques dans le texte ASCII auquel sont contraints les RFC, la lecture n'en est pas évidente et je suggère de partir plutôt de l'article d'Imperial Violet.

Le RFC donne ensuite la définition d'une courbe elliptique en section 3 et introduit la notion de transformation d'un système de coordonnées dans un autre, afin de faciliter les calculs (cf. annexe F pour du pseudo-code). Surtout, la section 3.3 liste les paramètres dont dépend une courbe elliptique particulière. Des propriétés de ces paramètres dépend la sécurité de la courbe et ils ne doivent donc pas être choisis au hasard (la section 3.3.2 donne les critères qu'ils doivent satisfaire). Un exemple d'une courbe et de ses paramètres, la courbe P-256, normalisée par le NIST (dans FIPS 186-2) et utilisée dans le RFC 4753, est donné en annexe D. Une autre courbe elliptique connue est Curve25519, utilisée dans DNScurve.

Une fois ECC définie, on peut l'utiliser dans des algorithmes de crypto classique. La section 4 décrit ECDH, courbe elliptique + Diffie-Hellman, pour permettre à ces chers Alice et Bob de se mettre d'accord sur un secret (qui servira au chiffrement ultérieur) bien qu'ils communiquent via un canal non sûr. Le principe est simple mais génial. Alice et Bob partent du même point G de la courbe, Alice choisit au hasard un nombre j et met G à la puissance j (je rappelle que le RFC utilise la notation multiplicative, pas l'additive comme dans l'article sur Imperial Violet, et note donc cette opération G^j). Bob en fait autant avec son nombre k pris au hasard. Chacun envoie le résultat de son calcul à l'autre, qui doit alors calculer G^(j*k). Par exemple, Alice reçoit donc G^k et calcule donc G^k^j (qui est équivalent à G^(k*j)). Alice et Bob connaissent donc le secret, G^(j*k), alors que l'écoutant éventuel n'a pu le déterminer, car il ignore j et k.

De même, on peut faire une version « courbe elliptique » de ElGamal (section 5). Cet algorithme de chiffrement était basé sur un autre groupe mathématique, celui des entiers modulo N mais on peut se servir d'un autre groupe, comme celui fourni par une courbe elliptique. C'est ainsi qu'est créé ECDSA, version à courbe elliptique de DSA (cet algorithme est disponible pour DNSSEC, cf. RFC 6605 ; il est déjà mis en œuvre dans PowerDNS ; DNSSEC a déjà un algorithme à courbe elliptique, GOST, cf. RFC 5832).

L'IETF se préoccupant de faire des protocoles qui marchent dans le monde réel, il faut se poser la question de l'interopérabilité. La section 7 décrit donc des détails pratiques nécessaires. Toujours sur le côté concret, la section 8 est consacrée aux détails d'implémentation et aux tests validant celle-ci. Par exemple, un test courant est de vérifier qu'un sous-programme produit, pour des paramètres d'entrée donnés, le résultat attendu. Comme le mécanisme de signature de KT-I (cf. section 5.4) est non déterministe, ce genre de tests ne va pas marcher, la signature étant différente à chaque fois. Par contre, la validation de la signature est, elle, déterministe (heureusement...) et peut donc être testée. De même, ECDH peut être testé avec les résultats des RFC 4753 et RFC 5114.

Reprenons de la hauteur : si les sections précédentes passionneront les mathématiciens et les programmeurs, la section 9 est consacrée aux problèmes que posent les brevets pour le déploiement des courbes elliptiques. Si les bases des courbes elliptiques semblent libres (en théorie, on ne peut pas breveter un théorème mathématique : mais, en pratique, les organismes comme l'Office Européen des Brevets violent régulièrement leurs propres règles, et semblent agir en dehors de tout contrôle démocratique), les optimisations nécessaires sont souvent plombées par un brevet. L'implémenteur d'une courbe elliptique doit donc, après avoir pris connaissance des règles de l'IETF sur le sujet (RFC 3979 et RFC 4879), consulter la base des appropriations intellectuelles publiées.

L'unique but de la cryptographie à courbes elliptiques étant la sécurité, la section Sécurité (la 10), revient donc en détail sur les précautions à prendre pour que les courbes elliptiques remplissent leur rôle. Il existe plusieurs attaques documentées (comme celle de Pohlig-Hellman), l'algorithme de Shanks ou celui de Pollard qui sont des algorithmes génériques, marchant avec n'importe quel groupe, comme des attaques spécifiques d'une courbe elliptique particulière. Le RFC insiste notamment sur l'importance de ne prendre que des courbes dont les paramètres ont été soigneusement choisis (voir aussi le RFC 4086, et l'annexe B, puisque plusieurs opérations dépendent de nombres aléatoires).

D'autre part, la cryptographie ne fait pas de miracles : si Diffie-Hellman protège contre un attaquant passif, il ne peut rien contre un intermédiaire actif.

Merci à Michael Le Barbier Grünewald pour sa relecture mathématique.


Téléchargez le RFC 6090


L'article seul

RFC 6082: Deprecating Unicode Language Tag Characters: RFC 2482 is Historic

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : K. Whistler (Sybase), G. Adams (Skynav), M. Duerst (Aoyama Gakuin University), R. Presuhn, J. Klensin
Pour information
Première rédaction de cet article le 8 Novembre 2010


Parfois, il y a des mauvaises idées. Parfois, elles sont même inscrites dans un RFC et sont alors utilisées. Lorsqu'une idée est reconnue comme mauvaise, il faut alors savoir l'abandonner. C'est ce que fait ce RFC 6082 qui abandonne officiellement l'idée du RFC 2482 qui fournissait un mécanisme d'indication de la langue utilisée, dans un texte brut en Unicode.

Le RFC 2482 réservait plusieurs caractères Unicode entre U+E0000 et U+E007F à des fins d'étiquetage, pour indiquer la langue utilisée pour écrire un texte. Par exemple, U+E0001 U+E006A U+E0061 (caractère language tag, puis caractère tag letter j puis enfin tag letter a) indiquait un texte en japonais (ja étant le japonais pour les étiquettes de langue). Il n'a pas été tellement utilisé en pratique et, aujourd'hui, a été remplacé par des mécanismes d'étiquetage globaux (comme l'en-tête Content-Language: du RFC 3282) pour le texte brut ou bien par des mécanismes plus fins pour les documents structurés (par exemple l'attribut xml:lang pour les textes en XML). Le consortium Unicode a officiellement abandonné ce mécanisme (section 16.9 de la norme Unicode 5.2) et notre RFC 6082 a été fait pour éviter que des implémenteurs tombent sur le RFC 2482 et ne le mettent en œuvre en le croyant toujours d'actualité.

Fin du parcours, donc, pour le RFC 2482, qui entre ainsi dans la catégorie « Intérêt historique uniquement » (catégorie décrite dans la section 4.2.4 du RFC 2026).


Téléchargez le RFC 6082


L'article seul

RFC 6079: HIP BONE: Host Identity Protocol (HIP) Based Overlay Networking Environment

Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : G. Camarillo, P. Nikander, J. Hautakorpi, A. Keranen (Ericsson), A. Johnston (Avaya)
Expérimental
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 25 Janvier 2011


Voici un RFC bien abstrait, qui normalise un mécanisme pour construire des réseaux virtuels (overlays) en utilisant le protocole HIP. Un de ces premiers réseaux virtuels pourrait être celui du protocole RELOAD, utilisé pour faire du SIP pair-à-pair.

Le nom de ces réseaux virtuels, HIP bone, est un jeu de mots sur l'os coxal (hip bone en anglais) et une allusion à d'autres réseaux virtuels comme le défunt 6bone. Mais le but est très différent : IPv6 ne peut pas passer sur l'infrastructure IPv4 du vieil Internet et doit donc être « tunnelé » au dessus d'IPv4, l'ensemble de ces tunnels formant le 6bone. Au contraire, HIP (RFC 5201) étant un protocole entièrement situé dans les machines terminales, il n'a pas besoin de tunnels pour marcher. On peut expérimenter avec HIP dès aujourd'hui. Alors, à quoi sert un HIP bone ? L'idée est de faciliter le développement de services pair-à-pair, d'utiliser HIP pour construire un réseau virtuel de machines HIP, les autres fonctions utiles (comme le stockage des données) étant fournies par des protocoles pair-à-pair situés au dessus (nommés peer protocol dans le RFC). Ces protocoles seront donc déchargés, grâce à HIP, de certaines des tâches de bas niveau.

HIP est un protocole de séparation du localisateur et de l'identificateur. Le routage dans le HIP bone se fait sur l'identificateur et c'est HIP qui se charge de le mettre en correspondance avec les localisateurs sous-jacents, le routage dans l'Internet se faisant sur la base de l'adresse IP (qui, en HIP, est réduite au rôle de localisateur). Si vous ne connaissez pas HIP, la section 3 du RFC sert de rappel.

Le HIP bone lui-même est introduit en section 4. Un réseau virtuel bâti au dessus d'un réseau réel comme l'Internet dépend d'un mécanisme de maintien du réseau (table de routage, tests de connectivité, pairs qui arrivent et qui repartent, etc), d'un mécanisme de stockage et de récupération de données (par exemple une DHT), et d'un mécanisme de gestion des connexions (se connecter à un pair, échanger des messages). Dans le HIP bone, HIP ne fournit que ce dernier service. L'application qui utilisera le HIP bone pourra parler directement à HIP pour certaines fonctions et au peer protocol pour les autres (cf. la figure 3 du RFC).

On l'a dit, notre RFC ne fait que spécifier un cadre assez général. Une bonne partie devra être faite dans le peer protocol et la section 5 du RFC rappelle ce qui relèvera de la responsabilité dudit protocole. Par exemple, il existe actuellement un Internet-Draft décrivant RELOAD (REsource LOcation And Disovery), draft-ietf-p2psip-base, et un autre qui décrit comment bâtir un réseau virtuel pour RELOAD au dessus de HIP, draft-ietf-hip-reload-instance.

Ainsi (section 5.1), c'est au peer protocol de gérer le délicat problème du recrutement (qui peut entrer dans le réseau virtuel). Pour aider ces protocoles situés au dessus d'un HIP bone, la section 6 liste quelques paramètres utiles qui seront mis dans les messages HIP comme le nouvel OVERLAY_ID, qui identifiera un réseau virtuel donné (car une machine HIP sera peut-être membre de plusieurs réseaux virtuels).

Voilà, une fois ce RFC 6079 lu et assimilé, il ne vous reste plus qu'à concevoir votre réseau virtuel à vous ⌣.


Téléchargez le RFC 6079


L'article seul

RFC 6077: Open Research Issues in Internet Congestion Control

Date de publication du RFC : Février 2011
Auteur(s) du RFC : Dimitri Papadimitriou (Alcatel-Lucent), Michael Welzl (University of Oslo), Michael Scharf (University of Stuttgart), Bob Briscoe (BT & UCL)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF iccrg
Première rédaction de cet article le 3 Février 2011


La congestion est la plaie des réseaux informatiques depuis leurs débuts. Quelle que soit la capacité de ceux-ci, les utilisations emplissent les tuyaux jusqu'à ce que ceux-ci débordent. Il y a donc depuis quarante ans, mais surtout depuis le travail de Van Jacobson en 1988 (voir son ancien mais toujours bon « Congestion Avoidance and Control », Proceeding of ACM SIGCOMM'88 Symposium, août 1988 ; attention, c'est assez matheux, réservé aux gens qui comprennent les fonctions de Liapounov), d'innombrables études et recherches sur la congestion. (Voir par exemple l'article du Wikipédia anglophone sur TCP.) Pourtant, le problème est loin d'être épuisé, comme le montre ce RFC du groupe ICCRG de l'IRTF consacré aux problèmes non résolus en matière de congestion. Couvrant tous les aspects de ce problème, il est également une passionnante lecture sur l'état actuel de l'Internet et le bouillonnement d'activité qu'il suscite toujours chez les chercheurs.

Qu'est-ce exactement que la congestion ? La section 1 la définit comme l'état d'un réseau dont les ressources sont tellement utilisées que des phénomènes visibles par les utilisateurs et objectivement mesurables (comme le retard d'acheminement des paquets, voire leur perte) apparaissent. Sur un réseau où les ressources sont partagées mais pas réservées (cas de l'Internet), la congestion se traduit par une diminution de la qualité de service. (Voir Keshav, S., « What is congestion and what is congestion control », Presentation at IRTF ICCRG Workshop, PFLDNet 2007, Los Angeles, février 2007.)

Le contrôle de congestion, lui, est l'ensemble des algorithmes qui permettent de partager les ressources en minimisant la congestion. Il existe sous deux formes, primal et dual (je n'ai pas cherché à traduire ces termes rares, apparemment issus de la recherche opérationnelle). La première fait référence à la capacité des émetteurs à adapter leur rythme d'envoi s'ils reçoivent des indications comme quoi la congestion a lieu. Sur l'Internet, c'est typiquement le rôle de TCP. La seconde forme fait référence au travail des équipements intermédiaires, les routeurs, qui détectent la congestion et réagissent, par exemple via la RED.

Aujourd'hui, des dizaines de RFC ont « congestion » dans leur titre ; le RFC 5783 fournit un survol de cette littérature et le RFC 5681 synthétise tout ce qu'il faut savoir sur la congestion dans TCP. Dans les mises en œuvre de TCP/IP aujourd'hui, d'innombrables lignes de code sont là pour réagir à la congestion. Malheureusement, un bon nombre des algorithmes et méthodes « historiques » pour gérer la congestion sur l'Internet rencontrent leurs limites avec les évolution des réseaux. Résultat, plusieurs systèmes d'exploitation sont livrés avec des algorithmes non-standard (comme, dans certains cas, Linux, avec l'algorithme Cubic ; l'algorithme en cours peut être affiché avec sysctl net/ipv4/tcp_congestion_control et les disponibles avec sysctl net/ipv4/tcp_available_congestion_control). (On peut voir aussi les projets de FreeBSD qui incluent également Cubic et d'autres.) À noter que tous les nouveaux algorithmes ne sont pas forcément un progrès. Francis Dupont fait ainsi remarquer, suite à cet article, que des algorithmes comme « TCP Vegas », excellent lors des tests, ne réussissaient pas aussi bien sur le vrai réseau.

Autre évolution, l'utilisation de solutions qui ne sont pas uniquement de bout en bout mais font participer les routeurs, comme ECN (RFC 3168).

Quels sont les défis d'aujourd'hui ? La section 2 examine les défis généraux. L'un des premiers est l'hétérogénéité de l'Internet (section 2.1). Des liens radio laissant passer quelques misérables kb/s aux fibres optiques Gb/s, l'éventail des capacités est immense. Même chose pour la latence, entre les réseaux locaux où elle est inférieure à la milli-seconde et les liaisons satellites où elle approche la seconde. Rien n'indique que de tels écarts se résorberont. On imagine le travail de TCP, qui doit fonctionner dans un environnement aussi varié. À l'époque de Van Jacobson, latence et capacité des réseaux faisait qu'une connexion TCP n'avait en transit, à un moment donné, que quelques douzaines de paquets. Aujourd'hui, cela pourrait être beaucoup plus. Il n'y a pas actuellement de consensus à l'IETF pour choisir les nouveaux algorithmes, d'autant plus que leurs interactions (entre un pair TCP qui utiliserait un ancien algorithme et un pair qui utiliserait un nouveau) sont mal connues. Si le RFC 5033 définit des critères sur le choix d'un algorithme, ceux-ci ne répondent pas à toutes les questions, comme celle de savoir si on accepte de réduire les performances des anciennes implémentations (ce que font certaines nouvelles méthodes).

Second grand problème, la stabilité (section 2.2). On souhaiterait que, à situation inchangée, les algorithmes de contrôle de la congestion convergent vers un état stable, au lieu de faire du ping-pong entre deux états (on ouvre les vannes, la congestion reprend, on diminue le débit, le trafic passe très en dessous du seuil, alors on rouvre les vannes, etc). Il existe des théories mathématiques à ce sujet pour des algorithmes en boucle fermée, comme TCP, mais qui ne servent pas dans le cas où il y a interaction entre plusieurs boucles de contrôle, ce qui est le cas de l'Internet, où le ralentissement du débit d'une connexion TCP peut pousser les autres à augmenter leur débit. On souhaite également une stabilité locale : si un système est perturbé, après la fin de la perturbation, il revient rapidement à l'équilibre.

Les modélisations issues de la théorie de l'automatique permettent d'éliminer les algorithmes les plus mauvais (s'ils ne marchent pas dans les cas simples, ce n'est pas la peine de se demander s'ils fonctionneront sur l'Internet). Mais elles sont insuffisantes pour les cas réels, l'approche la plus courante aujourd'hui est donc la simulation, ce qui ne garantit pas que ça fonctionnera en vrai. Est-ce que TCP est stable dans des conditions réelles ? Il n'y a aujourd'hui aucune certitude scientifique à ce sujet.

Ce ne sont pas les heuristiques qui manquent, lorsqu'on conçoit un nouvel algorithme de gestion de la congestion, comme par exemple le principe de la conservation des paquets (faire en sorte que l'émetteur envoie autant de paquets par seconde que le récepteur en consomme). Mais elles peuvent être trop exigeantes (c'est le cas de la conservation de paquets, dont il a été démontré qu'elle était un principe suffisant, mais pas nécessaire) ou tout simplement non démontrées.

Un exemple d'un problème réel est que TCP démarre lentement : son débit s'accroit avec le temps au fur et à mesure que l'envoyeur se rassure qu'il n'y a pas congestion. Mais beaucoup de flots de données, à commencer par les courtes connexions HTTP qui récupèrent une seule page HTML, sont de durée tellement faible que TCP n'atteint jamais son état d'équilibre et de débit maximum. Cela peut pousser certains à « améliorer » l'algorithme dans leur intérêt (c'est le cas de Google, voir leur article). Égoïsme ou bien usage normal de la liberté ? En tout cas, cela a poussé à des recherches sur un TCP résistant aux égoïstes comme dans l'article « TCP congestion control with a misbehaving receiver ».

Beaucoup plus chaude est la question de la justice, surtout dans le contexte du débat sur la neutralité de l'Internet. C'est en effet une chose d'assurer le bien de l'Internet, c'en est une autre que de vérifier que cela ne se fait pas aux dépens de certains utilisateurs, sacrifiés au bien commun. Intuitivement, la justice, dans un réseau, c'est que, en cas de sacrifices, tout le monde doit prendre sa part de manière équitable (section 2.3). On touche là clairement à des questions politiques, suscitant des articles vengeurs comme le très intéressant article de Briscoe, « Flow Rate Fairness: Dismantling a Religion » (ACM SIGCOMM Computer Communication Review, Vol.37, No.2, pp.63-74, avril 2007). Briscoe argumente essentiellement sur le fait que la justice entre les flots TCP n'a aucun intérêt, il faudrait chercher la justice entre les personnes, ou bien entre les organisations. Mais, de toute façon, la question de la justice est connue pour être impossible à définir de façon cohérente dans le parallélisme (je cite Francis Dupont) : elle est sujette à un problème de la famille du paradoxe de Condorcet sur le vote équitable, c'est-à-dire que les critères qui établissent l'équitabilité ne sont pas compatibles.

Des RFC ont également traité ce cas comme le RFC 3714. Dans l'approche traditionnelle, pour le cas ultra-simple de deux utilisateurs regardant tous les deux YouTube, la justice était considérée comme l'égalité de leurs débits. Certains idéologues du marché ont par exemple proposé de définir la justice comme « ce que les utilisateurs sont prêts à payer pour éviter la congestion ». Dans cette approche, les deux débits pourraient être très différents. Mais intégrer l'aspect financier ouvre bien d'autres boîtes remplies de questions difficiles comme le mécanisme par lequel on va comptabiliser la contribution à la congestion.

Même si on ne prend pas en compte l'argent dans l'équation, la définition de ce qui est « juste » n'est pas triviale. Pas exemple, l'égalité doit-elle être celle des bits/s ou bien celle des paquets/s ? Faut-il la mesurer sur le long terme de façon à ce qu'une application sur une machine puisse profiter à fond du réseau parce que cette machine a été raisonnable dans les heures précédentes ? Le RFC note justement que ce n'est pas forcément une question de recherche, c'est un débat, et aucun article scientifique ne va le trancher. Le RFC note également que des mécanismes trop complexes, au nom de la justice, pourraient sérieusement handicaper l'Internet (car ralentissant trop les équipements, cf. RFC 5290).

Place maintenant à l'étude détaillée des défis qui attendent l'IETF dans ce domaine. Ils font l'objet de la section 3. Le premier est celui de la répartition du travail entre le réseau (les équipements intermédiaires comme les routeurs) et machines situées aux extrémités (section 3.1). Traditionnellement, l'Internet fonctionne en limitant sérieusement les fonctions des routeurs et en concentrant le travail difficile aux extrémités, où les machines ont davantage de ressources (section 3.1.1), peuvent maintenir un état complexe, et surtout sont sous le contrôle des utilisateurs (mettre trop de fonctions dans les routeurs peut sérieusement menacer la neutralité du réseau).

En outre, si de nouveaux mécanismes de gestion de la congestion apparaissent, et qu'ils sont situés dans les couches basses (comme la couche 3), ils mettront du temps à être déployés, d'autant plus que les concepteurs de routeurs attendront sans doute que ces mécanismes soient stables avant de les câbler en dur dans leurs circuits. Mais, d'abord, que peut faire un routeur pour aider à gérer la congestion ? Il peut le faire par une meilleure gestion de ses files d'attente, ou bien il peut le faire en signalant aux extrémités les problèmes de congestion qu'il voit. La première approche est déjà utilisée mais pas de manière uniforme dans tout l'Internet. Une de ses limites est qu'on ne sait pas trop quels sont les paramètres idéaux, par exemple pour les méthodes RED ou AVQ (Adaptive Virtual Queue) et qu'on ne dispose pas de moyen de les déterminer automatiquement.

La seconde façon dont les routeurs peuvent aider, la signalisation explicite, est utilisée dans ECN (RFC 3168), Quick-Start (RFC 4782), XCP (eXplicit Control Protocol, draft-falk-xcp-spec) et dans d'autres protocoles. Contrairement à TCP, XCP sépare le contrôle de la justice (s'assurer qu'aucun flot de données ne prend toute la capacité) et le contrôle de la congestion. Mais XCP reste très expérimental et produit parfois de drôles de résultats (« An Example of Instability in XCP »). Dans tous les cas, ces mécanismes, qui donnent un plus grand rôle aux équipements intermédiaires, doivent être évalués dans le contexte du fonctionnement de bout en bout, qui est l'un des principaux piliers de l'Internet (RFC 1958), qui a assuré son succès et sa survie. La congestion est un problème intéressant précisément parce qu'elle ne peut pas se régler uniquement de bout en bout (puisque c'est un phénomène spécifique au réseau) mais il faut bien réfléchir avant de mettre dans le réseau des fonctions qui pourraient interférer avec les politiques d'utilisation des machines terminales.

Ainsi, un protocole comme XCP ne nécessite pas d'état dans le réseau (et semble donc respecter le principe de bout en bout) mais c'est uniquement à condition que les machines situées aux extrémités jouent le jeu, c'est-à-dire ne mentent pas sur les débits mesurés. Si on veut faire marcher XCP dans un environnement... non-coopératif (avec des tricheurs), les routeurs doivent alors garder trace des différents flots de données, ce qui met en péril le principe de bout en bout.

Tous ces problèmes (de comptabiliser l'usage que les différents flots de données font du réseau, et en résistant à la triche) existent depuis qu'on parle de QoS sur l'Internet, c'est-à-dire au moins depuis IntServ (RFC 2208). Le problème reste ouvert.

Une des raisons pour lesquels ils ne sont pas résolus est qu'il n'existe aucune technique (section 3.1.2) qui ne repose pas sur un état maintenu dans le routeur, par flot (donc, posant de grands problèmes de passage à l'échelle).

Autre problème pour l'usage des équipements réseaux à des fins de lutter contre la congestion, l'accès à l'information (section 3.1.3). Pour être efficace, le routeur qui veut gérer la congestion doit connaître des choses comme la capacité des liens. Attendez, me direz-vous, un routeur sait forcément que son interface ge-3/0/2 est à 1 Gb/s ! Mais c'est plus complexe que cela : par exemple en cas d'interface vers un réseau partagé (Wifi) ou en cas de tunnels (RFC 2784 ou RFC 4301 ou bien d'autres techniques). Dans ces circonstances, un routeur IP ne connaît pas forcément la capacité des liens auxquels il est connecté.

Idéalement, si le routeur connaît la capacité du lien et le débit effectif, il sait si on approche de la congestion ou pas, via une simple division. Nous avons vu que la capacité n'était pas toujours connue mais le débit ne l'est pas non plus forcément. S'il est très haché, avec de brusques pics, déterminer un débit, pour le diviser par la capacité, n'est pas trivial. Bref, le routeur manque souvent d'informations pour décider. Faut-il créer de nouveaux mécanismes pour l'informer ? Ne risquent-ils pas de tourner très vite à l'usine à gaz ? (Un routeur IP a déjà beaucoup de choses à faire.)

Deuxième défi auquel est confronté TCP/IP : différencier la perte d'un paquet due à la congestion de l'abandon de ce paquet en raison de sa corruption (section 3.2). Actuellement, un routeur abandonne un paquet lorsque la congestion empêche sa transmission sur l'interface suivante. L'émetteur va typiquement interpréter toute perte de paquets comme un signe de congestion et diminuer le débit (TCP le fait automatiquement). Mais la perte du paquet peut être due à une autre cause, par exemple une modification accidentelle d'un ou plusieurs bits, qui rendra invalide la somme de contrôle, amenant la carte réseau à ignorer le paquet anormal. De telles modifications sont rares sur un lien filaire (il faut un gros rayon cosmique) mais relativement fréquentes sur les liaisons radio. TCP diminuerait alors son débit à tort. Le problème est bien connu (voir Krishnan, Sterbenz, Eddy, Partridge & Allman, « Explicit Transport Error Notification (ETEN) for Error-Prone Wireless and Satellite Networks », Computer Networks, 2004, ou bien le RFC 6069). La solution n'est pas évidente, d'autant plus que les deux phénomènes peuvent être liés (une congestion qui se traduit par des corruptions) et qu'il n'est pas évident qu'il faille continuer à envoyer au même débit si on perd la moitié des paquets suite à la corruption (voir un exemple de discussion).

Il y a donc deux problèmes ouverts, détecter la congestion et y réagir. Pour la détection, on pourrait penser compter sur la somme de contrôle dans l'en-tête IP (à condition que la couche 2 n'ait pas déjà jeté le paquet corrompu, ce que fait Ethernet). UDP-lite (RFC 3828) et DCCP (RFC 4340) le font (sans indiquer quelle doit être la réaction à ces corruptions). Une étude a montré que cela marchait bien au-dessus de GPRS et mal au dessus du WiFi. De toute façon, toute détection de corruption dans la couche 3 poserait des problèmes de coopération entre couches, difficiles à assurer pour IP, qui est conçu pour fonctionner sur toutes les couches 2 possibles.

Quant à la réaction à la corruption, il n'existe aucun protocole standard pour cela, bien que plusieurs propositions aient été faites dans la littérature scientifique (le TCP dit « Westwood »).

Un autre « point noir » de la gestion de la congestion est la prise en compte de la taille du paquet (section 3.3). Aujourd'hui, TCP l'ignore complètement, en partie parce que les très grands paquets (> 1500 octets, la MTU d'Ethernet) sont extrêmement rares sur l'Internet. La question de savoir si TCP a tort ou raison d'ignorer ce facteur est toujours un sujet de recherche. DCCP, par contre, peut tenir compte de la taille des paquets (cf. RFC 5622). Les routeurs typiques, en cas de congestion, ne tiennent pas compte de la taille d'un paquet avant de le jeter, alors que certaines études semblent indiquer que cela pourrait être une bonne idée. Beaucoup de questions restent ouvertes sur ce sujet : le facteur limitatif sur le réseau, dans les prochaines années, sera-t-il le nombre de bits ou le nombre de paquets (sur les réseaux lents, c'est clairement le nombre de bits qui peut déclencher la congestion ; mais au fur et à mesure que les réseaux deviennent plus rapides, c'est la capacité des équipements à traiter un grand nombre de paquets qui devient problématique). En cas de congestion, faut-il diminuer le nombre de bits (en réduisant le débit d'émission, ce que fait TCP) ou le nombre de paquets (en tentant des paquets plus gros) ? Actuellement, l'émetteur ne sait pas pourquoi il y a congestion, ce qui rend difficile le changement de son comportement. Prendre en compte la distinction entre débit en bits et débit en paquets compliquerait l'Internet mais y aurait-il un bénéfice ? Si la taille maximale des paquets sur le réseau, actuellement limitée en pratique à 1500 octets dans la plupart des cas, devait augmenter, la question deviendrait brûlante.

La grande majorité des études sur le comportement de protocoles comme TCP supposait un flot relativement régulier sur le long terme, permettant ainsi aux algorithmes d'atteindre leur équilibre. Mais, dans la réalité, les choses ne se passent pas comme cela : un fichier HTML typique se charge avec seulement quelques paquets, et TCP sera donc, pendant toute la durée du flot, dans l'état « démarrage ». Comment améliorer ce cas fréquent (section 3.4) ? Au départ, le protocole de transport ne connaît rien des caractéristiques de la liaison et ne peut donc pas optimiser son débit. L'algorithme standard de TCP est tout de prudence : conçu par Van Jacobson et connu sous le nom significatif de slow start, il consiste à être très modéré tant qu'on ne connaît pas les détails de la liaison (RFC 2581 et RFC 5681). Résultat, le débit moyen est souvent trop bas, le réseau restant inoccupé. Ce problème est reconnu depuis longtemps (RFC 3742) mais sa solution souffre du manque de bases théoriques à cette difficile question (le slow start a été conçu de manière empirique).

Une autre solution serait de modifier les applications pour qu'elles réutilisent les connexions TCP existantes. C'est ce que peut faire HTTP, avec les connexions persistentes (RFC 2616, section 8.1).

Les spécificités de l'Internet ajoutent un nouvel élément au tableau (section 3.5). Contrairement à quasiment tous les autres réseaux informatiques qui ont existé, l'Internet est multi-organisations (le RFC dit multi-domains, où un domain est un système autonome). Ainsi (section 3.5.1), il existe des mécanismes de signalisation de la congestion qui peuvent poser des problèmes dans un tel environnement. C'est le cas de ECN (RFC 3168) où des bits non utilisés jusqu'à présent servent à indiquer que le routeur qui les a mis commence à voir de la congestion. En environnement mono-domaine, tout va bien. Mais dans le cas où le paquet rencontre plusieurs domaines, peut-on encore faire confiance à ces bits, qui ont pu être mis ou retirés à tort, par exemple pour ralentir une victime située dans un autre domaine (sections 8 et 19 du RFC 3168) ? Pour ECN, il y a des solutions techniques possibles (comme le RFC 3540), quoique apparemment peu déployées. Mais, d'une manière générale, toutes les solutions reposant sur la confiance entre domaines sont incertaines (notre RFC cite aussi le cas de TRC, TCP rate controller, un système de surveillance que les flots TCP se comportent bien). L'échange d'informations entre domaines, qui serait certainement utile pour lutter contre la congestion, est frappé de suspicion (section 3.5.2). Mon voisin me dit-il la vérité ? Dois-je lui dire la vérité en sachant que les informations transmises peuvent, entre autres, l'aider à se faire une bonne image de mon réseau, brisant ainsi la confidentialité ? Or, tous les mécanismes de signalisation de la congestion par les équipements réseau sont affectés par ce manque de confiance.

Un problème de sécurité proche est celui des applications malhonnêtes. L'Internet résiste aujourd'hui à la congestion car chaque pair TCP respecte les règles, même quand elles vont contre son propre intérêt. Après tout, un émetteur n'a jamais intérêt à diminuer son débit, si d'autres le feront à sa place. La section 3.7 se penche sur les comportements négatifs que pourraient adopter des applications. Le problème a déjà été étudié et des solutions proposées (RFC 3540). Elles sont efficaces (peut-être trop, dit le RFC, laissant entendre qu'elles pourraient sanctionner des innocents). Mais elles sont très peu déployées. Une des raisons est peut-être que les attaques sont pour l'instant apparemment très peu nombreuses. En fait, note notre RFC, l'étude de la quantité de telles attaques est en soi un sujet de recherche. On ne sait pas vraiment dire pour l'instant s'il y a beaucoup de tricheurs (peut-être l'exemple Google cité plus haut mais il est très récent et pas assez étudié). On soupçonne évidemment que tout logiciel qui annonce qu'il va « optimiser le temps de téléchargement » risque fort d'y arriver en trichant...

TCP n'est pas le seul protocole de transport : certaines applications utilisent un protocole sans contrôle de congestion, comme UDP, et sont donc censées gérer la congestion elles-mêmes. Or, comme indiqué plus haut, ce n'est pas dans leur intérêt et on pourrait voir des abus, comme s'en inquiétait le RFC 3714. Cette question est presque un problème philosophique : une machine connectée à l'Internet est libre, elle peut notamment utiliser le protocole de transport de son choix. Envoyer des octets au maximum de ses possibilités, sans tenir compte de la congestion, n'est-ce pas abuser de cette liberté ? Comme les applications qui utilisent UDP sont souvent les plus gourmandes (vidéo en haute définition, par exemple), le RFC 5405 insistait sur la nécessité qu'elles se comportent gentiment et mettent en œuvre une forme de contrôle de congestion adaptée à leurs bsoins propres.

Les applications ont des exigences souvent très différentes vis-à-vis du réseau. Par exemple, les gros transferts de fichiers peuvent souvent s'exécuter en arrière-plan en profitant de la capacité du réseau quand il est libre, tout en réduisant sérieusement leur débit s'il ne l'est pas (section 3.6). Comment utiliser cette « élasticité » pour mieux gérer la congestion ? L'idée de marquer les paquets en fonction de ces exigences des applications n'est pas neuve (on la trouve déjà dans les bits ToS du RFC 791) mais il y a aussi des propositions plus récentes comme le RFC 3662. Mais en pratique, ces mécanismes ne sont guère utilisés. Actuellement, un groupe de travail de l'IETF, LEDBAT, travaille sur ce sujet.

Enfin, il reste les autres défis, ceux qui sont jugés relativement peu importants aujourd'hui et n'ont donc pas mérité une section dédiée. Ils sont regroupés dans la section 3.8. On y trouve, par exemple, la question de la mesure du RTT (bien des protocoles dépendent d'une bonne évaluation de ce temps). Aujourd'hui, seul l'émetteur d'un paquet a une bonne idée du RTT, en mesurant le moment où revient l'accusé de réception. Il n'existe malheureusement pas de moyen pour le receveur d'estimer le RTT, ce qui l'empêche d'ajuster son comportement. D'autre part, le RTT brut n'est pas forcément utilisable directement (par exemple parce qu'il varie brutalement dans le temps) et il est utile de se pencher sur des valeurs extrapolées, plus lisses, comme celles du RFC 2988.

Autre défi qui se posera un jour (sections 3.8.2) : le cas des logiciels bogués, qui réagissent mal lorsqu'on essaie une nouvelle technique, même si elle est parfaitement légale : beaucoup de machines sur Internet ont été programmées avec les pieds et plantent (ou même plantent leur voisin) si les données envoyées ne sont pas celles attendues (comme ce fut le cas lors de la fameuse crise de l'attribut BGP 99). Ainsi, même si on conçoit un nouvel algorithme génial de contrôle de la congestion, il sera peut-être difficile à déployer. C'est ce qui est arrivé à ECN, qui a connu bien des problèmes mais aussi au window scaling que plusieurs routeurs de bas de gamme rejettaient (c'est arrivé par exemple sur les boxes d'Alice). Y a-t-il une solution à ce problème ? Le RFC suggère une responsabilité au moins partielle de l'IETF en demandant que, à l'avenir, le comportement par défaut des équipements, face à des options ou des champs inconnus, soit mieux spécifié, pour que le vieux logiciel laisse toujours passer proprement les options récentes. Je pense personnellement que c'est une illusion : dans bien des cas, ces règles existaient et les logiciels bogués les ignorent, car leurs auteurs, dissimulés derrière leur anonymat (comment retrouver les responsables du code des AliceBox ?) ont ignoré complètement ces règles. La section 3.8.6 revient d'ailleurs sur le cas des équipements intermédiaires (middleboxes) qui sont souvent les pires (RFC 2775).

Comme déjà signalé plus haut, un défi général auquel est confronté le contrôle de congestion est celui de la sécurité (section 4). Par exemple (RFC 4948), les DoS sont possibles parce que l'Internet n'impose pas de contrôle de congestion (attention, le RFC parle de dDoS mais c'est à mon avis une erreur : si certains réseaux ont des mécanismes de contrôle de congestion obligatoires, aucun ne prévoit un mécanisme global, qui pourrait arrêter un botnet composé de milliers de zombies indépendants). De manière plus générale, aujourd'hui, le respect des règles qui empêchent l'Internet de s'écrouler sous le poids de la congestion est facultatif, laissé à la bonne volonté de chacun. Cela peut être vu comme un problème de sécurité. S'il existait des mécanismes de contrôle de la congestion qui résistent aux égoïstes prêts à tricher, ces mécanismes pourraient également être utilisés contre les DoS.

Voilà, désolé d'avoir été si long mais ce RFC est très riche et le champ des problèmes non encore résolus dans ce domaine de la congestion est immense. Étudiants futurs chercheurs, à vous de travailler à le défricher !

Merci à Pierre Beyssac pour sa relecture et ses commentaires.


Téléchargez le RFC 6077


L'article seul

RFC 6076: Basic Telephony SIP End-to-End Performance Metrics

Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : D. Malas (CableLabs), A. Morton (AT&T Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF pmol
Première rédaction de cet article le 20 Janvier 2011


Le protocole de signalisation SIP est aujourd'hui le plus utilisé pour la voix sur IP. Il existe de nombreux fournisseurs SIP concurrents, de nombreux services SIP un peu partout. Comment les comparer ? Ce RFC se consacre à définir des métriques pour la téléphonie SIP.

Il est le premier RFC produit par le groupe de travail PMOL de l'IETF, groupe de travail qui est consacré à la définition de métriques pour les couches hautes (notamment la couche 7), le groupe IPPM se consacrant aux couches basses comme la couche 3. En suivant ses recommandations, il devrait être possible de comparer des mesures de performances SIP entre différents services. À noter qu'il existait déjà des métriques pour des systèmes de téléphonie autres, comme SS7, mais rien pour SIP.

Comme PMOL (contrairement à un autre groupe de travail sur les mesures, BMWG) établit des métriques pour le monde extérieur, le grand Internet, les résultats des mesures sont influencés par des variables extérieures à SIP, par exemple la qualité du réseau (latence et capacité libre). Les métriques définies ici n'essaient pas de séparer ces variables « réseau » des autres. On teste donc un service, pas uniquement un serveur.

D'autre part, il s'agit bien de définir des métriques (des grandeurs mesurables et définies rigoureusement) et pas des objectifs chiffrés, genre SLA. Ce RFC définit ainsi ce qu'est exactement un temps de réponse, mais pas quelle valeur de ce temps est acceptable pour l'utilisateur.

Après ces préliminaires, la section 2 définit le vocabulaire utilisé. Ainsi, End-to-end fait référence à une liaison entre les deux entités qui communiquent (deux téléphones, par exemple), même si cette communication passe, au niveau 3 par beaucoup de routeurs, et au niveau 7 par plusieurs relais SIP. Une session est la communication établie par SIP (dont le rôle principal est justement d'établir et de fermer les sessions ; le transfert de la voix encodée n'est pas directement du ressort de SIP) et elle peut donc comprendre plusieurs flots de données différents, par exemple plusieurs connexions TCP.

Enfin (non, tout le travail préparatoire n'est pas fini, on n'est pas encore arrivé aux métriques elles-mêmes), toute mesure faisant intervenir le temps, la section 3 est dédiée aux problèmes de mesure de celui-ci. C'est essentiellement une reprise du RFC 2330, section 10. Pour les besoins des mesures SIP (moins exigeantes que les mesures comme le temps d'acheminement d'un paquet IP du RFC 2679), une erreur de moins d'une milli-seconde est demandée, ainsi qu'une stabilité de un pour mille pour la fréquence de l'horloge.

La section 4 introduit enfin ces fameuses métriques. Le temps commence lorsque le premier message est envoyé par un des UA (User Agents, typiquement un téléphone, matériel ou logiciel). Même si ce premier message doit être répété, l'horloge n'est pas remise à zéro. On arrête le chrono lorsque l'opération souhaitée par l'UA est faite, même si elle a nécessité plusieurs transactions SIP (par exemple, si un appel a été redirigé). Des options comme l'authentification (qui est fréquemment utilisée dans le monde SIP car les fournisseurs de service qui procurent un accès au téléphone classique ne sont jamais gratuits) peuvent sérieusement augmenter la durée mesurée mais on n'essaie pas de les retirer du total : elles font partie du service mesuré (voir section 5.3 pour les détails). Enfin, les métriques de la section 4 ne précisent pas la taille de l'échantillon utilisé, se contentant de rappeller qu'on a en général de meilleurs résultats en augmentant la taille de l'échantillon.

Pour comprendre les métriques, il faut se rappeller que le fonctionnement typique d'un téléphone SIP est :

  • Au démarrage du téléphone, on s'enregistre auprès d'un fournisseur SIP (SSP pour SIP Service Provider) tel que OVH ou Free/Freephonie. Cela permettra, notamment, de recevoir des appels entrants même si l'appelant ne connait pas notre adresse IP actuelle.
  • Pour chaque appel téléphonique, on établit une session SIP avec le destinataire, et cette session sert à transmettre les paramètres d'envoi du flux audio (qui n'est pas envoyé dans la session SIP mais via un protocole séparé comme RTP).

Parmi les métriques définies, on trouve :

  • RRD (Registration Request Delay, section 4.1). Elle mesure le temps écoulé entre un enregistrement d'un UA auprès d'un fournisseur SIP (requête REGISTER) et la réponse réussie, typiquement 200 OK (les échecs sont comptés différemment, voir section 4.2), exprimée en milli-secondes.
  • IRA (Ineffective Registration Attempts, section 4.2) qui est le pourcentage des tentatives d'enregistrement qui échouent, soit par réponse négative, soit par expiration du délai d'attente.
  • SRD (Session Request Delay, section 4.3), qui est le délai nécessaire pour établir une nouvelle session. En termes de téléphonie classique, c'est le moment entre la composition du numéro et le décrochage du téléphone en face. En SIP, c'est le délai entre la requête INVITE et la réponse à celle-ci (la réponse pouvant être négative, par exemple un 486 - Occupé).
  • SDT (Session Duration Time, section 4.5) est la durée d'une session (d'un appel). C'est la différence entre le moment de la fin de la session (par requête explicite ou bien par expiration du délai d'attente) et la réponse réussie à un INVITE.
  • SER (Session Establishment Ratio, section 4.6) est le pourcentage de tentatives d'établissement de sessions SIP qui réussit (de même que IRA était le pourcentage de tentatives d'enregistrement auprès du SSP qui échouaient).

Le logiciel de test sipsak affiche dans certains cas des durées mais elles ne sont pas exprimées en terme des métriques de ce RFC donc il faudrait lire le source pour avoir leur sémantique exacte. Ici, l'établissement d'une session :

% sipsak -vv  -s "sip:bortzmeyer@ekiga.net"                      
...
message received:
SIP/2.0 200 OK
...
** reply received after 6.770 ms **

Et ici une session complète avec envoi d'un message :

% sipsak -vv -B "This is a test" -M -s "sip:stephane@10.10.86.76"     
...
received last message 55.642 ms after first request (test duration).

Téléchargez le RFC 6076


L'article seul

RFC 6071: IP Security (IPsec) and Internet Key Exchange (IKE) Document Roadmap

Date de publication du RFC : Février 2010
Auteur(s) du RFC : S. Frankel (NIST), S. Krishnan (Ericsson)
Pour information
Réalisé dans le cadre du groupe de travail IETF ipsecme
Première rédaction de cet article le 8 Février 2011


Le protocole de sécurité IPsec a connu plusieurs versions, et de nombreuses extensions. Le programmeur qui voudrait aujourd'hui le mettre en œuvre, l'administrateur réseaux qui voudrait le déployer, doivent souvent se gratter le crâne assez longtemps, uniquement pour identifier les normes pertinentes. Pour leur faciliter la tâche, l'IETF produit un RFC spécial, la « carte routière » qui est uniquement une liste commentée des RFC qui s'appliquent à leur cas. La précédente version de la carte d'IPsec était le RFC 2411, que notre RFC 6071 remplace. Si vous voulez comprendre IPsec et IKE et que vous ne savez pas par où commencer, ce RFC 6071 pourra vous servir de guide dans la jungle des normes sur IPsec.

La section 1 commence par fournir un résumé bien utile d'IPsec et de ses protocoles auxiliaires comme IKE. IPsec vise à fournir un service de sécurité à tout service Internet, sans modifier les applications (contrairement à TLS). Si l'échange de paquets entre deux machines est protégé par IPsec, toutes leurs communications pourront être authentifiées et/ou confidentielles. On peut utiliser IPsec de bien des façons, mais les plus courantes aujourd'hui sont de créer un tunnel sécurisé entre deux sites ou bien d'établir un VPN entre un site central et des machines en promenade.

IPsec utilise la cryptographie et, pour cela, a besoin de clés. On peut les gérer de plusieurs façons (aujourd'hui, c'est souvent fait manuellement), mais la méthode standard pour la gestion dynamique des clés est IKE.

La section 2 de notre RFC classe les normes IPsec en pas moins de sept groupes : l'architecture, le protocole ESP (qui fournit authentification et confidentialité), le protocole AH (qui ne fournit que l'authentification), les algorithmes cryptographiques, les algorithmes combinés (qui indiquent comment faire fonctionner ensemble les différentes pièces), les algorithmes de préservation de l'intégrité des paquets et enfin IKE.

Du fait de la longue histoire d'IPsec, plusieurs versions de ce protocole coexistent. La version actuelle est IPsec v3 mais IPsec v2 est encore fréquemment rencontré dans la nature. La section 2.1.1 résume leurs différences. Par exemple, le protocole AH (RFC 4302), dont l'utilité est douteuse, puisque ESP fournit les mêmes services (tels que perçus par l'application), n'est plus obligatoire. AH existait en raison des restrictions à l'exportation de logiciels cryptographiques en dehors des États-Unis et de restrictions d'usage moyenâgeuses dans certains pays comme la France. Aujourd'hui que ces restrictions sont assouplies, AH ne fait que générer de la complexité supplémentaire, comme l'exposait la fameuse critique de Niels Ferguson et Bruce Schneier, « A Cryptographic Evaluation of IPsec ».

IKE a aussi plusieurs versions qui coexistent (section 2.3). La version actuelle est la v2, mais la v1 est toujours en service. La v2 se signale (section 2.3.1) entre autres par l'intégration d'EAP, l'utilisation d'ESP pour protéger IKE lui-même (avant, c'était un protocole spécifique qui s'en chargeait), par de meilleures protections contre les DoS, notamment en permettant au répondeur de ne pas allouer trop de ressources avant d'avoir authentifié l'appelant.

Outre les RFC sur IPsec et IKE, présentés plus loin, en section 3, il existe plusieurs registres IANA sur ces protocoles (section 2.4), notamment :

La section 3 décrit les documents à lire si on veut programmer IPsec. Je ne mentionne ici que ceux de l'IPsec récent (IPsec v3) mais notre RFC 6071 décrit aussi (section 3.1.1) ceux de la précédente version d'IPsec, autour du RFC 2401.

Le cœur de IPsec v3 est décrit dans trois RFC (section 3.1.2), le RFC 4301 sur l'architecture générale, le RFC 4302 sur AH et le RFC 4303 sur ESP. Autour de ce cœur, on trouve plusieurs ajouts comme la possibilité d'encapsuler IPsec dans UDP (RFC 3948) ou bien la possibilité de chiffrer sans arrangement préalable entre les parties (RFC 4322), par exemple en récupérant les clés dans le DNS (avec protection par DNSSEC bien sûr).

Sans être des ajouts à IPsec, il existe plusieurs RFC qui discutent de questions générales (section 3.3) comme la traversée des équipements NAT par IPsec (RFC 3715) ou les suggestions pour évaluer si IPsec est une solution adaptée (RFC 5406, uniquement pour le vieil IPsec v2).

IKE est traité de la même façon en section 4 : les documents de base pour la vieille - mais encore utilisée - version et pour la version actuelle, la v2 (le principal document étant le RFC 4306, suivi du document de clarification RFC 4718) puis les ajouts.

La section 5 est entièrement consacrée au délicat problème des algorithmes de cryptographie. Comme la cryptanalyse progresse sans cesse, envoyant dans les poubelles de l'histoire des algorithmes peu sûrs, et poussant à l'introduction de petits nouveaux, il est important qu'un protocole de sécurité comme IPsec puisse suivre l'état de l'art sans avoir besoin d'une révision. En nombre de RFC, c'est de loin ce secteur qui contribue le plus à la taille des normes IPsec. Pour que, dans cette variété de protocoles, deux mises en œuvre d'IPsec aient une chance de communiquer (section 5.1), il faut qu'il y ait un ensemble d'algorithmes communs. Dans IPsec, les algorithmes sont marqués comme obligatoires (toute mise en œuvre d'IPsec doit les implémenter) ou facultatifs. Le RFC 4835 définit les exigences auxquelles doivent obéir les algorithmes utilisés par IPsec, le RFC 4307, celles pour IKE.

La section 5.2 décrit ensuite les algorithmes de chiffrement eux-mêmes, par exemple l'obligatoire NULL (qui ne chiffre rien et ne protège donc rien, RFC 2410), l'obligatoire AES-CBC (RFC 3602, le facultatif Camellia (RFC 4312), etc.

Si la section 5.2 listait les algorithmes de chiffrement, la 5.3 décrit ceux utilisés pour le contrôle d'intégrité. On y trouve HMAC-SHA1 (RFC 2404), dont la mise en œuvre est obligatoire, mais aussi la famille SHA-2 (optionnelle, cf. RFC 4868), et même MD5 (RFC 2403) pas conseillé mais pas interdit non plus, les multiples vulnérabilités de MD5 n'affectant apparemment pas (pour l'instant) son usage en HMAC (RFC 4835).

Certains algorithmes peuvent fournir à la fois le chiffrement et l'intégrité, et la section 5.4 décrit ces combinaisons. Ainsi, AES en mode CCM CBC-MAC permet d'assurer les deux tâches (RFC 4309).

Pas de cryptographie sans nombres aléatoires (section 5.5), par exemple pour générer les clés de sessions de IKE. C'est donc une nouvelle série d'algorithmes qui doit être spécifiée.

Le zoo des algorithmes de cryptographie utilisés devient donc d'une taille impressionnante et on peut se demander si deux pairs IPsec trouveront une combinaison d'algorithmes qu'ils peuvent utiliser tous les deux ! La section 5.6 expose donc les suites. Une suite est un ensemble cohérent d'algorithmes qui simplifie le travail du programmeur : si on implémente toute la suite, on a un groupe d'algorithmes qui interopérera avec les autres utilisateurs de la même suite. En outre, il est plus facile de se référer à une suite qu'à une longue liste d'algorithmes. C'est ainsi que le RFC 4308 décrivait deux suites, « VPN-A », qui inclut 3DES, HMAC-SHA-1, et un mode Diffie-Hellman et « VPN-B » qui inclut AES-CBC, AES-XCBC-MAC et un mode Diffie-Hellman plus long. On peut ainsi choisir tout un ensemble d'algorithmes avec un seul bouton dans la configuration (« Use VPN-B: Yes »). Le RFC 4869 a ajouté quatre autres suites, tirées de normes « Suite B » de la NSA. Elles incluent la famille SHA-2.

Tiens, puisque j'ai parlé de Diffie-Hellman, mécanisme pour permettre à deux pairs de trouver des clés secrètes communes pour pouvoir communiquer, la section 5.7 décrit les RFC qui mentionnent cette méthode dans le contexte d'IPsec. Ainsi, le RFC 5903 est la dernière norme pour l'utilisation de courbes elliptiques dans le cadre Diffie-Hellman, et le RFC 5114 définit de nouveaux groupes pour cet algorithme.

Dans le monde réel, IPsec a connu de nombreux usages qui dépassaient parfois le strict cadre de ce qui était normalisé. La section 7 décrit certains de ces usages, qui étendent et facilitent l'utilisation d'IPsec. Ainsi, les RFC 3586 et RFC 3585 se penchent sur la question de définitions formelles des politiques de sécurité IPsec, le RFC 4807 décrit une MIB pour la gestion IPsec (il semble très peu utilisé), etc.

Une extension intéressante a été BTNS (Better-Than-Nothing Security, section 7.5) qui a introduit le concept de « la plus mauvaise sécurité est celle qu'on ne déploie pas » dans le monde IPsec. Celui-ci était réputé pour sa rigidité et son strict respect des bons principes techniques de sécurité. Ainsi, les protocoles IPsec imposaient une authentification des deux pairs, sans laquelle une attaque de l'intermédiaire était possible. Très bonne idée sauf que, en pratique, cette authentification nécessitait une lourde infrastructure d'identité (par exemple à base d'IGC) et qu'elle a, en pratique, pas mal freiné le déploiement d'IPsec. D'où cette évolution récente (2008) d'accepter un mode sans authentification, BTNS, qui permet d'établir une session IPsec avec des gens qu'on ne connait pas (pensez à un serveur Web, qui ne connait évidemment pas chacun de ses clients à l'avance). Les RFC 5386 et RFC 5387 décrivent BTNS.

Le talon d'Achille de tout protocole de cryptographie est souvent dans la gestion des clés. Où les stocker, comment garantir que la clé privée est en sécurité, que la clé publique est bien authentique ? Pour la seconde question, la garantie que la clé publique est bien la bonne, la section 7.8 rappelle le mécanisme IPSECKEY qui permet de stocker les clés publiques dans le DNS (RFC 4025). Ce mécanisme est resté largement théorique à ce jour (après tout, le DNS n'offrait typiquement que peu de garanties de sécurité) mais la signature de la racine avec DNSSEC le 15 juillet 2010 lui a redonné de l'actualité. Il est désormais possible de valider une clé trouvée dans le DNS.

Le programmeur qui implémente IPsec doit se rappeler que c'est un mécanisme général, situé en desous de la couche transport. Normalement, il est invisible aux applications. Toutefois, certains protocoles intermédiaires font un usage spécifique d'IPsec et la section 8 en donne une liste. Ainsi (section 8.2) OSPF, depuis la version 3 (RFC 4552 et RFC 5340), a remplacé son ancien mécanisme d'authentification spécifique par IPsec. OSPF fonctionnant souvent en diffusion restreinte, cela ne permet pas IKE impose l'usage de clés manuelles. En pratique, ce mécanisme de sécurisation semble très peu déployé et le passage à IPsec, trop complexe par rapport à l'ancienne méthode, a donc réduit la sécurité de OSPF (en sécurité, comme souvent dans d'autres domaines de l'ingéniérie, le mieux est l'ennemi du bien...)

Autre protocole de routage qui aurait bien besoin de davantage de sécurité, BGP. La section 8.6 décrit ce que IPsec peut lui apporter. Le RFC 5566 décrit ainsi une méthode pour protéger les session BGP. En pratique, elle semble quasi-inutilisée, les opérateurs préférant le RFC 2385 (ou peut-être demain son successeur, le RFC 5925). À noter que le plus gros problème de BGP, en pratique, n'est pas l'authentification du pair, mais la confiance qu'on accorde à ce qu'il transmet. Et, là, IPsec ne peut rien.

Autre consommateur d'IPsec, HIP (section 8.3 et RFC 5201). HIP est un protocole de séparation de l'identificateur et du localisateur. Il introduit donc des failles potentielles liées à l'indirection supplémentaire, par exemple d'un méchant essayant de rediriger un trafic important vers une victime en faisant croire que l'adresse IP de la victime est la sienne. N'ayant pas de mécanisme de sécurité propre, HIP délègue la protection de son trafic à IPsec (RFC 5202 et RFC 5206).

IPsec garantissant l'intégrité du trafic IP, il peut rentrer en conflit avec des protocoles qui modifient les paquets, pour de bonnes raisons, par exemple la compression. D'où le nombre de RFC sur l'interaction entre IPsec et ROHC (section 8.5), par exemple le RFC 5856 qui permet de comprimer les paquets dans un tunnel IPsec ou le RFC 5858 qui décrit des extensions à IPsec lui permettant de mieux s'entendre avec ROHC.

Si certains protocoles, comme dans la section précédente, utilisent IPsec, d'autres réutilisent seulement IKE pour leurs besoins propres (section 9). C'est le cas par exemple d'EAP (RFC 5106).

Voilà, ce résumé d'un long RFC (et qui se termine par une longue bibliographie) aura réussi, je l'espère, à donner une idée de la richesse et de la complexité du monde d'IPsec.

Merci à Yves Rutschle pour avoir relu et trouvé une grosse bogue.


Téléchargez le RFC 6071


L'article seul

RFC 6069: Making TCP more Robust to Long Connectivity Disruptions (TCP-LCD)

Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : A. Zimmermann, A. Hannemann (RWTH Aachen University)
Expérimental
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 13 Décembre 2010


Depuis très longtemps, un des problèmes du protocole de transport TCP est le fait qu'il réduise son débit en cas de pertes de paquets, pensant que cette perte provient d'une congestion. Mais si la perte de paquets était due à une coupure temporaire de la connectivité (ce qui est fréquent avec les liaisons radio), il est inutile de diminuer le débit, puisque le problème ne venait pas d'une congestion. TCP devrait au contraire continuer au même rythme, surtout une fois que la connectivité est rétablie. Une solution au problème pourrait être d'utiliser les messages ICMP pour mieux diagnostiquer la cause de la perte de paquets et c'est cette approche que ce RFC 6069 suggère d'essayer.

Rappelons que TCP fonctionne en envoyant des données dont l'autre pair doit accuser réception. S'il ne le fait pas à temps, TCP réemet les données et, s'il n'y a toujours rien, TCP en déduit que le réseau est surchargé (et jette donc des paquets) et, bon citoyen, il réagit en diminuant le rythme d'envoi (RFC 2988 et section 1 de notre RFC 6069). C'est ce comportement qui évite à l'Internet de s'écrouler sous la charge. Il n'est donc pas question que TCP soit modifié pour envoyer systématiquement au maximum de ses possibilités, « au cas où ça passe ». Mais, parfois, TCP est excessivement prudent. Si je débranche puis rebranche un câble réseau pendant le transfert d'un gros fichier, TCP va ralentir alors qu'il n'y avait aucune congestion (voir l'article de Schuetz, S., Eggert, L., Schmid, S., et M. Brunner, « Protocol enhancements for intermittently connected hosts », dans SIGCOMM Computer Communication Review vol. 35, no. 3). En pratique, le cas le plus embêtant se produit avec les réseaux sans-fil où de tels « branchements/débranchements » sont fréquents, soit en raison d'une modification soudaine du médium (une pluie intense, si on est dehors, ou bien un parasite soudain), soit en raison d'un déplacement de l'ordinateur. Peut-on détecter qu'une absence d'accusés de réception était due à une coupure temporaire du réseau ?

D'abord (section 2), il faut distinguer deux sortes de coupure du réseau. Les courtes sont celles qui durent moins longtemps que le délai de retransmission de TCP. Si les files d'attente du routeur situé avant la coupure sont suffisamment grandes, il pourra « tamponner » les paquets et il n'y aura même pas de perte, juste des variations de délai (cf. RFC 3522, RFC 4015 ou RFC 5682). Les longues coupures sont celles qui durent plus longtemps et où l'émetteur TCP doit donc commencer à renvoyer des paquets déjà transmis. Suivant le RFC 5681, TCP ne se contente pas de réémettre, il diminue son rythme de transmission. Si la connectivité revient, TCP ne va pas s'en apercevoir tout de suite et, même si les accusés de réception réapparaissent, TCP continuera à envoyer à un rythme réduit, sans bonne raison, juste parce qu'il a cru à la congestion. Idéalement, TCP devrait, au contraire, recommencer à pleine vitesse dès que la liaison est rétablie.

Comment détecter la coupure et le rétablissement ? La section 3 rappelle l'existence des paquets ICMP Destination Unreachable (RFC 792, RFC 1812 et RFC 4443). Ces paquets sont envoyés par le routeur, vers l'émetteur, si le routeur est obligé de jeter le paquet (codes 1, Host unreachable ou 0, Network unreachable). Mais attention, ils ne sont pas parfaits : ils ne sont pas envoyés en temps-réel (et donc arriveront peut-être après que TCP ait trouvé tout seul qu'il y a un problème) et ils sont en général limités en quantité.

Ces paquets ICMP contiennent les premiers octets du paquet qui a déclenché le problème et l'émetteur peut donc, en recevant le paquet ICMP, trouver la connexion TCP en cause. Le principe du nouvel algorithme expérimental TCP-LD (TCP Long Disruption) est donc d'utiliser ces messages ICMP pour différencier la congestion et la coupure. Dans le cas d'une coupure, cela vaudra la peine de réessayer de manière plus agressive.

L'algorithme est présenté en section 4. Le principe est simple : lorsque TCP a déjà dépassé son délai de garde, attendant un accusé de réception, et en cas de réception d'un message ICMP indiquant une coupure, TCP ne va pas augmenter les délais de retransmission. Au retour des accusés de réception, TCP reprendra « plein pot ». Les détails figurent par la suite. D'abord, TCP-LD ne s'applique qu'aux TCP qui suivaient l'algorithme de retransmission du RFC 2988. L'algorithme ne doit être utilisé qu'une fois la connexion complètement établie. Les seuls messages ICMP pris en compte sont ceux qui sont émis en réponse à des données TCP qui ont fait l'objet d'une retransmission. (Et autres détails, l'algorithme complet figure dans cette section 4.)

Une discussion des différents points à garder en tête figure en section 5. Elle insiste sur le fait que l'algorithme TCP-LD n'est déclenché que s'il y a réception des messages ICMP indiquant une erreur et expiration du délai de garde. Cela garantit que TCP-LD ne sera utilisé qu'en cas de longue coupure. Il y a quand même des cas qui prennent TCP-LD en défaut. C'est le cas par exemple de l'ambiguité analysée en section 5.1. Cette ambiguité vient du fait que le paquet TCP (et donc le message ICMP d'erreur qui concerne ce paquet) n'indique pas s'il s'agit d'une transmission ou d'une retransmission. Ce n'est pas un problème en pratique mais, si l'émetteur TCP qui reçoit le paquet ICMP peut être sûr qu'il y a eu retransmission, il n'est pas forcément sûr que le message d'erreur était en réponse à la retransmission. Encore plus rigolo (section 5.2), TCP-LD peut associer à tort un message ICMP à une session TCP ayant connu une retransmission, simplement parce que le numéro de séquence a dépassé sa valeur maximale et est revenu au début (sur des réseaux rapides, les 32 bits qui stockent le numéro de séquence TCP ne suffisent pas longtemps). La probabilité que cela arrive et interfère avec une coupure réelle est toutefois très faible. D'autres problèmes amusants (pour ceux qui connaissent bien TCP) forment la fin de la section 4, comme par exemple les risques liés aux paquets dupliqués. Un certain nombre des problèmes exposés pourraient être résolus avec l'option d'estampillage temporel de TCP (RFC 1323 et section 6 de notre RFC) : les estampilles pourraient lever certaines ambiguités.

TCP-LD est une technique « côté émetteur » seulement, et qui peut donc être déployée unilatéralement. Y a-t-il des risques à le faire ? La section 7 explore ces risques. Par exemple (section 7.1), si un émetteur TCP essaie de détecter une coupure définitive en se donnant une limite maximale au nombre de retransmissions, l'utilisation de TCP-LD, qui va réduire l'intervalle entre les retransmissions, pourra amener à des conclusions erronées. Il faut donc évaluer la durée maximale qu'on accepte avant de couper en temps, et pas en nombre de retransmissions.

Je l'ai dit au début, ce problème est perçu depuis très longtemps par les utilisateur de TCP. Il y a donc eu bien d'autres efforts pour le résoudre. La section 8 les résume. On y trouve par exemple des modifications des couches inférieures (RFC 3819) ou bien des modifications des routeurs IP, pour qu'ils analysent suffisamment de TCP pour pouvoir générer des messages d'information. TCP-LD, par contre, ne nécessite pas de modification des couches basses, ni des routeurs intermédiaires.

Un point important de ce schéma est que les messages ICMP ne sont sécurisés en rien et que d'autres RFC, comme le RFC 5927, demandent de s'en méfier et au minimum de ne pas agir sans les avoir sérieusement validés. Quels sont donc les risques (section 9) ? Un attaquant pourrait, soit générer des faux messages ICMP Destination Unreachable pour que TCP, croyant à une coupure et pas à une congestion, continue à inonder le réseau, soit au contraire empêcher les messages ICMP d'arriver, ramenant TCP à la situation avant TCP-LD. Dans le premier cas, les paquets ICMP nécessiteraient d'inclure une partie du paquet TCP, dont des éléments difficiles à deviner, comme le numéro de séquence et les mécanismes de validation du RFC 5927 conviendraient donc. Si elles échouent, l'attaquant qui arrive à trouver le numéro de séquence et les autres informations a de toute façon la possibilité de monter des attaques bien pires.

L'algorithme TCP-LD avait été présenté en 2009 à la réunion IETF 75 de Stockholm. Les transparents (« Make TCP more Robust to Long Connectivity Disruptions ») sont en ligne. Ils exposent l'algorithme et le résultat d'une évaluation après mise en œuvre sur Linux. Plein de jolis graphes. À propos de Linux, le travail des auteurs était disponible en http://www.umic-mesh.net/downloads/linux-tcp.html et a depuis été intégré (sous une forme modifiée) dans le noyau standard : regardez tcp_v4_err() dans net/ipv4/tcp_ipv4.c et les commentaires mentionnant draft-zimmermann-tcp-lcd (l'ancien nom de ce RFC 6069).


Téléchargez le RFC 6069


L'article seul

RFC 6068: The 'mailto' URI Scheme

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : M. Duerst (Aoyama Gakuin University), L. Masinter (Adobe), J. Zawinski (DNS lounge)
Chemin des normes
Première rédaction de cet article le 5 Octobre 2010


Le plan d'URI mailto:, qui permettait d'indiquer une adresse de courrier à contacter, était normalisé dans le RFC 2368. Désormais, il est remplacé par ce RFC 6068, qui introduit notamment la possibilité d'internationalisation des adresses indiquées en paramètre de mailto:.

La plupart des plans d'URI, comme http: ou ftp: permettent de désigner une ressource accessible quelque part sur le Web. mailto: est un cas à part dans la mesure où il sert plutôt à déclencher une action, l'envoi d'un message. L'usage le plus connu du plan mailto: est dans HTML, quand on écrit quelque chose du genre :


<p>N'hésitez pas à <a href="mailto:contact@example.org">signaler</a> tout problème que vous verriez dans ces
pages. Merci d'avance.</p>

et le lecteur verra un lien sur le mot « signaler ». Sélectionnant ce lien, son navigateur lui proposera alors d'envoyer un courrier à contact@example.org (ou bien déléguera cette tâche à un MUA).

La syntaxe formelle des URI mailto: figure en section 2. Outre l'adresse de destination (comme dans l'exemple ci-dessus), la grammaire permet de spécifier des champs qui seront pré-remplis comme Subject: (la grammaire ne met pas de limite sur les noms de ces champs, donc elle peut servir pour tout nouveau champ inventé). Juste après le nom du plan, mailto et le deux-points obligatoire, figure l'adresse du destinataire. Elle est évidemment à la syntaxe normalisée dans le RFC 5322, avec quelques restrictions, notamment l'interdiction des commentaires (dans l'adresse Jean Durand <jean@durand.example>, « Jean Durand » est le commentaire). La section 6 fournit de nombreux exemples, que je reprends ici (parfois un peu adaptés). Par exemple, un URI mailto: de base peut être <mailto:chris@example.com> (en utilisant la convention de l'annexe C du RFC 3986 d'écrire l'URI entre chevrons). Un URI avec sujet peut être <mailto:infobot@example.com?subject=current-issue>.

En théorie, n'importe quel en-tête peut être ainsi spécifié et, par exemple, un logiciel qui archive une liste de diffusion sous forme de page Web (comme Mhonarc) pourrait mettre un In-Reply-To: dans les URI, pour garantir qu'une réponse ne casse pas les fils de discussion. Le RFC cite cet exemple :


<li><a href="mailto:list@example.org?In-Reply-To=%3C3469A91.D10AF4C@example.com%3E">
Foo larger than Bar?</a> 2010-10-04 08:28</li>

C'est très astucieux mais, en 2010, je ne connais aucun archiveur qui fasse cela...

Si on spécifie deux champs dans l'URI mailto:, on les sépare par le & : <mailto:joe@example.com?cc=bob@example.com&subject=hello>.

Bien des caractères qui sont légaux dans une adresse de courrier peuvent poser des problèmes dans un URI. C'est le cas par exemple de %, de /, de ?, etc. Ceux-ci doivent être encodés en « pour-cent », c'est-à-dire que, par exemple, ? devient %3F (la valeur de l'octet en hexadécimal). Ainsi, un URI avec indication du corps du message et un espace dans ce corps peut être <mailto:infobot@example.com?body=send%20current-issue>. Un URI pour écrire à gorby%kremvax@example.com devrait s'écrire <mailto:gorby%25kremvax@example.com>. (Cet exemple du RFC fait référence à une vieille blague Usenet.)

Si les caractères à encoder ne sont pas dans ASCII, c'est leur forme UTF-8 qui est encodée pour-cent, octet par octet. Ainsi, Stéphane devient St%C3%A9phane. Doit-on appliquer le même traitement aux caractères dans la partie « domaine » (à droite du @) de l'adresse, si le domaine est un IDN ? Oui, on peut, en appliquant l'encodage pour-cent à la forme UTF-8. Si l'adresse est druon@académie-française.fr, on peut l'écrire druon@acad%C3%A9mie-fran%C3%A7aise.fr dans un URI mailto: mais il faudra le transformer en Punycode (druon@xn--acadmie-franaise-npb1a.fr) au moment de la composition du message, ce qui garantira que cela fonctionne toujours, même avec des applications anciennes. Un exemple plus sophistiqué est donné en section 6.3 avec le mot japonais nattō, qui s'écrit en Unicode U+7D0D U+8C46. Pour écrire à user@"natto".example.org, on aura alors un URI <mailto:user@%E7%B4%8D%E8%B1%86.example.org?subject=Test&body=NATTO>.

Même les champs supplémentaires indiqués dans l'URI peuvent avoir besoin d'être encodés pour-cent, car leur nom peut contenir des caractères ASCII mais interdits dans un URI. C'est encore plus vrai pour les valeurs des champs, qui ont des chances de contenir des caractères non-ASCII. Ainsi, demander du café (cf. RFC 2324) par courrier se fera avec un URI <mailto:user@example.org?subject=caf%C3%A9>. body pose un cas particulier car ce n'est pas un vrai champ de l'en-tête, c'est un pseudo-champ qui identifie le corps du message. Il peut être en UTF-8 (et donc encodé pour-cent), mais on ne doit pas le stocker en Quoted-Printable ou autres encodages utilisés dans le courrier. De toute façon, ce pseudo-champ est conçu pour de courts messages, pas pour du multimédia compliqué.

Des surencodages peuvent ensuite avoir besoin de s'appliquer, selon le contexte. Ainsi, si un URI mailto: comprend un & (utilisé comme délimiteur de paramètres), il ne posera pas de problème en texte seul mais, en XML, il devra être écrit &amp; (regardez le source XML ou HTML de cet article pour des exemples...).

Après ces détails de syntaxe, le mode d'emploi des URI mailto: (section 3). Les normes sur les URI spécifient leur syntaxe mais en général ne donnent guère de détails sur leur résolution : un URI est avant tout un identificateur. Pour mailto:, l'usage typique est d'envoyer un courrier à l'adresse donnée en paramètre, en incluant les champs supplémentaires donnés dans l'URI.

L'encodage des URI, sujet compliqué, justifie une section entière, la numéro 5. Le RFC 3986 impose un surencodage de certains caractères, que l'on peut trouver dans une adresse, dans un en-tête, ou dans le corps du message. Un exemple typique est l'espace, qui doit être écrit %20. Quant aux fins de ligne, elles doivent suivre la règle de l'Internet et être composées de deux caractères, %0D%0A. Tout logiciel qui produit des URI mailto: doit donc faire attention à encoder ces caractères « spéciaux ». Par exemple, dans un formulaire HTML, il est courant de représenter l'espace par un +. Mais cela peut créer une confusion avec les vrais +, qui peuvent se retrouver dans un URI mailto:, y compris dans l'adresse comme dans l'exemple bill+ietf@example.org que cite le RFC. Bref, l'espace doit être représenté avec %20 et le + par lui-même ou par %2B.

À noter que ce RFC n'inclut pas la possibilité d'utiliser des adresses de courrier complètement internatonalisées, la spécification de celles-ci étant encore marquée « expérimental ». Elle est devenue norme complète en 2012 avec le RFC 6530.

Les changements depuis le RFC 2368 sont rassemblés en section 9 : le principal est évidemment la possibilité d'inclure de l'UTF-8, encodé en pour-cent, possibilité qui ajoute l'internationalisation aux URI mailto:. Le nouveau plan mailto: est désormais enregistré dans le registre des plans, tel que documenté en section 8.

Comme l'utilisation normale d'un URI mailto: est une action (envoyer un message), il faut soigner la sécurité, à laquelle la section 7 est consacrée. L'utilisateur n'est pas forcément conscient de ce qu'il fait (d'autant plus que le texte du lien peut être trompeur, par exemple <a href="mailto:victim@example.com">Envoyez un message à attacker@example.net</a>). Le RFC insiste donc que le logiciel ne doit pas envoyer de message en réaction à un mailto: sans l'accord explicite et informé (affichage du contenu complet, et des en-têtes) de l'utilisateur. Autrement, l'utilisateur risque, sans s'en rendre compte, d'envoyer des messages qui lui vaudront des ennuis (par exemple parce qu'ils contiennent des menaces).

D'autre part, les URI mailto:, étant structurés, se prêtent bien à l'analyse et donc à la récupération automatique. Comme cette récolte a en général pour but l'envoi de spam, il peut être préférable de ne pas utiliser d'URI mailto: (c'est le cas de ce blog pour l'adresse indiquée en bas de chaque page).

Autre problème, la section 4 met en garde contre les en-têtes « dangereux ». Une liste indicative se trouve en section 3, incluant par exemple les en-têtes de routage du courrier comme Apparently-To:. From: est aussi dangereux (car il permet de faire envoyer un message qui ment sur sa source). Le RFC cite ensuite quelques en-têtes « sûrs » : Subject:, Keywords: et le pseudo en-tête body. Si un URI mailto: contient des en-têtes dangereux, le navigateur ne doit pas envoyer le message, ou alors il doit le « censurer » en ne tenant pas compte des dits en-têtes. De toute façon, en pratique, le créateur d'un URI mailto: ne peut pas espérer que les en-têtes autres que Subject: et body soient compris par le navigateur.


Téléchargez le RFC 6068


L'article seul

RFC 6067: BCP 47 Extension U

Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : M. Davis (Google), A. Phillips (Lab126), Y. Umaoka (IBM)
Pour information
Première rédaction de cet article le 8 Décembre 2010


Le RFC 5646 (alias « BCP 47 » pour Best Common Practice 47), qui normalise les étiquettes de langue, prévoyait un mécanisme d'extension par le biais de sous-étiquettes d'un seul caractère. Ce RFC 6067 spécifie la première de ces extensions à rentrer en service, pour indiquer l'information de localisation du consortium Unicode.

Les étiquettes de langue sont utilisées pour marquer du contenu sur le Web mais également en plein d'autres endroits, afin d'indiquer la langue utilisée. Leur norme, le RFC 5646 décrit un mini-langage permettant d'indiquer la langue mais aussi l'écriture, le pays, voire la variante dialectale. Ainsi, ru-petr1708 désignera le russe tel qu'il était écrit dans l'ortographe de Pierre Ier, avant la réforme de 1917. Ce langage de construction des étiquettes est très riche mais ne permet de faire une étiquette qu'à partir de sous-étiquettes déjà enregistrées dans le registre des langues (ou bien à partir de sous-étiquettes purement privées). Il n'y a notamment pas de moyen pour utiliser les catalogues existants.

Or, un de ces catalogues est particulièrement utilisé, le catalogue des locales décrit dans le TR35 et géré par le consortium Unicode. C'est pour pouvoir l'utiliser que l'extension « u » est créée par notre RFC. (Le singleton « u » voulant dire Unicode.) Il permettra d'étiqueter avec d'avantage de précision un document. Ainsi, en-u-cu-usd désignera un texte en anglais dont, grâce à l'extension « u », on pourra savoir qu'il utilise le dollar états-unien (usd) comme unité monétaire.

Les données utilisables avec cette extension proviennent du CLDR, le grand dépôt des locales géré par le consortium Unicode et qui contient des choses aussi variées que les jours fériés par pays ou bien les différents ordres de tri utilisés.

Le RFC 5646/BCP 47 (section 3.7) impose un certain nombre de règles pour la création d'une extension, notamment l'indication précise de l'autorité en charge du catalogue accessible via l'extension, et de ses politiques. La section 2 de notre RFC 6067 satisfait à cette règle en décrivant comment est géré CLDR.

Maintenant, quelle information peut-on indiquer avec l'extension « u » ? La section 2.1 les liste en renvoyant à la section 3 du TR35. On peut indiquer des attributs, des clés et des types. Aujourd'hui, aucun attribut n'est défini. Les clés, elles, ont exactement deux caractères et sont définis par le TR35. ca désigne un calendrier, co un ordre de tri, cu la monnaie, tz le fuseau horaire, etc. Les types sont les valeurs associées aux clés. Ainsi, ca-coptic désigne le calendrier copte. Une étiquette complète comme de-DE-u-co-phonebk sera « l'allemand tel qu'écrit en Allemagne, utilisant l'ordre de tri phonebk, i.e. celui normalisé pour l'annuaire téléphonique (qui se nomme phonebook dans CLDR, qui n'a pas les mêmes contraintes de taille) ». en-u-tz-usden sera l'anglais avec le fuseau horaire Mountain Time. Et es-u-cu-mxn sera l'espagnol avec comme unité monétaire le peso mexicain. Bien sûr, dans la plupart des cas, il n'y aura pas besoin d'étiqueter les textes avec ce niveau de précision. (Merci à Doug Ewell pour la plupart des exemples.) Mais certaines utilisations pourront en avoir besoin.

CLDR distribue des fichiers contenant les informations nécessaires pour tous les types possibles en http://unicode.org/Public/cldr/. Si vous voulez l'ordre de tri allemand, il est en common/collation/de.xml.

La section 2.2 du RFC contient le formulaire d'enregistrement obligatoire (RFC 5646, section 3.7) pour une extension. « u » est donc désormais le premier élément du registre des extensions..

Attention à un petit piège : les extensions comme « u » n'ont rien à voir avec les Extended Language Subtags (alias extlangs), qui sont un mécanisme (pas le seul) pour représenter des idiomes intermédiaires entre une « vraie » langue et un dialecte.


Téléchargez le RFC 6067


L'article seul

RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions

Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : Donald Eastlake 3rd (Stellar Switches)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 18 Janvier 2011


Ce RFC décrit les extensions au protocole cryptographique TLS (résumées en section 1.1). Je n'en cite que certaines ici, lisez le RFC pour une liste complète. Ces extensions ne changent pas le protocole : un client ou un serveur TLS qui ne les comprend pas pourra toujours interagir avec ceux qui les comprennent. Le serveur doit en effet ignorer les informations contenues dans le Hello Client qu'il ne connait pas (section 7.4.1.2 du RFC 5246).

Le mécanisme général des extensions figure dans le RFC 5246, notamment la section 7 de ce dernier (voir la structure en 7.4.1.2). En gros, le principe est d'ajouter des données à la fin du paquet Hello, qui marque le début de la négociation TLS. Dans le langage de spécification propre à TLS, la liste des extensions possibles est un enum (indiqué en section 1.1) mais elle est désormais en ligne à l'IANA.

SNI (Server Name Indication, section 3) permet au client TLS d'indiquer au serveur le nom sous lequel il l'a trouvé. Cela autorise le serveur à présenter des certificats différents selon le nom sous lequel on y accède, fournissant ainsi une solution au problème récurrent de l'authentification avec TLS lorsqu'un serveur a plusieurs noms. À noter que SNI fonctionne avec les IDN, le RFC décrivant le mécanisme à suivre. Si le RFC 4366 permettait au client d'envoyer plusieurs noms, cette possibilité a été supprimée.

Maximum Fragment Length, section 4, permet au client d'indiquer qu'il souhaiterait des fragments de données de taille plus réduite. Cela peut être utile pour un client contraint en mémoire ou en capacité réseau, par exemple un téléphone portable. Certains de ces clients contraints apprécieront également Truncated HMAC (section 7) qui autorise à réduire la taille du MAC utilisé pour protéger l'intégrité des paquets.

Normalement, dans TLS, le certificat du client est envoyé pendant la session TLS. Mais l'extension Client Certificate URLs (section 5) permet au client d'indiquer un URL où le serveur ira chercher le certificat, allégeant ainsi le travail du client (là encore, c'est prévu pour les clients limités en puissance ou en capacité réseau). Une somme de contrôle en SHA-1 est ajoutée à la liste des URLs envoyés, pour permettre davantage de vérifications (autrement, le serveur risquerait, en cas d'empoisonnement DNS, par exemple, de récupérer un mauvais certificat). Dans le même esprit, la section 8 décrit (Certificate Status Request), une extension qui permet d'indiquer la volonté d'utiliser OSCP (RFC 2560), un protocole d'interrogation de la validité de certificats X.509 (plus léger que l'habituel téléchargement de la liste de certificats révoqués, suivi d'un traitement local).

Qui dit nouvelles extensions, dit nouvelles erreurs. La section 9 est donc consacrée aux nouveaux codes d'erreur, pour toutes les extensions décrites. La plus évidente étant unsupported_extension où le client TLS reçoit une extension qu'il n'avait pas demandé (mise dans son Hello). Certaines n'existaient pas dans le RFC 4366 comme certificate_unobtainable, utilisé si le mécanisme de Client Certificate URLs de la section 5 n'arrive pas à récupérer le certificat indiqué.

Tout le protocole TLS servant à la sécurité, il est normal de se demander si les extensions en question vont avoir un effet positif ou pas sur la sécurité. C'est ce que fait la section 11, qui examine les points forts ou faibles de la sécurité de chaque extension. SNI ne semble pas poser trop de problème, par contre Client Certificate URLs fait que le serveur TLS va jouer un rôle de client (en général, avec le protocole HTTP), ce qui soulève des questions : le client TLS ne va t-il pas utiliser cette extension pour pousser le serveur à attaquer un serveur HTTP, d'autant plus que le client TLS contrôle complètement l'URL ? Ou bien le client TLS coincé derrière un pare-feu ne va-t-il pas essayer de convaincre le serveur TLS de récupérer quelque chose de son côté du pare-feu ? Un serveur HTTP normalement non accessible depuis l'Internet pourrait ainsi être indirectement attaqué, si un serveur TLS gérant cette extension se trouve sur son réseau. Il est donc recommandé que cette extension ne soit pas activée par défaut et seul un jeu limité de plans d'URL soit accepté (ce dernier conseil me semble vain : le plan http: sera forcément sur la liste et c'est sans doute le plus intéressant pour un attaquant).

Quant à Truncated HMAC, elle peut aboutir à affaiblir la sécurité puisque le HMAC court est forcément moins fiable. Ce n'est pas forcément très grave car une attaque par force brute contre ce HMAC ne peut pas être faite hors-ligne mais doit être exécutée pendant la session TLS et qu'une seule erreur de la part de l'attaquant coupe la session.

L'annexe A résume les changements depuis la RFC 4366. Le principal est que la RFC 4366 spécifiait à la fois un mécanisme d'extension et des extensions spécifiques. Le mécanisme d'extension ayant été mis dans le RFC 5246 (section 7.4.1.2 à 7.4.1.4), notre RFC 6066 ne contient plus que les extensions.

D'autre part, l'extension SNI a été simplifié en éliminant la possibilité de noms en UTF-8. Désormais, IDN ou pas, le nom doit être représenté en ASCII. Et le condensat cryptographique sur les certificats reçus par l'extension Client Certificate URLs est désormais obligatoire.


Téléchargez le RFC 6066


L'article seul

RFC 6062: Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : S. Perreault (Viagenie), J. Rosenberg (jdrosen.net)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 30 Novembre 2010


Le protocole TURN, qui permet à deux machines coincées derrière des routeurs NAT de communiquer en utilisant un relais tiers, a été normalisé dans le RFC 5766, dans une version minimale, uniquement pour IPv4 et seulement pour UDP, les services « incontestables », qui étaient pressés d'avoir une solution. Depuis, des extensions à TURN sont développées pour d'autres services. C'est ainsi que ce RFC 6062 permet d'utiliser TURN pour établir des liaisons avec TCP.

TURN, tel que normalisé dans le RFC 5766, pouvait déjà utiliser TCP entre le client et le relais (le serveur). Mais, en sortie du relais, vers l'autre pair, c'était forcément de l'UDP. Cela posait un problème (section 1 du RFC) lorsque l'autre pair ne pouvait pas faire d'UDP, ou bien lorsque les propriétés de TCP (notamment de fiabilité) étaient nécessaires. Supposons un logiciel d'audio-conférence : le son est typiquement transmis en UDP (car la rapidité est préférable à la fiabilité, pour ce service) mais si on veut ajouter un système permettant aux participants de se montrer des images, TCP est certainement préférable, afin de transférer le fichier représentant l'image. Avec le protocole TURN, cela se nomme une « allocation TCP » et ce sera désormais possible, aussi bien en demandant une session TCP entrant vers un pair, qu'en acceptant une session TCP sortant d'un pair.

La section 3 rappelle le fonctionnement de TURN : le client TURN ouvre une connexion avec le serveur TURN (qui servira de relais) pour le contrôle (messages TURN, pour ouvrir et fermer des connexions). De plus, pour chaque connexion avec un pair, le client TURN aura une connexion de données pour faire passer ses données (son et image, dans l'exemple précédent), avec divers protocoles (par exemple RTP). Pour chacune de ces connexions de données, il y aura également une connexion entre le relais (le serveur TURN) et le pair avec qui on communique.

Pour avoir une allocation TCP, le client TURN va envoyer, sur la connexion de contrôle, une requête Allocate avec un attribut REQUESTED-TRANSPORT indiquant TCP. Le serveur, s'il accepte la requête, écoutera alors en TCP. Chaque fois qu'il voudra envoyer des donnée à un pair, le client enverra une requête Connect au serveur TURN et celui-ci se connectera à son tour en TCP au pair. Enfin, le client devra ouvrir une nouvelle connexion TCP pour les données (voir section 4.3). Une fois cette dernière connexion établie, le relais « connectera » les deux connexions (client->relais et relais->pair) puis relaiera les données entre les deux pairs.

Dans le cas où le client accepte que ce soit le pair qui initie la session, il indique d'abord au serveur qu'il accepte les connections entrantes (requête CreatePermission), le serveur écoute en TCP et, établit la connexion avec le pair et, lorsque c'est fait, signale au client que le pair est arrivé. Le client peut alors faire une connexion TCP vers le serveur puis tout continue comme dans le cas précédent.

Les détails pratiques figurent dans la section 4 (obligations du client) et 5 (obligations du serveur). On notera que, pour relayer du TCP, la connexion entre le client et le serveur doit être en TCP (pour relayer de l'UDP, elle pouvait être en UDP ou TCP). Outre l'attribut REQUESTED-TRANSPORT déjà mentionné, qui doit avoir la valeur 6 (pour TCP), le client doit prendre soin de ne pas inclure des attributs spécifiques à UDP comme EVEN-PORT (qui force l'utilisation d'un port de numéro pair, et qui n'est utile que pour UDP, voir le RFC 5766, section 14.6). TURN utilisera un attribut CONNECTION-ID qui sera indiqué lors de l'acceptation d'une allocation TCP, et devra être donné par le client lors de sa connexion TCP ultérieure, pour permettre au relais de mettre les deux opérations en correspondance.

Le serveur, lui, doit accepter toutes les connexions TCP entrantes (section 5.3), du moment qu'une allocation a été faite (et, donc, un port réservé). Un essai avec telnet montrera donc toujours Connected to $HOSTNAME. C'est ensuite que le serveur TURN vérifie que le client avait donné la permission de se connecter. Sinon (ou si le client, bien qu'il ait donné la permission, ne se manifeste pas lorsqu'on lui signale que le pair est arrivé), la session, à peine acceptée, sera close d'autorité.

La section 6 décrit l'enregistrement à l'IANA des nouvelles méthodes (Connect, ConnectionBind et ConnectionAttempt), d'un nouvel attribut CONNECTION-ID et de nouveaux codes d'erreur 446 (déjà une connexion pour ce couple adresse/port) et 447 (échec de la connexion avec le pair) dans le registre des paramètres STUN (rappelez-vous que TURN est défini comme une extension de STUN).

Enfin, la section 7, sur la sécurité, met en garde contre un petit piège : entre l'acceptation d'une connexion et son branchement de l'autre côté, le relais risque de recevoir des données, qu'il doit tamponner (section 5.2). Le tampon risquant de devenir trop gros, la section 7 demande qu'une taille maximale lui soit fixée.

Une mise en œuvre se trouve dans le service de Viagénie mais ne semble pas activée à l'heure actuelle. Pour une implémentation libre, turnserver a cette option TCP depuis la version 0.4.

Merci à Simon Perreault pour sa relecture et ses remarques.


Téléchargez le RFC 6062


L'article seul

RFC 6059: Simple procedures for Detecting Network Attachment in IPv6

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : S. Krishnan (Ericsson), G. Daley (NetStar Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dna
Première rédaction de cet article le 2 Décembre 2010


Un engin mobile connecté à l'Internet change souvent de réseau. Il se déplace, s'attache à un autre réseau, perd le contact avec la borne WiFi, retrouve du 3G un peu plus loin et, chaque fois, il peut se retrouver sur un réseau différent, avec des paramètres différents mais aussi parfois sur un réseau déjà visité, auquel cas il peut peut-être réutiliser tout de suite des paramètres mémorisés. Il est donc nécessaire de pouvoir déterminer rapidement à quel réseau on est attaché, et si les paramètres précédents sont toujours valables. C'est le but de la méthode exposée dans ce RFC, équivalent IPv6 du RFC 4436.

Le but, comme exposé par la section 2.1, est donc de rendre la mobilité plus agréable, sans avoir à changer les routeurs, sans dégrader le service existant (par exemple, le temps de réponse ne doit jamais être pire qu'avec les méthodes actuelles), en acceptant des faux négatifs (un réseau déjà visité n'est pas reconnu) mais jamais les faux positifs (un réseau nouveau est pris à tort pour un réseau connu).

A-t-on besoin d'un nouveau protocole pour cela ? Après tout (section 2.2), il existe déjà la procédure standard de Neighbor Discovery du RFC 4861. Le nouveau Simple DNA ne sera pas une amélioration de ND dans tous les cas mais il aidera dans certains, notamment ceux où l'engin se déplace régulièrement parmi un ensemble de quelques réseaux. Si le réseau est complètement nouveau, Simple DNA n'apportera rien (mais n'aura pas d'inconvénients). De même, Simple DNA n'aidera pas pour le cas où le réseau est statiquement configuré, il ne marche qu'avec les adresses allouées par Router Advertisement (RFC 4862) ou DHCP (RFC 3315).

Simple DNA va fonctionner en interrogeant les routeurs connus pour voir s'ils sont toujours là. Une autre approche aurait été possible, en interrogeant les couches basses (section 2.3) pour voir si l'attachement au réseau n'avait pas changé (par exemple, même si le RFC ne le mentionne pas, en WiFi, on peut regarder le SSID et l'adresse MAC de la borne). Mais cette méthode aurait été moins générale.

Donc, comment fonctionne ce Simple DNA (section 2.4) ? Le fait d'être connecté à un réseau est signalé par les couches basses (Link Up en Ethernet ou WiFi). Reste à trouver à quel réseau on est connecté. Simple DNA utilise à la fois des paquets unicast Neighbor Solicitation (RFC 4861, section 7.2.2) et des paquets multicast Router Solicitation (RFC 4861, section 6.3.7) pour tester les routeurs dont il se souvient. Si aucun ne répond, Simple DNA passe aux procédures normales, Stateless address autoconfiguration ou bien DHCP. Le fait de se servir de Neighbor Solicitation permettra d'obtenir une réponse plus rapide (les routeurs ne répondent pas instantanément aux Router Solicitation).

Bien sûr, dans la réalité, tout ne se passe pas aussi bien. Simple DNA dépend de plusieurs choses, résumées par la section 2.5 : le fait que le couple {adresse MAC du routeur, adresse IP du routeur locale au lien} soit unique et le fait que les machines sont prévenues lorsque le lien physique devient fonctionnel (RFC 4957 et section 5.4 de notre RFC).

La section 4 note ensuite que la mise en œuvre complète de l'algorithme nécessite une nouvelle structure de données, la SDAT (Simple DNA Address Table). Elle va contenir la liste des routeurs déjà vus et est donc composée d'entrées indexées par le couple {adresse MAC du routeur, adresse IP du routeur locale au lien}. Elle contiendra les informations suivantes : l'information a-t-elle été obtenue par DHCP ou bien autoconfiguration sans état, adresse IP de la machine, durée de vie, préfixe utilisé, l'information a-t-elle été sécurisée par SEND, ainsi que des informations spécifiques à DHCP. Ainsi, si Simple DNA trouve qu'un réseau a déjà été visité, il a toutes les informations sous la main pour configurer immédiatement l'interface réseau.

La marche exacte à suivre de la part de la machine qui se trouve connectée est détaillée en section 5 (avec une représentation en pseudo-code en section 6). La section 5.5 décrit ainsi l'envoi des paquets de sondage (un Router Solicitation pour voir si un routeur répond, des Neighbor Solicitations pour tester les routeurs dont on se souvient, six au maximum à la fois, pour ne pas surcharger le réseau). C'est là qu'est précisé le fait que ces paquets de sondage devraient être envoyés en parallèle, pour diminuer le temps total de l'opération (et garantir ainsi que Simple DNA ne prendra jamais plus de temps qu'une méthode classique).

Le traitement des réponses est en section 5.7 : il est important que la machine vérifie que les adresses MAC correspondent bien à ce dont elle se souvient. Sinon, cela signifie que le réseau est en fait différent et qu'il faut abandonner Simple DNA pour revenir à la méthode habituelle. Naturellement, si on reçoit un Router Advertisement normal, il faut l'utiliser, quelles que soient les informations stockées dans la table SDAT.

Bien plus embêtant est le cas où les informations recueillies sont incohérentes (section 5.7.3). Par exemple, si le test d'un routeur avec le Neighbor Solicitation ne coïncide pas avec les Router Advertisement reçus. Dans ce cas, le RFC décide qu'il faut croire le Router Advertisement (sauf si SEND est utilisé). Si le conflit est entre des tests par Neighbor Solicitation et DHCP, il faut faire confiance à DHCP.

Autres recommandations, ne pas effectuer de tests de duplication d'adresses (RFC 4862, section 5.4) si on retourne à un réseau connu et ne pas insister éternellement si les Neighbor Solicitations ne ramènent pas de réponses du tout : ce cas veut sans doute dire simplement que le réseau ne marche pas.

Ah, et si on tient à faire de l'IPv4 ? La section 8 rappelle que IPv4 a aussi un système équivalent (RFC 4436) mais qui suit un algorithme très différent (IPv4 n'a pas de Router Advertisement, par exemple).

Enfin, comme avec toutes les techniques de configuration automatiques ou semi-automatiques, il y a un sérieux problème de sécurité (section 10). Les messages reçus peuvent être des faux. À part utiliser SEND (RFC 3971), il n'y a pas de solution miracle, et la seule recommandation de notre RFC est de veiller à ce que des informations non sécurisées par SEND ne remplacent pas des informations sécurisées. Autrement dit, si on avait visité un réseau qui avait un routeur SEND et, qu'en revenant sur un réseau qui semble le même, on reçoit des Router Advertisement non-SEND, il ne faut pas les utiliser. (J'ai d'ailleurs bien l'impression que, si on suit strictement les règles du RFC, on ne pourra jamais se connecter à un réseau qui avait SEND mais a choisi ensuite de l'abandonner, sauf à vider la SDAT à la main.)

Reléguée en annexe A, une dernière recommandation. Bien que le DNA de IPv4 puisse se combiner avec des adresses manuellement configurées, les problèmes que cela a soulevé (notamment pour les réseaux qui utilisaient à la fois des adresses manuelles et des automatiques) font que DNA IPv6 déconseille formellement son utilisation dans les cas où l'adresse a été fixée à la main par l'administrateur système.


Téléchargez le RFC 6059


L'article seul

RFC 6057: Comcast's Protocol-Agnostic Congestion Management System

Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : C. Bastian (Comcast), T. Klieber (Comcast), J. Livingood (Comcast), J. Mills (Comcast), R. Woundy (Comcast)
Pour information
Première rédaction de cet article le 8 Décembre 2010


Pour tout FAI, la gestion de la congestion est un problème récurrent. Même avec de très gros tuyaux, les utilisateurs, avides de profiter de leur abonnement à l'Internet (et poussés par des évolutions comme le remplacement de cours sous forme texte par des conneries multimédia genre webinar), envoient de plus en plus de paquets. Beaucoup de FAI, lors de débats sur la neutralité du réseau défendent leur droit à « gérer la congestion » par tous les moyens, même les plus inavouables. C'est ainsi que l'un des plus gros FAI états-uniens, Comcast, s'est rendu célèbre en usurpant l'adresse IP de ses propres abonnés pour couper leurs sessions BitTorrent fin 2007. Ces méthodes de cow-boys ont suscité beaucoup de protestation et, dans ce RFC, Comcast annonce un changement de cap et l'adoption d'un nouveau système de gestion de la congestion, neutre (protocol agnostic car « neutre » est un gros mot pour les FAI) et fondé sur des mesures objectives (le nombre d'octets envoyés ou reçus). Ce système est mis en œuvre dans le réseau de Comcast depuis la fin de 2008.

Comcast, qui connecte des dizaines de millions de foyers états-uniens, notamment par le câble (des détails sur leur réseau figurent en section 7), s'est donc fait allumer par la FCC au sujet de ses curieuses pratiques de gestion du réseau, qui consistaient à générer, depuis un boîtier Sandvine, des faux paquets TCP de type RST (Reset) prétendant venir des pairs, de manière à couper les sessions pair-à-pair (voir le rapport très détaillé de l'EFF ou son résumé à Ars Technica). Ce mécanisme visait, de manière complètement arbitraire, un protocole réseau particulier, BitTorrent.

La section 1 du RFC resitue le problème de la congestion. TCP est un protocole gourmand : tant qu'il n'y a pas de perte (cf. RFC 2680) de paquets, il va augmenter le débit jusqu'à ce que le réseau ne puisse plus suivre et le signale en laissant tomber certains paquets (TCP réduira alors le débit). La congestion est donc un état normal du réseau (sinon, cela veut dire qu'il est sous-utilisé).

Le mécanisme déployé étant spécifique au réseau de Comcast, il est utile, pour suivre le RFC, de bien apprendre la section 3 sur la terminologie, notamment si on n'est pas habitué aux réseaux par câble TV coaxial. Ainsi, un modem câble est le CPE, l'engin placé chez le client, et un CMTS (Cable Modem Termination System, cf. section 2.6 du RFC 3083) est l'équipement situé dans les locaux du FAI où sont connectés les clients (à peu près l'équivalent d'un DSLAM pour les FAI ADSL). Le tout fonctionne grâce à la norme DOCSIS dont les documents sont disponibles en http://www.cablelabs.com/. D'autre part, la rubrique terminologique en section 3 référence également les RFC sur la qualité de service, les RFC 1633 et RFC 2475.

Le nouveau système de contrôle de la congestion a évolué, comme le résume la section 4, en partie en suivant les débats à l'IETF comme l'atelier de 2008, qui a été documenté dans le RFC 5594. La contribution de Comcast à cet atelier consistait en un document « Service Provider Perspective ». Le système décrit par Comcast à l'occasion de cet atelier (et qui avait été également présenté dans les réponses de Comcast à la FCC, qui était mécontente du système de piratage des sessions BitTorrent) a été progressivement déployé à partir de la fin de 2008.

En quoi consiste ce système de contrôle de la congestion ? La section 5 résume ses principes. Plusieurs éléments du réseau étant partagés, le but du système est de partager « équitablement » ces éléments (le terme « équitablement » est entre guillemets dans le RFC car il n'est pas évident d'en donner une définition rigoureuse). D'autre part, le système actuel est agnostique (le RFC aurait pu dire « neutre » mais la plupart des FAI ne veulent pas entendre parler du concept de neutralité), c'est-à-dire qu'il ne cible pas un protocole particulier, il tient juste compte d'un facteur objectif : le débit de la ligne de l'abonné. L'algorithme (simplifié) est donc le suivant : le logiciel surveille en permanence l'usage des ressources réseau. Si l'une de celles-ci devient congestionnée, le logiciel regarde quel client sur cette ressource consommait plus que les autres et lui affecte une priorité plus basse. Cela n'aura pas de conséquence pratique si les lignes ont de la capacité suffisante mais, si la congestion empêche de faire passer tous les paquets, ceux de ce(s) client(s) seront retardés, voire jetés (cela peut sembler violent mais c'est le mécanisme normal d'IP pour gérer la congestion ; les protocoles de transport savent réagir à ce problème, par exemple TCP réduit automatiquement son débit). Si le client diminue son usage, sa priorité redevient normale.

Ne serait-ce pas préférable, en cas de congestion, d'augmenter la capacité du réseau ? Certes, dit la section 6, mais le problème est plus compliqué que cela. D'abord, l'ajout de capacité nécessite souvent des travaux matériels, qui prennent du temps. Ensuite, quelle que soit la capacité du réseau, il y aura des pics de trafic imprévus et aucun réseau ne peut être assez dimensionné pour éviter complètement la congestion. (De même qu'aucun autoroute ne peut être assez large pour un samedi 1er août.) Pouvoir gérer la congestion est donc une nécessité.

Quelles sont les valeurs numériques exactes utilisées pour des opérations comme « abaisser la priorité » ? L'abaisser de combien ? Et que veut dire exactement « proche de la congestion » ? 90 % 95 % ? La section 7 du RFC traite de l'implémentation concrète des principes de la section 5. Elle commence par un excellent résumé de l'architecture du réseau de Comcast, où 3 200 CMTS servent environ 15 millions d'utilisateurs. Le réseau, comme illustré dans la figure 1 du RFC, est en fait mixte, les CMTS étant connectés en fibre optique, seul le dernier mile étant en câble de cuivre coaxial. La section 7.1 définit ensuite rigoureusement la métrique utilisée pour déclarer qu'un CMTS approche de la congestion. Ensuite, la valeur numérique a été déterminée par des essais en laboratoire : aujourd'hui 70 % d'utilisation en montée et 80 % en descente pendant 5 minutes de suite. La section 7.2 traite de la seconde partie de l'algorithme : définir ce que signifie, pour un utilisateur, « consommer plus que sa part ». (Les chiffres exacts dépendent de l'abonnement qu'il a souscrit : les riches ont plus que les pauvres.)

Ce RFC n'hésite pas devant les chiffres précis. Ainsi, un exemple donné est celui d'un abonné à un service à 22 Mb/s descendants. Malgré plusieurs usages simultanés (un flux vidéo HD depuis Hulu à 2,5 Mb/s, un appel Skype à 131 kb/s, et un flux musical à 128 kb/s), il reste en dessous de la limite. L'idée est donc que beaucoup d'utilisations, même multimédia, n'amèneront pas à la limite. Lors de tests avec de vrais utilisateurs, par exemple à Colorado Springs en 2008, 22 utilisateurs sur 6 016 ont été « déprioritisés ». Lors de tels tests, quel a été le ressenti des utilisateurs ? La section 7.3 note simplement que personne ne s'est plaint.

La section 9 argumente même que ce mécanisme, prévu pour gérer la minorité la plus gourmande des utilisateurs, est aussi utile en cas de congestion plus globale. Par exemple, si une brusque épidémie de grippe se développe, forçant l'arrêt des transports publics et amenant de nombreuses entreprises à fermer, le télétravail depuis la maison va brusquement augmenter. Le réseau tiendra-t-il ? En tout cas, le même mécanisme de gestion de la congestion peut être utile.

Rien n'étant parfait en ce bas monde, quelles sont les limites de ce système ? La section 10 en cite quelques unes. Entre autres, le mécanisme de Comcast ne signale pas à l'utilisateur qu'il a été déprioritisé. Cela empêche ses applications de s'adapter (par exemple en basculant vers une résolution vidéo plus faible) et l'utilisateur de changer son comportement.

D'autres mécanismes de contrôle de la congestion pourraient apparaître plus tard, par exemple issus des travaux de l'IETF, que la section 11 résume. Des groupes de travail comme Conex (signalisation explicite de la congestion), Alto (recherche du meilleur pair dans un réseau pair-à-pair) ou Ledbat (transfert de grosses quantités de données en arrière-plan, en se glissant dans les moments où le réseau est libre) produiront peut-être des solutions meilleures.

Enfin, la section 12, sur la sécurité, est une lecture intéressante : à chaque fois qu'on construit un tel appareillage, il faut se demander s'il ne risque pas d'être mal utilisé. Ici, la principale crainte est le risque d'injection de fausses données, pour bloquer les utilisateurs (une attaque par déni de service). Les équipements de statistiques doivent donc être protégés contre un accès non autorisé. Moins grand est le risque pour la vie privée : si le trafic par modem (donc par foyer) est stocké, cela n'inclut pas les adresses IP de destination, les ports, etc.

Arrivé au terme de ce très intéressant document, très détaillé (il faut noter qu'aucun FAI dans le monde n'a fait un tel effort de documentation, comparez par exemple avec le silence complet que maintient Free face aux accusations de shaping), quel bilan tirer ? D'abord, que les protestations des clients, de l'EFF et les menaces de la FCC ont eu un effet positif. Ensuite, je pense personnellement que le système est bon dans son principe. Face à la congestion, un problème auquel peut être confronté tout réseau, quelles que soient les dimensions de ses tuyaux, il est nécessaire de prendre des mesures. Celles-ci doivent être publiquement exposées (et, on l'a dit, Comcast est le seul à le faire) et être non-discriminatoires, fondées sur des problèmes objectifs (le débit dans les tuyaux) et pas sur les intérêts financiers du FAI (comme les opérateurs 3G qui interdisent la VoIP mais qui autorisent la vidéo ; cette dernière consomme pourtant bien plus de ressources mais, elle, elle n'empiète pas sur le business traditionnel de l'opérateur...). Donc, le principe du système de gestion de la congestion de Comcast est bon. Maitenant, tout est dans l'exécution en pratique. Le système effectivement déployé est-il celui décrit ? Les évolutions futures respecteront-elles les principes posés ? Poser la question n'est pas de la paranoïa. Comcast a déjà menti, par exemple en niant la création de faux TCP resets même si la section 8 du RFC reconnait aujourd'hui leur usage (cf. RFC 3360). Le lecteur des aventures de Thursday Next pensera certainement au tome 4, « Something rotten », où la tentaculaire société Goliath tente de faire croire qu'elle est devenue une église n'agissant plus que pour le bien commun...


Téléchargez le RFC 6057


L'article seul

RFC 6056: Transport Protocol Port Randomization Recommendations

Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : M. Larsen (TietoEnator), F. Gont (UTN/FRH)
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 18 Janvier 2011


Lorsqu'un méchant attaquant tente de s'infiltrer dans une conversation en TCP, par exemple pour la couper ou la ralentir, il doit, soit être sur le trajet des paquets et pouvoir les regarder soit, dans le cas le plus fréquent, celui d'une attaque en aveugle, deviner un certain nombre d'informations qui « authentifient » la connexion TCP. Parmi celles-ci, le port source est trop souvent trop facile à deviner. Notre RFC expose pourquoi et surtout comment rendre ce port source plus dur à trouver.

De manière plus rigoureuse : lors d'une attaque en aveugle (où le méchant n'est pas en position de sniffer les paquets de la connexion TCP), les paquets mensongers injectés par le méchant ne seront acceptés par la machine victime que si le penta-tuple {Adresse IP source, Adresse IP destination, Protocole, Port Source, Post Destination} est correct (cf. RFC 5961 et RFC 5927). Pour la sécurité de TCP face à ces attaques en aveugle, il vaut donc mieux que ce tuple soit caché. Mais une partie est triviale à deviner (par exemple, pour une connexion BGP, le port de destination sera forcément 179 dans un sens et, dans l'autre, ce sera le port source). Il faut donc faire porter l'effort sur les autres parties, en essayant de les rendre le moins prévisibles possible. Une telle protection fonctionnera aussi bien avec les attaques par TCP lui-même que en passant par ICMP.

Bien sûr, cela ne remplace pas une bonne protection cryptographique des familles mais le moins qu'on puisse dire est qu'IPsec est laborieux à déployer et le but de notre RFC est de fournir une solution aujourd'hui. Il est à noter que les mécanismes de ce RFC peuvent être déployés unilatéralement et ne changent pas les protocole de transport (il n'est d'ailleurs pas spécifique à TCP ; ainsi, le DNS, protocole qui tourne surtout sur UDP, a dû déployer des techniques analogues, notamment en réponse à la faille Kaminsky ; voir le RFC 5452).

La section 1 du RFC résume ce problème (voir aussi les RFC 4953, RFC 5927 et RFC 5961). Dans un protocole client-serveur, le protocole est souvent déterminé par l'application (BGP ne peut tourner que sur TCP), le port de destination est souvent fixe (80 pour HTTP), les adresses IP des serveurs en général connues. L'adresse IP du client n'est pas en général secrète (pour BGP, les adresses IP de tous les participants à un point d'échange sont un secret de Polichinelle). Il ne reste donc que le port source pour empêcher l'attaquant de fabriquer des faux paquets qui seraient acceptés. Certes, stocké sur 16 bits, il ne peut stocker, dans le meilleur des cas, que 65 536 valeurs différentes mais c'est mieux que rien. L'idée n'est pas de fournir une protection absolue mais simplement de rendre la tâche plus pénible pour l'attaquant.

Et, justement, il existe des moyens de faire varier ce port source de manière à rendre difficile sa prédiction par l'attaquant. Cela ne vaut pas des techniques comme l'authentification TCP du RFC 5925 mais c'est déjà un progrès pour la sécurité. En dépit du titre du RFC, il ne s'agit pas de rendre le port source réellement mathématiquement aléatoire mais simplement plus dur à deviner.

Place maintenant à l'exposé des méthodes. Juste un peu de vocabulaire : une « instance » est une communication identifiée par un penta-tuple (c'est équivalent à une connexion pour les protocoles de transport à connexions comme TCP). L'« ID » d'une instance est simplement le penta-tuple {Adresse IP source, Adresse IP destination, Protocole, Port Source, Post Destination}.

Il y a port et port. La section 2 explique le concept de « port temporaire ». Pour chaque protocole (TCP, UDP ou autre), les 65 536 valeurs possibles pour les ports se répartissent en « ports bien connus » (jusqu'à 1023 inclus), « ports enregistrés » (jusqu'à 49151 inclus) et « ports dynamiques et/ou privés » (le reste). Normalement, une application de type client/serveur se connecte à un « port bien connu » (parfois à un « port enregistré ») et utilise comme port source un port temporaire pris parmi les ports dynamiques. Pour que l'ID d'instance soit unique (sinon, il ne jouerait pas son rôle), une mise en œuvre simple est d'avoir une variable par protocole, mettons next_ephemeral, qui indique le prochain port libre et est incrémentée à chaque connexion. L'algorithme est en fait un peu plus compliqué que cela (section 2.2) car il faut tenir compte des ports déjà en service, et de ceux que l'administrateur système a manuellement interdit (par exemple, dans le serveur DNS Unbound, la plage de ports à utiliser se configure avec outgoing-port-permit et outgoing-port-avoid, dans son concurrent BIND, avec use-v6-udp-ports et avoid-v6-udp-ports ; autre exemple, dans FreeBSD, la fonction in_pcblookup_local() vérifie les ports utilisés).

Mais le principal problème de cet algorithme simple est que le port source choisi pour la communication est facile à deviner. Si l'attaquant gère un serveur auquel le client se connecte, il lui suffit de regarder le port utilisé, d'ajouter un, et il saura le port utilisé pour la connexion suivante. Il pourra alors monter facilement les attaques décrites dans les RFC 4953 et RFC 5927.

Avant de trouver une solution à ce problème de prédictibilité, il faut se pencher sur le problème des collisions entre ID d'instances. Même si le client fait attention à utiliser un penta-tuple qui n'est pas en service de son côté, il peut parfaitement choisir un port source qui correspondra à un penta-tuple encore en activité de l'autre côté. En effet, l'autre côté doit garder la connexion (et donc le penta-tuple) en mémoire jusqu'à être sûr que plus aucun paquet IP n'est encore en route et, si le client est très actif (ouvre de nouvelles connexions souvent), le risque de tomber sur un penta-tuple encore en activité est élevé. Cela peut alors entraîner les problèmes décrits dans le RFC 1337. Choisir le prochain port de manière incrémentale, comme dans l'algorithme exposé plus haut, minimise le risque, puisqu'on ne réutilisera un port qu'après que toute la plage possible ait été épuisée.

Comment faire alors ? Faut-il choisir entre la sécurité qu'apportent une sélection non-linéaire du port source à utiliser et le sécurité par rapport aux collisions d'ID d'instances ? La section 3 expose plusieurs méthodes pour rendre le prochain port source plus difficile à prédire pour un attaquant. D'abord, qu'attend t-on d'un algorithme d'embrouillage du choix du port ? On voudrait à la fois qu'il rende la prédiction difficile pour l'attaquant, qu'il minimise le risque de collision d'ID, et qu'il ne marche pas sur les pieds des applications qui sont configurées pour un port précis (par exemple un serveur SSH qui écouterait sur le port 4222). Un algorithme qui assurerait la première fonction (rendre la prédiction difficile) pourrait, par exemple, être de tirer au hasard le prochain port utilisé. Mais les deux autres fonctions en souffriraient... N'imposons donc pas un vrai tirage aléatoire et voyons les compromis raisonnables. Le premier algorithme présenté, celui qui incrémente le numéro de port de un, a les problèmes inverses (il minimise la réutilisation mais maximise la prédictibilité).

On l'a vu, la plage des ports temporaires allait traditionnellement de 49152 à 65535. Mais elle est trop étroite pour assurer une vraie inprédictibilité du port source et la section 3.2 demande donc que, par défaut, la plage utilisée par les algorithmes de choix aille de 1024 à 65535. Comme cette plage inclus des ports réservés à l'IANA, l'algorithme de choix doit donc faire attention à ne pas sélectionner des ports qui sont utilisés sur la machine locale (ou qui pourraient l'être).

Place maintenant aux algorithmes effectifs. La section 3.3 décrit successivement les différents algorithmes possibles, avec du pseudo-code proche du C pour leur implémentation. L'algorithme 1, en section 3.3.1, est celui de simple tirage au hasard de la variable next_ephemeral à chaque utilisation. Si le port sélectionné n'est pas utilisable (par exemple parce qu'un serveur écoute déjà sur ce port), on essaie le suivant, puis le suivant etc. Attention, si on veut qu'il soit efficace, il faut que le générateur aléatoire le soit réellement (cf. RFC 4086). La traditionnelle fonction random(), dans la plupart des cas, ne l'est pas. Comme cet algorithme 1 n'a pas de mémoire, il peut sélectionner un port qui avait été utilisé récemment, augmentant ainsi les risques de collision des ID d'instances. En outre, il a une autre faiblesse : s'il existe une longue plage de ports déjà utilisés, et que le tirage au hasard fait tomber dans cette plage, le port situé immédiatement après la plage sera très souvent sélectionné, ce qui augmente la prévisibilité.

L'algorithme 2, en section 3.3.2, améliore l'algorithme 1 en tirant au hasard, non seulement le port initial, mais aussi l'incrément à utiliser si le port initial n'est pas libre. Il est donc le moins prévisible mais, en cas d'extrême malchance, il peut échouer à trouver un numéro de port, même s'il y en a un de libre.

L'algorithme 3 (section 3.3.3, inspiré du mécanisme décrit par Bellovin dans le RFC 6528) renonce à utiliser un générateur aléatoire et repose au contraire sur un condensat des paramètres de l'instance (adresses IP, etc). Prenons une fonction F qui reçoit les deux adresses IP, le numéro de port de l'autre partie et une clé secrète et les condensent en un nombre qui sera l'incrément appliqué à la variable next_ephemeral. En dépendant des paramètres de l'instance, on minimise la réutilisation des ID d'instances. On peut d'ailleurs ajouter d'autres paramètres comme, sur un système multi-utilisateurs, le nom de l'utilisateur. Cette fonction F doit évidemment être une fonction de hachage cryptographique comme MD5 (RFC 1321). Certes, MD5 a aujourd'hui des faiblesses cryptographiques connues mais il ne s'agit que de rendre le prochain port imprévisible, tâche pour laquelle il suffit. La clé secrète, elle, est ici pour empêcher un attaquant qui connaitrait la fonction de hachage utilisée de faire tourner le même algorithme et de prédire ainsi les numéros de port. Elle est typiquement choisie aléatoirement au démarrage de la machine.

L'algorithme 3 peut être perfectionné en ajoutant un second condensat, qui servira à indexer une table des variables next_ephemeral (au lieu d'avoir une variable unique). C'est l'algorithme 4, présenté en section 3.3.4.

Enfin, le dernier algorithme, le numéro 5 (section 3.3.5) choisit l'incrément de next_ephemeral au hasard mais l'applique ensuite de manière déterministe, ce qui limite les risques de collision d'ID puisque le numéro de port utilisé augmente à chaque fois (et repart une fois arrivé au bout). Notez le rôle du paramètre N (dont le RFC dit qu'il devrait être configurable) pour déterminer si on utilise de petits incréments (plus prévisibles mais diminuant les risques de collision) ou des grands (avec les avantages et les inconvénients renversés).

Certains de ces algorithmes dépendent d'une clé secrète, choisie au hasard. Comment choisir celle-ci ? La section 3.4 qu'elle doit être assez longue (128 bits sont recommandés). Elle suggère aussi de changer cette clé de temps en temps. Mais attention : juste après le changement, le risque de collision va augmenter.

On l'a vu, il existe plusieurs algorithmes acceptables pour atteindre notre objectif de sélection de numéros de port peu prévisibles. Lequel choisir ? La section 3.5 est une évaluation comparée desdits algorithmes, basée sur le très bon article de Mark Allman, « Comments On Selecting Ephemeral Ports », publié dans ACM Computer Communication Review, 39(2), 2009. Tous ces algorithmes évitent les collisions de manière satisfaisante (moins de 0,3 % des cas mais le chiffre exact dépend de beaucoup de choses, comme le rythme d'ouverture et de fermeture des nouvelles connexions). L'étude empirique d'Allman montre que les algorithmes 1 et 2, les seuls réellement aléatoires sont aussi, comme attendu, ceux qui montrent le plus de collisions d'ID d'instances. Les algorithmes 3 et surtout le 4 sont ceux qui imposent la plus grande consommation de ressources machines (calcul du condensat cryptographique et, pour le 4, consommation de mémoire pour la table). À noter enfin que, dans certains systèmes d'exploitation et certaines applications (celles qui appellent bind() sans indiquer de numéro de port), les algorithmes 3 et 4 ne sont pas utilisables car l'adresse IP et le port distant ne sont pas connus au moment où on sélectionne le port local et la fonction de hachage ne dispose donc pas d'assez d'arguments. Le système d'exploitation doit alors se rabattre sur un algorithme comme le 2 ou bien effectuer un bind() paresseux en retardant l'allocation effective du port local jusqu'au moment où la connexion est réellement faite (avec, par exemple, connect()). C'est par exemple ce que fait Linux. (Pour l'anecdote, ce point avait été ma contribution à ce RFC, en 2008, au début du processus d'écriture.)

De nos jours, un grand nombre de machines sont coincées derrière un routeur NAT ou plus exactement NAPT (Network Address and Port Translation, RFC 2663) qui utilise les numéros de ports pour démultiplexer le trafic entre les différentes machines du réseau local. Comme l'explique la section 4, les techniques d'obscurcissement du prochain numéro de port peuvent être alors prises en défaut si le routeur NAPT change ces ports par d'autres, choisis de manière trop prévisible. Le RFC impose donc que le routeur NAT, soit conserve les numéros de port (RFC 4787 et RFC 5382), soit choisisse lui-même les ports selon un mécanisme non prévisible.

Une fois les algorithmes exposés, compris et analysés, la section 5 reprend à nouveau de la hauteur pour parler d'une approche générale de la sécurité. D'abord, elle rappelle qu'un attaquant qui n'est pas aveugle, qui peut sniffer le réseau où passent les paquets, se moque des algorithmes exposés ici puisqu'il peut lire directement le numéro de port dans les paquets. Dans ce cas, il n'y a pas d'autre solution que des protections cryptographiques comme celles du RFC 4301.

Plus rigolo, certains choix pour la liste des ports exclus peuvent poser de sérieux problèmes de sécurité. Ainsi, si un système d'exploitation prend comme liste de ports à éviter la totalité de la liste IANA, il ne doit pas utiliser l'algorithme 1 car les ports qui se trouvent immédiatement après la liste réservée seront sur-représentés.

Comment est-ce mis en œuvre en pratique ? L'annexe A du RFC précise les choix effectués par les principaux systèmes d'exploitation libres (pour les autres, on ne sait pas s'ils sont sûrs puisqu'on ne peut pas examiner le source). Ainsi, Linux utilise l'algorithme 3, avec MD4 comme fonction de hachage (même si le RFC dit que c'est MD5). Sur un Linux 2.6 de septembre 2010, le code se trouve (de haut en bas, dans l'ordre des appels successifs), en indiquant fichier-source:fonction :

  • net/ipv4/inet_hastables.c:inet_hash_connect (qui utilise net/ipv4/inet_connection_sock.c:inet_get_local_port_range pour récupèrer auprès de sysctl les ports utilisables),
  • net/ipv4/inet_hastables.c:inet_sk_port_offset,
  • drivers/char/random.c:secure_ipv4_port_ephemeral qui fait le hachage des paramètres indiqués par l'algorithme 3 (adresses et ports).

FreeBSD, OpenBSD et OpenSolaris utilisent l'algorithme 1. La séquence des appels est (dans le HEAD du CVS de FreeBSD en octobre 2010) :

Merci à Benoit Boissinot pour son aide dans la navigation dans le source de FreeBSD.

Une petite anecdote historique pour terminer : la prédiction correcte des numéros de série des tanks allemands pendant la Seconde Guerre mondiale a permis aux Alliés de calculer le nombre de tanks ennemis. Comme quoi, toute information trop régulière et prévisible peut être exploitée par l'ennemi.


Téléchargez le RFC 6056


L'article seul

RFC 6055: IAB Thoughts on Encodings for Internationalized Domain Names

Date de publication du RFC : Février 2011
Auteur(s) du RFC : D. Thaler (Microsoft), J. Klensin, S. Cheshire (Apple)
Pour information
Première rédaction de cet article le 22 Février 2011


Ce RFC de l'IAB fait le point sur un petit problème lié aux IDN, problème qui, semble t-il, n'avait jamais été traité en détail avant. La norme actuelle (RFC 5890 et suivants) est connue sous le nom d'IDNA pour IDN in Applications car elle ne change rien au protocole et que tout le travail doit être fait dans l'application. Toutefois, «application » est un terme un peu vague. Par exemple, un programme écrit en C doit-il convertir le U-label (forme Unicode du nom) en A-label (forme ASCII) avant l'appel à la fonction de bibliothèque getaddrinfo() ? Ou bien est-ce que getaddrinfo() doit le faire seul ? (Pour les impatients, la réponse, qui arrive au terme d'un long RFC, est que l'application ne doit pas convertir en Punycode avant d'être certaine que la résolution de noms se fera avec le DNS, dans l'espace public.)

Les deux méthodes mènent en effet à des résultats différents dès qu'un autre protocole que le DNS est utilisé pour la résolution de nom. En effet, contrairement à ce qu'on lit parfois, l'appel de getaddrinfo() n'est pas un appel au DNS mais aux mécanismes de résolution de nom locaux. Par exemple, sur un système d'exploitation qui utilise la GNU libc comme Debian, le mécanisme se nomme NSS (pour Name Service Switch) et le fichier /etc/nsswitch.conf permet de le configurer. Si ce fichier contient une ligne comme :

hosts:      files ldap dns

alors, un appel à getaddrinfo() par une application qui veut récupérer l'adresse IP correspondant à un nom de domaine ne produira pas forcément une requête DNS, le nom sera peut-être trouvé dans /etc/hosts ou dans LDAP d'abord. Dans ce cas, traduire le nom en ACE (ASCII compatible encoding, c'est-à-dire traduire palais-congrès.fr en xn--palais-congrs-7gb.fr, selon le RFC 3492) serait une erreur car LDAP, par exemple, est nativement Unicode depuis le début et n'a nul besoin de l'ACE.

La section 1 du RFC rappelle la terminologie, les textes de référence (comme le RFC 2130) et les concepts, notamment la notion d'encodage. Elle rappelle aussi que des opérations aussi simples que l'égalité sont plus complexes en Unicode qu'en ASCII. Cette même section revient sur la question des API, résumée plus haut. La lecture du RFC 3490 pourrait faire croire à l'implémenteur d'IDN que la situation est simple (figure 1 du RFC) avec l'application parlant au stub resolver DNS qui parle à l'Internet. La réalité est en fait plus riche comme le montre la figure 2, avec un niveau d'indirection supplémentaire entre le sous-programme appelé par l'application (par exemple getaddrinfo(), normalisé dans le RFC 3493) et les techniques de résolution utilisées, le DNS mais aussi LLMNR (RFC 4795), Netbios (RFC 1001), /etc/hosts (RFC 952), etc.

Tiens, justement, ces API, elles prennent des noms de domaine sous quelle forme ? UTF-8 ? Punycode ? Autre ? La section 1.1 se penche sur ce problème. La description de getaddrinfo() dit juste que le nom (le paramètre nodename) est un char *, une chaîne de caractères, sans indiquer d'encodage. Les règles des chaînes de caractères en C font que l'octet nul ne peut pas en faire partie, ce qui élimine des encodages comme UTF-16 et UTF-32. En pratique, le nom passé peut être de l'ASCII (c'est le cas s'il a été traité par Punycode), de l'ISO 8859, du ISO-2022-JP (très répandu au Japon) ou de l'UTF-8. On peut noter qu'il est possible de distinguer algorithmiquement certains de ces différentes encodages avec des règles comme « Si le nom comporte un ESC, U+001B, alors, c'est de l'ISO-2022-JP, sinon si n'importe quel octet a un bit de poids fort à un, c'est de l'UTF-8, sinon, si le nom commence par xn--, c'est du Punycode, sinon enfin c'est de l'ASCII traditionnel. » Ces règles ne sont pas parfaites (celle-ci ne tient pas compte des ISO 8859, d'autre part un nom ASCII traditionnel peut théoriquement commencer par xn-- sans être un A-label) et on peut préférer des règles plus sophistiquées comme celle exposée dans « The Properties and Promizes of UTF-8 ». Quant à ISO 8859, c'est le plus ennuyeux, car il n'y a aucun moyen fiable de reconnaître un membre du jeu ISO 8859 d'un autre. Dans un texte long, des heuristiques sont possibles mais les noms de domaines sont trop courts pour fournir assez d'information pour distinguer, par exemple, ISO 8859-1 de ISO 8859-15.

Enfin, il n'y a pas que le getaddrinfo() du RFC 3493, il y a d'autres sous-programmes comme, sur Windows, GetAddrInfoW qui accepte de l'UTF-16.

Tout cela, c'était pour expliquer que des sous-programmes de résolution de noms comme getaddrinfo() ne reçoivent pas toujours assez d'information pour savoir ce qu'ils doivent faire. L'autre moitié du problème est décrit dans la section 2 : il y a d'autres protocoles de résolution que le DNS. Par exemple, la technologie privée d'Apple, Bonjour, a des noms entièrement en UTF-8 (ce qui est conforme aux recommandations du RFC 2277). Une application qui traduirait les noms Unicode en ACE empêcherait donc Bonjour de trouver la machine portant ce nom. Même chose avec les autres protocoles comme le fichier hosts (RFC 952. Ainsi, si je mets dans mon /etc/hosts sur Unix :

64.170.98.32 café-crème

je peux l'utiliser sans problème :

% ping -c 1 café-crème 
PING café-crème (64.170.98.32) 56(84) bytes of data.
64 bytes from café-crème (64.170.98.32): icmp_req=1 ttl=70 time=155 ms

--- café-crème ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 155.568/155.568/155.568/0.000 ms

Traduire trop tôt est donc une méthode déconseillée : la traduction en ACE devrait se faire bien plus tard, lorsqu'on connait le protocole de résolution employé. Et cela ne peut pas se faire dans l'application à proprement parler, puisqu'elle ne connait jamais ce protocole.

D'ailleurs, puisque des protocoles comme LDAP utilisent Unicode de bout en bout, pourquoi le DNS n'en fait-il pas autant ? La section 3 décrit ce problème (voir aussi mon article « Pourquoi avoir développé IDNA au lieu d'utiliser directement l'Unicode dans le DNS ? »). Elle rappelle que, contrairement à ce que disent souvent les ignorants, le DNS est parfaitement capable, depuis le début, de faire passer autre chose que l'ASCII, a fortiori autre chose que le sous-ensemble LDH (Letters, Digits and Hyphen) de l'ASCII. Cette erreur est tellement répandue qu'il a fallu, en 1997, consacrer une part du RFC 2181 (section 11) à tordre le coup à cette idée. Le DNS peut donc gérer des octets où le huitième bit est à un et donc, par exemple, des noms en UTF-8 (il n'est donc pas en contradiction avec le RFC 2277 qui pose comme principe que UTF-8 est l'encodage Unicode de l'Internet). Il y a des raisons techniques pour ne pas utiliser UTF-16 ou UTF-32 (présence d'octets nuls qui pertuberaient les bibliothèques écrites en C pour lesquelles c'est une marque de fin de chaîne) mais UTF-8 ne pose pas de problème. En prime, UTF-8 est un sur-ensemble d'ASCII, toute chaîne ASCII est forcément une chaîne UTF-8, ce qui fait qu'une application peut tout traiter comme de l'UTF-8, même les noms existants.

Donc, le DNS ne pose pas de restrictions ASCII ou LDH. Par contre, les applications peuvent, elles, en imposer. Ainsi, pour le Web, l'ancienne norme des URI, le RFC 2396 (remplacé depuis par le RFC 3986), limitait (dans sa section 3.2.2) le nom de machine présent dans l'URL au jeu LDH (lettres, chiffres et tiret). C'est en raison de cette limitation (présente dans d'autres protocoles) que beaucoup de registres n'autorisent que ces noms à l'enregistrement.

Si le DNS n'est pas limité à l'ASCII, pourquoi ne pas faire des IDN uniquement en mettant carrément de l'UTF-8 dans les noms ? Certes, la représentation des chaînes de caractères dans le DNS ne permet pas d'indiquer l'encodage utilisé mais, après tout, le RFC 2277 dit clairement que, sur l'Internet, en l'absence de mention contraire, tout est en UTF-8. Cette méthode a effectivement été utilisée dans certaines zones, notamment privées (non visibles depuis l'Internet public). Elle marche : l'application passe de l'UTF-8 au résolveur qui la transmet aveuglément au DNS, qui sait répondre à ces requêtes. Le principal problème de cette méthode (et qui est à peine esquissé dans notre RFC 6055) est la canonicalisation. Le fait que les requêtes DNS soient insensibles à la casse ne marche pas pour l'Unicode, où les règles sont bien plus complexes (pensons au ß allemand dont la majuscule comprend deux lettres, SS, voir le RFC 5198 pour un point de vue plus large). C'est cette absence d'une canonicalisation satisfaisante (qui affecte également les autres protocoles comme LDAP), bien plus qu'une soi-disant incapacité du DNS à gérer l'Unicode, qui explique pourquoi l'actuelle norme IDN n'utilise pas UTF-8.

Parmi les autres surprises que nous réserve la résolution de noms, la section 3 note aussi que le nom actuellement résolu n'est pas forcément celui tapé par l'utilisateur. Il est en effet fréquent que le nom tapé soit complété par des noms de domaines locaux. Par exemple, sur Unix, le fichier /etc/resolv.conf contient souvent une directive search qui indique les noms « suffixes » à essayer (voir la section 6 du RFC 1536, le RFC 3397 et la section 4 du RFC 3646 pour d'autres exemples). Si ce fichier contient search foo.example bar.example et qu'un utilisateur tape le nom de machine toto, le résolveur essaiera successivement toto.foo.example et toto.bar.example. Si foo.example et bar.example utilisaient des règles différentes (par exemple que l'un de ces domaines autorise de l'UTF-8 brut et pas l'autre), la pauvre application qui reçoit le nom toto n'aurait pas de moyen de prévoir ce qui va se passer. (Ici, toto est en ASCII. Mais si on le remplace par café ?)

La section 3.1 donne une longue liste d'exemples détaillés des comportements actuels des applications. On y voit entre autres ce qui peut se passer lorsque l'application est « trop maligne » et tente de traduire trop tôt les noms. Par exemple, l'application reçoit le nom crème, le traduit en Punycode (xn--crme-6oa) mais resolv.conf contient un nom en UTF-8, mettons café.example et le résolveur (qui ne fait pas de conversion en Unicode) va alors chercher la chaîne incohérente xn--crme-6oa.café.example !

Après toutes ses considérations, très détaillées, est-il encore possible de donner une recommandation ? Oui, et elle tient en un paragraphe dans la section 4 : « Une application qui va appeler un sous-programme de résolution de noms ne doit pas convertir le nom en Punycode si elle n'est pas absolument certaine que la résolution se fera uniquement avec le DNS public. ». En d'autres termes, l'application plus haut qui appelerait aveuglément, par exemple, le sous-programme idna_to_ascii_8z() (qui, avec la GNU libidn, convertit du jeu de caractères local vers Punycode) avant de faire un getaddrinfo() a tort.

La section 4 de notre RFC laisse une possibilité à l'application d'essayer plusieurs méthodes, comme de tenter getaddrinfo() sur le nom brut, puis sur le nom punycodé. Mais ce n'est pas obligatoire. Même recommandation pour les traductions d'adresses IP en nom : une application « intelligente » peut se préparer à recevoir de l'UTF-8 ou du Punycode et réagir proprement dans les deux cas.

Dans tous les cas, une autre recommandation importante du RFC est que les API de résolution de noms spécifient clairement l'encodage qu'elles attendent. Sur Windows, GetAddrInfoW() spécifie bien qu'il prend de l'UTF-16 alors que la norme de getaddrinfo() (le RFC 3493) n'en parle pas, faisant que la mise en œuvre de getaddrinfo sur Windows utilise la page de code Windows alors que celle de MacOS utilise UTF-8.

On peut noter que la norme IDN a été révisée récemment mais, pour les questions discutées dans ce RFC, cela n'a pas de conséquence.

Aujourd'hui, l'erreur qui consiste à traduire en ACE sans faire attention semble assez fréquente. C'est le cas par exemple d'echoping avec sa bogue #3125516.

Merci à Pascal Courtois pour sa découverte d'une bogue gênante dans ce texte (pas dans le RFC).


Téléchargez le RFC 6055


L'article seul

RFC 6053: Implementation Report for ForCES

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : E. Haleplidis (University of Patras), K. Ogawa (NTT Corporation), W. Wang (Zhejiang Gongshang University), J. Hadi Salim (Mojatatu Networks)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 8 Novembre 2010


C'est bien joli de spécifier des protocoles réseau, encore faut-il qu'ils soient implémentés. Une des raisons pour lesquels les protocoles de la famille TCP/IP ont battu à plate couture les protocoles ISO, pourtant soutenus par divers moyens bureaucratiques, est l'accent mis sur la disponibilité de programmes mettant en œuvre les spécifications, les RFC. Ces programmes permettent de vérifier que la norme est implémentable (contrairement à beaucoup de normes qui sont restés sur le papier car irréalistes) et que les différentes implémentations interopèrent. Ce RFC 6053 est le rapport décrivant trois mises en œuvre du protocole ForCES (Forwarding and Control Element Separation, un protocole de communication à l'intérieur d'un routeur, entre ses divers éléments). Il suit donc les règles et principes du RFC sur les rapports d'implémentation, le RFC 5657.

Un petit rappel d'abord. ForCES (Forwarding and Control Element Separation), normalisé dans le RFC 5810, définit un modèle (RFC 3746) où le routeur est composé de CE (Control Element) qui pilotent des FE (Forwarding Element). Les CE parlent les protocoles de routage comme OSPF, les FE font la transmission des paquets. Entre CE et FE, les messages ForCES peuvent être transmis par plusieurs protocoles, le plus utilisé (car le seul qui soit obligatoire) étant SCTP-TML (SCTP-based Transport Mapping Layer) normalisé dans le RFC 5811 et fondé sur SCTP. (Voir la section 2 pour des rappels plus complets.)

Place aux tests, maintenant. Trois mises en œuvre indépendantes ont été testées (section 3) : celle de NTT, celle de l'université de Patras, et celle de l'université de Zhejiang Gongshang (aucune des trois n'est distribuée publiquement pour l'instant). Les tests ont été globalement couronnés de succès, la plupart des bogues ont été corrigées immédiatement, les manques ayant été identifiés et les programmeurs ayant promis qu'ils les combleraient bientôt. Le test d'interopérabilité a été fait en juillet 2009. Les chinois n'étaient pas présents physiquement sur le lieu du test, ce qui a été l'occasion de tester ForCES sur une longue distance, et à travers le NAT. Outre les trois implémentations citées, le test mettait en jeu des modifications locales de deux analyseurs réseaux répandus, Wireshark et tcpdump. (Le travail sur Wireshark a été publié dans « Method and implementation of building ForCES protocol dissector based on wireshark » par Feng Luo, Ligang Dong et Fenggen Jia, à la conférence Information Management and Engineering (ICIME), 2010. Le patch se trouve dans la bogue #3534. Quant à tcpdump, la gestion de ForCES a été intégrée à partir de la 4.1.1. Vous pouvez voir des exemples en ligne.)

Comment se fait un tel test d'interopérabilité ? La section 4 résume la méthodologie suivie. Les développeurs ont d'abord rempli un questionnaire où ils devaient indiquer quelle étaient les fonctions de ForCES que leur programme gérait. Les différents programmes ont ensuite été mis l'un en face =de l'autre dans le labo et ont échangé des messages. Le bon fonctionnemement a été vérifié à la fois par les réactions des programmes et par l'examen des sniffers. Quelques raccourcis ont été pris (section 5). Par exemple, bien qu'IPsec soit obligatoire pour SCTP-TML, il n'a pas été testé, en considérant qu'IPsec était un protocole suffisamment mûr pour qu'on puisse se dispenser de le tester.

La section 6 donne tous les détails des tests, des messages testés, et de leurs résultats. Par exemple, un des tests était d'activer le heartbeat (l'envoi de messages réguliers, permettant de vérifier que le système fonctionne toujours) sur un FE (section 6.1.2.6), puis de changer l'intervalle d'émission des battements.

On l'a dit, le test a été globalement réussi. Mais il y a eu quelques petits problèmes, listés dans la section 6.2.3. Par exemple, une ambiguité est apparue dans la section 4.2.1.2 du RFC 5811 (qui n'était pas encore publié au moment du test, et qui a finalement été publié en corrigeant l'ambiguité) quant au niveau de priorité à donner à une réponse lorsque la question n'avait pas le niveau de priorité standard. Il y avait aussi de franches bogues, comme le FE et le CE attendant tous les deux une action et se bloquant mutuellement ou bien comme un mauvais calcul du champ « longueur » des messages (qui ne doit pas inclure les bits de remplissage). Il y avait aussi des problèmes qui n'étaient de la faute, ni de la norme, ni du programme mais qui reflétaient des limites de ForCES (comme la détection trop lente, dans certains cas, des coupures de la liaison entre CE et FE : SCTP-TML n'est pas forcé de réagir en temps réel à une telle coupure).

Un autre RFC sur la mise en œuvre de ForCES est le RFC 6369.


Téléchargez le RFC 6053


L'article seul

RFC 6052: IPv6 Addressing of IPv4/IPv6 Translators

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : C. Bao (CERNET Center/Tsinghua University), C. Huitema (Microsoft), M. Bagnulo (UC3M), M. Boucadair (France Telecom), X. Li (CERNET Center/Tsinghua University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 1 Novembre 2010


Il existe plusieurs mécanismes pour assurer la co-existence entre les protocoles IPv4 et IPv6. Ce RFC ne normalise pas un nouveau mécanisme mais spécifie les formats d'adresse à utiliser pour les traducteurs IPv4<->IPv6, les logiciels qui vont convertir d'un format dans l'autre. Il est donc le socle des résultats de la nouvelle version du groupe de travail IETF Behave qui, depuis l'échec de NAT-PT, essaie de normaliser une technique de traduction d'adresses permettant d'assurer la coexistence dans certains cas.

Le RFC du groupe Behave qui décrit le cadre général de cette traduction (Framework for IPv4/IPv6 Translation) est le RFC 6144. Empruntons-lui quelques exemples. Supposons par exemple un réseau purement IPv6 (hypothèse réaliste à l'heure où il ne reste plus que quelques mois d'adresses v4) et qui veut parler aux serveurs Web existants qui n'ont que v4. Un des mécanismes possibles est la traduction d'adresses. Supposons que le site Web convoité soit en 198.51.100.129. La machine purement v6 interroge un serveur DNS 64 (protocole pas encore normalisé) qui lui répond « Va voir en 64:ff9b::c633:6481 » (c633:6481 == 198.51.100.129). Elle émet alors un paquet IPv6 vers cette adresse. Sur le trajet, un traducteur d'adresses va prendre ce paquet, le traduire en v4 algorithmiquement et, lorsque la réponse reviendra, il la traduira en v6, l'envoyant à la machine cliente. Voici un exemple où une machine purement IPv6 tente de contacter Twitter, service purement IPv4 :

% telnet twitter.com 80
Trying 64:ff9b::80f2:f0f4...
Connected to twitter.com.
Escape character is '^]'.

Bien sûr, cette présentation est très sommaire mais c'est parce que le travail de spécification n'est pas encore terminé. La première étape de cette spécification est de décider des adresses utilisées et c'est ce que fait notre RFC. (Il pourrait d'ailleurs, dans le futur, être utilisé par des techniques autre que la traduction, comme l'encapsulation, cf. section 1.1.)

Un peu de vocabulaire, d'abord (section 1.3) :

  • Un traducteur d'adresse est tout dispositif qui va tripoter des adresses, qu'il ait accès aux paquets (dans ce cas, on peut l'appeler « traducteur v4/v6 » ou « traducteur IP ») ou pas (cas d'un serveur DNS 64).
  • IPv4-embedded IPv6 address, une adresse IPv6 qui contient une adresse IPv4 (comme dans l'exemple 64:ff9b::c633:6481 plus haut).
  • IPv4-converted IPv6 address, un cas particulier des précédentes,
  • IPv4-translatable IPv6 address, un autre cas particulier des IPv4-embedded IPv6 address, où l'adresse IPv6 est globalement unique et peut donc être routée dans le grand Internet.

Les traductions peuvent être sans état (stateless) ou bien avec état (stateful). Dans le premier cas, le traducteur n'a aucune mémoire. Chaque paquet est traité isolément, comme si le traducteur venait juste de démarrer. Cela permet donc de traiter une bien plus grande quantité de paquets et assure les meilleures performances et, surtout, le passage à l'échelle. Dans le second cas, celui de la traduction avec état, la traduction dépend des paquets précédents, par exemple parce que le traducteur se souvient que les paquets venant de tel port sont destinés à telle adresse. Nécessitant une table des correspondances en mémoire, la traduction avec état passe moins à l'échelle. Mais, dans certains cas, elle est la seule réaliste, puisqu'on ne peut pas stocker toutes les informations dans une seule adresse, surtout si elle est IPv4.

Armé de ces définitions, quels sont les formats d'adresses IPv4-embedded possibles ? La section 2 les liste. D'abord, un préfixe spécial a été réservé à l'IANA (cf. section 6) pour certaines de ces adresses : 64:ff9b::/96 (section 2.1). Lorsque vous verrez passer une adresse IPv6 commençant par ce préfixe, vous pouvez être sûr de voir une adresse IPv4 embarquée.

Ensuite, toutes les adresses IPv6 IPv4-embedded, qu'elles utilisent ce préfixe ou pas, suivent le même format (section 2.2) : un préfixe (64:ff9b::/96 ou bien un préfixe tiré de l'espace d'adressage de l'opérateur), l'adresse IPv4, un suffixe (parfois nul). Pour respecter la section 2.5.1 du RFC 4291, un octet nul est parfois ajouté au milieu de l'adresse IPv4. Six longueurs de préfixe sont acceptées, 32, 40, 48, 56, 64, ou 96 (cette dernière est celle qui est typiquement utilisée avec le préfixe 64:ff9b::/96). Les sections 3.3 et 3.4 expliquent quelle longueur choisir selon les cas.

Si on utilise un préfixe de longueur 48, comme l'octet qui va des bits 64 à 71 inclus doit être nul, l'adresse IPv4 est en deux parties. On a donc d'abord le préfixe IPv6, les deux premiers octets de l'adresse IPv4, un octet nul, le reste de l'adresse IPv4 et un suffixe de cinq octets. Avec un préfixe de longueur 96, tout est plus simple, le prefixe occupe les douze premiers octets, l'adresse IPv4 prend le reste (et le suffixe est absent). Le tableau 1 dans la section 2.2 résume les autres possibilités.

Une fois ce format défini, la section 2.3 décrit le (très simple) algorithme qui permet de passer d'une adresse IPv4 à une adresse IPv6 et réciproquement.

Petite question de présentation : comment afficher les adresses IPv6 IPv4-embedded ? Bien sûr en obéissant au RFC 4291 (section 2.2) et au RFC 5952. Comme le RFC 4291 permet de représenter les quatre derniers octets (et uniquement ceux-ci) sous la forme d'une adresse IPv4, l'adresse 64:ff9b::c633:6481, citée plus haut, aurait aussi pu s'écrire 64:ff9b::198.51.100.129, ce qui est certainement plus lisible.

Ensuite, comment utiliser ces adresses sur un vrai réseau ? La section 3 couvre les questions de déploiement. D'abord, le préfixe 64:ff9b::/96 ne doit être utilisé qu'avec des adresses IPv4 globalement uniques (donc, par exemple, pas avec celles du RFC 1918). Moins évident, il ne doit pas non plus être utilisé pour construire des adresses IPv6 IPv4-translatable, celles-ci devant être globalement uniques. Si tout le monde est libre de se servir de ce préfixe 64:ff9b::/96, on ne peut pas compter qu'on recevra les paquets qui lui sont adressés depuis un point quelconque de l'Internet. Son usage normal est limité à l'intérieur d'un réseau (section 3.1), autrement, il faut se servir de préfixes spécifiques d'un opérateur.

Pendant qu'on parle de ce préfixe, il faut noter que les opérateurs qui s'en servent peuvent l'annoncer dans leurs tables de routage et qu'il apparaîtra donc sur l'Internet, par exemple si un opérateur décide de fournir un service de traduction d'adresses à un autre. Mais une telle annonce devrait normalement être contrôlée (section 3.2) et ne pas être transmise à toute la DFZ. Et, normalement, ceux qui annoncent ce préfixe en BGP doivent logiquement fournir un service de traduction ensuite (ou bien ils créent un trou noir).

Quel préfixe choisir pour ses services de traduction ? La section 3.3 donne quelques conseils. Par exemple, la « meilleure » longueur est sans doute 32, car, une fois l'adresse IPv4 ajoutée, la totalité de l'information se trouve dans les bits « de routage » (les 64 premiers). Pour le routage, c'est donc la meilleure solution mais obtenir de son RIR un /32 entier uniquement pour le service de traduction d'adresses peut être dificile. Des préfixes plus longs sont donc plus raisonnables. Le RFC suggère par exemple qu'un opérateur qui a un /32 en tout consacre un /40 au service de traduction (moins de 0,5 % de son espace d'adressage). S'il s'agit d'un simple client et pas d'un opérateur, et qu'il a un /48, un /56 conviendra pour le service de traduction. Mais la valeur exacte dépend aussi du scénario de coexistence considéré.

En cas de traduction avec état (section 3.4), les choix peuvent être différents et le préfixe 64:ff9b::/96 est souvent la solution la plus intéressante.

Un des intérêts de ce RFC est la section 4, qui explique les raisons des choix faits. Ainsi, le suffixe, pour les formats où il y en avait un, aurait pu être utilisé pour stocker de l'information sur les ports (section 4.1). Cela aurait augmenté les chances de pouvoir faire une traduction sans état. Cette option n'a pas été retenue dans l'immédiat mais pourrait être ajoutée plus tard. En attendant, le suffixe a obligatoirement tous ses bits à zéro ce qui, pour le format avec préfixe /32, mène à un identificateur d'interface (les 64 derniers bits d'une adresse IPv6) entièrement nul. C'est normalement interdit (section 2.6.1 du RFC 4291) mais notre RFC explique que c'est acceptable dans le contexte limité de la traduction d'adresse.

Le choix de la valeur 64:ff9b::/96 pour le préfixe de référence est expliqué en section 4.2. D'abord, le préfixe existant pour les adresses IPv4, ::ffff:0:0/96 (section 2.5.5.2 du RFC 4291), aurait pu être réutilisé (c'était prévu dans la section 2.1 du RFC 2765). Cela aurait simplifié l'effort de normalisation. Le problème est que, justement, ce préfixe est déjà connu. Plusieurs mises en œuvre d'IPv6 le traitent à part (par exemple, Windows génère systématiquement des paquets IPv4 lorsqu'on lui présente ces adresses IPv6).

Il fallait donc allouer un nouveau préfixe. Un /32 aurait permis d'avoir tous les bits significatifs dans les 64 premiers bits mais n'aurait pas permis d'utiliser la représentation texte avec une adresse IPv4 (qui n'est possible qu'à la fin d'une adresse v6). Finalement, un préfixe /96 a été choisi. Sa valeur 64:ff9b::/96 n'a pas été tirée au hasard : elle est neutre pour le calcul de la somme de contrôle. La somme de 64 et de ff9b est ffff, ce qui est équivalent à zéro en complément à un.

Ces systèmes de traduction d'adresse posent-ils des problèmes de sécurité ? Oui, dit la section 5 qui en expose certains. Par exemple, un paquet peut mentir sur son adresse IP source, qu'il y ait traduction ou pas. En fait, note la section 5.1, un traducteur IP est comme un routeur, il a les mêmes vulnérabilités et il peut mettre en œuvre les mêmes protections. Ainsi, lorsqu'il reçoit un paquet IPv6 incluant une adresse IPv4, il peut, avant traduction, s'assurer que la machine était autorisée à utiliser cette adresse IPv4 (si le paquet vient de l'intérieur d'un réseau, c'est relativement facile). D'autres tests sont possibles comme les vérifications du chemin de retour (cf. RFC 3704).

D'autre part, lorsqu'un pare-feu teste les adresses IPv4 (section 5.2), on pourrait imaginer un attaquant qui envoie des paquets IPv6 avec adresse v4 embarquée. Le paquet v6 ne serait pas arrêté par les filtres v4 mais, après traduction, le paquet v4 pourrait faire des dégâts. Il est donc crucial que le pare-feu vérifie les adresses v4 embarquées comme si elles étaient natives.


Téléchargez le RFC 6052


L'article seul

RFC 6049: Spatial Composition of Metrics

Date de publication du RFC : Janvier 2010
Auteur(s) du RFC : A. Morton (AT&T Labs), E. Stephan (France Telecom Division R&D
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 4 Janvier 2011


Prenant la suite du RFC 5835, ce nouveau RFC du groupe de travail IPPM définit la composition spatiale des métriques, ou comment passer des mesures faites sur des parties du chemin d'un paquet à la mesure sur le chemin complet.

Déjà, le RFC 2330 spécifiait des possibilités de composition temporelle et spatiale des mesures faites sur le réseau. Le RFC 5835 définissait ensuite plus rigoureusement le cadre général des compositions de mesures. Il posait des exigences comme, par exemple, le fait qu'une fonction de composition devait spécifier si les mesures partielles étaient faites avec les mêmes paquets ou pas (cf. section 2.2). Finalement, notre RFC 6049 précise ce cadre pour les compositions dans l'espace : si un paquet se promène sur l'Internet et va de A à C en passant par B, peut-on composer deux mesures, faites de A à B et de B à C, en une mesure pour le chemin complet, de A à C ? Et, si oui, comment ?

D'abord, pourquoi cet exercice ? Juste pour le défi intellectuel ? Non, dit la section 1.1, il existe des raisons pratiques à cette composition. Les RFC qui définissent les métriques, comme le RFC 2679 sur le délai d'acheminement d'un paquet ou bien le RFC 2680 sur le taux de pertes de paquets tiennent pour acquis qu'on a un accès complet à la source et à la destination et qu'on peut donc effectuer une mesure de bout en bout. Mais, parfois, ce n'est pas possible, par exemple parce que le chemin franchit une frontière administrative, et on n'a parfois que la possibilité de mesurer des sous-chemins (comme dans l'exemple de A à C ci-dessus). La composition spatiale devient alors un moyen de calculer la mesure sur le chemin complet.

Dans le futur, on pourrait même imaginer d'autres possibilités comme, dans le cas où on n'a pas de mesure pour un des sous-chemins, de calculer la valeur à partir de la mesure du chemin complet et des mesures sur les autres sous-chemins (« soustraction » et non plus « addition »). Mais cette possibilité n'est pas encore définie par le RFC (cf. section 2.1 et 2.3, qui pose que, pour l'instant, si la mesure n'a pas été faite sur un des sous-chemins, c'est le résultat entier qui est indéfini).

Pour définir les compositions elles-mêmes, le RFC procède en deux temps. La section 3 définit les paramètres communs à toutes les métriques et les sections suivantes définissent les paramètres spécifiques aux trois métriques retenues, le délai d'acheminement, le taux de pertes et la variation du délai.

Parmi les paramètres génériques, on peut citer par exemple (section 3.1.8), les causes possibles de déviation par rapport à la vérité de base (section 3.7) du RFC 5835. Ainsi, lorsqu'on mesure sur une partie du chemin, rien ne garantit que les paquets suivront le même chemin que si on mesure sur le chemin complet, en raison, entre autres, de l'ECMP. Sans compter le fait que, si les mesures ne se font pas au même moment, le routage a pu changer entre la mesure d'un sous-chemin et celle du chemin complet.

Les trois métriques spécifiques suivent cet exposé des paramètres génériques. La première est le délai d'acheminement (RFC 2679). D'abord, avant de composer de tels délais, la section 4.1 définit la notion de Type-P-Finite-One-way-Delay-<Sample>-Stream qui est une réduction d'une série de mesures, excluant celles où le paquet n'est pas arrivé (cela permettra de calculer des choses comme la moyenne). Cette façon de simplifier le problème est analogue à celle du RFC 3393 et est également utilisée dans la Recommandation UIT Y.1540, « Internet protocol data communication service - IP packet transfer and availability performance parameters ».

Armé de cette nouvelle définition, on peut s'attaquer à celle de Type-P-Finite-One-way-Delay-Mean (section 4.2). Informellement, c'est simplement la moyenne des délais. Et, finalement, on en arrive à la fonction composée, Type-P-Finite-Composite-One-way-Delay-Mean, qui est simplement la somme des moyennes des délais, somme prise sur tous les sous-chemins. Pour prendre un exemple trivial, si un paquet met en moyenne 0,12 ms pour aller de A à B et 0,05 ms pour aller de A à C, alors la Type-P-Finite-Composite-One-way-Delay-Mean sur le chemin de A à C (s'il passe par B, bien sûr), sera de 0,17 ms. Naturellement, cela suppose que le nombre de paquets utilisé pour calculer la moyenne sur chaque sous-chemin soit suffisant pour qu'on ait une valeur représentative. Il y a aussi d'autres conditions : par exemple, si la distribution des paquets sur un sous-chemin est multi-modale, la moyenne ne voudra pas dire grand'chose.

Comme on a défini une moyenne, on peut définir un minimum (section 4.3). Type-P-Finite-Composite-One-way-Delay-Minimum est la somme des délais minimaux d'acheminement sur chaque sous-chemin. Si on a fait trois tests et que le trajet de A à B a pris 0,12, puis 0,16 puis enfin 0,1 ms, et que celui de B à C a pris 0,05 ms à chaque fois, le Type-P-Finite-Composite-One-way-Delay-Minimum vaut 0,1 + 0,05 = 0,15 ms. On voit que cela suppose que les délais des sous-chemins sont indépendants, ce qui est raisonnable.

Cela, c'était pour le délai d'acheminement, pour lequel on a défini deux fonctions de composition, pour la moyenne et pour le minimum. La section 5 passe au taux de pertes de paquet. En partant de la définition de la perte Type-P-One-way-Packet-Loss du RFC 2680, on peut définir une probabilité de pertes, Type-P-One-way-Packet-Loss-Empirical-Probability puis une composition de cette probabilité, Type-P-Composite-One-way-Packet-Loss-Empirical-Probability. La définition est un peu plus compliquée que pour les compositions précédentes mais, de manière résumée, la probabilité de survie sur le chemin complet est le produit des probabilités de survie sur chaque sous-chemin. Comme la probabilité de perte est 1 - la probabilité de survie, le calcul est facile à faire.

Toutes ces métriques (je n'ai pas détaillé la troisième, présentée en section 6) ont été enregistrées dans la MIB qui sert de registre des métriques (cf. RFC 4148).


Téléchargez le RFC 6049


L'article seul

RFC 6045: Real-time Inter-network Defense

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : Kathleen M. Moriarty (EMC)
Intérêt historique uniquement
Première rédaction de cet article le 8 Novembre 2010


La sécurité, face aux innombrables attaques que connaissent les réseaux tous les jours, nécessite un échange d'information permanent. Ce RFC normalise donc un format permettant d'échanger et de traiter ce genre d'informations (depuis mis à jour dans le RFC 6545). Il sera donc peut-être un outil technique utile pour les CSIRT et les opérateurs.

La section 1 résume les problèmes de la sécurité des réseaux auxquels les opérateurs font face. Une fois l'attaque détectée, que ce soit un hameçonnage, une DoS ou une pénétration réussie dans un système connecté au réseau, il faut rédiger un rapport, transmettre à l'opérateur d'origine de l'attaque, demander à un opérateur amont de prendre des mesures pour limiter les dégâts, demander de continuer l'enquête en suivant la trace de l'attaquant, etc. Par exemple, si on veut suivre une trace de paquets dont l'adresse IP source est mensongère, et que le filtrage recommandé par le RFC 2827 n'est pas en place, il faut repérer par quel câble sont entrés ces paquets et envoyer ensuite à l'opérateur situé derrière une demande de continuation de l'enquête. Il n'y a pas de mécanisme formel pour cela. Ça se fait typiquement par téléphone ou par envoi d'un courrier en langue naturelle, ce qui augmente les coûts de traitement.

Le nouveau format, normalisé dans ce RFC 6045 (puis dans le RFC 6545, qui lui a succédé), se nomme RID pour Real-time Inter-network Defense et se base sur le format IODEF du RFC 5070, qui lui-même utilise XML. L'apport par rapport à l'IODEF de base est de cibler la circulation d'informations en « temps réel ». RID vise donc à permettre la réponse immédiate à une attaque. Par exemple, lorsqu'une dDoS est perpétrée par un botnet, il faut certes retrouver les zombies mais aussi identifier le contrôleur qui les commande. RID permet de demander un suivi de la trace des premiers, puis ensuite du second.

La section 2 traite de l'intégration aux systèmes existants. L'opérateur a typiquement un système de gestion centralisé de son réseau, un NMS. Le futur IHS (Incident Handling System) qui recevra et enverra les messages RID devra être intégré à ce NMS. La détection de l'attaque pourra se faire manuellement, ou via un IDS mais cette question est hors-sujet pour RID, qui se contente de permettre le signalement d'attaques, une fois celles-ci détectées.

Quelles sont les obstacles que rencontrent les tentatives de remonter à la source d'une attaque ? La section 3 en donne une liste, et c'est une lecture très recommandée pour comprendre la variété des problèmes auxquels fait face l'opérateur réseau lors d'une attaque. Par exemple, certaines attaques utilisent tellement peu de paquets qu'il est difficile de les répérer. D'autre part, pour prendre rapidement une « empreinte » des paquets utilisés pour l'attaque, les techniques à base d'une fonction de hachage ont souvent été utilisées (cf. « Hash-Based IP Traceback »). Or, certaines attaques ont un contenu des paquets qui varie énormément et il est difficile de trouver une « signature » qui permettrait de dire à l'opérateur précédent « Voici ce que je cherche ». Les nombreuses techniques de traceback pour IP ont été utilisées pour déterminer quelles étaient les informations importantes à inclure dans RID. Ainsi, il est essentiel d'inclure beaucoup d'informations dans le message RID car les champs significatifs et l'attaque, permettant de repérer les paquets, peuvent être n'importe lesquels. RID permet même d'envoyer la totalité du paquet, si nécessaire (section 3.2).

Une fois que le message RID est prêt, que fait-on pour la communication avec les autres opérateurs et avec les CSIRT ? Les sections 4.1 et 4.2 font remarquer que le courrier électronique n'est pas forcément adapté car il peut être trop lent. Mais, de toute façon, il faut prévoir plusieurs canaux de communication car, en cas d'attaque, certains deviendront peut-être inutilisables. Un réseau distinct de celui utilisé pour le trafic « normal » peut donc être nécessaire (voir plus loin le commentaire de la section 6). Le RFC suggère qu'on peut profiter des négociations qui précèdent un accord de peering pour mettre en place un canal de communication sécurisé.

Recommandation utile ou vœu pieux ? En tout cas, la section 4.2 rappelle également que RID ne devrait être utilisé que pour lutter contre des attaques, et pas pour perpétuer des sabotages (en dénonçant un innocent dans l'espoir qu'il se fasse filtrer) ou pour censurer.

Maintenant, place au format utilisé (section 4.3), fondé sur IODEF (RFC 5070). Il y a six messages RID possibles :

  • TraceRequest où on demande à un partenaire d'examiner son réseau pour voir d'où venait l'attaque (l'idée est que, partant de celui qui a détecté l'attaque, on envoit des Tracerequest successifs en remontant peu à peu vers la source de l'attaque).
  • Investigation où on demande une enquête mais pas un traçage de l'attaque, car le demandeur pense avoir déjà identifié la source.
  • Report où on transmet de l'information, sans demander d'action immédiate.
  • IncidentQuery où on demande des détails sur une attaque dont on a entendu parler (les deux derniers types de message sont typiquement pour la communication avec un CSIRT).
  • RequestAuthorization et Result servent à porter les résultats intermédiaires ou finaux.

La section 4.4 décrit plus en détail chacun de ces types.

La section 4.5 fournit plusieurs jolis exemples, que j'ai simplifié ici. Par exemple, une TraceRequest envoyé par un CSIRT qui a détecté une DoS et qui demande à un opérateur réseau de tracer l'attaque. Le message est composé d'un document RID puis du document IODEF qui décrit l'attaque :


<iodef-rid:RID> <!-- Le schéma est enregistré en
http://www.iana.org/assignments/xml-registry/ns.html -->
  <iodef-rid:RIDPolicy MsgType="TraceRequest" 
                       MsgDestination="RIDSystem">
    <iodef:Node>
      <iodef:Address category="ipv4-addr">192.0.2.3</iodef:Address>
    </iodef:Node>
    <iodef-rid:TrafficType type="Attack"/>
    <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN">
      CERT-FOR-OUR-DOMAIN#207-1
    </iodef:IncidentID>
  </iodef-rid:RIDPolicy>
</iodef-rid:RID>
<!-- IODEF-Document accompanied by the above RID -->
<iodef:IODEF-Document>
  <iodef:Incident restriction="need-to-know" purpose="traceback">
    <iodef:DetectTime>2004-02-02T22:49:24+00:00</iodef:DetectTime>
    <iodef:StartTime>2004-02-02T22:19:24+00:00</iodef:StartTime>
    <iodef:ReportTime>2004-02-02T23:20:24+00:00</iodef:ReportTime>
    <iodef:Description>Host involved in DOS attack</iodef:Description>
    <iodef:EventData>
      <iodef:Flow>
        <iodef:System category="source">
          <iodef:Node>
            <iodef:Address category="ipv4-addr">192.0.2.35
...

Et la première réponse, qui indique que la demande de traçage a été approuvée :


<iodef-rid:RID>
  <iodef-rid:RIDPolicy MsgType="RequestAuthorization"
                       MsgDestination="RIDSystem">
    <iodef-rid:TrafficType type="Attack"/>
  </iodef-rid:RIDPolicy>
  <iodef-rid:RequestStatus AuthorizationStatus="Approved"/>
</iodef-rid:RID>

Et enfin la réponse finale :


<iodef-rid:RID>
  <iodef-rid:RIDPolicy MsgType="Result"
                       MsgDestination="RIDSystem">
    <iodef:Node>
      <iodef:Address category="ipv4-addr">192.0.2.67</iodef:Address>
    </iodef:Node>
    <iodef-rid:TrafficType type="Attack"/>
    <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN">
      CERT-FOR-OUR-DOMAIN#207-1
    </iodef:IncidentID>
  </iodef-rid:RIDPolicy>
  <iodef-rid:IncidentSource>
    <iodef-rid:SourceFound>true</iodef-rid:SourceFound>
    <iodef:Node>
      <iodef:Address category="ipv4-addr">192.0.2.37</iodef:Address>
    </iodef:Node>
  </iodef-rid:IncidentSource>
</iodef-rid:RID>
<!-- IODEF-Document accompanied by the above RID -->
<iodef:IODEF-Document>
  <iodef:Incident restriction="need-to-know" purpose="traceback">
    <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN">
      CERT-FOR-OUR-DOMAIN#207-1
    </iodef:IncidentID>
    <iodef:DetectTime>2004-02-02T22:49:24+00:00</iodef:DetectTime>
    <iodef:StartTime>2004-02-02T22:19:24+00:00</iodef:StartTime>
...
      <iodef:Expectation severity="high" action="rate-limit-host">
        <iodef:Description>
          Rate limit traffic close to source
        </iodef:Description>
      </iodef:Expectation>
      <iodef:Record>
        <iodef:RecordData>
          <iodef:Description>
            The IPv4 packet included was used in the described attack
          </iodef:Description>
          <iodef:RecordItem dtype="ipv4-packet">450000522ad9
          0000ff06c41fc0a801020a010102976d0050103e020810d9
          4a1350021000ad6700005468616e6b20796f7520666f7220
          6361726566756c6c792072656164696e6720746869732052
          46432e0a
          </iodef:RecordItem>
        </iodef:RecordData>
      </iodef:Record>
    </iodef:EventData>
    <iodef:History>
      <iodef:HistoryItem>
        <iodef:DateTime>2004-02-02T22:53:01+00:00</iodef:DateTime>
        <iodef:IncidentID name="CSIRT-FOR-OUR-DOMAIN">
          CSIRT-FOR-OUR-DOMAIN#207-1
        </iodef:IncidentID>
        <iodef:Description>
          Notification sent to next upstream NP closer to 192.0.2.35
        </iodef:Description>
      </iodef:HistoryItem>
      <iodef:HistoryItem action="rate-limit-host">
        <iodef:DateTime>2004-02-02T23:07:21+00:00</iodef:DateTime>
        <iodef:IncidentID name="CSIRT-FOR-NP3">
          CSIRT-FOR-NP3#3291-1
        </iodef:IncidentID>
        <iodef:Description>
          Host rate limited for 24 hours
        </iodef:Description>
      </iodef:HistoryItem>
    </iodef:History>
  </iodef:Incident>
</iodef:IODEF-Document>

L'entiéreté du schéma XML, en xsd, figure en section 5.

Comme déjà noté, l'utilisation de ces messages RID ne va pas sans risques. La section 6 les analyse. D'abord, il faut évidemment un canal sécurisé pour les transmettre. Sécurisé au sens de :

  • Confidentiel, puisque les informations RID peuvent être très sensibles,
  • Fiable (disponible), puisque l'attaque rendra peut-être inutilisable les canaux normaux,
  • Authentifié, parce que ceux à qui on demande d'agir sur la base de messages RID voudront savoir à qui ils ont affaire.

Un canal physique dédié faciliterait l'obtention de ces propriétés mais n'est pas forcément réaliste. Le RFC recommande donc plutôt un tunnel chiffré. En combinant TLS sur le tunnel et les signatures XML du RFC 3275 sur le message, on atteint la sécurité désirée. Le protocole exact utilisé est normalisé dans un autre document, le RFC 6046. Bien qu'il utilise le chiffrement, RID ne repose pas uniquement sur la sécurité du canal et permet de chiffrer aussi le message par le chiffrement XML.

RID soulève aussi des questions liées à la protection de la vie privée et la section 6.6 les étudie. RID fournit le moyen de spécifier des détails comme l'extension du « domaine de confiance » à qui on peut envoyer les informations (élément PolicyRegion, section 4.3.3.3).


Téléchargez le RFC 6045


L'article seul

RFC 6041: ForCES Applicability Statement

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : A. Crouch, H. Khosravi (Intel), A. Doria (LTU), X. Wang (Huawei), K. Ogawa (NTT Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 30 Octobre 2010


Le protocole ForCES (Forwarding and Control Element Separation), décrit dans le RFC 5810, normalise la communication entre les différents éléments d'un routeur, de façon à permettre la création d'un routeur par l'assemblage de composants venus de constructeurs différents. Ce RFC 6041 se focalise sur l'applicabilité de ForCES, à savoir dans quels cas ce protocole est applicable et ce qu'on peut exactement lui demander. Ce RFC peut donc servir d'introduction de haut niveau à ForCES.

ForCES considère un routeur comme composé d'un élément de contrôle, qui parle les protocoles de routage comme OSPF, c'est le CE (Control Engine), et d'un ou plusieurs éléments qui transmettent effectivement les paquets, les FE (Forwarding Engine). ForCES est le mécanisme par lequel le CE communique avec ses FE. Outre le protocole lui-même, dans le RFC 5810, ForCES a aussi un modèle de données (RFC 5812) et un protocole de transport (RFC 5811). Dans quels cas peut-on les employer et, inversement, quand sont-ils inapplicables ? La section 4 forme le cœur du RFC et c'est surtout elle qui est résumée ici.

D'abord, ForCES est prévu pour des routeurs assez gros pour que les fonctions de contrôle et de transmission soient séparées. Sur un engin bas de gamme, où tout tient dans le même circuit, ForCES n'est sans doute pas utile. Par contre, les routeurs du milieu et du haut de gamme ont déjà une séparation physique entre le mécanisme de contrôle et les mécanismes de traitement des interfaces réseaux. Comme ce CE et ces FE doivent communiquer (par exemple, si le CE apprend par OSPF qu'une route pour 192.0.2.192/26 passe par l'interface ge-0-1, il doit communiquer cette information au FE qui gère cette interface, mais aussi à tous les autres pour qu'ils lui transmettent ce trafic). Les routeurs ont donc tous un protocole de communication entre CE et FE mais il est toujours privé (un des rares qui soit documenté est le Netlink de Linux, dans le RFC 3549). Avec ForCES, se profile la possibilité d'un protocole standard pour les remplacer.

Quels services, dans cette communication entre FE et CE, peuvent être assurés par ForCES ? Notons bien (section 4.1) que ForCES ne traite pas de la découverte par le CE de ses FE, découverte qui doit être assurée autrement. En revanche, une fois celle-ci effectuée, ForCES pilote l'association entre CE et FE, et la transmission des informations comme, par exemple, le nombre de ports réseaux que gère le FE. Le CE peut ensuite configurer le FE (par exemple en lui indiquant les adresses IP locales, qui doivent être transmises au CE), comme indiqué en section 4.1.3.

Mais le principal service assuré par ForCES est évidemment l'envoi d'informations de routage (section 4.1.4). Un CE transmet à ses FE les adresses IP à router, de façon à ce que les paquets soient transmis à la bonne interface réseau.

La section 4.1 note de nombreux autres services. Citons-en juste un : l'envoi par le CE de règles de filtrage (quels paquets abandonner, et sur quels critères), en section 4.1.7.

De quoi a besoin ForCES pour rendre ces services, et qui n'est pas forcément présent sur tous les routeurs ? De capacité réseau (section 4.2). Entre le CE et le FE, la capacité n'est pas infinie et des opérations comme l'envoi d'une table de routage complète peuvent être non-triviales sur un réseau d'interconnexion lent, d'autant plus que ForCES se veut utilisable pour des futures tables de routage, plus grandes que celle d'aujourd'hui (fin octobre 2010, il y a 340 000 entrées dans la table de routage BGP globale).

Cette question de la capacité en amène une autre, celle de la localité. ForCES sépare logiquement le CE et le FE. Peuvent-ils aussi être séparés physiquement, et mis dans des boîtes différentes ? La section 4.3 examine la question. Le principe est que la disponibilité du routeur ne devrait pas être affectée par la séparation du contrôle et de la transmission. La connexion entre le FE et le CE est doit donc être un bus très fiable, ou en tout cas aussi fiable que le CE, de façon à partager son sort. En pratique, cela veut dire que ForCES est utilisable sans problème pour les NE (Network Element, typiquement un routeur) où tout tient dans une seule boîte, avec des lames différentes pour le CE et les FE, mais un seul châssis et une interconnexion en Ethernet, PCI, etc (le cas de la majorité des routeurs actuels). Une telle configuration simplifiera notamment les problèmes de sécurité (cf. section 5). Mais ForCES peut aussi marcher dans des cas où CE et FE sont situés dans des boîtiers séparés.

Pas de protocole réaliste sans possibilité de gestion. La section 6 détaille le comportement de ForCES face aux exigences de la gestion du réseau. Le point important est que, quel que soit le degré de séparation entre CE et FE, ForCES permet de voir le routeur comme un élément unique. Cela se réalise en faisant passer l'essentiel des fonctions de gestion à travers le CE. Notre RFC recommande ainsi que tous les messages SNMP soient transmis au CE (par exemple en utilisant les mécanismes du RFC 2741). Ceux qui vont quand même directement traités par les FE doivent, ou bien être en lecture seule, ou bien permettre une notification du CE, afin que celui-ci reste seul maître. ForCES dispose d'une MIB, décrite dans le RFC 5813, qui permet d'accéder à des informations comme les associations entre le CE et les FE.


Téléchargez le RFC 6041


L'article seul

RFC 6039: Issues with existing Cryptographic Protection Methods for Routing Protocols

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : Vishwas Manral (IP Infusion), Manav Bhatia (Alcatel-Lucent), Joel Jaeggli (Checkpoint Software), Russ White (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 24 Octobre 2010


Le groupe de travail IETF opsec travaille à améliorer la sécurité des protocole de routage. Ce RFC du groupe (l'un des premiers, après les très intéressants RFC 4778 et RFC 5635) fait le point sur l'utilisation actuelle de la cryptographie dans ces protocoles et ses limites, les problèmes qu'elle soulève, notamment de gestion des clés.

Plusieurs protocoles de routage ont des mécanismes standards pour protéger par la cryptographie les informations transmises. OSPF v2 (RFC 2328), OSPF v3 (RFC 5340), IS-IS (RFC 1195), BGP (RFC 4271), ou des protocoles qui, sans être à proprement parler « de routage », en sont néanmoins proches comme BFD (RFC 5880), sont tous capables de prendre un condensat cryptographique de l'information transmise, en utilisant une fonction de hachage comme MD5 (RFC 1321) et une clé secrète. Le routeur récepteur, s'il a la même clé secrète, peut refaire le calcul du condensat et, s'il trouve la même valeur, être rassuré que le message vient bien d'un routeur autorisé, et qu'il n'a pas été modifié en route. (On notera que l'utilisation de protocoles à clés publiques est infiniment plus rare, au point d'être à peine mentionné dans le RFC.)

Notons que ces protocoles n'assurent pas de service de confidentialité : un méchant qui espionne la communication entre deux routeurs peut toujours apprendre les routes échangées.

Comme le note la section 1 du RFC, qui étudie les problèmes génériques, communs à tous les protocoles de routage, cette approche a des limites : l'utilisation de clés secrètes partagées entraine une gestion manuelle des clés, plutôt pénible. Remplacer une clé compromise est ainsi une opération longue et risquée (il est facile d'oublier un routeur, ce qui cassera les communication entre les routeurs ayant la nouvelle clé et les autres). D'autre part, plusieurs cas existent où les attaques par rejeu sont possibles.

Comme le note la section 1.1, la fonction de hachage la plus couramment utilisée est MD5. Celle-ci n'est pas sans reproche, cryptographiquement parlant. Des attaques par collision (trouver deux messages qui ont le même condensat cryptographique) ont déjà été publiées par exemple par Xiaoyun Wang, Xuejia Lai, Dengguo Feng & Hongbo Yu, dans « Collisions for hash functions MD4, MD5, HAVAL-128, and RIPEMD », Crypto 2004 Rump Session. En revanche, des attaques dites « pré-image » (où on produit un message qui a le même condensat qu'un message donné, ce qui est beaucoup plus difficile qu'une attaque par collision) ne semblent pas avoir été publiées. Pour le cas particulier des protocoles de routage, les collisions ne sont pas trop à craindre car beaucoup de champs dans un message ne peuvent pas prendre des valeurs arbitraires (par exemple, dans OSPF le champ « Link State Advertisement function code - section A.4.2.1 du RFC 5340 - peut valoir seulement de 1 à 14). Pour les attaques pré-image, elle seraient sans doute plus graves, mais la taille relativement limitée des messages de routage limite sans doute les risques d'exploitation effective.

SHA-1 a aussi ses faiblesses (section 1.2) mais il faut bien voir qu'elles ne sont pas réellement utilisables pour une attaque, dans les conditions spécifiques des protocoles de routage (cf. RFC 4270 pour un bon arrière-plan sur la question.)

Les sections suivantes détaillent ensuite les problèmes pour le cas spécifique de chaque protocole. À chaque fois, sont indiqués les problèmes d'ordre pratique (gestion des clés) et ceux d'ordre technique (faiblesses dans le protocole). OSPF v2 fait l'objet de la section 2. Les routeurs OSPF d'un même réseau peuvent s'authentifier en condensant les paquets et une clé secrète avec MD5 (RFC 2328, annexe D.3). Cette clé se configure avec :

interface eth0
  ip ospf authentication message-digest
  ip ospf message-digest-key 1 md5 MACLESECRETE

sur Quagga et avec :

authentication-type md5;
	interface fe-0/0/1.0 {
	     authentication {
	         md5 1 key "$9$dEbgoZUjqP5GUApO1hcgoaJHq"; MACLESECRETE 
	     }
	}

sur JunOS. Il existe aussi un mécanisme expérimental de signature des messages par des clés asymétriques (RFC 2154) mais qui n'a apparemment jamais été déployé.

Le condensat cryptographique s'applique aux messages échangés entre routeurs, pas à l'information de routage elle-même. Autrement dit, MD5 dans OSPF sécurise le canal mais pas le message (le LSA). OSPF ne fournit aucun mécanisme de négociation de paramètres comme l'algorithme de hachage utilisé. Si on veut utiliser SHA (RFC 5709), tous les routeurs d'un même lien doivent être manuellement configurés de manière identique. D'une manière générale, tout changement dans les clés doit faire l'objet d'une prudente intervention planifiée et manuellement exécutée.

L'authentification cryptographique dans OSPF a aussi des problèmes techniques (section 2.2) comme le fait que la même clé soit utilisé pour tous les routeurs d'un même réseau Ethernet, obligeant à largement partager le secret.

Pour OSPF v3 (RFC 5340 et section 3), encore peu déployé, la situation est toute différente. Il n'a pas de mécanisme d'authentification intrinsèque et ses utilisateurs sont censés s'appuyer sur IPsec (par exemple RFC 4303, sans chiffrement, comme spécifié dans le RFC 2410, pour avoir juste la signature). La norme de sécurité d'OSPF v3 (RFC 4552) précise que les clés IPsec doivent être gérées manuellement, pas avec un protocole comme IKE parce que le modèle de fonctionnement d'OSPF (un-vers-plusieurs) est très particulier.

Même si le RFC n'en dit pas un mot, le principal problème d'OSPF v3, aussi bien technique que pratique, est qu'IPsec est très peu déployé et que peu d'administrateurs réseaux ont envie de s'y mettre pour assurer une fonction qui, en OSPF v2, ne prenait que deux lignes de configuration.

Et le concurrent d'OSPF, IS-IS (RFC 1195 et section 4 de notre RFC) ? Lui aussi peut utiliser MD5 pour l'authentification (voir RFC 5304). Mais, contrairement à OSPF, la signature porte sur l'annonce d'état d'un lien, pas sur un message échangé entre deux routeurs. Cela veut dire qu'on peut authentifier un routeur distant, mais cela oblige (section 4.1) tous les routeurs à avoir la même clé... Comme OSPF, pas moyen de négocier la clé, ou l'algorithme de condensation. Si on veut remplacer MD5 par SHA-256, un gros travail de gestion est à prévoir.

Faut-il également parler de l'antédiluvien RIP ? La section 6 lui consacre quelques paragraphes. La version historique, dans le RFC 1058, avait zéro service de sécurité. La version 2, actuellement normalisée dans le RFC 2453, et dispose désormais d'un mécanisme d'authentification analogue à ceux des autres protocoles (cf. RFC 4822).

Bien que n'étant pas un protocole de routage, BFD (RFC 5880) est tellement souvent utilisé dans les routeurs qu'il mérite sa section de ce RFC, la 7. BFD sert à détecter la panne d'une liaison. Il dispose d'un mécanisme d'authentification optionnel (sections 4.2 et 6.7 du RFC 5880), à clés partagées. Il hérite donc des problèmes de gestion de clés de ce système.

Et BGP, vedette des protocoles utilisés sur l'Internet, puisque c'est lui qui assure le routage entre opérateurs ? La section 5 détaille ce protocole. BGP est forcément transporté sur TCP. Il peut donc utiliser les options d'authentification de TCP comme celle du RFC 2385 (très répandue en pratique dans le monde BGP) ou bien celle du RFC 5925, plus récente, bien meilleure et plus rare en pratique. Pour cette raison, notre RFC 6039 ne couvre que l'authentification MD5 du RFC 2385. Parmi les problèmes de gestion, il y a le fait que BGP est typiquement utilisé de part et d'autre d'une frontière administrative. Cela complique sérieusement les opérations de gestion de clés. Par exemple, quand avez-vous pour la dernière fois changé un mot de passe MD5 sur une session BGP avec un pair ? (Réponse : vous ne l'avez probablement jamais fait.) Sur un gros point d'échange, un routeur BGP peut se connecter à des dizaines, voire des centaines de pairs, et la gestion des « mots de passe MD5 » pour tous ces pairs est un défi. En général, on ne complique pas ce défi en essayant de suivre des bonnes pratiques, comme le changement des mots de passe...

Et les problèmes techniques de BGP ? Comme il utilise TCP, il profite de ses mécanismes de sécurité (comme les numéros de séquence qui protègent des rejeux) et il hérite de ses faiblesses (voir l'excellent exposé de Convery & Franz à Black Hat, « BGP Vulnerability Testing: Separating Fact from FUD », un modèle pour toute analyse de la sécurité). À plusieurs reprises, les fabricants de routeurs BGP ont dû mettre à jour leur logiciel pour traiter ces vulnérabilités.

À noter que le RFC ne mentionne pas du tout ce qui est probablement la plus grosse faiblesse de sécurité de BGP : le fait qu'on puisse authentifier le voisin, mais pas l'information qu'il envoie (ou relaie). Savoir que c'est bien mon pair 2001:db8:face:b00c::1 avec qui je parle, c'est très bien mais, lorsqu'il annonce une route vers 2001:db8:137::/48, comment savoir s'il a le droit de le faire ou bien si Pakistan Telecom a fait mumuse ? Il n'existe pour l'instant aucun protocole standard pour cela.


Téléchargez le RFC 6039


L'article seul

RFC 6038: TWAMP Reflect Octets and Symmetrical Size Features

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : A. Morton, L. Ciavattone (AT&T Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 11 Octobre 2010


Voici deux petites extensions au protocole de mesure active TWAMP. L'une permet de demander le renvoi d'octets choisis par le client. L'autre permet de garantir l'usage de paquets de même taille dans les deux directions.

L'IETF a deux protocoles de mesure active, OWAMP (One-way Active Measurement Protocol, RFC 4656, unidirectionnel, et TWAMP (Two-Way Active Measurement Protocol, RFC 5357), bidirectionnel. Avec TWAMP, un client peut demander une réponse à des paquets de tests qu'il envoie et en déduire des informations sur le réseau (comme le RTT). Mais le RFC original ne garantit pas grand'chose sur ces paquets de retour (section 4.2.1 du RFC 5357), ce qui peut être gênant dans certains cas. Désormais, le client peut décider d'une partie du contenu des paquets de test, ainsi que de leur taille (sections 1 et 2 du RFC).

La possibilité de réflexion d'octets, choisis par le client, ouvre de nombreuses possibilités à ce dernier comme d'étiqueter les paquets de la manière de son choix, en pouvant relire l'« étiquette » au retour.

La section 4.2.1 du RFC 5357 recommande que le serveur TWAMP choisisse des paquets de réponse qui soient de taille proche de celui des paquets reçus. Mais ce n'était pas une obligation. La nouvelle option indique que le client veut l'égalité des tailles de paquets.

Ces deux options sont signalées par des bits du champ Mode (section 3.1 du RFC 4656) autrefois inutilisés. Un serveur TWAMP correct doit ignorer ces bits s'il ne les connait pas, assurant ainsi la compatibilité des nouveaux clients avec les anciens serveurs.

Les détails pratiques figurent en sections 3 (pour la session de contrôle du test) et 4 (pour celle de test à proprement parler). Les deux nouveaux bits ont été enregistrés dans le registre IANA (voir aussi la section 6). La section 3.2 décrit le format des paquets de l'option « Reflect Octets » qui permet d'indiquer deux octets à réfléchir lors de l'acceptation de la session (ce qui permet de vérifier que le serveur gère bien cette extension). On indique aussi le nombre d'octets (au maximum 65536) à réfléchir lors du test. L'autre option, « Symmetrical Size » n'a pas nécessité de changer le format.

Enfin, la section 4.2 normalise le comportement du réflecteur en présence de ces nouvelles options. Les deux extensions en question sont optionnelles et ne seront pas forcément mises en œuvre par tous les serveurs TWAMP. Il n'existe de toute façon pas encore de mise en œuvre de TWAMP en logiciel libre.


Téléchargez le RFC 6038


L'article seul

RFC 6036: Emerging Service Provider Scenarios for IPv6 Deployment

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : B. Carpenter (Univ. of Auckland), S. Jiang (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 23 Octobre 2010


Maintenant que de nombreux FAI, dans le monde, ont déployé IPv6 et l'offrent comme service à leurs clients, il est temps de regarder ce qu'ils ont fait et de le documenter. Les auteurs de ce RFC ont donc commis un questionnaire début 2010 sur le thème « comment avez-vous déployé IPv6 », et l'ont envoyé à un certain nombres de FAI. Notre RFC 6036 résume les réponses.

Pendant longtemps, la décision de passer à IPv6 ou pas semblait ouverte. On déployait IPv6 quand, comme Nerim, on avait une clientèle techniquement exigeante, et on ne le déployait pas lorsqu'il n'y avait pas de demande des clients (le cas le plus fréquent). Mais, aujourd'hui, le business ne peut plus continuer comme avant, les adresses IPv4 étant presque épuisées. Cela laisse trois choix aux FAI (section 1 du RFC) :

  • Essayer d'économiser à l'extrême les adresses IPv4, en en allouant de moins en moins aux clients (ce qui est difficile pour l'accès individuel, où il n'y a déjà qu'une seule adresse par foyer) et en essayant d'acheter des adresses IPv4 sur les marchés gris ou noirs.
  • Installer de plus en plus de traduction d'adresse en étages successifs et laisser les clients déboguer les problèmes qui en résulteront.
  • Déployer IPv6.

Que font aujourd'hui les FAI ? L'enquête va essayer de répondre à cette question, en se focalisant sur ce qui est de la responsabilité directe des FAI, l'adressage, le routage, la gestion, le DNS, et en excluant les applications (qui sont souvent un des freins à la migration vers IPv6).

Plusieurs RFC couvrent ce champ. Par exemple, le RFC 4029 parle du déploiement chez un FAI, et prévoit la « double pile » (v4 et v6) sur tous les équipements. Compte-tenu du retard pris et de l'épuisement des adresses v4, cela ne sera sans doute pas possible et il faut aujourd'hui envisager la cohabitation et la communication entre des machines purement v4 et d'autres purement v6. Le RFC 5211 est une vision plus générale du déploiement d'IPv6, les FAI étant juste un cas particulier. Le RFC 4779 documente le déploiement de IPv6 dans des réseaux d'accès courants comme le câble TV ou l'ADSL. Les RFC 5181 et RFC 5121 traitent, eux, des accès 802.16. Les questions de sécurité sont abordées dans le RFC 4942 ainsi que dans le RFC 4864, ce dernier se focalisant sur la protection du réseau local du client.

Les normes IPv6 de base sont assez stables (la plupart des RFC récents n'ont touché qu'aux détails) mais le travail continue activement à l'IETF, par exemple dans des domaines comme la traduction d'adresses.

Place maintenant à l'étude elle-même (section 2). Le questionnaire figure dans l'annexe B. Il a été expédié à des listes d'opérateurs comme NANOG. 31 réponses ont été reçues. Seuls les volontaires répondaient, ce qui biaise évidemment les résultats (une liste - incomplète car certains ont demandé l'anonymat - des répondants figure en section 7). Les auteurs du RFC notent que les FAI qui ont déployé IPv6 étaient probablement plus prompts à répondre. Les réponses étaient confidentielles. Les réponses agrégées figurent dans l'annexe A.

Que trouve t-on dans ces réponses ? Les répondants fournissent de l'accès à l'Internet par un grand nombre de moyens (section 2.2), xDSL, DOCSIS, Ethernet, WiMAX et bien d'autres. Sur les adresses IP utilisées, plusieurs répondants poussent le négationnismes jusqu'à dire qu'ils n'auront jamais d'épuisement des adresses IPv4, les autres répondants citant, pour leur propre pénurie, des dates entre 2010 et 2015. En 2010, plusieurs FAI en Asie - 19 % des répondants - n'ont déjà plus une seule adresse IP publique et allouent du RFC 1918 à leurs clients ; ceux-ci n'ont donc pas un vrai accès Internet. 39 % des répondants utilisent des adresses privées en interne.

42 % des répondants ont déjà une offre IPv6 (section 2.4), mais moins d'1 % de clients l'utilise. 48 % des répondants ont une telle offre en travaux, avec l'idée d'ouvrir entre 2010 et 2013 (rappelez-vous que les réponses n'ont pas été vérifiées...) Donc, 10 % des répondants, en 2010, moins d'un an avant l'épuisement de la réserve IANA, ne font rien... Le pronostic sur le dépassement d'IPv4 par IPv6 en terme de trafic varie évidemment mais tourne autour de 2015.

Quelle technique de déploiement ? 94 % des répondants ont une épine dorsale en double-pile (section 2.5). 39 % ont ou bien vont avoir un relais 6to4 (je n'ai pas vérifié si cela incluait les relais 6rd comme ceux de Free) et 16 % du Teredo. Une des questions portait sur « les systèmes qui ne gèrent pas IPv6 ». Si les gros routeurs de l'épine dorsale sont évidemment tous prêts pour IPv6 depuis très longtemps, le maillon faible concerne plutôt des systèmes plus discrets : les CPE sont le plus souvent cités mais aussi les DSLAM, les répartiteurs de charge ou des logiciels comme celui de gestion des adresses IP des clients ou bien le système de facturation. À la question de savoir si des engins comme les CPE pourraient être mis à jour, beaucoup de réponses étaient « nous l'espérons »...

Parmi ceux qui allouent des adresses IPv6, les préfixes existants vont d'un /19 à un /48 (!) et celui alloué au client va de /48 à /64 en passant par plusieurs /56 (le RFC 6177 donne des recommandations à ce sujet). Pour déléguer le préfixe du client à la CPE, les méthodes vont de la configuration manuelle à DHCPv6 et SLAAC (StateLess Address AutoConfiguration). Certains utilisent Radius ou PPPoE bien qu'ils n'aient pas de moyen standard de déléguer un préfixe.

La moitié des répondants gèrent déjà des serveurs double-pile (SMTP, HTTP, IMAP). Des systèmes internes comme la surveillance du réseau semblent également v6isés à 50 % alors que les systèmes de facturation et de compatibilité, dejà cités, ne le sont qu'à 23 %.

Comment gérer la coexistence d'IPv4 et IPv6 ? 58 % des FAI ne croient pas aux clients « fixes » purement v6. Interrogés sur la date où la dernière application purement v4 disparaitra, les réponses sont souvent du type « au moins dix ans ». Il faudra donc gérer la coexistence. Sur ce point, la section 2.5 ne montre aucun consensus sur les solutions : un traducteur du genre NAT, par exemple, ou bien d'autres mécanismes pas forcément précisés.

Certains FAI ont IPv6 en production depuis des années. Quelles expériences peuvent-ils en tirer ? La section 3 fait le point. Ceux qui ont fait le choix de la double pile native (c'est le cas de Nerim en France) en sont contents. Mais ceux ceux qui utilisent 6to4 ou 6rd aussi. La plupart des répondants estiment a posteriori que le passage à IPv6 était plutôt facile, une opération qu'ils classent dans la catégorie « comment arriver à manger un éléphant ? » (la réponse est « une bouchée à la fois »). Les difficultés rencontrées portaient sur la difficulté à convaincre certains (il existe encore des négationnistes qui, cherchant à justifier leur inaction, prétendent que l'épuisement des adresses IPv4 est un faux problème) et, naturellement, sur le fait que, comme tous les changements d'infrastructure qui n'apportent pas un bénéfice immédiat et visible, le passage à IPv6 est difficile à justifier auprès de la direction, qui ne voit que l'intérêt financier immédiat. Des problèmes moins connus sont aussi soulevés, comme l'importance d'impliquer les gens qui font le support utilisateur, puisque certaines applications mal écrites ne se rabattront pas sur IPv4 si une connexion IPv6 échoue, ce qui peut entraîner des protestations des clients.

Puisqu'on parle des problèmes, quels sont les principaux manques à l'heure actuelle, pour le FAI qui veut passer à IPv6 ? La section 4 liste les réponses faites à ce sujet :

  • Les produits « bas de gamme » qui ne gèrent pas IPv6 (CPE, appliances SIP, IDS, ...). Sans compter ceux chez qui IPv6 est bogué, ou incomplet (un répondant cite le cas d'un CPE théoriquement IPv6 mais dont les fonctions de shaping ne marchaient qu'en IPv4) ou bien plus lent qu'IPv4. Dans le domaine du logiciel, si le logiciel libre n'est pas trop mal placé, beaucoup de logiciels commerciaux ne gèrent toujours pas IPv6.
  • L'offre de protocoles n'est pas encore complète (et, contrairement au point précédent, celui-ci est sous la responsabilité directe de l'IETF). La section 4.2 note que les répondants estiment qu'il n'existe pas de protocoles satisfaisants pour la délégation d'un préfixe v6 à la CPE, pour les mécanismes de contrôle des pare-feux comme UPnP, pour l'allocation d'adresses IP avec PPPoE ou Radius. (À noter que les réponses sont parfois mal informées ; ainsi, la demande d'un VRRP v6 a été satisfaite dans le RFC 5798 et celle d'une indication des serveurs DNS dans les Router Advertisement dans le RFC 6106. Le problème est donc en réalité désormais un problème de mise en œuvre et de déploiement, plus de protocole. Le cas inverse arrive aussi, où le FAI qui envisage de déployer v6 n'est pas conscient des limites de certains protocoles, voir la section 4.3.)
  • Enfin, des gros problèmes qui ne peuvent pas être résolus par les programmeurs ou par l'IETF demeurent : difficulté à trouver un vendeur de transit IPv6 en Amérique du Nord ou en Asie, problèmes de PMTU persistants, ...

Téléchargez le RFC 6036


L'article seul

RFC 6029: A Survey on Research on the Application-Layer Traffic Optimization (ALTO) Problem

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : I. Rimac, V. Hilt, M. Tomsu, V. Gurbani (Bell Labs, Alcatel-Lucent), E. Marocco (Telecom Italia)
Pour information
Première rédaction de cet article le 23 Octobre 2010


Dans le cadre des travaux menés à l'IETF (groupe de travail ALTO, RFC 5594, etc) et à l'IRTF sur le problème de l'optimisation du transfert de fichiers en pair-à-pair, ce RFC sert de bibliographie : il rassemble des pointeurs, classés et organisés, sur la littérature existante en matière d'optimisation, de recherche du « meilleur pair ».

Le pair-à-pair est un concept difficile à définir et encore plus à mesurer. D'autant plus, même si le RFC ne mentionne pas ce problème, que la répression dont il fait l'objet à l'instigation des ultras de l'appropriation intellectuelle oblige ses utilisateurs à diverses astuces pour dissimuler son utilisation, rendant ainsi les statistiques difficiles. Par exemple, les estimations de la part de trafic qui revient au pair-à-pair varient de 40 à 85 %... Une chose est sûre, cela représente un trafic important, et qu'il est donc logique de chercher à optimiser. Lorsqu'on utilise le pair-à-pair pour des transferts de fichier (avec des systèmes comme BitTorrent), le contenu convoité est répliqué sur de nombreux pairs à travers le monde (section 1 du RFC). Le problème est « Quel pair utiliser ? » Isolé, le pair qui veut récupérer un fichier ne peut utiliser que le hasard, ou bien des mesures qu'il fait lui-même et qui sont souvent imparfaites (par exemple, la mesure de la latence avec un ping ne donne qu'une vague idée du débit qu'on obtiendra). La DHT typique ne donne que des optimisations locales, qui ne sont pas forcément bonnes globalement. C'est le problème central de l'optimisation, décrit dans le RFC 5693.

Il y a plusieurs solutions à ce problème, comme des réseaux de machines faisant des mesures applicatives et donnant accès au résultat de ces mesures (Azureus le fait), ou bien comme des fournitures d'information aux pairs par le FAI, pour que les destinataires puissent prendre des décisions informées. Ce RFC résume la littérature existante sur ces solutions, en s'appuyant sur le RFC 4981.

La section 2 du RFC examine les résultats de recherche publiés sur ce thème, comme « The impact of DHT routing geometry on resilience and proximity » de Gummadi, K., Gummadi, R., Gribble, S., Ratnasamy, S., Shenker, S., et I. Stoica, qui étudie la relation entre le réseau overlay de plusieurs algorithmes de DHT et le réseau physique sous-jacent. Leur conclusion est notamment que les géométries les plus simples (comme l'anneau) sont les meilleures.

Pour les autres résultats de recherche, la section 2 les classe en deux groupes : les méthodes fondées sur des mesures faites uniquement par l'application (comme Meridian) et celles fondées sur une coopération entre les couches (comme P4P).

Les premières sont traitées plus en détail dans la section 2.1. L'idée de base est que les machines mesurent un coût (typiquement, la latence) par rapport à un certain nombre d'amers et qu'on peut ensuite calculer le coût de la communication entre deux machines, par le biais d'un système de coordonnées Internet. C'est ainsi que fonctionnent IDmaps ou GNP. Tous les deux dépendent d'un réseau d'amers stables. Au contraire, Vivaldi est entièrement distribué et c'est le système utilisé dans le client BitTorrent Azureus.

Les algorithmes cités dans le paragraphe précédent forment une sous-catégorie du groupe « Mesures faites par l'application ». Cette sous-catégorie est celle des systèmes de coordonnées explicites, qui essaient, à coup de mesures, de déterminer la topologie sous-jacente. Dans un réseau aussi complexe que l'Internet, où des inégalités aussi simples que l'inégalité triangulaire (qui dit que le coût pour aller de A à C est inférieur ou égal au coût de A à B plus celui de B à C) ne sont pas forcément vraies, il n'est pas évident qu'une telle approche soit efficace. D'où la seconde sous-catégorie, basée sur une mesure des distances. Moins générales, ces méthodes (dont la plus connue est Meridian) sont peut-être plus réalistes.

Dans tous les cas, toutes les mesures faites par les applications doivent se poser la problème de ce qu'on mesure. Le plus simple est de mesurer la latence (ce que fait, par exemple, la commande ping). Or, des métriques comme la capacité (RFC 5136) ou comme le taux de pertes de paquets (RFC 2680) seraient sans doute plus utiles. Plus difficiles à estimer par des mesures actives, elles conviennent par contre bien aux mesures passives (voir « Internet tomography » de Coates, M., Hero, A., Nowak, R., and B. Yu et ou iPlane).

Toutes les techniques de la section 2.1, où l'application cherche à se faire une idée de la topologie du réseau souffrent des mêmes problèmes : l'Internet est compliqué (section 3). Par exemple, le chemin le plus court n'est pas forcément le meilleur. Et la topologie ne renseigne pas sur les coûts financiers des liens, par exemple sur le fait que le transit est plus cher que le peering. Enfin, comme toutes les mesures actives, elles ajoutent à la charge du réseau.

Deuxième groupe, dans la section 2.2, les méthodes fondées sur une coopération entre les couches. Ce sont celles où l'application, au lieu de devoir faire les mesures elle-même, peut interroger un service qui a été configuré (typiquement par le FAI) avec des informations sur le réseau, sa capacité, son coût, etc. La plus connue est P4P (section 2.2.1) où des serveurs, les iTrackers, sont interrogés par les applications qui récupèrent ainsi des informations utiles. Des expériences, par exemple celle décrite dans le RFC 5632 indiquent que les gains de temps pour un téléchargement peuvent dépasser un facteur 2. Si le RFC ne parle pas des problèmes politiques, on note que ce mécanisme nécessite que le FAI soit prêt à révéler une partie de la structure de son réseau.

Une autre solution, décrite dans la section 2.2.2, est celle des « oracles » où l'application, au lieu d'avoir accès à des informations sur le réseau, fournit une liste de pairs potentiels et l'oracle lui indique les plus favorables. Là encore, le RFC ne rentre pas dans les questions politiques mais on voit que l'oracle acquière beaucoup d'informations sensibles, notamment sur les pairs avec qui on communique.

Une variante (section 2.2.3) du cas de l'oracle est celui où les deux machines qui veulent communiquer se connaissent déjà mais hésitent sur les adresses IP à utiliser, puisque ce choix influencera le chemin pris (cela ne concerne évidemment que les machines ayant plusieurs adresses). Cette approche, utilisée dans le système IDIPS (voir Saucez, D., Donnet, B., and O. Bonaventure, « Implementation and Preliminary Evaluation of an ISP-Driven Informed Path Selection », CoNEXT 2007) pourrait être utilisé pour le pair-à-pair en considérant l'ensemble des pairs possibles comme étant une immense machine virtuelle qu'on cherche à atteindre, un genre d'anycast.

Bien des questions restent ouvertes à l'heure actuelle (section 4). Ainsi, le problème des machines malveillantes qui vont essayer, dans le cas où le système de mesure est distribué, de perturber les mesures ou d'injecter de faux résultats (section 4.2). Dans un réseau de la taille de l'Internet, et compte-tenu du fait que certains ont un intérêt financier à limiter le partage de fichiers, il ne fait guère de doute qu'il y aura de telles machines pirates. Il n'existe pas actuellement de solutions miracles contre elles. Des tests de vraisemblance ont été proposés, pour vérifier si les mesures d'une machine ne s'écartent pas trop de celles des autres. Mais ces tests sont souvent fondés sur des suppositions qui ne sont pas forcément vraies sur l'Internet (comme l'inégalité triangulaire citée plus haut). Dans les cas où les pairs interrogent un oracle, la question de l'authentification de l'oracle est également cruciale. Mais les réseaux pair-à-pair se prêtent mal aux lourdes solutions d'identité comme les PKI.

Une variante de ce dernier problème se pose d'ailleurs au sujet de l'intégrité des données transmises (section 4.3). Ce n'est pas tout d'authentifier le pair ou l'oracle, encore faut-il être sûr que les informations reçues n'ont pas été modifiées en cours de route. Une telle modification permettrait, par exemple, d'affecter un coût très faible à une cible et de faire réaliser ainsi une dDoS contre elle (RFC 4732).

Enfin, parmi les différents problèmes encore largement ouverts, on peut citer les cas où l'optimisation marche trop bien (section 4.6). Poussée à l'extrême, en effet, l'optimisation ferait que les pairs ne s'adressent qu'à des pairs très proches, chez le même FAI et dans la même région. Les grands essaims pair-à-pair se fragmenteraient alors en essaims locaux, n'ayant pas de communication entre eux, ce qui réduirait la redondance qui fait la solidité du pair-à-pair (voir « Pushing BitTorrent Locality to the Limit » de Stevens Le Blond, Arnaud Legout et Walid Dabbous).


Téléchargez le RFC 6029


L'article seul

RFC 6020: YANG - A data modeling language for the Network Configuration Protocol

Date de publication du RFC : Octobre 2010
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 6 Octobre 2010


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, que décrit notre RFC.

Ce RFC 6020 est très détaillé, près 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 qui seront utilisées par Netconf. Ces données sont représentées sous forme arborescente. Yang est modulaire (section 5 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 6021). 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.

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 11 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) :


       <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 6021), 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.18.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 et à les convertir dans d'autres formats. Il ne semble plus maintenu depuis longtemps 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.


Téléchargez le RFC 6020


L'article seul

RFC 6018: IPv4 and IPv6 Greynets

Date de publication du RFC : Septembre 2010
Auteur(s) du RFC : F. Baker (Cisco), W. Harrop, G. Armitage (CAIA, Swinburne University of Technology)
Pour information
Première rédaction de cet article le 30 Septembre 2010


Il y a longtemps que les chercheurs en sécurité des réseaux utilisent des darknets, des réseaux dont les adresses IP ne sont normalement pas attribuées, pour analyser les attaques. Si on annonce une route vers un tel réseau, le trafic qu'on capte est essentiellement composé d'attaques ou de reconnaissances préalables à une attaque puisque rien de légitime ne peut utiliser ces réseaux. L'inconvénient des darknets est qu'ils sont trop gros et trop visibles : les attaquants apprennent vite leur existence et les mettent alors sur leur liste « pas touche » et les attaques cessents. Ce RFC décrit une alternative, le greynet, dont le préfixe IP est alloué et routé mais au sein duquel certaines adresses ne correspondent pas à une machine en activité.

Normalement, un routeur IP doit jeter les datagrammes destinés à une adresse qui ne répond pas aux requêtes ARP (RFC 826) ou ND (RFC 4861). On pourrait envisager de configurer des règles spéciales par adresse IP, pour copier les datagrammes destinés à ces machines vers la sonde d'observation. Mais, pour construire facilement le greynet, le RFC suggère une autre méthode : configurer le routeur pour que, au lieu de jeter les paquets qui ne peuvent pas être délivrés, il les copie vers la machine de surveillance. Toute adresse IP non affectée devient alors membre du greynet.

On peut ainsi détecter les attaques (ou les reconnaissances) vers ces adresses, mais aussi les cas d'usurpation de ces adresses par un tiers. Ces usurpations vont en effet produire du backscatter, de l'émission par les cibles en réponse aux reconnaissances, et une partie au moins de ce backscatter atteindra le greynet.

La section 2 sert ensuite de manuel pour l'administrateur réseaux qui voudrait déployer un tel système. Il doit évidemment d'abord mettre en place la machine de collecte, qui va recevoir les paquets, les enregistrer et plus tard les analyser. Ensuite, il peut utiliser le routage IP normal et choisir un préfixe non utilisé pour le router vers cette machine, créant ainsi un darknet (section 2.1). Sur Linux, par exemple, cela se ferait avec route add -net 192.0.2.128/25 gw 198.51.100.1192.0.2.128/25 est le préfixe du darknet et 198.51.100.1 l'adresse de la machine de collecte.

Mais s'il veut faire un greynet, il lui faut un routeur un peu spécial (section 2.2) qui va devoir, lorsqu'il reçoit un paquet pour lequel il n'a pas eu de réponse aux requêtes ARP et ND, le faire suivre à la machine de collecte. C'est à la fois plus simple qu'un darknet (pas de configuration explicite, à part l'adresse de la machine de collecte, cf. section 3) et plus compliqué (aucun routeur IP normal ne sait faire cela : en cas de non-réponse à ARP et ND, le paquet est abandonné).

La première documentation des greynets était dans « Greynets: a definition and evaluation of sparsely populated darknets », dans la 30th Conference on Local Computer Networks de l'IEEE en 2005. Elle a été suivie de plusieurs expériences, résumées dans la section 1.1 du RFC. L'utilisation du routeur pour identifier les adresses du greynet (ce sont celles qui ne répondent pas en ARP ou en ND) est venue après. La première mise en œuvre était sur un routeur Linux. Le fichier à récupérer est http://www.owenstephens.co.uk/files/neigh_fwd.c, et il se place dans le répertoire net/core des sources du noyau. Il faut ensuite appeler les fonctions nécessaires depuis neighbour.c, le moyen le plus simple étant sans doute de patcher ce dernier avec http://www.owenstephens.co.uk/files/neighbour.c.diff. (Merci à Owen Stephens pour avoir mis les sources en ligne.)

L'ajout d'IPv6 est venue encore ultérieurement. Bien qu'on entende souvent dire qu'un balayage complet d'un réseau IPv6 est impossible, vu le nombre d'adresses possibles, le RFC 5157 a montré que c'était faux. En pratique, les attaques IPv6 n'ont jamais été observées dans la nature mais il ne fait guère de doute que cela se produira un jour.

Un dernier avertissement pour ceux qui veulent tenter l'aventure : lisez bien la section 6 sur la sécurité. Tout dispositif de collecte peut faire l'objet d'abus, par exemple par un méchant qui, sachant qu'une collecte est en cours, va tenter de la saturer en envoyant plein de paquets.


Téléchargez le RFC 6018


L'article seul

RFC 6014: Cryptographic Algorithm Identifier Allocation for DNSSEC

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : P. Hoffman (VPN Consortium)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 22 Novembre 2010


L'allocation d'un nouveau numéro pour un algorithme cryptographique dans DNSSEC exigeait auparavant un RFC sur le chemin des normes. Désormais, n'importe quel RFC conviendra, ce qui est une libéralisation bienvenue.

Ces numéros sont attribués par l'IANA, stockés dans un registre public et permettent, lorsqu'on récupère un enregistrement DNSSEC, de savoir comment l'interpréter. Ainsi, le TLD .pm est signé avec l'algorithme de numéro 8, soit RSA/SHA-256 :

% dig +dnssec ANY pm.
...
pm.  172800 IN RRSIG SOA 8 1 172800 20100818151448 20100719141448 14659 pm. oepDlhY...

L'espace de nommage de ces codes ne fait qu'un seul octet, soit 256 possibilités seulement. Ce point a fait l'objet d'inquiétudes au moment de la libéralisation de l'allocation.

La norme DNSSEC, le RFC 4034 (section 7), reprenant des normes antérieures, impose un « IETF standards action » pour enregistrer un nouveau code, sauf pour 253 et 254, qui sont utilisables pour de expérimentations sans formalité. Une « IETF standards action », comme nous l'apprend le RFC 5226, est la publication d'un RFC situé sur le chemin des normes. C'est donc une opération plutôt lourde (mais possible : GOST a eu le numéro 12 ainsi, grâce au RFC 5933).

La section 2 du RFC explique le pourquoi de la libéralisation :

  • Certains algorithmes méritants peuvent avoir du mal à passer sur le chemin des normes, par exemple par suite de craintes sur les brevets qui les plombent, ou simplement parce qu'il n'ont pas encore été scrutés avec suffisamment d'attention. (Voir aussi la section 5 pour une discussion sur la sécurité des algorithmes et leur normalisation.)
  • Les demandes sont peu fréquentes (on n'invente pas un nouvel algorithme de cryptographie tous les jours !) et il y a donc peu de chances de voir les huits bits de l'espace occupés immédiatement.

Pour être complètement en sécurité, notre RFC demande à l'IETF de réévaluer les critères d'allocation lorsque 120 entrées du registre auront été allouées (en juillet 2010, on en a 11...). C'est pour cela que la plage 123-251 du registre est marquée comme réservée. Et les codes 253 et 254 restent disponibles pour les expérimentations.

Quelles sont les conséquences pour les mises en œuvre de DNSSEC (section 3) ? D'abord, il faut bien voir qu'un programme qui fait du DNSSEC n'a jamais été obligé d'implémenter tous les algorithmes du registre. Ceci ne change pas. Il y aura donc toujours des algorithmes qui ne seront pas universellement mis en œuvre. Les seuls algorithmes qui sont garantis sont ceux indiqués comme obligatoires dans le RFC 4034 (annexe A.1) ou son successeur. Actuellement, il n'y a que RSA/SHA-1.

Enfin, notons que le RFC précise que l'ordre des algorithmes dans le registre n'implique rien sur leur force cryptographique respective, ou leur sécurité...

Comme notre RFC ne fait que changer une règle d'allocation dans un registre IANA, toute sa partie normative se concentre dans la section 4, « IANA considerations ». En un mot, un RFC de n'importe quel statut suffit désormais pour demander un code dans le registre.


Téléchargez le RFC 6014


L'article seul

RFC des différentes séries : 0  1000  2000  3000  4000  5000  6000