Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

echoping

Ève

Recherche dans ce blog :

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.


BGP et le désormais célèbre attribut 99

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


Vendredi dernier, le 27 août, une expérience de mesure BGP menée par le RIPE-NCC et Duke University a révélé une bogue latente dans le code de certains modèles de routeurs Cisco, menant à la corruption des annonces BGP échangées, qui elle-même a entrainé la coupure de plusieurs sessions BGP, et finalement des perturbations plus ou moins fortes dans une partie de l'Internet. Cette panne a réactivé des débats sur la sécurité et la stabilité de l'Internet, ou bien sur la légitimité de procéder à de telles expériences.

Je ne vais pas détailler la panne elle-même car je n'étais pas là pour l'observer, je n'ai pas d'accès à toutes les données et, de toute façon, depuis une semaine, plusieurs très bons articles sont sortis sur le sujet. La meilleure synthèse est celle du RIPE-NCC. Bien plus technique, pour les amateurs de décodage de paquets, l'excellent article de Tassos et évidemment le RFC 4271, la norme de BGP (par exemple la section 4.3, sur les attributs, voir aussi le registre IANA des attributs). Et naturellement l'avis de sécurité de Cisco, qui donne plein de détails. Notons toutefois un point peu mentionné, le fait que le seul « privilège » qu'avait le RIPE-NCC est d'être bien connecté, avec beaucoup de peerings. Leurs annonces se propagent donc vite et loin. Mais, autrement, n'importe lequel des 40 ou 50 000 AS actifs pouvait faire pareil (si leur(s) opérateur(s) immédiats n'ont pas de Cisco bogué et transmettent l'annonce intacte). L'« expérience » aurait donc pu être faite par n'importe quel cyber-guerrier amateur.

Première question soulevée par cette panne : l'Internet est-il vraiment trop fragile ? Allons-nous tous mourir ? Al-Qaida va t-elle détruire la capacité de l'Occident à regarder YouTube toute la journée ? Faut-il refaire l'Internet en mieux ? Ou bien faire passer les routeurs sous le contrôle de l'US Army ? Ces questions resurgissent à chaque panne, surtout lorsqu'elle affecte des services dramatiquement essentiels. Des réunions sont organisés, des colloques causent, des rapports sont écrits. Mais, la plupart du temps, l'arbre cache la forêt et on oublie les points essentiels :

  • Il est très facile de perturber l'Internet, mais on est vite repéré et le problème est vite guéri. La panne du 27 août n'a duré qu'une heure. Même si le RIPE-NCC n'avait pas retiré l'annonce anormale, les ingénieurs auraient vite reconfiguré le réseau, comme cela a été le cas dans les affaires similaires.
  • L'Internet résiste aux soubresauts non pas parce que BGP est particulièrement bien conçu mais parce qu'il y a des gens compétents et dévoués derrière les routeurs. Rigidifier les procédures, augmenter le niveau de contrôle (dans le style UIT) aggraverait le problème au lieu de le résoudre, puisque cela empêcherait ces réactions intelligentes.
  • Il est facile de se vanter (et beaucoup de gens le font) qu'on peut construire un meilleur Internet. Techniquement, c'est faisable. Mais la vulnérabilité de l'Internet ne vient pas uniquement de ses protocoles mais aussi de leurs mises en œuvre. La faille du 27 août n'était pas dans BGP mais dans IOS XR. Les tenants d'une refonte de l'Internet ont-ils trouvé la méthode pour produire du logiciel sans bogue ? Si oui, il serait intéressant qu'ils la publient. De toute façon, la vulnérabilité fondamentale de l'Internet est qu'il connecte des organisations différentes et souvent ennemies. Tout réseau mondial aurait le même problème. Donc, soit on revient à un Minitel centralisé et national, soit on accepte le fait que la mondialisation a ses bons et ses mauvais côtés.
  • Peu de commentateurs ont relevé que le problème venait encore d'une bogue de Cisco. Bien sûr, d'autres marques de routeurs ont connu des bogues liées au traitement de BGP. Mais Cisco a quand même le record. Seulement, si on peut taper facilement sur le RIPE-NCC, s'attaquer à une grosse entreprise états-unienne ayant beaucoup d'avocats est plus difficile. Donc, peu de commentateurs ont osé dire qu'il fallait peut-être songer à faire des choix techniques différents et, au minimum, à diversifier les logiciels des routeurs. Ceci dit, si on veut défendre Cisco, le meilleur argument serait que les clients de ce vendeur réclament tout le temps des nouvelles fonctions, des nouveaux services et que l'accroissement du taille du logiciel qui en résulte ne va pas dans le sens de la fiabilité. Il faut savoir si on veut, de la stabilité ou bien le dernier truc à la mode...
  • Et enfin, un autre point doit être rappelé, lorsque je lis certaines indignations « Comment est-ce possible ? » ou « Que fait le gouvernement ? ». L'Internet n'est pas et ne doit pas être une infrastructure vitale. Bien sûr qu'il est important (par exemple, c'est lui qui justifie mon salaire) mais il n'y a pas de vies humaines en jeu. Si on voulait que des vies puissent être suspendues au bon fonctionnement de l'Internet (une très mauvaise idée), il faudrait en effet changer radicalement son architecture et en faire un réseau bien plus fermé, bien plus lent et bien moins innovant.

Et la deuxième question, celle de la légitimité à faire des tests sur le vrai Internet ? Plusieurs commentateurs (comme Pierre Col ou Earl Zmijewski - dans un article qui était autrement très intéressant) ont mis en cause le RIPE-NCC pour avoir fait des essais avec le vrai Internet. Des noms d'oiseax ont circulé avec des arguments du genre « on n'est plus à l'époque du réseau universitaire pour jouer, il faut maintenant être très prudent avec le réseau ».

Cet argument semble de bon sens mais il revient en fait à taper sur le messager parce qu'on n'aime pas le message. La panne est gênante et c'est justement pour cela qu'il faut féliciter le RIPE-NCC pour avoir testé et permis qu'on la découvre avant les méchants, qui l'auraient utilisé de manière bien plus agressive ! Pour la sécurité et la stabilité de l'Internet, il faut continuer à tester. Si on engueule le messager parce que le message nous déplait, plus personne n'osera faire de tests et on ne découvrira les problèmes que le jour d'une vraie attaque !

Au moins, aurait-il été possible de tester plus prudemment, comme semble le promettre le premier communiqué public du RIPE-NCC ? Par exemple, ne pouvait-on pas tester dans le laboratoire avant d'essayer sur le vrai Internet ? La lecture de l'article du RIPE-NCC montre bien que l'expérience avait été soigneusement étudiée (comme le montre le fait d'interposer un routeur BGP standard pour être sûr de n'émettre que du BGP légal, je n'y aurai pas pensé). Aurait-il fallu tester avec divers modèles de routeurs pour s'assurer qu'on ne les cassait pas ? Peut-être mais il n'y a de toute façon aucun chance pour qu'un laboratoire ait à sa disposition toutes les combinaisons de routeur et de logiciel (d'autant plus que la bogue « attribut 99 » n'affectait que le routeur suivant le routeur bogué). Il n'aurait donc pas été possible de tout tester. À un moment ou à l'autre, il faut passer aux essais en vrai grandeur. Comme l'avait noté un participant sur la liste Nanog, « I'm planning on announcing x.y.z.0/20 later in the week -- x, y and z are all prime and the sum of all 3 is also a prime. There is a non-zero chance that something somewhere will go flooie, shall I send mail now or later? ».

À défaut de pouvoir tout tester à l'avance, le RIPE-NCC aurait-il pu mieux communiquer ? Toute mesure active (ce qui était le cas de l'« expérience attribut 99 ») peut potentiellement pertuber le système qu'elle mesure. Le RIPE-NCC n'a, semble t-il, pas prévenu à l'avance, sa première annonce était envoyée sur une liste fermée (elle a ensuite été relayée sur une liste publique). Donc, oui, sur ce point et seulement sur celui-là, le RIPE-NCC aurait pu faire mieux. Ne nous faisons cependant pas trop d'illusions : les messages d'avertissement (« Nous allons annoncer pendant soixante minutes un attribut BGP non enregistré, depuis deux POP et pour le préfixe 203.0.113.0/24 ») sont en général complètement ignorés par les équipes opérationnelles déjà débordées...

Ah au fait, cette expérience, à quoi elle était destinée ? À la sécurité ! Il s'agissait de voir si certaines propositions techniques de sécurisation de BGP (pour empêcher des embrouilles à la Pakistan Telecom) étaient réalistes, car elles reposaient sur des attributs BGP nouveaux. Si on ne teste pas la possibilité de déployer ces extensions à BGP dans le vrai Internet, on peut arrêter tout de suite tout le travail sur le BGP sécurisé.

Si vous aimez les graphiques, deux jolis représentations de la baisse de trafic liées à la panne : http://www.bgpmon.net/ams-ix-ris-experiment.png et http://inl.info.ucl.ac.be/system/files/16all.png. Pour une analyse des conséquences de l'« expérience 99 » sur le DNS, voir le communiqué de l'AFNIC.


L'article seul

Fiche de lecture : What is Lojban?

Auteur(s) du livre: Nick Nicholas, John Cowan
Éditeur: Logical Language Group
0-9550283-1-7
Publié en 2003
Première rédaction de cet article le 1 Septembre 2010


Il existe d'innombrables langues construites, des langues qui ne sont pas issues d'une évolution « naturelle » mais qui ont été soigneusement élaborées par des humains. La plus connue est évidemment l'espéranto mais le lojban, présenté dans ce livre, a un cahier des charges assez différent. Son but principal n'est pas la paix dans le monde via la compréhension mutuelle, c'est la logique : faire une langue permettant de s'exprimer sans ambiguité, et qui soit complètement analysable par un analyseur syntaxique normal.

