Ce blog n'a d'autre prétention que de me permettre de mettre à la disposition de tous des petits textes que j'écris. On y parle surtout d'informatique mais d'autres sujets apparaissent parfois.
Première rédaction de cet article le 25 décembre 2011
Dans tout réseau, il y a besoin d'un mécanisme de
résolution des noms, traduisant les noms en
identificateurs de plus bas niveau, plus proches du fonctionnement
technique du réseau. C'est ainsi que, de 1983 à
2011, la résolution de noms sur l'Internet a
surtout été assurée par le DNS, permettant
ainsi de séparer des noms stables, comme
www.example.org
, des identificateurs moins stables,
comme 2001:db8:af::1:567
. Mais est-ce que cela
sera toujours le cas demain ?
Car le DNS est aujourd'hui menacé. Pas par les vagues
projets de construire un système « meilleur », tâche plus compliquée qu'elle n'en a l'air. Mais par
l'intérêt que portent des forces néfastes au DNS, et par les réactions
que cela va entraîner. Aujourd'hui, avec le DNS, nous avons sur
l'Internet un système d'une très grande fiabilité (les attaques
DoS contre la racine ont
toujours échoué, par exemple), largement
déployé, qui permet des identificateurs stables (mon blog est resté en
www.bortzmeyer.org
même lorsque je suis passé de
Slicehost à 6sync), et
qui assure une signification unique pour les noms. Pas besoin de
nuancer, de se renseigner, de demander quel réseau utilise son
interlocuteur, on est sûr que tout le monde pourra utiliser
www.bortzmeyer.org
et avoir un résultat
équivalent.
En raison de ces propriétés, le DNS est donc aujourd'hui à la base de toutes les transactions sur l'Internet, qui commencent toujours par une requête DNS (et parfois bien plus).
Ce rôle a évidemment attiré l'attention des méchants, notamment des censeurs. C'est ainsi que la loi LOPPSI en France permet d'imposer aux FAI de bloquer l'accès à certains sites, sur simple décision administrative (pour éviter que les citoyens puissent prendre connaissance de la liste des sites bloqués, et vérifier qu'ils sont bloqués pour de bonnes raisons). Un des mécanismes évidents pour mettre en œuvre ce blocage est le DNS (transformation du résolveur du FAI en DNS menteur, avec blocage du port 53). Déjà, de nombreux commerciaux font le tour des acteurs de l'Internet pour promouvoir des solutions de filtrage DNS, qui est également possible dans des logiciels comme BIND (avec la RPZ). La France dispose d'une grande avance technologique dans ce domaine, avec des entreprises comme Amesys, fournisseur de censure pour l'ex-dictature lybienne.
Les autres pays ne sont pas en reste et c'est ainsi que les États-Unis ont leur projet SOPA, équivalent de la LOPPSI, qui permet également d'obliger les FAI à bloquer l'accès à tel ou tel site. Comme, là encore, une implémentation évidente d'un tel système est via le DNS, SOPA a suscité des réactions vigoureuses de la part des acteurs du DNS, ce qui explique en partie le recul des promoteurs du projet. Toutefois, la présence ou l'absence de cette loi ne sera pas forcément le facteur principal : un certain nombre d'opérateurs censurent déjà via le DNS (c'est donc une censure privée, contrairement à SOPA qui proposait une censure étatique).
Naturellement, cette censure ne restera pas sans réponse. Des tas de gens chercheront des contournements, des moyens de passer outre à la censure, comme cela s'est déjà produit pour Wikileaks. Comme le dit An dans les commentaires d'un blog : « Dans le temps, on s'échangeait des adresses de ftp warez. Dans un futur proche, on s'échangera peut-être des fichiers hosts contenant des listes:
warez1 @IP1 warez2 @IP2 etc...
et on lancera bien gentiment notre navigateur sur http://warez1
, http://warez2
etc..
les sites webs auront été hackés et se verront ajouter un hostname warez1 qui servira
des films de vacances d'été comme au bon vieux temps du ftp warez. Ça ne tiendra pas
longtemps, ça sera difficilement traçable, et ça bougera bien trop rapidement pour
être coincé. ». D'autres tentatives ont déjà été faites, de diffuser
des listes d'adresses IP, suscitant de
vives discussions. En d'autres termes, il s'agit de revenir aux
anciennes listes genre
hosts.txt
distribuées, et
jamais parfaitement à jour (comme le note Pierre Beyssac, ce sera du « hosts.txt, cloud-style »).
Autre solution, on verra apparaître des résolveurs DNS promettant de ne pas censurer comme ceux de Telecomix. Des outils apparaîtront pour permettre de changer de résolveur DNS plus facilement (comme le montre l'article de Korben).
Ces réactions entraineront à leur tour des contre-réactions, vers davantage de contrôle, comme l'industrie du divertissement le prévoit déjà.
Lors d'une discussion sur la liste FRnog, Ronan Keryell s'exclamait : « Je pense qu'il faut à la base arrêter de tuer Internet.
C'était mieux avant (quand nous utilisions tous les 2 Internet dans les
années 80... :-) ).
Doit-on vraiment revenir au bon vieux hosts.txt
(RFC 952 pour ceux qui ont oublié ou plus
probablement ici n'ont jamais connu) face à tous ces délires de filtrage
et de résolution de faux problèmes imaginaires pour le bonheur de
l'utilisateur comme dans toute dictature qui se respecte ?
Stop ! On s'arrête ! ».
Mais nous en sommes déjà là, à revenir à des systèmes mal fichus, dont le résultat varie selon l'utilisateur, et dont la fiabilité n'est pas garantie. Les gens qui font les lois comme LOPPSI ou SOPA se moquent bien de tuer l'Internet. Ce n'est pas par ignorance de la technique qu'ils décident des mesures qui vont gravement blesser l'Internet. Ils veulent le contrôle avant tout, même au prix de problèmes permanents pour les utilisateurs.
Petit à petit, ces utilisateurs vont se servir de systèmes de résolution « inhabituels ». Ce seront des résolveurs DNS avec des règles spéciales (comme le plugin Firefox de Pirate Bay) puis des infrastructures utilisant le protocole DNS mais avec des données différentes (comme les racines alternatives sauf que cette fois, cela sera réellement adopté massivement, car il existe une forte motivation, qui manquait aux racines alternatives d'il y a dix ans, qui n'avaient rien à proposer aux utilisateurs).
On verra par exemple des « pseudo-registres » qui partiront des données des « vrais » registres puis les « corrigeront », ajouteront des termes ou d'autres, à partir d'une base à eux (contenant les domaines censurés).
Puis cela sera des systèmes de résolution nouveaux, comme Namecoin,
avec des passerelles vers le DNS (projet .bit
).
Pour l'utilisateur, cela entrainera désordre et confusion. Des noms
marcheront à
certains endroits et pas d'autres. On verra des tas de discussions sur
des forums avec des conseils plus ou moins avisés du genre « pour voir
tous les .fr
, utilise
telle ou telle adresse de résolveur DNS, et
pas ceux de X ou de Y qui sont
censurés ».
À la fin de l'année 2011, ce scénario catastrophe semble difficilement évitable, sauf réaction vigoureuse contre les ayant-trop-de-droits et autres censeurs.
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.
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 était donc un méta-RFC, chargé de dresser la liste de ce qui est indispensable dans une machine IPv6. Il a été remplacé depuis par le RFC 8504. Les deux points les plus chauds concernaient 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 (et est lui-même remplacé par le RFC 8504. 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 :
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 (depuis remplacé par le RFC 6724), 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 7084).
On a vu que l'autoconfiguration sans état (sans qu'un serveur doive se souvenir de qui a quelle adresse) était obligatoire. DHCP (RFC 8415), lui, n'est que recommandé.
Une extension utile (mais pas obligatoire) d'IP est celle des adresses IP temporaires du RFC 8981, 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 7084) 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. Depuis, le RFC 8504 a aussi apporté ses changements.
Première rédaction de cet article le 16 décembre 2011
Dernière mise à jour le 17 décembre 2011
Si vous administrez des machines Unix situées dans plusieurs fuseaux horaires, vous vous êtes peut-être déjà posé la question : quel fuseau indiquer à la machine ? Celui de sa localisation physique ? Celui de votre localisation physique ? Un autre ?
Voici la situation : Jean Michu, administrateur
système est à Paris et il gère des
machines à Newark,
Saint-Louis et d'autres endroits. Sur
Unix, on peut configurer chaque machine pour
indiquer son fuseau horaire (je ne crois pas qu'il existe de moyen
standard, par contre, sur Debian, c'est
dpkg-reconfigure tzdata
et sur Red Hat, c'est vi /etc/sysconfig/clock
). Mais lequel indiquer ?
Il y a au moins trois solutions :
C'est donc la dernière solution que j'ai choisie. Je configure toutes mes machines de manière à ce que leur heure par défaut soit UTC, ce qui produit des journaux utilisant cette heure.
Mais n'est-ce pas pénible que la commande date donne
cette heure UTC qui ne correspond pas au vécu de l'humain ? Et que
ls -l ne donne pas l'heure légale ?
Heureusement, Unix a réglé le problème depuis longtemps. Il suffit à
chaque administrateur système de définir la variable d'environnement TZ
et il aura l'heure
dans son fuseau horaire :
% date Fri Dec 16 20:03:03 UTC 2011 % export TZ=Europe/Paris % % date Fri Dec 16 21:03:08 CET 2011
Même chose pour ls. Si les États-uniens font parfois preuve de provincialisme (par exemple en utilisant ASCII sans penser que sept bits ne suffisaient pas pour toutes les écritures du monde), le fait que leur pays compte plusieurs fuseaux horaires a certainement contribué à mettre en place une gestion correcte de ce concept sur Unix.
Évidemmment, aucune solution n'est parfaite. Par exemple, si on veut configurer cron pour lancer une tâche à une heure légale particulière, il faudra faire un peu de calcul avant de le programmer. Ceci dit, vous pouvez demander à date de le faire pour vous (merci à Gabriel Kerneis pour le rappel). Si vous voulez savoir quelle est l'heure légale à Doualalorsque UTC est à midi :
% TZ=Africa/Douala date --date="2011-12-16 12:00:00Z" Fri Dec 16 13:00:00 WAT 2011
(Le format utilisé est celui du RFC 3339, Z signifiant UTC.)
Si on veut faire l'inverse, trouver quelle sera l'heure UTC correspondant à une certaine heure légale (ici, on se demande quelle sera l'heure UTC lorsqu'il est cinq heures du matin en Californie) :
% TZ=UTC date --date="$(TZ=America/Los_Angeles date --date='2011-12-16 05:00:00')" Fri Dec 16 13:00:00 UTC 2011
Une dernière chose sur les fuseaux horaires. Certaines personnes disent que l'argument de communication (« We observed an abnormal traffic from your AS around 0200 UTC ») n'est pas si important que ça car on peut toujours indiquer le fuseau horaire explicitement, même lorsqu'il n'est pas UTC (« We observed an abnormal traffic from your AS around 0300 CET »). Le problème est que ces abréviations ne sont pas forcément connues mondialement (demandez à un États-unien ce qu'est CET et à un Français à quoi correspond MST) et qu'elles sont ambigues : par exemple EST peut être un fuseau horaire aux États-Unis ou bien en Australie. On peut demander à date d'afficher l'heure avec un fuseau horaire explicite, indiqué numériquement, sans ses abréviations (ici, pour le fuseau horaire de la Californie) :
# Par défaut, affiche une abréviation ambigue % date Sat Dec 17 14:16:40 PST 2011 # Avec un décalage numérique, tout est plus clair % date --rfc-3339=seconds 2011-12-17 14:16:46-08:00
mais les utilisateurs n'y pensent pas toujours.
Première rédaction de cet article le 14 décembre 2011
Vous l'avez remarqué, ce blog parle entre autres des RFC, qui représentent un bon bout des articles. Les RFC y sont actuellement mentionnés au masculin (« un RFC », « le RFC 6455 »). Est-ce une règle ? Est-ce la meilleure ?
Je le dis tout de suite, il n'y a pas de réponse simple à cette question. Le terme RFC veut dire en anglais Request For Comments qu'on peut traduire par « demande de commentaires » ou « appel à commentaires » (la traduction que je préfère). Dans le premier cas, on devrait utiliser le féminin, dans le second le masculin. En anglais, la langue dans laquelle sont écrits (écrites ?) les RFC, le terme est neutre. Il ne faut donc pas chercher un argument d'autorité pour trancher.
Et l'usage, que nous dit-il ? Si on cherche sur Google en faisant s'affronter "le RFC" contre "la RFC" ou bien "un RFC" contre "une RFC", on obtient des scores très proches (en décembre 2011, "un RFC" -> 38 200 résultats, "une RFC" -> 29 400 résultats). Il n'y a pas d'interprétation dominante. On trouve même des textes où l'auteur dit à un endroit « une RFC » et à un autre « le RFC 2616 ». À défaut de l'opinion majoritaire, quelle est celle des experts ? Le site du projet de traduction des RFC utilise le féminin. Wikipédia fait de même.
Les arguments basés sur la traduction de Request For Comments ne sont pas parfaits. Écartons d'abord la traduction erronée « requête de commentaires » qui n'est pas du français correct (une requête n'est pas une request). Mais toutes les traductions, même justes, souffrent du même défaut : le sigle n'a plus beaucoup de signification, même en anglais. À l'origine, il avait été choisi par modestie (puisque les costards-cravate refusaient aux documents Internet le titre de normes, on les appelait « appel à commentaires ») et il reflétait une certaine réalité. Aujourd'hui, les RFC sont figés (une fois publié, un RFC n'est jamais modifié, même d'une virgule) et l'étymologie du sigle est devenue très trompeuse (il y a même des projets à l'IETF de supprimer le développé Request For Comments et de ne garder que le sigle).
Une autre traduction possible, qui respecte le sigle, serait « Référence Formalisée par la Communauté », qui décrit bien mieux la réalité des RFC (merci à Emmanuel Saint-James).
Bref, pour l'instant, je traduis par « appel à commentaire » (même si cela ne reflète pas leur réalité de documents stables) et je parle des RFC au masculin. Ça changera peut-être plus tard, mais il me faudra reprendre tout mon blog...
Première rédaction de cet article le 14 décembre 2011
Dans les discussions sur la protection de la vie privée, une confusion est souvent faite entre « donnée accessible publiquement » et « la totalité des données est récupérable » (ce qu'on nomme en anglais le bulk access).
Par exemple, cette confusion est souvent faite dans le cas de
l'accès aux données stockées dans le
DNS. N'importe qui peut interroger les serveurs
DNS de .fr
pour savoir si
le nom
anemelectroreculpedalicoupeventombrosoparacloucycle.fr
existe ou pas (on peut aussi le faire via le protocole whois). En revanche, le fichier comportant tous les noms
existants dans .fr
n'est pas
disponible. (Certaines zones permettent cet accès.) N'y a-t-il pas
une incohérence ? Si les données sont publiques, quel mal y aurait-il
à donner un accès à l'ensemble de ces données, un « bulk
access » (accès en masse) ?
Techniquement, la différence peut en effet sembler mince : si on
peut faire une requête DNS (ou whois) pour un nom, il est trivial de
faire une boucle pour essayer plein de
noms. Cela se nomme une attaque par dictionnaire et les serveurs de .fr
en voient régulièrement. Mais ce n'est pas très discret.
Et surtout, penser que l'accès individuel (éventuellement répété
dans une boucle) équivaut à l'accès en masse, c'est oublier
l'explosion combinatoire, qui limite
sérieusement les possibilités d'une attaque par
dictionnaire. Imaginons qu'on soit intéressé par les variantes de
mabanqueserieuse.example
. Imaginons également qu'on se
limite aux variations d'un seul
caractère. mabanqueserieuse
a 17 caractères. En
exploration systématique par des requêtes DNS, il faudrait 36 essais
(les lettres d'ASCII, plus les chiffres et le
tiret, moins le caractère existant) par caractère soit 612 essais. Et
cela ne teste que les substitutions, pas les ajouts ou suppressions
(dont on verra plus loin qu'ils existent). Bref, de tels tests
seraient assez bavards et feraient râler l'administrateur des serveurs
DNS (et c'est encore plus net avec whois). Dans la plupart des cas, énumérer toutes les variantes « intéressantes » (pour faire ensuite des requêtes DNS) n'est pas faisable.
Si on a l'accès en masse, tout est plus simple, car de superbes
algorithmes existent pour rechercher de manière plus efficace. Voyons
un exemple avec le programme agrep
(tre-agrep en fait), -E 1
signifiant qu'on cherche
les noms qui ne diffèrent que d'un seul caractère :
% grep mabanqueserieuse example.txt mabanqueserieuse.example % tre-agrep -E 1 mabanqueserieuse example.txt mabanqueserieuse.example mabanqueserieusr.example mabanqueserieusse.example mbanqueserieuse.example manbanqueserieuse.example ...
et on trouve ainsi de nombreuses autres variantes (testé avec une
banque réelle, où presque toutes les variantes avaient été
enregistrées par un bureau d'enregistrement
situé aux Bahamas). Le fait d'avoir accès à la
totalité de la base permet également des recherches sur une partie du
nom et de trouver ainsi les
doppelgangers comme wwwmabanqueserieuse.fr
.
Dans ce cas précis, vous me direz peut-être que détecter les cybersquatteurs opérant depuis un paradis fiscal ne serait pas une mauvaise chose. Mais mon but était de montrer que l'accès aux données en masse permettait des recherches bien plus poussées, et que cela peut se faire au détriment d'innocents (par exemple des particuliers harcelés par les détenteurs de titre de propriété intellectuelle, comme dans l'affaire Milka).
C'est pour cela que le mécanisme NSEC3 du RFC 5155 était important. Sans lui, il était possible d'énumérer tous les noms d'une zone DNS signée avec DNSSEC. Certaines personnes avaient relativisé ce risque en disant « les données DNS sont publiques, de toute façon », ce qui est une sérieuse erreur, comme indiqué plus haut.
Si vous préférez aborder le problème sous l'angle juridique, il faut lire les articles L. 342-1 à 3 du Code de la Propriété Intellectuelle (merci à Thomas Duboucher pour les indications).
Les curieux noteront que les algorithmes de recherche approximative de texte sont proches de ceux utilisés en génomique comme Smith et Waterman ou Needleman et Wunsch. En effet, la recherche d'une séquence de bases dans un génome ne peut pas se faire littéralement, comme avec grep. En raison des mutations et des erreurs dans le séquençage, la correspondance n'est jamais parfaite, et il faut donc accepter, comme dans l'exemple avec tre-agrep, un certain nombre de différences.
Première rédaction de cet article le 13 décembre 2011
Une série de chiffres en vaut une autre, pensez-vous ? Eh bien
non. Quoique numériques, toutes les adresses IP ne se valent pas. Le préfixe
128.0.0.0/16
, quoique parfaitement légal, est
ainsi invisible depuis une bonne partie de
l'Internet.
Tentez l'expérience depuis votre machine en visant l'amer mis en place par le RIPE-NCC :
% ping -c 3 128.0.0.1 PING 128.0.0.1 (128.0.0.1) 56(84) bytes of data. 64 bytes from 128.0.0.1: icmp_req=1 ttl=55 time=83.6 ms 64 bytes from 128.0.0.1: icmp_req=2 ttl=55 time=83.8 ms 64 bytes from 128.0.0.1: icmp_req=3 ttl=55 time=83.5 ms --- 128.0.0.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2005ms rtt min/avg/max/mdev = 83.519/83.692/83.890/0.367 ms
Si cela marche (comme ci-dessus), vous faites partie des favorisés. Sinon :
% ping -c 3 128.0.0.1 PING 128.0.0.1 (128.0.0.1) 56(84) bytes of data. --- 128.0.0.1 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2010ms
Mais pourquoi ? Qu'est-ce que ce chiffre a de particulier ?
C'est parce qu'une bogue des routeurs Juniper
traite ce réseau différemment et, par défaut, le considère comme
« martien » (anormal sur l'Internet) et refuse les annonces
BGP pour lui (ce
préfixe était réservé, mais le RFC 3330 l'a libéré en 2002). Le numéro
(interne) de bogue chez Juniper est le PSN-2011-10-393. Le problème est bien expliqué
dans un
article des RIPE labs et son effet mesuré
par les sondes Atlas. Aujourd'hui, un tiers de l'Internet ne
peut pas joindre ce réseau 128.0.0.0/16
. Autre
façon de mesurer le même problème, regarder la propagation des
annonces BGP, par exemple au
RIS qui, en décembre 2011, voit une propagation de seulement 80 %.
Une mise à jour existe désormais chez Juniper. On peut aussi
changer la configuration par défaut (qui est incorrecte). Si votre routeur
Juniper affiche 128.0.0.0/16
en réponse à
show route martians
, c'est que vous avez la
mauvaise configuration. Changez-la :
set routing-options martians 128.0.0.0/16 orlonger allow set routing-options martians 191.255.0.0/16 orlonger allow set routing-options martians 223.255.255.0/24 exact allow
(Trois préfixes sont concernés, même si c'est surtout le premier qui a fait parler de lui.)
Si vous n'arivez pas à pinguer l'adresse de l'amer ci-dessus, tapez sur votre FAI jusqu'à ce qu'il mette à jour ses routeurs (et ainsi de suite récursivement car cela dépend également de l'opérateur qui connecte le FAI).
Avant la mise à jour, sur la console du routeur :
admin@m7i-2-sqy> show route 128.0.0.1 admin@m7i-2-sqy> show route 128.0.0.1 hidden SERVICE.inet.0: 395145 destinations, 730370 routes (394162 active, 0 holddown, 1051 hidden) + = Active Route, - = Last Active, * = Both 128.0.0.0/21 [BGP/170] 1w5d 21:07:00, localpref 100 AS path: 2200 20965 1103 12654 I > to 193.51.182.46 via ge-1/3/0.0
Après la mise à jour :
admin@m7i-2-sqy> show route 128.0.0.1 SERVICE.inet.0: 369404 destinations, 369404 routes (368357 active, 0 holddown, 1047 hidden) + = Active Route, - = Last Active, * = Both 128.0.0.0/21 +[BGP/170] 00:01:55, localpref 100 AS path: 2200 20965 1103 12654 I > to 193.51.182.46 via ge-1/3/0.0
Merci à Sylvain Busson pour sa prompte mise à jour des routeurs.
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ésout 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 :
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).
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 <.
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 :
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.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.
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 7230) 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 7230, section 6.7 ; 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 7231, section 6.2.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étadonné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 :
GET
),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. (Une mise en œuvre existe.)
Les autres registres IANA pour WebSocket
sont en https://www.iana.org/assignments/websocket/websocket.xml
. Il existe un site de référence
sur WebSocket.
Un exemple de service publiquement accessible et utilisant WebSocket est le service RIS Live.
Enfin, si vous voulez d'autres articles sur WebSocket, j'ai beaucoup apprécié celui de Brian Raymor.
Première rédaction de cet article le 10 décembre 2011
Je sais, je ferais mieux d'être constructif, au lieu de râler, et de dire du mal des autres programmeurs. Mais c'est trop énervant, il faut que je me défoule : lorsqu'on écrit un programme en Python, et qu'il dépend de plusieurs paquetages (dont certains peuvent être installés et d'autres pas), c'est très galère. Il n'existe aucun mécanisme standard pour indiquer dans la distribution quels paquetages sont nécessaires.
Démonstration avec la bibliothèque seenthis-python, qui permet d'accéder au service de court-bloguage et de partage de liens SeenThis. seenthis-python dépend de deux paquetages, SimpleTAL, un système de gabarits, pour générer du XML propre, et FeedParser, pour analyser les messages en Atom que renvoie SeenThis. Dans la distribution de seenthis-python, comment indiquer (à part par du texte libre dans le README) qu'on dépend de ces paquetages ?
Commençons par le grand classique, car c'est le seul distribué avec
Python, dans la bibliothèque standard, et sur lequel tout le monde
peut compter : distutils. Le principe
est qu'on écrit un fichier setup.py
qui va
indiquer un certain nombre de choses sur le programme :
from distutils.core import setup setup(name='SeenThis', version='0.0', description='Use the SeenThis API', license='BSD', author='Stephane Bortzmeyer', author_email='stephane+seenthis@bortzmeyer.org', url='https://github.com/bortzmeyer/seenthis-python', )
Ce fichier peut ensuite être exécuté avec des options qui vont dire
par exemple d'installer le paquetage (python setup.py
install
) ou de l'enregistrer dans le Python Package Index (PyPI) (python setup.py register
).
distutils a des tas de limites. Par exemple, il ne permet pas de
faire des eggs, des paquetages binaires pour
Python. Mais, surtout, il ne permet pas d'exprimer des dépendances :
aucun moyen dans le script ci-dessus de dire qu'on a besoin de
SimpleTAL et de FeedParser. Le script setup.py
s'exécutera et installera la bibliothèque, même si les pré-requis
manquent. En lisant la
documentation, on a l'impression qu'on peut ajouter :
requires=['SimpleTAL', 'FeedParser']
mais c'est purement décoratif. La documentation ne le dit pas mais cette variable est complètement ignorée par distutils.
Au passage, le langage d'expression des dépendances (qui ne sert à
rien, on l'a vu) permet également d'indiquer un numéro de version, par
exemple le fait que, pour FeedParser, en raison de la
bogue #91 (« sgmllib.SGMLParseError: unexpected
'\xe2' char in declaration
»), il faut au moins la version 5.
Lorsque le débutant en Python se plaint de cet état de chose, les vieux experts blanchis sous le harnais lui rétorquent que tout le monde le sait, et que personne n'utilise le système standard (alors, pense le débutant naïf, pourquoi est-ce que ce truc reste dans la bibliothèque standard ?). Et c'est là que les choses se compliquent, car il existe plusieurs remplaçants possibles.
D'abord, le premier, setuptools (le
lien pointe vers PyPi puisque, à partir de là, on n'est plus dans la
bibliothèque standard, ce qui oblige l'utilisateur qui va installer
la bibliothèque à installer un autre programme d'abord, alors que le
but était de lui simplifier la vie). Il existe une bonne documentation pour débutant. En gros, on remplace la
première ligne de code du setup.py
par :
from setuptools import setup
et on a alors des fonctions et variables supplémentaires comme
install_requires
qui permet d'indiquer des
dépendances. Tout content, le programmeur Python naïf édite le README
pour indiquer à ses futurs utilisateurs qu'il va falloir installer
setuptools d'abord avant de faire le python setup.py
build
. Mais il va vite être déçu : même si SimpleTAL est
installé, le setup.py
va tenter de le télécharger
(et échouer, car il n'est pas dans PyPi). En effet, setuptools ne
teste pas si un module Python donné est disponible (import
simpletal
), il regarde s'il y a un egg du même
nom. Ce qui n'est pas le cas. Les dépendances de setuptools sont donc
vers les eggs, pas vers les modules, ce qui ôte une
bonne partie de leur intérêt.
D'autant plus que, on l'a vu, des paquetages fréquemment répandus, comme SimpleTAL, ne sont pas forcément disponibles dans PyPi... (SimpleTAL est arrivé plus tard.)
Bon, troisième tentative : distribute, qui prétend remédier aux problèmes de setuptools. Il reprend en partie son nom (ce qui contribue beaucoup à la confusion des programmeurs, par exemple le paquetage Debian de distribute se nomme setuptools) :
from distribute_setup import use_setuptools use_setuptools() from setuptools import setup [puis setup.py comme avant]
Comme setuptools, il permet de déclarer des dépendances, mais il les gère tout aussi mal :
# python setup.py install ... Searching for simpletal Reading http://pypi.python.org/simple/simpletal/ Reading http://www.owlfish.com/software/simpleTAL/index.html No local packages or download links found for simpletal error: Could not find suitable distribution for Requirement.parse('simpletal') % python Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import simpletal >>>
(La dernière commande montre que SimpleTAL est pourtant bien installé.)
Bref, on a trois systèmes concurrents et dont aucun ne permet d'assurer une tâche aussi simple que « vérifie que simpletal est bien disponible ». Pire, rien dans la documentation n'indique leurs limites. Ainsi tous les programmeurs Python semblent savoir que distutils est très limité mais cela n'apparaît pas dans la documentation de la bibliothèque standard. Et ce n'est pas fini. Comme l'écrit Victor Stinner «Le packaging Python est une série à la Dallas avec ses drames et ses rebondissements. Le dernier événement marquant est que la réécriture de distutils, "distutils2", a été intégrée dans Python 3.3 sous le nom "packaging". Sa version pour Python 2.5 - 3.2 sera maintenue en dehors de Python sous le nom "distutils2". » Il y a aussi des compétiteurs comme Bento ou plus exotiques comme zc.buildout.
Le problème du packaging Python est discuté avec bien plus de détails techniques (et moins de râleries pas constructives) dans l'excellent article Python packaging de Tarek Ziadé dans le livre Architecture of Open Source Software, (co-dirigé par Greg Wilson et Amy Brown).
Un petit truc : si on veut regarder la variété des fichiers
setup.py possibles, on peut demander
à Google (ici, en se limitant à ceux qui contiennent requires
).
Pour terminer, une bonne série de lectures, due à Nicolas Chauvat :
Première rédaction de cet article le 9 décembre 2011
Dernière mise à jour le 12 décembre 2011
Je viens d'acheter une tablette Packard Bell « Liberty Pad ». Je n'ai pas encore eu beaucoup d'occasions de m'en servir mais je documente quelques points ici, pour ceux qui envisagent d'acheter un modèle équivalent.
Le modèle que j'ai entre les mains est la Liberty Pad G100W, avec 1 Go de RAM et 12 Go de stockage. Elle a un grand écran, mais, avec plus de 700 grammes, elle est un peu lourde, on ne peut pas lire au lit en la tenant au dessus de soi.
Je m'en suis peu servi pour l'instant. Ce n'est pas qu'elle a des défauts insupportables, c'est plutôt qu'elle n'a pas encore trouvé sa place parmi mes gadgets électroniques, entre le smartphone et l'ordinateur portable.
Elle vient avec Android 3.2. Je n'ai pas mené de tests systématiques de toutes les variantes d'Android, d'autant plus que, comme c'est du logiciel libre, chaque constructeur peut en livrer une version différente avec son matériel. Mes observations sont donc pour l'Android 3.2 livré avec la Liberty Pad, j'accepte bien volontiers les remarques comme quoi c'est différent avec d'autres variantes de ce système.
Je dois dire que, compte-tenu de mon expérience avec les versions 2 d'Android, j'ai été plutôt déçu. Pas d'avantages évidents et des inconvénients :
Pour ceux qui aiment déboguer, voici ce que voit un PC Ubuntu quand la tablette est branchée :
[170151.693114] usb 3-2: USB disconnect, device number 9 [170157.054847] usb 3-2: new high speed USB device number 10 using xhci_hcd [170157.079225] xhci_hcd 0000:0b:00.0: WARN: short transfer on control ep [170157.081218] xhci_hcd 0000:0b:00.0: WARN: short transfer on control ep ...
(xhci indiquant de l'USB 3, ehci était l'USB 2.)
L'absence de liaison filaire par USB est évidemment très gênante. J'ai voulu activer Bluetooth et la tablette a alors redémarré... J'ai cherché alors à copier les fichiers vers la tablette en utilisant une synchronisation par un service extérieur, comme le S3 d'Amazon. Pour l'instant, c'est sans succès (pas trouvé de client S3 qui marche sur Android), j'écrirai un article un jour sur ce problème.
Même lorsqu'elles fonctionnent, toutes les applications Android ne se comportent pas comme il faut. Par exemple, le client Twitter Mustard n'arrive pas à utiliser correctement tout l'écran, bien plus large que celui des smartphones auquel il est habitué. Lorsqu'on le met en plein écran, les caractères sont pixelisés...
Certains de ces problèmes ont des solutions. Par exemple, pour le clavier, Florian Maury me suggère l'excellent Hacker's keyboard qui dote la tablette d'un clavier bien plus proche de celui d'un PC et qui facilite la saisie de plusieurs caractères (mais pas le #, qui n'est pas indiqué lorsque je tape en français, il faut un appui prolongé sur la touche 3 pour le voir). Sur un smartphone, une telle application serait pénible (ce clavier prend bien plus de place sur l'écran) mais sur une tablette, ça a un sens.
Pour le navigateur qui ne s'ajuste pas à la taille du texte, la solution la plus simple est de double-tapoter l'écran, le navigateur fait alors ce qu'il faut. (Merci à Gilles Maurer.)
Pour le problème USB, comme me l'a fort bien expliqué Erwann
Abalea, c'est parce qu'Android a changé entre les versions 2 et
3. Avant, la machine Android se présentait comme
Mass Storage Device, reconnue par tous
les systèmes. Depuis Android 3, elle se présente comme
MTP. Il faut donc installer la cuisine MTP (protocole fermé...) sur
Unix. Sur Ubuntu, le programme mtp-detect
du paquetage
mtp-tools sur Ubuntu détecte bien la tablette :
Device 0 (VID=18d1 and PID=335e) is UNKNOWN. ... Device info: Manufacturer: Packard Bell Model: Liberty Tab G100
Et on peut la monter avec mtpfs
(paquetage du
même nom). On crée /media/tablette
puis, à chaque
branchement :
# mtpfs -o allow_other /media/tablette % df -h Filesystem Size Used Avail Use% Mounted on ... mtpfs 13G 346M 13G 3% /media/tablette % ls -l /media/tablette total 0 drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Alarms drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 AndroAWS drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Android drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 DCIM drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Download drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Foldersync drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 LumiBooks drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Movies drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Music drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Notifications drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Pictures drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Playlists drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Podcasts drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 Ringtones drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 documents drwxrwxrwx 2 stephane stephane 0 Jan 1 1970 lost+found
(Si on veut le faire depuis un compte ordinaire, il faut qu'il soit
propriétaire du point de montage, ici
/media/tablette
et que l'option
user_allow_other
soit présente dans
/etc/fuse.conf
.) Là, on peut copier ses fichiers. Puis on démonte le volume :
# umount mtpfs
Je n'ai pas encore réussi à écrire la règle udev qui fera tout cela automatiquement. Mais au moins je peux copier des fichiers.
Bref, pour l'instant, je m'en sers surtout pour regarder YouTube (image et son sont parfaits). Lorsque j'aurai résolu les problèmes de synchronisation avec le monde extérieur, je m'en servirai pour de la lecture de documents, surtout si je trouve un logiciel qui me permet d'annoter les documents lus (un gros avantage du papier). Pour l'instant, je synchronise (sommairement) avec BotSync et un serveur SSH à moi quelque part dans le nuage.
Première rédaction de cet article le 7 décembre 2011
Je viens d'enregistrer la sonde Atlas n° 2012. Elle est située à Yaoundé, au Cameroun. C'est quoi, une sonde Atlas ?
L'Internet est aujourd'hui un énorme réseau,
qui s'étend sur toute la planète et sert à des milliards de gens, pour
tous les aspects de leur vie. Curieusement, on connait peu ce réseau
pourtant si indispensable. Il y a par exemple peu de mesures
quantitatives qui sont effectuées (chaque opérateur fait évidemment
des mesures intensives de son propre réseau ; mais il y a peu de
mesures trans-Internet). L'un des projets existants pour
améliorer la connaissance que nous avons de l'Internet est Atlas. Ce projet, initié et piloté
par le RIPE-NCC, héritier du vieux projet TTM, consiste à faire fabriquer des milliers de
petites sondes matérielles, minuscules boîtiers contenant le logiciel
de mesure, et munis d'une prise
USB (pour le courant) et
Ethernet (pour le réseau).
(Ces boîtiers sont dérivés du Lantronix Xport pro.) Les sondes sont
branchées, acquièrent une adresse par DHCP puis
« appellent la maison » en l'occurrence le RIPE-NCC. Leur contrôleur
peut alors leur faire effectuer un certain nombre de tests et
rassembler les résultats sur Atlas. On peut alors voir
l'Internet depuis un grand nombre de points.
La principale chose que je regrette, dans ce génial projet, est que le code source des sondes Atlas ne soit pas disponible. Le RIPE-NCC semble très fermé à cette idée. (S'il est impératif pour vous d'avoir le source, la seule solution semble être Bismark.)
Cette sonde particulière, la 2012, est la huitième opérationnelle en Afrique (Afrique du Sud exclue). Ce faible nombre donne d'ailleurs une idée de l'ampleur de la fracture numérique. On ne sait pas trop à quoi ressemble l'Internet vu de l'Afrique, à part que ça rame. La sonde m'a été donnée par le RIPE-NCC lors de la réunion RIPE de Vienne le 2 novembre 2011. Rapportée à Paris, confiée le 14 novembre à Michel Tchonang Minze qui rentrait au Cameroun pour la réunion d'AfriNIC (le courrier postal n'est pas toujours fiable, et certainement pas rapide), remise à Janvier N'gnoulaye le 23, qui s'est ensuite occupé de lui trouver une place. La sonde a été branchée et fonctionne depuis le 1er décembre.
Une fois la sonde enregistrée sur le site Web du RIPE-NCC, on peut voir des informations pratiques :
Probe ID: 2012 Firmware Version: 4270 IPv4 IPv6 Internet Address: 41.204.93.114 Undetermined/Unknown Local Address: 192.168.1.15 Undetermined/Unknown Gateway: 192.168.1.1 Undetermined/Unknown DNS Resolver: 192.168.1.1 Undetermined/Unknown AS Number: AS15964 Undetermined/Unknown Your probe is configured dynamically Your probe's public DNS entry is : p2012.probes.atlas.ripe.net Current status: Up since 2011-12-05 16:56:25 UTC Last Week Uptime: 94.75% Last Month Uptime: 94.75% Total Uptime: 94.75% (5d, 19h, 22m)
Notez les uptimes : une des plaies d'Atlas est le nombre de sondes distribuées mais jamais branchées, ou bien distribuées mais qui tombent en panne ou sont débranchées peu après. (D'ailleurs, la sonde de Yaoundé a planté peu après la parution de cet article, puis a été relancée.) Comme on le voit, le site ne dispose pas encore d'IPv6. Pour l'instant, la sonde est connectée via le réseau local de l'Université, qui va ensuite chez Camtel (l'AS 15964). Dans le futur, elle sera connectée par le NREN camerounais, en cours de construction.
Quel genre de mesures fait la sonde ? Elle
pingue par exemple un certain nombre
d'amers. Depuis l'Afrique, les
délais sont énormes (encore la fracture numérique). Par exemple, en
visant k.root-servers.net
, le serveur
racine DNS du RIPE-NCC, on trouve en trois tests dans la
journée 1248 ms /
1342 ms / 1495 ms. Les variations dépendent fortement de l'heure, ce
qui indique que ce n'est pas la latence du câble qui est le problème
mais la surcharge des tuyaux. Voici le graphique (le 4 décembre était
un dimanche) :
Pour une
vue sur une journée, voir par exemple le temps de réponse d'une autre
serveur racine, L, géré par l'ICANN :
Et les sondes Atlas font
bien d'autres mesures, qui nourissent les excellents articles des
RIPE Labs. Par exemple, en ce
moment (décembre 2011), elles testent la connectivité avec le réseau
128.0.0.0/16
, qui est filtré par une bogue des
routeurs Juniper. (Le problème ne se pose pas
au Cameroun où il n'y a que des Cisco.)
Première rédaction de cet article le 1 décembre 2011
Le déploiement très lent d'IPv6 dans l'Internet fait réfléchir aux causes : pourquoi est-ce que cela ne va pas plus vite ? Pour le cas des sites Web regardés par un public passif (public poétiquement baptisé « globes oculaires » - eyeballs), une des raisons est que d'être accessible en IPv6 peut rendre l'accès très lent pour les clients qui ont une connexion IPv6 incorrecte. Pourquoi ? Et quels sont les derniers développements qui permettent de traiter ce problème ?
Commençons par définir le problème : soit le célébrissime M. Toutlemonde qui veut regarder un site Web avec du graphique plein partout. M. Toutlemonde a donc des eyeballs, des globes oculaires, qui attendent avec impatience de se délecter d'images qui bougent. Mettons que le site Web visé a une connexion IPv4, une en IPv6 et qu'il publie dans le DNS les deux adresses (A et AAAA). Mettons encore que M. Toutlemonde a une connexion IPv6 mais qu'elle est très mauvaise, voire complètement cassée (c'est fréquent avec des techniques comme Teredo, 6to4, ou des tunnels d'amateurs, et c'est pour cela qu'il faut fuir toutes ces techniques).
Le navigateur Web de M. Toutlemonde va tenter une connexion en IPv6 (c'est ce que demande le RFC 6724), la connexion IPv6 étant inutilisable, ce logiciel va attendre... attendre... attendre une réponse qui ne viendra jamais. Il passera finalement à l'adresse suivante, en IPv4, mais trop tard. M. Toutlemonde, furieux, aura déjà éteint son ordinateur et ouvert un livre en papier de Frédéric Mitterrand à la place. Comment lui éviter ce sort tragique ?
L'algorithme utilisé par les programmeurs « naïfs » n'est pas optimum. Cet algorithme, c'est, en gros, la méthode séquentielle suivante :
adresses = getaddrinfo(nom_du_serveur) pour chaque adresse dans adresses connexion(adresse) si connexion réussie, sortir de la boucle
L'étape connexion(adresse)
est bloquante et prend un temps fou si
l'adresse en question est injoignable. C'est à cause de cela que
l'écrasante majorité des gros sites Web ne publient pas d'adresse IPv6
dans le DNS, de peur de mécontenter les globes oculaires de leurs utilisateurs.
La première idée d'optimisation a donc été de faire les tentatives de connexion en parallèle et non plus séquentiellement. Mais cette technique a des inconvénients aussi : elle consomme N fois plus de paquets (pour N adresses disponibles) et elle ouvre plusieurs connexions avec le serveur si celui-ci a plusieurs adresses qui répondent, connexions qu'il faudra fermer ensuite.
D'où la méthode qui est à la mode (illustrée par un célèbre programme de l'ISC ou bien par ce code en Go) : tenter la connexion en IPv6 mais avec un délai de garde très court, et passer aux adresses v4 plus vite, sans attendre le délai de garde normal d'une tentative de connexion TCP. 300 à 500 mili-secondes suffisent : il est rare qu'une connexion réussisse en un temps plus long. Ce système permet-il d'avoir toujours des « happy eyeballs », des globes oculaires heureux ?
Si vous avez logiciel et connexion IPv6, vous pouvez tester vous-même avec votre navigateur favori, en
regardant des sites Web dont la connectivité IPv6 est délibérement en
panne, comme http://intentionally.broken.dualstack.wdm.sg.ripe.net/
(admirez son adresse IPv6...) ou http://broken.redpill-linpro.com/
. Si vous y
arrivez très vite, vous être un globe oculaire heureux, derrière un
navigateur Web qui met en œuvre correctement les dernières
techniques. Si vous utilisez un logiciel qui utilise l'ancien
algorithme (ici, wget), vous allez souffrir :
% time wget http://intentionally.broken.dualstack.wdm.sg.ripe.net/ --2011-12-01 22:30:39-- http://intentionally.broken.dualstack.wdm.sg.ripe.net/ Resolving intentionally.broken.dualstack.wdm.sg.ripe.net... 2001:67c:2e8:dead:dead:dead:dead:dead, 193.0.0.169 Connecting to intentionally.broken.dualstack.wdm.sg.ripe.net|2001:67c:2e8:dead:dead:dead:dead:dead|:80... [Vingt secondes s'écoulent ici...] failed: Connection timed out. Connecting to intentionally.broken.dualstack.wdm.sg.ripe.net|193.0.0.169|:80... connected. HTTP request sent, awaiting response... 200 OK
Mais un excellent article d'Emile Aben, « Hampering Eyeballs - Observations on Two "Happy Eyeballs" Implementations », montre que le problème est plus compliqué que cela. Il a testé deux implémentations de l'idée ci-dessus, une sur Google Chrome (ticket #81686) et l'autre sur deux navigateurs tournant sur Mac OS X (l'algorithme de Mac OS X a été décrit par Apple). L'analyse montre que Chrome est parfait et réussit à rendre les globes oculaires heureux dans tous les cas. Mais Mac OS X ne s'y est pas aussi bien pris. Avec le navigateur Firefox, les globes oculaires peuvent être dans certains cas (machine qui a démarré récemment et n'a pas encore accumulé de statistiques de performance) aussi malheureux qu'avant. Avec Safari, le pire est évité mais il n'utilise parfois pas des connexions IPv6 pourtant parfaitement opérationnelles.
Si vous voulez tester vous-même le niveau de bon ou mauvais fonctionnement de serveurs IPv6, je recommande un programme attaché au système de gestion de bogues de Mozilla :
% ./test-happiness-eyeballs broken.redpill-linpro.com www.bortzmeyer.org \ intentionally.broken.dualstack.wdm.sg.ripe.net www.ietf.org [ 0us] begin gai_and_connect(broken.redpill-linpro.com) [+ 1626us] getaddinfo(broken.redpill-linpro.com) done [+ 34us] dest = 2a02:c0:1002:11::dead (AF_INET6) [+ 13us] about to connect() [+ 20997111us] connect() fails: Connection timed out [+ 77us] dest = 87.238.47.15 (AF_INET) [+ 14us] about to connect() [+ 59079us] connect() suceeds [ 0us] begin gai_and_connect(www.bortzmeyer.org) [+ 621us] getaddinfo(www.bortzmeyer.org) done [+ 18us] dest = 2001:4b98:dc0:41:216:3eff:fece:1902 (AF_INET6) [+ 11us] about to connect() [+ 156535us] connect() suceeds [+ 52us] dest = 2605:4500:2:245b::bad:dcaf (AF_INET6) [+ 13us] about to connect() [+ 117633us] connect() suceeds [+ 65us] dest = 204.62.14.153 (AF_INET) [+ 14us] about to connect() [+ 111054us] connect() suceeds [ 0us] begin gai_and_connect(intentionally.broken.dualstack.wdm.sg.ripe.net) [+ 558us] getaddinfo(intentionally.broken.dualstack.wdm.sg.ripe.net) done [+ 19us] dest = 2001:67c:2e8:dead:dead:dead:dead:dead (AF_INET6) [+ 10us] about to connect() [+ 20998608us] connect() fails: Connection timed out [+ 58us] dest = 193.0.0.169 (AF_INET) [+ 11us] about to connect() [+ 38271us] connect() suceeds [ 0us] begin gai_and_connect(www.ietf.org) [+ 635us] getaddinfo(www.ietf.org) done [+ 18us] dest = 2001:1890:123a::1:1e (AF_INET6) [+ 10us] about to connect() [+ 190011us] connect() suceeds [+ 61us] dest = 12.22.58.30 (AF_INET) [+ 14us] about to connect() [+ 199703us] connect() suceeds
Vous voyez que les connexions qui réussissent le font en moins de 200 ms, alors que celles qui échouent prennent 20 s.
Depuis la publication de cet article, Christophe Wolfhugel me fait remarquer qu'il n'y a pas que l'établissement de la connexion à prendre en compte pour le bonheur des globes oculaires. En effet, IPv6 a plus souvent des problèmes de MTU qu'IPv4 (les tunnels y sont plus fréquents, et l'ICMP plus souvent bloqué par des administrateurs réseaux maladroits, cf. RFC 2923 et RFC 4459). Dans ce cas, le globe oculaire malheureux risque de voir une connexion qui réussit en IPv6 (les paquets TCP de la poignée de main initiale sont tous de petite taille, bien inférieure à la MTU) mais où on ne pourra pas envoyer de données ensuite (car les paquets de données auront, eux, la taille maximale). Je ne connais pas de site Web délibérement cassé de ce point de vue (pour pouvoir tester) mais, en gros, si votre navigateur affiche qu'il a pu se connecter mais qu'ensuite il attend, cela peut être un problème de MTU (voir mon article à ce sujet, en attendant que tout le monde mette en œuvre le RFC 4821).
Un autre article sur le même sujet, très détaillé techniquement avec analyse du comportement des paquets, est « Dual Stack Esotropia ». La question du bonheur des globes oculaires a depuis fait l'objet du RFC 6555 qui spécifie les algorithmes utiles et du RFC 6556 qui décrit une technique de mesure du niveau de bonheur.
Première rédaction de cet article le 29 novembre 2011
Il existe des tas de systèmes d'exploitation libres. Certains sont très différents de la moyenne et, comme j'ai géré pendant des années un serveur sous Gentoo, voici quelques notes sur Gentoo et deux ou trois choses que j'ai apprises à son sujet.
Le système Gentoo utilise le noyau Linux, la GNU libc et les outils GNU habituels. (C'est donc ce que certains appellent, par erreur, une distribution Linux.) Mais Gentoo se distingue de systèmes comme Debian ou CentOS par le fait que tout est compilé à partir des sources et que l'administrateur système a bien plus de liberté pour ajuster le système à ses goûts. Gentoo n'est pourtant pas forcément plus difficile en utilisation quotidienne.
Un des problèmes du terme « distribution Linux » est qu'il suppose que tous les systèmes ainsi nommés ont des points en commun. Par exemple, j'ai lu lors d'une discussion un partisan de FreeBSD affirmer que « les distributions Linux sont en binaire », ce qui est certainement vrai de Debian ou CentOS, mais pas de Gentoo, qui est au contraire le royaume de la compilation.
Donc, le principe est que tout logiciel installé sur la machine a été compilé, avec des options choisies par l'administrateur. Contrairement à FreeBSD, il n'y a qu'une seule méthode (la bonne) pour maintenir l'arbre à jour (et c'est la même pour tout le système, le noyau, la libc, MySQL).
Lorsqu'on tape :
% emerge postfix
On ne se contente pas d'installer un paquetage
binaire de Postfix, on télécharge les sources
et on recompile. Les options de compilation (dites USE
flags) sont centralisés dans
/etc/portage/package.use
et, par exemple, on peut trouver :
mail-mta/postfix -ldap -mailwrapper
qui indiquent de compiler Postfix sans LDAP. Autre exemple :
net-dns/opendnssec -mysql sqlite
indique qu'OpenDNSSEC doit être compilé avec
SQLite mais sans
MySQL. Les valeurs possibles sont indiquées
dans /usr/portage/profiles/use.desc
pour les
variables globales, et dans
/usr/portage/profiles/use.local.desc
pour celles
spécifiques à une application donnée.
Ces compilations systématiques sont évidemment mauvaises du point de vue écologique (on fait tourner la machine et consommer davantage d'électricité). Il existe un moyen de fabriquer des paquetages binaires mais c'est juste en interne, il n'y a pas d'archive publique de tels paquetages.
Gentoo permet également une grande souplesse dans le choix des
versions installées. On peut masquer ou démasquer des programmes par
leur numéro de version, sélectionnant ainsi le choix de telle ou telle
version. Par
exemple, si on n'est pas prêt pour MySQL 5.1, on interdit mysql>=5.1
).
Quelques commandes Gentoo utiles (avec leur équivalent Debian entre parenthèses pour ceux qui sont plus familiarisés avec ce système) :
[Compile et installe le paquetage XXX ("aptitude install XXX")] % emerge XXX [Mets à jour la liste des paquetages connus ("aptitude update")] % emerge --sync [Ou emerge-webrsync si on est coincé derrière un pare-feu pénible.] [Cherche le nom d'un paquetage ("apt-cache search XXX")] % emerge --search XXX [Supprime le paquetage XXX] % emerge --unmerge XXX
La compilation peut rater. Par exemple, en essayant
emerge bind
:
!!! The ebuild selected to satisfy "net-dns/bind" has unmet requirements. - net-dns/bind-9.8.1_p1::gentoo USE="berkdb doc ipv6 (multilib) ssl xml -caps -dlz -geoip -gost -gssapi -idn -ldap -mysql -odbc -pkcs11 -postgres -rpz -sdb-ldap (-selinux) -threads -urandom" The following REQUIRED_USE flag constraints are unsatisfied: berkdb? ( dlz ) The above constraints are a subset of the following complete expression: postgres? ( dlz ) berkdb? ( dlz ) mysql? ( dlz !threads ) odbc? ( dlz ) ldap? ( dlz ) sdb-ldap? ( dlz ) gost? ( ssl )
C'est beau comme message, non ? Pour le supprimer, il a fallu ajouter
dans package.use
un net-dns/bind -mysql -ldap -berkdb -dlz
.
Autre problème, certains programmes nécessitent une énorme quantité de mémoire lors de la compilation. C'est ainsi que Ruby ou Haskell (le compilateur ghc) ne peuvent tout simplement pas être compilés sur un VPS de petite taille.
emerge est l'outil en ligne de commande du système Portage de gestion des paquetages :
% emerge --version Portage 2.1.7.17 (default/linux/amd64/10.0/server, gcc-4.3.4, glibc-2.10.1-r1, 2.6.24-24-xen x86_64)
Mais Gentoo offre d'autres possibilités, par exemple certains préfèrent utiliser Paludis. D'une manière générale, Gentoo dispose de plein d'outils rigolos.
Par exemple :
[Liste des paquetages ("dpkg -l")] % equery list
equery est livré dans le paquetage gentoolkit. Il sert à bien d'autres choses comme à trouver le paquetage auquel appartient un fichier.
emerge permet de mettre à jour tout le système d'un coup :
% emerge --update --deep --tree --verbose --ask world
Inutile de dire que cela prend du temps. Pire, on découvre souvent à cette occasion des problèmes subtils de dépendance, de bloquage d'un paquetage par un autre, qui sont longs et difficiles à régler. Je ne peux que conseiller d'appliquer la commande précédente fréquemment : plus on attend, plus elle devient cauchemardesque.
Et tout ne se passe pas toujours bien, ce qui ramène au bon (?) vieux temps où on était obligé de tout compiler. Il y a des fois des messages assez mystérieux, notamment concernant le masquage. Mais quand ça marche, on est tout heureux.
% sudo emerge -uDavt world These are the packages that would be merged, in reverse order: Calculating dependencies .... .. ...... done! [ebuild U ] x11-libs/fltk-2.0_pre6970-r1 [2.0_pre6970] USE="doc jpeg png xft zlib -cairo -debug -opengl -xinerama" 2,470 kB [0] [ebuild U ] dev-php/PEAR-PhpDocumentor-1.4.3-r1 [1.4.1] USE="-minimal" 2,367 kB [ 0] [ebuild NS #] dev-lang/php-5.2.17 [5.3.6] USE="apache2 berkdb bzip2 cgi cli crypt c type curl doc filter ftp gd gdbm hash iconv imap ipv6 json mysql ncurses nls pcre pdo pi c posix postgres readline reflection session simplexml snmp sockets spl sqlite ssl token izer truetype unicode xml xmlrpc xsl zlib (-adabas) -bcmath (-birdstep) -calendar -cdb - cjk -curlwrappers -db2 -dbase (-dbmaker) -debug -discard-path -embed (-empress) (-empres s-bcs) (-esoob) -exif (-fdftk) -firebird -flatfile -force-cgi-redirect (-frontbase) -gd- external -gmp -inifile -interbase -iodbc -kerberos -kolab -ldap -ldap-sasl -libedit -mha sh -msql -mssql -mysqli -oci8 -oci8-instant-client -odbc -pcntl -qdbm -recode -sapdb -sh aredext -sharedmem -soap (-solid) -spell -suhosin (-sybase-ct) -sysvipc -threads -tidy - wddx -xmlreader -xmlwriter -xpm -zip" 8,888 kB [0] [ebuild U ] net-analyzer/rrdtool-1.4.5-r1 [1.3.8] USE="doc perl python -lua% -rrdcg i -ruby -tcl (-nls%*)" 1,318 kB [0] ...
(Rappelez-vous que merge, en jargon Gentoo, signifie « installer ».)
Si vous êtes sur une machine AMD64 et
qu'emerge refuse de compiler avec des messages comme (masked
by: missing keyword), il faut typiquement ajouter
~amd64
après le nom du paquet dans
/etc/portage/package.keywords
. La
FAQ explique
pourquoi.
Notez que Gentoo dispose d'un Bugzilla qui est très actif.
Et pour ceux qui ne veulent pas tout mettre à jour (même en version
stable, c'est-à-dire testée pendant suffisamment longtemps par suffisamment de
gens), il y a un outil, glsa-check
, qui ne met à jour que les paquetages qui
ont des alertes de sécurité :
% glsa-check --test all This system is affected by the following GLSAs: 200809-05 200903-25 201006-18 201009-03
Très utile lorsque vous reprenez en main la gestion d'une Gentoo après une longue période de non-maintenance.
Il y a aussi des particularités de Gentoo qui peuvent être déroutantes, voire agaçantes. Par exemple, les démons ne sont pas redémarrés automatiquement en cas de mise à jour. C'est embêtant lorsque c'est une mise à jour de sécurité.
D'autre part, lorsqu'on met à jour
une bibliothèque, la mise à jour des paquetages qui en dépendent n'est
pas automatique. Si on a changé MYLIB, il faut penser à
revdep-rebuild --library=MYLIB
(sinon, on se
récupère des erreurs du genre « error while loading shared
libraries: libjpeg.so.62: cannot open shared object file: No such file
or directory ». Voici un exemple, après avoir recompilé
OpenSSL, on recompile tout ce qui dépendait de la vieille version :
# revdep-rebuild --library=/usr/lib/libssl.so.0.9.8 * Configuring search environment for revdep-rebuild * Checking reverse dependencies * Packages containing binaries and libraries using /usr/lib/libssl.so * will be emerged. * Collecting system binaries and libraries ... * found /usr/bin/htdig * found /usr/bin/ncat * found /usr/bin/ssh-keygen ... * Assigning files to packages * Assigning packages to ebuilds ... emerge --oneshot www-misc/htdig:0 net-analyzer/nmap:0 net-misc/openssh:0 ...
Même chose lorsqu'on a mis à jour des programmes d'infrastructure comme les interpréteurs Perl ou Python. Heureusement, il existe des programme perl-cleaner et python-updater, qui servent justement à cela, et qu'il ne faut pas oublier de lancer.
Enfin, les dépendances ne sont gérées qu'à l'installation, pas à la désinstallation. Rien, même pas un avertissement, ne prévient qu'on est en train de retirer une bibliothèque vitale.
Et pour les fichiers de configuration ? Une fois un emerge
réalisé, on fait un etc-update
:
# etc-update Scanning Configuration files... The following is the list of files which need updating, each configuration file is followed by a list of possible replacement files. 1) /etc/bind/named.conf (1) 2) /etc/init.d/named (1) Please select a file to edit by entering the corresponding number. (don't use -3, -5, -7 or -9 if you're unsure what to do) (-1 to exit) (-3 to auto merge all remaining files) (-5 to auto-merge AND not use 'mv -i') (-7 to discard all updates) (-9 to discard all updates AND not use 'rm -i'): -3 Replacing /etc/bind/named.conf with /etc/bind/._cfg0000_named.conf mv: overwrite `/etc/bind/named.conf'? y Replacing /etc/init.d/named with /etc/init.d/._cfg0000_named mv: overwrite `/etc/init.d/named'? y Exiting: Nothing left to do; exiting. :)
Il existe une alternative à etc-update
, dispatch-conf
.
Je l'avais signalé, mais Gentoo permet également des paquetages binaires qu'on peut installer avec :
emerge --usepkg --getbinpkgonly XXX
mais il semble qu'il faille un arbre portage complet. De toute façon, en l'absence d'un dépôt public de tels paquetages binaires, ils ne sont utilisables qu'à l'intérieur d'une organisation (si on a des dizaines de machines et qu'on ne veut pas que chacune recompile).
Comment passe t-on d'une version de Gentoo à une autre ? Le processus est documenté mais, en gros :
# cd /etc # ln -sf /usr/portage/profiles/default/linux/amd64/10.0/server make.profile
et cela fait passer en version 10.0 (au fur et à mesure des compilations).
Autre solution : eselect profile set
default/linux/amd64/10.0/server
(eselect
list
permet de voir tous les choix possibles).
Bien sûr, Gentoo permet aussi de créer son propre paquetage si son programme favori n'est pas encore disponible. On trouve de bonnes documentations en ligne mais le principe est simple :
ebuild
en s'inspirant
de ceux qui existent dans /usr/portage
. Voici par
exemple celui que j'avais fait pour
NSD (depuis, le paquetage a évolué)./usr/local/portage/$DIR/$PROGRAM
.ebuild $PROGRAM-$VERSION.ebuild digest
.emerge -u $PROGRAM
).Pour l'anecdote, voici quels avaient été les temps de fonctionnement de ma machine Gentoo chez Slicehost :
% uprecords # Uptime | System Boot up ----------------------------+--------------------------------------------------- 1 370 days, 18:57:23 | Linux 2.6.32.9-rscloud Mon Mar 22 20:20:22 2010 2 335 days, 22:40:29 | Linux 2.6.16.29-xen Mon Sep 22 16:28:39 2008 3 261 days, 23:45:51 | Linux 2.6.16.29-xen Fri Sep 14 10:46:04 2007 -> 4 245 days, 07:01:34 | Linux 2.6.32.9-rscloud Mon Mar 28 16:19:07 2011 5 154 days, 16:14:35 | Linux 2.6.16.29-xen Thu Apr 12 16:47:20 2007
Si vous voulez en savoir plus sur Gentoo :
Merci à Samuel Tardieu pour son aide et ses remarques sur Gentoo.
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 6890. 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 :
Première rédaction de cet article le 28 novembre 2011
Dernière mise à jour le 30 novembre 2011
Je sollicite l'aide de mes lecteurs pour trouver un logiciel qui m'affiche l'état (nombre de messages non lus) de mes multiples boîtes aux lettres. J'utilisais gbuffy mais il n'est plus maintenu et dépend de bibliothèques qui n'existent pas dans les systèmes récents.
Voici le problème exact : je classe automatiquement mon courrier dans des dizaines de boîtes (le classement est fait avec procmail, je passerais peut-être un jour à Sieve, cf. RFC 5228). Je tiens à avoir les boîtes en local, à la fois pour pouvoir travailler sans connexion (ah, les tarifs d'itinérance en 3G...) et pour pouvoir utiliser les outils d'Unix pour, par exemple, chercher dans ces boîtes. Gmail n'est donc pas envisageable.
Avec tant de boîtes, comment savoir lesquelles ont du courrier non
lu ? J'utilisais auparavant gbuffy. Il
convient parfaitement à mon usage et affichait de manière très simple
de nombreuses boîtes :
Mais gbuffy n'est plus maintenu depuis longtemps. Il dépend de la très vieille version de la bibliothèque GTK+ libgtk1, désormais retirée de Debian (bogue #520441) et d'Ubuntu (bogue #478219 ; le PPA de secours ne marche même plus avec les Ubuntu récents).
Il existe des tas de programmes qui suivent les boîtes aux lettres (locales ou IMAP) et signalent des choses à l'utilisateur. Beaucoup ont un nom dérivé de l'antique biff. Mais je ne veux pas de notification, je veux de l'affichage. La plupart des « biff-like » sont mono-boîte (ou à la rigueur, pour quatre ou cinq boîtes). Je cherche un programme qui puisse afficher des dizaines de boîtes.
Alors, par quoi puis-je remplacer gbuffy ?
Des idées ? Des suggestions ? Ou bien dois-je changer radicalement ma façon de gérer le courrier (en convertissant des années d'archives) ?
Actuellement, je teste le patch «
sidebar » de mutt,
disponible et documenté en http://www.lunar-linux.org/index.php?option=com_content&task=view&id=44
. On
peut l'obtenir sur Debian et
Ubuntu par le paquetage
mutt-patched
. Je le configure ainsi dans le
.muttrc
, pour qu'il connaisse la liste des boîtes :
mailboxes `display-mailboxes`
où le programme display-mailboxes
est disponible. C'est loin d'être
convaincant : mutt, comme Thunderbird, affiche la liste des boîtes
linéairement (contrairement à Gbuffy qui le fait en deux dimensions),
ce qui ne convient pas aux longues listes. Et passer de la
sidebar à la vue normale n'est pas naturel, je trouve.
Première rédaction de cet article le 27 novembre 2011
Le 26 novembre, à Toulouse, j'ai eu le plaisir de faire un exposé lors de l'Ubuntu Party (organisée par Toulibre) sur le sujet indiqué dans le titre.
L'accroche était « Que se passe-t-il derrière ma box ? Qui dirige l'Internet ? Qu'est-ce qu'un Tier 1 ? Pourquoi Comcast et Level 3 s'accusent-ils réciproquement de « patate chaude » ? À quoi sert un point d'échange ? BGP fait-il mal ? Pourquoi un maladroit au Pakistan peut-il bloquer YouTube sur toute la planète ? Cet exposé sera consacré au fonctionnement technique d'Internet : le rôle des différents acteurs, les techniques utilisées pour synchroniser le routage, et les mécanismes qui font que, vaille que vaille, l'infrastructure marche. ».
Voici les supports de présentation produits à cette occasion : en
PDF adaptés à la vue sur écran, en
PDF adaptés à l'impression, et leur source en format LaTeX/Beamer. On peut
également les télécharger à partir du site
de Toulibre. Enfin, une vidéo est disponible, au format WebM, en http://www.toulibre.org/pub/2011-11-26-capitole-du-libre/video/bortzmeyer-comment-internet-fonctionne.webm
(attention, 172 Mo).
Première rédaction de cet article le 23 novembre 2011
Dernière mise à jour le 24 novembre 2011
Le 23 novembre, à Toulouse, j'ai eu le plaisir de faire un exposé lors des JRES sur le sujet « Des clés dans le DNS, un successeur à X.509 ? ».
Voici les documents produits à cette occasion :
L'article est sous GFDL (JRES n'ajoute pas de contraintes).
Depuis, le mécanisme DANE de remplacement de X.509 a été normalisé dans le RFC 6698, en août 2012.
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 6724 (et son prédécesseur, le RFC 3484, qui est encore la référence). 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 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. Le RFC 6731 normalise les nouvelles règles de sélection pour les serveurs DNS.
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 :
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.
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és 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).
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'OMA (« Mobile 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.
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. (Un bon article de synthèse est « Video codecs: The ugly business behind pretty pictures ».)
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, dus 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...
Première rédaction de cet article le 9 novembre 2011
Je présente dans cet article le service EC2 d'Amazon, pas seulement parce que j'en suis assez content, mais aussi parce que cette offre ne m'a pas semblé claire du tout lorsque j'ai commencé à l'évaluer, puis à l'utiliser, et que cela vaut donc la peine d'écrire ce que j'ai compris.
Première rédaction de cet article le 7 novembre 2011
Ce lundi 7 novembre 2011, vers 14h05 UTC, grande perturbation de la Force. Des tas de destinations deviennent injoignables sur l'Internet...
Voici par exemple un des graphes montrant une brusque diminution du
trafic (les heures sont des heures locales, pas UTC) : . À noter qu'un second
plantage, moins important, a eu lieu vers 15h30 UTC. On voit bien
l'effet des deux plantages sur ce graphique de DNSmon, qui montre l'impact de la
panne sur les serveurs DNS de
.fr
(le serveur
c.nic.fr
a été le plus impacté) :
Les utilisateurs ne peuvent plus travailler et plein de gens se plaignent.
Le problème venait d'une annonce BGP amusante qui a planté (et fait redémarrer) certains routeurs Juniper. Voir les annonces Twitter d'Absolight et de Neo. Cela ressemble donc beaucoup à des problèmes comme celui de l'attribut 99. Même si c'était plutôt Cisco qui nous avait habitué à ce genre de crashes de grand style.
La bogue ne touchait apparemment que la gamme MX, en version 10.2, 10.3 et certaines 10.4 de JunOS ; Raphaël Maunier me dit que les plus basses versions non affectées sont les 10.4R6, 11.1R4 et 11.2R1). La bogue est apparemment enregistré chez Juniper sous l'identificateur PSN-2011-08-327 (j'ai mis un lien vers un pastebin car le rapport officiel est réservé aux clients de Juniper ; à tout hasard, je garde une copie de PSN-2011-08-327 ici).
Une bonne façon de voir d'un coup d'œil qu'il y a eu une
grande perturbation BGP est de regarder les
archives de RouteViews du mois en cours (merci à Jared Mauch
pour la bonne idée). Pour novembre 2011,
regardez les fichiers updates.20111107.1415.bz2
et
updates.20111107.1430.bz2
(le nom du fichier
donne l'heure en UTC), vingt fois plus gros que la normale et montrant
une avalanche de mises à jour BGP suite au crash de tant de routeurs.
C'est l'occasion de se rappeler que la résilience de l'Internet est un combat permanent. Ainsi, l'un des opérateurs affectés, Level 3 a une part du marché telle que ses pannes entraînent la coupure d'une bonne partie de l'Internet.
Quelques ressources utiles pour les administrateurs réseaux confrontés à ce genre de problèmes :
Autres articles sur cette panne :
Auteur(s) du livre : Ouvrage collectif coordonné par Vecam
Éditeur : C&F Éditions
978-2-915825-06-0
Publié en 2011
Première rédaction de cet article le 5 novembre 2011
Qu'est-ce qu'il y a de commun entre la paysanne mexicaine qui réclame de pouvoir faire pousser des semences de maïs de son choix, le parisien qui télécharge de manière nonhadopienne un film qu'il ne peut pas acheter légalement, la chercheuse états-unienne qui veut publier ses découvertes sans enrichir un parasite qui vendra très cher le journal scientifique, le programmeur brésilien qui développe du logiciel libre, et l'industriel indien qui veut fabriquer des médicaments moins chers ? Tous veulent pouvoir utiliser librement le savoir issu des communs. Les communs, ce sont tous les biens, matériels ou intellectuels, qui n'ont pas été capturés par des intérêts privés et qui sont gérés ensemble. Cet ouvrage collectif fait le tour de la question pour les communs immatériels, ceux dont l'usage par l'un ne prive de rien les autres. À travers 27 articles très divers, un vaste tour d'horizon de la question.
Car même si les cinq personnages cités plus haut n'en sont pas forcément conscients, leur lutte est la même. Depuis des millénaires, il existe des biens gérés en commun. Contrairement à ce que prétendent des textes de propagande comme le fameux « Tragedy of the commons » de Garrett Hardin (d'ailleurs en général utilisé de manière très simplifié par des gens qui ne l'ont pas lu), ces biens communs fonctionnent depuis très longtemps. Mais ils ont toujours eu à faire face aux tentatives d'appropriation par les intérêts privés, tentatives en général appuyées sur la force, comme dans le cas des fameuses enclosures. Les luttes d'aujourd'hui s'enracinent donc dans un très ancien héritage. Le phénomène n'a fait que s'accentuer avec le temps, le capitalisme ne supportant pas la concurrence d'autres systèmes.
Les biens immatériels représentent un cas particulier : contrairement au champ de l'article de Garrett Hardin, leur usage ne les épuise pas et ils peuvent être copiés. Comme le notait Thomas Jefferson, « Celui qui reçoit une idée de moi ne me prive de rien, tout comme celui qui allume une chandelle à la mienne ne me plonge pas dans l'obscurité ». Cette particularité du savoir, des biens communs immatériels, ôte donc toute légitimité à la notion de « propriété intellectuelle ». La propriété avait été conçue pour un monde de rareté et de ressources vite épuisées et c'est une pure escroquerie que de faire croire qu'elle peut s'appliquer au savoir et à la création.
D'autant plus que, à l'époque de Jefferson, la propagation du savoir, limitée par son support matériel, était lente et difficile. Aujourd'hui, des inventions comme l'Internet font de cette propagation illimitée de la connaissance, qui était purement théorique au dix-huitième siècle, une réalité quotidienne. Essayer de limiter la distribution et le partage des biens immatériels, comme le tente par exemple l'industrie du divertissement, c'est « comme si Faust se mettait à chercher un remède contre l'immortalité » (Stanislas Lem dans Solaris).
Revenons au livre « Libres savoirs ». Coordonné par Vecam, il est publié sous la licence Édition Équitable (mais pas encore disponible en ligne). Comme tous les ouvrages collectifs, les articles sont inégaux. Je recommande à mes lecteurs celui d'Adelita San Vicente Tello et Areli Carreón, « Mainmise sur les semences du maïs dans son berceau d'origine », sur la lutte des paysans mexicains pour que les semences mises au point par eux depuis des millénaires ne soient pas confisqués par des compagnies privées qui leur revendront très cher le droit d'utiliser des semences que leurs ancêtres avaient créées.
À noter que tout n'est évidemment pas simple dans le monde des communs, monde traversé par de nombreux débats. Ainsi, Anupam Chander et Madhavi Sunder dans l'article « La vision romantique du domaine public », proposent une vision plutôt critique, en estimant par exemple que la liberté d'accès au savoir profite surtout à ceux qui sont organisés et équipés pour l'exploiter, et que dans des cas comme celui des savoirs traditionnels, permettre leur accès sous une licence libre risquerait de favoriser uniquement les riches sociétés étrangères. (Je n'ai pas dit que j'étais d'accord, hein, juste que j'appréciais que ce livre ne contenait pas que des articles gentillets et unanimistes sur les beautés des biens communs.)
Autre difficulté sur le chemin des communs, leur adaptation à d'autres cultures. Un des points forts du livre est que les auteurs ne sont pas uniquement des gens issus des pays riches. Il y a donc une vraie variété de points de vue et l'article d'Hala Essalmawi « Partage de la création et de la culture », est un passionnant compte-rendu des difficultés, mais aussi des succès, rencontrés lors de l'adaptation des licences Creative Commons au monde arabe. Traductions difficiles, références historiques différentes (les enclosures ont été un traumatisme historique, qui pèse toujours dans la politique dans les pays anglo-saxons ; trouver une référence équivalente n'est pas forcément facile).
Le livre se conclut sur un amusant texte d'Alain Rey sur l'histoire et l'étymologie du terme « commun », ses multiples sens (en français, « commun » est péjoratif dans « ce livre est d'un commun » mais laudatif dans « travaillons en commun sur ce projet »), ses passages dans la politique (communisme)... Une autre façon de voir que le concept de « biens communs » est ancien, mais pas du tout dépassé. Le partage, la gestion commune des biens, sont aujourd'hui plus nécessaire que jamais pour lutter contre l'appropriation des biens par une poignée d'intérêts privés. « Communs » va donc être le drapeau à brandir contre les ACTA, OMPI, COV, et autres HADOPI.
Sinon, un autre bon article (bien plus détaillé) sur ce livre est « Les communs du savoir. Le laboratoire de la globalisation responsable ».
Première rédaction de cet article le 2 novembre 2011
À la réunion OARC de Vienne, le 29 octobre 2011, Duane Wessels a présenté un très intéressant (et très technique) exposé « Tracing a DNS reflection attack » (voir ses transparents). L'exposé présente l'analyse d'une attaque déni de service utilisant les serveurs DNS de la racine. Son originalité est la découverte d'une méthode pour identifier l'origine de l'attaquant, alors même que ce dernier met des adresses IP mensongères dans ses paquets.
Cette méthode utilise le fait que la plupart des serveurs de la racine du DNS sont anycastés. Revenons d'abord sur l'attaque : il s'agissait d'une attaque par réflexion. Le méchant envoie une requête DNS à un serveur. Celui-ci répond à l'adresse IP (mensongère) que le méchant a mis dans la question... et frappe ainsi la victime (p. 3 des transparents).
Comment savoir qui est l'attaquant ? Dans les romans policiers, lorsque le méchant envoie une lettre, il laisse plein de traces dessus : empreintes digitales, ADN, type de papier utilisé, caractéristiques de l'imprimante... Rien de tel dans un paquet réseau. Les bits ne conservent pas l'ADN... Il faut donc suivre en sens inverse le flux de paquets, demandant à chaque opérateur d'analyser d'où vient l'attaque. C'est lent et cela dépend de la bonne volonté de tous les opérateurs sur le trajet.
Duane Wessels, en analysant l'attaque, a fait une observation. Les requêtes du pirate passent parfois subitement d'une instance d'un serveur racine à une autre. Par exemple, p. 17, on voit les requêtes vers le serveur K passer de l'instance du NAP à celle du LINX vers 0233, puis repasser au NAP vers 0240 (et re-changer encore par la suite). C'est le comportement normal de l'anycast : BGP a changé les routes (contrairement à ce qu'indique le transparent p. 19, ce n'est pas forcément suite à une panne) et l'attaque a suivi. L'idée de Duane a donc été : quel est le trafic qui a changé exactement au même moment ? Car ce trafic vient forcément du même point que l'attaque et a été routé pareil. Naturellement, au début, on trouve plein de suspects mais, sur des serveurs fortement anycastés comme ceux de la racine, la liste se réduit vite et on arrive à un seul AS (p. 22). Le trafic d'attaque vient donc de là (un hébergeur situé sur la côte Est des États-Unis).
À noter que les glitches BGP qui ont permis de repérer l'origine étaient accidentels. On pourrait imaginer d'appliquer cette technique volontairement, en modifiant les annonces BGP pour voir où le trafic se déplace, détectant ainsi l'attaquant qui se croyait bien caché.
Première rédaction de cet article le 2 novembre 2011
À la réunion RIPE de Vienne, le 1er novembre, Axel Pawlik, directeur du RIPE-NCC a fait un exposé sur « What to do about IPv4 Legacy Address Space » ou que faire du marais, ces préfixes IP alloués il y a de nombreuses années, bien avant que les RIR n'existent. Il y a de nombreux préfixes dont le statut juridique et opérationnel est... peu clair.
Aujourd'hui, normalement, les choses sont précises : les RIR comme le RIPE-NCC allouent des adresses IP à leurs membres, les LIR (Local Internet Registry), qui sont typiquement des opérateurs ou des FAI. Cette allocation se fait suivant tout un tas de règles soigneusement mises par écrit et qui détaillent le statut juridique des adresses allouées. Le tout est ensuite publié par le RIR (on y accède typiquement via whois), pour que chacun puisse savoir qui gère quelle partie de l'Internet, et comment le contacter.
Ça, c'est aujourd'hui. Mais autrefois, avant que les RIR existent, à l'époque où journalistes, avocats et ministres ne connaissaient pas l'Internet ? Eh bien, les adresses IP étaient allouées aussi, mais on gardait moins de paperasse, c'était souvent informel, et les organisations qui s'en occupaient ont parfois disparu et parfois changé de métier. Par exemple, en Europe, il y avait souvent des NIR (National Internet Registry) qui servaient d'intermédiaire entre RIR et LIR, et qui ont tous abandonné cette activité. Les adresses qu'ils géraient sont donc parfois dans un limbe juridico-politique. Quant aux titulaires de ces adresses IP du lointain passé, il ont souvent oublié eux-même qu'ils en avaient, ou alors ils ne s'occupent pas des enregistrements qui moisissent dans les bases des RIR, sans être jamais mis à jour. Ce sont ces préfixes alloués dans les temps pré-RIR qu'on appelle le marais (the swamp) ou, plus gentiment, l'héritage (the legacy).
Voyons quelques exemples (tous sont publics et n'importe qui peut
les voir en utilisant un client whois sur le serveur du RIPE-NCC,
whois.ripe.net
, ou encore via l'interface Web
dudit NCC, en https://apps.db.ripe.net/search/query.html
). D'abord, le
préfixe 192.134.12.0/24
. whois nous dit :
inetnum: 192.134.12.0 - 192.134.12.255 ... country: FR admin-c: KA774-RIPE tech-c: KA774-RIPE status: EARLY-REGISTRATION mnt-by: ERX-NET-192-134-12-MNT
Le statut EARLY REGISTRATION (alias ERX) est un des signes de
l'appartenance de ce préfixe au marais. Alloué dans un quasi-vide
juridique, 192.134.12.0/24
flotte... Le
mainteneur de l'objet (l'entité autorisée à apporter des
modifications) a été créé et mis automatiquement par le RIPE-NCC (les
anciens objets de la base RIPE n'avaient pas ce concept de
mainteneur). Est-il à jour, ainsi que les contacts ? whois nous dit :
address: FR ... e-mail: ASHK@frined51.bitnet
Une adresse de courrier électronique Bitnet, ça, c'est un collector... Ce réseau ne fonctionne plus depuis de longues années. Cela indique clairement que l'objet n'est pas géré. Il n'est pas non plus utilisé (aucune route n'y mène).
Autre exemple, 192.93.12.0/24
, qui illustre un
autre problème. Lors de la création des RIR, il n'a pas été évident
d'affecter chaque objet de la base à un RIR et certains l'ont été deux fois. Ce préfixe
contient donc des informations issues des deux bases. Non protégé, il
a été automatiquement verrouillé par le RIPE-NCC, comme l'indique la
présence du mainteneur RIPE-NCC-LOCKED-MNT
. Le
récupérer ne sera donc pas une mince affaire. Si on regarde le
contact, on constate des numéros de téléphone à huit chiffres, ce qui
indique bien l'absence d'entretien. Comme le précédent, ce préfixe ne
semble pas utilisé, il n'apparaît pas dans les tables de routage
publiques.
Enfin, dernier exemple, 192.93.232.0/24
est
alloué à une société qui semble avoir purement et simplement
disparu. (Il existe une société de même nom mais qui semble n'avoir
aucun rapport. Pour en être sûr, il faudrait une vraie enquête sur place, ce qui
dépasse les moyens et l'envie des RIR.)
Tous ces exemples concernent la France mais le marais est bien sûr présent dans tous les pays de l'OCDE (ceux qui ont été les premiers à se précipiter sur l'Internet et à obtenir des adresses IP).
Alors, après cette longue introduction, qu'a annoncé Axel Pawlik à
Vienne ? Le lancement d'une campagne pour, dans un premier temps,
améliorer l'enregistrement des informations sur ces préfixes du
marais. L'idée est d'encourager les titulaires de ces adresses à enfin
mettre à jour les informations contenues dans la base du RIR. Le
RIPE-NCC, après des années d'inaction sur ce sujet, a fait les choses
en grand, sorti une jolie brochure « Legacy space in the
RIPE-NCC service region », annoncé la création d'une équipe
dédiée, joignable par courrier à legacy@ripe.net
,
et appelé sur
son site Web à nettoyer le marais.
Pourquoi cette soudaine activité ? Parce que l'épuisement des adresses IPv4 transforme le marais en or : ces adresses non gérées et souvent non utilisées deviennent tout à coup très valables. Comme l'a dit clairement Pawlik, mêlant la carotte (« Show you are a good Internet citizen ») et le bâton, ces adressses manifestement abandonnées sont des cibles tentantes pour des détourneurs... Pawlik n'a pas explicitement dit que ces adresses pourraient être récupérées par le RIPE-NCC un jour mais on peut penser que c'est une étape ultérieure possible.
Cela ne veut pas dire que tout soit rose si on « régularise » sa situation. Le RIPE-NCC, émanation des opérateurs réseaux, peut aussi en profiter pour « suggérer » qu'on confie désormais ses adresses à un LIR, transformant ainsi des adresses qui étaient, de fait, indépendantes du fournisseur en adresses qui « appartiendront » désormais à un opérateur.
Les conseils que je donnerai donc aux gens qui sont titulaires de préfixes IP du marais :
À noter que l'alerte avait déjà été donnée par
exemple sur la liste IP. Si vous voulez fouiller vous-même dans
la base du RIPE-NCC, un outil pratique est leur recherche plein
texte. La base est également téléchargeable en
FTP sur ftp.ripe.net:/ripe/dbase
.
La question se pose aussi dans les autres régions et, en Amérique du Nord, la NSF (qui gérait le réseau académique états-unien qui formait une bonne partie de l'Internet à cette époque) affirme que les adresses IP allouées à cette époque appartiennent bien à leurs titulaires et que le RIR nord-américain, ARIN, créé bien après, n'a aucun droit de les réclamer.
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 :
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 » :
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étadonné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étadonné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étadonnées globales (le format
XRD permet également de s'en servir pour des
métadonné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, et le
RFC 5785 a été depuis remplacé par le RFC 8615.)
Pour le client, par exemple un navigateur Web, récupérer les
métadonné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étadonné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étadonné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 (RFC 7033) 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
est normalisé dans le RFC 8615) 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étadonnées à une
ressource (par exemple les en-têtes HTTP comme
l'en-tête Link:
du RFC 8288), sauf à utiliser des trucs contestables comme de
considérer que /
, la racine du site, désigne tout
le site.
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.example.com
,Trois scénarios sont ensuite décrits dans la section 3, le œur de ce RFC :
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 retrouvent pas exactement dans le RFC 6698 sur le protocole qui a quatre types 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 :
Le protocole qui met en œuvre ce cahier des charges a été normalisé en août 2012 dans le RFC 6698.
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.
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 pour l'accès au stockage en ligne, notamment pour le pair à pair. 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 :
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 niveau 3 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 9171), 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 7230). 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 4.3.5 du RFC 7231) 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 7143. 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 8881) 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.
Première rédaction de cet article le 25 octobre 2011
À la réunion DNSEASY/SSR d'octobre 2011 à Rome, une intéressante table ronde portait sur le filtrage du DNS. C'est l'occasion de faire le point sur cette pratique. La réunion ne cherchait pas à obtenir un accord unanime, ni des solutions magiques, mais au moint à définir et délimiter le phénomène.
Comme la réunion se tenait sous la règle de Chatham House, je ne dirai pas ici qui a dit quoi.
Donc, le filtrage DNS est cette pratique qui consiste à substituer aux réponses normales des vrais serveurs DNS des mensonges, de façon à empêcher un utilisateur de communiquer avec les serveurs du domaine filtré. Il est utilisé en entreprise (pour empêcher les employés de regarder Facebook, par exemple) et par les États.
Les points étudiés étaient :
Sur le premier point, l'aspect politique (au sens large), l'accord s'est fait sur l'importance de distinguer qui demande le filtrage. Il peut y avoir :
google-analytics.com
sur mon résolveur car
je ne veux pas laisser de trace de ma navigation chez Google). Le
consensus est que c'est normal, de même qu'un citoyen a le droit de
refuser de lire des livres dont les idées ne lui plaisent pas.Bien sûr, il y a des tas de zones grises. Ainsi, lorsque OpenDNS prétend que leur système est opt in et donc politiquement correct, ils oublient de préciser que, si l'administrateur réseaux d'une école choisit de configurer le relais DNS pour interroger OpenDNS, les enseignants vont être filtrés sans l'avoir demandé... Même chose pour les enfants, mais ils sont mineurs donc le problème est encore différent. À propos d'enfants, un participant a demandé si le cas de l'entreprise était analogue à celui de la famille (où les parents peuvent décider de filtrer ce que peuvent voir leurs enfants) ; les employés sont-ils majeurs ? (En système capitaliste, la réponse est clairement non, l'entreprise n'est pas une démocratie.)
Le cas du filtrage par un prestataire est pour moi nettement un problème de violation de la neutralité du réseau. Toutefois, beaucoup de participants au débat ont refusé de poser le problème en ces termes car ce débat sur la neutralité est très chargé. Il pose pourtant les mêmes questions : information du client (les FAI qui filtrent, par exemple le port 53, ne le documentent jamais), et possibilité réelle de changer (la concurrence est souvent insuffisante, par exemple parce qu'il n'existe pas de FAI alternatif, ou bien tout simplement tous les FAI se sont mis d'accord, comme pour les opérateurs mobiles en France qui interdisent tous la voix sur IP).
Certains prestataires se défendent en affirmant que ce filtrage est demandé (ou en tout cas accepté) par la grande majorité de leurs clients (comme disait Camus, « Quelque chose en leur âme aspire à la servitude »). Même si c'est vrai (tout le monde parle de Mme Michu, mais personne ne lui demande jamais son avis), l'opinion dominante était que cela ne change rien : si 0,1 % des clients ne veulent pas de filtrage, ils doivent pouvoir y arriver, par exemple par un système d'opt-out clair et gratuit. Notez, opinion personnelle, que cela finirait par créer un Internet à deux vitesses, un filtré pour la majorité des citoyens, et un libre pour les 0,1 % de geeks qui cliqueront sur l'option « I know what I do, I understand that I may lose hair, be hacked and see awful things, and I accept the responsability » pour désactiver le filtrage.
Un autre cas présenté comme acceptable a été celui d'un FAI qui se vante de fournir du filtrage, comme étant un service. Puisqu'on était à Rome, l'intervenant a pris comme exemple un FAI catholique affirmant qu'il filtrait l'accès à tout ce qui n'était pas approuvé par le Vatican. Le débat sur cette offre est rigolo, mais cet exemple est purement théorique. Comme je l'ai indiqué, les filtreurs n'annoncent jamais qu'ils le font, et un tel FAI n'existe pas (quoiqu'il trouverait peut-être des clients au fin fond des États-Unis).
Une anecdote révélatrice ici : la conférence se tenait dans les locaux de la Poste, qui pratique un filtrage sino-saoudien. Tout utilisateur doit être nommément identifié et l'Internet est peu accessible : seuls les ports 80 et 443 sont ouverts (le port 53 est filtré, donc pas question de contourner les résolveurs DNS officiels). Le port 443 a un système de DPI qui envoie des resets TCP dès qu'il détecte quelque chose qui n'est pas du TLS (par exemple du SSH). Or, quelles que soient leurs opinions sur la légitimité ou non du filtrage (on est dans les locaux de la Poste, on doit accepter leurs règles), la totalité des participants, au lieu d'écouter les exposés, a passé l'essentiel de la première matinée à mettre au point et à déployer (au besoin en créant des comptes pour les voisins) des systèmes de contournement. Pour les gens qui défendaient la légitimité du filtrage, c'était un bonne illustration du principe « le filtrage, c'est pour les autres ».
Le deuxième point étudié concerne l'efficacité du filtrage. S'il
attente aux libertés, est-il au moins efficace ? (Et, question encore
plus vicieuse, cette efficacité justifie-t-elle son coût ?) La question est
complexe. Bien sûr, pour une minorité de
geeks, la question ne se
pose pas. Ils trouveront toujours, et souvent assez facilement, un
moyen de contourner le filtrage (comme l'a montré l'affaire
Copwatch où les miroirs de
secours sont apparus avant même le jugement). Mais cela
s'appliquera-t-il aux utilisateurs moins avertis, aux M. et Mme
Toutlemonde ? Peut-être pas (sauf si quelqu'un fait un logiciel simple
qui met en œuvre les mesures d'évitement). Notez bien que le
gouvernement répressif ne cherche pas forcément une efficacité à
100 %. Qu'une poignée de types dans leur garage contournent le filtre
n'est pas forcément un problème. D'autant plus que, souvent, le
gouvernement ne cherche pas d'efficacité du tout, il veut simplement
faire du théâtre et donner l'impression qu'il agit.
Dans le cas où le filtrage est « auto-infligé » (par exemple parce qu'un utilisateur essaie de se prémunir contre la possibilité d'une vision accidentelle d'images qui le choqueraient), la question de l'efficacité ne se pose pas. Celui qui a voulu le filtrage ne va évidemment pas essayer de le contourner. Dans le cas où le filtrage est réellement mis en place pour protéger l'utilisateur (par exemple contre le malware), l'efficacité a des chances d'être assez bonne, tant que le filtrage n'énerve pas l'utilisateur, le motivant assez pour chercher un contournement. Et dans le cas d'un filtrage obligatoire par l'État ? Si l'État n'est pas trop méchant, l'efficacité du filtrage est faible. On a bien vu, selon un classique effet Streisand, que Copwatch était beaucoup plus lu après la plainte de Guéant qu'avant, où ce site était quasiment inconnu. Si l'État est prêt à cogner, les choses sont différentes. Si on contourne moins le filtrage en Chine qu'en France, c'est parce que le gouvernement chinois a d'autres moyens de persuasion à sa disposition. C'est d'ailleurs une leçon classique en sécurité, bien illustrée par un dessin de XKCD.
Comme la grande majorité des participants était composée de technophiles, la question des liens entre le filtrage DNS et DNSSEC était inévitable. En effet, le filtrage DNS dans les résolveurs va invalider les signatures DNSSEC et sera donc détecté. À première vue, le filtrage va donc en opposition directe à la tentative de sécurisation du DNS qu'est DNSSEC.
En fait, le problème est plus complexe que cela. D'abord, si le
filtrage est fait au niveau du registre (comme lors des cas
des saisies ICE), DNSSEC ne protégera pas. Ensuite, DNSSEC ne gènera
pas si le censeur veut uniquement bloquer l'accès : un
SERVFAIL
(parce que la validation DNSSEC aura
échoué) est aussi bon pour lui qu'un NXDOMAIN
(d'ailleurs, un des mécanismes de censure pourrait être de bloquer les
réponses, au lieu de les remplacer par une réponse mensongère). Ce
n'est que si le censeur voulait rediriger discrètement vers une autre
destination que DNSSEC le gênerait. Mais il gênerait aussi
l'utilisateur : le domaine serait inaccessible. DNSSEC permet de
détecter la censure, pas de la contourner.
Néanmoins, DNSSEC est utile : dans beaucoup de pays, le gouvernement ne veut pas qu'on sache qu'il censure (ou, en tout cas, il essaie de rendre plus difficile la preuve) et, même s'il l'avoue, la liste des domaines censurés est en général secrète, ce qui permet de s'assurer que les citoyens ne pourront pas vérifier sa légitimité. DNSSEC permet d'être sûr qu'il y a bien filtrage, et on peut imaginer des logiciels qui utiliseront cette connaissance pour passer automatiquement à un plan B (un navigateur Web pourrait par exemple rereouter les requêtes pour ce domaine via Tor, s'il est sûr que c'est bien un problème de filtrage).
Et la détection qu'offre DNSSEC pourra servir aux opérateurs pour
dégager leur responsabilité. « Vilain opérateur du
.com
, vous avez supprimé
example.com
! » « Ah non, regardez les signatures
DNSSEC, ce n'est pas nous, c'est un Homme du
Milieu, sans doute l'opérateur du résolveur. »
À noter aussi que, si on imagine un pays dictatorial qui veut faire du filtrage, mais n'a pas le contrôle de tous les registres (contrairement au gouvernement états-unien), et choisit donc d'opérer dans les résolveurs, mais veut qu'on puisse quand même faire du DNSSEC, il existe toujours des solutions techniques (par exemple forcer les utilisateurs, dans ce pays, à utiliser une clé DNSSEC de la racine qui soit contrôlée par le gouvernement).
Quatrième point étudié pendant l'atelier, les conséquences techniques du filtrage. En fait, la discussion a un peu tourné court. Car, contrairement à un argument parfois entendu, le filtrage ne casse pas en soi le DNS. Il le rend simplement plus lent (traitement supplémentaire) et plus fragile (introduction d'un nouveau composant, qui peut avoir des problèmes). Bref, il peut y avoir des arguments techniques contre le filtrage, mais ils ne sont pas décisifs. Notons tout de même que certains gouvernements font preuve d'une grande schizophrénie en encourageant des travaux visant à améliorer la résilience de l'Internet, tout en prônant ou en imposant le filtrage, qui va certainement diminuer cette résilience.
Enfin, cinquième et dernier point de la discussion, les conséquences non techniques. Elles sont multiples :
.ru
ou tout
.cn
) ou par accident.Compte-tenu de ces différents points, quels sont les scénarios possibles (je n'ai pas dit « souhaitables ») pour le futur de DNSSEC ? La discussion en a identifié trois :
Ah, et puis une dernière chose, qui a fait l'objet d'amusantes
discussions. DNSSEC ne permet pas de distinguer facilement du filtrage d'une
attaque. Si la recherche de l'adresse de
www.example.com
fait un
SERVFAIL
(Server Failure,
indication par le résolveur DNS qu'il y avait un problème), comment
discerner si example.com
a été bloqué par le
résolveur (sur demande de l'ARJEL ou d'un autre
censeur) ou bien si un attaquant essaie de détourner le trafic vers
son propre site ?
Une des suggestions était donc, en cas de censure, de renvoyer un
enregistrement spécial, qui indique qu'il y a eu censure. Le résolveur
pourrait interroger sans validation (avec dig,
c'est l'option +cd
) et voir ainsi ce qui s'est
passé, pour annoncer à l'utilisateur qu'il a été filtré pour son bien.
J'avais suggéré, en cas de requête de type A
(adresse IPv4), de renvoyer la valeur spéciale
1.9.8.4
. Mais, bon, le préfixe englobant est déjà
alloué .
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ébogage 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ébogage 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) :
no-export
). La recommandation de
ce RFC s'applique à tous les nœuds, locaux ou globaux,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 :
LOC
du RFC 1876, peut-être en les attachant au nom obtenu par la
requête NSID),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
.
Pour avoir un autre point de vue, l'ISC a expliqué le fonctionnement de l'anycast chez eux, une explication détaillée de la supériorité de leur système, ainsi que leur liste de peerings.
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.
Première rédaction de cet article le 22 octobre 2011
Il y a déjà eu des tas de romans où un méchant quelconque arrivait à prendre le contrôle des esprits, et à faire faire ce qu'il voulait à ses victimes transformées en zombies. Le problème, avec les progrès de la science, est qu'il est possible que nous soyions tout proches d'une réalisation effective de cette idée. C'est le thème du roman « Les soldats de l'or gris » de Sébastien Bohler, où la CIA et les services secrets chinois vont essayer d'être les premiers à profiter d'une récente percée scientifique...
L'opération « Or gris » du titre fait bien sûr référence à la matière grise du cerveau. On peut faire plein de choses de cet organe si on sait le contrôler. Dans le roman (mais aussi apparemment dans la réalité), la CIA a déjà tenté plusieurs fois ce contrôle, comme dans le fameux projet MK-Ultra. Tous ces essais ont échoué. Mais le développement des nanotechnologies, associé à celui de la cartographie cérébrale, permet d'aborder le problème différemment. Si on arrive à placer certains anticorps sur des nanobilles, et à les envoyer au bon endroit du cerveau où elles libéreront les anticorps, peut-on convaincre un espion de changer de camp ? Un soldat de ne plus avoir peur de rien ? Une femme de dire oui à une proposition sexuelle (c'est sérieux, c'est même en note de pied de page dans le roman, lisez donc « The role of the anterior cingulate cortex in women's sexual decision making »).
Dans le roman, c'est possible. Dans la réalité... je ne sais pas trop, mais l'auteur est neurobiologiste et il connait le sujet. Si les informaticiens ricaneront en lisant les efforts de la CIA pour pirater l'informatique chinoise, rendus difficiles par le fait que, raconte un agent chinois, « Nous sommes à même de percer leurs défenses informatiques, qui reposent sur des codes-sources accessibles comme Microsoft ou [sic] Windows, alors que notre Kylin a un code confidentiel », l'amateur se régalera des descriptions de la biologie du cerveau, des efforts scientifiques dans ce domaine, et du fonctionnement du milieu scientifique.
Dans le récit, un jeune chercheur arrive à maîtriser les nanobilles comme personne avant lui... et le sujet de la manipulation du cerveau, qui concernait surtout les philosophes, devient d'actualité.
Si le roman démarre maladroitement, tout le reste est passionnant, avec tous les ingrédients d'un roman d'espionnage, plus les nouvelles possibilités qu'offrent le contrôle du cerveau (non, je ne dévoilerai pas ce qu'on peut faire, lisez le roman, vous ne le lâcherez pas.)
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 :
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.
Première rédaction de cet article le 15 octobre 2011
Une des faiblesses de la sécurité de l'Internet est que le mécanisme d'annuaire principal, le DNS, n'est pas très sécurisé. Il est trop facile de tromper un serveur DNS en lui injectant de fausses informations (faille dite Kaminsky). Mais il y a pire : souvent, c'est le serveur DNS mis à la disposition de l'utilisateur, par le FAI ou par le service informatique local, qui le trompe. Une solution technique existe, à ces deux problèmes : DNSSEC. Mais pour que DNSSEC protège M. Toutlemonde, les vérifications que permet ce protocole doivent être faites sur la machine de M. Toutlemonde, la seule en qui il peut avoir un peu confiance. C'est ce que permet le nouveau logiciel dnssec-trigger.
Depuis que DNSSEC existe (sa version actuelle a été normalisée dans le RFC 4033), il y a un débat sur l'endroit où doit se faire la validation, c'est-à-dire la vérification, par des calculs cryptographiques, que l'information reçue est bien authentique. Comme cette validation nécessite des calculs complexes et, jusqu'à la signature de la racine et de nombreux TLD, vers 2010-2011, nécessitait une configuration complexe, il semblait logique de faire la validation sur les résolveurs DNS que tout FAI, tout réseau local, met à la disposition de M. Toutlemonde. Le problème est que ces résolveurs sont souvent les premiers à mentir, comme on l'a vu de nombreuses fois, l'une des dernières étant l'affaire Earthlink. Bien que ce soit une violation claire de la neutralité de l'intermédiaire, d'autres FAI se livrent à ce genre de pratiques.
Il reste donc à faire la validation sur la machine de M. Toutlemonde. Pour un PC moderne, les calculs cryptographiques nécessaires ne représentent qu'une tâche bien légère (cela peut être différent pour un smartphone). Mais la validation directement sur le PC de l'utilisateur pose deux problèmes : elle nécessite l'installation et la configuration correcte d'un logiciel supplémentaire (même si cela ne prend que quelques minutes, l'expérience prouve que c'est beaucoup trop difficile pour M. Toutlemonde) et, si tout le monde en faisait autant, les serveurs DNS souffriraient sous la charge accrue. En effet, comme il n'y aurait plus de cache partagé (rôle que jouent aujourd'hui les serveurs résolveurs des FAI, qui gardent en mémoire la réponse aux questions déjà posées), les serveurs des différentes zones DNS recevraient bien plus de requêtes.
Cette question est connue depuis un certain temps (voir par exemple une discussion technique approfondie en 2011). Mais la nouveauté est qu'on a désormais un logiciel qui résout ces deux problèmes. dnssec-trigger est un outil génial. Développé aux NLnetLabs, partiellement financé par l'AFNIC, il va permettre de donner la puissance de DNSSEC à M. Michu, en lui permettant de valider sur sa machine, tout en n'écroulant pas les serveurs de l'AFNIC (ou les autres serveurs faisant autorité) sous la charge, comme cela se produirait si chacun avait un résolveur normal sur sa machine.
Comment fonctionne dnssec-trigger ? C'est un logiciel qui tourne sur plusieurs systèmes d'exploitation, plutôt ceux qui sont michuiens ou toutlemondesques (Ubuntu, Fedora, Microsoft Windows, Mac OS). Il s'intègre au système de gestion du réseau de ces systèmes (les programmeurs apprécieront l'exploit que cela représente, vue la variété de ces systèmes), par exemple NetworkManager, et, lorsque celui-ci lui signale une nouvelle connexion réseau, il teste les résolveurs indiqués (le réseau les indique typiquement avec DHCP). Pourquoi les tester ? Parce que, dans la nature, on trouve de tout sur les réseaux. Idéalement, les résolveurs devraient fonctionner. Mais très fréquemment (surtout dans les réseaux pourris fournis par les hôtels, les gares, etc), le résolveur est sérieusement cassé : il bloque DNSSEC, ou bien il bloque les réponses plus grandes que 512 octets (ce qui revient quasiment à bloquer DNSSEC) ou carrément il bloque toutes les requêtes qui utilisent EDNS0 (RFC 6891). Ces résolveurs ne peuvent pas aider l'utilisateur, ils ne sont qu'un obstacle. dnssec-trigger tente alors de joindre directement les serveurs faisant autorité (ce qui marche si le réseau ne bloque pas le port 53). Si cela échoue, il essaie plusieurs techniques (expérimentales et pas forcément présentes dans la version actuelle du logiciel) comme de joindre un résolveur public qui marche, ou comme de tunneler les requêtes sur le port 443. Ces techniques de contournement sont bien connues des hackers mais l'intérêt de dnssec-trigger est de les automatiser pour M. Michu.
Une fois ces tests terminés, dnssec-trigger reconfigure au vol le résolveur Unbound (dnssec-trigger pourrait aussi marcher avec BIND, qui a les mêmes capacités mais Unbound est meilleur sur la plupart des plans ; notez que la version Windows de dnssec-trigger inclus Unbound) de façon à :
.fr
sont déjà
surdimensionnés, pour faire face au risque de
DoS distribuées).Avec ce logiciel, on aura donc enfin le beurre et l'argent du beurre. On pourra donc valider en local, sur sa machine, sans pour autant massacrer les serveurs DNS sous les requêtes. Mais je parle au futur car dnssec-trigger est encore en béta-test. Il faut des volontaires pour le tester sur plein de réseaux différents (surtout les pénibles, aéroports, hôtels, etc). Ensuite, il reste à l'intégrer dans les systèmes d'exploitation, pour que M. Toutlemonde n'ait rien à installer (les discussions ont déjà commencé avec Fedora).
Après cet appel au peuple, un peu de technique. dnssec-trigger a
quatre parties, un démon qui doit tourner en
permanence, dnssec-triggerd
, un composant
enregistré auprès du gestionnaire de réseau (NetworkManager sur Ubuntu, le script
d'installation le détecte en général seul et se débrouille) pour être
prévenu des changements de connectivité, un logiciel de contrôle,
dnssec-trigger-control
et bien sûr le résolveur
validant, actuellement Unbound (toute la cuisine de communication
sécurisée entre dnssec-trigger et Unbound, incluant des
certificats X.509 pour l'authentification, est
faite automatiquement à l'installation de dnssec-trigger). On peut
regarder l'état du système de résolution :
% dnssec-trigger-control status at 2011-10-15 16:27:42 cache 212.27.40.240: OK cache 212.27.40.241: OK state: cache secure
Ici, on voit que dnssec-trigger a été informé (par NetworkManager) que le réseau local a deux résolveurs, qu'ils ont été testés et trouvés corrects, et que dnssec-trigger est donc heureux (secure) et utilise un cache. C'était sur un réseau local connecté à Free. On a eu de la chance ici car les deux résolveurs de Free sont composés de plusieurs machines ayant des configurations différentes (!) et il est fréquent qu'une des adresses ne gère pas DNSSEC. Ici, ce n'est heureusement pas le cas, dnssec-trigger a donc indiqué à Unbound d'utiliser ces deux résolveurs, ce qu'on peut vérifier, en demandant à Unbound :
# unbound-control forward 212.27.40.241 212.27.40.240
Et tcpdump nous le confirme :
17:06:26.848768 IP 192.168.2.26.37031 > 212.27.40.241.53: 31541+% [1au] A? ubuntu-archive.mirrors.proxad.net. (62) 17:06:26.871841 IP 212.27.40.241.53 > 192.168.2.26.37031: 31541 1/2/3 A 88.191.250.131 (146)
Les requêtes DNS (ici une demande de l'adresse
IPv4 de
ubuntu-archive.mirrors.proxad.net
) sont bien
envoyées au forwarder,
212.27.40.241
(qui pourra répondre à partir de
son cache), et pas directement aux serveurs
faisant autorité.
Si l'un des résolveurs indiqués ne gère pas DNSSEC (ici,
192.134.4.163
est un BIND
avec la configuration dnssec-enable no;
),
dnssec-trigger utilise les autres :
% dnssec-trigger-control status at 2011-09-20 10:01:09 cache 192.134.4.163: error no RRSIGs in reply cache 192.134.4.162: OK state: cache secure
On est quand même secure, seul
192.134.4.162
sera utilisé comme
forwarder.
dnssec-trigger sait gérer les annonces RA (Router Advertisment) du RFC 8106 et peut donc utiliser des résolveurs IPv6. Ici, toujours chez Free :
% dnssec-trigger-control status at 2011-10-15 17:04:32 cache 2a01:e00::1: OK cache 2a01:e00::2: error no EDNS cache 212.27.40.240: OK cache 212.27.40.241: OK state: cache secure
Un des deux résolveurs IPv6 ne gère pas EDNS0 (je l'ai dit, c'est un problème courant chez Free) donc dnssec-trigger n'utilise que les résolveurs qui marchent :
# unbound-control forward 212.27.40.241 212.27.40.240 2a01:e00::1
tcpdump nous confirme que la résolution se passe bien en IPv6 (ici,
demande de la clé de .org
,
nécessaire pour valider le nom www.bortzmeyer.org
qui avait été demandé) :
17:07:13.651758 IP6 2a01:e35:8bd9:8bb0:1a03:73ff:fe66:e568.31040 > 2a01:e00::1.53: 54769+% [1au] DNSKEY? org. (32) 17:07:13.771831 IP6 2a01:e00::1.53 > 2a01:e35:8bd9:8bb0:1a03:73ff:fe66:e568.31040: 54769 6/0/1 DNSKEY, DNSKEY, DNSKEY, DNSKEY, RRSIG, RRSIG (1334)
Jusqu'à présent, nous n'avons vu que des résolveurs assez sympa. Mais, lorsqu'on se promène de hotspot en hotspot, on tombe sur bien pire. Ici, aucun des résolveurs officiels ne gère DNSSEC :
% dnssec-trigger-control status at 2011-10-07 09:04:06 authority 128.63.2.53: OK cache 10.150.6.1: error no RRSIGs in reply cache 10.150.2.1: error no RRSIGs in reply state: auth secure
Mais dnssec-trigger a vu qu'il pouvait parler directement aux serveurs
faisant autorité (il indique avoir testé avec
128.63.2.53
, un des serveurs de la
racine, le H). On est donc bien secure
mais l'indication cache a été remplacée par
auth. Désormais, le seul cache est celui d'Unbound
sur la machine.
Pire, voici un hotspot qui ne laisse même pas parler aux serveurs faisant autorité (ici le serveur racine K) :
% dnssec-trigger-control status at 2011-10-07 09:02:21 authority 193.0.14.129: error no EDNS cache 192.168.16.1: error no EDNS state: nodnssec insecure
dnssec-trigger affiche alors un avertissement disant qu'il ne sait pas faire (dans cette version, qui n'a pas encore les techniques de contournement) et laisse le choix à l'utilisateur de se connecter de manière non sûre (ce qui a été choisi ici) ou bien de se déconnecter. Notez qu'on est en sécurité dans ce dernier cas, et dnssec-trigger affichera secure... :
% dnssec-trigger-control status at 2011-10-07 09:06:49 no cache: no DNS servers have been supplied via DHCP state: disconnected secure
Un cas beaucoup plus vicieux est celui d'un hotspot où les résolveurs ne gèrent pas DNSSEC, mais on a accès aux serveurs faisant autorité, sauf que le portail captif ne marche pas si on n'utilise pas les résolveurs officiels...
at 2011-10-07 09:08:46 authority 193.0.14.129: OK cache 10.150.6.1: error no RRSIGs in reply cache 10.150.2.1: error no RRSIGs in reply state: auth secure
dnssec-trigger utilise alors l'accès direct aux serveurs faisant autorité, qui marche (vérifié ici avec dig) :
; <<>> DiG 9.7.3 <<>> @193.0.14.129 DNSKEY . ... ;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ... ;; ANSWER SECTION: . 172800 IN DNSKEY 256 3 8 ...
Mais dès qu'on essaie d'aller sur le Web, on
est redirigé d'autorité vers un portail captif nommé
bsc-lsh3.essec.fr
et on reçoit un message
d'erreur disant qu'il n'existe pas. En effet, ce nom n'est pas présent
dans le vrai DNS :
; <<>> DiG 9.7.3 <<>> A bsc-lsh3.essec.fr ... ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 28170
mais il l'est dans les serveurs officiels du hotspot :
... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2500 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ... ;; ANSWER SECTION: bsc-lsh3.essec.fr. 28800 IN A 194.254.137.123
Seule solution, régler le problème à la main. dnssec-trigger fournit un GUI pour le faire, mais on peut aussi utiliser la ligne de commande :
... On dit à dnssec-trigger d'utiliser temporairement les résolveurs officiels ... % dnssec-trigger-control hotspot_signon ... On se connecte au portail captif, acceptant les conditions d'utilisation ... ... On re-teste ... % dnssec-trigger-control reprobe ... Et cette fois, on a bien du DNSSEC ...
Pour la petite histoire, voici quel était le cahier des charges original de dnssec-trigger, ceci était le compte-rendu d'une série de réunions informelles et de discussions en ligne.
My wishlist for Xmas: an easy (easy as in "works for M. Smith or M. Jones") way to have an Unbound resolver which:
À propos d'anglais, si vous préférez lire en anglais, ou simplement si vous voulez voir davantage de copies d'écran, Jan-Piet Mens a écrit sur le même sujet en anglais. Il y a également l'exposé d'Olaf Kolkman au RIPE 63. Voir aussi L'article de Dmitry Kohmanyuk (mais son titre contient une grosse erreur : le principe de dnssec-trigger est justement de tout faire pour éviter de demander aux serveurs faisant autorité).
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 :
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 :
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 :
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.
First publication of this article on 9 October 2011
I just installed Ubuntu on a Dell Latitude E6410 laptop. This article documents a few things about this machine and the issues I had.
Première rédaction de cet article le 9 octobre 2011
Ce n'est jamais évident, pour le mainteneur d'un programme, d'avouer qu'il n'assume pas et qu'il doit passer la main. Mais c'est le cas pour moi en ce qui concerne la maintenance d'echoping, un petit utilitaire de test réseau, que je n'ai clairement pas le temps et l'attaque de maintenir.
echoping est un logiciel libre qui permet de tester les performances des applications distantes en envoyant des requêtes (plusieurs protocoles sont gérés) et en affichant le temps écoulé. Non, utiliser time ou des commandes équivalentes ne convient pas, notamment parce que ces commandes incluent des temps qu'on ne souhaite pas forcément mesurer comme le temps de chargement du programme ou comme celui de la résolution DNS. echoping, au contraire, ne déclenche son chronomètre qu'une fois que tout est prêt. À ma connaissance, il n'existe pas de programme généraliste équivalent.
echoping cherche donc un nouveau maître. Il faut s'y connaître en C, en réseaux, et avoir un peu de temps : le programme est simple (un seul mainteneur suffit très largement) mais a quand même pas mal de bogues pas résolus.
echoping est un très vieux programme (début en 1995) mais est toujours utile. Il a des fonctions originales comme l'affichage de la médiane (alors que la quasi-totalité des programmes de mesure n'affichent que la moyenne), comme la possibilité de greffons pour ajouter un nouveau protocole sans changer le moteur principal, etc.
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 7680 - 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.
Première rédaction de cet article le 2 octobre 2011
Ah, la neutralité du réseau Internet... Vaste sujet, où ça part vite dans tous les sens, où la bonne foi est assez rare, où définir les principes est une chose mais où les traduire en termes concrets est étonnamment difficile... Que puis-je ajouter à un sujet sur lequel tant d'électrons ont déjà été agités ? Je vais quand même essayer de trouver quelques points de ce débat qui n'ont pas été trop souvent abordés.
Première rédaction de cet article le 28 septembre 2011
Dernière mise à jour le 24 octobre 2013
La littérature de science-fiction française de l'entre-deux-guerres recèle plein d'ouvrages curieux comme « La guerre des mouches » de Jacques Spitz, ou comme « Quinzinzinzili » de Régis Messac. Mais un des plus curieux est ce délirant récit d'une incroyable guerre mondiale, « Les hommes frénétiques », d'Ernest Pérochon.
Car l'auteur n'y va pas avec le dos de la cuillère : comme beaucoup de ceux qui avaient vécu les horreurs de la Première Guerre mondiale, Pérochon extrapole les progrès techniques à la guerre suivante. Mais ce ne sont pas simplement des avions plus gros et des bombes plus puissantes, que l'auteur imagine. Les physiciens mettent au point des tas d'armes nouvelles, toutes plus extravagantes les unes que les autres, afin d'augmenter le rendement des massacres, et leurs efforts culminent avec les féériques, des phénomènes mal décrits (l'auteur ne cherche pas à jouer les savants) mais spectaculaires, que les techniciens des deux camps lancent dans les régions adverses, et qui transforment les hommes en divers monstres. « Des maux inouïs, follement variés, s'abattirent sur l'humanité. ». À ne pas lire le soir, les cauchemars sont garantis.
Pérochon, qui n'a écrit que ce seul livre de science-fiction, n'apprécie pas la science dont la guerre précédente a bien montré l'absence de scrupules et la volonté sans faille à servir les armées. Les scientifiques de son livre sont tous des fous dangereux... ou des naïfs encore plus dangereux.
Une version en ePub gratuite de ce livre est
en http://editions-opoto.org/les-hommes-frenetiques/
.
Première rédaction de cet article le 28 septembre 2011
Dernière mise à jour le 29 septembre 2011
Tout programmeur le sait, programmer en langage assembleur est difficile. Avant d'avoir pu écrire un Hello world, on doit maîtriser beaucoup de détails. Même chose pour des opérations triviales comme de la simple arithmétique. Mais le compilateur peut nous aider dans notre démarche de formation : il a souvent une option pour produire du code assembleur lisible, permettant au débutant d'écrire dans un langage de plus haut niveau, avant de voir le code produit par son programme.
Supposons qu'on veuille mettre 3 dans une variable, en langage assembleur. Et l'incrémenter de 1. Mais l'assembleur, c'est dur. On va donc écrire en C, car c'est plus facile :
% cat plus.c main() { int a; a = 3; a++; }
Et le compilateur gcc le traduit en langage assembleur
(option -S
)
pour nous (le -O0
est pour éviter toute
optimisation), ici pour i386 :
% gcc -O0 -S -l plus.c % cat plus.s .file "plus.c" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $16, %esp # C'est moi qui ait ajouté les commentaires movl $3, -4(%ebp) # Mettre 3 dans la mémoire (movl = Move Long) addl $1, -4(%ebp) # Ajouter 1 à ce qui est dans la mémoire leave ret .size main, .-main .ident "GCC: (Debian 4.4.5-8) 4.4.5" .section .note.GNU-stack,"",@progbits
Pour lire ce code, il faut se souvenir que :
Des options de gcc comme -fverbose-asm
permettent d'avoir davantage de
détails dans le code assembleur. On peut donc ensuite faire des
programmes C de plus en plus compliqué et apprendre l'assembleur en
voyant ce que fait le compilateur.
Si on veut du vrai langage machine à partir du code assembleur :
% as -alhnd plus.s
Encore plus fort, si on veut un listing avec le code machine et le code C en commentaire, pour mieux suivre ce qu'a fait le compilateur :
% gcc -O0 -c -g -Wa,-a,-ad plus.c ... 4:plus.c **** a = 3; 26 .loc 1 4 0 27 0006 C745FC03 movl $3, -4(%ebp) 27 000000 5:plus.c **** a++; 28 .loc 1 5 0 29 000d 8345FC01 addl $1, -4(%ebp)
Et avec d'autres processeurs (et donc d'autres langages assembleur) que le i386 ? André Sintzoff propose, pour les ARM :
; generated by ARM C/C++ Compiler, 4.1 [Build 481] ; commandline armcc [-S -O0 plus.c] ... main PROC MOV r1,#3 ; mettre 3 dans le registre r1 ADD r1,r1,#1 ; ajouter 1 à ce registre MOV r0,#0 ; mettre 0 comme valeur de retour de la fonction BX lr ; aller à l'adresse contenue dans le registre lr ENDP ...
Et avec MIPS (sp = stack pointer, fp = frame pointer), un code très verbeux :
... main: .frame $fp,16,$ra # vars= 8, regs= 1/0, args= 0, extra= 0 .mask 0x40000000,-8 .fmask 0x00000000,0 subu $sp,$sp,16 sw $fp,8($sp) move $fp,$sp li $v0,3 # 0x3 sw $v0,0($fp) lw $v0,0($fp) addu $v0,$v0,1 sw $v0,0($fp) move $sp,$fp lw $fp,8($sp) addu $sp,$sp,16 j $ra .end main ...
Pour ceux qui veulent apprendre le langage assembleur en partant d'un langage de plus haut niveau, Olivier Bonaventure me recommande le livre « The Art of Assembly Language Programming », qui part d'un langage de haut niveau proche du C pour aller progressivement vers l'assembleur. Sinon, le livre de Hennessy & Patterson, « Computer Architecture: A Quantitative Approach » démarre aussi sur une description du langage assembleur en partant du C.
Première rédaction de cet article le 26 septembre 2011
Dernière mise à jour le 27 septembre 2011
Ceux qui utilisent un VCS pour stocker des documents structurés (par exemple du XML) ont souvent le problème d'éditeurs trop intelligents qui reformattent brutalement le document, lui conservant son sens sous-jacent (encore heureux !) mais changeant complètement la représentation textuelle. Les VCS typiques, conçus pour du texte, croient alors que le document est différent et annonçent des changements qui ne sont pas réellement importants. Une des solutions à ce problème est de canonicaliser les documents et de demander au VCS de vérifier que cette canonicalisation a bien été faite. Comment on fait avec le VCS Subversion ?
Le problème n'est pas spécifique avec XML. Si une équipe de
développeurs C utilise
indent (ou le vieux logiciel cb) pour
pretty-printer leur code,
mais qu'ils ont mis des options différentes dans leur
~/.indent.pro
(au passage, voici le mien), chaque
commit va engendrer des diff
énormes mais non significatifs. Mais le problème est plus fréquent
avec XML, où les auteurs utilisent rarement des éditeurs de
texte et passent en général par un logiciel spécialisé,
qui n'hésite pas à changer le fichier considérablement. C'est
typiquement le cas avec le format SVG, qu'on
édite rarement à la main. Si un membre de l'équipe utilise
Inkscape et l'autre
Sodipodi, les diffs entre
leurs commits ne seront guère utilisables. C'est un
problème que connait le projet CNP3,
enregistré dans la bogue #24. Ce problème a
aussi été discuté sur
StackOverflow.
Bien sûr, le problème n'est pas purement technique. Il y a aussi une part de politique : mettre d'accord les développeurs, fixer des règles. Mais la technique permet-elle ensuite de s'assurer qu'elles sont respectées ?
Avec le VCS Subversion, oui, c'est possible,
et c'est même documenté. Le
principe est d'avoir un script dit pre-commit
,
que le serveur Subversion exécutera avant le
commit et qui, si le code de
retour indique une erreur, avortera le
commit. Voici un exemple, avec un
pre-commit
qui teste qu'on soumet du
XML bien formé :
% svn commit -m 'Bad XML' bad Sending bad Transmitting file data .svn: Commit failed (details follow): svn: Commit blocked by pre-commit hook (exit code 1) with output: /tmp/bad:1: parser error : Opening and ending tag mismatch: x line 1 and y <x a="3">toto</y> ^
Vous pouvez voir ce script en pre-commit-check-xml-well-formed.sh
. Il est très inspiré du
script d'exemple (très bien documenté) fourni avec Subversion. Il utilise
xmllint pour déterminer si le fichier XML est
bien formé. Sinon, xmllint se termine avec un code de retour différent
de zéro, et, à cause de set -e
, le script entier
se termine sur une erreur, ce qui empêche le commit
d'un fichier incorrect.
Si le dépôt Subversion est en
/path/example/repository
, le script doit être
déposé dans le sous-répertoire hooks/
du dépôt,
sous le nom de pre-commit
. Il doit être
exécutable (autrement, vous verrez une mystérieuse erreur sans
message, avec un code de retour de 255).
Plus ambitieux, un script qui teste que le XML soumis est sous
forme canonique (cette forme est normalisée dans un texte du W3C). Pour cela, il va canonicaliser le fichier
soumis (avec xmllint --c14n
) et, si cela donne un
fichier différent de celui soumis, c'est que ce dernier n'était pas
sous forme canonique. Le commit est alors rejeté :
% svn commit -m 'Not canonical XML' bad Sending bad Transmitting file data .svn: Commit failed (details follow): svn: Commit blocked by pre-commit hook (exit code 3) with output: File "bad" is not canonical XML
Voici un exemple du travail de xmllint pour canonicaliser du XML :
% cat complique.xml <?xml version="1.0" encoding="utf-8"?> <toto > <truc a="1" >Machin C </truc >café</toto> % xmllint --c14n complique.xml <toto> <truc a="1">Machin C </truc>café</toto>
Le script de pre-commit
est en pre-commit-check-xml-canonical.sh
.
On peut se dire qu'il serait plus simple que le script canonicalise le fichier, qu'il l'était avant ou pas, épargnant ainsi ce travail aux auteurs. Mais Subversion ne permet pas de modifier un fichier lors d'un commit (cela impliquerait de changer la copie de travail de l'utilisateur). On ne peut qu'accepter ou refuser le commit.
Rien n'interdit d'utiliser le même principe avec du code, par
exemple en C. On peut envisager de tester si le
code est « propre » en le testant avec splint
dans le pre-commit
. Ou bien on peut voir si le
code C a été correctement formaté en le reformatant avec
indent et les bonnes options, et voir ainsi s'il
était correct.
Et avec les DVCS ? Par leur nature même, ils rendent plus difficile la vérification du respect de règles analogues à celles-ci. Je ne connais pas de moyen de faire ces vérifications avec les DVCS existants. Il faudrait le faire lors d'un push/pull car un dépôt n'a aucune raison de faire confiance aux vérifications faites lors du commit par un autre dépôt. J'ai inclus à la fin de cet article des explications fournies par des lecteurs, pour d'autres VCS. Il me manque encore git. Un volontaire ?
Enfin, tout ceci ne résout pas tous les problèmes, par exemple pour l'édition SVG citée plus haut : les éditeurs SVG comme Inkscape aiment bien rajouter aussi des éléments XML à eux et, là, le problème du diff est plus délicat. Des outils comme Scour deviennent alors nécessaires, pour nettoyer le SVG.
D'autres exemples de scripts pre-commit
sont
fournis avec Subversion en http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/
. Parmi
eux, on note un programme
écrit en Python (rien n'oblige les scripts
pre-commit
à être en
shell), qui vérifie un certain nombre de
propriétés (configurées dans son enforcer.conf
)
sur des sources Java.
Pour le cas du VCS distribué darcs, Gabriel Kerneis propose : « On peut créer un patch qui définit un test. Si les autres développeurs appliquent ce patch, alors darcs exécutera automatiquement le test à chaque fois qu'ils voudront enregistrer un nouveau patch :
darcs setpref test 'autoconf && ./configure && make && make test' darcs record -m "Add a pre-record test"
Mais comme vous le notez, cela ne prémunit pas d'un envoi de patch qui ne passe pas le test. Sur le répertoire central de référence (à supposer qu'il y en ait un), ou chacun sur son propre répertoire de travail, peut aussi ajouter un hook qui vérifiera que les patchs sont corrects avant de les appliquer :
# à vérifier que si le prehook échoue, le apply échoue bien - je ne # l'ai jamais utilisé en pratique echo 'apply prehook make test' >> _darcs/prefs/defaults echo 'apply run-prehook' >> _darcs/prefs/defaults
Il est même possible d'effectuer la canonicalisation à l'aide de
prehook
:
echo 'record prehook canonicalize.sh' >> _darcs/prefs/defaults echo 'record run-prehook'
Voir les détails des options prehook (et posthook). Malheureusement (ou heureusement ?), il n'est pas possible de distribuer les prehooks et les posthooks sous forme de patch, comme avec setpref. Mais on peut toujours ajouter un test avec setpref qui vérifie si les prehooks sont présents et échoue sinon... »
Pour Mercurial, André Sintzoff explique :
« Il y a aussi des hooks qui sont notamment décrits
dans
la documentation.
Le precommit hook permet de contrôler avant le commit comme avec Subversion
Comme tu le fais remarquer, c'est local à l'utilisateur donc pas
obligatoire.
La solution est donc de se baser sur les hooks changegroup
et
incoming
qui contrôlent l'arrivée de nouveaux changesets dans un
dépôt via pull ou push.
Il suffit donc de mettre un hook changegroup
avec la vérification qui va bien.
Bien entendu, il vaut mieux pour l'utilisateur d'utiliser un precommit
hook pour contrôler sur son dépôt local. »
Enfin, pour git, le bon point de départ
semble être http://book.git-scm.com/5_git_hooks.html
.
Merci beaucoup à Gabriel Kerneis et André Sintzoff pour leurs contributions.
Première rédaction de cet article le 23 septembre 2011
Vu l'épuisement des adresses IPv4, la question revient régulièrement (mais n'a encore débouché sur rien de concret) de la pertinence d'un marché des adresses IPv4. Le capitalisme peut-il résoudre tous les problèmes, y compris celui de l'épuisement d'une ressource virtuelle ?
La question de départ est que les politiques des RIR, à l'heure actuelle, interdisent la vente et revente d'adresses IP (le « second marché », comme il y en a pour les noms de domaine). Les adresses sont en théorie allouées sur la base d'un besoin documenté (en français : en remplissant des papiers plein de mensonges, qu'on appelle des « prévisions optimistes »). L'idée est qu'un marché des adresses IP rendrait disponibles des adresses IP actuellement bloquées chez les premiers arrivants qui se sont largement servis.
Une bonne introduction au début est fournie par deux articles de l'excellent Ars Technica, un plutôt pour de Timothy B. Lee, « The case for a free market in IPv4 addresses » (le marché est tout de suite plus sympa lorsqu'on rajoute l'adjectif free...) et un plutôt contre de Iljitsch van Beijnum, « Trading IPv4 addresses will end in tears ».
Les deux articles résument bien les arguments essentiels. Pour :
Et contre :
En français, on peut aussi lire le très bon article de Spyou, « Adresse IP à vendre ». Et en anglais, les excellents articles de l'Internet Governance Project comme celui consacré à l'achat des adresses IP de Nortel par Microsoft. On note que ce sujet de la politique d'attribution des adresses IP est très rarement discuté dans les organismes officiels de gouvernance, comme l'ICANN ou l'IGF, sans doute parce que c'est un sujet concret, et que ces organismes préfèrent pipeauter que de travailler.
Première rédaction de cet article le 23 septembre 2011
Dernière mise à jour le 25 septembre 2011
La presse a comme d'habitude annoncé n'importe quoi à propos de la faille de sécurité TLS qui a été officiellement publiée le samedi 24, vers 00h00 UTC (mais l'article n'est pas encore disponible officiellement). Les titres les plus sensationnalistes se sont succédés, « Le protocole SSL aurait été craqué », « Une faille dans le chiffrement SSL et des millions de sites HTTPS vulnérables », « Des pirates [sic] brisent le cryptage [re-sic] SSL utilisé par des millions de sites » et autres fariboles du même genre. C'est la loi habituelle des médias officiels : parler sérieusement et étudier son sujet ne rapportent rien. Faire de la mousse est bien plus efficace... et sera de toute façon oublié dans deux jours. Mais, derrière cette ridicule campagne de presse, qu'y a-t-il comme information fiable ?
La faille a été « pré-annoncée » par ses découvreurs, Juliano Rizzo et Thai Duong, qui ont pris soin de s'assurer que leur exposé à une conférence de sécurité peu connue ne passerait pas inaperçu. Leur plan comm' a été mis au point avec autant de soin que leur logiciel, même le nom de celui-ci (BEAST pour Browser Exploit Against SSL/TLS) a probablement fait l'objet d'une étude soignée, suivant les mœurs habituels dans le monde de la sécurité informatique. L'article n'a pas été officiellement publié mais des copies (apparemment incomplètes) ont fuité, par exemple sur Google Doc ou bien dans cette archive RAR. Comme, à l'heure où j'écris, il n'y a pas eu de publication scientifique sérieuse complète, on ne peut que deviner. Donc, en se fiant aux différentes rumeurs qui circulent et au code qui a été publié pour corriger la faille, que sait-on ?
L'attaque est apparemment de type « texte en clair choisi ». L'attaquant génère du texte de son choix et le fait chiffrer. L'observation du résultat lui donne alors des indications sur la clé de chiffrement utilisée. Les bons protocoles de chiffrement ne sont pas vulnérables à cette attaque, mais TLS 1.0 (et seulement cette version, normalisée dans le RFC 2246) a quelques particularités dans le chiffrement en mode CBC qui le rendent vulnérables. Ces vulnérabilités ont été corrigées dans la version 1.1 du protocole, publiée dans le RFC 4346 il y a plus de cinq ans (aujourd'hui, on en est à la 1.2, normalisée dans le RFC 5246). La section 1.1 du RFC 4346 expliquait les changements avec TLS 1.0 et notait déjà « The implicit Initialization Vector (IV) is replaced with an explicit IV to protect against CBC attacks. ». Mais corriger un protocole à l'IETF est une chose, déployer le correctif en est une autre.
Outre le changement de protocole, on pouvait aussi corriger le problème en bricolant les données à certains endroits, ce que fait la bibliothèque OpenSSL depuis... avant 2004 ! C'est d'ailleurs la publication de ce problème par l'équipe d'OpenSSL qui avait mené à TLS 1.1. (Un article plus détaillé sur ce sujet est celui de Gregory Bard en 2004. Le premier message rendant publique cette vulnérabilité est de 2002.) On le voit, il n'y a rien de nouveau, la plupart des failles de sécurité sont connues depuis longtemps lorsque la presse fait semblant de nous révéler des choquantes nouveautés.
Est-ce que cela veut dire que la nouvelle attaque n'est que du pschiiit ? Non, il y a au moins deux nouveautés, une mise en œuvre logicielle de l'attaque, et qui fonctionne (le fameux BEAST), et un certain nombre d'astuces et d'optimisations qui font toute la différence entre une faille connue et une faille attaquée. Le passage de la théorie à la pratique est donc un évenement important.
Faut-il alors paniquer ? Comme d'habitude, non. La faille ne semble pas triviale à exploiter. Il faut que l'attaquant puisse produire des données (le texte en clair choisi) sur le poste de la victime. BEAST peut utiliser plusieurs techniques pour cela (un navigateur Web moderne est un monstre bien trop compliqué et qui fournit plein de failles de sécurité à un attaquant), par exemple un code Java envoyé à la victime. Il faut aussi que l'attaquant puisse monter une attaque de l'homme du milieu, par exemple en prenant le contrôle d'un réseau WiFi mal protégé. L'attaque est donc possible mais pas simple et quelques précautions la rendent très difficile : ne faire que du HTTPS avec les sites sensibles, ne pas se connecter à ces sites sensibles depuis un réseau inconnu (genre le Wifi de Starbucks)... Ce sont des simples règles de défense en profondeur (certes, TLS était censé protéger contre le réseau WiFi dangereux, mais il n'est pas interdit de porter ceinture et bretelles).
Mais, puisque j'ai dit que la version 1.1 de TLS, qui corrige la faille fondamentale, date de 2006, et que le contournement dans OpenSSL, qui fonctionne même en version TLS 1.0, date de 2004, pourquoi l'attaque est-elle encore possible en 2011 ? Pour un simple problème de déploiement. D'abord, pour OpenSSL : cette bibliothèque est de loin la plus utilisée dans les serveurs HTTP, nettement devant GnuTLS. Mais chez les navigateurs Web, c'est plutôt NSS qui domine, et cette bibliothèque n'a pas le contournement. Le patch fait par les auteurs de Chromium à la bibliothèque qu'ils utilisent met d'ailleurs en œuvre la même technique qu'avec OpenSSL (une variante existe ; le patch pour Firefox est discuté dans la bogue #665814). Le problème est pourtant connu depuis longtemps (bogue Firefox #480514).
Actuellement, un très grand nombre de navigateurs Web
n'a
pas TLS 1.1 et aucune mesure prise uniquement sur le serveur ne
pourra résoudre cela. Si l'administrateur du serveur veut interdire le
vieux et dangereux TLS 1.0 (avec le module Apache de
GnuTLS, c'est apparemment GnuTLSPriorities
NORMAL:!VERS-TLS1.0
), il cassera tout puisque la plupart
des navigateurs ne pourront pas se connecter. Une autre
approche pour le gérant de site Web est plutôt de ne pas utiliser les
algorithmes de chiffrement en CBC. Elle est
détaillé dans l'article
de PhoneFactor (c'est cette méthode qu'utilisent les serveurs
HTTP de Google). Côté client, une bonne
compilation de techniques limitant les risques est disponible sur StackExchange.
C'est donc moins sexy qu'une nouvellement découverte faille du protocole mais la réalité est là : le problème principal est celui d'une non-mise à jour des logiciels, pour parer aux vulnérabilités connues. Les raisons de cette non-mise à jour sont nombreuses. Une d'elles est que gérer les nouvelles versions du protocole peut empêcher les connexions avec les serveurs bogués. En effet, le protocole TLS est conçu pour que les anciens clients puissent interagir avec les nouveaux serveurs et réciproquement, mais cela suppose que toutes les implémentations respectent la norme (qui décrit avec précision comment assurer la compatibilité des différentes versions, cf. annexe E du RFC 5246). Or, il existe beaucoup de programmes bogués, qui bloquent toute évolution du protocole (la faille de renégociation de TLS, corrigée par le RFC 5746, connaît des problèmes de déploiement similaires, un tiers des serveurs étaient encore vulnérables en 2010). Résultat, la plupart des serveurs TLS coupent TLS 1.1 et 1.2 pour éviter tout problème comme le montre l'excellente enquête de Qualys publiée à Blackhat.
Pour savoir la version maximale que permet un serveur TLS, vous
pouvez utiliser l'outil en ligne de commande
gnutls-cli
, livré avec GnuTLS (l'outil équivalent
d'OpenSSL ne semble pas capable de distinguer les différentes versions mineures
de TLS.) GnuTLS va tenter d'utiliser la version la plus élevée
possible. Avec un GnuTLS récent, qui gère TLS 1.2, contre un Apache
récent, lui-même avec GnuTLS :
% gnutls-cli --verbose --port 443 svn.example.org ... - Version: TLS1.2
Avec un serveur traditionnel (ici, celui de l'IETF) :
% gnutls-cli --verbose --port 443 www.ietf.org ... - Version: TLS1.0
Vous pouvez aussi utiliser sslscan pour tester un serveur mais, comme openssl, il ne sait pas distinguer les différentes versions de TLS 1.0.
Vous pouvez aussi tester votre propre site TLS en ligne depuis Qualys (il ne
semble pas gérer SNI, hélas). Quelques lectures pour approfondir le sujet : une bonne
explication pédagogique notamment du CBC, une autre
explication bien faite, notamment dans le contexte de
Tor, une très
bonne explication détaillée du problème, la déclaration
des développeurs de GnuTLS, un article
détaillé d'un des développeurs de Google Chrome, un très
bon résumé et analyse des conséquences pour le logiciel
OpenVPN, un bon résumé par
Microsoft, un autre chez
SANS, un article
plus détaillé de Bard (qui notait déjà les points essentiels, à savoir que la
vulnérabilité était close par TLS 1.1 ou bien par l'astuce de
l'enregistrement vide de OpenSSL), l'analyse du gourou TLS de l'IETF (très
clair, et un des rares articles écrits après
l'exposé de Rizzo et Duong), le très intéressant
récit du développement de BEAST par un de ses auteurs, un article
consacré uniquement aux techniques permettant de limiter l'effet de la
faille, la discussion
dans le groupe de travail TLS de l'IETF et, bien sûr, l'article
original, « Here Come The ⊕ Ninjas », dès
qu'il sera officiellement publié... En français, l'article
de SecurityVibes est intéressant. Ceux qui aiment lire le code
source pourront trouver une exploitation (je ne l'ai pas testée) de la
faille en
Java en http://pastebin.com/pM3ZbCdV
ou bien dans l'archive RAR citée plus haut.
Merci à Mathieu Pillard pour ses commentaires.
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 ?
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 :
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 7208,
puisque ce dernier authentifie l'enveloppe et pas le message).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 :
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.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.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 7001).
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.
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.
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 ».
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 de deux rapports d'interopérabilité (dans le RFC 6053 et le RFC 6984), 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 et éventuellement la bibliothèque de fonctions du RFC 6956. 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.
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.
Auteur(s) du livre : Thomas Deltombe, Manuel Domergue, Jacob Tatsitsa
Éditeur : La découverte
978-2-7071-5913-7
Publié en 2011
Première rédaction de cet article le 17 septembre 2011
Ce livre est de loin le plus détaillé qui existe sur une guerre coloniale un peu oubliée, celle qui a été menée au Cameroun de 1955 à 1971. Éclipsée par la guerre d'Algérie qui se déroulait au même moment, la lutte des troupes françaises contre les nationalistes de l'UPC s'est même prolongée après l'indépendance (théorique) du pays, dans une relative indifférence. Si cette guerre sans nom avait déjà été mentionnée (par exemple par François-Xavier Verschave dans ses ouvrages), on ne peut pas dire qu'elle soit bien connue des français d'aujourd'hui, ni d'ailleurs des camerounais, qui n'ont eu droit qu'à la version officielle. Ce fut pourtant une des très rares guerres coloniales gagnées par l'armée française. Mais les méthodes utilisées font que celle-ci a préféré ne pas trop se vanter de cette victoire.
Le Cameroun (l'orthographe « Kamerun » est celle choisie par les nationalistes) était une colonie allemande, que les français et les anglais se sont partagé après la première Guerre mondiale. En théorie, il s'agissait juste d'un mandat de la SDN, puis de l'ONU et la Cameroun n'était pas officiellement une colonie. En pratique, l'exploitation du pays ne fut guère différente de ce qui arriva dans les autres colonies d'Afrique. Dans les années 50, un mouvement nationaliste, analogue à celui qui apparaissait dans d'autres pays occupés, se développa, et se rassembla dans l'Union des Populations du Cameroun (UPC, dirigée par Ruben Um Nyobe, qui sera assassiné en 1958). Tout de suite, les colons français décidèrent que cette UPC n'était pas fréquentable, ne pouvait pas être retournée (comme l'a été le RDA de Houphouët-Boigny) et la guerre commença très rapidement. Ce fut une guerre coloniale classique, avec regroupements forcés de la population, massacres un peu partout, utilisation massive de collaborateurs locaux pour accomplir le sale boulot, tortures et assassinats. Cette guerre se déroulant sans témoins (l'ONU, normalement en charge de la tutelle, avait choisi de fermer les yeux), il est très difficile, même aujourd'hui, d'en tirer un bilan quantitatif. Le nombre total de morts de la guerre restera ainsi sans doute à jamais inconnu. (Les auteurs notent avec honnêteté quand ils n'ont pas pu établir un fait ou un chiffre ; c'est ainsi que l'utilisation du napalm par l'aviation française, dénoncée par les nationalistes, n'a pu être prouvée.) Il n'y a sans doute pas eu de tentative de génocide, mais il ne s'agissait pas non plus d'une « simple opération de police » contre « des bandits isolés » mais d'une vraie guerre, notamment en Sanaga-Maritime et en pays bamiléké.
Cette guerre resurgit aujourd'hui à travers l'enquête menée par les auteurs, deux journalistes et un historien. Ils ont fouillé les archives (qui ne contiennent pas tout, notamment les opérations menées par les forces supplétives sont nettement moins documentées), et interrogé de nombreux témoins et combattants. Il était temps : au moins un d'entre eux, le général Lamberton, est mort juste avant que les auteurs ne lui demandent ses souvenirs. Il ne « parlera » que via les notes qu'il prenait en marge des livres de sa bibliothèque... Mais beaucoup d'autres ont parlé, des deux côtés, et permettent ainsi de mieux comprendre l'ampleur de la guerre qui fut menée pour empêcher une vraie indépendance.
Car le Cameroun a fini par devenir indépendant : l'UPC sérieusement affaiblie, la France a fini par accorder l'indépendance à sa colonie, en 1960, avec un gouvernement qui, contrairement à l'UPC, comprenait les intérêts français, un vrai gouvernement françafricain. L'« indépendance » n'a pas mis fin à la guerre. Celle-ci a au contraire continué, menée cette fois officiellement par l'armée camerounaise, encadrée de près par l'armée française. Les derniers maquis n'ont été détruits que dix ans après.
Aujourd'hui, tout cela semble bien lointain, les acteurs de l'époque sont morts ou sont aujourd'hui à la retraite. Mais le système françafricain tient toujours, ainsi qu'un de ses mythes fondateurs comme quoi les indépendances en Afrique noire auraient été acquises pacifiquement. C'est donc une bonne chose que les auteurs aient sérieusement enquêté sur cette guerre, avant que toutes les traces soient effacées. « Quand le lion aura sa propre histoire, l'histoire ne sera plus écrite par le chasseur. »
Le livre est completé par un site Web, où on trouve par exemple les vidéos des interviews réalisés pour le film.
Rue89 avait publié un très bon article sur ce livre.
First publication of this article on 16 September 2011
Last update on of 22 October 2011
I just installed Ubuntu on a Dell Vostro 3350 laptop. This article documents a few things about this machine and the issues I had.
Première rédaction de cet article le 14 septembre 2011
Dernière mise à jour le 1 janvier 2012
Pendant les discussions sur la mesure de la capacité (souvent improprement nommée « débit » ou « bande passante ») d'un accès à l'Internet (par exemple au sein du « groupe de travail multilatéral sur la qualité de service » de l'ARCEP, créé suite à la septième proposition de l'ARCEP sur la neutralité du réseau), un point qui revient souvent est celui de l'endroit où doit se terminer la mesure. Cet endroit doit-il être chez le FAI ou plus loin dans l'Internet ?
Le but est de vérifier les offres commerciales existantes. Si un FAI annonce sur des grands panneaux publicitaires un débit (sic) de 100 Mb/s, est-ce vrai ? Une étude de la FCC, aux États-Unis, « Measuring broadband America », semblait indiquer que non, que la capacité réelle était bien plus basse. Il est donc normal que les autorités de régulation veulent effectuer des mesures indépendantes de la capacité réellement vendue au client. A priori, le problème est simple. On met une sonde (matérielle ou logicielle) chez le client, une terminaison de mesure quelque part dans l'Internet (avec la plupart des logiciels cités plus loin, c'est le même programme qui tourne aux deux extrémités, ce qui permet de voir le lien des deux côtés) et on regarde (il existe plusieurs outils libres pour faire cette mesure, voir par exemple mon article sur le RFC 6349).
Mais la position de la terminaison est cruciale :
Le débat sur ce sujet est souvent confus. Certes, le problème est compliqué. Mais c'est aussi que certains acteurs n'ont pas intérêt à ce que des mesures sérieuses soient faites. Certaines critiques de telle ou telle méthode sont parfois inspirées par un souci de rigueur scientifique, mais on voit aussi des critiques visant à faire dérailler tout le processus, en gros pour dire « on ne peut pas faire de mesure parfaite alors n'en faisons pas, et faisons confiance aux publicités ».
Comment résoudre ce problème ? Je ne vois pas de solution parfaite. Le mieux serait sans doute de publier les deux indicateurs : « capacité réseau interne » et « capacité avec certains points externes ». Comme souvent en métrologie, on ne peut pas espérer s'en tirer avec un seul chiffre, même si c'est ce que les publicitaires préféreraient.
Après la parution initiale de cet article, plusieurs personnes ont fait des remarques, nuançant tel ou tel point. Merci sur Twitter à lucasdicioccio, AlexArchambault, Grunt_ et bitonio. Les points à compléter :
Pour une définition plus rigoureuse de la notion de capacité, et pour une explication de ses différences avec la bande passante, on peut consulter le RFC 5136. Quant au débit, il représente l'utilisation effective du réseau, la capacité étant son potentiel maximum. Un bon article scientifique sur ce problème de mesure de la capacité fournie par le FAI est « Broadband Internet Performance: A View From the Gateway ». Suite à mon article, Éric Daspet a écrit « Où doit-on mesurer la capacité réseau », qui revient notamment en détail sur la responsabilité du FAI dans les connexions extérieures (par une bonne politique de peering, etc). Enfin, un autre débat qui a eu lieu dans le même groupe de travail ARCEP est également discuté sur mon blog, dans « Que doit-on mesurer, la QoS ou la QoE ? ».
La consultation publique lancée par l'ARCEP fin 2011 utilise une autre terminologie (voir notamment la question n° 19). La machine visée par la mesure est nommée mire et le projet soumis à consultation a trois sortes de mires, mire proches (situées dans un endroit bien connecté à beaucoup de FAI), mires lointaines (Yaoundé...) et mires commerciales (gros services très populaires comme YouTube). On notera qu'il n'existe pas de mires internes, situées sur le réseau du FAI.
Première rédaction de cet article le 13 septembre 2011
Le 13 septembre 2011, j'ai fait un exposé aux Bell Labs (centre de recherche d'Alcatel-Lucent à Nozay) sur le thème « Nommage : avoir le beurre, l'argent du beurre, et le sourire de la crémière », consacré aux différents systèmes de nommage dans les réseaux informatiques et à leurs propriétés, souvent contradictoires. Je parlais bien sûr des noms de domaine et du DNS mais aussi de plusieurs autres, en essayant de mettre l'accent sur leurs propriétés, de manière à pouvoir choisir le système adapté.
Voici les transparents de l'exposé :
J'avais déjà développé ces idées dans un article de mon blog.
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 https://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 :
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.
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 (qui a finalement été publié dans le RFC 6716).
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 :
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.
Première rédaction de cet article le 3 septembre 2011
Dernière mise à jour le 14 septembre 2011
Si vous voulez connecter un réseau local à l'Internet IPv6, mais que vous êtes coincé derrière un FAI qui ne fournit encore, en 2011, qu'IPv4, que faire ? La solution évidente est de configurer un tunnel vers un fournisseur de connectivité IPv6. Ce cas est bien connu et on trouve d'innombrables HOWTO et articles de blog sur ce sujet. Mais, que faire si le routeur d'entrée du site n'a pas IPv6, et que la machine qui pourrait servir de routeur IPv6 n'a pas d'adresse IPv4 publique ? Simple, il suffit de créer un deuxième tunnel, entre le routeur d'entrée de site et le routeur IPv6, et de faire tourner le second tunnel sur le premier...
Le cas réel m'est arrivé à l'université de Yaoundé 1 pour une formation sur IPv6. Le Cameroun a pour l'instant zéro connectivité IPv6. L'université n'a que peu d'adresses IPv4 publiques mais il y en avait quand même une de disponible pour établir un tunnel « IPv6 dans IPv4 » (protocole 41) avec un fournisseur de connectivité IPv6 comme l'excellent Hurricane Electric. Le seul problème est que, pour des raisons matérielles, le réseau où se trouvaient les machines à adresse publique ne permettait pas de nouvelle installation. Dans ce réseau, un routeur Cisco 2800 aurait pu servir de routeur IPv6 (l'excellente interface Web de Hurricane Electric fournit des instructions IOS qu'on n'a qu'à copier/coller ou bien on peut utiliser ce tutoriel). Mais ce Cisco-là n'avait pas IPv6, protocole qui nécessite une licence spéciale (baptisée Advanced quelque chose) et une image d'IOS nouvelle. Après une heure passée à naviguer dans les options incompréhensibles du site Web de Cisco, pour essayer de trouver un moyen de mettre à jour la machine, nous avons renoncé.
Bon, il faut donc mettre le routeur IPv6 sur un PC Debian. Il y a encore plus de documentation pour ce système, et cela a l'avantage d'utiliser du logiciel libre. Mais il y avait des limites matérielles : pas de PC avec deux cartes Ethernet disponible, pas de possibilité de le mettre dans la salle machines, etc, qui ont mené à une deuxième décision : le routeur IPv6 sur PC reste dans les salles où se trouvent les autres PC de l'université, et on va créer un tunnel entre lui et le Cisco, « apportant » l'adresse IPv4 publique dont a besoin Hurricane Electric jusqu'à ce PC.
Donc, les acteurs vont être :
216.66.80.26
et IPv6
2001:470:1f08:1c8f::1
.172.16.0.76
et adresse IPv4
publique41.204.94.222
, en IPv6,
2001:470:1f08:1c8f::2
. Le réseau alloué à
l'unversité de Yaoundé est
2001:470:1f09:1c8f::/64
(avec les adresses IPv6, ouvrez
l'œil : 1f08 n'est pas 1f09).41.204.93.101
.
Le problème est donc de permettre à la machine d'HE (Hurricane
Electric) d'atteindre 41.204.94.222
. J'ai choisi
un tunnel GRE (RFC 2784)
pour sa simplicité, et son caractère normalisé (tout le monde sait
faire du GRE). Si le tunnel, au lieu d'être limité à l'université,
s'était étendu sur un réseau public, il aurait été plus prudent de le
protéger par la cryptographie. Mes
followers sur Twitter ont voté massivement pour OpenVPN mais, ici, GRE suffit.
Pour l'intérieur du tunnel GRE, j'ai choisi les adresses IP
192.0.2.1
(pour le Cisco) et
192.0.2.2
(pour le PC). Attention si vous tentez
une expérience similaire : il faut vraiment y aller par étapes, en
testant soigneusement le résultat à chaque étape. Autrement, le
débogage est cauchemardesque.
On va d'abord dire au Cisco de créer son côté du tunnel GRE, sur l'interface Tunnel0
:
int tunnel 0 ip address 192.0.2.1 255.255.255.0 tunnel source 41.204.93.101 tunnel destination 172.16.0.76 exit ip route 41.204.94.222/32 tunnel0
Ainsi, IOS envoit désormais les paquets qu'il reçoit pour
41.204.94.222
à 172.16.0.76
,
en GRE. Côté du PC destinataire, on va configurer l'interface tun0
:
ip tunnel add tun0 mode gre remote 41.204.93.101 local 172.16.0.76 ttl 255 ip link set tun0 up ip addr add 192.0.2.2 dev tun0 ip route add 192.0.2.1/24 dev tun0
puis mettre l'adresse IPv4 publique sur une interface
dummy0
:
ifconfig dummy0 up ifconfig dummy0 41.204.94.222/32
Attention, avec ce système, le routage est asymétrique. Un paquet
entrant passera par l'interface tun0
alors que la
réponse sortira par le normal eth0
. On peut
changer la table de routage pour forcer le passage par le tunnel GRE,
ou bien on peut tout simplement débrayer le contrôle du routage
asymétrique (qui est activé par défaut sur Debian, pour limiter les
risques d'usurpation d'adresses IP) en mettant les variables
sysctl
net.ipv4.conf.all.rp_filter
et
net.ipv4.conf.default.rp_filter
à 0. Autrement,
vous verrez les paquets être mystérieusement jetés par Linux.
Et voilà, le tunnel GRE fonctionne. Depuis tout l'Internet, on peut
pinguer 41.204.94.222
, bien que la machine soit
reléguée loin du routeur d'entrée, dans une zone uniquement RFC 1918. Un autre avantage de GRE est que tcpdump le
connait et l'analyse très bien, rendant bien plus facile le
débogage. Voici un exemple de paquet qui passe par le tunnel. On a
capturé le trafic sur l'interface Ethernet et on voit les paquets GRE
entre 41.204.93.101
(le routeur Cisco) et
172.16.1.2
(le PC à l'autre bout du tunnel
GRE). Ici, le trafic dans le tunnel était une connexion
SMTP depuis 66.216.133.144
vers 41.204.94.222
:
12:11:21.894937 IP 41.204.93.101 > 172.16.1.2: GREv0, length 56: \ IP 66.216.133.144.26892 > 41.204.94.222.25: \ Flags [S], seq 1940136218, win 8192, options [mss 1380,nop,wscale 8,nop,nop,sackOK], length 0
Via l'interface Web d'Hurricane Electric (qui teste la connectivité effective avec l'adresse donnée, donc la configuration préalable de GRE était nécessaire), on peut créer le tunnel IPv6-dans-IPv4. Reste à le configurer sur le PC (le Cisco n'a plus rien à faire, il laissera passer ce qu'il prend pour des paquets IPv4 normaux).
Les instructions de HE sont simples, on utilise une interface
nommée he-ipv6
:
ip tunnel add he-ipv6 mode sit remote 216.66.80.26 local 41.204.94.222 ttl 255 ip link set he-ipv6 up ip addr add 2001:470:1f08:1c8f::2/64 dev he-ipv6 ip route add ::/0 dev he-ipv6
La première ligne configure le tunnel IPv6-dans-IPv4. Notez que, grâce
à l'autre tunnel, celui en GRE, la machine croit que
216.66.80.26
est directement joignable.
On a donc bien deux tunnels emboîtés :
% ip tunnel show tun0: gre/ip remote 41.204.93.101 local 172.16.0.76 ttl 255 he-ipv6: ipv6/ip remote 216.66.80.26 local 41.204.94.222 ttl 255 6rd-prefix 2002::/16
À partir de là, IPv6 passe : on peut faire un ping6 -n
www.ietf.org
, on peut regarder le serveur Web du RIPE-NCC et voir
en haut à droite qu'on utilise bien IPv6, etc. Là encore, si cela ne
marche pas, les outils classiques, tcpdump,
ping et traceroute sont
là. Voici le trafic sur le câble physique Ethernet, vu par tcpdump :
12:11:24.217673 IP 41.204.94.222 > 216.66.80.26: \ IP6 2001:470:1f09:1c8f:21c:23ff:fe00:6b7f > 2001:660:3003:2::4:20: \ ICMP6, echo request, seq 3, length 64 12:11:24.364372 IP 41.204.93.101 > 172.16.1.2: GREv0, length 128: \ IP 216.66.80.26 > 41.204.94.222: \ IP6 2001:660:3003:2::4:20 > 2001:470:1f09:1c8f:21c:23ff:fe00:6b7f: \ ICMP6, echo reply, seq 3, length 64
On y voit 2001:470:1f09:1c8f:21c:23ff:fe00:6b7f
(la machine interne) pinguer
2001:660:3003:2::4:20
(un serveur quelque part
sur l'Internet). On voit bien le routage asymétrique. La requête a été
encapsulée une seule fois, dans le tunnel Hurricane Electric (de
41.204.94.222
vers
216.66.80.26
). La réponse, en revanche, a été
encapsulée deux fois, dans le tunnel Hurricane Electric, puis dans le
tunnel GRE. On note que tcpdump n'a pas de problème avec cette double
encapsulation et arrive à décapsuler sans problème, affichant ce qui
passe dans le tunnel.
Si on regardait, toujours avec tcpdump, non pas sur l'interface
physique eth0
mais sur les interfaces virtuelles
du tunnel (option -i
de tcpdump), on verrait
directement le trafic IPv6.
Mais, pour l'instant, seul le routeur IPv6, notre brave PC/Debian,
peut profiter de l'Internet en IPv6. Les autres machines du réseau
local n'y ont pas droit. Notre PC n'est pas encore un routeur. Pour
cela, il faut d'abord activer le routage IPv6 en mettant les variables
sysctl
net.ipv6.conf.all.forwarding
et
net.ipv6.conf.default.forwarding
à 1 (cela peut
se faire avec la commande sysctl - option -w - ou bien en éditant
/etc/sysctl.conf
et en rechargeant les paramètres avec sysctl -p
). Autrement,
la machine jetterait sans remords les paquets IPv6 qui ne lui sont pas
destinés.
Ensuite, il faut créer une route vers le réseau local, soit en dotant le routeur d'une adresse de ce réseau, soit simplement en ajoutant une route :
ip route add 2001:470:1f09:1c8f::/64 dev eth0
Enfin, il faut prévenir les machines du réseau local qu'un routeur
IPv6 est là pour les servir. Cela se fait en envoyant des RA
(Router Advertisment, RFC 4862). J'ai installé le paquetage Debian
radvd
qui fournit ce service. La configuration
est triviale :
# /etc/radvd.conf interface eth0 { AdvSendAdvert on; prefix 2001:470:1f09:1c8f::/64 {}; };
Et c'est magique : toutes les machines du réseau local, par le biais
de ces RA, reçoivent le préfixe du réseau et l'adresse du
routeur. Désormais, tout le monde peut faire un traceroute6 www.afnic.fr
.
La plaie traditionnelle des tunnels est qu'ils diminuent la MTU (à cause des quelques octets nécessaires pour l'en-tête du protocole d'encapsulation). Cela va donc souvent imposer de la fragmentation qui, en raison de l'incompétence de certains ingénieurs système qui bloquent l'ICMP, marche souvent mal sur l'Internet. Alors, avec deux tunnels emboîtés, cela risque d'être encore pire. Mais, si tout est correctement configuré (en gros, si on laisse ICMP passer sur tout le chemin), tout se passe bien. Testons depuis l'extérieur en demandant à ping des paquets plus gros que d'habitude pour qu'ils dépassent, avec les octets des en-têtes, la MTU :
% ping6 -s 1450 2001:470:1f09:1c8f:21d:92ff:fe7f:e0ab PING 2001:470:1f09:1c8f:21d:92ff:fe7f:e0ab(2001:470:1f09:1c8f:21d:92ff:fe7f:e0ab) 1450 data bytes From 2001:470:0:67::2 icmp_seq=1 Packet too big: mtu=1480 From 2001:470:0:67::2 icmp_seq=3 Packet too big: mtu=1456 1458 bytes from 2001:470:1f09:1c8f:21d:92ff:fe7f:e0ab: icmp_seq=5 ttl=59 time=138 ms 1458 bytes from 2001:470:1f09:1c8f:21d:92ff:fe7f:e0ab: icmp_seq=6 ttl=59 time=141 ms
Tout s'est bien passé. Les messages packet too big
montrent que les paquets ICMP émis par le routeur d'entrée du tunnel
(deux messages, un par tunnel) sont bien arrivés, ping en a tenu
compte et tout fonctionne. (Pour les paquets émis depuis le réseau
local, on pourrait s'épargner cela en configurant
radvd
pour n'indiquer qu'une MTU assez petite
pour passer dans le tunnel.)
PS : ce réseau étant de nature expérimental, ne vous étonnez pas si vous testez les adresses et que cela « ne marche pas ».
Quelques lectures possibles :
Merci à Janvier Ngnoulaye pour sa patience et sa participation active et compétente.
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 :
turn
permet à une
application d'obtenir tout de suite un serveur ayant l'extension TURN,
sans tester plusieurs serveurs STUN),www
et
http
qui pointent vers le même port 80 ; seul
http
est correct, aujourd'hui),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 :
Il y a trois statuts possibles pour un numéro de port :
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 :
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.
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, et une autre en JSON, dans le RFC 7095), 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 :
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.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.)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.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étadonné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.
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
Dernière mise à jour le 18 août 2014
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 MKCOL
- RFC 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étadonné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 7232,
section 3.2) 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 :
i;ascii-casemap
du
RFC 4790 et les comparaisons Unicode
i;unicode-casemap
du RFC 5051,
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 la section 2.3 du RFC 7232). 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 deux mécanismes de découverte automatique, décrits dans le
RFC 5397 et dans le RFC 6764, mais qui ne sont pas
forcément présents partout. (iOS utilise celui du RFC 6764 donc si
vous voyez des requêtes /.well-known/carddav
passer, c'est lui.)
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 programmes qui gèrent CardDAV, citons le serveur Davical, Radicale ou Evolution. le client Kontact de KDE n'est plus maintenu. Pour Firefox, c'est en discussion. Merci à Mathieu Dupuy pour les détails.
Première rédaction de cet article le 29 août 2011
Les serveurs DNS ont souvent une option (complètement non officielle) pour obtenir le numéro de version du logiciel utilisé. Par souci de dissimulation, ou tout simplement pour s'amuser, certains administrateurs système décident d'afficher à la place un petit texte, souvent humoristique.
Cette option est une simple convention : aucun
RFC ne l'a jamais normalisé. Mais, si vous
interrogez un serveur DNS pour le nom
version.bind
, type TXT
,
classe CH
, vous obtenez cette information :
% dig @ns1.dns.example CH TXT version.bind ... ;; ANSWER SECTION: version.bind. 0 CH TXT "9.6.2-P3" ...
Comme son nom l'indique, cette option vient à l'origine de
BIND mais on la trouve dans bien d'autres
serveurs, comme NSD. BIND permet de la débrayer, ou bien de remplacer le
texte (option version
dans le bloc
options
, par exemple version "No information";
). On voit ainsi des choses comme :
% dig @dns.sncf.fr. CH TXT version.bind ... ;; ANSWER SECTION: version.bind. 0 CH TXT "S.N.C.F. French Railways"
Si on lance DNSdelve à
l'assaut de tout .fr
pour
regarder les textes ainsi diffusés, on trouve de nombreuses
perles. Par exemple :
Merci à Nicolas Delvaux pour le programme. Et une dernière pour la route :
% dig +short @rigel.illyse.org CH TXT version.bind "OpenOffice DNS server 1.0"
Pour ceux qui se souviennent du pare-feu d'OpenOffice... Autre exemple rigolo en dehors de .fr
:
% dig +short @ns1.conostix.com CH TXT version.bind "'\; DROP DATABASE mysql\; --"
L'auteur a tenté une injection SQL avec le DNS...
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 lien 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 :
Ce cahier des charges est-il réaliste ? Le reste de la section 3 raconte comment fonctionne A+P. Il y a trois fonctions :
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 :
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.
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 7680), 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 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 :
--mss
permet de
changer la taille des segments (des paquets TCP).--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ébogage : 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 7323) 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 7323) 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).
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
.
Première rédaction de cet article le 21 août 2011
Dernière mise à jour le 7 août 2022
Si on veut apprendre les réseaux informatiques, il existe d'innombrables articles et tutoriels sur l'Internet. Ce dernier, non seulement est une formidable réalisation de la science et de la technique des réseaux, mais c'est également un irremplaçable outil de diffusion du savoir. Mais on n'apprend pas un sujet complexe comme celui-ci en partant de zéro et en lisant les articles de Wikipédia. Cette encyclopédie est excellente quand on connait 90 % d'un sujet et qu'on a besoin de s'instruire sur les 10 % manquants. Mais ce n'est pas un outil pédagogique. L'apprenant a besoin d'une progression, d'un cadre, d'exercices bien calculés, bref, d'un livre de cours. Et, là, la situation est moins favorable.
Bien sûr, il existe des tas de livres d'apprentissage des réseaux informatiques. Outre que beaucoup sont écrits par des gens des télécoms, qui ne comprennent pas forcément bien les spécificités des réseaux d'ordinateurs, comme l'Internet, ces livres ont un défaut commun : il n'en existe à ma connaissance aucun qui soit distribué sous une licence libre. Résultat paradoxal : peu de livres expliquant le fonctionnement de l'Internet sont distribués via l'Internet.
Mais tout cela peut changer : grâce à Olivier Bonaventure et ses collègues de l'Université catholique de Louvain, un tel livre libre existe. Il se nomme Computer Networking : Principles, Protocols and Practice (CNP3 pour les intimes) et en est à sa troisième édition (voyez son site officiel). Quels sont les points importants de ce livre ?
CNP3 a été réalisé en petit comité (« cathédrale » et pas « bazar », pour reprendre une terminologie fameuse d'Eric Raymond). Cela garantit l'indispensable (pour un livre de cours) homogénéité et augmente les chances que quelque chose de concret soit produit (contrairement à plein de « livres » sur Wikibooks, qui ne dépassent pas le stade de l'intention et du remue-méninges). Résultat, je ne suis pas forcément d'accord avec certains choix pédagogiques (comme ces curieuses « primitives » réseau) mais, dans ce domaine, il est crucial de choisir une ligne et de s'y tenir.
Les outils pratiques utilisés sont classiques et les formats
utilisés sont naturellement des standards ouverts : texte en format
ReST, images en SVG,
git comme VCS (le source
est en ligne) et
suivi des bogues (voir la liste
actuelle en
).https://github.com/cnp3/ebook/issues
J'encourage donc tous les gens qui connaissent déjà les réseaux informatiques à participer au travail de relecture du texte, et ceux qui ne connaissent pas ce sujet à l'apprendre avec le livre, pour aider à indiquer les obscurités ou les approximations que les experts ne voient pas forcément.
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 :
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 :
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. Ce préfixe a d'ailleurs été élargi ultérieurement à d'autres systèmes que DS-Lite dans le RFC 7335.
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.
Première rédaction de cet article le 27 juillet 2011
L'informatique est à la fois un domaine de changements permanents (et souvent futiles) et d'extrême conservatisme. Sur bien des points, lorsque quelque chose marche, ou semble marcher, on n'y touche surtout pas. On voit ainsi parfois des survivances du passé bien vivantes, comme la persistance de résolveurs DNS qui utilisent le port source 53.
Les chiffres, d'abord. En regardant (avec DNSmezzo) un sous-ensemble des serveurs
DNS faisant autorité pour
.fr
, on observe que 1,8 % des clients
(les résolveurs) envoient toutes leurs requêtes
depuis un seul port source, le 53. Ces clients
représentent environ 1 % des requêtes (ce sont donc des petits
résolveurs, en moyenne). Ce n'est pas beaucoup, c'est
moins que le pourcentage de requêtes envoyées via
IPv6, mais, en 2011,
c'est surprenant.
En effet, utiliser toujours le même port source a un gros inconvénient : cela rend plus facile d'injecter une réponse DNS mensongère, permettant ainsi un empoisonnement du cache du résolveur (par exemple, avec la méthode Kaminsky). Normalement, le port source doit être aléatoire (RFC 5452, pensez à tester le vôtre). En outre, utiliser le port source 53 peut poser des problèmes avec certains pare-feux, qui demandent que le port source des clients soit supérieur à 1023 (les ports plus bas étant réservés aux serveurs).
Alors, pourquoi est-ce que certains (le plus gros résolveur de la liste est le principal FAI d'un pays d'Afrique) utilisent quand même le port source 53 ? Parce que c'était la méthode recommandée, à une époque très lointaine. Au début des années 1990, on recommandait d'utiliser un port source inférieur ou égal à 1023 pour les services critiques, car, sur une machine Unix, seul un logiciel lancé par root pouvait utiliser ce port source (rlogin avait une méthode de « sécurisation » équivalente). Aujourd'hui, évidemment comme chacun est root sur son PC Linux, sa tablette et son téléphone, cela semble ridicule mais cela a longtemps été une recommandation souvent donnée et très suivie. Lorsque les premiers pare-feux sont apparus, vers la même époque, il était courant de filtrer sur le port source (ce qui est bien plus contestable, puisque ce port est complètement contrôlé par l'assaillant présumé).
Cette recommandation se retrouvait dans le comportement du résolveur DNS le plus utilisé, BIND, qui, jusqu'à la version 8.1 (sortie en 1997), utilisait le port source 53 par défaut. Le script de conversion des anciens fichiers de configuration rajoutait ceci en commentaire :
/* * If there is a firewall between you and nameservers you want * to talk to, you might need to uncomment the query-source * directive below. Previous versions of BIND always asked * questions using port 53, but BIND 8.1 uses an unprivileged * port by default. */ // query-source address * port 53;
Ce message s'est donc retrouvé dans un grand nombre de fichiers de
configuration, named.conf
(y compris dans ceux
distribués par défaut dans des paquetages comme
celui de Debian), fichiers dont la syntaxe n'a
pas changé depuis.
Apparemment, un certain nombre d'administrateurs
systèmes avaient décommenté la ligne
query-source
. Et, depuis désormais quatorze ans,
ils recopient fidèlement leur named.conf
de
machine en machine, sans avoir jamais mis en cause ce réglage, et
sans s'être renseigné sur les évolutions de l'Internet. Bel exemple du
poids du passé.
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 les 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 :
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 :
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) :
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 :
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 :
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 :
example.com
,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'