Ce blog n'a d'autre prétention que de me permettre de mettre à la disposition de tous des petits textes que j'écris. On y parle surtout d'informatique mais d'autres sujets apparaissent parfois.
Première rédaction de cet article le 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 :
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.
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) :
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 :
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.
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.
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 :
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).2001:db8:f00f::fbf0:1.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).
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.
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 :
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 :
message/feedback-report,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,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.
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 :
.ES pas .SP.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 ?
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.
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;
}
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.
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.
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.
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.
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.
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 :
À 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 :
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.
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 »).
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 :
2001:db8:0:0:1:0:0:1 et
2001:0db8:0:0:1:0:0:1 sont ainsi équivalentes
(deuxième champ).::. 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.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 ?
2001:0db8::0001 doit être écrit
2001:db8::1.:: 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.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.
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 :
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 :
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.
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 :
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.
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 :
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 :
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.xn--stphane-cya est un
A-label.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.
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) :
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).White_Space).U+1D100
(𝄀) à
U+1D1FF.PVALID à
DISALLOWED ou le contraire. Ils seront alors mis dans cette catégorie
pour conserver leur ancien statut.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.
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