Le livre « What is lojban? » (ou, en lojban, « la lojban. mo », est un recueil de différents textes en anglais produits par l'organisation qui supervise la langue, le Logical Language Group. Pour ceux qui ne veulent ou ne peuvent acheter l'édition papier, il est aussi disponible en ligne. (Il y a aussi une version en français, malheureusement uniquement dans un format fermé, en lojban.doc.) Parmi les éditeurs de ce recueil, j'ai noté la présence de John Cowan, qui a été un des piliers du groupe de travail LTRU de l'IETF et j'ai pu apprécier, dans ce groupe, ses vastes connaissances, son excellent style et sa patience.

Que contient le livre ? La FAQ du site officiel, des exemples de courts textes en lojban, un guide de prononciation pour les locuteurs de diverses langues (mais pas le français) et surtout le texte « Overview of Lojban Grammar » qui décrit la structure de la langue. Ce n'est pas un tutoriel, pas question d'apprendre le lojban ainsi, mais c'est une description technique de la grammaire de la langue. À noter que, les composants d'un texte en lojban n'ayant pas forcément d'équivalent dans d'autres langues (des notions comme la distinction entre nom et verbe n'existent pas), ces composants sont désignés par leur nom en lojban. Il est donc prudent, en lisant le texte, d'avoir une fiche rappelant ce qu'est un brivla (le terme utilisé pour désigner un prédicat puisque le lojban est fondé sur la logique des prédicats), un sumti (l'argument d'un prédicat) ou un cmavo (catégorie qui regroupe les prépositions et ce pour quoi, dans d'autres langues, on utiliserait la ponctuation). Je ne vais pas résumer toute la grammaire lojban ici, juste décrire quelques points intéressants qui peuvent donner envie de voir le lojban de plus près.

Je commence par une phrase triviale en lojban, « mi klama le xunre zdani » (quelque chose comme « je vais à la maison rouge » ; si vous voulez voir un texte plus long, regardez la page d'accueil du site officiel). Comme le lojban est décrit par une grammaire formelle, en LALR(1), on peut écrire relativement facilement un analyseur syntaxique, comme par exemple le programme jbofihe. Cela donne :

% cat ~/tmp/hello.txt
mi klama le xunre zdani

% jbofihe -t ~/tmp/hello.txt  
| +-CMAVO : mi [KOhA3]
| | +-BRIVLA : klama
| | | +-CMAVO : le [LE]
| | | | +-BRIVLA : xenru
| | | | +-BRIVLA : zdani
| | | +-SELBRI_3
| | +-SUMTI_6
| +-BRIDI_TAIL_3
+-NO_CU_SENTENCE
CHUNKS

où le brivla le plus externe, klama joue le rôle du prédicat principal. jbofihe permet aussi de représenter l'arbre syntaxique sous d'autres formes par exemple en (mauvais) HTML avec l'option -H (notez qu'il a inclus une traduction des mots) :

[1(2[klama1 (go-er(s)) :] mi I, me)2 [is, does] <<3klama go-ing>>3 (4[klama2 (destination(s)) :] le the (5xunre red [type-of] zdani home(s))5)4]1

La même chose est possible en LaTeX avec l'option -l. Cette possibilité d'analyser syntaxiquement la langue permet le développement d'outils de traitement linguistique. jbofihe peut aussi vérifier que la syntaxe d'un texte est correcte. On peut même l'utiliser depuis Emacs avec un code d'initialisation comme :

(defun lojban-parse () ""
  (interactive "")      
  (shell-command-on-region (region-beginning) (region-end) "jbofihe"))

(global-set-key "\C-x-" 'lojban-parse)

(Il existe naturellement un mode Emacs pour le lojban.)

Après ce petit détour technique (désolé, problème classique des gens qui apprennent le loban, comme l'a montré un dessin de xkcd), quelques éléments intéressants sur la langue :

  • Chaque prédicat a un nombre d'arguments fixe et connu. Par exemple, tavla, « parler », a quatre arguments, le locuteur, le destinataire, le sujet et la langue utilisée. Si on utilise les quatre arguments, pas de problème. Si on ne spécifie que les N premiers, pas de problème, les autres sont optionnels. Mais si on ne spécifie, mettons, que le quatrième et qu'on veut dire « je parle en lojban » ? Deux solutions, un terme qui représente l'inconnu, zo'e ou bien des termes qui modifient l'ordre des arguments. Donc, la première solution serait mi tavla zo'e zo'e la lojban et la seconde mi tavla fo la lojbanfo indique que l'argument est normalement le quatrième (attention en comptant, le premier argument, ici mi, se met avant le prédicat).
  • Les questions se font en indiquant simplement mo ou ma à la place du terme qui serait la réponse à la question. Donc, le titre du livre, la lojban mo est une question dont la réponse serait la lojban EST-CECI-OU-CELA.
  • Le lojban permet de s'exprimer sans ambiguité, c'est là un élement essentiel de son cahier des charges. Mais il permet aussi de ne pas avoir à tout spécifier, si c'est inutile. Ainsi, en français, contrairement à l'anglais, on doit toujours préciser le genre de la personne dont on parle (comparez « je déjeune avec un ami » et « I have lunch with a friend ». En turc (exemple emprunté au Dictionnaire amoureux des langues), on doit toujours préciser si on a été témoin direct ou non du fait qu'on rapporte. En lojban, on peut omettre tout ce qu'on ne considère pas comme pertinent. Le genre de la personne, le temps des verbes, même le nombre de choses dont on parle sont optionnels. (Le lojban dispose de termes permettant, si on le juge utile, d'exprimer les nuances du turc sur l'observation directe ou pas d'un fait ; section « Evidentials », p. 104 dans l'édition papier.) Comme l'explique un excellent article du New York Times, les langues ne se différencient pas tant par ce qu'elles permettent ou empêchent de dire, mais par ce qu'elles imposent de préciser (ou pas).

Quelles ressources existent en lojban sur l'Internet ? Elles sont nombreuses, incluant un Wikipédia (peu rempli mais regardez par exemple l'article sur le phoque), un wiktionnaire (également peu rempli) et plein de choses en http://www.lobjan.org/. Il y a naturellement plusieurs listes de diffusion et canal IRC, avec un bot sympa qui me traduit un brivla et me donne ses arguments :

(23:05:39) bortzmeyer: valsi klama
(23:05:40) valsi: klama = x1 comes/goes to destination x2 from origin x3 via route x4 using means/vehicle x5. 

Quel est l'avenir du lojban ? C'est évidemment difficile à dire. Cette langue n'a pas échappé aux sorts de bien des projets marginaux, les scissions (en l'occurrence entre le Logical Language Group, qui gère le lojban, et le Loglan Institute, entre autre parce que le créateur originel de la langue prétendait détenir des droits de propriété intellectuelle. Voir la FAQ à ce sujet.

Mais, au delà de ces disputes assez glauques, le lojban reste une formidable aventure scientifique et intellectuelle. C'est un langage de geeks ? Tant pis, cela ne devrait pas arrêter les curieux.


L'article seul

Facebook joue avec BGP

Première rédaction de cet article le 31 Août 2010


Comme vous avez pu le voir, Facebook a été en panne pour beaucoup d'utilisateurs (surtout en Europe, il semble). La cause est un problème BGP.

De à peu près 1200 UTC à environ 1345, Facebook a été injoignable depuis beaucoup de réseaux. Les curieux qui ont fait un traceroute auront vu quelque chose du genre :

% traceroute www.facebook.com
traceroute to www.facebook.com (69.63.189.31), 64 hops max, 40 byte packets
 1  217.70.191.251 (217.70.191.251)  0 ms  0 ms  0 ms
 2  vl2.core4-d.gandi.net (217.70.176.132)  0 ms  0 ms  0 ms
 3  po88-jd4.core1-j.gandi.net (217.70.176.225)  1 ms  1 ms  1 ms
 4  po88-jd4.core1-j.gandi.net (217.70.176.225)  1 ms !H * *

montrant que le premier routeur BGP sans route par défaut n'avait pas de route vers le fameux réseau social... En effet, regarder quelques looking glasses (trouvés sur l'excellent http://www.traceroute.org/) confirme : « show ip bgp 69.63.190.14 \ Network not in table » ou des messages similaires. Si on a un routeur qui reçoit toute la table de routage de l'Internet, on peut voir que le réseau de Facebook apparait et disparait (ici un Juniper) :

admin@m7i-1-XXXX> show route 69.63.190.14

admin@m7i-1-XXXX>

...
admin@m7i-1-XXXX> show route 69.63.190.14

inet.0: 325150 destinations, 325150 routes (325081 active, 0 holddown, 69 hidden)
Restart Complete
+ = Active Route, - = Last Active, * = Both

69.63.184.0/21     *[BGP/170] 00:00:43, MED 0, localpref 100
                     AS path: 8220 8220 32934 I
                   > to X.Y.14.225 via fe-0/1/3.0

Résultat de ce yo-yo, les routeurs finissent par refuser automatiquement les annonces Facebook (« suppressed due to dampening »). Même lorsque Facebook a réparé sa configuration BGP, le problème a subsisté un certain temps. Voici un exemple sur le looking glass de PCH :

Looking Glass Results - route-collector.fra.pch.net
Date: Tue Aug 31 12:46:04 2010 UTC

Query:
Argument(s): 69.63.190.18

BGP routing table entry for 69.63.184.0/21
Paths: (2 available, no best path)
  Not advertised to any peer
  32934, (suppressed due to dampening)
    80.81.194.40 from 80.81.194.40 (204.15.20.1)
      Origin IGP, metric 0, localpref 100, valid, external
      Community: 3856:54800
      Dampinfo: penalty 5023, flapped 64 times in 01:09:18, reuse in 00:41:09
      Last update: Tue Aug 31 12:46:01 2010

  32934, (suppressed due to dampening)
    80.81.195.40 from 80.81.195.40 (204.15.23.109)
      Origin IGP, metric 0, localpref 100, valid, external
      Community: 3856:54800
      Dampinfo: penalty 4030, flapped 63 times in 01:09:18, reuse in 00:36:23
      Last update: Tue Aug 31 12:45:35 2010

Comme la configuration DNS de Facebook est très fragile (les serveurs de noms sont tous sur le même réseau), le DNS lui-même a des problèmes et, parfois, on ne peut pas résoudre le nom :

% traceroute www.facebook.com
traceroute: unknown host www.facebook.com

En effet, aucun serveur ne répond :

%  check_soa www.facebook.com 
There was no response from glb01.ash1.tfbnw.net
There was no response from glb01.ams1.tfbnw.net
There was no response from glb01.dfw1.tfbnw.net
...

Question DNS, notons aussi que les serveurs de facebook.com envoient des adresses IP différentes selon le demandeur. Cela explique en partie que Facebook ne soit pas en panne pour tout le monde (en Europe, www.facebook.com semble dans 69.63.184.0/21 et aux États-Unis dans 66.220.152.0/21). On peut avoir une bonne vision de la configuration BGP de Facebook en http://bgp.he.net/AS32934.


L'article seul

RFC 5963: IPv6 Deployment in Internet Exchange Points (IXPs)

Date de publication du RFC : Août 2010
Auteur(s) du RFC : R. Gagliano (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 31 Août 2010


Le fonctionnement de l'Internet aujourd'hui repose largement sur des points d'échange où les différents opérateurs se connectent pour échanger du trafic IP. Le point d'échange typique fournit un réseau Ethernet où chacun connecte son routeur, et alloue des adresses IP pour configurer ces dits routeurs, qui vont ensuite établir des liens BGP entre eux. La principale conclusion de ce nouveau RFC est que la très grande majorité des points d'échange fournissant un service de couche 2, le fait d'utiliser IPv6 au lieu d'IPv4 ne change pas grand'chose à la gestion du point d'échange.

La section 1 résume l'état actuel du monde des points d'échange. Presque toujours, le service rendu est une connexion de niveau 2, quasiment uniquement en Ethernet. Le principal service de niveau 3 rendu par les gérants du point d'échange est l'attribution d'adresses IP aux routeurs des opérateurs. Curieusement, ce service n'est pas mentionné dès la section 1, qui cite à la place des fonctions moins vitales comme le serveur de routes ou bien les statistiques (globales ou bien par protocole).

La section 2 du RFC passe ensuite aux questions liées à l'interface entre la couche de liaison et la couche réseau. IPv6 sur Ethernet doit se faire selon le RFC 2464. Le commutateur Ethernet lui-même, travaillant en couche 2, n'a rien de spécial à faire. On peut se poser la question de séparer les trafics v4 et v6. Cela peut se mettre en œuvre avec deux ports physiques sur le commutateur ou bien avec deux VLAN séparés. Mais cette séparation n'est pas indispensable. (Le faire avec des ports séparés consomme des ressources matérielles sur le routeur et le faire avec des VLAN impose aux routeurs de gérer 802.1Q.) Elle complique la configuration mais peut simplifier certaines fonctions comme les statistiques.

La section 3, plutôt descriptive que normative, décrit le mécanisme d'adressage à un point d'échange. Chaque RIR a sa politique pour l'allocation d'adresses IPv6 aux points d'échange. Ce sont typiquement des préfixes de longueur /48 qui sont alloués. Ces adresses ont besoin d'être résolvables en nom par le DNS et de pouvoir être trouvées dans la base des RIR via whois. Donc, un point d'échange n'utilise pas les ULA du RFC 4193. (Voyez par exemple les adresses IP allouées sur FranceIX.)

Par raport à un réseau local IPv6 typique, il faut aussi noter que l'autoconfiguration des adresses pa l'envoi de RA (Router Advertisment) n'est typiquement pas utilisée. La configuration des routeurs est faite manuellement puisque, de toute façon, la configuration de BGP dépend de l'adresse. Puisqu'on n'utilise pas l'autoconfiguration, que mettre dans les 64 bits les plus à droite ? En IPv4, les routeurs à un point d'échange sont en général numérotés séquentiellement mais l'espace d'adressage bien plus grand d'IPv6 permet des plans d'adressage plus informatifs. Il existe plusieurs mécanismes acceptables :

  • Encoder le numéro d'AS en décimal dans les 64 bits. Ainsi, si le point d'échange utilise le préfixe 2001:db8:f00f::/64 et qu'un opérateur connecté a le numéro d'AS 64496, son adresse IP sera 2001:db8:f00f::6:4496:1 (le 1 tout à fait à droite vient de la réservation des 16 derniers bits pour mettre plusieurs routeurs par opérateur connecté, si nécessaire).
  • Certains préfèrent l'hexadécimal, moins lisible mais plus compact, donc ici 2001:db8:f00f::fbf0:1.
  • Une autre méthode est de dériver l'adresse IPv6 de la v4. donc un routeur qui aurait 192.0.2.123 en v4 recevra 2001:db8:f00f::123 en v6 (ce n'est qu'un exemple, le RFC en cite un autre, qui permet des points d'échange de plus de 256 routeurs, contrairement à mon choix de ne garder que le dernier octet).
  • etc (d'autres méthodes sont possibles).

Ces adresses IP du point d'échange doivent-elles être routées globalement ? Le débat a toujours fait rage pour IPv4 et n'est pas différent ici. Les adresses routées globalement facilitent la configuration et le déboguage mais peuvent rendre le point d'échange plus vulnérable à certaines attaques. Si on ne route pas globalement ces adresses, les participants au point d'échange peuvent toujours le faire eux-même dans leur réseau, en prenant soin d'utiliser des méthodes comme la communauté no-export de BGP, pour éviter que les annonces des routes vers le point d'échange ne se propagent trop loin. Enfin, le point d'échange a aussi des services publics (pages Web, serveur DNS, serveurs NTP, etc) et ceux-ci doivent évidemment être installés sur des adresses routables, que ce soit dans le même préfixe que celles des routeurs des participants ou bien dans un préfixe différent.

Une des particularités d'un point d'échange est que les routeurs qui y sont présents appartiennent à des organisations différentes, souvent concurrentes. Le réseau Ethernet partagé n'est donc pas forcément peuplé que par des gentils paquets, on y trouve un peu de tout, des annonces OSPF aux serveurs DHCP illicites... La section 4 mentionne ce problème et ses conséquences pour la sécurité et note que le gérant du point d'échange peut, par exemple, limiter l'utilisation de la diffusion (qui sont transmis à tous) aux paquets de découverte des voisins (RFC 4861. En tout cas, bloquer les paquets Router Advertisment (qui ne devraient jamais apparaître sur le réseau du point d'échange) est conseillé.

Tiens, puisqu'on a parlé du DNS, la section 5 lui est consacrée. Elle recommande que les adresses IP du point d'échange aient un enregistrement « inverse » (enregistrement PTR) dans le DNS, pour faire de plus jolis traceroute et, de manière générale, pour faciliter le déboguage.

Un autre service très populaire sur les points d'échange est le serveur de routes, discuté en section 6. Il sert parfois à échanger réellement des routes entre pairs, et parfois simplement de looking glass. Voir par exemple le looking glass du DE-CIX. Notre RFC recommande qu'il soit accessible en IPv6 mais surtout qu'il gère les extensions à BGP des RFC 2545 et RFC 4760, qui permettent de gérer plusieurs familles d'adresses IP, donc de gérer des routes IPv6. Une autre recommandation est que les routes IPv6 soient échangées sur des sessions IPv6 (ce qui n'est pas obligatoire avec BGP), pour améliorer la cohérence de l'information de routage (si un pair BGP reçoit des informations sur IPv6, il peut être sûr que le pair qui lui annonce des routes IPv6 est lui-même effectivement joignable par ce protocole).

Enfin, la section 7 traite les cas « divers ». Par exemple, un des points peu spectaculaire, mais souvent critique, d'une transition vers IPv6 est l'adaptation des systèmes d'avitaillement (la base de données qui stocke les adresses des participants au point d'échange...) : ces systèmes doivent eux aussi être migrés de manière à pouvoir gérer des adresses IPv6.

La section 8 couvre le cas des politiques d'accès au point d'échange. Les règles d'utilisation doivent bien préciser si le contrat concerne seulement IPv4, seulement IPv6 ou bien les deux. Je me souviens, il y a quelques années (les choses ont peut-être changé depuis) que le contrat avec le Sfinx ne couvrait qu'IPv4 (alors que l'organisme qui gère le Sfinx se vantait de son rôle pionnier en IPv6) et qu'il fallait une paperasserie longue et compliquée pour pouvoir faire de l'IPv6. Notez que notre RFC ne formule pas de recommandation précise sur la politique idéale. Pour moi, le contrat devrait couvrir IP, quelle que soit sa version, car il n'existe aucune justification opérationnelle pour traiter IPv6 comme un « plus », imposant un contrat nouveau.


Téléchargez le RFC 5963


L'article seul

RFC 5965: An Extensible Format for Email Feedback Reports

Date de publication du RFC : Août 2010
Auteur(s) du RFC : Y. Shafranovich (ShafTek Enterprises), J. Levine (Taughannock Networks), M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 31 Août 2010
Dernière mise à jour le 1 Septembre 2010


Les opérateurs de réseaux et de serveurs, aujourd'hui, passent beaucoup de temps à s'envoyer des rapports indiquant qu'un message reçu est en fait abusif, spam ou hameçonnage. Ces rapports sont désormais bien trop nombreux pour être traités manuellement et il est donc nécessaire de définir un format standard pour les représenter, de façon à permettre un minimum de traitement automatique sur ces rapports. C'est ce que fait notre RFC, le premier du groupe de travail MARF. Ce format s'appuie évidemment sur MIME.

Avant l'adoption du format MARF (qui précède sa normalisation formelle dans ce RFC), plusieurs opérateurs avaient défini des formats privés (section 1). Cela rendait évidemment difficile l'analyse des rapports envoyés, il fallait écrire du code pour chaque opérateur. Désormais, il existe donc un format standard, basé sur le type MIME multipart/report normalisé dans le RFC 3462. Ce format utilise le sous-type (« type du rapport ») feedback-report.

Ce n'est pas la première tentative de normalisation dans ce domaine, les précédentes n'ont pas été des succès.

Ce RFC ne fait que normaliser un format, il ne spécifie pas à qui les rapports doivent être envoyés, comment les authentifier, ou ce qu'il faut en faire, il se focalise sur l'aspect technique. Le cahier des charges figure en section 1.2 :

  • Le format devait être lisible à la fois par un humain et par un programme,
  • Le message signalé devait être inclus dans le rapport,
  • Le format devait permettre l'ajout de méta-données,
  • Le format devait être extensible.

Ces objectifs ont-il été atteints ? Voyons la définition du nouveau format (une certaine familiarité avec le RFC 5598 est utile).

La section 2 du RFC décrit le format MARF. Un message MARF est donc un message MIME multipart/report, tel que défini dans le RFC 3462. Le type du rapport est feedback-report (donc le message contiendra un en-tête du genre Content-Type: multipart/report; report-type=feedback-report; ...). Chaque rapport ne concerne qu'un seul message, il n'y a pas de mécanisme pour l'agrégation de messages. Il comprend trois parties MIME obligatoires :

  • La première est une description en langue naturelle du rapport,
  • La seconde est un ensemble de méta-données structurées, de type MIME message/feedback-report,
  • La troisième est le message original, de type message/rfc822 en général (rappelez-vous que MIME est récursif et qu'il est donc parfaitement possible d'avoir un message MIME dans un autre message MIME).

Le sujet du rapport doit être le champ Subject: du message original, éventuellement avec un préfixe comme FW: (pour forwarded), ce qui me semble déroutant car, en examinant sa boîte aux lettres manuellement, on ne distingue pas facilement les spams des rapports sur les spams.

Focalisons-nous un instant sur la seconde partie, les méta-données. Le format de ce nouveau type MIME message/feedback-report est décrit dans la section 3. Cette partie est composée de plusieurs champs, suivant la syntaxe des en-têtes du courrier (attention, seule leur syntaxe est identique, un champ de même nom qu'un champ du RFC 5322 n'a pas forcément la même sémantique). Comme pour tout le contenu du rapport, le destinataire ne doit pas forcément leur faire une confiance aveugle. Ils représentent des assertions du créateur du rapport et ne sont pas forcément vérifiables.

La liste des champs n'est pas fixée définitivement, de nouveaux champs pourront être enregistrés dans le futur. Aujourd'hui, la liste des champs obligatoires comprend (section 3.1) :

  • Feedback-Type:, défini dans la section 3.5,
  • User-Agent:, indiquant le logiciel qui a produit le rapport,
  • Version:, aujourd'hui toujours 1.

Il y a aussi des champs facultatifs, parmi lesquels (sections 3.2 et 3.3) :

  • Arrival-Date: indiquant l'heure de réception,
  • Authentication-Results: qui indique les résultats des procédures d'authentification, tels que formalisés par le RFC 5451,
  • Incidents:, un nombre indiquant le nombre de fois que ce message a été reçu,
  • Reported-Domain:, qui indique le nom du coupable présumé (par exemple parce que le message vient de lui),
  • Reported-URI:, qui indique un URI pertinent pour le rapport, par exemple l'URL d'un site Web de hameçonnage pour lequel un spam faisait de la publicité,
  • Source-IP:, indiquant l'adresse IP source au moment où le message est entré dans le domaine qui génère le rapport,
  • Et bien d'autres (la liste complète et à jour figure dans le registre). Notez que certains champs facultatifs peuvent apparaitre plusieurs fois (comme Reported-URI:) et d'autres une et une seule fois (comme Arrival-Date:).

Un exemple d'une telle partie :


Feedback-Type: abuse
User-Agent: SomeGenerator/1.0
Version: 1
Arrival-Date: Thu, 8 Mar 2005 14:00:00 EDT
Source-IP: 192.0.2.1
Authentication-Results: mail.example.net;
               spf=fail smtp.mail=somespammer@example.com
Reported-Domain: example.com
Reported-Uri: http://example.com/earn_money_fast.html

La grammaire complète figure en section 3.5.

On le sait, le courrier électronique est une jungle où tout est possible. Les rapports peuvent être mensongers ou, tout simplement, incorrects techniquement. Que faire dans ce cas ? La section 4 est claire : de tels messages devraient être ignorés ou rejetés. Le principe de robustesse (« Acceptez n'importe quoi et essayez de le décoder ») ne s'applique pas aux questions de sécurité.

Je l'ai dit plus haut, une des exigences du cahier des charges était l'extensibilité. La section 6 expose les moyens déployés par MARF pour atteindre ce but. Notamment, deux registres IANA sont créés, pour pouvoir ajouter des nouvelles données : le registre des types de retours (feedback types) et celui des champs dans les méta-données. Les types et les champs inconnus doivent donc être ignorés par les programmes, afin de pouvoir ajouter des nouveaux sans casse.

Les registres en question sont décrits de manière plus formelle dans la section 7. Celle-ci décrit l'enregistrement du nouveau type MIME message/feedback-report, le nouveau registre des méta-données (dans lequel on peut enregistrer par la procédure « spécification obligatoire » du RFC 5226) et le nouveau registre des types de retour (même procédure pour l'enregistrement). Aujourd'hui, ce registre contient des types comme abuse (courrier non sollicité), fraud (courrier de tentative d'escroquerie), virus (courrier contenant un virus), etc.

Comme tout ce RFC porte sur un problème de sécurité, il est normal que la section dédiée à ce sujet, la 8, se demande si le nouveau format est lui-même sûr. Elle met notamment en garde contre les interprétations abusives (section 8.2) : cette norme décrit juste un format, elle ne garantit pas que les rapports, même syntaxiquement corrects, soient authentiques. Le mécanisme par lequel on décide de faire confiance (ou pas) à un rapport n'est pas spécifié par ce RFC. Il est donc déconseillé de déclencher automatiquement des actions (comme l'inscription sur une liste noire) sur la seule base d'un rapport, sans précautions supplémentaires.

Par exemple, le RFC recommande que les rapports soient un minimum authentifiés, par le biais de techniques comme SPF, DKIM ou S/MIME (ce dernier est conseillé mais, curieusement, PGP n'est pas cité).

Autre problème de sécurité lié à ces rapports, le risque d'attenter à la vie privée. La section 8.5 rappelle que la règle devrait être d'envoyer des rapports complets mais, si la protection de la vie privée le nécessite, qu'on peut supprimer certaines parties du rapport pour ne pas révéler d'informations privées. (Même si on devine que cette idée de vie privée défrise considérablement les auteurs du RFC.)

Peut-on générer automatiquement des rapports MARF (section 8.6), par exemple parce qu'un pot de miel a reçu un spam ? Le RFC met en garde : un attaquant qui sait qu'un tel générateur existe pourrait l'utiliser pour faire fabriquer des rapports contre ses ennemis, en envoyant de faux spams.

Encore un piège amusant : les rapports seront souvent générés pour des messages qui contiennent du logiciel malveillant. Ledit logiciel va se trouver dans la partie du rapport qui reprend le message original. Les processeurs de messages MARF doivent donc faire attention à ne pas, par exemple, exécuter accidentellement le méchant logiciel (section 8.7) !

Un exemple plus complet est cité dans l'annexe B2 du RFC (le message original a le sujet Earn money et prétend venir de somespammer@example.net) :


From: <abusedesk@example.com>
Date: Thu, 8 Mar 2005 17:40:36 EDT
Subject: FW: Earn money
To: <abuse@example.net>
MIME-Version: 1.0
Content-Type: multipart/report; report-type=feedback-report;
  boundary="part1_13d.2e68ed54_boundary"

--part1_13d.2e68ed54_boundary
Content-Type: text/plain; charset="US-ASCII"
Content-Transfer-Encoding: 7bit

This is an email abuse report for an email message received from IP
192.0.2.1 on Thu, 8 Mar 2005 14:00:00 EDT.  For more information
about this format please see http://www.mipassoc.org/arf/.

--part1_13d.2e68ed54_boundary
Content-Type: message/feedback-report

Feedback-Type: abuse
User-Agent: SomeGenerator/1.0
Version: 1
Original-Mail-From: <somespammer@example.net>
Original-Rcpt-To: <user@example.com>
Arrival-Date: Thu, 8 Mar 2005 14:00:00 EDT
Reporting-MTA: dns; mail.example.com
Source-IP: 192.0.2.1
Authentication-Results: mail.example.com;
            spf=fail smtp.mail=somespammer@example.com
Reported-Domain: example.net
Reported-Uri: http://example.net/earn_money.html
Reported-Uri: mailto:user@example.com
Removal-Recipient: user@example.com

--part1_13d.2e68ed54_boundary
Content-Type: message/rfc822
Content-Disposition: inline

From: <somespammer@example.net>
Received: from mailserver.example.net (mailserver.example.net
  [192.0.2.1]) by example.com with ESMTP id M63d4137594e46;
  Thu, 08 Mar 2005 14:00:00 -0400
To: <Undisclosed Recipients>
Subject: Earn money
MIME-Version: 1.0
Content-type: text/plain
Message-ID: 8787KJKJ3K4J3K4J3K4J3.mail@example.net
Date: Thu, 02 Sep 2004 12:31:03 -0500

Spam Spam Spam
Spam Spam Spam
Spam Spam Spam
Spam Spam Spam
--part1_13d.2e68ed54_boundary--

Qui utilise ou utilisera ce format ? Je n'ai pas trouvé sur le site officiel de liste des implémentations (pour générer et analyser du MARF). Il faut se contenter des liens en http://wordtothewise.com/resources/arfdeveloper.html. Mais, apparemment, plusieurs opérateurs utilisent déjà ce format. Idéalement, on devrait pouvoir l'utiliser pour soumettre des rapports à abuse@opérateur.net et à des organismes comme Signal-Spam (ce dernier semble tout à fait mort). Mais cela ne semble pas possible actuellement.


Téléchargez le RFC 5965


L'article seul

Les belles erreurs de l'Encyclopædia Universalis

Première rédaction de cet article le 29 Août 2010


Comme il y a encore des gens (de plus en plus rares) qui prétendent, contre toute évidence, que les encyclopédies traditionnelles comme l'Encyclopædia Universalis sont plus fiables et mieux vérifiées qu'une encyclopédie collaborative comme Wikipédia, je publie ici la lettre que j'ai envoyée le 24 juin à l'Encyclopædia Universalis, à propos des erreurs dans leur article sur Internet.

L'Encyclopædia Universalis n'est pas consultable librement en ligne. Donc, je ne peux pas dire si l'article a été corrigé. En tout cas, je n'ai jamais reçu de réponse. Voici quelles étaient mes remarques au sujet de http://www.universalis-edu.com/encyclopedie/internet-les-applications/ (l'abonnement est payant donc cet URL ne marchera que si vous êtes abonné).

Un ami m'a fait lire l'article http://www.universalis-edu.com/encyclopedie/internet-les-applications/. Il contient des erreurs plutôt sérieuses. Je ne cite que les trois premières :

  • Le TLD espagnol est .ES pas .SP.
  • Dire que « RIPE-NCC (Réseaux IP européens-Network Coordination Center) a reçu de l'I.C.A.N.N. la gestion des noms de domaine pour l'Europe. » est complètement faux. Le RIPE-NCC gère les adresses IP et n'a pas d'activité sur les noms de domaine. Des énormités pareilles ne vont pas aider les lecteurs à comprendre les délicats rouages de la gouvernance d'Internet. Le seul élément de vérité est le fait que, il y a une quinzaine d'années, avant donc la création de l'ICANN, le RIPE-NCC avait participé à la gestion de certains TLD européens. Ce n'est plus le cas depuis longtemps (et, de toute façon, cela n'a rien à voir avec l'ICANN).
  • « La référence MIME (multi purpose mail extension, RFC 822) » Ce vieux RFC est antérieur à MIME de dix ans ! MIME a été normalisé dans le RFC 1341 en juin 1992. Il est pourtant facile de vérifier l'index des RFC :-(

La lecture de cet article donne à penser qu'il a été rédigé par des gens qui ne connaissaient pas le sujet et, pire, qu'il n'a pas été relu par des experts. Compte-tenu du sérieux de ces erreurs, je compte sur une prompte correction, qui montrerait que les encyclopédies traditionnelles apportent réellement un plus par rapport à Wikipédia.

Voici ce que j'avais écrit à l'Encyclopædia Universalis, via leur formulaire de contact en ligne, et qui n'a jamais reçu de réponse. Notez bien que j'ai arrêté ma lecture très vite, après trois erreurs aussi énormes. D'autres attendaient certainement derrière.

Ces erreurs sont-elles graves ? Pas forcément mais elles montrent une extrême négligence. Par exemple, donner comme exemple de TLD .SP pour l'Espagne montre à la fois une grande paresse (rien n'est plus facile que de vérifier la liste des TLD) et un manque de familiarité avec les noms de domaine (ce qui n'est pas grave pour l'internaute lambda mais est bien plus sérieux lorsqu'on prétend faire une encyclopédie de référence).

Même chose pour l'erreur sur MIME : rien n'était plus facile que de vérifier le RFC 822 et de voir qu'il ne disait pas un mot de MIME.

Et, surtout, si l'erreur est humaine, ne pas corriger les problèmes signalés est quoi ?


L'article seul

RFC 5961: Improving TCP's Robustness to Blind In-Window Attacks

Date de publication du RFC : Août 2010
Auteur(s) du RFC : A. Ramaiah (Cisco Systems), R. Stewart (Huawei), M. Dalal (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 27 Août 2010


Le protocole TCP, à la base de la grande majorité des transferts de données sur l'Internet, souffre depuis longtemps de plusieurs vulnérabilités. L'une d'elles est sa susceptibilité à des attaques par injection de faux paquets, qui ne proviennent pas d'une des deux extrêmités de la connexion TCP. Un sous-ensemble de ces attaques, les attaques en aveugle, concerne les cas où l'attaquant n'est même pas sur le chemin entre les deux extrêmités (on dit qu'il est off-path) et doit deviner les numéros de séquence TCP pour que ses faux paquets soient acceptés. Ce nouveau RFC expose le problème et des moyens d'en limiter les effets.

Le problème des attaques en aveugle était traditionnellement considéré comme de peu d'importance. En effet, pour que le paquet injecté soit accepté comme légitime, il devait reproduire adresses IP source et destination, ports source et destination et un numéro de séquence situé dans la fenêtre. (Le concept de numéro de séquence TCP est décrit dans le RFC 793, section 3.3. Chaque octet transmis a un numéro de séquence et, à un moment donné, seule une plage de numéros, la fenêtre, est acceptable, car envoyée mais non encore reçue et validée.) À partir du moment où le numéro de séquence initial est choisi aléatoirement (ce qui n'a pas toujours été le cas, cf. RFC 1948, mais est désormais fait dans toutes les mises en œuvre de TCP), un attaquant aveugle, qui ne peut pas sniffer le réseau, n'a guère de chance de deviner juste et donc de fabriquer un faux qui soit accepté. (Voir le RFC 4953 pour les détails sur les attaques contre TCP.)

Mais les choses changent. En raison de l'augmentation de capacité des réseaux, les fenêtres TCP voient leur taille accrue, améliorant les chances de l'attaquant. Et certaines sessions TCP sont très longues (par exemple avec BGP ou avec H.323), avec des adresses IP et des ports prévisibles. En profitant de ces faiblesses, un attaquant peut alors voir ses faux paquets acceptés, et effectuer ainsi des DoS (si le faux paquet est un RST, qui coupe la connexion) ou modifiant les données (si le faux paquet contient des données).

La section 1 du RFC résume ce problème, aggravé par des implémentations comme celles de BGP qui utilisent souvent des ports prévisibles des deux côtés (même du côté client, où ce n'est pas obligatoire). La section 1.2 décrit en détail comment conduire une telle attaque, en prenant l'exemple d'une attaque RST, visant à couper des connexions TCP. La principale difficulté pour l'attaquant est que le numéro de séquence du paquet portant le bit RST doit se situer dans la fenêtre de réception actuelle (mais, bien sûr, l'attaquant a le droit d'injecter plusieurs paquets, pour essayer plusieurs fenêtres potentielles). Les chances du succès du méchant dépendent donc de la taille de la fenêtre. Elle est en général assez facile à déterminer (et cela donne une bonne idée du nombre de d'essais qu'il faudra faire). Une fois qu'il a une idée du numéro de séquence utilisé, l'attaquant peut alors commencer à envoyer des paquets RST, incrémentant le numéro de séquence par la taille de la fenêtre, à chaque nouvel essai. Au bout d'un moment, il a de fortes chances de tomber juste. Les calculs complets se trouvent dans l'article de Watson, « Slipping in the Window: TCP Reset attacks, Presentation at 2004 CanSecWest » et la question est également traitée dans le RFC 4953. La section 1.3 de notre RFC contient également ces calculs de probabilité de réussite.

Le fait que l'attaquant puisse , selon les règles du RFC 793, utiliser n'importe quel numéro de séquence situé dans la fenêtre de réception lui facilite la tâche (en moyenne, seulement 2^31/$WindowSize essais). Changer TCP pour n'accepter les RST que si le numéro de séquence est exactement celui attendu protégerait sérieusement, obligeant l'attaquant à bien plus d'essais (2^31 en moyenne). Sans ce changement, avec une fenêtre typique de 32 768 octets, 65 536 paquets suffisent pour une attaque réussie, en moyenne. Et les tailles des fenêtres tendent à augmenter, en raison de l'augmentation de capacité des réseaux, ce qui rend l'attaque de plus en plus facile.

Il existe bien sûr d'autres protections contre cette attaque, variables en coût et en complexité. IPsec, l'authentification TCP-AO du RFC 5925, etc. Des ports source choisis de manière réellement aléatoire aident aussi.

Les sections suivantes décrivent en détail les différentes possibilités d'une attaque en aveugle, ainsi que les méthodes à utiliser pour les rendre moins efficaces. Ainsi, la section 3 décrit les attaques utilisant le bit RST (ReSeT) du paquet TCP. Le RFC 793 (section 3.4) précise que la connexion doit être coupée lorsqu'un paquet portant ce bit est reçu (si le numéro de séquence est bien dans la fenêtre). Une mise en œuvre correcte de TCP est donc vulnérable à des paquets envoyés en aveugle, si l'attaquant peut trouver un bon numéro de séquence. Comment limiter les risques de ce déni de service ? La section 3.2 de notre RFC décrit le mécanisme suggéré, remplaçant l'algorithme du RFC 793 : ne couper la connexion que si le paquet entrant a pile le bon numéro de séquence. Si le numéro n'est pas celui attendu, mais figure néanmoins dans la fenêtre, envoyer un accusé de réception. Puisque l'attaquant aveugle ne pourra pas le recevoir, il ne pourra pas confirmer le reset (contrairement au pair légitime, qui recevra l'accusé de réception et, ayant coupé la connexion de son côté, renverra un RST qui sera, lui, accepté, puisque son numéro de séquence correspondra audit accusé). Un tel algorithme complique donc nettement les choses pour l'attaquant. Son principal inconvénient est qu'un RST légitime, mais qui n'a pas pile le bon numéro de séquence (par exemple parce que le paquet précédent a été perdu) ne coupera pas la session TCP légitime, il faudra attendre la confirmation.

Et si l'attaquant met le bit SYN (SYNchronize) à un ? La section 4 rappelle qu'une fois la connexion TCP établie, un paquet portant ce bit, toujours si le numéro de séquence figure dans la fenêtre, va couper la connexion. La section 4.2 demande donc que, pour tout paquet SYN reçu après l'établissement initial de la connexion, quel que soit son numéro de séquence, on envoie un accusé de réception. L'attaquant aveugle ne le verra pas et ne pourra pas confirmer. Le pair légitime qui avait envoyé un SYN (ce qui ne devrait pas arriver en temps normal et signifie probablement que le pair avait perdu tout souvenir de la connexion, par exemple suite à un redémarrage) enverra alors un RST puisque, pour lui, la session n'est pas ouverte.

Les deux attaques précédentes (RST et SYN) étaient des dénis de service. Mais on peut imaginer une attaque bien pire où le méchant réussit à injecter de fausses données dans une connexion TCP. Elle fait l'objet de la section 5. Si le méchant peut trouver un numéro de séquence dans la fenêtre, ses paquets de données seront acceptés et pourront être présentés à l'application qui utilise TCP (le succès effectif de l'attaque dépend d'un certain nombre de points, et peut dépendre de la mise en œuvre de TCP utilisée).

Pour contrer cette attaque, la section 5.2 demande de durcir les conditions d'acceptation des paquets de données. Davantage de paquets légitimes seront donc rejetés, afin de pouvoir compliquer la vie de l'attaquant.

À noter (section 6) que les recommandations des trois précédentes sections ne sont pas formulées avec la même force. Utilisant le vocabulaire du RFC 2119, les deux premières sont des fortes recommandations (SHOULD) et la troisième seulement une suggestion (MAY). En effet, une injection de données par un attaquant est bien plus difficile (car les vraies données finiront par arriver, avec un numéro de séquence légèrement différent, ce qui peut mener TCP à refuser soit les fausses, soit les vraies) et ne justifie donc pas d'imposer des contre-mesures qui peuvent mener au rejet de paquets légitimes.

Dernier conseil, celui de la section 7, la nécessité de limiter la quantité d'accusés de réception (ACK) émis. Avec les contre-mesures des sections 3 à 5, le nombre de paquets ACK va augmenter. La section 7 suggère donc de les limiter, par exemple à dix ACK de confirmation pour toute période de cinq secondes (et que ces chiffres soient réglables par l'administrateur système).

Les recommandations de notre RFC 5961 modifient légèrement le protocole TCP. Cela nécessite donc une section 8, décrivant les problèmes de compatibilité qui peuvent se poser entre deux mises en œuvre de TCP, l'une conforme à notre nouveau RFC 5961, l'autre plus ancienne. Normalement, les modifications du protocole sont 100 % compatibles avec le TCP existant. La section 8 décrit toutefois un cas limite où la coupure d'une connexion nécessitera un aller-retour supplémentaire.

D'autre part, le succès complet des contre-mesures décrites dans ce RFC impose qu'elles soient déployées des deux côtés. Une mise en œuvre moderne de TCP parlant à un vieux pair ne fournirait pas une protection complète.

Dernier problème avec les nouveaux algorithmes : le cas des middleboxes, ces équipements qui se mettent sur le trajet de deux machines IP qui communiquent et qui brisent souvent la transparence du réseau (par exemple les pare-feux). La section 9 examine les problèmes qu'elles peuvent poser. Par exemple, certains équipements ré-envoient le RST pour le compte du vrai pair TCP (section 9.1) et, s'ils ne mettent pas en œuvre les recommandations de ce RFC, peuvent ne pas traiter correctement le ACK de demande de confirmation. Ce genre de problèmes survient souvent lorsqu'une middlebox est « ni chair, ni poisson », ni un pur routeur transparent aux paquets de la couche 4 (TCP), ni un vrai pair TCP. Autre exemple cité (section 9.3), un équipement intermédiaire qui, en voyant passer le RST, supprimerait toute l'information associée à cette connexion TCP. Le ACK de demande de confirmation pourrait alors être jeté, et ne recevrait donc pas de réponse, laissant ainsi une connexion TCP ouverte.

Enfin, la traditionnelle section « Security Considerations » (section 10) synthétise l'ensemble des questions liées à ces contre-mesures. Elle rappelle notamment que le problème traité par ce RFC ne concerne que les attaques en aveugle, typiquement lorsque l'attaquant n'est pas sur le chemin des paquets. S'il l'est, par exemple si l'un des deux pairs TCP est sur un réseau Wi-Fi public, les contre-mesures des sections 3 à 5 ne s'appliquent pas, car elles peuvent facilement être contournées par un attaquant en mesure de regarder les paquets, et de voir quel est le numéro de séquence à utiliser. Ce fut le cas par exemple dans les attaques menées par Comcast contre ses propres clients ou bien dans celles perpétrées par la dictature chinoise.

Même dans le cas d'une attaque en aveugle, les contre-mesures de notre RFC n'empêchent pas l'attaque, elles la rendent simplement beaucoup plus difficile. Un attaquant chanceux peut donc encore réussir, même contre des implémentations de TCP parfaitement à jour. La section 10 rappelle (vœu pieux) que la seule vraie protection serait de généraliser IPsec (par exemple avec l'ESP du RFC 4303).

D'autre part, ce RFC 5961 ne traite que les attaques faites uniquement avec TCP mais ICMP fournit aux attaquants aveugles d'autres possibilités (traitées dans le RFC 5927). Une mise en œuvre sérieuse de TCP doit donc traiter également ces attaques ICMP.

Aucun médicament n'est sans effet secondaire et c'est également le cas ici. Les contre-mesures de notre RFC peuvent créer des possibilités d'attaque par réflexion, si l'attaquant déguise son adresse IP : des paquets comme l'ACK de demande de confirmation seront alors envoyés à un innocent. Le RFC estime ce problème peu grave car il n'y a pas amplification : l'attaquant pourrait donc aussi bien viser directement la victime.


Téléchargez le RFC 5961


L'article seul

Un exemple de panne amusante de tcpdump

Première rédaction de cet article le 26 Août 2010


Voici un cas rigolo qui m'est arrivé hier. Soit une machine Debian/Linux où les programmes de capture de paquets (comme tcpdump) tout marchaient autrefois. Tout à coup, plus aucun filtre BPF ne trouve un seul paquet...

tcpdump sans argument donne le résultat attendu :

% sudo tcpdump -i eth1 -n
12:36:40.723290 IP 193.243.207.47.31619 > 192.93.0.129.53: 40691 [1au] MX? doublev.fr. (39)
12:36:40.723440 IP 192.93.0.129.53 > 193.243.207.47.31619: 40691- 0/2/3 (112)
12:36:40.723480 IP 212.96.9.225.2123 > 192.93.0.129.53: 46420+ MX? fema.fr. (25)
12:36:40.723634 IP 192.93.0.129.53 > 212.96.9.225.2123: 46420- 0/2/0 (81)
...

Mais aucun filtre BPF ne trouve ne serait-ce qu'un seul paquet. Dès que je mets comme argument port 53, ou udp ou même ip, je n'ai plus aucun paquet. Par contre, les filtres not ip ou bien not port NN (pour n'importe quelle valeur de NN) me montrent le trafic... Le problème affecte tous les programmes utilisant la libpcap, pas seulement tcpdump.

La machine a deux interfaces dont une seule a ce problème (sur l'autre, même puce donc même driver, tcpdump marche bien). L'interface à problème n'est pas utilisée par la machine elle-même, elle reçoit du trafic uniquement par port mirroring.

Si j'enregistre les paquets avec l'option -w et que je tente de relire avec un filtre, zéro réponse :

% tcpdump -n -r /tmp/tcpdump-eth1.pcap | wc -l
reading from file /tmp/tcpdump-eth1.pcap, link-type EN10MB (Ethernet)
5722

% tcpdump -n -r /tmp/tcpdump-eth1.pcap ip | wc -l
reading from file /tmp/tcpdump-eth1.pcap, link-type EN10MB (Ethernet)
0

Utiliser l'option -O (ne pas optimiser le code BPF) ne change rien. Vider les caches ou même redémarrer la machine, au cas où un rayon cosmique aie corrompu la mémoire ne change rien non plus.

Arrivé là, voyez si vous avez trouvé la solution...

Mon collègue Antonio Kin-Foo a trouvé. La configuration réseau avait été refaite et le commutateur Ethernet Foundry trouvait drôle de désormais taguer les paquets. C'est ce que montrait tcpdump si on utilise l'option -e (afficher la couche 2). Au lieu de « ethertype IPv4 (0x0800) » pour des paquets IPv4, on voyait « ethertype 802.1Q (0x8100) ». Lorsque les paquets sont ainsi tagués, tcpdump sait se débrouiller dans certains cas (il formatait correctement les paquets) mais pas dans d'autres (définition du filtre). D'autre part, si l'encapsulation/décapsulation VLAN est gérée par le matériel de la carte ou par le système d'exploitation, parfois tcpdump n'a plus de problèmes puisqu'il ne voit plus le tag 802.1Q.

Le bon moyen est de rajouter pour réparer le filtre est d'ajouter vlan and. Par exemple, pour les paquets DNS :

tcpdump -n -i eth1 vlan and port 53

J'ai dû aussi modifier le code de l'outil que j'utilisais pour analyser les paquets. Quelque chose du genre (en C) :

        size_layer2 = SIZE_ETHERNET;
        ethernet = (struct sniff_ethernet *) (packet);
        ethertype = ntohs(ethernet->ether_type);
        if (ethertype == VLAN_ETHERTYPE) {  /* NEW: if the packets are
	tagged, move four bytes forward */
            packet += 4;
            ethernet = (struct sniff_ethernet *) (packet);
            ethertype = ntohs(ethernet->ether_type);
        }
        if (ethertype == IPv6_ETHERTYPE) {
            ip_version = 6;
        } else if (ethertype == IPv4_ETHERTYPE) {
            ip_version = 4;
        } else {                /* Ignore other Ethernet types */
            goto next_packet;
        }

L'article seul

Fiche de lecture : Real world Haskell

Auteur(s) du livre: Bryan O'Sullivan, John Goerzen, Don Stewart
Éditeur: O'Reilly
978-0-596-51498-3
Publié en 2009
Première rédaction de cet article le 26 Août 2010


Les langages de programmation fonctionnels ont la réputation d'être uniquement utilisés pour des problèmes mathématiques abstraits et jamais pour des vrais programmes dans le vrai monde avec des vrais utilisateurs. Il existe plusieurs livres pour apprendre Haskell mais celui-ci a un angle original, exposé dans le titre : utiliser Haskell pour des problèmes « réels ».

Donc, finis les exemples empruntés aux maths. Ce livre montre comment utiliser Haskell pour analyser du JSON, pour faire un programme de recherche dans le système de fichiers, un analyseur de fichiers PGM, un analyseur de code-barres, pour finir avec un client Web et un filtre de Bloom (note pour ceux qui ont lu le code source de Squid : ce programme utilise de tels filtres).

Tout l'attirail de Haskell est expliqué (les monades, l'évaluation paresseuse, map/fold, etc) mélé aux interfaces vers le monde réel (bases de données, analyse syntaxique, etc).

Une lecture recommandée pour tous les programmeurs, même ceux qui n'envisagent pas d'utiliser Haskell, cela leur ouvrira les idées.

Le livre a aussi un excellent site Web qui permet de tout lire en ligne. Le livre avait d'ailleurs été écrit suite à un intense processus collaboratif en ligne et les exemples ont été choisis et relus ainsi.


L'article seul

Ré-apprenons le BASIC pendant les vacances

Première rédaction de cet article le 25 Août 2010


Dans un grenier, j'ai mis la main sur un manuel de 1984, « Une merveille de simplicité / ALICE / Découvrez le Basic » coédité par Matra et Hachette avec une préface de Jean-Luc Lagardère, dirigeant à l'époque des deux entreprises. Le manuel documentait le micro-ordinateur ALICE, de Matra (en fait, fabriqué par Tandy). L'ALICE était muni en ROM d'un BASIC de Microsoft.

Ce BASIC était d'ailleurs son seul shell. Toute interaction avec la machine passait par des commandes BASIC. Le langage était vraiment minimum (même une technique aussi simple que l'indentation pour améliorer la lisibilité des programmes n'existait pas). De mes activités BASIC de l'époque, je ne me souvenais clairement que du fait qu'une variable stockait un nombre, sauf si son nom était suivi d'un $, indiquant que la variable stockait une chaîne de caractères. J'ai révisé le reste : le GOTO était largement utilisé pour presque tout (il y avait quand même des sous-programmes, se terminant par RETURN, et des vraies boucles avec FOR). La seule méthode d'analyse présentée était l'organigramme. Les programmes étaient stockés sur un mécanisme séquentiel, une simple cassette de magnétophone (instructions CSAVE et CLOAD).

L'ordinateur était à la hauteur de ce langage, avec un microprocesseur 6803, 16K de RAM (le manuel que j'ai lu documente la seconde version de l'ALICE, la première avait encore moins), et pas d'écran : il fallait le connecter à son téléviseur familial via le classique câble Péritel.

Heureuse époque où il ne faisait pas de doute que tout le monde devrait apprendre un minimum de programmation pour pouvoir se servir d'un ordinateur ! Le manuel, plutôt bien fait pourtant, est intarissable sur les détails pratiques (du genre, comment allumer un point vert sur l'écran, avec SET(X, Y, 1), 1 étant le vert), moins disert sur la méthodologie et l'analyse, et complètement muet sur les applications réalistes possibles (les exemples donnés sont essentiellement des jeux vidéos ultra-simples). Le manuel de l'ALICE servait à la fois d'introduction à une machine, à un langage et à la programmation en général, bien trop de choses pour 204 pages. Vu le caractère très sommaire du langage et de con environnement, vue l'absence complète du concept de bibliothèque, pas étonnant que l'ALICE n'ait pas nourri un grand nombre de vocations de programmeur.

Pire, comme l'ordinateur ne disposait pas de connexion au réseau, et que la seule possibilité d'échange de programmes passe par le magnétophone, les efforts des uns ne pouvaient pas servir aux autres : chacun était condamné à réinventer son Nième programme de gestion d'hôtel (un des exemples donnés). Pourtant, à la même époque, Unix disposait déjà d'une large bibliothèque de programmes que ses utilisateurs s'échangeaient, via Internet ou UUCP.

Où en est-on aujourd'hui ? On est plutôt passé à l'extrême opposé : la programmation est vue comme un repoussoir (cf. la publicité d'Apple associant l'apprentissage de la programmation à celle de l'alphabet Morse) et on demande surtout à l'utilisateur de ne rien faire d'autre que cliquer sur des endroits pré-définis.

À l'époque, l'utilisation de l'ordinateur semblait à la fois utile et plaisante, comme l'illustre la couverture du manuel, due à Moebius lui-même, dans le style psychédélique des années 70. Le ton du manuel se voulait léger, du genre « La nouvelle valeur de A écrase l'ancienne. Place aux jeunes ! » (encore un slogan qui marque bien son époque...) Aujourd'hui, le ton des manuels est tout aussi exaspérant (les auteurs étant convaincus que l'utilisateur est un abruti et qu'il faut lui parler jeune) mais les ambitions ont beaucoup diminué. En 1984, on pensait naïvement que tout le monde deviendrait programmeur. En 2010, on n'a pas d'autre perspective que de consommer des programmes existants, sans participer à leur création.


L'article seul

Remarkable creatures, de Tracy Chevalier

Première rédaction de cet article le 24 Août 2010


Depuis des millions d'années, elles étaient là, dans les roches de la côte Sud de l'Angleterre. Depuis des milliers d'années, des hommes habitaient là, sans les voir. Ce n'étaient que des cailloux. Mais, en ce début du 19ème siècle, le regard change. Désormais, on voit les fossiles de ces créatures remarquables. Désormais, on les étudie, on les collectionne, on les achète. C'est ce monde en train de changer, ce monde qui commence à accepter l'idée que les êtres vivants n'ont pas toujours été comme aujourd'hui, qui sert de cadre au dernier roman de Tracy Chevalier, Remarkable creatures.

Le livre tourne autout de deux personnages féminins aussi remarquables que les créatures du titre : Mary Anning et Elizabeth Philpot. Ce sont deux personnages historiques mais la romancière a élaboré, sur leurs travaux réels et documentés, une magnifique histoire d'amitié. Face à tous les préjugés d'une Angleterre bigote, où une femme qui décide de se promener seule, ou bien de s'intéresser aux fossiles, ne peut être qu'une folle ou une prostituée, Mary et Elizabeth vont se lancer à la chasse aux fossiles, découvrir des milliers de spécimens et plusieurs nouvelles espèces dont les plus fameuses étaient l'ichtyosaure et le plésiosaure.

L'époque voyait le développement d'une grande mode des fossiles. Elle était donc pleine de collectionneurs de fossiles qui ne savaient pas distinguer un ammonite d'un bélemnite... Les deux héroïnes du roman regardent ces collectionneurs de haut : elles n'achètent pas, elles chassent.

Le statut de ces espèces récemment découvertes faisait l'objet de nombreux débats (l'ichtyosaure n'était-il pas simplement un crocodile ? Le plésiosaure un couper/coller d'un serpent et d'une tortue ?) mais le roman n'est pas un livre de paléontologie. C'est surtout un hommage au passionné (plutôt à la passionnée puisque peu d'hommes ont un rôle positif dans ce livre...), à celle qui a « l'œil du chasseur », celle qui, entièrement prise par sa passion, ignorante des conventions sociales, voit les fossiles là où les gens ordinaires ne voient que des cailloux.


L'article seul

RFC 5966: DNS Transport over TCP - Implementation Requirements

Date de publication du RFC : Août 2010
Auteur(s) du RFC : R. Bellis (Nominet)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 24 Août 2010


La vague mention des virtual circuits (connexions TCP) dans la section 4.2 du RFC 1035 a suscité d'innombrables polémiques, que ce RFC 5966 va peut-être enfin trancher. En deux mots, un serveur DNS doit-il fournir son service avec les protocoles de transport TCP et UDP ou bien peut-il se contenter d'UDP ?

La discussion est d'autant plus vive que certains registres procèdent à des tests techniques obligatoires avant l'enregistrement d'un nom de domaine et que ces tests peuvent inclure la disponibilité du service sur TCP. Par exemple, l'outil Zonecheck dispose d'un tel test (qui se configure avec <check name="tcp" severity="f ou bien w" category="connectivity:l4"/>) et l'AFNIC impose le succès de ce test pour un enregistrement dans .fr (contrairement à ce qu'on lit parfois, il est faux de dire « Zonecheck impose TCP », Zonecheck est configurable et c'est l'AFNIC qui choisit d'activer ce test, et décide de son caractère bloquant ou non). On a vu ainsi des discussions sur ces tests, même si les opposants ont rarement fait l'effort de prendre le clavier pour écrire une argumentation raisonnée (on les comprend quand on voit que toutes les discussions publiques sur le sujet indiquent un consensus des experts sur l'importance du service TCP, voir par exemple http://www.circleid.com/posts/afnic_dns_server_redelegation/).

Mais c'est aussi que l'approche « légaliste » de la discussion est vouée à tourner en rond. Le texte du RFC 1035 (ou celui de la section 6.1.3.2 du RFC 1123) est vague, et peut s'interpréter de différentes manières. Il faut donc revenir aux bases du DNS, pour décider si TCP est important ou pas, et pas essayer vainement de trouver un texte sacré qui trancherait la question de manière claire.

Revenons donc à ces bases (section 1 du RFC). Le DNS peut s'utiliser sur UDP et TCP. Par exemple, l'outil dig, par défaut, utilise UDP, mais l'option +tcp (ou +vc pour virtual circuit) lui fait utiliser TCP. TCP est obligatoire pour les transferts de zone (cf. RFC 5936) mais, contrairement à une légende répandue, n'est pas réservé à ces transferts et peut être utilisé pour des requêtes ordinaires. Il est notamment obligatoire si la réponse arrive tronquée (bit TC mis à un) car elle ne tenait pas dans le paquet UDP (dont la taille était autrefois limitée à 512 octets). Depuis la création du DNS, la taille des réponses a beaucoup augmenté (IDN et IPv6 mais surtout DNSSEC y ont largement contribué) et, malgré la suppression de la limite de 512 (cf. RFC 2671), TCP est donc encore plus nécessaire que dans le passé.

Arrivé là, il faut faire une distinction importante entre ce que peut le logiciel et ce qu'a activé l'administrateur système. Ainsi, le logiciel djbdns permet parfaitement TCP mais il n'est pas activé par défaut. De même, BIND ou NSD ont TCP par défaut mais un pare-feu situé devant le serveur de noms peut bloquer les accès TCP. Notre RFC 5966 sépare donc protocole et mise en œuvre et ne traite que le cas du logiciel : il précise que tout logiciel DNS doit avoir la possibilité de faire du TCP mais il ne tranche pas (délibérement) la question de savoir si TCP doit être disponible sur un serveur de noms en activité. Il note simplement que l'absence de TCP peut planter le processus de résolution de noms.

La section 3 du RFC discute ensuite les différentes questions liées à ce choix. Le principal problème est celui de la taille des réponses. Autrefois limitée à 512 octets, elle peut prendre des valeurs plus grandes (jusqu'à 65536 octets) avec EDNS0. Mais la MTU de 1500 octets est hélas une limite pratique fréquente (cf. RFC 5625, du même auteur), en raison de pare-feux mal configurés. Cela peut poser des problèmes, par exemple lors du déploiement de DNSSEC. Un simple NXDOMAIN depuis .org dépasse les 512 octets :

 

% dig +dnssec SOA certainlydoesnotexist.org

; <<>> DiG 9.6-ESV-R1 <<>> +dnssec SOA certainlydoesnotexist.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 64046
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 1

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

;; AUTHORITY SECTION:
org.			0	IN	SOA	a0.org.afilias-nst.info. noc.afilias-nst.info. 2009281221 1800 900 604800 86400
org.			0	IN	RRSIG	SOA 7 1 900 20100907065203 20100824055203 52197 org. m3DPnEo+Ibd8W0d/cVW7sMZb8UooI6F6mOn/mQSeLiTnLRUvPaMFsd3m j12W4YgVGMyf1s/YLIItoBy7fhKDdJ2zi2r8PfuBrT9Hr+dut+IHRGDR r+6ALaqBISWeyptCe6TygeudG/1sQkQZlCvaBGKUFpsHEi831FwtMZjc hmI=
h9p7u7tr2u91d0v0ljs9l1gidnp90u3h.org. 86400 IN NSEC3 1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 NS SOA RRSIG DNSKEY NSEC3PARAM
h9p7u7tr2u91d0v0ljs9l1gidnp90u3h.org. 86400 IN RRSIG NSEC3 7 2 86400 20100907065203 20100824055203 52197 org. WNHP4aq9hxWHjgZ10HKlqiU6bx2PVQyCgeGJQqykAay4qTcQvD77QMRm c9efWt3M4BO7rr7bt/uY+TqsriJvB1uhvqg93Ti0fPH1SX86hhG8B09U czngma0DZ1UtaCgwpjVQJbAVYRknyfyi6NM7hWwbxUtD44EVWE14qEbb 93A=
b42oorh0vfd9ble13e1him76im76qsl6.org. 86400 IN NSEC3 1 1 1 D399EAAB B49TR2SSRPRC2FF6FIVQ25UFDMRL7Q63 NS DS RRSIG
b42oorh0vfd9ble13e1him76im76qsl6.org. 86400 IN RRSIG NSEC3 7 2 86400 20100906200816 20100823190816 52197 org. I5l7iR/5TngAspzO36TkNYGGugE2whPsUvQP/nPoNMBCC58/4TtNQysF Pdfswz5lPm14Ei8UrCSXjG17Db7yVFk4MD/oidsfweEJ2hwJqcoPAXqY bcqliZxUq/9dLW7zkH4tKwCDXfYHQKFgW7MhKr/i5JUJRkZgR0Q/7mmu PF4=
vae6tvink0oqnd756037uoir56fokhtd.org. 86400 IN NSEC3 1 1 1 D399EAAB VB1V404HEINQ7A8TQTJ9OASALN2IS19G A RRSIG
vae6tvink0oqnd756037uoir56fokhtd.org. 86400 IN RRSIG NSEC3 7 2 86400 20100907011155 20100824001155 52197 org. lHZ3Zi7vMKEcPif/SE9w31xobVq7VXcifR3EE+G1c3lxm3bKdMI9tY3x 6hOkHbUnbgY8XNvEmaobjmPYd4UdYLQa8eonTuRaupI90AZt9Fi83k6u ruCRHP0ChO9VUD+Yc68mM7spD+7nTIfRu/FkNKEuNvqSHipgR5blBfNg KZw=

;; Query time: 43 msec
;; SERVER: ::1#53(::1)
;; WHEN: Tue Aug 24 08:54:12 2010
;; MSG SIZE  rcvd: 1019

Dans tous ces cas, TCP est la seule solution fiable. À l'ère de YouTube et de ses giga-octets de vidéo, il serait curieux d'en rester au DNS de 1990 et de ses limites archaïques à 512 octets. Un serveur de noms doit donc pouvoir utiliser TCP.

Mais, lorsque le serveur de noms a le choix, quel protocole de transport doit-il utiliser ? C'est l'objet de la section 4. Elle modifie légèrement le RFC 1123 dont la section 6.1.3.2 imposait à un résolveur de tenter UDP d'abord (et de passer en TCP si la réponse arrive tronquée). Désormais, le résolveur a le droit de poser sa question en TCP d'abord, s'il a de bonnes raisons de penser (par exemple parce qu'il a déjà parlé à ce serveur) que la réponse arrivera tronquée.

Les sections 5 et 6 sont consacrées à des problèmes pratiques avec la mise en œuvre de TCP. Par exemple, comme le DNS sur TCP peut faire passer plusieurs requêtes dans une connexion TCP, notre RFC précise que les réponses ont parfaitement le droit d'arriver dans un ordre différent de celui des questions.

Restent les questions de sécurité et autres craintes qui sont mentionnées par certains objecteurs (on peut citer http://cr.yp.to/djbdns/tcp.html#why comme très bel exemple de catalogue d'erreurs et d'énormités). En effet, programmer TCP dans le serveur de noms n'est pas très difficile. Ma propre implémentation, dans Grong, fut triviale, car le langage Go, avec son parallélisme natif facilite beaucoup les choses. Mais, même en C, si le serveur utilise plusieurs sockets, par exemple pour gérer IPv4 et IPv6, ajouter TCP en prime ne changera pas beaucoup la boucle principale autour de select(). L'obligation de gérer TCP ne gênera donc qu'une petite minorité de programmeurs, ceux qui essayaient de faire un serveur DNS basé sur le traitement séquentiel des paquets.

En revanche, l'obligation de gérer TCP est parfois critiquée pour des raisons de sécurité. La section 7 discute ce problème des DoS : TCP nécessite un état sur le serveur et consomme donc des ressources. En théorie, cela rendrait les serveurs DNS plus sensibles aux DoS. Toutefois, presque tous les serveurs de noms de la racine ont TCP depuis longtemps, ainsi que la grande majorrté des serveurs des grands TLD et on ne voit pas d'attaques pour autant. (Le RFC se limite au cas du DNS mais on peut aussi, en sortant du petit monde DNS, noter que l'écrasante majorité des serveurs Internet utilise exclusivement TCP... En outre, UDP a ses propres problèmes de sécurité, notamment la facilité à tricher sur l'adresse IP source, facilité qui est à la base de l'attaque Kaminsky.) Le RFC recommande toutefois la lecture de bons textes comme « CPNI technical note 3/2009  \ Security assessment of the Transmission Control Protocol (TCP)  ».

Et la charge du serveur ? Le RFC n'en parle pas mais il y avait eu des inquiétudes à ce sujet, basées sur le fait que les études montrent une augmentation relative très importante du trafic TCP lorsqu'on active DNSSEC. Ce trafic peut-il épuiser le serveur. Notons que, si un passage de 0,2 requête/s à 50 peut sembler énorme, cela reste ridicule en valeur absolue, à l'heure où le plus petit serveur HTTP en gère bien davantage.

Par contre, une autre objection contre TCP n'est pas citée, ses possibles problèmes avec l'anycast. Désolé, mais je manque de temps pour la commenter ici.

Ah, me demanderez-vous, mon opinion personnelle ? Je trouve qu'aujourd'hui, TCP est à la fois indispensable pour ne pas limiter à des valeurs ridiculement basses la taille des réponses, et facile à déployer, comme le montre l'expérience de tous les gros TLD. EDNS0 permettrait de résoudre une bonne partie des problèmes de taille (et je veux donc bien entendre les objecteurs qui diraient « le test technique devrait exiger TCP ou EDNS0 ») mais je note que les serveurs qui n'ont pas TCP n'ont pratiquement jamais EDNS0 non plus... Il n'y a donc guère de raisons valables, en 2010, d'avoir des serveurs de noms inaccessibles en TCP.


Téléchargez le RFC 5966


L'article seul

RFC 5987: Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters

Date de publication du RFC : Août 2010
Auteur(s) du RFC : J. Reschke (greenbytes)
Chemin des normes
Première rédaction de cet article le 23 Août 2010


Les requêtes et réponses du protocole HTTP incluent des en-têtes (comme User-Agent: ou Content-Disposition:, même si ce dernier ne fait pas officiellement partie de la norme HTTP, cf. RFC 2183) avec des valeurs, qui ne pouvaient se représenter directement qu'avec les caractères du jeu ISO 8859-1. Comme MIME, dans le RFC 2231, prévoyait un mécanisme très riche pour encoder les en-têtes du courrier électronique, ce RFC 5987 réutilise ce mécanisme pour HTTP (plusieurs en-têtes l'utilisaient déjà, de manière pas vraiment officielle). Pour le corps du message (voir par exemple le RFC 2388), rien ne change.

Cette restriction à Latin-1 vient de la norme HTTP, le RFC 2616, dans sa section 2.2, qui imposait l'usage du RFC 2047 pour les caractères en dehors de ISO 8859-1.

Notre RFC peut être résumé en disant qu'il spécifie un profil du RFC 2231. Ce profil est décrit en section 3, qui liste les points précisés par rapport au RFC 2231. Tout ce RFC n'est pas utilisé, ainsi le mécanisme en section 3 du RFC 2231, qui permettait des en-têtes de plus grande taille, n'est pas importé (section 3.1 de notre RFC).

En revanche, la section 4 du RFC 2231, qui spécifiait comment indiquer la langue dans laquelle était écrite la valeur d'un en-tête est repris pour les paramètres dans les en-têtes. Ainsi, (section 3.2.2), voici un en-tête, avec un paramètre title traditionnel en pur ASCII :

X-information: news; title=Economy

et en voici un avec les possibilités de notre RFC pour permettre les caractères £ et € (ce dernier n'existant pas dans Latin-1) :

X-information: news; title*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates

Par rapport au RFC 2231, deux jeux de caractères sont décrétés obligatoires (ISO 8859-1 et UTF-8) et la mention du jeu utilisée est également désormais obligatoire (section 3.2 de notre RFC). La langue elle-même est indiquée par une étiquette, selon la syntaxe du RFC 5646. Du fait de ces possibilités plus riches que celles prévues autrefois pour HTTP, les paramètres qui s'en servent doivent se distinguer, ce qui est fait avec un astérisque avant le signe égal (voir l'exemple ci-dessus). La valeur du paramètre inclus donc le jeu de caractères et l'encodage (obligatoire), la langue (facultative, elle n'est pas indiquée dans l'exemple ci-dessus) et la valeur proprement dite.

Voici un exemple incluant la langue, ici l'allemand (code de) :

X-quote: theater; 
    sentence*=UTF-8'de'Mit%20der%20Dummheit%20k%C3%A4mpfen%20G%C3%B6tter%20selbst%20vergebens.

La section 4 couvre ensuite les détails pratiques pour les normes qui décrivent un en-tête qui veut utiliser cette possibilité. Par exemple, la section 4.3 traite des erreurs qu'on peut rencontrer en décodant et suggère que, si deux paramètres identiques sont présents, celui dans le nouveau format prenne le dessus. Par exemple, si on a :

X-information: something; title="EURO exchange rates";
               title*=utf-8''%e2%82%ac%20exchange%20rates

le titre est à la fois en ASCII pur et en UTF-8, et c'est cette dernière version qu'il faut utiliser, même si normalement il n'y a qu'un seul paramètre title.

Ceux qui s'intéressent à l'histoire du développement de cette nouvelle norme pourront regarder les minutes de la réunion IETF 72. Ces paramètres étendus sont déjà mis en œuvre dans Konqueror (à partir de la 4.4.1), Firefox et Opera. Des tests plus détaillés sont présentés en http://greenbytes.de/tech/tc2231.


Téléchargez le RFC 5987


L'article seul

RFC 5969: IPv6 Rapid Deployment on IPv4 Infrastructures (6rd)

Date de publication du RFC : Août 2010
Auteur(s) du RFC : M. Townsley (Cisco), O. Troan (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF softwire
Première rédaction de cet article le 23 Août 2010


La délicate question de la période de transition entre IPv4 et IPv6 n'a jamais été négligée à l'IETF. Bien au contraire, plusieurs mécanismes ont été normalisés pour assurer le passage d'un protocole à l'autre. Le mécanisme « 6rd », initialement décrit dans le RFC 5569, est un de ces mécanismes. 6rd modifie le 6to4 du RFC 3056 pour garantir un chemin de retour symétrique aux paquets IP (section 1 du RFC). 6rd permet à un FAI de vendre un service IPv6 alors que son réseau interne est essentiellement IPv4. Il est surtout connu pour être la technologie déployée par Free à partir de décembre 2007. Ce RFC 5969 prend la spécification originale de 6rd, dans le RFC 5569, l'étend pour des cas comme celui où les adresses sont distribuées par DHCP et le fait passer sur le chemin des normes IETF (le RFC 5569 avait uniquement le statut « pour information »).

S'il existe plusieurs mécanismes de coexistence d'IPv4 et d'IPv6, c'est parce que les besoins sont différents. Certains FAI ont un réseau interne entièrement IPv6 depuis de nombreuses années comme Nerim. D'autres n'ont pas encore commencé le déploiement. Parfois, le FAI est en avance sur ses clients, parfois c'est le contraire comme c'était le cas pour Free où de nombreux utilisateurs réclamaient IPv6 depuis longtemps. Il existe donc une variété de techniques de coexistence v4/v6. 6rd se positionne pour le cas où le FAI :

  • n'a toujours pas migré la totalité de son réseau interne en IPv6,
  • a une connectivité IPv6 externe, et des adresses IPv6 allouées par un RIR,
  • a certains clients qui réclament une connectivité IPv6,
  • et, de préférence, contrôle le routeur situé chez les clients (cas des « boxes », nommées CE pour « Customer Edge » dans le RFC).

À l'origine, le protocole « idéal » semblait être 6to4 du RFC 3056. Simple, déjà mis en œuvre, y compris en logiciel libre et sans état (chaque paquet est traité indépendamment) donc passe bien à l'échelle. Mais il a des limites, notamment le fait le retour du paquet n'est pas garanti : la machine avec laquelle on communique va chercher son propre relais 6to4 et ne va pas forcément en trouver un. 6rd est une modification de 6to4 pour utiliser comme préfixe, non plus le préfixe 6to4 commun à tous de 2002::/16 mais un préfixe par FAI. Ainsi, le FAI doit désormais lui-même installer des relais, il ne peut plus se reposer sur les relais existants mais, en contre partie, il contrôle complètement le routage, y compris sur le chemin du retour et se retrouve ainsi dans un cas plus classique où ses routeurs servent ses clients (alors que, avec 6to4, tout le monde sert tout le monde, ce qui est très bien lorsque cela marche).

La section 4 décrit la fabrication du préfixe 6rd pour les adresses IP. Ce préfixe combine un préfixe IPv6 choisi par le FAI et tout ou partie de l'adresse IPv4 du CE. Notons que, 6rd étant un bricolage purement local au FAI, la norme n'impose pas, par exemple, le nombre de bits IPv4 conservé (ce point était déjà dans le RFC 5569, voir aussi les sections 7 et 11). Il faut juste garder 64 bits pour le réseau local, pour permettre l'autoconfiguration sans état. On peut garder moins de 32 bits de l'adresse IPv4 car certains octets sont souvent fixés sur le réseau du FAI. Par exemple, un FAI qui consacre le préfixe 2001:DB8::/32 à ses clients 6rd, pour un CE d'adresse 192.0.2.137, et dont tous les CE sont sous 192.0.0.0/8, peut garder les trois quarts de l'adresse IPv4. Le FAI aura alors un préfixe 6rd de 32 + 24 = 56 bits (ce qui laissera 72 bits pour le réseau local, permettant 256 réseaux de longueur /64), le 2001:DB8:0002:8900::/56.

Les acteurs du protocole sont :

  • Les machines sur le réseau local du client, elles parlent IPv6 nativement sur ce réseau local (si elles utilisent l'auto-configuration sans état, la Freebox leur a envoyé le préfixe par RA),
  • Les CPE (CE dans le RFC, pour « Customer Edge », comme la Freebox chez Free), qui doivent parler 6rd pour traduire dans les deux sens,
  • Les relais 6rd, en bordure du réseau du FAI (BR dans le RFC pour « Border Relays »). Chez Free, ce sont des PC Unix. À noter que 6rd est sans état et que chaque paquet IP peut donc être traité indépendamment des autres. Les BR peuvent donc être joints, par exemple, par l'anycast (RFC 3068).

On peut se poser la question de savoir s'il s'agit vraiment d'IPv6 « natif ». Sans doute pas (le paquet circule dans le réseau de Free encapsulé IPv4, ce qui réduit la MTU à 1480 octets).

Pour faciliter le déboguage, la section 5 du RFC recommande que CE et BR répondent à l'adresse anycast subnet router du RFC 4291 (section 2.6.1).

La section 7 couvre les mécanismes par lesquels le CE peut être configuré pour faire du 6rd proprement. Ils sont multiples mais on notera en section 7.1.1 l'arrivée d'un nouveau : une option DHCP (numéro 212) pour configurer tous les paramètres 6rd du CE (préfixe IPv6, adresse(s) des BR, nombre de bits de l'adresse v4 à conserver, etc).

La question de la longueur idéale du masque v4 est couverte en section 11. Il s'agit de voir combien de bits de l'adresse v4 doivent être gardés dans le préfixe v6. Si on utilise les 32 bits, et qu'on veut allouer un /56 à chaque client, il faut un /24 pour les servir tous. Ce n'est pas si effrayant que cela, même si tous les AS actuellement actifs le faisaient, cela ne consommerait qu'un /9. Et si ces AS n'allouaient au client qu'un /60, la consommation totale ne serait qu'un /13. À noter que Free n'allloue aujourd'hui qu'un /64 à ses clients, ce qui ne leur permet pas d'avoir plusieurs réseaux chez eux (sauf à renoncer à l'autoconfiguration sans état) et annule donc une partie de l'intérêt de IPv6.

Mais la solution la plus courante sera sans doute de ne pas utiliser les 32 bits de l'adresse IPv4 mais seulement une partie. Par exemple, si tous les CE sont dans le même /12 IPv4, 20 bits suffisent pour les distinguer et on peut alors allouer un /56 à chaque client en ne consommant en tout qu'un /36.

6to4 soulève traditionnellement des gros problèmes de sécurité, documentés dans le RFC 3964. 6rd en supprime certains, si l'implémentation suit les recommandations de la section 12, et effectue les vérifications demandées, mais l'usurpation d'adresse IP demeure relativement facile.

Quelles sont les principales nouveautés de ce RFC 5969 par rapport au RFC 5569 original ? Thibault Muchery les résume en disant que ce nouveau RFC est plus général : la solution mise en œuvre pour Free prenait avantage de certaines particularités de Free (addresses IP fixes, maitrise des logiciels de la CE - la Freebox - et des BR). La solution nouvelle reprend tout à fait le même principe, en généralisant, en standardisant (nouvelle option DHCP, etc.), en présentant plus la solution comme inscrite dans une lignée d'autres solutions, en ajoutant des contrôles plus fins pour la sécurité mais au fond c'est exactement la même solution généralisée.

Et Rémi Desprès, concepteur de la solution originale, note que l'apport majeur du RFC 5969 est la spécification d'une option DHCP pour transmettre aux CPEs (ou "CEs") les paramètres 6rd de leur domaine. (Free n'en avait pas besoin, mais c'est indispensable si les CPE sont acquis indépendamment du FAI.) Il ajoute qu'il y a par contre une régression, mais limitée, dans la section 8. La nouvelle norme envisage une l'utilisation de NUD (Neighbor Unreachability Detection) sur le lien virtuel que constitue un domaine 6rd (tout en le décrivant comme sous-optimal), une complexité à son avis superflue. Le RFC 5969, et propose une technique différente pour tester l'accessibilité des BR, à son avis superflue également. La philosophie KISS du RFC 5569 en est à son avis amoindrie, mais avoir un RFC spécifiant l'option DHCP est plus important que ces points mineurs.

On imagine que la suite des opérations sera une implémentation par Cisco, étant donnée que le RFC est rédigé par des gens travaillant pour Cisco.


Téléchargez le RFC 5969


L'article seul

RFC 5943: A Dedicated Routing Policy Specification Language Interface Identifier for Operational Testing

Date de publication du RFC : Août 2010
Auteur(s) du RFC : B. Haberman (JHU APL)
Chemin des normes
Première rédaction de cet article le 23 Août 2010


Lorsqu'un nouveau réseau est connecté à l'Internet, il est parfois injoignable de certaines parties de l'Internet, par exemple parce que ses adresses IP sont illégalement utilisées par d'autres ou bien parce qu'il est filtré en raison d'une histoire antérieure. Les bonnes pratiques opérationnelles demandent donc la configuration d'un serveur ICMP qui répondre à des tests, par exemple depuis ping. Traditionnellement, l'existence de ce serveur était annoncé via les commentaires stockés dans la base d'un RIR (comme le commentaire remarks: pingable 2a01:190:1764:150::30 du réseau 2a01:190::/32. Ces commentaires n'étant pas analysables automatiquement par un programme, il était donc souhaitable de créer un nouvel attribut RPSL pour cela, pingable:.

Prenons l'exemple de l'allocation d'un nouveau préfixe à un RIR par exemple, l'allocation de 175/8 : le nouveau préfixe est souvent inaccessible depuis plusieurs parties de l'Internet, par exemple en raison de filtres anti-bogon. Il faut donc une étape de « débogonisation » où le préfixe sera annoncé par le RIR, des serveurs ICMP echo seront installés et testés. Lorsque les filtres anti-bogon auront été mis à jour, le test pourra cesser.

Notre RFC 5943 permet d'automatiser ce genre de tests en ayant un nouvel attribut dans la description en RPSL (RFC 4012) de la route vers le préfixe en question. Sa description complète figure dans la section 2 du RFC, avec cet exemple :

route6: 2001:DB8::/32
origin: AS64500
pingable: 2001:DB8::DEAD:BEEF
ping-hdl: OPS4-RIPE

(ping-hdl est le handle du contact technique de ce serveur de test).

À l'heure actuelle (août 2010), il n'existe pas encore d'objet ayant cet attribut dans la base du RIPE. il faut dire qu'il n'est pas encore mis en œuvre. Si on essaie d'en ajouter un :

 
pingable:      194.109.21.51
***Error: "pingable" is not a known RPSL attribute

(Merci à Marco Hogewoning pour ses essais et explications.)

Les processus qui testent les adresses pingable doivent prendre garde à ne pas surcharger le réseau en se limitant à un nombre raisonnable d'essais (section 3 du RFC). Naturellement, rien ne garantit que tous le feront et celui qui installe le serveur de test doit aussi déployer ses propres protections (section 4 du RFC).

L'adoption de ce nouvel attribut n'est pas allée de soi et on peut trouver un exemple des discussions qui l'ont accompagné dans les minutes de la réunion RIPE-60 (cherchez « E. A Dedicated RPSL Interface Identifier for Operational Testing »).


Téléchargez le RFC 5943


L'article seul

RFC 5952: A Recommendation for IPv6 Address Text Representation

Date de publication du RFC : Août 2010
Auteur(s) du RFC : S. Kawamura (NEC BIGLOBE), M. Kawashima (NEC AccessTechnica)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 23 Août 2010


Comme pour IPv4, mais de manière bien plus commune, les adresses IPv6 ont plusieurs représentations possibles. Ainsi (section 1 du RFC), l'adresse 2001:db8:0:0:1:0:0:1 peut aussi s'écrire 2001:0db8:0:0:1:0:0:1, 2001:db8::1:0:0:1, 2001:db8::0:1:0:0:1, 2001:0db8::1:0:0:1, 2001:db8:0:0:1::1, 2001:db8:0000:0:1::1 ou 2001:DB8:0:0:1::1. Cette variété peut dans certains cas être cause de confusion, notre RFC propose donc une forme recommandée (ici, 2001:db8::0:1:0:0:1).

La syntaxe des adresses IPv6 est fixée le RFC 4291, section 2.2. Cette syntaxe est très souple, et venait sans format recommandé, « canonique ». La section 2 liste les points où le RFC 4291 laissait le choix :

  • Possibilité d'indiquer (ou pas) les zéros initiaux dans chaque champ. 2001:db8:0:0:1:0:0:1 et 2001:0db8:0:0:1:0:0:1 sont ainsi équivalentes (deuxième champ).
  • Possibilité de compression des champs nuls consécutifs en les remplaçant par ::. 2001:db8:0:0:0:0:0:1 et 2001:db8::1 sont ainsi la même adresse. Si le :: peut apparaitre à deux endroits, le RFC 4291 impose, pour éviter toute ambiguité, de ne le mettre qu'une fois mais sans préciser où. Ainsi, 2001:db8::aaaa:0:0:1 et 2001:db8:0:0:aaaa::1 sont la même adresse.
  • Pour les chiffres hexadécimaux qui sont des lettres de A à F, on peut utiliser n'importe quelle casse.

Est-ce que cela pose vraiment des problèmes ? Parfois, dit notre RFC, dont la section 3 liste les problèmes possibles (sans les hiérarchiser, ce que je regrette car certains cas semblent quand même assez rares en pratique). Premier problème, la recherche d'une adresse dans un fichier texte ou bien avec un tableur. Si on utilise aveuglément grep sur ses fichiers, on risque de ne pas trouver l'adresse IP (avec grep, il faudrait utiliser une expression rationnelle mais les tableurs, par exemple, n'en disposent pas forcément et leurs utilisateurs peuvent ne pas y penser). Notez qu'avec un SGBD qui dispose d'un type « adresse IP » comme PostgreSQL, ce problème n'existe pas, le SGBD ne traite pas l'adresse comme du texte :

essais=> CREATE TABLE Machines (name TEXT, address INET);
CREATE TABLE
essais=> INSERT INTO Machines VALUES ('gandalf', '2001:db8::cafe:0:1');
INSERT 0 1
essais=> INSERT INTO Machines VALUES ('saroumane', '2001:db8::bad:0:1');
INSERT 0 1
essais=> SELECT * FROM Machines WHERE address = '2001:DB8:0:0:0:CAFE:0:1';
  name   |      address       
---------+--------------------
 gandalf | 2001:db8::cafe:0:1
(1 row)

On voit que, malgré une représentation toute différente de l'adresse, la machine gandalf a bien été trouvée. Si tout le monde utilisait des logiciels de gestion d'adresses IP bâties sur ce principe, il n'y aurait pas de problème. Mais, comme le note le RFC, les méthodes « du pauvre » à base de grep ou d'Excel sont courantes. (Voir aussi les sections 3.1.3 et 3.1.4, moins convaincantes à mon avis.)

Des problèmes analogues surviennent lorsqu'on veut écrire un programme capable d'analyser des adresses IPv6 sous toutes leurs formes légales (section 3.2.1, avec laquelle je ne suis guère d'accord : il existe des bibliothèques toutes faites pour cela, dans tous les langages, comme inet_pton() pour C, et celui qui réinvente la roue en écrivant un analyseur tout neuf en PHP ou Visual Basic mérite les ennuis qu'il aura).

Le RFC cite d'autres problèmes possibles, comme le fait qu'un module de journalisation qui afficherait les adresses IP sous leur forme longue (comme 2001:0db8:0:0:1:0:0:1) produirait des historiques peu lisibles, ou comme le fait qu'un mécanisme d'audit (par exemple avec un outil comme diff) ou de gestion de versions qui analyserait des changements dans la configuration d'un routeur pourrait croire à tort qu'il y a un changement lorsqu'une adresse IPv6 passe d'une forme à une autre (section 3.2.3). Bien d'autres points analogues sont pointés du doigt par le RFC.

Enfin, le jeu de caractères étendu de l'hexadécimal entraine un risque de confusion entre D et 0, de même qu'entre B et 8 (section 3.4.3).

Quelle solution propose donc notre RFC ? La section 4 est la partie normative du document : elle définit une forme canonique qui devrait être suivie systématiquement lorsqu'une adresse IPv6 est affichée. Rien de nouveau dans cette forme, qui est déjà celle choisie par la plupart des logiciels, à part sa désignation comme forme canonique officielle. Attention, cette obligation ne porte que sur la sortie d'adresses IPv6, en entrée, un logiciel conforme à la norme IPv6 doit toujours accepter les différentes syntaxes.

Une conséquence de cette existence d'une forme canonique est que le logiciel n'affichera donc pas toujours ce qu'on lui a indiqué. Pour reprendre l'exemple PostgreSQL :

essais=> INSERT INTO Machines VALUES ('galadriel', 
                    '2001:0DB8:0:DBA8:0:0:0:1');
INSERT 0 1
essais=> SELECT * FROM Machines WHERE name = 'galadriel';
   name    |      address       
-----------+--------------------
 galadriel | 2001:db8:0:dba8::1

L'adresse sera affichée sous une forme différente de celle sous laquelle elle a été entrée. La section 3.3.1 du RFC expliquait pourtant que c'était une mauvaise idée que d'afficher sous une forme différente, petite contradiction de ce RFC.

Donc, concrètement, comment doit être affichée une adresse ?

  • Les zéros initiaux dans un champ doivent être supprimés (section 4.1). 2001:0db8::0001 doit être écrit 2001:db8::1.
  • L'indication d'une suite de champs nulms, :: doit être utilisée au maximum, doit s'appliquer à la suite la plus longue (s'il y en a plusieurs) et, en cas d'égalité, à la première (section 4.2). Ainsi, 2001:db8:0:0:0:0:0:1 doit s'écrire 2001:db8::1, 2001:db8:0:42:0:0:0:1 doit être mis sous la forme 2001:db8:0:42::1 et 2001:db8:0:0:137:0:0:1 doit être affiché 2001:db8::137:0:0:1.
  • Les chiffres hexadécimaux doivent être en minuscule (section 4.3), donc 2001:DB8::BAD:DCAF doit être 2001:db8::bad:dcaf.

Le RFC prévoit aussi le cas des adresses spéciales comme les adresses IPv4 représentées en IPv6 (section 5).

Si l'adresse IP indiquée comprend également un port, il y avait traditionnellement plusieurs formes. La section 6 rend obligatoire la syntaxe avec crochets [2001:db8::deb:1]:80, issue du RFC 3986 (section 3.2.2) et qui n'était obligatoire que pour les URL.

L'annexe A donne des conseils pour les programmeurs, qui vont devoir écrire des programmes affichant des formes correctes. Ainsi, sur FreeBSD 7.0, l'utilisation de getnameinfo() avec l'option NI_NUMERICHOST produit déjà le résultat correct, sauf pour les adresses dites spéciales.

De même, PostgreSQL produit déjà des adresses au bon format. Et avec inet_pton() ? Le programme canonicalize-v6.c montre que son comportement est bien celui du RFC :

% ./canonicalize-v6 toto 2001:db8:Bad:0:0::0:1 127.0.0.1 35:0FF::1 2001:0:0:1:b:0:0:A 2001:db8:0:0:1:0:0:0
toto -> Illegal input IPv6 address
2001:db8:Bad:0:0::0:1 -> 2001:db8:bad::1
127.0.0.1 -> Illegal input IPv6 address
35:0FF::1 -> 35:ff::1
2001:0:0:1:b:0:0:A -> 2001::1:b:0:0:a
2001:db8:0:0:1:0:0:0 -> 2001:db8:0:0:1::

Voir aussi le RFC 4038 pour des détails sur les questions IPv6 pour les applications.


Téléchargez le RFC 5952


L'article seul

Nouvelle version d'IDN

Première rédaction de cet article le 22 Août 2010


Une série de cinq RFC vient de sortir, représentant la nouvelle version de la norme IDN, permettant d'utiliser des noms de domaine en Unicode. Cette nouvelle version est officiellement nommée « IDNA 2008 » mais n'a pas respecté le calendrier original, qui était complètement irréaliste. Il vaut donc mieux l'appeler « IDNAbis ».

IDNAbis marque des changements importants dans les concepts sous-jacents (indépendance par rapport à la version d'Unicode, détermination de la liste des caractères autorisés selon un algorithme et non plus selon une table, suppression de l'étape de canonicalisation obligatoire, etc), mais les conséquences pratiques pour les utilisateurs seront faibles. L'écrasante majorité des noms de domaines légaux selon IDNA 1 le seront toujours avec IDNAbis, leur encodage en Punycode (RFC 3492) reste le même (donc, تونس sera toujours représenté sur le câble par xn--pgbs0dh et maçonnerie par xn--maonnerie-r3a), un certain nombre de chaînes de caractères seront désormais autorisées mais elles concernaient surtout des écritures peu répandues. D'autres, qui étaient autorisés (mais rarement utilisées) sont désormais interdites.

La liste des RFC qui forment IDNAbis comprend :

  • RFC 5890, « Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework », donne les définitions des termes essentiels comme les nouveaux U-label (forme Unicode d'un nom légal) et A-label (forme Punycode d'un nom légal),
  • RFC 5894, « Internationalized Domain Names for Applications (IDNA): Background, Explanation, and Rationale », explique et justifie (fort mal, selon moi), le projet IDNAbis et ses concepts ; ce RFC n'est pas une norme, il n'est là que pour information,
  • RFC 5891, « Internationalized Domain Names in Applications (IDNA): Protocol  », est le cœur de la nouvelle norme, il décrit le protocole utilisé,
  • RFC 5892, « The Unicode code points and IDNA  », spécifie l'algorithme utilisé pour déterminer si un caractère est légal en IDNAbis, illégale ou bien si sa légalité dépend du contexte,
  • RFC 5893, « Right-to-left scripts for IDNA », expose les règles pour les noms de domaine dont une partie s'écrit de droite à gauche (par exemple en hébreu),
  • RFC 3492, « Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA) », faisait partie de IDNA 1 mais est inchangé pour IDNAbis.

Quels sont les changements par rapport à IDNA 1 ? La description la plus complète des changements figure dans l'annexe A du RFC 5891. Pour la résumer :

  • Le protocole est désormais indépendant de la version d'Unicode : tout changement dans Unicode est automatiquement disponible.
  • Les caractères de ponctuation et les symboles sont désormais presque tous exclus.
  • Il n'y a plus d'étape de normalisation standard. Chaque application est désormais libre d'effectuer la correspondance entre ce qu'a tapé ou sélectionné l'utilisateur et l'IDN envoyé sur le réseau.
  • Le modèle de sélection des caractères autorisés est passé de « entièrement manuel, caractère par caractère » à « essentiellement algorithmique, fondé sur les propriétés Unicode - avec un peu d'exceptions manuellement ajoutées ». C'est ce qui permet l'indépendance par rapport aux versions d'Unicode.

Mais IDNAbis reste largement compatible avec l'ancien IDN (même principe de fonctionnement, même Punycode, même préfixe xn--, beaucoup de règles communes). En pratique, les utilisateurs, et même les registres de noms verront peu de différences.

Quelles étaient les motivations pour créer un IDNAbis seulement quelques années après le premier ? Il y en avait plusieurs, pas toutes avouables. De fortes pressions de l'ICANN s'étaient exercées, notamment pour avoir un prétexte pour retarder l'introduction des IDN dans la racine (devenue effective en mai 2010). Il y avait aussi toute une campagne de FUD concernant un soi-disant rôle des IDN dans le hameçonnage. Très présente au début du projet, cette motivation, souvent répétée en des termes sensationnalistes (comme la répétition du terme ridicule de « caractères dangereux ») a été sérieusement édulcorée au fur et à mesure du travail du groupe idnabis de l'IETF (voir par exemple le compte-rendu de la réunion IETF de Philadelphie en mars 2008). Aujourd'hui, il n'en reste plus gère de trace dans les RFC.

D'autres motivations étaient plus consensuelles, comme le souhait d'avoir un IDNA indépendant de la version d'Unicode. Par exemple, IDNA 1 était lié à Unicode 3.2 et les écritures enregistrées par le consortium Unicode après la sortie de la 3.2 (comme le tifinagh) étaient donc interdites d'IDN. Ce point est désormais réglé.

Tout cela ne signifie pas que le résultat final fasse l'unanimité et, pour un bon résumé des questions qu'IDNAbis laisse ouvertes, on peut consulter la FAQ du consortium Unicode. Pour le point de vue des promoteurs d'IDNAbis, voir le RFC 5894.

Il ne semble pas exister encore d'implémentations de IDNAbis mais ce n'est pas forcément dramatique : les différences pratiques entre les deux versions sont suffisamment faibles pour que, pour la plupart des caractères, utiliser une des nombreuses bibliothèques mettant en œuvre l'ancienne version soit suffisant.


L'article seul

RFC 5891: Internationalized Domain Names in Applications (IDNA): Protocol

Date de publication du RFC : Août 2010
Auteur(s) du RFC : J. Klensin
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idnabis
Première rédaction de cet article le 22 Août 2010


L'ensemble des RFC sur la deuxième version d'IDN couvre la terminologie (RFC 5890), les tables de caractères autorisés (RFC 5892), les justifications des choix effectués (RFC 5894) et, dans ce RFC 5891, le protocole lui-même, utilisé pour l'enregistrement et la lecture des noms de domaine.

Ces RFC « IDNAbis » remplacent donc les RFC 3490 et RFC 3491 mais pas le RFC 3492, Punycode continuant à être l'encodage utilisé pour les IDN, avec le même préfixe, xn--. Le principe reste le même : comme les règles pour les noms de machine (mais pas pour les noms de domaine) imposent l'utilisation des seuls caractères US-ASCII, comme il n'est pas question de mettre à jour toutes les plate-formes utilisées, IDN fonctionne en encodant les noms de domaines Unicode en ASCII, grâce à l'algorithme Punycode. L'infrastructure n'est donc pas modifiée mais on peut présenter aux utilisateurs le vrai nom en Unicode, quitte à le traduire lors du passage sur le réseau. (Officiellement, IDNAbis est nommé IDNA 2008 mais ce nom est incorrect, le protocole n'ayant pas été terminé en 2008.)

La section 3 précise ce fonctionnement en exigeant qu'un nom de domaine utilisé comme tel (i.e. comme élément d'un protocole, pas lorsqu'il est simplement cité dans du texte libre), doit être encodé en ASCII lorsqu'on parle aux applications non-IDN, et que la comparaison entre deux noms de domaine (pour voir s'ils sont égaux) doit se faire entre deux formes Unicode ou deux formes ASCII mais pas en mélangeant les deux. Dans IDNAbis, le passage de la forme Unicode (U-label) à la forme ASCII (A-label) et en sens inverse se fait sans perte d'informations. Les deux comparaisons sont donc équivalentes. Comme beaucoup de protocoles utilisent des noms de domaine, les IDN affectent potentiellement beaucoup de monde. Sauf si le protocole le prévoit explicitement (ce qui est le cas des IRI du RFC 3987), les IDN doivent donc être mis sous leur forme ASCII. Idem pour les requêtes et réponses effectives faites avec le DNS.

Petit détail au passage. On trouve souvent des noms de domaine dans la partie droite d'un enregistrement DNS, par exemple dans le champ RNAME d'un SOA, qui indique l'adresse de courrier du responsable de la zone). Comme le rappelle la section 3.2.2, IDN ne change pas ces champs qui restent actuellement en pur ASCII, en attendant un futur RFC (le RFC 4952 ne suffit pas).

Passons maintenant aux deux protocoles utilisés par IDNAbis, le protocole d'enregistrement et le protocole de résolution. Le premier est décrit dans la section 4. Il concerne l'enregistrement d'un nom de domaine Unicode auprès d'un registre (attention, un registre ne gère pas forcément un TLD, ce protocole concerne tous les registres, même, par exemple, celui de bortzmeyer.org).

Donc, première étape, le registre reçoit un nom en Unicode (section 4.1). Il doit être normalisé en NFC et peut être encore normalisé selon des règles locales. Ce nom peut être transmis directement en Unicode (« U-label ») ou bien encodé en Punycode (« A-label »). Le RFC recommande de joindre la forme Punycode (voire uniquement celle-ci) mais il n'y a aucune justification technique à ce choix, c'est juste du FUD anti-Unicode.

Le registre doit ensuite vérifier que le nom est correct techniquement (section 4.2). Ainsi, il faut tester que la conversion U-label -> A-label et retour redonne bien le meme nom et, si uniquement une forme Punycode est reçue, qu'elle est bien légale (toute chaîne de caractères commençant par xn-- n'est pas forcément du Punycode). Les caractères interdits doivent être absents (cf. RFC 5892).

À côté des règles absolues (« le caractère ; est interdit »), il existe également des règles contextuelles comme l'interdiction du caractère Katagana U+30FB sauf dans les écritures utilisées au Japon (cf. RFC 5892). Enfin, si le nom comporte des caractères dont la directionnalité est de droite à gauche (cas de l'écriture arabe), il faut également suivre les prohibitions du RFC 5893.

Notons que les interdictions de ce RFC 5891 ne sont qu'un minimum. Un registre peut toujours ajouter ses propres règles comme de n'accepter que les caractères qui sont utilisés pour la langue locale, ou bien pour interdire des mots considérés comme grossiers.

Après ce parcours du combattant, le nom est enregistré. Reste à le résoudre via une requête DNS. C'est l'objet de la section 5, sur le protocole de résolution. Ce dernier effectue moins de tests puisqu'ils sont censés avoir été faits à l'enregistrement. Notez toutefois que ce n'est pas un argument très solide : non seulement il peut exister des registres qui ne font pas les tests ou bien les font mal mais la seule existence des jokers dans le DNS (RFC 1034, section 4.3.3) permet à un nom non enregistré d'« exister » quand même.

Bref, pour résoudre un IDN, le client doit donc convertir en Unicode (en effet, l'environnement de départ n'utilisait pas forcément Unicode, cela pouvait être, par exemple, Latin-1) et le normaliser en NFC. Ensuite, il teste que les caractères Unicode présents sont bien autorisés (section 5.4). Il est à noter que le résultat de ce test dépend de la version d'Unicode utilisée par le client (probablement via des bibliothèques standard fournies par le système d'exploitation). Ainsi, un nom de domaine utilisant un caractère très récemment affecté par Unicode pourrait être refusé par beaucoup de clients IDN.

Enfin, le client IDN convertit le nom en Punycode et termine par une résolution DNS normale (sections 5.5 et 5.6).

La section sur la sécurité, obligatoire dans les RFC, mentionne le risque de confusion entre des caractères similaires (un FUD classique contre IDN) mais ne fournit pas de solution dans le protocole. Elle compte sur les registres pour ne pas accepter les noms problématiques.

L'annexe A dresse la liste des différences avec la première version d'IDN. Je cite notamment :

  • Au lieu de dépendre d'une version spécifique d'Unicode (la 3.2 pour IDNA 1), le protocole est désormais indépendant de la version : tout changement dans Unicode est automatiquement disponible.
  • Les protocoles pour l'enregistrement d'un nom et sa résolution sont désormais séparés (et légèrement différents).
  • Les caractères de ponctuation et les symboles sont désormais presque tous exclus.
  • Il n'y a plus d'étape de normalisation comme l'était le nameprep du RFC 3491. Seul reste le NFC. D'une manière générale, chaque application est désormais libre d'effectuer la correspondance (mapping) entre ce qu'a tapé ou sélectionné l'utilisateur et l'IDN.
  • Le modèle de sélection des caractères autorisés est passé de « entièrement manuel, caractère par caractère » à « essentiellement algorithmique, fondé sur les propriétés Unicode - avec un peu d'exceptions manuellement ajoutées ». C'est ce qui permet l'indépendance par rapport aux versions d'Unicode.
  • La validité d'un caractère peut désormais dépendre du contexte (ce qui complique sérieusement la vérification).
  • Nouvelles règles « bidi ».
  • Largement compatible avec l'ancien IDN (même Punycode, même préfixe, beaucoup de règles communes) mais pas totalement (certains noms légaux deviennent invalides).

Pour un point de vue critique sur IDNA bis, on peut consulter le Unicode Technical Standard #46, « Unicode IDNA Compatibility Processing », qui remet notamment en cause le soi-disant rôle d'Unicode dans le hameçonnage. Une critique de cette critique a été publiée en Review of Unicode TR#46.


Téléchargez le RFC 5891


L'article seul

RFC 5890: Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework

Date de publication du RFC : Août 2010
Auteur(s) du RFC : J. Klensin
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idnabis
Première rédaction de cet article le 22 Août 2010


La nouvelle norme pour les noms de domaine écrits en Unicode, nommée IDNA2008, modifie les règles qui s'appliquent à ces IDN. Elle est composée de plusieurs RFC dont ce RFC 5890, qui fixe la terminologie.

Dans cette nouvelle version, sur laquelle le travail a commencé en 2008 (d'où son nom officiel d'IDNA2008, cf. section 1.1), la norme est plus riche et plus complexe. Le seul RFC des définitions fait 29 pages. Elle remplace IDNA 1, ou « IDNA2003 » (l'ancienne norme, dans les RFC 3490 et RFC 3491). Elle crée notamment les nouveaux termes de U-label (composant de nom de domaine en Unicode) et de A-label (composant de nom de domaine internationalisé encodé selon l'algorithme Punycode du RFC 3492). Contrairement à d'autres normes de l'IETF, elle n'est pas indispensable que pour les programmeurs, mais aussi pour ceux qui, par exemple, décident des politiques d'enregistrement des registres.

Quels sont les RFC qui composent IDNA2008 ? La section 1.3 donne la liste officielle :

  • Ce document, le RFC 5890, qui donne les définitions.
  • Le RFC 5894, de justification des choix effectués, et qui fournit aussi des avis sur les politiques d'enregistrement. Il n'a pas statut de norme et reflète des opinions peu consensuelles sur les IDN.
  • Le RFC 5891 qui normalise le protocole.
  • Le RFC 5893, spécifique aux questions posées par les écritures de droite à gauche,
  • Le futur RFC sur les fonctions qui transforment un nom de domaine avant de le passer à IDNA, par exemple pour mettre en œuvre les équivalences entre deux caractères.
  • Et enfin la liste des caractères autorisés, dans le RFC 5892. C'est une des grandes nouveautés, puisque, contrairement à la précédente version, elle ne dépend plus d'une version particulière de la norme Unicode.

La section 2 est ensuite consacrée aux mots-clés de IDNA2008 (attention à ceux qui connaissaient l'ancienne norme, le vocabulaire est souvent nouveau). Les RFC de IDNA2008 utilisent également un vocabulaire non-spécifique aux IDN mais qui est rappelé en section 2.2. Ainsi, un registre désigne toute organisation qui enregistre des noms de domaine, même si elle ne gère pas un TLD (je suis le registre de bortzmeyer.org). LDH (Letters Digits Hyphen) désigne les caractères ASCII qui sont traditionnellement autorisés dans les noms de machine (RFC 1123). Notez bien que les noms de domaine, contrairement à ce qu'écrivent beaucoup d'ignorants, ne sont pas limités à LDH.

La section 2.3 introduit les termes spécifiques à IDN. Par exemple :

  • LDH label est le composant (label) d'un nom de domaine, qui s'écrit uniquement avec LDH (c'est le nom traditionnel comme example dans www.example.com, nom qui compte trois composants). Deux sous-ensemble de LDH label sont définis, Reserved LDH label (ceux dont le troisième et quatrième caractères sont des tirets) et les non-réservés (les noms de domaines pré-IDN comme bortzmeyer.org). Parmi les réservés, certains ont xn en premier et deuxième caractère. Ils forment les XN labels dont tous, c'est important, ne sont pas forcément des encodages valides en Punycode. Ceux qui sont valides sont les A-labels, les autre étant nommés d'un terme péjoratif absolument non justifié, fake A-labels (IDNA2008 contient beaucoup de réglements de compte via le vocabulaire). La figure 1 du RFC représente graphiquement les relations entre ces différents ensembles. Il est recommandé de la consulter en cas de migraine.
  • Les A-labels sont donc la forme ASCII des IDN, produite par Punycode (RFC 3492). Par exemple, xn--stphane-cya est un A-label.
  • Un U-label est un composant valide d'un nom de domaine en Unicode. Par exemple, stéphane est un U-label (dont le A-label est le xn--stphane-cya cité plus haut). Toute chaîne Unicode n'est pas forcément un U-label. Elle doit être normalisée en NFC et ne compter que des caractères autorisés. Tout U-label peut être converti en un A-label unique et réciproquement.

Notons que tous ces termes sont pour des composants d'un nom de domaine (label). Le nom lui-même, s'il contient au moins un A-label ou un U-label est un IDN.

Il y a plein d'autres détails sur les composants d'un nom. Par exemple, lorsque les normes IDNA2008 parlent de l'ordre d'un caractère, c'est une référence à l'ordre de transmission via le réseau. L'affichage peut être différent, puisque certaines écritures se font de droite à gauche.

Tout RFC doit comporter une section sur la sécurité et c'est ici la section 4. Avec IDN, il y a potentiellement des problèmes de débordement de tableau (le U-label peut avoir plus de caractères que son A-label, section 4.2). Mais cette section est aussi l'occasion d'une attaque erronée contre les IDN, accusés d'augmenter la confusion des utilisateurs. D'où des conseils tout à fait inappropriés comme de montrer d'une manière spécifique les noms composés de plusieurs écritures (une pratique pourtant courante dans certains pays).

Les discussions sur cette section avaient été acharnées, avant même la création du groupe de travail, et ont donc mené à des paragraphes déroutants, bourrés d'allusions que le lecteur débutant ne comprendra sans doute pas (comme les mystérieux « risques », jamais explicités, de la section 4.4). Au moins, cette section et la 4.8 disent franchement que la question des caractères visuellement similaires n'a pas de solution technique.


Téléchargez le RFC 5890


L'article seul

RFC 5892: The Unicode code points and IDNA

Date de publication du RFC : Août 2010
Auteur(s) du RFC : P. Faltstrom (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idnabis
Première rédaction de cet article le 22 Août 2010


Dans l'ensemble des RFC sur la version 2 des IDN (appelée IDNAbis ou IDNA2008), ce document normalise les propriétés Unicode utilisées pour calculer la catégorie à laquelle appartient un caractère donné, catégorie qui déterminera s'il est autorisé dans un nom de domaine en Unicode.

Le concept de catégorie est défini dans la section 1 (avertissement : le vocabulaire de IDNAbis est très flou et on trouve « catégorie » ou « propriété » pour ce concept, des termes d'autant plus malheureux qu'ils existent aussi dans Unicode avec un sens différent ; j'ai donc plutôt utilisé « statut »). Ce RFC 5892 contient les tables complètes de tous les caractères Unicode et de leur catégorie. Mais ces tables ne sont présentes qu'à titre d'information : IDNAbis est en effet indépendant de la version d'Unicode utilisée et la vraie norme est l'algorithme utilisé pour créer les tables, algorithme qu'il faut faire tourner pour chaque version d'Unicode, pour trouver la table effective.

IDNAbis repose sur un principe d'exclusion par défaut. Tout caractère est interdit, sauf s'il est autorisé (cf. RFC 4690). Cette autorisation dépend de ses propriétés Unicode, propriétés qui font partie de la norme Unicode. Par exemple, le U+00E9 (petit e accent aigu) est dans la catégorie Unicode Ll (lettres minuscules, presque toutes autorisées).

Le fait d'être dans la bonne catégorie des tables ne suffit pas : dans certains cas, IDNAbis met des contraintes aux combinaisons de caractères.

Quelles sont les catégories (ou statuts) possibles ?

  • PROTOCOL VALID dit PVALID, les caractères acceptés.
  • CONTEXTUAL RULE REQUIRED, pour des caractères acceptés sous condition, par exemple sur leur position dans le composant du nom de domaine. Il est abrégé en CONTEXTJ (caractères qui contrôlent l'attachement de deux mots comme le U+200D, Zero-width joiner) ou CONTEXTO (les autres).
  • DISALLOWED, les caractères interdits.
  • UNASSIGNED, les points de code pas encore affectés dans la norme Unicode, interdits aujourd'hui mais qui, selon leurs propriétés, pourraient devenir autorisés dans le futur.

Le classement d'un caractère dans une de ces catégories dépend de l'algorithme décrit plus loin. Une liste d'exceptions maintenue manuellement (section 2.6) permet d'ajuster le résultat, une autre liste manuelle permet de maintenir la stabilité (d'empêcher un caractère de changer de catégorie).

La section 2 décrit les catégories utilisées pour classer les caractères (à ne pas confondre avec les catégories IDNA, comme PVALID, décrites plus haut) et les propriétés utilisées (elles ne sont pas mutuellement exclusives) :

  • Lettres & Chiffres (section 2.1) : le caractère a une catégorie Unicode dans l'ensemble {Ll, Lu, Lo, Nd, Lm, Mn, Mc}. Par exemple Ll désigne les lettres minuscules, ainsi le êta grec, ͱ (U+0371) est dans cette catégorie (sa définition dans la base Unicode étant 0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370).
  • Instables (section 2.2) : le caractère ne survit pas à une normalisation NFKC avec un changement de casse. La plupart de ces caractères ne seront pas autorisés.
  • Propriétés qu'on peut ignorer (section 2.3) : ces caractères ont des propriétés qui font qu'on peut les ignorer pour les noms de domaines (par exemple les caractères d'espacement, propriété Unicode White_Space).
  • Blocs qu'on peut ignorer (section 2.4) : des blocs entiers des tables Unicode peuvent être ignorés comme le bloc des symboles utilisés en musique qui va de U+1D100 (𝄀) à U+1D1FF.
  • LDH (Letters-Digits-Hyphens), les caractères ASCII traditionnellement utilisés dans les noms de machine (section 2.5).
  • Des exceptions, définies manuellement, pour le cas où les propriétés Unicode ne donnent pas le bon résultat (section 2.6). Ainsi, après de très longues discussions dans le groupe de travail, le ß allemand, le ς grec et le ་ tibétain (ce dernier, le tsheg, a été l'objet du débat le plus aveugle puisqu'aucun expert de cette écriture n'était présent) ont été manuellement autorisés (alors qu'ils auraient été interdits en appliquant l'algorithme). Par contre, les chiffres indo-arabes, qui auraient été autorisés inconditionnellement, sont maintenant autorisés uniquement dans certains contextes (voir le RFC 5564 pour une discussion sur ces chiffres).
  • Compatibilité (section 2.7) : cette catégorie est actuellement vide. Mais, dans les futures versions d'Unicode, des changements des propriétés pourraient faire passer des caractères de PVALID à DISALLOWED ou le contraire. Ils seront alors mis dans cette catégorie pour conserver leur ancien statut.
  • Contrôle du collage entre caractères (section 2.8). Cette catégorie regroupe les caractères « gluons » qui servent à coller des caractères ou des mots qui seraient normalement séparés. Certaines écritures (par exemple les indiennes) en font un grand usage.
  • Vieil Hangul (section 2.9), une catégorie très ad hoc pour des caractères utilisés en Corée.
  • Et enfin, la dernière catégorie, celle des caractères non actuellement affectés (section 2.10) mais qui pourraient l'être dans les futures versions d'Unicode.

Bien, on a dix catégories. Comment les utilise t-on pour déterminer si un caractère est acceptable ou pas ? C'est l'objet de la section 3, qui indique cet algorithme en pseudo-code. Je n'en donne qu'une partie ici :

SI le caractère est dans les Exceptions, sa propriété IDNA est donnée
par la table Exceptions
...
SINON SI le caractère est dans LDH, alors il est PVALID
...
SINON SI le caractère est dans les Blocs Ignorables alors il est
DISALLOWED
...
SINON SI le caractère est dans les Lettres & Chiffres, alors il
est PVALID

SINON SI (cas par défaut) il est DISALLOWED

La section 4 insiste sur le fait que la liste des caractères faisant foi est celle calculée par l'algorithme ci-dessus. La liste fournie dans ce RFC 5892, en annexe B, n'est là que pour information (en effet, chaque nouvelle version d'Unicode modifiera les tables).

On a vu que le sort d'un caractère dont le statut est CONTEXT nécessite de regarder une table. Celle-ci est définie dans la section 5.2 et sa syntaxe figure dans l'annexe A. Elle est hébergée à l'IANA.

Enfin, même si elle n'a pas de caractère normatif, la plus grande partie du RFC est formée par l'annexe B, qui donne l'état actuel des tables de caractères avec leur statut.

Comme indiqué plus haut, les tables figurant dans le RFC ne sont pas normatives, seul l'algorithme l'est. En pratique, les tables ont été produites par un programme écrit par l'auteur du RFC qui ne le distribue pas (malgré plusieurs demandes). J'ai refait une mise en œuvre incomplète (manque de temps) de l'algorithme qu'on peut récupérer en create-idnabis-tables.py.


Téléchargez le RFC 5892


L'article seul

Articles des différentes années : 2010  2009  2008  2007  2006  2005  2004  Précédentes années

Syndication : Flux Atom avec seulement les résumés et Flux Atom avec tout le contenu