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 : Août 2013
Auteur(s) du RFC : M. Goyal (University of Wisconsin, Milwaukee), E. Baccelli (INRIA), A. Brandt (Sigma Designs), J. Martocci (Johnson Controls)
Expérimental
Réalisé dans le cadre du groupe de travail IETF roll
Première rédaction de cet article le 27 août 2013
Le protocole RPL (Routing Protocol for Low power and Lossy Networks), normalisé dans le RFC 6550, est conçu pour des réseaux de machines très bon marché, ayant peu de capacités (mémoire et calcul), étant souvent très limitées en énergie, et étant connectées par des liens de qualité médiocre. Un tel environnement peut par exemple se rencontrer dans des réseaux de capteurs dispersés dans un environnement industriel. Une partie des machines du réseau va se dévouer pour router les paquets des autres. RPL permet de trouver et de diffuser des routes mais celle choisie ne sera pas forcément optimale. D'où ces deux extensions à RPL permettant à un routeur de 1) mesurer une métrique donnée en émettant un paquet de contrôle vers la destination, paquet qui accumulera au fur et à mesure, dans les routeurs intermédiaires, les informations à propos de la route utilisée actuellement et, 2) découvrir à la demande une route meilleure (si tant est qu'il y en a une).
C'est que ce n'est pas une vie que d'être routeur dans un LLN (Low power and Lossy Network, les réseaux difficiles dont je parlais au paragraphe précédent). Le RPL classique du RFC 6550 essaie de faciliter les choses en limitant le réseau à un graphe acyclique dirigé vers un puits de données et en calculant toutes les routes à l'avance (ce qu'on nomme un protocole proactif). Une extension à RPL, nommée P2P-RPL (P2P pour pair-à-pair) et normalisée dans le RFC 6997, permet à RPL de devenir réactif et donc de calculer des routes à la demande. Elle permet aussi de trouver des routes plus courtes, en évitant le passage par le sommet du graphe pré-établi. Le routeur utilise, pour ces calculs, les métriques du RFC 6551 (latence, capacité, qualité, et autres métriques dans le registre IANA). Mais comment connaître leur valeur effective dans un réseau ? Eh bien, en les mesurant, tout simplement.
Le protocole RPL ne transmettant pas cette information pour toutes les routes, c'est au routeur qui en a besoin de demander. Il génère un paquet de contrôle RPL d'un nouveau type, Measurement Request indiquant ce qu'il veut savoir à propos du chemin entre lui-même et la destination. Chaque routeur sur le trajet va mettre à jour ce paquet avec le coût (pour la métrique demandée) du lien effectivement emprunté. Au bout, le destinataire répondra au demandeur, avec un message de contrôle Measurement Reply, contenant toute l'information accumulée. Le demandeur pourra alors agir (changer d'avis pour certaines routes, par exemple).
En fait, les deux messages utilisent le même type de paquets, les Measurement Object de code 0x06 (section 3 et registre IANA). Un bit dans son en-tête, le bit T (pour Type) sert à distinguer si ce Measurement Object est un Measurement Request ou un Measurement Reply. Le paquet contient surtout des options Metric Container (section 6.7.4 du RFC 6550 et section 2.1 du RFC 6551) qui accumuleront au fur et à mesure les valeurs demandées.
Il est intéressant de comparer ce mécanisme à celui de traceroute qui n'accumule pas les mesures mais compte sur une réponse de chaque routeur intermédiaire vers la source ; des options avaient été proposées pour un traceroute « enregistreur » - Record Route du RFC 791 ou option IP du RFC 1393 - mais elles n'ont eu aucun succès.
Notez bien que, dans un réseau ad hoc, rien ne garantit que tous les routeurs accepteront de procéder à cet enregistrement de données. Ils ont parfaitement le droit de refuser de le faire (voir la section 5 de notre RFC), par exemple pour économiser leur batterie ou bien parce qu'ils trouvent une telle demande trop indiscrète (section 8 du RFC).
Il existe déjà plusieurs mises en œuvre de cette extension expérimentale et un test d'interopérabilité a été documenté. Sinon, un bon article consacré aux mesures de P2P-RPL est « The P2P-RPL Routing Protocol for IPv6 Sensor Networks: Testbed Experiments ».
Merci à Emmanuel Baccelli pour sa relecture attentive.
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : J. Mitchell (Microsoft)
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 29 juillet 2013
Comme pour beaucoup de nombres utilisés dans les protocoles TCP/IP, les numéros de système autonome ont une plage réservée aux usages privés, ne devant pas être transmis à l'extérieur. Ce nouveau RFC élargit la plage existante, qui était jugée trop petite par des gens qui gèrent des gros centres de données (comme Microsoft ou certains acteurs de l'infonuagique).
La section 10 du RFC 1930 réservait la plage allant de 64 512 à 65 535 (soit 1 024 numéros) pour des AS privés. Augmenter la taille de cette plage était délicat tant que les numéros d'AS étaient limités à 16 bits. Mais ils sont désormais sur 32 bits (RFC 6793) et il n'y a donc plus de raison de faire des économies. Une seconde plage, utilisant des numéros sur 32 bits, est donc réservée, allant de 4 200 000 000 à 4 294 967 294 (94 967 295 numéros). Ces deux plages sont documentées dans le registre IANA. (Notez que d'autres plages sont réservées pour la documentation, par le RFC 5398. Les numéros des deux plages de notre RFC sont, eux, conçus pour être utilisés par de vrais routeurs.)
La section 4 de notre RFC met en garde les opérateurs qui
utilseraient ces numéros privés : ils ne doivent
pas apparaître sur l'Internet public. Lorsqu'une
annonce BGP dont le chemin (attributs
AS_PATH
ou AS4_PATH
) sort du
domaine privé, ces numéros d'AS doivent être retirés. Les commandes sont neighbor x.x.x.x remove-private-as
pour IOS (c'est configuré pour chaque voisin BGP) et neighbor x.x.x.x remove-private
pour
JunOS mais attention : les anciennes versions
de ces logiciels ne connaissaient que la première plage d'AS privés et
ne retireront donc pas les numéros de la seconde plage. D'autre part,
certains logiciels pour les routeurs ne
retirent pas les numéros d'AS privés si le chemin dans l'annonce BGP
contient un mélange d'AS privés et publics. Si le routeur en question
n'a pas été mis à jour pour connaître la seconde plage de numéros d'AS
privés, il va les prendre pour des numéros d'AS publics et ne rien
retirer...
À noter que l'idée même d'avoir des nombres pour usage privé (que ce soient les numéros d'AS ou d'autres comme les adresses IP) défrise toujours un certain nombre de gens à l'IETF et que cette minorité s'était fait entendre dans le débat sur cet élargissement.
Date de publication du RFC : Août 2013
Auteur(s) du RFC : J. Touch (USC/ISI)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 24 août 2013
Le protocole TCP dispose d'un champ « Options » permettant d'indiquer des fonctions spécifiques. Ce champ commence par un identificateur d'option (sur un octet) et deux valeurs sont réservées pour des options expérimentales, non enregistrées. Deux, c'est trop peu, et, en prime, il y a parfois collision entre deux options expérimentales différentes. Notre RFC propose donc un nouveau mécanisme éliminant ces collisions, en ajoutant un deuxième identificateur, l'ExID, dans les options expérimentales.
Le champ « Options » est décrit dans le RFC 793. Il a deux formes mais la plus courante est composée d'un octet indiquant l'option, d'un octet indiquant la longueur de l'option et de données spécifiques à l'option (un TLV, donc). Les options sont enregistrées à l'IANA et sont aujourd'hui au nombre d'une trentaine. 30 sur 256 possibles, cela justifie de les allouer avec prudence (RFC 2780) et les gens qui veulent juste essayer une idée amusante, sans enregistrer leur option, n'avaient pas de solution simple avant que le RFC 4727 ne réserve les options 253 et 254 pour les expérimentations. Si vous avez une idée qui nécessite une option TCP, et que vous voulez la mettre en œuvre, prenez un de ces deux numéros et mettez-le dans vos paquets TCP, vous serez dans la légalité (le RFC 3692 dit toutefois que cela ne doit pas être activé par défaut).
Mais ces expérimentations risquent de se marcher sur les pieds entre elles. Par exemple, le RFC 6013 s'alloue l'option 253. Si vous voulez tester une option en même temps que celle du RFC 6013, il ne vous reste plus qu'un numéro, ce qui peut être insuffisant (certains systèmes nécessitent plusieurs options). À noter que cet usage d'un numéro d'option expérimental est légal (c'est fait pour) mais qu'il existe aussi des squatteurs, qui utilisent des numéros normalement réservés sans les avoir enregistrés proprement. Les options 31 et 32 avaient ainsi été squattées autoritairement, comme 76 à 78, 33, 69, 70, et 76 à 78 (ces derniers dans des produits commerciaux). Le registre IANA les note comme « known unauthorized use without proper IANA assignment ».
Plusieurs approches ont été suggérées à
l'IETF pour régler ce problème. Il a été
proposé d'élargir l'espace des numéros d'options
(Internet-Draft
draft-eddy-tcpm-addl-exp-options
) et/ou de
libéraliser les règles d'allocation, actuellement très strictes (il
faut un RFC sur le chemin des normes pour réserver une option). Ce
RFC 6994 utilise une autre approche : il crée un
« sous-espace » à l'intérieur des options expérimentales, dans lequel on
peut (mais ce n'est pas obligatoire) enregistrer sans trop de
formalités une expérimentation et son identificateur. C'est désormais
l'approche recommandée pour les nouvelles options expérimentales TCP
(et obligatoire si l'option expérimentale est déployée sur l'Internet public).
Le principe (section 3) est de remplacer la structure {numéro d'option, longueur, valeur} par {numéro d'option, longueur, ExID, valeur} où le ExID est l'identificateur d'une expérimentation. La taille des ExID (16 ou 32 bits) permet d'en avoir beaucoup et donc d'avoir une politique d'enregistrement libérale sans craindre d'épuiser une ressource finie. L'IANA les enregistre donc sur une base toute simple : « premier arrivé, premier servi » (RFC 5226 pour les différentes options d'allocation possibles). Le registre de ces ExID est en ligne (il compte actuellement trois expérimentations dont le Fast Open TCP qui a été décrit dans le RFC 7413).
Bon, mais l'ExID fait 16 ou 32 bits, alors ? C'est subtil : les 16 premiers bits doivent être uniques pour identifier une expérimentation. Les 16 bits optionnels suivants servent de nombre magique, pour éviter le risque de collision avec des mises en œuvre de TCP qui ne connaissent pas ce RFC (ou bien l'ignorent) et mettent leurs données juste après l'octet de longueur. Si on veut économiser de la place, on choisit un ExID de 16 bits, si on veut minimiser le risque de collision, on prend 32 bits.
Que va donc faire une mise en œuvre de TCP qui rencontre ces options (section 3.2) ? Si l'option est 253 ou 254, elle doit lire l'ExID et ignorer l'option s'il s'agit d'une expérimentation qui lui est inconnue.
Mais les collisions, alors ? Elles peuvent toujours exister. Si une implémentation ancienne de TCP utilise l'option 253 et met au début des données qu'elle envoie la valeur 0x15df, et que le récepteur TCP, conforme à ce nouveau RFC 6994, croit qu'il s'agit de l'expérimentation 5599, qu'il connait, et se met à analyser l'option comme telle ? Il n'y a pas de solution magique. La section 4 de notre RFC recommande aux receveurs TCP d'être robustes face à de telles collisions, ou bien de mettre en œuvre un mécanisme de contrôle de la cohérence des données, pour rejeter les faux positifs.
Un problème classique (et non spécifique à TCP) avec les options expérimentales est qu'un jour, elles seront peut-être normalisées et qu'il faudra alors gérer une transition depuis l'option expérimentale vers l'option standard. La section 5 couvre ce cas mais ne recommande pas une stratégie particulière. Elle se contente de dire qu'envoyer les deux options (l'expérimentale et la standard) dans le même paquet est une mauvaise idée (l'espace des options est limité en TCP).
La section 6 discute des autres approches qui auraient pu être choisies. Par exemple, au lieu des ExID, on aurait pu marquer les options avec un identificateur de l'organisation qui dirige l'expérience, en utilisant les OUI de l'IEEE ou bien les Enterprise Numbers de l'IANA (RFC 1155). Mais les OUI sont très chers (comme souvent à l'IEEE), plus de 1 800 dollars. Les PEN (Private Enterprise Numbers) sont gratuits mais ne sont normalement pas allouables à un individu. Et, dans les deux cas, ces nombres sont plus grands que l'ExID (les PEN n'ont pas de taille définie actuellement mais ils sont déjà trop nombreux pour 16 bits) alors que l'espace est limité dans le champ Options de TCP, puisque tout octet prend la place d'un octet utile aux données.
Si on regarde les versions de développement de
Linux et de FreeBSD, on
ne trouve rien dans ce dernier
(sys/netinet/tcp_input.c
dans tcp_dooptions()
), qui ne connait pas, par défaut, les
options expérimentales. Pour Linux, seul Fast Open
est reconnu. Le code dans net/ipv4/tcp_input.c
,
tcp_parse_options()
dit :
case TCPOPT_EXP: /* Fast Open option shares code 254 using a * 16 bits magic number. It's valid only in * SYN or SYN-ACK with an even size. */ if (opsize < TCPOLEN_EXP_FASTOPEN_BASE || get_unaligned_be16(ptr) != TCPOPT_FASTOPEN_MAGIC || foc == NULL || !th->syn || (opsize & 1)) break; foc->len = opsize - TCPOLEN_EXP_FASTOPEN_BASE; if (foc->len >= TCP_FASTOPEN_COOKIE_MIN && foc->len <= TCP_FASTOPEN_COOKIE_MAX) memcpy(foc->val, ptr + 2, foc->len); ... }
Où TCPOPT_FASTOPEN_MAGIC
vaut 0xF989 (l'ExID sur
16 bits dans le registre IANA).
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : J. Schoenwaelder (Jacobs University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF netmod
Première rédaction de cet article le 31 juillet 2013
Le langage de modélisation YANG, normalisé dans le RFC 6020, est notamment utilisé dans le protocole de gestion à distance NETCONF (RFC 6241). C'est en YANG que les utilisateurs de NETCONF décrivent les données à manipuler via NETCONF. Ce RFC, successeur du RFC 6021, normalise une bibliothèque de types de données d'usage général, dérivés des types de base de YANG.
Ces types de base sont décrits dans la section 9 du RFC 6020. On y trouve les classiques de l'informatique,
boolean, entiers,
string, etc. Deux modules YANG sont décrits dans ce
nouveau RFC,
ietf-yang-types
pour des types non limités à
l'Internet et ietf-inet-types
pour des types
spécifiques à TCP/IP.
Je ne vais pas ici reprendre la liste de tous ces nouveaux types,
juste donner quelques exemples de ce qu'apporte ce RFC. En section 3,
les types généraux, on trouve par exemple,
counter32
. C'est un compteur, c'est à dire une
variable qui ne fait que grimper, jusqu'au moment d'atteindre une
valeur maximale (elle repart alors de zéro). Comme son nom l'indique,
il est stocké sur 32 bits. Par contre, gauge32 peut
monter et descendre.
Le type yang-identifier, un nouveau venu, est
une chaîne de caractères ASCII (ne commençant
pas par xml
). Il est défini
en YANG par une expression rationnelle :
typedef yang-identifier { type string { length "1..max"; pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*'; pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*'; ...
date-and-time, lui, existait déjà dans le RFC 6021. C'est une date au format du RFC 3339 qui est proche du format traditionnel des schémas XML (mais, par contre, est différent de celui utilisé dans le SMI). Au contraire de date-and-time, qui est formaté, timeticks est simplement un nombre de secondes depuis l'epoch (non spécifiée : chaque schéma qui utilisera ce type indiquera quelle est l'epoch).
Il y a aussi des types plus orientés réseau comme mac-address pour les adresses MAC :
typedef mac-address { type string { pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'; }
Et d'autres qui empruntent à des identificateurs existants comme uuid (RFC 9562).
En section 4, les types spécifiques aux protocoles TCP/IP, on a entre autres ip-version qui permet d'indiquer si on parle d'IPv4 ou d'IPv6 :
typedef ip-version { type enumeration { enum unknown { value "0"; description "An unknown or unspecified version of the Internet protocol."; } enum ipv4 { value "1"; description "The IPv4 protocol as defined in RFC 791."; } enum ipv6 { value "2"; description "The IPv6 protocol as defined in RFC 2460."; } } ...
Il y a bien sûr les numéros de port :
typedef port-number { type uint16 { range "0..65535"; } ...
Et de système autonome :
typedef as-number { type uint32; ...
Et évidemment les adresses IP :
typedef ip-address { type union { type inet:ipv4-address; type inet:ipv6-address; } ... typedef ipv6-address { type string { pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + '(%[\p{N}\p{L}]+)?'; pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + '(%.+)?'; } ...
Un exercice amusant : essayez de retrouver dans quel RFC est défini l'expression rationnelle officielle pour les adresses IPv6... (Avertissement : c'est difficile.)
Enfin, ce RFC donne aussi une définition du type domain-name pour les noms de domaine :
typedef domain-name { type string { pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + '|\.'; length "1..253"; } ...
C'est une définition très contestable car, limitée à
l'ASCII, elle oblige à représenter les
IDN par un A-label
(café.fr
doit être écrit
xn--caf-dma.fr
, RFC 5890). Pire, le texte d'explication qui
accompagne le module est plutôt embrouillé quant à la la définition des noms de domaine par rapport à
celle des noms de machines (plus restrictive).
Par rapport au RFC 6021, qui contenait la bibliothèque originale, ce RFC ajoute quelques types (yang-identifier, uuid, etc, la liste complète est dans l'annexe A).
Date de publication du RFC : Septembre 2013
Auteur(s) du RFC : J. Quittek, M. Chandramouli (Cisco Systems), R. Winter (NEC Europe), T. Dietz (NEC Europe), B. Claise (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF eman
Première rédaction de cet article le 1 octobre 2013
L'augmentation considérable des coûts de l'énergie, et la montée plus que justifiée des préoccupations écologiques, fait que la question de la consommation énergétique des équipements informatiques devient de plus en plus cruciale (certaines études estiment que la consommation d'énergie de l'Internet dépasse celle d'un pays comme la Russie). Les gros centres de données du nuage, usines à consommer du mégawatt, sont particulièrement visés. Cela a amené l'IETF à se lancer dans un domaine nouveau pour elle, et à créer un groupe de travail consacré à la gestion de l'énergie, EMAN, dont voici le premier vrai RFC, le cahier des charges du problème.
Le modèle envisagé est celui d'engins qui consomment ou fournissent de l'énergie, typiquement sous forme électrique, et qu'on veut pouvoir à la fois surveiller (monitoring function) et piloter (control function). Ces engins ont parfois une adresse IP, permettant de leur parler directement, et parfois pas, et il faut alors passer par un relais, qui va être la face visible de l'engin. Ce premier RFC du groupe EMAN définit les services indispensables dans les futures normes de gestion de l'énergie, suivant le modèle décrit dans le RFC 7326 (attention, ce RFC est un cahier des charges pour les normes, les futurs RFC d'EMAN, pas forcément pour les mises en œuvres qui suivront).
La gestion d'engins connectés au réseau n'est évidemment pas un problème nouveau et il existe déjà solutions et normes. Mais la gestion de l'énergie a trois particularités :
Avant d'aborder le cahier des charges proprement dit, la section 2 de notre RFC expose la terminologie, car tous les participants à l'IETF, bien versés dans le vocabulaire TCP/IP, ne connaissent pas forcément celui du monde de l'énergie (l'IEEE a un « Authoritative Dictionary of IEEE Standards Terms » d'où le RFC extrait plusieurs termes, mais je ne trouve pas ce dictionnaire en ligne). Donc, révisons un peu physique et ingéniérie :
La section 3 complète cette section 2 de terminologie en exposant quelques problématiques générales, qu'il faut avoir en tête lorsqu'on veut gérer l'énergie. D'abord, la notion d'état (Power state) : un engin peut être en état normal (il fonctionne, il répond et il consomme du courant), endormi (il consomme moins de courant, il ne répond pas aux requêtes normales mais il peut revenir en état normal rapidement) ou éteint (il ne consomme plus rien mais peut prendre un certain temps à se rallumer et à redevenir opérationnel). Les engins les plus simples n'ont que deux états, allumé et éteint. Les plus perfectionnés en ont plus que trois : par exemple, ils peuvent avoir des modes de basse consommation où l'engin reste complètement opérationnel mais avec des performances réduites. Sur des engins composés de plusieurs parties relativement indépendantes, il est parfois possible de couper le courant dans une partie de ces sous-ensembles et pas seulement dans l'engin entier.
Le but ultime de la gestion de l'énergie est d'économiser du courant. Comme rien n'est parfait en ce bas monde, cela se fera souvent au prix d'un service moins bon. Il sera donc en général nécessaire de faire des compromis.
La gestion de l'énergie peut être entièrement locale (à l'intérieur de l'engin lui-même) ou bien globale au réseau. Un exemple de gestion locale est une machine qui se met en sommeil automatiquement lorsqu'elle n'a pas eu d'activité depuis N minutes. Cela peut se faire sans réseau, sans collecter l'information et sans système central. Un exemple de gestion globale est un système qui voit que la consommation électrique du réseau devient trop importante (en coût ou, tout simplement, par rapport aux capacités du fournisseur d'énergie) et qui éteint alors autoritairement certains engins. Le système de gestion ayant plus d'informations que les machines locales, il peut prendre des décisions plus appropriées, et tenir compte de politiques globales (on éteint les machines dans le bureau la nuit). Les deux méthodes ont leurs avantages et leurs inconvénients et, en général, on combine les deux.
À noter (section 3.4) que la supervision de la consommation d'énergie, à elle seule, ne diminue pas la consommation. Elle va même l'augmenter, puisque le système de supervision consomme lui-même du courant. Pour que ce système mène à une diminution de la consommation, il faut aussi qu'il soit utilisé pour chercher les économies possibles, évaluer les mesures de réduction de consommation, assurer la comptabilité de chaque entité, etc.
Pour assurer une bonne supervision, avec une granularité permettant cette comptabilité, il va falloir des identificateurs pour désigner les différentes entités (section 4). Une entité peut être une machine ou bien seulement une partie d'une machine (un disque dur, par exemple, ou bien une line card). En effet, certaines mesures d'économie d'énergie peuvent être à ce niveau de détail (éteindre une seule line card). Il existe déjà de tels identificateurs, par exemple dans les MIB des RFC 4133 et RFC 3621. Il faudra donc lier les informations de gestion de l'énergie à ces identificateurs, traitant des problèmes comme la persistence en cas de redémarrage.
Ensuite, il faut connaître, pour chaque entité supervisée et/ou contrôlée, un certain nombre d'informations (section 5). Par exemple, il est préférable de connaître l'importance d'une entité, pour éviter d'éteindre une machine importante alors qu'on voulait économiser quelques watts. Une autre propriété utile est l'ensemble des caractéristiques statiques de son alimentation électrique : utilise-t-elle du courant continu ou alternatif, quelle est la tension normale, la fréquence normale (par exemple, 230 V à 50 Hz), etc. Il faut aussi connaître la liste des interfaces utilisées pour l'énergie, et s'il s'agit de production (power outlet, par où on envoie de l'énergie) ou de consommation (power inlet, par où on reçoit de l'énergie).
Et il y a des caractéristiques dynamiques :
Après la supervision, le contrôle (section 6). Contrairement à la supervision, il est actif. Il s'agit d'agir. Agir sur quoi ?
Une section 9 détaillée couvre les problèmes de sécurité. On a beaucoup parlé des risques de sécurité des SCADA, souvent connectés à l'Internet sans réflechir. Ces systèmes de contrôle, souvent anciens et n'ayant pas fait l'objet d'une analyse de sécurité sérieuse, sont parfois reliés à ce réseau mondial sans précautions. Contrôler l'état des machines et leur fourniture d'électricité est clairement une fonction très sensible. La sécurité doit donc être soigneusement pesée. Tout doit être authentifié et autorisé. Et les engins qui mettent en œuvre les services décrits dans ce RFC ne devraient pas être connectés à l'Internet public sans une très bonne raison (section 9.2).
Il n'y a pas que le contrôle qui pose des problèmes de sécurité. Par exemple, la supervision soulève des problèmes de vie privée, comme cela a été plusieurs fois évoqué dans le débat sur les compteurs intelligents.
Depuis ce cahier des charges, plusieurs RFC sur le sujet ont été publiés comme les RFC 7326 et le RFC 7603.
Date de publication du RFC : Août 2013
Auteur(s) du RFC : V. Dolmatov (Cryptocom), A. Degtyarev (Cryptocom)
Pour information
Première rédaction de cet article le 5 septembre 2013
Ce RFC documente en anglais une norme russe de l'organisme GOST. GOST R 34.11-2012 est une fonction de condensation cryptographique. Elle pourra notamment être utilisée pour DNSSEC.
Les algorithmes GOST (un abus de langage puisque GOST est normalement le nom de l'organisme de normalisation) sont une alternative russe aux algorithmes de cryptographie d'origine états-unienne comme RSA ou ECDSA (qui peuvent être remplacés par GOST R 34.10-2001) ou comme SHA-2 (qui peut être remplacé par GOST R 34.11-2012, qui fait l'objet de ce RFC). Pour être utilisés dans les protocoles IETF, il leut fallait une documentation en anglais. GOST R 34.10-2001 avait été documenté dans le RFC 5832. Notre RFC 6986 documente le petit dernier membre de la famille (son prédécesseur pour la condensation, GOST R 34.11-94, était dans le RFC 5831). Notez que les algorithmes GOST sont normalisés pour un usage dans le cadre de DNSSEC (RFC 9558).
Comme les autres algorithmes GOST, notre R 34.11-2012 est donc un algorithme officiel en Russie. Il a été approuvé par le décret n° 216 de l'agence fédérale chargée de la régulation technique, en août 2012. À terme, il vise à remplacer l'ancien R 34.11-94. C'est un algorithme de condensation cryptographique, qui peut produire des condensats de 256 ou 512 bits.
Je ne vais pas essayer de vous expliquer son principe de fonctionnement (sections 4 à 10), car c'est trop loin de mon domaine de compétence. Si vous êtes plus courageux que moi, notez qu'il y a beaucoup de maths et que, dans le formatage texte brut des RFC, ce n'est pas forcément idéal.
Questions mises en œuvre, notez qu'OpenSSL
1.0.1c n'a apparemment pas d'algorithmes de condensation
GOST par défaut. openssl dgst
-h
pour voir la liste. Il faut apparemment éditer le openssl.cnf pour y avoir accès.
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : A. Morton (AT&T Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF bmwg
Première rédaction de cet article le 19 juillet 2013
Traditionnellement, les mesures des caractéristiques d'un réseau en labo (RFC 2544) se faisaient avec des paquets de taille constante, afin de bien contrôler les conditions de la mesure, de savoir exactement ce qui était mesuré et donc de pouvoir reproduire la mesure à volonté. C'est par exemple ce que fait la commande ping avec son option -s. Mais les réseaux réels sont bien différents : ils font passer des paquets de taille très diverses. Il est donc fréquent aujourd'hui de tester avec un mélange de paquets de différentes tailles, ce qu'on nomme un IMIX (Internet MIXture). De nos jours, les équipements de test ont souvent la possibilité d'utiliser des IMIX. Mais les tests doivent être reproductibles, il faut donc un moyen de caractériser un IMIX, d'indiquer sa composition (autrement que par un vague « on a utilisé un IMIX »). C'est le but du mini-langage présenté dans ce RFC.
En gros, les petits paquets vont tester la capacité du réseau à traiter les en-têtes et les gros vont tester sa capacité à faire circuler des bits. On a donc besoin des deux dans un test. L'IMIX genome est la description, dans un langage formel, de la répartition des tailles de paquets. (Comme un génome décrit une espèce.)
Donc, à quoi ressemble un IMIX (section 3 du RFC) ? À une série de
lettres dont chacune code une taille de paquet donnée, en utilisant
les tailles « standard » du RFC 2544. Ainsi,
avec la table a = 64 octets, b = 128, c = 256, d = 512, e = 1 024, f =
1 280 et g = 1518, l'IMIX aaafg
désigne une
séquence de cinq paquets, les trois premiers faisant 64 octets, le
quatrième 1 280 et le dernier ayant la taille maximale sur
Ethernet. Une lettre z est utilisée pour dire
« la MTU du lien », donc, ici, on aurait pu
utiliser aaafz
. Notez bien qu'avec cette notation, les autres tailles
ne peuvent pas être représentées (il faut choisir la taille la plus
proche) et qu'un test avec des milliers de paquets est décrit par un
IMIX assez illisible...
Si on tient à utiliser des tailles non prévues par le RFC 2544, la section 4 prévoit un moyen de définir
localement des lettres, notées en majuscule. Avec la table locale A =
98, B = 1 020, l'IMIX BBAA
indiquera deux gros
paquets puis deux petits.
Ce système manque clairement de souplesse : et si, pour un test long, une séquence de
base est répétée ? Ou bien si les tailles sont
choisies par un processus pseudo-aléatoire ? La
section 5 décrit deux fonctions utiles du mini-langage de description
des génomes IMIX. Pour les séquences répétées, on se sert simplement
d'un encodage en RLE. Le RFC ne propose pas de
syntaxe concrète pour le décrire, l'exemple est juste un tableau « 20
fois abcd
puis 5 fois ggga
et enfin 10 fois dcba
». Le RFC propose également
un autre mécanisme (à nouveau sans syntaxe précise), en indiquant les
pourcentages de chaque taille (sans spécifier la séquence) : « 23 % de
64 octets, 67 % de 128 et 10 % de 1 000 ».
Le RFC prévoit aussi le cas où les tailles sont générées par un algorithme. Dans ce cas, pas de langage particulier, il faut le décrire en langage naturel lorsqu'on publie les résultats de la mesure (« on part de paquets de 64 octets et on incrémente leur taille de 1 à chaque paquet, s'arrêtant à la MTU »). Idem si l'algorithme utilisé est un générateur pseudo-aléatoire, qui doit également être décrit (avec la graine utilisée).
Si vous voulez lire des articles sur les IMIX, voir « "Test Methodology Journal: IMIX (Internet Mix) », « Library: Test Plans » ou « The Journal of Internet Test Methodologies ». Pour une discussion sur la normalisation d'IMIX (et pas du langage qui les décrit), voir une discussion terminologique dans le groupe de travail.
Date de publication du RFC : Août 2013
Auteur(s) du RFC : W. Wang (Zhejiang Gongshang University), K. Ogawa (NTT Corporation), E.H. Haleplidis (University of Patras), M. Gao (Hangzhou BAUD Networks), J. Hadi Salim (Mojatatu Networks)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 25 août 2013
Un élément essentiel de la culture IETF est l'importance donnée aux programmes qui marchent : rough consensus and running code. D'où les fréquents tests d'interopérabilité, entre diverses mises en œuvre des protocoles IETF, afin de vérifier que, non seulement le code tourne mais qu'il peut interagir avec d'autres instances. Le groupe de travail ForCES, qui normalise des protocoles de communication internes aux routeurs, a ainsi procédé à deux ateliers de tests d'interopérabilité, ce RFC documentant le second.
Le premier avait eu lieu en 2009 à l'université de Patras et avait été documenté dans le RFC 6053. Le second a eu lieu en février 2011 à l'ITL (Internet Technology Lab) à l'université de Zhejiang Gongshang. (Oui, je sais, c'est long, entre l'atelier et la publication du compte-rendu dans un RFC...)
Rappelons ce que fait ForCES : il normalise la communication entre les éléments d'un routeur (ou autre engin du réseau : la norme parle de NE pour Network Element). Le but est de permettra la construction de routeurs en kit, en assemblant des parties d'origines différentes, mais parlant toutes ForCES. Le système ForCES est riche et complexe et cet atelier d'interopérabilité testait cinq composants : le protocole de communication entre CE (Control Element) et FE (Forwarding Element), normalisé dans le RFC 5810, le protocole de transport sous-jacent (RFC 5811), le modèle des FE (RFC 5812), la bibliothèque standard (RFC 6956) et le mécanisme de haute disponibilité (dont le RFC n'a pas encore été publié). Des CE et FE d'origines diverses ont été connectés entre eux, se sont parlé, la bonne compréhension a été vérifiée et tcpdump et Wireshark ont été utilisés pour un contrôle supplémentaire.
Trois mises en œuvre de ForCES ont été testées, les mêmes qu'à l'atelier précédent (ForCES n'a pas pour l'instant suscité un intérêt massif) : celle de NTT, celle de l'université de Patras, et celle faite en commun entre l'université de Zhejiang Gongshang et la société BAUD Network. Les Grecs n'ayant pu se déplacer, ils ont participé aux tests à distance, connectés via un VPN (dans la réalité, bien sûr, les FE et les CE seront toujours proches, souvent dans le même boîtier physique). Globalement, les tests ont été des succès, à part un problème embêtant avec l'encapsulation des données dans une réponse ForCES (voir les détails plus loin). Comme toujours, ces tests ont permis de découvrir des erreurs ou des approximations dans les RFC.
Les communications utilisaient IPsec, puisque le RFC sur le transport de ForCES, RFC 5811, fait obligation à chaque mise en œuvre de ForCES d'avoir IPsec (mais pas forcément de l'activer par défaut : c'est sa disponibilité qui est obligatoire, pas son usage).
Un exemple d'un des scénarios testés (section 3.4) : deux machines terminales sur deux réseaux locaux différents étaient connectées via deux routeurs OSPF. L'un était un routeur classique, l'autre une machine ForCES dont le CE (Control Element) parlait OSPF avec le routeur classique pendant que le FE (Forwarding Element) transmettait les paquets. Ce scénario nécessitait que le CE communique au FE les règles qu'il avait apprises en OSPF et testait la mise en œuvre correcte de plusieurs fonctions du RFC 6956. Une variante de ce test remplaçait le routeur classique par une autre machine ForCES : les deux CE se parlaient en OSPF et chacun disait ensuite à son FE ce qu'il devait faire des paquets IP.
La section 4 donne les résultats complets des tests. Il y a une très grande majorité de succès mais aussi deux échecs, qui vont nécessiter du travail chez les programmeurs.
Mais le principal problème de l'atelier a été un problème lors de la communication de tableaux (et pas de simples valeurs scalaires) entre deux programmes. Le problème est que ForCES permet plusieurs encodages possibles pour les données complexes (RFC 5810, section 6 et notamment 6.4). La règle est que chaque élément ForCES peut choisir librement parmi ces encodages (pas moins de trois possibilités légales, dans l'exemple discuté dans la section 5 de notre RFC). Mais un programme considérait que la réponse venait forcément dans l'encodage de la question, et plantait si ce n'était pas le cas. Bien qu'il soit clairement en tort, notre RFC considère qu'il vaut mieux en effet générer une réponse en utilisant le même encodage que la question ou la commande. Personnellement, je pense plutôt que c'était très gentil de donner un vaste choix aux CE et FE (par exemple pour optimiser le cas de grands tableaux ayant beaucoup de vide) mais que cela mène forcément à ce genre de problèmes. Traditionnellement, les protocoles IETF préfèrent l'interopérabilité à la liberté et ForCES était peut-être allé trop loin dans les possibilités de choix.
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : Y. Sheffer (Porticor), A. Farrel (Juniper)
Expérimental
Première rédaction de cet article le 18 juillet 2013
L'IETF se vante souvent de ne pas croire au blabla des marketeux, mais uniquement au code qui tourne. Comme le dit fièrement sa devise, « We believe in rough consensus and running code ». Mais, en pratique, les normes produites et publiées en RFC ne contiennent pas toujours la mention d'une mise en œuvre effective de cette norme. Parfois, c'est parce qu'il n'y en a pas (contrairement à une légende tenace, ce n'est nullement une obligation pour la publication d'un RFC). Parfois, c'est parce qu'elle n'est pas mentionnée. Avant la publication d'un RFC, lorsque le document est encore un simple Internet-Draft, la mention de l'existence de programmes mettant en œuvre le protocole ou le format décrit est complètement facultative. Ce nouveau RFC propose de formaliser et d'encourager cette mention. Il a depuis été remplacé par le RFC 7942.
Cela ne concerne que les Internet-Drafts, pas les RFC. En effet, les RFC sont stables (jamais modifiés) alors que les URL pointant vers un programme ne le sont pas : un programme peut être abandonné, plus maintenu, on peut se retrouver avec des 404, etc. Donc, un RFC n'est pas le bon endroit pour stocker un catalogue de mises en œuvre d'un protocole. L'expérimentation décrite dans ce nouveau RFC 6982 ne vise que les Internet-Drafts, afin d'aider à l'évaluation d'une proposition.
Le concept de running code est décrit dans le Tao (cf. RFC 4677 et RFC 6722). Il synthétise l'approche pragmatique de l'IETF : une norme qui n'est pas mise en œuvre ne sert à rien. Malgré cela, bien des RFC n'ont jamais connu la moindre mise en œuvre. En effet, ce principe général du running code n'a jamais été traduit dans une exigence formalisée et globale pour les auteurs de RFC. Il existe par contre des règles locales. Ainsi, la Routing Area de l'IETF (les groupes de travail qui normalisent les protocoles de routage) a longtemps demandé (RFC 1264) au moins une mise en œuvre avant la publication d'un RFC sur le chemin des normes. Le RFC 4794 a supprimé cette règle, qui reste appliquée par certains groupes de la Routing Area comme IDR.
Notre tout nouveau RFC 6982 est purement expérimental : il ne propose pas de définir une nouvelle règle, juste de formaliser une section dans les Internet-Drafts, facultative, qui permettra de documenter les mises en œuvre connues. L'idée est que les Internet-Drafts ayant cette section seront examinés avec plus de bienveillance, sans toutefois qu'elle soit obligatoire.
La section 4 du RFC fait la liste de tous les avantages qu'il y a à indiquer ces mises en œuvre dans l'Internet-Draft : meilleure information pour la prise de décision (aussi bien sur la publication de l'Internet-Draft que sur le statut du futur RFC), encouragement aux tests d'interopérabilité, possibilité (lorsque le code est publié) de mieux comprendre le protocole (beaucoup de programmeurs préfèrent lire le source plutôt que le RFC), et enfin assurance que telle fonction du RFC peut effectivement être mise en œuvre. C'est en effet souvent le cas (par exemple lors de la discussion qui a mené au RFC 5155) que certaines personnes affirment que la technologie envisagée est tout simplement trop complexe pour être programmée. L'existence d'un programme qu'on peut tester permet de d'assurer que, si, la technologie est réaliste (bien d'autres SDO produisent sans hésiter des technologies impossible à programmer dans des conditions raisonnables).
Cette nouvelle section, « Implementation status » est décrite en section 2 de ce RFC. Elle sera située vers la fin (comme l'actuelle - et obligatoire, elle - « Security considerations ») et pourra comporter les points suivants :
Cette section peut aussi indiquer l'expérience tirée de cette mise en œuvre, ainsi que des informations sur l'interopérabilité, au cas où plusieurs mises en œuvre existent. Les présidents des groupes de travail sont explicitement chargés de vérifier que cette section ne dégénère pas en simple marketing pour le produit d'un vendeur. Notre RFC propose aussi un texte standard d'avertissement à inclure au debut de cette section « Implementation status ».
D'autres endroits que l'Internet-Draft lui-même auraient pu être utilisés pour informer sur les mises en œuvre existantes. Le RFC suggère (section 3) de passer au wiki de l'IETF lorsque la liste des programmes devient trop longue, lorsqu'il semble préférable que cette liste soit maintenue par les implémenteurs plutôt que par les auteurs de l'Internet-Draft, lorsque le groupe de travail maintient activement un wiki, ou enfin lorsque la liste en question semble utile, même après la publication en RFC (pour indiquer le niveau d'adoption par les programeurs). Dans tous ces cas, il est bon d'indiquer l'URL du Wiki en question dans l'Internet-Draft.
Le RFC se donnait 18 mois pour l'évaluation de l'expérience, ce qui est la durée typique de production d'un RFC). Cette expérimentation est alors devenue la politique officielle de l'IETF (RFC 7942). On a évalué si cette section a été utilisée (par exemple pour trouver du code qu'on va ensuite tester) et si les décisions prises ont effectivement été meilleures. Curieusement, alors que cette nouvelle section n'est nullement obligatoire, ce RFC 6982 ne propose pas parmi les critères de succès de voir tout simplement combien d'auteurs d'Internet-Drafts ont inclus une telle section. Il faut dire qu'un certain nombre le font déjà de façon informelle.
Quelques exemples d'Internet-Drafts qui incluent
actuellement cette section : draft-clausen-lln-loadng
, draft-wilde-xml-patch
ou draft-ietf-mpls-multipath-use
.
Date de publication du RFC : Août 2013
Auteur(s) du RFC : F. Gont (SI6 Networks / UTN-FRH)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 26 août 2013
Ce court RFC traite un problème de sécurité lorsqu'on combine la fragmentation avec le protocole NDP d'IPv6. Il interdit désormais cette combinaison, qui pouvait être exploitée pour des attaques sur le réseau local.
NDP est normalisé dans le RFC 4861 (que ce RFC 6980 met à jour). Ce protocole est utilisé pour bien des choses, notamment pour résoudre une adresse IPv6 en adresse MAC et pour découvrir les routeurs du réseau local, ainsi que les préfixes des adresses IP de ce réseau (pour l'auto-configuration). Ses faiblesses de sécurité (très proches de celles d'ARP en IPv4) sont bien connues (RFC 3756). Notamment, n'importe quelle machine peut émettre des paquets NDP et répondre aux questions adressées à une autre machine. Ou bien l'attaquant peut se faire passer pour le routeur et émettre des « RAcailles », ces faux paquets RA (Router Advertisment).
Il existe plusieurs moyens de gérer ces dangers. On peut mettre des ACL statiques dans les commutateurs, n'autorisant les RA que sur le port où se trouve le routeur. Ou bien on peut utiliser la solution un peu plus sophistiquée du RA guard (RFC 6105). On peut aussi surveiller le trafic, avec un IPS ou bien un logiciel comme NDPmon ou ramond, et lever une alarme lorsque quelque chose d'anormal se produit. Mais toutes ces techniques ont un défaut commun : elles reposent sur une analyse du paquet pour détecter si c'était du NDP et il est trop facile de les tromper en fragmentant le paquet. S'il est en deux parties, avec les informations permettant de reconnaître et d'analyser le NDP dans le deuxième paquet, aucun des systèmes existants ne voit ce qui se passe, alors que la machine terminale réassemblera le paquet et se fera donc avoir. À l'heure actuelle, la totalité des mises en œuvre de RA guard est ainsi vulnérable (cf. RFC 7113). Bien sûr, des outils comme les IPS pourraient réassembler les paquets eux-aussi, pour voir le paquet original, mais c'est plus difficile pour les commutateurs Ethernet. Et cela leur fait courir un risque (si l'attaquant génère des quantités de fragments afin d'épuiser la mémoire des réassembleurs, pour faire une attaque par déni de service).
C'est d'autant plus balot que les vrais paquets NDP sont rarement assez grands pour avoir réellement besoin de la fragmentation (section 2). Même si un routeur a besoin d'annoncer de nombreux préfixes dans ses RA, il peut le faire en plusieurs datagrammes IP, il n'est pas nécessaire de tout mettre dans un seul grand datagramme fragmenté. Bref, la fragmentation est quasi-inutile pour NDP alors qu'elle est dangereuse. (Une exception partielle est décrite en section 3, pour SEND, dans le RFC 3971, dans le cas où il y a des gros certificats à transmettre. Je ne la mentionne pas davantage puisque SEND n'est quasiment jamais utilisé. Il résout radicalement presque tous les problèmes de sécurité de NDP mais le manque de mises en œuvre de ce protocole, et la difficulté qu'il y a à distribuer les clés cryptographiques nécessaires font qu'en pratique, SEND n'est pas une approche envisageable. Voir la conférence de l'auteur à DEEPSEC.)
La section 4 résume les raisons d'abandonner la fragmentation pour NDP :
Donc, la section 5 du RFC expose la nouvelle règle, qui met à jour le RFC 4861 : une machine qui émet des paquets NDP ne doit pas fragmenter ces paquets. (Une exception partielle est faite pour les messages Certification Path Advertisement utilisés par SEND. Mais, pour tous les messages habituels, la règle est l'interdiction de la fragmentation.) À la réception, les paquets NDP fragmentés doivent être ignorés.
Si vous voulez créer vous-même de tels paquets NDP fragmentés (qui
seront ignorés par les systèmes modernes, vous pouvez utiliser la
boîte à outils SI6 présenté dans mon article
sur le hacking IPv6, avec l'option -y
. Par exemple :
# ./ra6 -y 8 -i eth1 -d 2001:db8:8bd9:8bb0:ba27:ebff:feba:9094
va générer deux fragments, huit octets n'étant pas assez pour mettre le RA. tcpdump les voit ainsi :
08:34:29.122863 IP6 fe80::8609:88f4:14:a635 > 2001:db8:8bd9:8bb0:ba27:ebff:feba:9094: frag (0|8) ICMP6, router advertisement, length 8 08:34:29.122883 IP6 fe80::8609:88f4:14:a635 > 2001:db8:8bd9:8bb0:ba27:ebff:feba:9094: frag (8|8)
Notez que tcpdump ne s'est pas laissé avoir : il a bien identifié le premier fragment comme appartenant à un RA.
Date de publication du RFC : Août 2013
Auteur(s) du RFC : T. Pornin
Pour information
Première rédaction de cet article le 24 août 2013
Les algorithmes de signature DSA et ECDSA ont une particularité qui est souvent oubliée : chaque signature doit utiliser un nombre imprévisible. On peut, par exemple, générer ce nombre par un processus aléatoire. Mais tous les systèmes qui voudraient utiliser DSA ou ECDSA n'ont pas forcément un tel générateur aléatoire. Ce RFC propose une autre méthode : fabriquer ce nombre par dérivation déterministe d'un certain nombre de paramètres, produisant le même effet, sans pour autant nécessiter de source d'aléa.
Ces deux algorithmes sont très utilisés dans le monde. (À noter qu'ECDSA repose sur les courbes elliptiques, décrites dans le RFC 6090.) Mais cette nécessité de générer un nombre unique et imprévisible par signature n'a pas d'équivalent avec des algorithmes comme RSA. Le pourquoi de cette nécessité est bien expliqué dans un article de Nate Lawson. Si vous l'oubliez, vous serez piraté, comme Sony l'a été. Mais que ce nombre soit aléatoire n'est pas strictement nécessaire. En fait, l'aléatoire a deux défauts :
L'algorithme permettant de générer un nombre unique et imprévisible, mais sans générateur aléatoire, est décrit dans les sections 2 et 3 de notre RFC (il est fondé sur l'idée de derandomization, décrite dans « How Risky is the Random-Oracle Model? »). Je ne vais pas résumer cet algorithme ici (la cryptographie, c'est trop fort pour moi) mais ses propriétés importantes sont :
L'annexe A contient un exemple détaillé de calcul du nombre unique pour une signature.
Si vous envisagez de programmer cet algorithme de génération déterministe de signature, faites bien attention à la section 4, qui résume les problèmes de sécurité. Par exemple, comme rappelé plus haut, la procédure de ce RFC ne s'applique pas aux clés qui doivent, comme avant, être générées aléatoirement. Pour des engins sans générateur aléatoire, comme les carte à puce de bas et de milieu de gamme, cela peut par exemple être fait à l'usine, pendant la fabrication de l'engin.
D'autre part, comme la génération de la signature est déterministe, le même messsage aura donc toujours la même signature (tant qu'on garde la même clé privée, bien sûr). Cela n'est pas un problème dans certaines applications (RSA, tel que décrit dans le RFC 3447, fait pareil). Ainsi, TLS (RFC 5246), SSH (RFC 4251) ou CMS (RFC 5652) peuvent utiliser cet algorithme déterministe sans risque pour leur sécurité.
À noter que, de manière surprenante pour un RFC, la section 5 est consacrée aux risque de brevets sur cet algorithme (apparemment assez faibles). C'est surprenant car, comme la situation change tout le temps (nouveaux brevets, brevets reconnus comme futiles, etc), cette information est normalement distribuée en ligne et pas mise dans un RFC stable (c'est expliqué dans le RFC 8179). Les brevets actuellement connus pour ce RFC sont sur le site Web de l'IETF.
L'annexe B contient une mise en œuvre, en
Java, de cet algorithme (copiée ici dans le
fichier DeterministicDSA.java
). On peut l'utiliser, par
exemple, ainsi :
import java.math.BigInteger; import org.ietf.DeterministicDSA; public class TestDeterministicDSA { // http://stackoverflow.com/questions/5470219/java-get-md5-string-from-message-digest private static String binary2string(byte []bin) { StringBuilder binString = new StringBuilder(); for (int i = 0; i < bin.length; i++) { String hex = Integer.toHexString(bin[i]); if (hex.length() == 1) { binString.append('0'); binString.append(hex.charAt(hex.length() - 1)); } else binString.append(hex.substring(hex.length() - 2)); } return binString.toString(); } public static void main (String args[]) { int i; DeterministicDSA dsa = new DeterministicDSA("SHA-256"); String signature; // We use the private key for the appendix A.2.1 of the RFC BigInteger p = new BigInteger("86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED8873ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779", 16); BigInteger q = new BigInteger("996F967F6C8E388D9E28D01E205FBA957A5698B1", 16); BigInteger g = new BigInteger("07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA417BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD", 16); BigInteger x = new BigInteger("411602CB19A6CCC34494D79D98EF1E7ED5AF25F7", 16); dsa.setPrivateKey(p, q, g, x); for (i=0; i<args.length; i++) { dsa.update(args[i].getBytes()); signature = binary2string(dsa.sign()); System.out.println(args[i] + " -> " + signature); dsa.reset(); } } }
Et on retrouve les valeurs indiquées dans le RFC (ce qui est logique pour un processus déterministe...) :
% java TestDeterministicDSA sample test sample -> 302d02150081f2f5850be5bc123c43f71a3033e9384611c54502144cdd914b65eb6c66a8aaad27299bee6b035f5e89 test -> 302c021422518c127299b0f6fdc9872b282b9e70d079081202146837ec18f150d55de95b5e29be7af5d01e4fe160
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : J. Touch (USC/ISI)
Expérimental
Première rédaction de cet article le 20 juillet 2013
Le protocole d'authentification des paquets TCP AO (Authentication Option), normalisé dans le RFC 5925, a une limite : il ne fonctionne pas du tout lorsque la session est établie à travers au moins un routeur NAT. Ce nouveau RFC propose une extension qui lui permet d'authentifier quand même les paquets dans ce cas, au prix d'une légère baisse de la sécurité.
En effet, l'authentification AO range et génère ses clés en tenant compte d'un ensemble de paramètres de la session (RFC 5925, sections 3.1 et 3.2), parmi lesquels se trouvent les adresses IP de source et de destination, ainsi que les ports de source et de destination. Un routeur NAT modifie en général l'adresse IP source et les routeurs existants (qui font souvent du NAPT et pas du NAT à proprement parler, cf. RFC 2663) modifie également le port source. AO ne retrouve donc plus ses clés (RFC 5925, section 9.2). Ce n'était pas un gros problème pour le premier client d'AO, le protocole BGP : on met rarement des routeurs BGP derrière du NAT. Mais cette limite est gênante pour généraliser AO à d'autres utilisations, sans compter les futures améliorations de TCP, par exemple le multipath du RFC 6824, où la même connexion TCP utilise plusieurs adresses IP.
Donc, la nouvelle option se nomme TCP-AO-NAT et consiste (section 4
de notre RFC) à ajouter au MKT (Master Key Tuple,
cf. RFC 5925, section 3.1) deux booléens,
localNAT
et remoteNAT
indiquant si un routeur NAT est présent en local ou en distant. Si
localNAT
est vrai, AO va mettre à zéro l'adresse
IP source et le port source avant de calculer les clés. Si c'est
remoteNAT
qui est vrai, ce sera l'adresse et le
port de
destination qu'on ignorera.
Le MKT n'est pas transmis à la machine distante (et n'apparait
donc pas dans l'option TCP AO), il est typiquement configuré à la main
des deux côtés. La valeur à donner à localNAT
et
remoteNAT
est déterminée manuellement, mais elle
peut aussi être découverte par les méthodes habituelles de détection
de NAT. Le client situé immédiatement derrière un routeur NAT (par
exemple la machine de M. Michu à la maison) va mettre
localNAT
à 1. Le serveur en face va mettre
remoteNAT
à 1. Si les deux partenaires sont
derrière un NAT (et utilisent une technique comme celle du RFC 8489), les deux booléens peuvent être à 1.
Notez bien qu'AO ne protège que TCP et ne tient pas compte du contenu des paquets. Si un ALG sur le trajet modifie les adresses contenues, mettons, dans une connexion FTP, TCP-AO-NAT n'y pourra rien.
Attention, rappele la section 6 : TCP-AO-NAT revient à ignorer
certaines valeurs qui identifient la connexion et donc à diminuer
l'entropie. Si localNAT
est vrai, on passe d'une
source de hasard pour la KDF qui est composée de deux adresses IP, deux ports et
deux ISN (l'Initial Sequence Number de TCP) à une seule adresse, un seul port et les deux ISN. Si les deux booléens localNAT
et
remoteNAT
sont vrais, il ne reste plus que les
deux ISN comme source d'entropie. Bref, l'extension normalisée dans ce
RFC diminue la sécurité. Toutefois, comme les
ports ne sont pas toujours très aléatoires (malgré le RFC 6056) et les adresses encore moins, l'essentiel de
l'entropie venait des deux ISN, de toute façon.
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : S. Crocker (Shinkuro Inc.), S. Rose (NIST)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 4 juillet 2013
Le système d'authentification du DNS DNSSEC repose sur la signature cryptographique des enregistrements DNS. Cette signature peut se faire par des algorithmes différents. Comment savoir si tel algorithme, récemment spécifié, est désormais d'un usage fréquent ou pas chez les résolveurs validants ? Ce nouveau RFC propose que le résolveur indique, dans sa requête DNS, la liste des algorithmes qu'il comprend. Cela permettra, dans le futur, de mesurer objectivement l'état du déploiement de tel ou tel algorithme.
L'algorithme utilisé dans une signature DNSSEC apparait dans
l'enregistrement RRSIG
sous forme d'un octet dont
la signification est stockée dans un registre
IANA. Ainsi, dans cette signature de
.fr
:
% dig +dnssec SOA fr. ... ;; ANSWER SECTION: fr. 172800 IN SOA nsmaster.nic.fr. hostmaster.nic.fr. 2222283656 3600 1800 3600000 5400 fr. 172800 IN RRSIG SOA 8 1 172800 20130814151003 20130615141003 62646 fr. FSSGO0iZ6OBoSUE12Q/NYOU2f3AMNbOf/b4FoC48F8f5gDfSNpJStZF7 zGsN51+zFE3FCucNDw4cQMY8YqBeu6BN5IG4StqAjEp+3FqLYSzyUu4s tZY8GnLa9ZzJCTf6dGT0CE2JbEzc705hc6X6I7DDxqwrzzpj23F/Rg9 PEk= ...
La signature est faite avec l'algorithme 8,
RSA + SHA-256. Dans le cas de
ecdsa.isc.org
:
% dig +dnssec SOA ecdsa.isc.org ... ;; ANSWER SECTION: ecdsa.isc.org. 3600 IN SOA ns-int.isc.org. hostmaster.isc.org. 2013052903 7200 3600 604800 3600 ecdsa.isc.org. 3600 IN RRSIG SOA 14 3 3600 20130712033157 20130612023157 30631 ecdsa.isc.org. o+Q1WDDeiCM3z2b793Ni/FtMT223gJ/1Lr+RWOgPJLVxB+AlLKyKvLOs vWRBqUjwYeKE4Dx/ZUSIx8eVzOUt5g6HvBuGaYX/camsYn9ocuTp6J+w J2Fn69Qi6/WbhAa4 ...
Elle est fait avec 14, ECDSA avec SHA-384. On trouve également des numéros identifiant un algorithme, celui de condensation cryptographique, dans les enregistrements DS et un autre dans NSEC3 (les valeurs possibles étant dans un autre registre IANA).
Actuellement, les serveurs faisant autorité pour une zone ne savent
pas quels algorithmes sont compris par les résolveurs qui les
interrogent. Le serveur qui fait autorité envoie toutes les signatures
qu'il connait et le résolveur se débrouille. Reprenons le cas de
.fr
, signé avec
RSA. Pourrait-on passer à
ECDSA, normalisé dans le RFC 6605, et qui a l'avantage de fournir des clés et des
signatures plus courtes ? Le problème est qu'ECDSA dans DNSSEC est
très récent et qu'on pense que peu de résolveurs sont capables de
valider avec ECDSA. Mais quel pourcentage exactement ? Et, avec le
temps, ce pourcentage augmentera. Comment saura-t-on qu'on est arrivé
au point où la grande majorité des résolveurs parlent ECDSA ? Si ce
nouveau RFC 6975 est déployé, il fournira un moyen de
répondre à ces questions.
Le principe est d'utiliser trois nouvelles options
EDNS pour signaler les algorithmes connus. Le
résolveur mettra ces options dans la requête et le serveur faisant
autorité pourra les examiner pour connaître les capacités de ses
clients (notez bien que c'est uniquement à des fins d'information : le
serveur ne doit pas modifier sa réponse en
fonction de ces options). EDNS est normalisé dans le RFC 6891 et l'enregistrement OPT
qu'il
ajoute contient zéro, une ou plusieurs options (la liste des options
possibles est dans un registre IANA). Les
trois options ajoutées sont (section 2 de notre RFC) :
L'encodage d'une option EDNS se fait en trois champs, le code sur deux octets (5, 6 ou 7 ici), la longueur des données sur deux octets et les données. Ici, les données consistent en une liste d'algorithmes, un octet pour chacun, dans un ordre quelconque (l'ordre n'exprime pas une préférence). Par exemple, un résolveur validant qui accepte RSA-SHA1, RSA-SHA256 et ECDSA-SHA384 encodera un DAU avec les octets {5, 0, 3, 5, 8, 14}. En pratique, le RFC estime que les trois options toutes ensemble devraient prendre de 22 à 32 octets (en comptant 6 à 10 algorithmes de signature, plus quelques uns pour la condensation).
Bon, et une fois le format défini, on s'en sert comment ? Pour les clients (les résolveurs), c'est en sections 3 et 4 du RFC. Si le client valide, il ajoute une, deux ou trois des nouvelles options dans sa requête. Sinon, il ne doit pas les utiliser.
Si le résolveur valide et qu'il reçoit une requête ayant déjà une de ces options, il doit ajouter ses propres algorithmes. La liste finale sera donc l'union des deux. Un simple relais (forwarder) qui ne valide pas mais qui reçoit une requête ayant une de ces options, doit passer l'option telle quelle car ce qui compte, ce sont les capacités du résolveur qui fera la validation DNSSEC.
Et le serveur faisant autorité ? C'est en section 5. Le point important est qu'il ne doit rien faire. Il suit le même algorithme que d'habitude et, par exemple, il envoie les mêmes signatures quels que soient les algorithmes compris par l'émetteur. Les trois nouvelles options sont là pour information uniquement. D'autres part, les trois options DAU, DHU et N3U sont uniquement dans les requêtes. Le serveur faisant autorité n'en met pas dans les réponses.
Revenons aux administrateurs d'une zone qui voudraient mesurer le déploiement d'un nouvel algorithme cryptographique. Que faire si les clients n'envoient pas cette option ? La section 6 conseille de les considérer comme du vieux logiciel, n'ayant pas les nouvelles options, ni les nouveaux algorithmes. C'est un peu court, à mon avis, car on peut aussi imaginer qu'il y aura des résolveurs récents qui n'enverront pas cette option, peut-être par souci de discrétion (ce point est également couvert dans la section 7, consacrée aux risques de sécurité).
Il ne semble pas exister beaucoup de mises en œuvre de ce RFC. Par exemple, Wireshark, au moment de la publication du RFC, ne savait pas décoder ces options et affichait juste :
Additional records <Root>: type OPT Name: <Root> Type: OPT (EDNS0 option) UDP payload size: 1200 Higher bits in extended RCODE: 0x0 EDNS0 version: 0 Z: 0x0 Data length: 8 Data
Depuis r50840, Wireshark a le code nécessaire et on n'a plus qu'à patienter que cela arrive dans une version officielle.
L'examen des requêtes envoyées à un gros serveur de noms ne montrait, au moment de la sortie du RFC, pratiquement pas d'utilisation de cette option.
Trois ans après la publication du RFC, une discussion lors d'une réunion OARC semblait indiquer qu'il n'avait connu aucun déploiement et devait être considéré comme un échec. Mais en juin 2020, OpenDNS l'a activé sur ses serveurs.
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : A. Cooper (CDT), H. Tschofenig (Nokia
Siemens Networks), B. Aboba (Microsoft
Corporation), J. Peterson
(NeuStar), J. Morris, M. Hansen (ULD
Kiel), R. Smith (Janet)
Pour information
Première rédaction de cet article le 25 juillet 2013
La question de la vie privée est désormais une question de première importance sur l'Internet. La sortie de ce RFC en plein scandale PRISM est une coïncidence mais elle tombe bien. Pendant longtemps, la vie privée avait pourtant été plutôt négligée par les ingénieurs et cette négligence se retrouvait dans les normes techniques, par exemple les RFC, qui ne contenaient pas grand'chose sur la question. Désormais, l'importance du problème est reconnue à l'IETF et ce nouveau RFC vise à expliquer à tous les auteurs de RFC ce qu'il faut connaître de la vie privée et de sa protection, lorsqu'on conçoit un protocole réseau.
Ce n'est donc pas un texte général sur la vie privée (il en existe déjà beaucoup) même s'il explique les principes de base (le membre typique de l'IETF peut être très ignorant à ce sujet). Son objectif est de faire en sorte que les protocoles de la famille TCP/IP prennent en compte les problèmes de vie privée dès leur conception. Cela a été un long chemin. Peu de RFC traitaient explicitement cet aspect (une exception intéressante est le RFC 8981). Mais, petit à petit, entre autre grâce au travail d'Alissa Cooper, une des auteures de ce document, l'IETF est passé de « bof, c'est de la politique, ça ne nous concerne pas, et d'ailleurs la technique est neutre » à un atelier sur la protection de la vie privée (le compte-rendu figure dans le RFC 6462) puis à ce RFC 6973 qui dit en substance que tout nouveau protocole de la famille TCP/IP devrait avoir, lors de sa conception, une réflexion sur les risques qu'il pose pour la vie privée et les moyens de les limiter. S'il reste encore à l'IETF quelques partisans du « on s'en fiche, que toutes les données soient accessibles et que tout le monde soit à poil », ils se font nettement moins entendre désormais. Sans aller jusqu'à imposer une section Privacy considerations dans chaque RFC (sur le modèle de l'obligatoire section Security considerations, cf. RFC 3552), ce RFC l'encourage et aide à sa rédaction.
Le problème n'est pas trivial : la vie privée est quelque chose de complexe. Et tout le monde n'a pas la même opinion sur l'importance de son respect. Sans compter que le cadre légal est très différent d'un pays à l'autre, alors que les RFC sont censés avoir une portée mondiale. Si certains RFC ne semblent pas poser de problème de vie privée (notre RFC cite le RFC 6716...) d'autres sont ou seront entièrement consacrés à ce sujet (RFC 3325) et d'autres nécessiteront un paragraphe ou une section dédiée.
La section 2 détaille les responsabilités des concepteurs de protocoles Internet. Ces protocoles sont souvent utilisés dans une grande variété de cas, parfois non prévus lors de leur conception originelle. Bref, on ne peut pas demander au rédacteur du RFC sur un nouveau protocole de prévoir tous les usages et il y a donc des limites à l'analyse qu'il peut faire sur les conséquences de « son » protocole sur la vie privée. D'autre part, une grande partie, peut-être la majorité des problèmes de vie privée, prennent naissance dans un comportement de l'utilisateur, mal ou peu guidé par des mauvaises interfaces utilisateur. La conception de ces interfaces est typiquement hors-sujet pour l'IETF, qui ne se préoccupe que de protocoles.
Un bon exemple est fourni par HTTP (RFC 7230). Quand on voit la variété des usages de HTTP aujourd'hui, de l'accès à des pages Web statiques à l'échange de données médicales, on se dit qu'une analyse des risques qu'il pose pour la vie privée, faite à l'époque de son développement, aurait été bien limitée.
Le RFC commence vraiment avec la section 3, sur la terminologie. Section bien nécessaire pour ce sujet, où le vocabulaire utilisé est souvent trop flou. Un RFC précédent sur la terminologie de la sécurité avait été le RFC 4949 mais il parlait peu de vie privée. Donc, quelques termes nouveaux (d'autres sont dans le RFC) :
canari95
). Notez aussi que l'anonymat n'est pas
uniquement le fait de garder son nom officiel secret. Cela peut être
aussi de vouloir empêcher le rapprochement de deux de ses identités.Par exemple, avec IP, le routeur est un intermédiaire, et peut être un observateur (s'il est équipé pour cela, disons que si le routeur est une machine Unix, il devient un observateur dès qu'il lance tcpdump). Quelqu'un qui s'est branché sur le câble sans autorisation est un écoutant.
À noter que l'analyse de sécurité du RFC 3552 supposait que les deux extrémités de la communication étaient sûres et que seuls les intermédiaires représentaient un danger. En matière de vie privée, ce n'est évidemment pas le cas (section 4 de notre RFC). Comme l'a montré l'affaire PRISM, ou comme le montrent les pratiques des gros silos commerciaux du Web 2.0 comme Facebook, le danger est souvent chez l'une des parties en train de communiquer, pas chez un tiers...
Et quelles sont exactement les menaces qui pèsent sur la vie privée ? La section 5 les détaille, suivant en partie le livre de Solove et la recommandation du Conseil de l'Europe. D'abord, leurs conséquences. Les atteintes à la vie privée peuvent provoquer de la gêne mais aussi une perte de dignité, ou des pertes financières. Dans des cas extrêmes (violence conjugale, par exemple), ces atteintes peuvent mettre la vie des victimes en danger. D'autre part, même s'il n'y a pas eu accès à des informations privées, le seul fait d'être sous surveillance peut mettre très mal à l'aise, voir créer un sentiment d'angoisse. Il peut aussi entraîner un changement de comportement (on hésitera à commettre un acte légal, de peur des conséquences s'il était révélé) pouvant aller jusqu'à l'auto-censure. La vie privée est donc une affaire sérieuse, pas un simple détail.
Première attaque contre la vie privée envisagée, la surveillance des communications. Le RFC rappelle qu'elle n'est pas limitée au cas où l'attaquant a accès au contenu des communications. La seule analyse de trafic peut déjà en révéler beaucoup. Le chiffrement n'est pas une protection parfaite : le type de trafic reste visible, via des indicateurs comme la taille des paquets ou leur fréquence. Pour déjouer sérieusement la surveillance, il faudrait des protocoles avec des tailles de paquets variables, n'ayant pas de chaîne de bits prévisibles à un endroit fixe dans le paquet, etc. Pour sérieusement gêner l'analyse de trafic, il faut des systèmes comme Tor. Parmi les entitées présentées plus haut, aussi bien les écoutants que les observateurs peuvent avoir une activité de surveillance.
Une fois les messages arrivés à bon port, tout n'est pas terminé. Les données stockées à destination peuvent faire l'objet d'une compromission, si le serveur qui les stocke n'est pas suffisamment protégé et peut être piraté. Sans compter le cas, traité plus loin, où le serveur de destination est lui-même un attaquant. Ceci dit, ces problèmes ne sont pas du ressort de l'IETF qui s'occupe normalement uniquement des réseaux.
Les risques ci-dessus sont une combinaison de risques pour la vie privée avec les risques plus généraux de sécurité. Mais il y a aussi des risques très spécifiques à la question de la vie privée. Par exemple, la corrélation, qui permet d'acquérir des informations normalement privées en reliant des données qui, séparément, semblaient inoffensives. Par exemple, si des identificateurs stables sont utilisés, les protocoles réseaux facilitent la corrélation. Une adresse IP stable sur le long terme présente un certain nombre d'avantages techniques mais est aussi un danger pour la vie privée (cf. RFC 8981). Autre exemple, le protocole TLS permet de reprendre une session cryptographique existante, pour gagner du temps et éviter de recommencer la négociation de tous les paramètres (cela peut se faire côté serveur, RFC 5246 ou côté client, RFC 5077). Mais comme cette reprise de session se fait avant la négociation de ces paramètres de cryptographie, elle a lieu en clair. Un écoutant peut donc voir que le second client TLS qu'il écoute est en fait le même que le premier, s'il utilise cette fonction.
Autre attaque contre la vie privée, celle passant par
l'identification. Savoir que la machine
192.0.2.67
accède au site Web du gouvernement,
c'est une chose. Pouvoir accéder à des informations sur la personne
qui utilise cette machine, c'est bien mieux, pour l'attaquant. Cela
peut se faire facilement avec les protocoles qui identifient une
personne (une adresse SIP ou
XMPP par exemple) mais aussi de manière
indirecte même si le protocole permet l'anonymat. Prenons par exemple un site Web qui n'identifie pas ses
utilisateurs. Aucun risque qu'un attaquant qui l'observe retrouve qui
a accédé à la page /page-sensible.html
, non ?
Sauf que, si le même attaquant peut écouter le trafic d'un autre site
Web qui authentifie ses utilisateurs, il peut faire une corrélation
(via, par exemple, le champ User-Agent:
) et ainsi
identifier l'utilisateur.
Dans beaucoup de cas, l'utilisateur sait qu'on récolte des données personnelles sur lui. Si je me crée un compte sur amazon.com, il est clair qu'Amazon va savoir des choses sur moi, par exemple mon adresse postale pour me livrer les produits achetés. Il peut aussi y avoir des usages secondaires, des cas où le détenteur des données s'en sert pour autre chose que ce qu'il a annoncé. L'usage secondaire est techniquement indétectable et, comme cela se passe en dehors de la communication standardisée par l'IETF, notre RFC estime que ce problème, si grave qu'il soit en pratique, n'est pas de la responsabilité de l'IETF.
Encore plus sérieux, la révélation de données à des tiers. Comme il est trivial de copier des données numériques, il est techniquement impossible de savoir si les données personnelles qu'on a accepté de confier à l'entreprise X ne vont pas être copiées chez son partenaire Y. Là encore, c'est en dehors de la sphère IETF mais c'est quand même une des menaces les plus sérieuses. Le système PRISM est un exemple d'une telle copie, où les données qu'on avait accepté de confier à Google ou Facebook sont accessibles à la NSA. (Cet exemple n'est pas mentionné dans ce RFC qui, pour ne vexer personne et surtout pas les grosses entreprises états-uniennes qui contribuent beaucoup à l'IETF, passe rapidement sur ce risque, pourtant l'un des plus fréquents.)
Certains protocoles IETF permettent à l'utilisateur d'indiquer ses préférences en matière de protection de la vie privée, et notamment d'interdire la révélation de ces données à un tiers. C'est le cas par exemple du système décrit dans le RFC 6280. Évidemment, il n'existe aucun moyen technique de savoir si ces préférences sont respectées...
Notez aussi que la révélation peut être accidentelle : certains administrateurs systèmes sont assez négligents avec les données personnelles (ou bien ne se rendent pas compte qu'elles sont personnelles) et les laissent parfois accessibles par accident.
Dernière menace envisagée, l'exclusion. C'est le fait d'interdire à l'utilisateur de savoir ce qu'on sait sur lui. (La loi Informatique & Libertés appelle cela le droit d'accès aux données.) C'est une attaque tentante pour les gens qui veulent utiliser vos données personnelles. Cela limite le contrôle que l'individu peut faire.
Maintenant, assez déprimé sur les menaces, place aux solutions. La section 6 envisage les différentes méthodes connues pour limiter les dégâts. Améliorer la protection de la vie privée dans les protocoles réseau n'est pas facile car une protection sérieuse dépend de très nombreux facteurs, qui ne relèvent pas de la seule responsabilité des protocoles (ni même des logiciels). Je pense personnellement (et le RFC a tort de ne pas le rappeler) que le problème requiert avant tout des solutions politiques et juridiques. Mais ce RFC 6973 est un RFC, pas une loi, et se focalise donc surtout sur les aspects techniques : lorsqu'on est membre de l'IETF, que peut-on faire de concret aujourd'hui ?
Première chose évidemment, récolter moins de
données (data minimization ou No data, no
privacy problem). Les protocoles devraient être conçues de
façon à ne transmettre que les données strictement nécessaires à
l'accomplissemnt de la tâche. Les choix vont être délicats car les
informations envoyées, même pas strictement nécessaires, peuvent avoir
une utilité (le User-Agent:
en HTTP, énorme
risque pour la vie privée, mais si rigolo pour faire des
statistiques). Le RFC se focalise donc surtout sur un point,
l'identifiabilité. Il faut tout faire pour éviter qu'on identifie un
utilisateur. Cela peut passer par l'absence d'identificateurs dans le
protocole (ce que permet HTTP mais pas SMTP) ou par l'utilisation
d'identificateurs de durée de vie limitée, choisis aléatoirement et changés régulièrement (les
adresses IP temporaires du RFC 8981).
La meilleure protection de la vie privée est quand l'utilisateur
peut rester anonyme. Cela implique qu'il existe un ensemble d'anonymat
assez vaste pour qu'on soit réellement protégé. Un
User-Agent:
HTTP à lui seul vous place dans un
ensemble d'anonymat qui peut être très réduit (j'ai vu une fois dans
mes journaux un
User-Agent:
qui proclamait que le navigateur
tournait sur OpenBSD, ce qui diminue
considérablement le nombre de « suspects »). Par exemple, pour
SIP, le RFC 3325 permet
de choisir une adresse anonyme (notez que, comme souvent en matière
d'anonymat, l'information sur votre identité peut venir
d'ailleurs comme le champ Via:
).
Proche de la notion d'anonymat, celle de pseudonymat. Dans ce cas,
on a une identité stable et réutilisable, elle n'est simplement pas
liée aux identités qu'on veut protéger (comme son nom officiel, par
exemple). Dans l'exemple SIP ci-dessus, l'adresse utilisée est
toujours anonymous@anonymous.invalid
et est la
même pour tout le monde. C'est de l'anonymat. Si par contre je me crée
un compte aucbbf51n
chez un fournisseur SIP
example.net
qui ne
garde pas trace de mes informations personnelles, mon adresse
aucbbf51n@example.net
est un pseudonyme. Un
pseudonyme a l'avantage, par rapport à l'anonymat, de permettre de
construire une réputation.
Beaucoup d'identificateurs sur l'Internet vont être des pseudonymes
puisque les protocoles Internet n'obligent pas (et heureusement,
comparez avec ce que réclame l'UIT qui voudrait
obliger à utiliser des « vraies » identités) à se servir d'un nom
officiel. Ainsi, mon adresse de courrier pour ce blog est
stephane+blog@bortzmeyer.org
mais vous ne savez
pas si c'est mon nom officiel ou un pseudonyme. Parfois, tout de même,
des protocoles ou formats Internet transportent des identités qui
peuvent être des noms officiels. Un exemple typique est le format
vCard du RFC 6350.
Les pseudonymes ne sont pas parfaits, deux pseudonymes utilisés
dans des contextes différents peuvent parfois être reliés par exemple
via une information que vous communiquez. Si vous publiez sur
l'informatique avec une
adresse professionnelle
monsieursérieux@example.com
et que vous tenez un
blog sur la sexualité des hamsters avec l'adresse
lol-hamster218@example.net
, ne faites pas les mêmes
fautes d'orthographe, n'utilisez pas les mêmes tournures de phrase
dans les deux contextes ou bien vous serez démasqué. Un exemple de
pseudonymes impossibles à lier est fourni par Romain Gary et Émile Ajar : étant donné la
différence des styles, personne n'avait jamais suspecté que c'était le
même écrivain.
Un problème supplémentaire survient fréquemment de nos jours : beaucoup de services sur l'Internet ne font plus la gestion de l'identité eux-mêmes mais la délèguent à un fournisseur d'identité, utilisant des techniques comme OpenID ou des protocoles privés. Selon le protocole utilisé, les risques pour la vie privée peuvent être plus ou moins grands. Par exemple, si le service voulant authentifier (RP pour relying party, celui qui compte sur le fournisseur d'identité) communique directement avec le fournisseur d'identité (au lieu que tout passe via le client final), le fournisseur d'identité peut apprendre à quels services se connectent ses clients. Autre exemple, le fournisseur d'identité ne devrait pas envoyer au RP la totalité des informations dont il dispose sur un client.
Et, pour clore cette section 6 sur les solutions techniques améliorant la protection de la vie privée, le RFC note que le protocole doit fournir des mécanismes permettant à l'utilisateur de contrôler ses propres données (savoir ce que les autres savent sur lui, et pouvoir exprimer des préférences).
Plus pratique, la section 7 transforme ces bons conseils techniques en une liste de choses à vérifier lorsqu'on conçoit un nouveau protocole réseau. Une fois qu'on a développé un modèle du nouveau protocole (RFC 4101), lire cette liste et se poser les questions qu'elle contient devrait aider à limiter les risques pour la vie privée.
D'abord, minimiser la quantité de données distribuées. La meilleure
protection des données est quand il n'y a pas de données. Quels sont
les identificateurs utilisés par le protocole ? Est-ce qu'ils
permettent la corrélation entre des sessions différentes (c'est
souvent le cas s'ils sont stables sur le long terme) ? Ne pourrait-on
pas limiter leur utilisation ? Leur mettre une durée de vie limitée ?
Permettre aux utilisateurs d'en changer facilement ? Ensuite les données qui ne sont pas
officiellement des identificateurs ? Qu'est ce qui est échangé entre
les parties qui communiquent ? N'est-ce pas trop de données ? Ces
données ne permettraient-elles pas de retrouver les identificateurs
(pensez au Panopticlick) ? À qui sont envoyés ces identificateurs
et ces données (rappelez-vous qu'il y a typiquement plus que deux
parties impliquées dans une communication) ? Par exemple, lors d'une
connexion HTTP à http://www.example.com/
, la
requête DNS est envoyéee à des assistants (cf. le vocabulaire au
début), les serveurs de la racine et ceux de
.com
. La racine apprend donc qu'on se connecte à
www.example.com
. Et le risque d'empreinte
numérique ? Par exemple, si le protocole permet N opérations au début
d'une connexion, sans
spécifier leur ordre, un observateur peut apprendre quel logiciel vous
utilisez en regardant l'ordre choisi. Et enfin est-ce que le protocole
permet, voire impose, la conservation de données ou d'identificateurs
sur le long terme, en dehors des sessions de communication ?
Ça, c'était pour minimiser les données. Pour le contrôle par
l'utilisateur, les questions à se poser sont : quels sont les
mécanismes dans le protocole pour contrôler
quelles données on diffuse et à
qui ? Là encore, il ne faut pas penser qu'au
destinataire mais aussi à tous les intermédiaires possibles. Un
exemple, HTTP n'impose pas des en-têtes indiscrets comme
User-Agent:
et Referrer:
et
cela permet à certains navigateurs ou relais de les supprimer.
Les attaques contre la vie privée ne seront pas menées que par les participants légitimes à une communication. On aura aussi des tiers qui essaieront d'accéder à une information qu'ils ne sont pas censés avoir. Le protocole doit donc prendre en compte la possibilité de surveillance. Qu'est-ce qui est prévu contre l'écoute ? En général, c'est l'utilisation du chiffrement et le RFC contient donc une phrase « utilisez TLS si vous ne voulez pas être écouté ». Mais cela n'empêche pas l'analyse de trafic. Le protocole a-t-il des mécanismes qui facilitent ou au contraire compliquent cette analyse ? Par exemple, avec SSH, on voit facilement si on a affaire à un transfert de fichiers ou à une session interactive, par la quantité de données qui passe et leur cadencement. Lors d'un transfert de fichiers, on a beaucoup d'octets dans un sens et peu dans l'autre, les accusés de réception. Lors d'une connexion à un shell, on a peu d'octets de l'utilisateur vers le shell et une quantité moyenne (les réponses) en sens inverse. Le chiffrement ne dissimule pas cela. SSH a un mécanisme de remplissage de la communication avec des données bidon, pour brouiller les pistes mais je n'ai pas l'impression qu'OpenSSH l'utilise.
Toujours en sécurité classique, comment se comporte le protocole en cas de compromission des données stockées ? Ou contre une attaque active ?
Souvent, les préférences de protection de la vie privée sont réglables. Mais la plupart des utilisateurs ne modifieront jamais le réglage. Le RFC demande donc qu'on prête attention aux réglages par défaut. En l'absence d'intervention explicite, est-on protégé ou, au contraire, faut-il activer cette protection délibérement ? Par exemple, pour le cas des adresses IP temporaires, le RFC 4941 demandait qu'elles ne soient pas utilisées par défaut (sa mise à jour dans le RFC 8981 a changé les choses) alors que le RFC 6724 a demandé le contraire. Écrit quatre ans après, à un moment où les préoccupations de protection de la vie privée sont devenues plus importantes, ce RFC 6724 avait des priorités différentes.
D'ailleurs, la fin de cette section 7 rappelle que, comme Schneier aime le répéter, la sécurité est toujours un compromis. Elle prend du temps, ralentit le réseau, complique les choses (pour les programeurs et pour les utilisateurs), bref a un coût. La protection de la vie privée n'échappe pas à cette nécessité de chercher un compromis.
Pour clore ce RFC, la section 8 fournit un exemple complet d'analyse de sécurité d'un service donné. Les auteurs ont choisi la difficulté, car cette analyse porte sur un service particulièrement indiscret et intrusif, le service de présence (faire connaître à l'extérieur si on est disponible ou pas, par exemple pour être contacté par messagerie instantanée). Ce service permet d'illustrer toute la palette des questions soulevées par la protection de la vie privée. Présentée dans le RFC 2778, la présence (« je suis dispo », « je déjeune », « je suis en réunion ») est un service très dynamique, nécessitant de nombreuses mises à jour. Ses implications pour la vie privée sont évidentes et, dès le début, l'IETF avait prévu un contrôle des utilisateurs sur cette information (RFC 3859). Les protocoles qui utilisent un système de présence comme SIMPLE (RFC 6914) ou XMPP (RFC 3922) s'appuient sur ce contrôle.
Voici la gestion de la présence par l'utilisateur dans le client de messagerie instantanée Pidgin :
Dans l'architecture standard, il y a un tiers, un assistant, le serveur de présence, qui reçoit les informations des clients et les transmet aux lecteurs autorisés. Ce tiers est nécessaire pour les cas où la/les machine(s) du client soient toutes éteintes ou injoignables. Il sert également à agréger de l'information envoyée par les différentes machines de l'utilisateur (son ordinateur peut être éteint mais l'utilisateur être toujours joignable via son smartphone). Mais il complique évidemment beaucoup la sécurité puisqu'il va être au courant de beaucoup de choses. Bien sûr, le serveur ne distribue l'information qu'aux lecteurs autorisés. Mais il n'y a pas de protection technique : il faut faire une confiance totale au serveur, confiance en son honnêteté et ses bonnes pratiques de sécurité. On pirate un serveur de présence et on peut suivre les gens à la trace. Le serveur oublie de rendre TLS obligatoire et les écoutants peuvent tout apprendre (et le client du serveur de présence n'a aucun moyen de vérifier si TLS est activé ou pas). Encore pire, c'est le serveur de présence qui authentifie les lecteurs, pas le client final. L'anonymat n'est ici pas une solution puisque le but d'un service de présence est justement d'obtenir des informations sur des personnes identifiées (« quelqu'un est allé déjeuner » n'est pas une information intéressante).
Pour compléter le tableau, d'autres informations que la présence sont souvent transmises, par exemple les capacités du logiciel utilisé (accepte t-il les appels vidéo, par exemple). Elles peuvent permettre d'identifier l'appareil utilisé. En outre, les extensions ultérieures au service de présence ont permis de publier également la localisation physique. Un groupe de travail a été créé pour travailler sur la protection de la vie privée dans le cas où on distribue cette information, le groupe GEOPRIV, dont le premier RFC fut le RFC 4079 (mais il y en a d'autres).
Avec tellement d'information, l'analyse de sécurité du service de présence doit évidemment commencer par se demander si le jeu en vaut la chandelle. Déjà, on pourrait utiliser une autre architecture, plus pair à pair, où les utilisateurs se préviennent directement de leur présence. Il existe un format standard pour transporter cette information, PIDF (Presence Information Data Format), qu'on peut chiffrer pour empêcher toute écoute. Mais cette solution ne semble pas réaliste aux auteurs du RFC : elle ne fonctionne pas si la machine de publication est éteinte ou injoignable, chaque machine qui publie doit connaître les clés publiques de tous les abonnés, et enfin elle suscite un trafic important (la présence est très dynamique, avec des changements fréquents). Une variante est l'architecture où le serveur de présence ne sert que de redirecteur : il ne connait pas l'information, mais sait rediriger vers la machine actuelle de chaque personne qui publie de l'information de présence. Le serveur peut ainsi prévenir qu'une personne est injoignable et rediriger vers cette personne dans le cas contraire. Mais cette architecture, comme la précédente, a ses propres problèmes de vie privée, puisqu'elle permet à chaque participant d'apprendre les adresses IP des autres (normalement connues du seul serveur de présence). En outre, ces deux solutions, davantage pair à pair, souffrent du difficile problème de la connexion d'une machine à une autre, lorsqu'une des deux, ou les deux, sont derrière un pare-feu ou un routeur NAT. Avec le serveur de présence, il suffit aux clients d'une connexion sortante, ce qui est bien plus souvent possible.
Bref, cette intermédiaire dangereux qu'est le serveur de présence va être difficile à éliminer. D'où l'approche actuelle, qui repose plutôt sur des préférences quant à la divulgation de l'information, préférences (RFC 4745, RFC 5025 et RFC 6772) qui sont envoyées au serveur de présence, et à qui il faut faire confiance pour les respecter. Le RFC note bien que le succès est très limité : peu de logiciels exploitent cette information. Au moins, on peut documenter leurs limites, ce qui est fait ici.
On a donc là un bel exemple d'un compromis entre la protection de la vie privée (qui justifierait qu'on ne publie jamais rien sur sa présence) et le désir de faciliter la vie des utilisateurs en indiquant à l'avance si un appel a des chances d'aboutir ou pas.
Mon commentaire à une version préliminaire de ce RFC est disponible en ligne (notez la note de cloture du ticket). Globalement, mon regret est que ce document (même après les changements) est très axé sur les risques dus aux tierces parties et parle peu des risques du méchant silo qui stocke les données personnelles, ou sur les risques étatiques type PRISM.
Si vous voulez approfondir ces questions, ce RFC cite trois sources : le « FAIR INFORMATION PRACTICES: A Basic History » de Gellman, les directives de l'OCDE et le « Privacy Indexes: A Survey of Westin’s Studies ».
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : Y. Zhang, N. Zong (Huawei Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF ppsp
Première rédaction de cet article le 20 juillet 2013
Il existe actuellement des tas de logiciels qui font du streaming (audio ou vidéo) en pair à pair mais toujours en utilisant des protocoles privés et fermés. Cela a des tas de conséquences négatives, notamment sur le plan du choix : l'utilisateur est enfermé dans l'offre d'une compagnie particulière. Il est donc urgent de développer un protocole libre et ouvert de streaming pair à pair et c'est la tâche du groupe de travail PPSP de l'IETF. Son premier RFC, ce RFC 6972, est le cahier des charges du protocole (comme toujours à l'IETF, le travail a commencé bien avant la publication du cahier des charges et des mises en œuvre du protocole PPSP - normalisé dans le RFC 7574 - existent déjà).
Le streaming est un usage essentiel de l'Internet (le RFC cite une étude de Cisco à ce sujet). Dans sa version classique, avec un gros serveur ou une batterie de gros serveurs qui distribuent à des millions de clients, le streaming ne passe pas à l'échelle. Si on en était resté à ce mode de distribution, seule une poignée de très grosses entreprises pourraient héberger du contenu vidéo. Heureusement, il existe une meilleure solution, la distribution en pair à pair où chaque client se transforme en distributeur pour une partie du contenu. Le streaming pair à pair permet à n'importe qui de distribuer de la vidéo sur l'Internet, avec seulement des serveurs ordinaires.
Mais, car il y a un mais, ce streaming pair à pair, aujourd'hui, se fait essentiellement avec des protocoles privés d'une entreprise capitaliste particulière. La section 3 décrit les problèmes que cela pose. D'abord, sur le plan technique, cela interdit de développer des mécanismes de cache communs, le cache devant connaître le protocole utilisé (imaginez les caches Web si tout le monde ne parlait pas HTTP). Même chose pour les CDN qui ne peuvent pas être exploités facilement pour aider ce streaming puisqu'ils ne peuvent pas connaître tous les protocoles utilisés.
Enfin, les protocoles existants ne sont pas forcément bien adaptés aux mobiles qui sont pourtant une bonne partie des clients. Il y a eu des recherches à ce sujet (cf. J. Peltotalo et autres, « A real-time Peer-to-Peer streaming system for mobile networking environment » en 2009) mais qui ne se retrouvent pas forcément dans les protocoles existants. PPSP va donc devoir gérer :
À noter que la section 3 ignore les problèmes plus politiques comme l'excès de pouvoir que ces protocoles fermés donnent à l'entreprise qui les contrôle, et peut ainsi limiter la liberté des clients.
La section 4 décrit à un haut niveau les missions du protocole de streaming pair-à-pair. Pour modéliser ce protocole, elle reprend largement la terminologie de BitTorrent (la section 2 décrit tout le vocabulaire à connaître mais le RFC ne cite jamais BitTorrent), avec notamment la notion de tracker, le mécanisme (pas forcément une machine, cela peut être une DHT) qui garde trace de tous les pairs servant un contenu donné (ce qu'on nomme l'essaim). Il y a en fait deux protocoles, un entre le pair et le tracker et un entre pairs. Lorsqu'il rejoint un essaim, le pair doit pouvoir trouver les autres pairs (avec le premier protocole) et les contacter (avec le second). Il doit pouvoir connaître les caractéristiques des pairs, pour les choisir astucieusement. Le protocole doit bien sûr être efficace (le streaming vidéo fait passer d'énormes quantités de données) et doit être robuste (par exemple en cas de panne du tracker).
Le protocole pair<->tracker va nécessiter un identifiant unique pour les pairs (peer ID). Il va falloir aussi classer les pairs, par exemple selon le fait qu'ils ont une adresse IP publique ou pas, qu'ils sont en IPv4 ou en IPv6, qu'ils ont des ressources importantes ou pas, etc. Ce sera plutôt un protocole requête/réponse (le pair se connecte, transmet ses infos, et reçoit une liste de pairs).
Le protocole pair<->pair devra se colleter avec les problèmes de l'identification du contenu et de son intégrité (un problème important en pair-à-pair). Le contenu envisagé pour ce problème étant souvent de grande taille, il faudra le découper en morceaux (chunks) et il faudra donc un mécanisme d'identification des morceaux et de leur disponibilité. Ce sera plutôt un protocole de bavardage (échange continu d'information).
Avant d'aborder le cahier des charges précis, le RFC pose une dernière question, quels sont les usages envisagés pour ce nouveau protocole de streaming (section 5) ? Il y a la distribution de vidéo en temps réel, par exemple lors d'un événement (cela ressemble fortement à l'usage décrit dans les RFC 6707 et RFC 6770). Il y a aussi la VoD. D'autres usages sont moins évidents à première vue comme la possibilité d'avoir des caches pour le streaming. Même si on est dans une relation client/serveur, un protocole pair-à-pair de streaming permet d'envisager des systèmes de caches automatiques entre le client et le serveur, qui intercepteraient les requêtes et les mémoriseraient pour les futurs utilisateurs. Un exemple proche est l'extension P2Pyoutube du navigateur Opera.
Enfin, le cahier des charges proprement dit. Je ne vais pas reprendre ici toutes les exigences, classées en catégories (REQ : la base, OAM : gestion du protocole, TP : protocole pair<->tracker, PP : protocole pair<->pair) et numérotées. Certaines sont de l'ordre de l'évidence (PPSP.REQ.1 : chaque pair doit avoir un identificateur unique, PPSP.REQ.2 dit la même chose pour l'essaim et PPSP.REQ.4 pour le morceau). D'autres sont toujours bonnes à rappeler (PPSP.OAM.REQ-2 : il doit y avoir des paramètres de configuration, ayant des valeurs par défaut, PPSP.OAM.REQ-7 : on doit pouvoir les changer). Beaucoup sont communes à tout système de distribution de contenu en pair-à-pair et se retrouvent déjà dans BitTorrent. D'autres sont plus spécifiques au streaming. Ainsi PPSP.OAM.REQ-4 parle des mécanismes pour atteindre une qualité suffisante pour le flux audio ou vidéo. Cela implique un délai raisonnable. Le RFC dit par exemple qu'une minute de délai pour la retransmission d'un évenement sportif est inacceptable (imaginez le supporter du PSG ayant encore son verre de bière à la main alors que dans les maisons environnantes, tous les autres hurlent déjà « Buuuuuuuuuuuuuuut ! »).
Souci classique à l'IETF, le protocole doit être gérable. Des exigences comme PPSP.OAM.REQ-5 demandent qu'on puisse accéder à l'information nécessaire pour déboguer et/ou optimiser le protocole et PPSP.OAM.REQ-6 ajoute qu'il faut pouvoir tester un pair, sa connectivité, son bon fonctionnement, etc.
De même, les exigences sur le protocole tracker<->pair sont assez standards et évidentes (PPSP.TP.REQ-1 : le pair doit pouvoir obtenir du tracker une liste de pairs potentiels...). Notez quand même une exigence que l'authentification du pair soit possible, pour les essaims fermés (PPSP.TP.REQ-4). Même chose pour le protocole pair<->pair. Notez toutefois PPSP.PP.REQ-3 (obtenir directement du pair, sans passer par le tracker, d'autres pairs, de préférence vérifiés, ajoute PPSP.PP.REQ-5) et PPSP.PP.REQ-8, la possibilité d'obtenir plein d'informations sur les pairs.
Voilà, le cahier des charges est fini. Une faiblesse traditionnelle des systèmes pair-à-pair, la sécurité, fait l'objet d'une section à part, la 7. Elle analyse les risques dus à des pairs ou des trackers malveillants :
Cela entraîne l'ajout de quelques exigences supplémentaires, étiquetées SEC pour SECurity. PPSP.SEC.REQ-1 reprend l'exigence déjà mentionnée de pouvoir faire des essaims fermés, avec pairs authentifiés. PPSP.SEC.REQ-2 rappelle qu'il est indispensable d'avoir un mécanisme de contrôle de l'intégrité du contenu, pour empêcher un pair malveillant d'injecter des morceaux incorrects, et PPSP.SEC.REQ-3 appelle au réalisme en demandant que tout mécanisme de sécurité passe bien à l'échelle, on peut avoir des essaims immenses.
Les auteurs annoncent qu'il y a déjà trois mises en œuvre du protocole mais il ne semble pas y avoir beaucoup de documentation à ce sujet. Le protocole correspondant à ce cahier des charges a été normalisé dans le RFC 7574.
Date de publication du RFC : Juin 2013
Auteur(s) du RFC : U. Herberg (Fujitsu), A. Cardenas (University of Texas at Dallas), T. Iwao (Fujitsu), M. Dow (Freescale), S. Cespedes (U. Icesi)
Expérimental
Première rédaction de cet article le 29 juin 2013
Traditionnellement, l'acheminement à bon port d'un paquet IP nécessitait deux processus distincts : le routage (routing) à proprement parler, où les routeurs calculent des tables de routage indiquant, pour divers préfixes IP, la prochaine étape (next hop) à atteindre, et la transmission (forwarding) où les routeurs choisissent le prochain routeur, et l'interface de sortie, pour un paquet donné. Le premier processus, le routage, est fait à l'avance, indépendemment d'un paquet précis, et nécessite des protocoles complexes comme OSPF. Le second processus, la transmission, nécessite de faire tourner l'algorithme de plus long préfixe, et se fait par contre en temps réel, pour chaque paquet entrant. Pourquoi cette séparation en deux ? Car ces deux processus ont des caractéristiques très différentes. Le premier, nécessitant des protocoles et des algorithmes élaborés, est mieux réalisé sur un processeur classique. Le second est typiquement le domaine d'ASIC spécialisés. Les routeurs haut de gamme utilisent d'ailleurs les deux types de matériel, selon la tâche. Mais cette séparation a aussi des inconvénients. Ainsi, la détection qu'un lien ne marche plus est typiquement du ressort des algorithmes de routage, qui ajusteront alors leurs routes. Pourtant, certains réseaux physiques permettent la détection, lors de la transmission d'un paquet, d'une panne et d'une impossibilité d'envoi. Pourquoi ne pas utiliser cette information pour que les paquets suivants aillent essayer une autre étape suivante ? C'est ce que propose ce RFC.
Notez que, comme souvent en matière de réseaux informatiques, le vocabulaire est flou et incohérent. Ainsi, le terme de routage est souvent utilisé pour désigner les deux processus qui concourent à l'acheminement, le routage à proprement parler et la transmission. Par exemple, j'ai parlé de table de routage alors que le sigle FIB (Forwarding Information Base) aurait été plus correct. Et le terme routeur désigne une boîte qui fait de la transmission et parfois (sur le moyen et haut de gamme) le routage. On lit ainsi des phrases fausses comme « Quagga permet de transformer un PC Unix en routeur » alors que le noyau Unix a toujours été capable de faire de la transmission de paquets (Quagga met en œuvre les protocoles de routage, qui ne sont pas nécessaires à un routeur).
Mais passons. Il faut bien faire avec le vocabulaire que nous avons. Revenons à la proposition expérimentale de notre RFC 6971. Elle ne cherche pas à couvrir tous les cas de transmission de paquets. Ce RFC s'applique aux paquets IPv6, lors de leur transmission sur des liens peu fiables, avec une topologie sans cesse changeante, un trafic assez faible, et où le protocole de couche 2 permet de savoir si un paquet a été transmis avec succès ou pas. C'est typiquement le monde des MANET et des LowPAN, des réseaux de petites machines connectées en radio. L'idée centrale de ce protocole DFF est d'avoir, dans le processus de transmission, certaines techniques utilisées d'habitude uniquement dans le routage, pour chercher un chemin alternatif. DFF va transmettre un paquet au premier routeur, s'il ne reçoit pas de nouvelles, il va essayer le second et ainsi de suite. Par contre, si la transmission vers la première étape se fait avec succès, DFF va laisser le paquet continuer, passer au routeur suivant, etc. Il fonctionne donc en profondeur d'abord (on essaie d'aller le plus loin possible, avant de tester d'autres « frères »). Les essais successifs se font séquentiellement (et non pas en parallèle comme dans les protocoles d'inondation) pour éviter qu'un destinataire ne reçoive plusieurs copies du même message. Cela peut donc prendre pas mal de temps s'il y a beaucoup de routeurs potentiels. À noter que le tout fonctionne de manière répartie, sans composant central.
N'est-ce pas un peu bizarre que de refaire une partie du travail du processus de routage dans celui de transmission ? Mais c'est lié à la façon dont fonctionnent les protocoles de routage. Travaillant à l'avance, ils ne peuvent pas s'adapter assez vite à tous les changements de topologie, qu'on ne découvrira qu'en envoyant réellement des paquets. Les protocoles de routage fonctionnent typiquement en envoyant de temps en temps des messages d'information. L'information peut donc être dépassée au moment de la transmission. Pour avoir une information plus à jour (section 1.1), il faudrait augmenter le rythme des messages d'information et cela se ferait au détriment de la consommation d'énergie des machines (rappelez-vous que DFF est prévu pour des réseaux de petites machines, souvent sans autre source d'énergie que leur batterie). Se placer sur le dos du processus de transmission (qui doit avoir lieu de toute façon) permettra donc, si ce protocole DFF tient ses promesses (ce RFC est expérimental), d'augmenter le pourcentage de paquets effectivement transmis, sans augmenter les coûts.
DFF va donc récolter de l'information sur le fonctionnement effectif du réseau, information qui peut être utile au processus de routage. DFF peut donc la réinjecter dans ce dernier, pour l'aider à calculer de meilleures routes, mais ce point n'est pas détaillé dans ce RFC.
La section 3 du RFC revient sur l'applicabilité limitée de ce protocole DFF. On l'a dit, il ne s'agit pas de remplacer tous les mécanismes de routage existants par ce mécanisme utilisant le succès de la transmission comme indication. D'abord, tous les réseaux n'offrent pas de possibilité de détecter cet échec. 802.15.4 ou 802.11 le permettent mais pas Ethernet, par exemple. D'autre part, DFF n'est utile que si la topologie change souvent. Dans un réseau filaire stable et fiable, les mécanismes de routage actuels marchent très bien et n'ont pas besoin de DFF. Et DFF nécessite un réseau ayant une topologie dense, avec plusieurs liens possibles entre deux points. S'il n'existe qu'un seul lien, DFF ne servira à rien puisque, en cas de perte d'un paquet, il n'y aura pas d'alternative. Enfin, DFF, contrairement à la transmission IP traditionnelle, nécessite un état dans le routeur. Il faut se souvenir de chaque paquet envoyé, le temps qu'on soit sûr de son bon acheminement. DFF ne peut donc être utilisé qu'en cas de faible trafic.
DFF peut fonctionner aussi bien dans les réseaux route-over (réseaux routés par les méthodes IP classiques) que dans les réseaux mesh-under (réseaux utilisant un mécanisme de « routage » dans la couche 2, cette terminologie est empruntée au RFC 6775).
La section 4 résume le fonctionnement du protocole : pour chaque paquet qu'il a reçu et qu'il doit transmettre, le routeur construit une liste des prochaines étapes possibles. Il tente d'envoyer le paquet en essayant successivement ces étapes. Si toutes échouent, le routeur renvoie le paquet à l'expéditeur, qui va alors essayer l'étape suivante dans sa liste à lui (rappelez-vous qu'on est en profondeur d'abord). On voit donc que, pour chaque paquet pas encore transmis avec succès, le routeur doit garder cette information en mémoire : routeur précédent (qui a envoyé le paquet), numéro et prochaines étapes possibles en indiquant lesquelles ont déjà été essayées. C'est quoi, ce numéro ? C'est un identifiant unique par routeur et permettant de distinguer un paquet des autres (section 12). La liste des paquets en cours de transmission, avec les métadonnées, est nommée le Processed Set (section 6.2).
DFF doit connaître la liste des prochaines étapes possibles. Il a pu utiliser un protocole de découverte des voisins (comme le NHDP du RFC 6130), ou bien il a pu trouver cette information dans la RIB (Routing Information Base), la base de données construite par le processus de routage (voir la section 5 pour les détails).
Les informations dont a besoin DFF peuvent être représentées de
deux manières différentes dans le paquet. En
route-over, on utilise un en-tête d'extension
IPv6 standard, le hop-by-hop
options (et pas un destination options,
malgré les recommandations du RFC 6564 car cet
en-tête doit être examiné par tous les routeurs sur le trajet). Le
type de l'option DFF est 0xEE. Comme il commence par deux bits à Un,
le paquet sera rejeté par les routeurs non-DFF (RFC 2460, section 4.2). La section 13.1 de notre RFC fournit les
détails sur cette adaptation à IPv6. En mesh-under, on se sert des
en-têtes 6LoWPAN, avec les adresses du RFC 4944 (section 13.2 pour les précisions). Outre le numéro, il faut
mettre dans chaque paquet deux booléens : RET
indique un paquet renvoyé à l'expéditeur car non distribuable, et
DUP
indique une retransmission, au moins un essai
ayant apparemment échoué. Comme le paquet a pu être distribué quand
même (même si le routeur émetteur n'a pas été notifié),
DUP
sert à indiquer la possibilité de duplication
d'un paquet, avec laquelle les couches hautes vont devoir se débrouiller.
Rien ne garantit que le réseau soit un arbre
pur. Des boucles sont parfaitement possibles et DFF doit les
détecter.
Ces booléens RET
et DUP
permettent
notamment de distinguer un paquet délibérement renvoyé à l'émetteur
d'un paquet qui boucle dans le réseau. Si le routeur reçoit un paquet
qu'il a déjà transmis (il le sait d'après le numéro), avec DUP
et
RET
tous les deux à Zéro, c'est que le paquet
est en train de boucler. Si RET
est à Un, c'est
un retour délibéré car le routeur suivant n'a pas pu transmettre le
paquet.
Le format exact des paquets figure en section 7. Le traitement des paquets par les routeurs est détaillé en sections 10 et 11 du RFC. Des examples de fonctionnement de DFF dans diverses topologies, et pour divers cas de figure, se trouvent dans l'annexe A.
Notez que, comme la plupart des protocoles conçus pour ce type de réseau (sans administrateur réseaux, et où il y a beaucoup de machines, qu'il n'est pas question de configurer une par une), DFF ne présente guère de sécurité. Par exemple, en envoyant beaucoup de paquets à une adresse inexistante, on force les routeurs à retenir ces paquets en mémoire le temps de détecter la non-délivrabilité, réalisant ainsi facilement une attaque par déni de service (section 16.3.1).
Maintenant, il reste à tester DFF en vrai, et à récolter de
l'information sur les points détaillés en section 1.2 : quelles sont
les bonnes valeurs pour le délai d'attente
P_HOLD_TIME
(trop long, et on consomme
de la mémoire sur les routeurs, qui doivent se souvenir du paquet, trop
court, on risque d'oublier un paquet et de le croire nouveau lorsqu'il
revient après un échec, cf. section 8) ? Et les valeurs idéales pour le nombre de sauts
maximum MAX_HOP_LIMIT
? Et l'interaction idéale entre DFF et les protocoles de
routage ? Tous ces points vont devoir être étudiés en pratique.
L'annexe B du RFC rassemble un certain nombre d'informations sur le
déploiement effectif de DFF et ses mises en œuvre (au moins deux à
l'heure actuelle, une sur 802.11 et une sur 802.15.4). Par exemple, les
compteurs électriques de la
smart grid au
Japon utilisent apparemment DFF mais les détails
n'ont pas été publiés. Un autre distributeur d'électricité qui utilise
DFF est la Kit Carson Electric Cooperative au
Nouveau-Mexique, qui
en a http://www.kitcarson.com/index.php?option=com_content&view=article&id=45&Itemid=1
fait
état publiquement. Une mise en œuvre en logiciel libre de DFF en Java a été annoncée par
Fujitsu mais apparemment pas encore publiée
(en tout cas, je ne l'ai pas trouvée).
Merci à Laurent Toutain pour sa relecture et ses remarques pertinentes sur l'algorithme DFF.
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : M. Boucadair (France Telecom), R. Penno, D. Wing (Cisco)
Chemin des normes
Première rédaction de cet article le 24 juillet 2013
Le RFC 6887 normalise le protocole PCP (Port Control Protocol) qui permet de contrôler un routeur NAT ou un pare-feu depuis une machine cliente, par exemple pour ouvrir un port en entrée lorsqu'on utilise un logiciel de transfert de fichiers pair-à-pair ou bien un logiciel de téléphonie sur IP. PCP fonctionne également dans le cas des CGN. Mais cela ne sert à rien d'avoir des routeurs PCP si la quasi-totalité des applications sur les postes clients n'utilise toujours que le vieux protocole UPnP, certes très limité mais qui est largement déployé. Ce nouveau RFC décrit donc une solution de transition : une passerelle entre UPnP et PCP, permettant de satisfaire les clients UPnP et les serveurs PCP.
Cette passerelle sera typiquement installée dans le routeur
CPE (la box). Ainsi,
lorsque, par exemple, l'application qui parle UPnP fera un
AddPortMapping
, la passerelle le traduira en une
requête MAP
PCP (avec l'option
PREFER_FAILURE
puisque cette requête, contrairement
à AddAnyPortMapping
, réclame un numéro de port
spécifique et échoue s'il n'est pas disponible ; cf. section 5.6). Si vous aimez les sigles, vous
serez ravis car le nom complet de la passerelle est UPnP IGD-PCP IWF
pour UPnP Internet Gateway Device PCP Interworking
Function.
La section 4 donne les correspondances complètes entre les méthodes
UPnP et les méthodes PCP, ainsi qu'entre leurs codes d'erreur. Ainsi,
toute passerelle UPnP<->PCP sait qu'elle doit traduire une
erreur 8 de PCP (NO_RESOURCES
) en une erreur
501 ActionFailed
chez UPnP v1 et 728
NoPortMapsAvailable
chez UPnP v2 (qui a des codes d'erreur
bien plus détaillés). De la même façon, une erreur 2 de PCP
(NOT_AUTHORIZED
) devient 718
ConflictInMappingEntry
en UPnP v1 et 606
Action not authorized
en UPnP v2.
La passerelle UPnP<->PCP n'est pas un simple relais,
transférant des requêtes dans un sens et les réponses dans
l'autre. Elle doit garder un état, la mémoire de
toutes les correspondances demandées (section 5.3). Cela permet, par exemple de
faire face au fait que UPnP permet de créer une correspondance
{adresse interne, port
interne, adresse externe, port externe} de durée illimitée, ce que ne
sait pas faire PCP (RFC 6887, section 7.1). Dans
ce cas, la passerelle enregistre la correspondance et la renouvelle
dans le serveur PCP à chaque fois qu'elle approche de
l'expiration (section 5.9). D'autre part, des requêtes UPnP d'information comme
GetListOfPortMappings
ne sont pas relayés au
serveur PCP mais
traitées en examinant l'état local (section 5.7).
Autre point important de ce RFC : la passerelle peut être sur un routeur NAT ou pas (par exemple, dans certains cas de CGN, le routeur CPE ne fait pas de NAT). Si elle doit faire du NAT, la réception d'une requête UPnP va se traduire par une mise à jour de la table NAT locale et l'émission d'une requête au serveur PCP.
Ah, et pour trouver le serveur PCP à utiliser, comment fait la passerelle ? Comme un client PCP normal (via DHCP, par exemple).
Date de publication du RFC : Juin 2013
Auteur(s) du RFC : M. Boucadair (France Telecom), J. Touch (USC/ISI), P. Levis (France Telecom), R. Penno (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 19 juin 2013
Lorsque plusieurs machines sont situées derrière un routeur NAT, leurs pairs sur l'Internet ne peuvent pas facilement les distinguer. Tout le trafic vient de la même adresse IP, l'adresse publique allouée au routeur NAT, et c'est gênant pour certaines applications. Par contre, cela est positif d'un autre point de vue : cela fournit un certain niveau de masquage des machines individuelles, qui peut aider à protéger sa vie privée. Pris entre ces deux exigences contradictoires, l'IETF propose dans ce RFC une analyse des techniques permettant de révéler la machine individuelle derrière le routeur NAT, sans prendre position sur le fait de savoir si cette révélation est une bonne ou une mauvaise chose.
L'idée est que chaque machine a une identité unique (notée HOST_ID) et que les techniques étudiées ici doivent permettre de communiquer ce HOST_ID au pair avec qui on parle sur l'Internet. Autrefois, l'adresse IPv4 pouvait servir de HOST_ID mais cela ne marche plus désormais en raison de la prévalence du NAT. Le cas du petit routeur NAT à la maison n'est pas forcément le plus intéressant (toutes les machines appartiennent au même foyer) mais le problème est plus crucial avec les CGN, où des machines n'ayant aucun lien entre elles se partagent la même adresse IP, ce qui a des tas d'effets néfastes (RFC 6269) : impossible de mettre en liste noire la machine coupable, par exemple, sans risquer de gêner des utilisateurs n'ayant commis d'autre délit que de partager l'adresse IP d'un méchant. Même problème avec des techniques comme l'A+P du RFC 6346.
J'ai dit plus haut que le but était d'avoir des HOST_ID uniques. En fait, il doivent être uniques par adresse IP publique. Deux routeurs NAT qui utilisent des adresses IPv4 publiques différentes peuvent générer des HOST_ID identiques, seul le couple {adresse IPv4 publique, HOST_ID} a besoin d'être unique au niveau mondial (section 2 du RFC).
À ce stade, rappelez-vous que ce RFC présente un problème en terme très général et expose des solutions possibles. Par exemple, le HOST_ID peut figurer dans chaque paquet IP ou bien uniquement au début d'une session. Et il peut être ajouté par l'engin qui gère le partage d'adresse (le routeur NAT ou CGN) ou bien par la machine originale (qui pourra donc mentir, mais c'est pareil avec l'adresse IP source). Enfin, bien des identificateurs peuvent être utilisés comme HOST_ID (l'adresse IP à la source, les seize bits de poids le plus faible de l'adresse IP, un identifiant opaque compris uniquement par le FAI de départ, un VLAN ID, etc).
Une telle fonction de révélation des identités soulève évidemment des problèmes liés à la protection de la vie privée. Certains voient en effet dans le NAT des avantages en terme de sécurité comme, via le partage d'adresses, le fait que l'observateur extérieur ne puisse pas savoir quelle machine exactement, parmi toutes les machines situées derrière le routeur NAT, il est en train d'observer. En fournissant un HOST_ID à l'extérieur, on perdrait cette intimité. Notez qu'HOST__ID ramènerait juste au cas où on utilise une adresse IP publique sur sa machine, ni plus, ni moins. Notamment, un HOST_ID, comme une adresse IP publique, ne serait pas forcément permanent (lisez le RFC 8981 pour un exemple d'adresses publiques temporaires préservant la vie privée). Ainsi, une machine en redémarrant pourrait acquérir un nouvel HOST_ID.
Pour limiter les risques, ce RFC suggère deux règles : que les HOST_ID ne soient uniques que localement, pas globalement. Et qu'ils soient toujours temporaires. Cette question de la vie privée avait été la plus chaude lors des discussions à l'IETF sur le futur RFC, et le document a beaucoup évolué vers davantage de prise en compte du problème de la protection de la vie privée. Alissa Cooper, du CDT et auteure du RFC 6462 avait été particulièrement critique sur les premières versions de ce document, réclamant des modifications comme le fait que le HOST_ID ne soit pas forcément unique mondialement.
D'autre part, les logiciels qui visent à mettre en œuvre des mécanismes de dissimulation, afin de protéger la vie privée, comme Tor, supprimeront évidemment le HOST_ID, comme ils suppriment aujourd'hui d'autres informations bien plus révélatrices. Regardez le Panopticlick pour voir qu'on est facilement identifié de manière unique lorsqu'on navigue sur le Web, même derrière un routeur NAT.
La section 4 de notre RFC présente ensuite toutes les solutions étudiées pour transmettre l'HOST_ID. Certaines sont clairement mauvaises et ne sont mentionnées que pour documenter les raisons de leur rejet. D'autres méritent davantage d'étude.
D'abord, utiliser le champ Identification des paquets IP. Ce champ est surtout connu pour servir lors du réassemblage des datagrammes mais on peut théoriquement s'en servir pour « exfiltrer » de l'information sur une machine. Ce champ fait seize bits, ce qui est suffisant pour identifier une machine. Cela empêche évidemment de s'en servir pour le réassemblage après fragmentation (voir l'excellent RFC 6864 si vous voulez tout comprendre sur ce champ). Comme il n'est pas toujours facile pour le routeur NAT de garantir que les datagrammes ne seront jamais fragmentés, ni avant, ni après, cette solution est déconseillée par notre RFC.
On peut alors imaginer de définir une nouvelle option IP, conçue
uniquement pour notre but d'identification, et dont l'usage
n'entrerait pas en conflit avec des usages existants. Elle permettrait
de transporter l'information qu'on veut. (Cela avait été documenté dans l'Internet-Draft draft-chen-intarea-v4-uid-header-option
, abandonné depuis.) Cette solution, comme la
précédente, a l'avantage d'être indépendante du protocole de
transport. Elle pose quelques
problèmes techniques (que faire si le paquet a une taille proche de la
MTU et qu'on veut y ajouter cette option ? que
faire si l'espace pour les options, qui a une taille maximale en IPv4,
est plein ?) Mais elle a surtout comme défaut que les options IP sont
souvent bloquées sur
l'Internet (voir aussi « Measuring interactions between transport protocols
and middleboxes » par Alberto Medina, Mark Allman et Sally Floyd). Le RFC la regarde donc comme non
viable.
On peut alors monter d'une couche et choisir une nouvelle option
TCP, qui indiquerait le
HOST_ID. (Documenté dans
l'Internet-Draft
draft-wing-nat-reveal-option
qui a été abandonné
par la suite.) Cela aurait l'avantage qu'on n'aurait pas
à la répéter dans chaque paquet mais uniquement dans le paquet
SYN
. Cela aiderait à résoudre les problèmes de
MTU (le paquet SYN
est petit). Et les mesures indiquent que les options TCP
sont bien mieux respectées que les options IP sur l'Internet (voir
l'article de Medina, Allman et Floyd cité plus haut, ainsi que
l'Internet-Draft draft-abdo-hostid-tcpopt-implementation
).
Mais cette solution ne marcherait évidemment pas pour les autres protocoles de
transport. Et il y a quelques
problèmes techniques (une vision générale est dans l'article de Honda, M., Nishida, Y., Raiciu, C., Greenhalgh, A.,
Handley, M. et H. Tokuda, « Is it
still possible to extend TCP? »). Par exemple,
l'espace pour les options a une taille maximum dans TCP.
Si on n'a pas trouvé son bonheur dans la couche
3 (champ ID
d'IP ou option IP), ni
dans la couche 4 (option TCP), les couches
supérieures seront-elles plus accueillantes ? Pourquoi ne pas
transmettre l'information dans les applications ? Par exemple, pour
HTTP, l'en-tête
Forwarded:
(RFC 7239) pourrait être l'endroit idéal pour
cela. L'engin qui fait le partage d'adresses pourrait ainsi ajouter à
la requête HTTP :
Forwarded: for=192.168.13.1
Il existait avant un en-tête non-standard,
X-Forwarded-For:
, dit aussi XFF, qui faisait
quelque chose de ce genre. Comme les autres solutions au problème de la révélation du
HOST_ID, elle permet la triche. C'est pour cela que
Wikipédia maintient une liste des
FAI à qui on peut faire confiance pour mettre
de l'information XFF correcte. Wikipédia peut alors utiliser
l'information dans ce champ pour attribuer les responsabilités (de
vandalisme, par exemple, ou d'introduction délibérée d'informations
fausses) à la bonne adresse IP.
La principale limite de cette solution est qu'elle ne marche que pour
certains protocoles, comme HTTP. Pour les autres, il faudrait au fur
et à mesure concevoir une extension permettant de diffuser cette
information. Même pour HTTP, elle nécessite de modifier les requêtes
en cours de route, ce qui est impossible avec
HTTPS.
Pour éviter de devoir développer une extension ou un en-tête
spécifique par protocole applicatif, la solution PROXY a été
proposée. Elle consiste à ajouter l'information juste avant les
données de la couche
Application. L'information a cette allure (au moment du
partage d'adresses, 192.168.13.1:56324
voulait
parler à 192.0.2.15:443
) :
PROXY TCP4 192.168.13.1 192.0.2.15 56324 443\r\n
En la recevant, le serveur a juste à retirer cette ligne et à passer ce qui suit à l'application. En pratique, cette solution n'est pas réaliste car elle casse la compatibilité : un client qui a PROXY ne peut pas parler à un serveur qui ne l'a pas (l'opposé est vrai, par contre). Sans même parler des pare-feux qui n'accepteront pas ce qui leur semblera une requête invalide. Bref, elle n'est envisageable que dans des environnements fermés.
Le NAT tel que déployé aujourd'hui dans le monde IPv4 ne mérite pas
réellement son nom. Il ne traduit pas une adresse pour une autre mais
un couple {adresse, port} pour un autre. Il devrait plutôt être
qualifié de NAPT (Network Address and Port
Translation). Peut-on utiliser les ports alloués pour
transporter l'information sur le HOST_ID ? L'idée
est d'allouer un jeu de ports à chaque machine située derrière le
routeur NAPT. Par exemple, imaginons trois machines derrière le
routeur, celui-ci utilise les ports publics de 1 024 à 20 000 pour la
première machine, de 20 001 à 40 000 pour la seconde et de 40 001 à
65 535 pour la troisième (voir l'Internet-Draft draft-donley-behave-deterministic-cgn
). Il ne reste plus ensuite qu'à publier cette
information à l'extérieur (le RFC est muet sur ce point). Le RFC 6346 propose
une solution de ce genre. Malheureusement, cela contredit
partiellement les
exigences de sécurité des RFC 6056 et RFC 6269 qui demandent des ports sources
imprévisibles.
Plus disruptive est la solution qui consiste à utiliser un protocole nouveau, au dessus d'IP, le protocole HIP. HIP a déjà cette notion de HOST_ID (l'identité d'une machine est une clé cryptographique, ce qui résout bien des problèmes de sécurité). Mais cela nécessite que le client et le serveur parlent HIP tous les deux, ce qui parait irréaliste. À la rigueur, si tous les serveurs parlaient HIP, le routeur NAT pourrait se contenter de prendre des requêtes non-HIP et de les traduire en HIP. Mais tous les serveurs ne parlent pas HIP, loin de là.
Bon, si on n'arrive pas à mettre le HOST_ID dans
le canal normal de communication, peut-on le mettre à l'extérieur ?
Par exemple, peut-on utiliser ICMP pour
signaler l'adresse originale d'une communication en cours ? Dans cette
idée, le routeur NAT, en même temps que le paquet TCP initial vers le
serveur, enverrait une requête ICMP contenant l'information
utile. Cela avait été documenté dans
l'Internet-Draft
draft-yourtchenko-nat-reveal-ping
, qui a expiré
depuis. Cela marcherait pour tous les protocoles ayant la notion de
port (puisque c'est ce qu'on mettrait dans le
paquet ICMP pour indiquer de quelle session on parle). Et un problème
éventuel sur cette fonction de révélation de
l'HOST_ID (par exemple de l'ICMP bloqué) ne
gênerait pas la session normale (contrairement aux options IP ou
TCP). Par contre, on n'est pas sûr que ce soit la même machine qui
reçoive l'ICMP et qui reçoive les autres paquets (en cas d'utilisation
de répartiteurs de charge). Et cette technique
rend plus difficile l'examen de l'HOST_ID par des
intermédiaires, genre IDS.
Toujours dans la série « communications hors bande », l'idée de ressortir le vieux protocole IDENT (RFC 1413), qui récupérerait le HOST_ID par une connexion TCP vers la source d'une session. Il faudra donc un serveur IDENT dans la machine faisant le partage d'adresses et publier cette information (dans le DNS ?) pour éviter que les serveurs ne bombardent les pauvres CPE de requêtes IDENT. Il y a aussi des craintes quant aux performances de cette solution. Et quant à sa sécurité la requête IDENT pourrait être émise par un méchant.
Voilà, on a fait le tour de toutes les solutions envisageables. La section 5 de notre RFC présente une synthèse sous forme d'un tableau dont les lignes sont les solutions présentées plus haut et les colonnes sont les critères d'évaluation (« nécessite une modification de TCP/IP dans les machines », « a un impact sur les performances », « déployable aujourd'hui (sans refaire l'Internet de zéro) », etc).
Date de publication du RFC : Mai 2013
Auteur(s) du RFC : P. Saint-Andre (Cisco Systems)
Première rédaction de cet article le 24 mai 2013
Voici un nouvel espace de nommage pour les
URN, urn:example
, qui
servira pour les exemples et la documentation.
Les URN sont normalisés dans le RFC 8141 et offrent un moyen de construire des
URI stables et indépendants de toute notion de
localisation. L'URN commence par urn:
puis par un
NID (namespace identifier). Le RFC 3406
définissait trois genres de NID, formel, informel et expérimental (nom
commençant par x-
, et supprimé depuis par le RFC 8141). Lorsqu'on a besoin d'URN pour
une documentation ou un cours, on utilisait en général ces NID
expérimentaux. Mais les identificateurs commençant par
x-
sont désormais mal vus dans le monde
IETF (cf. RFC 6648) et ce
nouveau RFC propose donc d'abandonner ces NID expérimentaux et, pour
les exemples, d'utiliser le NID example
. De tels
noms réservés pour les exemples sont courants dans les RFC (par
exemple le RFC 2606 pour les noms de
domaine ou le RFC 5612 pour les
numéros d'organisations).
Ainsi, on peut désormais créer comme ça, gratuitement, l'URN
urn:example:foo:bar
et être sûr qu'il n'entrera
jamais en collision avec un « vrai » URN. (Par contre, deux URN
example
peuvent être accidentellement identiques
puisqu'aucune autorité ne les attribue.) Ces URN ne doivent être
utilisés qu'à des fins d'exemple et pas pour court-circuiter les
mécanismes normaux d'allocation des URN formels et informels, décrits dans le RFC 8141.
Date de publication du RFC : Juin 2013
Auteur(s) du RFC : B. Laurie, A. Langley, E. Kasper (Google)
Expérimental
Première rédaction de cet article le 7 juin 2013
Plusieurs attaques spectaculaires, notamment celle contre DigiNotar, ont montré la fragilité de l'actuel système de gestion de certificats X.509. Comme n'importe quelle AC peut émettre un certificat pour n'importe quel nom de domaine, il ne suffit pas d'évaluer la sécurité de son AC, il faudrait idéalement évaluer toutes les AC. Ce RFC propose une approche différente : encourager/obliger les AC à publier « au grand jour » les certificats qu'elles émettent. Un titulaire d'un certificat qui craint qu'une AC n'émette un certificat à son nom sans son autorisation n'a alors qu'à surveiller ces publications. (Il peut aussi découvrir à cette occasion que sa propre AC s'est fait pirater ou bien est devenue méchante et émet des certificats qu'on ne lui a pas demandés.) À noter qu'une deuxième version du système décrit ici a été publiée en décembre 2021, dans le RFC 9162 mais elle reste, fin 2021, peu déployée.
Ce n'est pas par hasard que les auteurs de ce RFC sont trois
employés de Google. Dans l'affaire
DigiNotar, comme dans d'autres affaires
analogues, le premier vrai/faux certificat émis par celui qui a piraté
une AC est souvent un certificat pour
gmail.com
, de façon à permettre d'espionner le
trafic vers Gmail. La proposition de ce RFC
(qui est encore expérimental) est d'empêcher l'émission « discrète »
de vrais/faux certificats qui seraient ensuite utilisés uniquement à
certains endroits (l'Iran dans le cas de
DigiNotar mais cela peut aussi concerner des entreprises qui font des
attaques de l'homme du milieu contre leurs propres employés).
Le principe est donc de créer un (ou plusieurs) journal des certificats émis. Le journal doit être public, pour que Google ou n'importe qui d'autre puisse l'auditer. Il doit être en mode « ajout seulement » pour éviter qu'on puisse réécrire l'histoire. Les certificats sont déjà signés mais le journal a ses propres signatures, pour prouver son intégrité. Conceptuellement, ce journal est une liste de certificats dans l'ordre de leur création. Toute AC peut y ajouter des certificats (la liste ne peut pas être ouverte en écriture à tous, de crainte qu'elle ne soit remplie rapidement de certificats bidons). En pratique, le RFC estime que la liste des AC autorisées à écrire dans le journal sera l'union des listes des AC acceptées dans les principaux navigateurs Web (voir aussi la section 4.7).
À chaque insertion, le journal renvoie à l'AC une estampille temporelle signée, permettant à l'AC de prouver qu'elle a bien enregistré le certificat. Si une AC peut présenter cette signature mais que le certificat est absent du journal, l'observateur aura la preuve que le journal ne marche pas correctement. Le format exact de cette estampille temporelle est décrit en section 3.2. Elle devra être envoyée au client par les serveurs TLS, comme preuve de la bonne foi de l'AC (cf. sections 3.3 et 5.2).
Les titulaires de certificats importants, comme Google, mais aussi des chercheurs, des agences de sécurité, etc, pourront alors suivre l'activité de ce(s) journal (journaux) public(s) (section 5.3 du RFC). Ce qu'ils feront en cas de détection d'un certificat anormal (portant sur leur nom de domaine, mais qu'ils n'ont pas demandé) n'est pas spécifié dans le RFC : cela dépend de la politique de l'organisation concernée. Ce RFC fournit un mécanisme, son usage n'est pas de son ressort. Ce journal n'empêchera donc pas l'émission de vrais/faux certificats, ni leur usage, mais il les rendra visibles plus facilement et sans doute plus vite.
Pour que cela fonctionne, il faudra que les clients TLS vérifient que le certificat présenté est bien dans le journal (autrement, le méchant n'aurait qu'à ne pas enregistrer son vrai/faux certificat, cf. section 5.4 du RFC).
En pratique, la réalisation de ce journal utilise un arbre de Merkle, une structure de données qui permet de mettre en œuvre un système où l'ajout de certificats est possible, mais pas leur retrait. La section 2 du RFC détaille l'utilisation de ces arbres et la cryptographie utilisée.
Le protocole utilisé entre les AC et le journal, comme celui
utilisé entre les clients TLD et le journal, sera
HTTP et le format des données sera
JSON (section 4). Ainsi, pour ajouter un
certificat nouvellement émis au journal géré sur
sunlight-log.example.net
, l'AC fera :
POST https://sunlight-log.example.net/ct/v1/add-chain
et le corps de la requête HTTP sera un tableau JSON de certificats encodés en Base64. La réponse contiendra notamment l'estampille temporelle (SCT pour Signed Certificate Timestamp). Pour récupérer des certificats, le programme de surveillance fera par exemple :
GET https://sunlight-log.example.net/ct/v1/get-entries
D'autres URL permettront de récupérer les condensats cryptographiques contenus dans l'arbre de Merkle, pour s'assurer qu'il est cohérent.
Notez que Google a produit une mise en œuvre de ce RFC, qui semble activement développée. Et il existe un pilote écrit en Go. Il y a aussi une liste de diffusion sur ce projet et un site officiel du projet par Google. Sinon, si vous voulez en savoir plus sur cette idée de vérification publique, consultez « Efficient Data Structures for Tamper-Evident Logging » de Scott A. Crosby et Dan S. Wallach. Autres lectures sur la certificate transparency, un article de promotion de Ben Laurie et un article violemment critique.
Quelles sont les chances de succès de cette idée ? Tant que peu d'AC participent, ces journaux ne serviront pas à grand'chose (le méchant attaquera uniquement les AC non participantes). L'idée est qu'à moyen terme, la pression sur les AC (directement ou bien via les navigateurs Web qui ne feraient plus confiance aux AC non participantes) pourra faire que tous les certificats devront être dans le journal et que l'examen de celui-ci suffira à détecter les « vrais/faux certificats ».
Merci à Florian Maury pour sa relecture très détaillée.
Date de publication du RFC : Juin 2013
Auteur(s) du RFC : S. Santesson (3xA Security), M. Myers
(TraceRoute
Security), R. Ankney, A. Malpani (CA
Technologies), S. Galperin (A9), C. Adams (University of Ottawa)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF pkix
Première rédaction de cet article le 7 juin 2013
Le protocole OCSP permet à un client X.509 (par exemple un navigateur Web engagé dans une connexion HTTPS) de s'informer en temps réel sur l'état d'un certificat, notamment afin de savoir s'il est révoqué ou pas. Ce nouveau RFC remplace (avec de légers changements) l'ancienne norme OCSP qui était dans le RFC 2560.
Normalement, le destinataire d'un certificat X.509 (par exemple le navigateur Web cité plus haut), authentifie ce dernier en utilisant les clés publiques des AC qu'il a dans son magasin, et en vérifiant dans une liste de CRL, mise à jour périodiquement, que le certificat est toujours d'actualité, qu'il n'a pas été révoqué par l'AC émettrice (section 3.3 du RFC 5280). En complément, ou à la place de ces CRL, le destinataire peut utiliser le protocole OCSP normalisé dans ce RFC. OCSP est un protocole synchrone : le destinataire du certificat émet une requête à un serveur OCSP et attend sa réponse avant de valider le certificat. Il peut ainsi obtenir des informations plus à jour qu'avec des CRL.
La requête OCSP contient (un survol du protocole figure en section
2 de ce RFC) le numéro de série du certificat qu'on veut authentifier. La réponse dépend
de si le répondeur (le serveur OCSP) a l'information sur ce
certificat. Si oui, il répond positivement (good
,
le certificat est valable)
ou négativement (revoked
, le certificat ne doit pas être accepté), en indiquant
l'heure (un certificat valable à un moment peut être révoqué par la
suite) et sa réponse est signée (typiquement
avec le certificat de l'AC). Si non, si le
répondeur n'a pas l'information, il répond unknown
.
Les réponses possibles sont donc good
,
revoked
et unknown
. Notez
que, de manière surprenante, good
ne dit pas que le certificat existe,
simplement qu'il n'a pas été révoqué. (Cette question a fait l'objet
de chauds débats dans le groupe de travail : que doit faire un
répondeur OCSP lorsqu'il reçoit une requête pour un certificat qu'il
est censé connaître mais qu'il
n'a pas émis ?)
Le répondeur peut aussi être dans l'incapacité de fournir une
réponse et, dans ce cas, le message d'erreur résultant n'est pas
signé. Parmi les causes possibles d'erreur, une requête incorrecte,
une erreur dans le répondeur (équivalent du 500 Internal
server error
de HTTP), un problème
temporaire qui nécessite que le client réessaie plus tard, un client
non autorisé, etc.
La réponse inclut souvent des temps : dernier moment où l'information retournée était correcte, moment de la prochaine mise à jour de l'information, moment de la signature de l'information (les réponses peuvent être pré-produites) ou moment où la révocation a eu lieu.
Mais comment un destinataire de certificat sait-il
où trouver le serveur OCSP ? Il est typiquement indiqué dans le
certificat qu'on teste, dans l'extension Authority Information
Access (section 4.2.2.1 du RFC 5280). Si la méthode d'accès est
id-ad-ocsp
, le contenu de cette extension est un
URL pointant
vers le serveur OCSP.
Voici un exemple dans un certificat récupéré sur l'Internet :
% openssl x509 -text -in /tmp/site.pem ... Authority Information Access: OCSP - URI:http://rapidssl-ocsp.geotrust.com CA Issuers - URI:http://rapidssl-aia.geotrust.com/rapidssl.crt
Mais cette information peut aussi être codée en dur dans le client.
La plupart du temps, l'URL en question sera un URL
HTTP, et OCSP tournera donc au dessus de ce
protocole (parfois en HTTPS). L'annexe A décrit en détail ce mécanisme. OCSP peut
utiliser GET
ou POST
. Dans
ce dernier cas, la requête HTTP aura le type
application/ocsp-request
et la requête OCSP forme le corps de la requête
POST
, après son encodage en
DER. Même chose pour la réponse, type
application/ocsp-response
, et du DER dans le
corps HTTP.
Voilà, vous savez l'essentiel, la section 4 décrit tout le
protocole, en ASN.1 (en s'appuyant sur les
modules de l'annexe B). Par exemple, une requête
est une TBSRequest
qui contient plusieurs
Request
, chacune concernant un certificat :
OCSPRequest ::= SEQUENCE { tbsRequest TBSRequest, optionalSignature [0] EXPLICIT Signature OPTIONAL } TBSRequest ::= SEQUENCE { version [0] EXPLICIT Version DEFAULT v1, requestorName [1] EXPLICIT GeneralName OPTIONAL, requestList SEQUENCE OF Request, requestExtensions [2] EXPLICIT Extensions OPTIONAL } ... Request ::= SEQUENCE { reqCert CertID, singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } CertID ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, issuerNameHash OCTET STRING, -- Hash of Issuer's DN issuerKeyHash OCTET STRING, -- Hash of Issuers public key serialNumber CertificateSerialNumber }
Et la réponse est un code de retour et la réponse elle-même :
OCSPResponse ::= SEQUENCE { responseStatus OCSPResponseStatus, responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } OCSPResponseStatus ::= ENUMERATED { successful (0), --Response has valid confirmations malformedRequest (1), --Illegal confirmation request internalError (2), --Internal error in issuer tryLater (3), --Try again later --(4) is not used sigRequired (5), --Must sign the request unauthorized (6) --Request unauthorized } ResponseBytes ::= SEQUENCE { responseType OBJECT IDENTIFIER, response OCTET STRING }
Avec response
comportant à son tour des
structures ASN.1 arrivant finalement à :
SingleResponse ::= SEQUENCE { certID CertID, certStatus CertStatus, thisUpdate GeneralizedTime, nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, singleExtensions [1] EXPLICIT Extensions OPTIONAL } CertStatus ::= CHOICE { good [0] IMPLICIT NULL, revoked [1] IMPLICIT RevokedInfo, unknown [2] IMPLICIT UnknownInfo } RevokedInfo ::= SEQUENCE { revocationTime GeneralizedTime, revocationReason [0] EXPLICIT CRLReason OPTIONAL }
On note que la raison de la révocation est indiquée. Elle n'est pas toujours indiquée par le répondeur OCSP (cela peut être une information sensible). La présence de cette information dans les CRL a permis à l'EFF de réaliser une intéressante étude sur les raisons des révocations (la section « How often are these attacks occurring? »).
La section 5 revient sur l'analyse de sécurité d'OCSP. On notera que les problèmes de vie privée n'y sont pas mentionnés. Pourtant, la requête OCSP indique au répondeur (en général l'AC) quels sites Web ont été visités. C'est d'ailleurs ainsi qu'il a été possible de prouver l'utilisation en Iran des vrais/faux certificats de DigiNotar, en regardant les requêtes OCSP de leurs navigateurs vers l'AC.
Un autre problème de sécurité n'est pas mentionné : que doit faire le navigateur Web qui tente d'authentifier un certificat lorsque la requête OCSP n'aboutit pas (peut-être parce qu'un Homme du Milieu bloque l'accès au serveur OCSP) ? S'il refuse d'authentifier le certificat, la connexion échoue. Mais s'il accepte, OCSP ne protège plus tellement.
Les changements depuis le RFC 2560 sont mineurs, et sont résumés dans la section 1.
Merci à Erwann Abalea pour sa relecture précise.
Date de publication du RFC : Mai 2013
Auteur(s) du RFC : D. McPherson (VeriSign), F.J. Baker (Cisco Systems), J.M. Halpern (Ericsson)
Pour information
Réalisé dans le cadre du groupe de travail IETF savi
Première rédaction de cet article le 30 mai 2013
On sait que, sur l'Internet, il est possible et même facile d'usurper une adresse IP , c'est-à-dire d'émettre un paquet IP avec une adresse source allouée à quelq'un d'autre (ou pas allouée du tout). Le projet SAVI (Source Address Validation Improvement) vise à améliorer la validation de l'adresse source, de manière à rendre l'usurpation plus rare et plus difficile. Ce RFC décrit la menace à laquelle SAVI répondra et étudie les contre-mesures existantes.
L'Internet emploie un protocole de réseau sans connexion (que ce soit en IPv4 ou en IPv6). Lorsqu'une machine veut communiquer avec une autre, elle met son adresse IP comme source d'un paquet, celle de son correspondant en destination et elle envoie le paquet. Substituer l'adresse IP d'une autre machine à la sienne est donc aussi simple que d'écrire une autre chaîne de bits à la place de l'adresse authentique. Le réseau n'essaie pas d'empêcher cela. Certes, le fraudeur ne pourra pas forcément recevoir les réponses (elles arriveront à celui dont l'adresse a été usurpée) mais ce n'est pas forcément un problème dans un réseau sans connexion. Il existe des mécanismes pour empêcher cette usurpation, le plus connu étant BCP 38 (les RFC 2827 et RFC 3704) mais ils sont insuffisamment déployés, car ils n'apportent pas de bénéfices à celui qui les déploie, uniquement aux autres acteurs de l'Internet. En outre, BCP 38 ne protège pas toujours suffisamment. Par exemple, s'il est mis en œuvre dans le premier routeur, il n'empêchera pas les machines du LAN d'usurper les adresses de leurs voisines.
L'une des idées de SAVI est donc de compléter BCP 38 avec des validations locales, apportant un bénéfice local, et qui permettraient une meilleure traçabilité.
Quelques termes à apprendre pour bien suivre les documents sur SAVI :
La section 3 détaille ensuite les attaques rendues possibles, ou facilitées par l'usurpation d'adresses IP source (la section 4 couvrira les contre-mesures). D'abord, les attaques en aveugle : l'assaillant, qui a usurpé l'adresse IP source, ne peut pas recevoir les réponses à ses paquets. Il peut les envoyer, ces paquets, mais c'est tout. Cela lui complique évidemment sérieusement la vie. Certaines attaques restent possibles. Il y a celles ne nécessitant qu'un seul paquet (et donc pas de réponse). Par exemple, si un paquet spécialement construit plante le logiciel du routeur qui le traite, un attaquant peut monter une attaque par déni de service en envoyant un unique packet of death. Un autre cas est celui où, en envoyant un paquet où l'adresse source et destination sont identiques, le destinataire se réponde à lui-même, puis à la réponse de la réponse, et entretienne ainsi lui-même la boucle sans fin (une bogue de cette famille avait frappé PowerDNS).
Une autre attaque en aveugle est le RST (ReSeT) TCP usurpé (section 2.3 du RFC 4953). Un seul paquet TCP accepté (l'attaquant doit deviner un numéro de séquence contenu dans la fenêtre en cours) va couper la connexion (notez que les protocoles applicatifs comme TLS et SSH ne sont d'aucune utilité contre cette attaque). Cela peut être très gênant pour les connexions censées durer longtemps (sessions BGP par exemple). Il existe des contre-mesures (voir le RFC 5961) mais empêcher l'usurpation d'adresse IP empêcherait complètement cette attaque.
Après les attaques en aveugle formées d'un seul paquet, place aux attaques volumétriques, reposant sur l'envoi d'un grand nombre de paquets. L'idée est de remplir certaines tables de taille fixe (par exemple la table des connexions entrantes) ou, encore plus simplement, de saturer le réseau de la victime. L'attaquant n'ayant pas besoin de réponse, il a tout intérêt, dans ces paquets, à usurper l'adresse IP source pour déguiser son identité. On constate que beaucoup de gens n'ont pas encore compris la facilité avec laquelle cette usurpation est possible, et croient réellement que l'adresse IP source qu'ils observent dans les paquets entrants est réellement celle de leur attaquant (pensez à cela la prochaine fois que vous lirez dans les médias quelque chose du genre « attaque par déni de service contre tel organisme, l'examen de l'attaque montrait que l'attaquant venait de Russie/Chine/Moyen-Orient »). Pire, la victime bloque parfois les paquets IP entrants en fonction de cette adresse source, réalisant ainsi une autre attaque par déni de service, contre la victime de l'usurpation d'adresse. Certaines attaques peuvent d'ailleurs être montées dans ce seul but.
Une autre raison pour l'attaquant d'usurper l'adresse IP source est la possibilité d'attaque par réflexion : comme au billard, on va viser une autre boule que celle qu'on veut vraiment toucher. L'attaquant envoie un paquet UDP au réflecteur (qui n'est pas sa vraie victime, juste un complice involontaire) en usurpant l'adresse IP source de la victime. Le réflecteur va alors répondre à ce qu'il croit être l'émetteur et qui est en fait la victime, qui sera ainsi bombardée par le ou les réflecteurs. La réflexion sert à l'attaquant à dissimuler ses traces (le paquet va suivre un tout autre chemin dans le réseau) mais elle est surtout intéressante couplée avec l'amplification. Avec certains protocoles, la réponse va être plus grande, voire beaucoup plus grande, que la requête. Avec une amplification de 20, l'attaquant pourra ainsi obtenir un bombardement de 1 Gb/s en ne dépensant lui-même que 50 Mb/s. Plusieurs protocoles permettent l'amplification, comme NTP, SNMP et surtout le DNS comme ce fut le cas lors de l'attaque de 2006 (le RFC ne les cite pas mais des attaques plus violentes ont eu lieu en 2012 et 2013).
Le RFC classe aussi dans les attaques volumétriques les actions visant à empoisonner les données d'un serveur distant. Le cas le plus courant est celui des empoisonnements DNS où le méchant va tenter de répondre avant le serveur légitime (cas, par exemple, des attaques Kaminsky). Ici, le volume élevé des requêtes n'est pas dû au désir de saturer la victime, mais à la nécessité de faire beaucoup d'essais pour en voir un accepté. (Dans le cas du DNS, il s'agit d'essayer beaucoup de Query ID et de ports source UDP.) À noter qu'il existe aussi des attaques par empoisonnement contre les caches ARP.
Cela, c'était les attaques en aveugle. Mais, parfois, un attaquant qui usurpe une adresse IP peut observer les réponses, par exemple parce qu'il est sur le même réseau local à diffusion que la victime de l'usurpation ou bien, si le réseau local ne diffuse pas à tous, parce qu'il a empoisonné les caches ARP. L'attaquant a alors bien plus de possibilités comme le détournement d'une connexion TCP à son profit, les tests de vulnérabilité d'un objectif sans se trahir, la subversion des protocoles de routage en se faisant passer pour un des routeurs participants, etc.
La section 4 décrit ensuite les contre-mesures qui peuvent être
adoptées aujourd'hui et qui sont effectivement déployées, au moins
partiellement. Par exemple, un commutateur peut
(en violant légèrement le modèle en couches),
refuser les paquets dont l'adresse IP source ne correspond pas à
l'adresse MAC du paquet (que le commutateur a pu apprendre en
examinant les requêtes et réponses ARP). Ou bien ceux qui viennent d'un autre port
physique que d'habitude. Si les paquets de
192.168.7.64
venaient toujours du port 3 et que,
tout à coup, ils viennent du port 4, le commutateur peut soupçonner
une usurpation (ou tout simplement une machine qui a été déplacée : la
sécurité peut se tromper).
On peut donc jeter un paquet lorsque son adresse IP source ne correspond pas aux informations qu'on possède. Notez bien que, plus on s'éloigne de la source des paquets, plus il est difficile d'être sûr que c'est bien une usurpation. Néanmoins, le RFC identifie cinq endroits où peut se faire cet examen de validité, du plus proche de la source au plus éloigné :
2001:db8:32:a17::/64
à l'Internet peut
raisonnablement jeter un paquet venant du réseau local et prétendant
avoir comme source 2001:db8:cafe::666
. Notez que
le routeur ne peut en général rien faire contre une machine qui
usurperait une adresse du même réseau local (ici,
2001:db8:32:a17::b00c
qui se ferait passer pour
2001:db8:32:a17::babe
). Dans des cas moins
triviaux (routeurs avec beaucoup d'interfaces et ayant de nombreux préfixes derrière eux), pour savoir quels
préfixes sont acceptables, le routeur peut simplement consulter une
ACL maintenue manuellement ou alors utiliser
RPF (RFC 3704).En pratique, il y a des tas de détails qui compliquent la validation d'adresse IP source. Par exemple, pour un commutateur réseau, le cas simple est celui où il y a une et une seule machine derrière chaque port physique et où chaque adresse MAC ne correspond qu'à une seule adresse IP. Si ce n'est pas le cas, le problème devient plus difficile. Pensez par exemple à une machine physique, connectée par le port d'un commutateur mais portant plusieurs machines virtuelles, chacune avec sa propre adresse IP et sans doute sa propre adresse MAC. Ce cas est en fait un commutateur interne, le commutateur physique n'étant que le deuxième commutateur sur le trajet et n'ayant donc que des capacités de validtaion limitées. Idéalement, c'est le commutateur virtuel dans le système de virtualisation qui devrait faire respecter les règles SAVI, mais l'administrateur réseaux n'en a pas forcément le contrôle et ne lui fait pas forcément confiance.
Pour apprendre le lien entre une adresse MAC et une adresse IPv4, la meilleure solution pour un commutateur est d'écouter les requêtes et les réponses DHCP et de considérer qu'elles font autorité au sujet de ce lien (cf. RFC 7513). Par exemple, en voyant passer cette réponse (vue avec tcpdump) :
09:49:23.191187 00:10:db:ff:40:70 > 18:03:73:66:e5:68, ethertype IPv4 (0x0800), length 368: (tos 0x0, ttl 64, id 16537, offset 0, flags [none], proto UDP (17), length 354) 192.0.2.20.67 > 192.0.2.54.68: BOOTP/DHCP, Reply, length 326, hops 1, xid 0x903b4b00, Flags [none] Your-IP 192.0.2.54 Client-Ethernet-Address 18:03:73:66:e5:68 ...
Le commutateur sait alors que l'adresse IP
192.0.2.54
a été allouée à
18:03:73:66:e5:68
et qu'un paquet IP dont
l'adresse MAC source serait 18:03:73:66:e5:68
et
l'adresse IP source serait autre chose que
192.0.2.54
est probablement une usurpation et
doit être jeté.
Pour IPv6, outre le trafic DHCP, le commutateur doit écouter les paquets DAD (Duplicate Address Detection) du protocole d'auto-configuration (RFC 4862). Le commutateur sera alors au courant des adresses IP légitimement enregistrées, et de l'adresse MAC correspondante, et pourra se servir de cette information pour valider. Par contre, contrairement à ce qu'on pourrait penser, le protocole d'authentification 802.1x n'aide pas : il authentifie un utilisateur mais ne limite pas les adresses IP qu'il peut utiliser. Enfin, il existe des techniques cryptographiques qui pourraient être utiles pour SAVI comme le SEND du RFC 3971 mais qui sont tellement peu déployées qu'on ne peut pas réellement compter dessus.
Certaines topologies de réseau, quoique parfaitement légales, peuvent sérieusement handicaper SAVI (section 5). Par exemple, si toutes les adresses sont statiques et stables, le problème est relativement bien circonscrit. Mais dans beaucoup de réseaux, ce n'est pas le cas et des adresses sont attribuées dynamiquement. Une même adresse IP sera, dans le temps, allouée à plusieurs adresses MAC et une même adresse MAC n'aura pas forcément la même adresse IP à chaque visite de ce réseau. (Ceux qui utilisent arpwatch sur un tel réseau savent le nombre d'« alarmes » que cela génère. SAVI a exactement le même problème.) D'autre part, si certaines machines sont simples (une adresses MAC, une adresse IP), d'autres sont plus complexes pour le validateur. Un exemple typique est un routeur. Par définition, il émet sur le réseau local des paquets avec sa propre adresse MAC mais des adresses IP source qui ne sont pas la sienne. Il est donc difficile de valider ces paquets.
Autre cas rigolo, notamment en cas de virtualisation : si une machine se déplace dans le data center mais garde son adresse IP. Les commutateurs vont devoir oublier la vieille information sur le port où est connecté cette machine et apprendre la nouvelle. (On appelle cela « mettre à jour son état SAVI ».)
La mobilité entraîne aussi des problèmes. Dans IP, elle peut se réaliser de plusieurs façons. Dans l'une, dite « en jambe de chien », la machine mobile émet des paquets avec son adresse IP source stable (home address), quel que soit le réseau physique où elle est attachée. Un tel mécanisme est évidemment incompatible avec toute solution de validation. Il faut donc que tous les paquets du mobile, aussi bien en émission qu'en réception, soient relayés par la station de base située sur son réseau d'attachement habituel.
Un petit mot aussi sur IPv6 : il crée des difficultés supplémentaires en raison de l'auto-configuration, très pratique mais, par son caractère local, non contrôlé centralement, pas forcément très sûre. Et son espace d'adressage très large (une bonne chose, et la principale raison pour laquelle il est important de déployer IPv6) a comme effet de bord la facilité à utiliser beaucoup d'adresses usurpées. En IPv4, un usurpateur a en théorie 2^32 adresses à usurper et, en pratique, plutôt moins de 2^24 (uniquement celles de son réseau local). En IPv6, même si on arrive à limiter l'usurpateur à son réseau local, il aura 2^64 adresses, ce qui permet de court-circuiter certains mécanismes de sécurité.
La section 6 revient en détail sur la question de la granularité de la validation. Aujourd'hui, il est relativement facile d'empêcher les usurpations inter-sites (où un attaquant prend l'adresse IP d'une machine sur un autre site). Mais empêcher les usurpations intra-sites est plus complexe or, justement, la plupart des attaques viennent de l'intérieur.
Notez que SAVI se limite aux couches basses : il n'est pas prévu de
vérifier les adresses IP qui apparaissent dans les applications (par
exemple dans le champ Received:
des messages
formatés suivant le RFC 5322).
Enfin, la section 7 revient sur les questions de sécurité à un haut niveau. Elle rappelle que SAVI n'a pas pour but de produire des preuves, au sens judiciaire du terme (dans le meilleur cas, la validation permet de s'assurer de l'adresse IP, mais certaines machines sont multi-utilisateurs). Elle rappelle aussi que SAVI est une technique relativement légère et que, même si elle était massivement déployé, il ne faudrait pas utiliser les adresses IP source comme authentiques. La seule solution fiable pour être certain de l'identité de son correspondant est la cryptographie.
Cette section 7 revient aussi en détail sur les conséquences de SAVI pour la vie privée. Une adresse IP peut être vue, dans certains cas, comme une donnée identifiant une personne et le fait de la valider a donc des implications. Le RFC note bien que la validation SAVI ne nécessite pas d'enregistrer de l'information et que, si on réalise cet enregistrement avec des adresses IP, on peut engager sa responsabilité morale et/ou légale.
Aujourd'hui, des fonctions de type SAVI sont présentes dans pas mal de systèmes (par exemple les commutateurs haut de gamme) mais pas forcément toujours activées. Le RFC 5210 contient un compte-rendu d'expériences à ce sujet.
Date de publication du RFC : Juin 2013
Auteur(s) du RFC : W. Wang (Zhejiang Gongshang University), E. Haleplidis (University of Patras), K. Ogawa (NTT Corporation), C. Li (Hangzhou DPtech), J. Halpern (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 29 juin 2013
Le protocole ForCES vise à permettre la création d'équipements réseaux (par exemple des routeurs) en assemblant des pièces d'origines diverses, parlant un protocole commun et pouvant donc interagir. Ce RFC marque l'achèvement de la première (et très longue) phase de ForCES, la normalisation complète de ce protocole. Notre RFC 6956 décrit la bibliothèque standard de ForCES, les parties d'un routeur qu'on trouvera partout et qui assurent les fonctions indispensables comme faire suivre un paquet IP.
ForCES peut servir à bien d'autres choses et il y aura aussi des bibliothèques pour d'autres équipements que les routeurs, et aussi des bibliothèques non-standard, développées par tel ou tel projet. Mais pour atteindre l'objectif premier de ForCES, créer un routeur par assemblage de pièces standards, cette bibliothèque « routeur » était le dernier élement manquant.
Avant de lire ce RFC 6956, il faut bien se pénétrer du cadre général (RFC 3746), du protocole (RFC 5810) et du modèle de données (RFC 5812). J'en extrais quelques termes qu'il faut connaître :
Ethernet/0/2
», etc). Un LFB est une fonction logique : dans la matériel, on ne
retrouve pas forcément ce concept.La bibliothèque composée des classes définies dans ce RFC 6956 permet de réaliser un routeur complet, mettant en œuvre toutes les fonctions obligatoires du RFC 1812, notamment :
Place maintenant au cœur de ce RFC, les classes qui y sont définies. Le choix du groupe de travail forces (section 3.2) a été de privilégier la souplesse en définissant plutôt trop de classes que pas assez. Chaque classe ne va donc effectuer qu'un minimum de fonctions, être logiquement séparée des autres classes et notre routeur devra donc mettre en œuvre beaucoup de classes. Cela rend donc le RFC très long et je ne vais donc pas parler de toutes les classes, seulement de quelques unes choisies comme exemples. Pour la totalité des classes, vous devez lire le RFC.
Les définitions des classes s'appuient sur un certain nombre de
types définis en section 4. Le RFC 5812 avait
normalisé les types de base comme uint32
,
char
ou
boolean
. Notre RFC y ajoute quelques types
atomiques comme IPv4Addr
,
IPv6Addr
, IEEEMAC
(une
adresse MAC),
PortStatusType
(permettant d'indiquer si le port
est activé ou non et s'il fonctionne), VlanIDType
pour le numéro de VLAN, etc. Il définit
également des types composés comme MACInStatsType
(une entrée dans le tableau de statistiques pour les paquets entrants, analysés à la
couche 2), IPv6PrefixInfoType
(un préfixe IPv6),
IPv4UcastLPMStatsType
(une entrée dans le tableau de
statistiques pour les paquets IPv4), etc. Logiquement, les
tableaux qui utilisent ces types sont également définis comme
IPv6PrefixTableType
(un tableau de préfixes IPv6)
ou VlanInputTableType
(un tableau de
VLAN).
Un NE manipule des paquets donc il y a évidemment des types de
paquets parmi lesquels EthernetII
,
IPv4
, IPv6
, et même
Arbitrary
pour des paquets quelconques.
Le tout est formellement décrit en XML dans la section 4.4. Ainsi, une adresse IPv4 est :
<dataTypeDef> <name>IPv4Addr</name> <synopsis>IPv4 address</synopsis> <typeRef>byte[4]</typeRef> </dataTypeDef>
et une IPv6 est :
<dataTypeDef> <name>IPv6Addr</name> <synopsis>IPv6 address</synopsis> <typeRef>byte[16]</typeRef> </dataTypeDef>
Un type atomique comme la capacité du lien est définie par :
<dataTypeDef> <name>LANSpeedType</name> <synopsis>LAN speed type</synopsis> <atomic> <baseType>uint32</baseType> <specialValues> <specialValue value="0x00000001"> <name>LAN_SPEED_10M</name> <synopsis>10M Ethernet</synopsis> </specialValue> <specialValue value="0x00000002"> <name>LAN_SPEED_100M</name> <synopsis>100M Ethernet</synopsis> </specialValue> ...
Même chose pour le PortStatusType
mentionné plus haut :
<dataTypeDef> <name>PortStatusType</name> <synopsis> Type for port status, used for both administrative and operative status. </synopsis> <atomic> <baseType>uchar</baseType> <specialValues> <specialValue value="0"> <name>Disabled</name> <synopsis>Port disabled</synopsis> </specialValue> <specialValue value="1"> <name>Up</name> <synopsis>Port up</synopsis> </specialValue> <specialValue value="2"> <name>Down</name> <synopsis>Port down</synopsis> </specialValue> </specialValues> </atomic> </dataTypeDef> <dataTypeDef>
Et les types structurés ? Un exemple est celui des statistiques sur les paquets sortants, qui a deux composants (les champs des objets), un pour les paquets transmis et un pour les paquets jetés :
<dataTypeDef> <name>MACOutStatsType</name> <synopsis> Data type defined for statistics in EtherMACOut LFB. </synopsis> <struct> <component componentID="1"> <name>NumPacketsTransmitted</name> <synopsis>Number of packets transmitted</synopsis> <typeRef>uint64</typeRef> </component> <component componentID="2"> <name>NumPacketsDropped</name> <synopsis>Number of packets dropped</synopsis> <typeRef>uint64</typeRef> </component> </struct> </dataTypeDef>
Un autre exemple est le préfixe IPv6, qui réutilise le type atomique IPv6Addr
:
<dataTypeDef> <name>IPv6PrefixInfoType</name> <synopsis>Data type for entry of IPv6 longest prefix match table in IPv6UcastLPM LFB. The destination IPv6 address of every input packet is used as a search key to look up the table to find out a next hop selector.</synopsis> <struct> <component componentID="1"> <name>IPv6Address</name> <synopsis>The destination IPv6 address</synopsis> <typeRef>IPv6Addr</typeRef> </component> <component componentID="2"> <name>Prefixlen</name> <synopsis>The prefix length</synopsis> <atomic> <baseType>uchar</baseType> <rangeRestriction> <allowedRange min="0" max="32"/> </rangeRestriction> </atomic> </component> ...
Une fois tous ces types définis (et cela prend un bon bout du RFC),
on peut les utiliser pour bâtir les classes (section 5). Chaque classe
va être un gabarit dont on tirera les instances. Premier exemple :
notre routeur ForCES va évidemment avoir besoin de connaître
Ethernet et de traiter des paquets Ethernet, en
envoi et en réception. Ethernet étant très varié, commençons par un
LFB (Logical Function Block) qui représente le
niveau physique, EtherPHYCop
. Ce LFB (cette
partie logique d'un routeur) a des composants pour indiquer l'état du
port (AdminStatus
et
OperStatus
), composants qui peuvent être lus et
modifiés via le protocole ForCES. Ce LFB peut aussi générer des
événements comme par exemple le changement d'état d'un port
(PHYPortStatusChanged
).
Au niveau au dessus (couche 2), il y a le
LFB EtherMACIn
. C'est par exemple là que se
trouve le composant LocalMACAddresses
qui indique
l'adresse MAC. ou bien le composant
PromiscuousMode
qui dit si on veut recevoir (ou
pas) tous les paquets, même adressés à une autre machine.
Rappelez-vous : cette bibliothèque standard de ForCES privilégie la
souplesse, et crée donc beaucoup de LFB, pour
pouvoir les arranger comme souhaité. Rien que pour Ethernet, il y en a
encore plusieurs comme EtherEncap
qui modélise
les fonctions d'encapsulation et de décapsulation des
trames (ajout ou retrait des en-têtes
Ethernet).
Mais on ne peut pas passer toute la journée sur les couches
basses. Pour « construire » un routeur par assemblage de LFB, il nous
faut maintenant des fonctions de manipulation
d'IP. C'est le cas du LFB
IPv6Validator
qui représente les fonctions de
validation d'un paquet (avant qu'on décide de le traiter, ou de le
jeter s'il est invalide). On suit le RFC 2460 et
on considère comme invalide (ne devant pas être transmis) les paquets
ayant une taile inférieure à la taille minimale, les paquets
ayant une adresse source ou destination inacceptable, etc. Il y a
aussi des paquets nommés « exceptionnels » qui, sans être à proprement
parler invalides, ne pourront pas être transmis normalement (par
exemple ceux avec un hop limit descendu à
zéro).
Et, ensuite, le travail sera fait par les LFB de transmission. Oui,
ils sont plusieurs. Pour IPv6, au moins IPv6UcastLPM
(trouver le LPM, Longest Prefix Match, dans la
table) et IPv6NextHop
(sélection du routeur
suivant), sans compter des futurs LFB optionnels, par exemple pour
mettre en œuvre RPF.
Les LFB sont eux aussi formalisés en XML
(section 6). Par exemple, le dernier que nous avons vu,
IPv6NextHop
, sera :
<LFBClassDef LFBClassID="13"> <name>IPv6NextHop</name> <synopsis> The LFB abstracts the process of next hop information application to IPv6 packets. It receives an IPv6 packet with an associated next hop identifier (HopSelector), uses the identifier as a table index to look up a next hop table to find an appropriate output port. </synopsis> <inputPorts> <inputPort group="false"> <name>PktsIn</name> <synopsis> A port for input of unicast IPv6 packets, along with a HopSelector metadata. </synopsis> ... </inputPort> </inputPorts> <outputPorts> ... </outputPorts> <components> <component componentID="1"> <name>IPv6NextHopTable</name> <synopsis> The IPv6NextHopTable component. A HopSelector is used to match the table index to find out a row which contains the next hop information result. </synopsis> <typeRef>IPv6NextHopTableType</typeRef> </component> </components> </LFBClassDef>
Si la tête commence à vous tourner sérieusement, c'est sans doute
normal et prévu. Les auteurs du RFC ont pensé à vous et inclus une
section 7 qui décrit comment on crée une fonction de haut niveau à
partir des LFB de cette bibiothèque standard. Leur premier exemple est
la transmission de paquets IPv4 et le dessin ne compte pas moins de
treize LFB... (Dont, il est vrai, neuf juste pour Ethernet.) Pour
ajouter ARP, cela prend sept LFB (certains sont
communs par exemple EtherEncap
est utilisé à la
fois par la transmission de paquets IPv4 et par ARP).
Les classes des LFB sont désormais dans un registre IANA, ce qui permettra d'en ajouter plus facilement d'autres.
Voilà, arrivé à ce stade, on a de quoi « fabriquer » un routeur ou plus exactement de quoi le modéliser. En pratique, les vrais routeurs seront bien différents mais ils exporteront aux clients ForCES des fonctions représentées par ces LFB standards, fonctions qu'on pourra configurer avec Forces.
Date de publication du RFC : Mai 2013
Auteur(s) du RFC : J. Schaad (Soaring Hawk Consulting), H. Prafullchandra (Hy-Trust)
Chemin des normes
Première rédaction de cet article le 30 mai 2013
Lorsqu'on détient une clé cryptographique privée et qu'on veut le prouver à un correspondant, la méthode la plus simple et la plus standard est de signer un message avec cette clé et de l'envoyer audit correspondant, qui, en vérifiant la signature, s'assurera qu'on était bien en possession de la clé privée. Mais dans certains cas, signer n'est pas possible. Ce RFC décrit trois algorithmes qui permettent de prouver qu'on connait une clé, sans signer. Il remplace le RFC 2875.
Ce test de POP (Proof Of Possession) est un de ceux que doit faire, par exemple, une autorité de certification, avant de signer un certificat. (Le RFC 4211, annexe C, explique pourquoi c'est important.) Ainsi, une CSR (demande de signature d'un certificat) faite par OpenSSL est signée et cela peut se vérifier :
% openssl req -verify -in server.csr -noout verify OK
Le format CRMF du RFC 4211 et le format PKCS#10 permettent tous les deux d'envoyer une demande de signature de certificat à une AC mais seul CRMF a un moyen d'inclure une POP pour les algorithmes ne permettant pas de signature. PKCS#10 (RFC 2986) n'a rien. Cela existe, de tels algorithmes, ne permettant pas de signature ? Oui, c'est le cas de Diffie-Hellman et de ECDH.
Les trois algorithmes de POP de notre RFC sont le Diffie-Hellman statique en section 4, le logarithme discret en section 6 et l'ECDH statique en section 6. Ne me demandez pas de vous les expliquer, cela dépasse largement mes compétences en cryptographie. Lisez le RFC pour cela. (Et révisez le RFC 6090 pour le troisième, qui utilise les courbes elliptiques.) Notre RFC 6955 fournit les algorithmes et les modules ASN.1 qui les décrivent.
La section 1.1 décrit les changements depuis le RFC 2875. Les deux algorithmes du précédent RFC ont été réécrits pour permettra leur paramétrisation par rapport à la fonction de condensation (obligatoirement SHA-1 dans l'ancien RFC, alors que plusieurs fonctions sont désormais possibles, notamment la famille SHA-2). Et un troisième algorithme a été ajouté, pour ECDH.
Date de publication du RFC : Mai 2013
Auteur(s) du RFC : M. Jethanandani (Ciena Corporation), K. Patel (Cisco Systems), L. Zheng (Huawei Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF karp
Première rédaction de cet article le 25 mai 2013
Dans le cadre du travail du groupe KARP de l'IETF, consacré à la sécurisation des protocoles de routage de l'Internet, ce RFC est consacré à l'analyse de la sécurité des protocoles de routage utilisant TCP, notamment BGP.
Deux petits rappels : KARP travaille sur les protocoles eux-mêmes, ni sur le contenu des informations transmises (c'est le rôle de SIDR, qui a produit le système RPKI+ROA), ni sur les pratiques quotidiennes d'administration des routeurs. Son rôle est d'améliorer la sécurité des protocoles, et pour cela il commence par des analyses de la sécurité des protocoles existants, suivant une méthode décrite dans le RFC 6518. Il y avait déjà eu une analyse d'OSPF (RFC 6863) et ce nouveau RFC s'attaque à des protocoles très différents mais qui ont en commun d'utiliser TCP comme transport : BGP (RFC 4271) et LDP (RFC 5036), ainsi que les moins connus PCEP (Path Computation Element Communication Protocol, RFC 5440) et MSDP (RFC 3618). Ils appartiennent tous à la catégorie un-vers-un du RFC 6518 (les messages d'un routeur sont transmis à un seul autre routeur).
Donc, aujourd'hui, quels sont les risques de sécurité pour ces protocoles et les défenses existantes ? D'abord, ceux et celles spécifiques à la couche transport. Il y a les attaques par déni de service et les attaques où l'ennemi va tenter d'établir une session avec sa victime, sans en avoir normalement le droit. Parmi les contre-mesures (RFC 4732 pour un point de vue plus général), il y a des ACL par adresse IP (tous ces protocoles utilisant TCP, il n'y a normalement pas de possibilité pour un attaquant en dehors du chemin d'usurper une adresse IP, si tout le monde suit bien le RFC 4953 et le RFC 5961) et le fait d'écouter les connexions entrantes uniquement sur les interfaces où on s'attend à avoir des pairs. Pour éviter les attaques de méchants lointains, il y a la technique GTSM du RFC 5082, qui consiste à n'accepter des paquets que s'ils ont un TTL maximal (ou proche du maximum).
Cela ne suffit pas contre des assaillants situés sur le chemin (par exemple parce qu'ils sont sur le réseau local). Ceux-ci peuvent établir une connexion avec une fausse adresse IP, ou bien simplement envoyer des resets TCP pour couper les sessions existantes (notez que TLS ou SSH ne protégeraient pas contre ce dernier risque car ils fonctionnent au-dessus de TCP). Pour assurer l'authentification et l'intégrité de la connexion TCP, on a l'« authentification MD5 » du RFC 2385, normalement remplacée par l'AO du RFC 5925. AO est très supérieur, fournissant notamment l'agilité cryptographique (la possibilité de changer d'algorithme si la cryptanalyse en a trop affaibli un, ce qui est le cas de MD5). Mais AO est loin d'avoir remplacé MD5.
Et puis il y a les problèmes qui ne dépendent pas du transport utilisé, comme l'absence d'un protocole de gestion des clés (KMP pour Key Management Protocol). Actuellement, la gestion des clés dans tous ces protocoles est purement manuelle et, résultat, les clés cryptographiques des routeurs ne sont quasiment jamais changées, même lorsqu'un administrateur quitte la société.
Maintenant, place à chaque protocole individuellement. Le RFC fait une présentation de chaque protocole (section 2), puis de l'état de sécurité idéal qu'on souhaite atteindre (section 3), puis de la différence entre l'état actuel et cet idéal (section 4). Enfin, la section 5 étudie les questions de transition vers une meilleure solution de sécurité (tous ces protocoles étant pair-à-pair, il faut que les deux pairs soient d'accord pour la nouvelle technique de sécurité). Ici, je procède différemment en traitant tous les aspects de chaque protocole successivement (enfin, pas chacun, je ne couvre que BGP et LDP, ne connaissant pas vraiment PCEP et MSDP). Donc, honneur à BGP pour commencer, puisque c'est sans doute le protocole de routage le plus important pour l'Internet (section 2.3). Comme il ne fonctionne que sur TCP, sa sécurité est en bonne partie celle de ce protocole de transport. Autrement, il devra attendre le déploiement d'AO, puis d'un KMP pour que sa sécurité s'améliore.
LDP, lui, est utilisé par
MPLS et le RFC général de sécurité sur MPLS, le
RFC 5920 est donc une utile lecture, ainsi que
la section 5 du RFC 5036. LDP (sections
2.4, 3.1 et 4.1 de notre RFC) peut, lui, fonctionner sur TCP ou sur UDP. Ce
dernier sert notamment aux messages Hello
d'établissement d'une session. Cet établissement n'est donc pas
protégé par les mesures de sécurité de TCP. En fait, il n'existe même
quasiment aucune protection pour ces messages.
Et pour TCP ? LDP peut utiliser l'authentification MD5 du RFC 2385 mais on a vu que MD5 n'était pas conseillé
(RFC 6151 et section 2.9 du RFC 5036) et LDP ne permet pas encore d'utiliser AO (RFC 5925).
L'état de sécurité idéal pour LDP serait clairement un état où les
messages Hello
seraient authentifiés. En
attendant, les contre-mesures minimales sont de n'accepter des
Hello
que sur les interfaces réseau qui en ont
réellement besoin, et d'utiliser GSTM. Cela ne supprime pas toutes les
attaques, mais un travail est déjà en cours pour l'authentification
des Hello
(Internet-Draft draft-zheng-mpls-ldp-hello-crypto-auth
).
Date de publication du RFC : Mai 2013
Auteur(s) du RFC : M. Tuexen (Muenster Univ. of Appl. Sciences), R. R. Stewart (Adara Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 30 mai 2013
Normalement, un nouveau protocole de transport comme SCTP ne devrait avoir besoin de l'autorisation de personne pour être déployé entre deux machines majeures et consentantes. Le modèle de l'Internet, fondé sur le protocole IP, permet aux machines terminales, sans autorisation d'un intermédiaire, de communiquer en mettant ce qu'elles veulent dans les paquets IP. Cela, c'est la théorie. En pratique, par incompétence, sécurité ultra-rigide ou paresse, des tas d'intermédiaires se permettent de se placer sur le chemin entre deux machines et ne laissent passer qu'un petit nombre de protocoles de transport (typiquement uniquement TCP et UDP). Un nouvel arrivé (SCTP a quand même été normalisé dans le RFC 2960 en 2000 donc, « nouveau » est relatif ; la norme actuelle est le RFC 4960) a donc le plus grand mal à se faire une place au soleil. On en est donc réduit à des astuces plus ou moins propres comme celle décrite dans ce RFC : encapsuler SCTP dans de l'UDP.
La principale cible visée est donc le grand nombre de machines coincées derrière un routeur NAT. Mais cette encapsulation peut aussi servir pour mettre en œuvre SCTP sans avoir accès au noyau, entièrement dans une application, sans avoir de privilèges particulier (ce qui est souvent nécessaire pour implémenter un protocole de transport). Attention, il ne s'agit pas de faire un tunnel pour mettre en relation deux réseaux, mais de faire communiquer deux machines terminales qui voudraient faire du SCTP et qui en sont empêchées par une middlebox (cf. section 4).
Pourquoi UDP, au fait, et pas TCP ? Parce que SCTP fournit tous les services de TCP (notamment le contrôle de congestion et la fiabilité) et qu'il ferait donc double emploi avec TCP.
Notez que rien n'empêcherait de faire un routeur NAT qui permettrait SCTP, comme ils permettent aujourd'hui de faire du TCP et de l'UDP. C'est juste que de tels routeurs, s'ils existent, sont très rares.
Bon, et comment SCTP sur UDP fonctionne (section 5) ? On utilise par défaut le port de destination et de source 9899. Toutefois, celui-ci aura pu être modifié en route par un routeur NAT et le port à l'arrivée sera donc peut-être différent. D'autre part, certaines machines peuvent se trouver dans l'obigation d'écouter sur un autre port et il faut donc qu'une mise en œuvre de ce RFC soit capable d'utiliser un port différent par correspondant (cf. l'API plus loin), et de se souvenir de ces ports. On met le paquet SCTP dans un paquet UDP qui sera lui-même transporté dans IP (peut-être avec des en-têtes d'extension, dans le cas d'IPv6). La somme de contrôle UDP doit être mise (même en IPv4 où elle est normalement facultative ; et, pour IPv6, on n'a pas le droit d'utiliser l'exception du RFC 6935).
C'est simple mais il y a quelques petits pièges. D'abord, avec les messages ICMP (section 5.5) : lors de leur réception, il n'y aura pas forcément assez d'octets du message original pour trouver l'association SCTP à qui envoyer le message ICMP. Il faudra alors jeter ce dernier sans remords. La mise en œuvre de SCTP doit donc être capable de se débrouiller sans les messages ICMP, dont la réception ne peut pas être garantie.
Deuxième piège, commun à toutes les techniques d'encapsulation, la MTU (section 5.6). SCTP doit penser à diminuer la MTU de la taille de l'en-tête UDP. Et se souvenir qu'ICMP est encore moins garanti lorsqu'on utilise l'encapsulation UDP donc les procédures de découverte de la MTU du chemin (RFC 4820, RFC 4821 et surtout RFC 8899) doivent fonctionner même si on ne reçoit pas les messages ICMP.
Dernier piège, mais crucial, le contrôle des adresses IP source
des paquets UDP. Pour les associations SCTP à une seule adresse IP, il ne faut
pas indiquer l'adresse IP de la machine dans les
sous-paquets (chunks) de type INIT
(section 3.3.2 du RFC 4960) mais la mettre dans
le paquet UDP (ce que fait UDP par défaut). Et si la machine a
plusieurs adresses IP, il faut se servir des mécanismes des RFC 5061 et RFC 4895 pour les faire connaître au correspondant, et non pas mettre les adresses IP dans les sous-paquets
SCTP car l'intervention d'un routeur NAT modifierait l'adresse source,
rendant ces sous-paquets invalides.
Et pour les applications, quels mécanismes sont nécessaires pour
faire fonctionner cette encapsulation ? La section 6 propose des
changements à l'API du RFC 6458, avec l'ajout d'une option
SCTP_REMOTE_UDP_ENCAPS_PORT
qui prendra en
paramètre une structure :
struct sctp_udpencaps { sctp_assoc_t sue_assoc_id; struct sockaddr_storage sue_address; uint16_t sue_port; };
Ce qui permettra de définir/connaître les adresses IP et les ports utilisés par l'encapsulation UDP.
Depuis sa version 9.1, FreeBSD a la capacité
d'utiliser cette encapsulation pour envoyer des paquets SCTP. Un
portage a été fait vers Mac OS X, disponible en
http://sctp.fh-muenster.de
.
Date de publication du RFC : Octobre 2013
Auteur(s) du RFC : J. Peterson (NeuStar), O. Kolkman (NLnet Labs), H. Tschofenig (Nokia Siemens Networks), B. Aboba (Microsoft Corporation)
Pour information
Première rédaction de cet article le 10 octobre 2013
Le DNS est un des plus grands succès de l'Internet : une base de données répartie, fiable, sur laquelle on peut compter, et qui est très souple dans ses usages, lui permettant d'être utilisée pour beaucoup de choses (seuls les journalistes écrivent encore que « le DNS sert à trouver une adresse IP à partir d'un nom de domaine » : la réalité est bien plus riche). Mais, justement, la disponibilité et l'efficacité du DNS font qu'il est utilisé par beaucoup d'applications dont les auteurs ne sont pas forcément conscients des forces et faiblesses du DNS. Ne faudrait-il pas les appeler à réfléchir deux secondes sur ces forces et ces faiblesses ?
Le DNS permet de récupérer des données (quelconques : ce ne sont pas forcément des adresses IP) à partir d'un nom de domaine. Il est même utilisé par des applications dont les identifiants ne sont pas des noms de domaine : une petite transformation pour convertir l'identifiant en nom de domaine et hop (ONS, ENUM, etc). Le premier RFC à avoir décrit l'usage du DNS pour autre chose qu'une correspondance nom->adresse est le RFC 974 en 1986. C'est dire que c'est ancien et cela explique mes critiques sévères des ignorants qui continuent à considérer le DNS comme un simple moyen de trouver des adresses. Depuis ce RFC 974, qui introduisait l'enregistrement MX, l'idée a suivi son chemin. Un mécanisme plus général, le SRV, a été introduit par le RFC 2052 (remplacé depuis par le RFC 2782). Et, pour faire des mécanismes de délégation aussi compliqués qu'on le souhaite, il y a le NAPTR créé par le RFC 2168, généralisé ensuite par le RFC 3401. Enfin, il y a des applications qui mettent simplement leurs données dans le très général et pas structuré enregistrement TXT, ce que fait par exemple DKIM (RFC 6376).
Mais ce succès, comme tous les succès, a aussi son revers : les applications demandent de plus en plus au DNS alors que son vaste déploiement est largement dû à sa focalisation sur un petit nombre de fonctions qu'il réalise très bien. La mentalité fréquente aujourd'hui de « on met tout dans le DNS » (illustrée par un gadget fameux) est parfois en conflit avec les principes du DNS. La confidentialité est un bon exemple : elle était délibérement exclue du cahier des charges du DNS (et à juste titre : lisez le RFC 3414 si vous voulez un exemple de la complexité que la confidentalité apporte à un protocole requête-réponse). Vouloir l'ajouter aujourd'hui risque fort de faire perdre au DNS ses propriétés intéressantes (il n'est pas cité par ce RFC, mais c'est l'une des raisons de l'échec de DNScurve, qui essayait de faire trop de choses). Bien des applications qui veulent utiliser le DNS ont réclamé une certaine dose de confidentialité, alors que le DNS doit une partie de son efficacité au fait que toutes les données sont publiques. Ainsi, un cache n'a pas à s'inquiéter si les données qu'il mémorise doivent être servies à tous ou pas.
Ce nouveau RFC de l'IAB vise donc à aider les concepteurs d'applications en exposant clairement ce que le DNS fait bien, ce qu'il peut faire, et ce qu'il ne sait pas faire. C'est un excellent document pour qui veut comprendre en détail le DNS et, malgré sa longueur, il mérite d'être lu attentivement. Il fournit les informations nécessaires pour que ledit concepteur puisse répondre intelligemment à la question « Dois-je mettre cette information dans le DNS ou bien ailleurs ? » Il complète le RFC 5507, qui restait plutôt sur les questions de syntaxe, alors que ce nouveau RFC 6950 adopte une vue plus générale, plus tournée vers l'architecture du système. Pour le résumer en deux mots : le DNS doit son succès à ce qu'il n'essaie pas de résoudre tous les problèmes mais un ensemble bien précis de problèmes, pour lesquels il est une bonne solution. Comme il existe d'autres protocoles que le DNS, une application ou un service qui envisage d'utiliser le DNS dit sérieusement étudier s'il est vraiment la solution la plus adaptée (parfois oui mais parfois non).
La section 2 de notre RFC présente un certain nombre d'usages du
DNS par des applications. Il commence évidemment par le routage du
courrier, avec les enregistrements
MX. Le MX était la première utilisation du DNS pour faire
autre chose que de la simple traduction de nom en adresse IP. En
partie droite d'un MX, on trouve le nom du ou des serveurs qui gèrent
la messagerie pour le domaine en partie
gauche. Bien sûr, une convention de nommage (du
genre « le serveur de messagerie de example.org
se nomme mail.example.org
») aurait pu jouer un
rôle similaire. Mais les MX sont plus souples (le serveur d'un domaine
n'est pas obligé d'avoir un nom dans le domaine, cf. RFC 4367) et offrent des
possibilités supplémentaires (plusieurs serveurs, avec des priorités
différentes). Mais le MX est spécifique au courrier électronique. Les
enregistrements SRV, créés par le RFC 2052 (aujourd'hui RFC 2782), ont étendu le principe à
tous les protocoles qui voulaient en profiter (avec des choses en plus
comme l'indication du numéro de port ou bien
comme la répartition de charge). Tous les
protocoles créés depuis utilisent ces enregistrements, à la triste
exception de HTTP qui, stupidement (l'avis est
le mien, il n'est pas dans le RFC), ne fournit
pas de mécanisme pour trouver le serveur d'un domaine (obligeant à
utiliser des conventions de nommage comme
www.example.com
ou, pire, à mettre une adresse IP
sur le domaine lui-même, et empêchant d'utiliser le DNS pour la
répartition de charge et la résilience, ce qu'auraient permis les SRV).
Autre service fourni aux applications par le DNS, les
enregistrements NAPTR. L'idée au début était de
pouvoir trouver n'importe quel identificateur, même distinct d'un nom
de domaine, dans le DNS (RFC 2915). Les NAPTR permettent de
spécifier des transformations complexes depuis une famille
d'identificateurs, vers les noms de domaine. L'idée est ancienne. Sa
première manifestation avait été le domaine
in-addr
dans le RFC 883 (c'était un TLD à l'époque, il est
devenu in-addr.arpa
dans
le RFC 973). Son but était de permettre de traduire des
adresses IP en noms, en convertissant d'abord l'adresse IP en un nom
de domaine se terminant en in-addr
. Ce genre de
transformation textuelle sur un identificateur pour en faire un nom de
domaine a ensuite été reprise par tpc.int
(RFC 1530, un
mécanisme pour router des appels téléphoniques via l'Internet, qui
allait déboucher sur ENUM). Ces mécanismes ne
changent pas le protocole DNS mais ils changent la manière dont on se
sert du DNS, et apportent de nouveaux utilisateurs, ayant de nouvelles attentes.
Une des demandes de ces « nouvelles » applications est de stocker des données quelconques dans le DNS. On peut mettre ce qu'on veut dans un URI (et même directement des données, cf. RFC 2397). Donc, comme un NAPTR mène à un URI, il peut nous mener à n'importe quoi. Mais, avant même cette astuce, le DNS pouvait déjà stocker n'importe quoi. Il existe même un type d'enregistrement, TXT, spécialement prévu pour des données non structurées. La souplesse du TXT et son absence de contraintes ont attiré plein de gens, malgré les conseils de prudence du RFC 5507. Il y a même eu une proposition de structurer le contenu des TXT (RFC 1464).
Bon, mais qui y a-t-il de mal à ce que les gens se servent du DNS pour y mettre des informations ? En combinant les différentes techniques vues ci-dessus, on pourrait faire tenir n'importe quel protocole requête/réponse dans le DNS. Mais ce n'est pas complètement exact. La section 3 décrit les défis auxquels son succès confronte le DNS. Certes, le DNS est une base de données répartie, fiable, et rapide. Mais lorsqu'on dit « base de données », certains utilisateurs voudraient que le DNS fournisse des services classiques des bases de données, comme la confidentialité, le contrôle d'accès, l'introspection (utiliser le protocole d'accès pour découvrir le schéma) et la possibilité de requêtes structurées complexes, un peu comme ce que fournit SQL. Mais le DNS n'a pas été conçu pour cela et ce RFC argumente que, plutôt que de forcer le DNS à fournir ces services, on utiliserait mieux son temps à développer d'autres protocoles ou tout simplement à utiliser d'autres protocoles existants. Le succès du DNS et ses qualités viennent justement de ce qu'il n'essayait pas de tout faire.
Les exemples donnés par le RFC sont tous empruntés au monde ENUM (RFC 6116) mais les questions soulevées ne sont pas spécifiques à ENUM.
D'abord, les critères de recherche : dans le DNS, la clé d'accès
est le triplet {nom de domaine, classe, type}, par exemple (en syntaxe
dig) www.afnic.fr. IN
AAAA
, et la correspondance doit être exacte (pas de
recherche floue). Or, certains souhaiteraient pouvoir exprimer des
requêtes plus riches. Des tentatives ont été faites pour mettre des
critères supplémentaires dans le nom de domaine lui-même (par exemple,
pour ENUM, tg011.0.0.4.5.4.3.4.1.7.5.1.e164.arpa
pour ajouter au nom normal,
0.0.4.5.4.3.4.1.7.5.1.e164.arpa
, qui est dérivé
du numéro de téléphone, le
trunk group
tg011
) mais cela devient vite pénible lorsque le
nombre de critères augmente.
Autre solution envisagée, EDNS (RFC 6891), en passant les critères supplémentaires comme options EDNS. Mais cela ne marche pas comme certains le prévoient car EDNS est de saut en saut et pas de bout en bout : un serveur DNS relais ne va pas transmettre les options EDNS.
Enfin, les requêtes complexes posent un problème pour les caches, si fréquents avec le DNS. Les caches actuels considèrent que la réponse ne varie qu'avec le triplet {nom de domaine, classe, type} et pourrait donc garder en cache à tort des réponses faites à des requêtes plus complexes.
Autre demande fréquente des nouveaux utilisateurs du DNS, avoir des
réponses « à la tête du client », dépendant de l'émetteur de la
question. Il est par exemple courant aujourd'hui de servir des réponses
différentes selon l'adresse IP de la source (option
view
de BIND). Tant que cela ne sert
qu'à présenter des versions adaptés d'un contenu (un
portail Web différent selon le pays d'origine
de la requête), sans problème de sécurité, ce n'est pas trop grave :
une erreur n'aura pas de conséquences trop ennuyeuses. Pour des cas
plus sensibles, cela peut être gênant. D'autant plus que l'adresse IP
de la source n'est pas celle du vrai client, mais celle du résolveur
qu'il utilise. Dans certains cas (Google
Public DNS), la distance entre les deux peut être énorme. Une
option EDNS a été proposée pour que le résolveur puisse indiquer au
serveur faisant autorité la vraie adresse IP du client mais elle n'est
pas encore adoptée (entre autres, elle pose des problèmes si le client
a une adresse IP privée, genre RFC 1918).
Le DNS a d'autres limites lorsqu'on veut l'utiliser comme base de
données générique, par exemple la taille des noms de domaine (limitée
à 63 caractères par composant) et la taille des réponses. Quelle
limite de taille ? L'ancienne limite de 512 octets n'est normalement
plus qu'un souvenir (mais il existe encore des
pare-feux bogués ou mal gérés qui imposent
cette limite) mais il y a deux autres seuils derrière, la
MTU (si la réponse est plus grosse, on risque
de la fragmentation) et les 4 096 octets qui
sont, en pratique, la limite de la plupart des serveurs. Si la réponse
est un URI, notez que le RFC 2397 sur les URI
data:
indique que ceux-ci doivent être « courts »
mais il ne définit pas cet adjectif. Le RFC note que, dans le contexte
d'ENUM, stocker des sonneries de téléphone rigolotes sous forme de
fichiers MP3 dans un URI
data:
n'est probablement pas raisonnable.
En outre, le DNS reposant sur UDP, qui ne
garantit pas l'adresse IP source, des données de grande taille
augmentent les risques d'attaque avec amplification (RFC 4732, section 3). Dans ces attaques, le méchant
émet une requête DNS (de petite taille, donc) en usurpant l'adresse IP
source de sa victime. Le serveur va alors répondre à celle qu'il croit
être l'émetteur et la réponse est souvent bien plus grande que la
question (le RFC cite l'exemple d'un certificat stocké dans le DNS,
comme dans le RFC 4398). L'attaquant pourra donc obtenir
ainsi un trafic plus important que ce qu'il peut lui-même
générer. C'est d'ailleurs une des raisons pour lesquels les serveurs
de .com
, par exemple,
limitent leurs réponses à 1 460 octets. Bref, malgré EDNS, on ne peut
pas espérer faire passer dans le DNS des données de taille
quelconque. Le DNS est prévu pour des informations courtes.
Autre limite du DNS lorsqu'on essaie de s'en servir comme d'une base de données générique, la non-correspondance des frontières administratives avec celles du DNS : les frontières des composants d'un nom de domaine ne sont pas forcément celles qu'on voudrait. Par exemple, pour la téléphonie, les anciennes numérotations étaient très hiérarchiques (et correspondaient donc bien au DNS) alors que, depuis la portabilité des numéros de téléphone, ce n'est plus le cas et il n'est donc pas évident de savoir où déléguer les noms ENUM. Ce n'est pas juste un problème esthétique : le bon fonctionnement du DNS dépend des délégations qui sont « cachées » (gardées en mémoire) dans les résolveurs, et qui épargnent à la racine la grande majorité des requêtes. Avec la portabilité des numéros téléphoniques, il faut interroger la racine ENUM pour tout numéro (puisqu'on ne peut pas savoir à l'avance quel opérateur téléphonique le gère). C'est d'autant plus ennuyeux pour la racine ENUM que les correspondances entre un numéro et un opérateur changent et qu'on souhaite souvent une portabilité rapide (de l'ordre de quinze minutes), peu compatible avec une racine simple et efficace.
Si vous pensez que ce n'est pas si grave, que
.com
est un espace plat
avec de nombreux noms et des changements rapides, ce qui démontre que
le DNS peut s'en tirer, pensez que dans les seuls
États-Unis, il y a trois cents millions de
numéros de téléphone attribués, trois fois la taille de
.com
.
Le problème n'est évidemment pas spécifique à ENUM : si on créait
un mécanisme de portabilité pour les adresses IP, les domaines comme
in-addr.arpa
auraient les mêmes problèmes.
La section 4 est entièrement consacrée à un problème particulier
qui a fait couler beaucoup d'encre, le désir d'avoir des réponses DNS
« à la tête du client ». Officiellement, le DNS présent une vue unique
à tous les utilisateurs (ce point est développé dans le RFC 2826) qui affirme que les noms doivent être
uniques et donc donner un résultat unique. Mais il existe une forte
demande pour avoir des noms qui ne fonctionnent que dans un espace
privé (à l'intérieur d'une entreprise, par exemple), afin de limiter
l'accès à certaines ressources. Il existe plusieurs solutions
techniques pour avoir des réponses différentes en local et en public
mais aucune n'est parfaitement satisfaisante. Par exemple, si on
utilise des noms locaux avec un TLD bidon comme
.prive
ou .local
, ces noms
« fuiront » un jour ou l'autre, seront vus à l'extérieur, ce qui
générera de la confusion (section 3.3 du RFC 5507).
Bien, après toutes ces critiques et toutes ces limites du DNS, quels conseils pratiques donner à ceux et celles qui voudraient quand même utiliser le DNS ? La section 5 est composée d'excellents conseils pour les développeurs d'applications ou de services utilisant le DNS. En gros, le DNS sera sans doute une bonne solution si le service qui veut l'utiliser a toutes ces propriétés :
Si une seule de ces propriétés manque, le DNS n'est peut-être pas la bonne solution pour le problème. À l'inverse, de bons signaux d'alarme, indiquant qu'on utilise le DNS à tort, sont :
Bon, mais si on n'utilise pas le DNS, alors quoi ? Le RFC suggère que, dans beaucoup de cas de protocole requête/réponse, HTTP convient parfaitement (par exemple, il a de l'authentification, il peut transporter des données de taille quelconque, il est largement déployé...)
Pendant l'élaboration de ce RFC, des commentaires intéressants ont été enregistrés dans le système de suivi des tâches.
Date de publication du RFC : Mai 2013
Auteur(s) du RFC : H. Flanagan (RFC Series Editor), N. Brownlee (Independent Submissions Editor)
Pour information
Première rédaction de cet article le 15 mai 2013
Cela fait longtemps que le format des RFC est critiqué, à l'IETF ou ailleurs. Pour d'excellentes raisons (détaillées plus loin), ce format est très ancien et très rigide, sans concessions aux gadgets modernes. Il n'a pas encore été possible de le modifier, à la fois en raison des difficultés de prise de décision au sein de la communauté, et aussi parce que le problème est réellement difficile. Contrairement à ce que prétendent certains yakafokon, trouver un format idéal n'est pas trivial. Ce RFC est la première étape d'une tentative de réforme, commençant par un cahier des charges sur les changements souhaitables. Les règles rigides de formatage (longueur des pages et des lignes) disparaissent, l'Unicode fait son entrée dans les RFC, et la possibilité d'inclure des images apparait.
Une des raisons de la stagnation du projet de changement depuis des années était la réorganisation de la fonction de RFC Editor. Désormais, les nouvelles règles sur cette fonction sont écrites (RFC 6635), une nouvelle RFC Editor a pris ses fonctions, jeune et dynamique (Heather Flanagan, un des auteurs de ce RFC), et il va peut être être enfin possible de faire évoluer le format traditionnel. (Depuis cet article, le nouveau format des RFC a été adopté, cf. RFC 7990.)
Le format actuel est documenté dans le RFC 7322 mais à l'époque de notre RFC, c'était le RFC 2223 qui s'appliquait : texte brut sans enrichissement, en ASCII, pages de 58 lignes, lignes de 72 caractères au maximum, pas de notes de base de page, références croisées par numéro de section et pas de page, etc. PostScript était autorisé et quelques RFC ont été publiés ainsi. Une tentative de mise à jour de ce RFC, avec écriture d'une proposition de nouvelle version, avait eu lieu en 2004 mais avait été abandonné. J'avais déjà écrit un article détaillé expliquant le pourquoi du format traditionnel et les raisons pour lesquelles il est difficile à changer.
La section 1 de ce RFC commence par rappeler la longue histoire des RFC. Ils ont commencé il y a plus de quarante ans, et dans les débuts, certains étaient écrits à la main (!), d'autres tapés à la machine, d'autres encore produits par les outils de formatage invraisemblables qu'on trouvait sur les mainframes de l'époque. Résultat, certains sont devenus illisibles avec le temps, les outils tombant en désuétude. Ce problème de permanence est un des problèmes les plus cruciaux pour les RFC et explique pourquoi le RFC Editor n'a jamais été très chaud à l'idée d'utiliser le logiciel à la mode du moment : l'informatique en a déjà enterré beaucoup.
Au bout d'un moment, un format standard a émergé, fondé sur du texte brut et un encodage en ASCII. À partir de là, la série des RFC a vécu une longue période de calme et de stabilité et cette permanence (songez aux formats à la mode vite disparus comme WordPerfect) a beaucoup contribué à son succès. On peut relire aujourd'hui sans problème un RFC de 1980 comme le RFC 768. Ce n'est pas que le format ait été jugé parfaitement satisfaisant par tout le monde, ni qu'aucune proposition de changement n'ait été faite, bien au contraire. Mais aucun des ces propositions n'a connu de consensus : toutes résolvaient un problème précis... en en créant plusieurs autres.
Avant de regarder les propositions actuellement sur la table, il faut bien comprendre qu'il y a plusieurs endroits dans le cycle de vie d'un RFC où un format standard est nécessaire ou utile. Cette terminologie est très importante car l'incompréhension de ces étapes du cycle de vie est l'une des causes principales de la confusion des débats sur la réforme des RFC :
http://tools.ietf.org
par exemple voici ce RFC), du PDF formaté différemment, etc.Évidemment, les choses ont changé depuis (le RFC 2223 date de seize ans...) Quels sont les points qui suscitent le plus de protestations ? D'abord, l'utilisation d'art ASCII et lui seul pour les graphiques. Elle a l'avantage d'encourager les auteurs à écrire des descriptions textuelles claires, plutôt que de passer du temps à faire de jolis dessins. Sans les limitations de l'art ASCII, les diagrammes seraient probablement moins concis. D'un autre côté, des choses comme les automates finis sont vite illisibles en art ASCII et les protocoles où il y a plus de trois acteurs qui interagissent sont difficiles à dessiner. Des graphiques plus élaborés que l'art ASCII permettraient également de représenter des équations mathématiques complexes.
Après les images, le sujet le plus chaud est évidemment l'encodage. ASCII a des tas d'avantages : standard, très répandu, facile à manipuler (outils de recherche, par exemple), plus pratique lorsqu'il faut renumériser un document (oui, le cas s'est déjà produit dans le passé)... Et la langue des RFC étant de toute façon l'anglais, les limites d'ASCII ne sont pas trop graves.
Mais il y a quand même des limites : lorsqu'un RFC parle
d'internationalisation (comme le RFC 5890 ou le
RFC 6530, ou comme de plus en plus de normes), c'est bien dommage de ne pas pouvoir
donner d'exemple lisible dans ce RFC. Devoir écrire
U+00c9
pour parler de É
est
pénible... Des exemples comme ceux de XMPP
(RFC 6121, section 5.2.3) bénéficieraient de
l'acceptation d'Unicode dans les RFC.
Et certains auteurs de RFC ont des noms qui ne peuvent pas s'écrire correctement en ASCII et ils regrettent de devoir les modifier.
Autres points sur lesquels des gens ont souvent râlé contre le format actuel : la pagination et l'ajustement du texte. La pagination en unités fixes fait vraiment rétro : elle avait un sens quand les RFC étaient souvent imprimés pour être lus mais à l'ère des tablettes, cela semble bien dépassé. Plus compliqué est le cas de l'ajustement du texte. La largeur de colonne fixe qui est la norme actuelle convenait aux VT100 mais pas aux écrans modernes, avec leurs tailles très variables.
Enfin, ce n'est pas tout de définir des formats, il faut aussi des outils qui rendent la production de RFC conforme à ces formats facile (pour avoir une idée des difficultés, lire le RFC 5385). Ces outils doivent-ils être développés à l'IETF ou bien doit-on utiliser des outils standard ? Les exigences de l'IETF sont-elles tellement spécifiques qu'on ne puisse pas utiliser des outils existants ? D'un autre côté, les outils spécifiques donnent plus de souplesse et de pouvoir et, aujourd'hui, il en existe déjà beaucoup (par exemple, la version 2 de xml2rfc - une réécriture complète, abandonnant TCL pour Python, pour produire des RFC suivant le schéma du RFC 7749, est bien meilleure que la précédente) donc on peut dire que le modèle « faisons tout nous-même » marche bien (il y a beaucoup d'informaticiens à l'IETF).
Enfin, s'il y a des réclamations des lecteurs et des auteurs, il y en a aussi du RFC Editor : il voudrait pouvoir abandonner nroff (65 % des RFC aujourd'hui sont soumis au format XML, qu'il faut traduire en nroff au lieu de l'utiliser directement comme format d'entrée pour les différentes publications).
Après les contraintes et les réclamations, les décisions (section 3). D'abord, ce qui ne change pas :
Ensuite, les nouvelles exigences effectivement retenues, notamment :
Et il y a aussi des exigences qui ont été supprimées :
Voilà, le cahier des charges est posé, il reste à définir le
nouveau format, développer les outils, et déployer le tout... Ce sera
pour le prochain épisode. À la réunion IETF 86 a été annoncé
le choix de s'appuyer sur le format XML comme format canonique, avec
comme formats de publication le texte brut, HTML, PDF et
EPUB (voir la FAQ sur ces décisions.)
Deux Internet-Drafts sont
en cours, un sur le format, draft-rfc-format-flanagan
,
et un sur le style, draft-flanagan-style
. (Depuis,
le premier draft a été publié, RFC 7990.)
Date de publication du RFC : Juillet 2013
Auteur(s) du RFC : A. Keranen, J. Arkko (Ericsson)
Pour information
Première rédaction de cet article le 18 juillet 2013
Le World IPv6 Day le 8 juin 2011 avait pour but de tester le comportement d'IPv6 si de nombreux services sur l'Internet activaient ce protocole. On peut noter que rien de spectaculaire ne s'est produit (tant mieux : comme prévu, cette activation n'a rien cassé) mais les impressions ne suffisent pas, il faut aussi mesurer ce qui s'est passé. C'est une de ces mesures que raconte ce RFC ; ses auteurs ont compté le nombre de sites Web qui activaient IPv6 et le résultat que cela avait sur le temps d'établissement d'une connexion, pour un client qui avait déjà IPv4 et IPv6.
Pourquoi est-ce que, alors qu'IPv6 est normalisé depuis de nombreuses années (RFC 2460), certains gros acteurs de l'Internet hésitent toujours à l'activer ? Les raisons vont de la simple passivité à la crainte que, dans certains cas, l'activation d'IPv6 ne dégrade le vécu de l'utilisateur (RFC 6555). Le but des IPv6 days (il y en avait d'autres avant celui de 2011 et d'autres sont apparus après) est à la fois d'encourager les frileux, et de tester pendant 24 h si les craintes sont justifiées (l'IPv6 Day de 2012, considérant que les tests avaient été suffisants et n'avaient guère montré de problèmes, était au contraire prévu pour qu'IPv6 reste activé). Pendant 24 h, le 8 juin 2011, un certain nombre d'opérateurs de services Internet ont donc configuré leurs services pour répondre en IPv6, leur permettant de tester que tout allait bien, et d'avoir une idée du pourcentage de leurs utilisateurs prêts à faire de l'IPv6. Cette configuration impliquait l'activation du protocole sur les différents équipements : serveurs, bien sûr, mais aussi applications car celles-ci gèrent parfois des adresses IP, par exemple à des fins de statistiques, et également les diverses middleboxes qui sont en général le maillon faible de la connectivité Internet.
Une fois qu'IPv6 était disponible et testé sur le service (normalement, bien avant le grand jour), il n'y avait plus qu'à le faire savoir au reste du monde, ce qui se fait en publiant un enregistrement AAAA dans le DNS.
Les mesures décrites dans ce RFC étaient donc le pourcentage de domaines avec des enregistrements AAAA et le temps pris à établir une connexion avec le serveur (ainsi que le pourcentage d'échecs).
Comme l'Internet est grand, l'étude de ce RFC s'est limitée 10 000 sites Web les mieux placés dans le
classement d'Alexa (section 3 du RFC). Pour
chaque domaine, le logiciel a fait une requête DNS AAAA pour
ledomaine
, www.ledomaine
, et
aussi des noms spécifiques à IPv6 comme
www.ipv6.ledomaine
(noms peu susceptibles d'être
utilisés par le visiteur moyen). Ce logiciel de mesure active était
écrit en Perl avec le module Net::DNS
. Ensuite, un petit programme en
C tentait une connexion TCP vers l'adresse
obtenue et mesurait le délai. Les mesures ont commencé une semaine
avant l'IPv6 day et se sont terminées trois jours
après. Le client était situé dans les locaux
d'Ericsson à
Helsinki.
Quels ont été les résultats ? La section 4 donne les valeurs obtenues, avec des liens vers des graphiques externes (les RFC ne permettent pas de mettre d'images). Le pourcentage d'enregistrements AAAA est ainsi passé de 2,45 % une semaine avant le grand jour et a culminé à 4,91 % pendant. Il est ensuite redescendu (contrairement à 2012, il n'était pas demandé aux sites de garder leurs AAAA), mais est resté plus élevé qu'avant le jour IPv6. Si on prend seulement les 100 sites les mieux classés par Alexa, on trouve la même courbe mais des pourcentages bien plus élevés (les gros sites sont plus sérieux pour ce qui concerne IPv6).
Ce n'est pas tout de publier des adresses IPv6. Encore faut-il que le serveur HTTP situé derrière réponde effectivement. Si on teste toutes les adresses (v4 et v6) en TCP vers les ports 80 et 443, on trouve entre 1 et 3 % d'échecs. Pour IPv6 seul, le pourcentage d'échec est bien plus élevé. Cela ne recoupe pas les résulats vus par DNSdelve (qui montrent nettement moins d'échecs de connexion) probablement parce qu'il s'agit ici d'une journée exceptionnelle, que tout le monde n'a pas bien préparé. Apparemment, certains ont publié leur AAAA avant de configurer leur serveur, leurs routeurs et leurs pare-feux (notez la baisse du pourcentage d'échecs au fur et à mesure que la journée avance).
Et si TCP marche, OK, mais marche-t-il vite ? La connexion prend t-elle plus ou moins de temps en IPv4 et en IPv6 ? Après tout, autrefois, en raison de l'utilisation de mauvaises technologies comme 6to4 (RFC 3056 et RFC 7526) ou comme des tunnels amateurs, IPv6 avait la réputation d'être lent. Qu'en est-il aujourd'hui ? En prenant la médiane et la moyenne, on voit que la différence est très faible (même pour la moyenne, pourtant plus sensible aux petites variations), et qu'IPv6 est un peu plus rapide en temps normal mais plus lent pendant le jour IPv6 (sans doute parce que l'arrivée de nombreux sites mal configurés a fait baisser les chiffres).
En conclusion, le jour IPv6 de 2011 n'a pas été inutile. Le RFC estime qu'avant celui de 2012, il a été une des journées où l'Internet avait changé le plus. Mais les utilisateurs ordinaires n'ont rien remarqué, ce qui était justement le but. Même ceux qui mesurent les temps de connexion n'auront guère vu de différences. Le principal problème est le nombre trop élevé de sites qui publient un AAAA mais avec qui la connexion IPv6 échoue.
Autres mesures équivalentes :
.fr
annonçant un
enregistrement AAAA pour leur serveur Web,Date de publication du RFC : Mai 2013
Auteur(s) du RFC : F. Gont (Huawei)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 15 mai 2013
Dernière mise à jour le 20 juin 2013
Une particularité amusante de la gestion de la fragmentation dans IPv6 est qu'un paquet peut très bien avoir un en-tête de fragmentation sans être fragmenté du tout. Cela se nomme un « fragment atomique » (le terme est très malheureux car il n'a rien à voir avec les « datagrammes atomiques » du RFC 6864). Ils n'ont aucun intérêt pratique mais sont engendrés par certains systèmes lorsqu'ils reçoivent un message ICMP Packet too big indiquant une MTU inférieure à 1280 octets (la taille miminale pour une MTU IPv6). Le problème est que ces fragments atomiques sont ensuite traités par bien des systèmes comme des vrais fragments, permettant ainsi certaines attaques subtiles. Ce nouveau RFC demande donc que les fragments atomiques soient gérés à part, compte tenu de leurs particularités. (Depuis, le RFC 8021 a carrément rendu ces fragments atomiques obsolètes.)
Si vous voulez réviser les règles de la fragmentation dans IPv6, c'est dans le RFC 2460 (depuis remplacé par le RFC 8200, qui a changé ces règles). Contrairement à IPv4, seules les machines de départ (pas les routeurs intermédiaires) peuvent fragmenter. Si une machine de départ doit envoyer un paquet qui est trop grand pour la MTU, elle le fragmente en plusieurs morceaux, chaque morceau indiquant son décalage par rapport au début du paquet original. Même si ce n'est pas explicite dans ce RFC, le recouvrement des fragments était autorisé, ce qui complique sérieusement le réassemblage et pouvait permettre d'échapper à certains IDS. Il n'est donc pas étonnant que le RFC 5722 ait finalement interdit ces fragments recouvrants. Bon, et les fragments atomiques, ils sont fabriqués pourquoi ? La section 5 du RFC 2460 ne laissait pas le choix aux mises en œuvre d'IPv6 : normalement, elles devaient fabriquer un fragment atomique (un paquet qui a l'en-tête de fragmentation, sans pour autant être fragmenté) si la taille indiquée par le paquet ICMP est inférieure aux 1280 octets minimaux d'IPv6 (c'est pour aider certains mécanismes de traduction IPv4<->IPv6). Dans un fragment atomique, le décalage (fragment offset) sera de zéro (puisque ce fragment est le premier) et le bit M sera à Zéro (puisque ce fragment est le dernier du datagramme). Comme ces paquets ICMP Packet too big ne sont pas authentifiés, même quand c'est possible (section 5.3 du RFC 4443 et RFC 5927), un attaquant peut donc faire fabriquer des fragments atomiques assez facilement. Notez que le RFC 8200 a changé cette règle et donc interdit les fragments atomiques.
Ensuite, comme bien des systèmes traitent ces fragments atomiques en même temps que les fragments normaux, ils peuvent, par exemple, être fusionnés avec d'autres fragments prétendant venir de la même source.
Les problèmes de sécurité liés aux fragments sont bien connus : voir notamment le RFC 5722 mais aussi le RFC 6274 qui décrit ces attaques pour IPv4 (beaucoup sont communes aux deux versions). Ce problème est encore aggravé par le fait que certains systèmes génèrent des identificateurs de fragment trop prévisibles, permettant à l'attaquant de savoir où il devra frapper.
La section 4 décrit ensuite les nouvelles règles, visant à résoudre ce problème. En deux mots, en recevant un fragment atomique (que l'on reconnait à la combinaison décalage=0 et bit M =0), on doit le traiter différemment des autres fragments et il ne peut être réassemblé qu'à partir du fragment unique.
L'annexe A contient un tableau listant un certain nombre de systèmes d'exploitation actuels en indiquant s'ils génèrent des fragments atomiques, et s'ils mettent en œuvre ce RFC (les traitent différemment des autres fragments). La plupart des systèmes génèrent ces fragments atomiques lorsqu'ils reçoivent le faux paquet ICMP Too big (une exception est NetBSD). Et plusieurs d'entre eux (Linux récent, NetBSD, OpenBSD) suivent déjà la recommandation de ce RFC et ne sont donc normalement pas vulnérables aux attaques décrites ici.
Si vous voulez tester vous-même, l'outil frag6 dans la boîte à outils SI6 permet de le faire facilement. D'abord, on envoie un fragment incomplet qui est le premier du datagramme :
# frag6 -v -i em0 --frag-type first --frag-id 1234 -d $MACHINE_UNDER_TEST
Dans une autre fenêtre, et avant l'expiration du délai de garde pour le réassemblage (60 secondes par défaut), on envoie un fragment atomique de même identificateur (1234 ici) :
# frag6 -v -i em0 --frag-type atomic --frag-id 1234 -d $MACHINE_UNDER_TEST
Si les fragments atomiques sont réellement traités à part (ce que notre RFC exige), ce qui est le cas sur un FreeBSD >= 9 ou un Linux >=> 3), le fragment atomique est « réassemblé » avec lui-même et on obtient une réponse :
ICMPv6 echo Reply from $MACHINE_UNDER_TEST (RTT: 5 seconds)
Si on n'a pas cette réponse, c'est que le système en face traite incorrectement les fragments atomiques avec les autres. Dans les deux cas, système correct ou non, le premier fragment ne sera jamais réassemblé et, au bout des 60 secondes, on aura :
Response from $MACHINE_UNDER_TEST: ICMPv6 Time Exceeded error message (Reassembly timeout: 60 seconds)
Et rappelez-vous que, normalement, les mises en œuvre d'IPv6 ne doivent plus générer de fragments atomiques depuis le RFC 8021.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : S. Rose (NIST)
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 2 mai 2013
Mais quel algorithme de cryptographie choisir pour mes signatures DNSSEC, se demande l'ingénieur système ? Il y a bien un registre IANA des algorithmes normalisés mais c'est juste une liste non qualifiée, qui mêle des algorithmes de caractéristiques très différentes. Ce nouveau RFC vise à répondre à cette question en disant quels sont les algorithmes recommandés. (Il a depuis été remplacé par le RFC 8624.)
La première liste d'algorithmes possibles avait été faite dans le RFC 4034. D'autres algorithmes avaient été ajoutés par la suite. Certains sont devenus populaires. Par exemple, RSA avec SHA-2 est utilisé pour presque tous les TLD importants et est donc difficilement contournable pour un résolveur validant. D'autres ont été peu à peu abandonnés, parfois parce que les progrès de la cryptanalyse les menaçaient trop, parfois simplement parce qu'ils n'avaient pas un bon marketing.
Aujourd'hui, le développeur qui écrit ou modifie un logiciel résolveur validant (comme Unbound ou BIND) doit donc se taper pas mal de RFC mais aussi pas mal de sagesse collective distillée dans plusieurs listes de diffusion pour se faire une bonne idée des algorithmes que son logiciel devrait gérer et de ceux qu'il peut laisser tomber sans trop gêner ses utilisateurs.
Ce RFC 6944 détermine pour chaque algorithme s'il est indispensable (on n'a pas le droit de faire l'impasse), recommandé (ce serait vraiment bien de l'avoir, sauf raison contraire impérieuse), facultatif (si vous n'avez rien d'autre à faire de vos soirées que de programmer) ou tout simplement à éviter (pour le cas de faiblesses cryptographiques graves et avérées). La liste se trouve dans la section 2.3 : RSA avec SHA-1 est le seul indispensable. RSA avec SHA-1 plus NSEC3 (voir plus loin l'explication de ce cas particulier), RSA SHA-256 ou SHA-512 (connus collectivement comme SHA-2), ECDSA avec SHA-256 ou SHA-384 sont recommandés. Tous les autres sont facultatifs (c'est par exemple le cas de GOST dans le RFC 5933) sauf RSA avec MD5 qui est à éviter (RFC 6151).
La section 2.2 justifie ces choix : RSA+SHA-1 est l'algorithme de référence, celui qui assure l'interopérabilité (tout logiciel compatible DNSSEC doit le mettre en œuvre). Normalisé pour DNSSEC avant l'apparition de NSEC3 dans le RFC 5155, il existe en deux variantes, une sans NSEC3 (celle qui est indispensable) et une avec (qui est recommandée car la plupart des TLD utilisent NSEC3). RSA+SHA-2 est recommandé car, comme indiqué plus haut, la racine et la plupart des TLD l'utilisent. Un résolveur qui ne comprendrait pas ces algorithmes ne servirait pas à grand'chose.
Au contraire, ECDSA est très peu utilisé en pratique. Mais les courbes elliptiques suscitent beaucoup d'intérêt, et sont une alternative au cas où il y aurait un gros problème avec RSA. D'où le statut « Recommandé ».
Des nouveaux algorithmes vont certainement apparaître dans le registre (cf. RFC 6014). Ils seront automatiquement considérés comme facultatifs, jusqu'à la sortie d'un nouveau RFC (qui a été le RFC 8624, qui privilégie désormais les algorithmes utilisant les courbes elliptiques).
Et si vous parlez plutôt la langue de Manuel Puig, ce RFC est également commenté en espagnol.
Date de publication du RFC : Mai 2013
Auteur(s) du RFC : D. Thaler (Microsoft)
Pour information
Première rédaction de cet article le 10 mai 2013
Utiliser des identificateurs (noms
de domaine, URI, noms
d'utilisateur, adresses de courrier, etc) comme
clés d'accès à des informations de sécurité est courant. Par exemple,
on autorise machin@truc.example
et lui seul à
accéder à certains contenus. Cela implique une
comparaison entre l'identificateur présenté et
ceux stockés dans une base. En apparence, rien de plus simple que de
comparer deux chaînes de caractères. En réalité, il existe plein de
pièges, que documente ce RFC de
l'IAB. Si tout le monde n'utilise pas
exactement le même algorithme de comparaison (et certains sont mal
spécifiés ou mal connus et permettent donc des variations), alors on
peut avoir aussi bien des dénis de service (utilisateur légitime
refusé) que des augmentations de privilèges (utilisateur illégitime
accepté).
L'informaticien naïf peut croire que comparer deux identificateurs, c'est simplement faire une comparaison bit à bit de leur représentation mais non, c'est plus compliqué que cela.
Pour comprendre le problème, la section 1 du RFC commence par parler du cycle de vie d'un identificateur. Il est d'abord généré, par exemple par une autorité centrale. Il est ensuite souvent stocké en deux endroits, chez l'utilisateur qui va s'en servir et dans une base des identificateurs enregistrés. Par exemple, si c'est une autorité centrale qui a fabriqué l'identificateur, elle le met dans sa base de données (cas, par exemple, d'un registre de noms de domaine). Naturellement, il y a des tas de possibilités différentes. Par exemple, un identificateur peut être une clé publique cryptographique, générée localement et stockée de même.
L'identificateur est ensuite distribué à ceux et celles qui en auront besoin. Cela peut se faire par des moyens numériques mais aussi par des moyens traditionnels comme une carte de visite ou une communication téléphonique. Pensez à un URL que l'on utilise dans des publicités, dans l'espoir que des gens tapent ensuite cet URL dans la barre d'adresse de leur navigateur. Ce passage par des moyens de communication non numériques est une des sources de problèmes car taper correctement un identificateur lu en vitesse sur le flanc d'un autobus n'est pas trivial.
Enfin, quelqu'un va utiliser cet identificateur. Par exemple, il va
essayer d'envoyer un message à
barack@whitehouse.gov
et espère que cela
atteindra la boîte aux lettres de quelqu'un de l'équipe du
Président. Ou bien un utilisateur va récupérer un identificateur et
essayer de le comparer avec celui qu'il connait. C'est le cas d'un
navigateur Web voulant valider un certificat
X.509 (RFC 6125).
À noter qu'il existe plein d'autres complications possibles. Par
exemple, une entité peut être désignée par plusieurs identificateurs
(ce RFC est à la fois http://www.ietf.org/rfc/rfc6943.txt
et
http://www.rfc-editor.org/rfc/rfc6943.txt
, un être humain
peut être référencé par son numéro de passeport ou bien par son
numéro de Sécu). Notre RFC ne se préoccupe pas
de ce cas, se limitant à celui, déjà assez difficile, de la
comparaison de deux identificateurs pour voir s'ils sont identiques.
Cela peut se faire de trois façons (section 1.1, et voir aussi le RFC 6885 qui avait introduit ces trois cas) :
2001:db8:1::1317
dans une
ACL, il n'y a aucune ambiguité pour déterminer
si l'adresse présentée est égale ou non à celle-ci. (Attention, ce
n'est vrai que pour la forme binaire des adresses IP, pas pour leur
représentation textuelle.)Une technique courante pour faciliter les comparaisons des identificateurs définis est la canonicalisation. On réduit d'abord l'identificateur à une forme canonique et on fait ensuite une comparaison absolue (bit à bit). Pour des noms de domaines, on peut par exemple toujours les passer en minuscules avant de comparer. Dans le cas d'identificateurs Unicode, c'est évidemment plus complexe mais il existe plusieurs algorithmes de canonicalisation Unicode. L'important est que toutes les parties impliquées utilisent le même.
On peut bien sûr comparer sans canonicaliser mais avoir une forme canonique est tellement pratique (par exemple pour l'affichage) que cela vaut toujours la peine d'en définir une. Ce faisant, on définit aussi un algorithme de comparaison.
La section 2 cite des exemples d'utilisation d'identificateurs dans
des contextes de sécurité. Par exemple, trouver une clé en échange
d'un nom (a principal, dit-on en sécurité),
chercher dans une ACL si une entité est
autorisée, compter l'activité d'une entité donnée (et il faut donc
ajouter son activité dans la bonne ligne du tableau). Le point
important est qu'il faut que tout le monde utilise le même
algorithme. Si on stocke l'activité d'adresses de courrier
électronique sans les canonicaliser, et que quelqu'un change son
adresse de jean@durand.example
à
jean@Durand.EXAMPLE
(pourtant la même adresse),
il pourra apparaître comme vierge, comme n'ayant pas d'activité
précédente.
Les cas réels peuvent être très compliqués. Par exemple, en HTTPS, on compare ce qu'a tapé un utilisateur dans la barre d'adresses du navigateur avec ce que contient le certificat (RFC 6125). Plusieurs protocoles différents sont en jeu (de la définition des URL à celle de X.509) et plusieurs acteurs (des utilisateurs qui tapent plus ou moins bien, sur des systèmes très variés, et tout le monde des AC), chacun de ces acteurs pouvant avoir ses propres règles.
En cas d'algorithmes différents utilisés par des parties
différentes, on peut avoir aussi bien des faux
positifs que des faux négatifs. Les
faux positifs, c'est quand deux identificateurs sont considérés comme
identiques alors qu'ils ne devraient pas. (Je me souviens d'un vieux
système Unix où le nom de
login était silencieusement tronqué à huit
caractères, donc bortzmeyer
et
bortzmeye
étaient considérés identiques.) Si les
privilèges sont attribués en fonction de cette égalité, on a un gain
en privilèges. Si, par contre, les privilèges sont refusés en fonction
de cette égalité (cas d'une liste noire), on a
un refus d'un service légitime. Le faux négatif, c'est le contraire :
deux identificateurs considérés comme différents alors qu'ils sont
équivalents (cas de jean@durand.example
et
jean@Durand.EXAMPLE
plus haut, si on oublie que
le nom de domaine est insensible à la casse). Les conséquences sont
opposées : si les
privilèges sont attribués en fonction de cette égalité, on a un refus
de service. Si, par contre, les privilèges sont refusés en fonction
de cette égalité, on a un gain de privilèges, à tort.
Évidemment, le gain de privilèges est plus grave que le refus de service et c'est pour cela qu'on trouve, par exemple, dans la section 6.1 du RFC 3986 « comparison methods are designed to minimize false negatives while strictly avoiding false positives ». (Cet exemple suppose que les privilèges sont accordés en fonction de l'égalité et que les faux positifs sont bien plus graves.)
Le RFC donne un exemple où les identificateurs sont des
URI. La société Foo paie
example.com
pour accéder à un service nommé
Stuff. Alice, employée de Foo, a un compte identifié par
http://example.com/Stuff/FooCorp/alice
. En
comparant des URI, Foo tient compte du fragment (la partie après le
#, section 3.5 du RFC 3986) ce qu'example.com
ne fait pas. Et
Foo permet les # dans les noms de compte. Un autre employé de Foo, le
malhonnête Chuck, se fait créer un compte avec l'identificateur
http://example.com/Stuff/FooCorp/alice#stuff
. Foo
ne voit pas le problème puisque cet identificateur n'existe pas. Chuck
va donc pouvoir obtenir des autorisations d'accès de Foo. Il
peut ensuite se connecter auprès d'example.com
comme étant
http://example.com/Stuff/FooCorp/alice
,
l'identificateur d'Alice. Certes, l'autorisation de Chuck n'était
valable que pour
http://example.com/Stuff/FooCorp/alice#stuff
mais
rappelez-vous qu'example.com
compare les URI en
ignorant les fragments... Voici un cas où les différences entre les
mécanismes de comparaison d'identificateurs ont permis un
accroissement illégitime de privilèges.
Après cet exemple, la section 3 fait le tour des identificateurs
les plus courants et de leurs pièges spécifiques. D'abord, les noms de
machines. Ce sont normalement un sous-ensemble des noms de domaines (RFC 6055) mais notre RFC utilise ce terme
dans un sens plus large, pour parler de tous les fois où un
identificateur ou composant d'identificateur est appelé Host. Ils sont souvent utilisés comme
identificateurs, soit directement (par exemple dans le RFC 5280), soit indirectement, comme partie d'un identificateur (le RFC cite
l'exemple des URI et des adresses de courrier). Le RFC note bien que
ce terme de nom de machine (hostname) est
ambigu. Ainsi, dans tyrion.lannister.got
, le nom
de machine est-il tyrion
ou bien
tyrion.lannister.got
(section 3.1 du RFC 1034) ? Cela peut entraîner des
problèmes lorsqu'on veut décider si la machine
tyrion
a accès aux privilèges de la machine
tyrion.lannister.got
...
Dans le sens large qu'il a ici « nom de machine » peut aussi être
une adresse IP littérale. Cela entraîne
d'autres confusions possibles. Par exemple, si le
TLD .42
existe et qu'un
nom 103.2.1.42
est enregistré, comment le
distinguer de l'adresse IPv4
103.2.1.42
? Normalement, la section 2.1 du RFC 1123 règle la question : on doit tester l'adresse
IP d'abord et 103.2.1.42
n'est donc jamais un
nom. Mais il n'est pas sûr que tous les programmes appliquent le RFC 1123... Certaines personnes pensent donc qu'il y
a un risque à accepter des TLD numériques, même si le RFC 1123 est clair.
Autre source d'ambiguité : la norme POSIX
1003.1 de l'IEEE admet pour une adresse IPv4
plusieurs formes, pas seulement la forme classique en quatre
composants séparés par des points. Ainsi, 10.0.258
,
0xA000201
et 012.0x102
sont
des représentations légales de la même adresse, 10.0.1.2
. Certaines normes se
tirent d'affaire en imposant la forme stricte, celle avec les quatre
composants décimaux séparés par des points. C'est le cas des URI, par
exemple (« an IPv4 address in dotted-
decimal form »). Même chose avec
inet_pton
qui n'accepte que la forme
stricte. Si les différentes formes sont acceptées, on peut avoir un
problème d'ambiguité.
Et avec IPv6 ? Il y a également plusieurs
représentations texte possibles (mais, à mon avis, moins susceptibles
de poser des problèmes en pratique), par exemple
2001:db8::1
et
2001:DB8:0:0:0:0:0:1
pour la même adresse, sans
compter des cas plus tordus comme les identificateurs de zone dans les
URL (RFC 6874). Contrairement à IPv4, il existe
une représentation canonique, normalisée dans le RFC 5952 mais elle n'est pas forcément utilisée par tous.
L'internationalisation (RFC 2277) ajoute
évidemment quelques questions. Par exemple, la section 3.2.2 du RFC 3986 autorise un nom de domaine
Unicode à être écrit en encodage pour-cent
ou en punycode (le second
étant recommandé mais pas imposé). Comment
comparer caf%C3%A9.fr
et
xn--caf-dma.fr
? Comme souvent en matière
d'internationalisation (qui n'a jamais été complètement acceptée par
certains), le RFC pinaille même plus loin en imaginant le cas
(purement hypothétique) d'un registre qui accepterait l'enregistrement
de noms commençant par xn--
, entrainant ainsi une
confusion avec des IDN.
Autre façon de comparer des noms : les résoudre en adresses IP et comparer les adresses. C'est ce que fait la bibliothèque standard Java par défaut (classe URL). Cette méthode a évidemment toujours été dangereuse, mais c'est encore pire maintenant, avec les adresses IP privées, les trucs du DNS pour avoir une réponse dépendant de la source, les mobiles, etc. Elle était conçue pour lutter contre des failles de sécurité comme le changement DNS mais le jeu en vaut-il la chandelle ? Sans compter qu'il est contestable d'attendre le DNS juste pour comparer deux identificateurs.
Après les noms de machines, les ports. L'URL
http://www.example.com:443/
est-il égal à
http://www.example.com:https
,
https
ayant été enregistré (RFC 6335) comme équivalent de 443 ? (Cet exemple est facile : la
seconde forme est illégale dans un URL HTTP. Mais, dans d'autres cas,
cela peut être ambigu.)
On a souvent vu les URI dans les deux sections précédentes, consacrées aux noms de machines et aux ports. Le principal problème de la comparaison d'URI est qu'un URI est formé de plusieurs composants, chacun suivant des règles de comparaison différentes. Second problème, il existe plusieurs mécanismes standard de comparaison d'URI (RFC 3986, section 6.2, qui décrit l'échelle des comparaisons, de la plus simple à la plus complète). Le but de cette variété est de permettre aux diverses applications des URI d'optimiser pour les performances ou pour la sécurité. L'inconvénient est que deux comparateurs d'URI peuvent donner des résultats différents sans même qu'on puisse accuser l'un d'eux d'être bogué ou non standard.
Certains composants de l'URI posent des problèmes particuliers :
les plans définissent la syntaxe spécifique d'un type d'URI et il ne
faut donc jamais essayer de comparer deux URI de plans différents
(http
et ftp
par exemple,
même si, dans ce cas, la syntaxe est la même).
Un autre cas souvent oublié dans les URI est la partie nommée
userinfo avant le @, par
exemple dans
ftp://alice:bob@example.com/bar
. Doit-elle être
considérée significative en comparant des URI ? Le RFC ne fournit pas
de règles à ce sujet.
Le chemin après le nom de machine pose un autre problème, celui des
caractères .
et
..
qui, normalement, indiquent un chemin relatif.
Mais la section 5.2.4 du RFC 3986 fournit un
algorithme pour les retirer, transformant
http://example.com/a/b/c/./../../g
en
http://example.com/a/g
. Un nouveau piège pour la
comparaison ?
Continuons vers la fin de l'URI. Après le ?
il y a une requête. Doit-elle être prise en compte dans la
comparaison ? Là encore, pas de réponse simple, c'est à l'application
de décider si
http://www.example.org/foo/bar?ref=323
est
identique à http://www.example.org/foo/bar
. Un
exemple où cette question se pose est celle d'un site de référencement
d'URI, avec les nombreux cas où la requête ne stocke en fait qu'une
variable de suivi de la circulation de l'URI (lu sur
Twitter, lu sur
Facebook, etc).
Reste le fragment, la dernière partie d'un URI, après le #. En général, lorsqu'on utilise un URI comme identificateur dans un contexte de sécurité, on ignore le fragment (voir l'exemple plus haut avec Chuck et Alice...) Mais ce n'est pas une règle qui marche dans tous les cas. Là encore, l'important est la cohérence : que toutes les applications qui gèrent cet URI fassent pareil.
Comme pour les noms de machine, dans l'exemple Java plus haut, on pourrait se dire qu'une façon simple de comparer deux URI est de les déréférencer et de voir s'ils pointent vers des contenus identiques. Mais tous les URI ne sont pas déréférençables, on n'a pas forcément envie d'imposer une connexion Internet en état de marche juste pour comparer deux identificateurs et, de toute façon, un tel algorithme serait très fragile (que faire si on trouve le même document XML mais avec des encodages différents ?) En outre, toute démarche active comme celle-ci est dangereuse pour la vie privée (elle informe les gérants des serveurs Web de ce que l'on est en train de faire, comme le font les Web bugs).
Après les URI, place à une catégorie d'identificateurs très souvent
utilisés pour identifier une entité, les adresses de courrier (RFC 5322 pour leur syntaxe, et RFC 6532 pour le cas où elles sont internationalisées). Une
adresse de courrier, comme un URI, a plusieurs parties, qui suivent
des règles différentes pour la comparaison. La partie à droite du
@ est un nom de domaine et ce cas a été traité
plus haut. La partie gauche, dite partie locale, est un identificateur
indéfini : ses règles ne sont pas connues à l'extérieur et on ne peut
donc pas savoir, par exemple, si rms@gnu.org
et
RMS@gnu.org
sont le même utilisateur, ou si
stephane+ps@bortzmeyer.org
est le même que
stephane+ump@bortzmeyer.org
. Dans le cas où des
adresses de courrier sont utilisées dans un certificat, on choisit
souvent une comparaison bit à bit... qui peut donner plein de faux négatifs.
Après cette liste à la Prévert de problèmes,
la section 4 de notre RFC tente une synthèse. Elle identifie quatre
problèmes. Le premier est la confusion. Un
identificateur est utilisé sans que son type soit clair. Par exemple,
si je tape telnet 1000
, est-ce l'adresse
IPv4 0.0.3.232
ou bien
l'adresse IPv6 ::3:e8
?
Et si je tape ping 10.1.2.42
, est-ce que
10.1.2.42
est un nom ou une adresse (le TLD
.42
peut exister) ?
Résoudre la confusion nécessite un algorithme clair. Dans le
premier exemple ci-dessus, il n'y a pas de
confusion. 100
ne peut pas être une adresse IPv6
légale (la présence ou l'absence d'un :
suffit à
les reconnaître). Le second exemple est normalement clair : l'adresse
IP a priorité donc 10.1.2.42
ne peut pas être un
nom même si le TLD .42
existe. Si cette règle de
précédence est respectée par les implémentations, il n'y aura pas de
problèmes (identificateurs définis). Mon avis personnel est que ce RFC
pinaille quand même très fort sur ce point, en s'interrogeant
gravement sur des problèmes théoriquement intéressants mais extrêmement
tordus et donc rares en pratique.
Deuxième problème, l'internationalisation. Un logiciel n'a aucun
problème à comparer google.com
et
goog1e.com
et à dire qu'ils sont
différents. C'est plus difficile pour un humain (vous aviez repéré le
L qui était en fait un 1 ?) Toutes les fois où un humain est impliqué,
dans la saisie ou la reconnaissance d'un identificateur, ce genre d'erreur peut se produire. Comme le montre cet exemple, cela n'a
d'ailleurs rien de spécifique aux chaînes de caractères Unicode. Mais
ce problème est souvent cité comme argument contre
l'internationalisation. Bref, le point important : la sécurité ne
devrait pas dépendre d'une vérification visuelle faite par un
humain. (Cf. l'article
de Weber et le RFC 6885.)
Problème suivant, la portée. Certains
identificateurs ne sont pas uniques au niveau
mondial. localhost
est un bon exemple. C'est
également le cas des adresses du RFC 1918. On
peut aussi citer l'adresse de courrier alice
qui,
utilisée depuis une machine d'example.com
arrivera à une Alice et, depuis une machine d'un autre domaine, à une
autre. Dans ce dernier cas, la bonne solution est de toujours utiliser
une adresse unique (par exemple
alice@example.com
) même dans un contexte local :
l'expérience prouve que les identificateurs fuient souvent d'un
domaine local vers un autre.
Enfin, dernier problème identifié par cette section 4, la
durée. Certains identificateurs ne sont pas
éternels et peuvent disparaître, ou désigner une autre entité. Par
exemple, bob@example.com
peut désigner un Bob
aujourd'hui et, s'il quitte l'entreprise et qu'un autre est embauché,
un Bob complètement différent dans quelques mois. C'est la même chose
pour les adresses IP et des tas d'utilisateurs ont déjà souffert de se
voir attribuer une adresse IP qui avait une mauvaise réputation.
La section 5 résume les conseils les plus importants : se méfier des identifcateurs indéfinis, prévoir une comparaison absolue ou définie pour tous les identificateurs futurs, penser aux mécanismes pour valider les identificateurs (RFC 3696). Le gros risque restera toujours le cas où plus d'un protocole utilise un identificateur donné, car les différents protocoles n'auront pas forcément les mêmes règles de comparaison des identificateurs.
Date de publication du RFC : Janvier 2014
Auteur(s) du RFC : C. Jennings (Cisco), B. Lowekamp (Skype), E. Rescorla (RTFM, Inc.), S. Baset, H. Schulzrinne (Columbia University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF p2psip
Première rédaction de cet article le 17 janvier 2014
Le groupe de travail IETF p2psip travaille à permettre la communication (par exemple téléphonique) entre utilisateurs de SIP sans passer par un fournisseur SIP, mais en se débrouillant en pair-à-pair. Pour cela, le groupe a choisi une approche modulaire et a d'abord développé un protocole de communication pair-à-pair, qui va servir de socle aux futures utilisations. Ce protocole se nomme RELOAD (pour REsource LOcation And Discovery), et fait l'objet de ce très long RFC, le premier du groupe p2psip.
L'enjeu est d'importance : le système fermé Skype a obtenu beaucoup d'utilisateurs en s'appuyant partiellement sur des techniques pair-à-pair. Le SIP traditionnel, où deux correspondants ne communiquent que via leurs fournisseurs SIP respectifs devait être amélioré en exploitant ces capacités pair-à-pair. Échanger des paquets RTP directement est facile. Se trouver et initier la communication l'est moins. Pour le faire en pair-à-pair, il n'existait pas de protocole ouvert et normalisé. On notera d'ailleurs que RELOAD est le premier protocole pair-à-pair (au sens moderne parce que, objectivement, IP a toujours été pair-à-pair) normalisé par l'IETF.
RELOAD est suffisemment général pour pouvoir être utilisé dans le futur par d'autres systèmes que SIP. Qu'est-ce qu'il fournit comme service que les autres protocoles existants ne fournissaient pas ?
Si vous voulez vous cultiver sur Chord, l'article original est « Chord: A Scalable Peer-to-peer Lookup Protocol for Internet Applications » (IEEE/ACM Transactions on Networking Volume 11, Issue 1, 17-32, Feb 2003, 2001) et Wikipédia en anglais a un bon article.
Une instance RELOAD est donc un overlay (un réseau virtuel utilisant un algorithme donné) où chaque nœud (pair ou simple client) a un identificateur, le Node-ID. Cet overlay forme un graphe où tout nœud n'a pas forcément directement accès à tout autre nœud, et les pairs doivent donc se préparer à router les messages (les simples clients en sont dispensés).
L'instance RELOAD offre deux services, la transmission de messages et le stockage de données (données de petite taille, a priori, celles nécessaires à la communication). Chaque donnée a un identificateur, le Resource-ID, qui utilise le même espace de nommage que les Node-ID. Il y a ensuite une relation entre les Node-ID et les Resource-ID par exemple, qu'un nœud est responsable de toutes les données dont le Resource-ID est compris entre son Node-ID et le Node-ID précédent (si vous connaissez les DHT, ce genre de concept vous est familier. Sinon, cela peut être le moment de s'arrêter pour lire des choses sur les DHT.) La relation exacte dépend de l'algorithme d'overlay utilisée. Celle donnée en exemple est valable pour Chord.
Pour accomplir ses tâches, RELOAD a plusieurs composants. De haut en bas (si cela ressemble au modèle en couches, c'est exprès, sauf que ces couches sont entassées sur l'overlay, pas sur un réseau physique) :
La sécurité est traditionnellement le point
faible des DHT (et du pair-à-pair en général). (Voir l'excellent exposé d'Eric Rescorla.) Le principe de base de la sécurité de RELOAD est que chaque
pair aura un certificat délivré par une
instance centrale (qui ne sera responsable que de l'inscription des
pairs : elle ne participera ni au routage, ni à l'envoi des messages,
ni au stockage,). Chaque message, et chaque objet stocké, sera signé avec ce certificat et
toutes les communications de bas niveau chiffrées (par exemple avec
TLS). Une machine qui veut rejoindre
l'overlay doit se connecter en
HTTPS au serveur central, qui lui attribuera un
Node-ID (dans le champ
subjectAltName
du certificat RFC 5280). Le serveur central demandera probablement une
authentification (par exemple nom et mot de passe). Ce serveur et les
vérifications qu'il fait sont le cœur de la sécurité de RELOAD. La machine joindra ensuite le réseau virtuel (les détails
sur la façon dont elle le fait dépendent de l'algorithme utilisé pour
le maintien de l'overlay).
Ne vous inquiétez pas forcément de ces obligations de sécurité : elles ne sont valables que pour un overlay installé sur le grand Internet public. Si vous avez un environnement restreint et sécurisé (disons un groupe de machines formant un réseau ad hoc local), vous avez le droit de vous en dispenser et de vous contenter de certificats auto-signés par les pairs, où le Node-ID est simplement un condensat de la clé publique. Une telle façon de fonctionner laisse le réseau très vulnérable aux attaques Sybil mais peut convenir si vous savez que vous êtes « entre vous ». Autre possibilité de simplification de la sécurité : RELOAD a un mode où les pairs s'authentifient, non pas par un certificat, mais par un secret partagé (par exemple RFC 4279).
Voici donc les grands principes de RELOAD. Je ne vais pas ensuite détailler les 186 pages du RFC, juste quelques points que je trouve intéressants. Le mécanisme de routage est présenté en section 3.3. Par défaut, RELOAD utilise du récursif symétrique (section 6.2). La requête enregistre les nœuds par lesquels elle est passée (dans la Via List) et la réponse suivra le même chemin en sens inverse. Si la topologie a changé entre-temps, la réponse sera perdue et ce sera aux couches supérieures de réémettre. (Il existe une alternative à ce stockage du chemin dans le message lui-même : si les pairs intermédiaires peuvent stocker des données, ils peuvent garder la mémoire des routes suivies, au lieu d'utiliser la Via List.)
L'inscription initiale dans l'overlay est un
problème intéressant, car on voudrait que cela soit simple pour
l'utilisateur, par exemple qu'il n'ait pas à rentrer 50 paramètres
dans son client SIP. L'idée est que le nouveau pair n'a à connaître que le
nom de l'overlay (un FQDN)
et peut-être des informations d'authentification. Une requête
SRV dans le DNS à partir
du nom du réseau (précédé de _reload-config._tcp
) donne le nom du serveur de configuration, qu'on
contacte en HTTPS en lui demandant la ressource
.well-known/reload-config
(RFC 8615 pour .well-known
). Ce serveur envoie alors tous les détails de
configuration de l'overlay, en
XML, un exemple figure en section 11 et à la
fin de cet article. (Une machine peut aussi avoir cette
configuration dans un fichier local.) C'est alors que le futur pair
connait le nom du serveur d'inscription et peut le contacter pour
apprendre son Node-ID.
Le stockage pair-à-pair dans RELOAD (section 4.1) permet de stocker différents
types (kind) d'objets. Un type peut être défini
comme stockant un scalaire, un
tableau ou un
dictionnaire (section 7.2 pour les détails). Tous les objets stockés sont
signés par le déposant, qui pourra ainsi vérifier que ses pairs ne se
sont pas moqués de lui. (Voir mon article « Assurer l'authenticité des données
stockée dans une DHT».) À noter qu'un pair ne peut pas stocker des
objets sous des noms arbitraires. Typiquement (cela dépend de l'application), il ne peut stocker que
sous son propre nom (alice@example.com
pour du SIP), ce qui fait qu'il ne pourra pas noyer tous les
nœuds de la DHT sous des objets à stocker.
Une des choses les plus nécessaires pour communiquer en pair-à-pair est la découverte. Trouver quelqu'un ou quelque chose dans l'immensitude de l'Internet est difficile (alors que c'est trivial en centralisé, d'où le succès de services comme Facebook). Il existe actuellement plusieurs Internet-Drafts décrivant de futurs services de découverte qui tourneront au dessus de RELOAD.
Le format des messages RELOAD est décrit en section 6.3 : format binaire, avec les premiers en-têtes, qui sont obligatoires, à une position fixe (pour une analyse plus rapide) et les suivants, qui sont optionnels, encodés en TLV (pour la souplesse et l'extensibilité). Chaque message est auto-suffisant, un peu comme un datagramme. Sa première partie, le Forwarding Header, est la seule qui ait besoin d'être examinée par les routeurs intermédiaires. Les deux autres, le Message Content et le Security Block (les signatures), ne concernent que la machine de destination.
Notre RFC utilise une syntaxe analogue à celle du
C pour décrire le format des messages (un peu
comme le fait le RFC 5246). Principal point à
noter pour lire cette syntaxe (la section 6.3.1 fournit tous les détails) : les termes entre
chevrons sont des valeurs de taille
variable. Par exemple data<0..15>
désigne
de zéro à quinze octets de données.
Le Forwarding Header contient les Via Lists vues plus haut et les destinations (la plupart du temps, il n'y en a qu'une seule mais RELOAD permet d'indiquer une liste de destinations à parcourir successivement : pour comparer avec le datagramme IP, disons que la liste des destinations est une fusion de l'adresse IP de destination et de l'option Source route). Cela donne :
struct { ... uint32 overlay; /* Un condensat du nom */ ... uint8 ttl; ... uint32 length; ... uint16 via_list_length; /* Pour le routage symétrique */ uint16 destination_list_length; ... Destination via_list[via_list_length]; Destination destination_list [destination_list_length]; ... } ForwardingHeader;
Pour cet en-tête, qui doit être lu très vite par les routeurs
intermédiaires, RELOAD utilise l'encodage {longueur, tableau}. Les
autres termes de longueur variable utiliseront un encodage moins
rapide à analyser mais plus propre. Le type
Destination
est, en résumant, un Node
ID ou Resource ID (rappelez-vous que ces
ID ont la même forme - dépendante du type
d'overlay - et sont tirés du même espace).
La deuxième partie du message, Message Content, est largement opaque :
struct { uint16 message_code; opaque message_body<0..2^32-1>; MessageExtension extensions<0..2^32-1>; } MessageContents;
C'est donc surtout une suite d'octets, 2^32 au maximum. Le code indique la sémantique du message (demande de stockage de données, « ping », annonce d'un nouveau pair, etc) et la liste des codes est dans un registre IANA.
La troisième et dernière partie du message, le Security Block, est une liste de certificats X.509 et une signature :
struct { GenericCertificate certificates<0..2^16-1>; Signature signature; } SecurityBlock;
Tous les messages doivent être signés et les signatures vérifiées à la réception.
Les responsabilités du greffon de gestion de la topologie figurent
dans la section 6.4. Elles sont décrites sous forme de messages
abstraits, à incarner pour chaque algorithme
d'overlay. Un exemple, le message
Join
lorsqu'un nouveau pair arrive :
struct { NodeId joining_peer_id; opaque overlay_specific_data<0..2^16-1>; } JoinReq;
Les protocoles de communication entre deux nœuds devront fournir des mécanimes d'authentification du Node ID, d'intégrité et de confidentialité, par exemple en s'appuyant sur TLS (section 6.6.1). Le RFC suggère d'explorer la possibilité d'utiliser HIP (RFC 7401 et section 6.6.1.1) qui a toutes les propriétés voulues. Ils doivent aussi respecter les principes du RFC 8085, i.e. ne pas noyer les destinataires sous les retransmissions.
Le stockage des données fait l'objet de la section 7. On stocke des objets qui ont cette forme :
struct { uint32 length; uint64 storage_time; uint32 lifetime; StoredDataValue value; Signature signature; } StoredData;
On voit qu'ils sont signés, et ont une durée de vie maximale.
On l'a dit, RELOAD utilise par défaut la DHT Chord et toutes les mises en œuvre de RELOAD doivent connaître Chord, pour assurer l'interopérabilité. Le mécanisme utilisé par RELOAD est légèrement différent du Chord original et la section 10 détaille ces différences. Les deux principales :
Les grands principes de Chord sont gardés : nœuds organisés en un anneau (le dernier nœud dans l'ordre des Node ID est donc le précédesseur du premier), utilisation de SHA-1 (tronqué aux 128 premiers bits dans Chord-RELOAD) pour trouver le Resource ID à partir des données, table de routage composée, non seulement des voisins immédiats, mais aussi de pointeurs (les fingers) vers un certain nombre de non-voisins (pour des raisons de performance, car cela évite de parcourir la moitié de l'anneau, mais aussi de résilience, pour survivre à la perte des voisins), etc
Un exemple de fichier de configuration d'un réseau virtual (overlay) figure en section 11 :
<overlay> <configuration instance-name="overlay.example.org" sequence="22" expiration="2002-10-10T07:00:00Z" ext:ext-example="stuff" > <!-- Le greffon de topologie par défaut : --> <topology-plugin>CHORD-RELOAD</topology-plugin> <!-- Le certificat qui va signer tout : --> <root-cert> MIIDJDCCAo2gAwIBAgIBADANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQGEwJVUzET... </root-cert> <!-- Les serveurs à contacter pour avoir Node-ID et certificat : --> <enrollment-server>https://example.org</enrollment-server> <enrollment-server>https://example.net</enrollment-server> <!-- Les pairs à contacter pour rejoindre l'overlay : --> <bootstrap-node address="192.0.0.1" port="6084" /> <bootstrap-node address="192.0.2.2" port="6084" /> <bootstrap-node address="2001:db8::1" port="6084" /> <!-- Les paramètres spécifiques à la DHT : --> <chord:chord-update-interval> 400</chord:chord-update-interval> <chord:chord-ping-interval>30</chord:chord-ping-interval> <chord:chord-reactive>true</chord:chord-reactive> <!-- Et bien d'autres choses encor... --> </overlay>
6084 est le port par défaut pour RELOAD (section 14.2). La grammaire pour ce fichier de configuration est normalisée (en Relax NG) en section 11.1.1.
Pour contacter les serveurs d'inscription (enrollment
server), le protocole à utiliser est en section 11.3. L'IETF
a choisi de ne pas réutiliser les protocoles existants (RFC 5272 et RFC 5273) car ils sont trop complexes. À la
place, le futur pair fait juste une requête HTTPS
POST
dont le contenu comprend
du PKCS#10 (contenant la demande de certificat,
cf. RFC 2311). Cette requête doit aussi contenir les
informations d'authentification du pair (par exemple un nom et un mot
de passe). En échange, le serveur enverra un certificat dont le sujet
(le nom) sera un Node ID, choisi au hasard (RFC 4086 ; c'est important car certaines attaquent
contre les DHT nécessitent que l'attaquant choisisse son Node
ID). En outre, le champ subjectAltName
doit contenir le nom que l'utilisateur sera autorisé à présenter à
l'application (pour SIP, ce sera un nom de type
machin@truc.example
). Certaines autorisations
(par exemple d'accès aux données stockées) dépendront de ce nom.
La faiblesse traditionnelle des DHT (ou du pair-à-pair en général) est la sécurité (RFC 5765). Sans chef pour contrôler les échanges, que faire si un méchant s'insère dans le réseau pair-à-pair pour l'espionner, modifier les données, ou bien empêcher le réseau de fonctionner ? La section 13 revient en détail sur les questions de sécurité. Le fond du problème est qu'on dépend des pairs (pour envoyer des messages à d'autres pairs ou bien pour stocker des données) et qu'on n'a pas de relation bien définie avec ces pairs. Sur un réseau public comme l'Internet, les pairs peuvent être n'importe qui, y compris des méchants. Si la majorité des pairs sont dans ce cas, on est fichu, aucun algorithme astucieux ne peut marcher dans ces conditions. Il faut donc agir sur l'inscription (enrollment). C'est ce que fait RELOAD (section 13.3) en imposant le passage par un serveur d'inscription pour obtenir un certificat, puis en imposant de prouver la possession d'un tel certificat (en signant les messages avec la clé).
RELOAD permet des certificats auto-signés mais, dans ce cas, l'overlay peut être vite noyé sous les pairs malveillants (ce qu'on nomme une attaque Sybil). La seule sécurité qui reste est le Node ID (qui est dérivé du certificat et est donc cryptographiquement vérifiable). Bref, une telle sécurité ne convient que dans des environnements fermés, où on est sûr de toutes les machines présentes. Un exemple typique est un réseau ad hoc entre les machines des participants à une réunion (et encore, en Wifi, attention à l'attaquant de l'autre côté du mur...). Dans ce cas, on peut même se passer complètement des certificats en choisissant la solution du secret partagé : on le distribue à tous les participants à la réunion et ça roule (section 13.4).
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : G. Fairhurst (University of Aberdeen), M. Westerlund (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 1 mai 2013
Le RFC 2460 qui normalise IPv6 indique dans sa section 8.1 que les paquets UDP sur IPv6 doivent avoir une somme de contrôle (elle était facultative en IPv4) calculée selon le RFC 1071. Dans quels cas est-elle réellement nécessaire ? Peut-on s'en passer parfois ? Ce nouveau RFC discute des conditions qui peuvent permettre de mettre zéro dans le champ Checksum, indiquant qu'on n'a pas utilisé de somme de contrôle. Pour résumer : si on veut se passer de somme de contrôle, cela doit se faire application par application, il faut être sûr qu'on supporte les paquets corrompus ou délivrés à tort, et il faut tester le chemin emprunté pour être sûr que les « nouveaux » paquets passent bien.
Ce RFC discute des solutions à un problème de performance d'UDP et des conditions dans lesquels on peut ne plus mettre de somme de contrôle. Il sert donc d'arrière-plan au RFC normatif, le RFC 6935 qui définit les nouvelles règles pour UDP sur IPv6 (somme de contrôle facultative) et fait donc un choix ferme parmi les propositions discutées ici. Notez toutefois qu'il y a pas mal de recouvrement et de redites entre les deux RFC.
UDP est très utilisé, et pour beaucoup d'applications (le RFC 8085 donne des conseils à ce sujet). Un des usages fréquents est pour construire des tunnels, afin de pouvoir passer à travers les millions de middleboxes stupides qui infestent l'Internet, et qui bloquent souvent tous les protocoles autres que UDP et TCP. Or, un routeur d'entrée ou de sortie de tunnel peut avoir à encapsuler ou décapsuler des millions de paquets par seconde et la génération ou la vérification des sommes de contrôle de chaque paquet peut avoir un effet mesurable sur ses performances (sections 1.3.2 et 1.3.3). D'autant plus qu'il n'est pas toujours possible d'utiliser le matériel spécialisé du routeur pour cela car il ne donne souvent accès qu'aux N premiers octets du paquet (avec N typiquement < 128), alors que le calcul de la somme de contrôle nécessite d'accéder à tout le paquet.
En UDP/IPv4, la solution est de couper la somme de contrôle sur le paquet externe (le protocole interne, qui n'est pas forcément UDP, reste protégé par sa propre somme de contrôle), ce qui est légal en IPv4. Le tunnel devient alors un lien virtuel non fiable, pouvant corrompre des paquets (comme c'est le cas d'un certain nombre de liens physiques). C'est par exemple la solution recommandée pour un gros consommateur de tunnels UDP, LISP. Il est donc tentant de l'utiliser également en UDP/IPv6.
Cela peut poser des problèmes avec certaines middleboxes qui vérifient la somme de contrôle UDP et n'accepteront pas d'y trouver zéro. Décréter que la somme de contrôle UDP en IPv6 devient facultative ne signifie donc pas que ces paquets optimisés pourront voyager dès demain sur tout l'Internet : un certain nombre de pare-feux les bloqueront. Cela peut sembler un problème rédhibitoire (on utilisait UDP justement pour passer facilement à travers les middleboxes puis on réforme les règles d'UDP, créant des paquets qui sembleront illégaux à beaucoup de ces middleboxes) mais il faut noter que la plupart des ces middleboxes ne font pas encore d'IPv6 et que donc les premiers déploiements ont des chances de se faire avec des middleboxes conformes à la nouvelle règle.
À part l'UDP existant, et l'UDP avec somme facultative du RFC 6935, quelles sont les autres technologies disponibles pour des tunnels (section 2 du RFC) ? Il y a UDP Lite (RFC 3828), avec une somme de contrôle qui ne couvre que le début du paquet (et est donc rapide à calculer), et qui est certes mis en œuvre dans le noyau Linux mais qui est peu reconnu par les middleboxes. Il utilise un identifiant (champ Next Header qui identifie en général le protocole de transport) différent de celui d'UDP (136 contre le 17 d'UDP) et est donc souvent bloqué par des pare-feux trop zélés. Il y a les techniques de tunnels génériques comme IP-in-IP et GRE. Elles n'ont pas de somme de contrôle du tout et sont donc rapides. Ce sont les solutions idéales pour les tunnels mais elles aussi utilisent un champ Next Header qui peut ne pas être connu de la middlebox (94 pour IP-in-IP et 47 pour GRE) et ils passent certainement moins souvent qu'UDP (d'où le choix d'UDP pour LISP). Notons aussi que la section 6 déconseille les tunnels récursifs (un tunnel dans un tunnel dans un tunnel...) qui augmentent les risques d'erreur pour le paquet le plus interne (et ajoutent une grande complexité à la fragmentation).
La section 3 examine ensuite les choses qui peuvent aller mal avec la solution retenue par le RFC 6935. Si on ne met pas de somme de contrôle dans le paquet UDP (ou, plus exactement, qu'on met zéro, indiquant qu'on n'a pas calculé de somme et que le récepteur ne doit pas vérifier), et qu'un bit du paquet est modifié, que peut-il se passer d'horrible ? Pour IPv4, la somme de contrôle UDP ne servait qu'à protéger les numéros de port et les données, des informations comme l'adresse IP de destination étaient protégées par la somme de contrôle de la couche 3. Celle-ci a disparu en IPv6 et la somme de contrôle UDP doit donc tout faire. Si elle est erronée, on n'est même pas sûr que le paquet nous était bien destiné (l'adresse IP de destination a pu être modifiée).
Comme l'expliquent le RFC 3819 ou des études comme « When the CRC and TCP Checksum Disagree », la corruption arrive réellement dans l'Internet. Des mesures ont indiqué jusqu'à 1 paquet corrompu sur 10 000 (cela dépend fortement du chemin suivi : le taux de corruption est quasi-nul sur certains chemins). Le RFC note (section 3.2) qu'on ne sait pas exactement où la corruption survient : cela peut être dans la RAM du routeur, sur le câble, dans les récepteurs et les émetteurs optiques ou électriques, etc.
Si c'est l'adresse IP de destination qui est modifiée, le paquet peut n'arriver nulle part, ou bien arriver à une machine qui ne l'attend pas. Si aucun programme n'écoute sur le port en question, le paquet est jeté (et un message d'erreur envoyé à la source, qui sera bien surprise). Si un programme écoute, il va recevoir un paquet invalide. Même chose si c'est le port de destination seul qui a été corrompu. Si l'application n'a pas de mécanisme (comme des numéros de séquence) pour détecter le problème, le paquet invalide pourra être accepté. Donc, une règle importante : une application qui est prête à débrayer les sommes de contrôle UDP doit être prête à réagir proprement si elle reçoit un datagramme envoyé à tort. C'est une des raisons pour lesquelles le RFC exige que la suppression de la somme de contrôle UDP ne se fasse pas globalement, pour toute la machine ou pour toute l'interface réseau, mais uniquement sur requête explicite d'une application majeure et consentante (section 3.5)
Si c'est l'adresse IP source qui est corrompue, le paquet arrivera sans doute à la bonne destination (mais pas à coup sûr, par exemple en cas de filtrage RFC 2827). Si l'application garde en mémoire ses correspondants, le paquet de ce correspondant inconnu sera jeté. Si elle ne le fait pas, si une réponse est envoyée... elle le sera au mauvais correspondant.
Et si c'est l'information de fragmentation qui est corrompue ? Cela peut empêcher le réassemblage (menant à la perte du paquet) mais aussi, ce qui est bien pire, conduire à des réassemblages erronés (par exemple, si le champ ID est modifié, attribuant le fragment à un autre datagramme). Comme le note le RFC 5722, il faut multiplier les tests lors du réassemblage.
Nous avons vu plus haut qu'un certain nombre de boîtiers intermédiaires jetteraient probablement sans autre forme de procès ces « nouveaux » paquets UDP avec une somme de contrôle nulle (ils étaient illégaux avant la sortie du RFC 6935). Il est donc essentiel, pour une application qui veut utiliser cette nouveauté, de tester le chemin et de vérifier que rien sur le trajet ne jette les paquets sans somme de contrôle. Il faut aussi penser à répéter ce test de temps en temps : le chemin peut changer (par exemple parce que BGP l'a décidé) et passer tout à coup par des boîtiers différents. (Et il faut faire le test dans les deux sens, ne serait-ce que parce que le routage n'est pas forcément symétrique.)
Dans tous les cas, il faut se rappeler que la somme de contrôle ne fournit de protection que contre la corruption accidentelle. Ce n'est pas un mécanisme d'authentification, et elle ne protège pas du tout contre un attaquant (qui peut modifier le paquet sans changer la somme de contrôle).
Les règles d'applicabilité sont formalisées dans les sections 4 (pour les implémentations) et 5 (pour l'usage de ces implémentations). Les programmes qui mettent en œuvre UDP sur IPv6 :
Cela, c'était pour l'implémentation d'UDP et d'IPv6 (qui, dans un Unix, est dans le noyau). Maintenant, pour les applications qui l'utilisent, la section 5 dit qu'elles :
Voilà, les règles d'applicabilités sont posées. Mais le RFC compte aussi une annexe intéressante, l'annexe A, qui est consacrée aux propositions alternatives. La solution choisie par le RFC 6935 a été d'autoriser les sommes de contrôle nulles. Mais on aurait pu faire différemment. Par exemple, le problème de performance et d'accès à la totalité du paquet aurait pu être traité par les calculs incrémentaux de somme de contôle du RFC 1624 (mais ils ne marchent pas quand il y a fragmentation IP). On aurait pu, comme cité, utiliser un protocole comme UDP Lite, ou UDPTT. Il avait aussi été proposé une mesure unilatérale, qu'un receveur ignore la somme de contrôle, quoiqu'ait mis l'émetteur (c'était plus simple mais il était alors impossible de détecter la corruption, pour tous les paquets). D'autres avaient suggéré une nouvelle option dans un en-tête Destination Options, ce qui revenait, à mon avis, à réintroduire une somme de contrôle en couche 3, ce qu'IPv6 avait délibérement abandonné. De toute façon, beaucoup de middleboxes auraient jeté les paquets avec cet en-tête (qui est rare, en pratique). Ces différentes propositions sont examinées en fonction de plusieurs critères : traversabilité des middleboxes, performances, déployabilité et résistance à la corruption de paquets.
Pour la traversée des middleboxes, l'UDP actuel ou bien un UDP avec un calcul incrémental des sommes de contrôle, est ce qui marche le mieux. Aucun changement à faire. L'UDP sans somme de contrôle du RFC 6935 aura sans doute quelques soucis (actuellement, de tels paquets sont illégaux), ainsi que les paquets avec l'en-tête Destination Options (pourtant légaux). Et les tunnels génériques seront sans doute bloqués par défaut par la plupart des pare-feux, ainsi qu'UDP Lite.
C'est à peu près la même chose pour la déployabilité : l'UDP actuel existe déjà et n'a pas à être déployé. Les sommes de contrôle facultatives du RFC 6935 nécessiteront au moins un changement dans les extrémités (ne pas calculer la somme, ne pas la vérifier) mais aussi dans certaines middleboxes qui se mêlent de vérifier la somme de contrôle, alors qu'on ne leur a rien demandé.
Pour les performances, l'UDP actuel est certainement le pire, puisqu'il faut calculer la somme de contrôle sur la totalité du paquet. C'est bien cela qui a motivé tout ce travail sur la réforme des sommes de contrôle UDP. UDP Lite, qui ne vérifie qu'une partie du paquet, et l'UDP réformé du RFC 6935 ont des bien meilleures performances (c'est aussi le cas des tunnels génériques).
Bref, il n'y a pas de solution parfaite, qui résolve tous les problèmes. Si on veut avant tout passer partout, l'UDP actuel est la meilleure solution. Si on veut une solution propre architecturalement, IP-in-IP est parfait. Si on se préoccupe des performances, l'UDP avec somme de contrôle facultative du RFC 6935 est une bonne approche et reçoit un avis favorable dans ce RFC.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : M. Eubanks (AmericaFree.TV LLC), P. Chimento (Johns Hopkins University Applied Physics Laboratory, M. Westerlund (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 1 mai 2013
Ne dites plus qu'en IPv6, la somme de contrôle est toujours obligatoire dans les en-têtes des paquets UDP. Depuis ce RFC 6935, ce n'est plus vrai dans tous les cas. Lors de l'encapsulation de paquets dans un tunnel UDP, on a désormais le droit de ne pas mettre de somme de contrôle dans les paquets UDP, essentiellement pour des raisons de performance.
Le principal demandeur de cette modification était le protocole LISP (RFC 9300), qui dépend énormement de tunnels UDP. Même si le calcul de la somme de contrôle Internet est rapide (RFC 1071), comme ce calcul peut se faire des millions de fois par seconde pour un routeur très actif, on peut chercher à l'économiser. D'autant plus qu'il n'est pas forcément utile puisque, dans le cas d'un tunnel, le protocole qui circule dans le tunnel est déjà protégé par une somme de contrôle. À noter que d'autres protocoles que LISP (comme ceux utilisés pour le multicast) peuvent bénéficier de cette nouvelle indulgence. Mais elle ne s'applique pas aveuglément à tout UDP (comme l'avaient proposé certains au début de la discussion), uniquement aux tunnels.
La norme actuelle sur IPv6, le RFC 2460, imposait (dans sa section 8.1) une somme de contrôle pour les paquets UDP (en IPv4, elle était facultative). En effet, IPv6 n'a pas de somme de contrôle dans la couche 3 (contrairement à son prédecesseur).
Ce RFC est un produit du groupe de travail IETF 6man, qui produit inlassablement d'innombrables RFC pour combler tous les petits problèmes qui trainent encore dans IPv6 et sont révélés par son utilisation dans le vrai monde.
Notez bien que cette dispense de somme de contrôle n'est pas générale : elle concerne les cas où il y a un tunnel et où il utilise UDP. Pourquoi UDP, alors qu'il existe des protocoles de tunnel qui s'en dispensent ? Parce que l'Internet est hélas de plus en plus ossifié, et que des middleboxes stupides et boguées sont partout sur le trajet des pauvres paquets. Les techniques de tunnel directement sur IP (comme l'excellent GRE du RFC 2784) sont souvent bloquées, alors qu'UDP passe partout. On aura donc un protocole X (LISP ou un autre) à l'intérieur du tunnel et de l'UDP à l'extérieur. Hier, cet UDP à l'extérieur était forcément protégé par une somme de contrôle. Pour un routeur qui sert de terminaison à des dizaines de milliers de tunnels (ce qui n'aurait rien d'étonnant avec LISP), calculer et vérifier ces sommes peut être très douloureux. D'autant plus que le protocole X a souvent sa propre somme de contrôle : ne serait-ce pas mieux pour tout le monde que le tunnel soit non sécurisé, ses éventuelles corruptions de paquets étant détectées par le protocole X uniquement ?
La section 4 discute plus en détail de certains aspects du problème mais il vaut mieux consulter le RFC 6936 pour tout savoir. Cet autre RFC précise notamment dans quels cas supprimer la somme de contrôle est une bonne idée et dans quels cas il vaut mieux la garder. La section 4 de notre RFC note particulièrement que les paquets de contrôle du tunnel, ceux qui servent à la signalisation, devraient rester protégés (s'ils sont corrompus, le tunnel peut cesser de fonctionner, c'est-à-dire que la corruption d'un paquet va affecter d'autres paquets). Notons que certains protocoles de tunnel comme GRE n'ont aucun mécanisme de contrôle. Lorsqu'il y en a un, il est souvent utilisé pour établir un contexte au début, avec choix des paramètres pour le tunnel : ce peut être le bon moment pour négocier le non-usage des sommes de contrôle sur les paquets de données.
Autre piège rigolo : certaines middleboxes vont tiquer en voyant les paquets UDP sans somme de contrôle (bien que, normalement, la somme de contrôle soit de bout en bout et ne regarde pas ces équipements intermédiaires). Bien que ce soit désormais légal, il va falloir attendre longtemps avant que tous ces engins soient mis à jour (section 4.3). En attendant ce jour, il est prudent que le tunnel détecte les problèmes en envoyant des paquets avec et sans somme de contrôle au début : si seuls les premiers passent, c'est qu'on a une middlebox agressive sur le trajet et qu'il faut renoncer à appliquer ce RFC 6935. Le test est d'ailleurs à répéter de temps en temps : la route peut changer et on peut donc se retrouver soudain à traverser une nouvelle middlebox.
La section 4.1 conseille également de tenter de détecter la corruption avant de décapsuler, par exemple en examinant l'adresse IP source, pour minimiser le risque d'envoyer au protocole encapsulé un paquet reçu corrompu. Mais cette détection ne marchera pas à tous les cas (sinon, on pourrait supprimer les sommes de contrôle dans tous les cas) et le protocole encapsulé doit donc être robuste et réagit proprement lorsque ces paquets corrompus sont injectés dans un flux existant (section 4.2).
La section 5 contient la nouvelle norme pour les sommes de contrôle UDP. Elle remplace le texte du RFC 2460 (qui disait que la somme de contrôle UDP était toujours obligatoire en IPv6) par un texte plus nuancé : par défaut, la somme de contrôle doit être calculée et mise dans le paquet. Mais on peut s'en dispenser dans le cas de tunnels (et uniquement celui-ci), sur le paquet extérieur. Le protocole à l'intérieur du paquet (qui n'est pas forcément de l'UDP et même pas forcément de l'IPv6) doit rester protégé par sa propre somme de contrôle. Cela ne doit s'appliquer que pour une liste explicite de ports (ceux utilisés par le tunnel) et pas pour tout le trafic UDP de la machine. Et le tout doit se faire en lisant le RFC 6936 qui précise les conditions d'application de cette nouvelle règle.
Les curieux et les chercheurs en informatique noteront que la section 6 liste des points qui mériteraient davantage d'étude. Ainsi, il n'y a pas eu d'étude systématique de la corruption de paquets sur l'Internet depuis 2000 et personne ne sait donc trop si c'est un phénomène fréquent ou pas. Cette section note aussi qu'il existe en théorie une meilleure solution pour les tunnels, UDP Lite (RFC 3828), mais que sa probabilité de passer les middleboxes est plus faible que celle d'UDP.
Plusieurs des mises en œuvre de LISP envoient déjà des paquets UDP sans somme de contrôle (ou plus exactement avec une somme à zéro).
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : Donald Eastlake (Huawei)
Chemin des normes
Première rédaction de cet article le 18 avril 2013
Il existe tout un ensemble de normes pour assurer la sécurité de documents XML, par exemple les protéger contre la lecture non autorisée, ou bien permettre leur authentification. Ces normes dépendent d'algorithmes cryptographiques identifiés par un URI. Ce RFC met à jour la liste précédente de ces URI (qui était dans le RFC 4051) et crée un registre des identificateurs d'algorithmes.
Ces normes de sécurité de XML étaient à l'origine un travail conjoint de l'IETF et du W3C. C'était par exemple le cas des signatures XML du RFC 3275, du XML canonique des RFC 3076 ou RFC 3741. Elles sont désormais maintenues par le W3C qui a produit des versions plus récentes (par exemple pour les signatures XML, le XML canonique ou le chiffrement XML).
Dans un monde dynamique comme celui de la
cryptographie, où les progrès de la
cryptanalyse nécessitent des changements
d'algorithmes, les normes ne sont pas liées à un algorithme
particulier. Elles permettent l'agilité cryptographique (le changement
d'algorithme) et il faut donc pouvoir indiquer quel algorithme est
utilisé pour signer ou chiffrer un document donné. Pour une norme
W3C, on ne s'étonnera pas que l'indication se
fait par le biais d'un URI. Ceux-ci commencent
désormais par le préfixe
http://www.w3.org/2007/05/xmldsig-more#
(les
anciens algorithmes pouvant avoir d'autres préfixes). Ces nouveaux
algorithmes (avec 2007/05
dans leur
identificateur) sont relativement rares dans ce RFC : on n'invente
quand même pas un bon algorithme de cryptographie tous les jours et la
plupart des exemples dans cet article utilisent donc le vieux
préfixe. Rappelez-vous qu'il s'agit d'URI, pas
forcément d'URL et que vous n'obtiendrez donc
pas forcément un résultat en pointant votre navigateur
Web vers http://www.w3.org/2001/04/xmlenc#sha256
.
Notons que notre RFC 6931 ne prend pas position sur la qualité cryptographique des algorithmes : il fournit un moyen de les désigner sans ambiguité, c'est tout. Si on veut étudier cette qualité cryptographique, il faut lire d'autres documents (comme le RFC 6194 pour SHA-1).
Un exemple d'un ancien algorithme est MD5
pour calculer les condensats
cryptographiques. Son URI est
http://www.w3.org/2001/04/xmldsig-more#md5
. Sa
sécurité est aujourd'hui sérieusement battue en brèche (cf. RFC 6151). Autre exemple d'un algorithme qui était déjà dans le
RFC 4051, SHA-384, identifié par http://www.w3.org/2001/04/xmldsig-more#sha384
.
Un exemple d'un nouvel algorithme pour la condensation
cryptographique ? Le NIST ayant récemment
annoncé que le vainqueur du concours « SHA-3 »
était Keccak, des URI utilisant le nouveau
préfixe ont été créés pour lui, par exemple
http://www.w3.org/2007/05/xmldsig-more#sha3-512
(regardez bien : sha-3
et plus
sha
, et la nouvelle date dans le préfixe).
Il existe aussi des identificateurs pour les
MAC combinés avec une condensation, par exemple
http://www.w3.org/2001/04/xmldsig-more#hmac-sha512
(RFC 6234).
Et pour les signatures avec un système à clé
publique ? L'identificateur indique l'algorithme de
cryptographie asymétrique et celui de condensation, par exemple
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
(voir aussi le RFC 3447). SHA-256
n'est pas tout récent et, si vous cherchez un algorithme enregistré
par notre nouveau RFC, pourquoi pas Whirlpool
avec http://www.w3.org/2007/05/xmldsig-more#rsa-whirlpool
. Si on trouve
RSA ennuyeux, il existe aussi des
identificateurs pour un algorithme à courbes
elliptiques (RFC 6090 mais notez ses errata), ECDSA, par exemple
http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512
.
Enfin, il y a les algorithmes de chiffrement symétrique. Par exemple, Camellia (RFC 3713) sera identifié par
http://www.w3.org/2001/04/xmldsig-more#camellia256-cbc
. Le
plus récent SEED (RFC 4269) sera http://www.w3.org/2007/05/xmldsig-more#seed128-cbc
.
Voici pour la cryptographie. Mais les normes de sécurité XML
prévoient aussi une étape de canonicalisation avant chiffrement ou
signature, et là aussi, il y a plusieurs algorithmes, identifiés par
des URI comme http://www.w3.org/2000/09/xmldsig#minimal
ou http://www.w3.org/2006/12/xmlc14n11#WithComments
.
Quelle est la politique d'allocation dans le nouveau registre ? La
section 5 décrit celle du W3C (le préfixe
http://www.w3.org/2007/05/xmldsig-more#
est figé,
a priori, on n'y mettra pas de nouveaux algorithmes) et celle de
l'IETF : comme il est facile d'obtenir un URI (n'importe qui peut en
créer un), la seule question est celle de leur enregistrement. Il se
fera après un examen par un expert (voir le RFC 5226 pour les politiques d'allocation IETF) après
publication d'un texte décrivant le nouvel algorithme.
Quels changements depuis la version précédente de ce RFC, le RFC 4051 ? L'annexe A les liste. Les principaux, à mon avis, sont :
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : Alan DeKok (Network RADIUS), Avi Lior
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF radext
Première rédaction de cet article le 1 mai 2013
RADIUS, un protocole utilisé pour l'authentification (et la configuration) d'accès à l'Internet, est ancien et marche toujours. Lorsque vous accédez à l'Internet depuis chez vous, sans vous en rendre compte, vous avez probablement indirectement utilisé RADIUS. Il marche toujours très bien mais, rançon du succès, il a été tellement étendu qu'un certain nombre de champs du message RADIUS sont désormais pleins : toutes les options possibles seront allouées très bientôt. Ce nouveau RFC décrit un mécanisme d'extension de RADIUS, permettant de continuer l'enregistrement de nouvelles options, au prix de quelques bricolages.
Il y a peu de gens qui manipulent RADIUS (RFC 2865) explicitement. Ce protocole se trouve en effet caché dans le réseau du FAI, entre la machine qui contrôle l'accès (le NAS) et un serveur RADIUS qui contient les données sur les utilisateurs. RADIUS permet de ne pas avoir à copier les informations d'authentification, ou les paramètres d'un utilisateur donné, directement dans tous les NAS, mais de les centraliser dans un petit nombre de serveurs RADIUS.
La requête, et surtout la réponse RADIUS peuvent contenir un
certain nombre d'attributs (RFC 2865, section 5) comme « nom de l'utilisateur », « mot de
passe », « adresse IP à attribuer », etc. Le champ
« Attribute » est en TLV et
le type (User-Name
= 1,
User-Password
= 2,
Framed-IP-Address
= 8, etc) est encodé sur un
seul octet. La liste (un registre
IANA) est aujourd'hui bien remplie et devrait l'être
complètement en 2014 ou
2015. C'est le principal problème de RADIUS
aujourd'hui (section 1 de notre RFC). Mais il y en a d'autres comme le
fait que la longueur d'un attribut soit codé sur un octet seulement
(donc 253 octets maximum pour la valeur d'un attribut, puisqu'il faut
retirer le type et la longueur).
Notre RFC fait donc les changements suivants :
Voilà, c'est l'essentiel du RFC. Ceux qui étendent le protocole RADIUS vont sans doute migrer vers les nouveaux types, dès aujourd'hui, ou bien lorsque les anciens seront épuisés.
Des exemples d'encodage figurent en section 9. Par exemple, un
attribut utilisant un type étendu (ici, 241.1) et ayant une valeur de type texte
(la chaîne "bob") se représentera f1 06 01 62 6f
62
(f1
, le type, 241,
06
la longueur totale, 01
le
sous-type du type étendu, 1 (à la place du premier octet de la
valeur), 62 6f 62
la vraie valeur, la chaîne
de caractères). Plus compliqué, un attribut 241.2 contenant un TLV
dont le type est 1, la longueur 4 et la valeur 23
45
, sera représenté f1 07 02 01 04 23
45
.
Avec les étendus longs (Long Extended
Type), un attribut 245.1 contenant le même "bob" sera
f5 07 01 00 62 6f 62
(f5
est
le type, la longueur est de sept octets, 01
est
la suite du type, l'octet supplémentaire est à 0 (donc le bit M
aussi : pas d'autres attributs à attendre) et la valeur est la chaîne
"bob" (62 6f 62
en
ASCII). Si un type 245.4 encode plus de 251
octets (ici, 260 octets de valeur), on
aura le premier attribut qui commencera par f5 ff 04
80
(longueur totale à 256 octets, l'octet supplémentaire vaut 80, indiquant que le bit M
est à Un) et un deuxième attribut qui commencera par f5 13
04 00
(octet supplémenaire à 0 donc bit M à Zéro, ce second
attribut est le dernier). La longueur totale est ff +
13
soit 260 octets pour la valeur.
Si vous voulez tester vous-même ces nouveaux types et leur encodage, l'annexe A du RFC contient un programme en C qui permet exactement cela (copie locale du source). Il s'utilise ainsi :
% echo '241.1 "bob"' | ./radius-attr-generator 241.1 "bob" -> f1 06 01 62 6f 62 % echo '243.2 42' | ./radius-attr-generator 243.2 42 -> f3 04 02 42 # Plus drôle, un TLV dans un TLV : % echo '241.4 { 1 23 45 } { 3 { 1 ab cd } }' | ./radius-attr-generator 241.4 { 1 23 45 } { 3 { 1 ab cd } } -> f1 0d 04 01 04 23 45 03 06 01 04 ab cd
Parmi les autres nouveautés du RFC, il y a la formalisation de la
convention de nommage informel des attributs : mots séparés par des
tirets (par exemple Framed-MTU
), attributs
spécifiques à un vendeur préfixés par le nom du vendeur (par exemple
Starbucks-Latte-Size
pour un vendeur nommé
Starbucks).
Le changement apporté au protocole n'est pas trivial, mais soigneusement conçu pour maintenir la compatibilité. La section 5 du RFC note toutefois quelques problèmes potentiels. D'abord, certains vendeurs se sont approprié des numéros de types qui étaient marqués comme réservés (et qui sont désormais utilisés pour les types étendus). Comme le notait le RFC 6158, c'est un comportement anti-social. Maintenant que ces numéros réservés sont utilisés, ces attributs spécifiques au vendeur anti-social ne marcheront plus (bien fait).
Autre problème potentiel, il est fréquent que les messages RADIUS soient relayés par un serveur intermédiaire (RFC 2865, section 2.3), notamment en cas d'itinérance. Idéalement, le relais devrait ignorer les attributs qu'il ne comprennent pas. Si, par contre, il rejette les messages contenant ces attributs nouveaux, un client et un serveur conformes au nouveau format ne pourront pas communiquer à travers un tel relais. Notre RFC rappelle bien qu'un relais devrait être transparent et relayer même ce qu'il ne comprend pas.
Les sections 6.6 et 10.3 fournissent les règles d'enregistrement des nouveaux types. Il est recommandé d'y aller mollo : les nouveaux espaces sont plus grands mais pas infinis. Le registre IANA stocke désormais des attributs des nouveaux types.
Devoir ajuster a posteriori un protocole, qui avait été conçu d'une certaine manière, et qui esr assez rigide, est toujours une opération délicate, spécialement lorsqu'il faut maintenir la compatibilité avec l'existant. Des tas de propositions ont été faites depuis des années, pour étendre RADIUS. La section 7 du RFC documente pourquoi celle-ci a été choisie. D'abord, elle est relativement simple, avec peu de modifications du format. Son principal inconvénient est que le format des Long Extended Type est assez baroque.
Quant au mécanisme pour agrandir la taille possible des valeurs, il a d'abord été conçu pour ne pas changer les attributs dont la valeur restait petite. D'après une étude de 2010 (citée en section 7.1) portant sur tous les dictionnaires Radius connus, les entiers représentent près de la moitié des valeurs d'attributs RADIUS publics. En ajoutant les autres types de taille fixe (adresses IP, par exemple), on arrive à plus de la moitié. Il fallait donc éviter de faire payer ces types peu consommateurs en octets.
Plusieurs des mises en œuvre de Radius gèrent déjà ces extensions, par exemple FreeRADIUS. Il faut dire qu'il n'y a guère le choix, vue l'imminence de l'épuisement.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : J. Chu, N. Dukkipati, Y. Cheng, M. Mathis (Google)
Expérimental
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 30 avril 2013
Sur l'Internet, il y a des choses qu'on hésite à toucher. Depuis quelques épisodes fameux de « catastrophes congestives », où tout l'Internet s'est arrêté en raison de l'encombrement des tuyaux, la mémoire collective du réseau, incarnée notamment par l'IETF, voit avec une extrême méfiance toute modification des algorithmes de TCP, qui sont la principale ligne de défense de l'Internet face à la congestion. Néanmoins, le réseau évolue, les choses changent et il y a des gens qui insistent pour essayer des changements. Cela fait un certain temps que Google réclame une modification connue sous le doux nom de IW10 (pour Initial Window 10 segments) et ce RFC est le premier à la documenter officiellement, après trois ans de discussion dans le groupe de travail. Pour l'instant, c'est encore étiqueté comme « expérimental ».
La norme reste celle du RFC 3390. Elle dit que la fenêtre initiale d'une connexion TCP, à savoir le nombre maximal d'octets qu'on peut envoyer avant le premier accusé de réception, est donnée par une formule qui, en pratique est d'environ 4 kilo-octets, soit deux à trois segments (paquets TCP), parfois quatre. Voici, vu par tcpdump sur le client, un exemple entre deux machines séparées par 100 ms de RTT, un client HTTP qui demande un gros fichier et un serveur :
21:54:15.371487 IP 204.62.14.153.80 > 192.168.2.1.57886: Flags [.], seq 1:1449, ack 118, win 1810, options [nop,nop,TS val 1079804426 ecr 2768078], length 1448 21:54:15.371509 IP 192.168.2.1.57886 > 204.62.14.153.80: Flags [.], ack 1449, win 137, options [nop ,nop,TS val 2768109 ecr 1079804426], length 0 21:54:15.372574 IP 204.62.14.153.80 > 192.168.2.1.57886: Flags [.], seq 1449:2897, ack 118, win 181 0, options [nop,nop,TS val 1079804426 ecr 2768078], length 1448 21:54:15.372593 IP 192.168.2.1.57886 > 204.62.14.153.80: Flags [.], ack 2897, win 182, options [nop ,nop,TS val 2768109 ecr 1079804426], length 0 21:54:15.372615 IP 204.62.14.153.80 > 192.168.2.1.57886: Flags [.], seq 2897:4345, ack 118, win 181 0, options [nop,nop,TS val 1079804426 ecr 2768078], length 1448 21:54:15.372630 IP 192.168.2.1.57886 > 204.62.14.153.80: Flags [.], ack 4345, win 227, options [nop ,nop,TS val 2768109 ecr 1079804426], length 0 21:54:15.372897 IP 204.62.14.153.80 > 192.168.2.1.57886: Flags [P.], seq 4345:5793, ack 118, win 18 10, options [nop,nop,TS val 1079804426 ecr 2768078], length 1448 21:54:15.372910 IP 192.168.2.1.57886 > 204.62.14.153.80: Flags [.], ack 5793, win 273, options [nop ,nop,TS val 2768109 ecr 1079804426], length 0 21:54:15.488019 IP 204.62.14.153.80 > 192.168.2.1.57886: Flags [.], seq 5793:7241, ack 118, win 181 0, options [nop,nop,TS val 1079804455 ecr 2768109], length 1448
On voit que 204.62.14.153
a envoyé quatre
segments avant de devoir s'arrêter, les accusés de réception n'ayant
pas eu le temps de l'atteindre. La pause dure 116 ms, avant que le
serveur ne reprenne son envoi.
Ce nombre de segments est trop petit (bien plus petit que les tampons d'entrée/sortie d'un équipement réseau typique) car, sur les réseaux modernes, cela veut dire qu'un pair TCP qui veut envoyer un gros fichier va très vite remplir cette fenêtre et va devoir attendre ensuite, alors qu'il ne sait absolument pas si le réseau est congestionné ou pas. D'où la proposition IW10 qui est de permettre l'envoi de dix segments. (Pourquoi dix ? Comme l'explique l'annexe A, c'est le résultat de tests avec plusieurs valeurs possibles. Dix était la valeur qui était le meilleur compromis entre les gains et les inconvénients. Regardez le dessin 2 dans l'article An Argument for Increasing TCP's Initial Congestion Window si vous avez besoin d'être convaincu : il montre un progrès jusqu'à 16 et une baisse ensuite. Notez qu'une des techniques étudiées par le groupe de travail - et finalement abandonnée - avait été un système complexe de mesure et de rétroaction, avec des tailles initiales de fenêtre variables.)
La formule proposée par ce RFC (section 2) est fenêtre_initiale (en octets) = minimum (10*MSS, maximum (2*MSS, 14600)). Cela pourra faire jusqu'à dix segments, en fonction de la MSS. Naturellement, la machine aura le droit de choisir une fenêtre plus petite, ce choix n'est en effet pas dangereux ; mais pas de fenêtre plus grande, le but étant d'éviter la congestion de réseau.
Notez bien que cette formule ne s'applique qu'au début de la connexion. Lorsque TCP reprend son algorithme de démarrage en douceur (slow start), par exemple suite à des pertes de paquets, il doit s'en tenir au RFC 2581.
Il y a aussi quelques questions pratiques à se poser. Par exemple, une connexion TCP est bi-directionnelle : ce n'est pas tout d'utiliser une fenêtre plus grande à l'émission, il faut aussi annoncer à son pair une fenêtre de réception plus grande (cf. « An Argument for Increasing TCP's Initial Congestion Window » de Dukkipati, N., Refice, T., Cheng, Y., Chu, J., Sutin, N., Agarwal, A., Herbert, T. et J. Arvind, article de 2010 qui va être souvent cité ici et dont je recommande fortement la lecture. À l'époque de l'article, la plupart des systèmes annonçaient cette grande fenêtre, sauf Linux.)
Ce changement a des conséquences pour les applications qui utilisent TCP (section 3). Ainsi, HTTP 1.1 n'autorisait que deux connexions TCP simultanées vers le même serveur (RFC 2616, section 8.1.4, mais le RFC 7230 a libéralisé cette consigne). Les navigateurs en ouvrent en général plus que cela, pour éviter l'attente due à la faible taille de la fenêtre TCP. (Voir « A Swifter Start for TCP », par Partridge, C., Rockwell, D., Allman, M., Krishnan, R. et J. Sterbenz, rapport technique n° 8339 de BBN en 2002.) C'est égoïste de leur part (cela s'oppose aux mécanismes de contrôle de congestion de TCP) et cela ne devrait logiquement plus être nécessaire avec le déploiement d'IW10. Le RFC conseille donc de réduire le nombre de connexions HTTP simultanées.
La section 4 du RFC donne des éléments de contexte et d'histoire. Au début (cf. le célébrissime article de Van Jacobson, « Congestion Avoidance and Control », en 1998), TCP ne pouvait envoyer qu'un seul segment avant de recevoir le premier accusé de réception. Ce n'était pas un problème pour de longues communications, comme celles de telnet. Mais l'Internet aujourd'hui voit surtout du trafic Web (cf. « Atlas Internet Observatory 2009 Annual Report » de Labovitz, C., Iekel-Johnson, S., McPherson, D., Oberheide, J. Jahanian, F. et M. Karir, présenté à NANOG 47 en 2009.), avec des connexions de courte durée. Attendre longtemps avant de pouvoir envoyer plusieurs segments est très pénalisant (la plupart de ces connexions courtes ne quitteront jamais l'état TCP « démarrage en douceur »).
Surtout, les changements dans la capacité des réseaux ont été spectaculaires. Le rapport « The State of the Internet » d'Akamai en 2010, annonce que les accès à plus de 2 Mb/s forment désormais la majorité, ce qui met la capacité moyenne à 1,7 Mb/s, alors que, pendant ce temps, la fenêtre d'envoi initiale de TCP restait aux 4 ko du RFC 2414, sans bouger pendant dix ans. Avec un RTT de 200 ms, cette fenêtre ne permettait que 200 kb/s.
Des tas de changements avaient été proposés (pour ne citer que les RFC, voir RFC 4782 et RFC 6077) mais sans être réellement déployés. Ce sont donc les applications qui se sont adaptées, comme vu plus haut avec les navigateurs qui ouvrent plusieurs connexions, et les sites Web créant des sous-domaines sans autre raison que de débrayer la limitation du nombre de connexions par serveur (cf. « A Client-Side Argument For Changing TCP Slow Start » en 2010). Le déploiement d'IW10 devrait logiquement s'accompagner d'un changement de stratégie de ces navigateurs Web.
Au fait, en parlant d'HTTP, les connexions persistentes de HTTP 1.1 ne devraient-elles pas résoudre le problème ? Le problème est que les mesures faites avec Chrome (article de Dukkipati et al. cité plus haut) montrent que 35 % des requêtes sont faites sur des nouvelles connexions, ne pouvant pas tirer profit des connexions persistentes.
Bon, mais, au fait, quels sont les avantages exacts qu'il y a à agrandir la fenêtre initiale ? La section 5 les examine en détail. D'abord, on réduit la latence. Par exemple, si on a 21 segments à envoyer, IW3 (fenêtre initiale de trois segments) va nécessiter 4 aller-retour (envoi de données + attente de l'accusé de réception) contre 2 pour IW10. Ensuite, une telle augmentation est cohérente avec l'augmentation régulière de taille des objets. Par exemple, sur le Web, les études citées par le RFC (mesures faites sur le moteur de recherche Google) montrent que seules 10 % des ressources sur le Web tiennent encore dans les 4 ko du RFC 3390. En outre, si on utilise les connexions persistentes de HTTP 1.1, on aura encore plus de données à transmettre sur une connexion HTTP. Le Web grossit, il est logique que la fenêtre initiale de TCP suive le mouvement.
Et il n'y a pas d'inconvénients à augmenter la taille de la fenêtre initiale ? Les sections 6 et 7 décrivent le côté obscur. D'abord, en section 6, les risques pour l'utilisateur. Il y a notamment le risque de remplir complètement les tampons d'entrée-sortie dès le démarrage, pour des petits routeurs. Le RFC estime toutefois que ce risque est faible avec les tampons actuels, en s'appuyant sur l'étude « Characterizing Residential Broadband Networks » de Dischinger, M., Gummadi, K., Haeberlen, A. et S. Saroiu, en 2007, qui montre que le routeur typique de M. Michu a au moins 130 ms de tampon.
Ça, c'était pour l'utilisateur. Et pour le réseau (section 7) ? Risque t-on davantage de congestion ? Probablement pas puisque IW10 ne s'applique qu'au début de la connexion. Tout le reste du mécanisme de contrôle de la congestion de TCP reste en place, inchangé, notamment sa réaction aux pertes de paquets. En revanche, il peut y avoir un problème de justice. Tant qu'une partie des machines applique IW10 et qu'une autre partie en est resté au RFC 3390, les machines IW10 vont prendre une part plus grande des ressources réseau (c'est une question générale de l'Internet : la répartition juste entre différentes connexions concurrentes dépend de leur bonne volonté). C'est donc un point à surveiller. (Un autre problème de justice est traité dans l'annexe A, entre des machines toutes IW10 mais où certaines n'ont pas dix segments à envoyer. Les mesures semblent indiquer que ces dernières machines ne sont pas défavorisées.)
Autre inconvénient possible : comme IW10 remplit plus vite les tampons d'entrée/sortie des routeurs, si ceux-ci sont trop grands (phénomène du bufferbloat), IW10 va aggraver le problème. Les protocoles sensibles à la latence comme le DNS ou certains jeux vont alors souffrir. Les mécanismes proposés comme alternative au bufferbloat (ECN, AQM, etc) sont alors encore plus nécessaires.
En synthèse (section 8), le RFC estime que le plus gros risque est pour les utilisateurs ayant des liaisons lentes avec des tampons d'entrée/sortie réduits, dans leur box. Les 10 segments initiaux peuvent, dans certains cas, faire déborder ces tampons, le réseau ne pouvant pas les envoyer assez vite. Le RFC suggère, si on détecte qu'on est sur un tel lien, de ne pas envoyer forcément les dix segments autorisés, et d'annoncer une fenêtre de réception plus petite. Voir aussi le RFC 3150, sur le problème général de ces liens lents.
La théorie, c'est bien joli mais, quand elle dit qu'il ne faut pas trop s'inquiéter, il est prudent de vérifier par des mesures effectives, pas juste des raisonnements. C'est ce que fait la section 10. L'expérience a été faite par Google dans deux de ses centres de données, l'un voyant plutôt des clients ayant la capacité réseau moyenne, l'autre ayant en moyenne des utilisateurs de connexions lentes (20 % à moins de 100 kb/s). Avec IW10, la latence a baissé de 11,7 % dans le centre moyen et 8,7 % dans le centre lent. En regardant plus finement, les auteurs ont constaté que, comme l'indiquait la théorie, les bénéfices les plus importants d'IW10 ont été pour les gens situés loin (forte latence réseau) mais ayant des connexions rapides (ce qu'on nomme le BDP élévé avec BDP = Bandwidth-Delay Product). Mais, contrairement à la théorie, même les clients à capacité réseau limitée ont vu une amélioration. (Voir l'exposé « Increasing TCP initial window » de Dukkipati, D., Cheng, Y., Chu, J. et M. Mathis, présenté à l'IETF 78 en 2010.) Aucun problème grave n'a été observé.
D'autres expériences ont été faites, listées sur le site Web du projet IW10 ou en section 11 de ce RFC. Notez toutefois que la plupart sont des simulations, pas des mesures sur le vrai Internet. Mais ce n'est pas forcément très grave, l'étude de Google, par son ampleur, a semblé largement suffisante. Bien des RFC ont été adoptés sans une aussi grande étude préalable !
L'annexe A du RFC contient une liste d'inquiétudes théoriques sur IW10 et les résultats des tests spécifiquement liés à chacune de ces inquiétudes. Ainsi, le taux de pertes de paquets n'a pas augmenté lors des tests, sauf lors de cas extrêmes où, même avec les valeurs du RFC 3390, le phénomène de pertes se produisait. De même, des mesures ont été faites en Afrique, pas seulement en Europe et en Amérique du Nord, pour s'assurer qu'IW10 n'aurait pas d'effet pénible pour les liens moins favorisés.
En conclusion, le RFC recommande (section 12) d'activer IW10 mais que les fournisseurs de mises en œuvre de TCP et/ou les administrateurs réseau surveillent le trafic, à la recherche d'indicateurs comme le taux de pertes de paquet, pour détecter une éventuelle augmentation des phénomènes négatifs.
Ce changement de la fenêtre initiale est déjà apparue dans certains
systèmes. Par exemple, pour Linux, cela a été
fait en 2011 dans le commit
git
442b9635c569fef038d5367a7acd906db4677ae1
. Notez
que, sur Linux, ip route ... initcwnd N
vous
permet d'ajuster cette variable, pour expérimenter.
Un peu de lecture supplémentaire ? Le premier exposé sur IW10 date de
2010. Une argumentation hostile à IW10 ? Vous pouvez lire
l'Internet-Draft draft-gettys-iw10-considered-harmful
.
Date de publication du RFC : Mai 2013
Auteur(s) du RFC : J. Levine (Taughannock Networks), P. Hoffman (VPN Consortium)
Pour information
Première rédaction de cet article le 7 mai 2013
Beaucoup d'utilisateurs des noms de domaine pensent que deux noms qui,
pour eux, sont « le même », devraient être traitées d'un bloc par le
DNS et/ou par les systèmes d'enregistrement de
noms. Tout le problème est évidemment de définir « le même » : il n'y
a en général pas d'accord entre les utilisateurs sur ce point. Ainsi,
des anglophones peuvent penser que
meter.example
et
metre.example
sont « le même nom » et devraient
donc se comporter ainsi. D'autres pensent que
pizzeria-napoli.example
et
pizzerianapoli.example
sont « le même nom ». Et,
évidemment, depuis l'arrivée des IDN, le
potentiel pour des noms « identiques » a encore augmenté. Il a donc
été proposé que ces variantes d'un « même » nom
soient explicitement reconnues. Ce RFC ne
suggère pas de mécanisme en ce genre (je pense personnellement que le
problème est bien trop flou et subjectif pour cela). Il se contente de
regarder les pratiques actuellement déployées par les
registres en matière de « variantes ».
Des exemples de caractères qui sont une « variante » d'un autre ne
manquent pas dans les écritures du monde. Ainsi, la
Chine a connu sous Mao
une réforme orthographique, passant des
sinogrammes
« traditionnels » aux
« simplifiés ». La plupart des sinophones
considèrent que 雲
et 云
sont des variantes du même mot. Dans les langues utilisant
l'alphabet latin avec des
accents, certains considèrent que le mot avec
et sans accent sont des variantes l'un de l'autre. Le RFC note qu'en
français certains omettent les accents sur les majuscules (c'est
incorrect, mais cela se fait parfois) et que donc
INTERNÉ
et INTERNE
sont
considérés comme « équivalents ». Ce qui est sûr, c'est
qu'historiquement, les difficultés à manier les caractères
non-ASCII dans beaucoup d'environnements
informatiques avaient mené bien des utilisateurs à considérer les
accents comme purement décoratifs, et pouvant être omis.
Est-ce que ce vague sentiment que deux groupes de caractères sont
« la même chose » peut être formalisé dans une définition rigoureuse
des « variantes » ? Il y a eu quelques tentatives comme à
l'ICANN, ou à l'IETF dans le RFC 3743 (non standard). Mais un autre
document de la même ICANN concluait
qu'il n'existait pas de définition utilisable. Ensuite, sur le
comportement attendu de deux noms identiques ne fait pas non plus
l'objet d'un consensus. Par exemple, si on veut, non pas seulement une
réponse identique dans le DNS, mais un vécu de
l'utilisateur identique, par exemple sur le
Web, il n'y a aucune solution purement DNS (en
raison du comportement de HTTP avec le champ
Host:
). Si vous voulez lire davantage sur cette
question, je vous renvoie à mon article « Que veut dire synchroniser deux
domaines ? ».
Ce RFC n'essaie donc pas de régler ce problème (très ancien et sans doute insoluble). Il fait un tour d'horizon des pratiques des gTLD (qui sont contractuellement obligés par l'ICANN de rédiger leurs pratiques IDN et de les déposer à l'ICANN, et qui rendent accessibles le contenu de leurs zones, permettant aux chercheurs de l'étudier) et d'un certain nombre de ccTLD. Ces obligations de l'ICANN sont décrites dans « Guidelines for the Implementation of Internationalized Domain Names ». Le RFC note que ces règles ne sont guère respectées, les politiques déposées à l'ICANN étant souvent dépassées et plus à jour (URL cassés, personnes désormais parties, etc). (Mon opinion personnelle est que ces « IDN Guidelines » n'ont aucun sens et sont motivées par des frayeurs bureaucratiques plutôt que par des considérations pratiques.)
Pensez à réviser la terminologie en section 2. Un lot (bundle, on dit aussi IDL package) est un ensemble de noms qui sont tous des variantes les uns des autres (RFC 3743). Un nom est alloué (allocated) ou enregistré s'il est attribué à un titulaire. Il est actif (active) s'il apparait dans le DNS. Il est bloqué (blocked) s'il ne peut pas être alloué du tout et réservé (witheld) s'il ne peut être alloué que dans certaines conditions.
La section 4 décrit les politiques des gTLD (avec vérification dans
les fichiers de zone de la réalité de ces politiques). Certains sont
faciles : .aero
,
.coop
ou .pro
n'ont pas
d'IDN (même chose pour .xxx
). D'autres ont un grand intérêt pour les IDN. Ainsi,
.asia
a évidemment une
politique
IDN détaillée, avec gestion de lots, via les enregistrements
NS (les variantes ont le même jeu de
NS). .cat
a un cas plus
simple que .asia
puisqu'il ne reconnait qu'une
seule langue, le catalan. La liste des
caractères autorisés est
publiée et elle comprend des caractères comme le l·l
(considéré comme un caractère en catalan mais représenté par trois
caractères Unicode). Lorsqu'on enregistre un nom IDN, l'ASCII
« équivalent » est aussi enregistré et un DNAME
(RFC 6672) est mis dans le fichier de
zones (il semble que cela soit le seul gTLD à procéder ainsi). Par
exemple :
xn--caball-gva.cat. 43200 IN DNAME caballe.cat.
Le nom IDN caballé.cat
pointant vers
l'ASCII caballe.cat
(et merci à DNSDB pour permettre l'exploration facile du DNS
à la recherche d'exemples).
Contrairement à .asia
et a fortiori à
.cat
,
.com
doit gérer toutes les
écritures du monde. VeriSign a transmis à
l'ICANN des tables pour des écritures
hiéroglyphiques et pour
l'araméen... Les politiques suivies sont
décrites en détail dans plusieurs documents (voir la liste dans la
bibliographie du RFC). Pour l'écriture
chinoise, et pour elle seule, les variantes d'un nom
alloué sont
bloquées. (.net
et
.name
suivent la même
politique que .com
.)
.org
publie une liste des langues gérées (notez que
c'est absurde puisque IDN gère des écritures, pas des langues, mais
cette confusion est fréquente dans les cercles ICANN, où il est
toujours mal admis que des gens osent utiliser d'autres écritures que
celle des États-Unis). Les tables déposées à l'ICANN sont un
sous-ensemble de ces tables publiées par le registre (pas de mise à
jour ?) Les documentations officielles de .org
font allusion à une politique
de gestion des variantes mais apparemment sans dire en quoi consiste
cette politique.
.tel
a beaucoup d'IDN
et une politique
publique. Les noms avec l'écriture
japonaise utilisent un système de blocage (le premier
arrivé empêche l'allocation des variantes) alors que pour l'écriture
chinoise, les variantes sont publiées (avec des enregistrements NS identiques).
La section 5 passe aux ccTLD. Je ne vais pas tous les citer mais
ils ont souvent des politiques
intéressantes. .cl
publie sa
politique, qui ne tient pas compte d'éventuelles variantes.
.cn
a évidemment plus
de travail : leur politique est publiée sous forme d'un
RFC, le RFC 4713. Les
variantes sont publiées, avec des enregistrements NS. Par contre,
.ir
n'a pas d'IDN. Comme
un certain nombre de registres des pays utilisant
l'écriture arabe (qui va de droite à gauche),
ils considèrent que le mélange d'un nom en écriture arabe avec un
TLD en écriture latine (allant de gauche à droite) n'est pas
souhaitable. (Mais il y a des IDN dans le TLD équivalent en écriture arabe, ایران.
)
Bien que TLD d'un pays majoritairement anglophone,
.nz
a une politique IDN (qui ne
parle pas des variantes) pour le maori. On
notera que le domaine compte des DNAME par exemple
māori.dns.net.nz
qui pointe vers l'équivalent
ASCII :
xn--mori-qsa.dns.net.nz. 86400 IN DNAME maori.dns.net.nz.
Contrairement aux autres ccTLD, il semble que
.ru
ne publie pas sa
politique directement, uniquement via la table déposée à l'ICANN.
La politique utilisée par
.fr
n'est pas étudiée dans
ce RFC. Elle est disponible
en ligne.
La liste des caractères acceptés figure en section 2 (ce sont les
caractères utilisés pour les langues d'Europe de l'Ouest). S'il y a eu
un système de variantes pendant la période d'ouverture (section 4), il
a ensuite disparu.
Voilà, si vous voulez approfondir la question et voir la politique des autres TLD, consulter ce RFC. J'espère en tout cas avoir donné une bonne idée de la variété des écritures du monde et des solutions pour les gérer dans les noms de domaine.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : B. Leiba (Huawei)
Pour information
Première rédaction de cet article le 11 avril 2013
Dans la grande famille des URN,
l'IETF avait son propre espace, commençant par
ietf
. Mais il n'existait pas de registre des
sous-espaces de ietf
. C'est désormais fait.
Le RFC 2648 avait créé cet espace
ietf
. Il avait quelques sous-espaces comme
rfc
(donc, par exemple, ce
RFC est urn:ietf:rfc:6924
.) Le RFC 3553 avait
créé un nouveau sous-espace params
, et un registre pour ce sous-espace. Ainsi, on voit des
URN comme
urn:ietf:params:xml:ns:vcard-4.0
(RFC 6350) ou
urn:ietf:params:xml:ns:netconf:base:1.0
(RFC 6241). Mais peut-on créer encore d'autres sous-espaces
que params
? Et où les décrire ?
Un registre existe désormais à cette fin. Il sera rempli selon la procédure (assez lourde) « examen par l'IETF » du RFC 5226. On n'y trouve pour l'instant que les sous-espaces des RFC 2648 et RFC 3553.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : Y. Shafranovich (BioFortis)
Pour information
Première rédaction de cet article le 11 avril 2013
Premier enregistrement d'un nouveau type de données (type
MIME) fait depuis les nouvelles règles du RFC 6838, ce RFC enregistre un
type très ancien mais qui n'avait jamais été normalisé,
application/sql
, pour le code source
SQL.
Donc, les nouvelles procédures du RFC 6838
marchent, même pour un type très ancien. SQL a
plus de trente ans d'usage derrière lui. La section 3 contient le
formulaire d'enregistrement du nouveau type
application/sql
. Ce formulaire rempli met en
garde contre quelques pièges de SQL comme le fait que
l'encodage puisse être indiqué dans le fichier
(ce qui rend inutile le paramètre charset
du type
MIME), ou comme les problèmes de sécurité si un client était assez
naïf pour exécuter aveuglément du SQL récupéré sur le réseau (quoique
j'ai rarement vu du malware
en SQL...). Le formulaire d'enregistrement comprend aussi une section
sur les problèmes d'interopérabilité et elle note que, bien que SQL
soit une norme ISO (norme 9075.2011, pas
disponible en ligne), les
différences entre mises en œuvre du langage sont quand même très
grandes. Verra t-on un jour des types plus spécifiques comme
application/oracle+sql
ou application/postgres+sql
?
J'ai modifié la configuration Apache de ce blog pour y ajouter :
AddType application/sql .sql
Et, désormais, des fichiers comme joins.sql
(cité dans
cet article) sont servis avec le
nouveau type MIME. N'était-ce pas mieux en text/plain
(par défaut affiché dans le navigateur) ? J'hésite.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : S. Farrell (Trinity College Dublin), D. Kutscher (NEC), C. Dannewitz (University of Paderborn), B. Ohlman, A. Keranen (Ericsson), P. Hallam-Baker (Comodo Group)
Chemin des normes
Première rédaction de cet article le 22 avril 2013
Dernière mise à jour le 23 avril 2013
La question des identificateurs sur le
Web agite des électrons depuis le début. Il
n'existe pas d'identificateurs idéaux, ayant toutes
les bonnes propriétés. Dans la grande famille des
URI (RFC 3986), il faut donc choisir selon l'importance
qu'on donne à tel ou tel critère. Par exemple, si on attache du prix à
la stabilité de l'identificateur et qu'on veut qu'il ne désigne pas
seulement un endroit où se trouve un contenu, mais qu'on veut qu'il
désigne ce contenu et pas un autre ? Alors, on peut choisir les
nouveaux URI ni:
(Named
Information) qui désignent un contenu par un
condensat (hash). Un URI
ni:
ne change pas si le contenu change de
serveur, mais il est modifié si le contenu lui-même change. C'est donc
une forme d'adressage par le contenu.
À quoi cela sert ? À éviter un problème de l'indirection : si je
dis « regardez l'image en
http://www.example.org/holidays/beach.png
» et
que l'image de vacances à la plage est remplacée par une photo de
LOLcat, l'URI sera
toujours valable, alors que le contenu a changé. Inversement, si un
webmestre incompétent et qui n'a pas lu
« Cool URIs don't change »
réorganise le site et met le contenu en
http://www.example.org/bigcomplicatedcmswithsecurityholes.php?kind=image&tag=beach&foo=bar&id=612981
,
l'URI ne marchera plus alors que le contenu est inchangé. Un autre
exemple, plus positif, est le cas où un contenu est répliqué en
plusieurs endroits, ayant des URL
différents. Il faut pouvoir désigner le contenu, indépendamment du
service qui l'héberge. C'est pour
répondre à ces deux problèmes qu'a été créé par ce
RFC le plan d'URI ni:
(désormais dans le registre IANA des plans d'URI). Le
contenu en question pourra donc être désigné par
ni:///sha256;rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc
. Une
telle technique a déjà été employée mais de manière non standard (par
exemple, on voit parfois des URI du genre
http://www.example.org/hash?function=sha256&value=rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc
où un programme situé sur www.example.org
récupère la ressource selon le contenu). Désormais, le but est de
permettre du vrai adressage par le contenu sur le Web. Cela se nomme
information-centric sur les
PowerPoint des gourous. Sur ce sujet, le RFC recommande la lecture de « Design
Considerations for a Network of Information » de Ahlgren, D'Ambrosio, Dannewitz, Marchisio, Marsh, Ohlman,
Pentikousis, Rembarz, Strandberg, et Vercellone, ainsi que des articles de Van Jacobson. On peut
aussi lire des articles sur les autres mécanismes d'adressage par le
contenu comme les magnet links de plusieurs systèmes
pair-à-pair, comme Freenet.
Une fois le contenu récupéré (en HTTP ou par d'autres moyens), le lecteur peut alors recalculer le condensat et vérifier s'il a bien reçu le bon fichier (des protocoles comme BitTorrent utilisent un mécanisme analogue pour s'assurer que le fichier transmis par les pairs est bien celui qu'on voulait).
D'autres informations peuvent se retrouver dans l'URI
ni:
(voir des exemples plus loin) mais la
comparaison de deux URI ni:
se fait uniquement
sur le couple {fonction de hachage utilisée,
valeur du condensat}.
Le condensat est calculé par une fonction de hachage
cryptographique et, par défaut, c'est
SHA-256 (vous avez noté le
sha256
dans l'URI ni:
donné
en exemple plus haut ?) Les valeurs possibles pour l'algorithme de
hachage figurent dans un nouveau
registre. Les nouvelles valeurs sont enregistrées selon une
procédure légère d'examen par un expert (RFC 5226 et section 9.4 de notre RFC).
Les condensats de SHA-256 sont de grande taille, parfois trop pour
certaines utilisations. On a donc le droit de les tronquer à leurs N
premiers bits et le nom d'algorithme indiqué doit préciser cette
troncation. Ainsi, si on garde les 32 premiers bits, on doit indiquer
sha256-32
et pas juste
sha256
. Attention, c'est évidemment au détriment
de la sécurité (si la sortie de SHA-256 est si longue, c'est pour une
bonne raison, cf. RFC 3766) et ces condensats raccourcis, quoique simples à
manipuler, ne protègent plus tellement. (Notez que le
VCS git, qui identifie
les commits par un condensat
cryptographique, permet également de les raccourcir, pour faciliter
son utilisation, par exemple depuis le
shell.)
Le format exact des URI ni:
figure en section
3. On note un composant dont je n'ai pas encore parlé, l'autorité. On
peut écrire
ni:///sha256;rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc
mais aussi
ni://www.example.net/sha256;rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc
. L'autorité
(ici, www.example.net
) désigne un endroit où on
pourra peut-être récupérer la ressource. Le gros problème des
identificateurs fondés sur le contenu du fichier, en effet, est qu'ils
sont inutiles pour accéder effectivement au fichier : pas moyen de
télécharger un fichier dont on ne connait que le condensat ! Il existe
plusieurs solutions et l'une d'elles est de passer par
l'autorité. L'idée est que l'URI ni:
est
automatiquement transformé en un URL HTTP sous
.well-known
(cf. RFC 8615 et section 4 de notre RFC). Ainsi,
ni://www.example.net/sha256;rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc
devient
http://www.example.net/.well-known/ni/sha256/rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc
qu'on peut ensuite récupérer par des moyens classiques. On combine
alors les avantages de l'adressage par le contenu (le condensat est là
pour vérifier le contenu) et du fait que les URL marchent bien pour
récupérer un contenu. On notera que le système d'identificateurs
ARK a un mécanisme analogue (un identificateur
stable et non résolvable plus un préfixe qui
permet de faire un URL résolvable et actionnable). On a ainsi le beurre
et l'argent du beurre. ni
fait désormais partie
des termes enregistrés dans le registre "well-known".
Petite question : pourquoi http:
et pas
https:
, qui serait plus sûr ? Parce que tous les
serveurs ne gèrent pas HTTPS et aussi parce que
ce n'est pas nécessaire pour s'assurer de l'intégrité du fichier
récupéré, le condensat cryptographique suffit. Bien sûr, une mise en
œuvre de ce RFC est autorisée à essayer avec HTTPS, par exemple
pour la confidentialité.
Comme indiqué plus haut, la comparaison entre deux URI
ni:
se fait uniquement sur le couple {algorithme,
condensat} donc ni://datastore.example/sha256;rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc
et
ni://www.example.net/sha256;rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc
sont identiques.
Au fait, SHA-256 peut être affiché en binaire ou bien sous une
forme hexadécimale. Laquelle est utilisée ? Le format binaire
suivi d'un encodage en
Base64 (RFC 4648), sous
sa forme URL encoding, celle qui utilise
_ et - au lieu de
/ et + (ce n'est pas la forme par
défaut : songez que l'outil base64
sur Unix ne permet pas de produire cette
variante).
Si on n'a pas besoin d'être lisible par des humains et
transmissible dans des textes, il existe aussi une forme binaire, plus
compacte, des URI ni:
, spécifiée en section
6.
Signe de leur souplesse, les URI ni:
ont
également une forme « prononçable ». S'il faut dicter un URI au
téléphone, l'encodage par défaut est très ambigu (par exemple,
minuscules et majuscules n'ont pas la même
valeur). D'où la syntaxe nih:
(NI for
Humans et non pas Not Invented Here, cf. RFC 5513) de la section
7. Les URI sous leur forme nih:
sont en
Base16 (RFC 4648), peuvent inclure
des tirets supplémentaires, pour la lisibilité,
et incluent une somme de contrôle (le dernier
chiffre, calculé selon l'algorithme de Luhn de
la norme ISO 7812) pour détecter les erreurs de
compréhension. Un exemple est nih:sha-256-120;5326-9057-e12f-e2b7-4ba0-7c89-2560-a2;f
.
Enfin, des paramètres peuvent apparaître dans l'URI, par exemple
pour indiquer le type de la ressource
(ni:///sha256;rJAeWFhQWIoTExwyEQ8w_L5uB0UkfmnCGfNIPy7CdDc?ct=image/png
). Une
liste de paramètres possibles est enregistrée.
À noter que l'abréviation ni
veut
officiellement dire Named Information mais que tout
geek va évidemment penser aux chevaliers qui disent Ni...
Avant d'utiliser les URI ni:
, il est prudent
de lire la section 10, consacrée aux questions de sécurité. Ainsi, il
ne faut pas oublier que le condensat cryptographique n'est
pas une signature. Il sert
à vérifier l'intégrité mais, comme n'importe qui peut générer un
condensat pour n'importe quel contenu, il ne prouve rien quant à
l'authenticité.
La fonction SHA-256 et ses camarades ne sont
pas inversibles. D'un condensat, on ne peut pas remonter au
contenu. Toutefois, celui-ci n'est pas vraiment secret. Un attaquant
peut toujours deviner plus ou moins le contenu (c'est particulièrement
facile si le contenu est très structuré, avec peu de variations
possibles) et tester les différentes possibilités. Il peut aussi
utiliser un moteur de recherche, si des pages
existent déjà avec la correspondance entre une ressource et son
condensat (pour empêcher cela, il faudrait que les condensats
ni:
soient salés, ce qui
n'est pas le cas).
Et, naturellement, si vous utilisez des condensats tronqués, comme le permet de RFC, vous perdez beaucoup en sécurité.
La notion d'autorité dans les URI
ni:
peut être trompeuse. Le nom de domaine qui peut apparaître dans un URI
ni:
n'est pas forcément la source du contenu,
puisque n'importe qui peut copier la ressource, et la servir depuis un
programme. Il ne faut donc pas attribuer de sémantique à la soi-disant « autorité ».
Si vous voulez regarder un tel système « en vrai », les articles de
ce blog sont tous accessibles via un URI
ni:
. L'identificateur est calculé toutes les
nuits et stocké dans une base de données. Un simple petit programme
WSGI permet ensuite de récupérer un fichier
en fonction de son identificateur. À noter que ce n'est pas la forme
HTML qui est utilisée mais le source en
XML (la forme en HTML change trop souvent, par
exemple si les outils qui la produisent automatiquement à partir du
source sont modifiés). Ainsi, l'URI
ni:///sha256;6OuucQ1RgugCDVinT2RGmzYYpra0fenH-zw7tilsx9k
correspond au source XML de cet
article. En indiquant explicitement l'autorité (le serveur qui
permet de faire la récupération), c'est l'URI
ni://www.bortzmeyer.org/sha256;6OuucQ1RgugCDVinT2RGmzYYpra0fenH-zw7tilsx9k
. Et
la version sous forme d'URL est
. Si
vous préferez un autre article,
https://www.bortzmeyer.org/.well-known/ni/sha256/6OuucQ1RgugCDVinT2RGmzYYpra0fenH-zw7tilsx9k
ni:///sha256;1etMCVZtd7_cq38MrtnQcoZW_e7J2cslulrFp92lueI
correspond au source de cet article.
Notez qu'il n'est pas possible de mettre l'URI
ni:
de l'article que vous êtes en train de lire
dans cet article (inclure le condensat change l'article et il faut
donc changer le condensat, ce qui change l'article...)
Vous voulez vérifier ? Allons-y.
% wget -O /tmp/x.xml https://www.bortzmeyer.org/.well-known/ni/sha256/1etMCVZtd7_cq38MrtnQcoZW_e7J2cslulrFp92lueI ... % openssl dgst -sha256 -binary /tmp/x.xml | base64 1etMCVZtd7/cq38MrtnQcoZW/e7J2cslulrFp92lueI=
Et on retrouve bien l'identificateur 1etMCVZtd...
(aux transformations URL encoding près).
Si vous voulez faire depuis le shell Unix les calculs nécessaires, voici quelques exemples avec OpenSSL. Pour calculer le NI de Hello World! :
% echo -n 'Hello World!' | openssl dgst -sha256 -binary | base64 f4OxZX/x/FO5LcGBSKHWXfwtSx+j1ncoSt3SABJtkGk=
Il faut ensuite rechercher/remplacer car base64
(ou bien la commande
openssl enc -base64
) ne sait pas faire de
l'URL encoding de Base64. Avec
sed :
% echo -n 'Hello World!' | openssl dgst -sha256 -binary | base64 | sed -e 's#/#_#g' -e 's#+#-#g' -e 's#=$##' f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk
(Pour la même manipulation, on peut aussi utiliser tr :
tr -cd a-zA-Z0-9+/ | tr +/ -_
. Comme expliqué par
Kim-Minh Kaplan : « Note le tr -cd
pour nettoyer le résultat de l’encodage en Base 64.
Si avec SHA-256 il n’est pas nécessaire, avec SHA-512, l’encodeur
d’OpenSSL introduira un retour à la ligne qu’il faudra aussi supprimer. »)
Si on reprend l'exemple plus haut, on peut combiner les deux opérations : on récupère le fichier grâce au condensat et on vérifie que le contenu est bien le contenu attendu. Utilisons ce simple script :
#!/bin/sh BASE_URL="https://www.bortzmeyer.org/.well-known/ni/sha256/" if [ -z "$1" ]; then echo "Usage: $0 ni" >&2 exit 1 fi ni=$1 hash=$(wget -q -O - ${BASE_URL}/${ni} | openssl dgst -sha256 -binary | openssl enc -base64 | \ sed -e 's#/#_#g' -e 's#+#-#g' -e 's#=$##') if [ "$hash" != "$ni" ]; then echo "Error: hash is $hash instead of $ni" >&2 exit 1 else exit 0 fi
Et voyons :
% get-and-check-ni 1etMCVZtd7_cq38MrtnQcoZW_e7J2cslulrFp92lueI %
Si on met une valeur fausse :
% get-and-check-ni 1etMCVZtd7_cq38MrtnQcoZW_e7J2cslulrFp922ueI Error: hash is 47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU instead of 1etMCVZtd7_cq38MrtnQcoZW_e7J2cslulrFp922ueI
Si vous voulez lire de source de mon programme, il est dans les fichiers de mon blog, scripts/blog2db/blog2db.py
pour le
stockage dans la base de données et wsgis/ni.py
pour la récupération.
Il existe une autre implémentation, par certains des auteurs du RFC, en http://sourceforge.net/projects/netinf/
.
Si vous voulez d'autres lectures, le RFC 1737. sur les URN, parlait déjà (en
1994) d'utiliser un condensat cryptographque
(avec MD5) pour désigner un contenu. En
2003, une proposition plus élaborée,
draft-thiemann-hash-urn
décrivait un système d'URN avec adressage par le contenu (des choses
comme
urn:hash::sha1:LBPI666ED2QSWVD3VSO5BG5R54TE22QL
).
Mais, avec draft-thiemann-hash-urn
, il y a un gros manque : pas moyen d'indiquer un (ou
plusieurs, comme dans le cas des magnets) serveur pouvant servir le
document en question. Avec draft-thiemann-hash-urn
, on n'a que des
URN (ils ne sont pas « actionnables »). Enfin, si vous voulez une
critique des ni:
par rapport aux
magnets, voyez la discussion sur LinuxFr.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : F. Gont (UTN-FRH / SI6 Networks), C. Pignataro (Cisco Systems)
Chemin des normes
Première rédaction de cet article le 18 avril 2013
Allez, encore un peu de nettoyage dans les registres IANA. Le protocole ICMP pour IPv4 a plein de types de messages différents. Beaucoup sont dépassés mais n'avaient pas été officiellement marqués comme tel. Ce RFC range le registre et reclasse quinze types de messages. En revoyant ces types, nous plongeons dans les essais ratés de TCP/IP...
La notion de type de message ICMP est normalisée dans le RFC 792. Les plus connus des types de message ICMPv4 sont le 8 (echo request) et le 0 (echo reply) à cause de leur utilisation dans ping. Mais il existe bien d'autres types, enregistrés à l'IANA et servant à de nombreuses fonctions discrètes, mais indispensables (comme l'indication qu'un paquet n'a pas pu être délivré, type 3). Le registre des types a aussi vu l'arrivée d'un certain nombre de types expérimentaux, qui n'ont guère eu de succès, et notre RFC s'occupe de les trier. (Rappelez-vous qu'IPv6 a un autre registre ICMP, complètement différent.)
Voici donc la liste des types abandonnés :
draft-simpson-ipv6-mobility
qui n'est jamais
devenu un RFC.)Tous ces types sont désormais marqués Deprecated dans le registre IANA.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : R. Gagliano (Cisco Systems), S. Kent (BBN Technologies), S. Turner (IECA)
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 11 avril 2013
La grosse infrastructure de sécurisation du routage RPKI+ROA est en train de se mettre en place, les RFC sont sortis, mais l'IETF ne s'arrête pas là. Ce document décrit la façon de changer les algorithmes de cryptographie utilisés par la RPKI lorsque les progrès de la cryptanalyse l'exigeront.
Disons-le tout de suite, cela va être un énorme travail. La RPKI n'a pas de centre, les décisions dépendent d'un grand nombre d'acteurs non coordonnés, des AC qui émettent les certificats aux RP (Relying Parties, les validateurs qui vérifient les ROA - Route Origin Authorizations). Le RFC ne sème pas d'illusion et affirme qu'un éventuel changement d'algorithmes dans la RPKI prendra plusieurs années.
Il y avait en théorie plusieurs stratégies possibles, du bas vers le haut (les acteurs situés le plus bas dans la hiérarchie migrent les premiers) ou celle finalement choisie, après de longues discussions dans le groupe de travail SIDR, du haut vers le bas (les acteurs les plus haut placés commencent).
À noter qu'il s'agit bien de changer d'algorithmes. Remplacer les clés (key rollover) est prévu et normal dans le fonctionnement de la RPKI (RFC 6489). Mais les algorithmes ne sont pas éternels. Ceux normalisés actuellement dans le RFC 6485 (RSA et SHA-256) ne résisteront pas toujours à la cryptanalyse et devront laisser un jour la place à d'autres (fondés sur les courbes elliptiques ?).
Comme le processus sera long, il devra commencer par une mise à jour de ce RFC 6485, documentant les nouveaux algorithmes et par la publication d'un plan de migration, avec chronologie. Puis la procédure décrite en section 4 sera appliquée, dans l'ordre chronologique : les AC commencent à émettre des certificats avec le nouvel algorithme, puis les RP (les validateurs) commencent à pouvoir vérifier le nouvel algorithme, puis les AC arrêtent d'utiliser l'ancien algorithme (période nommée Twilight dans le RFC, mais rien à voir avec Stephenie Meyer), puis on peut déclarer l'ancien algorithme mort. Le passage à chaque étape nécessite que tous les acteurs impliqués aient migré, ce qui explique le délai de plusieurs années envisagé (aucune procédure n'est envisagée pour le cas, catastrophique, où de brusques percées de la cryptanalyse obligeraient à un remplacement d'urgence). Le RFC est plein de phrases comme « If a substantial number of RPs are unable to process product sets signed with Suite B [le nouvel algorithme], the algorithm transition timeline document MUST be reissued, pushing back the date for this and later milestones [...] », qui donnent une idée des problèmes qui vont surgir à cause de cette règle « pas de passage sans unanimité ».
Il y aura donc une (longue) période de coexistence entre les deux algorithmes. La section 6 décrit ce que devra être le comportement des validateurs pendant cette période, notamment si les deux algorithmes donnent des résultats opposés (l'un valide et l'autre pas ; l'expérience avec des techniques cryptographiques comme DNSSEC montre que ce genre de choses arrive).
Et n'oubliez pas que ce beau plan n'a jamais été testé. Rendez-vous dans sept ou quinze ans pour le premier changement d'algorithme de la RPKI...
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : J. Rosenberg (jdrosen.net)
Pour information
Réalisé dans le cadre du groupe de travail IETF simple
Première rédaction de cet article le 22 avril 2013
Le monde de la messagerie instantanée est marqué par l'absence d'une norme unique et largement reconnue (au contraire de celui du courrier électronique, où SMTP et ses copains ont remplacé tous les concurrents). La plupart des protocoles courants de messagerie instantanée sont fermés et spécifiques à une seule entreprise. Et, même chez les standards ouverts, il y a deux normes, la plus connue, autour de XMPP, et une seconde, issue de la même organisation (l'IETF), autour de SIP. Car SIP ne sert pas qu'à la téléphonie sur IP. C'est un mécanisme de signalisation très général et il peut être utilisé pour la messagerie instantanée. En fait, de nombreux RFC, depuis des années, normalisent l'utilisation de SIP dans ce cas. Tellement nombreux, ces RFC, qu'il faut faire un méta-RFC pour servir de guide. C'est le rôle de ce RFC 6914 : la liste commentée des RFC qui, tous ensemble, décrivent SIMPLE, la messagerie instantanée utilisant SIP.
SIP lui-même est décrit dans le RFC 3261. Ce nouveau RFC 6914 fait la liste des RFC qui décrivent l'utilisation de SIP pour deux services :
Accrochez-vous, la liste est longue et SIMPLE ne mérite guère son nom. À noter que le groupe de travail IETF SIMPLE a été fermé le 26 février 2013, son travail étant considéré comme achevé.
Commençons par la présence (section 2). Elle se décompose en un service de base, permettant de publier des notifications (« je suis disponible ») et de s'y abonner (« qui est réveillé ? »), et une galaxie de services auxiliaires enrichissant tel ou tel aspect du service de base. Le seul service de base compte cinq RFC :
SUBSCRIBE
et NOTIFY
, au cœur
du service de présence. Il est bâti sur le RFC 3856.Ensuite, comment exprime-t-on les informations publiées et lues ? Le format de base (fondé sur XML) est dans le RFC 3863. Un modèle de données plus général est dans le RFC 4479, avec, dans le RFC 4480, plein d'extensions au format du RFC 3863. Autres extensions, celles du RFC 4481, qui ajoute la gestion du temps (évenements dans le passé et le futur, alors que le RFC 3863 se limitait au présent), et celles du RFC 4482 qui permettent de diffuser des informations sur un correspondant, par exemple une image le représentant.
Enfin, le RFC 5196 permettait d'indiquer, en sus de la présence et des données ci-dessus, les capacités du logiciel SIP qu'on utilise, par exemple pour prévenir ses correspondants qu'on accepte la vidéo.
Tout service de présence soulève évidemment des questions délicates de protection de la vie privée. Je ne souhaite pas forcément que la Terre entière soit au courant de mes déplacements et activités. La section 2.3 décrit les RFC qui s'attaquent au problème de la vie privée dans SIMPLE. Le RFC 4745 définit un format (basé sur XML) pour exprimer des préférences sur la vie privée (du genre « ne jamais diffuser cette information »). Le RFC 5025 utilise ensuite ce format pour décrire les souhaits spécifiques au service de présence. Les RFC 3857 et RFC 3858 décrivent un système d'autorisation préalable où l'utilisateur peut être prévenu si quelqu'un demande s'il est présent.
Un service SIMPLE nécessite un certain nombre de données, par exemple les carnets d'adresse. Comment les enregistre t-on ? Cela se fait avec XCAP (RFC 4825), un protocole qui permet d'envoyer des données stockées en XML. Il en existe des optimisations comme le RFC 5874 qui permet de n'envoyer que les différences avec les données précédentes, pour économiser des ressources réseau. Il se sert pour cela du format XML Diff du RFC 5261. On peut être prévenu de l'apparition de différences avec les mécanismes du RFC 5875. Les formats des données sont ensuite décrites par des documents comme le RFC 4826 (format des carnets d'adresses).
Un des gros intérêts des techniques IETF de messagerie instantanée, comme SIMPLE ou XMPP est qu'elles reposent sur une fédération. Il n'y a pas un service centralisé à qui faire confiance (comme c'est le cas avec les services des silos fermés comme MSN). Chacun peut installer son serveur et les différents serveurs peuvent communiquer entre eux, le DNS leur servant à se trouver. Le RFC 5344 approfondit les mécanismes utilisés pour la fédération.
La présence peut être un service très coûteux. Imaginez que vous receviez des notifications de présence pour une centaine de personnes, et que leurs états changent toutes les minutes (par exemple suite à des connexions/déconnexions). Au-dessus d'une liaison sans-fil, cela peut faire mal au réseau. Le RFC 4460 fournit donc des mécanismes de filtrage, pour ne pas tout recevoir. Les règles sont écrites dans le format du RFC 4461. Le RFC 5262 permet de ne pas recevoir la totalité de la notification mais uniquement la partie qui a changé (là encore, avec le format XML Diff du RFC 5261).
Maintenant qu'on en a terminé avec la présence (un service bien
plus compliqué qu'il n'avait l'air au premier abord), revenons à la
messagerie instantanée proprement dite (section 3). Dans SIMPLE, il y
a deux modes de fonctionnement pour celle-ci. En mode non connecté
(page mode, analogue au
SMS), une requête SIP
MESSAGE
est envoyée au
destinataire, contenant le message. En mode connecté (session
mode), une INVITE
SIP est envoyée au
destinataire et, une fois la session établie, on envoie les textes de
la conversation, comme on enverrait de l'audio avec de la téléphonie
SIP.
Le RFC 3428 décrit le mode non connecté et la méthode
MESSAGE
, le « texto » de SIP. Le RFC 5365 l'étend au cas où
il y a plusieurs destinataires.
Le mode connecté utilise des méthodes SIP classiques et sa description est uniquement celle des types de données envoyées, notamment RFC 4975 pour le type « message texte » et RFC 3862 pour les métadonnées.
Une extension très utile aux services de messagerie instantanée est la pièce collective (chat room, ou MUC - pour Multi-User Channel en XMPP). SIMPLE réutilise pour cela les mécanismes de conférence de SIP, normalisés dans les RFC 4353 et RFC 5239. Ensemble, ils indiquent comment on rejoint une conférence, comment on la quitte, etc.
Enfin (rassurez-vous, on arrive au bout), deux fonctions sympa : l'indication de composition dans le RFC 3994 (permettant d'indiquer que le correspondant est en train de taper un texte, il faut patienter), et l'accusé de réception dans le RFC 5438.
Voilà, vous savez désormais tout ce qu'il faut lire si vous voulez faire de la messagerie instantanée avec SIP...
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : A. Sullivan (Dyn, Inc), D. Thaler (Microsoft), J. Klensin, O. Kolkman (NLnet Labs)
Pour information
Première rédaction de cet article le 16 avril 2013
Ce RFC de l'IAB expose les principes que, selon l'IAB, devraient suivre les registres de noms de domaine lorsqu'ils décident quels caractères Unicode sont autorisés ou pas, pour l'enregistrement de noms de domaine internationalisés.
Notons tout de suite que les principes exposés dans ce RFC ne sont guère argumentés (les sections 6, 7 et 8, normalement consacrées à cette tâche, sont très pauvres). Dès l'introduction, le RFC dit qu'il ne faut pas autoriser tous les caractères mais ne dit pas pourquoi, ou quels dangers mystérieux menacent ceux qui oseraient passer outre. Mais, une fois qu'on a décidé de ne pas permettre tous les caractères Unicode (enfin, tous ceux qui sont légaux selon le RFC 5892), il reste le problème du choix. Il n'existe pas d'algorithme pour cela (le monde Unicode est bien trop complexe, reflétant la complexité des écritures du monde et nos connaissances insuffisantes) et ce RFC, plutôt que de donner un tel algorithme, pose des principes qui devraient guider ceux et celles qui feront le choix.
La section 1 donne quelques objectifs (sans que la suite du RFC
n'indique le rapport entre les principes et ces objectifs) : limiter
les possibilités de confusion entre deux noms (par exemple
google.com
et goog1e.com
,
regardez bien le second), éviter qu'une adresse IP soit prise pour un nom de domaine comportant des
éléments numériques (un faux problème typique, cf. RFC 1123,
section 2.1), et favoriser l'accessibilité
(cf. WCAG). Le RFC introduit une notion importante, celle de
zone publique. Une zone du
DNS est un ensemble de sous-domaines contigus
et gérés par la même organisation. Certaines sont privées, au sens où
une seule organisation les utilisent (par exemple la zone
univ-paris-diderot.fr
n'est utilisée que par
l'université Denis Diderot). D'autres sont
publiques au sens où le registre qui la gère
accepte des enregistrements de diverses organisations. La plupart des
TLD sont des zones publiques (par exemple
.fr
,
.org
ou
.pm
), ainsi que la
racine. En effet, le RFC estime qu'il faut des
règles particulières pour ces zones publiques (cf. section 4).
L'IAB s'est déjà exprimée sur cette question du choix des
caractères autorisés pour les IDN. Notons que
personne ne s'est posé la question pour les noms de domaines en
ASCII alors que, comme le montre l'exemple
goog1e.com
plus haut, ils posent exactement les
mêmes « problèmes ». Mais l'idée même de permettre à chacun, et pas
seulement aux anglophones, d'écrire les noms de domaine avec leur
écriture n'est toujours pas complètement acceptée. À part quelques
ultra-réactionnaires, plus personne n'ose
dire ouvertement qu'il est contre mais l'anti-IDNisme s'exprime plutôt
aujourd'hui par un discours de peur, parlant de dangers (jamais
clairement spécifiés) et laissant entendre qu'il faudrait contrôler
sévèrement les IDN. Les déclarations précédentes de l'IAB peuvent être
trouvées dans « IAB Statement: "The
interpretation of rules in the ICANN gTLD Applicant
Guidebook" » et « Response
to ICANN questions concerning 'The interpretation of rules in the ICANN gTLD
Applicant Guidebook' ». Dans ces textes, l'IAB
plaidait pour un extrême conservatisme dans l'autorisation de
caractères, en restreignant encore les règles techniques des RFC 5890 et RFC 5892, par
exemple en n'autorisant que les caractères de la catégorie Unicode
« Lettres ».
Dans ce RFC, l'IAB veut aller plus loin en interdisant également des caractères de cette catégorie. Le RFC prend l'exemple de ʼ (U+02BC, une apostrophe), qui a un rendu quasiment toujours identique à ’ (U+2019) alors qu'il est dans la catégorie Lettre (U+2019 étant dans la catégorie Ponctuation, mystères des catégories Unicode). Sans compter la traditionnelle ' (U+0027). Bien que, légalement, U+02BC soit un caractère autorisé dans un IDN, le RFC suggère que ce n'est sans doute pas une bonne idée de l'autoriser.
S'il y a des caractères dans la catégorie Lettres qui ne devraient sans doute pas être autorisés (cas ci-dessus), l'inverse existe aussi : des caractères situés dans d'autres catégories sont néanmoins indispensables dans certaines langues, notamment indiennes. Cela illustre le point mentionné plus haut : il n'y a pas d'algorithme pour établir automatiquement la liste des caractères autorisés, il va falloir y aller à la main. La section 4.2.4 du RFC 5891 mentionnait ce travail comme une reponsabilité indispensable du registre, et ce RFC 6912 ajoute que ce travail doit être fait à l'avance, pas décidé lorsqu'une demande d'enregistrement de nom se présente. Une telle décision lorsqu'une demande survient offrirait trop de possibilités à l'arbitraire. Non, il faut des règles pré-établies, et publiées. (À titre d'exemple, vous pouvez regarder les règles d'enregistrement des IDN dans .fr.)
Le RFC estime que ces règles doivent être d'autant plus sévères (doivent autoriser moins de caractères) que l'on monte dans la hiérarchie des zones et que la zone racine doit donc avoir des règles particulièrement conservatrices, puisqu'elle concerne tous les utilisateurs de l'Internet.
Donc, pas d'algorithme (s'il était possible, il aurait sans doute déjà été développé) mais des principes. Quels sont-ils ? La section 3 en fournit une liste. D'abord, le principe de longévité : comme un caractère peut changer de catégorie, invalidant son usage (un exemple figure dans le RFC 6452), il est prudent de n'autoriser que des caractères qui sont stables depuis plusieurs versions d'Unicode.
Ensuite, le principe de moindre étonnement : un utilisateur normal ne devrait pas être trop surpris de la présence ou de l'absence de tel caractère. Notez que cela dépend du contexte : un utilisateur d'une écriture donnée ne sera pas surpris par les mêmes choses qu'un utilisateur d'une autre écriture.
Ces principes étaient valables pour toutes les zones. Mais les zones publiques ont des contraintes supplémentaires (section 4). Il y a le principe conservateur (dans le doute, rejeter le caractère), le principe d'inclusion (les caractères sont interdits par défaut et on inclut ensuite explicitement ceux qu'on estime « sûrs », terme que le RFC ne définit pas, et qui vient du FUD anti-Unicode), le principe de simplicité (un « honnête homme », avec des compétences modérées en DNS et en Unicode, doit pouvoir comprendre les raisons qui ont amené au choix d'acceptation ou de rejet, sans avoir eu besoin d'être présent aux quinze dernières réunions de l'IETF)...
Ce principe de simplicité dépend là encore du contexte. Si l'honnête homme cité plus haut ne connait aucune langue indienne, il ne comprendra sans doute pas les raisons qui ont mené à l'ajout de caractères non-lettres, indispensables pour certaines de ces langues. La racine servant à tous, ses règles devraient être ultra-simples et ne pas demander de compétences linguistiques particulières. Un ccTLD d'un pays donné peut se permettre des règles plus complexes pour des étrangers, mais qui sembleront simples à ceux qui connaissent les langues locales.
Pour les zones publiques, il y a aussi le principe de prédictabilité (les règles doivent donner un résultat identique, dès qu'on les applique sérieusement) et de stabilité (la liste des caractères autorisés ne devrait changer que rarement).
La racine, pour les raisons expliquées plus haut, a droit à une section spéciale (section 5). Le RFC demande qu'elle soit strictement peuplée de lettres, en s'appuyant sur une note de la section 2.1 du RFC 1123 qui dit que c'est le cas (c'était vrai lorsque le RFC 1123 a été publié, mais il n'y a aucun consensus à l'IETF sur l'interprétation de cette note : exprime t-elle une constatation ou une prescription ?) L'idée derrière cette restriction (RFC 4690) est que les noms de domaines n'ont pas vocation à permettre d'écrire tous les mots, encore moins des phrases correctes et complètes, mais uniquement celle de permettre la création de mnémoniques pratiques.
Ce RFC exprimant des opinions très contestables, la discussion avait été animée (voir par exemple les commentaires que j'avais fait sur une précédente version, violemment anti-Unicode).
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : W. Dec (Cisco Systems), B. Sarikaya (Huawei), G. Zorn (Network Zen), D. Miles (Google), B. Lourdelet (Juniper Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF radext
Première rédaction de cet article le 30 avril 2013
Le protocole RADIUS joue un rôle important dans l'accès à l'Internet : c'est le principal mécanisme utilisé pour faire communiquer la machine qui contrôle l'accès physique avec la machine qui contient la base des utilisateurs et les informations sur les autorisations, les configurations spécifiques... RADIUS avait bien sûr déjà la capacité de transporter des informations IPv6 mais ce nouveau RFC en ajoute quelques unes.
Une petite révision sur RADIUS d'abord (vous pouvez suivre sur la figure 1 du RFC). Lorsqu'un utilisateur accède à l'Internet, plusieurs machines sont utilisées. Il y a d'abord la machine terminale de l'utilisateur, ou bien un petit routeur, nommé RG (Residential Gateway). L'un des deux porte les informations d'authentification (identificateur et mot de passe). Cette machine terminale ou bien se petit routeur se connecte au réseau et parle à un AN (Access Node : dans le cas de l'ADSL, c'est le DSLAM qui sert d'AN, dans le cas d'un accès commuté, c'est le serveur de modems). L'authentification pourrait être faite par l'AN. Mais l'utilisateur ne parle pas toujours au même AN (par exemple s'il est mobile) et puis, on gagne en souplesse en découplant les fonctions d'accès et d'authentification. On a donc un serveur qui stocke les informations d'authentification et les paramètres des clients, le AAA (Authentication, Authorization and Accounting). Entre l'AN et le AAA se trouve souvent un NAS (Network Access Server), un routeur IP (dans certains cas, AN et NAS sont confondus, par exemple pour la plupart des serveurs PPP). Le NAS est client RADIUS et utilise ce protocole pour demander à l'AAA « j'autorise ce client ? » L'AAA, serveur RADIUS, répond oui ou non et ajoute une série d'attributs, qui sont les paramètres de la session, par exemple l'adresse IP à utiliser. Notez que RADIUS ne sert qu'entre le NAS et le AAA. Entre le RG et le NAS, on peut utiliser plusieurs autres protocoles, comme PPP ou, plus courant aujourd'hui, DHCP (RFC 8415).
RADIUS avait déjà des attributs pour IPv6 :
le RFC 3162 avait Framed-IPv6-Prefix
pour indiquer le préfixe IPv6 à utiliser et
Framed-Interface-Id
qui, combiné avec la valeur
précédente, permettait de fabriquer une adresse IP6 pour
l'utilisateur (cette séparation puis recombinaison était plus adaptée
à PPP qu'à DHCP, qui donne des adresses entières). Et le RFC 4818 avait
Delegated-IPv6-Prefix
qui permettait de
transmettre un préfixe à déléguer à un routeur par l'option de
délégation DHCP du RFC 8415.
Quels sont ces attributs qui manquaient dans les RFC 3162
et RFC 4818 ? La section 3 en fournit la liste,
et ils sont désormais notés dans le registre
IANA (cf. section 6). Le premier est
Framed-IPv6-Address
qui permet d'attribuer une
adresse IPv6 complète au visiteur (a priori via DHCP). Elle peut apparaître dans les
réponses RADIUS, mais aussi dans les questions, pour exprimer un
souhait (que le serveur RADIUS peut ignorer). Framed-IPv6-Address
peut être envoyé dans une
réponse RADIUS en même temps que les anciens
Framed-IPv6-Prefix
and
Framed-Interface-Id
(par exemple si le réseau
local, derrière le RG, utilise à la fois DHCP et l'auto-configuration sans état
- SLAAC).
Le second attribut, DNS-Server-IPv6-Address
, indique
l'adresse IP d'un résolveur DNS. (Un seul
résolveur ; mais la réponse RADIUS peut contenir plusieurs attributs
DNS-Server-IPv6-Address
, afin de transmettre les
adresses de plusieurs résolveurs.) Ces serveurs DNS peuvent ensuite être indiqués aux machines du réseau
local par les Router Advertisement du RFC 8106 ou bien en DHCP (RFC 3646).
Ensuite, Route-IPv6-Information
permet de
spécifier une route statique. L'attribut existant,
Framed-IPv6-Route
(RFC 3162), ne suffit
pas car elle est pour l'usage du NAS, il ne la transmet pas au RG. Au
contraire, le nouvel attribut
Route-IPv6-Information
est prévu pour être
redistribué. Le NAS pourra transmettre cette information au RG avec les annonces
Router Advertisement du
RFC 4191 ou bien une méthode équivalente. Les autres données
nécessaires dans l'option Route Information de
l'annonce (par exemple la préférence ou la durée de vie), devront
être connues du NAS par un autre moyen (ce point a été le plus chaud
lors des discussions dans le groupe de travail).
Enfin, dernier attribut,
Delegated-IPv6-Prefix-Pool
indique le nom d'un
pool d'adresses IPv6 à utiliser par le NAS. Là encore, c'est un
attribute RADIUS conçu pour être relayé avec DHCP mais qui peut
coexister avec Framed-IPv6-Pool
, plutôt fait pour les Router
Advertisement.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : Y. Lee (Comcast), R. Maglione (Telecom Italia), C. Williams (MCSR Labs), C. Jacquenet (France Telecom), M. Boucadair (France Telecom)
Pour information
Réalisé dans le cadre du groupe de travail IETF softwire
Première rédaction de cet article le 26 mars 2013
DS-Lite est une des nombreuses techniques de transition / co-existence IPv4 / IPv6. Elle est normalisée dans le RFC 6333. Ce nouveau RFC se penche plutôt sur des problèmes opérationnels : comment déployer DS-Lite, quels pièges éviter, etc.
DS-Lite (Dual-Stack Lite) est conçu pour un FAI récent, qui vient d'arriver et n'a donc pas pu obtenir d'adresses IPv4, toutes épuisées. Ce FAI a donc dû numéroter son réseau en IPv6, et comme ses clients ont encore de l'IPv4 à la maison, et comme ils souhaitent accéder à des machines Internet qui sont encore uniquement en IPv4, le FAI en question va donc devoir 1) NATer les adresses de ses clients (RFC 3022) vers le monde extérieur 2) tunneler leurs paquets depuis leur réseau local IPv4 (RFC 2463) jusqu'au CGN, en passant par le réseau purement IPv6 du FAI. C'est là que DS-Lite intervient (RFC 6333).
Apparemment, il n'y a eu qu'un seul déploiement effectif de DS-Lite chez un vrai FAI (le RFC ne dit pas lequel) et ce RFC 6908 est largement tiré de cette expérience réelle. Il est donc une lecture intéressante pour les opérateurs qui aiment le concret.
Ce RFC est en deux parties : les questions liées à l'AFTR et celles liées au B4. Vous ne savez pas ce qu'est un AFTR ou un B4 ? Vous n'avez pas envie de lire le RFC 6333 qui explique cela ? Alors, en deux mots, l'AFTR (Address Family Transition Router) est le gros routeur NAT (le CGN) situé entre le FAI et l'Internet. Et le B4 (Basic Bridging Broadband element) est chez le client, typiquement dans sa box et représente le point d'entrée du tunnel, du « lien virtuel » (soft wire). Prononcez les sigles à voix haute : le B4 est avant le tunnel (before) et l'AFTR après (after).
Donc, bien qu'il soit « après », notre RFC commence par l'AFTR (section 2). D'abord, comme DS-Lite utilise un tunnel, il va y avoir des problèmes dus à la MTU inférieure. Le RFC recommande donc d'essayer de faire un lien entre le B4 et l'AFTR ayant une MTU d'au moins 1540 octets pour que, après avoir retiré les 40 octets de l'encapsulation dans le tunnel, on ait les 1500 octets d'Ethernet. Si ce n'est pas possible, alors le B4 et l'AFTR vont devoir gérer la fragmentation. Comme le réassemblage des paquets est une opération coûteuse en ressources (il faut garder les fragments en mémoire tant que tout n'est pas arrivé), la tâche va être particulièrement lourde pour l'AFTR (des milliers de tunnels peuvent se terminer sur un seul AFTR). Il faut les dimensionner largement ! (C'est un problème général des CGN.)
Ensuite, il faut penser à la journalisation. Le principe de DS-Lite est que tous les clients du FAI partageront la poignée d'adresses IPv4 publiques que NATeront les AFTR. Si un client fait quelque chose de mal (par exemple accéder à un site Web qui déplait au gouvernement), il faut pouvoir l'identifier. Un observateur situé à l'extérieur a vu une adresses IPv4 du FAI et des milliers de clients pouvaient être derrière. L'AFTR doit donc noter au moins l'adresse IPv6 du B4 (elle est spécifique à chaque client) et le port source utilisé après le NAT (en espérant que l'observateur extérieur ne notera pas que l'adresse IPv4 source mais aussi le port, cf. RFC 6302).
Les adresses IP partagées sont une plaie du NAT, ce n'est pas nouveau (RFC 6269). Par exemple, si une adresse IPv4 est mise sur une liste noire suite à son comportement, ce seront des centaines ou des milliers de B4 qui seront privés de connectivité IPv4. Si le destinataire ne tient pas compte du RFC 6302 et bloque sur la seule base de l'adresse IPv4, le support téléphonique du FAI qui a déployé DS-Lite va exploser. (Un travail est en cours à l'IETF pour aider à l'identification de l'utilisateur derrière un CGN. Mais il n'est pas terminé et, de toute façon ne sera pas forcément déployé. L'obstination de tant d'acteurs à rester en IPv4 va se payer cher.)
Un problème analogue se posera si le FAI veut faire de la comptabilité des octets échangés, et s'il ne met pas cette fonction dans le CPE. Le tunnel et le NAT rendront cette analyse plus compliquée (section 2.6). À noter que le RFC 6519 normalise des extensions à Radius pour les problèmes particuliers de DS-Lite.
Mais tout ceci n'est rien par rapport aux problèmes de fiabilité que posent les AFTR. L'Internet normal est très robuste car les équipements intermédiaires (les routeurs) n'ont pas d'état : s'ils redémarrent, rien n'est perdu. S'ils s'arrêtent de fonctionner, on en utilise d'autres. Le NAT met fin à tout cela : le routeur NAT a un état en mémoire, la table des correspondances {adresse interne, adresse externe} et, s'il redémarre, tout est fichu. C'est bien pire pour un CGN : s'il redémarre, ce sont des centaines ou des milliers d'utilisateurs qui perdent leurs connexions en cours. La fiabilité des AFTR est donc cruciale (cf. annexe A.3 du RFC 6333). Notre RFC propose que des AFTR de remplacement soient installés pour être prêts à prendre le relais. Ils peuvent fonctionner en « remplacement à chaud » (Hot Standby), se synchronisant en permanence avec l'AFTR primaire, prêts à le remplacer « sans couture » puisqu'ils ont le même état, ou bien en « remplacement à froid » (Cold Standby), sans synchronisation. Dans ce second cas, l'AFTR de secours fait qu'un AFTR en panne est vite remplacé, mais il n'y a pas de miracle : les clients doivent recommencer toutes leurs sessions. Vue la complexité qu'il y a à mettre en œuvre correctement la synchronisation des états, notre RFC recommande le remplacement à froid, et tant pis si c'est moins agréable pour les utilisateurs.
Et les performances ? Combien faut-il d'AFTR pour servir les utilisateurs ? La section 2.8 discute de ce point et du meilleur placement de ces équipements.
Comme avec tout CGN, DS-Lite, en centralisant les adresses IPv4, limite les possibilités de géo-localisation. Le B4 (donc la maison de l'utilisateur) et l'AFTR peuvent parfaitement être dans des villes différentes (RFC 6269, section 7). Les applications ne devraient donc pas se fier à la géo-localisation mais demander à l'utilisateur où il se trouve, par exemple avec le protocole HELD du RFC 5985 ou en suivant l'architecture du RFC 6280. Le RFC conseille, curieusement, de mettre les AFTR le plus près possible des utilisateurs, pour limiter ce problème (alors que les AFTR ont besoin d'une connectivité IPv4, et que le réseau du FAI ne la fournit pas forcément, sinon il n'aurait pas besoin de DS-Lite).
Autre problème douloureux avec les CGN (dont DS-Lite), les connexions entrantes. Contrairement au NAT traditionnel, celui fait par la box à la maison, plus question de configurer sa box via une interface Web pour rediriger certains ports. Et plus moyen de se servir d'UPnP. Les éventuelles redirections doivent être sur l'AFTR, un engin largement partagé. Donc, pas question de demander une redirection du port 80...
Pour « programmer » l'AFTR, lui demander d'ouvrir certains ports en entrée, notre RFC recommande d'installer un serveur PCP (Port Control Protocol, RFC 6887) sur les AFTR. Il n'est pas évident que cela soit une solution satisfaisante. D'une part, il existe encore très peu de clients PCP (par rapport aux clients UPnP). D'autre part, l'AFTR étant partagé entre plusieurs clients ne se connaissant pas, rien ne dit que la coexistence se passera bien et que les opérateurs accepteront d'ouvrir PCP à leurs clients.
Voilà, c'étaient les points essentiels pour les AFTR, lisez la section 2 du RFC si vous voulez la liste complète. Et les B4 ? Ils font l'objet de la section 3. D'abord, le problème du DNS. Le B4 est censé s'annoncer comme résolveur DNS et relayer les requêtes DNS au dessus d'IPv6 vers l'extérieur. Ce faisant, il est important qu'il suive les recommendations pour les relais DNS du RFC 5625 (en pratique, la grande majorité des boxes et des petits routeurs bas de gamme violent affreusement ces recommendations). C'est notamment nécessaire si on veut que DNSSEC fonctionne.
Si un client sur un réseau local IPv4 fait des requêtes DNS en IPv4 vers une adresse qui n'est pas celle du B4, ces requêtes seront tunnelisées et NATées comme n'importe quel trafic IPv4. Compte-tenu du fait que, du point de vue du NAT, chaque requête DNS est une session à elle seule, l'augmentation de la charge sur les AFTR sera sensible. Ce n'est donc pas conseillé.
Le B4 étant le début du réseau de l'opérateur, et beaucoup de choses dépendant de sa configuration et de son bon fonctionnement, il est important que l'opérateur puisse y accéder à distance, et au dessus d'IPv6, pas au dessus du lien virtuel (qui a davantage de chances d'avoir des problèmes).
À propos d'administration et de supervision du réseau, il est
important que les AFTR répondent aux paquets utilisés pour
ping et traceroute, afin
que le B4 puisse tester que la connectivité IPv4 au dessus du tunnel
marche bien. Des adresses IPv4 spéciales ont été réservées pour cela
(rappelez-vous que, si vous déployez DS-Lite, c'est que vous n'avez
pas assez d'adresses IPv4 publiques),
192.0.0.0/29
. Les AFTR sont censés tous répondre
aux paquets envoyés à 192.0.0.2
.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : E. Wilde (EMC Corporation)
Pour information
Première rédaction de cet article le 21 mars 2013
Les liens sont à la base du
Web, tout le monde le sait, mais on sait moins
que les liens sont typés, marqués avec un type qui indique leur
sémantique. Ainsi, le type profile
, décrit dans
ce RFC, indique que le lien pointe vers un
profil, une spécification du format utilisé qui restreint les
possibilités d'un format donné.
Ce concept de profil est très fréquent en informatique (mais pas vraiment défini de manière rigoureuse). Lorsqu'on veut réutiliser un format mais qu'on n'a besoin que d'une petite partie de ses possibilités, on définit un profil qui consiste en gros à dire « dans tel format, n'utiliser que ci et ça ». Un profil peut être un peu plus compliqué qu'une simple restriction, par exemple il peut spécifier quelques extensions obligatoires. Le point important est qu'un programme qui sait traiter le format doit savoir traiter un fichier utilisant un profil de ce format. Ainsi, un podcast est un flux de syndication (et doit donc pouvoir être traité par tout programme gérant ces flux) mais avec des éléments spécifiques, qui peuvent être compris par un lecteur de podcasts, comme Apple iTunes.
Le format lui-même est indiqué par d'autres méthodes. Par
exemple, en HTTP, le format peut être indiqué
par le type de media (ou type MIME), comme
text/html
. On peut aussi indiquer le format dans
le document lui-même : en HTML, on va utiliser la déclaration
DOCTYPE
pour cela. Et pour indiquer
le profil ? Eh bien on va se servir d'un lien. (HTML 4 avait un attribut
profile
dans l'élément
<head>
mais il n'est pas sûr que HTML 5 le
garde et, de toute façon, la solution de ce RFC est plus
générale.)
Ces liens suivent le cadre général normalisé dans le RFC 8288. Ce cadre comprend notamment un registre
des types de liens (dans lequel se trouve désormais
profile
), et plusieurs syntaxes pour mettre les
liens dans le document (cas du <link>
de HTML)
ou dans le protocole d'accès (cas de l'en-tête
Link:
de HTTP).
La distinction entre profils et formats est parfois subtile. Ainsi, XHTML n'est pas considéré comme un profil de XML parce que, pour les usages de XHTML, afficher du XML brut, sans les traitements spécifiques de XHTML, n'aurait guère d'intérêt. En revanche, hCard est bien un profil de XHTML, car, si un logiciel ne comprend pas hCard, le traiter et l'afficher comme du bête XHTML est utile.
Les profils sont identifiés par un URI
(comme les espaces de noms de
XML). Ces URI ne sont pas forcément
déréférençables (on ne peut pas toujours les donner à un
navigateur Web), ce sont juste des
identificateurs et le logiciel doit donc les traiter comme tels, pas
les présenter systématiquement comme des liens cliquables. Le RFC conseille
juste (ce n'est pas une obligation) de les rendre déréférençables, et
de mettre une jolie documentation du profil au bout de l'URI. Ainsi,
si je crée un profil de HTML nommé
http://www.example.org/profiles/myprofile
, il est
recommandé (juste recommandé) qu'une page Web décrivant myprofile
se
trouve effectivement à cette adresse.
Une curiosité : un document peut correspondre à plusieurs profils
et le lien de type profile
peut donc pointer vers
une liste.
La section 5 du RFC donne quelques exemples concrets.
D'abord, hCard, déjà cité. Il permet de mettre
des vCard (RFC 6350) dans HTML. Son
URI est
, on peut donc l'indiquer par un lien comme http://microformats.org/profile/hcard
<link rel="profile" href="http://microformats.org/profile/hcard" />
et on trouve plein d'exemples dans la documentation
Autre exemple, Dublin Core, identifié par le
profil
http://dublincore.org/documents/2008/08/04/dc-html/
qui permet de mettre des métadonnées Dublin Core dans une page en
HTML. (Je n'en ai pas mis dans ce blog mais mes flux de
syndication, en XML, continnent du
Dublin Core.) Un exemple simple, les éléments Dublin Core ayant un nom commençant par DC :
<html> <head> <title>Expressing Dublin Core in HTML/XHTML meta and link elements</title> <link rel="profile" href="http://dublincore.org/documents/2008/08/04/dc-html/"/> <meta name="DC.title" lang="en" content="Expressing Dublin Core in HTML/XHTML meta and link elements" /> <meta name="DC.creator" content="Andy Powell, UKOLN, University of Bath" /> <meta name="DCTERMS.issued" scheme="DCTERMS.W3CDTF" content="2003-11-01" /> <meta name="DCTERMS.abstract" content="This document describes how qualified Dublin Core metadata can be encoded in HTML/XHTML <meta> elements" /> <meta name="DC.format" scheme="DCTERMS.IMT" content="text/html" /> </head>
Dernier exemple, déjà cité, les podcasts. Il n'y a pas
d'identificateur officiel (on pourrait utiliser l'URI http://www.apple.com/itunes/podcasts/specs.html
).
Il existe désormais un registre de ces profils, créé par le RFC 7284.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : Tissa Senevirathne (CISCO), David Bond (IBM), Sam Aldrin, Yizhou Li (Huawei), Rohit Watve (CISCO)
Pour information
Réalisé dans le cadre du groupe de travail IETF trill
Première rédaction de cet article le 30 mars 2013
Le protocole TRILL est un protocole de routage pour réseaux locaux, qui veut combiner les avantages des réseaux L2 (non routés) et L3 (routés, avec des protocoles plus complexes). Ce RFC est le cahier des charges pour les futurs mécanismes d'administration et de supervision des réseaux TRILL.
TRILL est normalisé dans le RFC 6325. Il vise surtout les gros data centers et les fournisseurs d'infonuagique. Il est par exemple déployé sur le service d'hébergement de Gandi. Comme tous les protocoles, il a besoin d'OAM : Operations, Administration and Maintenance, c'est-à-dire l'ensemble des activités de l'administrateur réseaux pour maintenir le réseau en bon état de marche (cf. RFC 6291 et RFC 5860). Un réseau TRILL est composé de RBridges, engins intermédiaires entre les ponts et les routeurs et ce sont eux qu'il faut gérer. La section 4 du RFC énumère les exigences des futurs mécanismes OAM de TRILL. Parmi elles :
Il ne reste plus qu'à développer tout cela. Un expert de TRILL parmi mes lecteurs pour expliquer ce que peuvent faire les RBridges actuels, avec résultat de commandes à l'appui ?
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : J. Snell
Pour information
Première rédaction de cet article le 21 mars 2013
Allez, encore tout un lot de types de liens Web qui sont enregistrés. Pas de point commun entre les types créés par ce RFC, juste quelques types intéressants.
Tous suivent les principes du RFC 8288 qui normalise cette idée de type de lien et décrit le registre où ils sont désormais stockés.
Le premier, about
pointe vers une ressource
qui décrit celle qui contient le lien. L'exemple donné par le RFC est
celui d'un article de test d'un produit, qui pointe vers une page Web
décrivant le produit. Avec les en-têtes HTTP :
HTTP/1.1 200 OK Content-Type: text/html Link: <http://store.example.org/product/abc>; rel="about"
Le second, preview
permet de pointer vers une
ressource qui offre une version limitée, plus courte ou à plus basse
résolution, pour ceux qui voudraient aller vite. Ici, par exemple, une
vidéo a un lien vers une version courte de dix secondes :
HTTP/1.1 200 OK Content-Text: video/mpeg Link: <http://example.org/preview/10-second-preview.mpg>; rel="preview"; type="video/mpeg"
Le troisième, privacy-policy
, permet de
pointer vers une ressource (par exemple une page Web) décrivant la
politique du gérant, relative à la vie privée. Si vous regardez le source de ce blog, vous
trouverez un tel lien en HTML, allant vers
ma politique :
<link rel="privacy-policy" href="/privacy-policy.html"/>
Le RFC rappelle bien que cela n'a aucune valeur juridique : le Web est plein de « politiques de vie privée » que personne ne consulte et qui n'engagent nullement le site Web qui les affiche.
À noter que, pour indiquer ces pratiques (collectes de
données personnelles, enregistrement des
visites, etc), il existe un autre mécanisme,
P3P. Le mécanisme de lien
privacy-policy
peut pointer vers une ressource
P3P mais ce n'est pas obligatoire.
Le quatrième type est terms-of-service
, qui
pointe vers les conditions d'utilisation. Comme
vous le savez, personne ne les
lit, et pour des bonnes raisons (ce sont de longs textes incompréhensibles). Un exemple :
<html> <head> ... <link href="/tos.html" rel="terms-of-service"/> ... </head> <body> ... </body> </html>
Le RFC note à juste titre que celui qui les écrit peut ensuite les violer impunément. Ce lien n'a donc d'autre rôle que de signaler ces conditions d'utilisation.
Enfin, dernier type décrit ici, type
, permet
de dire qu'une ressource est une instance d'une classe plus générale,
identifiée par un URI,
ici qu'une page décrit une personne :
HTTP/1.1 200 OK Content-Type: text/plain Link: <http://example.org/Person/givenName>; rel="type" Jeanne Michu
C'est probablement surtout utile pour le Web sémantique. Attention, ce type
n'a
rien à voir avec le Content-type
qui indique le
format physique (dit souvent « type MIME »).
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : P. Bryan (Salesforce.com), M. Nottingham (Akamai)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 3 avril 2013
Le format de données structurées JSON, normalisé dans le RFC 8259, a pris une importance de plus en plus grande et est désormais utilisé dans bien des contextes. Cela entraine l'apparition de normes auxiliaires, spécifiant comment faire telle ou telle opération sur des fichiers JSON. Ainsi, le RFC 6901 indique comment désigner une partie d'un document JSON et ce RFC 6902, sorti en même temps, indique comment exprimer les modifications (patches) à un document JSON.
Logiquement, le patch est lui-même un fichier
JSON (de type application/json-patch
, cf. la
section 6 de notre RFC) et il indique les opérations à faire (ajouter, remplacer,
supprimer) à un endroit donné du document (identifié par un pointeur
JSON, ceux du RFC 6901). Voici un
exemple de patch :
[ { "op": "add", "path": "/baz", "value": "qux" } ]
Il va ajouter (opération add
) un membre nommé
baz
et de valeur qux
. Si le
document originel était :
{ "foo": "bar"}
Celui résultant de l'application du patch sera :
{ "baz": "qux", "foo": "bar" }
À noter que ces patches travaillent sur le modèle de donnéees JSON, pas directement sur le texte (autrement, on utiliserait le traditionnel format diff), et peuvent donc s'appliquer sur des données qui ont un modèle similaire, quelle que soit la syntaxe qu'ils avaient. Dans les exemples de code Python à la fin, le patch est appliqué à des variables Python issues d'une analyse d'un fichier JSON, mais qui pourraient avoir une autre origine. (Au passage, je rappelle l'existence d'un format équivalent pour XML, le XML patch du RFC 5261.)
Le patch peut être envoyé par divers moyens,
mais l'un des plus courants sera sans doute la méthode PATCH
de HTTP (RFC 5789). Voici un exemple d'une requête HTTP avec un
patch :
PATCH /my/data HTTP/1.1 Host: example.org Content-Length: 326 Content-Type: application/json-patch If-Match: "abc123" [ { "op": "test", "path": "/a/b/c", "value": "foo" }, { "op": "remove", "path": "/a/b/c" }, { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }, { "op": "replace", "path": "/a/b/c", "value": 42 }, { "op": "move", "from": "/a/b/c", "path": "/a/b/d" }, { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" } ]
Un patch JSON a quelle forme (section 3) ? C'est un tableau dont chaque object qui le compose est une opération, à appliquer dans l'ordre du tableau (dans le premier exemple ci-dessus, le tableau ne comportait qu'une seule opération). L'entité à laquelle on applique le patch est donc transformée successivement et chaque opération s'applique au résultat de l'opération précédente.
Quelles sont les opérations possibles (section 4) ? Le membre
op
indique l'opération,
path
la cible et value
la
nouvelle valeur. op
peut être :
add
: si la cible est dans un tableau, on
ajoute la valeur à ce tableau (si le pointeur pointe vers la fin du
tableau, avec la valeur -
, on ajoute après le
dernier élément). Si la cible est un membre inexistant
d'un objet, on l'ajoute. S'il existe, on le remplace (ce point a été
vigoureusement critiqué au sein du groupe de travail, où plusieurs
personnes regrettaient qu'on mélange les sémantiques de
add
et de replace
; parmi
les propositions alternatives, il y avait eu de nommer cette opération
set
ou put
plutôt qu'add
).remove
: on retire l'élément pointé.replace
: on remplace la valeur pointée.move
: on déplace l'élément (ce qui
nécessite un paramètre supplémentaire, from
).copy
: on copie la valeur pointée vers un
nouvel endroit.test
: teste si une valeur donnée est
présente à l'endroit indiqué. Cela sert lorsqu'on veut des opérations
conditonnelles. Les opérations étant appliquées dans l'ordre, et la
première qui échoue stoppant tout le patch, un
test
peut servir à faire dépendre les opérations
suivantes de l'état du document JSON.
Mais à quel endroit applique-t-on cette opération ? C'est indiqué par
le membre path
qui est un pointeur JSON
(cf. RFC 6901). Enfin,
value
indique la valeur, pour les opérations qui
en ont besoin (par exemple add
mais évidemment
pas remove
).
La section 5 spécifie ce qui se passe en cas d'erreurs : le
traitement s'arrête au premier problème. Pour le cas
de la méthode HTTP PATCH
, voir la section 2.2 du
RFC 5789. PATCH
étant
atomique, dans ce cas, le document ne sera pas
du tout modifié.
Quelles mises en œuvre existent ? Une liste est disponible en ligne, ainsi que des jeux de test. Je vais ici essayer celle en Python, python-json-patch. D'abord, il faut installer python-json-pointer et python-json-patch :
% git clone https://github.com/stefankoegl/python-json-pointer.git % cd python-json-pointer % python setup.py build % sudo python setup.py install % git clone https://github.com/stefankoegl/python-json-patch.git % cd python-json-patch % python setup.py build % sudo python setup.py install
Ensuite, on écrit un programme Python qui utilise cette bibliothèque. On va le faire simple, il prend sur la ligne de commande deux arguments, un qui donne le nom du fichier JSON original et un qui donne le nom du fichier contenant le patch. Le résultat sera écrit sur la sortie standard :
#!/usr/bin/env python import jsonpatch import json import sys if len(sys.argv) != 3: raise Exception("Usage: patch.py original patchfile") old = json.loads(open(sys.argv[1]).read()) patch = json.loads(open(sys.argv[2]).read()) new = jsonpatch.apply_patch(old, patch) print json.dumps(new)
Maintenant, on peut écrire un fichier JSON de test,
test.json
, qui décrit ce RFC :
% cat test.json { "Title": "JSON Patch", "Number": "NOT PUBLISHED YET", "Authors": [ "P. Bryan" ] }
On va maintenant essayer avec différents fichiers
patch.json
contenant des patches (l'annexe A
contient plein d'autres exemples). Un ajout à un tableau :
% cat patch.json [ { "op": "add", "path": "/Authors/0", "value": "M. Nottingham" } ] % python patch.py test.json patch.json {"Title": "JSON Patch", "Number": "NOT PUBLISHED YET", "Authors": ["M. Nottingham", "P. Bryan"]}
Un changement d'une valeur :
% cat patch.json [ { "op": "replace", "path": "/Number", "value": "6902" } ] % python patch.py test.json patch.json {"Title": "JSON Patch", "Number": "6902", "Authors": ["P. Bryan"]}
Un ajout à un objet :
% cat patch.json [ { "op": "add", "path": "/Status", "value": "standard" } ] % python patch.py test.json patch.json {"Status": "standard", "Title": "JSON Patch", "Number": "NOT PUBLISHED YET", "Authors": ["P. Bryan"]}
Une suppression d'un champ d'un objet :
% cat patch.json [ { "op": "remove", "path": "/Authors" } ] % python patch.py test.json patch.json {"Title": "JSON Patch", "Number": "NOT PUBLISHED YET"}
Si vous aimez les controverses, un des débats les plus animés, plus
d'un an avant la sortie du RFC, avait été de savoir si l'opération
d'ajout devait se noter add
(comme cela a
finalement été choisi) ou bien simplement +
. Le
format diff traditionnel utilise des
mnémoniques plutôt que des noms et cela peut accroître la lisibilité
(cela dépend des goûts).
Merci à Fil pour sa relecture attentive qui a trouvé plusieurs problèmes techniques.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : P. Bryan (Salesforce.com), K. Zyp (SitePen), M. Nottingham (Akamai)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 3 avril 2013
Ce court RFC spécifie une syntaxe pour identifier un élément particulier dans un document JSON. Cela permettra de pointer vers l'intérieur d'un document, par exemple depuis un URI.
JSON (RFC 8259) est un format structuré de données très populaire sur le Web. Les documents JSON peuvent être de taille très variable et il serait intéressant d'avoir une syntaxe formelle pour désigner une partie bien spécifique d'un document JSON, comme XPointer le permet pour XML et le RFC 5147 pour le texte brut. Outre les URI cités plus haut, un des usages envisagés est la modification de documents JSON, via la norme JSON patch du RFC 6902, puisque la mise à jour nécessite de dire exactement où on va faire l'ajout ou la suppression de données.
La syntaxe est exposée en section 3 : un JSON
pointer est une chaîne de caractères
Unicode (JSON pointer
travaille entièrement avec des caractères Unicode,
pas avec des octets).
Il contient plusieurs éléments séparés
par des barres obliques. Ce caractère, ainsi
que le tilde, sont donc spéciaux et, si on veut
avoir leur valeur littérale, il faut un
échappement, ~0
pour le ~
et ~1
pour le /. (Programmeurs, attention, en
décodant, il faut d'abord remplacer tous les ~1
par des /
avant de s'attaquer à la deuxième
substitution, sinon ~01
sera mal décodé.)
Pour illustrer ces pointeurs, je vais utiliser pour tous les
exemples les données des chemins de fer britanniques
disponibles en JSON en http://api.traintimes.im/
. Commençons par récupérer la liste des stations :
% wget http://api.traintimes.im/stations_all.json
On peut alors connaître les codes tiploc des gares, ici, on va utiliser WMOR
pour Woodsmoor.
Cherchons les trains qui passent à Woodsmoor aux alentours de midi :
% wget -O wmor.json http://api.traintimes.im/locations.json\?location=WMOR\&date=2013-02-14\&startTime=1200
Le fichier JSON (passé à jsonlint) ressemble à :
{ ... "services" : [ { "departure_time" : "1141", "destination" : { "arrival_time" : "1145", "crs" : "HAZ", "description" : "Hazel Grove", "tiploc" : "HAZL" }}, "departure_time" : "1206", "destination" : { "arrival_time" : "1227", "crs" : "MAN", "description" : "Manchester Piccadilly", "tiploc" : "MNCRPIC" }} ...
Par exemple, avec ces données
/services
, /services/1
et /services/1/destination/description
sont tous des pointeurs JSON
valides.
Et comment est-ce que cela s'interprète ? La section 4 le
décrit. On part de la racine du document JSON. Donc, le pointeur
composé d'une chaîne vide identifie la totalité du document. Ensuite,
si la racine est un objet JSON (avec des champs nommés),
l'élement suivant identifie un des champs. Ainsi,
/foo
identifie le champ foo
de l'objet situé à la racine (il doit être unique). Si par contre la racine est un tableau,
l'élement suivant doit être un nombre, l'index dans le tableau (en
partant de zéro donc /1
identifie le deuxième
élément du tableau situé à la racine). Une seule valeur non-numérique
est permise, -
qui indique l'élément situé après
la fin du tableau (pour le JSON patch du RFC 6902, cela sert aux ajouts à la fin du
tableau, autrement, cela désigne un élément non-existant).
Donc, attention, /
n'identifie pas la racine du document mais un élément de nom vide
situé à la racine.
Le pointeur JSON est ensuite représenté sous forme texte comme une
chaîne de caractères JSON (section 5) ce qui oblige à échapper les
caractères spéciaux des chaînes JSON comme la barre
inverse ou comme le guillemet. Par
exemple, il faudra écrire a\\b
pour trouver
le membre d'objet JSON nommé a\b
.
Et dans un URI (section 6) ? Il faudra
encoder le pointeur en UTF-8 et faire un
échappement « pour cent » (RFC 3986, section
2.1) des caractères qui sont spéciaux dans un URI (comme le
point d'interrogation, section 2.2 du RFC 3986). Ainsi,
http://api.traintimes.im/locations.json?location=WMOR\&date=2013-02-14\&startTime=1200#/services/1/destination/arrival_time
pointera vers la valeur 1227
(regardez
l'identificateur de fragment après le
croisillon : c'est un pointeur JSON). À noter que tous les types
MIME n'accepteront pas forcément le pointeur
JSON comme un moyen normal de désigner un fragment du document
JSON et l'exemple ci-dessus est donc hypothétique.
Reste à traiter le cas des erreurs (section 7). Deux erreurs typiques sont un élément non numérique dans le pointeur alors que la valeur est un tableau, ou bien un nom de champ inexistant. Le RFC ne spécifie pas ce qui doit se produire dans un tel cas, cela doit être défini par l'application qui utilise les pointeurs (pour JSON patch, voir les sections 4.1 et 5 du RFC 6902).
Une liste des mises en œuvre connues des pointeurs JSON est disponible à l'IETF (en fait, ce sont les mises en œuvre de JSON Patch mais, comme les pointeurs sont un pré-requis, elle couvre aussi les mises en œuvre des pointeurs). Il existe aussi une implémentation « faite en 20 minutes » en node.js, js-6901. Testons l'implémentation Python :
% git clone https://github.com/stefankoegl/python-json-pointer.git % cd python-json-pointer % python setup.py build % sudo python setup.py install
Et lançons l'interpréteur Python pour voir :
>>> import jsonpointer >>> import json >>> doc = json.load(open("wmor.json")) >>> jsonpointer.resolve_pointer(doc,'/services/1/destination/description') u'Manchester Piccadilly' >>> jsonpointer.resolve_pointer(doc,'/services/0/destination/description') u'Hazel Grove' >>> jsonpointer.resolve_pointer(doc,'/services/2/destination') {u'crs': u'BUX', u'arrival_time': u'1251', u'description': u'Buxton', u'tiploc': u'BUXTON'}
Tout marche donc bien et on récupère, soit des valeurs, soit des objets JSON. Et avec un pointeur qui ne pointe vers rien ?
>>> jsonpointer.resolve_pointer(doc,'/zzz') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python2.7/dist-packages/jsonpointer.py", line 105, in resolve_pointer return pointer.resolve(doc, default) File "/usr/local/lib/python2.7/dist-packages/jsonpointer.py", line 140, in resolve doc = self.walk(doc, part) File "/usr/local/lib/python2.7/dist-packages/jsonpointer.py", line 183, in walk raise JsonPointerException("member '%s' not found in %s" % (part, doc)) jsonpointer.JsonPointerException: member 'zzz' not found in { ...
On a, fort logiquement, une exception.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : Donald Eastlake (Huawei)
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 17 avril 2013
Un RFC un peu bureaucratique, pour détailler les mécanismes utilisés pour l'enregistrement dans les registres de l'IANA des paramètres liés au DNS. Il met très légèrement à jour son prédécesseur, le RFC 6195, libéralisant encore un peu plus l'enregistrement de nouveaux types de données dans le DNS.
Un certain nombre de paramètres (section 2, qui résume le format des paquets DNS), dans le DNS, sont enregistrés à l'IANA, afin de s'assurer d'une interprétation identique partout. C'est ainsi que l'IANA gère un registre des paramètres DNS où on trouve, entre autres, les types d'enregistrement (A, codé 1, pour une adresse IPv4, AAAA, codé 28, pour une adresse IPv6, LOC, codé 29, pour les positions géographiques du RFC 1876, TLSA, codé 52, pour le RFC 6698, etc). Cet espace n'étant pas de taille infinie, il faut y enregistrer de nouveaux paramètres avec prudence.
L'affectation dans cet espace forme le point le plus important de
ce RFC (section 3). Il faut comprendre qu'il y a trois types de
numéros utilisés dans cet espace : ceux qui identifient un type de
données (comme les quatre cités plus haut), ceux qui identifient une
question et le cas particulier des méta-types. Une question, dans le
DNS, peut être un type de données (on met 52 dans le champ
QTYPE
de la requête pour dire qu'on veut des
enregistrements TLSA), mais il existe aussi des questions qui ne
correspondent pas à un type unique comme 255
(noté ANY
ou ALL
ou *
) qui veut dire
« envoie-moi toutes les données que tu as, quelles que soit leur
type ». Enfin, les méta-types sont des données temporaires, liées à
une transaction, comme les TSIG
(numéro 250) du RFC 8945, qui n'existent que le temps de la session
DNS.
Pour les types de données, la politique d'allocation est simple et
libérale : on remplit un formulaire (qui se trouve en annexe A du RFC), on l'envoie à
l'IANA (via l'adresse
dns-rrtype-applications@ietf.org
) et un expert l'examinera (procédure
Expert Review du RFC 5226) et rendra son jugement. (Il est recommandé de l'envoyer d'abord à la liste du
liste de groupe de travail
dnsext pour un examen préalable.) Les formulaires approuvés
sont ensuite publiquement archivés (mais je n'ai pas trouvé où).
Le RFC donne les critères que doit suivre l'expert pour sa décision :
CNAME
,
DS
), on
revient à la procéédure, bien plus lourde, d'une norme en bonne et due
forme. Notez que, pour certains types, un traitement spécial est
possible mais pas obligatoire (cas de MX
, où il
est conseillé d'inclure les adresses IP des serveurs de courrier dans
la réponse mais, si ce n'est pas fait, le service marche quand
même). Dans ce cas, c'est la procédure libérale qui s'appliqueOutre l'enregistrement de nouveaux types de ressources DNS, notre
RFC mentionne également d'autres champs des messages DNS. Un
changement ou une extension de leur sémantique continue à nécessiter
une action plus lourde à l'IETF. C'est le cas des classes (comme la
plus courante, IN
pour Internet). C'est aussi le
cas de bits comme RD (Recursion
Desired), qui n'a de signification que dans une question DNS. Dans
une réponse, il est indéfini et son éventuelle utilisation future nécessitera
un RFC sur le chemin des normes. Même chose pour le dernier bit qui
reste libre dans les options, le bit Z (section 2.1). Quant aux
opcodes qui indiquent le type du message (requête /
notification / mise à jour dynamique / etc), un ajout à leur liste
nécessitera le même chemin (section 2.2). Ils ont leur
propre registre.
Les codes de réponse (rcodes), comme
NXDOMAIN
(nom inexistant),
FORMERR
(erreur de format) ou
BADTIME
(signature trop ancienne ou trop récente,
cf. RFC 8945) sont tirés d'un
espace plus vaste (il n'y a pas que les quatre bits 12 à 15 dans l'en-tête
classique, il y a aussi des extensions comme les pseudo-enregistrements
OPT
) et la procédure est donc un peu plus
libérale (IETF Review, c'est-à-dire un RFC non
individuel mais pas
forcément sur le chemin des normes, cf. section 2.3). Il y a également
un registre de ces codes. À
noter qu'une gestion trop légère des registres avait entraîné à une
époque une double affectation du rcode 16,
enregistré par le
RFC 2671, puis ré-enregistré par le RFC 2845...
Notez aussi que notre RFC mentionne (section 3.3) l'allocation des noms, pour rappeler qu'il existe des noms réservés (RFC 2606) et qu'il existe un RFC (bien dépassé par les évolutions politiciennes ultérieures à l'ICANN), le RFC 1591, sur l'allocation et la gestion des TLD.
Les changements depuis le RFC 6195 sont décrits dans l'annexe B. Le seul vraiment important est une simplification du processus d'enregistrement des nouveaux types de données (par exemple, l'examen de la demande d'enregistrement d'un nouveau type de données par le groupe de travail dnsext n'est plus obligatoire). Cette simplification était largement consensuelle. Le reste des changements est un ensemble varié de clarifications et de précisions.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : E. Wilde (EMC Corporation)
Pour information
Première rédaction de cet article le 13 mars 2013
Dans le registre des types de liens, il y
avait déjà un describedby
qui indiquait une
ressource Web décrivant la ressource courante. Désormais, il y a aussi
l'inverse, describes
, qui va d'une ressource à
celle qu'elle décrit.
C'est dans le RFC 8288 que sont spécifiés ces
types de liens. describedby
avait été spécifié
par la norme W3C POWDER
mais celle-ci ne spéficiait pas le type du lien inverse. Notons que
describes
est très général, il ne spécifie pas le
format à utiliser et, notamment, on n'est pas obligé de se limiter à
RDF, on a tout à fait le droit de fournir des
descriptions en XML ou
JSON (section 4 de notre RFC).
Par exemple, si une page Web parle du livre Net.Lang, elle peut le référencer ainsi, en utilisant comme identificateur du livre l'URL de son site officiel :
<link rel="describes" href="http://net-lang.net/"/>
ou bien, pourquoi pas, avec l'ISBN (RFC 8254) :
<link rel="describes" href="urn:isbn:978-2-915825-08-4"/>
Il peut y avoir sur le Web plusieurs ressources qui pointent, via
un lien describes
, vers une ressource donnée.
Attention, n'importe qui peut toujours mettre un lien
describes
pointant vers n'importe où : la seule
existence de ce lien n'implique pas qu'il fasse autorité (section 5).
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : J. Damas (Bond Internet Systems), M. Graff, P. Vixie (Internet Systems Consortium)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 17 avril 2013
L'extension EDNS au traditionnel DNS a plus de treize ans et fête cette longue durée avec une nouvelle version, essentiellement cosmétique. EDNS a servi à faire sauter un certain nombre de barrières qui limitait la croissance du DNS, notamment l'antédiluvienne limite des réponses à seulement 512 octets.
Le protocole DNS, dans sa forme originale, spécifiée dans le RFC 1034, ne permettait pas de négocier des options, d'indiquer au serveur ce que sait faire le client, en plus des capacités minimales qu'impose le protocole. La norme originale (RFC 1035, section 2.3.4) imposait une limite de 512 octets aux messages DNS envoyés sur UDP. Une telle limite est bien trop basse, depuis longtemps, par exemple pour DNSSEC (section 3 de notre RFC), et ne correspondait pas aux capacités des réseaux et des machines modernes. Le DNS avait d'autres limites comme des champs de taille fixe, ne permettant qu'un petit nombre de valeurs possibles, désormais presque toutes définies (par exemple, avant EDNS, les codes de réponse - RCODE - ne faisaient que quatre bits, donc étaient presque tous épuisés).
EDNS0 est un mécanisme d'extension du DNS et une première extension, pour indiquer une taille supérieure aux 512 octets. L'extension se fait en squattant des champs inutilisés du paquet (DNS est un format binaire rigide, il ne permet donc pas facilement d'ajouter de nouvelles possibilités) et en créant un pseudo-type d'enregistrement, le type OPT. Déclaré comme indispensable par certaines autres extensions (notamment DNSSEC), EDNS fait aujourd'hui partie du bagage nécessaire à toute mise en œuvre du DNS.
L'extension pour indiquer la taille permet au client de
spécifier la quantité d'octets qu'il est capable de recevoir (section 4.3). Avec le
client DNS dig, cela se fait avec l'option
bufsize
(désormais activée par défaut dans les
versions récentes de dig). Notre RFC recommande une valeur par défaut
de 4 096 octets (section 6.2.5).
Prenons par exemple le TLD
.hk
car c'est un des plus
gros en nombre de serveurs de noms. Si je demande cette liste :
% dig NS hk. ; <<>> DiG 9.8.1-P1 <<>> NS hk. ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65212 ;; flags: qr rd ra; QUERY: 1, ANSWER: 10, AUTHORITY: 0, ADDITIONAL: 14 ;; QUESTION SECTION: ;hk. IN NS ;; ANSWER SECTION: hk. 69658 IN NS X.HKIRC.NET.hk. hk. 69658 IN NS T.HKIRC.NET.hk. hk. 69658 IN NS S.HKIRC.NET.hk. hk. 69658 IN NS A.HKIRC.NET.hk. hk. 69658 IN NS B.HKIRC.NET.hk. hk. 69658 IN NS W.HKIRC.NET.hk. hk. 69658 IN NS Z.HKIRC.NET.hk. hk. 69658 IN NS U.HKIRC.NET.hk. hk. 69658 IN NS Y.HKIRC.NET.hk. hk. 69658 IN NS V.HKIRC.NET.hk. ;; ADDITIONAL SECTION: A.HKIRC.NET.hk. 69658 IN A 203.119.2.18 B.HKIRC.NET.hk. 69658 IN A 203.119.87.19 B.HKIRC.NET.hk. 69658 IN AAAA 2001:dca:1000::cb77:5713 S.HKIRC.NET.hk. 69658 IN A 128.32.136.3 S.HKIRC.NET.hk. 69658 IN AAAA 2607:f140:ffff:fffe::3 T.HKIRC.NET.hk. 69658 IN A 128.32.136.14 T.HKIRC.NET.hk. 69658 IN AAAA 2607:f140:ffff:fffe::e U.HKIRC.NET.hk. 69658 IN A 210.201.138.58 U.HKIRC.NET.hk. 69658 IN AAAA 2404:0:10a0::58 V.HKIRC.NET.hk. 69658 IN A 204.61.216.46 V.HKIRC.NET.hk. 69658 IN AAAA 2001:500:14:6046:ad::1 W.HKIRC.NET.hk. 69658 IN A 202.12.28.140 W.HKIRC.NET.hk. 69658 IN AAAA 2001:dc0:1:0:4777::140 X.HKIRC.NET.hk. 69658 IN A 202.45.188.39 ;; Query time: 1 msec ;; SERVER: 130.129.5.6#53(130.129.5.6) ;; WHEN: Tue Mar 12 19:30:33 2013 ;; MSG SIZE rcvd: 486
On voit que la réponse était proche des 512 octets et que, pour qu'elle tienne dans cette limite, le serveur a dû sérieusement réduire la taille de la section additionnelle (additional section). Si le serveur avait dû réduire encore plus, jusqu'à retirer des enregistrements de la section réponse (answer section), il aurait dû mettre le bit TC (troncation) à VRAI, imposant ainsi au client de reessayer en TCP.
Mais EDNS0 permet d'avoir la totalité de la section additionnelle (notez la pseudo-section lié à l'enregistrement OPT) :
% dig +bufsize=4096 NS hk. ; <<>> DiG 9.8.1-P1 <<>> +bufsize=4096 NS hk. ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50455 ;; flags: qr rd ra; QUERY: 1, ANSWER: 10, AUTHORITY: 0, ADDITIONAL: 20 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;hk. IN NS ;; ANSWER SECTION: hk. 69632 IN NS Z.HKIRC.NET.hk. hk. 69632 IN NS S.HKIRC.NET.hk. hk. 69632 IN NS A.HKIRC.NET.hk. hk. 69632 IN NS X.HKIRC.NET.hk. hk. 69632 IN NS T.HKIRC.NET.hk. hk. 69632 IN NS V.HKIRC.NET.hk. hk. 69632 IN NS W.HKIRC.NET.hk. hk. 69632 IN NS Y.HKIRC.NET.hk. hk. 69632 IN NS U.HKIRC.NET.hk. hk. 69632 IN NS B.HKIRC.NET.hk. ;; ADDITIONAL SECTION: A.HKIRC.NET.hk. 69632 IN A 203.119.2.18 B.HKIRC.NET.hk. 69632 IN A 203.119.87.19 B.HKIRC.NET.hk. 69632 IN AAAA 2001:dca:1000::cb77:5713 S.HKIRC.NET.hk. 69632 IN A 128.32.136.3 S.HKIRC.NET.hk. 69632 IN AAAA 2607:f140:ffff:fffe::3 T.HKIRC.NET.hk. 69632 IN A 128.32.136.14 T.HKIRC.NET.hk. 69632 IN AAAA 2607:f140:ffff:fffe::e U.HKIRC.NET.hk. 69632 IN A 210.201.138.58 U.HKIRC.NET.hk. 69632 IN AAAA 2404:0:10a0::58 V.HKIRC.NET.hk. 69632 IN A 204.61.216.46 V.HKIRC.NET.hk. 69632 IN AAAA 2001:500:14:6046:ad::1 W.HKIRC.NET.hk. 69632 IN A 202.12.28.140 W.HKIRC.NET.hk. 69632 IN AAAA 2001:dc0:1:0:4777::140 X.HKIRC.NET.hk. 69632 IN A 202.45.188.39 X.HKIRC.NET.hk. 69632 IN AAAA 2405:3001:1:58::1:39 Y.HKIRC.NET.hk. 69632 IN A 137.189.6.21 Y.HKIRC.NET.hk. 69632 IN AAAA 2405:3000:3:60::21 Z.HKIRC.NET.hk. 69632 IN A 194.146.106.70 Z.HKIRC.NET.hk. 69632 IN AAAA 2001:67c:1010:17::53 ;; Query time: 1 msec ;; SERVER: 130.129.5.6#53(130.129.5.6) ;; WHEN: Tue Mar 12 19:30:59 2013 ;; MSG SIZE rcvd: 613
Et voilà, tout le monde est désormais content.
La section 6 décrit le pseudo-enregistrement OPT, dont la présence
marque un paquet comme conforme à EDNS. Il est situé dans la section
additionnelle du message DNS, a le type 41, le nom de domaine est
forcément .
(la racine), la classe est détournée
de son rôle normal pour indiquer la taille des paquets que l'envoyeur
pourra recevoir en retour et le champ TTL est
également détourné de son usage normal pour offrir de nouvelles
options et de nouveaux codes de retour (rappelez-vous qu'il n'y avait
que quatre bits pour ces codes dans le DNS original). Pour l'instant, une seule
nouvelle option, le bit DO (DNSSEC OK) qui
indique la capacité de l'émetteur à traiter les signatures DNSSEC (il
avait été normalisé dans le RFC 3225).
L'ex-champ TTL sert aussi à indiquer le numéro de version d'EDNS, zéro actuellement (d'où le nom EDNS0 qu'on utilise parfois). Programmeurs, attention, certaines API (par exemple celle de DNS Python) nécessitent d'indiquer le numéro de version pour activer EDNS et il faut donc indiquer zéro pour dire qu'on veut de l'EDNS, ce qui peut être déroutant.
Ensuite, les données peuvent contenir plusieurs options. À l'heure actuelle, l'écrasante majoritéé des paquets EDNS n'en contiennent aucune. Mais, si c'est le cas, elles sont codées en TLV, un code indiquant l'option (les valeurs possibles étant dans un registre IANA), une longueur et les données spécifiques à l'option. Un exemple d'une telle option est le NSID du RFC 5001.
On notera qu'EDNS est ce que le DNS appelle une extension
hop by hop ce qui veut dire qu'elle s'applique
entre deux logiciels adjacents, pas de bout en bout. Si un client DNS
demande à un résolveur local, qui demande à son tour à un serveur de
.re
, les options EDNS
mises par le client sont transmises uniquement au résolveur, qui
fabriquera ensuite une requête différente (peut-être avec d'autres
options), pour le serveur faisant autorité pour
.re
.
Encore aujourd'hui, il existe des serveurs qui ne gèrent pas
EDNS. Par exemple, ceux de microsoft.com
répondent FORMERR
(Format Error) :
% dig +bufsize=4096 @ns2.msft.net. SOA microsoft.com. ; <<>> DiG 9.8.1-P1 <<>> +bufsize=4096 @ns2.msft.net. SOA microsoft.com. ; (2 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: FORMERR, id: 54935 ...
La section 6.2.2 de notre RFC précise donc qu'un émetteur intelligent peut alors se rabattre sur du DNS classique et ne pas envoyer l'enregistrement OPT :
% dig @ns2.msft.net. SOA microsoft.com. ; <<>> DiG 9.8.1-P1 <<>> @ns2.msft.net. SOA microsoft.com. ; (2 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22484 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;microsoft.com. IN SOA ;; ANSWER SECTION: microsoft.com. 3600 IN SOA ns1.msft.net. msnhst.microsoft.com. 2013031202 300 600 2419200 3600 ...
Au moins, les serveurs de microsoft.com
répondent, même si c'est par un refus. Plus embêtant, les serveurs qui
ne répondent plus du tout lorsque la requête est en EDNS, en général
en raison d'une boîte noire mal programmée et mal gérée installée
devant le serveur (un pare-feu par exemple :
beaucoup d'administrateurs réseaux ne supportent pas que le serveur
DNS marche bien et mettent donc une
middlebox boguée devant,
cf. section 8 de notre RFC, ainsi que le RFC 5625). Un
logiciel comme BIND, lorsqu'il ne reçoit pas de
réponse, réessaie sans EDNS pour voir si c'est cela la cause du
problème. Cette possibilité est décrite en section 6.2.5 qui
recommande d'essayer d'abord EDNS avec une taille plus petite
(inférieure à la MTU, au cas où le problème
soit lié à la fragmentation), puis enfin sans EDNS.
L'EDNS original, du RFC 2671, prévoyait également des nouvelles façons de stocker les composants d'un nom de domaine, en plus des deux méthodes DNS traditionnelles, comprimée ou non (sections 4.2 et 5 de notre RFC et section 4.1.4 du RFC 1035). Cette pratique a été très peu utilisée, en raison des difficultés de déploiement (cf. RFC 3363 et RFC 3364). Notre RFC 6891 abandonne donc cette possibilité et reclasse le RFC 2673 (le seul qui avait utilisé un nouveau type de composants, les « composants binaires ») dans le cimetière des RFC dépassés. C'est le principal changement de ce nouveau RFC (les autres étant plutôt des détails, cf. annexe A.) Notons aussi que ce nouveau RFC est désormais « Norme Internet » et plus simplement « Proposition de norme ».
Pour les amateurs de programmation, du code C d'analyse d'un paquet DNS contenant de l'EDNS est dans mon article « Décoder les paquets DNS capturés avec pcap ».
Quelques exemples de code pour finir. Pour analyser un enregistrement OPT d'EDNS, voir comment c'est fait dans DNSmezzo. Ensuite, pour envoyer des requêtes EDNS, en Go, avec godns :
const ( EDNSBUFFERSIZE uint16 = 4096 ) ... m := new(dns.Msg) ... m.SetEdns0(EDNSBUFFERSIZE, true)
En Python, avec DNSpython (notez qu'on indique la version d'EDNS donc zéro pour activer EDNS n'est pas une erreur) :
message = dns.message.make_query(name, type, use_edns=0, payload=4096)
Et pour finir, en C, si vous assemblez le paquet à la main (il y a évidemment des façons plus simples de faire de l'EDNS), le code pourra ressembler à :
/* OPT pseudo-RR */ after_qname[4] = 0; /* root domain */ /* OPT = type 41 */ after_qname[5] = 0; after_qname[6] = 41; /* Class stores the payload size */ bufsize_wire = htons(bufsize); memmove(after_qname + 7, &bufsize_wire, sizeof(bufsize)); /* TTL store the RCODE and flags */ after_qname[9] = 0; after_qname[10] = 0; if (dnssec) { after_qname[11] = 128; /* DO: request DNSSEC signatures */ } else { after_qname[11] = 0; } after_qname[12] = 0; /* Resource data length (empty, here) */ after_qname[13] = 0; after_qname[14] = 0;
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : M. Cotton (ICANN), L. Vegoda (ICANN), R. Bonica (Juniper), B. Haberman (Johns Hopkins University Applied Physics Lab)
Première rédaction de cet article le 30 avril 2013
Dernière mise à jour le 16 juin 2017
Un certain nombre de préfixes d'adresses IP sont spéciaux, réservés à des tâches comme les exemples dans la documentation, ou bien prévus pour des protocoles particuliers. Ces préfixes n'étaient pas documentés à un endroit unique, ils étaient dans certains RFC, avec parfois des registres IANA. Ce RFC restructure le système, désormais la seule source faisant autorité est le registre IANA (un pour IPv4 et un pour IPv6). En outre, ces deux registres ont désormais une structure bien définie, notamment pour indiquer les propriétés d'un préfixe spécial.
Parmi les nombreux préfixes spéciaux, on peut citer le
0.0.0.0/8
du RFC 1122, qui
sert à désigner le réseau local, ou le fe80::/10
que le RFC 4291 dédie aux adresses locales au
lien. De temps en temps, un RFC rassemble tous
ces préfixes en un seul document et c'est ainsi que le RFC 5735 cataloguait tous les préfixes spéciaux
IPv4 alors que le RFC 5156 faisait la même chose pour
IPv6. Certains préfixes sont affectés à
l'IANA pour une allocation ultérieure (comme le
192.0.0.0/24
du RFC 5736). Ces prefixes-là ont un registre à l'IANA, pour
enregistrer ces allocations mais il n'existait pas de registre général
de toutes les adresses IPv4 spéciales. Même chose en IPv6 : le RFC 2928 et le RFC 4773 affectaient
2001:0000::/23
à l'IANA et créaient un registre
pour les adresses de ce préfixe mais sans prévoir de registre pour
tous les préfixes spéciaux. Résultat, lorsqu'un nouveau préfixe était
déclaré, il n'y avait plus de source à jour, avant qu'on publie un
nouvel RFC de synthèse. Notre RFC 6890 change ce système
et crée
ce registre unique de la totalité des préfixes spéciaux, pour IPv4 et pour IPv6. Notre RFC annule donc
les RFC 5735 et RFC 5156.
La section 2 du RFC liste les décisions prises et que l'IANA devra appliquer (suivant les sections 4.1 et 4.3 du RFC 2860 qui décrit les tâches de l'IANA). Le registre doit conserver, pour chaque préfixe IP, un certain nombre d'informations parmi lesquelles :
Évidemment, si les adresses IP d'un préfixe n'ont pas le droit d'être présentes en destination, les deux booléens suivants (transmissible par un routeur, et transmissible à d'autres domaines) n'ont pas de sens.
Voici quelques exemples de ces préfixes spéciaux (en mélangeant IPv4 et IPv6 qui, en pratique, sont dans deux registres) :
0.0.0.0/8
: désigne ce réseau local. Décrit
dans la section 3.2.1.3 du RFC 1122. Peut
apparaître en source, pas en destination.10.0.0.0/8
: adressage privé. Décrit dans
le RFC 1918. Peut apparaitre en source et en
destination, transmissible par les routeurs, pas d'unicité
mondiale.2001:10::/28
: préfixe dit
« ORCHID » (Overlay Routable Cryptographic Hash Identifiers), utilisé pour des adressages
sécurisés avec adresse dépendant d'une clé cryptographique. Décrit dans le RFC 4843. Ne peut
apparaitre ni en source, ni en destination (il n'est pas prévu de les
mettre directement dans les champs Source et Destination des paquets IPv6). Non transmissible par les routeurs, pas d'unicité
mondiale (mais une quasi-unicité due à leur choix imprévisible dans un espace très large).100.64.0.0/10
: partage d'adresses en
CGN. Décrit dans le RFC 6598. Peut apparaitre en source et en
destination, transmissible par les routeurs, pas d'unicité
mondiale.169.254.0.0/16
: adresses locales au lien,
typiquement auto-attribuées. Décrit dans le RFC 3927. Peut apparaitre en source et en
destination, non transmissible par les routeurs (locales au lien...), pas d'unicité
mondiale.fc0::/7
:
ULA. Décrit dans le RFC 4193. Peut apparaitre en source et en
destination, transmissible par les routeurs, pas d'unicité
mondiale (il avait été prévu un registre mondial pour une partie de
l'espace des ULA mais cela ne s'était jamais concrétisé).2001:0002::/48
ou 198.18.0.0/15
: adresses réservées pour les
mesures en laboratoire. Décrit dans le RFC 2544 ou le
RFC 5180. Peut apparaitre en source et en
destination, transmissible par les routeurs, pas d'unicité
mondiale.198.51.100.0/24
(et deux autres en IPv4) ou 2001:db8::/32
: adresses réservées à la
documentation. Décrit dans le RFC 5737 ou le
RFC 3849. Ne peut
apparaitre ni en source, ni en destination. Non transmissible par les routeurs, pas d'unicité
mondiale. Notez que, en IPv6, ces adresses pourraient être
quasi-uniques si elles étaient choisies au hasard dans l'espace
immense du 2001:db8::/32
. Mais, en pratique, tout
le monde prend la première, 2001:db8::1
.Date de publication du RFC : Avril 2013
Auteur(s) du RFC : S. Perreault (Viagenie), I. Yamagata, S. Miyakawa (NTT Communications), A. Nakagawa (Japan Internet Exchange (JPIX)), H. Ashida (IS Consulting G.K.)
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 1 mai 2013
Qu'on les approuve (ce qui n'est pas mon cas) ou pas, les CGN, ces gros routeurs NAT installés dans le réseau du FAI et gérant des centaines ou des milliers de clients, sont d'ores et déjà une réalité douloureuse dans de nombreux pays d'Asie, pour les pauvres utilisateurs de la 3G, et peut-être demain sur d'autres continents pour les accès fixes. Pour limiter les dégâts qu'ils causent, ce RFC 6888 pose un certain nombre de règles que devraient respecter ces CGN.
D'abord, qu'est-ce qu'un CGN ? Fonctionnellement, il ressemble au petit routeur NAT (RFC 2663) que vous avez chez vous. Comme lui, il fait du NAPT (Network Address and Port Translation), c'est-à-dire qu'il traduit dynamiquement des adresses IP du réseau interne vers celles utilisées à l'extérieur (et vice-versa pour les paquets dans l'autre sens). La grosse différence avec le petit routeur ou box chez vous est qu'il travaille pour de nombreux clients du FAI. Au lieu que l'adresse IP externe soit partagée uniquement entre les membres de votre cercle de famille, elle sera partagée avec des centaines d'inconnus.
Avec le CGN, il y a souvent « double NAT », une fois dans le CPE et une fois dans le CGN. Mais ce n'est pas obligatoire. Lorsqu'il y a double NAT, on parle souvent de NAT444 (deux traductions, d'IPv4 en IPv4).
Sur cette image, on voit du double NAT. Un FAI gère un
CGN.
Les adresses IP publiques du FAI, allouées par son
RIR sont ici
198.51.100.0/25
. Ce sont celles qui seront vues,
par exemple, par les sites Web où se connectent les clients du FAI. Le
FAI n'a pas assez d'adresses IP publiques pour son réseau interne et
il utilise donc le 10.0.0.0/8
du RFC 1918. Prenons maintenant le client 1 : son réseau local a des adresses
dans la plage 192.168.3.0/24
. Les paquets seront
donc émis avec ces adresses, NATés une première fois par la machine
CPE 1, vers l'adresse 10.0.5.22
. Ils seront
ensuite NATés une seconde fois par le CGN.
Le CGN a des conséquences, par exemple dans le domaine légal (en théorie, vous pourrez voir les agents de la HADOPI débarquer chez vous parce qu'un autre utilisateur du même CGN a téléchargé illégalement, cf. RFC 6269). Et cela limite sérieusement les activités que vous pourrez avoir sur l'Internet. Par exemple, un moyen courant d'accepter les connexions entrantes, normalement interdites par le NAPT, est de configurer sa box pour rediriger tel numéro de port vers tel service sur le réseau local (par exemple pour faire fonctionner des applications pair-à-pair). Le routeur CGN étant partagé entre de nombreuses personnes qui ne se connaissent pas, cela n'est plus possible. Contrairement au routeur NAT à la maison, le CGN n'est pas géré par les abonnés, qui ne peuvent pas modifier sa configuration.
D'autre part, la simple taille du CGN en fait un engin compliqué et fragile, et sa panne affecte bien plus de clients que le redémarrage d'une box. Enfin, ayant moins de ports sources à sa disposition par client, par rapport au routeur de la maison ou du SOHO, il risque plus souvent de tomber à cours, si les clients font beaucoup de connexions sortantes.
Mais, alors, pourquoi met-on des CGN ? Juste pour embêter les clients ? En fait, les FAI n'ont pas forcément beaucoup le choix. La pénurie d'adresses IPv4, bien que niée par beaucoup de négationnistes, est réelle depuis de nombreuses années. Par exemple, cela fait longtemps qu'on ne peut plus avoir une adresse IP par machine à la maison. Mais, jusqu'à récemment, on pouvait encore avoir une adresse IP publique par foyer. Désormais, l'espace d'adressage IPv4 disponible se resserrant chaque jour, ce n'est même plus le cas. S'il n'y a pas d'adresse IPv4 publique disponible pour chaque client, le CGN est la seule solution pour pouvoir continuer à faire de l'IPv4 (passer à IPv6 ferait moins de travail mais les acteurs du marché sont frileux).
Cela, c'était la raison avouable pour mettre des CGN. Il y en a une moins avouable, c'est que le CGN, grosse machine centrale et point de passage obligatoire pour tous les abonnés, est bien en phase avec la mentalité des opérateurs telco traditionnels. C'est ainsi que, dans l'Internet mobile où les libertés sont bien plus limitées, et l'utilisateur bien plus restreint dans ce qu'il a le droit de faire, tous les opérateurs 3G ont déployé cette solution depuis longtemps, refusant de donner une adresse IPv4 publique à chaque abonné, même avant l'épuisement complet des réserves. Comme le note prudemment le RFC, « there are driving forces other than the shortage of IPv4 addresses ».
À noter qu'un RFC décrit le déploiement de CGN comme une des techniques pouvant aider à la transition vers IPv6 : RFC 6264. Le CGN est un des composants de la solution DS-Lite, décrite dans le RFC 6333 et ce composant doit donc suivre les règles données plus loin.
Maintenant qu'on a présenté les CGN, que contient ce RFC ? Il liste des conseils qui, s'ils étaient appliqués, rendraient les CGN un peu moins insupportables. Comme le note la section 1, la publication de ce RFC ne signifie pas que l'IETF approuve ou même accepte les CGN, simplement que, puisqu'ils existent, autant essayer de limiter leurs effets négatifs. Comme un CGN est un routeur NAT, les précédents documents du groupe de travail Behave, concernant tous les types de NAT, s'appliquent aussi au CGN : RFC 4787, RFC 5382 et RFC 5508 notamment.
Les section 3 à 5 représentent donc le cœur de ce RFC. Elles contiennent les recommandations spécifiques pour les CGN. Chacune est nommée REQ-n où n est un numéro d'ordre. Ainsi, REQ-1 dit que, pour chaque protocole de transport, le CGN doit suivre les recommandations spécifiques à ce protocole (RFC 4787 pour UDP, RFC 5382 pour TCP, RFC 5508 pour ICMP, et RFC 5597 pour DCCP). Notons que les autres protocoles de transport (comme SCTP) ont donc de sérieuses chances de ne pas fonctionner au travers du CGN.
Exigence suivante, REQ-2, qui dit que le comportement de l'IP address pooling doit être paired. Cela signifie quoi ? Qu'une machine donnée doit toujours obtenir la même adresse IP externe (un CGN, contrairement au petit routeur NAT de la maison, a en général plusieurs adresses IP externes à sa disposition). Cela limite les risques de casser les applications. Le RFC 4787, section 4.1, donne les détails sur ce concept de paired.
À propos du nombre d'adresses externes disponible pour le CGN : REQ-3 exige que ces adresses puissent être en nombre quelconque et dans des plages non-contigües (avec l'épuisement des adresses IPv4, il sera de plus en plus dur de trouver des plages contigües).
REQ-4 traite un problème spécifique aux CGN, que n'avaient pas les petits routeurs NAT de la maison : il faut pouvoir limiter le nombre de ports utilisables par un utilisateur donné. Dans le NAPT, il y a moins d'adresses externes que d'adresses internes. On se sert donc des ports pour désambigüiser. Un seul utilisateur gourmand pourrait lancer plein de sessions et épuiser à lui seul la plage de ports disponibles (cela peut même être volontaire, pour faire un déni de service, cf. section 8). C'est pour se protéger contre cette attaque que REQ-4 exige une limitation, configurable, par client. Le RFC recommande aussi qu'on puisse limiter le rythme de création de sessions par utilisateur. C'est nécessaire pour protéger les autres utilisateurs, mais c'est un bon exemple des inconvénients du CGN, qui casse sérieusement la transparence du réseau et le principe de bout en bout. Les routeurs NAT cassaient ces principes mais uniquement entre membres d'un même foyer ou d'un même SOHO. Avec le CGN, on dépend de gens dont on ne connait rien.
Même chose avec REQ-5, consacrée à d'autres ressources partagées dans le CGN, comme sa mémoire. Un CGN a des problèmes d'équité que n'ont pas les routeurs NAT classiques, vue son utilisation entre personnes qui n'ont rien en commun a priori.
Parfois, les cibles que vise l'utilisateur sont situées dans le réseau du FAI, et donc atteignables sans traduction d'adresse. Pour ce cas, REQ-6 demande que le CGN puisse être configuré pour ne pas traduire si la destination est dans une liste d'adresses configurées par l'administrateur réseaux.
Lorsqu'un routeur NAT accepte des paquets entrants du moment qu'il a, dans sa table des traductions, une entrée pour ce couple {adresse,port} de destination, indépendemment de l'adresse IP source d'émission, on dit qu'il fait du Endpoint-Independent Filtering (RFC 4787, section 5). REQ-7 souhaite que ce soit le comportement du CGN, car il casse moins d'applications (notamment jeux en ligne et pair-à-pair) que le Address-Dependent Filtering (où les paquets sont refusés si l'adresse source n'est pas celle dans l'entrée de la table).
REQ-8 légifère sur la réutilisation d'un port externe lorsqu'il n'est plus utilisé. Par défaut, il devrait rester réservé pendant deux minutes, le Maximum Segment Lifetime de TCP (RFC 793, section 3.3), après lequel on est sûr que le paquet ne traîne plus dans le réseau. Cela permet d'éviter une collision entre une ancienne correspondance et une nouvelle, qui utiliserait le même port externe et recevrait par erreur de vieux paquets. Des exceptions sont prévues, notamment :
REQ-9 est plus ambitieux car il exige quelque chose qui n'existe pas dans les CGN actuels : un mécanisme permettant à l'utilisateur de changer les affectations de port, et que ce mécanisme soit de préférence PCP (Port Control Protocol, RFC 6887). Aujourd'hui, sur les petits routeurs NAT de la maison ou du SOHO, ce mécanisme d'affectation manuelle des correspondances {adresse externe, port externe} -> {adresse interne, port interne} est typiquement fait par l'interface Web d'administration du routeur, ou bien par UPnP. La disparition d'un tel mécanisme dans les CGN actuels est un des plus gros problèmes que posent les CGN. Il était donc nécessaire de le rétablir, pour que toutes les applications puissent bien fonctionner. Mais PCP est encore très récent et peu déployé.
REQ-10 concerne plutôt les besoins de l'opérateur plus que ceux des simples utilisateurs : il demande que les routeurs CGN soient gérables (MIB du RFC 4008, etc).
Une autre exigence, REQ-11 concerne le traitement des erreurs. Si un routeur CGN ne peut pas créer une corrrespondance entre adresse+port externe et interne, il doit jeter le paquet et devrait renvoyer un message ICMP Destination unreachable / code 1 (Host unreachable). et déclencher une trap SNMP. Le « devrait » (et pas « doit ») est parce que ces deux types de messages peuvent légitimement avoir un débit limité.
Pourquoi Host unreachable et pas Communication administratively prohibited comme c'était le cas dans le RFC 5508, section 6 ? Parce que le code 1 (Host unreachable) est une erreur « douce » (cf. RFC 1122) et ne coupera pas les connexions TCP en cours entre les mêmes machines (RFC 5461).
En outre, le RFC interdit de supprimer des entrées existantes dans la table de correspondances, ce qui permettrait pourtant de faire de la place pour de nouvelles connexions. C'est parce que la plupart des applications gèrent beaucoup mieux une impossibilté à établir une connexion qu'une perturbation ou une interruption d'une connexion en cours (RFC 5508, section 6).
Un bon routeur CGN devrait pouvoir journaliser son activité. La section 4 encadre cette tâche. La principale question qui se pose est l'identification des clients, si une adresse IP externe est repérée pour son comportement abusif (envoi de spam, écriture d'un commentaire de blog défavorable aux autorités, partage de fichiers musicaux, et autres crimes). Le site distant va noter que « 192.0.2.42 a fait quelque chose de mal » et les enquêteurs vont chercher la personne qui est derrière cette adresse. En raison du CGN, des dizaines ou des centaines de personnes peuvent avoir utilisé cette adresse. Pour que l'enquêteur ait la moindre chance de retrouver le coupable, il faut que le site distant journalise, non seulement l'adresse IP source (comme c'est typiquement le cas aujourd'hui), mais aussi le port source (cf. RFC 6302). Et il faut que le routeur CGN ait journalisé ses correspondances, protocole de transport, adresse+port internes, adresse+port externes et heure exacte. (C'est une obligation légale dans certains pays, par exemple en France avec la LCEN.)
Non seulement c'est très Big Brother comme comportement mais, en plus, cela peut rapidement produire une énorme quantité de données, ce qui ne va pas faciliter la tâche de l'opérateur. C'est pour cela que REQ-12 demande que ce ne soit pas activé par défaut, à la fois pour préserver la vie privée des utilisateurs et pour éviter de remplir les disques durs. (Notez aussi que le RFC ne conseille pas de loguer l'adresse IP de destination, ce qui serait bien pire.)
Et, au fait, comment allouer aux utilisateurs cette ressource limitée, les numéros de ports externes ? La section 5 formule trois exigences. Le problème est que les trois sont contradictoires. REQ-13 dit qu'il faudrait chercher à maximiser l'utilisation des ports (ils sont en nombre limités, 65 536 par adresse IP), REQ-14 (qui a suscité beaucoup de discussions dans le groupe de travail) qu'il faudrait minimiser le nombre d'entrées produites dans le journal, par exemple en allouant toute une plage de ports par adresse IP, et REQ-15 que, pour des raisons de sécurité, il faudrait rendre difficile pour un attaquant la prédiction des ports sélectionnés (RFC 6056). Pas de miracle, ces trois exigences ne peuvent pas être satisfaites simultanément et un routeur CGN doit donc choisir lequel est le plus important pour lui. J'emprunte à Simon Perreault une description de la situation en mai 2013 : « Le CGN de Cisco allouait les ports 100 % dynamiquement, comme un NAT traditionnel, et génèrait donc beaucoup de logs. Mais ceux d'autres vendeurs, dont Alcatel, Juniper et Huawei, [ainsi que Cisco désormais, note de Nicolas Février] allouent les ports en bloc, ce qui génère beaucoup moins de logs au prix d'une légère perte de taux d'utilisation des adresses IPv4 externes. Il y a aussi le deterministic NAT qui alloue les ports statiquement tout en conservant une plage d'allocation dynamique pour les débordements. »
Merci à André Sintzoff pour la relecture technique et la détection d'une grosse faute technique. Merci à Nicolas Février pour ses utiles commentaires, même s'il n'est pas d'accord avec moi sur les défauts du CGN.
Date de publication du RFC : Avril 2013
Auteur(s) du RFC : D. Wing (Cisco), S. Cheshire (Apple), M. Boucadair (France Telecom), R. Penno (Cisco), P. Selkirk (ISC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF pcp
Première rédaction de cet article le 1 mai 2013
Aujourd'hui, l'utilisateur de l'Internet ne bénéficie que rarement d'une connexion neutre, d'un simple tuyau le connectant à toutes les autres machines de l'Internet. La plupart du temps, il est au contraire bloqué derrière des engins comme les routeurs NAT ou les pare-feux. Par défaut, ces engins bloquent les connexions entrantes, limitant l'utilisateur à un usage type Minitel. Dans ce cas, on a souvent besoin de dire à l'engin sur le trajet « laisse entrer des connexions vers tel port » (par exemple pour le pair à pair). Cela se fait aujourd'hui en général par une interface spécifique (par exemple une page Web d'administration du routeur NAT) ou par le protocole privé UPnP. Il y avait donc une demande pour un protocole standard, adapté aux mécanismes d'aujourd'hui comme les CGN : c'est ce nouveau protocole, PCP (Port Control Protocol).
Voici un exemple de configuration manuelle comme on fait souvent aujourd'hui, via une interface Web, ici celle d'une Freebox : Avec PCP, ces interfaces vont-elles disparaître complètement ?
Le principe est simple : un serveur PCP tourne sur l'engin bloquant (routeur NAT ou pare-feu) et autorise des clients PCP à lui parler et à demander des services comme l'ouverture d'un port entrant, ou comme une durée de vie plus longue pour les sessions en cours. Redonnant du contrôle à la machine de l'utilisateur, il rétablit un peu de neutralité dans le réseau. Avec PCP, on a un moyen propre de gérer un serveur (acceptant des connexions entrantes) derrière un routeur NAT et même derrière un CGN. Rappelez-vous qu'accepter des connexions entrantes n'est pas seulement utile si on a un serveur Web à la maison, c'est également une fonction demandée par les protocoles de voix sur IP comme SIP ou bien par le pair-à-pair.
Une fois que le client PCP a obtenu une réponse positive du serveur
PCP (« OK, j'envoie les connexions entrantes sur le
port 8080 à 172.19.1.1
,
port 80, comme tu me l'as demandé »), il peut alors prévenir le reste
du monde. Cette information sur le rendez-vous n'est pas gérée par
PCP : on se sert de fonctions spécifiques au protocole (SIP
REGISTER
auprès du mandataire, pour SIP, par exemple), ou bien du
DNS (éventuellement avec mise à jour dynamique
du RFC 2136 pour cela). Les enregistrements
SRV du DNS (RFC 2782) sont la solution idéale, puisqu'ils
permettent d'indiquer le numéro de port.
On notera que PCP diminue le besoin d'ALG dans les engins intermédiaires. Une nouvelle application n'aura pas besoin d'attendre que des ALG apparaissent, elle pourra contrôler les connexions dont elle a besoin elle-même, via PCP.
Même si on n'accepte pas de connexions entrantes, qu'on est un pur client, PCP peut être utile. Les routeurs NAT et les pare-feux coupent typiquement la session au bout de N minutes d'inactivité. Pour empêcher cela, les applications qui doivent rester connectées longtemps (SSH, par exemple), envoient régulièrement des paquets keepalive. Avec PCP, ce n'est plus nécessaire, l'application peut dire au serveur PCP « augmente N, s'il te plait ».
PCP est conçu, au contraire d'UPnP, pour une large gamme de besoins : du NAT traditionnel (RFC 3022), au NAPT commun aujourd'hui dans les boxes (cf. RFC 3022, section 2.2), en passant par le CGN (RFC 6888) et des choses plus exotiques comme DS-Lite (RFC 6333 et RFC 6619), NAT64 (RFC 6146), et même NAT66/NPT (RFC 6296).
PCP est prévu pour fonctionner avec les protocoles de transport qui ont la notion de port (UDP, TCP, SCTP, DCCP, etc). Pour les autres (ICMP, RSVP, ESP...), PCP ne fournit que des services partiels.
Autre limitation : PCP suppose que la machine de M. Toutlemonde n'a qu'une seule connexion à l'Internet, passant par l'équipement qui héberge le serveur PCP. Le but est de garantir que l'équipement qui répond en PCP verra bien passer tous les paquets. Ce modèle convient à la maison ou à la petite entreprise actuelle, avec son réseau local connecté via une unique box. Le dessin 1 en section 4 du RFC illustre ce modèle.
Les sections suivantes fournissent les détails du
protocole. Celui-ci manipulant souvent des adresses IP, la représentation de celles-ci (section
5) va servir
souvent : PCP utilise systématiquement un champ de taille fixe de 128
bits (même pour des adresses IPv4, qui sont
alors représentées préfixées du ::ffff:0:0/96
), car c'est
plus simple.
Une description de haut niveau du protocole est en section 6. À première vue, PCP pourrait être traité comme un protocole requête/réponse (un peu comme le DNS) mais, en fait, comme il n'est pas synchrone (on peut envoyer plusieurs requêtes à la suite et lire ensuite plusieurs réponses), il vaut peut-être mieux le considérer comme un protocole suggestion/notification. Le client PCP fait des suggestions au routeur ou au pare-feu (qui sont donc libres de refuser) et le serveur PCP (le routeur ou pare-feu) envoie des notifications indiquant son état. Dans ce modèle, il y a donc deux flux de données indépendants, un du client PCP vers le serveur et un du serveur PCP vers le client. Bien sûr, l'envoi d'une notification est en général corrélé à une suggestion (elle indique indirectement l'acceptation de la suggestion) mais, je le répète, ce n'est pas synchrone. (Une des raisons de ce choix est de permettre au serveur de résister aux attaques par déni de service en ignorant les suggestions lorsque la charge est trop élevée, laissant le client ré-émettre si nécessaire.) PCP tourne sur UDP (ports 5350 et 5351) et n'a pas de notion de transaction (les messages ne portent pas d'identificateur de transaction.) La notification donne l'état actuel du routeur ou pare-feu. Si le client tient à savoir à quelle suggestion est liée telle notification, il doit examiner le contenu du message et le corréler aux suggestions qu'il a envoyées.
La section 7 indique le format standard de tous les paquets : un
numéro de version (aujourd'hui 2), un bit indiquant s'il s'agit d'une
question ou d'une réponse, un code indiquant l'opération (la plus
importante est sans doute MAP
, décrite en section
11), l'adresse IP
du client PCP, la durée de vie demandée ou obtenue (pour certaines opérations) et quelques autres informations, qui dépendent de
l'opération. Parmi elles, les options, encodées en
TLV et enregistrées dans un registre IANA.
Les réponses ont un champ indiquant le code de retour d'une requête. 0 est un succès, tous les autres codes indiquent une erreur. Par exemple, 2 est la réponse à une requête non autorisée (rappelez-vous que le serveur PCP a sa propre politique et n'obéit pas aveuglément à tout ce que demande le client), 3 la réponse à une requête syntaxiquement incorrecte, etc. Ces deux erreurs sont permanentes (renvoyer le même paquet PCP ne changera rien). Mais il existe aussi des erreurs temporaires comme 8 qui indique que le serveur PCP aurait bien voulu répondre favorablement mais qu'il manque de ressources (par exemple de ports libres) pour cela. Ré-essayer automatiquement, après un délai raisonnable, peut donc être une bonne solution.
Le fonctionnement de base de PCP figure en section 8. Le client PCP
doit d'abord trouver le serveur. Il a pu le connaître par
configuration statique, ou tout simplement l'apprendre via une option
DHCP (RFC 7291). Sinon, il tente le routeur par défaut,
qui sera en général le serveur PCP. Le client va ensuite générer un
message, où l'adresse IP du client est sa propre adresse IP (qui sera
souvent une adresse privée, du RFC 1918). La
section 16.4 explique comment connaître cette adresse grâce à
getsockname()
. Le
client doit être prêt à retransmettre (section 8.1.1 pour les détails) : UDP ne
garantit pas l'acheminement.
Le serveur reçoit la requête, vérifie qu'elle arrive sur la bonne interface (le CPE typique de M. Toutlemonde, par exemple, n'acceptera pas les requêtes PCP venant de l'Internet, uniquement celles venant du réseau local), vérifie que l'adresse du client dans le paquet correspond à l'adresse IP source (autrement, c'est qu'un NAT supplémentaire se trouvait accidentellement sur le chemin) et répond. Il inclus dans la réponse un champ Epoch qui est un compteur s'incrémentant une fois par seconde. Si le client voit ce compteur diminuer, cela indiquera que le routeur a probablement redémarré, et donc perdu toutes les correspondances enregistrées, qu'il va falloir re-créer.
C'est quoi, ces « correspondances » (mappings
dans la langue de George Martin) ? Le routeur
NAT maintient une table des correspondances entre un couple {adresse
IP interne, port interne} et un couple {adresse IP externe, port
externe}. Cette table est en partie remplie automatiquement lors des
connexions sortantes mais peut aussi être partiellement gérée par
PCP. Par exemple, le fonctionnement classique du NAT d'un petit
routeur à la maison, lorsqu'un paquet venant de {192.168.10.10
,
5623} sort, est de réserver un port pour cette session (mettons le
port 7891) et de mémoriser une correspondance
{203.0.113.254
, 7891} <=> {192.168.10.10
,
5623} (on suppose que l'adresse IPv4 externe du routeur est
203.0.113.254
). Avec cette correspondance en tête,
le paquet de réponse destiné à {203.0.113.254
,
7891} sera automatiquement NATé et dirigé vers {192.168.10.10
,
5623}. PCP permet de manipuler de telles correspondances et, par
exemple, pour reprendre un exemple donné plus haut, de dire « envoie
les connexions entrantes sur le port 8080 à 192.168.10.1
,
port 80 », ce qui se traduira par la création d'une correspondance
(mapping) {203.0.113.254
, 8080} <=> {192.168.10.11
,
80}. On notera que le client PCP n'a pas indiqué l'adresse externe
203.0.113.254
. PCP permet de le faire mais, dans
le cas le plus courant, le client PCP ne connait pas cette adresse et
laisse le serveur la choisir.
La section 10 résume les opérations les plus importantes de PCP,
MAP
(détaillée en section 11) et
PEER
(détaillée en section 12). MAP
permet de
créer les correspondances statiques, pour gérer un serveur,
PEER
permet notamment de manipuler les correspondances dynamiques,
celles crées automatiquement par le routeur NAT. La liste de toutes
les opérations est dans un registre IANA
(cf. section 19.2, sur la politique d'affectation des codes numériques
correspondants.)
Prenons l'exemple d'un serveur du
réseau local (comme {192.168.10.11
,
80} dans mon exemple), qui va appeler MAP
pour
« ouvrir » le routeur ou pare-feu aux connexions entrantes. En
pseudo-code :
/* Les variables précédées de & sont des pointeurs, pour pouvoir écrire un résultat dans la variable. */ externalport = 80; pcp_send_map_request(myport, myaddr, &externalport, &externaladdr, requestedlifetime, &assignedlifetime); if (!pcp_response_received()) panic("No answer"); } else { /* Éventuellement mettre à jour le DNS, un serveur de rendez-vous, pour dire au reste du monde qu'il peut y aller */ } /* La suite est le code habituel, sans PCP */ if (received_incoming_connection_or_packet()) process_it(s);
Si l'application se moque du port externe attribué, il suffit de ne pas l'indiquer dans la requête et de regarder dans la réponse quel port a été alloué. De toute façon, le routeur ne lui allouera pas forcément le port demandé. Par exemple, pour un CGN, tout le monde voudra sans doute s'allouer le port 80, ce qui n'est pas possible. Soit le CGN le refusera à tous, soit il le donnera au premier arrivé et allouera un autre port pour les suivants. Un client PCP bien fait doit donc être préparé : il doit lire le port effectivement attribué et réagir intelligemment s'il n'a pas eu le port souhaité (ce n'est pas fait dans le programme d'exemple ci-dessus). Bien sûr, le client PCP doit aussi être prêt à ce que sa requête soit complètement rejetée, par exemple parce que la table des correspondances a une taille fixe et que ladite table est pleine.
La lecture de la réponse permet aussi au client PCP de savoir quelle est l'adresse externe allouée, ce qui peut être pratique. (Si on n'est intéressé que par cela, il suffit donc de créer une correspondance avec une très courte durée de vie et de lire la réponse.)
La réponse PCP inclut la durée de vie de la correspondance
(champ Lifetime du paquet, variable
assignedlifetime
du programme plus haut). C'est
la responsabilité du client de renouveller la correspondance avant
qu'elle n'expire (cf. section 15).
Si l'application ne sait pas si elle est derrière un routeur NAT ou un
pare-feu, ce qui est fréquent, la solution recommandée est quand même
d'essayer PCP. S'il n'y a pas de réponse, cela peut vouloir dire que
la machine a une connectivité complète (sans NAT) ou malheureusement
que le routeur ne gère pas PCP. (Le code plus haut suppose que
l'absence de réponse indique qu'on n'a pas de connectivité en tant que
serveur, donc panic()
.)
Le routeur doit créer des correspondances ayant la sémantique Endpoint Independent Filtering, ce qui veut dire que cette correspondance sera la même quelle que soit l'adresse IP de la machine distante. Il va devoir aussi se débrouiller pour que les messages ICMP correspondant à cette correspondance soient bien acheminés à la machine.
Outre les champs génériques communs à tous les paquets PCP,
MAP
a quelques champs qui lui sont propres
notamment le port interne (la variable myport
dans le pseudo-code), le port externe suggéré
(la variable externalport
dans le programme en
pseudo-code) et l'adresse IP externe suggérée (rappelez-vous que le
petit routeur NAT de la maison n'a pas le choix : il n'a en général
qu'une seule adresse IPv4 externe, donc il ignorera ce
paramètre). Dans la réponse à un MAP
, la valeur
de ces champs indiquera au client ce que le serveur PCP a finalement
choisi (pas forcément ce qui était demandé). Une option de la requête
permet de dire si les adresses et ports suggérés sont impératifs (on
préfère un échec plutôt qu'une correspondance avec d'autres valeurs
que celles demandées) ou
pas (cf. section 13.2).
MAP
permet aussi de contrôler un
pare-feu, avec son option
FILTER
(section 13.3) où on décrit les adresses
IP et ports autorisés, le reste étant bloqué. Séparer la fonction de
NAT de celle de pare-feu est essentiel : actuellement, les routeurs
NAT typiques mélangent les deux, ce qui a mené certaines personnes à
croire que le NAT avait un rôle de
protection. Outre la sécurité, FILTER
peut
être utile pour des machines sur batterie :
elles éviteront ainsi de gaspiller du courant à traiter des paquets
non désirés.
PCP est également utile au cas où on n'a certes besoin que de
connexions sortantes mais où on veut influencer des paramètres comme
la durée de vie des correspondances créées automatiquement, de manière
à ne pas avoir besoin d'envoyer de temps en temps des paquets
keepalive. On utilise pour cela l'opération
PEER
. Cette opération a à peu près les mêmes
champs que MAP
mais les correspondances crées
peuvent avoir des sémantiques autres que Endpoint Independent
Filtering. (MAP
a le code 1 et
PEER
2, dans le registre IANA.)
Un autre usage de l'opération PEER
est pour
re-créer des correspondances perdues. Un des plus gros inconvénients du NAT est qu'il maintient un
état dans le routeur. Normalement, l'Internet est
un réseau de paquets, les routeurs intermédiaires font passer les
paquets mais n'ont aucune notion de session associées, il font passer
du TCP, de l'UDP ou
n'importe quel autre protocole sans faire de différence. Un des
avantages de ce principe est que le redémarrage d'un routeur ne change
rien : les connexions TCP, par exemple, continueront comme si rien ne
s'était passé, l'état des connexions étant entièrement contenu dans
les machines terminales. Le NAT change tout cela : si un routeur NAT
redémarre, toutes les correspondances sont perdues. Si les machines
tentent de continuer la communication, de nouvelles correspondances
seront créées, avec de nouveaux numéros de port, et ce changement
cassera les connexions TCP en cours. C'est notamment insupportable
pour SSH.
Comment PCP peut-il aider ? Une machine qui connait la
liste des correspondances (elle a pu l'apprendre avec l'opération
PEER
) peut, lorsqu'elle détecte un redémarrage du
routeur, lui renvoyer cette liste (toujours avec
PEER
mais, cette fois, en remplissant les champs
Suggested Address et Suggested Port), rétablissant ainsi la même table
des correspondances (section 14). À noter que, pour accélérer la
reconstitution de l'état du routeur, un routeur qui sait qu'il va
redémarrer peut aussi envoyer des paquets PCP avec l'opération
ANNOUNCE
(section 14.1.3) pour prévenir les
clients. Ces envois se font aux adresses
multicast
224.0.0.1:5350
et
[ff02::1]:5350
(224.0.0.1
et ff02::1
voulant dire « toutes les machines du réseau »). Les machines clientes
peuvent alors savoir qu'elles vont devoir recréer leurs
correspondances (après avoir attendu un délai aléatoire, pour éviter
qu'elles ne le fassent toutes en même temps).
PEER
peut enfin créer une nouvelle
correspondance mais cela n'a pas un grand intérêt, puisque tout
routeur NAT sait le faire automatiquement au premier paquet d'une
nouvelle connexion sortante. (La seule exception est le cas cité plus
haut où on restaure l'état d'un routeur NAT qui a redémarré.)
Je ne connais pas l'état actuel de mise en œuvre de PCP dans les routeurs NAT typiques. Pour le programmeur qui veut s'y mettre sérieusement, la section 16 contient un certain nombre de conseils pratiques, aussi bien pour l'écriture de serveurs que pour celle de clients PCP. Quant à la section 17, elle se penche sur les problèmes de déploiement de cette nouvelle technologie. Par exemple, il est important que le routeur rejette les paquets entrants dont l'adresse source ne correspond pas à celles du réseau interne (RFC 2827) pour éviter qu'un méchant n'usurpe une adresse IP.
Tiens, puisqu'on parle de sécurité, la section 18 lui est entièrement consacrée. PCP permet de contrôler plus finement les correspondances dans le routeur, voire de modifier les filtres d'un pare-feu. Il est donc essentiel que ces nouvelles possibilités ne se fassent pas au détriment de la sécurité. Par exemple, une machine du réseau interne autorisée à créer ou modifier des correspondances peut voler le trafic d'une autre. Ce n'est pas très grave pour un réseau local à la maison mais bien plus embêtant dans le cas d'un grand CGN.
PCP, s'il est correctement mis en œuvre, est protégé contre les
attaquants situés en dehors du chemin. Par exemple, si une machine
quelque part sur l'Internet envoie un paquet PCP prétendant venir
d'une des adresses internes (mettons
192.168.1.1
), le routeur/serveur PCP rejettera ce
paquet qui arrive par l'interface externe (il ne doit accepter les
requêtes PCP que si elles sont internes). Par contre, un attaquant
interne a à peu près open bar avec PCP. Un serveur
PCP doit donc être déployé uniquement si toutes les machines internes
sont considérées comme membres de la même bande (une supposition
raisonnable pour un réseau domestique) ou si on peut séparer les
clients en plusieurs domaines, empêchant M. Michu de voler le trafic
de Mme Toutlemonde, située derrière le même CGN.
Une façon de limiter les risques est que le serveur PCP ne configure explicitement que des correspondances qu'il aurait de toute façon configuré implicitement, lorsqu'une nouvelle connexion sort. Cela veut dire qu'il y a des opérations PCP sûres (créer une correspondance sans spécifier le port et l'adresse externes) et d'autres qui peuvent être dangereuses (créer une correspondance avec un port externe spécifié).
Si on autorise PCP à configurer un pare-feu, il faut évidemment faire encore plus attention. Il n'existe pas à l'heure actuelle de mécanisme de sécurité standard pour PCP : son premier domaine d'application concerne des cas où il n'y a déjà pas de sécurité aujourd'hui. Pour d'autres domaines, il faudra trouver de nouvelles solutions de sécurité.
Quelques autres attaques possibles avec PCP :
PCP est le successeur d'un protocole très proche nommé PMP (Port Mapping Protocol, RFC 6886). L'annexe A décrit la coexistence entre les implémentations de PMP qui restent, et PCP. L'autre protocole qui avait été envisagé par le groupe de travail PCP était bien sûr UPnP, mais qui était techniquement moins proche de ce qui était souhaité (non routé, peu sécurisé, peu fiable). PMP utilisant les mêmes ports, des dissecteurs de paquets analysent parfois le PCP sous le nom de PMP.
Aujourd'hui, on trouve très peu de mises en œuvre de PCP déployées. Aucun système d'exploitation n'a de client PCP en série. Une solution possible sera peut-être (suggestion de Gunther Ozerito) de faire un relais UPnP <=> PCP comme décrit dans le RFC 6970. Sinon, Wireshark va bientôt avoir un dissecteur PCP (il vient d'être développé et sera livré avec la future version 1.10 ; un autre, sous forme d'un greffon en Lua, est disponible). Attention, Wireshark a aussi un dissecteur pour un autre PCP (Performance Co-Pilot Protocol).
Et j'ai bien envoyé des paquets PCP à ma Freebox, mais je reçois toujours une triste réponse ICMP port 5351 unreachable d'où je déduis qu'elle n'a pas encore de serveur PCP. (Et elle ne diffuse apparemment rien vers le port 5350.)
Au fait, pour les envoyer, j'ai utilisé ce (très grossier) script Scapy, qui est loin de remplir tous les champs mais permet quelques tests :
from scapy.all import * # http://www.secdev.org/projects/scapy/doc/build_dissect.html class PCP(Packet): name = "Port Control Protocol" fields_desc = [ ByteField("Version", 2), BitField("R", 0, 1), # 0 = Request / 1 = Response BitField('Opcode', 1, 7), # MAP is 1, PEER is 2 ShortField("Reserved", 0), IntField("RequestedLifetime", 0), LongField("ClientAddressUpper", 0), LongField("ClientAddressLower", 0) ] p = IP(dst="192.168.2.254")/UDP(sport=0,dport=5351)/PCP(RequestedLifetime=5000, ClientAddressLower=232236033) sr1(p)
Un bon article d'introduction sur PCP est « New Technology Demo: PCP » dans le numéro 7.2 de l'IETF Journal.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : M. Blanchet (Viagenie), A. Sullivan (Dyn, Inc.)
Pour information
Réalisé dans le cadre du groupe de travail IETF precis
Première rédaction de cet article le 14 mars 2013
Dans bien des protocoles, il y a besoin de comparer deux chaînes de caractères, pour voir si elles sont égales. Par exemple, un protocole d'authentification va comparer un identificateur à ceux enregistrés dans sa base, pour voir s'il est présent. Si les chaînes de caractères sont uniquement en US-ASCII, il n'y a guère de problèmes, à part décider si la comparaison est sensible à la casse. Mais si elles sont en Unicode ce qui, en 2013, est la moindre des choses ? Alors, c'est plus compliqué. Dans ce cas, on décide de préparer les chaînes avant la comparaison, pour les ramener à une forme de référence (en ASCII, un exemple simple de préparation serait de tout mettre en minuscules). Beaucoup de protocoles IETF utilisaient pour cette opération le stringprep du RFC 3454, popularisé par son utilisation dans les noms de domaines internationalisés. Mais la mise à jour de ces noms de domaines, en 2010, a abandonné stringprep (cf. RFC 5890). Dans ces conditions, les autres protocoles se retrouvaient privés d'une référence bien pratique. Le groupe de travail PRECIS a été créé pour étudier la mise en place d'un cadre général de préparation des chaînes Unicode pour tous les protocoles. Ce RFC 6885 est son premier RFC et il décrit le problème, sans proposer encore de solution.
C'est que stringprep avait été un grand succès. Voici une liste incomplète des protocoles qui l'utilisent :
stéphane@dns-oarc.net/Théâtre
est légal),Pour gérer plus facilement ce bestiaire, on peut les regrouper en quelques catégories (voir l'étude de Marc Blanchet), d'autant plus que beaucoup utilisent le même profil SASLprep du RFC 4013. L'annexe A de notre RFC liste ces catégories.
On l'a dit, la motivation immédiate pour le travail du groupe PRECIS était la perte de la référence que constituait les IDN, qui utilisent désormais d'autres méthodes. Puisque, de toute façon, il va falloir remettre à plat cette question de la préparation des identificateurs Unicode, c'était l'occasion de faire un bilan (il a commencé à la réunion IETF 77 dans une Bof nommée « Newprep » dont le compte-rendu est en ligne). La section 4 étudie les profils de stringprep existants et leurs limites :
Bref, c'est sur la base de ce cahier des charges informel qu'a été créé le groupe PRECIS avec l'ambition de servir des protocoles très différents (mais qui ne bénéficiaient pas des compétences d'experts en internationalisation), en s'inspirant (sans forcément le copier aveuglément) de l'IDN bis du RFC 5890 et suivants.
La section 5 de ce RFC est le cahier des charges formel. D'abord, sur la question de la comparaison entre chaînes, un rappel du problème. Il y a trois catégories de chaînes, pour ce qui concerne la comparaison :
Par exemple, deux chaînes Unicode identiques pour la deuxième catégorie (même séquence de points de code) peuvent ne pas l'être pour la première (par exemple si une est en UTF-8 et l'autre en UTF-32). Mais il peut exister un algorithme pour les comparer (tout convertir en UTF-8 puis comparer les octets). Le tableau en annexe A indique, pour les protocoles existants, à quelle catégorie ils appartiennent.
Ensuite, les caractères eux-même, un problème que la taille du bestiaire Unicode (plus de 100 000 caractères) rend difficile. Commençons par la casse. IDN v1 faisait une comparaison indépendante de la casse en convertissant tout en minuscules. IDN v2 a décidé de n'accepter que les minuscules, une éventuelle conversion des majuscules étant à faire en dehors du cadre IDN (RFC 5892). Le système défini par PRECIS doit donc gérer plusieurs cas, avec ou sans sensibilité à la casse, avec ou sans préservation de la casse.
Ensuite, la canonicalisation. Comme il existe plusieurs chaînes Unicode dont le rendu peut être identique (exemple classique : U+00C8, d'une part, et U+0045 U+0300, d'autre part, vont tous les deux donner É), Unicode prévoit des algorithmes de canonicalisation qui réduisent les chaînes de caractères à une forme canonique, avant la comparaison. La plupart des profils de stringprep se servent de NFKC. Est-ce le bon choix ? Dans tous les cas ? NFC peut être une meilleure idée (au fait, dans l'exemple ci-dessus, la chaîne deviendra U+00C8 avec NFC et avec NFKC).
Autre question délicate à considérer, les caractères interdits. Par exemple, un protocole peut avoir des caractères spéciaux comme @ ou / qu'il faudra interdire dans les identificateurs. Faut-il définir les caractères interdits (et autoriser donc le reste) ou au contraire les caractères permis (et donc interdire tous les autres) ?
Cette question est partiellement liée à la question de l'homographie. Ce RFC reprend la légende (pourtant bien démontée par UTR36) comme quoi les caractères pourraient avoir un rôle dans le hameçonnage. Mais il reconnait qu'il n'y a pas de solution technique à cette question.
Autre question sur les données, d'où viennent-elles ? Sont-elles typiquement saisies par un utilisateur (et, dans ce cas, il faut probablement lui laisser un grand choix de variantes possibles) ou bien sont-elles générées par un programme ? Derrière cette question se trouve la frontière oh combien mouvante entre ce qui relève de l'interface utilisateur et ce qui relève des protocoles (voir le RFC 5895 et aussi, même s'il n'est pas cité, le RFC 2277).
Après l'entrée, la sortie de ces chaînes de caractères soulève aussi des questions. Si les caractères sortent du monde « machine » et sont imprimés, pour se retrouver sur une carte de visite ou sur les flancs d'un autobus, les problèmes de risque de confusion visuelle seront plus aigus.
Et il y a le fait que certaines chaînes de caractères servent d'entrée au processus suivant, condensation cryptographique ou concaténation, par exemple.
Dernier problème à garder en mémoire, le risque de changements incompatibles lors de la sortie d'une nouvelle version d'Unicode. Idéalement, un caractère, une fois déclaré valide pour un protocole donné, devrait le rester éternellement, assurant ainsi la stabilité des identificateurs construits avec ce caractère. Mais Unicode ne fournit pas cette garantie (au passage, c'est pour cela que stringprep était lié à une version particulière d'Unicode). Un caractère peut changer de catégorie et, si sa validité était déterminée algorithmiquement à partir de sa catégorie, il peut passer de valide à invalide. Le cas s'est déjà produit (cf. RFC 6452).
La section 6 est ensuite le relevé des décisions (unanimes) concernant le travail du groupe PRECIS :
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : B. Carpenter (Univ. of Auckland), S. Jiang (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 8 mars 2013
Ce nouveau RFC sur IPv6 ne spécifie pas un protocole réseau mais rassemble simplement un ensemble de conseils pour les gens qui gèrent des serveurs Internet et qui veulent les rendre accessibles en IPv6. Bien sûr, en 2013, tous les serveurs devraient depuis longtemps être ainsi accessibles. Mais le déploiement d'IPv6 a pris du retard et ce RFC est une des nombreuses tentatives pour tenir la main des retardataires qui hésitent encore à traverser le gué.
Pourquoi faut-il une stratégie de déploiement IPv6 ? Pourquoi ne pas tout simplement se dire « Au diable les mines ! En avant toute ! » ? Parce que l'administrateur typique d'un serveur Internet pense à ses utilisateurs et il veut que l'introduction d'IPv6 ne rende pas les choses moins bonnes qu'en IPv4. Certaines techniques de transition et/ou de coexistence entre IPv4 et IPv6 ayant eu des effets négatifs, il est prudent de réfléchir et de ne pas se lancer aveuglément.
Comme indiqué plus haut, ce RFC ne concerne pas le pur utilisateur qui veut se connecter en IPv6, mais le gérant de serveurs, qui est un professionnel de l'hébergement, ou simplement une organisation qui gère ses propres serveurs (serveurs Web ou autres). Il n'est pas écrit pour l'expert IPv6 (qui n'apprendra rien de nouveau) mais pour l'administrateur système/réseaux de l'hébergeur de serveurs.
La stratégie recommandée par le RFC est celle dite de la « double pile » (RFC 6180), qui consiste à avoir à la fois IPv4 et IPv6 sur les serveurs. Comme on ne va pas déployer IPv6 instantanément partout, elle se subdivise en deux approches : de l'extérieur vers l'intérieur (on rend les serveurs externes accessibles en IPv6, peut-être via un relais comme décrit en section 7, puis on migre progressivement l'infrastructure interne) ou bien de l'intérieur vers l'extérieur (on passe l'infrastructure, les serveurs de base de données, les serveurs LDAP, etc, en IPv6, avant de petit à petit ouvrir IPv6 à l'extérieur). La première approche, de l'extérieur vers l'intérieur, a l'avantage qu'un bénéfice visible pour les utilisateurs est immédiat. Elle marche même si certains services internes sont coincés en IPv4 (par exemple une vieille application tournant sur un vieux système, indispensable à votre activité mais qu'on ne peut pas mettre à jour). Certaines organisations se vantent donc d'être accessibles en IPv6 alors qu'à l'intérieur, le déploiement du nouveau protocole est loin d'être achevé.
La deuxième approche, de l'intérieur vers l'extérieur, est surtout intéressante pour les organisations de petite taille (qui contrôlent tous les systèmes internes) ou récentes (qui n'ont plus d'AS/400 en production, et encore puisque même celui-ci a IPv6). Avec cette approche, l'activation d'IPv6 sur les serveurs externes sera simple, tout sera en place avant.
Le fournisseur de services doit aussi se rappeler qu'il ne contrôle pas les clients. Certains resteront en IPv4 pur pendant longtemps, d'autres seront double-pile et on verra sans doute apparaître bientôt des clients purement IPv6. Certains clients (les mobiles, par exemple) passeront même d'IPv4 à IPv6 au cours d'une seule visite sur le site Web.
Bref, le déploiement d'IPv6 nécessitera quelques études préalables, en vérifiant les capacités du logiciel déployé (cf. RFC 8504).
Maintenant, en route vers le déploiement. Première étape suggérée par le RFC, la formation (section 3). Aujourd'hui, rares sont les formations initiales qui mentionnent IPv6 (en France, la situation dans les IUT semble particulièrement mauvaise). C'est donc souvent dans l'entreprise qu'il faudra former les employés aux différences entre IPv4 et IPv6. Il faut surtout éviter le syndrome de l'expert IPv6 isolé. En 2013, tout professionnel IP doit connaître IPv6 aussi bien qu'IPv4. C'est donc la totalité du personnel informaticien qui va devoir progresser. Le RFC dit « everybody who knows about IPv4 needs to know about IPv6, from network architect to help desk responder ».
Le but est d'éviter des résultats ridicules comme ce réseau où, lors du déploiement d'IPv6, les adresses comportant les chiffres hexadécimaux entre A et F étaient soigneusement évitées, de peur de créer de la confusion chez les techniciens ! Évidemment, si on a des techniciens assez arriérés pour ne pas savoir gérer de l'hexadécimal, on a un problème... Autre anecdote embarrassante, cet employé du help desk qui parlait à un client de « one Pv6 » car il avait cru voir un 1 dans IPv6... L'un des buts de la formation est d'éviter ce genre de bavure.
L'approche du RFC est d'éviter de traiter IPv6 à part, par exemple d'avoir une procédure de remontée des problèmes différente pour IPv6, menant vers l'unique gourou IPv6. Plutôt qu'un « service IPv6 » spécialisé, le RFC recommande qu'IPv6 soit simplement traité comme IPv4.
Dernier point délicat sur la formation, le meilleur moment où la faire. Trop tôt, et elle sera oubliée lorsque le déploiement effectif commencera. Il faut donc essayer de la synchroniser avec le déploiement.
Ensuite, il faut obtenir une connectivité IPv6 (section 4). Elle peut être native (directement sur la couche 2, comme en IPv4) ou via un tunnel géré. Historiquement, bien des expérimentations IPv6 ont été faites en se connectant par un tunnel non géré et les résultats (en performances et en fiabilité) ont découragé beaucoup de gens de continuer avec IPv6. Le RFC recommande très fortement de ne pas perdre de temps avec les tunnels et de faire du natif. Toutefois, si on se connecte via un tunnel, cela doit être un tunnel géré (le RFC ne donne pas de noms mais c'est, par exemple, un service qu'Hurricane Electric offre très bien). Les solutions avec des tunnels automatiques, non gérés, comme 6to4 (que le RFC ne cite pas) sont à fuir.
Un tunnel géré a quand même des défauts : les performances seront inférieures, et la MTU réduite va mener à des problèmes pénibles à déboguer. Bref, le fournisseur de services ne devrait pas utiliser autre chose qu'une connexion native avant d'offrir un accès de production à ses services.
Notez que cela ne concerne que le fournisseur : on ne contrôle pas les clients et il faut donc se préparer à ce que certains utilisent des bricolages non fiables comme Teredo (cf. section 9).
Étape suivante (dans le RFC ; dans le déploiement, on peut paralléliser ces tâches), l'infrastructure IPv6 (section 5). D'abord, l'attribution des adresses. Comme en IPv4, on peut utiliser des adresses PI ou PA, selon ses besoins et selon la politique du RIR local. Si on utilise du PA, il faut se préparer à de futures renumérotations et, pour cela, bien relire le RFC 4192. Naturellement, si le fournisseur de service a hébergé ses services dans le cloud, il n'a pas le choix, il devra suivre la politique de l'hébergeur.
Pour gérer les adresses IPv6 locales, on peut utiliser un logiciel spécialisé, un IPAM. Pour distribuer les adresses aux machines, on peut le faire manuellement ou via un programme qui automatise partiellement la gestion du parc, comme Puppet ou Chef. Mais on peut aussi les distribuer par DHCP (RFC 8415). Le RFC suggère DHCP, car il facilitera une éventuelle renumérotation.
Plus exotique est la possibilité de ne pas avoir d'adresses statiques pour les serveurs mais de compter uniquement sur l'auto-configuration sans état d'IPv6 (SLAAC, RFC 4862), combinée avec des mises à jour dynamiques du DNS (RFC 3007). Dans ce cas, ce sont les noms des serveurs qui sont statiques, pas leurs adresses IP. Le RFC note bien que c'est une possibilité théorique mais que personne n'a encore essayé cela pour un grand réseau de production.
Pour la topologie du réseau (physique, via les câbles, ou logique, via les VLAN), le RFC recommande d'avoir la même topologie en IPv4 et IPv6. Ce n'est pas obligatoire mais cela facilitera grandement le débogage lorsqu'il y aura un problème.
Une fois les adresses attribuées, le routage : tous les protocoles de routage ont la capacité de router IPv6, même RIP (RFC 2080). La méthode la plus courante aujourd'hui est de déployer deux routages parallèles et indépendants, un pour IPv4 et un pour IPv6. Toutefois, deux protocoles de routage, IS-IS (RFC 5308) et OSPF (RFC 5838), ont la capacité de gérer les deux versions de manière intégrée, ce qui peut simplifier la gestion du réseau. (Pour OSPF, c'est encore très peu déployé, la plupart des sites OSPF font tourner deux routages parallèles.) Comme les concepts de routage sont les mêmes en IPv6 et en IPv4, il ne devrait pas y avoir trop de problèmes pour l'équipe qui s'en occupe.
Parmi les points qui risquent d'être différents en IPv6 figurera le cas où un site a plusieurs préfixes PA (un pour chaque fournisseur de connectivité). Il faudra alors soigner le routage pour éviter de faire sortir via le fournisseur A un paquet dont l'adresse source est prise dans le préfixe du fournisseur B : si A met en œuvre les filtrages recommandés par les RFC 2827 et RFC 3704, le paquet sera jeté.
C'est seulement lorsque tout est déployé et testé, au niveau
adressage et routage, qu'on pourra envisager d'annoncer les adresses
IPv6 des serveurs dans le DNS. Ne faites pas
l'erreur d'un gros fournisseur de raccourcisseur
d'URL qui avait fait cette annonce alors que son serveur
ne marchait pas en IPv6 ! Ou comme l'avait fait Yahoo qui avait mis le AAAA sans configurer Apache.Testez donc d'abord (par exemple avec un nom
spécifique comme ipv6.example.com
, comme expliqué
en section 9). Ensuite, mettez les
enregistrements AAAA dans le DNS. Dès qu'ils
seront publiés, le trafic arrivera.
Un équipement souvent placé devant les serveurs est le répartiteur de charge (section 6). Comme tous les intermédiaires, ils sont une source importante de problèmes. Après un long retard, la plupart gèrent aujourd'hui IPv6, mais il est important d'insister auprès des fournisseurs de tels équipements pour qu'IPv6 ait le même niveau de performance qu'IPv4.
Le logiciel sur les serveurs, maintenant (section 8). Dans les systèmes d'exploitation, il n'y a guère de problème, tout fonctionne en IPv6 depuis longtemps. C'est le cas des noyaux mais aussi des « grands » logiciels serveurs comme Apache, NSD ou Postfix. Mais les applications spécifiques, c'est une autre histoire, certaines ne sont pas forcément prêtes. Pour les applications client, le fait d'utiliser des noms de domaines au lieu des adresses IP aide beaucoup. Pour les serveurs, il peut y avoir des surprises, par exemple au moment de journaliser la requête, lorqu'on voudra enregistrer l'adresse IP du client. Des tests soigneux seront nécessaires.
Beaucoup de fournisseurs de service géo-localisent leurs utilisateurs. Dans ce cas, les bases de géo-localisation typiques comme GeoIP n'étant pas forcément prêtes pour IPv6, il y aura des problèmes, à moins de passer à une méthode de géolocalisation plus fiable que celle fondée sur l'adresse IP, par exemple avec la technique HELD du RFC 5985.
Lorsque le client change d'adresse IP (ce qui arrive avec les mobiles), il peut même changer de version d'IP. Si les cookies distribués sont liés à une adresse IP, il faudra en tenir compte.
On l'a vu plus haut, le fournisseur de service ne contrôle pas ses clients. Il peut tout à fait arriver que ceux-ci ont choisi des techniques de transition/coexistence entre IPv4 et IPv6 et que celles-ci soient peu fiables (par exemple Teredo). Avec l'approche recommandée dans ce RFC, la double pile, il n'y aura normalement pas de requêtes venant de NAT64 (RFC 6146). Mais on peut imaginer d'autres problèmes, y compris des doubles traductions, de v6 en v4 puis encore en v6, et que le serveur ne peut pas détecter.
Reste le cas des tunnels automatiques comme le 6to4 du RFC 3068. Le RFC 6343 donne plein de bons conseils pour limiter les dégâts. Les deux points importants, du côté du serveur, sont :
Mais l'hébergeur a un pouvoir limité : il peut vérifier que les paquets ICMP passent bien sur son réseau mais il ne peut rien garantir quant aux autres réseaux traversés. C'est pour cela que 6to4 est désormais abandonné (RFC 7526).
Certains fournisseurs de service ont donc choisi une approche plus violente en configurant leurs serveurs DNS pour ne pas envoyer les enregistrements AAAA au résolveur si celui-ci est dans un réseau dont on sait qu'il a des problèmes, notamment de PMTUd. Encore plus pessimiste, l'approche inverse où on n'envoie les AAAA qu'aux réseaux dont on sait qu'ils ont une connectivité IPv6 native correcte (Google avait utilisé ce mécanisme au début). Cette solution, décrite dans le RFC 6589, est coûteuse en temps (il faut gérer la liste noire ou la liste blanche) et pas tenable sur le long terme.
Malheureusement, les pouvoirs du fournisseur de service s'arrêtent là. Il ne contrôle pas la chaîne complète jusqu'au client et ne peut donc pas garantir à celui-ci un vécu parfait. La voie la plus prometteuse semble être le déploiement progressif du mécanisme happy eyeballs (globes oculaires heureux) du RFC 6555.
Et si le fournisseur de service utilise des CDN (section 10) ? Cela peut marcher, avec IPv6 comme avec IPv4 si le fournisseur du CDN suit, comme celui du serveur principal, les recommandations de ce RFC. À noter que, le CDN étant géré par une organisation différente de celle qui gère le serveur original, on aura parfois, si le CDN est plus avancé, un contenu partiellement accessible en IPv6 alors que le serveur original n'a pas IPv6. Sinon, parmi les pièges spécifiques aux CDN, la synchronisation. Le contenu à servir est distribué à tous les nœuds du CDN via l'Internet et ce processus n'est pas instantané. Comme le contenu n'est pas forcément servi en IPv4 et en IPv6 par les mêmes machines, un visiteur peut avoir, pendant les périodes où la synchronisation est en cours, un contenu différent selon qu'il y accède en v4 ou en v6.
La section 12 rassemble ensuite une liste hétérogène de problèmes potentiels supplémentaires. Par exemple, comme vu plus haut dans le cas du CDN, un service moderne comprend typiquement plusieurs éléments, parfois hébergés à des endroits différents (pensez à une page Web contenant du JavaScript et du Flash stockés sur les serveurs de Google). Dans ce cas, le service peut être partiellement accessible en IPv6 sans même que son gérant ne s'en rende compte. Si le visiteur a des problèmes de connectivité IPv6, les équipes du fournisseur de service risquent de ne pas comprendre tout de suite ce qui se passe en cas d'« IPv6 involontaire ».
C'est donc l'occasion de rappeler (section 13) que le déploiement d'IPv6 n'est pas juste un coup sans lendemain, qu'on pourrait sous-traiter, en « mode projet » : au contraire, il faut assurer la maintenance et le fonctionnement opérationnel dans le futur. Cela n'a rien d'extraordinaire et ne nécessite pas de compétences surhumaines. Il existe des réseaux et des sites en double pile depuis de nombreuses années. Mais il faut le faire.
Un exemple parmi d'autres : il est important d'assurer la supervision aussi bien en IPv6 qu'en IPv4. Cela concerne bien sûr les réseaux (pinguer les adresses IPv6 comme les adresses IPv4) mais aussi les services (si un service a été accidentellement lancé sans écoute en IPv6, il faut que cela soit détecté). À noter que, avec la plupart (peut-être tous) les logiciels de supervision existants, tester des machines ou des services qui écoutent sur plusieurs adresses IP (que celles-ci soient une adresse v4 et une adresse v6 ou bien plusieurs adresses v4) est souvent un peu pénible et pas vraiment prévu. Par exemple, avec Icinga, il faut mettre explicitement deux tests, un en IPv4 et un en IPv6, le programme de test ne testant qu'une seule des adresses du service. Si on ne fait pas attention, on risque donc de se rassurer en voyant l'écran vert du logiciel de supervision, sans avoir perçu que le service ne marchait plus en IPv6 (ou en v4, selon le cas).
Et la sécurité (section 14) ? Elle est évidemment aussi importante en IPv6 qu'en IPv4 mais on manque encore d'expérience. En pratique, début 2013, très peu d'attaques sont lancées en IPv6 (elles bénéficient par contre d'une exposition médiatique démesurée, justement parce qu'elles sont rares). Cela ne durera pas éternellement et les responsables réseaux et systèmes doivent donc se préoccuper de ces risques. En gros, comme IPv6 est uniquement une nouvelle version d'IPv4, fondée sur les mêmes concepts, la quasi-totalité des risques présents en IPv4 (de l'attaque par déni de service aux tentatives de se connecter au serveur SSH) existent en IPv6.
Aujourd'hui, il est difficile de répondre simplement à une question comme « est-ce plus dangereux en IPv6 ? » Comme on l'a vu, il y a beaucoup moins d'attaques. Mais les défenses sont également moins bonnes : il est fréquent qu'une organisation soit protégé par un pare-feu en IPv4 mais que tout le trafic IPv6 passe librement. En fait, aujourd'hui, aussi bien les attaquants que les défenseurs ne prennent guère en compte IPv6. On a donc un équilibre... instable. Sur ce sujet de la sécurité d'IPv6, on peut consulter mon exposé à l'ESGI.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : S. Jiang, B. Liu (Huawei Technologies), B. Carpenter (University of Auckland)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6renum
Première rédaction de cet article le 28 février 2013
Ce RFC ne normalise pas un protocole mais a pour ambition de servir de guide lors de la rénumérotation d'un réseau IPv6. Pourquoi renuméroter ? Et comment ? Les administrateurs réseaux ont tout intérêt à le lire, et de préférence avant la renumérotation et même avant la mise en production du réseau, pour ne pas mettre dans l'architecture de celui-ci des éléments qui gêneront les renumérotations futures.
C'est le deuxième RFC du groupe de travail 6renum qui planche sur les scénarios de renumérotation de réseaux IPv6, ainsi que sur les moyens de rendre ces renumérotations plus faciles. Ce RFC particulier se focalise sur le cas d'une organisation de taille significative : ni un SOHO, ni un opérateur réseau, un client de taille moyenne qui a IPv6 sur son réseau local, une ou plusieurs connexions à l'Internet et au moins un employé chargé d'administrer le réseau (cf. RFC 4057).
La seule façon d'être sûr de ne jamais renuméroter serait de n'utiliser que des adresses PI. Mais, comme le note le RFC 4116, cela aurait des conséquences quantitatives néfastes pour BGP. Donc, on part du principe que l'organisation aura à renuméroter un jour. Lisons les prérequis (RFC 4192 et RFC 5887) et allons-y.
Les machines reçoivent des adresses IP dynamiques (si elles ont des adresses statiques, le problème est plus compliqué, et c'est le domaine du RFC 6866). Pour cela, on utilise DHCP ou les annonces des routeurs (SLAAC).
Mais pourquoi renumérote-t-on ? Pourquoi s'embêter dans cette opération au lieu de se contenter de garder ses adresses actuelles ? La section 3 décrit plusieurs scénarios déclencheurs. Certains peuvent être externes, d'autres internes. Parmi les externes :
Et les causes internes ?
La section 4 décrit ensuite les méthodes existantes pour faire ces renumérotations avec le moins de douleur possible. Parmi les mécanismes qui peuvent aider, il ne faut pas oublier la délégation de préfixe IP (RFC 8415 et RFC 6603), qui permet à un routeur d'informer d'autres routeurs sur les préfixes qu'ils vont devoir gérer (annoncer avec des RA, router, etc). Ainsi, on n'aura pas à reconfigurer tous les routeurs. Autre mécanisme important, l'utilisation de noms de domaine le plus souvent possible, car ils sont plus stables que les adresses IP. Par exemple, pour IPsec, nul besoin de configurer en utilisant des adresses, des noms peuvent être utilisés (RFC 5996), simplifiant ainsi beaucoup les futures renumérotations. (Pour les réseaux sans serveur DNS, le RFC rappelle l'existence de Multicast DNS, RFC 6762.) De même, les applications devraient aussi utiliser des noms et pas des adresses. Configurer une application avec une adresse IP, c'est placer une bombe qui explosera lors de la prochaine renumérotation du réseau.
Mais les adresses IP peuvent se cacher en d'autres endroits, comme dans les ACL des pare-feux. Au minimum, ces configurations devraient être paramétrisées : on n'utilise l'adresse IP qu'une fois, pour lui donner un identificateur, puis on se sert de cet identificateur partout (des outils comme m4 ou cpp peuvent être utilisés pour cela). C'est le B A BA de l'administration réseaux, mais ce n'est pas toujours fait.
Pendant qu'on parle d'adresses IP qui traînent, il ne faut évidemment pas mettre dans ses configurations des adresses IP d'autres sites. Sinon, lorsqu'ils renuméroteront, ils ne penseront sans doute pas à vous prévenir...
Un truc plus exotique est l'utilisation d'ULA, des adresses IP locales (RFC 4193). L'idée est de tout numéroter avec les ULA et d'effectuer une traduction d'adresses ou un relayage dans les routeurs de sortie. Ainsi, la renumérotation n'impacte que ces routeurs. Les ULA sont donc une sorte de substitut aux adresses PI.
Continuons avec les techniques utilisées sur le réseau local :
comment les adresses IP arrivent-elles aux machines terminales ? En
IPv6, il y a deux solutions, SLAAC (RFC 4862) et DHCP (RFC 8415). Ce RFC ne tranche pas entre les deux : du
point de vue de la renumérotation, ils ont à peu près les mêmes
possibilités. (DHCP a une option, RECONFIGURE
qui
permet, si le client DHCP la gère, de faire des renumérotations
imprévues.)
Et le DNS ? Un petit site ne gère pas forcément ses propres serveurs DNS. Leur reconfiguration pourra nécessiter une coordination avec l'hébergeur DNS. Ce que le RFC recommande, c'est de ne pas le faire manuellement. Le fichier de zone édité avec vi et contenant les adresses IP de toutes les machines de l'organisation, c'est un mécanisme archaïque, et, en 2013, on doit normalement mieux faire : soit les données DNS sont dérivées automatiquement d'une base de données de machines (cela n'a pas besoin d'être une usine à gaz, cela peut être un simple script Perl/Python/Ruby), soit les machines (ou les serveurs DHCP) mettent à jour le DNS automatiquement avec les mises à jour dynamiques (RFC 3007).
Une fois qu'on a fait le tour de son réseau et des techniques utilisées, il faut se préparer, et planifier soigneusement. D'abord, diminuer la durée de vie des annonces d'adresses pour que la transition soit la plus courte possible et que les vieilles adresses ne trainent pas dans les caches. Avec l'autoconfiguration sans état (SLAAC), on ne peut pas réduire la durée de vie des annonces à moins de deux heures, il faudra faire avec. D'autre part, cette diminution va évidemment augmenter le trafic et il ne faut donc pas la faire des semaines à l'avance. Une telle durée de vie est stockée dans les enregistrements DNS (qu'il faut donc ajuster), mais aussi dans les annonces indiquant le résolveur DNS à utiliser (RFC 8106 pour SLAAC et RFC 3646 pour DHCP, où il faut réduire la durée du bail, on ne peut pas réduire seulement la durée de vie de l'option DNS). À noter que les applications qui maintiennent des connexions sur de longues périodes (SSH, par exemple), n'ont pas de mécanisme propre pour gérer la renumérotation. Il faudra faire une déconnexion/reconnexion.
Bref, anticiper et planifier sont des nécessités.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : A. B. Roach (Mozilla)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sipcore
Première rédaction de cet article le 2 mars 2013
Cet ultra-court RFC crée officiellement un
registre pour stocker les valeurs possibles du champ
Priority
du protocole
SIP.
Le RFC 3261, qui normalise le système de
téléphonie sur IP SIP
incluait un champ pour indiquer la priorité d'une communication
(section 20.26 du RFC 3261). Quatre valeurs
possibles étaient définies, non-urgent
,
normal
, urgent
et
emergency
, tout en précisant que d'autres
pourraient l'être mais sans indiquer comment. Ce RFC 6878
comble ce manque.
Il y donc désormais :
Date de publication du RFC : Février 2013
Auteur(s) du RFC : S. Kamei (NTT Communications), T. Momose (Cisco), T. Inoue, T. Nishitani (NTT Communications)
Pour information
Première rédaction de cet article le 23 février 2013
Ce RFC décrit une expérience faite il y a quelques années au Japon pour tester l'efficacité des mécanismes de sélection de pairs dans un réseau pair à pair. Elle montre que cette sélection peut améliorer l'efficacité des protocoles pair à pair, une leçon utile pour le projet ALTO (Application-Layer Traffic Optimization, RFC 5693).
Le réseau pair à pair typique relie des machines, les pairs, qui peuvent être très éloignées les unes des autres. Les relations des machines entre elles ne correspondent pas forcément aux réalités de l'interconnexion. En bref, un pair risque de télécharger des données depuis un pair lointain alors qu'il en existait un plus proche. Des tas de propositions ont été faites pour un mécanisme de sélection des pairs, menant théoriquement à une plus grande efficacité. De 2007 à 2008, au Japon, le P2P Network Experiment Council a réalisé une série de mesures pour comparer théorie et pratique. Une intense répression sous les ordres de l'industrie du divertissement, avec plusieurs arrestations, a réduit l'usage du pair à pair dans ce pays depuis, sans toutefois réussir à le réduire à zéro.
Le Japon est souvent un cas à part et, à l'époque en question, le système de pair à pair le plus populaire n'était pas Bit Torrent mais Winny ou Share. Leur trafic total combiné était estimé à 40 % du trafic total. Pour l'opérateur de réseaux, le pair à pair (P2P) a donc un impact important et cela les motive pour chercher des économies, justement ce que promettent les techniques de sélection du pair. Parmi les autres solutions envisagées par les FAI : faire un effort pour placer le contenu très demandé plus près des utilisateurs (les CDN, par exemple), augmenter les prix, ou limiter autoritairement le trafic.
L'approche choisie par le P2P Network Experiment Council, organisme créé par le gouvernement japonais en 2006, était de tester les solutions de sélection du pair. Pour cela, le conseil a déployé un réseau de serveurs indicatifs (les oracles, selon la terminologie généralement utilisée chez les chercheurs de ce domaine), indépendants d'un système de P2P particulier et donnant des indications sur le meilleur pair.
La section 3 décrit plus en détail ce « conseil pour des expériences P2P ». Créé par le ministère des télécommunications, à la suite de débats sur des sujets comme la neutralité du réseau, il est documenté (en japonais) dans le rapport « Disclosure of the Report `Working Group on P2P Networks' » et placé sous l'égide d'une fondation (oui, encore un texte dans la langue de Naoki Urasawa). Outre les tests qui font l'objet de ce RFC, le conseil a une activité de promotion des bonnes pratiques en matière de P2P.
La section 4 de notre RFC décrit les expériences menées : au début, il n'y avait aucun doute sur les économies en matière de serveurs, lorsqu'on migre vers le pair à pair. Ainsi, l'entreprise Utagoe annonçait une réduction de 90 % de son trafic sortant en migrant vers leur système UGLive. Et TV Bank Corp a vu 80 à 96 % de gain avec BB Broadcast. Mais ce sont des gains pour les fournisseurs de contenu. Et pour les opérateurs réseau ? Il y a eu de études au Japon sur le trafic total (comme celle de Cho, Fukuda, Esaki et Kato). Mais étudier le comportement des applications réellement installées sur les utilisateurs demande des mesures fort intrusives, par exemple avec du DPI.
Le choix du conseil avait donc été d'installer des faux utilisateurs : des PC munis de logiciels P2P modifiés (pour demander à l'oracle) ont été placés dans les réseaux des FAI. On peut ainsi faire varier librement et facilement tous les paramètres de mesure (et, bien que le RFC ne le dise pas, cela évite tout problème lié à la vie privée). Le faux utilisateur est donc un PC avec CentOS, VMware et un Windows par dessus. Le système hôte CentOS peut ainsi observer tout le trafic sans déranger. 60 machines ont été installées chez 40 FAI.
La section 5 décrit l'oracle (hint server), le serveur qui va distribuer les indications. C'est l'équivalent du « serveur ALTO » dans le protocole ALTO (RFC 6708). Lorsqu'un pair démarre, il indique à l'oracle son adresse IP et des informations comme les caractéristiques de la liaison Internet utilisée. L'oracle, en utilisant des informations sur la topologie du réseau informations fournies par le FAI et une table de routage obtenue via BGP (l'oracle inclut un Quagga), peut alors envoyer au pair une table des meilleurs pairs possibles. Dans ce cas idéal, l'optimisation réalisée est presque parfaite. En pratique, l'oracle n'a pas forcément toute l'information nécessaire : le FAI, l'estimant confidentielle, a pu ne pas donner une information complète.
Pour prendre sa décision, l'oracle s'appuie sur :
Voici un exemple simplifié d'une requête d'un pair à l'oracle, et de la réponse de l'oracle. Le tout est transporté sur HTTP et les données sont encodées en couples {type, valeur} :
POST /PeerSelection HTTP/1.1 Host: OracleServerName User-Agent: ClientName Content-Type: text/plain; charset=utf-8 v=Version number ip=IP address of physical interface port=1978 nat=unknown ub=256 db=15000
Vous avez compris que ub
et
db
sont les capacités réseau montant et
descendantes, et que nat
indique (si le pair le
sait), si le pair est coincé ou non derrière un routeur
NAT, qui rend difficile les connexions
entrantes. Et voici la réponse :
HTTP/1.1 200 OK Content-Type: text/plain; charset=utf-8 v=Version number ttl=ttl client_ip=192.0.2.67 numpeers=11 ...
La section 6 résume les résultats de l'expérience. Soit un pair situé à Tokyo. Sans l'oracle, de 22 à 29 % des pairs sélectionnés étaient déjà dans le même FAI, et de 19 à 23 % dans le même district (il est important de connaître ces valeurs car, si un contenu est peu populaire et ne se trouve pas du tout dans le même FAI que l'utilisateur, aucun oracle au monde ne pourra indiquer un pair proche). Avec l'oracle, la distance moyenne avec le pair a été réduite de 10 %. (Opinion personnelle : le RFC est beaucoup plus détaillé sur la configuration de l'expérience que sur les résultats obtenus, très brefs.)
Les auteurs estiment que ces résultats montrent l'intérêt d'un système de sélection du pair. Quelles conclusions pour le groupe de travail ALTO, qui standardise une technologie analogue ? Que l'information publiquement accessible via BGP est une source utile pour optimiser le trafic entre FAI. Que, pour le trafic interne au FAI, il faut une information détaillée de la topologie du réseau de ce FAI, information qui peut être difficile à obtenir. Que les demandes futures seront peut-être d'avoir une sélection plus précise, nécessitant peut-être une structure hiérarchique dans ALTO (des serveurs ALTO utilisant eux-même d'autres serveurs ALTO). Et qu'il serait bon que l'oracle soit un peu plus bavard sur les mécanismes qu'il a utilisé pour trier les pairs possibles, afin que le pair puisse combiner le jugement de l'oracle avec ses propres critères.
Sur l'évaluation des mécanismes de sélection du pair, voir aussi le RFC 6821.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : B. Carpenter (Univ. of Auckland), S. Cheshire (Apple), R. Hinden (Check Point)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 23 février 2013
Ce court RFC normalise la façon d'indiquer la zone dans un URI contenant une adresse IPv6 littérale.
Les zones sont définies et expliquées dans le RFC 4007. En gros, une adresse IPv6
n'est pas forcément globale, elle peut avoir une signification limitée
à une seule zone, une zone étant un ensemble de sous-réseaux contigus,
souvent composé d'un seul lien Ethernet. Les adresses locales au lien,
par exemple, celles qui sont dans le préfixe
fe80::/10
, sont dans ce cas, le lien qui les
relie forme une zone. Pour indiquer cette zone, la convention de
mettre un %, puis l'identificateur de la zone,
après l'adresse, est fréquemment utilisée. Mais elle n'était pas
normalisée, dans le cas où l'adresse apparaissait dans un
URI. Ce RFC répare ce manque.
Car il peut y avoir des adresses IP littérales dans un URI (section
3.2.2 du RFC 3986). Par exemple,
http://[2001:db8:1::23]/
est un URI valide. (Et
je viens de tester avec mon Firefox qui l'a
accepté sans problèmes.) Mais, si cette adresse est locale à une
zone ? D'habitude, on utilise la convention du
% (décrite en section 11 du RFC 4007). Ici, sur une machine
Linux récente (cela ne marchait pas autrefois, il fallait utiliser l'option -I
) :
% ping6 -c3 fe80::21e:8cff:fe76:29b6%eth0 PING fe80::21e:8cff:fe76:29b6%eth0(fe80::21e:8cff:fe76:29b6) 56 data bytes 64 bytes from fe80::21e:8cff:fe76:29b6: icmp_seq=1 ttl=64 time=8.36 ms 64 bytes from fe80::21e:8cff:fe76:29b6: icmp_seq=2 ttl=64 time=4.97 ms 64 bytes from fe80::21e:8cff:fe76:29b6: icmp_seq=3 ttl=64 time=4.84 ms --- fe80::21e:8cff:fe76:29b6%eth0 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 4.847/6.060/8.363/1.631 ms
On teste la machine fe80:1::23
reliée au réseau
identifié par eth0
(dans le cas de Linux, c'est
le nom d'une interface réseau mais d'autres systèmes d'exploitation
peuvent utiliser une syntaxe différente, par exemple identifier les
zones par un simple numéro). Cette possibilité de désigner une zone
spécifique est essentielle pour les activités de débogage
(M. Toutlemonde n'a sans doute jamais besoin d'URI incluant des
adresses IP). Mais si on
utilise un navigateur Web pour cette activité,
comment mettre la zone ? Le RFC 4007 était muet à ce
sujet. Certains navigateurs (par exemple certaines versions anciennes de
Firefox) acceptaient des adresses suivies d'un
pour-cent (alors que ce caractère est spécial dans les URI et que ces
navigateurs violaient donc le RFC 3986).
Encore mieux, comme le RFC 4007 ne précise pas quels sont les caractères autorisés dans un identificateur de zone, on pourrait voir des zones avec un nom invalide dans un URI (comme / ou #).
La syntaxe standard normalisée par notre RFC est donc :
%25
, ce qui était déjà la méthode déployée par
Internet Explorer),
Pour faciliter la vie de l'administrateur réseaux, notre RFC recommande que les navigateurs
acceptent un URI incluant un % tout nu, s'il est suivi d'au moins deux
caractères qui ne peuvent pas être des chiffres hexadécimaux. Cela permet de
copier-coller une adresse comme
fe80::a%en1
dans le navigateur et que cela
marche. (Par contre, fe80::a%ee1
ne serait pas
accepté car E peut être un chiffre hexadécimal et il y aurait une
ambiguité entre %ee
et î, qui est encodé
ainsi en notation pour-cent.) Cette opération de copier/coller sera
sans doute le principal usage de ces URI comportant une adresse IPv6
et une zone : on ne voit pas bien dans quels cas
ils se retrouveraient dans une page HTML, sauf
peut-être produite automatiquement par des systèmes d'administration
de réseaux (l'interface Web d'un routeur, par
exemple).
Donc, désormais,
http://[fe80::dead:beef%25en1]
ou
http://[fe80::1:2%25Ethernet%230]
sont des URI
légaux (dans le deuxième, le nom de la zone était
Ethernet/0
). Essayez-les sur votre navigateur !
Comme ces identificateurs de zone n'ont de signification que pour une machine donnée, les relais HTTP, par exemple, doivent les retirer des URI.
Voilà, c'est tout, les amateurs d'alternatives peuvent lire l'annexe A, consacrée aux raisons du choix qui a été fait. Il a l'avantage de ne pas changer le format des URI et les inconvénients qu'il n'est pas très joli, et que le copier/coller d'une console vers un navigateur ne marche pas toujours. Les autres possibilités considérées (les discussions ont été chaudes et longues) étaient :
http://[fe80::a-ee1]
(au passage, pourquoi pas un
tiret bas ? parce que les navigateurs
soulignent souvent automatiquement les URI, rendant le trait
invisible). Mais une telle réforme du RFC 4007 aurait
nécessité de changer tous les outils IPv6 et toutes les documentations.IPvFuture
de la
section 3.2.2 du RFC 3986 pour écrire, par
exemple http://[v6.fe80::a-en1]
. Mais cela ne
permettait pas le copier/coller. (Et j'ajoute qu'aucun navigateur ne
gère cette possibilité IPvFuture
.)Date de publication du RFC : Février 2013
Auteur(s) du RFC : G. Salgueiro (Cisco), V. Gurbani (Bell Labs, Alcatel-Lucent), A. B. Roach (Tekelec)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sipclf
Première rédaction de cet article le 15 février 2013
La question d'un format standard et commun pour la journalisation des événements SIP est exposée et discutée dans le RFC 6872. Ce RFC 6873, lui, spécifie un format standard conforme aux exigences et au modèle de données du RFC 6872. Techniquement, sa principale originalité est d'être un format texte... indexé. Il a donc les avantages des formats textes (lisible sans outil particulier, utilisable avec des outils génériques comme grep ou awk) tout en gardant de bonnes performances si on développe des outils qui lisent ces index.
Le projet d'un format standard pour les journaux de SIP s'appuie évidemment sur le grand succès du CLF des serveurs HTTP. Ce format CLF a facilité la vie de tous les administrateurs système, et a permis le développement de plein d'outils de statistiques et d'analyse. Il a toutefois quelques défauts, le principal étant de performance. Si on cherche un champ de taille variable, comme le nom de la ressource demandée, il faut parcourir chaque ligne jusqu'à ce champ. Or, en SIP, les lignes peuvent être longues (SIP est plus complexe que HTTP et il y a plein de choses à journaliser), d'où le souhait d'un format où on puisse sauter facilement à un champ donné. Les formats binaires permettent cela, mais au prix de la souplesse et de la facilité : il faut en effet des outils spécialisés pour tout accès au journal. Le nouveau format décrit par ce RFC va essayer de vous donner le beurre (le format texte lisible et facile à traiter) et l'argent du beurre (l'indexation, pour sauter directement aux informations intéressantes). Ce format « ASCII indexé » est une innovation : peu de programmes utilisent cette technique. En raison de sa nouveauté dans le monde IETF, ce choix a fait l'objet de chaudes discussions dans le groupe de travail.
La section 4 du RFC décrit ce format : chaque événement est
journalisé sous forme d'un enregistrement qui compte
deux lignes. La première, qui commence toujours
par une lettre, est un ensemble de métadonnées et de pointeurs vers
les champs principaux. Tous sont de taille fixe et donc d'accès direct rapide. La seconde, qui commence toujours par un
chiffre, comprend les champs eux-mêmes, dans l'ordre indiqué par le
RFC. Ces champs sont de taille
variable, mais indexés par les pointeurs cités plus haut. Il y a les champs obligatoires
(définis par le modèle de données du RFC 6872) comme From:
ou bien l'adresse IP
source, et les champs facultatifs. Pour les champs obligatoires, toute l'astuce est dans les
pointeurs. Ils sont à un emplacement fixe de la première ligne (pour
être trouvés facilement) et ils pointent vers l'octet de la deuxième
ligne où se trouve le champ. Pour connaître la fin du champ, on
regarde simplement le pointeur suivant, qui indique le début du champ
suivant. Ainsi, si on veut l'adresse IP de destination, on lit les
octets 20 à 23 de la première ligne (006D dans l'exemple suivant),
puis les octets 24 à 27 pour avoir le pointeur suivant (007D). Entre
ces deux pointeurs (109 à 125 en décimal), on trouve
192.0.2.10:5060
. (Pour les champs optionnels, il
faut faire une analyse syntaxique classique.)
Voici un exemple d'un enregistrement (section 5 du RFC) :
A000100,0053005C005E006D007D008F009E00A000BA00C700EB00F70100 1328821153.010 RORUU 1 INVITE - sip:192.0.2.10 192.0.2.10:5060 192.0.2.200:56485 sip:192.0.2.10 - sip:1001@example.com:5060 DL88360fa5fc DL70dff590c1-1079051554@example.com S1781761-88 C67651-11
On note que les champs numériques (les pointeurs) sont encodés en chiffres hexadécimaux, et pas en binaire (pour faciliter l'analyse par des outils orientés texte). Ce petit programme en Python (récupéré sur le Wiki du groupe de travail) permet de décoder l'enregistrement :
% python sip-clf-reader.py sip.log String length 257 str=005C CSeq message[83:92] = 1 INVITE str=005E Response message[92:94] = - str=006D ReqURI message[94:109] = sip:192.0.2.10 ...
Ici, on avait un programme spécifique comprenant ce format. Et si on veut utiliser les outils texte traditionnels ? La section 6 donne quelques détails à ce sujet. La méthode recommandée est de sauter les lignes d'index (elles commencent toujours par une lettre) et de ne traiter que les lignes de données (elles commencent toujours par un chiffre décimal, qui encode l'estampille temporelle). Ensuite, on éclate la ligne de données en champs, ceux-ci étant séparés par une tabulation. C'est moins rapide que les index, mais plus simple pour les utilisateurs de awk.
Merci à Régis Montoya pour sa relecture.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : V. Gurbani (Bell Laboratories,
Alcatel-Lucent), E. Burger (Georgetown
University), T. Anjali (Illinois Institute of
Technology), H. Abdelnur, O. Festor
(INRIA)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sipclf
Première rédaction de cet article le 15 février 2013
Un logiciel connecté à l'Internet a tout intérêt à enregistrer ses activités dans un « livre de bord » dont la lecture permettra notamment d'analyser ce qui s'est produit. Une des histoires à succès de la journalisation est celle des serveurs Web qui disposent, depuis longtemps, d'un format de journalisation standard, le Common Log Format (CLF). Ainsi, des logiciels comme Apache et Squid produisent des journaux compatibles, ce qui a permis de développer d'innombrables outils d'analyse et de statistiques pour ce format. Mais le protocole SIP, contrairement à HTTP, n'avait pas un tel format, chaque logiciel SIP journalisait comme cela lui plaisait. Ce fut le travail du groupe SIPCLF de l'IETF que de développer 1) un cadre standard de journalisation, dans ce RFC 6872 2) un format standard utilisant ce cadre, dans le RFC 6873.
Un exemple de journal au format CLF produit par Apache est :
192.0.2.219 - - [03/Feb/2013:07:33:07 +0000] "GET /samknows.html HTTP/1.0" 200 3923 "http://www.bortzmeyer.org/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.112 Safari/535.1" www.bortzmeyer.org
Mais HTTP a un modèle d'interaction très simple, chaque requête (ici, GET /samknows.html
qui veut dire « passe moi la page samknows.html
x) étant
complète et autonome. SIP est plus complexe et justifie donc une
approche plus élaborée (la section 7 détaille cette différence entre
les deux protocoles).
La section 3 du RFC synthétise la définition du problème : la variété des formats de journaux utilisés par les logiciels SIP rendent les analyses pénibles (particulièrement lorsqu'on veut analyser un appel qui est passé par plusieurs logiciels). Il faut donc un format commun. Il doit être utilisable par des outils simples en ligne de commande (un format fondé sur XML ne conviendrait donc pas). Il doit être cherchable de manière efficace (un journal SIP peut grossir très vite, c'est un protocole bavard), ce qui n'est pas le cas du CLF des serveurs HTTP, où il faut faire une analyse syntaxique de chaque ligne. Et, enfin, il doit pouvoir être généré facilement par tous les logiciels, sans dépendre de bibliothèques qui ne sont pas forcément disponibles partout (rien que pour cela, la famille ASN.1 ne convient donc pas).
La section 4, elle, est l'anti-cahier des charges, elle expose tout ce que le format commun de journaux SIP n'est pas : ce n'est pas un mécanisme de facturation (il se focalise sur la signalisation et ne voit donc pas l'échange de contenu), ce n'est pas un outil de mesure de la qualité de service, et ce n'est pas un outil d'espionnage, il n'est pas prévu pour aider Big Brother.
Le groupe de travail avait envisagé quatre possibilités, toutes abandonnées, avant de s'attaquer à la définition d'un format commun (section 5) :
From:
et To:
de SIP (qui peuvent être différents de
l'abonné). En outre, les CDR sont typiquement générés par des
serveurs intermédiaires, alors que le format commun de SIP pourra être
utilisé partout (par exemple par les
softphones). Enfin, le monde
SIP est bien plus large que celui des telcos :
des universités, par exemple, utilisent SIP, sans pour autant générer
de CDR.La section 6 revient sur les motivations de ce travail, en faisant une liste complète des scénarios d'usage du futur format commun :
Armé de ces considérations, le RFC définit ensuite (section 8) le modèle informationnel du journal SIP, c'est-à-dire la liste de ce qu'il faut journaliser (rappelez-vous que la syntaxe du journal n'apparaîtra que dans le RFC 6873). Ce modèle comprend une liste de champs obligatoires et la possibilité de journaliser des champs facultatifs.
D'abord, les champs obligatoires (je donne une liste non exhaustive, voir la section 8.1 du RFC pour la liste complète) :
From:
et To:
, qui
contiennent des URI),Comme leur nom l'indique, les champs obligatoires doivent être présents mais, dans certains cas, un champ donné n'a pas de sens pour cet évenement et le format doit alors spécifier un moyen de représenter cette absence.
La section 9 fournit quelques exemples (mais attention, ce sont des
exemples pour illustrer le modèle informationnel, pas pour illustrer
la syntaxe, qui n'est pas définie par ce RFC, mais dans le RFC 6873). Dans tous les exemples,
Alice, en
198.51.100.1:5060
, essaie d'appeler Bob, qui a
deux téléphones actifs, un en 203.0.113.1:5060
et
un en [2001:db8::9]:5060
. Alice et Bob ont chacun
un fournisseur, respectivement P1
(198.51.100.10:5060
) et P2
(203.0.113.200:5060
).
Ainsi, lorsque le softphone d'Alice s'enregistre auprès de son fournisseur SIP, le message SIP sera journalisé :
Timestamp: 1275930743.699 Message Type: R Directionality: s Transport: udp CSeq-Number: 1 CSeq-Method: REGISTER R-URI: sip:example.com Destination-address: 198.51.100.10 Destination-port: 5060 Source-address: 198.51.100.1 Source-port: 5060 To: sip:example.com To-tag: - From: sip:alice@example.com From-tag: 76yhh Call-ID: f81-d4-f6@example.com Status: - Server-Txn: - Client-Txn: c-tr-1
On note les champs sans valeur comme Status
, puisqu'il
s'agit d'une requête, il n'y a pas encore de réponse. Lorsqu'elle
arrive, le journal va enregistrer :
Timestamp: 1275930744.100 Message Type: r Directionality: r Transport: udp CSeq-Number: 1 CSeq-Method: REGISTER R-URI: - Destination-address: 198.51.100.1 Destination-port: 5060 Source-address: 198.51.100.10 Source-port: 5060 To: sip:example.com To-tag: reg-1-xtr From: sip:alice@example.com From-tag: 76yhh Call-ID: f81-d4-f6@example.com Status: 100 Server-Txn: - Client-Txn: c-tr-1
SIP peut aussi fonctionner en pair-à-pair, sans fournisseur. Ici, Alice appelle Bob :
Timestamp: 1275930743.699 Message Type: R Directionality: s Transport: udp CSeq-Number: 32 CSeq-Method: INVITE R-URI: sip:bob@bob1.example.net Destination-address: 203.0.113.1 Destination-port: 5060 Source-address: 198.51.100.1 Source-port: 5060 To: sip:bob@bob1.example.net To-tag: - From: sip:alice@example.com From-tag: 76yhh Call-ID: f82-d4-f7@example.com Status: - Server-Txn: - Client-Txn: c-1-xt6
et Bob répond positivement (résultat 200) :
Timestamp: 1275930746.100 Message Type: r Directionality: r Transport: udp CSeq-Number: 32 CSeq-Method: INVITE R-URI: - Destination-address: 198.51.100.1 Destination-port: 5060 Source-address: 203.0.113.1 Source-port: 5060 To: sip:bob@example.net To-tag: b-in6-iu From: sip:alice@example.com From-tag: 76yhh Call-ID: f82-d4-f7@example.com Status: 200 Server-Txn: - Client-Txn: c-1-xt6
La traditionnelle section sur la sécurité (section 10) appelle à quelques règles de prudence : les journaux contiennent des données personnelles et leur gestion doit se faire en prenant en compte les questions de protection de la vie privée. Pas question donc de mettre des journaux en accès libre. Le modèle d'information décrit dans ce RFC est suffisamment détaillé pour dispenser un attaquant qui aurait accès aux journaux d'écouter le trafic SIP. Le RFC suggère même d'étudier des méthodes de protection plus avancées comme le chiffrement du disque qui contient les journaux et la transmission des journaux uniquement par des canaux sécurisés, par exemple avec TLS.
Autre risque de sécurité, celui d'un dépassement de tampon : les entrées dans un journal SIP peuvent être très longues (surtout avec les champs optionnels) et un analyseur naïf qui utiliserait des structures de données de taille fixe pourrait se faire déborder.
La section 11 contient d'autres conseils utiles, pour les opérateurs cette fois : elle rappelle que les journaux sont facilement de grande taille, qu'un mécanisme de rotation (par exemple avec logrorate) est nécessaire.
Merci à Olivier Festor et Régis Montoya pour leur relecture.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : G. Salgueiro, J. Clarke, P. Saint-Andre (Cisco)
Chemin des normes
Première rédaction de cet article le 9 février 2013
Le format vCard (RFC 6350) de stockage de données structurées à propos d'une
entité a surtout été utilisé pour des personnes (pour faire des
carnets d'adresses) et des organisations. Le format standard définit
une propriété KIND
(section 6.1.4 du RFC 6350) qui indique quel est le type d'entité
décrit. À l'origine, KIND
pouvait avoir les
valeurs individual
(valeur par défaut),
group
, org
ou
location
. Ce nouveau RFC ajoute la valeur
device
qui permet d'indiquer qu'une vCard décrit
un engin, par exemple un routeur, à des fins
d'inventaire et de gestion du matériel.
KIND
avait déjà été étendu pour décrire les
logiciels (type application
, RFC 6473) et voici donc qu'il
passe au matériel. Attention, il y a une restriction : pour l'instant,
ces « device
» ne sont que les engins effectivements
connectés à l'Internet, du commutateur au Raspberry Pi, en passant par
l'imprimante et par des engins
plus exotiques mais qui ont tous en commun d'avoir une connexion
réseau et donc de participer à l'« Internet des Objets ». Les engins
purement mécaniques comme un ascenseur ou une
génératrice sont donc exclus, en attendant
qu'ils acquièrent une connexion Internet.
En revanche, les machines virtuelles sont incluses, contrairement à ce qui se passait en X.521 / RFC 4519 qui était restreint aux machines physiques.
Un des scénarios d'usage de ce nouveau RFC est d'inscrire la vCard
décrivant l'engin dans celui-ci, lors de la fabrication, permettant
ainsi de récupérer facilement et de manière standard les informations
utiles. Si la mémoire où est stockée la vCard est réinscriptible, on
peut aussi envisager d'y stocker des informations
opérationnelles. Mais comment récupérera t-on la vCard ? Pour
l'instant, aucun mécanisme standard n'est normalisé, ce
RFC ne spécifie que le format. Notez que
plusieurs vCards pourront être présentes dans un engin, par exemple
une de type device
pour l'engin, une de type
org
pour l'entreprise qui l'a fabriqué, etc. La
propriété RELATED
(section 6.6.6 du RFC 6350) pourra alors être utilisée pour relier ces
vCards.
Quelles propriétés vCard auront un sens pour un engin ainsi
identifié ? La section 2 en donne une liste indicative mais un exemple vaut mieux qu'un long discours, un routeur
installé au 60
Hudson géré par l'opérateur example.net
:
BEGIN:VCARD VERSION:4.0 KIND:device FN:core-rtr1-nyc1.example.net GEO:geo:40.717593,-74.00854 TZ:America/NewYork EMAIL:noc@example.net IMPP:PREF=1:xmpp:noc@example.net IMPP:PREF=2:irc:example@freenode.net ADR:;;60 Hudson Street;New York City;NY;;USA END:VCARD
On notera que FN
(Full Name) est un nom de
domaine.
À noter que le RFC utilise une autre syntaxe pour l'exemple de la section 3, en XML, en suivant le format xCard du RFC 6351.
Cette valeur device
est désormais enregistrée
dans le registre IANA.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : B. Carpenter (Univ. of
Auckland), S. Jiang (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6renum
Première rédaction de cet article le 28 février 2013
Comment renuméroter (changer les adresses IP) le réseau d'une organisation ? Quels sont les obstacles techniques qui font que cette renumérotation est parfois difficile ? Ce RFC décrit le problème du renumérotage en IPv6 pour le cas des adresses statiques, le RFC 6879 fournissant des solutions pour les autres cas (le RFC 4192 fournissait déjà certaines pistes).
Le problème avait été posé par le RFC 5887 : changer les adresses IP sur un réseau local nécessite du travail, trop de travail. Peut-on faciliter la vie des administrateurs réseaux sur ce point ? C'est le travail du groupe 6renum de l'IETF dont voici le premier RFC. 6renum se focalise sur les réseaux IPv6 (en IPv4, la pénurie d'adresses rend le problème bien pire). Et ce RFC de description du problème se lmite au cas où les machines ont des adresses statiques, c'est-à-dire stables sur une longue période. Autrement, pour les adresses dynamiques, renuméroter est bien plus simple (en général, on redémarre les machines et c'est tout). Les Enterprise Networks dont parle le titre du RFC sont les réseaux assez grands et complexes pour avoir pas mal d'adresses statiques (le petit réseau de la maison ou du SOHO est en général 100 % en adresses dynamiques).
Notons qu'avec une autre architecture de réseau, par exemple une séparation de l'identificateur et du localisateur, le problème n'existerait pas. Mais, comme le note la section 3.2 du RFC 6250, l'Internet a commencé avec uniquement des adresses statiques (DHCP n'existait pas) et les programmeurs ont supposé certaines propriétés des adresses IP qui étaient vraies à l'époque mais ne le sont plus forcément aujourd'hui. C'est à cause de cela qu'il est parfois plus simple aujourd'hui d'avoir des adresses statiques, bien que les raisons de ce choix ne soient pas toujours incontestables :
Attention, on parle bien d'adresses statiques, pas d'adresses manuellement affectées. Les adresses manuelles sont toujours statiques mais l'inverse n'est pas vrai : on peut attribuer des adresses statiques par DHCP, pour centraliser la configuration et éviter de modifier chaque machine.
La section 3 résume le problème à résoudre et l'approche proposée pour l'instant :
La section 2 analyse en détail chacun des points délicats. D'abord, pour
avoir des adresses statiques, il faut aussi des préfixes IP
statiques. Cela facilite certains diagnostics (« tous les gens qui se
plaignent sont dans 2001:db8:199:ac::
donc il
doit y avoir un problème de ce côté-là ») mais, en IPv6, ce n'est
nullement obligatoire, les préfixes, comme les adresses, peuvent être
entièrement dynamiques (d'autant plus que, contrairement aux préfixes
IPv4, ceux d'IPv6 sont difficiles à mémoriser). Pour les petits
réseaux, c'est certainement la meilleure solution.
Et les machines qui sont référencées par une adresse IP ? Pourquoi
des gens font cela alors qu'ils pourraient utiliser le
DNS, le SLP du RFC 2608 ou mDNS (combiné avec
Service Discovery) ? C'est parce qu'utiliser des adresses IP
peut représenter moins de travail pour les petites organisations que
d'installer et de configurer un serveur DNS. Et SLP, comme mDNS, est largement
implémenté mais très rarement déployé dans les réseaux d'« entreprise ». Bref, pas mal de gens
numérotent l'imprimante 10.1.1.2
et communiquent
cette adresse aux utilisateurs pour qu'ils l'entrent dans leur
configuration. Cela empêche une renumérotation facile. Il n'est pas
évident que cette pratique continue en IPv6, où les adresses sont
nettement plus difficiles à communiquer (« Non, j'ai dit
2001
comme le film, deux points, non l'un au
dessus de l'autre, pas un point suivi d'un autre,
db8
, oui, D comme Denise et B comme
Béatrice... »).
Naturellement, il n'y a pas que les imprimantes : les serveurs ont souvent des adresses IP fixes. Il serait mieux que les serveurs soient accédés par leurs noms, pas par leurs adresses. Mais cela suppose de mettre à jour le DNS en cas de renumérotation, ce que certains ont du mal à faire. Du DNS mis à jour dynamiquement et de manière sécurisée (RFC 3007) serait peut-être une solution. Cela laisserait toutefois la question du TTL (RFC 4192).
Je le répète, adresse statique ne signifie pas forcément adresse manuellement configurée quelque part sur le serveur. On peut parfaitement distribuer des adresses statiques avec DHCP. Si la zone DNS et la configuration DHCP sont dérivées automatiquement de la même base de données, la cohérence est assurée. C'est une bonne pratique, comme indiqué plus haut : nul besoin d'usines à gaz, un fichier plat et un script Python de quelques lignes suffisent. Sans cette pratique, il faut se connecter à chaque serveur pour changer sa configuration (ou bien utiliser des systèmes comme Ansible ou peut-être Chef).
Les routeurs et autres composants du réseau (comme les commutateurs) sont également souvent numérotés de manière fixe. Comme ils sont essentiels au bon fonctionnement du réseau, ils sont en général sous supervision. Cela rend difficile la renumérotation car il faut alors changer la configuration de Nagios ou de son équivalent. Il y a une école qui défend l'idée d'adresses ULA (RFC 4193) pour tous ces éléments de l'infrastructure, de manière à les préserver contre la renumérotation.
On l'a vu, une autre raison importante pour laquelle les
administrateurs réseaux utilisent des adresses IP statiques est la
gestion de parc. L'adresse IP sert alors
d'identificateur pour la machine, simplifiant certaines
procédures. L'IDS dit que
2001:db8:21:1::1:134
fait plein de connexions
vers le port 25 ? On retrouve facilement de
quelle machine il s'agit. Notons toutefois qu'aujourd'hui, même dans
les réseaux qui ont une telle pratique, les machines connectées en
WiFi y échappent, et ont des adresses
dynamiques.
À noter que les bons conseils de la section 3 laissent ouverts quelques problèmes :
Date de publication du RFC : Février 2013
Auteur(s) du RFC : J. Touch (USC/ISI)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 9 février 2013
Le champ ID
(internet identification
field) de l'en-tête des paquets
IPv4 sert à plusieurs usages mais le plus connu
est pour identifier les fragments d'un même
datagramme original, afin de réassembler ce
datagramme. La norme officielle de ce champ pose des contraintes qui
ne peuvent tout simplement pas être respectées avec les réseaux
modernes. Donc, toutes les mises en œuvre d'IP
violaient la norme, avant que ce RFC 6864 ne les ramènent
dans la légalité en changeant la norme, par le relâchement de ces
contraintes. Par ailleurs, cet excellent RFC, très bien écrit, est une
lecture très recommandée pour celui ou celle qui veut comprendre les
détails de la fragmentation dans IPv4.
La principale contrainte était que le champ ID
devait être unique pour tout tuple {adresse
source, adresse destination, protocole de transport}, pendant une période qui est la durée de vie
attendue des paquets. Avec les capacités des réseaux modernes, ce
champ, limité à 16 bits, ne pouvait tout simplement pas rester unique
aussi longtemps. Notre RFC change donc cette contrainte pour la
limiter aux paquets effectivement fragmentés (une minorité, en
général). Notez qu'IPv6 n'a pas ce problème, à
la fois parce que son champ ID
est plus grand
(RFC 2460, section 4.5) et parce que cette contrainte limitée avait été définie
dès le début.
Si vous voulez les détails du calcul, avec ses 16 bits, le champ
ID
peut stocker 65 536 valeurs. La durée de vie
des paquets dans le réseau est la MDL (maximum datagram
lifetime, typiquement deux minutes, cf. RFC 791 et RFC 1122 qui ne donnent pas
directement de
valeur précise). Avec une MTU typique de 1 500
octets, en supposant que les
datagrammes IP ont la taille de cette MTU (moins 20 octets pris par
l'en-tête) cela ferait (1 480 * 8) * (65 536 / (2 * 60)) = 6,465 Mb/s au
maximum ! Avec une MTU irréaliste (le maximum permis par IP, 65 535
octets), on n'irait encore qu'à 286 Mb/s. (Si vous aimez la précision,
notez qu'on pourrait, pour avoir ces 286 Mb/s, envoyer des datagrammes
de 65 535 octets sur un réseau dont la MTU n'est que de 1 500
octets. Mais, alors, tous les paquets seraient fragmentés et le coût
de réassemblage et les problèmes liés feraient que l'opération serait
sans doute une mauvaise idée.) Le calcul complet figure dans le RFC 4963. Notez
que tous ces RFC donnent des valeurs de plusieurs minutes pour le MDL,
valeurs qui me semblent complètement irréalistes. Je n'ai jamais vu un
datagramme se promener dans l'Internet pendant deux minutes entières
avant d'arriver ! (Voir la discussion en section 3.2.) Ceci dit, même avec une MDL de 3 secondes, on
n'arriverait encore qu'à 255 Mb/s (pour la MTU typique), ce qui n'est
pas suffisant. Des interfaces Ethernet à 1 Gb/s
sont aujourd'hui banales.
Les réseaux modernes vont évidemment bien plus vite que cela et il
est donc clair que les mises en œuvre d'IP violent cette contraine
d'unicité. Typiquement, elles réutilisent l'ID
bien avant l'expiration du délai maximum (section 5.1), ou bien elles utilisent un
ID
constant dès que le paquet n'est pas fragmenté
(ROHC en tient compte pour comprimer ce
champ, cf. section 5.4).
Avant de revenir sur les changements de ce RFC, retournons au
fonctionnement de la fragmentation (section
3). Celle-ci survient lorsqu'un datagramme est
plus grand que la MTU du prochain lien à traverser. Le datagramme est
alors fragmenté, chaque fragment est un paquet IP routé
indépendemment, mais tous les fragments d'un même datagramme ont la
même valeur du champ ID
. Vu par
tcpdump, voici une réponse
DNS de 3,5 ko fragmentée, les trois fragments
du datagramme original ayant l'ID
60977 (indiqué
juste après le TTL) :
16:32:35.631159 IP (tos 0x0, ttl 64, id 60977, offset 0, flags [+], proto UDP (17), length 1500) 217.70.190.232.53 > 88.189.152.187.44168: 41314*- q: ANY? sources.org. 23/0/1 sources.org. [1d] SOA ns3.bortzmeyer.org. hostmaster.bortzmeyer.org. 2013010100 7200 3600 604800 43200, sources.org. [1d] RRSIG [...] 16:32:35.631169 IP (tos 0x0, ttl 64, id 60977, offset 1480, flags [+], proto UDP (17), length 1500) 217.70.190.232 > 88.189.152.187: udp 16:32:35.631173 IP (tos 0x0, ttl 64, id 60977, offset 2960, flags [none], proto UDP (17), length 419) 217.70.190.232 > 88.189.152.187: udp
On note que les numéros de port, ainsi que
l'analyse du contenu du paquet, ne sont possibles que pour le premier
fragment (le seul qui contient les en-têtes UDP et DNS). D'autres
paquets de la même source vers la même destination, auront un
ID
différent :
16:42:17.601777 IP (tos 0x0, ttl 64, id 60988, offset 0, flags [+], proto UDP (17), length 1500) 217.70.190.232.53 > 88.189.152.187.54895: 15361*- q: ANY? sources.org. 23/0/1 sources.org. [1d] SOA ns3.bortzmeyer.org. hostmaster.bortzmeyer.org. 2013010100 7200 3600 604800 43200, sources.org. [1d] RRSIG, [...] 16:42:17.601787 IP (tos 0x0, ttl 64, id 60988, offset 1480, flags [+], proto UDP (17), length 1500) 217.70.190.232 > 88.189.152.187: udp 16:42:17.601792 IP (tos 0x0, ttl 64, id 60988, offset 2960, flags [none], proto UDP (17), length 419) 217.70.190.232 > 88.189.152.187: udp
En IPv4, la fragmentation peut être faite par la source des datagrammes, ou bien par un routeur intermédiaire, lorsqu'il détecte que le lien suivant a une MTU trop faible. L'émetteur ne sait donc pas forcément si son paquet sera fragmenté. En IPv6, par contre, seule la source peut fragmenter et elle sait donc si le paquet sera fragmenté ou pas.
Pour représenter la fragmentation, IPv4 a quatre champs,
ID
, déjà cité, le bit DF (Don't
fragment, qui interdit aux routeurs de fragmenter), la
distance depuis le début du datagramme (fragment
offset, 0, 1480 puis 2960 dans les exemples plus haut) et le bit MF (More fragments,
s'il vaut zéro, cela signifie que ce fragment est le dernier dans le
datagramme original, il est noté par un signe + dans la sortie de tcpdump). En IPv6, ce n'est plus dans l'en-tête mais dans
un en-tête d'extension (fragment header), qui ne
comporte que trois champs : le bit DF a disparu car, en IPv6, il est
toujours à 1 (un routeur intermédiaire n'a pas le droit de
fragmenter). Cet en-tête de fragmentation n'est présent que si le
paquet est effectivement fragmenté. Contrairement à IPv4, IPv6 ne
gaspille pas d'identificateur (ID
) pour les
paquets non fragmentés. IPv4 doit mettre un identificateur dans tous
les paquets, même non fragmentés, car il ne peut pas être sûr qu'un
routeur plus loin ne va pas décider de fragmenter.
En outre, en IPv6, le champ ID
fait 32 bits et
permet donc de stocker bien plus de valeurs. Bref, notre RFC ne couvre
que le cas d'IPv4, IPv6 n'a pas de problèmes. Même si tous les
paquets sont fragmentés, le champ ID
plus grand
permettrait à IPv6 de pomper 18,8 Tb/s (en supposant des datagrammes
de la taille maximale permise par IP). Si les paquets ne sont pas fragmentés, il n'y a
plus de limite.
Donc, que faire pour IPv4, afin de réconcilier la norme et la
pratique ? La section 4 expose les nouvelles règles pour le champ
ID
. L'idée de base est que tous les paquets ne
sont pas fragmentés. En fait, avec la PMTUD
(RFC 1191), la
plupart ne le sont pas. Donc, l'obligation d'unicité du champ
ID
n'est maintenue que pour
les paquets fragmentés ou susceptibles de l'être. La grande majorité
des paquets TCP, aujourd'hui, grâce à la PMTUD, ne seront pas
fragmentés (ils ont le bit DF, Don't fragment) et
n'ont donc pas d'obligation d'un identificateur unique.
Ce RFC introduit le concept de « datagramme atomique ». Un
datagramme atomique est un datagramme qui n'est pas fragmenté (MF = 0
et distance au début du datagramme = 0) et qui ne le sera pas (DF =
1). En pseudo-code ressemblant à du C,
(DF==1)&&(MF==0)&&(frag_offset==0)
. Les datagrammes non-atomiques sont tous les autres (ils sont déjà
fragmentés ou bien, n'ayant pas le bit DF à un, ils le seront
peut-être plus tard). Aujourd'hui, dans le trafic TCP habituel,
quasiment tous les datagrammes sont atomiques. La nouvelle règle de
non-unicité ne s'applique qu'aux datagrammes non-atomiques. Pour les datagrammes atomiques, IP peut mettre le
champ ID
à n'importe quelle valeur (section
4.2). Pour les
autres, il faut continuer à garder ID
unique
pendant la MDL (section 4.3). Cela a des conséquences sur les sources
qui émettent beaucoup de datagrammes non-atomiques, typiquement les
gros serveurs DNS (cf. RFC 6891, des réponses DNS plus grosses que la MTU sont
courantes et les serveurs ne font pas de PMTUD
en UDP). Ces sources, pour réussir à respecter
l'unicité des ID
peuvent se trouver dans
l'obligation de s'auto-limiter et donc de ne pas envoyer trop de
paquets (section 5.2).
À noter qu'il y a d'autres usages
possibles pour le champ ID
que la fragmentation et
le réassemblage. Il a été envisagé d'utiliser ce champ pour détecter
des datagrammes dupliqués (chose qui est possible dans un routeur
congestionné, cf. RFC 1122, section 3.2.1.5), ce
qui diminuerait le travail de protocoles de transport comme TCP qui,
actuellement, doivent gérer ce problème. Il a aussi été proposé de se
servir d'ID
pour des activités de
diagnostic. Aucun de ces projets n'est allé très loin et, de toute
façon, ils ne marcheraient pas en IPv6 qui n'a de champ
ID
que pour les datagrammes effectivement
fragmentés.
Comme la nouvelle règle ne marche que pour la fragmentation, les
autres usages du champ ID
sont désormais
interdits : plus question d'essayer d'utiliser ce champ pour autre
chose, puisqu'il n'est officiellement plus unique. Ce champ doit donc
être ignoré si le datagramme est atomique.
Le reste ne change pas. Par exemple, le bit DF garde exactement la même signification (« ne fragmente surtout pas ce paquet »).
En pratique, qu'est-ce que cela va changer (section 5) ? Rappelez-vous qu'en pratique, la nouvelle règle est depuis longtemps la règle de fait et que l'Internet ne s'est pas écroulé. Donc, notre RFC estime qu'il ne faut pas s'attendre à des problèmes, sinon, ceux-ci auraient été signalés il y a des années.
Une autre solution au problème du champ ID
trop court a été mentionnée plus haut : réutiliser les valeurs bien
avant l'expiration du MDL, d'autant plus qu'on a vu que celui-ci est
typiquement très grand. L'inconvénient de cette approche est que, si
des paquets fragmentés traînent et arrivent ensuite à peu près en même
temps que des fragments d'un autre datagramme, utilisant le même
identificateur, le réassemblage va produire des paquets qui ne
correspondent pas à l'original, en fusionnant les deux paquets (RFC 4963). Les sommes de
contrôle vont peut-être détecter le problème, mais le RFC
recommande d'utiliser des contraintes d'intégrité dans les
applications, pour être sûr. Si on a de telles contraintes bien
fortes, on peut réutiliser les identificateurs plus vite.
Autre problème potentiel, avec les
middleboxes qui réécrivent les
paquets, par exemple les routeurs NAT. Elles ne
doivent pas bêtement copier le champ ID
mais en
générer un correctement. Comme le routeur NAT typique réécrit
l'adresse source de N machines en un nombre bien plus petit d'adresses
(une seule pour le petit routeur NAT à la maison, un peu plus pour un
CGN), le risque de casser l'unicité est élevé :
si deux machines sur le réseau local communiquent avec la même
destination externe et émettent des datagrammes avec le même
ID
, une réécriture bête de l'adresse IP source
cassera l'unicité. Les CGN ont davantage d'adresses externes mais
aussi bien davantage de trafic et le risque est donc encore plus élevé
avec eux.
On a vu que ce RFC changeait l'ancienne norme (impossible à respecter) pour l'aligner avec la pratique. La section 6 donne la liste exacte des RFC modifiés : RFC 791, la norme IPv4 originale, et RFC 1122 notamment.
La fragmentation a des tas de conséquences sur la sécurité, d'où la section 7 qui examine les résultats de la nouvelle règle. Par exemple, elle rendra plus difficile le comptage des machines situées derrière un routeur NAT, même si ce n'était pas son objectif (cf. S. Bellovin, A Technique for Counting NATted Hosts).
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : S. Hartman (Painless Security), D. Zhang (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF karp
Première rédaction de cet article le 2 mars 2013
Le projet KARP (Keying and Authentication for Routing Protocols) vise à améliorer la sécurité des communications entre routeurs. La toute première étape est d'analyser l'état actuel de cette sécurité et ce RFC le fait pour le cas du protocole OSPF.
Il suit pour cela les principes posés dans le RFC 6518 dans sa section 4.2, « Work Items per Routing
Protocol ». Le RFC 6039 avait déjà
fait une telle analyse sous l'angle de la
cryptographie. Des
Internet-Drafts comme draft-ietf-rpsec-ospf-vuln
ont été écrits sur des aspects plus généraux de la sécurité d'OSPF. Et
des travaux ont déjà bien avancés pour améliorer cette sécurité (comme
l'ajout de l'authentification à OSPF v3 dans le RFC 6506). Ce nouveau RFC 6863 couvre le reste.
D'abord, la gestion des clés. Celle-ci est manuelle, dans OSPF. C'est à
l'administrateur réseaux de choisir les clés,
de configurer les routeurs, de changer les clés en allant modifier
chaque routeur, etc. Pour un protocole à gestion manuelle, OSPF est
plutôt bon : l'intégrité des communications est
protégée, le changement d'algorithme cryptographique est possible (ce
que l'on nomme l'agilité cryptographique), la sécurité n'empêche pas
de prioritiser certains paquets (comme les
HELLO
), etc.
Mais, par rapport aux exigences du RFC 6862, il reste quelque manques, et ce RFC a pour but de les lister. Par exemple :
HELLO
, indispensables au maintien de la
session, aient la priorité. Mais s'ils sont chiffrés avec IPsec, ce
n'est plus possible, tous les paquets doivent être traités par IPsec,
avant qu'on puisse les identifier et donc les prioritiser.Si vous voulez un résumé de la sécurité dans OSPF, la section 2 du RFC est faite pour vous, elle détaille l'état actuel, et les faiblesses. Rappelez-vous qu'il existe deux versions d'OSPF en service, OSPF v2 (RFC 2328), probablement le plus fréquent dans la nature, et OSPF v3 (RFC 5340 et RFC 5838) qui n'a pas été un grand succès.
D'abord, OSPF v2. L'annexe D du RFC 2328 décrit son mécanisme de protection cryptographique. En gros, on prend la plupart des champs de l'en-tête du paquet (mais pas l'adresse IP), plus un secret, on les condense et on ajoute le MAC au paquet. À l'époque, la fonction de condensation était forcément du MD5. Le RFC 5709 a permis des algorithmes modernes comme la famille SHA-2. Notez que la cryptographie n'est pas sans défauts (section 7) : comme elle impose des calculs importants à des engins qui n'ont pas forcément de gros processeurs, elle fournit une voie d'attaque par déni de service. Des protections supplémentaires comme celle du RFC 5082, permettant d'empêcher un attaquant extérieur d'injecter des paquets, sont à considérer.
OSPF v2 a une protection limitée contre le rejeu. Les paquets comportent un numéro de séquence qui est croissant. Il n'est donc pas possible de rejouer un vieux paquet, son numéro de séquence trop bas le trahirait. Mais il y a quelques limites : la norme impose que le numéro ne décroisse jamais, mais n'oblige pas à l'incrémenter à chaque paquet. Et elle ne précise rien sur le numéro initial (au démarrage du routeur) donc certains risquent de choisir un numéro initial identique à chaque démarrage (par exemple, avoir un numéro de séquence qui soit purement et simplement le nombre de secondes écoulées depuis le démarrage du routeur est tout à fait compatible avec la norme, mais très peu sûr). Autre piège, l'adresse IP n'est pas incluse dans la somme de contrôle, donc un attaquant peut copier un paquet envoyé par un pair, changer l'adresse IP et se faire ainsi passer pour un autre pair.
Par contre, OSPF v2 est tout à fait satisfaisant pour ce qui concerne le remplacement des clés. Les clés ont un identificateur, et des durées de vie explicitement indiquées (annexe D.3 du RFC 2328, qui permet d'accepter une nouvelle clé avant de l'utiliser soi-même), ce qui permet de faire des remplacements propres des clés.
Et OSPF v3 ? Malgré son numéro de version supérieur, il était plutôt moins bien placé, question sécurité. L'idée avait été de ne plus mettre de fonctions de sécurité dans OSPF, mais de compter sur IPsec pour tout (RFC 4552). IPsec fournissait tous les services demandés (et même d'autres comme la confidentialité), avec les caractéristiques souhaitées (comme l'agilité cryptographique). Mais IPsec ayant été très peu déployé, les sessions OSPF v3 se retrouvaient en pratique toutes nues. (Il y avait aussi des problèmes moins graves comme le fait que le chiffrement IPsec empêchait de prioritiser certaines paquets OSPF, puisqu'il fallait tout déchiffrer dans l'ordre d'arrivée avant de savoir lesquels étaient prioritaires. Même sans chiffrement, les techniques d'encapsulation d'IPsec rendaient l'analyse des paquets entrants difficile.)
La section 3 revient plus en détail sur les problèmes de rejeu. Aucune des deux versions d'OSPF n'est parfaite sur ce plan mais OSPF v3 est nettement plus vulnérable.
Après cet examen de l'existant, la section 4 résume ce qui manque à OSPF :
La section 5 pose ensuite les étapes du travail :
ietf-ospf-security-extension-manual-keying
).Date de publication du RFC : Mars 2013
Auteur(s) du RFC : G. Lebovitz, M. Bhatia (Alcatel-Lucent), B. Weis (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF karp
Première rédaction de cet article le 2 mars 2013
Le groupe de travail KARP de l'IETF travaille sur une partie bien spécifique du vaste programme de la sécurisation du routage sur l'Internet : il s'occupe de l'authentification réciproque des routeurs et de comment l'améliorer. Ce RFC fait l'analyse des menaces pesant sur cette authentification et expose le cahier des charges pour les nouveaux RFC qui vont s'attaquer à ces menaces (le premier RFC du groupe KARP, le RFC 6518, le recouvre partiellement mais se focalisait sur les tâches à long terme à accomplir).
Ce RFC 6862 ne spécifie pas un nouveau protocole, il sert de base au travail concret que le groupe KARP a désormais entamé. D'abord, l'analyse des menaces : comme le documente la section 8.1 du RFC 4948 (le compte-rendu d'un atelier sur le trafic Internet non sollicité), la meilleure solution pour un méchant qui veut perturber l'activité des autres est souvent de s'attaquer aux routeurs. Le RFC 4593 détaillait les attaques contre les protocoles de routage, et le RFC 6039 dénonçait le fait que les mécanismes de sécurité existant dans les routeurs étaient bien primitifs, par exemple parce qu'ils ne permettaient pas de changer les clés sans perturber sérieusement le fonctionnement du réseau (ce qui casserait les SLA), avec le résultat que bien des opérateurs ne changent jamais ces clés. (On peut aussi consulter le RFC 4949, un glossaire de la sécurité sur l'Internet.)
Quels sont les protocoles de routage concernés ? BGP, OSPF, IS-IS, LDP et RIP ont tous déjà des mécanismes cryptographiques de protection de la communication entre routeurs. Le but du projet KARP est d'améliorer ces mécanismes, pour lesquels il existe déjà du code qui tourne et de l'expérience opérationnelle, pas de les jeter et de les remplacer (principe dit « crawl, walk, run », autrement dit, ramper lorsqu'on n'a pas le choix, marcher si on peut, courir dans le meilleur des cas ; c'est tiré d'une citation célèbre de Martin Luther King). KARP est donc un projet incrémental (section 2.2). Parmi les raisons qui ne permettent pas d'envisager un passage à court terme vers des solutions radicalement différentes, avec de la cryptographie forte, partout, il y a le fait que les routeurs actuellement déployés ont des capacités matérielles très variables, par exemple, ils n'ont pas forcément d'accélérateur cryptographique. D'une manière générale, KARP essaie d'être réaliste et de coller aux témoignages des opérateurs, tels qu'exprimés dans le rapport Arbor.
Ce rapport note, par exemple, qu'aucun des opérateurs interrogés n'utilise IPsec entre ses routeurs (alors qu'il résoudrait un bon nombre des problèmes de sécurité de KARP). Par contre, 70 % utilisent les mots de passe MD5 sur les sessions BGP externes et 55 % sur les internes. Les clés sont très peu changées (des clés de plus de cinq ans sont courantes), en raison des conséquences (en BGP, changer la clé coupe la session, faisant osciller les routes) et des difficultés opérationnelles que cause leur changement (il faut se concerter avec le pair dont, bien souvent, on n'a plus les coordonnées, puis organiser le changement pile au même moment). Tout ceci pour un ROI nul. La décision du PHB est donc vite prise : on ne change pas les clés.
Le rapport Arbor cite même un opérateur qui utilisait la même clé pour tous ses clients et, à ceux qui s'inquiétaient de la sécurité et demandaient une clé spécifique, répondait que ce n'était pas possible. C'est gonflé, mais cela simplifiait beaucoup la vie de cet opérateur.
Ce travail de KARP, comme décrit dans le RFC 6518, aura deux phases :
Un bon exemple d'amélioration par déploiement incrémental a été pour BGP, où l'antédiluvien mécanisme de sécurité du RFC 2385 a d'abord été remplacé par l'AO (Authentication Option) du RFC 5925, alors même qu'il n'existait pas encore de protocole de gestion de clés, que plusieurs cryptographes estimaient indispensable. AO résout une partie des problèmes des mots de passe MD5 (notamment l'agilité cryptographique, la possibilité de changer d'algorithme) mais n'essaie pas de tout résoudre d'un coup.
Un peu de vocabulaire au passage : une KDF (Key Derivation Function) est une fonction qui génère une clé à partir d'une autre clé et de données diverses. Par exemple, une KDF possible est de concaténer la clé de départ (clé de dérivation) et une adresse IP, puis de condenser cryptographiquement le tout.
Un KMP (Key Management Protocol, le protocole qui fera l'objet de la phase 2) est un protocole de gestion de clés cryptographiques, permettant leur distribution aux routeurs. Le but d'un KMP est de permettre le changement relativement fréquent des clés (à l'heure actuelle, le changement des clés dans les protocoles de routage est manuel : comme c'est une opération pénible, elle n'est en général pas faite et les routeurs gardent en général les mêmes clés toute leur vie).
Une PSK (Pre-Shared Key) est une clé secrète partagée entre N routeurs, par exemple les mots de passe d'OSPF v2 ou bien les « mots de passe MD5 » de BGP. En l'absence de KMP, elles sont distribuées manuellement (copier-coller dans un terminal virtuel, par exemple).
Une bonne analyse de sécurité nécessite d'être conscient des capacités de l'adversaire. Première catégorie, les attaquants extérieurs à l'organisation (outsiders, section 3.1.1). Ils n'ont pas les clés. Notre RFC fait une distinction importante entre les attaquants extérieurs mais situés sur le chemin entre deux routeurs (on-path attackers) et ceux situés en dehors (off-path attackers). Les premiers peuvent écouter le trafic et injecter des paquets qui seront indistinguables des vrais. Les seconds ne peuvent pas écouter le trafic, peuvent parfois injecter des paquets mais, comme ils travaillent en aveugle, ils auront beaucoup plus de mal à les faire accepter comme authentiques. Le méchant situé sur le chemin (le plus dangereux) peut donc :
Les méchants extérieurs, qu'ils soient sur le chemin ou pas, peuvent aussi tenter de découvrir un mot de passe par force brute, en essayant de se connecter avec plein de mots de passe courants. Ou essayer de découvrir les clés par des essais systématiques (qui peuvent réussir si la clé est trop courte.)
Deuxième catégorie, les attaquants qui ont réussi à avoir une clé (section 3.1.2). Un exemple typique est un ex-employé mécontent (le taux de rotation du personnel est élevé dans ce métier). C'est à cause d'eux qu'il faut changer régulièrement les clés : on ne peut jamais être 100 % sûr que la clé n'a pas fuité et il est donc nécessaire de ne pas l'utiliser éternellement.
Enfin, il y a les byzantins, les pires (section 3.1.3). Ce sont les participants légitimes qui, pour une raison ou une autre, trahissent. Cela peut être un routeur bogué, qui émet des paquets incorrects. Ou un routeur piraté par le méchant. Comme le projet KARP vise à une meilleure authentification des pairs, le cas d'un pair légitime, mais traître, n'est pas traité dans le cadre de ce projet. (Idem pour un routeur qui jouerait correctement les protocoles de routage, mais jetterait ensuite les paquets, créant un trou noir.)
Avec de telles capacités, même les autres attaquants peuvent causer beaucoup de
dégâts. À noter que les attaques par déni de
service utilisant les protocoles de routage font partie des menaces considérées par KARP, par
exemple des paquets signés ou chiffrés qui entraînent des calculs
cryptographiques
lourds. Les attaques par déni de service volumétriques (pure force
brute, on envoie plein de paquets ordinaires) ne sont par contre pas
prises en compte par KARP. D'autres attaques par déni de service sont
des objectifs de KARP. Par exemple, si on faisait tourner BGP sur
TLS, pour le sécuriser, un attaquant sur le
chemin pourrait toujours envoyer des paquets
TCP RST
(ReSeT
) qui couperaient la connexion. KARP vise à
empêcher aussi ce genre d'attaques. (Si l'attaquant en question n'est
pas sur le chemin, et travaille donc en aveugle, cette attaque sera
plus compliquée pour lui, voir le RFC 5961.)
Il y aussi trois « non-objectifs », que KARP n'essaie même pas d'atteindre :
Et les solutions ? KARP se propose de mieux sécuriser les communications entre routeurs (il existe déjà des tas de techniques, mais imparfaites). Cette amélioration doit être incrémentale (pas question de faire de la table rase).
Le cahier des charges du travail de KARP (la « phase 1 », l'amélioration de l'existant, est déjà largement entamée) est donc ici, sous forme d'une longue liste d'exigences (section 4 du RFC) :
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : I. Dzmanashvili
Pour information
Première rédaction de cet article le 17 janvier 2013
Depuis la création du registre des types de liens par le RFC 5988, de nombreux types ont été enregistrés, pour qualifier les relations existant entre une ressource Web, et les ressources vers lesquelles elle a un lien. Ce nouveau RFC décrit deux nouveaux types, pour indiquer un lien vers un formulaire permettant de créer ou de modifier une ressource.
Prenons une encyclopédie en ligne comme
Wikipédia. Chaque article est modifiable par
les lecteurs. Trouver le lien menant au formulaire de modification est
une opération différente sur chaque site. Pour faciliter cette tâche, on peut mettre dans
l'article un lien typé edit-form
et le navigateur
pourra alors facilement mettre un bouton standard « Modifier cette
ressource ». Même si, pour les humains, ce n'est pas forcément
indispensable, ces liens typés peuvent être très utiles pour les
programmes, qui peuvent ainsi automatiquement détecter et suivre le
lien menant vers le formulaire. (Attention toutefois, avertit le RFC,
si le lien pointe vers un autre domaine : il ne faut pas forcément
suivre aveuglément tous les liens.)
Ce RFC est très court car ces deux types
sont simples à définir. Le premier, create-form
,
permet d'indiquer un formulaire pour créer une ressource inexistante
(il est donc intéressant lors d'une réponse « 404 », indiquant
que la ressource demandée n'a pas été trouvée, mais aussi pour ajouter
une entrée à une collection). Voici un exemple en
HTML :
<ul> <li>Endives au gratin</li> <li>Hachis parmentier</li> ... </ul> <a href="/recipe/create" rel="create-form">[Ajouter une nouvelle recette]</a>
Comme tous les liens typés du RFC 8288 (successeur du RFC 5988), ils ne sont pas limités à HTML et peuvent être mis dans une réponse HTTP (ce qui permet leur utilisation pour des ressources non-HTML) :
HTTP/1.0 404 Not found Server: Experimental 0.0 Link: </files/upload>; rel="create-form"; title="Create it" Date: Mon, 14 Jan 2013 07:35:01 GMT
L'autre type, edit-form
, permet de modifier
une ressource existante. En HTML :
<ul> <li> Endives au gratin <a href="/recipe/endivegratin/edit" rel="edit-form">[Modifier]</a> </li> <li> Hachis parmentier <a href="/recipe/hachisparmentier/edit" rel="edit-form">[Modifier]</a> </li> ... </ul>
Et sous forme d'un en-tête HTTP :
HTTP/1.0 200 OK Server: Experimental 0.0 Link: </recipe/fiadone/edit>; rel="edit-form"; title="Modifier la recette" Date: Mon, 14 Jan 2013 07:36:42 GMT
Notez qu'il existe déjà un type edit
(décrit
par le RFC 5023 et donc spécifique à
APP mais qu'on trouve parfois dans des pages HTML).
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : B. Leiba (Huawei)
Première rédaction de cet article le 15 janvier 2013
Un petit RFC bureaucratique, décrivant un léger changement dans les règles d'éligibilité au NomCom, le comité qui nomme à des postes au sein de la galaxie IETF. Désormais, les membres de l'IAOC rejoignent la liste des non-éligibles. (Ce RFC a depuis été fusionné avec d'autres pour former le RFC 7437.)
Le RFC 3777 décrivait le fonctionnement de ce NomCom (Nominating Committee). Il dressait une liste des comités dont les membres ne peuvent pas être au NomCom, afin d'éviter l'auto-sélection. Par exemple, les membres de l'IESG ne peuvent pas être au NomCom, ce qui est logique puisque celui-ci contribue à la nomination de l'IESG. Même chose pour l'IAB.
Depuis le RFC 3777, l'IAOC a été créée (RFC 4071) et ses membres sont également partiellement choisis par une procédure où le NomCom est présent. Notre RFC décrète donc que, désormais, la liste des non-éligibles inclut l'IAOC (mettant ainsi à jour la règle 15 de la section 4 du RFC 3777). Depuis, le RFC 7437 a rassemblé tous les changements en un seul RFC faisant autorité sur le NomCom.
On notera que les présidents des groupes de travail, les membres des directions transversales et d'autres comités ne sont pas concernés : aujourd'hui comme hier, ils peuvent siéger au NomCom.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : Arnt Gulbrandsen
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 12 mars 2013
Lorsqu'un message complètement internationalisé (avec en-têtes en Unicode, adresse d'expéditeur en Unicode, etc) est stocké sur un serveur de messagerie, et qu'un client IMAP ou POP veut le récupérer, que faire si le dit client n'est pas capable de gérer les messages entièrement internationalisés ? Le message a déjà été reçu et stocké. Il est trop tard pour le renvoyer à l'expéditeur (le courrier électronique étant asynchrone, on ne peut pas en général signaler à l'expéditeur qu'on ne sait pas gérer ses messages). Il faut donc se résigner à effectuer un repli stratégique (downgrading) et à transcrire plus ou moins bien le message en ASCII. Il existe deux algorithmes pour cela, un très simple dans ce RFC 6858 et un plus riche dans le RFC 6857.
Car notre RFC 6858 ne prétend pas faire un travail
satisfaisant. Si M. Li, en Chine, a utilisé son
nom comme adresse (From: 李@中国科学院.中国
), il n'existe pas
de mécanisme automatique satisfaisant pour transformer cette adresse
en une adresse qui marche toujours (par exemple, qui permette d'y
répondre). Le repli (downgrade) est donc toujours
rudimentaire et le message ne sera donc qu'imparfaitement rendu.
Une des solutions permises par le RFC 6855 est de dissimuler le message aux yeux des clients IMAP archaïques. Notre RFC en propose une autre, afficher un message dégradé (le « message de synthèse »), considérant que cela vaut mieux que rien.
L'algorithme de ce court RFC se veut simple, considérant que, si le programmeur est courageux et prêt à faire des choses compliquées, il a plutôt intérêt à mettre en œuvre le RFC 6855, pour gérer complètement l'Unicode. (L'autre algorithme, celui du RFC 6857, n'est pas d'accord.)
Le gros du RFC est la section 2, qui indique les transformations opérées pour transformer le message Unicode en du pur ASCII :
From: 李@中国科学院.中国
ci-dessus pourra devenir, par exemple, From:
Internationalized Address =?utf-8?b?5p2O?=
<international@address.invalid>
. Le
TLD
.invalid
est réservé par
le RFC 2606. Ici, le nom de M. Li a été encodé
avec le RFC 2047 (le truc qui commence avec =?
). Cette transformation
s'applique à tous les champs contenant des adresses
(From:
, ici, mais aussi Cc:
,
Reply-To:
, etc).Content-Disposition: attachment;
filename=اعلامیه_مطبوعاتی
deviendra
Content-Disposition: attachment
.Subject:
sera encodé en RFC 2047. Ainsi, Subject: Venez découvrir ce
café
deviendra Subject:
=?utf-8?q?Venez_d=C3=A9couvrir_ce_caf=C3=A9?=
. Contrairement
au cas de l'adresse (où le repli produit un en-tête qui ne marchera
plus), ici, le MUA pourra reconstruire le sujet
original.Voilà, j'avais promis un algorithme simple, il l'est. Il permet à
un serveur IMAP ou POP de ne pas trop dérouter ses lecteurs non-Unicode. Il
reste quelques petits détails, dans les sections 3 et 5. Ainsi, des
commandes IMAP comme FETCH RFC822.SIZE
permettent
de connaître la taille d'un message avant de le télécharger. Comme le
repli en ASCII change la taille, notre RFC permet au serveur de
renvoyer la taille du message originel, pas celle du message de
synthèse, pour lui simplifier la vie.
Question sécurité, le repli n'est pas idéal (section 5) :
Message-ID:
ont
pu disparaître purement et simplement dans l'opération,À noter que les réponses du serveur IMAP pourront désormais inclure
le mot-clé DOWNGRADED
, désormais dans le registre
IANA des réponses possibles.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : K. Fujiwara (JPRS)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 12 mars 2013
Ce nouveau RFC normalise un mécanisme de repli (downgrade) lorsqu'un serveur POP ou IMAP a reçu des courriers entièrement internationalisés et qu'un client POP ou IMAP de l'ancienne génération, qui ne comprend pas les adresses en Unicode, veut récupérer ce courrier. Le mécanisme de ce RFC est plus complet (et plus complexe) que celui, concurrent, du RFC 6858.
Dans la première version du courrier électronique entièrement en Unicode (celle normalisée dans les RFC 5335 et suivants), il était prévu un repli effectué entre serveurs SMTP. Si un serveur détectait que le serveur suivant ne gérait pas la nouvelle norme, il se repliait automatiquement sur un format compatible. Ce mécanisme, spécifié dans le RFC 5504, était compliqué et fragile et a été abandonné dans la deuxième version du courrier électronique entièrement internationalisé, celle des RFC 6530 et suivants. Désormais, les seuls endroits où un repli (downgrade) peut se faire sont à l'expédition, dans le MUA (de manière non standardisée, c'est un problème d'interface utilisateur) ou bien par les serveurs POP ou IMAP, lorsqu'ils ont reçu un message internationalisé et découvrent après qu'un de leurs clients ne gère pas cette norme (chose qu'on ne peut pas savoir à l'avance). Les RFC 6856 et RFC 6855 ne définissent pas de mécanisme obligatoire pour ce cas. Ils prévoient plusieurs possibilités (rejeter les vieux clients, cacher le message, comme s'il n'avait jamais été reçu, etc) parmi lesquelles le repli automatique vers un format compatible. Un tel repli n'est jamais une solution satisfaisante (il fait perdre de l'information, on ne pourra pas toujours répondre aux messages en question) mais, dans certains cas, cela peut être la moins mauvaise solution. Pour éviter une prolifération de mécanismes de repli différents, donnant des résultats distincts, deux algorithmes de repli sont normalisés, un très simple à mettre en œuvre (et faisant perdre beaucoup d'information), dans le RFC 6858, et un plus proche de l'esprit du RFC 5504, qui respecte davantage le message original, essayant de garder le plus d'information possible (mais qui sera plus compliqué à programmer), celui de notre RFC 6857.
La grosse différence entre le courrier actuel, complètement
internationalisé (RFC 6532), et la version immédiatement précédente (RFC 5322), est qu'il est désormais possible d'avoir
de l'Unicode, encodé en
UTF-8, dans tous les en-têtes, et y compris
dans les adresses (on peut avoir From:
stéphane@bortzmeyer.org
ou From: المنصف@التحرير.تونس
, qui étaient interdits dans le RFC 5322). Pour le reste du message, notamment le
corps, le problème est réglé depuis longtemps par
MIME. Mais ces en-têtes en Unicode ne sont pas
compris par les vieux clients POP et IMAP et la question se pose
donc : comment leur transmettre ?
La section 1.2 liste plusieurs solutions (en en oubliant une, qui était mentionnée dans d'autres RFC, cacher le message) : rejeter le message au moment de la distribution (si on sait qu'on a une majorité de clients anciens), envoyer un faux message qui dit qu'il y a intérêt à mettre à jour le client IMAP pour tout voir, ou bien effectuer un repli en transformant le message internationalisé en quelque chose de compatible, avec des en-têtes entièrement en US-ASCII. C'est cette dernière approche qui est choisie par notre RFC (et par son concurrent RFC 6858). Il reconnait pourtant qu'il n'existe pas de solution idéale à ce problème et que celle exposée ici est « la moins mauvaise ».
Donc, première opération, la plus importante, transformer (dégrader) les en-têtes, en section 3. (Les exemples sont tirés de l'annexe A du RFC, mais elle n'a malheureusement pas d'exemple avec les IDN.) La méthode est de diviser la valeur de l'en-tête en ses différentes composantes, et de transformer, dans chaque composante, l'UTF-8 dans l'encodage du RFC 2047. Cela marche bien pour des choses comme le nom affiché dans l'adresse, et c'est en général réversible (on ne perd donc pas d'information, mais le RFC ne mentionne pas ce point, pour ne pas susciter de faux espoirs ; voir le traitement des espaces par le RFC 2047 dans la section 6 de notre RFC). Ici, par exemple, le sujet et un en-tête inconnu ont été ainsi traités. L'original disait :
Subject: Qui télécharge de la musique vole un œuf et qui vole un œuf assassine les artistes X-Hadopi: Ne pas lire ce message est une négligence caractérisée
Et la version après repli est :
Subject: =?utf-8?q?Qui_t=C3=A9l=C3=A9charge_de_la_musique_vole_un_=C5=93uf_et_qui_?= =?utf-8?q?vole_un_=C5=93uf_assassine_les_artistes?= X-Hadopi: ?utf-8?q?Ne_pas_lire_ce_message_est_une_n=C3=A9gligence_caract=C3=A9ris?= =?utf-8?b?w6ll?=
On notera que c'est la forme actuellement utilisée par les MUA traditionnels, pour transmettre des caractères non-ASCII « déguisés » en ASCII. Le repli ramène donc à la situation antérieure au RFC 6532.
Deux exceptions : les noms de
domaines et la partie locale des adresses. Les
IDN sont réécrits en
Punycode (RFC 3492) donc
नईदिल्ली.भारत
devient
xn--o1b4de6ba0fj6h.xn--h2brj9c
. Exception dans
l'exception, cette traduction en Punycode n'est pas faite si la partie
locale de l'adresse est elle-même en Unicode (voir l'exemple de M. Li
plus loin).
Et une deuxième exception, plus sérieuse, les parties locales des
adresses. On utilise aussi le RFC 2047 mais
cette transformation est bien plus intrusive puisque le résultat ne
sera pas, la plupart du temps, une adresse utilisable (le logiciel qui
tenterait de répondre à un message qui a subi cette opération
récupérer un avis de non-remise). Ainsi, नेहरू
deviendra =?utf-8?b?4KSo4KWH4KS54KSw4KWC?=
qui, typiquement, ne sera pas accepté par le serveur de messagerie indien... Cela s'applique pour
tous les en-têtes qui peuvent contenir des adresses comme
From:
, To:
,
Cc:
, etc.
Combinant ces deux exceptions, voici ce que deviendra l'adresse de M. Li, qui était :
From: 李@中国科学院.中国
et qui, après le repli, est :
From: =?utf-8?b?5p2OQOS4reWbveenkeWtpumZoi7kuK3lm70=?=
Joli, non ?
Lorsque l'opération fait perdre trop d'information, le serveur POP
ou IMAP peut préserver l'ancien en-tête, globalement encodé en RFC 2047 (et non plus composante par composante), dans un en-tête dont le nom est préfixé par
Downgraded-
. Ainsi, avec un
Message-ID:
, il est globalement encodé (on ne
cherche pas le nom de domaine, qu'il contient souvent) :
Message-ID: <50EF7C49.4060203@नईदिल्ली.भारत>
devient :
Downgraded-Message-ID: =?utf-8?b?PDUwRUY3QzQ5LjQwNjAyMDNA4KSo4KSI4KSm4KS/4KSy4KWN4KSy4KWALg==?= =?utf-8?b?4KSt4KS+4KSw4KSkPg==?=
Si on avait suivi l'autre algorithme, celui du RFC 6858, cet en-tête aurait tout simplement été retiré.
Ces nouveaux en-têtes commençant par Downgraded-
sont désormais enregistrés à l'IANA. Les
en-têtes Downgraded-*
expérimentaux du RFC 5504 sont officiellement abandonnés.
La deuxième opération, en section 4, concerne les parties MIME du message, et les messages encapsulés comme les accusés de réception de la section 6 du RFC 3461. Eux aussi contiennent de l'UTF-8 et doivent subir une opération de repli analogue.
La section 5, sur la sécurité, rappelle les limites de la méthode : on ne peut pas, en général, répondre aux messages ayant subi le repli (les adresses ont été massacrées), le message est plus difficile à analyser par le destinataire (il y a donc plus de possibilités de tromperie), les signatures DKIM sont presque à coup sûr invalidées (celles en PGP peuvent tenir bon, dans certains cas), etc.
Je ne connais pas encore d'implémentation de ce RFC particulier.
Date de publication du RFC : Mars 2013
Auteur(s) du RFC : P. Resnick (Qualcomm), C. Newman (Oracle), S. Shen (CNNIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 12 mars 2013
Successeur du RFC 5738, voici la normalisation de la gestion d'Unicode par le protocole IMAP d'accès aux boîtes aux lettres.
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 maintenant 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). C'est donc une des composantes d'un courrier électronique complètement international (RFC 6530). Le RFC précédent sur le sujet, le RFC 5738 avait le statut « Expérimental » alors que notre RFC 6855 est sur le « Chemin des Normes ». (Il existe un RFC équivalent pour POP le RFC 6856.)
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 normalise une nouvelle,
UTF8=ACCEPT
(section 3). En l'utilisant, le serveur proclame qu'il sait faire de l'UTF-8. Par le biais de
l'extension ENABLE
(RFC 5161), le client
peut à son tour indiquer qu'il va utiliser UTF-8. Une fois que cela sera fait, client et serveur pourront faire de l'IMAP UTF-8. La section 3.1
détaille la représentation des chaînes de caractères UTF-8 sur le
réseau.
Les nouvelles capacités sont toutes décrites dans la section 9 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. Les noms de ces boîtes doivent se limiter au profil « Net-Unicode » décrit dans le RFC 5198, avec une restriction supplémentaire : pas de caractères de contrôle.
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, et la section 5 spécifie
ce point. Elle note 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. Prudence, donc.
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 6 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 forcément en UTF-8 (un tel
serveur, en 2013, n'aurait guère de
clients, puisqu'il ne peut plus interagir avec les anciens clients
IMAP pré-Unicode...)
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.
La section 7 expose le problème général des clients IMAP
historiques. Un serveur peut savoir si le client accepte UTF-8 ou pas
(par le biais de l'extension ENABLE
) mais, si le
client ne l'accepte pas, que peut faire le serveur ? Le courrier
électronique étant asynchrone, l'expéditeur ne savait pas, au moment
de l'envoi si tous les composants, côté réception, étaient bien
UTF-8. Le RFC, après des années de discussions vives dans le groupe de travail EAI, n'impose pas une solution unique. Le serveur peut
dissimuler le message problématique au client archaïque. Il peut
générer un message d'erreur. Ou il peut créer un substitut, un
ersatz du message originel, en utilisant les
algorithmes du RFC 6857 ou du
RFC 6858. Ce ne sera pas
parfait, loin de là. Par exemple, de tels messages « de repli » auront certainement
des signatures invalides. Et, s'ils sont lus
par des logiciels différents (ce qui est un des avantages d'IMAP),
certains gérant l'Unicode et d'autres pas, l'utilisateur sera
probablement très surpris de ne pas voir le même message, par exemple entre son
client traditionnel et depuis son
webmail. C'est affreux, mais
inévitable : bien des solutions ont été proposées, discutées et même
décrites dans des RFC (RFC 5504) mais aucune
d'idéale n'a été trouvée.
Je ne connais pas encore d'implémentation en logiciel libre mais il existe déjà, en Extrême-Orient, pas mal d'utilisateurs du courrier électronique en Unicode.
Notre RFC ne contient pas de résumé des différences avec son prédécesseur, le RFC 5738. Les principales sont à mon avis :
UTF8=USER
pour les noms d'utilisateur et eux
seuls. Désormais, un serveur IMAP internationalisé est complètement
UTF-8 ou pas.UTF-8
pour des
commandes comme EXAMINE
. Désormais, une fois
qu'on est en UTF-8, on l'est complètement. Ce RFC est donc plus simple
et plus court que son prédecesseur, ce qui est rare dans le monde de
la normalisation !Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : R. Housley (IETF Chair), S. Mills (IEEE-SA President), J. Jaffe (W3C CEO), B. Aboba (IAB Chair), L. St.Amour (ISOC President and CEO)
Pour information
Première rédaction de cet article le 26 janvier 2013
Au cours des préparatifs de la réunion WCIT, organisée par l'UIT à Dubaï en décembre 2012, une des propositions faites au sein de la bureaucratie UIT était de rendre obligatoires, d'une manière ou d'une autre, les normes techniques émises par l'UIT. Ce projet n'a finalement apparemment pas été adopté mais il avait déclenché une réaction des autres SDO, qui ne voyaient pas pourquoi l'UIT aurait un tel privilège. Trois de ces SDO, l'IEEE, l'IETF et le W3C ont signé en commun une déclaration, dite OpenStand, dont ce RFC reprend le texte.
On comprend l'UIT : ses normes techniques (comme X.25 ou X.400) sont aujourd'hui bien oubliées et, dans l'Internet d'aujourd'hui, il ne reste guère de normes UIT qui soient utilisées (X.509 et ASN.1 doivent être parmi les rares exceptions, et encore, X.509 est menacé par le RFC 6698). Obtenir par un traité international, puis par la loi, ce que les acteurs du réseau lui ont refusé est donc tentant. L'un des principaux points de la déclaration tripartite des autres SDO est donc que l'adoption des normes doit rester fondée sur le volontariat : on déploie sur le réseau réel les normes qui ont un sens, et pas n'importe quel délire issu des comités Théodule de l'UIT, déconnectés de la réalité depuis longtemps.
La déclaration tripartite OpenStand a été signée le 29 août 2012, sans discussion à l'intérieur de l'IETF, dont les membres ont découvert le texte a posteriori. Comme la déclaration était le résultat d'un accord multilatéral, il ne pouvait plus être modifié par la suite. Le RFC reprend son texte littéralement, et tout le processus normal de discussion d'un RFC a donc été court-circuité : il y a bien eu des appels à commentaires mais les commentaires ont été complètement ignorés.
D'autres organisations ont signé depuis cette déclaration, on peut en trouver la liste sur le site officiel d'OpenStand.
Que dit cette déclaration (section 2) ? Après un préambule où n'est mentionné que le business (comme si l'Internet ne servait pas à une myriade d'autres activités, comme le notait le commentaire #193), les global markets et la concurrence, la déclaration affirme cinq points. Le premier est une sorte de clause de « non-ingérence dans les affaires des autres SDO », où chaque signataire s'engage à respecter les règles des autres. Le deuxième est l'adhésion à cinq principes :
Le troisième point de la déclaration est un pot-pourri de points souhaitables dans les normes techniques produites (par exemple qu'elles permettent l'interopérabilité, la résilience, le passage à l'échelle, etc).
Le quatrième est le plus hypocrite : la disponibilité des normes techniques. Or, si des dinosaures comme l'ISO ou l'AFNOR ne publient toujours pas leurs normes sur l'Internet, si des organisations comme l'ETSI imposent des restrictions ridicules (enregistrement préalable, limite à trois normes accessibles), l'UIT, après de très longues hésitations, a fini par passer au vingt-et-unième siècle et ses normes sont désormais gratuitement accessibles. Par contre, un des signataires d'OpenStand, l'IEEE, ne le fait toujours pas... Il avait été question de mettre dans la déclaration tripartite une phrase comme « The text of standards is made accessible to all, free of charge or at low cost », voire, plus flou, un mot sur l'importance d'une distribution free des normes (avec la délicieuse ambiguité de l'anglais sur le mot free) mais cela a été écarté, sinon l'IEEE ne signait pas. C'est sur ce point que le caractère politicien d'OpenStand est le plus clair.
Le même point mentionne la délicate question de l'appropriation intellectuelle, qui affecte tant de normes. Les différences de politique entre les trois signataires (et même à l'intérieur de chaque signataire, notamment l'IETF), font que la déclaration reste très vague, acceptant aussi bien les techniques complètement libres que celles plombées par un brevet, à la seule condition, très générale, que les licences soient FRAND.
Enfin, le cinquième point de la déclaration est l'importance d'une adoption volontaire des normes, fondée sur leur mérite technique et pas sur une décision autoritaire, comme indiqué au début de cet article.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : A. Gulbrandsen, N. Freed (Oracle)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF imapmove
Première rédaction de cet article le 29 janvier 2013
Le protocole d'accès aux boîtes aux lettres
IMAP, normalisé dans le RFC 3501, ne prévoyait pas officiellement de moyen de
déplacer un message d'une boîte à une autre. Il
fallait que le client IMAP réalise une série de commandes à la place,
et le déplacement n'était donc pas
atomique. Plusieurs serveurs IMAP avaient mis
en œuvre une commande atomique non officielle, MOVE
, et ce
RFC la normalise.
Avant ce RFC, en effet, la meilleure méthode officielle pour
déplacer un message d'une boîte IMAP à une autre était un
COPY
(copier le message vers la nouvelle boîte), puis
STORE
(marquer le message comme devant être
détruit), suivis d'un
EXPUNGE
(détruire les messages
marqués). Plusieurs logiciels clients avaient ce service, pour que
l'utilisateur puisse déplacer un message. Le problème est que ce
n'était pas atomique. Par exemple, si le
serveur IMAP redémarrait entre le COPY
et le
STORE
, le message était dupliqué, et se
retrouvait dans les deux boîtes. Sans même
supposer un redémarrage, IMAP permet un accès simultané par plusieurs
clients et le second client peut alors voir la boîte dans un état
invalide (message copié mais pas encore détruit de l'ancienne
boîte). Enfin, certains serveurs ont un mécanisme efficace pour
déplacer un message sans copier les données (pensez à un serveur
Unix qui stocke chaque message dans son fichier
et peut donc faire un rename()
facilement) et il était donc
souhaitable de permettre son utilisation.
Bref, la section 3 décrit la nouvelle commande,
MOVE
, qui prend comme argument les numéros des
messages à déplacer et le nom de la nouvelle boîte (il y a aussi un
UID MOVE
qui désigne les messages par leur
identificateur, l'UID, et pas par leur numéro dans une séquence). À
noter que, comme MOVE
prend comme argument un
groupe de messages, l'atomicité n'est garantie que pour chaque message
(soit il est déplacé, soit il ne l'est pas, il ne peut pas être
dupliqué), pas pour le groupe (certains messages peuvent être déplacés
et d'autres pas).
Comme toute extension d'IMAP, MOVE
est annoncé
dans les capacités du serveur, au début de la connexion (les capacités
possibles sont dans un registre IANA).
La section 4 décrit les interactions de MOVE
avec d'autres extensions IMAP. Par exemple, les
quotas du RFC 2087
(MOVE
peut réussir là où un
COPY
aurait échoué, s'il y a un quota actif), ou
bien les ACL du RFC 4314 (pour
déplacer un message, il faut avoir le droit d'écrire dans la nouvelle
boîte, et de détruire dans l'ancienne). Pendant qu'on parle de
sécurité, le RFC rappelle aussi (section 6) qu'un
MOVE
peut avoir des interactions avec certaines
politiques de stockage dans les boîtes (par exemple, si
l'antispam met les spams dans une boîte
nommée SPAM
, un MOVE
hors de
cette boîte n'est pas innocent).
Il parait qu'il existe déjà plusieurs mises en œuvre de
MOVE
, aussi bien dans des clients que dans des
serveurs IMAP. Mais je ne connais pas lesquelles. J'ai testé avec des
Courier et des Zimbra
récents et ils ne semblent pas avoir cette extension. Pour Dovecot, c'est annoncé pour la 2.2.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : P. Hallam-Baker (Comodo), R. Stradling
(Comodo)
Chemin des normes
Première rédaction de cet article le 31 août 2017
Dernière mise à jour le 26 octobre 2017
Ce RFC a quelques années mais n'avait connu que peu de déploiement effectif. Cela va peut-être changer à partir du 8 septembre 2017, où les AC ont promis de commencer à vérifier les enregistrements CAA (Certification Authority Authorization) publiés dans le DNS. Ça sert à quoi ? En gros, un enregistrement CAA publié indique quelles AC sont autorisées à émettre des certificats pour ce domaine. Le but est de corriger très partiellement une des plus grosses faiblesses de X.509, le fait que n'importe quelle AC peut émettre des certificats pour n'importe quel domaine, même si ce n'est pas un de ses clients. Notez qu'il a depuis été remplacé par le RFC 8659.
C'est donc une technique très différente de DANE (RFC 6698), les seuls points communs étant l'utilisation du DNS pour sécuriser les certificats. DANE est déployé chez le client TLS, pour qu'il vérifie le certificat utilisé, CAA est surtout dans l'AC, pour limiter le risque d'émission d'un certificat malveillant (par exemple, CAA aurait peut-être empêché le faux certificat Gmail du ministère des finances.) Disons que CAA est un contrôle supplémentaire, parmi ceux que l'AC doit (devrait) faire. Les clients TLS ne sont pas censés le tester (ne serait-ce que parce que l'enregistrement CAA a pu changer depuis l'émission du certificat, la durée de vie de ceux-ci étant en général de plusieurs mois). CAA peut aussi servir à des auditeurs qui veulent vérifier les pratiques d'une AC (même avertissement : le certificat a pu être émis alors que l'enregistrement CAA était différent.)
La section 3 de notre RFC présente l'enregistrement CAA (la syntaxe détaillée est en section 5). Il a été ajouté au registre des types d'enregistrements sous le numéro 257. Il comprend une série d'options (flags) et une propriété qui est sous la forme {clé, valeur}. Un nom peut avoir plusieurs propriétés. Pour l'instant, une seule option est définie (un registre existe pour les options futures), « issuer critical » qui indique que cette propriété est cruciale : si on ne la comprend pas, le test doit être considéré comme ayant échoué et l'AC ne doit pas produire de certificat.
Les propriétés possibles sont, à l'heure actuelle (d'autres pourront être ajoutée dans le registre IANA) :
issue
, la principale, qui indique une
AC autorisée à émettre des certificats pour ce domaine (l'AC est
indiquée par son nom de domaine),issuewild
, idem, mais avec en plus la
possibilité pour l'AC d'émettre des certificats incluants des
jokers,iodef
, qui indique où l'AC doit envoyer
d'éventuels rapports d'échec, pour que le titulaire du nom de
domaine puisse les corriger. Un URL est
indiqué pour cela, et le rapport
doit être au format IODEF (RFC 7970).Voici par exemple quel était l'enregistrement CAA de mon domaine personnel :
% dig CAA bortzmeyer.org ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61450 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 7, ADDITIONAL: 7 ... ;; ANSWER SECTION: bortzmeyer.org. 26786 IN CAA 0 issue "cacert.org" bortzmeyer.org. 26786 IN CAA 0 issuewild "\;" ...
Il indique que seule l'AC CAcert peut
créer un certificat pour ce domaine (et sans les jokers). Bon, c'est
un peu inutile car CAcert ne teste pas les enregistrements CAA, mais
c'était juste pour jouer. Je n'ai pas mis d'iodef
mais il aurait pu être :
bortzmeyer.org. CAA 0 iodef "mailto:security@bortzmeyer.org"
Et, dans ce cas, l'AC peut écrire à
security@bortzmeyer.org
, avec le rapport IODEF
en pièce jointe.
Attention, l'enregistrement CAA est valable pour tous les
sous-domaines (et ce n'est pas une option,contrairement à, par
exemple, HSTS du RFC 6797, avec
son includeSubDomains
). C'est pour cela que
j'ai dû retirer l'enregistrement ci-dessus, pour avoir des
certificats pour les sous-domaines, certificats faits par une autre
AC.
Des paramètres peuvent être ajoutés, le RFC cite l'exemple d'un numéro de client :
example.com. CAA 0 issue "ca.example.net; account=230123"
Une fois les enregistrements CAA publiés, comment sont-ils utilisés (section 4) ? L'AC est censée interroger le DNS pour voir s'il y a un CAA (on note que DNSSEC est recommandé, mais n'est pas obligatoire, ce qui réduit le service déjà faible qu'offre CAA). S'il n'y en a pas, l'AC continue avec ses procédures habituelles. S'il y a un CAA, deux cas : il indique que cette AC peut émettre un certificat pour le domaine, et dans ce cas-là, c'est bon, on continue avec les procédures habituelles. Second cas, le CAA ne nomme pas cette AC et elle doit donc renoncer à faire un certificat sauf s'il y a une exception configurée pour ce domaine (c'est la deuxième faille de CAA : une AC peut facilement passer outre et donc continuer émettre de « vrais/faux certificats »).
Notez que le RFC ne semble pas évoquer la possibilité d'imposer la présence d'un enregistrement CAA. C'est logique, vu le peu de déploiement de cette technique mais cela veut dire que « qui ne dit mot consent ». Pour la plupart des domaines, la vérification du CAA par l'AC ne changera rien.
Notez que, si aucun enregistrement CAA n'est trouvé, l'AC est
censé remonter l'arbre du DNS. (C'est pour cela que SSL [sic]
Labs trouve un enregistrement CAA pour
mercredifiction.bortzmeyer.org
: il a utilisé
le CAA du domaine parent, bortzmeyer.org
.) Si example.com
n'a pas de CAA, l'AC va tester
.com
, demandant ainsi à
Verisign si son client peut avoir un
certificat et de qui. Cette erreur consistant à grimper sur l'arbre
avait déjà été dénoncée dans le RFC 1535, mais apparemment
la leçon n'a pas été retenue.
Enfin, la section 6 du RFC analyse les différents problèmes de sécurité que peut poser CAA :
Comme indiqué au début, le CA/Browser Forum a décidé que le test des CAA serait obligatoire à partir du 8 septembre 2017. (Cf. la décision.) Parmi les rares enregistrements CAA dans la nature, on trouve celui de Google, qui autorise deux AC :
% dig CAA google.com ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55244 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ... ;; ANSWER SECTION: google.com. 86400 IN CAA 0 issue "pki.goog" google.com. 86400 IN CAA 0 issue "symantec.com" ...
(Le TLD .goog
est
apparemment utilisé par Google pour son infrastructure,
.google
étant plutôt pour les choses publiques.)
Notez que gmail.com
, lui, pourtant souvent
détourné par des gouvernements et des entreprises qui veulent
surveiller le trafic, n'a pas d'enregistrement CAA.
Le célèbre SSL [sic] Labs teste la présence d'un
enregistrement CAA. S'il affiche « DNS Certification Authority Authorization (CAA) Policy found for
this domain », c'est bon. Regardez le
cas de Google.
Le type CAA est relativement récent (quatre ans quand même), donc il crée des problèmes amusants avec les serveurs DNS bogués comme ceux de BNP Paribas, qui timeoutent lorsque le type demandé n'est pas A :
% dig CAA mabanqueprivee.bnpparibas ; <<>> DiG 9.10.3-P4-Debian <<>> CAA mabanqueprivee.bnpparibas ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 42545 ^^^^^^^^
Quelques lectures et ressources pour finir :
urn:acme:error:caa
, « CAA record for
DOMAIN_NAME prevents issuance ».Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : F. Ljunggren (Kirei AB), AM. Eklund Lowinder (.SE), T. Okubo (ICANN)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 11 janvier 2013
Comme pour toutes les techniques de sécurité informatique, DNSSEC n'est efficace que si son déploiement s'accompagne de bonnes pratiques de sécurité. Il ne suffit pas de générer une clé et de signer la zone ! Pour prendre un exemple caricatural, si on signe sa zone DNS avec DNSSEC, mais que la partie privée de la clé est stockée, en mode 644 (lecture pour tous), sur un serveur sur lequel tous les employés du registre, les stagiaires et les consultants ont un compte, alors DNSSEC n'apportera guère de sécurité. Il est donc nécessaire de prendre certaines précautions. Un DPS (DNSSEC Policies and DNSSEC Practice Statement) est un document qui liste les politiques et les pratiques d'un utilisateur de DNSSEC, y compris ces précautions.
Il a deux usages principaux. L'un est plutôt externe, communiquer au reste du monde, notamment aux utilisateurs du nom de domaine en question, les pratiques du registre, pour que ces utilisateurs, le régulateur, les autorités de cyber-sécurité (comme l'ANSSI en France) et les autres parties prenantes puissent se faire une idée du niveau de sécurité de DNSSEC dans cette zone. Et le deuxième usage est plus interne, documenter des choix effectués. Si un DPS peut n'être vu que comme un exercice bureaucratique de plus, il peut aussi être une utile check-list pour s'assurer qu'on maîtrise bien tous les composants de la chaîne de sécurité et qu'on n'a rien oublié dans sa réflexion.
Ce RFC fait la liste de tout ce que peut contenir un DPS, de manière à guider les auteurs de tels documents. Par contre, il ne dit pas quels sont les bons choix (en partie parce que ceux-ci dépendent des caractéristiques particulières de la zone signée), cela sera « vous devez indiquer si vous utilisez NSEC ou NSEC3 », pas « NSEC3 est meilleur que NSEC ». Ce RFC s'inspire d'un document équivalent fait pour X.509, le RFC 3647 mais ne le copie pas, DNSSEC étant très différent de X.509.
En pratique, ce RFC sera sans doute surtout utilisé par les gérants de TLD mais il peut être utile à d'autres, notamment les zones les plus critiques, ou tout simplement ceux qui veulent améliorer leur sécurité (au prix d'un certain travail).
D'abord, une distinction entre politique DNSSEC (DNSSEC policy) et déclaration de pratiques DNSSEC (DNSSEC Practice Statement) en section 3 du RFC. La première est de plus haut niveau, plus générale, elle exprime le cahier des charges, ce qu'on veut atteindre comme objectif. Si une évaluation de la sécurité d'une zone est faite, par rapport à certaines menaces, c'est par rapport à cette politique DNSSEC. (La politique DNSSEC la plus simple est « on ne signe pas avec DNSSEC » mais elle est typiquement insuffisante face aux menaces d'aujourd'hui.) La seconde, la déclaration de pratiques DNSSEC, est plus concrète, décrivant les mécanismes qu'on déploie pour s'approcher de cet objectif. Si la politique DNSSEC dit ce qu'il faut faire, la déclaration de pratiques DNSSEC dit ce qui est fait. Attention, une déclaration de pratiques DNSSEC est typiquement un document public et on déclare donc ce qui est utile au public, et pas ce qui est confidentiel.
On notera que les deux documents peuvent être écrits par deux acteurs différents. On peut imaginer, par exemple, un régulateur écrivant la politique DNSSEC (les objectifs de sécurité) et le registre qui a obtenu la délégation de la zone écrivant la déclaration de pratiques DNSSEC (ce qu'il va faire pour atteindre ces objectifs).
La déclaration de pratiques étant plus concrète, elle est aussi plus détaillée et, typiquement, bien plus longue que la politique DNSSEC.
Si vous voulez voir des exemples de DPS existantes (je vais en
citer plusieurs, à titre d'exemple), l'ISOC
maintient une
bonne liste. Ce sont plutôt des déclarations de pratiques que
des politiques. On y trouve surtout des TLD
(j'ai utilisé pour les exemples la DPS de .FR
et celle de .NL
) mais
aussi des domaines comme
in-addr.arpa
(DPS du
RIPE-NCC en ligne
sur leur site) ou bien sûr comme la racine.
Notons qu'elles ne
sont pas forcément en anglais. Celle de
.CL
a deux versions mais
celle en espagnol est la seule à faire autorité.
Alors, justement, que peut-on mettre dans ces documents ? La section 4 fait la liste des points qu'il peut être souhaitable de couvrir. Je ne vais pas les répéter ici, consultez le RFC 6841 si vous voulez tout savoir. Parmi les points qu'on peut noter, l'importance d'identifier dans le document à qui il s'adresse (section 4.1.3) : au gouvernement, au régulateur, aux gérants des serveurs récursifs, aux titulaires de noms de domaine, à tous à la fois ?
Un sujet de discussion dans la communauté DNSSEC a toujours été la
publication des clés. DNSSEC reposant sur l'architecture arborescente
du DNS, il n'y a en théorie besoin de publier qu'une seule clé, celle
de la racine. Toutefois, on peut avoir de bonnes raisons de publier la
clé d'un sous-domaine, par exemple pour être indépendant de la racine,
ou bien parce qu'on a une relation plus forte avec le gérant de la
zone qu'avec celui de la racine. Pour prendre un exemple imaginaire,
on pourrait voir gouv.fr
signé et chaque
ministère mettre la clé de gouv.fr
dans ses
résolveurs, de manière à ce que la communication au sein du
gouvernement français ne dépende pas du tout d'une organisation
extérieure. Dans un cas comme celui-ci, la section 4.2.2 rappelle
qu'il faut inclure dans ses documents publics les mécanismes de
publication, et notamment la méthode que doivent utiliser les gérants
de résolveurs validant pour s'assurer de l'authenticité des clés
(récupération sur un serveur HTTPS, signature
des clés avec PGP, etc). D'autres informations
importantes peuvent être ajoutées comme la fréquence de renouvellement
des clés et la technique qui sera utilisée pour prévenir d'un tel
renouvellement. Par exemple, le .CL
utilise une
liste de diffusion
« NIC Chile mantendrá una lista de correo electrónico, de suscripción
pública, donde se anunciarán con anticipación los inicios y términos
de los rollovers de KSK: anuncios-dnssec@listas.nic.cl ».
À titre d'exemple, voyez la publication des clés
de la racine et sa
documentation, ou
bien celle de
.FR ou du RIPE-NCC. Au
contraire, les clés de .UK
ne font pas
l'objet d'une publication (à part dans le DNS).
La déclaration de pratiques doit exposer comment sont délégués les
enregistrements DS. DNSSEC ne servirait à rien
si, par exemple, on pouvait ajouter ou modifier une DS via un canal
non-sécurisé. De même, un registre peut avoir des méthodes pour tester
que la DS soumise l'a bien été par le gérant de la zone (par exemple,
Zonecheck, depuis la version 3, peut vérifier que la zone
est bien signée avec une clé correspondant à la DS indiquée). Ces
méthodes sont alors décrites dans ce document. Enfin, le document peut
indiquer comment on retire une DS de la zone (certains registres
peuvent le faire dès qu'un problème technique est signalé, rendant
alors la zone non sécurisée, mais, au moins, utilisable). Par exemple,
.FR
dit « Un enregistrement DS peut-être supprimé par une demande du bureau
d'enregistrement via EPP ou un formulaire web sécurisé par TLS. » mais
a aussi une possibilité de suppression par le titulaire « Un Titulaire d'un nom de domaine sous une extension géré par l'Afnic qui se
trouve incapable de joindre le bureau d'enregistrement correspondant à ce nom,
pourra utiliser une procédure exceptionnelle de suppression de DS, similaire à la
procédure de demande d'urgence du auth_info. ».
La sécurité n'est pas l'affaire que de technique. Les sections 4.4 et 4.5 rappelent qu'il y a aussi toute une organisation nécessaire et qu'elle aussi doit être décrite dans la document : accès physique aux locaux (si vous utilisez des empreintes rétiniennes, c'est là qu'il faut en parler, idem pour les autres mesures high-tech prises pour assurer la sécurité du système, bref tous les gadgets James Bond utilisés dans le registre), procédures à suivre pour les opérations, etc. Par exemple, il est fréquent que les opérations de sécurité (comme le démarrage du processus de signature) reposent sur un schéma « M parmi N ». Cela veut dire que N personnes sont habilitées à effectuer les opérations et que M d'entre elles (avec M ≤ N) doivent être présentes. La déclaration de pratiques DNSSEC est l'endroit où on donne les valeurs de M et de N (section 4.4.2).
Et comment décide-t-on que ces personnes sont « qualifiées » ? La
section 4.4.3 dit que cela doit être marqué noir sur blanc :
qualifications requises, enquêtes effectuées, sanctions prévues contre
les employés qui violent les procédures, etc. La racine va assez loin
dans l'examen de ses employés « Check of credit/financial
records to the extent allowed by national laws for the individual's
country of residence ». .FR
dit « Le recrutement interne ou externe est effectué par la fonction RH de l'Afnic, qui
vérifie les antécédents et les qualifications des candidats, prend en
compte : Le curriculum vitae des candidats, Emplois précédents,
Références, Les diplômes obtenus.
Pour être admissible à l'un des rôles de confiance, ces contrôles ne peuvent pas
révéler un critère d'incapacité. »
Et .NL
s'appuie
sur les mécanismes de certification du pays « All persons
that fulfill a role in the DNSSEC ceremony must have a "Certificate of
Good Conduct" ("Verklaring omtrent Gedrag") issued by the Dutch
government. ».
C'est aussi à cet
endroit qu'on devrait indiquer si les manœuvres de sécurité sont
effectuées uniquement par les employés du registre ou bien peuvent
l'être par le stagiaire envoyé par une
SSII. Ainsi, .NL
précise « No person outside of the specified Trusted Roles (4.2.1) can get access to the signer systems.If necessary, tasks
can be performed with the guidance of an external contractor. At no time is the contractor allowed to be the
person performing the tasks on the system. » alors que la racine est plus ouverte « In limited circumstances, independent contractors or consultants may
be used to fill Trusted Roles. Any such contractor or consultant is
held to the same functional and security criteria that apply to any
ICANN employees in a comparable role. Independent contractors and
consultants who have not completed or passed the background check
procedures specified in DPS section 4.3 are permitted access to
ICANN's secure facilities only to the extent they are escorted and
directly supervised by Trusted Persons at all times. ».
Au passage, la section 4.4.1 concernait les risques physiques. Aux Pays-Bas, comme leur nom l'indique, le
risque principal est l'inondation, ce qui explique cette mention dans
le DPS du RIPE-NCC : « Additionally, we have a back-up site outside of
Amsterdam at around 30 metres above sea level. » et, dans le
DPS de .NL
: « Several sites are located above sea level. ».
Les audits, pour vérifier si le système correspond réellement à ce qui est décrit dans la déclaration de pratiques DNSSEC, font l'objet de la section 4.7. Un avis personnel : comme toujours en sécurité, ils peuvent être traités comme un moyen concret de déterminer le vrai niveau de sécurité, ou bien simplement comme une série de processus, style ISO 27001, ayant peu de liens avec la réalité (« process over result »).
La génération des clés cryptographiques doit être particulièrement soignée (c'est souvent le point faible des processus cryptographiques). Chez les registres importants, elle fait en général l'objet de cérémonies solennelles, avec des auditeurs qui notent gravement toutes les étapes dans un gros livre, et deux caméras qui enregistrent le tout. La déclaration de pratiques DNSSEC doit indiquer comment se fait cette génération (sur un serveur Unix connecté à l'Internet ? au sein d'un HSM ?) et quelles précautions sont prises (la salle où se fait la génération est-elle une cage de Faraday, pour empêcher les attaques Tempest ?) Rappelez-vous, comme pour le reste de ce RFC, que ce RFC 6841 dit juste quels sont les points à couvrir, il ne prend pas position sur, par exemple, la question de savoir si un HSM vaut la peine ou pas. Le RFC dit juste « décrivez le système qui générera les clés ». La réponse « le responsable écrit à la main une série de chiffres sortis de sa tête, et qui lui semble cool et aléatoire » est acceptable, car elle permettra aux auditeurs de se faire une idée de la sécurité du système.
Une fois la clé générée, il faut garder en sécurité la partie
privée (section
4.5.2). La mettre dans un fichier en mode 0644 (lecture pour tous) sur
un serveur Web public (cf. section 4.5.6) est certainement une très mauvaise idée. Mais,
ensuite, il y a plusieurs choix possibles, le choix dépendant en
partie des moyens financiers du registre. Un fichier en mode 0600
(lisible uniquement par le propriétaire), propriété de
root, sur une machine
Unix bien gérée (cf. section 4.5.5), semble assez sûr mais il y a
des risques : si un attaquant vole la machine physique, il met le
disque dans une autre machine et il peut tout lire. Voilà pourquoi il
existe des boîtiers assurant une certaine protection contre le vol
physique. La norme FIPS-140 décrit leurs
différents niveaux. Il faut noter que ce n'est qu'à partir du niveau 4
que le boîtier est tamper-zeroize, c'est-à-dire
qu'il garantit l'effacement des clés en cas d'ouverture non
autorisée (« coupe le fil bleu »). Les HSM des niveaux 2 et 3 ne garantissent que la
résistance à l'ouverture (qui n'est jamais infinie) ou le
tamper-evident (si quelqu'un a ouvert le boîtier,
cela se verra). Il faut donc prêter attention, pas juste à l'étiquette
FIPS-140 mais aussi au niveau exact. Et, naturellement, comme toute
technique de sécurité, il faut une évaluation globale, pour s'assurer
de la cohérence du système. Il ne serait pas très utile d'avoir un HSM
FIPS-140 niveau 4 si la base de données du registre permettait à
n'importe qui d'écrire n'importe quoi dedans. Le RIPE-NCC dit « Systems used for signing the zones are FIPS 140-2 Level 2-certified » alors que la racine met la barre plus haut « For RZ KSK generation and RZ KSK private component operations and
storage, ICANN uses hardware security modules that are validated at
FIPS 140-2 level 4 overall. ». Même chose pour
.FR
: « Le Système utilise un module de Sécurité matérielle ( HSM ) conforme aux
exigences du standard FIPS 140-2 Niveau 4 ».
Le .CL
ne fait pas référence à FIPS-140 mais dit « La "máquina firmadora off-line" se encuentra en una caja fuerte bajo
control directo de NIC Chile, y los Ministros de Fe conocerán la
clave para abrirla. Cuando no esté en uso, la "máquina firmadora off-line" se mantendrá
en una bolsa sellada para asegurar que no ha sido intervenida. ».
Autres questions sur la gestion de la partie privée : y a-t-il un
séquestre ? Des
sauvegardes (si on n'en fait pas, on minimise
les risques de copie non autorisée mais on risque d'être très embêté en cas de
destruction accidentelle de la clé) ? Et, si oui, on veut bien des
détails. Pour .FR
, la DPS annonce « L`Afnic n'a
pas recours à l'entiercement des clés » et « Les clés créées sont :
recopiées en format chiffré sur les cartes de sauvegarde (SMK) spécifiques
au HSM exploité par l'Afnic. [...] Les clés sont sauvegardées de façon sûre et synchronisée après chaque
génération de clé. ».
L'activation de la clé privée, pour commencer les signatures, dépend souvent de choses que possèdent les personnes autorisées. Il faut donc écrire noir sur blanc ce que sont ces choses : une carte à puce ? Un PIN ? Une partie de la clé privée (pour les cas où elle est divisée) ? Plusieurs choses ?
Enfin, la journalisation correcte des
événements nécessite un estampillage temporel correct et la section
4.5.7 rappelle qu'il faut penser à décrire comment on obtient l'heure
et avec quel niveau de
sécurité. Le RIPE-NCC affirme « The signer systems securely sychronise their system clocks with a trusted time source inside our network ». Tout aussi vague, la racine dit « The ceremony administrator will manually set the signer
system clock and the wall clock to current UTC time drawn from a
reliable time source. ». Et .NL
: « The registry utilizes its default NTP-policy for timestamping. Time stamps are conducted using UTC and are
standardized for all log information and validity time for signatures. ». Bien sûr, aucune de ces trois déclarations n'est précise. Mais, bon, c'est une question
difficile quand on rédige une DPS : trop de détails, et on risque de
se lier les mains et de ne plus être à jour rapidement. Pas assez, et la déclaration
ne sert pas à grand'chose.
Tout aussi technique, la section 4.6 concerne le processus de
signature de la zone : quel algorithme de cryptographie utiliser
(aujourd'hui, c'est RSA pour l'écrasante
majorité des zones DNSSEC mais d'autres sont possibles, voir par
exemple les RFC 6605 et RFC 5933), quelle longueur pour les clés, quel
TTL pour les enregistrements, etc. On dit aussi ici
si on utilise NSEC ou NSEC3 (RFC 5155) pour
prouver la non-existence d'un nom. .NL
annonce
ses TTL ainsi « DNSKEY: 7200 seconds \
NSEC3: equal to minumum[sic] field of SOA record (RFC5155) \
RRSIG: equal tot[sic] TTL of RRset covered, 7200 in practice »
et la longueur « RSA algorithms with a key length of 2048
bits are currently used for KSK and 1024 bits for ZSK. ». La
racine dit « DNSKEY 48 hours \ NSEC same as SOA minimum (24
hours) \ RRSIG same as the covered RR (varies) ».
Un gros morceau de cette section est le problème récurrent du remplacement des clés. Le sujet est sensible mais, en tout cas, il faut documenter les choix effectués.
Et, comme la sécurité n'est pas une question purement technique,
que les registres peuvent avoir des obligations contractuelles, il
faut aussi penser aux risques légaux et (section 4.8) documenter
quelle est la loi qui s'applique au registre et ses éventuelles
obligations contractuelles. La racine dit « This DPS shall be
governed by the laws of the State of California » (problème
classique de gouvernance Internet, la racine,
ressource mondiale, est contrôlée par un seul État). Par contre, la
DPS de .JP
(dans sa
traduction anglaise non officielle) « When operating JP DNSSEC Service, the
Registry follows the laws of Japan and the rules defined by the
Registry (No English translation is available). ». Et celle de .FR
dit « La Loi française s'applique au présent document ».
La section 5 est simplement une suggestion de plan pour la rédaction d'une déclaration de pratiques DNSSEC. La plupart des déclarations que j'ai lues reprennent ce plan tel quel (certes, le RFC vient juste de paraître, mais il est issu d'Internet-Drafts bien plus anciens, le processus de publication ayant été très lent). Une étude faite au sein du CENTR en février 2011 a montré notamment que, sur les 19 registres répondants, 17 connaissait cet Internet-Draft et 13 l'avaient utilisé comme check-list pour écrire leur propre DPS.
Merci à Florian Maury pour sa relecture (ce qui ne veut pas dire qu'il est d'accord avec moi sur tout.)
Date de publication du RFC : Février 2013
Auteur(s) du RFC : S. Weiler (SPARTA), D. Blacka (Verisign)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 22 février 2013
DNSSEC, normalisé notamment dans le RFC 4033 et suivants, est une technologie très complexe et une erreur est vite arrivée lorsqu'on essaie de le mettre en œuvre. L'expérience de plusieurs programmeurs et de nombreux administrateurs système a permis de découvrir un certain nombre de faiblesses, voire de bogues, dans la spécification de DNSSEC et ce nouveau RFC rassemble des précisions et corrections. Leçon principale à en tirer : il n'y a pas que les logiciels qui ont des bogues, les normes aussi.
D'abord, des points qui étaient optionnels lors de leur
introduction mais qu'on doit maintenant, au vu de l'évolution du
monde, considérer comme faisant partie du cœur de DNSSEC, et sont donc
obligatoires. C'est le cas de NSEC3, introduit par le RFC 5155. Étant donné que des zones très importantes comme
.com
et
.fr
sont signées avec
NSEC3, un résolveur DNSSEC validant qui ne gérerait pas NSEC3 serait,
en 2013, bien inutile... Le RFC demande donc
que tous les résolveurs mettent en œuvre NSEC3. Notez que les anciens
noms d'algorithmes DNSSEC avaient
une version NSEC et une version NSEC3 mais ce n'est plus le
cas. l'algorithme 8, par exemple (RSA +
SHA-256), permet d'utiliser NSEC ou NSEC3.
À propos de SHA, notre RFC considère aussi que la famille SHA-2 (RFC 5702) est désormais obligatoire (elle est utilisée pour la racine donc un résolveur qui ne la connait pas n'irait pas bien loin).
Après cet ajout de nouvelles techniques cryptographiques, un mot sur le passage à l'échelle (section 3). Notre RFC demande désormais fortement que les résolveurs DNSSEC validants aient un cache des erreurs de signature. Si une signature est invalide, réessayer immédiatement ne sert qu'à charger le réseau inutilement : le problème ne va pas se résoudre seul. Un tel ré-essai ne peut mener qu'au « Rollover and die ». Le RFC 4035, section 4.7, permettait un tel cache mais il est désormais fortement recommandé.
Bon, venons-en maintenant aux bogues et problèmes, en section 4. Le RFC suit dans cette section 4 à peu près un plan d'importance décroissante : au début, les bogues graves, pouvant mener à des failles de sécurité. À la fin, les améliorations non-critiques. Pour commencer, les preuves de non-existence. L'algorithme donné en section 5.4 du RFC 4035 est incomplet. Mis en œuvre littéralement, il permettrait de valider la non-existence d'un nom avec un NSEC ou un NSEC3 situé plus haut dans l'arbre, même en dehors de la zone. La nouvelle formulation impose au résolveur validant de ne pas chercher de NSEC (ou NSEC3) au delà des frontières de zone.
Autre sous-spécification : lorsque la requête est de type
ANY
(on demande tous les types connus du
serveur), il est parfaitement légal de n'en renvoyer qu'une partie (un
serveur ne faisant pas autorité n'a pas forcément en cache tous les
enregistrements pour un nom donné, cf. section 6.2.2 du RFC 1034). Comment on valide cela ? Rien n'était dit
dans le RFC 4035. La nouvelle règle
est que, si un seul des ensembles d'enregistrements
(RRset) est invalide, toute la réponse doit être
considérée comme invalide. Mais, si tous les ensembles sont valides,
il ne faut pas pour autant que le résolveur croie qu'il a tout
obtenu.
Il y a aussi deux autres erreurs de sécurité corrigées par notre RFC. Et le RFC continue avec la section 5, les problèmes d'interopérabilité. D'abord, encore un problème posé par une règle qui, dans le RFC 1034 (section 3.1), semblait bien innocente, celle comme quoi les comparaisons de noms de domaines sont insensibles à la casse. Or, DNSSEC nécessite souvent des comparaisons et des tris (par exemple pour ordonner les noms pour NSEC). Le RFC 3755 disait « Embedded domain names in RRSIG and NSEC RRs [donc, dans la partie droite des enregistrements] are not downcased for purposes of DNSSEC canonical form and ordering nor for equality comparison » mais le RFC 4034 disait le contraire « all uppercase US-ASCII letters in the DNS names contained within the RDATA are replaced by the corresponding lowercase US-ASCII letters ». Les deux formulations sont acceptables mais il faut évidemment que tout le monde utilise la même. Et que faisaient les résolveurs, face à cette contradiction ? Eh bien, leurs auteurs avaient tranché en ne mettant en œuvre aucun des deux RFC (le RFC ne dit pas comment ces auteurs étaient arrivés à cet accord) : les noms dans la partie droite d'un NSEC ne sont pas convertis en minuscule, ceux dans la partie droite d'un RRSIG le sont. Le RFC 6840 entérine cette pratique en en faisant la nouvelle règle.
Autre problème d'interopérabilité. Le RFC 4035 est clair sur ce que doit faire un résolveur qui ne connait aucun des algorithmes utilisés pour signer une zone (par exemple parce que l'auteur de la zone a choisi uniquement des algorithmes très récents comme ceux du RFC 6605) : dans ce cas, la zone est considérée comme non signée. Mais si un enregistrement DS est condensé avec un algorithme de condensation non connu du résolveur ? Le cas n'était pas prévu mais il l'est désormais : le résolveur doit faire comme s'il n'y avait pas de DS (donc considérer la zone comme non signée).
Un cas plus fréquent en pratique est celui d'un ensemble d'enregistrements signés plusieurs fois, par exemple avec des clés différentes (certains mécanismes de remplacement de clés fonctionnent ainsi), ou bien avec des algorithmes différents (par exemple lorsqu'on déploie un nouvel algorithme pas encore très connu et qu'on garde donc des signatures faites avec l'ancien algorithme). Si ces signatures donnent des résultats différents (mettons que l'une est valide et l'autre pas), que doit faire le résolveur ? On peut imaginer deux politiques possibles, imposer que toutes les signatures soient valides (politique AND, la plus sûre) ou n'exiger qu'une seule signature valide pour être content (politique OR, celle qui créera le moins de problèmes). La section 5.3.3 du RFC 4035 renvoyait le problème au résolveur en disant qu'il choisissait librement sa politique de sécurité. Notre RFC 6840 tranche plus nettement : il faut utiliser la politique OR. Autrement, on ne pourrait pas introduire de nouveaux algorithmes cryptographiques. Et certains problèmes liés au moment exact où une donnée est introduite dans le cache du résolveur mènerait à des échecs de validation (par exemple, remplacement d'une clé, l'ancienne clé n'est plus disponible mais des signatures faites avec elle sont toujours dans le cache). D'autre part, une politique AND faciliterait certaines attaques par déni de service : un méchant n'aurait qu'à insérer des signatures bidon pour empêcher la validation. Enfin, personnellement, je rajoute que DNSSEC est assez compliqué comme cela, qu'il y a déjà suffisamment de problèmes et qu'une politique laxiste est plus raisonnable à l'heure actuelle.
Autre cas où les RFC originels sur DNSSEC n'avaient pas assez pinaillé dans les détails et avaient omis de spécifier des cas un peu exotiques : que doit-on faire si le bit AD (Authentic Data) est mis à 1 dans une question ? Désormais, cela a une sémantique précise : que le client DNS lit le bit AD, que sa valeur l'intéresse et que ce serait donc sympa de la part du serveur d'essayer de le déterminer. (C'est séparé du bit DO : le bit AD dans une requête n'implique pas qu'on veut recevoir toutes les données DNSSEC.)
Et le bit CD (Checking Disabled) dans les requêtes ? Désormais, la
règle est qu'il vaut toujours mieux le mettre à 1 lorsqu'on fait
suivre une requête, afin d'augmenter les chances d'obtenir toutes les
données disponibles chez le serveur en face. C'était une des deux
décisions les plus contestées de ce nouveau RFC (l'autre étant le cas
où plusieurs clés sont disponibles pour une zone). En pratique, cela n'a
d'importance que si on a plusieurs résolveurs à la queue-leu-leu, par
exemple avec la directive forwarders
de
BIND. Sans le dire clairement, le RFC 4035
semblait impliquer qu'il y ait au maximum un résolveur validant entre
le stub resolver et les serveurs faisant
autorité. Mais ce n'est pas toujours le cas. En suivant la nouvelle
règle de ce RFC (toujours mettre le bit CD à 1 lorsqu'on fait suivre
une requête), on simplifie : certes, il y a plusieurs validateurs sur
le trajet mais un seul, le premier, fera la validation. Cela rendra le
débogage des problèmes plus facile. L'annexe B décrit plus en détail ce problème et
ce choix. Elle présente des
politiques alternatives, avec leurs avantages et leurs
inconvénients. Notamment, mettre le bit CD à 1, dans certaines
politiques, dépend de s'il était à 1 dans la requête originale.
Encore un cas vicieux ? Vous aimez cela ? Alors, demandez-vous ce
que doit faire un résolveur validant avec DNSSEC lorsqu'il dispose de
plusieurs clés de confiance pour valider une zone. Mettons (exemple
purement théorique) qu'on ait
la clé publique de la racine et qu'on ait
installé celle de gouv.fr
car on est un ministère
et on veut pouvoir valider les domaines du gouvernement national sans
dépendre de la racine. Quelle clé utiliser pour valider
culturecommunication.gouv.fr
? Notre RFC ne
tranche pas : cela reste une question de politique de sécurité
locale (la question a été très disputée dans le groupe de travail et
aucun consensus n'est apparu). Mais le RFC recommande que cela soit configurable, avec l'option
par défaut la plus laxiste : « accepter n'importe quelle clé qui
marche ». (Avec cette politique, la validation n'échoue que si toutes
les clés échouent.) L'annexe C présente la liste des politiques
possibles, avec leurs avantages et inconvénients :
gouv.fr
de préférence à celle
de la racine, pour valider
culturecommunication.gouv.fr
). C'est la politique
la plus raisonnable pour les cas où, comme dans mon exemple
imaginaire, on a davantage confiance dans la clé située plus bas dans
l'arbre. Mais elle nécessite une grande rigueur dans la gestion des
clés des sous-zones. Si la clé de gouv.fr
change,
il faudra être sûr que tous les résolveurs gouvernementaux ont été mis
à jour. (En pratique, je conseille de n'avoir au maximum que trois
clés de confiance - incluant celle de la racine - et, de préférence,
une seule - celle de la racine. Au delà, on risque vraiment d'avoir un
jour ou l'autre une clé abandonnée.)J'avoue n'avoir pas testé avec des validateurs DNSSEC existants quelle était leur politique...
Voilà, bon courage aux programmeurs, ils ont désormais un RFC de plus à garder sous le coude lorsqu'ils créent un logiciel DNSSEC... Une bonne partie des règles de ce RFC sont déjà largement mises en œuvre dans les validateurs existants comme BIND ou Unbound.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : T. Hansen (AT&T Laboratories), A. Melnikov (Isode)
Pour information
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 30 janvier 2013
Tout le monde connait les « types de contenu » (media
types, aussi appelés types MIME pour
des raisons historiques), comme application/pdf
ou text/plain
. On sait qu'ils ont un
type (comme application
ou
text
, dans les exemples ci-dessus) et un
sous-type (pdf
ou
plain
ci-dessus) qui précise le format, à
l'intérieur de la catégorie définie par le type. On sait moins que le
sous-type peut avoir une structure : on peut voir un format générique
et un format plus spécifique, séparés par un +,
comme dans application/xhtml+xml
ou
image/svg+xml
. Cette structuration, introduite à
l'origine par le RFC 3023, pour XML,
est ici généralisée à d'autres formats et normalisée en détail. (Pour +xml
, une
mise à jour a été faite ensuite dans le RFC 7303.)
Cette technique vient du fait que certains formats ont deux
couches : un format décrivant la syntaxe de base et plusieurs formats
(plutôt appelés vocabulaires, ou même langages, dans le monde XML) qui
définissent des règles sémantiques différentes, mais tous utilisant la
même syntaxe de base. L'exemple typique est
XML. Ainsi, les fichiers
TEI (RFC 6129) sont en
XML et un processeur XML généraliste saura en faire quelque chose (par
exemple vérifier leur validité syntaxique). Mais TEI n'est pas que
XML : c'est aussi la définition d'un certain nombre d'éléments XML
légaux et de leurs relations (le schéma). Un
fichier TEI peut donc être étiqueté
application/xml
mais son type de contenu
officiel, application/tei+xml
, donne davantage
d'informations (cf. section 2, sur l'intérêt de ces suffixes). Si on
prend un autre vocabulaire XML, le Atom du RFC 4287, c'est aussi du XML mais les éléments
acceptés sont complètement différents. Son type de contenu aura donc
aussi le suffixe +xml
mais le type sera distinct,
ce sera application/atom+xml
.
La section 3 liste les sous-types à suffixe possibles (mais cette liste va grandir par la suite, cf. RFC 6838, section 6). Pour chaque suffixe, sont notamment indiquées les règles relatives à son encodage (pour savoir si la ressource doit être transportéee comme du texte ou comme du binaire), et les règles de sécurité. Parmi les suffixes possibles, il y a, entre autres :
+json
pour le format
JSON du RFC 7159. comme
vnd.oftn.l10n+json
(format de la bibliothèque
Javascript l10n) ou comme les réponses de l'API de GitHub. Comme XML, JSON peut être encodé en
UTF-8 (il est alors considéré comme texte,
cf. RFC 2045) ou
UTF-32 (il est alors vu comme du binaire).+ber
pour le format
BER et +der
pour le format
DER, tous les deux d'encodage
d'ASN.1 (norme UIT
ITU.X690.2008). Un exemple est dssc+der
, du
format du RFC 5698 (qui peut aussi se représenter en XML). À noter que BER
présente des risques particuliers en terme de sécurité. Encodage
TLV, il permet de construire des fichiers avec
des longueurs invalides, permettant de dépasser les limites des
données et de déclencher un débordement de
tampon chez des décodeurs naïfs. On peut aussi faire des
dépassements de pile puisque BER permet
d'emboîter des données récursivement.+fastinfoset
est la norme Fast Infoset, un encodage binaire de XML, qui ne semble pas
avoir été un grand succès (bien que résolvant un reproche parfois fait
à XML, celui que son encodage par défaut est trop bavard).+zip
est le fameux format de compression et
d'archivage ZIP. (Aucun n'a apparemment encore
été enregistré.)La section 4 reprend le suffixe +xml
, déjà
décrit dans le RFC 3023 et l'adapte aux exigences du RFC 6838.
Le registre IANA de ces suffixes est désormais en ligne.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : N. Freed (Oracle), J. Klensin, T. Hansen (AT&T Laboratories)
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 30 janvier 2013
Tout professionnel de l'Internet voit passer
les fameux types de contenu (media types, souvent
appelés types MIME) comme
audio/ogg
ou
text/json
. Comment sont enregistrés ces types ?
Suivant quelles procédures ? Si je veux un type pour mon super format
que j'ai inventé moi, comment je fais ? Ce nouveau
RFC, qui remplace l'ancienne norme (RFC 4288), donne la réponse à toutes ces
questions.
Ces types de contenu sont utilisés dans de nombreux protocoles multimédia. Les deux les plus connus sont HTTP et le format du courrier électronique (RFC 2045 et RFC 5322), le nom de « type MIME » venant d'ailleurs du courrier, même si ces types sont utilisés bien ailleurs. Lorsqu'un client HTTP interroge un serveur, celui-ci se sert ainsi de ces types pour lui indiquer le format des données envoyées :
% curl -v http://www.bortzmeyer.org/images/defile-fete-cheval-2008-4.png > /dev/null ... < Content-Length: 2094295 < Content-Type: image/png ...
Ces types sont composés de deux parties, le
type proprement dit et le sous-type,
séparés par une barre. Ainsi, dans le cas ci-dessus,
image/png
, le type est image
(une image) et le sous-type est PNG (le format
de l'image). Pour assurer l'unicité d'un type, ils sont enregistrés
à l'IANA et c'est la gestion de ce
registre qui est le cœur de ce RFC.
Les noms enregistrés sont regroupés en arbres,
un arbre étant identifié par une facette indiquée
dans le sous-type par le texte précédant le
point. S'il n'y a pas de point (comme dans tous
les exemples données jusqu'à présent), il s'agit de l'arbre standard,
qui stocke les noms d'intérêt général. Un exemple de nom dans un autre
arbre est image/vnd.microsoft.icon
qui est dans l'arbre « Vendeurs »
(vnd
) et désigne le format ICO.
L'enregistrement dans l'arbre standard est, comme on s'en doute, le plus difficile. Le format en question doit être normalisé par l'IETF ou une autre SDO reconnue par l'IESG (politique « Norme nécessaire » du RFC 5226). Un expert appointé par l'IANA est chargé de réviser ces enregistrements pour s'assurer que tout est complet. Au cas où un changement de l'enregistrement soit nécessaire, c'est la SDO originale qui peut seule décider (section 5.5).
Notez aussi que le sous-type doit normalement désigner un format
qui permette l'interopérabilité. Si un fichier
est étiqueté image/MACHIN
, un logiciel qui lit ce
format MACHIN doit pouvoir lire tous les fichiers de ce format, sans
que l'émetteur n'ait à s'angoisser sur les éventuelles variantes acceptées ou pas
(cf. section 4.5).
Après l'arbre standard, le plus important est sans doute l'arbre
« vendeur » (notez que le terme inclut les organisations
non-commerciales) où se trouvent les types liés à un fournisseur de
logiciel particulier. Les sous-types dans cet arbre commencent par la
facette vnd
comme par exemple
application/vnd.amiga.ami
. Le contrôle du changement, cette
fois, revient au vendeur en question (bien que l'enregistrement
lui-même puisse être fait par un tiers). À noter qu'aucune
vérification publique n'est nécessaire (ce sont des types pour un
produit privé, après tout) mais qu'une telle vérification est quand
même recommandée (sur la liste media-types
, voir
plus loin). Dans tous les cas, la demande sera examinée par l'expert
nommé par l'IANA.
Comme indiqué plus haut, « vendeur » (et son abréviation
vnd
) n'implique pas forcément une entreprise
commerciale. Par exemple, Debian a enregistré
vnd.debian.copyright
ce qui, au dire de Charles Plessy, le développeur Debian qui s'en est chargé, est
désormais très
simple avec la nouvelle procédure de notre RFC.
Et s'il n'y a pas du tout de vendeur, même pas une fondation ou
association établie ? Si Jean Durand, développeur avec un compte sur
GitHub, veut un type de contenu pour le format
d'images qu'il a développé ? Pas de panique, Jean peut utiliser
l'arbre « personnel ». Son sous-type aura alors la facette
prs
comme dans application/prs.plucker
. Comme pour l'arbre « vendeur », l'examen
public sur la liste media-types
est recommandé
mais pas indispensable.
Enfin, il y avait un arbre « privé » avec la facette
x
. Il n'y avait pas d'enregistrement dans cet
arbre, chacun pouvait y mettre ce qu'il voulait avec zéro
formalité. Ces préfixes X ayant créé quelques problèmes (collisions
entre deux noms, noms qui deviennent populaires et qui sont alors
« enregistrés de fait »), ils sont aujourd'hui abandonnés (RFC 6648) et l'utilisation de l'arbre
x
très découragée.
Bon, maintenant, je peux l'envoyer, ma demande à l'IANA, se demande notre programmeur qui veut enregistrer « son » type ? Pas encore, il faut encore lire toute la section 4 qui précise ce qu'on peut et qu'on ne peut pas enregistrer. Par exemple, le type doit désigner un format pas des trucs qui ressemblent à un format mais n'en sont pas comme un encodage de transfert. C'est pour cela qu'on ne trouvera pas Base64 dans le registre des types de contenu.
Les noms doivent évidemment obéir à la syntaxe standard (section
4.2) et audio/$%#&
n'est donc pas
acceptable. C'est d'autant plus vrai que certains protocoles qui
utilisent les types de contenu peuvent avoir des règles strictes sur
les caractères acceptés.
À noter que le sous-type peut avoir une structure : ainsi, les
sous-types XML peuvent s'écrire
FORMAT+xml
comme par exemple
application/svg+xml
pour
SVG. Cette structure (définie dans le RFC 6839, et comportant un format spécifique, un
plus et un suffixe qui indique le format général) permet de garder
toute l'information. Un logiciel générique XML peut ainsi faire
quelque chose d'un fichier SVG, même s'il ne connait pas SVG.
Depuis, d'autres formats ont suivi ce système (on trouve des
sous-types se terminant par +json
pour
JSON) et un registre de
ces formats génériques a été créé par le RFC 6839.
Il y a ensuite plein de règles spécifiques à certains types. Ainsi,
le type text
est conçu pour du contenu qui est
lisible par un humain, sans disposer d'un logiciel particulier. Pour le
logiciel qui reçoit un document, c'est une distinction importante : un
document text/UNKNOWN
où
UNKNOWN
est un sous-type inconnu, pourra toujours
être montré à l'utilisateur et ce sera mieux que rien. Avec les images (image/SOMETHING
)
ou le son (audio/SOMETHING
), cela n'aurait pas de sens.
C'est
ainsi que text/troff
(RFC 4263) désigne du texte formaté
avec troff ; si ce
format d'enrichissement prévoit quelques « décorations » au texte, il
reste néanmoins lisible sans processeur troff.
Le texte brut, sans aucun caractère spécial, est
text/plain
(RFC 2046). Tous
les sous-types de text/
peuvent avoir un
paramètre supplémentaire (voir la section 4.3 sur le concept de paramètres), charset
, qui indique à
la fois un jeu de caractères et un
encodage (le terme de
charset est donc malheureux mais il est trop tard
pour le changer). Les charsets sont eux-même
enregistrés en suivant le RFC 2978. Attention, certains
sous-types contiennent l'indication de charset dans
le texte lui-même (c'est le cas de XML) et ne
doivent donc pas utiliser le paramètre charset
(cf. RFC 6657). Dans tous les cas, s'il y a un
paramètre charset
, il doit dans la plupart des
cas désormais être obligatoire (pas de valeur implicite). Si, malgré
tout, une valeur par défaut est définie, cela doit être
UTF-8 (RFC 6657 qui a
remplacé l'ancienne règle, qui privilégiait US-ASCII).
image/
et audio/
ne
posent pas de problèmes particuliers. Par contre, pour
video/
, le RFC rappele qu'une vidéo inclut
souvent du contenu d'autres types (par exemple une piste audio
synchronisée) et que cela doit être pris en compte lorsqu'on
enregistre un sous-type.
Un type bien plus général, application/
, est
utilisé pour tout le reste. Ce sont les formats spécifiques à une
application, par exemple application/msword
pour le format privé de Microsoft Word, que
tant de gens s'obstinent à vous envoyer sans s'être demandé si vous
aviez payé votre taxe à Steve Ballmer. Mais
application/
sert aussi pour les cas où le format
n'est pas lisible directement (contrairement à
text/
) mais ne rentre pas dans les catégories
comme image/
ou
audio/
. C'est ainsi qu'il existe un
application/pdf
pour les fichiers
PDF.
Enfin, un type un peu spécial, multipart/
est
là pour le contenu composite (RFC 2046). Si le protocole permet de mettre
plusieurs objets de type différents dans un message, celui-ci va être
étiqueté multipart/QUELQUECHOSE
. On verra alors
multipart/signed
(deux parties, le contenu
lui-même et une signature, par exemple en
PGP), multipart/mixed
(plusieurs parties distinctes, chacune ayant son type et sous-type),
multipart/alternative
(plusieurs parties de sous-types
différents mais normalement équivalentes, le logiciel choisira le
format qu'il préfère), etc.
Le RFC prévoit la possibilité d'enregister de nouveaux types (et
pas seulement des sous-types). Il faudra pour cela un
RFC sur le chemin des normes et notre RFC 6838 prévoit qu'un tel enregistrement sera plutôt
rare. Un exemple est la création du type font/
par le RFC 8081.
Est-ce qu'un sous-type peut être enregistré pour un format
breveté ? Oui (autrement, on n'aurait pas
audio/mpeg
), mais en suivant les règles
habituelles de l'IETF, notamment de divulgation des brevets connus par
un participant (RFC 8179 et RFC 5378).
Il faut aussi penser à la sécurité (section 4.6). La demande
d'enregistrement d'un type de contenu doit comporter une section sur
la sécurité de ce format, indiquant quels sont les risques
connus. Quels formats peuvent créer des problèmes ? Ceux où le format
est en fait un langage complet, permettant des actions comme ouvrir un
fichier, sont les principaux. C'est ainsi
qu'application/postscript
a fait souvent parler
de lui (voir son analyse de sécurité détaillée dans la section 4.5.2
du RFC 2046). Un tel « contenu actif » est
toujours risqué.
Une fois qu'on a digéré toutes ces règles, ainsi que celles qui se
trouvent dans le RFC et que je n'ai pas reprises ici, on peut passer à
la rédaction de sa demande d'enregistrement d'un sous-type. La section
5 expose les procédures. La méthode canonique (mais il existe des
variantes) est de rédiger sa demande (le gabarit, qui précise quelles
informations doivent être données, figure en section
5.6), puis la soumettre d'abord
à la liste media-types@ietf.org
pour avoir un avis de la communauté. Ensuite, si l'enregistrement est
dans l'arbre standard, on envoie la demande à l'IANA qui vérifiera que
le format est bien décrit dans une norme stable (un RFC ou son
équivalent dans une autre SDO). Pour les autres
arbres, on écrit à l'IANA, ou bien on utilise le formulaire
Web. Les demandes seront ensuite examinées par l'expert
désigné, actuellement Ned Freed, avec Mark Baker en secours . Au cas où on n'aimerait pas sa décision,
on peut toujours tenter un appel auprès de
l'IESG.
Une autre procédure, en section 6, décrit le mécanisme
d'enregistrement des suffixes de sous-types (comme
+xml
ou +json
, voir le
registre, créé par le RFC 6839).
La nouvelle liste de discussion pour un
premier examen des demandes d'enregistrement a été créée le 17
septembre 2012. Elle se nomme media-types@ietf.org
et remplace l'ancienne ietf-types
.
Les amateurs d'histoire peuvent lire la section 1.1 de ce RFC :
elle rappelle la naissance de ces types de contenu, dans le seul
contexte du courrier électronique, lorsque
celui-ci est devenu multimédia, en 1992, avec
le RFC 1341. Notez que le courrier est
asynchrone. Cela veut dire qu'il n'est pas
possible de négocier un type de données entre les deux
machines. L'émetteur doit lancer son message sans connaître le
récepteur et étiqueter correctement le contenu est donc crucial. Pour
limiter les risques d'interopérabilité (l'émetteur choisit un type
très rare et le récepteur ne le connait pas), le choix avait été fait
de limiter sévèrement le nombre de types, par le biais d'une procédure
d'enregistrement très restrictive (RFC 2048,
puis son successeur le RFC 4288, voir aussi la
section 4.9 de notre RFC 6838). Aujourd'hui, les types sont souvent
utilisés dans des protocoles synchrones comme
HTTP, où la négociation est possible (le
serveur HTTP sait ce qu'accepte le client, grâce à l'en-tête
Accept:
), ces anciennes règles n'ont donc plus de
sens. D'où la libéralisation que marque notre nouveau RFC.
Outre celle-ci, les grands changements depuis le RFC 4288 sont (cf. annexe B) :
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : E. Lear (Cisco)
Expérimental
Première rédaction de cet article le 24 janvier 2013
Dès qu'on sépare, dans un protocole réseau, le localisateur de l'identificateur, on a créé la nécessité d'une base de données pour mettre les deux en correspondance : une fois qu'on a l'identificateur, il faut bien trouver le localisateur. Et cette base doit être accessible depuis le réseau. Le protocole LISP n'impose pas une base particulière : son architecture permet de tester plusieurs types de base et le système NERD (Not-so-novel EID to RLOC Database) est une de ces bases.
En pratique, LISP, décrit dans le RFC 9300, a un mécanisme de correspondance identificateur->localisateur favori, ALT (RFC 6836). Mais la base de données des correspondances est accédée via une interface standard (RFC 9301) et, derrière cette interface, on peut placer d'autres systèmes. NERD est nettement moins avancé qu'ALT (pas de mise en œuvre existante, juste un projet individuel) mais est intéressant parce qu'il explore une solution très différente. Le principe de NERD est de stocker la totalité des correspondances (ce n'est qu'un gros fichier, après tout, et relativement statique), et de la distribuer via les mécanismes habituels de distribution de fichiers (typiquement HTTP).
Question état d'avancement de NERD, il est amusant de noter que NERD était en fait le premier mécanisme de correspondance identificateur->localisateur proposé pour LISP. Pour diverses raisons, notamment organisationnelles à l'IETF, le RFC n'est publié que maintenant.
L'auteur estime que la méthode proposée fonctionne jusqu'à environ
cent millions d'entrées dans la base. Que devra contenir cette base ?
La correspondance entre les identificateurs (EID pour
endpoint identifiers) et les localisateurs (RLOC
pour routing locators). Qu'est ce que consulte un
routeur LISP lorsqu'il doit transmettre un paquet ? Ce paquet est à
destination de l'identificateur
2001:db8:1337::1:af
? Regardons dans la base des
correspondances, chic, on trouve que le localisateur correspondant en
192.0.2.254
. Encapsulons le paquet et envoyons-le
à 192.0.2.254
qui se débrouillera ensuite (et, au
passage, vous avez vu que les EID et les RLOC ont la forme physique
d'une adresse IP et qu'un EID
IPv6 peut avoir un RLOC
IPv4 et réciproquement).
La plupart des autres systèmes de base de données de correspondance sont « à la demande ». C'est lorsque le routeur doit transmettre un paquet qu'il va se mettre en chasse de la correspondance. L'inconvénient est que cela va prendre du temps et que le premier paquet d'une communication risque fort de ne pas patienter assez longtemps. La perte du premier paquet d'une session (typiquement un TCP SYN) est particulièrement gênante car l'application attendra longtemps. Avec NERD, au contraire, le routeur a en permanence toute l'information. (Ce point du « premier paquet perdu » est développé dans la section 7.2, qui explique en quoi NERD traite ce problème mieux que ALT.)
Pour concevoir NERD, l'auteur a supposé acquis les points suivants (section 1.1) :
Ensuite, NERD définit quatre choses :
Pour représenter les changements, un mécanisme aussi simple que le format patch traditionnel aurait pu être utilisé. Mais NERD utilise un format spécifique à la base de données LISP.
La section 2 explique comment fonctionne NERD :
openssl smime -binary -sign -outform DER -signer yourcert.crt -inkey yourcert.key -in database-file -out signature
.)openssl smime -binary -verify -inform DER -content
database-file -out /dev/null -in signature
). À
partir de là, le routeur LISP peut fonctionner, il connait les
correspondances identificateur->localisateur.Ainsi, un routeur d'entrée d'un tunnel LISP n'a jamais à attendre une résolution d'EID en RLOC. Il a toujours la totalité des informations. Ce gain en temps se paie par une consommation plus élévée de mémoire.
La section 2.3 discute qui pourrait être Autorité. NERD est compatible avec plusieurs mécanismes comme une Autorité unique et centrale (l'IANA ?), comme une oligarchie d'Autorités (les RIR), ou comme un système très décentralisé avec des tas d'Autorités différentes en concurrence.
Quant au format de la base, il figure en section 3. Il est fort simple, un en-tête avec les métadonnées. Parmi elles, la signature cryptographique au vieux format PKCS#7 du RFC 2315, un numéro de version permettant de voir si la base est plus récente qu'une copie locale, etc. Le format de la signature pourrait passer à CMS (RFC 5652) dans le futur. Le certificat doit contenir un DNS-ID (voir RFC 6125) qui sera le nom identifiant l'Autorité.
Et les données ? Une simple liste d'identificateurs (EID) suivi chacun d'une liste de ses localisateurs (RLOC), encodée dans un format binaire décrit en section 3.1. Les changements (section 3.2) suivent un format simple : si un EID a des RLOC, il est ajouté à la base (ou il remplace complètement les valeurs existantes, s'il y en avait : ajouter un seul RLOC à un EID nécessite donc de diffuser tous les RLOC), sinon (si sa liste des RLOC est vide), il est retiré de la base.
La section 4 spécifie les URL à utiliser. La
récupération initiale de la base
nerd.arin.net
, à partir d'un serveur
www.example.com
se fait avec
http://www.example.com/eiddb/nerd.arin.net/current/entiredb
et la récupération d'un changement se fait avec
http://www.example.com/eiddb/nerd.arin.net/current/changes/1105500
où 1105500 est le numéro de version de l'actuelle copie locale du
routeur. Si le serveur n'a pas les changements depuis 1105500 (par
exemple parce que c'est une trop vieille version), il a le droit de
faire une redirection HTTP vers une autre version. Le routeur aura
donc peut-être plusieurs étapes pour se mettre à jour. Attention, www.example.com
ne doit pas
mener à un identificateur LISP, sinon on rencontrerait un amusant
problème de circularité (voir aussi la section 8.1).
Est-ce réaliste en pratique ? La section 5 analyse quantitativement les « dépenses » liées à NERD. D'abord, la taille de la base. Elle dépend évidemment des hypothèses faites. Pour une hypothèse basse, 100 000 EID et une moyenne de 4 RLOC par EID, la base ferait dans les 9 méga-octets. Un bien petit fichier selon les critères d'aujourd'hui. Ceci dit, une hypothèse haute, avec 100 millions d'EID et 8 RLOC par EID donnerait une base de 17 giga-octets, nettement plus difficile à distribuer. Il est difficile de prévoir qu'elle est l'hypothèse réaliste. Par exemple, il y a aujourd'hui dans les 400 000 routes dans la table de routage globale, donc LISP, s'il est un succès, aura certainement plus de 400 000 EID. Le RFC compte sur un déploiement progressif, estimant que, même si l'hypothèse haute est atteinte, cela ne sera pas avant de nombreuses années, et les routeurs auront alors davantage de RAM.
Des calculs similaires donnent une idée du nombre de serveurs HTTP qui seront nécessaires pour distribuer une telle base, et ses changements, sans devoir attendre des heures.
Et pour jouer le rôle des Autorités ? Notez que ce RFC parle très peu de l'avitaillement de la base (enregistrement d'EID et changement de leurs RLOC). Voir les sections 2.3 et 5.4 qui donnent une idée de ce que serait le travail de ces Autorités et les caractéristiques (notamment de sécurité) qu'elles doivent avoir.
Les sections 6 et 7 sont consacrées aux alternatives non retenues. Pourquoi n'avoir pas utilisé XML pour le format ? (Principale raison : taille de la base, avec l'encodage habituel de XML.) Et pourquoi n'avoir pas spécifiéé d'autres mécanismes de distribution que ce système de miroirs HTTP ?
Un tel mécanisme aurait pu être celui de NNTP (RFC 3977). Il a largement montré ses capacités à distribuer rapidement une grande quantité de données et le RFC ne dit pas clairement pourquoi il n'a pas été retenu.
Plus éloigné du principe de NERD aurait été l'utilisation du DNS pour récupérer l'information de correspondance entre EID et RLOC. Les avantages du DNS sont que le partage administratif des responsabilités et l'infrastructure technique sont déjà en place. Il a déjà été envisagé de l'utiliser pour le routage (RFC 1383). Notre RFC suggère quelque chose du genre :
; Deux RLOC pour 10.0.128.0/23 $ORIGIN 0.10.nerd.arpa. 128 EID2RLOC mask 23 priority 10 weight 5 172.16.5.60 EID2RLOC mask 23 priority 15 weight 5 192.168.1.5
Mais le DNS n'est pas temps réel et, bien que cela ne soit pas forcément une gêne pour l'application (qui attend le résultat de la résolution DNS), c'est plus embêtant lorsque cette attente est dans le système de routage, laissant l'application dans l'ignorance de ce qui se passe. Et puis l'utilisation du DNS pour LISP ferait peser une contrainte sur les serveurs de noms (ne pas les numéroter avec des EID, qui obligeraient à avoir LISP pour trouver la base de données LISP).
Voilà, si vous aimez les jolis transparents avec des images et des citations érudites, l'auteur du RFC a mis en ligne son court exposé sur NERD.
Il n'y a apparemment pas de mise en œuvre de NERD aujourd'hui, ni côté Autorités, ni dans les routeur (les serveurs, eux, seraient des serveurs HTTP standard). Disons que NERD est une solution de rechange si ALT ou les autres mécanismes de correspondance ne tiennent pas leurs promesses. Après tout, LISP est expérimental...
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : V. Fuller (Cisco), D. Farinacci (Cisco), D. Meyer (Cisco), D. Lewis (Cisco)
Expérimental
Réalisé dans le cadre du groupe de travail IETF lisp
Première rédaction de cet article le 24 janvier 2013
Dans tous les systèmes de séparation de l'identificateur et du localisateur, le gros problème à résoudre est celui de la correspondance entre les deux. Sur le papier, cette séparation semble une idée simple et qui apporte des tas de bénéfices (multi-homing facile, plus besoin d'adresses PI, plus de rénumérotation des réseaux, etc), mais, dès qu'on rentre dans les détails, on se heurte au problème de la correspondance : comment trouver le localisateur lorsqu'on ne connait que l'identificateur, et de manière raisonnablement sécurisée ? Le protocole LISP a donc lui aussi ce problème et l'une des approches proposées (LISP est encore expérimental) est ALT (ALternative Topology) dont le principe est de créer un réseau virtuel des routeurs LISP, avec le mécanisme de tunnels GRE, leur permettant d'échanger en BGP ces informations de correspondance entre identificateurs et localisateurs. Avec ALT, route et résolution de noms sont fusionnés. De même que BGP dans l'Internet habituel peut être vu comme une résolution préfixe->nexthop, ALT est une résolution identificateur->localisateur faite en utilisant le routage.
Donc, le problème est le suivant : un ITR (premier routeur LISP qui traite un paquet) reçoit un paquet à destination d'un EID (un identificateur), il doit trouver l'ETR (dernier routeur LISP avant que le paquet ne repasse dans le routage habituel) à qui le passer et pour cela connaître son RLOC (le localisateur). Pour cela, l'ITR interroge un Map Resolver qui lui donnera la correspondance EID->RLOC. Mais comment le Map Resolver a-t-il trouvé l'information qu'il va servir ? Il existe plusieurs méthodes et notre RFC décrit l'une d'elles, ALT (ALternative Topology).
Pour éviter de réinventer la roue, ALT repose donc sur BGP (RFC 4271). Mais le protocole BGP n'est pas utilisé entre les routeurs habituels mais uniquement entre les routeurs ALT. Le réseau de ces routeurs est un réseau virtuel, construit avec des tunnels GRE (RFC 2784). Une fois le réseau virtuel, l'overlay, construit, les routeurs ALT vont se communiquer en BGP la liste des préfixes EID, qui va ainsi se propager partout. Les routes ainsi publiées mèneront à l'origine de l'annonce, un Map Server LISP qui connait l'ETR à qui demander la correspondance entre EID et RLOC. Notez donc bien qu'ALT ne distribue pas réellement les correspondances EID->RLOC mais les routes permettant de joindre celui qui connait la correspondance. Comme cela, il pourra recevoir une requête Map Request de LISP.
L'ITR typique, qui se retrouve avec un paquet IP destiné à un EID (l'identificateur) dont il ne connait pas le RLOC (le localisateur) ne fait en général pas partie de ALT. Il écrit à un Map Resolver (en utilisant l'interface standard décrite dans le RFC 9301) qui, lui, utilisera ALT (section 4.1). La réponse sera gardée dans un cache de l'ITR, pour accélerer les requêtes suivantes.
De même, ce n'est pas en général un ETR qui est membre de ALT pour diffuser les correspondances EID->RLOC mais un Map Server, auprès duquel les ETR enregistreront leurs préfixes.
Comme tous les protocoles de correspondance (par exemple le DNS), ALT réussit donc à résoudre le problème de l'œuf et de la poule : pour trouver un RLOC, on a besoin d'écrire à la machine qui le connait mais, pour cela, il nous faut son RLOC... Dans ALT, le problème d'œuf et de poule est résolu en créant ce réseau virtuel, qui ne repose que sur les EID (les identificateurs). Ce réseau virtuel ne sert qu'à la résolution d'identificateur en localisateur, il ne transporte pas de données.
On l'a vu, ALT réutilise des techniques très classiques et bien connues, déjà mises en œuvre dans tous les routeurs (BGP et GRE). Cela ne veut pas dire que les routeurs ALT seront les mêmes routeurs que ceux qui transmettent actuellement le trafic Internet. Bien au contraire, le RFC recommande de dédier des routeurs à cette tâche ALT.
Comme tous les RFC sur LISP, ce RFC 6836 rappelle que le protocole est expérimental. On ne sait pas encore trop comment LISP, et ALT, réagissent à des problèmes comme :
Bref, il y a besoin de pratiquer pour répondre à ces questions, et c'est la raison des déploiements actuels de LISP.
Donc, après ces principes de base, place à la construction et au fonctionnement de ALT. D'abord, révisons le vocabulaire (section 2). Les termes les plus importants :
Comment tous ces jolis sigles sont-ils utilisés ? La section 3 décrit le modèle ALT. Il reprend les mécanismes de LISP, Deux types de paquets LISP peuvent entrer dans le réseau virtuel ALT : les Map Requests, demande de résolution d'un EID en RLOC, et les Data Probes, équivalents aux précédentes mais incluant en plus des données à faire suivre (le but est d'éviter à un routeur de garder en mémoire les données en attendant la réponse à la requête de résolution).
Comment est-ce que les informations rentrent dans le système ? La méthode de loin la plus courante (façon de parler puisque LISP est encore très peu déployé, disons la méthode dont on pense qu'elle sera la plus courante) est pour les ETR d'enregistrer les EID dont ils ont la charge auprès d'un Map Server (RFC 9301), qui les propagera alors dans ALT. Mais on verra peut-être aussi des routes statiques depuis les routeurs ALT vers les ETR ou bien des montages plus exotiques.
Et, pour envoyer un paquet à destination d'un EID, lorsqu'on est ITR ? La méthode « la plus courante » est que l'ITR écrive à son Map Resolver, comme une machine Internet ordinaire écrit à son résolveur DNS pour trouver les adresses IP associées à un nom. Mais on aura peut-être la aussi des routes statiques (« si tu ne sais pas, envoie tous les paquets à tel ETR ») et d'autres configurations.
Donc, LISP n'impose pas un modèle unique mais recommande néanmoins fortement un modèle où les routeurs ALT sont au centre, communiquant entre eux, et où les ITR et ETR sont à l'extérieur de système de résolution, ne faisant pas d'ALT eux-mêmes mais transmettant les requêtes via les Map Resolver (questions des ITR) et les Map Server (réponses des ETR), dont les interfaces sont normalisées dans le RFC 9301. Un des avantages de ce modèle recommandé est qu'il permettra de tester d'autres systèmes que ALT et peut-être de le remplacer plus facilement (rappelez-vous que tout LISP est expérimental et que la partie « résolution d'identificateurs » est la plus expérimentale de toutes, donc très susceptible de changer).
Tout ce mécanisme ne gère pas le cas de la communication avec des sites non-LISP (tout l'Internet actuel) couvert dans le RFC 6832.
On l'a déjà dit, une des plus grosses discussions lors du développement de LISP avait été « le problème du premier paquet ». Lors d'une nouvelle connexion vers un identificateur, par exemple avec TCP, si le localisateur correspondant n'est pas dans les caches des routeurs, l'opération de résolution, a priori relativement lente, va obliger à garder le premier paquet dans les tampons de sortie du routeur, ou bien à jeter ce premier paquet. La première solution consomme de la mémoire et facilite les attaques par déni de service sur le routeur (un méchant pourrait commencer plein de connexions vers des EID injoignables, juste pour épuiser les ressources du routeur). La seconde est la seule réaliste (c'est ce qu'utilisent les routeurs du cœur de l'Internet pour les résolutions ARP, par exemple). Mais elle fait perdre un paquet crucial, celui d'ouverture de connexion. Cela obligera donc l'émetteur à attendre l'expiration d'un délai de garde, puis à réémettre, introduisant ainsi une latence considérable. C'est pourquoi des solutions où l'entiereté de la base des correspondances identificateur->localisateur serait gardée en mémoire de chaque routeur (ou, plus exactement, de chaque résolveur), avaient été proposées. ALT n'a pas suivi cette voie et propose donc autre chose : un type de paquets spécial, le Data Probe permet à la fois de demander une résolution (comme le fait un paquet Map Request) et de transmettre le premier paquet. Cette solution a été très contestée (elle viole le principe « le réseau virtuel ne sert qu'à la résolution ») et l'une des choses qui sera suivie avec le plus d'attention dans le déploiement de ALT est l'utilisation des Data Probes. La principale crainte est que ces Data Probes, potentiellement bien plus gros que les Map Requests soient un bon vecteur de DoS pour le réseau virtuel ALT, qui n'est pas du tout conçu pour un tel trafic (cf. section 3.3). Le RFC recommande donc que les Data Probes ne soient pas activés par défaut et que le réseau limite vigoureusement leur débit.
La section 4 détaille l'architecture de ALT, présentée plus haut. Le RFC présente ALT comme push/pull mais je le décrirai personnellement comme étant plutôt pull, comme le DNS, plutôt que push comme BGP. Pour tenir la charge dans un très grand réseau, une approche pull passe mieux à l'échelle. Dans ALT, la partie pull est la résolution elle-même (Map Request et réponse), la construction du réseau virtuel étant plutôt push.
Les tunnels sont construits avec GRE (RFC 2784) mais ce n'est pas fondamental pour l'architecture d'ALT,
qui pourrait utiliser d'autres types de tunnels dans le futur. (GRE
est faible, question sécurité, par exemple.) L'avantage de GRE est
qu'il est bien connu et bien maîtrisé. Deux routeurs ALT qui veulent
communiquer doivent donc créer un tunnel entre eux (ip
tunnel add tun0 mode gre remote 10.2.3.4 local 172.16.0.76 ttl
255
sur Linux, interface
tunnel 0 \
tunnel source 10.2.3.4 \
tunnel destination 172.16.0.76
sur un
Cisco, etc). Puis ils établissent une session
BGP au dessus de ce tunnel. Ces sessions devront utiliser des nouveaux
numéros de système autonome, pour éviter toute
collision avec le graphe BGP actuel, celui des routeurs du cœur
de l'Internet (section 6.1). Par contre, le RFC laisse ouverte la
question de savoir s'il faut un nouveau SAFI (Sub-Address
Family Identifier, RFC 4760, qui sert aujourd'hui à distinguer les
préfixes IPv4 de ceux IPv6). Cela serait souhaitable pour éviter qu'un
préfixe EID soit injecté accidentellement dans la
DFZ ou réciproquement. Mais cela compliquerait
le déploiement, surtout avec les anciens routeurs qui ne connaitraient
pas ce SAFI.
Comment sont alloués les identificateurs, les EID ? Attribués de manière hiérarchique, comme les adresses IP d'aujourd'hui, ils sont relativement statiques. On ne change pas d'EID quand on change d'opérateur réseau, par exemple. La topologie d'ALT, fondée sur les EID, n'a donc rien à voir avec celle de l'Internet, fondée sur les adresses IP avant LISP, et sur les localisateurs (RLOC) une fois LISP déployé. Et elle est bien plus stable. Des phénomènes ennuyeux du monde BGP comme le route flapping (un routeur qui annonce et retire frénétiquement un préfixe, faisant ainsi travailler tous les routeurs de la DFZ avant d'être amorti) seront donc probablement rares dans ALT (section 7.3).
Une note personnelle de
gouvernance
au passage : cela veut dire que la hiérarchie dans ALT ne suit pas des
relations de business et il n'est donc pas sûr que
l'agrégation de plusieurs préfixes EID dans un même Map
Server se passe bien, puisque ces préfixes sont alloués à
des organisations n'ayant aucun point commun (même pas le même
opérateur). C'est clairement une des questions les plus ouvertes
d'ALT, à l'heure actuelle (section 7.4). Si un routeur ALT a reçu de l'information
sur les EID 10.1.0.0/24
,
10.1.64.0/24
, 10.1.128.0/24
et 10.1.192.0/24
, peut-il et doit-il agréger en
un seul 10.1.0.0/16
?
Les fanas de sécurité liront avec intérêt la section 10, qui lui est entièrement consacré. En gros, ALT a la même sécurité que BGP. Il a donc les mêmes vulnérabilités (un routeur ALT méchant peut annoncer n'importe quel préfixe EID, même s'il ne lui « appartient » pas) et on peut envisager les mêmes solutions (comme la protection des sessions BGP du RFC 5925, et pourquoi pas, demain, BGPsec).
Sinon, si vous êtes plus intéressé par les performances que par la sécurité, vous pouvez consulter un exposé sur l'évaluation des performances d'ALT,
Il existe apparemment trois mises en œuvre différentes de ALT, dont une dans les routeurs Cisco.
Parmi les alternatives à ALT, il y a plusieurs propositions en cours de discussion à l'IETF, avec des jolis noms comme CONS, NERD ou DDT. Une solution évidente aurait été de choisir plutôt le système de correspondance le plus utilisé actuellement dans l'Internet, le DNS. Il existe des problèmes techniques avec le DNS mais la principale raison pour laquelle il n'a même pas été sérieusement considéré est que les gens qui travaillent quotidiennement sur des routeurs, et qui ont l'habitude de BGP et autres protocoles de routage, ne connaissent pas le DNS et ne l'aiment pas (ils l'assimilent souvent à un service de couche 7, loin de leurs problèmes opérationnels et envahis d'avocats). Comme tous les choix techniques, celui du système de correspondance a donc également une forte composante culturelle.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : D. Farinacci, D. Meyer (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF lisp
Première rédaction de cet article le 24 janvier 2013
De même que dig est la référence, connue de tous, des outils de débogage du DNS, le nom de lig va peut-être devenir célèbre dans le monde des opérateurs réseaux. lig est également un outil de débogage : il sert à interroger la base de correspondance identificateur->localisateur du protocole de routage LISP (RFC 9300, et sans lien avec le langage de programmation).
En quoi consiste LISP ? C'est une architecture de séparation de l'identificateur et du localisateur sur l'Internet (RFC 9300). Actuellement, l'adresse IP sert à deux choses : elle identifie une machine unique dans l'Internet (identificateur), et elle indique où envoyer les paquets à destination de cette machine (localisateur). LISP sépare ces deux fonctions. Et, comme toute architecture de séparation identificateur/localisateur, LISP nécessite une correspondance (mapping) entre les deux. Si on n'a que l'identificateur (EID - Endpoint ID - dans la terminologie LISP), il faut trouver le localisateur (RLOC - Routing Locator - en termes LISP) pour pouvoir envoyer les paquets. C'est le rôle du système de correspondance. Et lig permet d'interroger cette base de correspondances, pour voir son contenu et déboguer ainsi des problèmes.
Il existe plusieurs systèmes possibles pour cette correspondance,
comme les très expérimentaux CONS ou NERD. Mais
le plus répandu est le système officiel,
ALT (RFC 6836). Comme il existe un protocole standard de
communication avec le système de correspondance, « LISP Map-Server »
(dont l'interface est normalisés dans le RFC 9301), lig va pouvoir
interroger tous les systèmes, ALT et les autres. Voici un exemple simple, où on demande le RLOC de l'EID 153.16.4.1
:
% lig 153.16.4.1 Send map-request to eqx-ash-mr-ms.rloc.lisp4.net for 153.16.4.1 ... Received map-reply from 216.129.110.58 with rtt 0.11500 secs Mapping entry for EID '153.16.4.1': 153.16.4.0/24, via map-reply, record ttl: 1440, auth, not mobile Locator State Priority/Weight 216.129.110.58 up 1/100
Et on trouve que c'est 216.129.110.58
, qui va donc recevoir les paquets encapsulés à destination de 153.16.4.1
.
Pour suivre le RFC, ou même simplement cet article, il vaut mieux apprendre par cœur le vocabulaire, en section 2. Les termes que je trouve les plus importants :
La section 3 donne le principe général de fonctionnement de lig et sa syntaxe. lig se comporte un peu comme un ITR qui a reçu un paquet IP dont la destination est un EID, et qui se demande à quel RLOC envoyer le paquet. lig prend donc en argument un EID, fabrique un paquet LISP de type Map-Request, l'envoie, et attend une réponse Map-Reply. Là, contrairement au routeur, il se contentera d'afficher cette réponse à l'utilisateur. Il indiquera également le RTT de la requête et l'état de l'ETR (LISP surveille en permanence l'état des tunnels, cf. RFC 9300, sections 10 et 11 « Reachability », pour éviter d'envoyer les paquets à un trou noir).
Outre l'EID, lig prend deux paramètres optionnels, l'EID source (au
cas où la réponse en dépendrait) et l'adresse d'un Map-Resolver à
interroger (dans le premier exemple, le résolveur était indiqué via la variable d'environnement LISP_MAP_RESOLVER
).
On peut se servir de lig, comme dans l'exemple plus haut, pour savoir quel est le localisateur d'un EID donné, mais on peut aussi l'utiliser pour se liguer soi-même, en interrogeant les serveurs pour vérifier que le site où on est a bien enregistré son préfixe EID.
La section 4 présente les deux implémentations de lig
actuelles. Celle présente dans les routeurs
Cisco (dans des versions expérimentales du
code, seulement) est en section 4.1. La syntaxe générale (où les
crochets indiquent une mention facultative) et où les termes entre chevrons sont des variables) est
lig <destination-EID> [source <source-EID>] [to
<Map-Resolver>]
. Un exemple d'utilisation, tiré du RFC, est :
router# lig abc.example.com Send map-request to 10.0.0.1 for 192.168.1.1 ... Received map-reply from 10.0.0.2 with rtt 0.081468 secs Map-cache entry for abc.example.com EID 192.168.1.1: 192.168.1.0/24, uptime: 13:59:59, expires: 23:59:58, via map-reply, auth Locator Uptime State Priority/Weight Packets In/Out 10.0.0.2 13:59:59 up 1/100 0/14
Et si on veut tester son propre EID (se liguer soi-même), sans avoir à le taper, on peut remplacer le
<destination-EID>
par
self
(ou self6
pour
IPv6). Par exemple :
router# lig self Send loopback map-request to 10.0.0.1 for 192.168.2.0 ... Received map-reply from 10.0.0.3 with rtt 0.001592 secs Map-cache entry for EID 192.168.2.0: 192.168.2.0/24, uptime: 00:00:02, expires: 23:59:57 via map-reply, self Locator Uptime State Priority/Weight Packets In/Out 10.0.0.3 00:00:02 up 1/100 0/0
En section 4.2 figure la version en logiciel libre de lig, qui tourne notamment sur machines
Unix et est disponible en https://github.com/davidmeyer/lig
. Sa syntaxe est un peu
différente, lig [-m
<Map-Resolver>] <destination-EID>
. Elle ne permet pas de sélectionner
l'adresse source. Voici un exemple sur une machine
Debian :
% lig -m l3-london-mr-ms.rloc.lisp4.net 153.16.10.254 Send map-request to l3-london-mr-ms.rloc.lisp4.net for 153.16.10.254 ... Received map-reply from 173.36.254.163 with rtt 0.23900 secs Mapping entry for EID '153.16.10.254': 153.16.10.0/24, via map-reply, record ttl: 1440, auth, not mobile Locator State Priority/Weight 173.36.254.163 up 1/100
On y voit que les paquets à destination de l'EID
153.16.10.254
doivent être encapsulés dans LISP
par l'ITR
et transmis à l'ETR en 173.36.254.163
. Si vous
essayez avec une adresse qui n'est pas un EID,
vous recevez une réponse négative (Negative cache entry) :
% lig -m l3-london-mr-ms.rloc.lisp4.net 10.1.2.3 Send map-request to l3-london-mr-ms.rloc.lisp4.net for 10.1.2.3 ... Received map-reply from 195.50.116.18 with rtt 0.01200 secs Mapping entry for EID '10.1.2.3': 10.1.0.0/16, via map-reply, record ttl: 15, not auth, not mobile Negative cache entry, action: forward-native
Et si vous ne recevez rien :
% lig -m l3-london-mr-ms.rloc.lisp4.net 153.16.10.254 Send map-request to l3-london-mr-ms.rloc.lisp4.net for 153.16.10.254 ... Send map-request to l3-london-mr-ms.rloc.lisp4.net for 153.16.10.254 ... Send map-request to l3-london-mr-ms.rloc.lisp4.net for 153.16.10.254 ... *** No map-reply received ***
Alors le plus probable est que vous êtes derrière un pare-feu fasciste qui bloque les réponses. Pensez à autoriser le port UDP 4342, par exemple sur Linux :
# iptables --insert INPUT --protocol UDP --sport 4342 -j ACCEPT
(ou peut-être, sur un pare-feu avec état, l'état
RELATED
mais je n'ai pas testé.)
tcpdump ne connait pas encore LISP donc vous ne
verrez que deux paquets non analysés (notez que la réponse est venue
d'une autre adresse IP que celle interrogée...) :
14:56:11.873961 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 88) 217.70.190.232.50793 > 206.223.132.89.4342: UDP, length 60 14:56:12.051870 IP (tos 0xc0, ttl 110, id 31203, offset 0, flags [none], proto UDP (17), length 80) 173.36.254.162.4342 > 217.70.190.232.57375: UDP, length 52
On peut aussi
utiliser un looking glass (cf. section 5) comme
http://lispmon.net/lig.cgi
, pour interroger sur un EID
particulier. Si on veut une vision générale de l'état de LISP, on peut
regarder http://www.lisp4.net/status
(état des
résolveurs) et http://www.lisp4.net/lisp-site
(liste de
sites LISP et de résolveurs).
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : V. Fuller, D. Farinacci (cisco)
Expérimental
Réalisé dans le cadre du groupe de travail IETF lisp
Première rédaction de cet article le 24 janvier 2013
Comme pour tous les protocoles de séparation de l'identificateur et du localisateur, le nouveau-né LISP, normalisé dans le RFC 6830, doit faire face au problème de la correspondance (mapping) entre les deux informations. Comment trouver un localisateur, en ne connaissant que l'identificateur ? LISP n'a pas encore de solution ferme, bien qu'un protocole, ALT, normalisé dans le RFC 6836, ait été choisi pour l'instant. Comme il y a une probabilité non négligeable que LISP change de protocole de correspondance, voire en utilise plusieurs en parallèle, la stabilité du logiciel des routeurs imposait une interface stable avec le système de résolution des identificateurs en localisateurs. C'est ce que fournit notre RFC 6833, qui spécifie l'interface, vue du routeur, et qui ne devrait pas changer, même si ALT était remplacé par un autre système de correspondance/résolution. (Ce RFC a depuis été remplacé par le RFC 9301.)
LISP prévoit deux sortes de machines impliquées dans la résolution d'identificateurs (les EID) en localisateurs (les RLOC). Ces deux machines sont les Map-Resolver et les Map-Server. Pour ceux qui connaissent le DNS, on peut dire que le Map-Server est à peu près l'équivalent du serveur faisant autorité et le Map-Resolver joue quasiment le même rôle que celui du résolveur. Toutefois, il ne faut pas pousser la comparaison trop loin, LISP a ses propres règles. Pour résumer en deux phrases, un routeur LISP d'entrée de tunnel (un ITR), ayant reçu un paquet à destination d'une machine dont il connait l'identificateur (l'EID), va interroger un Map-Resolver pour connaître le localisateur (le RLOC, auquel l'ITR enverra le paquet). Pour accomplir sa tâche, le Map-Resolver fera suivre les requêtes au Map-Server, qui la transmettra finalement au routeur de sortie du tunnel (l'ETR), qui est la vraie source faisant autorité.
C'est entre le Map-Resolver et le Map-Server que se trouvent les détails du système de correspondance. Ils peuvent être connectés par ALT (RFC 6836, actuellement le mécanisme « officiel »), par CONS (RFC pas encore publié), par NERD (idem) ou bien par tout autre système de résolution, existant ou encore à créer (ils ne peuvent pas être connectés avec simplement LISP, puisqu'on aurait alors un problème d'œuf et de poule, LISP ayant besoin de ALT qui aurait besoin de LISP...). Rappelez-vous que notre RFC 6833 ne décrit qu'une interface, celle des ITR et ETR avec les Map-Resolver et Map-Server. Il est donc relativement court.
Comme avec toute technique nouvelle, il est prudent d'apprendre le
vocabulaire (section 2, puis section 3 pour un survol général du système). Il y a
deux types d'acteurs, les Map-Server et les Map-Resolver que nous avons déjà vu, et trois types de messages,
Map-Register
(un ETR l'envoie au Map-Server pour
indiquer les RLOC des EID dont il est responsable), Map-Request
(un
ITR l'envoie à un Map-Resolver pour obtenir les RLOC ; le Map-Resolver fait suivre
jusqu'au Map-Server, puis à l'ETR) et enfin Map-Reply
,
la réponse au précédent. Notons que ces types de messages ont leur
description complète (avec leur format) dans le RFC 6830. Notez aussi que Map-Resolver et Map-Server sont des fonctions, et
que les deux peuvent être assurée par la même machine, qui serait à la
fois Map-Resolver et Map-Server (dans le DNS, un tel mélange est déconseillé).
La section 4 de notre RFC plonge ensuite dans les
détails. Accrochez-vous. Voyons d'abord le premier routeur LISP que
rencontrera le paquet. On le nomme ITR pour Ingress Tunnel
Router. Les routeurs précédents traitaient l'adresse de
destination du paquet comme une adresse IP
ordinaire. L'ITR, lui, va la traiter comme un identificateur (EID pour
Endpoint IDentification). L'EID n'est pas routable
sur l'Internet.Il faut donc encapsuler le paquet en LISP pour
l'envoyer dans le tunnel. La nouvelle adresse IP de destination est le
localisateur (RLOC pour Routing LOCator). Pour trouver le
localisateur, l'ITR va demander à un ou plusieurs Map-Resolver. Il a été
configuré (typiquement, à la main) avec leurs adresses IP (qui doivent être des localisateurs,
pour éviter un amusant problème d'œuf et de poule; notez que
plusieurs Map-Resolver peuvent avoir la même adresse, grâce à l'anycast). L'ITR ne
connait que le protocole de résolution, envoi d'une
Map-Request
et récupération d'une
Map-Reply
(en termes DNS, l'ITR est un
stub resolver). L'ITR ne connait donc
pas les protocoles utilisés en interne par le
système de correspondance, il ne connait pas ALT (ou ses
concurrents). Cette communication avec le Map-Resolver peut être testée et
déboguée avec l'outil lig (RFC 6835).
La réponse du Map-Resolver ne sera pas forcément positive. L'ITR recevra
peut-être une
Negative-Map-Reply
, envoyée en réponse si un Map-Resolver ne trouve
pas de localisateur pour l'identificateur qu'on lui a passé. Cela veut
dire que le site final n'utilise pas LISP, et qu'il faut alors router
le paquet avec les méthodes habituelles
d'IP. (Il n'est évidemment pas prévu que tout
l'Internet passe à LISP du jour au lendemain, le routeur LISP doit
donc aussi pouvoir joindre les sites non-LISP.)
Si la réponse est positive, l'ITR peut alors encapsuler le paquet et le transmettre. Comment le Map-Resolver a-t-il trouvé la réponse qu'il a envoyé ? Contrairement aux routeurs LISP comme l'ITR, le Map-Resolver et le Map-Server connaissent le système de correspondance utilisé (si c'est ALT, ils sont tous les deux routeurs ALT) et c'est celui-ci (non traité dans ce RFC) qu'ils utilisent pour savoir s'il y a une réponse et laquelle.
Et, à l'autre bout du tunnel, que s'était-il passé ? Le routeur de
fin de tunnel (l'ETR, pour Egress Tunnel Router),
avait été configuré par un administrateur
réseaux avec une liste d'EID dont il est responsable. Pour
que le reste du monde connaisse ces EID, il les publie auprès d'un
Map-Server en envoyant à ce dernier des messages
Map-Register
. Pour d'évidentes raisons de
sécurité, ces messages doivent être authentifiés (champ
Authentication Data
du message
Map-Register
, avec clés gérées à la main pour
l'instant, avec SHA-1
au minimum, et le SHA-256 de préférence), alors que les
Map-Request
ne l'étaient pas (la base de données
consultée par les routeurs LISP est publique, pas besoin
d'authentification pour la lire, seulement pour y écrire). Ces
Map-Request
sont renvoyés périodiquement (le RFC
suggère toutes les minutes) pour que le Map-Server sache si l'information
est toujours à jour. Ainsi, si un ETR est éteint, l'information
obsolète dans les Map-Server disparaîtra en trois minutes maximum (des
messages peuvent être perdus, le RFC demande donc de patienter un peu
en cas de non-réception). Cela veut aussi dire que LISP ne convient
pas forcément tel quel pour les situations où on exige une mobilité
très rapide.
Notez que je ne décris pas tous les détails (comme la possibilité pour un ETR de demander un accusé de réception au Map-Server, chose que ce dernier ne fait pas par défaut), voyez le RFC si vous êtes curieux.
Arrivés là, nous avons un Map-Server qui connait les EID que gère
l'ETR. Désormais, si ce Map-Server reçoit une demande
Map-Request
, il peut la faire suivre à l'ETR (si
vous connaissez le DNS, vous avez vu que le
Map-Register
n'est pas tout à fait l'équivalent
des mises à jour dynamiques du RFC 2136 : avec
ces dernières, le serveur de noms qui a reçu la mise à jour répondra
ensuite lui-même aux requêtes). Le Map-Server ne sert donc que de relais, il
ne modifie pas la requête Map-Request
, il la
transmet telle quelle à l'ETR. Le rôle des Map-Resolver et des Map-Server est donc
simplement de trouver l'ETR responsable et de lui faire suivre (sans
utiliser l'encapsulation LISP) les requêtes, pas de répondre à sa
place. Cela se fera peut-être dans le futur lorsque des mécanismes de
cache seront ajoutés. Pour le moment, les Map-Resolver
n'ont pas de cache, grosse
différence avec le DNS (section 3). La
question, qui a suscité beaucoup de discussions dans le groupe de travail,
est laissée pour des études futures.
La section 5 couvre les questions encore ouvertes. LISP étant un protocole expérimental, celles-ci sont nombreuses. Par exemple, les paramètres quantitatifs (fréquence des enregistrements, limites de retransmission, durée de vie des informations) sont actuellement fixés de manière un peu arbitraire. Le niveau de sécurité des enregistrements doit-il être durci, ou au contraire est-il déjà trop élevé pour être facilement déployable ? Ces questions ne pourront recevoir de réponse ferme qu'avec l'expérience en production.
La section 7 fait le tour des questions de sécurité liées au service de résolution. Celles-ci ont été chaudement discutées dans le groupe de travail mais le problème reste très ouvert. Comme les requêtes sont faites avec le format de paquets de LISP, elles héritent des services de sécurité de LISP comme le nonce qui permet de limiter les risques d'usurpation. Par contre, comme pour les protocoles utilisés dans l'Internet actuel, il n'y a pas de vraie protection contre les annonces faites à tort (un Map-Server qui annoncerait un EID qui n'est pas à lui). C'est un problème très proche de celui de la sécurité de BGP et qui utilisera peut-être le même genre de solutions.
Le RFC dit qu'il existe quatre mises en œuvre. Outre l'outil de débogage lig (RFC 6835), il y a celle de Cisco pour ses routeurs, mais je ne connais pas les autres, sans doute dans des Unix.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : D. Farinacci (cisco), V. Fuller (cisco), D. Meyer (cisco), D. Lewis (cisco)
Expérimental
Réalisé dans le cadre du groupe de travail IETF lisp
Première rédaction de cet article le 24 janvier 2013
Le protocole LISP (qui n'a rien à voir avec le langage de programmation du même nom), vise à résoudre un problème documenté dans le RFC 4984 : les difficultés que rencontre le système de routage de l'Internet devant les pressions imposées par la croissance du réseau, et par le désir des utilisateurs de ne pas être lié à un unique fournisseur d'accès. Actuellement, tout changement de routage sur n'importe quel site se propage à tous les autres routeurs de la DFZ. Un tel système ne passe pas réellement à l'échelle (il ne peut pas croitre indéfiniment). LISP propose une solution (expérimentale, à l'époque), dans un ensemble de RFC dont ce RFC 6830 est le principal. Depuis, il a été remplacé par le RFC 9300.
Avant de plonger dans ce RFC, voyons les motivations pour LISP et ses principes essentiels (si vous préférez les lire dans le RFC et pas dans mon article, c'est en section 4). Aujourd'hui, les adresses IP ont deux rôles, localisation (où suis-je connecté au réseau) et identité (qui suis-je). Une adresse IP est un localisateur car changer de point d'attachement (par exemple parce qu'on change de FAI) vous fait changer d'adresse IP, et c'est un identificateur car c'est ce qui est utilisé par les protocoles de transport comme TCP pour identifier une session en cours : changer d'adresse IP casse les connexions existantes.
Le principal problème de cet approche concerne le routage. Un routage efficace nécessiterait une cohérence entre les adresses et la topologie du réseau, par exemple que deux sites proches sur le réseau aient des adresses proches. Mais on n'a pas cette cohérence actuellement. On notera qu'IPv6 ne résolvait pas ce problème, et délibérement (le cahier des charges d'IPv6 ne prévoyait pas de changer le modèle de routage).
Résultat, les routeurs doivent gérer bien plus de routes que nécessaire, augmentant leur prix (en attendant le jour où, même en payant, on n'arrivera pas à manipuler autant de routes, avec leurs changements fréquents). Le RFC 4984 insistait sur ce problème en affirmant que « The workshop participants believe that routing scalability is the most important problem facing the Internet today and must be solved, although the time frame in which these problems need solutions was not directly specified. »
Cette croissance de la table de routage peut être suivie sur le célèbre site de Geoff Huston. Notez que la taille n'est pas le seul aspect, le rythme de changement (le nombre d'updates BGP par seconde) est au moins aussi important.
LISP vise donc à résoudre ce problème par une technique connue sous le nom de séparation du localisateur et de l'identificateur (son nom, « Locator/ID Separation Protocol », en dérive d'ailleurs, bien qu'il soit loin d'être le seul protocole dans cette catégorie). Au lieu que tous les préfixes IP aillent dans la DFZ, seuls les localisateurs, les RLOC (Routing LOCators) y iront. Les identificateurs, les EID (Endpoint IDentifiers) seront dans un nouveau système, le système de correspondance (mapping), qui permettra de trouver un RLOC à partir d'un EID. LISP est donc l'application d'un vieux principe de l'informatique : « Tout problème peut être résolu en ajoutant un niveau d'indirection. »
À quoi ressemblent RLOC et EID ? Physiquement, ce sont juste des adresses IP (v4 ou v6), avec une nouvelle sémantique.
Par rapport aux autres solutions de séparation de l'identificateur et du localisateur (la plus achevée étant HIP), LISP s'identifie par les points suivants :
Comment se passe l'envoi d'un paquet avec
LISP ? Supposons qu'une machine veuille écrire à
www.example.com
. Elle utilise le
DNS comme aujourd'hui, pour trouver que
l'adresse est
2001:db8:110:2::e9
(c'est un EID, un
identificateur, mais la machine n'a pas besoin de le savoir, les
machines terminales ne connaissent pas LISP et ne savent même pas
qu'elles l'utilisent). Elle envoie le paquet à son routeur habituel. À
un moment dans le réseau, le paquet va arriver dans un routeur LISP
(qui, lui, a été modifié pour gérer LISP). Il va alors chercher le
RLOC (le localisateur). Il demande au système de correspondance
(l'équivalent LISP du DNS) qui va
lui dire « le RLOC de 2001:db8:110:2::e9
est
198.51.100.178
» (notez au passage que RLOC et
EID peuvent être des adresses v4 ou v6). (L'information est stockée
dans un cache du routeur, pour le prochain paquet.) Le paquet est alors
encapsulé dans un paquet LISP qui est transmis
en UDP (port 4341)
à 198.51.100.178
. (En raison de ces deux étapes,
correspondance puis encapsulation, LISP fait partie des protocoles
nommés Map and Encap.) 198.51.100.178
décapsule et le
paquet suit ensuite un chemin normal vers la machine
2001:db8:110:2::e9
. Pendant le trajet dans le
tunnel, le paquet aura donc deux en-têtes,
l'interne (celui placé par la machine d'origine
et qui utilise des EID dans les champs « Adresse IP source » et
« Adresse IP destination »)
et l'externe (celui placé par le routeur d'entrée du tunnel, et qui
utilise des RLOC).
Si le système de correspondance avait répondu négativement « Ce
n'est pas un EID, je n'ai pas de RLOC pour
2001:db8:110:2::e9
» (Negative map reply) ? Cela aurait voulu dire que
le site cible n'utilise pas LISP et, dans ce cas, on lui transmet le
paquet par les mécanismes habituels d'IP.
Ainsi, pour prendre le scénario d'usage principal de LISP, un site qui veut être multi-homé n'aura pas besoin de BGP et d'annoncer ses routes dans la DFZ. Il aura ses identificateurs, ses EID, et les paquets entrant ou sortant de son réseau seront encapsulés en LISP (le système de correspondance peut renvoyer plusieurs RLOC pour un EID, avec des préférences différentes, pour faire de l'ingénierie de trafic). Pour les routeurs de la DFZ, ce seront juste des paquets IP ordinaires. Seules les deux extrémités du tunnel sauront que LISP est utilisé.
Le système de correspondance de LISP n'est pas encore définitif : plusieurs choix sont possibles mais il existe un système privilégié, ALT (RFC 6836). Comme le DNS, il fonctionne en tirant les informations nécessaires (pas en les poussant vers tout le monde, comme le fait BGP), ce qui devrait lui donner une bonne capacité de croissance. De toute façon, LISP spécifie une interface vers le système de correspondance (RFC 6833) et les différents systèmes ont juste à mettre en œuvre cette interface pour qu'on puisse en changer facilement. Ainsi, ALT pourra être remplacé par un de ses concurrents, CONS, EMACS ou NERD (leurs noms sont des références au langage de programmation). NERD est documenté dans le RFC 6837.
LISP est aujourd'hui essentiellement promu par Cisco, qui a monté un réseau mondial de test, qui compterait 140 sites. LISP est considéré comme expérimental, comme l'indique le statut de ce RFC (et la section 15 de notre RFC, qui liste les problèmes connus). Ses effets sur l'Internet ne sont pas encore complètement maîtrisés. LISP est à l'heure actuelle un protocole très controversé. (Ces avertissements ont été ajoutés au document peu de temps avant son adoption comme futur RFC.)
Ce RFC est un gros morceau (d'autant plus que d'autres parties de LISP sont dans d'autres RFC). Je ne vais pas le couvrir en entier. Mais quelques points méritent d'être gardés en tête :
Pour les fanas de format de paquets, la section 5 décrit l'encapsulation. LISP est indépendant de la famille d'adresses, donc on peut avoir un paquet IP où les EID sont IPv4 qui soit tunnelé avec des RLOC IPv6 ou bien le contraire. Devant le paquet normal, LISP va ajouter un en-tête IP standard pour les RLOC, où la source sera l'ITR (routeur d'entrée du tunnel) et la destination l'ETR (routeur de sortie du tunnel), puis un en-tête UDP (l'UDP a davantage de chances de passer les middleboxes que de l'IP mis directement dans l'IP), avec le port de destination à 4341, puis un en-tête spécifique à LISP et enfin le paquet original. Donc, pour résumer :
L'en-tête spécifique à LISP contient notamment (section 5.3 si vous voulez tout connaître) :
Comme toutes les solutions à base de tunnel, LISP va souffrir de la mauvaise gestion de la PMTUD dans l'Internet d'aujourd'hui (cf. RFC 4459), l'en-tête LISP supplémentaire réduisant la MTU (cf. section 5.4 pour des solutions possibles).
La section 5 décrivait les paquets de données, ceux encapsulant les données envoyées par le site original. La section 6 couvre les paquets de contrôle, utilisés par LISP pour ses propres besoins, notamment le système de correspondance (cf. RFC 6833 pour les détails). On y retrouve l'utilisation d'UDP :
Il est évidemment essentiel qu'on sache si son correspondant est joignable ou pas. Comment cette « joignabilité » est-elle vérifiée ? La section 6.3 énumère les mécanismes disponibles. Entre autres :
Mais on peut aussi tester explicitement, par le mécanisme Echo Nonce de la section 6.3.1. Le testeur émet un message LISP avec les bits N (numnique présent) et E (écho demandé), met le numnique à une valeur aléatoire (RFC 4086), et envoie le paquet. L'ETR à l'autre bout doit normalement renvoyer ce numnique dans son prochain paquet. Notons que cela teste la bidirectionnalité de la connexion. Si on n'obtient pas de réponse, cela peut signifier que la connexion est complètement coupée ou tout simplement qu'elle ne marche que dans un seul sens. Mais, surtout, l'absence de réponse peut indiquer le cas où l'ETR qui reçoit le trafic pour un site n'est pas le même routeur que l'ITR qui génère le trafic sortant. Dans ce cas, l'absence de réponse n'est pas un problème. Enfin, le routeur en face peut tout simplement être configuré pour ignorer les demandes d'écho.
Une autre solution pour tester est donc d'utiliser les messages du système de correspondance EID->RLOC, les Map Request et Map Reply. Ces messages ont un bit P (pour probe) qui indique que le demandeur est intéressé par la joignabilité du site demandé.
LISP impose donc des traitements supplémentaires, par rapport à ceux de l'IP classique. Est-ce que cela ne ralentit pas trop les routeurs ? La section 7 explore le problème et explique pourquoi LISP ne nécessite pas de changement du matériel de forwarding (les ASIC du routeur). La plupart des routeurs ont déjà du code prévu pour gérer des tunnels (encapsuler et décapsuler) rapidement.
Comment sera déployé LISP ? La section 8 décrit plusieurs scénarios possibles mais il faut regarder le futur RFC sur le déploiement de LISP pour avoir les détails. Principal problème : combien d'ITR et d'ETR pour un opérateur ? Grâce aux tunnels, on peut n'avoir qu'un seul ITR et un seul ETR pour tout le trafic. Cela poserait évidemment des problèmes de redondance et de performance. Mais avoir beaucoup de xTR peut poser des problèmes d'administration. Si les ITR sont largement automatiques (leur cache des correspondance EID->RLOC est bâti dynamiquement), avoir beaucoup d'ETR risque d'être compliqué à maintenir (car l'ETR doit avoir dans sa configuration une liste des EID qu'il va gérerà).
On peut aussi se demander si le premier routeur LISP utilisé par les clients doit être dans le réseau du FAI ou bien s'il ne devrait pas être dans le CPE (section 8.3).
Toujours dans la série des problèmes pratiques, que devient l'indispensable outil de débogage traceroute (section 9) ? Si les routeurs ne faisaient rien de spécial, un traceroute depuis un site LISP vers un autre montrerait le tunnel entre l'ITR et l'ETR comme un seul saut. Pour qu'on voit les routeurs dans le tunnel, il faut que LISP bricole un peu : les messages ICMP time exceeded générés dans le tunnel arriveront à l'ITR (c'est son adresse qui est la source des paquets encapsulés). L'ITR doit donc, pour faire des jolis traceroute, regarder le contenu du message ICMP, extraire le message original et donc l'adresse originale, puis envoyer un ICMP Time Exceeded à la vraie source.
Ça, c'était pour IPv6. En IPv4, c'est un peu plus compliqué car le paquet ICMP d'erreur ne contient pas la totalité du message-sonde de traceroute, même pas le maximum possible. L'ITR doit donc maintenir un cache des requêtes traceroute qu'il voit passer, indexé par un numéro qui sera utilisé comme port source dans les requêtes encapsulées. Ainsi, lors de la réception du ICMP Time Exceeded, l'ITR pourra retrouver la vraie source.
Pour ceux qui s'intéressent à la question de la mobilité, la section 10 y est consacrée. Un des avantages de la séparation de l'identificateur et du localisateur est justement de faciliter la mobilité. Un site ou une machine peut garder son EID en changeant de RLOC. Plusieurs cas :
Un des gros problèmes que pose la séparation de l'identificateur et du localisateur est la sécurité : nouvelles attaques (par exemple contre le système de correspondance), nouveaux pièges (une machine qui utiliserait le vrai RLOC mais mentirait sur l'EID, par exemple), tout cela n'est pas encore bien connu et explique largement pourquoi les RFC sur LISP n'ont que le statut Expérimental. En attendant davantage d'expérience concrète , la section 12 examine les risques théoriquement présents dans LISP.
Comme avec toutes les techniques de tunnel, un émetteur peut facilement tricher sur l'adresse source interne (celle qui sera utilisée après décapsulation par l'ETR). Pour se protéger, un ITR devrait n'encapsuler un paquet que si l'adresse source est un EID qu'il contrôle. Et un ETR ne devrait transmettre un paquet que si la destination est un EID sous sa responsabilité.
Le test de la réversibilité (via les numniques, cf. section 3)) est essentiel contre ces risques. Sans ce test, un ETR pirate pourrait par exemple envoyer un Map Reply en réponse aveugle à un Map Request, et le voir accepté, avec des données mensongères (naturellement, l'ITR n'accepte que des Map Replies qui sont en réponse à un Map Request de sa part). Avec ce système de numnique que le récepteur doit mettre dans sa réponse, un attaquant aveugle (qui n'est pas situé sur le chemin des paquets et ne peut donc pas les observer) aura donc peu de chances de réussir à faire accepter ses paquets.
En revanche, un attaquant situé sur le chemin, et qui peut observer les paquets qui passent, a la possibilité de commettre bien plus de dégâts. Mais c'est déjà le cas avec les protocoles actuels (par exemple, les numéros de séquence difficiles à deviner du RFC 6528 ne protègent pas TCP contre des attaquants situés sur le chemin).
Les attaques par déni de service sont évidemment possibles avec LISP : une des précautions recommandées est de limiter le trafic des Map Requests et Map Replies. Autre attaque par déni de service, un ITR peut être victime d'une machine qui essaie de remplir la table des correspondances EID->RLOC du routeur. Il est donc important d'envisager ce cas, par exemple en permettant de garder dans le cache les entrées les plus fréquemment accédées (pour éviter qu'elles ne soient retirées automatiquement pour faire de la place). Mais il n'existe pas de solution miracle contre ce problème d'envahissement de cache.
On l'a dit, LISP a actuellement le statut Expérimental. La section 15 résume les problèmes connus à l'heure actuelle, et qui devront être traités pour obtenir un changement de statut :
Le fonctionnement de LISP est schématisé sur ce dessin :
Alice a l'identificateur (EID) 2001:db8:1::1
et
veut écrire à Bob qui a le 2001:db8:2::42
(dans
la plupart des cas, Alice aura trouvé l'adresse de Bob dans le
DNS, comme aujourd'hui). Ni
Alice, ni Bob n'ont à connaître LISP, chacun croit utiliser de l'IP
normal. Alice envoie donc un paquet standard, à destination de
2001:db8:2::42
. Mais, sur le trajet, il y a un
ITR, un routeur LISP. Celui-ci va chercher (dans le système de
correspondance, non montré ici) le RLOC (le localisateur) de Bob (ou,
plus exactement, de son site). Une fois qu'il a trouvé
2001:db8:ff::666
, il encapsule le paquet derrière
un en-tête LISP et envoie ce paquet à l'ETR, l'autre routeur LISP en
face,
2001:db8:ff::666
. Les routeurs de l'Internet,
entre l'ITR et l'ETR, ne connaissent pas LISP non plus et routent ce
qui leur semble un paquet IP normal. Arrivé à l'ETR, le paquet est
décapsulé et poursuit son chemin par du routage IP classique. Sur tout
le schéma, seuls l'ITR et l'ETR sont des nouveautés LISP.
Modifions légèrement le schéma pour y mettre le système de
correspondance :
On y voir l'ITR demander à son résolveur « Quel est le localisateur de
2001:db8:2::42
? » et son résolveur lui
répondre. Le résolveur avait demandé au serveur qui avait reçu de
l'ETR un enregistrement disans « Le localisateur de
2001:db8:2::42
est
2001:db8:ff::666
». Entre le résolveur et le
serveur se trouve le cœur du système de correspondance. LISP en
a plusieurs possibles, comme le ALT du RFC 6836.
Où trouve-t-on du code LISP aujourd'hui ?
Comme pour tous les protocoles fondés sur le principe de la séparation de l'identificateur et du localisateur, il est toujours utile, si on veut en comprendre les principes, de (re)lire l'article fondateur de Chiappa, « Endpoints and Endpoint names: A Proposed Enhancement to the Internet Architecture ». Autres articles à lire :
Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : E. Marocco, A. Fusco (Telecom Italia), I. Rimac, V. Gurbani (Bell Labs, Alcatel-Lucent)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF PeerToPeerResearchGroup
Première rédaction de cet article le 22 décembre 2012
Le trafic du pair-à-pair peut, on le sait, représenter une bonne part de l'activité d'un réseau, malgré les efforts de l'industrie du divertissement pour diaboliser cette technique. Il y a donc depuis plusieurs années de gros efforts de recherche pour optimiser ce trafic, notammment via l'amélioration de la sélection des pairs. Si je veux télécharger la saison 1 de Being human, et que trois pairs ont les données, auquel demander ? Le bon sens répond « au plus proche ». Mais le concept de « plus proche » est plus flou qu'il n'y parait, et, de toute façon, le logiciel pair-à-pair installé sur ma machine n'a pas forcément accès à toutes les informations nécessaires pour déterminer « le plus proche ». Il existe plusieurs solutions pour résoudre ce problème, mais notre RFC se penche plutôt sur le méta-problème : la sélection des pairs améliore-t-elle les choses ?
Tellement de choses ont été dites à ce sujet que l'ingénieur ou l'étudiant débutant qui se penche sur l'optimisation du pair-à-pair peut avoir une impression de grande confusion. Ce RFC choisit donc l'approche « retours aux faits ». Parmi toute la littérature scientifique et technique existante, peut-on trancher sur la question de l'intérêt de la sélection des pairs ?
Je préviens tout de suite que le titre de ce RFC, inutilement sensationnaliste, ne correspond pas à son contenu : le RFC ne dynamite pas de mythes, il examine un certain nombre de questions posées par la sélection des pairs et, pour chacune, en se basant sur des mesures ou des simulations déjà effectuées et publiées, fait une synthèse de leurs conclusions.
A priori, l'intérêt de la sélection est grand : comme les machines, dans un réseau pair-à-pair, ne connaissent pas la topologie sous-jacente (elles ne savent pas si les pairs sont proches ou lointains, s'ils sont joignables par des liens de peering gratuits ou par du transit payant, etc), elles risquent de ne pas choisir le meilleur pair. Une des conséquences fâcheuses sera l'utilisation d'inter-connexions lointaines, au lieu de rester dans le réseau du FAI. Il est donc logique que cette idée de sélection « intelligente » des pairs ait fait l'objet de nombreux travaux (résumés dans le RFC 6029 ; sinon, voir les articles « Can ISPs and P2P systems co-operate for improved performance? » d'Aggarwal, V., Feldmann, A., et C. Scheidler, ou « Taming the Torrent: A practical approach to reducing cross-ISP traffic in P2P systems » de Choffnes, D. et F. Bustamante, ou encore « P4P: Explicit Communications for Cooperative Control Between P2P and Network Providers » de Xie, H., Yang, Y., Krishnamurthy, A., Liu, Y., et A. Silberschatz) et qu'un groupe de travail de l'IETF, ALTO, travaille entièrement sur ce sujet (voir ses RFC 5693 et RFC 6708). (À noter que j'avais fait un exposé sur ces techniques en 2010.) L'évaluation de ces techniques n'est pas évidente, notamment de leur passage à l'échelle lorsque le réseau comprend des dizaines de millions de pairs.
Notre RFC suit le schéma suivant pour synthétiser la littérature existante :
Naturellement, cette synthèse n'est valable qu'aujourd'hui : les progrès de la science pourront changer les conclusions. Ah et, sinon, question terminologie, en l'absence d'une norme unique du pair-à-pair, ce RFC utilise largement le vocabulaire de BitTorrent (section 2), comme le terme d'essaim pour désigner un groupe de pairs ayant les données convoitées.
Place maintenant aux croyances et à leur évaluation. La première : « la sélection des pairs permettra de diminuer le trafic entre domaines ». Les différents essais ou simulations montrent des réductions allant de 20 à 80 % (la variation importante donne une idée de la difficulté à estimer cette réduction). 70 % pour la simulation de Xie, H., Yang, Y., Krishnamurthy, A., Liu, Y., et A. Silberschatz déjà citée. 34 % en sortie et 80 % en entrée pour les mesures du RFC 5632. Et jusqu'à 99,5 % si le trafic est fortement localisé (beaucoup de pairs dans le même domaine) selon « Pushing BitTorrent Locality to the Limit » de Stevens Le Blond, Arnaud Legout et Walid Dabbous.
Bref, cette croyance est tout à fait justifiée (comme la plupart de celles citées par le RFC). On peut vraiment espérer une réduction du trafic entre opérateurs.
Cette réduction profite aux opérateurs, qui voient baisser leur facture d'interconnexion. Une autre croyance fait espérer des gains pour les utilisateurs : « la sélection des pairs se traduira par une amélioration des performances », en clair, on attendra moins longtemps pour charger la dernière ISO d'Ubuntu.
Les simulations de Xie, H., Yang, Y., Krishnamurthy, A., Liu, Y., et A. Silberschatz montrent une diminution du temps de transfert de 10 à 23 %. Celles de « Applicability and Limitations of Locality-Awareness in BitTorrent File-Sharing » par Seetharaman, S., Hilt, V., Rimac, I., et M. Ammar (article que je n'ai pas réussi à trouver en ligne et qui ne semble pas avoir été publié « officiellement ») montraient que le gain n'est pas systématique. Les mesures du RFC 5632 indiquent une augmentation du débit de 13 à 85 %. L'expérience de Choffnes, D. et F. Bustamante déjà citée a vu 31 % de gain de débit en moyenne (mais une perte dans certains cas).
La conclusion est donc plutôt « ça dépend ». En général, il y a une amélioration mais dans certains cas (capacité du lien montant faible, peu de pairs disponibles à proximité), on peut voir une dégradation. Donc, la croyance est probablement justifiée mais pas dans tous les cas.
Et l'occupation du lien réseau montant ? Cela pourrait être un effet négatif d'une meilleure sélection des pairs. Ils sont plus proches, donc on envoie plus vite les données, saturant le canal montant, souvent très petit sur les liens asymétriques comme l'ADSL ou DOCSIS. Cette crainte est-elle justifiée ?
Les mesures du RFC 5632 ne montrent pas un tel effet. Théoriquement, cela serait pourtant possible (si la sélection des pairs menait à choisir une machine mal connectée mais proche plutôt qu'une machine lointaine et ayant de fortes capacités réseau, la machine mal connectée verrait son lien montant plus utilisé). Mais, en pratique, cela ne semble pas le cas.
Autre croyance parfois entendue : la sélection des pairs va avoir une influence sur les accords de peering. Ceux-ci sont souvent fondés sur le volume de trafic échangé. Si la sélection des pairs améliore la localité, le trafic entre opérateurs va baisser, le faisant passer en dessous du seuil qu'exigent certains opérateurs pour peerer avec eux. Mais, sur ce point, on ne dispose pas de mesures ou de simulations. On ne peut faire pour l'instant qu'une analyse théorique.
Par exemple, si les deux opérateurs ont une base d'utilisateurs très différente (mettons qu'un opérateur a beaucoup de clients offrant du contenu et l'autre pas du tout), non seulement le trafic entre eux va baisser, mais il peut baisser nettement plus dans une direction que dans l'autre, remettant en cause un accord de peering fondé sur la réciprocité.
Curieusement, le RFC affirme que, si les opérateurs sont très similaires (même base d'utilisateurs, mêmes technologies d'accès), il n'y aura sans doute pas beaucoup de changement. Pourtant, comme indiqué plus haut, la seule baisse du trafic entre eux, même symétrique, peut changer les conditions du peering.
Le RFC rappele que des opérateurs ont déjà tenté d'injecter des paquets vers un autre opérateur, pour obtenir artificiellement des chiffres élevés de trafic, avant de pouvoir demander un peering (« The art of Peering: The peering playbook » de Norton). Ce n'est pas très subtil car ce trafic purement unidirectionnel apparait vite comme suspect. En revanche, avec des techniques de sélection des pairs, le même FAI peu scrupuleux pourrait faire mieux, en redirigeant systématiquement ses utilisateurs vers l'opérateur avec qui il espère négocier un accord de peering, créant ainsi un trafic nettement plus réaliste.
En conclusion (fondée sur un raisonnement purement théorique, contrairement à la grande majorité des croyances étudiées dans ce RFC), il est probable que la sélection des pairs amène à changer les accords de peering.
Et sur le transit, y aura-t-il un impact ? Là aussi, on peut imaginer des transitaires peu scrupuleux qui, en utilisant les techniques de sélection de pairs comme ALTO, redirigeront le trafic vers des clients payants, plutôt que vers des opérateurs pairs gratuits. Là encore, on ne dispose pas d'études à ce sujet. Mais, vue l'importance de la question pour le monde des opérateurs, le RFC recommande que l'on se penche sur la question. Des cas comme Sprint contre Cogent ou Cogent contre AOL illustrent bien l'extrême sensibilité du problème.
Un effet de bord négatif d'une bonne sélection des pairs avait été envisagé dans l'article Stevens Le Blond, Arnaud Legout et Walid Dabbous ci-dessus (mais les mesures faites ne montraient pas cet effet). Si la sélection marche trop bien, l'essaim de pairs va se fragmenter en plusieurs essaims, un par FAI, avec peu de communications entre eux, ce qui annulerait une partie de l'intérêt du pair-à-pair. En effet, les simulations de Seetharaman, S., Hilt, V., Rimac, I., et M. Ammar ont montré que cela pouvait se produire.
Le RFC conclut que l'effet dépend de l'algorithme utilisé. Si BitTorrent semble assez résistant à ce problème, comme montré par les mesures de Stevens Le Blond, Arnaud Legout et Walid Dabbous, d'autres algorithmes peuvent avoir le problème. Et que la croyance peut donc être justifiée dans certains cas. Attention donc, si vous concevez un algorithme de pair-à-pair à ne pas mettre tous vos œufs dans le même panier en ne sélectionnant que des pairs très proches.
Dernière croyance étudiée, celle que des caches P2P chez les FAI, combinés avec la sélection des pairs, va améliorer les choses. Un problème classique de tous les caches réseau est de les trouver, et de ne les utiliser que s'ils apportent réellement un gain. Avec la sélection des pairs, le problème est théoriquement résolu : le cache est un pair comme un autre et est sélectionné s'il est « plus proche ».
Une étude chez un FAI a montré (« Are file swapping networks cacheable? Characterizing p2p traffic » de Nathaniel Leibowitz, Aviv Bergman, Roy Ben-Shaul et Aviv Shavit) que le cache pouvait potentiellement gérer 67 % du trafic pair-à-pair. Cette croyance est donc plausible.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : T. Narten (IBM), M. Karir (Merit Network), I. Foo (Huawei Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF armd
Première rédaction de cet article le 30 janvier 2013
Lorsque des dizaines de milliers, voire des centaines de milliers de machines, sont connectées au même réseau (ce qui peut être le cas dans un grand data center), certains protocoles TCP/IP, pas forcément prévus pour cela, peuvent avoir des problèmes. C'est le cas d'ARP et de NDP, protocoles utilisés pour trouver l'adresse MAC d'une machine voisine. ARP n'avait pas été prévu pour les data centers modernes et ses limites se font parfois sentir. ND pose pas mal de problèmes similaires. D'où ce document qui définit précisement le problème.
Il n'y aura par contre pas de solution de si tôt : le groupe de travail armd, qui devait travailler sur ce sujet, a été dissous immédiatement après avoir produit ce RFC de description du problème. Il ne semblait pas qu'il soit possible de travailler sur des solutions et l'IESG a donc choisi de dissoudre le groupe alors qu'il était loin du résultat. Il reste cet intéressant RFC 6820 qui sera lu avec plaisir par tous les passionnés de réseaux informatiques. (Un autre document, le RFC 7342, décrit les pratiques existantes.)
ARP (RFC 826) et
ND (RFC 4861) s'attaquent
tous les deux (le premier pour IPv4 et le
second pour IPv6) au problème de la résolution
d'adresses sur le réseau local. Une machine veut parler à une autre
machine dont l'adresse IP indique qu'elle est
sur le même réseau local. Pas besoin de
routage, donc, on peut lui envoyer directement
un paquet mais, pour cela, il faut d'abord trouver son
adresse MAC. ARP et ND procèdent de façon très
proche : ils diffusent un paquet à tout le
monde « qui est 2001:db8:1::af:41
? » et la
machine qui se reconnait répond. Cela veut dire que ce paquet de
demande va être transmis à toutes les machines du réseau local,
jusqu'aux routeurs qui marquent
la limite du « domaine de broadcast » (l'ensemble
des machines touchées par la diffusion « L2 », c'est-à-dire utilisant
les mécanismes de la couche 2). Des détails
comme les VLAN compliquent encore le
tableau. Pour notre RFC, un « domaine de broadcast
L2 » est l'ensemble des liens, répéteurs et
commutateurs traversés pour atteindre tous les
nœuds qu'on touche avec une diffusion.
(Il existe une légère différence entre ARP et ND, ND utilisant le multicast et pas le broadcast mais, en pratique, cela ne change pas grand'chose : ce point est traité plus loin.)
Depuis longtemps, on sait que les grands domaines de diffusion (réseaux « plats », sans routeurs) créent des tas de problèmes. La totalité des machines du réseau doit traiter les paquets de diffusion. Une machine méchante ou détraquée qui envoie des paquets de diffusion en boucle peut sérieusement perturber un réseau. Dans certains cas (« tempêtes de diffusion », provoquées par exemple par une boucle non détectée dans la topologie du réseau), ces paquets diffusés suscitent la création d'autres paquets diffusés et, là, on peut arrêter complètement le réseau. La sagesse des administrateurs réseaux est donc depuis longtemps « ne faites pas de grands domaines de diffusion ; partitionnez en mettant des routeurs au milieu »). Par exemple, si on architecture son data center en mettant un sous-réseau IP par armoire, la charge résultant d'ARP et de ND sera confinée à une seule armoire. Et les éventuelles tempêtes de diffusion resteront dans une armoire. Le problème est que cette configuration est plus rigide : avec les techniques de gestion modernes (buzzwords : cloud, élasticité, agilité, etc), on souhaite pouvoir déplacer une machine très facilement, sans la renuméroter. Les grands réseaux L2 plats permettent cela. Au contraire, les réseaux très partitionnés nécessitent de changer l'adresse IP de la machine selon sa position physique dans le data center, faisant perdre en souplesse de gestion. Même problème lorsqu'on veut ajouter des nouvelles machines : avec un réseau plat, on configure les machines et on les installe là où il y a de la place. Avec un réseau très partitionné, on doit les configurer en fonction de l'endroit où elles vont être installées, ajoutant ainsi une contrainte de gestion.
Et la virtualisation, très utilisée dans les data centers actuels, pousse encore plus dans ce sens. Avec la virtualisation, déplacer une machine ne nécessite même plus d'opérations physiques : on copie la VM, c'est tout. Si l'alimentation électrique d'une machine physique menace de défaillir, on copie toutes les VM hébergées dans l'armoire vers d'autres machines physiques, puis on peut arrêter l'armoire tranquillement. Une architecture où chaque armoire est son propre sous-réseau ne permet plus cela : changer d'armoire veut dire changer d'adresse IP, donc sérieusement impacter le service.
Autre conséquence de la virtualisation : le nombre de machines augmente. Il est courant aujourd'hui d'avoir plusieurs dizaines de machines virtuelles par machine physique. Demain, ce nombre sera probablement plus élevé. Les problèmes de passage à l'échelle d'ARP et de ND vont donc devenir plus aigus lorsqu'une VM émettra un paquet ARP qui devra être traité par des milions de machines situées dans le même data center (des data centers de 100 000 machines physiques existent déjà, ce qui fait bien davantage de VM).
Le désir de souplesse et d'agilité dans la gestion des machines virtuelles (VM) pèse aussi sur l'architecture du réseau : il est plus difficile de prédire les flux de données entre machines (ça change tout le temps) et on ne peut donc pas architecturer le réseau autour des flux d'aujourd'hui, par exemple pour conserver le trafic à l'intérieur d'une seule armoire, ou pour éviter de passer par plusieurs commutateurs.
Les sections 4 et 5 se penchent sur les spécificités des deux protocoles ARP et ND. ARP souffre du fait d'être un très vieux protocole, nettement sous-spécifié (par exemple, aucun RFC ne précise de stratégie de retransmission lorsqu'un paquet est perdu). Les mises en œuvre d'ARP sont très variables dans leur comportement. Certaines sont par exemple bien plus bavardes que d'autres, vidant les caches même lorsque ce n'est pas nécessaire, ce qui entraîne davantage de requêtes.
ND est mieux placé qu'ARP, car plus récent. Ceci dit, pour la plupart des problèmes listés dans ce RFC, ND et ARP sont proches. La principale différence est qu'ARP utilise le broadcast et ND le multicast. En théorie, cela permet que les requêtes n'aillent pas dans tout le réseau, seulement dans les parties où il y a des machines IPv6. En pratique, je suis sceptique : combien de commutateurs filtrent ainsi ? Mais, même si cela ne protège pas le réseau, cela protège les machines purement IPv4, qui peuvent ignorer ces sollicitations dès l'arrivée sur la carte Ethernet. Évidemment, si toutes les machines parlent IPv6, cet avantage disparait : tout le monde droit traiter les requêtes ND, comme tout le monde droit traiter les requêtes ARP.
Dernière chose à garder en tête avant de voir la liste des problèmes, l'architecture du data center (section 6). Un data center typique est hiérarchique : des armoires, connectées à un réseau d'accès, lui-même connecté à un réseau d'agrégation, lui-même connecté au cœur. L'armoire compte plein de serveurs et le réseau d'accès est, soit un commutateur réseau interne (ToR pour Top of Rack car il est souvent en haut de la baie), soit on utilise un commutateur situé à l'extrémité de la rangée d'armoirees (EoR pour End of Row).
Ensuite, le réseau d'agrégation qui, dans le cas le plus fréquent, est composé de commutateurs connectant les commutateurs ToR (souvent plusieurs centaines) entre eux.
Le cœur, lui, comprend les équipements qui connectent les commutateurs du réseau d'agrégation, ainsi que les liens avec l'extérieur.
Maintenant, la question d'architecture qui va le plus impacter notre problème : jusqu'où va le domaine de diffusion d'un serveur ? Jusqu'au réseau d'accès, jusqu'au réseau d'agrégation, ou bien jusqu'au cœur ? Comme vu plus haut, la première solution est plus sûre (les problèmes seront concentrés dans une armoire ou dans un relativement petit groupe d'armoires), la seconde plus flexible et la troisième offre le maximum de flexibilité... et de risques.
Pour profiter de la structure hiérarchique du data center, on souhaite que le trafic entre deux machines connectées au même réseau d'accès reste local et n'aille pas sur le réseau d'agrégation. Idem entre l'agrégation et le cœur. Si le data center est occupé par une seule organisation, où le trafic réseau est bien connu et compris, cela peut être possible. Par exemple, si on héberge une ferme de serveurs Web dynamiques, dépendant d'un SGBD, on prendra soin de mettre les serveurs de base de données proches du frontal HTTP, puisqu'ils auront beaucoup à parler entre eux.
Si le data center est public (utilisé par des tas de clients différents, n'ayant pas de lien entre eux, par exemple Amazon EC2, OVH ou Gandi), on ne peut plus espérer connaître les flux réseau. Bref, le type d'usage envisagé va peser sur l'architecture.
Enfin, après ces préliminaires, la section 7 expose la liste des problèmes ARP/ND identifiés. D'abord, le traitement par les routeurs. Ceux-ci doivent écouter le trafic ARP et traiter chaque paquet, ne serait-ce que pour mettre le cache ARP à jour (comme l'impose le RFC 826). Ce traitement se fait en général sur le « chemin lent » (slow path) du routeur, c'est-à-dire en remontant au CPU généraliste de la machine, sans pouvoir utiliser les plus rapides ASIC dont on se sert pour la transmisison de paquets. Ce CPU est limité et, avec les machines actuelles, il ne faut pas espérer plus de quelques milliers de paquets ARP par seconde, ce qui peut être insuffisant dans certains environnements.
Une des techniques utilisées par les routeurs est d'ignorer très tôt les requêtes ARP où l'adresse du routeur n'apparait pas. Cela viole le RFC 826 mais cela peut être nécessaire.
Une autre optimisation est de limiter le nombre de requêtes qui concernent le routeur en envoyant périodiquement de l'ARP gratuit (RFC 5227), pour garder les caches des autres machines peuplés (à noter que cela ne marche pas si la machine n'avait pas déjà une entrée dans son cache ARP).
Autre problème pour le routeur, chaque fois qu'on doit envoyer un paquet à une machine pour laquelle le routeur n'a pas d'entrée dans son cache ARP, il faut effectuer un traitement assez lourd (mettre le paquet IP en attente, comme imposé par les RFC 1122 et RFC 1812, envoyer la requête ARP, attendre et réémettre si nécessaire, peut être envoyer une réponse ICMP destination unreachable) et qui est typiquement géré par le slow path du routeur, sa partie la plus lente. Si le data center contient un grand réseau à plat, et que le routeur doit parler à des dizaines de milliers de machines (et donc faire de l'ARP avec elles), cela peut être une charge sérieuse. (Ce n'est pas le nombre d'interfaces physiques du routeur qui compte mais le nombre totale de machines avec qui il parle en couche 2.)
Ensuite, le cas du protocole ND d'IPv6. Il est très proche d'ARP et bien des problèmes sont les mêmes. La principale différence est qu'il utilise le multicast et que donc, dans certaines circonstances, ses paquets pourront être ignorés, diminuant la charge sur les équipements réseau.
Mais, par contre, le RFC 4861, section 7.3.1, impose des vérifications régulières de la validité des entrées dans le cache. La méthode de vérification n'est pas spécifiée (on a le droit de se servir des accusés de réception TCP pour cela). Mais cela pousse certaines machines à envoyer des demandes ND répétées, parfois une toutes les trente-cinq secondes. Et il n'y a pas d'équivalent de l'ARP gratuit, le RFC 4861, section 7.3.1, disant que la réception d'une réponse ND ne doit pas valider une entrée du cache (au contraire, cela peut générer un test ND, précisement ce qu'on tentait d'éviter). C'est parce que la réception d'une « réponse » ne prouve que le chemin retour, pas forcément l'aller.
La plupart des réseaux étant aujourd'hui en IPv4 et IPv6, les problèmes quantitatifs s'additionnent. La situation ne s'arrangera que lorsqu'on pourra arrêter IPv4, ce qui est une perspective encore très éloignée.
Derniers équipements à souffrir (le RFC ne considère pas le cas des machines terminales), les commutateurs. Pour n'envoyer les paquets que sur le bon port physique (au lieu de le diffuser partout), le commutateur doit garder en mémoire une table des adresses MAC. Si le réseau « couche 2 » est très grand, cette table le sera aussi.
Si vous voulez approfondir le sujet et notamment voir toutes les données quantitatives, lisez le document draft-karir-armd-statistics, et le RFC 7342.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : T. Lodderstedt (Deutsche Telekom AG), M. McGloin (IBM), P. Hunt (Oracle Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF oauth
Première rédaction de cet article le 8 janvier 2013
Le protocole d'autorisation sur le Web OAuth version 2 est riche, voire complexe. Son cadre général est décrit dans le RFC 6749. Et ce nouveau RFC documente les questions de sécurité liées à OAuth v2. Quelles sont les menaces ? Quels sont les risques ? Et comment OAuth gère-t-il ces risques ?
Le document reste assez abstrait car les détails, notamment les probabilités d'une attaque réussie, dépendent de la façon dont OAuth est utilisé. OAuth v2 n'est pas réellement un protocole mais plutôt un cadre général dans lequel peuvent être décrits plusieurs protocoles, qui n'auront pas la même utilisation, ni les mêmes vulnérabilités. En prime, ce mécanisme complexe n'est pas au cœur de mon domaine de compétence personnel, et je vais devoir me contenter de survoler le RFC. Il n'était à l'origine que la section Security Considerations du RFC 6749 mais il a grossi suffisamment pour devenir un document autonome, très détaillé.
Donc, d'abord, en section 2, le cadre général. Par exemple, l'analyse des risques de ce RFC suppose que l'attaquant a un accès complet au réseau et peut écouter à sa guise, voire changer les paquets. On considère également possible que deux des parties impliquées peuvent s'allier pour tromper la troisième. OAuth a trois - ou quatre, dans la v2 - acteurs, le client, le serveur et le propriétaire. Dans la v2, le serveur a été séparé en deux, le serveur d'autorisation et le serveur de ressources. La section 2.3 fait la liste de tout ce que connaissent les différentes parties, Le serveur d'autorisation connait ce qui sert à authentifier (par exemple les condensats des mots de passe des propriétaires). Le serveur de ressources connait les données qu'on veut protéger. Le client (l'application qui cherche à accéder aux données), par contraste, connait nettement moins de choses : le but principal d'OAuth était justement de permettre au propriétaire de donner un accès limité à des clients tiers, à qui il ne fait pas forcément une confiance aveugle.
OAuth repose largement sur des jetons (tokens), un petit bout de données qui sert à prouver qu'on est légitime. Avec certains de ces jetons (par exemple les jetons au porteur, bearer tokens), la seule possession du jeton suffit. Il est donc important de ne pas permettre à un tiers de les copier (donc, il faut communiquer en HTTPS, comme avec un cookie, cf. section 4.3.1, et aussi section 4.6.7 pour un moyen plus rigolo de faire fuiter les jetons).
Les jetons peuvent avoir une durée de vie limitée (RFC 6749, section 4.2.2), et cela permet à un utilisateur OAuth de retirer sa confiance à un client. Les jetons qu'a obtenu ce dernier avant la révocation de la confiance ne lui serviront pas éternellement.
La section 4 est le cœur du RFC. Elle expose toutes les menaces auxquelles a pu penser le groupe de travail, avec les solutions existant dans le cadre OAuth. Je ne vais pas la reprendre intégralement (pas moins de cinquante menaces ont été identifiées), juste en expliquer quelques-unes prises au hasard.
Par exemple (section 4.1.1), OAuth permet de stocker certains secrets (comme des jetons de rafraîchissement) dans le client, pour éviter de devoir passer par une autorisation explicite de l'utilisateur. La possession de ces secrets permet évidemment de se faire passer pour un client légitime. Certains programmeurs peuvent être tentés de planquer ces secrets dans un client distribué en binaire, en croyant naïvement que cela empêchera les hackers de les trouver. Le RFC rappelle donc à juste titre que la rétro-ingéniérie retrouvera rapidement ces secrets, même si le code source du client n'est pas distribué. La protection est donc simple : pas de secret dans un client public (section 5.3.1).
Même si les clients n'ont pas de secret codé en dur dans leur code, une fois qu'ils ont été utilisés, des secrets se retrouveront dans leur mémoire. En volant un engin qui fait tourner le client (un smartphone, par exemple), le méchant se retrouvera en possession des secrets. Les solutions sont dans les systèmes de verrouillage mais aussi dans les possibilités de révocation d'OAuth (encore faut-il que l'utilisateur y pense, lorsque son smartphone a été volé).
Autre menace, le hameçonnage. Comme OAuth dépend beaucoup des redirections HTTP (par exemple du site Web qu'on veut visiter vers le site Web d'autorisation), un utilisateur peut se faire tromper si la redirection est faite vers un site Web qui ressemble au site d'autorisation habituel. Autre façon de hameçonner, le client malveillant peut aussi, au lieu d'utiliser le navigateur Web normal du système, présenter à l'utilisateur humain sa propre interface, en la remplissant d'indicateurs rassurants, petit cadenas et tout. Le client, dans OAuth, ne devrait jamais avoir accès aux informations d'authentification de l'utilisateur (comme le mot de passe) mais ces techniques de hameçonnage le permettent. La seule solution est la vigilance de l'utilisateur, qui ne devrait se servir que de clients honnêtes. (Oui, je sais que c'est plus facile à écrire dans un RFC qu'à faire respecter en pratique. Le RFC suggère des contrôles de sécurité des applications avant de les mettre dans les dépôts comme l'App Store mais on sait que de tels contrôles ne sont pas faits.) Si le client est un navigateur Web, on sait que ces logiciels très complexes ont déjà eu de nombreuses failles de sécurité, permettant à un méchant de les détourner de leur rôle.
Outre le hameçonnage par le client (l'application qui tourne sur la machine de l'utilisateur), il y a un risque de hameçonnage par le serveur d'autorisation. Si celui auquel on accède n'est pas celui qu'on croit (par des trucs comme l'empoisonnement DNS ou ARP), et qu'on lui confie son mot de passe, on est fichu. L'utilisation de HTTPS est donc nécessaire.
OAuth soulève aussi des problèmes d'ergonomie : le serveur d'autorisation informe (voire permet de choisir) sur les permissions exactes qui seront données au client. Cette liste n'est pas toujours comprise par l'utilisateur, qui risque de donner au client trop de droits (section 4.2.2). Voici un exemple d'une application qui demande beaucoup de droits (car c'est un client Twitter généraliste) :
D'une manière générale, comme l'analyse la section 5.5, l'utilisateur manque d'expertise pour répondre intelligemment à des questions comme « il y a un problème de sécurité [ici, texte incompréhensible par l'utilisateur], voulez-vous continuer ? ». De même, la plupart des bonnes pratiques de sécurité (par exemple, l'utilisation obligatoire de seulement certains logiciels, soigneusement validés) vont être une gêne pour l'utilisateur. OAuth n'offre pas de solution ici, mais il est probable qu'il n'en existe pas : c'est le conflit classique entre sécurité et utilisabilité.
Certaines attaques ne sont pas réellement spécifiques à OAuth et visent le processus d'authentification de l'utilisateur, par exemple en essayant, auprès d'un serveur d'autorisation, des dictionnaires entiers de mots de passe pour essayer d'en trouver un qui marche. Les contre-mesures classiques s'appliquent ici, comme les si pénibles CAPTCHA (section 5.1.4.2.5) ou comme le verrouillage automatique des comptes après N essais infructueux (section 4.4.3.6).
Naturellement, le même processus d'authentification de l'utilisateur est vulnérable aux attaques Web classiques comme le clickjacking. Un navigateur Web moderne est rempli de tellement de fonctions différentes, visant en général à faire joli, qu'il est difficile de vérifier la totalité des risques de sécurité. Si un site Web charge la page du serveur d'autorisation dans un iframe transparent, au-dessus de ses propres boutons, il peut faire en sorte que l'utilisateur, croyant cliquer sur les boutons visibles, donne en fait une autorisation OAuth. Il existe plusieurs contre-mesures (section 4.4.1.9) mais des tas d'autres vulnérabilités attendent certainement, dissimulées dans les millions de lignes de code des navigateurs.
L'enfer étant pavé de bonnes intentions, ce sont aussi les solutions de sécurité, conçues pour résoudre une vulnérabilité, qui peuvent être utilisées pour monter une attaque. Ainsi, un méchant peut utiliser OAuth pour faire en sorte que des clients se connectent au serveur d'autorisation en masse. Cela oblige l'attaquant à faire une connexion HTTP mais, en échange, il obtient des connexions HTTPS, bien plus coûteuses (cf. « SSL handshake latency and HTTPS optimizations » de J. Sissel), vers le serveur d'autorisation. De même, si vous vous y connaissez en sécurité, vous avez peut-être noté que le verrouillage automatique des comptes après N essais ratés, proposé plus haut, permet une belle attaque par déni de service en autorisant n'importe qui à verrouiller un compte (cf. section 5.1.4.2.3).
Comme indiqué au début, je suis loin d'avoir listé toutes les menaces, notamment celles reposant sur de subtiles propriétés d'OAuth. N'écrivez pas un logiciel OAuth en suivant uniquement cet article, lisez bien tout le RFC !
Et les solutions à ces problèmes ? La section 5 regroupe les bons principes à suivre lorsqu'on développe ou déploie du OAuth. Chiffrer le trafic, avec TLS ou IPsec (OAuth vérifie l'authenticité et l'intégrité des requêtes mais, utilisé seul, ne fait rien pour la confidentialité), vérifier l'identité du serveur d'autorisation, etc.
Il y a aussi des mesures moins techniques, liées à l'interaction avec un humain, l'utilisateur. Il doit toujours être maintenu « dans la boucle », en lui demandant avant et en l'informant après de ce qui a été fait en son nom (section 5.1.3).
La section 5.1.4 se penche sur le problème de la conservation des « lettres de créance » (credentials), ces différentes informations que le serveur d'autorisation doit stocker en mémoire pour authentifier les utilisateurs. Elle rappelle l'importance de suivre les meilleures pratiques de ce domaine (comme documenté par OWASP). Cela va des protections contre les injections SQL (requêtes paramétrées, accès à la base de données sous un utilisateur non privilégié, etc) à la nécessité de ne pas stocker les mots de passe en clair. En 2012, garder des mots de passe en clair dans une base de données (qui se fera forcément copier un jour ou l'autre par un attaquant quelconque) est une faute grave. La méthode sûre la plus souvent utilisée est de ne stocker qu'un condensat du mot de passe mais cela ne suffit pas toujours, face aux attaques par dictionnaire, facilitées notamment par les tables arc-en-ciel. Ainsi, la copie de la base de mots de passe condensés de LinkedIn avait eu des conséquences sérieuses car les condensats n'étaient pas salés (section 5.1.4.1.3).
Si on génère des secrets qui n'ont pas besoin d'être manipulés par des êtres humains (comme les jetons), il faut bien penser à les faire longs et réellement aléatoires (RFC 4086).
Voilà, il existe encore plein de solutions décrites dans cette section, notamment sur les problèmes spécifiques à OAuth (sur lesquels je suis passé un peu rapidement, car je ne connais pas assez ce protocole). Si vous programmez un logiciel OAuth, il va évidemment falloir les lire.
Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : S. Shalunov (BitTorrent Inc), G. Hazel (BitTorrent Inc), J. Iyengar (Franklin and Marshall College), M. Kuehlewind (University of Stuttgart)
Expérimental
Réalisé dans le cadre du groupe de travail IETF ledbat
Première rédaction de cet article le 20 décembre 2012
Alors que tant d'efforts de recherche ont été dépensés pour faire des réseaux informatiques et des protocoles qui permettent d'aller plus vite, d'attendre moins longtemps avant de voir la page d'accueil de TF1, le groupe de travail LEDBAT (Low Extra Delay Background Transport ) de l'IETF travaillait à un tout autre projet : un protocole de transport de données qui aille moins vite, de façon à être un bon citoyen du réseau, à n'utiliser celui-ci que lorsqu'il est vide et qu'on peut donc faire passer ses bits sans gêner personnne. Ce RFC décrit l'algorithme LEDBAT, un algorithme « développement durable ».
LEDBAT n'est donc pas un protocole complet, mais un algorithme de contrôle de la fenêtre de congestion, ce mécanisme par lequel les protocoles de transport évitent de saturer le réseau. Le plus connu et le plus utilisé de ces mécanismes est celui de TCP (RFC 5681) et ses objectifs sont d'utiliser le réseau à fond et d'assurer une relative égalité entre les flots de données qui se concurrencent sur ce réseau. LEDBAT, au contraire, vise avant tout à céder la place aux autre flots, non-LEDBAT.
Mais pourquoi diable voudrait-on être si généreux ? Cela peut être parce qu'on estime les autres flots plus importants : si je télécharge Plus belle la vie pendant que je passe un coup de téléphone via SIP, je souhaite que le téléchargement ne prenne pas de capacité si SIP en a besoin (c'est la différence entre applications d'« arrière-plan » comme le transfert de gros fichiers et d'« avant-plan » comme un coup de téléphone ou une session SSH interactive). Ou bien cela peut être pour profiter de réductions offertes par le réseau : après tout, un routeur ou une fibre optique ne coûtent pas plus cher à l'usage, que les octets circulent ou pas (contrairement à un autoroute ou une voie ferrée). Il serait donc logique que les transports « charognards », comme LEDBAT, qui n'utilisent la capacité réseau que lorsque personne n'en veut, reçoivent une récompense financière, par exemple une réduction des prix (parlez-en à votre FAI).
Pour les détails sur les motivations de LEDBAT et les raisons pour lesquelles des technqiues comme le shaping ne conviennent pas, voir le premier RFC du groupe LEDBAT, le RFC 6297. Ici, je vais me focaliser sur l'algorithme spécifié par LEDBAT et qui répond au cahier des charges : céder la place le plus vite possible.
Le principe de cet algorithme est simple : utiliser les variations du temps de voyage des paquets pour détecter l'approche de la congestion et refermer alors la fenêtre de transmission. TCP utilise essentiellement le taux de pertes de paquets comme indicateur (ou les marques ECN du RFC 3168). Les routeurs ayant des tampons d'entrée-sortie, lorsque la ligne de sortie est saturée, les paquets commencent à s'entasser dans ce tampon. Lorsqu'il est plein, le routeur jette des paquets (et TCP va alors réagir). On voit que l'augmentation du temps de voyage (dû au séjour dans le tampon) précède la perte de paquets. En réagissant dès cette augmentation, LEDBAT atteint son objectif de céder la place à TCP. (À noter qu'il existe des variantes de TCP qui utilisent également le temps de voyage comme indicateur de l'approche de la congestion, par exemple TCP Vegas, documenté dans « TCP Vegas: New techniques for congestion detection and avoidance » de Brakmo, L., O'Malley, S., et L. Peterson, mais voir le RFC 6297 pour un tour d'horizon général.)
Où est-ce que LEDBAT va être mis en œuvre ? Cela peut être dans un protocole de transport, par exemple comme une extension de TCP, ou bien dans l'application. LEDBAT est un algorithme, pas un protocole précis. Il peut être utilisé dans plusieurs protocoles, du moment que ceux-ci permettent l'estampillage temporel des paquets, pour que les deux machines qui communiquent puissent mesurer le temps de voyage (section 4.1).
La section 2 décrit l'algorithme exact. LEDBAT a une fenêtre de
congestion, notée cwnd
qui indique combien
d'octets l'émetteur peut envoyer avant un nouvel accusé de
réception. L'émetteur met dans chaque paquet le moment où il a envoyé
ce paquet. Le récepteur regarde l'heure, en déduit le temps de voyage
(aller simple, puisque l'encombrement n'est pas forcément le même dans
les deux sens, une mesure aller-retour ne servirait pas à grand'chose) et retransmet cette indication à l'émetteur. Lorsque
celui-ci voit le temps de voyage augmenter (signe que les tampons des
routeurs se remplissent), il diminue la fenêtre de
congestion. L'émetteur notamment utilise deux paramètres,
TARGET
et
GAIN
. TARGET
est
l'augmentation du temps de voyage en dessous de laquelle LEDBAT ne
fait rien. GAIN
(qui vaut entre 0
et 1) indique le
facteur d'échelle entre l'augmentation du temps de voyage et la
réduction de la fenêtre de congestion. Plus il est élevé, plus LEDBAT
réagit rapidement et vigoureusement. Un GAIN
de 1
est équivalent à TCP Reno. À noter qu'on
pourrait avoir deux valeurs de GAIN
, une pour
augmenter la fenêtre de congestion et une pour la diminuer. En mettant
un GAIN
plus grand pour la diminution de la
fenêtre, on garantit que LEDBAT cédera très vite la place dès le plus
petit signal d'un ralentissement.
(Pour
les amateurs de pseudo-code, une description
de l'algorithme avec cette technique figure dans le RFC.)
Bien sûr, le temps de voyage varie pour tout un tas de raisons et
il n'est pas forcément souhaitable de refermer la fenêtre de congestion à chaque
dérapage. LEDBAT filtre donc les
outliers à l'aide d'une
fonction FILTER()
qui fait partie des paramètres
de l'algorithme (elle n'est pas imposée par le RFC, on peut tester
plusieurs mécanismes de filtrage des données.) Un filtre sommaire est
NULL
(aucun filtrage, on accepte toutes les
mesures). Un autre plus sophistiqué est EWMA
(Exponentially-Weighted Moving
Average). Un bon filtre résiste au bruit
inévitable, mais reste sensible aux signaux indiquant une vraie
congestion.
Le temps de voyage se décompose en temps de transmission sur le
câble (qui dépend de la vitesse du médium, par exemple 100 Mb/s pour
du Fast Ethernet), temps de propagation (lié à
la vitesse de la lumière), temps d'attente dans
les tampons et temps de traitement à la
destination. Tous ces temps sont constants ou presque, à l'exception
du temps d'attente dans les tampons. Ce sont donc ses variations qui
déterminent l'essentiel des variations du temps de voyage. Pour
estimer ce temps d'attente dans les tampons, LEDBAT calcule un
temps de base (section 3.1.1) qui est le temps de voyage minimum
observé. Il permet de connaître la valeur minimale en dessous de
laquelle le temps de voyage ne pourra pas descendre. Les calculs de
fenêtre de congestion se font à partir de (temps de voyage - temps de
base), une grandeur qui part donc de zéro (les méthodes du RFC 6298 peuvent être utiles ici). L'algorithme de LEDBAT
est linéaire : la fenêtre est réduite ou
agrandie proportionnellement à cette grandeur, le facteur de
proportionnalité étant le paramètre GAIN
. Autre intérêt du concept de
temps de base : en cas de changement de la route pendant la session
(par exemple, panne d'un lien et re-routage par un chemin plus long),
la mesure du temps de base pendant les N dernières secondes permettra
de voir que le trajet a changé et que les calculs doivent utiliser le
nouveau temps de base. (Le choix de N est un compromis : trop petit et
le temps de base va varier souvent, trop grand et il retardera le
moment où on détecte un changement de chemin.)
Avec son mécanisme de réduction de la fenêtre de congestion dès que le temps de voyage augmente, LEDBAT ne pousse normalement jamais jusqu'au point où il y aura des pertes de paquets. Néanmoins, celles-ci peuvent quand même survenir, et LEDBAT doit alors se comporter comme TCP, en refermant la fenêtre (section 3.2.2).
La section 4 du RFC discute ensuite de différents points
intéressants de LEDBAT. Par exemple, LEDBAT est efficace pour céder
rapidement à TCP lorsque celui-ci transfère de grandes quantités de
données. Mais cela laisse le problème des applications qui envoient
peu de données mais sont très sensibles à la
latence, comme la voix sur IP. Si la conversation téléphonique envoie peu de données,
il n'y aura jamais de remplissage des tampons, donc pas d'augmentation
du temps d'attente dans ceux-ci donc LEDBAT se croira tranquille et
enverra autant de données qu'il veut. Au moment où un des
interlocuteurs parlera, ses paquets se trouveront donc peut-être
coincés derrière un paquet LEDBAT. La seule protection contre ce
problème est le paramètre TARGET
qui ne doit donc
pas être mis trop haut. La norme G.114 de
l'UIT suggère 150 ms comme étant le maximum de
retard tolérable pour le transport de la voix. LEDBAT doit donc
choisir ses paramètres pour réagir avant les 150 ms. Le RFC
recommande 100 ms pour le paramètre TARGET
qui
indique l'augmentation de délai de voyage à partir de laquelle LEDBAT
réagit. (Ce paramètre TARGET
détermine le temps
maximal d'attente supplémentaire dû à LEDBAT.)
Autre point subtil, la compétition entre flots LEDBAT. On sait que TCP assure la « justice » entre flots TCP : si trois flots sont en compétition, chacun aura un tiers de la capacité. LEDBAT, lui, cède à TCP. Si un flot LEDBAT et un flot TCP sont en compétition, TCP aura toute la capacité. Mais si deux flots LEDBAT parallèles se concurrencent ? L'algorithme de LEDBAT ne garantit pas de justice. En général, c'est le flot le plus récent qui va gagner : arrivant tard, dans un réseau déjà bien encombré, il mesure un temps de base très élevé et ne voit donc pas d'augmentation due au temps d'attente dans les tampons, et ne réduit donc pas sa fenêtre de congestion (« Rethinking Low Extra Delay Background Transport Protocols » de Carofiglio, G., Muscariello, L., Rossi, D., Testa, C., et S. Valenti). Pour corriger cet effet, on ne peut compter que sur le bruit : de temps en temps, les tampons se videront, le temps de voyage diminuera, et le récent arrivé corrigera sa mauvaise estimation du temps de base.
La section 5 du RFC considère les points qui sont encore ouverts à
expérimentation. Après tout, un protocole comme LEDBAT est quelque
chose de très nouveau dans le zoo de l'Internet. Par exemple, l'effet
de changement de routes pendant une session LEDBAT, modifiant le temps
de base, n'est pas encore vraiment bien connu. Quant à la valeur des
paramètres comme TARGET
ou
GAIN
, elle aura certainement besoin d'être
ajustée à la lumière de l'utilisation réelle. Enfin, le filtre des
mesures, qui permet d'éliminer les mesures jugées anormales, et évite
donc à LEDBAT d'ajuster brusquement sa fenêtre de congestion pour
rien, aura certainement besoin de réglages, lui aussi.
Et la sécurité de LEDBAT ? La section 6 rappelle que, même si un attaquant arrive à tromper LEDBAT sur les valeurs du temps de voyage, dans le pire des cas, il ne pourra pas le faire se comporter de manière plus gloutonne que TCP. Par contre, il pourra faire une attaque par déni de service en lui faisant croire que le délai de voyage a augmenté et que LEDBAT devrait ralentir. Pour l'instant, il n'y a pas de mécanisme contre cela.
Le bon fonctionnement de LEDBAT dépend de bonnes mesures. Les fanas de métrologie seront donc ravis de l'annexe A, qui parle des causes d'erreur dans les mesures. Le principal problème est que, pour mesurer les temps de voyage aller-simple dont a besoin LEDBAT, il faut des horloges à peu près synchronisées. Si l'émetteur met dans le paquet une heure de départ à 13 heures, 37 minutes et 56,789 secondes, que le récepteur mesure une arrivée à 13 heures, 37 minutes et 57,123 secondes et que le récepteur a 0,5 secondes de retard sur l'émetteur, il mesurera un temps de voyage de 0,334 secondes (alors qu'il est en fait de 0,834 secondes). Reprenant le vocabulaire de NTP (RFC 5905), on peut dire qu'il y a deux sources de problèmes, l'écart des horloges par rapport à une référence et le décalage (la variation de l'écart). L'écart entraine une erreur fixe dans la mesure du temps (comme dans notre exemple ci-dessus). Mais LEDBAT n'utilise pas directement le temps mais la différence entre temps actuel et temps de base. Cette erreur s'annule donc et l'écart des horloges par rapport au temps correct n'est donc pas importante pour LEDBAT.
Plus embêtant est le décalage puisque lui ne s'annulera pas. Si
l'horloge du récepteur bat plus vite que celle de l'émetteur, il aura
toujours l'impression d'un réseau très encombré, puisque ses mesures
de temps de voyage seront toujours supérieures au temps de base qu'il
avait mesuré avant. Heureusement, alors que des écarts énormes sont
souvent vus sur l'Internet (il est fréquent de voir plusieurs minutes,
voire plusieurs heures de différence entre une machine et le temps
UTC), les décalages sont typiquement bien plus
petits. Les mesures citées par le RFC 5905
indiquent des décalages courants de 100 à 200 ppm, soit 6 à 12 ms
d'erreur accumulée
par minute. Comme une machine LEDBAT limite sa mémoire (paramètre
BASE_HISTORY
, pour lequel le RFC recommande
actuellement une valeur de dix minutes), et n'utilise donc que des
mesures récentes pour évaluer le temps de base, le problème reste donc
limité.
Si malgré tout, le problème se pose, il n'affectera que le cas où le récepteur a une horloge plus rapide, et en déduira donc à tort qu'il doit ralentir. Dans le cas inverse (horloge du récepteur plus lente), l'émetteur aura simplement l'impression que le temps de base augmente.
Pour corriger ce problème de décalage, on peut imaginer d'envoyer les estampilles temporelles dans les deux sens, pour que chaque machine puisse calculer ce que devrait voir l'autre, pour pouvoir détecter qu'un pair a une mauvaise mesure. Ensuite, l'émetteur pourrait corriger ses propres calculs por s'adapter à ce récepteur erroné. Il peut même calculer si le décalage est constant (horloge battant trop vite ou trop lentement, mais à une fréquence constante).
Et question mises en œuvre effectives ? LEDBAT a été testé dans des logiciels comme μTorrent Transport Protocol library. Il est l'algorithme utilisé par le microTP de BitTorrent (voir la documentation officielle de µTP). Il est aussi mise en œuvre dans Swift.
Merci à Mathieu Goessens pour sa suggestion et à André Sintzoff pour ses inlassables corrections.
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : S. Bradner (Harvard University), K. Dubray (Juniper Networks), J. McQuaid (Turnip Video), A. Morton (AT&T Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF bmwg
Première rédaction de cet article le 1 décembre 2012
Lors de la publication du RFC 2544, sur les tests de performances des équipements réseau, un point n'avait pas été mis assez clairement : comme tous les RFC du BMWG, le RFC 2544 ne concerne que les tests en laboratoire, dans des conditions bien contrôlées, et sans avoir peur de gêner un réseau de production. Comme certains avaient apparemment raté cette limitation, notre RFC 6815 enfonce le clou : ne faites pas les tests du RFC 2544 sur un vrai réseau !
Ce point est clairement précisé dans la charte du groupe de travail BMWG (Benchmarking Methodology Working Group). Les tests produits par ce groupe sont conçus pour des réseaux isolés (section 3 : un réseau isolé est un réseau dont le trafic de test ne sort pas et où le trafic non lié au test ne rentre pas). Il n'est pas prévu de les utiliser pour, par exemple, vérifier des SLA sur un réseau de production.
Mais pourquoi est-ce mal d'utiliser les tests BMWG sur un réseau de production ? La section 4 donne les deux raisons :
C'est d'ailleurs pour faciliter l'isolation et garder le trafic de
test à part qu'il existe des plages d'adresses IP dédiées aux tests, le
198.18.0.0/24
(RFC 2544,
annexe C.2.2) et le
2001:2::/48
(RFC 5180, section 8 mais notez que ce RFC comporte une grosse erreur). On peut ainsi
facilement filtrer ces plages sur ses routeurs
et pare-feux, pour empêcher du trafic de test
de fuir accidentellement.
Et si on veut quand même faire des mesures sur des réseaux de production ? Il faut alors se tourner vers un autre jeu de tests, ceux développés par le groupe de travail IPPM. Notez que cela n'est pas par hasard que cet autre jeu ne comporte pas de méthode pour la mesure de la capacité (RFC 5136) : une telle mesure perturbe forcément le réseau mesuré.
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : C. Pignataro (Cisco Systems), F. Gont (UTN-FRH / SI6 Networks)
Chemin des normes
Première rédaction de cet article le 29 novembre 2012
Ce très court RFC est purement administratif et n'aura pas de conséquences pratiques : il note simplement comme officiellement abandonnées neuf des options d'IPv4.
IPv4 (RFC 791, section 3.1) prévoit l'ajout d'options dans l'en-tête d'un paquet (en pratique, elles sont peu utilisées). Parmi les options enregistrées, certaines n'avaient jamais été déployées, ou bien était tombées en désuétude depuis longtemps. Lire ce RFC, c'est donc fouiller le grenier et retrouver des trucs que tout le monde croyait perdus... Le registre des options IP est mis à jour pour que ces options soient formellement retirées (et le RFC correspondant marqué comme « intérêt historique uniquement »). Ce sont :
D'autres options, MTU Probe et MTU Reply, avaient déjà été « nettoyées » par le RFC 1191.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : P. Mohapatra (Cisco Systems), J. Scudder (Juniper Networks), D. Ward (Cisco Systems), R. Bush (Internet Initiative Japan), R. Austein (Dragon Research Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 18 janvier 2013
Il manquait un élément dans les normes de la sécurisation du routage avec RPKI+ROA, une description de la façon exacte dont on valide une annonce BGP lorsqu'on a des ROA (Route Origin Authorizations) pour ce préfixe. Ce RFC comble ce manque. Jusqu'à présent, en suivant les RFC, on pouvait distribuer des certificats authentifiant le titulaire d'un préfixe IP (la RPKI) et on pouvait émettre des autorisations, pour un AS, d'annoncer un préfixe (les ROA). Désormais, on peut utiliser RPKI et ROA pour avoir une solution de sécurité complète.
Cette solution traite le cas des détournements BGP dont le plus
célèbre est celui de YouTube par
Pakistan Telecom. Elle permet de s'assurer de la validité de
l'origine d'une annonce de route. Dans un
routeur BGP, les annonces reçues des autres
routeur, dans un message BGP UPDATE
, ressemblent à 192.0.2.0/24 : 64497 64499 65550
,
ce qui indique que ce préfixe 192.0.2.0/24
a pour
origine l'AS 65550 (on lit
de droite à gauche) qui l'a ensuite transmis à l'AS 64499, qui l'a
ensuite envoyé à 64497. Cette liste
d'AS est transmise d'un routeur BGP à l'autre dans les attributs
AS_PATH
et AS4_PATH
. La
technique décrite dans ce RFC permet d'authentifier l'origine (et elle
seule), ce qui traite le cas de la plupart des accidents (comme la
bavure de Pakistan Telecom) mais pas forcément celui des attaques
délibérées.
Depuis plus d'un an, une RPKI réelle est en cours de déploiement. Elle contient des certificats permettant de prouver la titularité d'adresses IP et de numéros d'AS (RFC 3779). Ces certificats servent ensuite à la signature des ROA. Dans le modèle actuellement privilégié, RPKI et ROA sont distribués à des machines validantes chez les opérateurs et les routeurs BGP récupèrent une liste des ROA validés auprès de ces machines, avec le protocole RTR du RFC 6810 (cette séparation permet de réduire le travail, notamment cryptographique, des routeurs). Notre RFC appelle cette liste la liste des VRP (Validated ROA Payload).
Armé de ces VRP, un routeur peut, pour chaque annonce BGP, la classer en :
À noter que certains VRP ne peuvent jamais correspondre à une annonce légale, par exemple, si l'AS d'origine est zéro (RFC 7607). Cette propriété est utilisée pour indiquer que certains préfixes ne doivent jamais être annoncés (RFC 6491).
Tirés d'une documentation du RIPE-NCC, voici un exemple avec un routeur Cisco, montrant ces trois états :
isco-rpki-rtr>sh ip bgp 93.175.146.0/24 BGP routing table entry for 93.175.146.0/24, version 8995350 Paths: (1 available, best #1, table default) ... 64510 3333 12654, (received & used) ... path 51012284 RPKI State valid cisco-rpki-rtr>sh ip bgp 93.175.147.0/24 BGP routing table entry for 93.175.147.0/24, version 8995351 Paths: (1 available, no best path) ... 64510 3333 12654, (received & used) ... path 510122C8 RPKI State invalid cisco-rpki-rtr>sh ip bgp 84.205.83.0/24 BGP routing table entry for 84.205.83.0/24, version 5427340 Paths: (1 available, best #1, table default) ... 64510 3333 12654, (received & used) ... path 2609454C RPKI State not found
Le RFC parle de « couvrir » un préfixe, pas d'être égal à un
préfixe car le calcul est fait en tenant compte du caractère
hiérarchique des adresses. Ainsi, un ROA pour
192.0.2.0/24
couvre une annonce pour
192.0.2.128/26
. L'algorithme en
pseudo-code figure en section 2.1.
Et une fois qu'on a déterminé l'état Non trouvé ou Valide ou Invalide, qu'en fait-on ? Un point important de notre RFC (section 3) est que la décision est locale. Chaque routeur décide de ce qu'il fait du résultat de la validation (c'est analogue à la façon dont fonctionnent d'autres techniques de sécurité comme DNSSEC ou X.509 : la norme précise la technique, pas la décision). Le routeur peut se contenter d'envoyer une trap SNMP pour les routes invalides, il peut changer la préférence locale selon le résultat de la validation, ou bien il peut carrément rejeter les routes invalides (section 5).
Naturellement, avant de configurer son routeur pour prendre des décisions radicales, l'administrateur réseaux s'assurera que la validation se passe bien, que la machine validante se met bien à jour, n'a pas de faux positifs, est bien sécurisée, etc (section 8).
Insistons : cette technique ne valide que l'origine de l'annonce, pas le chemin d'AS complet (en anglais, c'est une Origin validation, pas une Path validation). Un attaquant malin qui veut fabriquer des fausses annonces BGP va donc s'assurer de mettre l'origine correcte, avant d'injecter l'annonce. Le RFC note donc que cette technique est plutôt une sauvegarde contre les « attaques du singe du milieu » (le singe étant supposé moins intelligent que l'homme du milieu) plutôt qu'une technique de sécurité au sens classique. D'autres techniques sont en cours de développement pour assurer la validation du chemin, mais c'est un problème bien plus complexe.
Fin 2012, les routeurs de Cisco et de Juniper (et sans doute d'autres) mettent déjà en œuvre ce RFC et permettent de configurer le sort des routes en fonction de leur validité.
On notera que Cisco prétend avoir un brevet sur cette technique : IPR #1569, où Cisco ne s'engage pas à permettre des licences gratuites.
Date de publication du RFC : Janvier 2013
Auteur(s) du RFC : R. Bush (Internet Initiative Japan), R. Austein (Dragon Research Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 18 janvier 2013
Le protocole décrit dans ce RFC fait partie de la grande famille des RFC sur la RPKI, un ensemble de mécanismes permettant de sécuriser le routage sur l'Internet. Il traite un problème bien particulier : comme la validation des annonces de route, potentiellement complexe en cryptographie, se fait typiquement sur une machine spécialisée, le cache validateur, comment communiquer le résultat de ces validations au routeur, qui va devoir accepter ou rejeter des routes ? C'est le rôle d'un nouveau protocole, RTR (RPKI/Router Protocol), un protocole très simple. (Ce RFC décrit la version 0 du protocole, une version plus récente, la 1, est normalisée dans le RFC 8210.)
L'opérateur Internet a donc deux acteurs qui font du RTR entre eux, le cache validateur qui récupère les ROA (Route Origin Authorization, cf. RFC 6482) par rsync, les valide cryptographiquement et garde en mémoire le résultat de cette validation (pour des exemples d'utilisation de deux programmes mettant en œuvre cette fonction, voir mon article sur les logiciels de la RPKI), et le routeur (Cisco, Juniper, Unix avec Quagga, etc). Ce dernier joue un rôle critique et on ne souhaite pas trop charger la barque en lui imposant les opérations assez lourdes du validateur. Dans la plupart des déploiements de la RPKI, le routeur ne fait donc que récupérer des résultats simples (« ce préfixe IP peut être annoncé par cet AS »). Le jeu de données que connait le cache validateur a un numéro de série, qui est incrémenté dès qu'il y a une modification (RFC 1982). Le cache peut donc facilement savoir si un de ses clients routeur est à jour en comparant son numéro de série avec celui du routeur. Le numéro de série est spécifique à un cache donné, il n'a pas de signification globale. Le routeur ne validant pas, le cache qu'il utilise doit donc être une machine de confiance.
Un autre acteur, externe à l'opérateur, est la RPKI, l'ensemble des informations de routage publiées (RFC 6481), et qui sont transportées en général en rsync et validées par les signatures cryptographiques qu'elles portent.
Le routeur va ouvrir une connexion avec un ou plusieurs caches et transmettre le numéro de série de ses données. Le cache va lui envoyer les données plus récentes que ce numéro (ou bien rien, si le routeur est à jour). Le cache dispose aussi d'un mécanisme de notification pour dire à tous les routeurs connectés « j'ai du nouveau ». La section 8 décrit plus en détail le processus avec plusieurs caches.
La section 5 décrit le format des paquets : chacun, outre le classique champ version, a un type, indiqué par un entier de 8 bits (requête, réponse, etc), le numéro de série de l'envoyeur et un identifiant de session, qui identifie le serveur du cache (pour détecter une remise à zéro d'un cache, par exemple), la longueur du préfixe annoncé et bien sûr le préfixe lui-même.
Les types de paquets les plus utiles (la liste complète est dans un registre IANA) :
Le dialogue typique entre un routeur et un cache validateur est décrit en section 6 (le RFC détaille aussi le dialogue de démarrage, ici, je ne montre que celui de fonctionnement régulier) :
Les codes d'erreur possibles sont décrits dans la section 10 et font désormais l'objet d'un registre IANA. On y trouve par exemple 0 (données corrompues), 1 (erreur interne dans le client ou le serveur), 2 (pas de nouvelles données ; ce n'est pas à proprement parler une erreur).
La question du transport des données entre le cache et le routeur est celle qui a fait l'objet du plus grand nombre de débats à l'IETF. Elle est traitée dans la section 7. Le principal problème est le suivant : comme le but de l'opération RPKI+ROA est d'augmenter la sécurité du routage, il faut que chaque maillon de la chaîne soit sécurisé. Il ne servirait pas à grand'chose de déployer une telle usine à gaz de validation si la liaison entre le routeur et le cache permettait à un intermédiaire de changer les données en cours de route. Il était donc tentant de normaliser une technique de sécurité particulière pour le transport, comme par exemple TLS. Malheureusement, il n'existe pas à l'heure actuelle de technique accessible sur tous les routeurs. L'IETF ayant toujours soin de normaliser des protocoles réalistes, qui puissent être mis en œuvre et déployés, le choix a été fait de ne pas imposer une technique de sécurisation particulière. L'interopérabilité en souffre (un cache et un routeur peuvent ne pas avoir de protocole de sécurité en commun) mais c'était la seule option réaliste. (J'ajoute que, si le but de la séparation du routeur et du validateur était de dispenser ce dernier des calculs cryptographiques, il ne serait pas logique de lui imposer ensuite une session protégée cryptographiquement avec le validateur.)
Le RFC se contente donc de donner une préférence à AO (TCP Authentication Option, cf. RFC 5925) en signalant qu'elle sera la technique préférée, dès lors qu'elle sera disponible sur tous les routeurs (ce qui est très loin d'être le cas en 2012). Les algorithmes du RFC 5926 doivent être acceptés.
En attendant AO, et pour s'assurer qu'il y aura au moins un protocole commun, le RFC spécifie que routeurs et caches doivent pouvoir se parler en utilisant du TCP nu, sans sécurité, vers le port 323. Dans ce cas, le RFC spécifie que routeur et cache validateur doivent être sur le même réseau (idéalement, sur le même segment, cf. section 11) et que des mécanismes, par exemple de contrôle d'accès physiques, empêchent les méchants de jouer avec ce réseau.
Au cas où AO ne soit pas disponible (la quasi-totalité des routeurs
aujourd'hui) et où le transport non sécurisé soit jugé nettement trop
faible, le RFC présente plusieurs transports sécurisés possibles. Par
exemple, SSH, avec une sécurisation des clés
obtenue par un moyen externe (entrée manuelle des clés, par
exemple). Le sous-système SSH à utiliser est nommé
rpki-rtr
. Notez que, si SSH n'a pas été rendu
obligatoire, alors que quasiment tous les routeurs ont un programme
SSH, c'est parce que ce programme n'est pas toujours disponible sous
forme d'une bibliothèque, accessible aux
applications comme RTR.
Autre alternative de sécurisation évidente,
TLS. Le RFC impose une authentification par un
certificat client, comportant l'extension
subjectAltName
du RFC 5280,
avec une adresse IP (celle du routeur qui se connecte, et que
le serveur RTR, la cache validateur, doit vérifier). Le client RTR,
lui (le routeur), utilisera le nom de
domaine du serveur RTR (le cache) comme entrée pour l'authentification (cf. RFC 6125). N'importe quelle
CA peut être utilisée mais notre RFC estime
qu'en pratique, les opérateurs créeront leur propre CA, et mettront
son certificat dans tous leurs routeurs.
Notez que ce problème de sécurité ne concerne que le transport entre le routeur et le cache validateur. Entre les caches, ou bien entre les caches et les serveurs publics de la RPKI, il n'y a pas besoin d'une forte sécurité, l'intégrité des données est assurée par la validation cryptographique des signatures sur les objets.
Ce RFC spécifie un protocole, pas une politique. Il pourra y avoir plusieurs façons de déployer RTR. La section 9 donne un exemple partiel de la variété des scénarios de déploiement, notamment :
Pour limiter la charge sur les serveurs rsync de la RPKI (voir RFC 6480), il est recommandé d'organiser les caches de manière hiérarchique, avec peu de caches tapant sur les dépôts rsync publics, et les autres caches se nourrissant (et pas tous en même temps) à partir de ces caches ayant un accès public.
Bien que ce protocole RTR ait été conçu dans le cadre de la RPKI, il peut parfaitement être utilisé avec d'autres mécanismes de sécurisation du routage, puisque RTR se contente de distribuer des autorisations, indépendemment de la manière dont elles ont été obtenues. On peut donc imaginer du RTR avec Rover.
Aujourd'hui, qui met en œuvre RTR ? Il existe en logiciel libre une bibliothèque en C, RTRlib. Elle a fait l'objet d'un bon article de présentation (avec schéma pour expliquer RTR). Elle peut tourner sur TCP nu mais aussi sur SSH. RTRlib permet d'écrire, très simplement, des clients RTR en C, pour déboguer un cache/validateur, ou bien pour extraire des statistiques. Un client simple en ligne de commande est fourni avec, rtrclient. Il peut servir d'exemple (son code est court et très compréhensible) mais aussi d'outil de test simple. rtrclient se connecte et affiche simplement les préfixes reçus. Voici (avec une version légèrement modifiée pour afficher la date) son comportement (en face, le RPKI Validator du RIPE-NCC) :
% rtrclient tcp localhost 8282 ... 2012-05-14T19:27:42Z + 195.159.0.0 16-16 5381 2012-05-14T19:27:42Z + 193.247.205.0 24-24 15623 2012-05-14T19:27:42Z + 37.130.128.0 20-24 51906 2012-05-14T19:27:42Z + 2001:1388:: 32-32 6147 2012-05-14T19:27:42Z + 2001:67c:2544:: 48-48 44574 2012-05-14T19:27:42Z + 178.252.36.0 22-22 6714 2012-05-14T19:27:42Z + 217.67.224.0 19-24 16131 2012-05-14T19:27:42Z + 77.233.224.0 19-19 31027 2012-05-14T19:27:42Z + 46.226.56.0 21-21 5524 2012-05-14T19:27:42Z + 193.135.240.0 21-24 559 2012-05-14T19:27:42Z + 193.247.95.0 24-24 31592 ...
Autre bibliothèque pour développer des clients RTR, cette fois en Go, ma GoRTR. Le programmeur doit fournir une fonction de traitement des données, qui sera appelée chaque fois qu'il y aura du nouveau. GoRTR est fournie avec deux programmes d'exemple, un qui affiche simplement les préfixes (comme rtrclient plus haut), l'autre qui les stocke dans une base de données, pour étude ultérieure. Par exemple, on voit ici que la majorité des préfixes annoncés autorisent une longueur de préfixe égale à la leur (pas de tolérance) :
essais=> SELECT count(id) FROM Prefixes WHERE serialno=(SELECT max(serialno) FROM Prefixes) AND maxlength=masklen(prefix); count ------- 2586 (1 row) essais=> SELECT count(id) FROM Prefixes WHERE serialno=(SELECT max(serialno) FROM Prefixes) AND maxlength>masklen(prefix); count ------- 1110 (1 row)
Autrement, Cisco et Juniper ont tous les deux annoncé que leurs routeurs avaient un client RTR, et qu'il a passé des tests d'interopérabilité avec trois mises en œuvre du serveur (celles de BBN, du RIPE et de l'ISC). Un Internet-Draft sur ces tests d'interopérabilité est draft-ymbk-rpki-rtr-impl. Quant aux serveurs, un exemple est fourni par le logiciel RPKI du RIPE-NCC qui fournit un serveur RTR sur le port 8282 par défaut.
Aujourd'hui (18 janvier 2013), un client RTR récupère 3696 préfixes (ce qui est plus que le nombre de ROA puisqu'un ROA peut comporter plusieurs préfixes). C'est encore très loin de la taille de la table de routage globale et il reste donc à voir si l'infrastructure suivra. (Sur ma station de travail, le validateur, écrit en Java, rame sérieusement.)
Pour les curieux, pourquoi est-ce que l'IETF n'a pas utilisé Netconf (RFC 6241) plutôt que de créer un nouveau protocole ? Les explications sont dans une discussion en décembre 2011. Le fond de la discussion était « les informations de la RPKI sont des données ou de la configuration » ? La validation est relativement statique mais reste quand même plus proche (fréquence de mise à jour, notamment) des données que de la configuration.
Si vous voulez tester un client RTR, BBN fournit un serveur public : rtr-test.bbn.com:12712 (TCP nu). Les données sont bidon et générées automatiquement. Voici le genre de choses qu'affiche rtrclient :
% rtrclient tcp rtr-test.bbn.com 12712 ... 2012-05-14T19:36:27Z + 236.198.160.184 18-24 4292108787 2012-05-14T19:36:27Z + 9144:8d7d:89b6:e3b8:dff1:dc2b:d864:d49d 105-124 4292268291 2012-05-14T19:36:27Z + 204.108.12.160 8-29 4292339151 2012-05-14T19:36:27Z + 165.13.118.106 27-28 4293698907 2012-05-14T19:36:27Z + 646:938e:20d7:4db3:dafb:6844:f58c:82d5 8-82 4294213839 2012-05-14T19:36:27Z + fd47:efa8:e209:6c35:5e96:50f7:4359:35ba 20-31 4294900047 ...
Les auteurs de la RTRlib gèrent également un serveur RTR public,
accessible en rpki.realmv6.org:42420
.
Une étude comparée des mises en œuvre de RTR a été publiée en février 2014 dans le RFC 7128.
Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : L. Ciavattone (AT&T Labs), R. Geib (Deutsche Telekom), A. Morton (AT&T Labs), M. Wieser (Technical University Darmstadt)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 6 décembre 2012
Voici le premier RFC à mettre en application la démarche du RFC 6576, qui définissait la méthode pour faire avancer un RFC décrivant des métriques sur le chemin des normes. Si l'IETF avait une grande expérience dans la mesure du déploiement et de la qualité d'un protocole, c'était moins évident pour les métriques, ces grandeurs définies rigoureusement et qu'on cherche à mesurer. Le RFC 6576 ayant déblayé ce terrain, ceci est sa première application : l'étude de l'avancement de la métrique « délai d'acheminement d'un paquet », qui avait été normalisée dans le RFC 2679 et l'est désormais dans le RFC 7679.
Deux mises en œuvre différentes de ce RFC 2679 ont été testées, pour vérifier que leurs résultats, face aux mêmes données, étaient compatibles. C'est le cas et cela plaide en faveur du RFC 2679 : il était clair et non ambigu puisque deux équipes différentes l'ont implémenté de manière compatible. On n'a pas dit « identique » car les métriques permettent une certaine souplesse et, de toute façon, la mesure est un domaine délicat, avec plein de possibilités d'erreur. On ne vérifie donc pas que ces deux programmes donnent les mêmes résultats, mais que leurs résultats sont équivalents, aux erreurs acceptables près.
L'essentiel du RFC est constitué de la description de l'environnement de test, et des mesures effectuées. Les deux implémentations sont NetProbe et Perfas+. NetProbe utilise des paquets UDP de taille variable, et peut produire des distributions de paquets suivant Poisson (RFC 3432) ou bien tout simplement périodiques (RFC 2330). Perfas+, lui (développé par Deutsche Telekom), peut aussi utiliser TCP. Entre deux sites connectés via l'Internet, les expérimentateurs ont monté un tunnel L2TP (RFC 3931), afin de diminuer la variation dans les mesures (autrement, certains équipements sur le trajet auraient pu distribuer le trafic de test sur plusieurs liens, en hachant par exemple les adresses IP des engins de test).
Le trafic passait par netem, un module du noyau Linux qui permet d'ajouter des pertes ou des retards quelconques. (Par exemple, pour le premier test, netem avait été configuré pour ajouter 100 ms de retard, avec une variation uniforme de ±50 ms.)
Les auteurs notent avec honnêteté que les ports des commutateurs étaient en half-duplex, ce qui n'était ni prévu, ni souhaitable (mais ils s'en sont aperçu une fois les mesures faites).
Les tests ont été faits avec des distributions périodiques et de Poisson, des rythmes allant de 1 à 10 p/s et des tailles de 64, 340 et 500 octets, ce que le RFC 2330, section 15, nomme des « paquets standards » (ce qui exclut les fragments).
Des centaines de paquets ont ensuite été envoyés. En conformité avec le RFC 2679 (section 3.8.4), un traceroute a été effectué et ses résultats sont inclus dans le RFC (NetProbe permet de faire le traceroute depuis l'outil, en même temps que la mesure, pour pouvoir analyser a posteriori des résultats surprenants, par exemple des variations inexpliquées).
Étape indispensable (mais pas forcément folichonne) dans une campagne de mesures, l'étalonnage des erreurs est décrite dans la section 4. Par exemple, NetProbe n'utilise pas réellement comme moment d'envoi d'un paquet le wire time défini par le RFC 2330 (il se sert du moment d'acceptation du paquet UDP par le noyau, qui peut être différent si la machine est chargée). L'horloge de la machine est synchronisée avec NTP et la résolution de NTP (typiquement pas mieux qu'une milli-seconde) est également à prendre en compte comme source d'erreur (mais cela peut être amélioré par les méthodes décrites dans la section 4.1 : pour ces mesures, la stabilité de l'horloge est plus importante que sa justesse).
Toutes les sources de l'erreur, après évaluation, ont ensuite été données à R qui nous donne les divers intervalles d'erreur.
Perfas+, lui, utilise un récepteur GPS pour son horloge mais d'autres causes font que ses intervalles d'erreur sont plus larges (et donc moins bons) que ceux de NetProbe.
La section 5 explique ensuite ce que veut dire « équivalent ». En raison de la souplesse de la métrique, et des erreurs dans la mesure, on ne peut pas espérer que les deux logiciels affichent pile les mêmes résultats. On pose donc les limites tolérables, pour une comparaison faite avec Anderson-Darling. (Rappelons que le but de cette expérience n'était pas de mesurer un réseau, mais de savoir si la norme du RFC 2679 était suffisamment bien écrite et précise, et que les implémentations étaient donc équivalentes dans leurs résultats.)
Les tests et leurs résultats figurent en section 6. On note que, dans l'un des tests, un des deux programmes n'a pas réussi le test de l'équivalence avec lui-même (les variations provoquées par le réseau ont été trop grandes). À part ça, toutes les comparaisons Anderson-Darling ont réussi.
La section 7 n'a plus qu'à résumer la conclusion : c'est bon, les deux programmes utilisés sont statistiquement équivalents, ce qui semble indiquer que la norme qu'ils ont tous les deux implémentée était correctement définie. La métrique définie par le RFC 2679 mérite donc d'avancer sur le chemin des normes. Quelques erreurs mineures dans la norme ont été détectées et il est proposé qu'elles soient corrigées dans la prochaine version. (Voir les errata.)
À noter que l'avancement de la métrique sur le chemin des normes a nécessité une nouvelle version du RFC 2679, le RFC 7679.
Une description de l'utilisation de NetProbe sur le réseau d'AT&T est documentée en ligne.
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : J. Hodges (PayPal), C. Jackson (Carnegie Mellon University), A. Barth (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF websec
Première rédaction de cet article le 20 novembre 2012
La technique HSTS (HTTP Strict Transport Security), normalisée dans ce RFC (mais déjà largement déployée) vise à résoudre une attaque contre TLS. Si un site Web est accessible en HTTPS, et qu'un méchant arrive à convaincre un utilisateur de se connecter en HTTP ordinaire à la place, le méchant peut alors monter une attaque de l'homme du milieu. Le fait que le site soit protégé par TLS n'aidera pas dans ce cas. Pour éviter cette attaque, HSTS permet à un site de déclarer qu'il n'est accessible qu'en HTTPS. Si l'utilisateur a visité le site ne serait-ce qu'une fois, son navigateur se souviendra de cette déclaration et ne fera plus ensuite de connexions non sécurisées.
Bien sûr, il n'y aurait pas de problème si l'utilisateur utilisait
systématiquement des URL
https://...
. Mais les erreurs ou les oublis
peuvent arriver, l'utilisateur peut cliquer sur un lien
http://...
dans un spam,
il peut être victime d'une page Web certes sécurisée mais qui contient
des images chargées via un URL http://...
. Bref,
il y a encore trop de risques. D'où l'idée
d'épingler la politique de sécurité du site Web
dans le navigateur, en permettant à un site de déclarer au navigateur
« je suis sécurisé, ne reviens jamais me voir en
HTTP ordinaire » et de compter sur le fait que le navigateur
respectera automatiquement cette politique, et s'en souviendra. Cette déclaration se fera
par l'en-tête HTTP Strict-Transport-Security:
, par
exemple Strict-Transport-Security: max-age=7905600
.
TLS est normalisé dans le RFC 5246. (Son prédécesseur, SSL, est
dans le RFC 6101.) L'utilisation de HTTP au dessus de TLS
(HTTPS) est décrite dans le RFC 2818. Un navigateur Web va typiquement
appliquer des politiques de sécurité différentes selon que la
connexion se fait en HTTP ou en HTTPS. Un exemple typique est fourni
par les cookies du RFC 6265 : s'ils ont été envoyés par le serveur avec
l'attribut Secure
, ils ne seront retransmis par
le navigateur que si la connexion est en HTTPS.
Pour vérifier l'identité du serveur en face, les navigateurs valident les certificats présentés par le serveur. Si cette vérification échoue (c'est en général suite à une erreur de l'administrateur du serveur, mais cela est parfois dû à une attaque d'un intermédiaire), le navigateur affiche typiquement un avertissement à l'utilisateur, en lui permettant de continuer de manière non sûre s'il le souhaite (cette possibilité est « officialisée » par la section 3.1 du RFC 2818). Ce mécanisme de click-through security, que le navigateur rend plus ou moins facile, est très critiqué : comme l'utilisateur veut avant tout continuer sa tâche, il va toujours chercher à passer outre l'avertissement de sécurité. C'est même une attitude raisonnable, compte tenu du fait que la plupart des erreurs d'authentification avec TLS ne sont pas des attaques, et aussi compte tenu de la difficulté, même pour un expert, d'analyser ces problèmes et de comprendre ce qui s'est passé. Deux bons articles sur les questions d'interface utilisateur liées à ce problème de sécurité sont « Crying Wolf: An Empirical Study of SSL Warning Effectiveness » de Sunshine, J., Egelman, S., Almuhimedi, H., Atri, N., et L. Cranor, puis « Stopping Spyware at the Gate: A User Study of Privacy, Notice and Spyware » de Good, N., Dhamija, R., Grossklags, J., Thaw, D., Aronowitz, S., Mulligan, D., et J. Konstan. Mais d'autres articles, non cités par ce RFC, prennent un point de vue différent, expliquant qu'ignorer les avertissements de sécurité peut être une attitude rationnelle.
Pour éviter ces risques, l'article de C. Jackson et A. Barth (deux des auteurs du RFC), « ForceHTTPS: Protecting High-Security Web Sites from Network Attacks » proposait une approche où le site Web disait à ses clients qu'ils devaient utiliser HTTPS pour se connecter. Ce RFC utilise une technique différente de celle de l'article mais l'idée est la même.
La section 2 décrit en détail le problème de sécurité. Si vous êtes plutôt intéressé par la solution, il faut sauter à la section 5. Sinon, si on continue dans l'ordre, une analyse des menaces. HSTS gère trois menaces :
Une analyse de sécurité sérieuse doit indiquer quelles sont les menaces traitées mais aussi celles qu'on ne prétend pas traiter. La section 2.3.2 liste les « non-buts » de HSTS :
https://www.mybank.example/
et qu'un attaquant tente de vous détourner. Mais il ne peut rien faire
si, suite à un spam, vous visitez https://s6712.example.net/php/mybank.example
...Maintenant, place à la solution. L'effet de l'épinglage HSTS sera double :
http://...
par des
https://...
avant de se connecter.Bref, avant de déclarer en HSTS qu'on ne doit être contacté que de manière sécurisée, il faut être sûr de soi...
La section 5 du RFC expose la solution. Comme indiqué plus haut, un
serveur HTTPS qui veut être sûr de n'être accédé qu'en HTTPS le
déclare en envoyant un en-tête
Strict-Transport-Security:
(en-tête désormais
dans le registre des en-têtes). Évidemment, cet
en-tête ne sera utilisé que si la session était sécurisée avec HTTPS
(envoyé sur de l'HTTP ordinaire, il sera ignoré). La
politique HSTS du site comprend une durée de vie
maximale de l'information, et le choix d'inclure ou pas les
sous-domaines. Pour la durée de vie, cela se fait avec une valeur
max-age
en secondes. Le navigateur pourra se
souvenir, pendant ce temps, que le site ne doit être accédé qu'en
HTTPS. Après, il pourra redemander (cela permet éventuellement de ne
plus avoir HSTS, si l'on veut se remettre à autoriser HTTP).
Pour les sous-domaines, c'est fait avec
une directive includeSubDomains
.
La section 6 va davantage dans les détails en couvrant la syntaxe
exacte de cet en-tête. Par exemple, un max-age
de
zéro spécifie que le client HTTP doit tout de suite oublier les choix
HSTS : cela revient à dire « j'arrête d'exiger HTTPS ».
Plusieurs sites Web aujourd'hui utilisent déjà HSTS. Par exemple, Gmail annonce une politique d'une durée d'un mois :
Strict-Transport-Security: max-age=2592000; includeSubDomains
Et l'EFF (qui n'utilise pas l'option
includeSubDomains
mais a presque la même durée de vie) :
Strict-Transport-Security: max-age=2628000
On l'a vu, la syntaxe est simple. Les sections suivantes portent sur une
question plus complexe, le comportement des logiciels lorsqu'ils
rencontrent cette option. D'abord, le serveur (section 7). S'il veut
utiliser HSTS, il met cette option dans la réponse, si elle est
protégée par TLS. Sinon (HTTP ordinaire), le serveur ne doit pas
mettre l'en-tête HSTS et le RFC recommande une redirection (code HTTP
301, par exemple) vers un URL https://
. Notons
que c'est risqué : un attaquant actif peut aussi faire des
redirections, si la requête était en HTTP. Voir l'excellente
« Transport
Layer Protection Cheat Sheet » de Coates, M., Wichers, d., Boberski, M., et T. Reguly.
Et le client HTTP (typiquement un navigateur Web) ? La section 8 lui donne des instructions : si on reçoit l'en-tête HSTS sur une session HTTP ordinaire, l'ignorer (cela peut être une blague, puisque la session n'est pas authentifiée), si on le reçoit sur HTTPS, enregistrer cette information (avec la durée de vie associée). Puis, à la prochaine visite de ce serveur (les règles exactes sont un peu plus compliquées, avec les sous-domaines, et les IDN) :
http://...
, le réécrire automatiquement en
https://...
).
À noter que l'en-tête HSTS doit être envoyé via le protocole réseau, pas via le contenu du document : le truc HTML <meta
http-equiv="Strict-Transport-Security" ...>
est
explicitement interdit.
Les sections 11 et 12 donnent des avis aux programmeurs sur la bonne façon de mettre en œuvre ce système de sécurité. D'abord, les serveurs (section 11). Le RFC leur rappelle que le serveur ne peut pas savoir si son client respecte l'en-tête qu'on lui envoie. On ne peut donc pas compter uniquement sur HSTS pour traiter les menaces décrites en section 2.
Ensuite, le choix de la durée de vie (via l'attribut
max-age
). Il y a deux approches : une durée
constante ou bien un max-age
calculé à chaque
fois pour correspondre à une date d'expiration choisie. La première
est évidemment plus facile à mettre en œuvre (sur
Apache, un Header set
Strict-Transport-Security "max-age=604800"
dans la
configuration ou bien dans un .htaccess
suffit). La seconde nécessite un calcul dynamique mais a l'avantage de
pouvoir faire correspondre la date d'expiration de HSTS avec une autre
date importante (le RFC suggère celle d'expiration du certificat
X.509 ; si on ne renouvelle pas le certificat, c'est une bonne chose
si HSTS cesse également).
Le RFC met aussi en garde contre les certificats auto-signés ou
bien signés par une AC non connue de certains navigateurs (comme CAcert). HSTS interdisant formellement de passer
outre un problème X.509 (pas de formulaire « voulez-vous continuer
bien que je ne connaisse pas cette AC ? »), si on active HSTS en
envoyant l'en-tête Strict-Transport-Security:
, et qu'il est accepté,
on risque, si on change ensuite de certificat, d'être injoignable par tous les clients (cas où on est passé à un certificat
auto-signé) ou par une partie d'entre eux (cas où est est passé à une AC peu
connue). Rappelez-vous que HSTS est une déclaration « je suis un
parano expert en crypto et je ne ferai jamais d'erreur, n'utilisez que
HTTPS ». Réflechissez donc bien avant de l'activer.
Autre piège pour l'administrateur d'un serveur HTTPS, le cas du
includeSubDomains
. Si on l'utilise, on peut
bloquer tout sous-domaine qui ne serait pas accessible en HTTPS. Si
vous gérez le domaine d'une grande entreprise, mettons
example.com
, et que vous mettez un
Strict-Transport-Security: max-age=15768000 ;
includeSubDomains
, alors le petit site Web que vous aviez
oublié, http://service.department.example.com/appli
, qui
n'était accessible qu'en HTTP, deviendra inutilisable pour tous ceux
qui utilisent HSTS. Soyez donc sûr de vos sous-domaines avant
d'activer cette option. (Le RFC cite l'exemple d'une
AC ca.example
qui veut permettre l'accès à
OCSP en HTTP ordinaire : la directive
includeSubDomains
pourrait bloquer
ocsp.ca.example
.) D'un autre côté, sans cette
option, vous n'êtes plus sûr de protéger les
cookies (cf. section 14.4) puisque ceux-ci peuvent
être envoyés à tout serveur d'un sous-domaine. (Avec secure
, ce sera forcément en HTTPS mais pas forcément blindé par HSTS.)
Et pour les auteurs de navigateurs Web ? La section 12 leur dispense de sages conseils. D'abord, elle leur rappelle un principe central de HSTS : pas de recours pour les utilisateurs. Si un site est étiqueté en HSTS et qu'il y a un problème d'authentification, il est interdit de permettre aux utilisateurs de passer outre. HSTS est là pour la sécurité, pas pour faciliter la vie des utilisateurs. Le but est d'éviter qu'une attaque de l'Homme du Milieu soit possible parce que l'utilisateur est trop prêt à prendre des risques.
Une suggestion intéressante pour les auteurs de navigateurs est celle de livrer le logiciel avec une liste pré-définie de sites HSTS (grandes banques, etc), comme ils ont aujourd'hui une liste pré-définie d'AC. Cela permettrait de fermer une des faiblesses de HSTS, le fait que la première connexion, si elle n'est pas faite en HTTPS (et sans erreur), n'est pas sécurisée. Après, on peut imaginer que cette liste soit éditable (possibilité d'ajouter ou de retirer des sites) mais permettre de retirer un site est dangereux : un utilisateur inconscient risquerait de virer un site important et de se retrouver ainsi vulnérable. En tout cas, le RFC dit que cette possibilité de retirer un site ne doit pas être accessible à JavaScript, pour éviter qu'un logiciel malveillant dans une page Web ne s'attaque à la sécurité de HSTS.
Tout ce RFC est évidemment consacré à la sécurité mais la
traditionnelle section Security considerations
(section 14) est néanmoins utile pour évaluer les risques
restants. Ainsi, HSTS ne protège pas contre les attaques
par déni de service. Il peut même les faciliter : par
exemple, un attaquant actif peut envoyer le trafic HTTPS vers un
serveur qu'il contrôle et, si l'utilisateur accepte le certificat
invalide, le serveur pourra alors mettre un
Strict-Transport-Security:
non prévu et qui
empêchera l'accès au serveur légitime dans certains cas. Autre
possibilité, si le navigateur permet à l'utilisateur ou, pire, à du
code JavaScript, d'ajouter un site à la liste locale des sites HSTS,
les sites pas accessibles en HTTPS deviendront inutilisables.
Autre problème que HSTS ne résout pas complètement : la première
connexion. Si, sur une nouvelle machine (dont la mémoire HSTS est
vide), vous vous connectez à
http://www.example.com/
, HSTS ne vous protège
pas encore. Si aucun attaquant n'était là pendant la première
connexion, vous serez redirigé vers
https://www.example.com/
, l'en-tête
Strict-Transport-Security:
définira ce site comme
HSTS et tout sera protégé par la suite. Mais, si un attaquant était
présent au moment de cette première connexion, HSTS ne pourra rien
faire. C'est un des cas où la liste pré-définie de sites HSTS, livrée
avec le navigateur, est utile.
Dernier piège, plus rigolo, un attaquant peut découvrir (par une
combinaison de noms de domaines qu'il contrôle et d'un script tournant
sur le navigateur) si le navigateur a déjà visité tel site HSTS (car,
dans ce cas, les liens vers un URL http://...
seront automatiquement réécrits en
https://...
). Cela permet une forme de flicage du
navigateur (voir la synthèse « Web
Tracking » de N. Schmucker.)
Deux annexes du RFC intéresseront les concepteurs de
protocoles. L'annexe A documente les raisons des choix effectués par
HSTS. Par exemple, la politique HSTS est indiquée par un en-tête et
pas par un cookie car les
cookies peuvent être manipulés et modifiés quand
ils sont dans la mémoire du navigateur. Autre cas qui a suscité des
discussions, le fait que le client HTTPS fasse confiance à la dernière
information reçue via
Strict-Transport-Security:
. Par exemple, si un
serveur annonce un max-age
d'un an le 18 novembre
2012, puis d'un mois le 19 novembre 2012, l'information expirera-t-elle le
18 novembre 2013 ou bien le 19 décembre 2012 ? Avec HSTS, c'est le
dernier en-tête qui gagne, donc l'expiration sera le 19 décembre
2012. C'est peut-être une faiblesse, question sécurité, mais cela
permet aux gérants des sites Web de corriger leurs erreurs (comme un
max-age
excessif).
À propos du max-age
, la même annexe explique
aussi pourquoi il indique une durée et pas une date d'expiration :
c'est pour éviter d'être dépendant de la synchronisation des
horloges. Le RFC donne une autre raison, le fait d'être ainsi
dispensé de la définition et de l'implémentation d'une syntaxe pour
représenter les dates. Cela ne me semble pas convaincant : il existe
déjà une syntaxe normalisée et largement implémentée, celle du RFC 3339. Mais, bon , la sécurité préfère des normes
simples, X.509 est un parfait exemple des résultats auxquels mènent
des normes compliquées.
Quant à l'annexe B, elle explique les différences entre HSTS et la SOP (Same-Origin Policy) du RFC 6454.
Ce RFC normalise une technique déjà largement déployée. Plusieurs sites Web envoient déjà cet en-tête et plusieurs navigateurs le reconnaissent (on trouve deux bonnes listes sur le Wikipédia anglophone).
À noter qu'il y eu des projets plus ou moins avancés de mettre cette déclaration « TLS seulement » dans le
DNS (évidemment avec
DNSSEC) plutôt que dans HTTP. Cela aurait permis de fermer la faille de la première
connexion, et de gérer le cas des autres protocoles sécurisés avec TLS. Deux exemples de cette voie (tous les deux n'ayant pas été poursuivis) : l'Internet-Draft draft-hoffman-server-has-tls
et un article de George Ou.
J'ai testé HSTS avec un Chromium « Version 20.0.1132.47 Ubuntu 12.04 (144678) » et tcpdump qui écoute. Tout marche bien. L'en-tête HSTS est ignoré si le certificat n'a pas pu être validé (AC inconnue). Une fois le certificat validé (AC ajoutée au magasin du navigateur), dès que l'en-tête HSTS a été reçu, plus aucune tentative n'est faite en HTTP, le navigateur file sur le port 443 directement.
Quant à Firefox, voici ce qu'il affiche quand un site qui avait auparavant été accessible en HTTPS authentifié ne l'est plus (ici, parce que le certificat a expiré) :
HSTS est également mis en œuvre dans wget (voir la documentation) et c'est activé par défaut.
Merci à Florian Maury pour sa relecture attentive. Un autre article sur HSTS est celui de Cloudflare.
Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : Q. Vohra (Juniper Networks), E. Chen (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 19 décembre 2012
Un des nombres trop petits de l'Internet était la taille des numéros de système autonome. En 2007, elle était passée, avec le RFC 4893, de deux à quatre octets. Ce nouveau RFC est juste une révision mineure de cette norme.
Il est assez courant dans l'Internet que des nombres prévus très larges au début s'avèrent ridiculement petits avec la croissance du réseau. C'est bien sûr le cas des adresses IPv4, dont les 32 bits sont bien trop peu pour le nombre de machines connectées aujourd'hui, mais c'est aussi vrai pour les numéros de système autonome (AS pour autonomous system). Chacun de ces numéros identifie un système autonome de routage, au sein duquel une politique de routage cohérente peut s'appliquer. En gros, chaque opérateur a un numéro de système autonome, les plus gros en ayant plusieurs (surtout en cas de fusion ou d'acquisition).
Ces numéros sont notamment utilisés par le protocole de routage
BGP (normalisé dans le RFC 4271), pour indiquer le chemin à suivre pour
joindre un réseau. La petite fonction shell bgproute
permet d'interroger les serveurs de Route Views et affiche les numéros
de système autonomes traversés :
% bgproute 80.67.162.1 AS path: 3257 3356 20766 20766 Route: 80.67.160.0/19
On voit que le serveur de Route Views a reçu l'annonce de la part du système autonome 3257 qui l'avait lui même reçu du système autonome 3356.
Ces numéros étaient autrefois stockés sur seulement 16 bits, ce qui ne permettait que 65 535 systèmes en tout, bien trop peu pour l'Internet d'aujourd'hui, qui va des villes chinoises aux hébergeurs brésiliens. Si certains conservateurs, méprisants et élitistes, ont regretté le fait que « n'importe qui, avec une armoire et deux PC avec Quagga » veuille faire du BGP, le fait est que l'Internet touche bien plus de monde et que la population des opérateurs a augmenté. D'où le RFC 4893, qui avait fait passer la taille des numéros d'AS à 32 bits, soit quatre milliards d'opérateurs possibles.
Ces AS de quatre octets s'écrivent en notation
ASPLAIN
, en
écrivant directement le nombre, par exemple
112617
(RFC 5396).
Les nouveaux AS sont ensuite annoncés par l'attribut
AS4_PATH
, n° 17 dans le
registre des attributs.
Le changement lui-même est assez trivial mais, comme souvent sur Internet, le gros du travail était la gestion de la transition. Notre RFC explique avec beaucoup de soin comment un routeur BGP récent va pouvoir parler à un routeur de l'ancienne génération (le routeur doit annoncer sa capacité à gérer les AS de quatre octets avec le capability advertisment n° 65 du RFC 5492). Et comment les chemins d'AS 4-octets pourront être transmis même à travers des « vieux » routeurs, utilisant un mécanisme de tunnel (l'article de Geoff Huston l'explique très bien).
Pour cette transition, le nouveau BGP utilise un numéro d'AS
spécial, le 23456, qui sert à représenter tous
les AS 4-octets pour les anciens routeurs. Si vous voyez apparaitre ce
système autonome, par exemple en tapant un show ip
bgp
sur un Cisco, c'est que votre
logiciel est trop vieux. Ceci dit, cela doit être rare de nos jours,
la gestion de ces AS sur quatre octets étant désormais présente dans
toutes les mises en œuvre sérieuses de BGP.
Les numéros d'AS sur quatre octets sont distribués par les RIR depuis des années (voir par exemple la politique du RIPE-NCC et sa FAQ). Le RIPE-NCC a publié d'intéressantes statistiques à ce sujet, notamment sur le taux de numéros d'AS 32 bits renvoyés au RIPE-NCC car le titulaire s'est aperçu, après coup, qu'il y avait quelques problèmes techniques, chez lui ou chez ses fournisseurs.
L'annexe A résume les différences par rapport au RFC 4893 : rien de vital, juste un toilettage. Notamment, la gestion d'erreurs, absente du précédent RFC, est spécifiée en détail.
Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : B. Briscoe (BT), R. Woundy (Comcast), A. Cooper (CDT)
Pour information
Réalisé dans le cadre du groupe de travail IETF conex
Première rédaction de cet article le 6 décembre 2012
Premier RFC du groupe de travail CONEX de l'IETF, ce document expose les principes de bases du mécanisme de « publication de la congestion » (CONgestion EXposure). L'idée est d'indiquer dans les paquets la congestion prévue, pour que les équipements réseaux puissent prendre des décisions appropriées. Une fois normalisée (ce RFC 6789 n'est qu'une toute première étape), ce sera une des nombreuses techniques permettant de gérer la congestion dans les réseaux TCP/IP et notamment l'Internet.
Il n'y a pas encore de protocole normalisé pour cette « publication de la congestion » (les deux premiers utiliseront une option IPv6 et une option de TCP). Pour l'instant, notre RFC s'en tient à des usages : à quoi cela pourrait servir. La congestion est clairement une des plaies du réseau. La force de TCP/IP est de multiplexer la capacité des liens au niveau des paquets et pas des circuits. Cela permet une utilisation bien plus efficace du réseau. Mais cela ne crée pas magiquement de la capacité : quand trop de paquets rencontrent trop peu de capacité, la congestion survient. Elle se manifeste par des pertes de paquets (le routeur, n'arrivant pas à suivre, abandonne certains paquets), mais aussi par des retards (si les tampons du routeur amortissent la congestion, ils augmentent les délais d'acheminement), et par le marquage ECN (RFC 3168) de certains paquets.
Le récepteur des données est censé détecter ces signaux (un trou dans la séquence TCP, des RTT qui augmentent, les marques ECN) et il doit alors dire à l'émetteur de ralentir. Ce fonctionnement où seules les machines terminales agissent (les routeurs intermédiaires, à part éventuellement des marques ECN, n'ont pas grand'chose à faire, ils se contentent de router) est typique de l'Internet mais, dans certains cas, exposés dans ce RFC, il est insuffisant.
L'idée de base de ConEx est que l'émetteur mette dans les paquets IP qu'il envoie des indications sur la congestion qu'on lui a signalé. Ainsi, des équipements qui sont purement de niveau 3 sur le trajet peuvent être informés de la congestion (ECN les informe aussi mais ne concerne que les équipements en aval du point où est détectée la congestion, cf. figure 1 du RFC). Ainsi, le réseau pourra avoir une meilleure vision de la congestion, comptant les paquets qui vont rencontrer de la congestion aussi facilement qu'il compte aujourd'hui les paquets ou les octets.
Pourquoi est-ce important de connaître les paquets qui vont circuler dans des parties du réseau où il y a congestion ? Déjà, cela a une importance économique : un réseau ne coûte pas plus cher qu'il soit utilisé ou pas. Un trafic qui emprunte le réseau à un moment où celui-ci est peu chargé ne coûte donc rien à l'opérateur du réseau. Par contre, la congestion coûte cher puisqu'elle est le signe qu'il faut sortir son carnet de chèques pour mettre à jour le réseau, vers des capacités plus grandes. Ainsi, ConEx pourrait être une brique de base pour un système qui pénaliserait uniquement les flots de données qui contribuent à la congestion.
La section 2 présente en détail les concepts et la terminologie ConEx. D'abord, évidemment, la congestion. Tout le monde en parle mais il n'y a pas de définition rigoureuse et unique pour ce concept. Pour une analyse de ce terme, voir « The Evolution of Internet Congestion » de S. Bauer, S., D. Clark et W. Lehr. Dans ConEx, la congestion est définie comme la probabilité de perte de paquet (ou de marquage par ECN). Un autre effet de la congestion, le retard, n'est pas pris en compte (donc, ConEx ne mesurera pas l'effet du bufferbloat).
Deuxième concept, le volume de congestion. Il s'agit du nombre d'octets perdus suite à la congestion. L'idée est de rendre les émetteurs responsables : envoyer 10 Go sur un lien congestionné n'est pas la même chose que d'y envoyer quelques octets. Par exemple, si Alice envoie un fichier d'un Go sur un lien où la probabilité de perte est de 0,2 %, son volume de congestion est de 2 Mo. Si, plus tard dans la journée, elle envoie un fichier de 30 Go alors que la ligne, moins encombrée, ne perd plus que 0,1 % des paquets, elle ajoutera 3 Mo à son volume de congestion (donc, 5 Mo en tout). L'un des intérêts de cette métrique est qu'elle est très facilement mesurable par un routeur : il lui suffit de compter le volume total des paquets qu'il a dû jeter (ou marquer avec ECN, s'il utilise cette technique). C'est donc quasiment la même chose que les compteurs de volume actuels.
Troisième concept important, la congestion aval (Rest-of-path congestion ou downstream congestion dans la langue de Van Jacobson). C'est celle que le flot de données va supporter entre le point de mesure et sa destination (la congestion amont étant évidemment celle entre la source et le point de mesure : aujourd'hui, elle est bien plus difficile à mesurer si on n'utilise pas ECN).
La section 3 décrit ensuite le principal scénario d'usage envisagé pour ConEx. Si vous vous demandez « mais à quoi sert ce truc ? » depuis tout à l'heure, vous allez bientôt avoir une réponse. Soit un opérateur réseau qui a des clients. La plupart consomment peu mais certains sont des acharnés et font passer en permanence des gigaoctets à travers le réseau. L'opérateur voudrait que les mesures désagréables qu'il va prendre pour limiter la congestion frappent en priorité ces gros consommateurs.
Il va pour cela placer un équipement qui regarde les indications de congestion ConEx et va ensuite limiter le trafic en fonction de ces indications (en fonction du volume de congestion). (Les limitations de trafic habituelles visent le débit, pas la participation à la congestion. Or comme on l'a vu, débiter 100 Mb/s sur un réseau vide n'est pas du tout la même chose que de le débiter sur un réseau chargé. Il est donc dommage de limiter le débit dans tous les cas.) L'article « Policing Freedom to Use the Internet Resource Pool » de B. Briscoe, A. Jacquet et T. Moncaster, détaille ce mécanisme. La force de cette méthode est qu'aucune limite, aucune mesure contraignante et désagréable, n'est prise lorsqu'il n'y a pas de congestion (car, dans ce cas, l'usage du résau ne coûte rien). Avec ConEx, un bit n'est plus égal à un bit : celui envoyé pendant la congestion coûte plus cher au réseau et doit donc, d'une certaine façon, être « payé » par l'utilisateur.
Si l'opérateur est un FAI ADSL, un bon endroit pour mettre cette supervision de la congestion et cette limitation du trafic est sans doute le BRAS. (Voir le rapport du DSL Forum « Technical Report TR-059: Requirements for the Support of QoS-Enabled IP Services » mais il ne semble pas en ligne.)
Ainsi, les utilisateurs seront encouragés à utiliser des protocoles que notre RFC appelle « charognards » dans la mesure où ils n'utilisent que la capacité dont personne ne veut (le charognard a une mauvaise image de marque mais c'est bien à tort : il consomme les ressources négligées par tous les autres). Ces protocoles n'envoient du trafic que lorsque le réseau est inutilisé. Leur coût est donc à peu près nul pour l'opérateur. Le RFC 6297 décrit ces protocoles. Pour encourager leur usage, on ne peut pas seulement compter sur des exhortations citoyennes, dont l'écologie montre le peu d'efficacité. Il faut aussi des motivations plus pratiques.
Mais il existe d'autres approches, déjà, pour ce genre de gestion (ralentir les gros consommateurs, ceux qui sortent franchement du rang), non ? La section 3.3 les examine :
Toutes ces solutions ont un autre défaut en commun : elles laissent l'utilisateur dans l'incertitude des performances qu'il obtiendra. Le principal intérêt des tarifs forfaitaires pour l'accès Internet (je parle des vrais forfaits, ceux où le prix est connu d'avance, pas de ce que les commerciaux menteurs de la téléphonie mobile appelent « forfait ») est la certitude : pas de mauvaises surprises au moment de l'arrivée de la facture. Mais cette certitude ne porte que sur les prix. Les performances, elles, peuvent varier, par exemple si le trafic émis était tel qu'on est désormais limité. Au contraire, avec Conex, l'utilisateur est en mesure de voir sa propre contribution à la congestion, et peut ajuster son comportement en fonction de cela. (À mon avis, c'est une vision un peu idéale, car elle suppose que le réseau n'agit sur les performances qu'en réponse aux indicateurs ConEx.)
Ce scénario d'usage de la section 3, informer l'opérateur sur la contribution des utilisateurs à la congestion, est le principal but de ConEx à l'heure actuelle. Les versions initiales de ce RFC traitaient sur un pied d'égalité plusieurs scénarios mais le groupe de travail, après bien des discussions, a décidé de prioritiser celui qui semblait le plus prometteur. Ceci dit, la section 4 présente quelques autres cas d'usage :
La section 5 se penche ensuite sur le déploiement de ConEx. Ce système ne nécessite pas un accord simultané de tous les acteurs (heureusement). ConEx est donc utile même si certains routeurs du trajet ne marquent pas et même si certains ne lisent pas l'information ConEx.
Par contre, il faut qu'au moins deux acteurs bougent : au moins un routeur doit marquer les paquets et au moins une machine doit réagir et signaler la congestion dans les paquets qu'elle émet. Les développeurs d'une application Ledbat (voir RFC 6297 et RFC 6817), par exemple, peuvent se lancer en espérant que cela motivera les routeurs pour s'y mettre.
Si certains paquets sont marqués par ConEx et d'autres non, que va faire le routeur ? Pour le déploiement de ConEx, il serait préférable que les paquets marqués soient favorisés d'une manière ou d'une autre. Mais comme la raison du marquage est leur contribution à la congestion, ce n'est pas forcément idéal... En outre, cela soulève un problème de sécurité (le marquage n'est pas authentifié et une machine peut mentir) sur lequel ce RFC 6789 est complètement muet (le problème sera traité dans les futurs RFC, plus concrets).
Comme ConEx va tripoter dans la couche 3, cœur de l'Internet, il risque de perturber le fonctionnement d'IP. Il faut donc considérer ConEx comme plutôt expérimental et la section 6 fait la liste des questions encore ouvertes, par exemple :
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : J. Levine (Taughannock Networks), R. Gellens (Qualcomm)
Pour information
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 7 novembre 2012
Depuis la sortie du RFC 6530 et de ses petits
camarades, il existe désormais une solution normalisée pour avoir du
courrier
électronique complètement internationalisé, y compris les
adresses (arôme@café.fr
...). Mais comment est-ce
que cela s'applique aux listes de diffusion ?
Peut-on avoir des listes où certains membres accepteraient les
nouvelles adresses et d'autres non ? Ce RFC,
successeur du RFC 5983, se
penche sur la question. Pour l'instant, la réponse est pessimiste : il
n'y a pas de moyen pratique de faire coexister anciens et nouveaux sur
la même liste.
Une liste de diffusion prend un message et le redistribue à N destinataires. Certains de ces N destinataires seront derrière un serveur de messagerie récent, qui gère les adresses internationalisés. Une partie de ceux-ci, en outre, auront des adresses internationalisées. Même si le destinataire, lui, n'a pas une adresse internationalisée, si l'émetteur en a une, ses messages ne pourront pas être remis aux gens qui ont les vieux logiciels.
Il y a donc un problème technique, le fait que des adresses internationalisées soient refusées par certains. Et il y a un problème humain : en communicaton bilatérale, après quelques essais, on peut toujurs trouver une solution technique qui permette la communication. Sur une liste, ce n'est plus possible, l'émetteur ne connait pas les destinataires et réciproquement. Il n'y a pas d'ajustement possible.
Autre problème : idéalement, la liste ne modifie pas le
message, à part par l'ajout de certains en-têtes spécifiques aux
listes (comme List-Unsubscribe:
ou
List-Id:
, normalisés dans le RFC 2369 et
RFC 2919). Toutefois, un certain nombre de listes vont plus
loin et, bien que cela soit une source d'ennuis connue, modifient d'autres
en-têtes comme Reply-To:
voire, pire,
From:
.
Pour synthétiser, il y a trois services différents qui peuvent marcher ou pas :
évolution-langue@académie-française.fr
,étienne@massé.fr
,Ces trois capacités sont relativement indépendantes (la deuxième et la troisième impliquent des logiciels différents donc l'une peut marcher et pas l'autre).
Le plus simple pour une liste qui veut gérer parfaitement
l'internationalisation serait de n'avoir que des abonnés qui eux-même
ont la gestion complète des adresses en Unicode
(option SMTPUTF8
de SMTP,
cf. RFC 6531). Pour cela, le mieux est de tester
lors de l'inscription, et de refuser l'abonnement de ceux qui ont le
vieux logiciel. Pour ce test, si le candidat à l'abonnement s'abonne
avec une adresse Unicode, c'est facile : s'il reçoit le message de
confirmation, c'est bon. Et s'il s'abonne avec une adresse
ASCII ? Alors, le mieux est de tester en
tentant de leur envoyer le message « répondez pour confirmer » depuis une
adresse Unicode.
Mais pour la majorité des listes, qui voudront accepter des abonnés
SMTPUTF8
et d'autres qui ne le sont pas ? (Fin
2012, très peu de serveurs de messagerie, à part en
Extrême-Orient, gèrent
SMTPUTF8
.) Il n'existe pas (ou plus, cf. RFC 5504) de mécanisme de repli automatique d'un
message aux adresses Unicode vers un message traditionnel. C'est donc
au MLM (Mail List Manager, le logiciel de gestion de la liste, par exemple Mailman) de faire ce repli.
D'abord, le logiciel de gestion de la liste doit déterminer quels
abonnés sont SMTPUTF8
et lesquels ne le sont
pas. Il y a plusieurs méthodes :
Ensuite, il faut décider, pour chaque message entrant vers la liste,
s'il est internationalisé ou pas. Cela peut se faire en considérant
que, si l'option SMTPUTF8
a été utilisée dans la
session, le message sera marqué comme « Unicode ». Ou bien on peut
examiner les en-têtes du message, à la recherche d'adresses en
Unicode.
Les logiciels de gestion de liste réécrivent en général l'émetteur
dans l'enveloppe SMTP du message. Ils mettent
leur propre adresse (par exemple ima-bounces@ietf.org
pour la liste du groupe de travail EAI, ex-IMA) ou même
ils mettent une adresse d'origine différente pour chaque abonné, pour
mieux gérer les messages de non-remise (technique
VERP). Dans les deux cas, l'adresse d'émetteur,
qui recevra les messages de non-remise, contient en général le nom de
la liste. Dans ce cas, elle sera une adresse Unicode et les serveurs
ne connaissant pas le courrier complètement internationalisé ne
pourront donc pas envoyer ces avis de non-remise
(bounces).
La section 3 contient les recommandations concrètes. D'abord, pour
les en-têtes ajoutés comme List-Id:
, la
recommandation est de les mettre sous une forme purement ASCII, pour
limiter les risques, même si cet en-tête prend comme valeur un
URI (comme le fait List-Unsubscribe:
) et que cet URI a un plan
(scheme) qui permet l'Unicode. Il faut dans ce cas
utiliser l'« encodage pour-cent ». Donc, pour une liste
pause-café@bavardage.fr
, on aura :
List-Id: Liste de discussion en Unicode <pause-caf%C3%A9@bavardage.fr> 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>
Dans certains cas, cela ne donnera pas un résultat lisible (par
exemple le List-Id:
d'une liste en
chinois encodé en ASCII ne va pas être
tellement utile aux lecteurs...) Mais cet inconvénient semble, aujourd'hui, moins
grave que le risque de faire arriver de l'Unicode à des gens qui ne
s'y attendent pas. Une meilleure solution devra attendre une nouvelle
version des RFC 2369 et RFC 2919.
Le RFC n'a pas de recommandation pour le cas où un auteur d'un
message a une adresse Unicode et où le gestionnaire de listes essaie
de diffuser le message à un abonné n'ayant que des logiciels anciens,
ne gérant pas SMTPUTF8
. Il n'y a pas de bonne
solution technique, juste des petits arrangements : réserver la liste
aux gens pouvant recevoir du courrier internationalisé (cf. plus haut
la discussion sur de telles listes), proposer aux abonnés
d'enregistrer une adresse ASCII et remplacer le
From:
par cette adresse avant de transmettre ou
enfin remplacer le From:
par une adresse de la
liste. Reste à programmer cela...
Je ne connais pas encore de « grand » 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 toujours au stade de la réflexion sur ce point.
Notre RFC ne contient pas de liste des
changements depuis le RFC 5983. Il y a eu réécriture complète puisque
le repli automatique et les adresses de secours
(alt-address
) ont été retirées de la norme finale
du courrier internationalisé.
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : V. Kuarsingh (Rogers Communications), L. Howard (Time Warner Cable)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 7 novembre 2012
Parfois, je me dis que si on consacrait tous les efforts qui ont été voués à écrire des RFC à propos d'IPv6 à déployer IPv6 au lieu d'expliquer comment le faire, ce protocole aurait remplacé IPv4 depuis longtemps... Toujours est-il que voici un nouveau RFC, consacré à la synthèse de l'état de l'art en matière de déploiement incrémental d'IPv6 pour un opérateur filaire (FAI ADSL ou câble par exemple).
« Incrémental » car peu d'opérateurs ont la possibilité de déployer un réseau purement IPv6. Par contre, je ne sais pas pourquoi le RFC se limite au filaire, la plus grande partie de son texte peut tout à fait s'appliquer aussi bien à un opérateur mobile (genre 3G).
Plein de textes ont déjà été écrits sur ce même sujet mais les choses changent et il est peut-être bon de temps en temps de refaire une synthèse. Donc, l'idée est de prendre par la main un opérateur qui, en 2012, serait toujours en IPv4 pur (c'est donc un opérateur assez retardé techniquement), pour l'amener (à long terme !) en IPv6 pur (cf. section 3.6). Le point important à garder en mémoire est que chaque opérateur est différent et que, s'il existe plusieurs mécanismes de migration d'IPv4 vers IPv6, ce n'est pas uniquement parce que l'IETF aime écrire beaucoup de RFC, c'est surtout parce qu'il n'y a pas un mécanisme qui conviendrait miraculeusement à tous les cas (cf. le RFC 6180 qui décrivait tous ces mécanismes).
Donc, point de départ, un opérateur Internet qui a des clients en IPv4 (et qu'il n'est pas question de migrer immédiatement), qui veut déployer IPv6 mais en ne cassant pas ce qui existe, en minimisant la quantité de travail nécessaire (donc sans déployer de technologies inutiles). En outre, on veut une qualité de service optimum, donc éviter les tunnels, si possible.
Avec un tel cahier des charges, une migration soudaine de tout le réseau d'un protocole vers un autre est hors de question. Il faut une démarche progressive, où IPv6 arrive petit à petit pendant qu'IPv4 continue de fonctionner correctement. Le problème, c'est que, sur le papier, une telle approche progressive (phased approach) est très sympa mais, en pratique :
Le RFC rappelle que le client final, le mythique « M. Michu », ne demande pas IPv6. Il ne demande pas IPv4 non plus. Il veut un accès à l'Internet, point. C'est aux professionnels de faire en sorte que son accès fonctionne, aussi bien en IPv4 qu'en IPv6. Les deux protocoles coexisteront sur le réseau local pendant encore longtemps (section 3.1 du RFC).
La section 3 du RFC examine plus en détail ces défis pratiques. La pénurie de plus en plus aiguë d'adresses IPv4 va nécessiter du partage d'adresses IP, avec tous ses inconvénients (RFC 6269, et la section 4.2 de notre RFC). Les autres solutions (gratter les fonds de tiroir à la recherche de préfixes oubliés, acheter au marché gris ou noir des adresses vendues sans garantie) ne suffiront sans doute pas.
Mais IPv6 ne peut pas se déployer en cinq minutes. Sans même prendre en compte l'existence de vieux systèmes ne parlant qu'IPv4, l'opérateur qui va déployer IPv6 va devoir prévoir une période d'assimilation des nouvelles pratiques (IPv6 est très proche d'IPv4 mais pas identique). Souvent, les humains ne sont pas au même niveau en IPv6 qu'en IPv4, et c'est pareil pour les logiciels (pas toujours testés au feu). Si la connectivité IPv4 de l'opérateur va dépendre de sa connectivité IPv6 (comme c'est le cas avec certaines techniques comme DS-Lite - RFC 6333 - ou NAT64 - RFC 6146), un problème IPv6 va également toucher IPv4.
Il faut donc faire attention à ne pas déployer IPv6 sans supervision et de réaction adaptés. Trop souvent, des organisations ont mis un peu d'IPv6, se disant que c'était facile et sans conséquences, puis se sont aperçu après qu'un réseau non géré était moins utile : pannes IPv6 non détectées par le système de surveillance, par exemple.
Certaines des techniques de transition n'ont pas aidé, en proposant des mécanismes qui avaient l'avantage de permettre de faire de l'IPv6 rapidement, et l'inconvénient de fournir aux utilisateurs un vécu de moins bonne qualité. C'est le cas notamment avec les tunnels (tous les tunnels ne sont pas forcément mauvais mais, dans l'histoire d'IPv6, il y a eu beaucoup de problèmes à cause de certains tunnels) : ajoutant une complication supplémentaire, forçant le passage par un chemin qui n'est pas toujours optimum, les tunnels ne devraient être utilisés que lorsqu'il n'y a pas d'autre choix, et en toute connaissance de cause. L'objectif est bien de fournir de la connectivité native.
Avec ces défis en tête, la section 4 du RFC rappelle les techniques de transition et de coexistence possibles. La première citée est la catégorie des tunnels automatiques, 6to4 et Teredo, à mon avis la pire (le RFC 6343 documente certains des problèmes avec 6to4 et le RFC 7526 demande qu'il ne soit plus utilisé). Le problème de fond de ces techniques est qu'elles ne fournissent aucun moyen de contrôler le chemin de retour, ou même de savoir s'il existe. Elles ne devraient à mon avis être utilisées que si on veut décourager les gens de faire de l'IPv6
6rd (RFC 5969) bouche certains des trous de 6to4 et c'est la technique qu'a utilisé Free pour distribuer IPv6 sur son réseau, en attendant un hypothétique accès natif. Son principal avantage est qu'il limite l'investissement initial pour l'opérateur, lui permettant de croître progressivement.
DS-Lite (RFC 6333) tunnele l'IPv4 sur un réseau IPv6. Il est surtout intéressant pour un opérateur qui part de zéro (par exemple parce qu'il vient de se créer) et qui peut donc construire un réseau entièrement IPv6 (ce qui peut être difficile avec certains équipements, encore aujourd'hui), tout en ayant des clients IPv4 à satisfaire. Le CPE doit être capable de faire du DS-Lite donc cette solution marche mieux si le FAI contrôle les CPE.
NAT64 (RFC 6146) est pour le cas où les clients sont bien en IPv6 mais où certains services à l'extérieur ne sont accessibles qu'en IPv4. Elle ne semble donc pas d'une grande actualité aujourd'hui, puisque le réseau local purement IPv6 est encore dans le futur (voir RFC 6586). Elle sera plus utile lorsque les réseaux purement IPv6 devront accéder aux derniers dinosaures IPv4.
La technique de coexistence IPv4/IPv6 qui donne les meilleurs résultats, est la double pile (dual stack) où les machines ont les deux protocoles et deux adresses. Pour permettre l'étape suivante (IPv6 pur), elle nécessite un réseau entièrement IPv6 (y compris les services, par exemple le DNS). Elle ne résout pas le problème de l'épuisement des adresses IPv4 donc, pour un opérateur actuel, le vécu IPv4 restera marqué par le partage d'adresses, le CGN et autres horreurs.
À noter que j'ai fait un exposé comparant toutes ces techniques de transition en 2011 à Grenoble.
Après les défis, et les techniques disponibles, la section 5 présente les différentes phases du déploiement. Une organisation qui va passer à IPv6 peut utiliser cette section comme point de départ pour établir son propre plan de migration. Il est important de noter que ce RFC ne fournit pas un plan tout prêt adapté à tout le monde. Il fournit des lignes directrices, mais chacun doit créer son propre plan, en tenant compte de son réseau, de ses clients, de ses moyens humains et financiers. (Une vision plus technique est dans le RFC 6180.)
La section 5 liste successivement plusieurs phases. J'espère qu'en 2012, plus personne n'en est encore à la phase 0 mais on ne sait jamais... La phase 0 commence par la formation : si personne dans l'organisation (ou bien seulement un ou deux geeks) ne connait IPv6, il faut apprendre. Cela peut se faire par des formations formelles, ou en lisant des livres ou des textes sur le Web. Pour le personnel d'exécution, le RFC rappelle qu'il vaut mieux que la formation soit faite juste avant le déploiement, pour qu'elle ne soit pas oubliée lorsque le moment de s'en servir viendra. Cette phase 0 ne doit pas être purement théorique, et il faut aussi pratiquer, dans un laboratoire dédié à cet effet, à la fois pour que les gens apprennent par la pratique, et pour tester si les matériels et logiciels utilisés dans l'organisation n'ont pas de problème avec IPv6.
Armé de cette formation et de cette expérience en laboratoire, les techniciens peuvent alors commencer à planifier le futur routage IPv6 de leur réseau. Est-ce la même tâche qu'en IPv4 ? On peut argumenter dans un sens ou dans l'autre. Le RFC met plutôt l'accent sur les différences mais on peut aussi considérer que le modèle de routage est tellement proche dans les deux protocoles qu'il ne faut pas dramatiser les différences.
Outre la politique de routage, trois autres points doivent retenir l'attention de l'équipe qui conçoit le plan de migration vers IPv6 :
On peut espérer qu'en 2012, la plupart des grosses organisations sérieuses ont au moins franchi la phase 0. Mais pas mal de petites organisations ne l'ont même pas encore commencé.
Étape suivante, la phase 1. Il s'agit cette fois de donner un accès IPv6 à ses clients ou utilisateurs, via des tunnels pour l'instant, car le réseau n'est pas forcément prêt pour de l'IPv6 natif partout. Par exemple, il est courant que le réseau interne d'un opérateur, équipé de routeurs récents, permette IPv6 mais que l'accès aux clients passe par des équipements qu'on ne contrôle pas complètement (par exemple des DSLAM) et qui ne sont pas prêts pour IPv6. (Notez qu'il n'est pas obligatoire de passer par toutes les phases. Si on a un réseau où on peut utiliser du natif tout de suite, nul besoin d'un détour par des tunnels.) La phase 1 peut se faire avec une technologie comme 6rd (RFC 5569), si on contrôle le CPE.
Naturellement, à cette phase 1, il n'y aura pas de miracle : on utilisera des tunnels, donc on aura les problèmes associés aux tunnels comme la MTU diminuée.
Ensuite, place à la phase 2. Cette fois, on fournit de l'IPv6 natif. Tout fonctionne en IPv6 et, surtout, avec le même niveau de qualité qu'en IPv4. C'est un point très important car un certain nombre de fournisseurs qui se vantent de permettre IPv6 ne surveillent pas automatiquement la connectivité IPv6 (laissant les clients faire cette surveillance) et, même lorsqu'on leur signale un problème, le traitent uniquement dès qu'ils ont du temps libre (alors qu'un problème IPv4 est traité immédiatement). Un niveau de service équivalent à celui d'IPv4 est crucial si on veut convaincre les clients de migrer. Si vous faites l'audit du niveau de préparation IPv6 d'un fournisseur d'accès ou d'hébergement, ce sont les meilleurs tests : 1) le monitoring est-il également fait pour IPv6 ? 2) en cas de panne IPv6, y a-t-il le même niveau de mobilisation que pour IPv4 ? (Ou bien, est-ce que le NOC réagira en se disant « ah, IPv6, c'est Richard, on va attendre qu'il revienne de vacances », ce qui est le cas de la majorité des sociétés prétendant faire de l'IPv6 aujourd'hui.)
À ce stade, il faut encore fournir le service IPv4. Compte-tenu de l'épuisement des adresses, il faudra probablement déployer du CGN/NAT444, peut-être avec l'aide de technologies comme DS-Lite (RFC 6333). Au début du déploiement, le CGN peut encore être une grosse machine centrale puis, si son usage croît, être réparti petit à petit sur d'autres machines.
Normalement, l'usage d'IPv4 devrait ensuite suffisamment baisser pour qu'on puisse passer à la phase 3, un réseau purement IPv6. En novembre 2012, au moment où j'écris ces lignes, cela semble une perspective très lointaine, sauf peut-être sur des réseaux très spécifiques. Mais cela arrivera bien un jour.
Même dans ce cas, il est possible qu'il faille fournir une connectivité IPv4 à certains clients. DS-Lite, qui tunnele le trafic IPv4 sur le réseau IPv6, est là encore utile. Si, ce qui est plus vraisemblable, on a juste besoin de permettre l'accès des clients IPv6 à des sites Web qui sont restés en IPv4, NAT64 (RFC 6144 et RFC 6146) sera sans doute la bonne solution. Mais, bon, c'est un problème pour le futur... Le RFC a un ton plutôt pessimiste et, à mon avis, voit le verre IPv6 plutôt à moitié vide.
Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : O. Kolkman (NLnet Labs), W. Mekking (NLnet Labs), R. Gieben (SIDN Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 22 décembre 2012
Comme avec toute technique fondée sur la cryptographie, le protocole DNSSEC impose, non seulement des bons algorithmes et une mise en œuvre correcte, mais surtout des procédures rigoureuses et soigneusement exécutées. C'est le but de ce RFC, qui remplace le RFC 4641 et qui explique tout ce à quoi doivent s'attendre les registres et autres administrateurs de zones DNS, grandes ou petites, qui déploieraient DNSSEC. (Le cas des serveurs DNS récursifs, par exemple les résolveurs d'un FAI, n'est pas étudié.)
Notre RFC rappelle donc des concepts de base du
DNS (notamment le fait que la réjuvénation des
modifications n'est pas instantanée) puis rappelle les différentes
clés (cf. section 1.1 pour une définition précise de clé) utilisées par DNSSEC et leurs caractéristiques souhaitables
(longueur, période maximale pendant laquelle on les utilise, lieu de
stockages, etc). Tout n'est pas encore bien connu dans ce
domaine. Certes, la racine est signée depuis
juillet 2010, ainsi que plus de 80
TLD mais, au niveau en dessous du TLD, peu de
zones sont signées (dans les 1 % de
.fr
, par exemple) et
l'expérience opérationnelle peut donc encore être améliorée.
Il explique ensuite les considérations temporelles (DNSSEC utilise le temps et nécessite des horloges bien synchronisées, par exemple par NTP). Le DNS étant hiérarchique, il faut veiller, lors de toutes les manipulations, à bien rester synchronisé avec le gérant de la zone parente, dont les enregistrements de type DS (delegation signer) pointeront vers notre clé. Le but est, qu'à tout moment, une chaîne de confiance intacte aille de la clé de confiance jusqu'aux enregistrements du domaine. Si un lien de cette chaîne casse, le domaine sera marqué comme bogus (RFC 4033, section 5) et rejeté par les résolveurs validants.
Enfin, le RFC étudie le rollover, le remplacement d'une clé. Les clés ne pouvant pas raisonnablement être utilisées éternellement, il faut prévoir à l'avance les remplacements périodiques et aussi, hélas les remplacements en urgence en cas de compromission. Il faut apporter beaucoup de soin à ce remplacement, si on veut éviter que, pendant une certaine période, les données publiées dans le DNS soient invalides et donc rejetées par un résolveur DNS paranoïaque (il faut publier la nouvelle clé suffisamment à l'avance pour qu'elle soit présente partout ou bien signer tous les enregistrements avec les deux clés, l'ancienne et la nouvelle). Mon article à la conférence SATIN en 2011 avait montré que c'était loin d'être le cas : les erreurs sont fréquentes, même pour les grandes zones sérieuses.
Bref, pour un gérant de zone DNS, déployer DNSSEC, ce n'est pas uniquement signer la zone : c'est aussi mettre en place des procédures de sécurité, analogues à celle d'une autorité de certification.
Maintenant, avec la section 3, voyons les détails pratiques. D'abord, la génération et le stockage des clés cryptographiques. D'abord, un message d'espoir : en lisant ce RFC, on peut avoir l'impression d'un ensemble de tâches très compliquées, impossible à réaliser correctement. Heureusement, il existe déjà des logiciels qui, en automatisant la plupart de ces tâches, rendent les choses bien plus faciles. J'utilise pour cela OpenDNSSEC.
D'abord, avant de se lancer, il faut faire certains choix technico-politiques :
Expire
du SOA, le temps de réaction souhaité en
cas de problème ? Il faut aussi se demander si NOTIFY
(RFC 1996) marche bien (ou si on ne peut compter que sur le paramètre
Refresh
de l'enregistrement SOA) et si on utilise
IXFR
(RFC 1995) ou
AXFR
,
Une fois ces choix faits, on pourra configurer le résultat (dans
OpenDNSSEC, fichier /etc/opendnssec/kasp.xml
). Mais que choisir ?
Pour le choix entre une séparation KSK/ZSK et une clé unique, le choix est purement un problème opérationnel du côté du gestionnaire de zone. Les résolveurs ne feront pas de différence.
Un problème à garder en tête pour le stockage des clés est le risque de compromission de la clé (vol du disque sur lequel se trouve la partie privée de la clé, par exemple). Si la clé privée est sur le disque d'une machine connectée à l'Internet, le risque est plus élevé que s'il est sur une machine déconnectée et enfermée dans un coffre-fort. Encore mieux, pour les plus riches, l'usage des HSM permet d'être raisonnablement sûr qu'il n'y aura pas de vol de la clé. D'un autre côté, pour signer des enregistrements, une clé sur une machine non-connectée est certainement moins pratique. Une des façons de résoudre le dilemne est de séparer KSK et ZSK : on met la KSK en sécurité dans un endroit bien protégé (elle ne sert qu'à signer la ZSK, qui ne change pas tous les jours) et on fait les signatures des enregistrements de la zone avec la ZSK. En cas de compromission de la ZSK, son remplacement est relativement simple, puisqu'il est entièrement interne à la zone, il ne nécessite pas d'interaction avec la zone parente. (C'est ainsi, par exemple, que fonctionne la racine.)
Comme toujours en sécurité,il y a un fort risque de blinder la porte en oubliant la fenêtre : il ne sert pas à grand'chose de protéger la KSK avec des précautions de niveau militaire si les données de la zone, celles qu'on va signer, peuvent être facilement modifiées par un attaquant (encore que le RFC oublie de dire que la possession de la clé privée permette de générer des enregistrements mensongers sans que le registre s'en aperçoive). De même, le HSM empêche certes le méchant de copier la clé privée, mais il ne l'empêche pas de signer : si le pirate prend le contrôle de la machine connectée au HSM, il peut faire signer à ce dernier ce qu'il veut. Bref, il n'y a pas de solution miracle en matière de sécurité.
Séparer KSK et ZSK permet donc plus de souplesse dans la gestion de la sécurité. Mais cela rend les choses plus complexes. Si les clés sont gérés automatiquement par un outil comme OpenDNSSEC, ce n'est pas trop un problème. Sinon, il vaut peut-être mieux n'avoir qu'une clé.
Une question qui agite les milieux DNSSEC depuis de nombreuses années est celle du remplacement (rollover) des clés. Il y a deux écoles :
Notre RFC note qu'il n'y a pas consensus sur cette question. Il note
qu'un facteur important est « est-ce que la clé est utilisée comme
clé de confiance quelque part ? », c'est-à-dire est-ce que des gens
l'ont configuré dans leur résolveur validant (directives trusted-keys
ou managed-keys
de
BIND et trust-anchor
ou trust-anchor-file
de
Unbound) ? Cela peut se faire, par exemple pour
éviter de dépendre de la hiérarchie du DNS (on peut imaginer une clé
DNSSEC de gouv.fr
installée dans les résolveurs
des ministères pour être sûr de ne pas être affectés par des problèmes à
l'AFNIC ou à la racine). Notez que cela peut arriver sans le
consentement du gérant de la zone. Si ce dernier publie un DPS
(DNSSEC Practice Statement) disant en gros
caractères « n'utilisez pas notre KSK comme clé de confiance, ne vous
fiez qu'au DS de la zone parente », alors, on peut tenir pour acquis
qu'il y aura peu de cas où la KSK sera installée en dur dans les
résolveurs. Autrement, le remplacement devient bien plus compliqué car
il faut prévenir tous les gens qui ont configuré cette clé de
confiance. Certains ne seront pas joignables ou ne réagiront pas et il
faudra donc prendre le risque de casser leur accès DNSSEC. Ainsi, pour la racine (qui ne peut pas compter sur
l'enregistrement DS de la zone parente) qui est forcément clé de
confiance, on peut penser qu'il n'y aura jamais de remplacement de la
KSK originelle, la 19036, sauf en cas de compromission : cela nécessiterait de changer
trop de résolveurs.
Notez qu'il existe un mécanisme pour mettre à jour les clés de
confiance, décrit dans le RFC 5011. Comme il
n'est jamais sûr que tous les « clients » le mettent en œuvre,
il est difficile de savoir si on peut compter dessus (dans Unbound,
trust-anchor-file: "/etc/unbound/root.key"
installe une clé de confiance statique et auto-trust-anchor-file: "/var/lib/unbound/root.key"
- notez le auto-
devant - installe
une clé qui pourra être mise à jour par les procédures du RFC 5011). Ces procédures n'ont jamais été testées
pour la racine.
Si on sépare KSK et ZSK, c'est normalement le bit SEP
(Secure Entry Point, cf. RFC 3757) qui les distingue (dans le cas le plus courant, la ZSK
aura un champ Flags
de 256 et la KSK de 257 à
cause du bit SEP). Ce bit n'est pas utilisé par les validateurs mais
certains outils s'en servent pour trouver la KSK (par exemple le
dnssec-signzone
de BIND). Si on n'a qu'une seule
clé, elle sert de KSK et doit donc avoir le bit SEP (autrement, le dnssec-signzone
de BIND vous dira dnssec-signzone: fatal: No self signed KSK's found
). Notez que
certains outils ne vous laisseront pas facilement n'utiliser qu'une
clé. Par exemple, avec dnssec-signzone
, vous aurez le message dnssec-signzone: fatal: No non-KSK
DNSKEY found; supply a ZSK or use '-z'.
et vous devrez
utiliser l'option indiquée pour signer quand même.
Un peu de cryptographie, maintenant. La durée de vie raisonnable d'une clé dépend de sa longueur. Le RFC suggère de décider d'une durée de vie, en tenant compte des contraintes opérationnelles, et d'en déduire la longueur. Une KSK qui a des enregistrements DS dans sa zone parente peut durer vingt ans sans problème, sauf si on désire tester régulièrement les procédures de remplacement ou sauf si la clé privée est compromise. Si on veut la remplacer régulièrement, une durée raisonnable proposée par le RFC est d'un an.
Quel algorithme cryptographique choisir ? Les quatre standardisés à l'heure actuelle (le RFC en cite trois mais ECDSA est apparu depuis), RSA, DSA et GOST sont bien connus et spécifiés et considérés comme fiables. En partie pour des raisons de performance, le RFC suggère la combinaison RSA/SHA-256 comme l'algorithme préféré (RFC 5702) et RSA/SHA-1 sinon.
Les algorithmes fondés sur les courbes elliptiques (GOST - RFC 5933 - et ECDSA - RFC 6605) ont des avantages importants sur RSA, notamment les clés et signatures plus petites. Mais très peu de résolveurs validant les gèrent et signer une zone uniquement avec ces algorithmes serait donc peu utile. D'autre part, même si le RFC ne le dit qu'en passant, les problèmes de brevet sont bien plus nombreux que pour RSA.
Si on a choisi RSA, il faut se décider pour une longueur de clé, suffisante pour résister à la cryptanalyse pendant la durée de vie de la clé (le RFC 3766 contient des calculs intéressants sur la solidité des clés). Comme le note le RFC, en dépit d'un FUD important, personne n'a encore annoncé la cryptanalyse d'une clé RSA de 1024 bits (le record publié est aux alentours de 700 bits). Et, le jour où cela arrivera, ce ne sera pas la fin de RSA mais la fin d'une seule clé. Bien sûr, la cryptanalyse progresse (et, le RFC oublie ce point, les meilleurs résultats ne sont pas forcément publiés) mais le RFC estime que les clés de 1024 bit sont encore sûres pour dix ans.
Néanmoins, utiliser des clés plus grandes est raisonnable si on veut une très longue durée de vie ou bien si on estime que le remplacement de la clé sera difficile (ce qui est certainement le cas de la clé de la racine). Pour ces cas, une clé de 2048 bits est donc utile. Attention, ce n'est pas gratuit, notamment la vérification est quatre fois plus lente et la signature huit fois moins rapide.
Certains férus de cryptographie peuvent tiquer à la pensée de n'utiliser que 1024 bits. Mais l'argument massue du RFC est celui de l'équilibre : on ne fait pas du DNSSEC pour le plaisir de la cryptographie. On le fait pour protéger quelque chose, par exemple un site Web de banque en ligne. Et ce genre de sites est en général protégé par TLS avec des clés qui ne sont souvent pas plus longues. Si un attaquant peut casser une clé de 1024 bits, il peut s'attaquer à TLS aussi bien qu'à DNSSEC. Avec des clés de 2048 bits, on blinde fortement la porte... alors que la fenêtre du rez-de-chaussée ne l'est pas toujours. Bref, si un brusque progrès de la cryptanalyse permet de casser ces clés de 1024 bits plus tôt que les dix ans indiqués, cela fera du bruit et cassera bien d'autres choses que DNSSEC.
Notons que, contrairement à son prédécesseur RFC 4641, notre RFC ne fait plus dépendre la solidité d'une clé du fait qu'elle soit largement utilisée ou pas. La cryptographie a évolué depuis le RFC 4641.
Où stocker ensuite ces clés ? Idéalement, sur une machine sécurisée et non connectée au réseau. On apporte les données sur cette machine, on signe et on repart avec les données signées pour les apporter au serveur de noms. C'est très sûr mais cela ne peut pas marcher si on utilise les mises à jour dynamiques du DNS (RFC 3007). Dans ce cas, il faut bien avoir la clé privée sur le serveur de noms (on parle de online key). C'est donc moins sûr et le RFC suggère, dans ce cas, que le serveur maître ne soit pas directement accessible de l'Internet (technique du hidden master, où le vrai maître n'est pas dans les enregistrements NS de la zone). Notez qu'une des motivations pour la séparation KSK/ZSK vient de là : avoir une KSK peu utilisée et dont la clé privée est stockéee de manière très sûre et une ZSK en ligne, plus vulnérable mais plus facile à changer.
Comme toujours en matière de sécurité, ces bons avis doivent être mis en rapport avec les contraintes opérationnelles et économiques. Ainsi, on peut sans doute améliorer la sécurité des clés en les gardant dans un HSM. Mais ces engins sont chers et pas pratiques pour les opérations quotidiennes.
Et la génération des clés ? C'est un aspect souvent oublié de la
sécurité cryptographique mais il est pourtant essentiel. La clé doit
être vraiment imprévisible par un attaquant et pour cela elle doit
être générée en suivant les recommandations du RFC 4086 et de NIST-SP-800-90A, « Recommendation for Random
Number Generation Using Deterministic Random Bit
Generators ». Par exemple, avec les outils de génération de
clés de BIND (dnssec-keygen
), il ne faut
pas utiliser l'option -r
/dev/urandom
en production, car elle n'utilise qu'un
générateur pseudo-aléatoire. (Les HSM disposent
tous d'un générateur correct.)
À noter que la version précédente de ce document, le RFC 4641 faisait une différence entre les zones DNS
selon leur place dans la hiérarchie (plus ou moins haute). Cette
distinction a disparu ici et les mêmes règles de sécurité s'appliquent
à toutes. L'une des raisons de ce choix est qu'on ne peut pas
facilement déterminer quelles zones sont importantes pour un attaquant
(grossebanque.com
est peut-être plus importante
que le TLD
.td
, même si ce dernier
est placé plus haut dans la hiérarchie). Cela n'empêche évidemment pas
chaque gérant de zone de devoir déterminer si sa zone est critique ou
pas, avant d'adapter les mesures de sécurité en conséquence.
La section 4 de notre RFC est ensuite consacrée au gros morceau de la gestion opérationnelle de DNSSEC : les remplacements de clés (key rollovers). Qu'on choisisse de faire des remplacements réguliers, pour qu'ils deviennent une simple routine, ou qu'on choisisse de n'en faire que lors d'évenements exceptionnels (comme une copie illégale de la clé), les remplacements sont une réalité et il faut s'y préparer. Par exemple, même si on décide de ne pas en faire systématiquement, il faut s'entrainer (et tester ses procédures) avec une zone de test. L'opération est délicate en raison de l'existence des caches DNS, qui vont garder la vieille information un certain temps. Personnellement, je déconseille fortement de faire les remplacements à la main : le risque d'erreur est bien trop grand. Il faut plutôt automatiser le processus, et avec un logiciel soigneusement débogué. L'expérience (mon article à la conférence SATIN en 2011) montre que les erreurs sont, elles aussi, une réalité.
Si on a décidé d'avoir deux clés, ZSK et KSK, leurs remplacements sont indépendants. Les ZSK sont les plus simples car elles peuvent être remplacées sans interaction avec la zone parente (pas d'échange d'enregistrements DS). Le RFC explique ensuite (en grand détail : je n'en donne qu'un court résumé ici) les deux méthodes connues pour remplacer une ZSK :
Dans le premier cas, on génére la nouvelle ZSK, on la publie (sans
qu'elle signe quoi que ce soit) puis, lorsque le nouvel ensemble
DNSKEY
est dans tous les caches, on utilise la
nouvelle ZSK pour signer. Une fois que les signatures faites avec
l'ancienne clé ont disparu des caches, on arrête de publier l'ancienne
clé. Le remplacement est terminé. Cette description très sommaire de
l'algorithme suffit déjà, je crois, à montrer qu'il vaut mieux ne pas
le faire à la main.
Quant à la double signature (plus rare, en pratique), elle consiste à signer tout de suite avec la nouvelle clé, tout en continuant à signer avec l'ancienne, pour les caches ayant seulement l'ancienne clé.
La section 4.1.1.3 résume les avantages et inconvénients de chaque méthode. La pré-publication nécessite davantage d'étapes (ce qui est grave si on la fait à la main, et moins si on a tout automatisé). La double signature est plus coûteuse puisque la zone sera, pendant la période transitoire, bien plus grosse (les signatures forment l'essentiel de la taille d'une zone signée). Dans les deux cas, comme il n'y a pas besoin d'interagir avec la zone parente, le processus peut être entièrement automatisé et c'est bien ce que fait, par exemple, OpenDNSSEC.
Et pour remplacer une KSK ? La double signature devient alors plus
intéressante, puisque la KSK ne signe pas toute la zone, seulement
l'ensemble d'enregistrements DNSKEY
. Les
problèmes de taille ne se posent donc pas. Par rapport au remplacement
d'une ZSK, la grosse différence est l'interaction avec la zone
parente. Il n'existe pas d'API standard pour le
faire. Les bureaux d'enregistrement (BE)
utilisent en général EPP - RFC 5910 - avec le registre mais
le gestionnaire de la zone, avec son BE, a typiquement une interface
Web, ou bien une API non-standard, par exemple à base de
REST (cf. aussi la section 4.3.2). L'opération nécessite donc souvent une
intervention manuelle comme décrit dans mon
article sur un exemple avec OpenDNSSEC.
Et si on a une clé unique ? Le cas est proche de celui d'un remplacement de KSK et le RFC recommande la double-signature, car c'est la solution la plus simple (et, si on n'utilise qu'une clé, c'est qu'on aime la simplicité).
La section 4.2 couvre le cas des préparatifs pour un remplacement d'urgence. On arrive le lundi matin au bureau, le coffre-fort est grand ouvert et la clé USB qui stockait la clé privée a disparu (une variante moins gênante est celle où la clé privée est détruite, mais pas copiée, par exemple en raison d'un incendie). Il faut alors remplacer cette clé et c'est bien plus facile si on a planifié avant. Notez qu'il y a toujours un compromis ici : si on supprime immédiatement l'ancienne clé, désormais compromise, une partie des résolveurs (ceux qui ont les anciennes signatures, mais pas l'ancienne clé) dans leurs caches considéreront la zone comme invalide. Mais, si on continue à diffuser l'ancienne clé, on augmente la durée pendant laquelle le voleur pourra injecter des informations mensongères. Il existe une méthode intermédiaire, faire retirer l'enregistrement DS par la zone parente. Selon les TTL en jeu, cela peut permettre de diminuer la durée du problème. Comme on le voit, il vaut mieux faire les calculs, l'analyse et le choix de la meilleure méthode avant le fatal lundi matin...
Une solution possible est d'utiliser des Standby keys, qui seront publiées (et donc dans tous les caches) mais pas utilisées pour signer, et dont la partie privée sera gardée à un endroit différent.
Le problème est évidemment plus grave si la clé en question avait
été configurée par certains comme clé de confiance dans leurs
résolveurs. Il faut alors prévenir tout le monde de la compromission,
par un message (authentifié) envoyé à plusieurs endroits, pour
maximiser les chances de toucher tout le monde. Si la clé de la racine
(ou d'un grand TLD comme .net
)
était compromise, on verrait sans doute l'annonce sur dns-operations, NANOG,
Twitter, etc. Outre l'authentification de
l'annonce, la nouvelle clé devra elle aussi être authentifiée, par un
moyen non compromis : ne mettez pas la partie privée de la KSK dans le
même coffre-fort que la partie privée de votre clé PGP !
Autre cas amusant pour les gérants d'une zone DNS, le changement d'opérateurs. Par exemple, le titulaire d'une zone décide de passer d'un hébergeur DNS à un autre (notez que l'hébergeur est souvent le BE mais ce n'est pas obligatoire). Si les deux hébergeurs (en pratique, c'est évidemment le perdant qui fait des histoires) coopèrent, le problème est relativement simple. Le RFC suppose que l'ancien hébergeur ne va pas transmettre la clé privée (si elle est dans un HSM, il ne peut tout simplement pas). Dans ce cas, l'ancien hébergeur doit mettre dans la zone la clé publique du nouveau, et les signatures calculées par le nouveau avec ses clés. Le nouvel opérateur publie la même zone et, une fois le changement terminé (une fois que les clés du nouvel hébergeur sont dans tous les caches), le nouvel hébergeur peut retirer les clés et les signatures de l'ancien. Ce n'est pas très pratique (il faut échanger clés publiques et signatures). Personnellement, je trouve cet algorithme tout à fait irréaliste. Dans le DNS d'aujourd'hui, des obligations bien plus modérées (en cas de changement d'hébergeur, continuer à servir la zone jusqu'à ce que les TTL sur les enregistrements NS expirent) ne sont jamais respectées par les hébergeurs perdants, même lorsqu'elles figurent dans les obligations contractuelles. Le RFC note à juste titre que c'est un problème économique et qu'il n'a pas de solution technique.
Il reste donc le cas qui sera sans doute le plus probable, celui où l'ancien hébergeur de la zone DNS ne coopérera pas. (Techniquement, il peut même saboter activement le transfert, en publiant un enregistrement DNSKEY avec un très long TTL, pour « empoisonner » les caches.) La seule solution est alors de passer par une phase où la zone ne sera pas sécurisée par DNSSEC : le parent retire l'enregistrement DS, on attend que l'ancien DS ait disparu des caches, puis on en remet un, pointant vers une clé du nouvel hébergeur.
Quelques mesures techniques dans les résolveurs validants peuvent aider :
Le gérant de la zone peut aussi aider en n'ayant pas des TTL trop longs.
Gérer proprement du DNSSEC impose une grande rigueur sur les questions temporelles. Avant DNSSEC, le temps dans le DNS était toujours relatif. Par exemple, le champ Expire de l'enregistrement SOA était relatif au moment de la dernière synchronisation avec le serveur maître. Même chose pour les TTL. Mais, avec DNSSEC, le temps devient absolu. Les dates de début et de fin de validité dans un enregistrement RRSIG, par exemple, sont absolues. Elles dépendent donc d'une horloge à l'heure.
Quelques conseils, donc, sur le temps :
Bon, mais alors, quelle durée choisir pour la validité des signatures (les outils de signature de BIND mettent un mois, par défaut). C'est un compromis : une durée trop longue et on est vulnérable aux attaques par rejeu. Une durée trop courte et on risque de n'avoir pas assez de temps pour réagir en cas de problème. Une erreur dans la configuration du pare-feu, les serveurs esclaves qui ne peuvent plus se synchroniser, les signatures sur ces serveurs esclaves qui expirent et crac, la zone est invalide. Cela arrive vite. Mon opinion personnelle est qu'aujourd'hui, les procédures ne sont pas assez testées et l'expérience DNSSEC est insuffisante. Il faut donc jouer la sécurité et avoir des durées de validité longues (au moins deux semaines). Dans le futur, au fur et à mesure de la montée en compétence et de l'amélioration des logiciels, on pourra mettre des durées de validité des signatures plus courtes, fermant ainsi la porte aux attaques par rejeu.
Voilà, nous avons couvert le gros de ce RFC. La section 5, qui suit, se consacre à un problème rigolo, celui des enregistrements indiquant l'enregistrement suivant, les enregistrements next. L'un des choix importants de conception de DNSSEC était de permettre que les signatures se fassent entièrement hors-ligne. On ne pouvait donc pas prévoir toutes les questions posées au serveur et avoir une signature pour toutes les réponses « ce domaine n'existe pas ». Il y a donc des enregistrements qui disent « il n'y a pas de domaine ici », enregistrements qui sont signés pour qu'un résolveur validant puisse authentifier une réponse négative. Ces enregistrements next sont le NSEC et le NSEC3. Le premier est en clair (il indique le nom de l'enregistrement suivant celui qui n'existe pas), le second est brouillé (il indique le condensat suivant le condensat du nom qui n'existe pas). Pour l'administrateur, les NSEC sont plus pratiques, notamment au débogage. Mais ils permettent la récupération complète de la zone, en marchant de NSEC en NSEC.
Le choix entre NSEC et NSEC3 dépend du type de la zone. Si on a une
petite zone au contenu prévisible (juste l'apex, un
mail
et un
www
, ce qui est le cas de très nombreuses zones),
aucune raison d'utiliser NSEC3. Même chose si la zone est très
structurée et donc très prévisible (ip6.arpa
,
ENUM...). Même chose si la zone est publique,
ce qui est le cas par exemple de la racine (il existe une autre raison
d'utiliser NSEC3, l'opt-out, qui intéresse surtout
les grandes zones de délégation comme certains TLD).
Autrement, si on n'est dans aucun de ces cas, si on est une assez
grande zone au contenu imprévisible et qui n'est pas publique, il est
cohérent d'utiliser NSEC3 (RFC 5155).
NSEC3 a certains paramètres à configurer (et qui sont publiés dans
l'enregistrement NSEC3PARAM). Notamment, on peut définir le nombre
d'itérations de hachage. Cette possibilité
protège des attaques par dictionnaires pré-calculés mais elle est
coûteuse et elle mène à l'exécution de code à chaque requête pour un
nom inexistant. Le RFC suggère un nombre de 100 itérations, ce qui est
colossal par rapport à ce que font la plupart des zones NSEC3
aujourd'hui (5 par défaut avec OpenDNSSEC, mais beaucoup l'abaissent, on trouve 1 pour
.fr
et
.com
, et même 0 pour
.org
...) NSEC3 ajoute un
sel au début de l'itération et notre RFC
suggère de changer ce sel en même temps que la ZSK.
Les changements depuis le RFC 4641 sont résumés dans l'annexe E. D'abord, les erreurs connues ont été corrigées. Ensuite, la fonction de hachage SHA-256 a été ajoutée aux recommandations. La partie sur le changement d'hébergeur DNS a été ajoutée. Le modèle avec séparation KSK/ZSK ne bénéficie plus d'un privilège particulier puisque le modèle avec une seule clé est également décrit.
(Les juristes noteront que VeriSign a un brevet sur certaines des techniques présentées dans ce RFC.)
Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : R. Sparks (Tekelec)
Pour information
Première rédaction de cet article le 31 octobre 2012
Dernière mise à jour le 31 janvier 2014
Ce RFC est le cahier des charges de l'outil d'accès aux archives des
innombrables listes de diffusion de
l'IETF. Le gros du travail de cette
organisation repose sur ces listes de diffusion, dont la plupart sont
publiques, archivées et accessibles via le
Web. Cette masse d'information est un outil
formidable pour comprendre les décisions de l'IETF et les choix
techniques effectués. Mais son volume rend l'accès à
l'information souvent difficile. L'IETF se vante de sa transparence
(tout le travail est fait en public) mais avoir toutes les discussions
accessibles ne suffit pas, si l'information est trop riche pour être
analysée. D'où l'idée de développer une
ensemble d'outils permettant d'accéder plus facilement à ce qu'on
cherche. C'est désormais accessible en https://mailarchive.ietf.org/
.
Avant, la recherche était particulièrement difficile si une discussion s'étendait sur une longue période et surtout si elle était répartie sur plusieurs listes. Imaginons un auteur d'un RFC, un président de groupe de travail, ou un simple participant, qui veut retrouver toutes les discussions qui ont concerné un Internet-draft donné. Il va trouver des messages dans la liste du groupe de travail mais aussi dans celles d'une ou plusieurs directions thématiques, et peut-être aussi dans la liste générale de l'IETF. Certains ont chez eux des copies de toutes ces listes (copies parfois incomplètes) pour utiliser des outils locaux. (Au fait, personnellement, je me sers surtout de grepmail et je cherche encore un outil qui indexerait les données.)
En l'absence de copie locale, notre participant IETF courageux va compter sur la force brute, ou bien va essayer un moteur de recherche généraliste (mais il est ennuyeux pour l'IETF de devoir compter sur un outil externe pour son propre travail).
Ce n'est pas qu'il n'existait aucun outil à l'IETF. Il y a des solutions proposées sur le site de l'IETF (l'option Email Archives Quick Search). Mais elles ne couvrent pas tous les besoins, loin de là.
Quels sont ces besoins ? La section 2 en donne la liste. D'abord,
il faut une interface Web. Elle doit permettre
de naviguer dans un fil de discussion donné, ou
suivant la date. (Les outils d'archivage classique comme
MHonArc permettent déjà tous cela.) Les fils
doivent pouvoir être construits en suivant les en-têtes prévus à cet
effet (References:
et
In-Reply-To:
) mais aussi en se fiant au sujet
pour le cas où les dits en-têtes auraient été massacrés en route, ce
qui arrive.
Surtout, il faut une fonction de recherche. Elle doit fonctionner sur une liste, ou un ensemble de listes, ou toutes les listes. Elle doit permettre d'utiliser ces critères :
Message-ID:
lorsqu'on
veut donner une référence stable d'un message (« ton idée a déjà été
proposée dans
<5082D93B.6000308@cnam.fr>
»). Le but est
de pouvoir faire circuler une référence comme http://datatracker.ietf.org/mlarchive/msg?id=5082D93B.6000308@cnam.fr
.
Et de les combiner avec les opérateurs booléens
classiques (AND
, OR
et
NOT
).
Il n'y a pas que la recherche dans la vie, on voudrait aussi
évidemment avoir des URI stables pour chaque
message (stables et beaux). Et cet URL
devrait être mis dans le champ Archived-At:
du
message avant sa distribution (cf. RFC 5064).
À propos d'URI, comme indiqué dans l'exemple de recherche via un
Message-ID:
montré plus haut, notre RFC demande
que les recherches soient représentables par un URI, qui puisse être
partagé (et qui soit donc stable). Le RFC ne donne pas d'exemple mais
cela aurait pu être quelque chose comme
http://datatracker.ietf.org/mlarchive/search?subject=foobar&startdate=2002-05-01&enddate=2004-06-01&author=smith
(dans la version publiée, c'est en fait quelque chose comme https://mailarchive.ietf.org/arch/search/?qdr=a&q=text%3A%28eszett%29&as=1&f_list=precis%2Cxmpp
). Naturellement,
« stabilité » fait référence à l'URI, pas au résultat, qui peut varier
dans le temps (par exemple si des nouveaux messages arrivent).
La plupart des archives à l'IETF sont publiques et doivent être
accessibles anonymement mais quelques unes
nécessitent une autorisation. Dans ce cas, le cahier des charges
demande que le système d'authentification
utilisé soit celui de datatracker.ietf.org
.
Difficulté supplémentaire, toutes les listes IETF ne sont pas gérées au même endroit et par le même logiciel. Les listes hébergées à l'IETF le sont avec mailman mais il existe aussi des listes hébergées ailleurs et notre cahier des charges demandent qu'elles puissent être intégrées dans ce système de recherche (par exemple en abonnant l'adresse du programme d'archivage à la liste).
Il y a aussi des cas où des archives de listes de diffusion deviennent accessibles alors qu'elles ne l'étaient pas avant et doivent être incorporées dans le corpus géré par le nouveau système. Le RFC demande qu'au moins le format d'entrée mbox (RFC 4155) soit accepté. Et qu'il serait souhaitable d'accepter aussi le maildir.
En sens inverse, le système doit permettre d'exporter les messages (un système ouvert ne l'est pas si on ne peut pas en sortir l'information pour la garder et l'étudier chez soi ; la fonction d'exportation n'a pas qu'un intérêt technique, elle est aussi un moyen de garantir la pérénnité de l'information publique). On doit pouvoir exporter une liste entière, une liste pour un intervalle de temps donné et, dans le meilleur des cas, le résultat d'une recherche (une vue, pour employer le langage des SGBD). Là encore, l'exportation en mbox est impérative et celle en maildir souhaitée.
Voilà, c'est tout, l'appel d'offres formel de
l'IAOC était en ligne. Plus rigolo pour le programmeur de cet ambitieux projet : la
section 3 lui rappelle qu'il devrait se préparer à l'arrivée du courrier électronique
internationalisé... Le produit final a été livré le 29 janvier 2014 et est disponible en https://mailarchive.ietf.org/
.
Date de publication du RFC : Janvier 2012
Auteur(s) du RFC : H. Schulzrinne (Columbia University), H. Tschofenig (Nokia Siemens Networks), J. Cuellar (Siemens), J. Polk (Cisco), J. Morris, M. Thomson (Microsoft)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF geopriv
Première rédaction de cet article le 11 janvier 2013
Toute information sur la position physique d'une personne ou d'une machine (la géolocalisation) est évidemment très sensible et il est normal que les considérations de protection de la vie privée jouent un grand rôle dès qu'on parle de géolocalisation. Le RFC 6280 fixait un cadre général pour la protection de la vie privée face à cette géolocalisation. Ce nouveau RFC étend les techniques des RFC 4119 et RFC 4745 pour permettre d'exprimer les autorisations concernant la géolocalisation, en fonction de la position : ce qu'on peut faire de l'information, à qui on peut la transmettre, etc.
Le principe est que le document suivant le format de ce RFC va poser des conditions (« si je suis en tel lieu », cf. section 4) et que, en fonction de ces conditions, on aura des actions (non spécifiées ici) et surtout des transformations (section 6), qui vont changer les valeurs spécifiées par le langage du RFC 4119 : autoriser ou interdire la retransmission de l'information, modifier la durée d'expiration, indiquer un texte décrivant une politique, et enfin délibérement faire perdre de la précision, afin de protéger sa vie privée. Ainsi, pour les localisations civiles (exprimées par rapport aux constructions humaines et pas par rapport à la Terre), on peut utiliser le vocabulaire du RFC 5139 pour spécifier que la localisation doit être limitée en précision à une rue, une ville, voire un pays.
Tirés de la section 7, voici quelques exemples (comme vous le voyez, la syntaxe est du XML, le schéma figure en sections 8 et 9) :
<?xml version="1.0" encoding="UTF-8"?> <ruleset xmlns="urn:ietf:params:xml:ns:common-policy" xmlns:gp="urn:ietf:params:xml:ns:geolocation-policy"> <rule id="AA56i09"> <conditions> <gp:location-condition> <gp:location profile="civic-condition" xml:lang="en" label="Siemens Neuperlach site 'Legoland'" xmlns="urn:ietf:params:xml:ns:pidf:geopriv10:civicAddr"> <country>DE</country> <A1>Bavaria</A1> <A3>Munich</A3> <A4>Perlach</A4> <A6>Otto-Hahn-Ring</A6> <HNO>6</HNO> </gp:location> </gp:location-condition> </conditions> <actions/> <transformations/> </rule> </ruleset>
Qu'est-ce que cela dit ? Que si la localisation civile actuelle est
« 6, Otto-Hahn-Ring, dans le quartier de
Perlach à Munich »,
alors, on ne fait rien de particulier (les éléments
<actions>
et
<transformations>
sont vides).
Les conditions auraient pu être exprimées en
géodésique et pas en civil, par exemple :
<gs:Circle srsName="urn:ogc:def:crs:EPSG::4326"> <gml:pos>-33.8570029378 151.2150070761</gml:pos> <gs:radius uom="urn:ogc:def:uom:EPSG::9001">1500 </gs:radius> </gs:Circle>
(C'est l'opéra de Sydney.)
Maintenant, avec une transformation qui interdit la retransmission, change la durée de vie de l'information, et limite la précision géodésique à 500 mètres :
<transformations> <gp:set-retransmission-allowed>false </gp:set-retransmission-allowed> <gp:set-retention-expiry>86400</gp:set-retention-expiry> <gp:provide-location profile="geodetic-transformation"> <lp:provide-geo radius="500"/> </gp:provide-location> </transformations>
Attention, si la protection de votre vie privée est cruciale, lisez bien la section 13, qui expose les limites de la protection qu'offrent ces techniques. Par exemple, imaginez que, lorsque vous êtes chez vous, vous réduisez la précision à 200 mètres, pour empêcher qu'on localise votre maison. Imaginons maintenant que le logiciel vous place donc au hasard quelque part dans un cercle de rayon 200 m centré sur votre maison. Un attaquant malin pourrait relever votre position pendant quelques jours, faire l'intersection de ces informations, et trouver la maison avec une bonne précision... Une bonne mise en œuvre de ce RFC devrait donc servir toujours la même information à un demandeur donné, mais, si vous étiez programmeur, vous auriez pensé à ce piège ? Aléatoire n'est dons pas synonyme de sécurité, bien au contraire.
Même sans cela, des informations externes peuvent guider celui qui cherche à vous pister. Si la précision est de mille mètres pendant votre déplacement de Paris à Lyon, l'observateur pourra remarquer que vous utilisez le TGV et réduire ainsi drastiquement l'imprécision.
Pire, le danger peut venir des règles de protection de la vie privée elle-même. Si la configuration par défaut est d'une précision de 100 m, et que quelqu'un indique une dégradation à 1000 m en certains endroits, il indique que ces endroits sont particulièrement sensibles et donc intéressants pour une personne mal intentionnée envers lui.
Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : L. Eggert (NetApp), G. Camarillo (Ericsson)
Pour information
Première rédaction de cet article le 18 octobre 2012
Autrefois, du temps des débuts de l'IETF, les seules réunions ayant un statut officiel étaient les réunions formelles des groupes de travail. Avec le temps, elles sont devenues tellement formelles (et n'ayant plus guère de rapport avec un « groupe de travail ») qu'un type de réunions plus légères est apparu petit à petit, les BOF (Birds Of a Feather). Les BOF étaient au début simples et faciles à organiser, comme l'étaient les groupes de travail des débuts. Mais elles se sont ossifiées petit à petit, devenant aussi formelles qu'un groupe de travail, et ayant même leur propre RFC, le RFC 5434. Continuant cette évolution logique, des participants à l'IETF ont créé un mécanisme léger alternatif aux BOF, les Bar BOF, qui étaient comme leur nom l'indique, des réunions faites au bistrot. Maintenant, on parle de fixer des règles pour les bar BOF...
Les bar BOF sont fréquentes pendant les réunions physiques de l'IETF. Elles se réunissent souvent dans un bar, d'où elles tirent leur nom, et permettent de discuter de manière complètement informelle, de nouvelles idées qui donneront peut-être naissance plus tard à un groupe de travail, voire à un ou plusieurs RFC. Elles ne sont pas mentionnées dans l'agenda officiel et n'ont aucun statut particulier. N'importe qui peut organiser une bar BOF comme il veut (alors que l'organisation d'une BOF est désormais toute une affaire, décrite dans le RFC 5434). Elles ont déjà été mentionnées dans un RFC, le fameux Tao (RFC 6722).
La malédiction se poursuivant, certaines bar BOF sont devenues tellement formalistes qu'on peut se demander si certains ne réclameront pas bientôt statuts et règles pour ces réunions. Ce RFC 6771 essaie de bloquer cette tendance, en plaidant pour que les bar BOF restent complètement an-archiques.
Car ce n'est pas le cas : on voit de plus en plus de bar BOF tenues dans les salles de réunion (et plus au café), avec les chaises organisées comme dans une salle de classe, des orateurs situés sur l'estrade, un tour de parole, des présentations faites avec PowerPoint et, surtout, plus de boissons du tout...
Ce RFC signale que cette évolution peut être due en partie au fait que le terme bar BOF est trop proche de BOF et que les débutants mélangent les BOF (dotées d'un statut, celui du RFC 5434) et les bar BOF. C'est au point que certains participants, voulant aboutir à la création d'un groupe de travail, se sentent obligés de faire une bar BOF uniquement parce qu'ils croient qu'une règle de l'IETF impose cette étape ! Les auteurs du RFC recommandent donc de parler plutôt de « réunion parallèle » (side meeting).
Et, pour que ces réunions parallèles se passent bien, notre RFC 6771 propose quelques conseils. D'abord (section 2), comment gérer les invitations. Une réunion parallèle doit être petite (« uniquement les gens nécessaires et pas plus »). Il ne s'agit pas, comme c'est souvent le cas pour les BOF, de sonner le clairon pour ramener le maximum de gens, espérant ainsi montrer que le sujet est considéré comme important par la communauté. On ne devrait donc pas faire d'annonce publique d'une réunion parallèle (par exemple, sur une liste de diffusion). Si on le fait, on risque de manquer de chaises dans le bar, et de ne pas pouvoir s'entendre d'un bout de la réunion à l'autre, menant à des réunions excessivement formelles, avec tour de parole. (Plusieurs bar BOF ont déjà souffert de ce syndrôme « apéro Facebook ».)
Bref, pas de touristes à une réunion parallèle, uniquement « a few good people », des gens qui vont activement participer au travail (l'IETF ne décide normalement pas sur la base du nombre de participants mais sur le nombre de gens qui vont effectivement bosser). L'implication plus large de la communauté viendra après. La réunion parallèle doit avant tout rester du remue-méninges, chose qui ne se fait pas dans des grands groupes. Par définition, les idées exprimées lors d'une réunion parallèle sont incomplètes et imparfaites et il faut pouvoir les discuter franchement.
De même, on n'est pas obligé d'inviter un membre de l'IESG ou de l'IAB en croyant que cela fera plus sérieux et plus crédible.
Après le Qui, la section 3 couvre la question du Où. Comme leur nom l'indique, les bar BOF se tiennent traditionnellement dans les bars. Mais la tendance récente est de la faire souvent dans les salles d'une réunion IETF, en partie parce que cela fait plus « sérieux ». Notre RFC, qui n'hésite pas à descendre dans les détails concrets, note que les bars sont souvent bruyants, ce qui pose un problème notamment pour les non-anglophones (le bruit gène beaucoup plus lorsque la conversation est dans une langue étrangère). Pour garder la convivialité, en supprimant le bruit, le RFC recommande de choisir un restaurant calme, voire de prendre une arrière-salle du bar. Les salles de la réunion IETF sont en général trop « salle de classe », un environnement qui ne convient pas au remue-méninges entre pairs. Cet environnement est bon pour les présentations, pas pour les discussion.
Toujours concret, le RFC note enfin que se réunir dans un bar ou un restaurant permet souvent de... manger. En effet, certaines réunions IETF se tiennent dans des endroits où le ravitaillement est difficile et la réunion d'Anaheim (IETF 77) a ainsi laissé un souvenir particulièrement cuisant. Sortir est donc souhaitable.
Après le Qui et le Où, le Comment. La section 4 s'insurge contre la tendance de plus en plus marquée à singer les réunions des groupes de travail. On voit ainsi des réunions parallèles ayant un agenda formel, des présentations avec supports, des organisateurs qui se présentent comme bar BOF chair. Les auteurs de notre RFC craignent que ce cirque provoque des réactions pavloviennes chez les participants, les faisant se comporter comme si la réunion parallèle était déjà devenue un vrai groupe de travail. Ces réunions qui caricaturent les réunions officielles ne sont pas très efficaces, et elles entraînent des confusions chez certains participants qui croient qu'il s'agit de réunions officielles, simplement parce qu'elles en ont l'apparence.
Enfin, le Quand, en section 5. La principale recommendation est que les réunions parallèles, comme elles visent à commencer le travail pour résoudre un problème précis, n'ont pas forcément vocation à être toujours parallèles à une réunion IETF, elles peuvent parfaitement se tenir en parallèle d'une réunion RIPE, NANOG ou équivalent.
Et une anecdote amusante : comme obligatoire, ce RFC a une section « Sécurité ». Elle contient l'avertissement qu'on a constaté un oubli fréquent des portables dans les bars, après une réunion parallèle trop arrosée...
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : G. Bertrand (France Telecom -
Orange), E. Stephan (France Telecom -
Orange), T. Burbridge, P. Eardley
(BT), K. Ma (Azuki Systems), G. Watson (Alcatel-Lucent - Velocix)
Pour information
Réalisé dans le cadre du groupe de travail IETF cdni
Première rédaction de cet article le 20 novembre 2012
Le groupe de travail CDNI de l'IETF travaille à normaliser les interfaces entre CDN pour permettre à deux de ces systèmes de distribution de contenu de coopérer pour servir un client. Ce second RFC du groupe (le premier, le RFC 6707, décrivait en détail le problème à résoudre et l'état de l'art) rassemble trois études de cas, illustrant ainsi par ces scénarios l'utilité du travail du groupe.
Un ancien effort de normalisation des CDN à l'IETF avait eu lieu, produisant des documents comme le RFC 3570, qui décrivait déjà des scénarios d'usage. Ce nouveau RFC remplace ce RFC 3570 ; la terminologie est notamment très différente et reprend celle du RFC 6707. Conjointement avec ce RFC 6707, il va servir de base au document « cahier des charges » du groupe de travail CDNI, qui sera publié en RFC 7337.
Interconnecter des CDN offre en théorie de nombreux avantages : améliorer le vécu de l'utilisateur (temps de réponse plus courts, voir le RFC 6390) et diminuer les coûts pour l'opérateur (on n'utilise que le réseau interne au lieu des lignes extérieures) notamment. Mais, actuellement, chaque CDN fonctionne de manière indépendante des autres, ce qui fait qu'il n'est pas toujours possible de récolter ces bénéfices. Voyons les trois études de cas.
D'abord (section 2), le cas d'un CDN qui a une couverture géographique insuffisante. Un opérateur de CDN est présent dans une région donnée (mettons l'Europe) mais ne peut pas fournir de service aux lecteurs en Asie ou en Amérique. Et imaginons un autre opérateur de CDN en Amérique qui n'a pas de présence en Europe. Les interconnecter permettrait au nouvel ensemble de servir les deux continents, sans que chaque opérateur n'ait eu à supporter d'énormes investissements.
Un autre cas proche est celui où un FAI a construit un CDN en interne pour distribuer du contenu dont il a les droits. Un autre fournisseur de contenu a déjà un contrat avec un autre opérateur de CDN. Dans ce cas, le FAI va recevoir un gros trafic de la part de ce CDN, qui va saturer ses liaisons externes, alors que ce contenu pourrait être distribué plus efficacement par le CDN du FAI. Pour le FAI en question, il serait utile que cet autre CDN puisse s'interconnecter avec le CDN du FAI (section 2.3), afin d'améliorer les performances et de décongestionner les liens d'interconnexion.
Deuxième étude de cas (section 3), celle où le CDN a une couverture géographique jugée suffisante mais des capacités trop petites pour la charge. Cela peut être à cause d'une énorme augmentation temporaire de la demande (effet Slashdot, dit aussi flash crowd) par exemple suite à un événement particulier. Cet événement peut être prévu - match de football à diffuser - ou imprévu. (Le RFC cite l'exemple de la vidéodiffusion du mariage d'une célébrité ; il est triste de penser que des technologies si sophistiquées servent à de telles conneries.) Le CDN menace alors de s'écrouler sous la charge. Appelons un autre CDN à son secours ! L'idée est que le gestionnaire du CDN trop petit va payer un autre CDN, s'interconnecter à lui, et que les deux CDN feront face ensemble à la charge. (Une autre solution serait d'agrandir le CDN, mais, avec l'interconnexion des CDN, on peut prendre des marges de dimensionnement moins importantes, sans pour autant perdre sa capacité de faire face à d'éventuels pics de trafic.)
Une variante de ce cas est la résilience en cas de problème, par exemple une attaque par déni de service ou une panne massive d'une partie d'un CDN (section 3.2). S'interconnecter à un autre CDN permet alors de continuer à fonctionner. Actuellement, chaque CDN doit se débrouiller seul en cas de panne.
Dernière étude de cas (section 4), celui où le CDN n'a, ni problème de couverture géographique, ni problème de capacité, mais un problème de fonctions : le client a des exigences techniques particulières que le CDN ne sait pas remplir. Par exemple, un CDN sert du contenu en HTTP mais un client réclame qu'une partie du contenu soit servie en HTTPS (qui, entre autres, nécessite des processeurs plus rapides, pour les calculs cryptographiques) qu'il ne sait pas faire. S'allier avec un CDN qui, lui, sait faire du HTTPS, permettrait de rendre le client heureux (en lui évitant de signer deux contrats). Autre exemple donné par le RFC (mais peu convaincant depuis l'échec ridicule de WAP), celui d'un client qui demanderait tout à coup un protocole de distribution qui soit spécifique aux engins mobiles, alors que le CDN habituel de ce client n'a pas mis en œuvre ce protocole.
Et, bien sûr, exemple évident, un CDN qui serait toujours, en 2012, uniquement en IPv4 et à qui des clients réclameraient qu'il utilise enfin un protocole de ce siècle, IPv6. Sous-traiter la distribution en IPv6, par le biais des protocoles d'interconnexion que concevra le groupe de travail CDNI, permettrait au CDN IPv4 d'attendre encore un peu.
Plus subtil, le cas où le CDN peut distribuer le contenu avec le protocole demandé, mais pas avec les exigences quantitatives du client (par exemple portant sur la latence). S'associer avec un autre CDN, meilleur de ce point de vue, peut être utile.
Dans ces trois cas, si on pouvait facilement interconnecter des CDN, tout irait bien et les oiseaux chanteraient plus mélodieusement. Mais, à l'heure actuelle, une telle interconnexion se heurte à l'absence totale de normes techniques (cf. RFC 6707). Chaque fois que deux CDN s'interconnectent, ils doivent développer du code spécifique à ce couple. C'est justement le travail du groupe CDNI que de spécifier ces normes techniques, en attendant leur futur développement et déploiement. Une fois que cela sera fait, l'interconnexion de deux CDN ne sera plus « que » une affaire de business... (Comme l'accord Orange/Akamai annoncé le même jour que le RFC...)
Ah, un petit point à ne pas oublier (section 5), l'application de politiques de distribution restrictives. C'est une demande courante des clients (distribuer une vidéo en Amérique du Nord seulement, par exemple, et donc barrer l'accès aux visiteurs d'autres régions, ou bien ne permettre l'accès gratuit que pendant 24 h). Cela ajoute une contrainte assez ennuyeuse à l'interconnexion de CDN : il faut aussi transmettre ces restrictions. L'annexe A.1 traite en détail ce problème.
Dernier problème lors de l'interconnexion, la marque (branding), vue en annexe A.3. Un CDN qui fait appel à un autre pour traiter une partie de son travail peut souhaiter que sa marque apparaisse quand même (par exemple, URL avec son nom de domaine). La solution d'interconnexion doit donc penser à fournir une solution à ce problème.
Merci à Gilles Bertrand pour sa relecture.
Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : R. Raszuk (NTT MCL), J. Heitz (Ericsson), A. Lo (Arista), L. Zhang (UCLA), X. Xu (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 25 octobre 2012
Un des gros problèmes des routeurs de la DFZ, dans l'Internet d'aujourd'hui, est l'augmentation du nombre de routes. Il y a, en octobre 2012, environ 450 000 routes dans cette DFZ et ce nombre croît sans cesse. Ces routes doivent être mises en mémoire et la mémoire d'un routeur du cœur de l'Internet est quelque chose de compliqué, qu'on ne veut pas gaspiller. Des tas d'approches ont été proposées pour traiter ce problème. Ce RFC propose un moyen astucieux de limiter les dégâts, en permettant au routeur d'agréger les routes pour les préfixes IP proches. Ce RFC est donc très court car l'idée est simple.
Attention au terme de « table de routage », trop vague. Un routeur met des routes dans au moins deux tables, la
RIB (Routing Information
Base, la base constituée par les protocoles de routage, BGP
et ses copains OSPF et IS-IS) et la FIB (Forwarding
Information Base, typiquement placée dans la
CAM car elle doit être très rapide,
elle est consultée à chaque paquet). Actuellement, le routeur
typique met toutes les entrées de sa RIB dans sa FIB. C'est sous-optimal car la RIB a beaucoup plus
d'entrées que le routeur n'a de voisins réseau (des centaines de milliers de
routes contre parfois seulement dix ou vingt routeurs voisins). Comme la taille
de la FIB est souvent un facteur limitant (ce n'est pas le seul, donc
ce RFC ne résout pas tous les problèmes de taille), il serait intéressant d'agréger
violemment, en découplant RIB et FIB. Par exemple, si la RIB contient
une entrée pour 2001:db8:16::/48
et une autre pour 2001:db8:17::/48
,
et que les deux vont vers le même voisin (ont le même next hop), mettre les deux entrées dans
la FIB est du gaspillage, une seule entrée, pour 2001:db8:16::/47
,
suffirait. (Et le calcul pour déterminer ce qu'on peut agréger est
simple.)
Au passage, on peut agréger dans la FIB mais moins dans la RIB car cette dernière doit être transmise aux routeurs pairs avec qui on échange des routes. Si on agrège, c'est une « compression avec perte » et les pairs ne recevront donc pas toute l'information. Néanmoins, ce RFC permet également de ne pas installer de routes dans la RIB. Celle-ci est typiquement dans une mémoire moins coûteuse mais on souhaite diminuer, non seulement la consommation mémoire mais également le rythme de changement. Moins on aura de préfixes, moins on aura de changements à gérer.
L'avantage de l'approche naïve ci-dessus est qu'elle est déployable
unilatéralement : chaque routeur peut le faire dès aujourd'hui sans
rien demander à personne. Son
principal inconvénient est que la RIB n'est pas statique : si BGP
change le next hop (le routeur suivant pour
acheminer le paquet) de 2001:db8:17::/48
, il faut désagréger en
vitesse et mettre deux entrées dans la FIB.
L'approche de ce RFC est donc un peu différente : certains routeurs de l'AS vont annoncer des préfixes virtuels (VA prefix pour Virtual Aggregation prefix). Ils seront transmis, à l'intérieur de l'AS uniquement, par les protocoles de routage habituels et tous les routeurs vont l'avoir dans leur RIB. Ces préfixes virtuels couvrent plusieurs préfixes « réels ». Les routeurs qui veulent économiser de la mémoire ne vont pas installer les préfixes réels couverts dans leur FIB. Notez bien que les préfixes virtuels ne sont pas annoncés en dehors de l'AS. Si cette solution n'est plus déployable par un routeur seul, elle l'est par un AS seul.
Un opérateur réseau va donc typiquement avoir quelques très gros routeurs qui auront dans leur FIB (et dans leur RIB) tous les préfixes. Ils annonceront en plus les préfixes virtuels. Les autres routeurs, moins gros et moins coûteux, garderont tous les préfixes uniquement dans leur RIB et ne mettront pas dans la FIB les préfixes qui sont couverts par un des préfixes virtuels. Le préfixe virtuel pourra même être la route par défaut, entraînant ainsi la non-installation dans la FIB de tous les préfixes ayant le même next hop que la route par défaut.
Un peu de vocabulaire, maintenant (section 1.1) : un FIR (FIB Installation Router) est un des gros routeurs de cœur, qui installe toutes les routes dans sa FIB, et annonce les préfixes virtuels. Un FSR (FIR Suppressing Router) est un routeur situé plus aux marges du réseau et qui n'installe pas dans sa FIB les routes couvertes par un préfixe virtuel, si elles ont le même next hop que le préfixe virtuel. (Le RFC dit « supprimer une route » pour « ne pas l'installer dans la FIB ».) Une troisième catégorie de routeurs est composé des machines actuelles, qui ne connaissent pas ce RFC, et ne peuvent donc ni émettre les préfixes virtuels, ni supprimer des routes couvertes par un tel préfixe.
La section 2 décrit en détail le fonctionnement de ce système. Un
FIR doit annoncer les préfixes virtuels en mettant dans les attributs
de l'annonce BGP un ORIGIN
(RFC 4271, section 5.1.1)
à INCOMPLETE
(pour dire que la route n'a pas été
apprise par un protocole de routage). Il doit mettre
NEXT_HOP
(RFC 4271, section
5.1.3) à l'adresse du routeur qui gérera toutes les routes du préfixe
virtuel. Et il doit ajouter un attribut NO_EXPORT
(RFC 1997) pour éviter que ce préfixe virtuel ne sorte de
l'AS.
Le FSR, lui, lorsqu'il reçoit de telles routes, les installe dans RIB et FIB. Il peut alors décider de supprimer de sa FIB les routes plus spécifiques ayant le même next hop. Comme vous le voyez, c'est très simple.
La section 3 du RFC se penche sur les problèmes opérationnels pratiques. D'abord, attention au fait qu'une route BGP peut être utilisée pour résoudre un next hop qui n'est pas directement connecté. Il ne faudra donc pas supprimer de la RIB de telles routes.
On l'a vu, les routeurs FSR peuvent économiser de la place non seulement en FIB mais également en RIB, en supprimant de celles-ci les routes couvertes par un préfixe virtuel. Attention, cela peut interagir avec une politique de redistribution de routes aux pairs. Si une telle politique est en place (fondée, par exemple, sur la longueur du préfixe) on peut avoir des cas où la route couverte aurait été redistribuée mais où le préfixe virtuel ne l'est pas. Dans ce cas, il ne faut pas supprimer la route couverte de la RIB (on peut toujours la supprimer de la FIB).
À noter que le groupe de travail grow avait également travaillé sur des mécanismes d'agrégation plus complexes (avec des tunnels MPLS pour joindre les routeurs annonçant les préfixes virtuels) mais que cela n'a pas abouti. Les Internet-Drafts ont été abandonnés. Un bon article de fond sur cette idée d'« agrégation virtuelle » est celui de Paul Francis et Xiaohu Xu (un des auteurs du RFC), « Extending Router Lifetime with Virtual Aggregation ».
Globalement, cela me semble une bonne idée. Avec les préfixes virtuels, ce n'est plus une solution locale au routeur mais c'est local à l'AS et donc ça reste déployable unilatéralement.
Merci à Sarah Nataf pour avoir attiré mon attention sur ce document et à Bastien Pilat et Benjamin Abadie pour leurs corrections.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : S. Cheshire (Apple), M. Krochmal (Apple)
Chemin des normes
Première rédaction de cet article le 20 février 2013
Ce RFC normalise une technique pour trouver des ressources sur un réseau. Soit une machine qui arrive sur ce réseau. Elle cherche une imprimante, un serveur de fichiers, comment fait-elle ? Il ne s'agit pas juste de trouver une information technique unique (comme le routeur par défaut, qui est indiqué par DHCP ou RA, les Router Advertisement du RFC 4862) mais de récolter une liste de mises en œuvre possible de ce service, liste parmi laquelle on choisira ensuite. SD (Service Discovery) fonctionne en interrogeant le DNS, avec le nom du service, la réponse indiquant les machines qui fournissent ce service.
Ce protocole est fondé sur le DNS et utilise du DNS standard : même format, mêmes messages, etc. (Rappelons que le DNS, contrairement à ce que racontent les articles des médias et les textes « DNS pour les nuls », ne sert pas qu'à trouver les adresses IP, c'est au contraire un protocole de base de données très général.) SD est donc uniquement un ensemble de conventions (notamment de nommage) au dessus du DNS. SD est souvent utilisé au dessus du Multicast DNS du RFC 6762, mais peut aussi être utilisé sans lui. Avec Multicast DNS, SD fournit une solution « zéro configuration ».
L'idée de base est que les services sont décrits par des enregistrements SRV (RFC 2782) dont le nom est le nom d'une instance du service et dont le contenu indique le nom du serveur rendant ce service, ainsi que le port à utiliser. Un enregistrement TXT permet, si nécessaire, d'indiquer d'autres informations, qui ne rentrent pas dans un enregistrement SRV. Et pour trouver toutes les instances d'un service ? On se sert d'un enregistrement PTR dont le nom est celui du service.
Par exemple, si une machine Multicast DNS cherche une imprimante (service
IPP, cf. RFC 2910), elle va faire une requête PTR
_ipp._tcp.local
(où .local
est le
pseudo-TLD de Multicast DNS). Mettons qu'elle obtienne
deux réponses, Imprimante comptabilité.local
et
myprinter.local
. Si l'utilisateur, via une
interface de sélection, choisit l'imprimante de la comptabilité,
l'étape suivante sera de faire une requête SRV Imprimante comptabilité.local
(rappelez-vous que le DNS permet
caractères Unicode et espace, contrairement à
ce qu'on lit parfois, et c'est courant dans le monde Multicast DNS). Mettons
que cette requête donne comme résultat a56grthg43.local,
port 9818
, alors la machine qui veut imprimer se connectera
à l'adresse de a56grthg43.local
, port
9818. Voilà, en quelques mots, le fonctionnement de Multicast DNS. La section
13, décrite plus loin, fournit des exemples réels.
Pour mieux comprendre SD, il est utile de lire la section 3, qui expose le cahier des charges de ce protocole :
SD se veut l'héritier du protocole NBP d'Apple (celui popularisé par le Chooser/Sélecteur des anciens Macintosh) et une plus longue discussion de cet héritage figure dans le RFC 6760.
La section 4 explique comment fonctionne l'énumération des
instances d'un service. On l'a vu, le client SD doit faire une requête
de type PTR pour un nom qui est la concaténation du service et du
domaine. Si le client cherchait à accéder au service
foobar
, il fera des requêtes PTR pour
_foobar._tcp.local
en Multicast DNS et
_foobar._tcp.example.net
autrement (si
example.net
est le domaine du client). La
requêtes renverra des noms d'instance. Ces noms d'instance sont en
Unicode (dans le profil du RFC 5198, qui exclut les caractères de contrôle mais pas
grand'chose d'autres ; voir l'annexe C pour une discussion de ce
choix et l'annexe E pour ses conséquences). Ainsi, un nom d'instance
peut comprendre des points (voir
la section 4.3 pour les précautions à prendre). Notez que, vue la façon
dont fonctionne l'encodage UTF-8, les limites
de taille du DNS peuvent réduire le nom à quinze caractères, dans le
pire des cas (caractères Unicode en dehors du
Plan Multilingue de Base). Notez que le DNS a deux limites, une de
63 octets sur
la longueur d'un composant du FQDN et une de
255 octets sur
le FQDN (section 7.2 pour les détails). Il y a aussi une taille imposée par la raison : si le but
est de présenter une liste d'instances d'un service à un utilisateur,
une liste de, mettons, cent entrées, n'a guère de sens.
Le nom de l'instance doit pouvoir être choisi par
l'utilisateur, et ne devrait pas être un nom unique généré à l'usine,
nom qui serait probablement incompréhensible (genre dérivé de
l'adresse MAC ou d'un autre identificateur
technique, par exemple Mac064389AB5
). L'annexe D
explique pourquoi ces noms d'usine sont une mauvaise idée. Notamment,
le fonctionnement de Multicast DNS et SD fait que des noms uniques ne sont pas nécessaires.
Quand au nom de domaine à la fin (.local
avec
Multicast DNS ou un nom de domaine habituel autrement), il n'a pas de règles
particulières. Notez encore que le FQDN n'est
pas limité aux lettres-chiffres-tiret du RFC 952. En effet, contrairement à ce que dit une légende tenace,
le DNS n'a jamais été limité à ASCII. Des noms
comme εκτυπωτής.local
ou
Building A, 1st floor printer.example.com
sont donc
parfaitement valables. Comme indiqué plus haut, s'ils comportent des
caractères non-ASCII, ils sont stockés dans le DNS en
UTF-8 (RFC 5198, qui
normalise le profil Unicode de l'Internet, incluant la
canonicalisation choisie). Un
client SD qui n'obtient pas de réponse pour une requête en UTF-8 a
toutefois le droit de reessayer en Punycode
(RFC 3492) mais ce n'est pas obligatoire.
Les RFC normalisent des protocoles tels
qu'ils s'expriment sur le câble, pas des interfaces
utilisateurs. Néanmoins, la section 4.2 et l'annexe F donnent quelques
conseils sur la présentation des résultats à
l'utilisateur. Typiquement, le logiciel fait sa requête PTR, récolte
une liste d'instances, et montre la liste à l'utilisateur pour qu'il
choisisse. A priori, seul le premier composant est montré, pas le FQDN
(donc, εκτυπωτής
et pas
εκτυπωτής.local
ou bien
Building A, 1st floor printer
et non pas
Building A, 1st floor printer.example.com
).
Après l'énumération des instances, la section 5
explique la résolution du nom d'une instance. Dans la section
précédente, on a obtenu le nom Building A, 1st floor printer.example.com
et on va chercher à contacter la
machine. C'est là que le client SD va faire une requête SRV (pour
obtenir nom de machine et port) et une requête TXT (pour obtenir des
détails qui n'étaient pas prévus dans l'enregistrement SRV). Les
enregistrements SRV (RFC 2782) sont très précieux car ils évitent des numéros de
port fixes (il n'y en a que 65 535 et ce n'est
pas possible d'en réserver un à l'usage exclusif de chaque service,
même si ça se faisait au début de l'Internet). N'importe quel service peut tourner
sur n'importe quel port, le client trouvera le port dans
l'enregistrement SRV. Autre avantage des SRV : les champs Priorité et
Poids qui permettent d'assurer la répartition de charge et la résistance aux
pannes. Notez que, si vous êtes programmeur et que cela
vous fatigue de gérer les règles de priorité et de poids, il existe
des bibliothèques qui font cela pour vous, comme RULI.
La section 6 décrit les enregistrements TXT. Les SRV sont très utiles, notamment parce qu'ils sont normalisés depuis longtemps et déjà mis en œuvre dans certains logiciels. Mais ils ne permettent pas d'enregistrer toutes les nuances qu'on voudrait spécifier. D'où l'usage des enregistrements TXT, du texte libre où on peut encoder ce qu'on veut. Par exemple, si un client SD cherche une imprimante, savoir le nom de la machine et le port ne suffit pas. Le vieux protocole LPR (RFC 1179 impose également un nom de file d'attente d'impression. De même, un serveur de fichiers peut avoir plusieurs volumes à servir. On va alors les stocker dans un TXT, avec des règles exactes qui dépendent de l'application (impression, service de fichiers, etc).
Cet enregistrement TXT est obligatoire, même si on n'a rien à dire. Cela permet notamment de choisir le TTL de cette information (autrement, c'est celui de la zone qui s'appliquerait). Le RFC recommande de le garder d'une taille raisonnable (quelques centaines d'octets), même si la théorie permet davantage. Mais, par exemple, il existe des mises en œuvre de Multicast DNS dans le matériel, qui permettent à une machine d'être découvrable sur le réseau même lorsqu'elle est en hibernation et ces mises en œuvre ont souvent des limites ridicules (par exemple 256 octets maximum pour un TXT).
Et le contenu de ce TXT, alors ? Ce sont des couples clé=valeur,
contenant des informations qui dépendent du service (par exemple, pour
le service d'impression, on peut consulter Bonjour Printing Specification). La valeur est
facultative. Donc, on peut avoir un couple
PlugIns=JPEG,MPEG2,MPEG4
(indiquant quels formats
sont acceptés) ou PaperSize=A4
, mais aussi uniquement passreq
(juste une clé, sans valeur, ce qui est utile pour les attributs
booléens, cet enregistrement est équivalent à passreq=true
). La valeur peut être également de taille nulle
(PlugIns=
pour indiquer qu'aucun format
supplémentaire n'est disponible).
Idéalement, ces informations devraient être facultatives, de simples optimisations du service, et la négociation entre le client et le serveur devrait suffire. En pratique, certains protocoles, comme LPR cité plus haut, imposent des informations qu'on ne trouve que dans le TXT (par exemple, le protocole LPR ne fournit aucun moyen pour une imprimante de dire à son client qu'elle accepte PostScript ou pas). En outre, lorsqu'une information est distribuée via ce TXT, il est important de veiller à ce qu'elle soit cohérente avec ce qui est réellement disponible sur la machine qui répond aux requêtes SD.
Dans les couples clé=valeur, la clé est courte (il n'est pas prévu de la montrer aux utilisateurs, elle n'a pas à être « conviviale »), en ASCII uniquement, et unique. Elle est insensible à la casse. La valeur peut être n'importe quoi, y compris du binaire (attention donc si vous l'affichez). Mais c'est souvent du texte, ASCII ou UTF-8.
Si un service risque d'évoluer dans le futur, et de manière
incompatible, le RFC recommande de mettre un attribut indiquant la
version, de clé txtvers
, par exemple
txtvers=1
. Cela aidera le client à savoir à quel
genre de serveur il parle.
Maintenant, discutons du noms des services. La section 7 dit qu'ils
sont faits de deux composants, le nom proprement dit (suivant le
registre décrit dans le RFC 6335, cf. section 16), précédé d'un
tiret bas, puis _tcp
ou
_udp
. Et les autres protocoles, comme
SCTP ? Ils n'ont malheureusement pas de domaine
pour eux, tout ce qui n'est pas TCP doit être
mis sous _udp
. Le point est discuté dans la
section 7 mais l'argumentation est invraisemblable, je ne sais même
pas comment l'IESG a laissé passer cela, bien
que c'était explicitement mentionné dans les revues du futur RFC.
Un point plus sérieux est celui du choix du nom d'un protocole. Il
est courant de bâtir un protocole applicatif au dessus d'un autre,
souvent au dessus de HTTP, à la fois pour
bénéficier des nombreuses bibliothèques existantes, et pour être
raisonnablement sûr de passer les
pare-feux. C'est ainsi que le protocole de
partage de musique
DAAP, utilisé par
iTunes, est construit au dessus de HTTP. Le
service, dans les enregistrements SF, doit-il être
_http._tcp.DOMAIN
ou bien
_daap._tcp.DOMAIN
? La réponse est claire, c'est
le second choix qui est le bon : DAAP n'a de sens qu'avec un client
iTunes (un navigateur Web normal, par exemple, serait bien embêté est
se connectant à un serveur DAAP, et un client iTunes ne saurait pas
quoi faire d'un serveur HTTP générique), et le fait que ce soit du HTTP
sous-jacent n'est qu'un détail technique, qui ne se reflète pas dans
le nom du service. SD publie le service, pas la façon dont il est mis
en œuvre.
À partir d'ici, le RFC continue mais il s'agit plutôt de points de détail, qui n'affectent pas la compréhension globale de SD.
Dans certains cas, il peut être utile de restreindre la demande à
un sous-ensemble des machines implémentant un service. Prenons
l'exemple d'une imprimante, dotée d'un serveur HTTP pour en permettre
l'administration. Si un navigateur Web qui cherche les imprimantes à
administrer demande _http._tcp.DOMAIN
, il va
trouver des tas de serveurs n'ayant rien à voir avec les
imprimantes. SD permet donc d'ajouter un champ, le sous-type, pour
faire une requête _printer._sub._http._tcp.DOMAIN
pour
« sous-service Imprimante du service HTTP ». (Notez le
_sub
, dont le RFC n'explique pas le rôle.) Notez
que c'est un problème différent de celui du paragraphe précédent :
ici, le service d'administration des imprimantes n'est pas juste
« bâti sur HTTP », il est en HTTP et un navigateur HTTP générique peut
l'utiliser (la section 7.1 détaille dans quels cas les sous-types sont
utiles et dans quels cas ils ne le sont pas). Le
navigateur Safari sur
MacOS fonctionne ainsi. En parlant de MacOS, la
commande dns-sd
permet de publier sur le réseau
local un nom de service. Par exemple, ici, on publie le service HTTP
A web page :
% dns-sd -R "A web page" _http._tcp local 100
Alors qu'ici on publie un « sous-service »
printer
nommé A printer's web
page (ouvrez bien l'œil, il y a une
virgule, pas un point) :
% dns-sd -R "A printer's web page" _http._tcp,_printer local 101
Avec la syntaxe standard des fichiers de zone du DNS (RFC 1035, section 5), les mêmes déclarations seraient :
; One PTR record advertises "A web page" _http._tcp.local. PTR A\032web\032page._http._tcp.local. ; Two different PTR records advertise "A printer's web page" _http._tcp.local. PTR A\032printer's\032web\032page._http._tcp.local. _printer._sub._http._tcp.local. PTR A\032printer's\032web\032page._http._tcp.local.
Que fait SD lorsque plusieurs protocoles assurent à peu près la même fonction (section 8) ? C'est un cas courant, pour des raisons historiques, ou bien lorsque plusieurs équipes n'ont pas pu résister à la tentation de développer leur propre jouet. Par exemple, la fonction d'impression peut être faite par LPR (RFC 1179) ou IPP (RFC 2910), sans compter des protocoles spécifiques d'un vendeur. Le principe de SD dans ce cas, est de décider qu'un des protocoles est le « vaisseau amiral ». Une instance a alors tout intérêt à mettre en œuvre ce protocole privilégié pour assurer le service. Toutefois, si ce n'est pas le cas, elle doit quand même créer un enregistrement SRV pour ce protocole, avec un port de zéro (signifiant qu'il n'est pas utilisable) afin que la détection de duplicata fonctionne.
En général, un client SD donné ne s'intéresse qu'à un seul
service. S'il veut imprimer, il cherche une imprimante, et se moque
des autres services existants sur le réseau. Toutefois, lorsqu'on veut
analyser et déboguer un réseau où il y a du SD, il est pratique de
pouvoir demander « toutes les instances de tous les services ». Cela
se fait (section 9) en demandant
_services._dns-sd._udp.DOMAIN
.
Au fait, comment est-ce que les informations SD arrivent dans le DNS (section 10) ? Fondamentalement, ce n'est pas notre problème : le RFC 6763 normalise les interactions sur le réseau, pas la façon dont chaque machine est configurée, et dont cette configuration arrive dans le DNS. Il peut y avoir deux méthodes : si on utilise Multicast DNS, chaque machine connait sa propre information et y répond. Sinon, il faut configurer un serveur DNS traditionnel. Cela peut se faire à la main (en éditant le fichier de zone) mais SD est plutôt conçu pour des réseaux non-gérés, où il n'y a pas d'administrateur système (même pas d'administrateur système incompétent). Il faut donc plutôt envisager des mécanismes automatiques, par exemple un programme qui balaie le réseau (en utilisant d'autres protocoles) puis produit le fichier de zone (cette possibilité est citée par le RFC mais semble peu déployée en pratique).
Comme un des buts de SD est de permettre l'énumération de choses
inconnues, par exemple lorsqu'un portable arrive sur un nouveau réseau, et sans
configuration manuelle préalable, comment apprendre les noms de
domaine à utiliser dans les requêtes SD (section 11) ? S'il n'y a pas
de serveur DHCP qui répond, il faut sans doute
utiliser le .local
de Multicast DNS. S'il y a un serveur
DHCP, il indique un nom par l'option 15, Domain
(RFC 2132), ou par l'option 119 Domain
Search
(RFC 3397). À noter qu'en
IPv6, ce sera sans doute
RA et non pas DHCP qui sera utilisé, et qu'il
peut aussi indiquer un domaine (RFC 8106).
Une fois qu'on a ce nom, on peut former des requêtes spéciales pour découvrir d'autres choses :
b._dns-sd._udp.DOMAIN
donne la liste de
tous les domaines disponibles pour l'exploration,db._dns-sd._udp.DOMAIN
donne le domaine
recommandé pour l'exploration,r._dns-sd._udp.DOMAIN
et
dr._dns-sd._udp.DOMAIN
les ou le domaine à
utiliser pour enregistrer des noms via les mises à jour dynamiques du
DNS.
Notons que beaucoup de clients SD n'utiliseront pas ces requêtes et se
contenteront du premier domaine déterminé (.local
ou bien celui appris par DHCP).
Le RFC recommande, en section 12, aux serveurs DNS qui répondront au requêtes SD d'inclure dans la section additionnelle des informations supplémentaires, non indispensables, mais qui peuvent diminuer le trafic en évitant au client de poser la question par la suite. Par exemple, lorsqu'on envoie une réponse SRV, inclure les adresses du serveur nommé dans l'enregistrement SRV est raisonnable. Bien sûr, le client est libre d'en tenir compte ou pas (il peut estimer que, pour des raisons de sécurité, il vaut mieux reposer la question : la section additionnelle est un bon endroit pour tenter d'empoisonner un client DNS avec des informations bidon).
La section 13 contient des exemples réels, en utilisant le domaine
dns-sd.org
, qui est servi par des
BIND standard (SD ne nécessite aucune
modification des serveurs de noms). Pour voir, on va l'interroger avec
drill, livré avec ldns (le RFC utilise l'antédiluvien
nslookup et moi je me sers habituellement de
dig). Commençons par les services HTTP :
% drill -b 4096 PTR _http._tcp.dns-sd.org. ... ;; ANSWER SECTION: _http._tcp.dns-sd.org. 60 IN PTR \032*\032Google,\032searching\032the\032Web._http._tcp.dns-sd.org. _http._tcp.dns-sd.org. 60 IN PTR \032*\032Amazon\.com,\032on-line\032shopping._http._tcp.dns-sd.org. _http._tcp.dns-sd.org. 60 IN PTR \032*\032Yahoo,\032maps,\032weather,\032and\032stock\032quotes._http._tcp.dns-sd.org. _http._tcp.dns-sd.org. 60 IN PTR \032*\032SlashDot,\032News\032for\032Nerds,\032Stuff\032that\032Matters._http._tcp.dns-sd.org. _http._tcp.dns-sd.org. 60 IN PTR \032*\032DNS\032Service\032Discovery._http._tcp.dns-sd.org. ...
L'option -b
(indiquer au serveur la taille des
réponses qu'on peut recevoir) est là car la réponse est de grande
taille. Notez aussi que drill a représenté les espaces par un code
pour éviter toute ambiguité. Affichée à un humain, cette liste
donnerait :
* Google, searching the Web. * Amazon.com, on-line shopping. * Yahoo, maps, weather, and stock quotes. * SlashDot, News for Nerds, Stuff that Matters. * DNS Service Discovery. ...
Une fois qu'on a choisi un des services découverts, comment le contacter ?
% drill SRV '\032*\032DNS\032Service\032Discovery._http._tcp.dns-sd.org' ... ;; ANSWER SECTION: \032*\032DNS\032Service\032Discovery._http._tcp.dns-sd.org. 60 IN SRV 0 0 80 dns-sd.org. ... % drill TXT '\032*\032DNS\032Service\032Discovery._http._tcp.dns-sd.org' ... ;; ANSWER SECTION: \032*\032DNS\032Service\032Discovery._http._tcp.dns-sd.org. 60 IN TXT "txtvers=1" "path=/"
Bref, on peut joindre l'instance DNS Service
Discovery
du service HTTP sur le port 80 en contactant la
machine dns-sd.org
. Le TXT indique une option non
triviale, path=/
.
À noter que les noms b et r cités plus haut ne donnent aucun résultat
sur le domaine de test dns-sd.org
.
Voici maintenant un exemple réel, vu avec
tcpdump, d'une machine cherchant les instances
du service sane-port
en Multicast DNS :
21:06:04.877355 IP6 (hlim 255, next-header UDP (17) payload length: 47) \ 2a01:e35:8bd9:8bb0:21e:8cff:fe7f:48fa.5353 > ff02::fb.5353: [udp sum ok] 0 \ PTR (QM)? _sane-port._tcp.local. (39)
tcpdump
sait décoder le Multicast DNS et a vu la demande d'énumération (type PTR demandé) des instances du service
_sane-port._tcp.local
.
La section 15 résume ce qu'il faut savoir de la sécurité de DNS-SD. Le RFC est très court à ce sujet et oublie de préciser clairement que DNS-SD n'offre en soi aucune sécurité. S'il est utilisé sur Multicast DNS, il en hérite l'absence totale de protection. Sinon, il a la sécurité du DNS (faible) et ses protections (DNSSEC mais, évidemment, les réseaux locaux sans administrateur n'auront pas DNSSEC, technique encore trop complexe à mettre en œuvre).
Chose rare dans les RFC, les pincipaux choix techhniques faits par les concepteurs de SD sont documentés dans le RFC, dans les annexes. Ce sont de très intéressantes lectures. Ainsi, l'annexe A explique pourquoi SD s'appuie sur le DNS et pas sur un nouveau protocole, peut-être plus adapté : c'est essentiellement pour pouvoir utiliser toute une infrastructure de normes (DNSSEC, mises à jour dynamiques), de logiciels (serveurs, clients comme drill, analyseurs) et de compétences, infrastructure qui a largement fait ses preuves. Technologie mûre, éprouvée, pour laquelle il existe beaucoup d'implémentations, beaucoup de livres et d'articles, et beaucoup de gens compétents : le DNS n'a aucun concurrent réaliste aujourd'hui.
L'annexe B explique pourquoi les noms interrogés sont écrits
INSTANCE.SERVICE.DOMAINE
et pas
SERVICE.INSTANCE.DOMAINE
. Il y a des raisons
sémantiques (les noms de domaines sont
petit-boutiens et le service est plus général
que l'instance) mais aussi techniques (la compression de noms dans le
DNS marche mieux dans ce cas).
L'annexe C est une très intéressante réflexion sur les services de découverte en général. C'est le genre de problèmes qui devrait être plus souvent discuté lors des enseignements de réseaux informatiques à l'Université (plus que les sempiternels réseaux de Petri). Certains services de découverte choisissent de donner à chaque instance un identificateur unique et opaque, typiquement représenté sous forme d'une longue chaîne de chiffres hexadécimaux. Le nom montré à l'utilisateur n'est alors que pour information, le protocole travaille avec les identificateurs uniques et opaques. SD n'a pas choisi cette approche, car elle sépare trop radicalement ce que voit l'utilisateur de ce qui se passe réellement sur le réseau. Par exemple, si deux instances différentes (et ayant donc des identificateurs opaques différents) ont le même nom montré ? Que va penser l'utilisateur de voir deux « Corridor Printer » ? Laquelle est la bonne ? En pratique, dans ce cas et dans d'autres (comme le remplacement d'un engin par un autre à qui on donne le même nom montré mais qui a un identificateur différent), l'utilisateur va devoir tôt ou tard apprendre l'existence des identificateurs cachés et se colleter avec eux. Résultat, pour SD, le nom montré à l'utilisateur et celui utilisé dans le réseau sont toujours le même.
Un autre problème à la frontière entre l'ergonomie et l'informatique est celui des noms configurés à l'usine, avant que la machine ne soit livrée au client (annexe D). Certains fabricants, croyant bien faire, configurent des noms « inamicaux » par exemple en incluant un numéro de série ou bien une adresse MAC. Leur idée est de garantir l'absence de conflit de noms. Toutefois, lorsque SD utilise Multicast DNS, c'est tout à fait inutile, puisque Multicast DNS dispose d'un mécanisme de détection et de résolution de conflits (RFC 6762, section 9). Et ces noms inamicaux sont incompréhensibles par l'utilisateur. Le RFC prend l'exemple d'un utilisateur n'ayant qu'une seule imprimante. Le nom « Printer » sera unique et un nom globalement unique comme « Printer 18:03:73:66:e5:68 » ne servirait qu'à troubler l'utilisateur. S'il a deux imprimantes, la détection de conflits de Multicast DNS les nommera « Printer » et « Printer (2) », ce qui est certainement mieux que « Printer 18:03:73:66:e5:68 » et « Printer 18:03:73:98:a3:12 ». Et, s'il a dix imprimantes, il va de toute façon devoir passer un peu de temps pour les nommer et les configurer.
Le RFC recommande donc simplement de choisir des noms d'usine qui décrivent le produit, comme « Xerox Phaser 6200DX » ou « HP LaserJet 4600 » et de compter sur la résolution de conflits de Multicast DNS pour le cas où deux HP LaserJet se retrouvent sur le même réseau.
On l'a déjà dit, SD n'est pas du tout limité à l'ASCII et peut utiliser Unicode. L'annexe E rappelle le contexte et insiste sur le fait qu'Unicode est une possibilité, pas une obligation. Si l'administrateur des machines n'aime pas Unicode et veut nommer ses machines uniquement en ASCII, il a évidemment le droit.
Normalement, l'IETF ne se préoccupe que de ce qui passe sur le câble et pas des interfaces utilisateur. On trouve donc peu de RFC qui mentionnent des problèmes d'IHM. Mais l'annexe F de ce RFC 6763 estime nécessaire d'insister sur une question qui a une influence directe sur le protocole et les implémentations : le fait que la découverte de services avec SD est un processus continu. On ne peut pas se contenter de présenter une liste à l'utilisateur et de le laisser choisir une fois pour toutes. Des nouvelles machines peuvent apparaître à tout instant, et d'autres disparaître (c'est évidemment particulièrement fréquent avec Multicast DNS). Plus important, des machines peuvent répondre avec retard et un service de découverte qui s'arrêterait au bout de quelques secondes risquerait de les rater. De plus, les concepteurs de SD considèrent que ce n'est pas sympa que de demander à l'utilisateur de relancer une découverte explicitement.
Le modèle privilégié par SD est donc : on affiche immédiatement la liste des instances trouvées (même si elle est initialement vide) et on met à jour cette liste en permanence (plus exactement jusqu'à ce que l'utilisateur ferme la fenêtre). La liste affichée doit représenter en permanence l'état actuel du réseau (on débranche le câble : elle se vide, on le rebranche, quelques secondes après les instances réapparaissent).
Ce RFC 6763 arrive longtemps après les premiers déploiements de SD. On n'est pas dans le cas d'un RFC qui propose une nouvelle technologie, encore à implémenter, mais dans celui d'un RFC qui décrit a posteriori un protocole qu'Apple a imposé unilatéralement. L'annexe G décrit la longue histoire de SD, depuis les réflexions originales en 1997, jusqu'au RFC actuel.
SD est aujourd'hui mis en œuvre sur Mac OS, Windows mais aussi sur de nombreux autres systèmes. Il existe par exemple une implémentations en C, mDNSResponder, une version Unix, Avahi, et plein d'autres.
À noter que j'avais été le relecteur Gen-ART (cf. RFC 6385)
pour ce document: http://www.ietf.org/mail-archive/web/gen-art/current/msg05815.html
.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : S. Cheshire (Apple), M. Krochmal (Apple)
Chemin des normes
Première rédaction de cet article le 20 février 2013
Après une très longue négociation (l'IETF
n'était pas enthousiaste pour entériner le coup de force
d'Apple), le protocole de résolution de noms
« Multicast DNS » est désormais normalisé dans ce
RFC. Multicast DNS permet de résoudre un
nom de domaine en données (par exemple en
adresses IP) sur le réseau
local, sans faire appel à un serveur DNS
configuré. Le demandeur claironne la question et la machine qui se
reconnaît répond. Les noms résolus par Multicast DNS utilisent presque
toujours le pseudo-TLD
.local
, décidé par
Apple.
Le problème que tente de résoudre Multicast DNS est
celui du réseau local rempli de petites machines
(smartphones, tablettes,
grille-pains, etc) et pas
d'administrateur réseaux compétent pour
configurer le tout. De tels réseaux sont de plus en plus
fréquents. Trouver l'adresse IP du grille-pain
par les mécanismes DNS classiques (un
administrateur réseau installe un serveur DNS, puis ajoute
grille-pain IN AAAA 2001:db8:1337::2
dans sa
configuration) n'est pas envisageable. L'idée de base de Multicast DNS est de
faire en sorte que chaque machine réponde aux requêtes pour son propre
nom. Ainsi, pas besoin d'un serveur DNS configuré manuellement. Multicast DNS
est donc une solution « zéro infrastructure ».
Multicast DNS est issu du projet de remplacement du protocole NBP d'AppleTalk, projet décrit dans le RFC 6760. L'idée de base, connue sous le nom de « Zeroconf » (le produit commercial d'Apple aujourd'hui se nomme « Bonjour ») était de rendre les réseaux IP aussi simples de configuration (pour un petit réseau sans importance) que l'étaient les réseaux AppleTalk. Au niveau de l'adressage, cela était déjà fait dans les RFC 3927 et RFC 4862, il restait à le faire pour le nommage.
Multicast DNS est du DNS (RFC 1034 et RFC 1035) au sens où il réutilise le format des paquets, les types de données et la syntaxe des noms. En revanche, le protocole utilisé pour la résolution de noms est nouveau. Il n'y a pas de récursion, la machine demandeuse diffuse simplement sur le réseau local sa question et la machine qui reconnaît son nom répond. Multicast DNS, qui n'est donc pas le DNS, tourne sur un autre port, le 5353.
Multicast DNS vise donc à être simple pour l'utilisateur (réseau sans administration). Mais le RFC est long et compliqué et plein de détails. Courage.
Avant de décrire plus en détail Multicast DNS, un peu de vocabulaire (section 2) :
La section 3 du RFC couvre un point délicat, les noms à
utiliser. Le concurrent de Multicast DNS, LLMNR (RFC 4795) utilise des noms normaux comme
gandalf.middleearth.example
. Les concepteurs de
Multicast DNS considèrent que tout le monde n'a pas de nom de domaine où y
enregistrer ses machines et qu'il est donc nécessaire d'avoir un
espace spécial pour mettre les engins qui répondent en Multicast DNS, le
pseudo-TLD
.local
. Multicast DNS peut
résoudre des noms habituels mais le cas privilégié est celui des noms
se terminant par .local
. Normalement, réserver un
TLD nécessite une procédure lente et très coûteuse (185 000 $ uniquement pour déposer le dossier !), mais
Apple semble avoir des privilèges particuliers
et a pris ce TLD sans demander son avis à l'ICANN, ni suivre aucune procédure habituelle. C'était un des aspects les plus brûlants de cette norme, et qui
avait suscité le plus de débats. Voir aussi annexe G.
Dans .local
, toute
machine peut « enregistrer » un nom, simplement en s'en proclamant
propriétaire et en répondant aux requêtes Multicast DNS pour ce nom. Ainsi,
si je nomme mon smartphone
dumbledore
, il répondra aux requêtes Multicast DNS
dumbledore.local
, et ce nom pourra être utilisé
en argument des commandes comme ping, ou mis
dans un URL
(http://dumbledore.local/
). L'utilisation d'un
seul composant avant .local
(ici,
dumbledore
) est recommandé.
Voici un dialogue Multicast DNS entre le PC/Ubuntu « tyrion » et le Raspberry Pi « alarmpi ». Tous les deux ont le logiciel Avahi. tyrion veut pinguer alarmpi :
09:11:25.650228 IP (tos 0x0, ttl 255, id 0, offset 0, flags [DF], proto UDP (17), length 59) 192.168.2.26.5353 > 224.0.0.251.5353: [udp sum ok] 0 A (QM)? alarmpi.local. (31) 09:11:25.651092 IP (tos 0x0, ttl 255, id 0, offset 0, flags [DF], proto UDP (17), length 69) 192.168.2.4.5353 > 224.0.0.251.5353: [bad udp cksum db2!] 0*- [0q] 1/0/0 alarmpi.local. (Cache flush) [2m] A 192.168.2.4 (41)
On voit que 192.168.2.26
(tyrion) a demandé à la
cantonade (224.0.0.251
) qui était
alarmpi.local
. La question était posée en
multicast (QM
). La réponse
contenait l'adresse d'alarmpi, 192.168.2.4
.
Ensuite, tyrion veut résoudre cette adresse en nom, il va faire une
requête PTR
:
09:11:25.779570 IP (tos 0x0, ttl 255, id 0, offset 0, flags [DF], proto UDP (17), length 70) 192.168.2.26.5353 > 224.0.0.251.5353: [udp sum ok] 0 PTR (QM)? 4.2.168.192.in-addr.arpa. (42) 09:11:25.780463 IP (tos 0x0, ttl 255, id 0, offset 0, flags [DF], proto UDP (17), length 91) 192.168.2.4.5353 > 224.0.0.251.5353: [bad udp cksum 8d1!] 0*- [0q] 1/0/0 4.2.168.192.in-addr.arpa. (Cache flush) [2m] PTR alarmpi.local. (63)
.local
, quoique non enregistré dans le RFC 2606 est donc un nom spécial. Les noms dans ce
pseudo-TLD n'ont pas de signification globale, un peu comme les
adresses IP locales au lien des RFC 3927 et RFC 4291. Les requêtes pour un nom se terminant en
.local
sont donc envoyées en Multicast DNS aux adresses
de diffusion restreinte
224.0.0.251
ou ff02::fb
(désormais enregistrées
à l'IANA - idem en
IPv6, cf. section 22). Les
autres noms peuvent aussi être résolus en Multicast DNS mais ce n'est pas
l'usage. Cela permettrait à la résolution de noms locaux de
fonctionner, même en cas de coupure de l'accès Internet. Mais cela
poserait de gros problèmes de sécurité puisque, en Multicast DNS, n'importe
quelle machine du réseau local peut répondre « oui, je suis
onlinebanking.banqueserieuse.example
». Le RFC
demande que DNSSEC, ou un mécanisme
équivalent, soit alors utilisé...
Naturellement, il peut y avoir des conflits, puisqu'il n'y a pas de registre chargé d'attribuer les noms de manière unique. Multicast DNS résout ce problème en testant un nom sur le réseau local avant de l'utiliser. S'il est déjà utilisé, la machine Multicast DNS fait marche arrière et choisit un autre nom.
Multicast DNS peut aussi être utilisé pour la résolution d'adresse en nom
(section 4). Dans ce cas, il n'utilise pas .local
mais les noms en .arpa
des
adresses IP locales au lien, 254.169.in-addr.arpa
et de 8.e.f.ip6.arpa
à b.e.f.ip6.arpa
.
Une fois les noms décidés, reste à envoyer les requêtes et à y
répondre. Il existe deux acteurs, le demandeur, ou client
(Querier) et le répondeur, ou serveur
(Responder). Multicast DNS a deux modes (section 5) : envoi unique et envoi
continu. Le premier est très proche du fonctionnement actuel du
DNS. Le demandeur Multicast DNS envoie un paquet vers
224.0.0.251:5353
ou
[ff02::fb]:5353
et attend la réponse. Le client
n'a même pas besoin de savoir que c'est une adresse
multicast. Il suffit donc de
changer quelques lignes de code dans le client, pour dire « si le nom
se termine par .local
, envoie le paquet DNS à
[ff02::fb]:5353
, sinon envoie au résolveur
normal ». (Il faut aussi éviter d'utiliser le port source 5353 car
celui-ci indique un client Multicast DNS complet, qui utilise le second
mode.) Rappelez-vous que Multicast DNS utilise le format habituel des
paquets DNS donc la construction du paquet de requête et l'analyse de
la réponse ne changent pas.
Un tel client simple acceptera probablement la première réponse qui
arrivera. Cela a quelques inconvénients. Si on réclame
myprinter.local
et que plusieurs imprimantes sur
le réseau local portent ce nom, seule la plus rapide à répondre sera
prise en compte. Il est donc préférable de
patcher un peu plus le
demandeur et d'en faire un client Multicast DNS complet, utilisant
le second mode.
Ce deuxième mode de fonctionnement, en continu, ne va pas se
contenter de la première réponse, mais va continuer jusqu'à une
conclusion satisfaisante. Par exemple, si un navigateur Web veut se
connecter à http://myprinter.local/controlpanel
,
la conclusion est satisfaisante quand la page est affichée. Si
l'utilisateur est en train de naviguer dans le réseau local à la
recherche de ressources (par exemple avec le Service
Discovery du RFC 6763), la
conclusion n'arrive que lorsque la fenêtre de navigation est fermée
(tant que ce n'est pas le cas, il peut y avoir des nouvautés à
afficher et il faut continuer l'interrogation). Dans le cas de
recherche d'une imprimante cité plus haut, cela permet de ne pas se
limiter à l'imprimante qui a le répondeur Multicast DNS le plus rapide, mais de
s'assurer au contraire qu'on a reçu de l'information de toutes les
imprimantes.
Pour cela, le répondeur va donc tourner en permanence, et répéter les questions, notant les nouvelles réponses, jusqu'à ce que le programme qui lui a demandé une résolution qui signale qu'il n'est plus intéressé.
Pour indiquer la gestion complète de Multicast DNS, y compris le mode
d'interrogation en continu, le demandeur utilise le port source 5353
dans ses requêtes. Multicast DNS détourne un bit (section 5.4) dans le champ « classe » des
paquets (champ quasi-inutilisé puisque seule la classe IN - pour
Internet - est réellement déployée) pour indiquer si la réponse doit
elle-même être envoyée en diffusion ou en
unicast. Le fonctionnement
normal est que la réponse elle-même soit diffusée, pour permettre aux
autres clients Multicast DNS du réseau local d'en prendre connaissance,
économisant ainsi du trafic. Le bit est mis alors à zéro dans ces
requêtes QM (Query Multicast, comme dans l'exemple
entre tyrion et alarmpi plus haut), et c'est en général
ce que vous verrez dans la sortie de tcpdump si
vous surveillez le trafic Multicast DNS. Sinon, si le bit est mis à un, les
requêtes sont QU (Query Unicast) et la réponse sera
envoyée en unicast. Voici le dialogue précédent, entre tyrion et alarmpi, vu par
tshark : mdns1-tshark.txt
.
Et le répondeur, que doit-il faire (section 6) ? Multicast DNS n'a pas la distinction entre résolveur/cache et serveur faisant autorité, qui est si importante dans le DNS. Un répondeur fait toujours autorité, il ne met jamais dans la réponse les informations qu'il a apprises sur le réseau. Avec Multicast DNS, on ne sert que ses propres informations. Si le répondeur a l'information demandé, il répond avec autorité (bit AA - Authoritative Answer - mis à un), sinon, il ne répond tout simplement pas. C'est donc un comportement très différent de celui d'un serveur DNS habituel.
Si le répondeur a déterminé qu'un
nom, mettons example.local
, était unique et chez
lui, il répond positivement aux requêtes sur ce nom, s'il a des
données sur le type
demandé. Il répond négativement s'il n'en a pas (par exemple à une
requête pour des adresses IPv4 si le répondeur
ne connait qu'une adresse IPv6, sections 6.1 et
20). Si le nom est
partagé, et que le répondeur n'a pas d'information, il ne répond pas,
il n'envoie pas de NXDOMAIN. S'il a de l'information (par exemple, il
sait qu'il est le seul majoliemachine.local
sur
le réseau) et que la question porte sur un type qu'il n'a pas, il
renvoie une réponse avec un enregistrement
NSEC (voir l'annexe E pour les raisons du choix). Celui-ci joue un rôle analogue à celui qu'il a en
DNSSEC : dire clairement qu'on n'a pas une
information (voir section 20 aussi).
Comme tous les protocoles « zéro configuration », Multicast DNS peut être assez bavard et il y a donc des règles pour limiter le trafic, comme de retarder aléatoirement la réponse, pour éviter que tous les répondeurs ayant une information ne veulent émettre en même temps sur l'Ethernet.
À noter que, dans la grande majorité des cas, le répondeur ne répond pas en unicast mais en multicast. Le but est de permettre aux autres machines Multicast DNS d'observer les réponses (cf. section 10.5 et annexe D). D'une manière générale, les répondeurs coopèrent en écoutant les réponses des autres. Si le nom est partagé, il n'y a pas de problème. Si un répondeur détecte une réponse pour un nom qui est censé être unique et dont il est détenteur, il y a conflit et on passe alors à la section 9. (Si les données dans la réponse sont identiques, par contre, il n'y a pas de conflit : cela permet de répartir le travail entre plusieurs répondeurs, par exemple pour la résistance aux pannes.)
Les requêtes de type ANY
(où le demandeur veut
la totalité des enregistrements, quel que soit leur type) sont un cas
particulier (section 6.5). Dans le DNS, elles ont une sémantique
subtile et beaucoup d'utilisateurs se trompent à ce sujet, croyant par
exemple d'un récurseur va leur renvoyer tous les enregistrements qui
existent, alors qu'il n'envoie que ceux qu'il a dans son cache. Avec
Multicast DNS, c'est plus simple : comme tous les répondeurs sont des
serveurs faisant autorité, la réponse à une requête
ANY
est toujours complète, elle inclut tous les
enregistrements pour un nom.
J'ai déjà parlé de l'intensité du trafic que peut générer Multicast DNS sur le réseau local. La section 7 regroupe un ensemble de techniques de « réduction de bruit », qui permettent de limiter ce trafic. Bien sûr, sur un LAN, la capacité réseau ne coûte pas trop cher. Néanmoins, il est toujours plus sympa de ne pas abuser de la ressource partagée. Par exemple, si un demandeur connait déjà une partie des réponses, il les inclut dans le paquet de requête. Les répondeurs savent alors que ce n'est pas la peine d'y répondre. (Cela ne concerne en général que les noms partagés.) On économise ainsi un paquet (celui de la réponse).
Autre cas, si un répondeur s'apprête à répondre mais voit passer sur le réseau une réponse identique à celle qu'il allait donner, il se tait. Si plusieurs répondeurs ont les mêmes données, il n'est donc pas nécessaire, bien au contraire, qu'ils répondent tous. Au passage, c'est une excellente illustration de l'intérêt qu'il y a à envoyer les réponses en multicast, pour que les autres puissent les lire.
Avant de commencer son service, un répondeur doit savoir ce qu'il y a sur le réseau local, et notamment si d'autres répondeurs traiteront le même nom. C'est le sondage (probing) et c'est couvert en section 8. Le sondage est suivi de l'annonce (announcing). Ces deux opérations doivent être faites dès que la connectivité de la machine change (démarrage, arrivée sur un nouveau réseau, coupure/reconnexion du câble, etc).
D'abord, le sondage. Si le répondeur gère des noms censés être
uniques, il doit envoyer une requête sur le réseau pour ces
noms (avec le type ANY
). Normalement, elle ne
doit pas avoir de réponse. Avant d'envoyer la requête, on attend un
court délai aléatoire (entre 0 et 250 ms), aléatoire afin d'éviter, en cas de
coupure de courant, par exemple, ou de remise en service d'un
commutateur, que tout le réseau ne hurle en
même temps. Cette requête est répétée trois fois mais cela veut dire
que le délai total, pour une machine existante, pour défendre son nom
contre un nouveau venu, est relativement court, sur certains réseaux
lents. Le sondage peut donc ne pas détecter tous les conflits et il
est donc nécessaire, en phase de fonctionnement normal, d'écouter en
permanence les requêtes des autres et d'y répondre immédiatement (pas
de délai aléatoire, cette fois).
Si un conflit est détecté, la machine doit renoncer à ce nom et en chercher un autre (par exemple en demandant à son utilisateur humain).
Ça, c'était le sondage, pour voir si quelqu'un utilisait « mon » nom. Et l'annonce ? Décrite en section 8.3, elle consiste, une fois que le sondage est fait, à répondre (sans qu'il y ait eu de question) en diffusant tous ses enregistrements. Un écoutant passif saura alors que ce nom est pris et pourra mettre à jour son cache. Pour être sûr que cette « réponse » soit reçue, on en transmet au moins deux exemplaires. Par contre, on ne répéte pas cette réponse non sollicitée périodiquement ; elle n'est renvoyéee que si la connectivité réseau change ou bien si les données changent (section 8.4). Dans ce dernier cas, il n'est pas nécessaire de répéter l'étape du sondage, puisqu'on sait que le nom est déjà unique.
Maintenant, voyons un cas très difficile mais qui est fréquent sur
les réseaux non-gérés pour lesquels Multicast DNS est fait : le conflit
(section 9). Un répondeur a un nom unique,
monmactrescher.local
et il entend tout à coup sur
le réseau une réponse Multicast DNS pour le même nom ! Il y a conflit !
Quelqu'un d'autre a pris ce nom ! Si les données sont les mêmes, ce
n'est pas grave (c'est même une technique utilisée par Multicast DNS pour la
résistance aux pannes). Mais si elles sont différentes, que faire ? Si
un demandeur envoie une requête pour l'adresse IP de
monmactrescher.local
, que va-t-il recevoir ? La
mienne ou celle du méchant qui a pris le même nom pour sa machine ? Le
résultat ne sera pas du tout le même ! Le RFC impose que, dès qu'un
conflit est détecté, toutes les machines en conflit repartent à la
section 8 et recommencent les étapes de sondage et d'annonce. Une des
deux machines va alors l'emporter, l'autre devra changer de nom. Ce
changement peut se faire manuellement (« Une autre machine sur le
réseau se nomme monmactrescher
. Choisissez
un autre nom. ») ou automatiquement (le RFC suggère d'ajouter « 2 » à
la fin du nom, « 3 » si monmactrescher2.local
existe déjà, etc.) Dans le cas où le nom a été changé automatiquement,
le RFC suggère de prévenir l'utilisateur, par une boîte de dialogue si
la machine a une interface graphique, par des moyens adaptés sinon
(SNMP, par exemple).
Une des métadonnées dans les enregistrements DNS est le TTL. Quelle valeur doit être utilisée en Multicast DNS (section 10) ? Le RFC recommande, pour les enregistrements liés à un nom de machine, notamment les adresses IP, 2 minutes (valeur faible, mais rappelez-vous qu'il n'existe pas d'équivalent des résolveurs/caches en Multicast DNS ; chaque machine fait autorité et a un cache). Pour les autres, la valeur demandée est de 75 minutes. Cette valeur, au contraire de la première, peut sembler élevée. Des informations dépassées pourraient rester plus d'une heure dans les caches. Mais plusieurs techniques permettent de limiter le risque :
le Mac de Mic.local
est
2001:db8:1337::2
»), qu'il voit passer une
requête par un tiers (« quelle est l'adresse IP de le Mac de
Mic.local
? ») mais qu'il ne voit passer aucune réponse (le
Mac de Mic est éteint...), alors ce répondeur sait qu'il peut virer
l'enregistrement de son cache.Vous avez déjà noté (je reviendrais là-dessus plus tard en discutant la section 21 du RFC) que Multicast DNS n'offre aucune sécurité : n'importe quelle machine peut répondre n'importe quoi. Pour limiter les risques, le RFC impose quelques vérifications sur l'origine du paquet (section 11). Le test que le TTL était à 255, qui était dans les premières versions du protocole, a été abandonné (j'ignore pourquoi car ce test, décrit dans le RFC 5082, est simple et efficace). En revanche, le récepteur d'un paquet Multicast DNS envoyé à une adresse unicast doit vérifier que l'adresse IP source est bien sur le réseau local (un test qui, pour être utile, suppose que le pare-feu interdit l'entrée du réseau local aux paquets ayant une adresse IP source de ce réseau). Si le paquet a une adresse de destination multicast, pas besoin d'autre test, on compte que le routeur d'entrée de site ne l'aurait pas laissé passer, de toute façon.
Les noms utilisés par Multicast DNS ont quelques caractéristiques
spéciales par rapport au DNS auquel on est habitué. La section 12
liste ces caractéristiques, qui peuvent dérouter l'administrateur
système qui connait le DNS (s'il ne ne connnait pas, il peut sauter
cette section). D'abord, les noms en .local
n'ont une signification que... locale. Autrefois, le DNS était prévu
pour qu'un nom ait partout le même sens et que sa résolution donne
partout le même résultat. Aujourd'hui, avec des bricolages comme le
split view de BIND, ou comme
les pare-feux, ce n'est déjà plus le cas. Avec
Multicast DNS c'est encore plus marqué. machine à café.local
ne pointera donc pas vers les mêmes données
selon le lieu où on se trouve.
D'autre part, il n'y a pas de délégation dans Multicast DNS et donc pas
d'enregistrements NS. Si une machine répond à
machine à café.local
, rien ne garantit qu'elle
réponde à sucre.machine à café.local
.
Ah, et un point de multilinguisme : le FQDN n'est pas prévu pour être montré aux
utilisateurs. Le RFC précise donc qu'il ne faut pas traduire le
.local
...
Comme tout le monde n'a pas forcément envie de faire du Multicast DNS, la
section 13 du RFC précise que le fait de passer en Multicast DNS pour un nom
qui ne se termine pas
en .local
devrait être configurable par
l'utilisateur. Et, pour des raisons de sécurité, devrait être débrayée
par défaut. (Sinon, www.mabanque.example
pourrait
être résolue par Multicast DNS, avec son absence de sécurité...)
Dans les exemples cités ci-dessus, vous avez déjà vu des noms qui peuvent sembler surprenants, par exemple parce qu'ils comportents des espaces. La section 16 discute du cas des noms ayant des caractères sortant du traditionnel LDH (Letter-Digit-Hyphen avec Letter restreint à US-ASCII). Il faut bien noter que, contrairement à ce qu'affirme une légende tenace, le DNS a toujours permis tous les caractères. La restriction à LDH est une tradition, maintenue de crainte de planter les applications qui se croient dans un monde purement anglophone. Multicast DNS a l'avantage de la nouveauté et n'a pas d'héritage à assumer : dès le début, tous les noms peuvent être en Unicode, encodé en UTF-8 (dans le profil du RFC 5198). Notez bien que Multicast DNS n'utilise pas Punycode (l'annexe F discute cet excellent choix).
Cela a toutefois quelques conséquences qui peuvent sembler
déroutantes. Ainsi, Multicast DNS, comme le DNS, prétend être
insensible à la casse. Mais ce n'est vrai que
pour les caractères ASCII. La machine
MyPrinter.local
va répondre aux requêtes Multicast DNS
pour myprinter.local
mais Machine À
Café.local
ne répondra pas pour machine à
café.local
! Pour faire une telle équivalence, il faurait
fallu s'aventurer dans la jungle des conversions de casse en Unicode,
un sujet très complexe (dans certains cas, cela dépend de la langue).
Pour les mêmes raisons, Multicast DNS ne fournit pas d'équivalence
automatique, par exemple entre version accentuée et non accentuée d'un
nom. Si on cherche machine à café.local
, on ne
trouvera pas machine a cafe.local
. Si on veut que
cela fonctionne, il faut que le répondeur décide de répondre à tous
ces noms (ou bien que quelqu'un ait créé des
enregistrements CNAME).
Continuous cette longue exploration des points de détails qui font que Multicast DNS est plus compliqué qu'il n'en a l'air à première vue. La section 17 étudie le problème de la taille des paquets. Au tout début, il y a très longtemps, du temps des dinosaures, les paquets DNS étaient limités à 512 octets. Cette limite a sauté il y a des années, et, de toute façon, elle n'a guère de sens en réseau local, le domaine de Multicast DNS. Il n'y a pas non plus de problème de découverte de la MTU du chemin. Les paquets Multicast DNS peuvent donc avoir la taille de la MTU du réseau. La fragmentation IP est bien sûr possible, mais déconseillée.
Quel est le format exact des paquets Multicast DNS (section 18) ? Bien sûr, c'est du DNS. Mais il y a quelques particularités. Je ne vais pas répéter toute la section 18 mais je note deux points :
D'ailleurs, quelles sont les différences entre Multicast DNS et le DNS ? La section 19 offre un utile résumé. Quelques points qui méritent d'être retenus (la liste exacte est bien plus longue) :
.local
,Et, par contre, ce qui ne change pas :
Arrivé à ce stade, il est temps de faire un tour complet de la
sécurité de Multicast DNS. La section 21 est consacrée
à ce point. Pour résumer, Multicast DNS n'offre aucune sécurité, encore
moins que le DNS normal. Multicast DNS suppose que tous les participants
coopèrent sincèrement. En cas de désaccord, il n'existe par définition
aucune autorité supérieure qui pourrait trancher. Multicast DNS est une
parfaite an-archie et, comme pour tous les
protocoles « zéro-configuration », est donc très difficile à
sécuriser. Si on craint la présence d'un ou plusieurs méchants sur le
réseau local, la première solution est d'utiliser un autre
protocole. Si on connait les gentils, on peut toujours utiliser
IPsec, pour être sûr de ne communiquer qu'avec
les gentils (je trouve cette idée curieuse, IPsec n'étant pas
spécialement « zéro-configuration »...) DNSSEC
est également bien sûr une solution possible (mais il a le même
problème). DNSSEC est évidemment impératif si on utilise Multicast DNS pour
résoudre des noms en dehors de .local
. Notons au
passage que ce modèle de sécurité pose un problème à l'utilisateur :
celui-ci devra prêter attention aux noms et savoir que
.local
est moins sûr. Un défi pour Monsieur
Toutlemonde. C'est en raison de cette sécurité inexistante de
.local
que le RFC demande que les logiciels
n'ajoutent pas automatiquement .local
à un nom
qui soit déjà un FQDN (par exemple
www.example.com
) mais seulement à des noms faits
d'un seul composant.
La section 22.1 revient sur les domaines que Multicast DNS considère comme spéciaux et sur leur usage : si les applications peuvent les traiter à part, elles ne sont pas obligées (Multicast DNS fonctionne donc avec les applications existantes). (Tous les détails sur ces « noms spéciaux » figurent dans le RFC 6761.) Pour que Multicast DNS fonctionne bien, c'est la bibliothèque de résolution de noms (la libc sur Unix) qui doit reconnaitre ces noms comme spéciaux, et les passer à Multicast DNS. D'autres acteurs de l'Internet doivent également veiller à considérer ces noms comme spéciaux : par exemple, un bureau d'enregistrement ne doit pas permettre leur location, un hébergeur DNS ne doit pas permettre de les gérer, etc.
Dans la plupart des RFC, il n'y a pas de justification des choix effectués, et on passe souvent beaucoup de temps à méditer devant la norme en se demandant « pourquoi X et pas Y ? » Ce n'est pas le cas ici, et ce RFC fournit plusieurs annexes (non normatives) détaillant les raisons des différents choix. Une très bonne lecture pour comprendre. Ainsi, l'annexe A explique pourquoi utiliser un port spécifique (5353) et pas le standard 53. Réutiliser l'ancien port aurait permis de ne pas modifier du tout les bibliothèques de résolution de noms mais :
L'annexe B, elle, répond à une question plus rigolote : pourquoi
utiliser une seule adresse Multicast
(ff02::fb
en IPv6) plutôt que de condenser le nom demandé, utilisant le
résultat de cette condensation comme adresse, diminuant ainsi la
charge sur les répondeurs (pas besoin de traiter les paquets qui
arrivent pour d'autres noms que ceux qu'on gère) ? IPv6 fait cela dans le
RFC 4861. Mais cela a des défauts : les machines
ayant beaucoup de noms peuvent avoir besoin de s'inscrire à beaucoup
de groupes multicast, on ne peut plus utiliser
plusieurs questions dans un même paquet si elles portent sur des noms
différents (ou, plus exactement, se condensent en des adresses
différentes), et surtout des tas de fonctions de réduction de trafic
(comme l'écoute du trafic des autres) ne fonctionnent plus.
L'annexe E explique comment NSEC a été choisi pour encoder les
réponses négatives. Le code de retour NXDOMAIN
est global au paquet et ne convient donc pas s'il y avait plusieurs
questions dans une même requête. Une autre possibilité envisagée avait
été d'utiliser des enregistrements dont les données étaient de taille
nulle. Mais, dans certains cas, on peut avoir besoin de tels
enregistrements, sans qu'ils soient interprétés comme une réponse
négative. Il ne restait donc que les enregistrements
NSEC.
Et l'annexe G ? Elle discute des conflits possibles entre des
usages locaux du TLD
.local
et Multicast DNS. Un certain nombre de sites ont
en effet utilisé un pseudo-TLD local pour nommer les machines
internes. .local
semble le nom le plus répandu
mais on en trouve d'autres (.prive
,
.intranet
, .home
, etc). Le RFC note que c'est bien sûr une mauvaise
idée, entre autres parce qu'elle rentre en collision avec
Multicast DNS. Malheureusement, cette annexe a aussi la mauvaise idée de
suggérer d'autres noms possibles, alors qu'ils ont des problèmes
analogues.
L'annexe H décrit la longue histoire de Multicast DNS : depuis la première proposition de faire tourner NBP sur IP, en 1997, aux premières mises en œuvre et au premier Internet-Draft en 2000, jusqu'aux premiers vrais déploiements en 2002.
Finalement, l'IETF a entériné l'existant (processus connu sous le nom peu flatteur de rubber-stamping, allusion aux tampons de l'administration), marquant son mécontentement uniquement par de longs délais.
Aujourd'hui, il existe de très nombreuses mises en œuvre de Multicast DNS. Citons parmi d'autres :
Si vous aimez regardez des pcap, attention
sur pcapr.net, il y a plein de traces
étiquetées mdns
qui n'en sont pas. Mais d'autres
le sont par exemple http://www.pcapr.net/view/tyson.key/2009/8/2/8/WebSense_and_mDNS.pcap.html
ou http://www.pcapr.net/view/tyson.key/2009/9/6/6/Storage_Protocols_2.html
.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : S. Cheshire (Apple), M. Krochmal (Apple)
Chemin des normes
Première rédaction de cet article le 20 février 2013
Parmi tous les noms de domaines
existants, certains sont « spéciaux » au sens où ils ont des
propriétés particulières ou ont été réservés pour un certain
usage. Jusqu'à présent, il n'y avait pas de liste exhaustive de tels
noms, ni de définition stricte, ni surtout de spécification des
conséquences (par exemple, est-ce que les mises en œuvre du
DNS sont censées traiter différemment ces
noms ?) C'est désormais fait avec ce RFC, qui fournit une description
de ces noms « spéciaux » et crée un
registre où ils seront répertoriés. Écrit chez
Apple, il a surtout pour but de permettre
l'enregistrement direct (sans passer par
l'ICANN) du TLD
.local
, utilisé unilatéralement par le protocole Apple
Bonjour. L'utilisation sans vergogne de ce nom
avait en effet suscité bien des critiques.
On peut faire une analogie avec les adresses IP : certaines sont « spéciales » (RFC 6890) et certaines de ces adresses spéciales sont
reconnues par les mises en œuvre d'IP,
qui les traitent d'une manière particulière. C'est par exemple le cas
des adresses multicast comme
224.0.0.0
à 239.255.255.255
(en IPv4), ou comme l'adresse locale
::1
(en IPv6,
cf. RFC 4291). Les noms de domaine ont un concept analogue avec les
noms réservés du RFC 2606 comme
example.org
. Mais le RFC 2606 ne précise pas si un client ou un serveur DNS doit
appliquer un traitement particulier à ces noms. Et il n'est pas
extensible, il ne fournit pas de mécanisme d'enregistrement de noms
supplémentaires. Si on voulait, mettons, ajouter un exemple
IDN, il faudrait une nouvelle version du RFC 2606.
Pour mieux comprendre ce qu'est un nom de domaine « spécial » et ce
que signifie un traitement spécial, reprenons l'exemple des adresses IP. Lorsque le
multicast a été créé par le
RFC 1112, les mises en œuvre
d'IP ont du être modifiées pour reconnaître une
adresse multicast et savoir en faire quelque
chose. Ainsi, une adresse comme 224.0.0.1
(qui
désigne toutes les machines à la fois)
devenait « spéciale » et du code particulier était nécessaire (essayez
de configurer une machine IP avec 224.0.0.1
comme
adresse et vous verrez tout un tas de choses bizarres se produire,
puisque cette adresse est traitée spécialement par la pile IP). Ce
traitement spécial s'applique à toute machine IP, quel que soit le
réseau auquel elle est connectée, et qu'elle utilise le
multicast ou pas.
De la même façon, un nom de domaine va être
spécial lorsqu'on aura besoin d'un traitement particulier de ce nom,
par le logiciel. Le RFC donne l'exemple d'une
norme qui utilise un nom dont on est certain qu'il n'existe pas (il
renvoie toujours NXDOMAIN
, le code de retour pour
« domaine non existent »). On ne peut pas garantir un tel nom avec les
procédures d'enregistrement actuelles. Prenons par exemple
foobar.42, qui n'existe pas aujourd'hui. Même si la
racine n'inclut pas un TLD
.42
, rien ne garantit qu'un résolveur quelque
part ne va pas utiliser une autre racine ou, tout simplement, avoir
une règle spéciale pour le TLD .42
(directives
stub-zone
ou local-zone
dans
Unbound, par exemple).
Si on veut garantir un certain comportement, il ne suffit donc pas de compter sur les règles d'enregistrement, il faut l'indiquer dans le code. (Et cela a l'avantage de couper court à la discussion sur le fait de savoir s'il faut que l'IETF débourse 185 000 $ à l'ICANN lorsqu'elle a besoin d'un TLD spécial.) À l'inverse, si on n'a pas besoin d'un comportement uniforme sur toutes les machines IP, connectées à l'Internet ou pas, alors on n'a pas besoin de ces noms spéciaux.
Bon, d'accord, les noms spéciaux sont cool, j'en veux un, comment je fais ? La section 3 expose les règles d'enregistrement dans la liste des domaines spéciaux. Il faut une norme ou bien une approbation de l'IESG (cf. RFC 5226). À noter que ce n'est pas juste un nom qui est ainsi réservé mais tout un sous-arbre des noms de domaines, commençant par ce nom. La demande de réservation d'un nom spécial doit préciser (section 5 du RFC) :
getaddrinfo
)
doivent traiter ces noms spécialement.example.org
est réservé par les
procédures normales d'enregistrement et que le site Web derrière affirme au
contraire que ce nom ne peut pas être enregistré.Si la réponse à toutes ces sept questions est non (pas de traitement spécial), le RFC note que, dans ce cas, il vaut mieux abandonner l'enregistrement, qui n'a pas de sens.
Pour mieux comprendre les sept questions, voyons leur application
aux domaines spéciaux qui font partie du registre initial. D'abord,
les noms correspondant aux adresses IP privées du RFC 1918, par exemple 23.172.in-addr.arpa
:
Autre exemple, le TLD .test
qui avait été réservé
par le RFC 2606 :
NXDOMAIN
par défaut). Le but est de ne pas
embêter les serveurs racine avec ces noms bidon.
Les TLD .localhost
et
.invalid
sont traités ensuite. Par exemple, pour
.invalid
, le fait de répondre
NXDOMAIN
est demandé (alors que, pour
.test
, ce n'était qu'une possibilité). D'autre
part, pour ces deux TLD, il est recommandé que les bibliothèques de
manipulation de noms de domaine traitent ces noms à part, n'envoyant
pas de requêtes au résolveur DNS.
Quant aux domaines d'exemple du RFC 2606, il
est également demandé qu'ils soient considérés comme spéciaux et ne
génèrent pas de requêtes DNS (et, si c'est le cas, qu'elles reçoivent
immédiatement une réponse négative). Ce n'est pas le cas actuellement
et, comme vu plus haut, vous pouvez visiter http://www.example.org/
.
Voilà, le registre géré par l'IANA est
désormais en
ligne et .local
y a déjà été ajouté (RFC 6762). Le second TLD important qui a été mis dans
ce registre a été le
.onion
dans le RFC 7686, en octobre 2015. Cet enregistrement a fait
des vagues, et mené à des critiques, exprimées dans le RFC 8244.
Date de publication du RFC : Février 2013
Auteur(s) du RFC : Stuart Cheshire (Apple), Marc Krochmal (Apple)
Pour information
Première rédaction de cet article le 20 février 2013
Il y a bien longtemps, à l'époque où même DHCP n'existait pas, et où les seules machines connectées à l'Internet étaient de gros Vax configurés à la main, Apple avait mis au point un ensemble de protocoles concurrents de TCP/IP, la famille AppleTalk. Durant les années suivantes, ces protocoles privés ont été petit à petit remplacé par les normes ouvertes et AppleTalk a quasiment disparu. Mais certains des protocoles de la famille n'ont pas été réellement remplacés et c'est dommage. Parmi eux, NBP, le Name Binding Protocol, qui n'a pas encore d'équivalent standard dans le monde TCP/IP. Que faudrait-il pour le remplacer ? Ce RFC décrit les fonctions souhaitées.
AppleTalk comportait tout un ensemble de protocoles, même si l'insistance des marketroïdes d'Apple à appeler « AppleTalk » le mécanisme physique de connexion LocalTalk a sérieusement brouillé les pistes. Ces protocoles AppleTalk avaient en commun de pouvoir fonctionner sans configuration, dans la configuration dite « bureau du dentiste ». Le dentiste est supposé riche (il a plusieurs ordinateurs) mais n'a pas de compétence en informatique. Il faut donc que tout marche tout seul et NBP jouait un rôle essentiel dans cette auto-configuration.
Cette partie du projet de remplacement d'AppleTalk par IP, concernant l'auto-configuration, a souvent été désignée du nom de « Zeroconf ». Pour développer un équivalent à NBP, il faut le connaître et c'est un des rôles de ce RFC. Un autre rôle est de spécifier plus rigoureusement le remplaçant de NBP. Faire au moins aussi bien était un des buts mais pas le seul. Le protocole dont les propriétés sont décrites dans ce RFC 6760 étend NBP sur plusieurs aspects comme l'internationalisation. AppleTalk utilisait un jeu de caractères privé, Apple Extended ASCII, alors que son successeur se sert évidemment d'Unicode. Un autre changement, moins visible, est que NBP, conçu uniquement pour des LAN était très bavard et que son successeur doit être plus économe des ressources réseau.
Ce RFC 6760 désigne comme successeur de NBP les protocoles Multicast DNS (RFC 6762, notons que le nom est très mauvais puisque ce protocole n'est pas le DNS) et DNS-based service discovery (RFC 6763). Ce sont deux protocoles conçus entièrement par Apple, sans participation de l'IETF, et qu'Apple a essayé pendant des années de faire adopter par l'IETF. Le RFC 6760 n'a donc pas uniquempent un rôle technique mais sert aussi de plaidoyer pro domo d'Apple. Ce RFC 6760 sert donc aussi d'arrière-plan et de justification aux RFC 6761, RFC 6762 et RFC 6763.
Revenons à l'auto-configuration (section 2). Traditionnellement,
tous les protocoles TCP/IP avaient été conçus pour des configurations
manuelles (par exemple dans le fichier
/etc/network/interfaces
sur une
Debian). Cette configuration peut être
centralisée, grâce à DHCP (RFC 2131), qui évite de configurer chaque machine. AppleTalk
permettait au contraire une auto-configuration des ordinateurs du
dentiste, sans qu'aucun administrateur réseaux ne soit
intervenu. Bref, AppleTalk était pair-à-pair
même si Apple, entreprise costard-cravate, n'utilise guère ce
terme, trop connoté « pirate ».
IP dispose désormais de mécanismes d'auto-configuration, comme les adresses lien-local (RFC 4862 et RFC 3927). Il reste donc à auto-configurer le mécanisme de résolution de noms en adresses.
La section 3 donne la liste des exigences pour le nouveau protocole. Elle découle des fonctions qu'assurait NBP. La plus connue et la plus spectaculaire est le choix d'un service réseau via le Chooser (Sélecteur) du Macintosh mais la section 3.1 nous rappelle que ce n'est qu'une extension : le premier service de NBP n'est pas le butinage, c'est la traduction de nom en adresse. À chaque fois que le dentiste veut imprimer, NBP est appelé pour traduire le nom de l'imprimante sélectionnée en une adresse, vers laquelle on va ensuite établir une session, avec le protocole d'impression.
Deuxième point important de NBP (section 3.2), il nomme des services pas des machines. Supposons que le même ordinateur porte un service de fichiers et un service d'impression, le dentiste Michu se moque de savoir si les deux services sont sur la même machine ou pas. Seul l'administrateur réseaux se préoccupe des machines, l'utilisateur pense aux services. Même si on est administrateur réseaux, d'ailleurs, on ne communique pas avec des machines mais avec le logiciel qui tourne sur ces machines. Comme le dit le RFC, « on ne pingue pas une machine, on pingue le logiciel sur cette machine qui met en œuvre le RFC 792 ». Conséquence, les machines n'ont pas de nom dans AppleTalk, seuls les services en ont.
Le RFC rappelle d'ailleurs que le DNS a déjà
cette possibilité de nommer des services et pas des machines. On ne
sait pas si www.example.org
et
ldap.example.org
sont sur la même machine et,
d'ailleurs, on s'en fiche (sauf si on est l'administrateur réseaux en
train de déboguer). Toutefois, cette approche a une limite, c'est que
le DNS ne fournit en échange du nom qu'une adresse IP. Pour se connecter au service, il faut encore un numéro
de port. Parfois, il est bien connu, fixé en
dur dans le protocole (80 pour HTTP). Si on
veut deux services HTTP distincts (par exemple
www.example.org
et
www.makemoney.example
), c'est à l'application de
gérer le démultiplexage (dans le cas de HTTP, avec le champ
Host:
de la requête). Celle-ci double alors un
travail que le noyau sait déjà faire. Et même
ce démultiplexage par l'application ne résout pas tout : par exemple il est difficile de faire
tourner deux serveurs HTTP différents (mettons
Apache et nginx) sur la même machine. Parfois,
le port est indiqué explicitement par l'utilisateur, par exemple
http://www.example.org:8042/
, ce qui n'est pas
pratique et annule une bonne partie de l'intérêt d'avoir un système
d'annuaire. Et puis le nombre de ports est limité (65536) et le fait
d'avoir des ports fixes n'aide pas à la gestion de cette ressource
limitée.
NBP, au contraire (section 3.3) fournissait systématiquement adresse et port en échange d'un nom (le port était nommé socket number). Son remplaçant doit donc garder la même propriété.
Mes lecteurs qui connaissent le DNS, à ce stade, sont déjà devenus
tout rouges en criant « Mais il suffit d'utiliser le RFC 2782 ! » Mais ces enregistrements SRV
ne résolvent pas tout : ils prennent en entrée un nom de domaine alors que, pour un service d'impression, on veut
en plus utiliser d'autres éléments comme le nom de la file d'attente
lpr. (Je suis personnellement sceptique par
rapport à cet argument : si le serveur d'impression a deux files,
library
et secretariat
,
pourquoi ne pas avoir deux noms,
library.printer.example.org
et
secretariat.printer.example.org
, chacun avec son SRV ?)
NBP permettait également de chercher un service par
type et par zone. La syntaxe
complète était Nom:Type@Zone
où les valeurs
pouvaient être remplacées par des signes égal
pour indiquer qu'on recherchait tout (voir section 3.10). Le Type
indiquait le service recherché (par exemple, pour des raisons
historiques, le type LaserWriter
désignait tout
service parlant PostScript au dessus du
protocole PAP, même si ce service n'était pas
une imprimante laser). Quant à la
Zone
, elle fournissait un mécanisme permettant de
répartir les grands réseaux AppleTalk en plusieurs zones dans
lesquelles la recherche se faisait indépendemment. Rappelez-vous que
NBP travaillait par inondation
dans tous les réseaux connectés, et ne passait donc pas à
l'échelle. Dès qu'on avait un ensemble de réseaux plus grand que le
bureau du dentiste, par exemple à l'échelle d'un
campus, il fallait le découper en zones (le
mécanisme de découverte des zones distantes fonctionnait également par
inondation :
AppleTalk était conçu avec une vision étroite des réseaux, limités à
une seule organisation, et n'avait pas tiré les leçons du
développement de l'Internet). Bref, le remplaçant de NBP doit fournir
également un service de partitionnement, qu'on puisse avoir plusieurs
serveurs de fichiers nommés File server. Il doit
également permettre d'informer l'utilisateur de quelle est la zone
courante et quelle est
la liste des zones accessibles (section 3.11).
Et la syntaxe des noms ? La section 3.5 note que des noms qui sont
tapés sur la ligne de commande doivent être
courts et sans fioritures (pas d'espace). Mais
des noms choisis dans une liste ont plutôt intérêt à être longs et
précis. Donc, lp-fred
convient bien à
l'imprimante dans le bureau de Frédérique si on travaille en ligne de
commande, mais « Imprimante couleur de Frédérique » est préférable pour choisir
la bonne imprimante dans une liste de possibilités. Le remplaçant de
NBP doit donc autoriser peu ou prou tous les caractères
Unicode, de préférence encodés en
UTF-8. La section 3.5 rappelle également que
des caractères comme . ou : doivent être autorisés dans les noms.
NBP était conçu pour fonctionner sans aucune configuration et la section 3.6 demande que son successeur en fasse autant, tout en pouvant tirer profit de l'infrastructure existante, s'il en existe une.
Un réseau sans configuration est très sympa, pas d'administrateur réseaux barbu et grognon à supporter, pas de formulaires à remplir, le rêve des utilisateurs : ils sortent le Mac tout neuf de sa boîte, le branchent, le nomment « Mon Macintosh » et c'est parti, sans rien demander à personne. C'est cool, oui, mais ce n'est pas sans risque. Que se passe t-il si Jean-Michel et Frédérique appelent tous les deux leur ordinateur « Mon Macintosh » ? Ou si le fabriquant d'imprimantes Brother livre des imprimantes qui sont toutes pré-configurées avec le nom « Brother Printer » ? La section 3.7 se consacre à la gestion des noms. Le remplaçant de NBP doit donc gérer ces cas. Pour une machine qui a un utilisateur humain juste en face, comme un ordinateur, on peut imaginer un message « Tiens, une autre machine nommée « Mon Mac » vient d'apparaître, voulez-vous changer le nom de la vôtre ? » Pour une machine sans écran et clavier, comme une imprimante, le logiciel doit d'autorité affecter un nouveau nom comme « Brother Printer 2 », l'utilisateur pouvant toujours la renommer ensuite. Attention, cette vérification d'unicité doit se faire en permanence, pas juste au démarrage, car les machines se déplacent et une nouvelle machine risque toujours d'apparaître.
Avec AppleTalk, mais aussi avec des techniques IP comme DHCP ou bien les adresses locales au lien (RFC 4862), une machine n'a pas d'adresse stable. Le logiciel ne doit donc pas, une fois la résolution faite, stocker des adresses. Il ne doit mémoriser que des noms et refaire une requête de résolution avant chaque connexion (section 3.8).
On l'a vu, NBP permet un mécanisme de joker, où le caractère
= remplace n'importe quel nom. Ainsi, la
requête NBP =:LaserWriter@MaZone
signifie
« N'importe quelle imprimante compatible dans
MaZone
». Cela permet d'énumérer toutes les
instances d'un service donné et de présenter une liste à l'utilisateur
humain (section 3.10) et cette possibilité doit donc être gardée.
Autre demande pour l'interface utilisateur : le protocole doit fournir un moyen de présenter à l'humain une liste à jour en permanence (section 3.15). Pas question d'obliger ce dernier à cliquer sur Refresh et à attendre dix secondes l'apparition d'une nouvelle liste. Les nouvelles machines sur le réseau doivent donc pouvoir signaler leur présence tout de suite (sans que chaque machine ne doive interroger les autres en permanence, ce qui chargerait le réseau).
Cela commence à faire pas mal d'exigences mais la section 3.9 ajoute une méta-exigence difficile : que le logiciel soit suffisamment simple pour qu'il puisse être mis en œuvre dans des équipements bas de gamme (par exemple une imprimante à jet d'encre bon marché). Voir aussi la section 3.12 sur les économies d'énergie.
Autre méta-exigence, le protocole qui remplacera NBP doit être relativement stable sur le long terme (section 3.13). Pas question de le faire dépendre d'une mode comme par exemple le format de données structuré du moment (XML, JSON, etc sont sans doute visés, en des termes fort critiques pour l'industrie informatique).
Après une telle liste, on peut se demander s'il est possible de concevoir un protocole qui ait toutes ces qualités. La section 4 explore déjà un protocole existant. Question qui fâche : l'IETF n'a-t-elle pas déjà un protocole qui fait tout cela, SLP (RFC 2608) ? Non, répond le RFC : même s'il fournit bien plus de choses que ne faisait NBP en matière de découverte de services, SLP ne fait pas de détection de conflit, et n'a pas de mécanisme efficace de traduction de nom en adresse, la principale fonction de NBP.
Reste la question de la sécurité (section 6). AppleTalk et NBP n'en offraient aucune. C'est clairement un point où le nouveau protocole ne peut pas se contenter de faire « aussi bien » que NBP et où il doit faire mieux.
(Il avait existé un groupe de travail nommé Zeroconf mais qui n'était pas allé très loin, à part le RFC 3927. Le terme est donc surtout du marketing Apple.)
Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : D. Hardt (Microsoft)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF oauth
Première rédaction de cet article le 13 octobre 2012
Le protocole OAuth a désormais sa seconde version, OAuth 2.0, normalisée dans ce RFC. OAuth permet de à un programme de s'authentifier sur le Web, pour accéder à un jeu limité de services, qu'un utilisateur lui a autorisé.
OAuth est donc 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, le resource owner. (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, Twibbon ou TwitterCounter). 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é : le service doit stocker le mot de passe (le fera-t-il de façon sûre ?), le service peut abuser de son privilège, puisqu'il a tous les droits du propriétaire, le serveur doit gérer l'authentification par mot de passe (pas la meilleure), retirer un droit d'accès à un service veut dire changer le mot de passe, retirant ainsi le droit d'accès à tous les services tiers, etc.
OAuth fournit une meilleure solution : le serveur, en recevant la requête du client, demande au propriétaire l'autorisation : Cette demande se fait typiquement via un formulaire HTML.
Le service tiers reçoit alors un token, une autorisation qui lui est spécifique, et ne lui donne que certains droits. Il présentera ce token au serveur pour obtenir l'accès.
Tout se fait par redirections HTTP (RFC 7231, section 6.4 et ce RFC 6749, section 3). Bien sûr, pour que cela soit sûr, il y a de nombreux détails à prendre en compte.
Si OAuth v1 (RFC 5849) était juste l'officialisaton à l'IETF d'un protocole qui avait été développé à l'extérieur, cette nouvelle version 2 marque des changements profonds, et incompatibles avec l'ancienne version. C'est d'abord une refonte de la norme, d'un seul document à un ensemble dont ce nouveau RFC 6749 n'est que le document de cadrage. Les documents décrivant effectivement le protocole ne sont pour la plupart pas encore parus (il y a par exemple un projet de RFC sur les scénarios d'usage, et un entièrement consacré à la sécurité, via une études des menaces portant sur OAuth). Seuls les RFC 6750, sur un type particulier de token, et RFC 6755 sur des URN pour OAuth, accompagnent ce nouveau OAuth. C'est aussi le passage d'un protocole relativement simple à un ensemble de protocoles, partageant un cadre commun mais n'étant plus forcément interopérables (section 1.8), puisque OAuth v2 permet bien des variantes. C'est complètement contraire aux principes posés dans le RFC 6709, sur les extensions aux protocoles. Donc, attention, un service OAuth v1 ne peut pas interagir avec un serveur OAuth v2 (quand ils existeront) ou le contraire. Les programmeurs OAuth sont encouragés à repartir de zéro, vue la différence des deux protocoles.
Une fois que Twitter a adopté ce protocole (notez que, à la date de publication de ce RFC, Twitter utilise OAuth v1 et n'a pas annoncé d'intention de passer à la v2) et documenté son usage, la plupart des services tiers l'ont intégré (par exemple Twibbon).
Lisons maintenant le RFC. Premièrement, les concepts (section 1) et 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 qu'OAuth v2 a transformé le triangle en carré, en passant à quatre rôles, le serveur ayant été séparé en deux, le serveur qui contrôle l'accès à la ressource convoitée, et celui qui donne les autorisations. En pratique, on ne sait pas encore si des serveurs suivront cette séparation.
Pour voir le cheminement complet d'une authentification OAuth, on
peut regarder la jolie
image de Yahoo (mais attention, elle utilise une 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
).Un guide complet sur OAuth v1 est disponible en http://hueniverse.com/oauth/guide/
. Une autre bonne
introduction à OAuth v1 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 v1 pour accéder à Twitter en
Python figure dans mon article. Mais OAuth v2 ne bénéficie
pas encore de telles documentations.
OAuth v2 a suscité de nombreuses critiques, notamment sur sa complexité. Mon pronostic est qu'OAuth v2, victime du Second System Effect, ne sera guère déployé, la grande majorité des sites Web restant à la v1.
Une bonne critique qui synthétise la plupart des remarques qui ont été faites sur OAuth v2 est « OAuth 2.0 and the Road to Hell ». Eran Hammer, l'auteur, est marqué dans l'annexe C de ce RFC comme ayant participé à OAuth v2 jusqu'à la version 26 du brouillon (la version publiée est la 31). Il a ensuite cessé sa participation au projet et s'en explique dans cet article. Ses principaux arguments :
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews)
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012
Une grande partie de la sécurité d'ILNP, architecture de séparation de l'identificateur et du localisateur, dépend d'un numnique, nombre imprévisible choisi par une machine et transmis à son correspondant au début d'une session. En renvoyant ce nombre, le pair prouve qu'il est bien le même correspondant. Ce RFC décrit les détails de l'option IPv6 Nonce (numnique), utilisée pour ILNP sur IPv6.
ILNP est décrit dans le RFC 6740, avec certains détails pratiques dans le RFC 6741. Comme tous les systèmes à séparation de
l'identificateur et du localisateur, son talon d'Achille est le lien
(binding) entre l'identificateur d'une machine et
son localisateur. Si on reçoit un paquet disant « pour joindre la
machine d'identificateur 3a59:f9ff:fe7d:b647
,
envoie désormais les paquets au localisateur
2001:db8:43a:c19
», faut-il le croire ?
Évidemment, non, pas sur l'Internet public en
tout cas. La solution adoptée par ILNP est d'avoir un
numnique. C'est un nombre généré de manière
imprévisible par un tiers (idéalement, ce devrait être un nombre
aléatoire), que chaque machine envoie au début de la session
ILNP. Lorsqu'un correspondant veut s'authentifier (par exemple
lorsqu'il envoie le message de changement de localisateur cité plus
haut, cf. RFC 6743), il inclura ce
numnique.
Ce numnique sera transporté, aussi bien pour le début de la session que pour les mises à jour de localisateur, dans une option Destination IPv6 (ces options sont décrites dans le RFC 2460, section 4.6). Cette option sert donc à la sécurité d'ILNP. Mais elle a aussi une autre fonction, signaler, lors du débat d'une conversation, qu'on connait ILNP et que le correspondant peut l'utiliser (la coexistence pacifique d'ILNPv6 et d'IPv6 Classic en dépend). Elle ne doit donc apparaître que dans les paquets ILNP.
L'en-tête « options pour la Destination » peut contenir plusieurs options (en pratique, à l'heure actuelle, comme le note notre RFC, il n'est quasiment jamais utilisé), mais il ne doit y avoir qu'une seule option Nonce. Si d'autres options sont quand même présentes (comme celle du RFC 5570), le RFC recommande que Nonce soit la première dans l'en-tête.
La section 2 décrit la syntaxe de cette option. Elle comporte les champs obligatoires, Option Type (0x8b dans le registre IANA), Option length (en octets ; le numnique n'a pas de longueur fixe mais au moins les valeurs de 4 et 12 octets doivent être acceptées par les mises en œuvre de ce RFC) et Nonce (la valeur du numnique, de préférence générée selon les bons principes du RFC 4086).
En l'absence de l'option Nonce dans un paquet entrant, ILNP jettera le paquet si le localisateur source n'est pas dans la liste actuellement connue et stockée dans l'ILCC (Identifier-Locator Communication Cache, cf. RFC 6741). Lorsqu'une machine ILNP change sa liste de localisateurs (section 4), elle envoie un paquet avec la nouvelle liste et ce paquet doit inclure l'option Nonce (avec un numnique correct) pour être accepté. Le RFC recommande également d'inclure cette option dans les paquets suivants, pour une durée d'au moins trois RTT, afin de se prémunir contre un éventuel réordonnancement des paquets. (Notez que cela ne règle que le cas d'un retard du Locator Update, pas le cas de sa perte. Recevoir le paquet avec le numnique correct ne suffit pas à changer les localisateurs mémorisés, ne serait que parce que ce paquet ne contient qu'un seul localisateur et pas la liste actuelle.)
Si vous êtes en train de programmer une mise en œuvre d'ILNP, lisez aussi la section 5, qui donne d'utiles conseils, notamment sur l'ILCC (qui garde en mémoire le numnique actuel de la session, c'est une des informations les plus importantes qu'il stocke).
L'Internet à l'heure actuelle ne contient que des machines IP Classic. Comment cela va t-il se passer pour les premières machines ILNP ? La section 6 décrit la compatibilité. L'option Nonce sert à deux choses, indiquer le numnique, bien sûr, mais aussi signaler qu'ILNP est utilisé. Cette nouvelle option ne doit donc pas être présente dans des paquets IP Classic. Dans les paquets ILNP, elle doit être présente dans les premiers paquets (pour signaler qu'on connait ILNP) et dans tous les messages ICMP générés par les machines ILNP (comme le Locator Update du RFC 6743). Elle peut aussi être mise dans tous les paquets mais ce n'est pas indispensable. Le RFC recommande quand même de le faire si le taux de pertes de paquets de la session est particulièrement élevé (car les paquets portant l'option pourraient être perdus).
Donc, la machine recevant le premier paquet ILNP sait que son
correspondent connait ILNP grâce à l'option Nonce. Et la machine qui
émet le premier paquet ? Comment sait-elle que le pair connait ILNP ?
La principale méthode est, comme toujours dans ILNP, via le
DNS. Comme décrit en détail dans le RFC 6742, la présence d'enregistrements
NID
dans le DNS indique que la machine distante
connait ILNP. Et si l'information dans le DNS est fausse ou dépassée ?
Dans ce cas, vu le type de l'option Nonce (avec
les deux bits de plus fort poids à 10, ce qui indique que le paquet
doit être rejeté si cette option n'est pas comprise, RFC 2460, section 4.2). L'émetteur, en recevant le message ICMP
de rejet (Parameter Problem), saura qu'il ne faut plus essayer en ILNP.
Dans un monde idéal, cela s'arrêterait là. Mais les options de destination comme celle décrite ici sont rares dans l'Internet actuel et il serait bien imprudent de promettre que celle d'ILNP passera sans problème. Comme l'a montré l'expérience d'IPv4, ce qui n'est pas utilisé finit par ne plus être géré correctement, notamment par les équipements intermédiaires. Le RFC ne mentionne pas ce problème mais évoque un problème proche, se contentant de dire que les routeurs IPv6 correctement programmés devraient ignorer tout l'en-tête Destination Options (dans un monde idéal, là encore).
La section 7 revient sur les exigences de sécurité. Le numnique ne doit pas être prévisible par un attaquant extérieur, il est donc recommandé qu'il soit généré selon les règles du RFC 4086. Notez bien que cela ne sert à rien si l'attaquant est situé sur le chemin des paquets et peut les sniffer. C'est également le cas en IP Classic et le seul mécanisme vraiment sûr dans ce cas est IPsec, si on veut protéger jusqu'à la couche 3.
Si vous aimez regarder les paquets qui passent sur le réseau avec wireshark ou tcpdump, désolé, mais ces logiciels ne gèrent pas encore les options spécifiques à ILNP et ne les analyseront pas.
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews)
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012
Le protocole ILNP, décrit dans le RFC 6740, permet de séparer l'identificateur et le localisateur d'une machine. L'identificateur est stable, voire très stable, et identifie une machine, le localisateur est bien plus changeant et identifie un point d'attachement au réseau. Lors d'une communication entre deux machines, si le localisateur change, il faut pouvoir prévenir son correspondant. C'est le rôle des nouveaux messages ICMP Locator Update. Ce RFC 6743 décrit ces messages pour le cas d'IPv6.
Donc, comme déjà expliqué dans les RFC 6740 et RFC 6741, une machine ILNP peut avoir besoin de modifier dynamiquement la liste de ses localisateurs. Par exemple parce qu'elle s'est déplacée. Ou, tout simplement, parce qu'un nouvel attachement au réseau est disponible (nouveau FAI, par exemple).
Cela se fait avec des paquets ICMP envoyés au(x) correspondant(s). Ces paquets ont le type 156 et ne sont utilisés que pour ILNPv6 (ILNP sur IPv6 ; leur équivalent IPv4 est dans le RFC 6745). Le type 156 a été enregistré à l'IANA.
Leur syntaxe est décrite en section 2. Les champs les plus importants :
L64
,
cf. RFC 6742).Lorsqu'une liste de localisateurs change pour un nœud (ajout ou retrait d'un localisateur), le nœud envoie ce message à tous ses correspondants (tous les nœuds avec lesquels il est en train de communiquer). Ceux-ci enverront un accusé de réception (même contenu, seul le champ Operation changera). Le RFC ne spécifie pas quoi faire si on ne reçoit pas d'accusé de réception (les messages ICMP peuvent se perdre). C'est volontaire : le manque d'expérience pratique avec ILNP ne permet pas encore de recommander une stratégie de rattrapage particulière (réemettre, comme avec le DNS ?)
Notez que c'est une liste complète de tous les localisateurs qui est envoyée. Elle peut donc être grosse, programmeurs, attention aux débordements de tampon si Num of locs vaut sa valeur maximale, 256.
Le message Locator Update doit être authentifié (section 6) en incluant, pour chaque correspondant, l'option IPv6 Nonce (RFC 6744) avec la valeur en service pour ce correspondant. Les messages seront ignorés si le numnique (valeur choisie de manière à être imprévisible par l'attaquant) est incorrect. (Dans les environnements où on souhaite encore plus de sécurité, on peut ajouter IPsec.)
Et comment se passera la cohabitation avec les machines IPv6 classiques ? La section 5 traite ce cas. Comme le type ICMP 156 est inconnu des machines IPv6 classiques, elles ignoreront ces messages Locator Update (RFC 4443, section 2.4).
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews), Scott Rose (US NIST)
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012
Le système ILNP, qui vise à fournir une nouvelle (et meilleure) architecture à l'Internet, dépend du DNS pour plusieurs fonctions critiques. Plusieurs nouveaux types d'enregistrement DNS sont nécessaires et ce RFC les décrit.
Avant de lire ce RFC, il faut connaître ILNP. Le mieux est de commencer par le RFC 6740, qui décrit tout le système. Le RFC 6741 fournit ensuite quelques détails pratiques. Il faut aussi naturellement connaître les bases du DNS (RFC 1034 et RFC 1035).
C'est fait ? Vous avez lu tout cela ? Alors, place à ce nouveau RFC, le RFC 6742. ILNP utilise le DNS essentiellement pour permettre un rendez-vous entre deux machines. Celle qui veut commencer connaît le nom de l'autre mais aucune information pratique sur comment la rencontrer. Quatre types d'enregistrements sont utilisés pour cela :
NID
qui permet de trouver
l'identificateur d'une machine à partir de son
nom,L64
et L32
qui
permettent de trouver le localisateur d'une
machine à partir de son nom,LP
, une optimisation facultative qui
sera présentée plus loin.Commençons par le NID
. Un de ses rôles est
d'indiquer à la machine qui veut en contacter une autre si sa future
correspondante connait ILNP (ou bien si elle est uniquement en IP
Classic). Sa présence dans le DNS est donc un signal : « tu peux y
aller, elle parle ILNP ». Un enregistrement erroné (disant qu'une
machine a un NID
alors qu'en fait elle ne parle
pas ILNP) n'est pas fatal mais ralentirait sérieusement
l'établissement de la connexion.
Le NID
a reçu le numéro 104 (cf. le registre IANA) et il comporte deux champs, une
préférence et l'identificateur. Attention, ce sont les préférences les
plus faibles qui sont celles à choisir en premier. Par exemple, voici
trois NID
pour
host1.example.com
:
host1.example.com. IN NID 10 0014:4fff:ff20:ee64 IN NID 20 0015:5fff:ff21:ee65 IN NID 50 0016:6fff:ff22:ee66
L'identificateur 0014:4fff:ff20:ee64
est le
préféré. (La syntaxe des identificateurs et des localisateurs est
décrite dans le RFC 6740.)
Si un serveur DNS « connaît ILNP »,
c'est-à-dire qu'il a été programmé avec du code spécifique pour ILNP,
au lieu d'attribuer aux enregistrements ILNP le traitement par défaut,
il peut
optimiser, par exemple en envoyant des enregistrements non demandées
mais qui seront probablement utiles. Cette optimisation, qui
n'a rien d'obligatoire, est analogue à ce que font les
serveurs actuels pour une requête MX : si la
réponse est mail.example.com
, ils incluent
également les adresses IP de
mail.example.com
dans la réponse, conscients
qu'elles seront probablement nécessaires bientôt (si on demande le MX
de example.com
, c'est en général pour lui envoyer
du courrier juste après). Ici, un serveur
« connaissant ILNP » à qui on demande le NID
de
host1.example.com
peut aussi mettre dans le
réponse des L64
et des L32
,
non demandés mais qui seront probablement utiles juste après.
Le type L64
stocke des localisateurs pour
ILNPv6, c'est_à-dire ILNP tournant sur
IPv6. La présence de L64
dans le DNS indique que la
machine peut faire de l'ILNP au-dessus d'IPv6. Pour ce protocole, les
localisateurs font 64 bits, d'où le nom de ce type. Son numéro est
106. Lui aussi a une préférence, suivie par le localisateur proprement
dit.
Voici un exemple où la machine
host1.example.com
a deux localisateurs, avec une préférence pour
2001:0db8:1140:1000
:
host1.example.com. IN L64 10 2001:0db8:1140:1000 IN L64 20 2001:0db8:2140:2000
Rappelez-vous que les localisateurs d'ILNPv6 ont une syntaxe qui ressemble à celle des adresses IPv6 mais il s'agit bien d'un type différent.
Quant au type L32
, il stocke des localisateurs pour
ILNPv4, c'est-à-dire l'incarnation d'ILNP pour
IPv4. Leur présence dans le DNS indique que la
machine peut faire de l'ILNP au-dessus d'IPv4. Pour ce protocole, les
localisateurs font 32 bits, d'où le nom de ce type. Son numéro est
105. Il comprend une préférence, puis le localisateur proprement
dit.
Voici un exemple où la machine
host1.example.com
a trois localisateurs,
10.1.2.0
étant le préféré (la machine est sans
doute multi-homée) :
host1.example.com. IN L32 10 10.1.2.0 IN L32 20 10.1.4.0 IN L32 30 10.1.8.0
Le dernier type d'enregistrement DNS, LP
, est
un peu différent. Il s'agit de fournir un niveau
d'indirection. En effet, si une machine change
de localisateurs (ce qui est normal, en ILNP), et veut pouvoir être
jointe, la méthode est de mettre à jour le DNS. Or, la zone où est
déclarée la machine peut ne pas être facilement accessible en écriture
(RFC 2136 ou méthode équivalente). L'idée (voir
RFC 6740) est
donc de pointer, via un enregistrement LP
, vers
une zone prévue pour les mises à jour rapides, où se trouveront les
localisateurs.
L'enregistrement LP a le numéro 107 et comprend une préférence et
un FQDN. Ce FQDN aura à son tour des
L32
ou des L64
. Voici un
exemple :
host1.example.com. IN LP 10 subnet1.dynamic.example.net. IN LP 20 subnet3.backup.example.com. ; Puis, dans la zone dynamic.example.net : subnet1.dynamic.example.net. IN L64 50 2001:0db8:1140:1000 IN L64 100 2001:0db8:2140:2000
Avec cet exemple, si host1.example.com
change de
localisateur, on ne touche pas à la zone
example.com
, on ne modifie que
dynamic.example.net
. Cette indirection via les
LP
n'est pas indispensable mais elle aidera dans
bien des cas, lorsque la zone « principale » ne permettra pas les
mises à jour rapides. Autre avantage, toutes les machines d'un même
sous-réseau ayant le même localisateur, leurs noms pourront pointer vers
le même LP
et une seule mise à jour suffira pour
tout le monde.
La section 3 synthétise ensuite l'usage de ces types
d'enregistrement. Le minimum pour une machine ILNP est un
NID
+ un L64
(ou
L32
en ILNPv4) :
host1.example.com. IN NID 10 0014:4fff:ff20:ee64 IN L64 10 2001:0db8:1140:1000
Si la machine est
multi-homée, on aura
plusieurs L64
:
host1.example.com. IN NID 10 0014:4fff:ff20:ee64 IN L64 10 2001:0db8:1140:1000 IN L64 20 2001:0db8:2140:2000
Si la machine est mobile, elle aura souvent intérêt à utiliser les
LP
et cela donnera quelque chose du genre :
host1.example.com. IN NID 10 0014:4fff:ff20:ee64 IN LP 10 mobile-1.example.net. ; ... mobile-1.example.net. IN L64 2001:0db8:8140:8000
Rappelons que ces enregistrements ne doivent apparaître que si la machine parle ILNP. Un de leurs rôles est de signaler qu'ILNP est disponible.
Un client ILNP qui veut récupérer ces informations ne doit pas
compter qu'elles soient toutes envoyées d'un coup (même si c'est une
optimisation recommandée). Au passage, rappelez-vous que la requête
ANY
, envoyée à un résolveur, n'a pas forcément la
sémantique attendue (elle renvoie ce que le résolveur a dans son
cache, pas forcément toutes les données disponibles sur les serveurs
faisant autorité). D'autre part, même si la réponse du serveur faisant
autorité incluait tous les enregistrements, certains résolveurs
peuvent, pour des raisons de sécurité, en jeter certains. Enfin, même
si les données sont gardées dans le cache, elles expirent au bout d'un
moment et les TTL ne sont pas forcément les
mêmes pour tous les types d'enregistrement. Le client ILNP doit donc se préparer à faire
plusieurs requêtes, par exemple NID
(s'il n'y a
pas de résultat, la machine distante ne parle pas ILNP) puis
LP
(qui est facultatif), puis
L64
puis enfin, s'il n'y a pas de
L64
, se résigner à L32
.
À propos des TTL, notez qu'il est logique que les TTL soient assez
longs pour les NID
(une information normalement
très stable, je dirais que plusieurs jours ne sont pas un
problème). En revanche, les L32
et
L64
peuvent avoir des TTL bien plus courts (le
RFC ne donne pas de chiffre mais, disons, moins d'une minute), surtout
si la machine ou le réseau est mobile. On peut alors s'inquiéter
« est-ce que ces courts TTL, empêchant une mise en cache sérieuse, ne
vont pas augmenter excessivement la charge sur le système DNS, et
ralentir les requêtes ? ». Mais plusieurs articles (« Reducing DNS Caching », « DNS performance and the effectiveness of caching ») ont montré que les
caches du DNS étaient surtout rentables pour l'information
d'infrastructure (enregistrements
NS
et
colle). Pour les enregistrements « terminaux »
comme les adresses IP ou les localisateurs, les caches sont moins nécessaires.
Un petit mot sur la sécurité, maintenant. Comme les informations
nécessaires sont vraiment critiques (un L64
erroné et tout le trafic va à une autre machine), la section 4
recommande d'utiliser DNSSEC (RFC 4033) pour protéger ses
informations. (À l'été 2012, le déploiement de DNSSEC est très avancé,
alors que celui d'ILNP est inexistant. Il est donc raisonnable de
compter que DNSSEC sera disponible.) Lors des mises à jour dynamiques,
il faut utiliser les sécurités décrites dans le RFC 3007. Par exemple, avec le serveur de noms
Yadifa, on peut mettre à jour dynamiquement
une zone signée. On copie la clé privée (par exemple, pour une clé
générée avec dnssec-keygen
pour la zone
secure.example
, le fichier de la clé privée peut
être Ksecure.example.+005+05461.private
) dans le
répertoire indiqué par la directive keyspath
de
Yadifa et c'est tout. Les mises à jour dynamiques seront faites et
automatiquement signées. Le journal de Yadifa dira :
2012-09-25 20:54:12.754705 | server | I | update (831e) secure.example. SOA (127.0.0.1:44480) 2012-09-25 20:54:12.754749 | server | D | database: update: checking DNSKEY availability 2012-09-25 20:54:12.754778 | server | D | database: update: processing 0 prerequisites 2012-09-25 20:54:12.754791 | server | D | database: update: dryrun of 2 updates 2012-09-25 20:54:12.754828 | server | D | database: update: opening journal page 2012-09-25 20:54:12.755008 | server | D | database: update: run of 2 updates 2012-09-25 20:54:13.000526 | server | D | database: update: closed journal page
À la date de publication de ce RFC, il n'existe pas encore de logiciel DNS qui gère ILNP.
Pour finir, quelques articles sur l'idée d'utiliser le DNS pour localiser une machine mobile : « An End-To-End Approach To Host Mobility », « Reconsidering Internet Mobility » et « Mobile Host Location Tracking through DNS ».
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews)
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012
Le RFC 6740 décrivait l'architecture générale du mécanisme de séparation de l'identificateur et du localisateur ILNP. C'était le premier document à lire pour comprendre ILNP. Ce RFC 6741 est plus concret, exposant les questions d'ingéniérie autour d'ILNP. Il décrit surtout des points qui sont indépendants de la version d'IP utilisée, d'autres RFC couvrent les points spécifiques à IPv4 (RFC 6745 et RFC 6746) ou IPv6 (RFC 6743 et RFC 6744).
Donc, ILNP vise à fournir une meilleure architecture à l'Internet, en faisant évoluer IP vers une séparation de l'identificateur d'une machine (stable, indépendant de comment et par qui la machine est attachée au réseau) avec le localisateur (lié à l'attachement actuel au réseau, et pouvant donc changer). ILNP est décrit dans le RFC 6740 mais celui-ci ne donne qu'une vision de haut niveau, à laquelle manquent pas mal de détails. C'est le rôle de notre RFC que de combler ces manques. L'architecture ILNP peut avoir bien des incarnations concrètes, y compris par des approches « table rase » où on ne tient aucun compte de l'existant. Ce RFC 6741 présente une autre approche, plus progressive, où on essaie de déployer ILNP dans l'Internet actuel.
Vous avez bien lu le RFC 6740 d'architecture d'ILNP ou son résumé ? Alors, allons-y, plongeons nous dans les détails ILNP. D'abord, les identificateurs (section 2). Toute machine ILNP en a au moins un. Ils ne sont pas liés à une interface réseau et une machine avec N interfaces peut très bien n'avoir qu'un seul identificateur. (Notez toutefois qu'un identificateur peut être formé à partir d'une caractéristique d'une interface, comme l'adresse MAC. Mais ce n'est qu'un mécanisme de génération de l'identificateur, la carte réseau peut ensuite être changée sans affecter celui-ci.)
Les identificateurs sont des chaînes de 64 bits et la
représentation la plus simple est donc un entier non signé de 64 bits
(uint64_t
dans un programme en
C, par exemple). Comme les identificateurs
d'interface d'IPv6 (section 2.5.1 du RFC 4291),
ils utilisent la syntaxe EUI-64. Cette
syntaxe décrit notamment deux bits, U et G, le premier indiquant si
l'identificateur est globalement unique ou non, et le second indiquant
s'il s'agit d'une adresse de groupe. Attention pour les programmeurs,
rien n'empêche une machine de prendre l'identificateur qu'elle veut
et, en pratique, des collisions peuvent se produire. À plusieurs
reprises, notre RFC donne des conseils à ceux qui mettent en
œuvre ILNP pour que ces collisions n'aient pas de conséquences
graves.
Si le bit U est à 1, cela indique que l'identificateur dérive de l'adresse MAC, et est donc garanti unique via l'enregistrement à l'IEEE.
Si le bit U est à 0, cela veut dire que l'identificateur n'est pas dérivé d'un registre central et n'a donc qu'une signification locale. Cela permet à ILNP de se passer d'une dépendance vis-à-vis d'une autorité unique. Autre intérêt, on peut alors générer un identificateur qui soit une clé cryptographique, par exemple (RFC 3972). On peut aussi avoir des identificateurs temporaires, pour préserver la vie privée, comme on le fait en IPv6 avec les adresses temporaires du RFC 8981.
Normalement, ce RFC n'était censé couvrir que les points indépendants de la famille d'adresses utilisée. Néanmoins, on y trouve aussi l'encodage des localisateurs et identificateurs dans un paquet IP (section 3). En IPv6, dans les champs « adresse IP » (source et destination), le localisateur prend les 64 bits de plus fort poids, et l'identificateur le reste. Grâce à cet encodage, le routeur IPv6, qui ne tient compte que du préfixe, traitera le localisateur comme un préfixe IP normal et n'aura besoin d'aucune modification pour gérer de l'ILNP. Le format du paquet ILNPv6 est en effet exactement le même que celui du paquet IPv6 classique.
C'est plus complexe en IPv4, en raison de la petite taille des champs adresse. On met donc les localisateurs dans l'adresse (source et destination), afin que les routeurs IPv4 puissent travailler comme aujourd'hui, et l'identificateur (qui fait toujours 64 bits) doit être mis dans une option IP, comme décrit dans le RFC 6746.
Et au niveau 4 (transport), qu'est-ce qui doit changer ? La principale modification est que TCP ou UDP doivent lier l'état d'une session en cours uniquement à l'identificateur et non plus à une adresse. Ainsi, le tuple traditionnel de TCP {adresse IP locale, port local, adresse IP distante, port distant}, qui identifie une connexion en cours, doit être remplacé par {identificateur local, port local, identificateur distant, port distant}, afin de bénéficier d'ILNP (notamment de la possiblité de changer d'adresse sans casser la connexion).
Attention, TCP doit normalement remplir le champ « somme de contrôle » (Checksum dans l'en-tête TCP) en incluant les deux adresses IP, locale et distante. En ILNP, il ne doit plus utiliser que les identificateurs, les localisateurs étant remplacés, pour le calcul de la somme de contrôle, par une série de bits nuls.
Un aspect d'ingéniérie très important d'ILNP est
l'ILCC, Identifier-Locator Communication
Cache. Cette structure de données, décrite en section 5,
garde trace des détails permettant de maintenir une communication avec
les CN (Correspondent Node, les machines ILNP avec
qui on parle). De tels caches existent déjà pour certains protocoles
(par exemple pour ARP, sur une machine
Unix, vous pouvez l'afficher avec la commande
arp -a -n
, pour NDP, sur
Linux, avec ip -6 neighbour
show
). Et ceci sans parler des informations que doit garder
TCP. Donc, le nouvel ILCC n'est pas forcément une grosse contrainte
pour les machines.
Que stocke l'ILCC ?
La validité peut être déterminée par divers moyens. Lorsque l'information a été apprise dans le DNS, c'est typiquement le TTL qui est utilisé. Toutefois, même lorsque le TTL expire, ce n'est pas une bonne idée de retirer les valeurs immédiatement (on risque de se couper d'un CN qui n'a pas mis à jour ses données assez vite). Il vaut donc mieux marquer un Localisateur comme « pas à jour mais peut-être encore utilisable si on n'a pas le choix ».
Et pour accéder à l'ILCC, quelle clé de recherche utilise-t-on ? L'identificateur, ce qui serait logique ? Raté. Pour les paquets qui contiennent un numnique, on utilise un tuple {Identificateur, Numnique} et pour les autres un tuple {Identificateur, Localisateur}. Le but de ce choix est de se prémunir contre les cas où deux machines utiliseraient le même identificateur (ce qui peut arriver, surtout avec le bit U à zéro).
On a vu qu'un des buts d'ILNP était de gérer proprement les cas où une machine change de connectivité (panne d'un lien, déplacement, etc). La section 6 explique les détails de ce cas. Lorsqu'une machine apprend qu'un de ses localisateurs ne marche plus, elle prévient ses CN (Correspondent Node) par un message ICMP Locator Update (RFC 6743 et RFC 6745). Ce message permet de retirer ou d'ajouter des localisateurs. Il est authentifié par le numnique, qui doit être identique à celui d'une session en cours (sinon, le paquet entrant ne correspond à aucune entrée dans l'ILCC, voir la section précédente).
Ça, c'est pour les sessions en cours. Pour les nouvelles, si une machine veut être contactée, elle doit mettre à jour la liste de ses localisateurs dans le DNS. ILNP dépend donc assez fortement des mises à jour dynamiques du DNS (RFC 2136 et RFC 3007), ou d'un mécanisme similaire.
Le lecteur attentif a pu remarquer plus tôt que le localisateur joue le rôle d'un préfixe IP, le routage est fondé sur lui. Mais un préfixe IP n'a pas forcément une longueur fixe. En IPv6, on peut parfaitement avoir un Tier 1 qui annonce un /32 en BGP, qui route ensuite dans son IGP des /48 et finalement un réseau local d'un client de l'opérateur qui route sur des /64. ILNP ne change rien à cela (section 7). Le localisateur comprend en fait deux parties, de longueur variable, un préfixe de localisateur et un sélecteur de réseau. Dans le cas de l'annonce BGP citée plus haut, les 64 bits du localisateur se partagent entre 32 bits de préfixe et 32 bits pour choisir un réseau.
On a vu qu'ILNP dépend énormément du DNS. Il est donc logique que ce RFC compte une une section 8 consacrée à ce service. D'abord, comme on l'a vu, pour des raisons de sécurité, ILNP recommande fortement de sécuriser les mises à jour du DNS (RFC 3007). Cette technique marche dans de nombreuses mises en œuvre du DNS (par exemple, BIND ou Active Directory l'ont depuis des années). Les clients capables d'utiliser TSIG ou une technique similaire pour mettre à jour un serveur DNS sont disponibles pour toutes les plate-formes (comme nsupdate sur Unix). Un exemple figure dans mon article sur le RFC 6742.
Pour accéder à l'information disponible, quatre nouveaux types d'enregistrement DNS sont créés par le RFC 6742 :
NID
pour stocker l'identificateur,L32
et L64
pour
stocker des localisateurs de 32 (pour IPv4) et 64 bits,LP
, pour ajouter un niveau d'indirection
vers le localisateur, apportant ainsi davantage de souplesse pour les
changements (qui peuvent être fréquents) des localisateurs, qui
peuvent être délégués à une autre zone.Quels TTL utiliser pour ces enregistrements ?
Le choix est particulièrement important pour les localisateurs, qui
peuvent parfois changer vite. Dans certains cas, un TTL de quelques secondes seulement
peut donc être une valeur raisonnable pour les
L32
et L64
. Si cela vous
semble peu, rappelez-vous que des études comme celle de Alex C. Snoeren, Hari Balakrishnan, & M. Frans Kaashoek, « Reconsidering Internet Mobility » (dans Proceedings of 8th Workshop on Hot Topics in Operating Systems en 2002) ou celle de S. Bhatti & R. Atkinson, « Reducing DNS Caching » (dans Proc. GI2011 - 14th IEEE Global Internet Symposium en 2011) ont montré qur le cache dans
le DNS est surtout utile pour les enregistrements
d'infrastructure (type NS
et colles, c'est-à-dire adresses IP des serveurs situés dans la zone qu'ils servent), pas pour les enregistrements « terminaux » comme
AAAA
ou MX
.
Les enregistrements LP
et
NID
sont bien plus stables et peuvent, eux, avoir
des TTL de plusieurs jours. Dans le cas d'identificateurs temporaires
et/ou cryptographiquement signés, un TTL plus court est toutefois à envisager.
À noter que le RFC recommande que les machines ILNP publient dans
le DNS, non seulement les NID
et
L64
spécifiques d'ILNP mais aussi des plus
traditionnels AAAA
pour les machines non-ILNP. Un
serveur DNS qui connait ILNP peut également envoyer d'autorité les NID
et
L64
dans la section additionnelle de la réponse
DNS. Les machines non-ILNP ignoreront ces enregistrements inconnus mais les autres pourront en
tirer profit.
L'expérience (douloureuse) d'IPv6 a montré que la possibilité d'un déploiement progressif, n'exigeant pas de tout le monde qu'il migre, était un élément nécessaire de tout nouveau protocole réseau. La section 10 de notre RFC regarde donc de près si ILNP est déployable progressivement. D'abord, les paquets ILNP, que ce soit ILNPv4 ou ILNPv6 sont indistinguables, pour les routeurs, les pare-feux et autres équipements, de paquets IPv4 et IPv6 classiques. Ils devraient donc passer sans problème sur ces équipements, sans qu'on change leurs configurations, leurs protocoles de routage, etc. ILNP, comme HIP, peut en effet être déployé uniquement sur les machines terminales, par une simple mise à jour logicielle. Pour la même raison, des machines ILNP peuvent coexister avec des machines IP Classic sur un même lien.
Je trouve que le RFC est trop optimiste : l'expérience montre que les options IP, nécessaires à ILNP, passent mal dans l'Internet IPv4 actuel et n'ont guère été testées en IPv6 (le RFC ne mentionne que le cas des pare-feux qui bloqueraient explicitement les options et pas celui de routeurs bogués). De toute façon, une exception est à prévoir, en ILNPv4 uniquement, les routeurs du réseau local devront être mis à jour pour gérer une extension d'ARP. Autre exception, certains routeurs NAT, selon la façon dont ils sont réglés, peuvent casser ILNP en réécrivant ce qu'ils croient être une adresse et qui serait un bout de l'identificateur.
Pour les applications, c'est plus compliqué. Si l'application est « bien élevée » (n'utilise que des noms de domaine, ne manipule pas explicitement d'adresses IP), elle devrait fonctionner en ILNP sans problème. Mais bien des applications ne sont pas bien élevées (FTP, SNMP...)
La section 14, consacrée aux applications et API revient en détail sur ces questions. D'abord, une bonne partie des applications existantes, notamment parmi celles écrites en C, utilise l'API dite BSD Sockets. Elle n'est pas forcément incompatible avec ILNP. Par exemple, les applications IPv6 peuvent mettre la concaténation du localisateur et de l'identificateur dans les champs de l'API prévus pour mettre une adresse IP et cela passera, puisque c'est justement l'encodage du couple {Identificateur, Localisateur} sur le câble. Néanmoins, cette API est de trop bas niveau, même sans tenir compte d'ILNP (par exemple, elle oblige à avoir un portage d'IPv4 en IPv6 alors que cette modification dans la couche 3 devrait être invisible des applications). Souhaitons donc (et pas seulement pour ILNP) que les programmeurs passent à des API plus abstraites.
Tout le monde ne programme pas en C. Pour les autres langages, il
est courant d'utiliser des API de plus haut niveau que ces
sockets. Ainsi, en Java, les
clients Web vont plutôt faire appel à la classe
java.net.URL
. Ainsi, complètement isolés des
couches basses, ils passeront à ILNP sans s'en rendre compte. Même
chose pour des langages comme Ruby ou Python.
Le piège classique des API réseau est l'utilisation de références, lorsqu'Alice dit à Bob « va voir Charlie ». Ces références cassent pas mal de protocoles. Une solution pour ILNP serait de faire des références avec des FQDN.
Et pour communiquer entre machines ILNP et non-ILNP ? Le RFC recommande que les
machines ILNP gardent également l'IP Classic, approche connue sous le
nom de dual stack (être capable de parler les deux
protocoles). Une longue coexistence d'ILNP avec des machines IP est
prévue. Pour la machine qui initie la connexion, si elle trouve
un NID
dans le DNS, elle tente ILNP (en mettant
l'option Nonce/numnique), sinon elle
reste en IP Classic. Si la machine distante ne gère pas ILNP (malgré
ce que raconte le DNS), elle rejettera l'option Nonce avec un message
ICMP (l'option a un type qui indique que le paquet doit être rejeté
par ceux qui ne comprennent pas l'option, cf. RFC 2460, sections 4.2 et 4.5), qui permettra à l'initiateur de voir qu'il s'est trompé et doit
réessayer en IP traditionnel.
Pour la machine qui répond aux demandes de connexion, si le paquet initial contient une option Nonce, c'est que le demandeur gère ILNP. Sinon, on s'en tient à l'IP de nos grand-mères.
Question sécurité, la section 9 est consacrée à IPsec. Il n'est pas très différent avec ILNP de ce qu'il est avec IP Classic. Le principal changement est que les associations de sécurité se font avec l'identificateur, pas avec l'adresse (elles ne changent donc pas si une machine change de localisateur). Ainsi, AH ne valide que l'identificateur (le localisateur n'est pas protégé, ce qui permet à ILNP+AH de fonctionner même en présence de NAT).
Autres questions de sécurité en section 11 : les auteurs estiment qu'ILNP n'est pas moins sûr qu'IP. Il ne l'est pas non plus forcément davantage. Un exemple typique est qu'une machine peut mentir sur son identificateur, comme elle peut mentir sur son adresse IP (les solutions sont également les mêmes, IPsec + IKE ou bien les CGA du RFC 3972).
Le principal risque nouveau est celui de faux messages ICMP Locator Update. Ils pourraient provoquer bien des dégâts, par exemple en convaincant un CN d'envoyer tous les paquets d'une machine à un attaquant. C'est pour cela que l'option Nonce est absolument indispensable, même lorsque IPsec est utilisé. À noter que cette option ne protège pas contre un attaquant situé sur le chemin, puisque ce dernier peut alors écouter le réseau et lire le numnique (la situation est exactement la même en IP Classic, par exemple avec les numéros de séquence TCP, qui ne protègent que contre les attaquants hors du chemin). On est donc bien dans un cas « sécurité pas pire qu'avec IP Classic (mais pas meilleure non plus) ». Si on veut aller plus loin en sécurité, il faut IPsec ou un équivalent.
À noter aussi que les autres messages ICMP (Packet too big, Destination unreachable, etc), ne sont pas protégés par le numnique. Ces messages sont en général émis par des équipements intermédiaires, genre routeurs, qui ne connaissent normalement pas le numnique. Comme en IP Classic, ils peuvent donc parfaitement être usurpés (cf. RFC 5927).
La sécurité inclus aussi le respect de la vie privée (section 12). Notre RFC renvoie au RFC 6740 qui discutait cette question dans le cadre d'ILNP.
Enfin, la section 13 contient diverses notes sur des problèmes pratiques. Notamment :
L64
dans le DNS peut
être erroné et rien ne l'indique au client ILNP. Comme
en IP Classic, on n'est jamais sûr qu'un paquet arrivera et les
logiciels doivent en tenir compte.Comme il n'y a pas encore eu de déploiement, même limité, même de test, d'ILNP, nul doute que la liste des problèmes et questions s'allongera lorsqu'on passera à l'expérience sur le terrain.
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews)
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012
Le protocole ILNP vient d'être spécifié dans une série de neuf RFC, dont ce RFC 6740 est le point de départ, décrivant l'architecture générale d'ILNP. ILNP appartient à la famille des protocoles à séparation de l'identificateur et du localisateur. Ces protocoles visent à résoudre une limite fondamentale de l'Internet : l'adresse IP est utilisée à la fois comme identificateur (nommer une machine, par exemple pendant la durée d'une session TCP) et comme localisateur (indiquer son point d'attachement au réseau). Cette confusion rend certaines configurations, notamment le multi-homing et la mobilité, très difficiles.
Ce n'est pas qu'ILNP soit le premier protocole à vouloir séparer ces deux fonctions. Avant de donner le feu vert à la publication de ces RFC, l'IESG a notamment examiné HIP et LISP, avant de conclure qu'ILNP avait des caractéristiques suffisamment originales pour qu'il soit intéressant qu'il soit décrit dans des RFC.
ILNP avait été choisi par les présidents du groupe de recherche Routage de l'IRTF comme étant la base des futurs travaux sur une meilleure architecture pour l'Internet (travaux décrits dans le RFC 6115). S'il faut le résumer en cinq points :
Bon, après cette introduction rapide, voyons tout en détail. D'abord, pourquoi veut-on à tout prix séparer identificateur et localisateur ? Le mieux est de relire le RFC 4984 pour avoir tous les détails. Disons que l'actuelle confusion de l'identificateur et du localisateur est pénible pour :
Face à ces problèmes, des tas de propositions pour améliorer les mécanismes d'adressage et de nommage dans l'Internet ont été faites : RFC 814, RFC 1498, RFC 2101, RFC 2956 et bien d'autres. La conclusion était souvent la même : le mélange de fonctions d'identification d'une machine et de sa localisation dans le réseau est une mauvaise idée. Ces fonctions devraient être séparées.
Il y a un petit problème terminologique ici : les architectures où ces fonctions sont séparées sont parfois toutes appelées « séparation de l'identificateur et du localisateur ». Mais notre RFC adopte un vocabulaire plus strict. Il réserve ce terme de « séparation de l'identificateur et du localisateur » aux architectures (comme ILNP) où la séparation est faite dès le début (dans les machines terminales) et utilise le terme de « map and encapsulate » (qu'on trouve souvent abrégé en map-and-encap) aux architectures qui utilisent un tunnel pour transporter les paquets entre deux machines ne connaissant pas la séparation Identificateur/Localisateur. Selon cette terminologie, LISP, dont le nom veut dire Locator/Identifier Separation Protocol, n'est donc pas un « vrai » système « à séparation de l'identificateur et du localisateur ».
Ce RFC, le premier à lire lorsqu'on veut comprendre ILNP, est d'abord la description d'une architecture. On n'y trouvera pas de protocole, de format des paquets, etc. Les protocoles concrets viennent après, dans d'autres RFC. Deux protocoles qui mettent en œuvre l'architecture ILNP ont été définis, ILNPv4 pour IPv4 et ILNPv6 pour IPv6. Je parlerai surtout d'ILNPv6, qui est plus simple à exposer (le faible espace d'adressage d'IPv4 a nécessité quelques astuces qui rendent ILNPv4 plus difficile à comprendre).
Comme indiqué plus haut, d'autres incarnations de l'architecture ILNP peuvent être imaginées, notamment en choisissant une approche « table rase » qui ferait tourner cette architecture sur un nouveau protocole, sans relation avec IP. Mais, pour l'instant, ces hypothétiques incarnations n'ont pas été définies.
Les autres RFC à lire, une fois celui-ci achevé, sont :
Les section 2 et 3 détaillent cette architecture. Parmi les propriétés importantes de l'Identificateur, le fait qu'une machine puisse en avoir plusieurs, par exemple à des fins de protection de la vie privée : avoir le même Identificateur tout le temps permettrait la traque d'une machine à travers ses déplacements, un problème analogue à celui qui a mené au RFC 8981. Une machine peut donc utiliser plusieurs identificateurs (mais, évidemment, pas au sein d'une même session).
Si l'application ne se sert que de noms de domaine pour contacter son pair, elle est dite « bien élevée » et fonctionnera sans problèmes avec ILNP. Ce comportement est celui recommandé par le RFC 1958. Si, par contre, l'application utilise explicitement des adresses IP (le RFC cite les fichiers de configuration d'Apache), elle pourra avoir des ennuis avec ILNP, où ces adresses ont une sémantique différente.
Les connexions des protocoles de transport, comme TCP, utilisent uniquement l'identificateur, résistant ainsi aux changements de localisateurs. Une machine d'un site multi-homé peut ainsi basculer d'un FAI à l'autre sans casser ses connexions TCP (cf. section 3.4).
Notez bien que l'identificateur identifie une machine, pas une interface réseau. Sa sémantique est donc très différente de celle des adresses IPv4, IPv6, ou des Interface Identifier d'IPv6 (RFC 4219).
Cela ne signifie pas que l'identificateur puisse être utilisé directement par les applications clientes. Comme indiqué plus haut, il est plutôt recommandé de se servir du nom de domaine.
Dans cette architecture, qu'est-ce qui est le plus proche d'une adresse IP ? Probablement le couple {Identificateur, Localisateur}, I-LV (pour Identifier - Locator Vector, cf. section 3.3). Ce couple désigne une liaison, notée (I, L), entre un identificateur et un localisateur.
Bref, un paquet ILNP contiendra un I-LV source et un I-LV destination. Notez que la sémantique d'un I-LV est proche de celle d'une adresse IP mais pas identique (l'I-LV se sépare en deux, I et L, l'adresse IP est structurée différemment, avec plusieurs préfixes hiérarchiquement emboîtés, etc). Le RFC 6741 indique comment ces IL-V sont représentés dans un paquet IP.
Dans les fichiers
ou entre discussions entre humains, les identificateurs ont le format
d'un Interface Identifier IPv6 (section 3.1.2). Ce
format, normalisé dans le RFC 4291 est fondé sur
le format EUI-64 par exemple 3a59:f9ff:fe7d:b647
. Si le bit « global » est mis
à 1, l'identificateur est supposé être unique au niveau mondial.
Le localisateur a une syntaxe analogue (par exemple,
2001:db8:43a:c19
). Une machine peut aussi avoir plusieurs localisateurs (par exemple
parce qu'elle a plusieurs connexions réseau). Le routage sera fait sur
la base des localisateurs, comme avec IP Classique
aujourd'hui (ce n'est donc pas par hasard que le localisateur
ressemble à un préfixe IPv6). Le localisateur peut être modifié en
route (cas du NAT). Contrairement à l'identificateur, relativement stable (en
tout cas pendant la durée d'une connexion), le localisateur peut
changer souvent (par exemple en situation de mobilité). Lorsque cela
se produit, la machine avertit ses correspondants (CN pour
Correspondent Nodes) avec un message ICMP
Locator Update. Si elle veut être contactée (si
c'est un serveur), elle doit aussi mettre à jour le DNS. Ces deux
mécanismes sont décrits en détail dans le RFC 6741.
Ces identificateurs et localisateurs sont publiés dans le
DNS (cf. RFC 6742). Une
application qui veut contacter www.example.com
aujourd'hui utilise le DNS pour connaître l'adresse IP
correspondante. Demain, elle utilisera ILNP pour connaître
identificateur et localisateur. (Pour des raisons de sécurité,
DNSSEC est recommandé.)
Il est aussi précisé que l'un des buts d'ILNP est de pouvoir l'incarner dans des protocoles qui sont compatibles avec l'existant (pour permettre à ILNP et IP Classique de coexister) et déployables de manière incrémentale (ne pas exiger que tout le monde passe à ILNP d'un coup).
La section 4 explique ensuite comment se fait le routage. Alice et Bob connaissent ILNP et veulent se parler, avec, entre eux, plusieurs routeurs traditionnels ne connaissant rien à ILNP. (En terminologie ILNP, Bob est le CN - Correspondent Node.) Dans le cas le plus courant, Bob a mis son (ou ses) Identificateurs et son (ou ses) Localisateurs dans le DNS (notez que les serveurs DNS utilisés n'ont pas besoin de connaître ILNP, mais cela optimise le temps de réponse DNS s'ils le gèrent). Cela a pu être fait manuellement ou, mieux, automatiquement via les mises à jour dynamiques (de préférence sécurisées, cf. RFC 3007). Alice va faire une requête DNS (cf. RFC 6742) et récupérer ainsi Identificateur et Localisateur de Bob (notez qu'ILNP n'a pas pour l'instant de mécanisme pour récupérer un Localisateur à partir d'un Identificateur).
Alice et Bob vont avoir besoin dans leurs systèmes d'une nouvelle structure de données, l'ILCC (I-L Communication Cache, section 4.2 et RFC 6741) qui permet de se souvenir des Localisateurs actuellement en service pour un CN donné. Au début, on y met les localisateurs récupérés via le DNS.
Ensuite, en IPv6, tout est simple. Alice fabrique un paquet IPv6,
contenant l'option Nonce (numnique) du RFC 6744, et dont la source est la concaténation de son
Localisateur et de son Identificateur (avec les valeurs données plus
haut à titre d'exemple, ce sera 2001:db8:43a:c19:3a59:f9ff:fe7d:b647
). La destination est formée en
concaténant Localisateur et Identificateur de Bob. Les deux adresses
ainsi fabriquées sont des adresses IPv6 tout à fait normales et les
routeurs entre Alice et Bob suivent la méthode de routage, et de
résolution d'adresses en local (NDP)
traditionnelles.
En IPv4, cela sera toutefois plus complexe (on ne peut pas mettre Identificateur et Localisateur dans les 32 bits d'une adresse IPv4, et ARP ne permet pas de résoudre un Identificateur, trop gros pour lui). Voir les RFC 6746 et RFC 6747 pour les solutions adoptées.
Comment est-ce que cela résout le problème du multi-homing, déjà cité plusieurs fois ? Comme l'explique la section 5, ILNP traite le Muti-homing en fournissant un Identificateur par machine et au moins un Localisateur par FAI. Alice utilise un des localisateurs pour le paquet initial, puis prévient Bob par un message ICMP Locator Update pour annoncer les autres. En cas de panne ou de ralentissement d'un des FAI, Bob pourra envoyer ses paquets via les autres localisateurs (l'identificateur restant inchangé).
Pour les connexions entrantes (si Alice est un serveur Web), on publiera dans le DNS tous les localisateurs et le client les essaiera tous.
Multi-homing est en fait un terme très large. Il y a plusieurs cas :
Dans ILNP, la mobilité est traitée quasiment comme le multi-homing (section 6). Elle est donc très différente du Mobile IP du RFC 6275. Dans les deux cas, l'identificateur reste constant pendant que le localisateur actuellement utilisé peut changer. La principale différence est le délai : en cas de mobilité rapide, les mécanismes d'ILNP peuvent être trop lents pour assurer la transition (point que le RFC oublie de mentionner).
Comme pour le multi-homing, il peut y avoir mobilité d'une machine (le smartphone cité précédemment qui, maintenant, se déplace) ou d'un réseau entier (cas d'un bateau en déplacement, par exemple, où il faudra que les machines à bord connaissent ILNP). ILNP obtient le maintien de la connectivité grâce à des localisateurs qui changent dynamiquement (même en cours de session), une mise à jour de la liste que connait le CN, grâce aux messages ICMP Locator Update et enfin les mises à jour dynamiques du DNS (RFC 2136) pour continuer à recevoir de nouvelles sessions même après déplacement.
Avec IP Classic, si le téléphone se déplace et perd la Wi-Fi, les connexions TCP en cours sont coupées. Avec ILNP, le téléphone pourra simplement utiliser le(s) localisateur(s) restant(s) (ici, celui de la 3G) et garder ses connexions.
On a vu qu'ILNP était un truc assez ambitieux, promettant de résoudre plein de problèmes. Mais, comme l'ont montré les malheurs de plusieurs protocoles, être meilleur ne suffit pas. L'inertie de la base installée est forte. Il faut donc absolument, pour qu'un nouveau protocole ait la moindre chance de réussir, des mécanismes de compatibilité avec l'existant et de déploiement incrémental (on ne peut pas exiger que tout le monde migre au même moment). La section 8 discute en détail ces points. D'abord, un paquet ILNPv6 ne se distingue en rien d'un paquet IPv6 actuel (c'est un peu plus compliqué avec ILNPv4, pour lequel le traditionnel ARP ne suffit pas, cf. RFC 6747). Cela veut dire que les routeurs, de la petite box au gros routeur du cœur de l'Internet n'auront besoin d'aucun changement. Le routeur ne sait même pas que le paquet est de l'ILNPv6 (voir le RFC 6741 sur les détails concrets des paquets ILNP). On est donc dans un cas très différent de celui d'IPv6 où il fallait modifier tous les routeurs situés sur le trajet.
Côté DNS, il faudra des nouveaux types d'enregistrement (RFC 6742). Cela ne nécessite pas de modifications des résolveurs/caches. Sur les serveurs faisant autorité, il faudra légèrement modifier le code pour permettre le chargement de ces nouveaux types.
Il serait tout de même souhaitable que les serveurs DNS, lorsqu'ils
reçoivent une requête pour des noms qui ont des enregistrements ILNP,
envoient tous ces enregistrements dans la réponse. Ce n'est pas
nécessaire (le client pourra toujours les demander après) mais cela
diminuera le temps total de traitement. (Les requêtes de type
ANY
, « donne-moi tous les enregistrements que tu
as », ne renvoient pas forcément le résultat attendu, un cache n'ayant pas
forcément tous les enregistrements correspondant à un nom.)
Si Alice et Bob connaissent tous les deux ILNP et qu'Alice initie
une session avec Bob, tout se passera bien. Alice demandera
l'enregistrement DNS de type NID
, le serveur lui
renverra l'identificateur de Bob, les localisateurs seront ajoutés par
le serveur DNS (s'il connait ILNP) ou demandés explicitement par Alice
par la suite. Alice générera le numnique, et l'enverra à Bob avec sa
demande de connexion (RFC 6744). Mais, dans une optique de déploiement incrémental, il
faut prévoir le cas où Alice aura ILNP et pas Bob, ou bien
l'inverse. Que se passera-t-il alors ?
Si Alice connait ILNP et pas Bob, il n'y aura pas d'enregistrement
NID
dans le DNS pour Bob. Alice devra alors
reessayer avec de l'IP classique. Si un enregistrement NID était
présent à tort, Alice tentera en ILNP et enverra le numnique. Bob, en
recevant cette option inconnue, rejettera le paquet en envoyant un
message ICMP indiquant à Alice ce qui s'est passé.
Si Alice ne connait pas ILNP alors que Bob le connait, Alice ne
demandera pas le NID
et ne tentera rien en
ILNP. Si Bob accepte l'IP Classic, la connexion marchera, sans
ILNP.
Vu du point de vue de Bob (qui ne connait pas les requêtes DNS qui ont été faites), la connexion est en ILNP si l'option Nonce était présente dans le paquet initial, et en IP Classic autrement.
Le RFC ne mentionne toutefois pas trois problèmes pratiques :
Et la sécurité ? La section 7 couvre le cas particulier des interactions entre ILNP et IPsec (RFC 4301). La principale différence avec IP Classic est que l'association de sécurité IPsec se fait avec les identificateurs et plus avec les adresses.
Pour la sécurité d'ILNP en général, c'est la section 9 qu'il faut lire. En gros, ILNP a le même genre de risques qu'IP (on peut mentir sur son localisateur aussi facilement qu'on peut mentir sur son adresse IP) et les mêmes mesures de protection (comme IPsec).
Les Locator Updates d'ILNP, qui n'ont pas d'équivalent dans IP, sont protégés essentiellement par le numnique (RFC 6744). Sans cela, un méchant pourrait faire un faux Locator Update et rediriger tout le trafic chez lui. Avec le numnique, les attaques en aveugle sont extrêmement difficiles. Par contre, si l'attaquant peut espionner le trafic (par exemple s'il est sur le chemin de celui-ci), le numnique ne protège plus (c'est analogue au problème du numéro de séquence initial de TCP, cf. RFC 6528). Il faut alors chiffrer toute la session avec IPsec (selon le type de menaces, on peut aussi envisager SSH ou TLS). Cette situation n'est pas très différente de celle d'IP Classic.
Notez qu'il existe deux numniques par session, un dans chaque sens. Les chemins sur l'Internet étant souvent asymétriques, cela complique la tâche de l'attaquant (s'il n'est que sur un seul chemin, il ne trouvera qu'un seul numnique).
Autre attaque courante sur l'Internet (même si le RFC dit, curieusement, qu'elle existe mais n'est pas répandue), l'usurpation d'adresses. Il est facile de mentir sur son adresse IP. Peut-on mentir sur son Identificateur ou bien son Localisateur ? Disons que mentir sur son Identificateur est en effet facile et qu'on ne peut guère l'empêcher. Contrairement à HIP, ILNP n'a pas forcément de protection cryptographique de l'identificateur (cf. RFC 7343). Il est possible d'utiliser les adresses cryptographiques du RFC 3972, il reste à voir si cela sera déployé. Autre solution dans le futur, utiliser IPsec avec des clés indexées par l'identificateur (mais cela reste bien théorique).
En revanche, un mensonge sur le Localisateur est plus difficile. Il peut être protégé par les techniques du RFC 2827 et RFC 3704. Certains protocoles au-dessus, comme TCP avec ses numéros de séquence initiaux imprévisibles, ajoutent une autre protection.
Autre aspect de la sécurité, la vie privée. Comme le rappele la section 10, avoir un identificateur stable peut faciliter le suivi d'une machine (et donc de son utilisateur) même lorsqu'elle se déplace. Ce problème est connu sous le nom d'identity privacy. Le problème avait déjà été mentionné avec IPv6 et la solution est la même : se servir des identificateurs temporaires du RFC 8981. (Une machine ILNP n'est pas forcée de n'avoir qu'un seul identificateur.)
Autre menace, celle sur la location privacy. Non spécifique à ILNP, c'est le fait qu'on puisse connaître la localisation actuelle d'une machine via son localisateur. Le problème est très difficile à résoudre, la qualité de la connectivité étant inversement proportionnelle à la dissimulation de l'adresse. Si on force le passage par une machine relais fixe (comme le permet Mobile IP), on a une bonne protection de la vie privée... et une bonne chute des performances et de la résilience.
Si le localisateur a été publié dans le DNS, un indiscret qui veut le connaître n'a même pas besoin d'une communication avec la machine qu'il veut pister, interroger le DNS (qui est public) suffit. Si une machine veut rester discrète sur sa localisation et qu'elle n'a pas besoin d'être contactée, le mieux est qu'elle ne mette pas son localisateur dans le DNS.
Il n'existe encore aucune mise en œuvre publique d'ILNP. Un projet existe mais rien n'est encore sorti.
Pour les curieux d'histoire, la section 1.2 présente la vision des auteurs sur les différentes étapes ayant mené à ILNP. Ils remontent jusqu'en 1977 où la note IEN1 notait déjà le problème qu'il y avait à faire dépendre les connexions d'une adresse qui pouvait changer. Cette note proposait déjà une séparation de l'identificateur et du localisateur, qui n'a pas eu lieu dans TCP/IP. Par exemple, TCP utilise dans la structure de données qui identifie une connexion les adresses IP de source et de destination. Tout changement d'une de ces adresses (par exemple parce que la machine a bougé) casse les connexions TCP en cours.
Après ce choix, et quelques années plus tard, l'idée d'une séparation de l'identificateur et du localisateur est revenue, compte-tenu de l'expérience avec TCP/IP. En 1994, une note de Bob Smart repropose cette idée. Même chose en 1995 avec Dave Clark. Enfin, en 1996, Mike O'Dell propose son fameux 8+8, qui n'atteindra jamais le statut de RFC mais reste la référence historique des propositions de séparation de l'identificateur et du localisateur. (Une grosse différence entre 8+8 et ILNP est que ce dernier n'impose pas de réécriture du localisateur en cours de route).
Depuis, plusieurs autres travaux ont été faits en ce sens, mais sans déboucher sur beaucoup de déploiements. Des « vrais » protocoles de séparation de l'identificateur et du localisateur (rappelons que les auteurs ne considèrent pas LISP comme faisant partie de cette catégorie), seul HIP a connu une description dans un RFC et plusieurs mises en œuvres. ILNP offre sans doute moins de sécurité que HIP (contrairement à HIP, pas besoin d'établir une connexion avant toute communication) mais autant qu'avec l'IP actuel. Et ILNP est moins disruptif que HIP, ce qui peut être vu comme un avantage ou un inconvénient.
Quelques lectures :
Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : V. Fajardo (Telcordia Technologies), J. Arkko (Ericsson Research), J. Loughney (Nokia Research Center), G. Zorn (Network Zen)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dime
Première rédaction de cet article le 26 octobre 2012
Pendant longtemps, le seul protocole standard d'authentification entre un NAS et sa base d'utilisateurs était Radius. Diameter, normalisé dans notre RFC (qui fait suite au RFC 3588), visait à le remplacer, et est bien plus riche en fonctions.
Traditionnellement, lorsqu'un client PPP ou d'un protocole similaire se connecte à son FAI, sa session est terminée sur un NAS, équipement qui ne possède en général pas de base des utilisateurs autorisés. Il y a plusieurs raisons à cela, comme le fait que le NAS n'est en général pas un ordinateur généraliste, il a peu de moyens, notamment en place disque ou bien comme le fait qu'un FAI a typiquement plusieurs NAS (au moins un par POP), et qu'il souhaite centraliser l'authentification. (Dans le monde 802.11, le NAS est typiquement nommé AP - Access Point.)
Le mécanisme habituel est donc que le NAS soit client d'un protocole d'authentification et que le FAI gère un serveur de ce protocole, serveur qui connaitra les utilisateurs autorisés. Le même protocole assure en général également des fonctions de comptabilisation des accès, d'où le sigle AAA (Authentication, Authorization and Accounting). Le premier protocole standard en ce sens est Radius (RFC 2865), que Diameter vise à remplacer. (Un protocole privé, Tacacs, qui sera documenté dans le RFC 1492, avait également été utilisé.) Diameter avait été normalisé à l'origine dans le RFC 3588. Après une longue gestation (plusieurs années, alors qu'aucun changement de fond n'a été fait, et pas moins de trois « Last Calls » devant l'IETF), il est désormais remplacé par ce nouveau RFC 6733. Le protocole reste le même et les logiciels conformes à l'ancien et au nouveau RFC devraient interopérer.
Que reproche Diameter à Radius ? La section 1 de notre RFC détaille les faiblesses de Radius perçues par les auteurs de Diameter. Une analyse plus détaillée figure dans le RFC 3169 :
Diameter est donc plus riche et plus complexe que Radius. Diameter reprend aussi plusieurs idées de Radius comme le codage en doublets Attribut / Valeur (AVP pour Attribute-Value Pairs) ou comme l'utilisation des NAI du RFC 7542 pour coder l'identité vérifiée.
Le RFC est bien plus long et compliqué que son équivalent Radius (154 pages !). La section 1 introduit le protocole, et ses usages, et le compare aux exigences listées dans le RFC 2989.
La section 2 précise le protocole, par exemple le mécanisme de transport fait l'objet de la sous-section 2.1, qui impose au minimum TCP et SCTP (les détails sont dans le RFC 3539). Diameter écoute par défaut sur le port 3868. La 2.4 introduit le nouveau concept d'Application Identifier, valeur enregistrées auprès de l'IANA qui identifie un usage particulier de Diameter (plus riche que Radius, Diameter permet davantage d'usages). Par exemple, l'usage en tant que service d'authentification pour un NAS (Application Identifier n° 1) n'est pas dans le cœur du protocole, il est délégué au RFC 4005. D'autres RFC décrivent des applications de Diameter comme le RFC 4740 qui parle de son usage pour SIP. 2.5 parle de la différence entre connexions et sessions, une connexion étant un concept de la couche 4 alors qu'une session Diameter peut impliquer plusieurs connexions. En 2.8, on trouve le bestiaire des agents Diameter, les clients et les serveurs bien sûr mais également les relais ou bien les traducteurs, pour parler à des agents d'autres protocoles, notamment Radius.
La section 3 décrit l'en-tête des paquets
Diameter et les codes de commande qu'ils contiennent comme
Capabilities-Exchange-Request
. Seuls les codes
communs à toutes les applications sont définis dans la section 3.1,
des codes aussi importants que AA-Request
(demande d'authentification, l'équivalent du Access-Request
de Radius) sont délégués à d'autres RFC (comme le RFC 4005).
En section 4, nous arrivons aux AVP eux-même, les doublets
attributs-valeur qui portent l'information. On notera en 4.1 un
concept désormais fréquent dans les protocoles réseaux, l'option
Mandatory qui indique pour un AVP, s'il doit
absolument être connu de l'implémentation (le dialogue Diameter avorte
autrement) ou bien s'il peut tranquillement être ignoré, par exemple
par une vieille implémentation qui ne connait pas ce nouvel AVP. La
sous-section 4.3
décrit, entre autre, les URI Diameter, de
plan aaa:
,
comme
aaa://host.example.com:666:transport=stcp;protocol=diameter
.
Les sections 5 à 8 spécifient les nombreuses machines à état qui doivent être mises en œuvre par les agents Diameter. Au contraire de Radius qui, comme le DNS, est purement requête/réponse, Diameter nécessite un vrai automate dans chaque agent.
La sous-section 5.2 explique comment un agent Diameter peut en trouver un autre. Avec Radius, la configuration (par exemple du serveur d'authentification) devait être manuelle. Avec Diameter, on peut utiliser SLP (RFC 2165) ou NAPTR combiné avec SRV (RFC 2782).
La section 13, sur la sécurité, est très stricte. Un agent Diameter doit pouvoir faire du TLS (mais, contrairement au RFC 3588, IPsec n'est plus qu'une possibilité secondaire).
Une bonne introduction à Diameter a été publié en http://www.interlinknetworks.com/whitepapers/Introduction_to_Diameter.pdf
.
Il n'existe que trois implémentations de serveur Diameter en
logiciel libre, Free Diameter, Open Diameter et OpenBlox Diameter, et, à part la première,
elles semblent peu maintenues. (Et je ne suis pas sûr qu'OpenBlox soit vraiment libre.)
Le bilan opérationnel de Diameter est mince : beaucoup plus complexe que Radius, il ne l'a pas réellement remplacé dans son secteur, l'authentification via un NAS. Diameter semble bien être une nouvelle victime de l'effet « Deuxième système ».
Quels sont les changements par rapport au premier RFC Diameter, le RFC 3588 ? La section 1.1.3 en donne un résumé (la liste exacte est trop longue pour être incluse dans ce RFC déjà très long). Si les changements sont nombreux, ils ne sont pas suffisamment importants pour qu'on puisse parler d'un nouveau protocole. C'est le même Diameter et les nouveaux logiciels pourront parler avec les anciens. Les changements sont des clarifications, des abandons de certaines fonctions, et la correction des nombreuses erreurs du RFC précédent (à mon avis, il y a une leçon à en tirer : les spécifications compliquées sont plus difficiles à faire correctement). Certaines fonctions étaient mentionnées dans le RFC 3588 mais même pas décrites complètement. Les principaux changements :
Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : T. Savolainen (Nokia), J. Kato (NTT), T. Lemon (Nominum)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mif
Première rédaction de cet article le 19 décembre 2012
Lorsqu'une machine connectée à l'Internet a plusieurs interfaces réseaux, et apprend (par exemple en DHCP) l'existence d'un résolveur DNS différent sur chaque interface, lequel utiliser ? Le principe de base de cette nouvelle norme est qu'il faudrait garder en mémoire chaque résolveur et utiliser à chaque fois celui qui correspond à l'interface réseau qu'on va utiliser.
Autrefois, le problème ne semblait pas crucial : après tout, un
résolveur DNS en vaut un autre, puisque tous
donnent les mêmes réponses. Mais ce n'est plus le cas aujourd'hui. Par
exemple, sur certaines interfaces, le résolveur DNS peut donner accès
à des noms de domaine privés,
strictement locaux, que les autres résolveurs ne connaissent pas. On
ne peut donc pas se contenter de prendre l'un des résolveurs au
hasard, ni même « le meilleur » résolveur car chacun peut avoir des
caractéristiques uniques (par exemple, l'un des résolveurs connait le domaine privé
foo.example
et un autre un autre domaine privé bar.example
). D'où cette règle de garder en mémoire tous
les résolveurs connus. (Le RFC utilise le terme de
RDNSS - Recursive DNS
Servers - pour les résolveurs.)
Ce n'est pas tout de mémoriser tous les résolveurs, encore faut-il savoir lequel utiliser. C'est le rôle de nouvelles options DHCP normalisées ici, qui permettent de distribuer les méta-informations dont le client a besoin pour savoir de quel résolveur se servir.
Si on veut mieux comprendre le problème de ces machines ayant
plusieurs interfaces réseaux, il faut lire le premier
RFC du groupe de travail MIF, le RFC 6418, qui définit le problème. Un exemple d'une telle
machine est un smartphone
qui a accès à la fois à un réseau WiFi privé et
à la 3G. Mais il y a aussi le cas où il n'y a
qu'une seule interface physique, mais plusieurs virtuelles, par
exemple un accès à l'Internet par le FAI local
et un VPN vers le réseau sécurisé de
l'entreprise. La partie la plus évidente du problème des machines à
plusieurs interfaces est celui des noms privés (section 2.1). Imaginons que la
société Foobar ait le domaine foobar.example
et
qu'un sous-domaine internal.foobar.example
contienne les informations privées, spécifiques à l'entreprise et non
visibles dans le DNS public. Cela se fait en configurant spécialement
les résolveurs utilisés par les employés de l'entreprise. Par exemple, avec Unbound, pour un domaine nommé 42
et servi par 91.191.147.246
et 91.191.147.243
, cela serait :
stub-zone: name: "42" stub-addr: 91.191.147.246 stub-addr: 91.191.147.243
Si un de ces employés est en voyage, connecté depuis l'hôtel,
ayant activé le VPN, et que sa machine utilise
le résolveur de l'hôtel, il ne pourra pas utiliser les noms en
internal.foobar.example
. (Vous pouvez vous dire
« il faut utiliser le résolveur DNS de l'entreprise pour tout ». Mais il
sera en général plus lent et il pourra avoir ses propres limites, par
exemple ne pas pouvoir résoudre facebook.com
car
le résolveur de l'entreprise censure ce nom.)
Notez aussi que le fait que l'application de ce RFC permettre de
gérer les noms de domaines privés (non rattachés à l'arbre principal
du DNS) ne signifie pas que ces noms privés soient une bonne idée,
approuvée par l'IETF. Ce point avait été une
des grosses controverses dans le groupe de travail. La section 6 donne à ce sujet des conseils pour
minimiser les risques associés à ces noms privés. (En gros, les
choisir uniques, par exemple en les suffixant du nom de
l'organisation, pour que tout le monde ne nomme pas ses machines dans
.private
ou .lan
.)
En général, le « bon » résolveur à utiliser dépend de l'interface
de sortie et les techniques de ce RFC sont donc à utiliser en
combinaison avec celles du RFC 4191 et du RFC 3442. Même si un nom de domaine est visible partout, il peut
se résoudre en des adresses
IP différentes selon l'interface réseau utilisé (cas
célèbre de smtp.orange.fr
qui ne donne pas le
même résultat aux abonnés d'Orange et aux
autres.) On peut encore citer le cas des extensions au DNS utilisées
dans certains cas de coexistence
IPv4-IPv6 (RFC 6147).
Il peut y avoir des cas encore plus complexes et notre RFC ne prétend pas tout résoudre (section 2.3).
Avant de décrire la solution standardisée, le RFC présente trois études de cas permettant d'illustrer un problème soluble (section 3). Des études de cas plus détaillées, avec examen des pratiques actuelles, figurent dans le RFC 6419.
D'abord, le cas d'un foyer connecté à l'Internet via un FAI
ainsi qu'à un réseau privé, les deux connexions passant par le même
CPE. Ce réseau privé utilise uniquement des noms
dans un domaine qui n'apparait pas sur l'Internet (mettons
hidden.example
). Pour que tout marche, du point
de vue de l'utilisateur, il faut envoyer les requêtes de résolution de
noms au résolveur du réseau privé, si le nom se termine en
hidden.example
et au résolveur du FAI
autrement. Le plus simple est qu'un relais DNS
tourne sur le CPE et aiguille automatiquement les requêtes DNS vers le
bon résolveur.
Autre scénario d'usage, celui mentionné plus tôt d'un smartphone connecte à la fois au réseau 3G et à un accès WiFi local. Pour des raisons financières, on souhaite utiliser le WiFi dans le plus grand nombre de cas. Mais on peut avoir besoin d'établir certaines connexions via la 3G, soit parce que certains services ne sont que là, soit pour des raisons de sécurité (à mon avis, le RFC surestime nettement la sécurité de la 3G mais c'est une autre histoire).
Le smartphone doit donc utiliser le DNS de l'accès WiFi par défaut mais avoir des règles (par exemple une liste de destinations sensibles qu'on ne veut contacter qu'en 3G) qui imposeront l'utilisation du résolveur DNS du fournisseur de 3G.
Enfin, dernière étude de cas, celui du road warrior doté d'un accès à un (ou plusieurs) VPN de son entreprise. Aussi bien pour des raisons de sécurité que d'accès à des noms de domaines privés, on veut faire passer les accès au réseau interne de l'entreprise (requêtes DNS comprises) par le VPN. Par contre, pour consulter Facebook et YouTube, on va passer par l'accès par défaut.
La section 4 du RFC donne ensuite les règles exactes à suivre pour que tout se passe bien. Le principe essentiel est que la machine doit construire une liste de résolveurs (et pas uniquement garder le dernier annoncé) accessibles, en notant pour chacun les options envoyées par DHCP (nouvelles options décrites un peu plus loin), qui vont permettre de sélectionner le résolveur à utiliser pour une requête donnée. Par défaut, on considère que tous les résolveurs sont équivalents (donnent les mêmes résultats). Mais certains critères permettent de les distinguer :
IF_CELLULAR
préféré à IF_WLAN
.) Cette confiance est à configurer dans le client, il
n'y a pas de protocole pour la déterminer.
Avec tous ces critères, on peut faire une sélection intelligente du
résolveur. Ainsi, s'il faut résoudre un nom en
private.mycompany.example
et qu'un seul des
résolveurs annonce ce domaine (les autres gérant l'arbre public du
DNS), c'est clair qu'il faut utiliser ce serveur, les autres ne
pourront pas répondre. Les règles de sélection exactes figurent dans
la section 4.1. Si vous préférez lire le
pseudo-code, l'annexe C contient une mise en
œuvre de cet algorithme.
Les sections 4.2 et 4.3 décrivent les nouvelles options pour DHCPv4 (RFC 2131) et DHCPv6 (RFC 8415). Elles sont quasiment identiques en v4 et v6 donc je me limite à celle de v6 :
private.company.example
, (et
.
tout court s'il connait tous les domaines, ce qui est le
cas d'un résolveur normal), ainsi qu'une liste de domaines
correspondant à des préfixes IP pour les
résolutions dans ip6.arpa
(RFC 3596).Un client DHCP qui connait notre RFC met une demande de cette option dans sa requête et reçoit en échange la liste ci-dessus. Attention, elle est limitée en taille par les contraintes de DHCP (section 4.4), il ne faut donc pas espérer y indiquer des centaines de domaines possibles.
Une fois qu'un résolveur a été sélectionné pour une requête DNS, il
doit continuer à être utilisé si cette requête déclenche à son tour
d'autres requêtes (section 4.7). Imaginons qu'on cherche l'adresse IPv6 de
portal.company.example
, on va faire une requête
AAAA portal.company.example
et si on obtient une
réponse portal.company.example CNAME
www.example.com
, alors, la requête ultérieure
AAAA www.example.com
doit utiliser le même
résolveur, pour être cohérente, au cas où
www.example.com
renvoie des adresses différentes
selon le résolveur qui demande. Programmeurs, attention, cela implique
de garder un état et de ne pas faire la sélection du résolveur de
manière indépendante pour chaque requête.
De même qu'on garde une liste de résolveurs à utiliser, il faut aussi avoir autant de caches que d'interfaces, ou vider le cache entre deux requêtes, pour éviter qu'une information venant du cache n'« empoisonne » une résolution. Et il ne faut pas oublier, lorsqu'une interface réseau disparait, de vider le cache des données apprises via cette interface (section 4.8). Le logiciel local de la machine devient donc assez compliqué !
Voilà, vous savez tout. Si le problème vous intéresse et que vous voulez creuser la question, l'annexe A de ce RFC présente « ce qui aurait pu être », les autres mécanismes qui auraient pu être choisis (comme « envoyer la requête sur toutes les interfaces réseau et prendre la première réponse qui revient »).
Actuellement, il semble que certains systèmes de Nokia et de Microsoft (Name Resolution Policy Table) utilisent déjà ce mécanisme dans leurs téléphones.
Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : S. Krishnan, J. Halpern (Ericsson)
Pour information
Première rédaction de cet article le 27 septembre 2012
L'IETF dispose d'une institution curieuse, le NomCom (Nominations Committee) qui est chargée de sélectionner des candidats pour des postes à l'IESG, l'IAB ou l'IAOC. Sa tâche d'examen des noms et de sélection nécessite un certain nombre d'outils informatiques, qui n'existent pas forcément tous à l'heure actuelle. Ce RFC est le cahier des charges des outils, pour servir de base aux futurs développements.
Tous les détails sur le NomCom et son fonctionnement sont spécifiés dans le RFC 7437. On peut aussi consulter le site officiel. Le NomCom dispose déjà d'un outil (accessible via le Web pour sa partie publique, mais il a aussi une partie privée, réservée aux membres du NomCom) mais qui est insuffisant. Notre nouveau RFC liste les nouveautés nécessaires pour cet outil. La première exigence, étiquetée META-001 est que le nouvel outil devra reprendre toutes les fonctions de l'ancien.
Ensuite, comme le NomCom travaille avec des données personnelles,
la plupart des exigences du cahier des charges concernent la
sécurité. Le logiciel stockera des noms, des appréciations, des
opinions sur des personnes, etc, toutes choses assez sensibles. Il faudra un système d'authentification (exigences AUTH-001
à AUTH-003), capable de
distinguer trois rôles (membre ordinaire de
l'IETF, membre du NomCom, président du
NomCom). Les membres ordinaires n'ont accès qu'à la partie
publique. Ils se servent pour cela de leur compte
datatracker.ietf.org
(cf. RFC 6175, tout le monde peut se créer un compte avec cet
outil puisque tout le monde peut participer à l'IETF).
Toutes les communications seront évidemment chiffrées et l'exigence SEC-001 demande que les données stockées le soient de telle façon qu'on minimise même leur exposition accidentelle (même l'administrateur ne doit les voir que sur une action explicite de sa part). Les données seront stockées chiffrées avec la clé publique du NomCom (exigences SEC-002 à SEC-005) et seront détruites à la fin de la sélection (toutes les données ne sont pas concernées, voir plus loin).
Moins cruciales, les autres exigences portent sur le processus de désignation des candidats (exigences NOM-001 à NOM-011) et sur l'enregistrement de l'acceptation ou du rejet car un candidat peut ne pas accepter sa désignation, qui a pu être faite par un tiers (exigences AD-001 à AD-007).
Enfin, l'outil devra gérer les réponses des candidats aux questionnaires qui leur seront soumis (« que ferez-vous si vous êtes élu à l'IAB ? » (exigences QR-001 à QR-007) et surtout les retours des membres sur les candidatures (exigences FB-001 à FB-006). Ces retours, avis, et opinions forment une part essentielle du processus mais, malheureusement, les exigences d'ouverture et de sécurité ne sont pas faciles à concilier. Ainsi, les messages envoyés au NomCom par les membres sont archivés, contrairement aux autres données collectées par le NomCom (exigence FB-005).
On peut finir avec l'amusante annexe A de ce RFC, qui décrit les
commandes OpenSSL nécessaires pour la gestion
de la cryptographie dans l'outil du NomCom. La configuration (le
fichier nomcom-config.cnf
) ressemble à :
[ req ] distinguished_name = req_distinguished_name string_mask = utf8only x509_extensions = ss_v3_ca [ req_distinguished_name ] commonName = Common Name (e.g., NomcomYY) commonName_default = Nomcom12 [ ss_v3_ca ] subjectKeyIdentifier = hash keyUsage = critical, digitalSignature, keyEncipherment, dataEncipherment basicConstraints = critical, CA:true subjectAltName = email:nomcom12@ietf.org extendedKeyUsage= emailProtection # modify the email address to match the year.
Et on peut générer le certificat avec :
openssl req -config nomcom-config.cnf -x509 -new -newkey rsa:2048 \ -sha256 -days 730 -nodes -keyout privateKey.pem \ -out nomcom12.cert
Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : D. Crocker (Brandenburg
InternetWorking), M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 7 septembre 2012
Lorsqu'on débogue un problème de courrier électronique en examinant un message reçu, le technicien
regarde souvent en premier les champs Received:
de l'en-tête. Ceux-ci indiquent les différents
MTA qui ont pris en charge le message et sont
notamment très utiles en cas de retard inattendu : ils permettent de
voir quel MTA a traîné dans la remise du message au MTA suivant. Mais
cela ne suffit pas toujours. Aujourd'hui, il est de plus en plus
fréquent que les messages soient retardés en raison d'un traitement
local à une machine, par exemple le passage par un programme de
sécurité qui met très longtemps à vérifier quelque chose. Il n'y avait
pas de moyen pratique avec les champs Received:
pour indiquer ces traitements. C'est désormais fait avec un nouvel
indicateur dans Received:
:
state
qui permet de signaler le passage d'un
traitement lent à un autre.
Voici un exemple d'une suite de champs
Received:
. Rappelez-vous qu'elle se lit de bas en
haut :
Received: from slow3-v.mail.gandi.net (slow3-v.mail.gandi.net [217.70.178.89]) by mail.bortzmeyer.org (Postfix) with ESMTP id 5EC103AD82 for <stephane+blog@bortzmeyer.org>; Thu, 6 Sep 2012 18:26:36 +0000 (UTC) Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by slow3-v.mail.gandi.net (Postfix) with ESMTP id 2268638B64 for <stephane+blog@bortzmeyer.org>; Thu, 6 Sep 2012 20:21:20 +0200 (CEST) Received: from mfilter1-d.gandi.net (mfilter1-d.gandi.net [217.70.178.130]) by relay4-d.mail.gandi.net (Postfix) with ESMTP id 0844C172094 for <stephane+blog@bortzmeyer.org>; Thu, 6 Sep 2012 20:21:10 +0200 (CEST) Received: from relay4-d.mail.gandi.net ([217.70.183.196]) by mfilter1-d.gandi.net (mfilter1-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id 9nO2SZ5sO3KB for <stephane+blog@bortzmeyer.org>; Thu, 6 Sep 2012 20:21:08 +0200 (CEST)
On note que la machine mfilter1-d.gandi.net
a
renvoyé le message à relay4-d.mail.gandi.net
d'où
il venait. Ce n'est pas une erreur,
mfilter1-d.gandi.net
est la machine de filtrage
et utilise Amavis pour un certain nombre de
tests sur le message (absence de virus, par
exemple) avant de le réinjecter. Ici, cet examen a été rapide (deux
secondes, si on peut se fier aux horloges des machines) mais, s'il est
plus long (et Amavis peut être très long), il serait souhaitable de pouvoir
le marquer plus clairement.
Il existe bien des tests/vérifications/etc qui peuvent ainsi
ralentir un message : mise en quarantaine,
modération, tests anti-spam ou anti-virus,
etc. Pour les indiquer plus clairement, notre
RFC reprend le champ
Received:
(défini à la section 4.4 du RFC 5321 et un des outils les plus importants du
technicien qui fait fonctionner le courrier électronique). Ce champ comprend plusieurs clauses (dans
les exemples ci-dessus, on voit les clauses from
,
by
, with
et
for
, définies dans la section 4.4 du RFC 5321). Notre RFC en ajoute une nouvelle,
state
(désormais enregistrée,
section Additional-registered-clauses), qui
ressemble à ça (exemple du RFC car je n'ai pas encore trouvé de clause
state
dans mes boîtes aux lettres, bien qu'il
existe apparemment déjà une mise en œuvre en production) :
Received: from newyork.example.com (newyork.example.com [192.0.2.250]) by mail-router.example.net (8.11.6/8.11.6) with ESMTP id i7PK0sH7021929 for <recipient@example.net>; Fri, Feb 15 2002 18:33:29 -0800 Received: from internal.example.com (internal.example.com [192.168.0.1]) by newyork.example.com (8.11.6/8.11.6) with ESMTP id i9MKZCRd064134 for <secret-list@example.com> state moderation (sender not subscribed); Fri, Feb 15 2002 17:19:08 -0800
Ici, le MTA de newyork.example.com
a décidé de ne
pas envoyer le message tout de suite mais de le soumettre à un
modérateur (avant-dernière ligne du plus ancien
Received:
, clause
state
). Cela suffit à expliquer le délai d'une
heure vingt entre les deux Received:
, sans
imaginer une coupure réseau ou une autre panne. On voit que la clause
state
indique l'entrée dans
un nouvel état (ici, l'état « en attente d'approbation par le
modérateur »), la sortie étant marquée par le
champ Received:
suivant (qui, ici, n'a pas d'état
explicite). Rappelez-vous (promis, c'est la dernière fois que je le
dis) que les champs Received:
se lisent de bas en
haut.
La clause state
dans l'exemple ci-dessus
utilisait le mot-clé moderation
. Une liste
limitative de tels mots-clés est
enregistrée (section Registered-states) et elle comprend
notamment :
auth
: le message attend une authentification,content
: le contenu du message va être
analysé, par exemple pour s'assurer qu'il ne contient pas de
spam ou de
malware,moderation
: passage par le
modérateur,timed
: message délibérement gardé, en
attendant l'heure de la remise (voir RFC 4865),normal
: ce mot-clé est enregistré mais, en
fait, c'est celui par défaut, lorsqu'aucune clause
state
n'est présente,other
: il y a toujours des cas où on ne
sait pas :-)
À noter que le mot-clé peut être suivi d'une barre oblique et d'une valeur (non enregistrée, on met ce qu'on
veut), on peut donc avoir
moderation/not-subscribed
ou
quarantine/spam
. D'autres états pourront être
enregistrés dans le futur, sous la politique « Premier arrivé, premier
servi » (cf. RFC 5226). Ce point avait été le
principal sujet de discussion avant la publication du RFC, certains
auraient préféré la politique plus restrictive « Examen par un expert ».
Les programmeurs de MTA qui veulent ajouter cette clause aux
champs Received:
qu'ils écrivent ont tout
intérêt à bien lire les sections 4 et 5, qui discutent de quand utiliser la
clause state
. Elle n'est pas prévue pour des
opérations différentes à l'intérieur d'un même agent. Le RFC
recommande bien qu'elle ne soit utilisée que lorsqu'on passe à un
agent différent, par exemple de Postfix à
Amavis. Autrement, on risque de se retrouver
avec plein de Received:
qui rendront l'analyse
plus difficile (et risquent d'atteindre la limite des MTA, qui
rejettent les messages ayant trop de Received:
,
pensant qu'ils bouclent). L'idée est de déboguer les performances et
donc cette clause est là uniquement pour les problèmes temporels,
pas pour n'importe quelle action ou changement d'état interne à l'agent.
Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : T. Paila (Nokia), R. Walsh (Tampere University of Technology), M. Luby (Qualcomm), V. Roca (INRIA), R. Lehtonen (TeliaSonera)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF rmt
Première rédaction de cet article le 7 novembre 2012
Peut-on envoyer un fichier d'un ordinateur à un autre lorsque la liaison est unidirectionnelle, c'est-à-dire que les paquets ne voyagent que dans un sens ? Pas question de se servir de FTP ou de HTTP, qui reposent sur le protocole de transport TCP, qui a besoin de bidirectionnalité (car il dépend du retour des accusés de réception). Le protocole FLUTE (File Delivery over Unidirectional Transport) normalisé dans ce RFC, fournit un ensemble de mécanismes pour effectuer ce transfert. La principale application concerne le multicast, où une machine unique diffuse un fichier à plusieurs autres, qu'elle ne connait pas forcément et qui ne peuvent pas lui écrire. Un exemple typique est la distribution des mises à jour d'un gros logiciel à des milliers, voire millions, de machines dans le monde. Parmi les usages possibles, distribuer de la vidéo, une nouvelle version d'un jeu très populaire, etc.
Pour cela, FLUTE s'appuie sur le système ALC (RFC 5775) + LCT (Layered Coding Transport, RFC 5651), qui fait l'essentiel du travail. ALC+LCT sert de protocole de transport d'objets binaires, FLUTE se charge de la sémantique. FLUTE dépend aussi d'autres protocoles de la famille multicast, comme FEC (RFC 5052), qui assure la fiabilité du transport, en permettant au récepteur de détecter les erreurs.
Transférer des gros fichiers sur un réseau ouvert comme l'Internet implique également un mécanisme de contrôle de la congestion, pour éviter que l'émetteur ne noie le réseau sous les paquets, sans se rendre compte que les tuyaux sont pleins. Comme on n'a pas TCP pour limiter la congestion en détectant les paquets perdus, il faut trouver un autre mécanisme. Dans le cas de FLUTE, les récepteurs souscrivent plusieurs abonnements multicast, éventuellement de débits différents, et jonglent avec ces divers abonnements. (Sur des réseaux fermés, le contrôle de congestion de FLUTE peut se faire par encore d'autres mécanismes comme le shaping.)
Les métadonnées (les propriétés du fichier) sont transmises dans un élément XML. On y trouve entre autres :
text/plain
.L'élement XML <File>
qui contient tout cela
est mis ensuite dans un élément
<FDT-Instance>
(FDT = File
Delivery Table) qui contient également les informations
externes au fichier (comme la date limite pendant laquelle
cette information sera valable). Voici
l'exemple que donne le RFC, pour le fichier track1.mp3
:
<?xml version="1.0" encoding="UTF-8"?> <FDT-Instance xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:fdt ietf-flute-fdt.xsd" Expires="2890842807"> <File Content-Location="http://www.example.com/tracks/track1.mp3" Content-Length="6100" Content-Type="audio/mp3" Content-Encoding="gzip" Content-MD5="+VP5IrWploFkZWc11iLDdA==" Some-Private-Extension-Tag="abc123"/> </FDT-Instance>
Cet élément XML est transmis avec le fichier. Les informations liées à l'émission du fichier (adresse IP source qui émettra le fichier, début de l'émission, etc) sont récupérées par le destinataire par un moyen non spécifié ici (cf. section 6). Cela a pu être une description SDP (RFC 4566), une ressource sur le Web ou bien d'autres méthodes, même une configuration manuelle. Le point important est que, une fois toutes ces informations en sa possession, le récepteur FLUTE peut se préparer à recevoir le fichier, et peut vérifier sa bonne délivrance (l'émetteur, lui, n'en saura rien, puisque la liaison est unidirectionnelle).
L'envoi unidirectionnel de fichiers soulève des problèmes de sécurité particuliers (section 7, très détaillée). Si le fichier transmis est confidentiel, il doit être chiffré avant, que ce soit par un chiffrement global du fichier (par exemple avec PGP) ou en route par IPsec.
Et si l'attaquant veut modifier le fichier ? On peut utiliser une signature numérique du fichier, avant son envoi ou bien, pendant le trajet authentifier les paquets ALC avec le RFC 6584 ou bien TESLA (Timed Efficient Stream Loss-Tolerant Authentication, RFC 4082 et RFC 5776) ou encore, là aussi, IPsec. À noter que certaines de ces techniques demandent une communication bidirectionnelle minimale, par exemple pour récupérer les clés publiques à utiliser.
Ce RFC est la version 2 de FLUTE, la version 1 était normalisée dans le RFC 3926, qui avait le statut expérimental. Avec ce nouveau document, FLUTE passe sur le chemin des normes IETF. La liste des changements importants figure en section 11. Notez tout de suite que FLUTE v2 est un protocole différent, incompatible avec FLUTE v1.
Je ne connais pas les implémentations de FLUTE mais il en existe plusieurs (pour la version 1) par exemple jFlute, l'ancien MCL v3 (plus maintenue en version libre mais Expway en a une version commerciale fermée) ou MAD-FLUTE fait à l'université de Tampere.
Merci à Vincent Roca pour sa relecture attentive.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : S. Rose (NIST)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 30 août 2012
Lors de la conception d'un protocole cryptographique, il est essentiel de permettre l'agilité des algorithmes, c'est-à-dire de changer d'algorithme pour répondre aux progrès de la cryptanalyse. C'est ainsi que DNSSEC inclut dans les enregistrements DNS de clés et de signatures un numéro qui identifie l'algorithme utilisé. Les numéros possibles sont dûment notés dans un registre IANA et ce nouveau RFC « nettoie » le registre, mettant à jour des entrées inutilisées.
Au passage, les érudits noteront que cette absence d'agilité cryptographique (l'algorithme n'est pas indiqué donc un seul algorithme est possible) est un des inconvénients de DNScurve. Mais ne digressons pas. Quels changements a apportés notre nouveau RFC 6725 ? Les numéros 4, 9 et 11, correspondant à des algorithmes qui n'ont jamais été déployés sont désormais marqués comme « réservés ». C'est tout. On ne peut pas les réaffecter (au cas où il traine dans la nature des mises en œuvre expérimentales utilisant ces algorithmes).
4 était réservé pour un algorithme à courbes elliptiques (on n'a jamais su lequel), 9 et 11 n'étaient pas officiellement affectés mais l'ont apparemment été non-officiellement.
Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : D. Thaler (Microsoft), R. Draves (Microsoft Research), A. Matsumoto (NTT), T. Chown (University of Southampton)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 12 septembre 2012
Lorsqu'une machine IPv6 a plusieurs adresses et qu'elle va initier une communication avec une autre machine ayant elle-même plusieurs adresses, quelle adresse choisir pour la source ? Et pour la destination ? Ce RFC donne deux algorithmes (un pour la source et un pour la destination) à suivre pour que la sélection d'adresse par défaut soit prévisible. Naturellement, il sera toujours possible, pour l'ingénieur système ou pour le programmeur, de passer outre ce choix par défaut et de choisir délibérement une autre adresse. Ce RFC remplace le RFC 3484.
Alors, quel est le problème ? En IPv6, il est courant d'avoir plusieurs adresses IP pour une machine (RFC 4291). Par exemple, si un site est multi-homé, les machines peuvent avoir une adresse par FAI. Ou bien il peut y avoir des tunnels, qui viennent avec leurs adresses. Toutes ces adresses peuvent avoir des caractéristiques variables : portée, statut (préférée, abandonnée, cf. RFC 4862), temporaire (pour des raisons de vie privée, cf. RFC 8981) ou pas... Voici un exemple sur une machine Debian ayant six adresses IPv6 :
% ip -6 addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000 inet6 2605:4500:2:245b::f00/64 scope global valid_lft forever preferred_lft forever inet6 2605:4500:2:245b::bad:dcaf/64 scope global valid_lft forever preferred_lft forever inet6 2605:4500:2:245b::42/64 scope global valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fed9:83b3/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000 inet6 fe80::5054:ff:fe9f:5bb1/64 scope link valid_lft forever preferred_lft forever
Il faudra donc un mécanisme pour décider de l'adresse source à utiliser.
Quant à la machine de destination, elle peut aussi avoir plusieurs adresses, par exemple plusieurs enregistrements AAAA sont dans le DNS. Il faudra donc aussi choisir l'ordre dans lequel on essaiera les adresses de destination. À noter que ce choix peut inclure le choix entre IPv6 et IPv4. Si les deux machines (source et destination) sont en double pile, va t-on utiliser IPv4 ou IPv6 ? (Notre RFC donne la préférence à IPv6 mais voyez plus loin pour les règles exactes.)
Notez que les deux algorithmes ne rendent donc pas le même type de résultat. Pour la destination, l'algorithme produit une liste d'adresses ordonnées, pouvant mêler IPv4 et IPv6. Pour la source, il produit une adresse, la meilleure, et forcément en IPv6 (la sélection d'une adresse source IPv4 est un problème intéressant mais non couvert par ce RFC).
Soit une application en C qui appelle la routine standard
getaddrinfo()
(RFC 3493) pour trouver les
adresses IP du correspondant. Dans le cas le plus fréquent, elle va
essayer toutes les adresses IP renvoyées par
getaddrinfo()
, dans l'ordre où ce dernier les a
renvoyées, et l'application ne spécifiera pas son adresse source
(c'est le cas simple : les variantes sont discutées plus loin). Pour
mettre en œuvre ce RFC, getaddrinfo()
va
utiliser l'algorithme de sélection de la destination, pour trier la
liste obtenue du DNS, et le noyau du système va
utiliser l'algorithme de sélection de la source pour décider de
l'adresse IP source, au moment du
connect()
.
À noter qu'essayer uniquement la première
adresse IP renvoyée par getaddrinfo()
serait une
mauvaise stratégie : si elle est injoignable, aucune communication ne
sera possible, alors que certaines des autres adresses marchaient
peut-être. Essayer les adresses de manière strictement séquentielle
n'est pas non plus optimum et le RFC 6555
conseille de le faire en partie de manière parallèle.
Si on veut résumer les deux algorithmes utilisés, on peut dire qu'ils préfèrent former des couples source/destination où les deux adresses ont la même portée, ont la portée la plus étroite possible, sont des adresses préservant la vie privée, et, en fin de compte, partagent le plus de bits de préfixe possibles.
Comme indiqué plus haut, cet algorithme pourra toujours être
surmonté par un choix explicite du programmeur comme la directive
outgoing-interface
d'Unbound (mal nommée puisque prenant comme
paramètre une adresse IP et pas une interface) ou comme, avec OpenSSH, l'option
-b
sur la ligne de commande (ou bien
BindAddress
dans le fichier de configuration). Ou bien un choix explicite de l'administrateur système
qui peut éditer une table des politiques (celle qui dit par exemple
que IPv6 est préféré à IPv4, ce qu'on peut changer), modifier la
préférence par défaut en faveur des adresses de préservation de la vie
privée, et permettre ou pas l'addition automatique de certaines
adresses à la table des politiques.
Que contient cette « table des politiques » ? La section 2.1 la
détaille. Elle stocke des préfixes d'adresses IP et, comme pour une
table de routage, c'est le plus spécifique (le plus long) qui
gagne. Sur un système Linux, c'est en général
le fichier /etc/gai.conf
qui contient la table,
fichier que l'administrateur système peut éditer selon ses goûts
(section 10.3 du RFC). La
table par défaut contient :
Prefix Precedence Label ::1/128 50 0 ::/0 40 1 ::ffff:0:0/96 35 4 2002::/16 30 2 2001::/32 5 5 fc00::/7 3 13 ::/96 1 3 fec0::/10 1 11 3ffe::/16 1 12
La préférence est donnée aux préfixes ayant le champ
Precedence le plus élevé. Ainsi, si on a le choix
entre les adresses 2001:db8:1::cafe
et
fec0::90ff:fe92:bd00
, la première a une
précédence de 40 (en raison de la règle ::/0
), la
seconde de 1 (en raison de la règle fec0::/10
) :
rappelez-vous que c'est le préfixe le plus spécifique qui est choisi,
pas celui qui est le premier dans la table). On va donc choisir
l'adresse publique, 2001:db8:1::cafe
(le préfixe
fec0::/10
a été abandonné par le RFC 3879).
Autre conséquence de cette table, IPv6 est préféré à
IPv4 (représenté par ::ffff:0:0/96
, cf. RFC 4291, section 2.5.5.2). Si on veut changer cela,
par exemple parce qu'on a une connectivité IPv6 vraiment trop mauvaise
(voir le problème des globes
oculaires et la section 10.3.1 de notre RFC), on édite gai.conf
ou son
équivalent et on met, par exemple (syntaxe de
gai.conf
) une précédence de 100 :
precedence ::ffff:0:0/96 100
D'autres trucs Linux sont documentés dans « IPv6
Source Address Selection on Linux ». Si on travaille
sur FreeBSD, la configuration est dans
/etc/ip6addrctl.conf
et
il faut donc regarder la
documentation
de ip6addrctl.
Notez que cette table peut être dynamique : une implémentation a le droit d'y ajouter des préfixes en cours de route, par exemple pour ses ULA (RFC 4193).
Autre définition importante, la notion de la longueur du préfixe
commun. Cette longueur est définie en comparant uniquement les 64
premiers bits de l'adresse. Ainsi, la longueur du préfixe commun à
2001:db8:1::bad
et
2001:db8:2::bad
est 32
(2001:db8
est la seule partie commune). Mais la
longueur du préfixe commun à 2001:db8:1::bad:dcaf
et 2001:db8:1::bad:cafe
n'est que de 64 et pas de
112 comme on pourrait le croire à première vue. C'est parce qu'on
ignore l'Interface ID (les 64 derniers bits). C'est
un des gros changements par rapport au précédent RFC, le RFC 3484, motivé par des problèmes comme une mauvaise
interaction avec des systèmes de répartition de charge..
Et les propriétés des adresses (section 3) ? On a entre autres :
fe80::35cd:efc1:e399:3aa9
a une portée inférieure
à 2001:4f8:3:2bc:1::64:21
.Maintenant, les algorithmes eux-mêmes. D'abord, pour le choix de
l'adresse source (sections 4 et 5). Il faut
d'abord établir une liste d'adresses candidates
pour la destination choisie. La méthode conseillée est que cet
ensemble de candidates soit la liste des adresses attachées à
l'interface réseau par laquelle les paquets vont sortir. Sur une
machine Linux, si on veut écrire à
::1
, ce sera l'interface locale
(lo
) et si on veut écrire à 2001:4860:4860::8888
, ce sera la plupart du temps
eth0
. Cela permet notamment de tenir compte des
filtres éventuels des routeurs (un FAI ne
laissera pas passer des paquets dont l'adresse source n'est pas chez
lui, cf. RFC 2827).
Une fois cette liste établie, il faut choisir l'adresse IP source (notez le singulier), parmi cet ensemble de candidates. Conceptuellement, il s'agit de trier la liste des candidates et, pour cela, il faut une fonction permettant de comparer ces adresses deux à deux. La définition de cette fonction est le cœur de notre RFC. Soient deux adresses SA et SB pour une destination D, ces huit règles permettent de les départager :
2001:db8:1::1
,
candidates source 2001:db8:3::1
et
fe80::1
, on choisira 2001:db8:3::1
,2001:db8:1::d5e3:0:0:1
et que les adresses
candidates sont 2001:db8:1::2
(publique) et
2001:db8:1::d5e3:7953:13eb:22e8
(temporaire), on
choisit 2001:db8:1::d5e3:7953:13eb:22e8
. Cette règle est un changement par rapport au
prédecesseur de notre RFC, le RFC 3484. Cette préférence doit
être réglable (sur Linux, c'est apparemment avec la variable sysctl
net.ipv6.conf.*.use_tempaddr
qui, mise à 1, alloue des adresses temporaires et, mise à 2, fait qu'elles sont préférées),2001:db8:1::1
et que les adresses source
possibles sont 2001:db8:1::2
(48 bits communs) et
2001:db8:3::2
(32 bits communs), on sélectionne 2001:db8:1::2
.Une implémentation a le droit de tordre certaine de ces règles si elle dispose d'informations supplémentaires. Par exemple, si elle suit la RTT des connexions TCP, elle peut connaître les « meilleures » adresses et ne pas utiliser la huitième règle (préfixe le plus long).
Maintenant, il faut choisir l'adresse de destination (section 6). Cette fois, le résultat est une liste d'adresses qui seront essayées dans l'ordre. Et, contrairement au précédent, cet algorithme gère IPv6 et IPv4 ensemble (les règles de sélection de la source n'étaient valables que pour IPv6 ; par exemple la règle du plus long préfixe commun n'a guère de sens avec les courtes adresses v4). Le point de départ est la liste d'adresses récupérées en général dans le DNS. Et il y a ensuite dix règles de comparaison entre les destinations DA et DB, en tenant compte des adresses sources, S(DA) et S(DB). Beaucoup de ces règles sont proches de celles utilisées pour la sélection de la source donc je ne les réexplique pas ici :
2001:db8:1::1
et
198.51.100.121
, avec comme adresses source
disponibles 2001:db8:1::2
,
fe80::1
et 169.254.13.78
,
alors le premier choix est 2001:db8:1::1
(source
2001:db8:1::2
) puis
198.51.100.121
(source
169.254.13.78
). Ce n'est pas une préférence pour
IPv6 (elle intervient plus tard, dans la sixième règle) mais une
conséquence du fait que l'adresse IPv4
169.254.13.78
est locale au lien (RFC 3927),2001:db8:1::1
ou
fe80::1
, et que les sources possibles sont
2001:db8:1::2
ou fe80::2
, on
préférera fe80::1
(avec la source fe80::2
),2001:db8:1::1
et
2001:db8:3ffe::1
, avec comme sources possibles
2001:db8:1::2
,
2001:db8:3f44::2
ou fe80::2
,
le premier choix est 2001:db8:1::1
(pour al
source 2001:db8:1::2
) puis
2001:db8:3ffe::1
(pour la source
2001:db8:3f44::2
),
Le lecteur subtil a noté que l'interaction de ces règles avec le routage IP normal n'est pas évidente. Le principe de base est qu'une machine sélectionne la route de sortie avant de sélectionner l'adresse source mais la section 7 de notre RFC autorise explicitement une implémentation d'IPv6 à utiliser l'adresse source pour le choix de la route.
Voilà, les deux algorithmes sont là. Mais, si vous voulez les
mettre en œuvre et pas seulement comprendre comment ils
marchent, la section 8 est une lecture recommandée, car elle donne de
bons conseils d'implémentation. Par exemple, comme l'algorithme de
sélection de la destination a besoin de connaître les adresses sources
possibles, le RFC suggère à
getaddrinfo()
de demander à la
couche 3, pour obtenir la liste des adresses
source possibles. Il sera alors capable de renvoyer une liste de
destinations déjà triée. Il peut même garder en mémoire cette liste
d'adresses, pour éviter de refaire un appel système supplémentaire à chaque fois. (Le RFC dit
toutefois que cette mémorisation ne devrait pas durer plus d'une
seconde, pour éviter d'utiliser une information dépassée.)
Et la sécurité (section 9) ? Il n'y a que des petits détails. Par exemple, en annonçant des tas d'adresses différentes pour lui-même, un méchant peut, en examinant les adresses source de ceux qui se connectent à lui, apprendre leur politique locale (pas une grosse affaire). Autre cas amusant, en sélectionnant soigneusement les adresses source ou destination, on peut influencer le chemin pris par les paquets, ce qui peut être utile par exemple pour sniffer. Mais c'est une possibilité très limitée.
Quels sont les changements de notre RFC 6724 par rapport à son prédécesseur, le RFC 3484 ? Ils sont détaillés dans l'annexe B. Les principaux (dans l'ordre à peu près décroissant d'importance) :
fc00::/7
),À noter que les premières versions de ce RFC étaient rédigées simplement sous forme d'une liste des différences avec le RFC 3484. C'était illisible.
Enfin, une anecdote, le prédécesseur, le RFC 3484, avait
été accusé
d'un problème sérieux. Mais c'est contestable,
les responsabilités sont partagées : l'algorithme du RFC 3484
(qui ne concerne qu'IPv6) est certes discutable, l'implémentation de
Vista n'est pas géniale (extension du RFC 3484 à IPv4, où les préfixes
sont bien plus courts), la configuration de l'auteur de l'article est
mauvaise (il dépend de l'ordre des enregistrements, qui n'est pas
garanti par le DNS, c'est la même erreur qu'un programmeur C qui
dépendrait de la taille d'un int
) et, pour couronner le tout, le NAT qui fait qu'une machine ne connait pas son adresse
publique.
Une intéressante discussion de certaines objections à ce RFC a eu lieu sur SeenThis.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : P. Hoffman (VPN Consortium)
Pour information
Première rédaction de cet article le 30 août 2012
Le fonctionnement et les particularités de l'IETF étaient traditionnellement décrits dans un RFC nommé Tao, à l'usage des débutants qui débarquaient dans ce monde merveilleux. Le dernier de ces RFC a été le RFC 4677 : désormais, pour évoluer plus facilement, le Tao est une page web ordinaire, régulièrement tenue à jour. Depuis, en juin 2024, le Tao a cessé d'être maintenu (cf. RFC 9592.
Le Tao est le document à lire absolument quand on débute à l'IETF. Il explique son fonctionnement, ses codes, ses rites, son jargon. L'IETF est à ma connaissance la seule SDO à le faire, ce qui est un gage d'ouverture. Le Tao a été d'abord publié comme RFC 1391, puis a connu de nombreuses évolutions jusqu'au RFC 4677. Mais les RFC, statiques et longs à faire publier, ne sont pas le canal idéal pour ce genre de documents, qui doit évoluer en permanence.
Désormais, le Tao est donc une page Web, et contrôlée par l'IESG, qui sera donc l'autorité responsable pour son contenu. Actuellement, cette page est encore très proche du RFC 4677 mais elle va petit à petit s'en éloigner.
Si vous voulez participer à la maintenance du Tao, cela se fait sur
la liste de diffusion
tao-discuss@ietf.org
. Un éditeur (actuellement
Paul Hoffman) décide ensuite des changements qui seront transmis à
l'IESG (cette proposition est visible en
ligne). L'IESG accepte ou refuse les changements et le
secrétariat n'a plus qu'à éditer la page.
Le Tao est versionné (la version d'aujourd'hui est 20120829
)
et on peut accéder aux
versions précédentes (dès qu'il y en aura plusieurs). On a donc
des identificateurs stables pour les précédentes
versions (toutes les organisations qui publient des documents
devraient en faire autant).
Il existe des traductions du Tao qu'on trouve ici ou là mais le RFC note qu'elles sont toutes non-officielles (et souvent pas à jour). Par exemple, en français, on trouve une traduction du RFC 3160 ou bien la traduction de l'ISOC-Togo.
La section 3 du RFC couvre les propositions alternatives : certains auraient préféré un wiki pour des modifications plus rapides ou plus souples, mais le choix a finalement été de privilégier la sécurité.
Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : J. Snell
Chemin des normes
Première rédaction de cet article le 26 septembre 2012
Le format Atom, normalisé dans le RFC 4287, est surtout utilisé pour la syndication de contenus Web. Dans ce cas, si une entrée d'un flux Atom n'est plus publiée (remords de l'auteur ou autre raison), le client Atom n'avait pas de moyen de le savoir. Désormais, avec l'extension de ce RFC, surnommée « pierre tombale », on peut indiquer que l'absence d'une entrée est délibérée.
Rappelez-vous qu'un flux de syndication comporte un certain nombre d'entrées mais rarement la totalité des articles d'un site Web (dans le flux de ce blog, par défaut, les articles des quatre derniers mois). On ne peut donc pas dire, lorsqu'un article n'a pas d'entrée dans le flux Atom, si l'article a été supprimé ou simplement s'il n'a pas été inclus dans le flux. Si, par exemple, l'entrée a été gardée dans la mémoire locale du client de syndication, elle risque d'y rester même si l'article original a disparu du site.
Pour éviter cela, ce RFC ajoute un nouvel élément
XML à Atom. Il est défini avec la syntaxe
Relax NG (l'espace de noms XML abrégé en
at
est http://purl.org/atompub/tombstones/1.0
) :
deletedEntry = element at:deleted-entry { atomCommonAttributes, attribute ref { atomUri }, attribute when { atomDateConstruct }, ( element at:by { atomPersonConstruct }? & element at:comment { atomTextConstruct }? & element atom:link { atomLink }* & element atom:source { atomSource }? & anyElement* ) }
On note donc que la référence de l'article détruit
(ref
) est obligatoire. Elle correspond à
l'attribut id
d'un flux Atom, qui a la forme d'un
URI. Ainsi, cet article que vous êtes en train
de lire a l'id
tag:bortzmeyer.org,2006-02:Blog/6721
et une
pierre tombale, si je supprimais cet article, comporterait
<at:deleted-entry
ref="tag:bortzmeyer.org,2006-02:Blog/6721" ...
.
Comme l'attribut ref
, l'attribut
when
est obligatoire et contient la date et
l'heure de destruction (au format du RFC 3339). Il est particulièrement utile si une entrée est
détruite puis recréée : en examinant les dates, un client Atom peut
savoir quel est l'évènement le plus récent (la suppression ou la
création) et ignorer les autres.
Les autres attributs de l'élement
at:deleted-entry
sont facultatifs. C'est le cas
par exemple de comment
qui permet d'ajouter une
explication en texte libre. Voici, tiré du RFC, un exemple minimal :
<at:deleted-entry ref="tag:example.org,2005:/entries/1" when="2005-11-29T12:11:12Z"/>
et un exemple plus complet :
<at:deleted-entry ref="tag:example.org,2005:/entries/2" when="2005-11-29T12:11:12Z"> <at:by> <name>John Doe</name> <email>jdoe@example.org</email> </at:by> <at:comment xml:lang="la">Lorem ipsum dolor</at:comment> </at:deleted-entry>
Notez bien que l'élement at:deleted-entry
n'est qu'indicatif : on ne peut évidemment pas garantir qu'un client
Atom facétieux ne va pas conserver localement (et même redistribuer)
des entrées qu'il avait gardé dans son cache et
qui ont été détruites dans le flux original.
Autre piège de sécurité : un client Atom ne doit pas croire
aveuglément tous les at:deleted-entry
qu'il
rencontrerait sur le Web ! Car un méchant peut toujours publier des
pierres tombales pour un autre site que le sien. Il faut donc vérifier
l'origine (la pierre tombale doit être dans le même flux que l'article
original, ce qui peut poser des problèmes avec les
agrégateurs et autres redistributeurs) et/ou
vérifier les signatures cryptographiques
attachées (avec XML Signature).
Cette extension est mise en œuvre au moins dans AtomBeat (voir leurs intéressants exemples d'usage).
Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : JM. Valin (Mozilla Corporation), K. Vos (Skype Technologies), T. Terriberry (Mozilla Corporation)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF codec
Première rédaction de cet article le 11 septembre 2012
Il y a désormais plus de deux ans que le groupe de travail codec de l'IETF avait commencé un effort inédit de spécification d'un codec audio libre. Ce nouveau RFC est le couronnement de cet effort : Opus, le codec standard et libre est désormais officiel.
Opus n'est pas un format de fichiers, comme MP3. Il est conçu pour l'audio en temps réel (RFC 6366 pour son cahier des charges). Il est prévu pour un grand nombre d'utilisations audio distinctes : téléphonie sur IP, mais aussi, par exemple, distribution de musique en temps réel. Il est prévu pour être utilisable lorsque la capacité du réseau est minimale (dans les 6 kb/s) aussi bien que lorsqu'elle permet de faire de la haute fidélité (mettons 510 kb/s, cf. section 2.1.1). Ses deux principaux algorithmes sont la prédiction linéaire (plus efficace pour la parole) et la transformation en cosinus discrète (plus efficace pour la musique).
Le projet codec avait déjà produit deux RFC : le RFC 6366 était le cahier des charges du nouveau codec, et le RFC 6569 posait les principes de développement et d'évaluation dudit codec. Je renvoie à ces documents pour l'arrière-plan de la norme Opus. Celle-ci a été acceptée sans problèmes par le groupe de travail (c'est plutôt le mécanisme de tests qui a suscité des controverses.)
Opus présente une particularité rare à l'IETF : la norme est le code. Habituellement, à l'IETF, la norme est le texte du ou des RFC, rédigés en langue naturelle. Il existe souvent une implémentation de référence mais, en cas de désaccord entre cette implémentation et le RFC, c'est ce dernier qui gagne et le programme doit être modifié. Pour Opus, c'est tout le contraire. La moitié du RFC 6716 (180 pages sur 330, en annexe A, soit 30 000 lignes de code pas toujours bien commentées et avec plein de nombres magiques) est constituée par l'implémentation de référence (en C, langage que le RFC qualifie de « lisible par un humain », ce qui est parfois optimiste) et c'est elle qui fait autorité en cas de différence avec l'autre moitié, les explications (voir sections 1 et 6 du RFC). Ce point a suscité beaucoup de débats à l'IETF et on trouve trace des critiques, entre autres, dans l'évaluation détaillée qui avait été faite pour GenArt. L'idée de ce choix « le code est la norme » était que l'alternative (faire une spécification en langue naturelle, complète et sans ambiguité), serait bien plus de travail et, dans le cas particulier d'un codec audio, serait peut-être même irréaliste. (À noter que seul le décodeur est normatif. On peut améliorer la sortie de l'encodeur, tant que le décodeur arrive à lire ce qu'il produit.)
Le langage C étant ce qu'il est, il n'est pas étonnant que des bogues aient été découvertes depuis, corrigées dans le RFC 8251.
L'autre moitié du RFC est composé d'explications, avec beaucoup de maths.
Un codec libre est difficile à obtenir, surtout vu le nombre de brevets, la plupart futiles, qui encombrent ce domaine. Plusieurs déclarations de brevet ont été faites contre Opus : #1520, #1524, #1526, #1602, #1670, #1712 et #1741. Une liste mise à jour est disponible à l'IETF.
Comme ces codecs sont très loin de mes domaines de compétence, je ne vais pas me lancer dans des explications détaillées du fonctionnement d'Opus : lisez le code source :-) Notez que le code fait beaucoup d'arithmétique en virgule fixe (et aussi avec des entiers, bien sûr) donc attention si vous le reprogrammez dans un autre langage, les calculs doivent être exacts (voir section 1.1).
Si vous n'avez pas l'ambition de reprogrammer Opus, si vous voulez simplement une idée générale de son fonctionnement, la section 2 est faite pour vous. Opus, comme indiqué plus haut, a deux « couches », LP (prédiction linéaire) et MDCT (transformée en cosinus discrète). L'une ou l'autre (ou même les deux en même temps) est active pour encoder le signal audio, donnant ainsi à Opus la souplesse nécessaire. La couche LP est dérivée du codec Silk. Elle permet le débit variable mais aussi le constant (section 2.1.8). La couche MDCT, elle, est basée sur CELT.
Le codec Opus peut favoriser la qualité de l'encodage ou bien la consommation de ressources (processeur, capacité réseau). Cela permet d'ajuster la qualité du résultat aux ressources disponibles (section 2.1.5). Idem pour la sensibilité aux pertes de paquets : Opus peut être ajusté pour mettre plus ou moins de redondance dans les paquets. Avec le moins de redondance, on augmente la capacité mais on rend le décodage plus sensible : un paquet perdu entraîne une coupure du son.
Le format des paquets est décrit en section 3. À noter qu'Opus ne met pas de délimiteur dans ses paquets (pour gagner de la place). Il compte qu'une couche réseau plus basse (UDP, RTP, etc) le fera pour lui. Une possibilité (optionnelle dans les implémentations) de formatage avec délimiteur figure dans l'annexe B.
Chaque paquet compte au moins un octet, le TOC (Table Of Contents). Celui-ci contient notamment 5 bits qui indiquent les configurations (couches utilisées, capacité réseau utilisée et taille des trames).
Le fonctionnement du décodeur est en section 4 et celui de
l'encodeur en section 5. Mais le programmeur doit aussi lire la
section 6, qui traite d'un problème délicat, la conformité à la
spécification. Je l'ai dit, la référence d'Opus est un programme,
celui contenu dans ce RFC. Cela n'interdit pas de faire d'autres mises
en œuvre, par exemple à des fins d'optimisation, à condition qu'elles soient compatibles avec
le décodeur (c'est-à-dire que le décodeur de référence,
celui publié dans l'annexe A du RFC, doit pouvoir lire le flux audio produit
par cette mise en œuvre alternative). Pour aider aux tests, des
exemples (testvectorNN.bit
) et un outil de comparaison,
opus_compare
, sont fournis avec
l'implémentation de référence (les tests sont en https://opus-codec.org/testvectors/
). Un outil de comparaison est nécessaire
car il ne suffit pas de comparer bit à bit la sortie de l'encodeur de
référence et d'un nouvel encodeur : elles peuvent différer, mais dans
des marges qui sont testées par opus_compare
. Si
vous avez écrit votre propre encodeur, ou modifié celui de référence, les
instructions pour tester figurent en section 6.1.
Autre avertissement pour les programmeurs impétueux que les 150 pages d'explication et les 180 pages de code n'ont pas découragés : la sécurité. Opus est utilisé sur l'Internet où on trouve de tout, pas uniquement des gens gentils. La section 7 met donc en garde le programmeur trop optimiste et lui dit de faire attention :
Le compte-rendu des tests divers se trouve dans l'Internet-Draft draft-ietf-codec-results
.
L'annexe A contient le code source de l'implémentation de référence
encodée en Base64
(qu'on trouve également en ligne sur le site
Web officiel et qui est distribuée par
git en git://git.xiph.org/opus.git
). Par défaut,
elle dépend de calculs en virgule flottante
mais on peut la compiler avec la macro
FIXED_POINT
pour ne faire que de la virgule fixe
(voir le fichier README
).
Voici un exemple d'utilisation avec la version de développement (il
n'y en avait d'autre prête à ce moment)
% export VERSION=1.0.1-rc2 % wget http://downloads.xiph.org/releases/opus/opus-$VERSION.tar.gz ... % tar xzvf opus-$VERSION.tar.gz ... % cd opus-$VERSION % ./configure ... % make ... % make check ... All 11 tests passed ...
Il n'existe pas à l'heure actuelle d'autre mises en œuvre d'Opus.
Combien de logiciels intègrent actuellement le code Opus pour lire et produire des flux audios ? Difficile à dire. L'excellent client SIP Csipsimple a Opus depuis plusieurs mois. Autre exemple, le logiciel de voix sur IP Mumble l'a promis pour bientôt.
Un bon article en français sur Opus, notamment ses performances :
« Un
codec pour les dominer tous ». Et un article de synthèse de Numérama sur ce RFC. Pour une comparaison des
performances d'Opus avec les autres, voir https://www.opus-codec.org/comparison/
. Pour les nouveautés de
la version 1.1 (publiée après le RFC), voir la liste officielle.
Merci à Régis Montoya pour sa relecture.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : J.R. Levine (Taughannock Networks)
Pour information
Première rédaction de cet article le 25 août 2012
Encore un RFC qui comble un manque
ancien. Les types MIME
application/gzip
et
application/zlib
n'avaient jamais été
formellement enregistrés. Voici qui est fait.
Ces deux types apparaissent désormais dans le
registre IANA avec ce RFC 6713 comme référence. Rien
de nouveau, ils étaient déjà utilisés dans de nombreuses
applications. (Parfois, des types non officiels étaient utilisés comme
application/x-gzip
ou encore des trucs comme application/gzipped
.)
Pour ceux qui veulent apprendre ces deux techniques de compression, Zlib est spécifié dans le RFC 1950 (et a un site « officiel ») et Gzip est dans le RFC 1952 et a aussi son site. Les deux techniques sont très proches (utilisant l'algorithme Deflate du RFC 1951), la principale différence étant que Gzip inclut un en-tête et une terminaison. Il est donc plus adapté pour les fichiers (et Zlib pour le streaming).
Ah, au fait, soyez prudent : comme le dit l'inévitable section Security Considerations, les données comprimées récupérées sur l'Internet (qui est, comme le dit le sage Beigbeder, « l'empire de la méchanceté, de la bêtise ») peuvent être trompeuses. Elles peuvent prétendre être en Zlib ou en Gzip et comporter des erreurs, des pointeurs ne pointant pas au bon endroit, des champs Longueur qui n'indiquent pas la longueur, et autres choses qui peuvent mener à des accidents comme le dépassement de tampon. Programmeurs, attention.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Melnikov (Isode), K. Carlberg (G11)
Chemin des normes
Première rédaction de cet article le 26 août 2012
Des tas d'utilisateurs du courrier électronique souhaiteraient un mécanisme de priorité,
permettant de dire que tel message est plus important que tel autre et
devrait être traité en premier. Après tout, les ressources (par
exemple la capacité disponible dans le réseau) sont souvent
insuffisantes et il serait souhaitable que les messages vraiment
urgents en profitent avant les informations envoyées par
Twitter (« vous avez un nouvel abonné »). Il n'existait pas jusqu'à présent,
pour un serveur de messagerie, de
moyen standard en SMTP de dire à un de ses
pairs quelle était la priorité d'un message. C'est désormais fait
grâce à la nouvelle extension SMTP
MT-PRIORITY
.
Dans les en-têtes du message (le format des messages est normalisé
dans le RFC 5322), il existait un en-tête
standard, Priority:
, décrit dans le RFC 2156. Ce dernier avait à l'origine été écrit
pour assurer l'interfaçage avec X.400. Ce
système avait été un échec complet mais l'en-tête
Priority:
garde son utilité (on trouve aussi
souvent un en-tête non officiel et n'ayant pas exactement la même
sémantique, notamment par le nombre de niveaux et leur représentation,
X-Priority:
.) Par contre,
l'inconvénient de noter la priorité dans le message est que cela
oblige les MTA à analyser les en-têtes, ce qui
n'est pas normalement leur rôle. De manière cohérente avec l'évolution
du courrier électronique depuis quinze ans (meilleure séparation entre
le format du RFC 5322 et le transport normalisé dans le RFC 5321), la priorité est désormais exprimable lors de la
session SMTP. (Un autre
RFC en cours d'écriture, draft-melnikov-smtp-priority-tunneling
, utilisera un nouvel
en-tête, MT-Priority:
, pour le cas où on doive tunneler des
messages prioritaires au dessus de MTAs qui ne gèrent pas les
priorités.) Par exemple, un MTA dont les files d'attente d'envoi de
messages sont grandes, pourra mettre au début de la file les messages
de plus forte priorité.
Notez bien que c'est une priorité, donc
relative (« ce message est très urgent, celui-ci
l'est moins ») pas d'une garantie de délai. Le courrier électronique
demeure « au mieux », sans délais certains. Les annexes de ce RFC
contiennent des discussions plus en détails sur certaines utilisations
de ces priorités. Si on ne se satisfait pas de la délivrance « au
mieux », il faut utiliser une autre extension SMTP
(DELIVERBY
dans le RFC 2852 et section
5.2 de notre RFC 6710) ou regarder du côté de techniques réseaux comme
DiffServ (RFC 2474).
Notez aussi que l'une des raisons du peu de déploiement effectif de
l'en-tête Priority:
est un problème de
confiance (comme souvent quand on prétend faire
de la qualité de service : tout le monde va
demander la qualité maximale). Rien ne garantit que celui qui met dans
ses messages Priority: urgent
le fait à bon
escient, peut-être ajoute-t-il systématiquement cette indication pour
que ses messages aillent plus vite. Notre RFC 6710 précise
donc bien que le MTA récepteur n'est pas obligé
d'honorer les priorités de n'importe qui. Il peut ne le faire que
lorsqu'il connait l'expéditeur et lui fait confiance (voir les
mécanismes utilisés en sections 4.1 et 5.1).
Maintenant, les détails techniques (section 3) : la nouvelle extension SMTP se
nomme Priority Message Handling et est annoncée par
le mot-clé MT-PRIORITY
lors de la connexion
SMTP. Par exemple (S indique le serveur et C le client) :
S: 220 example.com SMTP server here C: EHLO mua.example.net S: 250-example.com S: 250-AUTH STARTTLS S: 250-AUTH SCRAM-SHA-1 DIGEST-MD5 S: 250-SIZE 20000000 S: 250-DSN S: 250-ENHANCEDSTATUSCODES S: 250 MT-PRIORITY MIXER
(Le paramètre MIXER
est le nom d'une politique de
priorités et est expliqué plus loin, section 9.2.)
La priorité du message est annoncée par un paramètre de la commande
MAIL FROM
également nommé
MT-PRIORITY
. Elle va de -9 (plus faible priorité)
à 9 (priorité la plus élevée). Par exemple :
C: MAIL FROM:<eljefe@example.net> MT-PRIORITY=6 S: 250 2.1.0 <eljefe@example.net> sender ok C: RCPT TO:<topbanana@example.com> S: 250 2.1.5 <topbanana@example.com> recipient ok
En pratique, tous les serveurs ne géreront pas forcément 19 niveaux distincts (il n'y en avait que 3 dans le RFC 2156). L'annexe E explique pourquoi ce choix de 19.
Cette extension est utilisable aussi bien pendant la soumission (RFC 6409) que pendant la transmission (RFC 5321), ainsi qu'en LMTP (RFC 2033).
Lorsque le MTA « serveur » gérant cette extension reçoit un message ayant une priorité
explicite, il va le traiter en fonction de cette priorité. Par défaut,
la priorité est de zéro (d'où le choix d'avoir des priorités
négatives, on voit tout de suite si la priorité est plus ou moins
importante que celle par défaut, voir annexe E pour les raisons de ce
choix). En prime, le MTA va noter cette priorité dans l'en-tête
Received:
qu'il va ajouter au message. Avant
cela, le MTA aura du toutefois vérifier l'émetteur : le RFC précise
qu'on peut accepter des priorités négatives de n'importe qui mais
qu'on ne devrait accepter des positives (élevant le niveau de
priorité) que des émetteurs qu'on a authentifiés d'une manière ou
d'une autre, et à qui on fait confiance. Autrement, il serait facile
de réclamer systématiquement la plus haute priorité (9), épuisant
ainsi les ressources du serveur. Un exemple
d'une politique d'autorisation pourrait être « n'accepter de priorités
positives que depuis les utilisateurs authentifiés avec la commande
AUTH
- RFC 4954 - ainsi que depuis les MTA dont
l'adresse IP a été mise dans une liste blanche,
suite à un accord bilatéral avec leur gérant ». (Voir aussi les sections
5.1 et 11.)
Naturellemnt, un MTA peut avoir des politiques plus complexes comme
de modifier automatiquement la priorité demandée en fonction de
l'émetteur (« maximum 3 pour
2001:db8:666::1:25
»). Il doit dans ce cas
prévenir l'émetteur en réponse au MAIL FROM
:
C: MAIL FROM:<eljefe@example.net> MT-PRIORITY=6 ... S: 250 X.3.6 3 is the new priority assigned to the message
Lorsqu'un serveur transmet un message à un autre serveur SMTP, il
inclut la priorité, sauf évidemment si l'autre serveur n'a pas annoncé
qu'il gérait les priorités (extension
MT-PRIORITY
).
Les considérations pratiques liées au déploiement de cette
extension MT-PRIORITY
figurent dans la section
9. Ainsi, si on a plusieurs serveurs de courrier pour un même domaine
(via plisieurs enregistrements MX), le RFC
recommande de veiller à ce que tous ou aucun acceptent l'extension de
gestion de la priorité. Autrement, des problèmes difficiles à déboguer
vont survenir. (De toute façon, avoir plusieurs enregistrements MX est
complexe et déconseillé pour les petits
domaines, exactement pour ce genre de raisons.)
J'ai parlé un peu plus haut du paramètre « Nom de la politique de
priorité » qu'un serveur peut ajouter lorsqu'il indique qu'il gère les
priorités. La section 9.2 décrit plus en détail ce que cela
signifie. L'idée est que différentes organisations vont avoir des
politiques de priorité différentes : nombre de niveaux,
notamment. L'idée est de donner un nom à ces politiques afin de
permettre à un serveur d'indiquer quelle politiques il suit. Par
exemple, si le serveur a une politique qui ne gère que trois niveaux,
-1, 0 et 1, un message indiquant qu'il a réduit la priorité demandée
de 3 à 1 n'est pas inquiétant. Il est recommandé d'enregistrer les
politiques à l'IANA
(la section « SMTP PRIORITY extension Priority Assignment
Policy »). Ce nouveau registre est rempli selon la règle
« Norme nécessaire » du
RFC 5226. Il comprend actuellement trois
politiques, issues de normes existantes. Par défaut, la politique
appliquée est MIXER
qui est celle du RFC 2156 et reprise dans l'annexe B de notre RFC 6710 :
trois niveaux de priorité seulement (-4, 0 et 4), pas de valeurs numériques définies par
défaut pour les tailles maximales des messages ou pour les délais de retransmission.
Deux autres annexes décrivent des utilisations des priorités, avec
la politique associée. L'annexe A concerne l'usage militaire
(politique STANAG4406
, six niveaux, les
deux plus urgents étant étiquetés Flash et
Override). Et l'annexe C concerne les services
d'urgence (RFC 4190 et RFC 4412). Un avis personnel : il n'est sans doute
pas sérieux
d'utiliser le courrier électronique sur
l'Internet public pour des appels aux pompiers
ou des messages militaires alors que l'ennemi attaque.
Puisqu'on a parlé de l'IANA, outre ce nouveau registre, les enregistrements suivants ont été faits (section 10) :
MT-PRIORITY
a été ajouté aux
extensions SMTP (la section « SMTP Service
Extensions »).Et questions mises en œuvre ? Aujourd'hui, un
Postfix typique, par exemple, ne gère pas
encore ces priorités (et répond 555 5.5.4 Unsupported
option: MT-PRIORITY=3
si on essaie.) Il existe apparemment déjà
trois MTA qui ont en interne ce concept de priorité et qui, en
l'absence de norme, la déterminaient de manière non-standard. Ils
n'ont pas encore été adaptés à ce RFC. Pour cela, l'annexe D donne
d'intéressants avis sur les stratégies d'implémentation possibles.
Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : B. Carpenter, B. Aboba, S. Cheshire
Pour information
Première rédaction de cet article le 15 septembre 2012
Concevoir des protocoles de communication monolithiques qui n'évoluent jamais est une chose. Concevoir des protocoles qui soient extensibles, qui puissent, après leur conception initiale, évoluer par le biais d'extensions, est un exercice plus difficile. Cet excellent RFC de l'IAB décrit comment faire un protocole extensible et comment assurer ainsi une évolution heureuse. C'est un document avant tout destiné aux auteurs de protocoles, mais qui intéressera aussi les étudiants en réseaux informatiques et tous les techniciens curieux, qui veulent savoir comment ça marche.
Parmi les innombrables exemples de protocoles IETF qui ont été étendus, on peut citer les extensions d'internationalisation de SMTP dans le RFC 6531, la recherche floue dans IMAP avec le RFC 6203, ou les capacités BGP du RFC 5492.
Le RFC 5218 (section 2.2.1), qui décrivait les raisons du succès pour un protocole réseau, notait parmi celles-ci l'extensibilité. Beaucoup de protocoles IETF ont des mécanismes pour cette extensibilité, qui est largement reconnue comme un bon principe. Mais, si elle est mal faite, des ennuis peuvent survenir, et cela peut menacer l'interopérabilité, voire la sécurité. Le RFC sur SMTP, le RFC 5321, note ainsi (section 2.2.1) que les protocoles avec peu d'options sont partout et que ceux avec beaucoup d'options sont nulle part. Un RFC comme le RFC 1263 (consacré aux extensions de TCP) critiquait également l'abus des extensions, et ce dès 1991. Malgré cela, d'innombrables RFC normalisent des extensions à tel ou tel protocole, mais il n'existait pas encore de document d'architecture sur le principe des extensions, rôle que ce RFC ambitionne de jouer.
D'abord, une distinction importante (section 2) entre extension « majeure » et « de routine ». Les secondes sont celles qui ne modifient pas le protocole de manière substantielle (et peuvent donc être introduites avec un minimum d'examen), les premières changent le protocole sérieusement et doivent donc être étudiées de près. Le problème est particulièrement aigu si l'extension est faite par d'autres personnes que le protocole originel : les « extensionneurs » risquent de ne pas connaître certaines règles non écrites que les auteurs originaux avaient en tête. Pour éviter cela, la spécification originale d'un protocole devrait toujours expliciter les règles, et décrire comment étendre le protocole proprement.
Comment distinguer une extension majeure d'une extension de routine ? Les extensions majeures sont celles qui peuvent empêcher l'interopérabilité (la capacité de deux pairs à communiquer), perturber le fonctionnement de l'Internet, ou mettre en péril la sécurité. Cela se produit notamment :
Foobar
sur un octet et que, les 256 valeurs étant
occupés, on passe à un champ de deux octets, les nouvelles mises en
œuvre ne pourront pas parler aux anciennes, tout l'en-tête étant
décalé à partir de ce champ (uniquement pour un
octet ajouté). Il existe des méthodes pour éviter ces problèmes (par
exemple utiliser des TLV au lieu des champs de
taille fixe) mais elles ont aussi des inconvénients (de performance,
par exemple) et, de toute façon, nécessitent d'avoir été mises dès le
début dans le protocole. Un autre exemple est celui d'un protocole où
les messages ont un type et où tout type inconnu fait couper la
communication. Dans ce cas, ajouter un type de message, même
optionnel, représente une extension majeure (là aussi, il existe des
solutions, comme de spécifier dès le début que les messages de type
inconnu doivent être silencieusement ignorés, cf. section 4.7).Et les extensions de routine, alors, elles ressemblent à quoi ?
Une extension de routine ne nécessitera aucun changement sur les vieux programmes. Seuls ceux qui voudront utiliser la nouvelle extension auront à être modifiés.
Quelques exemples d'extensions de routine : les options spécifiques
à un fournisseur de DHCP (RFC 2132),
les options spécifiques à un fournisseur de
Radius (RFC 2865), les
types MIME de l'arbre vnd
(vendor), etc. Ce n'est que lorsqu'on est sûr que
l'ajout d'une extension ne sera que de la routine qu'on peut avoir des
politiques du genre « premier arrivé, premier servi » (RFC 5226), c'est-à-dire peu ou pas d'examen préalable. Et
encore, l'expérience a montré que même les extensions de routine
pouvaient poser des problèmes inattendus et qu'un examen de toutes les
extensions par un expert est souvent une bonne chose.
Une fois posée cette importante distinction entre extensions de routines et extensions majeures, la section 3 de notre RFC s'attache des bons principes architecturaux pour assurer une extensibilité heureuse :
Premier principe, limiter l'extensibilité. Il faut essayer de ne traiter que les cas les plus courants et ne pas chercher l'extensibilité à tout prix. C'est évidemment plus facile à dire qu'à faire. Comme le note le RFC 5218, un protocole qui rencontre un « succès fou » est utilisé dans des contextes que ses concepteurs n'imaginaient pas. Alors, essayer de déterminer à l'avance les extensions qui vont être vraiment utiles... On peut donc être amené à réviser le mécanisme d'extension en cours de route.
Deuxième principe, l'interopérabilité, c'est-à-dire la capacité de deux mises en œuvre complètement différentes du même protocole à communiquer. Le RFC 4775 (section 3.1) insiste sur ce concept, qui est au cœur de la mission de l'IETF. Une extension qui empêcherait les nouveaux programmes de communiquer avec les anciens casserait cette interopérabilité et serait donc inacceptable.
D'autres familles de protocole que la famille TCP/IP avaient une approche différente : le protocole était tellement bourré d'options très larges que deux mises en œuvre toutes les deux conformes à la norme pouvaient néanmoins ne pas pouvoir communiquer car elles n'implémentaient pas les mêmes options. C'est ce qui est arrivé aux protocoles OSI et la solution adoptée avait été de créer des profils (un ensemble d'options cohérent), créant ainsi autant de protocoles que de profils (les profils différents n'interopéraient pas même si, sur le papier, c'était le même protocole). Notre RFC dit clairement que ces profils ne sont pas une solution acceptable. Le but est d'avoir des protocoles qui fonctionnent sur tout l'Internet (alors qu'OSI avait une vision beaucoup plus corporate où il n'était pas prévu de communications entre groupes d'utilisateurs différents).
En pratique, pour assurer cette interopérabilité, il faut que le mécanisme d'extension soit bien conçu, avec notamment une sémantique claire (par exemple, précisant ce que doit faire un programme qui rencontre un message d'un type inconnu, ou bien un message d'un type qui ne correspond pas à ce qu'il devrait recevoir dans son état actuel).
Le RFC note aussi qu'écrire les plus belles normes ne suffira pas si elles sont mal mises en œuvre. On constate que les problèmes liés aux extensions sont souvent dus à des implémentations qui ne le gèrent pas correctement. Un exemple est celui des options d'IP qui, bien que clairement spécifiées dès le début (RFC 791), ne sont toujours pas partout acceptées en pratique.
Et puisqu'on parle d'interopérabilité, une idée qui semble bonne mais qui a créé beaucoup de problèmes : les extensions privées. Pas mal de programmeurs se sont dit « de toute façon, ce système ne sera utilisé que dans des réseaux fermés, tant pis pour l'interopérabilité sur le grand Internet, je peux, sur mon réseau, ajouter les extensions que je veux ». Mais les prédictions ne sont que rarement 100 % vraies. Les ordinateurs portables, les smartphones et autres engins se déplacent, et les implémentations ayant des extensions privées se retrouvent tôt ou tard à parler aux autres et... paf. Même chose lorsque deux extensions privées rentrent en collision, par exemple à la suite de la fusion de deux entreprises. Imaginons que chacune d'elles ait choisi de mettre du contenu local dans un attribut DHCP de numéro 62, en pensant que, DHCP n'étant utilisé que sur le réseau local, cela ne gênerait jamais. Des années après, une des deux entreprises rachète l'autre, les réseaux fusionnent et... repaf.
Pour résoudre ce problème, on a parfois fait appel à des espaces réservés comme le fameux préfixe « X- » devant le nom d'un paramètre (RFC 822). Le RFC 6648 a mis fin à cette pratique (qui était déjà retirée de plusieurs RFC), notamment parce que les paramètres « privés », tôt ou tard, deviennent publics, et qu'alors les ennuis commencent.
Un problème proche existe pour les paramètres considérés comme « expérimentaux ». Ils ont leur utilité, notamment pour que les programmeurs puissent tester leurs créations. C'est ainsi que le RFC 4727 propose des valeurs pour les expérimentations avec de nouveaux protocoles de transport, des nouveaux ports, etc. Le RFC 3692 décrit plus en détail les bonnes pratiques pour l'utilisation de valeurs expérimentales. Elles doivent être strictement limitées au système en cours de test, et jamais distribuées sur l'Internet. Si l'expérience est multi-site, c'est une bonne raison pour ne pas utiliser de valeurs expérimentales. C'est ainsi que des expériences comme HIP et LISP ont obtenu des paramètres enregistrés, non expérimentaux, pour pouvoir être testés en multi-sites.
À noter que ces valeurs expérimentales ne sont nécessaires que
lorsque l'espace disponible est limité. Le champ Next
header
d'IPv6 ne fait qu'un octet et
il est donc logique de bloquer deux valeurs réutilisables, 253 et 254,
pour expérimenter avec des valeurs non officiellement
enregistrés. Mais ce n'est pas le cas, par exemple, des champs de
l'en-tête HTTP, composés d'un grand nombre de
caractères et permettant donc des combinaisons quasi-infinies. Si on
expérimente avec HTTP, il y a donc peu de raisons de réserver des
champs expérimentaux.
Troisième principe architectural, la compatibilité avec le protocole de base. Elle implique un double effort : les auteurs du protocole original doivent avoir bien spécifié le mécanisme d'extensions. Et les auteurs d'extensions doivent bien suivre ce mécanisme. Quelques exemples de protocole où le mécanisme d'extensions est documenté en détail : EPP (RFC 3735), les MIB (RFC 4181), SIP (RFC 4485), le DNS (RFC 2671 et RFC 3597), LDAP (RFC 4521) et Radius (RFC 6158).
Quatrième principe d'architecture, faire en sorte que les extensions ne mènent pas à une scission, avec apparition d'un nouveau protocole, incompatible avec l'original. Des changements qui semblent très modérés peuvent empêcher l'interopérabilité, ce qui serait de facto un nouveau protocole. Un protocole trop extensible peut donc ne pas être une si bonne idée que cela, si cette extensibilité va jusqu'à la scission.
Comme le note le RFC 5704, écrit dans le contexte d'une grosse dispute entre l'IETF et l'UIT, la scission (fork) peut venir de l'action non coordonnée de deux SDO différentes. Mais il n'y a pas toujours besoin d'être deux pour faire des bêtises : le RFC 5421 réutilisait un code EAP, rendant ainsi le protocole incompatible avec la précédente version. L'IESG avait noté le problème (documenté dans la section IESG Note du RFC 5421) mais avait laissé faire.
Cette notion de scission est l'occasion de revenir sur un concept vu plus haut, celui de profil. Il y a deux façons de profiler un protocole :
Contrairement à la première, la seconde approche peut être une bonne idée. En réduisant le nombre de choix, elle peut améliorer l'interopérabilité. Par contre, retirer des obligations est presque toujours une mauvaise idée. Ces obligations, dans un RFC (les fameux MUST, SHOULD et MAY), sont décrites avec les conventions du RFC 2119 et ce RFC insiste bien sur le fait qu'elles doivent être soigneusement choisies. Par exemple, un MUST ne doit être utilisé que si la violation de cette obligation est effectivement dangereuse, par exemple pour l'interopérabilité. Si ce conseil a été suivi, changer un MUST en SHOULD dans un profil va donc être négatif à coup presque sûr. Et, le RFC rappelle aussi qu'un MAY veut dire « vous n'êtes pas obligés de l'implémenter » mais certainement pas « vous avez le droit de planter si l'autre machine l'utilise ».
Place au cinquième principe, les tests. On a vu que ce n'est pas tout de bien normaliser, il faut aussi bien programmer. Pour s'assurer que tout a été bien programmé, il faut tester. Cela implique d'avoir développé des jeux de tests, essayant les différents cas vicieux (par exemple, essayer toutes les possibilités du mécanisme d'extension, pour vérifier qu'aucune ne plante les programmes ne les mettant pas en œuvre). Sinon, le test sera fait dans la nature, comme cela avait été le cas du fameux attribut 99 de BGP. La norme spécifiait très clairement ce qu'un pair BGP devait faire d'un attribut inconnu, mais IOS n'en tenait pas compte et, lorsque quelqu'un a essayé d'utiliser réellement cette possibilité de la norme, il a planté une bonne partie de l'Internet européen... TLS, étudié plus en détail plus loin, fournit un autre exemple d'implémentations déplorables, bloquant le déploiement de nombreuses extensions.
Sixième grande question d'architecture, l'enregistrement des paramètres. Beaucoup de protocoles ont besoin de registres pour noter les valeurs que peuvent prendre tel ou tel champ (par exemple, il y a un registre des numéros de protocole de transport et un registre des options DHCP). Ces registres et leur bonne utilisation sont une question souvent sous-estimée de l'interopérabilté. Si un champ du paquet identifie une extension et que deux extensions incompatibles utilisent le même numéro, l'accident est inévitable. Cette collision peut être due à l'absence de registre mais on rencontre régulièrement des développeurs qui ne vérifient pas le registre et qui s'attribuent tout simplement un numéro qui leur semble libre. (Le RFC note, de manière politiquement correcte, qu'il ne peut pas « publier les noms sans embarrasser des gens ». Mais cela semble particulièrement fréquent pour les numéros de port et pour les plans d'URI.)
Les concepteurs de protocole devraient vérifier, d'abord si un des registres existants ne suffit pas et, sinon en créer un. Dans ce cas, il faut soigneusement choisir la politique d'allocation des valeurs dans ce registre. Le RFC 5226 décrit les différentes politiques possibles, de la plus laxiste à la plus stricte. Attention : choisir une politique très stricte peut avoir des effets de bord désagréables, par exemple encourager les gens à « s'auto-enregistrer », c'est-à-dire à prendre un numéro au hasard (et tant pis pour l'interopérabilité) parce que la complexité et la lenteur des procédures les ont découragés. Il peut être préférable d'avoir une approche plus ouverte du registre, qui devrait documenter ce qui existe plutôt que d'essayer de contrôler tous les enregistrements.
Enfin, septième et dernier principe architectural à garder en tête pour faire des protocoles extensibles, l'importance particulière des services critiques. Si on arrête BGP, l'Internet ne fonctionne plus. Si on arrête le DNS, il n'y a quasiment plus aucune activité possible (même si vous ne voyez pas de noms de domaine, ils sont présents dans la communication). Même chose pour certains algorithmes comme le contrôle de congestion : si on modifie cet algorithme et qu'on se trompe, on peut mettre l'Internet à genoux. Il faut donc faire dix fois plus attention lorsqu'on étend ces protocoles critiques.
Le RFC cite un exemple BGP. Il existait depuis longtemps dans les IGP comme OSPF la notion de LSA opaque (LSA = Link State Attribute, la structure de données qui contient les informations que s'échangent les routeurs). « Opaque » signifie que les routeurs n'ont pas forcément besoin de comprendre son contenu. Ils peuvent le propager sans l'analyser et cela permet des extensions intéressantes du protocole, en introduisant de nouveaux types de LSA opaques. L'expérience montre que cela marche bien.
Mais l'introduction de nouveaux attributs dans BGP ne s'est pas aussi bien passé puisque des routeurs ont réinitialisé les sessions locales si un attribut, transmis par un routeur lointain, était inconnu ou mal formé. (Cas du fameux attribut 99.)
Une fois ces sept principes en tête, la section 4 se penche sur le protocole de base. Une bonne extensibilité implique un bon protocole de base, conçu pour l'extensibilité. Cela implique :
Écrire un protocole bien extensible nécessite aussi de prêter
attention à ce qui peut sembler des petits détails. Ainsi (section
4.1), le problème des numéros de versions. Il est courant que le
protocole porte un tel numéro, permettant au pair de savoir tout de
suite s'il a affaire à une implémentation équivalente (même numéro de
version) ou pas (numéro de version plus récent ou plus ancien). Par
exemple, voici une session TLS avec l'outil
gnutls-cli
de GnuTLS :
% gnutls-cli --verbose --port 443 svn.example.net ... - Version: TLS1.2
où on voit que le serveur accepte TLS version 1.2. Un tel versionnement n'est utile que si le protocole de base précise bien ce qu'il faut faire lorsqu'on rencontre une version différente. Par exemple, si un logiciel en version 1.1 rencontre un 2.0 ? Il y a plusieurs sémantiques possibles, par exemple le protocole de base peut préciser que toute version doit être un sur-ensemble de la version antérieure (le logiciel en 2.0 doit accepter toutes les commandes du 1.1). Une autre sémantique pourrait être qu'il n'y a compatibilité qu'au sein d'une même version majeure (entre 1.0, 1.1, 1.2, etc) et que donc les deux logiciels de l'exemple (1.1 et 2.0) doivent renoncer à se parler. Dans les deux cas, cela doit être clairement spécifié.
Un contre-exemple est fourni par la norme
MIME. Le RFC 1341 décrivait un en-tête
MIME-Version:
mais sans dire ce que devait faire
une implémentation correcte de MIME si elle rencontrait une version
inférieure ou supérieure. En fait, ce RFC 1341 ne précisait
même pas le format de la version ! Le RFC 1521 a un peu
précisé les choses mais pas au point qu'on puisse prédire le
comportement d'une mise en œuvre de MIME face à des versions
nouvelles. Notre RFC 6709 estime donc que le
MIME-Version:
n'a guère d'utilité pratique.
Pour un exemple plus positif, on peut regarder ROHC. Le RFC 3095 décrivait un certain nombre de jeux de paramètres pour la compression. À l'usage, on leur a découvert des limitations, d'où le développement de ROHCv2 (RFC 5225). Ce dernier n'est pas compatible mais ne plante pas les ROHC précédents, ils ont simplement des jeux de paramètres différents et la négociation initiale (qui n'a pas changé en v2) permet à un ROHC ayant les jeux v1 de se comprendre facilement avec un plus récent.
Quelles sont les stratégies utilisées par les protocoles pour la gestion des versions ? Il y en a plein, toutes n'étant pas bonnes. On trouve :
Et c'est à peu près tout. Le RFC considère qu'il ne faut pas chercher d'autres stratégies de versionnement, qui ont de fortes chances d'être trop complexes pour être mises en œuvre sans erreur.
Autre chose importante à considérer lorsqu'on normalise le protocole de base (la première version) : les champs réservés. On trouve souvent dans les RFC des phrases comme (celle-ci est extraite du RFC 1035) « Reserved for future use. Must be zero in all queries and responses. ». (Dans le cas du DNS, ils ont été utilisés par la suite pour DNSSEC, bits AD et CD. Le bit 9, selon le RFC 6195, section 2.1, avait été utilisé de manière non standard autrefois et semble donc inutilisable désormais.) Certains champs dans l'en-tête sont donc gardés pour un usage futur et, presque toujours, le RFC demande à l'envoyeur de les mettre tous à zéro et au récepteur de les ignorer, ce qui est très important : autrement, on ne pourra jamais déployer d'implémentation d'une nouvelle version du protocole, qui utiliserait ces champs qui avaient été réservés. Dans les diagrammes montrant les paquets, ces champs sont en général marqués Z (pour Zero) ou MBZ (Must Be Zero, voir par exemple le RFC 4656). Notons que bien des pare-feux, fidéles jusqu'à l'excès au principe « tout ce qui est inconnu est interdit », au lieu d'ignorer ces champs, comme l'impose le RFC, jettent les paquets où ce champ ne vaut pas zéro. Ces engins sont une des plus grosses sources de problème lorsqu'on déploie un nouveau protocole. Donc, attention, programmeurs, votre travail n'est pas de vérifier ces champs mais de les ignorer, afin de permettre les futures extensions.
Autre problème douloureux, la taille à réserver aux champs (section 4.4). Certains protocoles utilisent des champs de taille illimitée (paramètres de type texte) ou suffisamment grands pour qu'on ne rencontre jamais la limite, même après plusieurs extensions du protocole. Mais ce n'est pas toujours le cas. Tout le monde se souvient évidemment de l'espace d'adressage trop petit d'IPv4 et de la difficulté qu'il y a eu à passer aux adresses plus grandes d'IPv6 (le champ Adresse étant de taille fixe, les deux versions ne pouvaient pas être compatibles). Dans la réalité, on rencontre :
Si un tel problème se pose, si on voit les valeurs possibles pour un champ arriver à un tel rythme que l'épuisement est une possibilité réelle, il y a plusieurs solutions :
Un usage particulier de l'extensibilité concerne la cryptographie (section 4.5). Celle-ci demande une agilité, la capacité à changer les algorithmes de cryptographie utilisés, pour faire face aux progrès constants de la cryptanalyse (c'est bien expliqué dans la section 3 du RFC 4962). Presque tous les protocoles de cryptographie sérieux fournissent cette agilité (le RFC ne donne pas d'exemple mais je peux citer deux contre-exemples, un à l'IETF, le TCP-MD5 du RFC 2385 depuis remplacé par le meilleur RFC 5925 qui est encore très peu déployé et, en dehors de l'IETF, le protocole DNScurve). Le problème est lorsqu'un algorithme noté comme obligatoire (avant d'assurer l'interopérabilité, un ou plusieurs algorithmes sont obligatoires à implémenter, pour être sûr que deux pairs trouvent toujours un algorithme commun) est compromis au point qu'il n'est plus raisonnable de s'en servir.
Soit un algorithme non compromis est déjà très répandu dans les mises en œuvre existantes du protocole et on peut alors le déclarer obligatoire, et noter le vieil algorithme comme dangereux à utiliser. Soit il n'existe pas encore un tel algorithme répandu et on a peu de solutions : déployer du code dans la nature prend beaucoup de temps. Bref, le RFC recommande que, lorsque les signes de faiblesse d'un algorithme face à la cryptanalyse apparaissent (le RFC ne cite pas de noms mais, en 2012, on peut dire que c'est le cas de SHA-1 et RSA), on normalise, puis on pousse le déploiement de solutions de rechange (par exemple SHA-2 et ECDSA dans ces deux cas, algorithmes qui sont aujourd'hui utilisables dans la plupart des protocoles IETF). Il faut bien se rappeler que le déploiement effectif d'un algorithme normalisé peut prendre des années, pendant lesquelles la cryptanalyse continuera à progresser.
Un aspect peu connu des protocoles applicatifs de la famille IP est qu'ils peuvent parfois tourner sur plusieurs transports, par exemple TCP et SCTP (section 4.6). Cela a parfois été fait dès le début, pour avoir le maximum de possibilités mais, parfois, le protocole de couche 7 n'était prévu que pour un seul protocole de couche 4, puis a été étendu pour un autre protocole. Par exemple, utilisant TCP, il ne passait pas à l'échelle, alors on l'a rendu utilisable sur UDP. (Dans ce cas, les concepteurs du protocole devraient lire le RFC 8085 car il y a plein de pièges.)
Cela peut évidemment casser l'interopérabilité. Si le protocole Foobar est normalisé pour tourner sur TCP ou SCTP, deux mises en œuvre de Foobar, une qui ne gère que TCP et une qui ne gère que SCTP (pensez aux systèmes embarqués, avec peu de ressources, ce qui impose de limiter les choix), ne pourront pas se parler. Notre RFC conseille donc de bien réflechir à ce problème. Davantage de choix n'est pas forcément une bonne chose. D'un autre côté, si le premier protocole de transport choisi a de sérieuses limites, on pourra en ajouter un autre comme option mais il sera quasi-impossible de supprimer le premier sans casser l'interopérabilité.
Enfin, dernier casse-tête pour le concepteur de protocoles, le cas des extensions inconnues (section 4.7). Je suis programmeur, je crée un programme pour la version 1.0 du protocole, ce programme sait traiter un certain nombre de messages. Le temps passe, une version 1.1 du protocole est créé, des programmeurs la mettent en œuvre et, soudain, les copies de mon programme reçoivent des messages d'un type inconnu, car introduit dans la 1.1. Que faire ? Première approche, une règle comme quoi les extensions inconnues doivent être ignorées (silently discarded). Je reçois un tel message, je le jette. Un champ qui était à zéro acquiert une signification ? J'ignore ce champ. L'avantage de cette approche est qu'elle permet le maximum d'interopérabilité. On est sûr que les vieilles versions pourront parler avec les nouvelles, même si seules les nouvelles pourront tirer profit des extensions récentes. L'inconvénient de cette approche est qu'on ne sait même pas si les nouveaux messages sont traités ou pas. Dans le cas de la sécurité, on voudrait bien pouvoir savoir si une extension qu'on considère comme indispensable a bien été acceptée par le pair (voir par exemple la section 2.5 du RFC 5080).
Autre approche, mettre un bit Mandatory (aussi
appelé Must Understand) dans les messages. Si ce
bit est à zéro, une vieille implémentation peut ignorer le
message. Sinon, elle doit prévenir qu'elle ne sait pas le gérer (par
exemple via un message ICMP
). C'est ce que font
L2TP (RFC 2661, section 4.1) ou
SIP (RFC 3261, section
8.1.1.9). Cette méthode
permet d'éviter qu'une extension cruciale soit ignorée par le
pair. Mais elle diminue l'interopérabilité : si un programme récent
l'utilise, il ne pourra pas parler avec les vieux qui ne savent pas du
tout gérer cette extension.
On peut aussi négocier les extensions gérées au début de la
session. Cela ralentit son établissement mais cela permet aux deux
pairs qui dialoguent de savoir ce que fait l'autre. Typiquement,
l'initiateur de la connexion indique ce qu'il sait gérer et le
répondeur choisit parmi ces extensions
acceptées. IKE (RFC 5996) fait cela,
HTTP et SIP aussi, via
leurs en-têtes Accept*:
et Supported:
.
Enfin, le concepteur d'un protocole de base, ou d'une extension à ce protocole doit lire la section 5 sur la sécurité. Elle rappelle qu'une extension à l'apparence inoffensive peut facilement introduire un nouveau risque de sécurité, ou parfois désactiver une mesure de sécurité qui était dans le protocole de base (l'ajout d'une poignée de mains dans un protocole qui était avant sans état peut créer une nouvelle occasion de DoS). L'analyse de sécurité de la nouvelle extension ne peut donc pas se contenter de reprendre celle du protocole de base, il faut s'assurer qu'il n'y ait pas de régression.
L'annexe A de notre RFC est très instructive car elle comprend trois études de cas de protocoles qui ont réussi, ou raté, leur extensibilité. La première concerne Radius (RFC 2865) grand succès mais qui, pour cette raison, a connu de fortes pressions pour son extension, pressions qui ont sérieusement secoué un protocole qui n'était pas vraiment conçu pour cela. L'idée dans le protocole de base était que les extensions se feraient en ajoutant des attributs (le protocole venait avec un certain nombre d'attributs standards dans les messages) dont la valeur pouvait avoir un nombre limité de types.
En pratique, on a constaté que, non seulement beaucoup de fournisseurs ne pouvaient pas s'empêcher de s'auto-allouer des noms d'attributs, mais aussi que bien des attributs ajoutés sortaient du modèle original (comme l'idée d'un dictionnaire, sur lesquels les correspondants se mettent d'accord et qui permet le déploiement de nouveaux attributs sans changer le code : idée astucieuse mais qui n'est pas dans le RFC 2865). La section 1 du RFC 2882, tirant un premier bilan, note qu'une des raisons de la tension est que le monde des NAS, pour lequel Radius avait été conçu, s'était beaucoup diversifié et complexifié, au delà du modèle initialement prévu. Le RFC 2882 notait aussi que certaines mises en œuvre ressemblaient à Radius (même format des messages) mais ne l'étaient pas vraiment (sémantique différente).
Un des cas compliqué est celui des types de données pour les attributs. Il était prévu d'ajouter de nouveaux attributs mais pas de nouveaux types. Il n'existe pas de registre des types définis, ni de moyen pour un client ou serveur Radius que savoir quels types gèrent son correspondant. L'utilisation d'attributs définis avec un type nouveau est donc problématique. Le RFC 6158 (section 2.1) a tenté de mettre de l'ordre dans ce zoo des types mais, publié plus de quatorze ans après la première norme Radius, il n'a pas eu un grand succès.
Radius dispose d'un mécanisme d'extensions spécifiques à un fournisseur (RFC 2865, section 6.2). Ce mécanisme a été utilisé à tort et à travers, notamment par des SDO différentes de l'IETF qui voulaient leurs propres extensions (alors que ces extensions n'avaient jamais été prévues pour être compatibles d'un fournisseur à l'autre). Autre problème, le cas des extensions « fournisseur » inconnues n'avait pas été traité. Or, certaines ont des conséquences pour la sécurité (définition d'une ACL par exemple) et il serait dommage qu'elles soient ignorées silencieusement. Le RFC 5080, section 2.5, estime que la seule solution est que les programmes mettant en œuvre Radius n'utilisent les extensions que lorsqu'ils savent (par exemple par configuration explicite) que l'autre programme les gère.
Autre protocole qui a connu bien des malheurs avec les extensions, TLS (annexe A.3). Son histoire remonte au protocole SSL, v2, puis v3, celle-ci remplacée par TLS. SSL, et TLS 1.0, n'avaient aucun mécanisme d'extension défini. Il a fallu attendre le RFC 4366 pour avoir un mécanisme normalisé permettant de nouveaux types d'enregistrements, de nouveaux algorithmes de chiffrement, de nouveaux messages lors de la poignée de mains initiale, etc. Il définit aussi ce que les mises en œuvre de TLS doivent faire des extensions inconnues (ignorer les nouveaux types, rejeter les nouveaux messages lors de la connexion). Mais, à ce moment, TLS était déjà très largement déployé et ces nouveaux mécanismes se heurtaient à la mauvaise volonté des vieilles implémentations. En pratique, les problèmes ont été nombreux, notamment pendant la négociation initiale. Ce n'est qu'en 2006 que les clients TLS ont pu considérer que SSLv2 était mort, et arrêter d'essayer d'interopérer avec lui. Encore aujourd'hui, de nombreux clients TLS restent délibérement à une version de TLS plus faible que ce qu'ils pourraient faire, pour éviter de planter lors de la connexion avec un vieux serveur (ces serveurs étant la majorité, y compris pour des sites Web très demandés). C'est ainsi que, lors de l'annonce de l'attaque BEAST en 2011, on s'est aperçu que TLS 1.1 résolvait ce problème de sécurité depuis des années... mais n'était toujours pas utilisé, de peur de casser l'interopérabilité.
Dans le futur, cela pourra même poser des problèmes de sécurité sérieux : il n'existe aucun moyen pratique de retirer MD5 de la liste des algorithmes de hachage, par exemple. TLS 1.2 (RFC 5246) permet d'utiliser SHA-256 mais tenter d'ouvrir une connexion en TLS 1.2 avec un serveur a peu de chances de marcher, le mécanisme de repli des versions n'existant que sur le papier.
Morale de l'histoire, dit notre RFC : ce n'est pas tout de faire de bonnes spécifications, il faut aussi qu'elles soient programmées correctement.
Dernier cas intéressant étudié, L2TP (RFC 2661). Fournissant dès le début des types spécifiques à un fournisseur, disposant d'un bit Mandatory pour indiquer si les types doivent être compris par le récepteur, L2TP n'a guère eu de problèmes. On pourrait imaginer des ennuis (RFC 2661, section 4.2) si un programmeur mettait un type spécifique et le bit Mandatory (empêchant ainsi toute interaction avec un autre fournisseur qui, par définition, ne connaîtra pas ce type) mais cela ne s'est guère produit en pratique.
Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : S. Kiesel (University of Stuttgart), S. Previdi (Cisco Systems), M. Stiemerling (NEC Europe), R. Woundy (Comcast Corporation), Y R. Yang (Yale University)
Pour information
Réalisé dans le cadre du groupe de travail IETF alto
Première rédaction de cet article le 30 septembre 2012
Le système Alto (Application-Layer Traffic Optimization), permettant aux machines d'un réseau pair-à-pair de trouver le meilleur pair, par exemple pour obtenir un fichier plus rapidement, avance, lentement, mais sûrement. Ce nouveau RFC spécifie le cahier des charges d'Alto.
Alto peut servir à autre chose qu'au pair-à-pair. Mais le scénario d'utilisation principal est le suivant : une machine veut accéder à un fichier. Celui-ci est offert par plusieurs pairs. Lequel choisir ? En prendre un au hasard risque de ne pas être optimum, ni pour la machine (temps de transfert du fichier plus long qu'il ne pourrait l'être), ni pour son FAI (utilisation de liens externes plus coûteux que son réseau interne). Alto vise donc à permettre à des serveurs Alto de donner à leurs clients (les machines qui veulent accéder aux fichiers) des informations sur lesquelles décider intelligemment, ou même simplement d'indiquer directement le pair à utiliser. Le groupe de travail Alto a été créé en novembre 2008, le RFC 5693, qui définit le problème à résoudre, a été publié en octobre 2009, et voici désormais le deuxième RFC du groupe, le cahier des charges du protocole. (Pour ceux qui ne connaissent pas l'IETF, et qui craignent que le travail sur le protocole ne commence qu'une fois le cahier des charges terminé, je vous rassure, ce n'est pas ainsi que fonctionne l'IETF. Le protocole est déjà bien avancé à l'époque, et a été publié dans le RFC 7285.)
Pair-à-pair ou pas, le but d'Alto est donc d'améliorer simultanément la qualité de la vie pour l'utilisateur (télécharger les chefs d'œuvre de la culture plus vite) et pour le réseau (ne pas gaspiller des ressources chères comme les lignes transocéaniques). Cela ne peut pas se faire par des mesures uniquement faites par les machines terminales. Par exemple, celles-ci peuvent faire des ping mais elles ne peuvent pas déterminer si un lien est de peering (« gratuit ») ou de transit (facturé au 95ème centile de l'usage).
Les serveurs Alto ne feront pas bouger les octets : leur seul rôle est de dire aux pairs « tu devrais plutôt causer avec lui, ça devrait aller vite ». Les pairs sont ensuite responsables de leurs décisions.
L'habituelle section de terminologie, nécessaire pour comprendre le reste du RFC, est la section 2. Attention, le RFC 5693 définissait déjà certains termes (comme client Alto et serveur Alto) qui ne sont pas répétés ici. Les termes les plus importants :
2001:db8:1337::/32
») ou un numéro
d'AS (« toutes les machines joignables par l'AS
42 »).Les exigences sur le futur protocole figurent en section 3 et sont numérotées AR-n (AR pour Alto Requirment). Elles vont des plus évidentes (exigence AR-1 : les clients et serveurs Alto doivent parler le protocole Alto...) aux plus pointues. Voici les plus importantes, selon moi.
Le protocole devra gérer les descripteurs de groupe : types
multiples (AR-3), au moins les types « préfixe
IPv4 » et « préfixe
IPv6 » (AR-5) et extensible (possitibilité
d'ajouter de nouveaux types de descripteurs de groupe dans le futur,
AR-6). Les types « préfixes IP » sont, à ce stade, les types
recommandés. Donc, en deux mots, les pairs possibles seront identifiés
par leur adresse (« j'hésite entre un pair en
2001:db8:1:2::af
et un pair en
192.0.2.43
, tu me recommandes lequel ? »). Voir
aussi AR-7 et AR-8.
Le protocole devra permettre d'indiquer un critère de classement (AR-11) permettant de comparer les machines entre elles. Alto ne détermine pas comment on fait les calculs : il utilise le résultat (on peut tout imaginer, y compris des tables gérées à la main, par exemple en fonction du fait que les liens sont de transit ou de peering). Alto devra, là aussi, être extensible et permettre d'ajouter d'autres critères dans le futur.
Ces critères doivent être relativement stables (ne pas oublier qu'une fois un transfert de fichiers commencé, il peut durer de nombreuses heures) donc ne pas dépendre, par exemple, de l'état de congestion du réseau (AR-13). À propos de la congestion, les applications qui utiliseront Alto ne doivent pas s'en servir comme remède contre la congestion, elles doivent utiliser un protocole qui dispose de mécanismes d'évitement de la congestion, comme TCP (AR-14, et aussi AR-29).
Le critère de classement doit pouvoir être indiqué au serveur (en mode « recherche dépendante de la cible », car, dans l'autre mode, c'est le client Alto qui classe) afin qu'il l'utilise pour classer (AR-16).
Où va être situé le client Alto ? Le protocole ne l'impose pas et il y aura au moins deux positionnements possibles : directement dans l'application (le client BitTorrent, par exemple) ou bien chez un tiers qui fera une partie du travail pour le compte du client (le tracker BitTorrent, par exemple). Alto devra fonctionner dans les deux cas (AR-18 et AR-19).
Et qui va fournir ses informations au serveur Alto ? Une possibilité évidente est que ce soit le FAI, et qu'Alto devienne un service de base de l'accès Internet, comme le résolveur DNS et le serveur NTP. Mais les exigences AR-20 et AR-21 demandent que le protocole n'impose pas ce choix : il faut que des acteurs tiers puisse jouer le rôle de serveur Alto.
Le protocole doit aussi permettre la redistribution de l'information obtenue (AR-25), en indiquant des conditions de redistribution.
Comment va-t-on trouver son serveur Alto ? Il faudra décrire un mécanisme et AR-37 demande que ce mécanisme soit intégré aux protocoles existants comme PPP ou DHCP (comme c'est le cas pour découvrir un résolveur DNS).
La sécurité étant un enjeu important pour Alto (voir aussi la section 5), il faudra aussi un mécanisme d'authentification des serveurs (AR-40), des clients (AR-41), la possibilité de chiffrer (AR-42), et d'ajuster la taille des requêtes et réponses selon le niveau de confiance du client envers le serveur, ou réciproquement (AR-44). Un client devra donc pouvoir rester intentionnellement vague dans sa demande, au risque évidemment que les informations du serveur soient moins pertinentes.
Et la sécurité ? Outre le RFC 5693 qui couvrait déjà la sécurité d'Alto, la section 5 de notre RFC met l'accent sur le point le plus important, le risque de distribution d'informations sensibles.
Ce risque existe dans les deux sens, du client vers le serveur et du serveur vers le client. Le client ne souhaite pas forcément communiquer au serveur tout ce qu'il sait. Par exemple, lorsque la HADOPI espionne, un client Alto ne va pas dire à un serveur qu'il ne connait pas « je cherche une copie HD du dernier Disney ». Et, en sens inverse, un serveur Alto géré par un FAI n'est pas forcément enthousiaste à l'idée de donner des informations qui permettent de se faire une bonne idée de la configuration de son réseau, de l'identité des opérateurs avec qui il peere et autres informations confidentielles.
Même si le client ne donne pas d'informations aussi évidentes que dans l'exemple ci-dessus, un serveur malin peut déduire plein de choses des demandes que le client lui adresse (la liste des pairs potentiels, par exemple, est une information utile pour repérer les plus grosses sources de contenu en pair-à-pair).
Pour l'opérateur du serveur, le principal risque est en recherche indépendante de la cible, lorsque le client télécharge de grandes quantités d'information. Un serveur prudent ne dira donc pas tout. En outre, même si le serveur accepte de donner ces informations au client, il peut quand même s'inquiéter de ce qu'elles deviendront. Un tiers qui écoute le réseau ne va t-il pas mettre la main sur l'information confidentielle ? Et, même si l'information donnée à chaque client est limitée (par exemple, uniquement une partie des descripteurs de groupes que le serveur connait), ne risque t-on pas de voir des clients coopérer pour récupérer chacun un bout, avant de le mettre en commun ?
Le futur protocole Alto devra donc contenir des mesures pour faire face à ces problèmes : par exemple, permettre au serveur d'être délibérement incomplet ou imprécis (annoncer un préfixe IP plus général que le vrai, par exemple), authentifier clients et serveurs, chiffrer les communications contre l'écoute par TMG, etc. En revanche, le RFC écarte l'idée de DRM dans les données Alto, complexes et facilement contournables. Les acteurs Alto sont donc prévenus que les données échangées ne peuvent pas être 100 % confidentielles. Un client ou un serveur méchant pourra toujours en faire mauvais usage.
À noter que les intérêts du client et du serveur peuvent être contradictoires. Ainsi, les requêtes en mode indépendante de la cible préservent la vie privée du client (il ne dit rien sur ce qu'il va faire des données) mais oblige le servur à diffuser de l'information. Et, pour les requêtes en mode dépendant de la cible, c'est le contraire :le client se dévoile, le serveur ne prend pas de risque.
Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : B. Niven-Jenkins (Velocix (Alcatel-Lucent)), F. Le Faucheur (Cisco), N. Bitar (Verizon)
Pour information
Réalisé dans le cadre du groupe de travail IETF cdni
Première rédaction de cet article le 26 septembre 2012
Aujourd'hui, les CDN sont partout. Ces serveurs munis de nombreux disques et disposés dans les réseaux des FAI, au plus près de l'abonné, afin de servir du contenu numérique le plus rapidement possible, sont derrière un grand nombre de sites Web (non, ce blog n'utilise pas de CDN) et derrière bien des fournisseurs de streaming. La plus connue des entreprises de CDN est Akamai mais il en existe bien d'autres. Et c'est là que le problème commence : il n'existe aucun mécanisme d'interconnexion des CDN. Chacun utilise ses protocoles spécifiques et pas question de les faire travailler ensemble. L'IETF a donc créé un groupe de travail, CDNI, chargé de réfléchir à l'interconnexion des CDN. Ce RFC est le premier du groupe, et il essaie de définir le problème (les solutions viendront plus tard, le cahier des charges formel a été publié dans le RFC 7337).
L'extension massive des CDN est bien sûr liée à l'augmentation considérable du contenu numérique : présentations PowerPoint ennuyeuses, vidéos de chats mignons, communiqués de presse en PDF qui prennent plusieurs mégaoctets pour ne pas dire grand'chose, publicités débiles, webinars en haute définition et au contenu vide, etc. Sans le CDN, un site Web qui veut distribuer un fichier de N mégaoctets à M clients va voir N*M mégaoctets passer sur sa liaison Internet. Avec le CDN, le fournisseur de contenu (CSP dans le RFC pour Content Service Provider) n'aura à faire passer le contenu qu'une fois, vers le CDN. Le contenu sera ensuite distribué par les serveurs du CDN, situés typiquement chez les FAI (notez aussi que certains FAI ont leur propre CDN). Meilleure latence, meilleure résilience (attaques dDoS et flash crowds), meilleur débit, bref, tous les avantages.
Aujourd'hui, les CDN ne coopèrent pas. Si un fournisseur de CDN est très présent en Europe et en Amérique, mais pas en Asie, un CSP client de ce CDN verra ses clients asiatiques mécontents. Pour les satisfaire, il devra signer un contrat avec un autre CDN, très présent en Asie. Il serait pourtant plus simple que le premier fournisseur de CDN puisse s'appuyer sur l'infrastructure du second et lui transmettre données et instructions. Mais, en l'absence de normes techniques pour l'interconnexion des CDN, cela n'est possible aujourd'hui que par des arrangements privés. C'est l'une des principales motivations pour la création du groupe de travail CDNI. L'idée est que, dans le futur, le premier fournisseur de CDN cité (celui qui est trés présent en Europe et en Amérique) aura juste à signer un contrat avec le second fournisseur et, techniquement, tout se passera tout seul, il utilisera le réseau du second sans que le fournisseur de contenu n'y voit rien.
Avant d'attaquer la question de l'interconnexion, notre RFC 6707 précise qu'il vaut mieux connaître les CDN pour suivre. Si ce n'est pas le cas, il recommande la lecture des RFC 3040 qui décrit les composants d'un CDN, RFC 3466 et RFC 3570, les deux derniers étant le résultat du travail du précédent groupe de travail IETF sur les CDN. Le RFC recommande également la lecture de « A Taxonomy and Survey of Content Delivery Networks ».
La section 2 de notre RFC précise les cas où il est intéressant d'interconnecter les CDN. À la raison donnée plus haut (permettre à des CDN de s'allier pour avoir une meilleure couverture géographique), s'ajoute le désir de permettre l'interconnexion des CDN que gèrent certains FAI : en se regroupant, ils pourraient former un CDN alternatif aux CDN indépendants des FAI comme Akamai. Il y a aussi des cas où un FAI a déployé plusieurs CDN spécialisés et souhaite après les regrouper. Enfin, un dernier scénario envisagé est celui où un CDN doit faire appel temporairement à un autre (suite à une grosse panne, par exemple) et doit le faire vite, sans programmer des scripts spécifiques.
Mais qu'est-ce que veut dire « Interconnecter des CDN » ? Des essais ont déjà été tentés, montrant qu'il y avait des choses qui marchaient et d'autres qui étaient vraiment pénibles en l'absence de normes. La section 3 identifie quatre interfaces par lesquelles on voudrait connecter des CDN, et pour lesquelles il n'existe pas de normes :
Vous avez noté quelque chose qui manque ? Prenez le temps de réfléchir avant de regarder le paragraphe suivant.
Une interface importante est exclue du projet CDNI : l'interface d'acquisition des données elle-mêmes. Ce n'est pas tout de s'entendre avec un autre CDN pour qu'il contribue à distribuer le contenu de vos clients, encore faut-il mettre la main sur le dit contenu ! Mais notre RFC considère le problème comme déjà largement résolu. Il existe en effet plusieurs protocoles standards, ayant toutes les caractéristiques voulues, et effectivement utilisés par les CDN (HTTP et rsync sont deux exemples typiques). En écartant ce problème des données, le groupe CDNI se focalise sur le contrôle des CDN.
Et pour les quatre interfaces citées plus haut, ne pourrait-on pas trouver des protocoles existants qui résolvent le problème, sans avoir besoin de développer quelque chose de nouveau ? La section 4 reconnait que ce serait très souhaitable, cite des protocoles intéressants (comme XMPP ou APP) et étudie cette question.
Des détails sur cette réutilisation de protocoles existants figurent dans l'annexe A. Elle est particulièrement riche pour le cas de l'interface de routage, qui doit permettre des scénarios de redirection complexes (plus complexes que, par exemple, les simples 301 et 302 de HTTP). Pour la journalisation, si le protocole de transport peut être un protocole existant, il restera à spécifier le format des données transportées (les champs, leur syntaxe, leur sémantique, etc).
La traditionnelle section de sécurité (section 6) est longue car une telle interconnexion des CDN soulève plein de problèmes difficiles. C'est d'autant plus vrai que le contenu numérique servi est souvent commercial et que le fournisseur de contenu souhaite en contrôler la distribution. Dans un CDN homogène, c'est relativement facile. Mais comment faire lorsqu'on interconnecte des CDN hétérogènes ? Il va falloir faire confiance aux autres...
En outre, l'interconnexion des CDN différents va introduire des problèmes légaux, puisque les CDN en question seront peut-être gérés par des entreprises différentes, donc soumises à des lois différentes. Ainsi, une loi locale peut obliger à anonymiser plus ou moins les données envoyées sur l'interface de journalisation.
L'annexe B intéressera les concepteurs de protocoles et les étudiants car elle définit les non-buts, ce que le groupe CDNI n'essaiera pas de faire. Par exemple :
Autre partie intéressante de l'annexe B, celle consacrée aux autres groupes de travail IETF qui avaient une importance pour ce sujet :
Enfin, pour ceux et celles qui veulent vraiment beaucoup approfondir, les Internet-Drafts qui avaient précédé le RFC contenaient également une annexe (non gardée dans le RFC final) intéressante sur les autres efforts de normalisation des CDN. On y trouve de nombreux projets, parfois toujours actifs, y compris un ancien groupe de travail IETF, CDI, qui avait produit plusieurs RFC intéressants (RFC 3466, RFC 3568 et RFC 3570). Trop ambitieux, ce groupe n'avait pas vraiment réussi à faire avancer l'interconnexion.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Morton (AT&T Labs), G. Ramachandran (AT&T Labs), G. Maguluri (AT&T Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 24 août 2012
Le groupe de travail IPPM de l'IETF a défini de nombreuses métriques, des définitions rigoureuses de grandeurs qu'on peut mesurer sur un réseau. Ce nouveau RFC porte sur un problème un peu différent : une fois qu'on a ces métriques, comment publier les résultats ? Quels sont les pièges de la publication ? Parmi les paramètres de la mesure, que mettre en évidence ? Ce RFC est loin de traiter en détail toutes ces questions, il décrit surtout les conséquences de deux points de vue différents : celui de l'ingénieur réseaux, intéressé surtout par les performances de son réseau, et celui du programmeur, intéressé par les performances de son application.
Il y a bien sûr un lien entre les deux : si le réseau perd beaucoup de paquets, par exemple (RFC 7680 et RFC 6673), les applications auront de moins bonnes performances. Mais, dans certains cas, les deux points de vue ne s'intéressent pas exactement à la même chose. Voyons en quoi. (À noter aussi que ce RFC 6703 ne regarde que les analyses sur le relativement long terme, au moins plusieurs heures. Et il ne se penche pas sur le problème, bien plus difficile, de la publication vers M. Toutlemonde, par exemple pour lui communiquer la QoE.)
Toute présentation de mesures nécessite évidemment de connaître l'audience. On ne va pas communiquer de la même façon vers le management et vers les techniciens, par exemple. Et, même parmi les techniciens, il existe plusieurs catégories. Ce RFC s'intéresse à la différence entre « les gens du réseau » (qui pensent planification des investissements, dépannage, SLA, etc) et « les gens des applications » qui se demandent quel va être l'effet du réseau sur les applications. Les premiers mesurent des métriques comme le taux de pertes de paquets (RFC 7680) ou comme le délai d'acheminement (RFC 7679), avec l'idée de modifier le réseau (par des investissements ou bien des changements de la configuration), si les chiffres sont défavorables. Les seconds vont ajuster les applications pour s'adapter à ces résultats, qu'ils ne peuvent pas changer.
Les recommandations de notre RFC occupent la section 3. Lorsqu'on publie des mesures, on doit notamment :
C'est le minimum. Mais on peut l'enrichir, avec d'autres métriques comme la variation du délai d'acheminement (RFC 3393), le réordonnancement des paquets (RFC 4737), la capacité (RFC 3148 et RFC 5136, le premier RFC décrivant la capacité utile et le second celle mesurée au niveau IP). Et on peut ajouter d'autres statistiques, pour ne pas être bloqués par les limites de la moyenne et de la médiane. Par exemple, minimum, maximum, « 95 percentile ».
Bon, et les deux points de vue différents dont je parlais au début, que deviennent-ils ? La section 4 du RFC examine les différentes métriques selon ces deux points de vue. Par exemple, le taux de pertes du RFC 7680 a un paramètre important : le délai d'attente avant qu'on renonce à attendre un paquet. Le RFC 7680 ne donne pas de valeur quantitative. Intuitivement, on pourrait penser que des durées de l'ordre de la demi-seconde suffisent. Après tout, on n'a jamais vu ping signaler un délai plus long, non ? Mais ce n'est pas idéal. En cas de boucle de routage, par exemple, avant que l'IGP ne converge enfin, un délai de plusieurs secondes est possible (cf. « A Fine-Grained View of High Performance Networking » à NANOG 22 ou « Standardized Active Measurements on a Tier 1 IP Backbone » dans IEEE Communications Mag. de juin 2003). Un délai long est donc recommandé. En modélisant le pire cas dans le réseau, notre RFC arrive à une recommandation de 50 secondes, qui devrait couvrir tous les cas. Revenons maintenant aux deux point de vue. L'homme (ou la femme) du réseau veut déterminer le vrai taux de perte, en étant sûr que les paquets sont vraiment perdus et pas simplement très en retard. Mais la femme (ou l'homme) des applications n'a pas besoin de tels délais d'attente : l'application ne patientera jamais autant. Pour la plupart des applications, si ça n'arrive pas en quelques secondes, c'est comme si c'était perdu.
Faut-il alors faire deux mesures pour nos deux points de vue ? C'est une possibilité. Le RFC en suggère une autre : ne faire qu'une mesure, avec le délai long, mais noter le moment où le paquet arrive et calculer le taux de pertes avec deux délais différents, pour faire deux rapports.
Et le cas des paquets erronés (par exemple car ils ont une somme de contrôle invalide) ? Pour le RFC 7680, ils sont à compter comme perdus (si le paquet est erroné, on ne peut même pas être sûr qu'il était bien pour nous). C'est le point de vue des gens du réseau. Mais les gens des applications ne sont pas toujours d'accord. Certaines applications, notamment dans le domaine de l'audio et de la vidéo temps-réel préfèrent que l'application reçoive les paquets erronés, dont on peut parfois tirer quelque chose. Notre RFC suggère donc de publier deux résultats, un en comptant les paquets erronés comme perdus, l'autre en les acceptant.
Et la métrique « délai d'acheminement des paquets », en quoi les deux points de vue l'affectent (section 5) ? Notre RFC s'oppose surtout à l'idée de présenter les paquets qui, lors de la mesure, n'arrivent pas, avec une valeur artificielle comme un nombre très grand ou comme l'infini. Quel que soit le point de vue, l'infini n'est pas une valeur utile et il vaut donc mieux considérer que le délai, pour un paquet qui n'arrive pas, est « indéfini ».
Maintenant, la capacité (sections 6 et 7). Notre RFC 6703 introduit un nouveau vocabulaire, « capacité brute » (raw capacity) pour celle du RFC 5136 (qui n'intègre pas les effets de la retransmission des paquets perdus ou erronés) et « capacité restreinte » (restricted capacity) pour celle du RFC 3148, qui intègre les actions du protocole de transport (retransmettre les données manquantes, par exemple). La capacité restreinte est donc inférieure ou égale à la capacité brute, et elle est plus proche de ce qui intéresse les utilisateurs.
D'abord, un rappel, la capacité n'est définie que pour un Type-P donné, c'est-à-dire (RFC 2330) un type de paquets (protocole, port, etc). Ensuite, le RFC 5136 définit trois métriques pour la capacité brute : capacité IP maximum (ce que le système peut faire passer), utilisation (ce qui passe effectivement, et qu'on pourrait appeler « débit » mais le RFC évite ce terme, trop galvaudé), et enfin capacité disponible (certaines applications, par exemple, voudraient simplement savoir si la capacité disponible est suffisante - supérieure à une certaine valeur). Les trois métriques sont liées : en en connaissant deux, on peut calculer la troisième. L'utilisation (et donc la capacité disponible) peut varier rapidement sur un réseau réel. Notre RFC 6703 recommande donc de moyenner sur une longue période, par exemple une minute (en notant que cinq minutes est plus fréquent, en pratique, mais peut-être trop long). D'autre part, il suggère de publier plusieurs chiffres : miminum, maximum et un intervalle (par exemple, le pourcentage de temps pendant lequel la métrique vaut entre telle et telle valeur, comme « la capacité est de X Mb/s pendant au moins 95 % du temps »). Maximum et minimum peuvent aussi être publiés sous forme d'un seul chiffre, leur ratio : (max/min = 1) => grande stabilité, (max/min = 10) => forte variabilité, etc.
Pour la capacité restreinte, un autre problème se pose : elle est
dépendante des algorithmes de contrôle de
congestion. Par exemple, avec certaines mises
en œuvre de TCP anciennes, la capacité
restreinte (celle réellement accessible aux applications) pouvait être
très inférieure à la capacité brute, par exemple parce que TCP
réagissait mal en cas de perte de paquets et ralentissait trop son
débit. Notre RFC introduit donc un nouveau concept, le « Type-C » qui
est l'ensemble des algorithmes du protocole de transport et leurs
paramètres (RFC 6349). Il est nécessaire de
publier le Type-C utilisé, avec les résultats. (Un exemple, sur
Linux, est la valeur du paramètre
sysctl
net.ipv4.tcp_congestion_control
.)
Autre piège, le temps d'établissement de la connexion TCP. Si on
mesure la capacité restreinte avec quelque chose comme (sur
Unix) time wget
$GROSFICHIER
, le délai pour la triple poignée de mains qui
commence toute connexion TCP peut sérieusement affecter le
résultat. Même chose avec le « démarrage en douceur » que fait TCP
avant d'atteindre l'équilibre. Il peut diminuer la capacité mesurée
(d'un autre côté, l'ignorer serait irréaliste puisque les « vraies »
connexions l'utilisent). Bref, toutes ces informations doivent être
publiées avec le résultat de la mesure.
Enfin (section 8), deux détails qui peuvent avoir leur importance : la distribution des paquets lors d'une mesure active (Poisson ? Périodique, ce que fait ping ?). Et la taille de l'échantillon (par exemple le nombre de paquets envoyés.) Ces détails doivent également être publiés.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : T. Polk (National Institute of Standards and Technology), P. Saint-Andre (Cisco)
Pour information
Première rédaction de cet article le 21 août 2012
Les règles de l'IETF concernant la publication des brevets sur les techniques en cours de normalisation ont déjà été violées plusieurs fois, par exemple par RIM. Deux RFC viennent donc d'être publiés pour traiter ce problème : un répressif, le RFC 6701, qui dresse la liste des sanctions possibles contre les tricheurs. Et un préventif, ce RFC 6702, qui expose tous les mécanismes à mettre en œuvre pour encourager tout le monde à respecter les règles. Pour le résumer : la principale (voire unique) méthode envisagée est de rappeler les règles au bon moment, de façon à augmenter les chances qu'elles soient lues.
Que disent ces règles, au juste ? Formulées dans le RFC 8179 et répétées en ligne, elles imposent, en substance, qu'un participant à l'IETF qui connait des revendications de propriété intellectuelle (typiquement des brevets) sur une technique en cours de normalisation doit en informer l'IETF (cela se fait en ligne), qui publiera alors ces revendications. C'est tout. L'IETF n'impose que cette transparence, qui permet ensuite aux groupes de travail de prendre des décisions en toute connaissance de cause (RFC 2026, section 10.4). Le but est d'éviter les brevets sous-marins, où une entreprise fait normaliser une technologie sur laquelle elle a des brevets, qu'elle ne révèle qu'après la publication de la norme, lorsqu'il est trop tard pour chercher une alternative. Pas étonnant que cette obligation de divulgation déplaise aux maneuvriers de l'appropriation intellectuelle. Au moins deux tricheries ont été détectées, une de RIM et l'autre de Huawei (dans le RFC 6468). La seconde a été la goutte d'eau qui a fait déborder le buffer et mené à ces deux RFC qui essaient de redresser la barre. Ils ne définissent pas de nouvelles règles : les anciennes s'appliquent comme avant, ces deux nouveaux RFC disent juste comment le faire.
À noter que, comme l'ont montré l'analyse de ces deux cas, il s'agissait de tricheries délibérées. Mais il y a aussi eu des cas où la négligence ou l'ignorance ont fait que les brevets n'étaient pas annoncés à l'IETF, ou bien l'étaient en retard. Ces deux RFC vont aussi servir pour le cas où la violation des règles s'est faite de bonne foi. Car, même commis de bonne foi, ce manque de divulgation d'un brevet peut avoir des conséquences fâcheuses : un groupe de travail qui ne connaissait pas un brevet risque de négliger une piste alternative, non plombée par des brevets.
En pratique, les méthodes suggérées dans ce RFC concernent surtout les personnes ayant un rôle dirigeant à l'IETF (RFC 2418 et RFC 3669) : président de groupe de travail, directeur de zone (ceux qui forment l'IESG), etc. Ce sont ces personnes qui ont la responsabilité de faire avancer proprement le processus.
La section 3 du RFC décrit les stratégies disponibles. Il s'agit essentiellement de mieux informer les participants à l'IETF pour éviter toute inattention... ou toute fausse excuse. S'appuyant sur les conseils du RFC 3669, les responsables peuvent :
ietf-announce@ietf.org
incluent
automatiquement un URL vers les divulgations de
brevet pertinentes pour ce document),L'idée est qu'on a plus de chance de capter l'attention des distraits si on envoie le rappel au moment où les auteurs travaillent activement sur le document, pour lui faire franchir une étape. Quant aux gens de mauvaise foi, ils auront moins de possibilités de faire croire à une erreur (« je n'avais pas vu le rappel »). Voici un exemple d'un appel à un IETF Last Call (pour le document « TCP Extensions for Multipath Operation with Multiple Addresses ») :
Date: Wed, 01 Aug 2012 09:43:18 -0700 From: The IESG <iesg-secretary@ietf.org> To: IETF-Announce <ietf-announce@ietf.org> Subject: Last Call: ... ... The IESG plans to make a decision in the next few weeks, and solicits final comments on this action. ... The following IPR Declarations may be related to this I-D: http://datatracker.ietf.org/ipr/1842/ http://datatracker.ietf.org/ipr/1843/
La même chose s'applique aux soumissions individuelles (section 4).
Un petit piège : les règles de divulgation précisent que la divulgation doit être tenue à jour. Par exemple, si un brevet qui avait simplement été déposé est accepté, le texte de la divulgation doit être modifié (section 6). Ne pas mettre à jour une divulgation est aussi sérieux que de ne pas en faire.
Si jamais vous accédez à des responsabilités à l'IETF et que vous avez à procéder vous-même à ces rappels, vous pourrez être aidé par l'annexe A de ce RFC, qui contient des messages-types qu'il n'y a qu'à copier-coller.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Farrel (Juniper Networks), P. Resnick (Qualcomm)
Pour information
Première rédaction de cet article le 21 août 2012
Comme toutes les organisations de normalisation, l'IETF a élaboré une série de règles pour gérer le difficile problème de l'appropriation intellectuelle et surtout des brevets. Ces règles existent depuis des années mais ce n'est que récemment, suite à deux affaires spectaculaires, que l'IETF a pris conscience du fait que la question des sanctions, en cas de violation de ces règles, n'avait jamais été sérieusement discutée. Ce RFC corrige ce manque et fait la liste des réactions possibles de l'IETF en cas de violation des règles. Disons-le tout de suite, il n'y en a pas de très dissuasives : l'IETF n'a pas le pouvoir de couper des têtes ou de condamner au bûcher. Un autre RFC, le RFC 6702, discute de l'aspect positif, comment encourager le respect des règles.
Que disent ces règles actuellement ? Documentées dans le RFC 8179, résumées sur le site Web et par l'IESG, et fréquemment rappelées pendant les réunions physiques et sur les listes de diffusion, par les fameux « Note Well », ces règles reposent sur deux piliers :
Le but est d'éviter les brevets sous-marins, par lesquels une entreprise pousse à la normalisation d'une technique, pour laquelle elle dispose de brevets, en dissimulant ces brevets pour qu'ils n'effrayent pas les normalisateurs.
La section 2 décrit plus en détail cette politique de l'IETF. D'abord, elle ne s'applique qu'aux contributeurs à l'IETF. Quelqu'un qui n'écrirait aucun document, ne prendrait jamais la parole aux réunions et ne s'exprimerait pas sur les listes de diffusion n'aurait pas à la respecter. C'est d'ailleurs la seule solution pour un employé que sa compagnie n'autorise pas à divulguer l'existence d'un brevet : se retirer du processus IETF (« Aime-la ou quitte-la »).
Cette politique est ensuite souvent rappelée aux participants, par exemple lorsqu'on s'inscrit à une liste de diffusion IETF, on est redirigé vers la page Web d'avertissement (Note Well).
Pour signaler un brevet portant sur une technologie en cours d'examen à l'IETF, cela se fait via un formulaire Web. Les déclarations sont elles-mêmes publiées sur le Web.
Que fait ensuite le groupe de travail IETF de ces déclarations ? L'IETF n'impose pas une politique unique à ses groupes de travail à ce sujet. Le groupe peut décider d'ignorer le brevet (n'oubliez pas que la grande majorité des brevets logiciels sont futiles : technologies évidentes, communes longtemps avant le brevet, etc). Il peut aussi décider de changer la technique en cours de normalisation pour contourner le brevet (et c'est la crainte de ce résultat qui motive certaines entreprises à garder leurs brevets secrets).
Naturellement, il y a des tricheurs. C'est ainsi que RIM ou Huawei (dans le RFC 6468) avaient caché leurs brevets. C'est à cause de ces tricheurs qu'il faut prévoir la possibilité de sanctions, dont la gravité doit être adapté à chaque cas.
Qui va décider de l'action à entreprendre contre les tricheurs (section 3) ? Les chefs du groupe de travail concernés, puisque ce sont eux qui connaissent le mieux tous les détails et, s'ils ne le peuvent pas, le directeur de zone (Area Director) responsable du groupe de travail.
La section 4 liste les sanctions elles-mêmes. Aucune n'est très effrayante, l'IETF n'ayant pas de pouvoirs particuliers. À noter que la liste présentée ici n'est pas exhaustive, d'autres sanctions pourront être imaginées dans le futur. Donc, en gros, par ordre de sévérité croissante, quelques-uns de ces sanctions :
Comme toute les décisions à l'IETF, elles sont susceptibles d'appel devant l'IESG (section 5 et la section 6.5 du RFC 2026).
À noter que l'annexe A contient des indications pour ceux qui auront à choisir et appliquer les sanctions. Rien ne sera automatique et les décideurs devront faire preuve de jugement. Parmi les points qu'ils devront examiner avant de décider figurent l'ancienneté de la personne en cause dans l'IETF, le moment exact où le brevet a été révélé, la place de l'individu dans le travail en question (contributeur occasionnel ou principal ?), qualité des excuses présentées, etc.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : P. Hoffman (VPN Consortium), J. Schlyter (Kirei AB)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dane
Première rédaction de cet article le 19 août 2012
À chaque seconde, d'innombrables transactions sur
l'Internet sont protégées contre l'écoute et la
modification malveillante par le protocole
TLS. Ce dernier est capable de
chiffrer la session (pour la protéger contre
l'écoute par un tiers) et d'authentifier le pair avec qui
on parle (pour s'assurer qu'on n'est pas en train de communiquer avec
un usurpateur). Comment TLS authentifie t-il ? La méthode la plus
courante aujourd'hui est de se servir de
certificats X.509
vérifiés (en théorie) par une Autorité de
Certification. Ce mécanisme repose sur une confiance
aveugle dans de très nombreuses organisations, et a de nombreuses faiblesses,
comme on l'a vu en 2011 où le piratage de
plusieurs AC a permis à des attaquants d'obtenir de « vrais-faux »
certificats, y compris pour des organisations qui n'étaient pas
clientes des AC piratées. La démonstration étant ainsi faite que X.509
n'était pas digne de la confiance que certains lui accordent, il
restait à concevoir une meilleure solution. Rendue possible par le
déploiement de DNSSEC, voici
DANE (DNS-based Authentication of Named Entities) et ses enregistrements
DNS TLSA
. DANE permet à
chacun de publier de manière sécurisés ses certificats, bouchant ainsi
les vulnérabilités de X.509, ou permettant même de s'en passer
complètement.
Avant de décrire DANE, il faut comprendre le fonctionnement de X.509, afin de voir pourquoi il ne garantit pas grand'chose en matière de sécurité. (La section 1 du RFC contient une description plus détaillée.) Un client qui se connecte à un serveur et qui craint, souvent à juste titre, que la session soit écoutée, voire modifiée par un attaquant situé sur le chemin, va utiliser le protocole TLS, normalisé dans le RFC 5246 pour chiffrer la session. (TLS est utilisé dans de nombreuses applications, la plus connue étant le HTTPS du RFC 2818, celui du petit cadenas dans le navigateur Web.) Ce chiffrement le protège contre l'écoute passive. Mais d'autres risques se cachent derrière. Si le client croit parler à une machine alors qu'en fait, par le biais de piratages portant sur DNS, BGP ou un autre protocole, il parle à la machine de l'attaquant, le chiffrement seul ne le protégera pas. Pour cette raison, TLS ajoute l'idée d'authentification. Le client peut vérifier que le serveur est bien ce qu'il prétend être (l'inverse, l'authentification du client par le serveur, existe aussi mais est plus rare).
Aujourd'hui, cette authentification se fait essentiellement via
X.509 (il existe d'autres voies, très
marginales, comme celle du RFC 6091). Le
principe de X.509 est le suivant. La clé
publique du serveur TLS est contenue dans un
certificat, contenant le nom du serveur, et signé par une autorité reconnue. En
vérifiant la signature, le client TLS peut s'assurer qu'il parle bien
à la machine souhaitée (on dit que TLS associe un
nom à une clé). Si un navigateur Web se connecte à
https://www.dns-oarc.net/
, il doit recevoir un
certificat signé et comportant le nom
www.dns-oarc.net
(la question du nom à indiquer
est très compliquée dans X.509, voir le RFC 6125). Notez qu'en fait, TLS utilise un sous-ensemble de
X.509, spécifié dans le RFC 5280 mais ce n'est
pas essentiel pour cette analyse.
Mais quelles sont les « autorités reconnues » ? La plupart du temps, elles ont été choisies et configurées par l'éditeur du logiciel utilisé. Si vous être adepte de Firefox, c'est la fondation Mozilla qui a décidé que les centaines d'autorités de certification (AC) que connait ce logiciel sont dignes de confiance.
Tout repose donc sur l'AC. Si une AC est malhonnête, ou bien a été piratée, elle peut émettre des vrais-faux certificats, qui tromperont l'utilisateur. Cette dépendance vis-à-vis d'un tiers est traditionnellement une des faiblesses les plus critiquées de X.509, d'autant plus que les dites AC, pressées par des considérations économiques, ne font pas toujours de gros efforts pour vérifier les titulaires de certificats.
Mais il y a pire. Rappelez-vous qu'il suffit à un certificat de comporter la signature d'une AC pour être accepté. Il n'y a pas de limites aux noms pour lesquelles les AC peuvent s'engager. Si l'AC DigiNotar est reconnue comme AC de confiance par un client TLS, elle peut signer des certificats pour n'importe quel nom, même si le nom est géré par une organisation qui a choisi une autre AC. C'est le problème le plus fondamental de X.509. Ce système, conçu par l'UIT, supposait que le monde se divisait en deux, une masse de clients payants et une oligarchie d'AC toutes parfaites. Ce modèle a éclaté devant la réalité des choses : les AC ne sont pas toutes parfaites. L'année 2011 a montré que cette vulnérabilité, connue depuis longtemps, n'était pas purement théorique. Le détournement de l'AC Comodo, puis le piratage de DigiNotar, au cours de l'opération Tulipe Noire, ont montré que les AC, non seulement étaient vulnérables mais que, en outre, les vrais-faux certificats marchaient bien. C'est ainsi que le gouvernement iranien a pu, suite à Tulipe Noire, obtenir de vrais-faux certificats pour Gmail (alors que Google n'était pas client de DigiNotar), lui permettant d'observer le trafic de ses citoyens.
Bon, tout cela est bien triste, mais comment DANE empêche t-il
cela ? Le principe est, plutôt que d'introduire un nouvel acteur, de
réutiliser une infrastructure existante, le
DNS avec des identificateurs existants, les
noms de domaine. Le certificat est publié dans le DNS et
signé avec DNSSEC (je
schématise : lisez plus loin pour une description complète) et le
client TLS peut alors le vérifier. Bien sûr, le piratage d'un
registre DNS (ou d'autres acteurs) permettra de
court-circuiter cette protection mais l'énorme avantage de cette
technique est qu'on n'a pas besoin de faire confiance à toute la
planète, seulement aux fournisseurs qu'on a choisi (et desquels on
dépendait déjà). Ainsi, si on
décide de fonder son identité en ligne sur un
.com
, on dépend de la
sécurité de VeriSign mais seulement
de celle-ci. En cas de piratage ou de malhonnêteté de
VeriSign, seuls les .com
seront affectés, les
gens qui ont un .fr
(par
exemple) ne seront pas touchés.
Cette idée avait été documentée dans le RFC 6394, premier RFC du groupe de travail DANE, créé à la fois en
raison des faiblesses manifestes de X.509, et parce que le déploiement
de DNSSEC rendait réaliste une solution
alternative. Le protocole DANE réalise le cahier des charges du RFC 6394 et crée pour cela un nouveau type
d'enregistrement DNS, TLSA
(ne cherchez pas une
signification à ce sigle, il n'en a officiellement pas). Tel
qu'actuellement normalisé, DANE couvre les besoins de
HTTPS mais, pour des protocoles avec une
indirection dans le DNS (comme les MX
du RFC 5321 ou les
SRV
du RFC 6120), c'est plus compliqué et il faudra attendre de
futurs RFC pour adapter les TLSA
à ces cas.
Notez que d'autres protocoles peuvent aussi mettre leurs clés dans le DNS comme SSH avec le RFC 4255 et IPsec avec le RFC 4025.
À noter que notre RFC demande que les enregistrements DANE/TLSA soient protégés par DNSSEC mais ne précise pas comment le client le vérifie. Il existe plusieurs façons de déployer DNSSEC et notre RFC préfère ne pas trancher prématurément.
Bien, maintenant, place à DANE lui-même. Le cœur de ce
protocole est le nouveau type d'enregistrement DNS
TLSA
, présenté en section 2. Il a le type 52
dans le registre IANA (cf. section 7).
Un enregistrement TLSA comprend :
Le premier, « Utilisation du certificat », voit ses valeurs possibles enregistrées dans un nouveau registre IANA (voir aussi la section 7). On pourra ainsi ajouter de nouvelles utilisations sans modifier ce RFC. Pour l'instant, sont définies les valeurs numériques :
TLSA
est alors utilisé
comme « contrainte sur l'AC ». Il spécifie un certificat qui doit être
présent dans la chaîne des certificats utilisés pour la validation
X.509. Il vient donc en complément de X.509. Son
rôle est de lutter contre des attaques par une AC qui n'est pas celle
choisie. Si on est client de GeoTrust, on peut
mettre le certificat de l'AC GeoTrust dans l'enregistrement
TLSA
et, ainsi, un vrai/faux certificat émis par
Comodo ou DigiNotar sera refusé. L'utilisation 0 est la plus
traditionnelle, sans remplacer X.509 et bouchant simplement sa
principale vulnérabilité. Attention si vous changez d'AC, il faudra
quand même penser à mettre à jour vos enregistrements
TLSA
.TLSA
indique le
certificat du serveur TLS (qui devra toujours, comme dans
l'utilisation 0, être validé selon les
règles du RFC 5280). Il s'agit d'une « contrainte sur le
certificat » et plus seulement sur l'AC. Il permet donc de se protéger
contre une attaque par sa propre AC. Si elle décide d'émettre un
nouveau certificat sans vous prévenir, il ne sera pas
accepté. Attention en pratique, on change de certificats plus souvent
que d'AC et il ne faut pas oublier de mettre à jour le
TLSA
.Depuis le RFC 7218, il y a également des mnémoniques standards pour ces valeurs, ainsi que celles des deux champs suivants.
Le sélecteur, quant à lui, fait également l'objet d'un registre IANA. Actuellement, il compte deux valeurs numériques. D'autres pourront être ajoutées, sous la seule obligation d'une spécification écrite et stable :
TLSA
contient (dans
son champ « Données ») le
certificat complet.TLSA
ne contient que
la clé publique, omettant le reste du certificat.Et la méthode de correspondance ? Voici un nouveau registre IANA, et ses valeurs :
TLSA
est la valeur exacte, à comparer bit à bit avec celle récupérée dans
la session TLS.TLSA
est le condensat
SHA-256 de celle récupérée dans
la session TLS.Enfin, le champ de données contient, selon la valeur des autres champs, le certificat ou la clé publique, éventuellement condensées.
Voici des exemples d'enregistrement TLSA
au
format de présentation standard :
; Utilisation 0 (contrainte sur l'AC) ; Les données sont le condensat du certificat _443._tcp.www.example.com. IN TLSA ( 0 0 1 d2abde240d7cd3ee6b4b28c54df034b9 7983a1d16e8a410e4561cb106618e971 ) ; Utilisation 1 (contrainte sur le certificat) ; Les données sont le condensat de la clé publique _443._tcp.www.example.com. IN TLSA ( 1 1 2 92003ba34942dc74152e2f2c408d29ec a5a520e7f2e06bb944f4dca346baf63c 1b177615d466f6c4b71c216a50292bd5 8c9ebdd2f74e38fe51ffd48c43326cbc ) ; Utilisation 3 (déclaration d'un certificat local) ; Le certificat entier (abrégé ici) est dans les données _443._tcp.www.example.com. IN TLSA ( 3 0 0 30820307308201efa003020102020... )
Mais quel est ce nom bizarre dans les enregistrements,
_443._tcp.www.example.com
? Décrit en section 3,
le nom de domaine des enregistrements TLSA est
la concaténation du numéro de port d'écoute du
serveur TLS, du
protocole (TCP, SCTP,
etc) et du nom du serveur TLS. Ici, les enregistrements
TLSA
concernaient un serveur TLS
www.example.com
écoutant en TCP
sur le port 443, donc, sans doute du HTTPS. Avec du
SMTP sur TLS, ce serait sans doute _25._tcp.mail.example.com
.
À noter que cette convention de nommage est générique (pour tous les protocoles) mais qu'il est prévu que, dans le futur, d'autres conventions soient adoptées, par exemple pour des protocoles où la relation entre service et serveur est plus complexe que dans le cas d'HTTP.
Une fois ces enregistrements publiés, comment le client TLS les
utilise-t-il ? La section 4 décrit les règles à suivre. D'abord, le
client TLS doit demander les enregistrements TLSA
et vérifier s'ils sont utilisables :
TLSA
contiennent une utilisation, un sélecteur ou
une méthode de correspondances inconnues, ils doivent être ignorés,TLSA
n'est utilisable,
Le but de ces règles est de s'assurer qu'un attaquant ne peut pas
effectuer une attaque par repli, où il convaincrait le client qu'il
n'y a pas d'enregistrements TLSA
(RFC 6394, section 4). DNSSEC
empêchera ce repli et DANE coupera alors la connexion TLS.
Pour les gens qui préfèrent le pseudo-code, les mêmes règles sont disponibles sous cette forme dans l'annexe B. Attention, c'est le texte de la section 4 qui est normatif, le pseudo-code n'étant là qu'à titre d'illustration. Par exemple, comme tous les pseudo-codes procéduraux, il « sur-spécifie » en indiquant un ordre d'évaluation qui n'est pas obligatoire.
Si le client TLS fait la validation DNSSEC lui-même (comme le permettent des
bibliothèques comme libunbound), rien de spécial à dire. Mais s'il confie
la validation à un résolveur externe (et se contente de tester que le
bit ad
- Authentic Data - est
bien mis à un dans la réponse), il doit s'assurer que le chemin
avec ce résolveur est sûr : résolveur sur
localhost
, ou bien communication avec le
résolveur sécurisée par TSIG (RFC 8945) ou
IPsec (RFC 6071). C'est
le problème dit de « la sécurité du dernier kilomètre ».
Comme vous voyez, le principe est très simple. Mais, comme souvent en sécurité, il y a plein de détails pièges derrière. La section 8 se consacre à l'examen de ces pièges. D'abord, DANE dépend de DNSSEC (RFC 4033). Si on n'a pas de DNSSEC, ou s'il est mal géré, tout s'écroule. Pas question d'envisager de déployer DANE avant d'avoir une configuration DNSSEC solide. (Au début du groupe de travail DANE à l'IETF, il était prévu que DNSSEC soit facultatif pour des utilisations comme 0 et 1, où DANE ne vient qu'en addition de X.509. Techniquement, ça se tenait mais cela compliquait l'analyse de sécurité, et les messages à faire passer. Donc, désormais, DNSSEC est obligatoire et on ne discute pas !)
DANE dépendant du DNS, cela veut dire qu'un administrateur DNS qui
devient fou ou méchant peut changer les A
,
AAAA
et TLSA
d'un serveur et
sans que cela soit détecté. Beaucoup d'AC émettant des certificats
juste après avoir vérifié un échange de
courrier, cela ne change donc pas grand'chose
par rapport à X.509.
Par contre, si jamais le mécanisme de sécurité pour changer les
TLSA
était plus faible que celui pour changer les
A
et AAAA
, alors, là, il y
aurait un problème. La solution est simple : tous les enregistrements
DNS doivent avoir le même niveau de sécurité.
Les enregistrements TLSA
d'utilisation 0 et 1
viennent en supplément de X.509. Leur analyse de sécurité est donc
relativement simple, ils ne peuvent pas affaiblir la sécurité qui
existe. En revanche, ceux d'utilisation 2 et 3 sont nouveaux : ils
peuvent permettre des choses qui n'existaient pas en X.509. Il faut
donc bien réfléchir à l'AC qu'on indique par un certificat
d'utilisation 2. En mettant son certificat dans un enregistrement
TLSA
, on lui donne tous les droits.
Comment fait-on une révocation avec DANE ? Les TTL normaux du DNS s'appliquent mais, si un méchant fait de l'empoisonnement DNS, il pourra réinjecter de vieux enregistrements. La seule protection est donc la durée de validité des signatures DNSSEC : trop courte, elle peut entraîner des risques pour la résilience de la zone (signatures expirées alors qu'on n'a pas eu le temps de les refaire), trop longue, elle permet à un méchant de continuer à utiliser un certificat normalement révoqué (attaque par rejeu, voir l'article de Florian Maury).
Au fait, petit piège avec les TTL : si tous les serveurs résolveurs gèrent les TTL proprement, il est courant que le résultat d'une requête DNS soit gardé dans l'application sans tenir compte de ces TTL, ce qui peut être gênant pour des applications qui restent ouvertes longtemps (comme un navigateur Web). Un client DANE doit donc veiller à toujours obtenir ses données d'un résolveur (ou à gérer les TTL lui-même) pour ne pas risquer de se servir de vieilles données (section 8.2).
La section 8.1 compare DANE aux AC classiques. Un registre de noms
de domaines qui fait du DNSSEC a des responsabilités qui ressemblent
assez à celles d'une AC : distribuer la clé publique (qui doit être
toujours disponible) de manière authentifiée, garder la clé privée
vraiment secrète (par exemple dans des HSM),
avoir des plans prêts d'avance pour le cas d'une compromission de la
clé, etc. D'abord, une
évidence : les acteurs de l'industrie des noms de domaine
(registres,
registrars, hébergeurs DNS)
ne sont pas meilleurs (ou pires) que les AC X.509. Comme elles, ils
peuvent être incompétents ou malhonnêtes ou se faire pirater. On peut
même penser que certains de ces acteurs ont une culture sécurité faible
ou inexistante, très inférieure à celle de la pire AC. Mais la force
de DANE ne vient pas de ce que les acteurs du DNS seraient magiquement
meilleurs que ceux de X.509. Elle vient du fait qu'on choisit ses
fournisseurs. Avec X.509, c'est la sécurité de la plus mauvaise AC
qui compte puisque n'importe quelle AC peut émettre des certificats
pour n'importe qui (la faille énorme de X.509). Avec DANE+DNSSEC, on revient à un modèle plus
sérieux en matière de sécurité : il faut faire confiance à ses
fournisseurs, certes, mais au moins on les choisit. Un déploiement
correct de DANE implique donc une évaluation des acteurs qu'on a
choisi. Si on a un .com
,
on dépend de la sécurité et de l'honnêteté de
VeriSign. En revanche, un piratage du registre
de .lu
n'aura pas de
conséquence. Si on choisit à la place un
.lu
, on dépend de la
sécurité et de l'honnêteté de Restena mais plus
de celle de VeriSign. Et ainsi
de suite. (Tout ceci est également vrai pour les autres techniques de
pubication de clés dans le DNS comme celles du RFC 4255.)
Le DNS étant hiérarchique, il faut ajouter à ses fournisseurs directement choisis, les registres situés « au dessus ». Ainsi, une compromission de la clé privée de la racine affecterait tous les domaines (avec X.509, c'est la compromission de n'importe laquelle des centaines d'AC qui aurait ce résultat), ce qui justifie les mesures coûteuses adoptées pour gérer la clé de la racine (meilleures que celles de la plupart des AC X.509).
Comme indiqué plus haut à propos de la sécurité du dernier kilomètre, un problème classique avec DNSSEC est le lien entre l'application cliente et le résolveur validant. Le RFC recommande (section 8.3), pour une sécurité correcte, que le résolveur soit sur la même machine (c'est très facile avec des logiciels comme dnssec-trigger). Aujourd'hui où le moindre téléphone sait jouer des films en haute résolution, le temps de calcul lié à la validation cryptographique n'est plus forcément un obstacle. La section A.3 revient en détail sur ce problème du dernier kilomètre.
Les gens qui aiment les problèmes opérationnels liront avec plaisir l'annexe A, qui rassemble plein de bons conseils sur le déploiement de DANE.
Maintenant, voyons les mises en œuvre existantes de DANE/TLSA. Il faut bien voir que ce mécanisme est encore récent. On ne trouve que peu d'enregistrements TLSA dans la nature, et aucun navigateur Web connu ne gère encore le TLSA standard (DANE ne nécessite par contre aucune modification du serveur Web, uniquement du client Web, et des serveurs DNS). Néanmoins, il existe plusieurs outils.
D'abord, côté DNS. BIND et NSD peuvent tous les deux être serveur maître pour une zone qui contient des enregistrements TLSA (nsd connait DANE/TLSA à partir de la version 3.2.11). Pour un serveur esclave, pas de problème, TLSA est juste un type d'enregistrement inconnu, que le serveur peut servir sans le comprendre. Pour valider ses zones DNS, l'excellent outil validns lit et vérifie le TLSA depuis juillet 2012.
D'accord, mais un être humain normal ne va pas fabriquer les enregistrements TLSA à la main. Et, même s'il le faisait, il serait souhaitable de vérifier leur cohérence avec le certificat présenté par le serveur HTTP. C'est le rôle de l'outil Swede. Il permet, par exemple, de créer l'enregistrement TLSA à partir du certificat actuellement distribué par le serveur HTTPS :
% ./swede create www.afnic.fr No certificate specified on the commandline, attempting to retrieve it from the server www.afnic.fr. Attempting to get certificate from 192.134.4.20 Got a certificate with Subject: /1.3.6.1.4.1.311.60.2.1.3=FR/1.3.6.1.4.1.311.60.2.1.2=Ile de France/1.3.6.1.4.1.311.60.2.1.1=MONTIGNY LE BRETONNEUX/businessCategory=Non-Commercial Entity/serialNumber=0002 414757567/C=FR/ST=Ile de France/postalCode=78180/L=Montigny Le Bretonneux/OU=AFNIC/O=AFNIC/CN=www.afnic.fr _443._tcp.www.afnic.fr. IN TYPE52 \# 35 010001ed8a70a9c8783777e463232ef343aa32f2bbd6aa0182e6a0fc929b64c8e06518 Attempting to get certificate from 2001:67c:2218:2::4:20 Got a certificate with Subject: /1.3.6.1.4.1.311.60.2.1.3=FR/1.3.6.1.4.1.311.60.2.1.2=Ile de France/1.3.6.1.4.1.311.60.2.1.1=MONTIGNY LE BRETONNEUX/businessCategory=Non-Commercial Entity/serialNumber=0002 414757567/C=FR/ST=Ile de France/postalCode=78180/L=Montigny Le Bretonneux/OU=AFNIC/O=AFNIC/CN=www.afnic.fr _443._tcp.www.afnic.fr. IN TYPE52 \# 35 010001ed8a70a9c8783777e463232ef343aa32f2bbd6aa0182e6a0fc929b64c8e06518
[Le certificat est le même, qu'on accède au serveur en
IPv4 ou en IPv6 mais
Swede ne le sait pas à l'avance, d'où les deux connexions.] Notez
aussi que Swede formatte l'enregistrement DNS comme un type inconnu,
ce qui permet de le charger dans n'importe quel serveur. Il ne reste
donc qu'à mettre le _443._tcp.www.afnic.fr. IN TYPE52 \# 35
010001ed8a70a9c8783777e463232ef343aa32f2bbd6aa0182e6a0fc929b64c8e06518
dans son fichier de zone.
Swede permet également de vérifier un enregistrement TLSA existant.
Maintenant, côté « divers », la bibliothèque NSS a un
patch pour faire du TLSA mais il semble ancien en
non maintenu : https://mattmccutchen.net/cryptid/#nss-dane
.
L'outil sshfp, en dépit de son nom, fait aussi du TLSA. Il devrait être remplacé par hash-slinger.
Quelques petits trucs utiles, maintenant. Pour créer une clé à partir d'un certificat (afin d'utiliser le sélecteur 1), en Python, avec M2Crypto :
from M2Crypto import X509 cert = X509.load_cert('/path/to/cert') print cert.get_pubkey().as_der() print cert.get_pubkey().as_text()
Avec OpenSSL, pour un sélecteur 1 (uniquement la clé) openssl x509 -pubkey
-in ... | openssl rsa -pubin | head -n -1 | tail -n +2 | base64
-d
doit marcher (ajouter sha512sum -
à
la fin du tube pour condenser, méthode de
correspondance 2). Pour l'extraire d'un
serveur TLS existant :
% openssl s_client -showcerts -connect mattmccutchen.net:443 < /dev/null 2> /dev/null | \ openssl x509 -pubkey | openssl rsa -pubin | \ head -n -1 | tail -n +2 | base64 -d | sha256sum - writing RSA key 62d5414cd1cc657e3d30ea5e6d0136e92306e725413c616a51cab4b852c70a1c -
On trouve aujourd'hui des enregistrements TLSA
dans de nombreux domaines. Voici quelques exemples avec le dig de BIND 9.9.1-P2 (sorti en juillet 2012). Notez
le bit ad
mais rappelez-vous qu'on ne peut s'y
fier que si le résolveur est honnête et que la
liaison avec le résolveur est protégée (même machine, ou bien TSIG,
IPsec, tunnel TLS ou méthode équivalente) :
% dig TLSA _443._tcp.dane.rd.nic.fr ... ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 5 ... ;; ANSWER SECTION: _443._tcp.dane.rd.nic.fr. 1 IN TLSA 3 0 1 63C43B664AB2EC24E5F65BF6671EE1BE48E6F12660FEEF9D7BB1EDA7 7499EDC0 _443._tcp.dane.rd.nic.fr. 1 IN RRSIG TLSA 5 6 1 20120810085609 20120711085609 24765 dane.rd.nic.fr. FXClnltKo1ZBKSHjmflwcIUIT5bo8AibfZnJJCLqhufBs4UW8HFGcdXU Hys0znMOmsoJVbeoj2GTRaNr1CoMoy/RJRMczo7CP32o6Z0m4BQeOgDf FSiGEG2YUMbwbiVyAgAQhunv1QdqFxvU+uoKCXs0LMLe/SM/vz8oHSJP 2zc= ... % dig TLSA _5269._tcp.proxima.lp0.eu ... ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 4, AUTHORITY: 5, ADDITIONAL: 5 ... ;; ANSWER SECTION: _5269._tcp.proxima.lp0.eu. 10800 IN CNAME _tlsa.proxima.lp0.eu. _5269._tcp.proxima.lp0.eu. 10800 IN RRSIG CNAME 10 5 10800 20120920174820 20120718212409 42615 lp0.eu. GjhRHziHqL9OGkOVvuukyCt7wkD1VzUs5USbBgy3lHBUpfzcxydXFEMR VUiWRwmKDslIrM33tltjKax3jYA8anet8+TTqehoQJ72M37iN2nvx7zg 5JktVDBbYXkJtwzznFADVOT+6/2K243gGh5gjibogwLo9mzUer64jvIh VGWqFOG7HIP3/l2Ajg+x7q/Pe6PPB0n75Qtuu7e8zc13DA== _tlsa.proxima.lp0.eu. 3600 IN TLSA 3 1 2 490D884C778E9031D8F1BDFB4B6E7673418BAD66CB8115E36CED911E A612B688AE7CC1909BF23391574E41865E41A51E03ECBC18FA6125A5 A14C7D2BA5E0CFF3 _tlsa.proxima.lp0.eu. 3600 IN RRSIG TLSA 10 4 3600 20120920183558 20120719092413 42615 lp0.eu. t9xaSN+Owj41DrtKEeqJhwqcAGjLAfYF+PGjOuT32+hG8MI6XgSrXBmL +HaPXF6rgAdk1BoAkwLij4kpuPu50hIZ3tefTFduO2QU1S8YVEcMys4C FDFz70tGuhcBtyODLxMIWw1zgQGLD/i8dyQnNsllgtNkuJZVJVguAOAp Y35EjlFOXR9sYbvNJnCGcpxqNEZ3FjVmKVVnoOsW+irJwQ==
À noter la section A.2.1.1 pour l'utilisation des alias avec DANE, comme dans ce dernier cas.
% dig TLSA _443._tcp.ulthar.us ... ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 5, ADDITIONAL: 5 ... ;; ANSWER SECTION: _443._tcp.ulthar.us. 3600 IN TLSA 3 1 1 7EB3A92457701C1A99742E902337BAE786B656ABAF1B13DFE3616D09 90C4F4D8 _443._tcp.ulthar.us. 3600 IN RRSIG TLSA 8 4 3600 20120812104422 20120713104422 8550 ulthar.us. nqZ16HERJMQsAklddkhlU2r9TgHL0VUNxgtxmB5lKobI/1J+i66psClv 2hUWEN2EVudYVtViRF/b2b8JOl1ZmSoTVqxk0sF3LEr4UaUJMbO99SOB PiQjXKFI9XXoKyMz71zQiPSgFMos5dAxoKEhFTpAFJI2r3Jrl8QMvFmv +xo= ... % dig TLSA _443._tcp.nohats.ca ... ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 5, ADDITIONAL: 7 ... ;; ANSWER SECTION: _443._tcp.nohats.ca. 3600 IN TLSA 1 0 1 6BCFF9A283336DD1ED99A9C40427741B5658863BD54F0A876A2BC4BF 8D822112 _443._tcp.nohats.ca. 3600 IN RRSIG TLSA 8 4 3600 20120730210435 20120716182008 28758 nohats.ca. VrY1bsk9IEijZ7yu9jiWUhgY0nsWuJGm1nDWBRI0X1iULJrJE1ZaXCFM PaoY3txlkhqPNbUq3AymKdtKXq9dtUVHF5UQCWnEm29X1YoU5I/Z5in5 VplLx3yp9pib3f7TifgC4Jw0dmYwWCr6jH2tQ1ELFaV2eDN1Li5Wizuk 0M0=
On peut vérifier le TLSA
avec
OpenSSL. Ici, sur
mattmccutchen.net
:
% dig +short TLSA _443._tcp.mattmccutchen.net 3 0 1 F9A682126F2E90E080A3A621134523C6DE4475C632A00CF773E6C812 A321BB25
Utilisation 3 (donc le serveur TLS doit envoyer le certificat correspondant) avec sélection 0 (tout le certificat) condensation en SHA-256. Testons :
% openssl s_client -showcerts -connect mattmccutchen.net:443 < /dev/null 2> /dev/null | \ openssl x509 -outform der | sha256sum - f9a682126f2e90e080a3a621134523c6de4475c632a00cf773e6c812a321bb25 -
Je n'ai pas encore trouvé de vrai enregistrement TLSA pour d'autres protocoles que HTTP. C'est logique, puisque ceux-ci impliquent en général une indirection et sont donc plus complexes.
Enfin, si vous voulez un serveur HTTPS où DANE ne va
pas marcher, rogue.nohats.ca
a un enregistrement TLSA délibérement incorrect.
Autres articles sur DANE/TLSA :
Date de publication du RFC : Août 2012
Auteur(s) du RFC : S. Moonesamy
Pour information
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 24 août 2012
Les URI commencent par un
plan (scheme en anglais),
indiquant leur type. Un plan très répandu en pratique n'avait jamais
été normalisé : « about:
». Il permet de décrire des
URI internes au navigateur. Le plus célèbre est le
about:blank
qui permet d'afficher une page
blanche. Ce plan, et ce premier URI utilisant ce plan sont désormais
officiellement spécifiés dans ce RFC.
Le plan est souvent appelé par erreur « protocole ». Mais il ne
correspond pas toujours à un protocole, comme c'est le cas de notre
about:
. Celui-ci sert à tout, pages spéciales qui
n'ont pas été récupérées sur le Web, accès à la
configuration du navigateur et même amusants
œufs de Pâques. Il figure désormais dans
le registre des plans.
La section 2 indique la syntaxe formelle et la sémantique des URI
about:
. Un point
important est que, contrairement aux URI http:
,
il n'y a pas de structure. Tout le texte après
about:
indique la ressource cherchée, sans qu'on
puisse détailler des composants dans ce texte. Certains de ces textes
sont eux-mêmes normalisés (comme le blank
cité
plus haut) mais pas tous. Et, comme about:
décrit
des ressources internes au navigateur, il est courant et normal que
ces URI about:
soient spécifiques d'un navigateur
particulier. Attention donc aux URL about:
dans cet article, certains ne
marcheront pas dans votre navigateur.
Les noms « bien connus » sont désormais enregistrés (section 5.2). Pour
l'instant, le registre
IANA ne compte que
blank
(décrit sommairement en section 3) et
invalid
(qui vient d'une autre norme, au
W3C) mais d'autres pourront s'y ajouter après la
publication de ce RFC. Cet enregistrement est recommandé dès qu'au
moins deux navigateurs connaissent ce nom. La procédure à suivre (cf. RFC 5226) est « premier arrivé, premier servi ». Ce principe n'a
pas fait l'objet d'un consensus immédiat à
l'IETF, certains auraient préféré une procédure
plus formelle, « Spécification nécessaire ».
Il y a même des questions de sécurité liées aux URI
about:
(section 4) car ils donnent parfois accès à des
informations sensibles comme des mots de passe.
Voici maintenant quelques URI about:
à tester
dans votre navigateur. N'hésitez pas à me raconter lesquels marchent
et à m'en envoyer d'autres. De manière surprenante, il n'est pas
toujours facile d'avoir de la documentation stable et fiable sur les
about:
. Pour Firefox, on
peut consulter « Firefox about: pages » et pour Chrome « Google
Chrome's about: Pages » ou bien « Behind
the Scenes of Google Chrome: Optimizing and
Troubleshooting », un bon article sur les réglages de
Chrome pour maximiser les performances, qui fait beaucoup appel aux about:
. Voici
les exemples. Vous noterez que je n'en ai pas fait des liens
hypertextes car des navigateurs comme Firefox n'acceptent pas tous les
liens about:
dans une page Web (sans doute pour
des raisons de sécurité). Il faudra donc copier/coller :
about:blank
, la page
blanche,about:config
, accès à la
configuration du navigateur (marche sur Firefox, il offre plein
de possibilités),about:about
, le
méta-about:
, à propos de l'à-propos (marche avec
Firefox et Chrome),about:robots
, un joli
œuf de Pâques (marche sur Firefox),about:dns
, donne accès aux
informations DNS, utilise avec
Chrome qui joue de drôles de jeux avec le
DNS. Il est très riche et des explications ne sont pas inutiles. Voir
« DNS
Prefetching (or Pre-Resolving) », « Google
Chrome DNS Fetching », « Chrome
Networking: DNS Prefetch & TCP Preconnect » ou « What does the about:dns page in Google Chrome show? ».Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Lindgren (SICS), A. Doria
(Consultant), E. Davies (Folly
Consulting), S. Grasic (Lulea University of Technology)
Expérimental
Première rédaction de cet article le 1 septembre 2012
Les protocoles traditionnels de routage (comme, mettons, OSPF) sont conçus dans l'idée que les machines sont connectées et joignables en permanence, sauf rares pannes. Mais il existe des réseaux où cette hypothèse ne se vérifie pas. Par exemple, dans l'espace, domaine traditionnel du groupe de recherche DTN, il est fréquent que la communication soit l'exception plutôt que la règle. Comment router dans ces conditions ? Ce nouveau RFC propose un mécanisme de routage adapté à des connexions intermittente, Prophet.
On n'est plus dans le monde tranquille de l'Internet, avec ses connexions stables et ses problèmes connus. Ici, on est à l'IRTF, l'équivalent de l'IETF pour les recherches avancées. À l'IRTF, on étudie des problèmes comme les connexions entre vaisseaux perdus dans l'espace, ou groupes d'éleveurs samis se déplaçant en Laponie, ou encore entre objets communiquants se déplaçant sans cesse et ne venant que rarement à portée de radio des autres objets. C'est là que Prophet devient utile. (Voir le RFC 4838 pour avoir une meilleure idée des sujets sur lesquels travaille le groupe DTN.). Les protocoles de routage traditionnels (cf. section 1.3), conçus pour trouver le chemin optimum dans le graphe et pour éviter les boucles, n'ont pas réellement de sens ici (par exemple, l'émetteur et le destinataire peuvent ne jamais être allumés en même temps).
Le principe de base de Prophet est d'utiliser l'histoire des rencontres entre deux machines. Si deux engins viennent en contact radio de temps en temps, puis se re-séparent, la mise en œuvre de Prophet se souviendra de ses contacts et pourra se dire « ah, j'ai un bundle (cf. RFC 5050 et RFC 6255) à passer à Untel et, justement, je l'ai vu trois fois dans la dernière semaine, donc je garde le bundle, je devrais le revoir bientôt. » Au moment du contact, les machines Prophet échangent aussi des informations sur les machines qu'elles ont rencontré donc la décision peut aussi être « ah, j'ai un bundle à passer à Untel, je ne l'ai jamais croisé mais Machin l'a souvent fait et, justement, j'ai vu trois fois Machin dans la dernière semaine, donc je garde le bundle, je devrais revoir Machin bientôt, et je lui refilerai le bundle et la responsabilité. »
Une manière courante de résoudre ce problème est d'envoyer le message (dans l'architecture DTN, les messages sont découpés en unités de transmission appelées bundles) à tous ceux qu'on croise, qui le transmettent à leur tour à tous ceux qu'ils croisent et ainsi de suite jusqu'à ce que tout le monde l'ait eu. C'est ce qu'on appelle l'inondation et la mise en œuvre la plus connue de ce principe est dans Usenet (RFC 5537). Mais, dans Usenet, on supposait que tous les nœuds étaient intéressés par le message. Ici, un seul destinataire le veut et, pour ce cas, l'inondation fonctionne mais gaspille pas mal de ressources. Elle marche bien lorsque les ressources ne sont pas un problème mais Prophet se veut utilisable pour des réseaux d'objets communiquants, objets ayant peu de mémoire, de capacité réseau, et de processeur. Prophet adopte donc plutôt une démarche probabiliste : il ne garde que les routes les plus prometteuses, risquant ainsi de ne pas trouver de chemin vers la destination, mais limitant la consommation de ressources. Cet élagage des routes est la principale innovation de Prophet.
Pour échanger les routes (pas forcément les bundles), deux nœuds Prophet, lorsqu'ils se rencontrent, établissent un lien TCP entre eux. La mise en œuvre de Prophet doit donc pouvoir parler TCP et interagir avec le programme de gestion des bundles, pour pouvoir informer les besoins des bundles qu'on souhaite transmettre.
On notera que, comme toujours dans l'architecture DTN (Delay-Tolerant Networking, cf. RFC 4838), la transmission n'est pas synchrone : le message, découpé en bundles, va être bufferisé et pourra mettre « un certain temps » à atteindre sa destination. En outre, il est parfaitement possible que la source et la destination du message ne soient jamais allumés et joignables en même temps : on fait donc du réseautage transitif (le message d'Alice est transmis à René, qui le passe à Rose, qui l'envoit finalement au destinataire, Bob). L'annexe A contient un exemple plus détaillé.
À noter que Prophet est utilisé pour des connexions intermittentes, ce qui ne veut pas dire aléatoires. Elles peuvent au contraire être très prévisibles (cas d'engins spatiaux sur leur orbite, ou cas de déplacement d'objets sur un rythme circadien). D'autre part, Prophet n'est pas seulement utile pour le cas où les nœuds se déplacent mais aussi pour celui où ils sont fixes mais souvent en hibernation, par exemple pour économiser du courant (capteur industriel fixé dans un ouvrage d'art, par exemple). Dans les deux cas, la connectivité est intermittente et ce sont les mêmes solutions qu'on utilise. (Voir « Epidemic Routing for Partially Connected Ad Hoc Networks »).
Les détails pratiques, maintenant. Le RFC est long et il y a beaucoup de détails à prendre en compte. Ce qui suit est donc un simple résumé. La section 2 présente l'architecture de Prophet. À son cœur, la notion de « probabilité de remise [d'un message] » (delivery predictability). Notée P_, définie pour tout couple de machines (A, B), comprise entre 0 et 1, c'est la principale métrique de Prophet. Si P_(A, B) > P_(C, B), alors Prophet enverra les bundles destinés à B via C plutôt que via A. Attention, cette probabilité est asymétrique, P_(A, B) n'a aucune raison d'être égal à P_(B, A). Lorsque deux machines Prophet se rencontrent, elles échangent toutes les probabilités de remise qu'elles connaissent.
Au début, lorsqu'un nœud ne connait rien, la probabilité de
remise est indéfinie. À la première rencontre, elle passe
typiquement de 0,5 (paramètre P_encounter_first
),
reflétant l'ignorance encore grande. Au fur et à mesure des
rencontres, la probabiité augmente (lentement, pour ne pas se heurter
au plafond de 1 trop vite, paramètre delta
). Cette augmentation est amortie par un
intervalle minimum entre deux rencontres (paramètre
P_encounter
, pour éviter qu'un lien
WiFi très instable ne se traduise par plein de
rencontres, qui seraient en fait uniquement des rétablissements du
lien). C'est un résumé, la définition complète de ce calcul figure en
section 2.1.
Vous allez peut-être vous dire « mais les rencontres du passé ne signifient pas qu'elles vont se reproduire dans le futur ». En effet, si les rencontres sont complètement dues au hasard, le passé n'est pas un bon indicateur. Mais rappelez-vous que, dans les réseaux réels, les rencontres ne sont pas complètement aléatoires.
Ces différents paramètres ne sont pas forcément les mêmes pour tous les nœuds Prophet du réseau mais il est recommandé qu'ils soient proches. La section 3.3 détaille ces paramètres.
Ah, au fait, j'ai dit « quand deux nœuds Prophet se rencontrent ». Mais comment le savent-ils, qu'ils sont en vue l'un de l'autre ? Prophet nécessite que la couche 2 transmette cette information (« new neighbor in sight »). Comme détaillé en section 2.4, si Prophet peut tourner sur des protocoles de niveau 2 différents, il faut néanmoins que tous soient capables de signaler l'arrivée ou le départ d'un voisin, ainsi que l'adresse de niveau 2 pour le joindre.
La section 3 décrit le protocole utilisé entre les nœuds Prophet. Il permet d'échanger avec le pair :
La section 4 présente le format des messages Prophet. Ce format
utilise largement des TLV. Chacun a un type
(enregistré à
l'IANA, cf. section 7) et,
par exemple, le TLV Hello
, qui sert en début de
connexion, a le type 1. Les structure de données plus complexes, comme
la table de routage, sont encodés en SDNV (RFC 6256).
La section 5 fournit ensuite les machines à états du protocole.
Et la sécurité ? Ce sujet obligatoire est traité en section 6. Ce sera vite fait : Prophet n'a à peu près aucune sécurité. Il est très vulnérable car les exigences du cahier des charges (machines avec peu de ressources, connectées seulement de manière très intermittente) rendent difficile toute conception d'un protocole de sécurité.
Prophet ne fonctionne donc que si tous les nœuds participant sont gentils et œuvrent dans le but commun. Un mécanisme de sécurité simple serait donc que tous les nœuds utilisent une authentification et que seuls les membres d'une même tribu soient autorisés à faire du Prophet ensemble.
Que pourrait-il se passer, autrement ? Un nœud peut prétendre de manière mensongère qu'il a des routes, en mettant toutes les probabilités de remise à 1 (attaque du trou noir : les autres nœuds lui confieront des bundles qu'il ne pourra pas transmettre). Il peut annoncer un identificateur qui n'est pas le sien, piquant le trafic destiné à un autre. Il peut aussi générer des tas de bundles et les transmettre à ses malheureux pairs (une attaque par déni de service). Et tout ceci serait encore pire si un réseau Prophet était connecté à l'Internet via une passerelle. Les méchants pourraient alors attaquer l'Internet, cachés derrière les faiblesses de Prophet. Bref, un nœud sadique peut faire beaucoup de dégâts, difficiles à empêcher. D'où l'importance de l'authentification, pour ne jouer qu'avec des copains de confiance.
Les sections 8 et 9 de notre RFC décrivent l'expérience existante avec les mises en œuvre de Prophet. C'est un vieux protocole, bien que le RFC ne sorte que maintenant, et il a déjà été implémenté plusieurs fois. Le première fois, écrite en Java, était pour un environnement original, Lego Mindstorms. Elle est documentée dans la thèse de Luka Birsa. Une autre mise en œuvre, en C++, a tourné sur le simulateur OmNet. Encore une autre, pour Android, est décrite dans l'article « Bytewalla 3: Network architecture and PRoPHET implementation ».
Le tout a déjà été testé dans un environnement réel, dans des montagnes du nord de la Suède, en 2006, et raconté dans « Providing connectivity to the Saami nomadic community » (avec une jolie photo de renne dans l'article).
Date de publication du RFC : Juillet 2012
Auteur(s) du RFC : D. Borman (Quantum Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 26 juillet 2012
Le protocole TCP a une option nommée MSS (Maximum Segment Size, RFC 793, section 3.1) qui indique la taille maximale des segments (les paquets, au niveau TCP) qu'on peut recevoir. Quelle valeur y indiquer ? Faut-il tenir compte des options IP et TCP, dont la taille est variable ? Ce RFC a depuis été intégré dans la norme TCP, le RFC 9293.
Le RFC 879 semblait répondre clairement : on ne compte que
le segment lui-même, pas les en-têtes IP ou TCP. Mais le reste du RFC 879 détaillait des exemples qui ne correspondaient pas à cette
règle. Donc le RFC 1122 (section 4.2.2.6 et l'annexe A de notre RFC,
pour l'historique) revenait là-dessus. En effet, les options IP
et TCP sont de taille variable et peuvent changer pendant une
connexion TCP. La MSS ne sera alors pas optimum. La MSS ne pouvant pas
facilement changer en cours de connexion (elle est normalement envoyée
avec le paquet SYN
), il était nécessaire d'avoir une
meilleure règle pour sa détermination. Cela n'a pas empêché des
RFC ultérieurs comme le RFC 2385 de se prendre les pieds dans le tapis et de formuler
les règles incorrectes pour la prise en compte des options variables
(option d'authentification, dans le cas du RFC 2385).
Notre RFC 6691 réécrit donc la règle. La nouvelle (section 2) est « La MSS devrait être la MTU moins les en-têtes fixes d'IP et de TCP, sans les options de taille variable ». Notez le « fixes ». Si l'envoyeur des données met des options IP ou TCP, il doit donc diminuer la taille des données TCP, afin de respecter la MSS. Le but est d'éviter la fragmentation IP. Autrement, en-têtes fixes + options variables + MSS pouvaient dépasser la MTU, menant à la fragmentation.
L'en-tête fixe fait 20 octets en IPv4 et 40 en IPv6. L'en-tête TCP fixe est de 20 octets. Si la MTU est de 1500 octets (celle d'Ethernet), cela donnera une MSS de 1460 octets en IPv4 et 1440 en IPv6. Comme indiqué plus haut, si on rajoute des options IP (augmentant ainsi la taille de l'en-tête), on ne pourra pas envoyer 1460 (ou 1440) octets en TCP, il faudra se serrer (diminuer le nombre d'octets envoyés). C'est le comportement actuel de toutes les mises en œuvre de TCP, désormais officiellement documenté.
La règle est simple et bien exprimée. Le reste du RFC est consacrée à la justifier.
Pour résumer (section 4), il y a quatre choix possibles lorsque des options variables sont ajoutées à un paquet (comme l'option d'authentification du RFC 2385) :
Comme celui qui envoie des données ne sait pas si son pair a tenu compte des options ou pas, dans la MSS qu'il a indiquée, la seule solution sûre est donc, si on utilise les options, de décroître la quantité de données envoyées. (Rappelez-vous que seul l'envoyeur des données connait avec certitude les options utilisées. Le récepteur, qui avait indiqué dans l'option MSS la taille qu'il acceptait, ne sait pas s'il y aura des options variables.) Mais, si tout le monde fait cela, ajuster la MSS pour les options ne sert plus à rien. D'où la décision de notre RFC de ne pas tenir compte des options variables dans le calcul de la MSS.
La section 5 décrit d'ailleurs d'autres raisons derrière cette décision comme le fait qu'avec la nouvelle règle, la MSS peut être diminuée par la PMTUD. Par contre, elle ne peut pas être augmentée. Il vaut donc mieux ne pas la mettre trop bas, comme cela arriverait si on essayait de tenir compte des options variables. Elle traite aussi les cas de la compression ROHC (RFC 5795) et des « jumbogrammes » du RFC 2675.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : Z. Shelby (Sensinode)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF core
Première rédaction de cet article le 16 août 2012
Le contexte de ce nouveau RFC est celui des machines ayant peu de ressources, les environnements « contraints ». Les serveurs HTTP tournant sur ces machines ont besoin d'un moyen de faire connaître la liste des services qu'ils proposent. Ce RFC propose de le faire en distribuant en REST des fichiers d'un format spécifique (normalisé ici) listant ces services. Le format s'appuie sur les liens du RFC 8288.
Le groupe de travail IETF CoRE travaille pour ces pauvres machines contraintes, n'ayant parfois qu'un processeur 8-bits et peu de mémoire, connectées par des LowPAN (RFC 4919). Il se focalise sur les applications de machine à machine, où un programme parle à un autre (et pas à un humain, comme la plupart des serveurs Web).
Le problème spécifique traité par ce RFC est celui de la
découverte des services (typiquement représentés
par un URI) offerts par une
machine. Il n'y a pas d'humain dans la boucle, pour lire un mode
d'emploi ou une documentation. Et des interfaces statiques sont trop
rigides. L'idée de ce RFC est donc de mettre ces URI sous un format
standard, dans une ressource à l'URI bien connu,
/.well-known/core
(les URI
.well-known
sont normalisés dans le RFC 8615). La ressource en question (cela peut être
un fichier statique ou bien elle peut être construite à la demande)
est récupérée en HTTP (GET
/.well-known/core
) ou bien avec le
protocole COAP (RFC 7252). Et le format est une
concrétisation du concept de lien décrit dans le RFC 8288.
Ainsi, un client CoRE pourra récupérer la liste des variables mesurées par un capteur, par exemple. C'est évidemment très limité par rapport à un moteur de recherche, mais c'est implémentable dans des machines même très limitées.
Le RFC 8288 décrivait un concept abstrait de
lien, pour lequel il peut y avoir plusieurs
sérialisations (liens <a>
de
HTML, en-têtes HTTP,
liens Atom, etc). La sérialisation normalisée
ici est conçue pour être compacte et triviale à analyser
(rappelez-vous : machines contraintes), mais les mêmes données peuvent
également être servies par des protocoles et des formats plus
classiques, si on a aussi des clients plus puissants. Le format
compact de ce RFC est identifié par le type
application/link-format
.
Chaque URI indique un service hébergé (section 2 du RFC). On les écrit entre chevrons. On peut les voir comme un lien « héberge » entre le serveur et le service (« ce serveur héberge - hosts - ce service »).
Voici un exemple de liens suivant ce format, adapté de la section 5 du RFC. Le serveur permet de contrôler des capteurs de température et de lumière. Il y a donc deux services :
</sensors/temp>;if="sensor",</sensors/light>;if="sensor"
Désolé de ne pas pouvoir vous montrer d'exemple réel mais une
recherche Google
inurl:".well-known/core"
ne donne pas le résultat
attendu. Trop malin, Google décide d'ignorer ce qu'il prend pour de la ponctuation.
Les URI indiqués sont relatifs. Ils sont relatifs à un contexte qui est en général
l'endroit où on a obtenu la ressource
/.well-known/core
.
Ces liens, comme vous avez vu dans les exemples plus haut, peuvent contenir des attributs (section 3 du RFC). Les attributs spécifiques à ce format sont :
rt
(Resource type), qui identifie le service (c'est un
identificateur formel, pas un texte lisible pour les humains). Pour prendre
l'exemple d'un service de mesure de la
température, rt
peut
être une simple chaîne de caractères comme
outdoor-temperature
ou bien un URI pointant vers
une ontologie comme
http://sweet.jpl.nasa.gov/2.0/phys.owl#Temperature
.if
(Interface), qui
indique l'URI par lequel on va interagir avec le service. Plusieurs
services peuvent avoir la même interface (comme dans le premier
exemple donné plus haut avec le capteur de température et celui de lumière). La valeur de
if
peut être un URI pointant vers une description
en WADL.sz
(Size), qui indique
la taille maximale de la ressource qu'on va récupérer, une information
essentielle pour les machines contraintes ! Cette information peut
être omise si elle est inférieure à la MTU. Un
exemple serait </firmware/v2.1>;rt="firmware";sz=262144
.
Les attributs standards des liens peuvent aussi être utilisés, comme
title
(RFC 8288, section
5.4).
Voici pour la syntaxe du fichier (de la ressource) récupérée. Et
pour le récupérer, ce fichier (cette ressource) ? La section 4 revient
en détail sur le concept d'URI bien connu (normalisé dans le RFC 5785) et sur celui utilisé par CoRE,
/.well-known/core
. Un point intéressant est la
possibilité de filtrer les requêtes (section 4.1). La syntaxe est définie par un
gabarit RFC 6570 :
/.well-known/core{?search*}
. ce qui permet des
requêtes comme :
?href=/foo*
, pour se limiter aux liens
commençant par /foo
,?foo=bar
pour se limiter aux liens ayant un
attribut foo
dont la valeur est
bar
,?foo=*
pour ne garder que les liens ayant
un attribut foo
(valeur quelconque).
Le serveur étant une machine contrainte, il a parfaitement le droit de
ne pas mettre en œuvre les filtres (dans la libcoap, présentée
plus loin, il y a une option de compilation
--without-query-filter
pour supprimer les filtres
et réduire ainsi la taille du code). Le client doit donc être prêt à
récupérer plus que ce qu'il a demandé.
Si on prend cette ressource Core :
</sensors/temp>;rt="temperature-c";if="sensor",</sensors/light>;rt="light-lux";if="sensor"
Alors une requête HTTP GET
/.well-known/core?rt=light-lux
renverra (si le serveur gère
les filtres) uniquement :
</sensors/light>;rt="light-lux";if="sensor"
Des questions de sécurité à garder en tête ? Non, pas trop, dit la
section 6, qui rappelle qu'un serveur est autorisé à donner des
informations différentes selon le client, et rappelle aussi que ne
pas mettre un URI dans
/.well-known/core
n'apporte pas grand'chose,
question sécurité (un attaquant peut le deviner).
Enfin, en section 7, les nombreux enregistrements à l'IANA nécessaires :
core
dans le registre
des bien connus,hosts
(« héberge ») dans le registre des
types de liens,application/link-format
dans la liste des
types MIME,core
, et, pour les autres, selon la politique
« Spécification nécessaire ».
Les implémentations de ce RFC semblent surtout se trouver dans les
bibliothèques COAP comme libcoap, bien que COAP
soit un protocole, pas un format. Voir le fichier
net.c
de cette bibliothèque. Une liste se trouve
en
bas de l'article Wikipédia.
TinyOS semble avoir un client capable de
tester un /.well-known/core
, voir http://docs.tinyos.net/tinywiki/index.php/CoAP
. Par contre, je
n'ai pas trouvé de
validateur en ligne.
Date de publication du RFC : Juillet 2012
Auteur(s) du RFC : M. Kucherawy (Cloudmark)
Pour information
Réalisé dans le cadre du groupe de travail IETF spfbis
Première rédaction de cet article le 21 juillet 2012
L'IETF avait créé en 2004 un groupe de travail nommé MARID, qui avait pour tâche de normaliser un mécanisme d'authentification faible du courrier électronique par le biais de la publication dans le DNS des serveurs autorisés à envoyer du courrier pour un domaine. Deux propositions étaient sur la table, SPF et Sender ID. Microsoft avait pratiqué une intense obstruction contre SPF, pour promouvoir sa propre solution, Sender ID. En 2006, l'IETF avait cédé devant cette obstruction, en renonçant à normaliser SPF, déjà très répandu, et en publiant les deux protocoles avec le statut Expérimental : RFC 4408 pour SPF et RFC 4406 pour Sender ID. Cette solution peu courageuse avait été contestée, notamment pour le risque que la coexistence de deux protocoles incompatibles faisait peser sur la bonne délivrance du courrier. Officiellement, la retraite de l'IETF devait être provisoire : une période de deux ans d'observation était prévue, suite à laquelle des conclusions pourraient être tirées sur l'expérience. En fait, c'est seulement six ans après qu'est publié notre RFC 6686 qui conclut enfin officiellement que Sender ID est un échec total et que seul SPF est déployé et utilisé.
Le groupe de travail spfbis avait été constitué en février 2012 pour documenter les preuves du déploiement de SPF et pour réviser la spécification. Ce document est son premier RFC, et il n'a pas été facile à produire, tant les controverses étaient vives. D'une certaine façon, c'est la création de ce groupe qui avait marqué le choix définitif en faveur de SPF. Mais, en 2006, le consensus n'était pas évident, notamment face à l'opposition acharnée de Microsoft, qui tenait à pousser sa solution. Il était pourtant déjà clair à l'époque que SPF était largement déployé et que Sender ID n'était pas utilisé, même par les services appartenant à Microsoft comme Hotmail. Mais la politique politicienne l'avait emporté et l'IETF avait donc fait semblant de traiter les deux protocoles sur un pied d'égalité.
Avantage de ce délai : il a permis de récolter beaucoup plus d'informations pratiques. C'est l'une des forces de ce RFC 6686 que de présenter de nombreuses données issues de plusieurs campagnes de mesure.
Notez aussi que ce RFC ne fait pas de comparaison technique des deux protocoles. Il considère que le choix a déjà été fait par la communauté et il se contente donc d'observer ce qui tourne réellement dans la nature.
Avant les chiffres, qui constituent l'essentiel de ce document, un
petit rappel : le RFC 4408 introduisait un
nouveau type de données DNS, le type
SPF
(code 99). Historiquement, SPF utilisait le
type générique TXT
(code 16) et le nouveau type
SPF
avait été ajouté alors que le déploiement
était déjà largement commencé. Une question secondaire à laquelle
notre RFC répond est donc « pour ceux qui utilisent SPF, avec quel
type DNS ? ».
La section 3, le cœur de notre RFC, présente donc les
résultats de différentes mesures. D'abord, trois séries de mesures
actives (faites en interrogeant le DNS sur son contenu, comme peut le
faire un logiciel comme DNSdelve) ont mesuré le
pourcentage de domaines qui publiaient des enregistrements SPF
(commençant par v=spf1
) ou
Sender ID (commençant par spf2.0/
, oui, Microsoft
était allé jusqu'à détourner le terme « SPF » pour brouiller davantage
la discussion ; il était prévu de critiquer ce point dans le RFC mais
le texte a dû être retiré pour ne fâcher personne).
La première étude avait été faite par Cisco à partir du million de domaines les plus populaires sur le Web selon Alexa. 39,8 % ont un enregistrement TXT d'authentification du courrier électronique. Seuls 1,3 % de ces enregistrements sont pour Sender ID.
La deuxième étude a été faite par le Trusted Domain Project, en utilisant comme liste de domaines des extraits des journaux de leurs serveurs de messagerie. Elle trouve 56,4 % de TXT d'authentification du courrier (dont 4,6 % pour Sender ID). Cette étude a également observé que certains serveurs DNS cassés répondent pour une demande de type TXT mais pas pour une demande de type SPF (ce point est couvert plus en détail par la suite, dans l'annexe A).
La troisième étude a été faite par Hotmail, à partir des domaines qui leur envoient du courrier. 46,2 % de TXT avec authentification. Hotmail, filiale de Microsoft, n'a pas publié le pourcentage de Sender ID parmi eux.
En étudiant le contenu de la zone
.fr
(non mentionnée dans
le RFC, étude faite à l'AFNIC avec le logiciel
DNSdelve), on trouve
20 % de domaines ayant un enregistrement SPF. Et aucun avec Sender ID...
(la mesure a été faite en échantillonant la zone donc une poignée de
domaines ayant Sender ID a pu échapper à la mesure). 70 % de ces
domaines SPF sont dus à un seul hébergeur de courrier. À noter que
cette étude n'a pas fait de différence entre les enregistrements DNS
TXT
et SPF
.
Ces trois études portaient sur les enregistrements dans le DNS. Et pour les requêtes DNS, que voit-on ? Des mesures passives ont été faites (mais le RFC ne contient guère de détails), montrant très peu de requêtes de type SPF (99) et depuis un très petit nombre d'acteurs. À noter qu'on ne peut en général pas savoir, en envoyant ou en recevant du courrier, si le pair SMTP utilise SPF et/ou Sender ID.
Le serveur de noms de
.fr
d.nic.fr
voit, sur ses différentes instances
anycast, 0,7 % de requêtes
TXT
, et 0,1 % de requêtes SPF
(données analysées
par DNSmezzo). SPF
est quand même loin devant un type comme NAPTR
mais il est nettement dominé par TXT
(toutes les
requêtes TXT
ne sont pas forcément pour SPF). L'abandon du type DNS SPF a ensuite
été repris dans la nouvelle norme SPF, le RFC 7208.
Reste la question des programmes qui mettent en œuvre SPF
et/ou Sender ID (section 3.2). L'offre logicielle pour Sender ID est
recensée en http://www.microsoft.com/mscorp/safety/technologies/senderid/support.mspx
. Aucun
logiciel libre n'y est cité. Parmi les treize
opérateurs mentionnés, au moins un n'utilise plus Sender ID (la
dernière mise à jour date de 2007).
Celle de SPF est en http://www.openspf.net
. Six
bibliothèques sont citées, vingt-deux
MTA (à la fois en logiciel libre et en
privateur), ainsi que des
patches pour les autres.
Il y a quand même un moyen de tester la présence de Sender ID dans
un MTA, via l'extension SMTP SUBMITTER
(RFC 4405). Elle est utilisée pour optimiser
l'algorithme PRA du RFC 4407 en annonçant au
récepteur l'identité de l'expéditeur. Deux logiciels la mettent en
œuvre, Santronics WinServer et
McAfee MxLogic. Les journaux des fournisseurs
montrent qu'environ 11 % des sessions SMTP utilisent cette extension, mais
sans qu'on sache s'il s'agit d'un logiciel très répandu ou de
plusieurs logiciels moins populaires.
Le Trusted Domain Project a donc fait des mesures actives, se
connectant à de nombreux MTA pour leur demander les extensions qu'ils
géraient. 4,7 % annonçaient l'extension SUBMITTER
et presque tous étaient du MxLogic.
Restait une question délicate à étudier : le refus de l'IETF de
trancher entre les deux propositions SPF et Sender ID laissait ouverte
la possibilité que ces deux protocoles donnent des résultats
différents pour un même message. Par exemple que l'un l'accepte et
que l'autre le refuse. Cela serait certainement gênant, l'acceptation
ou le rejet d'un message dépendant du choix technique fait par le
récepteur. D'abord, deux études par Hotmail et par Trusted Domain
Project ont montré que, dans environ 50 % des cas, le PRA (l'identité
utilisée par Sender ID, cf. RFC 4407) et le
MAIL FROM
SMTP (l'identité utilisée par SPF) sont les
mêmes.
Ensuite, le Trusted Domain Project a analysé 150 000 messages reçus et abouti à la conclusion que, dans 95 % des cas, SPF et Sender ID auraient formé le même diagnostic (acceptation ou rejet). Une analyse analogue faite par Hotmail sur un échantillon plus large (des millions de messages) trouvait moins : 80 %.
Bon, en pratique, on a rarement vu de rapports comme quoi des ingénieurs système avaient été perturbés par les différences restantes.
La section 5 analyse tous ces résultats et synthétise :
SPF
(99) n'ont pas été
adoptés et des problèmes techniques à l'utilisation d'enregistrements
d'un type « nouveau » demeurent.TXT
publiés ne le sont que rarement pour
Sender ID.SUBMITTER
est rare.En conclusion, la section 6 estime que :
SPF
, ne sert à
rien.Le problème des types de données DNS, déjà
mentionné plusieurs fois ci-dessus, est traité en détail dans l'annexe
A. SPF avait été créé en dehors de l'IETF et ses concepteurs n'avaient
pas suivi la voie recommandée, qui consistait à utiliser un type
d'enregistrement DNS spécifique. Au lieu de cela, ils s'étaient servis
d'un type existant, et perçu comme généraliste, TXT
(code 16). Il faut
dire qu'à l'époque (le RFC ne le dit pas franchement), obtenir un
nouveau type d'enregistrement DNS à l'IANA
était très difficile.
Lorsque SPF est arrivé à l'IETF, il y avait déjà une forte base
installée, et donc une grande difficulté à migrer vers un nouveau type
d'enregistrement. Ce nouveau type, SPF
(code 99),
était accompagné lors de sa création d'un plan de migration, qui a été
un échec.
Plusieurs raisons à cet échec sont identifiées par notre RFC 6686 :
SPF
), en violation du RFC 3597,TXT
et ne
voyait pas de raison impérative de migrer (« faire plus propre » n'est
pas une raison impérative),Depuis, des choses ont changé. L'allocation de nouveaux types, très pénible, a été considérablement libéralisée par le RFC 6195, suivant les recommandations du RFC 5507. Mais le déploiement effectif des nouveaux types reste un problème difficile dans l'Internet d'aujourd'hui.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Morton (AT&T Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 16 août 2012
Tiens, le groupe de travail ippm n'avait pas encore normalisé toutes les métriques possibles ? Il restait encore des indicateurs de performance et de qualité de service qui n'avaient pas de RFC. En voici une nouvelle, le taux de pertes de paquets sur un trajet aller-retour.
La plupart des applications ont besoin d'envoyer et de recevoir des
paquets. Un exemple typique est la connexion
TCP, qui requiert que le paquet
SYN
du demandeur soit transmis dans un sens et le
SYN+ACK
du demandé dans l'autre sens. Sans liaison
bidirectionnelle, pas de TCP. Le taux de pertes sur le trajet aller-retour est donc
certainement utile. Il est même déjà mis en œuvre dans le
protocole TWAMP (Two-way Active Measurement Protocol, RFC 5357) mais sans que la métrique correspondante n'ait été
définie proprement, selon les règles du RFC 2330. Notre RFC 6673 comble ce manque (le RFC 7680 définissait la métrique pour le taux de
pertes en aller-simple). Attention toutefois en interprétant le
résultat : si le taux de pertes aller-retour est plus significatif
pour l'utilisateur (plus proche de son problème), il est moins adapté
pour le diagnostic car il ne dit pas dans quel sens a eu lieu la perte.
Donc, maintenant, les détails. Suivant le principe du RFC 2330, la métrique est définie pour un certain
type de paquets (on n'aura pas forcément le même taux de pertes en
UDP et en TCP, par
exemple, surtout si l'opérateur viole la neutralité du réseau), le
« Type-P ». La section 3.2 donne la liste complète
des paramètres de la mesure. À noter le Tmax
qui
indique le temps maximum pendant lequel on attend la réponse (un
paquet peut donc être marqué comme perdu alors qu'il est simplement
très en retard). À noter également que la métrique est définie en
termes booléens : 0, le paquet arrive, 1, il n'arrive pas.
Première définition (section 4),
Type-P-Round-trip-Loss
. La source envoie un
paquet, la destination répond et la source reçoit la réponse. Si cette
réponse arrive avant Tmax
, le résultat est 0
(succès) sinon 1 (échec). Naturellement, les problèmes habituels de
mesure se posent ici, dont les RFC 7680 et RFC 2681 ont déjà discuté. À noter que la destination doit répondre
« le plus vite possible » (une des grosses faiblesses de cette
métrique, qui ne dépend pas que du réseau mais également du
« réflecteur »). La section 4.4 discute plus en détail ce problème et
suggère que la destination réponde en moins d'une seconde, ce qui ne
devrait pas être trop difficile (cela suppose que
Tmax
soit très supérieur à une seconde). Notez aussi que, en l'absence de réponse, on ne peut pas
savoir si le paquet a été perdu entre source et destination, ou bien
entre destination et source (ou, pourquoi pas, si la destination était
défaillante et n'a pas renvoyé le paquet).
Ça, c'était pour un seul paquet. Pour un ensemble de paquets, la
section 5 définit
Type-P-Round-trip-Loss-<Sample>-Stream
. <Sample>
doit être remplacé par le type de la
distribution des paquets (RFC 3432). Deux exemples
typiques : une distribution de Poisson ou une
distribution périodique (où les paquets sont simplement envoyés à
intervalles réguliers, comme le fait la commande
ping, dont l'option -i
permet de choisir cet intervalle). Cette grandeur sera un tableau de
valeurs logiques, 0 pour le succès et 1 pour l'échec.
On pourra ensuite dériver de ce tableau des statistiques comme
Type-P-Round-trip-Loss-<Sample>-Ratio
(section 6), qui
est la moyenne du tableau (« X % des paquets
ont été perdus »). Notez que, sur des vrais réseaux de bonne qualité
(qui perdent peu de paquets),
il faudra envoyer des dizaines de milliers de paquets pour mesurer le
taux de pertes de manière significative.
Comment mesure-t-on en pratique ces grandeurs ? La section 8 donne quelques indications. Par exemple, il aura fallu configurer les deux machines pour envoyer et recevoir (pour la source) et réfléchir (pour la destination) les paquets du Type-P choisi (qui peut être ICMP, auquel toutes les machines TCP/IP doivent répondre, mais pas forcément). Le protocole TWAMP du RFC 5357 peut être utilisé pour cela. La machine de destination ne doit pas, autant que possible, être elle-même une cause de perte de paquets et doit donc avoir notamment des tampons suffisamment larges.
Il faut aussi se préoccuper de sécurité (section 9) : comme il
s'agit de mesures actives, il faut faire attention à ne pas écrouler
le réseau sous la charge (option -f
de ping...)
Et, lorsqu'on mesure sur un vrai réseau, il faut se rappeler que des
décisions de l'opérateur (par exemple de prioritiser certains flux)
peuvent fausser la mesure (c'est une des raisons pour lesquelles il
est essentiel de publier le Type-P utilisé par
exemple « Ces tests ont été faits avec des paquets
TCP SYN
, port de
destination 80 »).
Et les implémentations ? Le célèbre logiciel ping mesure et affiche un taux de pertes aller-retour, sans toutefois suivre rigoureusement la définition de notre RFC. Voici un exemple (la Freebox étant tombée en panne pendant la mesure, ce qui explique le taux élevé de 34 % de pertes) :
% ping -i 0.2 ns2.nic.fr ... --- ns2.nic.fr ping statistics --- 9085 packets transmitted, 5981 received, +128 errors, 34% packet loss, time 1843752ms rtt min/avg/max/mdev = 25.068/27.514/156.796/3.477 ms, pipe 3
ping est toutefois très limité : il n'utilise qu'un seul protocole, ICMP, qui peut être filtré ou limité en débit. Autrement, toutes les implémentations de TWAMP mesurent le taux de pertes aller-retour d'une manière compatible avec ce RFC. Même chose pour Cisco IP-SLA. L'auteur du RFC note que son employeur, AT&T, a mille points de mesure TWAMP, mille points IP-SLA et mesure ce taux de pertes cent mille fois par jour (chaque point mesure toutes les quinze minutes).
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : S. Rose (NIST), W. Wijngaards (NLnet Labs)
Chemin des normes
Première rédaction de cet article le 18 juin 2012
Depuis sa normalisation dans le RFC 1034, le DNS a suscité le développement d'innombrables extensions, plus ou moins réalistes, plus ou moins utilisées. L'enregistrement DNAME, sujet de ce RFC, semble encore très peu utilisé : il permet de donner un synonyme à une zone entière, pas à un seul nom, comme le fait l'enregistrement CNAME. DNAME avait à l'origine été normalisé dans le RFC 2672, que notre RFC met à jour.
Les enregistrements DNAME permettent d'écrire des équivalences comme :
vivendi-environnement.fr. DNAME veolia.fr.
et un nom comme www.vivendi-environnement.fr
sera
transformé en www.veolia.fr
. Le but étant ici de
changer le nom de l'entreprise en Veolia sans
avoir à s'inquiéter de toutes les occcurrences de l'ancien nom qui
trainent dans des signets privés,
dans la presse écrite, sur del.icio.us,
etc. DNAME a aussi été envisagé (mais peu utilisé) pour les
délégations des sous-arbres de traduction d'adresses IP en noms
(in-addr.arpa
et ip6.arpa
),
afin de permettre une rénumérotation d'un réseau relativement
légère (section 6.3, qui fournit un exemple et note honnêtement que
cela ne résout qu'une petite partie du problème de la renumérotation). Il a aussi été prévu de l'utiliser pour les variantes de
domaines IDN (par exemple pour faire une
équivalence entre le domaine en chinois
traditionnel et le domaine en chinois
simplifié). Enfin, il est utilisé dans l'ONS fédéré.
En fait, les enregistrements DNAME ne sont pas aussi simples que
cela. Le DNAME ne s'applique pas réellement à la zone mais à tous les
sous-domaines de l'apex. Il faut donc dupliquer
tous les enregistrements de l'apex (typiquement, les MX et les NS). Le
vrai fichier de zone pour
videndi-environnement.fr
ressemblerait plutôt à :
@ IN SOA ... Dupliquer le SOA de veolia.fr IN NS ... Idem pour NS et MX IN MX ... IN DNAME veolia.fr. ; Et ça suffit, les noms comme www.vivendi-environnement.fr seront ; gérés par le DNAME.
DNAME est donc complémentaire du CNAME : celui-ci « aliase » un nom, le DNAME aliase un sous-arbre. Si on veut aliaser les deux, il faut faire comme dans le fichier de zone ci-dessus. Sinon, il faudrait DNAME et CNAME (mais on ne peut pas se servir des deux en même temps) ou bien créer un nouveau type de données (un BNAME, qui aurait les propriétés des deux, a été discuté à l'IETF).
Le tableau 1 du RFC donne des exemples de cas simples et de cas
plus tordus. Il prend trois entrées, le nom demandé (QNAME pour
Query Name), le nom du DNAME (owner
name) et la cible de ce dernier. Par exemple, avec le DNAME
ci-dessus (owner name
videndi-environnement.fr
, cible
veolia.fr
), un QNAME de
videndi-environnement.fr
ne donnera rien (le
DNAME ne concerne que les domaines en dessous de l'apex), un QNAME de
www.videndi-environnement.fr
donnera
www.veolia.fr
, un QNAME de
www.research.videndi-environnement.fr
donnera
www.research.veolia.fr
. Attention, les chaînes
(un DNAME pointant vers un DNAME) sont légales. Du point de vue
sécurité, une chaîne est aussi forte que son maillon le plus faible et
notre RFC, comme le RFC 6604 spécifie que
DNSSEC ne doit valider une chaîne que si tous
les alias sont valides (section 5.3.3).
Pour que la redirection vers la cible soit déterministe, le RFC impose (section 2.4) qu'un seul DNAME, au maximum, existe pour un nom. BIND refuserait de charger une telle zone et nous dirait (version 9.9.1) :
23-May-2012 22:39:35.847 dns_master_load: foobar.example:20: sub.foobar.example: multiple RRs of singleton type 23-May-2012 22:39:35.847 zone foobar.example/IN: loading from master file foobar.example failed: multiple RRs of singleton type 23-May-2012 22:39:35.847 zone foobar.example/IN: not loaded due to errors.
Si on préfère tester avec l'excellent validateur de zones validns, il faut se
rappeler que ce test est considéré comme de politique locale et n'est
pas activé par défaut. Il faut donc penser à l'option
-p
:
% validns -z foobar.example -p all ./foobar.example ./foobar.example:19: multiple DNAMEs
Notre RFC prévoit le cas où le client DNS pourrait ignorer les DNAME. Le serveur synthétise des enregistrements CNAME équivalents (section 3.1) et les met dans la réponse. Le TTL de ses enregistrements doit être celui du DNAME (c'est un des gros changements par rapport au RFC 2672, où le TTL du CNAME généré était de zéro).
Notez qu'un DNAME peut être créé par mise à jour dynamique du contenu de la zone (section 5.2, une nouveauté par rapport au RFC 2672), masquant ainsi tous les noms qui pouvaient exister avant, sous son nom. Avec un serveur BIND 9.9.1, avant la mise à jour, on voit un nom ayant une adresse :
% dig @127.0.0.1 -p 9053 AAAA www.sub.foobar.example ... ;; ANSWER SECTION: www.sub.foobar.example. 600 IN AAAA 2001:db8::2
et, après une mise à jour dynamique où ce programme ajoute un DNAME
pour sub.foobar.example
et pointant vers example.org
, on obtient :
% dig @127.0.0.1 -p 9053 AAAA www.sub.foobar.example ... ;; ANSWER SECTION: sub.foobar.example. 300 IN DNAME example.org. www.sub.foobar.example. 300 IN CNAME www.example.org.
(Si le serveur était récursif, on obtiendrait également l'adresse
IPv6 de www.example.org
.)
Les DNAME sont mis en œuvre dans BIND
et nsd mais semblent
peu déployés. Si vous voulez regarder ce que
cela donne, testez testonly.sources.org
qui est
un DNAME de example.org
donc, par exemple,
www.testonly.sources.org
existe :
% dig AAAA www.testonly.sources.org ... ;; ANSWER SECTION: testonly.sources.org. 86400 IN DNAME example.org. www.testonly.sources.org. 0 IN CNAME www.example.org. www.example.org. 171590 IN AAAA 2001:500:88:200::10
(Notez que le serveur utilisé n'a pas suivi la nouvelle règle de notre RFC 6672 et a mis un TTL de zéro.)
Selon moi, une des raisons pour le peu de déploiement de DNAME est que le problème peut se résoudre tout aussi simplement, sans changement dans le DNS, par l'utilisation d'une préprocesseur ou bien en créant un lien symbolique entre les deux fichiers de zone (si le fichier ne contient que des noms relatifs, ça marche très bien, que ce soit avec BIND ou avec nsd).
Les changements par rapport au RFC 2672 sont limités. C'est le même type d'enregistrement (numéro 39) et le même format sur le réseau. Parmi les principaux changements, le TTL du CNAME synthétisé (déjà décrit plus haut) et la disparition complète de l'utilisation d'EDNS pour signaler qu'un client connait les DNAME (cette option était normalisée dans le RFC 2672, section 4.1). L'annexe A donne la liste complète des changements.
Date de publication du RFC : Août 2012
Auteur(s) du RFC : N. Hilliard (INEX), D. Freedman (Claranet)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 21 août 2012
Une technique couramment utilisée en cas d'attaque par déni de service est le RTBH :
Remote Triggered Black Hole où la victime demande
à son FAI, via un
protocole, de jeter des
paquets sur tel ou tel critère. On utilise pour
cela les protocoles de routage standards comme
BGP ou OSPF. Même chose
lorsqu'un opérateur réseaux veut propager en interne, entre ses
routeurs, la décision de jeter ou de rediriger tel ou tel type de
paquets. Pour cela, il est bien pratique de disposer d'un préfixe IP
spécial, qui désigne le trou noir (ou l'IDS, si
on redirige le trafic vers un équipement d'analyse spécial). Il
n'existait pas de tel préfixe pour IPv6, c'est
désormais fait avec ce RFC, qui enregistre
0100::/64
.
Les RFC 5635 et RFC 3882 décrivent plus en détail cette idée de RTBH dans le
cas d'une DoS. On
sélectionne les paquets en fonction de leur adresse IP source ou
destination et on les jette (trou noir) ou bien on les envoie (par
exemple via un tunnel) vers un dispositif
d'analyse. Pour configurer cela, il faut des adresses IP (plusieurs,
car on peut avoir plusieurs traitements différents selon les attaques,
donc une seule adresse IP ne suffit pas). Certains
utilisent des adresses privées ou bien les adresses IP réservées pour
la documentation (RFC 3849). Ce n'est pas très
satisfaisant (et cela peut interférer avec les politiques de filtrage
en interne, cf. section 2 du RFC) d'où le nouveau préfixe. Si on voit
0100::/64
dans la configuration d'un routeur, on
sait désormais exactement ce que cela implique.
Ce préfixe peut être propagé, à l'intérieur du réseau de l'opérateur, ou bien entre l'opérateur et ses clients, par les protocoles de routage dynamiques habituels comme OSPF. Il ne doit pas être transmis à l'extérieur et il est recommandé de le filtrer en entrée, sur les liens de peering ou de transit. Comme il sert pour gérer des attaques qui peuvent être de taille impressionnante, une fuite de ce préfixe vers un autre opérateur pourrait potentiellement entraîner un reroutage de l'attaque vers cet autre opérateur (sections 3 et 5 du RFC). Prudence, donc !
Ce préfixe 0100::/64
est désormais dans le
registre
des adresses IPv6 spéciales.
Date de publication du RFC : Juillet 2012
Auteur(s) du RFC : A. Melnikov (Isode), J. Reschke (greenbytes)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 10 juillet 2012
Lorsqu'un programme envoie des données en les étiquetant avec le
type MIME
text/quelquechose
, quels sont le jeu de caractères et l'encodage
utilisés par défaut ? ASCII ?
UTF-8 ? Un autre ? Si vous l'ignorez, vous
n'êtes pas le seul. Très peu de gens connaissaient les règles
appliquées par défaut et ce
RFC choisit donc de les simplifier en les supprimant. Pour le
résumer : il n'y aura plus de
charset par défaut pour les
nouveaux types MIME text/*
.
Le RFC 2046, qui normalisait ces étiquettes
MIME, disait pourtant (section 4.1.2) que le
charset par défaut était
US-ASCII (un point de vocabulaire au passage :
le terme de charset est fréquent dans les normes
IETF mais étymologiquement incorrect, puisqu'il
désigne en fait à la fois un jeu de caractères
et un encodage). Mais d'autres RFC avaient fait
d'autre choix et l'exemple le plus connu était
HTTP qui spécifiait que, lorsqu'un serveur envoie
des données sans indiquer charset
, c'est qu'elles
sont en ISO 8859-1 (RFC 2616, section 3.7.1, le RFC 7231 a depuis changé cela), comme les en-têtes de la réponse
HTTP. En pratique, le serveur HTTP prudent indiquera le
charset (par exemple Content-Type: text/html; charset=UTF-8
) plutôt que de compter sur cette règle mal connue.
Pire, certains types ont un mécanisme inclus dans les données pour
trouver le charset, notamment
text/html
et text/xml
. Bref,
il est difficile à un programme de compter sur la valeur par
défaut. Ce RFC formalise en fait un usage déjà très répandu : être explicite.
La nouvelle règle est donc « pas de valeur par défaut générique
pour tous les text/*
, chaque sous-type de
text/*
peut définir sa propre valeur par défaut,
y compris imposer qu'une valeur explicite soit indiquée. » Pour des
raisons de compatibilité avec l'existant, les sous-types existants ne
sont pas modifiés, la nouvelle règle s'appliquera aux nouveaux
sous-types. Notre RFC recommande en outre de choisir de ne
pas avoir de valeur par défaut et, soit
d'indiquer le charset dans le contenu (comme le
fait XML avec son <?xml
version="1.0" encoding="iso-8859-1"?>
), soit de rendre
obligatoire le paramètre charset=
(indication
explicite du charset).
Les nouveaux enregistrements
de sous-types MIME de text/*
ne devraient donc
plus indiquer de valeur par défaut pour le
charset. Si c'est absolument nécessaire, le RFC
recommande que cette valeur soit UTF-8 (on est
en 2012 et ASCII ne devrait plus être considéré
comme le jeu de caractères par défaut).
On l'a dit, ce RFC ne change pas les sous-types existants et, par
exemple, le charset par défaut du sous-type
text/plain
reste donc, lui, en ASCII.
Une alternative à l'étiquetage des données a toujours été d'essayer
de deviner le charset par diverses heuristiques. Le
RFC rappelle que cette méthode est dangereuse et déconseillée. Autre
piège, le conflit entre l'information extérieure au contenu et celle
incluse dans le contenu. Que faut-il faire avec un document XML servi
en HTTP
comme text/html; charset=iso-8859-1
et commençant par <?xml
version="1.0" encoding="utf-8"?>
? Le RFC recommande de
se fier à l'information la plus interne (ici, la déclaration XML, qui
dit que le document est en UTF-8), probablement la plus correcte.
Ce RFC 6657 est désormais celui cité à l'IANA
pour les nouveaux enregistrements dans le registre
des sous-types de text/
.
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : S. Kitterman (Agari)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 26 juin 2012
Le but principal de ce RFC est d'améliorer l'utilisation du format ARF (RFC 5965) pour rendre compte d'un problème d'authentification SPF. Ce protocole d'authentification du courrier électronique, normalisé dans le RFC 7208, n'avait pas de registre des modificateurs disponibles dans un enregistrement SPF. Ce RFC comble ce manque.
ARF est un format standard, structuré, permettant l'envoi de rapports d'incidents ou de problèmes (par exemple un spam) entre opérateurs. L'idée d'un format normalisé est de faciliter la production et la lecture automatique de ces rapports. Des extensions à ARF (RFC 6591 et RFC 6650) permettent de l'utiliser pour signaler des erreurs d'authentification.
SPF est un mécanisme d'authentification du courrier électronique qui fonctionne en listant les serveurs de courrier autorisés à émettre du courrier pour un domaine donné. Une fois l'émetteur connu, un récepteur peut alors appliquer ses politiques de sélection (accepter tous les messages en provenance de tel domaine, par exemple).
Les erreurs SPF peuvent être détectées par un récepteur de courrier, s'il fait des tests SPF, ou bien par un serveur de noms d'un domaine couvert par SPF : si on publie un enregistrement SPF spécialement fait pour cela (en utilisant les macros SPF qui permettent de récupérer plein d'informations sur la session SMTP en cours), le serveur DNS du domaine va voir passer les requêtes de vérification et pourra, par exemple, détecter une tentative d'usurpation pendant qu'elle se déroule.
Mais à qui signaler le problème ? Avant notre RFC 6652, il n'y avait pas d'autre moyen, en cas de problème SPF pour
example.net
, que d'écrire à
postmaster@example.net
. Désormais, la section 3
de notre RFC normalise des nouveaux modificateurs SPF, qu'on peut
inclure dans ses enregistrements, et qui permettent d'indiquer des
adresses de contact et les conditions sous lesquelles envoyer un
beau rapport ARF conforme au RFC 6591 :
ra=
(Reporting Address)
est le nom à utiliser à la place de
postmaster
. Si l'enregistrement SPF de
example.net
contient
ra=jimmy
, on enverra l'éventuel rapport à
jimmy@example.net
(il n'existe aucun mécanisme
pour spécifier un autre nom de domaine comme
victim@somewhere.example
, afin d'éviter que le
gérant de example.net
puisse faire spammer
d'autres domaines).rp=
(Requested report
Percentage) est la proportion de problèmes SPF qui peut
déclencher l'envoi d'un rapport. Si l'enregistrement SPF de
example.net
contient rp=0
,
il ne veut jamais être embêté par des rapports. Si l'enregistrement
contient rp=100
, il veut un rapport à chaque
fois. Et s'il contient rp=25
, il veut qu'un
problème sur quatre, choisi au hasard, fasse l'objet d'un
rapport. Cela permet de limiter le trafic répétitif. Notez qu'un champ
du rapport ARF, Incidents:
(section 3.2 du RFC 5965), permet d'indiquer que
d'autres incidents sont connus mais ne font pas l'objet d'un
rapport. Comme le note la section 6.2, à propos de la sécurité, le
volume de rapports envoyés peut être conséquent (et pas connu à l'avance).rr=
(Requested Reports)
permet d'indiquer par quelle sorte de rapport on est intéressés
(all
= tous, f
= erreurs
fatales, etc, voir section 4.1).
Ces modificateurs SPF sont enregistrés dans le tout nouveau registre IANA, créé par ce RFC 6652 (section 5). Il inclut les modificateurs de la liste ci-dessus
ainsi que exp=
et redirect=
qui avaient déjà été normalisés par le RFC 4408. Désormais, ce registre est ouvert à de futures
additions, selon les règles « Norme nécessaire » du RFC 5226.
Tirés de l'annexe B, voici des exemples d'enregistrements SPF du
domaine example.org
utilisant les nouveautés de notre RFC. D'abord un cas simple, avec
juste une
demande que les rapports soient envoyés à postmaster
:
v=spf1 ra=postmaster -all
Un cas un peu plus compliqué, toujours avec un seul modificateur :
v=spf1 mx:example.org ra=postmaster -all
Et un cas qui utilise tous les modificateurs de ce RFC. On demande que
10 % des rapports d'erreur (pas d'échec d'authentification, non, des
erreurs lorsque l'enregistrement SPF ne peut être analysé, cf. RFC 7208, sections 2.6.6 et 2.6.7) soient envoyés à
postmaster
:
v=spf1 mx:example.org -all ra=postmaster rp=10 rr=e
Il reste à voir quel sera le déploiement de ce système. Apparemment, plusieurs fournisseurs de logiciels y travaillent.
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : J. Falk (Return Path), 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 26 juin 2012
Le format ARF, normalisé dans le RFC 5965 permet à des acteurs de l'Internet (typiquemet des FAI et des gros hébergeurs de courrier comme Gmail) de s'envoyer des rapports structurés, produits et analysés automatiquement, au sujet des abus commis avec le courrier électronique, notamment du spam. Ce nouveau RFC du groupe de travail qui a conçu ARF expose comment et dans quelles circonstances utiliser ARF.
L'idée de base d'ARF était qu'un message serait détecté comme abusif (par exemple par l'utilisateur cliquant un bouton « C'est du spam ! ») et que cette détection déclencherait l'envoi d'un rapport ARF au responsable (qui pourra le faire suivre, si nécessaire). En comparaison avec un rapport non structuré, l'avantage d'ARF est que les messages ARF seront analysables par des programmes, pour rendre leur traitement plus efficace.
(Il existe des extensions à ARF pour des usages qui ne sont pas forcément des abus ou des erreurs d'authentification, comme l'extension du RFC 6430 mais elles sont encore peu déployées et pas étudiées ici.)
Ce RFC 6650 est largement inspiré d'un document externe à l'IETF, le RFC 6449. En quelque sorte, il en est la version officielle.
Les autres documents existants, comme la norme ARF (RFC 5965), sont purement techniques (définition d'un format) et ne répondent pas à des questions comme « à qui envoyer les rapports ? » ou « que faut-il mieux mettre dans un rapport ? », qui font l'objet de ce RFC.
D'abord, faut-il un accord explicite du destinataire avant d'envoyer les rapports ARF ? La section 3 considère qu'il y a deux cas, celui de deux acteurs décidant entre eux de se transmettre des rapports ARF, relatifs à leurs clients. C'est le cas le plus fréquent aujourd'hui. Et le second cas est celui où des rapports non sollicités sont envoyés à quelqu'un dont l'expéditeur pense qu'il est concerné. En l'absence d'un accord préalable, ces rapports ne feront pas forcément l'objet de la même attention.
La section 4 détaille le premier cas, les rapports attendus. En vrac, elle demande, entre autres :
arf-feedback@example.net
, par exemple).Original-Mail-From
,
Arrival-Date
, Source-IP
,
Original-Rcpt-To
.La section 5 s'attaque aux rapports inattendus, envoyés sans concertation préalable. Elle est bien plus longue puisqu'il s'agit d'embêter des gens qui n'ont rien demandé (dans le précédent cas, les deux parties ont pu se mettre d'accord sur tous ces points, qui doivent être explicités ici.) Les auteurs du RFC demandent, entre autres :
Feedback-TYpe:
(RFC 5965,
section 3.1), indication de toutes les informations pertinentes,
etc. Par contre, pas besoin d'hésiter avant de choisir le format ARF : les
rapports qui suivent ce format sont lisibles manuellement, même si le
destinataire n'a pas de logiciel adapté.Source-IP:
du rapport et jeter
sans autre forme de procès les rapports où ladite adresse IP source ne
fait pas partie de ses préfixes IP. Malgré cela, il y a quand même des
rapports corrects ce qui ne signifie
pas qu'ils seront lus. Le RFC discute également de la délicate
question de la réponse : faut-il signaler à l'envoyeur du rapport que
son message a été lu et qu'on a agi ? (Actuellement, même si les
rapports d'abus sont traités, l'utilisateur ne reçoit jamais de
retour.) La conclusion est que ce serait souvent une bonne idée que de
signaler à l'émetteur du rapport qu'il n'a pas travaillé pour rien.Les recommandations précédentes concernaient surtout les rapports
envoyés en réponse à un message abusif, du spam par exemple. La
section 6 couvre les rapports signalant un problème
d'authentification, avec SPF ou
DKIM. Ces rapports utiliseront le
Feedback-Type: auth-failure
(RFC 6591) et sont normalisés dans des documents comme le RFC 6652 et le RFC 6651. Les demandes pour cette section sont :
MAIL FROM
vide (plus exactement ayant la valeur <>
),Quelques pièges de sécurité peuvent attendre les utilisateurs du format ARF. La section 8 en fait le tour. D'abord et avant tout, les rapports ARF peuvent être des faux, fabriqués de A à Z (afin, par exemple, de faire accuser un innocent). La confiance qu'on leur accorde doit dépendre de l'authentification de l'émetteur et de la confiance qu'on accorde à cet émetteur. (C'est un problème ancien, voir par exemple la section 4.1 du RFC 3464.)
Le modèle originalement envisagé pour ARF était celui du rapport déclenché manuellement ; un utilisateur se plaint, il clique sur le bouton « Ceci est un spam », le message est transmis au fournisseur de messagerie qui fabrique un rapport ARF et l'envoie. Le rythme d'envoi des rapports restait donc limité. Au contraire, les évolutions récentes d'ARF, notamment pour le signalement de problèmes d'authentification, vont vers des rapports déclenchés automatiquement. Un message arrive, le test SPF échoue, paf, un rapport ARF est généré et envoyé. Cela peut mener à des rythmes d'envoi bien plus grands, qui peuvent dépasser les capacités de réception et de traitement du destinataire. C'est d'autant plus ennuyeux qu'un attaquant vicieux pourrait générer exprès des problèmes d'authentification, pour déclencher ces envois massifs. Il peut donc être raisonnable de limiter le débit d'envoi de tels rapports.
Autre façon de traiter ce problème : ne pas envoyer un rapport par
incident. Le format ARF prévoit (RFC 5965,
section 3.2) d'indiquer dans le rapport combien d'incidents similaires
il couvre (champ Incidents:
). On peut donc
choisir, par exemple, de n'envoyer qu'un rapport pour N incidents ou,
mieux de faire une décroissance exponentielle (un rapport par incident
pour les 10 premiers, un rapport par série de 10 incidents pour les
100 suivants, etc).
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : P. Saint-Andre (Cisco), D. Crocker (Brandenburg InternetWorking), M. Nottingham (Rackspace)
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 25 juin 2012
Ce RFC met officiellement fin à une amusante
tradition, qui était un des charmes des protocoles
TCP/IP mais qui, en pratique, a causé quelques
ennuis, justifiant son abandon. Cette tradition concernait le nommage
des paramètres
dans les protocoles. Normalement, ces noms étaient
enregistrés à l'IANA pour éviter des collisions
(par exemple, il ne doit y avoir qu'un seul champ nommé
User-Agent:
dans une requête
HTTP). Comme cet enregistrement nécessitait une
procédure, parfois lente et lourde, cela contrariait les gens qui
voulaient expérimenter avec une nouvelle idée, qui impliquait un
nouveau paramètre. L'habitude, avec l'appui de quelques RFC, s'était donc
répandue de donner à ces paramètres expérimentaux, non officiels, un nom
commençant par la lettre X suivie d'un tiret. Cette pratique a
rencontré plusieurs problèmes et est donc désormais fortement
déconseillée.
Le prefixe « X- » permettait de marquer clairement le nom de paramètre
comme expérimental. Sans lui, certains développeurs auraient peut-être
été tentés de s'auto-attribuer des noms, quitte à provoquer des
collisions avec d'autres développeurs. Mais le problème de l'Internet
est que les expériences durent : on invente un nouveau champ dans les
requêtes HTTP, mettons
X-recipe:
pour indiquer sa recette favorite, on
se dit que c'est juste un essai, qu'on ne va pas s'embêter à demander
un nom officiel pour si peu, on
l'utilise dans un patch de
Firefox, dans un module
Apache, des gens commencent à s'en servir, on
se dit qu'il serait bon d'enregistrer un vrai nom et on s'aperçoit que
la base installée d'utilisateurs est déjà trop grande pour abandonner
le nom expérimental. C'est essentiellement pour éviter ce genre de
blocage que l'IETF vient de décider de mettre
fin à cette convention du « X- ».
Il y a d'autres protocoles que HTTP (d'où sont extraits les exemples précédents) qui utilisent de tels paramètres. Par exemple le format standard du courrier électronique (RFC 5322) ou bien les vCard (RFC 6350). Tous à un moment ou à un autre ont vu passer des paramètres dont les noms commençaient par « X- », X comme eXpérimental ou comme eXtension (SIP faisait un peu différemment avec des en-têtes dont le nom commençait par « P- », cf. RFC 5727). Une méta-information sur le paramètre, son statut expérimental, se trouvait ainsi stockée dans le nom. L'idée semblait tellement bonne qu'elle a même été codifiée par plusieurs RFC comme le RFC 822 (qui différenciait les Extension fields et les User-defined fields, section 4.1) ou comme le RFC 5545 (section 3.1). Par la suite, ces codifications ont souvent été retirées (pour le courrier, le RFC 2822 a annulé les dispositions du RFC 822).
Donc, ce nouveau RFC :
Les programmeurs reçoivent (en section 2) la consigne de ne pas traiter un paramètre différemment juste sur la base de son nom. Qu'il commence par « X- » ou pas, le résultat doit être le même. (Faire autrement pourrait avoir des conséquences négatives sur la sécurité, par exemple si un programme considérait que les noms sans « X- » sont plus « sûrs » que les autres, comme expliqué en section 5.)
Quant aux créateurs de nouveaux paramètres (« Eh, je trouve qu'il
faudrait pouvoir indiquer la boisson favorite de l'utilisateur, y
a-t-il un en-tête Favorite-Drink:
? »), la section 3 leur dit que :
Pour limiter les risques de collision, si le paramètre n'est pas
enregistré, cette section recommande de le préfixer avec le nom de
l'organisation, à la Java, par exemple si
l'organisation se nomme Example International et a le domaine
example.com
, utiliser
Example-International-Favorite-Drink:
ou
Com-Example-Favorite-Drink:
pour l'en-tête
experimental.
Quant aux concepteurs des futurs protocoles, la section 4 leur dit :
Reléguée en annexe A, mais essentielle, se trouve l'analyse historique de la convention « X- ». Il semble qu'elle ait été mentionnée la première fois par Brian Harvey en 1975, pour les paramètres FTP du RFC 691 (« an initial letter X be used for really local idiosyncracies »). Les RFC 737, RFC 743, RFC 775, RFC 822 ont ensuite repris l'idée, à laquelle les RFC 1123 et RFC 1154 ont donné une forme de reconnaissance officielle, en notant toutefois déjà le problème que posent des paramètres qui sont expérimentaux au début et qui deviennent normalisés sans le « X- » plus tard. On ne peut pas citer les nombreux RFC qui ont ensuite mentionné l'idée, sans forcément l'encourager. Mais même LDAP s'y était mis (RFC 4512). Par contre, cette convention n'a jamais reçu de validation au niveau de tout l'IETF : ni le RFC 2026, ni le RFC 5226 n'en parlent. Cette convention est donc (théoriquement) restée cantonnée à certains protocoles.
Les problèmes que pose cette convention « X- » ont quand même été notés assez tôt et, dès le RFC 2822, le courrier électronique arrêtait officiellement de l'utiliser. Idem pour SIP avec le RFC 5727.
Si vous voulez tout savoir des inconvénients de la convention
« X- », la partie du RFC à lire est l'annexe B, qui énumère les
problèmes. Le principal est que les paramètres ainsi nommés,
normalement locaux et/ou temporaires, tendent à fuir vers l'extérieur
et que, s'ils sont des succès, ils deviennent rapidement des
« standards de fait » (et les programmes doivent le traiter comme tel). Il faut alors se décider entre une migration
depuis le nom en « X- » et le nom officiel sans « X- », ou bien une
officialisation du nom avec « X- ». Dans les deux cas, la convention
« X- » n'aura pas aidé. Elle ne servirait que si les paramètres ainsi
nommés étaient tous des échecs qui ne restaient pas longtemps. Mais ce
n'est pas le cas. Un exemple typique est donné par les en-têtes
HTTP x-gzip
et
x-compress
, qui sont devenus des standards
de fait, au point que le RFC 2068 (section 3.5) conseillait de les
accepter, comme synonymes aux en-têtes standard ! (Son successeur, le
RFC 2616, a gardé cette recommandation.)
Dans le contexte du courrier électronique, on voit un phénomène
équivalent avec le conseil du RFC 5064
d'accepter X-Archived-At:
comme équivalent à
Archived-At:
(section 2.5). Excellent exemple
d'une expérimentation qui a tellement bien réussi qu'elle devient
ensuite une gêne. Quant au conseil de considérer les deux noms comme
équivalents, il est dangereux : les deux noms ont été définis
séparement et peuvent avoir des propriétés subtilement différentes (le
nom officiellement enregistré a souvent des règles de sécurité plus
strictes sur son usage, par exemple).
Bien sûr, il y a des gens qui défendent la convention « X- ». D'abord, il peut y avoir des cas où elle est légitime :
priority
et qu'on est tenté de créer
x-priority
, il vaut mieux utiliser un synonyme
(comme urgency
) ou bien être créatif
(get-it-there-fast
).x
). Mais, là, il vaut
encore mieux utiliser des numéros.Les critiques de ce RFC mettaient en avant d'autres arguments, plus philosophiques :
Very-Long-Parameter-With-Useless-Information-Just-Because-I-Can:
pour être
sûr qu'on ne le confonde pas avec un autre. (Les étiquettes de langue
citées plus haut sont un contre-exemple, où l'espace de nommage n'est
pas énorme.)Si les gens utilisaient la convention « X- », au lieu d'enregistrer le nom de leur paramètre, ce n'est pas uniquement pour semer des chausse-trappes sous les pieds des futurs programmeurs. C'est aussi parce que l'enregistrement d'un nom a souvent été considéré (souvent à juste titre) comme excessivement compliquée et bureaucratique. Si on veut mettre effectivement fin à la convention « X- », la bonne méthode est donc aussi de libéraliser l'enregistrement, ce qu'avaient fait les RFC 3864 ou RFC 4288. Plusieurs participants à l'IETF avaient fait remarquer lors des discussions sur ce RFC que le vrai enjeu était de normaliser plus rapidement, pour éviter que les concepteurs de nouveaux paramètres ne soient tentés de s'allouer des noms de manière sauvage.
Ce RFC ne s'applique qu'aux protocoles utilisant des paramètres textuels. Lorsque le paramètre est, au contraire, identifié par sa position ou par un nombre, il n'est évidemment pas concerné.
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : M. Kucherawy (Cloudmark), D. Crocker (Brandenburg InternetWorking)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 18 juin 2012
La lutte contre le spam est un domaine où les certitudes (souvent assénées avec conviction) sont plus fortes que les faits. Prenez n'importe quel forum, en ligne ou ailleurs, où on discute des mesures qui pourraient limiter les conséquences du spam, vous y lirez et entendrez des affirmations radicales, par exemple sur l'efficacité du greylisting, sans que les affirmateurs ne se soucient d'appuyer leurs déclarations sur des mesures concrètes, faites dans la réalité. Comme le note notre RFC 6647, le greylisting est largement déployé, depuis de nombreuses années, marche bien et n'a pas d'inconvénient grave, mais il reste rejeté, sans raisons valables, par de nombreux « experts ». Ce RFC a mis du temps à sortir (il est courant à l'IETF que le texte de la norme vienne très longtemps après le déploiement) mais il changera peut-être cette perception.
Faites l'expérience vous-même : sur un MTA typique qui n'a pas encore le greylisting, activez-le, vous stopperez entre le tiers et les deux tiers du spam avant même que le premier octet de données n'ait été transmis. Si vous souhaitez, avant ou après, vous informer en détail, vous pouvez lire cet excellent RFC 6647, « Tout ce qu'il faut savoir sur le greylisting ». Il documente enfin officiellement une pratique courante depuis de nombreuses années.
Le principe du greylisting peut se résumer ainsi : on va refuser temporairement l'accès au serveur de messagerie à certains clients. Les clients normaux réessaieront, ce qu'une partie des spammeurs ne feront pas. On en sera ainsi débarrassé. La différence entre les mises en œuvre du greylisting se situe essentiellement dans les critères utilisés pour rejeter, puis pour accepter, un client SMTP.
L'idée est donc de considérer qu'un client « nouveau » est soumis au greylisting jusqu'à ce qu'il devienne « connu ». Une fois connu, on pourra le juger, par exemple sur les messages qu'il envoie. Ces mécanismes de réputation ne prenant pas en compte les nouveaux arrivants, le greylisting sert à les gérer en attendant. Sur la base de ce concept très général, le greylisting tel que déployé actuellement, consiste à renvoyer un code d'erreur SMTP, indiquant une erreur temporaire (code commençant par 4), à tout nouveau client SMTP. Les spammeurs utilisent souvent des logiciels spéciaux qui, pour de bonnes raisons, ne retentent pas de délivrer le message en cas d'erreur temporaire. Leur renoncement diminue la quantité de spam reçue. Les MTA ordinaires mettent le message dans une file d'attente, puis réessaient (c'est une fonction de base du courrier électronique, on essaie jusqu'à ce que ça passe) et verront donc leur message délivré car, au bout d'un moment, le greylisteur les considérera comme connus.
Il y a plusieurs types de greylisting et la section 2 en donne une liste. D'abord, ceux qui décident uniquement sur la base des informations de connexion (l'adresse IP et, peut-être, le nom obtenu par une requête de traduction d'adresse en nom). Le greylisting garde ensuite en mémoire les adresses des sources de courrier. Il refuse (code SMTP 421 ou équivalent) tant qu'une source n'a pas été vue depuis au moins N minutes (avec N variant typiquement entre 10 et 30).
En général, l'information est automatiquement retirée de la base lorsqu'on n'a pas vu cette source depuis X jours (typiquement entre 15 et 60). L'émetteur occasionnel devra donc montrer patte blanche à nouveau.
Naturellement, ce mécanisme peut être combiné avec une liste noire d'adresses IP (n'imposer le greylisting qu'à celles qui sont sur la liste noire) ou une liste blanche (dispenser du greylisting celles qui sont sur la liste blanche).
Avec le logiciel Postgrey, on peut avoir ce comportement (ne prendre en compte que l'adresse IP, pas le MAIL FROM
et le RCPT TO
), en utilisant l'option
--auto-whitelist-clients
(l'idée est que, si un
MTA réessaie plusieurs fois, il ne sert à rien de le tester pour
chaque adresse, il a montré qu'il était un « vrai » MTA.)
En laissant le client SMTP aller plus loin, et continuer la
session, on peut récolter des informations supplémentaires, qui
peuvent servir de paramètres au processus de décision du
greylisteur. C'est ainsi qu'on peut attendre le salut SMTP
(EHLO
ou bien le vieux HELO
)
et utiliser alors comme identificateur de la source SMTP le couple
{adresse IP, nom annoncé par EHLO
}. Cela permet,
par exemple, de différencier deux clients SMTP situés derrière le même
CGN et ayant donc la même adresse IP
publique. Autrement, toutes les machines derrière un routeur
NAT bénéficieraient du passage de la première machine.
En continuant, on peut aussi récolter l'adresse de courrier
émettrice (commande SMTP MAIL FROM
) et la ou les
adresses de courrier de destination (RCPT TO
). Un
greylisteur qui est allé jusque là peut donc utiliser le triplet {adresse
IP, expéditeur, destinataire}. C'est la politique la plus
courante. C'est par exemple ce que fait par défaut Postgrey,
déjà cité, qui journalise ces informations (voir l'exemple plus
loin) pour pouvoir
analyser ce qui s'est passé.
Voici d'ailleurs un exemple de session SMTP. Le client est nouveau et donc greylisté :
% telnet mail.bortzmeyer.org smtp Trying 2001:4b98:dc0:41:216:3eff:fece:1902... Connected to mail.bortzmeyer.org. Escape character is '^]'. 220 mail.bortzmeyer.org ESMTP Postfix EHLO toto.example.net 250-mail.bortzmeyer.org 250-PIPELINING 250-SIZE 10000000 250-VRFY 250-ETRN 250-STARTTLS 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN MAIL FROM:<foo@example.net> 250 2.1.0 Ok RCPT TO:<stephane+blog@bortzmeyer.org> 450 4.7.1 <stephane+blog@bortzmeyer.org>: Recipient address rejected: Greylisted by greyfix 0.3.9, try again in 300 seconds. See http://www.kim-minh.com/pub/greyfix/ for more information.
Cinq minutes après, le client réessaie et est accepté :
% telnet mail.bortzmeyer.org smtp Trying 2001:4b98:dc0:41:216:3eff:fece:1902... Connected to mail.bortzmeyer.org. Escape character is '^]'. 220 mail.bortzmeyer.org ESMTP Postfix EHLO toto.example.net 250-mail.bortzmeyer.org 250-PIPELINING 250-SIZE 10000000 250-VRFY 250-ETRN 250-STARTTLS 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN MAIL FROM:<foo@example.net> 250 2.1.0 Ok RCPT TO:<stephane+blog@bortzmeyer.org> 250 2.1.5 Ok DATA 354 End data with <CR><LF>.<CR><LF>
En pratique, la grande majorité des logiciels de greylisting ne va pas
plus loin. Après tout, le but est de rejeter du spam sans consommer de
ressources et donc en réduisant la durée de la session et la capacité
réseau utilisée. Toutefois, le RFC cite la possibilité d'attendre
encore un peu et d'aller jusqu'à la réception du message (commande
SMTP DATA
). Le greylisteur ne va pas forcément
analyser le corps du message, il peut aussi attendre le
DATA
car certains clients bogués réagissent mal
lorsque le refus de continuer la session arrive avant
DATA
. Mais le RFC note que cette analyse du
contenu du message reste possible, bien que je ne connaissais pas de
greylisteur qui le fasse. Mais Gabriel Kerneis m'en a cité un : sa-exim qui documente cette fonction. Et il y a aussi smtpf.
Naturellement, un greylisteur peut inclure d'autres informations dans sa prise de décision comme la présence de l'expéditeur dans une liste noire (RFC 5782) ou comme un motif dans le nom du client (on fait une requête pour traduire l'adresse IP en nom, et si dyn ou adsl sont dans le nom, on rejette temporairement).
Le greylisteur peut aussi avoir une liste d'exceptions, pour gérer les
cas particuliers, par exemple ceux dont on sait qu'ils ne réessaient
pas correctement, ou qui attendent trop longtemps avant de
réessayer. Par exemple, pour Postgrey, on trouve dans le fichier
/etc/postgrey/whitelist_clients
une liste de
domaines dont l'émetteur de courrier est défaillant (il ne réessaie
pas) mais dont on souhaite recevoir les messages, par exemple :
... # greylisting.org: Southwest Airlines (unique sender, no retry) southwest.com ...
Comme toute technique de sécurité, le greylisting est un compromis : il a des bénéfices et il a des coûts. La section 3 est consacrée à l'examen de ces avantages et inconvénients (et la section 9 revient ensuite sur certains de ces choix). L'avantage principal est qu'une partie significative du spamware ne réessaie jamais, après le refus initial, et que la quantité de spam à traiter va donc diminuer.
L'inconvénient principal est que certains messages seront retardés. Le MTA typique réessaie par défaut au bout de 15 minutes mais c'est réglable et les gros hébergeurs de courrier augmentent en général cette durée, souvent jusqu'à 60 minutes, pour limiter la charge de leurs serveurs, dont la file d'attente est souvent très grosse. Pire, certains (comme le serveur de Southwest Airlines, cité plus haut) ne réessaient pas du tout. Dans ce dernier cas, ils sont en violation caractérisée de la norme SMTP et auront des problèmes avec bien d'autres choses que le greylisting (une coupure réseau, et hop, le courrier est fichu).
Ce problème du retard est-il sérieux ? Le courrier électronique a toujours été « au mieux », c'est-à-dire qu'une distribution immédiate ne fait pas partie du cahier des charges. Si des gens comptaient sur une délivrance instantanée, c'est qu'ils n'avaient pas compris le principe du courrier.
Le retard est de toute façon rare en pratique. Comme le greylisteur se souvient des émetteurs corrects (qui réessaient après la première rebuffade) qu'il a rencontrés, et comme la plupart des messages entrants viennent de correspondants réguliers, peu de messages sont vraiment retardés. Si on souhaite à tout prix réduire encore ce nombre, notamment en mettant en service un nouveau serveur, dont la mémoire est vide, on peut toujours envisager de pré-remplir la mémoire avec des adresses extraites du journal (le RFC cite cette possibilité, que je trouve bien compliquée et n'en valant pas la peine).
La section 4 décrit en détail les conséquences non souhaitées du greylisting. Comme pour les notices des médicaments qui préviennent des effets secondaires possibles, il faut la lire en mettant ces inconvénients en rapport des avantages (voir aussi la section 9.1, sur les compromis). Exemple de problème, si on a plusieurs serveurs de courrier (plusieurs entrées dans l'enregistrement MX), et s'ils ne partagent pas leur base d'émetteurs, un client SMTP qui, refusé par le premier, essaiera le second, puis le troisième, etc, sera ainsi retardé plusieurs fois. En parlant de MX secondaire, le RFC recommande également de configurer le primaire pour qu'il accepte les messages des secondaires sans greylisting (puisque le message a déjà été greylisté par le secondaire, a priori une machine de confiance).
Autre cas pathologique, celui d'une machine qui n'envoie du courrier que rarement. Ses informations expireront de la base avant le prochain envoi et elle sera donc souvent considérée comme « nouvelle » et donc greylistée.
Outre le retard, un effet parfois ennuyeux du greylisting est le
réordonnancement des messages. Si Alice écrit à Bob et Charlie et que
son émetteur est connu du MTA de Bob, mais pas de celui de Charlie, la
délivrance à Charlie sera retardée. Si Bob répond à Alice, et que le
MTA de Bob est connu de celui de Charlie, Charlie recevra la réponse
de Bob avant le message original d'Alice. Une note personnelle au
passage : cela montre l'importance des MUA qui
remettent les messages dans l'ordre comme mutt
avec son option set sort=date-sent
(qui dépend
d'un réglage correct de la date par l'expéditeur) ou
set sort=threads
(qui utilise les en-têtes du
message comme References:
).
Il y a aussi des problèmes qui sont de la faute du client SMTP. S'il ne réessaie pas, il aura des problèmes avec le greylisting mais aussi avec toute panne réseau temporaire. S'il considère tous les codes d'erreur SMTP comme permanentes (alors que la section 4.2.1 du RFC 5321 est bien clair que les codes de type 4xy sont des erreurs temporaires), il aura des problèmes avec le greylisting et avec certaines erreurs sur le MTA.
Si le client SMTP utilise une adresse d'expéditeur de courrier différente pour chaque essai (une idée très baroque mais tout existe sur l'Internet), et que le greylisteur utilise cette adresse pour déterminer si un envoi est nouveau, alors, le message ne passera jamais.
Enfin, les logiciels de test des adresses de courrier peuvent avoir des problèmes avec le greylisting comme Zonecheck et sa bogue #9544.
Après cette liste de problèmes possibles, les recommandations concrètes, pour que le greylisting apporte joie et bonheur et que les problèmes restent virtuels. Elles figurent en section 5 et les principales, tirées de la longue expérience du greylisting, sont notamment :
MAIL FROM
, première adresse de
courrier dans le RCPT TO
}. L'inclusion des
adresses de courrier a notamment pour but de limiter le
réordonnancement des messages. Une fois que ce test a
été passé une fois, autoriser l'adresse IP quelles que soient les
adresses (le MTA client a montré qu'il réessayait, de toute façon).--delay
.)--max-age
.)--lookup-by-subnet
, mais où la longueur du
préfixe est fixe, 24 bits en IPv4. Greyfix est plus souple.)/etc/postgrey/whitelist_clients
.)En revanche, notre section 5 ne recommande pas de valeur particulière pour le code de retour SMTP lorsqu'on refuse temporairement un client. 421 et 450 semblent les deux choix possibles (RFC 5321, section 4.2.2).
SMTP permet de mettre dans la réponse, outre un code numérique, un court texte. Faut-il dire explicitement que du greylisting est en action, ce qui peut aider un spammeur ? Le RFC estime que oui, pour être sympa avec les utilisateurs légitimes (c'est ce que font les deux logiciels de greylisting montrés en exemple dans cet article).
La section 6 du RFC est consacrée à la question de la mesure de l'efficacité du greylisting. Elle suggère une expérience intéressante que, à ma connaissance, personne n'a tenté : regarder si les adresses IP greylistées (et qui ne réessaient pas) sont plus souvent présentes que les autres dans les grandes DNSBL. Une corrélation indiquerait qu'on gêne bien surtout les spammeurs.
Il existe aujourd'hui des mises en œuvre du greylisting pour à peu
près tous les MTA possibles. Pour
Postfix, les deux solutions les plus courantes
en logiciel libre sont Greyfix et Postgrey. On configure Greyfix en indiquant dans le
master.cf
de Postfix :
greyfix unix - n n - - spawn user=nobody argv=/usr/local/sbin/greyfix --greylist-delay 300 --network-prefix 28
Les deux options indiquées ici lui imposent de ne pas accepter un
nouveau client avant 300 secondes, et de considérer toutes les
adresses d'un même /28 comme équivalentes. (Greyfix peut aussi le
faire en IPv6, avec --network6-prefix
.). Un nouveau
client rejeté est journalisé ainsi :
May 29 14:59:32 aetius postfix/smtpd[25150]: NOQUEUE: reject: RCPT from unknown[117.214.206.76]:4974: 450 4.7.1 <w3c@bortzmeyer.org>: Recipient address rejected: Greylisted by greyfix 0.3.9, try again in 300 seconds. See http://www.kim-minh.com/pub/greyfix/ for more information.; from=<viagra-soft.pills@peoplecube.com> to=<w3c@bortzmeyer.org> proto=ESMTP helo=<rkktfe.com>
Pour
Postgrey, qui tourne comme un démon séparé, ici
sur le port 10023, la
configuration se fera dans le main.cf
:
smtpd_recipient_restrictions = permit_mynetworks, \ check_policy_service inet:127.0.0.1:10023
Et un client rejeté produira :
May 28 16:08:33 lilith postfix/smtpd[20582]: NOQUEUE: reject: RCPT from 241.146.12.109.rev.sfr.net[109.12.146.241]:3964: 450 4.2.0 <info@generic-nic.net>: Recipient address rejected: Greylisted, see http://postgrey.schweikert.ch/help/generic-nic.net.html; from=<banderolepub01@gmail.com> to=<info@generic-nic.net> proto=SMTP helo=<3lyw4> May 28 16:08:33 lilith postgrey[1447]: action=greylist, reason=new, client_name=241.146.12.109.rev.sfr.net, client_address=109.12.146.241, sender=banderolepub01@gmail.com, recipient=info@generic-nic.net
Une question un peu philosophique, maintenant, que ne traite guère
notre RFC. Pourquoi est-ce que les logiciels de spam courants ne réessaient
pas, après l'erreur temporaire reçue ? Cela peut sembler déroutant
puisque, de leur point de vue, ce serait la solution évidente au
greylisting. Il y a plusieurs raisons à cette passivité. L'une
est que le greylisting n'est pas universellement déployé. S'il l'était, les
choses changeraient peut-être (finalement, était-ce une bonne idée de
publier ce RFC ?) Ce point de vue est par exemple développé dans
l'Internet-Draft draft-santos-smtpgrey
. Ensuite,
les spammeurs visent typiquement le volume,
pas la qualité. Pourquoi s'embêter à réessayer alors qu'il est bien
plus efficace, en terme de volume, de passer tout de suite à la
victime suivante dans la liste ? Mais il y a aussi sans doute
aussi crainte d'être repérés s'ils essaient : un
zombie essaie en général d'être discret.
De bonnes lectures :
Merci à Kim-Minh Kaplan pour sa relecture.
Date de publication du RFC : Juillet 2012
Auteur(s) du RFC : H. Song, N. Zong (Huawei), Y. Yang (Yale University), R. Alimi (Google)
Pour information
Réalisé dans le cadre du groupe de travail IETF decade
Première rédaction de cet article le 10 juillet 2012
Dernière mise à jour le 20 septembre 2012
Le groupe de travail DECADE de l'IETF travaillait à optimiser les applications pair-à-pair notamment en leur permettant de stocker facilement des données dans le réseau (on devrait dire le cloud, pour que ce RFC se vende mieux). Ce RFC décrit précisement les problèmes que DECADE essayait de résoudre, les solutions étant prévues pour de futurs documents. Le principal problème identifié est de doter les applications P2P d'accès à des caches dans le réseau, évitant d'utiliser de manière répétée des liens coûteux et/ou lents. DECADE ayant été fermé en septembre 2012, le projet ne se conclura sans doute pas.
Ce n'est pas que ces caches n'existent pas déjà : des tas d'applications en ont. Mais ils souffrent de limites : étant souvent spécifiques à une application (BitTorrent, FlashGet, Thunder, etc), ils ne peuvent pas être réutilisés via un protocole standard, et ils n'ont pas de mécanismes de contrôle d'accès permettant, par exemple, de mettre des données dans le cache mais de limiter leur accès à certains.
Le pair-à-pair sert à beaucoup de choses (deux cas connus sont le partage de fichiers, et le streaming vidéo) et ces usages sont souvent très consommateurs de ressources réseau. Cette consommation justifie qu'on travaille activement à limiter le gaspillage. C'est particulièrement gênant pour « le dernier kilomètre », la ligne, relativement lente, qui connecte M. Toutlemonde à son FAI. Les accès actuellement commercialisés sont presque toujours asymétriques (bien plus de capacité dans le sens TF1->temps-de-cerveau que dans le sens citoyen-producteur->réseau). Si M. Toutlemonde a un gros fichier sur le disque dur de son PC à la maison, et que dix personnes le téléchargent, le gros fichier encombrera dix fois l'accès « montant » de M. Toutlemonde, à son grand dam. Il est ainsi courant que la grande majorité de la capacité montante soit prise par le pair-à-pair. M. Toutlemonde pourrait « téléverser » le fichier une fois pour toutes chez un hébergeur situé « dans le nuage » mais attention : pour qu'il conserve les avantages du pair-à-pair, cela devrait être intégré dans les applications, sans qu'il y ait besoin d'un compte Dropbox (avec acceptation de conditions d'usage qui disent que le gérant du nuage fait ce qu'il veut des données), d'un téléversement explicite, etc. Bref, que cela se fasse tout seul.
Un problème analogue à celui de M. Toutlemonde est celui de l'hébergeur dont un client a un fichier qui intéresse dix personnes à l'extérieur de l'hébergeur. Faire passer le fichier dix fois sur les coûteux liens de transit n'est pas une utilisation géniale de la capacité réseau... À noter qu'une autre voie d'optimisation, complémentaire de celle de DECADE, est celle du groupe de travail ALTO, qui consiste à faciliter la découverte de ressources proches (« télécharger localement »), comme décrit dans le RFC 5693. ALTO ne fonctionne que si le contenu est déjà disponible localement. Sinon, DECADE prend le relais. Deux autres efforts IETF qui ont un rapport avec DECADE, et lui sont complémentaires, sont PPSP, sur la conception d'un protocole de streaming en pair-à-pair (RFC 7574), et LEDBAT, sur des mécanismes permettant à des applications non critiques de céder automatiquement les ressources réseau aux autres (RFC 6297 et RFC 6817).
On l'a vu, il existe déjà des applications pair-à-pair qui ont des formes de cachage des données. Mais chacune nécessite d'être adaptée à un protocole pair-à-pair particulier, alors que le travail de DECADE est plutôt de chercher des solutions génériques, qui pourraient convenir à tout nouveau protocole. Une telle solution générique n'existe pas actuellement. Mais des projets ont déjà été définis comme les Data Lockers. Avec un tel système, le PC de M. Toutlemonde pourrait téléverser le fichier dans le nuage, là où la capacité réseau est meilleure, et les pairs de M. Toutlemonde aller le chercher là-bas, sans que M. Toutlemonde ait d'action explicite à faire, et sans qu'il gaspille les ressources du dernier kilomètre.
L'exercice de DECADE sera donc de définir un protocole d'accès standard à ces ressources de stockage dans le nuage. Ce protocole comportera deux parts : la signalisation (permettant de découvrir les caractéristiques de ces ressources) et le transfert permettant de lire et d'écrire le contenu. La difficulté sera d'identifier ce qui est suffisamment commun chez tous les protocoles, pour faire l'objet d'une normalisation. Et le protocole devra être assez souple pour s'adapter à des applications pair-à-pair qui ont des caractéristiques très différentes.
Une étude a déjà été faite par le groupe de travail DECADE sur les systèmes de stockage des données en ligne. Documentée dans le RFC 6392, elle liste les systèmes existants sur lequels aurait pu être basé le futur protocole DECADE.
Si cela vous semble encore un peu flou, vous pouvez sauter à la section 4 qui présente des études de cas pour certaines applications. Par exemple, pour BitTorrent, ce qui est envisagé est de modifier les pairs pour qu'ils envoient les blocs de données (l'unité de transfert de base de BitTorrent) non pas à chaque autre pair mais à un cache dans le réseau, en indiquant au pair où le bloc a été mis.
Un autre cas étudié est celui des distributeurs de contenu (par exemple une vidéo) et qui voudraient le mettre le plus proche possible des « globes oculaires » (les consommateurs de contenu). Garder la vidéo sur son petit site Web mal connecté ne permettra pas une distribution efficace. Faire appel à un CDN imposera l'utilisation de l'interface spécifique de ce CDN, et tout sera à recommencer en cas de changement de fournisseur. Le protocole standard mentionné plus haut résoudrait ce problème. Pour ce cas, encore plus que pour celui du pair-à-pair, il est important que celui qui met des données dans le réseau puisse indiquer les règles d'accès (par exemple, ne distribuer qu'à des utilisateurs identifiés).
Tout cela, vous vous en doutez, soulève plein de problèmes de sécurité. La section 5 les passe en revue. D'abord, il y a un risque évident de déni de service, par exemple avec un méchant stockant tellement de données qu'il remplit tout le nuage et ne laisse rien pour les autres. Il est donc crucial d'avoir des mécanismes d'authentification et d'autorisation.
Ensuite, lorsqu'on dit « distribution de contenu multimédia », « partage en pair-à-pair », on peut être sûr que des hordes de juristes vont accourir et réclamer que les règles définies par l'industrie du divertissement soient automatiquement mises en œuvre par les systèmes techniques, ici par le stockage dans le nuage. (Par exemple, distribution du contenu à certains pays seulement, pour permettre de faire payer plus un sous-ensemble des pays.) Le RFC dit sagement que ce genre de demandes est hors-sujet pour le projet DECADE.
Le fournisseur du système de stockage va en apprendre beaucoup sur les utilisateurs, ce qui peut menacer leur vie privée. Même si le contenu est chiffré, le fait que N personnes demandent le même fichier est déjà une indication utile (qu'elles ont les mêmes centres d'intérêt). Un autre risque avec un fournisseur de stockage méchant est qu'il modifie le contenu des fichiers qu'on lui a confié. Le RFC ne fournit pas de solutions pour ces deux derniers problèmes (une signature cryptographique permettrait de traiter le second).
Bref, ce n'est pas le travail qui manquait pour le groupe DECADE. Il travaillait sur les trois futurs RFC de cahier des charges pour le protocole d'accès au stockage, de description de l'architecture du système, et de l'intégration avec les protocoles existants, comme BitTorrent. Mais les difficultés colossales de ce travail ont eu raison du groupe, qui a été dissous en septembre 2012. (Après coup, le travail déjà fait a été publié dans le RFC 7069.)
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : W. George (Time Warner Cable)
Pour information
Première rédaction de cet article le 25 juin 2012
Il n'y a pas que de gros RFC sérieux, détaillant pendant des dizaines de pages des protocoles compliqués. L'IETF est aussi une occasion de nombreuses rencontres dans le Vrai-Monde-Physique, grâce à ses réunions qui se tiennent trois fois par an dans des lieux éloignés (du point de vue de l'auteur du RFC et de ses lecteurs). Pour diminuer le stress de l'ingénieur en déplacement, il faut lui fournir de l'information. Laquelle ? Ce RFC répond à la question.
Il ne contient pas les réponses aux questions des étrangers en visite. Ces réponses dépendent du pays visité (et elles changent vite alors que les RFC sont statiques). Mais il liste les questions, de manière à ce que les indigènes puissent documenter les points importants de leur beau pays.
En effet, il y a toujours des volontaires locaux qui montent un site Web ou un Wiki pour présenter de l'information sur le site de la réunion. (Le RFC en donne des exemples.) S'ils suivent ce RFC, ils sont sûrs de n'oublier aucune question. Le RFC liste les grands sujets :
Bref, un RFC pour les aventuriers, les explorateurs et les curieux. Voyagez, vous ne le regretterez pas.
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : A. Jivsov (Symantec Corporation)
Chemin des normes
Première rédaction de cet article le 12 juin 2012
Le format OpenPGP, normalisé dans le RFC 4880, permet de choisir parmi plusieurs algorithmes de cryptographie, afin de pouvoir suivre les progrès de la cryptanalyse. Notre tout nouveau RFC ajoute à la liste de ces algorithmes des algorithmes à courbes elliptiques, venant s'ajouter aux traditionnels RSA et DSA. Il a par la suite été intégré à la nouvelle version de la norme OpenPGP, dans le RFC 9580.
La section 3 rappelle deux ou trois choses sur les courbes elliptiques. Celles-ci sont décrites dans le RFC 6090 mais pour ceux et celles qui voudraient un cours plus scolaire, ce RFC recommande le Koblitz, « A course in number theory and cryptography », chapitre VI « Elliptic Curves » (ISBN: 0-387-96576-9, Springer-Verlag, 1987). La motivation principale pour utiliser les courbes elliptiques est qu'elles fournissent une alternative à l'augmentation régulière de la taille des clés RSA, augmentation rendue nécessaire par les avancées de la cryptanalyse. La section 13 de ce RFC fournit une estimation quantitative : la courbe elliptique P-256, avec ses 256 bits, fournit à peu près la résistance d'une clé RSA de 3 072 bits. Et la P-384 fournit environ l'équivalent de 7 680 bits RSA.
La NSA a listé une série d'algorithmes à courbes elliptiques recommandés, sous le nom de Suite B. Celle liste comprend deux algorithmes, ECDSA et ECDH, et trois courbes elliptiques (cf. norme NIST FIPS 186-3) P-256, P-384 et P-512. Ce RFC décrit donc comment intégrer la suite B au format ouvert et normalisé OpenPGP. Les deux algorithmes ont reçu les numéros 19 (pour ECDSA) et 18 (pour ECDH).
Si vous voulez l'encodage exact des paramètres de la courbe elliptique dans les données, voir les sections 6 à 8 de notre RFC. L'encodage des clés cryptographiques figure en section 9.
Au moins deux mises en œuvre d'OpenPGP ont déjà du code pour ces courbes elliptiques, celle de Symantec et le logiciel libre GnuPG. Pour ce dernier, le code est déjà dans la version de développement (tête du dépôt git) mais pas encore dans la dernière version officiellement publiée (la 2.0.19).
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : O. Kolkman (IAB), J. Halpern (Ericsson)
Pour information
Première rédaction de cet article le 12 juin 2012
L'articulation compliquée entre l'IETF qui produit les normes TCP/IP et le RFC Editor qui les publie, n'a jamais cessé de faire couler de l'encre (ou d'agiter des électrons). Dans ce document, l'IAB décrit un modèle pour le RFC Editor, modèle où les fonctions de ce dernier sont éclatées en plusieurs fonctions logiques. Elles peuvent ainsi être réparties entre plusieurs groupes. Ce modèle « v2 » est une version légèrement modifiée de la première description (« v1 »), qui figurait dans le RFC 5620. À son tour, il a été remplacé (mais sans changement fondamental du modèle) par le RFC 8728.
Le document de référence actuel est le RFC 8729. Comme le rappelle la section 1, il décrit les tâches du RFC Editor de manière globale, comme si c'était forcément une seule entité (c'était, à l'origine, une seule personne, Jon Postel). La section 2 note que la tâche de RFC Editor est actuellement une partie de l'IASA et financée par son budget.
La même section 2 s'attaque à la définition du rôle du RFC Editor sous forme de fonctions séparées. Le RFC 5620 avait été le premier à décrire ces fonctions. Elles sont ici légèrement modifiées, compte-tenu de l'expérience et des problèmes rencontrés, problèmes de communication qui n'existaient évidemment pas lorsque Postel faisait tout lui-même. (Notez que notre RFC 6635 ne donne malheureusement pas la liste des changements les plus importants, par rapport à la v1 du RFC 5620. Il est vrai qu'il n'y a rien de crucial, juste de la cuisine organisationnelle.) Le terme de RFC Editor désigne collectivement toutes ces fonctions. L'IAB voit maintenant trois fonctions (voir aussi le dessin 1 de notre RFC) :
Chaque section va ensuite détailler ces tâches. Il y a également des rôles de supervision, tenus par l'IAB (RFC 2850) et l'IAOC (RFC 4071).
L'Éditeur de la série des RFC (RFC Series Editor, actuellement Heather Flanagan ) est décrit en premier, en section 2.1. Il est responsable du travail à long terme, il doit définir les principes qui assurent la pérennité des RFC, réfléchir à la stratégie, développer le RFC 7322, le guide de style des RFC (ce qui inclus les délicates questions du format, de la langue des RFC, etc), etc. Il sert aussi de « visage » aux RFC, vis-à-vis, par exemple, des journalistes. L'Éditeur est censé travailler avec la communauté IETF pour les décisions politiques.
Le RFC 6635 évalue la charge de travail à un mi-temps, ce qui me semble très peu. Notre RFC décrit les compétences nécessaires (section 2.1.6) pour le poste d'Éditeur de la série des RFC, compétences en anglais et en Internet, capacité à travailler dans l'environnement... spécial de l'IETF, expérience des RFC en tant qu'auteur souhaitée, etc.
Le travail quotidien est, lui, assuré par le Producteur des RFC (RFC Production Center) dont parle la section 2.2. C'est un travail moins stratégique. Le Producteur reçoit les documents bruts, les corrige, en discute avec les auteurs, s'arrange avec l'IANA pour l'allocation des numéros de protocoles, attribue le numéro au RFC, etc.
Les RFC n'étant publiés que sous forme numérique, il n'y a pas d'imprimeur mais le numérique a aussi ses exigences de publication et il faut donc un Publieur des RFC (RFC Publisher), détaillé en section 2.3. Celui-ci s'occupe de... publier, de mettre le RFC dans le dépôt où on les trouve tous, d'annoncer sa disponibilité, de gérer l'interface permettant de soumettre les errata, de garder à jour ces errata, et de s'assurer que les RFC restent disponibles, parfois pendant de nombreuses années.
Chacune de ces fonctions pourra faire l'objet d'une attribution spécifique (à l'heure actuelle, les fonctions de Producteur et de Publieur sont assurées par le même groupe à l'AMS). La liste à jour peut être vue sur le site officiel.
Un comité joue un rôle de supervision et de contrôle du RFC Editor : le RSOC (RFC Series Oversight Committee) est décrit en section 3.
Combien cela coûte et qui choisit les titulaires des différentes fonctions ? La section 4 décrit ce rôle, dévolu à l'IAOC (RFC 4071). Le budget est publié en sur le site de l'IAOC ainsi que l'évaluation du RFC Editor. On peut aussi trouver cette information, ainsi que plein d'autres sur le fonctionnement du RFC Editor, via le site officiel).
Date de publication du RFC : Mai 2012
Auteur(s) du RFC : F. Gont (UTN-FRH / SI6 Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 29 mai 2012
Il y avait belle lurette que les messages ICMP « Répression de la source » (Source Quench) n'étaient plus utilisés. Ces messages devaient servir, à l'origine, à signaler à un émetteur qu'il exagérait et qu'il devrait ralentir l'envoi de données. Divers problèmes, notamment de sécurité, font que ces messages sont désormais ignorés par toutes les mises en œuvre de TCP/IP. Mais cet abandon de fait n'avait jamais été documenté. Voilà qui est fait, ce RFC 6633 marque donc l'abandon officiel de la répression de la source.
À l'origine, cette répression (quench) avait été normalisée dans le RFC sur ICMP pour IPv4, le RFC 792. De type 4 et de code 0, le message Source Quench était censé limiter la congestion en disant à l'émetteur qu'un récepteur n'arrivait plus à suivre. Inefficace et injuste, le Source Quench n'a jamais été très utilisé. Les routeurs ont officiellement arrêté de s'en servir avec le RFC 1812, dès 1995. Ce RFC notait déjà les limites et problèmes du Source Quench (dans sa section 4.3.3.3, qui fournissait des références).
En outre, les messages Source Quench, n'étant pas authentifiés, posaient un gros problème de sécurité : un méchant pouvait générer de faux messages pour réduire le débit de son ennemi, comme expliqué dans le RFC 5927 (et la section 8 de notre RFC). C'est d'ailleurs à cause de cela que des IDS comme Snort couinent lorsqu'ils voient passer des messages de répression de la source (voir Anderson, D., Fong, M., et A. Valdes, « Heterogeneous Sensor Correlation: A Case Study of Live Traffic Analysis », Proceedings of the 3rd Annual IEEE Information Assurance Workshop New York, NY, USA, 2002).
Restaient les protocoles de transport. Le RFC 1122 disait dans sa section 4.2.3.9 que les machines terminales devaient réagir aux Source Quench en diminuant le débit émis. La méthode recommandée pour TCP était de revenir au démarrage en douceur (RFC 5681).
De fait, le problème est réglé depuis longtemps, comme le
documentait le RFC 5927 : les mises en
œuvre de TCP et autres protocoles de
transport ignorent les messages Source Quench
depuis au moins 2005, RFC 1122 ou pas RFC 1122. L'annexe A de
notre RFC 6633 fait le tour des implémentation TCP/IP et note
que Linux a commencé à ignorer ces messages en
2004, FreeBSD,
NetBSD et Solaris depuis
2005, etc. Voici par exemple ce que fait NetBSD (fichier sys/netinet/tcp_subr.c
, routine tcp_ctlinput()
:
if (cmd == PRC_QUENCH) /* * Don't honor ICMP Source Quench messages meant for * TCP connections. */ return NULL;
Bref, ce RFC ne fait que documenter l'état des choses déjà existant.
En outre, ces messages Source Quench sont largement filtrés et ont donc peu de chances d'atteindre les machines qui émettent les données. Une étude de 1994 (Floyd, S., « TCP and Explicit Congestion Notification », ACM CCR Volume 24, Issue 5) notait déjà qu'on trouvait très peu de tels messages dans la nature. À la place, les routeurs sont censés utiliser ECN (RFC 3168) et (même si le RFC ne le rappelle pas), les machines terminales doivent de toute façon réagir aux pertes de paquets en ralentissant leur émission (RFC 5681).
Donc, le Source Quench est désormais officiellement abandonné. La section 3 de notre RFC modifie le RFC 1122 en demandant aux machines terminales de ne pas émettre de tels messages et d'ignorer ceux qu'elles recevraient. La section 4 fait de même pour les routeurs. La section 9 demande à l'IANA de marquer ces messages comme abandonnés dans le registre ICMP.
Il n'y avait pas de règle précise dans le passé pour d'autres protocoles de transport comme UDP ou SCTP. Les sections 5 et 6 de notre RFC leur applique la même règle : il faut ignorer complètement les messages de répression de la source qu'on pourrait recevoir.
Ah, et puis quelqu'un avait proposé une utilisation des messages Source Quench dans le RFC 1016. Suivant l'idée générale d'abandonner ces messages, la mise en œuvre de ce RFC est donc désormais déconseillée (cf. section 7).
De toute façon, le problème aurait disparu avec IPv4 : IPv6, lui, n'a jamais eu de message Source Quench (RFC 4443).
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : M. Ersue (Nokia Siemens Networks), B. Claise (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsawg
Première rédaction de cet article le 2 juin 2012
Selon une vieille blague de l'informatique, « ce qu'il y a de bien avec les standards, c'est qu'il y en a beaucoup parmi lesquels choisir. » Cette blague a été reprise dans un célèbre dessin de xkcd. Le but de ce RFC est-il de prendre le relais en montrant la variété des normes IETF relatives à la gestion des réseaux TCP/IP ?
En fait, non. Le but est de s'arrêter deux secondes de développer des nouveaux protocoles et de regarder ce qui existe (il y a donc une imposante bibliographie, reflet des très nombreux RFC cités). À une époque, il y avait un rêve, celui d'un protocole unique pour la gestion des réseaux (cela devait être SNMP). L'évolution des choses fait qu'aujourd'hui, l'architecte réseaux a à sa disposition plusieurs protocoles, dont les rôles se recouvrent en bonne partie. Même chose pour le membre de l'IETF qui développe un nouveau protocole et cherche des mécanismes de gestion de ce protocole. Ce RFC est donc juste un moyen de les aider à y voir plus clair. Il peut ausssi servir aux autres SDO qui veulent se renseigner sur le travail déjà existant, pour éviter de le dupliquer. Le lecteur pressé peut sauter tout de suite à l'annexe A du RFC (résumée à la fin de cet article), qui classe rapidement les protocoles avec des tableaux synthétiques.
D'abord, c'est quoi, la gestion des réseaux ? Ce sont l'ensemble des méthodes et techniques mises en œuvre par l'administrateur réseaux pour s'assurer que le réseau va bien, prévoir ses évolutions, et réparer ses pannes. Cela va du bon vieux ping aux mécanismes les plus complexes. (Si vous suivez les débats sur la neutralité de l'Internet, vous êtes peut-être déjà tombé sur des termes comme « services gérés » ou « gestion de trafic ». Il faut savoir que ces termes relèvent de la propagande des opérateurs réseaux, qui cherchent à justifier des services privilégiés - et plus chers - en prétendant qu'ils seraient « gérés », comme si le reste de l'Internet marchait tout seul. Les termes corrects sont « services privilégiés » et « discrimination de trafic ».)
Il y a déjà eu des RFC analogues à celui-ci (section 1.2). Par exemple, le RFC 6272 faisait le tour de tous les protocoles TCP/IP (y compris ceux sur la gestion de réseaux) dans le contexte de la Smart grid. Le RFC 3535 rendait compte d'un atelier de l'IAB consacré à la gestion de réseaux, qui avait examiné la situation en 2002. Le RFC 5706 posait les règles relatives à la gestion pour tous les nouveaux protocoles IETF, imposant qu'ils prennent en compte cette gestion dès le premier RFC. Enfin, les RFC 4221 et RFC 6371 décrivent le cas spécifique de la gestion des réseaux MPLS et sont à l'origine d'un conflit de compétences avec l'UIT qui dure encore aujourd'hui (cf. RFC 5704). Plusieurs Internet-Drafts sont également en cours de rédaction sur ce sujet de l'OAM (Operations, Administration and Maintenance, ce sigle est souvent utilisé dans le monde MPLS pour parler de la gestion des réseaux).
La section 2 de notre RFC couvre les protocoles de gestion généralistes, qui peuvent servir à tout. Le premier est évidemment SNMP (section 2.1). Il s'agit en fait d'une structure modulaire, avec un modèle de données (les fameuses MIB), un mécanisme d'encodage de ces données sur le réseau et un protocole, SNMP. Le RFC de description général est le RFC 3410, pour SNMPv3. Un réseau est vu par SNMP comme un ensemble de machines gérées (les agents), une ou plusieurs machines de gestion (le ou les managers) et le protocole utilisé entre les deux (SNMP). Les variables exportées par l'agent sont décrites dans une MIB, et il en existe des dizaines de normalisées et encore plus de privées.
SNMP v1 (RFC 1157) et v2 avaient de sérieuses limites en matière de sécurité, la version officielle aujourd'hui est donc la v3, normalisée dans le RFC 3411 (mais la v1 reste très utilisée). SNMP est présent partout, pour lire les valeurs des variables des équipements réseaux, faire des statistiques, aider à déboguer les pannes, etc. C'est un des grands succès de l'IETF.
Pour décrire les données récupérées en SNMP, un cadre standard existe nommé SMI (Structure of Managed Information), actuellement en version 2, normalisée dans les RFC 2578 et RFC 2579. Ces RFC définissent entre autre le langage dans lequel sont écrits les MIB.
SNMP est, on l'a vu, très répandu, et le RFC lui consacre à juste titre de nombreuses pages, parlant de sa sécurité, du mécanisme de transport, etc. Un autre protocole très populaire pour la gestion de réseaux est syslog (section 2.2). Il est concurrent de SNMP pour le signalement de problèmes (les traps de SNMP) mais, autrement, il ne remplit pas le même rôle. syslog sert à une machine à transmettre de l'information (pas forcément une panne) en temps réel, à des fins d'alarme ou de journalisation. Décrit d'abord dans le RFC 3164, il est désormais normalisé (sous une forme bien plus riche) dans le RFC 5424. Le syslog traditionnel des débuts ne prévoyait pas de structure pour le message envoyé : c'était juste du texte libre. Le RFC 5424 a introduit la notion de messages syslog structurés, analysables par un programme.
Si syslog est très répandu (on trouve des récepteurs syslog en logiciel libre sur tous les Unix, tous les routeurs savent émettre du syslog, etc), je ne suis pas sûr que les extensions modernes, encore peu implémentées, soient souvent utilisées.
Autre protocole très répandu dans la boîte à outils de
l'administrateur réseaux, IPFIX (souvent
désigné par son ancien nom, NetFlow). La
section 2.3 décrit son rôle : IPFIX permet de récolter de
l'information statistiques sur les flots de données qui sont passés
par un routeur (« [2001:db8:1::42]:35612
a parlé à
[2001:db8:cafe::1337]:80
et il a reçu 935
ko ») et de la transmettre à une machine de gestion. Avoir des
compteurs par flot (un flot étant typiquement une connexion
TCP complète) permet d'avoir une information
plus légère que si on transmettait des données sur chaque paquet.
L'architecture d'IPFIX est décrite dans le RFC 5470 et le protocole est dans le RFC 7011. L'ancien Netflow, lui, était décrit dans le RFC 3954. IPFIX/Netflow est très répandu et la plupart des opérateurs l'utilisent pour suivre l'activité de leurs réseaux. (Le logiciel libre ntop le parle, entre autres.)
Si on veut suivre les paquets individuels, il y a le protocole PSAMP (Packet SAMPling) du RFC 5474. Il permet d'utiliser le protocole d'IPFIX pour transmettre des données sur les paquets (qu'on a pu, pour limiter le trafic, échantilloner, comme bien expliqué dans le RFC 5475).
IPFIX, syslog et SNMP (tel que réellement utilisé dans la plupart des cas, sans ses fonctions d'écriture) ne font que lire les informations. Si on veut les modifier, si on veut changer la configuration d'un routeur, par exemple, que fait-on ? SNMP avait théoriquement un mécanisme pour cela mais, en pratique, il n'est que très rarement utilisé. L'atelier de l'IAB raconté dans le RFC 3535 identifiait ce manque (section 2.4) et l'un des résultats a été le protocole NETCONF normalisé dans le RFC 6241. NETCONF permet d'envoyer des commandes de configuration (encodées en XML) à un équipement réseau. Relativement récent, NETCONF n'est pas encore d'usage universel.
Pour décrire les données manipulées par NETCONF, l'IETF a un langage, YANG (RFC 6020). Celui-ci dispose d'un certain nombre de types de données pré-existants, normalisés dans le RFC 6991. Ces types sont évidemment proches de ceux que le SMI v2 avait déjà, pour SNMP. Idéalement, il faudrait encore ajouter une traduction standard de SMI vers YANG, afin de pouvoir récupérer toutes les MIB existantes. Pour l'utilisation de NETCONF et de YANG dans une solution globale, voir le RFC 6244. YANG est encore plus récent que NETCONF et encore peu déployé.
Tous ces protocoles, SNMP, syslog, NETCONF, etc, sont génériques et peuvent servir à gérer des tas de protocoles différents. La section 3 couvre au contraire les protocoles de gestion spécifiques, liés à une tâche donnée. Elle commence avec les protocoles de gestion de l'allocation d'adresses IP (section 3.1). D'abord, DHCP (RFC 2131 et RFC 8415). Il permet de transmettre à une machine son adresse IP mais aussi plein d'autres informations de configuration comme le résolveur DNS à utiliser (RFC 3646). DHCP n'offre aucun mécanisme de sécurité et le RFC rappelle donc qu'il vaut mieux ne l'utiliser que sur des réseaux dont l'accès physique est contrôlé.
Les adresses IP peuvent aussi être configurées automatiquement, sans serveur, dans le cadre décrit par le RFC 5889.
Depuis de nombreuses années, l'Internet est en cours de transition (très lente) d'IPv4 vers IPv6. Cette transition a donné naissance à tout un ensemble de techniques spécifiques, à commencer par le RFC 4213.
Une part importante de la gestion des réseaux est la mesure des performances (section 3.4). Ce n'est pas tout d'aller bien, il faut encore aller vite. Un groupe de travail IETF spécialisé, IPPM existe depuis longtemps pour développer des métriques (des grandeurs mesurables et rigoureusement définies) pour les réseaux TCP/IP. Il a produit un document de cadrage (RFC 2330), un document sur le développement de nouvelles métriques (RFC 6390), et de nombreuses métriques comme le délai de transmission (RFC 7679), le taux de pertes (RFC 7680), la mesure de la duplication de paquets (RFC 5560), etc. Pour pouvoir mesurer effectivement ces métriques, plusieurs protocoles ont été créés comme OWAMP (One-way Active Measurement Protocol, RFC 4656).
Toujours dans cette section de protocoles divers, une part importante est dédiée à RADIUS (RFC 2865), protocole permettant l'authentification d'un client, connecté à un NAS (Network Access Server), et utilisant un serveur d'authentification partagé entre plusieurs NAS. RADIUS permet par exemple à un FAI de centraliser l'authentification afin d'éviter que chaque NAS ait une base d'utilisateurs différente. Il est très largement utilisé aujourd'hui. De nombreux RFC sont venus lui ajouter telle ou telle fonction, ou guider les programmeurs (RFC 5080).
Officiellement, RADIUS a un concurrent, Diameter (RFC 6733). Conçu après, incompatible avec la base déployée, censé résoudre des problèmes réels ou supposés de RADIUS, Diameter n'a guère eu de succès. Le RFC oublie complètement de mentionner cet échec ; RADIUS est simple et facilement implémentable, Diameter, grosse usine à gaz, ne l'a jamais réellement concurrencé.
La section 3 décrit encore plusieurs autres protocoles peu connus, mais j'arrête ici. Il y a un autre gros morceau à avaler, les modèles de données pour la gestion de réseaux (section 4). Ils sont très nombreux et couvrent beaucoup d'aspects de la gestion de réseaux. Un de mes préférés est le peu connu RMON (RFC 2819), qui modélise des sondes réseaux. Il permet de déclencher à distance, avec SNMP, des mesures du réseau.
L'annexe A, présentée au début, est une sorte de résumé pour lecteurs pressés. Elle classe les différents protocoles de gestion de réseaux (rappelez-vous que la liste est longue) selon divers critères (fonctionnement en push ou en pull, passif ou actif, extensibilité de leur modèle de données, etc)
Le premier tableau, en A.1, classe les protocoles selon leur place dans le chemin des normes (cf. RFC 2026, notre RFC ne tient pas encore compte de la réduction de ce chemin à deux entrées, dans le RFC 6410). Ainsi, SNMP est Internet standard (norme au sens propre) alors qu'IPFIX n'est que Proposed standard (projet de norme) et que DHCP n'a jamais décollé de la première étape, Draft standard (proposition de norme), en dépit de son très vaste déploiement.
Autre façon de classer, en A.2, selon les tâches à accomplir. Syslog et SNMP permettent la surveillance du réseau mais SNMP permet en outre d'agir sur la configuration de celui-ci (en pratique, il n'est guère utilisé pour cette tâche). NETCONF peut faire de la configuration, mais, si on veut mesurer les performances, ce sont SNMP et IPFIX.
Comment ces protocoles font-ils leur travail (A.3) ? SNMP et NETCONF sont pull (la machine de gestion décide quand agir), Syslog, RADIUS ou IPFIX sont purement push (ils réagissent aux événements extérieurs). Notez que SNMP a aussi une fonction Push, les notifications (auutrefois nommées traps).
Autre façon de les regarder travailler (A.4), certains protocoles sont actifs posant des questions au réseau (ping et traceroute - RFC 1470, BFD - RFC 5880, OWAMP, etc). D'autres sont passifs, observant simplement le réseau (IPFIX, PSAMP, etc).
Le travail de gestion des réseaux ne s'arrêtera jamais. Il y aura toujours de nouveaux problèmes et de nouvelles solutions. L'annexe B décrit un travail récent à l'IETF, la gestion de l'énergie, préoccupation désormais très forte, en raison de l'augmentation des coûts de l'électricité et des soucis écologiques plus présents (menant par exemple à des lois plus strictes). Actuellement, dans la gestion de réseaux, il est rare que la consommation électrique soit prise en compte. Les serveurs ne distribuent pas cette information et les logiciels de gestion ne la demandent pas. On surveille le taux de pertes de paquets, le débit, mais pas la consommation électrique au niveau de chaque machine.
Une des difficultés pour effectuer cette mesure est que la consommation électrique est souvent mieux mesurée en dehors de la machine, par exemple par une source PoE, ou bien par un bandeau électrique « intelligent ». Il faut donc travailler, entre autres, sur la liaison entre une machine et sa consommation. C'est la tâche du groupe de travail IETF EMAN (cf. RFC 6988 et RFC 7326, publiés depuis).
Date de publication du RFC : Mai 2012
Auteur(s) du RFC : J. Dong, M. Chen (Huawei Technologies), A. Suryanarayana (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 7 mai 2012
Un très court RFC pour enrichir la liste des codes d'erreur qu'un routeur BGP peut envoyer à son pair en cas de problèmes dans l'automate à états finis du protocole. Cela devrait permettre d'améliorer les messages d'erreur vus par les opérateurs de routeurs.
La section 4.5 du RFC 4271 (qui normalise
BGP), indique le mécanismes des codes d'erreur
à envoyer à un pair en cas de problèmes. Il y a les
codes (1 pour une erreur dans l'en-tête d'un
paquet, 2 pour une erreur à l'ouverture d'une session, 3 pour une
erreur lors du traitement d'une mise à jour des routes, etc) et les
sous-codes, dont la signification dépend du
code. Ainsi, lorsque le code vaut 2 (erreur lors d'une ouverture de
session BGP entre deux pairs), un sous-code 2 indique que le numéro
d'AS du pair n'est pas celui qui était configuré
(tcpdump affiche cette erreur avec BGP (NOTIFICATION: error OPEN Message Error, subcode Bad Peer AS
). Lorsque le code d'erreur est 3 (erreur
lors d'un message UPDATE
), le sous-code 2 veut
dire, par contre, qu'un attribut BGP envoyé par le pair est
inconnu.
Un des codes d'erreur est 5, problème dans l'automate à états finis : typiquement, un message a été reçu alors qu'il n'aurait pas dû l'être, vu l'état actuel de l'automate. Mais ce code 5 n'avait pas de sous-code (cf. RFC 4271, section 6.6) et il était donc difficile de connaître le problème exact. Ce RFC comble ce manque.
Les nouveaux sous-codes sont donc (la liste des états de l'automate est dans le RFC 4271, section 8.2) :
OpenSent
. Par exemple, si un routeur
est dans l'état OpenSent
(message
OPEN
envoyé mais pas encore de réponse favorable)
et reçoit un message UPDATE
(mise à jour des
routes, ne devrait être envoyé que si la session est opérationnelle),
alors il renverra un message NOTIFICATION
avec
le code à 5 et le sous-code à 1.OpenConfirm
,Established
(session BGP
opérationnelle). Ce serait le cas, par exemple, d'un message
OPEN
reçu dans cet état.Ces sous-codes sont enregistrés à l'IANA et de nouveaux sous-codes ne pourront être ajoutés que via un RFC sur le chemin des normes (cf. RFC 5226).
L'annonce du RFC notait qu'il existait déjà deux mises en œuvre de ces sous-codes mais j'avoue ignorer desquelles il s'agit.
Date de publication du RFC : Mai 2012
Auteur(s) du RFC : E. Kim (ETRI), D. Kaspar (Simula Research Laboratory), C. Gomez (Universitat Politecnica de Catalunya/i2CAT), C. Bormann (Universitaet Bremen TZI)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6lowpan
Première rédaction de cet article le 29 mai 2012
Il y en a, des RFC produits par le groupe de travail 6lowpan, qui a pour tâche de normaliser des protocoles pour les LowPAN (Low-Power Wireless Personal Area Network), ces réseaux de toutes petites machines, limitées en puissance de calcul et en électricité (réseaux de capteurs industriels, par exemple). Parmi les questions soulevées par les LowPAN, le routage. Les liens radio 802.15.4 entre les machines ont une portée limitée et la communication entre deux machines quelconques du LowPAN nécessite parfois une transmission par un ou plusieurs routeurs intermédiaires. Les normes des couches basses, comme IEEE 802.15.4 ne spécifient pas de mécanisme pour gérer ce routage. Ce RFC 6606 est le cahier des charges pour les protocoles de routage du LowPAN, protocoles qui seront établis par d'autres groupes comme Roll, qui travaille sur un problème plus général que celui des seuls LowPAN et a normalisé le protocole RPL dans le RFC 6550. Notez qu'il y a eu d'autres RFC proches comme le RFC 5826 qui se focalise sur le cas particulier de la domotique, ou le RFC 5673, pour les réseaux industriels.
Pour réviser les caractéristiques des machines d'un LowPAN, le mieux est de lire le RFC 4919. Pour savoir comment IPv6 (le 6 dans le nom du groupe 6lowpan) fonctionne sur un LowPAN, c'est le RFC 4944. Un point important à garder en tête avant d'étudier le routage est que ce dernier consomme des ressources (courant électrique, par exemple) et qu'il faut donc limiter cette fonction aux machines les mieux pourvues.
La norme de couche 2 IEEE 802.15.4, sur laquelle s'appuient les LowPAN ne dit pas comment les topologies sont établies puis maintenues. Et elle ne spécifie pas de protocole de routage. Dans un LowPAN, on distingue traditionnellement deux formes de « routage », une en couche 2, le mesh under (brièvement mentionné dans le RFC 4944 : tout le LowPAN est un seul réseau IP), et une en couche 3 (la seule qu'on devrait normalement appeler « routage »), le route over. Le groupe Roll cité plus haut ne travaille que sur le route over (le « vrai » routage) mais notre RFC 6606 couvre les deux formes. Pour le routage, l'IETF a déjà des tas de protocoles (comme OSPF). Mais aucun ne convient aux LowPAN, en raison de leurs caractéristiques propres (notamment les faibles ressources en processeur et en puissance électrique, et le problème spécifique posé par l'hibernation).
Le RFC 4919 formulait déjà des exigences spécifiques pour les protocoles de routage du LowPAN : minimisation de la consommation de ressources, et acceptation des machines qui hibernent pendant la majorité du temps. Ce RFC 6606 reprend et détaille ces exigences.
Notez que, dans un LowPAN typique, les adresses allouées aux machines n'ont aucune chance de suivre la topologie du réseau. Il n'y a donc pas de possibilité de router par préfixe IP, d'agréger des préfixes adjacents, etc.
Il y a beaucoup de sortes de LowPAN, d'autant plus qu'on en est aux débuts et qu'on ne sait pas encore tout. La section 4 détaille les caractéristiques des différents types de LowPAN qui peuvent avoir une influence sur les algorithmes de routage. Par exemple, le nombre de machines est un des principaux (un algorithme d'inondation n'est envisageable que dans les petits réseaux). Or, un LowPAN peut aller de deux machines (cas de capteurs dans le corps humain, les Body Area Network) à des millions de machines (grande usine).
Et c'est à partir de la section 5 qu'on en arrive aux exigences explicites pour l'algorithme de routage. Elles sont numérotées Rn, de R1, à R18 mais, rassurez-vous, je ne les expliquerai pas toutes.
R1 est liée à la taille des machines du LowPAN. Elle exige un mécanisme de routage qui convienne à ces toutes petites machines. Par exemple, certaines auront si peu de mémoire qu'il faudra limiter la table de routage à 32 entrées. Le système de routage doit donc permettre de stocker une table partielle, ou fortement résumée (voir aussi R10). Pour donner une idée des contraintes, certaines machines auront entre 4 et 10 ko de mémoire vive, et seulement 48 à 128 ko de mémoire Flash, pour stocker le code du programme de routage. Un MICAz a 4ko/128ko, un TIP700CM 10ko/48ko. Il faudra donc des algorithmes simples, pour que le code tienne dans ces mémoires.
L'exigence R2 porte sur la consommation électrique : il faut un mécanisme qui la limite. Par exemple, un paquet de diffusion va potentiellement réveiller toutes les machines du lien, les forçant à traiter ce paquet. Il faut donc les éviter. Même si le temps de processeur est à économiser, il faut se rappeler que la principale cause de consommation d'électricité, de loin, est la radio. Celle du TR1000 consomme 21 mW en transmission et 15 mW en réception.
Le LowPAN fonctionnant sur 802.15.4, il doit tenir compte des caractéristiques de celui-ci. Par exemple, R3 demande que les paquets de contrôle du protocole de routage tiennent dans une seule trame 802.15.4 pour éviter toute fragmentation. D'autre part, 802.15.4 a des caractéristiques de taux de pertes et de latence qui peuvent éliminer certains algorithmes (R4 et R5 pour les détails).
Les machines d'un LowPAN étant typiquement peu fiables (déplacement, extinction, panne), les protocoles de routage doivent se préparer à trouver des routes alternatives (exigence R6). Le RFC demande moins de deux secondes de convergence si le destinataire d'un paquet s'est déplacé et seulement 0,5 seconde si seul l'expéditeur a bougé (voir aussi le RFC 5826).
Les liens radio ayant souvent des caractéristiques asymétriques, R7 demande que les protocoles de routage fonctionnent quand même dans ces conditions. Cela veut dire, par exemple, que le coût d'un lien doit être une paire {coût aller, coût retour}.
Chaque machine, dans un LowPAN, a droit à un sommeil fréquent (99 % de sommeil n'est pas impossible), pour économiser sa batterie (des capteurs industriels doivent parfois tenir cinq ans sans changement de batterie). R8 en tire les conséquences en rappelant que le routage doit marcher même si certains nœuds hibernent. Et le calcul des coûts de routage doit inclure celui de la consommation électrique (il faut éviter de choisir comme routeurs les machines limitées en énergie).
La taille des LowPAN variant considérablement, le protocole de routage doit marcher aussi bien pour un réseau urbain de plusieurs millions de machines (RFC 5548) que pour un réseau de 250 machines dans une maison (RFC 5826). Rappelez-vous les contraintes de taille mémoire : pas question de stocker une table de routage d'un million d'entrées en mémoire !
Les machines se déplacent, dans un LowPAN. Dans les environnements industriels, il faut que le réseau fonctionne malgré des déplacements jusqu'à 35 km/h (RFC 5673). Aujourd'hui, on en est loin mais, en tout cas, R12 exige des protocoles qui gèrent des réseaux qui changent, avec des machines qui bougent.
Et la sécurité, problème très crucial et très difficile pour les LoWPAN (un réseau sans-fil est toujours plus vulnérable) ? Non seulement un attaquant qui viserait le routage pourrait sérieusement perturber les communications entre les machines, mais il pourrait indirectement vider la batterie de certaines, réalisant ainsi une attaque par déni de service très efficace. L'exigence R14 impose donc aux protocoles de routage candidats de fournir des services de confidentialité, d'authentification et de vérification de l'intégrité des messages. C'est beaucoup, vous trouvez ? Et pourtant cela ne protège pas contre tout (par exemple contre une machine authentifiée, mais malveillante). De toute façon, il ne faut pas se faire d'illusion : compte-tenu du coût élevé (en processeur et donc en énergie électrique) de la plupart des techniques de sécurité (notamment de la cryptographie à clé publique), le routage des LowPAN restera très peu protégé. Le RFC n'espère qu'un compromis raisonnable (un peu de sécurité, si ça ne coûte pas trop cher).
Il semble donc, note le RFC, que cela exclut IPsec, alors qu'il serait une solution élégante au problème, car il est bien trop consommateur de ressources et trop compliqué du point de vue de la gestion des clés.
À noter que 802.15.4 dispose de mécanismes de sécurité propres. S'ils sont activés, des protocoles comme NDP deviennent relativement sûrs. (La section 6 est également à lire, si on s'intéresse à la sécurité.)
Enfin, après la sécurité, la gestion : le RFC 5706 impose de la prendre en compte dès la conception du protocole. L'exigence R18 demande donc que le futur protocole de routage des LowPAN soit gérable (test de l'état de la table de routage, compteurs d'erreurs, etc).
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : P. Hoffman (VPN Consortium), W. Wijngaards (NLnet Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 13 avril 2012
Le mécanisme de sécurité DNSSEC permet évidemment de choisir entre plusieurs algorithmes de signature cryptographique, à la fois pour pouvoir faire face aux progrès de la cryptanalyse et pour pouvoir choisir en fonction de critères particuliers (taille des clés, temps de signature et de vérification, etc). La palette de choix s'agrandit avec ce RFC qui normalise l'usage d'ECDSA, un algorithme à courbes elliptiques (le deuxième dans DNSSEC après le RFC 5933).
DNSSEC est normalisé dans le RFC 4033 et les suivants. Il permet d'authentifier les enregistrements DNS par une signature cryptographique et l'algorithme de loin le plus fréquent aujourd'hui est RSA, avec des clés de 1024 ou 2048 bits. Beaucoup de gens préfèrent les courbes elliptiques, décrites dans l'excellent RFC 6090. Notre RFC étend donc la liste des algorithmes disponibles à :
ECDSA est normalisé dans FIPS 186-3. Les paramètres des courbes sont pris dans le RFC 5114.
Les clés ECDSA et les signatures étant bien plus petites que celles de RSA, on peut espérer des économies sur la capacité réseau. Signer est également bien plus rapide avec ECDSA (20 fois plus dans certains tests). Par contre, vérifier les signatures est plus long (5 fois plus dans certains tests) et le processeur des résolveurs DNS validants va donc souffrir.
Au passage, notre RFC normalise aussi (section 2) l'utilisation de SHA-384 dans DNSSEC, ce qui n'avait pas été fait précédemment (mais n'a aucun rapport avec les courbes elliptiques). SHA-384 était déjà décrit dans le RFC 6234 et DNSSEC a juste eu à lui ajouter un numéro de code, 4. (La première personne qui voit un DS de numéro 4 dans la nature est priée de me le signaler, pour ma collection.)
La section 4 décrit les formats utilisés pour DNSSEC. Une clé publique ECDSA est juste une valeur, notée Q, qu'on met telle quelle dans l'enregistrement DNSKEY. La signature, elle, est faite de deux valeurs, r et s. On les concatène simplement avant de les mettre dans le RRSIG. Les codes enregistrés pour les deux nouveaux algorithmes sont 13 pour ECDSA Curve P-256 with SHA-256 et 14 pour ECDSA Curve P-384 with SHA-384. (Là encore, si quelqu'un en trouve dans la nature, je suis preneur...)
La section 6 fournit des exemples. Voici une clé et le DS correspondant, avec le premier algorithme (notez la petite taille par rapport aux DNSKEY RSA) :
example.net. 3600 IN DNSKEY 257 3 13 ( GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== ) example.net. 3600 IN DS 55648 13 2 ( b4c8c1fe2e7477127b27115656ad6256f424625bf5c1 e2770ce6d6e37df61d17 )
Et les signatures qui l'utilisent (également toutes petites) :
www.example.net. 3600 IN A 192.0.2.1 www.example.net. 3600 IN RRSIG A 13 3 3600 ( 20100909100439 20100812100439 55648 example.net. qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )
Question mises en œuvre, on notera
qu'OpenSSL, bibliothèque utilisée par de
nombreux programmes DNS, a ECDSA, avec nos deux courbes (au moins depuis la version 1.0.1,
celle que j'ai testée). C'est apparemment activé par défaut (il faut
faire un ./config no-ecdsa
pour ne
pas l'avoir). Voir le source dans
crypto/ecdsa
. Mais le code a été retiré de certains
systèmes (comme Fedora) en raison des
brevets, une infection fréquente pour les
courbes elliptiques.
Dans les serveurs de noms, le seul à gérer déjà ECDSA semble être PowerDNS. BIND ne semble pas avoir encore ECDSA (version 9.9, la dernière officiellement publiée). Même chose pour Unbound dans sa version 1.4.16, la dernière. nsd comprend ECDSA depuis la version 3.2.11, publiée en juillet 2012. Enfin, pour Go-DNS, c'est en cours de développement. Enfin, pour la bibliothèque ldns, ECDSA a été ajouté dans la version 1.6.13, sortie en mai 2012. Pour les autres, il va donc falloir patienter un peu. Notez que certains des registres de noms de domaine ont une liste limitative des algorithmes acceptés et que cette liste ne comprend pas forcément déjà ECDSA.
Si vous voulez regarder une zone signée avec ECDSA (c'est très rare), il y a ecdsa.isc.org
.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : Donald Eastlake 3rd (Huawei)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 14 avril 2012
Ce RFC est très court car il avait juste à répondre à une question simple : le DNS a des mécanismes (le plus connu est l'enregistrement CNAME) permettant à un nom de domaine de pointer vers un autre. Si, en suivant cette chaîne de noms, on rencontre une erreur, que doit indiquer le code de retour dans la réponse DNS ? Le résultat de la première requête de la chaîne ou bien celui de la dernière ? Le RFC tranche dans le sens de la grande majorité des résolveurs DNS actuels : le rcode doit être celui de la dernière requête de la chaîne.
C'est tout bête, mais ce cas n'était pas clairement spécifié dans les précédents RFC sur le DNS. Si on a par exemple, dans le DNS :
www.foobar.example. IN CNAME www.nothere.example.
Alors une requête AAAA www.foobar.example
rencontrera l'alias et le résolveur continuera en demandant
www.nothere.example
. Si www.nothere.example
n'existe pas,
alors qu'on a demandé de l'information sur
www.foobar.example
, le code de retour doit-il
être NXDOMAIN
(ce nom n'existe pas) ou bien
NOERROR
(on a bien trouvé un enregistrement, ici
le CNAME et
www.foobar.example
existe) ? Même chose avec
d'autres types d'enregistrement « alias » comme
DNAME. (CNAME redirige un nom, DNAME redirige
les noms situés en dessous de lui.) On parle alors de xNAME pour
désigner globalement tous les types « alias ». Notez bien que, quoique
cela soit déconseillé, il peut y avoir une chaine de plus de deux
xNAME.
Avant de voir le cas du code de retour (rcode dans la terminologie DNS, pour return code), la section 2 règle celui des bits de statut. Le bit AA (Authoritative Answer) est décrit dans le RFC 1035, section 4.1.1. Il indique que la réponse vient d'un serveur faisant autorité (pas d'un cache). Dans le cas d'une chaîne de xNAME, les AA peuvent être différents à chaque étape. Mais le RFC 1035 disait clairement que le bit dans la réponse était pour le premier nom mentionné dans la section Réponse du paquet. Rien ne change ici, la spécification était claire dès le début.
Le bit AD (Authentic Data) est plus récent. Normalisé dans le RFC 4035, section 3.2.3, il indique que la réponse est correctement signée avec DNSSEC. Là encore, la règle était claire dès le début : ce bit n'est mis que si toutes les réponses dans la section Réponse (et la section Autorité) sont authentiques.
Mais le vrai problème concerne le rcode (RFC 1035, section 4.1.1) car, là, le RFC original (voir aussi
RFC 1034, section 4.3.2 et bon courage pour le
comprendre) n'était pas
clair. Le RFC 2308, dans sa section 2.1, dit qu'il faut fixer
le code de retour en fonction de la dernière
étape de la chaîne, tout en notant que tous les serveurs ne le font pas.
La section 3 fixe donc des règles précises : lorsqu'on suit une
chaîne, les étapes intermédiaires n'ont pas
d'erreur. Il ne sert donc à rien d'indiquer le résultat de la
première étape. Le code de retour doit donc être
mis en fonction de la dernière étape uniquement. Dans
l'exemple plus haut, le résultat de la requête AAAA
www.foobar.example
doit donc être NXDOMAIN (domaine inexistant).
Voilà, vous pouvez arrêter la lecture ici, l'essentiel du RFC est le paragraphe précédent. Mais la section 4 apporte quelques détails sur la sécurité. Par exemple, elle rappelle que des bits comme AA ou AD ne sont pas protégés par DNSSEC. Un attaquant a donc pu les changer sans être détecté. Si on veut être sûr de leur intégrité, il faut protéger la communication avec le serveur, par exemple avec le TSIG du RFC 8945 (ou bien que le client ignore le bit AD et valide lui-même avec DNSSEC).
Si vous voulez tester vous-même que votre résolveur obéit bien aux
règles de ce RFC, vous pouvez tester avec
dangling-alias.bortzmeyer.fr
qui existe mais
pointe vers un nom qui n'existe pas. Vous devez donc obtenir un
NXDOMAIN, ce qui est le cas avec la plupart des résolveurs actuels (la
question de l'implémentation de ce RFC ne se pose pas, le RFC a pris
acte du comportement très majoritaire des logiciels).
Voici un exemple avec un résolveur correct (un Unbound) :
% dig AAAA dangling-alias.bortzmeyer.fr ... ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 45331 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 6, ADDITIONAL: 1
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : J. Weil (Time Warner Cable), V. Kuarsingh (Rogers Communications), C. Donley (CableLabs), C. Liljenstolpe (Telstra Corp), M. Azinger (Frontier Communications)
Première rédaction de cet article le 23 avril 2012
Après beaucoup de discussions pas toujours sereines,
l'IESG a finalement décidé de publier ce très
controversé RFC. Il réserve un préfixe
IPv4, 100.64.0.0/10
, aux
services de partage d'adresses IP entre utilisateurs, les
CGN (Carrier-Grade NAT). Ce
faisant, il légitime ce concept de CGN, ce qui a déclenché la colère
de beaucoup.
Voyons d'abord le paysage : les adresses IPv4 sont à peu près épuisées. Mais le déploiement d'IPv6 a pris beaucoup de retard et il n'est pas, à l'heure actuelle, prêt à prendre le relais. Plusieurs FAI, notamment en Asie, ont donc commencé à déployer des systèmes où l'abonné de base n'a aucune adresse IPv4 publique. Avant cela, M. Toutlemonde n'avait certes qu'une seule adresse publique et devait faire du NAT pour donner à toutes ses machines une connectivité Internet partielle. Mais, au moins, le partage d'adresses ne se faisait qu'entre habitants du même foyer, Aujourd'hui, par manque d'adresses IPv4, les déploiements en cours repoussent le NAT dans le réseau de l'opérateur (d'où le nom de CGN, Carrier-Grade NAT, voir par exemple le RFC 6264 ou bien le RFC 6888) et le partage d'adresses publiques se fait désormais entre abonnés n'ayant rien en commun. Désormais, si votre voisin télécharge illégalement, c'est peut-être sur vous que l'HADOPI tombera...
Le partage d'adresses (documenté dans le RFC 6269) n'est pas le seul inconvénient des CGN. Ces gros routeurs NAT, gardant en mémoire l'état des flux pour des centaines ou des milliers d'abonnés, diminuent la résistance aux pannes : si on redémarre l'un d'eux, tous les abonnés perdent leurs sessions en cours. Voilà pourquoi l'idée même de CGN (qui met de l'« intelligence » dans le réseau et non pas aux extrémités) hérisse tant de gens à l'IETF.
Si on fait quand même des CGN, se pose le problème de la
numérotation des réseaux. Le réseau local de l'abonné (appelons-le
M. Li car les CGN pour des accès Internet fixe sont aujourd'hui
surtout répandus en Chine) est typiquement
numéroté avec le RFC 1918. L'opérateur ne peut
pas utiliser les adresses de ce même RFC pour son réseau, entre M. Li
et le gros CGN, à cause du risque de conflit avec le réseau local de
M. Li (sauf si l'opérateur contrôle ledit réseau, via ses
boxes). Il ne peut pas
utiliser des adresses IP publiques puisque, c'est le point de départ
de toute l'histoire, celles-ci manquent. Il faut donc un « nouveau
RFC 1918 ». C'est le rôle de ce RFC 6598, qui réserve un nouveau préfixe,
100.64.0.0/10
, à cet usage. Il s'ajoute aux
autres préfixes « spéciaux » du RFC 6890. Il servira aux
machines entre le CPE (la
box) et le routeur CGN et ne sera donc typiquement
jamais vu sur l'Internet. À noter que ce
préfixe n'a rien de particulier, à part son usage officiel : on
pourrait parfaitement s'en servir pour autre chose que du CGN.
Voici le nouveau préfixe, vu avec whois :
% whois 100.64.0.0 NetRange: 100.64.0.0 - 100.127.255.255 CIDR: 100.64.0.0/10 OriginAS: NetName: SHARED-ADDRESS-SPACE-RFCTBD-IANA-RESERVED NetHandle: NET-100-64-0-0-1 Parent: NET-100-0-0-0-0 NetType: IANA Special Use RegDate: 2012-03-13 Updated: 2012-03-15
Ah, pourquoi une longueur de 10 à ce préfixe ? Un préfixe plus court (comme un /8) aurait été difficile à trouver de nos jours, et un plus long (par exemple un /12), offrant moins d'adresses, aurait obligé les FAI, dans certaines régions très peuplées, à déployer des CGN emboités... Un /10, par exemple, suffit à desservir toute l'agglomération de Tokyo (un FAI japonais ne peut donc pas avoir un seul routeur CGN pour tous le pays).
La section 4 du RFC précise l'usage attendu : chaque FAI utilisera
librement 100.64.0.0/10
et ce préfixe n'aura donc
de signification que locale. Les adresses
100.64.0.0/10
ne doivent pas
sortir sur l'Internet public (le mieux est de les filtrer en sortie
et, pour les autres FAI, en entrée, car il y aura toujours des
négligents). Ces adresses ne doivent pas non plus apparaître dans le
DNS public. Les requêtes DNS de type
PTR pour ces adresses ne doivent
pas être transmises aux serveurs DNS globaux,
comme celles pour les adresses du RFC 1918,
elles doivent être traitées par les serveurs du FAI (cf. le RFC 7793). Comme pour le
RFC 1918, c'est sans doute un vœu pieux,
et il faudra sans doute que l'AS112 (voir le RFC 7534) prenne en charge ces requêtes.
La section 3 décrit plus en détail les alternatives qui avaient été envisagées et les raisons de leur rejet. La solution la plus propre aurait évidemment été d'utiliser des adresses IPv4 globales, attribuées légitimement au FAI. Mais l'épuisement d'IPv4 rend cette solution irréaliste. Déjà, extraire un /10 des réserves n'a pas été facile.
La solution qui est probablement la plus utilisée à l'heure actuelle est celle d'utiliser un préfixe IPv4 usurpé, en se disant « de toute façon, ces adresses ne sortiront jamais sur l'Internet donc quel est le problème ? » Se servir sans demander est certainement plus rationnel, économiquement parlant, que de supplier la bureaucratie d'un RIR pour avoir des adresses. Autrefois, les FAI qui numérotaient ainsi leur réseau interne se servaient de préfixes non alloués (provoquant pas mal d'accidents au fur et à mesure de leur allocation ; même s'il n'y a pas de fuite de ces adresses, les abonnés du FAI peuvent être dans l'impossibilité de communiquer avec le détenteur légitime). Aujourd'hui, ils regardent quels sont les préfixes alloués mais non routés et les utilisent. Inutile de dire que le RFC condamne cette pratique incivique.
Le RFC 1918 n'est, on l'a vu, possible que si le FAI contrôle complètement le réseau local de M. Li et sait donc quels préfixes sont utilisés sur celui-ci, et peut ainsi choisir des préfixes qui ne rentrent pas en collision. (Cela peut aussi marcher si la box sait bien se débrouiller lorsque le même préfixe est utilisé en interne et en externe, ce qui est le cas de certaines.)
Bref, l'allocation d'un nouveau préfixe semblait la seule solution raisonnable.
La section 5 du RFC est consacrée à une longue mise en garde sur
les dangers associés aux CGN. Certaines applications peuvent avoir des
mécanismes pour découvrir l'adresse externe de la machine sur laquelle
l'application tourne (l'adresse qu'on verra sur l'Internet) et,
ensuite, faire des choses comme de demander à un pair d'envoyer des
données à cette adresse. Avec le CGN, cela a encore moins de chances
de marcher que d'habitude car les applications actuelles ne
connaissent pas encore 100.64.0.0/10
et
considéreront que ces adresses sont globalement utilisables.
Parmi les applications qui ont de fortes chances de mal marcher
dans le contexte du CGN, citons les jeux en ligne (si deux abonnés
essaient de se connecter alors qu'ils sont derrière le même CGN et ont
la même adresse publique), le pair-à-pair, et
bien sûr les applications de téléphonie avec
SIP, la géo-localisation (le CGN sera trouvé,
pas la vraie machine), certaines applications Web qui restreignent les
connexions simultanées en provenance de la même adresse IP, etc. Pour
les applications de type pair-à-pair (échange de fichier, SIP), les
techniques habituelles d'ouverture manuelle d'un
port sur le routeur (« tout ce qui est envoyé
au port 4554, transmets le à 10.4.135.21
») ne
marchent pas avec le CGN, l'utilisateur résidentiel n'ayant
typiquement pas de moyen de configurer le routeur CGN.
Enfin, quelques bons conseils de sécurité forment la section 6 : ne
pas accepter les annonces de route pour
100.64.0.0/10
à l'entrée d'un site, les paquets
depuis ou vers ces adresses ne doivent pas franchir les frontières
d'un opérateur, etc.
Voilà, comme indiqué, cela ne s'était pas passé tout seul et l'IESG avait même dû faire une longue note détaillant le pourquoi de sa décision et expliquant que, certes, il n'y avait pas de consensus en faveur de ce projet mais qu'il n'y avait pas non plus de consensus contre. L'argument « pour » était :
Les arguments contre étaient :
Pour d'autres articles sur ce sujet, voir celui sur le bon blog de Chris Grundemann (en anglais) ou bien celui de Jérôme Durand (en français).
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : M. Ohye, J. Kupke
Pour information
Première rédaction de cet article le 9 avril 2012
Depuis le RFC 5988, il existe un mécanisme
standard pour exprimer les types des liens entre deux ressources sur le
Web. Ce très court RFC
spécifie un nouveau type de lien, canonical
, qui
permet d'indiquer quel est l'URI
canonique
d'une ressource Web.
Le but de ces liens est de permettre d'exprimer l'idée « Quel que soit l'URI que vous avez utilisé pour arriver sur cette ressource, sachez que l'URI canonique, la référence, est celui indiqué par ce lien. » Cela permet notamment à un moteur de recherche de n'indexer les ressources que sous l'URI canonique (au cas où du contenu soit dupliqué sous plusieurs URI). Cela permet également à un navigateur de ne mémoriser que l'URI canonique, sans d'éventuels paramètres (options d'affichage, identificateurs de session et autres trucs qui viennent souvent polluer les URI).
L'auteur qui place un lien canonical
doit donc
veiller à ce que l'URI canonique désigne bien une ressource qui mérite
ce titre (identique à la ressource de départ, ou un sur-ensemble de
celle-ci, ce dernier cas est explicitement autorisé par le RFC). Voir
la section 5 qui donne de bons conseils aux auteurs.
Par contre, l'URI canonique ne doit notamment pas :
La section 4 donne des exemples concrets. Si la version canonique
d'une ressource est désignée par l'URI
http://www.example.com/page.php?item=purse
, alors
les URI
http://www.example.com/page.php?item=purse&category=bags
ou
http://www.example.com/page.php?item=purse&category=bags&sid=1234
qui sont des URI possibles de la même ressource peuvent indiquer
http://www.example.com/page.php?item=purse
comme
canonique.
Pour cela, deux techniques, le classique lien
HTML avec l'attribut rel
:
<link rel="canonical" href="http://www.example.com/page.php?item=purse">
Il est également utilisable en version relative :
<link rel="canonical" href="page.php?item=purse">
Et la deuxième technique (pratique notamment pour les ressources qui ne sont pas en HTML, une image, par exemple), l'en-tête HTTP (section 3 du RFC 8288) :
Link: <http://www.example.com/page.php?item=purse>; rel="canonical"
Pour prendre un exemple réel, si on demande à
Wikipédia (qui fait face à des homonymies
nombreuses) l'URL http://fr.wikipedia.org/wiki/M%C3%A9lenchon
, on est redirigé
vers la page sur Jean-Luc Mélenchon qui
contient :
<link rel="canonical" href="/wiki/Jean-Luc_M%C3%A9lenchon" />
qui indique que la page canonique est celle avec le nom complet.
Le nouveau type canonical
est désormais enregistré à l'IANA.
Petit avertissement de sécurité (section 7). Si une ressource est modifiée par un attaquant, il peut mettre un lien vers un URI canonique de son choix. Bien sûr, il pourrait aussi massacrer complètement la ressource. Mais le changement d'URI canonique est discret et risquerait de ne pas être noté par un humain, alors même que certaines implémentations en tiendraient compte, par exemple pour apport du trafic à l'URI de l'attaquant.
Qui gère aujourd'hui ce type de liens ? Chez les moteurs de recherche, Google le fait (voir leurs articles « Specify your canonical », « Supporting rel="canonical" HTTP Headers », l'article de conseils pratiques « About rel="canonical" » et enfin « Handling legitimate cross-domain content duplication »). Pareil chez Yahoo (« Fighting Duplication: Adding more arrows to your quiver ») et Bing (« Partnering to help solve duplicate content issues »). Par contre, je ne sais pas si les sites de bookmarking comme del.icio.us ou SeenThis font ce travail de canonicalisation.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : H. Fontana
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 13 avril 2012
Le format ARF, normalisé dans le RFC 5965, permet d'envoyer des rapports structurés (analysables par un programme) à propos d'un message électronique abusif, spam ou hameçonnage, par exemple. Ce RFC 6591 spécifie une extension à ARF pour le cas où le problème avec le message est un échec d'un mécanisme d'authentification. On peut ainsi prévenir l'émetteur que quelqu'un essaie d'usurper son identité ou, plus fréquemment aujourd'hui, qu'il y a une erreur dans la configuration de ses mécanismes d'authentification.
Par exemple, si le message est authentifié par
SPF (RFC 7208 et RFC 6652), il arrive
assez souvent que l'émetteur se mette à utiliser un
MTA non prévu et non listé dans
l'enregistrement SPF. Si ce dernier se termine par un
-all
, l'usage de ce MTA va se traduire par une
erreur d'authentification. L'extension ARF décrite ici permettra de
transmettre un rapport à l'émetteur, pour qu'il corrige.
L'extension consiste en un nouveau type de rapport ARF,
auth-failure
(section 3.1), rejoignant les
rapports existants (comme
abuse
ou fraud
). Un rapport
de ce type va comporter, dans sa seconde partie (celle qui est
structurée, la première étant en langue naturelle et la troisième
étant le message original), les champs suivants. À noter que certains étaient déjà définis
par le RFC 5965 mais peuvent avoir des exigences
différentes ici (par exemple, être obligatoires pour les rapports
auth-failure
alors qu'ils étaient optionnels pour
les autres). Les nouveaux sont désormais dans le
registre IANA. Commençons par les champs obligatoires :
Auth-failure:
Nouveauté de ce RFC, il
indique en un mot la raison de l'échec. Les valeurs possibles sont
adsp
(cf. RFC 5617),
bodyhash
(le condensat
cryptographique du corps du message ne correspond pas à la
signature), revoked
(signature
DKIM expirée), signature
(signature DKIM invalide, cf. RFC 6651), spf
(échec SPF, RFC 6652).Authentication-Results:
Normalisé dans le
RFC 7001, il indique les paramètres
d'authentification et les raisons de l'échec.Reported-Domain:
Le nom de domaine annoncé par l'expéditeur.D'autres champs sont recommandés ou simplement optionnels :
Original-Envelope-Id:
Un identifiant unique
pour la transaction SMTP (cf. section 2.2.1 du RFC 3464)Original-Mail-From:
Source-IP:
Delivery-Result:
Ce dernier indique la
décision qui a été prise après l'échec de l'authentification (jeter le
message, le distribuer quand même, etc)
Il peut en outre y avoir des champs spécifiques à certaines techniques
d'authentification. Par exemple, pour DKIM
(RFC 6376), les champs
DKIM-Domain:
, DKIM-Identity:
et DKIM-Selector:
ou pour SPF le champ
SPF-DNS:
..
Voici un exemple (annexe B du RFC) de rapport ARF sur un échec d'authentification DKIM, par suite d'une incohérence entre le contenu effectif et ce qu'indiquait la signature :
Message-ID: <433689.81121.example@mta.mail.receiver.example> From: "SomeISP Antispam Feedback" <feedback@mail.receiver.example> To: arf-failure@sender.example Subject: FW: You have a new bill from your bank Date: Sat, 8 Oct 2011 15:15:59 -0500 (CDT) MIME-Version: 1.0 Content-Type: multipart/report; boundary="------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg"; report-type=feedback-report Content-Transfer-Encoding: 7bit --------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline Content-Transfer-Encoding: 7bit This is an authentication failure report for an email message received from a.sender.example on 8 Oct 2011 20:15:58 +0000 (GMT). For more information about this format please see [this memo]. --------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg Content-Type: message/feedback-report Content-Transfer-Encoding: 7bit Feedback-Type: auth-failure User-Agent: Someisp!Mail-Feedback/1.0 Version: 1 Original-Mail-From: anexample.reply@a.sender.example Original-Envelope-Id: o3F52gxO029144 Authentication-Results: mta1011.mail.tp2.receiver.example; dkim=fail (bodyhash) header.d=sender.example Auth-Failure: bodyhash DKIM-Canonicalized-Body: VGhpcyBpcyBhIG1lc3NhZ2UgYm9keSB0 aGF0IGdvdCBtb2RpZmllZCBpbiB0cmFuc2l0LgoKQXQgdGhlIHNhbWU ... DKIM-Domain: sender.example DKIM-Identity: @sender.example DKIM-Selector: testkey Arrival-Date: 8 Oct 2011 20:15:58 +0000 (GMT) Source-IP: 192.0.2.1 Reported-Domain: a.sender.example Reported-URI: http://www.sender.example/ --------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg Content-Type: text/rfc822-headers Content-Transfer-Encoding: 7bit Authentication-Results: mta1011.mail.tp2.receiver.example; dkim=fail (bodyhash) header.d=sender.example; spf=pass smtp.mailfrom=anexample.reply@a.sender.example Received: from smtp-out.sender.example by mta1011.mail.tp2.receiver.example with SMTP id oB85W8xV000169; Sat, 08 Oct 2011 13:15:58 -0700 (PDT) DKIM-Signature: v=1; c=relaxed/simple; a=rsa-sha256; s=testkey; d=sender.example; h=From:To:Subject:Date; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqOB 4nujc7YopdG5dWLSdNg6xNAZpOPr+kHxt1IrE+NahM6L/LbvaHut KVdkLLkpVaVVQPzeRDI009SO2Il5Lu7rDNH6mZckBdrIx0orEtZV 4bmp/YzhwvcubU4= Received: from mail.sender.example by smtp-out.sender.example with SMTP id o3F52gxO029144; Sat, 08 Oct 2011 13:15:31 -0700 (PDT) Received: from internal-client-001.sender.example by mail.sender.example with SMTP id o3F3BwdY028431; Sat, 08 Oct 2011 13:15:24 -0700 (PDT) Date: Sat, 8 Oct 2011 16:15:24 -0400 (EDT) Reply-To: anexample.reply@a.sender.example From: anexample@a.sender.example To: someuser@receiver.example Subject: You have a new bill from your bank Message-ID: <87913910.1318094604546@out.sender.example> --------------Boundary-00=_3BCR4Y7kX93yP9uUPRhg--
Le but de l'authentification du courrier électronique étant d'améliorer la sécurité, il n'est pas étonnant que la section 6, considérée aux problèmes de sécurité, soit particulièrement détaillée. Quelques points à garder en tête, donc. Par exemple, les rapports ARF eux-même peuvent être des faux. Il ne faut agir de manière automatique sur un de ces rapports que s'ils ont été authentifiés d'une manière ou d'une autre. Ensuite, générer automatiquement des rapports ARF peut ouvrir une voie à l'attaque par déni de service : un méchant pourrait envoyer plein de messages délibèrement faux, pour déclencher l'émission massive de rapports ARF.
Il existe apparemment déjà au moins un générateur d'ARF qui gère cette extension. PayPal et Hotmail ont déjà annoncé leur intention de l'utiliser.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : J. Falk (Return Path), 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 8 avril 2012
Il est fréquent qu'un message électronique contienne de l'information sensible ou personnelle, ne serait-ce que le nom des parties qui communiquent. Si ce message doit être transmis, comme faisant partie d'un rapport de problème, cette information doit être protégée. Ce RFC décrit un cadre général pour la retouche des messages. Le terme de « retouche » désigne l'opération d'occultation des parties confidentielles (notez que le redaction de l'original en anglais est un faux-ami, il ne signifie pas « rédaction »).
Le format ARF est normalisé dans le RFC 5965. Ce format standard permet de transmettre un rapport structuré (donc analysable automatiquement, par un programme) indiquant du spam, du hameçonnage ou tout autre abus. ARF permet également d'inclure dans le rapport le message qui a déclenché le processus de plainte. Mais ce message peut contenir des informations confidentielles, qu'on ne souhaite pas partager avec un tiers (sans compter les obligations légales comme, en France, la loi Informatique & Libertés). Le message est donc parfois retouché (redacted dans la langue de Katy Perry) avant d'être transmis. La section 8.5 du RFC 5965 décourage plutôt cette pratique (l'information occultée était peut-être nécessaire à la compréhension du rapport) mais cette approche « au diable la vie privée, la fin justifie les moyens » est très contestée et ce RFC 6590 adopte une vue plus raisonnable. L'occultation est désormais considérée comme justifiée.
L'important est donc plutôt de donner des conseils pratiques. Il y
a des bonnes et des mauvaises façons d'occulter. Ainsi, remplacer
toutes les parties locales des adresses
(stephane+blog
dans mon adresse
stephane+blog@bortzmeyer.org
) par la même chaîne
de caractères (mettons xxxxx@bortzmeyer.org
) fait
perdre beaucoup d'information : on ne sait plus si deux rapports
concernent le même utilisateur.
La section 3 de notre RFC conseille donc plutôt :
En appliquant ces règles, on a partiellement anonymisé le rapport, tout en permettant l'identification de tendances (par exemple, que le spam est plus souvent envoyé à certains utilisateurs).
Mais quelle opération de transformation utiliser ? Après la section 3 qui posait les principes, la section 4 s'occupe de technique. Ce RFC ne normalise pas une opération de transformation particulière. Si ROT13, qui est réversible, ne devrait pas être utilisé, les méthodes possibles incluent un hachage cryptographique (comme dans le RFC 2104) ou le remplacement des noms par un identifiant interne (numéro de client, par exemple).
Voici l'exemple qui figure dans l'annexe A du RFC. Le message de spam originel était :
From: alice@example.com To: bob@example.net Subject: Make money fast! Message-ID: <123456789@mailer.example.com> Date: Thu, 17 Nov 2011 22:19:40 -0500 Want to make a lot of money really fast? Check it out! http://www.example.com/scam/0xd0d0cafe
Ici, le récepteur, le FAI
example.net
est furieux et veut transmettre un
rapport à example.com
pour lui demander de faire
cesser ces spams. example.net
va occulter le nom
du destinataire (son client), avec SHA-1 et la
clé potatoes
, qui sera concaténé au nom avant
hachage, le résultat étant encodé en
Base64. Cela donnera :
% echo -n potatoesbob | openssl sha1 -binary | openssl base64 -e rZ8cqXWGiKHzhz1MsFRGTysHia4=
On va pouvoir alors construire un rapport ARF incluant :
From: alice@example.com To: rZ8cqXWGiKHzhz1MsFRGTysHia4=@example.net Subject: Make money fast! Message-ID: <123456789@mailer.example.com> Date: Thu, 17 Nov 2011 22:19:40 -0500 Want to make a lot of money really fast? Check it out! http://www.example.com/scam/0xd0d0cafe
Attention, en pratique, il existe pas mal de pièges. Par exemple,
comme le note la section 5.3, l'information confidentielle peut se
trouver aussi à d'autres endroits et des techniques de corrélation
peuvent permettre de retrouver l'information occultée. Globalement,
les messages retouchés selon ce RFC ne fourniront
pas une forte confidentialité. Ainsi, le champ
Message-ID:
peut permettre, en examinant le
journal du serveur de
messagerie (celui de example.com
dans
l'exemple précédent), de retrouver
émetteur et destinataire. C'est pour cette raison que le RFC n'impose
pas l'usage de la cryptographie : elle
n'apporterait pas grand'chose en sécurité.
Même chose pour les informations non structurées, par exemple le texte du message : il peut contenir des indications permettant de remplir les cases occultées (section 6).
D'une manière générale, il faut garder en mémoire qu'il existe de puissantes techniques de désanonymisation comme illustré par exemple par les articles « A Practical Attack to De-Anonymize Social Network Users » de Gilbert Wondracek, Thorsten Holz, Engin Kirda et Christopher Kruegel ou bien « Robust De-anonymization of Large Sparse Datasets » de Arvind Narayanan et Vitaly Shmatikov.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : J. Livingood (Comcast)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 23 avril 2012
Ce document rassemble un certain nombre d'analyses et de conseils sur la transition vers IPv6 pour les gens qui hébergent du contenu, typiquement les sites Web. Les gérants de ces sites souhaiteraient pouvoir rendre ce contenu accessible en IPv6, sans que cela entraîne de conséquences fâcheuses pour les lecteurs. Ce RFC décrit notamment la technique du whitelisting, qui consiste à ne renvoyer d'adresses IPv6 (les enregistrements AAAA du DNS) qu'à certains réseaux, identifiés comme mettant en œuvre correctement IPv6. Cette technique a été popularisée par Google mais elle est contestée. Le RFC estime qu'elle est acceptable et qu'il est utile d'informer, non pas les sites qui la pratiquent (ils connaissent déjà) mais la communauté Internet en général.
Bien sûr, ce RFC peut être utile à d'autres qu'aux gérants de sites Web. Mais il se focalise particulièrement sur leurs besoins. Un site Web se caractérise par un gros déséquilibre : au lieu de deux pairs qui veulent communiquer, on a un fournisseur de contenu, et des clients passifs, à qui on ne peut pas demander d'effectuer des réglages particuliers. Ça doit marcher, point. En outre, les sites Web à plus fort trafic sont souvent des entreprises commerciales, qui ne veulent pas prendre de risques et n'acceptent pas même un très faible pourcentage de clients pénalisés par IPv6.
Le but est donc de migrer de gros sites Web uniquement accessible en IPv4 (la grande majorité des gros sites Web à l'heure actuelle, la principale exception étant Google) vers un accès possible en IPv4 (protocole qui ne va pas disparaître de si tôt) et IPv6.
Mais quels sont les problèmes qu'IPv6 pourrait causer ? Le site Web
typique publie son adresse dans le DNS. Pour
l'adresse IPv4, il utilise un enregistrement de
type A. Pour IPv6, de type AAAA. Ainsi, aujourd'hui,
www.bortzmeyer.org
annonce deux AAAA et un A :
% dig A www.bortzmeyer.org ... ;; ANSWER SECTION: www.bortzmeyer.org. 42641 IN A 204.62.14.153 ... % dig AAAA www.bortzmeyer.org ... ;; ANSWER SECTION: www.bortzmeyer.org. 10222 IN AAAA 2605:4500:2:245b::bad:dcaf www.bortzmeyer.org. 10222 IN AAAA 2001:4b98:dc0:41:216:3eff:fece:1902 ...
Par contre, la très grande majorité des sites Web ne publient que des
A, par exemple www.gouvernement.fr
:
% dig A www.gouvernement.fr ... ;; ANSWER SECTION: www.gouvernement.fr. 86383 IN CNAME www.premier-ministre.gouv.fr. www.premier-ministre.gouv.fr. 86383 IN CNAME cdn2.cdn-tech.com.c.footprint.net. cdn2.cdn-tech.com.c.footprint.net. 213 IN A 209.84.9.126 ... % dig AAAA www.gouvernement.fr ... ;; ANSWER SECTION: www.gouvernement.fr. 86358 IN CNAME www.premier-ministre.gouv.fr. www.premier-ministre.gouv.fr. 86358 IN CNAME cdn2.cdn-tech.com.c.footprint.net. ...
Certains de ces sites sont simplement gérés par des incompétents ou des paresseux, qui ne peuvent pas ou n'envisagent pas de publier des enregistrements AAAA, qui permettraient à leur lecteurs d'accéder au contenu en IPv6. Mais, dans d'autres cas, l'administrateur du site Web connaît IPv6, a refléchi, et a décidé de ne pas publier le AAAA. Pourquoi ? Parce qu'il craint le problème du malheur des globes oculaires (eyeball misery ?). J'ai décrit ce problème dans un autre article et il fait en outre l'objet de deux autres RFC, les RFC 6555 et RFC 6556. En deux mots, le malheur des globes oculaires peut venir d'une connexion IPv6 cassée, ou simplement de qualité très inférieure. Si le site Web ne publie pas d'enregistrement AAAA, le client ne tentera pas de se connecter en IPv6 et sa connexion pourrie n'aura donc pas de conséquences négatives. Mais dès que le site Web publie son AAAA, patatras, l'expérience utilisateur se dégrade sérieusement et le pauvre client doit supporter des délais, voire des pannes.
Le problème n'arriverait pas si les administrateurs réseaux prenaient autant soin de la connexion IPv6 que de l'IPv4 mais ce n'est pas toujours le cas en pratique : quand un des deux protocoles marche nettement moins bien que l'autre, aujourd'hui, c'est presque toujours IPv6. Logiciels moins testés, surveillance moins sérieuse, moindre réactivité lors des pannes, sont la triste réalité d'IPv6 chez beaucoup d'opérateurs réseaux. Un autre problème est quantitatif : certaines bogues ne se déclenchent qu'à partir d'une certaine quantité de trafic et les tests en laboratoire ne les détectent donc pas. Si un gros site Web très populaire publie tout à coup des enregistrements AAAA, on peut imaginer que l'augmentation de trafic résultante plante des équipements réseaux qui marchaient l'instant d'avant. Ou, tout simplement, dépasse leur capacité (section 2.3 de notre RFC). Prenons l'exemple d'un FAI qui déploie 6rd (RFC 5969) et le fait tourner sur trois vieux PC avec Linux (le noyau Linux a désormais 6rd en standard), cela peut marcher très bien tant que les utilisateurs font un peu de ping6 et traceroute6, et ne pas suffire si tout à coup YouTube devient accessible en IPv6.
Bien sûr, tous les sites Web ne sont pas logés à la même enseigne,
car ils n'ont pas tous le même public. http://www.ietf.org/
a un AAAA depuis très longtemps, sans
problèmes. Mais son public, les gens qui suivent le travail de
l'IETF, ne ressemble pas à celui de
TF1 : il est nettement plus soucieux de la
qualité de sa connexion et s'assure qu'elle marche en v4 et en
v6. D'autres sites Web qui ont un public moins
geek ne veulent pas prendre
le moindre risque.
Quelle est l'ampleur de ce risque ? Quelques organisations ont fait des études sur le malheur des globes oculaires et trouvent jusqu'à 0,078 % de malheureux. C'est évidemment très peu mais cela fait encore trop de monde pour un gros site Web qui a des millions de visiteurs. (Voir les études « IPv6 & recursive resolvers: How do we make the transition less painful? », « Yahoo proposes 'really ugly hack' to DNS », « Evaluating IPv6 adoption in the Internet » et « Measuring and Combating IPv6 Brokenness ».) Le risque est donc jugé inacceptable par beaucoup de gérants de gros sites Web.
Bref, il faut trouver une solution. Sinon, le risque est que les gérants de sites Web les plus timides retardent éternellement la migration vers IPv6.
Alors, quelles sont les solutions possibles (section 4) ? Comme
avec toutes les techniques de migration vers IPv6, il ne faut pas les
appliquer toutes bêtement. Chacune a ses avantages et ses
inconvénients et le choix de la meilleure technique dépend des
caractéristiques du site Web qui veut se rendre accessible en
v6. Première méthode, la plus satisfaisante techniquement, est de
résoudre le problème à la source en s'assurant que tous les clients du
site aient un IPv6 qui marche bien. C'est ainsi que cela fonctionne
pour les sites Web qui visent un public technique, comme http://www.ietf.org/
: les problèmes sont
discutés et résolus collecivement. C'est en effet la meilleure
solution sauf qu'elle est souvent impossible : au contraire de ce qui
se passe pour le site Web interne à une organisation, le site Web
public typique n'a pas de
contrôle sur la connectivité de ses clients, ni sur le logiciel
utilisé (navigateur Web, par exemple). Toutefois, s'il s'agit d'un
gros site très populaire, il peut influencer les utilisateurs en
recommandant ou en déconseillant des logiciels, des FAI, ou des
configurations, par exemple via une page Web d'aide sur le site.
Comme le problème, par exemple d'un FAI donné, a des chances de toucher tous les gros sites qui servent du contenu, ceux-ci peuvent aussi se coordonner pour faire pression sur le maillon faible. Ce genre de coordinations entre acteurs différents n'est jamais facile mais elle a eu lieu pour le World IPv6 Day . En deux mots, celle approche du problème est possible mais sans doute insuffisante.
Deuxième tactique possible, avoir des noms de domaine spécifiques à IPv6 (section
4.2). Par exemple, à la date d'écriture de cet article,
Facebook n'a pas d'enregistrement AAAA pour
www.facebook.com
(attention, cela dépend du résolveur qui demande, pour les raisons expliquées plus loin) mais il en a un
pour www.v6.facebook.com
. Ainsi, l'utilisateur
naïf ne risque pas d'avoir des problèmes IPv6 mais l'utilisateur plus
tenté par la technique pourra essayer l'accès en IPv6 et aider au
débogage initial. Cela permet une transition progressive, au lieu
d'ouvrir les vannes en grand d'un coup. Et cela permet de tester la
connectivité v6 du site, celle de certains de ses clients,
d'introduire IPv6 en production (si le nom en question bénéficie de la
même surveillance et des mêmes exigences de qualité de service que les
noms classiques).
Mais cette méthode ne permet pas d'aller très loin : comme il faut une action consciente de l'utilisateur pour se connecter en IPv6, le trafic restera très limité. Comme la population de testeurs n'est pas représentative, les logiciels ou FAI qui sont peu utilisés par les utilisateurs geeks ne seront pas réellement testés. Cette technique ne peut donc convenir qu'au tout début de la migration.
Une autre méthode, qui a été mise au point et popularisée par Google, et qui est la plus détaillée dans ce RFC, est le whitelisting (section 4.3). Il s'agit de configurer les serveurs DNS faisant autorité pour le domaine, afin de ne renvoyer d'enregistrements AAAA qu'aux clients dont on sait qu'ils ont de l'IPv6 correct, et qui ont été placés sur une liste blanche, indiquant les réseaux jugés corrects. Notez bien que la liste indique des réseaux, pas des machines individuelles. Non seulement il serait humainement impossible de gérer une liste de machines, mais en outre le serveur DNS faisant autorité ne voit pas la machine individuelle, il est interrogé par les résolveurs, typiquement des machines du FAI.
Cette technique ressemble donc à celle de certains systèmes de load-balancing ou de CDN (cf. sections 4.3.2 et 4.3.3, ainsi que le RFC 1794), qui eux-aussi renvoient une réponse DNS différente selon le client. Cela évoque donc aussi le split DNS (section 4.3.4) décrit dans la section 3.8 du RFC 2775. Le split DNS (conçu à l'origine pour renvoyer des réponses différentes au client du réseau local, par exemple des adresses RFC 1918) a toujours été très contesté. Les objections des sections 2.1 et 2.7 du RFC 2956 concernent surtout le fait que le FQDN n'est plus un identificateur stable, si la résolution DNS dépend du client. Cette fragmentation de l'espace de nommage est la principale raison pour laquelle beaucoup de gens n'aiment pas le whitelisting.
Déployé par Google, le whitelisting est documenté dans l'article de C. Marsan « Google, Microsoft, Netflix in talks to create shared list of IPv6 users » et dans celui de E. Kline « IPv6 Whitelist Operations ». Son principe est donc « plutôt que de résoudre le problème, masquons-le ».
Voici le whitelisting en action : je demande
l'adresse IPv6 de google.com
depuis
Free, qui est whitelisté.
% dig AAAA google.com ... ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ... ;; ANSWER SECTION: google.com. 300 IN AAAA 2a00:1450:4007:802::1005
Par contre, depuis Orange, on n'a pas de réponse.
% dig AAAA google.com ... ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ...
Notez bien que le whitelisting est complètement indépendant du protocole utilisé pour le transport de la requête DNS. Le fait que le résolveur utilise IPv4 ou IPv6 pour interroger le serveur faisant autorité n'implique rien quant aux capacités v4 ou v6 de la machine cliente (celle sur laquelle tourne le navigateur Web). La liste blanche contient donc aussi bien des adresses IPv4 qu'IPv6.
Par définition, le fait d'être dans la liste blanche nécessite une évaluation du réseau client. Sa maintenance est donc non triviale et consomme des ressources humaines, nécessite des mesures, etc. Google peut se le permettre, mais ce n'est pas accessible à tout le monde.
Notez que cette technique nécessite d'avoir le contrôle de tous les serveurs faisant autorité sur le domaine, y compris les secondaires. Et qu'elle n'est pas toujours mise en œuvre dans les logiciels serveurs typiques, il faut donc se préparer à programmer un peu. Je n'ai pas testé mais je suppose qu'on peut mettre en œuvre le whitelisting sur BIND en utilisant les vues, avec deux fichiers de zone (un avec AAAA et un sans) et en définissant une ACL pour la liste blanche, dirigeant ses membres vers la vue ayant les AAAA :
acl v6-whitelist { 192.0.2.0/24; 2001:db8:3003::/48; }; ... view "with-aaa" { match-clients { v6-whitelist; }; zone "example.com" { ... file "/etc/bind/example.com-with-aaaa"; }; }; view "external" { match-clients { any; }; zone "example.com" { ... file "/etc/bind/example.com-without-aaaa"; }; };
La solution n'est pas parfaite : un réseau peut avoir correctement déployé IPv6 mais un utilisateur peut avoir un navigateur Web qui a des problèmes avec IPv6. La liste blanche stockant des réseaux, les globes oculaires de cet utilisateur seront malheureux quand même. Mais cela reste une des meilleures solutions existantes.
Aujourd'hui, on l'a vu, cette solution est manuelle : les réseaux qui veulent être whitelistés soumettent leur candidature, sont évalués (ce qui peut nécessiter une interaction qui consomme donc également des ressources humaines du côté du FAI), et mis (ou pas) dans la liste. Dans le futur, on verra peut-être une automatisation de la procédure, avec des tests faits de temps en temps. Autre évolution possible, le passage en mode « liste noire » où tous les clients DNS recevraient l'enregistrement AAAA, sauf ceux explicitement listés dans la liste noire (section 4.4). Cela sera intéressant le jour où la majorité des FAI auront un IPv6 qui marche, et où seuls quelques maillons faibles subsisteront.
Un résumé des inquiétudes sur le whitelisting figure dans l'article de Brzozowski, J., Griffiths, C., Klieber, T., Lee, Y., Livingood, J., et R. Woundy, « IPv6 DNS Resolver Whitelisting - Could It Hinder IPv6 Adoption? ». Outre la fragmentation de l'espace de nommage, la principale inquiétude concerne l'introduction d'une nouvelle composante dans le réseau, qui rend le débogage plus compliqué (un principe cardinal de l'Internet est que les décisions « politiques » doivent être faites aux extrémités, pas dans des équipements intermédiaires, cf. RFC 3724 et l'article de Blumenthal, M. et D. Clark, « Rethinking the design of the Internet: The end to end arguments vs. the brave new world » et, sur le cas spécifique du DNS, la section 2.16 du RFC 3234.) Un bon exemple est donné par les résultats de dig cités plus haut : déboguer l'accès à Google va dépendre du réseau où on fait le dig. De beaux malentendus peuvent alors survenir. Mais le débat est complexe : s'il y a un large consensus sur l'importance de ne pas mettre trop d'état et de décisions dans les équipements intermédiaires (le principe « de bout en bout »), la discussion a toujours fait rage sur qu'est-ce qu'un équipement intermédiaire. Est-ce qu'un serveur DNS fait partie des middleboxes qui perturbent si souvent la connexion de bout en bout ?
Enfin, la dernière tactique de migration possible est le saut
direct (section 4.5) : activer IPv6 sur le serveur, le tester, puis
publier un AAAA normal. Cela n'est pas forcément si radical que ça car
on peut le faire nom par nom (par exemple, pour
static-content.example.com
avant
www.example.com
) mais c'est quand même la méthode
la plus audacieuse. À ne faire qu'une fois qu'on maîtrise bien
IPv6. Relativisons tout de même les choses : des tas de sites Web vus
par un public non technique (comme http://www.afnic.fr/
)
ont un AAAA depuis de nombreuses années et sans que cela crée de
problèmes.
Si on est toutefois inquiets, on peut utiliser cette tactique, mais pendant une période limitée : on teste, on publie le AAAA pendant quelques heures, on arrête, on analyse les résultats, on corrige les éventuels problèmes et on recommence.
Pour les lecteurs pressés, la section 5 résume les étapes possibles d'un plan de transition. Là encore, pas question de l'appliquer aveuglément. Chacun doit l'adapter aux caractéristiques spécifiques de son réseau. Rappelez-vous en outre que le RFC cible les gros sites : la plupart des petits n'auront pas envie d'autant d'étapes. Voici ces étapes potentielles successives :
www.ipv6.example.org
,Voici, vous connaissez maintenant l'essentiel. La section 6 du RFC liste quelques points de détail. Par exemple, contrairement à ce que certains pourraient croire au premier abord, le whitelisting est tout à fait compatible avec DNSSEC (section 6.1), puisqu'il se fait sur les serveurs faisant autorité. Ceux-ci peuvent donc parfaitement signer les deux versions de la réponse, avec ou sans AAAA, et ces deux réponses pourront être vérifiés comme authentiques.
Par contre, si un résolveur DNS s'avisait de faire des manipulations analogues au whitelisting, par exemple en retirant les réponses AAAA vers des clients qu'il sait ne pas gérer IPv6 correctement, alors, là, DNSSEC détecterait la manipulation comme une tentative d'attaque, et la réponse ne pourrait pas être validée.
On a vu que la gestion d'une liste blanche représentait un certain travail. Il est donc tentant de partager les résultats de ce travail entre plusieurs acteurs. Mais attention à le faire en respectant la vie privée (section 6.2). Il n'y a pas de problèmes avec les listes actuelles, dont la granularité ne descend pas jusqu'à l'individu, mais, si des listes plus précises devaient apparaître, ce problème est à garder en tête.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : J. Arkko, A. Keranen (Ericsson)
Pour information
Première rédaction de cet article le 22 avril 2012
La plupart des RFC décrivent, de façon normative, un protocole ou un format qui sera ensuite déployé sur l'Internet. Mais ce document est différent : c'est un récit d'expérience, celle de deux courageux chercheurs qui, au péril de leur usage de Facebook et dans l'intérêt de la science, ont coupé IPv4 et n'ont accédé à l'Internet que via IPv6 pendant la durée de l'expérience. Les machines de l'expérience n'avaient plus du tout d'IPv4 et seule une fragile passerelle NAT64 les reliaient aux territoires barbares où régnait encore IPv4. Qu'est-ce qui marche dans ce cas ? Qu'est-ce qui ne marche pas ? Qu'est-ce qu'on peut améliorer ?
Deux réseaux ont été utilisés, un professionnel et un à la maison. Tous les deux étaient en double-pile (IPv4 et IPv6, cf. RFC 4213) depuis longtemps. Tous les deux avaient une connectivité IPv6 stable et correcte depuis des années. Il était donc temps de sortir de la « zone de confort » et d'essayer le grand large. Mais la majorité de l'Internet reste accessible en IPv4 seulement. C'est là qu'intervient NAT64 (RFC 6144), qui permet aux machines purement IPv6 d'accèder à des sites Web attardés en v4.
Ce n'est pas juste une expérience de démonstration pour montrer que les Vrais Hommes peuvent se passer du vieux protocole des mangeurs de yaourt. L'épuisement des adresses IPv4 fait que de plus en plus de FAI envisagent de déployer des réseaux uniquement IPv6, puisqu'ils n'ont plus la possibilité d'obtenir des adresses. Tester de tels réseaux en vrai est donc nécessaire. La conclusion est d'ailleurs que cela ne marche pas trop mal mais qu'il reste un certain nombre de petits problèmes qu'il serait bon de régler.
La section 3 du RFC explique l'environnement de l'expérience. Les deux réseaux (un à la maison et un au bureau) étaient un mélange classique de PC, d'appareils photos numériques, de gadgets électroniques divers et de petits routeurs du commerce, avec divers systèmes (Mac OS, Windows, Linux...). Les usages étaient également classiques, courrier, SSH, VoIP, jeu (pas dans le réseau de bureau, bien sûr), messagerie instantanée, un peu de domotique et bien sûr du Web. Il s'agissait de petits réseaux avec une dizaine d'utilisateurs au maximum.
Comme certains des utilisateurs des deux réseaux, des petits bras, avaient choisi de ne pas participer à l'expérience, il a fallu créer un réseau séparé pour celle-ci, avec un VLAN propre. Il n'y avait évidemment pas de serveur DHCP v4 sur ce réseau seulement des RA (Router Advertisement) v6.
On l'a vu, l'essentiel du Web aujourd'hui n'est accessible qu'en IPv4. Il a donc fallu mettre en place une passerelle NAT64 (RFC 6146). Elle incluait le serveur DNS64 (RFC 6147). L'installation et la configuration de cette passerelle étaient très simples pour un administrateur réseaux.
Le serveur DNS cité plus haut était publié
via les RA (RFC 6106). (À noter que Windows écrit
aussi à des serveurs DNS bien connus,
fec0:0:0:ffff::1
,
fec0:0:0:ffff::2
, et
fec0:0:0:ffff::
.) Trouver le serveur DNS dans un
environnement IPv6 pur n'est pas trivial. Dans les environnements
mixtes, il est fréquent que le résolveur DNS à utiliser par les
clients ne soit publié qu'en v4, les clients demandant ensuite aussi
bien les enregistrements A que les AAAA en IPv4. Ici, cette méthode
n'était pas possible et les auteurs du RFC ont également testé avec
DHCP v6 (RFC 8415). Un
des charmes d'IPv6 est en effet qu'il existe deux façons de découvrir
automatiquement le résolveur DNS local, via les RA ou bien via
DHCP.
Le serveur DNS64 et la passerelle NAT64 fonctionnaient de la manière habituelle (RFC 6144) : si un client demandait un AAAA (adresse IPv6 dans le DNS) inexistant, le serveur DNS64 en synthétisait un, les paquets à destination de cette adresse étaient ensuite interceptés par la passerelle et NATés en IPv4 (la passerelle avait, elle, une adresse v4 publique). Les destinations ayant des AAAA étaient traitées normalement : la passerelle servait alors de simple routeur v6, le cas idéal d'une connectivité v6 complète.
Les résultats de l'expérience occupent le reste du RFC. La section 4 fournit une synthèse et la section 5 examine un par un les choses qui ont plus ou moins bien marché. Principale conclusion ; ça marche. Un des auteurs du RFC travaille dans un environnement IPv6 pur depuis un an et demi et est toujours vivant et en bonne santé. Certains points marchent particulièrement bien (aucun problème avec le Web). Sur un téléphone Symbian, toutes les applications ont marché (sur un Android, toutes les applications de base marchaient, mais après un bricolage pour permettre à la machine de trouver son résolveur DNS).
Les problèmes rencontrés se subdivisent en plusieurs catégories :
http://192.0.2.80/
). Ce problème est rare
mais très agaçant lorsqu'il se produit.Bref, aucun de ces problèmes n'était un problème fondamental d'IPv6 ou de NAT64, nécessitant de revisiter le protocole. C'était « uniquement » des questions de développement logiciel.
Maintenant, avec la section 5, voyons ces problèmes cas par cas. D'abord, ceux situés dans les systèmes d'exploitation. Par exemple, Linux ne jette pas l'information acquise par les RA lorsque la connectivité réseau change, il faut faire explicitement un cycle suspension/reprise. Ensuite, le démon rdnssd, censé écouter les annonces de résolveurs DNS faites en RA, n'était pas intégré par défaut sur Ubuntu et, de toute façon, ne semblait pas très fiable. Comme pas mal de problèmes rencontrés lors de cette expérience, il s'est résolu en cours de route, avec une nouvelle version du système. Mais tout n'est pas parfait, notamment le NetworkManager qui s'obstine à sélectionner un réseau sans-fil IPv4 qui n'a pas de connectivité externe, plutôt que le réseau IPv6 pur.
Les autres systèmes ont aussi ce genre de problèmes. Ainsi, avec Mac OS X, il faut dire explicitement au système qu'IPv4 est facultatif et qu'un réseau sans IPv4 ne doit pas être considéré comme cassé et à ignorer. Et passer d'un réseau v4 à v6 nécessite des manipulations manuelles.
Pour Windows 7, le problème était avec les résolveurs DNS : Windows les affichait mais ne les utilisait pas sans action manuelle.
Android a un problème analogue. Il peut faire de l'IPv6 mais il ne sait pas sélectionner les résolveurs DNS en IPv6. Par défaut, il lui faut donc un résolveur DNS v4. Heureusement, il s'agit de logiciel libre et les auteurs ont pu résoudre ce problème eux-même avec le nouveau logiciel DDD.
En conclusion, le RFC note que tous ces systèmes ont IPv6 à leur catalogue depuis des années, parfois de nombreuses années, mais tous ces problèmes donnent à penser qu'ils n'ont jamais été sérieusement testés.
La situation des langages de programmation et des API semble meilleure, par exemple Perl qui était un des derniers grands langages à ne pas gérer complètement IPv6 par défaut semble désormais correct.
C'est moins satisfaisant pour la messagerie instantanée et la voix sur IP. Les cris les plus perçants des utilisateurs impliqués dans l'expérience avaient été provoqués par Skype, qui ne marche pas du tout en IPv6 (il a fallu utiliser un relais SSH vers une machine distante). La légende comme quoi Skype marcherait toujours du premier coup en prend donc un... coup.
Parmi les autres solutions testées, celles passant par le Web marchaient (Gmail ou Facebook, par exemple), celles fondées sur XMPP également mais les solutions commerciales fermées comme MSN, WebEx ou AOL échouent toutes. Ces solutions sont mises en œuvre dans des logiciels privateurs (on ne peut donc pas examiner et corriger le source) mais l'examen du trafic réseau montre qu'il passe des adresses IPv4 entre machines, ce qui est incompatible avec NAT64.
Et pour les applications stratégiques essentielles, je veux dire les jeux ? Ceux utilisant le Web n'ont pas de problème, pour les autres, c'est l'échec complet. En outre, aucun des ces logiciels ne produit de messages de diagnostic utilisables et le débogage est donc très difficile. Au moment des premiers tests, ni Battlefield, ni Age of Empires, ni Crysis ne fonctionnaient sur le nouveau réseau. Depuis, World of Warcraft est devenu le premier jeu majeur qui marchait en IPv6. Les jeux dont le source a été libéré (comme Quake) ont également acquis cette capacité. Les autres feraient bien d'utiliser une API réseau plus moderne... (Cf. RFC 4038.)
Pendant qu'on en est au divertissement, que devient la musique en ligne ? La plupart des boutiques reposent sur le Web et marchent donc, sauf Spotify qui réussit l'exploit d'être un des rares services accessibles via le Web qui ne fonctionne pas en IPv6.
Moins bonne est la situation des appliances comme les webcams. La plupart ne parlent pas IPv6 du tout, sourds que sont leurs constructeurs chinois aux sirènes de la modernité.
Enfin, les problèmes ne sont pas forcément avec les matériels et logiciels du réseau local. Parfois, le problème est situé chez le pair avec qui on veut communiquer comme lorsque bit.ly (le RFC cite ce cas mais sans mentionner le nom comme si l'information n'était pas déjà publique...) avait publié un enregistrement AAAA invalide : NAT64 ne peut rien dans ce cas puisque la passerelle pense que le service est accessible en IPv6. C'est l'occasion de rappeler qu'il vaut mieux ne pas publier de AAAA que d'en publier un erroné.
On l'a vu, une bonne partie de la connectivité externe des deux réseaux de test dépendait de NAT64, puisqu'une grande partie de l'Internet n'est hélas pas joignable en IPv6. La section 6 tire le bilan spécifique de ce protocole et il est très positif : pas de problèmes de fond, juste quelques bogues dans l'implémentation, corrigées au fur et à mesure.
Le cas des adresses IPv4 littérales dans les URL est irrémédiable (le DNS n'est pas utilisé donc DNS64 ne peut rien faire) mais rare. Les deux seuls cas bloquants concernaient certaines pages YouTube (tiens, pourquoi est-ce que les erreurs de bit.ly sont mentionnées sans indiquer son nom, alors que YouTube est désigné dans le RFC ?) et une page de réservation d'un hôtel qui renvoyait vers un URL contenant une adresse IPv4. Les auteurs du RFC ont mesuré les 10 000 premiers sites Web du classement Alexa et trouvé que 0,2 % des 1 000 premiers ont un URL IPv4 dans leur page (pour charger du JavaScript, du CSS ou autre), et que ce chiffre monte à 2 % pour les 10 000 premiers (ce qui laisse entendre que les premiers sont mieux gérés). Cette stupide erreur n'empêchait pas le chargement de la page, elle privait juste le lecteur d'un bandeau de publicité ou d'une image clignotante. Ce n'est donc pas un problème sérieux en pratique.
Les auteurs ont également testé avec wget
le chargement des pages d'accueil de ces 10 000 sites en comparant un
accès IPv4, un accès IPv6 sans NAT64 et le réseau de test, IPv6 pur
mais avec NAT64. En IPv4 pur, 1,9 % des sites ont au moins un problème
(pas forcément la page d'accueil elle-même, cela peut être un des
composants de cette page), ce qui donne une idée de l'état du Web. Le
RFC note toutefois que certains problèmes peuvent être spécifiques à
ce test, si le serveur refuse à wget du contenu qu'il accepterait de
donner à un navigateur Web. wget avait été configuré pour ressembler à
un navigateur (le RFC ne le dit pas mais je suppose que cela veut dire
des trucs comme --user-agent="Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:11.0) Gecko/20100101 Firefox/11.0"
). Mais cela
ne suffit pas dans des cas comme l'absence d'une adresse pour un nom
de domaine, qui ne gène pas le navigateur qui ajoute
www
devant à tout hasard, chose que ne fait pas
wget.
Avec le réseau IPv6 pur, 96 % des sites échouent (ce qui est logique, vu le nombre de sites Web accessible en v6). Les sites Google étaient une des rares exceptions.
Avec le réseau IPv6 aidé de la passerelle NAT64, le taux d'échec est de 2,1 %, quasiment le même qu'en IPv4 pur (la différence venant surtout des adresses IPv4 littérales).
Sur quoi doivent porter les efforts de mesure futurs (section 7) ? Le RFC estime important de mesurer plus précisement les phénomènes à l'œuvre lors d'une connexion utilisant NAT64. Certains utilisateurs ont signalé des ralentissements, mais qui ne sont pas confirmés par une analyse des paquets et des temps de réponse. S'il se passe quelque chose qui ralentit, c'est plus subtil, et cela devrait être investigué.
Compte-tenu de cette expérience, quelles conclusions en tirer (section 8) ? Comme indiqué plus haut, la principale est qu'un réseau purement IPv6 est viable. (Le RFC ne le précise pas mais je rajoute : s'il est géré par un informaticien compétent et disponible. Cette expérience n'est pas encore reproductible par M. Toutlemonde.)
Seconde grande conclusion : il reste du travail, trop de petites bogues sont encore présentes, et à beaucoup d'endroits.
Bref, aujourd'hui, il reste prudent d'utiliser plutôt la double-pile (IPv6 et IP4) pour un réseau de production. Un réseau IPv6 pur, à part pour le geek, est surtout intéressant pour des environnements très contrôlés, comme par exemple celui d'un opérateur de téléphonie mobile qui fournirait un modèle de téléphone obligatoire, permettant de s'assurer que tous les clients aient ce qu'il faut.
Comme tout ne s'arrangera pas tout seul, nos héroïques explorateurs revenant de la terre lointaine et mystérieuse où tout ne marche qu'en IPv6 suggèrent des actions à entreprendre pour se préparer à notre future vie dans ce monde :
Le RFC note que pratiquement aucune de ces actions ne nécessite d'action dans le champ de la normalisation. Cela veut dire que toutes les normes nécessaires sont là, l'IETF a terminé son travail et c'est maintenant aux programmeurs et aux administrateurs réseaux d'agir.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : M. Nottingham (Rackspace), R. Fielding (Adobe)
Chemin des normes
Première rédaction de cet article le 1 mai 2012
Le protocole HTTP, normalisé dans le RFC 7230, utilise des réponses numériques sur trois chiffres pour indiquer le résultat de la requête. Certains de ces codes sont devenus célèbres comme le 404 pour une ressource non trouvée. Et comme l'Internet fonctionne avec des LOLcats, il existe même un ensemble de photos des réponses HTTP avec des chats (d'où sont tirées les images de cet article). Mais la liste des réponses possibles n'est pas figée et de nouveaux codes sont ajoutés de temps en temps. Ce RFC normalise quatre de ces codes.
Ces nouveaux codes permettent de préciser le code utilisé autrefois, qui était en général moins précis. Ainsi, les limiteurs de trafic utilisaient souvent, lorsqu'un client demandait trop de ressources, le code 403 (Interdiction), qui pouvait servir à bien d'autres choses. Ils ont désormais un code à eux, 429. Les nouveaux codes sont enregistrés à l'IANA.
Rappelez-vous bien que le premier chiffre indique la classe de l'erreur (RFC 7231, section 6) et qu'un serveur HTTP qui utilise un code nouveau n'a pas de souci à se faire : un client qui ne connaîtrait pas ce nouveau code peut le traiter comme le code générique commençant par le même chiffre. Pour reprendre l'excellent résumé de Dana Contreras, « HTTP response codes for dummies. 5xx: we fucked up. 4xx: you fucked up. 3xx: ask that dude over there. 2xx: cool ».
Premier cité (section 3), 428
Precondition Required (pas de jolie image de chat pour ce code). Pour éviter le problème de
la « mise à jour perdue » (un client récupère une ressource Web, la
modifie et la renvoie au serveur pour mise à jour, alors que, pendant
ce temps, un autre client a fait pareil : l'un des deux va perdre sa
mise à jour), certains serveurs HTTP exigent que les requêtes soient
conditionnelles (par exemple avec le If-Match:
de
la section 3.1 du RFC 7232). Si le client n'a
pas utilisé de condition, le serveur l'enverra promener avec ce code
428 (qui doit normalement être accompagné d'un message clair indiquant
le problème) :
HTTP/1.1 428 Precondition Required Content-Type: text/html <html> <head> <title>Precondition Required</title> </head> <body> <h1>Precondition Required</h1> <p>This request is required to be conditional; try using "If-Match".</p> </body> </html>
Deuxième code, 429 Too Many Requests (section 4) Il était apparemment assez répandu dans la nature mais n'était pas encore normalisé. C'est désormais fait et les limiteurs de trafic peuvent donc désormais dire clairement à leurs clients qu'ils exagèrent :
HTTP/1.1 429 Too Many Requests Content-Type: text/html Retry-After: 3600 <html> <head> <title>Too Many Requests</title> </head> <body> <h1>Too Many Requests</h1> <p>I only allow 50 requests per hour to this Web site per logged in user. Try again soon.</p> </body> </html>
C'est uniquement un indicateur d'une décision prise par le serveur : le RFC n'impose pas aux serveurs un mécanisme particulier pour prendre cette décision. De même, le serveur n'est pas obligé de renvoyer quelque chose (ce qui consomme des ressources), il a le droit d'ignorer purement et simplement les requêtes excessives (section 7.2).
Troisième code, en section 5, 431 Request Header Fields Too Large Le protocole HTTP n'impose pas de limite à la taille des en-têtes envoyés lors d'une requête mais un serveur donné peut avoir une telle limite. Si elle est dépassée, il peut répondre 431. Le même code peut dire « taille totale des en-têtes trop grande » ou « taille d'un en-tête trop grande ». Dans ce dernier cas, la réponse doit indiquer quel en-tête :
HTTP/1.1 431 Request Header Fields Too Large Content-Type: text/html <html> <head> <title>Request Header Fields Too Large</title> </head> <body> <h1>Request Header Fields Too Large</h1> <p>The "Example" header was too large.</p> </body> </html>
Ces trois premiers codes n'ont pas suscité de controverses particulières. Ce n'était pas le cas de 511 Network Authentication Required (section 6, pas de jolie image de chat pour ce code) qui indique que le client aurait dû s'authentifier. Le problème est d'architecture : ce code est utilisé pour les portails captifs qui, tant qu'on n'est pas authentifié, redirigent d'autorité toutes les requêtes HTTP vers un serveur permettant de s'authentifier. (Après l'authentification, l'adresse MAC est mémorisée par le routeur, qui ne redirige plus.) De tels portails violent sérieusement les bons principes d'architecture du Web. Mais ils existent et il était donc préférable qu'ils puissent répondre avec un code sans ambiguité. La réponse 511 inclut donc le lien vers la page de login. Elle ne doit jamais être envoyée par un serveur normal, uniquement par le relais détourneur.
Le RFC dit donc que les portails captifs sont le Mal (surtout pour les clients HTTP qui ne sont pas des navigateurs) mais que le 511 permettra de limiter les dégats. Au moins, curl ou wget comprendront tout de suite ce qui s'est passé.
Un exemple de réponse (notez l'élément
<meta>
pour les navigateurs) :
HTTP/1.1 511 Network Authentication Required Content-Type: text/html <html> <head> <title>Network Authentication Required</title> <meta http-equiv="refresh" content="0; url=https://login.example.net/"> </head> <body> <p>You need to <a href="https://login.example.net/"> authenticate with the local network</a> in order to gain access.</p> </body> </html>
Les réponses 511 ou, plus exactement, les redirections forcées posent des tas de problèmes de sécurité. Par exemple, elles ne viennent pas du serveur demandé, ce qui casse certains mécanismes de sécurité de HTTP comme les cookies du RFC 6265. Un problème analogue survient si on utilise TLS car le certificat X.509 ne correspondra pas au nom demandé. L'annexe B du RFC détaille les problèmes de sécurité des portails captifs et les façons de les limiter. Cela va de problèmes esthétiques (la favicon récupérée depuis le portail et qui s'accroche ensuite dans le cache du navigateur) jusqu'aux protocoles de sécurité qui risquent de prendre la réponse du portail pour l'information qu'ils demandaient (P3P, WebFinger, OAuth, etc). Ces protocoles sont souvent utilisés par des applications HTTP qui ne passent pas par un navigateur (Twitter, iTunes, le WebDAV du RFC 4918, etc). En détectant le code 511, ces applications ont une chance de pouvoir réagir proprement (en ignorant les réponses transmises avec ce code).
À l'heure actuelle, je ne pense pas qu'il y ait beaucoup de hotspots qui utilisent ce code mais cela viendra peut-être. Mais je n'en suis pas sûr, ces portails captifs étant en général programmés avec les pieds, par un auteur anonyme à qui on ne peut jamais signaler les bogues. Et je ne sais pas quels sont les clients HTTP qui le reconnaissent et agissent intelligement. Si un lecteur courageux veut enquêter...
Les images de chats citées plus haut sont également accessibles via une API REST simple. Si vous préférez les chiens, ça existe aussi.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : T. Henderson (Boeing), S. Floyd (ICSI), A. Gurtov (University of Oulu), Y. Nishida (WIDE Project)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 7 avril 2012
Même les plus vieux protocoles, comme TCP, continuent à évoluer, dans l'environnement toujours changeant qu'est l'Internet. Pour lutter contre le principal ennemi d'un protocole de transport, la congestion, de nouveaux algorithmes sont régulièrement mis au point. Même des années après leur spécification, on trouve des choses à corriger ou améliorer. Ainsi, l'algorithme NewReno, originellement proposé par le RFC 2582 en 1999, puis normalisé par le RFC 3782 en 2004, voit avec ce nouveau RFC sa description évoluer très légèrement, pour répondre aux problèmes rencontrés.
La référence pour la lutte de TCP contre la congestion est le RFC 5681. Ce dernier spécifie quatre algorithmes possibles, et autorise des modifications limitées à ces algorithmes, par exemple en utilisant les accusés de réception sélectifs (SACK, RFC 2883) ou bien en utilisant les accusés de réception partiels (ceux qui ne couvrent pas la totalité des données encore en transit). C'est le cas de NewReno et ce RFC remplace l'ancienne définition de NewReno (celle du RFC 3782).
Un peu d'histoire de NewReno (section 1) : l'algorithme de retransmission rapide (Fast Recovery) de TCP avait d'abord été mis en œuvre dans une version de BSD connue sous le nom de Reno. (L'article original est toujours en ligne, ainsi qu'une comparaison des méthodes.) L'idée de base de la retransmission rapide est de retransmettre les accusés de réception lorsqu'arrivent des paquets dont les numéros de séquence sont supérieurs à ceux attendus (section 5 de notre RFC ; cette retransmission indique la perte de paquets intermédiaires). L'émetteur commence alors tout de suite à retransmettre, sans attendre l'expiration du délai de garde normal. Le problème est que l'émetteur ne sait pas exactement ce qu'il faut retransmettre. Par exemple, avec une MSS de 1460 octets et un numéro de séquence initial (ISN) de 67891, si un émetteur envoie cinq paquets, il sera satisfait lorsqu'il recevra un accusé de réception pour l'octet 75191. S'il reçoit des accusés de réception dupliqués pour l'octet 70811, cela veut dire que deux paquets sont arrivés, puis que le paquet n° 4 ou le n° 5 est arrivé, déclenchant l'émission des accusés de réception dupliqués. L'émetteur va alors retransmettre le paquet n° 3. Mais doit-il aussi renvoyer les n° 4 et n° 5 ? L'émetteur ne le sait pas, les accusés de réception n'indiquent pas les octets reçus hors-séquence, sauf à utiliser les SACK du RFC 2883. NewReno avait justement été conçu pour ce cas où on ne peut pas ou bien où on ne veut pas utiliser les accusés de réception sélectifs (SACK). Son principe est, pendant la retransmission rapide, de regarder si les accusés de réception couvrent tous les paquets transmis (accusé de réception pour l'octet 75191) ou bien seulement une partie (par exemple, accusé de réception pour l'octet 72271). Dans ce cas (accusés de réception partiels), on sait qu'il y a perte de plusieurs paquets et on peut retransmettre tout de suite (ici, le paquet n° 4).
NewReno est donc une légère modification, située uniquement chez l'émetteur, à l'algorithme de retransmission rapide (« OldReno » ?). Cette modification est déclenchée par la réception, une fois la retransmission rapide commencée, d'accusès de réception partiels. Elle consiste en la réémission de paquets supplémentaires, suivant le paquet qu'« OldReno » retransmettait déjà.
Si vous voulez tous les détails, la section 3 précise le nouvel algorithme. Comme il ne nécessite des modifications que chez l'émetteur des données, il n'affecte pas l'interopérabilité des mises en œuvre de TCP. Évidemment, SACK serait une meilleure solution, donnant à l'émetteur toute l'information nécessaire mais, en son absence, NewReno améliore les performances en évitant d'attendre inutilement l'expiration d'un délai de garde.
Il existe quelques variations à NewReno, moins importantes que la différence entre OldReno et NewReno. Ces variations possibles sont documentées dans l'ancien RFC, le RFC 3782 et citées dans l'annexe A.
NewReno est aujourd'hui bien établi et éprouvé. L'ancien RFC, le RFC 3782 contenait des éléments en sa faveur (notamment via des simulations), qui semblent inutiles aujourd'hui et ont donc été retirés.
Globalement, les principaux changements depuis le RFC 3782 sont le retrait de nombreuses parties qui n'apparaissent plus aussi importantes qu'à l'époque. Le lecteur qui veut approfondir le sujet, et pas uniquement programmer NewReno correctement, peut donc lire le RFC 3782 pour découvrir d'autres discussions. Autrement, les changements sont de détail, et résumés dans l'annexe B.
Merci à Didier Barvaux pour sa relecture.
Date de publication du RFC : Mars 2012
Auteur(s) du RFC : R. Geib (Deutsche Telekom), A. Morton (AT&T Labs), R. Fardid (Cariden Technologies), A. Steinmitz (Deutsche Telekom)
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 26 mars 2012
Pour déterminer si un protocole de communication est bien décrit dans les RFC qui le normalisent, l'IETF a une méthode simple, tester si les différentes mises en œuvre de ce protocole interopèrent proprement entre eux (par exemple, on vérifie qu'un client HTTP parle au serveur HTTP avec succès). Ce genre de tests est maintenant fréquent, et sert de base à l'avancement des RFC sur le chemin des normes (de simple proposition au statut de norme complète). Mais, lorsqu'un RFC spécifie, non pas un protocole mais une métrique, c'est-à-dire une grandeur mesurable, comment fait-on pour vérifier que le RFC est correct et est bien implémenté ? Ce nouveau RFC de l'inépuisable groupe de travail IPPM propose une solution : on mesure le même phénomène avec les différentes mises en œuvre et les chiffres obtenus doivent être identiques (ou suffisamment proches pour être statistiquement équivalents). Cette méthode permettra aux RFC décrivant les métriques d'avancer sur le chemin des normes : si les résultats sont les mêmes, on considérera que cela semble indiquer que la métrique est définie clairement et sans ambiguité. (Si les résultats sont différents, cela pourra être dû à une bogue dans l'un des systèmes, ou à un RFC confus, qui n'a pas été compris de la même façon par tous les développeurs.)
Le chemin des normes, qui comportait trois étapes du temps du RFC 2026, n'en a plus que deux depuis le RFC 6410. Un des critères d'avancement d'une norme est l'interopérabilité entre des mises en œuvre indépendantes. Cette interopérabilité devait autrefois se démontrer par des tests explicites (RFC 5657) mais, aujourd'hui, le simple déploiement massif suffit (nul besoin de tester HTTP pour voir tous les jours dans l'Internet que clients et serveurs se parlent...). Tout cela est très bien pour les protocoles de communication. Mais pour des métriques ? On peut avoir plusieurs mises en œuvre indépendantes, qui sont largement déployées, sans que cela ne prouve qu'elles soient cohérentes entre elles. La section 5.3 du RFC 5657 prévoit explicitement le cas des normes qui ne sont pas des protocoles de communication mais ne fournit guère de solutions. L'analyse du groupe IPPM est qu'il est quand même possible de tester explicitement des définitions de métriques et que l'identité (aux variations statistiques près) des chiffres obtenus par deux mesures du même phénomène réseau est l'équivalent de l'interopérabilité. (Notez qu'IPPM a aussi quelques protocoles à son actif, comme ceux du RFC 4656 et RFC 5357, dont l'interopérabilité peut être testée par des moyens classiques.)
Pour les métriques, l'idée va donc être de générer un phénomène réseau contrôlé, avant de le faire mesurer par les différents systèmes. (Mesurer un phénomène réel, non contrôlé, est plus difficile car cela implique que les différentes mesures soient parfaitement synchronisées, pour observer exactement la même chose. Tous les systèmes de mesure n'ont pas forcément ce mécanisme de synchronisation.) Un exemple complet figure dans l'annexe A, avec la métrique « délai d'acheminement », et c'est une lecture très recommandée si tout cela vous semble trop abstrait.
La section 2 détaille cette idée de base. Inspirée du RFC 2330, elle part du principe qu'une mesure doit être reproductible (on mesure le même phénomène deux fois, et les résultats doivent être identiques, aux fluctuations statistiques près). En pratique, mesurer exactement « le même phénomène » implique de prêter attention à de nombreux détails, par exemple à la stabilité des routes (sur l'Internet, le délai d'acheminement entre deux points peut varier brusquement, si BGP recalcule les routes à ce moment). D'autre part, si la métrique a des options, les deux mesures doivent évidemment utiliser les mêmes options. Et, en raison des variations du phénomène, l'échantillon mesuré doit être assez grand pour que la loi des grands nombres rende ces variations négligeables. La section 2 dit clairement qu'on n'envisage pas de mesurer des singletons (par exemple, pour le délai d'acheminement, le délai d'un seul paquet).
Une fois ces précautions comprises, comment détermine-t-on la conformité d'une mesure à la spécification de la métrique (section 3) ? D'abord, dans la grande majorité des cas, les critères de comparaison vont dépendre de la métrique, et doivent donc être définis spécifiquement pour chaque métrique (l'annexe A fournit un exemple complet). Ensuite, on va comparer deux mesures (qui peuvent avoir été faites dans le même laboratoire, ou bien dans des endroits différents.) La méthode statistique de comparaison recommandée est le test d'Anderson-Darling K. Entre deux mesures d'un même phénomène, on veut un niveau de confiance d'Anderson-Darling K d'au moins 95 %.
Selon l'environnement de test, il va falloir faire attention à des techniques comme la répartition de charge qui peuvent envoyer le trafic par des chemins distincts, une bonne chose pour les utilisateurs, mais une plaie pour les métrologues (cf. RFC 4928).
Compte-tenu de tous les pièges que détaille la section 3 (le gros du RFC), il est nécessaire de documenter soigneusement (RFC 5657 et section 3.5 de notre RFC) l'environnement de test : quelle était la métrique mesurée, quelle était la configuration de test, tous les détails sur le flot de paquets (débit, taille, type, etc).
Si on trouve des différences entre deux mesures de la même métrique, sur le même phénomène, alors il faudra se lancer dans un audit soigneux pour déterminer où était la racine du problème : bogue dans une implémentation ou manque de clarté de la spécification, cette seconde raison étant un bon argument pour ne pas avancer la métrique sur le chemin des normes et pour l'améliorer.
Si vous voulez en savoir plus que le test d'Anderson-Darling, il est documenté dans le rapport technique 81 de l'Université de Washington, par Scholz, F. et M. Stephens, « K-sample Anderson-Darling Tests of fit, for continuous and discrete cases ». Le test Anderson-Darling K est faisable en R : voir le paquetage « adk: Anderson-Darling K-Sample Test and Combinations of Such Tests ». Une implémentation d'Anderson-Darling K en C++ figure dans l'annexe B du RFC.
L'annexe A contient un exemple complet de test d'une métrique, en l'occurrence le délai d'acheminement d'un paquet, tel que défini par le RFC 2679 (le test complet sera documenté dans un futur RFC, actuellement l'Internet-Draft « Test Plan and Results for Advancing RFC 2679 on the Standards Track »). Par exemple, on met le délai d'attente maximum (une option de la métrique) à 2 secondes, on mesure un flot de paquets à qui on impose un délai d'une seconde, grâce à un dispositif qui introduit délibérement des problèmes réseaux (un impairment generator ; ce genre de traitement peut se faire sur un Unix courant), on vérifie qu'ils sont tous comptés, on passe le délai imposé à 3 secondes, et on vérifie qu'on n'obtient plus aucun résultat (la grandeur « délai d'acheminement » est indéfinie si le paquet n'arrive pas avant le délai maximum, RFC 2679, section 3.6).
Ce n'est évidemment pas le seul test. L'annexe A propose également de tester le délai d'acheminement (qui va jusqu'à la réception du dernier bit du paquet, RFC 2679, section 3.4) en faisant varier la taille des paquets, mettons à 100 et 1500 octets. Les implémentations testées doivent mesurer la même augmentation du délai d'acheminement (qui ne dépendra que du temps de transmission supplémentaire, que devra supporter le plus gros des paquets). Autre test, mesurer le délai, puis imposer un retard N, les différentes mesures doivent voir la même augmentation du délai.
Le premier RFC à avoir testé cette démarche a été le RFC 2679, dont le rapport d'avancement a été publié dans le RFC 6808.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : H. Tschofenig (Nokia Siemens Networks), J. Arkko (Ericsson)
Pour information
Première rédaction de cet article le 13 avril 2012
Traditionnellement, les engins connectés à l'Internet étaient des ordinateurs généralistes, dotés de bonnes capacités de calcul et alimentés en courant électrique à volonté. Est-ce que la famille de protocoles TCP/IP convient toujours, lorsque les machines connectées sont des petits trucs avec un processeur ridicule, et alimentés par une batterie qu'il faut faire durer le plus longtemps possible ? C'était l'objet de l'atelier Interconnecting Smart Objects with the Internet qui s'est tenu à Prague le 25 mars 2011, à l'instigation de l'IAB. Le but était d'explorer cette question, de voir si la connexion à l'Internet de ces « objets malins » était triviale, possible avec quelques adaptations des protocoles ou, pourquoi pas, irréaliste sans des changements radicaux.
L'atelier a rassemblé près de cent participants (liste complète en annexe D), la plupart ayant déjà travaillé sur l'adaptation de TCP/IP à des objets contraints (en mémoire, en alimentation, etc). Ces objets peuvent être des capteurs, des actionneurs, etc. À côté d'eux, même un smartphone est riche en capacités CPU et en énergie électrique.
Rappelons que l'IAB, qui a produit ce RFC, est en charge du travail d'architecture à l'IETF. Ce comité ne s'occupe pas des protocoles individuels (dont le développement, dans les groupes de travail IETF, est piloté par l'IESG) mais du maintien et du développement d'une architecture saine pour l'Internet, avec une insistance sur le travail à long terme.
Une de ces questions à long terme est celle du passage d'un Internet composé uniquement d'ordinateurs à un Internet auquel sont attachés, entre autres, des engins qu'on qualifie du terme générique d'« objets » et qui ont en commun de sévères restrictions matérielles, rendant parfois difficile un attachement normal à l'Internet. Pour les développements liés à ces objets, les gens du marketing ont inventé le terme ridicule d'« Internet des objets » (IoT en anglais pour « Internet of Things »). Mais, même si le terme est grotesque, il y a une vraie question technique : l'Internet est-il accessible à des objets contraints en ressources ?
Connecter ces objets présente souvent des avantages (pour des capteurs, cela permet de les interroger à distance, alors qu'auparavant il fallait qu'un humain se déplace pour les lire), et certains le sont déjà, en utilisant des protocoles privés. Mais la tendance actuelle est de migrer vers les protocoles standard de l'Internet. Cela se reflète entre autres dans les groupes de travail IETF, dont plusieurs planchent sur cet Internet des Trucs : Constrained RESTful Environments (CoRE), IPv6 over Low power WPAN (6LowPAN), Routing Over Low power and Lossy networks (ROLL) ou Light-Weight Implementation Guidance (LWIG).
C'est que le travail d'ingéniérie n'est pas facile : il faut jongler entre des exigences contradictoires, la sécurité, le prix, l'utilisabilité, la protection de la vie privée (ces objets sont souvent liés à notre vie quotidienne), la longévité sous batterie, etc. (Le RFC cite, sur cette questions des exigences contradictoires, l'excellent article « Tussle in Cyberspace: Defining Tomorrow's Internet ».)
L'atelier de l'IAB partait de la constatation que les protocoles actuels de l'Internet, d'IPv4 à IPv6, d'UDP à TCP et jusqu'à bien sûr HTTP, fonctionnent même sur les objets contraints. Il en existe déjà dans la nature. Une première question était « quel bilan tirer de ces premiers déploiements ? ». Une autre était « quels sont les problèmes pas encore résolus ? ».
En quoi ces objets sont-ils contraints ? Que leur manque-t-il exactement, par rapport à un ordinateur classique ? La section 2 détaille leurs propriétés :
La loi de Moore, souvent citée pour relativiser ces limites, ne suffit pas. Les gains qu'elle permet sont souvent utilisés pour réduire coûts et consommation électrique, pas pour augmenter la puissance.
Place à l'atelier lui-même, maintenant. Avec 70 papiers acceptés (la liste complète figure en annexe B du RFC), il n'est pas facile à synthétiser. La section 3 de notre RFC essaie quand même d'indiquer les grands lignes de la réflexion. Quatre grandes questions structuraient l'atelier, les questions d'architecture, les points soulevés par les nœuds dormants, la sécurité et le routage. Commençons par l'architecture, section 3.1.
Première question d'architecture, parle-t-on de connecter ces objets contraints à l'Internet (singulier, et avec une majuscule, car c'est une entité unique comme l'Atlantique ou l'Himalaya) ou bien à des réseaux utilisant TCP/IP, mais qui ne sont pas forcément reliés à l'Internet ? Après tout, les capteurs et actionneurs dans une usine n'ont pas forcément besoin de se connecter à YouTube et, même si le RFC ne le rappelle pas, du point de vue sécurité, il est irresponsable de relier un SCADA à l'Internet. (Le RFC cite un cas moins grave, celui des fontaines devant l'hôtel Bellagio, à Las Vegas, fontaines qui sont électroniquement contrôlées à distance mais qui n'ont pas besoin d'être sur le même réseau que les clients dans leurs chambres, cf. l'exposé de B. Dolin à l'atelier.) Même chose pour les smart grids qui n'ont rien à gagner (et beaucoup à perdre) à être joignables depuis l'Internet. Bref, l'IETF doit-elle séparer clairement le cas des objets connectés à l'Internet et celui des objets reliés à TCP/IP ? Du point de vue purement économique, il est clair qu'il vaut mieux un seul réseau, comme l'a rappelé Cullen Jennings, qui prédisait que tour le monde serait connecté au même Internet, car c'était plus simple et moins coûteux.
Une autre question d'architecture fondamentale est celle des protocoles spécifiques à un domaine d'application. Prenons l'exemple d'une ampoule électrique du futur. Grâce aux normes, on la branche au réseau et elle acquiert une adresse IP (grâce à DHCP ou NDP), trouve un serveur DNS, on peut la pinguer. On peut même imaginer qu'elle ait un serveur HTTP et tout client HTTP peut alors s'y connecter. Mais pour une tâche simple pour laquelle elle est conçue, éclairer, il n'y a pas de norme. Une commande de base « allume-toi » n'est pas normalisée. Comment s'assurer que l'objet, non seulement sera connecté (ping), mais pourra interagir avec son environnement, selon ses capacités ? Les protocoles de couche 3, 4 et même 7 ne suffisent pas. Il va falloir mettre au point des modèles (des classes, dirait-on en programmation objet, dont le nom est bien adapté ici), pour exploiter ces objets « intelligents ».
Un des principes de base de l'Internet, qui est défié par l'arrivée massive des objets connectés, est celui comme quoi l'intelligence est uniquement aux extrémités et le réseau fournit uniquement un service de base (faire passer les paquets). Avec des objets assez limités en ressources, on pourrait imaginer de revisiter ce principe et de mettre de l'« intelligence » dans le réseau. Parmi les services pour lesquels ce serait un bon endroit, on peut imaginer :
Deuxième grande question après l'architecture, le sommeil des objets (section 3.2). Pour économiser l'énergie, beaucoup de ces objets contraints s'endorment souvent. Pour qu'une pile AAA tienne des mois, il faut que l'objet dorme pendant 99, voire 99,9 % du temps. Chaque bit, chaque aller-retour sur le réseau, et chaque milli-seconde d'activité radio (une activité qui consomme beaucoup de courant) est précieux. Or, la plupart des protocoles TCP/IP sont conçus autour de l'idée que les machines sont allumées en permanence, qu'elles peuvent garder un état et répondre à tout moment à un paquet, même non sollicité. Mais, lorsque la simple attente d'un éventuel message consomme du courant, cette idée n'est plus valable : les objets contraints sont plus souvent endormis qu'éveillés, contrairement aux ordinateurs classiques.
Pire, lorsqu'un nœud se réveille après une période de sommeil, son adresse IP a pu être prise par un autre. Il va donc devoir se lancer dans une procédure coûteuse pour obtenir une adresse. Il peut toutefois économiser des efforts s'il met en œuvre les méthodes DNS (Detecting Network Attachment) des RFC 4436 et RFC 6059. Autre piège, si l'objet est mobile, après son réveil, il a pu bouger pour un tout autre endroit.
Pour gérer ces machines « Belle au bois dormant », les solutions envisagées lors de l'atelier étaient :
Troisième grande question explorée lors de l'atelier, la sécurité (section 3.3). Il faut évidemment la prendre en compte dès le début (RFC 3552 et RFC 4101). L'idéal est que la sécurité soit intégrée dans le début, au lieu d'être une option qu'on oublie d'activer. Mais les défis pour les objets contraints sont énormes. Les calculs qu'impose la cryptographie ne vont pas dans le sens de l'économie d'énergie. D'autre part, l'absence d'une interface utilisateur commode limite sérieusement la configuration qui peut être faite (pas moyen de demander à l'administrateur d'entrer un mot de passe compliqué). Les protocoles de sécurité de l'IETF permettent de gérer tous les cas, mais ils peuvent être trop riches et on peut défendre l'idée de profils, de restrictions ne gardant, par exemple, que certains algorithmes de cryptographie. Le choix ne sera pas évident car il existe des exigences contradictoires. Par exemple, les algorithmes à base de courbes elliptiques (RFC 6090) sont souvent moins consommateurs de ressources matérielles mais sont bien plus encombrés de brevets.
Enfin, les objets communiquants ayant vocation à être partout (à l'usine, au bureau, mais aussi à la maison et, pourquoi pas, dans notre propre corps), les questions de protection de la vie privée sont cruciales. Pas question qu'un sniffer puisse espionner la communication entre le frigo et le supermarché, apprenant ainsi mes habitudes, mes heures de présence, etc. (Dans ce cas, le principal danger pour la vie privée vient probablement du supermarché et, là, le chiffrement des communications n'aide pas.)
Mais l'algorithme de cryptographie n'est pas tout : l'expérience de l'usage de la cryptographie dans l'Internet a montré que les problèmes de gestion des clés cryptographiques étaient souvent bien pires.
Enfin, dernière grande question analysée à Prague, le routage (section 3.4). Les objets communiquants peuvent être trop loin les uns des autres pour se parler directement et il peut être nécessaire de passer par un routeur. Comment les objets et les routeurs vont-ils apprendre les routes disponibles ? Il existe deux approches, mesh-under et route-over. La première n'est pas vraiment du routage, elle consiste à résoudre le problème au niveau 2. Les objets ont ensuite tous l'impression d'être sur le même réseau local. L'autre approche, le route-over, met en place des vrais routeurs IP. Cela implique donc un protocole de routage et celui officiel à l'IETF pour cette tâche est le RPL du RFC 6550 (mais il en existe d'autres, comme le Babel du RFC 8966).
Les protocoles de routage pour les objets contraints font face à de nombreux défis. Par exemple, en filaire classique, les caractéristiques (latence, perte de paquets) sont les mêmes pour toutes les machines attachées au même lien. Ici, c'est par contre loin d'être le cas. Le groupe de travail roll avait été formé pour étudier ce problème (qui avait déjà été abordé par le RFC 3561) et il avait produit plusieurs RFC de débroussaillage et de définition du problème (RFC 5867, RFC 5826, RFC 5673, RFC 5548), avant de définir RPL. Notez que le problème suscite des controverses. Un RFC d'étude comparée des différents protocoles de routage avait été abandonné par le groupe roll (manque de consensus pour avancer). Et, à l'atelier, les polémiques n'ont pas manqué, comme la défense d'AODV par Thomas Clausen dans son article.
Alors, à la fin, peut-on faire une synthèse ? La section 4 s'y essaie. Premier thème décrit, la sécurité. La consommation de temps de processeur (et donc d'électricité) par la cryptographie est une sérieuse limite à la sécurisation des objets communicants. La difficulté de la gestion des clés en est une autre. Notre RFC 6574 recommande d'y travailler sérieusement sur ce dernier point, en donnant comme exemple le mécanisme d'appariement de Bluetooth qui combine harmonieusement sécurité et simplicité. Un groupe de travail de l'IETF avait été formé sur cette question, enroll, mais avait échoué. Peut-être le travail devra-t-il être repris par le nouveau groupe lwig.
Quant à la question des algorithmes cryptographiques « développement durable » (à consommation de ressources réduite), un groupe de recherche de l'IRTF existe, cfrg. Par exemple, le futur SHA-3 a prévu de prendre en compte ce problème (dont l'importance n'était pas perçue pour les algorithmes précédents de la famille).
Assurer l'interopérabilité n'est pas évident lorsque des objets ont une mémoire limitée et ne peuvent pas stocker le code correspondant à tous les algorithmes existants. Le RFC rappelle que plus de cent algorithmes de cryptographie sont définis pour TLS, dont certains sont officiellement déconseillés depuis cinq ou parfois dix ans, mais toujours répandus dans la nature : une mise en œuvre de TLS qui veut être sûre de pouvoir communiquer avec tout le monde a besoin de les connaitre. Les nouveaux algorithmes à consommation d'énergie réduite pourraient encore aggraver ce problème. Faut-il créer un nouvel algorithme, avec les problèmes d'appropriation intellectuelle, avec les difficultés de déploiement, juste pour économiser 20 % de la consommation électrique ? Le RFC laisse entendre que le gain de consommation devrait être nettement plus élevé pour que le jeu en vaille la chandelle.
Un autre thème choisi pour la conclusion est justement celui de la consommation électrique. Il existe une liste de discussion active pour cela, recipe, et l'article de Margaret Wasserman à l'atelier fournit un bon point de départ pour ceux qui veulent s'engager dans ce travail.
Quant à la question du réseau « centré sur le contenu », le RFC conclut que c'est encore bien trop nébuleux et qu'il n'y a pas de travail concret de normalisation à envisager. Il s'agit de recherche pure pour l'instant.
Sur l'architecture, le RFC plaide en faveur d'un futur document de synthèse de l'IAB expliquant comment tous les protocoles Internet marchent ensemble dans ce contexte des objets contraints et communiquants. Le RFC 6272 fournit un bon exemple d'un tel travail.
Dans la lignée de l'exemple de l'ampoule électrique, le RFC insiste aussi sur l'importance de développer des modèles de données (« Une ampoule a deux états, allumé et éteint ») permettant de créer des applications (ici, de contrôle de l'ampoule). La question est « est-ce bien le travail de l'IETF, puisqu'il faut à chaque fois une expertise spécifique d'un domaine ? ».
Pour la partie « découverte » de services ou de machines, le RFC recommande de travailler avec mDNS ou équivalent.
Pour le routage, notre section de conclusion suggérait de travailler entre autres sur la question des « sous-réseaux couvrant plusieurs liens » (RFC 4903). L'essentiel du travail sur le routage pour les objets communiquants continue au sein du groupe roll.
Notez enfin le récent groupe de travail homenet qui travaille sur les problèmes de domotique (voir son RFC 7368).
La liste des présentations à l'atelier figure dans l'annexe B. On trouve en ligne la page officielle de l'atelier, les articles présentés (une impressionnante masse de bons documents à lire), les supports des présentations, et les notes prises pendant l'atelier.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : M. Amundsen
Pour information
Première rédaction de cet article le 7 avril 2012
Depuis le RFC 5988, il existe un mécanisme standard pour exprimer les types des liens entre deux ressources sur le Web. Ce très court RFC documente deux types récemment ajoutés, permettant de dire qu'une ressource (une page HTML, un fichier, etc) est membre d'une collection de ressources ou, à l'inverse, qu'une ressource désigne une collection et indique quels sont ses membres.
Ces deux types, collection
et
item
(l'un étant le réciproque de l'autre) sont d'ores et déjà largement utilisées par
d'autres normes comme OpenSearch
(section 4.5.4.1 de la
norme), Maze ou Collection+JSON.
La section 2 définit complètement ces deux
relations. item
est utilisé dans une ressource
qui représente une collection, pour identifier les membres de cette
collection. Un exemple en HTML pour un
catalogue de produits serait, avec l'attribut rel
:
<h1>Product Group X Listing</h1> ... <a href="..." rel="item">View Product X001</a> <a href="..." rel="item">View Product X002</a> ...
Ce code exprime le fait que chacun des produits est un élement (item) de la collection qu'est la page qui contieent ce code.
Comme l'indique le RFC 8288 (successeur du
RFC 5988), les liens peuvent se représenter
autrement qu'en HTML (toutes les ressources Web ne sont pas forcément
des pages en HTML), par exemple avec l'en-tête
HTTP Link:
. On peut donc
avoir dans une réponse HTTP :
HTTP/1.1 200 OK ... Link: <...>; rel="item"; title="View Product X001" Link: <...>; rel="item"; title="View Product X002"
En section 2.2, on trouve le deuxième type de lien celui qui, en sens inverse du précédent, va d'un élément vers la(les) collection(s) dont il est membre :
<a href="..." rel="collection">Return to Product Group X</a>
Là aussi, on peut utiliser les en-têtes HTTP :
HTTP/1.1 200 OK ... Link: <...>; rel="collection"; title="Return to Product Group X"
Les deux types ont été ajoutés au registre IANA.
Date de publication du RFC : Mars 2012
Auteur(s) du RFC : J. Gregorio (Google), R. Fielding (Adobe), M. Hadley (MITRE), M. Nottingham (Rackspace), D. Orchard (Salesforce.com)
Chemin des normes
Première rédaction de cet article le 28 mars 2012
Beaucoup d'applications Web utilisent des URI (RFC 3986) qui peuvent être décrits par un gabarit (template), avec des variables qui seront incarnées pour produire l'URI final. Ce RFC, issu d'une coopération entre l'IETF et le W3C normalise un langage (déjà largement déployé) pour ces gabarits.
La section 1.1 du RFC fournit quelques exemples d'URI obéissant à un gabarit. Par exemple, des pages personnelles identifiées par le tilde :
http://example.com/~fred/ http://example.com/~mark/
ou des entrées d'un dictionaire :
http://example.com/dictionary/c/cat http://example.com/dictionary/d/dog
ou encore un moteur de recherche :
http://example.com/search?q=cat&lang=en http://example.com/search?q=chien&lang=fr
À chaque fois, le patron de conception sous-jacent est assez clair. Le langage décrit dans ce RFC 6570 permet d'abstraire ce patron dans un gabarit d'URI. Les trois exemples cités plus haut pourront être décrits :
http://example.com/~{username}/ http://example.com/dictionary/{term:1}/{term} http://example.com/search{?q,lang}
Cela permet d'abstraire un URI, en montrant clairement au lecteur le processus de construction. Cela contribue donc à la création de beaux URL, qui ne sont pas simplement des identificateurs opaques, mais qui peuvent être compris par l'utilisateur du Web.
En dehors de l'intérêt intellectuel, quelle est l'utilité de ce
système ? Il permet notamment la création automatique d'URI, à partir
de gabarits et de valeurs pour les variables (comme la variable
term
dans le deuxième exemple ci-dessus). Les
protocoles fondés sur REST en seront
ravis. Ainsi, le gabarit
http://www.example.com/foo{?query,number}
combiné
avec les variables {query: "mycelium", number: 100}
va donner
http://www.example.com/foo?query=mycelium&number=100
. Si
query
n'était pas défini, cela serait simplement http://www.example.com/foo?number=100
.
Pour prendre des exemples réels, on peut décrire les URL
d'OpenStreetMap comme tirés du gabarit
http://www.openstreetmap.org/?{lon,lat}
et ceux
de Wikipédia comme faits à partir de
http://fr.wikipedia.org/wiki/{topic}
.
La section 1.2 explique qu'il existe en
fait plusieurs niveaux pour le langage de description de gabarits. Une
mise en œuvre donnée s'arrête à un certain niveau, les premiers
étant les plus simples. Le
niveau 1 fournit simplement l'expansion des
variables (qui sont placées entre accolades), avec échappement. Si
var
vaut "Bonjour le monde", l'expansion de
{var}
sera
Bonjour%20le%20monde
.
Le niveau 2 ajoute un opérateur
+
pour les variables
pouvant contenir des caractères spéciaux, et le
#
pour les identificateurs
de fragment. Si path
vaut "/foo/bar",
{path}
est expansé en
%2Ffoo%2Fbar
alors que
{+path}
donnera /foo/bar
. Et
avec la variable var
valant "Bonjour le monde", l'expansion de
{#var}
sera
#Bonjour%20le%20monde
permettant de construire
des URI avec un identificateur pointant vers un point précis du
document. Par exemple, les URL des Internet-Drafts
dans la file d'attente de l'éditeur des RFC ont
le gabarit
http://www.rfc-editor.org/queue2.html{#draftname}
avec, par exemple, draftname
égal draft-ietf-lisp
.
Au niveau 3, cela devient bien plus riche : on
a plusieurs variables dans une expression (le gabarit
map?{x,y}
devient l'URI
map?1024,768
si x=1024 et y=768). Et on gagne
surtout les paramètres multiples (séparés par
&) si utilisées dans les
formulaires Web : le gabarit
{?x,y}
devient
?x=1024&y=768
.
Enfin, le niveau 4 ajoute des modificateurs
après le nom de la variable. Par exemple, :
permet d'indiquer un nombre limité de caractères (comme dans le
term:1
que j'ai utilisé au début, qui indique la
première lettre). Et le *
indique une variable
composite (une liste ou un
dictionnaire) qui doit être elle-même
expansée. Si la variable couleurs
vaut la liste
{rouge, bleu, vert}, le gabarit (de niveau 1)
{couleurs}
donnera
rouge,bleu,vert
alors que la gabarit de niveau 4
{?couleurs*}
vaudra
?couleurs=rouge&couleurs=bleu&couleurs=vert
.
Des mécanismes similaires à ces gabarits existent dans d'autres
langages comme OpenSearch ou
WSDL. Par exemple, le gabarit décrivant les URL
du moteur de recherche de mon blog a la
forme http://www.bortzmeyer.org/search{?pattern}
et, dans dans sa description
OpenSearch, on trouve la même information (quoique structurée différemment).
Comme l'explique la section 1.3, cette nouvelle norme vise à unifier le langage de description de gabarits entre les langages, tout en restant compatible avec les anciens systèmes. Normalement, la syntaxe des gabarits d'URI est triviale à analyser, tout en fournissant la puissance expressive nécessaire. Il s'agit non seulement de générer des URI à partir d'un patron, mais aussi de pouvoir capturer l'essence d'un URI, en exprimant clairement comment il est construit.
La section 2 décrit rigoureusement la syntaxe. En théorie, un analyseur qui ne gère que le niveau 1 est acceptable. Toutefois, le RFC recommande que tous les analyseurs comprennent la syntaxe de tous les niveaux (même s'ils ne savent pas faire l'expansion), ne serait-ce que pour produire des messages d'erreurs clairs (« This feature is only for Level 3 engines and I'm a poor Level 2 program. » .
Cette section contient donc la liste complète des caractères qui ont une signification spéciale pour le langage de gabarits, comme +, ? ou &, ainsi que de ceux qui sont réservés pour les futures extensions (comme = ou @). En revanche, $ et les parenthèses sont exprèssement laissés libres pour d'autres langages qui voudraient décrire une part de l'URI.
Ensuite, la section 3 se consacre aux détails du processus d'expansion qui,
partant d'un gabarit et d'un ensemble de valeurs, va produire un
URI. Notez qu'une variable qui n'a pas de valeur ne donne pas un 0 ou
un N/A
ou quoi que ce soit de ce genre. Elle
n'est pas expansée. Donc, le gabarit {?x,y}
avec
x valant 3 et y n'étant pas défini, devient
?x=3
et pas
?x=3&y=NULL
. Si x n'était pas défini non
plus, le résultat serait une chaîne vide (sans même le point
d'interrogation).
Est-ce que ces gabarits peuvent poser des problèmes de sécurité ? La section 4 regarde cette question et conclus que cela dépend de qui fournit le gabarit, qui fournit les variables, et comment va être utilisé l'URI résultant (aujourd'hui, les mises en œuvre existantes les utilisent dans des contextes très variés). Par exemple, des variables contenant du code JavaScript peuvent être dangereuses si l'URI résultant est traité par ce langage. Des attaques de type XSS sont donc parfaitement possibles si le programmeur ne fait pas attention.
Pour les programmeurs, l'annexe A contient un ensemble de recommandations sur la mise en œuvre de ce RFC, ainsi qu'un algorithme possible pour cette mise en œuvre. Il existe plusieurs mises en œuvre de ce RFC. Malheureusement, toutes celles que j'ai essayées semblent limitées au niveau 1 et ne le disent pas clairement.
Le code Python en http://code.google.com/p/uri-templates/
(niveau 1 et un bout du niveau 2) :
import uritemplate import simplejson import sys vars = {"foo": "bar/"} def test_print(template): actual = uritemplate.expand(template, vars) print actual test_print("http://www.example.org/thing/{foo}") test_print("http://www.example.org/thing/{+foo}")
On obtient :
http://www.example.org/thing/bar%2F http://www.example.org/thing/bar/
Avec le module Perl URI::Template
(niveau 1), on peut écrire :
use URI::Template; my $template = URI::Template->new( 'http://example.com/{foo}' ); my $uri = $template->process( foo => 'Hello World/' ); print $uri, "\n";
Le code Haskell en http://hackage.haskell.org/cgi-bin/hackage-scripts/package/uri-template
(niveau 1 seulement) écrit ainsi :
module Main(main) where import Network.URI.Template testEnv :: TemplateEnv testEnv = addToEnv "foo" "Hello World/" $ addToEnv "x" "1024" $ addToEnv "y" "768" $ newEnv main :: IO () main = do putStrLn (expand testEnv "http://example.org/{foo}") return ()
Donne :
% runhaskell Test.hs http://example.org/Hello%20World%2f
Date de publication du RFC : Mars 2012
Auteur(s) du RFC : JM. Valin (Mozilla), S. Borilin
(SPIRIT DSP), K. Vos, C. Montgomery
(Xiph.Org Foundation), R. Chen (Broadcom Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF codec
Première rédaction de cet article le 27 mars 2012
Constatant l'absence d'un codec entièrement libre (pas plombé par des brevets, pas contrôlé par une société unique, implémentable en logiciel libre), l'IETF s'est lancée dans la spécification d'un codec satisfaisant. Le RFC 6366 donnait le cahier des charges technique du futur codec (le produit final, publié dans le RFC 6716) et ce nouveau RFC donne les considérations portant sur le processus de développement (processus déjà bien entamé) : méthodologie d'évaluation des propositions, mécanisme de vérification de la compatibilité des implémentations, questions de propriété intellectuelle. Une tâche difficile, accomplie dans une ambiance pas toujours sereine, les questions du multimédia étant toujours délicates.
Le développement d'un nouveau codec est une tâche d'ampleur, compte-tenu des exigences très strictes du RFC 6366 et du fait que le marché est déjà encombré de codecs complètement fermés, ou bien à moitié libres. L'IETF n'avait pas imposé que le codec libre soit entièrement nouveau : la sélection et/ou l'adaptation d'un codec existant sont des plans possibles. La section 2 du RFC résume le processus. Au moment où sort ce RFC, une partie des étapes a déjà été franchie. Les principales sont :
Comment s'assurer, tout au long du développement, que le codec sera
de qualité suffisante, pour ne pas avoir de mauvaise surprise à la fin
du projet ? Il faudra tester le logiciel au fur et à mesure (section
3) en utilisant des méthodes comme PESQ (norme
UIT P.862) et PEAQ (UIT BS.1387). Pour des changements
plus fondamentaux, il faudra utiliser les méthodologies d'évaluation
subjective comme MUSHRA (UIT BS.1534). Et, comme l'IETF
travaille depuis toujours dans un environnement ouvert, il faudra bien
sûr impliquer toute la communauté Internet dans ses essais (le code du
codec Opus est donc librement accessible en
http://git.xiph.org/?p=opus.git
). C'est d'autant plus
important que l'IETF n'a pas de « laboratoires de test » propres et
que tous les tests devront être faits à l'extérieur (une raison de
plus pour que l'implémentation de référence soit publiquement disponible).
La section 4 du RFC revient sur les détails de la spécification et sert de guide aux auteurs du futur RFC. Elle précise notamment ce que devrait imposer la spécification et ce qui devrait être laissé aux décisions des programmeurs. D'abord, la décision est prise que l'implémentation de référence aura le pas sur le texte de la spécification, en cas de désaccord. C'est inhabituel à l'IETF, où la règle est en général l'inverse, pour éviter que les particularités d'une implémentation ne figent la norme. Mais le monde des codecs est très complexe et la spécification complète et parfaite un art difficile. Au moins, en décrétant que « le code fait la loi », on est sûr d'avoir une référence précise en cas de litige.
Le principe général sera d'essayer de limiter les obligations dans la norme, donc de ne pas abuser des MUST du RFC 2119. En pratique, cela veut dire que seul le décodeur du flux audio aura besoin d'être rigoureusement défini, les encodeurs pourront s'améliorer avec le temps et faire des choix radicalement différents.
Avoir un programme comme description faisant autorité présente plusieurs risques. L'un d'eux est de « sur-spécification » : faudra-t-il qu'une implémentation compatible donne le même résultat, au bit près, que l'implémentation de référence ? Cela rendrait très difficile le travail des programmeurs pour certaines architectures (le couple CPU/DSP ne permet pas forcément de produire un résultat au bit près, en tout cas pas en gardant des performances maximales). Le principe est donc qu'il n'est pas nécessaire de faire exactement comme le programme de référence, mais de faire quelque chose qui n'est soit pas distinguable à l'oreille.
La section 5 est consacrée au problème douloureux mais, dans le secteur du multimédia, indispensable, de la propriété intellectuelle. Les effets néfastes de celle-ci sur la mise en œuvre et le déploiement des codecs audios sont bien connus. Par exemple, les coûts de licence des brevets éliminent les petits acteurs, qui sont souvent à l'origine de l'innovation. En outre, même si les conditions de la licence sont raisonnables financièrement, elles sont souvent incompatibles avec le logiciel libre (par exemple, exiger une licence pour la distribution, même si la licence est gratuite, empêche l'intégration du logiciel dans un logiciel libre, qui ne met aucune restriction à la distribution).
Bref, libre, c'est mieux que contraint. Des tas de codecs tout à fait valables techniquement posent des problèmes légaux, qui limitent leur déploiement. L'IETF rappelle donc dans ce RFC sa préférence pour des techniques non plombées par la propriété intellectuelle. Le problème est difficile à résoudre car à peu près tout a été breveté (les organismes de dépôt des brevets ne font aucun effort pour refuser les brevets futiles). Même si l'IETF adopte un codec qui semble non breveté, rien ne garantit qu'il ne sera pas frappé soudainement par un brevet sous-marin, un brevet auquel son détenteur ne donne aucune publicité, attendant qu'il soit déployé pour réclamer de l'argent.
Compte-tenu des brevets futiles (qui couvrent à peu près tous les algorithmes possibles et qu'on ne peut invalider que par un long et incertain procès), compte-tenu de l'état de l'art en matière de codec, compte-tenu du fait qu'une technologie peut être brevetée dans certains pays et pas d'autres, l'IETF ne promet donc pas de normaliser un codec complètement libre, ce qui serait une mission impossible (à part peut-être en se limitat à de très vieux codecs, conçus il y a tellement longtemps que tous les brevets ont forcément expiré). Mais elle promet de chercher sérieusement (même si les codecs libres ont de moins bonnes performances techniques) et, dans le pire des cas, de préférer les codecs où les licences des brevets sont gratuites (RF, pour royalty-free). Rappelez-vous toutefois que le plus gros problème pour obtenir une licence n'est pas forcément l'argent, cela peut être le processus bureaucratique de longues négociations avec un bataillon d'avocats qui ont beaucoup de temps libre et vous font lanterner. Il y a des licences gratuites qui coûtent très cher en temps passé !
Cela suppose évidemment que l'IETF soit au courant des brevets existants. Les participants à l'IETF doivent l'informer des brevets qu'ils connaissent (RFC 3979, section 6). Mais cette règle a déjà été violée. Par exemple, dans le cas du groupe de travail Codec, Huawei n'a publié son brevet US 8,010,351 que bien tard, en affirmant qu'il était dans le portefeuille d'une entreprise récemment acquise par Huawei.
D'autres SDO travaillent sur des codecs. Comment l'IETF doit-elle gérer ses relations avec ces organisations (section 6) ? On trouve dans la liste l'UIT (notamment le Study Group 16), le groupe MPEG de l'ISO, ETSI, 3GPP... L'IETF a déjà pris position nettement contre la concurrence des SDO et le développement non coordonné de protocoles, dans le RFC 5704. Ce RFC pose comme principe que, pour chaque protocole ou format, une et une seule SDO doit être responsable. Mais ce n'est pas un problème ici. Soit le groupe de travail codec approuve un codec existant, géré par une autre SDO et celle-ci continuera comme avant, l'IETF aura juste dit « le codec préféré de l'IETF est le codec XXX ». Soit l'IETF développe un nouveau codec (éventuellement dérivé, mais différent, d'un codec existant) et il n'y aura alors pas de concurrence. Les règles du RFC 5704 découragent le concurrence pour un même format ou protocole, pas pour une même catégorie (deux organisations peuvent travailler sur deux codecs différents, même si ces deux codecs visent le même « marché »).
L'IETF appelle bien sûr les experts en codecs audio des autres SDO à donner leur avis sur son travail mais considère que ce n'est pas indispensable : le groupe codec rassemble d'ores et déjà suffisamment de compétences. Cette participation éventuelle des autres SDO peut prendre la forme de contributions individuelles (un expert peut être membre à la fois du SG16 de l'UIT et du groupe codec de l'IETF), ou par le mécanisme plus formelle des liaisons. En tout cas, il existe des choses utiles chez les autres SDO (par exemple dans les mécanismes de test), comme documenté dans le RFC 3356.
Je l'ai indiqué, le groupe de travail codec a travaillé sous forte pression. Parmi les trolls des débats, je me souviens de la proposition que le problème du coût des licences soit relativisé, car un codec techniquement supérieur fait économiser de la capacité réseau (meilleure compression) et donc justifie de payer une licence...
Actuellement, dans la catégorie « nouveaux codecs », le groupe de travail n'a qu'un seul candidat, Opus (autrefois nommé Harmony) et qui a donc été normalisé finalement en septembre 2012 (RFC 6716). Si vous vous intéressez aux tests pratiques de ce codec, voir le document Summary of Opus listening test results.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : E. Kim (ETRI), D. Kaspar (Simula Research Laboratory), N. Chevrollier (TNO), JP. Vasseur (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6lowpan
Première rédaction de cet article le 1 mai 2012
Vous ne connaissez pas encore le terme de LowPAN ? Ce n'est pas grave, c'est encore assez rare. Un LowPAN est un Low-Power Wireless Personal Area Network. En gros, c'est un ensemble de petites machines (très petites : pas des ordinateurs), disposant de peu de puissance électrique, connectées souvent sans fil, et cherchant à communiquer. Le groupe de travail IETF 6lowpan établit des normes de communication pour ces LowPAN, en utilisant IPv6 (d'où le 6 au début de son nom). Ce document est son quatrième RFC. Il explique les principes de base de son travail, à travers des scénarios d'utilisation des LowPAN.
Un LowPAN typique va être, dans une exploitation agricole, l'ensemble des capteurs qui mesurent l'humidité, et des actionneurs qui déclenchent l'arrosage. La section 1 explique les douleurs du LowPAN : machines ayant peu de ressources (processeur, mémoire, courant), et connectées par des liens lents et sujets aux parasites et aux coupures (WiFi, CPL). En général, on veut en prime que ces machines soient peu chères. Résultat :
Bref, on est très loin des ordinateurs portables ou même des smartphones. Et c'est pourtant dans ces machines qu'il va falloir faire tenir le code réseau. Deux bonnes lectures sur ces environnements si différents des machines sur lesquelles l'Internet a commencé : le RFC 4919 décrit plus en détail le monde des LowPAN, le RFC 4944 normalise l'utilisation d'IPv6 sur IEEE 802.15.4.
Il existe en fait beaucoup de LowPAN différents. Suivant le document « The Design Space of Wireless Sensor Networks », la section 2 du RFC explique les axes sur lesquels se différencient les LowPAN : déploiement conçu dès le début ou bien incrémental, taille du réseau (10 machines ou 1000 ?), connectivité permanente ou intermittente (ce qui est courant lorsque les machines se déplacent), etc.
Bien, maintenant, assez de précautions, place au cœur du RFC, la section 3. Elle expose une partie des scénarios d'usage des LowPAN. Par exemple, en section 3.1, figure un usage souvent cité, la surveillance de bâtiments industriels. L'idée est que les capteurs dispersés un peu partout dans les bâtiments deviennent communiquants. Au lieu d'être relevés manuellement par un humain faisant sa ronde, ils transmettront d'eux-mêmes les résultats des mesures. De très nombreuses mesures peuvent être envisagées, comme les vibrations d'une machine (trop intenses, elles indiquent un problème) ou la température dans les entrepôts (attention à conserver la chaîne du froid). Les communications sans-fil sont ici cruciales car certaines parties de l'usine peuvent être difficiles à atteindre pour les câbles.
Comme exemple précis de ce type de surveillance, le RFC cite les salles de stockage d'un hôpital. Les globules rouges doivent être stockés entre 2 et 6°, les plaquettes entre 20 et 24°, et le plasma à -18°. Les capteurs de température sont disposés tous les 25 mètres environ, chaque emballage a une étiquette et des nœuds 6LowPAN sont placés dans les palettes. Par rapport aux axes de classification cités plus haut, on a un cas de déploiement planifié, avec un réseau de taille moyenne mais très dense, et peu de déplacements. Le débit attendu est faible mais les données peuvent être urgentes (alerte de réchauffement, par exemple). Les exigences de sécurité sont élevées. 6LowPAN peut-il convenir ? Oui, analyse cette section.
Autre cas, celui de la surveillance d'un bâtiment, pour veiller à son intégrité (section 3.2). Par exemple, un pont est construit et est truffé de capteurs et de machines LowPAN qui relèvent les capteurs et transmettent à un contrôleur. Le RFC part d'un pont de 1 000 m de long, avec 10 piliers. Chaque pilier a 5 capteurs pour mesurer le niveau de l'eau sont le pont et 5 autres qui mesurent les vibrations. Les machines LowPAN ne sont pas gênées par les murs du bâtiment, comme dans l'exemple précédent, et peuvent se voir à 100 m de distance. Tout est placé manuellement (attention à ne pas avoir un pilier dans la LoS) et ne bouge pas.
Le réseau est cette fois de petite taille, très statique. Mais sa sécurité est vitale. Dans ce cas simple, 6LowPAN convient bien (il faut juste faire attention aux placements des engins sur les piliers).
Pas d'article ou de document sur les LowPAN sans l'inévitable bla-bla sur la domotique et ses promesses d'un monde merveilleux où le réfrigérateur détectera la fin proche du stock de bières et en commandera d'autres. C'est le rôle ici de la section 3.3. Après la santé et les transports, où des vies humaines sont en jeu, cette section se penche sur le confort de l'occidental rose moyen, qui veut que sa maison high-tech s'occupe de tout pendant qu'il regarde le match de foot à la télé.
Il y a beaucoup de choses à mesurer dans une maison, la température, l'humidité, l'état des portes (ouvert ou fermé), la vidéo-surveillance (pendant qu'on est dans les délires de mauvaise science-fiction, transformons la maison en bunker avec caméra braquée sur les quartiers sensibles). En combinant avec l'idée de « Smart Grid » (réseau de distribution électrique doté de capacités de mesure et de transmission de l'information), on peut aussi imaginer de connecter ces informations avec celle du réseau électrique.
Du point de vue technique, les murs de la maison feront souvent obstacle aux communications sans fil. Le réseau devra donc permettre le routage, pour le cas où la machine qu'on veut joindre n'est pas directement visible (« Multi-hop routing »). Les fonctions de ce réseau de gadgets ne sont pas vitales, cette fois. Par contre, l'ergonomie est cruciale, le réseau devra être très simple à administrer.
Autre scénario d'usage, en section 3.4, l'assistance médicale. L'idée est de mettre les capteurs sur et dans le patient, de manière à pouvoir surveiller son état à tout moment. Pour une personne âgée à la maison, on peut imaginer quelques capteurs portés à même le corps et qui mesurent des choses commes les battements cardiaques, et d'autres capteurs dans la maison, captant les mouvements, par exemple pour pouvoir donner l'alerte en cas de chute. Les enjeux de sécurité, notamment de protection de la vie privée, sont très importants. Si le LowPAN est ici de petite taille, et que la mobilité est limitée, les contraintes de bon fonctionnement sont essentielles, puisqu'une vie humaine peut être en jeu.
Un scénario dans un univers plus technique est celui de l'automobile (section 3.5). Les nœuds LowPAN peuvent être inclus dans la route au moment de sa construction et surveiller les véhicules qui passent. Cela pose un sacré problème de durée de vie puisque les nœuds vont devoir durer autant que la route (typiquement, dix ans, avant la première réfection sérieuse qui permettra de les changer). Malgré cela, avec le temps, la densité des capteurs diminuera, au fur et à mesure des pannes. Les machines LowPAN de la route seront nombreuses mais statiques, celles des véhicules peu nombreuses mais très mobiles.
Enfin, le dernier exemple est un peu plus vert, puisqu'il concerne l'agriculture (section 3.6), celle qui, selon Jared Diamond, est à la base de la force des empires. L'idée est de mesurer à distance, via de nombreux capteurs, l'humidité, la température et l'état du sol, de manière à appliquer l'irrigation ou les pesticides au bon moment. Le RFC prend l'exemple d'une vigne de bonne taille (dans les huit hectares) où 50 à 100 machines de contrôle piloteront des centaines de capteurs. La principale difficulté, pour ces derniers, sera de résister à des conditions hostiles dehors (humidité, poussière, hommes et machines qui passent en permanence et font courir des gros risques aux fragiles capteurs), etc. Heureusement, les exigences de sécurité sont cette fois bien plus basses.
En parlant de sécurité, la section 4 y est entièrement consacrée. Elle rappelle que les machines d'un LowPAN sont souvent exposées dehors, et donc physiquement accessibles à un éventuel attaquant. Les méthodes de sécurisation doivent tenir compte de cela. La communication entre les machines du LowPAN est souvent par radio, médium qui n'offre aucune sécurité, permettant à l'attaquant de capter tout le trafic, voire d'injecter de fausses données. La cryptographie devient alors nécessaire.
Mais les machines d'un LowPAN ont des ressources, notamment d'énergie, très limitées. Elles sont donc vulnérables aux attaques par déni de service : des requêtes répétées et hop, la batterie est à plat. À cause de cela, les techniques de sécurité adoptées doivent être légères et ne pas abuser des ressources très limitées de ces petits engins. Par exemple, IPsec est probablement exagéré pour ces environnements, en raison des calculs qu'il entraîne. Cela doit évidemment s'adapter à l'usage envisagé : le nœud LowPAN qui allume une lampe n'a pas les mêmes contraintes de sécurité que celui qui contrôle un stimulateur cardiaque.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : S. Krishnan (Ericsson), j h. woodyatt (Apple), E. Kline (Google), J. Hoagland (Symantec), M. Bhatia (Alcatel-Lucent)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 10 avril 2012
IPv6 permet l'insertion, entre l'en-tête de taille fixe du paquet, et les données de la couche 4, d'un ou plusieurs en-têtes d'extensions, qui modifient le comportement du paquet. L'analyse de ces en-têtes d'extension par un programme a toujours été difficile car ils n'ont pas un format cohérent. Ce RFC résout le problème en décrétant que, au moins pour les futurs en-têtes, ils devront suivre un format identique, permettant de les sauter sans même en comprendre le contenu.
Ces en-têtes d'extension sont normalisés dans la section 4 du RFC 2460. La plupart suivent le schéma « un octet pour indiquer le type de l'en-tête suivant, un octet pour indiquer la longueur de cet en-tête, puis les données » mais pas tous (notamment, l'en-tête de fragmentation a une syntaxe différente). Si on veut écrire un programme d'analyse des paquets IPv6, on doit donc connaître tous les types d'en-tête (il n'y en a, après tout, pas beaucoup) et traiter chacun spécialement. Mais cela ne résout pas le problème des futurs en-têtes : si un nouvel en-tête est créé (comme cela avait été le cas dans le RFC 5533), et qu'il commence à apparaître sur le réseau, les programmes d'analyse vont souffrir.
Outre les programmes d'analyse, on peut citer d'autres logiciels qui souhaitent regarder à l'intérieur des paquets, y compris avant que le paquet n'atteigne sa destination (section 1 du RFC). Par exemple les pare-feux veulent accéder à la couche transport, et ils doivent le faire à la vitesse du réseau physique (si on a un Ethernet 1 Gb/s, on veut que les paquets soient analysés au même rythme), ce qui implique le recours à des circuits électroniques relativement simples (les ASIC) qui n'ont pas la possibilité de faire tourner du code arbitrairement complexe. Or, aujourd'hui, tout nouvel en-tête IPv6 est à peu près sûr d'invalider ces pare-feux.
Ne peut-on pas s'en tirer en disant qu'il vaut mieux éviter de définir de nouveaux en-têtes d'extension ? C'est l'option que rappelle la section 3, qui note que l'en-tête Destination Options (section 4.6 du RFC 2460) est déjà très général : il permet d'inclure plusieurs options différentes, chacune identifiée par son type et encodée sous forme TLV. Le RFC recommande donc que les concepteurs de nouvelles idées pour IPv6 réutilisent l'en-tête Destination Options autant que possible. Au cas où un concepteur de protocole décide de créer un nouvel en-tête, il doit désormais expliquer en détail pourquoi l'en-tête Destination Options ne convient pas à son but.
Notez que l'en-tête Destination Options, comme son nom l'indique, ne doit normalement être traité que par la machine de destination (les routeurs, notamment, n'ont pas besoin de le gérer ou de le connaître, sauf à des fins de statistique). Si on veut transporter des options qui sont analysées par les routeurs, on a l'en-tête Hop-by-hop Options. En pratique, il n'est pas du tout évident que ce dernier fonctionne : comme chaque routeur du trajet doit en tenir compte, il ouvre une voie d'attaque possible et il semble que bien des routeurs l'ignorent complètement, voire jettent sans autre forme de procès les paquets qui le contiennent. Quoi qu'il en soit, notre RFC 6564 précise qu'il ne faut pas créer de nouveaux en-têtes ayant cette sémantique « examen par chaque routeur ». Non seulement la création d'en-têtes est déconseillée, mais elle ne doit se faire qu'avec la sémantique « examen par la destination seulement ».
Bien, maintenant qu'on a sérieusement refroidi les concepteurs de protocole qui auraient pensé à créer un nouvel en-tête, la section 4 fixe les règles à suivre au cas où on ne serait pas encore découragé. Les éventuels nouveaux en-têtes devront désormais tous suivre le modèle de la plupart des en-têtes existants et commencer par un octet indiquant l'en-tête suivant (typiquement, cela sera les données de la couche Transport, les valeurs possibles sont dans un registre), puis un octet indiquant la longueur de l'en-tête. Cela devrait rendre un peu plus facile l'analyse des futurs en-têtes, s'il y en a de créés.
Rappelez-vous que cela n'affecte que les futurs en-têtes. Pour analyser les existants (notamment l'en-tête Fragment qui ne suit pas ce schéma, cf. section 5), il faut garder le code existant. La section 6 rappele d'ailleurs que le traitement des en-têtes reste un problème pas complètement résolu pour les équipements intermédiaires, par exemple parce qu'il peut y avoir plusieurs en-têtes, chaînés, parce que leur ordre est important, et parce que le traitement des en-têtes peut influer celui de la charge utile. Personnellement, je pense que la première mise en œuvre d'IPv6 qui essaiera d'utiliser vraiment les en-têtes aura de vilaines surprises... Cela sera encore pire avec un nouvel en-tête, qui ne fait pas partie des anciens.
Notez aussi que tout le problème traité par ce RFC a une faible importance pratique : on ne trouve quasiment pas d'en-têtes d'extension dans les paquets IPv6 qui circulent aujourd'hui.
Donc, désormais, une implémentation d'analyse d'IPv6 (comme la mienne, que j'ai eu la flemme de modifier) peut adopter la stratégie suivante :
Date de publication du RFC : Mars 2012
Auteur(s) du RFC : S. Jiang (Huawei), D. Conrad (Cloudflare), B. Carpenter (Univ. of Auckland)
Pour information
Première rédaction de cet article le 13 mars 2012
Un peu de rangement dans le DNS : en
2000, un nouveau type d'enregistrement DNS, le
A6
, avait été créé pour gérer plus facilement les
adresses IPv6 dans le DNS. N'ayant finalement
pas marché comme espéré, il vient d'être officiellement abandonné. Le
RFC 2874, qui le normalisait, devient « intérêt historique seulement ».
Le type officiel pour représenter les adresses
IPv6 dans le DNS était
le AAAA
, introduit par le RFC 1886
(aujourd'hui RFC 3596). Très proche du type
A
d'IPv4, il n'offrait pas
de services particuliers, par exemple pour gérer la rénumérotation
d'un réseau. Si on avait dans son fichier de zone :
www IN AAAA 2001:db8:33::1 mail IN AAAA 2001:db8:33::fada
et qu'on passe du réseau 2001:db8:33::/48
au
2001:db8:bad::/48
, il fallait faire un
rechercher/remplacer pour changer toutes les adresses. Le type
A6
, du RFC 2874, fournissait un système
plus souple, découplant le préfixe et l'adresse.
Évidemment, le fait d'avoir deux types pour les adresses IPv6 a
entraîné pas mal de confusion (section 2.5). Il est même possible que cela ait
contribué au retard du déploiement d'IPv6. En
2002, les RFC 3363 et RFC 3364 critiquaient A6
et il était reclassé
« expérimental ». Cela n'a apparemment pas suffit à éclaircir les
choses et notre RFC 6563 met aujourd'hui
A6
comme « d'intérêt historique seulement », ce
qui devrait enlever toute ambiguité. Le seul type pour représenter les
adresses IP dans le DNS est donc AAAA
.
Mais que reprochait-on à A6
, finalement ? La
section 2 de ce RFC résume les principaux problèmes (le RFC 3363 donne davantage de détails) :
A6
implique plusieurs requêtes DNS
non-parallélisables, et sur des
serveurs différents),A6
était de permettre de déléguer plus facilement, en mettant les
différents enregistrements nécessaires dans des organisations
différentes. Mais l'expérience d'A6
(comme celle
des enregistrements de colle dans la zone parente, ou celle des
PTR
de in-addr.arpa
) a
montré qu'il était très difficile de synchroniser de tels
enregistrements « trans-frontières » et qu'ils se prêtaient mal à
l'automatisation,A6
peut affecter de nombreuses adresses
IP, qu'on ne voit pas (le reste des données peut être dans une autre
zone, et même avoir des TTL différents, rendant
la prévision des résultats difficile),La section 3 décrit l'usage effectif d'A6
,
depuis que certaines versions de BIND (de 9.0 à
9.2, puis abandonné dans les versions ultérieures) ont
ajouté la gestion de ce type d'enregistrements. De même, certaines
versions de la GNU libc ont fait des requêtes
A6
. Mais, aujourd'hui, l'analyse du trafic
sur deux serveurs DNS de la racine montre très peu de trafic
a6
Les statistiques sur les serveurs de
.fr
gérés par
l'AFNIC montrent que A6
n'a pas disparu. Il ne fait certes
que 0,2 % des requêtes (contre 8 % pour AAAA
)
mais il est le dixième type d'enregistrement
demandé, devant des types comme SPF
, SSHFP
,
NAPTR
ou DNSKEY
, normalement bien plus
« officiels ». Cela illustre le conservatisme des administrateurs
système (qui gardent en production de très vieilles versions de leurs logiciels).
La section 4 expose les conséquences de la reclassification de
A6
comme n'ayant qu'un intérêt historique. Les
gérants de zone DNS doivent retirer ces enregistrements (s'ils
existaient encore), les clients DNS doivent arrêter de demander des
A6
et les
serveurs DNS doivent désormais traiter ce type comme inconnu (RFC 3597) lors de la réception d'une requête. (Le type
A6
faisait partie de ceux pour lesquels le
serveur DNS devait faire un traitement spécial.) Comme c'est déjà
largement le cas, ce RFC n'aura sans doute pas de conséquence pratique.
Date de publication du RFC : Mars 2012
Auteur(s) du RFC : J. Livingood (Comcast), N. Mody (Comcast), M. O'Reirdan (Comcast)
Pour information
Première rédaction de cet article le 20 mars 2012
Une des plus grosses menaces sur la sécurité de l'Internet réside dans les zombies, ces machines Windows contaminées par du logiciel malveillant et qui obéissent désormais à un maître qui leur ordonne, selon sa volonté, de lancer une dDoS, d'envoyer du spam, etc. Ce RFC documente le point de vue d'un gros FAI, Comcast, sur le problème. La partie que je trouve la plus riche est celle sur le difficile problème de la notification des utilisateurs.
Il n'existe pas de solution miracle contre les zombies. C'est comme cela que je lis ce document qui, malgré son nom, propose peu de remèdes. Et certaines des solutions relèvent plus d'une logique « business » (se débarrasser d'un problème) que d'une volonté d'améliorer l'Internet (le document se réclame du MAAWG, cartel de gros opérateurs très tentés par le nettoyage civilisateur).
Le RFC commence par un peu de terminologie (section 1). Bot est l'abrévation de robot et désigne dans ce RFC un zombie, une machine qui n'obéit plus à son propriétaire légitime mais au « maître des zombies » (bot master), qui les contrôle à distance. Le logiciel qui transforme une innocente machine en zombie a typiquement été installé en trompant l'utilisateur (« Click here to install over 200 000 HOT pictures of REAL CHICKS! »), ou bien en profitant d'une faille de sécurité de ses logiciels, ou encore en essayant plein de mots de passe jusqu'à en trouver un qui marche. Le RFC note qu'il existe des gentils robots (par exemple pour interagir automatiquement sur les canaux IRC) mais qu'il ne se consacre qu'aux méchants, aux robots malveillants. Petite colère au passage : le mot anglais malicious veut dire « malveillant » et pas « malicieux » comme on le voit souvent stupidement traduit.
Les bots sont ensuite regroupés en bandes, les botnets, un groupe de zombies obéissant au même maître. Les activités des botnets sont très variées, envoi de spam, de spim, de spit, dDoS, hébergement de relais ou de sites de hameçonnage, hébergement de contenu illégal, fraude aux clics, etc.
Pendant longtemps, le protocole de communication favori des bot herders (ceux qui créent les botnets et les entretiennent) était IRC (RFC 1459). Muni d'une seule machine maître (le C3C, Command and Control Center), le botnet était assez facile à neutraliser : une fois le maître déconnecté, les zombies ne savaient plus quoi faire. Aujourd'hui, les botnets sont plus perfectionnés : utilisation de protocoles plus variés (HTTP, plus discret et moins filtré, a remplacé IRC), souvent en pair à pair, le tout largement chiffré.
Quelles sont les conséquences des actions du botnet ? Pour les victimes (ceux qui reçoivent le spam ou qui sont attaqués par déni de service), elles sont évidentes (pour le spam, voir « Spamalytics: An Empirical Analysis of Spam Marketing Conversion »). Pour l'utilisateur de la machine, c'est surtout la consommation de ressources, qui diminue les performances attendues. Mais pour le FAI, ces zombies ont aussi un coût : capacité réseau utilisée mais aussi atteinte à la réputation du FAI. Ses adresses IP courent un risque élevé de se retrouver sur des listes noires dont il est difficile de sortir. Certaines des opérations du botnet peuvent mettre en danger des ressources Internet critiques (voir le « Emerging Cyber Threats Report for 2009 » et « Distributed Denial of Service Attacks: Explanation, Classification and Suggested Solutions" »).
Le FAI est évidemment bien situé pour détecter la présence de bots, et pour prévenir les utilisateurs. Notons toutefois que, le concept de neutralité du réseau étant tabou chez les FAI, les risques pour ladite neutralité si le FAI s'engage dans ce combat ne sont pas mentionnés dans le RFC.
Personne ne pense bien sûr que des solutions parfaites existent : la lutte entre les bot herders d'un côté, et les FAI et les utilisateurs de l'autre, n'est pas près de se terminer. Toutefois, affirme le RFC dans sa section 2, on peut espérer limiter les dégâts et réduire la taille des botnets, les rendant ainsi moins dangereux.
La section 3, consacrée à doucher les éventuels enthousiasmes, dit d'ailleurs bien que l'éradication des bots est une tâche difficile. Elle note que la seule méthode parfaite sur une machine est « Réinstallez votre système d'exploitation », un remède assez radical et donc peu susceptible d'être suivi... Et le RFC fait remarquer que même cette approche ne suffit pas (voir l'exposé « Persistent BIOS Infection », ou le cas d'engins fermés, comme certains smartphones ou consoles de jeu, où l'utilisateur n'a même pas la liberté d'installer le système d'exploitation).
Maintenant, place à l'action. La première étape est de détecter les zombies dans le réseau. Cela peut se faire par l'analyse passive du trafic, ou bien par les plaintes, même si peu de FAI les traitent. Idéalement, ces plaintes devraient être transmises sous un format structuré, permettant leur analyse automatique, comme les formats ARF (RFC 5965) ou IODEF (RFC 7970). Le document évoque aussi la possibilité de recherches actives, comme le permet un outil comme nmap, bien que de telles recherches ne soient pas forcément légales (cela dépend du pays, note le RFC). Le RFC déconseille néanmoins ces méthodes actives, pas tant sur leur caractère intrusif que sur leur inefficacité (le bot ne va pas forcément se signaler lors du balayage).
Le RFC insiste sur la nécessité de détecter vite, si nécessaire au détriment de la justesse des résultats (tirer d'abord, réflechir ensuite...)
Parmi les techniques passives disponibles, le document cite aussi l'analyse des flux Netflow (RFC 3954, mais depuis remplacé par le IPFIX du RFC 5470) ou bien les méthodes à base de DNS, très à la mode en ce moment, notamment grâce au travail des chercheurs de Georgia Tech (voir par exemple David Dagon, Wenke Lee, « Global Internet Monitoring Using Passive DNS », Cybersecurity Applications & Technology Conference for Homeland Security, 2009). Ces méthodes fondées sur l'observation du trafic DNS ont été utilisées dans le cas de Conficker (les zombies font des demandes de résolution pour les noms de domaine générés par l'algorithme de Conficker, ce dernier n'utilisant pas de noms câblés en dur, cf. l'excellent rapport « An Analysis of Conficker's Logic and Rendezvous Points »). Mais combien de FAI, qui n'arrivent déjà pas à fournir un service correct à leurs utilisateurs, ont les moyens, la compétence et le temps de mener ce genre d'études ?
Idéalement, le FAI devrait non seulement détecter mais également identifier l'infection spécifique, les remèdes pouvant varier.
La partie la plus intéressante du RFC, à mon avis, concerne la notification des utilisateurs. Comment les prévenir que leur machine, infectée, est devenue un zombie ? Et le faire de façon à ce qu'ils comprennent et agissent ? Toutes les techniques de communication possibles avec les utilisateurs sont soigneusement passées en revue, mais aucune ne semble parfaite.
Voici donc les principales techniques envisagées :
http://igotyou.biz/phishing.asp
pour indiquer vos
coordonnées »...). Ce dernier point est notamment développé en section
9 : il est très difficile d'imaginer un système de notification qui
ne puisse pas être détourné par les hameçonneurs.18:03:73:66:e5:68
est infectée par un logiciel
malveillant. Son propriétaire est prié de la désinfecter de toute
urgence. » Cela peut être utile dans ces environnements, où
l'administrateur du réseau n'a pas de lien particulier avec ses
utilisateurs et ne sait pas comment les contacter.À noter que toutes ces méthodes ne produisent pas de bons résultats au cas, le plus fréquent aujourd'hui, où les adresses IP sont partagées. Dans une entreprise de 500 personnes, montrer la notification aux 500 utilisateurs alors que seul l'administrateur système peut agir est probablement contre-productif. Si le FAI connaît les coordonnées dudit administrateur, il vaut certainement mieux lui écrire directement.
Cette discussion (section 5) des difficultés à attirer l'attention de ses propres clients sur un problème sérieux est la plus concrète du document. Mais elle pose plus de questions qu'elle n'apporte de réponses. Vous vous demandez peut-être quelle solution a finalement retenue Comcast ? Décrite dans le RFC 6108, elle consiste à modifier le contenu des pages Web vues par l'utilisateur pour y insérer une fenêtre-polichinelle d'avertissement.
La seule section qui ait un rapport direct avec le titre (section 6), sur les remèdes est, par contre, très courte, peut-être à juste titre, étant donné la difficulté à traiter les zombies. On les a détecté, on a notifié l'utilisateur, maintenant, que faire ? Le RFC suggère aux FAI de créer un site Web dédié à cet usage, où utilisateurs et administrateurs système pourront accéder à diverses documentations et outils. Les textes visant les utilisateurs sont difficiles à écrire : il faut les motiver pour agir (le bot peut être très discret, et l'utilisateur n'a alors rien détecté de problématique pour lui), sans les paniquer, et il faut expliquer rapidement car l'utilisateur ne lira pas de longs textes. Le RFC cite comme exemple d'introduction pour capter l'attention : « What is a bot? A bot is a piece of software, generally installed on your machine without your knowledge, which either sends spam or tries to steal your personal information. They can be very difficult to spot, though you may have noticed that your computer is running much more slowly than usual or you notice regular disk activity even when you are not doing anything. Ignoring this problem is risky to you and your personal information. Thus, bots need to be removed to protect your data and your personal information. »
La tâche de désinfection peut être difficile (surtout sur des engins comme les consoles de jeu, qui ne donnent typiquement pas accès au système) et, dans tous les cas, l'utilisateur n'a en général pas de compétences techniques : les instructions de désinfection doivent donc être très concrètes et détaillées.
Donc, sous forme d'une liste, voici quelques-unes des étapes que le RFC recommande de ne pas oublier, dans les conseils donnés aux utilisateurs :
Et si l'utilisateur ne peut pas ou ne veut pas réparer (section 7) ? Le RFC note que c'est évidemment un problème non-technique et a une approche très états-unienne, « shoot them » (supprimer l'abonnement et déconnecter l'utilisateur).
Le document rend aussi un hommage obligatoire à la nécessite de préserver la vie privée des utilisateurs (sections 4 et 10), sans trop s'attarder sur comment concilier surveillance rapprochée et respect de la vie privée. Un intéressant problème à la fois politique et légal. Voir aussi la section 8 sur les problèmes que pose le partage de données entre l'utilisateur, le FAI et éventuellement les autorités. L'annexe A donne une liste d'organisations privées qui peuvent être intéressés par ces données (liste de machines infectées, pour faire une liste noire, par exemple) et les publier.
À noter qu'une autre faiblesse de ce document est que, pour éviter de déchaîner les avocats de Microsoft, le fait que la quasi-totalité des zombies soient aujourd'hui des machines Windows est tout simplement absent...
Date de publication du RFC : Février 2012
Auteur(s) du RFC : E. Lear, P. Eggert
Première rédaction de cet article le 3 mars 2012
Vous aviez peut-être suivi l'affaire il y a quelques mois : une société d'astrologie (!) a fait un procès au responsable de la base de données des fuseaux horaires, base utilisée ensuite par des tas de logiciels dans le monde (notamment les logiciels libres). La société prétendait qu'elle était propriétaire des données. Comme le responsable de la base, Arthur David Olson, est un simple individu, sans moyens financiers (la justice, c'est seulement pour les riches), il a cédé. Désormais, cette base est gérée par l'IANA, et ce RFC documente les procédures de gestion.
La solution trouvée, confier cette base à l'ICANN, permet au moins de se mettre à l'abri des trolls, l'ICANN ayant beaucoup d'argent et d'avocats. Au moins, les millions de dollars stockés par l'ICANN, à titre de précaution juridique en cas de procès vont servir à quelque chose d'utile. Mais, en attendant, c'est un nouveau pan de la gouvernance de l'Internet qui passe d'un volontaire bénévole, aidé par quelques internautes, à une grosse bureaucratie politicienne, très lente et très chère.
Le registre est donc désormais en ligne à l'IANA. La section 7 du RFC discute les questions de propriété intellectuelle associées.
Quelques articles sur le sujet :
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : F. Baker (Cisco)
Pour information
Première rédaction de cet article le 7 avril 2012
Le problème du bonheur des globes oculaires (eyeball happiness) fait l'objet de recherches actives en ce moment. Il s'agit de s'assurer que, lorsqu'un service Internet (par exemple un site Web) est accessible à la fois en IPv4 et en IPv6, l'utilisateur (le propriétaire des globes oculaires) sera heureux (il verra le site très vite), que sa connectivité IPv6 fonctionne correctement ou pas. L'incertitude à ce sujet est la principale cause du très faible nombre de sites Web qui ont un enregistrement AAAA (adresse IPv6) dans le DNS aujourd'hui.
Ce RFC ne propose pas de solution : issu de travaux menés notamment au sein du groupe de travail benchmarks de l'IETF, il propose simplement de mesurer ce bonheur des globes oculaires, de manière à ce qu'on puisse comparer les solutions. On pourra alors retenir les meilleures, de manière à faire sauter ce qui est aujourd'hui un sérieux obstacle au déploiement d'IPv6.
La section 1 du RFC résume le problème de base : si on a une connectivité où plusieurs préfixes IP sont possibles (un IPv4 et un IPv6, ou bien plusieurs IPv6), et que l'application choisit comme source le « mauvais » (celui qui a la moins bonne connectivité, voire pas de connectivité du tout), quelles seront les conséquences pratiques ? L'établissement de la session en sera-t-il ralenti ? Comment TCP va-t-il réagir (RFC 5461) ?
L'algorithme naïf pour l'application est de récupérer une liste
d'adresses possibles pour la destination, via
getaddrinfo()
, et d'essayer chaque
adresse successivement. Si certaines timeoutent, le
temps total d'établissement de la connexion (attendre l'expiration du
délai de garde, puis essayer l'adresse suivante) va largement dépasser
les capacités de l'utilisateur même le plus patient (cela peut
dépasser la minute, la valeur exacte dépend de nombreux paramètres). Les globes
oculaires seront malheureux.
C'est à cause de cela que, alors que plus de 40 % des zones dans
.fr
ont une adresse IPv6
pour leur service DNS (mesures faites en janvier 2012), seules moins d'1 % en ont une pour leur service
Web. C'est parce que le DNS a été prévu pour résister aux pannes dès
le début (le résolveur se souvient de quelles adresses marchent, pour
une zone) et que l'ajout d'un AAAA cassé n'a
pas de conséquences graves. Au contraire, le Web n'a pas de mécanisme
natif pour assurer la haute disponibilité et un AAAA cassé se paie
très cher en temps d'attente pour les clients. Beaucoup de gérants de
sites Web préfèrent donc ne pas courir le risque, même s'il ne
frapperait qu'une petite minorité de leurs clients.
L'idée de ce RFC, présentée en section 2, est de quantifier ce problème. Le but est d'aboutir à des chiffres indiquant, pour un système donné (nommé Alice), le temps qu'il met à ouvrir une session avec un service (nommé Bob) dont certaines adresses sont incorrectes. Plusieurs cas d'incorrection peuvent se présenter :
DROP
dans iptables par
exemple),RST
(reset) TCP,Le test doit être fait pour tous ces cas car rien ne dit que l'application réagira de la même façon à tous ces problèmes. Le plus important est sans doute celui de la perte silencieuse des paquets, car c'est le pire : si l'application réagit bien même dans ce cas, elle s'en tirera sans doute dans les autres. Si on n'en teste qu'un, cela doit donc être celui-ci. (C'est ce que dit le RFC. En pratique, le cas des problèmes de MTU est souvent aussi grave, et il ne se détecte qu'après l'ouverture de la session, lorsqu'on commence à envoyer de gros paquets.)
La section 2.2 explique la procédure, notamment le fait qu'on intègre le temps de la requête DNS préalable (ce que je trouve contestable, mais les raisons ne sont pas expliquées). Les métriques elle-mêmes sont en section 2.3. On mesure le temps entre la première requête DNS et la fin de l'établissement de la connexion TCP, qui est le moment où l'application peut commencer à travailler. Cela se nomme le Session Setup Interval. Si on garde les temps minimum (meilleur cas, probablement celui où la première tentative réussie) et maximum (pire cas, lorsqu'il aura fallu essayer toutes les adresses de la cible), on les nomme Minimum Session Setup Interval et Maximum Session Setup Interval. Le reste du RFC est composé de détails concrets pour qui voudrait effectuer cette mesure. Telle qu'elle est définie (avec des notions comme « l'arrivée du dernier but »), elle n'est pas triviale, voire pas possible à mettre en œuvre sur une machine Unix normale.
Il existe aussi une métrique « qualitative », où on décrit le
trafic observé (Attempt Pattern). Cela peut être
simple (« Un paquet TCP SYN
est envoyé
successivement à toutes les adresses, à des intervalles de X
milli-secondes ») mais aussi très complexe. Mon article sur les algorithmes en
donne quelques exemples.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : D. Wing, A. Yourtchenko (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 7 avril 2012
Une question récurrente qu'IPv6 pose aux développeurs d'application et aux administrateurs système qui déploieront ces applications ensuite est celle d'une machine accessible à la fois en IPv4 et IPv6. Si le pair cherchant à joindre cette machine croit avoir IPv6 mais que sa connectivité ne marche pas, ou mal, l'application arrivera-t-elle à se rabattre en IPv4 très vite ou bien imposera-t-elle à l'utilisateur un long délai avant de détecter enfin le problème ? Cette question est connue comme « le bonheur des globes oculaires » (les dits globes étant les yeux de l'utilisateur qui attend avec impatience la page d'accueil de YouPorn) et ce RFC spécifie les exigences pour l'algorithme de connexion du client, afin de rendre les globes oculaires le plus heureux possible. (Il a depuis été remplacé par un RFC plus général, ne se limitant pas à IPv6, le RFC 8305.)
La section 1 rappelle les données du problème : on veut évidemment que cela marche aussi bien en IPv6 qu'en IPv4 (pas question d'accepter des performances inférieures) or, dans l'état actuel du déploiement d'IPv6, bien des sites ont une connexion IPv6 totalement ou partiellement cassée. Si un serveur a IPv4 et IPv6 et que son client n'a qu'IPv4, pas de problème. Mais si le client a IPv6, tente de l'utiliser, mais que sa connexion est plus ou moins en panne, ses globes oculaires vont souffrir d'impatience. Certains fournisseurs (notamment Google) ont résolu le problème en n'annonçant leur connectivité IPv6 (via le DNS et les enregistrements AAAA) qu'à certains réseaux, configurés manuellement après examen de la qualité effective de leur connectivité. Cette approche, nommée « whitelisting » ne passe évidemment pas à l'échelle. Même pour Google, c'est un travail colossal que d'évaluer le réseau de tous les sites Internet.
(À noter que deux lecteurs m'ont fait remarquer que YouPorn n'est pas un bon exemple, puisqu'il ne publie pas d'adresse IPv6. C'est vrai et cela montre que mes lecteurs connaissent bien YouPorn.)
La bonne solution est donc que l'application elle-même gère le problème (ou, sinon l'application elle-même, la bibliothèque logicielle qu'elle utilise et où se trouve la fonction de connexion). Il existe plusieurs algorithmes pour cela, déjà largement déployés. Ce RFC normalise les caractéristiques que doivent avoir ces algorithmes. Si on suit ce RFC, le trafic (IP et DNS) va légèrement augmenter (surtout si la connectivité IPv6 marche mal ou pas du tout) mais la qualité du vécu de l'utilisateur va être maintenue, même en présence de problèmes, ce qui compense largement. Autrement, il existerait un risque élevé que certains utilisateurs coupent complètement IPv6, plutôt que de supporter ces problèmes de délai de connexion.
La section 3 revient dans l'histoire, pour montrer que le problème n'est pas nouveau. En 1994, le RFC 1671 disait « The dual-stack code may get two addresses back from DNS; which does it use? During the many years of transition the Internet will contain black holes. » (Au passage, cela montre la stupidité de la légende, fréquemment entendue, comme quoi les problèmes de la transition IPv4->IPv6 n'auraient pas été étudiés à l'avance.) Tout le reste de notre RFC 6555 est consacré à répondre à cette question. La cible principale est composée des protocoles de transport avec connexion (TCP, SCTP), les protocoles sans connexion comme UDP soulevant d'autres questions (s'ils ont une sémantique requête/réponse, comme dans ICE, les algorithmes de ce RFC peuvent être utilisés).
Le RFC rejette l'idée d'utiliser des noms différents pour les deux familles (comme
www.ipv6.example.com
), car cela complique le
partage de noms (envoi d'un URL à un copain,
par exemple).
Donc, on a un nom de machine qu'on veut contacter, mettons
www.example.com
, avec deux adresses associées,
une par famille (voir les sections 5.3 et 5.4 pour le cas avec plus de deux adresses). Avec l'algorithme naïf
qu'utilisent certains logiciels, et une connexion IPv6 qui marche mal,
voici la séquence d'évenements :
192.0.2.1
et
2001:db8::1
./etc/gai.conf
). L'initiateur envoie un paquet
TCP SYN
à
2001:db8::1
.SYN
à 192.0.2.1
.SYN+ACK
en échange,
l'initiateur réplique par un ACK
et la connexion
TCP est établie.Le problème de cet algorithme naïf est donc la longue attente lors des essais IPv6. On veut au contraire un algorithme qui bascule rapidement en IPv4 lorsqu'IPv6 ne marche pas, sans pour autant gaspiller les ressources réseau en essayant par exemple toutes les adresses en même temps.
L'algorithme recommandé (section 4, cœur de ce RFC) aura donc la tête :
192.0.2.1
et
2001:db8::1
. Il sait donc qu'il a plusieurs
adresses, de famille différente.SYN
à
2001:db8::1
, avec un très court délai de garde.SYN
à 192.0.2.1
.SYN+ACK
en échange,
l'initiateur réplique par un ACK
et la connexion
TCP est établie.Si le répondeur réagit à une vitesse normale en IPv6, la connexion sera établie en IPv6. Sinon, on passera vite en IPv4, et l'utilisateur humain ne s'apercevra de rien. Naturellement, si le DNS n'avait rapporté qu'une seule adresse (v4 ou v6), on reste à l'algorithme traditionnel (« essayer, patienter, ré-essayer »).
La section 4 précise ensuite les exigences auxquelles doit obéir
l'algorithme. D'abord, il est important de ne pas tester IPv4 tout de
suite. Les premiers algorithmes « bonheur des globes oculaires »
envoyaient les deux paquets SYN
en même
temps,
gaspillant des ressources réseau et serveur. Ce double essai faisait
que les équipements IPv4 du réseau avaient autant de travail qu'avant,
alors qu'on aurait souhaité les retirer du service petit à petit. En
outre, ce test simultané fait que, dans la moitié des cas, la
connexion sera établie en IPv4, empêchant de tirer profit des
avantages d'IPv6 (cf. RFC 6269). Donc, on
doit tester en IPv6 d'abord, sauf si on se
souvient des tentatives précédentes (voir plus loin la variante « avec
état ») ou bien si l'administrateur système a délibérement configuré
la machine pour préférer IPv4.
L'avantage de cet algorithme « IPv6 d'abord puis rapidement basculer en IPv4 » est qu'il est sans état : l'initiateur n'a pas à garder en mémoire les caractéristiques de tous ses correspondants. Mais son inconvénient est qu'on recommence le test à chaque connexion. Il existe donc un algorithme avec état, où l'initiateur peut garder en mémoire le fait qu'une machine (ou bien un préfixe entier) a une adresse IPv6 mais ne répond pas aux demandes de connexion de cette famille. Le RFC recommande toutefois de re-essayer IPv6 au moins toutes les dix minutes, pour voir si la situation a changé. De plus, un changement de connectivité (détecté par le DNA des RFC 4436 ou RFC 6059) doit entraîner un vidage complet de l'état (on doit oublier ce qu'on a appris, qui n'est plus pertinent).
Une conséquence de l'algorithme recommandé est que, dans certains
cas, les deux connexions TCP (v4 et v6) seront
établies (si le SYN
IPv6 voyage lentement et que
la réponse arrive après que l'initiateur de la connexion se soit
impatienté et soit passé à IPv4). Cela peut être intéressant dans certains cas rares, mais le
RFC recommande plutôt d'abandonner la connexion perdante (la
deuxième). Autrement, cela pourrait entraîner des problèmes avec, par
exemple, les sites Web qui lient un
cookie à l'adresse IP du
client, et seraient surpris de voir deux connexions avec des adresses différentes.
Voilà, l'essentiel du RFC est là. La section 5 donne quelques détails en plus. Par exemple, l'algorithme des globes oculaires heureux est astucieux, mais tend à masquer les problèmes. Si un site Web publie les deux adresses mais que sa connectivité IPv6 est défaillante, aucun utilisateur ne lui signalera puisque, pour eux, tout va bien. Il est donc recommandé que le logiciel permette de débrayer cet algorithme, afin de tester la connectivité avec seulement v4 ou seulement v6, ou bien que le logiciel indique quelque part ce qu'il a choisi, pour mieux identifier d'éventuels problèmes v6.
D'autre part, vous avez peut-être remarqué que j'ai utilisé des
termes vagues (« un certain temps ») pour parler du délai entre, par
exemple, le premier SYN
IPv6 et le premier
SYN
IPv4. La section 5.5 donne des idées
quantitatives en suggérant entre 150 et 250 ms entre deux
essais (les navigateurs actuels sont plutôt du côté de 300 ms). C'est quasiment imperceptible à un utilisateur humain devant
son navigateur Web, tout en évitant de surcharger le réseau
inutilement. Les algorithmes avec état ont le droit d'être plus
impatients, puisqu'ils peuvent se souvenir des durées d'établissement
de connexion précédents.
Autre problème pratique, l'interaction avec la politique de sécurité des navigateurs Web (RFC 6454). Pour limiter les risques d'attaque par changement DNS (croire qu'on se connecte au même serveur HTTP alors que c'est en fait un autre), les navigateurs ne doivent pas changer de famille d'adresse (v4 en v6 ou réciproquement) une fois la session commencée.
Enfin, les implémentations. La section 6 donne les exemples de
Firefox et Chrome, très
proches de ce que décrit le RFC. D'autres
possibilités sont disponibles en ligne, en
Erlang ou en
C. Une version pour
Go avait été affichée en http://www.pastie.org/1528545
(en voici une sauvegarde locale).
Enfin, pour un exemple de test du malheur des globes oculaires, voir « Experiences of host behavior in broken IPv6 networks ». Ou bien « Evaluating the Effectiveness of Happy Eyeballs » qui contient d'intéressantes mesures.
Date de publication du RFC : Mars 2012
Auteur(s) du RFC : T. Winter, P. Thubert (Cisco
Systems), A. Brandt (Sigma
Designs), T. Clausen (LIX, École
Polytechnique), J. Hui (Arch Rock
Corporation), R. Kelsey (Ember
Corporation), P. Levis (Stanford
University), K. Pister (Dust
Networks), R. Struik, JP. Vasseur (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF roll
Première rédaction de cet article le 26 mars 2012
Il y a beaucoup d'intérêt en ce moment pour un (largement mythique) « Internet des objets » qui mèle des fantasmes domotiques éculés (le réfrigérateur qui commande tout seul des bières à Carrefour via l'Internet, lorsqu'il est vide), l'arrivée massive d'ordinateurs qui ne sont pas considérés comme des ordinateurs (smartphones, tablettes, télévisions connectées), la connexion à des réseaux TCP/IP d'équipements très modestes, et la diffusion de plus en plus large d'étiquettes RFID. Pour les ordinateurs (un smartphone, bien plus puissant que l'ordinateur qu'embarquait les vaisseaux Apollo, mérite tout à fait ce titre), un des enjeux de l'Internet des objets est le routage des paquets IP. Ces « objets » ont des ressources électriques limitées, et sont souvent connectés par des liens radio de qualité médiocre. Les protocoles de routage traditionnels ne sont pas très adaptés à cette situation. Le groupe de travail ROLL de l'IETF travaille sur ce problème et vient de produire son protocole « officiel », RPL (Routing Protocol for LLNs où un LLN est un Low power and Lossy Network, un réseau où mêmes les routeurs ont peu de courant et où pas mal de paquets se perdent en route). Le groupe ROLL a déjà produit plusieurs RFC détaillant les demandes de ces LLNs : RFC 5867, RFC 5826, RFC 5673 et RFC 5548. Il a également normalisé l'algorithme de distribution utilisé par RPL, Trickle (RFC 6206).
Un exemple de LLNs est un groupe de capteurs dispersés un peu partout dans un bâtiment industriel : ce sont des petites machines par rapport au smartphone typique, fonctionnant sur batteries ou sur piles, ils doivent faire attention à leur consommmation électrique. Connectés par radios, ils n'ont en général pas la possibilité de parler directement aux gros routeurs de la salle machines, située à des dizaines de mètres. Certains des objets doivent donc tenir le rôle de routeur, relayant les communications de leurs camarades (la distinction entre routeur et machine terminale est d'ailleurs assez floue dans RPL). Il leur faut donc un protocole de routage pour trouver les chemins possibles et les protocoles existants comme OSPF n'ont jamais été conçus pour ce genre de missions (par exemple, OSPF émet des messages même lorsqu'il n'y a pas de changements, ce qui peut vider une batterie rapidement). Le « public » visé est donc composé de machines avec des processeurs 16bits, quelques ko de RAM et de Flash, dans des réseaux où il peut y avoir des milliers de tels engins.
RPL est la solution technique à ce problème du routage. Je préviens tout de suite mes fidèles lecteurs que ce RFC est très long et que je n'ai pas tout suivi, loin de là. Il n'y aura donc pas ici de cours sur RPL mais juste la mise en évidence de certains points intéressants (si vous ne lisez qu'une partie du RFC, la section 3 est une description de haut niveau de RPL). Notez qu'il existe d'autres protocoles de routage répondant à peu près à ce cahier des charges, notamment Babel (RFC 8966).
Pour distribuer l'information sur les routes et les routeurs, RPL utilise l'algorithme Trickle (RFC 6206).
RPL essaie de construire un graphe acyclique, qui est lui-même divisé en sous-graphes acycliques, chacun enraciné dans une et une seule destination (RPL les nomme DODAG pour Destination-Oriented Direct Acyclic Graphs). Tout le trafic pour une destination donnée a ainsi la garantie de l'atteindre, sans boucler. Le graphe est orienté : les informations de routage indiquent si le paquet progressera « vers le haut » ou bien « vers le bas » et cette orientation joue un rôle essentiel dans la prévention des boucles (section 11.2). L'annexe A décrit en détail un exemple de fonctionnement.
Pour optimiser les routes, RPL est paramétré avec une fonction nommée OF (pour Objective Function). Des concepts comme celui de distance sont définis par cette fonction. Des réseaux différents peuvent utiliser des OF différents (une qui cherche le chemin le plus court, une qui cherche à ne pas utiliser comme routeur les machines n'ayant pas de connexion au courant électrique, etc), même s'ils utilisent tous RPL. Ces fonctions sont enregistrées à l'IANA (section 20.5). La section 14 décrit les règles auxquelles doivent obéir ces fonctions.
RPL nécessite des liens bidirectionnels. Ce n'est pas toujours évident d'avoir de tels liens dans le monde des ondes radio. RPL doit donc tester la bidirectionnalité des liens avec un potentiel routeur, par exemple en utilisant le protocole du RFC 5881. Comme tout bon protocole TCP/IP, RPL peut fonctionner sur un grand nombre de modèles de réseaux physiques (cf. RFC 3819). Les communications du protocole RPL utiliseront ensuite des paquets ICMP (RFC 4443) de type 155.
Conçu pour des réseaux de machines ayant peu de capacités, et qu'on ne peut pas aller toutes configurer à la main, RPL a par défaut peu de sécurité. Dans le mode de base, n'importe quelle machine peut se joindre au réseau et se faire désigner comme routeur. Dans le mode « pré-installé », les machines doivent connaître une clé pour joindre le réseau. Dans le mode de sécurité maximale, dit « authentifié », il y a deux clés, une pour devenir un nœud ordinaire, et une pour devenir un routeur. (Voir la section 10 pour tous les détails sur la sécurité.)
RPL est un protocole de routage (routing), c'est-à-dire de construction de routes. Il ne change pas le modèle de transmission (forwarding) d'IP, celui que suivent les nœuds une fois les routes connues. Néanmoins, la section 11 donne quelques conseils intéressants sur la façon dont les machines peuvent limiter les problèmes lors de la transmission des paquets. Par exemple, une machine peut faire partie de plusieurs réseaux RPL (on dit « plusieurs instances RPL ») et elle doit faire attention en routant des paquets entre deux instances car les protections contre les boucles ne s'appliquent plus. Une solution possible est d'ordonner les instances (on peut transmettre les paquets destinés à un réseau seulement vers un réseau dont le numéro d'instance est supérieur).
L'ingénieur réseaux qui devra installer et configurer un réseau utilisant RPL peut aller regarder tout de suite la section 18 : elle explique la gestion de ces réseaux et les paramètres qu'on peut avoir à configurer, dans l'esprit du RFC 5706. Évidemment, c'est toujours préférable lorsqu'il n'y a rien à configurer et que cela marche tout seul (RFC 1958, section 3.8). C'est particulièrement vrai pour le type de réseaux auxquels est destiné RPL, des réseaux composés de nombreuses machines planquées un peu partout. Néanmoins, si on veut configurer, il y a quelques boutons à tourner comme le choix du numéro d'instance RPL (section 18.2.3) qui permet d'avoir plusieurs réseaux RPL différents dans un même endroit.
Enfin, la section 19 est la traditionnelle section sur la sécurité. Comme résumé au début de cet article, RPL offre forcément peu de sécurité : les réseaux ad hoc pour lesquels il est prévu ne s'y prêtent guère (difficulté à configurer chaque machine, par exemple pour y indiquer une clé, ou bien ressources limitées des machines, ce qui limite l'usage de la cryptographie). RPL fournit néanmoins des mécanismes de sécurité mais il est à parier qu'ils ne seront pas souvent déployés.
Comme souvent de nos jours, une bonne partie des efforts du groupe de travail a été dépensé en discussions sur les différentes brevets plombant le protocole. Il a finalement été décidé de foncer mais les juristes peuvent regarder les différentes prétentions à l'appropriation qui pèsent sur RPL.
Quelles implémentations sont disponibles ? Selon le groupe de travail, elles seraient déjà plus de dix, mais je n'ai pas de liste. Ce qui est sûr, c'est que deux tests d'interopérabilité ont déjà eu lieu, sous la houlette de l'IPSO et du consortium Zigbee. La section 16 intéressera certainement les implémenteurs car elle récapitule les choses importantes qu'il faut savoir pour que toutes les mises en œuvre de RPL coopèrent.
Un résumé de synthèse sur RPL est « "The Internet of Things" takes a step forward with new IPv6 routing protocol », écrit par un employé de Cisco (entreprise qui a fondé l'alliance IPSO en septembre 2008).
Date de publication du RFC : Juin 2012
Auteur(s) du RFC : N. Brownlee (University of Auckland), éditeur pour l'IAB
Pour information
Première rédaction de cet article le 18 juin 2012
Si vous n'aimez pas les RFC de procédure, et que vous ne voulez que de la technique, rassurez-vous, ce document est court : il spécifie le rôle et les qualités de l'ISE (Independent Submission Editor), celui (ou celle) qui supervise les RFC qui ne passent pas par l'IETF. (Il a par la suite été remplacé par le RFC 8730.)
Comment, ça existe ? Tous les RFC ne naissent pas au sein d'un des nombreux groupes de travail de l'IETF ? Eh oui, c'est souvent oublié, mais c'est le cas, il existe une voie indépendante qui permet à des individus de publier un RFC, quel que soit l'avis de l'IETF. Cette voie est décrite dans le RFC 4846. Autrefois, il n'existait qu'un seul RFC Editor pour examiner et préparer tous les RFC. Mais cette tâche est désormais répartie entre plusieurs éditeurs spécialisés et l'ISE est en charge de la voie indépendante.
Ce mécanisme était décrit dans le RFC 5620 (modèle du RFC Editor, « v1 »), document désormais réparti entre plusieurs RFC comme le RFC 6635 (modèle du RFC Editor, « v2 ») et ce RFC 6548.
La section 2.1 décrit les qualifications attendues de l'ISE. Ce doit être quelqu'un d'expérimenté (senior), compétent techniquement dans les sujets traités à l'IETF (ce qui fait beaucoup !), connu et reconnu de la communauté IETF, sachant écrire et corriger, connaissant très bien l'anglais, et capable de travailler dans le milieu souvent agité de l'IETF.
Sa tâche principale (section 2.2) est de maintenir la qualité des RFC de la voie indépendante, par la relecture et l'approbation des documents, avant transmission au Producteur des RFC (RFC Production Center). Mais il doit aussi traiter les errata pour les RFC de la voie indépendante, contribuer à définir les évolutions de cette voie, interagir avec les autres acteurs des RFC, et fournir des statistiques à l'IAB et l'IAOC. Il peut se faire assister par un conseil consultatif, dont il nomme les membres « at the pleasure of the ISE », dit le RFC dans une jolie formule. Il y a aussi un conseil éditorial, également nommé par l'ISE (section 3 du RFC).
Le site officiel des RFC contient une page consacrée à la voie indépendante, si cela vous tente d'y publier.
L'ISE est nommé par l'IAB, selon une procédure analogue à celle du RFC 4333. Aujourd'hui, c'est Nevil Brownlee (l'auteur du RFC), qui joue ce rôle. Il a été reconfirmé le 5 février 2012, sa première désignation avait été en 2010.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : W. George (Time Warner Cable)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 1 mars 2012
Un très court RFC qui se contente de déclarer formellement que le RFC 3627 n'a plus qu'un intérêt historique. La principale recommendation de ce vieux RFC, que les liens point-à-point ne soient pas numérotés en IPv6 avec un /127, a été annulée par le RFC 6164, qui recommande au contraire cette pratique.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : Kathleen M. Moriarty (EMC)
Chemin des normes
Première rédaction de cet article le 22 avril 2012
La sécurité, face aux innombrables attaques que connaissent les réseaux tous les jours, nécessite un échange d'information permanent. Ce RFC normalise donc un format permettant d'échanger et de traiter ce genre d'informations. Il sera donc peut-être un outil technique utile pour les CSIRT et les opérateurs.
La section 1 résume les problèmes de la sécurité des réseaux auxquels les opérateurs font face. Une fois l'attaque détectée, que ce soit un hameçonnage, une DoS ou une pénétration réussie dans un système connecté au réseau, il faut rédiger un rapport, transmettre à l'opérateur d'origine de l'attaque, demander à un opérateur amont de prendre des mesures pour limiter les dégâts, demander de continuer l'enquête en suivant la trace de l'attaquant, etc. Par exemple, si on veut suivre une trace de paquets dont l'adresse IP source est mensongère, et que le filtrage recommandé par le RFC 2827 n'est pas en place, il faut repérer par quel câble sont entrés ces paquets et envoyer ensuite à l'opérateur situé derrière une demande de continuation de l'enquête. Il n'y a pas de mécanisme formel pour cela. Ça se fait typiquement par téléphone ou par envoi d'un courrier en langue naturelle, ce qui augmente les coûts de traitement.
Le nouveau format, normalisé dans ce RFC 6545, se nomme RID pour Real-time Inter-network Defense et se base sur le format IODEF du RFC 5070 (désormais RFC 7970), qui lui-même utilise XML. L'apport par rapport à l'IODEF de base est de cibler la circulation d'informations en « temps réel ». RID avait d'abord été spécifié dans le RFC 6045, que notre RFC met à jour. À part le changement de statut (RID est désormais sur le chemin des normes), les changements (résumés dans la section 1.1) sont de peu d'importance.
RID vise donc à permettre la réponse immédiate à une attaque. Par exemple, lorsqu'une dDoS est perpétrée par un botnet, il faut certes retrouver les zombies mais aussi identifier le contrôleur qui les commande. RID permet de demander un suivi de la trace des premiers, puis ensuite du second.
L'opérateur a typiquement un système de gestion centralisé de son réseau, un NMS. Le futur IHS (Incident Handling System) qui recevra et enverra les messages RID devra être intégré à ce NMS. La détection de l'attaque pourra se faire manuellement, ou via un IDS mais cette question est hors-sujet pour RID, qui se contente de permettre le signalement d'attaques, une fois celles-ci détectées.
Quelles sont les obstacles que rencontrent les tentatives de remonter à la source d'une attaque ? La section 2 en donne une liste, et c'est une lecture très recommandée pour comprendre la variété des problèmes auxquels fait face l'opérateur réseau lors d'une attaque. Par exemple, certaines attaques utilisent tellement peu de paquets qu'il est difficile de les répérer. D'autre part, pour prendre rapidement une « empreinte » des paquets utilisés pour l'attaque, les techniques à base d'une fonction de hachage ont souvent été utilisées (cf. « Hash-Based IP Traceback »). Or, certaines attaques ont un contenu des paquets qui varie énormément et il est difficile de trouver une « signature » qui permettrait de dire à l'opérateur précédent « Voici ce que je cherche ». Les nombreuses techniques de traceback pour IP ont été utilisées pour déterminer quelles étaient les informations importantes à inclure dans RID. Ainsi, il est essentiel d'inclure beaucoup d'informations dans le message RID car les champs significatifs et l'attaque, permettant de repérer les paquets, peuvent être n'importe lesquels. RID permet même d'envoyer la totalité du paquet, si nécessaire.
Une fois que le message RID est prêt, que fait-on pour la communication avec les autres opérateurs et avec les CSIRT ? Les sections 3.1 et 3.2 font remarquer que le courrier électronique n'est pas forcément adapté car il peut être trop lent. Mais, de toute façon, il faut prévoir plusieurs canaux de communication car, en cas d'attaque, certains deviendront peut-être inutilisables. Un réseau distinct de celui utilisé pour le trafic « normal » peut donc être nécessaire (voir plus loin le commentaire de la section 9). Le RFC suggère qu'on peut profiter des négociations qui précèdent un accord de peering pour mettre en place un canal de communication sécurisé.
Recommandation utile ou vœu pieux ? En tout cas, la section 3.1 rappelle également que RID ne devrait être utilisé que pour lutter contre des attaques, et pas pour perpétuer des sabotages (en dénonçant un innocent dans l'espoir qu'il se fasse filtrer) ou pour censurer.
Maintenant, place au format utilisé (section 4), fondé sur IODEF (RFC 5070). Il y a cinq messages RID possibles :
Request
où on demande à un partenaire
d'examiner son réseau pour voir d'où venait l'attaque (l'idée est que,
partant de celui qui a détecté l'attaque, on envoit des
Request
successifs en remontant peu à peu
vers la source de l'attaque). Le même message sert si on a déjà
identifié la source et qu'on veut juste davantage d'information.Report
où on transmet de l'information,
sans demander d'action immédiate.Query
où on demande des détails sur
une attaque dont on a entendu parler (les deux derniers types de
message sont typiquement pour la communication avec un CSIRT).Acknowledgment
et
Result
servent à porter les résultats
intermédiaires ou finaux.La section 4.2 décrit plus en détail chacun de ces types.
La section 7 fournit plusieurs jolis exemples, que j'ai simplifié
ici. Par exemple, une Request
envoyé par un
CSIRT qui a détecté une DoS et qui demande à un
opérateur réseau de tracer l'attaque. Le message est composé d'un
document RID puis du document IODEF qui décrit l'attaque :
<iodef-rid:RID> <!-- Le schéma est enregistré en https://www.iana.org/assignments/xml-registry/ns.html --> <iodef-rid:RIDPolicy MsgType="TraceRequest" MsgDestination="RIDSystem"> <iodef:Node> <iodef:Address category="ipv4-addr">192.0.2.3</iodef:Address> </iodef:Node> <iodef-rid:TrafficType type="Attack"/> <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN"> CERT-FOR-OUR-DOMAIN#207-1 </iodef:IncidentID> </iodef-rid:RIDPolicy> </iodef-rid:RID> <!-- IODEF-Document accompanied by the above RID --> <iodef:IODEF-Document> <iodef:Incident restriction="need-to-know" purpose="traceback"> <iodef:DetectTime>2004-02-02T22:49:24+00:00</iodef:DetectTime> <iodef:StartTime>2004-02-02T22:19:24+00:00</iodef:StartTime> <iodef:ReportTime>2004-02-02T23:20:24+00:00</iodef:ReportTime> <iodef:Description>Host involved in DOS attack</iodef:Description> <iodef:EventData> <iodef:Flow> <iodef:System category="source"> <iodef:Node> <iodef:Address category="ipv4-addr">192.0.2.35 ...
Et la première réponse, qui indique que la demande de traçage a été approuvée :
<iodef-rid:RID> <iodef-rid:RIDPolicy MsgType="RequestAuthorization" MsgDestination="RIDSystem"> <iodef-rid:TrafficType type="Attack"/> </iodef-rid:RIDPolicy> <iodef-rid:RequestStatus AuthorizationStatus="Approved"/> </iodef-rid:RID>
Et enfin la réponse finale :
<iodef-rid:RID> <iodef-rid:RIDPolicy MsgType="Result" MsgDestination="RIDSystem"> <iodef:Node> <iodef:Address category="ipv4-addr">192.0.2.67</iodef:Address> </iodef:Node> <iodef-rid:TrafficType type="Attack"/> <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN"> CERT-FOR-OUR-DOMAIN#207-1 </iodef:IncidentID> </iodef-rid:RIDPolicy> <iodef-rid:IncidentSource> <iodef-rid:SourceFound>true</iodef-rid:SourceFound> <iodef:Node> <iodef:Address category="ipv4-addr">192.0.2.37</iodef:Address> </iodef:Node> </iodef-rid:IncidentSource> </iodef-rid:RID> <!-- IODEF-Document accompanied by the above RID --> <iodef:IODEF-Document> <iodef:Incident restriction="need-to-know" purpose="traceback"> <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN"> CERT-FOR-OUR-DOMAIN#207-1 </iodef:IncidentID> <iodef:DetectTime>2004-02-02T22:49:24+00:00</iodef:DetectTime> <iodef:StartTime>2004-02-02T22:19:24+00:00</iodef:StartTime> ... <iodef:Expectation severity="high" action="rate-limit-host"> <iodef:Description> Rate limit traffic close to source </iodef:Description> </iodef:Expectation> <iodef:Record> <iodef:RecordData> <iodef:Description> The IPv4 packet included was used in the described attack </iodef:Description> <iodef:RecordItem dtype="ipv4-packet">450000522ad9 0000ff06c41fc0a801020a010102976d0050103e020810d9 4a1350021000ad6700005468616e6b20796f7520666f7220 6361726566756c6c792072656164696e6720746869732052 46432e0a </iodef:RecordItem> </iodef:RecordData> </iodef:Record> </iodef:EventData> <iodef:History> <iodef:HistoryItem> <iodef:DateTime>2004-02-02T22:53:01+00:00</iodef:DateTime> <iodef:IncidentID name="CSIRT-FOR-OUR-DOMAIN"> CSIRT-FOR-OUR-DOMAIN#207-1 </iodef:IncidentID> <iodef:Description> Notification sent to next upstream NP closer to 192.0.2.35 </iodef:Description> </iodef:HistoryItem> <iodef:HistoryItem action="rate-limit-host"> <iodef:DateTime>2004-02-02T23:07:21+00:00</iodef:DateTime> <iodef:IncidentID name="CSIRT-FOR-NP3"> CSIRT-FOR-NP3#3291-1 </iodef:IncidentID> <iodef:Description> Host rate limited for 24 hours </iodef:Description> </iodef:HistoryItem> </iodef:History> </iodef:Incident> </iodef:IODEF-Document>
Comme déjà noté, l'utilisation de ces messages RID ne va pas sans risques. La section 9 les analyse. D'abord, il faut évidemment un canal sécurisé pour les transmettre. Sécurisé au sens de :
Un canal physique dédié faciliterait l'obtention de ces propriétés mais n'est pas forcément réaliste. Le RFC recommande donc plutôt un tunnel chiffré. En combinant TLS sur le tunnel et les signatures XML du RFC 3275 sur le message, on atteint la sécurité désirée. Le protocole exact utilisé est normalisé dans un autre document, le RFC 6546. Bien qu'il utilise le chiffrement, RID ne repose pas uniquement sur la sécurité du canal et permet de chiffrer aussi le message par le chiffrement XML.
RID soulève aussi des questions liées à la protection de la
vie privée et la section 9.5 les étudie. RID
fournit le moyen de spécifier des détails comme l'extension du
« domaine de confiance » à qui on peut envoyer les informations
(élément PolicyRegion
, section 4.3.3.3).
Date de publication du RFC : Mars 2012
Auteur(s) du RFC : J. Rosenberg (Skype), A. Keranen (Ericsson), B. Lowekamp (Skype), A. Roach (Tekelec)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mmusic
Première rédaction de cet article le 20 mars 2012
Le protocole ICE, normalisé dans le RFC 8445, permet de traverser des obstacles comme les routeurs NAT, en essayant plusieurs techniques successives. ICE fonctionne en proposant une liste d'adresses candidates et en testant ensuite ces candidates (avec STUN, notamment) jusqu'à ce qu'on en trouve une qui passe. Dans le RFC originel sur ICE, ces candidates ne pouvaient être testées qu'en UDP. Désormais, notre RFC 6544 permet des candidates TCP (ainsi qu'un mélange des deux).
ICE vise surtout les applications pair-à-pair notamment pour le multimédia (par exemple, pour la télé-conférence). Pourquoi est-ce important de pouvoir faire du TCP ? La section 1 rappelle que certains protocoles ne marchent qu'avec TCP (comme le MSRP du RFC 4975) et que certains protocoles ont certes la possibilité d'utiliser UDP mais peuvent choisir TCP dans certains cas (RTP, RFC 4571, par exemple). C'est évidemment surtout utile dans le cas où on utilise TURN (RFC 5766), protocole qui est parfois le seul à passer certains routeurs NAT, en utilisant un relais TCP.
En général, pour les protocoles qui se servent d'ICE, UDP sera préférable (l'annexe A explique pourquoi). Dans les autres cas, ce nouveau RFC leur permet de faire enfin du TCP. (Et cette possibilité est désormais enregistrée à l'IANA.)
La section 3 résume les changements dans ICE liés à ce nouveau service. Mais c'est assez simple. Il y a trois sortes de candidats TCP, les actifs (qui vont ouvrir la connexion eux-mêmes), les passifs (qui attendent) et les S-O (Simultaneous Open) qui peuvent faire les deux. Dans la liste testée, le type du candidat est indiqué et ICE, pour tester une adresse, va évidemment les apparier en fonction du type (une adresse active avec une passive mais pas avec une autre active, par exemple). Le reste sera fait par de l'ICE normal, comme en UDP. Un petit piège : les messages STUN utilisés par ICE sont sur le même port que le trafic applicatif. Pour un protocole à messages comme UDP, il fallait donc marquer les messages pour les distinguer du trafic STUN. Pour un protocole à flot continu de données, comme TCP, il a fallu introduire un marquage, celui du RFC 4571 (conçu pour RTP mais qui peut être utilisé avec tout flot TCP).
Les détails de l'offre initiale figurent en section 4, par exemple la priorité accordée à UDP, lorsque le choix existe. S'il n'existe pas, on utilisera TCP, avec une adresse active, qui a plus de chances de pouvoir sortir du NAT.
Comme avec UDP, l'offre d'adresses candidates est encodée en SDP, avec un nouvel attribut pour différencier les adresses utilisées en TCP selon qu'elles soient actives ou passives. L'annexe C du RFC contient plusieurs exemples de descriptions SDP, par exemple, pour un appel audio :
v=0 o=jdoe 2890844526 2890842807 IN IP4 10.0.1.1 ... m=audio 45664 TCP/RTP/AVP 0 ... a=connection:new a=candidate:1 1 TCP 2128609279 10.0.1.1 9 typ host tcptype active a=candidate:2 1 TCP 2124414975 10.0.1.1 8998 typ host tcptype passive a=candidate:3 1 TCP 2120220671 10.0.1.1 8999 typ host tcptype so ...
Cet exemple ne montre que des candidats TCP, un de chaque sorte.
Et comment trouver toutes les adresses candidates possibles ? La section 5 donne quelques idées. Attention, plus il y a de candidates, et comme il faut tester chaque couple possible source/destination, plus les tests seront longs.
Les fanas de programmation noteront l'annexe B, qui explique que les opérations à effectuer avec ICE ne correspondent pas tout à fait à l'utilisation habituelle des sockets. Notamment, il s'agit, sur la même socket, d'initier des nouvelles connexions (vers le serveur STUN) et d'en recevoir (depuis les pairs distants). Le pseudo-code suivant est suggéré :
for i in 0 to MAX sock_i = socket() set(sock_i, SO_REUSEADDR) bind(sock_i, local) /* Réserver les "sockets" et les lier à un port */ listen(sock_0) connect(sock_1, stun) connect(sock_2, remote_a) connect(sock_3, remote_b)
Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Kucherawy (Cloudmark)
Expérimental
Première rédaction de cet article le 1 mars 2012
Depuis la sortie de la norme DKIM
d'authentification du courrier électronique
(originellement RFC 4871, désormais RFC 6376), il y a des incompréhensions sur ce que
DKIM garantit réellement. Beaucoup d'utilisateurs croient que,
lorsqu'un message prétend venir de joe@example.net
et
qu'il est signé par DKIM, on peut être sûr que le message vient de
joe@example.net
. Rien n'est plus
faux. DKIM garantit tout autre chose. Il dit que l'identité du
domaine signeur, dans le champ DKIM-Signature:
,
est correcte, et que ce domaine prend la responsabilité du message. Résultat, il y a un fossé entre ce qu'espère
l'utilisateur et ce que DKIM livre effectivement. Ce
RFC expérimental propose une solution pour
combler ce fossé.
Voici une signature DKIM typique, envoyée par le service 23andme :
From: 23andMe Research Team <donotreply@23andme.com> ... DKIM-Signature: v=1; q=dns/txt; a=rsa-sha256; c=relaxed/relaxed; s=132652; d=23andme.ccsend.com; h=to:subject:mime-version:message-id:from:date:sender:list-unsubscribe:reply-to; bh=87HtUCQR/Puz+14IeKPwOPzfeG32vY3BDJBMB74Kv+w=; b=Omftsz+Y3ZbbSbaPWZadKuy8aP35ttpXKTTPdjY4VGttx82q5igLb2r14U3sFI7a+9OXpKODHqOC3HKz1hPQ3GW1L...
On y voit que le domaine 23andme.ccsend.com
prend la
responsabilité de ce message (on peut vérifier l'authenticité de cette
déclaration en vérifiant cryptographiquement la signature, qu'on a récupéré dans le DNS, pour le nom 132652._domainkey.23andme.ccsend.com
) mais que le
message dit avoir été envoyé par 23andme.com
. Peut-on
vérifier cette prétention ? Non, pas avec DKIM. Celui-ci ne fournit,
et c'est un choix de conception délibéré, aucun mécanisme pour lier la
signature à l'« identité » de l'émetteur (notez au passage que le
concept d'identité d'un émetteur de courrier est déjà très flou).
Notre RFC 6541 propose un moyen de faire cette liaison : un domaine peut publier dans le DNS qu'il autorise des tiers à signer ses messages et à les garantir ainsi.
DKIM permettait déjà de déléguer la signature à des tiers (RFC 6376, sections 2.6 et 3.5) mais pas de dire « je fais entièrement confiance à tel domaine pour signer mes messages). C'est ce que fournit cette nouvelle norme, ATPS (Authorized Third-Party Signers).
Quels sont les parties en présence (sections 2 et 3) ?
From:
du
message (RFC 5322).d=
de la
signature.
Dans le monde réel, l'émetteur va par exemple être une entreprise avec une
infrastructure de messagerie sommaire, ne permettant pas de signer, et
le signeur ATPS va être son sous-traitant. Pour faire connaître cette
relation d'affaires entre l'émetteur et son sous-traitant, ATPS permet à
l'émetteur de publier dans le DNS un enregistrement
TXT annonçant ce lien. Le vérificateur pourra alors
récupérer cet enregistrement et se dire « le message est signé par
provider.example
, le message prétend être émis
par customer.example
, or le domaine
customer.example
contient bien un enregistrement
ATPS désignant provider.example
comme signeur
autorisé »
La section 4 contient les détails techniques du protocole. D'abord,
quel va être le nom de l'enregistrement TXT dans le domaine émetteur ?
(Au fait, l'annexe B explique pourquoi utiliser TXT et pas un nouveau type.) Il peut
être directement le nom du domaine du signeur mais aussi une
version encodée de ce nom. Ensuite, que contient la signature DKIM en
cas d'utilisation d'ATPS ? Deux nouveaux champs,
atps=
et atpsh=
(désormais
dans le registre IANA) apparaissent. Si le champ
d=
contiendra, comme avant, le nom de domaine du
signeur, le nouveau champ atps=
contiendra le nom
de domaine de celui pour lequel on signe, l'émetteur. Le vérificateur
testera si la valeur d'atps=
correspond à l'en-tête
From:
(ATPS est ignoré s'ils ne correspondent
pas), fait une requête DNS pour le type TXT, et vérifie qu'on obtient
bien une réponse positive.
Le nom de domaine interrogé pour le type TXT est, dans le cas le
plus simple, le
DOMAINE-SIGNEUR._atps.DOMAINE-ÉMETTEUR
. Si
atpsh=
contient autre chose que
none
, alors DOMAINE-SIGNEUR
est remplacé par un condensé de son nom.
S'il y a une réponse positive, c'est-à-dire un enregistrement TXT,
c'est que c'est bon (pour plus de sécurité, l'enregistrement TXT doit
contenir d=DOMAINE-SIGNEUR
). Si on récupère NXDOMAIN
(nom
non existant) ou bien NOERROR
mais pas
d'enregistrement TXT, c'est que la vérification a échoué. Le signeur
n'est en fait pas autorisé à signer pour l'émetteur (section 5). Le vérificateur
peut prendre une décision comme de mettre un résultat
d'authentification dans les en-têtes du message (cf. section 8.2 pour
la création d'un nouveau type d'authentification,
dkim-atps
, mis dans le registre IANA nomalisé par le RFC 7001).
Et les ADSP (Author Domain Signing Practices) du RFC 5617 ? Ce protocole permet à un domaine émetteur d'annoncer si ses messages sont signés ou non avec DKIM. La section 6 de notre RFC prévoit qu'ATPS doit être testé avant ADSP.
Ce RFC est seulement expérimental. L'idée même d'ATPS est fortement
contestée (les questions de sécurité et de confiance sont toujours
sensibles...) et le besoin s'est fait sentir d'un essai en vrai, pour
déterminer si ATPS marche bien ou pas. ATPS est déjà mis en
œuvre dans OpenDKIM (il faut configurer
avec les options --enable-atps --enable-xtags
),
bibliothèque utilisée notamment par sendmail. Il inclut même un outil pour générer les enregistrements TXT. Les auteurs d'ATPS ont promis
de tester et de décrire dans un document ultérieur le résultat de ces
tests.
Quelques points particuliers de sécurité (section 9) :
Notez que le RFC ne fournit pas un seul exemple complet de signature avec ATPS et je n'en ai pas encore trouvé dans ma boîte aux lettres.
Date de publication du RFC : Avril 2012
Auteur(s) du RFC : W. George (Time Warner Cable), C. Donley (Cablelabs), C. Liljenstolpe (Telstra), L. Howard (Time Warner Cable)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 13 avril 2012
Il y a plusieurs façons de présenter ce RFC qui décrète que toute machine IP doit être capable de faire de l'IPv6. Le meilleur angle, je trouve, est de dire que c'est un RFC contre la publicité mensongère : dans l'Internet d'aujourd'hui, IP ne veut plus seulement dire IPv4. Vendre une machine ou un logiciel comme étant capable de parler IP, alors qu'elle ou il ne fait pas d'IPv6 est mensonger.
Bien sûr, en pratique, il est peu probable que ce RFC change grand'chose : les vendeurs continueront à fourguer des produits incapables de parler IPv6, protocole pourtant normalisé depuis seize ans, avec la sortie du RFC 1883 (depuis remplacé par le RFC 2460). Mais, au moins, ils ne pourront plus dire qu'il y avait une ambiguité et que certains RFC anciens parlent de « IP » pour désigner IPv4. Désormais, il est clair que « IP » veut dire IPv6 et (bien que le RFC ne le spécifie pas), si on est seulement IPv4, cela doit être annoncé comme tel et non pas sous l'étiquette « IP ».
Le succès d'IPv4 est incontestable. Il est désormais déployé absolument partout, malgré les vigoureuses oppositions des telcos traditionnels, relayés par pas mal de gouvernements (souvenez-vous des ridicules campagnes de promotion de l'ATM, censé barrer la route à IP). Mais c'est ce succès même qui a condamné IPv4. Le stock d'adresses disponibles est désormais épuisé. Un certain nombre de techniques ont été développées par acharnement thérapeutique, pour essayer de gagner encore quelques années, comme le NAT444. Toutes ont de sérieux inconvénients (cf. RFC 6269 pour un exemple).
La solution correcte, qui évite de fragiliser l'Internet par l'empilement de techniques de transition et/ou de coexistence est donc de déployer IPv6. Mais cela ne s'est pas fait tout seul. L'absence, ou la mauvaise qualité, de mise en œuvre d'IPv6 dans les logiciels a longtemps retardé ce protocole. Beaucoup de fournisseurs de logiciels se sont comportés comme si « IP » se réduisait à IPv4, IPv6 étant une addition possible mais facultative. Pendant de nombreuses années, Cisco exigeait une licence supplémentaire payante pour l'activation d'IPv6 dans IOS... Bref, des engins étaient vendus comme « IP » alors qu'ils n'étaient qu'« IPv4 ». Le problème continue aujourd'hui, empêchant la migration de progresser.
C'est particulièrement gênant dans le domaine des équipements proches du consommateur : ce dernier, à juste titre, ne se soucie pas de la version du protocole IP installé. IPv6 a été conçu justement pour ne pas changer le modèle de fonctionnement d'IP et il n'y a donc aucun avantage, pour M. Toutlemonde, à migrer vers IPv6. La migration, décision technique, ne devrait pas dépendre d'un choix explicite du consommateur, surtout si on le fait payer pour cela, comme le faisait Cisco. La migration devrait se faire au fur et à mesure que les vieilles machines et vieux logiciels sont remplacés, sans que M. Toutlemonde ne s'en rende compte.
À la décharge des vendeurs, il faut noter que tous les RFC, même ceux encore en vigueur, ne sont pas clairs là-dessus. Par exemple, le RFC 1812, qui établit les règles pour les routeurs IPv4, utilise souvent le terme IP pour désigner IPv4. Même chose pour le RFC 1122, qui normalise les machines terminales et ne mentionne pas IPv6. Aujourd'hui, le terme « IP », dans un RFC, peut indiquer IPv4 seul, IPv6 seul ou bien les deux.
La section 2 de notre RFC pose donc la règle : « IP implique IPv6 ». Plus précisément :
Évidemment, ce n'est qu'un RFC. Bien des vendeurs l'ignoreront. Espérons toutefois qu'il contribuera à une meilleure information des consommateurs.
Ce document était loin d'être consensuel à l'IETF. Beaucoup de gens critiquaient le principe même d'un document d'exhortation, qui risque fort de n'être qu'un rappel de plus. Toutefois, les partisans de ce document étaient actifs et les opposants ne voyaient pas d'inconvénients graves à la publication.
Date de publication du RFC : Mars 2012
Auteur(s) du RFC : T. Henderson (Boeing), A. Gurtov (HIIT)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF hiprg
Première rédaction de cet article le 25 mars 2012
Le protocole HIP, normalisé dans le RFC 4423, est maintenant stable depuis des années et a fait l'objet de plusieurs essais sur le terrain. Ce RFC de l'IRTF documente certains de ces essais concrets et indique les leçons à en tirer.
Le groupe de recherche hip de l'IRTF a travaillé sur ce sujet de 2004 à 2009. Pendant cette période, un certain nombre de mises en œuvre de HIP ont été programmées et plusieurs bancs de test ont été montés. La section 7 du RFC donne une liste exhaustive des expériences menées, notamment chez Boeing et dans le projet InfraHIP, qui gère des serveurs HIP publics. (Notez que, HIP fonctionnant au dessus d'IP, deux machines HIP peuvent communiquer au dessus de l'Internet public sans problème.) Ce RFC est le compte-rendu de ces expériences, sur les points suivants :
D'abord, la mise en œuvre (section 2). HIP est un protocole pour les machines terminales, pas pour les routeurs. Implémenter HIP, c'est donc modifier Linux ou Windows, sans toucher à ses Cisco ou D-Link. Il existe aujourd'hui trois de ces modifications sous une licence libre :
L'expérience montre bien qu'implémenter un nouveau protocole n'est pas du yakafokon et que plein de pièges insoupçonnés se cachent dans le code. La section 2.1 résume ce qu'il faut modifier au noyau pour intégrer HIP. Les applications fonctionnent comme avant, un HIT (le condensat cryptographique d'une clé HIP) ayant la même forme qu'une adresse IPv6 (avec le préfixe ORCHID du RFC 4843). En section 2.2, c'est le cas d'une implémentation en dehors du noyau qui est couvert (notez que certaines mises en œuvre d'HIP sont mixtes, par exemple avec le traitement des paquets dans le noyau et la cryptographie dans un démon à part). Cela permet de faire fonctionner HIP sur des systèmes qu'on n'a pas le droit de modifier comme Microsoft Windows.
Dans tous les cas, quels ont été les problèmes rencontrés ? En l'absence de système de résolution, manipuler les HIT à la main, se les échanger, etc, a été pénible. Des systèmes de résolution existent désormais (mettre les HIT dans le DNS sous forme d'enregistrements AAAA, comme le propose le RFC 5205, utiliser une DHT dédiée à HIP, etc) et OpenHIP les a tous programmés. Et il y a aussi le mode opportuniste de HIP, où on se connecte sans connaître a priori le HIT du pair. Mais aucune solution n'est à 100 % parfaite.
Le mode
opportuniste du RFC 5201, section 4.1.6 a posé
des problèmes avec l'interface
sockets, car le HIT du pair
distant n'est pas encore connu au moment du
connect()
. De toute façon, ce mode a
l'inconvénient de ne pas être très sécurisé (il fonctionne en mode
TOFU - Trust On First Use - puisque, la première fois qu'on parle à un
pair, on doit accepter son HIT en lui faisant une confiance
aveugle). HIPL a mis en œuvre ce mode. OpenHIP également, avec
une option explicite (-o
), débrayée par
défaut. Le problème de sécurité est particulièrement crucial lorsqu'il
s'agit d'applications traditionnelles, qui ne connaissent pas HIP et
ne peuvent donc pas formuler de souhaits, ou interactivement demander
confirmation à l'utilisateur, ce que peuvent faire les applications
récentes qui utilisent le RFC 6317.
Quant au DNS, certains administrateurs de zones DNS n'ont pas aimé qu'on mette des HIT sous le nom d'AAAA, arguant que c'était un détournement de la sémantique du AAAA.
Autre problème, lorsqu'on connait le HIT du pair (on ne fait donc pas de mode opportuniste) mais pas son adresse IP. Pour lui envoyer des paquets, il faudra alors une résolution, pour trouver cette adresse. Des essais ont été faits avec OpenDHT, ou bien avec le DNS. HIPL a même tenté, pour le cas particulier du LAN, d'envoyer un paquet de diffusion, un peu comme on fait en NDP. Cela a paniqué certains antivirus Windows qui considéraient toute diffusion avec un protocole inconnu comme un danger.
Parmi les nombreuses autres questions que décrit le RFC en tenant compte de l'expérience des programmeurs HIP, celui de la gestion des HI (Host Identifiers, l'identité d'une machine HIP, dont le HIT est le condensat cryptographique). Une machine peut avoir plusieurs identités (par exemple pour protéger la vie privée, voir plus loin), et laquelle doit-elle utiliser lorsqu'elle se connecte à un pair ? Dans quelle mesure le choix doit-il être fait par l'utilisateur ? (Intéressant problème d'interface.) Plus gênant, puisque HIP repose sur des clés cryptographiques, comment stocker les clés privées sur la machine ? Toutes les implémentations actuelles utilisent un fichier appartenant à root en mode 0600 (ce qui interdit la lecture par les utilisateurs ordinaires). Cela ne suffit pas si, par exemple, un attaquant a un accès physique à la machine. La solution serait alors de stocker les clés dans un TPM mais aucune mise en œuvre de HIP n'a encore tenté le coup.
Cette section comprend également un problème qui, à mon avis, est plutôt de déploiement que de programmation, l'interaction avec les pare-feux. HIP est un protocole (le numéro 139 des protocoles IP, TCP étant 6, UDP 17 et OSPF 89) marqué comme expérimental et qui est globalement peu connu. Il n'y a donc pas de règle pour lui dans les règles configurées par défaut et le pare-feu refusant tout ce qui n'est pas explicitement autorisé, les paquets HIP se retrouvent bloqués. Il n'est pas forcément trivial de modifier les règles sans tout casser (le RFC rapporte que celles par défaut de SUSE ont plus de cent entrées) et, de toute façon, l'utilisateur qui veut déployer HIP n'a pas forcément le contrôle du pare-feu. Heureusement, HIP peut tourner sur UDP (au lieu de directement sur IP) ce qui limite les problèmes.
Bien que HIP ait été surtout conçu pour IPv6, et que son déploiement massif ne semble pas devoir précéder celui d'IPv6, toutes les mises en œuvre de HIP ont choisi de gérer également IPv4. Comme on ne peut absolument pas faire rentrer un condensat cryptographique sérieux dans les 32 bits d'une adresse IPv4, il faut ajouter le concept de LSI (Local Scope Identifier), un alias local à la machine pour référencer un HI donné.
Plus amusant, HIP permet également de faire tourner des applications IPv6 sur un réseau IPv4 (et réciproquement), ce qui fonctionne sur tous les codes cités.
Bref, les programmeurs ont bien travaillé et HIP fonctionne sur plusieurs plate-formes. Quelles leçons peuvent être tirées ? Il n'y a pas eu beaucoup de tests de performances, notamment pour comparer les implémentations en mode noyau et en mode utilisateur. Il semble que, sur une machine généraliste et pour des usages typiques, le mode utilisateur (le plus lent) est acceptable.
Le choix entre les deux modes peut dépendre de bien d'autres choses. Par exemple, HIPL avait une mise en œuvre des fonctions de gestion de clés dans le noyau, mais les développeurs du noyau Linux l'ont rejeté, arguant que d'autres protocoles comme IKE faisaient cette gestion en mode utilisateur et qu'il n'y avait pas de raison de l'intégrer dans le noyau. (Il faut dire aussi que c'était un gros patch, qui touchait à beaucoup d'endroits du noyau.)
La section 3 aborde ensuite les points liés au déploiement, notamment à l'effet sur les infrastructures. La section sur le DNS (extensions HIP du RFC 5205) est curieusement incompréhensible (qu'est-ce qu'un binary blob format ?) mais, de toute façon, les serveurs DNS peuvent servir des types de données qu'il ne connaissent pas, donc peu de problèmes à attendre.
Plus sérieux, le cas des middleboxes. Les NAT sont hostiles à HIP comme à beaucoup de choses (problème décrit dans le RFC 5207). HIP peut par exemple chiffrer même la connexion initiale, empêchant le routeur NAT de comprendre ce qui se passe. Le mécanisme de rendez-vous du RFC 5204 pourrait aider à résoudre les problèmes du NAT mais il n'a pour l'instant été testé qu'en laboratoire.
Et l'infrastructure de résolution ? Une mise en œuvre de résolution de HIT en adresses IP via OpenDHT a été faite pour HIPL et OpenHIP. OpenDHT est désormais arrêté mais un nouveau projet a pris le relais, Hi3, qui tourne sur PlanetLab. Au cours des premiers essais, le débogage s'est révélé très pénible, et les middleboxes qui bloquent tout une énorme source de frustration.
Une solution d'avenir pourrait être de mêler DNS (déploiement massif, compatibilité avec le logiciel existant) et DHT (bonne résistance aux pannes, bonne efficacité même dans un espace plat, celui des clés cryptographiques). Par exemple, une organisation ferait tourner une DHT pour stocker les HI ou les HIT de ses machines, connectée avec le DNS pour les clients extérieurs. Ensuite, ces DHT locales pourraient être interconnectées petit à petit. Un test a été fait en modifiant BIND pour qu'il interroge une DHT (Bamboo) pour les HIT. Les performances ont été plutôt mauvaises, et se dégradant vite avec la charge, donc des travaux supplémentaires sont nécessaires.
Et pour les applications ? L'expérience du déploiement d'IPv6 a montré qu'il était plus facile de mettre à jour l'infrastructure que les applications. La section 4 explore les conséquences de HIP sur celles-ci. Il y a deux sortes d'applications : celles qui connaissent HIP et celles qui ne le connaissent pas (la quasi-totalité, aujourd'hui : le RFC 5338 explique comment faire tourner HIP avec les applications traditionnelles).
Par exemple, HIPL a testé une bibliothèque
dynamique (chargée avec LD_PRELOAD
) qui change le comportement du résolveur,
permettant aux applications de se connecter à un pair HIP sans s'en
rendre compte. Un Firefox et un
Apache non modifiés ont ainsi pu se parler en
HIP. L'avantage de cette méthode est de permettre de choisir,
application par application, qui va faire du HIP (cette finesse de
choix pouvant être considérée comme un avantage ou comme un
inconvénient). Une autre solution serait de passer par des relais
applicatifs mais elle ne semble pas avoir été testée encore.
HIP a même réussi à fonctionner avec des applications qui utilisent des références (passer son adresse IP au pair pour qu'il vous envoie ensuite des messages) comme FTP. D'autres applications seraient peut-être moins tolérantes mais, de toute façon, en raison du NAT, les applications qui se servent de références ont déjà beaucoup de problèmes dans l'Internet d'aujourd'hui.
Une des raisons pour lesquelles il peut être intéressant de mettre une gestion de HIP explicite dans les applications est la performance : l'établissement d'une connexion est plus long en HIP et certaines applications (par exemple un navigateur Web) peuvent être très sensibles à cette latence supplémentaire. Elles pourraient alors choisir de laisser tomber la sécurité de HIP au profit de la vitesse.
Continuons dans les problèmes concrets : quelle va être l'expérience de l'administrateur réseaux qui, le premier, tentera de déployer HIP ? Pour l'instant, aucun ne l'a fait mais. HIP peut tourner entièrement dans les machines terminales, sans que le réseau soit impliqué. Si celui-ci l'est, il aura peut-être les problèmes suivants (détaillés en section 5) :
La section 6 du RFC s'attaque ensuite à un difficile problème, celui de la vie privée des utilisateurs. HIP permet enfin de doter chaque machine sur l'Internet d'une véritable identité, indépendante de sa position dans le réseau, qu'on peut vérifier avec la cryptographie. Mais ce gain en sécurité peut se payer en terme de vie privée : si mon ordinateur portable a HIP, je me connecte à un site Web HIP depuis chez moi, et depuis l'hôtel et, sans cookies ou autres techniques de suivi Web, le serveur peut reconnaitre que c'est la même machine (les adresses autoconfigurées d'IPv6 avaient un problème du même genre, qui a été résolu par le RFC 4941).
Pire, dans certains cas, un tiers qui écoute le réseau peut apprendre l'identité des deux machines, même si le reste de la session est chiffré.
HIP permet d'utiliser des HIT non publiés (RFC 5201, sections 5.1.2 et 7) mais cela suppose que le destinataire les accepte (ce qui serait logique pour un serveur public, qui ne se soucie pas en général de l'identité de ses clients). Globalement, la protection de la vie privée dans HIP n'est pas encore suffisante mais des travaux sont en cours. Mon opinion personnelle est que la meilleure solution serait analogue à celle du RFC 4941 : des identificateurs jetables, créés pour une courte période (voire pour une seule session) et abandonnés après. Cela nécessite de faire attention aux autres identificateurs (comme l'adresse IP) qui doivent changer en même temps que le HI (sinon, l'attaquant pourrait faire le rapprochement). L'Université Technologique d'Helsinski a déjà une mise en œuvre expérimentale de cette idée.
HIP n'est pas la seule architecture de séparation du localisateur et de l'identificateur. La section 8 du RFC résume les autres expériences en cours. Il ne va pas de soi que cette séparation soit une bonne idée. C'est même un point de vue très controversé, comme l'avait montré l'échec du NSRG (Name Space Research group). Parmi les efforts récents :
Date de publication du RFC : Février 2012
Auteur(s) du RFC : J. Ahrenholz (Boeing)
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF hiprg
Première rédaction de cet article le 1 mars 2012
Dans tout protocole réseau séparant le localisateur et l'identificateur, il y a une grosse question : comment relier les deux ? Comment, lorsqu'on ne connait que l'identificateur d'une machine, trouver son localisateur afin de lui envoyer un paquet ? Le protocole HIP a plusieurs solutions possibles et ce RFC de l'IRTF en propose une nouvelle : faire appel à une DHT.
Dans HIP, l'identificateur est la partie publique d'une clé cryptographique, et le localisateur une adresse IP. Notre RFC 6537 propose de stocker la correspondance entre les deux dans une DHT. En outre, un second service est proposé, celui permettant de trouver l'identificateur à partir d'un nom de domaine. En fait, ce RFC ne décrit pas tellement la DHT, mais simplement l'interface entre la machine HIP et un service de résolution (qui pourrait aussi bien être mis en œuvre autrement ; le titre du RFC est donc trompeur).
Pourquoi, d'ailleurs, une DHT ? Comme l'expose la section 1, une des bonnes raisons est que l'espace de nommage des identificateurs est plat : il n'y a pas de hiérarchie permettant des résolutions efficaces comme avec le DNS. Les DHT permettent justement de résoudre des noms situés dans un espace plat aussi efficacement que les protocoles reposant sur des noms hiérarchiques.
Petit détail au passage, le protocole de ce RFC n'utilise pas directement les identificateurs (HI pour Host Identifier) mais leur condensat, le HIT (Host Identifier Tag). Il y a donc deux services, nom->HIT et HIT->adresses.
Le DNS est très optimisé depuis longtemps (et il existe un autre travail en cours pour résoudre les identificateurs HIP en localisateurs avec le DNS) mais explorer de nouvelles techniques est toujours intéressant. Il s'agit donc d'un travail plutôt expérimental, où plein de questions n'ont pas encore de réponse.
Une expérience concrète a été faite en utilisant la DHT Bamboo, écrite en Java, et
qui formait la base du service OpenDHT (service qui tournait sur
PlanetLab et a été fermé en 2009). Comme toute DHT, ou d'ailleurs
comme toute table (les dictionnaires de
Python, les hashes de
Perl, les java.util.Dictionary
de Java,
etc), OpenDHT fournissait trois primitives, put
,
get
et remove
. La première
permet de stocker une valeur, sous un certain index (on dit souvent
« clé » mais je l'ai évité pour ne pas risquer une confusion avec les
clés cryptographiques), la seconde de récupérer une valeur dont on
connait l'index, et la troisième (rm
dans la
documentation) de supprimer une valeur. Dans
OpenDHT, ces trois primitives étaient appelées via le protocole
XML-RPC.
La section 2 décrit précisement cette interface XML-RPC. Elle avait été choisie parce qu'OpenDHT fournissait un service simple et gratuit accessible aux chercheurs. Les index pouvaient avoir jusqu'à 20 octets, les valeurs jusqu'à 1024. Toutes les entrées étaient temporaires, OpenDHT les supprimant au plus une semaine après leur insertion (un problème classique des DHT et du pair-à-pair en général est sa vulnérabilité aux méchants, ici à des machines insérant des quantités énormes de données pour faire une DoS).
Outre les paramètres cités plus haut (l'index et la valeur pour
put
, l'index pour get
et
rm
), OpenDHT imposait quelques autres paramètres
comme le TTL du précédent paragraphe, comme un
identifiant de l'application, ou comme un mot de passe permettant de
fournir un peu de
sécurité.
Une fois qu'on a compris l'interface XML-RPC d'OpenDHT et ses paramètres, comment l'utilise-t-on pour HIP ? C'est l'objet de la section 3 et des suivantes. D'abord, on définit en section 3 une structure de données, le HDRR (HIP DHT Resource Record). Son format binaire est le même que celui d'un paquet HIP (RFC 5201, section 5, le HDRR a le numéro 20 dans le registre IANA), c'est-à-dire essentiellement une suite de paramètres encodés en TLV. Il n'a donc rien à voir avec le Resource Record DNS du RFC 5205.
Ces paramètres sont surtout des HI (Host Identifier, identificateurs), des HIT (rappelez-vous que c'est un condensat cryptographique du HI) et des localisateurs (les adresses IP, v4 ou v6). On peut aussi y trouver un certificat, au format du RFC 6253 ou une signature HIP. Ces deux derniers paramètres pourraient, dans une DHT spécialisée, être utilisée pour vérifier que la machine qui enregistre un localisateur pour un identificateur donné est bien autorisée à le faire (cd. RFC 7343, c'est une des forces de HIP, que d'avoir des clés cryptographique comme identificateur, cela permet de signer ses paquets et d'éviter ainsi l'usurpation). Toutefois, cela n'est pas mis en œuvre dans Bamboo, DHT généraliste qui ne sert pas qu'à HIP. Le problème de la DHT spécialisée en HIP est de toute façon plus complexe que cela : par exemple, les vérifications cryptographiques nécessaires faciliteraient une éventuelle attaque par déni de service contre la DHT (HIP évite ce problème par un protocole d'établissement de connexion conçu à cet effet, cf. RFC 5201, section 4.1.1).
Puis, la section 4 décrit le protocole de requête. Il fournit deux services :
Il n'y a pas de requête directe du nom vers les localisateurs. La première correspondance, nom->HIT, est supposée relativement stable (une machine HIP n'a guère de raisons de changer d'identificateur). La seconde correspondance est typiquement variable, voire très variable en cas de mobilité (RFC 5206).
Le reste, ce sont des détails techniques. Par exemple, l'index utilisé pour la requête à la DHT dans le premier cas n'est pas réellement le nom mais un SHA-1 du nom car les index OpenDHT sont limités à vingt octets. Autre point qu'il a fallu régler, les HIT sont typiquement représentés comme des adresses IPv6 ORCHID (RFC 7343), et donc tous les HIT commencent par les mêmes 28 bits (la longueur du préfixe ORCHID). Pour une DHT, qui utilise un hachage des index pour trouver le nœud responsable du stockage des données correspondantes, cela risquerait de causer une répartition très inégale, certains pairs de la DHT étant plus chargés que d'autres. Lors de la deuxième requête (HIT->localisateurs), on n'utilise donc comme index que les 100 derniers bits du HIT.
Une fois ces détails de syntaxe réglés, la section 5 décrit la chorégraphie des requêtes. D'abord, pour trouver un identificateur (ou bien son HIT) à partir d'un nom de domaine, faut-il utiliser le DNS, comme le prévoit le RFC 5205 ou bien le service DHT décrit dans ce RFC 6537 ? La réponse dépend des cas. Tout le monde n'a pas forcément le contrôle des serveurs de noms du domaine souhaité et, même si c'est le cas, tous les serveurs de noms ne permettent pas forcément d'ajouter des enregistrements DNS de type HIP dans leur domaine (testez avec l'interface de votre hébergeur DNS pour voir...) Donc, la solution DHT est intéressante au moins dans ces cas.
On l'a vu, les localisateurs changent, c'est normal. Quand faut-il faire la requête HI->localisateur ? Si on la fait très à l'avance, les localisateurs seront peut-être usagés lorsqu'on s'en servira. Si on la fait au moment de la connexion, on peut ralentir celle-ci de manière intolérable. Le RFC suggère donc de faire les requêtes à l'avance, et, si la première tentative de connexion échoue, de refaire une requête de résolution avant de tenter la deuxième connexion.
Les informations enregistrées dans OpenDHT ont une durée de vie (le
paramètre ttl
de la requête, mais la DHT peut
aussi supprimer les données avant l'expiration de celui-ci, par
exemple s'il faut faire de la place). Une machine HIP doit donc penser
à mettre à jour régulièrement ses entrées dans la DHT, pour s'assurer
qu'il y a toujours quelque chose. Et, naturellement, si l'information
change, la machine doit prévenir la DHT dès que possible.
La DHT étant globale, les adresses IP privées (RFC 1918) ne doivent pas être publiées dans la DHT. Si une machine HIP est coincée derrière un routeur NAT, elle doit, si elle veut être contactée, enregistrer l'adresse du serveur HIP de rendez-vous (RFC 5204).
OpenDHT présentait quelques particularités qui pouvaient surprendre
la machine HIP tentant de stocker ses identificateurs et
localisateurs. Par exemple, un put
ne remplace
pas la donnée précédente, il s'y ajoute. Et rien ne garantit que
l'ordre dans lequel seront renvoyés les HDRR sera celui dans lequel
ils ont été insérés. Il faut donc identifier le plus récent (le HDRR a
un paramètre Update ID
, dont je n'avais pas
encore parlé, juste pour cela). Le mieux serait de penser à faire
le ménage et virer explicitement ses vieilles informations.
Notez d'ailleurs que, le nom n'étant pas authentifié, on peut voir
plusieurs machines s'enregistrer sous le même nom. En attendant un
système d'authentification du nom (certificat
X.509 portant ce nom en sujet ?), il est
recommandé de tester et de choisir un autre nom, si celui qu'on
voulait est déjà pris (ce qui ne devrait pas arriver, avec les noms de
domaine, mais la DHT ne vérifie pas que celui qui enregistre
www.google.com
a le droit).
Autre problème pratique, le choix de la passerelle XML-RPC vers
OpenDHT. Il en existait plusieurs, d'une fiabilité douteuse (OpenDHT
était un projet de recherche, qui ne visait pas à fournir un service
fiable à 100 %) et le client doit donc être prêt à détecter une panne
et à passer sur une autre passerelle (OpenDHT fournissait un service
anycast,
opendht.nyuld.net
, qui facilitait cette
tâche.)
À propos de qualité de service, le RFC note aussi qu'OpenDHT ne
garantissait pas de temps de réponse, et que les opérations
put
et get
peuvent être
lentes, ce à quoi les clients de la DHT doivent se préparer.
Pour approfondir davantage les questions de sécurité (point faible classique de toutes les DHT), la section 7 fait un examen complet des problèmes que pose cette solution. Concernant le contenu de l'information, l'attaque peut être menée par un client de la DHT qui enregistre délibérement des informations fausses, ou bien par un pair participant à la DHT qui modifie les informations avant de les rendre. En l'absence d'un mécanisme tiers d'authentification des données (la DHT de CoDoNS utilisait DNSSEC pour cela), il n'y a pas grand'chose à faire. On l'a dit, c'est un problème récurrent avec toutes les DHT. Le RFC dit que les paranoïaques n'ont pas d'autres solutions que d'échanger les HIT à la main (ensuite, même si la DHT renvoie de mauvais localisateurs, le protocole HIP permettra de vérifier qu'on ne se connecte pas à une machine pirate). Dans le futur, une solution serait peut-être d'utiliser des certificats numériques.
Je l'ai dit, le protocole HIP garantit au moins, par la signature des paquets échangés lors de la connexion, qu'on se connecte bien à la machine possédant l'identificateur voulu. Pour un attaquant, enregistrer dans la DHT de fausses correspondances HIT->localisateur ne permet donc pas de détourner vers une machine pirate. Pour ce stade, la seule possibilité de l'attaquant est d'enregistrer plein de correspondances bidons, pour faire une attaque par déni de service.
La seule solution à long terme à cette attaque serait que la DHT vérifie les données avant de les enregistrer, et donc connaisse HIP. Elle pourrait tester que la signature incluse dans la requête corresponde à la clé publique (l'identificateur). Cette vérification laisserait la DHT vulnérable à d'autres attaques par déni de service, où l'attaquant ferait beaucoup de requêtes et imposerait donc beaucoup de vérifications. Pour parer cela, on peut imaginer une DHT qui impose que ses clients la contactent en HIP, réutilisant ainsi les protections anti-DoS de HIP. Et cela permettrait de s'assurer que le client n'enregistre des localisateurs que pour lui.
À noter enfin que OpenLookup est un exemple d'un service fournissant la même interface qu'OpenDHT même si, derrière, ce n'est pas une DHT.
Date de publication du RFC : Mai 2012
Auteur(s) du RFC : N. Duffield (AT&T Labs-Research), A. Morton (AT&T Labs), J. Sommers (Colgate University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 7 mai 2012
Le RFC 7680 définissait une métrique (une grandeur mesurable et spécifiée rigoureusement) pour le taux de pertes de paquets entre deux points du réseau. Mais un certain nombre de logiciels ne sont pas sensibles uniquement à la moyenne du taux de pertes mais aussi à sa répartition. Sur un flot de cent paquets, ce n'est pas la même chose d'en perdre trois, répartis au hasard, et d'en perdre trois de suite, par exemple pour certains protocoles multimédia qui encodent les différences entre paquets. Ce nouveau RFC définit donc des métriques pour caractériser les épisodes, ces pertes consécutives de paquets.
Par exemple, au taux de pertes moyen du RFC 7680, il serait intéressant d'ajouter la durée maximale d'un
épisode, ou bien la durée moyenne d'un épisode. Prenons les deux flots
suivants, où OK indique un paquet arrivé et LOST un paquet perdu : OK -
OK - LOST - LOST - LOST - OK - OK - OK - LOST - OK, puis LOST - OK -
LOST - OK - LOST - OK - LOST - OK - OK - OK.Le taux de pertes
moyen (Type-P-One-way-Packet-Loss-Average
du RFC 7680) est de 0,4 (40 % de paquets perdus) dans les
deux cas. Mais la longueur maximale d'un épisode est de 3 dans le
premier cas et de 1 dans le second, ce qui peut être important pour
certains protocoles, et n'apparaissait pas dans la moyenne. Ainsi, un
flux MPEG comporte des trames plus importantes
que les autres, les I-frames, et la perte de
paquets immédiatement consécutifs à la perte d'une
I-frame est peu importante (sans la
I-frame, ils ne servent à rien).
Première leçon à tirer de ce simple exemple, la notion de perte de paquets est une notion complexe dans l'Internet, où le trafic connaît des pics brutaux. Le modèle trivial de Bernoulli, où chaque perte est indépendante des autres, est clairement inadapté. De la même façon, comme illustré au paragraphe précédent, la simple moyenne n'est pas une description quantitative suffisante du phénomène. Des modèles plus markoviens ont été proposés (voir section 7), avec la notion d'épisode (période pendant laquelle on perd tous les paquets), en modélisant par des transitions entre une période normale et un épisode de pertes. Des RFC comme le RFC 3357 ou le RFC 3611 avaient déjà exploré cette voie. Mais ces modèles ne semblent pas avoir démontré d'intérêt pratique. L'approche de notre RFC est plus empirique : observer et quantifier le phénomène, sans chercher à le modéliser. Plusieurs mesures ont déjà été proposées comme l'IDC (Index of Dispersion of Counts) mais avec peu de succès. Notre RFC représente donc une nouvelle tentative pour décrire ce phénomène.
Ce RFC 6534 utilise des paires de paquets,
l'intervalle entre deux paquets indiquant la résolution temporelle de
la mesure (les épisodes plus courts que cet intervalle ne seront pas
vus). Première métrique définie, qui sert de base (section 2),
Type-P-One-way-Bi-Packet-Loss
. (Un
Bi-Packet = une paire.) La mesure donne (0, 0) si
les deux paquets sont arrivés, (1, 1) si les deux sont perdus,
etc. (Ce n'est peut-être pas intuitif mais le chiffre binaire indique
s'il y a eu une perte, donc 0 signifie le succès de la transmission.)
Ensuite, comme pour le RFC 7680, des
métriques moins élémentaires et plus utiles sont spécifiées à partir
de celle-ci. La section 3 définit
Type-P-One-way-Bi-Packet-Loss-Stream
, une suite
de résultats de la métrique précédente. Pour le premier exemple de cet
article, ce sera ((0, 0), (0, 1), (1, 1), (1, 1), (1, 0), (0, 0), (0, 0), (0,
1), (1, 0)). (0, 1) indique une transition vers un épisode de perte, (1, 0) la fin de cet épisode. La section 4
précise la même suite pour le cas où les intervalles de temps entre
paquets forment une distribution
géométrique.
Jusque là, l'intérêt pratique de ces définitions semble
faible. Avec la section 5, on en arrive presque à des métriques
utilisables (mais patientez encore un peu, le RFC parle de
« proto-métriques » pour la section
5). Par exemple, Loss-Pair-Counts
indique les fréquences de
chaque paire (dans l'exemple précédent 2/9 - 22 % - de (1,
1), 3/9 de (0, 0), 2/9 de (1, 0) et 2/9 de (0,
1). Bi-Packet-Loss-Episode-Duration-Number
, elle,
caractérise la longueur des épisodes (2 ici, car on ne compte pas le
premier paquet des épisodes de perte).
Et ensuite, en section 6, on définit les métriques de plus haut
niveau, la
Type-P-One-way-Bi-Packet-Loss-Geometric-Stream-Ratio
pour le pourcentage de paquets perdus, la
Type-P-One-way-Bi-Packet-Loss-Geometric-Stream-Episode-Duration
pour la durée (en secondes) des épisodes, la
Type-P-One-way-Bi-Packet-Loss-Geometric-Stream-Episode-Frequency
la fréquence des épisodes de perte, etc.
Voilà, nous avons maintenant nos métriques (je vous ai épargné la définition rigoureuse, indispensable mais aride : lisez le RFC pour la connaître).
Ah, un mot pour les juristes : il y a même eu des requins pour breveter des métriques, et des bureaux des brevets pour l'accepter. Voir la déclaration #1354.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : C. Newman (Sun Microsystems), A. Melnikov (Isode)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 18 février 2012
Dans l'ensemble des RFC sur l'internationalisation des adresses de courrier électronique, ce document traite le cas des accusés de réception (MDN, pour Message Disposition Notification) et avis de non-remise (DSN pour Delivery Status Notification).
Puisque les RFC 6531 et RFC 6532 permettent désormais d'utiliser des adresses de courrier électroniques internationalisées, c'est-à-dire utilisant tout le jeu de caractères Unicode, il faut prévoir le cas où les courriers provoquent l'envoi d'avis de remise ou de non-remise (DSN pour Delivery Status Notification, RFC 3461 et RFC 3464) et d'accusés de réception (MDN, pour Message Disposition Notification, RFC 8098). C'est l'objet de ce RFC, qui met à jour les anciens documents qui limitaient ces accusés et avis au jeu ASCII. Il fait suite au RFC 5337, qui n'était qu'expérimental. Désormais, les adresses de courrier en Unicode font partie des normes de l'Internet.
Le format des DSN dans le RFC 3464 parle de « types
d'adresse ». Les adresses en UTF-8 du RFC 6532 sont un nouveau type d'adresses. Si le
serveur SMTP accepte l'extension SMTPUTF8 du RFC 6531 et l'extension DSN du RFC 3461, il doit
permettre d'utiliser ce type dans le paramètre ORCPT
(Original Recipient, section 4.2 du RFC 3461). Si le
serveur n'accepte pas SMTPUTF8, l'adresse à utiliser dans les DSN doit
être encodée en 7bits, selon les règles exposées dans cette section 3. Par
exemple, stéphane@bortzmeyer.org
peut s'écrire
st\x{E9}phane@bortzmeyer.org
. (La
section 3 détaille plus complètement le traitement des adresses UTF-8,
et notamment les différentes formes qu'elles peuvent prendre, et les
encodages de certains caractères, comme l'espace ou la barre oblique
inverse, normalisé par le RFC 3461.)
Une fois réglé le problème de la représentation des adresses, la
section 4 traite les DSN en UTF-8. Les DSN traditionnels étaient
composés d'un objet MIME de type
multipart/report
(RFC 6522) comportant trois objets
décrivant le problème (un objet conçu pour être lu par un humain, un
message/delivery-status
et le message originel,
message/rfc822
). Pour le courrier
internationalisé, de nouveaux types ont été créés :
message/global-delivery-status
qui,
contrairement à son prédécesseur
message/delivery-status
, accepte l'UTF-8 et
permet donc de placer directement les adresses UTF-8, sans encodage en
ASCII. En
outre, il dispose d'un nouveau champ,
Localized-Diagnostic, qui permet de stocker des
messages lisibles par un humain. La langue de ces messages est
indiquée par une étiquette de langue (RFC 5646). (Le champ Diagnostic-Code est
désormais en UTF-8, mais dans la langue par défaut du système,
cf. i-default
dans le RFC 2277.)message/global
qui remplace
message/rfc822
(dont le nom, hommage au vieux
RFC 822, était de toute façon dépassé). À noter que le terme global
(mondial) utilisé pour noter ce type avait fait l'objet de vives
discussions et même d'un vote. Cet objet permet de
transporter le message original (si on ne transporte que les en-têtes,
on utilise message/global-headers
).
On peut noter que la norme MIME (RFC 2046) interdisait l'usage de l'option
Content-Transfer-Encoding
pour les objets de type
message/*
mais cette règle a été assouplie par le
RFC 5335.
La section 5 traite des MDN (Message Disposition
Notification, RFC 3798). Ils ne sont pas très
différents des DSN et ont un format très proche, avec un type MIME message/global-disposition-notification
.
La section 6 traite des registres
IANA. Le type « UTF-8 » est ajouté au registre des types d'adresses
(section 6.1), et les nouveaux types MIME qui avaient été créés par
les premiers RFC expérimentaux, comme
message/global
sont ajoutés au registre des types MIME (sections 6.3
à 6.5).
Enfin, la section 7 est dédiée aux questions de sécurité. Il y a les problèmes de sécurité classiques des DSN et des MDN : non authentifiés, ils permettent de faire croire qu'un message a échoué, alors qu'il a bien été délivré, ou le contraire. Et les DSN et MDN reçus sont souvent émis en réponse à des messages faux, qui n'avaient pas été émis par l'utilisateur. D'autre part, le RFC nous prévient que des DSN ou des MDN délibérement incorrects peuvent être envoyés par un attaquant dans l'espoir de profiter d'erreur dans la programmation des analyseurs, par exemple pour déclencher un débordement de tampon. Le risque est plus important s'il y a beaucoup d'encodage, le décodage pouvant faire varier la taille des données.
Quels sont les changements depuis le RFC expérimental, le RFC 5337 ? L'annexe A les résume, les principaux étant la suppression de tout ce qui concernait le mécanisme de repli (downgrade), mécanisme complexe qui avait été normalisé pour gérer les cas où un serveur sur le chemin ne pouvait pas transmettre les adresses en UTF-8. Trop délicat, ce mécanisme a été retiré de la version normalisée de ces adresses.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : A. Yang (TWNIC), S. Steele (Microsoft), N. Freed (Oracle)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 18 février 2012
Dans l'ensemble des RFC qui décrivent les adresses de courrier électronique internationalisées (c'est-à-dire pouvant utiliser tout le répertoire Unicode), celui-ci se consacre au nouveau format des en-têtes, complétant celui normalisé dans le RFC 5322.
Désormais, on peut avoir dans un message un en-tête comme :
From: Stéphane Bortzmeyer <stéphane@sources.org>
Oui, avec du vrai UTF-8, y compris dans l'adresse proprement dite, pas seulement dans les commentaires, et encore, à condition de les surencoder selon le RFC 2047 comme c'était le cas avant (méthode inélégante et inefficace). Cette possibilité d'utiliser directement UTF-8 avait été créée par le RFC 5335, qui n'avait que le statut « Expérimental ». Désormais, ce mécanisme est complètement normalisé, en partie parce que de plus en plus de logiciels savent traiter directement l'UTF-8.
L'un des éditeurs du RFC travaille à TWNIC, le
registre chinois de .tw. Les
Chinois ont, fort logiquement, été
particulièrement actifs dans tout le processus EAI (Email Addresses Internationalization). Celui-ci visait à
terminer l'internationalisation du courrier électronique, qui avait
passé une étape décisive en novembre 1996, avec la sortie du RFC 2045 sur MIME. Mais cette norme MIME
n'internationalisait que le corps des messages. EAI permet
d'internationaliser également les en-têtes comme
From:
, Subject:
ou Received:
(mais
pas, par exemple, Date:
, qui restera en ASCII pur ; Date:
est censé
être analysé par le MUA et présenté ensuite à
l'utilisateur dans sa langue).
EAI comprend plusieurs RFC, par exemple le RFC 6530
définit le cadre général, le RFC 6531, l'utilisation des
adresses Unicode dans SMTP (avec l'extension
SMTPUTF8
), les RFC ou futurs RFC sur
POP (RFC 5721) ou IMAP (RFC 5738) et notre RFC 6532, qui se concentre sur le format des messages. Il
suppose que le transport sera « 8-bits clean », c'est-à-dire
laissera passer les octets qui codent les données UTF-8 sans les
modifier (le cas des vieux systèmes qui ne gèrent pas proprement les
caractères non-ASCII est délibérement laissé de côté).
Concrètement, que change donc ce RFC ? La section 3 détaille ce qui est modifié, par extension de la grammaire du RFC 5322) :
Message-ID:
est traité à part
(section 3.3). Les caractères UTF-8 y sont autorisés mais déconseillés
(le RFC rappelle que cet en-tête sert à former automatiquement
d'autres en-têtes comme In-Reply-To:
).From:
ou To:
)
est modifiée pour accepter UTF-8. Pour les sites qui utilisent une
adresse électronique comme identificateur, comme le fait
Amazon.com, ce sera un intéressant
défi !message/global
, pour permettre d'identifier un
message EAI (section 3.7). Les messages de ce type ne doivent être
transportés qu'avec des protocoles 8-bits clean
comme celui du RFC 6531.Parmi les conséquences pratiques de ce changement, il faut noter que les programmeurs qui écrivent des logiciels traitant le courrier doivent désormais gérer Unicode, même s'ils se contentent d'analyser les en-têtes... L'époque du courrier traité avec des scripts shell est bien passée.
Autre point important pour les programmeurs, les limites de taille des en-têtes (qui étaient de 998 caractères maximum et 78 recommandés) changent de sémantique (section 3.4) puisque, en UTF-8, un caractère ne fait plus forcément un octet. Les limites sont désormais de 998 octets et 78 caractères (cette seconde limite étant conçue pour tenir sur l'écran). Attention aussi à la section 4, qui rappelle le risque de débordement de tampons.
La section 4 liste également quelques conséquences pour la sécurité comme le fait qu'un mécanisme d'authentification devra être prêt à gérer plusieurs adresses pour la même personne (car, pendant un certain temps, plusieurs utilisateurs auront à la fois une adresse en Unicode et une en ASCII pur).
Les changements depuis le RFC 5335 sont résumés dans la section 6 du RFC 6530. Le principal est la suppression de la possibilité de repli (downgrading) automatique vers des adresses en ASCII pur.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : J. Yao (CNNIC), W. Mao (CNNIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 18 février 2012
Dans la grande série des RFC décrivant les adresses de courrier internationalisées, ce document traite des modifications au protocole SMTP. Il succède au RFC 5336, qui avait créé ces modifications mais qui n'avait que le statut « Expérimental ». Désormais, ces extensions internationales sont sur le Chemin des Normes de l'IETF.
Plusieurs RFC composent la nouvelle norme EAI ou « Email Addresses Internationalized » (cf. RFC 6530). Les deux principaux concernent le format des messages (RFC 6532) et le dialogue entre deux serveurs de messagerie, suivant le protocole SMTP. Ce dernier cas est couvert dans notre RFC 6531.
Les adresses de courrier en Unicode ne sont
pas en effet compatibles avec le SMTP « brut ». Ainsi, la commande
RCPT TO
qui permet d'indiquer le destinataire, ne
prend en paramètre que de l'ASCII. Et les en-têtes du
courrier peuvent désormais être en UTF-8 (RFC 6532). Il faut donc
étendre SMTP (actuellement normalisé en RFC 5321) pour
permettre de l'UTF-8 en paramètre de commandes
comme MAIL FROM
et RCPT
TO
. Cette extension se signale avec l'option
SMTPUTF8
(l'ancien RFC, le
RFC 5336, utilisait UTF8SMTP
), dont l'usage permet de vérifier que le
MTA situé en face comprend bien la nouvelle
norme (sections 1 et 2 du RFC).
La section 3 forme le gros du RFC en spécifiant rigoureusement le nouveau protocole. Voyons d'abord un exemple de dialogue SMTP avec la nouvelle extension (C est le client - l'appelant - et S le serveur - l'appelé). Notre RFC 6531 ne modifie pas SMTP (RFC 5321), il l'étend :
S: 220 mail.example.org ESMTP Foobar (Debian/GNU) C: EHLO mail.iloveunicode.example S: 250-mail.example.org 250-ENHANCEDSTATUSCODES 250-8BITMIME 250-SMTPUTF8 250 DSN C: MAIL FROM:<stéphane@internet-en-coopération.fr> SMTPUTF8 S: 250 2.1.0 Ok C: RCPT TO: <françoise@comptabilité.example.org> S: 250 2.1.5 Ok
Notez les deux adresses, chacune comprenant des caractères non-ASCII, à gauche et à droite du @.
Les serveurs qui mettent en œuvre l'extension
SMTPUTF8
doivent également accepter la très
ancienne extension 8BITMIME
(RFC 6152)
qui permet, depuis belle lurette, de ne pas se limiter à l'ASCII dans
le contenu des messages, sans pour autant nécessiter des encodages
comme Quoted-Printable (en dépit de ce que
prétend une légende tenace).
Les sections 3.1 et 3.2 présentent la nouvelle extension,
SMTPUTF8
(enregistrée à l'IANA, cf. section 4.1). Les extensions SMTP sont définies par
le RFC 5321, section 2.2. Un MTA peut annoncer
qu'il accepte SMTPUTF8, permettant à son pair, s'il l'accepte également,
d'utiliser des adresses UTF-8. C'est également cette section qui
définit ce que doit faire un MTA lorsqu'il tente de transmettre un
message internationalisé à un ancien MTA qui ne gère pas cette
extension. Trois solutions sont possibles, dont le rejet complet du message
(retour à l'expéditeur) et un effort pour trouver une route
alternative, passant par des serveurs plus modernes (le RFC 5336 avait un quatrième mécanisme, le repli
- downgrade - qui a été abandonné après usage, car
trop complexe et trop imprédictible).
La section 3.3 décrit la nouvelle syntaxe pour les adresses. L'ancienne était limitée à ASCII mais très permissive (bien qu'on trouve, notamment derrière les formulaires Web, énormément de logiciels de « vérification » bogués). En gros, la syntaxe est qu'une adresse est formée de deux parties, la partie locale et le nom de domaine, tous les deux séparés par l'arobase. La nouveauté est que les deux parties peuvent désormais être en Unicode, avec peu de restrictions sur la partie locale (le nom de domaine étant soumis aux restrictions du RFC 5890).
Il y a plein d'autres détails dans cette section 3, comme celui
(section 3.7.1) que
le paramètre de la commande EHLO
(un nom de
machine) doit être encodé en Punycode puisque,
à ce stade, on ne sait pas encore si SMTPUTF8 est accepté ou pas.
Les changements depuis le RFC 5336 sont
résumés dans la section 6 du RFC 6530. Le
principal est la suppression de la possibilité de
repli (downgrading)
automatique vers des adresses en ASCII pur. Le paramètre ALT-ADDRESS
disparait donc.
Cette extension de SMTP ne semble pas mise en œuvre dans les
grands logiciels libres classiques comme
sendmail ou exim. Pour
Postfix, l'auteur a clairement exprimé son
manque d'enthousiasme. Il existe des
patches non-officiels
développés en Chine, pour Postfix http://www.cdnc.org/gb/news/src-EAI.tar.gz
(l'archive comprend
également d'autres logiciels, d'où sa taille) et pour sendmail
http://www.cdnc.org/gb/news/twnic.zip
. La société
chinoise Coremail est en train de travailler à un produit commercial
basé sur ces patches.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : J. Klensin, Y. Ko (ICU)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 18 février 2012
Parmi les protocoles utilisés sur
Internet, presque tous sont internationalisés
depuis longtemps. Le dernier gros manque concernait les adresses de
courrier électronique, obligées de s'en tenir à
stephane@internet-en-cooperation.fr
alors qu'on voudrait pouvoir
écrire à
stéphane@internet-en-coopération.fr
. Désormais,
nous avons une solution standard, Internationalized
Email Addresses.
Bien sûr, pour l'exemple ci-dessus, le gain n'est pas évident. Mais il l'est beaucoup plus si vous voulez écrire votre adresse avec l'écriture arabe ou chinoise. (Cf. section 3 pour la description du problème, section qui exprime clairement le fait qu'un Chinois a le droit d'avoir une adresse en sinogrammes, comme un Occidental jouit des avantages d'une adresse en caractères latins.)
Le contenu des courriers était internationalisé
depuis longtemps, au moins depuis MIME (RFC 1341 à l'origine, en juin 1992). De même, certains en-têtes
comme le sujet ou même comme le nom de l'expéditeur dans le champ
From:
- mais pas son adresse - pouvaient être
internationalisés via MIME (RFC 2047). Mais les adresses ne l'étaient pas
encore et ce manque de cohérence (possibilité d'utiliser des écritures
non-latines à certains endroits mais pas à d'autres) rendait le
courrier peu attirant pour M. Ali ou M. Wu. Notre RFC, qui remplace le RFC 4952 qui
n'était qu'expérimental, décrit le cadre général de l'internationalisation
des adresses de courrier. Il y avait depuis longtemps des messages internationaux, il y a désormais également des adresses internationales.
Il y a deux parties à l'adresse (décrites dans le RFC 5322) : la partie locale, à gauche du @ et le nom de domaine à droite. Si ce nom de domaine, depuis la sortie du RFC 3490, en mars 2003, peut s'écrire en Unicode (norme IDN), le courrier exigeait toujours un nom de domaine en ASCII donc un message de non-délivrance, par exemple, allait affichait la forme Punycode du nom. Ce n'était pas une vraie internationalisation.
Le cadre d'internationalisation du courrier couvre plusieurs aspects, couverts chacun par un RFC. Ce RFC expose l'architecture générale. La section 5 décrit le fonctionnement du nouveau système.
SMTP est modifié pour permettre une nouvelle
extension, SMTPUTF8
, indiquant le support du courrier internationalisé (RFC 6531).
Le format des messages (RFC 5322) est modifié
pour permettre d'inclure de l'Unicode, encodé
en UTF-8, directement dans les en-têtes, comme
le champ To:
(RFC 6532). Les autres charsets (comme
UTF-32) ne sont pas prévus.
Le format des accusés de réception est modifié pour permettre des rapports de remise ou de non-remise lorsque l'expéditeur ou le destinataire avaient des adresses Unicode (RFC 6533).
Plusieurs autres protocoles « auxiliaires » seront également
modifiés, par exemple pour les listes de
diffusion (RFC 6783) ou pour
IMAP et POP. Même chose
pour des formats comme les IRI de plan
mailto:
(section 11.1 de notre RFC, RFC 3987 et RFC 6068).
Notons (section 11.2 du RFC) que les adresses de courrier sont utilisés en de nombreux
endroits, par exemple comme identificateurs sur certains sites Web de
commerce électronique, comme Amazon et que ces
utilisateurs vont également devoir s'adapter. Quant on voit le nombre
de sites, supposés professionnels, qui continuent à interdire des
adresses de courrier légales, on mesure
l'ampleur
du travail. La section 10, elle aussi, décrit des questions
liées à l'interface utilisateur. Par exemple, elle rappelle qu'il y a
toujours eu des cas délicats dans la syntaxe, dont il est plus
prudent de se tenir à l'écart. Ainsi, la partie gauche d'une adresse
est sensible à la casse donc, en théorie, on
pourrait avoir une adresse Stephane@bortzmeyer.fr
et que le courrier bêtement envoyé à
stephane@bortzmeyer.fr
n'atteindrait pas. Inutile
de dire que peu de MTA mettent en œuvre
une telle distinction... Dans le cas des adresses internationalisées,
il faut donc prendre garde à la canonicalisation
Unicode. Au minimum, il faudrait accepter la canonicalisation en
NFC de toute adresse, car cette
canonicalisation aura peut-être lieu quelque part dans le chemin, qu'on le veuille ou pas.
Les changements par rapport à l'ancien cadre (RFC 4952 et ses copains) sont décrits dans les sections 6 et 12. La section 6 fait en outre le bilan de la phase expérimentale. Désormais, les adresses de courrier internationalisées ont le statut de norme et non plus de simple expérience. Le principal changement technique, de loin, est la suppression du repli. Le repli (downgrading, cf. RFC 5504 et RFC 5825) était prévu pour le cas où un émetteur internationalisé rencontrerait un récepteur qui ne l'est pas, nécessitant une modification des adresses en ASCII. En effet, contrairement à HTTP, le courrier ne fonctionne pas de bout en bout et le message est relayé par plusieurs serveurs, qu'on ne connaît pas forcément a priori.
Le repli était certainement la partie la plus complexe : modifier un message est toujours une opération délicate, notamment en présence de signatures cryptographiques (section 11.3), que le repli ne doit pas invalider ! Tellement complexe que sa mise en œuvre s'est avérée très délicate et que les différentes implémentations avaient du mal à interagir. En outre, l'expérience a montré que le fait de devoir gérer deux adresses (celle en Unicode et une en ASCII pour le repli), sans lien sécurisé entre les deux, était une belle source de problèmes. Résultat, par rapport aux RFC de la phase expérimentale, le repli a été abandonné. Désormais, un courrier internationalisé ne pourra tout simplement pas être transmis à travers les vieux serveurs, ce sera au MUA ou à l'utilisateur de trouver une solution de rechange (cf. section 8, qui détaille les solutions). On note que la phase expérimentale, dont beaucoup de RFC ne sortent jamais, a été ici utile, permettant, par la pratique, d'atteindre un très large consensus sur un point qui était précédemment fortement discuté.
Un deuxième changement technique important par rapport aux premiers RFC sur ce sujet est que, en SMTP, le client aussi bien que le serveur doit signaler sa volonté d'utiliser les nouvelles adresses.
La section 8 décrit plus en détail la marche à suivre si le serveur suivant ne gère pas les adresses Unicode (par exemple, on peut prévoir que certains administrateurs activeront les adresses Unicode sur le serveur de courrier principal du domaine et oublieront le MX secondaire). Elle n'est pas normative puisque c'est largement une question d'interface utilisateur, quelque chose que l'IETF ne fait pas normalement. Comme le note cette section, le meilleur repli est celui fait manuellement par l'utilisateur, car celui-ci est intelligent et motivé. Néanmoins, si on tient à faire du repli automatique, il peut être fait par le MUA, ou bien par une future extension au protocole de soumission (RFC 4409). Ça, c'était pour le cas où le serveur ancien était le premier de la chaîne. Et si le problème d'un serveur non-Unicode survient en cours de route, lorsqu'un MTA se rend compte que le MTA suivant ne convient pas ? La section 9 rappelle qu'il est désormais strictement interdit aux MTA de tripoter le message et il n'y a donc rien d'autre à faire que d'indiquer une erreur, qui sera remontée à l'utilisateur.
Et si le problème survient une fois le message délivré, parce que le protocole de récupération n'a pas été adapté aux adresses Unicode ? Le problème est là encore formellement en dehors du cadre, le RFC notant juste que le MDA peut faire un repli automatique s'il le juge utile.
Cette extension du courrier ne semble pas encore implémentée officiellement dans les logiciels classiques de courrier, malgré la longue période des RFC expérimentaux.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : F. Gont (SI6 Networks / UTN-FRH), S. Bellovin (Columbia University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 2 février 2012
Ce court RFC spécifie les précautions que doit prendre une mise en œuvre de TCP pour éviter qu'un attaquant ne puisse deviner le numéro de séquence initial. Rien de nouveau, les précautions en question étant programmées dans TCP depuis de nombreuses années, juste un rappel et une mise à jour du précédent RFC sur ce sujet, le RFC 1948. Il a depuis été intégré dans le RFC 9293.
Pour comprendre le problème de sécurité des numéros de séquence, et les solutions présentées dans ce RFC, il vaut mieux revenir à l'attaque qui exploitait les anciennes vulnérabilités. C'est fait dans l'annexe A du RFC, que je reprends ici.
Le but de l'attaquant est de s'en prendre à un serveur qui autorise par adresse IP. À l'époque du RFC 1948, cela concernait rsh mais, de nos jours, SSH a complètement remplacé cet archaïque protocole. Aujourd'hui, ce serait plutôt un serveur DNS qui authentifie le transfert de zones ainsi, ou bien un serveur SMTP qui autorise seulement certaines adresses IP à passer par lui - même s'il ferait mieux de se servir du RFC 4954, ou encore un serveur HTTP qui ne permet l'invocation de certaines actions qu'aux utilisateurs de certaines adresses. En deux mots, dès que l'autorisation se fait par adresse IP uniquement, il faut s'assurer que vous utilisez un TCP qui mette en œuvre les recommandations de ce RFC 6528.
On le sait, il est trivial pour un attaquant d'envoyer des paquets avec une fausse adresse IP source (le RFC 2827, censé l'empêcher, n'étant quasiment pas déployé). Mais, dans ce cas, l'attaquant ne reçoit pas les réponses. Or, si on veut maintenir une connexion TCP avec sa victime, il faut lui envoyer des paquets avec les données qu'elle attend, notamment le numéro de port et les numéros de séquence. Sinon, la victime va jeter ces paquets TCP qui lui sembleront anormaux. Pour les numéros de port, le RFC 6056 s'en occupe. Pour les numéros de séquence, voyons ce qui se passe. Tout paquet TCP doit inclure ces numéros, un pour chaque sens de la conversation (RFC 793, section 3.3). Ce numéro identifie l'octet suivant à envoyer. Une ouverture de connexion TCP normale ressemble donc, pour le cas où Alice veut parler à Bob, à :
SYN
est mis, avec un numéro de séquence initial
ISNa - ISN = Initial Sequence Number.)Voici d'ailleurs, vu par tcpdump, un exemple d'ouverture de connexion (vers le dépôt git de Linux) :
% tcpdump -S -n -r tmp/3wayhandshake.pcap reading from file tmp/3wayhandshake.pcap, link-type EN10MB (Ethernet) 09:47:53.086347 IP 192.134.6.69.39859 > 149.20.4.72.9418: Flags [S], seq 3366079112, ... 09:47:53.242880 IP 149.20.4.72.9418 > 192.134.6.69.39859: Flags [S.], seq 3075029842, ack 3366079113, ... 09:47:53.242910 IP 192.134.6.69.39859 > 149.20.4.72.9418: Flags [.], ack 3075029843, ...
Le S
entre crochets indique un paquet
SYN
. L'option -S
est là pour indiquer à tcpdump
d'afficher les numéros de séquence absolus, tels qu'ils sont envoyés
sur le câble (par défaut, il montre des numéros relatifs, sauf pour
les paquets SYN
). On note aussi que tcpdump
n'affiche pas le premier numéro de séquence s'il n'y a pas de données,
et n'affiche pas le second si le bit ACK
n'est
pas mis.
Le deuxième paquet n'a été accepté par Alice que parce qu'il contenait un numéro de séquence attendu. Même chose pour le troisième. Un attaquant qui procéderait au hasard, envoyant des numéros de séquence quelconques, n'aurait aucune chance que ses paquets soient acceptés. Imaginons maintenant que l'attaquant puisse connaître les numéros de séquence utilisés. Bob fait confiance à Alice mais Mallory, l'attaquant, va se faire passer pour Alice. Mallory n'est pas situé sur le chemin entre Alice et Bob (sinon, cela serait trivial, il lui suffirait d'écouter le réseau) :
SYN
est mis, avec un numéro de séquence initial
ISNa.)Et comment Mallory a-t-il trouvé le numéro de séquence que va utiliser Bob ? Le RFC originel, le RFC 793 ne mettait pas du tout en garde contre cette attaque, inconnue à l'époque (1981). Il ne se préoccupait que du risque de collision accidentel entre deux connexions et suggérait donc un algorithme où l'ISN était simplement incrémenté toutes les quatre micro-secondes, ce qui le rendait très prévisible (l'attaquant ouvre une connexion, regarde l'ISN, et sait quel va être celui de la prochaine connexion). Le premier article décrivant une faiblesse dans les mises en œuvre de TCP, faiblesse permettant de trouver le prochain numéro de séquence, a été publié en 1985 (Morris, R., A Weakness in the 4.2BSD UNIX TCP/IP Software, CSTR 117, AT&T Bell Laboratories). À l'époque, elle était suffisante pour établir des sessions rsh avec la victime.
À noter qu'Alice, elle, reçoit l'accusé de réception de Bob, auquel
elle ne s'attend pas. Elle va donc émettre un paquet
RST
qui va fermer la connexion. Diverses
techniques permettent à l'attaquant de réussir quand même (par exemple
en montant au même moment une attaque DoS
contre Alice pour ralentir ses paquets, donnant à l'attaque le temps de réussir).
C'est pour répondre à cette attaque que le RFC 1948 avait été écrit en 1996,
documentant la pratique qui était devenue courante, de générer des
numéros de séquence, sinon aléatoires, en tout cas
imprévisibles. (Un article plus récent et plus détaillé sur la
vulnérabilité initiale était celui de Shimomura, T., Technical
details of the attack described by Markoff in NYT,
envoyé sur Usenet, en
comp.security.misc
, Message-ID:
<3g5gkl$5j1@ariel.sdsc.edu>
, en 1995.) Notre RFC 6528 met à jour ce RFC 1948. La section 2 expose les principes d'un bon algorithme de
génération d'ISN (Initial Sequence Number), la
section 3 décrit l'algorithme proposé. Commençons par celui-ci. Il
tient en une formule :
ISN = M + F(localip, localport, remoteip, remoteport)
où M est un compteur qui s'incrémente toutes les quatre micro-secondes, et F une fonction pseudo-aléatoire, qui va prendre comme paramètre le tuple qui identifie une connexion TCP (adresse IP locale, port local, adresse IP distante, port distant). F ne doit pas être prévisible de l'extérieur et le RFC suggère une fonction de hachage cryptographique, comme MD5 (RFC 1321), hachant le tuple ci-dessus après l'avoir concaténé à une clé secrète. La sécurité reposera sur cette clé, l'algorithme de hachage utilisé étant sans doute connu. On peut envisager qu'elle soit générée aléatoirement (vraiment aléatoirement, en suivant le RFC 4086), ou configurée à la main (en espérant que l'ingénieur système ne choisira pas « toto »). Il est recommandé de la changer de temps en temps.
Notez que, bien que MD5 ait de nombreuses faiblesses cryptographiques pour d'autres utilisations, il est parfaitement sûr pour celle-ci (et bien plus rapide que ses concurrents).
La section 2, elle, définissait le cahier des charges :
qu'attend t-on d'un algorithme de sélection de l'ISN ? D'abord, il
n'est pas forcé d'empêcher des vieux paquets IP
qui traînent dans le réseau d'être acceptés. Pour cela, il vaut mieux
compter sur l'état TIME_WAIT
de TCP (après la fin
d'une connexion, garder l'état pendant deux MSL - Maximum
Segment Life, cf. RFC 7323). Ça ne
marche pas forcément si les connexions sont créées à un rythme très
rapide mais c'est la seule solution sûre (mais consommant de la mémoire). On peut lire à ce sujet deux
articles sur les générateurs d'ISN, leurs avantages et inconvénients, « Strange Attractors and TCP/IP Sequence
Number Analysis » et « Strange Attractors and TCP/IP
Sequence Number Analysis - One Year Later ».
Compte-tenu de ces risques, une génération aléatoire de l'ISN suffirait. Mais elle aurait l'inconvénient de de ne pas permettre de deviner si un nouveau paquet TCP appartient à une ancienne connexion ou pas. L'idée de base de ce RFC est donc de créer un espace de numéros de séquence par identificateur TCP (le tuple {adresse IP locale, port local, adresse IP distante, port distant}) et, dans chacun de ces espaces, de suivre les règles d'incrémentation progressive de l'ISN du RFC 793.
Pour ceux qui veulent pousser l'analyse de sécurité, la section 4
prend de la hauteur et rappelle quelques points importants. D'abord
que la vraie solution serait évidemment de protéger les paquets IP par
de la cryptographie comme le fait
IPsec, ou au niveau TCP comme le fait le TCP-AO
du RFC 5925 (TLS ou
SSH ne suffisent pas, ils n'empêchent pas une
attaque par déni de service avec des faux
paquets TCP RST
).
La section 4 fait aussi remarquer que rien n'est parfait et que l'algorithme proposé dans notre RFC a des effets de bord, comme de permettre le comptage du nombre de machines qui se trouvent derrière un routeur NAT, ce qui peut être une information qu'on souhaiterait garder privée.
Et, surtout, elle rappelle que toutes les précautions de notre RFC 6528 ne s'appliquent que si l'attaquant est en dehors du chemin entre les deux pairs TCP. S'il est sur le chemin et qu'il peut écouter le réseau, elles ne servent à rien.
Quels sont les changements depuis le RFC 1948 ? Il n'y a pas de changement sur le fond (l'algorithme est le même donc un TCP compatible avec le RFC 1948 l'est également avec le RFC 6528). Les changements sont résumés dans l'annexe B. Le statut du RFC a changé (désormais sur le chemin des normes), les exemples maintenant dépassés par l'évolution des techniques ont été mis à jour ou supprimés,
On l'a dit, les précautions décrites dans ce RFC sont présentes
dans les implémentations depuis longtemps. Pour un exemple de mise en œuvre de cet algorithme, on peut
regarder le code source de NetBSD. Il se trouve
en sys/netinet/tcp_subr.c
. Son comportement est
contrôlé par la variable sysctl
iss_hash
. Mise à 1, elle indique qu'il faut
utiliser l'algorithme ci-dessus. À 0, qu'il faut utiliser une valeur
aléatoire. Prenons le premier cas, celui de notre RFC. On voit la
génération du secret (un nombre aléatoire, issu de
cprng_strong()
) puis le hachage
MD5 de l'identifiant de connexion avec le secret :
/* * If we haven't been here before, initialize our cryptographic * hash secret. */ if (tcp_iss_gotten_secret == false) { cprng_strong(kern_cprng, tcp_iss_secret, sizeof(tcp_iss_secret), 0); tcp_iss_gotten_secret = true; } /* * Compute the base value of the ISS. It is a hash * of (saddr, sport, daddr, dport, secret). */ MD5Init(&ctx); MD5Update(&ctx, (u_char *) laddr, addrsz); MD5Update(&ctx, (u_char *) &lport, sizeof(lport)); MD5Update(&ctx, (u_char *) faddr, addrsz); MD5Update(&ctx, (u_char *) &fport, sizeof(fport)); MD5Update(&ctx, tcp_iss_secret, sizeof(tcp_iss_secret)); MD5Final(hash, &ctx); memcpy(&tcp_iss, hash, sizeof(tcp_iss)); return (tcp_iss);
Pour Linux (remerciements au passage à @ackrst), il faut regarder le
net/core/secure_seq.c
qui contient à peu près la
même chose (la variable net_secret
est
initialisée au tout début de ce fichier) :
__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport) { u32 hash[MD5_DIGEST_WORDS]; hash[0] = (__force u32)saddr; hash[1] = (__force u32)daddr; hash[2] = ((__force u16)sport << 16) + (__force u16)dport; hash[3] = net_secret[15]; md5_transform(hash, net_secret);
Date de publication du RFC : Janvier 2012
Auteur(s) du RFC : M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 17 janvier 2012
Un court RFC pour un format simple : le type
MIME multipart/report
permet d'envoyer des rapports structurés au sujet d'un message. Ce RFC est la
dernière version de la norme sur
multipart/report
, marquée par un léger allègement
des règles d'utilisation.
Pas de grands changements, sinon. L'idée de base de
multipart/report
est de pouvoir faire des
messages à propos des messages. Par exemple, un avis de non-remise
(RFC 3461) est un message disant qu'un message
n'a pu être remis, et intégrant le message originel. Un rapport
ARF (RFC 5965) est un message disant qu'un message est
abusif (spam, par exemple) et intégrant
également le message originel. D'où l'idée d'avoir un type commun pour
tous ces « messages sur les messages », et c'est
multipart/report
, normalisé dans notre RFC 6522, qui succède au RFC 3462 (qui
succédait lui-même au RFC 1892). Ce type
multipart/report
est très largement utilisé
depuis longtemps, et par de nombreux logiciels.
La présentation détaillée du type « rapport » figure en section 3. Voici d'abord un exemple d'un tel message, ici pour indiquer une non-délivrance, généré par un MTA Postfix :
Date: Wed, 11 Jan 2012 13:45:44 +0000 (UTC) From: MAILER-DAEMON@bortzmeyer.org (Mail Delivery System) Subject: Undelivered Mail Returned to Sender To: bortzmeyer@nic.fr Auto-Submitted: auto-replied MIME-Version: 1.0 Content-Type: multipart/report; report-type=delivery-status; boundary="154CD3AC2C.1326289544/mail.bortzmeyer.org" Content-Transfer-Encoding: 8bit This is a MIME-encapsulated message. --154CD3AC2C.1326289544/mail.bortzmeyer.org Content-Description: Notification Content-Type: text/plain; charset=us-ascii [La première partie du rapport, lisible par un humain.] This is the mail system at host mail.bortzmeyer.org. I'm sorry to have to inform you that your message could not be delivered to one or more recipients. It's attached below. --154CD3AC2C.1326289544/mail.bortzmeyer.org Content-Description: Delivery report Content-Type: message/delivery-status [La deuxième partie du rapport, conçue pour être analysée par des programmes.] Reporting-MTA: dns; mail.bortzmeyer.org X-Postfix-Queue-ID: 154CD3AC2C X-Postfix-Sender: rfc822; bortzmeyer@nic.fr Arrival-Date: Wed, 11 Jan 2012 12:24:50 +0000 (UTC) Final-Recipient: rfc822; nothere@nowhere.example Action: failed Status: 5.4.4 Diagnostic-Code: X-Postfix; Host or domain name not found. Name service error for name=nowhere.example type=AAAA: Host not found --154CD3AC2C.1326289544/mail.bortzmeyer.org Content-Description: Undelivered Message Content-Type: message/rfc822 Content-Transfer-Encoding: 8bit [Puis le message originel, dans la troisième partie du rapport.]
Notez le paramètre report-type
, qui a ici la
valeur delivery-status
. (Cela serait
feedback-report
pour du ARF.)
Notez surtout le découpage en trois parties (la dernière est optionnelle) :
message/delivery-status
du RFC 3464).Si on trouve le message originel trop gros, la troisième partie
peut se composer uniquement des en-têtes du message. Elle aura alors
le type message/rfc822-headers
(section 4 de
notre RFC).
Naturellement, les messages multipart/report
ne sont pas plus authentifiés que les autres messages : il faut donc
éviter d'agir automatiquement lors de leur réception (section 7).
Le seul changement de fond depuis le RFC 3462
concerne une ancienne restriction :
multipart/report
ne pouvait apparaître qu'au plus
haut niveau du message (rappelez-vous que MIME
est récursif, un message MIME peut contenir d'autres messages
MIME). Cela interdisait, par exemple, de faire un
multipart/report
au sujet d'un
multipart/report
. Il semble bien que personne ne
mettait en œuvre cette restriction et ce nouveau RFC 6522 l'a donc supprimé. (Voir section 1.)
Date de publication du RFC : Février 2012
Auteur(s) du RFC : R. Seggelmann, M. Tuexen (Muenster Univ. of Appl. Sciences), M. Williams
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 8 février 2012
Dernière mise à jour le 8 avril 2014
Le protocole de cryptographie TLS ne disposait pas en standard de mécanisme de « battement de cœur », permettant de tester qu'une connexion est toujours vivante. C'est désormais chose faite. Grâce à la nouvelle extension de TLS, normalisée dans ce RFC, deux pairs TLS peuvent s'assurer, par un mécanisme standard, que l'autre pair est bien là, et répond.
Savoir si l'autre partie de la connexion est toujours là est souvent utile en matière de réseau. Les sessions qui utilisaient TLS (RFC 5246) ou DTLS (RFC 6347) ne disposaient pas d'un moyen générique de tester si le cœur du pair battait toujours. Les applications devaient donc envoyer des données inutiles et attendre une réponse. Une autre solution était de faire une renégociation (RFC 5246, section 7.4.1) mais cette opération est coûteuse en calculs cryptographiques. C'était encore pire avec DTLS, qui est parfois utilisé dans des applications unidirectionnelles, où aucune réponse applicative n'est prévue.
Désormais, les mises en œuvre de TLS qui gèrent la nouvelle
extension, Heartbeat
, pourront envoyer des
messages HeartbeatRequest
, auxquels le pair devra
répondre avec un HeartbeatResponse
. Cette
extension est spécifiée au moment de la négociation (section 2), dans
les messages Hello
(RFC 5246, section
7.4.1). Dans la syntaxe vaguement analogue à ASN.1 de TLS, la
nouvelle extension est décrite par :
enum { peer_allowed_to_send(1), peer_not_allowed_to_send(2), (255) } HeartbeatMode; struct { HeartbeatMode mode; } HeartbeatExtension;
Le mode peer_not_allowed_to_send
est là pour
indiquer qu'une machine veut utiliser l'extension pour tester son pair
mais qu'elle-même ne répondra pas aux requêtes
HeartbeatRequest
. La nouvelle extension est enregistrée à l'IANA (numéro 15).
Une fois que les deux parties se sont mises d'accord, quel est le protocole pour l'utilisation de cette extension (section 3) ? Le test des battements de cœur fonctionne au-dessus du Record Protocol de TLS, auquel il ajoute deux messages :
enum { heartbeat_request(1), heartbeat_response(2), (255) } HeartbeatMessageType;
Un message HeartbeatRequest
peut arriver à tout
moment pendant une session, le pair doit alors répondre par un
HeartbeatResponse
. D'autres types que Requête et
Réponse seront peut-être un jour créés, et enregistrés dans le nouveau registre IANA.
Lorsque la session protégée par TLS fonctionne au dessus d'un
protocole fiable, comme TCP, c'est tout. La
couche de transport se chargera des éventuelles
retransmissions. Si
la session TLS utilise un protocole non-fiable comme UDP,
l'émetteur du HeartbeatRequest
doit se préparer,
en l'absence de réponse, à réémettre le message (RFC 6347, section 4.2.4).
Et le contenu des messages (section 4) ? Une charge utile est autorisée :
struct { HeartbeatMessageType type; uint16 payload_length; opaque payload[HeartbeatMessage.payload_length]; opaque padding[padding_length]; } HeartbeatMessage;
Le contenu du champ payload
est quelconque. La
réponse doit inclure le même contenu (elle doit être un écho de la
requête).
La section 5 du RFC décrit ensuite deux cas d'utilisation pratique
de cette extension. Le premier est celui de la découverte de la
MTU du chemin, pour laquelle DTLS n'avait pas
de mécanisme (RFC 6347, section 4.1.1.1). La
méthode, inspirée du RFC 4821, est simplement d'utiliser des
HeartbeatRequest
de plus en plus gros, jusqu'à ce
qu'on n'obtienne plus de réponse, auquel cas on sait qu'on a trouvé la
MTU maximale.
L'autre usage de cette extension est le test de bonne santé du
pair, comme expliqué au début de cet article. Le RFC recommande de ne
pas en abuser, et de n'émettre les
HeartbeatRequest
qu'à des intervalles de
plusieurs fois le RTT.
Il existe déjà au moins une mise en œuvre de ce mécanisme de
battement de cœur. OpenSSL l'aura à
partir de la 1.0.1 (le code est déjà dans les versions de
développement, l'extension - option heartbeats
- est apparemment compilée par défaut). Pour GnuTLS, ce n'est encore
qu'un projet. Comme souvent en informatique, quand on ajoute du code,
on ajoute des bogues. C'est ainsi que la mise en œuvre de cette
extension dans OpenSSL a été à l'origine de la faille CVE-2014-0160,
dite « HeartBleed ».
Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Lebovitz, M. Bhatia (Alcatel-Lucent)
Pour information
Réalisé dans le cadre du groupe de travail IETF karp
Première rédaction de cet article le 2 février 2012
Dans l'ensemble du travail engagé pour améliorer la sécurité du routage sur l'Internet, un sous-problème important est celui de la gestion des clés. En cryptographie, c'est souvent par une faiblesse dans cette gestion que les systèmes de sécurité sont compromis. Le groupe de travail KARP de l'IETF est occupé à améliorer les protocoles de gestion de clés et son premier RFC, ce RFC 6518, expose les propriétés attendues des futurs protocoles de gestion des clés des routeurs.
Prenons par exemple N routeurs OSPF qui veulent s'authentifier les uns les autres. La technique du RFC 2328 est d'avoir un secret partagé par tous les routeurs du même réseau local. Les messages OSPF sont concaténés avec ce secret, le résultat de la concaténation est ensuite condensé cryptographiquement, ce qui permettra au destinataire de s'assurer que l'émetteur connaissait bien le secret. Ce secret partagé est une clé cryptographique. Qui va la générer ? Comment la distribuer de façon sûre ? Comment la changer facilement et rapidement si le secret est compromis (ou, tout simplement, si un employé quitte l'entreprise) ? Ce genre de questions est la problématique de gestion de clés. Dans le cas d'OSPF, actuellement, la quasi-totalité des opérateurs de routeurs fait cela à la main (on se logue sur chaque routeur et on change le secret...) ou, à la rigueur, via un protocole général de configuration des routeurs. Peut-on faire mieux ? C'est en tout cas ce que va essayer de faire le groupe KARP (les deux RFC suivants de KARP ont été le RFC 6862, sur l'analyse des menaces, et le RFC 6863, sur l'analyse spécifique du protocole OSPF).
C'est que les mécanismes actuels ne sont pas satisfaisants. Comme le rappelle la section 1 du RFC, lors d'un colloque en 2006 (cf. RFC 4948), les participants avaient dénoncé la vulnérabilité des routeurs aux tentatives de prise de contrôle et appelé à durcir leur sécurité. Quatre axes d'amélioration avaient été identifiés, améliorer la gestion des routeurs (groupe de travail OPSEC), améliorer les IRR, valider les annonces de route (groupe de travail SIDR), et enfin sécuriser les communications entre routeurs (groupe de travail KARP), ce qui fait l'objet de ce RFC. Les informations de routage sont échangées via un protocole et la protection de ce protocole se fait par la cryptographie. Qui dit cryptographie dit clés. Lorsqu'un routeur cherche une clé pour protéger un message, où demande-t-il ? Pour l'instant, il n'y a pas de mécanisme standard et KARP va essayer d'en développer un. Le plus courant aujourd'hui est la gestion manuelle des clés (l'opérateur configure les clés, les change à la main - lorsqu'il y pense, les communique via PGP, SCP voire sans aucune sécurité) mais le RFC estime que le futur est dans des mécanismes automatisés de gestion de clés, les KMP (pour Key Management Protocol). Un KMP, par exemple, change automatiquement les clés au bout d'une période pré-définie.
Compte-tenu de la variété des protocoles de routage, et du transport qu'ils utilisent, ce sera un mécanisme abstrait, pas un protocole précis (ce RFC 6518 n'a donc pas d'implémentation, il définit juste un cadre). Plus précisement, KARP va concevoir les interfaces abstraites entre le système de gestion de clés et le protocole de routage, puis, pour chaque protocole de routage, la correspondance entre cette interface abstraite et le protocole réel. Un projet ambitieux.
Maintenant, au boulot. Qu'est-ce qui est déjà fait dans ce RFC ? La
section 2 classe les protocoles de routage selon leurs
propriétés. L'idée est que les protocoles de routage qui partagent les
mêmes propriétés pourront, avec un peu de chance, utiliser les mêmes
mécanismes de gestion de clés. Première propriété, le type de
message. Certains protocoles sont de type un-vers-un : les messages
d'un routeur sont envoyés à un autre routeur. Les
UPDATE
BGP (RFC 4271) fonctionnent
ainsi. Mais c'est aussi le cas de LDP (RFC 5036), de BFD (RFC 5880) et même d'OSPF (RFC 2328) dans certaines conditions (liens point
-à-point). D'autres protocoles fonctionnent en un-vers-plusieurs. Un
routeur diffuse sur le réseau local l'information de routage. C'est le
mode de fonctionnement le plus courant d'OSPF et c'est aussi celui de
RIP (RFC 2453). Enfin,
il y a les protocoles utilisés pour le multicast.
Deuxième propriété pour classer les protocoles de routage, proche de la précédente mais pas identique, le fait que la clé soit par groupe ou par pair. Dans BGP ou LDP, les clés sont individuelles, on a une clé différente par pair. Dans OSPF, la clé est la même pour tous les pairs d'un groupe.
La section 3 liste ensuite les points auxquels il faut penser lorsqu'on envisage un protocole de gestion de clés, un KMP. Le RFC 4107 fournit les bases générales et notre RFC l'adapte aux protocoles de routage. Entre autres, il faudra penser aux paramètres à passer avec le système de gestion de clés, comme la durée de vie pour les clés, l'identificateur de l'association de sécurité (SPI dans IPsec, KeyID dans TCP-AO, etc), l'algorithme de chiffrement et plusieurs autres.
Deux points sont soulignés par le RFC, les questions particulières des clés asymétriques (section 3.1) et le cycle de vie des clés (section 3.2). Les clés asymétriques sont souvent une bonne solution aux problèmes de sécurité : déjà utilisées par les routeurs (lorsqu'ils sont administrés via SSH), générées sur le routeur, elles peuvent n'avoir jamais besoin de le quitter (le RFC ne le dit pas clairement mais on peut même imaginer un petit HSM dans le routeur). Générées aléatoirement, elles ne peuvent pas être devinées comme le sont tant de mots de passe choisis par des humains. Il faut juste faire attention à leur taille, pour limiter les risques des attaques par force brute (RFC 3766). L'algorithme classique pour ces clés est RSA mais les algorithmes à base de courbes elliptiques commencent à se répandre, et permettent d'utiliser des clés plus courtes.
Quant au cycle de vie des clés, notre RFC insiste surtout sur la nécessité d'avoir des remplacements (rollover) de clés qui soient discrets : un remplacement de clés ne devrait pas casser les sessions de routage existantes, car cela imposerait des recalculs lourds des tables de routage, se propageant dans tout le réseau, et entraînant parfois des perturbations dans la connectivité. (Le RFC ne le cite pas mais la traditionnelle authentification MD5 de BGP - RFC 2385 - n'a pas cette propriété. Changer la clé impose de relancer les sessions BGP. C'est sans doute une des raisons pour lesquelles ces clés ne sont jamais changées, même quand tout le monde les connait.)
Pourquoi, d'ailleurs, faut-il changer les clés de temps en temps ? Il peut y avoir des raisons cryptographiques (progrès de la cryptanalyse, mais le RFC note qu'en pratique, ce sont les cas les plus rares, des problèmes moins prestigieux scientifiquement sont bien plus communs), des raisons liées au personnel (départ d'un ingénieur qui connaissait les clés), des raisons plus urgentes (compromission d'une machine où étaient stockées des clés). Même s'il n'y a aucune raison immédiate de changer, un remplacement des clés de temps en temps peut être nécessaire pour s'assurer qu'un attaquant qui a obtenu une clé et l'utilise discrètement (de manière purement passive), ne puisse pas profiter de son butin éternellement.
Lorsque les procédures de changement de clés sont manuelles, les changements peuvent être en eux-mêmes une source de vulnérabilité (l'erreur est humaine...).
Après ces préliminaires, la section 4 dessine le travail futur. Il y a deux chantiers génériques (indépendants du protocole de routage) importants, le premier étant un pré-requis du second :
Pour que les mécanismes nouveaux aient des chances de succès, ils doivent pouvoir être déployés sans ajouter de complexité par rapport à ce que font déjà les opérateurs (qui connaissent SSH, TCP-MD5, HTTPS et les certificats, etc). Le but n'est pas de faire un système qui empêche l'opérateur de faire une erreur (comme d'utiliser « foobar » comme mot de passe pour tous les systèmes) mais de faire un système qui soit utilisé dans le monde réel, et pour cela, la simplicité et la déployabilité sont des critères essentiels (mais très souvent oubliés par les experts en sécurité, qui se soucient davantage de faire des systèmes parfaits que des systèmes déployables, cf. section 6).
Avec une gestion manuelle des clés, on ne peut gérer de manière raisonnablement sûre que des petits réseaux. La deuxième étape sera donc de déployer le mécanisme de gestion automatique.
Le travail d'amélioration de chaque protocole de routage est décrit en section 4.2 sous forme d'une liste de tâches :
On l'a vu en section 2, KARP classe les protocoles de routage en catégories selon leurs propriétés. La section 5 examine les points qui sont spécifiques à chaque catégorie. BGP, LDP et quelques autres sont dans la catégorie « messages un-vers-un et clés par pair ». BGP fonctionne toujours sur TCP, LDP parfois sur TCP et parfois sur UDP. Pour le cas de TCP, une bonne partie du travail a déjà été faite dans le groupe TCPM, avec la technique d'authentification AO (RFC 5925) qui a les propriétés voulues pour la première phase du travail de KARP (agilité des algorithmes et changement de clé facile). Il ne reste donc que le cas de LDP sur UDP.
Pour la catégorie « un-vers-plusieurs avec clés par groupe », qui comprend OSPF, IS-IS et RIP, rien de générique n'est fait. Le problème est ici bien plus difficile, d'autant plus que ces protocoles n'utilisent pas en général de protocole de transport standard, et ne peuvent donc pas réutiliser un mécanisme fourni par la couche 4 (comme peut le faire BGP avec AO). Ceci dit, le RFC 7166 fournit une méthode d'authentification pour OSPF qui, grâce à une indirection, fournit l'agilité de l'algorithme de chiffrement, qu'on peut changer en vol.
BFD est un cas à part et qui nécessitera sa propre équipe. Par exemple, il est beaucoup plus sensible aux délais que les autres. Pour lui, une milliseconde est très longue.
On l'a vu, ce RFC répète régulièrement qu'il est essentiel de prévoir un déploiement incrémental des nouveaux mécanismes de sécurité. Pas question d'ignorer l'existant. La section 6 insiste sur ce point. Contrairement à une attitude fréquente chez les experts en sécurité, qui est de chercher une solution parfaite, KARP va essayer de trouver des solutions qui puissent être déployées par étapes, sans casser le routage actuel, même si ces solutions ne sont pas les meilleures, question sécurité. Par exemple, les routeurs configurés avec les nouveaux mécanismes doivent pouvoir interagir sans ennuis avec les vieux routeurs non sécurisés.
Un des problèmes de sécurité les plus difficiles dans l'Internet est celui des attaques par déni de service (section 7). Ces attaques touchent aussi les routeurs et les protocoles de routage. Il ne faut donc pas que les nouvelles techniques conçues dans le cadre du groupe KARP aggravent le problème. Par exemple, les calculs cryptographiques peuvent être coûteux, surtout pour les ressources matérielles souvent limitées des routeurs, et les protocoles ne doivent donc pas permettre à un attaquant de faire faire au routeur une énorme quantité de ces calculs. Pour éviter cela, il faut permettre au routeur de faire des vérifications non-cryptographiques, donc bien plus légères, avant de se lancer dans les calculs compliqués. Par exemple, le RFC 5082 utilise le TTL du paquet entrant (quelque chose de trivial à vérifier) pour empêcher certaines attaques. Il est important, dans le cadre de KARP, de développer et de documenter de telles alternatives. D'autre part, le protocole doit être conçu de manière à ce que ce soit l'initiateur de la connexion (un attaquant potentiel) qui ait le plus de travail cryptographique à faire, et qui doive maintenir un état pendant ce temps.
La section 9 du RFC, la traditionnelle section sur la sécurité, détaille quelques points précis qui n'avaient pas trouvé leur place dans le reste du RFC. Par exemple, il est important de considérer aussi si le protocole de routage qu'on veut protéger est un IGP ou un EGP (certains protocoles peuvent être utilisés pour les deux, comme BGP avec son mode iBGP). Les deux sont sans doute aussi importants mais les menaces et les solutions ne seront pas forcément les mêmes. Un routeur purement interne et qui n'a aucun accès à l'Internet est ainsi sans doute moins menacé qu'un routeur BGP posé sur un point d'échange avec des dizaines d'autres routeurs inconnus.
Autre question transversale, celle des clés partagées ou uniques. Faut-il utiliser la même clé à plusieurs endroits ? Le débat est simple : c'est la sécurité (clés uniques !) contre la commodité (clés partagées). Actuellement, dans la grande majorité des environnements, les opérateurs ont choisi la commodité, réutilisant la même clé à plusieurs endroits. Les clés des routeurs sont stables dans l'espace (utilisées dans plusieurs routeurs) et dans le temps (on les change rarement, voire jamais et certains routeurs gardent la même clé toute leur vie). L'un des buts de KARP est de casser ce dilemne « sécurité ou commodité » en fournissant des mécanismes de gestion de clés qui soient sûrs (clés uniques) tout en étant faciles à déployer.
Enfin, la section 9.4 discute du dernier problème transversal, la distribution des clés. La méthode la plus courante aujourd'hui est un mécanisme « hors-bande », par exemple l'administrateur qui se connecte en SSH au routeur et entre manuellement les clés dans la configuration. Ça ne passe pas tellement à l'échelle (il faudrait automatiser les connexions SSH, par exemple avec Capistrano, pour faire l'opération sur N routeurs). Et changer toutes les clés en cas, par exemple de départ d'un administrateur (ou, pire, en cas de compromission de la clé) est trop lent. L'approche d'un KMP, protocole de gestion de clés, est donc préférée par KARP, comme nous l'avons déjà vu. Mais le RFC ne cache pas que le KMP a ses propres problèmes : lenteur au début (davantage de calculs cryptographiques) et surtout risques liés au manque de maturité des programmes, les KMP étant encore chose récente.
Une des possibilités envisagées est de réutiliser un KMP existant comme IKE, adapté au monde du routage, mais tournant en dehors du protocole de routage. L'autre possibilité est un nouveau KMP, embarqué dans le protocole de routage. Mais la décision n'est pas encore prise.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Bhatia (Alcatel-Lucent), V. Manral (Hewlett Packard), A. Lindem (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ospf
Première rédaction de cet article le 14 février 2012
La version 2 du protocole de routage OSPF avait un mécanisme d'authentification (annexe D du RFC 2328). Lors de la conception de la version 3 (qui permettait notamment d'ajouter IPv6), ce mécanisme avait été abandonné, l'idée étant que l'IETF avait déjà un mécanisme d'authentification plus général, IPsec, et qu'il « suffisait » de l'utiliser. Selon cette analyse, il n'y avait plus besoin de doter chaque protocole de son propre mécanisme d'authentification. C'était très bien sur le papier. Mais, en pratique, le déploiement d'IPsec est très limité, à la fois en raison de sa complexité et du caractère imparfait de ses implémentations. Résultat, les utilisateurs d'OPSFv3 n'ont, la plupart du temps, pas déployé de mécanisme de sécurité du tout. En voulant faire trop propre, on a donc diminué la sécurité du routage. Ce RFC (depuis remplacé par le RFC 7166) corrige le tir en dotant enfin OSPFv3 d'un mécanisme d'authentification léger et réaliste.
OSPFv3 est normalisé dans le RFC 5340, dont le titre (« OSPF pour IPv6 ») est trompeur car, depuis le RFC 5838, OSPFv3 peut gérer plusieurs familles d'adresses et peut donc, en théorie, remplacer complètement OSPFv2. En pratique, toutefois, ce n'est pas encore le cas, notamment pour le problème de sécurité qui fait l'objet de ce RFC : contrairement aux autres protocoles de routage internes, OSPFv3 ne disposait d'aucun mécanisme d'authentification. N'importe quel méchant sur le réseau local pouvait se proclamer routeur et envoyer de fausses informations de routage. L'argument répété était « pas besoin de mécanisme spécifique à OSPFv3, utilisez les mécanismes IPsec, comme expliqué dans le RFC 4552 ». Mais on constate que cette possibilité a été très peu utilisée. Le RFC se contente de noter que c'est parce que IPsec est mal adapté à certains environnements comme les MANET mais il ne parle pas des autres environnements, où IPsec est simplement rejeté en raison de la difficulté à trouver une implémentation qui marche, et qu'un administrateur système normal arrive à configurer.
IPsec a également des faiblesses plus fondamentales pour des protocoles de routage comme OSPF. Ainsi, les protocoles d'échange de clés comme IKE ne sont pas utilisables tant que le routage ne fonctionne pas. Pour résoudre le problème d'œuf et de poule, et parce que les communications OSPF sont de type un-vers-plusieurs (et pas un-vers-un comme le suppose IKE), le RFC 4552 prône des clés gérées manuellement, ce qui n'est pas toujours pratique.
Enfin, l'absence de protection contre le rejeu affaiblit la sécurité d'IPsec dans ce contexte, comme le note le RFC 6039.
La solution proposée figure en section 2. L'idée est d'ajouter à la fin du packet OSPF un champ qui contienne un condensat cryptographique du paquet et d'une clé secrète, comme pour OSPFv2 (RFC 5709) (D'autres types d'authentification pourront être utilisés dans le futur, un registre IANA des types a été créé.) Les options binaires du paquet, au début de celui-ci (RFC 5340, section A.2), ont un nouveau bit, en position 13, AT (pour Authentication Trailer, désormais dans le registre IANA), qui indique la présence ou l'absence du champ final d'authentification (tous les paquets n'ont pas ce champ Options, donc le routeur devra se souvenir des valeurs de ce champ pour chaque voisin).
Pour chaque couple de routeurs ainsi protégés, il y aura un certain nombre de paramètres, qui forment ce qu'on nomme un accord de sécurité (security association, section 3) :
Une fois qu'on a toutes ces informations, qu'est-ce qu'on met dans le paquet OSPF envoyé sur le câble ? La section 4 décrit le mécanisme. Le champ final d'authentification (Authentication Trailer) est composé notamment de l'identifiant d'un accord de sécurité (SA ID, décrit au paragraphe précédent, et qui permet au récepteur de trouver dans sa mémoire les paramètres cryptographiques liés à une conversation particulière), d'un numéro de séquence (qui sert de protection contre le rejeu ; il est augmenté à chaque paquet émis ; il comprend 64 bits, après une très longue discussion dans le groupe de travail, certains auraient préféré 32 bits) et du condensat cryptographique du paquet concaténé avec la clé (la section 4.5 décrit l'algorithme en détail et notamment quels champs du paquet sont inclus dans les données condensées).
Le routeur qui reçoit un paquet utilisant l'authentification (il le sait grâce au bit AT qui était notamment présent dans les paquets OSPF Hello) va accéder au champ d'authentification (le champ Longueur du paquet OSPF lui permet de savoir où commence le champ d'authentification, éventuellement en tenant compte du bloc Link-Local Signaling du RFC 5613, un routeur doit donc gérer au moins en partie ce dernier RFC s'il veut authentifier). Le récepteur refait alors le calcul cryptographique et vérifie si le champ final d'authentification est correct. Le calcul est très proche de celui du RFC 5709 à part l'inclusion de l'adresse IPv6 source.
Supposons que nous soyons administrateur réseaux et que nos routeurs gèrent tous ce nouveau RFC. Comment déployer l'authentification sans tout casser ? La section 5 recommande de migrer tous les routeurs connectés au même lien simultanément. Autrement, les routeurs qui n'utilisent pas l'authentification ne pourront pas former d'adjacences OSPF avec ceux qui l'utilisent. Le RFC prévoit un mode de transition, où le routeur envoie le champ final d'authentification mais ne le vérifie pas en entrée mais l'implémentation de ce mode n'est pas obligatoire.
La section 6 contient l'analyse de sécurité de cette nouvelle extension d'OSPF. Elle rappelle qu'elle ne fournit pas de confidentialité (les informations de routage seront donc accessibles à tout espion). Son seul but est de permettre l'authentification des routeurs, résolvant les problèmes notés par le RFC 6039. À noter que cette extension ne permet pas d'authentifier un routeur particulier mais simplement de s'assurer que l'émetteur est autorisé à participer au routage sur ce lien (tous les routeurs ont la même clé). La clé, rappelle cette section 6, devrait être choisie aléatoirement, pour ne pas être trop facile à deviner (cf. RFC 4552).
À ma connaissance, il n'existe pas encore d'implémentation de cette option dans le logiciel d'un routeur.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Davis (Google), A. Phillips (Lab126), Y. Umaoka (IBM), C. Falk (Infinite Automata)
Pour information
Première rédaction de cet article le 23 février 2012
Le RFC 5646, qui normalise les étiquettes de langue, prévoit un mécanisme d'extension pour ajouter à ces étiquettes des informations maintenues dans des registres extérieurs. Ces extensions sont identifiées par une lettre unique et une nouvelle extension est ajoutée par notre RFC 6497, « T » (pour transformation), qui permet d'indiquer les transformations qu'a subies un texte (par exemple une traduction), en se référant au registre CLDR.
Le RFC 5646 est également connu sous
l'identificateur « BCP 47 » (BCP pour Best Common
Practice), ce qui explique le titre de notre RFC 6497. Les transformations qu'on pourra noter dans une
étiquette de langue sont notamment la
translittération, la
transcription et la
traduction. Sans cette extension « T », on ne
peut étiqueter que l'état actuel du document. Par exemple,
pes-Latn
désignerait un texte en
persan dans l'alphabet
latin (ce qui est inhabituel) ; l'extension « T » permettra
d'écrire pes-Latn-t-pes-arab
, indiquant que le
texte persan a été translittéré ou transcrit depuis l'alphabet
arabe. Autre exemple, donné dans le
RFC, une carte
d'Italie pour des japonais où les noms des villes ont été
translittérés en Katakana. N'indiquer que
ja
(langue japonaise) pour
ce texte serait insuffisant. Cette information sur la source, donnée
par l'extension « T » est souvent
importante, pour aider à comprendre certaines particularités du
texte (comme des fautes lors de la traduction). Le mécanisme des variantes du RFC 5646 ne
suffisait pas pour cela, d'où la nouvelle extension. C'est la deuxième
enregistrée, après la « U » du RFC 6067. Le
mécanisme d'extension est normalisé dans le RFC 5646,
sections 2.2.6 et 3.7. Les extensions sont enregistrées dans
le registre IANA.
Parfois, il existe des méthodes standard de translittération ou de transcription. C'est par exemple le cas de celles spécifiées par l'UNGEGN. La nouvelle extension « T » permet également d'indiquer comment et par quelle méthode standard un texte a été translittéré ou transcrit.
Maintenant, les détails techniques : l'extension est notée par un
t
suivi d'une étiquette de langue légale (section
2, notamment 2.2). Ainsi,
es-t-pid
signifie que le texte est en
espagnol, traduit du piaroa. Mais, comme le texte après
t
peut être une étiquette de langue complète, on
peut noter bien plus de détails, comme l'écriture utilisée (comme dans
l'exemple du perse plus haut). Comme l'étiquette de langue doit
comporter obligatoirement une langue en première position, si celle-ci
n'est pas connue ou tout simplement pas pertinente (rappelez-vous que
la différence principale entre translittération et transcription est
que la première ne dépend pas de la langue, c'est
une opération purement mécanique sur les caractères), on la note par
und
, ce qui veut dire « inconnue ». Ainsi,
und-Latn-t-und-cyrl
signifie que le texte a été
translittéré de l'alphabet cyrillique vers le
latin (par exemple par l'algorithme ISO 9),
sans tenir compte des langues en jeu.
Enfin, il est possible d'indiquer le mécanisme de transformation,
en utilisant le séparateur m0
, puis l'organisme
qui spécifie ces mécanismes, puis un identificateur d'un mécanisme
particulier. Ainsi,
und-Cyrl-t-und-latn-m0-ungegn-2007
est du texte
en alphabet latin, transformé en cyrillique, suivant la spécification
UNGEGN de 2007. D'autres séparateurs que m0
seront peut-être créés dans le futur.
Quels termes peut-on mettre après m0
? Ce qui
vous passe par la tête ? Non. Il faut suivre la section 3 du document
Unicode UTR #35. C'est
d'ailleurs le consortium Unicode qui est
l'autorité gérant l'extension « T » (section 2.4). Cela a suscité de
vigoureuses discussions (pourquoi pas
l'IETF ?). La conséquence en a été la
définition d'un mécanisme plus ouvert pour soumettre des propositions
de changement. Si on veut
enregistrer de nouvelles possibilités (section 2.6), cela se fait en
créant un ticket en http://cldr.unicode.org/index/bug-reports/
.
La liste complète des possibilités de mécanismes de transformation
figure dans un fichier structuré (section 2.9), librement accessible
en http://cldr.unicode.org/index/downloads
. Ce point a suscité
beaucoup de débats sur la liste de diffusion de l'ancien groupe de
travail LTRU. En effet, le fichier
officiel est un gros .zip
rempli de tas de choses qui n'ont rien à
voir. Il faut donc tout télécharger puis trier (les transformations
sont dans le répertoire common/transforms
).
Date de publication du RFC : Février 2012
Auteur(s) du RFC : R. Bush (Internet Initiative Japan)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
Les certificats de la RPKI, qui permettent de sécuriser le routage sur l'Internet en prouvant un droit à utiliser telle ou telle adresse IP, ne portent pas en clair de nom de titulaire. Cela peut être un problème dans certains cas opérationnels. Par exemple, une route reçue en BGP est refusée par le routeur, l'administrateur réseaux enquête, découvre un certificat qui a expiré, et voudrait prévenir le responsable qu'il a fait une boulette. Mais comment trouver le responsable ? Ou, selon la phrase culte du film Ghostbusters, « Who you gonna call? ». Ce RFC résout le problème en permettant de mettre une vCard dans le certificat, indiquant qui contacter en cas de problème.
Il n'y a guère de doute que ce genre de problèmes sera fréquent. La
RPKI permet de distribuer des
certificats numériques disant « le titulaire de
la clé privée de ce certificat est responsable du préfixe IP
2001:db8:137::/48
». Ce certificat est ensuite
utilisé pour signer les ROA (Route
Origin Authorization) qui indiquent quel
AS peut annoncer ce préfixe. Si on se fie à
l'expérience du déploiement d'autres technologies à base de
cryptographie dans
l'Internet (par exemple
DNSSEC), il y aura des problèmes : préfixes
trop génériques, interdisant des annonces plus spécifiques,
certificats expirés, oubli de créer un nouvel ROA lorsqu'on contracte
avec un nouveau transitaire BGP, etc. Ceux et
celles qui détecteront les problèmes auront donc besoin de contacter
les responsables, dans l'espoir qu'ils agissent.
Or, les métadonnées dans les certificats de la RPKI ne contiennent pas d'identificateurs utilisables par les humains (cf. RFC 6484). D'où l'idée de ce RFC, de mettre une vCard (plus exactement un profil restrictif des vCards du RFC 6350) dans un objet RPKI signé (la description de la syntaxe générique de ces objets est dans le RFC 6488).
Arrivé à ce stade, vous vous demandez peut-être « pourquoi un nouveau format au lieu d'utiliser les données des RIR, telles que publiées via whois ? ». La réponse est que l'enregistrement Ghostbusters identifie le responsable du certificat, qui n'est pas forcément le même que celui de la ressource (adresse IP ou numéro d'AS). Et puis, en pratique, les bases des RIR ne sont pas toujours correctes. Comme le chemin de mise à jour de l'enregistrement Ghostbuster est différent, peut-être sera-t-il parfois correct lorsque la base du RIR ne le sera pas ?
De toute façon, l'enregistrement Ghostbuster est facultatif. Un certificat peut en avoir zéro, un ou davantage. La section 3 du RFC fournit un exemple :
BEGIN:VCARD VERSION:4.0 FN:Human's Name ORG:Organizational Entity ADR;TYPE=WORK:;;42 Twisty Passage;Deep Cavern;WA;98666;U.S.A. TEL;TYPE=VOICE,TEXT,WORK;VALUE=uri:tel:+1-666-555-1212 TEL;TYPE=FAX,WORK;VALUE=uri:tel:+1-666-555-1213 EMAIL:human@example.com END:VCARD
En fait, cette vCard est embarquée dans un objet de la RPKI, qu'on peut lire avec des outils comme openssl. Voici un exemple sur un objet réel :
% openssl asn1parse -inform DER \ -in b-hiK-PPLhH4jThJ700WoJ3z0Q8.gbr ... 60:d=5 hl=3 l= 139 prim: OCTET STRING :BEGIN:VCARD VERSION:3.0 EMAIL:michael.elkins@cobham.com FN:Michael Elkins N:Elkins;Michael;;; ORG:Cobham Analytic Solutions END:VCARD ...
Le sous-ensemble de vCard qui est accepté dans les chasseurs de
fantômes est décrit en section 4. La définition est très restrictive :
ne sont acceptées que les propriétés VERSION
(qui
doit valoir au moins 4, vous noterez que les enregistrements réels
cités plus haut
sont donc illégaux), FN
,
ORG
, ADR
,
TEL
et EMAIL
(un
enregistrement qui inclus N
, comme ci-dessus, est
donc illégal).
Ensuite (section 5), la vCard est embarquée dans un objet CMS signé (RFC 6488 ; la validation de ces enregistrements se fait de la même façon que pour les autres objets de la RPKI). Le type (OID) est 1.2.840.113549.1.9.16.1.35, ce qu'on voit dans la sortie d'openssl :
% openssl asn1parse -inform DER \ -in owCgRbSAAkKS9W-MFbSAd7Bru2c.gbr ... 44:d=4 hl=2 l= 11 prim: OBJECT :1.2.840.113549.1.9.16.1.35 57:d=4 hl=3 l= 195 cons: cont [ 0 ] 60:d=5 hl=3 l= 192 prim: OCTET STRING :BEGIN:VCARD VERSION:3.0 ADR:;;5147 Crystal Springs;Bainbridge Island;Washington;98110;US EMAIL:randy@psg.com FN:Randy Bush N:Bush;Randy;;; ORG:RGnet\, LLC TEL:+1 206 356 8341 END:VCARD
L'objet CMS est enfin mis dans un fichier d'extension
.gbr
. Fin 2011, on n'en trouvait que très peu
dans les dépôts de la RPKI.
Attention, toutes ces données sont publiques. Comme le rappelle la section 8, sur la sécurité, publier ses informations dans un enregistrement Ghostbuster et vous risquez d'être harcelé par des commerciaux au téléphone ou bien spammé.
D'autre part, l'entité qui signe l'objet ne garantit nullement que les informations sont correctes. Elle garantit juste que ces informations ont bien été mises par le titulaire de la ressource (préfixe IP ou AS) correspondante. Celui-ci a pu mettre un numéro de téléphone ou une adresse de courrier bidon...
Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Huston, R. Loomans, B. Ellacott (APNIC), R. Austein (ISC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
La RPKI est l'infrastructure de création et de distribution de certificats pour les titulaires de ressources Internet (essentiellement les adresses IP), afin de sécuriser le routage sur l'Internet. Ce RFC normalise un protocole de communication pour réclamer ces certificats (avitaillement, ou provisioning). Il sera typiquement utilisé entre les RIR et les LIR.
Les termes exacts utilisés par le RFC sont Émetteur (Issuer), en général un RIR, qui va donc être une AC, et Destinataire (Subject), qui sera un FAI ou autre opérateur réseau. Le RIR distribue des INR (Internet Number Resource, ce sont les adresses IP et les numéros d'AS, collectivement nommés Ressources) et les certificats prouvant le droit du Destinataire à utiliser ces INR. Notez qu'un Destinataire peut être Émetteur pour des ressources qu'il redistribuera, par exemple à des opérateurs plus petits.
Le trafic attendu rend nécessaire d'automatiser l'avitaillement des
certificats. Cela se fait avec un simple protocole (section 3), qui
est une extension de HTTP. Le client HTTP fait
une requête POST
(RFC 7231,
section 4.3.4), de type MIME
application/rpki-updown
. Le protocole est
strictement requête/réponse (synchrone). Aussi bien le corps de
la requête, que celui de la réponse du serveur, sont au format
CMS (RFC 5652), encodé en DER. Le
profil CMS est défini en section 3.1. CMS permet de transporter les
signatures des différents objets (et les métadonnées associées comme
la date de signature) mais le gros du contenu est un
élément XML stocké dans le CMS sous le nom de
RPKIXMLProtocolObject
.
Cet élément XML est forcément
<message>
. Il forme l'essentiel de la requête ou de la
réponse. Sa grammaire est décrite en Relax NG en
section 3.7.
Quelles sont les opérations possibles ? Elles sont indiquées par
l'attribut type
de la requête. Par exemple, le client peut demander une
liste des ressources que lui a alloué le serveur, avec
type="list"
. La réponse arrivera sous forme d'une
séquence d'éléments <class>
. Ou bien il peut demander un
certificat pour une nouvelle ressources avec
type="issue"
.
Naturellement, vu que tout le but de l'exercice est d'augmenter la sécurité du routage dans l'Internet, les implémenteurs et les utilisateurs de ce RFC devraient bien faire attention à la section 4, qui couvre la sécurité de ce protocole d'avitaillement. Le RFC précise que l'Émetteur et le Destinataire doivent s'authentifier (par les siognatures contenues dans les messages CMS), en utilisant des lettres de créance qu'ils ont échangé précédemment (par un moyen non spécifié). On note que TLS n'est pas utilisé par ce protocole (ce fut une chaude discussion au sein du groupe de travail), CMS fournissant tous les services de sécurité nécessaires.
Je ne connais pas encore de mise en œuvre publique de ce protocole mais plusieurs RIR ont annoncé qu'ils auraient des serveurs prêts pour la sortie du RFC.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : T. Manderson, L. Vegoda (ICANN), S. Kent (BBN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
La RPKI est le système de distribution de
certificats et d'objets signés avec les clés de
ces certificats, qui permet de poser les
bases d'une sécurisation du routage dans l'Internet, en
permettant aux titulaires des ressources (préfixes d'adresses IP,
notamment), d'autoriser tel ou tel opérateur et uniquement ceux-ci, à
utiliser ces ressources. Certains préfixes ne sont pas alloués à un
utilisateur, ils dépendent directement de
l'IANA et ce RFC 6491 est donc
consacré à lister les tâches de l'IANA pour ces préfixes. Par exemple,
l'IANA devra émettre et signer un objet disant « Personne ne peut
annoncer de route vers 198.51.100.0/24
(ce
préfixe étant réservé, par le RFC 5737, à la
documentation) ».
Rappelons que les responsabilités de l'IANA vis-à-vis de l'IETF sont fixées par le RFC 2860. Pour le cas particulier de la RPKI (RFC 6480), l'IANA va devoir verrouiller l'usage des préfixes IP qu'elle gère (section 1). Ces préfixes sont utilisées pour la documentation ou réservés pour d'autres usages. Comme personne ne doit les router, l'IANA va émettre des ROA (RFC 6482) négatifs, c'est-à-dire prouvant que ces adresses ne sont pas routables. Un routeur BGP validant (RFC 6483) va alors pouvoir les rejeter, si jamais ils apparaissent dans des annonces de routes. Ces ROA négatifs sont officiellement appelés « AS0 ROA », le numéro d'AS zéro étant invalide (il ne doit jamais être dans un chemin d'AS). La section 4 du RFC 6483 détaille ce concept de désaveu de route.
Ce désaveu s'applique aux préfixes qui sont prévus pour ne jamais apparaître dans la table de routage globale (section 5), ainsi qu'à ceux qui ne sont pas actuellement alloués et donc toujours à l'IANA (aujourd'hui, cela ne concerne plus qu'IPv6, cf. section 6). Les adresses « spéciales » (section 7, voir aussi le RFC 6890) se divisent, elles, en deux : celles prévues pour être routées globalement, pour lesquelles l'IANA ne doit rien faire, et celles non prévues pour être routées, et pour lesquelles il y aura donc un AS0 ROA.
La liste des préfixes figure en annexe A du RFC. On y trouve les
suspects habituels, le préfixe 169.254.0.0/16
ou fe80::/10
des
adresses locales au lien, les préfixes privés des RFC 1918 et RFC 4193, les préfixes réservés à la documentation... Tous
ceux-ci ne seront jamais routés sur l'Internet.
Avant de commencer à émettre ces ROA, l'IANA devra évidemment établir une CA (section 10). Cette CA devra utiliser les extensions à X.509 du RFC 3779. Elle devra aussi publier la liste de ses objets (j'avoue n'avoir pas trouvé où c'était documenté sur le site de l'IANA...).
Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Lepinski, A. Chi, S. Kent (BBN)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
Le système de sécurisation de BGP et du routage sur l'Internet, qui tourne autour de la RPKI, utilise des objets numériques signés cryptographiquement pour représenter les autorisations d'annoncer telle ou telle route. Ces objets sont définis avec la syntaxe CMS et le profil que normalise ce RFC.
Le contenu typique de ces objets est une autorisation du genre «
L'AS 64641
est autorisé à annoncer le préfixe 192.0.2.0/24
». Ils sont ensuite signés avec les clés contenues dans les
certificats qui identifient le titulaire de ces
ressources (ici, seul le titulaire de
192.0.2.0/24
peut émettre l'autorisation
ci-dessus). Ces certificats suivent le format du RFC 6487.
Les objets d'autorisation utilisent la syntaxe de CMS (RFC 5652), celle-ci permettant de réutiliser les nombreux outils CMS existants (dont plusieurs en logiciel libre, voir mon article sur les outils de la RPKI). Sur cette syntaxe CMS est bâti le gabarit présenté par ce RFC 6488, qui s'applique à tous les objets de la RPKI. Enfin, sur ce gabarit, est bâti la syntaxe précise de chaque type d'objet. Par exemple, les ROA (Route Origination Authorization), une classe particulière d'objets, sont normalisés dans le RFC 6482.
La syntaxe est décrit dans la section 2 du RFC. CMS utilisant
ASN.1, le profil de notre RFC 6488
est décrit en ASN.1. On part de la définition
SignedData
du RFC 5652 :
SignedData ::= SEQUENCE { version CMSVersion, digestAlgorithms DigestAlgorithmIdentifiers, encapContentInfo EncapsulatedContentInfo, certificates [0] IMPLICIT CertificateSet OPTIONAL, crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, signerInfos SignerInfos }
et on y ajoute quelques restrictions ou précisions. Par exemple, le
digestAlgorithm
doit être un de ceux spécifiés
dans le RFC 6485. Même méthode pour les
métadonnées de signature :
SignerInfo ::= SEQUENCE { version CMSVersion, sid SignerIdentifier, digestAlgorithm DigestAlgorithmIdentifier, signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, signatureAlgorithm SignatureAlgorithmIdentifier, signature SignatureValue, unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
Les objets de la RPKI doivent être encodés en DER. La liste des règles sémantiques à respecter figure dans la section 3.
Je le rappelle, ce profil, bien que spécialisé par rapport à CMS, est encore très générique. Chaque classe d'objets signés va donc nécessiter son propre RFC, remplissant les blancs indiqués par la section 4 :
encapContentInfo
(qui contient les données
effectivement signées),Ces classes d'objets sont ensuite enregistrés à l'IANA (section 6).
Notez bien que la sécurité que fournissent ces objets signés est d'authentification et d'intégrité. Les données ne sont pas chiffrées et donc pas confidentielles (section 5). C'est logique, les tables BGP et les informations dans les IRR sont publiques.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Huston, G. Michaelson, R. Loomans (APNIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
La norme de certificats numériques X.509 est d'une telle complexité (comme beaucoup de productions des comités de l'UIT) qu'il est à peu près impossible de la mettre en œuvre complètement et correctement. La plupart de ses utilisations se font sur un profil de la norme, c'est-à-dire une restriction des usages possibles. De tels profils ont permis l'utilisation pratique de X.509, notamment sur l'Internet. Le profil décrit dans ce RFC a été conçu pour les certificats décrivant le « droit d'utilisation » des ressources Internet, ce qui veut dire, dans le monde du routage, les adresses IP et numéros d'AS (collectivement : les INR pour Internet Number Resources). Ces certificats ainsi profilés seront ensuite ceux utilisés pour la RPKI, afin de sécuriser le routage sur l'Internet.
Rappelons le principe : des certificats sont
émis par une autorité, l'AC. Ces certificats suivent le profil décrit ici,
qui est lui-même dérivé du profil PKIX du RFC 5280, de loin le plus répandu sur
l'Internet. Ces certificats permettent à l'autorité de dire « le
titulaire de ce certificat a le droit d'utiliser les adresses
2001:db8:f33::/48
, par exemple de les annoncer
en BGP », en utilisant les extensions INR du
RFC 3779. L'engin qui va valider les routes
(c'est typiquement une machine spécialisée, agissant pour le compte
d'un routeur) fera une validation X.509 de la chaîne des certificats,
plus quelques vérifications spécifiques aux INR (par exemple, dans
certains cas, le certificat peut autoriser une route plus spécifique)
et dira ensuite si la route est valide, ou bien si elle est émise par
un attaquant (ou un maladroit qui a mal configuré BGP).
Donc, un certificat de la RPKI est un certificat PKIX. Les principaux points de notre nouveau profil (section 4) sont le fait que le sujet est un nom choisi par l'AC, la présence obligatoire des extensions INR (Internet Number Resources) du RFC 3779 (le certificat prouve le droit d'usage des préfixes IP indiqués dans ces extensions), et l'indication d'un dépôt accessible en rsync où se trouvent les CRL. Les sections 2 à 6 donnent tous les détails sur ces points.
Quant à la validation des certificats, elle fait l'objet de la section 7, qui précise les points généraux de la section 6 du RFC 5280. Notamment, un certificat peut être accepté même si le préfixe d'adresses présenté est plus spécifique (davantage de bits dans le masque).
La section 8 explique ensuite (et justifie) les principaux choix qui ont été faits lors de la conception de ce profil. Par exemple, notre profil ne permet pas d'utiliser des extensions X.509 autres que celles décrites dans ce RFC. Le but est d'utiliser les certificats dans un environnement bien défini, pour un usage limité, et il s'agit donc de limiter au maximum les risques de non-interopérabilité (un problème fréquent avec X.509, norme conçue par un comité et d'une très grande complexité ; bien des parties de la norme n'ont jamais été testées sur le terrain et nul ne sait comment réagiraient les implémentations). En outre, la RPKI est conçu pour être utilisée dans un contexte opérationnel (le routage sur l'Internet) et il était donc raisonnable de sacrifier l'extensibilité.
Quant au choix du nom du sujet, la RPKI n'étant pas centralisée, et n'ayant pas de système d'allocation arborescente des noms, on ne peut pas espérer avoir des noms uniques. Le RFC conseille donc aux AC (les RIR et les opérateurs réseau) d'adopter un schéma de nommage qui garantisse l'unicité au sein d'une même AC (rappelez-vous que, contrairement à l'utilisation de X.509 dans le cas de TLS, le nom du sujet n'est pas utilisé par la RPKI et n'est donc pas vérifié). Cela peut même être une valeur aléatoire comme un UUID.
L'annexe A du RFC fournit un exemple d'un certificat à ce
profil. Mais on peut aussi l'obtenir en regardant un vrai certificat
de la RPKI avec openssl (attention, il faut
s'assurer qu'il ait été compilé avec l'option
enable-rfc3779
, ce qui n'est pas le
cas chez Debian) :
% openssl x509 -inform DER -text -in \ ./RPKI-repository/33/36711f-25e1-4b5c-9748-e6c58bef82a5/1/wdWccNZAgvBWFvBZNDJDWLtf-KQ.cer Certificate: Data: Version: 3 (0x2) Serial Number: 78697736 (0x4b0d508) Signature Algorithm: sha256WithRSAEncryption Issuer: CN=u75at9r0D4JbJ3_SFkZXD7C5dmg Validity Not Before: May 13 07:43:52 2011 GMT Not After : Jul 1 00:00:00 2012 GMT Subject: CN=wdWccNZAgvBWFvBZNDJDWLtf-KQ Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:99:d8:66:8b:26:15:22:fd:8e:45:c2:32:79:eb: a4:36:d0:6d:47:18:34:d4:ad:17:bf:6f:82:d7:a3: 85:d9:80:ea:9f:59:31:6d:da:9f:b5:e0:36:67:e0: f0:00:1b:96:2d:71:3e:5f:35:e0:f9:98:ee:fa:9f: 3e:6b:ab:9e:18:a6:ad:3c:fd:7a:50:6d:a5:42:4c: bd:2d:02:f0:2a:7a:e6:66:bf:d5:b1:83:f1:19:02: fe:90:21:d2:e3:b3:cc:91:a4:a6:6f:70:be:65:62: 7f:97:c1:43:2e:2c:a5:b2:14:79:e0:f5:5e:4b:c2: aa:ed:13:d0:f2:4d:47:ac:53:fd:82:78:ef:c9:cd: 94:ea:52:10:56:88:80:bc:ca:ad:92:46:ef:4c:ae: aa:ae:ae:02:d6:af:ae:2a:4e:dc:8b:c9:43:57:27: 84:1f:5a:82:ff:d7:24:ac:25:67:66:5f:70:d1:d6: 45:4b:a5:1d:c2:6f:bf:ae:14:3d:e4:2b:50:35:72: ea:52:1c:b2:7d:15:12:15:07:d1:86:bb:2b:4b:ba: 47:1c:3e:37:b7:2c:ab:a6:4e:d3:16:54:84:96:92: 37:b6:6c:5c:3b:61:f1:73:9e:9c:9b:b8:ad:33:f8: e0:19:9e:6a:dc:30:a6:45:90:f7:90:bb:d2:f9:65: 5b:53 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: C1:D5:9C:70:D6:40:82:F0:56:16:F0:59:34:32:43:58:BB:5F:F8:A4 X509v3 Authority Key Identifier: keyid:BB:BE:5A:B7:DA:F4:0F:82:5B:27:7F:D2:16:46:57:0F:B0:B9:76:68 X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: critical Certificate Sign, CRL Sign Authority Information Access: CA Issuers - URI:rsync://rpki.ripe.net/ta/u75at9r0D4JbJ3_SFkZXD7C5dmg.cer Subject Information Access: CA Repository - URI:rsync://rpki.ripe.net/repository/72/f82cc3-00a3-4229-92ff-e5992b4b3fad/1/ 1.3.6.1.5.5.7.48.10 - URI:rsync://rpki.ripe.net/repository/72/f82cc3-00a3-4229-92ff-e5992b4b3fad/1/wdWccNZAgvBWFvBZNDJDWLtf-KQ.mft X509v3 CRL Distribution Points: Full Name: URI:rsync://rpki.ripe.net/repository/33/36711f-25e1-4b5c-9748-e6c58bef82a5/1/u75at9r0D4JbJ3_SFkZXD7C5dmg.crl X509v3 Certificate Policies: critical Policy: 1.3.6.1.5.5.7.14.2 sbgp-ipAddrBlock: critical IPv4: 81.27.128.0/20 IPv6: 2a00:8980::/32 Signature Algorithm: sha256WithRSAEncryption 8f:03:51:23:44:85:92:42:54:37:a2:22:53:66:0a:ab:be:a7: ... 2e:31:d5:0d -----BEGIN CERTIFICATE----- MIIFLDCCBBSgAwIBAgIEBLDVCDANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBt1 ... -----END CERTIFICATE-----
Voyez notamment :
CN=wdWccNZAgvBWFvBZNDJDWLtf-KQ
généré à
partir d'un condensat cryptographique,rsync://rpki.ripe.net/repository/33/36711f-25e1-4b5c-9748-e6c58bef82a5/1/u75at9r0D4JbJ3_SFkZXD7C5dmg.crl
),rsync://rpki.ripe.net/ta/u75at9r0D4JbJ3_SFkZXD7C5dmg.cer
),sbgp-ipAddrBlock
, qui contient un préfixe
IPv4 et un IPv6
(attention, pour les voir, il faut un openssl compilé
avec la bonne option).Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Huston (APNIC), G. Michaelson (APNIC)
Pour information
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
Ce document s'inscrit dans la longue liste des RFC sur la sécurisation du routage BGP. Il décrit la sémantique des ROA (Route Origin Authorization), ces objets qui expriment l'autorisation du titulaire d'un préfixe IP à ce que ce préfixe soit annoncé initialement par un AS donné. La syntaxe des ROA, elle, figure dans le RFC 6482.
Les ROA (Route Origin Authorization) sont issus
de la RPKI, l'IGC du
routage (RFC 6480). Ce sont des objets signés qu'un routeur
BGP peut vérifier lorsqu'il reçoit une
annonce. Ainsi, si un routeur BGP voit son pair lui dire « je connais
un chemin vers 192.0.2.0/24
et son chemin
d'AS est 64498 65551 65540
»,
le routeur peut vérifier que l'AS 65540 a bien été autorisé, par le
titulaire du préfixe 192.0.2.0/24
, à annoncer
cette route (l'origine, le premier AS, est le
plus à droite ; ce RFC ne permet de valider que l'origine, pas le
chemin complet, donc on ne peut rien dire au sujet de la présence des AS 64498
et 65551). Les clés utilisées pour les signatures sont contenues
dans des certificats
X.509 suivant le format Internet standard (RFC 5280) avec des extensions pour stocker des informations comme
les adresses IP (RFC 3779). Ces certificats permettent de vérifier que le
signataire était bien titulaire de la ressource (ici, le préfixe
192.0.2.0/24
). Quant au format des ROA, on l'a
dit, il figure dans le RFC 6482.
Tout d'abord (section 2 du RFC), que se passe-t-il pendant la validation d'une annonce de route et quels sont les résultats possibles ? Une route est composée d'un ensemble de préfixes IP, d'un chemin d'AS et de quelques attributs. L'origine, la seule chose vérifiée par les ROA, est le premier AS du chemin (donc le plus à droite). S'il y a eu agrégation, et que le premier élément du chemin est un ensemble d'AS, l'origine est inconnue.
L'engin qui fait la validation (nommé RP, pour Relying
Party, c'est le routeur
BGP, ou bien une machine spécialisée à laquelle il a sous-traité ce
travail) est supposé avoir accès à tous les ROA valides (ce RFC ne
décrit pas comment, a priori, ce sera le protocole standard de
récupération des préfixes validés, protocole nommé RTR, normalisé dans le RFC 6810). Il cherche les ROA s'appliquant à
l'annonce qu'il veut valider. Si un ROA correspond, l'annonce est
valide. Un ROA pour un préfixe donné
s'applique à tous les préfixes plus spécifiques (ceux où le masque est
plus long). Ainsi, si un ROA dit « l'AS 65540
a le
droit d'annoncer 192.0.2.0/24
», alors une annonce de
192.0.2.128/25
(plus spécifique) est invalide (même si
l'origine est la même, cf. le tableau Route's validity
state). Toutefois, l'utilisation du champ
maxLength
dans le ROA permet d'accepter des
préfixes plus spécifiques (jusqu'à maxLength
). Si une annonce ne
correspond à aucun ROA, elle est dans l'état « inconnu » (également
appelé « non trouvé »). Au début du déploiement, évidemment, la plupart des
annonces seront dans l'état inconnu, puisque peu de ROA seront
émis. Mais dès qu'un opérateur crée un ROA pour un de ses préfixes,
tous les sous-préfixes non signés deviennent invalides (la RPKI suit
le modèle hiérarchique des adresses IP). L'algorithme exact est décrit
à la fin de la section 2. (Ceux qui ont suivi toute l'histoire de ce
RFC avant sa publication noteront que l'algorithme initial était bien
plus complexe.)
Maintenant, que faire de ce résultat ? La section 3 explique comment utiliser cet état (valide, invalide, inconnu) pour sélectionner une route (rappelez-vous qu'un routeur BGP typique reçoit plusieurs routes possibles pour chaque préfixe et qu'il doit choisir). En gros, le routeur doit préférer les routes valides, puis les inconnues. Mais la décision est locale : le RFC n'impose rien, notamment il ne dit pas si le routeur doit ignorer complètement les annonces invalides ou, a fortiori, les inconnues (la très grande majorité, au début du déploiement de ce système). Autre piège : la vitesse de propagation des ROA ne sera pas forcément celle des routes, et une annonce peut arriver avant le ROA correspondant.
Le problème est similaire à celui que connaissent les résolveurs DNS avec DNSSEC. Rejeter les réponses DNS non signées, aujourd'hui, reviendrait à rejeter la majorité des réponses. (Une autre expérience de DNSSEC est que les réponses invalides sont beaucoup plus souvent dues à des erreurs du gentil administrateur systèmes qu'à des attaques par les méchants.) Pour BGP, le problème est plus complexe car il est normal de recevoir plusieurs routes vers la même destination. Sans rejeter les annonces inconnues, le routeur peut donc décider de les faire passer après les valides. Et, s'il n'y a qu'une seule route pour une destination donnée, et que l'annonce est invalide, il vaut peut-être mieux l'accepter que de couper la communication avec le réseau concerné (la résilience de l'Internet le recommande).
Donc, pour résumer la section 3 : chaque administrateur réseaux configure son routeur comme il veut, pour décider du sort des annonces inconnues, et même pour celui des annonces invalides. Un exemple en syntaxe IOS serait :
route-map rpki permit 10 match rpki invalid set local-preference 50 route-map rpki permit 20 match rpki unknown set local-preference 100 route-map rpki permit 30 match rpki valid set local-preference 200
Dans cet exemple, tous les états sont acceptés, mais avec des préférences différentes.
Il est également possible à un titulaire de préfixe d'interdire complètement l'utilisation de ce préfixe, en créant un ROA où le numéro d'AS est mis à zéro (section 4). L'AS 0 est réservé dans le registre IANA et ne doit jamais apparaître dans une annonce réelle.
Une fois une route validée, pendant combien de temps garde-t-elle son état ? Question facile à laquelle la section 5 répond : la durée de validité est celle du certificat qui a signé le ROA (rappelez-vous que les ROA indiquent l'AS d'origine, et que c'est une information relativement stable). Si on veut annuler un ROA avant, il faut révoquer le certificat qui l'a signé.
La section 6 rassemble les considérations de sécurité des ROA : d'abord, elle rappelle qu'il y a un risque réel de se tirer dans le pied. Si on publie un ROA pour un préfixe, les préfixes plus spécifiques deviennent aussitôt invalides. Si on a de ces préfixes plus spécifiques, il faut donc penser à leur créer un ROA avant de publier le ROA le plus général.
Voilà, si vous voulez mettre tout cela en pratique, lisez mon article sur les logiciels de la RPKI.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Lepinski, S. Kent, D. Kong (BBN Technologies)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
Un nouveau sigle va devoir être appris par les administrateurs réseaux et sera sans doute souvent prononcé dans les discussions sur les listes de diffusion d'opérateurs : ROA, pour Route Origin Authorizations, ces objets signés cryptographiquement qui permettent à un routeur BGP de valider l'origine d'une route. Dans la très longue liste des RFC décrivant ce système de sécurité, notre court RFC 6482 décrit le format des ROA. Il a depuis été remplacé par le RFC 9582.
Ces ROA (Route Origin
Authorizations) sont, à bien des égards, le cœur du
système de sécurisation du routage de
l'Internet (dont l'architecture générale est
décrite dans le RFC 6480). Ils expriment des autorisations
d'annonce, par exemple « L'AS 64641
est autorisé à annoncer le préfixe 192.0.2.0/24
» et sont signés par le titulaire de la ressource (ici, le titulaire
du préfixe 192.0.2.0/24
).
Le format des ROA est tiré de la norme CMS (RFC 5652), précisée par le profil générique des objets de la RPKI, dans le RFC 6488. Ce dernier RFC précise, dans sa section 4, les points spécifiques à normaliser pour chaque classe d'objets de la RPKI. Dans le cas des ROA, ces blancs sont remplis ainsi :
Le contenu précis, tel qu'indiqué dans la section 3, est, en ASN.1 :
RouteOriginAttestation ::= SEQUENCE { version [0] INTEGER DEFAULT 0, asID ASID, ipAddrBlocks SEQUENCE (SIZE(1..MAX)) OF ROAIPAddressFamily }
où asID
est le numéro d'AS, et
ipAddrBlocks
la liste des préfixes. Les
ROAIPAddressFamily
sont composées de
ROAIPAddress
et celles-ci ont un attribut
intéressant, maxLength
, qui indique la longueur
maximale des sous-préfixes que peut annoncer cet AS. Par exemple, en
IPv6, un maxLength
de 56
indiquera qu'on peut annoncer un /56 mais pas un /60. L'autre attribut
d'une ROAIPAddress
est le préfixe, représenté
selon les règles du RFC 3779.
La section 4 décrit quant à elle les règles de validation spécifiques aux ROA : aux règles génériques des objets de la RPKI, elle ajoute l'obligation de vérifier que les adresses indiquées dans le ROA figurent bien dans le certificat signataire (c'est-à-dire que c'est bien le titulaire des adresses qui a émis le ROA). Mais il vaut mieux consulter le RFC 6483 pour avoir tous les détails.
À noter qu'on ne peut mettre qu'une seule signature par ROA. Une des vives discussions du groupe de travail SIDR avait porté sur la possibilité de signatures multiples, afin de gérer certaines relations complexes entre clients et opérateurs, mais cela avait finalement été rejeté.
On peut récupérer tous les ROA des préfixes
RIPE en https://certification.ripe.net/certification/public/all-roas
. Si
on en télécharge un, on peut afficher ce contenu avec l'outil du même
RIPE-NCC :
% certification-validator --print -f roa-5574190.roa Content type: 1.2.840.113549.1.9.16.1.24 Signing time: 2011-01-11T19:04:18.000Z ASN: AS559 Prefixes: 193.5.26.0/23 [24] 193.5.152.0/22 [24] 193.5.168.0/22 [24] 193.5.22.0/24 193.5.54.0/23 [24] 193.5.58.0/24 193.5.60.0/24 193.5.80.0/21 [24]
ou bien avec l'outil de l'ARIN, rcynic :
% print_roa /home/bortzmeyer/tmp/roa-5574190.roa Certificates: 1 CRLs: 0 SignerId[0]: b6:6f:5a:10:d5:7f:ed:6d:b1:62:96:2c:cb:92:35:bb:5d:f8:c3:ca [Matches certificate 0] [signingTime(U) 110111190418Z] eContentType: 1.2.840.113549.1.9.16.1.24 version: 0 [Defaulted] asID: 559 addressFamily: 1 IPaddress: 193.5.26.0/23-24 IPaddress: 193.5.152.0/22-24 IPaddress: 193.5.168.0/22-24 IPaddress: 193.5.22.0/24 IPaddress: 193.5.54.0/23-24 IPaddress: 193.5.58.0/24 IPaddress: 193.5.60.0/24 IPaddress: 193.5.80.0/21-24
Comme les ROA sont en CMS, on peut aussi tenter sa chance avec des logiciels qui traitent du CMS générique. Ils ne comprendront pas tout mais pourront au moins afficher une partie de la structure :
% openssl asn1parse -inform DER -in RFZr0zO7xjc1bNCEVboVjI8JZlw.roa 0:d=0 hl=2 l=inf cons: SEQUENCE 2:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-signedData ... 1340:d=7 hl=2 l= 9 prim: OBJECT :contentType 1351:d=7 hl=2 l= 13 cons: SET 1353:d=8 hl=2 l= 11 prim: OBJECT :1.2.840.113549.1.9.16.1.24 1366:d=6 hl=2 l= 28 cons: SEQUENCE 1368:d=7 hl=2 l= 9 prim: OBJECT :signingTime 1379:d=7 hl=2 l= 15 cons: SET 1381:d=8 hl=2 l= 13 prim: UTCTIME :110406122632Z 1396:d=6 hl=2 l= 47 cons: SEQUENCE ...
De même, les outils génériques ASN/1 comme dumpasn1 peuvent permettre de récupérer une partie de l'information dans le ROA. D'autres outils pour jouer avec les ROA sont présentés dans mon article sur les logiciels de la RPKI.
Un exposé d'Arnaud Fenioux à l'assemblée générale du France-IX en septembre 2017 montrait l'utilisation de ces ROA au France-IX.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : G. Huston (APNIC), R. Loomans (APNIC), G. Michaelson (APNIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
La RPKI, cette infrastructure de certificats utilisée pour sécuriser le routage sur l'Internet, repose sur un certain nombre d'objets (certificats mais aussi révocations et surtout les objets signés qui expriment les autorisations, les ROA). Ce RFC décrit comment ils sont stockés dans les points de publication à partir desquels ils sont distribués au monde entier. Cela permet de consolider facilement les données obtenues auprès de plusieurs points de publication. (Il n'est pas obligatoire qu'une copie de la RPKI soit complète.)
Rappelez-vous en effet que les routeurs n'accèdent pas aux informations de la RPKI lorsqu'ils en ont besoin (ce qui ferait dépendre le routeur de serveurs extérieurs) mais à l'avance en chargeant dans un validateur la totalité des informations, que le validateur va ensuite vérifier avant de passer au routeur. Comment se présentent ces informations ? Chacun fait comme il veut mais il existe une forme recommandée, celle de notre RFC 6481.
Dans ce format recommandé, chaque objet va être un fichier. Ces
fichiers vont être placés dans une arborescence de répertoires,
référencée par un URI (typiquement de type
rsync:
).
Dans les exemples ci-dessous, j'utiliserai une copie locale de la RPKI obtenue au RIPE-NCC, avec les outils logiciels de ce même RIPE-NCC (voir mon article sur ces outils).
À chaque point de publication (typiquement, chaque
AC, c'est-à-dire en pratique chaque opérateur
réseau), on trouve un manifeste qui liste les
objets publiés. Le fichier a l'extension .mft
, le type MIME application/rpki-manifest
(cf. section 7.1 du RFC) et
son nom est un condensat cryptographique de la
clé publique de l'AC (en suivant par exemple la section 2.1 du RFC 4387). Voici le contenu d'un tel manifeste, à un petit point
de publication (seulement quatre ROA) :
% certification-validator -print -file Sxe2vn2-fqZLB5Q578V0Vzf_RfQ.mft Serial: 39571085 Subject: CN=779caa1de4e5938149c831b097a86ee561bf12f3 Not valid before: 2011-10-31T03:42:07.000Z Not valid after: 2011-11-01T03:42:07.000Z ... Filenames and hashes: 1c_GrZeKKzG5b9BI9Iu4fEEG-QU.roa 20aade4dd3e303103b7facb0d462d89e0cc74753c99bf35a8ff28d16e48f7e6a 1sOqx9K6uCNTcCTMIe7f5P1bZX0.roa 7e9c4c0be54d180b05743abbd6163f0a812c43d4db59fe0550eb2446ceedbb7e 4nKGhPF4_7JKjwwBrTCXgE_4YYg.roa f1f55d72eb6e66c36b6312c4c6484a83156d32b7e01067a6a3449327095e409f Sxe2vn2-fqZLB5Q578V0Vzf_RfQ.crl 39ec393db6b9a8ec6289304a5c1982ab17ef3bfc5feaffaf4a30174af9054966 TZw7cXuBc5b9BOlBHqCtAEgTZ-w.roa bd7aa3efae357a8591a7b5d708ccb509ad30f791063ea6fe9aa53730d95cb680
On trouve également des révocations, dans
des fichiers ayant l'extension .crl
(et le type MIME application/pkix-crl
qui vient du RFC 2585) :
% certification-validator -print -file Sxe2vn2-fqZLB5Q578V0Vzf_RfQ.crl CRL type: X.509 CRL version: 2 Issuer: CN=Sxe2vn2-fqZLB5Q578V0Vzf_RfQ Authority key identifier: Sxe2vn2-fqZLB5Q578V0Vzf_RfQ= Number: 790 This update time: 2011-10-31T03:42:07.000Z Next update time: 2011-11-01T03:42:07.000Z Revoked certificates serial numbers and revocation time: 32399600 2011-09-10T05:40:48.000Z
On trouve bien sûr les certificats, encodés au format
DER et stockés dans des fichiers ayant
l'extension .cer
et le type MIME application/pkix-cert
:
% certification-validator -print -file Fx2dYP3STZSiTUjLGrM8oDkK4Ys.cer Serial: 18282008 Subject: CN=Fx2dYP3STZSiTUjLGrM8oDkK4Ys Not valid before: 2011-01-12T02:39:31.000Z Not valid after: 2012-07-01T00:00:00.000Z Resources: 46.254.48.0/21
Notez qu'il s'agit d'un format standard donc
OpenSSL peut l'afficher aussi (pour voir les
ressources gérées, ici 46.254.48.0/21
, il faut un
OpenSSL compilé avec l'option RFC 3779) :
% openssl x509 -inform DER -text -in Fx2dYP3STZSiTUjLGrM8oDkK4Ys.cer Certificate: Data: Version: 3 (0x2) Serial Number: 18282008 (0x116f618) Signature Algorithm: sha256WithRSAEncryption Issuer: CN=u75at9r0D4JbJ3_SFkZXD7C5dmg Validity Not Before: Jan 12 02:39:31 2011 GMT Not After : Jul 1 00:00:00 2012 GMT Subject: CN=Fx2dYP3STZSiTUjLGrM8oDkK4Ys ... sbgp-ipAddrBlock: critical IPv4: 46.254.48.0/21
Et, bien sûr, le dépôt contient des autorisations d'annonces de
route, les ROA (Route Origination
Authorization), normalisés dans le RFC 6482. Elles sont contenues
dans des fichiers d'extension .roa
et ont le type MIME application/rpki-roa
:
% certification-validator -print -file FiUGfSV6BgZqFlJnQ7SSq_700w8.roa Content type: 1.2.840.113549.1.9.16.1.24 Signing time: 2011-04-11T15:07:23.000Z ASN: AS56595 Prefixes: 46.226.0.0/21 2a00:a600::/32
Le ROA ci-dessus autorise l'AS 56595 à annoncer
des routes pour 46.226.0.0/21
et
2a00:a600::/32
. À noter que la suite logicielle
rcynic permet également l'affichage de
ROA :
% print_roa FiUGfSV6BgZqFlJnQ7SSq_700w8.roa Certificates: 1 CRLs: 0 SignerId[0]: 16:25:06:7d:25:7a:06:06:6a:16:52:67:43:b4:92:ab:fe:f4:d3:0f [Matches certificate 0] [signingTime(U) 110411150723Z] eContentType: 1.2.840.113549.1.9.16.1.24 version: 0 [Defaulted] asID: 56595 addressFamily: 1 IPaddress: 46.226.0.0/21 addressFamily: 2 IPaddress: 2a00:a600::/32
La section 3 décrit ensuite les caractéristiques souhaitées du serveur qui va publier toutes ces informations. Il doit notamment être très fiable : même si le serveur n'est évidemment pas accédé de manière synchrone, à chaque mise à jour BGP, il doit néanmoins être accessible la grande majorité du temps, puisque toute panne empêchera les mises à jour de la base et aura potentiellement des conséquencees opérationnelles sur le routage. C'est une tâche nouvelle, par exemple pour les RIR, qui n'avaient pas de rôle opérationnel avant.
Ce serveur doit utiliser rsync (cf. RFC 5781) et peut aussi utiliser d'autres protocoles en prime. Grâce à rsync, la commande :
% rsync -av rsync://rpki.ripe.net/repository /var/RPKI
va vous récupérer tous les objets décrits ici, tels qu'ils sont
distribués par le RIPE-NCC, et les mettre dans
le répertoire /var/RPKI
. rsync travaillant de
manière incrémentale, seules les nouveautés seront chargées, pas la
totalité de la base (sauf la première fois).
Cette commande peut donc être placée dans le crontab de la machine qui fera la validation. Toutefois, la section 3 recommande des techniques plus subtiles, à base de copie dans un dépôt temporaire puis de renommage (ce que font automatiquement les outils de rcynic), avant d'éviter une incohérence si le rsync est interrompu et qu'on n'a récupéré qu'une partie de la base.
Cette copie locale de la RPKI dans le validateur (machine qui sera proche des routeurs qui l'interrogeront) permettra de fonctionner même en cas de panne des serveurs de distribution (cf. section 5).
Attention à la sécurité, nous avertit la section 6. Les
informations de la RPKI sont publiques, il n'y a donc pas besoin de
confidentialité, mais il est essentiel que leur
intégrité soit préservée. Le protocole rsync utilisé plus haut ne
fournit aucune garantie en ce sens. En fait, la protection des données
est complètement assurée par les signatures faites avec les clés
contenues dans les certificats. Il ne faut donc
pas utiliser les informations RPKI récupérées
avant d'avoir validé (vérifié les signatures). C'est ce que fait
automatiquement rcynic en déplaçant les données validées dans un
répertoire nommé authenticated
:
% pwd /var/rcynic/data % ls -lt total 12 lrwxrwxrwx 1 rcynic rcynic 34 Oct 31 15:42 authenticated -> authenticated.2011-10-31T13:36:08Z lrwxrwxrwx 1 rcynic rcynic 34 Oct 31 15:42 authenticated.old -> authenticated.2011-10-31T11:36:11Z drwxr-xr-x 15 rcynic rcynic 4096 Oct 31 15:42 authenticated.2011-10-31T13:36:08Z drwxr-xr-x 15 rcynic rcynic 4096 Oct 31 14:31 authenticated.2011-10-31T11:36:11Z drwxr-xr-x 17 rcynic rcynic 4096 Oct 31 11:31 unauthenticated
Les extensions des différents fichiers stockés figurent dans un registre IANA.
Date de publication du RFC : Février 2012
Auteur(s) du RFC : M. Lepinski, S. Kent (BBN Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 4 février 2012
Les techniques de sécurisation de BGP du groupe de travail SIDR viennent d'être publiées. Elles reposent sur une infrastructure de clés publiques cryptographiques, la RPKI (Resource Public Key Infrastructure). Ce RFC décrit cette RPKI, fondation de tous les systèmes de sécurisation du routage dans l'Internet, ainsi que l'architecture générale du système.
Le principe est le suivant : le titulaire d'un préfixe IP a un certificat lui permettant de signer des objets, par lesquels il autorise tel ou tel AS à annoncer ce préfixe. Ces signatures peuvent être ensuite vérifiées par les routeurs, qui rejetteront les erreurs et les tentatives de piratage.
La section 1 résume les trois composants essentiels de la solution, qui permettra de protéger le routage BGP (RFC 4271) :
Dans un premier temps, cette solution permettra de valider l'origine des annonces BGP (le premier AS, cf. RFC 6483). Plus tard, elle pourra servir de base à des solutions plus globales, encore en cours de développement, comme soBGP ou Secure Border Gateway Protocol (Secure-BGP).
La correspondance entre le graphe des certificats et celui existant pour allouer des ressources comme les adresses IP évite de réinventer une nouvelle classe d'acteurs. Cela ne veut pas dire que les rapports de force ne vont pas être modifiés. Ainsi, à l'heure actuelle, un RIR peut toujours, techniquement, retirer un préfixe à un LIR, mais cela n'aura pas de conséquence pratique, le RIR n'ayant aucun rôle dans le routage. Demain, avec la RPKI, le RIR enverra une révocation et les routeurs considéreront la route comme invalide... Il y a donc bien renforcement des pouvoirs de la hiérarchie, comme l'analysait un article de l'IGP.
Techniquement, peu de protocoles ou de formats nouveaux sont développés. Ainsi, les certificats de la RPKI sont du X.509, avec les extensions déjà existantes de l'IETF, RFC 5280, plus celles permettant de représenter des ressources (adresses IP et numéros d'AS), normalisées dans le RFC 3779 et suivant le profil du RFC 6487. Les objets signés (cf. RFC 6488) utilisent quant à eux le format CMS (RFC 5652).
Le premier des trois composants, la RPKI (Resource Public
Key Infrastructure), est décrit en section 2. L'idée est que
c'est le titulaire d'une plage d'adresses IP qui
décide comment elle peut être routée et par qui. Les certificats
permettent donc d'attester que telle entité est bien le titulaire (ce
qui se fait actuellement en consultant la base du RIR, par exemple via
whois). L'IANA va donc
signer les plages qu'elle alloue aux RIR (cette étape est optionelle,
voir plus loin), les RIR signent les plages qu'ils allouent aux LIR et
ainsi de suite si nécessaire (il y a des cas plus complexes, pour les
NIR, ou bien pour les adresses
PI, ou encore lorsqu'un titulaire sous-alloue
une partie de ses adresses). Lorsqu'un certificat affirmera « je
suis titulaire du 192.0.2.0/24
», il sera ainsi
possible de remonter la chaîne, jusqu'à une référence de confiance
(l'IANA ou bien l'ensemble des RIR) pour vérifier cette
assertion. Donc, bien que le routage dans l'Internet ne soit
pas hiérarchique, l'allocation l'est, et la RPKI
s'appuie là-dessus.
Les exemples ci-dessus portent sur des adresses IP mais le raisonnement est le même pour les numéros d'AS, d'où ce nom collectif de ressources (adresses IP et numéros d'AS).
Il faut bien noter que ces certificats, s'ils sont techniquement des certificats X.509 comme les autres, ont une sémantique différente; Le fait qu'une CA signe un certificat ne dit pas qu'elle certifie l'identité contenu dans le certificat mais qu'elle certifie le lien entre une ressource et un titulaire. Ces certificats sont davantage d'autorisation que d'authentification. Le RFC recommande simplement de mettre comme nom (X.509 appelle cela le subject) un identificateur spécifique à la CA, par exemple un numéro de client.
Comme cette sémantique est différente, et qu'il n'y a pas les risques juridiques associés aux certificats d'authentification classiques, il n'y a donc pas de nécessiter d'utiliser les CA existantes, ni de raison d'hésiter, pour un opérateur, à devenir CA. Les certificats fournis aux entités intermédiaires (typiquement les LIR) doivent être des certificats CA, autorisant le titulaire à émettre lui-même des certificats (la signature de chaque objet nécessite la création d'un certificat pour cet objet, cf. section 2.2). Les sites terminaux, en général, n'auront pas besoin de certificats du tout (sauf s'ils sont multi-homés avec des adresses PI, cf. section 7.3.2).
Les certificats finaux (section 2.3), ceux qui n'auront pas besoin d'avoir le bit CA à un, servent pour signer les objets (l'intérêt de créer un certificat juste pour signer un objet est de permettre une révocation, en réutilisant les mécanismes existants de X.509).
Pour vérifier, les validateurs (les routeurs BGP, ou bien les machines à qui ces routeurs sous-traiteront le travail), auront besoin de certificats « racine ». Comme en général pour X.509, le choix de ces certificats est une question politique locale et n'est pas spécifiée par la norme. Le RFC évite ainsi (section 2.4) l'épineuse question politique de savoir s'il faut configurer le validateur avec le certificat de l'IANA (donnant à celle-ci un grand pouvoir) ou bien avec les certificats des cinq RIR (court-circuitant ainsi l'IANA).
La section 3, elle, décrit les objets qu'on va signer, les
ROA (Route Origination
Authorization). La RPKI va dire « il est le titulaire de
192.0.2.0/24
» et le ROA va ajouter « l'AS 64641
est autorisé à annoncer 192.0.2.0/24
» (le ROA
n'autorise que l'origine, pas les AS ultérieurs qui relaieront
l'annonce). Le ROA est donc tout au bout du graphe des
autorisations. On pourrait donc avoir une chaîne comme :
Le format des ROA est décrit en RFC 6482 et leur utilisation dans la validation des annonces BGP en RFC 6483. Le format est une spécialisation du format générique des objets de la RPKI, décrit dans le RFC 6488, lui-même issu de CMS. Chaque ROA contient un numéro d'AS, un ou plusieurs préfixes que cet AS a l'autorisation d'« originer » et (facultativement) une longueur maximale des sous-préfixes. Notez bien qu'il n'y a qu'un AS. Si plusieurs AS ont le droit d'être à l'origine des annonces de ces préfixes, il faut créer plusieurs ROA. Il n'y a pas de durée de validité dans le ROA, la validité est celle du certificat.
La distribution des ROA se fait essentiellement par le
système de dépôts décrit dans la section 4 mais pourrait se faire dans
le futur par d'autres moyens, comme les messages BGP UPDATE
.
On l'a vu, la validation des routes suppose que les validateurs (les
routeurs BGP eux-même, ou bien des machines spécialisées à qui les
routeurs sous-traitent l'opération) aient accès à tous les ROA. (Ce
n'est pas un nombre énorme, typiquement un seul par route visible
mondialement.) Un mécanisme est proposé pour créer un dépôt distribué
de ROA, accessible à la demande (les mécanismes où les ROA seraient
poussés vers les validateurs, par exemple par BGP, ne sont pas encore
définis). Le dépôt est décrit en détail dans le RFC 6481.
Le dépôt n'est pas spécialement « de confiance ». Ce sont les signatures sur les ROA qui comptent, pas l'endroit où ils ont été récupérés. C'est d'autant plus vrai que le RFC encourage à recopier le dépôt, pour faciliter l'accès.
Le dépôt pourra offrir un choix de protocoles d'accès (section 4.3). Notre RFC décrit juste les fonctions de ces protocoles :
Des tas de protocoles offrent ces fonctions (par exemple HTTP/REST, même s'il n'est pas cité). Pour éviter que chaque acteur du routage ne déploie un protocole d'accès différent, rendant la vie des clients infernale, notre RFC impose que chaque copie soit accessible en lecture avec rsync, garantissant ainsi un mécanisme toujours disponible. On désigne donc la copie avec un URI rsync (RFC 5781) et on y accède par :
% rsync -av rsync://rpki.ripe.net/repository /where/i/want/RPKI-repository
Les experts en sécurité ont peut-être noté un peu de hand waving dans les paragraphes précédents. J'ai dit que la sécurité du dépôt était peu importante puisque ce sont les signatures des ROA qui font foi et que l'endroit où on les a trouvé ne compte donc pas. Mais si un méchant arrive à modifier un dépôt et supprime un ROA ? La signature ne protège pas contre ce genre de problèmes. La RPKI a donc un système de manifestes, des listes d'objets signés, listes elle-même signées et mises dans le dépôt (section 5 et RFC 6486).
Le dépôt sera donc massivement distribué, et les validateurs encouragés à garder des copies locales. La section 6 décrit ce processus, où le validateur obtient la copie de tous les objets (ROA, certificats, manifestes, etc), valide la signature des manifestes, puis vérifie leur contenu, et vérifie la signature des objets indiqués dans le manifeste.
Comme avec tous les caches, cette copie pose le problème de la fraîcheur des informations. Le cache ne contient-il pas des informations dépassées ? La section 6 n'est pas très bavarde sur ce point. À l'heure actuelle, ces informations de routage sont assez stables (on ne change pas d'AS d'origine tous les mois) donc le problème n'est pas trop aigü.
La section 7 décrit la vie du dépôt, et les opérations courantes. Les acteurs du routage devront donc désormais penser à la mise à jour de ce dépôt. Dans le futur, l'émission de ces certificats se fera peut-être automatiquement, en même temps que l'allocation des ressources. Aujourd'hui, ce n'est pas encore le cas.
La section 7.3 décrit en détail les aspects pratiques de cette gestion des ROA. Il va falloir acquérrir de nouveaux réflexes, notamment celui de créer et signer des ROA lors de tout changement de la politique de routage. Comme l'absence d'un ROA pour une annonce donnée pourra être interprété comme un détournement, et mener à un refus de l'annonce BGP par les routeurs validants, il y aura plein de possibilité de « se tirer une balle dans le pied ». Les opérateurs devront donc appliquer le principe « make before break », c'est-à-dire créer le ROA signé bien avant d'annoncer la route (pour permettre à tous les dépôts et tous les caches d'être à jour) et, en sens inverse, arrêter l'annonce longtemps avant de signer la révocation du ROA correspondant (et s'assurer qu'il existe un autre ROA, pour la nouvelle annonce).
Cela ne s'applique qu'aux opérateurs, pas au client final. Le site qui a des adresses PA et est connecté à un seul opérateur, n'a rien à faire, les ROA seront émis par l'opérateur. Ce site ne participe donc pas à la RPKI. En revanche, un site multi-homé peut, dans certains cas, avoir à émettre des ROA. Par exemple, s'il a un préfixe PA qu'il fait relayer par deux opérateurs, il doit créer un ROA pour cela (et donc obtenir un certificat depuis l'opérateur qui lui a affecté le préfixe PA) ou demander à l'opérateur de le faire pour lui. Si les adresses sont PI, le site doit émettre un ROA avec son propre AS en origine, en utilisant le certificat reçu avec le préfixe PI.
Si vous souhaitez appronfondir la question, une liste d'articles à lire se trouve dans mon article général. Si vous voulez pratiquer et voir la RPKI en action, regardez mon article sur les logiciels.
Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : K. Li, B. Leiba (Huawei Technologies)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF vcarddav
Première rédaction de cet article le 24 décembre 2011
Le format de carte de visite numérique
vCard, normalisé dans le RFC 6350, est un des grands succès de l'Internet. On trouve ces
cartes partout. Le format de base définit un jeu de données limité
mais permet des extensions. Ce RFC est donc la
première extension à vCard version 4 (ex-aequo avec celle du RFC 6473), et normalise des
champs pour indiquer un lieu de naissance, un lieu de mort et une date
de mort (la date de naissance, BDAY
, est dans le
format de base).
La section 2 décrit ces trois propriétés, toutes facultatives :
BIRTHPLACE
indique le lieu de naissance. Il
peut être indiqué en texte libre ou bien sous forme d'une
URI, comme par exemple les URI de plan
geo:
du RFC 5870. Ainsi,
Jésus-Christ pourrait avoir
BIRTHPLACE: Dans une grange, Bethléem
(Palestine)
ou bien
BIRTHPLACE;VALUE=uri:geo:31.7031,35.196
.DEATHPLACE
indique le lieu de
mort, par exemple DEATHPLACE: Colline
du Golgotha, Jérusalem
(le RFC fournit un exemple où la
longitude et latitude
indiqués sont celles du point où a coulé le
Titanic).DEATHDATE
indique la date de la mort. Il
avait longtemps été envisagé de la garder dans le format de base,
comme BDAY
mais elle avait finalement été
retirée, suite à la réunion IETF de
Pékin en 2010. Comme
son homologue BDAY
, le format préféré de
DEATHDATE
est celui
d'ISO 8601 (cf. RFC 6350,
section 4.3), par exemple DEATHDATE:00300501
(date mise un peu au hasard, vu le manque de sources fiables...). Mais on peut aussi utiliser du texte libre pour le cas où
on doit utiliser des formules vagues comme « au début du treizième
siècle ».Un exemple complet d'une vCard avec ces trois propriétés est :
BEGIN:VCARD VERSION:4.0 FN:Jeanne d'Arc N:d'Arc;Jeanne;;; UID:urn:uuid:4f660936-28d5-46bf-86c6-9720411ac02a GENDER:F KIND:individual TITLE:Bergère TITLE:Pucelle TITLE:Sauveuse de la France PHOTO:http://commons.wikimedia.org/wiki/File:Lenepveu,_Jeanne_d%27Arc_au_si%C3%A8ge_d%27Orl%C3%A9ans.jpg LANG:fr URL:http://fr.wikipedia.org/wiki/Jeanne_d%27arc BDAY:14120106 BIRTHPLACE:Domrémy (Lorraine) DEATHDATE:14310530 DEATHPLACE:Rouen (Normandie) END:VCARD
Ces trois nouvelles propriétés sont désormais enregistrées dans le registre IANA.
Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : C. Lewis (Nortel
Networks), M. Sergeant (Symantec Corporation), J. Levine (Taughannock Networks)
Pour information
Première rédaction de cet article le 19 janvier 2012
En raison de l'importance du problème du spam (et d'autres comportements tout aussi nuisibles), un grand nombre de sites utilisent des listes noires des gens avec qui on ne veut pas communiquer (DNSBL pour DNS-based Black List). Ces listes sont souvent distribuées via le DNS, et gérées par des organismes très divers, dont le niveau de sérieux et d'honnêteté est très variable. La question étant très polémique, documenter le comportement attendu de ces organismes n'a pas été une mince affaire. Ce RFC 6471 décrit donc ce qu'on espère d'un gérant de DNSBL.
Rien ne dit qu'il sera suivi, bien sûr. Mais l'espoir est que ce document serve à faire évoluer les choses dans le bon sens. À noter que le groupe en charge de ce RFC, l'Anti-Spam Research Group de l'IRTF, n'a pas toujours réussi à se mettre d'accord sur le comportement idéal de la DNSBL. Dans ces cas, ce RFC 6471 se contente d'indiquer des recommandations sur la forme (« le gérant de DNSBL devrait documenter ce qu'il fait » si le RFC ne peut pas dire ce qui devrait être fait). La section 1.4 rappelle d'ailleurs que les règles de l'IRTF n'imposent pas de consensus au sein du groupe avant publication. À noter que ce RFC ne parle pas de protocole, les questions purement techniques étant traitées dans le RFC 5782.
Le sujet est tellement polémique que je ne vais pas forcément me contenter d'un compte-rendu neutre, objectif et ennuyeux de ce RFC et que je risque de glisser quelques opinions personnelles, pour lesquelles je demande l'indulgence de mes lecteurs. C'est que les DNSBL sont un marécage de gens bizarres, de racketteurs (« pour être retiré de notre liste, il faut payer »), d'éradicateurs (« nous avons mis les trois-quarts de l'Afrique en liste noire ») et de quelques personnes sérieuses. Le groupe ASRG représente plutôt le point de vue des éradicateurs (« dans le doute, on filtre »).
La section 1 du RFC rappelle ce qu'est une DNSBL et comment elle fonctionne. Les détails techniques du fonctionnement de ce service sont exposés dans le RFC 5782. L'idée est de publier dans le DNS les noms de domaine des méchants, ou bien les adresses IP de leurs serveurs de messagerie. Le serveur qui reçoit du courrier peut alors, en consultant le DNS (ce qui est simple et rapide), prendre connaissance de la « note » attribuée au domaine ou à l'adresse IP par le gérant de la DNSBL. Sur la base de cette note, il peut alors décider de filtrer, de contrôler plus étroitement, etc. Rappelons-bien que c'est le destinataire qui décide quoi faire du courrier, pas le gérant de la DNSBL, qui se contente de publier une information. Au bout du compte, c'est le gérant du serveur de messagerie de destination qui est responsable de l'usage qu'il fait de cette information. Beaucoup sont irresponsables, et filtrent aveuglément sur la base de listes noires sur lesquelles ils n'ont même pas pris la peine de se renseigner.
Comme le DNS est une technique éprouvée, très fiable et rapide, cet
usage original des DNSBL s'est étendu. On voit aujourd'hui des DNSWL
(listes blanches, désignant ceux qui ont droit à un traitement de
faveur), listes d'URI dont la présence dans un
courrier indique un spam, etc. On voit aussi des changements dans
l'usage de ces listes. Très binaire autrefois (l'adresse IP est
présente dans la liste noire => on rejette le message), il est
devenu plus souple, les résultats d'une recherche dans la liste noire
étant souvent un facteur de décision parmi d'autres
(SpamAssassin fonctionne ainsi). Poursuivant
cette idée d'utiliser le DNS pour récupérer de l'information, on voit
aussi des services de géolocalisation utilisant
le DNS et d'autres encore plus techniques (je me sers beaucoup du
domaine aspath.routeviews.org
de Route Views, qui permet de
récupérer les informations de routage d'une
adresse). Enfin, les listes distribuées par le DNS sont désormais
utilisées pour bien d'autres choses que le courrier, par exemple pour
du contrôle d'accès à des serveurs IRC ou des
formulaires Web. Bref, on peut tout faire avec le DNS, qui a cessé il y bien
longtemps d'être uniquement un service qui « traduit des noms de domaine en
adresses IP ».
Quelles sont les DNSBL aujourd'hui ? Il y a de tout, certaines sont privées, gérées par une organisation pour son besoin propre, d'autres publiques et gratuites, d'autres payantes (beaucoup de DNSBL sont gratuites en dessous d'un certain seuil d'utilisation et payantes ensuite). On estime qu'il existe plus de 700 listes publiques, la plus ancienne ayant été créée en 1997. À cette époque, les spammeurs utilisaient leurs propres machines et c'est en grande partie en raison des DNSBL, qui distribuaient rapidement les adresses de ces machines, que les spammeurs sont passés à d'autres tactiques (comme les relais de courrier ouverts), tactiques à lesquelles les DNSBL ont dû s'adapter.
Il n'y a pas que le statut juridique et administratif qui différencient les DNSBL actuelles. Elles se différencient également par leurs politiques (comment une entrée est-elle ajoutée à la base et, plus important, comment elle est retirée) et, comme le note pudiquement le RFC, les DNSBL se différencient aussi par le niveau d'honnêteté de leurs responsables.
Justement, cette politique (qui va être mis dans la liste noire, sur quels critères ?) est un point de controverse permanent. Des cow-boys qui vous blacklistent un /20 entier parce qu'une adresse a envoyé un spam, aux gens sérieux qui prennent beaucoup de temps et d'effort avant d'ajouter une adresse à la base, il y a un large spectre d'opinions. Ce RFC 6471 n'essaie pas de trancher entre ces opinions. Il ne dit pas quelle est la bonne politique, simplement que le gérant de la DNSBL doit documenter ses critères d'inclusion et d'exclusion, et faire ensuite réellement ce qu'il annonce (ce qui est très loin d'être le cas). C'est ensuite à l'utilisateur de la DNSBL (l'administrateur d'un serveur de messagerie qui décide d'interroger cette base avant d'accepter un message) de s'informer et de s'assurer que la politique de la DNSBL lui convient.
La section 1.2 fournit une bonne check-list pour ledit utilisateur, sous forme d'une série de questions à se poser avant d'utiliser une DNSBL. Par exemple (entre parenthèses, une étude de l'application de cette check-list à Spamhaus, pour sa liste SBL) :
Il faut en outre réviser ces questions de temps en temps, les listes évoluent et plus d'une a cessé tout fonctionnement.
Le RFC enfonce le clou à plusieurs reprises : c'est
l'utilisateur qui est responsable, au final, pas la
DNSBL. Certes, c'est un plaidoyer pour les gérants de DNSBL
(« ce n'est pas nous qui filtrons », remarque courante des DNSBL face aux contestations) mais cela reflète la
réalité. Filtrer avec une DNSBL, c'est sous-traiter une partie
de sa sécurité, c'est confier les décisions à d'autres (la section 4
revient sur ce point et rappelle que des DNSBL ont déjà listé
0/0
c'est-à-dire tout l'Internet). Il est donc
crucial d'évaluer les sous-traitants. Le
postmaster responsable
comprend ce point : la DNSBL exprime une opinion, mais c'est lui qui
décide d'agir sur la base de cette opinion.
Bref, quels sont les conseils effectifs de ce RFC 6471 ? Ils commencent en section 2. D'abord, la transparence de l'offre. La DNSBL doit écrire noir sur blanc quels sont les critères pour être mis dans la liste noire et quels sont ceux pour être enlevés. Par exemple, une liste qui s'appuie sur un pot de miel peut avoir comme critère d'ajout « On ajoute toute adresse IP qui a envoyé au moins trois messages dans une semaine aux adresses du pot de miel » et comme critère de retrait « On retire toute adresse qui n'a rien écrit au pot de miel depuis deux mois ». Cette politique doit ensuite être suivie rigoureusement et honnêtement. Dans la jungle des DNSBL, on a déjà vu des gérants de liste qui ajoutaient à la liste noire les adresses IP des gens qui les critiquaient (spite listing)... Il y a des tas de politiques raisonnables, l'important est de se tenir à celle publiée. Si on prétend gérer une liste de relais de courrier ouverts, on ne doit pas y mettre des adresses IP pour une autre raison, même en rapport avec le spam.
La transparence n'empêche pas des politiques dingues, mais ouvertement assumées par le gérant de la liste. Un bel exemple est chez UCEprotect, qui menace directement les critiques « Should you want to contact us, you should keep this in mind and behave rationally and calmly in order not to aggravate your situation. [...] Applying legal action or other pressure against us will result in your IP address and/or your network range being listed in our database. ».
À noter que cette règle de transparence n'impose pas de donner tous les détails. Par exemple, l'opérateur de la liste ne va évidemment pas publier les adresses du pot de miel, cela détruirait complètement son efficacité.
Ensuite, la traçabilité. La DNSBL devrait maintenir un historique des ajouts et retraits, avec les raisons, et publier cet historique. Là encore, l'historique publié peut être expurgé mais il doit contenir suffisamment d'informations pour qu'un utilisateur (ou l'administrateur d'une machine listée dans la liste noire) puisse comprendre pourquoi. Si on prend (un peu au hasard), la liste CBL, on trouve juste : « IP Address X.Y.Z.170 is listed in the CBL. It appears to be infected with a spam sending trojan or proxy. It was last detected at 2011-12-17 12:00 GMT (+/- 30 minutes), approximately 4 hours ago. », ce qui est un peu court.
Beaucoup de gérants de DNSBL sont du genre « éradicateur » et n'hésitent pas devant les dommages collatéraux. Le RFC dit d'ailleurs franchement qu'on ne fait pas d'omelette sans casser d'œufs. Ainsi, il arrive que des listes répondent pour des adresses qui n'ont pas eu de comportement malveillant mais font partie du même préfixe (mettre dans la liste tout un /28 lorsqu'une seule adresse IPv4 de ce /28 a mal agi, par exemple). Le RFC recommande que cette pratique d'élargissement soit clairement documentée.
L'entrée dans la liste est une chose. Mais, avec la plupart des DNSBL, les problèmes sont encore pires pour sortir de la liste. Même quand l'entrée est correctement faite, et à juste titre, on peut avoir des difficultés incroyables pour se faire rayer de la liste. Par exemple, une machine Windows devient un zombie, crache du spam à tout va, et se retrouve « noirlistée », ce qui est normal. Ensuite, l'administrateur système prend les choses en main, reformate le disque, installe NetBSD à la place, et va tenter de « délister » la machine, désormais propre. Avec la plupart des DNSBL, il aura un mal fou. Être enregistré dans une liste est facile, la quitter est très très dur. C'est le même problème lorsqu'une organisation disparait et que ses adresses IP sont récupérées par une autre, qui va s'apercevoir, mais trop tard, que le RIR lui a passé des adresses plombées par une mauvaise réputation.
Le RFC demande donc que les gérants de liste changent de perspective. Au lieu de considérer le retrait comme une opération en soi, toute la liste devrait être considérée comme temporaire et la sortie devrait être automatique au bout d'un moment.
Quelle durée avant cette expiration automatique ? Cela dépend de comment est constituée la liste. Si elle est faite manuellement, sur la base d'informations relativement statiques, comme les allocations de préfixes IP, alors les durées de vie peuvent être longues. Si la détection est automatique (par exemple une liste noire de relais HTTP ouverts), alors une durée de vie très courte est plus raisonnable. Ainsi, la machine dont la configuration a été corrigée disparaîtra vite de la liste et la machine qui rechute sera vite réadmise dans la liste. Dans tous les cas, le RFC demande que la politique d'expiration soit elle aussi publiée. Des informations comme « dernière vérification le tant » sont très précieuses pour évaluer la qualité d'une entrée de la base.
Autre bonne pratique, la fourniture d'un canal privé pour demander le retrait d'une entrée dans la base. Il est nécessaire qu'un tel canal soit disponible. Cela peut être aussi simple qu'une adresse de courrier ou qu'un formulaire Web. Mais, en tout cas, une DNSBL ne devrait pas exiger de discussion publique de la demande de retrait. (Oui, certaines le font, comme forme de punition des administrateurs systèmes qui ont fait preuve de négligence, et laissé leur machine être utilisée pour le spam.)
Et, bien sûr, la DNSBL doit fournir un canal de communication qui
ne soit pas lui-même bloqué par la DNSBL... Si l'administrateur de
192.0.2.25
veut demander le retrait de cette
adresse de la liste, et que le canal des demandes de retrait est une
adresse de courrier, sur un serveur qui utilise la DNSBL, on se
retrouverait dans une situation très kafkaïenne. Bien sûr, ces adresses de demande de
retrait reçoivent beaucoup de spam mais le filtrage qui les protège
devrait être très prudent, pour ne pas rejeter des demandes
légitimes.
Les réponses à ces demandes de retrait devraient être raisonnablement rapides. Le RFC suggère deux jours (et sept au grand maximum).
Certaines DNSBL n'acceptent de demandes de retrait de la liste noire que lorsqu'il y a eu une forme d'authentification que le demandeur est bien en charge de l'adresse en question (vérification de l'adresse de courrier dans les bases des RIR, par exemple). Cette pratique est déconseillée car une telle authentification est souvent très difficile à fournir dans l'Internet d'aujourd'hui.
Le RFC recommande même de sérieusement envisager la possibilité de retirer automatiquement les adresses incriminées, sur simple requête (politique dite « pas de question » car on ne demande rien au demandeur). Si l'inscription dans la liste est le résultat d'un test automatique, l'adresse IP « coupable » sera très vite remise, de toute façon. Si on craint une guerre d'ajout/retrait dans la base, il suffit de mettre une limitation au rythme des requêtes (par exemple, deux retraits maximum en vingt-quatre heures) ou de détecter ces guerres et de verrouiller alors l'adresse dans la base. Une telle politique « pas de question » permet de corriger très vite les erreurs dans la base, et ne diminue pas sensiblement l'efficacité globale de la DNSBL (qui ne dépend pas de quelques adresses). Enfin, cette politique permet de désamorcer les (nombreux) conflits entre les gérants de la DNSBL et les responsables des adresses noirlistées.
On l'a vu, ce RFC ne veut pas trancher la question de savoir si une politique d'ajout dans la liste est correcte ou pas. Par contre, la liste des bonnes pratiques demande qu'il y ait symétrie entre la politique d'ajout et celle de retrait. Normalement, si une adresse est ajoutée pour une raison X, et que X cesse d'être vrai, l'adresse devrait être retirée. Par exemple, si une DNSBL stocke les adresses IP des relais de courrier ouverts, elle devrait retirer les adresses qui ne sont plus de tels relais (parce que l'administrateur a réparé la configuration). Cette recommandation du RFC va à l'encontre de la pratique de certaines DNSBL de punir les gérants des machines en question, en demandant une autocritique publique, voire carrément de l'argent, pour être délisté.
Enfin, dernière bonne pratique dans la section 2, cette question du paiement. Le RFC explique qu'il est normal qu'une DNSBL fasse payer ses clients pour y accéder (la définition d'une DNSBL commerciale, après tout). Mais faire payer les administrateurs système, responsables des adresses listées, est, comme le dit le RFC avec euphémisme « proche du racket ». Pour convaincre les administrateurs de listes noires que cette pratique devrait être abandonnée, le RFC note que, même lorsqu'elle est faite avec les meilleures intentions du monde, elle est susceptible de déclencher des réactions négatives, et de mettre en péril le principe même des DNSBL.
Les points traités dans la section 2 étaients de nature plutôt
politique. La section 3 touche plutôt aux questions
techniques. Quelles sont les bonnes pratiques opérationnelles ? Il y
en a plusieurs, par exemple l'importance de disposer d'un ensemble de
serveurs de noms suffisant pour faire face à la charge. Il s'agit non
seulement de la charge normale, mais également de celle, bien plus
élevée, qui surviendra lors d'une dDoS (les
spammeurs n'ont pas le sens de l'humour et les attaques par déni de
service contre les listes noires ne sont pas rares). Pour être sûr que
le nom de domaine « principal » de l'opérateur (mettons
spamhaus.org
) soit à l'écart des problèmes, le
RFC conseille que la DNSBL soit dans un sous-domaine délégué, avec ses
propres serveurs de noms :
% dig NS sbl-xbl.spamhaus.org ; <<>> DiG 9.7.3 <<>> NS sbl-xbl.spamhaus.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16914 ;; flags: qr rd ra; QUERY: 1, ANSWER: 21, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;sbl-xbl.spamhaus.org. IN NS ;; ANSWER SECTION: sbl-xbl.spamhaus.org. 86400 IN NS b.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS 5.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS 0.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS k.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS d.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS o.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS x.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS h.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS l.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS 2.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS 4.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS i.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS 3.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS r.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS f.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS g.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS t.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS 8.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS q.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS 1.ns.spamhaus.org. sbl-xbl.spamhaus.org. 86400 IN NS c.ns.spamhaus.org. ;; Query time: 341 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sat Dec 17 17:40:40 2011 ;; MSG SIZE rcvd: 388
Un des problèmes récurrents avec les DNSBL est que la plupart des
administrateurs système ne testent jamais si leur configuration est
toujours bonne, et lorsqu'une DNSBL cesse son activité, elle continue
à être interrogée. Pour éviter cela, certaines DNSBL en fin de vie ont
choisi la solution radicale de lister la totalité de l'Internet. À
chaque adresse, elles répondaient qu'elle était listée. Pour détecter
rapidement ce genre de problèmes, le RFC rappelle qu'on peut tester
127.0.0.1
. Cette adresse ne devrait jamais
apparaître dans une DNSBL. Si elle le fait, c'est que la liste a un
gros problème et ne devrait plus être utilisée. Si la liste comprend
des noms de domaines et pas des adresses IP, c'est le domaine
invalid
qui joue ce rôle. (Le RFC 5782 donne des détails sur ces conventions. D'autres
domaines réservés par le RFC 2606 peuvent être
utiles comme test
.)
Néanmoins, la première responsabilité est celle du gérant de la liste : s'il arrête le service, il doit le faire proprement (prévenir sur son site Web au moins un mois à l'avance, etc) et surtout pas en se mettant soudain à lister tout l'Internet dans sa base. Il est important de garder le nom de domaine actif : si celui-ci était libéré, un méchant pourrait l'enregistrer et monter une fausse liste noire, qui serait utilisée par tous les clients distraits qui ont oublié de changer leur configuration.
Du point de vue technique, la méthode recommandée est de changer les serveurs de noms de la zone où se trouve la liste pour des adresses IP qui ne peuvent pas exister, par exemple celles réservées pour la documentation (RFC 5735). Ainsi, on est sûr que le domaine ne marchera pas et qu'aucun enregistrement ne sera retourné, montrant bien aux clients que la liste n'est plus en service. Par exemple, avec la syntaxe standard des fichiers de zone DNS :
dnsbl.example.com. 604800 IN NS u1.example.com. 604800 IN NS u2.example.com. u1.example.com. 604800 IN A 192.0.2.1 u2.example.com. 604800 IN A 192.0.2.2
Le RFC a aussi des recommandations opérationnelles à faire pour le cas spécifiques des DNSBL qui listent les adresses IP de machines présentant une certaine vulnérabilité (relais SMTP ou HTTP ouverts, par exemple), détectée par un programme. D'abord, le programme ne devrait pas tester des machines préventivement (la question est controversée : certains défendent la légitimité de balayages systématiques de tout l'Internet, d'autres ne sont pas d'accord). Il ne devrait le faire que si quelque chose (un rapport d'envoi de spam, par exemple) attire l'attention sur des machines spécifiques.
Ensuite, une fois une adresse listée, les tests périodiques qui visent à évaluer si la machine est toujours vulnérable devraient être relativement espacés (pas plus d'une fois par jour). Et, bien sûr, le test ne doit pas avoir d'effet négatif (pas d'envoi de grandes quantités de données, par exemple).
Les logiciels qui sont derrière la DNSBL, comme tous les logiciels, ont des bogues. Et les utilisateurs d'une DNSBL peuvent faire des erreurs de configuration. Il est donc important que tout soit vérifié et testé et que des procédures soient en place pour faire face aux problèmes (par exemple, le gérant de la DNSBL doit être prêt à vider manuellement la base ou une partie de celle-ci, si une erreur entraîne le listage erronée d'adresses IP).
À noter que le Wikipédia anglophone a un intéressant tableau de comparaison des DNSBL.
Pour résumer, on a vu que ce RFC résultait d'un compromis entre ceux qui voulaient des listes noires opérant comme elles le voulaient et ceux qui souhaitaient les rendre un peu plus responsables. Le compromis a été de donner peu de recommandations concrètes excepté de documenter les choix effectués. À l'heure actuelle, le moins qu'on puisse dire est que la plupart des listes noires ne font même pas ce minimum...
Date de publication du RFC : Février 2012
Auteur(s) du RFC : A. Melnikov (Isode), B. Leiba (Huawei), K. Li (Huawei)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sieve
Première rédaction de cet article le 3 mars 2012
Je vais peut-être décevoir certains lecteurs mais, dans cet article, je ne parlerai pas du contenu du RFC mais uniquement du scandale de brevets qui l'a accompagné. En violation des règles de l'IETF, Huawei avait dissimulé l'existence d'un brevet que cette compagnie détenait sur le sujet de ce RFC.
Techniquement, ce RFC est simple : c'est une extension au langage de filtrage de courrier Sieve (RFC 5228) pour notifier des destinataires de l'arrivée d'un message, en utilisant le protocole SIP (RFC 3261). Comme les organismes de dépôt des brevets acceptent tout et n'importe quoi, on peut breveter une idée aussi simple... (Le brevet ne semble pas avoir encore été publié mais nul doute qu'il ne le sera : je n'ai pas trouvé de serveur permettant de lire les brevets chinois comme ce CN 200710076523.4 mais une version états-unienne existe aussi, le US Patent 20090204681.)
Le problème n'est pas que la technologie soit brevetée. Les règles de l'IETF ne l'interdisent pas. Le problème est que Huawei a dissimulé ce brevet, pour être sûr que le RFC soit adopté malgré cette menace (c'est ce qu'on nomme un brevet sous-marin). Et cette dissimulation, elle, est interdite par l'IETF (RFC 8179). Mais les entreprises capitalistes n'ont manifestement pas peur des règles de l'IETF, celle-ci n'ayant pas de dents pour mordre les contrevenants...
Laissons Adam Roach résumer ce qui s'est passé (message envoyé à la liste de diffusion générale de l'IETF) : Just to make sure I understand the sequence of events:
La publication du 14 décembre 2011 à laquelle il fait allusion est la #1658. Une version plus récente est la #1681.
Le 25 janvier 2012, l'IESG a relancé l'IETF (Second Last Call, un terme bien orwellien) pour demander un avis sur la publication du RFC, malgré la divulgation du brevet sous-marin. Suite à cela, le RFC a été publié. L'IETF n'avait aucun moyen de représailles, à part refuser le RFC (qui ne posait aucun problème technique).
Aucune sanction n'a été prise, l'IETF n'avait pas de mécanisme évident pour cela. Une discussion a commencé, qui a mené à la publication de deux RFC, un répressif, le RFC 6701 (qui liste des sanctions, de l'annonce publique de la tricherie, méthode du name and shame, jusqu'au retrait des Internet-Drafts des mains des tricheurs, en passant par la suspension de leur droit d'écriture dans les listes IETF, selon les principes du RFC 2418 et surtout du RFC 3683), et un préventif, le RFC 6702.
À noter que Huawei n'est pas la première société à agir ainsi, RIM en avait fait autant.
Date de publication du RFC : Janvier 2012
Auteur(s) du RFC : A. Cooper (Center for Democracy and Technology)
Pour information
Première rédaction de cet article le 17 janvier 2012
Après une très longue période d'ignorance quasi-complète des problèmes de protection de la vie privée, l'IETF a évolué et on n'entend plus gère ses participants écarter d'un revers de main ces questions, en disant « Nous, on fait juste de la technique, tout ça, c'est de la politique, ça ne nous concerne pas. » De nos jours, au contraire, la prise de conscience est nette et l'IETF a désormais une activité structurée autour de la notion de vie privée, activité qui se traduit par un programme dédié et une liste de diffusion. Faut-il aller plus loin ? C'était une des questions posées lors de l'Atelier « Internet Privacy Workshop 2010 », atelier qui s'est tenu du 8 au 9 décembre 2010 à Cambridge et dont ce RFC est le compte-rendu. (L'auteure travaille pour une ONG qui lutte pour les libertés sur l'Internet.)
Pas de décisions à attendre tout de suite, donc. On en est à un stade d'exploration. L'atelier de Cambridge était coorganisé par l'IETF, le MIT et le W3C pour voir ce que les SDO pouvaient faire en terme de protection de la vie privée. On est loin d'un accord unanime (et le résumé du RFC dit bien qu'aucun des organismes présents n'a de position officielle sur ces questions) mais au moins quelques pistes de travail émergent. L'IETF étant chargé de produire des spécifications concrètes, une bonne partie de l'atelier a porté, non pas sur des discours généraux sur la vie privée, mais sur les tâches envisageables.
La question de la protection de la vie privée sur l'Internet est immense et couvre beaucoup de domaines très différents. Certains problèmes apparaissent de manière récurrente, le fingerprinting (la détermination d'une identité à partir de traces numériques qui n'étaient a priori pas conçues pour cela), la fuite d'informations, la difficulté à distinguer les partenaires primaires (à qui on a donné directement de l'information) des tiers (qui ont eu de l'information sans qu'on interagisse explicitement avec eux), le manque d'informations des utilisateurs sur les avantages et inconvénients d'une meilleure protection, etc. (Notons que le RFC mentionne les faiblesses des utilisateurs, mais pas l'aggressivité avec laquelle les capitalistes collectent et revendent de l'information privée.) Le RFC note que la vie privée n'est pas un absolu et que, par exemple, la protéger peut influer négativement sur l'utilisabilité d'un service. Bref, il y a pour l'instant davantage de défis que de solutions (section 1).
Plus précisement, de quoi a-t-on parlé pendant l'atelier (les supports présentés sont disponibles en ligne) ? La section 2 résume tout cela. D'abord, une discussion technique (section 2.1). Commençons par l'adresse IP. Elle donne souvent bien trop d'informations (il est trivial de remonter d'une adresse IP à un utilisateur, ce qui explique pourquoi elle est considérée comme une donnée personnelle). Certains protocoles offrent des risques particuliers comme certaines techniques de mobilité, qui permettent de suivre un utilisateur à la trace.
C'est d'ailleurs dans le cas de l'adresse IP qu'on trouve un des rares exemples d'une technologie IETF spécialement développée pour répondre à des craintes concernant la vie privée : les adresses IP temporaires du RFC 4941, qui sont partiellement aléatoires, et regénérées de temps en temps, pour éviter le suivi de l'utilisateur.
Autre mécanisme bien connu pour empêcher le suivi par l'adresse IP : le routage en oignon, surtout connu grâce à Tor. Ce service route les paquets à travers plusieurs nœuds distincts, chiffrant leur contenu à chaque fois. Seuls les premiers et derniers nœuds voient le message en clair. Observer le trafic ne permet de trouver, au pire, que l'origine (si on espionne au début), ou bien que la destination (si on espionne à la fin).
Mais Tor n'est pas parfait : le contenu des messages peut donner des indications sur l'origine (cookies, par exemple, pour une requête HTTP). Si on veut vraiment être anonyme, utiliser Tor ne suffit pas : il faut aussi couper bien des choses sur son navigateur, à commencer par Flash et JavaScript, et certains peuvent considérer cela comme un problème. Comme souvent en sécurité, rien n'est gratuit. Protéger sa vie privée peut nécessiter des sacrifices.
Les participants à l'atelier ont également planché sur le mode private browsing qu'offrent certains navigateurs. C'est un mode dans lequel le navigateur ne stocke pas localement les identifiants de session (comme les cookies). Son but n'est pas de protéger contre un suivi de l'utilisateur par le serveur mais de protéger contre d'autres utilisateurs du même poste client. L'expérience indique que beaucoup d'utilisateurs ne comprennent pas la différence et croient que le private browsing leur procure une navigation sans flicage. C'est un exemple d'un autre problème courant en sécurité : les utilisateurs ne comprennent pas les risques.
Enfin, dernière discussion technique, sur les propositions Do Not Track, qui permettent à un utilisateur d'indiquer clairement aux sites Web qu'il ne veut pas être suivi à la trace. Pour l'instant, ce ne sont que des propositions, sans accord technique ou politique.
Après ces discussions techniques, l'atelier s'est demandé quel
pouvait être le rôle des SDO dans cette
histoire. Dans le passé, il n'y a pas eu d'appproche systématique de
la vie privée dans les protocoles IETF. Cela ne veut pas dire que rien
n'a été fait : certains RFC ont été entièrement conçus pour résoudre
un problème de vie privée (comme le RFC 4941
pour IPv6 ou le RFC 3323 pour
SIP). Certains services particulièrement
sensibles ont bénéficié de davantage d'efforts, par exemple
l'indication de présence (RFC 2778) ou bien sûr
la géolocalisation (RFC 3693). Un protocole
comme ALTO (RFC 5693) a
également vu ses problèmes de vie privée étudiés dès le début. Le cas
d'ALTO est difficile car le protocole est d'autant plus efficace que
l'utilisateur révèle beaucoup de choses sur lui (en demandant à
l'oracle « Je veux télécharger
le fichier Serge Reggiani - Les Loups Sont Entrés
Dans Paris.mp3
de taille 4732679 octets et de
MD5
2d79e0d7e25c8c10c9879cefcef4102a
et voici la
liste complète des pairs BitTorrent qui l'ont »
par rapport au plus discret mais moins efficace
« je voudrais savoir si le pair 2001:db8:1::1
est
plus ou moins rapide que le
2001:db8:67e::34a:1ff3
»).
La protection de la vie privée a pas mal de rapports avec la sécurité (la section 8 discute du rapprochement de ces deux concepts) et la sécurité est un bon exemple d'une préoccupation transverse (elle affecte tous les protocoles) qui était largement ignorée au début de l'IETF et a vu son rôle de plus en plus pris en compte. L'IETF a ainsi bâti une culture de la sécurité. Ainsi, depuis le RFC 1543, tous les RFC doivent inclure une section Security Considerations pour exposer l'analyse sécurité du protocole. Elle peut être vide mais elle doit être présente avec une mention expliquant pourquoi les auteurs du RFC ont consciemment laissé la section vide. Cette obligation bureaucratique n'est évidemment pas suffisante et l'IETF a ajouté une direction de la sécurité, un RFC dédié pour guider les auteurs de RFC (RFC 3552), de nombreux tutoriels pour auteurs de RFC aux réunions physiques, etc. La même méthode peut-elle être appliquée à la vie privée ? (Le RFC 2828, qui rassemble la terminologie IETF sur la sécurité, contient des termes liés à la protection de la vie privée.)
Le W3C a également procédé à un effort semblable. Un de ses premiers grands efforts a été P3P, un mécanisme pour permettre aux sites Web d'exprimer de manière formelle leur politique de gestion des données personnelles. P3P est un langage riche, qui permet d'indiquer des politiques complexes. Mais il a été très peu adopté en pratique. Opinion personnelle : comme pour la neutralité du réseau, tout le monde prétend que l'information du consommateur résout tous les problèmes, qu'il suffit d'annoncer sa politique et que le marché choisira. Mais personne ne veut le faire réellement. P3P permettait d'exprimer les politiques de protection des données personnelles en des termes simples et non ambigus et c'était évidemment intolérable pour les e-commerçants, qui préfèrent infliger à l'utilisateur des privacy policies de vingt pages écrites en langage légal.
Après ce tour d'horizon du travail effectué et des acteurs en place, l'atelier s'est attaqué aux défis (section 3). Quels sont les grands problèmes à résoudre ?
D'abord, la trop grande facilité à identifier un utilisateur donné
par les informations que donne le logiciel qu'il utilise : adresse IP,
champs de la requête HTTP comme
User-Agent:
ou
Accept-Language:
, cookies
(RFC 6265), et plein
d'autres paramètres font qu'on peut identifier un utilisateur ou une
machine bien trop souvent. C'est ce
qu'on nomme le fingerprinting et c'est bien
démontré par le Panopticlick.
Comme dans toute réunion de geeks, les participants à l'atelier ont évidemment pris plaisir à explorer en détail des techniques de fingerprinting particulièrement rigolotes comme d'envoyer du code JavaScript qui va transmettre au serveur la liste des polices installées dans le navigateur (elle est souvent unique).
Capturés par un simple script WSGI sur le
serveur (testez-le en https://www.bortzmeyer.org/apps/env
; les variables d'environnement dont le nom commence par
HTTP_
sont les en-têtes de la requête HTTP), voici une partie de ce
qu'envoie un Firefox typique, depuis une machine
Ubuntu :
HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7 HTTP_USER_AGENT: Mozilla/5.0 (Ubuntu; X11; Linux i686; rv:8.0) Gecko/20100101 Firefox/8.0 HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 HTTP_ACCEPT_LANGUAGE: en-us,en;q=0.5 HTTP_ACCEPT_ENCODING: gzip, deflate
Cette combinaison d'options et de numéros de version est probablement unique, ou en tout cas rare sur le Web, et identifie donc assez bien une machine (sans même avoir besoin de cookie). Une telle combinaison a par exemple déjà été utilisée pour confondre un agresseur agissant pour le compte de l'industrie du divertissement.
Ces informations n'étaient pas prévues pour cet usage (par exemple, les adresses IP étaient prévues pour router les paquets, pas pour identifier une machine ou une personne). Mais remplacer ces informations par des mécanismes qui empêchent ou limitent le fingerprinting ne sera pas trivial. D'autant plus que pas mal de gens se sont habitués à les utiliser dans ce but et qu'il sera de plus en plus difficile de revenir en arrière. Ainsi, le fingerprinting est souvent utilisé pour détecter des fraudes, ou pour fournir du contenu adapté (et le RFC, qui est gentil et évite les sujets qui fâchent, ne cite pas les applications répressives du fingerprinting, pour identifier l'auteur d'un délit abominable, comme de partager des œuvres d'art). Il y aura probablement beaucoup de désaccords sur le compromis entre vie privée et service « amélioré » grâce au fingerprinting.
Au minimum, l'IETF et le W3C vont essayer de documenter les points qui, dans les protocoles courants (TCP, HTTP, SIP), facilitent le fingerprinting.
Un problème proche est celui de la fuite d'informations (section 3.2) : des
mécanismes conçus pour des motifs tout à fait honorables transmettent
néanmoins plus d'information qu'ils ne le devraient. Ainsi, le champ
Referer:
dans une requête HTTP permet de savoir
d'où vient un visiteur Web (ce qui est utile) mais révèle également
des choses comme les ID de session (lorsqu'ils sont mis dans l'URL), les termes de recherche
utilisés, etc. Voici un exemple vu dans le
journal de mon blog (les informations trop sensibles ont été modifiées). On voit les termes de recherche utilisés dans Google :
192.0.2.70 - - [16/Dec/2011:17:08:53 +0000] "GET /1383.html HTTP/1.0" 200 3291 "http://www.google.fr/url?sa=t&rct=j&q=aide+rfc+dns...
Le contrôle sur les données privées repose normalement sur la possibilité de distinguer les récepteurs primaires des données des tiers (section 3.3). Ainsi, si je me connecte sur SeenThis, ce site est récepteur primaire de mes données et je ne suis pas surpris qu'il récolte des informations sur moi. Il s'agissait d'un choix conscient et informé de ma part. Mais l'examen du code source de ce site montre qu'il fait appel au service Google Analytics et donc, sans l'avoir demandé, sans même le savoir, je transmets également des données à Google, un tiers qui peut alors récolter des données sans que je l'ai choisi.
Le cas ci-dessus est relativement simple. Mais dans le Web d'aujourd'hui, on trouve d'autres cas où la distinction entre destinataire primaire et tiers est moins évidente. Un utilisateur qui met un widget amusant sur une page peut le considérer comme primaire alors que le navigateur (par exemple pour retourner les cookies) le traitera comme un tiers, et l'inverse existe également.
Enfin, le dernier grand défi est celui de l'information de l'utilisateur (section 3.4). La plupart du temps, le flicage de ce dernier se fait discrètement, sans qu'il se rende compte de l'immense quantité de données qui est collectée à son insu. La seule information disponible est composée de « policy statements » écrits dans un jargon juridique délibérement confus, conçu pour protéger le patron de l'entreprise et pas pour informer l'utilisateur. Le RFC note que des informations cruciales (comme la durée de conservation des données) en sont souvent absentes. Opinion personnelle : c'est pour cela que les mécanismes du marché - l'entreprise publie sa politique et le consommateur est libre de continuer ou pas - ne fonctionnent pas et qu'il faut des lois comme la loi I&L. Le marché suppose une information parfaite et des acteurs symétriques, ce qui n'est pas du tout le cas ici.
Le problème est d'autant plus sérieux que, si le technicien se doute bien de tout ce que le site Web peut apprendre sur son visiteur, l'utilisateur ordinaire n'a souvent pas pas idée de la quantité de traces numériques qu'il laisse.
Il est donc nécessaire de travailler à une meilleure information. P3P était un bon effort dans ce sens. Mais comme c'était un langage riche, il était difficile de traduire une politique P3P de manière claire pour l'utilisateur. Les efforts actuels portent plutôt sur un nombre limité d'icônes qui pourraient devenir largement connues (un panneau « danger, ici votre vie privée est menacée »...) Un exemple est le projet Common Terms.
La section 4 étudie ensuite les défis liés au déploiement des bonnes pratiques. D'abord (section 4.1), le problème que les mesures techniques sont génériques, alors que les menaces effectives sont souvent spécifiques à un contexte donné. La vie privée n'est pas un concept binaire. Il y a d'autres stades que « complètement privé » et « public ». Mais il est très difficile de traiter cette complexité par des mesures techniques.
Par exemple, les solutions situées en couche 3 comme les adresses IP temporaires du RFC 4941 résolvent certes certains problèmes (le serveur qui reconnaît un visiteur récurrent uniquement sur son adresse) mais ne protège pas du tout contre un FAI ou un État qui essaie d'associer une adresse à un utilisateur. Selon la menace envisagée, ces adresses temporaires sont donc efficaces... ou pas du tout.
Il ne faut donc pas évaluer les solutions techniques en leur demandant de résoudre tous les problèmes possibles. Il ne serait pas raisonnable pour l'IETF d'exiger de ses protocoles qu'ils empêchent complètement toute atteinte à la vie privée. Il faut plutôt dire clairement quels sont les risques et qui (le programmeur, l'utilisateur, la loi) est chargé de les traiter.
Autre problème délicat de déploiement de solutions de protection de la vie privée : la tension entre l'utilisabilité et la protection (section 4.2). Comme souvent en matière de sécurité, il va falloir faire des choix douloureux. Les tenants du Roi Marché ont beau jeu de faire remarquer que les utilisateurs, lorsqu'ils ont le choix, vont vers les services qui violent le plus leur vie privée (Facebook, Google, etc) en échange d'applications sympas et qui brillent. La principale faiblesse de cet argument est qu'il suppose que l'utilisateur est parfaitement conscient des risques, et de ce qui peut lui arriver, ce qui est très optimiste.
Un bon exemple de ce compromis est donné par Tor. Celui-ci fournit une bonne protection mais complique et ralentit (en raison du nombre d'étapes de routage) la navigation. Résultat, il reste peu utilisé, en bonne partie parce que les utilisateurs font un calcul coût/bénéfice (peu informé, d'ailleurs) et décident que leur vie privée n'est pas assez importante pour justifier ce coût.
Avec Tor, le coût de la protection est élevé. Mais même des mesures
bien plus légères ont des coûts. Supprimer l'en-tête
Referer:
des requêtes HTTP améliore certainement
la protection. Mais certains sites Web proposent une vue différente
selon la valeur de ce champ et, en le supprimant, on se prive de ce
service. Reste à savoir qui va décider du compromis, et sur quelles informations : comment exposer
ce choix (« Do not send Referer headers ») dans une
interface utilisateur, de manière qui permette un choix raisonné ?
Alors même que l'effet de ce choix va dépendre des sites (dans la
plupart des cas, le Referer:
est inutile au
client Web.)
Ces problèmes d'utilisabilité sont cruciaux. Le RFC cite l'exemple de SIP, où un mécanisme normalisé de protection des requêtes contre l'écoute existe (RFC 3261, section 23) mais il n'est pas utilisé en pratique car trop contraignant.
Dernier obstacle au déploiement de techniques respectant davantage la vie privée, la difficulté à trouver les bonnes motivations (section 4.3). Les différents acteurs impliqués ne feront pas d'effort s'ils n'ont pas une motivation pour cela. Cela peut être la crainte du gendarme, la conviction que cela leur apportera plus de clients ou simplement le souci d'utiliser les meilleures techniques (ces trois motivations sont rarement présentes en même temps). La crainte du gendarme est discutée en section 4.3.1. Traditionnellement, beaucoup de services proposés sur l'Internet sont gratuits et la possibilité de vendre les données personnelles des utilisateurs est l'une des voies les plus évidentes pour gagner de l'argent. Comme l'illustre un dessin célèbre, « soit l'utilisateur est le client, soit il est la marchandise ». Dans un tel contexte, il n'y a pas de motivation économique à respecter la vie privée, bien au contraire. Les diverses autorités de régulation ont fini par froncer les sourcils, ce qui a mené les fournisseurs de ces services à publier de longues politiques d'utilisation des données sur leur site. Comme le note le RFC, ces politiques, écrites sans effort pédagogique, visent plutôt à protéger le fournisseur du service qu'à informer correctement et complètement l'utilisateur. Le RFC note à juste titre que ces problèmes ne se corrigeront pas tout seuls et qu'une approche régulatrice est nécessaire (cf. le rapport de la FTC de 2010 sur l'importance d'avoir des politiques publiques mieux écrites).
Le RFC soutient que cette tendance doit continuer : sans forte pression des régulateurs, de la loi, le patronat Internet va toujours essayer de concéder le moins de vie privée possible aux utilisateurs. Un exemple d'une telle pression est la directive européenne qui parle des cookies, indiquant qu'ils ne doivent pas être utilisés sans le consentement des utilisateurs.
Le cas de P3P, déjà cité, est un bon exemple de ce problème des motivations (section 4.3.2). L'idée de base était que les logiciels du côté du client allaient pouvoir lire et comprendre les politiques de protection de la vie privée et automatiquement réagir (par exemple en n'envoyant pas de cookies aux sites dont la politique était trop peu protectrice de la vie privée). C'est une idée très états-unienne : les acteurs libres s'informent mutuellement de leurs pratiques et décident ensuite librement, en adultes majeurs, informés et consentants, de poursuivre ou pas la relation. Si on croit qu'il y a égalité (d'information, de moyens de traitement, de pouvoir) entre le patron de Facebook et M. Michu, utilisateur de Facebook, cela peut marcher. Sinon, on préfère l'approche européenne où certaines pratiques sont interdites, qu'il y ait ou pas consentement de la marchandise, pardon, de l'utilisateur.
Donc, P3P permettait d'automatiser ce processus d'information et de décision. Microsoft a pris une décision importante en choisissant, dans Internet Explorer 6, de n'envoyer des cookies aux tiers que si ceux-ci avaient une politique P3P. Comme n'importe quelle politique, même outrageusement prédatrice, était acceptée par Internet Explorer, la plupart des sites Web se sont pliés à cette décision et ont copié/collé la première politique P3P qu'ils trouvaient (souvent l'exemple pris sur le site du W3C). Cette expérience menée grâce à Internet Explorer (les autres auteurs de navigateurs n'ont fait aucun effort et n'ont jamais intégré P3P) a permis de mettre en évidence une limite de P3P : le site qui publie sa politique peut mentir (« Nous ne vendons pas vos données personnelles »). Aucun mécanisme légal ou autre ne l'en empêche. (Voir par exemple l'article « Token Attempt: The Misrepresentation of Website Privacy Policies through the Misuse of P3P Compact Policy Tokens ».)
Le cas illustre bien la question des motivations : pour qu'ils reçoivent des cookies d'Internet Explorer, les sites devaient publier du P3P. Alors, ils l'ont fait (motivation technique). Il n'y avait pas de pression légale ou régulatrice pour dire la vérité dans ces politiques P3P, alors ils ne l'ont pas fait (pas de motivation légale). Les clients (en partie à cause de l'absence de gestion de P3P par les navigateurs) ne donnaient pas la préférence aux sites publiant du bon P3P, alors les sites n'ont pas cherché à l'améliorer (pas de motivation commerciale).
Il sera intéressant de voir si cela marche mieux en sens inverse : pour la géolocalisation, le RFC 4119 et le RFC 6280 fonctionnent de manière opposée à P3P, en permettant aux utilisateurs d'indiquer leurs choix en matière de protection des données personnelles. Ils sont normalement plus motivés que les entreprises capitalistes pour cela.
Bien sûr, on est ici très loin des questions techniques que se posent normalement les SDO. Mais la compréhension de ces enjeux économiques et légaux est nécessaire, si on veut que les futures techniques de protection de la vie privée aient plus de succès que P3P.
Conclusion, en section 5, quel est le plan d'action pour les SDO ?
Pour l'IETF, la synthèse est que cela va être compliqué. L'IETF
normalise des protocoles dans les couches
basses, sans présupposer d'un usage particulier, alors que
les menaces pour la vie privée sont très dépendantes du contexte. Il
va donc être difficile de trouver des réponses générales, dans les
protocoles IETF. Cela ne veut pas dire qu'il ne faut rien faire. Le
travail a déjà commencé autour d'une série de recommandations pour les
auteurs de RFC (rassemblées dans le
Internet-Draft,
draft-morris-privacy-considerations
, qui a évolué depuis et a été publié en RFC 6973).
Les participants à l'atelier étaient tous d'accord sur la nécessité de poursuivre également le travail technique, par exemple sur les leçons apprises de Tor, ainsi que sur les capacités (plus fortes que prévues) de fingerprinting des protocoles existants.
Et le W3C ? Il est probablement mieux placé pour améliorer la protection de la vie privée, puisque les normes du W3C sont plus proches de l'utilisateur, et utilisées dans un contexte plus spécifique. Contrairement à l'IETF, le W3C peut se restreindre au Web.
L'annexe A résume quels sont les documents bruts disponibles pour ceux qui veulent approfondir leur connaissance des travaux de cet atelier :
Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : R. Stewart (Adara Networks), M. Tuexen (Muenster University of Applied Sciences), K. Poon (Oracle Corporation), P. Lei (Cisco Systems), V. Yasevich (HP)
Pour information
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 12 décembre 2011
Il n'y a pas de protocole qui réussit sans une API, c'est-à-dire une spécification d'une interface qui permet au programmeur d'utiliser le protocole en question. Le protocole de transport SCTP, normalisé dans le RFC 4960, n'avait pas jusqu'à présent d'API standard et les programmes ne fonctionnaient donc qu'avec une seule bibliothèque. Désormais, avec ce RFC, SCTP a des chances de voir le développement de programmes portables.
SCTP est le principal concurrent de TCP dans la catégorie « protocole de couche 4 fiable » (i.e. qui garantit l'acheminement des données, contrairement à UDP). Mais il est beaucoup moins utilisé que TCP, plus ancien, et qui a une API standard depuis longtemps, interface décrite dans la norme POSIX. Il y a aussi d'autres raisons au moindre déploiement de SCTP. Mais l'absence d'API jouait certainement un rôle : pas moyen de programmer avec SCTP sans devoir se limiter, non seulement à un système donné, mais en prime à une mise en œuvre particulière de SCTP. Les instructions d'installation devenaient donc pénibles à lire. C'est ce problème que résout notre RFC.
L'API décrite dans ce RFC est longue (le RFC fait 113 pages) donc je résume plutôt sauvagement. Elle permet d'écrire des programmes qui font la même chose qu'avec TCP, comme des programmes qui tirent profit des fonctions spécifiques de SCTP. Car la sémantique de SCTP n'est pas exactement la même que celle de TCP, le remplacement de l'un par l'autre n'est pas entièrement invisible aux applications. Les points importants de cette nouvelle API :
Ces deux styles ne sont pas compatibles dans le même programme, le programmeur devra choisir.
Notez que les efforts de conception d'une API SCTP sont anciens. Résultat, il traîne dans la nature des tutoriels, des Howto, des exemples de programme utilisant des mécanismes qui ne sont plus les mécanismes recommandés. Plusieurs éléments des API expérimentales qui ont précédé celle-ci sont repris dans ce RFC, en les notant comme dépassés et ne devant plus être utilisés pour de nouveaux programmes.
Un programme serveur typique qui utilise le style un-vers-N ressemble à :
socket(..., SOCK_SEQPACKET, IPPROTO_SCTP): /* Le type SOCK_SEQPACKET indique le style 1-vers-n. Section 3.1.1 */ bind(...); listen(...); /* Pas besoin de accept(). Les nouvelles associations sont gérées automatiquement (si le serveur le veut, il est prévenu lors des recvmsg(), évenement SCTP_ASSOC_CHANGE). Section 3.1.3 */ recvmsg(...); sendmsg(...); close(...); /* close() ferme tout. Pour ne fermer qu'une seule association, on utilise sendmsg() avec SCTP_EOF. */
pendant que le client fera plutôt :
socket(..., SOCK_SEQPACKET, IPPROTO_SCTP): sendmsg(...); recvmsg(...); close(...):
Toutes les associations du serveur seront représentées par une seule
prise et distinguées par leur identificateur d'association, de type
sctp_assoc_t
. La section 3.3 fournit les détails
pour ce cas. Par exemple, si le programme n'utilise qu'un seul tampon
par prise réseau, une association qui traîne peut bloquer toutes les
autres. Le RFC recommande d'utiliser des prises non-bloquantes.
Quant au style un-vers-un, c'est celui de TCP et il est familier à tous les programmeurs réseau. Il est présenté en section 4. L'idée est qu'une application d'aujourd'hui, qui utilise TCP, sera ainsi portée en très peu de temps.
La séquence de commandes pour le serveur est typiquement :
socket(..., SOCK_STREAM, IPPROTO_SCTP); /* Le protocole IPPROTO_SCTP est la seule différence avec TCP. */ bind(...); listen(...); accept(...); /* Ensuite, recv() et send() avec la nouvelle prise retournée par accept(). */ close(...);
Et chez le client :
socket(..., SOCK_STREAM, IPPROTO_SCTP); connect(...); /* Ensuite, recv()/recvmsg() et send()/sendmsg() */ close(...);
Voici pour le code. La section 5 présente ensuite les nouvelles
structures de données, celles qui sont spécifiques à SCTP, lorsqu'on
utilise recvmsg()
et
sendmsg()
pour des opérations de
contrôle (et pas seulement d'envoi et de récupération de données). Ces
fonctions prennent un paramètre message
de type
msghdr
(RFC 3542). On peut
s'en servir pour définir des paramètres de la connexion (options
SCTP_INIT
et SCTP_SNDINFO
),
ou obtenir des informations supplémentaires lors de la réception de
données (option SCTP_RCVINFO
, par exemple le
champ rcv_assoc_id
indiquera par quelle
association est venue le message).
Pendant la durée de vie d'une connexion SCTP, des tas d'évenements
qui n'ont pas d'équivalent dans le monde TCP peuvent se produire :
changement d'adresse IP d'un pair
(SCTP_PEER_ADDR_CHANGE
, section 6.1.2), établissement de nouvelles
associations (ou arrêt des anciennes,
cf. SCTP_ASSOC_CHANGE
, section 6.1.1), etc. La section 6 décrit
comment être informé de ces évenements. Quant aux options des prises spécifiques
à SCTP, elles sont dans la section 8. Elles s'utilisent avec
setsockopt()
et
getsockopt()
. Par exemple,
SCTP_ASSOCINFO
permet d'obtenir (ou de modifier)
les paramètres liés aux associations,
SCTP_PRIMARY_ADDR
d'obtenir l'adresse IP du pair
pour une association donnée, etc.
Le RFC contient en annexe A deux exemples d'utilisation de cette API, un pour un serveur en un-vers-N et un pour un client en un-vers-un. Pour les raisons expliquées plus haut (retard à normaliser l'API et bibliothèque non standards développées en attedant), ces exemples ne compilent pas sur une Debian ou une Ubuntu récente :
% gcc sctp-sample-client.c sctp-sample-client.c: In function 'main': sctp-sample-client.c:40:25: error: storage size of 'info' isn't known sctp-sample-client.c:97:54: error: 'SCTP_SENDV_SNDINFO' undeclared (first use in this function) sctp-sample-client.c:97:54: note: each undeclared identifier is reported only once for each function it appears in
Je n'ai pas encore trouvé de système où ces exemples compilent. Il existe en effet plusieurs mises en œuvre de SCTP mais pas de cette API. Plus exactement, les implémentations de cette API sont ultra-récentes et ne sont pas encore arrivés chez l'utilisateur. On a :
Le RFC note que des implémentations de l'API standard existent sur Linux, FreeBSD et Solaris mais leur déploiement effectif est inconnu. Elles ont apparemment déjà servi à ajouter SCTP à Firefox et Chrome.
Le livre de référence sur la programmation réseau, celui de Stevens, ne parle pas de SCTP dans les deux premières éditions. C'est à partir de la troisième édition (réalisée par d'autres, après la mort de l'auteur) que SCTP apparaît.
En attendant, la bogue echoping #1676608 risque d'attendre longtemps (d'autant plus que je n'ai plus le temps de m'occuper d'echoping).
Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : I. Fette (Google), A. Melnikov (Isode)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF hybi
Première rédaction de cet article le 12 décembre 2011
Ce nouveau protocole, WebSocket, vise à résoudre un problème embêtant pour les développeurs d'applications réseau. L'architecture de l'Internet était conçue pour que le seul point commun réellement obligatoire soit le protocole de couche 3, IP. Ce protocole est simple et fournit peu de services. Les développeurs qui voulaient des choses en plus les mettaient dans leurs applications ou, la plupart du temps, comptaient sur les protocoles de transport comme TCP. Si aucun des protocoles de transport existant ne satisfaisaient leurs besoins, ils avaient parfaitement le droit d'en inventer un autre et de le déployer sans rien demander à personne (principe dit « de bout en bout »). Ce modèle ne marche plus guère aujourd'hui. Il est devenu très difficile de faire passer un autre protocole de transport que TCP à travers les innombrables obstacles du réseau (NAT et pare-feux, notamment), et même un protocole applicatif nouveau, tournant sur un port TCP à lui, risque d'avoir le plus grand mal à passer. D'où l'idée de base de WebSocket : faire un protocole de transport au dessus de HTTP, qui va être le seul à passer à peu près partout. WebSocket est donc l'aboutissement d'un processus, qui a mené à ce que le protocole d'unification ne soit plus IP mais HTTP. Bienvenue dans l'Internet d'aujourd'hui « Tout sur le port 80 ».
WebSocket n'est toutefois pas un protocole généraliste, il est conçu pour fonctionner essentiellement dans le cadre du navigateur Web qui charge du code inconnu (typiquement en JavaScript) et qui va ensuite l'exécuter. Ce code pourra utiliser le réseau, dans une certaine limite (vers la même origine, cf. RFC 6454) mais les possibilités de communication offertes précédemment étaient limitées. WebSocket donne à ce code JavaScript (ou écrit dans d'autres langages) les possibilités d'une vraie communication réseau bidirectionnelle.
Avant, les applications s'exécutant sur le navigateur n'avaient pas
de moyen simple de faire de telles communications, équivalentes à ce
qu'on fait en TCP. Des applications comme la messagerie instantanée, le partage d'un document en cours d'édition
ou bien comme des jeux en commun souhaitaient un
modèle d'interaction plus riche que le traditionnel
GET
du client vers le serveur. Bien sûr, elles
auraient pu être extérieures au navigateur, ce qui était certainement
plus propre du point de vue architectural. Mais elles se heurtent
alors au problème de filtrage décrit plus haut. Et, dans le
navigateur, elles dépendaient de
XMLHttpRequest ou bien de <iframe>
et de
polling. Par exemple, un
code tournant sur le navigateur qui voulait simplement se mettre en
attente de donnés émises de manière asynchrone par le serveur n'avait
pas d'autres solutions que d'interroger ce dernier de temps en temps. Ce problème est
décrit en détail dans le RFC 6202. Il avait
plusieurs conséquences fâcheuses comme un surcoût en octets (tout
envoi de données nécessitait les en-têtes HTTP complets) ou comme un
modèle de programmation peu naturel.
WebSocket vise à résoudre ce problème en transformant HTTP en un protocole de transport. Il réutilise toute l'infrastructure HTTP (par exemple les relais ou bien l'authentification). Passant sur les mêmes ports 80 et 443, on espère qu'il réussira à passer partout. Comme le note un observateur, « WebSocket est un protocole totalement alambiqué pour contourner la stupidité du monde ».
Le résultat n'est donc pas parfait (rappelez-vous que HTTP n'avait pas été conçu pour cela) et le RFC note qu'on verra peut-être un jour les services de WebSocket fonctionner directement sur TCP (personnellement, j'ai des doutes, puisqu'on pourrait aussi bien dans ce cas utiliser des protocoles de transport qui fournissent les mêmes services, comme SCTP - RFC 4960).
Une petite note avant d'attaquer le RFC : si vous avez l'habitude de lire des RFC, vous noterez que celui-ci a des notations originales (section 2.1) comme d'utiliser les tirets bas pour souligner les définitions, les barres verticales pour encadrer les noms d'en-têtes ou de variables et les barres obliques pour les valeurs des variables.
La section 1.2 résume le fonctionnement du protocole (le lecteur
pressé du RFC peut d'ailleurs se contenter de la section 1, non
normative mais qui contient l'essentiel sur WebSocket). Le principe
de base est d'utiliser du HTTP normal (RFC 7230) mais le client ajoute un en-tête
Upgrade:
à une requête GET
, pour indiquer sa volonté de faire du
WebSocket :
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Origin: http://example.com Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13
Le serveur répond alors par un code 101 et en indiquant upgrade
dans
l'en-tête Connection:
et en ajoutant des en-têtes
spécifiques à WebSocket :
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= Sec-WebSocket-Protocol: chat
Bien sûr, d'autres en-têtes HTTP sont possibles comme les petits gâteaux du RFC 6265. Une fois que le client a fait sa demande, et que le serveur l'a acceptée, il existe une connexion bidirectionnelle entre ces deux acteurs et on peut faire passer les données.
Contrairement à TCP (mais comme dans SCTP), la communication n'est pas un flot d'octets sans structure ; c'est une suite de messages, chacun composé d'une ou plusieurs trames. Les trames sont typées et toutes les trames d'un même message ont le même type. Par exemple, il existe un type texte, où les trames contiennent des caractères Unicode encodés en UTF-8. Il existe évidemment un type binaire. Et il existe des trames de contrôle, conçues pour l'usage du protocole lui-même.
La section 1.3 se focalise sur la poignée de main entre
client et serveur qui lance le protocole (les détails complets étant en section 4). On l'a vu, le client doit
ajouter l'en-tête Upgrade: websocket
pour
demander au serveur de basculer en WebSocket (RFC 7230, section 6.7 ; la valeur
websocket
pour cet en-tête est enregistrée à l'IANA, cf. section 11.2, et aussi le RFC 2817, section 7.2). Le client indique également des
en-têtes spécifiques à WebSocket comme
Sec-WebSocket-Protocol:
qui permet d'indiquer un
protocole applicatif au dessus de WebSocket (chat
dans l'exemple plus haut). Ces protocoles applicatifs (section 1.9)
sont normalement enregistrés à l'IANA pour
assurer l'unicité de leurs noms. L'en-tête Origin:
du
RFC 6454 sert à indiquer quelle était l'origine de la page Web
qui a chargé le script client. Quand à
Sec-WebSocket-Key:
, son rôle est de permettre de
vérifier que la connexion était bien prévue pour être du WebSocket et
pas des jeux faits par un programme malveillant qui enverrait des
données ressemblant à du WebSocket sur le port 80, sans être passé par
la poignée de main normale. Le serveur doit combiner la valeur de
l'en-tête Sec-WebSocket-Key:
avec un
GUID (RFC 9562) fixe,
258EAFA5-E914-47DA-95CA-C5AB0DC85B11
. Il passe le résultat par
SHA-1 puis par Base64
et retourne ce résultat au client (dans un en-tête Sec-WebSocket-Accept:
), qui peut alors être sûr que c'est
bien ce serveur qui a reçu sa poignée de main. (Voir la section 1.6
sur ce point. Les en-têtes commençant par Sec
ne
peuvent pas être ajoutés via du code
XMLHttpRequest normal et, donc, un client
JavaScript ordinaire ne peut pas se comporter en client
WebSocket.)
À noter que les en-têtes spécifiques de WebSocket ont été ajoutés au registre des en-têtes.
La réponse du serveur utilise le code HTTP 101 (qui avait été prévu
de longue date par le RFC 7231, section 6.2.2), qui signifie que le serveur accepte
le changement de protocole. Tout autre code indique que le serveur
n'accepte pas WebSocket et que le client doit donc continuer en HTTP
normal. Ainsi, un serveur HTTP normal refusera l'en-tête Upgrade:
:
% telnet www.bortzmeyer.org http Trying 2605:4500:2:245b::bad:dcaf... Connected to www.bortzmeyer.org. Escape character is '^]'. GET / HTTP/1.1 Host: www.bortzmeyer.org Upgrade: websocket HTTP/1.1 400 Bad Request Date: Tue, 29 Nov 2011 21:15:34 GMT Server: Apache/2.2.16 (Debian) Vary: Accept-Encoding Content-Length: 310 Connection: close Content-Type: text/html; charset=iso-8859-1
La section 1.4, elle, décrit la fermeture de la connexion (détails en section 7). Elle se fait par l'envoi d'une trame de contrôle ad hoc. Notez que la simple fermeture de la connexion TCP sous-jacente ne suffit pas forcément : en présence d'intermédiaires, par exemple les relais, elle peut être insuffisante.
Un peu de philosophie après ces détails ? La section 1.5 décrit les concepts à la base de WebSocket. Par exemple, l'un des buts était de garder au strict minimum le nombre de bits de tramage. La structure des données que permet WebSocket est donc réduite (séparation des trames, et typage de celles-ci) et toute structuration plus sophistiquée (par exemple pour indiquer des métadonnées) doit être faite par l'application, au dessus de WebSocket.
Dans cette optique « ne pas trop en ajouter », cette section note que WebSocket ajoute à TCP uniquement :
GET
),Et c'est tout. Le reste doit être fait par les applications. Compte-tenu des contraintes spécifiques du Web, WebSocket offre donc pratiquement le même service aux applications que TCP. Sans ces contraintes Web (de sécurité, de fonctionnement à travers les middleboxes), du TCP brut suffirait.
Voila, vous connaissez maintenant l'essentiel de WebSocket. Le
reste du RFC précise les détails. La section 3 décrit les
URI WebSocket. Ils utilisent le plan
ws:
(non chiffré, port 80
par défaut) ou le wss:
(chiffré avec
TLS, port 443 par défaut). La section 11 décrit
l'enregistrement de ces plans dans le registre
IANA. Par exemple
ws://example.com/chat
est un URI WebSocket (pour la connexion donnée en exemple au début de cet article), comme ws://www.3kbo.com:9090/servers/1/status
ou wss://foobar.example/newsfeed
.
Comment fonctionne le tramage, le découpage du flot de données en
trames bien délimitées ? La section 5 le normalise avec précision. Une
trame a un type, une longueur et des données. On trouve également
quelques bits comme FIN
qui indique la dernière
trame d'un message, ou comme RSV1
,
RSV2
et RSV3
, réservés pour
de futures extensions du protocole. Une grammaire complète
est donnée en section 5.2, en utilisant ABNF
(RFC 5234. Les fanas d'ABNF noteront que cette
grammaire ne décrit pas des caractères mais des bits, ce qui
représente une utilisation originale de la norme.
Le type est nommé opcode et occupe quatre bits. Les valeurs de 0x0 à 0x7 indiquent une trame de données, les autres sont des trames de contrôle. 0x1 indique une trame de texte, 0x2 du binaire, 0x8 est une trame de contrôle signalant la fin de la connexion, 0x9 une demande d'écho (ping), 0xA une réponse (pong), etc. La sémantique des trames de contrôle figure en section 5.5. On y apprend par exemple que des échos non sollicités (pong non précédé d'un ping) sont légaux et peuvent servir à indiquer qu'une machine est toujours en vie.
On le sait, l'insécurité est une des plaies du Web, on trouve tout le temps de nouvelles manières de pirater les utilisateurs. Les problèmes viennent souvent de nouveaux services ou de nouvelles fonctions qui semblent super-cool sur le moment mais dont on découvre après qu'elles offrent plein de pièges. Il n'est donc pas étonnant que la section 10, sur la sécurité, soit longue.
D'abord, le serveur WebSocket doit se rappeler qu'il peut avoir
deux sortes de clients (section 10.1) : du code « embarqué » par
exemple du JavaScript exécuté par un navigateur
et dont l'environnement d'exécution contraint sérieusement les
possibilités. Par exemple, l'en-tête Origin:
est
mis par ce dernier, pas par le code Javascript, qui ne peut donc pas
mentir sur sa provenance. Mais un serveur WebSocket peut aussi être
appelé par un client plus capable, par exemple un programe
autonome. Celui-ci peut alors raconter ce qu'il veut. Le serveur ne
doit donc pas faire confiance (par exemple, il ne doit pas supposer
que les données sont valides : il serait très imprudent de faire
une confiance aveugle au champ Payload length,
qu'un client malveillant a pu mettre à une valeur plus élevée que la
taille de la trame, pour tenter un débordement de
tampon).
WebSocket ayant été conçu pour fonctionner au dessus de
l'infrastructure Web existante, y compris les relais, la section 10.3
décrit les risques que courent ceux-ci. Un exemple est l'envoi, par un
client malveillant, de données qui seront du WebSocket pour le serveur
mais qui sembleront un GET
normal pour le
relais. Outre le tramage, la principale protection de WebSocket contre
ce genre d'attaques est le masquage des données avec une clé contrôlée
par l'environnement d'exécution (l'interpréteur JavaScript, par
exemple), pas par l'application (section 5.3 pour en savoir plus sur
le masquage). Ainsi, un code JavaScript méchant ne pourra pas
fabriquer des chaînes de bits de son choix, que WebSocket
transmettrait aveuglément.
Un peu d'histoire et de politique, maintenant. WebSocket a une histoire compliquée. L'idée de pousser les informations du serveur vers le client (connue sous le nom de Comet) est ancienne. Le protocole WebSocket (dont l'un des buts est justement cela) a été créé par Ian Hickson (qui a aussi écrit les premiers projets de RFC mais n'apparait plus comme auteur). Le groupe de travail WHATWG a ensuite beaucoup participé. La plupart des mises en œuvre de WebSocket citent ce groupe ou bien les anciens Internet-Drafts, écrits avant la création du groupe de travail IETF HyBi en janvier 2010.
Le principe même de WebSocket a souvent été contesté. Pourquoi passer tant d'efforts à contourner les problèmes de l'Internet aujourd'hui (notamment les middleboxes abusives) plutôt qu'à les résoudre ? Un intéressant texte de justification a été écrit à ce sujet. Notez qu'il inclut des exemples de code. Le groupe HyBi a connu de vives discussions, avec menaces de scission (« À WHATWG, c'était mieux, on va quitter l'IETF si ça n'avance pas »). Un des points d'affrontement était par exemple les problèmes de sécurité (résolus par la solution du masquage). Cela s'est ensuite arrangé, début 2011.
Si vous voulez vous lancer dans la programmation d'applications WebSocket tournant dans le navigateur, regardez l'API. Aujourd'hui, on trouve des implémentations de WebSocket pour les différents serveurs (GlassFish, Jetty, Apache). Dans les environnements de développement, on trouve du WebSocket chez Django et bien d'autres. Chez les clients, Firefox l'a en théorie depuis la version 6, Chrome et Internet Explorer l'ont annoncé pour une version prochaine. Bon, en pratique, c'est compliqué, et la démo ne donne pas toujours les résultats attendus (elle me refuse mon Firefox 7 mais accepte un Chrome).
Attention si vous lisez les sources, pas mal d'implémentations ont été faites en suivant des vieilles versions de la spécification de WebSocket, antérieures à sa normalisation à l'IETF. Cela se sent par exemple dans les noms des variables utilisés. (Un terme comme « opcode » pour le type est dans le RFC mais pas toujours dans les programmes.)
En dehors du monde des navigateurs, si vous voulez programmer du WebSocket, vous avez, entre autres :
Si vous voulez jouer plutôt avec un programme client comme curl, vous avez un bon article qui explique comment faire du WebSocket avec curl.
Si vous cherchez des fichiers pcap de Websocket, on en trouve sur pcapr mais attention, la plupart concernent des mises en œuvres de versions antérieures du protocole. Mais Wireshark n'a pas l'air encore capable de décoder le framing Websocket. (Une mise en œuvre existe.)
Les autres registres IANA pour WebSocket
sont en https://www.iana.org/assignments/websocket/websocket.xml
. Il existe un site de référence
sur WebSocket.
Un exemple de service publiquement accessible et utilisant WebSocket est le service RIS Live.
Enfin, si vous voulez d'autres articles sur WebSocket, j'ai beaucoup apprécié celui de Brian Raymor.
Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : A. Barth (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF websec
Première rédaction de cet article le 12 décembre 2011
Chaque jour, plusieurs failles de sécurité sont annoncées frappant
un site Web, ou, plus rarement, un
navigateur. Ces failles proviennent souvent de
l'exécution de code, par exemple Java ou
JavaScript, téléchargé depuis un serveur qui
n'était pas digne de confiance, et exécuté avec davantage de privilèges
qu'il n'aurait fallu. Une des armes principales utilisées par la
sécurité du Web, pour essayer d'endiguer la marée de ces attaques, est
le concept d'origine. L'idée est que toute
ressource téléchargée (notamment le code) a une origine, et que cette
ressource peut ensuite accéder uniquement à ce qui a la même origine
qu'elle. Ainsi, un code JavaScript téléchargé depuis
www.example.com
aura le droit d'accéder à l'arbre
DOM de www.example.com
, ou
à ses cookies, mais pas à
ceux de manager.example.net
. Ce concept d'origine
semble
simple mais il y a plein de subtileries qui le rendent en fait très
complexe et, surtout, il n'avait jamais été défini précisément. Ce que
tente de faire ce RFC.
Pour comprendre l'importance de l'origine,
revoyons un navigateur Web en action. Imaginons
qu'il n'impose aucune limite au code (Java,
JavaScript, Silverlight,
etc) qu'il exécute. Un méchant pourrait alors mettre du
code malveillant JavaScript sur son serveur, faire de la
publicité (par exemple via le spam) pour
http://www.evil.example/scarlet-johansson-pictures/
,
et attendre les visites. Le navigateur récupérerait
l'HTML, puis le JavaScript inclus, et celui-ci
pourrait faire des choses comme lancer une DoS
par connexions HTTP répétées vers
http://www.victim.example/
. C'est pour éviter ce
genre d'attaques que tous les navigateurs ont la notion d'origine. Le
code récupéré sur le site du méchant va avoir l'origine
www.evil.example
, et le navigateur l'empêchera de
faire des requêtes HTTP vers un autre serveur que
www.evil.example
. En gros, le principe
traditionnel de sécurité est « Le contenu récupéré depuis l'origine X
peut interagir librement avec les ressources ayant cette même
origine. Le reste est interdit. » (section 1 du RFC, pour un résumé).
Mais ce principe très simple à énoncer et à comprendre dissimule pas mal de pièges. Ce RFC va donc essayer de les mettre en évidence. À noter qu'il ne fait que fournir un cadre, ce n'est pas un protocole, et il n'y a donc pas besoin de modifier les navigateurs pour obéir à ce texte. Les détails concrets du principe d'origine vont en effet dépendre du protocole utilisé et chacun (HTML, WebSockets du RFC 6455, etc) va donc devoir décliner ce principe selon ses caractéristiques propres. Par exemple, pour le futur HTML5, voici la définition.
Donc, on attaque avec la section 3, qui expose ce qu'est ce
« principe de même origine » (Same Origin
Policy). D'abord, la
confiance (section 3.1) est exprimée sous forme
d'un URI. Lorsque le serveur
www.niceguy.example
sert une page
HTML
https://www.niceguy.example/foo/bar.html
qui contient :
<script src="https://example.com/library.js"/>
Il annonce sa confiance envers l'URI
https://example.com/library.js
. Le code
JavaScript téléchargé via cet URI sera exécuté avec les privilèges de
https://www.niceguy.example/foo/bar.html
, qui a choisi de lui faire confiance.
Cette idée de « confiance par URI » peut poser des problèmes dans
certains cas. Par exemple, si on utilise le
STARTTLS
du RFC 2817, le
fait d'utiliser TLS ou pas n'apparait pas dans
l'URI et la page HTML ne peut donc pas exiger TLS. Les URI de plan
https:
n'ont pas ce défaut, l'exigence de TLS y
est explicite.
Mais il y a une question plus sérieuse : dans
https://www.niceguy.example/foo/bar.html
, quelle
est l'origine, celle dont vont dépendre les
autorisations ultérieures (section 3.2) ? Est-ce tout l'URI ? Ou bien
seulement le FQDN
www.niceguy.example
? Réponse : aucune des
deux.
Utiliser tout l'URL comme origine manquerait de souplesse. Un code
venu de http://www.niceguy.example/foo
ne
pourrait pas interagir avec du contenu récupéré en
http://www.niceguy.example/bar
. Mais n'utiliser
que le nom de domaine n'est pas génial non plus. Car cela permettrait
à du code JavaScript récupéré par
http://www.niceguy.example:8080/
de modifier un
arbre DOM de
https://www.niceguy.example/
(notez que la
seconde est sécurisée avec HTTPS ; ne se servir
que du nom de domaine comme origine permettrait à du contenu non sûr
de manipuler du contenu sûr).
Et faut-il utiliser tout le FQDN ? Cela
empêche http://portal.niceguy.example/
de jouer
avec http://manager.niceguy.example/
alors que
les deux sites sont sous la même autorité, celle de
niceguy.example
. Mais le problème est que la
détermination de cette autorité est difficile. Contrairement à ce que
croient les débutants, elle n'est pas forcément dans les deux derniers
composants du nom de domaine. Par exemple,
jones.co.uk
et smith.co.uk
ne sont pas sous la même autorité. Et, même lorsque c'est le cas, une
Université ne souhaite pas forcément que
http://students.example.edu/
(consacré aux pages
personnelles des étudiants) aient des droits sur
http://admin.example.edu/
. Bien sûr, aucun
système n'est parfait. Avec le FQDN,
http://example.edu/students/~mark
aura des droits
sur http://example.edu/grades/admin
. Mais ce
modèle fondé sur le FQDN est maintenant trop ancien pour le changer
(rappelez-vous qu'il a évolué informellement, notre RFC 6454 ne fait que le documenter a posteriori).
Donc, pour résumer le point important de la section 3.2 : une
origine est un tuple {FQDN, plan, port}. Par exemple,
http://example.com/
,
http://example.com:80
et
http://example.com/toto.html
ont tous les trois la même origine,
le tuple {example.com
, http
,
80}. En revanche, http://example.com:81/
a une
autre origine (port différent), de même que
ftp://example.com
(plan différent), ou
http://www.example.com/
(nom différent).
Ce principe de même origine ne répond pas à tous les risques de
sécurité. Il faut également intégrer la notion d'autorité (tel que ce
terme est utilisé en sécurité, notez que le RFC 3986 utilise ce mot dans un autre sens). L'autorité est
que le navigateur donne des droits différents selon le type de document. Une
image n'a aucun droit, c'est du contenu passif (du moins pour les formats traditionnels : avec des formats comme SVG, l'analyse de sécurité est bien plus complexe). En revanche, un
document HTML a le droit de déclencher le
chargement d'autres ressources (styles CSS mais
surtout code actif, par exemple JavaScript). Normalement, l'autorité
dépend du type MIME indiqué
(image/png
pour une image,
text/html
pour l'HTML). Si ce type est déterminé
par un utilisateur, de nouvelles vulnérabilités peuvent
survenir (et certains navigateurs sont assez imprudents pour deviner
le type MIME en examinant le contenu, une mauvaise pratique, connue
sous le nom de content sniffing). Pire, si l'utilisateur peut insérer du contenu qu'il choisit
dans des documents ayant une forte autorité (pages HTML), de nouveaux
risques peuvent survenir. Par exemple, une attaque
XSS débute par l'insertion de contenu dans une
page HTML, contenu qui sera ensuite interprété par le navigateur, et
exécuté avec l'origine de la page Web (cf. section 8.3). Or, ce cas est très fréquent
(pensez à un moteur de recherche qui affiche la requête originale sans
précaution, alorss qu'elle était choisie par un utilisateur
extérieur). La protection contre les XSS est complexe mais le conseil
de base est : modifiez tout contenu venu de l'extérieur avant de
l'inclure dans un document ayant de l'autorité (comme une page HTML),
de façon à ce qu'il ne puisse pas être interprété par le
navigateur. Le plus simple pour cela est d'utiliser exclusivement un
système de gabarit pour fabriquer les pages. Il
se chargera alors des précautions comme de transformer
les < en <.
Une fois déterminée l'origine, il reste à décider des privilèges donnés aux objets de la même origine (section 3.4). Pour les objets récupérés, on l'a vu, la politique est typiquement de ne donner accès qu'aux objets de même origine que le code. Mais pour les accès à d'autres objets, tout est bien plus complexe et la sécurité rentre ici en conflit avec l'utilisabilité. Par exemple, une application stricte du principe de même origine aux accès aux ressources interdirait à une page Web de mener à une autre page, d'origine différente, alors que c'est évidemment une fonction essentielle du Web. Moins caricatural, le cas d'images ou autres contenus embarqués dans une page Web. Bien que cela pose des problèmes de sécurité (pensez aux Web bugs), aucun navigateur n'impose que les images aient la même origine que la page qui les charge... De même, aucun navigateur n'interdit complètement d'envoyer des données à une autre origine, même si c'est la base de nombreuses CSRF.
Voilà, l'essentiel des principes du RFC tient dans cette section
3. Le reste, ce sont les détails pratiques. La section 4 formalise la
notion d'origine en en donnant une définition rigoureuse. Elle couvre
des cas rigolos comme les URI de plan file:
(autrefois, les navigateurs considéraient tous les fichiers locaux
comme ayant la même origine, aujourd'hui, les plus paranoïaques font
de chaque fichier une origine différente), ou bien explicite le cas
des ports par défaut de certains plans (vous avez remarqué
l'équivalence entre les URI http://example.com/
,
http://example.com:80
, plus haut ?). La section 5
décrit d'autres pièges comme le cas des plans où n'apparaissent pas de
noms de machine comme par exemple les data:
du RFC 2397 (un cas amusant car
deux URI data:
complètement identiques, bit par
bit, sont quand même d'origine différente). Et la section 6 explique
la sérialisation d'un URI, à des fins de comparaison simples avec
d'autres URI, pour déterminer s'ils ont la même origine. Par exemple,
http://www.example.com:80/
et
http://www.example.com/toto
se sérialisent tous
les deux en http://www.example.com
. Pour les URI
de type {scheme, host,
port} (les plus fréquents), une simple
comparaison de chaînes de caractères nous dira ensuite s'ils ont la
même origine (ici, oui).
Si on revient au premier exemple JavaScript que j'ai donné, celui
où https://www.niceguy.example/foo/bar.html
charge https://example.com/library.js
, on voit
que l'origine n'est pas l'URI du script mais celle de la page qui le
charge. Or, on peut imaginer que le serveur
example.com
voudrait bien connaître cette
origine, par exemple pour appliquer des règles différentes. ou tout
simplement pour informer le script du contexte dans lequel il va s'exécuter. C'est le rôle de l'en-tête
HTTP Origin:
, normalisé
dans la section 7, et qui peut être ajouté aux requêtes. Ainsi, dans
l'exemple ci-dessus, la requête HTTP ressemblerait à :
[Connexion à exemple.com...] GET /library.js HTTP/1.1 Host: example.com Origin: https://www.niceguy.example ...
On voit que l'origine indiquée est la forme sérialisée comme indiqué
plus haut. Ce n'est donc pas l'équivalent de
Referer:
qui indique un URI complet.
Cet en-tête est désormais dans le registre des en-têtes (cf. section 9).
Comme tout ce RFC décrit un mécanisme de sécurité, il est prudent de bien lire la section 8, Security Considerations, qui prend de la hauteur et rappelle les limites de ce mécanisme. Historiquement, d'autres modèles que le « principe de même origine » ont été utilisés (à noter que le RFC ne fournit pas de référence), comme le taint tracking ou l'exfiltration prevention mais pas avec le même succès.
D'abord, la notion d'origine est une notion unique qui s'applique à des problèmes très différents et peut donc ne pas être optimisée pour tous les cas.
Ensuite, elle dépend du DNS (section 8.1)
puisque la plupart des plans d'URI utilisent la notion
d'host et que la politique de même origine considère que deux serveurs sont les mêmes s'ils ont le
même nom. Si l'attaquant contrôle le DNS, plus aucune sécurité n'est
possible (on croit parler au vrai www.example.com
et on
parle en fait à une autre machine).
À noter que le RFC prend bien soin de ne pas parler de la principale vulnérabilité de ce concept d'host : l'absence de notion générale d'identité d'une machine dans l'Internet (cette notion n'existe que pour certains protocoles spécifiques comme SSH). En l'absence d'une telle notion, des attaques sont possibles sans que l'attaquant ait eu à compromettre le DNS, comme par exemple le changement d'adresse IP.
Autre piège, le fait que le principe de même origine, ne soit pas
apparu tout de suite et que certaines techniques de sécurité du Web
utilisent une autre unité d'isolation que l'origine (section
8.2). Le Web n'a pas en effet de sécurité cohérente. C'est le cas des
cookies (RFC 6265), qui se servent d'un autre concept, le « domaine
enregistré ». Le navigateur essaie de trouver, lorsqu'il récupère un
cookie, à quel « domaine enregistré » il appartient
(l'idée étant que sales.example.com
et
it.example.com
appartiennent au même domaine
enregistré, alors qu'ils n'ont pas la même origine). Il enverra
ensuite le cookie lors des connexions au même
domaine enregistré. Pour déterminer ce domaine, notez que les
cookies ne font pas de différence entre HTTP et
HTTPS (sauf utilisation de l'attribut Secure
) et
qu'un cookie acquis de manière sûre peut donc être
envoyé par un canal non sûr.
Notre RFC note que cette pratique d'utiliser le « domaine enregistré » est mauvaise et la déconseille. En effet :
a.co.jp
et b.co.jp
sont deux
domaines enregistrés différents. Il existe des listes publiques de
politiques d'enregistrement comme http://publicsuffix.org/
mais aucune n'est officielle et aucune
n'est à jour.Autre faiblesse du principe de même origine, l'autorité diffuse (section 8.3). L'autorité va dépendre de l'URI, pas du contenu. Or, un URI de confiance peut inclure du contenu qui ne l'est pas (pour le cas, fréquent, où une page Web inclut du contenu généré par l'utiisateur) et c'est alors un risque de XSS.
Résultat, le principe de même origine ne suffit pas à lui seul à protéger l'utilisateur (plusieurs attaques ont déjà été documentées.) Il faut donc ajouter d'autres pratiques de sécurité.
Notez que la question des mises en œuvre de ce RFC ne se pose pas, il a été réalisé après le déploiement du concept de même origine et tous les navigateurs Web utilisent aujourd'hui ce système. Toutefois, certains ne le font peut-être pas encore absolument comme décrit ici, par exemple en accordant au plan ou au port moins de poids qu'au host (il semble que cela ait été le cas de certaines versions d'Internet Explorer).
Une autre bonne lecture sur ce concept d'origine est l'article de Google pour les développeurs.
Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : P. Faltstrom (Cisco), P. Hoffman (VPN Consortium)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 13 novembre 2011
Une des exigences de la norme sur les IDN
(RFC 5890) est la stabilité : si un caractère est autorisé dans les
noms de domaine à un
moment donné, il devrait l'être pour toujours, sous peine qu'une
épée de Damoclès pèse sur les titulaires de
noms, la crainte qu'un nom qu'ils utilisent devienne subitement
invalide. Mais le mécanisme par lequel sont déterminés les caractères
autorisés ou interdits rend inévitable de tels problèmes, heureusement
dans des cas rares et marginaux. C'est ce qui vient de se produire
avec la sortie de la norme Unicode version 6 : le caractère ᧚ (U+19DA
),
autrefois autorisé, est désormais interdit. S'il y avait eu des noms
de domaine l'utilisant (ce n'était apparemment pas le cas), ils
deviendraient subitement illégaux.
Vu que ce caractère est très rare, toute cette discussion n'est-elle pas une tempête dans un verre d'eau ? Pas complètement, parce que c'est la première fois que le problème se pose depuis la sortie de la version 2 de la norme IDN, et que la façon dont ce cas a été traité va servir de modèle pour des futurs problèmes qui pourraient être plus délicats.
Reprenons dès le début : dans la norme actuelle sur les IDN, dite « IDNAbis » (RFC 5890), les caractères Unicode peuvent être valides ou invalides dans un nom de domaine. Cette validité (qui était déterminée manuellement dans la première version d'IDN) découle d'un algorithme, normalisé dans le RFC 5892, qui prend en compte les propriétés que la norme Unicode attache à un caractère. Par exemple, si le caractère a la propriété « Est une lettre », il est valide. Ce système a l'avantage de remédier au principal inconvénient d'IDN version 1, le fait que le premier IDN était lié à une version particulière d'Unicode. Avec IDNAbis, au contraire, lorsque le consortium Unicode sort une nouvelle version de sa norme, il suffit de faire tourner à nouveau l'algorithme, et on a la liste des caractères valides dans cette nouvelle version.
Le problème que cela pose est que les propriétés d'un caractère
Unicode peuvent changer d'une version à l'autre. Elles ne sont pas
forcément couvertes par les engagements de stabilité du consortium
Unicode. C'est ce qui s'est produit en octobre
2010, lors de la sortie de la version 6 d'Unicode. Trois caractères ont vu leur
validité changer car leur GeneralCategory Unicode a
changé. Pour les deux premiers, rien de très grave. ೱ (U+0CF1
)
et ೲ (U+0CF2
), classés à tort comme des
symboles, ont été reclassés comme lettres et sont donc devenus
valides, alors qu'ils étaient invalides. Personne n'avait donc pu les
utiliser et le changement ne va donc pas affecter les titulaires de
noms de domaine.
Mais le troisième pose un problème épineux. Pas
quantitativement. Ce caractère ᧚ (U+19DA
),
de l'écriture Tai
Lue n'a apparemment jamais été utilisé dans un nom de
domaine, en partie par ce que l'écriture dont il fait partie est peu
répandue (et ses utilisateurs sont peu connectés à l'Internet). Mais,
qualitativement, c'est ennuyeux car U+19DA
(un
chiffre) fait le chemin inverse. D'autorisé, il devient
interdit. Potentiellement, il peut donc remettre en cause la stabilité
des noms de domaine. Si on applique aveuglément l'algorithme du RFC 5892, U+19DA
va devenir
interdit. Alors, que faire ? Le RFC 5892 (section 2.7)
prévoyait une table des exceptions, où on pouvait mettre les
caractères à qui on désirait épargner le sort commun. Fallait-il y
mettre le chiffre 1 du Tai Lue ?
La décision finalement prise, et documentée par ce RFC (décision
pompeusement baptisée « IETF consensus », bien
que la section 5 rappelle qu'elle a été vigoureusement discutée) a
finalement été de laisser s'accomplir le destin. Aucune exception n'a
été ajoutée pour ces trois caractères, l'algorithme normal s'applique
et U+19DA
ne peut donc plus être
utilisé. L'argument principal est que ce caractère n'était quasiment
pas utilisé. Les cas suivants mèneront donc peut-être à des décisions
différentes (la section 2 rappelle bien que, dans le futur, les choses
seront peut-être différentes).
Ce RFC 6452 documente donc cette décision. Bien qu'elle se résume à « ne touchons à rien », il était préférable de la noter, car un changement qui casse la compatibilité ascendante n'est pas à prendre à la légère.
Les deux autres caractères, utilisés en Kannada, ೱ (U+0CF1
)
et ೲ (U+0CF2
) ne créent pas le même
problème car ils ont changé en sens inverse (interdits autrefois, ils sont
désormais autorisés).
Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : L. Vegoda (ICANN)
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 29 novembre 2011
Dernière mise à jour le 5 janvier 2012
Pour limiter certains risques de sécurité, des opérateurs réseaux filtraient en entrée de leur réseau les adresses IP non encore allouées (dites bogons). Les adresses IPv4 étant désormais totalement épuisées, cette pratique n'a plus lieu d'être et ce RFC demande donc que ces filtres soient démantelés.
L'idée était d'empêcher l'usage de ces préfixes IP non alloués. Ils représentaient des cibles tentantes, par exemple pour un spammeur qui voulait des adresses jetables et non traçables : on trouve un bloc non alloué, on l'annonce en BGP (puisqu'il n'est pas alloué, il n'y a pas de risque de collision), on envoie son spam et on arrête l'annonce BGP (voir les articles cités à la fin). Pour éviter cela, et d'autres attaques analogues, l'habitude s'est prise de filtrer les bogons, ces préfixes non alloués. Certains opérateurs rejetaient les annonces BGP pour ces bogons, d'autres bloquaient sur le pare-feu les paquets ayant une adresse source dans ces préfixes non alloués. Ces pratiques étaient largement documentées par exemple sur le site de référence sur les bogons.
Cette pratique a toujours posé des problèmes, notamment celui de la « débogonisation ». Lorsqu'un préfixe qui n'était pas alloué le devient, il faut toute une gymnastique pour le retirer des filtres existants, sachant que beaucoup de ces filtres ne sont que rarement mis à jour. On voit ainsi des messages sur les listes de diffusion d'opérateurs réseaux avertissant de l'arrivée prochaine d'un nouveau préfixe et demandant qu'il soit supprimé des filtres. Voici deux exemples de ces annonces en 2004 et en 2005. Pour permettre aux opérateurs de tester que tout va bien après cette suppression, les RIR mettent souvent un beacon, un amer, dans le préfixe, une adresse IP qu'on peut pinguer pour tester, comme le recommande le RFC 5943. Tout ce travail faisait donc que la chasse aux bogons était contestée depuis longtemps.
À noter (section 2) que le terme de bogon a été défini dans le RFC 3871, qui recommande leur blocage. Ce même RFC 3871 décrit en détail le problème que posent les bogons et la raison de leur éradication. Le terme de martien, plus flou (il vient du RFC 1208), est appliqué à toutes sortes de paquets dont l'adresse source est anormale (dans le DNS, il a un autre sens, celui de paquet de réponse à une question qui n'a pas été posée).
La section 3 représente le cœur du RFC : elle formule la nouvelle règle. Celle-ci, tenant compte de l'épuisement des adresses IPv4 est simple : tous les préfixes IPv4 sont désormais alloués ou réservés. Il ne faut donc filtrer que les réservés. Les autres peuvent désormais tous être une source légitime de trafic IP. La chasse aux bogons et les difficultés de la débogonisation faisant partie du folklore de l'Internet depuis très longtemps, c'est donc une page d'histoire qui se tourne. (Les adresses IPv6 sont, elles, loin d'être toutes allouées et ne sont donc pas concernées.)
La section 4 rappelle que l'autorité pour cette liste de préfixes réservés est le RFC 6890. On y trouve par exemple les adresses privées du RFC 1918 ou bien les adresses réservées à la documentation du RFC 5737. Les listes de bogons qu'on trouve sur le réseau, comme celle de TeamCymru sont désormais réduites à ce groupe.
À noter que l'assertion « Tous les préfixes sont désormais alloués » ne vaut que pour les préfixes de longueur 8 (les « /8 ») distribués aux RIR. Certains peuvent filtrer à un niveau plus fin, en distinguant dans ces /8 les adresses que les RIR ont affectés de celles qui ne le sont pas encore. Comme le rappelle la section 3.2, cette pratique est risquée, les affectations par les RIR changeant vite. Le RFC demande donc que, si on a de tels filtres, ils soient changés au moins une fois par jour.
Pour en apprendre plus sur les bogons, on peut
regarder la bonne
analyse faite par BGPmon. On voit finalement peu d'annonces
BGP de bogons (6 seulement
en 2011), la plupart pour le préfixe
198.18.0.0/15
des mesures de performance (RFC 5735). Un bon résumé des
bogons et de la débogonisation avait été fait par
Dave Deitrich en 2005.
Quelques articles sur les trucs utilisés par des méchants (spammeurs, par exemple), en connexion avec les bogons :
Date de publication du RFC : Décembre 2011
Auteur(s) du RFC : E. Jankiewicz (SRI International), J. Loughney (Nokia), T. Narten (IBM Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 22 décembre 2011
Il existe des tas de RFC qui concernent IPv6 et le programmeur qui met en œuvre ce protocole dans une machine risque fort d'en rater certains, ou bien d'implémenter certains qu'il aurait pu éviter. Ce RFC était donc un méta-RFC, chargé de dresser la liste de ce qui est indispensable dans une machine IPv6. Il a été remplacé depuis par le RFC 8504. Les deux points les plus chauds concernaient la configuration (par DHCP ou par RA - Router Advertisment ?) et la gestion d'IPsec, désormais officiellement facultative.
Ce document remplace son prédécesseur, le RFC 4294 (et est lui-même remplacé par le RFC 8504. Il vise le même but, servir de carte au développeur qui veut doter un système de capacités IPv6 et qui se demande s'il doit vraiment tout faire (réponse : non). Ce RFC explique clairement quels sont les points d'IPv6 qu'on ne peut pas négliger, sous peine de ne pas pouvoir interagir avec les autres machines IPv6. Le reste est laissé à l'appréciation du développeur. La section 2 résume ce but.
Les deux gros changements par rapport au RFC 4294 sont :
Ce RFC s'applique à tous les nœuds IPv6, aussi bien les routeurs (ceux qui transmettent des paquets IPv6 reçus qui ne leur étaient pas destinés) que les machines terminales (toutes les autres).
Bien, maintenant, les obligations d'une machine IPv6, dans l'ordre. D'abord, la couche 2 (section 4 du RFC). Comme IPv4, IPv6 peut tourner sur des tas de couches de liaison différentes et d'autres apparaîtront certainement dans le futur. En attendant, on en a déjà beaucoup, Ethernet (RFC 2464), 802.16 (RFC 5121), PPP (RFC 5072) et bien d'autres, sans compter les tunnels.
Ensuite, la couche 3 (section 5 du RFC) qui est évidemment le gros morceau puisque c'est la couche d'IP. Le cœur d'IPv6 est normalisé dans le RFC 2460 et ce dernier RFC doit donc être intégralement implémenté, à l'exception de l'en-tête de routage de type 0, qui a été abandonné par le RFC 5095.
Comme IPv6, contrairement à IPv4, ne permet pas aux routeurs intermédiaires de fragmenter les paquets, la découverte de la MTU du chemin est particulièrement cruciale. La mise en œuvre du RFC 1981 est donc recommandée. Seules les machines ayant des ressources très limitées (genre où tout doit tenir dans la ROM de démarrage) sont dispensées. Mais le RFC se doit de rappeler que la détection de la MTU du chemin est malheuresement peu fiable dans l'Internet actuel, en raison du grand nombre de pare-feux configurés avec les pieds et qui bloquent tout l'ICMP. Il peut être donc nécessaire de se rabattre sur les techniques du RFC 4821).
Le RFC 2460 décrit le format des paquets et leur traitement. Les adresses y sont simplement mentionnées comme des champs de 128 bits de long. Leur architecture est normalisée dans le RFC 4291, qui est obligatoire.
Également indispensable à toute machine IPv6, l'autoconfiguration sans état du RFC 4862, ainsi que ses protocoles auxiliaires comme la détection d'une adresse déjà utilisée.
ICMP (RFC 4443) est évidemment obligatoire, c'est le protocole de signalisation d'IP (une des erreurs les plus courantes des administrateurs réseaux incompétents est de bloquer ICMP sur les pare-feux).
Dernier protocole obligatoire, la sélection de l'adresse source selon les règles du RFC 3484 (depuis remplacé par le RFC 6724), pour le cas où la machine aurait le choix entre plusieurs adresses (ce qui est plus fréquent en IPv6 qu'en IPv4).
Le reste n'est en général pas absolument obligatoire mais recommandé (le terme a un sens précis dans les RFC, définie dans le RFC 2119 : ce qui est marqué d'un SHOULD doit être mis œuvre, sauf si on a une bonne raison explicite et qu'on sait exactement ce qu'on fait). Par exemple, la découverte des voisins (NDP, RFC 4861) est recommandée. Toutes les machines IPv6 en ont besoin, sauf si elles utilisent les liens ne permettant pas la diffusion.
Moins générale, la sélection d'une route par défaut s'il en existe plusieurs, telle que la normalise le RFC 4191. Elle est particulièrement importante pour les environnements SOHO (RFC 7084).
On a vu que l'autoconfiguration sans état (sans qu'un serveur doive se souvenir de qui a quelle adresse) était obligatoire. DHCP (RFC 8415), lui, n'est que recommandé.
Une extension utile (mais pas obligatoire) d'IP est celle des adresses IP temporaires du RFC 8981, permettant de résoudre certains problèmes de protection de la vie privée. Évidemment, elle n'a pas de sens pour toutes les machines (par exemple, un serveur dans son rack n'en a typiquement pas besoin). Elle est par contre recommandée pour les autres.
Encore moins d'usage général, la sécurisation des annonces de route (et des résolutions d'adresses des voisins) avec le protocole SEND (RFC 3971). Le déploiement effectif de SEND est très faible et le RFC ne peut donc pas recommander cette technique pour laquelle on n'a pas d'expérience, et qui reste simplement optionnelle.
L'une des grandes questions que se pose l'administrateur réseaux avec IPv6 a toujours été « autoconfiguration RA - Router Advertisment - ou bien DHCP ? » C'est l'un des gros points de ce RFC et la section 6 le discute en détail. Au début d'IPv6, DHCP n'existait pas encore pour IPv6 et les RA ne permettaient pas encore de transmettre des informations pourtant indispensables comme les adresses des résolveurs DNS (le RFC 6106 a résolu cela). Aujourd'hui, les deux protocoles ont à peu près des capacités équivalentes. RA a l'avantage d'être sans état, DHCP a l'avantage de permettre des options de configuration différentes par machine. Alors, quel protocole choisir ? Le problème de l'IETF est que si on en normalise deux, en laissant les administrateurs du réseau choisir, on court le risque de se trouver dans des situations où le réseau a choisi DHCP alors que la machine attend du RA ou bien le contraire. Bref, on n'aurait pas d'interopérabilité, ce qui est le but premier des normes Internet. Lorsque l'environnement est très fermé (un seul fournisseur, machines toutes choisies par l'administrateur réseaux), ce n'est pas un gros problème. Mais dans un environnement ouvert, par exemple un campus universitaire ou un hotspot Wifi, que faire ? Comme l'indiquent les sections 5.9.2 et 5.9.5, seul RA est obligatoire, DHCP ne l'est pas. RA est donc toujours la méthode recommandée si on doit n'en choisir qu'une, c'est la seule qui garantit l'interopérabilité. (Voir aussi la section 7.2 sur DHCP.)
Continuons à grimper vers les couches hautes. La section 7 est
consacrée aux questions DNS. Une machine IPv6
devrait pouvoir suivre le RFC 3596 et donc avoir
la possibilité de gérer des enregistrements DNS de type AAAA (les
adresses IPv6) et la résolution d'adresses en noms grâce à des
enregistrements PTR dans
ip6.arpa
. Les anciens enregistrements A6 (RFC 3363) ont été
abandonnés mais on constate que ces
enregistrements sont toujours très demandés lors des requêtes à des
serveurs DNS faisant autorité, comme ceux de
.fr
(dans les 0,5 % des requêtes, soit davantage que SRV ou DS).
À noter qu'une machine IPv6, aujourd'hui, a de fortes chances de se retrouver dans un environnement où il y aura une majorité du trafic en IPv4 (c'est certainement le cas si cet environnement est l'Internet). La section 8 rappelle donc qu'une machine IPv6 peut avoir intérêt à avoir également IPv4 et à déployer des techniques de transition comme la double-pile du RFC 4213.
Encore juste une étape et nous en sommes à la couche 7, à laquelle la section 9 est consacrée. Si elle parle de certains détails de présentation des adresses (RFC 5952), elle est surtout consacrée à la question des API. En 2011, on peut dire que la grande majorité des machines a IPv6, côté couche 3 (ce qui ne veut pas dire que c'est activé, ni que le réseau le route). Mais les applications sont souvent en retard et beaucoup ne peuvent tout simplement pas communiquer avec une autre machine en IPv6. L'IETF ne normalise pas traditionnellement les API donc il n'y a pas d'API recommandée ou officielle dans ce RFC, juste de l'insistance sur le fait qu'il faut fournir une API IPv6 aux applications, si on veut qu'elles utilisent cette version d'IP, et qu'il en existe déjà, dans les RFC 3493 (fonctions de base) et RFC 3542 (fonctions avancées).
La sécurité d'IPv6 a fait bouger beaucoup d'électrons, longtemps avant que le protocole ne soit suffisamment déployé pour qu'on puisse avoir des retours d'expérience. Certains ont survendu IPv6 en prétendant que, contrairement à IPv4, il avait la sécurité intégrée dès le début et était donc plus sûr. Cette légende vient du fait qu'en théorie, IPsec était obligatoire pour toute mise en œuvre d'IPv6. Ce point n'a jamais été respecté par les implémentations (et puis, de toute façon, avoir IPsec est une chose, l'activer, avec sa complexe configuration, en est une autre). Désormais, depuis la sortie de notre RFC 6434, ce point n'est même plus vrai en théorie, IPsec (RFC 4301) est officiellement simplement recommandé.
Le RFC note donc bien que la sécurité est un processus complexe, qui ne dépend certainement pas que d'une technique magique (« IPsec est intégré donc il n'y a pas de problème de sécurité ») et qu'aucun clair gagnant n'émerge de la liste des solutions de sécurité (IPsec, TLS, SSH, etc). D'autant plus qu'IPv6 vise à être déployé dans des contextes comme « l'Internet des Trucs » où beaucoup de machines n'auront pas forcément les ressources nécessaires pour faire de l'IPsec.
Toutes les règles et recommandations précédentes étaient pour tous les nœuds IPv6. La section 12 expose les règles spécifiques aux routeurs. Ils doivent être capables d'envoyer les Router Advertisment et de répondre aux Router Solicitation du RFC 4861 et on suggère aux routeurs SOHO d'envisager sérieusement d'inclure un serveur DHCP (RFC 7084) et aux routeurs de réseaux locaux de permettre le relayage des requêtes DHCP.
Enfin, la section 13 se penche sur la gestion des réseaux IPv6 en notant que deux MIB sont obligatoires, celle du RFC 4292 sur la table de routage, et celle du RFC 4293 sur IP en général.
Les changements par rapport au RFC 4294 sont résumés dans l'annexe 16. Les deux plus importants, comme déjà noté, sont IPsec et DHCP, un qui descend, l'autre qui monte. Mais on y trouve aussi l'arrivée de SEND (mais en option), celle des options DNS du RFC 6106, et beaucoup de détails et de clarifications. Depuis, le RFC 8504 a aussi apporté ses changements.
Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : K. Li (Huawei), B. Leiba (Huawei)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF marf
Première rédaction de cet article le 11 novembre 2011
Il existe un format standard pour la transmission de rapports d'abus entre acteurs de l'Internet qui permet, par exemple, à des opérateurs de serveurs de messagerie de signaler un spam, et de traiter automatiquement ces rapports. Ce format se nomme ARF et est normalisé dans le RFC 5965. Chaque rapport ARF indique un type d'abus et ce nouveau RFC 6430 ajoute le type not spam, qui permet d'attirer l'attention sur un message classé à tort.
Le format ARF est conçu pour de gros
opérateurs, traitant des millions de messages et d'innombrables
rapports d'abus (spam mais aussi
hameçonnage, distribution de logiciel
malveillant, etc). Avec de tels
volumes à traiter, l'automatisation est nécessaire et c'est ce que
permet ARF. Le type abuse
, documenté en section
7.3 du RFC 5965, permet de signaler un message
comme n'étant pas désiré. Mais on a parfois besoin de l'inverse, signaler
qu'un message n'est pas du spam, pour que le destinataire du rapport
ajuste ses filtres. C'est ce qu'introduit notre RFC, suite à une
demande de l'OMA (« Mobile Spam Reporting
Requirements », OMA-RD-SpamRep-V1_0 20101123-C).
Bien sûr, le destinataire du rapport est libre de l'action à entreprendre. Il peut par exemple attendre d'avoir plusieurs rapports équivalents, Si l'opérateur accepte des rapports envoyés directement par les utilisateurs (ceux-ci ne vont pas taper du ARF à la main mais ils peuvent avoir un MUA muni d'un bouton Report as non-spam qui le fait pour eux), il doit tenir compte du fait que les utilisateurs peuvent se tromper (cliquer trop vite) ou même tenter d'influencer le système (mais non, cette publicité n'est pas du spam, laissez-la passer...). La section 4 rappelle donc de traiter avec prudence ces rapports.
Les détails de syntaxe figurent en section 3 du RFC. Voici un
exemple de rapport avec le Feedback-Type:
à
not-spam
. abusedesk@example.com
signale à abuse@example.net
que le message de
someone@example.net
n'est
pas, en dépit des apparences, du spam (mettons qu'il ait été envoyé en
réponse à une sollicitation d'un médecin) :
From: <abusedesk@example.com> Date: Thu, 8 Mar 2005 17:40:36 EDT Subject: FW: Discount on pharmaceuticals To: <abuse@example.net> Message-ID: <20030712040037.46341.5F8J@example.com> 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://tools.ietf.org/html/rfc5965 Comment: I sell pharmaceuticals, so this is not spam for me. --part1_13d.2e68ed54_boundary Content-Type: message/feedback-report Feedback-Type: not-spam User-Agent: SomeGenerator/1.0 Version: 1 --part1_13d.2e68ed54_boundary Content-Type: message/rfc822 Content-Disposition: inline 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 From: <someone@example.net> To: <Undisclosed Recipients> Subject: Discount on pharmaceuticals MIME-Version: 1.0 Content-type: text/plain Message-ID: 8787KJKJ3K4J3K4J3K4J3.mail@example.net Date: Thu, 02 Sep 2004 12:31:03 -0500 Hi, Joe. I got a lead on a source for discounts on pharmaceuticals, and I thought you might be interested. [...etc...] --part1_13d.2e68ed54_boundary--
Le type not-spam
fait donc désormais partie du
registre des types de rapport ARF.
Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : M. Wasserman (Painless Security, LLC), P. Seite (France Telecom - Orange)
Pour information
Réalisé dans le cadre du groupe de travail IETF mif
Première rédaction de cet article le 22 novembre 2011
Il fut une époque où la machine terminale connectée à l'Internet n'avait typiquement qu'une seule interface réseau. Seuls les routeurs avaient plusieurs interfaces et donc des décisions difficiles à prendre comme « quelle adresse source choisir pour le paquet que je génère ? » Aujourd'hui, les machines les plus ordinaires ont souvent, à leur tour, plusieurs interfaces réseau. Mon smartphone a une interface WiFi et une 3G. Mon ordinateur portable a une interface filaire, une 3G, une Wifi et une Bluetooth. Qui dit plusieurs interfaces dit décisions à prendre. Quel serveur DNS utiliser ? Celui appris via l'interface filaire ou bien celui appris en Wifi ? Par quelle interface envoyer un paquet qui sort de la machine ? La question est d'autant plus difficile que les différentes interfaces fournissent en général des services très différents, en terme de qualité et de prix. Le groupe de travail MIF de l'IETF travaille à normaliser le comportement des machines sur ce point. Son premier RFC (un autre, le RFC 6418, concerne l'exposé du problème) commence par examiner l'état de l'art : que font aujourd'hui les divers systèmes d'exploitation confrontés à cette question ?
Le RFC ne prétend pas couvrir tous les systèmes. Il se contente de ceux que les membres du groupe de travail connaissaient, ceux sur lesquels ils avaient de la documentation et des informations : Nokia S60, Windows Mobile, Blackberry, Android, Windows, et des systèmes à base de Linux.
Comment ces systèmes gèrent cette multiplicité des interfaces
réseaux, se demande la section 2. Une première approche est de
centraliser la gestion des connexions : ce n'est pas l'application qui
choisit l'interface à utiliser, elle passe par un gestionnaire de
connexions (en lui transmettant parfois quelques souhaits) qui choisit
pour elle. Le gestionnaire peut choisir en fonction de la table de
routages (si l'application veut écrire à
172.23.1.35
et qu'une seule interface a une route
vers cette adresse, le choix est vite fait) mais elle ne suffit pas
toujours (que faire si deux interfaces sont connectées à un réseau
privé 172.23.0.0/16
?). Le gestionnaire doit aussi tenir
compte d'autres facteurs. Le coût est souvent le plus important (prix
élevés de la 3G, surtout en itinérance, par
rapport au Wifi ou au filaire, par exemple).
Une autre solution est que l'application choisisse elle-même, en fonction des informations qu'elle reçoit du système. Certaines applications ont des idées bien précises sur la connexion qu'elles veulent utiliser. Par exemple, sur Android, la plupart des clients SIP refusent par défaut d'utiliser les connexions 3G, les opérateurs y interdisant en général le trafix voix (en violation de la neutralité du réseau). Les deux méthodes (gestionnaire de connexions centralisé et choix par l'application) ne sont pas complètement exclusives. Comme indiqué, on peut aussi avoir un gestionnaire centralisé, mais qui permet aux applications d'indiquer des préférences (« essaie d'éviter la 3G »).
Certains choix sont par contre typiquement réglés par une troisième approche : le faire entièrement dans le système, sans demander à l'utilisateur ou aux applications (section 2.3). Le système rassemble des informations de sources diverses (DHCP, RA (Router Advertisment), configuration manuelle par l'administrateur système) et fait ensuite des choix qui sont globaux au système, ou bien spécifiques à chaque interface. Il n'y a aucune règle commune entre les différents systèmes d'exploitation sur ce plan, et aucun ne semble fournir une solution parfaite.
Par exemple, la configuration DNS voit certains systèmes permettre un jeu de résolveurs DNS différent par interface, avec des règles indiquant quel jeu est choisi. D'autres ont au contraire un seul jeu de résolveurs.
La sélection de l'adresse source est plus « standard
». L'application fournit l'adresse de destination et, lorsqu'elle n'a
pas choisi une adresse source explicité (option
-b
de OpenSSH, par
exemple), le système en sélectionne automatiquement une. Pour
IPv6, il existe même une norme pour cela, le
RFC 6724 (et son prédécesseur, le RFC 3484, qui est encore la référence). Un grand nombre de systèmes d'exploitation ont
adapté cette norme à IPv4 et l'utilisent donc pour toutes les familles
d'adresses. En revanche, tous ne fournissent pas forcément un mécanisme
permettant à l'administrateur système d'influencer cette sélection (le
/etc/gai.conf
sur Linux). Autre point où les
systèmes diffèrent, certains choisissent l'interface de sortie avant
l'adresse source, d'autres après.
La section 3 est ensuite l'exposé des pratiques des différents systèmes, à l'heure actuelle (une version future pourra changer leur comportement). Ainsi, le système S60 (qui tourne sur Symbian) introduit le concept d'IAP (Internet Access Point) ; un IAP rassemble toutes les informations sur une interface (physique ou virtuelle, dans le cas des tunnels). La machine a en général plusieurs IAP et l'application choisit une IAP au moment où elle a besoin du réseau. Ce choix est motivé par le fait que toutes les IAP ne fournissent pas forcément le service attendu par l'application. Par exemple, l'envoi d'un MMS nécessite l'usage d'un IAP qui donne accès à la passerelle MMS de l'opérateur, qui n'est en général pas joignable depuis l'Internet public. De même, une application qui accède aux serveurs privés d'une entreprise va choisir l'IAP qui correspond au VPN vers l'entreprise.
Ce concept d'IAP permet d'éviter bien des questions. Ainsi, le serveur DNS est indiqué dans l'IAP et, une fois celle-ci choisie, il n'y a pas à se demander quel serveur utiliser. (Reprenez l'exemple du VPN : cela garantira que l'application corporate utilisera un serveur DNS sûr et pas celui du hotspot où le téléphone est actuellement connecté.) De même, il existe une route par défaut par IAP et ce n'est donc pas un problème si deux interfaces de la même machine ont des plages d'adresses RFC 1918 qui se recouvrent (ou même si les deux interfaces ont la même adresse IP).
Comment l'application choisit-elle l'IAP ? Cela peut être fixé en dur dans le programme (cas de l'application MMS, en général), choisi par l'utilisateur au moment de la connexion, ou bien déterminé automatiquement par le système. La documentation de ce système figure en ligne.
Pour Windows Mobile et Windows Phone 7, tout dépend du Connection Manager. Celui-ci gère les connexions pour le compte des applications, en tenant compte de critères comme le coût ou comme la capacité du lien. Les applications peuvent l'influencer en demandant des caractéristiques particulières (par exemple une capacité minimale). Windows met en œuvre le RFC 3484 et l'administrateur système peut configurer des règles qui remplacent celles par défaut. Ce système est documenté en ligne.
Le Blackberry laisse les applications choisir la connexion qu'elles veulent, même s'il fournit un relais pour celles qui le désirent. Cela dépend toutefois de la configuration du réseau (l'utilisation obligatoire du Enterprise Server peut être choisie, par exemple). Les réglages comme le DNS sont par interface et non pas globaux au système. Plus de détails sont fournis dans la documentation.
Et Google Android ? Utilisant un noyau Linux, il partage certaines caractéristiques avec les autres systèmes Linux. Par défaut, il se comporte selon le modèle « machine terminale ouverte » (weak host model, cf. RFC 1122, section 3.3.4.2), mais peut aussi utiliser le modèle « machine strictement terminale » (strong host model). Dans le premier cas, les différentes interfaces réseaux ne sont pas strictement séparées, un paquet reçu sur une interface est accepté même si l'adresse IP de destination n'est pas celle de cette interface. Dans le second, la machine est stricte et refuse les paquets entrants si l'adresse IP de destination ne correspond pas à l'interface d'entrée du paquet.
La configuration DNS est globale (attention, Android ne la note pas
dans /etc/resolv.conf
, dont le contenu est
ignoré). Cela veut dire que, dès qu'une réponse DHCP est reçue sur une
interface, la configuration DNS de cette interface remplace la
précédente.
Depuis Android 2.2, le RFC 3484 est géré. (Notez que, à l'heure actuelle, Android ne peut pas faire d'IPv6 sur l'interface 3G.)
La documentation figure dans le paquetage
android.net
. Les
applications peuvent utiliser la classe
ConnectivityManager
si elles veulent influencer
la sélection de l'interface. Pour cela, le système met à leur
disposition la liste des interfaces et leurs caractéristiques. (Pour étudier un programme qui l'utilise, vous pouvez par exemple regarder les occurrences de ConnectivityManager
dans le source Java de CSIPsimple.)
Le RFC se penche aussi sur un système moins connu, Arena, qui utilise également Linux et fournit un gestionnaire de connexions pour choisir les interfaces, avec indication des préférences par les applications. Il sera décrit dans un futur RFC.
Et sur les systèmes d'exploitation utilisés sur le bureau ? Windows est présenté mais sera décrit plus en détail dans un autre RFC. Les systèmes utilisant Linux (comme Ubuntu ou Fedora) partagent plusieurs caractéristiques :
Les systèmes à base de BSD ont en gros les
mêmes caractéristiques. Dans les deux cas, Linux ou BSD, certaines
options permettent de passer outre les informations obtenues par
DHCP. Par exemple, des option modifiers dans le client DHCP OpenBSD offrent la possibilité
d'indiquer des valeurs à utiliser avant, ou bien à la place de, celles
fournies par le serveur DHCP. Même chose pour des options comme
-R
du client DHCP
Phystech (qui indique de ne pas modifier
resolv.conf
) ou comme nodns
et nogateway
dans les options de Pump, pour ignorer les résolveurs DNS et la route
par défaut de certaines interfaces. D'autres systèmes disposent
d'options similaires.
Enfin, même si le RFC ne le mentionne que très rapidement, il existe des systèmes de plus haut niveau (comme Network Manager, très pratique pour les machines qui se déplacent fréquemment) dont la tâche est d'orchestrer tout cela, de surveiller la disponibilité des interfaces, de lancer le client DHCP lorsque c'est nécessaire, d'accepter ou de passer outre ses choix, etc.
Voilà en gros la situation actuelle. Prochains efforts du groupe MIF : l'améliorer... Le RFC 6418 donne le cahier des charges de cet effort. Le RFC 6731 normalise les nouvelles règles de sélection pour les serveurs DNS.
Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : P. Eardley (BT), L. Eggert (Nokia), M. Bagnulo (UC3M), R. Winter (NEC Europe)
Pour information
Première rédaction de cet article le 2 novembre 2011
Nourri de la vaste expérience de ses auteurs (tous chercheurs et tous ayant écrit des RFC), ce document essaie de combler une partie du fossé entre la communauté des chercheurs et la normalisation, en encourageant ces chercheurs à participer à l'IETF, et en leur expliquant ce à quoi ils doivent s'attendre.
L'Internet est bien issu d'un projet de recherche, ARPANET, et a ensuite intégré un bon nombre de résultats de recherche. Normalement, le monde académique devrait se sentir à l'aise dans celui de la normalisation Internet. Mais ce n'est pas toujours le cas. Le chercheur isolé peut même trouver que l'IETF est une organisation mystérieuse et que le processus de normalisation y est très frustrant. C'est pour guider ces chercheurs que ce RFC leur explique ce nouveau (pour eux) monde.
Optimisme scientiste ou simplement désir de plaire aux lecteurs issus de la recherche ? En tout cas, le RFC commence par prétendre que le développement de nouvelles techniques est dû à la recherche scientifique. Après ce remontage de moral, la section 1 explique pourtant aux chercheurs candidats à un travail de normalisation à l'IETF qu'ils ne doivent pas s'attendre à un chemin de roses. Une SDO a d'autres motivations qu'une université. Dans la recherche, le plus important est qu'une solution soit correcte. Dans la normalisation, les problèmes à résoudre sont ceux du monde réel et le caractère pratique et réaliste de la solution a autant, voire plus d'importance, que sa parfaite correction.
Ainsi, l'IETF adopte souvent des solutions dont les limites, voire les défauts, sont connus, simplement parce que des alternatives « meilleures » ne semblent pas déployable sur le terrain. De même, une bonne solution à un problème intéressant peut être écartée, si ce problème ne se pose tout simplement pas dans l'Internet. Enfin, la normalisation progresse souvent par étapes incrémentales, nécessaires pour un déploiement effectif, et cela peut être jugé peu apétissant par des chercheurs qui veulent s'attaquer aux Grands Problèmes.
On voit ainsi régulièrement des malentendus, où des chercheurs arrivent à l'IETF avec des idées trop éloignées du domaine de l'IETF, ou bien trop générales pour qu'un travail concret (l'IETF normalise des bits qui passent sur le câble...) puisse commencer, des idées qui ne peuvent pas être déployées dans l'Internet d'aujourd'hui, ou encore des idées qui résolvent des problèmes qui ne sont pas, ou pas encore, d'actualité. Sans compter des problèmes moins techniques comme l'hésitation à passer leur bébé à l'IETF (perdant ainsi le contrôle de son évolution), la constatation que la normalisation est très chronophage, ou simplement l'impression qu'on ne les écoute pas réellement.
Cela ne veut pas dire que les chercheurs ne doivent même pas essayer. Bien au contraire, ce RFC doit leur permettre de mieux déterminer si et comment ils peuvent présenter leur travail à l'IETF. Il vient en complément de documents plus généraux sur l'IETF, notamment le fameux Tao (RFC 4677)).
Donc, première question à se poser (en section 2) : est-ce que l'IETF est le bon endroit pour ce travail ? Le RFC suggère deux questions simples aux candidats. Si votre travail était pris en compte :
La première question est une variante du classique « Quel problème essayez-vous de résoudre ? » Après tout, il y a déjà eu des tas de travaux (dont certains normalisés à l'IETF) qui n'ont jamais été déployés. Il est donc raisonnable de se demander si ce travail apportera un bénéfice. Un travail de recherche, même remarquable, n'est pas forcément dans ce cas.
La seconde question, sur les machines à mettre à jour en cas d'adoption de la technique, a pour but de pointer du doigt les problèmes de déploiement. Les chercheurs ont facilement tendance à les ignorer, préférant partir d'une table rase. Dans l'Internet d'aujourd'hui, utilisé par des milliards de personnes et pour qui des investissements colossaux ont été faits, cette approche n'est pas réaliste. Il est donc crucial de se demander « Est-ce que cette nouvelle technique pourra être déployée, et à quel coût ? » Par exemple, est-ce que la nouvelle technique nécessitera de mettre à jour seulement les routeurs, seulement les machines terminales, ou les deux ? Cette analyse est d'autant plus complexe qu'il faudra prendre en compte, non seulement les protocoles, mais également les pratiques opérationnelles et peut-être même certains modèles de business, qui pourraient être remis en cause.
Une fois cette analyse faite, si la conclusion est que le travail semble à sa place à l'IETF, comment convaincre celle-ci de s'y mettre (section 3) ? Il faut trouver le bon endroit dans l'IETF. Celle-ci n'est plus le petit groupe de travail du début, où tout le monde était impliqué dans tous les protocoles. C'est désormais un gros machin, avec des dizaines de groupes de travail différents (eux-même regroupés en zones - areas) et il faut trouver le bon. S'il existe, il faut le rejoindre (l'IETF n'a pas d'adhésion explicite, rejoindre un groupe, c'est simplement s'abonner à sa liste de diffusion). Et s'il n'existe pas ?
Alors, il va falloir construire une communauté d'intérêts autour de la nouvelle proposition. Après tout, la normalisation, contrairement à la recherche, nécessite un accord large et il va donc falloir se lancer dans le travail de persuasion. Le RFC note que cet effort aura des bénéfices, notamment celui d'améliorer la proposition technique, grâce aux remarques et commentaire des participants à l'IETF. Cela oblige également à documenter le protocole d'une manière compréhensible pour les autres (on peut s'inspirer du RFC 4101). C'est à ce stade qu'on peut tenir des réunions informelles (les Bar BoF) pendant les réunions physiques de l'IETF.
Si on n'a pas trouvé de groupe de travail qui convenait, que faut-il faire ? « En créer un ! », vont crier beaucoup de gens. Bonne idée, mais il faut d'abord lire la section 3.4, qui explique les étapes préalables, celles citées dans le paragraphe précédent, et la tenue recommandée d'une BoF (cf. RFC 5434).
Une fois que tout ceci est fait, la situation semble idyllique. L'IETF a accepté de travailler sur la nouvelle technique, un groupe de travail a été créé, il suffit d'attendre tranquillement son résultat ? Mais non. Comme le rappelle la section 4, il faut continuer à suivre le projet. Il faut prévoir pour cela des efforts importants, du temps et de la patience. Les gens qui n'ont jamais travaillé avec une SDO sont presque tous étonnés de la longueur et de la lourdeur du processus. Tout groupe de travail ne produit pas forcément de RFC et le succès va dépendre d'un travail continuel. Bien qu'en théorie, tout puisse se faire à distance, le RFC rappelle qu'une présence physique aux réunions va, en pratique, augmenter les chances de réussite (c'est comme pour les élections, il faut serrer des mains).
Pire, on a parfois l'impression que le processus s'enlise. L'IETF n'a pas de votes et encore moins de chefs qui décideraient tout. Un consensus relatif est nécessaire pour à peu près tout, et l'IETF n'est pas connue pour sa capacité à prendre des décisions... Bref, notre RFC prévient les candidats : deux ans au moins, depuis la création du groupe de travail. Si le projet de recherche qui a donné naissance à la nouvelle technique dure trois ans, cela veut dire qu'il faut commencer le travail de lobbying à l'IETF dès la première semaine du projet, si on veut que la nouvelle technique soit normalisée avant la fin du projet ! Il vaut donc mieux se préparer d'avance à ce que le projet ne soit pas complété par l'auteur lui-même, et soit terminé par d'autres.
Et c'est si tout se passe bien. Mais il y a parfois des chocs de cultures qui ralentissent le projet. Par exemple, le monde de la recherche privilégié la paternité (« l'algorithme X, décrit par Dupont et Durand dans leur article de 2008 ») alors que l'IETF privilégie le travail collectif. Une norme n'appartient pas à son auteur mais à toute la communauté. Il est donc préférable d'avoir une mentalité très ouverte avant de commencer.
Autre point sur lequel le choc des cultures est fréquent : la mise en œuvre de l'idée dans du vrai logiciel qui tourne. L'IETF accorde une grande importance à ce logiciel (le running code), qui montre que l'idée est viable, et que quelqu'un y a cru suffisamment pour dédier une partie de son précieux temps à sa programmation. C'est encore mieux si le programme connait un début de déploiement (le RFC suggère, pour un protocole réseau, d'essayer de le faire adopter dans le noyau Linux, par exemple). Si ces règles semblent contraignantes, il faut se rappeler qu'elles sont dues à de nombreuses expériences douloureuses, de protocoles déployés uniquement sur le papier, et qui avaient donc fait perdre du temps à tout le monde.
Pour rendre ces conseils plus concrets, le RFC contient une section d'exemples, la 5. On y trouve des résumés de l'incorporation dans le processus IETF de deux protocoles issus de la recherche « académique » :
Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : E. Hammer-Lahav, B. Cook
Chemin des normes
Première rédaction de cet article le 1 novembre 2011
Ce court RFC spécifie une convention qui
permet à un client Web de récupérer sur un
serveur une description formelle de
métadonnées sur le site servi (par exemple
l'auteur du site Web, ou bien la licence du
contenu servi). Cela se fait en mettant ces métadonnées au format
XRD dans une ressource nommée
/.well-known/host-meta
.
Vous pouvez voir le résultat dans le /.well-known/host-meta
de mon site, très inspiré de l'exemple
de la section 1.1 du RFC. Il est vraiment minimal et
n'inclut que des métadonnées globales (le format
XRD permet également de s'en servir pour des
métadonnées locales à une ressource, cf. section 4.2).
Notez que le vocabulaire peut être trompeur. Le RFC 3986 parle de host pour le
example.com
de
http://example.com/truc/machin
mais ce terme ne
désigne pas du tout une machine. Finalement, le terme marketing flou
de « site » est encore le moins mauvais.
Ce nouveau nom de host-meta
a donc été le
premier à être enregistré (cf. section 6.1) dans le registre des ressources
bien connues qui avait été créé par le RFC 5785. (Deux ou trois autres sont venus juste après, et le
RFC 5785 a été depuis remplacé par le RFC 8615.)
Pour le client, par exemple un navigateur Web, récupérer les
métadonnées consiste juste donc à faire une requête
GET
sur le nom
/.well-known/host-meta
(section 2). Il obtient en échange un
fichier XML au format
XRD, servi avec le type
application/xrd+xml
.
Le contenu du document est détaillé dans la section 3. Ce
vocabulaire XRD a été normalisé par
OASIS et sert à beaucoup de choses très
compliquées. Mais l'accent est mis ici sur son utilisation pour
fournir des métadonnées. Tout en gardant le modèle de données de XRD,
le serveur peut envoyer du XML (la syntaxe
habituelle) ou du JSON. Cette dernière syntaxe
est normalisée dans l'annexe A, sous le nom de JRD. On peut l'obtenir
(n'essayez pas sur mon site, il n'est pas configuré pour cela) en
utilisant la négociation de contenu HTTP (champ Accept:
application/json
dans la requête) ou en demandant
/.well-known/host-meta.json
au lieu de simplement /.well-known/host-meta
.
Qui utilise ou va utiliser ces métadonnées ? Pour l'instant, les moteurs de recherche ne semblent pas y accéder mais cela viendra peut-être bientôt (Yahoo et Google ont annoncé travailler sur le sujet). La communauté WebFinger (RFC 7033) est également très impliquée dans ce projet.
Sinon, ce choix d'utiliser une ressource avec un nom spécial (le préfixe
/.well-known
est normalisé dans le RFC 8615) est dû au fait qu'un serveur n'a pas
d'URI qui le désigne globalement et on ne peut
donc pas utiliser les techniques qui attachent les métadonnées à une
ressource (par exemple les en-têtes HTTP comme
l'en-tête Link:
du RFC 8288), sauf à utiliser des trucs contestables comme de
considérer que /
, la racine du site, désigne tout
le site.
Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : R. Housley (Vigil Security), D. Crocker (Brandenburg InternetWorking), E. Burger (Georgetown University)
Première rédaction de cet article le 12 octobre 2011
Ce très court RFC met fin (provisoirement ?) à un très long et très agité débat au sein de l'IETF. Après de longs efforts, il réussit à réformer une vache sacrée du processus de normalisation des protocoles TCP/IP. Les RFC spécifiant ces protocoles avaient trois étapes sur le chemin des normes. Il n'y en a désormais plus que deux.
D'innombrables documents, cours et articles ont expliqué le
cheminement d'un RFC sur le chemin des normes,
tel que le décrit le RFC 2026. Un premier point
essentiel du RFC 2026 est que tous les RFC ne
sont pas sur le chemin des normes. Ils peuvent être simplement « expérimentaux » ou bien « pour information ». Un deuxième point
essentiel était que le chemin des normes comprenait trois étapes,
chacune marquant une progression vers le statut de norme complète et
achevée. L'étape atteinte par chaque RFC (pas encore adaptée à ce nouveau
RFC) est visible en http://www.rfc-editor.org/category.html
.
Ce schéma était simple et bien décrit. Mais il a été peu appliqué en pratique. D'abord, même parmi les participants à l'IETF, peu ont vraiment compris les subtiles nuances entre les trois étapes. A fortiori, à l'extérieur, peu de gens prenaient leurs décisions techniques en fonction des niveaux atteints sur le chemin des normes ! (Je me souviens de réunions d'un groupe de travail anti-spam où la lobbyiste d'AOL pouvait ergoter sans fin sur les niveaux de maturité de normes comme SMTP, uniquement pour donner un habillage pseudo-juridique aux décisions déjà prises par AOL.) Enfin, on constate qu'avancer sur ce chemin était trop pénible. Certaines normes l'ont fait, car elles étaient poussées par un acteur décidé qui avait intérêt à un statut le plus élevé possible mais, dans d'autres cas, personne ne s'en est occupé et des tas de normes très stables et très déployées sont restées à une étape intermédiaire. C'est ainsi que EPP, bien que récent, a atteint l'étape suprême avec le RFC 5730, simplement parce que VeriSign a poussé très fort, alors que HTTP (RFC 2616) est coincé en étape Projet-de-norme, parce que personne n'a le courage de lobbyer pour qu'il avance. Même chose pour SMTP (RFC 5321) qui, comme HTTP, est indubitablement largement déployé et avec succès ! Bref, l'état actuel de ses RFC sur le chemin des normes ne reflète que très peu la qualité, la stabilité, la popularité et la maturité d'un protocole.
L'IETF a donc, non sans douleur, réfléchi depuis plusieurs années à une simplification du processus, en réduisant le nombre d'étapes à deux. Il y a eu de nombreuses discussions à ce sujet, certains voulant en profiter pour faire une refonte complète du système de normalisation à cette occasion. C'est finalement un choix plus conservateur qui a été fait : le changement reste limité. C'est déjà bien qu'il ait lieu, certains commençaient même à être sceptiques quant aux capacités de l'IETF à réformer ses processus.
Le RFC 2026 réclamait, pour bouger de la première étape (proposition de norme), un rapport explicite sur l'interopérabilité des mises en œuvre de la norme. Et pour atteindre la troisième (norme tout court), un déploiement massif était nécessaire. Ces deux critères sont désormais fusionnés en un seul, qui permettra le passage de la nouvelle première étape, à la nouvelle deuxième (et dernière) étape. Il faudrait plutôt dire la seconde étape, d'ailleurs, si on suit les règles du français soutenu, où « deuxième » implique qu'il y a d'autres étapes ensuite.
Les règles précises figurent en section 2. Il n'y a désormais que deux niveaux sur l'échelle :
Lors de son passage de la première à la seconde étape, une norme peut être révisée de façon mineure (c'est bien l'un des buts de ce chemin des normes que de permettre l'amélioration des normes, à la lumière de l'expérience). Mais, si l'utilisation réelle montre des problèmes sérieux, qui nécessitent une révision plus fondamentale du protocole, il faudra repartir de la première étape.
Donc, désormais, pour avancer de la première à la seconde étape, il faudra :
Et pour les RFC actuels, on fait quoi ? La section 2.3 traite de la transition et précise que les RFC à l'étape Norme-tout-court passent automatiquement à l'état Norme-Internet. Ceux à l'étape Proposition-de-norme y restent (rappelez-vous que cette étape n'a pas changé). Et ceux à l'étape (supprimée) Projet-de-norme y restent provisoirement, en attendant une reclassification par l'IESG (qui aura le droit, dans deux ans, de les passer tous, d'autorité, à l'état de Norme-Internet).
Ce RFC supprime également certaines obligations, bonnes sur le principe mais qui, en pratique, bloquaient certains RFC sur le chemin des normes, sans bonne raison (section 3). C'est ainsi qu'il n'est plus nécessaire :
Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : R. Gellens (Qualcomm), J. Klensin
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF yam
Première rédaction de cet article le 16 novembre 2011
Pendant longtemps, le système de courrier électronique de l'Internet ne faisait aucune différence entre le serveur de messagerie et le simple PC de l'utilisateur. Tous utilisaient le même protocole SMTP, spécifié dans le RFC 2821. Depuis le RFC 2476 et plus encore depuis le RFC 4409, précurseurs de notre RFC 6409, ce n'est plus vrai. Le simple PC doit désormais utiliser une autre solution, la soumission de message.
L'ancienne architecture était raisonnable à l'époque où toutes les machines connectées à l'Internet étaient de gros serveurs gérés par des professionnels. Ceux-ci pouvaient faire en sorte que tout soit correctement configuré. Et, donc les autres serveurs, les MTA pouvaient ériger en principe le "Pas touche" et ne jamais modifier ou contester un message reçu (section 1 du RFC ; en pratique, pas mal de MTA modifiaient quand même le contenu des messages, avec des conséquences négatives).
Aujourd'hui, avec le nombre de micro-ordinateurs non gérés qui sont connectés à Internet, cela n'est plus possible. Le RFC 2476 avait donc séparé les clients SMTP en deux catégories : les MTA qui se connectent au port traditionnel, le numéro 25 et les MUA qui, s'ils veulent envoyer en SMTP, doivent utiliser un autre service, nommé MSA, tournant en général sur le port 587 (section 3.1), et soumis à d'autres règles :
Attention toutefois, la section 8 rappelle que les modifications du message soumis ne sont pas toujours inoffensives et qu'elles peuvent, par exemple, invalider les signatures existantes.
Notre RFC, qui remplace le RFC 4409, qui lui-même remplaçait le RFC 2476, pose en principe que, désormais, les machines des simples utilisateurs devraient désormais utiliser ce service.
La soumission de messages, telle que normalisée dans ce RFC est ses prédécesseurs, a été un grand succès depuis dix ans, notamment depuis trois ans. Le port 25 est de plus en plus souvent bloqué en sortie des FAI (pour limiter l'envoi de spam par les zombies), et la seule solution pour écrire sans passer par le serveur de son FAI est désormais le port 587. La norme technique est sortie il y a désormais treize ans et est particulièrement stable et mûre.
Si vous utilisez Postfix, vous pouvez lire un exemple de configuration de Postfix conforme (partiellement) à ce RFC.
Notre RFC a été développé par le groupe de travail YAM de l'IETF. Ce groupe est chargé de prendre toutes les normes IETF liées au courrier électronique et de les faire avancer sur le chemin des normes, si possible. La soumission de courrier est ainsi devenue « norme tout court » (Full Standard) avec ce RFC 6409. Les changements depuis le RFC 4409 sont décrits dans l'annexe A. Les principaux sont l'importance plus grande de l'internationalisation (section 6.5, qui précise que le MSA peut changer l'encodage), et une mise en garde plus nette contre les risques encourus en cas de modification de messages par le MSA.
Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : R. Barnes (BBN Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF dane
Première rédaction de cet article le 28 octobre 2011
Le projet DANE (DNS-based Authentication of Named Entities, anciennement KIDNS - Keys In DNS), vise à améliorer et/ou remplacer les certificats X.509 utilisés dans des protocoles comme TLS (RFC 5246). Ces certificats souffrent de plusieurs problèmes, le principal étant qu'une Autorité de Certification (AC) malhonnête ou piratée peut créer des certificats pour n'importe quelle entité, même si celle-ci n'est pas cliente de l'AC tricheuse. C'est ce qui s'est produit dans les affaires Comodo et DigiNotar et ces deux affaires ont sérieusement poussé aux progrès de DANE. Ce premier RFC du groupe de travail DANE établit les scénarios d'usage : quels problèmes veut résoudre DANE et selon quels principes ?
Revenons d'abord sur le fond du problème (section 1 du RFC) : lors de l'établissement
d'une session TLS (par exemple en HTTPS), le
client se connecte à un serveur dont il connait le nom (par exemple
impots.gouv.fr
, cf. RFC 6125), le
serveur (et, plus rarement, le client) présente un
certificat numérique à la norme X.509 (bien
qu'un certificat PGP soit aussi possible,
cf. RFC 6091). Ce certificat suit le profil
PKIX, normalisé dans le RFC 5280, un sous-ensemble de X.509. Comme ce certificat peut avoir
été présenté par un homme du milieu qui a
intercepté la session (par exemple en jouant avec
BGP ou OSPF), il faut l'authentifier,
sinon TLS ne protégerait plus que contre les attaques
passives, laissant ses utilisateurs à la merci des attaques
actives. Cette authentification se fait typiquement aujourd'hui en
vérifiant que le certificat a été signé par une des plusieurs
centaines d'AC qui se trouvent dans le magasin de
certificats de n'importe quel navigateur Web. Le point important, et qui est l'une des deux
principales faiblesses de X.509 (l'autre étant son extrême
complexité), est que n'importe laquelle de ces centaines d'AC peut
signer un certificat. Ainsi, dans l'affaire
DigiNotar, une AC néerlandaise était piratée, le pirate lui
faisait générer des certificats pour *.google.com
ou *.gmail.com
(alors que Google n'est pas du tout client de
DigiNotar) et ces certificats sont acceptés par tous les
navigateurs. Le pirate a vendu ou donné les clés privées de ces
certificats au gouvernement iranien, qui n'a
plus eu qu'à monter une attaque de l'homme du
milieu (facile lorsqu'on est un état policier et qu'on
contrôle tous les FAI du pays) pour détourner les utilisateurs vers un faux
Gmail, qui présentait un certificat
acceptable. La dictature intégriste pouvait alors lire les messages
et emprisonner ou tuer les opposants. (Le fait que l'attaque venait
d'Iran est établi par les requêtes OCSP des
victimes. Cf. le rapport sur l'opération Tulipe
Noire.)
Identifiée depuis longtemps (mais niée par le lobby des AC ou par
l'UIT, à l'origine de la norme X.509), cette
vulnérabilité a mené au projet DANE. L'idée de base est qu'introduire
un intermédiaire (l'AC) est en général une mauvaise idée pour la
sécurité. Pour reprendre l'exemple ci-dessus, il vaudrait mieux
permettre à Google de prouver sa propre identité. Comme quasiment
toutes les transactions sur l'Internet commençent par une requête
DNS, pourquoi ne pas utiliser la zone DNS
google.com
pour y mettre le certificat ? L'idée
est ancienne, mais elle ne suscitait guère d'intérêt tant que le DNS
lui-même n'était pas un tant soit peu sécurisé. Le déploiement rapide
de DNSSEC, à partir de
2009, a changé la donne : mettre des clés
cryptographiques ou des certificats dans le DNS devient réaliste. D'où
la création, en février 2011, du groupe de travail DANE de
l'IETF, chargé de trouver une technique de
sécurité qui marche.
Ce RFC ne donne pas encore de solution (au moment de sa parution, celle-ci est très avancée et a des chances sérieuses d'être publiée en 2012). Il explique les scénarios d'usage, pour aider à évaluer la future solution. Pour décrire ces scénarios, on recourt évidemment aux personae traditionnels :
alice.example.com
,Trois scénarios sont ensuite décrits dans la section 3, le œur de ce RFC :
Dans les deux premiers cas, DANE ne fait qu'ajouter de la sécurité à X.509 et on a toujours besoin de l'IGC actuelle. Le troisième est le plus novateur, permettant de remplacer complètement l'IGC, et ne gardant de X.509 que son format de certificats. (Notez que ces trois scénarios ne se retrouvent pas exactement dans le RFC 6698 sur le protocole qui a quatre types et non pas trois.)
Voyons d'abord le premier scénario (section 3.1) , les contraintes sur l'AC. Dans
un cas comme celui des piratages de Comodo ou de DigiNotar, Alice, qui
est cliente d'une autre AC, Charlie, est inquiète du risque d'un faux
certificat pour alice.example.com
, émis par l'AC
voyoute. Elle voudrait dire aux visiteurs de
https://alice.example.com/
que les seuls
certificats légitimes sont ceux émis par Charlie. En d'autres termes,
elle voudrait que la vérification du certificat de son serveur parte
du certificat de Charlie, pas de n'importe quel certificat d'AC du
magasin.
Notez que, si Alice dispose d'un tel système, elle peut aussi s'en servir vis-à-vis de Charlie. Lorsqu'elle demande un certificat à ce dernier, il pourrait vérifier qu'Alice l'a bien listé comme AC.
Donc, Alice va mettre dans le DNS un enregistrement qui dit « je suis cliente de Charlie ». Cet enregistrement doit-il être sécurisé par DNSSEC ? La question est toujours très discutée au sein du groupe DANE. A priori, DNSSEC n'est pas impératif puisque cet enregistrement DNS n'est qu'une sécurité supplémentaire : le X.509 traditionnel fonctionne toujours en dessous. D'un autre côté, cette sécurité supplémentaire est très faible si on ne met pas DNSSEC : un attaquant qui peut monter une attaque de l'Homme du Milieu pour détourner vers son propre serveur peut probablement aussi supprimer les enregistrements DANE au passage. Notons aussi que le fait d'exiger la validation X.50 comme avant limite les possibilités d'attaque par un registre DNS. Avec le type 0 (contrainte sur l'AC), un attaquant devrait contrôler à la fois l'enregistrement DNS et l'Autorité de Cértification.
Second scénario, la contrainte sur le certificat (section 3.2),
alias type 1. Alice est cliente de Charlie mais se demande si Charlie
ne va pas émettre d'autres certificats pour
alice.example.com
, par exemple parce que les
machines de Charlie ont été piratées. Elle voudrait donc indiquer aux
visiteurs de https://alice.example.com/>
que seul
tel certificat est valable. Alice va donc mettre le certificat (ou un
condensat cryptographique de celui-ci) dans le DNS. Comme avec le type
0, toute la validation classique de X.509 est ensuite appliquée. Dans
ce mode, DANE ne fait qu'ajouter une vérification supplémentaire.
Bien plus « disruptive » est la possibilité de se passer complètement des AC et de dire dans le DNS « voici le certificat à utiliser », sans qu'il doit validé par d'autres mécanismes que DNSSEC. Cette possibilité (section 3.3), dite type 2, est l'équivalent des certificats auto-signés actuels, mais avec possibilité de les vérifier (grâce à DNSSEC). Alice se passe alors complètement de Charlie. (Notez que le cas où Alice est cliente de Trent est équivalent, le certificat de Trent n'étant quasiment dans aucun magasin. Alice va alors publier dans le DNS le certificat de Trent et non le sien.)
Notez que ce mécanisme n'empêche pas Bob d'avoir sa propre politique de validation. On pourrait imaginer un Bob suspicieux vis-à-vis de DNSSEC qui n'accepterait que les enregistrements DANE de type 0 ou 1. Ou un Bob qui aurait une liste noire des certificats à qui il ne fait pas confiance, DANE ou pas DANE.
Cette fois, avec le type 2, DNSSEC est absolument
indispensable. Sans lui, il n'y a plus aucune validation du
certificat. Ne publiez donc pas d'enregistrements de type 2 avant
d'avoir vérifié que DNSSEC était correctement déployé et que vous le
maîtrisez parfaitement. Pour la même raison, le type 2 est celui qui
met le plus de responsabilités chez les opérateurs DNS. Si ceux-ci
trahissent ou sont piratés, tout le système est en danger. Mais
rappelez-vous que, contrairement à ce qui se passe pour X.509, le
risque est uniquement dans les prestataires que vous choisissez. Si
vous choisissez d'utiliser un nom de domaine en
.org
, vous savez
qu'Afilias peut tout faire rater, mais que ni
l'AFNIC, ni CNNIC n'ont
ce pouvoir. Alors qu'avec X.509, même en choisissant soigneusement son
AC, on peut être victime de n'importe quelle autre AC, qu'on n'a pas
choisi. Donc, conseil pratique, choisissez bien vos prestataires
(registre DNS, bureau d'enregistrement,
hébergeur DNS, etc).
Mais il est clair que DANE donne plus de responsabilité (on peut même dire de pouvoir) aux acteurs du DNS. Ce point est souvent à la base de la plupart des critiques de DANE.
Autre point à garder en tête lorsqu'on évalue la sécurité de DANE : aujourd'hui, avec X.509, le contrôle de la zone DNS donne déjà souvent accès à des certificats (bien des AC ne font pas d'autres vérifications que l'envoi d'un courrier avec un cookie, ou la publication d'un certain enregistrement).
Voilà, vous connaissez l'essentiel sur DANE. la section 4 couvre toutefois d'autres points, moins centraux, sous forme d'une liste de souhaits pour le futur protocole :
Le protocole qui met en œuvre ce cahier des charges a été normalisé en août 2012 dans le RFC 6698.
Pour ceux qui souhaitent approfondir le sujet, j'ai fait un exposé sur la question (avec article détaillé) en novembre 2011 aux JRES à Toulouse.
Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : M. Yevstifeyev
Pour information
Première rédaction de cet article le 19 septembre 2011
L'expérimentation des ION (IETF Operational Notes, une série de documents IETF plus légers que les RFC) ayant été abandonnée, ce RFC reclassifie officiellement le RFC 4693, qui créait les ION, comme n'ayant qu'un intérêt historique.
Ce nouveau RFC, de même que la décision d'abandon, ne s'étend guère sur les raisons de l'échec et ne tire pas de bilan.
Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : R. Alimi (Google), A. Rahman (InterDigital Communications), Y. Yang (Yale University)
Pour information
Réalisé dans le cadre du groupe de travail IETF decade
Première rédaction de cet article le 26 octobre 2011
Cette intéressante étude des systèmes de stockage de données en ligne (le RFC n'utilise pas le terme de cloud, pourtant bien plus vendeur) fait le tour des principales solutions d'aujourd'hui. Son but est de préparer le travail ultérieur du groupe de travail IETF DECADE, dont le rôle est de normaliser une architecture pour l'accès au stockage en ligne, notamment pour le pair à pair. Ce RFC, le premier produit par DECADE, étudie l'offre existante, afin de voir dans quelle mesure elle est réutilisable pour DECADE.
Notons que tous les systèmes existants n'y sont pas : l'accent a été mis sur une sélection de systèmes typiques couvrant à peu près toutes les variantes possibles d'un tel service. C'est ainsi que, par exemple, Swift/OpenStack n'y figure pas. Par contre, le plus célèbre, le S3 d'Amazon est présent. Certains de ceux qui y figurent sont très expérimentaux, peu déployés, mais ont été ajoutés parce qu'ils illustrent un point important.
Il existe des tas de raisons pour stocker ses données dans le nuage. Cela peut être pour y accéder de partout, depuis n'importe quelle machine. Ou bien cela peut être pour rapprocher les données des utilisateurs. Si on distribue du contenu en pair à pair, il vaut mieux qu'il soit déjà dans le nuage, plus près des téléchargeurs, que sur une machine à la maison, connectée en ADSL, où le coût du dernier kilomètre à franchir est élevé.
La section 2 brosse un panorama historique du stockage en
ligne. Par exemple, le goulet d'étranglement que représente le gros
site Web, lorsqu'il a de très nombreux utilisateurs, a été
partiellement levé avec l'introduction des
CDN. Ceux-ci dupliquent le contenu statique des
sites Web, et le rapprochent des utilisateurs, en plaçant des copies
chez les principaux FAI. Mais les CDN ne sont
pas accessibles à l'utilisateur normal. Si je voulais accélérer le
temps de chargement des pages de
http://www.bortzmeyer.org/
, je ne pourrais
certainement pas monter un CDN moi-même, un tel travail nécessite des
moyens financiers et administratifs hors de ma portée.
Le pair à pair a ensuite fourni d'autres possibilités. Si on utilise les machines de tout le monde pour distribuer du contenu, pourquoi ne pas également s'en servir pour améliorer l'accès au contenu par une réplication et une copie proche des autres pairs ? Plusieurs systèmes de « caches P2P » ont ainsi été développés pour accélérer le pair à pair (cf. section 4.12). Malheureusement, tous sont spécifiques à une application particulière et ne peuvent donc pas servir aux nouvelles applications. Le monde du pair à pair évoluant vite, il ne peut donc pas bénéficier d'une infrastructure de stockage existante. Le but de DECADE est justement de permettre la création de cette infrastructure.
Pour pouvoir étudier de manière systématique les techniques existantes, la section 3 du RFC liste les composants d'une solution de stockage en ligne. Chaque technique sera alors décrite pour chacun de ces composants :
Sur la base de ce découpage en composants, on peut décrire les systèmes existants (section 4, mais rappelez-vous que le RFC ne prétend pas les présenter tous et que je n'ai pas repris ici tous ceux listés dans le RFC). Notez que l'ordre de la présentation est celui du RFC, même s'il peut sembler incohérent. D'autre part, un bon nombre des descriptions ressemblent à du copier-coller depuis les descriptions officielles (y compris dans leur côté marketing).
Commençons par le plus connu, Amazon S3. Les utilisateurs créent des containers, les seaux (buckets) puis y déposent des objets. Les accès se font en REST.
Pour montrer les capacités de S3, testons un peu avec un client
Unix en ligne de
commande, s3cmd. On lui indique les
clés avec s3cmd --configure
puis on peut créer
un seau (le nom est hiérarchique car un nom de seau doit être unique entre tous les utilisateurs ; on peut aussi préfixer avec l'ID Amazon) :
% s3cmd mb s3://org-bortzmeyer-essais
(où mb
signifie make bucket,
créer un seau.)
Puis on peut mettre un fichier dans ce seau :
% s3cmd put tartiflette1.jpg s3://org-bortzmeyer-essais /home/stephane/Downloads/tartiflette1.jpg -> s3://org-bortzmeyer-essais/tartiflette1.jpg [1 of 1] ... 35267 of 35267 100% in 0s 37.21 kB/s done
Il est ensuite possible de récupérer cet objet, par exemple depuis une autre machine :
% s3cmd get s3://org-bortzmeyer-essais/tartiflette1.jpg ... s3://org-bortzmeyer-essais/tartiflette1.jpg -> ./tartiflette1.jpg [1 of 1] 35267 of 35267 100% in 0s 74.04 kB/s done
On a donc vu les deux commandes les plus importantes,
put
et get
(lire et écrire
des objets).
S3 est devenu très populaire, entre autres en raison de sa simplicité. Pas d'espace de nommage hiérarchique, pas de possibilité de modifier les données existantes, accès en REST... L'interface d'accès permet de lire et d'écrire (les deux opérations illustrées plus haut), on peut détruire les objets, on peut lire le contenu d'un seau (c'est la seule possibilité de recherche), S3 fournit des mécanismes de contrôle d'accès riches, il n'y a pas de vraie découverte (l'utilisateur doit connaître l'URL où envoyer les requêtes, dans l'exemple ci-dessus, on utilise celle par défaut), et enfin, on l'a vu, S3 stocke des objets (aucun mécanisme de dossiers ou répertoires).
Il existe d'autres systèmes analogues à S3 comme Dropbox.
Un exemple d'un service très différent est le BranchCache de Windows, assez répandu en raison de la diffusion de ce système d'exploitation. Les accès ne sont pas explicites comme avec S3, BranchCache vise à stocker et récupérer les données automatiquement dans un cache. Il y arrive en se mettant sur le trajet des requêtes HTTP et SMB. Il intercepte la requête normale, et accède au fichier depuis le cache, si c'était une opération de lecture et que le fichier était déjà disponible.
Autre exemple très différent de S3, le CNF (Cache-and-Forward), une architecture de recherche visant à doter les réseaux d'un mécanisme efficace d'accès aux données. Dans CNF, les routeurs ne sont plus simplement des routeurs qui opèrent au niveau 3 mais des moteurs d'accès des données (store and forward) qui font suivre les requêtes d'accès et gardent le résultat localement, pour les accès ultérieurs. Le contenu très populaire est ainsi petit à petit copié dans les routeurs les plus proches. Un mélange de Usenet et de cache opportuniste (tout le contenu n'est pas copié, contrairement à Usenet ou aux CDN, seulement celui qui est demandé).
Plus dans l'idée d'un accès explicite aux données, le standard CDMI vise à résoudre un problème récurrent du cloud : l'absence de normes pour l'accès aux données, qui font qu'une fois choisi un fournisseur, on en est prisonniers. Si vous bâtissez votre service autour d'un accès à S3, vous ne pouvez plus quitter Amazon. Certes, l'interface de S3 est tellement populaire qu'il existe désormais des offres compatibles (hébergées, ou bien à construire soi-même comme celle d'Eucalyptus) mais ces offres sont à la merci d'un changement unilatéral de l'interface S3 par Amazon. CDMI est donc une tentative pour concevoir et populariser, au sein d'un consortium industriel, la SNIA, une interface standard. Elle ressemble dans ses principes à S3 et repose sur les modes actuelles (REST et JSON).
Comme CDMI est indépendant d'un vendeur particulier, et repose sur des protocoles simples et bien connus comme HTTP, elle est une approche tentante pour le groupe DECADE.
J'ai déjà parlé des CDN. Ils représentent aujourd'hui une des approches les plus populaires, d'accès aux données en ligne. Un bon tour d'horison complet des CDN figure dans « A Taxonomy and Survey of Content Delivery Networks » de Pathan, A.K. et Buyya, R. Le principe est de copier à l'avance le contenu vers des serveurs situés chez les FAI et d'utiliser divers trucs (par exemple fondés sur le DNS) pour que les utilisateurs soient redirigés vers ces serveurs. Le plus connu des CDN est Akamai mais il en existe bien d'autres comme Limelight ou CloudFront. Pour DECADE, l'intérêt des CDN est que c'est une technique très répandue et éprouvée. Mais elle nécessite une relation d'affaires existante entre l'opérateur du CDN et le fournisseur de contenu (contrairement aux caches classiques).
Le CDN ne fournit typiquement d'accès qu'en lecture (l'écriture est réservée au fournisseur de contenu, via le mécanisme que lui offre l'opérateur du CDN).
Plus proche du CNF, le système DTN vise à créer un environnement adapté aux cas difficiles, notamment aux missions spatiales. Dans ces cas où la connectivité est très intermittente (une seule tempête solaire peut tout interrompre pendant des semaines), et où les délais sont énormes, les protocoles TCP/IP classiques ne conviennent plus. D'où le DTN, normalisé dans le RFC 4838, une architecture store and forward qui ressemble davantage à UUCP.
Le DTN repose sur le protocole Bundle (RFC 9171), qui permet de stocker les données en attendant que le destinataire soit à nouveau disponible. Bien sûr, IP est lui aussi store and forward dans la mesure où le routeur garde le paquet en mémoire avant de le passer au routeur suivant. Mais le temps de rétention des données dans IP est typiquement de quelques milli-secondes au maximum, alors qu'il atteint couramment plusieurs jours dans Bundle, imposant le recours à un stockage persistant (au cas où le routeur redémarre). Contrairement à IP, où le routeur a le droit de jeter des paquets, Bundle est plus proche du courrier électronique : le routeur doit prendre soin des données jusqu'à ce qu'il ait pu les transmettre. Il n'est donc pas exagéré de l'inclure dans cette liste des services de stockage en ligne.
Dans la catégorie futuriste, une autre famille de candidats intéressants est celle qu'on va appeler, pour simplifier. les « réseaux fondés sur les objets nommés » (c'est le nom de la première conférence scientifique sur le sujet). C'est une vaste famille, comprenant uniquement des projets de recherche fondamentale, qui ont en commun le fait que toute l'architecture du réseau repose sur des objets de données, ayant un nom, et que le réseau est conçu pour accéder rapidement et de manière sûre à ces objets. Cette famille privilégie donc l'accès au contenu. On y trouve des systèmes comme CCN, ou comme NDN (Named Data Networking) et NetInf (Network of Information), traités plus en détail dans ce RFC.
NDN est un tel système. Le réseau gère des objets nommés et signés cryptographiquement. Les routeurs qui transmettent ces objets ont la possibilité de les garder en cache. Les objets les plus demandés vont donc avoir plus de chance de se retrouver dans un cache proche, réalisant ainsi automatiquement ce que les CDN font manuellement. Comme les autres propositions de la famille Name-oriented networking, tout repose sur l'idée que « data delivery has become the primary use of the network ».
NetInf reprend les mêmes affirmations minitéliennes et y ajoute des fausses explications sur ce que représente un URL (le deuxième champ d'un URL, après le plan, n'identifie pas une machine).
Plus sérieux, OceanStore est une architecture où un ensemble de machines coopèrent en mettant en commun des espaces de stockage. OceanStore met l'accent sur la résilience et l'auto-organisation. Son intérêt pour DECADE est surtout cette capacité à résister aux pannes, et même à une certaine proportion de participants malhonnêtes (qui modifieraient les données, ou bien les effaceraient). OceanStore fournit une interface permettant lecture et écriture des objets mais reste encore très expérimental.
Un des domaines où il y a eu le plus d'utilisations du stockage en ligne est évidemment le partage de photos. Une section est donc consacrée à ce cas particulier, où on voit apparaître des noms connus comme Flickr ou ImageShack, sans compter des services qui, sans être spécialisés dans les photos, sont néanmoins largement utilisés pour cela, comme Tumblr. Une particularité de ces services est l'accent mis sur les fonctions de recherche (qui sont absentes de beaucoup de services de stockage), notamment par le biais d'étiquettes attachées aux photos. On peut ainsi retrouver, parmi des myriades de photos, celles qui concernaient saint-quentin-en-yvelines ou lascaux. Ces services ont en général également des moyens d'organisation des photos (en « albums » ou « galeries », analogues à ce que fournit un système de fichiers).
Ces services fournissent la plupart du temps des moyens de désigner les photos comme privées (personnelles) ou publiques et, dans certains cas, comme limitées à un ensemble de personnes. À noter que le RFC n'évoque pas un problème sérieux du stockage en ligne : le fait que rien n'est privé pour l'opérateur du service. On peut toujours marquer ses données comme privé, l'opérateur y a quand même accès (ainsi que la police et la justice de son pays).
Le RFC n'hésite pas à mélanger technologies très nouvelles (et souvent très expérimentales) et très anciennes. Usenet a ainsi sa section. C'est un système de distribution de messages, rangés hiérarchiquement par sujet (cf. RFC 5537). Ces messages sont automatiquement recopiés entre tous les serveurs Usenet qui participent à ce réseau. L'utilisateur final peut alors y accéder via un protocole comme NNTP. Usenet était donc du P2P longtemps avant que ce terme ne soit à la mode. Si Usenet semble nettement sur le déclin aujourd'hui, il reste un des plus importants exemples de distribution efficace de contenu sur le réseau.
En tant que système de stockage en ligne, Usenet permet de lire et d'écrire (on dit to post), et, dans une mesure très limitée, de détruire des messages (avec l'opération cancel).
S'il y a les caches pair à pair, un autre type de cache largement déployé est le cache Web, qui fait l'objet d'une analyse dans ce RFC. L'idée est surtout d'économiser de la capacité réseau (et de gagner en latence), et le cache Web est donc en général mis en œuvre par le FAI ou par les administrateurs du réseau local. Le protocole HTTP dispose de tout un tas d'options pour contrôler finement le niveau de « cachage ». Le logiciel libre le plus répandu pour cette tâche est Squid.
Ce service ne donne accès aux utilisateurs qu'en lecture, l'écriture est faite automatiquement, comme conséquence de la lecture.
Après ce long catalogue de systèmes très variés, la section 4.15 fait le point : est-ce que DECADE a trouvé ce qu'il cherchait ? La plupart de ces services sont nettement plus client-serveur que pair à pair. Et beaucoup sont spécifiques au « cachage », pas au stockage à long terme (un cache peut toujours perdre des données, par exemple, elles seront récupérées sur le site originel). Pour ces raisons et pour d'autres, il est probable que DECADE devra développer son propre service.
Après l'examen des services, la seection 5 du RFC porte sur un examen des protocoles. Quels protocoles existants pourraient être utiles pour DECADE ? Le premier examiné est bien sûr HTTP (RFC 7230). S'il est surtout connu pour ses fonctions de lecture (téléchargement de ressources Web), HTTP peut servir à bien d'autres choses, à développer des applications REST ou à écrire du contenu nouveau sur le serveur. Un des gros avantages de HTTP est évidemment que les logiciels clients sont déjà disponibles, du navigateur Web au programme en ligne de commande comme cURL, en passant par des bibliothèques pour tous les langages de programmation.
HTTP permet donc les fonctions d'accès aux données (opérations
GET
, PUT
, etc), de gestion
des données
(le RFC fait une erreur en disant qu'il n'y en a pas, ce qui oublie
DELETE
, section 4.3.5 du RFC 7231) et de contrôle d'accès (accès public, ou
accès restreint après authentification). Les données sont nommées « ressources » et sont souvent des fichiers. HTTP étant client-serveur, il
ne convient pas parfaitement à DECADE, qui met plutôt l'accent sur le
pair à pair.
HTTP a servi de base à d'autres protocoles. Pour l'accès aux données en ligne, on pense évidemment à WebDAV (RFC 4918). C'est une extension de HTTP qui lui ajoute des fonctions comme le verrouillage ou comme le regroupement des ressources en collections, qu'on peut gérer collectivement. Ces collections font que le modèle de données de WebDAV devient très proche de celui d'un modèle « système de fichiers ».
WebDAV a également une extension pour avoir des ACL, le RFC 3744. Par contre, il n'est pas évident que ce mécanisme de gestion des droits passe à l'échelle, dans le contexte de l'Internet entier.
Autre protocole d'accès à du stockage en ligne, iSCSI, normalisé dans le RFC 7143. En gros, il s'agit d'un protocole permettant l'envoi de commandes SCSI au dessus de TCP, vers des périphériques de stockage comme des disques durs. iSCSI est typiquement un outil pour réaliser des SAN, bien qu'il puisse aussi servir au dessus de l'Internet (par exemple avec les services de nommage du RFC 4171).
iSCSI fournit des opérations de lecture et d'écriture sur des blocs de données (qui correspondent en général aux blocs du disque dur). iSCSI est de très bas niveau et aucun développeur d'applications n'aurait envie de travailler directement avec ce protocole. En réseau local, on utilise plutôt NFS, dont les dernières versions (RFC 8881) disposent de ce qu'il faut pour travailler sur l'Internet.
NFS fournit des opérations de lecture, d'écriture, de gestion (destruction, renommage) de fichiers. Il a des mécanismes de contrôle d'accès qui se sont particulièrement perfectionnés avec sa version 4, qui a amené les ACL.
Par contre, il n'est pas du tout évident qu'il puisse servir dans un service pair à pair de grande taille, notamment vue la rigidité de certains de ses mécanismes de sécurité (même problème qu'avec WebDAV).
Le dernier protocole envisagé, OAuth (RFC 5849) n'est pas vraiment un protocole d'accès à du stockage en ligne. S'il est mentionné ici, c'est parce qu'il fournit un modèle intéressant pour le contrôle d'accès à ces services de stockage. Les modèles traditionnels n'avaient que deux acteurs, le client et le serveur. Le serveur autorisait (ou pas) le client à accéder aux données. OAuth introduit un troisième acteur, le titulaire des données. Celui-ci peut donner une autorisation d'accès à un client tiers, sans lui fournir pour autant toutes ses lettres de créance (mots de passe, clés privées, etc). OAuth permet donc de déléguer l'accès.
Que peut-on synthétiser de l'examen de ces protocoles ? Ils sont surtout conçus pour du client-serveur (bien que certains puissent être adaptés au pair à pair). Et HTTP est tellement répandu et bien connu qu'il peut fournir un bon point de départ à DECADE. Par contre, aucun de ces protocoles ne prend en compte la nécessité d'accès avec faible latence, qui est nécessaire pour la diffusion de vidéo en streaming.
Enfin, si presque tous les protocoles fournissent les mécanismes de base, comme lire et écrire, la grande majorité n'a aucun mécanisme de contrôle de l'allocation des ressources, un des objectifs de DECADE (il s'agit de permettre un accès à ses ressources, sans que les pairs ne puissent tout consommer).
Bref, résume la section 6, conclusion de ce RFC, s'il existe de nombreux systèmes de stockage en ligne, ils ont été conçus avec un cahier des charges très différent de celui de DECADE (l'exemple le plus net étant leur conception client-serveur et pas pair à pair). Aucun ne peut donc être choisi tel quel pour le projet.
Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : A. Clark (Telchemy Incorporated), B. Claise (Cisco Systems)
Réalisé dans le cadre du groupe de travail IETF pmol
Première rédaction de cet article le 6 octobre 2011
Le groupe de travail IETF PMOL était chargé de travailler à la définition de métriques de haut niveau, proche de l'utilisateur (le groupe IPPM s'occupant, lui, des couches plus basses). Désormais fermé, il condense son expérience dans ce RFC, qui explique comment définir de nouvelles métriques, comme PMOL l'avait fait dans les RFC 5814 sur MPLS et RFC 6076 sur SIP. La section 3 résume ce but de ce RFC, définir un cadre utile.
La section 1 rappelle l'importance de la mesure, pour pouvoir améliorer les performances d'un système. Pour que ces mesures soient vraiment efficaces, il faut qu'elles s'appuient sur des métriques normalisées, une métrique étant une définition rigoureuse de la grandeur qu'on veut mesurer. Il faut aussi définir une méthode concrète pour faire la mesure et un format pour publier cette mesure. Pour les métriques « applicatives » de PMOL, ces mesures concernent des choses comme le temps de transfert d'un fichier, le temps de réponse d'un serveur DNS à une requête, etc (section 2.3).
Comme la plupart des RFC, on commence avec un peu de terminologie (section 2). D'abord, l'IETF aura désormais une Direction des Performances (Performance Metrics Directorate). C'est quoi ? Comme les autres Directions, c'est un organe transversal, composé d'experts du domaine, qui doit garder un œil sur tout travail IETF lié à la définition de métriques de performance. Ensuite, le RFC définit la qualité de service (QoS pour Quality of service) et la qualité du vécu (QoE pour Quality of Experience). J'ai déjà écrit sur la différence entre QoS et QoE et je trouve les définitions du RFC très embrouillées, et ne permettant pas de saisir la différence entre les deux concepts (la QoE vient d'une norme UIT, la E.800). Heureusement, la section 4 clarifie cette question. En gros, la QoS est une mesure scientifique de paramètres qui influencent le service rendu (par exemple, la latence ou la gigue), la QoE est la vision de l'utilisateur, qui peut être influencée par divers facteurs, y compris psychologiques. Bien sûr, la QoE va dépendre en partie de la QoS (par exemple, un taux de perte de paquets élevé va sérieusement baisser le débit TCP atteignable) mais le lien n'est pas évident (la norme UIT P.800 donne un exemple de reconstruction de QoE à partir de la QoS). Il y a aussi des facteurs techniques à la différence entre QoS et QoE, comme l'application utilisée : elle peut, indépendamment du bon ou mauvais comportement du réseau, influencer la QoE. Il y a enfin le contexte : tel problème de VoIP passera inaperçu pendant une communication de bavardage mais sera intolérable s'il s'agit d'un appel d'urgence.
La section 5 est le cœur du RFC, les conseils concrets sur la définition de nouvelles métriques. Premier point, déterminer le public visé (section 5.1). Qui va utiliser la métrique et pourquoi ? Est-elle destinée au laboratoire ou bien aux mesures sur des réseaux de production ? Quelle degré d'approxmation peut être accepté ? Et autres questions fondamentales.
Ensuite, la métrique elle-même (section 5.2). Pour qu'elle soit utile, il faut étudier si son absence causerait une sérieuse perte d'information, et si elle est corrélée au vécu de l'utilisateur (par exemple, un taux de pertes élevé - cf. RFC 7680 - entraine une baisse très nette de la capacité du « tuyau » TCP, attristant ainsi l'utilisateur). Mais certaines applications peuvent tolérer des pertes isolées tout en étant intolérantes à des moments de pertes massives. Dans ce cas, une meilleure métrique incluerait non seulement le taux de pertes moyen, mais sa distribution dans le temps (voir par exemple le RFC 3611).
Les grandeurs ne sont pas toujours mesurées, elles peuvent aussi être calculées à partir d'autres grandeurs (section 5.3). On trouve ainsi des compositions spatiales de métriques (RFC 5835, RFC 6049), comme lorsqu'on déduit le taux de pertes sur un chemin en faisant le produit du pourcentage de paquets qui passent, sur toutes les composantes du chemin. Il y a aussi des compositions temporelles (RFC 5835), par exemple le calcul d'un minimum en prenant le plus petit résultat d'une série de mesures.
Une fois qu'un a bien défini ce qu'on voulait, on peut écrire la spécification de la métrique (section 5.4). Il faut un nom (mais voir le RFC 6248 qui explique pourquoi il n'y a plus de registre de ces noms), une description (qui inclus les critères d'utilité présentés plus haut), une méthode de mesure, les unités de mesure, et des indications sur le choix des points de mesure (le temps de réponse à une requête SIP n'est pas le même sur l'UAC (logiciel client, le softphone) et l'UAS (logiciel serveur du fournisseur SI de l'abonné). La méthode de mesure doit permettre de répondre aux questions-pièges. Par exemple, la métrique « taux de perte de paquets » semble triviale à définir. On retire de 1 le résultat de la division du nombre de paquets arrivés par le nombre de paquets envoyés. Mais cette définition sommaire est insuffisante. Si des paquets sont dupliqués (c'est possible avec IP), comment les traite-t-on ? Et, pour compter le nombre de paquets arrivés, on les attend combien de temps ? Un retardataire est-il une perte (voir aussi la section 5.5.2) ? Un autre exemple est que la méthode de mesure peut décider délibérement d'éliminer les outliers, ces valeurs très éloignées de la moyenne, qui sont fréquentes sur les réseaux informatiques. C'est ainsi que les opérateurs Internet font en général payer leurs clients en « 95 percentile » (on élimine 5 % de valeurs qui sortent trop du rang, les outliers).
Outre ces points essentiels de la spécification, la définition d'une métrique peut aussi inclure une mise en œuvre (par exemple sous forme de code), des valeurs attendues pour certains cas (pour évaluer la qualité du résultat), etc. Plus délicat, la définition peut inclure des indications sur l'usage de la métrique, par exemple sur les valeurs « raisonnables ». Un utilisateur typique à qui on dit qu'il y a « 1 % de pertes » sur le réseau ne sait pas forcément quoi en faire. Lui dire que les performances de TCP commencent à baisser sérieusement dès 0,5 % de pertes, serait plus utile. De même, annoncer dans un système de transport de la voix un niveau sonore de -7 dBm0 n'est guère utile à l'utilisateur non expert en téléphonie si on n'ajoute pas que les valeurs normales sont entre -18 et -28 dBm0 et que le son est donc ici bien trop fort.
Notre RFC 6390 fournit un exemple complet de définition d'une métrique, en prenant le taux de perte du RFC 3611 comme exemple. Notez que cette définition est un peu floue quant au sort des paquets arrivant tardivement.
Dans le monde réel, aucune mesure n'est parfaite : divers problèmes limitent la qualité des mesures effectuées. La section 5.5 décrit ces problèmes : précision de l'horloge, présence ou non d'une middlebox (RFC 3303) qui fausse les résultats, etc.
Et enfin, la métrique ainsi normalisée doit préciser les différents paramètres utilisés, pour que les utilisateurs puissent comparer deux mesures différentes.
La section 6 est plutôt orientée vers le processus social de développement d'une nouvelle métrique : si on a une idée d'une métrique à normaliser, comment agir dans l'IETF pour augmenter les chances de succès ? Elle insiste par exemple sur la check-list des caractéristiques à vérifier (la métrique est-elle bien définie, par exemple) et sur la rôle de la Direction des Performances, qui va évaluer le futur RFC.
Un peu d'histoire (section 1.1): l'IETF avait déjà travaillé, dans des temps anciens, sur des métriques pour les applications. Ce furent le RFC 4710, centré sur les terminaux mobiles, ou les RFC 3611 ou RFC 6035 sur la téléphonie. Mais, pendant longtemps, les principales métriques développées étaient uniquement pour les couches 3 et 4. Notre RFC 6390 vise donc à élargir le bestiaire des métriques.
Date de publication du RFC : Novembre 2011
Auteur(s) du RFC : J. Bankoski, J. Koleszar, L. Quillio, J. Salonen, P. Wilkins, Y. Xu (Google)
Pour information
Première rédaction de cet article le 11 novembre 2011
Le monde des formats vidéo est très hostile pour ceux qui apprécient la liberté et l'ouverture : formats privés, non documentés, contrôlés par une seule compagnie, plombé de brevets tous plus futiles les uns que les autres... Aujourd'hui, il est à peu près impossible de regarder une vidéo, quelle qu'elle soit, avec du logiciel entièrement libre, et sans enfreindre une centaine de brevets. Ce RFC documente un des très rares codecs vidéos ouverts, qui puisse être mis en œuvre dans du logiciel libre sans trop de crainte juridique. Il a été produit par Google, documenté pour l'IETF et se nomme VP8.
Lorsqu'on configure une machine utilisant du logiciel libre aujourd'hui, si on s'en tient strictement à ses principes, et qu'on refuse d'intégrer les sources de logiciel que Debian ou Ubuntu marquent comme non-libres, on n'arrivera pas à voir beaucoup de films... Même si le format du container vidéo est relativement ouvert, les techniques de compression ne le sont pas et on constate vite que son MPlayer ou son vlc n'arrivent pas à lire grand'chose. (C'est particulièrement vrai pour les films achetés légalement, pour lesquels l'usage de formats fermés sert de DRM. Les films partagés gratuitement sur le réseau réservent en général moins de mauvaises surprises.) Le problème de la personne qui produit le film est le manque de formats ouverts dans ce domaine. Le principal est Ogg (avec le codec vidéo Theora) mais les experts lui reprochent des performances en compression et décompression qui ne sont pas extraordinaires. Google prétend avoir une solution, son format VP8 (avec le format de container WebM), supposé bien meilleur (il a été développé à l'origine par On2). Mais utiliser un format spécifique à Google n'est pas mieux qu'utiliser un format spécifique à Adobe. Alors, Google a produit un RFC, soumis à l'IETF (en termes IETF, c'est une « soumission indépendante », pas le résutat d'un groupe de travail IETF) et qui devient donc un format ouvert, libre de la compagnie qui lui a donné naissance. Ce RFC inclut également une mise en œuvre de référence du décodeur, distribuée sous une licence libre (la BSD, cf. section 20.26).
La question des brevets est traditionnellement une de celles qui plombent le plus les projets de codecs ouverts. La section 20.27 décrit en détail la situation pour VP8. Google promet une licence gratuite d'exploitation de ses brevets pour toute implémentation de VP8. Mais il n'est pas clair, pour un non-juriste, si cela couvre la possibilité de versions ultérieures de VP8, qui ne seraient pas approuvées par Google. En attendant, pas mal de requins pourraient attaquer VP8. (Un bon article de synthèse est « Video codecs: The ugly business behind pretty pictures ».)
Ce RFC 6386 est essentiellement composé de code. VP8 est en effet défini par son implémentation de référence (la libvpx), le texte n'étant là que pour expliquer. Le RFC note bien (section 1) que, s'il y a une contradiction entre le code et le texte, c'est le code qui a raison (choix inhabituel à l'IETF). Avec ses 310 pages, c'est un des plus longs RFC existants. Je ne vais donc pas le traiter dans sa totalité, d'autant plus que les codecs vidéos ne sont pas ma spécialité.
Donc, en simplifiant à l'extrême, VP8 décompose chaque image d'un flux vidéo en une série de sous-blocs, chacun des sous-blocs étant composé de pixels. La compression d'un sous-bloc dépend des sous-blocs précédents, pour bénéficier de la redondance temporelle de la vidéo (sauf dans les films avec Bruce Willis, il y a relativement peu de changements d'une image à la suivante, et en général sur une partie de l'image seulement). Il y a aussi une redondance spatiale (des parties de l'image qui sont répétées, par exemple un grand ciel noir pour les scènes de nuit). La technique de compression se nomme transformée en cosinus discrète, mais VP8 utilise également à certains endroits une autre technique, la transformée de Walsh-Hadamard. VP8 ne permet pas de reconstituer exactement les pixels originaux, il compte sur la tolérance de l'œil humain (qui peut accepter certains changements sans tiquer).
Contrairement à son concurrent MPEG, VP8 encode et décode uniquement avec des nombres entiers et ne perd donc pas de précision dans les calculs en virgule flottante. Ces pertes peuvent parfois provoquer des effets surprenants, visibles à l'écran (rappelez-vous que, dans l'arithmétique en virgule flottante, il y a moins d'assertions vérifiables. Par exemple, 1 - x + x n'est pas forcément égal à 1).
La section 2 du RFC expose les grandes lignes du format :
utilisation de l'espace YUV en 4:2:0 8bits, c'est-à-dire
que chaque pixel dans les deux plans chromatiques (U et V) fait huit
bits et correspond à un bloc de quatre pixels dans le plan de lumière Y. Les
pixels sont ensuite transmis en lignes, de haut en bas, chaque ligne
étant transmise de gauche à droite. Les informations permettant le
décodage ne sont pas au niveau du pixel mais à celui de
blocs de pixels. Dans l'implémentation de référence, la description du
format se trouve dans le fichier d'en-tête
vpx_image.h
.
Une fois comprimées, il y a deux types de trames dans un flux VP8 (section 3) : les intratrames (ou trames clés, ce que MPEG appelle les trames-I) sont complètes et n'ont pas besoin d'autres trames pour être décodées. La première trame envoyée est évidemment une intratrame. Et le deuxième type sont les intertrame (trames-P chez MPEG), qui codent une différence par rapport à la précédente intratrame, et aux autres intertrames arrivées entre temps. La perte d'une intertrame empêche donc de décoder les suivantes, jusqu'à l'arrivée de la prochaine intratrame, qui permettra au décodeur de repartir d'un état connu.
À noter que, contrairement à MPEG, il n'y a pas de trame-B, trame permettant d'indiquer le futur. En revanche, VP8 a des « trames en or » et des « trames de référence de secours » qui sont des intertrames contenant suffisamment d'informations pour permettre de reconstituer les quelques trames suivantes. Elles permettent à VP8 d'être plus tolérant aux pertes de trame (normalement, lorsqu'un perd une intratrame, il n'y a rien d'autre à faire qu'à attendre la suivante).
Le format des trames compressées est décrit en section 4. Un
en-tête (plus grand dans le cas des intratrames), et les données. Bon,
en fait, c'est un peu plus compliqué que cela car, au sein des données, les macroblocs ont
aussi leur en-tête. Pour décoder (section 5), le programme doit garder
quatre tampons YUV : la trame actuellement en
cours de reconstruction, la trame précédente (rappelez-vous que les
intertrames sont uniquement des différences par rapport à la trame
précédente, qu'il faut donc garder en mémoire), et les plus récentes
trames en or et de référence de secours. Le principe est simple (on
réapplique les différences à la trame de référence, obtenant ainsi la
trame originale), mais il y plein de pièges, dus par exemple à
l'abondance du contexte à maintenir (puisque le décodage dépend du
contexte en cours). Le code se trouve dans
dixie.c
dans le RFC (l'implémentation de référence a été réorganisée et ce fichier n'y figure plus). Une façon de simplifier l'écriture d'un
décodeur est de commencer par ne programmer que le décodage des intratrames, avant
d'ajouter celui des trames intermdiaires. C'est d'ailleurs le plan que
choisit le RFC.
Le langage de l'implémentation de référence est le
C. Comme le note la section 6, c'est en raison
de sa disponibilité universelle et de sa capacité à décrire exactement
la précision des calculs qu'il a été choisi. Notez que le code C dans
le RFC n'est pas exactement celui de
l'implémentation de référence (qui est, elle, disponible en http://www.webmproject.org/code/
). Plusieurs raisons à cela, notamment le fait que l'implémentation de
référence a été optimisée pour la performance, le code dans le RFC
pour la lisibilité, Mais les deux codes produisent le même
résultat. Rappelons enfin que VP8 n'utilise pas de
flottants, seulement des entiers.
Le code commence en section 7, avec le décodeur booléen. L'idée est que l'encodage est fait en produisant une série de booléens, avec pour chacun une probabilité d'être à zéro ou à un. Si la probabilité était de 0,5, aucune compression ne serait possible (il faudrait indiquer explicitement tous les booléens) mais ici, les probabilités sont souvent très éloignées de 0,5 (en raison des cohérences spatiales et temporelles du flux vidéo) et VP8 consomme donc moins d'un bit par booléen. Travailler sur bits étant typiquement peu efficace sur la plupart des processeurs, le code en section 7.3 les regroupe en octets.
Le reste du RFC est essentiellement composé de code C avec commentaires. Je saute directement à la section 19 / annexe A qui donne la liste complète des données encodées, Tous les objets manipulés par VP8 sont là.
Notez que le projet parent, WebM, utilise actuellement Vorbis pour l'audio (VP8 ne faisant que la vidéo). L'IETF a un projet de développement d'un codec audio, les détails figurent dans le RFC 6366.
Pour plus d'information, on peut consulter le site officiel du projet WebM qui contient entre autres une liste des outils disponibles. Pour le déploiement de WebM, on peut voir la page du Wikipédia anglophone. Une analyse (critique) de VP8 a été faite par Jason Garnett-Glaser.
Parmi les autres mises en œuvre de VP8, un cas curieux, un décodeur en JavaScript...
Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : M. Barnes (Polycom), A. Doria (Lulea University of Technology), H. Alvestrand (Google), B. Carpenter (University of Auckland)
Pour information
Première rédaction de cet article le 19 octobre 2011
Comme souvent à l'IETF, les expériences les plus réussies ne sont pas documentées, ou alors le sont longtemps après. Les examens des Internet-Drafts par Gen-ART (General Area Review Team) ont commencé en 2004 mais viennent juste d'être formalisées. Gen-ART, dont l'expérience est décrite dans ce nouveau RFC, est un groupe d'experts volontaires qui regardent les Internet-Drafts lorsqu'ils sont prêts de devenir un RFC. Le terme de « Gen-ART » apparait de plus en plus souvent dans les discussions à l'IETF, mais que recouvre-t-il exactement ?
Les procédures de l'IETF sont loin d'être toutes documentées. Il y a la théorie, et la pratique. Par exemple, l'IESG est censée examiner les Internet-Drafts avant leur publication au cours de ses réunions à distance, les telechats. Mais la quantité de documents à examiner est telle que toute aide est la bienvenue. Un groupe de volontaires s'est donc constitué et s'est mis tout seul (rappellons que tout le processus IETF est public, il n'y a pas besoin d'une autorisation spéciale pour créer un groupe, lire des documents et publier les résultats) à lire les documents qui allaient passer à l'IESG, pour débrousailler le tas de papier. Ce RFC est le compte-rendu de l'expérience de ce groupe, qui prend désormais de plus en plus de place, au point que certains croient même qu'il s'agit d'un projet officiel.
La section 1 du RFC résume d'où vient Gen-ART, et insiste sur ce caractère non officiel. Gen-ART fait ce que tout le monde a le droit de faire : lire les Internet-Drafts (ils sont publics) et les commenter publiquement. Son autorité est purement morale, provenant de la qualité de ses examens et du prestige de ses membres.
La section 2 est consacrée à ces membres : un groupe d'experts auto-désignés, en général auteurs de plusieurs RFC, et expérimentés dans la normalisation IETF. La section 12 donne la liste actuelle (qu'on trouve aussi en ligne). Bien que le RFC n'en parle pas, on peut noter que la relecture est parfois faite par un autre membre de l'IETF, sur délégation d'un membre de Gen-ART (évidemment en toute transparence). C'est ainsi que j'ai fait ma première (et unique, pour l'instant) revue Gen-ART, en décembre 2010, comme délégué de Francis Dupont. Il s'agissait du document draft-cheshire-dnsext-dns-sd, très contesté (ma conclusion était peu favorable, et le document est toujours, aujourd'hui, en discussion). L'auteur avait répondu à mon analyse.
La section 3 résume ensuite le but poursuivi par Gen-ART : décharger l'IESG d'une partie du fardeau (parfois vingt Internet-Drafts en un seul telechat), de façon à ce que l'examen de l'IESG puisse se concentrer sur les quelques documents à problème, en ignorant la majorité qui va bien. Bien qu'il existe tout un tas de comités et de groupes à l'IETF, personne ne vise cette tâche à part Gen-ART.
La section 4 décrit comment fonctionne Gen-ART, quels documents sont relus, et qu'est-ce que produit Gen-ART. Le rapport final indique si l'Internet-Draft :
Les critères pour décider sont ceux classiquement utilisés à l'IETF :
Gen-ART étant issu de la « zone générale » (General Area, celle qui s'occupe de tout ce qui ne rentre pas dans une catégorie particulière), le groupe de relecteurs fait notamment attention à tout ce qui n'est pas sous la responsabilité d'une autre zone. Par exemple, dans un Internet-Draft sur un nouveau protocole de routage, on peut supposer que la zone Routage (Routing Area) s'est occupé de la qualité technique du protocole. Cela laisse donc à vérifier, un tas de choses, certaines de haut niveau et d'autres triviales. Le RFC cite, entre autres :
La section 4 décrit ensuite le processus suivi lors des relectures. Il faut notamment noter que les RFC ne sont pas affectés aux relecteurs en fonction de leur spécialité : le but étant d'avoir un regard général, un expert en sécurité peut se retrouver avec un Internet-Draft sur le routage. Le processus bureaucratique, lui (maintien de la liste des relecteurs, détails très précis sur les conditions d'affectation d'un document à un relecteur), est en section 5.
Quels sont les résultats de Gen-ART ? La section 6 fait le bilan : environ 2 000 relectures ont été faites en sept ans, avec une équipe comportant environ douze relecteurs, chacun recevant plus d'un Internet-Draft par mois. Ces relectures ont permis de faire passer le pourcentage de documents considérés comme « prêts pour publication » au moment du telechat IESG de 25 % à 75 %.
Par delà les chiffres, quel est le ressenti des participants ? La section 7 rassemble tout un tas de témoignages très variés, notant par exemple que la qualité moyenne est bonne mais que Gen-ART a déjà servi à arrêter de très mauvais documents.
Mais le mécanisme des relectures Gen-ART est-il parfait ? La section 8 propose de l'améliorer, notant les points faibles. Le principal est l'absence presque complète d'automatisation. Gen-ART n'a actuellement pas d'outils spécialisés (un des buts de la section 5 était, en décrivant précisement le processus, de faciliter l'écriture d'un cahier des charges pour le développement de ces outils).
Vous pouvez aussi visiter le site Web de Gen-ART et prendre connaissance de sa FAQ.
Date de publication du RFC : Octobre 2011
Auteur(s) du RFC : Danny McPherson, Ryan Donnelly, Frank Scalzo (Verisign)
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 25 octobre 2011
Dernière mise à jour le 26 octobre 2011
Ce court RFC propose un changement radical dans la gestion des annonces BGP par les services anycastés. Actuellement, ils utilisent presque tous un seul numéro d'AS pour tous les nœuds d'un nuage anycast. Notre RFC 6382, au contraire, suggère d'utiliser un numéro d'AS par nœud.
Comme l'explique la section 2 de notre RFC,
l'anycast (RFC 4786) est désormais une
technique banale. Elle permet notamment d'augmenter sérieusement la
résistance aux dDoS. Dans le monde du
DNS, l'anycast est
particulièrement répandu (par exemple,
.fr
n'a plus que deux
serveurs unicasts, tous les autres sont
anycastés).
L'anycast fonctionnant en injectant la même route, via BGP, depuis des points différents du réseau, on peut se demander s'il faut que tous ces points annonçent le préfixe depuis le même AS, ou bien si chacun doit utiliser un AS différent ? Aujourd'hui, la quasi-totalité des services anycastés utilisent un seul numéro d'AS pour tous leurs points de présence (POP). VeriSign (la boîte des auteurs du RFC) est un des rares acteurs à le faire, pour certains de leurs serveurs. Cela a notamment l'avantage de préserver une ressource rare : les numéros d'AS n'étaient codés que sur seize bits. Cela facilite également la configuraion des routeurs. Et, aujourd'hui, cela évite des ennuis avec les systèmes d'alarme BGP, qui pourraient couiner en voyant le même préfixe avoir plusieurs AS d'origine. Hurricane Electric fournit ainsi une liste des préfixes annoncés par plusieurs AS. Même chose chez Cymru. Comme illustré par un exposé à NANOG en 2001, c'était plutôt considéré comme une erreur.
Mais cette politique a aussi des défauts : lorsqu'un routeur BGP
voit arriver une annonce pour un préfixe anycasté,
il ne sait pas exactement de quel nœud elle vient. Cela peut
compliquer le débogage des problèmes. Certains services ont un
mécanisme pour identifier le serveur (RFC 5001
pour le DNS, ou bien le traditionnel quoique non normalisé
hostname.bind
dans la classe
CH
). Et, évidemment, on peut toujours utiliser
traceroute pour trouver où se trouve telle
instance anycast. Essayons avec un serveur DNS
anycasté, d.nic.fr
, depuis une
machine située dans le Missouri :
% dig +nsid @d.nic.fr SOA fr. ... ; NSID: 64 6e 73 2e 6c 79 6e 32 2e 6e 69 63 2e 66 72 (d) (n) (s) (.) (l) (y) (n) (2) (.) (n) (i) (c) (.) (f) (r) ...
C'est donc dns.lyn2.nic.fr
qui a répondu.
Et on confirme (l'AFNIC utilise les Locodes pour nommer ses machines, donc LYN = Lyon) qu'on touche l'instance de
Lyon (cette machine a surtout des instances
en métropole et dans les DOM-TOM et aucune aux États-Unis) :
# tcptraceroute d.nic.fr 53 Selected device eth0, address 208.75.84.80, port 43778 for outgoing packets Tracing the path to d.nic.fr (194.0.9.1) on TCP port 53 (domain), 30 hops max 1 208.75.84.1 0.000 ms 0.000 ms 0.000 ms 2 host123.datotel.com (208.75.82.123) 0.000 ms 0.000 ms 0.000 ms 3 stl-c1-g1-15.datotel.com (208.82.151.29) 10.000 ms 0.000 ms 0.000 ms 4 stl-e2-g0-2.datotel.com (208.82.151.13) 0.000 ms 0.000 ms 0.000 ms 5 vlan100.car2.StLouis1.Level3.net (4.53.162.121) 0.000 ms 0.000 ms 0.000 ms 6 ae-4-4.ebr2.Chicago1.Level3.net (4.69.132.190) 10.000 ms 9.999 ms 10.000 ms 7 ae-5-5.ebr2.Chicago2.Level3.net (4.69.140.194) 0.000 ms 9.999 ms 9.999 ms 8 ae-6-6.ebr2.Washington12.Level3.net (4.69.148.145) 10.000 ms 19.999 ms 19.999 ms 9 ae-5-5.ebr2.Washington1.Level3.net (4.69.143.221) 19.999 ms 19.999 ms 29.998 ms 10 ae-44-44.ebr2.Paris1.Level3.net (4.69.137.61) 89.994 ms 99.994 ms 109.994 ms 11 ae-22-52.car2.Paris1.Level3.net (4.69.139.227) 109.994 ms 99.994 ms 99.994 ms 12 JAGUAR-NETW.car2.Paris1.Level3.net (212.73.207.162) 109.993 ms 99.995 ms 99.994 ms 13 dns.lyn2.afnic.cust.jaguar-network.net (78.153.224.126) 119.993 ms 119.993 ms 139.992 ms 14 d.nic.fr (194.0.9.1) [open] 109.994 ms 119.993 ms 109.993 ms
Les machines de l'AFNIC ayant un enregistrement DNS indiquant leur position physique (RFC 1876), on peut même être plus précis :
% dig LOC dns.lyn2.nic.fr ... dns.lyn2.nic.fr. 172800 IN LOC 45 43 20.568 N 4 51 39.816 E 1.00m 1m 10m 10m
et on sait alors où est la machine.
Autre essai, avec un serveur de la racine du DNS,
L.root-servers.net
, largement
anycasté. Depuis un fournisseur en France :
% dig +nsid @l.root-servers.net SOA . ... ; NSID: 6c 79 73 30 31 2e 6c 2e 72 6f 6f 74 2d 73 65 72 76 65 72 73 2e 6f 72 67 (l) (y) (s) (0) (1) (.) (l) (.) (r) (o) (o) (t) ( -) (s) (e) (r) (v) (e) (r) (s) (.) (o) (r) (g)
On touche lys01.l.root-servers.org
. Comme son
opérateur, l'ICANN, utilise (comme beaucoup),
les codes aéroport pour nommer les machines, on
voit qu'elle est également à Lyon (LYS est l'aéroport de
cette ville). Depuis une machine d'un autre
FAI français, la même requête renvoie
lux01.l.root-servers.org
, ce qui situe le
nœud anycast au Luxembourg. Et, en testant depuis la
machine missourienne citée plus haut, on atteint
lax12.l.root-servers.org
soit Los Angeles.
Ces techniques sont toutefois imparfaites. Or, les services anycast ont des vulnérabilités paticulières. Par exemple, l'injection de routes pirates dans BGP par un méchant est plus difficile à détecter (cf. section 5). L'anycast a besoin d'outils de débogage puissants, pour venir à bout des problèmes de routage, volontaires ou involontaires, qui peuvent se manifester. Pire, on peut avoir des cas où les différentes instances d'un même nuage anycast ne répondent pas exactement la même chose, et il est dans ce cas crucial de pouvoir identifier sans aucune ambiguïté celles qui sont différentes.
Avant la recommandation officielle, un petit détour de terminologie (section 1). Parmi les termes importants (lire le RFC 4786 pour plus de détails) :
no-export
). La recommandation de
ce RFC s'applique à tous les nœuds, locaux ou globaux,Venons-en maintenant à la nouveauté de ce RFC. Il tient en une
phrase (section 3), « Il faudrait utiliser un numéro d'AS
différent par nœud ». Le but est de fournir un
mécanisme discriminant les annonces. Si on a deux nœuds, un en
Chine (AS 65536) et un en Europe (AS 65551), et qu'on voit le préfixe
anycast 192.0.2.64/26
annoncé
depuis l'AS 65536, on sait qu'on s'adressera à l'instance chinoise. On
peut même filtrer sur l'AS d'origine pour éviter cela. L'utilisation de numéros
d'AS différents permettra de choisir sa politique de routage.
Est-ce sans inconvénient ? Actuellement, le principal problème
risque d'être les systèmes d'alarme
qui s'inquiéteraient de ces différentes origines. Ainsi, BGPmon, par défaut, considère qu'une
annonce depuis un autre AS que celui indiqué comme origine, est une
attaque possible (possible hijack) et il alarme. Toutefois, le même BGPmon permet
d'indiquer plusieurs AS d'origine supplémentaire, ce qui lui permet de
gérer la nouvelle politique. (Une société comme
PCH a environ soixante localisations physiques
dans le monde, Netnod en a cent : les enregistrer toutes comme origine possible, auprès
d'un système d'alarme BGP, pourrait être fastidieux. À noter que la
fonction auto-detect de BGPmon simplifie cela : comme
l'explique l'auteur « Just click on the prefix to edit it, then click on
the little green icon next to the 'Additional Origin AS' section.
It will then show a popup with all additional origin ASn's we have in
our database. You can then copy paste that line into the 'Additional
Origin AS' field. ». Un exemple est donné par un serveur de
.com
, m.gtld-servers.net.)
Autre inconvénient possible : la consommation excessive de numéros d'AS. Toutefois, depuis le RFC 4893, ceux-ci peuvent désormais être codés sur 32 bits et le risque d'épuisement disparait.
Après cette nouvelle recommandation de consommer un numéro d'AS par site, la section 4 du RFC rassemble divers conseils aux gérants de services anycast :
LOC
du RFC 1876, peut-être en les attachant au nom obtenu par la
requête NSID),Et la section 6 contient l'examen de divers points pratiques liés au déploiement de cette nouvelle politique. Les opérateurs de services anycast critiques ont été largement consultés avant la publication du RFC, ce qui ne veut pas dire qu'ils déploieront cette recommandation tout de suite (aucun n'a annoncé de plan précis et l'ISC a au contraire annoncé qu'ils ne le feraient pas, voir plus loin leur analyse). En gros, la nouvelle politique fera davantage de travail au début (obtenir les numéros d'AS - ce qui nécessitera probablement un changement dans la politique des RIR, ajouter une colonne pour le numéro d'AS dans la base de données des instances anycast, penser à indiquer le bon numéro d'AS lorsqu'on fait une demande de peering, changer les centaines de peerings existants, etc) mais simplifiera la surveillance du service, en permettant de trouver plus facilement l'origine d'une annonce.
Et pour finir, un exemple de ce que donne un excellent outil
d'analyse existant, le RIS, avec le serveur de
.com
déjà cité (annoncé par trois AS) : http://www.ris.ripe.net/dashboard/192.55.83.0/24
.
Pour avoir un autre point de vue, l'ISC a expliqué le fonctionnement de l'anycast chez eux, une explication détaillée de la supériorité de leur système, ainsi que leur liste de peerings.
Une autre question n'est pas couverte dans le RFC mais mérite une
mention (merci à Olivier Benghozi et Guillaume Barrot pour leurs explications) : pourquoi
n'avoir pas utilisé plutôt les communautés BGP (RFC 1997), des étiquettes qu'on peut attacher aux annonces et
qui sont transitives ? La raison principale est qu'elles sont
fréquemment effacées en entrée des AS (sans compter les systèmes qui,
par défaut, ne les transmettent pas du tout comme
IOS, cf. un
article sur leur utilisation). Même problème avec d'autres attributs facultatifs
de BGP comme AGGREGATOR
(qu'on aurait pu, en le détournant un peu, utiliser à ce but).
Merci à Jean-Philippe Pick pour sa relecture et pour les informations.
Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : M. Kucherawy (Cloudmark)
Réalisé dans le cadre du groupe de travail IETF dkim
Première rédaction de cet article le 22 septembre 2011
La sécurité, c'est compliqué. Ce n'est pas tout de définir des normes techniques comme DKIM, pour sécuriser le courrier électronique. Il faut encore étudier leurs conséquences pour tous les cas. Le courrier électronique ayant débuté il y a très longtemps, et n'ayant pas vraiment été spécifié dans tous les détails (son architecture n'a été officiellement décrite qu'en 2009, avec le RFC 5598), il représente un défi particulier pour tous ceux qui essaient de le sécuriser a posteriori. C'est ainsi que ce nouveau RFC s'attaque au cas particulier des listes de diffusion et étudie comment elles réagissent avec le mécanisme d'authentification DKIM.
D'abord, à quoi sert DKIM ? Normalisé dans le RFC 6376, DKIM permet de signer un message électronique. Sans lui, il
est trivial de fabriquer un faux message (prétendant venir de votre
banque et vous demandant de saisir votre mot de passe sur un
formulaire Web) et il n'y a aucun moyen d'acquérir des
certitudes sur ce message, où (presque) tout peut être faux. Avec
DKIM, un domaine de courrier peut signer le
message et ainsi en prendre la responsabilité. Si le message est signé
par mabanque.example
, vous pouvez être sûr, pas
forcément de sa véracité, mais en tout cas d'un lien avec votre
banque. Contrairement à PGP, conçu pour
authentifier une personne, DKIM permet d'authentifier un domaine qui a
une responsabilité dans l'envoi de ce message.
Mais les listes de diffusion posent des problèmes spécifiques (section 1). DKIM avait été conçu avec l'idée que le message n'était pas modifié en cours de route. S'il l'est, c'est considéré comme une attaque qu'il faut détecter. Or, les gestionnaires de listes de diffusion ne respectent pas ce principe. Par exemple, il est fréquent (bien que ce soit une très mauvaise idée, cf. le RFC 4096) que le sujet soit modifié pour y inclure le nom de la liste entre crochets. De même, l'ajout d'instructions de désabonnement à la fin de chaque message est commun. De telles modifications sont peut-être honnêtes (dans l'esprit de celui qui les a décidés, ce ne sont pas des tentatives de fraude) mais, pour un logiciel de vérification, elles suffisent à invalider la signature.
Si les intermédiaires qui relaient un message le laissaient rigoureusement intact, ce serait non seulement une bonne idée pour les utilisateurs, mais cela permettrait à DKIM de continuer à fonctionner. Comme, parmi les intermédiaires, les MLM (Mailing List Managers) sont souvent les plus intrusifs, que peut faire DKIM pour gérer ce problème ?
Ce RFC ne normalise pas de réponse officielle à ces questions : il explique le problème et pointe du doigt les compromis à faire. La recommandation générale est « dans le cas typique, le MLM a intérêt à signer les messages qu'il relaie, et les vérificateurs à la destination ont intérêt à tenir compte de cette signature ». Le lecteur attentif aura noté que cette recommandation laisse plein de questions ouvertes...
Avant de détailler les problèmes, la fin de la section 1 rappelle
quelques éléments importants sur le courrier
électronique et les MLM (voir le
RFC 5598 pour une présentation générale de
l'architecture du courrier et sa section 5.3 sur les MLM). Les MLM (les gestionnaires de listes de
diffusion) n'ayant jamais fait l'objet d'une normalisation officielle
(le RFC 5598 a été écrit longtemps après), leur
comportement varie énormément. Lorsqu'un MLM fait une opération, il
est bien difficile de trouver un RFC qui dit noir sur blanc s'il est
en droit de la faire ou non. Une notion aussi simple que celle
d'identité (qui est l'auteur du message) n'est
pas évidente et DKIM a donc sagement décidé de ne
pas lier le domaine signant (celui qui est
indiqué par d=
dans une signature DKIM) avec une
des « identités » présentes dans les en-têtes du message. Ainsi, le
domaine signant n'est pas forcément celui présent dans le champ
From:
. Il peut refléter, par exemple, un domaine
qui a relayé le courrier et, en le signant, a affirmé une certaine
responsabilité pour ce message. Donc, si un MLM signe avec son domaine
un message venu d'un autre domaine, cela ne pose
pas de problème : c'est dans l'esprit de DKIM.
C'est l'interprétation qui va poser problème. Si j'écris un message
sur la liste smtp-fr@cru.fr avec mon adresse
professionnelle (bortzmeyer@nic.fr
), qui est
responsable ? L'« auteur », mentionné dans le champ
From:
, ou bien l'ex-CRU, qui
gère le MLM, ou
encore la personne mentionnée (ce terme est d'ailleurs malheureux)
comme « propriétaire » de la liste smtp-fr (aujourd'hui, Christophe Wolfhugel). Selon
le cas, un vérificateur sera plus intéressé par l'un ou l'autre des
responsables.
Je l'ai dit, la normalisation des fonctions des MLM n'a été faite
qu'a posteriori, n'est pas complète, et n'a pas été largement
adoptée. C'est ainsi que des normes comme le champ
List-ID:
(RFC 2929) ou les
en-têtes donnant les mécanismes de désabonnement (RFC 2369) ne sont que partiellement déployés.
Bref, que conseille ce RFC ? Avant d'en arriver aux conseils pratiques, en section 4 et 5, il faut encore bien se mettre à jour sur la terminologie (section 2) et les principes de fonctionnement des MLM (section 3). En section 2, il faut d'abord lire les RFC sur DKIM, le RFC 5585, qui sert d'introduction et le RFC 6376 sur la norme elle-même. Ensuite, notre RFC introduit quelques termes nouveaux comme « gentil avec DKIM » (DKIM-friendly), qui désigne un MLM dont les actions n'invalident pas les signatures DKIM. À noter que cela ne dépend pas que du logiciel mais aussi de sa configuration (si on lui fait ajouter un pied de page en bas de chaque message, les signatures portant sur le corps du message sont invalidées), et des options du signeur (si le MLM modifie le sujet mais que le signeur n'a pas signé le sujet, le MLM sera considéré comme gentil avec DKIM).
Alors, comment fonctionnent les MLM ? Le problème, note la section 3, est qu'il y en a plusieurs sortes. Les différents rôles qui décrivent les acteurs du système de messagerie (auteur, signeur, récepteur, etc) sont évidents lorsque le message est un envoi direct d'Alice à Bob. Mais le MLM perturbe ce bel ordonnancement théorique. Déjà, il y a quatre types de MLM :
Received:
). La section 3.9.2 du RFC 5321 les mentionne. Ils ne changent que l'enveloppe
SMTP, pas le message (en tout cas pas dans les
parties signées). Les alias se mettent typiquement en œuvre sur
Unix dans les fichiers
aliases
(directives
alias_database
et alias_maps
de Postfix). Ces MLM sont gentils avec DKIM et
n'invalident jamais les signatures (on notera que c'est le contraire
avec SPF, RFC 7208,
puisque ce dernier authentifie l'enveloppe et pas le message).multipart/digest
(certains abonnés préfèrent lire
ainsi). Cette synthèse est un nouveau message, mais composé à partir
de messages pré-existants.Dans les deux derniers cas, le MLM crée un nouveau message. Dans le second, le plus difficile, son rôle est moins clair. Si on veut approfondir ces nuances philosophiques, on peut consulter les sections 3.6.4 du RFC 5322 et 3.4.1 du RFC 5598.
Quels sont les effets exacts des MLM sur les messages signés ? La section 3.3 les détaille :
Subject:
) est parfois modifié,
pour ajouter le nom de la liste entre crochets. Cette pratique est
très contestée (personnellement, je ne l'aime pas du tout, car elle
modifie le message pour rien : si on veut trier le courrier, il est
plus simple de le faire automatiquement via
Sieve ou un système équivalent) mais, comme le
note le RFC, contestée ou pas, elle ne va pas disparaître du jour au
lendemain. Comme le sujet est un des éléments les plus importants de
l'en-tête (c'est souvent ce que l'utilisateur regarde en premier) et
qu'il est donc recommandé de le signer, ce comportement des MLM pose
un problème.List-ID:
du RFC 2929 ne posent a priori pas de problème, car ils sont
rarement mis par les MUA et DKIM n'a pas de
problème avec l'ajout de nouveaux champs.Bref, à l'heure actuelle, les MLM sont souvent méchants avec DKIM. Dans le futur, cela évoluera peut-être mais on ne peut pas en être sûr, notamment parce que DKIM n'est pas assez important pour que les programmeurs de MLM changent leurs pratiques juste pour lui.
Une fois ces pratiques des MLM étudiées, le RFC a deux parties de conseils. L'une est consacrée aux MLM qui ne connaissent pas DKIM. Cette section 4 fournit donc des conseils aux signeurs et aux validateurs pour le cas où le message est passé par un tel MLM. L'autre, la section 5, est composée de conseils aux MLM qui connaissent DKIM et veulent bien faire. Voyons d'abord la section 4. Si un message signé va passer par un MLM non-DKIM, que faire ?
Idéalement, si l'auteur sait qu'un message va passer par un MLM non-DKIM, il devrait décider de signer ou pas, selon le comportement du MLM. La signature est risquée car le MLM peut faire une des modifications citées plus haut, rendant la signature invalide et inquiétant les récepteurs. (En théorie, une signature invalide doit être ignorée - RFC 6376, section 6.1 - sauf si le domaine émetteur publie en ADSP une politique plus stricte.) Le problème de cette approche est que l'émetteur ne connaît pas forcément les détails de tous les MLM et autres logiciels par lesquels son message risque de passer. Les administrateurs système qui activent DKIM sur leur infrastructure vont donc devoir décider sans connaître toute l'information. Les politiques strictes de signature et de vérification n'ont donc de sens qu'en cas de contrôle complet de la chaîne entre l'émetteur et le récepteur (ce qui exclut les MLM). Ne mettez donc pas une politique ADSP discardable si le courrier de ce flux de messages risque de passer par un MLM.
Cette absence d'information sur les MLM et autres logiciels intermédiaires touche également les vérificateurs. Une solution possible est d'exclure de la vérification les courriers passés par les listes. Ce serait évidemment un gros travail, sans compter la maintenance d'un tel système (lorsqu'une nouvelle liste apparait). Les vérificateurs ont donc tout intérêt à respecter l'un des principes de base de DKIM : ne pas jeter un message simplement parce que sa signature est invalide.
Et pour les MLM modernes et qui gèrent DKIM ? Que doivent-ils faire
? La section 5 expose, dans l'ordre du voyage du message, les recommandations qui leur sont
destinées. Ajouter des en-têtes (comme List-ID:
)
ne pose pas de problèmes. C'est un comportement gentil (sauf dans le
cas où ces en-têtes étaient déjà présents et signés, ce qui est
rare).
Par contre, ajouter un texte à la fin du message, on l'a vu, casse
la signature. L'IETF n'a pas de politique
officielle à ce sujet et il n'existe pas de RFC
qui dise noir sur blanc « Thou SHALL NOT change the text,
even by a single byte ». Même si un tel RFC existait, rien
ne dit que les MLM suivraient ses consignes d'autant plus qu'il
n'existe pas d'en-tête standard pour des informations telles que les
conditions d'usage de la liste. DKIM a normalement une
technique pour ce cas : l'option l=
qui indique
la portée de la signature (en nombre d'octets). L'ajout de texte après
la valeur indiquée par l=
n'invalide pas la
signature. Mais cette méthode est déconseillée : un de ses
inconvénients est qu'un attaquant peut, lui aussi, ajouter ce qu'il
veut au message, sans craindre d'être détecté.
Notre RFC suggère donc, plutôt que d'ajouter à la fin de chaque
message un texte comme « Le spam et les remarques désagréables sont
prohibées sur cette liste. Les règles d'utilisation complètes sont
présentées en
http://www.example.com/lists/the-list/terms-of-use
», d'envoyer de telles informations de temps en temps via un message
automatique. Certes, ce sera ennuyeux (pensez à tous les messages de
Mailman le premier du mois) mais cela pourra
être filtré facilement.
Le problème d'ADSP (RFC 5617) est encore plus fort. ADSP permet de publier dans le DNS des directives de validation du genre « Je signe tout et correctement, vous pouvez jeter tout ce qui n'est pas bien signé ». Si un domaine publie une politique ADSP discardable, il interdit quasiment tout usage d'un MLM. Les seules solutions sont encore dans le futur. Par exemple, le RFC imagine des MLM qui connaissent ADSP et qui, lors de la réception d'une demande d'abonnement, testent la politique et, si elle est stricte, refusent l'abonnement. Mais la politique ADSP peut changer à tout moment, donc ce n'est pas une solution parfaite. Va-t-il falloir retester régulièrement ?
L'auteur d'un message signé est de toute façon toujours dans une
position difficile : il ne sait pas ce qui va arriver à son message et
il ne connaît pas les réglages des logiciels intermédiaires. La
section 5.5 recommande donc de séparer le courrier en deux : celui qui
sera forcément de bout-en-bout devrait être signé avec une identité et
une clé différente du courrier général, qui sera peut-être relayé par
un MLM. Ainsi, si mabanquecherie.example
est le
domaine d'une banque, le courrier envoyé directement au client ne
devrait pas avoir le même d=
que celui utilisé
pour le travail quotidien des employés.
Et sur le MLM lui-même, s'il connaît DKIM, quelles sont les bonnes
pratiques (section 5) ? La
plupart des MLM procèdent à une forme d'authentification, souvent
plutôt faible (par exemple, une vérification du
From:
vis-à-vis de la liste des abonnés). Avec
DKIM, on pourrait avoir apparaître de nouvelles politiques, plus sûres
(par exemple une exigence que le message soit signé et que le domaine
indiqué par d=
soit celui du champ
From:
). Évidemment, aujourd'hui, très peu de
messages seront signés, donc le gérant du MLM va devoir décider quoi
faire des autres. En tout cas, une vérification positive est bon signe
et le RFC demande que le MLM ajoute dans ce cas un en-tête indiquant
une authentification réussie (RFC 7001).
Et que faire des signatures DKIM existantes, déjà présentes lorsque le MLM reçoit le message original ? Si le MLM est sûr de ne rien changer au message, il peut laisser ces signatures, qui apportent une information intéressante. Mais s'il modifie le message, il est sans doute plus prudent de les supprimer, pour éviter tout risque qu'un message arrive au destinataire final avec une signature invalide (ce que certains destinataires considéreront, en violation de la norme DKIM, comme une incitation à jeter le message).
Ensuite, il reste une autre décision à prendre pour le MLM : doit-il apposer sa propre signature ? Le RFC le recommande fortement, afin de bien marquer que le gérant du MLM accepte sa responsabilité pour le message qu'il transmet. Le risque est évidemment que certains destinataires interprètent cette signature comme signifiant que le message a été authentifié dès le début. Toutefois, DKIM en lui-même ne peut rien faire dans ce cas : il y aura toujours des gens pour mal interpréter une signature et lui attribuer un poids qu'elle n'a pas.
Continuons le trajet du message : nous approchons de la fin avec les conseils aux vérificateurs. En gros, le RFC demande que ceux-ci traitent les messages des listes comme n'importe quel autre message (dans l'état actuel du déploiement des RFC 2919 et RFC 2369, il n'y a pas de moyen fiable de savoir si un message est passé par un MLM).
Les listes de diffusion de l'IETF signent tous les messages
sortants, depuis
juillet 2011, avec d=ietf.org
(les
signatures originelles sont apparemment retirées). Barry Leiba
a bien résumé ce que cela apporte : « What it does is allow you to assure yourself that the message was,
indeed, from an IETF mailing list (well, from an IETF email server),
and that it wasn't that someone tried to spoof that. That, in turn,
allows you to confidently increase your trust that the message is not
spam in proportion to your confidence in the IETF's spam-filtering
capabilities. ». Voici une telle signature :
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=
Le RFC mentionnait à plusieurs reprises les MLM qui comprennent DKIM. À ma connaissance, aujourd'hui, il n'y a que Sympa dans ce cas. DKIM y a été introduit dans la version 6.1. Quelqu'un connaît d'autres implémentations ?
Un bon article de fond en français sur la coexistence entre DKIM et
les listes de diffusion est l'article de Serge Aumont aux
JRES, « DKIM
et les listes de diffusion ». Sinon, concernant les modifications d'en-tête par les MLM, un
article toujours utile, quoique centré sur les modifications du
Reply-To:
, est « "Reply-To" Munging Considered Harmful ».
Merci à Serge Aumont pour sa relecture.
Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : D. Crocker (Brandenburg InternetWorking), T. Hansen (AT&T Laboratories), M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dkim
Première rédaction de cet article le 22 septembre 2011
Le courrier électronique, on le sait,
n'offre, en natif, aucun mécanisme
d'authentification des utilisateurs. Il est
donc assez facile d'envoyer un courrier prétendant venir de
Bill.Gates@microsoft.com
. DKIM, spécifié dans
notre RFC, est la dernière tentative de combler ce manque. (La
première version de DKIM était normalisée dans le RFC 4871. Cette nouvelle version n'apporte pas de changements cruciaux.)
Notons d'abord que, si le courrier électronique, tel que décrit dans les RFC 5321 ou RFC 5322, ou bien leurs prédécesseurs, n'offre pas d'authentification des utilisateurs, ce n'est pas parce que leurs concepteurs étaient imprévoyants ou trop confiants dans la nature humaine. C'est tout simplement parce que le problème est très complexe, ne serait-ce que parce qu'il n'existe pas de fournisseur d'identité unique sur Internet, qui pourrait jouer le rôle que joue l'État avec les papiers d'identité.
Mais l'absence d'authentification devient de plus en plus regrettable, d'autant plus qu'elle est activement exploitée par les spammeurs et les phisheurs pour leurs entreprises malhonnêtes. Non seulement il est difficile de retrouver le véritable envoyeur d'un message, mais une personne tout à fait innocente peut voir son identité usurpée. Ces problèmes de sécurité sont documentés dans le RFC 4686.
De nombreuses tentatives ont eu lieu pour tenter de traiter ce problème. Certaines ont connu un déploiement non négligeable comme PGP (normalisé dans le RFC 4880), surtout connu pour ses services de chiffrement mais qui peut aussi servir à l'authentification.
PGP est surtout utilisé dans des environnements à forte composante technique, au sein de groupes d'experts qui se connaissent. D'autres protocoles ont tenté de traiter le problème de l'authentification de la masse d'utilisateurs de Hotmail ou de Wanadoo.
DKIM aborde
le problème différemment. Comme SPF, il vise surtout à authentifier le
domaine dans l'adresse électronique, en d'autres
termes à garantir que le courrier vient bien de
microsoft.com
, laissant à
Microsoft le soin de dire si la partie gauche
(Bill.Gates
) est authentique ou pas. En deux
mots, DKIM permet à un domaine de proclamer qu'il a une part
de responsabilité dans un message, et donc que ce domaine
peut répondre dudit message. On trouve une introduction générale à
DKIM dans le RFC 5585 et une réfutation de
beaucoup d'erreurs à propos de DKIM en « The truth about:
Trust and DKIM ».
Mais, contrairement à SPF, DKIM ne procède pas par énumération des adresses IP des MTA autorisés à émettre du courrier pour le compte d'un domaine mais par signature cryptographique.
Le principe de DKIM est le suivant (les exemples sont tirés de l'excellente annexe A du RFC). Un message émis ressemble à :
From: Joe SixPack <joe@football.example.com> To: Suzie Q <suzie@shopping.example.net> Subject: Is dinner ready? Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT) Message-ID: <20030712040037.46341.5F8J@football.example.com> Hi. We lost the game. Are you hungry yet? Joe.
DKIM (qui peut être installé dans le MUA mais sera en général plutôt dans le MTA, cf. section 2.1 et annexe B) le signe et ajoute un en-tête DKIM-Signature (section 3.5 pour sa syntaxe) :
DKIM-Signature: v=1; a=rsa-sha256; s=brisbane; d=example.com; c=simple/simple; q=dns/txt; i=joe@football.example.com; h=Received : From : To : Subject : Date : Message-ID; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqOB 4nujc7YopdG5dWLSdNg6xNAZpOPr+kHxt1IrE+NahM6L/LbvaHut KVdkLLkpVaVVQPzeRDI009SO2Il5Lu7rDNH6mZckBdrIx0orEtZV 4bmp/YzhwvcubU4=; Received: from client1.football.example.com [192.0.2.1] by submitserver.example.com with SUBMISSION; Fri, 11 Jul 2003 21:01:54 -0700 (PDT) From: Joe SixPack <joe@football.example.com> To: Suzie Q <suzie@shopping.example.net> Subject: Is dinner ready? Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT) Message-ID: <20030712040037.46341.5F8J@football.example.com> Hi. We lost the game. Are you hungry yet? Joe.
L'en-tête en question spécifie l'algorithme de chiffrement utilisé
(ici SHA-256 et RSA), le domaine signant (ici
example.com
), un sélecteur
(ici brisbane
) qui servira à sélectionner la
bonne clé (section 3.1), les en-têtes effectivement signés (ici Received :
From : To : Subject : Date : Message-ID
, cf. la section 5.4
sur le choix des en-têtes à signer), la signature elle-même et
l'identité de l'émetteur (ici
joe@football.example.com
). (La différence entre
le domaine, identifié par d=
et l'« identité »
indiquée par i=
est subtile.)
L'identité est indiquée dans la signature pour éviter les longs
débats sur l'identité la plus pertinente parmi toutes celles présentes
dans un message (cf. le RFC 4407 pour un des
exemples d'algorithme qui croit naïvement qu'il existe une et une
seule bonne identité). Le signeur n'est donc pas forcément
l'émetteur (section 1.2). Notre RFC note que le
MUA doit en tenir compte et doit afficher
l'adresse qui est authentifiée, pas seulement celle qui se trouve dans
le champ From:
et qui peut être différente.
Le programme qui veut vérifier la signature (en général un
MTA mais cela peut être le
MUA) va devoir récupérer la clé de
signature. DKIM ne souhaitant pas dépendre des lourdes et chères
autorités de certification, la clé est récupérée via le
DNS (section 3.6.2 ; d'autres
méthodes que le DNS sont en cours de normalisation mais ça n'avance pas). Pour le message ci-dessus, la requête DNS
sera brisbane._domainkey.example.com
et un
enregistrement DNS de type TXT contiendra la clé. Pour voir une clé
réelle, vous pouvez taper dig TXT
beta._domainkey.gmail.com.
ou dig TXT
ietf1._domainkey.ietf.org
. DKIM n'impose pas d'utiliser
DNSSEC et la sécurité de la clé ainsi ramassée
peut être faible (cf. section 8.5 : DKIM ne prétend pas être aussi
fort que PGP).
Un des problèmes difficiles en cryptographie est que les messages
sont souvent modifiés en cours de route. Par exemple, un logiciel
imposé par le direction de l'entreprise va ajouter automatiquement un
stupide message pseudo-légal comme « Ce message e-mail et les pièces
jointes sont transmis à l'intention exclusive de ses destinataires et
sont confidentiels et/ou soumis au secret professionnel. Si vous
recevez ce message par erreur, merci de le détruire et d'en avertir
immédiatement l'expéditeur par téléphone ou par mail. Toute
utilisation de ce message non conforme à sa destination, toute
diffusion ou toute publication, totale ou partielle, est interdite,
sauf autorisation. L'intégrité de ce message n'étant pas assurée sur
Internet, nous ne pouvons être tenu responsables de son contenu. »
(notons que le dernier point devient faux avec DKIM). Ou
bien une liste de diffusion va mettre des
instructions de désabonnement (pour ces listes, voir aussi le RFC 6377). DKIM traite ces problèmes avec deux
méthodes : une canonicalisation (section 3.4 du RFC) du message (plusieurs algorithmes sont
disponibles, plus ou moins violents) pour limiter les risques qu'une modification triviale ne
fausse le calcul de la signature et l'option l=
qui permet d'indiquer sur quelle distance le message est signé. Si on
indique l=1000, seuls les mille premiers octets seront signés et une
liste pourra ajouter un message automatiquement à la fin, cela
n'invalidera pas la signature. (Cette technique est déconseillée, voir
la section 8.2.)
Malheureusement, DKIM encourage également (section 5.3) à remplacer les caractères codés sur 8 bits (comme l'UTF-8 ou le Latin-1) par des horreurs comme le Quoted-Printable, pour limiter les risques qu'une conversion automatique en Quoted-Printable, comme le font certains MTA, n'invalide la signature. Des années d'efforts pour faire passer les caractères 8-bits dans le courrier sont ainsi négligées.
DKIM a nécessité la création de plusieurs registres à l'IANA (section 7) comme le registre des méthodes pour récupérer la clé (aujourd'hui, seulement le DNS).
Parmi les limites de DKIM (qui sont celles de beaucoup de solutions de sécurité, un domaine complexe où il faut faire beaucoup de compromis), il faut aussi se rappeler qu'un attaquant actif peut tout simplement retirer complètement une signature. Tant que les domaines ne publient pas leur politique de sécurité (en suivant le RFC 5617) et donc annoncent « Nous signons toujours », cette attaque passera inaperçue.
Quels sont les changements depuis la première version de DKIM,
normalisée dans le RFC 4871 ? L'annexe E les
résume. Premier point, les changements sont mineurs : comme le note
l'annexe C.2, les anciennes et nouvelles implémentations de DKIM
peuvent communiquer sans problèmes. Mais la sortie de ce nouveau RFC
ne s'est pas faite sans mal. Il y avait des désaccords sérieux sur
l'avis à donner en terme de quels en-têtes devraient être signés, sur
le lien entre le domaine signant et les autres domaines de l'en-tête
(typiquement celui dans le from:
), la façon de
traiter les attaques par ajout d'en-têtes (non couverts par la
signature originale), etc. Beaucoup d'erreurs ont été
détectées dans le RFC 4871 et corrigées ici, la
plus grosse étant celle qui avait fait l'objet d'une mise à jour
d'urgence dans le RFC 5672, désormais
inutile. D'autre part, le nouveau RFC comporte davantage de texte
d'introduction et d'architecture. Enfin, l'option de signature
g=
(qui contrôlait la granularité de la clé) a été abandonnée.
Il y a aussi une différence
complète entre les deux RFC, en ligne.
Aujourd'hui, tous les messages sortant de Gmail sont signés avec DKIM et des implémentations de DKIM existent pour plusieurs logiciels (comme le DKIM milter de sendmail). Le rapport d'implémentation du RFC 4871 en donne une bonne liste. Mais peu de domaines signent et encore moins de domaines vérifient les signatures aujourd'hui (le RFC 5863 discute les questions de déploiement).
Enfin, notons que
DKIM est une technologie d'authentification,
pas d'autorisation. Cette distinction est cruciale. DKIM peut prouver
que le message vient bien de
Nicolas.Sarkozy@elysee.fr
(plus exactement, DKIM
peut dire que le message a bien été approuvé par elysee.fr
), il ne peut pas dire si
la personne en question est digne de confiance ou si elle va
réellement se préoccuper de « la France qui se lève tôt ».
Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : E. Haleplidis, O. Koufopavlou, S. Denazis (University of Patras)
Pour information
Première rédaction de cet article le 21 septembre 2011
Le protocole ForCES (Forwarding and Control Element
Separation) sert à la communication
entre les éléments d'un même routeur. Il permet
à la « tête » du routeur (le CE Control Element) de
donner des instructions aux « jambes » (les FS Forwarding
Element), par exemple de dire où envoyer le trafic pour
2001:db8::/32
. Le fait que ce protocole soit
normalisé pourrait permettre dans le futur d'acheter des routeurs en
plusieurs parties, par exemple un PC avec
du logiciel libre pour le CE et des
ASIC matériels spécialisés pour les FE, le tout
communiquant dans la joie. Ce RFC fait le court
bilan
d'une des équipes qui a le plus travaillé à la programmation de
ForCES, à l'Université de Patras.
Le cahier des charges de ce système figure dans le RFC 3654. ForCES est normalisé dans le RFC 5810 et son architecture est décrite dans le RFC 3746. Il a déjà fait l'objet de deux rapports d'interopérabilité (dans le RFC 6053 et le RFC 6984), vérifiant que les trois mises en œuvre de ForCES coopéraient correctement. L'une de ces mises en œuvre était celle de l'Université de Patras. Les auteurs de cette implémentation tirent, dans ce nouveau RFC, les leçons de leur expérience, afin qu'elle puisse profiter à d'autres.
Petit rappel de ForCES (section 1) : le CE (Control Element) est la partie intelligente du routeur, celle qui fait tourner les protocoles compliqués comme OSPF. Le FE (Forwarding Element) peut être réalisé en logiciel mais, sur les routeurs haut de gamme, il s'agit plus souvent d'un circuit matériel, puisqu'il doit faire passer des millions de paquets à la seconde. Le LFB (Logical Function Block) est une fonction dans le FE, que le CE contrôle. Par exemple, la fonction « comptage des paquets » (à des fins de surveillance et de statistique) est un LFB. Un LFB fait partie d'une classe, qui a des instances (un routeur a souvent plusieurs exemplaires d'un LFB de chaque classe). Pour décrire un LFB, on utilise le modèle du RFC 5812 et éventuellement la bibliothèque de fonctions du RFC 6956. Le protocole ForCES gouverne la communication entre CE (le maître, qui donne des ordres) et FE (l'esclave, qui obéit). S'il y a des discussions entre CE ou bien entre FE, elles se font en dehors de ForCES. De même, le mécanisme par lequel sont configurés CE et FE n'est pas normalisé. Le protocole ForCES peut être transporté entre FE et CE de diverses manières, mais celle recommandée est le transport du RFC 5811.
Le RFC suit l'architecture de ForCES (section 3). La configuration initiale du FE et du CE (non spécifié par ForCES) doit permettre de fixer l'identificateur de chaque élément, le transport utilisé et l'adresse IP (si le transport se fait sur IP).
Le transport standard de ForCES, normalisé dans le RFC 5811, utilise SCTP. Lors des tests d'interopérabilité, ce transport avait même été utilisé entre un site en Chine et un en Grèce mais, évidemment, dans un routeur réel, les distances sont moins longues. (Comme ForCES permet de séparer FE et CE, ils ne sont pas forcément dans la même boîte, et il peut même y avoir des choses bizarres, comme un pare-feu entre eux.) Bien moins connu que son concurrent TCP, SCTP pose un problème au programmeur : les bibliothèques existantes ne permettent pas toujours de l'utiliser simplement. La section 4 contient un tableau des disponibilités pour C, C++ et Java. Par exemple, pour Java sur Windows, il n'y a pas grand'chose à attendre. (Les auteurs ont également eu des difficultés avec un autre problème Java, la gestion des types non signés, pour laquelle ils recommandent Java Unsigned Types.)
Le protocole n'est pas trivial à programmer. En effet, la liste des classes de LFB possibles n'est pas figée. De nouveaux LFB peuvent apparaître à tout moment. En outre, un message peut comporter plusieurs opérations, et plusieurs LFB par opération. C'est bien sûr une... force du protocole (il est très puissant et complet) mais cela le rend plus complexe. Il est donc très difficile de créer du code générique, capable de traiter tous les messages. C'est sans doute la principale difficulté que rencontre l'implémenteur de ForCES. La section 3.4 fournit des pistes possibles, ainsi que des algorithmes d'encodage et de décodage des messages. Les informations dans le message pouvant être emboîtées, l'utilisation de la récursion est recommandée.
Date de publication du RFC : Août 2011
Auteur(s) du RFC : JM. Valin (Mozilla), K. Vos (Skype Technologies)
Pour information
Réalisé dans le cadre du groupe de travail IETF codec
Première rédaction de cet article le 7 septembre 2011
Début 2010, l'IETF avait lancé un travail pour la normalisation d'un codec libre pour l'Internet, c'est-à-dire qui ne serait pas plombé par des brevets ou autres appropriations intellectuelles et pourrait donc être utilisé par n'importe quel protocole Internet. Ce RFC est le premier produit par le groupe de travail, et contient le cahier des charges du futur codec (qui a finalement été publié dans le RFC 6716).
Comme toujours avec ce groupe de travail, cela n'a pas été sans mal. Par exemple, le RFC mentionne des codecs « à battre », c'est-à-dire où le nouveau codec doit être meilleur que ceux-ci, pour être pris en considération. Certains demandaient que les codecs à battre soient uniquement ceux qui sont déjà à peu près libres, d'autres voulaient qu'on compare le nouveau codec avec tous ses concurrents, même plombés. Vue la difficulté de la tâche technique, une telle comparaison aurait sérieusement menacé le projet. Finalement, les codecs libres ont été pris comme référence, mais avec mention des autres, en demandant que, à défaut de les battre, le nouveau codec ne soit pas trop pire qu'eux (section 5.2).
Le but est donc d'avoir un codec libre pour les applications Internet, comme la téléphonie sur IP, la téléconférence, l'exécution de musique en temps réel (concert où les musiciens ne sont pas au même endroit), etc. La section 3 liste, pour chaque application envisagée, ses caractéristiques propres. Car certaines applications sont bien plus exigeantes que les autres. Commençons par l'ordinaire téléphonie à deux. Un codec à large bande (16 kHz) est nécessaire, mais le cahier des charges ajoute la possibilité de fonctionner avec seulement 8 kHz, par exemple pour les vieux téléphones. En large bande, la consommation de capacité réseau attendue va de 12 à 32 kb/s. La latence imposée par le codec doit rester inférieure à 40 ms, mais 25 ms sont souhaitées. (Pour des détails sur les bandes et les latences, voir la section 5.1 du RFC.) Pas besoin d'être haute-fidélité, encore que le RFC note que le codec ne doit pas massacrer les musiques d'attente au point de les rendre désagréables.
Plus exigeantes, la conférence (ou le bavardage en temps réel entre joueurs d'une même partie), où plusieur voix se mêlent. Comme ces applications ont en général davantage de capacité réseau, le codec doit cette fois fonctionner à plus de 24 kHz, pour un débit de 32 à 64 kb/s. Comme les participants à une conférence ont souvent les mains occupées par autre chose et ne tiennent pas le téléphone près de la bouche ou de l'oreille, les problèmes d'écho sont plus sévères qu'en conversation à deux. La latence doit donc être encore plus basse (moins de 30 ms, avec le souhait de descendre à 10), car elle influence la qualité de la suppression d'écho.
Mais, surtout, un système de conférence va mixer les voix de plusieurs participants. Le codec ne doit donc pas gêner le mixage.
Les applications dites de téléprésence sont encore plus demandeuses en terme de qualité, pour arriver à reproduire quelque chose qui ressemble à la présence physique.
Encore plus dur pour un codec, la téléopération (commande d'un robot à distance, par exemple). Si le retour d'information est par la voix (l'opérateur entend ce qui se passe près du robot), une très faible latence est nécessaire.
Et la diffusion de musique en train d'être jouée par plusieurs musiciens ? Des mesures faites avec des musiciens imposent une latence totale de moins de 25 ms (50 si on est prêt à accepter de sérieux problèmes de synchronisation dans l'orchestre). Compte tenu de la latence des autres composants (à commencer par le réseau), cela contraint la latence propre au codec à rester en dessous de 10 ms. Chaque milli-seconde gagnée dans le codec nous donne 200 km de distance en plus, compte-tenu de la vitesse de la lumière dans la silice de la fibre optique. On peut avoir un concert où les musiciens sont dans le même pays, mais pas s'ils sont dispersés aux quatres coins du monde. Et, pour cette application, il faut évidemment une grande qualité, donc un débit soutenu (facilement 128 kb/s).
Il y a bien sûr d'innombrables autres applications où un codec audio est utile mais ce tour d'horizon couvre bien les exigences essentielles.
Le futur codec est conçu avant tout pour être utilisé sur l'Internet. Il s'agit d'un environnement difficile pour un codec audio. La section 4 du RFC liste les contraintes qui découlent de cet environnement. D'abord, les pertes de paquets sont un phénomène normal sur l'Internet et le codec doit y réagir proprement (voir section 5.3). Notamment, lorsque les paquets recommencent à arriver après une ou plusieurs pertes :
Cela implique que la taille d'un paquet soit inférieure à la MTU (pour éviter la fragmentation : la perte d'un des fragments entraîne celle du paquet original tout entier), et qu'il n'y ait pas d'information implicite, car contenue dans un paquet précédent. Par exemple, si on change les paramètres d'encodage, les paquets suivants ne doivent pas considérer que le changement a été reçu : il pouvait être dans le paquet perdu. Les paramètres permettant le décodage doivent donc être dans chaque paquet (ou pouvoir être récupérés rapidement).
Cela n'interdit pas au décodeur de faire des prédictions sur les paquets suivants mais il doit pouvoir les corriger rapidement en cas de pertes. En gros, un codec résistant aux pertes de paquet doit être conçu comme un compromis entre l'efficacité (qui pousse à ne pas répéter les informations et à faire de chaque paquet un delta du précédent) et la robustesse (qui pousse à faire des paquets autonomes, pouvant être interprétés même si on a perdu les précédents).
Autre particularité de l'Internet, c'est un réseau qui fait « au mieux », et qui ne garantit pas la capacité réseau disponible. Le codec doit donc s'ajuster dynamiquement (augmentant et diminuant son débit), sans que cela ne s'entende après le décodage.
Les protocoles de la famille TCP/IP fournissent des mécanismes qui peuvent aider le codec à prendre ses décisions, comme l'ECN du RFC 3168, et il est donc recommandé des les utiliser.
Enfin, le nouveau codec arrivera dans un monde où il existe déjà des protocoles applicatifs qui ont besoin de lui, et il devra donc s'interfacer gentiment avec ces protocoles comme RTP (RFC 3550 et RFC 2736). Si le codec nécessite de négocier des paramètres entre les deux machines qui communiquent, cette négociation devra utiliser les protocoles de signalisation existants comme SDP (RFC 3261 et RFC 4566) dans le cas de SIP, et Jingle (XEP-O167) dans le cas de XMPP.
La section 5 en vient aux exigences détaillées. Le but est que le rapport entre la qualité du son et le débit utilisé soit meilleur qu'avec les codecs existants comme Speex, iLBC (RFC 3951) et G.722.1 (norme UIT du même nom). Ces trois codecs sont a priori implémentables sans payer de royalties mais seul Speex est vraiment libre et c'est donc le seul que le nouveau codec doit battre. En outre, il serait souhaitable que le nouveau codec fasse ex-aequo avec AMR-NB en bande étroite (8 à 16 kb/s) et AMR-WB en bande large (12 à 32 kb/s). Cette qualité doit être mesurée pour plusieurs langues, y compris les langues à tons pour lesquelles une bonne qualité de son est impérative.
À noter que la seule exigence est de faire mieux que ces codecs : le RFC ne demande aucune interopérabilité avec eux (section 6.10).
Concernant la résistance aux pertes de paquets, le codev devra bien se comporter jusqu'à 5 % de pertes et la voix rester compréhensible jusqu'à 15 % de pertes. Comme la qualité ne dépend pas que du pourcentage global de pertes, mais aussi de leur répartition (continue ou au contraire en brusques trous noirs), la qualité devra être évaluée avec des traces réelles, et avec des répartitions de pertes telles qu'on les observe dans un accès ADSL typique.
Les codecs peuvent être gourmands en ressources machines, par exemple exiger un processeur très rapide. Or, il devra être mis en œuvre sur une grande variété de machines (de l'ordinateur généraliste au petit téléphone), qui ne disposeront parfois pas de FPU et dont les éventuels DSP auront des caractéristiques très différentes. Le RFC demande donc que le codec puisse être implémentable en virgule fixe. Du point de vue quantitatif, notre RFC exige une limite à la consommation de processeur. Pour un x86 récent, l'encodage et le décodage d'un signal en mono ne devrait prendre que 40 MHz en bande étroite (soit 2 % du temps d'un cœur à 2 Hz), et 200 MHz en très large bande. Ces chiffres peuvent paraître bas mais il faut se rappeler que le codec va aussi tourner sur des machines dont le processeur est bien plus lent que celui du PC de bureau typique.
Il est facile d'ammonceler dans un cahier des charges des exigences irréalistes, et ensuite de laisser les pauvres implémenteurs se débrouiller. Ce problème est fréquent dans les SDO où les participants à la normalisation sont des bureaucrates et des politiciens qui ne feront pas le travail de mise en œuvre eux-mêmes. L'IETF se méfie traditionnellement de ce risque et une des méthodes utilisées pour s'en préserver est l'implémentation de référence, une mise en œuvre du logiciel réalisée pour s'assurer que c'est possible, et qui est souvent publiée en même temps que le RFC. Notre RFC encadre cette implémentation de référence du futur codec en lui interdisant de tirer profit de fonctions spécifiques de tel ou tel matériel : elle doit être le plus portable possible. Par exemple, le RFC interdit de dépendre de l'arithmétique saturée, pour pouvoir tourner sur les processeurs qui n'ont pas cette fonction comme certains ARM. Par contre, les « vraies » implémentations, elles, auront tout intérêt à exploiter à fond les particularités du matériel sur lesquelles elles tournent.
Outre la consommation de processeur, le nouveau codec ne doit pas être trop encombrant en mémoire (code et données), pour pouvoir être lancé sur des systèmes embarqués. Pour les données (l'état à garder en mémoire pour faire fonctionner le codec), le RFC met une limite à 2*R*C octets, où R est le taux d'échantillonage et C le nombre de canaux.
Et ce n'est qu'une petite partie des problèmes auxquels un codec sur l'Internet fait face. La section 6 charge la barque avec diverses considérations et des souhaits (les exigences précédentes étaient considérées comme impératives). Par exemple, s'il y a mixage (pour une téléconférence, par exemple), il serait bien de limiter le coût de l'opération. L'implémentation naïve du mixage est de décoder tous les flux audios, les mélanger et réencoder le résultat. Une approche où un décodage complet ne soit pas nécessaire est souhaitée. Autre souhait : un bon support de la stéréo, là encore en évitant l'approche naïve, qui consiste à encoder séparement les deux canaux. Comme ceux-ci ont probablement beaucoup de redondances, cette propriété devrait être utilisée pour limiter le débit utilisé. Il serait également très bien de gérer les erreurs dans les paquets (bits dont la valeur a changé). La plupart des applications Internet ne le font pas car le phénomène est rare. En général, un paquet arrive intact ou n'arrive pas. Mais des transformations non désirées se produisent parfois (avec des protocoles comme UDP Lite, il n'y a pas de somme de contrôle, cf. RFC 3828) et le RFC demande que la question soit étudiée, en insistant que, dans tous les cas, c'est la robustesse du codec aux pertes de paquets qui est prioritaire.
Plus rigolo, et pour les amateurs de polars, la section 6.9 demande que le codec n'élimine pas et ne dégrade pas le bruit de fond des appels : ce bruit peut servir à identifier l'origine d'un appel, et, dans le cas d'appels au 112, cela peut être crucial. Un bon exemple figure dans le génial film de Kurosawa, « Entre le ciel et l'enfer », où policiers et employés du tramway arrivent à reconnaître près de quelle ligne de tramway se trouve le criminel qui appelle, juste en écoutant le bruit de fond, et en remarquant un léger bruit, caractéristique d'un endroit où le câble est abîmé par un accident récent. (Les cinéphiles savent qu'il y a un exemple plus léger dans « La double vie de Véronique ».)
Restent les traditionnelles questions de sécurité : la section 7 rappelle l'évidence (le décodeur doit faire attention aux attaques par débordement de tampons) mais aussi l'importance d'avoir une consommation de ressources bornée : quels que soient les paquets entrants, le temps de processeur utilisé et la mémoire consommée ne doivent pas croître sans limites (autrement, une DoS serait possible en envoyant des paquets créés pour cela).
Plus subtil, le problème de la fuite d'informations lorsque la communication est normalement protégée par du chiffrement. Des attaques ont déjà été décrites où des informations importantes sur la conversation pouvaient être extraites d'un flux audio chiffré (« Spot me if you can: Uncovering spoken phrases in encrypted VoIP conversations » et « Phonotactic Reconstruction of Encrypted VoIP Conversations: Hookt on fon-iks »). Le codec peut compliquer certaines de ces attaques, par exemple en ayant un mode où le débit est constant, quelle que soit la conversation.
Date de publication du RFC : Septembre 2011
Auteur(s) du RFC : P. Hoffman (VPN Consortium), J. Klensin
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 12 septembre 2011
L'internationalisation des protocoles développés par l'IETF est depuis quinze ans un des sujets chauds de cette organisation. Réussir à rendre tous les protocoles Internet adaptés aux différentes langues, écritures et cultures nécessite d'avoir un socle linguistique commun et c'est le rôle de ce RFC, qui décrit la terminologie en usage à l'IETF. Il remplace le RFC 3536 dans le rôle du texte « l'internationalisation pour les débutants ». Le texte est long car le sujet est complexe.
Cette terminologie est d'autant plus importante que les discussions sur le sujet sont souvent victimes d'un vocabulaire flou et mal utilisé. Ainsi, on voit parfois apparaître le terme de « caractère latin » sans que celui-ci soit bien défini. Seulement ASCII ou bien également les caractères composés, utilisés par exemple en français ? Autre exemple, à l'ICANN, les discussions sur les IDN sont souvent rendues incompréhensibles par une confusion fréquente entre des concepts aussi différents que « langue » et « écriture ». Si vous lisez dans un article ou un rapport des termes absurdes comme « noms de domaines multilingues », faites lire ce RFC 6365 à l'auteur de ce texte, il en a besoin...
Ce RFC est en anglais et fixe une terminologie anglophone. Dans mon article, je vais donner le terme anglais défini et la traduction française que j'utilise (sans consulter les normes officielles, qui ne sont pas toujours de grande qualité et souvent faites par des gens qui ignorent le domaine). Mais le lecteur doit bien être conscient du fait qu'il n'existe pas forcément de terminologie standard en français. Même en anglais, le consensus est loin d'exister sur tous ces termes, et le caractère ultra-sensible des questions de langue n'arrange rien.
Petit rappel de l'objectif poursuivi, en section 1 : comme le dit
le RFC 2277, document fondateur,
l'internationalisation concerne les humains,
pas les protocoles. On ne va donc pas traduire le
GET
de HTTP. Par contre, lorsqu'un protocole manipule des chaînes de
caractères qui vont être lues ou écrites par des humains, il faut
que cela soit possible quelle que soit la langue ou l'écriture
utilisée. Cette politique de l'IETF est donc différente de celle, qu'on entend souvent
à l'ICANN, comme quoi tout le monde n'a qu'à parler anglais, langue
internationale de toute façon.
Avoir un vocabulaire commun est évidemment essentiel pour les discussions au sein de l'IETF, et pour la qualité et l'homogénéité des documents produits (les RFC). Ce RFC 6365 sert aussi de tutoriel sur l'internationalisation en expliquant les concepts de base aux membres de l'IETF, un public d'ingénieurs qui n'est pas forcément très sensible à cette question. Notre RFC rappelle ainsi que, dans beaucoup de groupes de travail de l'IETF, lorsque quelqu'un soulève la question de l'internationalisation du protocole en cours de développement, les réponses « faut-il vraiment s'en préoccuper ? » sont souvent nombreuses. Il y a donc un certain fossé à combler.
Voyons maintenant les définitions générales (section 2). Le RFC ne pouvait pas tout couvrir et un des plus grands débats dans le groupe avait été l'étendue de la liste des termes à définir. Le choix a été fait de se restreindre, pour augmenter la probabilité que les non-spécialistes de l'internationalisation lisent le texte. Je ne reprends ici qu'une partie des termes, ceux que je trouve indispensables, ou bien dont la définition est mal connue.
Une langue (language) est une façon de communiquer entre humains, notamment par la parole ou l'écriture. Lorsqu'une forme écrite et une forme parlée existent pour une langue, elles sont parfois très proches... et parfois très distantes. Ce terme n'inclus pas les langages de programmation.
Une écriture (script) est un ensemble de caractères graphiques qui sont utilisés pour la forme écrite d'une ou de plusieurs langues. C'est le cas de l'écriture latine, cyrillique, arabe (attention dans ce cas, arabe est également le nom d'une langue) et han. L'IETF s'occupant surtout de l'écrit (la langue parlée peut être transmise par des protocoles comme RTP mais elle n'est typiquement pas interprétée par ces protocoles), presque toujours, les protocoles IETF s'occupent d'écritures, pas de langues. C'est ainsi que les IDN sont des noms de domaines multi-écritures et surtout pas multilingues. (Le RFC note explicitement que « multilingue » est un de ces termes flous et passe-partout, qu'il faut éviter.)
(La définition de l'internationalisation dans notre RFC est d'ailleurs modeste, « permettre ou améliorer l'utilisation de caractères non-ASCII dans les protocoles IETF », par rapport celle du W3C, plus ambitieuse, « permettre l'adaptation facile à n'importe quelle langue, écriture ou culture ».)
La relation entre les langues et les écritures est complexe : il y a beaucoup moins d'écritures que de langues et la plupart des écritures peuvent servir à plusieurs langues. D'autre part, si certaines langues n'ont jamais été écrites qu'avec une seule écriture (le français avec l'écriture latine, le russe avec la cyrillique), d'autres ont changé, comme le turc ou le vietnamien. L'effondrement de l'URSS a eu entre autres pour conséquence l'abandon du cyrillique par plusieurs langues comme le mongol. Autre exemple, le malais est passé récemment (et la transition n'est pas terminée) du jawi à l'alphabet latin.
On voit parfois le terme alphabet pour désigner une écriture mais, comme toutes ne sont pas alphabétiques (cf. section 4.1), ce terme est plutôt à éviter.
Un système d'écriture (writing system) est un ensemble de règles pour utiliser une écriture dans le cas d'un langage donné. Ainsi, le français et l'anglais utilisent la même écriture, mais avec des règles différentes (par exemple pour la ponctuation).
Un caractère (character) est un membre de l'ensemble des éléments qui servent à représenter les données écrites. Le terme est plus flou qu'il n'y parait car il existe des tas de cas qui défient la classification comme le digramme « ll » du catalan. En anglais, les informaticiens disent souvent char au lieu de character, vu que c'est le type de données utilisé dans plusieurs langages de programmation. En tout cas, un caractère n'est pas une représentation graphique, un glyphe. Par exemple, il n'y a qu'un seul caractère A alors qu'il en existe de nombreuses représentations possibles (il y a un excellent article sur ce sujet dans le livre de Hofstadter, « Metamagical Themas »).
En parlant de glyphe, sa définition dans le RFC est « l'image d'un caractère rendue sur une surface ». On aura donc un glyphe différent si on affiche avec une résolution différente. Unicode a une autre définition, basée plutôt sur l'encodage d'une police particulière, et où le glyphe est donc le même quel que soit le périphérique de sortie. Dans la définition d'Unicode, chaque glyphe a un code de glyphe, qui est un index dans une police donnée (et qui n'est pas standard : deux auteurs de polices peuvent utiliser des codes de glyphes différents).
Un jeu de caractères (repertoire) est simplement un ensemble de caractères, rigoureusement défini (c'est par exemple à ce stade qu'on décide si œ est un seul caractère ou deux).
Un jeu de caractères codé (Coded Character Set, CCS) est un ensemble de règles qui définissent un jeu de caractères et une représentation codée (typiquement, par un nombre entier unique par caractère). Unicode ou ISO-8859-6 définissent un CCS.
L'encodage (character encoding scheme) est la représentation en machine des caractères, c'est-à-dire la définition de quelle chaîne de bits représente tel caractère. Si des normes comme ISO 8859 ne définissent qu'un seul encodage possible, Unicode en a plusieurs (le plus connu étant UTF-8, qui est le protocole par défaut dans l'Internet, cf. RFC 2277).
Le transcodage (transcoding) est la traduction d'un encodage dans un autre, comme le font les outils Unix iconv ou recode.
Je laisse en anglais le terme charset car il est purement technique et n'est pas la même chose qu'un jeu de caractères tel que défini plus haut. Ce terme de charset est très utilisé dans les normes IETF (notamment MIME) et les charsets peuvent être enregistrés dans un registre IANA selon les règles du RFC 2978. Un charset est un moyen de passer d'une séquence d'octets à une chaîne de caractères abstraits. C'est donc la combinaison d'un jeu de caractères codé et d'un encodage. charset doit être considéré comme un mot-clé, à utiliser sans regarder de trop près son étymologie, et le RFC déconseille notamment de le remplacer par character set, qui peut avoir d'autres définitions en anglais. On va donc dire que charset est un néologisme spécifique à l'IETF.
La section suivante, la 3, liste les organismes de normalisation qui ont à voir avec l'internationalisation (ou plutôt une partie d'entre eux). Par exemple, l'ISO a une norme de jeu de caractères, ISO 10646, qui fait même partie des rares normes ISO disponibles gratuitement en ligne (dans sa version anglaise, uniquement, et après acceptation d'un long texte juridique menaçant, c'est pour cela que je ne mets pas de lien ici). Cette norme est synchronisée avec Unicode et il n'y a donc pas de raison de la lire, Unicode offre davantage de choses. Le groupe de travail SC2/WG2 qui produit la norme ISO a un site Web qui donne des aperçus du travail en cours.
D'autres normes ISO ont un rapport direct avec
l'internationalisation comme ISO 639 qui gère
un catalogue de langues, avec des codes alphabétiques (comme
fr
pour le français) ou ISO 3166 qui gère une liste de pays, avec leurs codes (comme
fr
pour la France). Ces normes forment la base
des étiquettes de langue (cf. RFC 5646), utilisées par exemple dans le
Web pour indiquer la langue d'une page.
Le consortium Unicode est un autre organisme de normalisation, qui gère le jeu de caractères du même nom, ainsi qu'un certain nombre de travaux qui lui sont liés, comme la définition d'expressions rationnelles pour Unicode. On l'a vu, Unicode et ISO 10646 sont synchronisées et, techniquement, on peut se référer à l'une ou l'autre norme, sans conséquences pratiques. Ce RFC 6535 ne le dit pas mais c'est pour des raisons politiciennes qu'ISO 10646 était plus souvent cité, l'ISO, organisation privée, tout comme le consortium Unicode, étant parfois considérée par certains comme plus ouverte (alors que l'essentiel de ses documents n'est pas distribué en ligne).
Le Web est une des applications où l'internationalisation est la plus avancée, ayant été prise en compte pratiquement dès le début. C'est le rôle du W3C, qui gère des normes comme XML (dont le modèle de caractères est Unicode depuis la première version).
Enfin, et c'est important dans le contexte de l'internationalisation, il existe aussi un certain nombres d'organismes nationaux qui ont parfois une activité touchant à ce sujet.
Comme le cœur de l'internationalisation des protocoles est la définition d'un jeu de caractères commun, la section 3.2 liste le vocabulaire spécifique d'Unicode. Il faut par exemple savoir ce que sont UCS-2, UTF-16 et UCS-4/UTF-32, que le BMP (Basic Multilingual Plane) est composé des 65 536 premiers caractères d'Unicode (qui sont traités à part par certains encodages), qu'UTF-8, normalisé dans le RFC 3629, est l'encodage recommandé pour tous les protocoles IETF, mais que l'IETF a un encodage spécifique pour les noms de domaines, Punycode, normalisé dans le RFC 3492. Encodant n'importe quel chaîne Unicode avec uniquement des caractères ASCII, Punycode peut sembler une solution tentante au problème d'internationalisation d'un vieux protocole, mais il vient aussi avec ses propres problèmes (cf. RFC 6055).
On l'a dit, il existe souvent des SDO nationales qui, avant l'avènement d'Unicode, ont souvent développé des jeux de caractères locaux, permettant de représenter les écritures utilisées dans leur pays. La section 3.3 rappelle ainsi que ces jeux de caractères sont encore souvent très utilisés, comme Shift-JIS pour le japonais.
Ce sont ces jeux de caractères, et leurs encodages (dans la plupart
des définitions, le jeu de caractères et l'encodage sont
intrinsèquement liés ; Unicode est une exception), qui sont
enregistrés sous le nom de charsets à
l'IANA, dans https://www.iana.org/assignments/character-sets
. Cette liste
n'est pas connue pour sa grande rigueur : beaucoup de noms ont été
ajoutés au pifomètre. Elle ne s'appuie pas toujours sur des normes
reconnues.
Le plus connu des charsets est évidemment US-ASCII, historiquement le jeu par défaut de l'Internet, depuis le RFC 20. Sa domination a officiellement pris fin lors de la sortie du RFC 2277, qui le remplaçait comme charset par défaut par son sur-ensemble UTF-8. À noter que la norme ASCII originale était uniquement un jeu de caractères, et que le terme « ASCII » utilisé à l'IETF lui ajoute un encodage spécifique aux protocoles Internet (champ de huit bits, le bit de plus fort poids toujours à zéro, les sept autres stockant le code ASCII) qui n'a été formellement décrit qu'avec le RFC 5198, bien plus tard...
Ces histoires de caractères font surgir plein d'autres problèmes de terminologie. D'où la section 4, qui lui est consacrée. Ainsi, un point de code (code point) est le numéro que la plupart des normes attribuent à chaque caractère, pour le référencer sans ambiguité. C'est en général un nombre entier strictement positif mais, dans la norme ASCII originale, c'était un couple de nombres, identifiant la ligne et la colonne d'une table. « A » était ainsi 4/1 (ligne 4, colonne 1), en ASCII, alors qu'il est 65 en décimal et U+0041 en Unicode.
Et connaissez-vous les caractères combinants (combining characters) ? Il s'agit d'une particularité d'Unicode, qui met en cause la définition typographique de « caractère » puisqu'un caractère combinant se... combine avec son prédécesseur (par exemple, U+0301 est l'accent aigu combinant, donc U+0065 suivi de U+0301 fait un « é »).
Autre concept important pour les chaînes de caractères, la canonicalisation (normalization ; notez que, en anglais, « canonicalization a un sens très précis dans Unicode, et distinct de celui de normalization, qui justifie l'emploi d'un mot séparé). C'est le processus par lequel une chaîne de caractères est mise sous une forme canonique, permettant les comparaisons (autrement, comparer U+00E9 avec U+0065 U+0301 pourrait échouer alors que, dans les deux cas, il s'agit d'un é).
Quant à la casse (case), c'est le fait pour un caractère d'exister en deux formes, une majuscule et une minuscule. Souvent, la correspondance entre les deux formes est un-un (chaque minuscule a une et une seule majuscule, et réciproquement) mais ce n'est pas toujours le cas. Pire, le changement de casse peut dépendre de la langue. Cette dépendance est mise en œuvre, par exemple, en Java et, outre qu'elle est très coûteuse en ressources, elle produit forcément des résultats différents selon la locale (voir section 8 pour ce terme).
Enfin, place au tri (sorting) et au classement (collation). Le classement est le fait de d'ordonner les caractères. C'est un sujet très vaste. Même en ASCII, il existe au moins deux classements distincts (un par les numéros, A, B, C, D..., a, b, c, et un selon l'ordre alphabétique, A, a, B, b, C, c...). En ISO 8859-1, le cas des caractères composés n'est pas traité de manière uniforme car le classement dépend de la langue (comparez un annuaire téléphonique en France et en Suède pour voir où sont placés les noms propres commençant par un caractère composé). Sans connaître la langue, on ne peut pas espérer classer les caractères Unicode d'une manière qui ne surprenne pas l'utilisateur. Quant au tri, c'est le processus effectif de mise des caractères dans l'ordre du classement. Il fait l'objet d'innombrables algorithmes qui ont fait la joie et le malheur de centaines de milliers d'étudiants en programmation.
Même les adjectifs utilisés pour les différents types de caractères ne sont pas toujours connus. La section 4.1 explique par exemple que le terme d'idéogramme ne décrit pas vraiment correctement les écritures comme la chinoise. Si U+260E est bien une icône (☎, un téléphone), beaucoup de caractères chinois sont utilises phonétiquement, sans coder une idée.
En tout cas, en français, une chose est sûre, on ne devrait pas parler de « caractère accentué » pour des signes comme ç qui n'ont pas d'accent. Le terme Unicode de diacritique (diacritic) convient mieux. Et, évidemment, il ne s'agit pas de caractères spéciaux.
Unicode soulève un autre problème intéressant : la liste des caractères est très longue et il est souvent utile d'en définir des sous-ensembles. Mais attention : contrairement à ASCII ou aux ISO 8859, qui étaient statiques, Unicode grossit tout le temps (la dernière version a été la 6). Un sous-ensemble défini en intension comme « toutes les lettres majuscules » grossira donc lui aussi à chaque nouvelle version d'Unicode (une question qu'il a fallu résoudre pour IDN, voir le RFC 5892).
On l'a dit, le but de l'internationalisation est d'aider les humains, de leur rendre la vie plus facile. Il faut donc un peu se pencher sur les interfaces utilisateur, même si celles-ci sont traditionnellement hors de la portée de l'IETF (qui normalise « au dessus du câble et en dessous de l'application »). En effet, certaines caractéristiques des interfaces utilisateur peuvent affecter les protocoles. D'où l'importance d'apprendre quelques nouveaux termes.
Une méthode d'entrée (input method) est un mécanisme qui permet d'envoyer du texte à une application. Le périphérique d'entrée est souvent un clavier mais les claviers ayant des tailles limitées, les différentes méthodes d'entrée fournissent des mécanismes pour saisir d'autres caractères. Le clavier sur lequel je suis en train de taper n'a pas de majuscules avec diacritiques donc, pour faire un É, je tape Compose (touche dite Windows, sur mon clavier) puis E puis ' (le signe sous le 4). Plus complexe, et ayant bien plus de caractères qu'il n'y a de touches sur un clavier, l'écriture chinoise peut être saisie par plusieurs méthodes différentes : taper les sons au clavier, par exemple.
Les protocoles IETF ont bien de la chance : ils n'échangent que des bits, sans se soucier de savoir comment les afficher. Un serveur HTTP, par exemple, n'a aucun besoin de connaître l'écriture arabe ou la chinoise (ou même de comprendre Unicode), il se contente d'envoyer les octets. Mais le navigateur Web, lui, va devoir afficher les textes pour l'utilisateur. Il s'appuie pour cela sur les règles de rendu (rendering rules), qui sont les algorithmes d'affichage du texte à l'écran. Avec certaines écritures, c'est encore relativement simple : chaque caractère est représenté par un glyphe dans une police de caractères et on pousse simplement ce glyphe vers le périphérique de sortie. Mais dans d'autres écritures, il faut modifier le caractère selon le contexte (par exemple, avec l'écriture arabe, selon qu'il est au début ou à la fin de la phrase). Et, bien sûr, une des choses les plus difficiles pour un moteur de rendu, est de gérer le bidi. Comme je l'ai dit, les protocoles IETF n'ont pas besoin de connaître ces subtilités (un serveur HTTP envoie des textes en alphabet arabe comme ceux en alphabet latin : dans l'ordre de saisie). Mais il est bon que leurs concepteurs soient au courant de ce qui attend les logiciels de l'utilisateur.
Après ces définitions indispensables, quelle est la situation actuelle du texte dans les protocoles IETF ? La section 6 étudie la question. Il n'y a pas de règle générale, car certains protocoles IETF étaient internationalisés depuis le début (comme XMPP), d'autres ne l'ont été qu'après un long et pénible processus (cas du courrier électronique, créé sans penser à l'internationalisation et largement déployé, donc difficile à changer, lorsqu'on a voulu l'adapter à un monde vaste et varié).
Il y a donc encore du vocabulaire à apprendre. Ainsi, les
éléments de protocole (protocol
elements) sont les éléments qui nomment une partie du
protocole. Certains ne sont pas textuels, comme les numéros de
port dans TCP, d'autres
le sont (comme les commandes SMTP, par exemple
EHLO
et MAIL FROM
) mais ne
sont pas vus par l'utilisateur et donc, ne sont pas sujets à
l'internationalisation (d'ailleurs, EHLO
n'est
pas de l'anglais non plus...).
Quant à l'encodage sur le câble (on-the-wire encoding), il désigne les bits qui passent effectivement sur le réseau. Cet encodage est souvent très différent de la forme texte que verront les humains.
Mais il ne pose pas de problèmes d'internationalisation, au
contraire du texte analysé (parsed
text) qui désigne le texte libre qu'un programme va analyser
pour essayer d'y trouver des éléments de protocole. Le cas le plus
connu est sans doute la convention d'ajouter un
Re:
(pour Reply) dans le sujet
d'un message. Un tel système est clairement très fragile, la
localisation de ce préfixe suffisant à empêcher
l'analyse. Il ne devrait pas apparaître dans les protocoles
récents.
Lorsqu'un protocole transporte du texte, et que la connaissance de
la langue dans laquelle est écrit ce texte est importante (par exemple
pour déterminer l'ordre de classement), il faut utiliser une
identification de langue (language
identification). C'est un mécanisme par lequel on indique la
langue utilisée, en se servant des étiquettes de
langue du RFC 5646. Ainsi, HTTP va
utiliser l'en-tête Content-Language: gsw-FR
dans la
réponse, pour indiquer que le document servi est en alsacien.
Le texte contenu dans les échanges normalisés par un protocole IETF
est souvent décrit par ASN.1. Ce langage permet
plusieurs sortes de chaînes de caractère, de la traditionnelle
IA5String
, qui contient les caractères ASCII, à
UTF8String
qui, comme son nom l'indique, peut
stocker tout Unicode. Ainsi, lorsque le RFC 5280 utilise ce type pour des champs d'un
certificat X.509, il permet à ce format d'avoir
des noms de CA ou d'utilisateurs complètement internationalisés.
Il existe également toute une terminologie spécifique aux IDN. On la trouve dans le RFC 5890 et résumée dans la section 7.
Plus nouveau est le problème des variantes (variants). Il date du RFC 3743 et peut se définir comme « des chaînes de caractères que certains humains, dans certaines conditions, considèrent comme équivalents ». Dans le RFC 3743, il ne s'agissait que de la différence entre les sinogrammes traditionnels et les sinogrammes simplifiés, pour lesquels une solution était recommandée dans le RFC 4713. Mais la question des variantes peut surgir dans bien d'autres cas :
La question des variantes a donc deux sous-questions : comment classer les caractères et les chaînes en lots (où les membres d'un lot sont considérés variantes l'un de l'autre) ? Et, surtout, le protocole doit-il intégrer cette notion, ou bien considérer plus traditionnellement que deux chaines de caractère sont différentes si elles ont des numéros Unicode différentes, point ?
Dernière section avec des définitions, la section 8 est consacrée aux termes divers. On y trouve, par exemple, le profil local (locale), qui est l'ensemble des informations qui varient selon le lieu ou la culture, et qui sont nécessaires pour que le programme, non seulement parle la langue de l'utilisateur, mais lui présente des informations comme la date ou la monnaie locale.
Les profils locaux sont une source de questions philosophiques sans fin. Par exemple, pour afficher un texte, faut-il utiliser le profil de l'auteur du texte ou bien celui du lecteur ? Et le profil doit-il dépendre de la personne, ou bien de sa localisation physique ? (Si je suis à Tokyo, je veux l'heure locale mais mes textes toujours en français.)
Autres termes utile, ceux de translittération (transliteration), de transcription (transcription) et de romanisation (romanization). La translittération est la conversion d'une écriture dans une autre, en général lettre par lettre. Elle est réversible, la plupart du temps, puisque chaque lettre a été convertie. Cela marche bien entre écritures alpabétiques. La transcription, elle, suit les sons (et non pas les lettres) et va donc être différente selon la langue cible. C'est c'est ainsi que le nom du fondateur du parti bolchevique russe, Ульянов, peut être translittéré Ul'yánov (le résultat exact dépend de la norme suivie car il existe plusieurs normes de translittération de cet alphabet) mais est transcrit Ulyanov en anglais et Oulianov en français. Avec les écritures comme le chinois, la translittération n'est en général pas possible et il n'y a que des transcriptions, comme le pinyin. On nomme romanisation une conversion (translittération ou transcription, même si le RFC n'indique que la première possibilité) vers l'alphabet latin.
Quels sont les changements depuis le précédent RFC, le RFC 3536 ? L'annexe C les résume. Il y a des clarifications, pas de retraits mais plusieurs ajouts, notamment sur la question des variantes. La section 7, sur la terminologie spécifique aux IDN, est toute nouvelle.
Il existe bien sûr d'autres documents qui ont développé un vocabulaire cohérent sur l'internationalisation, et qui ont donc inspiré ce RFC. On peut citer la norme Unicode, le « Character Model for the World Wide Web » du W3C, et les RFC 2277, RFC 5646 et RFC 5890. Patrick Andries a un excellent glossaire de l'internationalisation en français.
L'annexe A contient une bibliographie sur le sujet de l'internationalisation, où on trouve des ouvrages de référence comme la somme sur les écritures du monde, « The world's writing systems ». Sur le sujet d'Unicode, je recommande ces livres :
Enfin, on trouve plein de choses en français sur le site de Patrick Andries.
Date de publication du RFC : Août 2011
Auteur(s) du RFC : R. Housley (Vigil Security)
Pour information
Première rédaction de cet article le 22 août 2011
Les RFC, textes sacrés de l'Internet, comportaient un sous-ensemble, dénommé FYI (For Your Information), qui visait un public plus large que les ingénieurs réseaux et les programmeurs. Cette sous-série n'a pas été un grand succès, malgré la qualité des documents produits, et est officiellement abandonnée.
Lancée par le RFC 1150 en 1990, la sous-série FYI visait à élargir le lectorat des RFC et à fournir de l'information utile et techniquement correcte (puisque écrite directement par les experts) à un large public, celui de tous les utilisateurs de l'Internet (les autres RFC n'étant lus que par des geeks barbus). Trente-huit RFC ont été publiés dans cette sous-série, chacun recevant un numéro FYI. Ainsi, le RFC 1178 (FYI 5) expliquait comment choisir un nom pour son ordinateur, le RFC 1359 (FYI 16) détaillait l'intérêt et les bénéfices de se connecter à l'Internet (tout le monde n'était pas encore convaincu), et le dernier de la sous-série, le RFC 3098 (FYI 38) expliquait à quel point c'était mal de spammer. Parfois, le RFC était mis à jour, son successeur héritant de son numéro de FYI. Rappelez-vous qu'un RFC n'est jamais modifié, donc le nom « RFC 1594 » désigne toujours le même document alors que le nom « FYI 4 » a désigné plusieurs RFC successivement, depuis le RFC 1325, intéressant document historique, puisque c'est une FAQ pour les nombreux nouveaux utilisateurs de l'Internet (le dernier RFC pointé par « FYI 4 » a été le RFC 2664).
Depuis 2001, aucun numéro de FYI n'avait été attribué et le groupe de travail qui les gérait ne s'est pas réuni. Ce RFC 6360 ne formule pas d'hypothèse sur cet arrêt mais on peut penser que les experts n'avaient pas forcément le temps ou la compétence d'écrire pour les utilisateurs, et que le modèle des RFC (documents très stables et accessibles sur le long terme) n'était pas forcément adapté à des publications de ce type dans un Internet changeant très vite. Bref, la sous-série a tourné court. Dans d'autres organisations, on aurait continué pendant longtemps la fiction mais l'IETF préfère (et parfois réussit) nettoyer. Ce RFC 6360 marque donc officiellement la fin des FYI. Les documents existants restent accessibles mais il n'y aura pas de nouveautés.
Pour ceux qui veulent accéder à ces excellents documents, la liste
est disponible en http://www.rfc-editor.org/fyi-index.html
.
Date de publication du RFC : Août 2011
Auteur(s) du RFC : C. Daboo (Apple)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF vcarddav
Première rédaction de cet article le 1 septembre 2011
Dernière mise à jour le 18 août 2014
De même que le format de fichiers iCal, décrivant des événements, avait son protocole CalDAV pour synchroniser des agendas entre machines, le format vCard décrivant des informations sur une personne a désormais son protocole CardDAV, pour synchroniser des carnets d'adresses.
Lorsque ce RFC sera largement déployé, on pourra donc sauvegarder, distribuer, partager son carnet d'adresses de manière standard. Cela se fait en définissant, comme pour CalDAV, des extensions au protocole WebDAV (RFC 4918).
Ce n'est pas qu'on manquait de protocoles pour l'accès à un
carnet. Comme le rappelle la section 1, on avait
LDAP (RFC 4510), IMSP et
ACAP (RFC 2244), ainsi que
SyncML. Mais bâtir sur
WebDAV (RFC 4918) permettait de récupérer les fonctions
perfectionnées de ce protocole. Le nouveau CardDAV permet d'avoir
plusieurs carnets d'adresses, d'en protéger l'accès par des
autorisations (RFC 3744), de faire des recherches côté
serveur (sans avoir besoin de récupérer tout le carnet d'adresses chez
le client), etc. WebDAV étant lui-même bâti sur
HTTP, on récupère aussi les fonctions de HTTP
comme la sécurité avec TLS (RFC 2818). CardDAV utilise le format vCard. Ce
format avait été normalisé dans le RFC 2426 et
se trouve désormais dans la RFC 6350. CardDAV dépend
de certaines extensions à WebDAV et tout serveur WebDAV ne conviendra
pas forcément. La section 3 résume les exigences de CardDAV (serveur
permettant de créer des collections avec MKCOL
- RFC 5689 et exemple d'usage en section 6.3.1, versionnement - RFC 3253, etc). Par contre, il
n'y a pas encore dans le protocole CardDAV de
mécanisme de notification asynchrone (« Machin a changé de numéro de
téléphone »). Le RFC ne le précise pas mais il y a un
inconvénient à utiliser WebDAV, la complexité. Notre RFC 6352 fait 56 pages, et il faut avoir compris WebDAV avant...
La section 4 du RFC explique le modèle de données utilisé pour le carnet : chaque
carnet d'adresses est une collection WebDAV et
chaque entrée dans le carnet est une ressource WebDAV, adressable et
verrouillable séparement. En même temps que les carnets d'adresses, un
serveur CardDAV peut aussi gérer avec WebDAV d'autres ressources (un
exemple serait un serveur où le carnet d'adresses de Lisa serait en
/addressbooks/lisa
et son agenda, via
CalDAV, en
/calendars/lisa
). Le serveur publie le fait qu'il
gère CardDAV en ajoutant addressbook
à la réponse
à la requête HTTP OPTIONS
.
La section 5 passe ensuite à ces ressources. Chacune d'elles est une entrée du carnet, typiquement exprimée en format vCard (le serveur peut gérer également d'autres formats).
Emprunté au RFC (section 6.1), voici un exemple de connexion à un serveur CardDAV :
(Le client demande) OPTIONS /addressbooks/ HTTP/1.1 Host: addressbook.example.com (Le serveur répond) HTTP/1.1 200 OK Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE Allow: MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL DAV: 1, 2, 3, access-control, addressbook DAV: extended-mkcol Date: Sat, 11 Nov 2006 09:32:12 GMT Content-Length: 0
Le client sait désormais que le serveur gère CardDAV (le
addressbook
dans l'en-tête
DAV
).
Différentes propriétés WebDAV (RFC 4918, section 4 ; les propriétés sont les
métadonnées de WebDAV) permettent de se
renseigner sur les carnets d'adresses. Elles sont formatées en
XML. Ici,
addressbook-description
(section 6.2.1 ; son nom
indique bien à quoi elle sert) peut valoir, par exemple (notez l'attribut xml:lang
qui illustre les capacités d'internationalisation de CardDav) :
<carddav:addressbook-description xml:lang="fr-CA" xmlns:carddav="urn:ietf:params:xml:ns:carddav"> Adresses de Oliver Daboo </carddav:addressbook-description>
Et pour créer des entrées dans le carnet d'adresses, ce qui est
quand même la tâche la plus importante de CardDAV ? CardDAV étant
fondé sur HTTP, on utilise évidemment une requête
PUT
(de même que la lecture se ferait par un GET
). La section 6.3.2 nous fournit un exemple,
avec l'entrée au format vCard :
PUT /lisa/addressbook/newvcard.vcf HTTP/1.1 If-None-Match: * Host: addressbook.example.com Content-Type: text/vcard Content-Length: xxx BEGIN:VCARD VERSION:3.0 FN:Cyrus Daboo N:Daboo;Cyrus ADR;TYPE=POSTAL:;2822 Email HQ;Suite 2821;RFCVille;PA;15213;USA EMAIL;TYPE=INTERNET,PREF:cyrus@example.com NICKNAME:me NOTE:Example VCard. ORG:Self Employed TEL;TYPE=WORK,VOICE:412 605 0499 TEL;TYPE=FAX:412 605 0705 URL:http://www.example.com UID:1234-5678-9000-1 END:VCARD
Le If-None-Match
dans la requête (RFC 7232,
section 3.2) est là pour garantir qu'une
ressource du même nom n'existe pas déjà. Cela évite d'effacer une
ressource existante. Le .vcf
à la fin de l'URL
est l'extension commune des fichiers vCard.
Les carnets d'adresses sont évidemment des choses assez personnelles, on a donc des moyens de les protéger (section 7). Un serveur CardDAV permet de définir des ACL, comme normalisé dans le RFC 3744.
Récupérer un carnet d'adresses avec GET
est
simple mais ne laisse guère de choix. La section 8 présente des
mécanismes plus sophistiqués. CardDAV a la méthode HTTP
REPORT
du RFC 3253 pour produire des
extractions du carnet. Mais il a aussi des fonctions de recherche et de
tri. Celles-ci posent le problème des règles de
comparaison (rappelez-vous qu'un fichier vCard est de
l'Unicode et peut contenir des caractères de
toute sorte). La section 8.3 précise donc :
i;ascii-casemap
du
RFC 4790 et les comparaisons Unicode
i;unicode-casemap
du RFC 5051,
Voici un exemple de commande REPORT
en ajoutant
une condition pour ne sélectionner que les entrées du carnet dont le
NICKNAME
est exactement égal à « me » :
La requête : REPORT /home/bernard/addressbook/ HTTP/1.1 Host: addressbook.example.com Depth: 1 Content-Type: text/xml; charset="utf-8" Content-Length: xxxx <?xml version="1.0" encoding="utf-8" ?> <carddav:addressbook-query xmlns:dav="DAV:" xmlns:carddav="urn:ietf:params:xml:ns:carddav"> <dav:prop> <dav:getetag/> <carddav:address-data> <carddav:prop name="VERSION"/> <carddav:prop name="UID"/> <carddav:prop name="NICKNAME"/> <carddav:prop name="EMAIL"/> <carddav:prop name="FN"/> </carddav:address-data> </dav:prop> <carddav:filter> <carddav:prop-filter name="NICKNAME"> <carddav:text-match collation="i;unicode-casemap" match-type="equals"> me </carddav:text-match> </carddav:prop-filter> </carddav:filter> </carddav:addressbook-query> La réponse : HTTP/1.1 207 Multi-Status Date: Sat, 11 Nov 2006 09:32:12 GMT Content-Type: text/xml; charset="utf-8" Content-Length: xxxx <?xml version="1.0" encoding="utf-8" ?> <dav:multistatus xmlns:dav="DAV:" xmlns:carddav="urn:ietf:params:xml:ns:carddav"> <dav:response> <dav:href>/home/bernard/addressbook/v102.vcf</dav:href> <dav:propstat> <dav:prop> <dav:getetag>"23ba4d-ff11fb"</dav:getetag> <carddav:address-data>BEGIN:VCARD VERSION:3.0 NICKNAME:me UID:34222-232@example.com FN:Cyrus Daboo EMAIL:daboo@example.com END:VCARD </carddav:address-data> </dav:prop> <dav:status>HTTP/1.1 200 OK</dav:status> </dav:propstat> </dav:response> </dav:multistatus>
Écrire un client CardDAV n'est pas trivial, pas seulement à cause
de la longueur du RFC mais aussi parce qu'il existe plusieurs
pièges. La lecture de la section 9 est donc recommandée. Elle rappelle
par exemple que le client peut ne demander qu'une
partie des données (dans l'exemple ci-dessus, le
client demande à ne voir que VERSION
,
UID
, NICKNAME
,
EMAIL
et FN
). Cela lui évite
de devoir télécharger des données qui peuvent être de grande taille
comme PHOTO
ou SOUND
. Par
contre, cette astuce ne marche qu'en lecture, pas en écriture : un
PUT
doit transmettre la totalité de la
vCard et le protocole ne fournit pas de moyen de ne
mettre à jour qu'un seul champ. Le client doit donc récupérer toute la
vCard, changer un champ et renvoyer toute la
vCard modifiée.
Piège classique dans ce cas, la « mise à jour perdue ». Que se
passe-t-il si les données ont été changées entre leur récupération et
le renvoi ? Ce changement risque d'être écrasé. Pour éviter cela, le
client a tout intérêt à utiliser l'option
If-Match:
de la requête HTTP, en indiquant comme
paramètre un Etag récupéré précedemment (les
Etags sont décrits dans la section 2.3 du RFC 7232). Ainsi, dans le cas cité ci-dessus, le
renvoi du vCard modifié sera refusé, préservant la
mise à jour qui avait été faite parallèlement. (Emmanuel Saint-James
me fait remarquer qu'on aurait aussi pu utiliser
If-Unmodified-Since:
, si le serveur CardDAV met
les informations dans une base de données qui stocke la date de
modification, par exemple le système de fichiers Unix ; cette
possibilité n'est pas mentionnée par le RFC.)
Comment configure-t-on un client CardDAV (section 9.3) ? On a vu que
l'URL utilisé était arbitraire, au choix de
l'implémenteur. Le client doit donc être configuré avec cet URL. Il
existe bien deux mécanismes de découverte automatique, décrits dans le
RFC 5397 et dans le RFC 6764, mais qui ne sont pas
forcément présents partout. (iOS utilise celui du RFC 6764 donc si
vous voyez des requêtes /.well-known/carddav
passer, c'est lui.)
Et le nom du serveur ? La section 11 décrit un
enregistrement SRV pour le trouver. Le nom
_carddav._tcp.domain.example
permet donc de
trouver le serveur CardDAV du domain
domain.example
(et _carddavs
pour utiliser TLS). Si l'enregistrement SRV
vaut :
_carddav._tcp SRV 0 1 80 addressbook.example.com.
Cela indique que ce serveur est
addressbook.example.com
et qu'il est accessible
sur le port 80.
Si ces
enregistrements SRV sont présents, et si la propriété
current-user-principal-URL
du RFC 5397
est utilisée, il n'y a plus à configurer que le nom de domaine, le nom
de l'utilisateur et un mot de passe.
Et si on veut accéder au carnet d'un autre utilisateur, ce qui peut
arriver en cas de carnets partagés ? La section 9.4 rappelle
l'existence de la propriété
principal-property-search
du RFC 3744,
qui peut permettre de demander un REPORT
en
cherchant le carnet sur divers critères. Ici, on cherche le carnet de
Laurie :
REPORT /home/bernard/addressbook/ HTTP/1.1 Host: addressbook.example.com ... <dav:principal-property-search xmlns:dav="DAV:"> <dav:property-search> <dav:prop> <dav:displayname/> </dav:prop> <dav:match>Laurie</dav:match> </dav:property-search> <dav:prop> <carddav:addressbook-home-set xmlns:carddav="urn:ietf:params:xml:ns:carddav"/> <dav:displayname/> </dav:prop> </dav:principal-property-search>
Notez que, CardDAV s'appuyant sur XML, il hérite de ses capacités d'internationalisation (section 12), notamment l'usage d'Unicode.
Et question sécurité ? Des failles dans CardDAV ? La section 13 tente de prévenir les problèmes : d'abord, CardDAV hérite des questions de sécurité de HTTP. Si on n'utilise pas HTTPS, les requêtes et réponses circulant sur le réseau peuvent être lues et/ou modifiées. C'est particulièrement important si on utilise l'authentification HTTP de base, avec envoi d'un mot de passe.
Ensuite, une fois les utilisateurs authentifiés, encore faut-il éviter qu'un utilisateur ne tripote les carnets des autres. L'extension « ACL » du RFC 3744 permet d'atteindre cet objectif. Elle permet d'avoir des carnets publics, partagés ou complètement privés. Le serveur doit ensuite veiller au respect de cette classification.
Le schéma XML complet pour les éléments CardDAV figure en section 10. Question implémentations, on peut regarder la liste gérée par les gens de Zimbra, celle de Trinity, celle de Wikipédia. Parmi les programmes qui gèrent CardDAV, citons le serveur Davical, Radicale ou Evolution. le client Kontact de KDE n'est plus maintenu. Pour Firefox, c'est en discussion. Merci à Mathieu Dupuy pour les détails.
Date de publication du RFC : Août 2011
Auteur(s) du RFC : S. Perreault (Viagenie)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF vcarddav
Première rédaction de cet article le 1 septembre 2011
vCard, désormais en version 4 avec ce RFC est le format standard de carnet d'adresses sur l'Internet. Tous les logiciels de gestion de carnet d'adresses peuvent (ou devraient pouvoir) lire et écrire du vCard. Ce RFC met à jour la norme vCard.
vCard est simplement un modèle de données (très léger) et une syntaxe pour représenter des données permettant de contacter des individus ou organisations. Par exemple, une entrée vCard pour mon employeur, l'AFNIC, pourrait être :
BEGIN:VCARD VERSION:4.0 FN:Association Française pour le Nommage Internet en Coopération KIND:org GENDER:N NICKNAME:AFNIC LANG;PREF=1:fr LANG;PREF=2:en ADR:;;Immeuble International;Saint-Quentin-en-Yvelines;;78181;France LOGO:http://www.afnic.fr/images/logo.png TEL;VALUE=uri:tel:+33-1-39-30-83-00 EMAIL:afnic@afnic.fr GEO:geo:2.0455,48.7873 BDAY:19980101 TZ:Paris/Europe URL:http://www.afnic.fr/ NOTE;LANGUAGE=en:@AFNIC on Twitter\, AFNIC on Facebook. END:VCARD
Ce texte peut ensuite être lu et interprété par les logiciels de
gestion de carnet, être envoyé via l'Internet, etc. Un exemple courant
est l'envoi d'une vCard dans le courrier, via MIME et
le type text/vcard
(section 10.1 pour
l'enregistrement de ce type). Le cas échéant, il
est relativement compréhensible par un humain (s'il comprend l'anglais
et quelques sigles), ce qui justifie le type MIME
text
indiqué plus haut.
La version de vCard dans ce RFC est largement terminée depuis mi-2010. Mais de nombreux détails avaient été discutés jusqu'au dernier moment. Si la syntaxe ne pose guère de problèmes (on notera qu'il existe une variante XML normalisée, dans le RFC 6351, et une autre en JSON, dans le RFC 7095), le modèle de données peut susciter des discussions sans fin.
Pour prendre des exemples de cette discussion, voici quelques sujets qui avaient été abordés lors de la réunion du groupe de travail à l'IETF de Pékin en 2010 :
RELATED
qui peut
valoir spouse
, friend
,
etc. Une jolie liste des valeurs possibles est http://gmpg.org/xfn/11
. On pourra coder toutes les relations
Facebook en vCard.SEX
de vCard 3 par
GENDER
. La moitié des participants se sont
exprimés, ce qui est rare à l'IETF. Le sexe est déterminé biologiquement et,
en toute première approximation, peut être considéré comme binaire
(homme ou femme). Le
genre est construit socialement et peut prendre bien plus de
valeurs. GENDER
pourra donc être du texte libre
(une des propositions discutées à Pékin avait été de créer un registre
IANA des différents genres possibles...) et les
exemples du RFC (avec des valeurs comme grrrl,
intersex ou complicated)
illustrent la difficulté du problème. Le changement dans vCard permet donc de mieux prendre en compte des cas comme celui des
transsexuels ou, tout simplement, des gens qui
ont une autre identité que celle que leur impose la biologie. L'ironie
de la longue et animée discussion est qu'il n'y avait que des hommes
dans la salle. (GENDER
est désormais décrit en
détail dans la section 6.2.7 du RFC, avec notamment sa façon subtile de
combiner deux champs, un énuméré et un en texte libre.)DEATH
permettant, si nécessaire, d'indiquer la
date de la mort de l'entitée considérée. Elle a
finalement été retirée. Mettre du vCard sur une pierre tombale
aurait pourtant été curieux... Cela a finalement été possible quelque
temps après, avec l'approbation du RFC 6474.EMAIL
permettra de telles adresses (voir la
section 6.4.2 pour les détails).J'espère que cette liste amusante vous aura donné une idée des
problèmes que pose la définition d'un modèle de données
standard. Retournons maintenant à la technique. D'abord, le niveau
lexical (sections 3.1 et 3.2) : les fichiers vCard sont en
UTF-8 (la possibilité d'autres encodages a été
retirée, avec cette version de vCard), et sont composés de lignes terminées par
CRLF (c'est-à-dire les deux caractères U+000D et U+000A). Comme pour
les en-têtes du courrier électronique, on peut
continuer sur plusieurs lignes : si une ligne commence par un espace
ou une tabulation,
c'est une continuation (regardez la NOTE
dans
l'exemple plus haut). Du fait de ces continuations, un outil
mono-ligne comme grep n'est pas bien adapté
pour chercher dans des vCards.
Ensuite, la syntaxe (section 3.3). Elle est
très simple et indiquée en ABNF (RFC 5234). Une « carte » commence par la ligne
BEGIN:VCARD
, continue par une ligne avec le
numéro de version, puis par une ou plusieurs lignes comportant les
données, et se termine avec END:VCARD
. Les
données sont composées de propriétés, chaque
ligne étant un nom de propriété (insensible à la
casse, même si la convention recommandée est de les mettre
en majuscules), suivi d'un :,
puis de la valeur de la propriété (celle-ci pouvant elle-même être
structurée, comme dans l'ADR
ci-dessus).
Certains caractères sont spéciaux, comme la virgule et, si on veut les avoir comme valeur, doivent subir un échappement avec la barre inverse (section 3.4).
Les données peuvent avoir des paramètres. La section 5 décrit ce
concept. Un paramètre permet de préciser des métadonnées sur une
propriété. Par exemple, LANGUAGE
permet
d'indiquer la langue d'un
texte. PREF
permet de spécifier, lorsqu'il existe
plusieurs exemplaires d'une propriété, laquelle est préférée (celle
qui a la valeur la plus basse). Ainsi, dans l'exemple de l'AFNIC
ci-dessus, c'est le français qui est la langue
de contact préférée. SORT-AS
permet de
définir un tri entre les valeurs (un problème
difficile pour les noms d'humains). TYPE
permet
d'indiquer, pour une ADR
, si elle concerne la
maison ou le travail. (vCard version 3 avait un mécanisme plus riche,
qui aurait permis, dans l'exemple de l'AFNIC ci-dessus, d'indiquer la
différence entre l'adresse postale - TYPE=postal
et l'adresse physique - TYPE=parcel
. Trop confus,
il a été supprimé.) Et il existe plusieurs autres paramètres.
La sémantique est décrite dans la suite de
cette section 3.3 et, pour chaque propriété, dans les sections 4, 5 et 6.
Notons qu'une seule propriété est obligatoire (à part VERSION
),
FN
, le nom de l'entité décrite dans la vCard. Pour chaque propriété, la
section 4 indiquera si des valeurs multiples sont autorisées. Par
exemple, on peut avoir plusieurs NICKNAME
(surnom), mais un seul (facultatif) GENDER
(genre).
Je ne vais évidemment pas lister toutes les propriétés que décrit la section 5 (voir le registre IANA pour une liste à jour). Pour chacune, elle donne son nom, sa cardinalité (zéro, zéro-ou-une, une, zéro-ou-plus, une-ou-plus occurrence) et son type. Pour ce dernier, il y a de nombreuses possibilités comme, par exemple, du texte libre, un URI, une date ou un temps (en utilisant la norme ISO 8601 et pas le plus simple RFC 3339), un booléen, un nombre entier, une langue (représentée selon le RFC 5646), etc.
À certains égards, la section 6 est la plus importante du RFC. C'est la liste de toutes les propriétés possibles actuellement, avec leurs caractéristiques. Quelques exemples, non limitatifs :
N
indique le nom, sous forme d'une série de
composants (dont la plupart sont facultatifs). Pour les humains, je
rappelle surtout que le fait d'avoir Prénom + Nom est très
loin d'être universel.KIND
indique quelle est la catégorie de
l'entité décrite par cette « carte » (personne physique, organisation
- comme dans l'exemple de l'AFNIC plus haut,
etc).PHOTO
est l'URI
(éventuellement de plan data:
, c'est-à-dire
fournissant directement le contenu) d'une photo de la
personne. LOGO
joue un rôle analogue pour les organisations.BDAY
est la date de naissance de l'entité.IMPP
indique le moyen de contacter l'entité
par messagerie instantanée.LANG
permet d'indiquer, sous la forme d'une
étiquette de langue comme
fr
ou pt-BR
, la langue
à utiliser pour contacter l'entité.GEO
est la localisation physique habituelle
de l'entité, en suivant de préférence la syntaxe du RFC 5870. (Notez le « de préférence ». Analyser la syntaxe d'une
vCard est très simple, mais accéder à la sémantique est bien plus
complexe, en raison du choix qui est laissé pour le codage
d'informations comme le numéro de téléphone ou la position physique.)KEY
permet de distribuer des clés
cryptographiques
(attention à comment on a récupéré le vCard avant de leur faire confiance...)Notez que la liste n'est pas figée dans le temps (c'est une
nouveauté de vCard version 4). Des propriétés ou
paramètres nouveaux pourront être enregistrés, selon la procédure
décrite dans la section 10.2. Il faudra d'abord les discuter sur la
liste vcarddav@ietf.org
, puis il y aura un examen
par un expert. Si accepté, le nouvel élément sera enregistré à l'IANA.
Le reste du RFC est consacré à des points d'utilisation des
vCard. Par exemple, la section 7 est consacrée à la synchronisation
des vCards entre deux engins (par exemple l'ordinateur du bureau et le
smartphone). Que faire si une entrée a été modifiée sur un carnet et détruite dans un autre ? Deux mécanismes sont fournis pour
aider à une fusion intelligente des deux carnets, une propriété
UID
qui identifie de manière unique et non
ambigüe une entité (de préférence en utilisant le RFC 9562) et PID
qui identifie une
propriété. Les section 7.1.1 et 7.1.2 détaillent l'algorithme à
utiliser lorsqu'on synchronise deux carnets. Par exemple, si on a
identifié, grâce à UID
, une entrée dans les deux
carnets, et qu'une propriété est différente entre les carnets, alors, si la
cardinalité d'une propriété est de 1, ou bien si le PID est le même,
les deux propriétés doivent être fusionnées. Sinon, le synchroniseur
est libre de fusionner, ou tout simplement de mettre les deux
propriétés côte-à-côte. La section 7.2 donne des exemples détaillés de
fusions. À noter qu'il existe un protocole pour la synchronisation des
cartes avec un serveur, CardDAV, normalisé
dans le RFC 6352.
Le message d'enregistrement du type MIME text/vcard
, qui
commençait la procédure, avait été fait en
août 2010.
Publier ainsi de l'information, parfois sensible, sur l'Internet,
n'est pas sans conséquences. La section 9 couvre les risques de
sécurité de vCard. Par exemple, la carte en elle-même n'offre aucune
garantie d'authentification ou d'intégrité. Rien ne prouve qu'une
carte indiquant FN:Theo de Raadt
vient réellement
de de Raadt. Et même si la
carte était authentique au départ, rien n'indique qu'elle n'a pas été
modifiée en cours de route, sauf si elle a été transportée de manière
fiable (par exemple dans un message signé avec PGP). Bref,
ne vous fiez pas aveuglément à n'importe quelle vCard trouvée sur
l'Internet !
Autre risque, celui pour la vie privée. Ce
n'est pas par hasard ou par oubli que vous ne trouverez pas
BDAY
ou ADR
sur ma carte, un
peu plus loin. Une carte doit donc ne comporter que des informations
publiques, ou bien être uniquement transportée de manière sûre (par
exemple via un canal chiffré) et vers des gens
de confiance.
Les changements de vCard depuis la version 3 (qui était normalisée
dans les RFC 2425 et RFC 2426) sont décrits dans l'annexe A. La liste est
longue et pas facile à résumer (ce n'est qu'une accumulation de
changements ponctuels). Le changement que je trouve le plus
spectaculaire est la possibilité d'enregistrer de nouveaux éléments
sans changer de RFC, juste par un processus
d'enregistrement IANA. Sinon, voir la section 6.7.9 pour le rôle de la propriété
VERSION
pour gérer le fait que les cartes en
circulation aient des versions différentes.
Si vous voulez en savoir plus sur vCard, le site Web du groupe de travail est très riche, quoique plutôt difficile d'accès (il est conçu pour le travail du groupe, pas pour la pédagogie).
Et du point de vue pratique, quels outils le programmeur a à sa
disposition s'il veut lire et/ou écrire du vCard ? Il existe une
bibliothèque pour les programmeurs
C (le paquetage se nomme libvc-dev sur
Debian), qui est utilisée dans des applications
comme rolo. Elle n'est distribuée avec aucune
documentation digne de ce nom et pas d'exemples. Pour les programmeurs
Perl, il existe
Text::vCard
. Attention
à son analyseur : très laxiste, il accepte des vCards bourrées
d'erreurs de syntaxe.
Voici un exemple d'usage de cette bibliothèque Perl :
#!/usr/bin/perl use Text::vCard::Addressbook; for $file (@ARGV) { my $address_book = Text::vCard::Addressbook->new({ 'source_file' => $file}); $number = 0; foreach my $vcard ($address_book->vcards()) { print "Got card for " . $vcard->fullname() . "\n"; $number++; } if (!$number) { print "No correct vCard in $file\n"; } }
Ah, et si vous voulez me contacter, voici une carte pour moi :
BEGIN:VCARD VERSION:4.0 FN:Stéphane Bortzmeyer N:Bortzmeyer;Stéphane;;; UID:urn:uuid:a06340f8-9aca-41b8-bf7a-094cbb33d57e GENDER:M KIND:individual EMAIL:stephane+blog@bortzmeyer.org TITLE:Indigène de l'Internet PHOTO:http://www.bortzmeyer.org/images/moi.jpg LANG;PREF=1:fr LANG;PREF=2:en IMPP;PREF=1:xmpp:bortzmeyer@dns-oarc.net IMPP;PREF=2:xmpp:bortzmeyer@gmail.com URL:http://www.bortzmeyer.org/ KEY:http://www.bortzmeyer.org/files/pgp-key.asc END:VCARD
Merci à Simon Perreault pour sa relecture.
Date de publication du RFC : Août 2011
Auteur(s) du RFC : B. Constantine (JDSU), G. Forget (Bell
Canada), R. Geib (Deutsche
Telekom), R. Schrage (Schrage Consulting)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 22 août 2011
La mesure des performances du réseau intéresse évidemment fortement
les utilisateurs (combien de temps me faudra-t-il pour télécharger
justin-bieber.flac
?) et les décideurs qui
cherchent à savoir, par exemple, quelle capacité offre un
FAI, s'il délivre bien le service promis, ou encore s'il
limite artificiellement les débits. La plupart des métriques définies
rigoureusement,
et des outils qui les mettent en œuvre, concernent des
phénomènes de bas niveau, comme le taux de perte de paquets (RFC 7680), C'est ainsi que, lorsqu'il existe des
SLA formalisés, ils portent en général sur ces
phénomènes proches du réseau. Ces métriques sont utiles et relativement faciles à
mesurer objectivement, mais elles sont très éloignées de l'expérience
ressentie par l'utilisateur final. Ce dernier voudrait plutôt
savoir comment l'intégration de toutes ces métriques de bas niveau se
traduit en un petit nombre de chiffres faciles à comprendre. Ce n'est
pas une tâche triviale que de passer des métriques de base au ressenti
utilisateur, et ce RFC est une première étape sur le chemin.
L'idée est de préciser les conditions de mesure de débit sur une connexion TCP, de bout en bout (donc tenant compte du comportement de tous les liens et équipements intermédiaires). Le débit mesuré en TCP donne une première idée de la capacité du réseau, qui est elle-même souvent la première métrique qui intéresse les utilisateurs (c'est en tout cas en général celle qui est mise en avant dans les publicités). Mais cette mesure contient de nombreux pièges et l'un des buts de ce RFC est de les lister. Au final, ce RFC ne permet pas de répondre simplement à la question de M. Toutlemonde « ça va moins ramer avec le fournisseur X qu'avec son concurrent Y ? », mais il avance quand même dans cette direction.
On grimpe donc d'une couche et on passe des mesures traditionnelles (taux de pertes, comme cité plus haut, ou bien capacité du lien au niveau 2) vers le niveau 4. Le désir de mesurer rigoureusement le débit atteignable avec TCP oblige à apporter quelques restrictions. Par exemple, le cadre de mesure décrit dans ce RFC se limite aux réseaux dont tous les aspects sont contrôlés par un fournisseur unique, avec des garanties explicites. Cela concerne donc plutôt la clientèle « entreprises ». La section 2 détaille tout ce qui n'est pas un objectif de ce RFC :
Le but est au contraire de pouvoir mesurer, de manière objective et reproductible, les performances TCP d'un chemin donné, en fonction d'un certain nombre de réglages, bien définis. Les outils existants comme iperf ou ttcp permettent d'ajuster ces réglages.
Passons maintenant à la technique (la section 1.1 liste la terminologie employée) : TCP utilise à tout moment deux fenêtres, une pour l'envoyeur (congestion windows) et une pour le récepteur (receive window). Le débit théorique est limité par la bande passante (capacité de la couche 2) et par le RTT. Leur produit, le BDP (Bandwidth*Delay Product), va déterminer la taille des tampons optimaux (le tableau en section 3.3.1 donne des valeurs numériques). Ce BDP est, en gros, le nombre d'octets qui peuvent se trouver en transit à un moment donné. Ensuite, la fenêtre de congestion sera ajustée pour tenir compte du taux de pertes. Le nombre d'octets en route à un moment donné dépendra de la fenêtre la plus petite (si on a une grande congestion window mais que l'autre partie annonce une petite receive window, le débit restera faible : un émetteur TCP n'est pas censé noyer son pair sous les octets non désirés).
Toutes ces variables vont déterminer le débit effectivement atteint. Avant de tenter de mesurer celui-ci, le RFC insiste bien sur le fait que les tests de bas niveau (couches 2 et 3) doivent quand même être faits, pour déterminer que le réseau fonctionne bien. Le RFC note qu'un taux de pertes de paquets de 5 %, ou bien une gigue dans le délai d'acheminement de 150 ms, sont trop élevées pour que les mesures de débit TCP aient un sens. La méthodologie du RFC 2544 (bien que conçue à l'origine pour un environnement de laboratoire) peut être utilisée pour ces tests de bon fonctionnement.
Ensuite, notre méthodologie ne concerne que les connexions TCP ayant atteint l'état d'équilibre (section 1.2). Rappelons qu'une connexion TCP établie peut avoir trois comportements par rapport à la congestion : l'état d'équilibre où TCP essaie de remplir le tuyau au maximum, le démarrage en douceur, utilisé au début de la connexion, où TCP commence à sonder prudemment le réseau, en augmentant doucement son débit, et le troisième comportement, la récupération en cas de pertes, où TCP réduit brusquement son débit, avant de repartir plus ou moins doucement. En pratique, un certain nombre de connexions utilisées pour HTTP, par exemple, n'atteindront jamais cet équilibre, car elles durent trop peu de temps. C'est un bon exemple de la distance entre les mesures techniques et le vécu de l'utilisateur !
Dans un réseau idéal, à l'équilibre, TCP devrait avoir un débit très proche de la bande passante offerte.
La section 3 du RFC présente la méthodologie de mesure détaillée, avant que la section 4 ne décrive les métriques utilisées. La mesure impose d'utiliser un équipement capable de saturer le lien (donc, pas un vieux PC). Les mesures à plus de 100 Mb/s peuvent donc exiger une machine dédiée. La mesure exige ensuite les étapes suivantes :
--mss
permet de
changer la taille des segments (des paquets TCP).--time
, avec ipmt, c'est -d
). Compte-tenu de la variété
des mécanismes de tripotage du réseau qui existent, il peut être
prudent de faire plusieurs mesures (par exemple de voir si une seule
connexion obtient bien N fois ce qu'obtenait chacune des connexions
d'un groupe de N
connexions simultanées, cf. section 5.1).Les métriques utilisées sont définies dans la section 4 du RFC. Elles sont au nombre de trois. La première est le ratio du temps de transfert, soit le rapport entre le temps nécessaire pour transférer N octets par rapport à la situation idéale (compte-tenu de la bande passante). Le calcul exact de cette situation idéale figure en section 4.1.1. Par exemple, pour une ligne T3 à 44,21 Mb/s exploitée en PPP, une MTU de 1500 octets, vus les en-têtes TCP, on arrive à 42,8 Mbps. Si on mesure un débit maximal de 40 Mbps, le ratio sera donc de 1,07 (rappelez-vous que c'est un rapport des temps de transfert, pas des débits). Pour un Ethernet 1 Gb/s, le cas idéal, qu'aucune amélioration du logiciel ne permettra de dépasser, est de 949 Mbps. L'utilisation de jumbo frames permettrait bien sûr de faire mieux.
La seconde métrique est l'efficacité de TCP. C'est le pourcentage des octets qui n'ont pas été retransmis. Il vaut donc 1 en l'absence de pertes (ou de retards qui mèneraient TCP à croire à une perte de paquets).
Plus subtile, la troisième métrique est le retard dû aux tampons. C'est le rapport entre l'excès de RTT (par rapport au RTT minimum, celui imposé par les caractéristiques de la ligne) et le RTT minimum. Par exemple, si le RTT minimum (qui, sur les lignes à grande distance, est souvent dépendant essentiellement de la vitesse de la lumière) est de 25 ms, et qu'on observe un RTT moyen de 32 ms pendant un transfert TCP, le retard dû aux tampons est donc de 28 %.
La première métrique est celle qui est la plus directement pertinente pour l'utilisateur. Les deux autres fournissent surtout un moyen de diagnostic : si le ratio du temps de transfert est mauvais, l'examen de l'efficacité et du retard dû aux tampons nous indiquera peut-être pourquoi.
Voilà, la norme est définie. La section 5, elle, revient sur les conditions pratiques de mesure. Entre autres, elle expose les règles du choix entre une seule connexion TCP et plusieurs. Ce choix dépend des caractéristiques du réseau (si le produit bande passante * délai est de 2 Moctets, une seule connexion TCP ne pourra pas remplir le tuyau, cf. le tableau des valeurs numériques en section 5.1).
Reste l'interprétation des résultats (section 5.2). Les résultats devraient toujours être accompagnés de la valeur des paramètres indiqués plus haut (ce que font les outils existants, cf. plus loin). Le RFC demande évidemment que les valeurs des trois métriques citées plus haut soient affichées, ce qui n'est pas (encore ?) le cas avec les logiciels Unix de mesure existants. Une fois qu'on a ces valeurs, si elles ne correspondent pas aux valeurs idéales, on peut se livrer aux joies du débogage : la congestion avec des tampons de petite taille dans les routeurs fera sans doute grimper les pertes de paquets, ce qui se traduira par une mauvaise efficacité TCP. Si les routeurs ont de quoi stocker les paquets en attente, c'est le RTT qui augmentera, ce qui se verra dans le retard dû aux tampons. Mais il peut aussi y avoir ralentissement délibéré par le réseau (policing), tampons trop petits sur les machines de test (qui ont, après tout, une mémoire limitée, qui peut être trop faible pour les réseaux à haute performance d'aujourd'hui). Les machines Unix ont de tels tampons aussi bien globalement pour tout le système que par socket. On peut fixer ces derniers (la valeur idéale est le BDP, le produit bande passante*délai) dans le programme, mais aussi les laisser s'ajuster automatiquement (service auto-tuning, qui existe dans Linux et FreeBSD ainsi que, depuis moins longtemps, Windows et Mac OS). Il faut également regarder du côté du mécanisme de window scaling (RFC 7323) sans lequel il est impossible d'exploiter les réseaux à très fort BDP qu'on trouve aujourd'hui. Et, bien sûr, émettre des paquets ayant la taille maximale possible sans fragmentation est aussi une bonne tactique.
Bien d'autres réglages de TCP sont possibles, comme l'option d'estampille temporelle (RFC 7323) qui permet à TCP de mieux calculer le RTT (et qui protège contre les numéros de séquence TCP qui reviennent à leur valeur initiale, un problème qui devient sérieux au delà de 100 Mb/s), les accusés de réception spécifiques (SACK) du RFC 2018, qui permettent de limiter les retransmissions, etc.
À titre d'exemple, voici des exemples de mesure, plus ou moins compatibles avec notre RFC, dans le cas de certains outils libres. Le premier est iperf. Existant sous forme de paquetage pour divers systèmes Unix (ici, Debian), il est facile à installer. On doit le lancer côté client et côté serveur (c'est un point commun entre tous ces outils : il faut un compte sur les deux machines ; on ne peut donc pas les utiliser pour tester son débit possible avec YouTube).
# Serveur % iperf -s ------------------------------------------------------------ Server listening on TCP port 5001 TCP window size: 85.3 KByte (default) # Client % iperf --print_mss --client test.bortzmeyer.org ------------------------------------------------------------ Client connecting to test.bortzmeyer.org, TCP port 5001 TCP window size: 16.0 KByte (default) ------------------------------------------------------------ [ 3] local 192.0.2.69 port 46908 connected with 203.0.113.232 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 173 MBytes 145 Mbits/sec [ 3] MSS size 1448 bytes (MTU 1500 bytes, ethernet)
On peut aussi changer la taille de la fenêtre TCP. Les 145 Mb/s obtenus ci-dessus sont probablement indépassables mais, parfois, ce changement améliore les performances. Il peut aussi les dégrader, ici, on choisit une fenêtre très petite :
% iperf --window 1K --client test.bortzmeyer.org ... TCP window size: 2.00 KByte (WARNING: requested 1.00 KByte) ------------------------------------------------------------ ... [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 27.3 MBytes 22.9 Mbits/sec
Cet exemple illustre l'importance de documenter, lorsqu'on publie les
résultats de la mesure, les options utilisées. Ici, on a divisé la
capacité utile par sept... (Quant au message d'avertissement, il vient
de l'habitude du noyau Linux de fixer la taille
de la fenêtre à une valeur double de celle qui est demandée.)
iperf permet théoriquement de faire fonctionner plusieurs sessions TCP
simultanées (option --parallel
) mais j'avoue
n'avoir pas réussi à la faire fonctionner.
Un autre outil traditionnel est ttcp. Très
ancien, il a depuis été remplacé par des versions plus récentes. Je
vais utiliser nuttcp, également en paquetage dans tous les bons
systèmes. Son serveur a la désagréable habitude de passer en
arrière-plan immédiatement (et il ne semble pas y avoir d'option pour
changer cela), et on risque donc facilement d'oublier un serveur qui
tourne. Le mieux est donc de toujours le lancer avec l'option
-1
qui ne permet qu'un seul test.
# Serveur % nuttcp -1 # Client % nuttcp -v -t 203.0.113.232 nuttcp-t: v6.1.2: socket nuttcp-t: buflen=65536, nstream=1, port=5001 tcp -> 203.0.113.232 nuttcp-t: time limit = 10.00 seconds nuttcp-t: connect to 203.0.113.232 with mss=1448, RTT=2.173 ms nuttcp-t: send window size = 16384, receive window size = 87380 nuttcp-t: available send window = 12288, available receive window = 65535 nuttcp-t: 166.5708 MB in 10.00 real seconds = 17056.72 KB/sec = 139.7286 Mbps nuttcp-t: retrans = 0 nuttcp-t: 2666 I/O calls, msec/call = 3.84, calls/sec = 266.60 nuttcp-t: 0.0user 0.0sys 0:10real 0% 0i+0d 592maxrss 0+2pf 893+0csw
On note des chiffres proches de ceux de iperf, ce qui est
rassurant. nuttcp a le même genre d'options que iperf
(-l
pour changer la taille des tampons,
-w
pour la fenêtre TCP, etc). Il peut utiliser
plusieurs sessions TCP (option -N
) mais ne semble pas
permettre de fixer la MSS.
Un outil plus récent, encore un peu expérimental mais qui a bien marché sur mes machines est ipmt. On lance le serveur ainsi :
% tcptarget IPv6 (and IPv4) protocol Using port 13000 ...
Et le client avec :
% ./tcpmt test2.bortzmeyer.org IPv4 protocol Time Packets Total | Kbit/s Avg 10 Avg 33496.429 486 486 | 5045 5045 5045 33497.345 179 665 | 2283 3805 3805 33498.467 134 799 | 1394 2950 2950 ...
et les résultats sont affichés en continu (utile si le réseau change).
Enfin, le traditionnel Netpipe ne semble plus guère maintenu et fonctionne mal sur les Unix récents.
Le RFC mentionne aussi d'autres outils comme
tcptrace, outil d'analyse des sessions
capturées au format pcap et qui, avec ses
options -r
et -l
, permet de
calculer des choses comme le RTT.
Un petit avertissement de sécurité, pour finir (section 6). Les mesures de ce RFC sont des mesures actives, susceptibles de perturber sérieusement le réseau. Le principe étant d'occuper tout le tuyau, la mesure ressemble fort à une DoS. Soyez donc prudent (RFC 4656 et RFC 5357).
Date de publication du RFC : Janvier 2012
Auteur(s) du RFC : E. Rescorla (RTFM), N. Modadugu
(Stanford University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 21 janvier 2012
Le protocole de cryptographie TLS, normalisé dans le RFC 5246, ne s'appliquait traditionnellement qu'à TCP. Les applications utilisant UDP, comme le fait souvent la téléphonie sur IP, ne pouvaient pas utiliser TLS pour protéger leur trafic contre l'écoute ou la modification des données. Mais cette limitation a disparu avec DTLS, qui permet de protéger du trafic UDP. Ce RFC met à jour DTLS (initialement normalisé dans le RFC 4347) pour TLS 1.2. (Depuis, la version 1.3 est sortie, dans le RFC 9147.)
TLS ne tournait que sur TCP car il avait besoin d'un transport fiable, garantissant que les données arrivent toutes, et dans l'ordre. Le grand succès de TLS (notamment utilisé pour HTTP et IMAP) vient de sa simplicité pour le programmeur : rendre une application capable de faire du TLS ne nécessite que très peu de code, exécuté juste avant l'envoi des données. Par contre, cela laissait les applications UDP comme SIP non protégées (section 1 de notre RFC). Les solutions existantes comme IPsec ne sont pas satisfaisantes (cf. RFC 5406), notamment parce qu'elles n'offrent pas la même facilité de déploiement que TLS, qui tourne typiquement dans l'application et pas dans le noyau.
DTLS a été conçu pour fournir TLS aux applications UDP. Il offre les mêmes services que TLS : garantie de l'intégrité des données et confidentialité.
La section 3 explique les principes de DTLS : protégé ou pas par DTLS, UDP a la même sémantique, celle d'un service de datagrammes non fiable. D'autre part, DTLS est une légère modification de TLS : il en garde les principales propriétés, bonnes ou mauvaises.
Mais pourquoi ne peut-on pas faire du TLS normal sur UDP ? Parce que TLS n'a pas été conçu pour tourner au dessus d'un protocole non fiable. TLS organise les données en enregistrements (records) et il ne permet pas de déchiffrer indépendamment les enregistrements. Si l'enregistrement N est perdu, le N+1 ne peut pas être déchiffré. De même, la procédure d'association initiale de TLS (handshake) ne prévoit pas de perte de messages et ne se termine pas si un message est perdu.
Le premier problème fait l'objet de la section 3.1. La dépendance des enregistrements TLS vis-à-vis de leurs prédécesseurs vient du chaînage cryptographique (le chiffrement par chaînage - stream cipher - est donc supprimé en DTLS) et de fonctions anti-rejeu qui utilisent un numéro de séquence, qui est implicitement le rang de l'enregistrement. DTLS résout le problème en indiquant explicitement le rang dans les enregistrements.
Et la question de l'association initiale est vue dans la section 3.2. Pour la perte de paquets lors de l'association, DTLS utilise un système de retransmission (section 3.2.1) et pour l'éventuelle réorganisation des paquets, DTLS introduit un numéro de séquence (section 3.2.2). En prime, DTLS doit gérer la taille importante des messages TLS (souvent plusieurs kilo-octets), qui peut être supérieure à la MTU. DTLS permet donc une fragmentation des paquets au niveau applicatif, un message pouvant être réparti dans plusieurs enregistrements (section 3.2.3).
Enfin, l'anti-rejeu a été modifié pour tenir compte du fait que la duplication de paquets, en UDP, n'est pas forcément malveillante (sections 3.3 et 4.1.2.6).
La définition formelle du nouveau protocole est en section 4. DTLS étant une légère évolution de TLS, la définition se fait uniquement en listant les différences avec TLS. Il faut donc garder le RFC 5246 sous la main.
Dans le Record Protocol de TLS, l'enregistrement spécifié dans la section 6.2.1 du RFC 5246 gagne deux champs (section 4.1) :
struct { ContentType type; ProtocolVersion version; uint16 epoch; // NOUVEAU uint48 sequence_number; // NOUVEAU uint16 length; opaque fragment[DTLSPlaintext.length]; } DTLSPlaintext;
notamment le numéro de séquence sequence_number
(qui était implicite dans TLS, puisque TCP garantissait l'ordre des
messages). Pour éviter la fragmentation et les
ennuis associés, les mises en œuvre de DTLS doivent déterminer
la MTU du chemin et n'envoyer que des
enregistrements plus petits que cette MTU (section 4.1.1).
Contrairement à IPsec, DTLS n'a pas la notion d'identificateur d'association. Une machine qui reçoit du TLS doit trouver l'association toute seule, typiquement en utilisant le tuple (adresse IP, port).
En toute rigueur, DTLS n'est pas spécifique à UDP, il peut marcher sur n'importe quel protocole de transport ayant une sémantique « datagrammes ». Certains de ces protocoles, comme DCCP (cf. RFC 5238), ont leur propres numéros de séquence et ils font donc double emploi avec ceux de DTLS. Petite inefficacité pas trop grave.
Au niveau du Hanshake protocol, les modifications que DTLS apporte à TLS font l'objet de la section 4.2. Les trois principales sont :
Les gâteaux de DTLS sont analogues à ceux de
Photuris ou
IKE (section
4.2.1). Le message ClientHello
de la section
7.4.1.2 du RFC 5246 y gagne un champ :
opaque cookie<0..32>; // NOUVEAU
Évidemment, ils ne protègent pas contre un attaquant qui utilise sa vraie adresse IP, puisque celui-ci pourra lire la réponse.
OpenSSL gère DTLS depuis la version 0.9.8
(on peut aussi consulter le site Web du
développeur). Un exemple d'utilisation se trouve dans http://linux.softpedia.com/get/Security/DTLS-Client-Server-Example-19026.shtml
. Il
me reste à inclure ce protocole dans echoping. GnuTLS
a un support DTLS plus récent.
Et les nouveautés de DTLS 1.2 par rapport au 1.0 du RFC 4347 ? (Il n'y a pas eu de DTLS 1.1.) Elles sont résumées dans la section 8. La principale nouveauté est que DTLS est désormais défini par rapport à TLS 1.2 et non plus 1.0. Cela a notamment permis d'inclure les numéros de séquence explicites de TLS 1.1, nécessaires contre l'attaque BEAST (section 4.1.2.1). Une autre nouveauté est la section 4.1.2.7 qui discute le traitement des paquets invalides. Contrairement à TLS, DTLS peut fonctionner en présence de tels paquets, avec une sémantique proche de celle d'UDP : les laisser tomber et attendre que l'application se débrouille (en demandant leur réémission ou bien en passant à autre chose). Enfin, d'autres clarifications ont été apportées, par exemple à la détection de la PMTU ou bien à l'enregistrement dans les registres IANA.
Une très bonne description de la conception de Datagram TLS et des choix qui ont été faits lors de sa mise au point, se trouve dans l'article The Design and Implementation of Datagram TLS, écrit par les auteurs du RFC. C'est une lecture très recommandée.
Date de publication du RFC : Août 2011
Auteur(s) du RFC : R. Bush (Internet Initiative Japan)
Expérimental
Première rédaction de cet article le 28 août 2011
Pendant longtemps, le problème technique posé à l'IETF par l'épuisement des adresses IPv4 était traité par la perspective d'une migration vers IPv6, et les efforts de l'IETF allaient vers la création de jolis mécanismes de transition vers ce nouveau protocole. Mais la migration est très loin d'être terminée (sur beaucoup de sites, elle n'a même pas réellement commencé) et, dans des régions comme l'Asie, les adresses IPv4 ne sont plus seulement difficiles à obtenir et chères, elles sont tout simplement toutes utilisées. Il faut donc maintenant, en urgence, mettre au point des mécanismes qui permettront de vivre pas trop mal en attendant le déploiement d'IPv6. C'est le cas du mécanisme A+P (Address plus Port) de ce RFC.
Tous ces mécanismes sont pour le court terme. À moyen et à long terme, la solution correcte, comme avant, reste le passage à IPv6. Toutefois, pour tous les paresseux et les irresponsables qui n'ont pas encore commencé cette migration, il est trop tard : même s'ils se réveillaient demain, ils n'auraient pas le temps de terminer leur transition vers IPv6 avant que le manque d'adresses IPv4 ne devienne un vrai blocage pour leur activité.
A+P, présenté dans ce RFC, propose une solution pour limiter les dégâts, chez les derniers utilisateurs d'IPv4. Cet article va être relativement court, par manque de temps pour explorer en détail cette technologie, mais aussi parce que je suis sceptique : c'est très gentil d'essayer de maintenir la tête des utilisateurs IPv4 hors de l'eau encore quelques mois ou quelques années, mais cela va coûter pas mal d'efforts, qui seraient mieux employés à leur apprendre à nager (à déployer IPv6).
Donc, quels sont les principes d'A+P ? Comme les miracles n'existent pas, l'idée de base est un compromis. On va sacrifier quelques bits du numéro de port pour les donner à l'adresse IP. Ce faisant, on réduit la capacité des applications à allouer beaucoup de connexions ouvertes (chacune nécessitant un port) mais il n'y a plus guère le choix. Comme le note le RFC, « the need for addresses is stronger than the need to be able to address thousands of applications on a single host » ou, en termes plus brutaux, « en cas de famine, on ne réclame pas d'assaisonnement sur tous les plats ».
Cette famine fait que le partage d'adresses IPv4, déjà largement réalisé au sein d'une même maison ou entreprise, va forcément s'étendre et que des clients différents, sans lien entre eux, partageront la même adresse IP. L'idée d'A+P est que, même si l'adresse ne sera plus unique, le couple {adresse, partie du port} restera unique par client. Avec 65536 ports possibles, on peut mettre 65536 clients sur une même adresse IP (si chacun se contente d'un seul port), 256 (avec 256 ports chacun), ou un seul (avec le système actuel où le client a 65536 ports)... L'un des intérêts d'A+P est qu'il limite (sans toutefois le supprimer) le recours au NAT et à tous ses inconvénients.
En effet, une alternative à A+P serait de déployer des gros routeurs NAT (CGN, pour Carrier-grade NAT) dans les réseaux des FAI, routeurs qui traduiraient pour plusieurs clients (au contraire du routeur NAT typique d'aujourd'hui, qui n'opère que pour un seul client). La section 1.1 explique pourquoi c'est une mauvaise idée : le CGN ne maintient pas la connectivité de bout en bout, qui est au cœur d'Internet. Par exemple, le déploiement d'une nouvelle application qui échange des adresses serait bloqué tant que le routeur CGN (qui est sous le contrôle du FAI) n'est pas mis à jour avec un nouvel ALG. Les techniques qui permettent de rendre les routeurs NAT actuels un peu moins insupportables (configuration manuelle de la redirection de port, UPnP) ne marchent en effet pas sur un CGN. Enfin, les routeurs CGN stockent un état considérable (des centaines ou des milliers de clients) et sont donc un point de faiblesse du réseau : si un routeur CGN redémarre, tout est perdu.
La section 3 détaille les contraintes que s'impose A+P, afin d'éviter ces défauts :
Ce cahier des charges est-il réaliste ? Le reste de la section 3 raconte comment fonctionne A+P. Il y a trois fonctions :
Le traducteur devra faire bien attention, contrairement au NAT actuel, à n'utiliser en sortie que des ports appartenant à la plage allouée.
La signalisation est le gros morceau (section 3.3.1). A+P peut utiliser plusieurs protocoles pour cela (à ma connaissance, tous sont encore au stade de brouillon). Le protocole doit permettre d'informer une machine A+P de l'adresse IPv4 publique à utiliser, des plages de ports réservées pour elle, de la durée pendant laquelle ces allocations restent valables, etc. L'allocation des ports peut être statique (« tu as de 20 000 à 31 000 ») ou dynamique par des nouveaux protocoles comme UpNPv2.
Si on a un site client réduit, avec une seule machine, qui connaît
A+P, et un
équipement A+P chez le FAI, et que l'adresse IPv4
publique donnée au site client est {192.0.2.1
,
ports 20 000 à 31 000}, un paquet sortant du site client est émis tel
quel (la machine sait n'utiliser comme port source que ceux alloués) et le paquet rentrant est traité ainsi dans l'équipement A+P :
Dans ce cas, pas besoin de traduction. Évidemment, dans la réalité, ce sera plus compliqué : il y aura plusieurs machines sur le site du client et, surtout, ces machines ne connaîtront pas toutes A+P et émettront donc des paquets avec des ports source quelconques. Cette fois, on ne pourra pas se passer de traduction : une machine chez le client (et non pas chez le FAI) va alors traduire ces paquets pour mettre l'adresse source allouée et changer le port source pour un des ports alloués. Au retour, ce même traducteur fera l'opération inverse, très proche de celle des routeurs NAT d'aujourd'hui.
Est-ce que tout cela marche vraiment en pratique ? La section 3.4 rend compte des essais effectués à France Télécom. Les plus gros problèmes sont survenus avec des mises en œuvre de BitTorrent, qui veulent accepter des connexions entrantes sur un port précis mais, globalement, il n'y a pas eu trop de problèmes.
Si vous aimez les considérations pratiques, la section 5 est vouée aux problèmes de déploiement. Par exemple, pour des sites client en ADSL ou connectés par le câble, le modèle le plus logique est que les fonctions de traduction soient dans la box, le FAI allouant les plages de ports et les communiquant audit CPE. (Pour un réseau 3G, c'est plus complexe, car le smartphone ne peut pas forcément assurer beaucoup de fonctions.)
Comment le FAI décide-t-il de l'allocation des ports (section 5.2) ? Une solution évidente est de diviser équitablement. Si on met cent clients par adresse IP, chacun a 655 ports et se débrouille avec. Le risque de cette allocation statique est alors que les clients les plus gourmands soient limités, alors que les autres ont des ports libres. L'idéal serait donc que l'allocation soit dynamique, s'ajustant à la demande.
Comme avec le NAT, certains protocoles vont poser des problèmes particuliers. Ainsi, ICMP (section 5.3.2), n'ayant pas le concept de port, va être difficile à faire passer. Pour les messages d'erreur transportés par ICMP, comme ils incluent le début du paquet qui a provoqué l'erreur, on peut y trouver un numéro de port et router par ce biais. Pour les messages d'écho (ceux qu'utilise ping), il n'y a pas d'autre solution que de bricoler avec des champs comme l'identificateur du message ICMP, ou comme le numéro de séquence ICMP, en les utilisant comme numéros de port.
Parmi les autres problèmes concrets que devra résoudre la machine A+P, il y a enfin la fragmentation, source traditionnelle d'ennuis. Ici, le routage se faisant en fonction du port de destination, un réassemblage des fragments entrants est nécessaire, pour déterminer ledit port.
A+P, on l'a vu, est un système complexe. Il a quelques limitations, documentées en section 5.3.4. La principale est que les ports bien connus, notamment le célébrissime port 80, utilisé par les serveurs HTTP, ne seront pas forcément disponibles. Si le client qui a obtenu une plage de ports située au début (du côté des ports bien connus, en dessous de 1024) est heureux (et on peut même envisager de le faire payer plus cher pour ce « privilège »), les autres n'ont pas de solution, s'ils veulent faire tourner un serveur HTTP sur leur machine.
Enfin, A+P marche mal ou pas du tout avec IPsec, bien qu'il soit possible de contourner le problème avec les techniques du RFC 3715.
Et question sécurité, ça se passe comment ? La section 7 fait la liste des questions de sécurité liées à A+P. La première est la difficulté de suivre à la trace un utilisateur. Pour savoir qui a osé commettre un délit aussi grave que de partager de la culture, il faut que l'espion qui surveille le trafic ait noté le numéro de port source (cf. RFC 6302), et que l'équipement A+P ait enregistré qui avait la plage où se trouve ce numéro. A+P est donc plus efficace pour le flicage qu'un CGN ou qu'un NAT traditionnel, qui doit noter une information bien plus évanescente (qui avait ce port à ce moment-là). Reste à savoir si c'est un avantage...
Quel est l'état des implémentations de A+P au moment de la
publication de ce RFC ?
L'ISC a A+P dans son routeur logiciel (surtout connu pour DS-Lite) AFTR (qui ne semble
actuellement pourvoir faire que de l'allocation de ports statique), France
Télécom / Orange a également un logiciel libre en http://opensourceaplusp.weebly.com/
, et il existe le logiciel
4RD de la société ipinfusion.com.
Pour le futur, Iskratel et, dans une moindre
mesure, Cisco et
Juniper, ont indiqué qu'ils y travaillaient.
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : M. Westerlund (Ericsson), C. Perkins (University of Glasgow)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mmusic
Première rédaction de cet article le 20 juillet 2011
Le protocole de traversée des NAT, ICE (normalisé dans le RFC 5245), offre la possibilité d'ajouter des options, identifiées par un nom (section 14 du RFC 5245). Mais aucun registre n'existait pour stocker les noms de ces options et éviter des collisions. C'est désormais fait.
Il n'y a pas encore une seule option utilisée par les mises en œuvre d'ICE. Mais une est en cours de développement et cela a motivé la création de ce registre. Donc, une option a un nom, composé d'une série de caractères alphanumériques (on peut aussi utiliser le + et le /). Ce nom est enregistré en suivant la règle « spécification (écrite et publique) obligatoire » de la section 4.1 du RFC 5226, et en indiquant diverses métadonnées comme les coordonnées de la personne ou de l'organisme qui enregistre.
Et c'est tout, le registre (actuellement vide) se trouve en https://www.iana.org/assignments/ice-options/ice-options.xml
.
Date de publication du RFC : Août 2011
Auteur(s) du RFC : M. Cotton (ICANN), L. Eggert
(Nokia), A. Mankin (Johns Hopkins
Univ.), J. Touch
(USC/ISI), M. Westerlund
(Ericsson), S. Cheshire (Apple)
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 3 septembre 2011
Ce RFC parle autant de gouvernance que de technique. Il refond considérablement les procédures utilisées pour enregistrer les numéros de port à l'IANA. Bien que moins médiatisé que l'enregistrement des noms de domaine, ou même que celui des adresses IP, cet enregistrement des ports a déjà suscité des conflits, et peut en faire encore plus maintenant qu'une des plages utilisées approche de la saturation. L'ancien mécanisme d'enregistrement était peu documenté, avait plusieurs limites techniques, et était éclaté entre plusieurs registres ayant des règles différentes. Le nouveau vise à unifier tout cela et à suivre de bons principes, soigneusement explicités.
D'abord, de quoi s'agit-il (section 3) ? Les ports sont des numéros, codés sur 16 bits, qui
servent à démultiplexer les paquets IP entrant
dans une machine (port de destination 62981 -> processus 7653, qui
fait tourner dig, etc) et à identifier le
protocole utilisé (port 80 -> HTTP, port 22
-> SSH, etc). Les noms de services, eux,
sont des courts identificateurs alphabétiques, qui servent à
s'abstraire du numéro de port, en permettant aux applications
d'utiliser un nom de service pour récupérer dynamiquement un numéro de
port (par exemple avec les enregistrements SRV
du DNS, ou bien avec un appel à getservbyname()
). Sur Unix, vous
avez une liste (incomplète) de ces noms, avec le numéro de port
correspondant, dans le fichier /etc/services
. Pendant longtemps, les registres
officiels stockaient à la fois un nom de service et un numéro de
port. Désormais, ils pourront ne contenir qu'un nom de service.
Le port n'est pas indiqué dans l'en-tête IP mais dans celle du protocole de couche 4 au dessus. On peut donc techniquement utiliser le même numéro de port pour des applications différentes, si l'une utilise UDP et l'autre TCP. La procédure d'enregistrement, elle, est désormais la même pour tous les protocoles de transport.
Les en-têtes de couche 4 incluent deux ports, celui de source et celui de destination, et, avec les adresses IP source et destination et l'identificateur du protocole de transport, ils servent aussi à identifier une connexion de manière unique.
Du fait que l'ancien système d'enregistrement à l'IANA allouait en
même temps un nom de service et un numéro de port, bien des
applications savent utiliser ce nom de service. Par exemple, avec
telnet, on peut se connecter à un serveur de
courrier avec
telnet mail.example.net 25
(le numéro de port)
mais aussi avec telnet mail.example.net smtp
(le
nom du service). Le port ainsi enregistré est dit « bien connu » (80
pour HTTP...) Mais attention : de nos jours, il est courant de
faire tourner une application sur un port autre que celui prévu à
l'origine (parce que le pare-feu ne laisse
passer que le port 80, pour échapper à la détection, ou encore
parce qu'on veut faire tourner deux mises en œuvre différentes
du protocole sur la même machine, ou derrière le même routeur NAT). Enfin,
certaines applications n'ont pas de port fixe et comptent sur les
enregistrements SRV du DNS (RFC 2782), ou bien sur d'autres méthodes (comme les
trackers dans BitTorrent).
Un dernier points sur les numéros de port : comme ils sont stockés sur seulement 16 bits, il n'y a que 65 536 valeurs possibles. C'est très peu. La première plage, celle des ports bien connus, est déjà pleine à 76 %. Un des objectifs de la politique d'allocation des ports est donc d'épargner cette ressource limitée, notamment en conseillant fortement aux applications d'utiliser uniquement un nom de service, sans réserver de numéro de port.
Le plan du RFC commence par expliquer la situation actuelle et pourquoi elle n'est pas satisfaisante. Mais je préfère partir de la nouvelle situation, celle qui est désormais l'officielle, et parler du passé tout à la fin de cet article.
D'abord, les noms de services (section 5). Ce sont les clés d'accès au registre des services. Les applications les utilisent pour chercher un numéro de port, typiquement via les enregistrements SRV du RFC 2782. Il peut y avoir plusieurs services qui se partagent un numéro de port, par exemple :
turn
permet à une
application d'obtenir tout de suite un serveur ayant l'extension TURN,
sans tester plusieurs serveurs STUN),www
et
http
qui pointent vers le même port 80 ; seul
http
est correct, aujourd'hui),Les noms de services dans le registre sont enregistrés sur une base « premier arrivé, premier servi », tel que décrit dans le RFC 5226 (voir aussi la section 7.2). Contrairement aux numéros de port, il n'y a pas de pénurie et donc pas de raison de faire des économies, sauf si l'IANA détecte un problème (comme un enregistrement massif de noms) auquel cas elle peut passer au mécanisme Expert review, où un examen de fond est fait. Les noms doivent être courts (quinze caractères maximum) et informatifs, et éviter les redondances (comme de mettre protocole ou port dans le nom).
La syntaxe des noms (une nouveauté de ce RFC) est décrite en
section 5.1. En résumé, seuls les lettres
d'ASCII, les chiffres et le
tiret sont admis. Il faut au moins une lettre,
pour éviter des noms de service comme 23, qui pourrait être pris pour
un numéro de port. 98 % des noms du registre étaient déjà conformes à
cette syntaxe
avant ce RFC, les 2 % restants ont dû changer de nom pour se plier à
la nouvelle syntaxe. C'est ainsi que, par exemple,
z39.50
(pour le protocole du même
nom) est
devenu z39-50
.
Dans le cas le plus courant, l'application va traduire ces noms en
numéro de port via une requête DNS. Prenons
l'exemple de XMPP. Si le serveur de
messagerie instantanée de Google Talk veut contacter un utilisateur dont
l'adresse XMPP est martinedurand@dns-oarc.net
,
le serveur de Google va faire une requête SRV pour le service
xmpp-server
, protocole TCP (RFC 6120, section 3.2.1). Il trouvera :
% dig SRV _xmpp-server._tcp.dns-oarc.net ... ;; ANSWER SECTION: _xmpp-server._tcp.dns-oarc.net. 3600 IN SRV 0 0 5269 jabber.dns-oarc.net.
et saura donc qu'il doit se connecter au port 5269. (Le fait que le champ « service » du RFC 2782 doive être un nom de service enregistré n'était pas clair : c'est notre nouveau RFC qui impose cette règle.)
L'enregistrements des numéros de port est plus complexe, en raison du risque de pénurie (section 6). Il y a trois plages de numéros de port :
Il y a trois statuts possibles pour un numéro de port :
Aujourd'hui, 76 % des ports système et 9 % des ports utilisateur sont affectés.
Il existe aussi des ports voués à des usages expérimentaux (section 6.1, voir aussi le RFC 3692), les ports 1021 et 1022. Comme des tas de protocoles peuvent s'y bousculer, les applications qui utilisent ces ports doivent s'assurer qu'elles se connectent bien au service attendu (par exemple, le client peut vérifier que le serveur envoie un nombre magique caractéristique de l'application).
Comment enregistre-t-on un nouveau numéro de port ? La section 7 décrit les grands principes. Le plus important est la nécessité d'allouer lentement, pour éviter d'épuiser ce qui reste de cette ressource (si vous développez un nouveau protocole, rappelez-vous que la méthode recommandée est de ne pas réclamer de numéro de port du tout, mais d'utiliser un nom de service). Environ 400 ports par an sont affectés, et le chiffre est stable depuis des années. Cela devrait permettre de tenir jusqu'à la fin du 21ème siècle.
Compte-tenu de cela, les nouveaux principes, exposés en section 7.2 sont :
Les ports « repris » auront le statut Réservé (sur l'Internet, il n'est pas prudent de réallouer des ports trop tôt, on ne peut jamais être sûr de ce qui traîne dans des vieilles applications, cf. section 8.3). Le jour où une plage de numéros de port est épuisée, l'IANA pourra recycler ces vieux numéros en les affectant.
Tout le détail des procédures bureaucratiques est en section 8. Si on veut un numéro de port ou un nom de service, il faut remplir un formulaire (section 8.1.1) indiquant les coordonnées du demandeur (pour les normes au sens propre, ce demandeur sera l'IETF), une description du protocole prévu et le nom du protocole de transport (TCP, UDP, etc). Si on veut un numéro de port, on peut préciser lequel (et l'IANA le donnera, sauf bonne raison contraire). Les ports rigolos comme 42, 666 ou 1984 (utilisé par un logiciel de surveillance) sont déjà pris.
Rappelez-vous qu'il y aura une grosse différence entre demande d'un numéro de port et demande d'un simple nom de service. Les premiers feront l'objet d'une Expert Review (cf. RFC 5226), le seconds seront distribués sans trop de formalité. Pour les numéros de port, cela dépendra en outre de la plage visée. La plage dynamique ne permet pas de réservation du tout, la plage utilisateur est recommandée pour les nouvelles réservations, la plage système, celle des ports bien connus, est tellement pleine que l'enregistrement est découragé, un avis d'expert ne suffira pas, il faudra un IETF review et encore, après avoir expliqué en détail pourquoi ne pas utiliser un port de la plage utilisateur.
Nouveauté de notre RFC, il y a désormais des procédures explicites pour le retrait d'un enregistrement (section 8.2 ; cela concerne surtout les numéros de port, les noms de service peuvent rester enregistrés sans que cela ne gène personne). Le demandeur original peut demander un retrait, s'il n'a plus besoin de l'enregistrement. Mais l'IANA peut aussi le faire d'autorité, si cela semble vraiment nécessaire.
Dans tous les cas, l'IANA tentera de déterminer si le port est encore utilisé.
En revanche, le transfert d'un enregistrement (numéro de port ou nom de service) d'un protocole à un autre est formellement interdit (section 8.4), même entre adultes consentants. Pas de marché des numéros de port, qui aurait permis à ceux qui avaient déposé des numéros il y a longtemps de gagner de l'argent en les vendant maintenant qu'ils sont rares. Si on veut récupérer un numéro de port, il faut le faire désaffecter, puis candidater pour l'avoir.
Il y aura sans doute des désaccords et des crises (comme dans l'affaire CARP). La procédure habituelle de gestion des conlits à l'IETF (section 7 du RFC 5226) sera donc utilisée.
Un peu d'histoire, maintenant. Quels étaient les procédures avant notre RFC ? Les règles IANA étaient dans le RFC 2780 et notre RFC remplace ses sections 8 et 9. Il y avait aussi des règles spécifiques aux différents protocoles de transport : RFC 3828 pour UDP-Lite, RFC 4340 pour DCCP, et RFC 4960 pour SCTP. Mais elles n'étaient pas complètes (une partie de la procédure était également dans les formulaires Web de soumission à l'IANA, une autre partie était dans le texte du registre), et aussi bien l'IANA que ses « clients » se plaignaient de leur flou (section 1). La section 7.1 de notre RFC 6335 tente de résumer a posteriori les règles (largement informelles) qui étaient utilisées (affectation du port pour TCP et UDP simultanément, pas d'enregistrement des noms de service séparément des ports, SCTP et DCCP traités à part, etc).
En outre, les enregistrements SRV du RFC 2782 ajoutaient leurs propres concepts (nom de service, notion mal définie dans le RFC 2782) et leur propre registre. Ainsi, comme les procédures de l'IANA ne permettaient pas d'enregistrer un nom de service sans obtenir en même temps un numéro de port, on a vu apparaître un registre informel des noms de service (qui a fusionné avec l'officiel, cf. section 10). Un des changements importants de ce RFC 6335 est d'unifier les procédures d'enregistrement et les registres.
La syntaxe admissible pour les noms de service n'avait même jamais
été spécifiée (section 2). Les formulaires de l'IANA donnaient une limite de
longueur (arbitraire et, d'ailleurs, pas toujours respectée dans le registre) à 14 caractères, mais sans préciser si des
caractères comme le + ou le
/ étaient autorisés. On trouvait donc des noms
avec des caractères non-alphanumériques
comme whois++
(RFC 2957) ou sql*net
.
D'autre part, il n'existait aucune procédure écrite pour les opérations postérieures à l'enregistrement : changement, ou suppression (volontaire ou forcée).
PS : si vous vous intéressez aux questions d'enregistrement de paramètres pour les protocoles, voyez la nouvelle liste de discussion happiana.
Date de publication du RFC : Août 2011
Auteur(s) du RFC : A. Durand (Juniper Networks), R. Droms (Cisco), J. Woodyatt (Apple), Y. Lee (Comcast)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF softwire
Première rédaction de cet article le 14 août 2011
Il existe une myriade de techniques de coexistence entre l'ancien protocole IPv4 et le nouvel IPv6, à tel point qu'on peut même avoir du mal à faire son choix (voir mon exposé à ce sujet). Et le groupe de travail Soft Wires (réseaux virtuels variés) de l'IETF en invente de temps en temps des nouvelles. Pour ne pas s'affoler devant cette multitude, il faut se rappeler que chacune de ces techniques a un but bien précis et sert dans un cas donné. DS-Lite (Dual-Stack Lite), objet de ce RFC, vise les FAI récents, qui n'ont jamais eu d'adresses IPv4 publiques en quantité et dont le réseau interne est en IPv6 depuis le début.
Donc, DS-Lite est à l'opposé de, par exemple, 6rd (RFC 5969), qui vise les FAI existants qui n'ont pas le courage de mettre à jour leur réseau IPv4. DS-Lite vise un autre problème : si, en 2011, je crée un nouveau FAI en Asie (APNIC a été le premier RIR dont le stock d'adresses IP est tombé à zéro), je n'obtiendrai dans le meilleur des cas qu'une poignée d'adresses IPv4 publiques. Mais le reste de l'Internet (et même le réseau local de mes clients, et leurs applications) est majoritairement en IPv4. Mon beau réseau tout neuf, qui pourra être IPv6 depuis le début puisqu'il n'aura pas à porter le poids de l'héritage, ne me servira donc à rien (sauf à voir ce blog, qui est accessible en IPv6). Ce cas n'était pas prévu à l'origine ; il y a eu largement assez de temps pour faire une transition plus simple de IPv4 vers IPv6 mais beaucoup d'acteurs ont traîné les pieds, nous amenant à la situation actuelle, où il faut déployer IPv6 sans pouvoir compter sur des adresses v4 publiques en quantité suffisante. DS-Lite arrive alors à la rescousse.
Le principe de DS-Lite est donc de connecter à l'Internet IPv4 (et bien sûr aussi IPv6) des machines IPv4 (les machines des clients) au dessus d'un FAI v6, et sans avoir beaucoup d'adresses IPv4 publiques. (Les machines purement IPv6 ne sont donc pas concernées, elles ont une connexion native normale, seules les machines/applications qui utilisent encore IPv4 doivent passer par ce bricolage.) Le principe : le réseau local du client a des adresses privées v4. La box encapsule les paquets v4 au dessus du réseau v6 (tunnel IPv4-dans-IPv6) jusqu'à un NAT géant (CGN) qui traduit ces adresses en adresses publiques (il faut donc avoir au moins quelques adresses IPv4 publiques). DS-Lite réutilise donc deux techniques éprouvées, le tunnel et le NAT.
Pour suivre la description détaillée, un peu de vocabulaire (section 3). DS-Lite nécessite deux composants :
Entre le B4 et l'AFTR, il n'y a qu'IPv6 : tous les paquets IPv4 doivent être tunnelés. Enfin, pour suivre ce RFC, il peut être utile de réviser le vocabulaire de la double-pile (RFC 4213) et du NAT (RFC 4787).
Voici un schéma d'une communication avec le serveur Web d'adresse
192.0.2.23
. L'adresse IPv4 publique utilisée par
l'AFTR est 203.0.113.201
. Le réseau IPv6 du FAI
utilise 2001:db8::32
. Le réseau local reçoit des
adresses en 10.0.0.0/24
:
La section 4 décrit plus en détail les scénarios envisageables pour DS-Lite. Rappelez-vous d'un des points les plus importants des techniques de transition/coexistence v4/v6 : on n'est pas obligés de les déployer toutes, bien au contraire. Chacune s'applique à des cas spécifiques. Les avantages essentiels de DS-Lite, vus par le RFC :
J'ai indiqué qu'un déploiement typique mettrait le B4 dans le CPE, dans la box. Ce n'est pas la seule possibilité. Mais ce sera sans doute la plus fréquente (l'annexe B décrit les différentes architectures, avec le détail des adresses). La section 4.2 décrit les caractéristiques d'un CPE ayant une fonction DS-Lite : il inclut un serveur DHCP pour distribuer des adresses IPv4 privées (RFC 1918) sur le réseau local, il ne fait pas de NAT lui-même (contrairement aux CPE d'aujourd'hui), il n'a pas d'adresse IPv4 publique, et, en IPv6, il est simplement un routeur ordinaire, sans traduction, ni particularités (connexion IPv6 native pour les clients qui en sont capables).
S'il n'y a pas de CPE (cas typique d'un smartphone connecté à un réseau 3G), la section 4.3 prend le relais : dans ce cas, la machine connectée doit être son propre B4.
La section 5 décrit en détail la fonction B4. Elle comprend la tunnelisation des paquets IPv4 vers l'AFTR. Au fait, comment le B4 connait-il son AFTR (section 5.4) ? Il doit être configuré avec l'adresse IPv6 de celui-ci, ou bien la récupérer via DHCP avec l'option du RFC 6334.
Pour le service DNS, le B4 doit connaître les adresses IPv6 des serveurs récursifs du FAI (rappelez-vous que la machine qui fait le B4 n'a typiquement pas d'adresse IPv4 publique), par exemple via DHCPv6. Les machines du réseau local, n'ayant pas forcément IPv6, il faut leur fournir un serveur récursif v4. Le RFC recommande que le B4 joue ce role et s'annonce lui-même comme récurseur (et suive alors les recommandations du RFC 5625).
Enfin, le B4 a besoin d'une adresse IPv4 à lui, pour les paquets
dont il est l'origine. La plage 192.0.0.0/29
a
été réservée pour cela (cf. section 10), le 192.0.0.2
étant pour
le B4. Ce préfixe a d'ailleurs été élargi ultérieurement à d'autres systèmes que DS-Lite dans le RFC 7335.
La section 6 fait la même chose (décrire tous les détails) pour la
fonction AFTR, qui est à la fois la terminaison du tunnel
IPv4-and-IPv6 et le CGN (Carrier-Grade NAT). Par
exemple, l'AFTR n'a pas de fonction DNS à assurer (le B4 fait la
résolution sur IPv6). Il a lui aussi une adresse bien connue,
192.0.0.1
, et c'est celle qu'on verra sans doute
souvent lors des traceroute.
Pour que tout cela marche bien, il y a quelques détails techniques à régler. La section 7 couvre ceux qui concernent le réseau : notamment, le tunnel doit respecter les règles des RFC 2473 et RFC 4213. Et la section 8 couvre les détails liés au NAT : possibilité pour un AFTR d'avoir plusieurs plages d'adresses IPv4 publiques, pour des ensembles de B4 différents, conformité impérative aux RFC sur le NAT, comme les RFC 4787, RFC 5508 et RFC 5382, précisions sur la possibilité pour l'AFTR d'être aussi un ALG (découragée, vue le nombre de clients que sert un AFTR, et le nombre de protocoles applicatifs présents et futurs), rappel que tout partage d'adresses, que ce soit par DS-Lite ou une autre méthode, engendre des ennuis (RFC 6269), etc.
L'annexe A du RFC est particulièrement intéressant pour les administrateurs réseaux car il détaille les scénarios de déploiement possibles. Il couvre des questions comme le placement des AFTR dans le réseau, ou la fiabilité requise des AFTR (ils ont un état donc on ne peut pas juste en multiplier le nombre).
Comme tout nouveau protocole, DS-Lite va soulever des questions de
sécurité nouvelles, qu'étudie la section 11 du RFC. En soi, les
problèmes de sécurité liés au NAT sont bien connus (RFC 2663
et RFC 2993). Mais déplacer la fonction NAT depuis une
machine située chez l'utilisateur vers le réseau du FAI crée des
nouveaux défis. Par exemple, les adresses IPv4 publiques, qui
n'étaient partagées qu'entre les membres d'une même famille ou les
employés d'une même entreprise, vont désormais être partagées entre
des clients du même FAI, clients qui ne se connaissent pas. Si la
HADOPI voit 203.0.113.201
commettre un crime grave (par exemple partager des œuvres
d'art), et qu'elle veut couper l'utilisateur de cette adresse, la
probabilité de bavure devient bien plus élevée. Enregistrer les
adresses IP ne suffit donc plus, il faut noter l'adresse IP
et le port (RFC 6302) et que l'AFTR enregistre ses tables de
correspondance (identité du tunnel, protocole, adresses et
ports), comme précisé en section A.4.
Vu le partage intensif d'adresses (bien plus important qu'avec les NAT sur le CPE), le nombre de ports devient une ressource critique. L'AFTR doit donc faire attention à empêcher les utilisateurs de monter une DoS (volontairement ou par accident) en s'attribuant tous les ports possibles. Par exemple, l'AFTR peut limiter le rythme d'allocation des ports, ou bien mettre une limite absolue au nombre de ports qu'un B4 peut s'allouer.
Enfin, l'AFTR doit veiller à ne pas se transformer lui-même en un outil facilitant les DoS. Par exemple, il ne doit pas permettre à l'autre extrémité du tunnel d'injecter des paquets IPv4 avec d'autres adresses sources que celles prévues (autrement, les réponses à ces paquets frapperaient un innocent).
Notre RFC ne mentionne pas les inconvénients et problèmes de DS-Lite : c'est un mécanisme complexe, avec plusieurs composants qui doivent travailler en bonne intelligence. DS-Lite dépend notamment d'un composant très sollicité, le CGN. Sera t-il suffisant lorsque des dizaines ou des centaines de réseaux locaux utiliseront le même AFTR ? En outre, comme indiqué plus haut, DS-Lite souffre des problèmes liés au partage d'adresses : les lois HADOPI ou LCEN ne seront pas contentes.
Si, à ce stade, vous êtes convaincu de l'intérêt de DS-Lite dans
votre cas, où trouver des implémentations ? Il existe un AFTR en
logiciel libre à l'ISC, disponible en http://www.isc.org/software/aftr
. Comcast
a aussi produit un code pour Linksys
(apparemment pas très stable mais suffisant pour des tests) et un pour
Mac OS (nommé ComcastDSLiteClient). L'ISC a rassemblé une documentation globale sur le B4. Enfin, les routeurs
d'A10 ont la fonction d'AFTR. Verrons-nous bientôt la
fonction de B4 dans tous les routeurs et boxes ?
Impossible à dire pour l'instant.
Merci à Fabien Delmotte pour ses connaissances sur les mises en œuvre de DS-Lite.
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : M. Azinger (Frontier Communications), L. Vegoda (ICANN)
Pour information
Première rédaction de cet article le 20 juillet 2011
Il y a bien longtemps que la pénurie d'adresses IPv4 est une réalité. Longtemps avant leur épuisement complet, ces adresses étaient très difficiles à obtenir, nécessitant un long processus bureaucratique (et le remplissage de nombreux documents), ou tout simplement l'abonnement à une offre qualifiée de « professionnelle » ou « gold » dont le seul intérêt était d'avoir quelques adresses de plus. Résultat, beaucoup d'organisations ont choisi des adresses IP privées et des systèmes de relais ou de traduction d'adresses pour se connecter à l'Internet. Si l'organisation ne grossit pas par la suite, tout va bien. Mais si elle devient plus importante et dépasse la taille permise par les plages d'adresses privées existantes, que se passe-t-il ?
La section 3 du RFC détaille les mécanismes utilisés pour se connecter à l'Internet malgré l'absence d'adresses IP publiques. La principale est sans doute le NAT (RFC 2993 et RFC 3022). Le NAT a de multiples inconvénients, notamment pour les applications pair-à-pair, même si certaines techniques (comme ICE, RFC 8445) permettent de contourner partiellement le problème.
On peut emboîter plusieurs niveaux de NAT, mettant par exemple un traducteur dans la maison ou le bureau et un autre sur le réseau du FAI (on nomme souvent ce double-NAT NAT444). Si le FAI contrôle le CPE et donc les adresses IP qu'il alloue (cas de la Freebox par défaut, par exemple), cela peut marcher. C'est bien plus délicat si le CPE alloue les adresses qu'il veut car, alors, rien ne garantit qu'elles ne seront pas en conflit avec celles utilisées dans le réseau interne du FAI. Bref, le NAT444 ajoute de la complexité et des problèmes. Enfin, toute traduction d'adresses effectuée hors du réseau local de l'abonné soulève les problèmes liés au partage d'adresses que le RFC 6269 documente.
Le plus large bloc privé est le 10.0.0.0/8
(cf. RFC 1918). Il a parfois été suggéré
d'allouer de nouveaux blocs pour agrandir l'espace privé mais ce
projet a très peu de chances de se matérialiser désormais, vu l'épuisement des adresses
IPv4. Ce bloc 10.0.0.0/8
comprend
16 777 216 adresses IP. Qui peut en consommer autant ? Comme le résume
la section 2 de notre RFC, les gros opérateurs, par exemple un
câblo-opérateur national (comme
Comcast, non cité mais qui est effectivement
dans ce cas), un opérateur de téléphonie mobile
3G, un gros fournisseur
VPN, l'intranet d'une
grosse entreprise, peuvent tous se trouver à l'étroit dans ce /8.
Quelles sont les possibilités une fois les adresses du RFC 1918 épuisées ? La section 4 les passe en revue. La première (section 4.1) est évidemment de passer enfin à IPv6, ce qui aurait dû être fait depuis longtemps. Le RFC note à juste titre que déployer IPv6 sur un réseau dont la taille est telle qu'il arrive à épuiser un /8 entier n'est pas une opération triviale. Elle va prendre du temps et c'est pour cela que ces opérateurs auraient dû commencer il y a des années. Si cela n'a pas été fait, l'opérateur peut se trouver dans le cas où les adresses du RFC 1918 sont épuisées et où il n'a matériellement pas le temps de déployer IPv6.
Notons que les adresses IPv6 utilisées ne sont pas forcément globales, on peut aussi déployer IPv6 avec des ULA (RFC 4193). Toutefois, celles-ci ne sont que pseudo-uniques donc, dans des cas comme celui du fournisseur de VPN, le risque de collision existe.
Bon, et pour les administrateurs réseaux qui, en 2011, n'ont toujours pas déployé IPv6, quelles solutions ? La section 4.2 liste les solutions purement v4. Obtenir de nouvelles adresses était la solution classique. Mais ajourd'hui, où les RIR qui ont encore des adresses IPv4 les épuisent vite et passent à la politique d'allocation finale, cela ne parait pas très réaliste.
La seconde solution est d'acquérir des adresses IP d'autres organisations, comme l'avait fait Microsoft dans une opération fameuse. Cette opération peut désormais être légale vis-à-vis des RIR comme le montre l'étude comparée de leurs politiques de transfert. Les possibilités pratiques d'un tel transfert sont très incertaines. Y aura-t-il assez d'adresses sur ce « marché » ? Et à quel coût ? Personne ne le sait trop. Mais le RFC est pessimiste : on ne trouvera probablement pas de larges blocs d'adresses continus ainsi, il est plus probable qu'il n'y aura qu'une poussière de /24 et /23. (Le RFC discute aussi la possibilité de locations de tels blocs, encore pire car sans garantie sur ce qui arrivera au terme de la location.)
Il y a bien sûr une autre possibilité. Après tout, qui a dit qu'il fallait être honnête et respecter les règles de vie en société ? Comme le montre l'exemple d'innombrables hommes d'affaires, on réussit bien mieux en violant ces règles et en écrasant les autres. La section 4.2.2 du RFC est donc consacrée à la solution libérale : prendre ce qui vous intéresse sans se poser de questions, ici, utiliser des adresses IP non encore allouées, ou bien allouées à quelqu'un mais pas annoncées dans la table de routage mondiale. L'article de Duane Wessels montre bien que l'espace non alloué est déjà utilisé. C'est évidemment très mal de faire cela : les rares blocs non encore alloués vont l'être bientôt (et cela fera une collision avec ceux du voleur, avec des conséquences imprévisibles), et ceux qui ne sont pas annoncés dans la table de routage publique le seront peut-être demain. Même si ce n'est pas le cas, la collision est toujours possible (cela dépend de la façon dont est configuré le réseau qui utilisait ces adresses mais, par exemple, les adresses internes fuient souvent, par exemple dans les en-têtes de courrier). La section 2.3 du RFC 3879 discute plus en détail ce problème. Il y a aussi bien sûr des risques juridiques à jouer avec les adresses des autres. Cela peut expliquer pourquoi les voleurs d'adresses préfèrent utiliser des préfixes alloués à des opérateurs peu dangereux juridiquement, par exemple en Afrique.
Quelle solution pourrait-on développer ? La section 5 examine
plusieurs possibilités : la première est d'agrandir le RFC 1918 en y ajoutant des préfixes actuellement marqués comme
publics. Cela réduirait encore plus le stock d'adresses IPv4
disponibles. Plusieurs propositions avaient été faites de réserver,
par exemple un /8 supplémentaire. Par exemple, le réseau
1.0.0.0/8
était tentant car son utilisation
publique soulevait des problèmes. Comme
indiqué plus haut, il est clair
que cela se fait déjà, de manière officieuse. Aucune de ces
propositions n'a été adoptée officiellement et leurs
chances semblent désormais nulles. (Voir la discussion
à NANOG.)
Il y a en effet pas mal de systèmes qui traitent les adresses du RFC 1918 de manière spéciale, et où ces adresses sont codées en dur. Il y a peu de chances de pouvoir mettre à jour tous ces systèmes. Déjà, dé-bogoniser les plages allouées est très difficile.
Dernière possibilité, réaffecter une plage réservée,
240.0.0.0/4
, qui avait été mise de côté pour des
usages futurs qui ne se sont jamais concrétisés. Le problème est que
beaucoup de systèmes déployés traitent de manière spécifique ces
adresses et qu'il y a peu de chance de pouvoir les changer tous. En
pratique, elles seront donc largement inutilisables. Par exemple, sur Linux :
% sudo ifconfig eth1 240.0.0.1/24 SIOCSIFADDR: Invalid argument
(Mais ça marche sur FreeBSD et NetBSD). L'Internet-Draft draft-fuller-240space
documente ce problème pour quelques systèmes.)
Bref, même si le RFC ne le rappelle pas, il n'y a pas vraiment d'autre solution que de migrer vers IPv6.
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : M. Komu (Helsinki Institute for Information Technology), T. Henderson (The Boeing Company)
Expérimental
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 23 juillet 2011
Il ne sert à rien de disposer d'un nouveau protocole si les applications ne s'en servent pas. Et, pour qu'il y ait une chance qu'elles s'en servent, il faut qu'elles aient une API standard pour cela. Ce RFC spécifie une possible API pour le protocole HIP (RFC 9063), un protocole qui sépare l'adresse IP de l'identité d'une machine. Celle-ci est désormais une clé cryptographique et l'API permet d'établir des connexions en connaissant la clé.
Cette API ne concerne pour l'instant que le langage C. Son utilité principale commence lorsque l'identificateur HIP a été obtenu (par exemple par le DNS, cf. RFC 8005) et lorsque l'adresse IP est connue. Elle prévoit toutefois d'autres cas. Spécifique à HIP, elles pourrait toutefois être étendue dans le futur à d'autres protocoles réalisant une séparation du localisateur et de l'identificateur, comme SHIM6 (RFC 5533). Notez que cette API utilise déjà certaines extensions créées pour SHIM6 et spécifiées dans le RFC 6316.
À quoi ressemblent les identificateurs que manipule cette API ?
Nommés HIT pour Host Identity
Tag, ce sont des résumés cryptographiques des clés publiques des
machines (clés nommées HI pour Host
Identity). Stockés sur 128 bits, ils sont, pour faciliter
leur traitement, représentés sous forme d'adresses
IPv6, en utilisant le préfixe ORCHID décrit
dans le RFC 4843. Par exemple,
2001:10::1
est un HIT.
Certaines applications, ignorantes de ce qui se passe dans les couches basses, n'auront pas besoin d'être modifiées pour HIP (cf. RFC 5338). Les autres doivent suivre notre RFC, dont la section 1 expose les principes généraux :
Bien, commençons par le commencement, la résolution de noms
(section 3). D'abord, le cas où l'application a un
résolveur à sa disposition (section
3.1). Celui-ci, en échange d'un nom de domaine, fournit les
informations qu'il a trouvées, typiquement dans le
DNS : HIT ou HI, adresses IP et peut-être des
serveurs de rendez-vous (RFC 8004). L'application a donc uniquement à appeler
getaddrinfo()
et elle récupère des
HIT, qu'elle utilise pour remplir les informations transmises à la
prise. Le résolveur a fourni à HIP les informations auxiliaires comme
la correspondance entre un HI et des adresses IP.
Et si on n'a pas de résolveur HIP (section 3.2) ? Cette API permet à une application, de fournir quand même tous les détails nécessaires pour réussir une connexion (notamment les adresses IP associées à un HI).
La section 4 définit formellement la nouvelle API. D'abord, les
structures de données. Le
nouveau type sockaddr
est défini ainsi :
typedef struct in6_addr hip_hit_t; struct sockaddr_hip { uint8_t ship_len; sa_family_t ship_family; in_port_t ship_port; uint32_t ship_flags; hip_hit_t ship_hit; };
Le résolveur prend des nouvelles options (section 4.2). La nouvelle famille
AF_HIP
, passée à
getaddrinfo()
, indique que l'application veut
uniquement parler HIP et que toutes les sockaddr
doivent donc être de ce type, quant à l'option
AI_NO_HIT
, elle indique au contraire que
l'application ne veut pas entendre parler de HIP.
Une fois la connexion HIP établie, l'application peut se servir de
getsockname()
et
getpeername()
pour trouver des
informations sur la machine paire (section 4.3). Elles permettent par
exemple d'accéder au HIT de celle-ci (ce qui est utile si
l'application acceptait n'importe quel HIT).
Si la machine dispose de plusieurs identités, le choix du HIT
utilisé comme source est laissé à l'initiative du système. Si
l'application veut l'influencer, elle peut se servir de mécanismes
analogues à ceux du RFC 5014 : une option de
setsockopt()
,
HIT_PREFERENCES
(section 4.4), et deux valeurs possibles :
HIT_PREFER_SRC_HIT_TMP
: donner la
préférence aux HIT temporaires (dits aussi « anonymes », cf. sections
5.1.2 et 7 du RFC 5201),HIT_PREFER_SRC_HIT_PUBLIC
: donner la
préférence aux HIT publics.Si HIP_HIT_ANY
signifiait qu'on exigeait une
connexion HIP mais avec n'importe qui,
HIP_ENDPOINT_ANY
indiquait qu'on n'avait même pas
cette préférence et que des connexions non-HIP étaient
possibles. Mais, après coup, on veut parfois savoir ce qu'on a obtenu
et la nouvelle fonction sockaddr_is_srcaddr()
(section 4.5) permet de savoir si le pair avec lequel on s'était
connecté utilisait HIP ou pas. (Il y a aussi une fonction
hip_is_hit()
qui teste simplement si une valeur
de 128 bits est bien un HIT.)
On l'a vu, cette API permet, dans une large mesure, à une
application de se connecter en HIP en ignorant presque tout de ce
protocole : il suffit d'indiquer AF_HIP
au lieu
de AF_INET6
et ça roule. La traduction des HIT en
localisateurs est notamment effectuée automatiquement, l'application
ne se souciant pas de ces derniers. Toutefois, certaines
applications peuvent vouloir davantage de contrôle, notamment sur le
choix des localisateurs (les adresses IP). La section 4.6 est faite
pour elles. Elle s'appuie sur les options SHIM6
du RFC 6316. Par exemple, l'option
SHIM_LOC_PEER_PREF
permet, avec
setsockopt()
, de définir le localisateur préféré
et, avec getsockopt()
, de découvrir le
localisateur utilisé.
Quelques points sur la sécurité viennent compléter ce RFC, en
section 6. Ainsi,
l'option HIP_ENDPOINT_ANY
dit explicitement qu'on
accepte des pairs non-HIP, pour les connexions entrantes ou
sortantes. On peut donc se retrouver sans la sécurité associée à HIP
(notamment l'authentification du pair). Les applications soucieuses de
sécurité devraient donc utiliser HIP_HIT_ANY
et
pas HIP_ENDPOINT_ANY
.
Aujourd'hui, cette extension de l'API traditionnelle ne se retrouve pas encore dans Linux, ni dans un des BSD. Pour cela, un programme comme echoping n'a donc pas encore de possibilité d'utiliser HIP (cf. bogue #3030400.)
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : C. Boulton (NS-Technologies), J. Rosenberg (Skype), G. Camarillo (Ericsson), F. Audet (Skype)
Pour information
Première rédaction de cet article le 23 juillet 2011
Aujourd'hui, il est rare pour une machine individuelle (ordinateur de bureau, ordinateur portable, smartphone, tablette, etc) d'avoir un vrai accès Internet. Presque toujours, la malheureuse machine est limitée à une adresse IP privée et coincée derrière un NAT qui traduira cette adresse à la volée. Cela ne gêne pas trop certains protocoles (SSH sortant, par exemple) mais est beaucoup plus gênant pour d'autres, notamment le protocole de téléphonie sur IP SIP. Ce RFC décrit l'ensemble des techniques que doivent mettre en œuvre les clients SIP pour arriver à passer quand même. C'est la meilleure lecture pour commencer à se pencher sur le problème « pourquoi a-t-on si souvent des problèmes avec SIP ? ».
Pour comprendre pourquoi SIP (RFC 3261) est particulièrement affecté, il faut se rappeler qu'il utilise des références : le client SIP indique au serveur à quelle adresse répondre, par exemple à quelle adresse envoyer les paquets audio du protocole compagnon RTP (RFC 3550). En présence d'un NAT, la machine ne connait pas son adresse IP telle que vue de l'extérieur et, de toute façon, le NAT traditionnel (qui agit sur le port, pas seulement sur l'adresse en dépit de son nom) bloque les paquets entrants, ne sachant pas que le flux RTP est lié à la connexion SIP. Pire, les différents routeurs NAT ont des comportements différents et il est donc difficile de trouver une solution qui marche partout (RFC 4787).
Ces problèmes du NAT sont bien connus et documentés. L'essentiel du code réseau d'un client SIP est consacré à contourner le NAT. Des solutions partielles ont été développées comme STUN (RFC 5389), TURN (RFC 5766), ICE (RFC 8445) ou bien des solutions spécifiques à SIP comme le RTP symétrique (RFC 4961), ou le SIP sortant (RFC 5626). Toutes ces solutions sont partielles et il manquait un document de haut niveau, décrivant le mécanisme général. Ce RFC 6314 ne propose donc pas « encore un nouveau protocole » mais explique la marche à suivre et les bonnes pratiques pour passer outre les routeurs NAT.
SIP peut être utilisé dans des contextes très différents : ce RFC se focalise sur l'utilisation en « client-serveur » où un client SIP (par exemple un softphone) appelle un fournisseur SIP qui routera l'appel vers le destinataire. Le SIP pair-à-pair (actuellement expérimental) n'utilisera pas forcément les mêmes techniques.
La section 3 détaille le problème que rencontrent les clients SIP en présence du NAT. Si le routeur NAT contient un ALG, celui-ci peut interférer avec SIP, par exemple en interdisant les communications chiffrées, ou bien en imposant que le même chemin soit emprunté à l'aller et au retour. Comme documenté dans les RFC 4787, RFC 3424 et RFC 8445, les ALG sont donc une solution limitée.
Et s'il n'y a pas d'ALG ? Dans ce cas, voyons comment SIP établit
une connexion avec son fournisseur, par défaut. Le client envoie une
requête sur UDP et le serveur est censé
répondre au couple {adresse, port} de l'en-tête
Via:
de cet en-tête. Mais, après le passage
du routeur NAT, cette adresse et son port, mis là par le client
original, ne correspondent plus à rien d'utile. Même si le paquet de
réponse atteint le NAT, il sera typiquement jeté par lui. Même si le
client SIP s'était connecté en utilisant TCP,
les appels qu'il recevra (INVITE
) ne seront pas routés sur cette connexion TCP
mais envoyés à l'adresse indiqué ce qui, là encore, ne marchera pas
(sans compter d'autres problèmes comme la fermeture automatique de la
session par le NAT après un délai de garde).
Cela, c'était pour la signalisation, pour le protocole SIP lui-même. Mais un coup de téléphone complet nécessite aussi de faire passer les données, les paquets audio. Ceux-ci voyagent en général via la protocole RTP (RFC 3550, le protocole à utiliser, les ports où envoyer les données, etc, étant indiqués via SDP (RFC 4566) ou bien via une requête SIP spécifique (RFC 3264). Même si la session SIP a été bien établie, ces paquets RTP risquent fort de ne pas arriver, les adresses et les numéros de port qu'indiquent SDP ou SIP n'ayant pas de signification en dehors du réseau local.
Donc, pour résumer cette section 3, SIP a deux problèmes avec le NAT :
Soyons maintenant positifs et voyons les solutions (section 4). Pour la signalisation, la section 4.1 expose les méthodes possibles :
Pour le transport des données, la section 4.2 cite :
La section 5 illustre ensuite ces méthodes par divers exemples. En
voici un très simple, pour la signalisation, où le client, 192.168.1.2
est derrière un NAT (qui réécrit son adresse en
172.16.3.4
) et s'enregistre auprès d'un
fournisseur SIP, Example.com. La requête est :
REGISTER sip:example.com SIP/2.0 Via: SIP/2.0/UDP 192.168.1.2;rport;branch=z9hG4bKnashds7 Max-Forwards: 70 From: Bob <sip:bob@example.com>;tag=7F94778B653B To: Bob <sip:bob@example.com> Call-ID: 16CB75F21C70 CSeq: 1 REGISTER Supported: path, outbound Contact: <sip:bob@192.168.1.2 >;reg-id=1 ;+sip.instance="<urn:uuid:00000000-0000-1000-8000-AABBCCDDEEFF>" Content-Length: 0
Le client SIP a utilisé le paramètre rport
(RFC 3581) dans l'en-tête Via:
pour indiquer que le serveur doit répondre au port d'où
vient la requête (et que le routeur NAT a ouvert). La réponse est :
SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.1.2;rport=8050;branch=z9hG4bKnashds7; received=172.16.3.4 From: Bob <sip:bob@example.com>;tag=7F94778B653B To: Bob <sip:bob@example.com>;tag=6AF99445E44A Call-ID: 16CB75F21C70 CSeq: 1 REGISTER Supported: path, outbound Require: outbound Contact: <sip:bob@192.168.1.2 >;reg-id=1;expires=3600 ;+sip.instance="<urn:uuid:00000000-0000-1000-8000-AABBCCDDEEFF>" Content-Length: 0
et le paramètre received
du champ
Via:
indique l'adresse IP source qu'avait vue le
serveur. (Une autre solution aurait été d'utiliser TCP.) Les amateurs
de scénarios plus complexes seront comblés, avec le reste de la
longue section 5.
À noter qu'un argument souvent présenté en faveur de Skype, par rapport à SIP, est son meilleur comportement en présence de NAT hostiles (parfois très hostiles, par exemple ne laissant passer que HTTP). Il est amusant de noter que deux des auteurs du RFC travaillent chez Skype. Mais, surtout, si les clients SIP ont souvent moins de succès que Skype lors de la traversée de routeurs très fermés, c'est pour trois raisons :
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : J. Abley (ICANN), W. Maton (NRC-CNRC)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 14 juillet 2011
Un RFC très inhabituel, non seulement par
son titre amusant mais aussi parce que le public visé n'est pas le
programmeur qui va mettre en œuvre des normes, ni même
l'administrateur réseaux qui s'occupe de grands réseaux complexes,
mais un public bien plus large, celui des gens qui gèrent un petit
réseau, ont installé comme pare-feu ou
IDS une boîte noire à laquelle ils ne
comprennent rien, et qui voient arriver des messages d'alerte comme
quoi leur petit réseau serait attaqué par un mystérieux
prisoner.iana.org
. Ce RFC a été écrit pour
fournir à l'IANA et aux opérateurs de serveurs
de l'AS112 (décrit dans le RFC 7534) une réponse toute faite à envoyer à ces angoissés.
En effet, l'« attaque » en question n'est pas une attaque et ne
vient pas de l'IANA ou de
l'AS112. Elle est entièrement de la faute des
administrateurs de ces réseaux soi-disant attaqués. Un certain nombre
de petits réseaux utilisent, soit parce qu'il n'y a plus d'adresses IPv4 disponibles, soit parce qu'ils
croient à tort que cela leur apporte une certaine sécurité, des
adresses IP privées, tirées
du RFC 1918. Ces adresses étant spécifiques à un
certain réseau, n'ayant pas de signification globale, les requêtes
DNS demandant les noms associés à ces adresses
ne devraient jamais sortir du réseau local (section 2 du RFC) et être toujours traitées
par un serveur DNS interne. Mais, en pratique, c'est loin d'être le
cas, et les serveurs de in-addr.arpa
, le domaine
utilisé pour la résolution d'adresses IP en noms (section 3), reçoivent un trafic
important et inutile. Pour le traiter sans charger ces serveurs, les
domaines servant aux plages d'adresses du RFC 1918 sont déléguées à l'AS112 (RFC 7534) qui est chargé de répondre « ce domaine
n'existe pas » à toutes ces requêtes.
Mais, comme les requêtes de ce type sont des erreurs (rappelez-vous qu'elles n'auraient normalement jamais dû sortir), les réponses qu'envoie l'AS112 sont souvent inattendues pour le réseau local. Et, si le pare-feu ou l'IDS sont bizarrement configurés (ce qui est fréquent sur ces réseaux mal gérés), la réponse DNS à leur question leur apparait comme une tentative d'attaque ! S'ils se plaignent, l'idée est de simplement leur renvoyer ce RFC 6305 à lire.
Ce RFC explique donc en termes simples ce que sont les adresses
privées, ce qu'est la résolution d'adresses en noms, les raisons
pour lesquelles est déployé l'AS112 (section 4 du RFC), et les noms et
adresses des serveurs de l'AS112 (section 5) notamment le
prisoner.iana.org
qui donne son titre au
RFC. Pour augmenter les chances que Google
trouve cet article, je cite ici ces informations :
PRISONER.IANA.ORG
(192.175.48.1
),BLACKHOLE-1.IANA.ORG
(192.175.48.6
),BLACKHOLE-2.IANA.ORG
(192.175.48.42
).La section 6 explique ensuite le mécanisme par lequel la fausse
alerte est déclenchée : un résolveur DNS du réseau local envoie la
requête, par exemple PTR 1.2.20.172.in-addr.arpa
,
elle arrive aux serveurs de l'AS112, qui répondent, mais leurs
réponses sont, pour des raisons diverses, bloquées. Normalement, le
pare-feu ne couine pas pour chaque paquet bloqué mais, ici, les
requêtes étant souvent déclenchées automatiquement par un logiciel,
elles peuvent être nombreuses, provoquant de fréquentes réponses, qui
peuvent ressembler à une attaque. Deux autres phénomènes expliquent
cette perception : si la réponse est bloquée, la machine à l'origine
de la requête va réessayer, souvent très vite. Et si le résolveur DNS
refait ces essais avec
des numéros de port croissant régulièrement,
les réponses ressembleront à un balayage de
ports.
Que devrait donc faire l'administrateur du site au lieu de harceler l'IANA ou les opérateurs de l'AS112 ? La section 7 lui donne quelques pistes, pour résoudre le problème qu'il a causé :
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : J. Abley (ICANN), W. Maton (NRC-CNRC)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 14 juillet 2011
Le système AS112, autrefois décrit dans ce RFC, est à la fois un utile composant du DNS, améliorant les performances et reduisant la charge du réseau, un banc d'essai pour des nouvelles techniques comme l'anycast, et une expérimentation sociale, celle d'un service 100 % acentré. Il est désormais documenté dans le RFC 7534.
Comme beaucoup de bonnes choses sur l'Internet, la documentation arrive comme les carabiniers, longtemps après. Car l'AS112 tourne depuis des années. Pour comprendre son rôle, il faut d'abord se pencher sur le problème à résoudre.
Un certain nombre de sites connectés à
l'Internet utilisent des adresses IP privées, tirées du RFC 1918. Bien des logiciels, lorsqu'ils voient
passer un nouveau client, font une résolution
DNS pour obtenir le nom du client en fonction
de son adresse IP (résolution dite PTR). C'est
par exemple le cas du serveur de courrier
Postfix, chez qui ce comportement n'est pas
débrayable. Lorsque l'adresse IP est privée, il ne sert à rien de
poser la question au DNS public. Par définition, celui-ci ne peut pas
savoir que MaPetiteEntreprise utilise
192.168.1.0/24
et a attribué
192.168.1.33
à
posteclientX.mapetiteentreprise.com
. La bonne
pratique est donc que l'administrateur réseaux
d'un site qui utilise ces adresses privées doit configurer des
serveurs DNS pour répondre aux requêtes PTR (cf. RFC 6303). Pour voir cela, on peut utiliser l'option -x
de dig, qui permet de faire
automatiquement une résolution d'adresse en nom. Le domaine
in-addr.arpa
(RFC 5855) accueille la forme inversée des
adresses (192.168.1.33
devient
33.1.168.192.in-addr.arpa
). Testons ici une adresse publique :
% dig -x 192.134.4.20 ... ;; ANSWER SECTION: 20.4.134.192.in-addr.arpa. 172800 IN PTR rigolo.nic.fr.
Mais beaucoup d'administrateurs réseaux sont négligents, surchargés
de travail, incompétents ou les trois à la fois. Ils ne configurent
pas ces serveurs DNS et, résultat, la requête PTR sort de leur réseau
et va taper sur les serveurs DNS de la racine puis à ceux de in-addr.arpa
. (Une bonne partie du trafic semble ainsi venir des réseaux 3G, où le smartphone ne reçoit qu'une adresse privée et où le résolveur DNS qui lui est indiqué ne connait pas les zones correspondantes.) Ceux-ci ont normalement
autre chose à faire que de répondre à des requêtes qui sont, dès le
départ, des erreurs. Ils délèguent donc à l'AS112, un ensemble de
serveurs de noms qui est chargé de répondre « ce nom n'existe pas » à
toutes ces requêtes parasites. L'AS112 est donc un puits où finissent
les erreurs.
On peut voir la délégation de l'AS112 avec dig :
% dig NS 168.192.in-addr.arpa ; <<>> DiG 9.7.1 <<>> NS 168.192.in-addr.arpa ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56273 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 3 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;168.192.in-addr.arpa. IN NS ;; ANSWER SECTION: 168.192.in-addr.arpa. 300 IN NS blackhole-2.iana.org. 168.192.in-addr.arpa. 300 IN NS blackhole-1.iana.org. ;; ADDITIONAL SECTION: blackhole-1.iana.org. 3500 IN A 192.175.48.6 blackhole-2.iana.org. 3500 IN A 192.175.48.42 ;; Query time: 29 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Wed Jul 6 12:34:19 2011 ;; MSG SIZE rcvd: 141
La délégation va être conservée dans les mémoires caches des
résolveurs DNS et la racine ou in-addr.arpa
ne seront donc plus embêtés, après la
première requête.
Mais qui sont ces machines 192.175.48.6
et
192.175.48.42
? Des très gros serveurs payés par un mécène
et installées à un endroit bien connecté ? Pas du tout. C'est ici que
rentre en jeu l'AS112. Ce dernier est composé d'un réseau informel de
dizaines de machines un peu partout dans le monde et qui annoncent
toutes être 192.175.48.6
et
192.175.48.42
. Chacune de ces machines encaisse une partie
de la charge. L'AS112 n'a pas de chef, juste un site Web et, depuis aujourd'hui, un
RFC, ce RFC 6304.
L'AS112 doit son nom au numéro de système autonome qui lui a été attribué. Ses serveurs utilisent l'anycast (RFC 4786) pour distribuer la charge entre eux. Avant Global Anycast, c'était donc le premier projet d'anycast entre serveurs faiblement coordonnés.
Les détails pratiques, maintenant. La liste des zones servies
figure en section 2.1. Elle comprend
10.in-addr.arpa
pour le réseau
10.0.0.0/8
,
de 16.172.in-addr.arpa
à
31.172.in-addr.arpa
pour le
172.16.0.0/12
, et
168.192.in-addr.arpa
pour le
192.168.0.0/16
, les préfixes du RFC 1918. Elle inclus aussi
254.169.in-addr.arpa
pour le préfixe « local au
lien » du RFC 5735. Pour aider à l'identification du
nœud qui répond, les serveurs de l'AS112 servent également la
zone hostname.as112.net
, ici à Paris :
% dig +nsid TXT hostname.as112.net ; <<>> DiG 9.7.3 <<>> +nsid TXT hostname.as112.net ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1078 ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 2, ADDITIONAL: 3 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;hostname.as112.net. IN TXT ;; ANSWER SECTION: hostname.as112.net. 267 IN TXT "Unicast IP: 193.17.192.194" hostname.as112.net. 267 IN TXT "See http://as112.net/ for more information." hostname.as112.net. 267 IN TXT "See http://noc.hivane.net/cgi-bin/dsc-grapher.pl for local information." hostname.as112.net. 267 IN TXT "Paris, FR" hostname.as112.net. 267 IN TXT "Hivane Networks" ;; AUTHORITY SECTION: hostname.as112.net. 267 IN NS blackhole-2.iana.org. hostname.as112.net. 267 IN NS blackhole-1.iana.org. ;; ADDITIONAL SECTION: blackhole-1.iana.org. 241 IN A 192.175.48.6 blackhole-2.iana.org. 241 IN A 192.175.48.42 ;; Query time: 1 msec ;; SERVER: 217.70.184.225#53(217.70.184.225) ;; WHEN: Wed Jul 6 12:36:14 2011 ;; MSG SIZE rcvd: 348
On note que les préfixes IPv6 n'y figurent
pas. Une des discussions les plus vives sur ce RFC, et qui explique le
temps très long qu'il a mis à sortir, portait sur la délégation de
préfixes d'ip6.arpa
à l'AS112. Aucune décision
n'a encore été prise et, pour l'instant, notre RFC 6304
décrit l'état actuel de l'AS112 (on peut avoir une liste à jour sur
le site officiel).
La section 2.2 décrit les serveurs de noms qui reçoivent la
délégation, joliment (mais incorrectement, puisqu'ils répondent)
nommés blackhole-1.iana.org
et
blackhole-2.iana.org
(en dépit de leurs noms, les
serveurs de l'AS112 ne sont pas gérés par
l'IANA, cf. section 7). Dans le champ
MNAME
du SOA de la zone
déléguée, on trouve également prisoner.iana.org
dont la tâche principale est de répondre aux mises à jour dynamiques
(RFC 2136) que certaines machines envoient audit MNAME
.
Ce RFC 6304 n'est pas seulement la description d'une
technique mais également un HOWTO sur la
configuration d'un serveur de l'AS112. De tels textes, prévus pour les
administrateurs système, sont rares dans les
RFC. La section 3 décrit ainsi tout
ce que doit savoir le volontaire qui va créer un nouveau
nœud. Il doit connaître BGP (RFC 4271), nécessaire pour
l'anycast (RFC 4786) et la gestion d'un serveur DNS faisant
autorité. Les serveurs de l'AS112 peuvent être situés n'importe où
mais ils sont surtout utiles dans les endroits bien connectés,
notamment les points d'échange. Ils peuvent
être locaux (annonçant les routes avec la communauté
BGP no-export
, 0xFFFFFF01,
cf. RFC 1997), ou
globaux (servant le monde entier). Et naturellement, ils doivent se
coordonner (via une liste de diffusion) avec les
autres serveurs de l'AS112.
L'AS112 n'impose pas de système d'exploitation particulier (section 3.3) mais tous les serveurs existants semblent utiliser Unix et tous (c'est difficile à dire, puisque l'AS112 ne contrôle pas tout ce qui se passe sur les serveurs) se servent de BIND. Il est recommandé que la machine AS112 soit dédiée à cette tâche : ces serveurs reçoivent parfois un trafic intense qui pourrait perturber leurs autres activités.
Le serveur signale son existence et sa disponibilité en
BGP. Il faut donc coupler le serveur de noms au
serveur BGP, pour que l'arrêt du serveur DNS entraîne l'arrêt de
l'annonce (le RFC ne fournit pas de script pour cela). Un exemple de
comment cela peut se réaliser sur Linux, avec
les adresses de l'AS112 attachées à une interface dummy
, est
(code utilisé sur un serveur anycast réel, quoique
pas de l'AS112) :
# Load the variables (the machine is a RedHat) . /etc/sysconfig/network-scripts/ifcfg-eth0 # Test if the name server actually works. Do not use ps: the server may be there but unresponsive TMP=(`dig +short +time=1 +tries=1 @${IPADDR} SOA example.`) MASTER=${TMP[0]:=somethingwaswrong} # Normal reply or not? if test ${MASTER} != "nsmaster.nic.example." then # Disable the interface: Quagga will stop announcing the route ifdown dummy0 # Raise an alarm, send SMS, etc fi
Le serveur BGP annonce le préfixe
192.175.48.0/24
qui couvre les adresses de tous
les serveurs et l'origine est évidemment 112.
Les exemples du RFC supposent que le serveur BGP est
Quagga mais cela peut évidemment marcher avec
d'autres. Dans l'exemple ci-dessous, tiré du RFC (section 3.4), le router
ID est 203.0.113.1
et le serveur BGP a
deux pairs, 192.0.2.1
et
192.0.2.2
. Voici un extrait du
bgpd.conf
(la version intégrale est dans le
RFC) :
hostname my-router ... router bgp 112 bgp router-id 203.0.113.1 network 192.175.48.0/24 neighbor 192.0.2.1 remote-as 64496 neighbor 192.0.2.1 next-hop-self neighbor 192.0.2.2 remote-as 64497 neighbor 192.0.2.2 next-hop-self
En farfouillant sur le site officiel (pas très bien organisé, je trouve), on peut trouver d'autres exemples.
Le serveur AS112 a ensuite besoin d'un serveur DNS faisant autorité
(section 3.5), évidemment compatible avec toutes les règles du DNS
(RFC 1034). Les exemples de configuration du RFC
sont fondés sur BIND. Voici un extrait du
named.conf
(la version intégrale est dans le
RFC) :
options { listen-on { ... // the following addresses correspond to AS112 addresses, and // are the same for all AS112 nodes 192.175.48.1; // prisoner.iana.org (anycast) 192.175.48.6; // blackhole-1.iana.org (anycast) 192.175.48.42; // blackhole-2.iana.org (anycast) }; recursion no; // authoritative-only server }; // RFC 1918 zone "10.in-addr.arpa" { type master; file "db.empty"; }; ... // RFC 5735 zone "254.169.in-addr.arpa" { type master; file "db.empty"; }; // also answer authoritatively for the HOSTNAME.AS112.NET zone, // which contains data of operational relevance zone "hostname.as112.net" { type master; file "db.hostname.as112.net"; };
Un exemple équivalent pour NSD (utilisé sur le nœud AS112 de Paris) est disponible en as112-nsd.conf
. Pour simplifier son écriture, il a été
produit à partir d'un source en M4, as112-nsd.conf.m4
.
Que contiennent les fichiers de zone db.empty
et db.hostname.as112.net
? Conformes à la syntaxe
de la section 5 du RFC 1035, ils sont communs à
BIND et NSD. Le premier, comme son nom l'indique, est un fichier de
zone vide, puisque le serveur AS112 ne connait évidemment rien : il ne
peut que répondre NXDOMAIN
(ce nom n'existe pas)
à toutes les requêtes. Il ne contient donc que les informations
obligatoires à toute zone (SOA, avec une adresse
de contact appropriée) et NS. L'autre zone sert au débogage de l'AS112,
lorsqu'on veut obtenir des informations sur le serveur AS112
courant. Un contenu typique est juste composé d'enregistrements TXT :
TXT "Human AS112 server" "Minas Tirith, Gondor" TXT "Forbidden to orcs and nazguls." TXT "See http://www.as112.net/ for more information."
et parfois d'une localisation (cf. RFC 1876). Le résultat sur un site réel étant :
% dig ANY hostname.as112.net. ; <<>> DiG 9.7.3 <<>> ANY hostname.as112.net. ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41528 ;; flags: qr rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 2, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;hostname.as112.net. IN ANY ;; ANSWER SECTION: hostname.as112.net. 604796 IN LOC 37 58 22.590 N 23 44 43.890 E 100.00m 100m 10m 10m hostname.as112.net. 604796 IN TXT "See http://as112.net/ for more information." hostname.as112.net. 604796 IN TXT "Unicast IP: as112.grnet.gr" hostname.as112.net. 604796 IN TXT "Greek Research & Technology Network" "Athens, Greece" hostname.as112.net. 604796 IN SOA flo.gigafed.net. dns.ryouko.imsb.nrc.ca. 1 604800 60 604800 604800 hostname.as112.net. 604796 IN NS blackhole-2.iana.org. hostname.as112.net. 604796 IN NS blackhole-1.iana.org. ;; AUTHORITY SECTION: hostname.as112.net. 604796 IN NS blackhole-1.iana.org. hostname.as112.net. 604796 IN NS blackhole-2.iana.org. ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Wed Jul 6 12:51:53 2011 ;; MSG SIZE rcvd: 391
(La version intégrale des deux fichiers de zone figure dans le RFC.)
Une fois le nœud installé, il faut évidemment le tester (avec
dig, par exemple). Si les réponses aux requêtes
PTR sont correctes, mais pas celles aux requêtes pour le nom
hostname.as112.net
, c'est sans doute un problème
de routage (on est envoyés sur un autre nœud de l'AS112) et il
faut alors sortir traceroute et les
looking glasses (section 3.6). Des
tests dignes de ce nom doivent être faits depuis plusieurs
FAI, et doivent tester les trois adresses IP de
l'AS112.
Le bon fonctionnement de l'AS112 ne dépend pas uniquement de sa configuration initiale mais aussi de sa gestion et surveillance quotidiennes. La section 4 est consacrée aux questions opérationnelles. Le nœud doit être surveillé automatiquement, pour s'assurer qu'il répond toujours. S'il doit être arrêté (par exemple pour une maintenance prévue), il faut s'assurer que l'annonce BGP stoppe (autrement, BGP annonce un trou noir, d'où aucune réponse ne reviendra). Autre point important de la gestion opérationnelle d'un serveur de l'AS112, des statistiques, obtenues à partir d'outils comme DSC ou dnstop. Quelle est l'utilisation réelle de l'AS112 ? Ces statistiques n'étant pas consolidées globalement, c'est difficile à dire. Certains opérateurs publient leurs chiffres mais pas tous. Par exemple, le serveur d'Ottawa voit mille requêtes par seconde (cf. « AS112 Intro » par l'un des auteurs du RFC), celui géré par le RIPE-NCC dans les mille cinq cents, et celui à Paris deux fois plus (voir les graphiques), ce qui fait quand même quelques mégabits par seconde. La majorité des types demandés est évidemment du PTR mais il y a aussi un flux important de TXT, apparemment dus à la technologie SD (Service Discovery) d'Apple (voir des statistiques plus détaillées à la fin).
Le nouveau serveur peut alors être annoncé sur les listes appropriées (par exemple, chaque point d'échange a en général la sienne). Enfin, bien que chaque serveur de l'AS112 puisse fonctionner indépendemment des autres, il est évidemment préférable de se coordonner avec les petits camarades (section 5) en écrivant à la liste officielle.
Et dans le futur ? La section 6 explore l'avenir possible de l'AS112. Idéalement, il devrait disparaître petit à petit au fur et à mesure que les administrateurs réseaux prennent soin de ne pas laisser fuir les requêtes PTR pour les réseaux privés, comme recommandé dans le RFC 6303. Le déploiement de logiciels respectant ce principe dès le début pourrait aider. Toutefois, aujourd'hui, les opérateurs de l'AS112 n'observent pas de tendance à la baisse du trafic. Même des années après le déploiement de serveurs mettant en œuvre le RFC 6303, il est probable que le trafic de l'AS112 ne tombera pas à zéro et que ce service restera donc nécessaire.
Il pourrait même s'étendre à IPv6 (cela a
été fait début 2015) : les
serveurs pourraient répondre en IPv6 (et pas seulement en IPv4 comme
aujourd'hui). Un préfixe a déjà été alloué pour cela, 2620:4f:8000::0/48
mais il n'est pas encore publié. Et les serveurs pourraient servir des données de
ip6.arpa
. Rien n'est encore décidé, gardez un
œil sur http://www.as112.net/
si vous voulez être
au courant. Un bon exposé du problème est « AS112-bis. » et un plan
de déploiement IPv6 est en http://public.as112.net/node/26
. Quant aux nouveaux domaines
délégués, la solution finalement adoptée a été décrite dans le RFC 7535.
Enfin, qu'en est-il de la sécurité ? Comme le rappelle la section 8, les requêtes DNS auxquelles répond l'AS112 ne devraient jamais y arriver, normalement. Elles auraient dû rester sur le réseau local. En sortant, elles exposent de l'information interne, qui était peut-être privée (qu'il y ait un serveur qui y réponde ou pas ne change guère ce risque).
Plus rigolo, comme ces requêtes sont en général involontaires (comme indiqué, elles auraient dû rester privées), les réponses sont inattendues. Plus d'un IDS a donc crié que l'AS112 essayait d'attaquer le réseau. Le RFC 6305 a été écrit pour fournir une réponse toute faite aux administrateurs incompétents qui accusaient l'IANA ou l'AS112.
Comme l'AS112 n'a pas de chef et que l'anycast ne permet pas de limiter le nombre de participants, il est tout à fait possible de fantasmer sur l'hypothèse d'un nœud AS112 voyou, qui donnerait exprès de mauvaise réponses. Ce problème (purement théorique) n'a pas vraiment de solution. Signer les zones avec DNSSEC semble franchement excessif.
L'annexe A du RFC expose la longue histoire de l'AS112, de ses
débuts en 2002 (les adresses IP
privées datent de 1996) à son état actuel,
après la redélégation en 2011 de
in-addr.arpa
, autrefois sur les serveurs de la
racine (RFC 5855). L'AS112 a été le premier
déploiement massif de l'anycast et a donc joué un
rôle primordial dans l'évaluation de cette technologie.
On voit que neuf ans ont donc été nécessaires pour documenter ce projet. Une des raisons du retard était la longue discussion pour savoir si le RFC devait documenter l'état actuel de l'AS112 (ce qui a finalement été fait) ou son état souhaité (avec, par exemple, les nouvelles zones IPv6).
À noter que, d'après la liste officielle des sites, il existe au moins un serveur AS112 en France, chez Hivane, désormais (novembre 2011) connecté au France-IX. Malgré cela, les requêtes françaises pour les serveurs de l'AS112 voyagent souvent loin. C'est un problème banal comme le montrait l'excellente présentation « Investigating AS112 Routing and New Server Discovery ».
Voici quelques analyses sur le trafic de ce serveur français, faites avec DNSmezzo. Le fichier pcap fait 6,8 Go. Il y a 43 701 087 paquets DNS dont 21 858 845 sont des requêtes. Les données ont été prises un vendredi, de 13h40 à 15h30 (heure locale). Regardons d'abord les types de données demandés :
dnsmezzo=> SELECT (CASE WHEN type IS NULL THEN qtype::TEXT ELSE type END), meaning, count(results.id)*100/(SELECT count(id) FROM DNS_packets WHERE query) AS requests_percent FROM (SELECT id, qtype FROM dns_packets WHERE query) AS Results LEFT OUTER JOIN DNS_types ON qtype = value GROUP BY qtype, type, meaning ORDER BY requests_percent desc; type | meaning | requests_percent -------+----------------------------------------+------------------ PTR | a domain name pointer | 57 TXT | text strings | 35 SOA | marks the start of a zone of authority | 6 CNAME | the canonical name for an alias | 0 MX | mail exchange | 0 AAAA | IP6 Address | 0 40 | | 0 DS | Delegation Signer | 0 ...
La première place des PTR
est normale. Celle des
TXT
est plus surprenante. En regardant les noms
utilisés
(cf._dns-sd._udp.Y.X.243.10.in-addr.arpa
...), on
voit qu'ils sont dus à la technique Service
Discovery d'Apple, un système normalement confiné au réseau
local mais qui bave beaucoup à l'extérieur.
Et quels sont les domaines les plus populaires ?
dnsmezzo=> SELECT substr(registered_domain,1,46) AS domain, count(id)*100/(SELECT count(id) FROM DNS_packets WHERE query) AS requests_percent FROM dns_packets WHERE query GROUP BY registered_domain ORDER BY requests_percent DESC LIMIT 30; domain | requests_percent ------------------+------------------ 10.in-addr.arpa | 78 192.in-addr.arpa | 12 172.in-addr.arpa | 7 169.in-addr.arpa | 1 151.in-addr.arpa | 0 i~-addr.arpa | 0 83.in-addr.arpa | 0 | 0 gfi.private | 0 local.de | 0 grupofdez.com | 0 ....
On voit que le réseau 10.0.0.0/8
est nettement le
plus populaire. On notera les trois derniers, sans doute des erreurs
de configuration.
Et quels sont les résolveurs les plus actifs ? En agrégeant les préfixes IPv4 en /28 :
dnsmezzo=> SELECT set_masklen(src_address::cidr, 28) AS client, count(id)*100/(SELECT count(id) FROM DNS_packets WHERE query) AS requests_percent FROM dns_packets WHERE query GROUP BY set_masklen(src_address::cidr, 28) ORDER by requests_percent DESC LIMIT 30; client | requests_percent --------------------+------------------ CENSURE.160/28 | 29 CENSURE.0/28 | 10 CENSURE.16/28 | 8 CENSURE.96/28 | 6 ...
Oui, j'ai préféré ne pas donner les adresses. Je dirai simplement que ces quatre plus gros sont des opérateurs de téléphonie mobile, deux français et deux extrême-orientaux (les mystères du routage...).
Merci à Clément Cavadore pour les données et pour sa relecture.
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : M. Andrews (ISC)
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 14 juillet 2011
Autrefois, les serveurs DNS récursifs, ceux qui, installés sur un réseau local ou chez un FAI pour ses abonnés, répondent aux requêtes DNS des clients finaux, ne servaient par défaut aucune zone. Tout était demandé aux serveurs DNS faisant autorité, sauf des zones locales configurées à la main. Le problème est que certaines zones privées très répandues étaient oubliées, et que le récurseur allait alors embêter les serveurs faisant autorité avec ces requêtes qui auraient dû rester locales. Ce nouveau RFC demande donc que, par défaut, sans aucune configuration explicite, les récurseurs fassent autorité pour certaines zones locales.
Un exemple typique est celui d'un réseau local numéroté avec les
adresses IP privées du RFC 1918, mettons 172.27.0.0/16
. Les machines
dudit réseau reçoivent en DHCP l'adresse d'un
serveur DNS récursif local. Celui-ci, avant la sortie de notre RFC 6303, ne connaissait pas
27.172.in-adr.arpa
, le domaine utilisé pour les
résolutions d'adresses IP en noms. Il va donc transmettre ces requêtes
aux serveurs publics, en l'occurrence ceux de l'AS112 (RFC 7534), les
faisant travailler pour rien. La bonne pratique, depuis toujours, est
que l'administrateur système local ajoute la zone
27.172.in-adr.arpa
à son récurseur. Mais
incompétence, manque de temps et négligence (quelqu'un d'autre
paie...) se conjuguent pour faire que c'est rarement déployé. L'idée
de notre RFC 6303 est donc de déplacer le travail depuis les
nombreux administrateurs réseaux vers les nettement moins nombreux
auteurs de logiciels serveurs.
La section 3 du RFC décrit le changement chez les
résolveurs. Ceux-ci devront répondre avec autorité
NXDOMAIN
(code de réponse 3), indiquant que le
nom demandé n'existe pas. Une façon triviale d'implémenter ce
comportement est de servir des zones vides, plus exactement, ne
contenant que des SOA et des
NS (exactement ce que fait l'AS112, cf. RFC 7534). La valeur recommandée pour le SOA et pour
les NS est le
nom de la zone et, pour l'adresse de contact,
nobody@invalid
. Le SOA est nécessaire pour le
cache des réponses négatives (et pour les machines qui tiennent à
tenter des mises à jour dynamiques du DNS, qui ont également besoin
des NS). Sous forme d'un fichier de zone
standard, cela donne (avec un TTL de trois heures) :
@ 10800 IN SOA @ nobody.invalid. 1 3600 1200 604800 10800 @ 10800 IN NS @
Ce comportement doit être débrayable, de préférence zone par zone, pour le cas des sites qui utilisent les adresses privées et ont configuré leurs serveurs DNS pour résoudre ces adresses en noms.
La liste initiale des zones à servir figure en section 4. Elle
sert de point de départ au registre IANA, https://www.iana.org/assignments/locally-served-dns-zones/locally-served-dns-zones.xml
,
qui est la source faisant autorité (les auteurs de logiciels devraient
donc le consulter avant des nouvelles publications de leur
logiciel). Le registre est mis à jour
(cf. section 6) par le
processus « IETF review » décrit dans le RFC 5226, avec un appel au conservatisme : une fois
ajoutée au registre, une zone ne pourra jamais être retirée, puisqu'il
faudrait mettre à jour tous les logiciels. Il faut donc réfléchir
longtemps avant d'ajouter une zone.
Aujourd'hui, ce registre inclut notamment
les zones
in-addr.arpa
correspondant au RFC 1918 et celles correspondant aux réseaux du registre
documenté dans le RFC 6890 , qui ne sont pas
censés apparaître publiquement (comme les réseaux réservés pour la
documentation). Il y a aussi des zones ip6.arpa
(domaine utilisé pour la résolution d'adresses
IPv6 en noms), comme celles des
ULA du RFC 4193 (premier
RFC à avoir normalisé cette pratique pour les résolveurs DNS, pour le
domaine d.f.ip6.arpa
), celles des adresses
locales au lien (RFC 4291, section 2.5.6, un
exemple étant 8.e.f.ip6.arpa
), et celle du réseau
réservé pour la documentation (RFC 3849).
En revanche, certaines zones ne sont pas incluses (section 5) comme les anciennes adresses locales au site d'IPv6 (RFC 4291, sections 2.4 et 2.5.7) ou comme des zones plus controversées comme les TLD numériques (pour traiter le cas des logiciels qui feraient des résolutions pour ces adresses, en les prenant pour des noms).
Suivre les recommandations de ce RFC peut-il avoir des effets
négatifs ? La section 2 examine le cas. Comme les serveurs sont
incités à ne servir les zones privées que si elles n'ont pas été
configurées explicitement, les sites qui utilisent le RFC 1918 et ont peuplé les zones en
in-addr.arpa
ne devraient pas avoir de
problème. La section 2 conclut que le problème ne
se posera que dans un seul cas, les sites qui utilisent une délégation
(typiquement depuis une racine locale, non connectée à l'Internet), sans que les
résolveurs ne le voient. Ceux-ci devront explicitement reconfigurer
leurs résolveurs pour ne pas servir les zones vides désormais
installées par défaut.
Aujourd'hui, plusieurs récurseurs mettent déjà en œuvre ce RFC. C'est le cas par exemple d'Unbound (testé avec la 1.4.9). Un commentaire dans le fichier de configuration livré avec ce serveur dit :
# defaults are localhost address, reverse for 127.0.0.1 and ::1 # and nxdomain for AS112 zones. If you configure one of these zones # the default content is omitted, or you can omit it with 'nodefault'.
Le commentaire ne semble pas tout à fait correct, Unbound sert aussi
par défaut des zones qui ne sont pas gérées par l'AS112 (comme les
adresses réservées à la documentation).
Voici
sa réponse par défaut, lors d'une tentative de trouver le nom
correspondant à l'adresse IP 172.27.1.1
:
% dig -x 172.27.1.1 ... ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 8856 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; AUTHORITY SECTION: 27.172.in-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800 ;; Query time: 67 msec ;; SERVER: ::1#53(::1) ;; WHEN: Fri Jul 8 17:47:21 2011 ;; MSG SIZE rcvd: 111
À noter que localhost
est mis comme nom de
serveur maître, pas 27.172.in-addr.arpa
comme le
demande le RFC (et je n'ai pas trouvé de moyen de le configurer). Pour le cas cité dans la section 2, où on veut interroger les serveurs
faisant normalement autorité, on peut simplement mettre dans la
configuration :
local-zone: "27.172.in-addr.arpa" nodefault
et la zone 27.172.in-addr.arpa
ne sera plus
traitée comme spéciale, elle ne suivra plus ce RFC.
BIND (testé en version 9.8.0-P2) reconnait un certain nombre de zones automatiquement remplies et prévient au démarrage :
08-Jul-2011 19:43:59.410 automatic empty zone: 2.0.192.IN-ADDR.ARPA 08-Jul-2011 19:43:59.410 automatic empty zone: 100.51.198.IN-ADDR.ARPA 08-Jul-2011 19:43:59.410 automatic empty zone: 113.0.203.IN-ADDR.ARPA ...
Mais cette liste ne comprend pas encore les zones du RFC 1918. Voici le résultat en interrogeant les zones spéciales pour BIND :
% dig -x 192.0.2.1 ... ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 22522 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ... ;; AUTHORITY SECTION: 2.0.192.in-addr.arpa. 86400 IN SOA 2.0.192.in-addr.arpa. . 0 28800 7200 604800 86400 ;; Query time: 1 msec ;; SERVER: ::1#53(::1) ;; WHEN: Fri Jul 8 19:45:03 2011 ;; MSG SIZE rcvd: 86
On note que BIND ne respecte pas encore le RFC (l'adresse de contact
n'est pas nobody@invalid
) et que sa liste de
zones spéciales n'est pas encore celle du registre IANA. Toutefois,
tout cela est modifiable. Regardez la section « Built-in
Empty Zones » de l'ARM (Administrator Reference
Manual). Par exemple, vous pouvez changer l'adresse de
contact avec empty-contact nobody@invalid
dans la
section options
. Vous
pouvez désactiver le comportement spécial pour une zone avec
disable-empty-zone 2.0.192.in-addr.arpa
dans la
même section (l'équivalent du nodefault
d'Unbound). Et
bien d'autres possibilités.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : A. Durand (Juniper Networks), I. Gashinsky (Yahoo! Inc.), D. Lee (Facebook), S. Sheppard (ATT Labs)
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 1 juillet 2011
Ce court RFC prend position clairement en faveur d'un enregistrement, par les serveurs Internet, du numéro de port source du client, en plus de l'adresse IP. Cette recommandation est là pour tenir compte de la pratique de plus en plus répandue du partage d'adresses IP, notamment en raison de la pénurie des adresses IPv4.
En effet, depuis l'épuisement de ces adresses v4 début 2011, le partage d'adresses IP entre machines, par exemple via un routeur NAT, est de plus en plus fréquent. Or, de nombreux serveurs enregistrent dans un journal les adresses IP de leurs clients. Voici un exemple avec Apache :
2001:db8:1:4::1972 - - [29/Jun/2011:12:11:27 +0200] "GET /racine-dns-28-juin-2011.html HTTP/1.1" 200 9392 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30" www.bortzmeyer.org
et un avec Postfix :
Jun 29 12:04:30 aetius postfix/smtpd[29360]: connect from foo.bar.example[198.51.100.79]
(Les adresses ont été changées.)
Noter les adresses IP seules n'a guère de sens puisque ces adresses n'identifient plus une machine unique. Le RFC recommande donc que le port source soit également noté. Le processus de discussion qui a mené à ce RFC avait commencé au moins deux ans avant, à la réunion d'Hiroshima.
Évidemment, la meilleure solution au partage d'adresses serait le déploiement d'IPv6. Mais comme il va prendre des années, il faut bien gérer la situation existante. Cela implique des solutions comme le NAT44 (le NAT traditionnel, cf. RFC 3022 et mon article sur les différentes formes de NAT), le NAT64 (RFC 6146) ou bien DS-Lite (RFC 6333). Ce partage d'adresses pose des tas de problèmes (documentés dans le RFC 6269) mais celui qui nous intéresse ici est le problème de l'enregistrement de l'adresse du client.
Prenons un NAT44 classique. Le client a une adresse privée (RFC 1918), mettons
192.168.42.1
et utilise le port source 52645. Il passe à travers un routeur NAT
et ressort avec l'adresse publique
203.0.113.68
et le port source 61921. Le routeur
a mémorisé l'association entre les deux tuples, interne
{192.168.42.1
, 52645} et externe
{203.0.113.68
, 61921}. Le serveur auquel se
connecte ce client ne verra que le tuple externe. Si le serveur
enregistre uniquement l'adresse 203.0.113.68
, il
ne pourra pas distinguer les requêtes faites par la machine
192.168.42.1
de celles faites par les autres
machines situées derrière le même routeur NAT. Ce n'est pas forcément
très grave pour du NAT fait à la maison (après tout,
l'HADOPI coupera tout le monde, papa, maman et
petit frère, si la fille
aînée a téléchargé illégalement) mais c'est bien plus gênant pour du
CGN, technique récente où plusieurs abonnés
sans lien entre eux partagent une adresse IP.
Solution ? Que le serveur enregistre également le port source (ici, 61921). C'est désormais une recommandation officielle de l'IETF (voilà pourquoi ce document se nomme également « BCP 162 » pour Best Common Practices). Cette information, jointe à celle contenue dans le routeur NAT, permettra de retrouver le client original.
Notez le point mis en évidence : tout ceci n'a un sens que si le routeur NAT enregistre aussi les correspondances entre tuples {adresse, port} interne et externe. Le RFC prend soin de préciser que ses recommandations ne s'appliquent qu'aux serveurs, pas aux routeurs NAT qui, en pratique, à l'heure actuelle, n'enregistrent pas cette information (cf. section 3 sur ce point).
La recommandation exacte du RFC figure en section 2. Je la reprends ici :
Vous avez bien noté que le RFC ne prend pas position sur la question de savoir si un serveur devrait enregistrer l'adresse IP de ses clients (note au passage : il existe des serveurs qui n'enregistrent pas cette adresse, justement pour éviter de « fliquer » leurs propres clients ; cela leur évite également la responsabilité d'un fichier sensible, puisque contenant des données à peu près nominatives). Il dit juste que, si le serveur le fait, il devrait également noter le port source et l'heure. Enregistrer l'adresse IP seule ne sert pas à grand'chose (sauf, je suppose, si le but est justement de ne pas garder de données trop nominatives. Au passage, un peu de publicité pour le service No Log.)
De la même façon, le RFC évite prudemment les questions de rétention des données (lesquelles, pour combien de temps). Chaque administrateur système doit consulter la loi locale (en France, la LCEN, loi liberticide qui contient des obligations très rigoureuses à ce sujet).
Enregistrer l'heure précise est nécessaire car le serveur ne sait évidemment pas à quel rythme sont réutilisés les numéros de port par le routeur NAT.
Voyons maintenant la mise en œuvre concrète de ces recommandations, avec les deux logiciels cités plus haut. Postfix a cette possibilité depuis assez longtemps (malgré les moqueries assez bêtes de son auteur au début) :
smtpd_client_port_logging = yes
Cela donne :
Jun 29 12:04:39 aetius postfix/smtpd[30055]: connect from foo.bar.example[198.51.100.79]:48525
Par contre, son concurrent sendmail ne semble pas avoir cette capacité (il
faudrait peut-être modifier le source, en
sendmail/srvrsmtp.c
ou bien utiliser un
milter smfi_connect
, peut-être avec la macro ${client_port}
.) Et je n'ai pas d'informations sur d'autres serveurs comme exim.
Pour Apache, cela se fait en ajoutant un
%{remote}p
dans le
LogFormat
:
LogFormat "%h %{remote}p %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %v" combined
ce qui donnerait :
2001:db8:1:4::1972 42425 - - [29/Jun/2011:12:11:27 +0200] "GET /racine-dns-28-juin-2011.html HTTP/1.1" 200 9392 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30" www.bortzmeyer.org
(Le 42425 en deuxième champ.) Attention, si on analyse ses fichiers avec un programme de statistique comme analog, il faut changer également sa configuration, pour qu'il ne soit pas surpris par le champ supplémentaire.
J'ai montré un exemple avec une adresse IPv6. C'est sans doute inutile pour ce protocole (pas de traduction d'adresse/port en IPv6) mais c'est plus simple de mettre la même configuration pour les deux. Le paragraphe suivant présente un exemple où IPv4 et IPv6 sont traités différemment.
Si on veut faire plus joli, et écrire les adresses dans le style habituel des tuples {adresse, port} (adresse, deux-points, port dans le cas d'IPv4 et avec des crochets dans le cas d'IPv6, cf. RFC 3986), c'est plus compliqué. La solution que j'utilise (merci à @bitonio et @siddartha) passe par la définition d'une variable puis son utilisation dans la définition du format. (Une autre solution, due à @Grunt_, aurait été d'avoir un virtual host pour IPv4 et un pour IPv6.) Cela se configure ainsi :
LogFormat "[%h]:%{remote}p %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %v" combinedv6 LogFormat "%h:%{remote}p %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %v" combinedv4 SetEnvIf Remote_Addr : remote-v6 CustomLog /var/log/apache2/access.log combinedv6 env=remote-v6 CustomLog /var/log/apache2/access.log combinedv4 env=!remote-v6
Pour reconnaître une adresse IPv6, je cherche simplement la présence d'un deux-points. Si on veut faire mieux, il existe de jolies expressions rationnelles pour tester les familles d'adresses. Quoi qu'il en soit, le résultat est :
[2001:db8:1:4::1972]:42425 - - [29/Jun/2011:12:11:27 +0200] "GET /racine-dns-28-juin-2011.html HTTP/1.1" 200 9392 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30" www.bortzmeyer.org 192.0.2.202:53124 - - [01/Jul/2011:08:29:15 +0200] "GET /6269.html HTTP/1.1" 200 37392 "-" "Netvibes (http://www.netvibes.com)" www.bortzmeyer.org
Là aussi, il faut penser aux programmes d'analyse, dont la plupart ne sont pas capables de traiter des cas où le format varie d'une ligne à l'autre. La première solution, moins jolie, était peut-être plus raisonnable.
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : Z. Zhu (UCLA), R. Wakikawa (TOYOTA ITC), L. Zhang (UCLA)
Pour information
Première rédaction de cet article le 10 juillet 2011
Dernière mise à jour le 12 juillet 2011
Dans le monde des réseaux informatiques, on distingue en général le nomadisme (pouvoir changer d'endroit et avoir à peu près les mêmes services) et la mobilité (pouvoir changer d'endroit en maintenant les sessions existantes, comme si on n'avait pas bougé). Aujourd'hui, où beaucoup d'équipements sont mobiles (smartphone, tablette, ...), la mobilité suscite beaucoup d'intérêt. D'où ce RFC qui évalue l'état actuel du déploiement des techniques de mobilité sur l'Internet. (Disons-le tout de suite, il est très faible.)
Je vais me permettre de commencer par une polémique et des opinions personnelles : dans la famille de protocoles TCP/IP, la mobilité, c'est comme le multicast. Beaucoup de RFC, très peu de paquets. Le sujet passionne les experts, pose plein de problèmes techniques amusants, permet d'écrire des algorithmes rigolos... mais touche très peu les utilisateurs. Comment cela, les utilisateurs ne veulent pas se connecter à l'Internet depuis leur maison, puis continuer au bureau ? Si, ils le veulent, mais il n'est pas du tout évident que la mobilité au niveau IP soit nécessaire pour cela. Aujourd'hui, la technique de mobilité la plus courante est DHCP... La machine reçoit une nouvelle adresse IP et ce sont les applications qui gèrent les déconnexions/reconnexions. Prenons l'exemple du client de messagerie instantanée Pidgin et supposons que je me promène avec mon ordinateur portable, connecté via clé USB 3G dans le train, via le Wifi au Starbucks, puis via un câble Ethernet au bureau. J'aurai une adresse IP différente à chaque fois et les sessions IRC ou XMPP seront donc coupées lors des changements. Est-ce grave ? Pas tellement. Pidgin se reconnectera automatiquement à chaque fois et la seule conséquence pratique sera les messages de déconnexion et de reconnexion que verront les abonnés de chaque canal IRC / pièce XMPP. On a là un bon exemple du fait qu'une gestion de la mobilité par l'application cliente (section 5.5 de notre RFC) est suffisante et qu'il n'y a pas besoin d'un service réseau (compliqué et amenant des problèmes de sécurité) pour cela. Même chose avec une application Web : chaque requête HTTP peut utiliser une adresse source différente, l'utilisateur ne s'en rendra pas compte (à part éventuellement une obligation de se réauthentifier si le cookie est lié à l'adresse IP, ce qui se fait parfois pour limiter la réutilisation d'un cookie volé). Les applications qui reposent sur HTTP (les clients Twitter, par exemple) arrivent également à maintenir une « session » lors de changements d'adresse IP.
Bien sûr, une telle gestion par l'application ne couvre pas tous les cas. Un gros transfert de fichiers avec curl ou wget ne peut pas fonctionner ainsi, puisque ce transfert utilise une seule connexion TCP, donc dépend de l'adresse IP source utilisée au départ (cf. section 6.2). (Avec rsync, et un script qui le relance jusqu'à completion, ça marcherait.) Et, évidemment, les sessions SSH ne peuvent pas être maintenues lorsqu'on change d'adresse. Mais il reste quand même énormément de cas où il n'y a pas de vrai problème lié à la mobilité et cela explique largement, à mon avis, pourquoi les techniques de mobilité IP sont si peu déployées. J'arrête là les opinions personnelles et je reviens au RFC.
La section 1 explique que ce RFC est motivé par le fait que la mobilité est depuis longtemps un sujet de recherche actif à l'IETF et que, depuis quelques années, le déploiement des engins mobiles a explosé (smartphones, tablettes, etc). Le besoin est donc nettement plus marqué maintenant que dix ans auparavant, lorsqu'un ordinateur portable était un machin encombrant et lent. Pourtant, les solutions normalisées par l'IETF ont été peu déployées.
Ces solutions utilisent un vocabulaire rappelé en section 2 et dans le RFC 3753. Notons notamment les termes d'identificateur (identifier) qui indique une valeur qui ne change pas lors des déplacements, de localisateur (locator), qui, lui, change lorsqu'on se déplace (en IP classique, c'est le cas de l'adresse IP), de correspondance (mapping), la fonction qui permet de trouver un localisateur en connaissant l'identificateur, de correspondant (CN pour Correspondent Node, la machine avec laquelle l'engin mobile communique), etc.
La section 3 expose les principes de base de la gestion de la mobilité. Le CN doit pouvoir, dans l'Internet actuel :
Un exemple de solution de type 1 est d'utiliser le
DNS. Si le mobile met à jour (par exemple par
mise à jour dynamique, cf. RFC 2136) le DNS
lorsqu'il se déplace, on utilise le nom de domaine comme identificateur, l'adresse IP comme
localisateur et le DNS comme correspondance. Le CN peut donc toujours
trouver l'adresse IP actuelle par un simple
getaddrinfo()
. La plupart des
techniques normalisées par l'IETF sont, elles, de type 2. Dans
celles-ci, l'adresse IP sert d'identificateur (permettant de maintenir
les sessions TCP, par exemple dans le cas de SSH). Les paquets envoyés
par le CN sont alors transmis à cette adresse IP stable, où un
équipement doit ensuite les renvoyer au mobile, alors que les paquets
émis par le mobile vers le CN voyagent directement. On parle de
routage en triangle. Peu satisfaisant du point de vue des
performances, il est en revanche excellent pour la protection de la
vie privée : le CN, la machine avec laquelle correspond le mobile, ne
sait pas où on est et ne sait pas si on bouge. (Notons que le RFC, et
c'est plutôt choquant, ne mentionne pas une seule fois ces questions
de protection de la vie privée, même pas dans la section 7 sur la sécurité.)
La section 4 présente ensuite les protocoles de mobilité existants. Je ne vais pas les reprendre tous ici (la liste en compte vingt-deux !) mais simplement en choisir arbitrairement quelques uns. On trouve dans cette liste des ancêtres comme le protocole Columbia de 1991, ou des protocoles plus récents comme le Mobile IP de 1996. Certains des protocoles étudiés n'ont pas été conçus uniquement pour la mobilité, mais la facilitent. C'est le cas de HIP (2003), ILNP (2005) ou LISP (2009).
Columbia, par exemple, le premier conçu, ne fournissait la mobilité qu'à l'intérieur du campus. Dans chaque cellule radio, un routeur spécial, le MSS (Mobile Support Station), assurait le routage des paquets dont l'adresse IP source appartenait au préfixe spécial « mobilité ». Le mobile gardait donc son adresse et les MSS s'arrangeaient entre eux pour acheminer le paquet.
Le principal protocole standard de mobilité est aujourd'hui Mobile IP, normalisé dans les RFC 3344, RFC 6275 et RFC 5454. Il fonctionne en IPv4 ou en IPv6, sur la base des mêmes principes. Chaque mobile a un Home Agent, qui ne bouge pas, et qui fournit au mobile une adresse stable (Home Address). Le mobile a aussi une adresse IP liée à son point d'attache actuelle, l'adresse CoA (Care-of Address). Le mobile prévient le Home Agent de tout changement de CoA. Le correspondant, le CN, écrit toujours à l'adresses Home Address, charge au Home Agent de faire suivre. Mobile IP est donc de type 2 et, par défaut, fait du routage en triangle (une optimisation permet de le supprimer dans certains cas). Il existe aujourd'hui de nombreuses mises en œuvre de Mobile IP, aussi bien pour les mobiles que pour les Home Agents mais très peu de déploiements.
Un exemple de protocole de type 1 est E2E. Dans ce cas, l'identificateur stable du mobile est un nom de domaine, et c'est une simple requête DNS qui indique au correspondant quelle adresse IP utiliser. Le mobile, lorsqu'il change d'adresse IP, utilise les mises à jour dynamiques du DNS pour modifier cette information.
HIP n'était pas conçu uniquement pour la
mobilité. Toutefois, en séparant identificateur et
localisateur, il facilite celle-ci (RFC 5206). Pour trouver une adresse IP
à partir d'un HI (Host Identifier, les
identificateurs stables des nœuds HIP), on peut utiliser le DNS
mais aussi des « serveurs de rendez-vous » spécifiques à HIP (RFC 5204). La mobilité avec HIP nécessite que le CN
soit un nœud HIP également. Lorsqu'un mobile HIP se déplace, il
doit prévenir à la fois les CN et le serveur de rendez-vous (message
HIP UPDATE
, section 5.3.5 du RFC 5201).
Autre protocole de séparation de l'identificateur et du
localisateur qui facilite la mobilité,
LISP. Bien plus récent, il est encore peu
déployé, et ses extensions de mobilité sont seulement sous forme d'un
projet de RFC, draft-meyer-lisp-mn
.
Armé de ces descriptions, le RFC, dans se section 5, explique les différents choix qui ont été faits pour chaque protocole. C'est la section la plus intéressante du RFC. (La section 6.3 examine plus en détail les avantages et inconvénients de chaque approche.) Par exemple, une approche était de réutiliser le routage, en gardant l'adresse IP fixe pour le mobile, et en comptant sur des protocoles proches de ceux de routage pour assurer l'acheminement du paquet jusqu'au bonne endroit. Le protocole Columbia fonctionnait ainsi. Mais de telles solutions ne marchent bien qu'en réseau local : pas question de changer les routes de l'Internet chaque fois qu'un mobile se déplace.
Deuxième approche : une fonction de correspondance entre un identificateur stable et l'adresse IP actuelle. Au lieu de prévenir le monde entier lorsque son adresse change, le mobile n'aurait plus à prévenir qu'un seul point (le serveur DNS, ou le serveur de rendez-vous, pour les solutions de type 1 ou bien le Home Agent, pour celles de type 2.) Si le CN n'est pas prévenu du changement (cas de Mobile IP, par défaut), on perd en performances (routage en triangle) mais on gagne en intimité et surtout on n'a pas besoin que le CN comprenne le protocole de mobilité (avec Mobile IP, le mobile peut parler à des machines IP normales, qui ignorent tout de ce protocole).
Ce dernier point, couvert en détail dans la section 5.2, est crucial : qui doit être mis au courant de la mobilité ? Il y a quatre parties concernées : le mobile, son correspondant (CN), le réseau (les routeurs) et le composant qui donne un coup de main (Home Agent, serveur DNS, etc). Si le CN doit être mis au courant (cas de HIP, par exemple), il faut mettre à jour toutes les machines avec qui le mobile est susceptible de communiquer, ce qui ne semble pas très réaliste (d'autant plus que les gros serveurs Internet auraient à garder un état considérable, pour se souvenir de tous leurs clients récents). La plupart des approches, à commencer par Mobile IP, gardent donc une adresse IP stable et le CN est une machine ordinaire, qui ne sait même pas qu'elle parle à un mobile. Il existe aussi quelques protocoles où ni le CN, ni le mobile, ne sont au courant et où le réseau fait tout. Dans le futur, toutefois, de plus en plus de machines seront mobiles et il est possible que le premier choix (rendre le CN conscient que son partenaire se déplace) redevienne attirant.
Autre choix à faire, la mobilité doit-elle être contrôlée par le réseau ou par l'utilisateur (section 5.3) ? Dans les réseaux de téléphonie mobile, le terminal ne gère pas la mobilité, le réseau fait tout pour lui, et ça marche. Mais cela prive l'utilisateur de tout contrôle sur la façon dont est gérée la mobilité. (Songez aux scandaleux tarifs d'itinérance, rendus possibles par le fait que l'utilisateur ne peut pas empêcher que tout passe par son opérateur habituel.)
Les différences entre les protocoles de mobilité s'expliquent aussi par le fait que certains visent une solution mondiale, qui doit marcher pour des centaines de millions de mobiles se déplaçant partout dans le monde (ce qui soulève de sérieux problèmes de scalability) alors que d'autres (comme Columbia, cité plus haut), ne cherchent qu'une mobilité locale, problème bien plus facile (section 5.4).
Enfin, les vingt-deux protocoles examinés dans ce RFC ne couvrent
pas tout. On peut aussi baptiser « mobilité » des solutions simples
comme un serveur OpenVPN - qui jouera un rôle
équivalent à celui du Home Agent - plus un client OpenVPN sur chacune des
machines de l'utilisateur, avec une adresse IP fixe chacune. Il existe aussi des approches radicalement différentes
(section 5.5) comme GTP (qui ne marche qu'à l'intérieur d'un fournisseur donné) ou comme des solutions fondées sur les
applications, comme je l'ai prôné au début de cet article. Par
exemple, SIP dispose d'une extension pour gérer
la mobilité (cf. Schulzrinne, H. et E. Wedlund, « Application-Layer
Mobility Using SIP », dans Mobile Computing and Communications
Review, 2010) où un nouveau message
INVITE
est envoyé lorsque le mobile change
d'adresse IP pendant une communication.
Je l'ai dit, les protocoles spécifiques de mobilité sont pour l'instant un échec complet. Mais que prévoient les auteurs du RFC pour le futur ? La section 6 analyse d'abord cet échec (section 6.1). Peu ou pas de déploiement en production, donc. Mais pourquoi ? Le RFC estime que c'est en partie le résultat du fait que les machines mobiles ne sont devenues banales que depuis très peu de temps. Mais il reconnait aussi que les protocoles de mobilité sont des usines à gaz complexes et lentes. Certains suggèrent même de simplifier le problème en ignorant les questions de performance et de sécurité (cf. section 7 sur les problèmes de sécurité spécifiques à la mobilité) dans un premier temps (ce conseil vient directement de l'excellente section 3 du RFC 5218).
Puis la section 6 explore les pistes à suivre. Une très bonne lecture pour les concepteurs de protocoles et les étudiants en réseaux informatiques.
Pour la mobilité des téléphones et la fréquence des déconnexions, changements d'adresse IP, etc, je recommande le bon article « A Day in the Life of a Mobile Device ».
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : M. Welzl (University of Oslo), D. Ros (Institut Télécom / Télécom Bretagne)
Pour information
Réalisé dans le cadre du groupe de travail IETF ledbat
Première rédaction de cet article le 29 juin 2011
Aujourd'hui, de nombreuses applications se battent pour accéder à une ressource critique, la capacité du réseau. Tout le monde veut télécharger plus vite et les applications tentent d'obtenir le meilleur débit possible pour recevoir le dernier épisode de Dr House ou bien la page de ses amis sur Facebook. Pourtant, il existe une catégorie d'applications plus philosophes, qui cherchent à être le moins dérangeantes possibles et à ne transférer des octets que lorsqu'absolument personne d'autre n'a besoin du réseau. Ce RFC examine les techniques utilisées par ces applications tranquilles.
Il existe bien des cas où il n'y a pas d'urgence à transférer des données. Des mises à jour quotidiennes de gros fichiers ou bases de données non critiques, le transport des nouvelles Usenet (cf. RFC 5537), du téléchargement qu'on laisse tourner tout le temps, par exemple. Ces transferts, même s'ils n'ont pas besoin d'être « temps-réel » rentrent actuellement en compétition avec les transferts pressés. Si on télécharge tranquillement, sans être pressé, un gros film, et qu'on a un besoin urgent d'un fichier pendant ce temps, le fichier n'aura, pendant son transfert, que la moitié de la capacité, l'autre étant prise par le film. Il serait donc intéressant d'avoir des applications gentilles, modestes, qui cèdent systématiquement la place aux applications normales, dès que le réseau est encombré. L'IETF a un groupe de travail pour ce sujet du trafic « d'arrière-plan », dit aussi « moins que au mieux » (le trafic normal dans l'Internet étant acheminé « au mieux » - best effort). Ce groupe se nomme LEDBAT (Low Extra Delay Background Transport), et voici son premier RFC, qui étudie les techniques existantes pour atteindre cet objectif.
On pourrait même imaginer des tarifs intéressants ou des conditions d'accès au réseau plus favorables pour ces applications. Après tout, l'essentiel des coûts d'un réseau sont fixes : une fois la fibre posée et allumée, une fois les routeurs et commutateurs installés et configurés, le coût d'exploitation est le même que des bits passent ou pas. Ce qui coûte cher, en exploitation, c'est la congestion, lorsque la capacité du réseau est trop faible, que le service commence à se dégrader, et que les clients réclament une mise à jour de l'infrastructure, qui ne sera pas gratuite. Par contre, si le réseau est inutilisé à certains moments, y faire passer nos transferts de données gentils ne coûte rien. Dans tous les cas, tarifs intéressants ou pas, avoir des applications modestes aideraient certains services gourmands (comme le transfert de fichiers en pair-à-pair) à se faire accepter : on n'hésitera plus à laisser tourner BitTorrent en permanence si on est sûr qu'il cédera toujours aux applications habituelles.
La référence pour le trafic normal est TCP, le protocole de transport qu'utilisent quasiment tous les transferts de données et qui fait au mieux pour utiliser toute la capacité du réseau, ou pour la partager équitablement si elle est insuffisante (RFC 5681). Notre RFC vise donc le trafic « moins que TCP » tel que, s'il y a compétition entre trafic normal et notre trafic d'arrière-plan, le trafic normal ait la part du lion.
Le trafic d'arrière-plan est nommé dans ce RFC LBE pour less than best-effort. Un système LBE doit donc réagir à la congestion plus vite que TCP, pour abaisser son débit. Il y a quatre catégories de systèmes LBE :
Les sections suivantes fournissent divers exemples (je ne les reprends pas tous ici) de chaque catégorie.
Les solutions dans les applications font l'objet de la section 4. A
priori, on pourrait croire que les solutions de
shaping comme l'option
--bwlimit
de rsync
atteignent notre objectif de « trafic d'arrière-plan », ne rentrant
jamais en compétition avec TCP. Mais ce n'est pas le cas. Les
solutions de shaping sont :
rsync --bwlimit 64
, le débit ne dépassera
jamais 64 ko/s.Bref, ces options ne sont pas réellement LBE (voir Crovella, M. et P. Barford, « The network effects of prefetching », Proceedings of IEEE INFOCOM 1998, pour une meilleure description d'une solution de limitation de débit) .
De même, essayer de faire tourner les applications LBE aux heures creuses ne convient pas à toutes les applications (par exemple le transfert de fichiers en pair-à-pair). Autre solution, le BITS de Windows, qui surveille en permanence le débit pour ralentir ces transferts de fichiers en arrière-plan si le débit devient trop important. (Le RFC ne fournit pas d'éléments d'évaluation précis de ce service.)
Comment réaliser une application modeste ? Une première possibilité (section 4.1) est d'agir sur la fenêtre de réception, sur la machine destinataire. Le récepteur diminue la fenêtre TCP, par exemple lorsque le délai d'acheminement des paquets augmente (sur Unix, cela doit être mis en œuvre dans le noyau, je ne crois pas que l'application ait accès à cette fenêtre, mais cela ne nécessite pas de modifier le protocole TCP, c'est juste un changement unilatéral de comportement). C'est par exemple ce qui est fait en Spring, N., Chesire, M., Berryman, M., Sahasranaman, V., Anderson, T., et B. Bershad, « Receiver based management of low bandwidth access links ».
Dans les deux catégories de nouveaux protocoles de transport, voyons d'abord ceux fondés sur le délai d'acheminement. Le principe est de mesurer le temps que mettent les paquets à faire le trajet. Si cette durée augmente, c'est sans doute parce que le réseau est encombré et que donc la congestion approche. On diminue donc le débit (TCP, lui, attend bien plus, que les paquets soient effectivement jetés). La section 2 cite comme exemple TCP Vegas, un des premiers à pouvoir partager un lien avec TCP en étant systématiquement moins gourmand que lui, même si, curieusement, ce n'était pas son but initial. TCP Vegas permet au contraire souvent un meilleur débit, lorsqu'il est seul. Cela illustre le fait que ce n'est pas en diminuant le débit (cf. la discussion sur rsync) qu'on atteint l'objectif de modestie.
TCP Vegas est toujours la référence dans ce domaine. Mais, depuis, il existe des améliorations comme TCP Nice (voir Venkataramani, A., Kokku, R., et M. Dahlin, « TCP Nice: a mechanism for background transfers », qui reprennent le même principe de diminuer le débit lorsque le RTT diminue (sans attendre que les pertes de paquets commencent). À noter que TCP Nice a une mise en œuvre dans Linux (citée dans l'article ci-dessus).
Autre cas de protocole fondé sur le délai, TCP-LP, qui utilise le délai en aller simple et pas le RTT comme les deux précédents. C'est normalement un meilleur indicateur (on n'est pas perturbé par le trafic de retour, qui peut n'avoir rien à voir puisque le chemin de retour peut être différent, et/ou moins congestionné) mais il est plus difficile à mesurer (TCP-LP utilise l'option d'estampillage temporel des paquets de TCP, cf. RFC 7323).
Tous ces schémas ont un défaut commun : les études (par exemple McCullagh, G. et D. Leith, « Delay-based congestion control: Sampling and correlation issues revisited ») montrent que le délai d'acheminement n'a qu'un faible rapport avec l'approche de la congestion. Le délai varie souvent pour des raisons qui n'ont rien à voir avec l'encombrement (les tampons devraient être bien plus grands pour mesurer ce délai sans ce bruit ; les liens radio vont varier le délai quel que soit l'encombrement ; etc). En outre, les horloges des machines sont souvent insuffisantes pour mesurer le délai avec une bonne précision, surtout sur un réseau local où les paquets voyagent vite et où l'essentiel du délai est dû au traitement dans les machines, pas au réseau. Enfin, certaines techniques d'optimisation de TCP faussent encore plus cette mesure.
En pratique, ces problèmes peuvent mener à réduire le débit sans raison. Ces « faux positifs » atteignent quand même l'objectif (être moins gourmand que TCP) mais les problèmes de mesure peuvent aussi mener à des faux négatifs, où le protocole de transport ne détecte pas une congestion bien réelle.
Enfin, tout protocole fondé sur le délai d'acheminement donne un avantage aux derniers arrivants : sur un tuyau déjà très encombré, le flot récent voit des délais importants dès le début et ne se rend donc pas compte de la congestion.
Il existe aussi des protocoles de transport LBE (modestes) n'utilisant pas le délai d'acheminement (section 3). Ils jouent sur le rythme d'envoi (qui dépend de la réception des accusés de réception) pour, par exemple, diminuer la fenêtre d'envoi plus vite que TCP. C'est le cas de 4CP ou de MulTFRC (une extension du TFRC du RFC 5348).
Enfin, il y a les solutions qui utilisent une assistance du réseau (section 5). Sur le papier, ce sont les plus efficaces (pas besoin de mesures indirectes, comme celle du délai d'acheminement, le routeur sait parfaitement si le réseau est encombré ou pas) mais aussi les plus dures à déployer car elles nécessitent une modification de tous les routeurs.
Un exemple d'une telle technique est NF-TCP (Arumaithurai, M., Fu, X., et K. Ramakrishnan, « NF-TCP: A Network Friendly TCP Variant for Background Delay- Insensitive Applications ») qui combine ECN (RFC 3168) et RED (RFC 7567) pour diminuer la priorité des flots NF-TCP dans les routeurs dès que la congestion menace.
Armé de la connaissance de toutes ces techniques (on voit que l'imagination des chercheurs et ingénieurs a été intense sur ce sujet), que va faire le groupe de travail LEDBAT ? La section 6 explique que LEDBAT a déjà un système, décrit un l'Internet-Draft, fondé sur le délai d'acheminement » (ceux de la section 2). Ce n'est pas à proprement parler un protocole mais un algorithme, qui pourra être utilisé dans les protocoles concrets. Il a depuis été publié dans le RFC 6817.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : M. Wasserman (Painless Security), F. Baker (Cisco Systems)
Expérimental
Première rédaction de cet article le 30 juin 2011
Avec ce RFC, encore expérimental, IPv6 gagne la possibilité de faire de la traduction d'adresses, c'est-à-dire d'avoir dans un réseau local des adresses internes, qui seront dynamiquement traduites en adresses externes par le routeur de sortie, qui pourra également faire l'opération inverse (de l'extérieur vers l'intérieur).
Cette traduction est souvent nommée NAT (Network Address Translation) mais ce terme n'est pas correct : la traduction habituelle en IPv4, celle que tout le monde doit supporter pour sa connexion Internet à la maison et pour son accès 3G, NAT44, ne traduit pas uniquement l'adresse. Pour faire face à la pénurie d'adresses IPv4, elle met en correspondance plusieurs adresses internes (typiquement du RFC 1918), avec une adresse externe, en utilisant les numéros de port pour démultiplexer les paquets entrants. Cette technique devrait donc s'appeler NAPT (Network Address and Port Translation) et pas NAT. Elle a des tas d'inconvénients, décrits dans le RFC 6269.
En IPv6 au contraire, sujet de notre RFC, il n'y a pas de pénurie d'adresses et pas de raison de faire du NAPT. Le protocole de traduction proposé dans ce RFC 6296 mériterait donc, lui, de s'appeler NAT (ou peut-être NAT66), mais, comme ce terme est désormais très galvaudé, ses auteurs ont plutôt choisi NPT pour Network Prefix Translation. NPTv6 permet une correspondance univoque (1:1) entre les adresses internes et les adresses externes, évitant ainsi le partage d'adresses dont le RFC 6269 décrit les défauts. Pour diverses raisons (cf. RFC 2993 et section 5 de notre RFC), l'IETF n'encourage pas les systèmes de traduction mais, si un utilisateur tient à en faire, ce RFC lui fournit un protocole bien étudié. Il n'évite pas tous les problèmes de la traduction (RFC 4864, RFC 5902) mais les limite.
N'utilisant pas les ports, NPTv6 fonctionne donc avec tous les protocoles de transport, contrairement au NAT44 traditionnel (cf. section 6). Il est sans état (chaque paquet est traduit indépendemment des autres) donc le routeur qui fait la traduction n'a pas de problèmes comme le remplissage de la table (fréquent avec NAT44). Ainsi, un réseau peut être servi par deux traducteurs (par exemple pour la redondance) sans qu'ils aient à partager un état. Mais ce caractère sans état a aussi d'autres conséquences :
Voilà pour un résumé très rapide des propriétés de NPT v6.
Mais pour quelles raisons peut-on avoir envie de déployer un système de traduction ? La section 1.1 de notre RFC propose de les résumer en un principe : indépendance vis-à-vis de l'adresse. Ce principe comprend plusieurs propriétés :
« Adresses internes + traduction » est donc potentiellement un « PI du pauvre ». En IPv4, beaucoup de sites utilisaient le NAT pour atteindre cette indépendance, même lorsqu'elles pouvaient obtenir suffisamment d'adresses IP. Le RFC 4864 décrit d'ailleurs un concept proche nommé « autonomie du réseau ».
NPTv6 est donc un mécanisme qui permet de réaliser cette indépendance du réseau. Meilleur que le NAT44 (pas de manipulation des ports, fonctionne donc avec tous les protocoles de transport, comme SCTP, permet les connexions entrantes, purement « algorithmique » donc sans état), il peut donc être un ajout intéressant à la boîte à outils de l'administrateur de réseaux IPv6.
Pour être tout à fait complet, il faut aussi rappeler ses inconvénients (RFC 2993) :
Bref, NPTv6 n'est pas une solution parfaite et c'est pour cela que ce RFC reste au statut Expérimental.
Si on décide de poursuivre cette voie, il faut choisir les adresses à utiliser en interne. Les ULA du RFC 4193 semblent la solution idéale, maximisant l'indépendance.
Voici pour les grands principes. Quelques détails pratiques
maintenant. Prenons l'exemple simple de la section 2.1 : un réseau
interne, utilisant un préfixe ULA,
fd01:203:405:/48
, est connecté à l'Internet via
un unique FAI, et un routeur qui fait du NPTv6. Le préfixe
PA alloué par le FAI et routable publiquement
est 2001:0db8:1:/48
(notez que NPT n'impose pas
que les deux préfixes aient la même longueur, cf. section 3.7). Lorsqu'un paquet « sort »
(va du réseau local vers l'Internet), l'adresse IP source est
remplacée par une adresse IP prise dans le préfixe du FAI. Les autres
champs de l'en-tête IP ne sont pas modifiés. En sens inverse,
lorsqu'un paquet « entre » (vient de l'Internet vers le réseau local),
c'est l'adresse de destination qui est touchée, pour être remplacée
par une adresse du réseau local.
La partie identifiant la machine sur le réseau local (80 bits dans
cet exemple) n'est en général pas conservée telle quelle. Ainsi, si fd01:203:405:1::1234
écrit à
2a00:1450:8007::13
, Gmail, le
destinataire, verra le paquet venant de
2001:0db8:1:d550::1234
En effet, la traduction est neutre pour la somme de contrôle. Si on suit l'algorithme standard du RFC 1071, on veut obtenir la même somme de contrôle avant et après traduction. Les protocoles qui utilisent une somme calculée sur une partie de l'en-tête IP (c'est le cas de TCP) ne seront donc pas affectés. Astuce amusante, pour atteindre cet objectif de neutralité, 16 bits de l'adresse sont réservés pour pouvoir y faire les modifications qui annuleront les autres changements faits dans l'adresse. L'algorithme exact de calcul est dans les sections 3.1 et suivantes. Une mise en œuvre en C figure en annexe B. À noter qu'elle ne prétend pas être optimale, faisant par exemple les calculs de somme de contrôle avec du code portable et pas de l'assembleur adapté à une machine particulière.
On peut avoir des cas plus compliqués que ce simple réseau, par exemple du multi-homing, où le réseau local est connecté à deux FAI (section 2.4). Chacun de ces deux FAI alloue un préfixe PA différent. Les liens avec les deux FAI passent par deux routeurs NPT différents, tous les deux configurés avec le même préfixe interne mais différents préfixes externes. Une machine du réseau local ne pourra pas savoir sous quelle adresse elle apparaitra à l'extérieur, sauf à utiliser une technique comme STUN (RFC 8489). La décision de sortir par un FAI ou l'autre peut être prise comme on veut. Par contre, par rapport à du vrai multi-homing, avec adresses PI et BGP, un changement de FAI de sortie entraîne un changement de l'adresse IP vue par l'extérieur et coupe donc toutes les sessions en cours.
Continuons avec les considérations de déploiement et de configuration (section 4). Le plus probable est que NPTv6 sera mis en œuvre dans les routeurs, comme dans l'exemple ci-dessus, et, pour les particuliers et petites organisations dans le CPE. Les obligations du RFC 7084 s'appliquent donc à l'engin qui fait la traduction.
Cela implique entre autres que le traducteur NPT soit capable de faire des virages en épingle à cheveux (renvoyer vers le réseau local un paquet qui était à destination du réseau local, cf. RFC 4787), afin que des machines du réseau local puissent se parler en utilisant leurs adresses publiques. Comme NPT ne tripote pas les ports, la plupart des autres exigences des RFC du groupe BEHAVE ne s'appliquent pas à lui.
Et pour les applications, quelles sont les conséquences (section 5) ? Plusieurs des problèmes classiques de la traduction, qui avaient déjà été décrits dans le RFC 2993 sont toujours présents. Les applications ne verront pas les mêmes adresses, selon qu'elles sont situées d'un côté ou de l'autre du traducteur. Par exemple, si un ordinateur portable se déplace de part et d'autre du traducteur, il verra ses connexions s'interrompre, son adresse IP ayant changé. Mais les problèmes les plus fréquents et les plus sérieux seront pour les protocoles applicatifs qui utilisent des références, c'est-à-dire qui indiquent dans les données à quelle adresse IP envoyer les paquets. Les cas les plus connus sont FTP et SIP. Si un client SIP envoie à un autre son adresse interne, pour recevoir un flux RTP, cette adresse ne sera pas traduite, et le flux ne joindra pas la destination. Que peut-on faire pour limiter les dégâts ?
Et la sécurité du NPTv6 ? La section 7 résume les points importants. Le principal est que, contrairement au NAT classique, avec état, NPT n'empêche pas les connexions entrantes. C'est une bonne chose mais cela peut dérouter certains administrateurs réseaux qui croyaient que la traduction les protégeait de l'extérieur. Ce n'est pas le cas avec NPTv6 et si on veut une telle protection, il faut installer un pare-feu explicite (alors que le NAT traditionnel mélange les deux rôles de traduction et de protection), comme décrit dans le RFC 6092.
Curieusement, cette idée de traduction d'adresses sans état, selon une cardinalité 1:1, est très ancienne. Si notre RFC 6296 semble être le premier RFC à la décrire, elle avait été à la base du projet GSE, auquel l'annexe A rend hommage. GSE, décrit dans le draft draft-ietf-ipngwg-gseaddr, était un des projets qui avaient été élaborés pour le successeur d'IPv4. Contrairement au projet retenu (le futur IPv6) qui conservait les concepts de base de son prédécesseur, GSE repensait nettement le problème de l'adressage dans l'Internet. Celui-ci était divisé en deux, les réseaux de transit et les réseaux de bordure. Dans GSE, seuls les réseaux de transit avaient des adresses publiques et annoncées dans la table de routage globale. Les réseaux de bordure avaient des adresses stables et uniques mais qui n'étaient pas routées. Les adresses étaient traduites lors du passage du réseau de bordure au réseau de transit et réciproquement. Le but était surtout de limiter la croissance de la table de routage (problème qu'IPv6 avait finalement décidé de ne pas traiter). En décembre 2010, sur l'Internet, il y a 36 000 systèmes autonomes dont 15 000 n'annoncent qu'un seul préfixe (et sont donc probablement des réseaux de bordure). Seuls 5 000 systèmes autonomes apparaissent dans des chemins (en dehors de l'origine) et sont donc des réseaux de transit.
Et les implémentations publiquement disponibles ? (Merci à François Romieu et Samuel Thibault pour leurs informations.) Il y a map66 et aussi nfnat66 (NAT66 pour Netfilter), qui utilise netfilter et est présenté en français dans l'exposé de Guy Leduc et plus en détail dans la thèse de Terry Moës, « IPv6 address translation in a Linux kernel ». Ne m'en demandez pas plus, je n'ai pas testé. (À noter qu'il en existe aussi pour des techniques de traduction IPv6<->IPv6 différentes, par exemple avec état.)
Mais c'est une autre mise en œuvre qui a été intégrée dans le
noyau Linux en août 2012 (commit
8a91bb0c304b0853f8c59b1b48c7822c52362cba
) et qui a donc été livrée avec la sortie de la version
3.7 en décembre 2012. Regardez les fichiers en
net/ipv6/netfilter
comme ip6table_nat.c
.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : P. Hoffman (VPN Consortium)
Pour information
Réalisé dans le cadre du groupe de travail IETF genarea
Première rédaction de cet article le 24 juin 2011
Dernière mise à jour le 6 juillet 2012
Une des particularités de l'IETF est son extrême ouverture. Tout le monde peut suivre le travail en cours, les documents de travail (les Internet Drafts) sont publiquement accessibles, l'état de chaque document dans le processus de publication peut être suivi sur le Web. Bref, sans avoir à se ruiner en déplacements physiques, le participant à l'IETF a accès à tout ce qu'il faut. Mais ce système a aussi ses insuffisances, notamment parce qu'il ne permet pas d'accès personnalisé et que seuls certains participants ont un accès en écriture. Ce RFC est donc le cahier des charges d'un nouveau système de suivi des Internet Drafts, système qui a finalement été déployé début juillet 2012.
Le système de suivi du travail de l'IETF repose sur un
ensemble d'outils non-officiels maintenus par des volontaires, http://tools.ietf.org/
, et par un site officiel de suivi, le
« Datatracker » (http://datatracker.ietf.org/
. Le
Datatracker permet de s'identifier, pour certaines
actions, mais cette possibilité n'était pas ouverte aux participants
ordinaires, seulement à ceux chargés d'une tâche comme le pilotage
d'un groupe de travail. (Notez que « participant IETF » = « public »
puisque l'IETF n'a pas d'adhesion formelle, tout le monde en est
membre dès qu'il participe, cf. section 1.3.)
Le Datatracker donne accès à plein
d'informations sur les documents en cours (la section 1 résume les possibilités de l'actuel Datatracker). Prenons l'exemple de
l'Internet Draft que demandait
l'ICANN sur la syntaxe des noms de
TLD,
draft-liman-tld-names
. On peut connaître son état
en visitant http://datatracker.ietf.org/doc/draft-liman-tld-names/
: au 23
juin 2011, la version actuelle est la n° 5, datant du 12 avril, et il est en état I-D Exists, qui est
l'état normal de tout Internet Draft. Il n'est donc
pas en vue d'une publication comme RFC, juste
en discussion. Si on veut suivre les évolutions du document, nul
besoin de tout relire (comme c'est le cas dans d'autres organisations,
où les diff ne sont pas fournies lors de la
sortie d'un nouveau document), le Datatracker est
serviable. Voici les différences entre les versions 4 et 5 : http://tools.ietf.org/rfcdiff?url1=draft-liman-tld-names-04&difftype=--html&submit=Go!&url2=draft-liman-tld-names-05
(dans ce cas précis, elles étaient purement administratives).
Si je
m'intéresse plutôt au document sur le protocole de résolution de noms
d'Apple appelé (bien à tort) Multicast
DNS, je trouve l'information en http://datatracker.ietf.org/doc/draft-cheshire-dnsext-multicastdns/
. Le
document (actuellement en version 14) est approuvé par
l'IESG mais a besoin d'une nouvelle
version. Les opinions des membres de l'IESG sont accessibles en http://datatracker.ietf.org/doc/draft-cheshire-dnsext-multicastdns/ballot/
(Discuss signifiant une objection.).
Ce niveau de transparence est bien au delà de ce que font les autres SDO comme l'UIT ou l'AFNOR où tout le travail est fait derrière des portes closes, pour éviter que le public n'y participe. Mais on peut encore faire mieux.
Par exemple (section 1.1), on pourrait imaginer qu'un utilisateur veuille s'identifier pour retrouver les informations sur la liste des Internet Drafts qu'il suit, liste déterminée manuellement ou via une recherche. Il peut aussi vouloir recevoir une notification si une nouvelle version d'un de ces documents apparait.
La section 2 décrit plus précisement les exigences du nouveau Datatracker :
D'autres idées, dont la mise en œuvre n'est pas requise pour la première phase, figurent dans les annexes A et B. Par exemple, suivi des changements dans les registres IANA (ça, cela me serait très utile).
Le cahier des charges est donc fini, il ne restait plus que le développement et le déploiement, qui a été finalisé le 3 juillet 2012. Tout le monde peut désormais en bénéficier.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : E. Chen, J. Yuan (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 11 octobre 2011
Un tout petit RFC pour régler un bête problème de définition dans le protocole BGP. L'identifiant d'un routeur BGP devait être une adresse IPv4. Avec l'épuisement de ces adresses, tous les routeurs n'en auront pas forcément une et ce RFC accepte explicitement comme identificateur n'importe quel numéro unique (à l'intérieur d'un AS).
Cet identifiant est défini par la norme BGP (RFC 4271, section 1.1) comme un nombre de 32 bits, qui doit être une des adresses IPv4 du routeur (cela assurait son unicité en réutilisant un nombre déjà alloué ; cette unicité est vérifiée lors de l'établissement de la connexion). La section 2.1 de notre RFC supprime l'obligation d'être une adresse IPv4, et ajoute celle que le numéro soit unique au sein de l'AS (ou, plus exactement, de la confédération, s'il y a plusieurs AS). Cette unicité par AS était nécessaire pour les cas où un routeur fait de l'agrégation de routes qu'il relaie (section 3).
Ce changement ne modifie donc pas le protocole BGP, ni le comportement de chacun des pairs BGP. Simplement, dans le cas d'un réseau purement IPv6, où aucun des routeurs n'avait d'adresse IPv4, ils pourront désormais prendre un nombre quelconque comme identifiant, sans violer de RFC.
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : R. Barnes, M. Lepinski (BBN Technologies), A. Cooper, J. Morris (Center for Democracy & Technology), H. Tschofenig (Nokia Siemens Networks), H. Schulzrinne (Columbia University)
Réalisé dans le cadre du groupe de travail IETF geopriv
Première rédaction de cet article le 24 juillet 2011
Aujourd'hui, de nombreuses applications des réseaux informatiques dépendent de la localisation physique de l'appareil mobile. La récolte de ces données de localisation (« le 31 mai 2011, à 08:04, l'appareil était en 40,756° Nord et 73,982° Ouest, ±150m »), leur transmission à travers le réseau, et leur traitement par le service qui héberge l'application posent de graves questions de protection de la vie privée, surtout quand on lit les conditions d'utilisation de ces services (si on pouvait comprendre le jargon juridique, elles se résumeraient à « nous faisons ce que nous voulons, nous nous occupons de tout, ne vous inquiétez pas »). D'où ce RFC qui essaie de définir une architecture de gestion de la vie privée pour ces informations de localisation.
Un exemple d'une telle application est Pages Jaunes sur Android : elle permet d'obtenir des réponses qui dépendent du lieu, tel que l'a indiqué le téléphone. Ainsi, si on tape « pizzeria », on obtient en haut du classement les pizzerias les plus proches physiquement. Résultat, les Pages Jaunes savent où vous êtes et on imagine facilement les conséquences pour la vie privée de ce genre de suivi (« L'utilisateur est allé quatre fois dans une clinique spécialisée cette semaine. »). Outre les Pages Jaunes, plusieurs intermédiaires connaissent également votre position (l'opérateur du réseau, qui sait par quelle borne vous vous connectez, les tiers qui écoutent, si le trafic n'est pas chiffré, et le téléphone lui-même qui peut garder cette information très longtemps, comme le fait l'iPhone). À noter que cette information est collectée en permanence, sans action explicite de l'utilisateur (section 1.2). Dans les romans policiers, finies les longues filatures sous la pluie pour savoir où passe le suspect. Le cyber-policier moderne ne bouge plus de sa chaise et obtient via le réseau toutes les informations nécessaires, chaque citoyen emportant avec lui volontairement l'outil qui permet de le suivre à la trace.
Le RFC (section 1) ne prétend même pas qu'il va régler ce problème, qui est consubstantiel de la récolte et diffusion d'informations de localisation : il affirme juste qu'il tente de limiter les dégâts.
Il y a deux autres points importants à comprendre sur cette « architecture de protection de la vie privée » : d'abord, ce n'est qu'une architecture, pas un protocole, encore moins un logiciel. Elle définit un cadre et des principes, elle ne fournit pas de solutions clé en main. Ensuite, s'agissant d'un travail de l'IETF, elle ne traite que l'aspect technique. Si on suit ce RFC, et les standards futurs qui le développeront, on peut faire un système relativement protecteur de la vie privée. Mais la technique ne suffit pas : le respect du RFC ne garantit pas la sécurité, c'est une norme technique, pas une politique. Des lois de protection de la vie privée (et qui soient d'application générale, pas annulables par des conditions d'utilisation d'un service commercial), bien appliquées et une vigilance citoyenne permanente sont nécessaires si on veut empêcher la vie privée de devenir une marchandise comme les autres.
Ce RFC 6280, œuvre du groupe de travail Geopriv, qui travaille sur tous les problèmes situés à l'intersection de la localisation et de la vie privée, tourne autour de la notion d'« objet de localisation » (une bonne introduction à Geopriv est le RFC 3693). Cet objet stocke la localisation et les règles d'utilisation de cette information. Lorsque l'objet est transmis, les conditions d'utilisation voyagent avec lui (section 1.1). Ainsi, celui qui reçoit une information de localisation ne peut pas prétendre ignorer les règles qui s'y attachent. Ces règles sont, par exemple, « ne transmets ces données à personne » ou, plus subtil, « ne transmets les informations à mon entreprise que pendant les heures de travail ».
Lier les règles d'usage aux informations de localisation est contraignant mais permet de d'assurer que le destinataire a accès à ces règles. Le RFC cite l'exemple des licences libres comme Creative Commons, qui imposent une telle liaison. Il y a eu de nombreuses polémiques (par exemple au sujet de la GFDL), sur l'opportunité d'imposer l'inclusion du (long) texte de la licence dans chaque document couvert par cette licence mais le but est le même : couper court à toute tentative de jouer l'ignorance. Un autre exemple donné par le RFC est celui des classifications utilisées par les militaires (« Secret », « Confidentiel », etc). Tous les documents sont marqués avec leur niveau de sécurité et tout militaire qui les manipule sait donc exactement ce qu'il peut faire ou ne pas faire avec ce document. (Un exemple détaillé figure dans les règles de classification du ministère de la défense états-unien.)
La solution radicale serait évidemment d'arrêter la collecte et la transmission de ces informations. Mais, outre qu'elles peuvent permettre d'améliorer certains services (comme dans l'exemple des pizzérias plus haut), des systèmes comme le GSM ne peuvent pas fonctionner sans connaître la localisation de l'utilisateur (pas moyen de lui faire suivre un appel entrant si on ne sait pas quelle borne le dessert en ce moment). Comment limiter les dégâts ? Historiquement, les décisions en matière de vie privée étaient prises uniquement par le récepteur des données, qui en faisait à peu près ce qu'il voulait. Le seul choix de la personne concernée était de partager ses données ou pas, et ce choix binaire ne permettait pas d'indiquer ce qu'il acceptait qu'on fasse des données (section 1.3). Comme, évidemment, les intérêts des personnes ne coïncident pas avec ceux des entreprises privées et organisations étatiques qui reçoivent les données, les abus étaient inévitables. Par exemple, un utilisateur envoie volontairement son adresse électronique sur un site Web pour recevoir ensuite des informations, mais il ne pouvait jamais s'opposer à ce que cette adresse soit ensuite revendue à des spammeurs. (Aujourd'hui, il est courant de voir une case à cocher « J'accepte de recevoir du spam, pardon, que mon adresse soit revendue à des tiers » mais il faut noter que c'est le site Web destinataire qui définit les choix possibles, pas le titulaire de l'adresse.) Geopriv pose donc comme principe que l'utilisateur, pas le destinataire, définit les usages acceptables, et les indique avec les données. À noter que ce n'est qu'une indication. Il n'existe pas de moyen technique de s'assurer que ces choix de l'utilisateur seront respectés, une fois les données transmises. Sur un réseau distribué comme l'Internet, il n'y a pas de possibilité de concevoir un mécanisme technique de respect de ces règles. Celui-ci doit être assuré par des moyens autres, comme la loi (loi Informatique & Libertés, par exemple), des régulateurs efficaces et/ou le marché (note personnelle : pour des raisons idéologiques, le marché est mentionné par le RFC comme mécanisme possible de rétroaction sur les entreprises qui violeraient les usages spécifiés par l'émetteur ; l'expérience déjà ancienne de l'Internet en matière de protection de la vie privée montre bien la vanité de cette idée). Le mécanisme technique de Geopriv sert donc juste à s'assurer que le destinataire des données était conscient des règles et donc, s'il les a violées, qu'il était de mauvaise foi (ce qui est important pour d'éventuelles poursuites judiciaires).
Avec la section 3 commence la partie la plus technique du RFC : elle décrit l'architecture utilisée. Les deux objectifs de cette architecture sont :
Comme on l'a vu, s'assurer que les entités réceptrices ne peuvent pas techniquement violer les règles est un non-but : il n'est pas réalisable techniquement. Pour atteindre les deux objectifs, il y a deux classes de règles :
Un exemple figure en section 3.1, décrivant le « cycle de vie » des données. Alice se déplace. Son mobile apprend sa position (par le réseau de communication, ou bien par GPS) et elle veut partager cette information avec ses amis via un service de présence (un tiers, qu'on suppose de confiance). Avec cette information viennent les règles d'usage qu'Alice a définies, par exemple que les amis ne peuvent pas garder cette information plus de N jours. Si un ami, mettons Bob, veut transmettre l'information sur la localisation d'Alice à des amis à lui, il devra également vérifier si les règles d'usage lui permettent (rappelez-vous que ce RFC définit une architecture de sécurité, pas des moyens techniques de protection ; comme le savent ceux qui ont essayé de mettre en œuvre des DRM, il n'existe aucun moyen technique d'empêcher Bob de tricher et de faire suivre ces données à des gens non autorisés).
Décrire ensuite tout ce qui se passe nécessite un vocabulaire élaboré (section 3.2). On y trouve de nombreux rôle (un même acteur pouvant tenir plusieurs rôles) :
J'ai simplifié en mettant un seul décideur et un seul localisateur mais il peut y avoir des cas plus complexes.
Pour mettre en œuvre l'architecture de sécurité Geopriv, on a besoin de deux formats de données :
En utilisant cette terminologie, la section 4 du RFC décrit le cycle de vie de l'information de localisation. Elle passe par trois étapes :
Les trois étapes sont ensuite étudiées une à une, chacune posant des problèmes spécifiques de protection de la vie privée.
La section 4.1 parle de la détermination. Elle peut être faite par l'engin lui-même (GPS, observation des étoiles et bien d'autres, y compris pour le cas trivial où l'utilisateur rentre manuellement l'information), par le réseau auquel il se connecte, ou bien via une coopération entre tous les deux. Dans le premier cas, guère de problème de sécurité dans cette étape, l'engin étant tout seul (les satellites GPS ne dialoguent pas avec l'engin, ils ne savent pas qui les utilise). Bien plus délicat est le cas où c'est le réseau qui détermine la position. C'est ce qui se produit en GSM (le réseau sait avec quelle base parle l'engin, et l'intensité du signal, ainsi que sa direction, peuvent donner une idée plus précise de la position de l'engin) mais évidemment aussi en connexion filaire, où le réseau sait exactement où on se trouve. Tout mécanisme du genre GeoIP est également un cas de détermination de la position par le réseau. Il n'y a pas forcément besoin d'un protocole réseau. Mais le point important est qu'un tiers (pas seulement le sujet) connait dès le début la position de l'engin. Enfin, le troisième cas est celui de la détermination assistée par le réseau. Par exemple, un engin va mesurer un certain nombre de choses comme la force du signal radio, l'adresse MAC obtenue, etc, et les envoyer à un localisateur qui en déduira une position précise. Cette fois, il y a un protocole réseau (entre l'engin et le localisateur), qu'il faut protéger, par exemple contre l'écoute.
L'étape de détermination est le premier endroit où on peut appliquer des mesures de protection, comme l'utilisation d'identificateurs qui ne permettent pas un lien simple avec l'utilisateur, et comme le chiffrement pour empêcher l'écoute, dans le cas où la détermination emploie un dialogue sur le réseau.
La deuxième étape est la distribution de l'information de localisation (section 4.2). C'est là que les règles d'usage commencent à jouer un rôle, en limitant la redistribution. Voici quelques exemples de règles :
example.com
,Les deux derniers exemples montrent qu'un serveur de localisation a deux armes à sa disposition, ne pas transmettre la localisation du tout, ou bien la transformer pour limiter les risques.
Pour cette étape de distribution, les choses les plus importantes sont de toujours transmettre les règles d'usage avec la localisation, et de respecter ensuite ces règles. Ces règles pouvant dépendre de l'identité de celui à qui on transmet, utiliser des techniques d'authentification fiables est donc impératif. De même, il faut veiller à ce qu'un tiers non-autorisé ne puisse pas accéder aux données qui circulent sur le réseau, donc le chiffrement est fortement souhaité. On est là dans un domaine plus traditionnel pour l'IETF, la conception de protocoles réseaux sûrs.
Enfin, la troisième étape du cycle de vie de l'information de localisation est l'utilisation de l'information (section 4.3). Le destinataire doit respecter les règles d'usage, qu'il a reçu avec l'objet de localisation. Normalement, ce respect est obligatoire et des mesures administratives ou légales doivent être déployées pour s'assurer que ce soit le cas. Cette étape ne comprend pas de transmission de l'information et ne nécessite donc pas de protocole réseau.
La section 6 du RFC fournit des exemples de scénarios concrets
d'utilisation de cette information de localisation. Le premier
scénario est très simple : un engin détermine sa position et la
transmet à une application Web dans une requête
HTTP de type POST
ou bien
une requête SIP de type
INVITE
. Le serveur fournit le service demandé,
sans stocker l'information de localisation. Dans ce cas ultra-simple,
pas de place pour les architectures compliquées, les rôles sont bien définis (le RFC oublie
toutefois de rappeler que la connexion entre l'engin et le serveur
doit être protégée contre l'écoute).
Plus complexe, en section 6.2, le cas où un navigateur Web qui fait appel à des API de détermination de sa position (comme la Geolocation API, dont l'implémentation fait souvent appel à l'aide du réseau d'accès) et exécute du code JavaScript qui va appeler des services d'assistance à la détermination de la position (voyez un bon tutoriel en « Geocoding A User's Location Using Javascript's GeoLocation API »). Notez qu'une partie des risques peut provenir d'une action du navigateur après avoir obtenu sa position. Par exemple, s'il demande à Google Maps une carte des environs, Google Maps, bien que n'étant pas partie lors de la détermination de la position, la connaîtra désormais. Il y a plus de deux acteurs, cette fois (notez que, même sur une machine unique, il peut y avoir plusieurs composants logiciels ne se faisant pas mutuellement confiance) et donc davantage de complexité.
Enfin, le troisième scénario est plus critique puisqu'il concerne un appel d'urgence, domaine très régulé, puisque beaucoup d'opérateurs ont l'obligation légale de fournir automatiquement la localisation de l'appel. Ici, la distribution de l'information se fera typiquement en utilisant LoST (RFC 5222).
Comme tout RFC, notre RFC 6280 inclut une section sur les problèmes de sécurité (section 5). Ici, elle sert surtout de rappel car tout le RFC est consacré à la sécurité. Parmi les rappels : le fait qu'il existe déjà des protocoles fournissant les fonctions de sécurité importantes (IPsec et TLS, par exemple) et que les solutions de localisation devraient les utiliser. Autre rappel : la sécurité de bout en bout est préférable à la sécurité transitive et il est donc recommandé qu'on sécurise l'ensemble du trajet, pas juste chaque étape (pensez au cas de Bob faisant suivre un objet de localisation : l'a-t-il modifié ?). Une bonne étude générale des problèmes de sécurité de Geopriv est dans le RFC 3694.
Date de publication du RFC : Juillet 2011
Auteur(s) du RFC : F. Gont (UK CPNI)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 6 juillet 2011
Le protocole IPv4, qui représente toujours la très grande majorité du trafic réseau sur l'Internet, n'avait jamais fait l'objet d'un rapport synthétique sur sa sécurité. Certes, il existe d'innombrables articles portant sur la sécurité d'IPv4, des avis des CSIRT, de très nombreuses mentions dans les RFC et ailleurs. Mais tout ceci était dispersé dans de nombreux documents, et pas forcément facilement accessible lorsqu'on se mettait à lire les normes. D'où ce RFC 6274 qui rassemble en un seul endroit tout ce qu'il faut savoir sur la sécurité d'IPv4. Pas de révélations dans ce document, les problèmes qui y sont décrits sont très classiques, souvent résolus depuis des années mais, comme ils n'avaient pas forcément été documentés dans un RFC, il y avait un risque sérieux qu'un programmeur, voulant mettre en œuvre IPv4 en partant de zéro, retombe dans des failles anciennes. Ce RFC vise donc à éviter toute régression. Avant sa publication, un programmeur qui ne lisait que les RFC était à peu près sûr de créer des failles de sécurité béantes.
Parfois, c'est même pire : des failles connues ne sont pas résolues dans certaines implémentations, ou bien le sont d'une manière qui rend le remède pire que le mal (beaucoup de programmeurs ne connaissent de la sécurité que de vagues notions et des légendes entendues et jamais contestées).
L'introduction (section 1) note qu'IPv4 avait été conçu dans un environnement très différent de ce qu'il est aujourd'hui. Toutefois, elle ne reprend pas l'idée courante mais fausse comme quoi les failles de sécurité d'IPv4 découleraient d'une vision optimiste et naïve de la nature humaine, d'une époque où seuls des bisounours utilisaient l'Internet et où il n'était donc pas nécessaire de prévoir des mécanismes de sécurité. En réalité, même si on refaisait l'Internet aujourd'hui en partant de zéro, une bonne partie des problèmes se poserait de la même façon : sécuriser un réseau multi-organisations et multi-national n'est pas de la tarte, que ce soit aujourd'hui, ou bien il y a vingt-cinq ans ! Quoi qu'il en soit, l'Internet est aujourd'hui une ressource critique, dont dépendent bien des choses dans le monde. Sa sécurité est donc un enjeu majeur.
À propos de légendes, le RFC prend position sur le récit « Internet a été conçu pour résister à une attaque nucléaire » en estimant que ce n'est pas exact, que la principale motivation n'était pas de fournir un système de communications invulnérable aux militaires, mais de partager l'accès à des mainframes (voir l'article de D. Clark, « The Design Philosophy of the DARPA Internet Protocols », Computer Communication Review Vol. 18, No. 4, 1988).
Les problèmes de sécurité découverts depuis ont parfois affecté une mise en œuvre particulière (c'est une loi générale du logiciel : « il y a des bogues ») et parfois les concepts de base du protocole, rendant bien plus difficile la solution. La bibliographie du RFC donne une idée des problèmes les plus importants.
Comme il n'est pas réaliste de couvrir tous les problèmes de sécurité de l'Internet, ce RFC se focalise (section 1.2) sur ceux d'IP lui-même, excluant les protocoles de transport comme TCP ainsi que les protocoles de routage comme BGP ou ceux de démarrage comme DHCP. Les RFC cruciaux pour cette évaluation de la sécurité sont donc :
La section 2 du RFC rappelle les concepts de base d'IP, inchangés depuis ses débuts (et parfois depuis l'époque d'Arpanet). Reprenant l'article fondateur de Clark cité plus haut, il cite les trois principes essentiels :
Maintenant, allons-y, avec deux longues sections, dont je ne transmets ici qu'une partie : la section 3 examine un par un les champs de l'en-tête du paquet IP et les différentes façons dont ils peuvent impacter la sécurité. La section 4 examine les différents mécanismes de traitement de paquets IP et ce qui peut en résulter.
La section 3 commence par rappeler le schéma du RFC 791 décrivant tous les champs qu'on trouve dans l'en-tête d'un paquet
IP. En théorie, tous les paquets doivent obéir à certains invariants,
le premier cité par le RFC étant que la taille du paquet doit être
d'au moins vingt octets (la taille minimale d'un en-tête et donc d'un
paquet). Mais, comme l'a observé toute personne qui a analysé du
trafic réseau avec des dissecteurs mal écrits, on
trouve de tout sur l'Internet et notamment plein de paquets mal
formés. Notre RFC 6274 donne donc à chaque fois des
conseils de tests de santé à faire sur chaque paquet avant de le
traiter. Le premier test est donc longueur(paquet) >= 20
. À
chaque fois, si le test échoue, le paquet devrait être abandonné et un
compteur de problèmes incrémenté. Allons-y maintenant pour les autres
tests (oui, cela va être long), dans l'ordre des champs.
L'en-tête a un champ Version qui, pour IPv4, doit valoir... 4
(section 3.1). En théorie, on peut imaginer des techniques de
couche 2 où les paquets de différentes versions
d'IP soient démultiplexés par ce champ (une telle technique existe
dans la section 3.2 du RFC 6214, publié le premier avril
2011). En pratique toutefois, tous les
réseaux existants fournissent un autre moyen de démultiplexer (par
exemple le champ EtherType
dans
Ethernet, qui vaut 0x0800 pour IPv4 et 0x86DD
pour IPv6) et donc, une fois le paquet reçu par l'implémentation IPv4,
le champ Version doit donc forcément valoir 4 et il faut vérifier cela. Oublier ce test
permettrait certaines attaques où un méchant mettrait une autre
valeur pour exploiter le fait que certains équipements
accepteraient le paquet et d'autres (avec un peu de chance, les
IDS) l'ignoreraient.
Champ suivant, IHL (Internet Header Length), la
longueur de l'en-tête du paquet IP (contrairement à
IPv6, celle-ci n'est pas constante, en
raison de la présence possible d'options). Comme elle est exprimée en
nombre de mots de quatre octets, le test de longueur minimale est
cette fois
longueur(en-tête) >= 5
. Comme l'en-tête est
forcément plus petit que le paquet, on doit aussi vérifier
longueur(en-tête) * 4 <= longueur(paquet)
. Ces
tests peuvent sembler un peu bêtes mais il y a déjà eu des attaques
jouant sur des longueurs bizarres, pour forcer une implémentation à
lire des zones mémoire où elle n'aurait pas dû aller. Là encore, en
cas d'échec des tests, abandon du paquet et incrémentation du compteur
des paquets invalides.
Tout est évidemment plus compliqué lorsqu'un champ a changé de sémantique, ce qui est le cas de l'ancien ToS (Type of Service) devenu DSCP avec le RFC 2474 (section 3.3). Normalement, toutes les mises en œuvre d'IP devraient traiter ce champ selon la nouvelle définition mais cela ne semble pas être le cas. Donc, une application peut mettre une valeur qui semblera inoffensive si elle est interprétée comme ToS mais lui donnera une priorité si cette même valeur est interprétée comme DSCP. Une protection possible est d'effacer ce champ lorsqu'un paquet arrive dans un domaine administratif (la qualité de service différenciée n'a de toute façon de sens qu'à l'intérieur d'un même domaine, au sein d'une même entreprise, par exemple).
Les bonnes intentions faisant parfois les belles failles de sécurité, la section 3.3.2.2 est consacrée à ECN (RFC 3168), une technique de lutte contre la congestion, qui peut dans certains cas être exploitée contre la sécurité (par exemple en faisant croire qu'on gère la congestion par cette technique, même si ce n'est pas vrai, simplement pour diminuer la probabilité de voir ses paquets jetés par les routeurs).
On a déjà parlé de longueur, de celle indiquée par la couche 2, de celle indiquée par le champ IHL pour indiquer la longueur de l'en-tête... Il y a aussi un champ Total Length qui indique la longueur du paquet (en-tête compris). Quels sont les pièges de sécurité liés à ce champ (section 3.4) ? D'abord, ce champ pouvant indiquer des tailles jusqu'à 65535 octets, les mises en œuvre d'IP doivent préparer des tampons d'entrée/sortie assez grands pour cela. Normalement, les correspondants ne doivent pas envoyer de paquets de plus de 576 octets avant qu'on leur ai signalé qu'on pouvait traiter plus (par exemple par le biais de l'option MSS de TCP, ou par l'EDNS du DNS). Mais il existe certains cas où les autres machines envoient des paquets plus grands sans prévenir (cas de NFS) et, de toute façon, un attaquant ne suivra pas forcément les règles.
Plus rigolo, un attaquant peut transmettre un paquet plus grand que la taille indiquée dans le champ Longueur, par exemple dans l'espoir d'obtenir un débordement de tampon. Si la couche 2 lui permet, il peut même envoyer des paquets plus grands que 65535 octets. Ce genre de paquets se trouve réellement dans la nature et peuvent être le résultat d'une programmation maladroite, ou bien d'une tentative d'attaque (comme celle citée en « US-CERT Vulnerability Note VU#310387: Cisco IOS discloses fragments of previous packets when Express Forwarding is enabled »). Le récepteur doit donc être paranoïaque. Allouer un tampon de la taille indiquée par le champ Longueur, puis y copier le paquet sans vérification serait très imprudent. Il faut utiliser au contraire la taille indiquée par la couche 2.
Le champ suivant la longueur, ID, identifie le fragment (section 3.5), pour permettre le réassemblage en cas de fragmentation. Sur certains systèmes, la façon dont est choisie ce nombre peut révéler bien des choses sur l'emetteur (voir « Idle scanning and related IP ID games »). Sur les systèmes anciens, l'ID était unique par paquet, choisi de manière incrémentale et donnait donc au récepteur une indication, par exemple sur le nombre de machines derrière un routeur NAT. Comment peut-on limiter ces risques de fuite d'information ? Une des solutions est de mettre le champ ID à zéro pour tout paquet qui a le bit DF (Don't Fragment). Ces paquets ne pouvant être fragmentés, le fait d'avoir tous le même ID n'est pas gênant. Linux a été le premier à faire cela. Mais certains équipements mal conçus (les affreuses middleboxes) fragmentaient quand même ces paquets, qu'on ne pouvait plus réassembler. Depuis, Linux (et Solaris) mettent un ID fixe, mais différent pour chaque adresse, ce qui limite les fuites d'information. En effet, l'ID n'a pas besoin d'être unique par machine, il suffit qu'il soit unique par tuple {source, destination, protocole}. Le mieux serait donc de générer aléatoirement (pour empêcher les fuites d'information) un ID unique par « session » pour chaque tuple. Attention à bien lire le RFC 4086 avant de choisir son générateur aléatoire. Ce problème de choix entre un identificateur prévisible (qui est donc indiscret) et un identificateur aléatoire (qui risque donc d'être réutilisé plus vite) est très proche de celui du choix du port source décrit dans le RFC 6056.
Le cas est plus complexe pour les protocoles sans connexion comme UDP (utilisé notamment pour le DNS qui, depuis le déploiement de DNSSEC, a plus souvent des paquets fragmentés). Dans certains cas, des paquets corrompus risquent d'être réassemblés et les protections des couches supérieures risquent de ne pas être suffisantes pour détecter cette corruption (pour le DNS, il faut au moins activer la somme de contrôle UDP, ce qui limite les risques).
Passons maintenant au champ Flags de l'en-tête (section 3.6). Il contient trois bits dont deux sont définis : DF (Don't Fragment) et MF (More Fragments). De manière amusante, le bit DF peut être utilisé pour empêcher la détection par un IDS. Si l'attaquant sait que, après l'IDS, la MTU baisse, il peut envoyer des paquets ayant le bit DF dont certains sont trop gros pour cette MTU. L'IDS va les lire mais la machine de destination ne les verra jamais, puisqu'ils ont été jetés par le routeur précédent (qui n'avait pas le droit de les fragmenter). L'IDS et la machine de destination verront alors des données différentes, ce qui peut permettre de rendre indétectable une charge utile malveillante. Si ce cas semble extrêmement tordu (depuis quand met-on des tunnels après les IDS ?), il faut préciser qu'il existe des variantes de cette attaque, basées sur les bogues de certains logiciels (par exemple qui jettent les paquets ayant à la fois MF et DF, alors que ces paquets peuvent atteindre la destination), qui permettent d'obtenir le même résultat.
Juste après, un autre champ lié au réassemblage, le champ Fragment Offset (section 3.7). Si certaines des attaques décrites dans ce RFC peuvent sembler purement théoriques, celles portant sur des jeux avec l'algorithme de réassemblage des fragments sont très courantes en pratique. Ce champ indique la position du fragment dans le datagramme original et les valeurs bizarres de ce champ sont fréquentes dans la nature. Par exemple, un fragment peut prétendre être situé plus loin que le 65535ème octet du paquet original (le champ est assez grand pour cela, on peut aller jusqu'à 131043 octets), ce qui peut mener à des débordements de tampon au cours du réassemblage. Cela a déjà été utilisé par exemple dans l'attaque nommée (bien à tort) ping of death (« CERT Advisory CA-1996-26: Denial-of-Service Attack via ping » et « The Ping of Death Page » en 1996. Cette attaque est très mal nommée parce qu'elle n'a rien à voir avec ping, ni même avec ICMP. un paquet IP de n'importe quel protocole peut convenir. Si vous faites un interview d'un candidat à un poste d'administrateur réseaux, c'est une bonne question à poser : « faut-il filtrer ICMP sur le pare-feu ? ». S'il répond « oui, à cause du ping of death », vous savez qu'il n'y connait pas grand'chose en sécurité des réseaux.
Et le bon vieux champ TTL (Time To Live, section 3.8), pose-t-il aussi des problèmes de sécurité ? Oui. Il peut transmettre de l'information (type de système d'exploitation à la source, puisque la valeur par défaut du TTL peut en dépendre, distance de la source, d'après la diminution observée, etc). Son rôle dans la découverte de la topologie du réseau est bien connu puisqu'elle est utilisée par l'outil traceroute (qui lance des paquets de TTL croissant, pour repérer les routeurs qui reçoivent un paquet de TTL nul et refusent donc de le transmettre).
Il peut, comme dans le cas de DF, être utilisé pour faire en sorte qu'un IDS et la machine de destination ne voient pas la même chose, par exemple en mettant un TTL plus bas aux paquets destinés seulement à l'IDS. S'il y a un routeur après l'IDS, ces paquets ne seront pas vus par la machine cible. L'outil Scrub d'OpenBSD peut aider contre cette attaque.
Mais le TTL a aussi des usages positifs en terme de sécurité. Par exemple, mis à la valeur maximale (255), il peut permettre de s'assurer qu'un paquet vient bien du réseau local, en vérifiant que le TTL est bien 255 à l'arrivée (cette technique est décrite en détail dans le RFC 5082).
Le champ suivant le TTL indique le protocole utilisé par les couches supérieures (UDP, TCP, SCTP, etc). Il n'a rien de dangereux mais certaines attaques dans le passé utilisaient ce champ avec des implémentations boguées (section 3.9).
Ensuite vient la somme de contrôle de l'en-tête. Là encore, on peut s'en servir pour échapper à certains contrôles faits par des équipements qui ne testent pas cette somme. En mettant délibérement une valeur invalide, on crée un paquet qui sera vu par certaines machines et pas par d'autres, trompant ainsi les IDS.
Puis viennent les adresses IP, les deux champs suivants, qui indiquent respectivement les adresses source et destination (section 3.11 et 3.12). Normalement, tout le monde connait leur principale faiblesse en matière de sécurité : elles ne sont pas authentifiées et l'émetteur du paquet (ou un intermédiaire) peut mettre ce qu'il veut, surtout dans la source. Les adresses identifient normalement une interface réseau (la notion d'« adresse IP d'une machine » n'existe pas en IP). Sauf que rien n'empêche de mettre ce qu'on veut. (Un rappel au passage : le logiciel le plus souple et le plus facile d'usage pour fabriquer de faux paquets, en bricolant les champs qu'on veut, est Scapy. Utilisez-le, vous en serez content.) Normalement, un filtrage est réalisé par le réseau d'accès (RFC 2827 et RFC 3704, mais aussi « NISCC Technical Note 01/2006: Egress and Ingress Filtering ») pour empêcher les mensonges les plus éhontés de sortir sur l'Internet mais, en pratique, très peu de fournisseurs d'accès font ce test. (Le Spoofer Project mesure ce pourcentage.) Une autre technique de protection est la surveillance des adresses utilisées sur le réseau local, par exemple avec arpwatch.
On a donc vu d'innombrables attaques où les adresses IP source des attaquants étaient fausses. Le RFC fournit quelques exemples comme « CERT Advisory CA-1996-01: UDP Port Denial-of-Service Attack », « CERT Advisory CA-1996-21: TCP SYN Flooding and IP Spoofing Attacks » ou « CERT Advisory CA-1998-01: Smurf IP Denial-of- Service Attacks ».
Cette absence d'authentification des adresses IP se retrouve à d'autres endroits que l'en-tête IP, par exemple, dans les paquets ICMP qui sont censés transporter une partie du paquet original : rien n'indique que cette information soit fiable (RFC 5927).
Conséquence pratique, il ne faut surtout pas authentifier une machine sur la seule base de l'adresse IP qu'elle présente. Par exemple, dans le cas d'une dDoS, on voit parfois des administrateurs réseaux naïfs croire qu'ils ont découvert l'origine de l'attaque lorsqu'ils ont fait un whois sur l'adresse IP source, sans penser une seconde qu'elle puisse être trompeuse...
À noter que le RFC ne rappelle pas qu'on peut « authentfier » une adresse IP si le protocole de transport impose des aller-retours, ce qui est en général le cas avec TCP (si les numéros de séquence initiaux sont bien choisis au hasard, l'attaquant doit recevoir ou voir passer les paquets de réponse, pour arriver à établir une connexion).
IPv4 a ensuite un champ Options, le dernier du paquet. Il est de taille variable car les options sont... optionnelles (section 3.13). Bien que plusieurs options aient été normalisées, elles sont très peu utilisées en pratique, en partie parce qu'elles ne passent pas partout, en partie parce que leur présence peut ralentir sérieusement le paquet (beaucoup de routeurs traitent le paquet « normal » en ASIC et transmettent les paquets ayant des options au processeur principal, bien plus lent : cela peut être exploité pour DoSer le routeur en envoyant plein de paquets avec options).
Les options étant de taille variable (le curieux lira avec
amusement la section 3.1 du RFC 791, qui
explique les deux méthodes d'encodage d'une option), il y a une
nouvelle possibilité d'attaque par débordement de tampon, si l'indication de la longueur de
l'option est fausse. Là encore, quelques tests sont indispensables,
les options du cas 2 ont une longueur d'au moins deux octets
(option-length >= 2
), et cette longueur ne
doit pas nous mener en dehors du paquet (option-offset +
option-length <= IHL * 4
). Si vous êtes étudiant, faites
attention : écrire un analyseur de paquets IP est un
TP classique et le professeur sadique risque
fort d'envoyer à votre analyseur des paquets délibérement mal formés
pour vous prendre en défaut.
Autre piège pour le code d'analyse, les types utilisés : certaines options ont des pointeurs, stockés sur un octet, et le RFC 791 ne précise pas si cet octet est signé ou non. Si on ne fait pas attention, on peut se retrouver avec des pointeurs négatifs.
Ça, c'était le problème des options en général. Après, certaines options spécifiques ont leurs propres problèmes de sécurité. LSSR (Loose Source and Record Route, option de numéro 13) permet de contourner le routage et donc certaines règles des pare-feux, permet de joindre des machines normalement injoignables (par exemple si elles ont une adresse IP privée et sont derrière un routeur NAT), etc. Ces risques sont tels, par rapport aux bénéfices de cette option, que notre RFC 6274 recommandent de jeter sans autre forme de procès tous les paquets ayant cette option, dans la configuration par défaut des équipements. Un exemple d'attaque contre OpenBSD est décrit dans « OpenBSD Security Advisory: IP Source Routing Problem ». Mêmes remarques, et même recommandation pour l'option SSSR (Strict Source and Record Source, numéro 137). Cette option a déjà été utilisé pour des attaques (par exemple « Microsoft Security Program: Microsoft Security Bulletin (MS99-038). Patch Available for "Spoofed Route Pointer" Vulnerability" ».
L'option Record Route (section 3.13.2.5) est encore pire puisque le routeur doit alors écrire dans le paquet lui-même. Comme avec les deux précédentes, il est vital de vérifier que les pointeurs ne pointent pas n'importe où. (Le problème touche d'autres protocoles qu'IP ; par exemple, lors du dévelopement de DNSmezzo ou de grong, j'ai pu constater que les pointeurs utilisés dans la compression des paquets DNS sont souvent invalides et ne doivent pas être suivis aveuglément.) En outre, cette option est indiscrète, puisqu'elle permet de réveler les routeurs par lesquels est passé un paquet. La taille très limitée du champ Options limite ce risque (on ne peut pas stocker plus de quelques routeurs) et rend cette option peu utile.
Un grand nombre de ces options peuvent être considérées comme n'étant que d'un intérêt historique (mais le code pour les traiter est parfois toujours là dans la pile IP et peut provoquer des problèmes de sécurité). C'est le cas de Timestamp (numéro 68, section 3.13.2.7), qui indique au routeur de marquer l'heure de passage du paquet dans le paquet. Comme Record Route, elle est indiscrète et devrait donc être ignorée par défaut. Comme Record Route, elle entraine une écriture dans le paquet, à l'endroit indiqué par un pointeur et il faut donc, si on a activé cette option, vérifier le pointeur.
Je passe sur un certain nombre d'options pittoresques pour arriver à DoD Basic security Option (numéro 130). Cette option militaire, normalisée dans le RFC 1108, indique le niveau de sécurité du paquet (« confidentiel », « secret », « très secret », etc). Contrairement à la plupart des options IPv4, elle est largement mise en œuvre et déployée. Par exemple, SELinux, Cisco IOS et Solaris l'ont et beaucoup de réseaux comptent dessus. Elle a même inspiré un équivalent IPv6, décrit dans le RFC 5570.
Après cette longue liste des champs de l'en-tête IP, la section 4 de notre RFC 6274 s'attaque aux mécanismes actifs de traitement des paquets. De nouvelles failles se cachent là. Les principales touchent le processus de fragmentation et réassemblage (section 4.1). Lorsqu'un paquet IPv4 est trop gros pour le lien qu'il va emprunter, l'émetteur, ou bien le routeur intermédiaire, fragmentent ce paquet en paquets plus petits. La machine de destination (pas les routeurs) va devoir réassembler un paquet entier. Historiquement, ce processus est à l'origine de très nombreuses failles de sécurité. En effet, le réassemblage est une opération très complexe et qui était mal normalisée. C'est une opération qui nécessite de maintenir un état (dans un protocole, IP, qui est normalement sans état), le réassembleur ne connait pas les caractéristiques du chemin suivi par les paquets et ne sait donc pas combien de temps il peut attendre des fragments manquants, et les fragments peuvent arriver dans le désordre.
Quelles sont les conséquences de sécurité de la fragmentation ? D'abord, l'allocation mémoire : la machine de destination ne sait pas combien de temps elle doit attendre les fragments manquants. Elle doit donc réserver un espace mémoire pour le paquet et le garder jusqu'à être sûr que les fragments manquants n'arriveront jamais. Le RFC 1122 conseille de rester ainsi pendant 60 à 120 secondes, ce qui est très long si on reçoit beaucoup de paquets et peut mener à un épuisement de la mémoire si un attaquant génère des paquets fragmentés et délibérement incomplets. C'est encore pire si on suit le conseil du RFC 815 qui est d'allouer de la mémoire suffisante pour le plus grand paquet possible (la taille du paquet n'est connue qu'avec le dernier fragment).
Autre problème, le champ ID et sa taille limitée : sur un lien à 1 Gb/s, un flot continu de paquets IP de 1 kb (ce qui peut arriver avec de la vidéo en temps réel), chacun fragmenté en deux, va mener à une réutilisation du champ ID en moyenne au bout de 0,65 secondes seulement. Il y aura donc collision entre les fragments de deux paquets différents et le réassemblage mènera à la corruption (dont on espère qu'elle sera détectée par les protocoles des couches supérieures). Si des paquets sont injectés par un attaquant, il peut ainsi facilement créer une DoS.
Certains des problèmes de sécurité des fragments proviennent d'erreurs ou d'ambiguités dans la spécification. Ainsi, il est possible d'avoir des fragments qui se recouvrent (un fragment va de l'octet 0 à l'octet 959 inclus, un autre fragment de 1200 à 1919 inclus et encore un autre fragment va de 960 à 1279. Pour les octets de 1200 à 1279, doit-on utiliser le deuxième ou le troisième fragment ? Différents mises en œuvre d'IP ont fait des choix différents et ce point a été exploité par des outils qui fragmentent le paquet afin qu'il échappe à l'IDS (en utilisant le fait que l'IDS et la machine de destination n'utiliseront pas la même stratégie.) Un exemple d'un tel outil est Frag.
La section 4.1.2 rassemble un ensemble de conseils sur la fragmentation. S'ils étaient appliqués, IP serait plus sûr :
Le RFC 1858 et son successeur RFC 3128 fournissent des détails sur ces points.
Autre grande question, la transmission des paquets IP par un routeur (section 4.2). Par définition, un routeur reçoit des paquets qui ne lui sont pas destinés et qu'il doit transmettre. Cela peut soulever des problèmes de sécurité. Par exemple (section 4.2.3) , si un routeur doit faire une requête ARP (RFC 826) pour trouver l'adresse MAC de la machine suivante, et qu'il garde le paquet à transmettre en attendant la fin de la résolution ARP, un attaquant peut épuiser les ressources du routeur en envoyant plein de paquets vers des destinations inexistantes. Il est donc suggéré de jeter immédiatement les paquets lorsqu'une résolution ARP est nécessaire, en espérant que l'émetteur les renverra, s'ils étaient importants.
Enfin, l'adressage IP peut aussi recéler des pièges (section
4.3). Ainsi, un préfixe est réservé à des fins expérimentales, le
240/4
(ancienne « classe E », section 4.3.4). Le
RFC, suivant
une vieille pratique, recommande de jeter sans hésitation les paquets
dont l'adresse source est dans ce bloc. Ce conseil est d'ores et déjà
largement suivi, et est la raison pour laquelle on ne peut pas espérer
récupérer ces nombreuses adresses IPv4 pour faire face à l'épuisement.
Voilà, et on n'a couvert qu'IP et pas les autres protocoles de la famille. Reste maintenant à faire le même travail pour IPv6. Qui s'y colle ?
Si cette lecture peut donner l'impression qu'IPv4 est une incroyable erreur de sécurité, bourrée de vulnérabilités, il faut aussi se rappeler, comme l'analyse le RFC 5218, que ce sont certains raccourcis pris par IP qui ont permis ce succès. Aujourd'hui, il est certain qu'IPv4 ne serait pas accepté par l'IESG et c'est pourtant le protocole qui a fait décoller l'Internet.
À noter que ce RFC est très largement inspiré du rapport « Security Assessment of the Internet Protocol », du Centre for the Protection of National Infrastructure (CPNI) britannique. D'autre part, la bibliographie du RFC est recommandée, c'est un rappel de toutes les fameuses failles de sécurité d'IP.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : F. Baker, D. Meyer (Cisco Systems)
Pour information
Première rédaction de cet article le 22 juin 2011
Le titre de ce RFC ne rend pas complèment compte de son but. Ce document est en fait une présentation complète de la suite de protocoles TCP/IP, celle qui fait tourner l'Internet. Conçu pour des ingénieurs qui viennent d'une autre culture que celle des barbus Unix, récapitulant tout ce qu'il faut savoir sur les protocoles de la famille, ce texte est utilisable comme base d'un cours, ou comme introduction à TCP/IP. Il a été conçu pour le projet Smart Grid.
En effet, ce projet de distribution de l'électricité en faisant appel à des équipements plus proches des ordinateurs que des traditionnels transformateurs et compteurs, équipements qui communiqueraient beaucoup entre eux, cherche une architecture réseau. Un certain nombre de consultants, souvent ignorants de ce qui s'est fait depuis trente ans sur l'Internet, prône le développement en partant de zéro de nouvelles techniques, non prouvées et coûteuses à créer, alors que TCP/IP fournit déjà tout ce qu'il faut. Ce RFC explique TCP/IP pour les débutants, et fournit une liste des protocoles, dont peut être tirée un futur profil Smart Grid (un profil étant un sous-ensemble adapté à une tâche donnée). Voir la section 1 à ce sujet.
Comme je ne connais pas assez Smart Grid, et que le RFC ne contient quasiment rien de spécifique à ce projet (l'annexe A rassemble les informations purement Smart Grid), je vais adopter une autre perspective en utilisant ce RFC comme moyen de présenter les protocoles d'Internet, à un ingénieur qui ne les connaîtrait pas. Ces protocoles sont désignés dans le RFC sous le nom d'IPS, Internet Protocol Suite. À partir d'ici, si vous connaissez déjà l'IPS, vous avez le droit de partir et d'aller voir un film (par exemple Le chat du rabbin) ou de lire un livre (par exemple Le chat du rabbin).
L'IPS est décrite dans les fameux RFC. Outre la normalisation des protocoles, certains RFC sont là pour décrire l'implémentation par exemple les RFC 1122 et RFC 1123 sur les machines terminales et le RFC 1812 sur les routeurs. (Avec une version des spécificités IPv6 dans le RFC 8504.) Une des particularités de l'IPS est qu'elle offre des choix : ainsi, il existe plusieurs protocoles de transport comme TCP (RFC 793) ou SCTP (RFC 9260) et même un « non-protocole », UDP (RFC 768), où l'application doit faire tout le travail de la couche 4. La section 2 de ce RFC va présenter l'architecture de l'IPS, la section 3 une liste de protocoles et la section 4 l'organisation non-technique de l'Internet (relations d'affaires, etc).
Donc, c'est parti, comment tous ces protocoles tiennent-ils ensemble ? L'Internet Protocol Suite suit la classique organisation en couches (section 2.1). Si le principe est celui du modèle OSI, le découpage des couches n'est pas forcément le même, ni la terminologie. Ainsi, l'OSI parle (en anglais) de end system lorsque l'IPS dit host (que je traduis par machine terminale) et l'OSI dit intermediate system où l'IPS dit router.
En partant du haut, de ce qui est le plus proche des utilisateurs, on trouve la couche Applications (section 2.1.1). L'IPS ne fait pas de distinction forte entre les couches 5, 6 et 7, considérant plutôt une seule couche Applications.
Ensuite, toujours en allant vers le bas, l'IPS a une couche de Transport (section 2.1.2). Le terme de transport est très galvaudé. Énormément d'ingénieurs l'utilisent pour dire « les couches du dessous qui ne m'intéressent pas ». Un concepteur d'un réseau optique va parler du transport pour la fibre sous-jacente, alors que le développeur d'une application Web va considérer que le protocole HTTP est le transport, pour son application. Mais dans l'IPS, « transport » a un sens bien précis, c'est la plus basse couche qui va de bout en bout. Des protocoles archi-connus comme TCP (RFC 793) ou très exotiques comme NORM (RFC 5740) mettent en œuvre ce transport. Comme plusieurs flots de données simultanés peuvent exister entre deux adresses IP, le démultiplexage se fait sur la base d'un numéro de port géré par la couche transport. Deux flots différentes auront ainsi des couples {port source, port destination} différents. Les différents protocoles de transport fournissent en outre des services tels que garantie de délivrance des données (ou pas), gestion de messages séparés (ou bien flot d'octets continu, ce que fait TCP), contrôle de la congestion.
Continuons à descendre vers les couches bases, la couche Réseau (section 2.1.3) vient ensuite. Au contraire du choix qui existe en couche Transport, il n'y a qu'un seul protocole de couche Réseau, IP (ou deux, si on considère IPv4 et IPv6 comme différents). IP fournit un service de datagrammes : chaque paquet est indépendant des autres, porte donc les adresses IP de source et de destination, et il n'y a pas besoin d'établir un circuit avant d'envoyer des données. IP fournit également un service de fragmentation, permettant de découper un paquet trop gros avant de le réassembler à la fin.
IP peut fonctionner sur d'innombrables protocoles de couche 2. L'IETF n'en normalise aucun (à l'exception possible de MPLS, RFC 4364, tout dépend comment on place ce protocole dans le modèle en couches). La plupart du temps, ces protocoles des couches basses (section 2.1.4) sont normalisés par l'IEEE : 802.3, 802.11, 802.16, etc. IP peut aussi tourner sur IP, via des tunnels comme GRE (RFC 2784).
La famille TCP/IP a souvent été critiquée pour son manque de sécurité (section 2.2). En fait, toute la sécurité dans l'Internet ne dépend pas de TCP/IP. Le hameçonnage, par exemple, est une question d'éducation et d'interface utilisateur, deux points très importants mais qui ne sont pas du ressort de l'IETF. D'autres problèmes (comme la faille BGP dite « attribut 99 ») ne relèvent pas non plus de la sécurité du protocole puisqu'ils sont causés par une bogue dans un programme mettant en œuvre le protocole.
D'autres questions de sécurité viennent de l'organisation de l'Internet, pas de ses protocoles. Ainsi, il n'existe pas de chef de l'Internet, qui pourrait ordonner que les vieilles versions des logiciels, versions ayant des bogues connues, soient immédiatement retirées du service. On constate qu'elles traînent souvent dans la nature. De même, les nouvelles techniques de sécurité ont souvent du mal à être déployées, puisqu'aucune autorité ne peut imposer leur emploi. Il faut au contraire convaincre chaque administrateur réseaux. (Des exemples de protocole de sécurité dont le déploiement a été faible sont SPF - RFC 4408 et IPsec - RFC 4301. Un exemple d'un protocole de sécurité qui a mis très longtemps à être déployé est DNSSEC - RFC 4033.)
Cela ne veut pas dire que l'IETF baisse les bras sur la sécurité. Chaque nouveau protocole doit inclure une analyse de sécurité, et le RFC 3552 guide les auteurs pour cette tâche.
Les problèmes de sécurité de la couche physique se traitent en général par des moyens physiques (enterrer et protéger les câbles, par exemple). Pour les autres couches, le problème est posé en termes de trois services : Confidentialité, Intégrité et Disponibilité. On souhaite que les conversations privées restent privées (Confidentialité), on souhaite que les données soient authentifiées au départ, puis arrivent sans modifications (Intégrité) et on souhaite que l'Internet marche (Disponibilité). Voici deux exemples :
Dans beaucoup de cas, une première étape vers la sécurisation est la création d'un canal sûr entre la source et la destination (TLS ou IPsec le permettent.) Mais attention, ce n'est pas suffisant de sécuriser la communication, car le pair peut lui-même être malveillant, délibérement ou à son insu.
Enfin, l'infrastructure de l'Internet compte également des protocoles qui sont officiellement dans les applications mais sont en pratique nécessaires au bon fonctionnement. La section 2.3.1 mentionne le DNS, système de correspondance entre un nom de domaine et des données (typiquement des adresses IP). Bien sûr, l'Internet peut fonctionner sans le DNS. Mais, en pratique, cela serait vite insupportable (contrairement à ce qu'on lit parfois, la plupart des sites Web ne sont pas accessibles via leur adresse IP, voir section 5.4 du RFC 7230). Et la section 2.3.2 mentionne les outils de gestion de réseau comme les deux protocoles de gestion SNMP et Netconf (RFC 4741). (Dans le projet français PREMIO, SNMP est utilisé.)
La section 3 du RFC attaque ensuite les protocoles spécifiques. L'idée, là encore, est d'utiliser pour la Smart Grid des protocoles bien conçus, éprouvés, et disposant de mises en œuvre nombreuses et de qualité, souvent en logiciel libre.
Cette section commence avec la sécurité, La section 3.1 se penche d'abord sur l'AAA. Dans le contexte de l'Internet, cela concerne les protocoles qui autorisent l'accès au réseau, Radius (RFC 2865 et Diameter (RFC 6733). Ces protocoles utilisent souvent un mécanisme d'authentification nommé EAP (RFC 4017 ; opinion personnelle, EAP est d'une grande complexité), qui permet à son tour plusieurs méthodes (RFC 5216, RFC 5433).
Une fois qu'on a accès au réseau, reste à protéger les communications. Au niveau 3, une solution générale est IPsec (RFC 4301), qui « cryptographie » tout le trafic IP, fournit intégrité et authentification, aussi bien que confidentialité (IPsec est une architecture, pas un protocole, donc la liste des services peut dépendre du protocole). Pour l'échange des clés cryptographiques, cela peut se faire à la main (sans doute la technique la plus courante aujourd'hui) ou bien via le protocole IKE (RFC 5996). À noter que notre RFC 6272, bien que se voulant pratique, mentionne rarement de choix lorsque plusieurs protocoles existent. Toutefois, pour IPsec, il note que ESP (RFC 4303) est de très loin le plus utilisé et qu'on peut oublier les autres.
La sécurité peut-elle être assurée dans la couche 4 ? Oui, grâce au très connu protocole TLS (RFC 5246). TLS chiffre toute la communication de l'application. Il ne protège pas contre les attaques situées plus bas, mais est bien plus simple à déployer qu'IPsec.
Enfin, la sécurité peut être appliquée au niveau des applications, où on a le maximum de souplesse. La famille TCP/IP a plusieurs mécanismes dans sa boîte à outils pour cela :
Toujours dans la boîte à outils, la famille TCP/IP a aussi un protocole de connexion sécurisée à distance, SSH (RFC 4253), qui peut aussi servir de mécanisme pour faire des tunnels sûrs (en concurrent d'IPsec, donc).
Toute solution fondée sur la cryptographie a besoin d'un mécanisme de gestion des clés. L'IETF en a au moins deux, PKIX (RFC 5280), fondé sur X.509, et Kerberos (RFC 4120), le second étant plutôt limité au cas où tout les participants sont dans le même domaine administratif.
Après ces considérations sur la sécurité, place à la description des protocoles de couche 3. L'Internet en a actuellement deux, IPv4 et IPv6 (section 3.2). IPv4 est décrit en détail dans la section 3.2.2. Je passe rapidement, pour arriver à IPv6 en section 3.2.3. IPv6 est normalisé dans le RFC 2460. À noter que, pour le cas de la Smart Grid, dont certains équipements peuvent avoir des capacités et des connexions peu performantes, les RFC comme le RFC 4919 peuvent être également utiles.
Les adresses IPv6 sont décrites dans le RFC 4291. Elles peuvent être distribuées aux machines terminales via le protocole DHCP (RFC 8415) ou bien sans serveur par un système d'auto-configuration (RFC 4862). Deux machines IPv6 dans le même réseau se trouvent par le protocole NDP (RFC 4861).
Le routage des paquets IPv6 se fait d'abord par la distribution des informations entre routeurs, puis par l'utilisation de ces routes lors de la transmission de chaque paquet. La route la plus spécifique (le préfixe le plus long) est utilisée. Pour distribuer les routes, les routeurs peuvent utiliser divers protocoles comme OSPF (RFC 5340 et qui peut router IPv4 comme IPv6, grâce au RFC 5838) et BGP (RFC 2545). OSPF est utilisé à l'intérieur d'un domaine administratif et fait partie des protocoles « à état des liens » dont l'avantage est que chaque routeur a une vue complète du réseau (au lieu de router par « on-dits »). BGP est utilisé entre domaines administratifs et c'est donc lui qui lie les routeurs de l'Internet.
Il y a aussi des protocoles de routage spécifiques aux réseaux de capteurs, les équipements peu puissants dont je parlais plus haut. OSPF, où chaque routeur doit garder en mémoire tous les liens de tout le réseau, ne convient pas forcément pour cette tâche. Parmi les concurrents plus adaptés, on trouve par exemple AODV (RFC 3561) ou d'autres protocoles en cours de définition (voir le cahier des charges dans les RFC 5548, RFC 5673, RFC 5826 et RFC 5867).
Depuis l'épuisement des adresses IPv4, la migration vers IPv6 est nécessaire mais elle n'est pas instantanée et il faut donc gérer la coexistence entre les deux protocoles. Il existe plusieurs mécanismes pour cela mais tous ne sont pas recommandés (cf. RFC 6180). Le plus simple et le plus conseillé est la « double-pile » : le réseau et les machines ont à la fois IPv4 et IPv6, jusqu'à ce qu'on puisse éteindre la dernière adresse v4 (RFC 4213). Si on ne peut pas disposer d'une connectivité IPv6 native, l'approche recommandée est de tunneler le trafic v6 à travers l'Internet, par exemple par les techniques du RFC 5569. Enfin, si une des deux machines participant à la communication est purement v4 ou purement v6, il faut utiliser les techniques de traduction. Celles-ci recélant des pièges inattendus, le mieux est de préférer la traduction faite au niveau des applications (par des relais applicatifs). Sinon, l'IETF a normalisé un cadre général de traduction v4<-> v6 dans le RFC 6144, avec des déclinaisons dans des protocoles comme celui du RFC 6146.
Continuant à monter vers les couches hautes, la section 3.3 présente les protocoles de transport de l'IPS (Internet Protocol Suite). Le plus connu est TCP, responsable sans doute de la très grande majorité du trafic de l'Internet. TCP garantit aux applications qui l'utilisent la délivrance des octets, dans l'ordre et sans perte. Si le RFC qui le normalise date de trente ans, TCP a subi pas mal de travaux et de modifications et il vaut donc mieux commencer par lire le RFC 7414 pour tout savoir de ce protocole. Par exemple, pour la sécurité de TCP, le RFC 4987 est une bonne lecture.
Autre protocole de transport, UDP (RFC 768), un protocole minimal qui n'assure presque aucune fonction : l'application qui l'utilise doit tout prévoir, le contrôle de congestion (ne pas envoyer trop de paquets pour ne pas surcharger le réseau), la détection des pertes (et réessayer si nécessaire), etc. Le RFC 8085 guide les applications à ce sujet.
Il existe d'autres protocoles de transport qui n'ont guère eu de succès comme SCTP (RFC 9260) ou DCCP (RFC 4340), une sorte d'UDP avec contrôle de congestion.
Pour les protocoles d'infrastructure, la section 3.4 mentionne :
www.example.com
est un
sous-domaine de example.com
, lui-même
sous-domaine de .com
) et un
protocole de résolution de noms en données (RFC 1034). Il existe un mécanisme de sécurisation, décrit par le
RFC 4033.Et la gestion de réseaux (section 3.5) ? Les deux protocoles concurrents sont SNMP (RFC 3411 et RFC 3418) et Netconf (RFC 4741). Lequel choisir ? Notre RFC 6272 ne fournit pas d'indications à ce sujet... La seule information de comparaison donnée est que SNMP utilise l'encodage ASN.1 alors que Netconf utilise XML.
Une machine qui démarre a souvent besoin d'informations sur son environnement, par exemple les coordonnées d'une imprimante ou bien d'un serveur de courrier. C'est le domaine des protocoles de découverte (section 3.6). C'est depuis longtemps une faiblesse de la famille TCP/IP. Le problème n'est pas complètement résolu de manière standard. Le RFC cite un protocole comme SLP (RFC 2608, qui n'a jamais été très utilisé) ou comme le protocole d'Apple, Bonjour. D'autres protocoles sont en cours de déploiement comme COAP (Constrained Application Protocol, RFC 7252), qui utilise HTTP pour demander à un serveur ces informations, en utilisant les adresses « bien connues » du RFC 8615.
Enfin, le RFC 6272 cite également (section 3.7) un certain nombre d'applications, qui ne font pas partie de l'IPS à proprement parler, mais qui peuvent être utiles à des déploiements sur TCP/IP. Par exemple, la famille TCP/IP a un protocole standard d'établissement de sessions multimédia, SIP (RFC 3261 et beaucoup d'autres). SIP est surtout utilisé pour la téléphonie sur IP mais a d'autres usages. SIP ne fait que la signalisation (appeler, raccrocher, etc) et la description de la session (voix, vidéo, codecs utilisés, est faite avec le format SDP (RFC 4566). En pratique, SIP a pas mal de problèmes sur l'Internet, face à la fermeture croissante du réseau par des mécanismes comme le NAT (le RFC 2993 décrit le problème et le RFC 5626 propose des solutions).
Autre application qui peut servir, XMPP (RFC 6120), un protocole d'échange de données XML en temps réel dont l'utilisation la plus connue est pour la messagerie instantanée (RFC 6121). XMPP est très riche et dispose de nombreuses extensions (par exemple pour du dialogue à plusieurs, dans des « pièces » virtuelles).
Après cette longue présentation des différents protocoles de la famille, le RFC expose l'architecture non-technique de l'Internet, c'est-à-dire son organisation sociale. Rien de nouveau pour les professionnels de l'Internet mais rappelez-vous que ce RFC est conçu pour des gens d'une culture très différente. La section 4 explique donc que l'Internet est un réseau de réseaux (c'est en cela que son ancêtre, l'Arpanet, était très différent : il était mono-réseau). Ces réseaux s'interconnectent entre eux (sinon, un abonné d'un réseau ne pourrait pas joindre un abonné d'un autre, ce qui était courant avec les technologies pré-Internet). Cette interconnexion est le cœur de l'architecture sociale de l'Internet dont le but est que tout le monde puisse parler à tout le monde (note personnelle au passage : cette interconnexion généralisée semble une banalité aujourd'hui. Mais, dans les années 1990, il était fréquent d'entendre des messieurs sérieux expliquer qu'il n'était pas nécessaire qu'une entreprise doive se connecter à d'autres que ses sous-traitants.)
On peut présenter les différents réseaux qui composent l'Internet en disant qu'il y a une différence entre les réseaux de transit et les autres. Les réseaux de transit forment le cœur de l'Internet. Leur seule activité est de connecter les autres réseaux. Ils vendent ce service aux réseaux d'accès et réseaux d'organisations. Les réseaux d'accès sont ceux du FAI typique, qui connecte M. Toutlemonde (particuliers et petites organisations) moyennant un paiement de trente € par mois. L'accès se fait via ADSL, RTC, 3G ou bien d'autres techniques. Les réseaux d'organisation sont ceux des entreprises, associations, collectivités locales ou universités, qui fournissent de l'accès à leurs employés et étudiants.
Si je fais de chez moi (abonné à Free) un traceroute vers ce blog, je passe successivement par le réseau d'accès du groupe Iliad (Free et Proxad), puis par le réseau de transit Cogent, puis j'arrive chez Datotel, le réseau d'entreprise où le serveur est hébergé :
% traceroute www.bortzmeyer.org traceroute to www.bortzmeyer.org (208.75.84.80), 30 hops max, 60 byte packets 1 freebox (192.168.2.254) 5.984 ms 7.027 ms 7.068 ms ... 4 cha75-6k-1-v906.intf.nra.proxad.net (78.254.255.197) 35.671 ms 35.726 ms 35.766 ms 5 bzn-crs16-1-be1502.intf.routers.proxad.net (212.27.58.65) 35.806 ms 37.060 ms 37.125 ms 6 bzn-6k-2-po57.intf.routers.proxad.net (212.27.59.217) 38.222 ms * * 7 th2-crs16-1-be1005.intf.routers.proxad.net (212.27.56.5) 39.893 ms 23.638 ms * 8 te4-8.330.ccr01.par04.atlas.cogentco.com (149.6.164.221) 44.829 ms 45.136 ms 49.465 ms 9 te0-1-0-4.mpd21.par01.atlas.cogentco.com (130.117.2.77) 55.562 ms 53.303 ms 54.986 ms ... 16 host46.datotel.com (208.82.151.46) 127.897 ms 127.465 ms 127.109 ms 17 stl-d2-g5-1.datotel.com (208.82.151.26) 128.295 ms 126.546 ms 127.575 ms 18 host125.datotel.com (208.75.82.125) 127.461 ms * * ...
(Les étoiles représentent des cas où un paquet a été perdu.) Notez que le routeur chez moi, la Freebox, avait une adresse privée (RFC 1918).
Le RFC ne parle pas des relations de peering entre réseaux. À ce sujet, un très intéressant document est le rapport de PCH.
À noter que le RFC n'expose que l'architecture sociale, pas la gouvernance de l'Internet, vaste sujet mais fort loin des problèmes opérationnels...
Souvent, les traceroutes sont interrompus subitement et plus rien n'est visible. C'est souvent le résultat d'un pare-feu mis sur le trajet. Notre RFC note que ces équipements sont très fréquents dans l'Internet d'aujourd'hui, mais aussi qu'ils sont très controversés. En effet, leur efficacité n'est pas prouvée, la plupart des attaques provenant de l'intérieur (soit parce qu'une personne située dans l'organisation mène l'attaque, soit parce qu'une machine interne a été infectée par un logiciel malveillant, le pare-feu ne protégeant souvent pas contre les attaques par « charge utile »). Bref, le pare-feu ne doit être utilisé que comme composante d'une solution de sécurité, pas comme l'alpha et l'oméga de la sécurité. Il existe plusieurs RFC ayant un rapport avec les pare-feux comme le RFC 2647 (mesures de performance), RFC 2979 (règles que doivent suivre les pare-feux), RFC 5207 (un exemple des problèmes que peuvent poser les pare-feux pour un nouveau protocole), etc.
Autre source de problèmes lorsqu'on circule dans l'Internet, les NAT. Cette technique a été inventée vers 1993 pour pallier le manque d'adresses IPv4 en traduisant des multiples adresses privées du réseau interne vers la seule adresse IP publique. En IPv6, le NAT est devenu inutile, vue l'abondance d'adresses. Mais comme certaines personnes s'imaginent que le NAT joue aussi un rôle pour la sécurité, en servant de pare-feu, il reste très présent et gêne souvent les communications. Les NAT sont décrits dans les RFC 2663 et RFC 3022, leurs conséquences néfastes pour les communications sont expliquées dans le RFC 3027, des idées pour les développeurs d'applications dans un monde où il y a beaucoup de NAT ont été rassemblées dans le RFC 3235, d'autres techniques de contournement sont dans le RFC 5128, quant à la position officielle de l'IAB sur les NAT, elle est dans le RFC 3424.
Sur le projet Smart Grid, si celui-ci n'a pas encore d'architecture réseau normalisée, il a déjà des documents. On peut consulter « Smart Grid Architecture Committee: Conceptual Model White Paper » (document uniquement en format privateur MS-Word, ce qui donne une idée de l'écart de culture avec l'Internet) et IEC 61850.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : M. Yevstifeyev
Chemin des normes
Première rédaction de cet article le 6 juin 2011
Ce RFC n'aura pas un grand intérêt pratique, vu le petit nombre de terminaux 3270 encore en service ! Mais il était nécessaire pour compléter la liste des plans (schemes) d'URI, qui le mentionnait sans vraiment le décrire.
En effet, le désormais dépassé RFC 1738
mentionnait la possibilité d'avoir des URL
comme tn3270:mainframe.accounting.example
mais
sans expliquer leur syntaxe ou leur sémantique. 3270 est une référence
aux vieux terminaux des
mainframes
IBM d'il y a très longtemps. Ces terminaux sont
décrits dans les RFC 1041, RFC 1576 et RFC 2355.
Le RFC 1738 a été remplacé il y a longtemps, par le RFC 3986, qui décrit la syntaxe générique des URI. Mais ce petit point
spécifique du tn3270:
n'avait jamais été traité. Notre RFC 6270 comble donc le vide en spécifiant
rigoureusement syntaxe et sémantique des URI
tn3270:
. La sémantique est très proche de celle
des URI telnet:
du RFC 4248. Le plan
tn3270:
est donc désormais, en suivant les règles
du RFC 4395, enregistré dans le registre des plans d'URI.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : M. Ford (Internet Society), M. Boucadair (France Telecom), A. Durand (Juniper Networks), P. Levis (France Telecom), P. Roberts (Internet Society)
Pour information
Réalisé dans le cadre du groupe de travail IETF intarea
Première rédaction de cet article le 29 juin 2011
Pour pas mal de raisons, il est fréquent aujourd'hui qu'une adresse IP soit partagée entre plusieurs machines. Le cas le plus typique est celui des N machines d'une petite entreprise, forcées d'utiliser une seule adresse IP publique, via un routeur NAT. Ce RFC est le premier document qui discute en détail de ce partage d'adresses, et de ses innombrables inconvénients.
Le RFC met surtout l'accent (section 1) sur une cause du partage d'adresses : l'épuisement de la réserve d'adresses IPv4, qui, n'étant pas compensée par un déploiement massif d'IPv6, mène à ce que le partage d'adresses soit très fréquent, et le sera sans doute davantage dans le futur (la plupart des solutions d'attente d'IPv6 utilisent intensivement ce partage). En fait, aujourd'hui, il est rare que M. Michu puisse bénéficier d'une vraie connexion Internet : il partage en général son adresse avec d'autres M. Michu ; par exemple, à la maison, M. Michu n'a aucune chance d'obtenir plus d'une adresse IPv4, même si plusieurs personnes vivent dans ce foyer et utilisent toutes des appareils connectés à l'Internet (ce qui est banal aujourd'hui dans les grandes villes du Nord). Le CPE fait office de routeur NAT et les machines de M. Michu et de sa petite famille sont contraintes de se contenter d'adresses IP privées (RFC 1918). Mais l'avenir (déjà réalisé en Europe sur les connexions ultra-civilisées de la 3G, et, en Asie, dès à présent sur toutes les connexions) nous réserve pire : le partage d'adresses IP, non pas au sein du foyer ou de la petite entreprise, mais entre abonnés, ce qu'on nomme parfois le CGN, pour Carrier-Grade NAT et qu'on pourrait qualifier de « partage d'adresses généralisé ». (L'annexe A résume les différents types de partage d'adresses.) Le « facteur multiplicatif » (annexe B) entre le nombre d'adresses privées et celui d'adresses publiques vaut typiquement entre 3 et 10 pour une maison européenne typique (une seule adresse publique mais plusieurs machines connectées, smartphones, ordinateurs, consoles de jeu, etc). Il pourrait dépasser 1000 avec les CGN (plusieurs adresses IP publiques mais des milliers d'abonnés se partageant ce mince gâteau).
Le RFC insiste sur le fait que le déploiement d'IPv6 est la seule solution correcte aux problèmes engendrés par le partage d'adresses. C'est vrai mais il faut noter que le partage d'adresses a commencé bien avant la famine, qu'il est pratiqué par des entreprises qui disposent de suffisamment d'adresses IPv4 (en général au nom de pseudo-arguments de « sécurité ») et qu'on le trouve pratiqué massivement en Afrique et en Asie alors que le continent africain est celui qui a la plus grande réserve d'adresses IPv4 officielles disponibles. Donc, le non-déploiement d'IPv6 n'est pas la seule raison de l'utilisation du partage d'adresses.
J'ai mentionné le NAT tout à l'heure. Si le partage d'adresses se fait en général (mais pas toujours) via le NAT, l'inverse n'est pas forcément vrai. On peut avoir du NAT sans partage d'adresses, si chaque adresse interne est mise en correspondance avec une et une seule adresse externe. Évidemment, en IPv4, c'est rare, vu le manque d'adresses, mais cela sera peut-être plus fréquent avec IPv6.
À noter que ce RFC ne discute que du problème : il ne propose pas de solution, celles-ci étant renvoyées à des documents ultérieurs (qui ne seront peut-être pas nécessaire si le déploiement d'IPv6 rend inutile ces solutions). Il ne se penche pas non plus sur les problèmes qui sont spécifiques à une technique utilisant le partage d'adresses, essayant au contraire de voir les questions communes à toutes ces techniques. Ainsi, qu'on utilise, pour gérer le passé en attendant le déploiement d'IPv6, NAT64, DS-Lite ou encore d'autres importe peu : toutes ont en commun les même défauts liés au partage d'adresses.
Des problèmes, notamment de sécurité, liés au partage d'adresses avaient déjà été discutés dans les RFC sur le NAT comme les RFC 2663 et RFC 2993 (section 2 de notre RFC). Mais le partage généralisé, entre utilisateurs n'ayant rien en commun, va aggraver ces problèmes. Cette situation se rencontre souvent aujourd'hui en Asie, et dans les hotspots WiFi publics. Mais elle sera hélas sans doute demain le lot de beaucoup d'utilisateurs.
Bien, arrivé à ce stade, vous avez le droit de penser que j'ai beaucoup répété qu'il y avait des problèmes, sans dire lesquels. Patientez encore un peu. L'analyse des problèmes qui commence en section 3 est faite en cherchant d'abord si le problème affecte l'organisation qui déploie le partage d'adresses (et donc ses abonnés ou employés), ou bien des tiers (comme la police par exemple ou bien comme un CDN qui essaie de distribuer du contenu en fonction de l'adresse). Le tout est stocké dans un grand tableau synthétique (figure n° 1) et détaillé dans les sections suivantes. Pour ne prendre que trois exemples de ce tableau, le fait que les requêtes DNS traduisant une adresse en nom perdent de leur signification affecte aussi bien l'utilisateur que les tiers (ceux qui traduisent une adresse IP entrante en nom). Par contre, la perte de traçabilité qui résulte du partage (si on détecte un comportement illégal lié à une adresse IP, on ne retrouve plus facilement la machine en cause) n'affecte que les tiers (les organisations répressives comme la HADOPI). Au contraire, la perte de fiabilité de la connexion (car l'engin qui fait les traductions d'adresses est un nouveau composant dans la connexion, qui peut avoir des bogues ou des pannes, cf. section 18) ne concerne que l'utilisateur, les tiers ne seront pas touchés.
Les sections suivantes du RFC détaillent successivement chacun de
ces problèmes (je ne les présente pas dans l'ordre, j'essaie de mettre
les plus importantes en premier). La section 5 s'attaque aux problèmes liés à
l'allocation de port. Avec le partage
d'adresses, plusieurs adresses « internes » sont mises en
correspondance avec une seule adresse « externe ». Comment, dans ces
conditions, différencier les paquets IP qui arrivent, à destination de
cette adresse IP externe ? On utilise le numéro de port
TCP ou UDP pour cela et
c'est donc le couple {adresse, port} qui identifie la machine et non
plus l'adresse seule. Ce
numéro de port n'étant stocké que sur 16 bits, cela met une limite stricte à
l'ampleur du partage. Si 500 machines partagent une adresse (facteur
multiplicatif de 500), cela ne
fait qu'un peu plus de 131 ports chacune (et même moins car certains
doivent être réservés, cf. RFC 4787), ce qui est vite épuisé sur une machine un tant
soit peu active, qui ouvre de nombreuses connexions (une seule page
Web peut se traduire par l'ouverture de dizaines de connexions). D'autant plus que
ce n'est pas le nombre de connexions actives qui compte, mais celui
des connexions TCP dans l'état TIME-WAIT
, celui
dans lequel les connexions fermées restent pendant quatre minutes
(RFC 1337).
Voyons les ports « sortants », ceux alloués pour les connexions initiées de l'intérieur (section 5.1). Les études (Alcock, S., « Research into the Viability of Service-Provider NAT ») semblent indiquer que la distribution de la consommation est très inégale : une minorité d'utilisateurs consomme beaucoup de ports. Cela encourage à répartir les numéros de port à partir d'un pool central, et pas à attribuer de manière fixe des plages de ports à chaque client (cf. annexe A). Mais la seconde solution serait bien plus simple et moins coûteuse. Et la première est vulnérable à une attaque DoS : une seule machine infectée par du malware et qui ouvre des connexions le plus vite possible peut épuiser le pool. Ceci dit, l'allocation statique de plages de ports a aussi ses risques (cf. RFC 6056). Tous ces problèmes existaient avec le partage limité à un foyer ou une entreprise mais sont évidemment plus graves en cas de partage généralisé puisqu'un utilisateur peut être bloqué par un autre utilisateur qu'il ne connait pas.
Et pour les ports des connexions entrantes (section 5.2) ? L'étude
citée ci-dessus montre qu'elles sont fréquentes (la majorité des
utilisateurs) mais consomment moins de ports. Comment négocier entre
la machine de l'utilisateur et le routeur NAT l'allocation d'un port
« entrant » ? Aujourd'hui, les méthodes les plus courantes sont
l'allocation manuelle (la plupart des CPE
permettent de configurer des ports entrants, du genre « toute
connexion arrivant pour le port 80 de l'adresse publique doit être traduite vers
192.168.1.13:8080
») ou bien un protocole comme
UPnP. Le CGN complique
sérieusement les choses puisqu'il n'est pas dédié à un utilisateur et
qu'on doit donc sérieusement étudier sa sécurité avant de permettre à
un utilisateur de se réserver les ports 22 ou 80 ! C'est encore pire
si le CPE et le CGN doivent coopérer pour rendre le service, puisqu'il
n'existe aucun protocole standard pour cela. Actuellement, sur
l'abonnement 3G typique en Europe, on n'a pas
accès à l'allocation de ports entrants et le
smartphone ne peut donc pas
héberger de serveur. Cet engin bien plus puissant que les
ordinateurs des débuts de l'Internet est donc limité à un rôle de
Minitel plus perfectionné.
Il existe des solutions potentielles à ces problèmes mais aucune n'est vraiment satisfaisante. À titre d'exemple, le RFC cite les enregistrements SRV qui pourraient permettre de faire savoir que tel service réside sur tel port de la machine coincée derrière le partage d'adresses. Parmi les limites de cette solution, notons qu'elle ne s'applique pas au protocole le plus demandé, HTTP, qui n'utilise pas les SRV...
Jusqu'à présent, j'ai surtout parlé du problème des applications « serveur », celles qui écoutent des connexions inattendues sur un port bien connu, un serveur SSH, par exemple. On peut se dire que de tel cas sont rares sur la machine de M. Michu, qui n'installe en général pas de serveur SSH, ni même HTTP. Mais il y a toute une catégorie d'applications qui a besoin d'écouter des connexions entrantes sans être pour autant un « serveur » à proprement parler. La section 6 est une bonne occasion de les mentionner. En effet, cette section examine tous les cas où le partage d'adresses gène les applications. Cela concerne bien sûr les serveurs traditionnels, vus en section 5.2, mais aussi, entre autres :
Résultat, les applications passent aujourd'hui beaucoup de temps à mettre en œuvre des techniques de contournement, cherchant à récupérer leur connectivité que le NAT contrarie. Il suffit de regarder le code source de n'importe quelle application de téléphonie sur l'Internet pour voir le résultat : le code est plus complexe, et dépend de systèmes difficiles comme ICE (RFC 8445). Avis personnel : il est donc faux de dire que le NAT fait faire des économies. Le NAT est un déplacement de coûts, depuis les administrateurs réseaux vers les développeurs d'applications, contraints à des prodiges d'astuces pour assurer la connectivité.
Un des principaux problèmes que pose fondamentalement le partage
d'adresses est la traçabilité (notez que ce n'est pas un problème pour
tout le monde). Il est fréquent de suivre les actions d'une machine et
de son propriétaire via l'adresse IP. 192.0.2.66
s'est connecté à
www.anonymous.org
. 203.0.113.13
a envoyé du
spam. 198.51.100.254
a
participé à une attaque DoS. Évidemment, si les
adresses IP sont partagées, cette traçabilité n'existe
plus. Aujourd'hui, avec le NAT local classique, on peut au moins
relier une adresse IP à un foyer ou une entreprise. Avec du partage
d'adresses généralisé, cela ne sera plus le cas (section
12). Actuellement, une requête de la police auprès d'un
FAI pour obtenir l'identité d'un abonné dont la
machine s'est fait repérer inclus l'adresse IP et l'heure (pour les
cas d'adresses IP dynamiques, changeant régulièrement). Le partage
généralisé oblige à inclure d'autres informations dans la requête,
comme le numéro de
port, que peu de serveurs enregistrent aujourd'hui. Attention, identifier un abonné à partir du couple
{adresse IP, port} est délicat, car la table de correspondance change
bien plus vite que les baux DHCP typiques. La
requête doit donc inclure une heure très précise et, pour cela,
s'appuyer sur une horloge bien synchronisée. Comme cela risque de ne
pas suffire (et cette solution implique que le serveur enregistre le
numéro de port source, ce qui est inhabituel aujourd'hui), faudra t-il
que le routeur NAT enregistre également l'adresse IP de destination ?
Cela étendrait le domaine du flicage très loin...
Et le FAI doit garder des
journaux de taille colossale pour pouvoir
répondre aux questions comme « Qui utilisait le couple
{198.51.100.254
, 23152} le 23 mai à 11:28:05 ? »,
les obligations légales de surveillance imposant en général de
conserver ces données pendant six à douze mois.
Cela ne sera probablement pas réaliste pour tous les FAI, sauf à créer
des obligations légales qui acculeraient bien des opérateurs à la
faillite. Noter l'adresse IP de destination aggraverait évidemment le
problème.
Comment cela va t-il se passer alors ? Une solution est de baisser les bras et de ne pas divulguer l'identité de l'abonné. Cela peut poser des problèmes légaux au FAI, des lois comme la LCEN en France leur faisant obligation de surveiller leurs abonnés, comme un hôtelier des vieux films policiers surveillait les entrées et sorties de ses clients. Une autre solution est de divulguer les coordonnées de tous les abonnés qui avaient une session active à ce moment là et de laisser la police trier. On imagine le nombre d'innocents qui seront alors harcelés.
À noter que la situation décrite par cette section 12 ne sera pas forcément perçue comme un problème par tout le monde. Ainsi, certains utilisateurs pourraient trouver des avantages à un système qui rend plus compliquée la tâche des surveillants. Si, à cause du partage d'adresses, une société privée de surveillance comme TMG, qui collecte les adresses IP de partageurs de fichiers, a des problèmes, tant mieux, se diront-ils. Le partage d'adresses pourrait alors fournir, sinon l'anonymat, au moins un certain brouillage de pistes. Ce n'est pas faux mais c'est à mettre en rapport avec les inconvénients de ce partage d'adresses.
Le partage d'adresses perturbe une mesure importante pour le bon
fonctionnement de l'Internet, celle de la MTU
du chemin (section 10). Bien des systèmes mesurent cette MTU du chemin
(RFC 1191) pour optimiser le transfert de données. Mais cette
PMTU est en général stockée par adresse IP et
le partage généralisé peut donc fausser les mesures : deux machines
derrière la même adresse IP peuvent ne pas avoir la même PMTU. Cela
peut permettre des attaques par déni de service où une des machines
derrière l'adresse publique générerait des paquets ICMP
packet too big
(type 3 et code 4 d'ICMP)
indiquant une taille ridiculement basse... qui sera utilisée pour tous
les malheureux situés derrière la même adresse.
Il y a d'autres questions de sécurité liées au partage d'adresses. La section 13 les expose successivement. Par exemple, bien des mesures de sécurité sont prises sur la base de l'adresse IP. Un exemple est le logiciel fail2ban qui met automatiquement en liste noire (et donc filtre) les adresses IP qui sont à l'origine de comportements agressifs (comme des connexions SSH répétées). Si cette adresse IP est partagée, des innocents vont aussi se voir bloquer l'accès. Même chose pour les listes noires des expéditeurs de spam.
Des problèmes peuvent également survenir avec des logiciels qui estiment qu'une adresse IP identifie une machine (section 14). Un des exemples est l'optimisation TCP du RFC 2140, qui consiste à partager l'information entre toutes les connexions TCP vers la même machine. Cette optimisation ne fonctionnera plus si la même adresse IP sert à des machines connectées de manière très différente (avec le NAT résidentiel d'aujourd'hui, ce n'est pas trop un problème car toutes les machines de la même maison ont à peu près la même connectivité).
Autre conséquence négative du partage d'adresses : la géolocalisation (section 7). Les adresses IP sont souvent utilisées pour donner une idée (fort imparfaite) de la localisation d'une machine. C'est un système très contestable, déjà aujourd'hui, comme le note le RFC. Mais le partage généralisé d'adresses le rendra encore moins utile, puisque c'est l'adresse du routeur CGN qui sera vue par le serveur, et qu'elle peut n'avoir qu'un très lointain rapport avec le client. Bon, personnellement, je trouve qu'on en arrive à un fort niveau de pinaillage ici : les problèmes posés par le partage d'adresses sont assez graves pour qu'on ne charge pas la barque en mentionnant des conséquences négatives sur un système qui était déjà mal fichu, comme la géolocalisation. Même remarque pour la section 8, qui fait remarquer que le partage généralisé empêchera de compter le nombre d'utilisateurs uniques en comptant le nombre d'adresses IP - ce qui est déjà largement le cas, ou la 11 qui note que le fait d'utiliser le numéro de port pour démultiplexer les paquets arrivant dans le routeur NAT pose un problème avec la fragmentation, puisque seul le premier fragment contient le numéro de port.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : J. Reschke (greenbytes)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF httpbis
Première rédaction de cet article le 6 juin 2011
Le protocole HTTP ne sert pas qu'à récupérer
des pages HTML qu'on va afficher à
l'utilisateur. Une part importante de ses usages est la récupération
de fichiers qu'on enregistrera sur le stockage local. Quel nom donner
au fichier local ? HTTP dispose depuis longtemps d'un en-tête dans les
réponses, Content-Disposition:
, qui fournissait
des suggestions de noms. Cet en-tête était imparfaitement normalisé et
traité un peu à part. Ce nouveau RFC en fait un élément standard et
rigoureusement défini de la panoplie HTTP.
Cet en-tête était donc décrit dans les RFC 2616 (section 19.5.1, qui prend des pincettes et affirme que cet en-tête n'est décrit que parce qu'il est largement mis en œuvre mais qu'il ne fait pas vraiment partie de la norme) et RFC 2183. La description était incomplète, notamment question internationalisation.
La grammaire formelle de cet en-tête est désormais décrite en section 4. Voici un exemple :
Content-Disposition: Attachment; filename=example.txt
Cette réponse HTTP demande que le fichier soit traité comme un
attachement, à enregistrer, et que le nom suggéré est
example.txt
. Le premier terme se nomme le
type (section 4.2) et à la place du
Attachment
qu'on a ici, on pourrait avoir
Inline
qui suggère au client HTTP d'afficher le
fichier, plutôt que de l'enregistrer (c'est le comportement par défaut
en l'absence de l'en-tête
Content-Disposition
). Les types et les noms de
paramètres (ci-dessous) sont insensibles à la casse.
Après le type et un point-virgule, on trouve
des paramètres. Ici, le paramètre
filename
était indiqué, pour proposer un nom de
fichier. À noter que ce paramètre peut être complété par un
filename*
, doté de possibilités étendues,
notamment celle de suggérer des noms comportant des caractères
non-Latin1 (cf. RFC 8187, section 6 et annexe C). Ce filename*
est plus récent et
pas compris de tous les clients HTTP. L'idée est que le serveur
moderne envoie les deux, le client ancien ne gardera que
filename
(qui est « sûr ») et le client nouveau
n'utilisera que filename*
. Voici un exemple
suivant ces recommandations :
Content-Disposition: attachment; filename="EURO rates"; filename*=utf-8''%e2%82%ac%20rates
Ce fichier sera enregistré, par un client récent, sous le nom
€ rates
.
J'ai utilisé à plusieurs reprises des verbes comme « suggérer » ou
« proposer » car le client HTTP reste maître du choix du nom. Il est
même important qu'il n'accepte pas aveuglément n'importe quel nom
donné par le serveur
(imaginez une machine Unix où le navigateur Web
stockerait le fichier sous le nom /etc/passwd
sans réfléchir). Plus précisement, insiste le RFC (sections 4.3 et 7), le client HTTP
doit :
.txt
). Avec certains systèmes d'exploitation
comme Windows, c'est cette extension (et pas le
type MIME - RFC 2046 - envoyé avec le fichier) qui détermine
le comportement associé au fichier. Un nom se terminant en
.exe
peut donc avoir des conséquences
ennuyeuses.
Un bon exemple de faille de sécurité provoquée par le non-respect de
ces règles figure en en http://securitytracker.com/id?1024583
.
La section 4.4 ajoute qu'il faut ignorer les paramètres inconnus
(pour permettre l'extensibilité ultérieure). Les en-têtes invalides
devraient être ignorés par les clients HTTP. De nombreux détails sur
le traitement de Content-Disposition:
par les
clients figurent dans l'excellente page http://greenbytes.de/tech/tc2231/
.
Les clients HTTP, par exemple les navigateurs Web, respectent-ils
cette norme ? Actuellement, Firefox,
Opera et Konqueror le
font, ainsi que Chrome depuis sa version 9
(parait-il : ça ne marche pas chez moi) et
Internet Explorer depuis sa version
9. Cela ne signifie pas qu'ils gèrent tout et notamment Firefox 3
semble ignorer le paramètre de nom de fichier international,
filename*
(bogue #588781). wget semble ignorer l'indication de nom de
fichier par défaut. Il faut lui ajouter l'option
--content-disposition
pour que cela marche. C'est
encore pire pour curl dont l'auteur refuse
de gérer Content-Disposition:
et fait semblant de
croire que l'option --remote-name
le
remplace. lynx a une amusante bogue : il inclus
le point-virgule qui suit (s'il y a un deuxième paramètre), dans le nom de fichier.
À noter que le registre des en-têtes (section 8.2) et celui des
paramètres de Content-Disposition:
(section 8.1) sont utilisés
par d'autres protocoles que HTTP (cf. section 4.5).
L'annexe A résume les changements par rapport au RFC 2616, le premier qui mentionnait cet en-tête
Content-Disposition:
dans le cadre de HTTP. Le
principal est l'ajout des capacités d'internationalisation du RFC 8187. Mais il y a aussi quelques détails, comme
la suppression de la restriction qui limitait cet en-tête aux
ressources de type application/octet-stream
. L'annexe B, elle, résume les changements depuis le RFC 2183. Ils consistent essentiellement en l'abandon de
paramètres intéressants mais qui, en pratique, n'ont jamais été mis
en œuvre par les clients HTTP, comme
creation-date
ou size
.
L'annexe C discute l'approche d'internationalisation utilisée dans ce RFC, en comparant avec les alternatives. Un peu d'histoire : les en-têtes HTTP sont historiquement limités à ISO 8859-1 (RFC 2616, section 2.2 ; j'ai bien dit ISO 8859-1 et pas ASCII ; c'est ainsi que ce blog émettait un en-tête en ISO 8859-1, qui avait planté quelques logiciels qui n'avaient pas bien lu le RFC 2616 ; le RFC 7230, depuis, a supprimé cette possibilité). C'est évidemment une limite unsupportable. La solution standard, depuis belle lurette (RFC 2231, en 1997) est d'encoder les caractères Unicode en « notation pourcent ». Le RFC 8187, plusieurs fois cité ici, est l'application de ce principe à HTTP. Mais les clients HTTP, notamment les navigateurs, ont très souvent essayé des approches non-standard. Pourquoi n'ont-elles pas été reconnues dans notre RFC 6266 ?
Par exemple, certains ont implémenté les encodages du RFC 2047, même si ce RFC précisait bien qu'ils ne
devaient pas être utilisés dans les en-têtes. D'autres gèrent
l'encodage pourcent (RFC 3986, section 2.1) dans le paramètre filename
,
ce qui encourage les serveurs à l'utiliser ainsi, semant la confusion
chez les navigateurs. Ainsi, si le nom de fichier est
caf%C3%A9.html
, certaines navigateurs
l'enregistreront sous le nom café.html
et
d'autres sont le nom caf%C3%A9.html
. Plus rigolo, certains navigateurs
pratiquent l'examen du nom du fichier et appliquent diverses
heuristiques pour déterminer son contenu (« Hmmm, on dirait de
l'UTF-8 encodé pour-cent... Je vais essayer ça. ») C'est évidemment
très fragile. Le tableau « Test Result Summary » en
http://greenbytes.de/tech/tc2231/
résume fort bien le
comportement actuel des navigateurs Web.
Les programmeurs, enfin, ont tout intérêt à lire l'annexe D, qui rassemble les conseils pour les développeurs de serveurs HTTP et d'applications Web (en pratique, c'est souvent le framework de développement, pas le serveur HTTP, qui génère ces en-têtes). Parmi les conseils :
filename
si l'ASCII
suffit (ce devrait être
Latin-1 mais le RFC note qu'il n'est pas prudent de compter dessus,
trop de programmeurs n'ont pas lu le RFC 2616 et
ne gèrent pas correctement le non-ASCII et, de toute façon, le RFC 7230 a modifié la règle depuis),filename*
si l'ASCII
ne suffit pas, tout en sachant que bien des clients Web ne le
cherchent pas et n'utiliserons que
filename
; le RFC suffère donc de mettre les
deux, une version dégradée du nom étant présente dans
filename
(cela est possible en
français, voir l'exemple ci-dessous, mais pas
tellement en arabe),filename*
.Notez que le moteur de recherche de
mon blog produit des en-têtes
« Content-Disposition:
» en respectant, je
l'espère, les conseils de cette annexe D...
% wget --server-response 'http://www.bortzmeyer.org/search?pattern=café chocolat&format=atom' ... Server: Apache/2.2.9 (Debian) mod_wsgi/2.5 Python/2.5.2 Content-Disposition: Inline; filename=bortzmeyer-search-caf--chocolat.atom; filename*=UTF-8''bortzmeyer-search-caf%C3%A9-or-chocolat.atom Content-Type: application/atom+xml; charset="utf-8" ...
(Si vous lisez le code
source, c'est dans wsgis/search.py
.)
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : A. Barth (UC Berkeley)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF httpstate
Première rédaction de cet article le 29 avril 2011
Dernière mise à jour le 30 avril 2011
Les cookies, ces célèbres gâteaux du Web ont déjà fait l'objet d'innombrables articles, par exemple pour critiquer les conséquences pour la vie privée d'un mécanisme qui permet de suivre l'utilisateur à la trace (voir par exemple l'introduction de la CNIL). Mais on connait moins leur spécification technique, ou plutôt le fait que, mal spécifiés dès le début, ces gâteaux ont été mis en œuvre de diverses manières et qu'il est très difficile de décrire intégralement leur fonctionnement. C'est la tâche de notre RFC 6265, d'être, normalement, la norme technique complète et faisant autorité sur les cookies, en capturant l'ensemble des points techniques sur les gâteaux en une seule norme. Les textes précédents étaient la description originale de Netscape (on notera avec ironie que cette spécification privée n'est plus accessible que via WebArchive), puis le RFC 2109, puis le RFC 2965, que notre RFC remplace et annule. Les documents précédents étaient loin de spécifier tous les aspects des petits gâteaux.
Le point de départ est que le protocole
HTTP, le plus utilisé du
Web est sans état. Lors
d'une visite à un site Web, l'utilisateur clique successivement sur
plusieurs liens, visite plusieurs pages, et chaque téléchargement
d'une page est une requête HTTP séparée des autres, sans rien qui
permette de les corréler (par exemple pour se souvenir des préférences
exprimées par
un utilisateur lors de l'arrivée sur la première page). Les gâteaux
visent à combler ce manque. La norme définit deux en-têtes HTTP,
Set-Cookie
qui permet au
serveur HTTP de déposer un gâteau sur
l'ordinateur de l'utilisateur et Cookie
qui
permet au client HTTP (typiquement le
navigateur) de renvoyer un gâteau préalablement
déposé. Lorsque le serveur reçoit le gâteau, il le compare à ceux
qu'il a envoyés et reconnait ainsi un utilisateur déjà vu. HTTP
devient alors un protocole avec état.
Ce n'est pas que les gâteaux soient une solution géniale : imposés par un acteur du Web particulier, Netscape, ils n'avaient pas fait l'objet d'un examen sérieux par une SDO et ont des tas d'inconvénients techniques et politiques. Néanmoins, comme ils sont largement utilisés dans le Web, il était préférable qu'une documentation sérieuse de leur syntaxe et de leur comportement existe, et c'est le rôle de ce RFC 6265.
La section 1 de ce RFC résume le principe des gâteaux. Un gâteau
inclus un certain nombre de métadonnées qui
permettent au client HTTP de savoir si et quand il doit retransmettre
le cookie. Par exemple, on peut spécifier la
période pendant laquelle le gâteau reste valable, les serveurs à qui
on doit le renvoyer, etc. Du fait de leur spécification hâtive et non
collective, les gâteaux ont bien des faiblesses techniques. Par
exemple, l'attribut secure
dans les métadonnées
ne fournit aucune garantie d'intégrité en dépit
de ce que son nom pourrait faire croire. D'autre part, les gâteaux ne
sont pas spécifiques à un port donné donc, si
plusieurs serveurs tournent sur des ports différents de la même
machine, ils peuvent se voler leurs gâteaux mutuellement. Mais, d'une
manière générale, ce RFC n'essaie pas de réparer la situation, mais de
documenter les gâteaux tels qu'ils sont réellement produits et
consommés sur le Web.
Bien, assez râlé, qui doit lire ce RFC ? Il y a deux audiences, les développeurs d'applications côté serveurs (ou, plus exactement, des bibliothèques qui sont utilisées par ces applications) qui produisent et consomment des gâteaux, et les développeurs des logiciels clients, notamment les navigateurs Web. Pour maximiser les chances d'interopérabilité, les serveurs devraient se montrer très prudents et ne produire que des gâteaux parfaitement conformes à la norme (section 4 du RFC, qui décrit le profil restreint), alors que les clients doivent être plus tolérants et accepter la grande variété des gâteaux actuellement fabriqués (section 5, sur le profil libéral), car tous les serveurs ne suivent pas le profil restreint.
Avant de lire le gros du RFC, un petit détour par la norme HTTP, le RFC 7230, peut être utile, puisque notre RFC en reprend le vocabulaire.
La section 3 décrit les généralités sur les gâteaux. Ceux-si sont
envoyés par un en-tête Set-Cookie
dans la
réponse HTTP, puis retournés dans un en-tête
Cookie
dans la requête
suivante. L'état est donc stocké chez le client mais, en pratique, la
taille des gâteaux étant limité, le serveur stocke l'essentiel de
l'état et le gâteau ne sert que d'index pour retrouver une session
particulière. Un serveur peut utiliser Set-Cookie
dans n'importe quelle réponse (y compris les erreurs comme 404) et le client doit le gérer (sauf pour
les réponses de type 1xx, qui sont seulement « pour
information »). Plusieurs gâteaux peuvent être envoyés, chacun dans un
en-tête Set-Cookie
différent (le client, lui,
peut utiliser un seul en-tête Cookie
pour envoyer
plusieurs gâteaux). Un exemple
classique est l'envoi d'un identificateur de session (ici, SID, pour
Session ID). Le serveur envoie :
Set-Cookie: SID=31d4d96e407aad42
et à la requête suivante, le client renverra :
Cookie: SID=31d4d96e407aad42
Le serveur peut réduire la portée du gâteau avec les attributs
Path
et Domain
. Ici, par
exemple, le gâteau doit être renvoyé pour tous les
URL dans example.com
:
Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com
Ici, un serveur prudent utilise en plus les attributs
Secure
et HttpOnly
. En
outre, il envoie deux gâteaux, SID et lang (chacun étant un doublet nom-valeur) :
Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly Set-Cookie: lang=en-US; Path=/; Domain=example.com
Le client peut les renvoyer en un seul en-tête :
Cookie: SID=31d4d96e407aad42; lang=en-US
Ici, le serveur fixe une date d'expiration au gâteau :
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
Après ces exemples tirés du RFC, voici maintenant un exemple réel entre un site Web écrit en PHP et un navigateur. Le trafic a été capturé et formaté avec tshark :
# Le serveur envoie : Set-Cookie: PHPSESSID=euk3daoldp4s3j90uocetas3a0; path=/\r\n # Le client répond (d'autres gâteaux avaient été transmis) : Cookie: __utma=85646793.1868252067.1190397623.1190397623.1190397623.1; \ PHPSESSID=euk3daoldp4s3j90uocetas3a0; \ culture=fr\r\n
Autre façon de voir les gâteaux, se servir du client en ligne de commande curl :
% curl -v http://twitter.com/ > /dev/null ... < Set-Cookie: guest_id=130393513906128799; path=/; expires=Fri, 27 May 2011 20:12:19 GMT < Set-Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCPc8l5gvAToHaWQiJWY3NTg3YTU1YTgwOWE2%250AODcxMTA5M2NiNzNiOWMxODRmIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--dd45d4b08ccac6e6f832ccb70af983e16a12df43; domain=.twitter.com; path=/; HttpOnly
curl permet même de renvoyer ces gâteaux au serveur :
% curl --cookie _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCPc8l5gvAToHaWQiJWY3NTg3YTU1YTgwOWE2%250AODcxMTA5M2NiNzNiOWMxODRmIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--dd45d4b08ccac6e6f832ccb70af983e16a12df43\;guest_id=130393513906128799 -v http://twitter.com/ > /dev/null ... > Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCPc8l5gvAToHaWQiJWY3NTg3YTU1YTgwOWE2%250AODcxMTA5M2NiNzNiOWMxODRmIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--dd45d4b08ccac6e6f832ccb70af983e16a12df43;guest_id=130393513906128799 ...
La section 4 définit rigoureusement les obligations d'un serveur sérieux, qui ne cherche pas à exploiter les possibilités de la norme à fond et qui veut être sûr que tous les clients pourront traiter correctement ses gâteaux. Sa section 4.1.1 définit la syntaxe formelle à suivre, en ABNF. Les valeurs qui ne sont pas réduites à un strict sous-ensemble de caractères sûrs, pour maximiser les chances d'être transmises sans accident, sont encodées en Base64. Les dates s'expriment avec le format du RFC 1123 (mais certains serveurs non compatibles avec ce profil envoient des dates sur deux chiffres...). Certains clients stockent les dates dans un entier de seulement 32 bits donc il est possible que les choses se passent mal à partir de 2038.
Le serveur peut ajouter des attributs aux gâteaux. Ainsi,
l'attribut Expires
(section 4.1.2.1) permet de
spécifier la date limite de consommation du gâteau (« À consommer avant le 29 avril
2011 ») et l'attribut Max-Age
indique la durée de
vie maximale (le RFC prévient que Max-Age
est
moins souvent mis en œuvre que Expires
par
les clients HTTP). Le gâteau peut durer moins longtemps que cela, par exemple
parce que le navigateur Web a décidé de faire de la place, ou bien
parce que l'utilisateur l'a détruit explicitement (chose que
permettent tous les bons navigateurs, vues les conséquences négatives des
gâteaux pour la vie privée).
Important pour la sécurité, l'attribut Domain
permet d'indiquer le domaine des serveurs à qui
le client doit renvoyer le gâteau. Attention, les sous-domaines de ce
domaine sont également acceptés. Si le serveur envoie
Domain=example.org
lors du
Set-Cookie
, le client renverra le gâteau à, par exemple,
www.example.org
et
mail.example.org
. (Et si un serveur distrait met
un gâteau avec Domain=com
? Il sera renvoyé à
tous les domains en .com
?
Cela dépend du navigateur ; beaucoup ignorent cet attribut
Domain
s'il correspond à un domaine
d'enregistrement comme .fr
ou .co.uk
mais il n'existe
pas de moyen officiel d'en connaître la liste donc ces navigateurs
dépendent de listes incomplètes comme http://publicsuffix.org
. Voir la section 5.3 pour une
discussion complète. À noter que Konqueror
utilise une méthode encore pire qui n'a jamais été corrigée.)
Le serveur peut restreindre encore plus l'utilisation du gâteau
qu'il envoie avec l'attribut Path
(section
4.1.2.4). Celui-ci indique quelle section du site Web a besoin du
gâteau. Si on met Path=/accounting
et que le
domaine est www.example.com
, seuls les URL
commençant par http://www.example.com/accounting
recevront le gâteau.
Enfin, deux autres attributs permettent d'améliorer la (faible)
sécurité des gâteaux, Secure
, qui impose au
client de ne renvoyer le gâteau qu'au dessus d'une connexion « sûre »
(typiquement HTTPS, pour éviter les attaques
par FireSheep) et HttpOnly
qui restreint le gâteau à ce protocole.
Une fois que le serveur a créé le gâteau et l'a envoyé avec les
attributs qu'il juge utile, il doit être prêt à recevoir des gâteaux
retransmis par le client. La section 4.2 décrit l'en-tête
Cookie
des requêtes HTTP, qui sert à cela. (Voir
les exemples plus haut.)
La section 4 décrivait un profil réduit des gâteaux. Un client HTTP sérieux qui veut pouvoir comprendre tous les serveurs existants dans la nature, y compris ceux qui ne s'en tiennent pas à ce profil réduit, doit, lui, lire la section 5, qui décrit l'intégralité du très compliqué comportement des gâteaux. Cette section reprend le plan de la 4, en détaillant toutes les horreurs qu'on peut rencontrer dans le monde réel.
Par exemple, le format des dates (section 5.1.1), utilisées dans
des attributs comme Expires
, permet à peu près
toutes les variations possibles. Écrire un
analyseur complet n'est pas trivial, d'autant
plus que le RFC ne décrit pas une grammaire
indépendante du contexte mais un algorithme à état. (Si un pro de
l'analyse syntaxique peut fournir une grammaire plus déclarative de
cette syntaxe, je serais intéressé...)
De même, l'analyse du Set-Cookie
en section 5
est plus complexe car le client doit accepter des
Set-Cookie
plus variés, par exemple avec des
espaces en plus.
La section 5.3, qui n'a pas d'équivalent dans la section 4, décrit la façon dont les clients, les navigateurs Web, doivent stocker les gâteaux et les renvoyer. Elle rappelle la liste des attributs à stocker avec chaque gâteau (par exemple, s'il doit être renvoyé uniquement sur une connexion sécurisée ou bien si ce n'est pas nécessaire). Elle est très longue et le pauvre auteur de navigateur Web a donc bien du travail.
En parlant du programmeur, justement, la section 6 décrit les questions que pose l'implémentation de cette spécification. Parmi elles, la question de la taille du magasin où sont stockés les gâteaux. Le client Web n'est nullement obligé de fournir un magasin de taille infinie. Néanmoins, le RFC demande que le client accepte au moins quatre kilo-octets par gâteau, cinquante gâteaux par domaine et trois mille gâteaux en tout (ce qui permet déjà une belle indigestion). Conséquence de cette limite : un serveur doit s'attendre à ce qu'un client ne renvoie pas tous les gâteaux prévus. Certains ont pu être abandonnés par manque de place.
On l'a vu, la section 5, qui normalise le comportement du client,
est très complexe. La section 4 l'est moins mais l'expérience a
largement prouvé que les serveurs émettant des gâteaux avaient du mal
à se tenir à un profil strict, et produisaient trop de variations. Une
des raisons identifiées par la section 6.2 est le manque
d'API. La plupart du temps, les applications
font directement un printf "Set-Cookie: foobar=1234567;
Expires=Wed, 06 Jun 2012 10:18:14 GMT\n"
(ou équivalent) au
lieu d'appeler une API plus abstraite dont l'implémentation se
chargera de sérialiser proprement les objets complexes comme la
date. Avec tant de liberté laissée au programmeur, il n'est pas
étonnant qu'il y ait des variations non-standard.
Si le RFC ne propose pas de solution, il insiste sur l'importance
pour les programmeurs d'utiliser des bibliothèques bien déboguées et
de ne pas se croire capable d'écrire un
Set-Cookie
correct après cinq minutes de lecture
de la norme. Un exemple d'une telle bibliothèque est, en
Python, http.cookies. D'encore
plus haut niveau, dans le même
langage, urllib2 gère les gâteaux toute seule.
Comme le respect de la vie privée est le principal problème des gâteaux, il est normal que cette question ait une section entière, la 7, qui détaille ce point. C'est inhabituel à l'IETF, où la vie privée ne génère en général que peu d'intérêt. Peu de RFC ont une section Privacy considerations. Que dit-elle ? Que les gâteaux sont effectivement une technologie sensible (bien qu'il existe d'autres moyens de suivre un utilisateur mais moins pratiques donc moins dangereux) et que les plus problématiques sont les gâteaux envoyés à un tiers (c'est-à-dire à une autre organisation que celle qui gère visiblement la page, par le biais d'une discrète image insérée, par exemple). Par exemple, un service de statistiques utilisé sur de nombreux sites Web, ou bien un service de placement de publicités, peuvent permettre à leur gérant de croiser les visites faites sur plusieurs sites différents et ceci sans que l'utilisateur n'ait fait de visite explicite aux services de cette indiscrète organisation. Certains navigateurs sont, à juste titre, davantage paranoïaques lorsque le gâteau est envoyé par un tiers, par exemple en les refusant par défaut. D'autres ne traitent pas ces gâteaux différemment des autres. La question étant essentiellement politique, notre RFC 6265 ne définit pas de comportement normalisé, se contentant d'attirer l'attention sur ce point.
Peut-on demander son avis à l'utilisateur ? C'est ce qu'expose la section 7.2, consacrée au contrôle par l'utilisateur. Le RFC recommande que les clients Web fournissent des mécanismes de contrôle des gâteaux permettant de :
about:config network.cookie.lifetimePolicy=1
),
Voici la liste des gâteaux stockés, telle que Firefox permet de
l'examiner et de la modifier :
Et la question que pose le même Firefox lorsqu'on l'a configuré avec about:config network.cookie.lifetimePolicy=1
:
Et le dialogue de configuration dans Firefox 4, montrant l'option qui permet de demander à chaque gâteau si on l'accepte :
À noter qu'il existe bien d'autres moyens de configurer la politique
des gâteaux, si le navigateur ne fait pas ce qu'on veut, par exemple
des extensions comme Cookie
Monster, WebDeveloper (qui permet de voir tous les gâteaux de la page en cours, avec pour chacun « Éditer » ou « Supprimer ») ou Ghostery
pour Firefox. Le navigateur Dillo, quant à lui,
à un mécanisme très
détaillé.
Même en dehors du cas de la vie privée, les gâteaux posent un certain nombre de problèmes de sécurité (section 8). L'utilisation de HTTPS, quoique évidemment souhaitable, ne protège pas complètement contre ces vulnérabilités.
Premier problème, l'autorité diffuse (ambient authority, section 8.2). Le gâteau utilisé pour l'authentification sépare la désignation (l'URL) de l'autorisation. Le client risque donc d'envoyer le gâteau pour une ressource Web qui était contrôlée par un attaquant, une technique connue sous le nom de CSRF (il existe plusieurs moyens de convaincre un navigateur de se prêter à cette attaque, une étude bien plus détaillée des CSRF, qui a parmi ses auteurs l'auteur de ce RFC, est « Robust Defenses for Cross-Site Request Forgery »). Une solution à ce problème serait de traiter les URL comme une capacité, donnant accès à une ressource. L'URL serait alors le secret à transmettre pour avoir accès (le RFC ne note malheureusement pas que les URL ne restent pas secrets longtemps, par exemple certains navigateurs ou extensions des navigateurs - la Google Toolbar - transmettent les URL consultés à leur maître).
Autre problème des gâteaux, leur envoi en texte clair (section
8.3). Si on n'utilise pas HTTPS, Set-Cookie
et
Cookie
sont transmis en clair avec leur contenu,
permettant à un espion de les copier et de les utiliser (c'est cette
vulnérabilité qu'exploite un programme comme
FireSheep). En outre, un attaquant actif peut
modifier ces en-têtes. La solution recommandée est évidemment de
chiffrer toute la session, et de mettre l'attribut
Secure
aux gâteaux envoyés, pour éviter qu'ils ne
soient plus tard transmis sur une session non chiffrée. Beaucoup de
gros services très populaires ne sont pas accessibles en HTTPS ou bien
ne le mettent pas en œuvre par défaut (souvent pour des raisons
de performance, facteur crucial pour ces services qui reçoivent
beaucoup de visites). Dans le cas de Gmail,
c'est l'option « Général : Connexion du navigateur ; Toujours utiliser
le protocole https ». Dans celui de Twitter,
c'est « Toujours utiliser le HTTPS ». L'EFF
mène une campagne pour systématiser
cette protection. À noter qu'on peut limiter (mais pas
supprimer) la réutilisation du gâteau en liant celui-ci à
l'adresse IP du client ; si le gâteau vient
d'une autre adresse, il sera refusé. Cette méthode n'est pas si
efficace qu'elle en a l'air en raison de la fréquence du partage
d'adresses IP (via le NAT). Ainsi, dans un café
avec WiFi, un attaquant qui utilise FireSheep n'aura pas de problèmes
malgré cette protection car tous les clients sont probablement
derrière la même adresse IPv4 (c'est sans doute
pour cela que le RFC ne propose pas cette solution).
C'est encore pire si le gâteau contient directement de
l'information utile. Par exemple, si le gâteau est
lang=en-AU
, l'espion qui écoute peut trouver la
langue et le pays de l'utilisateur. En général, cette information est
plutôt stockée sur le serveur et le gâteau ne contient qu'un
identificateur de session, inutile si on n'a pas accès au
serveur. Mais cette technique présente d'autres risques (section 8.4),
par exemple celui du « choix de session » où l'attaquant se connecte
au serveur, puis convainct la victime (par exemple par le biais d'un
lien) d'utiliser l'identificateur de session et d'interagir avec le
serveur (par exemple en y déposant des informations
confidentielles). L'attaquant, qui a conservé l'identificateur de
session, pourra alors continuer la session et récupérer ces
informations. (Voir un
exemple et un article
complet.)
Autre problème de sécurité des gâteaux, la confidentialité (section
8.5) : comme les gâteaux ne sont pas spécifiques d'un
port ou d'un plan (http, gopher, ftp, etc), un
client risque toujours de transmettre les gâteaux d'un serveur à un
autre. L'intégrité n'est pas non plus garantie (section 8.6). Si
bar.example.com
a mis un gâteau de domain de
example.com
, un autre serveur,
foo.example.com
peut parfaitement le
remplacer. Path
n'est pas une protection : il
n'empêche pas le remplacement.
Enfin, les gâteaux dépendent du DNS et en héritent les vulnérabilités (section 8.7).
Une très bonne synthèse des failles de sécurité des gâteaux figure dans l'excellent article « HTTP cookies, or how not to design protocols ».
Voilà, c'est tout, il reste à enregistrer les deux en-têtes dans le registre des en-têtes, ce que fait la section 9.
Contrairement aux autres RFC qui remplacent un autre RFC, ce RFC 6265 ne contient pas de description des changements par rapport aux précédents documents. Les clarifications et précisions sont sans doute trop nombreuses pour former une liste intéressante.
Merci à Jean-Baptiste Favre, bohwaz et Ollivier Robert pour leurs remarques et suggestions.
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : S. Jiang, D. Guo (Huawei), B. Carpenter (University of Auckland)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 14 juin 2011
Verra-t-on un jour la fin des RFC sur les plans de transition d'IPv4 vers IPv6 ? Sans doute pas tant que la transition traîne. En effet, la lenteur imprévue du déploiement d'IPv6 remet en cause les plans initiaux (qui reposaient sur l'idée qu'il resterait des adresses IPv4 pendant toute la phase de transition) et nécessite le développement de nouveaux plans, pour répondre à une situation différente.
Le plan présenté ici est une variante des plans reposant sur l'idée de CGN (Carrier-Grade NAT), ces routeurs NAT installés, non pas dans la box de M. Michu, pour son usage et celui de sa famille, mais installés chez le FAI, pour l'usage partagé de plusieurs clients du FAI. Le CGN a l'avantage de nécessiter zéro logiciel ou configuration chez l'utilisateur (qui n'a probablement pas le temps et l'envie de maîtriser ces mécanismes). Ces solutions reposant uniquement sur le travail du FAI sont donc tentantes pour répondre au problème de la trop lente migration chez les utilisateurs. (Toutefois, mon impression personnelle est que beaucoup de réseaux de M. Michu, plein de gadgets récents, sont plus avancés vers IPv6 que pas mal de réseaux de FAI, conçus il y a des années.)
La nouveauté par rapport aux autres plans reposant sur le CGN est l'introduction de mécanismes pour éviter que ce CGN ne se transforme en impasse, et pour le faire évoluer vers de l'IPv6 natif complet. En effet, dans la plupart des cas, le terme de CGN fait penser à un mécanisme pour retarder la transition, le NAT444, qui permet au FAI paresseux de continuer à utiliser IPv4 même alors qu'il ne peut plus distribuer ne serait-ce qu'une seule adresse IPv4 publique à ses clients. Ce CGN-là ne fait pas progresser vers IPv6 (section 1 du RFC).
D'où cette idée de proposer un plan de migration reposant sur le CGN mais prévoyant dès le début les moyens d'en sortir. Ce RFC ne contient pas de nouveaux protocoles, il ne fait que combiner les protocoles existants.
Dans un certain nombre de FAI, la situation est actuellement la suivante (section 2) :
Dans d'autre cas, FAI ayant fait son travail à l'avance et ayant déployé IPv6 depuis longtemps, ou bien FAI tout récent et préférant l'approche radicale de déployer un réseau purement IPv6, avec NAT64 (RFC 6144, et section 2.6 de notre RFC) pour assurer la liaison avec le vieux protocole, ces hypothèses ne sont plus vraies et l'approche de ce RFC ne s'applique donc pas. Comme toujours avec la transition vers IPv6, il faut analyser son réseau et déterminer la ou les meilleures stratégies de transition : chacune s'applique à un cas bien particulier.
Le dessin n° 1 en section 2.1 résume bien l'approche « CGN progressif » (Incremental Carrier-Grade NAT). En partant de chez M. Michu (ou plutôt M. Li car le cas décrit est plus proche de ce que vivent les FAI asiatiques), on a :
Les deux composants nouveaux, que n'a pas forcément le FAI aujourd'hui, sont le HG et le CGN. Le HG doit obéir au RFC 7084. Autrement, tous les équipements (routeurs classiques et machines terminales) ne changent pas (cf. section 2.5).
Quelle technique de tunnel choisir entre le HG et le CGN ? La section 2.2 rappelle les possibilités. Les tunnels configurés manuellement du RFC 4213 paraissent peu pratiques. Ceux du RFC 3053 peuvent ne pas être très utilisables par l'utilisateur résidentiel. Cela laisse 6rd (RFC 5969) et peut-être GRE (RFC 2784). Si le FAI a déjà une infrastructure MPLS, il peut aussi considérer RFC 4798, mais cela suppose que MPLS aille jusqu'au HG, ce qui est peu probable. Bref, le RFC recommande 6rd.
La section 2.3 peut alors décrire en détail le fonctionnement de la HG (Home Gateway, la box). Lorsqu'elle reçoit un paquet de l'intérieur :
Et le CGN (Carrier-Grade NAT, un routeur NAT qui sert plusieurs clients) ? La section 2.4 lui est consacrée. Lorsqu'il reçoit un paquet IPv4 venu d'une HG (rappelons que tout ce RFC est consacré au cas où l'infrastructure du FAI est purement IPv4), deux cas :
Voilà, sur le papier, c'est tout simple. Quelles sont les conséquences pratiques ? La section 2.7 discute divers points. D'abord, comme toute solution à base de NAT, notre schéma a tous les inconvénients du partage d'adresses. Pire, comme le CGN est situé loin de l'utilisateur, et que celui-ci ne peut pas le configurer, des techniques permettant d'avoir des connexions entrantes comme les correspondances statiques ou comme UPnP ne fonctionnent plus. D'autre part, le tunnel v6-sur-v4 entre le HG et le CGN posera les habituels problèmes de MTU (dont le RFC se débarasse avec une pirouette).
L'originalité de l'approche de ce RFC est la possibilité de migrer de cette solution NAT complexe et fragile vers une solution IPv6 propre. Comment ? C'est ce que décrit la section 3, qui prévoit plusieurs étapes, en supposant :
Comme indiqué, le passage d'une étape à une autre peut être détecté automatiquement par le HG, la box, qui peut par exemple interroger le CGN pour noter les nouvelles fonctions disponibles. Cela éviterait une action explicite sur la HG.
Il reste à étudier les conséquences de ce schéma en terme de
sécurité (section 4). Le NAT en général pose de nombreux problèmes de
sécurité (RFC 2663 et RFC 2993). Le partage massif
d'adresses, par exemple dans un CGN, crée des failles expliquées dans
le projet de RFC draft-ietf-intarea-shared-addressing-issues
. Les
protocoles spécifiques utilisés ont également leurs propres questions
de sécurité, documentées dans leur norme respective (par exemple, pour
6rd, dans la section 12 du RFC 5969).
Toutefois, le fait que ce schéma concerne uniquement des mécanismes utilisés à l'intérieur du réseau d'un FAI, la sécurité est simplifiée. On peut certes sécuriser les tunnels avec le RFC 4891 mais ce n'est peut-être pas nécessaire, à l'intérieur d'un réseau unique et géré.
Par construction, il n'y a pas d'implémentation complète de ce RFC, mais des implémentations de certaines des fonctions. Par exemple, DS-Lite est mis en œuvre dans AFTR.
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : W. Eddy (MTI Systems), E. Davies (Folly Consulting)
Pour information
Première rédaction de cet article le 26 mai 2011
Comment encoder des valeurs dans un protocole ? Il existe des tas de méthodes mais celle de ce RFC 6256, les « valeurs numériques auto-terminées » (SDNV pour Self-Delimiting Numeric Values) sont encore très peu connues et guère utilisées.
Soit un concepteur de protocoles réseau. Il doit indiquer dans les données qui circulent des valeurs, par exemple un gâteau qui identifie une session ou bien une durée ou une longueur ou bien une clé cryptographique ou des tas de choses encore. Comment transmettre ces valeurs (section 1.1) ? Une technique courante, très utilisée dans les protocoles « binaires » comme IP (RFC 791) ou bien le DNS (RFC 1035) est le champ de taille fixe. On décide que la longueur sera représentée sur 16 bits et les producteurs et les lecteurs de ce champ connaissent cette taille, qu'ils ont lu dans le RFC correspondant. Plus la taille est grande, plus on consomme de ressources réseaux pour la transmettre mais, plus elle est petite, et moins on pourra représenter de valeurs. Dans mon exemple, que fera t-on si les changements dans les techniques ou dans les usages nécessitent de stocker des longueurs supérieurs à 65 536 ? Le problème est fréquent car des protocoles sont souvent utilisés pour des dizaines d'années consécutives, années pendant lesquelles les hypothèses de base ont changé. Le RFC cite ainsi les exemples de la fenêtre TCP (RFC 793, la fenêtre est limitée à 16 bits, soit 65 kilo-octets, ce qui est bien trop peu pour les réseaux à 10 Gb/s d'aujourd'hui, et a nécessité le hack de l'échelle de fenêtre du RFC 1323, désormais en RFC 7323) et du bien connu champ Adresse d'IPv4, qui s'est montré trop petit. Le RFC note bien que les deux décisions avaient semblé raisonnables à l'époque : sur une ligne spécialisé à 64 kb/s, la fenêtre maximale était de huit secondes, ce qui donnait largement aux accusés de réception le temps de revenir. Aujourd'hui, la même taille ne laisse que 50 microsecondes... Même problème pour les adresses IPv4, épuisées par le changement du modèle de l'ordinateur (de « un par entreprise » à « plusieurs par personnes ») et par le succès inespéré de l'Internet. Les SDNV permettent donc d'éviter de prendre des décisions (« 16 bits ? 32 bits ? Allons-y pour 16 bits, ça suffira bien. ») qu'on regrettera ensuite.
Une autre approche, commune à l'IETF, est d'utiliser TLV. C'est le mécanisme le plus souple, mais, pour des valeurs assez petites, il prend plus de place que SDNV.
Le groupe de recherche IRTF DTNRG, qui est occupé notamment à développer des protocoles réseau pour les vaisseaux spatiaux (cf. RFC 4838) a son idée sur la question (la section 4 présente une discussion des alternatives), et cela a donné ce RFC. Par exemple, dans l'espace, vu le RTT, les protocoles qui négocient des paramètres au début de la connexion (comme l'échelle de fenêtre TCP), et qui permettent ainsi d'avoir des champs de taille fixe et de choisir la taille au début de la connexion, ne sont pas envisageables. Mais le problème n'est pas spécifique aux réseaux « DTN » (Delay-Tolerant Networking, les réseaux où l'acheminement d'un bit prend un temps fou, ce qui est le cas dans l'espace où la vitesse de la lumière est une limite gênante, cf. RFC 5325) et on peut retrouver des ancêtres de SDNV dans des encodages ASN.1 ou bien dans certains protocoles UIT. Par contre, en dehors du projet DTN, il ne semble pas que les SDNV aient été utilisés par des protocoles IETF, peut-être parce que leur encodage et décodage est plus lent qu'avec des champs de taille fixe (le protocole WebSocket utilise les SDNV). À noter que notre RFC n'est pas la premier à normaliser SDNV, ceux-ci avaient déjà été décrits dans les RFC 5050 et RFC 5326 mais de manière sommaire. Un description plus complète n'était donc pas du luxe.
SDNV se limite à représenter des entiers positifs ou des chaînes de bits. Pour des types plus complexes, on peut utiliser les encodages d'ASN.1 ou bien MSDTP (décrit dans le RFC 713).
Après ces préliminaires, attaquons-nous à la définition d'un SDNV (section 2). Un SDNV est encodé sous forme d'une série d'octets en n'utilisant que sept bits de chaque octet. Le huitième indique si l'octet est le dernier du SDNV. Ce mécanisme impose un décodage strictement séquentiel, en examinant un octet après l'autre. Quelques exemples :
L'annexe A contient d'autres exemples et j'en montre certains à la fin de cet article. Il y a quelques détails pratiques comme les zéros initiaux : le premier nombre est-il 3 où 03 ? Le RFC explique que les zéros initiaux ne sont pas significatifs. Pour les nombres, cela ne change évidemment rien (3 = 03) mais si on voulait représenter des chaînes de bits, c'est plus compliqué et SDNV ne fournit pas de solution satisfaisante (le RFC suggère par exemple d'indiquer explicitement la longueur dans un autre champ, ce qui annule l'intérêt de SDNV ; une autre suggestion est de toujours mettre un bit à 1 au début de toute chaîne).
Les SDNV ont parfois été décrits sous le nom de Variable Byte Encoding (cf. le livre de Manning, Raghavan, et Schuetze, « Introduction to Information Retrieval », qui s'intéressait toutefois à la compression plutôt qu'à la souplesse). On peut remarquer qu'aucune valeur encodée en SDNV n'est un préfixe d'une valeur encodée en SDNV (SDNV est prefix-free, autre façon de dire que les données sont auto-terminées).
Comment encode et décode-t-on ces SDNV ? La section 3 décrit
quelques algorithmes qui peuvent être utilisés à cette fin. La section
3.1 contient un algorithme d'encodage très simple en O(log(N)) où N est le nombre à encoder. Le décodage
est plus sioux : on ne connait en effet pas la valeur du nombre avant
de l'avoir décodé et on ne sait donc pas quel type on doit utiliser
pour stocker le résultat. Même un type de grande taille, genre
uint64_t
peut être trop petit. La section 3.2
propose un algorithme de décodage récursif, qui évalue à chaque étape
si le résultat est de taille suffisante et alloue une autre variable
si nécessaire.
Cette histoire de taille de la variable qui stocke le résultat est
un des problèmes pénibles de SDNV. On ne peut pas exiger de chaque
implémentation qu'elle mette en œuvre un système d'entiers infinis (le RFC cite GNU
MP comme exemple). La section 3.3 propose que chaque
protocole qui utilise des SDNV fixe une taille maximale aux entiers
stockés (retombant ainsi partiellement dans les problèmes des champs
de taille fixe). Ainsi, le protocole Bundle
(RFC 5050) fixe cette limite à la valeur
maximale pouvant être représentée avec 64 bits. Le décodeur peut donc
utiliser un uint64_t
sans crainte.
Voilà, les SDNV sont donc très simples dans leur principe. Mais quels sont leurs avantages et leurs inconvénients ? La section 4 discute des alternatives : SDNV actuels, TLV, et l'ancien système de SDNV qui avait été utilisé dans des versions antérieures de certains protocoles DTN. En gros, le système le plus souple est TLV mais c'est aussi le moins efficace, en place et en temps. Un avantage de TLV est que, via le champ Type, la sémantique est connue, alors que les SDNV ne sont que des entiers non typés. Autre avantage : la taille du résultat est connue tout de suite et l'allocation mémoire pour le résultat tombe donc toujours juste (l'ancien SDNV avait un système analogue). Mais l'un des problèmes des TLV est que la représentation des champs Type et Longueur. S'ils sont de taille fixe, les TLV héritent certains des problèmes des champs de taille fixe. Notons qu'on peut combiner les techniques, par exemple utiliser SDNV pour le champ Longueur d'un TLV.
Bien que le RFC n'en discute guère, je me permets d'ajouter ici une comparaison essentiellement personnelle entre champs de taille fixe et SDNV. Les champs de taille fixe :
Bref, je trouve personnellement que l'utilisation fréquente de champs de taille fixe dans les protocoles Internet n'est pas due au hasard.
Reparlons de décodage avec la question de la sécurité (section 5). Un décodeur SDNV doit faire attention aux valeurs qui dépassent ses limites, non seulement pour ne pas planter, mais aussi parce que cela peut avoir des conséquences de sécurité (débordement de tampon, par exemple). Autre piège, les entiers gérés par SDNV sont toujours positifs. Une implémentation ne doit donc pas les décoder vers un type signé, ce qui risquerait d'introduire des valeurs négatives dans un processus qui ne s'y attend pas. (TLV a le même problème si on place un champ Longueur dans une variable de type signé.)
Place aux implémentations. Le programme Python sdnv.py, qui utilise le code présent dans l'annexe A du RFC, permet de tester encodage et décodage. L'affichage (pas le calcul) nécessite l'excellent module bitstring :
# Encodage % python sdnv.py -e 3 3 -> 0b00000011 % python sdnv.py -e 130 130 -> 0b1000000100000010 % python sdnv.py -e 4598 4598 -> 0b1010001101110110 % python sdnv.py -e 46598 46598 -> 0b100000101110110000000110 # Décodage % python sdnv.py -d 00000000 00000000 -> 0 % python sdnv.py -d 00000011 00000011 -> 3 % python sdnv.py -d 1000000100000010 1000000100000010 -> 130 [Ajout d'un troisième octet, fait de bits nuls, _après_ le SDNV.] % python sdnv.py -d 100000010000001000000000 100000010000001000000000 (only 2 bytes read) -> 130
À noter que les SDNV disposent d'une page Web officielle. En dehors du code Python du RFC, je n'ai pas vu d'autres implémentations mais on peut probablement en extraire du code DTN.
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : M. Blanchet (Viagénie)
Pour information
Première rédaction de cet article le 26 mai 2011
Le groupe de recherche DTN (Delay-Tolerant Networking, cf. RFC 4838) de l'IRTF a déjà produit plusieurs protocoles comme Bundle (RFC 5050) et Licklider (RFC 5326). Ces protocoles n'avaient pas jusqu'alors de registres officiels pour leurs paramètres, manque que notre RFC 6255 vient de combler.
Jusqu'à présent, les paramètres enregistrés étaient stockés sur
le site Web du groupe. Ils sont désormais à
l'IANA qui en assurera la maintenance: https://www.iana.org/assignments/bundle/bundle.xml
.
Ces paramètres sont souvent encodés sous forme de SDNV (Self-Delimiting Numeric Values, RFC 6256 et section 2 de notre RFC). Pour le protocole Bundle (RFC 5050) les paramètres à enregistrer sont décrits en section 3. On peut citer par exemple les options de traitement (processing control flags, section 3.3), dont la liste peut évoluer, la seule contrainte pour l'enregistrement étant la disponibilité d'une spécification stable (pour les politiques d'enregistrement dans les registres IANA, voir le RFC 5226 ; cette politique particulière, « Specification required » est décrite en section 4.1). Ces options ont la forme de bits dans un tableau de taille 64, parmi lesquels le bit 2 indique que le lot (bundle) ne doit pas être fragmenté, le 5 qu'un accusé de réception est demandé, etc.
Autre exemple, les codes de réponse (status report flags, section 3.5) comme « lot accepté » ou « lot transmis ». Comme le tableau de bits est bien plus petit cette fois (huit bits dont seuls trois sont encore libres), les règles d'enregistrement sont plus strictes, un RFC (pas juste n'importe quelle spécification) est exigé.
Les autres protocoles comme Licklider n'ont pas encore leur registre.
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : D. Thaler (IAB)
Pour information
Première rédaction de cet article le 20 mai 2011
Qu'offre l'Internet aux développeurs d'application et aux concepteurs de protocole ? Le modèle de service de l'Internet n'a pas toujours été bien documenté, et les préjugés et idées fausses abondent chez les programmeurs (l'essentiel du RFC est d'ailleurs composé de l'exposé des affirmations erronées sur le modèle Internet.) En outre, l'Internet ayant crû de manière analogue à un écosystème, sans suivre strictement un plan pré-établi, ce modèle a largement changé, sans que ce changement n'ait été intégré par les développeurs. D'où ce RFC, qui ambitionne de documenter le modèle de service de l'Internet tel qu'il est en 2011. Ce RFC devrait être lu par tous les développeurs d'applications, afin qu'ils apprennent le service que leur offre réellement l'Internet.
Tout le monde sait que l'Internet offre un service de
niveau 3 (le protocole
IP). Même si les applications y accèdent en
général via un service de niveau 4 (typiquement
TCP), bien des caractéristiques de la couche 3
apparaissent aux applications (comme les adresses IP). (Le RFC utilise d'ailleurs parfois le terme
« application » pour parler de tout ce qui est au dessus de la couche 3.)
Quelles sont exactement les propriétés
de ce service ? Par exemple, les caractéristiques de la communication
(latence, taux de perte de paquets, etc) mesurées au début sont-elles
constantes (réponse : non) ? Quelle est la taille d'une adresse IP
(ceux qui répondent « quatre octets » peuvent abandonner
l'informatique pour l'élevage des chèvres en
Lozère) ? Si 192.0.2.81
se
connecte chez moi, pourrais-je me connecter à mon tour à cette machine
(réponse : plutôt oui, à l'origine, malheureusement non aujourd'hui) ?
Si certaines applications (par exemple une application qui inclus un
simple client HTTP pour récupérer un fichier
distant) peuvent ignorer sans problème ce genre de questions, pour
d'autres (logiciel de transfert de fichiers
pair-à-pair, client SIP,
etc), ces questions sont cruciales et les développeurs ne connaissent
pas forcément les bonnes réponses.
Revenons à l'histoire, comme le fait la section 1 du RFC. Le modèle original d'IP (et qui est encore souvent enseigné comme tel dans pas mal d'établissements d'enseignement) était partiellement documenté en 1978 dans l'IEN28 (les premières publications sur le TCP/IP actuel, les RFC 791 et RFC 793 ne sont venus qu'après). Un des principes était que les applications étaient très différentes mais que toutes tournaient sur IP, qui à son tour tournait sur tous les réseaux physiques possibles (modèle dit « du sablier », IP représentant le goulet d'écoulement du sablier). Ce modèle a nécessité plusieurs clarifications dans les RFC ultérieurs, par exemple le RFC 1122 en 1989 ou le RFC 3819. Résultat, aujourd'hui, il n'y a pas de document unique qui décrive le modèle de service, ce qu'offre IP aux applications.
Il est d'autant plus nécessaire de comprendre ce modèle qu'il est désormais difficile de le changer. Au début de l'Internet, on pouvait changer un concept et obtenir de tous les développeurs de toutes les applications de s'adapter. Aujourd'hui, la taille de l'Internet et son absence de centre rendent une telle opération impossible. L'Internet s'est ossifié.
Bon, en quoi consiste ce fameux « modèle de service » ? Il est décrit par la section 2. Un modèle de service est défini comme la description du service que rend une couche aux couches supérieures, ici le service que rend IP aux applications. Le schéma n° 1 résume cette notion de couches et la place d'IP dans l'architecture de l'Internet. Et le comportement d'IP ? Sa description officielle était dans la section 2.2 du RFC 791 : un service sans connexion (orienté paquets), acceptant des paquets de taille variable, et les délivrant (mais pas toujours) sans garantir leur ordre ou leur absence de duplication. Bref, un service qui « fait au mieux » (best effort dans la langue de Jack London). Les émetteurs n'ont pas besoin de se signaler aux destinataires ou au réseau avant d'émettre et les récepteurs n'ont pas besoin de signaler quoi que ce soit au réseau avant de recevoir.
On l'a dit, l'architecture réelle n'est plus vraiment celle du RFC 791, qui était de toute façon décrite de manière très brève dans ce RFC. D'autres documents ont approfondi la question comme le RFC 1958 ou comme le rapport « New Arch: Future Generation Internet Architecture » de 2004.
En fait, il est plus facile de décrire ce qu'il n'y a pas dans le modèle de service d'IP. La section 3, consacrée aux préjugés erronés, est donc beaucoup plus longue que la section 2. Je ne vais pas la répéter dans son entièreté mais simplement citer quelqu'uns de ces préjugés, en commençant par ceux concernant la connectivité.
Une des suppositions non dites les plus fréquentes dans les applications est que la possibilité d'envoyer un paquet (reachability) est symétrique (section 3.1.1). Un protocole comme FTP (RFC 959), avec sa notion de « voici mon adresse IP, rappelle-moi », repose largement là-dessus. Si la machine A peut envoyer un paquet à la machine B, le contraire est aussi vrai. Ce principe était largement vrai au début de l'Internet (attention, la possibilité d'envoyer était symétrique mais pas le chemin suivi) mais est tout à fait faux aujourd'hui. C'est même plutôt le contraire : la machine typique est coincée derrière un routeur NAT et un pare-feu qui empêchent tout envoi initié par l'extérieur. L'annexe A du RFC 5694 discute plus en détail ce problème et ses conséquences notamment pour les applications pair-à-pair. Bref, la seule chose que laquelle les applications peuvent relativement compter, est qu'une réponse à une requête initiée depuis l'intérieur a des chances d'arriver (c'est le modèle de HTTP). Les requêtes initiées de l'extérieur sont par contre impossibles dans le cas général (RFC 2993).
À noter que, même en l'absence de boîtiers intermédiaires qui bloquent les paquets, certains liens physiques ne sont pas symétriques, notamment en radio, comme l'illustre la section 5.5 du rapport « The mistaken axioms of wireless-network research ».
Autre supposition fréquente mais erronée, la transitivité. L'idée est que, si une machine A peut joindre B, et que b peut joindre C, alors A peut joindre C (section 3.1.2). Exactement comme pour la symétrie, ce principe était vrai au début, et ne l'est plus maintenant, en raison du NAT et des pare-feux, mais aussi de protocoles physiques comme 802.11 qui ne garantissent pas une telle transitivité.
Autre erreur que font certains développeurs d'applications, parce qu'ils confondent le modèle original de l'Internet et la triste réalité d'aujourd'hui, la conviction que les paquets signalant une erreur arriveront à l'émetteur du paquet qui a déclenché l'erreur (section 3.1.3). Ces paquets signalant une erreur sont typiquement portés par le protocole ICMP. Des exemples de leur usage ? La découverte de la MTU du chemin (RFC 1191 et RFC 1981) ou bien traceroute (RFC 1812).
Pourquoi ne peut-on plus compter sur ces messages ? D'abord, bien des routeurs ont été configurés pour limiter le rythme d'envoi, avant de rendre plus difficile leur utilisation dans une attaque DoS (RFC 2923, section 2.1. Ensuite, bien des pare-feux ont été stupidement configurés par des incompétents et bloquent tout l'ICMP (malgré les recommandations des RFC 2979, section 3.1.1, et RFC 4890). Résultat, il a fallu développer des mécanismes alternatifs pour la découverte de la MTU (RFC 4821).
Autre erreur : certaines applications croient qu'elles peuvent
utiliser la diffusion IPv4 pour transmettre un
message à toutes les machines (section 3.1.5). Autrefois, des adresses
comme 10.1.255.255
(les seize derniers bits tous à un) envoyaient en
théorie un message à toutes les machines du réseau
10.1.0.0/16
, et les routeurs devaient faire
suivre ce message au delà du lien local. Comme ce mécanisme facilitait
trop les attaques par déni de service, il a été abandonné par le RFC 2644 en 1999. Depuis, la diffusion ne marche plus que sur le
lien local. Et encore, car certains liens, dits
NBMA, ne la permettent pas. Plus drôle,
certains liens comme 802.11 en mode
ad hoc autorisent la diffusion mais, en
pratique, le message n'atteint pas toutes les machines du lien. Bref,
si on veut écrire à toutes les machines d'un groupe, il vaut mieux le
faire soi-même, sans compter sur la diffusion.
À ce sujet, la section 3.1.6 note que, contrairement à une croyance courante, un ensemble de paquets unicast n'est pas forcément plus coûteux ou moins rapide qu'un multicast ou qu'un broadcast. Sur les liens filaires traditionnels, un seul paquet multicast sera sans doute plus rapide. Ce n'est plus le cas sur les liens radio où le multicast devra être transmis au débit de base, même s'il existe des machines ayant une interface radio plus rapide, et qui a négocié un débit plus élevé.
Un problème subtil est causé par le cas où l'application compte sur la latence des paquets, par exemple pour faire de la visioconférence. Une application qui mesure cette latence peut avoir tendance à mesurer le premier paquet et à la considérer comme représentatif. Mais c'est souvent à tort (section 3.1.6). En effet, pour le premier paquet d'un flot de données, il y a souvent un temps d'établissement (dû à la résolution ARP, par exemple). Et ce sera pire avec les futurs systèmes de séparation de l'identificateur et du localisateur qui, tous, prévoient une forte latence pour le premier paquet, lorsqu'il faut résoudre l'identificateur en localisateur.
Autre caractéristique d'un chemin suivi par les paquets : le taux de réarrangement, qui mesure le fait que certains paquets arrivent avant des paquets partis plus tôt. Des études comme celle de Bennett, J., Partridge, C., et N. Shectman, « Packet reordering is not pathological network behavior » ou comme les RFC 2991 ou RFC 3819, section 15, montrent que le réarrangement a des conséquences pour les applications. Pour un programme de streaming, par exemple, il oblige à augmenter la taille des tampons. TCP voit ses performances se dégrader si les paquets n'arrivent pas dans l'ordre. Mais le réarrangement est un fait : des tas de raisons peuvent le causer (un routeur qui fait de la répartition de charges entre deux liens, par exemple) et les applications doivent s'y attendre.
Et le taux de pertes des paquets ? Sur quoi peut-on compter ? Beaucoup de gens pensent que les pertes sont rares, et probabilistiques (c'est-à-dire que le destin frappe un paquet au hasard, et qu'en reessayant, ça va marcher). Mais ce n'est pas forcément le cas (section 3.1.9). D'abord, si l'application a un comportement non-uniforme (des grands moments de silence, puis de brusques envois de nombreux paquets), les pertes se concentreront pendant ces envois, qui rempliront les files d'attente. Ensuite, il existe des phénomènes qui mènent à la perte préférentielle du premier paquet, comme ces routeurs de cœur qui, pour éviter une attaque DoS (envoi de paquets vers beaucoup d'adresses qui ne répondent pas), ne gardent pas en mémoire les paquets qui déclenchent une résolution ARP. Le premier paquet vers une nouvelle destination sera donc forcément perdu. Un autre exemple d'un comportement analogue est le Wake-on-LAN, où le paquet qui déclenche l'allumage de la machine n'est en général pas gardé.
L'Internet garantit-il qu'un chemin existe, à un moment donné, vers une destination (section 3.1.10) ? Oui, c'est toujours largement vrai. Mais cela cesse de l'être dans des réseaux exotiques comme les DTN (cf. RFC 4838) où deux machines pourront communiquer sans jamais être allumées en même temps. Avec humour, le RFC mentionne également le cas de réseaux où les paquets sont transportés par des animaux, peut-être une allusion au RFC 1149.
Pourquoi ces suppositions, qui étaient en général vraies autrefois, ont cessé de l'être (section 3.1.11) ? Il y a deux classes de raisons, une située dans les couches 1 et 2, et une autre placée dans la couche 3. Pour la première, le RFC 3819 donnait d'utiles conseils aux concepteurs de réseaux physiques. En gros, il indique une liste de services que doivent rendre les couches basses à IP et, si celles-ci ne le font pas, comment la couche d'adaptation à IP peut compenser. Ainsi, les RFC 3077 et RFC 2491 décrivent des mécanismes pour compenser l'absence d'atteignabilité symétrique et donc restaurer les services auquel s'attend IP. Mais toutes les couches basses ne le font pas : par exemple, il n'existe pas de moyen standard, lorsqu'une machine est connectée en WiFi ad hoc, de compenser le manque de symétrie dans les liens. Un mécanisme, situé sous IP, reste à élaborer.
Autre classe de causes pour lesquelles les suppositions d'autrefois ne sont plus forcément respectées, les raisons situées dans la couche 3 elle-même. Cela peut être une conséquence d'une politique de sécurité (RFC 4948), qui mène au filtrage. Cela peut être aussi à cause du NAT. Plusieurs applications font beaucoup d'efforts pour contourner ces problèmes. Cela semble une bonne application du principe de robustesse (« soyez strict dans ce que vous envoyez mais laxiste dans ce que vous acceptez »), et, en effet, les protocoles qui réussissent à contourner les limites de la couche 3 ont en général plus de succès que les autres (RFC 5218). Mais le principe de robustesse a aussi l'inconvénient de masquer les problèmes, et de diminuer la pression pour les résoudre. Par exemple (qui n'est pas dans le RFC), Skype réussit à passer via des hotspots où seul le port 80 fonctionne en sortie, donc les clients de ces hotspots ne râlent pas contre l'opérateur de ce dernier et celui-ci continue donc à fournir un service de daube. Le RFC suggère, pour sortir de ce dilemme, de fournir un mode spécial pour l'application, activable à la demande, où l'application n'utilisera que des techniques propres et officielles, permettant ainsi de déboguer les réseaux mal fichus, sans que leurs problèmes soient masqués.
Cela, c'était pour la connectivité. Et pour l'adresssage ? La section 3.2 rassemble les suppositions erronées les plus fréquentes sur ce sujet.
D'abord, bien des applications considèrent l'adresse IP
comme stable sur une assez longue période (ce qui était vrai
autrefois, où les adresses étaient toutes fixes et configurées
manuellement). Cette supposition (section 3.2.1) se reflète dans
l'API : par exemple,
getaddrinfo()
ne fournit pas
d'indication sur la durée de validité de l'adresse récupérée. Même
avec plein de bonne volonté, l'application ne peut pas savoir si
l'adresse IP récupérée en échange du nom peut être conservée pour une
minute, une heure ou un jour (la plupart des applications appelent
getaddrinfo()
et ne remettent jamais en cause son
résultat, gardant l'adresse IP pendant toute leur durée de vie, un
phénomène connu sous le nom d'épinglage - pinning -
et qui peut avoir des conséquences pour la sécurité).
Or, aujourd'hui, avec des techniques comme DHCP, les adresses ne sont pas stables et changent, notamment lorsque la machine se déplace. Cela casse des applications comme SSH. Plusieurs protocoles ont été proposés pour conserver un identificateur stable même lorsque le localisateur change (par exemple HIP).
Encore plus répandue, l'idée comme quoi une adresse IP ferait
quatre octets (section 3.2.2). Faites le test lors d'un entretien d'embauche :
demandez au candidat à écrire un petit programme
C qui gère des adresses
IP. S'il déclare une variable de type uint32_t
, cela
montre qu'il ne connait pas IP (si la variable est de type
int
, cela montre qu'il ne connait pas
C...). Cette idée était juste il y a douze ans, mais ne l'est plus
depuis que l'Internet est redevenu multi-protocole, avec la
coexistence d'IPv4 et
IPv6 (dont les adresses font seize octets).
Plus subtile, la question du nombre d'adresses par interface. Pas mal de programmeurs tiennent pour acquis que « l'adresse IP identifie une interface » (ce qui est faux) et écrivent un code qui ne gère pas vraiment le cas d'adresses multiples. Ce préjugé n'a jamais été réellement justifié (le RFC 791 mentionne explicitement la possibilité d'avoir plusieurs adresses IP par interface) mais il l'est encore moins maintenant, où l'existence de plusieurs adresses IP sur une interface est devenue banale (surtout pour IPv6). On note que HIP, cité plus haut, donnerait raison au préjugé, s'il était déployé massivement : l'identificateur serait en effet unique (par machine virtuelle).
En parlant de l'idée d'une adresse IP par machine, si une machine peut avoir plusieurs adresses IP, est-ce qu'une adresse IP peut être utilisée par plusieurs machines ? Cela mène à la notion d'identité d'une machine. Ce concept n'existe pas réellement dans les protocoles TCP/IP mais pas mal d'applications font comme si (section 3.2.4). Par exemple, une ACL sur un pare-feu, bloquant une adresse IP, signifie que l'administrateur du pare-feu considère que l'ennemi peut être identifié par son adresse IP, ce qui n'est pourtant pas toujours le cas.
Parmi les évolutions technologiques qui empêchent ce préjugé d'être exact : l'anycast (RFC 4786), ou bien certaines solutions de haute disponibilité. Des RFC comme le RFC 2101 ou le RFC 2775 discutent de cette question de l'unicité de l'adresse.
Plus ridicule mais néanmoins fréquente, l'idée que l'adresse IP d'une machine identifie sa position géographique (section 3.2.5). C'est clairement faux aujourd'hui (pensez aux tunnels, par exemple).
Plus subtile, l'idée que l'adresse IP a un rapport avec le routage (section 3.2.6). Par exemple, une application qui déduirait de la proximité de deux adresses la proximité des machines. Avec des protocoles comme Mobile IPv6 ou HIP (déjà cité), cette supposition serait complètement fausse. D'une manière générale, tout système de séparation de l'identificateur et du localisateur casserait cette idée. Dans les textes originels (IEN019 ou IEN023),l'adresse IP était présentée comme un localisateur, alors que TCP, par exemple, l'utilise comme identificateur. C'est là la source de cette confusion d'aujourd'hui.
Ces erreurs sur l'adressage sont fréquentes. La section 3.2.10
fournit une perspective plus large, en partant du RFC 1958, dont la section 4.1 avait été le premier texte à
insister sur l'importance d'utiliser des noms plutôt que des adresses
(celles-ci ayant une sémantique trop floue). Notre RFC 6250 réinsiste fortement sur ce point : c'est bien à tort que des
API comme
getaddrinfo()
exposent les adresses
IP aux applications. La plupart du temps, celles-ci ne devraient pas
avoir accès à ces adresses, ce qui éliminerait la tentation de les
utiliser de manière incorrecte. Ceci dit, le conseil du RFC 1958 n'est pas possible à suivre intégralement aujourd'hui :
bien des machines IP (au hasard, mon téléphone portable) n'ont pas de
FQDN à elles.
On l'a vu, le terme « applications », dans ce RFC 6250 est utilisé de manière souple, pour décrire tout ce qui se trouve au dessus de la couche 3. la section 3.3 aborde les problèmes spécifiques à une partie de ces « applications », la couche transport (couche 4). Quelles sont les erreurs courantes à propos de cette couche 4 ?
D'abord, un certain nombre d'acteurs de l'Internet croient qu'il est possible d'ajouter de nouveaux protocoles de transport, des concurrents des classiques TCP et UDP (section 3.2.1), tels que ceux enregistrés à l'IANA. C'était certainement le but originel de l'architecture de TCP/IP. Mais, aujourd'hui, ce n'est plus vrai. L'Internet s'est terriblement ossifié et les nouveaux protocoles de transport ont très peu de chances de passer à travers toutes les middleboxes mal fichues qui abondent sur le réseau. Souvent, on doit même tout tunneler au dessus d'HTTP. C'est au point où le RFC suggère même de ne pas hésiter à normaliser cette utilisation de HTTP (quelque chose que, traditionnellement, l'IETF avait toujours refusé de faire, au nom de la qualité technique des normes). XMPP le fait, par exemple, dans son XEP 0124. SIP n'a pas de méthode standard pour cela, et ça lui a parfois été reproché, alors que le système fermé Skype n'hésite pas à détourner HTTP. Un groupe de travail de l'IETF, HyBi, travaille sur un mécanisme générique d'utilisation de HTTP pour contourner ces middleboxes stupides.
Bref, le point le plus étroit du sablier, celui par lequel tout devait passer, et qui était IP dans l'architecture originale, est de plus en plus souvent TCP, voire HTTP. C'est parfois fait au nom de la sécurité (par des gens qui ne connaissent pas forcément ce sujet). L'IETF continue ses efforts pour casser cette dangereuse évolution mais, au cas où ces efforts ne seraient pas couronnés de succès, il faut se préparer à s'adapter.
En parlant de sécurité, quelles sont les idées reçues sur la sécurité (section 3.4) ? Elles sont évidemment nombreuses (et une analyse plus complète figure dans le RFC 3552). Par exemple, bien des applications se comportent encore comme si les paquets n'étaient jamais modifiés en route, à part pour quelques champs bien définis comme le TTL. Le NAT change malheureusement cette situation. On peut parfois restaurer le comportement correct avec des tunnels (RFC 4380) ou avec IPsec en mode transport (RFC 4301).
À défaut d'être respectés dans leur intégrité, les paquets sont-ils au moins privés (section 3.4.2) ? Pas davantage. Il a toujours été possible d'écouter les communications et pourtant on trouve toujours des protocoles et des applications qui s'obstinent à envoyer des mots de passe en clair. Là encore, IPsec, s'il était déployé, pourrait fournir une solution générique, ne nécessitant pas de changer les applications.
Autre erreur que font souvent les débutants en sécurité : croire
que, puisqu'un paquet prétend venir de
198.51.100.66
, alors c'est vrai (section
3.4.3). La vérité est qu'il est relativement facile de mettre une
fausse adresse IP source (la plupart des lecteurs de mon blog le
savent depuis longtemps mais on trouve pourtant régulièrement des
articles qui parlent d'une attaque par déni de service en disant
« elle vient de tel pays » simplement parce que les adresses IP source
indiquent ce pays). Il existe des mécanismes techniques qui pourraient
permettre d'avoir des adresses sûres, par exemples les adresses
cryptographiques du RFC 3972.
En conclusion, que faut-il retenir de ce RFC ? La section 5 fournit les points essentiels :
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : A. Morton (AT&T Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 15 avril 2011
Le progrès, c'est aussi de savoir reconnaître quand une idée était mauvaise et qu'il vaut mieux l'abandonner. Ce court RFC prend ainsi acte de l'échec du registre des métriques lancé par le RFC 4148 et décide d'y renoncer.
Le groupe de travail IPPM est chargé notamment de développer des métriques (définitions rigoureuses d'une grandeur qu'on peut mesurer) comme le taux de perte des paquets (RFC 7680). Dans le cadre de ce travail, il avait semblé intéressant, avec le RFC 4148 de créer un registre IANA des métriques existantes. En fait, aucun logiciel n'a été développé pour l'utiliser, aucun utilisateur de ce registre n'a pu être identifié après des mois de recherche (fin 2010), et le registre était donc déjà de facto abandonné avant que notre RFC 6248 le reconnaisse et ne le decrète dépassé. Un exemple montrant l'inutilisation du registre ? Le fait qu'il contenait une faute de syntaxe qui a mis huit mois (depuis la parution du RFC 5644) avant d'être signalée ! Cette décision d'abandon explicite est nécessaire pour éviter d'accumuler dans les registres IANA un grand nombre d'informations qui ne sont plus maintenues.
Notre RFC rappelle d'abord quelles étaient les motivations qui avaient mené à la création du registre : la grande variabilité des définitions de métriques, d'autant plus que certaines étaient modifiées et/ou enrichies par des RFC ultérieurs comme le RFC 3432. Stocker ces variations dans un registre semblait une bonne idée sauf que, en pratique, la structure du registre n'avait pas permis de stocker toute l'information.
Le registre ne sera donc plus mis à jour (le dernier RFC à l'avoir fait avait été le RFC 6049) même s'il continue à être distribué par l'IANA mais avec un texte montrant sans ambiguité son statut.
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : L. Eggert (Nokia)
Pour information
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 17 mai 2011
Grand nettoyage à l'IETF, plus précisement au sein du groupe de travail TCP Maintenance and Minor Extensions. Huit RFC sur le protocole TCP sont rangés dans la cave de l'IETF, en étant reclassés comme « Document d'intérêt historique seulement ».
La famille de protocoles TCP/IP est bien vivante. La preuve, il y a régulièrement des protocoles ou des extensions aux protocoles qui apparaissent. Mais, pour que l'évolution fonctionne, il faut aussi que certains disparaissent. C'est ce qui vient d'arriver à huit extensions du protocole TCP, qui avaient été normalisées, avaient parfois suscité beaucoup d'espoirs, mais ont ensuite été des échecs. Peu de déploiements, des sérieux problèmes identifiés a posteriori, et voici ces extensions vouées au statut « Historique ». La plus récente, le RFC 1693, datait de 1994... Ces huit RFC perdent donc tout droit au nom de « norme ». Les raisons de ce reclassement figurent en général dans la section 5 du RFC 4614, qui avait fait un tour d'horizon complet et critique de tous les RFC sur TCP.
Parmi les RFC ainsi rabaissés, notons le RFC 1644, qui normalisait l'extension T/TCP qui semblait à une époque pouvoir fournir un TCP léger et rapide, mais qui a montré de sérieuses failles de sécurité à l'usage.
Conséquence pour l'IANA, certaines options enregistrées dans le registre des options TCP, comme les options 6 et 7, du RFC 1072, sont désormais marquées comme « dépassées ».
Date de publication du RFC : Juin 2011
Auteur(s) du RFC : R. Enns (Juniper Networks), M. Bjorklund (Tail-f Systems), J. Schoenwaelder (Jacobs University), A. Bierman (Brocade)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF netconf
Première rédaction de cet article le 1 juillet 2011
Netconf est un protocole de configuration de matériel réseau (typiquement des routeurs ou des commutateurs). Ce RFC est la nouvelle version publiée par le groupe de travail IETF sur Netconf. (La precédente était le RFC 4741.)
Si on doit gérer un seul routeur, le faire à la main est raisonnable. Mais, si on doit en gérer des dizaines ou des centaines, cela devient impossible sans automatisation. Il existe depuis longtemps de nombreux outils pour gérer un grand nombre d'équipements réseaux, Rancid étant le plus connu. (L'excellent article de Joe Abley, Managing IP Networks with Free Software en donne un bon aperçu. Le RFC 3535 rend compte d'un atelier de l'IAB qui a discuté de ces questions en 2002.) Netconf vise à rendre l'écriture de ces outils plus simple.
Netconf spécifie donc un protocole de RPC permettant à un gérant (manager) de modifier la configuration de l'équipement (device) en lui envoyant du XML.
Le contenu exact de ce document XML n'est pas entièrement spécifié par Netconf car il dépend de l'équipement configuré (la section 1.2 de notre RFC explique ce point). Un langage de description des modèles, Yang (RFC 6020), existe pour décrire les possibilités.
Extrait du RFC, voici un exemple (hypothétique) où on fixe à 1500
octets la
MTU de l'interface réseau
eth0
:
<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config> <target> <running/> </target> <config> <top xmlns="http://example.com/schema/1.2/config"> <interface> <name>eth0</name> <mtu>1500</mtu> </interface> </top> </config> </edit-config> </rpc>
Il est difficile de ne pas penser à l'acronyme NIH en lisant ce RFC. Netconf définit un protocole de RPC alors qu'il existe déjà SOAP et XML-RPC, Netconf définit en section 6, un mécanisme d'extraction de sous-arbres XML alors que XPath existe déjà...
Quels sont les changements depuis le RFC
original ? L'annexe F les résume. Pas de grand changement, des bogues
signalées contre le RFC 4741 et quelques
ajouts : un malformed-message
ajouté aux messages
d'erreur possibles, une option remove
ajoutée aux
opérations possibles, l'ajout de la notion de « nom d'utilisateur »,
le schéma XSD de modélisation des opérations remplacé par un module
YANG, etc.
À noter qu'un Wiki, http://trac.tools.ietf.org/wg/netconf/trac/wiki
, fournit plein
d'informations sur Netconf, notamment sur les mises en œuvre
existantes du protocole, dont certaines en logiciel libre. Parmi les
autres, les routeurs Juniper peuvent déjà être
configurés avec Netconf (et une bibliothèque
Java est fournie). Ça marche aussi sur
un Cisco.
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : D. M'Raihi (Verisign), S. Machani
(Diversinet), M. Pei
(Symantec), J. Rydell (Portwise)
Pour information
Première rédaction de cet article le 7 juin 2019
Ce RFC documente le protocole TOTP, utilisé pour bâtir des systèmes d'authentification à deux facteurs. TOTP est une amélioration du protocole HOTP du RFC 4226, remplaçant le simple compteur par l'heure. Ainsi, il n'est plus nécessaire que les deux machines mémorisent la même séquence.
Mais d'abord, qu'est-ce que l'authentification à deux facteurs ? Imaginons que vous vous connectiez à une interface Web, d'un établissement financier comme Paymium ou PayPal, d'un bureau d'enregistrement de noms de domaines, ou de tout autre service important. La méthode la plus courante d'authentification est le couple {identificateur, mot de passe}. Elle est simple, et facilement expliquable aux utilisat·rice·eur·s. Mais elle pose des problèmes de sécurité : le mot de passe choisi est souvent trop faible, et les utilisat·rice·eur·s le communiquent parfois à des tiers, par exemple suite à une attaque par ingéniérie sociale. On dit traditionnellement qu'il existe trois voies d'authentification : ce qu'on est, ce qu'on a, ou bien ce qu'on sait. La biométrie utilise la première voie, et le mot de passe la troisième. TOTP, décrit dans ce RFC, va permettre d'utiliser la deuxième voie. Mais on n'utilise pas TOTP seul. Le principe de l'authentification à deux facteurs est d'avoir… deux facteurs. Par exemple, sur le Web, le cas le plus courant est un mot de passe classique, plus un code produit par TOTP. Les deux facteurs doivent évidemment être indépendants. Si on se connecte à sa banque depuis son ordiphone et que le générateur TOTP est sur le même ordiphone, il n'y a pas réellement d'indépendance (si le téléphone est volé ou piraté, les deux facteurs peuvent être compromis en même temps). Une solution est d'avoir mot de passe sur l'ordinateur et générateur TOTP sur l'ordiphone, ou bien mot de passe sur l'ordiphone et générateur TOTP sur un dispositif auxiliaire, genre YubiKey.
Pour prendre un exemple récent, lors de l'attaque de 2018 contre de nombreux noms de domaine moyen-orientaux, l'absence d'authentification à deux facteurs avait certainement joué, rendant relativement facile le piratage en masse.
Mais comment fonctionne TOTP ? L'idée de base est qu'on part d'un secret partagé entre les deux parties, le client et le serveur, secret qui n'est pas envoyé pour l'authentification (et donc moins vulnérable qu'un mot de passe). Ce secret sert à générer un code à usage limité dans le temps (donc, si vous l'avez envoyé au pirate par erreur, ce n'est pas forcément grave). Dans l'ancien protocole HOTP (RFC 4226), la génération du code était contrôlée par le nombre de connexions au service (et il fallait donc que les deux parties communicantes gardent trace du nombre de connexions, et soient bien synchrones sur ce point), dans le nouveau protocole TOTP, objet de ce RFC, c'est l'heure qui gouverne le code généré (et les deux parties doivent donc avoir des horloges à peu près correctes).
Voici ce que voit l'utilisateur avec le logiciel andOTP sur Android. On voit la liste des comptes de l'utilisateur (j'ai masqué les identifiants de l'utilisateur, bien qu'ils ne soient pas totalement secrets), et le code courant (je l'ai partiellement masqué mais notez que ce n'est pas nécessaire : ils ne sont utilisables que pendant le bon intervalle).
Un petit rappel sur HOTP : HOTP, normalisé dans le RFC 4226, le code à usage unique était généré en condensant avec SHA-1 la concaténation d'un secret partagé et d'un compteur, chaque partie incrémentant le compteur lors d'une connexion. Il y a donc un risque de désynchronisation si une partie incrémente le compteur alors que l'autre a eu un hoquet et a raté cette incrémentation (RFC 4226, section 7.4).
TOTP, au contraire, utilise un condensat du secret partagé et de l'heure. Il est en effet plus facile d'avoir deux machines ayant une horloge à peu près correcte que d'avoir deux machines restant en accord sur un compteur partagé. (D'autre part, TOTP peut utiliser SHA-2 et plus seulement SHA-1.)
La section 3 du RFC résume quel était le cahier des charges de TOTP : dépendance vis-à-vis de l'heure (plus précisement du temps Unix), avec un intervalle de validité partagé, dépendance vis-à-vis d'un secret partagé entre les deux parties (et avec personne d'autre), secrets qui doivent être bien gardés par les deux parties.
L'algorithme exact (j'ai beaucoup simplifié ici) est en section 4. Un code TOTP est la
condensation avec SHA-2 de la concaténation
du secret partagé et de l'heure, plus exactement du nombre de
secondes depuis l'epoch, divisée par
l'intervalle. Ainsi, pour un même couple client/serveur, deux
demandes de code très rapprochées donneront le même code,
contrairement à HOTP où les codes n'étaient pas réutilisés. Notez
que les valeurs de l'epoch et de l'intervalle ne
sont pas spécifiées dans le protocole, elle sont communiquées en
dehors du protocole. On ne peut donc pas utiliser TOTP seul et
espérer que cela va marcher, il faut ajouter des informations. Cela peut se faire via des cadres de
référence comme OATH ou bien dans
l'URI fabriqué par le serveur (par exemple
otpauth://totp/ACME%20Co:john.doe@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&period=60
pour mettre un intervalle à soixantes secondes, le format exact de
ces URI est
documenté
par Google.)
La section 5, sur la sécurité, est évidement très détaillée. Elle rappelle par exemple que la transmission du secret initial doit être faite sur un canal sécurisé, par exemple avec TLS. D'autre part, ce secret, cette clé, doit être stockée de manière sûre. Si on utilise un ordiphone pour générer les codes, ce qui est fréquent, il faut tenir compte du fait qu'un ordiphone se perd ou se vole facilement. Il ne doit pas divulguer le secret simplement parce qu'un voleur a l'appareil en main. Le RFC recommande que le secret soit chiffré, et de manière à ce que la possession physique de la machine ne permettre pas de le déchiffrer. (Dans andOTP, la base de données est chiffrée avec un mot de passe choisi par l'utilisateur. À l'usage, il est assez pénible de taper ce mot de passe - forcément long et compliqué - très souvent, mais c'est le prix de la sécurité.)
TOTP repose sur l'heure et non seulement les deux horloges ne sont pas parfaitement synchrones mais en outre les délais de transmission du réseau ajoutent une incertitude. On pourrait mettre un intervalle important (la valeur recommandée est de 30 secondes) pour limiter le risque de rejet d'un code mais, d'une part, cela augmente le risque qu'un code volé puisse être réutilisé (il reste valable pendant tout l'intervalle) et d'autre part on peut jouer de malchance, par exemple si un code est généré juste avant la fin d'un intervalle. Le RFC recommande donc d'accepter les codes de l'intervalle précédent l'intervalle courant.
L'annexe A du RFC contient une mise en œuvre de TOTP en Java (avec au moins une bogue).
Pour envoyer, lors de l'enrôlement initial, le secret partagé qui servira de base au calcul, la méthode la plus courante est que le serveur auprès duquel on s'authentifiera la génère, puis l'affiche sous forme d'un QR-code à lire, ou sous une forme texte. Voilà comment ça se passe chez le bureau d'enregistrement Gandi. On active l'authentification à deux facteurs :
Puis on fait lire à son ordiphone le secret (j'ai masqué QR-code et secret en texte, puisqu'ils doivent rester secrets) : )
Bien d'autres services sur le Web acceptent l'authentification à deux facteurs. C'est le cas entre autres de GitLab (et donc de l'excellent service Framagit) dans la rubrique « Compte », des places de marché Bitcoin comme Kraken (qui le documente très bien) ou Paymium (qui, stupidement, ne le documente que comme imposant l'utilisation de Google Authenticator, ce qui est faux, ça a marché avec andOTP, remarquez, Mastodon commet presque la même faute), des registres comme le RIPE (qui documente également très bien), etc. En revanche, les banques, comme le Crédit mutuel ou la Banque postale, imposent un outil privateur, sous forme d'une application fermée, exigeant trop de permissions, et contenant des pisteurs. (Alors que le but des normes comme TOTP est justement de permettre le libre choix du logiciel. Mais un tel mépris du client est classique chez les banques.)
Côté client, j'ai choisi andOTP sur mon
ordiphone mais il y a aussi Aegis, FreeOTP, Google
Authenticator, etc. Si vous êtes fana de la ligne
de commande, vous pouvez même directement utiliser
l'outil oathtool présenté plus loin, comme décrit
dans cet article (avec un astucieux script pour analyser les
URI otpauth:
). Il y a aussi des mises en œuvre
privatrices dans du matériel spécialisé comme la YubiKey (à partir de 35 € à l'heure actuelle.)
TOTP est à l'origine issu du projet OATH (ne pas confondre avec OAuth.) Une de leurs initiatives est le développement d'outils logiciels pour faciliter le déploiement de techniques d'authentification fortes. C'est par exemple le cas de l'outil libre oathtool et des autres logiciels du OATH Toolkit. Voici une utilisation sur une Debian (le paramètre à la fin est la clé, le secret partagé) :
% oathtool --totp=sha256 123456789abcde 839425
Si on le lance plusieurs fois de suite, il affichera le même code, jusqu'à la fin de l'intervalle en cours :
% oathtool --totp=sha256 123456789abcde 839425 % oathtool --totp=sha256 123456789abcde 839425 % oathtool --totp=sha256 123456789abcde 839425 % oathtool --totp=sha256 123456789abcde 963302
Par défaut, oathtool utilise l'horloge courante. On peut lui indiquer une autre heure (cf. sa documentation mais attention à ne pas copier/coller les exemples, ça ne marchera pas, les tirets ayant été remplacés par des caractères typographiquement plus jolis, menant à un « hex decoding of secret key failed » incompréhensible). Essayons avec les vecteurs de test indiqués dans l'annexe B de notre RFC :
% oathtool --totp=sha256 --digits=8 3132333435363738393031323334353637383930313233343536373839303132 62307269 % oathtool --totp=sha256 --digits=8 --now "1970-01-01 00:00:59 UTC" 3132333435363738393031323334353637383930313233343536373839303132 46119246
(Et, oui, les valeurs de la clé secrète indiquées dans le RFC sont fausses.)
Notez aussi que oathtool fait par défaut du HOTP (ici, au démarrage, puis au bout de cinq connexions) :
% oathtool 123456789abcde 725666 % oathtool --counter=5 123456789abcde 030068
Pour configurer un serveur ssh avec TOTP et l'outil de gestion de configuration Salt, vous pouvez utiliser la recette de Feth Arezki.
Si on veut déveloper des services utilisant TOTP, il existe plein d'autres mises en œuvre comme ROTP pour Ruby, onetimepass ou otpauth pour Python, etc. Pour apprendre à utiliser TOTP depuis Python, j'ai apprécié cette transcription de session.
Il ne faut pas croire que l'authentification à deux facteurs est une solution magique. Comme toujours en sécurité, elle vient avec ses propres inconvénients. (Ils sont très bien expliqués dans l'excellent article « Before You Turn On Two-Factor Authentication… ».) Le risque le plus sérieux est probablement le risque de s'« enfermer dehors » : si on perd l'ordiphone ou la clé physique, ou bien s'il tombe en panne, tout est fichu, on ne peut plus se connecter sur aucun des services où on a activé l'authentification à deux facteurs. Une seule solution : les sauvegardes. Avec andOTP, par exemple, on peut exporter la liste des comptes et leurs secrets dans un fichier en clair (ce qui est évidemment déconseillé), chiffré avec AES et le mot de passe d'andOTP, ou bien chiffré avec PGP, la solution la plus pratique. J'ai installé openKeychain sur mon Android, récupéré ma clé PGP et tout marche, les sauvegardes, une fois exportées, sont copiées sur d'autres machines. Si je déchiffre et regarde en quoi consiste la sauvegarde, on y trouve un fichier JSON contenant les informations dont nous avons déjà parlé (la clé secrète), le type d'algorithme, ici TOTP, l'algorithme de condensation, l'intervalle (period), etc :
{ "secret": "K...", "label": "framagit.org - framagit.org:stephane+frama@bortzmeyer.org", "digits": 6, "type": "TOTP", "algorithm": "SHA1", "thumbnail": "Default", "last_used": 1559836187528, "period": 30, "tags": [] }
Si on veut utiliser ces sauvegardes depuis l'outil en ligne de commande présentée plus haut, il faut prendre note de l'algorithme de condensation (ici SHA-1), du nombre de chiffres (ici 6) et de la clé (qui est encodée en base32) :
% oathtool --totp=sha1 --digits 6 --base32 K...
Sinon, je recommande cet article en anglais très détaillé : « Understanding TOTP Two-Factor Authentication: An ELI5 », avec une mise en œuvre en Python.
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : E. Boschi, B. Trammell (ETH Zurich)
Expérimental
Réalisé dans le cadre du groupe de travail IETF ipfix
Première rédaction de cet article le 14 mai 2011
La question de la protection de la vie privée sur l'Internet est, à juste titre, une question très sensible et qui a déjà agité beaucoup d'électrons sur les blogs et autres sites Web, d'autant plus que de grosses et puissantes entreprises, comme Facebook et Google sont à l'œuvre pour réduire cette vie privée à pas grand'chose. Parmi toutes les problèmes pratiques que pose la protection de la vie privée, ce RFC se limite à celui des fichiers de trafic réseau, contenant des données sensibles et qu'on souhaite anonymiser. Le RFC se concentre sur le format IPFIX mais la plupart des problèmes exposés et des recommandations faites peuvent s'appliquer à d'autres formats comme les journaux de connexion ou comme les fichiers pcap. Un RFC utile, donc, pour tous les techniciens qui se soucient de la vie privée de leurs utilisateurs (et qui n'ont donc pas été embauchés par Facebook).
« Anonymiser » n'est pas un bon terme (mais je reprends celui du RFC). Tout le problème est qu'en effet les données ne sont pas réellement anonymes après cette opération : il est devenu simplement plus difficile de les relier à une personne ou une organisation donnée. Mais ce n'est pas impossible : de nombreux travaux de recherche ont montré qu'on pouvait reconstituer une bonne part des données manquantes dans un fichier « anonymisé ». Un exemple est l'excellent article de Bruce Schneier : « Why 'Anonymous' Data Sometimes Isn't » qui montre très bien à quel niveau de perfectionnement les outils de « désanonymisation » sont parvenus.
Avant d'attaquer le RFC lui-même, commençons par un exemple simple. Supposons qu'on ait enregistré le trafic réseau en un endroit donné et qu'on récupère donc un fichier pcap. On peut le dire avec divers outils comme tcpdump et voici un résultat typique :
% tcpdump -n -v -r MYFILE.pcap ... 15:00:24.451549 IP (tos 0x0, ttl 64, id 17621, offset 0, flags [DF], proto TCP (6), length 1059) 192.168.2.1.41949 > 193.159.160.51.80: Flags [P.], cksum 0xd268 (correct), seq 1029:2036, ack 247, win 108, options [nop,nop,TS val 2792071 ecr 1944126014], length 1007
On peut y voir que 192.168.2.1
interrogeait le
serveur HTTP
193.159.160.51
(un des serveurs
d'Akamai, qui héberge
www.wired.com
, le site cité précedemment). On sait
que c'était de l'HTTP par le port de
destination (80) mais on aurait aussi pu le déduire en examinant les
données (que tcpdump n'affiche pas, mais qui sont bien dans le fichier
pcap et qu'un outil comme Wireshark peut
afficher de manière très lisible ; ces mêmes données auraient pu nous
dire qu'elle était la page Web exacte qui avait
été consultée). Autre exemple, le journal d'un
serveur HTTP où on trouvera des choses comme :
2001:db8:33::dead:beef:1 - - [10/May/2011:19:49:57 +0200] "GET /aventures-jules.html HTTP/1.1" 200 5306 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1" www.bortzmeyer.org
qui nous indique que la machine d'adresse IP 2001:db8:33::dead:beef:1
a
consulté la page aventures-jules.html
de ce
serveur. Ces informations sont-elles
sensibles ? D'abord et avant tout sont-elles
nominatives, ce qui, dans la loi
Informatique & Libertés ne se limite pas
aux informations comportant le nom d'une personne physique, mais
inclut celles qui permettent de retrouver facilement cette personne
(comme le « numéro de Sécu »). Ici, l'adresse IP source
n'est pas la vraie (les données ci-dessus ont été anonymisées) mais,
si elle l'était, elle permettrait assez facilement de retrouver
l'auteur de cette visite à Wired et donc il est
tout à fait justifié de considérer l'adresse IP comme nominative.
Et c'est embêtant pour les chercheurs et les analystes. Car de telles données de connexion sont très utiles et de nombreux articles scientifiques intéressants ont été produits à partir de données comme celles-ci, collectées dans des grandes opérations comme le DITL. De même, les opérateurs réseaux ont souvent besoin d'analyser ces données pour mieux comprendre ce qui se passe dans leur réseau et pour l'améliorer. Enfin, l'étudiant, le curieux, le programmeur qui met au point un nouvel outil d'analyse ont besoin de telles données (on trouve par exemple plein de fichiers pcap sur pcapr.net). Mais transmettre ces données, les rendre publiques, les envoyer dans un pays qui n'a aucune législation de protection de la vie privée, comme les États-Unis, pose des problèmes éthiques et légaux considérables.
Une façon courante de concilier ces deux demandes est d'anonymiser les données. Par exemple, si on supprime l'adresse IP, on a enlevé la donnée la plus sensible, tout en permettant encore plusieurs analyses (par exemple sur la taille des paquets, sur les ports - donc, souvent, les services - les plus fréquents, etc. Mais en faisant cela, on a interdit certaines analyses, comme par exemple la répartition du trafic (tout le monde consomme t-il pareil, ou bien certains gros consommateurs sont-ils « responsables » de la majorité du trafic ?) Bref, l'anonymisation sera toujours un compromis : plus on retire de données et mieux on a anonymisé. Et plus les données perdent de leur intérêt... Il faudra donc prendre une décision en fonction des risques et des bénéfices. L'IETF n'a évidemment pas le pouvoir de prendre une telle décision mais ce RFC pose au moins les bases techniques nécessaires pour comprendre les choix. Il insiste notamment sur les techniques de désanonymisation, qui font que certaines techniques d'anonymisation ne protègent guère la vie privée.
Pour prendre l'exemple des requêtes DNS, si
on peut croire que l'adresse IP source (qui est celle du résolveur,
par celle du client final) n'est pas une information bien sensible, il
ne faut pas oublier que le contenu de la requête
(le QNAME
, pour Query NAME)
peut en dire beaucoup. Par exemple, certains réseaux sociaux utilisent
un sous-domaine qui a le nom de l'utilisateur.
Passons au RFC maintenant. Il a deux parts, une première générale sur les techniques d'anonymisation, leurs forces et leurs faiblesses et une seconde spécifique au format IPFIX (RFC 7011). La première partie intéresse tous les programmeurs et récolteurs de données. Le fait d'avoir un format standard, IPFIX, pour les échanges d'information sur les flots de données (pcap - un standard de fait - est limité aux paquets individuels, une information de plus bas niveau) est évidemment un avantage pour tous ceux qui font circuler de l'information mais cela augmente aussi les risques de divulgation. D'où l'importance particulière de ce problème pour IPFIX.
Commençons par une définition rigoureuse de l'anonymisation (qu'il faudrait normalement écrire entre guillemets à chaque fois, tellement on est loin du vrai anonymat). La section 1 la définit comme la suppression ou la transformation d'une information qui, sans cette suppression ou cette transformation, pourrait permettre d'identifier la personne ou de l'organisation à l'origine d'une communication. Il ne faut pas utiliser l'anonymisation seule (elle a des tas de limites, notamment en raison de la puissance des techniques de désanonymisation) mais elle peut être un outil utile dans un arsenal de mesures de protection de la vie privée.
La section 1.4 rappelle d'ailleurs que ce RFC a le statut « Expérimental » car il considère que toutes les techniques d'anonymisation sont encore peu fiables (voir Burkhart, M., Schatzmann, D., Trammell, B., et E. Boschi, « The Role of Network Trace Anonymization Under Attack »).
La première partie de ce RFC revient sur ces techniques, d'une manière indépendante du format des données (pcap, IPFIX, etc). D'abord, la section 3 classifie les techniques d'anonymisation. Toutes ont en commun de chercher à empêcher la traçabilité, tout en préservant les informations utiles à l'analyse. Elles fonctionnent par mise en correspondance de l'espace des vrais valeurs vers un autre espace, « anonyme », suivant une fonction bien définie. La mise en correspondance est récupérable si on peut inverser cette fonction (ce qu'on ne souhaite évidemment pas, pour l'anonymisation) et commensurable (ou mesurable) si les deux espaces ont la même taille (préservant ainsi toutes les analyses qui cherchent à compter, par exemple le nombre d'adresses IP distinctes). Ainsi, une fonction de généralisation qui ne garderait que les N premiers bits de l'adresse IP (pour empêcher l'identification d'un individu) ne serait pas commensurable (plusieurs adresses IP seraient mises en correspondance avec un préfixe unique). Lorsque la fonction est commensurable, la technique d'anonymisation est appelée une substitution (je change chaque adresse IP par une autre). Notez que la substitution est vulnérable aux attaques par force brute, même si l'attaquant ignore la fonction utilisée, s'il peut injecter le trafic qu'il veut et observer les résultats (une variante des attaques « par dictionnaire »).
L'anonymisation la plus radicale est de retirer complètement un champ des données (méthode du feutre noir, le black-marker, dit le RFC, du nom de l'outil des censeurs du courrier d'autrefois). Ni récupérable, ni commensurable, elle offre le maximum de sécurité mais peut faire perdre des informations précieuses.
Voyons maintenant chaque champ un à un. La section 4, qui détaille les techniques adaptées à chaque champ, commence évidemment par les adresses IP car c'est le champ le plus « nominatif ». Lorsqu'on parle d'anonymisation, on pense tout de suite à celle des adresses IP, et à juste titre (section 4.1). Le problème de leur anonymisation n'est pas simple. Par exemple, une adresse IP est structurée. Même si on supprime les N derniers bits, ceux qui restent, le préfixe, identifient encore un FAI ou une entreprise et donne donc des informations. Il y a quatre moyens d'anonymiser une adresse IP (sans compter évidemment le feutre noir) :
AND
avec un nombre de M-N uns et N zéros). C'est ce que permet un logiciel
comme Squid avec sa directive client_netmask
,
qui permet de préserver la vie privée des utilisateurs du
cache en ne gardant dans le journal que le
préfixe de leur adresse IP. La troncation est une généralisation (elle
ne conserve pas le nombre d'adresses IP.)192.0.2.57
et
203.0.113.57
) vont être confondues (ici, si on supprime
les 24 premiers bits). Attention, si le réseau sur
lequel a été fait la collecte est connu, il n'est pas difficile de
retrouver le préfixe des adresses de ce réseau.Les adresses MAC identifient également une machine. Elles ne sont pas toujours présentes dans les données collectées (si le point de capture est sur le réseau d'un gros opérateur, les adresses MAC de la source et de la destination ne sont pas disponibles) mais on peut les trouver dans des captures faites localement. Elles peuvent aussi apparaître comme partie d'un identificateur de couches hautes, par exemple dans certaines adresses IPv6 (cf. section 2.5.1 du RFC 4291, et RFC 8981 pour une solution). Donc, il faut également anonymiser ces adresses (section 4.2). Comme les adresses IP, elles ont une structure, mais plus simple (les 24 ou 40 premiers bits indiquent le constructeur). Comme pour les adresses IP, on peut utiliser la troncation (on ne garde typiquement que les bits qui identifient le constructeur), la troncation inverse, la permutation et la pseudonymisation structurée.
Les numéros de port et de protocole de couche 4 n'identifient pas une entité du monde réel (comme une personne) mais peuvent servir à classer les machines (par exemple, le choix des ports sources permet souvent d'identifier le système d'exploitation, cf. RFC 6056). Ils méritent donc parfois une anonymisation (section 4.5) par exemple par permutation. Le RFC ne le mentionne pas, mais il n'est pas sûr qu'une technique d'anonymisation, qu'elle qu'elle soit, puisse fonctionner avec la distribution typique des protocoles : le plus répandu sera forcément TCP (numéro 6).
Les traces de trafic réseau contiennent souvent des nombres (collectivement appelés compteurs) qui peuvent révéler des choses sur leurs émetteurs (section 4.4). On peut donc les anonymiser en diminuant leur précision ou en les quantifiant, c'est-à-dire en les répartissant dans un petit nombre d'intervalles (les corbeilles ou bin dans le texte original du RFC) et en ne gardant qu'une valeur par intervalle.
Plus étonnant, les estampilles temporelles que contiennent les traces (date de passage du paquet, dates de début et de fin du flot) peuvent être également indiscrètes (voir Murdoch, S. et P. Zielinski, « Sampled Traffic Analysis by Internet-Exchange-Level Adversaries »). Par exemple, le séquencement des paquets peut permettre d'identifier une activité (une communication téléphonique n'aura pas du tout la même répartition temporelle des paquets qu'un téléchargement donc, même sans DPI, on pourra identifier le type de trafic). On peut donc essayer d'anonymiser les indications temporelles mais la plupart des méthodes disponibles, à part bien sûr le feutre noir, sont assez faibles contre la désanonymisation (section 4.3). On peut diminuer la résolution des temps (comme on a fait pour les compteurs, par exemple arrondir à la seconde la plus proche), on peut utiliser l'énumération (méthode qui remplace chaque estampille temporelle par un chiffre croissant : elle préserve l'ordre des événements, qui peut être important mais pas les écarts, ce qui interdit de mesurer des grandeurs comme la gigue), etc.
Une fois qu'on a anonymisé les données, il faut indiquer au destinataire comment on l'a fait, pour qu'il puisse faire ses analyses (section 5). Par exemple, si les adresses IP ont été tronquées, le destinataire ne doit pas tenter d'étudier des distributions de trafic par machine, puisque plusieurs machines sont désormais regroupées dans le même préfixe. Il faudra donc indiquer si l'anonymisation était stable ou pas (la stabilité est la propriété de mise en correspondance d'une valeur de départ avec la même valeur d'arrivée ; une anonymisation instable, au contraire, peut diriger vers une autre valeur d'arrivée après un certain temps). Typiquement, un jeu de données est stable, sauf indication contraire, mais deux jeux de données peuvent ne pas l'être entre eux, donc il vaut toujours mieux l'indiquer explicitement.
S'il y a eu troncation, il faut évidemment indiquer la longueur qui a été conservée. S'il y a eu quantification, il faut donner la liste des valeurs et leurs intervalles. S'il y a eu permutation, il ne faut pas donner la fonction utilisée (ou alors, si une clé a été ajoutée, donner la fonction mais sans la clé), afin d'éviter les attaques par dictionnaire (traduire des valeurs et regarder le résultat obtenu).
L'anonymisation soulève d'autres questions de sécurité, décrites en section 9. Elle enfonce le clou que l'anonymisation n'est jamais parfaite (sauf à effacer toutes les données). Elle rappelle que l'anonymisation ne remplace pas la confidentialité. Si des données sensibles sont exportées vers un tiers de confiance, le chiffrement sur le trajet reste nécessaire, même si les données sont anonymisées.
Ici commencent maintenant les questions spécifiques à IPFIX. Si vous ne pratiquez pas ce format, vous pouvez décider d'arrêter là. Sinon, la section 1.1 offre un utile rappel des RFC 5470, RFC 5101 et RFC 7012. IPFIX permet d'envoyer des tuples TLV dont la sémantique est décrite dans un gabarit (Template). Plusieurs gabarits standards figurent dans le registre décrit par le RFC 7012.
La section 6 décrit comment représenter les données anonymisées et
les méta-informations (celles de la section 5 sur le mécanisme
d'anonymisation) dans un flow IPFIX. Les données effacées par le
feutre noir représentent le cas le plus simple : on ne les met pas du
tout dans le flot. Pour les autres, il faut ajouter au flot un
Anonymization Options Template qui décrira les
fonctions d'anonymisation. Les détails de ce gabarit figurent en
section 6.1 et 6.2. Par exemple, un champ
anonymizationTechnique
va indiquer l'absence
d'anonymisation s'il vaut 1, la troncation (ou la dégradation de la
précision, qui est à peu près la même chose) s'il vaut 2,
l'énumération s'il vaut 4, etc (des exemples plus complets figurent en
section 8).
Ces considérations d'encodage ont été inscrites dans les registres
IANA d'IPFIX. anonymizationTechnique
,
par exemple, est identifié par le nombre 286.
L'anonymisation est typiquement effectuée dans un relais IPFIX (Mediator), en général situé à la frontière administrative du domaine (on n'anonymise pas si les données restent dans l'organisation d'origine). Attention : outre les données proprement dites, le flot contient souvent des méta-informations sur le processus de collecte qui peuvent si on ne prend pas soin de les modifier, casser en partie ou totalement l'anonymisation. Ainsi (section 7.2.3), le temps auquel a été fait l'observation peut permettre de retrouver les estampilles temporelles, même brouillées. L'identité du réseau où a été fait la mesure permet de retrouver une partie de l'adresse IP, même en cas de troncation inverse (cette identité a la même taille qu'une adresse IPv4 et il peut donc être tentant d'utiliser une adresse du réseau local comme identité).
Plus rigolo, la section 7.2.5 recommande de se méfier des adresses IP « spéciales » (RFC 6890). Ces adresses sont en effet souvent utilisées à des fins bien connues, qui font qu'on peut les retrouver, même anonymisées, en examinant leur activité. Cela fournit alors un point de départ au travail du désanonymisateur. Le RFC recommande donc d'exclure ces adresses des données exportées.
Les mises en œuvre d'IPFIX permettent-elles aujourd'hui cette anonymisation ? Je ne crois pas mais, en dehors du monde IPFIX, il existe un grand nombre d'outils d'anonymisation. Citons :
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : Donald Eastlake (Huawei), Tony Hansen (AT&T Labs)
Pour information
Première rédaction de cet article le 7 mai 2011
Ce long RFC (127 pages, dont la majorité est composé de code source C) est la mise à disposition de la communauté IETF du code de FIPS 180-2, décrivant les algorithmes de cryptographie de la famille SHA-2. Il remplace le RFC 4634.
Cette famille de fonctions de hachage cryptographiques normalisée par le NIST (et donc standard officiel aux États-Unis) a vocation à remplacer l'ancien SHA-1 (RFC 3174). Elle comprend SHA-224 (également décrit dans le RFC 3874), SHA-256, SHA-384 et SHA-512. Tous ont le même principe (section 1) : un document de longueur quelconque est transformé en un condensat cryptographique de longueur fixe (le nom de l'algorithme indique le nombre de bits du condensat), de telle manière qu'il doit extrêmement difficile de fabriquer un document ayant le même condensat qu'un document donné (ou même de fabriquer deux documents ayant le même condensat).
Notre RFC décrit également leur utilisation en HMAC (cf. RFC 2104), et en HKDF (HMAC-based Key Derivation Function, cf. RFC 5869). L'essentiel du RFC est tiré directement de la norme officielle et les assertions sur la sécurité de SHA-2 viennent donc directement du NIST et pas des éditeurs du RFC.
Les sections 2 à 7 du RFC résument le fonctionnement de ces algorithmes, et la section 8 est le code source C les mettant en œuvre.
La licence de ce code source figure dans le
fichier sha.h
, listé en section 8.1.1. C'est une licence
BSD-3 (sans la clause de publicité), qui permet tout usage,
commercial ou non, ainsi que toute modification et
redistribution. Elle est donc adaptée au logiciel libre.
Comme copier/coller le code source depuis le RFC en éliminant les
en-têtes et pieds de page n'est pas pratique, on peut récupérer une
archive « propre » en http://www.pothole.com/~dee3/source/sha.tar
. Il y
en a plein d'autres mises en œuvre de SHA décrites en http://en.wikipedia.org/wiki/SHA-2#Implementations
.
Les changements depuis le RFC 4634 sont résumés dans l'annexe. Le principal est l'ajout de HKDF (HMAC-based Key Derivation Function). Il y a aussi pas mal d'errata dans le code, détectés par le meilleur relecteur des RFC, Alfred Hoenes, et désormais réparés. La licence est nouvelle (BSD-3 désormais) et a nécessité de remplacer le code de getopt.
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : T. Li (Cisco)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 7 mai 2011
Le problème fondamental du routage dans l'Internet est connu depuis longtemps : le système actuel a du mal à fournir certains services (multi-homing, mobilité, ingénierie de trafic, etc) d'une manière qui passe à l'échelle, c'est-à-dire qui puisse grandir au rythme de la croissance de l'Internet. Un groupe de travail IRTF, le Routing Research Group travaille donc sur ce sujet et ce RFC 6227 est le cahier des charges produit.
Il est très court : il est plus facile de spécifier le problème que de décrire les solutions. Le problème (les services difficiles à fournir tout en passant à l'échelle) a déjà été présenté par le RFC 4984. Reste à concevoir les solutions et, pour cela, à décrire les exigences auxquelles doit se plier la future architecture, et leurs priorités respectives. Logiquement, le cahier des charges s'écrit au début et est publié longtemps avant que le travail ne se termine mais, ici, cela n'a pas été le cas. Les conclusions du travail sur la nouvelle architecture sont déjà sorties (RFC 6115). Simplement, le cahier des charges avait bien été écrit au début mais il a été modifié et raffiné au fur et à mesure de l'avancement du travail et d'une meilleure compréhension du problème, pour n'être publié officiellement que maintenant.
Chaque exigence listée dans ce RFC a une priorité : requise, fortement souhaitée ou souhaitée, et les exigences avec leurs priorités sont résumées dans un tableau dans la section 3.11. D'autre part, les principes traditionnels de l'Internet, tels qu'explicités dans le RFC 1958 s'appliquent toujours (notamment le principe de bout-en-bout qui indique que les deux machines terminales qui communiquent doivent faire l'essentiel du travail, puisque ce sont elles qui doivent décider, par exemple des priorités de trafic).
La « liste au Père Noël » est en section 3. D'abord, compte-tenu de la croissance continue de la table de routage globale (cf. les rapports sur la croissance de la table BGP), il est fortement souhaité (section 3.1) que le nouvelle architecture permettre de séparer la croissance de l'Internet et celle de la table de routage. Actuellement, un nouvel utilisateur qui veut être « multi-homé » proprement ajoute une entrée BGP dans la table de routage globale, qui risque donc de devenir proportionnelle au nombre de tels utilisateurs. Ce n'est clairement pas souhaitable. Notez que le RFC est ambitieux : on ne parle pas de faire croître la table de routage moins vite que le nombre d'utilisateurs, mais de ne pas la faire croître du tout lorsque ce nombre d'utilisateurs augmente.
Autre exigence, concernant l'ingénierie de trafic, c'est-à-dire la possibilité d'envoyer le trafic sur tel ou tel chemin selon des critères qui ne sont pas ceux du système de routage classique, par exemple pour forcer le passage par un lien moins coûteux. Une méthode courante aujourd'hui est d'injecter dans la table de routage globale des préfixes d'adresses IP plus spécifiques. Cela augmente la taille de ladite table. Il est donc fortement souhaité qu'une meilleure solution soit trouvée (section 3.2).
Même chose pour le multi-homing, déjà cité : il est fortement souhaité qu'il puisse aussi passer à l'échelle (section 3.3).
Une bonne partie des problèmes de l'architecture actuelle de l'Internet vient de la confusion de deux rôles dans l'adresse IP : localisateur (indique un point d'attachement dans l'Internet) et identificateur (nomme une machine ou une interface). Il est depuis longtemps reconnu (cela se trouvait déjà dans l'IEN1) que cette confusion est dommageable. Il est donc souhaité qu'on sépare ces deux rôles (section 3.4).
Un certain nombre de gens (note au passage : je n'en fais pas partie) considèrent qu'il est essentiel qu'une machine terminale, voire un réseau entier, puisse se déplacer dans l'Internet, changer de fournisseur, etc, sans remettre en cause son adresse IP et les sessions existantes. Par exemple, une connexion SSH devrait rester intacte si mon smartphone passe du Wi-Fi chez moi avec Free, au 3G chez Bouygues, voire si je passe de Free à la maison à Paris à un accès Verizon en Californie. Comme ces deux scénarios entraînent un changement de l'adresse IP, la connexion SSH cassera. Les mécanismes existants pour permettre ces changements d'attachement sans casser les connexions en cours sont la mobilité IP (RFC 5944), avec introduction d'une machine relais, le home agent, ou bien l'injection de préfixes dans la table de routage lorsque la machine se déplace. Les deux solutions sont imparfaites (la seconde impacte sérieusement la table de routage globale) et on désire donc une meilleure solution pour la mobilité (section 3.5). Le mieux serait qu'elle sépare complètement la mobilité du routage.
Autre problème du système de routage : comme il est très difficile de rénuméroter un grand réseau (cf. RFC 5887), beaucoup d'organisations font tout pour garder des adresses IP à elles, ce qui impacte le système de routage (l'agrégation des préfixes devient plus difficile). Le RFC note bien qu'une rénumérotation complètement automatique est utopique, il estime néanmoins (section 3.6) qu'on peut abaisser sérieusement le coût de renumérotation (cf. RFC 4192) et que c'est fortement souhaitable.
Autre souhait fort : que le nouvelle architecture soit conçue de manière modulaire, de manière à ce qu'on puisse en utiliser seulement une partie et à ce que les différents composants de la solution ne soient pas excessivement couplés (par exemple, si la solution introduit un tunnel, la détermination de la PMTU devrait se faire par les moyens standard, sans introduire un nouveau mécanisme pour les machines terminales).
Ce n'est pas tout que les paquets arrivent : encore faut-il qu'ils arrivent vite. La qualité du chemin trouvé par le système de routage compte donc beaucoup. Il est donc fortement souhaité (section 3.8) que ce dernier trouve une route rapidement (convergence efficace), n'en change tout le temps (routes stables) et que les routes trouvées soient proches de l'idéal (faible élongation - stretch - cette dernière étant définie comme le rapport entre la longueur du chemin effectif et la longueur du chemin le plus court possible, cf. « A Trade-Off between Space and Efficiency for Routing Tables » de Peleg et Upfal).
Autre préoccupation importante, la sécurité (section 3.9). Il est requis que la nouvelle architecture ait une sécurité au moins équivalente à l'ancienne. C'est un des deux seuls points où l'exigence est requise. Les cyniques diront que celle-ci n'est pas trop difficile à atteindre, vu le niveau de sécurité existant.
Enfin, une dernière exigence, elle aussi requise, en section 3.10 : la déployabilité. Il ne sert à rien de concevoir une splendide architecture si celle-ci reste dans les cartons. Or, des expériences malheureuses comme celle d'IPv6 ont montré que déployer des nouvautés dans l'Internet était très difficile. Il faut notamment que le nouveau système soit déployable de manière incrémentale : les premiers adoptants doivent pouvoir l'installer, et même en tirer des bénéfices immédiats. Sinon, chacun attendra que l'autre fasse le premier pas et on n'avancera pas. (Il n'est évidemment pas question de repartir de zéro, vus les investissements réalisés.)
Voilà, il n'y a maintenant plus qu'à trouver des solutions correspondant à ce cahier des charges : le RFC 6115 résume les résultats de cette quête.
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : Danny McPherson (IAB), Olaf M. Kolkman (IAB), John Klensin (IAB), Geoff Huston (IAB)
Pour information
Première rédaction de cet article le 15 avril 2011
Dernière mise à jour le 6 mai 2011
Voici un RFC officiel de l'IAB pour mettre solennellement par écrit le rôle de l'opérateur des registres des protocoles utilisé par l'IETF. Des tas de protocoles normalisés par cet organisme ont besoin de garder une trace des noms ou numéros réservés (par exemple les numéros de port de TCP ou UDP, les numéros d'options DHCP, etc) et le rôle de l'opérateur du registre qui garde ces réservations (aujourd'hui, essentiellement l'IANA) n'avait apparemment jamais été formalisé. À noter que, depuis, ce RFC a été remplacé par le RFC 8722.
L'IETF n'assure en effet pas ce rôle d'opérateur du registre elle-même. Elle se focalise sur la production de normes (les RFC) et délègue la gestion du registre. Pourquoi les valeurs en question ne sont-elles pas directement mises dans les RFC ? Parce qu'elles évoluent plus vite que la norme elle-même. Ainsi, l'enregistrement d'un nouveau type d'enregistrement DNS est un processus bien plus souple que de modifier un RFC et la liste de tels types ne peut donc pas être figée dans un RFC (ceux-ci ne sont jamais modifiés, seulement remplacés, et cela n'arrive pas souvent).
Mais on ne peut pas non plus laisser chacun définir ses propres paramètres, car cela empêcherait toute interprétation commune. D'où cette idée d'un registre des paramètres. Les règles d'enregistrement dans ce registre, la politique suivie, sont décrites pour chaque norme dans la section IANA considerations du RFC, en utilisant le vocabulaire et les concepts du RFC 5226 (pour les types d'enregistrements DNS, cités plus haut, c'est dans le RFC 6895).
Plusieurs autres SDO suivent ce même principe de séparation entre la normalisation et l'enregistrement (en revanche, les groupes fermés d'industriels qui tentent d'imposer leur standard ne séparent pas en général ces deux fonctions). Par exemple, l'ISO définit, pour la plupart de ses normes, une Registration Authority ou bien une Maintenance Agency qui va tenir le registre. (Exemples : l'opérateur du registre de ISO 15924 est le consortium Unicode et celui du registre de ISO 639 est SIL. Contre-exemple : l'opérateur du registre de ISO 3166 est l'ISO elle-même.) Pourquoi cette séparation ? Les raisons sont multiples mais l'une des principales est la volonté de séparer la politique de base (définie dans la norme) et l'enregistrement effectif, pour gérer tout conflit d'intérêts éventuel. Un opérateur de registre séparé peut être plus indépendant, afin de ne pas retarder ou bloquer l'enregistrement d'un paramètre pour des raisons commerciales ou politiques. Notons aussi que bien d'autres fonctions liées à l'IETF sont également assurées à l'extérieur, comme la publication des RFC (cf. RFC 6335).
Contre-exemple, celui du W3C, qui utilise
très peu de registres et pas d'opérateur de registre officiel séparé. En
pratique, c'est l'IANA qui gère plusieurs registres Web, comme celui
des URI bien connus (RFC 8615), celui des types de
fichiers (comme application/pdf
ou
image/png
), celui des en-têtes
(utilisés notamment par HTTP), etc. En dehors
de l'IANA, le W3C a quelques registres gérés en interne comme celui de
Xpointer. Pour le reste, la politique
du W3C est plutôt qu'un registre est un point de passage obligé et que
de tels points ne sont pas souhaitables.
Dans le cas de l'IETF, les documents existants sont le RFC 2026, qui décrit le processus de normalisation
mais pas celui d'enregistrement. Ce dernier est traditionnellement
connu sous le nom de « fonction IANA » (d'où la section IANA
considerations des RFC) même si, en pratique, ce n'est pas
toujours l'IANA qui l'effectue. (Les registres
de l'IANA sont en https://www.iana.org/protocols/
.)
La section 2 du RFC expose donc le rôle et les responsabilités
du(des) opérateur(s) de registres de paramètres. Celui(ceux)-ci, désormais nommés
avec majuscules IETF Protocol Parameter Registry Operator, seront formellement
choisis désormais par l'IAOC (RFC 4071). J'ai mis le pluriel car l'IANA
n'assure pas actuellement la totalité du rôle : il existe d'autres
opérateurs de registres, en général sur des tâches très secondaires comme par
exemple le RIPE-NCC pour l'enregistrement en
e164.arpa
(ENUM, cf. RFC 6116 et
lettre
de l'IAB). Dans le futur, on pourrait imaginer un
rôle moins exclusif pour l'IANA.
La section 2.1 est la (longue) liste des devoirs qu'implique le rôle d'opérateur de registre. Il y a bien sûr le tenue du registre à proprement parler mais ce n'est pas tout. En voici une partie :
https://www.iana.org/assignments/bootp-dhcp-parameters/
.Après cette description des devoirs de l'opérateur du registre, la section 2 continue avec les devoirs des autres acteurs. En section 2.2, ceux de l'IAB, qui supervise l'opérateur du registre : l'IAB procède à la délégation formelle du registre, après que l'IAOC ait identifié les candidats. L'IAB décide, l'IAOC gère la relation avec l'opérateur.
En section 2.3, le rôle de l'IESG : celui-ci s'occupe de la partie technique, vérifier que les RFC comportent une bonne section IANA considerations, identifier les experts techniques si le RFC précise que l'enregistrement est précédé d'une évaluation technique (exemple : le RFC 5646, où l'enregistrement d'une langue dans le registre des langues est précédé d'une telle évaluation par un linguiste), répondre aux questions de l'opérateur du registre si celui-ci a un problème pratique.
En section 2.4, le rôle de l'IETF Trust (RFC 4748). Il gère la propriété intellectuelle de l'IETF donc est « propriétaire » du contenu des registres. Enfin, en section 2.5, le rôle de l'IAOC, bras administratif de l'IETF, qui est de gérer au quotidien les relations avec l'opérateur du registre.
Voilà, l'essentiel était là mais la section 3 rajoute quelques détails.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : P. Levis (Stanford University), T. Clausen (LIX, Ecole Polytechnique), J. Hui (Arch Rock Corporation), O. Gnawali (Stanford University), J. Ko (Johns Hopkins University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF roll
Première rédaction de cet article le 29 mars 2011
Dernière mise à jour le 30 mars 2011
Dans le cadre des travaux sur l'Internet des objets, le groupe de travail ROLL de l'IETF s'occupe de définir des mécanismes de routage pour des réseaux d'engins aux capacités limitées, et connectés par des liens radio à faible portée et souvent brouillés. (Par exemple, cela peut décrire la situation de capteurs dans une usine.) Une brique de base pour beaucoup de protocoles utilisés dans ce contexte est un algorithme pour coordonner un état entre toutes les machines (cet état pouvant être par exemple la table de routage, mais aussi une configuration commune). Trickle (terme désignant un mince filet d'eau, par exemple celui coulant du robinet en cas de fuite) est l'algorithme utilisé et ce RFC est sa première normalisation. Il est notamment utilisé dans le protocole RPL du RFC 6550.
Vu le contexte très spécial, les protocoles classiques de distribution d'information ne convenaient pas forcément à ce type de réseau, où il est crucial d'économiser l'énergie, et de fonctionner malgré des liaisons physiques sommaires. Trickle atteint ces objectifs en ne diffusant l'information que lorsque elle a changé. L'idée de base est de permettre à deux nœuds de déterminer très rapidement s'ils ont la même version de l'information distribuée et, sinon, de se synchroniser. S'ils sont synchronisés, il n'y a plus beaucoup de communication. Lorsque de la nouvelle information apparait, le trafic reprend. Trickle repose entièrement sur les mécanismes de diffusion du réseau local et n'est donc pas routé. Le tout est simple et tient dans 50 à 200 lignes de code C (je n'ai pas trouvé de distribution officielle de référence de ce code miracle mais l'implémentation dans Contiki fait effectivement cette taille).
Trickle est un algorithme générique : conçu à l'origine pour distribuer du code (pour mettre à jour le programme sur les autres machines), il a pu être adapté pour distribuer n'importe quel type d'information, par exemple une table de routage. Pour un nouveau type d'information, il suffit de définir ce que veut dire « être synchrone » ou pas et la partie générique de Trickle fait le reste.
Assez de publicité, place à l'algorithme (sections 3 e 4 du RFC). Le travail de chaque nœud est de transmettre les données qu'il connait jusqu'à ce que, en entendant les autres nœuds, il se rende compte que ses transmissions sont inutiles (cela veut dire qu'un nœud Trickle isolé continuera à parler tout seul). Pour prendre l'exemple du protocole CTP (Collection Tree Protocol), quelques paquets par heure suffisent.
La transmission se fait à une adresse
multicast locale. Par
exemple, au dessus d'IPv6, Trickle va écrire à
une adresse multicast locale au lien alors qu'en
IPv4, il utiliser
255.255.255.255
.
Lorsqu'un nœud reçoit les messages d'un autre, il y a deux cas :
L'un des principaux paramètres d'un algorithme spécifique utilisant Trickle est un moyen de déterminer cette notion de « être à jour ». Par exemple, supposons que l'information ait un numéro (comme le numéro de série des zones DNS). Alors, « être à jour » signifie avoir le même numéro que l'autre et « être en retard » avoir un numéro inférieur.
Pour décider ensuite de l'action exacte à entreprendre, les nœuds Trickle ont besoin de quelques paramètres :
et de quelques variables :
Le nœud suit les règles suivantes :
On note que Trickle ne réagit pas immédiatement en détectant un retard : il se contente de démarrer un nouvel intervalle. C'est fait exprès pour éviter une tempête de mises à jour, par exemple lorsqu'un nouveau nœud rejoint le réseau après une absence. Trickle privilégie donc l'économie de ressources, et ne cherche pas à être temps-réel.
Ça, c'était l'algorithme. Simple, non ? Maintenant, si vous êtes concepteur de protocoles et que vous voulez utiliser Trickle, que vous reste-t-il à faire ? La section 5 liste vos tâches :
Il ne faut quand même pas oublier quelques considérations pratiques (section 6). D'abord, le bon fonctionnement de Trickle dépend d'un accord de tous les nœuds sur les paramètres à utiliser. En cas de différence, le résultat peut être sous-optimal voire faux dans certains cas. Par exemple, un nœud qui aurait une constante de redondance k supérieure aux autres pourrait se retrouver à émettre à chaque intervalle, vidant sa batterie. De même, un désaccord sur Imax pourrait mener certains nœuds à ne jamais transmettre, laissant les autres faire tout le travail. En outre, toutes les valeurs ne sont pas forcément raisonnables. Par exemple, la constante de redondance k mise à l'infini est théoriquement possible (Trickle travaillerait alors en mode bavard, n'économisant pas les transmissions) mais très déconseillée. Il faut donc trouver un moyen de distribuer la bonne configuration à toutes les machines.
Le pire problème serait évidemment une fonction de définition de la cohérence différente selon les nœuds, cela pourrait mener à une impossibilité de converger vers un état commun. C'est pour cela que le RFC demande qu'elle soit strictement définie pour un protocole donné, et non configurable.
L'auteur de protocole, ou le programmeur, pourraient vouloir « améliorer » Trickle en ajustant l'algorithme. Attention, avertit le RFC, cet algorithme a été soigneusement étudié et testé et la probabilité d'arriver à l'améliorer est faible. Il est conseillé de ne pas le toucher gratuitement. Trickle est extrêmement simple et la plupart des améliorations mèneraient à un code plus compliqué. Or, pour le genre de machines pour lesquelles Trickle est prévu, économiser en transmissions de paquets pour finir par faire davantage de calculs ne serait pas forcément optimal.
Enfin, question sécurité, c'est simple, Trickle n'en a pas (section 9). Un méchant peut facilement pousser tous les nœuds à transmettre, épuisant leurs ressources. Et il peut assez facilement empêcher le groupe de converger vers un état stable. Les protocoles qui utilisent Trickle doivent donc définir leurs propres mécanismes de sécurité.
Pour approfondir Trickle, notamment sur ses performances ou son implémentation, les articles recommandés sont « Trickle: a self-regulating algorithm for code propagation and maintenance in wireless sensor networks » et « The emergence of a networking primitive in wireless sensor networks ».
Plusieurs utilisations de Trickle sont mentionnées en section 6.8,
avec références. Trickle est par exemple utilisé dans Contiki : http://www.sics.se/~adam/contiki/contiki-2.0-doc/a00543.html
. Damien Wyart s'est attelé à la tâche de trouver d'autres mises en œuvre et voici ses
résultats (je le cite).
« Dans les travaux qui parlent de Trickle, on voit souvent cité Maté, une sorte d'environnement qui permet de mettre en réseau des mini-machines virtuelles (si j'ai bien compris), et certains documents indiquent que Maté contient une implantation de Trickle. Maté est distribué principalement sous forme de RPM, ce qui n'aide pas sur Debian... Il ne semble plus évoluer depuis 2005 (mais l'auteur principal continue à travailler sur TinyOS et peut sans doute être contacté pour obtenir plus de détails sur les implantations de Trickle. De plus, Maté est intimement lié à TinyOS qui a depuis, semble-t-il, beaucoup évolué. »
« Par recoupements (c'est assez rare d'avoir à autant jouer les détectives
entre fichiers RPM, confusion sur les versions et vieux dépôts
CVS ---
TinyOS a maintenant un SVN chez Google Code), je suis arrivé
principalement au fichier http://tinyos.cvs.sourceforge.net/viewvc/tinyos/tinyos-1.x/tos/lib/VM/components/MVirus.nc?view=log
. Sur
une copie locale des deux sous-arborescences
tinyos-1.x/tools/java/net/tinyos/script
et
tinyos-1.x/tos/lib/VM
(citées dans http://www.eecs.berkeley.edu/~pal/mate-web/downloads.html
),
j'arrive à ceci (avec le bien pratique concurrent de grep, ack) :
dw@brouette:/storage/sandbox/tinyos-1.x$ ack -ai trickle tos/lib/VM/components/MVirus.nc 118: MateTrickleTimer versionTimer; 119: MateTrickleTimer capsuleTimer; 153: void newCounter(MateTrickleTimer* timer) { tos/lib/VM/doc/tex/mate-manual.tex 615:that has newer code will broadcast it to local neighbors. The Trickle 635:Trickle's suppression operates on each type of packet (version, 645:\subsubsection{Trickle: The Code Propagation Algorithm} 647:The Trickle algoithm uses broadcast-based suppressions to quickly 651:completes, Trickle doubles the size of an interval, up to 662:Trickle maintains a redundancy constant $k$ and a counter tos/lib/VM/types/Mate.h 168:typedef struct MateTrickleTimer { 173:} MateTrickleTimer; tools/java/net/tinyos/script/VMFileGenerator.java 524: writer.println(" * MVirus uses the Trickle algorithm for code propagation and maintenance."); 528: writer.println(" * \"Trickle: A Self-Regulating Algorithm for Code Propagation and Maintenance"); 549: writer.println(" the timer interval for Trickle suppression, and the redundancy constant");
Cela donne donc des pistes, la partie principale semblant bien être le fichier
MVirus.nc
. »
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : H. Singh, W. Beebee (Cisco), C. Donley (CableLabs), B. Stark (AT&T), O. Troan (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 28 avril 2011
Ce RFC du groupe de travail v6ops, qui se consacre aux problèmes pratiques du fonctionnement d'IPv6 (sans modification des protocoles, donc), porte sur les CPE (Customer Premises Equipment), alias CER (Customer Edge Routers), alias home gateway, qui sont les boîtiers installés chez l'utilisateur domestique ou petite entreprise. Par exemple, en France, la Freebox ou la DartyBox sont des CPE. Certains d'entre eux gèrent le protocole IPv6 et ce RFC résume tout ce que doivent savoir les concepteurs de ces « boxes » pour faire de l'IPv6 proprement. Il a depuis été remplacé par le RFC 7084.
Le gros débat qui avait eu lieu à l'IETF lors de la conception de ce RFC portait sur une règle exprimée dans les premières versions de l'Internet-Draft qui avait précédé le RFC : cette règle disait qu'un CPE IPv6 devait, par défaut, bloquer les connexions entrantes. L'argument principal était que les CPE IPv4 font tous cela. Mais ils le font parce qu'en IPv4, la pénurie d'adresses oblige à des bricolages comme le NAT, et empêchent de toute façon les connexions entrantes. IPv6 permettant enfin de récupérer une adresse IP unique mondialement, et donc d'avoir à nouveau une connectivité de bout en bout, cette règle évoquait plus un « Minitel 2.0 » que l'Internet du futur.
Elle a donc été retirée de ce RFC, qui laisse ouverte la question de la sécurité, la déléguant à un autre document, le RFC 6092. En coupant les connexions entrantes, on bloque certaines attaques (par forcément les plus fréquentes : aujourd'hui, la plupart des attaques se font par le contenu des données transférées - importation de malware - et pas directement sur IP) mais on empêche les utilisateurs de profiter des services comme la téléphonie sur IP ou le pair-à-pair, qui dépendent souvent de cette possibilité de connexions entrantes.
Donc, en dehors de ce point, que contient ce RFC ? La section 1 résume les points importants : le RFC se focalise sur le cas où IPv6 est natif (pas de traduction d'adresses entre v4 et v6), et sur le cas simple où il n'y a qu'un seul CPE, qui récupère sa configuration sur le WAN, puis la distribue aux machines IPv6 locales, puis route leurs paquets. Le déploiement de l'IPv6 dans le réseau de l'opérateur n'est pas discuté (cf. RFC 4779). Ce RFC concerne uniquement le « foyer, doux foyer ».
D'abord, un rappel du fonctionnement d'un CPE IPv4 aujourd'hui. Ce fonctionnement n'est spécifié nulle part, il résulte d'une accumulation de choix par les auteurs anonymes des CPE existants. Ces choix sont souvent erronés. En l'absence de norme formelle, la section 3.1 décrit le CPE « typique » de 2010. Ce CPE typique a une (et une seule) connexion avec l'Internet, une seule adresse IP publique (et encore, parfois, il y a même du NAT dans le réseau de l'opérateur) et il sert de routeur NAT aux machines IPv4 situées sur le réseau local. Par défaut, en raison du NAT, il bloque toutes les connexions entrantes (c'est la seule allusion à cette question qui soit restée dans la version finale du RFC). Ouvrir des ports entrants (port forwarding) se fait par une configuration manuelle du CPE, via une interface Web (cas de la Freebox) ou bien par UPnP. C'est donc un vrai Minitel 2.0. Un avantage de ces adresses privées est toutefois d'assurer la stabilité des adresses internes : elles ne changent pas si on quitte son FAI.
L'architecture ci-dessus est largement déployée et correspond au cas de la plupart des abonnés à l'Internet à la maison. À quoi ressemblera t-elle en IPv6 ? On ne peut évidemment pas encore être sûr. mais la section 3.2, qui la décrit en termes très généraux, suppose qu'elle ne sera pas très différente, à part que la présence de plusieurs réseaux (et donc plusieurs préfixes IP) sera peut-être un cas plus fréquent qu'aujourd'hui. Quelles adresses IP seront utilisées à l'intérieur ? On pense immédiatement au RFC 5902, qui n'est toutefois pas cité. Le RFC 6204 présente la possibilité que des adresse locales, les ULA (RFC 4193) soient utilisées pour le réseau local. Le CPE devra bien alors fournir un mécanisme de traduction.
Alors, maintenant, quelles sont les exigences auxquelles devront se plier les futurs CPE IPv6 ? La section 4 est la liste de ces demandes. Elles sont nombreuses. Citons, parmi elles, l'obligation de d'abord se comporter en bon routeur, ce qui implique par exemple de mettre en œuvre ICMP (RFC 4443) correctement. Du côté du WAN, le CPE devra lui-même utiliser les protocoles standard de découverte d'un routeur (RFC 4861) pour trouver où envoyer les paquets, devra demander son préfixe avec DHCP (RFC 8415), devra bien sûr encapsuler IPv6 correctement (RFC 2464 pour Ethernet), etc. Du côté du LAN, il devra fournir des adresses globales ou des ULA (les adresses locales au lien ne suffisent pas et, de toute façon, pas besoin d'un routeur pour en acquérir). La gestion des ULA est désormais obligatoire, et le CPE doit pouvoir mémoriser le préfixe ULA, même en cas de redémarrage, de façon à fournir un préfixe stable (et, idéalement, configurable) au réseau dont il a la charge. Il doit évidemment pouvoir distribuer ce préfixe sur le réseau local avec SLAAC (Stateless Address Autoconfiguration, RFC 4862) ou avec DHCP (RFC 3315, ce protocole devient donc désormais obligatoire). Il doit fournir des options comme l'annonce des serveurs DNS (RFC 3646).
La sécurité, on l'a vu, est l'aspect délicat de ces machines, puisque le M. Michu qui les utilise pour connecter sa maison, ne connait pas le problème et n'a pas envie d'apprendre. Sur ce point controversé, la section 4.4 se contente de renvoyer à un autre RFC, le RFC 6092 en disant que ce serait bien de mettre en œuvre ses recommandations. Délibérement, la question de la configuration par défaut souhaitable (permettre les connexions entrantes ou pas) est laissée de côté.
Les CPE d'aujourd'hui mettent-ils en œuvre ces recommandations ? Difficile à dire, je ne connais pas d'étude systématique ayant été faite sur les capacités de ces engins (un projet est en cours), mais ce serait certainement très instructif. Des tests chez Free sur une Freebox v5 semblent indiquer que tout est correct (pas de filtrage bizarre, et merci à Ludovic Martin pour ses essais.)
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : T. Sirainen
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF morg
Première rédaction de cet article le 27 mars 2011
Où s'arrêtera la liste des extensions au protocole IMAP d'accès aux boîtes aux lettres ? En tout cas, elle ne cesse de grossir. Ce RFC propose une extension aux fonctions de recherche d'IMAP pour permettre des recherches floues, par exemple pour que « hipothèse » puisse trouver « hypothèse ».
Beaucoup de systèmes de recherche disposent de mécanisme analogue,
par exemple le moteur de recherche Google,
lorsqu'on lui soumet la requête erronée citée plus haut propose
« Essayez avec cette orthographe : hypothèse 2 premiers résultats affichés ». Mais IMAP n'avait qu'un service de recherche exact, via la
commande SEARCH
(RFC 3501,
section 6.4.4). Notre RFC 6203 l'étend en permettant, via
l'ajout du mot-clé FUZZY
, des recherches
floues. Il est important de noter que ce RFC ne spécifie qu'une
syntaxe : la sémantique exacte d'une recherche est laissée à
chaque mise en œuvre, et on peut penser qu'elle évoluera avec
les progrès de la recherche floue. Ainsi, pour prendre un exemple,
est-ce que « Penelope » trouvera les textes sur Pénélope ? Le RFC ne
le spécifie pas, laissant chaque serveur IMAP ajouter les algorithmes de
recherche floue qu'il préfère.
La syntaxe exacte figure en section 3. Un mot-clé,
FUZZY
, enregistré dans le registre
IANA d'IMAP, préfixe le critère de recherche, comme
dans, par exemple :
C: MYTAG1 SEARCH FUZZY (SUBJECT "balade dames jadisse") S: * SEARCH 1 5 10 S: MYTAG1 OK Search completed.
Et on trouvera peut-être (selon l'implémentation) un message dont le sujet était « La ballade des dames du temps jadis » (et merci à ma fille pour une intéressante discussion sur balade / ballade). Je répète que c'est le serveur qui décidera du niveau de flou acceptable, le RFC ne fournit pas de guide à ce sujet.
Le mot-clé FUZZY
s'applique au critère qu'il
préfixe, pas à
toute la recherche. Donc :
C: MYTAG2 SEARCH FUZZY (SUBJECT "balade dames jadisse") FROM francois@villon.fr S: * SEARCH 1 4 S: MYTAG2 OK Search completed.
fera une recherche floue sur le sujet mais une recherche exacte sur l'auteur.
Les recherches floues vont évidemment renvoyer davantage de
résultats que les recherches exactes et le tri de ces résultats, par
pertinence, est donc essentiel. La section 4 décrit donc le mécanisme
de pertinence. Le RFC recommande très fortement aux serveurs IMAP qui
mettent en œuvre FUZZY
d'affecter une
grandeur entre 0 et 100 à chaque résultat, indiquant la pertinence. Si
le serveur accepte également l'extension ESEARCH
(RFC 4731), celle-ci peut servir à récupérer
les valeurs de pertinence, avec la nouvelle option de
RETURN
, RELEVANCY
:
C: MYTAG3 SEARCH RETURN (RELEVANCY ALL) FUZZY TEXT "Bnjour" S: * ESEARCH (TAG "MYTAG3") ALL 1,5,10 RELEVANCY (4 99 42) S: MYTAG3 OK Search completed.
Les exemples ci-dessus utilisaient la recherche floue avec des chaînes de caractère. Mais la norme ne se limite pas à ces chaînes, comme le précise la section 5. Un serveur peut donc décider de permettre des recherches floues pour d'autres types de données et le RFC donne des indications sur les types pour lesquels c'est utile :
Le concept de pertinence s'applique aussi à la commande
SORT
(section 6). On peut donc trier les messages
selon la pertinence :
C: MYTAG4 SORT (RELEVANCY) UTF-8 FUZZY SUBJECT "Bjour" S: * SORT 5 10 1 S: MYTAG4 OK Sort completed.
Si vous être programmeur et que vous ajoutez cette capacité de flou à un serveur IMAP existant, lisez bien la section 8 sur la sécurité. En effet, les recherches floues peuvent consommer bien plus de ressources du serveur et faciliter ainsi des attaques par déni de service.
D'autre part (comme, là encore, avec les moteurs de recherche du Web), les recherches floues peuvent être plus susceptibles d'empoisonnement par des méchants qui glisseraient dans les messages de quoi apparaître en tête du classement.
Et quelles sont les implémentations existantes de cette extension ? Il y en a apparemment au moins deux mais j'ai été trop paresseux pour chercher lesquelles, comptant sur les lecteurs pour me les signaler.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : Donald E. Eastlake 3rd (Motorola)
Première rédaction de cet article le 29 mars 2011
Un RFC un peu bureaucratique, pour détailler les mécanismes utilisés pour l'enregistrement dans les registres de l'IANA des paramètres liés au DNS. Il met très légèrement à jour son prédécesseur, le RFC 5395, qui avait libéralisé l'enregistrement de nouveaux paramètres. Et il a lui-même été remplacé par la suite par le RFC 6895.
Un certain nombre de paramètres, dans le DNS, sont enregistrés à l'IANA, afin de s'assurer d'une interprétation identique partout. C'est ainsi que l'IANA gère un registre des paramètres DNS où on trouve, entre autres, les types d'enregistrement (A, codé 1, pour une adresse IPv4, AAAA, codé 28, pour une adresse IPv6, LOC, codé 29, pour les positions géographiques du RFC 1876, etc). Cet espace n'étant pas de taille infinie, il faut y enregistrer de nouveaux paramètres avec prudence, selon les règles qui étaient expliquées dans le RFC 2929, qui a été sérieusement réformé par le RFC 5395 avant de l'être, beaucoup plus légèrement, par notre RFC 6195.
En effet, les règles du RFC 2929 étaient bien trop strictes à l'usage. Notamment, le processus d'enregistrement d'un nouveau type d'enregistrement était tellement pénible que beaucoup de protocoles (comme SPF à ses débuts) préféraient utiliser le fourre-tout TXT pour y mettre leurs enregistrements. Ce goulet d'étranglement était souvent cité comme un exemple typique des blocages liés à l'IETF.
Le RFC 5395 avait donc assoupli les règles d'enregistrement des types de ressources DNS (les autres règles sont peu changées). Avant, il y avait deux solutions (voir le RFC 5226 pour plus d'explications), IETF Review (ex-IETF Consensus), un processus long et incertain imposant un RFC sur le chemin des normes, approuvé par l'IESG, ou Specification required, qui impose l'écriture d'une norme (pas forcément un RFC) « stable et permanente ».
Le nouveau système est plus léger (section 3.1.1) : il suffit désormais de remplir un formulaire décrivant le nouveau type d'enregistrement (un gabarit figure en annexe A), de le soumettre sur la liste dnsext@ietf.org et d'attendre le jugement d'un expert, désigné parmi les noms fournis par l'IESG, qui décidera, sur la base du formulaire soumis, d'allouer ou pas la requête. Un tel processus est utilisé pour d'autres enregistrements à l'IANA, par exemple pour les nouvelles étiquettes de langue.
Le nouveau processus a été testé pour la première fois pour le
type
d'enregistrement ZS (Zone Status) qui a
été accepté, sous un autre nom, NINFO, et figure désormais sous
le numéro 56 dans le registre
IANA. Autre exemple, plus récent, le type
URI
, permettant de stocker des
URI dans le DNS, enregistré en
février 2011, sous le numéro 256. Mais tous les types ne
réussissent pas forcément leur entrée dans le
registre. CAA
, qui sert à indiquer
l'autorité de certification du domaine, est
toujours
en discussion.
Quels sont les changements entre le RFC 5395, qui avait marqué l'entrée dans la nouvelle ère, et notre RFC 6195 ? Ils sont minimes (voir annexe B). Le principal est le changement de nom de la liste de diffusion où se discutent les demandes. Autrement, ce sont surtout des petites corrections éditoriales. À son tour, le successeur de notre RFC, le RFC 6895 n'a apporté que de petits changements.
Outre l'enregistrement de nouveaux types de ressources DNS, notre RFC mentionne également d'autres champs des messages DNS. Un changement ou une extension de leur sémantique continue à nécessiter une action plus lourde à l'IETF. Ainsi, le bit RD (Recursion Desired) n'a de signification que dans une question DNS. Dans une réponse, il est indéfini et son éventuelle utilisation future nécessitera un RFC sur le chemin des normes. Même chose pour le dernier bit qui reste libre dans les options, le bit Z. Quant aux opcodes qui indiquent le type du message (requête / notification / mise à jour dynamique / etc), un ajout à leur liste nécessitera le même chemin.
Les codes de réponse (rcodes), comme
NXDOMAIN
(nom inexistant) ou
BADTIME
(signature trop ancienne ou trop récente,
cf. RFC 8945) sont tirés d'un
espace plus vaste et la procédure est donc un peu plus libérale (section 2.3).
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : C. Daboo (Apple)
Chemin des normes
Première rédaction de cet article le 31 mars 2011
Les enregistrements DNS de type
SRV ont été normalisés dans le RFC 2782 il y a dix ans, pour permettre de trouver la
ou les machines rendant un service (par exemple de
messagerie instantanée avec
XMPP), en ne connaissant que le nom de
domaine délégué, par exemple
example.org
ou apple.example
. Ils ont été adoptés par la plupart des protocoles
Internet, avec deux exceptions importantes : le
Web ne les utilise toujours pas, ce qui mène à
des bricolages contestables comme de mettre une adresse IP sur un nom de domaine délégué. Et le
courrier électronique n'utilise pas non plus
SRV car, pour trouver le serveur d'un domaine, il compte sur une
technique plus ancienne, proche du SRV mais spécifique au courrier, le
MX (les MX ne présentent aucun avantage
spécifique et, si tout était à refaire de zéro, on utiliserait
certainement les SRV aussi pour cela). Les enregistrements MX ne concernent
toutefois que la transmission de courrier de
MTA à MTA. Pour les autres logiciels de
courrier, comment font-ils ?
Depuis ce RFC 6186, ils utilisent
SRV à leur tour. Ainsi, un
MUA qui cherche à quel serveur transmettre le
courrier n'aura plus besoin d'être configuré explicitement (options
Mail submission server, Mail retrieval server, ou quelque chose de ce
genre). Il suffira d'indiquer l'adresse électronique de l'utilisateur
(mettons jeanne@example.org
) et le MUA pourra
extraire le domaine (example.org
) et chercher des
enregistrements SRV qui lui indiqueront où trouver ces serveurs. (Une
autre méthode ancienne était d'utiliser des
conventions comme de mettre le serveur
IMAP en imap.example.org
mais elle est moins souple, les SRV permettent en effet d'indiquer
plusieurs serveurs, de préciser leurs priorités, etc.)
Bien, commençons par l'introduction. Une liste (sans doute non limitative) des services de courrier est donnée par la section 1 :
Le premier cité de ces RFC, le RFC 5321 (section 5)
normalise l'utilisation des enregistrements MX
pour trouver le serveur de courrier suivant. Mais il ne dit rien des
autres services. Par exemple, un MUA ne peut pas trouver dans les MX
le serveur de soumission. Résultat, les MUA dépendent d'une
configuration manuelle des serveurs à utiliser, parfois augmentée
d'une série d'heuristiques (du genre, essayer l'IMAP sur le serveur de
soumission, au cas où ce serait le même...). Ce système est complexe
pour les utilisateurs (« Indiquez le numéro de port de votre serveur
IMAP ; si vous ne le connaissez pas, écrivez à jenerepondsjamaisintelligemment@support.votre-fai.net
»...)
Les différents noms SRV utilisés sont normalisés en section 3 :
submission
(section 3.1) sert pour la soumission initiale
de message, telle que décrite dans le RFC 6409. Ainsi, pour le domaine
example.org
, on pourrait voir un enregistrement
_submission._tcp.example.org. SRV 0 1 9587
mail.example.NET.
indiquant que les messages doivent être
soumis à mail.example.NET
, sur le port
non-standard 9587. À noter que cet enregistrement couvre les
connexions avec ou sans TLS, ce qui est une
autre source de confusion lors de
la configuration. (Depuis, la sortie du RFC 8314, avec son _submissions._tcp
, a
clarifié les choses.)imap
(section 3.2) et
imaps
servent pour trouver le serveur IMAP. Donc,
par exemple, avec cette fois le port standard,
_imap._tcp.example.org. SRV 0 1 143
imap.example.NET.
.pop3
et pop3s
servent
à localiser le serveur POP3. Leur absence peut
donc indiquer que ce vieux protocole n'est pas disponible pour un
domaine.Les enregistrements SRV indiqués ici utilisent évidemment la sémantique standard du RFC 2782. Ainsi, l'ensemble suivant :
$ORIGIN example.org. _imap._tcp SRV 0 1 143 imap.example.net. SRV 10 1 143 imap.plan-B.example.
signifie, en raison du champ Priorité (mis à zéro pour le premier
enregistrement et à 10 pour le second), que le client IMAP
doit tenter d'abord de se connecter à
imap.example.net
et ne doit essayer
imap.plan-B.example
que si le premier est
injoignable. Tout cela est ancien et bien connu. Mais le courrier
présente un défi spécifique, l'existence de deux protocoles de
récupération, IMAP et POP. Que doit faire le MUA si les deux sont
annoncés dans le DNS ? La section 3.4 tranche : le MUA qui gère les
deux protocoles devrait
récupérer les enregistrements pour POP et IMAP et utiliser ensuite le
champ Priorité, non seulement à l'intérieur d'un ensemble (POP ou
IMAP) mais même pour choisir entre les deux protocoles. Ainsi, ces
données :
$ORIGIN example.org. _imap._tcp SRV 10 1 143 imap.example.net. _pop3._tcp SRV 50 1 143 pop.example.net.
indiquent sans ambiguité que l'administrateur système voudrait qu'on utilise de préférence IMAP (champ Priorité plus petit, donc plus prioritaire).
Bien, maintenant, dans le futur (car, aujourd'hui, il n'y a à ma
connaissance aucune mise en œuvre de ce RFC dans un logiciel), comment se comportera un
MUA lorsque ce RFC sera déployé ? La section 4
expose le mode d'emploi. Il leur suffira d'interroger l'utilisateur
sur son adresse électronique et tout le reste pourra être trouvé dans
le DNS, en prenant la partie à droite du @ et
en cherchant les SRV pour les différents services. Regardez par
exemple le domaine bortzmeyer.fr
comment
c'est fait (enregistrements _submission._tcp
,
_imap._tcp
et
_imaps._tcp
). Si la recherche des SRV ne donne
rien, le MUA pourra alors, comme aujourd'hui, demander à l'utilisateur
ces informations.
Notez toutefois que beaucoup d'hébergeurs DNS ne permettent pas, via le panneau de contrôle qu'ils proposent à leurs clients, d'ajouter un enregistrement SRV. Même lorsque cette possibilité existe, elle est souvent boguée comme chez Gandi où le formulaire ne permet pas d'indiquer proprement poids, priorité ou port (astuce : il faut les taper dans le champ Valeur, dans le bon ordre).
La partie de cette section concernant TLS
est plus faible (mais a été changée dans le RFC 8314, bien plus détaillé). Si on trouve un serveur IMAP, par exemple,
le RFC demande de tenter la commande STARTTLS
pour voir si elle marche. Les enregistrements SRV de notre RFC ne permettent pas
d'indiquer que la gestion de TLS est obligatoire (chose que l'on peut
configurer dans beaucoup de MUA) et, si TLS échoue, le MUA doit donc
compter sur une configuration manuelle par l'utilisateur (du genre
« Toujours utiliser TLS »). La section 6 détaille ce choix.
Notons aussi que
l'utilisation des SRV peut compliquer la vérification de l'identité du
serveur distant (si le domaine est
mapetiteentreprise.example
et que l'enregistrement SRV indique
que le serveur IMAP est
mail.grosfournisseur.example
, l'identité du
serveur dans le certificat ne sera pas
mapetiteentreprise.example
). La procédure du RFC 6125 doit impérativement
être utilisée.
Lors de la connexion au serveur IMAP ou au serveur SMTP de soumission, il faut en général s'authentifier, ce qui implique qu'on puisse indiquer un nom d'utilisateur. Notre section 4 impose au MUA d'utiliser d'abord l'adresse électronique entière, puis la partie à gauche du @. Si ces deux tentatives échouent, il reste à demander à l'utilisateur (le nom pour la procédure d'authentification n'est en effet pas forcément dans l'adresse de courrier).
Les informations sur les serveurs peuvent être conservées pour éviter de demander au DNS à chaque fois. Mais, si la connexion a marché à un moment mais échoue par la suite, le MUA doit ré-interroger le DNS pour voir si les serveurs n'ont pas changé.
La section 4 conseillait les auteurs de MUA. La section 5 aide les fournisseurs de courrier. Le principal conseil est de permettre comme nom de connexion l'adresse électronique complète, vu que c'est la première chose que tenteront les MUA.
La section 6 est celle de la sécurité. En l'absence de signatures DNSSEC, la récupération des enregistrements SRV n'est pas sûre. Si un attaquant a réussi à empoisonner le cache du résolveur DNS, il peut rediriger le courrier vers n'importe quel serveur de son choix. Notez bien que c'est un des cas où l'argument des sceptiques sur DNSSEC « Il suffit d'utiliser TLS » ne tient pas. Sans DNSSEC pour sécuriser le SRV (le lien entre un nom de domaine et les noms des serveurs), TLS ne protégerait rien puisque les serveurs d'un attaquant peuvent parfaitement avoir un certificat valide et correspondant à leur nom.
La section 6 conseille, au cas où DNSSEC ne soit pas utilisé (ce
qui est aujourd'hui le cas le plus fréquent), de vérifier que les
serveurs sont dans le même domaine que le domaine de l'adresse de
courrier et, sinon, de demander confirmation à l'utilisateur,
procédure lourde qui annulerait une partie de l'intérêt de ce RFC (et qui n'est pas suivie dans l'exemple de bortzmeyer.fr
donné plus haut).
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : A. Ford (Roke Manor Research), C. Raiciu, M. Handley (University College London), S. Barre (Université catholique de Louvain), J. Iyengar (Franklin and Marshall College)
Pour information
Réalisé dans le cadre du groupe de travail IETF mptcp
Première rédaction de cet article le 23 mars 2011
Plusieurs efforts ont déjà été déployés pour avoir un protocole de transport qui puisse utiliser plusieurs chemins simultanés, pour le cas où deux machines disposent de plusieurs moyens de se joindre. Le projet « Multipath TCP » dont voici le premier RFC se distingue par le fait que son trafic apparaîtra comme du TCP habituel, aussi bien aux applications qu'aux équipements intermédiaires situés sur le réseau.
L'idée de base de tous ces efforts est : il arrive qu'entre deux machines A et B, il existe plusieurs chemins possibles, par exemple si A et B sont tous les deux connectés à au moins deux FAI (cf. section 1.3). Utiliser simultanément ces deux chemins permettrait d'augmenter la capacité disponible (et donc le débit effectif) et d'augmenter la résilience (en cas de panne d'un chemin pendant la connexion, on utiliserait automatiquement l'autre). TCP ne permet pas cela, puisqu'il est lié à des adresses IP source et destination qui ne changent pas. Des protocoles de couche 4 comme SCTP (RFC 4960) ont déjà exploré cette voie. Mais ils souffrent d'un double problème : il faut parfois adapter les applications, qui s'attendent à la sémantique de TCP, et il faut être sûr que le chemin complet soit de l'IP propre. Or, cela est rare dans l'Internet aujourd'hui, que des incompétents ont truffé de boîtiers intermédiaires non transparents et qui rendent le déploiement de tout nouveau protocole très difficile.
Pourtant, pouvoir mettre en commun la capacité de plusieurs chemins est tellement tentant que d'autres projets ont vu le jour. C'est ainsi que le groupe de travail mptcp de l'IETF a été créé pour mettre au point une architecture, Multipath TCP et un protocole mettant en œuvre cette architecture, MPTCP (le RFC normalisant ce protocole étant encore en cours d'élaboration).
Comme son nom l'indique, l'idée de base est de ne pas trop s'éloigner du TCP actuel, afin d'assurer une compatibilité à la fois avec les applications actuelles et avec le réseau actuel, les deux points sur lesquels SCTP a largement achoppé. SCTP est donc plus propre, plus conforme à l'architecture originale de l'Internet mais Multipath TCP est peut-être plus réaliste. (Notre RFC 6182 ne cite pas SHIM6 - RFC 5533 - mais celui-ci possède pas mal de points communs avec SCTP, notamment un très faible déploiement dans l'Internet actuel.)
La section 2 précise les buts de l'architecture Multipath TCP. Du point de vue des fonctions, on voudrait :
Notons que SCTP n'avait que le second but (SCTP ne permet pas actuellement d'envoyer des paquets sur différents chemins, cf. section 2.4). Naturellement, il faut en outre que le tout se fasse automatiquement : une machine MPTCP doit pouvoir trouver seule si son partenaire est également MPTCP et basculer automatiquement vers le nouveau protocole.
Mais, tout aussi importants que les fonctions sont les critères de compatibilité avec l'Internet d'aujourd'hui :
La deuxième exigence de compatibilité, celle avec le réseau, va donc être difficile à assurer. Mais elle est nécessaire pour le succès de Multipath TCP, les innombrables middleboxes programmées avec les pieds et configurées n'importe comment étant un puissant frein au déploiement de tout protocole de transport qui ne serait pas TCP ou UDP.
Multipath TCP a également des contraintes en terme de sécurité : la section 2.3 impose qu'il n'aggrave pas la situation par rapport à TCP.
Une fois les buts exposés, comment les atteindre ? la section 3 décrit l'architecture de Multipath TCP. En gros, Multipath TCP part des idées exposées dans « Breaking Up the Transport Logjam » de Ford & Iyengar : séparation de la couche transport en deux, une demi-couche haute « sémantique » (service aux applications, fonctionnant de bout en bout) et une demi-couche basse « flot et terminaison » (pas forcément de bout en bout, si des middleboxes sont présentes).
La section 4 de notre RFC descend ensuite dans le concret. On passe de l'architecture, Multipath TCP, au protocole, MPTCP. Le principe de base de MPTCP est de répartir chaque connexion TCP en plusieurs « sous-connexions », chacune d'entre elles apparaissant à un observateur extérieur comme une connexion TCP complète et normale (et aura donc de bonnes chances de passer à travers les NAT et autres horreurs). Les méta-informations spécifiques à MPTCP seront transportées à part. MPTCP aura les tâches suivantes :
La section 5 rappelle les choix techniques importants de MPTCP et leurs raisons. Ainsi de la façon de numéroter les octets. La section 5.1 explique qu'il y avait deux façons :
Autre choix délicat, les retransmissions en cas de perte. Chaque sous-connexion étant du TCP normal, elle a un système d'accusé de réception. Mais si des données sont perdues, par exemple lors du réassemblage des sous-connexions, on ne peut pas utiliser les mécanismes TCP normaux pour demander une réémission puisque ces données ont déjà fait l'objet d'un accusé de réception. Il y a donc également un système d'accusés de réception et de réémission au niveau de la connexion MPTCP globale.
Plusieurs des fonctions de MPTCP nécessitent donc un mécanisme de signalisation entre les deux pairs, par exemple au démarrage lorsqu'il faut signaler au pair TCP qu'on sait faire du MPTCP. La section 5.4 explore l'espace des choix : les options TCP (RFC 793, section 3.1) ont été retenues pour cette signalisation, de préférence à un encodage TLV dans les données. Les options sont la solution standard de TCP et la seule propre. Elle présentent toutefois une limitation, leur faible taille, et un risque : certaines middleboxes massacrent les options (section 7 et voir aussi par exemple l'excellente étude de Google Probing the viability of TCP extensions).
Et comment va t-on identifier une connexion MPTCP ? Traditionnellement, l'identificateur d'une connexion TCP était un quadruplet {adresse IP source, adresse IP destination, port source, port destination}. La connexion MPTCP, reposant sur plusieurs connexions TCP, ne peut pas utiliser un de ces identificateurs (puisqu'il risque de ne plus rien signifier si la connexion TCP associée casse). MPTCP devra donc développer un nouvel identificateur (section 5.6). Cela limitera d'ailleurs la compatibilité de MPTCP avec les anciennes applications, qui n'utiliseront comme identificateur celui de la première connexion TCP. Si celle-ci défaille ultérieurement, la connexion MPTCP entière pourra avoir un problème.
L'Internet étant ce qu'il est, tout nouveau protocole apporte un lot de nouveaux problèmes de sécurité (section 5.8). Le cas de la sécurité de Multipath TCP est traité plus en détail dans un futur RFC « Threat Analysis for TCP Extensions for Multi-path Operation with Multiple Addresses ». En attendant, les propriétés de sécurité essentielles attendues sont :
Atteindre ces objectifs ne va pas être facile pour MPTCP : le choix d'utiliser les options TCP limite sévèrement la quantité d'information qu'on peut transmettre et le choix de permettre qu'une middlebox s'interpose oblige à compter avec le fait que certains paquets seront modifiés en transit.
Revenons aux applications (section 6). Il y aura un certain nombre de points de détail qu'elles vont devoir gérer. Par exemple, si l'application se lie explicitement à une adresse particulière de la machine, MPTCP ne doit pas être utilisé (puisque l'application a marqué une préférence pour une adresse donnée).
L'interaction avec les équipements intermédiaires fait l'objet d'une étude plus approfondie en section 7. MPTCP ne sera pas déployé dans un réseau idéal, un réseau qui ne fournirait que de la délivrance de datagrammes IP. Au contraire, il opérera au milieu d'une jungle de middleboxes toutes plus mal programmées les unes que les autres : routeurs NAT, pare-feux, IDS, PEP, etc. Toutes ont en commun d'optimiser les applications d'aujourd'hui au détriment de celles de demain. En effet, violant la transparence du réseau, elles rendent très difficiles de déployer de nouvelles techniques qui font des choses inattendues. La section 7 donne une liste détaillées des différentes catégories de middleboxes et de leur influence possible. Ansi, certains pare-feux mélangent les numéros de séquence TCP (pour protéger les systèmes bogués qui ne choisissent pas le numéro initial au hasard). Si un tel équipement se trouve sur le trajet, l'émetteur TCP ne sait même pas quel numéro de séquence sera vu par le récepteur ! Quant aux IDS, ne connaissant pas MPTCP, ils trouveront peut-être suspect cet établissement de multiples connexions. À moins qu'ils ne comprennent pas que ces connexions sont reliées, ratant ainsi certaines informations transportées. (Imaginons une attaque transmise par MPTCP, où les différentes parties de l'attaque arrivent par des chemins séparés...).
Comme indiqué, MPTCP n'est pas encore complètement spécifié. Seule
l'architecture générale est choisie. Il n'est donc pas étonnant qu'on
n'en trouve pas encore d'implémentations officielle, que ce soit dans
Linux ou dans
FreeBSD. Néanmoins, le travail est déjà en
cours sur Linux à l'Université de
Louvain qu'on peut tester selon les instructions en http://mptcp.info.ucl.ac.be/
.
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : J. Arkko (Ericsson), F. Baker (Cisco Systems)
Pour information
Première rédaction de cet article le 28 mai 2011
IPv6 fait souvent peur aux administrateurs réseaux par le nombre de techniques de coexistence entre IPv4 et IPv6. Ces techniques sont variées, et inévitables, puisque la transition a pris un retard considérable, ce qui mène à devoir déployer IPv6 alors que les adresses IPv4 sont déjà épuisées. Ce RFC 6180 vise à simplifier la tâche dudit administrateur système en le guidant parmi les techniques existantes.
Il ne s'agit donc pas de normaliser le Nième protocole de transition et/ou de coexistence entre IPv6 et IPv4, plutôt de faire le point sur les protocoles existants, dont le nombre a de quoi effrayer. Mais il ne faut pas paniquer : selon le cas dans lequel on se situe, toutes ces techniques ne sont pas forcément pertinentes et il n'est donc pas nécessaire de les maîtriser toutes.
D'abord, notre RFC 6180 rappelle qu'il n'y a pas le choix : la réserve IPv4 de l'IANA a été épuisée en février 2011 et celle des RIR le sera fin 2011-début 2012. IPv6 est donc la seule solution réaliste. Le point sur la transition est fait dans le RFC 5211 et elle a commencé il y a longtemps, dans les organisations les mieux gérées. Un des points qui la freine est que l'administrateur réseaux normal, celui qui ne suit pas heure par heure les travaux de l'IETF, voit un grand nombre de techniques de coexistence IPv4/IPv6 (le Wikipédia anglophone a excellente page de synthèse sur ces techniques) et se demande « Dois-je donc déployer 6to4 et 6rd et DS-lite et NAT64 et donc maîtriser toutes ces techniques ? ». La réponse est non : selon son réseau, notre malheureux administrateur n'aura à gérer qu'une partie de ces méthodes.
Déjà, il faut comprendre ce que ces termes barbares veulent dire : la section 2 rappelle la terminologie, et les RFC à lire.
La section 3 décrit ensuite les principes suivis dans le RFC : le premier est de garder en tête le but, qui est de pouvoir continuer la croissance de l'Internet sans être gêné par des problèmes comme le manque d'adresses. Pour cela, le but final de la transition doit être le déploiement complet d'IPv6 natif dans tout l'Internet. Lorsque cela sera réalisé, toutes les techniques de transition et de coexistence pourront être abandonnées, simplifiant ainsi beaucoup la situation. Mais pour atteindre ce but lointain, il n'y a pas qu'une seule bonne méthode. Par contre, ces méthodes ont quelques points en commun. Il est par exemple essentiel de s'y prendre à l'avance : les adresses IPv4 sont déjà épuisées et une organisation qui n'aurait encore rien fait du tout, question IPv6, va avoir des problèmes. Donc, aujourd'hui, En tout cas, il n'existe pas de raison valable de retarder le déploiement d'IPv6. Ceux qui n'ont pas encore commencé devraient s'y mettre immédiatement.
Mais cela implique une longue période de coexistence avec IPv4. Pas pour tout le monde : il existe des réseaux un peu particuliers, des déploiements récents, contrôlés par une seule organisation, dans un environnement fermé (une usine, par exemple) et qui n'ont pas besoin d'échanger avec le reste du monde. Ceux-ci peuvent faire de l'IPv6 pur et ne pas lire ce RFC. Mais tous les autres doivent se poser la question « Qu'est-ce que je fais avec mes deux protocoles ? ».
Et cela va durer longtemps. Même si on peut espérer qu'un jour on éteigne la dernière machine IPv4, cela ne se produira pas avant de nombreuses années. Même si un réseau est entièrement IPv6, il faudra bien qu'il puisse communiquer avec des machines v4 à l'extérieur. (Le RFC ne mentionne pas le fait qu'actuellement, l'effort de la coexistence repose entièrement sur ceux qui veulent déployer IPv6. Une date importante sera celle où l'effort changera de camp et où ce sera ceux qui veulent continuer à utiliser IPv4 qui devront travailler pour cela. Cette date surviendra longtemps avant la disparition de la dernière machine IPv4.)
Ceux qui déploient IPv6 doivent donc choisir un modèle de déploiement. Le RFC 5218 rappelait, en s'inspirant de l'expérience de plusieurs protocoles, ce qui marche et ce qui ne marche pas. Certains de ces rappels semblent évidents (ne pas casser ce qui marche aujourd'hui, permettre un déploiement incrémental, puisqu'il n'y a aucune chance de faire basculer tout l'Internet d'un coup) mais sont toujours bons à garder en mémoire.
Voilà, après ces préliminaires, place aux techniques elle-mêmes, en section 4. Le début de cette section précise qu'elle n'est pas exhaustive : il existe d'autres mécanismes de coexistence/transition mais ils sont considérés comme relativement marginaux. Les techniques sont exposées dans l'ordre d'importance décroissante et les premières sont donc les plus recommandées.
Premier mécanisme de coexistence, et le plus recommandé, la double pile. Chaque machine a deux mises en œuvre des protocoles réseau, une pour IPv4 et une pour IPv6 et peut parler ces deux protocoles au choix. Ce modèle s'applique aussi bien sur la machine terminale (où les applications sont donc « bilingues ») que sur les routeurs du FAI (qui font tourner des protocoles de routage pour les deux familles, cf. RFC 6036 pour le point de vue du FAI). C'était le mécanisme de transition originellement envisagé. Le choix de la version d'IP dépend de la machine qui initie la connexion (RFC 6724), et de ce que la machine réceptrice a annoncé (par exemple dans le DNS). Ce mécanisme est simple et évite les problèmes qu'ont, par exemple, les tunnels, comme les problèmes de MTU. Comme le rappelle le RFC 4213, c'est la méthode recommandée.
Cela n'empêche pas ce modèle d'avoir des failles. D'abord, si l'adoption de ce modèle est une décision individuelle de chaque réseau, son utilisation nécessite que les deux réseaux qui communiquent aient adopté ce système. Si un client double-pile veut se connecter à un serveur en IPv6, celui-ci doit avoir une connectivité IPv6 (ce qui dépend de son FAI), doit avoir une application IPv6isée et doit avoir annoncé un AAAA dans le DNS. Autrement, on a IPv6, mais on n'observe guère de trafic. Inversement, lorsqu'un gros fournisseur de contenu active IPv6 (comme l'a fait YouTube en février 2010), le trafic IPv6 fait soudain un bond.
Une deuxième limite de l'approche double-pile est que certaines applications ne réagissent pas proprement lorsqu'un des protocoles fonctionne mais pas l'autre. De nos jours, c'est en général l'IPv6 qui a un problème et la double-pile peut alors entraîner une dégradation du service, l'application perdant bêtement du temps à tenter de joindre le pair en IPv6 au lieu de basculer tout de suite vers IPv4. Le code naïf de connexion d'un client vers un serveur est en effet (en pseudo-code) :
for Address in Addresses loop try connect_to(Address) exit loop except Timeout # Try the next one end try end loop
Cette approche purement séquentielle peut être pénible si les adresses
IPv6 sont en tête de la liste Addresses
et si le
délai de garde est long. Car chaque connexion fera patienter
l'utilisateur plusieurs secondes. (La durée exacte avant le
Timeout
dépend de la nature de la
non-connectivité IPv6 - le routeur envoie-t-il
un message ICMP ou pas, de ce que transmet la
couche 4 à l'application, etc.) C'est pour
cette raison que de nombreux gérants de gros services Internet
hésitent à activer IPv6 (par exemple, ce dernier est disponible pour
le service, mais n'est pas annoncé dans le DNS), de peur de pourrir la
vie d'une partie, même faible, de leurs utilisateurs. C'est ainsi que
www.google.com
n'a d'enregistrement
AAAA que pour certains réseaux, que
Google estime suffisamment fiables en IPv6. Ce
mécanisme de « liste blanche » où Google décide qui va pouvoir se
connecter à eux en IPv6 est contestable mais n'oublions pas que les
autres « gros » sites Internet ne font rien du tout.
Rendre les applications plus robustes vis-à-vis de ce problème pourrait aider (voir par exemple la technique proposée par l'ISC ou bien le très bon guide de programmation IPv6 d'Étienne Duble), surtout si ces mécanisme de connexion intelligents (tenter en parallèle les connexions v4 et v6) sont emballés dans des bibliothèques standard. Par exemple, la plupart des applications pair-à-pair gèrent relativement bien ce problème, habituées qu'elles sont à vivre dans un monde de connectivité incertaine et intermittente.
Ces défauts sont à garder en tête mais il n'en demeure pas moins que la double-pile reste la meilleure méthode, d'autant plus que de nombreux réseaux ont aujourd'hui IPv6 (le RFC cite les NREN comme Renater ou Internet2, complètement IPv6 depuis longtemps).
Une conséquence amusante de la double-pile est qu'elle nécessite une adresse IPv4 par machine. Cela ne semblait pas un problème au moment où ce mécanisme a été conçu, puisqu'il semblait possible de passer tout le monde en IPv6 avant l'épuisement des adresses v4. Comme cela ne s'est pas fait, on se retrouve aujourd'hui dans une situation où il n'y a plus d'adresses IPv4. La double pile est donc en général utilisée avec une adresse IPv6 publique et une IPv4 privée, NATée plus loin.
La double pile, c'est très bien mais que faire si on n'a pas de connectivité IPv6, et qu'on veut relier son réseau IPv6 au reste de l'Internet v6 ? La section 4.2 expose la solution des tunnels. L'intérêt des tunnels est qu'ils ne nécessitent aucune action sur les routeurs situés sur le trajet. On n'a pas à attendre que son FAI se bouge le postérieur et déploie IPv6. C'est une technique connue et éprouvée, qui est d'ailleurs utilisée pour bien d'autres choses qu'IPv6. L'inconvénient des tunnels est la complexité supplémentaire, et le fait qu'ils réduisent la MTU entraînant tout un tas de problèmes avec les sites qui bloquent stupidement l'ICMP.
Il existe plusieurs types de tunnels : les tunnels manuels du RFC 4213, des tunnels automatiques comme 6to4 (RFC 3056), les serveurs de tunnel présentés dans les RFC 3053 et RFC 5572, et bien d'autres, résumés dans le RFC 5565.
Lorsque le tunnel fait partie d'une solution gérée par un administrateur réseaux compétent, il ne pose pas de problème en soi. Mais certaines solutions techniques (comme 6to4) sont prévues pour être « non gérées » et elles ont toujours posé beaucoup de problèmes. Ainsi, elles peuvent donner aux applications l'impression qu'une connectivité IPv6 fonctionne alors qu'en fait les paquets ne reviennent pas. Beaucoup d'applications tentent alors de se connecter en IPv6 et mettent longtemps avant de s'apercevoir que cela ne marchera pas et qu'il vaut mieux se rabattre sur IPv4. 6to4 a donc beaucoup contribué à la réputation d'IPv6 comme technologie fragile et source d'ennuis. (La solution 6rd - RFC 5969, quoique dérivée de 6to4, n'a pas ces défauts.)
Pour l'instant, IPv6 est peu déployé et ce sont les gens qui veulent utiliser ce protocole qui doivent faire des efforts pour se connecter. Désormais que les adresses IPv4 sont épuisées, on commencera bientôt à voir des déploiements purement IPv6 et il faudra alors faire des efforts pour maintenir les vieux systèmes v4. Les sections 4.3 et 4.4 couvrent ces cas. En 4.3, la question est celle d'un nouvel entrant dans le monde des opérateurs qui n'a pas eu d'adresses IPv4 pour son beau réseau tout neuf et qui a donc déployé un cœur purement v6 ce qui, après tout, simplifie sa configuration. Mais ses clients, et les partenaires auxquels ses clients essaient de se connecter, sont restés en v4. Comment leur donner la connectivité qu'ils désirent ? Il va falloir cette fois tunneler IPv4 sur IPv6. Le modèle recommandé est DS-lite (Dual Stack Lite), dont le RFC n'est pas encore publié. Le principe est que le client recevra uniquement des adresses IPv4 privées, que le CPE fourni par le fournisseur d'accès encapsule les paquets IPv4 qu'émettrait un client, les tunnele jusqu'à un équipement CGN qui décapsulera, puis procédera au NAT44 classique. Le nouveau FAI aura donc quand même besoin de quelques adresses IPv4 publiques. Il existe déjà une mise en œuvre en logiciel libre de la fonction CGN, AFTR.
Autre cas, légèrement différent, est celui où le réseau local connecté à l'Internet n'a pas d'équipement IPv4 du tout. Tout beau, tout neuf, toutes ses machines (et les applications qu'elles portent) sont purement IPv6. Ce n'est pas aujourd'hui très réaliste avec des machines et des applications ordinaires mais cela pourrait arriver avec de nouveaux déploiements dans des environnements modernes. Le problème, décrit en section 4.4, est alors de se connecter quand même à d'éventuels partenaires restés v4. Une des solutions est le passage par un relais (j'en ai fait l'expérience lors d'un atelier de formation et Apache fait un très bon relais pour HTTP, permettant aux machines purement IPv6 de voir tout le ouèbe v4). Une autre solution est NAT64 (RFC 6144).
Puisqu'un certain nombre de trolls ont deversé du FUD sur la sécurité d'IPv6, la section 7, consacrée à ce sujet, est une bonne lecture. Elle rappelle que IPv6 a en gros le même niveau de sécurité qu'IPv4, c'est-à-dire pas grand'chose et que ce sont les implémentations et les déploiements qui apportent des risques, plus que les spécifications. Par contre, chaque technique de transition a ses propres risques de sécurité, en plus de ceux d'IPv6 ou d'IPv4 mais notre RFC ne les détaille pas, renvoyant aux normes décrivant ces techniques.
Conclusion ? La section 5, après cette longue énumération de bricolages variés recentre le débat : l'essentiel est d'activer IPv6. Une fois ce principe posé, cette section rappelle des points mentionnés au début comme le fait qu'il ne faut pas appliquer aveuglément la même technique à tous les réseaux. Ainsi, un réseau tout neuf ne fera sans doute pas les mêmes choix qu'un réseau existant depuis vingt et ayant accumulé plein de technologies historiques.
La section 6 propose une bibliographie pour ceux qui veulent approfondir le sujet : plein de RFC dont les RFC 4213, RFC 4038, RFC 6036, etc. D'autre part, j'avais fait un exposé au GUILDE à Grenoble sur ces sujets (IPv6 et la transition), exposé dont les transparents sont disponibles.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : F. Templin (Boeing Research & Technology
Expérimental
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 21 mars 2011
Sous la houlette du groupe de travail RRG (Routing Research Group) de l'IRTF, un gros effort est en cours pour définir une nouvelle architecture de routage pour l'Internet. Cette future architecture doit permettre de poursuivre la croissance de l'Internet sans se heurter aux limites quantitatives des routeurs, et en autorisant des configurations qui sont actuellement peu pratiques comme le multi-homing. Cet effort a été synthétisé dans les recommandations du RFC 6115. La plupart des propositions d'architecture résumées dans le RFC 6115 seront sans doute publiées, chacune dans son RFC. Notre RFC 6179 ouvre la voie en décrivant le système IRON (Internet Routing Overlay Network).
IRON fait partie de la famille des architectures Map-and-Encap où les réseaux ont un identificateur indépendant de leur position dans le réseau et où les routeurs doivent utiliser un mécanisme de mapping, de correspondance entre l'identificateur connu et le localisateur cherché, avant d'encapsuler les paquets, pour qu'ils puissent atteindre leur destination via un tunnel. L'originalité d'IRON est de combiner mapping et routage pour distribuer l'information nécessaire aux routeurs. Comme les autres architectures Map-and-Encap (par exemple LISP), IRON ne nécessite pas de changement dans les machines terminales, ni dans la plupart des routeurs, mais seulement dans les routeurs d'entrée et de sortie des tunnels.
Comme IRON utilise une terminologie très spéciale, qu'on ne trouve pas dans les autres protocoles, cela vaut la peine, si on veut lire ce RFC, de bien apprendre la section 2, qui décrit le vocabulaire. IRON est donc un système d'overlay, c'est-à-dire de réseau virtuel fonctionnant au dessus d'un réseau « physique », l'Internet. Il part de RANGER RFC 5720 en le généralisant à tout l'Internet. En partant du bas (la description du RFC, c'est peut-être symptomatique, part du haut), chaque organisation connectée à IRON (un EUN pour End User Network) aurait un préfixe à elle, un identificateur, nommé le EP (EUN Prefix). Ces préfixes viennent de préfixes plus larges, les VP (Virtual Prefix), qui sont alloués par de nouvelles organisations, les VPC (Virtual Prefix Companies). Ces organisations n'ont pas d'équivalent dans l'Internet actuel : les VPC pourraient être des FAI mais ce n'est pas obligatoire. Le RFC ne donne aucun détail sur les points non-techniques de cette architecture (par exemple, comment une VPC gagnera sa vie ? Si on change de VPC, pourra t-on garder son préfixe ?) considérant que ces questions sont hors-sujet pour une spécification technique.
Les routeurs IRON se connectent entre eux par des liens NBMA qui sont simplement des tunnels au dessus de l'Internet existant.
Toujours dans le vocabulaire original (IRON n'utilise pas les termes d'ITR - Ingress Tunnel Router - et ETR - Egress Tunnel Router - probablement parce que son architecture ne colle pas bien à ce modèle), IRON repose sur trois types de routeurs (appelés collectivement agents) :
Les détails de l'architecture sont ensuite détaillés en sections 3 à 6. Les agents IRON (les trois sortes de routeurs présentées plus haut) forment des tunnels entre eux, en utilisant la technique VET (Virtual Enterprise Traversal, RFC 5558) et encapsulent selon le format SEAL (Subnetwork Encapsulation and Adaptation Layer, RFC 5320). Curieusement, l'auteur prend soin de préciser que SEAL permet de tunneler d'autres protocoles qu'IP et il cite CLNP, ce qui donne une idée de l'âge des idées qui sont derrière SEAL...
SEAL dispose d'un protocole d'échange d'informations sur les routes, les MTU, etc, SCMP (SEAL Control Message Protocol) et c'est lui qui permet à l'overlay IRON de fonctionner.
Chaque VPC représente donc un morceau d'un patchwork global. Les morceaux sont connectés entre eux via l'Internet public. Le client final, lui, doit se connecter à l'Internet puis acquérir une connectivité IRON auprès d'une VPC, et s'équiper d'un routeur client qui va relier son EUN (son réseau local) à la VPC.
Pour amorcer la pompe (section 5), chaque relais est configuré avec la liste des VP qu'il va servir, la liste des serveurs (les routeurs des VPC), et avec celle de ses voisins BGP. Avec ces derniers, il établit des liens comme aujourd'hui et annonce sur ces liens les VP. Avec les serveurs, le relais découvre la correspondance entre les EP, les identificateurs des réseaux IRON et les serveurs. (Rappelons que les identificateurs, EP et VP, ont la même forme que des adresses IP et peuvent donc être annoncés comme tels aux routeurs BGP actuels.)
Les serveurs, eux, sont nourris avec la liste des relais, auxquels ils vont transmettre les VP qu'il servent. Ils attendent ensuite les connexions des clients, apprenant ainsi petit à petit les EP connectés, que les serveurs transmettront aux relais.
Les clients, eux, auront besoin de connaître les serveurs de leur VPC, ainsi que leurs EP, et un moyen de s'authentifier.
Une fois tout ceci fait, les routeurs n'ont plus qu'à router les paquets comme aujourd'hui (section 6, qui décrit les différents cas, notamment selon que le destinataire du paquet est dans IRON ou pas ; par exemple, le cas du multi-homing est en section 6.5.2, qui précise qu'un client peut avoir plusieurs localisateurs pour un même EP).
Et d'une manière plus générale, comment cela va se passer en pratique ? La section 7 se lance dans certains détails concrets. Par exemple, comme le routage à l'intérieur d'IRON est souvent sous-optimal, mais qu'un mécanisme d'optimisation des routes permet de les raccourcir par la suite, le premier paquet de chaque flot aura sans doute un temps de trajet bien supérieur à celui de ses copains.
Et, comme toute solution utilisant des tunnels, IRON aura sans doute à faire face à des problèmes de MTU, que cette section mentionne, mais jette un peu rapidement à la poubelle.
Toujours pour ceux qui s'intéressent aux problèmes concrets, l'annexe B est une très bonne étude des propriétés de passage à l'échelle d'IRON.
IRON ne semble pas avoir été testé, même en laboratoire, même tout simplement dans un simulateur. Et mon avis personnel ? Je dois avouer n'avoir pas tout compris et avoir la sensation inquiétante que ce n'est pas uniquement une limite de mon cerveau, mais que l'architecture d'IRON reste encore insuffisamment spécifiée.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : Thomas Narten (IBM), Geoff Huston (APNIC), Lea Roberts (Stanford University)
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 27 mars 2011
Ce RFC vient remplacer le RFC 3177 et modifier assez sérieusement les recommandations en matière d'allocation d'adresses IPv6 aux sites situés aux extrémités du réseau (entreprises, universités, particuliers, à l'exclusion des FAI et des opérateurs). Le RFC 3177 recommandait, en gros, de donner un préfixe de même longueur, un /48, à tout le monde. Ce nouveau RFC 6177 met un sérieux bémol à cette recommandation.
Le RFC 3177 avait été publié en
2001 et mis en œuvre par les
RIR dans leurs politiques d'allocation
d'adresses (celle du RIPE-NCC est en http://www.ripe.net/ripe/docs/ipv6policy.html
). À partir de 2005, plusieurs
critiques se sont fait jour (voir par exemple la
proposition 2005-08), menant à une révision de ces politiques
et à ce nouveau RFC 6177. Les critiques portaient aussi
bien sur la technique (un /48 n'est-il pas excessif ?) que sur la
politique (est-ce vraiment le rôle de l'IAB et
de l'IETF de recommander des politiques
d'allocation ?). Résultat, le « /48 pour tous » n'est plus la
politique officielle.
La section 1 de notre nouveau RFC rappele les principaux changements par rapport au RFC 3177 :
Mais alors, que reste-t-il du RFC 3177 ? Le principe comme quoi un site ne devrait pas avoir à geindre et à supplier pour avoir suffisamment d'adresses. En IPv4, la rareté des adresses justifiait les obstacles mis devant les utilisateurs mais, en IPv6, cet argument ne joue plus. Les sites devraient donc toujours avoir les adresses dont ils ont besoin, et ne jamais être contraints à utiliser des techniques comme le NAT pour économiser des adresses, ces économies étant tout à fait inutiles avec IPv6.
La question de l'allocation d'un /48 aux sites d'extrémité est discutée dans la section 2. La recommandation du RFC 3177 était fondée sur trois motivations :
ip6.arpa
seront plus simples à gérer si on change
juste de préfixe, sans avoir à réorganiser ses sous-réseaux. L'idée d'une même taille d'allocation
pour tous (de la grande université au particulier) est donc une mesure
de protection du client, de garantie qu'il n'y aura pas d'obstacle
artificiel à un changement de fournisseur.Mais, alors, quels sont les problèmes perçus avec cette recommandation du « /48 pour tous » ? D'abord, certains trouvent qu'elle mène au gaspillage. (Je pense personnellement que c'est un argument subjectif, sans base scientifique : il existe 280 billions de /48 disponibles, ce qui fait qu'on n'épuisera pas IPv6 en en donnant un à chacun.) Les partisans de cet argument disent souvent qu'on pourrait ne donner qu'un /64 aux particuliers (ce que fait aujourd'hui un FAI comme Free), oubliant qu'une maison bien dotée en appareils numériques peut avoir besoin de plusieurs réseaux, pas seulement d'adresses, et que, avec l'auto-configuration des adresses IPv6, il faut un /64 par réseau. Notre RFC 6177 demande donc qu'on donne à tous davantage qu'un /64 (un /56 est cité comme possibilité).
Notons que notre RFC 6177 ne traite pas explicitement le cas des hébergeurs de serveurs dédiés comme Gandi ou OVH. Par exemple, Gandi ne permet apparemment qu'une seule adresse IPv6 par machine, rendant ainsi difficile d'y faire tourner plusieurs serveurs. (Pour OVH, l'information est en ligne, avec l'orthographe habituelle de ce fournisseur.)
Le RFC 3177 contenait d'autres points (section 3). Par exemple, il rappelait explicitement que la règle d'un /48 pour tous limitait le pouvoir des intermédiaires : sans avoir à demander, sans remplir de paperasserie, l'utilisateur avait droit à une quantité d'adresses suffisante. C'est hélas quelque chose qui sera différent désormais, l'utilisateur devra à nouveau affronter un bureau insensible pour avoir la quantité d'adresses nécessaire.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : E. Juskevicius (TrekAhead)
Pour information
Première rédaction de cet article le 11 mars 2011
Comme toute organisation qui manipule de grandes quantités de documents, et des processus formalisés complexes, l'IETF a besoin de logiciels qui mettent en œuvre ces processus. Le principal outil est le Datatracker et ce RFC 6175 est le cahier des charges pour une nouvelle extension du Datatracker.
Le Datatracker sert entre autres à suivre l'état des Internet-Drafts. Il était traditionnellement très détaillé pour la phase d'évaluation à l'IESG de ces documents, et nettement moins précis pour les autres phases. Ce service était très réclamé depuis longtemps. Ce cahier des charges demande donc que le Datatracker soit mis à jour pour gérer les états décrits par le RFC 6174.
Quelques rappels, en section 2, pour les gens qui ne suivent pas
l'évolution du vocabulaire IETF. Tous les
Internet-Drafts ne sont pas forcément liés à un
groupe de travail de l'IETF. Ceux qui le sont, parce qu'un groupe a
décidé de les adopter, sont qualifiés de
WG draft. Leur nom est du type
draft-ietf-wgname-...
. Ces
drafts, et ceux qui sont candidats à
l'adoption mais n'ont pas encore été adoptés, sont ensemble les associated
with a WG. Dans le cas où ils ne sont pas encore adoptés,
leur nom inclus l'acronyme du groupe de travail mais ne commence pas
par draft-ietf
. Enfin, tous les autres
Internet-Drafts sont qualifiés
d' « individuels ».
Les exigences générales sur le « nouveau »
Datatracker figurent en section 3. Chacune est
numérotée. La première, R-001, est que le
Datatracker doit
permettre aux présidents des groupes de travail de l'IETF de saisir
directement l'état des I-D, en suivant les états
décrits dans le RFC 6174. Parmi les
autres exigences (consultez le RFC pour une liste complète), le fait
que tout changement doit être estampillé, lié à
une personne précise
(R-007) et que la date et l'heure de ce changement soient
affichées. Le Datatracker doit étendre la
machine à états existante (illustrée en https://datatracker.ietf.org/images/state_diagram.gif
), pas la
remplacer (R-011). Et les présidents d'un groupe de travail doivent
pouvoir agir sur l'état d'un I-D, indépendemment de son statut à
l'IESG (R-012).
La section 4 est consacrée aux questions d'autorisation. En lecture, le Datatracker est accessible à tous (R-013), l'IETF tirant une grande fierté de son ouverture au public (contrairement à la majorité des SDO, qui travaillent derrière des portes closes). Mais en écriture, les personnes qui peuvent modifier l'état d'un I-D doivent d'abord s'authentifier auprès du Datatracker (et inutile de dire que l'IETF n'utilise pas Facebook Connect). La section 11 note d'ailleurs les conséquences que cela peut avoir en matière de sécurité.
Les présidents des groupes de travail doivent avoir la possibilité (section 4.2) de modifier l'état de tous les Internet-Drafts de leur groupe, en restant dans la liste d'états pré-définie (cf. RFC 6174 et voir aussi la section 5.1), peuvent désigner jusqu'à trois délégués pour les aider, etc. Une autre population intéressante est celle des pasteurs (sheperds, cf. RFC 4858). Ceux-ci (section 4.4) sont chargés de suivre un document particulier et doivent donc pouvoir déposer le write-up, le formulaire rempli qui indique à l'IESG les points importants du document (voir aussi la section 5.3). Au sommet de cette série de personnes privilégiées, se trouvent évidemment les directeurs de secteurs (Area Directors), qui couvrent chacun plusieurs groupes de travail et doivent également pouvoir mettre à jour l'état des documents (section 4.5).
Certains états des documents posent des problèmes particuliers et la section 6 les énumère. Ainsi, un document peut être garé (parked document, section 6.4) lorsqu'il a perdu son auteur. Le directeur de secteur a alors des pouvoirs supplémentaires, comme de le transférer à un autre groupe de travail. Plus triste, un document peut aussi mourir (dead document, section 6.5) lorsque tout travail le concernant a été abandonné. Là encore, le directeur peut le transférer.
Jusqu'ici, on a parlé des changements manuels, comme lorsque le
président d'un groupe de travail met à jour l'état d'un I-D
(Internet-Draft). Y a-t-il aussi des changements
automatiques ? Oui, et la section 7 liste les cas où le
Datatracker doit agir seul. Par exemple, si une
nouvelle version d'un document a un nom qui commence par
draft-ietf
, le document devient automatiquement
document d'un groupe de travail (avant, c'était juste une convention :
désormais, cela fait partie des règles mises en œuvre
automatiquement).
Quelles sont les informations qui doivent être affichées par le Datatracker ? Les sections 8 et 9 les définissent. Par exemple, le Datatracker doit garder trace de l'historique complet du document puisqu'il doit pouvoir le montrer à quiconque a les droits d'écriture (la foule anonyme n'a droit qu'à l'affichage de l'état actuel).
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : E. Juskevicius (TrekAhead)
Pour information
Première rédaction de cet article le 11 mars 2011
Le processus de production de normes au sein de l'IETF était historiquement informel et peu documenté. Petit à petit, il s'est formalisé (voire ossifié) et a même reçu l'aide de logiciels permettant de suivre l'avancement des travaux. Ce RFC de processus décrit des nouveaux états que peut avoir un document en cours de discussion à l'IETF.
Une des particularités de l'IETF est son ouverture. Tout le monde doit pouvoir suivre l'état d'avancement des travaux, via l'Internet. C'est ce que permet par exemple le Datatracker de l'IETF qui donne accès à l'état (en février 2011) du document sur la syntaxe des TLD (apparemment abandonné, et tant mieux), à celui de la documentation de l'AS 112 (adopté par un groupe, mais perdu dans les sables bureaucratiques depuis très longtemps), à celui sur l'enregistrement DNS CERT (pas adopté par un groupe de travail), ou à celui sur le protocole LISP (en plein développement par un groupe de travail).
Les informations affichées par le Datatracker n'étaient pas toutes documentées et certaines, non actuellement affichées, pourraient être nécessaires. Ce RFC 6174 documente donc les états possibles des documents.
Le Datatracker gère bien d'autres choses que les
documents, puisqu'il donne aussi accès aux revendications
d'appropriation intellectuelle, et à d'autres aspects de la vie
de l'IETF. Concernant le document, la version du
Datatracker en service fin 2010 ne permettait de
suivre que les documents présentés à l'IESG
pour évaluation. Avant cela, il ne savait pratiquement d'un document que le fait
qu'il soit Active
(en cours de discussion) ou
Expired
(les Internet-Drafts
ont une durée de validité de six mois). Or le processus (décrit dans
le RFC 8729 est bien plus riche.
Comme le rappelle la section 2 de notre RFC, un Internet-Draft peut être complètement individuel ou bien être un Working Group I-D si un groupe de travail IETF a décidé de l'adopter et de travailler sur ce document. Dans ce cas, sa vie au sein du groupe passe par plusieurs stades qui étaient ignorés du Datatracker.
La section 3 résume en effet l'état du
Datatracker fin 2010. Si ce dernier connaissait
tous les détails de l'évaluation à l'IESG, la vie du document avant
son passage devant cet aréopage était nettement moins détaillé, le
Datatracker ne prenant en compte que la
disponibilité du document. La
section 3.1 donne une liste complète. Celle-ci inclut, comme vu plus haut,
Active
et Expired
, mais
aussi des états comme Replaces
et
Replaced-by
qui indique le remplacement d'un
Internet-Draft par un autre, équivalent. Cela se
produit typiquement lors de l'adoption d'un draft
par un groupe de travail. Si le document était nommé
draft-authorname-topic-nn
, il devient alors
draft-ietf-wgname-topic-00
. À noter qu'il
n'existe pas de moyen automatique pour identifier ce remplacement (les
Internet-Drafts n'ont pas de métadonnées structurées), le
président du groupe de travail doit l'indiquer explicitement.
Une fois le document terminé par le groupe de travail, il passe à l'IESG pour évaluation. Cette phase est celle qui a suscité le plus de formalisation et celle-ci est décrite dans la section 3.2 (avec l'intégralité des états dans l'annexe A). Un Internet-Draft peut ainsi être, entre autres :
Publication requested
, le premier stade,
suivant les procédures de la section 7.5 du RFC 2418.AD evaluation
qui indique qu'un AD (un
Area Director, la personne coresponsable d'une zone
de travail de l'IESG comme le routage, la sécurité, les applications)
est en train d'évaluer le document.IESG evaluation
qui indique que le document
est désormais évalué par toute l'IESG, c'est-à-dire par tous les
AD. Chacun peut émettre une objection bloquante, connue sous le nom
(fort mal choisi) de DISCUSS
.Quels sont les nouveux états possibles pour un document, créé par ce RFC 6174 ? La section 4 les détaille et s'appuie pour cela sur une machine à états (figure 1). Ils sont déjà mis en œuvre dans le Datatracker et se trouvent simplement documentés ici, par exemple (ce n'est pas une liste complète) :
Call for adoption
quand un document est
encore individuel mais que son auteur a demandé qu'un groupe de
travail l'adopte comme document de travail officiel du groupe,Adopted
, une fois que c'est fait ; le
document prendra alors un nom du genre draft-ietf-workingroupname-topic-00
,Working Group document
une fois que le
travail du groupe a effectivement commencé,Working Group Last Call
; le sigle WGLC
apparît souvent dans les listes IETF car cet état est une partie
importante (quoique optionnelle, cf. RFC 2418) du folklore de cette organisation. C'est le dernier moment
où le groupe peut donner son avis avant que le document, transmis à
l'IESG, ne lui échappe.Working Group consensus, waiting for
write-up
, qui indique que le document fait l'objet
d'un large consensus dans le groupe, et qu'il a juste besoin d'un
write-up, le formulaire qui accompagne tout envoi à
l'IESG et qui explique à celle-ci les points importants (comme
l'existence de mises en œuvre, l'état effectif du consensus, les
menaces d'appel, etc, voir RFC 4858),Submitted to IESG
, lorsque le travail du
groupe est fini,Outre ces états, qui sont mutuellement exclusifs, le document peut porter un certain nombre d'étiquettes indiquant des points importants du processus, parmi lesquelles :
Awaiting Expert Review/Resolution of Issues
Raised
qui indique qu'un examen du document par un expert
du domaine
est en cours (de tels examens existent, par exemple, pour toutes les
MIB, qui sont vérifiées par un spécialiste
ès-MIB),Waiting for Referencing Document
, le
document dépend d'un autre document, pas encore prêt,Revised I-D Needed - Issue raised by WGLC
,
lorsque le dernier appel à commentaires dans le groupe de travail a
suscité des problèmes suffisamment sérieux pour justifier un nouvel ID
(Internet-Draft).Enfin, un autre champ est spécifié, en section 5. Tout document doit avoir un « niveau de normalisation visé » qui indique si le groupe de travail veut voir le futur RFC sur le chemin des normes, ou simplement « Pour information » ou encore purement « Expérimental ». (Ces niveaux sont expliqués dans le RFC 2026.)
La mise en œuvre de ces nouveaux états dans le Datatracker se fera suivant le cahier des charges contenu dans le RFC 6175.
Une lecture intéressante sur le sujet de la vie des Internet-Drafts est « Guidelines to Authors of Internet-Drafts ».
Date de publication du RFC : Mai 2011
Auteur(s) du RFC : W. Hardaker (Sparta)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 4 mai 2011
Traditionnellement, les serveurs DNS étaient
gérés par des mécanismes spécifiques au logiciel
utilisé. BIND a son rndc
,
Unbound son
unbound-control
(voir des exemples à la fin), d'autres logiciels utilisent
d'autres méthodes et on n'avait pas de moyen facile de gérer un ensemble
hétérogène de serveurs. En outre, ces programmes n'étaient pas prévus
pour des autorisations précises (modifier telle zone mais pas telle
autre) et cela rendait difficile de déléguer la gestion d'une
partie du service à un
tiers. L'IETF est donc lancée depuis quelques
années dans un effort pour mettre en place un mécanisme standard de
gestion à distance des serveurs DNS et ce RFC 6168 en est
le cahier des charges formel.
Car c'est un vieux projet ! Une des étapes avait été la publication, il y a plus de quatre ans, du brouillon « Requirments for the Nameserver Communication protocol ». Il y a eu ensuite un groupe de travail restreint, nommé DCOMA, dont j'ai fait partie. Le projet a avancé à une allure de tortue mais, au moins, il a désormais un cahier des charges figé. Avant même le document cité plus haut, un effort de normalisation avait mené à deux MIB, décrites dans les RFC 1611 et RFC 1612, qui n'avaient jamais été réellement déployées et ont été officiellement abandonnées par le RFC 3197.
L'annexe A rassemble quelques études de cas, pour illustrer à quoi
pourrait servir un tel protocole. Par exemple, en A.1 se trouve le cas
de zones locales non-standard comme un .prive
ou
.local
. Si des TLD locaux
sont une
mauvaise idée, ils n'en sont pas moins très utilisés et des
domaines purement locaux peuvent avoir un sens dans certains
cas. Actuellement, pour qu'un tel système fonctionne, il faut mettre
des directives stub
ou
forward
dans tous les
résolveurs de l'organisation, et garder ces résolveurs (qui peuvent
être de marques différentes) synchronisés. D'une façon générale, gérer
un pool de résolveurs DNS qui doivent avoir la même
configuration (par exemple les mêmes clés
DNSSEC, cf. annexe A.3) est une tâche courante pour un
FAI et plutôt pénible. Le futur protocole de
contrôle pourrait faciliter l'automatisation de cette tâche.
A.2 propose un autre cas, dans l'optique de résilience maximale
d'une zone DNS : le RFC 2182 recommande à juste
titre qu'une zone DNS soit servie par plusieurs serveurs de noms, ne
partageant pas de SPOF. Une solution fréquente
est l'hébergement réciproque des zones d'un partenaire. Par exemple
(au 12 avril 2011), l'AFNIC héberge un serveur
secondaire de .nl
et
SIDN (Stichting Internet Domeinregistratie Nederland) a un serveur secondaire de
.fr
. La configuration
correspondante est actuellement maintenue à la main, ou par des
logiciels ad hoc. Ainsi, si un TLD dont le
serveur secondaire est à l'AFNIC, veut tout à coup autoriser le
transfert de zones, ou au contraire le restreindre à certaines
adresses IP, il doit envoyer un message et attendre qu'un technicien
de l'AFNIC
ait changé la configuration. De même, si deux hébergeurs DNS assurent
réciproquement un service de secours en hébergeant les zones de
l'autre, la création d'une nouvelle zone doit actuellement être
automatisée par des moyens spécifiques du logiciel utilisé. À noter
que ce cas nécessite des autorisations à grain fin, comme rappelé en
section 4.4.
Ce cahier des charges concerne à la fois les serveurs faisant
autorité (par exemple ceux de
.FR
) que les récurseurs
(par exemple les résolveurs de votre FAI). La
section 2.2 donne des détails sur les types de serveurs qui seront
gérés (les maîtres, les esclaves, et les récurseurs). Les
stub resolvers (la bibliothèque de résolution de
noms sur votre machine) sont exclus du champ d'application de ce
projet. De même, le futur protocole qui mettre en œuvre ces
exigences ne s'occupera que de la configuration des serveurs, pas des
données servies (pour lesquelles il existe déjà des protocoles
standard de transmission, cf. RFC 2136 et RFC 5936).
Le RFC est écrit sous forme d'une suite d'exigences, chacune dans sa propre section. Donc, le numéro de section identifie l'exigence. Voyons les principales.
L'exigence 2.1.1 concerne la taille : parmi les serveurs faisant
autorité, il y en a avec peu
de zones mais beaucoup de données dans ces zones (les serveurs des
TLD par exemple) et d'autres avec beaucoup de
toutes petites zones (un hébergeur DNS qui accueille des centaines de
milliers de mapetiteentreprise.com
). La solution
doit convenir pour toutes les tailles.
La solution pourra permettre la découverte automatique des serveurs de noms existant sur le réseau mais ce n'est pas obligatoire (exigence 2.1.2).
Elle devra fonctionner pour des serveurs dont la configuration change souvent (nombreuses zones ajoutées et retirées par heure, par exemple, exigence 2.1.3).
Pour contrôler quelque chose, il faut un modèle décrivant la chose en question. L'exigence 2.1.5 impose donc la création d'un modèle de données d'un serveur de noms. Enfin, 2.1.6 impose que la nouvelle solution n'interfère pas le service principal, le DNS lui-même.
La section 3 décrit les classes d'opérations de gestion à implémenter :
Le futur protocole devra gérer toutes ces classes.
Quelles sont les opérations à faire sur un serveur de noms ? La section 3.1 liste les plus importantes :
À noter que l'opération « démarrer le serveur » est la seule qui ne puisse pas être mise en œuvre dans le serveur lui-même.
Comme certaines de ces opérations peuvent être très longues (la seule lecture du fichier de zone d'un gros TLD peut prendre du temps), la même section demande en outre que le futur protocole ait un mécanisme de notification asynchrone (« fais ça et préviens-moi quand c'est fini »).
Et question configuration, que doit-on pouvoir configurer ? La section 3.2 donne une liste :
foobar.example
et ton maître est
2001:db8:2011:04:11::53
»), ce qui n'est pas
possible de manière standard actuellement,Le protocole, on l'a vu, doit également permettre la surveillance du bon fonctionnement du serveur. Des exemples de données utiles sont (section 3.3) :
Le serveur doit pouvoir transmettre ces informations à la demande du logiciel de surveillance, mais aussi pouvoir sonner des alarmes sans qu'on lui ait rien demandé (section 3.4) :
Un tel protocole, riche en fonctions, peut attirer l'attention des méchants : arrêter à distance un serveur de noms, sans avoir besoin de se connecter sur la machine, est tentant. D'où la section 4 qui pose les exigences de sécurité du protocole (voir aussi section 6). La plus importante est l'exigence d'une authentification mutuelle : le serveur de noms doit pouvoir authentifier le logiciel de gestion et réciproquement. Il est également nécessaire que le protocole soit confidentiel : des informations secrètes (comme les clés TSIG) seront parfois transmises par ce canal. Et, une fois l'authentification faite, le protocole doit permettre d'exprimer des autorisations détaillées : tel client peut ajouter des zones mais pas redémarrer le serveur, tel client peut lire toutes les informations mais n'en modifier aucune, etc.
La section 5 est ensuite un pot-pourri d'exigences supplémentaires pour le futur protocole de contrôle des serveurs de noms. On y trouve les grands classiques comme l'extensibilité dans le temps (futures fonctions) et dans l'espace, via des extensions spécifiques à un vendeur (un logiciel donné peut toujours avoir des fonctions très spéciales, trop spéciales pour être normalisées, mais qu'il serait intéressant de contrôler via le protocole).
Pour avoir une idée plus précise des fonctions d'un tel protocole, on peut regarder ce qui existe aujourd'hui. Comme exemple de serveur faisant autorité, essayons BIND. Son outil de contrôle à distance se nomme rndc. Il y a plusieurs moyens de le configurer (la plupart des paquetages binaires de BIND font tout cela automatiquement), ici, je vais générer une clé d'authentification et un fichier de configuration à la main. La clé est une clé secrète partagée, on la génère avec dnssec-keygen :
% dnssec-keygen -a hmac-md5 -n HOST -b 128 samplekey
Le fichier produit, ici
Ksamplekey.+157+06915.private
, contient le
secret :
% cat Ksamplekey.+157+06915.private ... Key: 7fCXQYhOXW+jkpEx9DuBdQ== ...
On va alors créer le fichier de configuration de rndc. Comme il contient un secret (la clé), il faudra s'assurer que ce fichier ait les bonnes protections :
options { default-server localhost; default-key samplekey; }; server localhost { key samplekey; addresses { ::1 port 9153; }; }; key samplekey { algorithm hmac-md5; secret "7fCXQYhOXW+jkpEx9DuBdQ=="; };
Et il faut configurer le serveur de noms, dans son
named.conf
. Ici, le protocole de contrôle
n'acceptera que localhost
(::1
) sur le port 9153 (la valeur par défaut est 953) :
key samplekey { algorithm hmac-md5; secret "7fCXQYhOXW+jkpEx9DuBdQ=="; }; controls { inet ::1 port 9153 allow {::1;} keys {samplekey;}; };
Je me répète, attention à la sécurité. Car, s'il peut lire la clé, un utilisateur pourra arrêter BIND, supprimer des zones, etc.
Voyons maintenant des exemples d'utilisation :
% rndc status version: 9.8.0 number of zones: 2 ... server is up and running
Cette commande était bien inoffensive. Mais on peut en faire d'autres comme :
rndc reload
$MAZONE
),rndc stop
),rndc addzone example.com '{ type master; file "example.com"; };'
),
À la lumière du cahier des charges, que manque t-il à BIND ? Les
grandes lignes y sont mais il manque pas mal de détails comme les notifications asynchrones, les changements d'ACL et peut-être la finesse des
autorisations. rndc addzone
nécessite une option spéciale dans named.conf
mais elle s'applique à toutes les zones et, de toute façon, on ne peut
pas la lier à certaines clés seulement. Une fois qu'on a un accès au
serveur, c'est un accès total.
Comme exemple de serveur récursif, prenons
Unbound. La configuration se fait dans le
unbound.conf
à peu près comme ceci (même adresse
et port qu'avec BIND plus haut) :
remote-control: control-enable: yes control-interface: ::1 control-port: 9153 server-key-file: "unbound_server.key" server-cert-file: "unbound_server.pem" control-key-file: "unbound_control.key" control-cert-file: "unbound_control.pem"
Les certificats X.509 utilisés pour
l'authentification peuvent facilement être créés avec
unbound-control-setup
. Le programme de contrôle
du serveur utilise le même fichier de configuration
unbound.conf
(contrairement à BIND) :
% unbound-control status version: 1.4.5 verbosity: 4 threads: 1 modules: 2 [ validator iterator ] uptime: 206 seconds unbound (pid 5315) is running...
et on peut faire plein de choses avec ce programme comme arrêter le
serveur (unbound-control stop
), afficher d'utiles
statistiques (nombre de requêtes, nombre de succès et d'échecs de
cache, etc, avec unbound-control stats
), activer
ou désactiver le relayage vers un autre serveur
(unbound-control forward 2001:db8:42::53
), vider
le cache pour une zone donnée (unbound-control flush_zone
example.com
, notez qu'unbound_control
a d'autres commandes de vidage, plus ou moins subtiles), etc.
Par rapport aux exigences de notre RFC 6168, on note
que unbound-control
ne permet pas de changer les
clés de confiance utilisées par le serveur. Il ne peut pas non plus
afficher les zones définies localement sur le récurseur (mais il
permet d'en ajouter). Et la finesse des autorisations est insuffisante
(la possibilité de créer des zones locales est ouverte à tous ceux qui
ont un accès.) Autrement, il a une bonne partie de ce
qu'il faut pour un récurseur.
Maintenant que le cahier des charges est fait, quelles sont les
solutions pour le mettre en œuvre ? Historiquement, le protocole
officiel de gestion des machines, à l'IETF,
était SNMP. Comme on l'a vu, il y a même eu une
tentative de s'en servir avec les serveurs DNS, tentative qui n'est
pas allé loin. Aujourd'hui, la mode est plutôt à un autre protocole de
gestion, Netconf (RFC 6241). Il existe une proposition, documentée dans
l'Internet-Draft draft-dickinson-dnsop-nameserver-control
,
qui utilisera dans le futur Netconf (une version précédente de cette
proposition incluait le protocole, et même une implémentation, mais la version actuelle se concentre sur le modèle de données). Voir la présentation au CENTR à Amsterdam en mai 2011.
Aux diverses réunions IETF sur le sujet, une alternative ne nécessitant pas un nouveau protocole avait souvent été proposée : se servir d'outils de gestion de configuration comme Chef ou Puppet. La principale limite de ces outils est qu'ils ne conviennent qu'à l'intérieur d'une même organisation et ne règlent pas facilement des problèmes multi-organisations.
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : M. Kohno (Juniper Networks, Keio University), B. Nitzan (Juniper Networks), R. Bush, Y. Matsuzaki (Internet Initiative Japan), L. Colitti (Google), T. Narten (IBM Corporation)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 23 avril 2011
Quelles adresses IP utiliser sur un lien point-à-point, lorsque les deux machines qui se parlent sont seules sur le lien ? Ce nouveau RFC recommande l'utilisation d'un préfixe de longueur /127 pour IPv6, ne permettant que deux adresses IP.
Cette recommandation existait déjà pour IPv4, dans le RFC 3021, qui recommande un /31. Pour IPv6, la norme, en l'occurrence le RFC 4291 préconisait au contraire un préfixe /64 pour tous les liens. Les adresses sous ce préfixe pouvaient alors être construites selon le format dérivé du EUI-64. Certains opérateurs avaient déjà ignoré cette norme et utilisaient des préfixes de longueur /127 (ne laissant qu'un seul bit pour identifier la machine), malgré l'avis du RFC 3627, qui mettait en avant le risque de confusion avec l'adresse anycast des routeurs. Notre RFC 6164 leur donne raison et officialise les préfixes /127.
Lorsqu'il n'y a que deux machines sur un lien (par exemple une
liaison point-à-point, que ce soit parce
qu'elle utilise un technologie purement point-à-point ou bien
simplement parce qu'elle a été configurée ainsi), on peut aussi utiliser
les adresses locales au lien (fe80::/10
). Mais,
comme le rappelle la section 2 de notre RFC, celles-ci ne sont pas
toujours suffisantes : surveillance du réseau à distance,
traceroute et BGP sont
des exemples de bonnes raisons pour utiliser des adresses
globales.
Quelles étaient les raisons pour se méfier des préfixes de longueur 127 ? La section 4 résume la principale : confusion possible avec l'adresse des routeurs du lien, définie en section 2.6.1 du RFC 4291. Or, non seulement l'expérience des opérateurs qui ont violé le RFC 3627 a été positive (pas de problèmes notés) mais on peut trouver des très bonnes raisons pour utiliser des préfixes plus spécifiques qu'un /64. La section 5 cite :
Synthétisant tout cela, la section 6 de notre RFC conclut qu'il faut utiliser les /127. Le logiciel des routeurs doit accepter de tels préfixes. Les opérateurs doivent faire attention à ne pas utiliser certaines adresses, celles-ci ayant une signification particulière : adresses où les 64 bits les plus à droite sont nuls, ou bien adresses dont ces mêmes bits ont une des 128 plus grandes valeurs (réservées par le RFC 2526).
Pour un exemple des discussions récurrentes /64 vs. /127, voir « Point-to-point Links and /64s ». Le RFC 3627 a été officiellement déclaré « d'intérêt historique seulement » par le RFC 6547. À noter que ce RFC 6164 ne met pas à jour formellement le RFC 5375, qui continuait avec les anciennes recommandations.
Date de publication du RFC : Avril 2010
Auteur(s) du RFC : G. Camarillo, O. Novo (Ericsson), S. Perreault (Viagenie)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 avril 2011
Le protocole TURN, qui permet à deux machines coincées derrière des routeurs NAT de communiquer en utilisant un relais tiers, a été normalisé dans le RFC 5766, dans une version minimale, uniquement pour IPv4 et seulement pour UDP, les services « incontestables », qui étaient pressés d'avoir une solution. Depuis, des extensions à TURN sont développées pour d'autres services. C'est ainsi que ce RFC 6156 permet d'utiliser TURN pour établir des liaisons en IPv6. Cette extension à TURN a depuis été intégrée dans la norme de base, le RFC 8656, remplaçant ce RFC.
Cette extension permet de communiquer avec une machine IPv4 depuis une machine IPv6, avec une machine IPv6 depuis une autre machine IPv6 et enfin avec une machine IPv6 depuis une machine IPv4 (section 1 du RFC). C'est donc une véritable solution de communication entre les deux protocoles, travaillant dans la couche 7 (contrairement aux techniques comme le NAT qui travaillent dans la couche 3). Le serveur TURN relais la totalité des données entre les deux clients TURN.
On peut se demander si un tel service est bien nécessaire. Après tout, TURN avait été inventé pour le cas du NAT, qui lui-même était motivé par le faible nombre d'adresses IPv4 disponibles. En IPv6, le problème de la pénurie ne se pose pas et TURN semble inutile. Toutefois, comme le note le RFC 5902, il risque d'y avoir quand même des réseaux IPv6 NATés, peut-être avec des adresses ULA à l'intérieur, et TURN peut donc trouver sa place ici. Autre utilité : TURN peut aider les machines purement v4 (la majorité d'aujourd'hui) et les machines purement v6 (qui se répandront sans doute) à communiquer entre elles. Enfin, TURN peut aussi être utile pour un administrateur de pare-feu à état pour permettre aux utilisateurs d'ouvrir des ports afin de recevoir des connexions entrantes. TURN a été conçu pour qu'il soit très restreint dans ce qu'il accepte, de façon à ce que les administrateurs de pare-feux puissent lui faire confiance.
La nouvelle extension fonctionne avec un nouvel attribut TURN,
REQUESTED-ADDRESS-FAMILY
, valeur 0x0017 (section 3). L'attribut
XOR-RELAYED-ADDRESS
(RFC 5766, section 14.5, et section 4.2 de notre RFC) de la réponse contiendra une
adresse de la famille demandée (v4 ou v6). La famille d'adresse du
client est déterminée, elle, en regardant l'adresse utilisée pour
contacter le serveur. À noter que chaque demande
d'allocation TURN ne peut gérer qu'une seule adresse IP. Le client qui
voudrait communiquer avec une adresse IPv4 et une v6 devra faire deux
demandes d'allocation. Si le serveur ne veut ou ne peut pas gérer une
famille donnée, il répondra 440 (Address Family not
Supported
).
La section 4 contient ensuite les détails concrets comme le format du nouvel attribut (section 4.1.1). Celui-ci a le numéro 0x0017, ce qui le met dans les plages des attributs dont la compréhension par le serveur est impérative. Un vieux serveur qui ne met pas en œuvre notre RFC ne peut donc pas ignorer cet attribut.
Un problème qui a toujours été très chaud dans le groupe Behave est celui de la traduction des paquets. Comme on dit en italien, « Traduttore, Traditore » (traducteur = traître). Lorsqu'un serveur TURN relaie des paquets, doit-il respecter toutes les options de l'en-tête IP ? La question est évidemment encore plus difficile pour une traduction entre IPv4 et IPv6. La section 8 fournit les règles. Par exemple, lors de la traduction de IPv4 vers IPv6 (section 8.1), que doit valoir le champ Traffic Class (RFC 2460, section 7) d'un paquet IPv6 sortant ? Le comportement souhaité est celui spécifié dans la section 3 du RFC 7915 (RFC qui décrit le mécanisme de traduction de IPv4 vers IPv6, notamment pour l'utilisation dans NAT64). Le comportement possible est d'utiliser la valeur par défaut de ce champ. Le Flow label (RFC 2460, section 6), lui, devrait être mis à zéro (il n'a pas d'équivalent IPv4). Et pour les en-têtes d'extensions IPv6 (RFC 2460, section 4) ? Aucun ne doit être utilisé, dans tous les cas (sauf la fragmentation).
Et si on relaie entre deux machines IPv6 ? Ce sont quasiment les mêmes règles, comme indiqué par la section 8.2. Par exemple, bien qu'il existe un Flow label des deux côtés, on considère que TURN, relais de la couche 7, ne devrait pas essayer de le copier : il y a deux flots différents de part et d'autre du serveur TURN.
Cette extension de TURN pose t-elle des problèmes de sécurité ? Potentiellement oui, répond la section 9. En effet, elle donne aux machines des capacités nouvelles. Ainsi, une machine purement IPv6 obtient, si elle a le droit d'accéder à un serveur TURN mettant en œuvre ce RFC 6156, la possibilité de parler aux machines purement IPv4, possibilité qu'elle n'avait pas avant. Comme il est recommandé de ne faire fonctionner TURN qu'avec une authentification préalable des clients, ce n'est sans doute pas une question sérieuse en pratique.
La section 10 décrit l'enregistrement à
l'IANA des nouveaux paramètres (attribut
REQUESTED-ADDRESS-FAMILY
et codes d'erreur 440 et
443) dans le registre
des paramètres STUN (rappelez-vous que TURN est défini comme
une extension de STUN).
Question mise en œuvre, il en existe une côté serveur, non
distribuée mais accessible vie le réseau (voir http://numb.viagenie.ca/
), une libre qui a IPv6 depuis la version 0.5, mais apparemment rien encore côté
client.
Merci à Simon Perreault pour sa relecture et ses remarques.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : S. Turner (IECA), L. Chen (NIST)
Pour information
Première rédaction de cet article le 7 mars 2011
Ce RFC marque un peu l'enterrement officiel de MD5 dans les protocoles IETF. Cet algorithme de cryptographie, très répandu et très utilisé, décrit dans le RFC 1321, a connu de nombreuses attaques cryptanalytiques réussies et, pour plusieurs de ces usages, ne doit plus être considéré comme offrant une protection raisonnable. Une bonne partie de la sécurité de l'Internet reposait historiquement sur des protocoles utilisant MD5 et c'est donc un chapitre important qui se clot.
Peut-on dire aujourd'hui que MD5 est « cassé » et n'offre plus aucune protection ? La réponse doit en fait être plus nuancée et cela explique que ce très court RFC ait fait l'objet d'une aussi longue discussion à l'IETF, pour ne sortir que maintenant. En effet, si on voit souvent des affirmations hâtives de la part des ignorants, prétendant sans nuance que MD5 a été cassé, la réalité est plus complexe.
La section 1 rappelle en effet l'état de l'art. MD5 est utilisé pour deux choses :
Dans le premier cas, MD5 n'offre en effet plus une sécurité acceptable face à un attaquant (il reste utilisable lorsque le seul but est de détecter des erreurs produites par un processus aveugle, par exemple des parasites sur la ligne). Pour le second cas, c'est moins évident.
C'est qu'il existe plusieurs types d'attaques contre les fonctions de hachage cryptographiques comme MD5 (voir le RFC 4270). Par exemple, une attaque par collision consiste en la production de deux messages ayant le même condensat. Ce sont ces attaques auxquelles MD5 est le plus vulnérable. Si un document est signé via un condensat MD5, il est aujourd'hui simple de créer deux documents ayant le même condensat MD5, ce qui annule une bonne partie de l'intérêt des signatures.
Mais MD5 résiste bien mieux à d'autres attaques comme celles par pré-image, où un attaquant cherche à fabriquer un message ayant le même condensat qu'un message donné. C'est une tâche nettement plus complexe que la collision, où l'attaquant contrôle les deux messages. Donc, chaque protocole ou application qui utilise MD5 doit analyser si son usage de cette fonction est acceptable ou pas, compte-tenu de l'état de l'art en cryptographie.
Pour voir la différence entre ces deux problèmes, reprenons la
commande md5sum. Soit un fichier
toto.txt
. md5sum calcule le condensat :
% md5sum /tmp/toto.txt 0365023af92c568e90ea49398ffec434 /tmp/toto.txt
Une attaque par pré-image consisterait en la création d'un nouveau fichier
ayant le même condensat
0365023af92c568e90ea49398ffec434
que
toto.txt
. Cela reste une tâche non-triviale. Une
attaque par collision permet au contraire à l'attaquant de choisir le
condensat à produire. Avec l'aide du paradoxe de
l'anniversaire, c'est bien plus facile. Mais cela ne
marche que si l'attaquant a le choix des données, ce qui est
partiellement vrai pour les signatures mais pas pour HMAC. (Voir une
bonne explication des différentes possibilités d'attaque, assez trapue mais originale, en « Meaningful Collisions (for SHA-1) ».)
La section 2 liste les attaques publiées contre MD5. Attention, en cryptanalyse, toutes les attaques réussies ne sont pas publiées, certains préférant les garder pour eux. Il faut donc toujours prévoir une marge en se disant que, si une attaque publiée permet de casser un algorithme de cryptographie en un mois, les attaques non publiées peuvent sans doute le faire en quelques jours, voire quelques heures.
Donc, les attaques par collision réussies contre MD5 ont été publiées pour la première fois en 1993. Les progrès ont été importants en 2004 avec « Cryptanalysis of HMAC/NMAC-MD5 and MD5-MAC » de Wang, Feng, Lai et Yu. En 2006, une attaque publiée descend à une seule minute de temps d'exécution sur un portable normal. En 2007, ce genre d'attaques a pu casser des certificats X.509. Il est donc clair que MD5 ne doit plus être utilisé pour la signature numérique. (En cherchant, vous trouverez probablement un certain nombre de sites Web qui ont toujours un certificat utilisant MD5.)
Au contraire, comme le note la section 2.2, les meilleures « attaques » pré-image publiées n'ont pas encore abouti. Quelles sont les conséquences pour HMAC (section 2.3) ? S'il y a eu plusieurs tentatives de casser HMAC-MD5 (tel qu'il est utilisé, par exemple, dans TSIG, RFC 8945), aucune de celles publiées n'a réussi. Il n'y a donc pas d'urgence à supprimer MD5 lorsqu'il est utilisé ainsi, néanmoins des remplaçants sont prêts (cf. RFC 4231) et peuvent être intégrés dans les nouvelles versions des protocoles (RFC 6039). Notez que les faiblesses de MD5 ne sont évidemment pas spécifiques aux protocoles Internet, voir par exemple la documentation de GnuPG.
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : M. Bagnulo (UC3M), A. Sullivan
(Shinkuro), P. Matthews
(Alcatel-Lucent), I. van Beijnum (IMDEA Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 avril 2011
Ce nouveau RFC est un composant indispensable de la nouvelle technique de traduction entre des machines IPv4 et IPv6 (dont une description générale se trouve dans le RFC 6144). Les machines purement IPv6 ne pouvant pas initier une communication avec des machines n'ayant qu'une adresse IPv4, il est nécessaire de les « tromper » en fabriquant dynamiquement des adresses IPv6. Les machines IPv6 tenteront alors de s'y connecter, leurs requêtes seront reçues par le traducteur d'adresses, qui pourra alors les convertir en IPv4 (cf. RFC 7915 et RFC 6146).
DNS64 n'est donc pas utilisable seul. Il doit se combiner à une machine, typiquement un routeur, qui fait la traduction d'adresses, dite NAT64. La configuration typique des utilisateurs de DNS64 sera un réseau local purement IPv6 (puisque le stock d'adresses IPv4 est épuisé), dont le routeur fait de la traduction NAT64, et qui est muni d'un résolveur DNS capable de fabriquer des adresses IPv6 à partir des adresses v4 des machines externes. En effet, le but du système NAT64 est de ne pas avoir à modifier les machines, seulement les équipements d'infrastructure (routeur et résolveur DNS). Les machines purement v6, ignorantes de la traduction qui se fait entre leur réseau et le monde extérieur, ne pourraient pas se connecter si elle ne connaissaient de leur pair qu'une adresse IPv4. NAT64 et son indispensable compagnon DNS64 rejoignent donc la boîte à outils des techniques permettant de faire coexister IPv4 et IPv6 (cf. RFC 6144).
Comment est-ce que le serveur DNS64 synthétise cette adresse IPv6 ?
Supposons qu'une machine IPv6 du réseau local veuille se connecter à
www.example.com
et que celui-ci n'ait qu'une
adresse v4, mettons 203.0.113.18
. Le navigateur
Web tournant sur le client va faire une requête DNS de type AAAA
(adresse IPv6 ; puisqu'il n'a pas d'IPv4, les requêtes de type A
n'auraient aucun intérêt). Le serveur DNS la reçoit, la relaie et
récupère une réponse vide (le nom existe mais n'a pas d'enregistrement
AAAA). Il tente alors une requête A, reçoit
203.0.113.18
en réponse et génère l'adresse v6 de
manière purement algorithmique, sans état, en utilisant l'adresse v4
et les paramètres avec lesquels le serveur a été configuré
(typiquement, un préfixe v6). Rappelez-vous donc bien que le serveur
DNS64 et le traducteur doivent être configurés de manière cohérente
(dans la plupart des cas, ils seront sans doute dans la même boîte
mais, conceptuellement, ce sont deux services séparés.)
Pour le lecteur pressé qui veut juste une introduction à la norme, la section 2 est la meilleure lecture. Voici un exemple où une machine purement IPv6 tente de contacter Twitter, service purement IPv4 :
% telnet twitter.com 80 Trying 64:ff9b::80f2:f0f4... Connected to twitter.com. Escape character is '^]'.
C'est le serveur DNS64 qui a généré l'adresse
64:ff9b::80f2:f0f4
et c'est le traducteur qui
changera les paquets IPv6 en IPv4 à l'aller et en sens inverse au
retour. Twitter et le client purement IPv6 n'y verront que du
feu. Pour le préfixe à utiliser, le serveur DNS64 et le traducteur ont
le choix (cf. RFC 6052) entre un préfixe bien
connu, réservé à la traduction d'adresse (celui utilisé dans
l'exemple, qui avait été testé lors d'une réunion
IETF à Pékin) ou bien un
préfixe appartenant à l'opérateur réseau (NSP, pour
Network-Specific Prefix). La seule contrainte est
qu'il doit être configuré de manière identique dans le serveur DNS64
et dans le traducteur.
La norme elle-même fait l'objet de la section 5. Elle décrit avec précision le fonctionnement que j'ai résumé plus haut. Quelques petits points intéressants :
::ffff:0:0/96
doivent être ignorés et le AAAA de
synthèse produit.J'ai dit plus haut que l'adresse IPv6 de synthèse était fabriquée par concaténation du préfixe IPv6 (configuré à la main dans le serveur DNS64) et de l'adresse IPv4. Mais, en fait, le RFC n'impose pas l'utilisation d'un tel algorithme. La méthode utilisée n'a pas besoin d'être normalisée (elle n'est pas vue à l'extérieur) et doit seulement être la même sur le serveur DNS64 et sur le traducteur. La section 5.2 précise plus rigoureusement les exigences auxsquelles doit obéir cet algorithme. Le point le plus important est qu'il doit être réversible : en échange de l'adresse IPv6 de synthèse, le traducteur doit pouvoir retrouver l'adresse IPv4 originelle. Pour faciliter la vie des administrateurs réseau, un algorithme doit être obligatoirement présent dans les programmes (mais ce n'est pas forcément celui que l'administrateur choisira), celui décrit en section 2 du RFC 6052.
Et que doit faire le serveur DNS64 s'il reçoit des requêtes d'un
autre type que A ou AAAA ? La section 5.3 couvre ce cas. En gros, il
doit les traiter normalement sauf les requêtes de
type PTR (résolution d'une adresse en nom). Dans ce cas, le serveur
doit extraire l'adresse du nom en ip6.arpa
(section 2.5 du RFC 3596), regarder si cette
adresse correspond à un des préfixes qu'il gère et, si oui, le serveur
DNS64 a deux possibilités :
locally-generated-ipv6-address-with-dns64.example.net
). L'avantage est que les clients
DNS verront bien que l'adresse avait été synthétisée, l'inconvénient
est qu'on n'utilisera pas les informations qui pouvaient se trouver
dans le DNS,in-addr.arpa
, fait une requête PTR et renvoie le
résultat au client.La section 6, sur le déploiement, est consacrée aux problèmes pratiques qui pourront survenir lorsqu'on utilisera réellement DNS64. Par exemple, si une machine est multi-homée, il est possible que seulement certaines de ses connexions à l'Internet passent par un traducteur v4-v6. Il faudrait donc idéalement interroger des résolveurs DNS différents selon l'interface de sortie, et considérer les résultats comme locaux à l'interface.
Autre problème pratique, le cas d'une machine à double-pile qui utiliserait DNS64, passant ainsi par le traducteur même lorsque ce n'est pas nécessaire (section 6.3.2 et 6.3.3). Comme la configuration par défaut des systèmes d'exploitation est de préférer IPv6 à IPv4, le cas risque de se produire souvent. Il n'existe pas de moyen simple de le détecter puisque, pour le client, un serveur DNS64 semble un serveur comme un autre. Une machine double-pile (IPv4 et IPv6) ne devrait donc pas utiliser de résolveur DNS64. Mais il peut y avoir des cas où c'est nécessaire, par exemple si la machine double-pile n'a une connectivité IPv4 que partielle. Dans ces conditions, le serveur DNS64 doit exclure les préfixes IPv4 locaux de la synthèse. On peut donc prévoir quelques problèmes de débogage amusants...
La section 7 décrit des exemples de déploiement, en utilisant les
scénarios du RFC 6144. Par exemple, la section 7.1 cite le cas qui sera sans doute
le plus fréquent au début, une machine H1 réseau purement IPv6 (parce que arrivé
après l'épuisement des adresses
IPv4) qui essaie de se connecter à un serveur H2 situé dans
l'Internet v4 traditionnel. Le traducteur T et le serveur DNS sont
configurés avec le préfixe bien connu
64:ff9b::/96
. H1 va commencer par faire une
requête AAAA pour h2.example.com
. Le résolveur
DNS ne trouve pas de AAAA pour ce nom, mais il récupère un
enregistrement de type A, 192.0.2.1
. Il fabrique
alors le AAAA 64:ff9b::c000:201
(qui peut aussi légitimement
s'écrire 64:ff9b::192.0.2.1
). H1 va alors envoyer
un paquet TCP SYN
à
64:ff9b::c000:201
. Le routeur/traducteur le voit
passer, note le préfixe NAT64 avec lequel il a été configuré et le
traduit en un paquet TCP/IPv4.
Autre exemple, en section 7.3. C'est à peu près l'inverse : une machine dans un Internet passé presque entièrement en IPv6 essaie de se connecter à un des derniers serveurs v4 existants. À noter que DNS64 n'est pas indispensable dans ce cas : on peut simplement affecter algorithmiquement une adresse IPv6 à toutes les adresses IPv4, les publier sur des serveurs DNS normaux, et donc n'utiliser que le traducteur. Toutefois, cette section cite quelques cas où DNS64 peut être utile, par exemple si les adresses IPv4 sont affectées dynamiquement.
Fondamentalement, un serveur DNS64 est un menteur : il fabrique des réponses qui n'existent pas (Twitter, utilisé dans l'exemple plus haut, n'a pas d'adresse IPv6 à ce jour...). Il a donc des problèmes avec DNSSEC, qui a justement été conçu pour détecter les mensonges. Toute la section 3 est consacrée à discuter ce problème. Bien sûr, le résolveur DNS64 ment pour la bonne cause. Mais DNSSEC est au delà du bien et du mal, il se moque des motivations, il ne regarde que le résultat. Plusieurs cas peuvent se poser (le RFC en identifie sept !) selon les options indiquées dans la requête DNS et selon la configuration DNSSEC utilisée. Rappelons que les deux options importantes pour DNSSEC dans une requête DNS sont le bit DO (DNSSEC OK, RFC 4035, section 3.2.1) qui indique si le client DNS comprend les enregistrements DNSSEC et le bit CD (Checking Disabled, RFC 4035, section 3.2.2) qui indique au résolveur que le client fera la validation lui-même et qu'il faut lui envoyer toute l'information, même si elle s'avère fausse.
Les différents cas sont donc (je ne les ai pas tous mentionnés, voir le RFC pour les détails) :
La section 5.5 donne les détails sur le fonctionnement de DNSSEC dans DNS64. La section 6.2 rappelle les problèmes pratiques de déploiement de DNS64 si on utilise déjà DNSSEC.
DNS64 pose t-il des problèmes de sécurité ? Pas beaucoup, dit la section 8. Comme indiqué (paragraphes précédents), il peut interférer avec DNSSEC. Et, surtout, il impose une coordination entre le serveur DNS64 et le traducteur. Si un attaquant peut modifier la valeur du préfixe du serveur DNS64, il peut envoyer les paquets où il veut. Donc, attention, la sécurité du serveur DNS64 est exactement aussi importante que celle du traducteur.
Enfin, l'annexe A explique des motivations pour générer un AAAA alors qu'il existe déjà. Il se peut que la meilleure route passe plutôt par le traducteur et donc, dans certains cas, un serveur DNS64 peut offrir à son administrateur la possibilité de permettre la synthèse d'enregistrements AAAA même quand un vrai existe.
BIND met en œuvre DNS64 depuis les versions 9.7.3 et 9.8.0. Voici un exemple de configuration de DNS64 avec une 9.8.0 :
acl me { ::1/128; 127.0.0.0/8; }; acl rfc1918 { 10/8; 192.168/16; 172.16/12; }; options { ... dns64 64:ff9b::/96 { // The well-known prefix clients { me; }; mapped { !rfc1918; any; }; // Never synthetize AAAA records // for private addresses exclude { 64:ff9b::/96; ::ffff:0000:0000/96; }; // If the retrieved // AAAA record is in that range, do not send it back to the user, // synthetize a AAAA. // // suffix ::42; // Trailing bits. Require some free space (here, // 96 + 32 bits leave no room for trailing bits). };
Le premier préfixe est celui des AAAA synthétisés (ici, le préfixe
bien connu). La directive clients
réduit le
service DNS64 à certaines machines seulement (celles qui sont
connectées via un traducteur NAT64, relisez les sections 6.3.2 et
6.3.3 du RFC). La directive mapped
met en
œuvre la règle d'exclusion des préfixes IPv4 locaux (ici, ceux
du RFC 1918). La directive
exclude
implémente la règle d'exclusion des
préfixes IPv6 qui ne devraient même pas être mis dans le DNS
global. S'il existe un AAAA, mais qu'il pointe vers un des ces
préfixes, il sera remplacé par un AAAA synthétique. Enfin, la
directive suffix
permet d'ajouter quelques bits à
la fin du AAAA de synthèse (mais, ici, avec 96 bits pour le préfixe
IPv6 et 32 pour l'adresse IPv4, il n'y a plus de place).
Voici l'effet du serveur ayant la configuration ci-dessus (il écoute sur le port 9053) :
[Adresse IPv6 déjà dans le DNS global.] % dig +short -p 9053 @::1 AAAA www.ietf.org 2001:1890:1112:1::20 [Pas d'adresse IPv6 dans le DNS global mais trois adresses IPv4.] % dig +short -p 9053 @::1 AAAA facebook.com 64:ff9b::453f:bd0b 64:ff9b::453f:bd10 64:ff9b::453f:b50c [Les requêtes PTR marchent bien, BIND synthétise un CNAME, une des deux techniques permises par le RFC.] % dig -p 9053 @::1 -x 64:ff9b::453f:bd10 ... ;; QUESTION SECTION: ;0.1.d.b.f.3.5.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa. IN PTR ;; ANSWER SECTION: 0.1.d.b.f.3.5.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa. 600 IN CNAME 16.189.63.69.in-addr.arpa. 16.189.63.69.in-addr.arpa. 7172 IN PTR www-11-01-ash2.facebook.com. ... [Ici, le nom a une adresse IPv4 mais privée. L'ACL 'rfc1918' va donc la bloquer.] % dig +short -p 9053 @::1 A ciel.administratif.prive.nic.fr 10.1.84.200 % dig -p 9053 @::1 AAAA ciel.administratif.prive.nic.fr ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ^^^^^^^^^
Pour comparer, voici une configuration BIND avec un préfixe du FAI (NSP pour Network-Specific Prefix). Plus court que le précédent, il dégage de la place pour le suffixe :
dns64 2001:db8:666::/48 { // A Network-Specific Prefix (NSP). clients { me; }; suffix ::42; // Trailing bits. };
Et voici les résultats :
% dig +short -p 9053 @::1 AAAA facebook.com 2001:db8:666:453f:bd:1000:0:42 2001:db8:666:453f:b5:c00:0:42 2001:db8:666:453f:bd:b00:0:42
Si vous voulez manipuler les adresses vous-même, voici un joli script awk dû à gbfo, pour traduire les adresses IPv6 en la v4 correspondant :
% echo 64:ff9b::453f:bd0b | \ awk -F: '{h=strtonum("0x" $(NF-1));l=strtonum("0x" $NF);printf("%d.%d.%d.%d\n",h/256,h%256,l/256,l%256);}' 69.63.189.11
Question mises en œuvre de DNS64, outre le cas de BIND, déjà présenté, il existait une rustine pour Unbound, chez Viagénie (avec un très ennuyeux système de formulaire à remplir pour l'obtenir). Cette rustine porte sur une version ancienne du protocole, mais Unbound a désormais DNS64 en série. Il y a aussi au même endroit un serveur DNS64 autonome, écrit en Perl. Ce dernier est très court et peut donc être un bon moyen de comprendre le protocole, pour ceux qui aiment lire le code source. Enfin, Cisco a désormais DNS64 sur ses produits.
Voici un exemple de configuration Unbound pour un serveur DNS64 :
server: module-config: "dns64 validator iterator" dns64-prefix: 64:ff9b::0/96
Et mon opinion personnelle sur DNS64 ? Je dirais que, certes, c'est un hack, mais qu'on a vu pire et que ça traite un vrai problème. DNS64 semble bien pensé, rien n'est oublié et le RFC parle bien de tous les problèmes, notamment avec DNSSEC.
Pour un récit très détaillé, avec plein de technique, d'un test de NAT64 avec DNS64, voir l'article de Jérôme Durand « J'ai testé pour vous : Stateful NAT64 avec DNS64 ».
Notez qu'il existe des résolveurs DNS publics ayant DNS64
(évidemment uniquement avec le préfixe bien connu), comme celui de
Hurricane Electric, nat64.he.net /
2001:470:64::1
ou celui de Google,
google-public-dns64-b.google.com /
2001:4860:4860::6464
.
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : M. Bagnulo (UC3M), P. Matthews (Alcatel-Lucent), I. van Beijnum (IMDEA Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 avril 2011
Dans la grande série des techniques de coexistence entre IPv4 et IPv6, voici une normalisation de NAT64, une technique de traduction entre IPv6 et IPv4, permettant à une machine purement IPv6 de se connecter à une machine purement IPv4. Ce RFC fait partie de la série introduite par le document d'architecture générale RFC 6144.
Aujourd'hui, l'état de l'Internet est que la majorité des serveurs sont accessibles uniquement en IPv4. Or, les dernières adresses IPv4 disponibles à l'IANA ont été distribuées le 3 février 2011. Demain, les nouvelles machines recevront donc de plus en plus uniquement des adresses IPv6. Comment se connecteront-elles à ces serveurs purement v4 ? Une des solutions est de traduire automatiquement les paquets IPv6 du client en IPv4 pour les envoyer au serveur, et de faire la traduction inverse au retour. Cela se nomme NAT64 et notre RFC normalise la version « à état » de cette méthode. « À état » car le traducteur garde un souvenir des flux de données en cours et peut donc, pour la traduction, tenir compte d'un état, des paquets précédents (la version sans état est dans le RFC 7915).
Notez le titre de ce RFC : ses ambitions sont limitées, il ne s'agit pas, comme l'essayait le défunt NAT-PT (RFC 2766) de fournir une solution générale à tous les problèmes de communication v4-v6 mais seulement de permettre à des clients IPv6 de se connecter à des serveurs IPv4.
NAT64 ressemble beaucoup à l'actuel NAT44 (celui que tout le monde est obligé d'utiliser à l'hôtel, chez lui s'il a plusieurs machines, cf. RFC 3022) dans la mesure où il permet :
Il s'en distingue par le fait qu'on ne se contente pas de traduire les adresses, il faut traduire tout l'en-tête du paquet, et par le fait que, pour que les applications tournant sur la machine purement IPv6 trouvent une adresse IPv6, un serveur DNS spécial, DNS64 (RFC 6147) est nécessaire. Vu la nécessité de faire plus de travail qu'en NAT44, la spécification ne fonctionne que pour certains protocoles des couches supérieures, pour l'instant uniquement ICMP, UDP et TCP. Ne comptez donc pas faire, par exemple, du SCTP.
Notre RFC s'appuie sur plusieurs autres documents, celui d'architecture (RFC 6144), celui sur la traduction des adresses (RFC 6052), et celui sur l'algorithme de traduction (RFC 7915).
Les équipements qui font faire le travail sont donc :
Normalement, les traducteurs qui suivront ce RFC seront conformes aux recommandations qu'avait édicté le groupe de travail Behave, dans sa première version, à savoir les RFC 4787, RFC 5382, RFC 5508... et ils permettront les techniques de passage au travers des NAT comme ICE (RFC 5245).
La norme elle-même commence en section 3 mais une gentille introduction, utilisable si vous ne connaissez pas grand'chose aux NAT, figure en section 1.2. Essayons de la résumer sommairement en prenant pas mal de raccourcis : le traducteur a donc deux interfaces, une vers le réseau IPv6-pur et une vers un réseau IPv4 (et peut-être aussi IPv6 mais, dans ce cas, pas besoin de traduction). Le traducteur doit donc avoir une adresse IPv4 publique. Lorsqu'il reçoit un paquet IPv6 dont l'adresse de destination indique qu'il doit être traduit, il le transforme en IPv4 (l'adresse IPv4 est encapsulée dans l'adresse IPv6), et l'envoie par l'interface IPv4. Au retour, c'est un peu plus dur car l'adresse IPv4 de destination est celle du traducteur et, pour retrouver l'adresse IPv6 du vrai destinataire, il doit consulter une table où il a stocké les clients IPv6 qui parlaient à l'extérieur. Comme en NAT44, le numéro de port est utilisé pour reconnaitre les clients locaux. La combinaison d'une adresse IP et d'un port est appelée « adresse de transport ». On le voit, cela ne marche bien que si c'est le réseau IPv6 qui initie la communication (mais diverses astuces permettent des communications un peu plus pair-à-pair).
Le NAT64 devrait donc être appelé NAPT (Network Address AND PORT Translation) car, dans l'écrasante majorité des cas, le traducteur n'aura pas assez d'adresses IPv4 pour tous les clients IPv6 qu'il sert (si on avait assez d'adresses v4, il n'y aurait guère de raison de migrer vers v6).
Comment le client IPv6 a-t-il trouvé l'adresse IPv6 de destination, puisque le serveur n'a qu'une adresse IPv4 ? C'est le rôle du serveur DNS64 qui ment (pour la bonne cause) en fabriquant un enregistrement DNS de type AAAA (adresse IPv6) à partir de l'enregistrement réel A (adresse IPv4). Les étapes complètes effectuées par le client sont décrites en section 1.2.2.
On a vu que cette opération nécessitait de réserver une partie de
l'espace d'adressage IPv6 pour représenter les adresses IPv4. Cette
partie peut être localement définie (après tout, seuls le traducteur
et le résolveur DNS64 auront besoin de la connaître) ou bien on peut
utiliser le préfixe standard 64:FF9B::/96
.
Ici, on voit un serveur DNS64 et un traducteur coopérer pour permettre
à une machine purement IPv6 de communiquer avec
www.example.com
, qui n'a qu'une adresse IPv4 : .
Du fait que le traducteur a un état, tous les paquets IPv4 venus de l'extérieur ne sont pas acceptés. Seuls peuvent être transmis ceux qui correspondent à une correspondance existante, en suivant les règles des RFC 4787 et RFC 5382 (Endpoint-Independent Filtering et Address-Dependent Filtering ; suivre ces règles est important pour que les applications pair-à-pair fonctionnent).
Voilà pour l'introduction. Maintenant, pour lire la spécification elle-même, il faut d'abord bien apprendre la terminologie, en section 2. Quelques termes qui ne sont sans doute pas familiers à tous :
Vous avez bien retenu tout le vocabulaire ? Alors, vous pouvez lire la norme elle-même, à partir de la section 3. Quelques points importants à retenir :
FIN
par les deux parties),
que faire pour une « session » UDP puisqu'il n'y a pas de connexion et
donc pas de fin explicite ? La solution est d'utiliser une minuterie,
remise à zéro par chaque paquet, et qui se déclenche après un certain
temps d'inactivité, coupant la session UDP.Vous avez noté qu'à plusieurs reprises, j'ai utilisé des termes vagues comme « un certain temps ». Les valeurs numériques recommandées pour les diverses constantes sont en section 4. Ainsi, avant de fermer une session UDP, le traducteur doit attendre (par défaut) au moins cinq minutes (cf. RFC 4787), le traducteur doit attendre les fragments manquants au moins deux secondes, etc.
Cette technique du NAT64 améliore-t-elle ou aggrave-t-elle les problèmes de sécurité ? D'abord, cette section note que toute solution de sécurité de bout en bout qui protège l'en-tête IP contre les modifications (par exemple l'AH d'IPsec) va être cassée par NAT64, qui modifie précisément l'en-tête. Si le NAT64 est obligatoire, IPsec peut, par exemple, utiliser l'encapsulation UDP (RFC 3948). La section 5 insiste d'autre part sur le fait qu'un traducteur n'est pas un pare-feu et que le filtrage réalisé par effet de bord de la gestion d'état n'est pas forcément adapté à la sécurité.
D'autre part, NAT64 a ses propres vulnérabilités. Les principales sont le risque d'attaques par déni de service. Par exemple, un attaquant situé à l'intérieur (côté IPv6) peut utiliser toutes les adresses (en général une seule) et ports disponibles et empêcher ainsi l'accès des autres utilisateurs. Une autre attaque possible est d'envoyer régulièrement des paquets de façon à maintenir une liaison active et d'empêcher le traducteur de relâcher des ressources. Une protection possible serait de ne remettre à zéro la minuterie que si le paquet qui passe vient de l'intérieur (supposé plus fiable).
Quelles implémentations existent aujourd'hui ? Viagénie
en à une en logiciel libre, voir http://ecdysis.viagenie.ca/
.
Le terme de ecdysis désigne la
mue des arthropodes puisque NAT64 permet à IP
de muer vers un nouveau protocole...
Voici un exemple d'installation et d'usage :
c'est un module noyau, donc il
faut installer les paquetages qui permettent la compilation de modules
noyau. Sur une Debian version « squeeze » avec
le noyau Linux 2.6.32-5 :
% sudo aptitude install linux-headers-2.6.32-5-686 linux-kbuild-2.6.32 ... % make /bin/sh: [[: not found make -C /lib/modules/2.6.32-5-686/build M=/home/stephane/tmp/ecdysis-nf-nat64-20101117 modules make[1]: Entering directory `/usr/src/linux-headers-2.6.32-5-686' CC [M] /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64_main.o CC [M] /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64_session.o CC [M] /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64_config.o LD [M] /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64.o Building modules, stage 2. MODPOST 1 modules CC /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64.mod.o LD [M] /home/stephane/tmp/ecdysis-nf-nat64-20101117/nf_nat64.ko make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-5-686' % sudo make install ... # On peut éditer le script avant pour changer les paramètres... % sudo ./nat64-config.sh
Ensuite, on peut vérifier que tout s'est bien passé en regardant la table de routage :
% netstat -r -n -Ainet6 Kernel IPv6 routing table Destination Next Hop Flag Met Ref Use If 64:ff9b::/96 :: U 1024 0 0 nat64 ...
Parfait, les paquets pour le préfixe NAT64 sont bien routés à part. Tentons notre chance :
% telnet 64:ff9b::453f:bd0b Trying 64:ff9b::453f:bd0b...
Et on voit bien les paquets IPv6 sur l'interface nat64 :
21:18:58.910669 IP6 2a01:e35:8bd9:8bb0:304b:5a4b:3b8c:7b1c.37033 > \ 64:ff9b::453f:bd0b.23: Flags [S], seq 3580860303, win 5760, \ options [mss 1440,sackOK,TS val 23731660 ecr 0,nop,wscale 6], length 0
Et les IPv4 sur l'interface normale :
21:19:09.263613 IP 192.168.2.1.37038 > \ 69.63.189.11.23: Flags [S], seq 4043093045, win 5760, \ options [mss 1440,sackOK,TS val 23734248 ecr 0,nop,wscale 6], length 0
Un déploiement expérimental de NAT64 est celui du réseau de la recherche lituanien. Voir leur site Web.
Pour un récit très détaillé, avec plein de technique, d'un test de NAT64 avec DNS64, voir l'article de Jérôme Durand « J'ai testé pour vous : Stateful NAT64 avec DNS64 ».
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : X. Li, C. Bao (CERNET Center/Tsinghua University), F. Baker (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 avril 2011
Parmi les nombreuses techniques de coexistence d'IPv4 et IPv6, le groupe de travail Behave, dans sa version 2 (la 1 avait été consacrée aux techniques permettant de supporter le NAT) développe un mécanisme de traduction permettant à une machine IPv6 de communiquer avec une machine v4 et réciproquement. Une des pièces de ce mécanisme est l'algorithme de traduction, présenté dans ce RFC 6145.
Ce nouveau mécanisme de traduction entre IPv4 et IPv6 s'inscrit dans le cadre décrit dans le RFC 6144. Il vise à remplacer « NAT-PT » (RFC 2765 et RFC 2766), officiellement retiré, après n'avoir eu aucun succès. Ce RFC a lui-même été remplacé par la suite par le RFC 7915.
Plus spécifiquement, notre RFC 6145 est la version sans état du traducteur, c'est-à-dire que le traducteur peut traiter chaque paquet indépendemment des autres. Le traducteur n'a pas de table des flots en cours. S'il redémarre et perd toute mémoire, pas de problème, il peut immédiatement reprendre son travail. Cette technique permet notamment le passage à l'échelle : un traducteur d'adresses peut gérer un très grand nombre de clients sans épuiser sa mémoire. Mais elle a quelques inconvénients comme le fait que les fragments ICMP ne seront pas traduits. Il existe donc également une version avec état du nouveau mécanisme, normalisée dans le RFC 6146. La section 1.3 discute plus en détail ces deux possibilités, avec ou sans état.
Donc, le NAT64 (son nom non officiel) vise à traduire des adresses IP entre deux réseaux, l'un v4 et l'autre v6. Comme notre RFC 6145 ne traite que le cas sans état, les adresses doivent être converties de manière purement algorithmique, sans référence à leur histoire (cf. RFC 6052 pour ces algorithmes).
Dit comme ça, cela a l'air simple mais la traduction entre deux protocoles différents porte pas mal de pièges. Ainsi, les en-têtes de paquet n'ont pas la même taille en v4 (20 octets ou plus) et en v6 (40 octets, fixe), ce qui fait que des problèmes de MTU peuvent se poser (section 1.4). Le traducteur doit se comporter comme un routeur, donc fragmenter les paquets trop gros (en IPv4) ou retourner un message ICMP « Packet too big ».
La section 4 du RFC décrit en détail les opérations que doit faire le traducteur depuis IPv4 vers IPv6 (rappelez-vous que la traduction des adresses v4 en v6 est essentiellement dans le RFC 6052, section 2). Il y a des détails que ne connaissent pas les routeurs NAT44, qui se contentent de changer adresses et ports. En effet, ici, il faut traduire tout l'en-tête. Je ne vais pas résumer complètement cette section, juste pointer quelques pièges possibles. Ainsi, les en-têtes n'étant pas les mêmes en v4 et en v6, notre RFC doit spécifier quoi en faire. Certains cas sont évidents (comme le champ Longueur), d'autres moins. Ainsi, le champ TOS de IPv4 doit être copié verbatim dans le champ Traffic Class de IPv6. Mais le traducteur doit aussi offrir une option pour ignorer le TOS et mettre systématiquement zéro comme Traffic Class. Le champ TTL de IPv4 doit être copié dans Hop limit mais après avoir été décrémenté (rappelez-vous que le traducteur est un routeur).
La vraie difficulté n'est pas tellement dans la traduction d'IP que dans celle d'ICMP. En effet, le paquet ICMP contient le début du paquet IP qui a motivé son envoi, et ce début de paquet doit être traduit, également, sans quoi le destinataire du paquet ICMP n'y comprendra rien (par exemple, sans traduction ICMP, il recevrait en IPv6 un paquet ICMP dont le contenu est un paquet IPv4...). Notre RFC détaille donc les traductions à faire pour tous les modèles de paquets ICMP.
Le traducteur doit aussi veiller au champ Type d'ICMP, dont les valeurs sont différentes entre IPv4 et IPv6 (par exemple, Echo Reply est 0 en v4 et 129 en v6). Certains types n'ont pas d'équivalent (comme les types Timestamp ou Address Mask d'ICMPv4, absents d'ICMPv6) et le paquet ICMP doit donc être abandonné.
Enfin, le traducteur doit aussi prendre en charge les en-têtes de la couche 4 car la traduction des adresses peut ne pas être neutre pour la somme de contrôle (section 4.5) et il peut donc être nécessaire de recalculer cette dernière.
Et en sens inverse ? La section 5 décrit la traduction d'IPv6 vers IPv4. On retrouve TOS et Traffic Class, les problèmes de MTU et de fragmentation, et la traduction des messages ICMP.
Les problèmes de MTU et de fragmentation sont des cauchemars habituels sur l'Internet, notamment en raison d'équipements intermédiaires (typiquement des pare-feux) programmés avec les pieds par des anonymes, ou bien configurés n'importe comment, et qui bloquent les paquets ICMP, voire les modifient, en ignorant complètement le RFC 4890. Les traducteurs v4<->v6 auront donc ce problème, comme tant d'autres techniques utiles. La section 6 doit donc se pencher sur le traitement des paquets ICMP Packet too big qui signalent normalement que la MTU est plus réduite que ne le croit l'émetteur et qu'il faut fragmenter. Comme ces paquets sont parfois interceptés, voire modifiés, par des machines gérées par des incompétents, le traducteur doit donc parfois faire des efforts spécifiques (par exemple en modifiant la valeur de la MTU dans certains messages Packet too big).
Rien n'étant parfait en ce bas monde, les traducteurs NAT64 vont aussi introduire de nouvelles questions de sécurité. La section 8 tente de prévoir lesquelles mais reste optimiste en considérant que la plupart des problèmes existent déjà dans IPv4 ou dans IPv6. Ainsi, comme avec le NAT traditionnel, l'authentification des paquets par IPsec (RFC 4302) ne marchera pas.
Pour les gens qui aiment bien les exposés concrets, avec des 0 et
des 1, l'annexe A explique en grand détail le
processus de traduction avec un réseau simple d'exemple, connectant le
réseau traditionnel 198.51.100.0/24
et le réseau
nouveau 2001:db8::/32
, via un
traducteur. Deux machines, H4 et H6, Alice et Bob du NAT64, vont tenter de communiquer. Le traducteur
utilise le préfixe 2001:db8:100::/40
pour
représenter les adresses IPv4 et 192.0.2.0/24
pour représenter les adresses IPv6. Ainsi,
H6, qui a l'adresse 2001:db8:1c0:2:21::
est
représenté en v4 par 192.0.2.33
. H4 a l'adresse
198.51.100.2
. Une fois le routage
correctement configuré pour passer par le traducteur, suivez le RFC
pour voir le trajet des paquets et les opérations qu'ils subissent,
dans le cas où c'est H6 qui initie la connexion, et dans le cas inverse.
Au moins deux mises en œuvre existent déjà, faite par Ecdysis/Viagénie (avec état) et Tayga (sans état, mais nettement plus simple, d'après ses utilisateurs). Pour compenser l'absence de traduction avec état chez Tayga, on peut, sur Linux, le coupler avec SNAT/MASQUERADE (merci à Guillaume Leclanché pour sa suggestion).
Quels sont les changements entre ce mécanisme et celui du RFC 2765 ? Ils sont résumés en section 2. Outre une complète réorganisation des documents, il s'agit surtout de détailler bien davantage les opérations à effectuer. Depuis, notre RFC 6145 a été mis à jour dans le RFC 7915.
Pour réfléchir à la grande question « avec état ou sans état », un article « pro-état » : « Stateless NAT64 is useless ».
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : F. Baker (Cisco), X. Li, C. Bao (CERNET Center/Tsinghua University), K. Yin (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 28 avril 2011
Le groupe de travail Behave de l'IETF a travaillé pendant longtemps sur les mécanismes permettant de communiquer malgré la présence d'un routeur NAT sur le trajet. Ayant terminé ce travail avec succès, il a été muni d'une nouvelle charte pour travailler sur la transition IPv4 -> IPv6, notamment sur un mécanisme de traduction pour permettre à des machines purement v4 de parler à des machines purement v6 et réciproquement. Le groupe « Behave 2 », en ayant fini avec NAT44 s'est donc attaqué à cette tâche et ce RFC est le deuxième de cette nouvelle série (le premier avait été le RFC 6052), qui décrit NAT64.
Il ne décrit pas une technique ou un protocole mais fournit seulement le cadre général dans lequel vont s'inscrire les autres RFC du nouveau groupe Behave comme le RFC 6145 sur le protocole de traduction ou le RFC 6147 sur l'aide que lui apporte le DNS. La liste de ces documents est en section 3.3.
En effet, l'IETF avait déjà normalisé une technique de traduction d'adresses entre IPv4 et IPv6, le NAT-PT (RFC 2766), technique qui avait été abandonnée officiellement par le RFC 4966. La traduction d'adresses entre v4 et v6 n'était pas forcément considérée mauvaise en soi mais NAT-PT était vu comme une mauvaise solution, pour les raisons expliquées dans le RFC 4966.
Mais il est vrai que la traduction d'adresses a toujours été mal vue à l'IETF et que NAT-PT a du faire face à une forte opposition. Le modèle de transition d'IPv4 vers IPv6 promu par l'IETF (RFC 4213) a toujours été d'activer IPv6 au fur et à mesure, de laisser coexister IPv4 et IPv6 sur le réseau et les machines pendant un moment (stratégie de la « double pile ») puis, une fois qu'IPv6 était généralisé, de supprimer IPv4 petit à petit. Cette méthode était encore raisonnable en 2005, lorsque le RFC 4213 a été publié, mais, aujourd'hui, après des années de ratiocination, alors que l'épuisement des adresses IPv4 est effectif, elle n'est plus réaliste : nous n'avons tout simplement plus le temps de procéder à une telle migration ordonnée (cf. section 1.4). Des machines purement v6 vont apparaître, tout simplement parce qu'il n'y aura plus d'adresses v4, alors que les machines purement v4 existant aujourd'hui n'auront pas encore commencé à migrer. Les mécanismes de traduction d'adresses d'une famille à l'autre prennent donc tout leur intérêt (section 1 du RFC). Le RFC 5211 propose donc un autre plan de transition, faisant sa place à ces mécanismes.
La section 1.1 explique pourquoi considérer les mécanismes de traduction d'adresses, à côté des deux techniques du RFC 4213 (la double-pile mais aussi les tunnels). Si la traduction d'adresses est souvent utilisé pour de mauvaises raisons (par exemple parce qu'elle assurerait la sécurité des machines), elle présente aussi des avantages, notamment le fait qu'elle soit, avec les ALG (cf. section 3.1.5), la seule à permettre la communication entre des machines purement v4 et des machines purement v6. Elle a donc sa place dans les stratégies de transition à moyen terme.
La section 1.3 fixe les objectifs de la traduction d'adresses. Il ne s'agit pas de résoudre tous les problèmes (NAT-PT avait souffert d'objectifs irréalistes) mais d'attraper les fruits les plus bas. Il y a (en simplifiant beaucoup), deux types d'application : les client/serveur comme SSH, où le serveur attend les connexions d'un client, et les pair-à-pair comme SIP, où tout le monde initie et accepte des nouvelles connexions. Celles-ci de subdivisent à leur tour en pair-à-pair « d'infrastructure » (SIP, SMTP, ...) où les connexions sont typiquement d'assez courte durée et pair-à-pair « d'échange » comme avec BitTorrent, où on choisit ses pairs (le plus fiable, le plus rapide) et où on maintient de longues sessions avec eux. Quelles sont les conséquences pratiques de cette typologie ? Les applications client/serveur nécessitent des connexions d'un client v4 vers un serveur v6 (ou réciproquement), idéalement sans que les équipements de traduction d'adresses aient à garder un état. Les applications pair-à-pair nécessitent aussi de telles connexions, et dans les deux sens cette fois, mais elles seront sans doute moins nombreuses que celles d'un client vers un serveur, et les solutions avec état seront donc moins problématiques. Enfin, dans le cas de machines purement clientes (des Minitel), il n'est pas nécessaire d'ouvrir des connexions vers elles. Dans tous les cas, s'il faut garder un état pour la traduction, il est très nettement préférable qu'il soit entièrement dans les équipements réseaux (typiquement le routeur) et que la traduction ne nécessite aucune aide de la part de la machine aux extrémités. NAT-PT exigeait de l'état dans deux endroits (le traducteur lui-même et le serveur DNS) et que ces états soient coordonnés. Un routeur NAT IPv4 actuel a un état mais qui est entièrement dans le routeur et qui ne nécessite aucune participation d'une autre machine.
Enfin, un problème de vocabulaire quasiment philosophique. Faut-il parler de « transition » vers IPv6 sachant que ce mot connote une idée d'achèvement (un jour, il n'y aura plus d'IPv4) alors que rien n'est moins sûr et que, de toute façon, cela prendra de nombreuses années ? Certains préfèrent dire que des mécanismes comme la traduction d'adresses sont des mécanismes de « coexistence » plutôt que de « transition » (section 1.4).
La section 2 du RFC s'attache ensuite à décrire les scénarios où les mécanismes de transition pourront être utiles. Par exemple, en 2.1, le scénario est celui d'un FAI récemment apparu dans un endroit où il est très difficile d'obtenir des adresses IPv4 (par exemple en Asie ou en Afrique) et qui est donc entièrement en IPv6. Ses clients veulent quand même se connecter à des services IPv4. Des techniques comme celles du RFC 7915 peuvent alors être utilisées (rappelez-vous que notre RFC 6144 ne décrit qu'un cadre, pas des techniques spécifiques). Le scénario de la section 2.4 représente le problème inverse : un réseau ancien et jamais mis à jour, entièrement en IPv4, et qui veut accéder aux services uniquement v6. Bien plus difficile à résoudre (le petit nombre d'adresse IPv4 ne permet pas de faire une traduction d'adresses efficace, on doit consommer également les ports et ils ne sont que 65536 par adresse IP), ce problème est considéré comme « hors-sujet ». On ne peut pas résoudre tous les malheurs du monde et ce réseau devra utiliser d'autres techniques (probablement des ALG, même si le RFC ne les cite pas ici).
Le cadre complet de ces solutions à base de traduction d'adresses est en section 3. La section 3.1 liste les composants du cadre :
Une fois les composants de la solution listés (on voit qu'il faut beaucoup de choses pour faire fonctionner l'Internet malgré le retard pris à migrer vers IPv6), la section 3.2 expose leurs modes de fonctionnement. La traduction sans état (section 3.2.1) passe mieux à l'échelle et maintient la transparence du réseau de bout en bout. Mais elle ne peut pas être utilisée pour tous les scénarios. La traduction avec état (section 3.2.2) peut alors prendre le relais.
Il n'existe pas de solution magique à tous les problèmes. Le déploiement bien trop lent d'IPv6 a laissé une situation peu satisfaisante, et qui ne pourra pas être complètement résolu par de nouveaux protocoles. La section 5 rappelle donc que certaines questions n'ont pas de solution présente. Mais le groupe Behave a dû travailler dans l'urgence, pour fournir des solutions avant l'épuisement d'IPv4 et s'est donc focalisé sur les problèmes les plus « faciles ». Peut-être dans de futurs RFC ?
À noter qu'un FAI britannique a déjà un tel service déployé sur son réseau.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : T. Richardson, J. Levine (RealVNC)
Pour information
Première rédaction de cet article le 8 mars 2011
Il est assez fréquent à l'IETF qu'un protocole ne soit documenté dans un RFC que longtemps après son déploiement. C'est le cas de RFB (Remote Framebuffer Protocol), le protocole utilisé dans le système VNC, système qui permet de transmettre via un réseau TCP/IP l'interface graphique d'une machine. VNC permet, par exemple, d'avoir sur son ordinateur le bureau d'une machine distante, se s'y loguer, etc, comme si on était physiquement devant. C'est donc un concurrent de X11 avec XDMCP ou bien de NX mais avec l'avantage sur ce dernier d'avoir désormais une spécification publique, et de nombreuses mises en œuvre. Je compte une quarantaine de clients, de serveurs et de bibliothèques VNC sur mon Ubuntu.
RFB se veut un protocole simple, bien plus simple que X11, basé sur l'idée d'un serveur, tournant sur la machine distante, qui écrit dans une mémoire graphique (le framebuffer) qui est en fait située sur la machine de bureau (le client ; notez que « client » et « serveur » ont des sens différents de celui de X11). Le système VNC, qui utilise ce protocole, est très largement utilisé pour l'accès distant à une machine, exactement dans les mêmes conditions que si on était présent devant cette machine (système de fenêtrage, accès à la souris, etc).
RFB travaille au niveau de la mémoire graphique et est donc compatible avec tous les systèmes de fenêtrage comme X11 ou comme celui de Windows. Le protocole se veut simple, surtout côté client, pour pouvoir être mis en œuvre sur de petites machines. Il existe même un widget VNC/RFB pour GTK, pour ceux qui veulent mettre un client VNC dans leurs programmes.
Le client est sans état et peut donc redémarrer à tout moment et reprendre la session là où il l'avait laissée. C'est le serveur qui maintient l'état de l'interface utilisateur. Cela permet par exemple de changer de client en cours de session.
RFB, je l'ai dit, a été implémenté avant d'être spécifié et a connu plusieurs versions. Ce RFC essaie donc de documenter l'état actuel du protocole.
Si les détails prennent parfois de la place, les principes sont simples et les premières sections du RFC sont donc courtes. La section 2 décrit les connexions entre le client et le serveur. Le mode normal de fonctionnement de VNC est que le serveur tourne pendant une longue période, gardant en mémoire l'état de la mémoire graphique, le ou les clients se connectant à loisir, pendant parfois seulement de courtes périodes. Cela ressemble donc, adapté au graphique, au principe de screen. Le client peut être n'importe où sur l'Internet et se connecte par défaut au port 5900.
Loin de la richesse du protocole de
X11, RFB ne fournit qu'une seule primitive :
« afficher un rectangle à la position X,Y
indiquée » (section 3). Cela peut sembler très inefficace mais divers
encodages subtils permettent de rendre ce protocole supportable. Les
mises à jour (nouveaux rectangles à afficher) ne sont jamais envoyées par
le serveur mais demandées par le client (message
FramebufferUpdateRequest
, section 7.5.3). Le protocole est donc
adaptatif : un client lent ne demandera pas souvent des mises à jour
et aura donc moins de travail. Si une même région de la mémoire
graphique voit plusieurs modifications successives, le client lent
peut donc parfaitement sauter les étapes intermédiaires.
Afficher des rectangles, c'est très joli mais un environnement graphique digne de ce nom doit aussi permettre à l'utilisateur de dire quelque chose, par exemple de taper au clavier ou de cliquer avec la souris. La section 4 résume le protocole d'entrée de RFB : ce dernier ne connait que clavier et souris (multi-boutons). Tout autre périphérique d'entrée doit donc être modélisé comme clavier ou comme souris.
Et les pixels, comment sont-ils modélisés ? La section 5 décrit le modèle. Il repose sur une négociation entre client et serveur, à l'ouverture de la connexion, où le client est roi. C'est lui qui choisit la représentation des pixels sur le réseau, et il peut donc choisir ce qui lui fait le moins de travail, tout reposant alors sur le serveur. Les deux formats les plus classiques sont le « couleurs réelles » où chaque pixel est un nombre sur 24 bits, chaque groupe de 8 bits indiquant l'intensité de rouge, de vert ou de bleu, ou bien le « table des couleurs » où chaque pixel est un nombre sur 8 bits indiquant une entrée d'une table où sont stockées les 256 couleurs possibles.
Plusieurs encodages sont ensuite possibles dans RFB, six étant définis par notre RFC 6143, permettant plus ou moins de compression.
En parlant de négociation, comme RFB existe depuis un certain temps et a connu plusieurs versions, la section 6 décrit la notion de version du protocole. Notre RFC 6143 normalise la version 3.8. Les versions précédentes résumées dans l'annexe A. Si une version 4.x apparaîtra peut-être un jour, la version actuelle, la 3.8, est extensible sans avoir besoin de changer de version. On peut ainsi introduire :
Le protocole RFB lui-même figure dans la section 7. Elle est très longue, bien plus que les autres sections, mais pas forcément plus difficile, elle liste juste tous les messages possibles. RFB peut fonctionner sur n'importe quel protocole de transport fiable (comme TCP). La communication commence par une phase de négociation entre le client et le serveur, puis l'initialisation, puis l'envoi des messages de mise à jour de la mémoire graphique. La description des messages utilise quelques types de base comme U8 (entier de huits bits non signé), S16 (entier de seize bits signé, toujours en gros boutien), etc.
La section 7.1 décrit le protocole de négociation. Ainsi, le
serveur commence par envoyer un message où il indique la version
(message ProtocolVersion
, ici, le serveur à l'autre bout est x11vnc) :
% nc ec2-xxx.eu-west-1.compute.amazonaws.com 5900 RFB 003.008
La sécurité se négocie ensuite (section 7.2). La phase
d'initialisation est décrite en section 7.3. Par exemple, le message
ServerInit
contiendra la hauteur et la largeur de
la mémoire graphique en nombre de pixels (tous les deux en UA16),
ainsi que le format de représentation des pixels (décrit en section 7.4).
La représentation des caractères tapés au clavier du client
(message KeyEvent
, section 7.5.4) est
complexe. La valeur utilisée est un keysym
de X11
(même si ni le client, ni le serveur n'utilisent X11). Si vous avez
une machine Unix où X11 est installé, le
fichier /usr/include/X11/keysymdef.h
vous donnera
une idée des valeurs possibles. Cela aurait été
plus simple si un point de code Unicode était
envoyé... Mais il n'y a que pour ASCII que le
keysym
correspond au point de code. Le RFC va
même jusqu'à préciser qu'il vaut mieux utiliser le
keysymI
traditionnel, même s'il y en a un pour le
caractère Unicode. l faut dire
que le protocole RFB ne transmet pas que des caractères mais aussi des
états des touches (comme le fait que la touche Majuscule est pressée)
et des touches non affectées à un caractère particulier (comme F1,
F2, etc). Les règles d'interprétation des keysyms
sont d'une grande complexité. Le lecteur curieux doit se munir
d'aspirine avant de lire lui-même cette section.
Plus facile, le cas du « pointeur » (la souris) en section 7.5.5. Les événements sont simplement « bouton pressé » et « bouton relaché », les attributs étant la position X,Y et le numéro du bouton (huit boutons sont prévus, afin de pouvoir modéliser des dispositifs d'entrée plus complexes comme les roulettes).
Jusqu'à présent, je n'ai parlé que des messages envoyés par le
client RFB au serveur. En sens inverse, le principal message est
FramebufferUpdate
(section 7.6.1) qui indique un changement dans
la mémoire graphique. Il contient un certain nombre de rectangles et,
pour chacun d'eux, sa position X,Y, sa hauteur et sa largeur, et le
type d'encodage utilisé.
Les encodages sont définis en section 7.7. Les six standards à l'heure actuelle sont :
Raw
: comme son nom l'indique, aucun
effort, on envoie juste les pixels l'un après l'autre (largeur, puis
hauteur).CopyRect
: le serveur indique les
coordonnées d'un rectangle existant dans la mémoire du client. Cela
sert, par exemple, lorsqu'une fenêtre est déplacée sur l'écran.RRE encoding
: officiellement
abandonné.Hextile encoding
: officiellement
abandonné.TRLE encoding
: Tiled Run-Length
Encoding utilise un ensemble de techniques de
compression dont le
run-length encoding appliquée à des « tuiles » de 16x16
pixels.ZRLE encoding
: Zlib Run-Length
Encoding utilise la compression Zlib
(RFC 1950 et RFC 1951).La normalisation du Remote Framebuffer Protocol a nécessité quelques nouveaux registres IANA, décrits en section 8 : celui des types de sécurité, celui des messages RFB, et celui des encodages, qui permettra d'étendre la liste de six encodages présentée plus haut.
Quelle est la sécurité de RFB ? Par défaut, inexistante : comme le note justement la section 9, l'authentification est faible et la confidentialité et l'intégrité sont nulles. RFB est traditionnellement utilisé avec une protection fournie par, par exemple, un VPN chiffré, seule façon de l'utiliser de manière sûre.
L'annexe A du RFC résume les différences entre cette version du protocole (la 3.8) et les précédentes. Ces différences sont concentrées dans la phase de négociation.
À l'heure d'aujourd'hui, je n'ai pas trouvé de connaissance de ce
protocole dans tcpdump mais
Wireshark, par contre, le décode, sous son ancien
nom de VNC (qui est désormais uniquement le nom d'un logiciel). C'est
aussi le nom à utiliser sur pcapr : http://www.pcapr.net/browse?proto=vnc&order=date
.
Date de publication du RFC : Février 2011
Auteur(s) du RFC : Dimitris Zisiadis (CERTH), Spyros Kopsidas (CERTH), Matina Tsavli (CERTH), Leandros Tassiulas (CERTH), Chrysostomos Tziouvaras (GRNET), Guillaume Cessieux (CNRS), Xavier Jeannin (CNRS)
Expérimental
Première rédaction de cet article le 19 février 2011
Les centres qui gèrent les réseaux qui composent l'Internet, les NOC, ont régulièrement besoin d'échanger de l'information. Celle-ci, concernant les incidents, les nouveautés, les problèmes, circule souvent en quantités impressionnantes et est donc une bonne candidate pour l'automatisation. Ce RFC expérimental propose donc un format standard, basé sur XML, pour représenter l'information qui circule entre NOC, notamment ceux qui gèrent en commun une grande grille, ce qui est le cas d'EGEE, où travaillent les auteurs. Il est important pour de grosses infrastructures réseau comme les grilles de calculs, qui s'étendent sur plusieurs domaines administratifs, de pouvoir interpréter correctement les tickets avec un minimum de dépendance vis-à-vis de l'origine du ticket. L'effort de normalisation prend tout son sens dans ce contexte. Un ticket pourra donc être lu et compris sans avoir besoin de connaître les particularités et la terminologie du domaine d'origine.
Le but (section 1) n'est pas de remplacer les outils de gestion de tickets de chaque NOC mais d'avoir un format d'échange standard, suivant les souhaits du RFC 1297. Les tickets ainsi formatés pourront automatiquement être émis par un NOC, reçus par un autre, être analysés, etc. Ces outils de gestion de tickets seront ensuite utilisés pour analyser le problème, suivre son évolution et, d'une manière générale, assurer un bon fonctionnement du réseau.
On comprend mieux la taille du problème quant on voit que la grille de calcul EGEE qui utilise les NREN (vingt participants) pour sa connectivité, reçoit 800 tickets et 2500 messages par mois.
Notre RFC décrit un modèle de données en UML, puis un format concret de représentation en XML. Un problème classique que rencontrent toutes les tentatives de normalisation dans ce domaine est qu'il faut à la fois décrire de manière formelle l'incident, en énumérant de manière limitative les choix possibles, pour permettre son traitement automatique, tout en gardant des possibilités d'exprimer des problèmes nouveaux, ce qui impose de garder la possibilité de mettre du texte libre, non formaté.
Voyons d'abord les types de données utilisés (section 2). On y
trouve plusieurs énumérés comme
TT_TYPE
qui indique si le ticket concerne un
problème opérationnel, administratif, ou bien n'est là que pour
information, TYPE
qui indique si l'événement
était prévu ou accidentel, TT_STATUS
qui donne
l'état du ticket (ouvert, résolu, annulé, fermé..., avec un diagramme
de transition apparemment obligatoire). On trouve aussi bien sûr des
chaînes de caractères (qui seront simplement le type W3C
XML Schema xs:string
) et des heures
(au format du RFC 3339, alias
xs:dateTime
).
Armée de ces définitions, la section 3 détaille la longue liste des
attributs d'un ticket. On y trouvera même un diagramme de classe
UML en art
ASCII... Parmi ces attributs, les grands classiques, comme
l'identificateur unique du ticket (formé par la concaténation de
l'identificateur du NOC et d'un identificateur local, ce qui permet d'allouer ces identificateurs uniques de
manières décentralisée), l'état du ticket, sa date de création, l'identificateur du NOC qui est
à l'origine du ticket (le RFC n'explique pas comment ses
identificateurs, qui doivent être uniques, sont attribués et
conservés), une description courte qui est sélectionnée à partir d'une
liste pré-définie (pour permettre le traitement automatique) et une
description longue qui est en texte libre (la
langue utilisée peut être représenté dans le
fichier XML par un attribut lang
- pour des
raisons que j'ignore, l'attribut standard XML
xml:lang
n'a pas été utilisé), les identificateurs de
tickets ayant un rapport avec celui-ci, etc. Pour chaque attribut est
indiqué s'il est obligatoire ou non.
La section 4 décrit l'approche utilisée pour l'internationalisation puisque les tickets seront échangés entre NOC de pays et de langues différents. Les champs formels (comme la description courte) n'ont pas besoin d'être adaptés (le logiciel de chaque NOC pourra les présenter comme il le voudra), les textes libres (comme la description longue de l'incident) peuvent être dans n'importe quelle langue (des systèmes de traduction automatique sont prévus pour EGEE dans le futur).
Si vous êtes impatients de voir à quoi ressemblent ces fameux tickets en XML, sautez directement à la section 5, qui présente les exemples. Voici un joli ticket indiquant une panne chez Forth en Grèce :
<?xml version="1.0" encoding="UTF-8"?> <!-- This example describes a link failure that was detected --> <NTTDM-Document version="1.00" lang="el" xmlns="urn:ietf:params:xml:ns:nttdm-1.0"> <Ticket> <Original_ID>5985</Original_ID> <Partner_ID>01</Partner_ID> <TT_ID>01_5985</TT_ID> <TT_Title>Forth Link Failure</TT_Title> <TT_Type>Operational</TT_Type> <TT_Status>Closed</TT_Status> <TT_Open_Datetime>2008-12-16T10:01:15+02:00</TT_Open_Datetime> <TT_Short_Description>Core Line Fault</TT_Short_Description> <TT_Long_Description>Forth Link Failure</TT_Long_Description> <Type>Unscheduled</Type> <TT_Impact_Assessment>No connectivity</TT_Impact_Assessment> <Start_Datetime>2008-12-16T09:55:00+02:00</Start_Datetime> <TT_Last_Update_Time>2008-12-16T15:00:34+02:00</TT_Last_Update_Time> <Location>HERAKLION</Location> <History>Optical transmitter was changed</History> <TT_Close_Datetime>2008-12-16T15:05:00+02:00</TT_Close_Datetime> <End_Datetime>2008-12-16T15:01:21+02:00</End_Datetime> <Network_Node> <Node>FORTH</Node> </Network_Node> <Network_Link_Circuit> <Link_Circuit>FORTH-2</Link_Circuit> </Network_Link_Circuit> <Open_Engineer>Dimitris Zisiadis</Open_Engineer> <Close_Engineer>Guillaume Cessieux</Close_Engineer> <Contact_Engineers> <Engineer>Spyros Kopsidas</Engineer> <Engineer>Chrysostomos Tziouvaras</Engineer> </Contact_Engineers> <TT_Priority>High</TT_Priority> </Ticket> </NTTDM-Document>
On notera que l'exemple est imparfait :
l'étiquette de langue el
indique du
grec mais le texte est entièrement en anglais.
Enfin, la section 6 contient le schéma complet, en langage W3C XML schema et la section 7 quelques avertissements de sécurité. Comme le contenu des tickets peut être sensible, il peut être utile de chiffrer et d'authentifier les tickets mais le RFC ne suggère pas de technique standard pour cela.
Merci à Xavier Jeannin pour sa relecture.
Date de publication du RFC : Février 2011
Auteur(s) du RFC : L. Romary (TEI Consortium and INRIA), S. Lundberg (The Royal Library, Copenhagen)
Pour information
Première rédaction de cet article le 12 février 2011
Petit à petit, de nombreux formats XML
obtiennent un type MIME, comme indiqué dans le
RFC 7303 et RFC 6839. Ces types permettent d'identifier un contenu de
manière précise sur le réseau, et ont la forme
application/XXX+xml
où XXX indique le format
précis. Ici, notre RFC concerne le type
application/tei+xml
, pour le format
TEI, un format de documents très utilisé dans
le monde des bibliothèques et dans les sciences humaines en général (le secteur de l'étude des documents
anciens est un utilisateur très visible de TEI, mais ce n'est pas le seul).
En effet, TEI (Text Encoding and
Interchange) est un format utilisé depuis longtemps, par les
musées, les bibliothèques, et des chercheurs, par exemple pour encoder un manuscrit qu'on a réussi à déchiffrer. Nous sommes donc ici à
l'intersection du monde des geeks et de celui
d'Umberto Eco. Si vous voulez voir des exemples
de documents TEI, on en trouve un peu partout, par exemple une version
d'« Alice au pays des merveilles » issue du
Projet Gutenberg et TEIsée. L'original est en
http://www.gnutenberg.de/pgtei/0.5/examples/alice/alice.tei
mais j'en ai fait une version légèrement
modifiée pour en retirer ce qui était spécifique de Gutenberg.
Comme tout bon fichier XML, les documents
TEI ont un namespace XML, ici
http://www.tei-c.org/ns/1.0
. Plusieurs éléments
XML peuvent être utilisés pour être la racine d'un document TEI, mais
les plus communs sont <TEI>
et
<teiCorpus>
. On les trouve souvent sur
l'Internet avec des extensions de fichier .tei
et
.teiCorpus
. (À noter qu'une recherche
Google des fichiers se terminant par
.tei
ne donne pas le
résultat attendu en raison du nombre de chinois nommés
Tei...)
Notre RFC est très court. TEI lui-même est spécifié dans des documents du consortium TEI (le format est du Relax NG et disponible en format XML ou en format compact) et ce RFC ne fait que spécifier le type MIME et donner quelques conseils. Armé de ces schémas, on peut valider avec rnv :
% rnv tei_all.rnc alice.tei alice.tei
Par contre, la validation avec xmllint échoue en raison d'une boucle sans fin.
Enfin, le consortium TEI fournit divers outils permettant, par exemple, la traduction vers LaTeX ou HTML. À noter que le journal de ce consortium est sur revues.org.
À noter que la traditionnelle section sur la sécurité couvre des points
inhabituels dans un RFC. Par exemple, les documents encodés en TEI
peuvent être tellement anciens qu'ils sont montés dans le
domaine public mais parfois ils sont au
contraire encore plombés par des règles d'appropriation intellectuelle. Le format
TEI permet de spécifier ces règles, avec une grande granularité (élément availability
). Ces spécifications
peuvent être utilisées pour mettre en œuvre un système de
menottes numériques ou, plus
simplement, pour permettre l'application du droit moral de l'auteur (citer
correctement les auteurs de chaque partie d'un document TEI).
D'autre part, TEI a déjà été utilisé pour encoder des documents ayant un rôle légal, et qui peuvent être encore applicables des siècles plus tard. Il peut donc être nécessaire de prendre des précautions pour vérifier l'authenticité et l'intégrité de ces documents (TEI lui-même ne le fait pas).
Enfin, les documents encodés peuvent être confidentiels et, là encore, cette confidentialité peut devoir être respectée sur de longues périodes (des dizaines d'années, si des personnes physiques sont mentionnées). Regardez donc bien les règles pour les archives de votre pays avant de distribuer des documents TEI.
Merci à Laurent Romary et Sebastian Rahtz pour leurs relectures et
pour m'avoir envoyé un autre exemple de document TEI, un encodage du
« Conte de Noël » de
Dickens. Le fichier
carol.zip
contient le source TEI et on peut en tirer
automatiquement une version EPUB, qui est dans
le fichier 3256.epub
.
Date de publication du RFC : Avril 2011
Auteur(s) du RFC : J. Chroboczek (PPS, University of Paris 7)
Expérimental
Première rédaction de cet article le 6 avril 2011
La recherche sur les protocoles de routage ne désarme pas, motivée à la fois par les avancées de la science et par les nouvelles demandes (par exemple pour les réseaux ad hoc). Ainsi Babel est un nouveau protocole de routage, de la famille des protocoles à vecteurs de distance, qui vise notammment à réduire drastiquement les probabilités de boucle. (Depuis, Babel a été normalisé dans le RFC 8966.)
Il y a en effet deux familles de protocole de routage, ceux à vecteurs de distance comme l'ancêtre RIP et ceux à états des liens comme OSPF (RFC 2328). Ce dernier est aujourd'hui bien plus utilisé que RIP, et à juste titre. Mais les problèmes de RIP n'ont pas forcément la même ampleur chez tous les membres de sa famille, et les protocoles à vecteurs de distance n'ont pas dit leur dernier mot.
Babel s'inspire de protocoles de routage plus récents comme DSDV. Il vise à être utilisable, à la fois sur les réseaux classiques, où le routage se fait sur la base du préfixe IP et sur les réseaux ad hoc, où il n'y a typiquement pas de regroupement par préfixe, où le routage se fait sur des adresses IP « à plat » (on peut dire que, dans un réseau ad hoc, chaque nœud est un routeur).
L'un des principaux inconvénients du bon vieux protocole RIP est sa capacité à former des boucles lorsque le réseau change de topologie. Ainsi, si un lien entre les routeurs A et B casse, A va envoyer les paquets à un autre routeur C, qui va probablement les renvoyer à A et ainsi de suite (le champ « TTL » pour IPv4 et « Hop limit » dans IPv6 a précisement pour but d'éviter qu'un paquet ne tourne sans fin). Babel, lui, évitera les boucles la plupart du temps mais, en revanche, il ne trouvera pas immédiatement la route optimale entre deux points. La section 1.1 du RFC spécifie plus rigoureusement les propriétés de Babel.
Autre particularité de Babel, les associations entre deux machines pourront se faire même si elles utilisent des paramètres différents (par exemple pour la valeur de l'intervalle de temps entre deux « Hello » ; cf. l'annexe B pour une discussion du choix de ces paramètres). Le RFC annonce ainsi que Babel est particulièrement adapté aux environnements « sans-fil » où certaines machines, devant économiser leur batterie, devront choisir des intervalles plus grands.
Je l'ai dit, rien n'est parfait en ce bas monde, et Babel a des limites, décrites en section 1.2. D'abord, Babel envoie périodiquement toutes les informations dont il dispose, ce qui, dans un réseau stable, mène à un trafic total plus important que, par exemple, OSPF (qui n'envoie que les changements). Ensuite, Babel a des mécanismes d'attente lorsqu'un préfixe disparait, qui s'appliquent aux préfixes plus généraux. Ainsi, lorsque deux préfixes deviennent agrégés, l'agrégat n'est pas joignable immédiatement. Notre RFC a le statut « Expérimental » et l'usage découvrira peut-être d'autres faiblesses.
Comment Babel atteint-il ses merveilleux objectifs ? La section 2 détaille les principes de base du protocole, la 3 l'échange de paquets et la 4 l'encodage d'iceux. Commençons par les principes. Babel est fondé sur le bon vieil algorithme de Bellman-Ford, tout comme RIP. Tout lien entre deux points A et B a un coût (qui n'est pas forcément un coût monétaire, c'est un nombre qui a la signification qu'on veut, cf. section 3.5.2). Le coût est additif (la somme des coûts d'un chemin complet faisant la métrique du chemin, section 2.1 et annexe A), ce qui veut dire que Métrique(A -> C) - pour une route passant par B - = Coût(A -> B) + Coût(B -> C). L'algorithme va essayer de calculer la route ayant la métrique le plus faible.
Un nœud Babel garde trace de ses voisins nœuds en envoyant
périodiquement des messages Hello
et en les
prévenant qu'ils ont été entendus par des messages
IHU
(I Heard You). Le contenu
des messages Hello
et IHU
permet de déterminer le coût.
Pour chaque source (d'un préfixe, pas d'un paquet), le nœud garde trace de la métrique vers cette source (lorsqu'un paquet tentera d'atteindre le préfixe annoncé) et du routeur suivant (next hop). Au début, évidemment la métrique est infinie et le routeur suivant indéterminé. Le nœud envoie à ses voisins les routes qu'il connait. Si celle-ci est meilleure que celle que connait le voisin, ce dernier l'adopte (si la distance était infinie - route inconnue, toute route sera meilleure).
L'algorithme « naïf » ci-dessus est ensuite amélioré de plusieurs façons : envoi immédiat de nouvelles routes (sans attendre l'émission périodique), mémorisation, non seulement de la meilleure route mais aussi de routes alternatives, pour pouvoir réagir plus vite en cas de coupure, etc.
La section 2.3 rappelle un problème archi-connu de l'algorithme de Bellman-Ford : la facilité avec laquelle des boucles se forment. Dans le cas d'un réseau simple comme celui-ci A annonce une route de métrique 1 vers S, B utilise donc A comme routeur suivant, avec une métrique de 2. Si le lien entre S (S = source de l'annonce) et A casse comme B continue à publier une route de métrique 2 vers S, A se met à envoyer les paquets à B. Mais B les renvoie à A, créant ainsi une boucle. Les annonces ultérieures ne résolvent pas le problème : A annonce une route de métrique 3, passant par B, B l'enregistre et annonce une route de métrique 4 passant par A, etc. RIP résout le problème en ayant une limite arbitraire à la métrique, limite qui finit par être atteinte et stoppe la boucle (méthode dite du « comptage à l'infini »).
Cette méthode oblige à avoir une limite très basse pour la métrique. Babel a une autre approche : les mises à jour ne sont pas forcément acceptées, Babel teste pour voir si elles créent une boucle (section 2.4). Toute annonce est donc examinée au regard d'une condition, dite « de faisabilité ». Plusieurs conditions sont possibles. Par exemple, BGP utilise la condition « Mon propre numéro d'AS n'apparaît pas dans l'annonce. ». (Cela n'empêche pas les micro-boucles, boucles de courte durée en cas de coupure, cf. RFC 5715.) Une autre condition, utilisée par DSDV et AODV, repose sur l'observation qu'une boucle ne se forme que lorsqu'une annonce a une métrique supérieure à la métrique de la route qui a été retirée. En n'acceptant que les annonces qui diminuent la métrique, on peut donc éviter les boucles. Babel utilise une règle un peu plus complexe, empruntée à EIGRP, qui tient compte de l'histoire des annonces faites par le routeur.
Comme il n'y a pas de miracles en routage, cette idée de ne pas accepter n'importe quelle annonce de route a une contrepartie : la famine. Celle-ci peut se produire lorsqu'il existe une route mais qu'aucun routeur ne l'accepte (section 2.5). EIGRP résout le problème en « rédémarrant » tout le réseau (resynchronisation globale des routeurs). Babel, lui, emprunte à DSDV une solution moins radicale, en numérotant les annonces, de manière strictement croissante, lorsqu'un routeur détecte un changement dans ses liens. Une route pourra alors acceptée si elle est plus récente (si elle a un numéro de séquence plus élevé).
À noter que tout se complique s'il existe plusieurs routeurs qui annoncent originellement la même route (section 2.7 ; un exemple typique est la route par défaut, annoncée par tous les routeurs ayant une connexion extérieure). Babel gère ce problème en associant à chaque préfixe l'identité du routeur qui s'est annoncé comme origine et considère par la suite ces annonces comme distinctes, même si le préfixe est le même. Conséquence : Babel ne peut plus garantir qu'il n'y aura pas de boucle (Babel essaie de construire un graphe acyclique mais l'union de plusieurs graphes acycliques n'est pas forcément acyclique). Par contre, il pourra détecter ces boucles a posteriori et les éliminer plus rapidement qu'avec du comptage vers l'infini.
Voilà pour les principes. Et le protocole ? La section 3 le décrit. Chaque routeur a une identité sur huit octets (le plus simple est de prendre l'adresse MAC d'une des interfaces). Les messages sont envoyés dans des paquets UDP et encodés en TLV. Le paquet peut être adressé à une destination unicast ou bien multicast.
Un routeur Babel doit se souvenir d'un certain nombre de choses (section 3.2) :
Les messages Babel ne bénéficient pas d'une garantie de délivrance (c'est de l'UDP, après tout), mais un routeur Babel peut demander à ses voisins d'accuser réception (section 3.3). La décision de le demander ou pas découle de la politique locale de chaque routeur. Si un routeur ne demande pas d'accusé de réception, l'envoi périodique des routes permettra de s'assurer que, au bout d'un certain temps, tous les routeurs auront toute l'information. Les accusés de réception peuvent toutefois être utiles en cas de mises à jour urgentes dont on veut être sûr qu'elles ont été reçues. (L'implémentation actuelle de Babel ne les utilise pas.)
Comment un nœud Babel trouve t-il ses voisins ? La section 3.4 décrit ce mécanisme. Les voisins sont détectés par les messages Hello qu'ils émettent. Les messages IHU (I Heard You) envoyés en sens inverse permettent notamment de s'assurer que le lien est bien bidirectionnel.
Les détails de la maintenance de la table de routage figurent en section 3.5. Chaque mise à jour envoyée par un nœud Babel est un quintuplet {préfixe IP, longueur du préfixe, ID du routeur, numéro de séquence, métrique}. Chacune de ces mises à jour est évaluée en regard des conditions de faisabilité : une distance de faisabilité est un doublet {numéro de séquence, métrique} et ces distances sont ordonnées en comparant d'abord le numéro de séquence (numéro plus élevée => distance de faisabilité meilleure) et ensuite la métrique (où le critère est inverse). Une mise à jour n'est acceptée que si sa distance de faisabilité est meilleure.
Si la table des routes contient plusieurs routes vers un préfixe donné, laquelle choisir et donc réannoncer aux voisins (section 3.6) ? La politique de sélection n'est pas partie intégrante de Babel. Plusieurs mises en œuvre de ce protocole pourraient faire des choix différents. Les seules contraintes à cette politique sont qu'il ne faut jamais réannoncer les routes avec une métrique infinie (ce sont les retraits, lorsqu'une route n'est plus accessible), ou les routes infaisables (selon le critère de faisabilité cité plus haut). Si les différents routeurs ont des politiques différentes, cela peut mener à des oscillations (routes changeant en permanence) mais il n'existe pas à l'heure actuelle de critères scientifiques pour choisir une bonne politique. On pourrait imaginer que le routeur ne garde que la route avec la métrique le plus faible, ou bien qu'il privilégie la stabilité en gardant la première route sélectionnée, ou encore qu'il prenne en compte des critères comme la stabilité du routeur voisin dans le temps. En attendant les recherches sur ce point, la stratégie conseillée est de privilégier la route de plus faible métrique, en ajoutant un petit délai pour éviter de changer trop souvent.
Une fois le routeur décidé, il doit envoyer les mises à jour à ses voisins (section 3.7). Ces mises à jour sont transportées dans des paquets multicast (mais peuvent l'être en unicast). Les changements récents sont transmis immédiatement, mais un nœud Babel transmet de toute façon la totalité de ses routes à intervalles réguliers. Petite optimisation : les mises à jour ne sont pas transmises sur l'interface réseau d'où la route venait, mais uniquement si on est sûr que ladite interface mène à un réseau symétrique (un Ethernet filaire est symétrique mais un lien WiFi ad hoc ne l'est pas forcément).
Un routeur Babel peut toujours demander explicitement des annonces de routes à un voisin (section 3.8). Il peut aussi demander une incrémentation du numéro de séquence, au cas où il n'existe plus aucune route pour un préfixe donné (problème de la famine, section 3.8.2.1).
La section 4 spécifie l'encodage des messages Babel sur le
réseau. C'est un paquet UDP, envoyé à une
adresse multicast (FF02:0:0:0:0:0:1:6
ou 224.0.0.111
) ou bien unicast,
avec un TTL de 1 (puisque les messages Babel
n'ont jamais besoin d'être routés), et un port
source et destination de 6696. En IPv6, les
adresses IP de source et de destination unicast sont
link-local et en IPv4 des
adresses du réseau local.
Les données envoyées dans le message sont typées et la section 4.1
liste les types possibles, par exemple interval, un
entier de 16 bits qui sert à représenter des durées en centisecondes
(rappelez-vous que, dans Babel, un routeur informe ses voisins de ses
paramètres temporels, par exemple de la fréquence à laquelle il envoie
des Hello
). Plus complexe est le type
address, puisque Babel permet d'encoder les
adresses par différents moyens (par exemple, pour une adresse IPv6
link-local, le préfixe
fe80::/64
peut être omis).
Ensuite, ces données sont mises dans des
TLV, eux-même placés derrière l'en-tête Babel,
qui indique un nombre magique (42...) pour identifier un paquet Babel,
un numéro de version (aujourd'hui 2) et la longueur du message. (La
fonction babel_print_v1
dans le
patch de tcpdump est un bon
moyen de découvrir les différents types et leur rôle.) Chaque TLV, comme son nom l'indique, comprend un
type (entier sur huit bits), une longueur et une valeur, le
corps, qui peut comprendre plusieurs champs
(dépendant du type). Parmi
les types existants :
Hello
. Le corps
contient notamment le numéro de séquence actuel du routeur. Le type 5
désigne une réponse au Hello
, le IHU, et ajoute
des informations comme le coût de la liaison entre les deux
routeurs ou comme la liste des voisins entendus (les amateurs d'OSPF
noteront que, dans ce protocole, la liste des voisins détectés
apparaît dans le Hello
, ce qui augmente sa taille).Update
(type 8) contient notamment un préfixe (avec sa longueur), un numéro
de séquence, et une métrique.Quelle est la sécurité de Babel ? La section 6 dit franchement
qu'elle est à peu près inexistante. Un méchant peut annoncer les
préfixes qu'il veut, avec une faible métrique pour être sûr d'être
sélectionné, afin d'attirer tout le trafic. Des extensions futures à
Babel (par exemple telles que spécifiées dans le projet
draft-ietf-ospf-auth-trailer-ospfv3
) permettront peut-être de signer les messages mais ce n'est pas
encore fait. (Notons que, en matière de routage, la signature ne
résout pas tout : c'est une chose d'authentifier un voisin, une autre
de vérifier qu'il est autorisé à annoncer ce préfixe.)
En IPv6, une protection modérée est fournie par le fait que les adresses source et destination sont locales au lien. Comme les routeurs IPv6 ne sont pas censés faire suivre les paquets ayant ces adresses, cela garantit que le paquet vient bien du réseau local.
Vous pourrez trouver plus d'informations sur Babel en lisant le RFC, ou bien sur la page Web officielle.
Qu'en est-il des mises enœuvre de ce protocole ? Il existe une
implémentation d'exemple, assez éprouvée pour être disponible en
paquetage dans plusieurs systèmes, comme babeld dans
Debian ou dans OpenWrt, plateforme très
souvent utilisée pour des routeurs libres (cf. https://dev.openwrt.org/browser/packages/net/babel
). Si vous
voulez écrire votre implémentation, l'annexe C contient plusieurs conseils utiles,
accompagnés de calculs, par exemple sur la consommation mémoire et
réseau. Le RFC proclame que Babel est un protocole relativement simple
et, par exemple, l'implémentation de référence
contient environ 7300 lignes de C.
Néanmoins, cela peut être trop, une fois compilé, pour des objets (le RFC cite les fours à micro-ondes...) et l'annexe C décrit donc des sous-ensembles raisonnables de Babel. Par exemple, une mise en œuvre passive pourrait apprendre des routes, sans rien annoncer. Plus utile, une mise en œuvre « parasite » n'annonce que la route vers elle-même et ne retransmet pas les routes apprises. Ne routant les paquets, elle ne risquerait pas de créer des boucles et pourrait donc omettre certaines données, comme la liste des sources. (Le RFC liste par contre ce que la mise en œuvre parasite doit faire.)
Toujours côté programmes, il existe un patch à tcpdump pour afficher les paquets Babel et un en cours pour Wireshark. On commence à voir des traces Babel sur pcapr.net.
Si vous voulez approfondir la question des protocoles de routage, une excellente comparaison a été faite par David Murray, Michael Dixon et Terry Koziniec dans « An Experimental Comparison of Routing Protocols in Multi Hop Ad Hoc Networks » où ils comparent Babel (qui l'emporte largement), OLSR (RFC 7181) et Batman (ce dernier est dans le noyau Linux officiel). Notez aussi que l'IETF a un protocole standard pour ce problème, RPL, décrit dans le RFC 6550.
Merci beaucoup à Juliusz Chroboczek pour sa relecture et ses nombreux avis.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : P. Saint-Andre (Cisco), J. Hodges (PayPal)
Chemin des normes
Première rédaction de cet article le 1 avril 2011
Un RFC long et complexe pour un problème
difficile. En résumant violemment, il s'agit de savoir quelle
identité utiliser lorsqu'un client
TLS s'assure de l'authenticité du serveur
auquel il se connecte. Par exemple, si un MTA
veut transmettre du courrier à bill@example.com
,
que doit contenir le certificat
X.509 du MX d'example.com
pour que l'authentification réussisse ?
example.com
? D'autres noms, plus spécifiques à
ce service, sont-ils possibles ? Ce cas particulier est mentionné
dans la section 4.1 du RFC 3207 mais très peu détaillé, et renvoyé à des
décisions locales. Comme de nombreux autres protocoles ont des
problèmes de ce genre, l'idée avait germé de faire un RFC générique,
définissant un cadre et des principes,
RFC que les protocoles n'auraient plus qu'à citer. C'est notre RFC 6125 (depuis remplacé par le RFC 9525).
Traditionnellement, l'identité du pair avec lequel on se connecte était indiqué dans le champ Subject du certificat X.509. openssl permet de l'afficher :
% openssl s_client -starttls smtp -connect mail.bortzmeyer.org:25 ... Certificate chain 0 s:/C=FR/ST=Ile-de-France/L=Paris/O=Moi/OU=Maison/CN=mail.bortzmeyer.org/emailAddress=postmaster@b ortzmeyer.org ...
Le champ Sujet est formé de doublets attribut-valeur (par exemple,
l'attribut C veut dire Country, ici la France)
notamment CN (Common Name), le plus utilisé. Mais l'identité pouvait aussi figurer dans une
extension X.509, Subject Alternative Name (section
4.2.1.6 du RFC 5280). Cette extension est rare en pratique,
bien que normalisée depuis de nombreuses années. Je ne sais pas
comment l'afficher avec openssl. La seule solution que je
connaissais était de copier/coller le certificat affiché par
openssl s_client -connect www.example.com:443
puis de faire un openssl x509 -text -noout -in
/le/certificat.pem
, ici avec le serveur HTTPS www.digicert.com
:
Certificate: ... Subject: businessCategory=V1.0, Clause 5.(b)/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Utah/serialNumber=5299537-0142, C=US, ST=Utah, L=Lindon, O=DigiCert, Inc., CN=www.digicert.com ... X509v3 extensions: ... X509v3 Subject Alternative Name: DNS:www.digicert.com, DNS:www.origin.digicert.com, DNS:content.digicert.com, DNS:digicert.com ...
On peut aussi combiner les deux commandes (openssl s_client
-connect www.digicert.com:443 | openssl x509 -text
) voire
n'afficher que la partie qui nous intéresse (openssl s_client -connect www.digicert.com:443 | openssl x509 -text | perl -n0777e 'print $1 if /(.*Subject Alternative Name:.*\n.*\n)/'
, merci à minimalist pour son aide).
Mais les
navigateurs Web permettent en général de
montrer tout le certificat, y compris cette extension. Regardez par
exemple sur https://www.cisco.com/
ou bien https://www.digicert.com/
. Un Subject Alternative
Name peut contenir un dNSName
(un
nom de domaine), mais aussi un
uniformResourceIdentifier
(un
URI) et, par des extensions de l'extension
(RFC 4985), un
SRVName
(un nom de service, tel que présent en
partie gauche d'un enregistrement SRV).
Quel nom utiliser lorsque plusieurs sont présents ? C'est tout le but de ce RFC : lorsqu'un client TLS se connecte à un serveur TLS, et qu'une authentification X.509 prend place, le client a une idée sur l'identité du serveur (reference identity, identité de référence, dit le RFC) et le serveur présente un certificat contenant un certain nombre d'identités (presented identity, identité affichée). Comment comparer ? Aujourd'hui, la situation est plutôt confuse et deux approches sont largement utilisées :
Une partie de la difficulté est que le déploiement d'une méthode propre et standard nécessite la copération de plusieurs acteurs. Ce nouveau RFC 6125 est surtout destiné à l'usage interne de l'IETF, aux concepteurs de protocoles (section 1.2). Mais les autres acteurs impliqués, par exemple ceux qui écrivent les logiciels ou bien qui gèrent une CA ont tout intérêt à le lire également. Ils ne s'amuseront pas forcément (ce RFC est long, complexe et très abstrait, la section 1.3 donne quelques pistes pour le lire sans trop souffrir) mais ils apprendront des choses utiles. Avant de se mettre à la lecture, il fraut s'assurer d'avoir lu et bien compris le RFC 5280, dont les règles demeurent actives. Il faut également garder en mémoire les RFC spécifiques d'un protocole applicatif particulier comme le RFC 2595 pour IMAP, RFC 2818 pour HTTP, RFC 2830 pour LDAP, RFC 3207 pour SMTP, RFC 6120 pour XMPP, et plusieurs autres encore (liste en section 1.6)...
Pour le lecteur pressé, la section 1.5 résume les recommandations essentielles de ce RFC 6125 :
*.example.com
),
un conseil qui plaira aux CA, car il augmentera leur chiffre d'affaires.Plusieurs points sont exclus de ce RFC (section 1.7) :
rfc822Name
), qui peuvent servir en cas de
présentation d'un certificat client. Notre RFC ne considère que
l'authentification du serveur.Une fois éliminé ces « non-sujets », le lecteur doit ensuite passer un peu de temps sur la section de terminologie en 1.8, car X.509 utilise beaucoup de vocabulaire. Il faut également connaître le vocabulaire standard de la sécurité, exposé dans le RFC 4949. Parmi les sigles dont on aura le plus besoin ici :
www.gmail.com
(après redirection vers mail.google.com
), le champ sujet est
CN = mail.google.com, O = Google Inc, L = Mountain View, ST
= California, C = US
et le CN-ID est
mail.google.com
. C'est de très loin le type le plus fréquent
aujourd'hui.dNSName
mis dans l'entrée subjectAltName
du RFC 5280. Par exemple, dans le certificat actuel de
www.digicert.com
, le DNS-ID est
www.digicert.com
(le même que le CN-ID, ce qui
est le cas de la quasi-totalité des certificats qu'on trouve sur
l'Internet public).subjectAltName
du RFC 5280 (plus le RFC 4985
pour le SRV-ID), de types respectifs SRVName
et
uniformResourceIdentifier
. On ne les trouve
quasiment jamais dans les certificats disponibles sur l'Internet public.Puisqu'on parle de ce qu'on trouve en pratique ou pas, je précise que mes avis là-dessus sont surtout tirés de quelques explorations faites sans méthode. Ce qui serait cool, ce serait d'avoir un Google des certificats X.509. Un robot récolterait les certificats, les analyserait et un moteur de recherches permettrait de trouver « Des certificats avec Subject Alternative Name » ou bien « Des certificats avec un condensat MD5 » ou aussi « Des certificats expirant après 2014 » ou encore « Des certificats Comodo émis par la Iranian Cyber Army :-) » Il existe deux projets allant dans cette direction : SSLiverse, qui a la récolte mais pas le moteur de recherche. L'archive fait 12 Go et est disponible en torrent. Il ne reste plus qu'à fouiller dedans (ce qui peut s'avérer assez long), la liste de diffusion du projet devient utile dans ce cas (merci à Étienne Maynier pour ses conseils et informations). L'autre projet est Shodan qui, lui, dispose non seulement d'une telle base, mais d'une partie des fonctions de recherche souhaitées (mais pas celle qui me fallait, pour trouver les certificats avec Subject Alternative Name).
Maintenant, passons aux noms. Un certificat contient les noms de
services comme www.example.org
. Certains noms
sont directs : ils ont été tapés par un être
humain ou sélectionnés à partir d'une page Web. D'autres, indirects,
ont été obtenus, par exemple via une résolution
DNS. Ainsi, pour envoyer du courrier à
sandra@example.com
, une résolution DNS de type
MX permettra de trouver le relais de courrier
de example.com
, mettons
smtp.example.net
. (On peut noter que, en
l'absence de résolution sécurisée, par exemple par
DNSSEC, c'est le premier nom qu'il faut
chercher dans le certificat,
le second peut être le résultat d'un empoisonnement DNS.)
Les noms peuvent également être restreints ou pas. Un nom restreint ne peut être utilisé que pour un seul service. Par exemple, une CA peut émettre un certificat qui ne sera utilisable que pour de l'IMAP.
On voit donc qu'un CN-ID ou un DNS-ID sont directs et non restreints, qu'un SRV-ID peut être direct ou indirect (mais il est indirect la plupart du temps) mais est restreint (le nom de l'enregistrement SRV indique un certain type de service), qu'un URI-ID est direct et restreint.
Et le nom de domaine lui-même, a-t-il plusieurs catégories possibles ? Oui, dit la section 2.2 qui sépare les noms en :
Au tout début de X.509, les noms étaient censés être tirés d'un
grand Annuaire officiel X.500 mais ce projet
s'est cassé la figure, comme la plupart des autres éléphants blancs de
l'UIT et il ne reste que des certificats
isolés (section 2.3). Pour assurer l'unicité des noms, la méthode la
plus courante sur l'Internet a donc rapidement été de mettre un nom de
domaine dans le CN (Common Name) du sujet du
certificat, par exemple C=CA,O=Example
Internetworking,CN=mail.example.net
. Mais ce n'est qu'une
convention : le CN n'est pas typé, il peut contenir n'importe quoi,
par exemple un nom lisible par un humain comme CN=A Free
Chat Service,O=Example Org,C=GB
et, dans ce cas, la
vérification automatique de ce nom par rapport à ce qu'attendait
l'utilisateur n'est pas évidente. Voici pourquoi notre RFC 6125 recommande l'utilisation des champs typés de
subjectAltName
au lieu du CN (recommandation très
peu suivie dans l'Internet d'aujourd'hui).
Ces (longs) préliminaires étant achevés, la section 3 commence enfin la partie pratique du RFC, destinée aux auteurs de protocoles. Ceux-ci doivent d'abord faire une petite liste des caractéristiques pertinentes de leur protocole : utilise-t-il les enregistrements SRV ? Utilise-t-il des URI ? A-t-il besoin de jokers dans les noms de domaine ? Armé de cette connaissance, le concepteur de protocoles peut passer à la section 4 qui définit les règles de production d'identité (les règles pour les autorités de certification, donc).
Il est donc recommandé de mettre dans les certificats un
subjectAltName
DNS-ID. Si le protocole utilise
les SRV, il est recommandé de mettre un SRV-ID (même conseil évident
pour les URI). J'aimerais bien savoir
combien de CA permettent de mettre un tel identificateur. Je parierais
bien qu'il n'y en a aucune. Le RFC conseille également de ne
pas inclure de nom de domaine dans le CN, pour
encourager la migration (notons que le premier exemple donné, en
section suivante, ne suit pas ce conseil...).
Voyons quelques exemples concrets :
www.example.com
doit inclure un DNS-ID
www.example.com
et peut inclure un CN-ID
www.example.com
pour la compatibilité avec les
vieilles implémentations.user@example.net
et se nomme
mail.example.net
, comme le protocole peut
utiliser les SRV (cf. RFC 6186), il faudra
mettre le SRV-ID _imap.example.net
, ainsi que les
DNS-ID example.net
et
mail.example.net
(là encore, on pourra ajouter un
nom de domaine dans le CN, si on tient à gérer les vieux clients
IMAP).XmppAddr
(section 13.7.1.4 du RFC 6120).user@voice.example.edu
, comme SIP peut utiliser
des URI (cf. RFC 5922), il faudra au moins un URI-ID
sip:voice.example.edu
et un DNS-ID
voice.example.edu
.Ces spécifications de la section 4 étaient pour les autorités de certification. Et les gérants des services sécurisés, que doivent-ils mettre dans leurs demandes de certificats (CSR, Certificate Signing Requests) ? La section 5 précise qu'ils doivent demander tous les identificateurs nécessaires (ce qui ne veut pas dire que la CA leur donnera...), donc, par exemple, le SRV-ID et le DNS-ID dans le cas de IMAP. Si le certificat sera utilisé pour des services différents, il vaut mieux ne demander que le DNS-ID (les autres étant restreints, rappelez-vous la section 2.1).
Les gérants des services ont demandé les certificats (section 6), les CA ont émis des certificats (section 5), reste à les vérifier dans le logiciel client (section 6, qui concerne donc surtout les programmeurs). Le principe est le suivant :
thierry.breton@iloveemail.example
, le nom
iloveemail.example
sera une identité de référence
(rappelez-vous que notre RFC ne se préoccupe que d'authentifier des
serveurs, pas des personnes, donc le nom de l'individu n'est pas pris
en compte). Si l'utilisateur a sélectionné
https://www.dns-oarc.net/
sur une page Web,
www.dns-oarc.net
est une identité de référence.Le reste de la section 6 formalise cette méthode. Quelques points particuliers, par exemple :
gmail.com
»). La règle n'est toutefois pas
absolue car, par exemple, l'utilisateur a pu « épingler » un autre nom
précédemment (« je sais que le serveur XMPP de
example.org
est
jabber.toto.example
, authentifie ce dernier
nom », cf. section 7.1).
Le RFC donne quelques exemples : une requête
Web pour
https://www.dns-oarc.net/
produira une liste
d'identités de référence comportant un DNS-ID,
www.dns-oarc.net
et un CN-ID optionnel
identique. Une tentative de connexion IMAP pour le domaine
example.net
, dont l'enregistrement SRV indiquera
que le serveur est mail.example.net
, donnera une
liste comportant les SRV-ID _imap.example.net
et
_imaps.example.net
ainsi que les DNS-ID
example.net
et
mail.example.net
(sans compter le CN-ID)
optionnel. Le RFC ne rappelle apparemment pas que l'étape de
résolution DNS de example.net
en
mail.example.net
n'est pas forcément sûre... Le
fait qu'ils soient sous le même domaine
example.net
n'est pas une protection parfaite
(car on ne connait pas les frontières des zones DNS) et, de toute
façon, le serveur n'est pas forcément dans le même domaine que celui
qu'il sert. Et le RFC semble avoir oublié ici son conseil précédent de se méfier des noms dérivés...
Ensuite, il reste à comparer les deux listes (section 6.3). Le principe est celui de la première correspondance. Dès qu'une identité présentée correspond à une des identités de référence, on s'arrête, on a authentifié le serveur (section 6.6.1) et cette identité authentifiée est celle qui doit pêtre montrée à l'utilisateur. (Le cas où on voudrait que toutes les identités correspondent est laissé à une future norme.) Attention, le CN-ID dans les identités de référence est traité un peu à part : il ne doit pas être utilisé si le certificat inclus d'autres identités (comme un DNS-ID).
Cette correspondance nécessite quelques précisions (section 6.4). Ainsi, le RFC rappelle que les noms de domaine traditionnels doivent être comparés de manière insensible à la casse (RFC 4343), que les noms de domaine internationalisés doivent être transformés en A-labels (cf. RFC 5890) avant comparaison, que les jokers (indiqués par le signe *) nécessitent de l'attention particulière (par exemple, ils ne sont considérés comme spéciaux que s'ils apparaissent seuls, dans le composant le plus à gauche du nom). Globalement, faire correctement cette comparaison n'est pas trivial pour le programmeur.
Pour les CN, il est rappelé qu'un CN dans la liste des identités de référence n'est là que pour pouvoir authentifier avec les « vieux » certificats et ne doit pas être utilisé avec un certificat moderne, incluant des DNS-ID, SRV-ID ou URI-ID. S'il n'y a pas le choix (pas de Subject Alternative Name dans le certificat), l'application peut comparer ses identités de référence au CN, en suivant les règles de comparaison des noms de domaine.
Bon, si l'authentification du serveur a réussi, on continue et on affiche à l'utilisateur, sur un joli fond vert, l'identité authentifiée. Et si ça a raté, que doit-on faire ? La section 6.6.4 propose des stratégies de repli : si le logiciel est interactif, avec un humain pas loin, la méthode recommandée est de mettre fin à la connexion, avec un message d'erreur (conseil que je trouve déplorable : vu le nombre de certificats invalides, cela diminuerait nettement l'utilisabilité du Web et cela encouragerait les sites à ne pas proposer HTTPS). La possibilité de permettre à l'utilisateur de passer outre le problème et de contnuer (ce que font tous les navigateurs Web, autrement ils perdraient tous leurs clients) est mentionnée mais très découragée.
Si l'application n'est pas interactive, la démarche recommandée est
d'afficher un message d'erreur et de s'arrêter. Une option pour
ignorer le certificat est possible mais ne doit pas être activée par
défaut. C'est ainsi que wget, fidèle à cette
règle, a son option --no-check-certificate
, alors
que
fetchmail, qui ne suit pas le RFC, a son
--sslcertck
pour activer la
vérification.
D'ailleurs, une section entière, la 7, est consacrée à la discussion détaillée de certains problèmes de sécurité. Ainsi, les jokers font l'objet de la section 7.2. Ils sont déconseillés (pour les raisons expliquées en « New Tricks for Defeating SSL in Practice » et « HTTPS Can Byte Me ») mais, s'ils sont présents dans un certificat, le client devrait se préparer à les gérer, avec prudence.
Autre cas complexe, celui où un même serveur est accédé par plusieurs noms (virtual hosting) par exemple un serveur IMAP qui hébergerait plusieurs domaines de messagerie, ce qui est courant. Il existe plusieurs méthodes pour gérer ce cas, comme de mettre tous les noms possibles dans le certificat (pas pratique...), ou bien d'utiliser SNI (Server Name Indication, section 3 du RFC 6066). Si on met plusieurs noms dans le certificat, le RFC recommande que ce soit plusieurs DNS-ID (ou SRV-ID ou URI-UID) pas plusieurs CN.
Voilà, arrivé ici, le concepteur d'un protocole utilisant l'authentification avec X.509 sait normalement tout ce qu'il faut savoir. Il ne lui reste plus qu'à inclure dans sa spécification le texte exact et, pour lui faciliter la vie, l'annexe A contient un tel texte (pris dans le RFC 6120, section 13.7.1.2), qui peut être copié/collé avant d'être adapté à ce protocole particulier. De nombreux RFC avaient des règles spécifiques, avant la publication de notre RFC 6125 et la variété de ces règles était justement une motivation pour le développement du nouveau RFC. L'annexe B rappelle et cite les principaux RFC qui avaient traité le sujet comme le RFC 2818 pour HTTPS ou le RFC 2830 pour LDAP.
Ce RFC 6125 avait été chaudement discuté à l'IETF, ce qui explique qu'il ait mis si longtemps à être publié. Le lecteur courageux doit relire toutes les archives de la liste certid pour suivre toutes ces discussions (je recommande celles de septembre 2010 et décembre 2010).
Quelques petits trucs techniques pour ajouter des extensions comme
subject alternative name
avec les logiciels
existants (merci à Dany Mello et Christian Pélissier ; on peut aussi
consulter mon article « Plusieurs noms dans un certificat X.509 »). Avec OpenSSL,
on peut aussi utiliser un fichier texte où on place l'extension. Pour une
extension de type IP, le fichier ext.txt
contient :
subjectAltName="IP:1.1.1.1"
puis on ajoute l'argument -extfile
dans la ligne de commande d'openssl :
% openssl x509 -req -days 7300 -in moncsr.csr -CA ca.crt -CAkey ca.key \ -set_serial 01 -out moncrt.crt -extfile ext.txt
Avec l'utilitaire certpatch (qui ne semble pas très documenté) disponible dans le paquetage isakmpd, c'est :
% certpatch -t fqdn -i www.example.org -k /etc/ssl/private/ca.key \ oldcert.crt nwcert.crt
Avec l'utilitaire certutil (des outils de sécurité NSS), c'est :
% certutil -R -s "cn=dapou.exemple.fr,ou=DI,o=Exemple,...,c=FR" \ -a -o $CADIR/$host.$domain.pem.csr -d $CADIR \ -8 "cn=ldap1.exemple.fr" \ -z random -f password-file
où ldap1.exemple.fr
sera le nom alternatif.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : P. Saint-Andre (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF xmpp
Première rédaction de cet article le 31 mars 2011
Ce RFC normalisait le format des adresses du protocole de messagerie instantanée XMPP, également connu sous son ancien nom de Jabber. Il s'agissait d'un document transitoire, qui remplaçait une partie de l'ancien RFC 3920, et qui a lui même été remplacé par le RFC 7622.
Le protocole XMPP est le standard actuel de
messagerie instantanée de
l'IETF. Les utilisateurs sont identifiés par
une adresse également connue, pour des raisons
historiques, sous le nom de JID (Jabber
IDentifier). Ces adresses ont une forme qui ressemble aux
adresses de courrier électronique mais elles
sont en fait complètement différentes. Ainsi, j'ai personnellement
deux adresses XMPP, bortzmeyer@gmail.com
(le
service de messagerie Google Talk utilise en
effet la norme XMPP), qui me sert surtout pour la distraction, et
bortzmeyer@dns-oarc.net
qui me sert pour le
travail. Mais rien ne dit qu'un courrier envoyé à ces adresses
fonctionnera : adresses XMPP et de courrier vivent dans des mondes différents.
Le format des adresses XMPP était spécifié à l'origine dans le document XEP-0029. Puis il a été normalisé dans la section 3 du RFC 3920. La norme XMPP ayant subi une refonte complète, qui a mené entre autre à un nouveau RFC, le RFC 6120, se posait la question du format d'adresses, dont l'internationalisation, compte-tenu de la nouvelle norme IDN, suscitait des débats. Ces débats n'étant pas terminés, la décision a été prise de sortir le format d'adresses du RFC principal, et d'en faire ce RFC 6122, jusqu'à ce qu'un consensus apparaisse sur le format « définitif ».
Donc, quels sont les points essentiels des adresses XMPP (section
2) ? Une adresse (ou JID) identifie une entité (un humain mais peut-être aussi
un programme automatique). Elle comprend trois parties (donc une seule
est obligatoire), la partie locale, le
domaine et une
ressource. Ainsi, dans
bortzmeyer@gmail.com/Home
,
bortzmeyer
est la partie locale,
gmail.com
le domaine et Home
la ressource. Le @ et le
/ servent de séparateurs. Chacune des trois
parties peut-être composée de caractères
Unicode (cf. section 3), qui doivent être encodés en
UTF-8. La partie locale doit être canonicalisée
avec Nodeprep
, le domaine avec le
Nameprep
du RFC 3491. Seul le domaine est obligatoire et
bot.example.org
est donc un JID valide.
Les adresses XMPP (ou JID) sont souvent représentées sous forme
d'un IRI, selon le RFC 5122. En gros, un IRI XMPP est un JID préfixé par
xmpp:
. Mais ces IRI ne sont pas utilisés par le
protocole XMPP. Dans les champs to
et
from
des strophes (stanzas) XMPP, on
ne trouve que des JID (sans le xmpp:
devant). Les
IRI ne servent que dans les liens dans les pages Web, comme xmpp:bortzmeyer@gmail.com
(attention, ce lien ne marchera pas
avec tous les navigateurs).
Le RFC détaille ensuite chaque partie. Le domaine, seule partie
obligatoire, est dans la section 2.2. On peut le voir comme une
identification du service auquel on se connecte
(gmail.com
= Google Talk), et la création de
comptes et l'authentification se font typiquement en fonction de ce
service. En théorie, une adresse IP est
acceptable pour cette partie mais, en pratique, c'est toujours un
FQDN. Ce nom de domaine peut être un
IDN donc
instantanée.nœud.example
est un nom
acceptable pour former un JID. Auquel cas, ce doit être un IDN légal
(ce qui veut dire que toute chaîne de caractères Unicode n'est pas
forcément un nom légal pour la partie domaine d'un JID). À noter que
XMPP n'utilise pas l'encodage en
ASCII des IDN (le Punycode).
Et la partie locale, celle avant le @ ? La
section 2.3 la couvre. Elle est optionnelle et identifie en général
une personne (mais peut aussi indiquer un programme ou bien un salon de
conversation à plusieurs). Si elle est en Unicode, elle doit être
canonicalisable avec le
profil Nodeprep
(Nodeprep
est normalisé en
annexe A de notre RFC).
Quant à la ressource, troisième partie du JID (après le
/), également optionnelle, elle sert à
distinguer plusieurs sessions par le même utilisateur (par exemple
/Home
et /Office
). La
section 2.4 la décrit en détail. Également en Unicode, elle est
canonicalisée par le profil Resourceprep
. Elle n'a pas de structure
officielle. Un / dans une ressource (par exemple
example.com/foo/bar
) n'implique donc pas une hiérarchie.
De même, si on y trouve quelque chose ressemblant à une adresse (par
exemple joe@example.net/nic@host
), cette ressource
nic@host
doit être traitée comme un identificateur
opaque (et pas être analysée en « nom (at) machine »).
Quelles sont les conséquences de sécurité de ces adresses ? Il n'y
en a guère mais, bon, il y a toujours des inquiets donc la section 4
examine en détail tous les risques, même très théoriques. Bien sûr,
les adresses XMPP héritent des questions de sécurité de
Stringprep
(section 9 du RFC 3454) mais le RFC mentionne surtout les risques de triche
sur les
adresses. Il y en a de deux sortes, les usurpations et les
imitations. Les usurpations (section 4.3.1) sont les cas où un méchant
arrive à envoyer un message XMPP en trichant sur
l'origine, par exemple si jean@example.net
, une
fois authentifié auprès de son propre serveur, arrive
à transmettre un message prétendant venir de
jeanne@jabber.example
. Normalement, le protocole
XMPP empêche cela, par l'authentification mutuelle des serveurs (sauf
attaques un peu sophistiquées, par exemple sur le DNS). Cela
dit, cette authentification n'empêche pas un serveur d'annoncer une
autre partie locale (jeanne@example.net
au lieu
jean@example.net
).
L'autre risque est celui d'imitation (section 4.3.2). Cette fois,
il s'agit d'utiliser des JID légitimes et authentiques mais qui ressemblent à celui de la victime,
par exemple fric@paypa1.com
au lieu de
fric@paypal.com
(si vous ne voyez pas la
différence, regardez mieux). Cette technique est souvent connue sous
le nom de typejacking. Dans un accès de beaufitude,
le RFC mentionne aussi le cas d'écritures « moins familières » que
l'alphabet latin (moins familières pour qui ?)
mais, comme le montre l'exemple du RFC ou bien celui cité plus haut,
le problème arrive même en se limitant à ASCII. Si vous voulez un joli
exemple avec Unicode (mais le résultat dépend de l'environnement avec
lequel vous lisez cet article), le RFC cite ᏚᎢᎵᎬᎢᎬᏒ
qui ressemble à
STPETER
mais est écrit en
Cherokee. Comme un JID peut contenir à peu près
n'importe quel caractère Unicode, il n'y a pas vraiment de prévention technique
possible contre ce problème. Toutefois, contrairement à ce que prétend
le RFC (qui évoque le spectre du hameçonnage),
il est peu probable que cela ait des conséquences en pratique. Le RFC, qui
exagère le risque, suggère que les serveurs XMPP qui servent une
communauté homogène, linguistiquement parlant, peuvent réduire le jeu
de caractères Unicode acceptés comme partie locale d'un JID (par
exemple, à l'alphabet cyrillique pour un
serveur russe). Une telle
politique serait, je trouve, un gros recul dans l'internationalisation
de l'Internet et, de toute façon, elle n'aiderait pas les serveurs
internationaux comme jabber.org
ou
Google Talk. Une approche moins restrictive est
aussi proposée par le RFC : le logiciel client XMPP pourrait prévenir
visuellement l'utilisateur lorsqu'un JID utilise une écriture
distincte de celle utilisée habituellement par l'utilisateur (et qui
est déduisible de ses préférences).
Le RFC se termine par les annexes normalisant
les profils Nodeprep
et
Resourceprep
. Rappelons que
Stringprep
(RFC 3454)
décrit un cadre général pour la canonicalisation de chaînes de
caractères Unicode, afin de faciliter les comparaisons
ultérieures. Stringprep
laisse un grand nombre de
choix ouverts et doit donc, avant utilisation, être réduit à un
profil. Les profils normalisés sont enregistrés
à l'IANA. Par exemple, Nodeprep
précise
que la normalisation Unicode utilisée doit être la
NFKC et donne la liste des caractères interdits
dans une partie locale
(par exemple @, <, >, /,
etc). Resourceprep
, lui, est dans l'annexe B et
n'est pas équivalent (par exemple, les caractères cités plus haut ne
sont pas interdits dans la ressource d'un
JID). Stringprep ayant depuis été abandonné (remplacé par le cadre du RFC 7564), une nouvelle version de XMPP est en cours de rédaction pour la partie « Unicode ».
La liste complète des changements par rapport au RFC 3920 figure en annexe C. Rappelons que le RFC 3920 s'appuyait, pour les parties en
Unicode, sur des profils
Stringprep
(RFC 3454) comme Nameprep
. Ce Nameprep
, décrit dans le RFC 3491, ayant été supprimé à l'occasion de la
réforme IDNA bis, la question se posait
de l'avenir des profils Stringprep
. Un groupe de
travail IETF, PRECIS, a été monté pour
discuter de l'avenir des normes utilisant
Stringprep
. Son travail n'étant pas terminé, et le
groupe de travail sur XMPP ne souhaitant pas retarder la sortie de la
nouvelle norme (RFC 6120), la question du
successeur de Nameprep
a été remise à plus tard et
notre RFC 6122 normalise donc le format d'adresses XMPP
tel qu'il était avant IDNA bis. Le RFC note que les implémenteurs sont
encouragés à utiliser dès maintenant IDNA bis, même avant la sortie du
RFC sur le format d'adresses (à part la question de la
canonicalisation avec Nameprep
, les différences
entre l'IDN original et IDNA bis sont de peu d'importance
pratique). Ce RFC a finalement été le RFC 7622,
qui est désormais la norme des adresses XMPP.
Les autres changements sont limités : clarification sur
l'utilisation d'adresses IPv6 littérales dans
les JID (j'offre une bière au premier qui annonce un JID
quelqun@[2001:db8::bad:dcaf:1]
qui
marche), correction de bogues dans la
grammaire pour le cas de termes de longueur
nulle, changements de terminologie (la partie locale se nommait
node identifier, d'où le terme de
Nodeprep
, survivance de l'ancien vocabulaire), etc.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : P. Saint-Andre (Cisco
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF xmpp
Première rédaction de cet article le 7 avril 2011
Le protocole XMPP, normalisé dans le RFC 6120, est souvent cité comme protocole de messagerie instantanée. Mais c'est en fait plus compliqué que cela : XMPP lui-même ne fournit qu'un service minimum de routage d'éléments XML, les vrais services devant être développés au dessus de XMPP. C'est ainsi que les services de messagerie instantanée et de présence sont normalisé dans ce RFC, le 6121. Il succède au premier RFC sur ces services, le RFC 3921.
Le protocole de base, décrit dans le RFC 6120, transmet des éléments XML, les strophes (stanzas, j'ai choisi cette traduction parce qu'elle maintenait la métaphore musicale), en temps réel ou presque. Sur ce protocole de base, des tas de services sont possibles. La messagerie instantanée est le plus connu. Décrite dans le RFC 2779, elle a aujourd'hui éclipsé la plupart des autres usages de XMPP.
XMPP a été développé vers 1999 sous le nom de Jabber. Le nom de XMPP lui est venu lors de son adoption par l'IETF en 2002, les premiers RFC sont sortis en 2004 et ils viennent d'être mis à jour par la sortie des RFC 6120 (le protocole de base), RFC 6121 (la messagerie instantanée, qui remplace le RFC 3921) et RFC 7622 (le format des adresses). De son histoire, qui s'est déroulée partiellement en dehors de l'IETF, XMPP a gardé plusieurs extensions qui ne sont pas spécifiées dans un RFC, mais dans des documents connus sous le nom de XEP (XMPP Extension Protocols) comme par exemple XEP-0160 pour le stockage des strophes si elles ne peuvent pas être délivrées immédiatement.
Qu'est-ce que la messagerie instantanée ? Vu de XMPP, ce sont une liste de connaissances (le carnet ou roster) et la possibilité d'envoyer entre ces connaissances des messages relativement courts, de manière quasi-instantanée. Contrairement au courrier électronique, dont la caractéristique principale est d'être asynchrone (on peut envoyer un message à quelqu'un qui est en vacances et qui le lira au retour), la messagerie instantanée (ou IM pour Instant Messaging ou chat ou clavardage si on veut parler comme l'Académie française) est synchrone : un message perd beaucoup de son intérêt s'il n'est pas lu tout de suite. Cela implique donc de gérer la présence : les correspondants ont besoin de savoir si le type en face est là ou pas. Comme cette information peut être considérée comme confidentielle, la présence n'est communiquée qu'à ceux qu'on a accepté comme correspondants (buddies, ce qu'un utilisateur de Facebook traduirait sans doute par ami).
Donc, les quatre fonctions :
résument très bien le RFC 2779, qui fut le cahier des charges de XMPP.
La section 1.4 de notre RFC détaille les dites fonctions. Le transport des données, la connexion au serveur, l'authentification, etc, sont des choses très importantes mais elles sont absentes de ce RFC, puisqu'elles sont déjà couvertes dans le RFC 6120. Pour résumer ce dernier : un client XMPP se connecte à un serveur XMPP et s'authentifie. La session XMPP ainsi ouverte (et qui dure typiquement des heures, voire des jours) permet de transmettre des strophes (l'élément de base d'une conversation XMPP), ces strophes pouvant être des messages lisibles par un humain (« Ça va ? Tu viens bouffer ? ») comme des messages de service comme ceux informant de la présence d'un correspondant. (Il y a aussi des messages entre serveurs, pour qu'un utilisateur puisse parler à un client d'un autre service. Contrairement à Facebook ou MSN, XMPP est un protocole Internet, donc ouvert) Une session typique est :
Notons que les utilisateurs ne sont pas forcément des humains, ils peuvent être des bots.
Terminées, les généralités, place au protocole. Ce RFC est très long (cent seize pages), mais la longueur vient surtout du nombre de types de messages possible, pas tellement de la complexité du protocole. Je ne vais pas détailler chaque fonction, seulement mettre en évidence quelques points.
La plus importante fonction est évidemment l'échange de messages,
donc commençons par elle (alors que le RFC fait passer la gestion du
carnet et celle de la présence d'abord). Elle figure en section 5. Le
principe est que le client XMPP transmet au serveur des éléments
<message>
. Ceux-ci sont délivrés à un autre
client connecté au même serveur, ou bien routés vers un autre
serveur. XMPP fonctionne donc par push, pas par
pull : l'information doit être délivrée tout de
suite (la section 8.5.2.1.1 précise ce que doit faire un serveur si un
serveur distant n'est pas disponible de suite).
L'usage le plus courant est sous la forme d'une session de
discussion où plusieurs messages vont se suivre. Dans ces cas,
l'élément <message>
reçoit un attribut
type
dont la valeur est
chat
(section 5.2.2). Voici un exemple de message (vous
noterez vite que tous les examples XMPP sont tirés de
Roméo et Juliette ; je n'ai pas
traduit le texte, que j'ai laissé dans la langue originale, celle de
Shakespeare, pas celle des amants de
Vérone, qui s'échangeaient plutôt des mots doux
en italien).
<message from='juliet@example.com/balcony' id='ktx72v49' to='romeo@example.net' type='chat' xml:lang='en'> <body>Art thou not Romeo, and a Montague?</body> </message>
Tiens, justement, question langues, XMPP permet d'avoir plusieurs versions du même message, en des langues différentes (section 5.2.3). Voici un exemple en anglais et en tchèque :
<message from='juliet@example.com/balcony' id='z94nb37h' to='romeo@example.net' type='chat' xml:lang='en'> <body>Wherefore art thou, Romeo?</body> <body xml:lang='cs'> PročeŽ jsi ty, Romeo? </body> </message>
La section 3 explique le mécanisme de gestion de la présence. Celle-ci n'est transmise qu'aux abonnés, pas au public. Pour s'abonner, on envoie une demande (ici de Roméo vers Juliette) :
<presence id='xk3h1v69' to='juliet@example.com' type='subscribe'/>
Cette demande est en général présentée à l'utilisateur pour qu'il l'approuve (section 3.1.3). Le serveur peut alors répondre :
<presence from='juliet@example.com' id='xk3h1v69' to='romeo@example.net' type='subscribed'/>
Une fois qu'on est approuvé, un peut recevoir des informations de présence (section 4). Celles-ci indiquent si l'entité (la personne ou le programme mais, en général, les programmes ne s'absentent pas) est disponible ou pas. Les clients XMPP l'affichent alors par exemple en vert si le contact est disponible et en rouge autrement, ou bien avec du texte comme online et offline. Donc, lorsque je lance mon client XMPP, ou bien lorsque je change manuellement l'état (le menu en bas de la fenêtre des contacts, avec Pidgin), le client XMPP envoie au serveur :
<presence/>
et celui-ci le retransmet aux abonnés (section 4.2.2). Le client peut aussi marquer explicitement qu'il ne veut pas être dérangé :
<presence type='unavailable'/>
information à laquelle on peut ajouter une explication :
<presence type='unavailable' xml:lang='fr'> <status>Je suis en vacances.</status> </presence>
La section 2 concerne la gestion du carnet (roster). Le serveur le stocke et le transmet à l'utilisateur, ce qui permet à celui-ci de disposer de son carnet depuis n'importe quelle machine (rappelons que XMPP est un protocole ouvert et que n'importe qui peut installer un serveur : celui-ci n'est donc pas forcément une grosse entreprise anonyme dans le nuage, il peut être géré par votre entreprise, votre association, par un copain ou par vous-même). Cela ne se fait évidemment qu'après authentification (la liste de mes copains ne regarde que moi...). À noter qu'un des changements depuis le RFC 3921 est que le carnet peut désormais être stocké sur un autre serveur que celui où on se connecte.
En gros, pour avoir le carnet, le client envoie la strophe :
<iq from='juliet@example.com/balcony' id='bv1bs71f' type='get'> <query xmlns='jabber:iq:roster'/> </iq>
et le serveur lui transmet (ici, seulement trois correspondants, pour ne pas rendre cet article trop long) :
<iq id='bv1bs71f' to='juliet@example.com/balcony' type='result'> <query xmlns='jabber:iq:roster' ver='ver11'> <item jid='romeo@example.net' name='Romeo' subscription='both'> <group>Friends</group> </item> <item jid='mercutio@example.com' name='Mercutio' subscription='from'/> <item jid='benvolio@example.net' name='Benvolio' subscription='both'/> </query> </iq>
Dans la liste d'élements <item>
renvoyés,
l'attribut jid
contient l'adresse XMPP formelle (JID =
Jabber ID, voir le RFC 7622)
et name
un identificateur plus
convivial. L'élément <subscription>
indique
si le correspondant est abonné à notre présence, nous à la sienne, ou
bien les deux. Le schéma XML complet figure en
annexe D, en utilisant le langage XSD.
La section 2 couvre également le cas des mises à jour du carnet (le
client ajoute ces mises à jour dans son
<query>
). Notez que XMPP peut aussi utiiser
des enregistrements au format vCard (RFC 6350) pour remplir le carnet (annexe C et XEP-0054). Un serveur comme ejabberd gère cette possibilité.
La section 7 fournit un exemple plus détaillé d'une session complète, avec quatre utilisateurs. Lecture nécessaire si vous voulez comprendre tous les détails de XMPP.
Comme nous vivons dans un monde cruel (regardez ce qui est arrivé de tragique à Roméo et Juliette), XMPP a besoin d'une section sur la sécurité, la numéro 11. Elle traite des points comme l'importance de ne pas répondre aux demandes de présence si le demandeur n'est pas autorisé (soit explicitement, soit via une politique générale, par exemple l'autorisation de tous pour tous dans une même entreprise).
Qu'est-ce qui a changé depuis le RFC 3921 ? L'annexe E résume les principales différences. La plupart sont très pointues et ne se rencontrent pas tous les jours.
XMPP étant un protocole ancien et éprouvé, il est très largement déployé et on trouve de nombreuses implémentations :
Et enfin, si vous voulez m'écrire, mes adresses XMPP sont
bortzmeyer@dns-oarc.net
pour le travail et
bortzmeyer@gmail.com
(du Google Talk) pour le reste.
Date de publication du RFC : Mars 2011
Auteur(s) du RFC : Peter Saint-Andre (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF xmpp
Première rédaction de cet article le 13 avril 2011
Jabber est le nom original, et XMPP le nom IETF d'un protocole d'échange d'informations encodées en XML, protocole surtout connu pour son utilisation dans la messagerie instantanée. Ce RFC 6120 met à jour la définition originale de XMPP, qui était dans le RFC 3920.
La messagerie instantanée est une application très populaire surtout chez les moins de dix ans. Elle permet d'échanger des messages sans prendre le temps de réfléchir et en général sans craindre qu'ils soient archivés (contrairement au courrier électronique où il faut réfléchir car ce que l'on écrit restera). Elle sert à de nombreux usages, discussions entre geeks, systèmes de surveillance avec notification des problèmes, etc. À l'exception du vénérable protocole IRC (décrit - insuffisamment - dans le RFC 2810 et suivants), les systèmes existants de messagerie instantanée sont tous basés sur des protocoles privés et fermés comme MSN. La normalisation qui fait le succès du courrier électronique n'a pas réussi ici.
D'où le vieux projet (RFC 2779) de développer un protocole moderne et ouvert, adapté à cette application. C'est ce qu'on fait les développeurs du protocole Jabber en 1999, projet adopté ultérieurement par l'IETF, rebaptisé XMPP en 2002 et normalisé désormais dans ce RFC. Notre RFC décrit un protocole généraliste, un RFC compagnon, le RFC 6121, normalise les aspects spécifiques à la messagerie instantanée. Il est donc objectivement incorrect de dire que XMPP est un protocole de messagerie instantanée (c'est en fait un protocole d'échange de données XML en temps réel) mais je suis sûr que mes lecteurs me pardonneront mes abus de langage. Ce RFC 6120 est très long (notons pour la petite histoire que dix RFC sont quand même encore plus longs, le détenteur du record étant le RFC 5661), avec plus de deux cents pages, mais il est surtout composé de longues listes de détails, les principes sont relativement simples. En dépit de la longueur de ce RFC, il ne spécifie pas tout XMPP de nombreuses extensions existent, certaines très populaires (comme la possibilité pour un client de créer un compte sur un serveur directement via XMPP) et elles sont en général décrites, non pas dans un RFC, mais dans les XEP (XMPP Extension Protocols) de la XMPP Standards Foundation.
Quels sont les principes de XMPP (section 1.3) ? Les données sont encodées en
XML (avec
quelques bémols notés en section 11 comme l'interdiction des
commentaires XML, ou des encodages autres qu'UTF-8), dans des
strophes (stanzas) qui sont des petits paquets
d'information. Citons Wikipédia : « Les stances
sont, dans les sujets graves et spirituels, ce que le couplet est dans
les chansons et la strophe dans les odes ». Ces strophes sont transmises sur une connexion TCP
(section 3) entre
client et serveur, ou bien entre serveur et serveur (la section 2.5
contient une très intéressante présentation des concepts « réseau » de
XMPP, notamment pour répondre à la question philosophique « XMPP
est-il pair-à-pair ? »). Les entités qui
communiquent (ce ne sont pas forcément des humains, Jabber ayant été
conçu pour permettre également la communication entre programmes) sont
identifiées par une adresse, qui a une forme syntaxique proche de
celle du courrier électronique. Par exemple, mon adresse XMPP est bortzmeyer@gmail.com
.
XMPP, comme le courrier électronique, fonctionne par le connexion
de serveurs, chacun chargé d'un ou plusieurs domaines. Les clients se
connectent à un serveur (par exemple talk.l.google.com.
pour
Google Talk, par exemple) et s'y authentifient, puis ils
transmettent les messages aux serveurs, qui se chargent de les
acheminer au serveur suivant (section 2.1 du RFC). Les serveurs sont
trouvés en utilisant les enregistrements SRV
(RFC 2782) du
DNS (section 3.2) par exemple, pour un client
de l'OARC :
% dig SRV _xmpp-client._tcp.dns-oarc.net ... ;; ANSWER SECTION: _xmpp-client._tcp.dns-oarc.net. 3223 IN SRV 0 0 5222 jabber.dns-oarc.net. ...
L'usage de SRV fait que le numéro de port utilisé n'est pas toujours le même mais 5222 (pour les communications de client à serveur) et 5269 (pour celles de serveur à serveur) sont les valeurs les plus courantes (section 14.7).
Les adresses (JID pour Jabber Identifier) sont décrites dans un autre document, le RFC 7622. Outre le classique
nom@domaine
, elles peuvent comporter une
ressource, indiquée après la barre oblique (par
exemple bortzmeyer@gmail.com/AFNIC
).
La représentation des données en XML est décrite dans la section
4. Un flux de données, un stream, est un
élément XML <stream>
,
qui comporte une ou plusieurs strophes,
<stanza>
. Il existe de nombreux types de
strophes (section 8) sans compter les messages d'erreur, décrits en 4.9. Voici un
exemple classique d'un échange (C étant le client et S le serveur), avec des strophes de type
message
:
C: <message from='juliet@example.com' to='romeo@example.net' xml:lang='en'> C: <body>Art thou not Romeo, and a Montague?</body> C: </message> S: <message from='romeo@example.net' to='juliet@example.com' xml:lang='en'> S: <body>Neither, fair saint, if either thee dislike.</body> S: </message>
Des exemples plus détaillés figurent en section 9.
Contrairement à beaucoup d'autres protocoles de messagerie instantanée, conçus uniquement pour jouer, XMPP, étant prévu aussi pour le travail, dispose de fonctions de sécurité très riches. La section 5 précise l'utilisation de TLS et la 6 celle de SASL. La section 13 détaille en profondeur tous les problèmes de sécurité de XMPP.
La section 8 détaille les types de strophes disponibles. Trois
types sont définis dans ce RFC, <message>
,
<presence>
et
<iq>
. <message>
,
dont la sémantique est décrite en section 8.2.1, transporte
un... message, tandis que <iq>
(section
8.2.3) est une interrogation (Info / Query). Ces éléments XML ont un certain
nombre d'attributs par exemple l'attribut
to
, sections 4.7.2 et 8.1.1, qui spécifie l'adresse du destinataire
(romeo@example.net
dans la pemière strophe de
l'exemple ci-dessus). La syntaxe complète, exprimée en W3C
Schema, figure dans l'annexe A.
Du fait de l'utilisation de XML, des attributs standard comme
xml:lang
sont possibles (section 8.1.5) et on
peut ainsi marquer un message en tchèque :
<presence from='romeo@example.net/orchard' xml:lang='en'> <show>dnd</show> <status>Wooing Juliet</status> <status xml:lang='cs'>Dvořím se Julii</status> </presence
L'annexe D résume les changements depuis le RFC 3920, qui avait été fait en 2004. Le format des adresses a été sorti pour être dans un document à part, le RFC 7622, le vieux protocole de rappel (dialback) a été retiré des RFC, TLS est devenu obligatoire (section 13.8, il reste à voir si ce sera mis en œuvre : au moment de la sortie de notre RFC, très peu de clients XMPP Android avaient TLS), et le reste est un certain nombre de clarifications et de corrections : il ne s'agit donc pas d'une nouvelle version du protocole, juste d'une évolution inspirée par l'expérience.
XMPP est aujourd'hui mis en œuvre dans de nombreux logiciels. C'est ainsi que le service de messagerie instantanée Google Talk utilise XMPP. Le client XMPP (qui est aussi un client de nombreux autres protocoles) le plus populaire sur Unix est sans doute Pidgin (ex-Gaim). Côté serveurs, le plus pittoresque (et pas le moins utilisé) est sans doute ejabberd, écrit en Erlang. Mais il y en a d'autres comme Movim.
Les développeurs liront avec intérêt le livre Programming Jabber qui explique comment utiliser Jabber/XMPP dans ses propres programmes.
Date de publication du RFC : Février 2011
Auteur(s) du RFC : T. Li (Cisco)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF RoutingResearchGroup
Première rédaction de cet article le 22 février 2011
Le mécanisme de routage dans l'Internet est une invention géniale. Bien qu'ayant été décrié par tous les experts des télécoms, unanimes dans leur appréciation comme quoi cela ne pourrait jamais marcher, ce mécanisme a permis la croissance d'un réseau de quatre machines aux États-Unis à des débuts, vers des centaines de millions aujourd'hui, réparties partout dans le monde. Néanmoins, rien n'est éternel en technologie. Tous les systèmes sont un jour remplacés, ne serait-ce que parce que de nouveaux besoins émergent et que de nouveaux problèmes apparaissent. Le groupe RRG (Routing Research Group) de l'IRTF est donc chargé d'explorer, pour le moyen et long terme, les solutions qui pourraient remplacer le routage actuel, notamment pour améliorer son passage à l'échelle, le cas des réseaux multihomés et la possibilité de faire de l'ingénierie de trafic. Ambitieux défi puisqu'il faut, non seulement concevoir un système meilleur que le système qui a assuré un tel succès, mais aussi le déployer, dans un réseau qui se méfie des nouveautés.
On ne s'étonnera donc pas que le RRG a à moitié échoué. Aucune idée géniale, créant un consensus par sa beauté, n'a émergé. De nombreuses propositions, souvent astucieuses, ont été présentées et discutées mais aucune n'a fait l'objet d'un consensus. Les présidents du groupe ont fini par publier le RFC tel quel, avec les différentes contributions, les points sur lesquels un accord s'est fait, et leur recommandation personnelle, qui est de partir de la proposition ILNP. Celle-ci a été normalisée en novembre 2012 dans les RFC 6740 et suivants.
D'abord, un peu de contexte. Les documents sur lesquels se base le
travail du RRG (Routing Research Group) n'ont pas
tous été publiés en RFC encore. Parmi eux, le RFC 6227, cahier des charges du projet. Les autres sont seulement des Internet-Drafts. Le
principal est l'exposé du problème, draft-narten-radir-problem-statement
. Ces
deux documents ont donné naissance à de nombreuses
propositions. Attention en les lisant : il n'y a pas de censure à
l'IRTF et toutes les propositions sont étudiées
et discutées. Beaucoup provenaient d'une personne isolée et, s'il
existe parfois des génies solitaires et incompris, les propositions
individuelles sont plus souvent l'œuvre de gens assez
déconnectés de la pratique. On trouvera donc de tout dans ce RFC,
hommage à l'ouverture de l'IRTF, plus qu'à sa capacité de
sélection...
Il y avait en effet pas mal de zozos au RRG, des fois même incapables de formater un message électronique correctement (erreurs dans les citations, par exemple). Plusieurs propositions n'ont ainsi pas encore (?) connu le moindre début de mise en œuvre.
À noter également que les bruyants partisans des solutions de type « table rase » comme John Day ou comme le projet Clean Slate n'ont pas participé du tout à cet effort. À leur décharge, il faut dire que la solution devait être déployable incrémentalement, ce qui contredisait leur postulat de départ, qui est d'ignorer l'existant. Mais cette non-participation reflète aussi leur difficulté à travailler sur des questions concrètes. Tant qu'on se contente d'interviews au New York Times, refaire l'Internet en partant de zéro est facile. S'il faut écrire de vraies normes, compréhensibles, et se confronter au jugement de ses pairs, il y a moins d'enthousiasme.
Je ne vais pas détailler chacune des nombreuses propositions, plutôt me servir de chacune pour exposer un défi particulier auquel est confronté l'architecte du futur réseau. Par manque de temps, j'ignorerai même complètement certaines des propositions.
Pour résumer ces documents de base, à quoi servait le groupe RRG (Routing Research Group) ? Il avait été établit pour trouver une nouvelle architecture de routage pour l'Internet, rien que ça. Il s'est réuni à chaque réunion IETF de 2007 à 2010, a beaucoup discuté via sa liste de diffusion, mais, comme indiqué, n'a pas atteint de consensus. Les présidents du groupe, Lixia Zhang et Tony Li, deux experts expérimentés et reconnus, ont donc fini par jeter l'éponge et décider de tout publier, en ajoutant leur recommandation personnelle en faveur d'ILNP. Chaque proposition d'architecture ou de protocole a bénéficié d'un résumé (en général par son auteur, et la plupart de ces résumés sont de lourdes publicités avec peu de détails pratiques), résumé qui inclus obligatoirement les avantages de la proposition, mais aussi de ses coûts (il n'y a pas de déjeûner gratuit...), d'une critique par un autre membre du groupe et, parfois, d'une réponse de l'auteur à cette critique. (En pratique, je trouve que certaines critiques pinaillent sur quelques détails de la proposition, et n'analysent pas assez ses grandes idées et principes.)
Mais tout n'a pas été un flop : s'il n'y a pas eu d'accord sur une proposition concrète, le groupe a quand même mis en évidence plusieurs points importants, qui n'étaient pas évidents au début, mais qui ont rencontré un large accord. Ces points étaient (section 1.2) parfois de simple terminologie, parfois portant sur des concepts plus profonds. Par exemple :
À propos de terminologie, je recommande au lecteur du RFC qui n'aurait pas suivi tous les travaux du RRG de bien lire la section 1.3, qui liste les sigles les plus courants. Tout le reste du RFC en fait une forte consommation et certains ne sont pas forcément familiers à l'ingénieur réseaux (comme ITR, Ingress Tunnel Router, qui désigne le point d'entrée d'un tunnel, pour les solutions à base de tunnel ou EID, Endpoint IDentifier, qui désigne l'identificateur de la machine de destination).
Maintenant, assez de préliminaires, place aux propositions concrètes. La première exposée est LISP, qui n'a rien à voir avec le langage de programmation du même nom et qui occupe la section 2. À noter que les « LISPiens » ont peu participé au RRG, ayant un groupe de travail IETF à eux et leur proposition étant de loin la plus avancée, puisque implémentée et déployée. Par contre, aucun RFC LISP n'a encore été publié.
LISP fait partie des propositions dites CES pour Core-Edge Separation, où une coupure très nette est faite entre le cœur de l'Internet (en gros, le monde de ceux qui ont aujourd'hui un routeur dans la DFZ) et les bords. Si LISP est largement déployé, seul le cœur aura encore des adresses IP globalement uniques et les bords auront des identificateurs uniques, qui ne seront pas des localisateurs. Un mécanisme d'annuaire (mapping) permettra de trouver l'adresse d'un routeur capable d'acheminer les paquets pour un identificateur donné et ce routeur sera le point d'entrée d'un système de tunnels, qui permettra de router ce paquet. Le tunnel n'est pas forcément fourni par le FAI, et on pourrait imaginer un nouveau métier dans l'Internet, celui de fournisseur de tunnels. Comme avec toutes les autres propositions de séparation identificateur-localisateur, les localisateurs, plutôt dépendants du FAI, sont fortement agrégeables, les identificateurs sont stables (on ne les change pas en changeant de FAI, ce que les LISPiens appellent PI for all). LISP ne nécessite aucune modification des machines terminales (c'est une solution purement dans les routeurs et encore, pas dans tous, uniquement les routeurs d'entrée et de sortie de tunnel). Ce type de solution est aussi appelée Map-and-Encap car on cherche d'abord une correspondance entre identificateur et localisateur (Map) puis on encapsule le paquet (Encap) pour la traversée du tunnel.
Notez que cette CES, cette séparation entre cœur et bords changerait le modèle classique de l'Internet, fondé sur le même protocole IP partout, du réseau local de M. Michu à celui du plus gros Tier-1. Cela rappelerait les réseaux des PTT où X.25 ne servait qu'à l'accès, d'autres protocoles (comme X.75) étant utilisés à l'intérieur du réseau de l'opérateur.
Et, comme toutes les solutions fondées sur la séparation entre identificateur et localisateur, LISP nécessite un système de correspondance (mapping) entre les deux, permettant de trouver, lorsqu'on cherche à joindre la machine d'identificateur X, à quel routeur Y il faut envoyer le paquet. Pour des raisons en partie idéologiques, LISP n'a pas considéré le DNS pour cette tâche et a plusieurs systèmes de correspondance possibles, le plus avancé se nommant ALT (pour ALternative Topology). La tâche serait relativement simple si le réseau ne changeait pas mais la réalité étant qu'il y a des pannes, des reconfigurations, etc, une bonne partie de la complexité de LISP et de sa fonction de correspondance va être dans la détection et le traitement des pannes (pas question d'envoyer des paquets à un ITR en panne). Ce problème, là encore, est commun à toutes les propositions de séparation de localisateur et d'identificateur.
C'est donc logiquement sur ces fonctions (correspondance entre identificateur et localisateur, et détection puis contournement de pannes) que se focalisent les critiques. Alors que LISP ne change pas énormément le modèle d'IP, le déploiement d'un tout nouveau système de correspondance, non testé, et qui doit encaisser d'énormes quantités d'information changeant souvent, est vu comme le plus gros risque de LISP. Parmi les problèmes posés : que va t-il advenir du premier paquet, celui pour lequel le routeur ne connait pas encore de localisateur ? Le temps que le système de correspondance l'obtienne (et une requête dans ALT peut avoir un long chemin à parcourir), le paquet va devoir attendre. Les gros routeurs, ne souhaitant pas gérer de longues files d'attente, abandonneront probablement immédiatement de tels paquets, comme ils le font aujourd'hui lorsqu'il n'y a pas d'entrée ARP pour le destinataire. La source finira par réemettre et, cette fois, la table aura été remplie et le second paquet sera acheminé. Certains protocoles pourraient mal supporter cette « perte du premier paquet » (qui n'est pas non plus un problème spécifique à LISP). La réponse des LISPiens est que le problème n'est pas si grave que cela, les caches des routeurs se peupleront vite de l'essentiel des correspondances, ne serait-ce que grâce aux pirates scannant le réseau. Quant à ALT, il n'est qu'une des propositions, LISP offre le choix de plusieurs systèmes de correspondance identificateur -> localisateur comme TREE. Le modèle de LISP ne repose pas sur une fonction de correspondance unique.
Quant à la complexité de détection des pannes, nécessitant des échanges spécifiques entre les ITR et les ETR (les routeurs d'entrée et de sortie des tunnels), elle est vue comme inévitable, et, comme LISP fonctionne déjà sur le terrain, l'argument massue des LISPiens est que « ça marche ».
Le second système présenté, RANGI (Routing Architecture for the Next Generation Internet, présenté par X. Xu), en section 3, est, au contraire de LISP, une solution basée sur les machines terminales et non plus sur les routeurs. Comme HIP, RANGI introduit un identificateur propre à la machine et les connexions TCP sont liées à cet identificateur et plus aux adresses IP. Mais, alors que l'identificateur de HIP est « plat », sans structure, ce qui le rend difficilement résolvable en localisateur (et difficilement filtrable par les pare-feux), celui de RANGI est hiérarchique, pour pouvoir être résolu en localisateur par les méthodes arborescentes qui ont fait leur preuve, par exemple avec le DNS (alors que HIP doit utiliser des techniques moins éprouvées comme les DHT).
Comme HIP, RANGI ne connait que la distinction entre routeurs et machines terminales et n'a pas de distinction entre le cœur du réseau et ses bords. On parle donc de solution CEE (Core-Edge Elimination). Comme toute solution « côté machines terminales », RANGI nécessitera une mise à jour de tous les systèmes d'exploitation. La question de savoir s'il vaut mieux modifier toutes les machines terminales (plus nombreuses, pas forcément gérées, mais moins sensibles et plus souvent changées pour une neuve) ou tous les routeurs (moins nombreux, gérés par des professionnels mais souvent difficiles à remplacer ou à mettre à jour) a été souvent discutée dans le RRG mais sans résultat ferme.
Comme toute solution de séparation de l'identificateur et du localisateur, RANGI nécessitera le déploiement du nouveau système de correspondance entre identificateur et localisateur. Mais, contrairement à LISP, RANGI envisage de réutiliser le DNS.
À noter que le RRG insistait sur la déployabilité incrémentale des solution, nécessaire pour éviter d'arrêter tout l'Internet pendant les années de la transition. RANGI la permet mais les premiers adoptants ne gagnent rien à le faire, ce qui conduit à s'interroger sur la possibilité d'un déploiement effectif. Après tout, HIP, solution élégante et sûre, normalisée depuis longtemps, implémentée pour Linux et FreeBSD, n'a jamais décollé, en partie à cause de ce problème de la « récompense initiale ».
Proposition suivante, en section 4, IVIP (Internet Vastly Improved Plumbing, dû à R. Whittle). Système de séparation cœur-bords, comme LISP, proche de LISP par beaucoup d'aspects, il s'en distingue notamment par le fait que les correspondances entre identificateurs et localisateurs sont poussées, plutôt que tirées, et que donc tous les routeurs d'entrée de tunnel ont un accès rapide à tout moment à une copie complète de la base. Cette mise à jour en temps réel élimine la nécessité pour les ITR (routeurs d'entrée des tunnels) de tester que l'ETR correspondant attend toujours les paquets à la sortie. En contrepartie, elle exige beaucoup de mémoire chez l'ITR, de l'ordre de dizaines de Go (cela semble énorme mais, d'ici à l'adoption massive, le moindre ordinateur de bureau aura autant de RAM que cela).
Cette base des correspondances, disponible en temps réel, malgré le taux de changement qu'imposent, par exemple, les machines et les réseaux mobiles, est évidemment la principale faiblesse d'IVIP. Certes, elle permet d'éliminer complètement plusieurs problèmes sérieux, concernant la mobilité ou la détection des pannes d'un ETR, mais est-elle réaliste ? Il n'y a aucun précédent développé et déployé avec succès... Le DNS ne fonctionne qu'en renonçant à la propagation instantanée des informations. DRTM (Distributed Real Time Mapping, le système de correspondance d'IVIP) fera-t-il mieux ? En tout cas, il est intéressant de voir ce que permet cette approche.
Autre point à noter : les solutions de séparation du cœur et des bords, comme LISP et IVIP, sont parmi les seules à ne pas avoir besoin de noms uniques et donc à pouvoir fonctionner avec les petites adresses IPv4. La plupart des autres solutions dépendent d'IPv6.
Mais IVIP et LISP peuvent fonctionner avec IPv6. Au contraire, hIPv4 est spécifique à IPv4. Il a souvent été dit que la séparation entre identificateur et localisateur était déjà réalisée dans l'Internet, via le NAT, où l'adresse privée est un identificateur et l'adresse publique est un localisateur. C'est bien sûr largement une boutade (par exemple, l'adresse privée n'est pas unique, une machine qui se déplace peut changer d'adresse privée, etc), mais cela peut inspirer des idées qui ont des points communs avec le NAT comme hIPv4 (protocole créé par Patrick Frejborg). L'idée de base est que chaque machine a un identificateur sous forme d'une adresse IPv4 et un localisateur de même syntaxe. Les deux noms seront insérés dans chaque paquet (une petite couche entre la couche 3 et la couche 4), les routeurs de bord du domaine faisant l'échange des noms, pour que les autres routeurs n'aient pas à être modifiés. Du fait que la machine terminale doive insérer ces deux noms (l'identificateur et le localisateur), son système d'exploitation doit être modifié et hIPv4 est donc une des rares solutions qui nécessitent des changements à la fois dans les machines terminales et dans certains routeurs. Autre problème, l'épuisement des adresses IPv4 fait qu'on peut se demander d'où viendront ces adresses... Ce problème, celui de la déployabilité, et la question (qu'on retrouve dans le NAT) des protocoles qui s'échangent directement des adresses IP (comme SIP) fait que hIPv4 fait partie des propositions qui sont explicitement rejetées.
Continuons, puisque l'imagination des participants au RRG est sans limites. La section 6 présente NOL (Name OverLay). Actuellement, dans l'Internet, les noms de domaine, gérés dans le DNS, sont complètement extérieurs à la machine elle-même. C'est au point qu'une machine n'a pas de moyen simple de connaître son propre nom de domaine (si elle en a un !) sans parler de l'idée de l'influencer ou de le changer. L'idée de base de NOL est d'ajouter une couche de gestion des noms de domaine à toutes les machines, et d'utiliser ces noms comme identificateurs. (Voir les Name-Based Sockets, en section 15, une idée qui présente de nombreuses similarités.) Il est difficile de la décrire en détail car, apparemment, aucune spécification écrite n'a été produite. Il n'est pas nécessaire de modifier le système d'exploitation mais il faudra modifier les bibliothèques utilisées habituellement pour la résolution de noms (sur Unix, la libc). NOL n'implique pas de modifier l'application des deux côtés (contrairement à NBS, name-based sockets, présenté plus loin) car des relais spéciaux traduisent les noms et les adresses IP (une sorte de routeur NAT étendu). NOL n'a pas bénéficié de critiques ou de jugements précis, peut-être en raison de son caractère trop exotique.
C'est seulement avec la section 12 qu'apparait
ILNP
(Identifier-Locator Network Protocol, fait par
R. Atkinson & S. Bhatti, site officiel en http://ilnp.cs.st-andrews.ac.uk/
, bons transparents
d'introduction en à
NANOG, RFC 6740 et suivants, l'architecture qui a finalement eu les
faveurs des présidents du groupe. Il repose sur une stricte séparation
de l'identificateur et du localisateur, avec le
DNS pour passer de l'un à l'autre. Pour gérer
les changements de connectivité, ILNP fait donc un usage intensif de
DNSSEC et des
mises à jour dynamiques du DNS (RFC 2136 et RFC 3007). L'auteur semble d'ailleurs prêter trop de
pouvoirs à DNSSEC, par exemple en disant que les requêtes
PTR peuvent également être authentifiées. C'est
vrai qu'on peut signer un enregistrement PTR mais, lorsque le PTR de
2001:db8::dead:beef
pointe vers
www.amazon.com
, il n'y a aucun moyen de s'assurer
qu'il en a le « droit », DNSSEC ou pas.
ILNP atteint plusieurs des
objectifs du RFC 5887 mais pas tous. Ainsi,
certains serveurs (ceux du DNS, par exemple)
doivent toujours être décrits par un localisateur. Dans son état
actuel, ILNP impose l'usage du DNS pour tout (plus de ping
2001:db8:1:3::cafe
), ce qui ne convient pas forcément à
toutes les applications. Il faudra donc sans doute étendre ILNP sur ce
point.
Dernière architecture de routage envisagée dans notre RFC, IRON/RANGER (section 16) où IRON signifie Internet Routing Overlay Network (auteur : F. Templin, décrit dans le RFC 6179) et s'appuie sur l'architecture RANGER (Routing and Addressing in Networks with Global Enterprise Recursion, RFC 5720). RANGER est dérivé de ISATAP (RFC 5214) et fournit un système de tunnels automatiques pour transporter des paquets identifiés par un... identificateur à travers un cœur qui n'utilise que des localisateurs. À son tour, RANGER s'appuie sur le mécanisme SEAL (Subnetwork Encapsulation and Adaptation Layer, RFC 5320, qui gère notamment les questions de MTU, toujours cruciales avec les tunnels. La critique de ce mécanisme note que beaucoup de détails manquent, notamment la fonction de recherche de la correspondance entre un identificateur et un localisateur. Elle remarque aussi que SEAL empêcherait de déployer les jumbogrammes. Dans sa réponse à la critique, l'auteur note que IRON ne repose pas sur un système de mapping classique mais sur une combinaison du protocole de routage et d'un protocole spécifique de distribution des correspondances. Personnellement, cela me semble encore très flou.
Une autre architecture est présentée en section 14, Évolution. Conçue par Lixia Zhang, une vétéran de l'IETF, auteure de plus de trente RFC, Évolution propose une approche du passage à l'échelle du système de routage qui est assez originale. L'idée de base est de faire feu de tout bois, en agrégeant les routes partout où on peut, sans attendre le « Grand Soir » d'une nouvelle architecture. Évolution critique la tendance des autres propositions du RRG à considérer qu'on ne peut rien résoudre tant qu'on n'a pas changé tout le routage. Mais, comme le peu de déploiement de IPv6 l'a montré, les solutions qui aideront tout le monde, une fois que tout le monde les aura déployé, ont le plus grand mal à s'imposer sur l'Internet. Les solutions qui gagnent sont au contraire en général celles qui procurent un bénéfice immédiat et à court terme aux décideurs.
Évolution propose donc de commencer par le routeur seul : tout routeur pourrait déjà agréger massivement les routes qu'il connait, économisant ainsi sa mémoire. Cet effet est d'autant plus marqué que le routeur a peu de liens physiques possibles. Ensuite, au sein cette fois d'un système autonome, on pourrait désigner certains routeurs comme étant les seuls à avoir une connaissance complète des liens externes, la plupart des routeurs de l'AS pouvant alors se contenter de tunnels vers ces « super-routeurs », créant une sorte de schéma Map-and-Encap local. Une fois cette « agrégation virtuelle » réalisée à l'intérieur de plusieurs AS, ceux-ci pourraient annoncer ces super-routeurs via BGP, étendant leur bénéfice aux autres AS. Enfin, une séparation plus intense entre le contrôle des routes (fait par BGP, et qui limite l'agrégation puisqu'il faut pouvoir annoncer les routes aux autres) et la transmission effective des paquets (où le routeur peut se contenter d'une FIB bien plus petite que sa RIB) complèterait le dispositif. Le point important d'Évolution est que chaque étape apporte ses bénéfices, et qu'il n'est donc pas indispensable de faire miroiter des bénéfices lointains aux décideurs pour les convaincre. Chaque étape a sa récompense propre.
Mais Évolution a ses propres problèmes. Certaines des techniques d'agrégation perturbent les systèmes existants (par exemple, l'agrégation de N préfixes en un super-préfixe, qui couvre un espace plus grand que ne le faisaient les N sous-préfixes, crée des adresses routables qui n'existaient pas avant, ce qui peut entraîner de nouvelles boucles de routage, et peut gêner les systèmes de sécurité comme RPF - RFC 3704). D'autre part, l'agrégation virtuelle allonge le chemin pris par les paquets, et peut aussi gêner RPF. À noter qu'Évolution ne fournit pas de solution pour la mobilité, concept à la mode, mais dont il n'est pas évident qu'il doive être géré par le système de routage (plutôt que, par exemple, une combinaison de DHCP et de meilleures applications).
Une autre critique faite à Évolution est plus philosophique : en fournissant des bénéfices à court terme, n'encourage-t-on pas les rustines sur un système déjà pas mal rapiécé, au risque de détourner les gens d'une transition, certes coûteuse mais nécessaire ?
On l'a vu, un problème commun à toutes les propositions de séparation du localisateur et de l'identificateur est le système de correspondance (mapping) entre les deux. Cela a mené certains à concentrer leurs efforts sur ce problème et à travailler sur des systèmes de correspondance génériques, pouvant être utilisés pour plusieurs protocoles. C'est le cas de LMS (Layered Mapping System), en section 8. Comme le ALT de LISP, il repose sur une hiérarchie des noms (système de résolution bien plus éprouvé que les systèmes plats, qu'utilisent par exemple les DHT). Mais, contrairement à ALT, la correspondance entre noms est complètement déconnectée du routage : ce ne sont pas les FAI ou les opérateurs réseau qui font la résolution de noms.
Autre système de correspondance, le 2-phased mapping de la section 9. Ce système vise à trouver l'ETR (le routeur de sortie du tunnel, celui qui est le plus « proche » du réseau visé) correspondant à un préfixe donné, le préfixe contenant l'identificateur de la machine visée. Tout serait simple si cette correspondance préfixe -> ETR était relativement statique. Mais, évidemment, ce n'est pas le cas et 2-phased mapping considère qu'un système qui stockerait toutes les relations préfixe -> ETR de la planète ne tiendrait pas longtemps. Son idée centrale est d'intercaler un numéro de système autonome (AS) entre les deux, de façon à avoir une relation préfixe -> AS -> ETR. Les systèmes autonomes connaissent en effet certainement leurs clients et donc les ETR qui les desservent. Il ne reste donc qu'à créer un système pour que les AS puisse informer le système de résolution des préfixes qu'ils servent. On peut donc envisager de d'abord résoudre le préfixe en un numéro d'AS puis d'interroger ce dernier. Ce système en deux étapes (les résultats de chacune pouvant être mis en cache) passe certainement mieux à l'échelle. À noter que les deux étapes ne sont pas forcées d'utiliser les mêmes techniques (par exemple, la première pourrait être faite avec le DNS, ou bien avec un serveur centralisé, type whois, et la seconde avec une extension à BGP). L'idée n'a toutefois pas été assez développée pour être considérée sérieusement par le RRG.
On l'a vu, toutes les propositions soumises au RRG ne concernaient pas forcément une architecture de routage nouvelle, certaines présentaient une solution auxiliaire, qui allait aider les nouvelles architectures. C'est le cas des Name-based sockets de la section 15. L'idée de base est de ne manipuler, depuis les applications, que des noms et de laisser les couches basses gérer et stocker les adresses. Dans la proposition actuelle, ces name-based sockets permettraient aux applications d'initier et de recevoir des communications uniquement avec les noms. Il ne s'agit pas seulement de cacher les adresses IP dans une bibliothèque utilisée par l'application (comme le font, par exemple, les bibliothèques curl et neon pour les programmeurs C) mais de déplacer leur gestion bien plus bas, dans la pile IP elle-même, permettant ainsi des choses comme le changement d'adresse IP en cours de communication.
En quoi est-ce que cela aiderait le routage ? Eh bien, cela réduirait la nécessité de disposer d'adresses PI et transformerait l'adresse IP est un nom largement invisible, comme l'est l'adresse MAC aujourd'hui. La souplesse que cela apporterait permettrait, par exemple, d'agréger plus radicalement les préfixes. Les NBS (name-based sockets) ont bien d'autres propriétés intéressantes comme de rendre le NAT largement inoffensif (si l'application ne voit jamais d'adresses IP, leur changement par le routeur NAT n'aura pas de conséquence).
Les NBS sont donc une solution situéee dans la machine terminale, sans changement des routeurs. Leur déploiement suppose donc leur adoption par les systèmes d'exploitaion (rappelez-vous qu'il ne s'agit pas d'une simple couche pour aider le programmeur, les NBS doivent interagir fortement avec IP et donc être dans le noyau). NBS est plus longuement documenté dans l'article de Vogt, « Simplifying Internet Applications Development With A Name-Based Sockets Interface ».
Quelles sont les limites des NBS ? D'abord, certaines applications auront toujours besoin d'adresses IP, par exemple celles nécessaires au bootstrapping comme les serveurs DNS. Ensuite, un réseau ne pourra abandonner ses adresses PI que lorsque toutes ses machines auront migré vers NBS.
Où cela nous mène t-il ? Comme indiqué au début, aucune proposition n'a recueilli le consensus du groupe. La section 17 expose donc la seule recommandation des présidents du groupe. Ceux-ci exposent d'abord le contexte, celui d'un Internet faiblement coordonné, sans point de décision central, et où les changements ne peuvent être introduits que de manière incrémentale. Tout changement étant compliqué, il faut choisir avec soin les changements qu'on propose. L'Internet a tenu, et très bien, jusqu'à présent, grâce à un grand nombre de modifications partielles, faites au fur et à mesure que les problèmes se posaient. Mais l'accumumation de ces changements a fini par mener à un réseau excessivement complexe et difficiles à maintenir. Les présidents du RRG proposent donc à la fois des changements à court terme, pour traiter les cas les plus urgents et une « bonne » solution à long terme, dont ils reconnaissent qu'elle n'existe pas encore. La recommandation est donc de travailler sur trois techniques :
draft-zhang-evolution
).Pourquoi ces choix ? L'agrégation de Évolution parce qu'on a besoin de solutions à court terme. ILNP parce que c'est une solution architecturalement propre, qui sépare nettement identificateur et localisateur, et qui ne dépend pas de tunnels. Et la rénumérotation facilitée parce que, quelle que soit la solution finale choisie, on ne pourra pas éviter des rénumérotations de temps en temps.
Date de publication du RFC : Février 2011
Auteur(s) du RFC :
C. Chung (Comcast), A. Kasyanov (Comcast), J. Livingood (tComcast), N. Mody (Comcast), B. Van Lieu
Intérêt historique uniquement
Première rédaction de cet article le 24 février 2011
Soit un FAI avec beaucoup de clients résidentiels. La plupart utilisent une machine sous Windows. Beaucoup de ces machines sont infectées par un des innombrables virus ou vers qui existent pour cette plate-forme. Devenues des zombies, ces machines participent désormais à diverses opérations illégales comme les dDoS ou l'envoi de spam. Si le FAI détecte, par le comportement de ces machines, ou par des rapports qui lui sont envoyés, qu'un de ses clients a été zombifié, comment le prévenir ? Vues les marges financières existantes dans cette industrie, pas question d'envoyer un technicien compétent chez le client pour lui expliquer. Il n'est même pas possible de l'appeler et de passer une heure à répondre à ses questions idiotes, cela mangerait tout le profit retiré de l'abonnement de ce client. Ce RFC décrit le système qu'utilisait Comcast pour prévenir ses abonnés.
Il existe bien sûr d'autres méthodes, comme de couper purement et simplement la connexion Internet dudit client. Cette méthode est régulièrement réclamée par certains éradicateurs. Outre qu'elle n'est pas dans l'intérêt financier du FAI (le client arrêterait de payer s'il était coupé), elle n'est pas envisageable dans un État de droit (en France, le Conseil Constitutionnel avait cassé une version de la loi Hadopi car elle prévoyait une coupure de l'accès Internet sans jugement). Même dans un pays de cow-boys, cette mesure est largement jugée comme trop radicale (voir la description de la section 12, plus loin). En outre, l'utilisateur risque de ne pas la comprendre, de croire à une panne et d'embêter le support utilisateur. Comcast a donc choisi une autre approche, celle de la notification à l'utilisateur, dont on espère qu'il réagira et prendra des mesures pour éliminer le malware de sa machine.
Concevoir un tel système de notification n'est pas évident. Il n'existe (heureusement) pas de moyen technique standard permettant à un tiers, le FAI, de faire soudain apparaître des messages sur l'écran de l'utilisateur (un tel mécanisme serait vite détourné par des plaisantins). Envoyer un courrier est simple et automatisable mais rien ne garantit que l'utilisateur les lit (la plupart ne le liraient pas ou bien, peut-être à raison, considéreraient-ils qu'il s'agit de hameçonnage).
L'approche de Comcast est donc de profiter du fait que la plupart
des utilisateurs passent beaucoup de temps à regarder des pages
Web. Il « suffit » de détourner les pages HTML,
d'y insérer le message et bingo ! Le message apparaîtra à l'écran. Voici une copie d'écran de http://www.example.com/
,
avec l'exemple de modification que donne le RFC en section 8. Cette
modification consiste simplement en l'ajout d'un peu de
JavaScript:
(On note que la possibilité d'accuser réception, mentionnée plus loin
dans le RFC, est absente de cet exemple. Notez aussi le commentaire
dans le code CSS qui insiste sur l'importance
de ne pas hériter des styles qui seraient déjà présents dans la page.)
Bref, ce mécanisme est une attaque de l'homme du milieu, réalisée pour la bonne cause. Les auteurs insistent beaucoup sur le fait que leur solution repose sur des normes ouvertes et n'utilise pas de DPI mais cela me semble tout à fait secondaire. Le point important est que le FAI joue un rôle plus actif dans la chasse aux zombies et, pour cela, s'insère dans les communications de son client. Ce n'est pas forcément une mauvaise idée mais c'est une modification sérieuse du modèle traditionnel (où le client était seul maître à bord, même si, la plupart du temps, il ne se rendait pas du tout compte de la responsabilité qu'il avait.) Pour l'instant, il n'existe pas de travail organisé à l'IETF sur ce problème des machines zombies et chacun en est donc conduit à expérimenter seul (cf. section 13 du RFC).
Les détails pratiques suivent. La solution décrite très en profondeur est spécifique à DOCSIS mais pourrait être adaptée assez facilement à d'autres types d'accès. Les techniques utilisées sont le protocole ICAP (RFC 3507) et HTTP, les logiciels étant Squid et Tomcat.
Voyons d'abord le cahier des charges exact. Il figure en section 3. Je ne vais pas répéter tous ses points ici, seulement les plus importants. D'abord, les principes généraux :
Ensuite, ceux liés au relais HTTP :
Il y a aussi quelques exigences techniques pour le serveur ICAP (un protocole, normalisé dans le RFC 3507, permettant à un serveur ou relais de demander au serveur ICAP des changements à apporter au contenu qu'ils servent) et pour l'arrière-plan du système (la partie qui va noter les comportements bizarres des machines, ainsi que les actions de réparation des utilisateurs).
Armée de ces bons principes, les sections 4, 5, 6 et 7 présentent le système effectivement déployé. Le relais Squid... relaie les requêtes HTTP et, lorsqu'il reçoit une réponse, demande au serveur ICAP si et comment la modifier. Le serveur ICAP utilise GreasySpoon. Si la notification est nécessaire, il répond avec un bout de code Javascript à insérer dans les pages. Un serveur Tomcat garde les messages à envoyer aux utilisateurs (il peut y avoir plusieurs types de messages). Un équipement de load-balancing est utilisé pour séparer le trafic HTTP du reste (même s'il tourne sur le port 80) et pour n'aiguiller vers le relais Squid que les clients listés comme suspects. Le dessin n° 1 montre tous ces composants et leur interaction. Le dessin n° 2, plus concret, illustre les connexions réseau entre ces composants. À noter qu'il ne semble pas y avoir de protection contre un malware qui supprimerait la notification (après tout, il contrôle la machine de l'utilisateur).
Voici pour le fonctionnement technique. Maintenant, quelques considérations de sécurité, en section 10. D'abord, la rédaction du message de notification doit être très soignée, notamment pour éviter que l'utilisateur ne la considère comme du hameçonnage. Le message ne doit pas mener à une page où l'utilisateur est invité à taper son mot de passe. Il doit fournir un moyen d'obtenir plus de détails, par exemple un numéro de téléphone ou tout autre mécanisme de validation indépendante.
Un tel système de modification des pages Web vues, à des fins de notification, est-il Bon ou Méchant ? La section 11 discute cette question philosophique. Certains peuvent penser que le changement, par un intermédiaire technique, le FAI, est un franchissement de la ligne rouge. Selon ce point de vue, les intermédiaires ne devraient jamais tripoter le contenu des communications. Le RFC ne répond pas réellement à ces objections (à part en affirmant que Comcast a de « good motivations » et par l'argument traditionnel de chantage que, si on refuse ce mécanisme, on aura pire, par exemple à base de DPI) mais note que, au minimum, l'existence de ce système doit être annoncée aux clients (actuellement, la plupart des FAI gardent un silence complet, vis-à-vis de leurs propres clients, sur les éventuelles opérations de « gestion du réseau » qu'ils effectuent).
Et, compte-tenu des objections que peut soulever ce système, fallait-il publier ce RFC ? C'est un débat traditionnel à l'IETF : lorsqu'une idée ne fait pas l'objet d'un consensus, mais est largement déployée sur l'Internet, faut-il la documenter dans un RFC (évidemment sans que celui-ci ait le statut de norme, cf. RFC 1796 et RFC 2026), au risque que des gens croient que l'idée bénéficie d'un soutien de l'IETF, ou bien l'ignorer, au risque que les RFC ne reflètent plus la réalité de l'Internet ? La section 11 répond également à ce débat de fond en considérant qu'il vaut mieux publier, ne serait-ce que pour aider aux futurs débats.
Le problème de ces notifications est d'autant plus complexe que le FAI n'est pas tout seul face aux décisions à prendre : de nombreux organismes, au gouvernement ou ailleurs, font lourdement pression sur les FAI pour que ceux-ci fassent quelque chose contre les machines zombies. Est cité Howard Schmidt, conseiller d'Obama pour la cybersécurité, qui dit « As attacks on home-based and unsecured networks become as prevalent as those against large organizations, the need for ISPs to do everything they can to make security easier for their subscribers is critical for the preservation of our nation's information backbone. » Le RFC dit clairement qu'un des buts de cette technique de notification est de satisfaire de telles demandes.
Mais, pour atteindre ce but, y a-t-il d'autres méthodes ? La section 12 présente une alternative possible, le jardin fermé. Dans un tel système, les clients détectés comme zombifiés sont limités à l'accès à un petit nombre de sites Web, par exemple ceux de sites liés la sécurité, ou à la mise à jour de leur système d'exploitation. De facto, cela notifie l'utilisateur qu'il y a un problème. On peut aussi rediriger toutes les autres connexions HTTP vers un serveur présentant un message d'alerte. Mais c'est beaucoup plus violent, en coupant l'accès à des services que l'utilisateur peut considérer comme essentiels, comme une conversation téléphonique qui serait alors brutalement interrompue. La responsabilité du FAI serait alors clairement engagée. Le RFC rappelle à juste titre qu'il n'y a pas que le Web ! Et rejette donc l'idée du jardin fermé.
Ah, et mon opinion personnelle ? Je pense que cette méthode est un compromis acceptable. Sur le principe, c'est une attaque de l'intermédiaire et une violation de la neutralité du réseau mais l'ampleur du problème des machines Windows infectées, qui attaquent ensuite les autres, est tel qu'il peut être justifié de prendre des mesures un peu dures. Après, tout dépendra des détails concrets de réalisation (taux de fausses alertes, par exemple).
Un article avait été fait à l'occasion des premiers tests, « Comcast to send infected-PC alerts ».
Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : J. Jeong (Brocade/ETRI), S. Park (Samsung), L. Belœil (France Telecom R&D), S. Madanapalli (Ordyn)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 30 novembre 2010
Dernière mise à jour le 22 décembre 2010
Il existe deux méthodes pour configurer une machine IPv6 automatiquement, DHCP (RFC 8415) et RA (Router Advertisement, RFC 4862). Pendant longtemps, l'avantage de la première était de pouvoir indiquer d'autres informations que l'adresse IP, comme par exemple les adresses des serveurs DNS. Le RFC 5006 avait apporté cette possibilité à la configuration par RA. Mais son statut n'était qu'expérimental. Désormais, voici la même option mais sous la forme d'une vraie norme. (Ce RFC a depuis été à son tour remplacé par le RFC 8106.)
Si on gère un gros réseau, avec de nombreuses machines dont
certaines, portables, vont et viennent, s'assurer que toutes ces
machines ont les adresses IP
des serveurs de noms à utiliser n'est pas trivial (section 1 du RFC). On ne peut évidemment pas utiliser le DNS, cela serait tenter de voler en tirant
sur les lacets de ses chaussures. Et configurer à la main les adresses
sur chaque machine (par exemple, sur Unix, en
les écrivant dans le fichier /etc/hosts
)
est bien trop difficile à maintenir. Se passer du DNS est hors de
question. Pour les machines bi-protocoles (IPv4
et IPv6), une solution possible était
d'utiliser un serveur de noms en v4. Mais pour une solution purement v6 ?
La solution la plus populaire actuellement est DHCP (RFC 8415 et RFC 3646). Son principal inconvénient est qu'elle est à état : le serveur DHCP doit se souvenir des baux qu'il a attribué. Sur un gros réseau local, le nombre de requêtes à traiter, chacune nécessitant une écriture dans une base de données, peut devenir très lourd.
Une autre solution est sans état et repose sur
une nouveauté d'IPv6, les RA (Router
Advertisements, cette méthode est aussi appelée ND, pour
Neighbor Discovery, les RA en étant un cas particulier), décrits dans le RFC 4862. Ce sont des messages envoyés à intervalles
réguliers par les routeurs et
qui informent les machines non-routeuses des caractéristiques
essentielles du réseau, comme le préfixe utilisé (par exemple
2001:DB8:BEEF:42::/64
). Le routeur diffuse ses
messages et n'a pas besoin d'écrire quoi que ce soit sur son disque,
ni de faire des traitements compliqués lors d'une sollicitation, il
répond toujours par le même message RA.
Ces RA peuvent diffuser diverses informations, par le biais d'un système d'options. Le principe de notre RFC est donc d'utiliser ces RA pour transporter l'information sur les serveurs de noms récursifs utilisables sur le réseau local, via des nouvelles options notamment celle nommée RDNSS (le numéro 25 lui a été affecté par l'IANA).
La section 1.1 du RFC rappelle qu'il existe plusieurs choix, notre RFC 6106 n'étant qu'une possibilité parmi d'autres. Le RFC 4339 contient une discussion plus détaillée de ce problème du choix d'une méthode de configuration des serveurs de noms (notons qu'il existe d'autres méthodes comme l'anycast avec une adresse « bien connue »). La section 1.2 décrit ce qui se passe lorsque plusieurs méthodes (par exemple DHCP et RA) sont utilisées en même temps.
La méthode RA décrite dans notre RFC repose sur deux nouvelles options, RDNSS, déjà citée, et DNSSL, qui n'existait pas dans le RFC précédent (section 4). La première permet de publier les adresses des serveurs de noms, la seconde une liste de domaine à utiliser pour compléter les noms courts (formés d'un seul composant).
La première option, RDNSS, de numéro 25, est décrite en section 5.1. Elle indique une liste d'adresse IPv6 que le client RA mettra dans sa liste locale de serveurs de noms interrogeables.
La seconde option, DNSSL, de numéro 31, est en section 5.2 (les
deux options sont enregistrées dans le registre
IANA, cf. section 8). Elle
publie une liste de domaines, typiquement ceux qui, sur une machine
Unix, se retrouveront dans l'option
search
de /etc/resolv.conf
.
Sur Linux, le démon rdnssd permet de recevoir ces RA et de modifier la configuration DNS. Pour FreeBSD, on peut consulter une discussion sur leur liste. Les CPE de Free, les Freebox, émettent de telles options dans leurs RA (apparemment, à la date de publication de notre RFC 6106, uniquement des RDNSS). Voici ce qu'affiche Wireshark :
... Ethernet II, Src: FreeboxS_c3:83:23 (00:07:cb:c3:83:23), Dst: IPv6mcast_00:00:00:01 (33:33:00:00:00:01) ... Internet Control Message Protocol v6 Type: 134 (Router advertisement) ... ICMPv6 Option (Recursive DNS Server) Type: Recursive DNS Server (25) Length: 40 Reserved Lifetime: 600 Recursive DNS Servers: 2a01:e00::2 (2a01:e00::2) Recursive DNS Servers: 2a01:e00::1 (2a01:e00::1)
et les serveurs DNS annoncés répondent correctement. (Vous pouvez récupérer le paquet entier sur pcapr.net.)
Autre mises en œuvre de ces options, dans radvd, qui a déjà l'option RDNSS et bientôt (en décembre 2010) la nouvelle DNSSL (ainsi que pour les logiciels auxiliaires). Quant à Wireshark, le code a déjà été écrit mais n'est pas encore intégré.
La section 6 de notre RFC donne des conseils aux programmeurs qui voudraient mettre en œuvre ce document. Par exemple, sur un système d'exploitation où le client RA tourne dans le noyau (pour configurer les adresses IP) et où la configuration DNS est dans l'espace utilisateur, il faut prévoir un mécanisme de communication, par exemple un démon qui interroge le noyau régulièrement pour savoir s'il doit mettre à jour la configuration DNS.
RA pose divers problèmes de sécurité, tout comme DHCP, d'ailleurs. Le problème de ces techniques est qu'elles sont conçues pour faciliter la vue de l'utilisateur et de l'administrateur réseau et que « faciliter la vie » implique en général de ne pas avoir de fonctions de sécurité difficiles à configurer. La section 7 traite de ce problème, par exemple du risque de se retrouver avec l'adresse d'un serveur DNS méchant qui vous redirigerait n'importe Dieu sait où (les RA ne sont pas authentifiés). Ce risque n'a rien de spécifique aux options DNS, toute la technique RA est vulnérable (par exemple, avec un faux Neighbor Advertisement). Donc, notre RFC n'apporte pas de risque nouveau. Si on considère cette faiblesse de sécurité comme insupportable, la section 7.2 recommande d'utiliser SEND (RFC 3971).
À noter que l'annexe A résume les changements depuis le RFC 5006. Passage sur le chemin des normes, ajout de la nouvelle option DNSSL (DNS Search List) plus diverses précisions sur le protocole. Depuis, le RFC 8106 a été publié et c'est lui qui est désormais la norme pour cette option.
Merci à Alexis La Goutte pour ses informations.
Date de publication du RFC : Février 2011
Auteur(s) du RFC : E. Levy-Abegnoli, G. Van de Velde, C. Popoviciu (Cisco Systems), J. Mohacsi (NIIF/Hungarnet)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 24 février 2011
Comme le décrit très bien le RFC 6104, la situation de la sécurité des RA (Router Advertisement, cf. RFC 4861) n'est pas satisfaisante. Les « faux RA », envoyés par un méchant ou par un maladroit, sont trop fréquents. Notre RFC 6105 propose donc une solution. Elle est bien plus légère que SEND et repose sur un filtrage au niveau deux.
Je vous renvoie à mon article sur le RFC 6104 pour davantage de détails sur le problème. Ici, je ne vais parler que de la solution. Elle fonctionne pour un réseau partagé où les participants doivent passer par un commutateur (on ne peut donc pas l'utiliser pour du WiFi ad hoc, cf. section 5) et elle nécessite que ledit commutateur mette en œuvre le système décrit dans ce RFC (cf. section 2 et sa figure 1).
Officiellement, SEND (RFC 3971), reste la solution de choix. Après l'obligatoire rappel que SEND résoudrait tous les problèmes, notre RFC rappelle qu'il n'est pas réaliste d'espérer un déploiement massif de SEND dans les années à venir. Pire, le RFC reconnait que certains équipements (on pense au célèbre grille-pain IPv6) n'auront jamais SEND. La solution proposé, RA Guard, est donc un système de filtrage des RA par le commutateur, suivant plusieurs méthodes possibles. Le commutateur sert donc de centre de contrôle, autorisant ou bloquant les RA selon plusieurs possibilités.
Quelles sont ces possibilités ? Les sections suivantes les décrivent. D'abord, le RA guard sans état (section 3). Dans ce mode, le commutateur examine les RA entrants et les bloque ou pas en ne tenant compte que du contenu du RA et de sa propre configuration. Il n'a donc pas de mémoire, pas d'état. Sur quelle base décider ? L'adresse MAC source du RA, le port sur lequel le RA a été reçu, l'adresse IP source, le ou les préfixes annoncés dans le RA… Le commutateur a pu être configuré pour autoriser ou interdire sur la base de ces informations. Une fois le RA considéré comme légitime, il est transmis sur toutes les interfaces, comme n'importe quel paquet. Le RFC présente par exemple une solution ultra-simple où l'administrateur du commutateur indique juste un port comme étant celui du routeur officiel, et les RA arrivant sur les autres ports seront donc simplement ignorés. Cette méthode a l'inconvénient de nécessiter une configuration manuelle.
Plus sophistiquée, le RA guard avec état (section 4). Le principe est d'apprendre automatiquement à quoi ressemblent les RA légitimes, avant de se mettre à bloquer les autres. Dans sa version la plus simple, le commutateur écoute pendant un moment (défini par l'administrateur), notant qui envoie les RA, puis considère que, après ce laps de temps, tout autre RA est illégitime. Cela protège donc contre les RA anormaux survenant après cette période d'apprentissage. Si un nouveau routeur légitime arrive, on recommence l'apprentissage de zéro.
La section 4.1 décrit les détails. Au début, le commutateur est dans l'état
LEARNING
où il écoute les RA. Fait-il suivre tous
les RA pendant cette phase, ou bien les bloque-t-il tous ? C'est
configurable selon le degré de paranoïa de l'administrateur. Une fois
cette phase terminée, les interfaces passent dans l'état
BLOCKING
ou FORWARDING
selon
qu'elles recevaient des RA acceptables ou non. (Le
RFC ne mentionne donc que la possibilité d'apprendre les interfaces où
se trouve un routeur légitime, pas celles d'apprendre son adresse
MAC.) La section 7 suggère fortement que l'administrateur jette un
coup d'œil à la liste des interfaces à RA légitimes, pour
vérifier… Par contre, elle ne rappelle pas que le mécanisme est mis
en danger si un routeur illégitime est présent dès la phase
d'apprentissage. Normalement, ce cas est traité par le fait que cette
technique est combinée avec des filtres manuels comme ceux de la
section précédente.
Encore plus ambitieux, la possibilité pour le commutateur d'être un mandataire SEND (section 4.2). L'un des problèmes de SEND est que chaque machine du réseau, grille-pain et frigidaire inclus, doit faire de la cryptographie (parfois compliquée, par exemple s'il faut récupérer des certificats intermédiaires) et être configurée avec un certificat. Avec le mandataire SEND, seul le commutateur va valider les annonces signées par SEND. Il les fera suivre ou les bloquera en fonction du résultat de la validation.
Je ne connais pas de liste d'implémentations officielles de ce service. Apparemment, certains le déploieraient déjà, si on en croit des témoignages. Fin 2011, Juniper annonçait RA Guard pour les versions 12.x, Cisco a déjà cette fonction dans des engins comme le Cisco 3750g avec « advanced enterprise featureset » (voir un bon article sur le sujet et un plus détaillé, du même auteur). Brocade n'a rien communiqué. Une technique permettant de contourner le RA guard a déjà été décrite.
Date de publication du RFC : Février 2011
Auteur(s) du RFC : T. Chown (University of Southampton), S. Venaas (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 24 février 2011
Il y a une tension permanente en sécurité des réseaux, entre la sécurité et la facilité d'usage (quelqu'un a une meilleure traduction pour convenience ? « ergonomie » ?). Ainsi, le protocole IPv6 permet l'autoconfiguration sans état des machines, par le biais d'annonces, les RA (Router Advertisement) diffusées par les routeurs. C'est très pratique et IPv4 n'a rien de tel. Mais qui dit que la machine qui diffuse est un vrai routeur légitime ? Rien. Les « RAcailles » (mauvaise traduction de rogue RA), ces annonces envoyées à tort, sont très fréquents dans la réalité. Avant que des solutions soient proposées et discutées, ce court RFC spécifie précisément le problème.
Le mécanisme des RA (Router Advertisement) est décrit dans le RFC 4861. Le principe est que le ou les routeurs officiels du réseau local diffusent des informations telles que le préfixe à utiliser sur ce lien (ce qui permet l'autoconfiguration du RFC 4862) ou l'adresse IP du routeur à utiliser par défaut. Les « RAcailles » sont des annonces RA envoyées par un engin qui n'est pas routeur officiel. Cela peut être dû à une attaque délibérée, ou tout simplement à une erreur de configuration, par exemple une machine configurée pour monter un hotspot WiFi avec réseau ad hoc et qui diffuse donc des RA, se croyant le routeur officiel. Ce phénomène est fréquent sur les réseaux sans-fil partagés (on le voit à chaque réunion IETF, dont les participants sont pourtant censés être des experts, et il faut des annonces répétées au micro pour que les machines émettant des RAcailles se taisent ; un exemple à la réunion d'Hiroshima est décrit dans ce message). Mais on le voit aussi dans des réseaux filaires, par exemple les résidences d'étudiants.
Sur un réseau sans-fil partagé, il n'y a guère de moyen de repérer le coupable, dont on ne connait que l'adresse MAC. Encore aujourd'hui, la solution la plus courante (décrite en section 3.7) est de filtrer les RA, sur la base de l'adresse attendue (liste blanche), ou sur celle des adresses repérées comme erronées (liste noire). Mais cela diminue évidemment sérieusement l'intérêt de l'autoconfiguration (toujours cette tension entre sécurité et facilité d'usage). Sur Linux, cela serait quelque chose comme :
% ip6tables -A INPUT -m mac --mac-source 00:1b:77:bc:a4:e6 -j DROP
(Exercice pour le lecteur : cette commande bloque absolument
tout le trafic en provenance de
00:1b:77:bc:a4:e6
. Comment ne bloquer que les
RA ? Benjamin Bachelart
suggère ip6tables -A INPUT -m mac --mac-source
00:1b:77:bc:a4:e6 -p icmpv6 --icmpv6-type router-advertisement -j
DROP
qui semble correct mais je ne l'ai pas testé.)
Quel problème posent ces RAcailles ? La section 1 les résume : si les machines présentes les croient, et utilisent les informations qu'ils contiennent, elles peuvent se trouver partiellement ou totalement coupées du réseau. Par exemple, si elles changent l'adresse IP du routeur par défaut, pour celle indiquée dans le RAcaille, tous les paquets qui ne sont pas envoyés au réseau local sont transmis à un routeur voyou, qui peut les transmettre... ou pas.
Un point important de ce RFC est qu'il se focalise surtout sur les RAcailles accidentels, ceux provoqués par une erreur de configuration, qui sont de loin les plus fréquents aujourd'hui (les méchants sont plus habiles mais les maladroits sont beaucoup plus nombreux...). En outre, si les RAcailles sont émis par un attaquant conscient de ce qu'il fait, protéger contre eux serait très insuffisant : s'il peut émettre des faux RA, il peut aussi bien interférer avec le protocole ND.
Donc, première question (section 2), quel phénomène peut mener à l'envoi de RAcailles par une machine ? Il y en a trois :
Et quelles sont les solutions possibles ? La plupart seront
détaillées dans d'autres RFC comme le RFC 6105 mais la section 3 du nôtre
donne quelques pistes. La plus évidente est de laisser tomber
l'autoconfiguration et de revenir aux solutions à configuration
manuelle. Sûr mais pas forcément enthousiasmant pour l'administrateur
du réseau. D'autant plus que cela n'éliminera pas les
erreurs... Pour être cohérente, une telle solution implique, outre la
configuration manuelle de l'adresse IP et du routeur, d'ignorer les
éventuels RA (avec Linux, il faut mettre la
variable sysctl net.ipv6.conf.all.accept_ra
à 0).
Autre solution, profiter de ce que les RA soient diffusés à tous pour les observer et détecter ainsi rapidement les RAcailles. C'est ce que fait NDPMon, par exemple. Fait dans le commutateur, comme le propose le RFC 6105, cela pourrait permettre le blocage des RAcailles en temps réel. Le filtrage par les commutateurs peut aussi être configuré manuellement, par le biais d'ACL. Après tout, l'administrateur réseaux sait sur quel(s) port(s) du commutateur se trouvent les routeurs légitimes et il peut donc bloquer les RA sur les autres (quelqu'un a des exemples concrets avec des commutateurs réels ? Je n'ai jamais essayé.) Notez que cela marche seulement si toutes les communications passent par le commutateur, ce qui est typiquement le cas aujourd'hui des réseaux filaires. Avec un réseau sans-fil ad hoc, il faudra trouver autre chose.
De plus haute technologie, il y a aussi l'inévitable solution utilisant la cryptographie, SEND (RFC 3971), où les annonces des routeurs légitimes sont signées. SEND est très peu déployé en pratique, sans doute en raison de sa complexité, et du fait qu'il faille configurer chaque machine avec le certificat de la CA. Du point de vue sécurité, SEND est la solution idéale (cf. section 6), mais il est probablement peu adapté aux environnements assez ouverts, comme un campus ou bien un café avec WiFi, où chacun administre sa machine. Le principal avantage de SEND est qu'il fonctionne aussi en cas d'attaque délibérée et intelligente et il convient donc bien aux environnements qui exigent un haut niveau de sécurité.
D'autres solutions techniques ? Mais oui, l'imagination des experts étant inépuisable. Par exemple, puisque le RFC 4191 ajoute une option Préférence aux RA, pourquoi ne pas mettre cette option à la valeur maximale pour les routeurs légitimes, en espérant que les accidentels la laissent à une valeur plus faible ? Mais le RFC n'indique pas si cette option est souvent reconnue par les clients. Autre idée, se servir des protections de la couche 2 (par exemple 802.1X) pour limiter l'accès au réseau. Le problème est qu'authentification n'est pas autorisation. Une machine peut avoir légitimement un accès, sans être pour autant autorisée à envoyer des RA. Il reste le filtrage au niveau de la machine, déjà mentionné. Son principal inconvénient est qu'il faut manuellement maintenir à jour les ACL, ce qui supprime une bonne partie de l'intérêt de l'autoconfiguration.
Et la contre-attaque ? Si une machine envoie des RAcailles sans y
être autorisée, on n'a pas de raison d'avoir des scrupules à la faire
taire. Une autre solution aux RA non autorisés est donc de surveiller
le trafic (comme avec NDPMon) et de générer des faux RA, ayant la même adresse source que
les RAcailles, avec une durée de vie de zéro. Cet empoisonnement
devrait donc masquer le RAcaille par le RA à durée de vie nulle (et
qui ne sera donc pas utilisé par les machines). Cette technique est
mise en œuvre dans la suite logicielle
KAME et a déjà été déployée lors de réunions
IETF. On peut télécharger le source en http://ramond.sourceforge.net
. À noter qu'un tel outil
pourrait aussi parfaitement être utilisé pour lancer une belle
attaque par déni de service (cf. section 7).
Enfin, dernière solution proposée par notre RFC, configurer les machines pour n'utiliser que DHCPv6 et renoncer à l'autoconfiguration sans état. DHCP peut allouer les adresses. Une nouvelle option, en cours de normpalisation, lui permettra d'indiquer également le routeur à utiliser. DHCP présente de nombreux avantages pour l'administrateur réseaux, notamment d'un meilleur contrôle de la configuration des machines. Mais on n'a fait que déplacer le problème. Comme le montre l'expérience d'IPv4, les serveurs DHCP non autorisés sont un problème, autant que les RA non autorisés... Le seul avantage serait que le problème est mieux connu avec DHCP (voir aussi la section 5.2).
Les différentes solutions, avec leur domaine d'application, sont résumées dans un tableau en section 4. La section 5 discute ensuite d'autres problèmes liés à celui des RAcailles. Par exemple, un RA n'est pas forcément envoyé par diffusion, il peut être transmis directement à une machine et, dans ce cas, a des chances de ne pas être détecté par d'éventuels outils de surveillance. Les RAcailles accidentels seront sans doute en multicast mais un attaquant, lui, choisira peut-être donc l'unicast.
La section 5.2 compare les menaces de RA par rapport à celles de DHCP. De même que les RA peuvent être protégés avec SEND, DHCP peut être protégé par des options d'authentification (RFC 3315, section 21). Mais ne nous voilons pas la face : personne n'utilise ces options de sécurité (elles ont même été larguées par le RFC 8415). Elles sont bien trop contraignantes, alors qu'on choisit justement RA ou DHCP pour se simplifier la vie.
L'importance d'une surveillance du réseau, avec un logiciel comme NDPMon, est rappelée dans la section 5.4. Si cette recommandation est appliquée, l'administrateur réseaux saura au moins ce qui se passe. Actuellement, il est probable que la plupart de ces administrateurs ne savent même pas si le problème existe dans leur réseau.
Toujours dans la série « guérir si on n'a pas pu prévenir », la section 5.5 est consacrée aux conséquences. Si les RAcailles existent et que certaines machines en ont tenu compte, que faire ? Le comportement de la machine touchée est très imprévisible (plusieurs adresses, plusieurs routes par défaut, et, avec SHIM6, la machine peut même croire qu'elle est réellement connectée à plusieurs réseaux). Aujourd'hui, il n'y a pas de moyen simple, une fois les RAcailles supprimés, de ramener ces machines à la normale, on risque d'attendre jusqu'à deux heures (RFC 4862, section 5.5.3) avant que la machine n'oublie le RAcaille.
Quelques documents à lire sur ce sujet et des logiciels à essayer :
Date de publication du RFC : Février 2011
Auteur(s) du RFC : M. Bhatia (Alcatel-Lucent), V. Manral (IP Infusion)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 3 février 2011
Plusieurs protocoles de routage utilisent de la cryptographie pour l'authentification. C'est le cas par exemple d'OSPFv2 (RFC 2328), IS-IS (RFC 1195) et RIP (RFC 2453). Limitée au début à MD5, la liste des algorithmes utilisées croît petit à petit mais dans le désordre. L'idée de ce RFC est de spécifier le minimum d'algorithmes qu'un routeur sérieux doit gérer, de manière à garantir l'interopérabilité. Il faut être sûr que tous les routeurs aient au moins un algorithme en commun.
La section 1 détaille le problème. Lorsque qu'un protocole de routage (prenons comme exemple OSPFv2, RFC 2328, annexe D) permet d'authentifier ses pairs, il peut le faire par un mot de passe passé en clair, ou bien par un condensat cryptographique du mot de passe et d'autres informations. (D'autres protocoles sous-traitent l'authentification à une couche inférieure, comme OSPFv3 - RFC 5340 - qui la délègue à IPsec mais ils sont hors-sujet pour ce RFC. Depuis le RFC 6506, OSPFv3 a de toute façon une authentification à lui.) Le mot de passe en clair offre peu de sécurité puisque n'importe quel sniffer peut le capter. Ce mot de passe n'est vraiment efficace que contre les accidents, pas contre les attaques délibérées. La protection par condensat cryptographique n'a pas cet inconvénient. Elle fonctionne en résumant un message composé d'un secret partagé (le mot de passe) et d'autres informations connues des routeurs. Ainsi, le mot de passe ne circule jamais en clair.
Traditionnellement, la fonction de hachage utilisée était MD5 (RFC 1321) mais des attaques cryptographiques réussies contre MD5 mènent à son abandon progressif. L'avantage de MD5 était que tout le monde le connaissait et l'utilisait, alors que la migration vers de nouveaux algorithmes fait courir un risque de babelisation. Il faut noter que les attaques connues contre MD5 (RFC 4270) ne s'appliquent pas forcément à l'utilisation qu'en font les protocoles de routage et que la vulnérabilité de MD5 est donc encore dans le futur. Néanmoins, il est plus prudent de prévoir son remplacement dès aujourd'hui. Les remplaçants envisagés sont en général de la famille SHA. Ceux-ci seront sans doute à leur tour remplacés dans le futur, la cryptanalyse ne cessant jamais de progresser. L'ancienne normalisation, qui indiquait « en dur » la fonction de hachage dans la spécification du protocole de routage, n'est donc plus adaptée. Les sections suivantes du RFC détaillent la situation pour les principaux protocoles de routage cherchant, pour chacun d'eux, comment éliminer MD5 tout en ayant un algorithme commun.
Commençons par la section 2, consacrée à IS-IS. Si la norme ISO originelle ne permettait que le mot de passe en clair, le RFC 5304 a ajouté la possibilité de cryptographie, d'abord avec MD5 puis, dans le RFC 5310, d'autres algorithmes comme la famille SHA. L'avantage de l'authentification par mot de pass en clair est que, normalisée dès le début, elle fonctionne avec toutes les mises en œuvre de IS-IS. Sa sécurité est très mauvaise (il est trivial d'écouter le réseau pour découvrir le mot de passe). Il est donc recommandé d'utiliser les solutions cryptographiques, mais cela implique des algorithmes communs. Si un routeur ne connait que SHA-256 et l'autre que SHA-1, ils ne pourront pas s'authentifier mutuellement. Or, même si les deux routeurs mettent en œuvre le RFC 5310, cette situation est possible.
Notre RFC ne fait pas de choix mais demande que les futurs RFC sur IS-IS choisissent au moins un algorithme obligatoire, qui sera donc connu de tous les routeurs, et qui ne soit pas MD5.
L'autre grand protocole de routage interne, OSPF, fait l'objet de la section 3. Si OSPFv3 reposait entièrement sur IPsec et n'avait pas de mécanisme d'authentification propre (cela a changé avec le RFC 6506), OSPFv2 (de très loin le plus utilisé) a son mécanisme à lui. Ce dernier, dans la norme originale (RFC 2328), permettait le mot de passe en clair ou bien de la cryptographie avec MD5. Le RFC 5709 ajoutait la possibilité d'utiliser la famille SHA. Mais les seuls mécanismes d'authentification obligatoires sont ceux de l'ancien RFC (y compris le plus simple, « pas d'authentification »). Comme avec IS-IS, il est donc nécessaire qu'une nouvelle norme dise clairement quel est l'algorithme standard et sûr que doivent mettre en œuvre tous les logiciels OSPF.
Quant à OSPFv3 (section 4), du fait qu'il utilise IPsec, ses algorithmes communs sont ceux d'IPsec, ESP (RFC 4522) qui lui même utilise SHA-1 (RFC 2404). Ce dernier sera sans doute remplacé bientôt par AES (qui avait été introduit dans le RFC 3566).
Et le bon vieux RIP, dans sa version RIPv2 (section 5) ? Sa norme actuelle est le RFC 2453, qui ne prévoyait comme authentification que le mot de passe en clair. Le RFC 2082 ajoutait MD5 que le RFC 4822 a remplacé par SHA. Toutefois, comme les deux autres protocoles cités, RIP n'a pas d'algorithme unique garanti et une nouvelle norme est donc nécessaire, pour éviter que les routeurs ne se rabattent sur MD5 (ou, pire, sur le mot de passe en clair) pour pouvoir interopérer.
La version RIPng, elle (section 6), comme OSPFv3, se repose entièrement sur IPsec et donc sur les mêmes algorithmes.
La section 7 résume et rappelle les problèmes de sécurité abordés. D'abord, tous les mécanismes étudiés ici ne fournissent que l'authentification. Si on désire en plus de la confidentialité, il faut chercher ailleurs (par exemple IPsec avec ESP). D'autre part, les experts en cryptographie conseillent généralement de changer les clés régulièrement, diverses attaques cryptanalytiques prenant du temps. Il ne faut donc pas en donner à l'ennemi. Or, aucun de ces protocoles de routage ne fournit de mécanisme pour un remplacement coordonné des clés, il faut tout gérer à la main.
Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : J. Woodyatt (Apple)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 25 janvier 2011
Ah, la sécurité informatique... Sujet de polémiques sans fin, à l'IETF comme ailleurs. Faut-il des pare-feux ? Faut-il protéger le PC de M. Michu par défaut ? Vaut-il mieux la liberté ou bien la sécurité (réponse en un paragraphe, de préférence) ? Il est très difficile de réunir un consensus sur ce thème et, après avoir essayé, le groupe de travail v6ops de l'IETF a décidé de produire uniquement des recommandations sur la configuration d'un pare-feu pour les CPE (les « boxes ») IPv6, sans s'engager sur la question de savoir s'il fallait un pare-feu ou pas...
Le CPE (Customer Premises Equipment) est le petit boîtier qui connecte le réseau du client résidentiel (M. Michu) au FAI. Parfois fourni par le FAI, parfois acheté en supermarché, il est typiquement laissé tel quel, sans changement de la configuration, et sa configuration par défaut a donc une grande importance. Aujourd'hui, où le principal protocole de l'Internet est IPv4, le CPE a en général une configuration par défaut qui inclut l'allocation d'adresses IP privées (RFC 1918) aux machines du réseau local, et une connexion au FAI, par laquelle arrivera une adresse IP publique. Certaines personnes croient que le fait que les machines « internes » ont une adresse IP privée leur assure une certaine sécurité. C'est largement faux mais, ce qui est sûr, c'est que le mécanisme de traduction d'adresses entre l'intérieur et l'extérieur empêche l'ouverture de connexion à la demande des machines extérieures. Si une imprimante a un serveur HTTP pour sa configuration, le monde extérieur ne peut pas s'y connecter par des moyens normaux (il existe plusieurs moyens « anormaux » comme le changement DNS, et c'est pour cela que le bénéfice en terme de sécurité est douteux). Parfois, on est content de ce barrage (qui empêche les méchants barbares de se connecter à notre innocente imprimante, qui n'est probablement pas configurée de manière très sûre, avec son mot de passe d'usine jamais changé), parfois on le regrette (quand le transfert de fichiers en pair-à-pair échoue ou bien quand un coup de téléphone SIP s'établit mais que la voix ne passe pas). Ce filtrage de fait peut en effet frapper aussi bien les applications légitimes que les autres.
Et en IPv6 ? Le NAT s'est imposé pour IPv4 car, de toute façon, vu le manque d'adresses IPv4, il n'y avait pas le choix. Mais en IPv6, on revient à l'abondance. Chaque machine du réseau local a une adresse IP unique au niveau mondial et redevient donc contactable. La sécurité largement illusoire que fournissait le NAT disparait. Que faut-il mettre à la place ? Un pare-feu ? Et, si oui, configuré comment à sa sortie d'usine ? (Rappelez-vous que M. Michu ne changera probablement jamais la configuration. La règle d'ergonomie que rappelle notre RFC est que le réglage de la sécurité dans le CPE doit être facile à faire et encore plus facile à ignorer.)
Notre RFC 6092 ne répond pas à toutes les questions sur la sécurité d'IPv6. Il vise le cas où on veut fournir une sécurité simple dans un environnement simple, celui de l'accès Internet résidentiel. Les cas plus complexes, par exemple celui d'un réseau d'une entreprise, avec des ingénieurs compétents, sont délibérement laissés de côté (section 1 et RFC 4864). Ici, ce RFC propose un compromis jugé raisonnable dans ce contexte, entre la sécurité et le respect du principe de connexion de bout en bout, qui est à la base du succès d'Internet.
Chaque virgule de ce RFC a été négociée avec acharnement. Ainsi, le statut de ce document est « pour information » mais il utilise le vocabulaire normatif du RFC 2119, tout en précisant en section 1.2 que c'est uniquement pour la précision du discours.
La section 2 du RFC décrit le modèle de réseau considéré. Le CPE est un engin simple (on ne peut donc pas lui demander des services complexes), routeur par défaut du réseau local (RFC 8504), et n'ayant typiquement qu'une seule interface avec l'extérieur, celle qui mène au FAI, plus un petit nombre d'interfaces vers l'intérieur (par exemple Ethernet et WiFi). Pour ce qui concerne la sécurité, leur vision du monde est également très simple : un univers rassurant et civilisé du côté du réseau local, un monde hostile et dangereux de l'autre côté. Le RFC 4864 résume les services de sécurité attendus : filtrer les paquets clairement anormaux (comme les paquets venant de l'extérieur mais prétendant avoir une adresse IP source interne, ou comme les paquets martiens du RFC 4949), ne pas permettre de paquets entrants sans qu'une « connexion » ait d'abord été initiée de l'interieur, permettre des exceptions manuellement configurées (sur la base des adresses IP et ports source). En IPv4, un routeur NAT fournissait plusieurs de ces services sans même y penser, comme effet de bord de la traduction d'adresses (qui, en IPv4, impose de garder un état, donc de se souvenir des connexions ouvertes). En IPv6, routage et filtrage sont nettement séparés. Le RFC 4864 proposait donc de répondre au besoin des utilisateurs (qui s'attendent au même niveau de protection en IPv4 et IPv6) en ayant par défaut un pare-feu à état, qui bloque les connexions entrantes.
Il faut noter que certaines applications voudraient bien autoriser les connexions entrantes, au moins depuis certaines adresses. Il n'existe pas actuellement de mécanisme normalisé pour qu'une application puisse dire au CPE « je veux bien recevoir des connexions sur mon port 443, s'il te plait, laisse-les passer ». Plusieurs projets ont été discutés à l'IETF mais sans résultat consensuel pour l'instant.
Autre point à garder en tête, le CPE est un routeur et doit donc se comporter comme tel (RFC 8504, sur les obligations des routeurs). Il doit également (section 2.1) bloquer certains paquets dangereux, comme les usurpateurs ou les martiens cités plus haut, ainsi que ceux ayant l'en-tête de routage 0 (RFC 5095). En revanche, le CPE ne doit pas empêcher le développement de nouveaux services et applications sur l'Internet. Il ne faut donc pas qu'il bloque aveuglément les paquets IPv6 ayant des en-têtes de sécurité ou de routage.
Au niveau 3, le CPE va devoir bloquer par défaut les tunnels, sauf ceux d'IPsec (car il serait paradoxal qu'un pare-feu, censé améliorer la sécurité, bloque par défaut un protocole qui permet de sécuriser le trafic). Pour la même raison, HIP doit être autorisé.
Et au niveau 4 (section 2.3) ? Le principe posé est celui d'une fermeture par défaut : pas de paquets TCP ou UDP entrants s'ils n'ont pas été sollicités de l'intérieur, par une application se connectant à l'extérieur. C'est cette simple règle, qui prend juste une phrase du RFC, qui a suscité le plus de tempêtes de discussions autour de ce document, puisqu'elle revient à renoncer, par écrit, au principe de la connectivité de bout en bout.
La section 3 du RFC transforme ensuite ces principes généraux en recommandations concrètes. Si on est pressé, on peut lire à la place la section 4, qui est un résumé de ces recommandations. Les recommandations sont identifiées par un numéro unique et je vais reprendre ici la syntaxe du RFC, qui les désigne par REC-N où N est le numéro. Dans ses recommandations, cette section s'appuie sur la classification des paquets et des flots (ensemble de paquets liés à la même « connexion ») :
La section 3.1 traite ensuite du cas du filtrage le plus simple, le filtrage sans état, où chaque paquet est examiné uniquement pour son contenu, indépendamment de tout contexte. Il ne s'agit donc que de filtrage de paquets, sans considérer les flots. Ce filtrage sans état devrait éliminer les usurpateurs (REC-5, REC-6, RFC 2827 et RFC 3704). De même, les adresses IPv6 appartenant à des services obsolètes (RFC 3879) ou non admises sur l'Internet public (RFC 6890) devraient être rejetées (REC-3). Les requêtes DNS de l'extérieur devraient être rejetées (REC-8).
Les sections 3.2 et 3.3 traitent ensuite du cas du filtrage avec état, où le CPE filtrant se souvient des paquets précédents et peut donc reconstituer des flots. Le cas facile (section 3.3) est celui où le protocole de couche 4 a une sémantique de connexion. Le pare-feu peut alors savoir exactement quand la connexion est ouverte et quand elle se termine (ce qui permet de libérer les ressources allouées pour le filtrage). Parmi les protocoles dans ce cas, TCP, SCTP mais aussi tous les futurs protocoles de transport à connexion. Un problème typique des pare-feux avec état est en effet qu'ils regardent l'établissement et la fermeture de la connexion et que cela implique qu'ils connaissent le protocole de transport utilisé (beaucoup de pare-feux de bas de gamme ne connaissent pas SCTP et le bloquent donc aveuglément, ce qui rend difficile le déploiement de ce « nouveau » protocole).
Commençons par TCP, le cas le plus simple (section 3.3.1). REC-31 demande que les CPE qui gèrent TCP le gèrent complètement et de manière conforme à la machine à états du RFC 793, y compris dans ses aspects moins connus comme l'ouverture simultanée (les deux pairs envoyant un SYN presque en même temps). C'est quand même un comble qu'il faille un RFC pour dire que les autres RFC doivent être respectés et cela donne une idée des problèmes auquel est confronté l'Internet aujourd'hui. Afin de maximiser les chances qu'une application nouvelle fonctionne correctement, REC-33 demande que le filtrage ait un comportement indépendant de la destination, c'est-à-dire que l'adresse de destination ne soit pas prise en compte pour mettre en correspondance un paquet avec un flot. Le comportement dépendant de l'adresse peut être adopté si on souhaite contrôler davantage. Voir le RFC 5382 pour plus de détails sur la gestion de TCP dans un CPE.
Autre demande de notre RFC qui ne correspond pas à l'état actuel de la plupart des CPE : REC-34 exige que, par défaut, les paquets TCP SYN entrants bloqués suscitent l'envoi d'un message ICMP Destination unreachable. Aujourd'hui, il est probable que la grande majorité des CPE avalent silencieusement le paquet TCP, sans prévenir l'envoyeur.
Et les délais de garde ? A priori, pour les protocoles orientés
connexion comme TCP, ils ne sont pas nécessaires, puisque la fin d'une
connexion sera toujours explicite, avec les paquets FIN (ou
RST). Mais, en pratique, le CPE peut rater la fin d'une connexion (par
exemple parce qu'un des pairs TCP a été éteint et n'a donc pas pu
terminer proprement la connexion). Pour gérer ce cas, tous les
équipements intermédiaires qui gèrent les états des connexions TCP
ajoutent un délai de garde et, si aucun paquet n'est passé pendant ce
délai, ils suppriment l'état, ce qui empêchera les paquets ultérieurs
de passer. C'est souvent un problème pour les applications comme
SSH, qui peuvent laisser passer des heures sans
envoyer de paquets (avec OpenSSH, la directive
ServerAliveInterval
permet d'envoyer des paquets
pour maintenir la connexion ouverte). Il existe aussi des mécanismes
pour envoyer des paquets TCP sans réel contenu, uniquement chargés de
maintenir une connexion ouverte (RFC 1122, qui
spécifie une durée par défaut de deux heures, bien trop longue pour la
plupart des CPE). REC-35 demande donc un délai de garde minimal par
défaut de
deux heures et quatre minutes (voir le RFC 5382 pour les
raisons de ce choix), bien plus long que celui des CPE d'aujourd'hui.
Comme TCP a besoin d'ICMP (notamment pour découvrir la MTU du chemin), REC-36 rappelle que, si un équipement transmet du TCP, il doit aussi transmettre les messages ICMP essentiels, Destination unreachable et Packet too big. A contrario (REC-37), le passage d'un paquet ICMP ne doit pas entraîner le CPE à supprimer les états des connexions TCP (décider, lors de la réception d'un paquet ICMP, si on coupe la connexion TCP associée est un processus complexe, voir le RFC 5927).
TCP est très répandu et relativement bien connu. On peut espérer (même si c'est illusoire) que tous les CPE le gèrent bien. Mais qu'en est-il de SCTP, son concurrent bien moins connu (section 3.3.2) ? D'abord, il faut noter que SCTP a des particularités, notamment le fait qu'une même connexion puisse utiliser plusieurs adresses IP. Cela rend le modèle simple de notre RFC 6092 inapplicable puisqu'il faudrait que les différents routeurs qui voient passer les paquets d'une même connexion se coordonnent (ce qui ne serait pas « simple »). Toutefois, les applications SCTP qui n'exploitent pas toutes les fonctions de ce protocole peuvent quand même s'en tirer. Si tous les paquets passent au même endroit (un seul routeur) et que cet endroit suit le RFC 4960, comme indiqué par REC-38, alors tout peut bien se passer. En pratique, SCTP souffre bien plus du fait que beaucoup de CPE bloquent tous les protocoles inconnus, ce qui signifie en général tous ceux ayant été créés il y a moins de vingt ans (les boxes sont très conservatrices).
La section 3.2, elle, s'occupe du cas moins facile où, contrairement à ce qui se passe avec TCP ou SCTP, il n'y a pas de connexion explicite. Le CPE ne peut pas savoir quand une « session » se termine. La seule solution générale est d'attendre un certain temps après le dernier paquet vu. Autrement, il faut que le CPE connaisse le protocole applicatif utilisé (et sache ainsi, par exemple, qu'une « session » DNS, c'est typiquement seulement deux datagrammes UDP, un de requête et un de réponse). La section 3.2.2 avertit que cette méthode ne doit pas mener à une interdiction de fait des applications nouvelles, donc inconnues du CPE.
Pour ICMPv6, les recommandations concernant son filtrage figurent dans le RFC 4890 (pour le résumer : il ne faut surtout pas filtrer aveuglément la totalité d'ICMP). La règle ajoutée par notre RFC 6092 est de vérifier, avant de faire suivre un paquet ICMP, que les données de la couche transport qu'il contient correspondent à une session en cours (section 3.2.1).
Pour les autres protocoles, afin de maximiser les chances qu'une application nouvelle ou un protocole de couche 4 nouveau fonctionnent correctement, la section 3.2.2 recommande fortement que le filtrage ait un comportement indépendant de la destination (REC-11, endpoint independent filter), c'est-à-dire que l'adresse de destination ne soit pas prise en compte pour mettre en correspondance un paquet avec un flot. Le comportement dépendant de l'adresse peut être adopté si on souhaite une sécurité plus fasciste, peut-être via une option de configuration du pare-feu.
Le cas spécifique d'UDP (rappelons qu'il existe d'autres protocoles de transport que TCP et UDP) est traité en section 3.2.3. Le RFC 4787 donnait déjà des règles pour le comportement attendu d'un routeur NAT avec UDP. Ces règles s'appliquent toujours dans le cas de notre CPE IPv6. Par exemple, REC-14 demande un délai de garde minimum, avant de détruire l'état associé à un flot, de deux minutes (moins si les ports sont dans la zone bien connue, cf. REC-15). Beaucoup d'applications avaient en effet souffert de CPE qui détruisaient l'état trop tôt, empêchant les paquets ultérieurs de passer.
Et IPsec ? Il est en section 3.2.4. Comme son utilisation permet d'améliorer sérieusement la sécurité de l'Internet, il serait paradoxal qu'un équipement assurant des fonctions de sécurité le bloque. REC-21 et REC-22 demandent donc qu'IPsec passe par défaut. Même chose pour HIP avec REC-26. Notons que de telles recommandations laissent de côté le cas de futurs protocoles de sécurité, dont le déploiement risque d'être bloqué par un CPE qui interdit trop de choses par défaut.
Enfin, les applications de gestion font l'objet de la section 3.5. La plupart des CPE ne verront jamais leur configuration par défaut modifiée et, si c'est le cas, celui ou celle qui change la configuration ne sera en général pas un expert. Le RFC ne donne pas plus de détails, à part l'insistance sur le fait que ces fonctions de configuration ne doivent pas être accessibles depuis l'Internet, seulement depuis le réseau local.
On l'a vu, le comportement par défaut d'un CPE qui suit ce RFC est
d'interdire les connexions entrantes. Or, certaines applications
souhaiteraient pouvoir en recevoir (section 3.4), soit parce qu'elle
jouent un rôle de serveur, soit parce que le fonctionnement du
protocole sous-jacent implique que l'application se mette en écoute
(c'est le cas de SIP). Il n'existe pas de
mécanisme normalisé pour l'application de dire au pare-feu « laisse
entrer les paquets RTP en provenance de
2001:db8:1010::47:1
», même s'il existe des
solutions non-standard comme UPnP. Avec les CPE
traditionnels, gérant de l'IPv4 NATé, les applications se servent
typiquement de STUN pour « ouvrir
(indirectement) une brèche »
dans le pare-feu. Et en IPv6 ? Même s'il n'y a pas de NAT, les
recommandations de notre RFC 6092 ont le même résultat
d'empêcher les connexions entrantes. L'idéal serait un mécanisme
standard équivalent à UPnP ou à des propositions comme
l'Application Listener Discovery Protocol. Mais il n'existe pas et l'état actuel des
discussions à l'IETF ne permet pas de penser qu'il apparaitra bientôt,
bien que des propositions existent comme une extension des RFC 5189 ou RFC 4080.
En attendant, les recommendations pour les CPE sont d'offrir un mécanisme pour permettre aux applications de solliciter l'ouverture du pare-feu (REC-48) et de permettre, via une action de l'administrateur, de couper le pare-feu ou de changer sa politique pour laisser entrer les connexions (REC-49). Bien sûr, ce dernier mode impose que les machines sur le réseau local soient proprement sécurisées (le RFC utilise une formulation plus restrictive, en demandant que les machines aient leur propre pare-feu, alors que ce n'est qu'une solution de sécurisation parmi d'autres) mais il est nécessaire que cette option soit présente, car c'est la seule qui permet l'accès à toutes les potentialités de l'Internet. Sans elle, le CPE n'est pas un point d'accès à l'Internet mais un Minitel amélioré.
La section 7, consacrée spécifiquement à la sécurité, prend de la hauteur et rappelle quelques bons principes de sécurité. Elle note ainsi que le RFC ne prétend pas que la politique par défaut proposée (qu'on peut résumer par « zéro connexion entrante par défaut ») soit effective, simplement qu'elle assure le même niveau de sécurité ou d'insécurité que celui fourni par un routeur NAT d'aujourd'hui. Comme le rappelle le RFC 2993, cette politique peut même diminuer la sécurité (par exemple par l'« illusion du limes », ce qui fait qu'on se fie aveuglément à la protection qu'elle offre et qu'on oublie de sécuriser l'intérieur). Les bonnes pratiques de sécurité, et des protections comme celles recommandées dans le RFC 4864 sont donc toujours d'actualité. Après tout, les attaques ne viennent pas que de l'extérieur. Même quand l'attaquant humain n'a pas accès au réseau local, il peut trouver un moyen (via du malware, par exemple) de l'attaquer de l'intérieur.
Cette section sur la sécurité note que la grande majorité des ordinateurs dont le système d'exploitation gère IPv6 ont également un mécanisme de filtrage compatible IPv6. Ce n'est toutefois pas forcément le cas pour les autres machines, comme les imprimantes.
Petite exception au principe comme quoi la sécurité d'un réseau situé derrière un CPE IPv6 conforme à ce RFC est à peu près la même que celle d'un réseau NATé : IPsec n'est pas, par défaut, autorisé par le CPE typique actuel. De toute façon, le dernier paragraphe du RFC, écrit dans le pur style juridique états-unien, note bien que l'IETF n'est responsable de rien et ne garantit pas que les règles énoncées dans ce RFC améliorent la sécurité... C'est une innovation dans un RFC : verra-t-on le RFC sur TCP dire « L'IETF ne promet pas que vous échapperez à la congestion si vous suivez cet algorithme » et celui sur SMTP affirmera-t-il « Attention, utiliser le courrier vous expose au spam » ?
Date de publication du RFC : Février 2011
Auteur(s) du RFC : N. Mavrogiannopoulos (KUL), D. Gillmor
Pour information
Première rédaction de cet article le 3 février 2011
Le protocole TLS, permettant de chiffrer et d'authentifier des communications sur Internet n'utilisait qu'un seul type de certificats, ceux à la norme X.509 (cf. RFC 5280). Désormais, on peut aussi se servir de certificats PGP. Ce RFC 6091 met à jour la première spécification de « PGP dans TLS », qui était dans le RFC 5081 et la fait passer du statut « expérimental » à « pour information ». (Depuis, le RFC 8446 a supprimé cette possibilité d'utiliser les clés PGP.)
Pour authentifier l'autre partie, lors d'une communication TLS (utilisée par exemple avec HTTP ou bien avec SMTP), on doit signer ses messages avec sa clé privée. Le correspondant doit connaitre la clé publique pour vérifier cette signature. Avec l'ancien protocole SSL et avec son successeur TLS (normalisé dans le RFC 5246), cela se faisait en présentant un certificat X.509. X.509 a plusieurs limites, notamment le fait qu'il dépende d'une autorité de certification. Tout le monde n'a pas envie de payer une telle autorité, pour un gain de sécurité contestable. Il était donc important d'avoir une alternative.
Celle-ci est déjà mise en œuvre dans GnuTLS (pour l'instant, le seul logiciel à le faire).
Techniquement, notre RFC dépend du mécanisme d'extension TLS spécifié dans
le RFC 5246. Ces extensions permettent d'annoncer le type de
certificat utilisé (extension cert_type
, numéro 9
dans le registre des extensions), et donc de choisir X.509 ou bien PGP (PGP est
normalisé dans le RFC 4880). Le RFC précise que ces
extensions ne doivent pas être utilisées si on ne gère que des
certificats X.509, pour interopérer plus facilement avec les vieilles
implémentations. Sinon, si le client propose du PGP et que le serveur
ne connait pas, ce dernier répond
unsupported_certificate
. Un registre des types de certificats possibles permettra d'ajouter plus tard autre chose que X.509 ou PGP. L'algorithme de chiffrement de la session, lui, est
indépendant du fait qu'on utilise X.509 ou PGP.
Notre RFC utilise le terme de clé pour parler des clés PGP actuelles et de certificat lorsque les mêmes clés sont utilisées pour l'authentification (cf. section 2). La clé PGP est envoyée encodée en binaire, ou bien peut être récupérée sur le réseau, si celui qui veut s'authentifier indique uniquement l'empreinte de la clé (de la même façon qu'un certificat X.509 peut être récupéré sur le réseau, si celui qui veut s'authentifier indique l'URL de son certificat, cf. RFC 6066, section 5). Attention, contrairement à l'option équivalente pour X.509, la possibilité de récupérer le certificat sur le réseau ne permet pas d'indiquer le nom ou l'URL d'un serveur de certificats. Celui-ci doit être connu du serveur (qui vérifiera ensuite que les empreintes cryptographiques correspondent.)
Les changements par rapport au RFC 5081 sont
résumés dans l'annexe A. Le principal, de loin, est un changement dans
la sémantique du message indiquant le certificat (Client Certificate
et Server Certificate
) qui fait que les mises en
œuvre de l'ancien RFC et celles de notre nouveau RFC 6091 ne peuvent pas interopérer. Comme l'ancien
RFC n'avait que le statut « expérimental » et qu'il n'a jamais été
largement déployé, ce n'est pas un trop gros problème en pratique.
Date de publication du RFC : Février 2011
Auteur(s) du RFC : D. McGrew (Cisco Systems), K. Igoe, M. Salter (National Security Agency)
Pour information
Première rédaction de cet article le 4 février 2011
Dans l'arsenal des algorithmes de cryptographie utilisés sur l'Internet, on trouve de plus en plus d'algorithmes basées sur les courbes elliptiques (par exemple les RFC 4754, RFC 5289, RFC 5656 et RFC 5753, sans compter les normes d'autres SDO). Mais il n'existait apparemment pas de texte de synthèse sur cette famille d'algorithmes, utilisable comme référence pour des RFC. Ce manque est désormais comblé avec ce RFC 6090 qui résume ce que tout participant à l'IETF devrait connaître des courbes elliptiques et de leur utilisation en cryptographie. Ainsi, RSA et la factorisation en nombres premiers ne restera pas la seule méthode de cryptographie asymétrique sur laquelle faire reposer la sécurité des communications à travers l'Internet.
Ce RFC nécessite donc un peu plus de connaissances en mathématiques que la moyenne. Le débutant pourra commencer par l'excellent article d'Adam Langley, sur son blog Imperial Violet, « Elliptic curves and their implementation ». Il apprendra que les courbes elliptiques n'ont rien à voir avec les ellipses (en mathématiques, lorsqu'on classe des objets en deux types on appelle souvent l'un le type pair, le type impair ; lorsqu'on tombe sur trois types, on qualifie souvent les trois types de parabolique, elliptique et hyperbolique, en référence aux coniques), il verra de jolies images : (toutes les images de cet article ont été volées à l'article sur Imperial Violet). Il devra aussi réviser quelques notions de maths (cf. section 2 du RFC) comme celle de groupe (section 2.2 du RFC). En effet, les points de la courbe elliptique, plus une opération d'addition sur la courbe (qu'on peut aussi représenter visuellement, voir l'image plus loin), qui a un élément neutre (un zéro), forment un groupe. (À noter que le RFC, lui, sans donner de nom à cette opération, la note * qui est d'habitude réservé, en informatique, à la multiplication, voir annexe E pour une discussion de ces deux notations possibles.)
Une fois qu'on a l'addition, on définit la multiplication par un nombre entier positif (qui consiste juste à répéter l'addition). Pour tout point de la courbe, on peut donc relativement facilement le multiplier par un nombre quelconque (ce nombre sera la clé privée). Mais l'inverse est extrêmement dur : étant donné un point résultat, et le point de départ, comment trouver le nombre qui a servi à la multiplication ? Dans le groupe formé par les nombres entiers et l'addition usuelle, c'est trivial (c'est une simple division euclidienne). Sur la courbe elliptique, c'est au contraire une tâche herculéenne. Et c'est là son intérêt pour la cryptographie. De méme que RSA reposait sur le fait qu'une composition des facteurs premiers est triviale mais que la décomposition est très difficile, la cryptographie par courbes elliptiques repose sur le fait que la multiplication sur la courbe est simple, la division très difficile. On a donc la base de la cryptographie asymétrique, une opération mathématique très difficile à inverser.
J'ai dit que la multiplication sur la courbe elliptique était simple mais tout est relatif. L'essentiel de l'article d'Imperial Violet est consacré à la mise en œuvre logicielle et beaucoup d'optimisations sont nécessaires, pour pouvoir multiplier un point en un temps raisonnable, sachant que le facteur de multiplication est un très grand nombre. L'article devient nettement plus chevelu ici, à réserver aux fanas de l'algorithmique.
Après ce petit détour par les maths, revenons au RFC. Il utilise le sigle ECC pour parler de l'ensemble des techniques de Elliptic Curve Cryptography. Ce sont donc des techniques de clé publique, qui peuvent servir à mettre en œuvre des techniques comme Diffie-Hellman ou ElGamal. Bien qu'assez ancienne, ECC est toujours relativement peu déployé, alors qu'elle fournit en général une meilleure sécurité et des performances plus importantes. Notre RFC note que c'est sans doute en partie par manque de documents normatifs facilement disponibles (un problème que notre RFC vise justement à traiter) mais aussi en raison de problèmes d'appropriation intellectuelle (la plupart des techniques ECC sont pourries de brevets jusqu'au trognon, cf. section 9).
Le RFC fournit d'abord un arrière-plan mathématique nécessaire, en section 2. Comme il n'est pas facile de lire des formules mathématiques dans le texte ASCII auquel sont contraints les RFC, la lecture n'en est pas évidente et je suggère de partir plutôt de l'article d'Imperial Violet.
Le RFC donne ensuite la définition d'une courbe elliptique en section 3 et introduit la notion de transformation d'un système de coordonnées dans un autre, afin de faciliter les calculs (cf. annexe F pour du pseudo-code). Surtout, la section 3.3 liste les paramètres dont dépend une courbe elliptique particulière. Des propriétés de ces paramètres dépend la sécurité de la courbe et ils ne doivent donc pas être choisis au hasard (la section 3.3.2 donne les critères qu'ils doivent satisfaire). Un exemple d'une courbe et de ses paramètres, la courbe P-256, normalisée par le NIST (dans FIPS 186-2) et utilisée dans le RFC 4753, est donné en annexe D. Une autre courbe elliptique connue est Curve25519, utilisée dans DNScurve.
Une fois ECC définie, on peut l'utiliser dans des algorithmes de crypto classique. La section 4 décrit ECDH, courbe elliptique + Diffie-Hellman, pour permettre à ces chers Alice et Bob de se mettre d'accord sur un secret (qui servira au chiffrement ultérieur) bien qu'ils communiquent via un canal non sûr. Le principe est simple mais génial. Alice et Bob partent du même point G de la courbe, Alice choisit au hasard un nombre j et met G à la puissance j (je rappelle que le RFC utilise la notation multiplicative, pas l'additive comme dans l'article sur Imperial Violet, et note donc cette opération G^j). Bob en fait autant avec son nombre k pris au hasard. Chacun envoie le résultat de son calcul à l'autre, qui doit alors calculer G^(j*k). Par exemple, Alice reçoit donc G^k et calcule donc G^k^j (qui est équivalent à G^(k*j)). Alice et Bob connaissent donc le secret, G^(j*k), alors que l'écoutant éventuel n'a pu le déterminer, car il ignore j et k.
De même, on peut faire une version « courbe elliptique » de ElGamal (section 5). Cet algorithme de chiffrement était basé sur un autre groupe mathématique, celui des entiers modulo N mais on peut se servir d'un autre groupe, comme celui fourni par une courbe elliptique. C'est ainsi qu'est créé ECDSA, version à courbe elliptique de DSA (cet algorithme est disponible pour DNSSEC, cf. RFC 6605 ; il est déjà mis en œuvre dans PowerDNS ; DNSSEC a déjà un algorithme à courbe elliptique, GOST, cf. RFC 7091).
L'IETF se préoccupant de faire des protocoles qui marchent dans le monde réel, il faut se poser la question de l'interopérabilité. La section 7 décrit donc des détails pratiques nécessaires. Toujours sur le côté concret, la section 8 est consacrée aux détails d'implémentation et aux tests validant celle-ci. Par exemple, un test courant est de vérifier qu'un sous-programme produit, pour des paramètres d'entrée donnés, le résultat attendu. Comme le mécanisme de signature de KT-I (cf. section 5.4) est non déterministe, ce genre de tests ne va pas marcher, la signature étant différente à chaque fois. Par contre, la validation de la signature est, elle, déterministe (heureusement...) et peut donc être testée. De même, ECDH peut être testé avec les résultats des RFC 4753 et RFC 5114.
Reprenons de la hauteur : si les sections précédentes passionneront les mathématiciens et les programmeurs, la section 9 est consacrée aux problèmes que posent les brevets pour le déploiement des courbes elliptiques. Si les bases des courbes elliptiques semblent libres (en théorie, on ne peut pas breveter un théorème mathématique : mais, en pratique, les organismes comme l'Office Européen des Brevets violent régulièrement leurs propres règles, et semblent agir en dehors de tout contrôle démocratique), les optimisations nécessaires sont souvent plombées par un brevet. L'implémenteur d'une courbe elliptique doit donc, après avoir pris connaissance des règles de l'IETF sur le sujet (RFC 8179), consulter la base des appropriations intellectuelles publiées.
L'unique but de la cryptographie à courbes elliptiques étant la sécurité, la section Sécurité (la 10), revient donc en détail sur les précautions à prendre pour que les courbes elliptiques remplissent leur rôle. Il existe plusieurs attaques documentées (comme celle de Pohlig-Hellman), l'algorithme de Shanks ou celui de Pollard qui sont des algorithmes génériques, marchant avec n'importe quel groupe, comme des attaques spécifiques d'une courbe elliptique particulière. Le RFC insiste notamment sur l'importance de ne prendre que des courbes dont les paramètres ont été soigneusement choisis (voir aussi le RFC 4086, et l'annexe B, puisque plusieurs opérations dépendent de nombres aléatoires).
D'autre part, la cryptographie ne fait pas de miracles : si Diffie-Hellman protège contre un attaquant passif, il ne peut rien contre un intermédiaire actif.
Merci à Michael Le Barbier Grünewald pour sa relecture mathématique.
Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : K. Whistler (Sybase), G. Adams (Skynav), M. Duerst (Aoyama Gakuin University), R. Presuhn, J. Klensin
Pour information
Première rédaction de cet article le 8 novembre 2010
Parfois, il y a des mauvaises idées. Parfois, elles sont même inscrites dans un RFC et sont alors utilisées. Lorsqu'une idée est reconnue comme mauvaise, il faut alors savoir l'abandonner. C'est ce que fait ce RFC 6082 qui abandonne officiellement l'idée du RFC 2482 qui fournissait un mécanisme d'indication de la langue utilisée, dans un texte brut en Unicode.
Le RFC 2482 réservait plusieurs caractères Unicode entre U+E0000 et
U+E007F à des fins d'étiquetage, pour indiquer la
langue utilisée pour écrire un texte. Par
exemple, U+E0001 U+E006A U+E0061 (caractère language
tag, puis caractère tag letter j puis
enfin tag letter a) indiquait un texte en
japonais (ja
étant le
japonais pour les étiquettes de
langue). Il n'a pas été tellement utilisé en
pratique et, aujourd'hui, a été remplacé par des mécanismes
d'étiquetage globaux (comme l'en-tête
Content-Language:
du RFC 3282) pour le
texte brut ou bien
par des mécanismes plus fins pour les documents structurés (par
exemple l'attribut xml:lang
pour les textes en
XML). Le consortium
Unicode a officiellement abandonné ce mécanisme (section 16.9
de la norme Unicode 5.2) et notre RFC 6082 a été fait pour éviter que des implémenteurs tombent
sur le RFC 2482 et ne le mettent en œuvre en le croyant
toujours d'actualité.
Fin du parcours, donc, pour le RFC 2482, qui entre ainsi dans la catégorie « Intérêt historique uniquement » (catégorie décrite dans la section 4.2.4 du RFC 2026).
Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : G. Camarillo, P. Nikander, J. Hautakorpi, A. Keranen (Ericsson), A. Johnston (Avaya)
Expérimental
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 25 janvier 2011
Voici un RFC bien abstrait, qui normalise un mécanisme pour construire des réseaux virtuels (overlays) en utilisant le protocole HIP. Un de ces premiers réseaux virtuels pourrait être celui du protocole RELOAD, utilisé pour faire du SIP pair-à-pair.
Le nom de ces réseaux virtuels, HIP bone, est un jeu de mots sur l'os coxal (hip bone en anglais) et une allusion à d'autres réseaux virtuels comme le défunt 6bone. Mais le but est très différent : IPv6 ne peut pas passer sur l'infrastructure IPv4 du vieil Internet et doit donc être « tunnelé » au dessus d'IPv4, l'ensemble de ces tunnels formant le 6bone. Au contraire, HIP (RFC 7401) étant un protocole entièrement situé dans les machines terminales, il n'a pas besoin de tunnels pour marcher. On peut expérimenter avec HIP dès aujourd'hui. Alors, à quoi sert un HIP bone ? L'idée est de faciliter le développement de services pair-à-pair, d'utiliser HIP pour construire un réseau virtuel de machines HIP, les autres fonctions utiles (comme le stockage des données) étant fournies par des protocoles pair-à-pair situés au dessus (nommés peer protocol dans le RFC). Ces protocoles seront donc déchargés, grâce à HIP, de certaines des tâches de bas niveau.
HIP est un protocole de séparation du localisateur et de l'identificateur. Le routage dans le HIP bone se fait sur l'identificateur et c'est HIP qui se charge de le mettre en correspondance avec les localisateurs sous-jacents, le routage dans l'Internet se faisant sur la base de l'adresse IP (qui, en HIP, est réduite au rôle de localisateur). Si vous ne connaissez pas HIP, la section 3 du RFC sert de rappel.
Le HIP bone lui-même est introduit en section 4. Un réseau virtuel bâti au dessus d'un réseau réel comme l'Internet dépend d'un mécanisme de maintien du réseau (table de routage, tests de connectivité, pairs qui arrivent et qui repartent, etc), d'un mécanisme de stockage et de récupération de données (par exemple une DHT), et d'un mécanisme de gestion des connexions (se connecter à un pair, échanger des messages). Dans le HIP bone, HIP ne fournit que ce dernier service. L'application qui utilisera le HIP bone pourra parler directement à HIP pour certaines fonctions et au peer protocol pour les autres (cf. la figure 3 du RFC).
On l'a dit, notre RFC ne fait que spécifier un cadre assez
général. Une bonne partie devra être faite dans le peer
protocol et la section 5 du RFC rappelle ce qui relèvera de
la responsabilité dudit protocole. Par exemple, il existe actuellement
un Internet-Draft décrivant
RELOAD (REsource LOcation And Disovery),
draft-ietf-p2psip-base
,
et un autre qui décrit comment bâtir un réseau virtuel pour RELOAD au
dessus de HIP, draft-ietf-hip-reload-instance
.
Ainsi (section 5.1), c'est au peer protocol de
gérer le délicat problème du recrutement (qui peut entrer dans le
réseau virtuel). Pour aider ces protocoles situés au dessus d'un
HIP bone, la section 6 liste quelques paramètres
utiles qui seront mis dans les messages HIP comme le nouvel
OVERLAY_ID
, qui identifiera un réseau virtuel
donné (car une machine HIP sera peut-être membre de plusieurs réseaux virtuels).
Voilà, une fois ce RFC 6079 lu et assimilé, il ne vous reste plus qu'à concevoir votre réseau virtuel à vous ⌣.
Date de publication du RFC : Février 2011
Auteur(s) du RFC : Dimitri Papadimitriou (Alcatel-Lucent), Michael Welzl (University of Oslo), Michael Scharf (University of Stuttgart), Bob Briscoe (BT & UCL)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF iccrg
Première rédaction de cet article le 3 février 2011
La congestion est la plaie des réseaux informatiques depuis leurs débuts. Quelle que soit la capacité de ceux-ci, les utilisations emplissent les tuyaux jusqu'à ce que ceux-ci débordent. Il y a donc depuis quarante ans, mais surtout depuis le travail de Van Jacobson en 1988 (voir son ancien mais toujours bon « Congestion Avoidance and Control », Proceeding of ACM SIGCOMM'88 Symposium, août 1988 ; attention, c'est assez matheux, réservé aux gens qui comprennent les fonctions de Liapounov), d'innombrables études et recherches sur la congestion. (Voir par exemple l'article du Wikipédia anglophone sur TCP.) Pourtant, le problème est loin d'être épuisé, comme le montre ce RFC du groupe ICCRG de l'IRTF consacré aux problèmes non résolus en matière de congestion. Couvrant tous les aspects de ce problème, il est également une passionnante lecture sur l'état actuel de l'Internet et le bouillonnement d'activité qu'il suscite toujours chez les chercheurs.
Qu'est-ce exactement que la congestion ? La section 1 la définit comme l'état d'un réseau dont les ressources sont tellement utilisées que des phénomènes visibles par les utilisateurs et objectivement mesurables (comme le retard d'acheminement des paquets, voire leur perte) apparaissent. Sur un réseau où les ressources sont partagées mais pas réservées (cas de l'Internet), la congestion se traduit par une diminution de la qualité de service. (Voir Keshav, S., « What is congestion and what is congestion control », Presentation at IRTF ICCRG Workshop, PFLDNet 2007, Los Angeles, février 2007.)
Le contrôle de congestion, lui, est l'ensemble des algorithmes qui permettent de partager les ressources en minimisant la congestion. Il existe sous deux formes, primal et dual (je n'ai pas cherché à traduire ces termes rares, apparemment issus de la recherche opérationnelle). La première fait référence à la capacité des émetteurs à adapter leur rythme d'envoi s'ils reçoivent des indications comme quoi la congestion a lieu. Sur l'Internet, c'est typiquement le rôle de TCP. La seconde forme fait référence au travail des équipements intermédiaires, les routeurs, qui détectent la congestion et réagissent, par exemple via la RED.
Aujourd'hui, des dizaines de RFC ont « congestion » dans leur
titre ; le RFC 5783 fournit un survol de cette
littérature et le RFC 5681 synthétise tout ce qu'il faut
savoir sur la congestion dans TCP. Dans les mises en œuvre de TCP/IP
aujourd'hui, d'innombrables lignes de code sont là pour réagir à la
congestion. Malheureusement, un bon nombre des algorithmes et méthodes « historiques » pour gérer la congestion sur l'Internet rencontrent leurs limites avec les
évolution des réseaux. Résultat, plusieurs systèmes d'exploitation
sont livrés avec des algorithmes non-standard (comme, dans certains
cas, Linux, avec l'algorithme
Cubic ;
l'algorithme en cours peut être affiché avec sysctl
net/ipv4/tcp_congestion_control
et les disponibles avec
sysctl
net/ipv4/tcp_available_congestion_control
). (On peut voir
aussi les projets
de FreeBSD qui incluent également Cubic et d'autres.) À noter
que tous les nouveaux algorithmes ne sont pas forcément un
progrès. Francis Dupont fait ainsi remarquer, suite à cet article, que
des algorithmes comme « TCP Vegas », excellent lors des tests,
ne réussissaient pas aussi bien sur le vrai réseau.
Autre évolution, l'utilisation de solutions qui ne sont pas uniquement de bout en bout mais font participer les routeurs, comme ECN (RFC 3168).
Quels sont les défis d'aujourd'hui ? La section 2 examine les défis généraux. L'un des premiers est l'hétérogénéité de l'Internet (section 2.1). Des liens radio laissant passer quelques misérables kb/s aux fibres optiques Gb/s, l'éventail des capacités est immense. Même chose pour la latence, entre les réseaux locaux où elle est inférieure à la milli-seconde et les liaisons satellites où elle approche la seconde. Rien n'indique que de tels écarts se résorberont. On imagine le travail de TCP, qui doit fonctionner dans un environnement aussi varié. À l'époque de Van Jacobson, latence et capacité des réseaux faisait qu'une connexion TCP n'avait en transit, à un moment donné, que quelques douzaines de paquets. Aujourd'hui, cela pourrait être beaucoup plus. Il n'y a pas actuellement de consensus à l'IETF pour choisir les nouveaux algorithmes, d'autant plus que leurs interactions (entre un pair TCP qui utiliserait un ancien algorithme et un pair qui utiliserait un nouveau) sont mal connues. Si le RFC 5033 définit des critères sur le choix d'un algorithme, ceux-ci ne répondent pas à toutes les questions, comme celle de savoir si on accepte de réduire les performances des anciennes implémentations (ce que font certaines nouvelles méthodes).
Second grand problème, la stabilité (section 2.2). On souhaiterait que, à situation inchangée, les algorithmes de contrôle de la congestion convergent vers un état stable, au lieu de faire du ping-pong entre deux états (on ouvre les vannes, la congestion reprend, on diminue le débit, le trafic passe très en dessous du seuil, alors on rouvre les vannes, etc). Il existe des théories mathématiques à ce sujet pour des algorithmes en boucle fermée, comme TCP, mais qui ne servent pas dans le cas où il y a interaction entre plusieurs boucles de contrôle, ce qui est le cas de l'Internet, où le ralentissement du débit d'une connexion TCP peut pousser les autres à augmenter leur débit. On souhaite également une stabilité locale : si un système est perturbé, après la fin de la perturbation, il revient rapidement à l'équilibre.
Les modélisations issues de la théorie de l'automatique permettent d'éliminer les algorithmes les plus mauvais (s'ils ne marchent pas dans les cas simples, ce n'est pas la peine de se demander s'ils fonctionneront sur l'Internet). Mais elles sont insuffisantes pour les cas réels, l'approche la plus courante aujourd'hui est donc la simulation, ce qui ne garantit pas que ça fonctionnera en vrai. Est-ce que TCP est stable dans des conditions réelles ? Il n'y a aujourd'hui aucune certitude scientifique à ce sujet.
Ce ne sont pas les heuristiques qui manquent, lorsqu'on conçoit un nouvel algorithme de gestion de la congestion, comme par exemple le principe de la conservation des paquets (faire en sorte que l'émetteur envoie autant de paquets par seconde que le récepteur en consomme). Mais elles peuvent être trop exigeantes (c'est le cas de la conservation de paquets, dont il a été démontré qu'elle était un principe suffisant, mais pas nécessaire) ou tout simplement non démontrées.
Un exemple d'un problème réel est que TCP démarre lentement : son débit s'accroit avec le temps au fur et à mesure que l'envoyeur se rassure qu'il n'y a pas congestion. Mais beaucoup de flots de données, à commencer par les courtes connexions HTTP qui récupèrent une seule page HTML, sont de durée tellement faible que TCP n'atteint jamais son état d'équilibre et de débit maximum. Cela peut pousser certains à « améliorer » l'algorithme dans leur intérêt (c'est le cas de Google, voir leur article). Égoïsme ou bien usage normal de la liberté ? En tout cas, cela a poussé à des recherches sur un TCP résistant aux égoïstes comme dans l'article « TCP congestion control with a misbehaving receiver ».
Beaucoup plus chaude est la question de la justice, surtout dans le contexte du débat sur la neutralité de l'Internet. C'est en effet une chose d'assurer le bien de l'Internet, c'en est une autre que de vérifier que cela ne se fait pas aux dépens de certains utilisateurs, sacrifiés au bien commun. Intuitivement, la justice, dans un réseau, c'est que, en cas de sacrifices, tout le monde doit prendre sa part de manière équitable (section 2.3). On touche là clairement à des questions politiques, suscitant des articles vengeurs comme le très intéressant article de Briscoe, « Flow Rate Fairness: Dismantling a Religion » (ACM SIGCOMM Computer Communication Review, Vol.37, No.2, pp.63-74, avril 2007). Briscoe argumente essentiellement sur le fait que la justice entre les flots TCP n'a aucun intérêt, il faudrait chercher la justice entre les personnes, ou bien entre les organisations. Mais, de toute façon, la question de la justice est connue pour être impossible à définir de façon cohérente dans le parallélisme (je cite Francis Dupont) : elle est sujette à un problème de la famille du paradoxe de Condorcet sur le vote équitable, c'est-à-dire que les critères qui établissent l'équitabilité ne sont pas compatibles.
Des RFC ont également traité ce cas comme le RFC 3714. Dans l'approche traditionnelle, pour le cas ultra-simple de deux utilisateurs regardant tous les deux YouTube, la justice était considérée comme l'égalité de leurs débits. Certains idéologues du marché ont par exemple proposé de définir la justice comme « ce que les utilisateurs sont prêts à payer pour éviter la congestion ». Dans cette approche, les deux débits pourraient être très différents. Mais intégrer l'aspect financier ouvre bien d'autres boîtes remplies de questions difficiles comme le mécanisme par lequel on va comptabiliser la contribution à la congestion.
Même si on ne prend pas en compte l'argent dans l'équation, la définition de ce qui est « juste » n'est pas triviale. Pas exemple, l'égalité doit-elle être celle des bits/s ou bien celle des paquets/s ? Faut-il la mesurer sur le long terme de façon à ce qu'une application sur une machine puisse profiter à fond du réseau parce que cette machine a été raisonnable dans les heures précédentes ? Le RFC note justement que ce n'est pas forcément une question de recherche, c'est un débat, et aucun article scientifique ne va le trancher. Le RFC note également que des mécanismes trop complexes, au nom de la justice, pourraient sérieusement handicaper l'Internet (car ralentissant trop les équipements, cf. RFC 5290).
Place maintenant à l'étude détaillée des défis qui attendent l'IETF dans ce domaine. Ils font l'objet de la section 3. Le premier est celui de la répartition du travail entre le réseau (les équipements intermédiaires comme les routeurs) et machines situées aux extrémités (section 3.1). Traditionnellement, l'Internet fonctionne en limitant sérieusement les fonctions des routeurs et en concentrant le travail difficile aux extrémités, où les machines ont davantage de ressources (section 3.1.1), peuvent maintenir un état complexe, et surtout sont sous le contrôle des utilisateurs (mettre trop de fonctions dans les routeurs peut sérieusement menacer la neutralité du réseau).
En outre, si de nouveaux mécanismes de gestion de la congestion apparaissent, et qu'ils sont situés dans les couches basses (comme la couche 3), ils mettront du temps à être déployés, d'autant plus que les concepteurs de routeurs attendront sans doute que ces mécanismes soient stables avant de les câbler en dur dans leurs circuits. Mais, d'abord, que peut faire un routeur pour aider à gérer la congestion ? Il peut le faire par une meilleure gestion de ses files d'attente, ou bien il peut le faire en signalant aux extrémités les problèmes de congestion qu'il voit. La première approche est déjà utilisée mais pas de manière uniforme dans tout l'Internet. Une de ses limites est qu'on ne sait pas trop quels sont les paramètres idéaux, par exemple pour les méthodes RED ou AVQ (Adaptive Virtual Queue) et qu'on ne dispose pas de moyen de les déterminer automatiquement.
La seconde façon dont les routeurs peuvent aider, la signalisation
explicite, est utilisée dans ECN (RFC 3168), Quick-Start (RFC 4782),
XCP (eXplicit Control Protocol, draft-falk-xcp-spec
) et dans d'autres protocoles. Contrairement
à TCP, XCP sépare le contrôle de la justice (s'assurer qu'aucun flot
de données ne prend toute la capacité) et le contrôle de la
congestion. Mais XCP reste très expérimental et produit parfois de
drôles de résultats (« An Example
of Instability in XCP »). Dans tous les cas, ces
mécanismes, qui donnent un plus grand rôle aux équipements
intermédiaires, doivent être évalués dans le contexte du
fonctionnement de bout en bout, qui est l'un
des principaux piliers de l'Internet (RFC 1958), qui a assuré
son succès et sa survie. La
congestion est un problème intéressant précisément parce qu'elle ne
peut pas se régler uniquement de bout en bout (puisque c'est un
phénomène spécifique au réseau) mais il faut bien réfléchir avant de
mettre dans le réseau des fonctions qui pourraient interférer avec les
politiques d'utilisation des machines terminales.
Ainsi, un protocole comme XCP ne nécessite pas d'état dans le réseau (et semble donc respecter le principe de bout en bout) mais c'est uniquement à condition que les machines situées aux extrémités jouent le jeu, c'est-à-dire ne mentent pas sur les débits mesurés. Si on veut faire marcher XCP dans un environnement... non-coopératif (avec des tricheurs), les routeurs doivent alors garder trace des différents flots de données, ce qui met en péril le principe de bout en bout.
Tous ces problèmes (de comptabiliser l'usage que les différents flots de données font du réseau, et en résistant à la triche) existent depuis qu'on parle de QoS sur l'Internet, c'est-à-dire au moins depuis IntServ (RFC 2208). Le problème reste ouvert.
Une des raisons pour lesquels ils ne sont pas résolus est qu'il n'existe aucune technique (section 3.1.2) qui ne repose pas sur un état maintenu dans le routeur, par flot (donc, posant de grands problèmes de passage à l'échelle).
Autre problème pour l'usage des équipements réseaux à des fins de
lutter contre la congestion, l'accès à l'information (section
3.1.3). Pour être efficace, le routeur qui veut gérer la congestion
doit connaître des choses comme la capacité des liens. Attendez, me
direz-vous, un routeur sait forcément que son interface
ge-3/0/2
est à 1 Gb/s ! Mais c'est plus complexe que
cela : par exemple en cas d'interface vers un réseau partagé
(Wifi) ou en cas de tunnels (RFC 2784 ou
RFC 4301 ou bien d'autres techniques). Dans ces
circonstances, un routeur IP ne connaît pas forcément la capacité des
liens auxquels il est connecté.
Idéalement, si le routeur connaît la capacité du lien et le débit effectif, il sait si on approche de la congestion ou pas, via une simple division. Nous avons vu que la capacité n'était pas toujours connue mais le débit ne l'est pas non plus forcément. S'il est très haché, avec de brusques pics, déterminer un débit, pour le diviser par la capacité, n'est pas trivial. Bref, le routeur manque souvent d'informations pour décider. Faut-il créer de nouveaux mécanismes pour l'informer ? Ne risquent-ils pas de tourner très vite à l'usine à gaz ? (Un routeur IP a déjà beaucoup de choses à faire.)
Deuxième défi auquel est confronté TCP/IP : différencier la perte d'un paquet due à la congestion de l'abandon de ce paquet en raison de sa corruption (section 3.2). Actuellement, un routeur abandonne un paquet lorsque la congestion empêche sa transmission sur l'interface suivante. L'émetteur va typiquement interpréter toute perte de paquets comme un signe de congestion et diminuer le débit (TCP le fait automatiquement). Mais la perte du paquet peut être due à une autre cause, par exemple une modification accidentelle d'un ou plusieurs bits, qui rendra invalide la somme de contrôle, amenant la carte réseau à ignorer le paquet anormal. De telles modifications sont rares sur un lien filaire (il faut un gros rayon cosmique) mais relativement fréquentes sur les liaisons radio. TCP diminuerait alors son débit à tort. Le problème est bien connu (voir Krishnan, Sterbenz, Eddy, Partridge & Allman, « Explicit Transport Error Notification (ETEN) for Error-Prone Wireless and Satellite Networks », Computer Networks, 2004, ou bien le RFC 6069). La solution n'est pas évidente, d'autant plus que les deux phénomènes peuvent être liés (une congestion qui se traduit par des corruptions) et qu'il n'est pas évident qu'il faille continuer à envoyer au même débit si on perd la moitié des paquets suite à la corruption (voir un exemple de discussion).
Il y a donc deux problèmes ouverts, détecter la congestion et y réagir. Pour la détection, on pourrait penser compter sur la somme de contrôle dans l'en-tête IP (à condition que la couche 2 n'ait pas déjà jeté le paquet corrompu, ce que fait Ethernet). UDP-lite (RFC 3828) et DCCP (RFC 4340) le font (sans indiquer quelle doit être la réaction à ces corruptions). Une étude a montré que cela marchait bien au-dessus de GPRS et mal au dessus du WiFi. De toute façon, toute détection de corruption dans la couche 3 poserait des problèmes de coopération entre couches, difficiles à assurer pour IP, qui est conçu pour fonctionner sur toutes les couches 2 possibles.
Quant à la réaction à la corruption, il n'existe aucun protocole standard pour cela, bien que plusieurs propositions aient été faites dans la littérature scientifique (le TCP dit « Westwood »).
Un autre « point noir » de la gestion de la congestion est la prise en compte de la taille du paquet (section 3.3). Aujourd'hui, TCP l'ignore complètement, en partie parce que les très grands paquets (> 1500 octets, la MTU d'Ethernet) sont extrêmement rares sur l'Internet. La question de savoir si TCP a tort ou raison d'ignorer ce facteur est toujours un sujet de recherche. DCCP, par contre, peut tenir compte de la taille des paquets (cf. RFC 5622). Les routeurs typiques, en cas de congestion, ne tiennent pas compte de la taille d'un paquet avant de le jeter, alors que certaines études semblent indiquer que cela pourrait être une bonne idée. Beaucoup de questions restent ouvertes sur ce sujet : le facteur limitatif sur le réseau, dans les prochaines années, sera-t-il le nombre de bits ou le nombre de paquets (sur les réseaux lents, c'est clairement le nombre de bits qui peut déclencher la congestion ; mais au fur et à mesure que les réseaux deviennent plus rapides, c'est la capacité des équipements à traiter un grand nombre de paquets qui devient problématique). En cas de congestion, faut-il diminuer le nombre de bits (en réduisant le débit d'émission, ce que fait TCP) ou le nombre de paquets (en tentant des paquets plus gros) ? Actuellement, l'émetteur ne sait pas pourquoi il y a congestion, ce qui rend difficile le changement de son comportement. Prendre en compte la distinction entre débit en bits et débit en paquets compliquerait l'Internet mais y aurait-il un bénéfice ? Si la taille maximale des paquets sur le réseau, actuellement limitée en pratique à 1500 octets dans la plupart des cas, devait augmenter, la question deviendrait brûlante. (Ce point est couvert avec plus de détails dans le RFC 7141.)
La grande majorité des études sur le comportement de protocoles comme TCP supposait un flot relativement régulier sur le long terme, permettant ainsi aux algorithmes d'atteindre leur équilibre. Mais, dans la réalité, les choses ne se passent pas comme cela : un fichier HTML typique se charge avec seulement quelques paquets, et TCP sera donc, pendant toute la durée du flot, dans l'état « démarrage ». Comment améliorer ce cas fréquent (section 3.4) ? Au départ, le protocole de transport ne connaît rien des caractéristiques de la liaison et ne peut donc pas optimiser son débit. L'algorithme standard de TCP est tout de prudence : conçu par Van Jacobson et connu sous le nom significatif de slow start, il consiste à être très modéré tant qu'on ne connaît pas les détails de la liaison (RFC 2581 et RFC 5681). Résultat, le débit moyen est souvent trop bas, le réseau restant inoccupé. Ce problème est reconnu depuis longtemps (RFC 3742) mais sa solution souffre du manque de bases théoriques à cette difficile question (le slow start a été conçu de manière empirique).
Une autre solution serait de modifier les applications pour qu'elles réutilisent les connexions TCP existantes. C'est ce que peut faire HTTP, avec les connexions persistentes (RFC 2616, section 8.1).
Les spécificités de l'Internet ajoutent un nouvel élément au tableau (section 3.5). Contrairement à quasiment tous les autres réseaux informatiques qui ont existé, l'Internet est multi-organisations (le RFC dit multi-domains, où un domain est un système autonome). Ainsi (section 3.5.1), il existe des mécanismes de signalisation de la congestion qui peuvent poser des problèmes dans un tel environnement. C'est le cas de ECN (RFC 3168) où des bits non utilisés jusqu'à présent servent à indiquer que le routeur qui les a mis commence à voir de la congestion. En environnement mono-domaine, tout va bien. Mais dans le cas où le paquet rencontre plusieurs domaines, peut-on encore faire confiance à ces bits, qui ont pu être mis ou retirés à tort, par exemple pour ralentir une victime située dans un autre domaine (sections 8 et 19 du RFC 3168) ? Pour ECN, il y a des solutions techniques possibles (comme le RFC 3540), quoique apparemment peu déployées. Mais, d'une manière générale, toutes les solutions reposant sur la confiance entre domaines sont incertaines (notre RFC cite aussi le cas de TRC, TCP rate controller, un système de surveillance que les flots TCP se comportent bien). L'échange d'informations entre domaines, qui serait certainement utile pour lutter contre la congestion, est frappé de suspicion (section 3.5.2). Mon voisin me dit-il la vérité ? Dois-je lui dire la vérité en sachant que les informations transmises peuvent, entre autres, l'aider à se faire une bonne image de mon réseau, brisant ainsi la confidentialité ? Or, tous les mécanismes de signalisation de la congestion par les équipements réseau sont affectés par ce manque de confiance.
Un problème de sécurité proche est celui des applications malhonnêtes. L'Internet résiste aujourd'hui à la congestion car chaque pair TCP respecte les règles, même quand elles vont contre son propre intérêt. Après tout, un émetteur n'a jamais intérêt à diminuer son débit, si d'autres le feront à sa place. La section 3.7 se penche sur les comportements négatifs que pourraient adopter des applications. Le problème a déjà été étudié et des solutions proposées (RFC 3540). Elles sont efficaces (peut-être trop, dit le RFC, laissant entendre qu'elles pourraient sanctionner des innocents). Mais elles sont très peu déployées. Une des raisons est peut-être que les attaques sont pour l'instant apparemment très peu nombreuses. En fait, note notre RFC, l'étude de la quantité de telles attaques est en soi un sujet de recherche. On ne sait pas vraiment dire pour l'instant s'il y a beaucoup de tricheurs (peut-être l'exemple Google cité plus haut mais il est très récent et pas assez étudié). On soupçonne évidemment que tout logiciel qui annonce qu'il va « optimiser le temps de téléchargement » risque fort d'y arriver en trichant...
TCP n'est pas le seul protocole de transport : certaines applications utilisent un protocole sans contrôle de congestion, comme UDP, et sont donc censées gérer la congestion elles-mêmes. Or, comme indiqué plus haut, ce n'est pas dans leur intérêt et on pourrait voir des abus, comme s'en inquiétait le RFC 3714. Cette question est presque un problème philosophique : une machine connectée à l'Internet est libre, elle peut notamment utiliser le protocole de transport de son choix. Envoyer des octets au maximum de ses possibilités, sans tenir compte de la congestion, n'est-ce pas abuser de cette liberté ? Comme les applications qui utilisent UDP sont souvent les plus gourmandes (vidéo en haute définition, par exemple), le RFC 8085 insistait sur la nécessité qu'elles se comportent gentiment et mettent en œuvre une forme de contrôle de congestion adaptée à leurs bsoins propres.
Les applications ont des exigences souvent très différentes vis-à-vis du réseau. Par exemple, les gros transferts de fichiers peuvent souvent s'exécuter en arrière-plan en profitant de la capacité du réseau quand il est libre, tout en réduisant sérieusement leur débit s'il ne l'est pas (section 3.6). Comment utiliser cette « élasticité » pour mieux gérer la congestion ? L'idée de marquer les paquets en fonction de ces exigences des applications n'est pas neuve (on la trouve déjà dans les bits ToS du RFC 791) mais il y a aussi des propositions plus récentes comme le RFC 3662. Mais en pratique, ces mécanismes ne sont guère utilisés. Actuellement, un groupe de travail de l'IETF, LEDBAT, travaille sur ce sujet (voir leur solution dans le RFC 6817).
Enfin, il reste les autres défis, ceux qui sont jugés relativement peu importants aujourd'hui et n'ont donc pas mérité une section dédiée. Ils sont regroupés dans la section 3.8. On y trouve, par exemple, la question de la mesure du RTT (bien des protocoles dépendent d'une bonne évaluation de ce temps). Aujourd'hui, seul l'émetteur d'un paquet a une bonne idée du RTT, en mesurant le moment où revient l'accusé de réception. Il n'existe malheureusement pas de moyen pour le receveur d'estimer le RTT, ce qui l'empêche d'ajuster son comportement. D'autre part, le RTT brut n'est pas forcément utilisable directement (par exemple parce qu'il varie brutalement dans le temps) et il est utile de se pencher sur des valeurs extrapolées, plus lisses, comme celles du RFC 2988.
Autre défi qui se posera un jour (sections 3.8.2) : le cas des logiciels bogués, qui réagissent mal lorsqu'on essaie une nouvelle technique, même si elle est parfaitement légale : beaucoup de machines sur Internet ont été programmées avec les pieds et plantent (ou même plantent leur voisin) si les données envoyées ne sont pas celles attendues (comme ce fut le cas lors de la fameuse crise de l'attribut BGP 99). Ainsi, même si on conçoit un nouvel algorithme génial de contrôle de la congestion, il sera peut-être difficile à déployer. C'est ce qui est arrivé à ECN, qui a connu bien des problèmes mais aussi au window scaling que plusieurs routeurs de bas de gamme rejettaient (c'est arrivé par exemple sur les boxes d'Alice). Y a-t-il une solution à ce problème ? Le RFC suggère une responsabilité au moins partielle de l'IETF en demandant que, à l'avenir, le comportement par défaut des équipements, face à des options ou des champs inconnus, soit mieux spécifié, pour que le vieux logiciel laisse toujours passer proprement les options récentes. Je pense personnellement que c'est une illusion : dans bien des cas, ces règles existaient et les logiciels bogués les ignorent, car leurs auteurs, dissimulés derrière leur anonymat (comment retrouver les responsables du code des AliceBox ?) ont ignoré complètement ces règles. La section 3.8.6 revient d'ailleurs sur le cas des équipements intermédiaires (middleboxes) qui sont souvent les pires (RFC 2775).
Comme déjà signalé plus haut, un défi général auquel est confronté le contrôle de congestion est celui de la sécurité (section 4). Par exemple (RFC 4948), les DoS sont possibles parce que l'Internet n'impose pas de contrôle de congestion (attention, le RFC parle de dDoS mais c'est à mon avis une erreur : si certains réseaux ont des mécanismes de contrôle de congestion obligatoires, aucun ne prévoit un mécanisme global, qui pourrait arrêter un botnet composé de milliers de zombies indépendants). De manière plus générale, aujourd'hui, le respect des règles qui empêchent l'Internet de s'écrouler sous le poids de la congestion est facultatif, laissé à la bonne volonté de chacun. Cela peut être vu comme un problème de sécurité. S'il existait des mécanismes de contrôle de la congestion qui résistent aux égoïstes prêts à tricher, ces mécanismes pourraient également être utilisés contre les DoS.
Voilà, désolé d'avoir été si long mais ce RFC est très riche et le champ des problèmes non encore résolus dans ce domaine de la congestion est immense. Étudiants futurs chercheurs, à vous de travailler à le défricher !
Merci à Pierre Beyssac pour sa relecture et ses commentaires.
Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : D. Malas (CableLabs), A. Morton (AT&T Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF pmol
Première rédaction de cet article le 20 janvier 2011
Le protocole de signalisation SIP est aujourd'hui le plus utilisé pour la voix sur IP. Il existe de nombreux fournisseurs SIP concurrents, de nombreux services SIP un peu partout. Comment les comparer ? Ce RFC se consacre à définir des métriques pour la téléphonie SIP.
Il est le premier RFC produit par le groupe de travail PMOL de l'IETF, groupe de travail qui est consacré à la définition de métriques pour les couches hautes (notamment la couche 7), le groupe IPPM se consacrant aux couches basses comme la couche 3. En suivant ses recommandations, il devrait être possible de comparer des mesures de performances SIP entre différents services. À noter qu'il existait déjà des métriques pour des systèmes de téléphonie autres, comme SS7, mais rien pour SIP.
Comme PMOL (contrairement à un autre groupe de travail sur les mesures, BMWG) établit des métriques pour le monde extérieur, le grand Internet, les résultats des mesures sont influencés par des variables extérieures à SIP, par exemple la qualité du réseau (latence et capacité libre). Les métriques définies ici n'essaient pas de séparer ces variables « réseau » des autres. On teste donc un service, pas uniquement un serveur.
D'autre part, il s'agit bien de définir des métriques (des grandeurs mesurables et définies rigoureusement) et pas des objectifs chiffrés, genre SLA. Ce RFC définit ainsi ce qu'est exactement un temps de réponse, mais pas quelle valeur de ce temps est acceptable pour l'utilisateur.
Après ces préliminaires, la section 2 définit le vocabulaire utilisé. Ainsi, End-to-end fait référence à une liaison entre les deux entités qui communiquent (deux téléphones, par exemple), même si cette communication passe, au niveau 3 par beaucoup de routeurs, et au niveau 7 par plusieurs relais SIP. Une session est la communication établie par SIP (dont le rôle principal est justement d'établir et de fermer les sessions ; le transfert de la voix encodée n'est pas directement du ressort de SIP) et elle peut donc comprendre plusieurs flots de données différents, par exemple plusieurs connexions TCP.
Enfin (non, tout le travail préparatoire n'est pas fini, on n'est pas encore arrivé aux métriques elles-mêmes), toute mesure faisant intervenir le temps, la section 3 est dédiée aux problèmes de mesure de celui-ci. C'est essentiellement une reprise du RFC 2330, section 10. Pour les besoins des mesures SIP (moins exigeantes que les mesures comme le temps d'acheminement d'un paquet IP du RFC 7679), une erreur de moins d'une milli-seconde est demandée, ainsi qu'une stabilité de un pour mille pour la fréquence de l'horloge.
La section 4 introduit enfin ces fameuses métriques. Le temps commence lorsque le premier message est envoyé par un des UA (User Agents, typiquement un téléphone, matériel ou logiciel). Même si ce premier message doit être répété, l'horloge n'est pas remise à zéro. On arrête le chrono lorsque l'opération souhaitée par l'UA est faite, même si elle a nécessité plusieurs transactions SIP (par exemple, si un appel a été redirigé). Des options comme l'authentification (qui est fréquemment utilisée dans le monde SIP car les fournisseurs de service qui procurent un accès au téléphone classique ne sont jamais gratuits) peuvent sérieusement augmenter la durée mesurée mais on n'essaie pas de les retirer du total : elles font partie du service mesuré (voir section 5.3 pour les détails). Enfin, les métriques de la section 4 ne précisent pas la taille de l'échantillon utilisé, se contentant de rappeller qu'on a en général de meilleurs résultats en augmentant la taille de l'échantillon.
Pour comprendre les métriques, il faut se rappeller que le fonctionnement typique d'un téléphone SIP est :
Parmi les métriques définies, on trouve :
REGISTER
) et la réponse réussie, typiquement
200 OK
(les échecs sont
comptés différemment, voir section 4.2), exprimée en milli-secondes.INVITE
et la réponse à celle-ci
(la réponse pouvant être négative, par exemple un 486 - Occupé).INVITE
.Le logiciel de test sipsak affiche dans certains cas des durées mais elles ne sont pas exprimées en terme des métriques de ce RFC donc il faudrait lire le source pour avoir leur sémantique exacte. Ici, l'établissement d'une session :
% sipsak -vv -s "sip:bortzmeyer@ekiga.net" ... message received: SIP/2.0 200 OK ... ** reply received after 6.770 ms **
Et ici une session complète avec envoi d'un message :
% sipsak -vv -B "This is a test" -M -s "sip:stephane@10.10.86.76" ... received last message 55.642 ms after first request (test duration).
Date de publication du RFC : Février 2010
Auteur(s) du RFC : S. Frankel (NIST), S. Krishnan (Ericsson)
Pour information
Réalisé dans le cadre du groupe de travail IETF ipsecme
Première rédaction de cet article le 8 février 2011
Le protocole de sécurité IPsec a connu plusieurs versions, et de nombreuses extensions. Le programmeur qui voudrait aujourd'hui le mettre en œuvre, l'administrateur réseaux qui voudrait le déployer, doivent souvent se gratter le crâne assez longtemps, uniquement pour identifier les normes pertinentes. Pour leur faciliter la tâche, l'IETF produit un RFC spécial, la « carte routière » qui est uniquement une liste commentée des RFC qui s'appliquent à leur cas. La précédente version de la carte d'IPsec était le RFC 2411, que notre RFC 6071 remplace. Si vous voulez comprendre IPsec et IKE et que vous ne savez pas par où commencer, ce RFC 6071 pourra vous servir de guide dans la jungle des normes sur IPsec.
La section 1 commence par fournir un résumé bien utile d'IPsec et de ses protocoles auxiliaires comme IKE. IPsec vise à fournir un service de sécurité à tout service Internet, sans modifier les applications (contrairement à TLS). Si l'échange de paquets entre deux machines est protégé par IPsec, toutes leurs communications pourront être authentifiées et/ou confidentielles. On peut utiliser IPsec de bien des façons, mais les plus courantes aujourd'hui sont de créer un tunnel sécurisé entre deux sites ou bien d'établir un VPN entre un site central et des machines en promenade.
IPsec utilise la cryptographie et, pour cela, a besoin de clés. On peut les gérer de plusieurs façons (aujourd'hui, c'est souvent fait manuellement), mais la méthode standard pour la gestion dynamique des clés est IKE.
La section 2 de notre RFC classe les normes IPsec en pas moins de sept groupes : l'architecture, le protocole ESP (qui fournit authentification et confidentialité), le protocole AH (qui ne fournit que l'authentification), les algorithmes cryptographiques, les algorithmes combinés (qui indiquent comment faire fonctionner ensemble les différentes pièces), les algorithmes de préservation de l'intégrité des paquets et enfin IKE.
Du fait de la longue histoire d'IPsec, plusieurs versions de ce protocole coexistent. La version actuelle est IPsec v3 mais IPsec v2 est encore fréquemment rencontré dans la nature. La section 2.1.1 résume leurs différences. Par exemple, le protocole AH (RFC 4302), dont l'utilité est douteuse, puisque ESP fournit les mêmes services (tels que perçus par l'application), n'est plus obligatoire. AH existait en raison des restrictions à l'exportation de logiciels cryptographiques en dehors des États-Unis et de restrictions d'usage moyenâgeuses dans certains pays comme la France. Aujourd'hui que ces restrictions sont assouplies, AH ne fait que générer de la complexité supplémentaire, comme l'exposait la fameuse critique de Niels Ferguson et Bruce Schneier, « A Cryptographic Evaluation of IPsec ».
IKE a aussi plusieurs versions qui coexistent (section 2.3). La version actuelle est la v2, mais la v1 est toujours en service. La v2 se signale (section 2.3.1) entre autres par l'intégration d'EAP, l'utilisation d'ESP pour protéger IKE lui-même (avant, c'était un protocole spécifique qui s'en chargeait), par de meilleures protections contre les DoS, notamment en permettant au répondeur de ne pas allouer trop de ressources avant d'avoir authentifié l'appelant.
Outre les RFC sur IPsec et IKE, présentés plus loin, en section 3, il existe plusieurs registres IANA sur ces protocoles (section 2.4), notamment :
La section 3 décrit les documents à lire si on veut programmer IPsec. Je ne mentionne ici que ceux de l'IPsec récent (IPsec v3) mais notre RFC 6071 décrit aussi (section 3.1.1) ceux de la précédente version d'IPsec, autour du RFC 2401.
Le cœur de IPsec v3 est décrit dans trois RFC (section 3.1.2), le RFC 4301 sur l'architecture générale, le RFC 4302 sur AH et le RFC 4303 sur ESP. Autour de ce cœur, on trouve plusieurs ajouts comme la possibilité d'encapsuler IPsec dans UDP (RFC 3948) ou bien la possibilité de chiffrer sans arrangement préalable entre les parties (RFC 4322), par exemple en récupérant les clés dans le DNS (avec protection par DNSSEC bien sûr).
Sans être des ajouts à IPsec, il existe plusieurs RFC qui discutent de questions générales (section 3.3) comme la traversée des équipements NAT par IPsec (RFC 3715) ou les suggestions pour évaluer si IPsec est une solution adaptée (RFC 5406, uniquement pour le vieil IPsec v2).
IKE est traité de la même façon en section 4 : les documents de base pour la vieille - mais encore utilisée - version et pour la version actuelle, la v2 (le principal document étant le RFC 4306, suivi du document de clarification RFC 4718) puis les ajouts.
La section 5 est entièrement consacrée au délicat problème des algorithmes de cryptographie. Comme la cryptanalyse progresse sans cesse, envoyant dans les poubelles de l'histoire des algorithmes peu sûrs, et poussant à l'introduction de petits nouveaux, il est important qu'un protocole de sécurité comme IPsec puisse suivre l'état de l'art sans avoir besoin d'une révision. En nombre de RFC, c'est de loin ce secteur qui contribue le plus à la taille des normes IPsec. Pour que, dans cette variété de protocoles, deux mises en œuvre d'IPsec aient une chance de communiquer (section 5.1), il faut qu'il y ait un ensemble d'algorithmes communs. Dans IPsec, les algorithmes sont marqués comme obligatoires (toute mise en œuvre d'IPsec doit les implémenter) ou facultatifs. Le RFC 7321 définit les exigences auxquelles doivent obéir les algorithmes utilisés par IPsec, le RFC 4307, celles pour IKE.
La section 5.2 décrit ensuite les algorithmes de chiffrement eux-mêmes, par exemple l'obligatoire NULL (qui ne chiffre rien et ne protège donc rien, RFC 2410), l'obligatoire AES-CBC (RFC 3602, le facultatif Camellia (RFC 4312), etc.
Si la section 5.2 listait les algorithmes de chiffrement, la 5.3 décrit ceux utilisés pour le contrôle d'intégrité. On y trouve HMAC-SHA1 (RFC 2404), dont la mise en œuvre est obligatoire, mais aussi la famille SHA-2 (optionnelle, cf. RFC 4868), et même MD5 (RFC 2403) pas conseillé mais pas interdit non plus, les multiples vulnérabilités de MD5 n'affectant apparemment pas (pour l'instant) son usage en HMAC (RFC 4835).
Certains algorithmes peuvent fournir à la fois le chiffrement et l'intégrité, et la section 5.4 décrit ces combinaisons. Ainsi, AES en mode CCM CBC-MAC permet d'assurer les deux tâches (RFC 4309).
Pas de cryptographie sans nombres aléatoires (section 5.5), par exemple pour générer les clés de sessions de IKE. C'est donc une nouvelle série d'algorithmes qui doit être spécifiée.
Le zoo des algorithmes de cryptographie utilisés devient donc d'une taille impressionnante et on peut se demander si deux pairs IPsec trouveront une combinaison d'algorithmes qu'ils peuvent utiliser tous les deux ! La section 5.6 expose donc les suites. Une suite est un ensemble cohérent d'algorithmes qui simplifie le travail du programmeur : si on implémente toute la suite, on a un groupe d'algorithmes qui interopérera avec les autres utilisateurs de la même suite. En outre, il est plus facile de se référer à une suite qu'à une longue liste d'algorithmes. C'est ainsi que le RFC 4308 décrivait deux suites, « VPN-A », qui inclut 3DES, HMAC-SHA-1, et un mode Diffie-Hellman et « VPN-B » qui inclut AES-CBC, AES-XCBC-MAC et un mode Diffie-Hellman plus long. On peut ainsi choisir tout un ensemble d'algorithmes avec un seul bouton dans la configuration (« Use VPN-B: Yes »). Le RFC 4869 a ajouté quatre autres suites, tirées de normes « Suite B » de la NSA. Elles incluent la famille SHA-2.
Tiens, puisque j'ai parlé de Diffie-Hellman, mécanisme pour permettre à deux pairs de trouver des clés secrètes communes pour pouvoir communiquer, la section 5.7 décrit les RFC qui mentionnent cette méthode dans le contexte d'IPsec. Ainsi, le RFC 5903 est la dernière norme pour l'utilisation de courbes elliptiques dans le cadre Diffie-Hellman, et le RFC 5114 définit de nouveaux groupes pour cet algorithme.
Dans le monde réel, IPsec a connu de nombreux usages qui dépassaient parfois le strict cadre de ce qui était normalisé. La section 7 décrit certains de ces usages, qui étendent et facilitent l'utilisation d'IPsec. Ainsi, les RFC 3586 et RFC 3585 se penchent sur la question de définitions formelles des politiques de sécurité IPsec, le RFC 4807 décrit une MIB pour la gestion IPsec (il semble très peu utilisé), etc.
Une extension intéressante a été BTNS (Better-Than-Nothing Security, section 7.5) qui a introduit le concept de « la plus mauvaise sécurité est celle qu'on ne déploie pas » dans le monde IPsec. Celui-ci était réputé pour sa rigidité et son strict respect des bons principes techniques de sécurité. Ainsi, les protocoles IPsec imposaient une authentification des deux pairs, sans laquelle une attaque de l'intermédiaire était possible. Très bonne idée sauf que, en pratique, cette authentification nécessitait une lourde infrastructure d'identité (par exemple à base d'IGC) et qu'elle a, en pratique, pas mal freiné le déploiement d'IPsec. D'où cette évolution récente (2008) d'accepter un mode sans authentification, BTNS, qui permet d'établir une session IPsec avec des gens qu'on ne connait pas (pensez à un serveur Web, qui ne connait évidemment pas chacun de ses clients à l'avance). Les RFC 5386 et RFC 5387 décrivent BTNS.
Le talon d'Achille de tout protocole de
cryptographie est souvent dans la gestion des clés. Où les stocker,
comment garantir que la clé privée est en sécurité, que la clé
publique est bien authentique ? Pour la seconde question, la garantie
que la clé publique est bien la bonne, la section 7.8 rappelle le
mécanisme IPSECKEY
qui permet de stocker les clés
publiques dans le DNS (RFC 4025). Ce
mécanisme est resté largement théorique à ce jour (après tout, le DNS
n'offrait typiquement que peu de garanties de sécurité) mais la
signature de la racine avec DNSSEC le 15 juillet 2010 lui
a redonné de l'actualité. Il est désormais possible de valider une clé
trouvée dans le DNS.
Le programmeur qui implémente IPsec doit se rappeler que c'est un mécanisme général, situé en desous de la couche transport. Normalement, il est invisible aux applications. Toutefois, certains protocoles intermédiaires font un usage spécifique d'IPsec et la section 8 en donne une liste. Ainsi (section 8.2) OSPF, depuis la version 3 (RFC 4552 et RFC 5340), a remplacé son ancien mécanisme d'authentification spécifique par IPsec. OSPF fonctionnant souvent en diffusion restreinte, cela ne permet pas IKE impose l'usage de clés manuelles. En pratique, ce mécanisme de sécurisation semble très peu déployé et le passage à IPsec, trop complexe par rapport à l'ancienne méthode, a donc réduit la sécurité de OSPF (en sécurité, comme souvent dans d'autres domaines de l'ingéniérie, le mieux est l'ennemi du bien...)
Autre protocole de routage qui aurait bien besoin de davantage de sécurité, BGP. La section 8.6 décrit ce que IPsec peut lui apporter. Le RFC 5566 décrit ainsi une méthode pour protéger les session BGP. En pratique, elle semble quasi-inutilisée, les opérateurs préférant le RFC 2385 (ou peut-être demain son successeur, le RFC 5925). À noter que le plus gros problème de BGP, en pratique, n'est pas l'authentification du pair, mais la confiance qu'on accorde à ce qu'il transmet. Et, là, IPsec ne peut rien.
Autre consommateur d'IPsec, HIP (section 8.3 et RFC 7401). HIP est un protocole de séparation de l'identificateur et du localisateur. Il introduit donc des failles potentielles liées à l'indirection supplémentaire, par exemple d'un méchant essayant de rediriger un trafic important vers une victime en faisant croire que l'adresse IP de la victime est la sienne. N'ayant pas de mécanisme de sécurité propre, HIP délègue la protection de son trafic à IPsec (RFC 5202 et RFC 5206).
IPsec garantissant l'intégrité du trafic IP, il peut rentrer en conflit avec des protocoles qui modifient les paquets, pour de bonnes raisons, par exemple la compression. D'où le nombre de RFC sur l'interaction entre IPsec et ROHC (section 8.5), par exemple le RFC 5856 qui permet de comprimer les paquets dans un tunnel IPsec ou le RFC 5858 qui décrit des extensions à IPsec lui permettant de mieux s'entendre avec ROHC.
Si certains protocoles, comme dans la section précédente, utilisent IPsec, d'autres réutilisent seulement IKE pour leurs besoins propres (section 9). C'est le cas par exemple d'EAP (RFC 5106).
Voilà, ce résumé d'un long RFC (et qui se termine par une longue bibliographie) aura réussi, je l'espère, à donner une idée de la richesse et de la complexité du monde d'IPsec.
Merci à Yves Rutschle pour avoir relu et trouvé une grosse bogue.
Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : A. Zimmermann, A. Hannemann (RWTH Aachen University)
Expérimental
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 13 décembre 2010
Depuis très longtemps, un des problèmes du protocole de transport TCP est le fait qu'il réduise son débit en cas de pertes de paquets, pensant que cette perte provient d'une congestion. Mais si la perte de paquets était due à une coupure temporaire de la connectivité (ce qui est fréquent avec les liaisons radio), il est inutile de diminuer le débit, puisque le problème ne venait pas d'une congestion. TCP devrait au contraire continuer au même rythme, surtout une fois que la connectivité est rétablie. Une solution au problème pourrait être d'utiliser les messages ICMP pour mieux diagnostiquer la cause de la perte de paquets et c'est cette approche que ce RFC 6069 suggère d'essayer.
Rappelons que TCP fonctionne en envoyant des données dont l'autre pair doit accuser réception. S'il ne le fait pas à temps, TCP réemet les données et, s'il n'y a toujours rien, TCP en déduit que le réseau est surchargé (et jette donc des paquets) et, bon citoyen, il réagit en diminuant le rythme d'envoi (RFC 2988 et section 1 de notre RFC 6069). C'est ce comportement qui évite à l'Internet de s'écrouler sous la charge. Il n'est donc pas question que TCP soit modifié pour envoyer systématiquement au maximum de ses possibilités, « au cas où ça passe ». Mais, parfois, TCP est excessivement prudent. Si je débranche puis rebranche un câble réseau pendant le transfert d'un gros fichier, TCP va ralentir alors qu'il n'y avait aucune congestion (voir l'article de Schuetz, S., Eggert, L., Schmid, S., et M. Brunner, « Protocol enhancements for intermittently connected hosts », dans SIGCOMM Computer Communication Review vol. 35, no. 3). En pratique, le cas le plus embêtant se produit avec les réseaux sans-fil où de tels « branchements/débranchements » sont fréquents, soit en raison d'une modification soudaine du médium (une pluie intense, si on est dehors, ou bien un parasite soudain), soit en raison d'un déplacement de l'ordinateur. Peut-on détecter qu'une absence d'accusés de réception était due à une coupure temporaire du réseau ?
D'abord (section 2), il faut distinguer deux sortes de coupure du réseau. Les courtes sont celles qui durent moins longtemps que le délai de retransmission de TCP. Si les files d'attente du routeur situé avant la coupure sont suffisamment grandes, il pourra « tamponner » les paquets et il n'y aura même pas de perte, juste des variations de délai (cf. RFC 3522, RFC 4015 ou RFC 5682). Les longues coupures sont celles qui durent plus longtemps et où l'émetteur TCP doit donc commencer à renvoyer des paquets déjà transmis. Suivant le RFC 5681, TCP ne se contente pas de réémettre, il diminue son rythme de transmission. Si la connectivité revient, TCP ne va pas s'en apercevoir tout de suite et, même si les accusés de réception réapparaissent, TCP continuera à envoyer à un rythme réduit, sans bonne raison, juste parce qu'il a cru à la congestion. Idéalement, TCP devrait, au contraire, recommencer à pleine vitesse dès que la liaison est rétablie.
Comment détecter la coupure et le rétablissement ? La section 3 rappelle l'existence des paquets ICMP Destination Unreachable (RFC 792, RFC 1812 et RFC 4443). Ces paquets sont envoyés par le routeur, vers l'émetteur, si le routeur est obligé de jeter le paquet (codes 1, Host unreachable ou 0, Network unreachable). Mais attention, ils ne sont pas parfaits : ils ne sont pas envoyés en temps-réel (et donc arriveront peut-être après que TCP ait trouvé tout seul qu'il y a un problème) et ils sont en général limités en quantité.
Ces paquets ICMP contiennent les premiers octets du paquet qui a déclenché le problème et l'émetteur peut donc, en recevant le paquet ICMP, trouver la connexion TCP en cause. Le principe du nouvel algorithme expérimental TCP-LD (TCP Long Disruption) est donc d'utiliser ces messages ICMP pour différencier la congestion et la coupure. Dans le cas d'une coupure, cela vaudra la peine de réessayer de manière plus agressive.
L'algorithme est présenté en section 4. Le principe est simple : lorsque TCP a déjà dépassé son délai de garde, attendant un accusé de réception, et en cas de réception d'un message ICMP indiquant une coupure, TCP ne va pas augmenter les délais de retransmission. Au retour des accusés de réception, TCP reprendra « plein pot ». Les détails figurent par la suite. D'abord, TCP-LD ne s'applique qu'aux TCP qui suivaient l'algorithme de retransmission du RFC 2988. L'algorithme ne doit être utilisé qu'une fois la connexion complètement établie. Les seuls messages ICMP pris en compte sont ceux qui sont émis en réponse à des données TCP qui ont fait l'objet d'une retransmission. (Et autres détails, l'algorithme complet figure dans cette section 4.)
Une discussion des différents points à garder en tête figure en section 5. Elle insiste sur le fait que l'algorithme TCP-LD n'est déclenché que s'il y a réception des messages ICMP indiquant une erreur et expiration du délai de garde. Cela garantit que TCP-LD ne sera utilisé qu'en cas de longue coupure. Il y a quand même des cas qui prennent TCP-LD en défaut. C'est le cas par exemple de l'ambiguité analysée en section 5.1. Cette ambiguité vient du fait que le paquet TCP (et donc le message ICMP d'erreur qui concerne ce paquet) n'indique pas s'il s'agit d'une transmission ou d'une retransmission. Ce n'est pas un problème en pratique mais, si l'émetteur TCP qui reçoit le paquet ICMP peut être sûr qu'il y a eu retransmission, il n'est pas forcément sûr que le message d'erreur était en réponse à la retransmission. Encore plus rigolo (section 5.2), TCP-LD peut associer à tort un message ICMP à une session TCP ayant connu une retransmission, simplement parce que le numéro de séquence a dépassé sa valeur maximale et est revenu au début (sur des réseaux rapides, les 32 bits qui stockent le numéro de séquence TCP ne suffisent pas longtemps). La probabilité que cela arrive et interfère avec une coupure réelle est toutefois très faible. D'autres problèmes amusants (pour ceux qui connaissent bien TCP) forment la fin de la section 4, comme par exemple les risques liés aux paquets dupliqués. Un certain nombre des problèmes exposés pourraient être résolus avec l'option d'estampillage temporel de TCP (RFC 7323 et section 6 de notre RFC) : les estampilles pourraient lever certaines ambiguités.
TCP-LD est une technique « côté émetteur » seulement, et qui peut donc être déployée unilatéralement. Y a-t-il des risques à le faire ? La section 7 explore ces risques. Par exemple (section 7.1), si un émetteur TCP essaie de détecter une coupure définitive en se donnant une limite maximale au nombre de retransmissions, l'utilisation de TCP-LD, qui va réduire l'intervalle entre les retransmissions, pourra amener à des conclusions erronées. Il faut donc évaluer la durée maximale qu'on accepte avant de couper en temps, et pas en nombre de retransmissions.
Je l'ai dit au début, ce problème est perçu depuis très longtemps par les utilisateur de TCP. Il y a donc eu bien d'autres efforts pour le résoudre. La section 8 les résume. On y trouve par exemple des modifications des couches inférieures (RFC 3819) ou bien des modifications des routeurs IP, pour qu'ils analysent suffisamment de TCP pour pouvoir générer des messages d'information. TCP-LD, par contre, ne nécessite pas de modification des couches basses, ni des routeurs intermédiaires.
Un point important de ce schéma est que les messages ICMP ne sont sécurisés en rien et que d'autres RFC, comme le RFC 5927, demandent de s'en méfier et au minimum de ne pas agir sans les avoir sérieusement validés. Quels sont donc les risques (section 9) ? Un attaquant pourrait, soit générer des faux messages ICMP Destination Unreachable pour que TCP, croyant à une coupure et pas à une congestion, continue à inonder le réseau, soit au contraire empêcher les messages ICMP d'arriver, ramenant TCP à la situation avant TCP-LD. Dans le premier cas, les paquets ICMP nécessiteraient d'inclure une partie du paquet TCP, dont des éléments difficiles à deviner, comme le numéro de séquence et les mécanismes de validation du RFC 5927 conviendraient donc. Si elles échouent, l'attaquant qui arrive à trouver le numéro de séquence et les autres informations a de toute façon la possibilité de monter des attaques bien pires.
L'algorithme TCP-LD avait été présenté en
2009 à la réunion IETF 75
de Stockholm. Les transparents (« Make
TCP more Robust to Long Connectivity Disruptions ») sont
en
ligne. Ils exposent l'algorithme et le résultat d'une
évaluation après mise en œuvre sur
Linux. Plein de jolis graphes. À propos de
Linux, le travail des auteurs était disponible en http://www.umic-mesh.net/downloads/linux-tcp.html
et a depuis
été intégré (sous une forme modifiée) dans le noyau standard : regardez
tcp_v4_err()
dans
net/ipv4/tcp_ipv4.c
et les commentaires
mentionnant
draft-zimmermann-tcp-lcd
(l'ancien nom de ce RFC 6069).
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : M. Duerst (Aoyama Gakuin University), L. Masinter (Adobe), J. Zawinski (DNS lounge)
Chemin des normes
Première rédaction de cet article le 5 octobre 2010
Le plan d'URI mailto:
,
qui permettait d'indiquer une adresse de courrier à contacter, était normalisé dans le
RFC 2368. Désormais, il est remplacé par ce RFC 6068,
qui introduit notamment la possibilité
d'internationalisation des adresses indiquées
en paramètre de mailto:
.
La plupart des plans d'URI, comme
http:
ou ftp:
permettent de
désigner une ressource accessible quelque part sur le
Web. mailto:
est un cas à part dans la mesure où
il sert plutôt à déclencher une action, l'envoi d'un message. L'usage
le plus connu du plan mailto:
est dans
HTML, quand on écrit quelque chose du genre :
<p>N'hésitez pas à <a href="mailto:contact@example.org">signaler</a> tout problème que vous verriez dans ces pages. Merci d'avance.</p>
et le lecteur verra un lien sur le mot « signaler ». Sélectionnant ce
lien, son navigateur lui proposera alors
d'envoyer un courrier à contact@example.org
(ou
bien déléguera cette tâche à un MUA).
La syntaxe formelle des URI mailto:
figure en
section 2. Outre l'adresse de destination (comme dans l'exemple
ci-dessus), la grammaire permet de spécifier
des champs qui seront pré-remplis comme
Subject:
(la grammaire ne met pas de limite sur
les noms de ces champs, donc elle peut servir pour tout nouveau champ
inventé). Juste après le nom du plan, mailto
et
le deux-points obligatoire, figure l'adresse du
destinataire. Elle est évidemment à la syntaxe normalisée dans le RFC 5322, avec quelques restrictions, notamment
l'interdiction des commentaires (dans l'adresse Jean Durand
<jean@durand.example>
, « Jean Durand » est le
commentaire). La section 6 fournit de nombreux exemples, que je
reprends ici (parfois un peu adaptés). Par exemple, un URI
mailto:
de base peut être
<mailto:chris@example.com>
(en utilisant la
convention de l'annexe C du RFC 3986 d'écrire
l'URI entre chevrons). Un URI avec sujet peut
être
<mailto:infobot@example.com?subject=current-issue>
.
En théorie, n'importe quel en-tête peut être ainsi spécifié et, par
exemple, un logiciel qui archive une liste de diffusion sous forme de page Web
(comme Mhonarc) pourrait mettre un
In-Reply-To:
dans les URI, pour garantir qu'une
réponse ne casse pas les fils de discussion. Le RFC cite cet exemple :
<li><a href="mailto:list@example.org?In-Reply-To=%3C3469A91.D10AF4C@example.com%3E"> Foo larger than Bar?</a> 2010-10-04 08:28</li>
C'est très astucieux mais, en 2010, je ne connais aucun archiveur qui fasse cela...
Si on spécifie deux champs dans l'URI mailto:
,
on les sépare par le & : <mailto:joe@example.com?cc=bob@example.com&subject=hello>
.
Bien des caractères qui sont légaux dans une adresse de courrier
peuvent poser des problèmes dans un URI. C'est le cas par exemple de
%, de /, de
?, etc. Ceux-ci doivent être encodés en
« pour-cent », c'est-à-dire que, par exemple, ? devient %3F (la valeur
de l'octet en hexadécimal). Ainsi, un
URI avec indication du corps du message et un espace dans ce corps
peut être
<mailto:infobot@example.com?body=send%20current-issue>
. Un URI pour écrire à gorby%kremvax@example.com
devrait s'écrire <mailto:gorby%25kremvax@example.com>
. (Cet exemple du RFC fait référence à une vieille blague Usenet.)
Si les caractères à encoder ne sont pas dans
ASCII, c'est leur forme
UTF-8 qui est encodée pour-cent, octet par
octet. Ainsi, Stéphane
devient
St%C3%A9phane
. Doit-on appliquer le même
traitement aux caractères dans la partie « domaine » (à droite du @)
de l'adresse, si le domaine est un IDN ? Oui,
on peut, en appliquant l'encodage pour-cent à la forme UTF-8. Si
l'adresse est druon@académie-française.fr
, on
peut l'écrire
druon@acad%C3%A9mie-fran%C3%A7aise.fr
dans un URI
mailto:
mais il faudra le transformer en
Punycode
(druon@xn--acadmie-franaise-npb1a.fr
) au moment
de la composition du message, ce qui garantira que cela fonctionne
toujours, même avec des applications anciennes. Un exemple plus sophistiqué est donné en
section 6.3 avec le mot japonais nattō, qui
s'écrit en Unicode U+7D0D U+8C46. Pour écrire à
user@"natto".example.org
, on aura alors un URI
<mailto:user@%E7%B4%8D%E8%B1%86.example.org?subject=Test&body=NATTO>
.
Même les champs supplémentaires indiqués dans l'URI peuvent avoir
besoin d'être encodés pour-cent, car leur nom peut contenir des
caractères ASCII mais interdits dans un
URI. C'est encore plus vrai pour les valeurs des champs, qui ont des
chances de contenir des caractères non-ASCII. Ainsi, demander du café
(cf. RFC 2324)
par courrier se fera avec un URI
<mailto:user@example.org?subject=caf%C3%A9>
. body
pose un cas particulier car ce n'est
pas un vrai champ de l'en-tête, c'est un pseudo-champ qui identifie le
corps du message. Il peut être en UTF-8 (et donc encodé pour-cent),
mais on ne doit pas le stocker en
Quoted-Printable ou autres encodages utilisés
dans le courrier. De toute façon, ce pseudo-champ est conçu pour de
courts messages, pas pour du multimédia compliqué.
Des surencodages peuvent ensuite avoir besoin de s'appliquer, selon
le contexte. Ainsi, si un URI mailto:
comprend un
& (utilisé comme délimiteur de paramètres),
il ne posera pas de problème en texte seul mais, en
XML, il devra être écrit
&
(regardez le source XML ou HTML de cet article pour des exemples...).
Après ces détails de syntaxe, le mode d'emploi des URI
mailto:
(section 3). Les normes sur les URI
spécifient leur syntaxe mais en général ne donnent guère de détails
sur leur résolution : un URI est avant tout un identificateur. Pour
mailto:
, l'usage typique est d'envoyer un
courrier à l'adresse donnée en paramètre, en incluant les champs
supplémentaires donnés dans l'URI.
L'encodage des URI, sujet compliqué, justifie une section entière,
la numéro 5. Le RFC 3986 impose un surencodage
de certains caractères, que l'on peut trouver dans une adresse, dans
un en-tête, ou dans le corps du message. Un exemple typique est
l'espace, qui doit être écrit %20. Quant aux
fins de ligne, elles doivent suivre la règle de
l'Internet et être composées de deux caractères, %0D%0A. Tout logiciel
qui produit des URI mailto:
doit donc faire
attention à encoder ces caractères « spéciaux ». Par exemple, dans un
formulaire HTML, il est courant de représenter
l'espace par un +. Mais cela peut créer une
confusion avec les vrais +, qui peuvent se retrouver dans un URI
mailto:
, y compris dans l'adresse
comme dans l'exemple bill+ietf@example.org
que
cite le RFC. Bref, l'espace doit être représenté avec %20 et le + par lui-même
ou par %2B.
À noter que ce RFC n'inclut pas la possibilité d'utiliser des adresses de courrier complètement internatonalisées, la spécification de celles-ci étant encore marquée « expérimental ». Elle est devenue norme complète en 2012 avec le RFC 6530.
Les changements depuis le RFC 2368 sont rassemblés en
section 9 : le principal est évidemment la
possibilité d'inclure de l'UTF-8, encodé en pour-cent, possibilité qui
ajoute l'internationalisation aux URI mailto:
. Le
nouveau plan mailto:
est désormais enregistré
dans le registre des plans, tel que documenté en
section 8.
Comme l'utilisation normale d'un URI mailto:
est une action (envoyer un message), il faut
soigner la sécurité, à laquelle la section 7 est
consacrée. L'utilisateur n'est pas forcément conscient de ce qu'il
fait (d'autant plus que le texte du lien peut être trompeur, par
exemple <a href="mailto:victim@example.com">Envoyez un
message à attacker@example.net</a>
). Le RFC insiste
donc que le logiciel ne doit pas envoyer de
message en réaction à un mailto:
sans l'accord
explicite et informé (affichage du contenu complet, et des en-têtes)
de l'utilisateur. Autrement, l'utilisateur risque, sans s'en rendre
compte, d'envoyer des messages qui lui vaudront des ennuis (par
exemple parce qu'ils contiennent des menaces).
D'autre part, les URI mailto:
, étant
structurés, se prêtent bien à l'analyse et donc à la récupération
automatique. Comme cette récolte a en général pour but l'envoi de
spam, il peut être préférable de ne pas
utiliser d'URI mailto:
(c'est le cas de ce blog
pour l'adresse indiquée en bas de chaque page).
Autre problème, la section 4 met en garde contre les
en-têtes « dangereux ». Une liste indicative se trouve en section 3,
incluant par exemple les en-têtes de routage du courrier comme
Apparently-To:
.
From:
est aussi dangereux (car il permet de faire
envoyer un message qui ment sur sa source). Le RFC cite ensuite
quelques en-têtes « sûrs » : Subject:
,
Keywords:
et le pseudo en-tête
body
. Si un URI mailto:
contient des en-têtes dangereux, le navigateur ne doit pas envoyer le
message, ou alors il doit le « censurer » en ne tenant pas compte des
dits en-têtes. De toute façon, en pratique, le créateur d'un URI
mailto:
ne peut pas espérer que les en-têtes
autres que Subject:
et body
soient compris par le navigateur.
Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : M. Davis (Google), A. Phillips (Lab126), Y. Umaoka (IBM)
Pour information
Première rédaction de cet article le 8 décembre 2010
Le RFC 5646 (alias « BCP 47 » pour Best Common Practice 47), qui normalise les étiquettes de langue, prévoyait un mécanisme d'extension par le biais de sous-étiquettes d'un seul caractère. Ce RFC 6067 spécifie la première de ces extensions à rentrer en service, pour indiquer l'information de localisation du consortium Unicode.
Les étiquettes de langue sont utilisées pour
marquer du contenu sur le Web mais également en
plein d'autres endroits, afin d'indiquer la
langue utilisée. Leur norme, le RFC 5646 décrit un mini-langage permettant d'indiquer la langue
mais aussi l'écriture, le
pays, voire la variante dialectale. Ainsi,
ru-petr1708
désignera le
russe tel qu'il était écrit dans l'ortographe
de Pierre Ier, avant la réforme de 1917. Ce
langage de construction des étiquettes est très riche mais ne permet
de faire une étiquette qu'à partir de sous-étiquettes déjà
enregistrées dans le registre
des langues (ou bien à partir de sous-étiquettes purement
privées). Il n'y a notamment pas de moyen pour utiliser les catalogues
existants.
Or, un de ces catalogues est particulièrement utilisé, le catalogue
des locales décrit dans le
TR35 et géré par
le consortium
Unicode. C'est pour pouvoir l'utiliser que l'extension « u »
est créée par notre RFC. (Le singleton « u » voulant dire Unicode.) Il
permettra d'étiqueter avec davantage de précision un document. Ainsi,
en-u-cu-usd
désignera un texte en
anglais dont, grâce à l'extension « u », on
pourra savoir qu'il utilise le dollar états-unien
(usd
) comme
unité monétaire.
Les données utilisables avec cette extension proviennent du CLDR, le grand dépôt des locales géré par le consortium Unicode et qui contient des choses aussi variées que les jours fériés par pays ou bien les différents ordres de tri utilisés.
Le RFC 5646/BCP 47 (section 3.7) impose un certain nombre de règles pour la création d'une extension, notamment l'indication précise de l'autorité en charge du catalogue accessible via l'extension, et de ses politiques. La section 2 de notre RFC 6067 satisfait à cette règle en décrivant comment est géré CLDR.
Maintenant, quelle information peut-on indiquer avec l'extension
« u » ? La section 2.1 les liste en renvoyant à la section 3 du
TR35. On peut indiquer des attributs, des clés et des
types. Aujourd'hui, aucun attribut n'est défini. Les clés, elles, ont
exactement deux caractères et sont
définis par le TR35. ca
désigne un calendrier,
co
un ordre de tri, cu
la monnaie, tz
le fuseau horaire, etc. Les types sont les
valeurs associées aux clés. Ainsi, ca-coptic
désigne le calendrier copte. Une étiquette
complète comme de-DE-u-co-phonebk
sera
« l'allemand tel qu'écrit en
Allemagne, utilisant l'ordre de tri
phonebk
, i.e. celui normalisé pour
l'annuaire téléphonique (qui se nomme
phonebook
dans CLDR, qui n'a pas les mêmes
contraintes de taille) ». en-u-tz-usden
sera
l'anglais avec le fuseau
horaire
Mountain Time. Et
es-u-cu-mxn
sera
l'espagnol avec comme unité monétaire le
peso mexicain. Bien sûr, dans la plupart des
cas, il n'y aura pas besoin d'étiqueter les textes avec ce niveau de
précision. (Merci à Doug Ewell pour la plupart des exemples.) Mais certaines utilisations pourront en avoir besoin.
CLDR distribue des fichiers contenant les informations nécessaires
pour tous les types possibles en http://unicode.org/Public/cldr/
. Si vous voulez l'ordre de tri allemand,
il est en common/collation/de.xml
.
La section 2.2 du RFC contient le formulaire d'enregistrement obligatoire (RFC 5646, section 3.7) pour une extension. « u » est donc désormais le premier élément du registre des extensions..
Attention à un petit piège : les extensions comme « u » n'ont rien à voir avec les Extended Language Subtags (alias extlangs), qui sont un mécanisme (pas le seul) pour représenter des idiomes intermédiaires entre une « vraie » langue et un dialecte.
Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : Donald Eastlake 3rd (Stellar Switches)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 18 janvier 2011
Ce RFC décrit les extensions au protocole cryptographique
TLS (résumées
en section 1.1). Je n'en cite que certaines ici, lisez le RFC pour une
liste complète. Ces extensions ne changent pas le protocole : un client ou un
serveur TLS qui ne les comprend pas pourra
toujours interagir avec ceux qui les comprennent. Le serveur doit en
effet ignorer les informations contenues dans le Hello
Client
qu'il ne connait pas (section 7.4.1.2 du RFC 5246).
Le mécanisme général des extensions figure dans le RFC 5246,
notamment la section 7 de ce dernier (voir la structure en 7.4.1.2). En gros, le principe est
d'ajouter des données à la fin du paquet Hello
,
qui marque le début de la négociation TLS. Dans le langage de
spécification propre à TLS, la liste des extensions possibles est un
enum
(indiqué en section 1.1) mais elle est désormais en
ligne à l'IANA.
SNI (Server Name Indication, section 3) permet au client TLS d'indiquer au serveur le nom sous lequel il l'a trouvé. Cela autorise le serveur à présenter des certificats différents selon le nom sous lequel on y accède, fournissant ainsi une solution au problème récurrent de l'authentification avec TLS lorsqu'un serveur a plusieurs noms. À noter que SNI fonctionne avec les IDN, le RFC décrivant le mécanisme à suivre. Si le RFC 4366 permettait au client d'envoyer plusieurs noms, cette possibilité a été supprimée.
Maximum Fragment Length, section 4, permet au client d'indiquer qu'il souhaiterait des fragments de données de taille plus réduite. Cela peut être utile pour un client contraint en mémoire ou en capacité réseau, par exemple un téléphone portable. Certains de ces clients contraints apprécieront également Truncated HMAC (section 7) qui autorise à réduire la taille du MAC utilisé pour protéger l'intégrité des paquets.
Normalement, dans TLS, le certificat du client est envoyé pendant la session TLS. Mais l'extension Client Certificate URLs (section 5) permet au client d'indiquer un URL où le serveur ira chercher le certificat, allégeant ainsi le travail du client (là encore, c'est prévu pour les clients limités en puissance ou en capacité réseau). Une somme de contrôle en SHA-1 est ajoutée à la liste des URLs envoyés, pour permettre davantage de vérifications (autrement, le serveur risquerait, en cas d'empoisonnement DNS, par exemple, de récupérer un mauvais certificat). Dans le même esprit, la section 8 décrit (Certificate Status Request), une extension qui permet d'indiquer la volonté d'utiliser OSCP (RFC 6960), un protocole d'interrogation de la validité de certificats X.509 (plus léger que l'habituel téléchargement de la liste de certificats révoqués, suivi d'un traitement local).
Qui dit nouvelles extensions, dit nouvelles erreurs. La section 9
est donc consacrée aux nouveaux codes d'erreur, pour toutes les
extensions décrites. La plus évidente étant
unsupported_extension
où le client TLS
reçoit une extension qu'il n'avait pas demandé (mise dans son
Hello
). Certaines n'existaient pas dans le RFC 4366 comme
certificate_unobtainable
, utilisé si le mécanisme
de Client Certificate URLs de la section 5 n'arrive
pas à récupérer le certificat indiqué.
Tout le protocole TLS servant à la sécurité, il est normal de se
demander si les extensions en question vont avoir un effet positif ou
pas sur la sécurité. C'est ce que fait la section 11, qui examine les
points forts ou faibles de la sécurité de chaque extension. SNI ne
semble pas poser trop de problème, par contre Client Certificate
URLs fait que le serveur TLS va jouer un rôle de client
(en général, avec le protocole HTTP), ce qui
soulève des questions : le client TLS ne va t-il pas utiliser cette
extension pour pousser le serveur à attaquer un serveur HTTP, d'autant
plus que le client TLS contrôle complètement l'URL ? Ou bien le client
TLS coincé derrière un pare-feu ne va-t-il pas essayer de convaincre
le serveur TLS de récupérer quelque chose de son côté du pare-feu ? Un
serveur HTTP normalement non accessible depuis l'Internet pourrait
ainsi être indirectement attaqué, si un serveur TLS gérant cette
extension se trouve sur son réseau. Il est donc recommandé que cette
extension ne soit pas activée par défaut et seul un jeu limité de plans
d'URL soit accepté (ce dernier conseil me semble vain : le plan
http:
sera forcément sur la liste et c'est sans
doute le plus intéressant pour un attaquant).
Quant à Truncated HMAC, elle peut aboutir à affaiblir la sécurité puisque le HMAC court est forcément moins fiable. Ce n'est pas forcément très grave car une attaque par force brute contre ce HMAC ne peut pas être faite hors-ligne mais doit être exécutée pendant la session TLS et qu'une seule erreur de la part de l'attaquant coupe la session.
L'annexe A résume les changements depuis la RFC 4366. Le principal est que la RFC 4366 spécifiait à la fois un mécanisme d'extension et des extensions spécifiques. Le mécanisme d'extension ayant été mis dans le RFC 5246 (section 7.4.1.2 à 7.4.1.4), notre RFC 6066 ne contient plus que les extensions.
D'autre part, l'extension SNI a été simplifié en éliminant la possibilité de noms en UTF-8. Désormais, IDN ou pas, le nom doit être représenté en ASCII. Et le condensat cryptographique sur les certificats reçus par l'extension Client Certificate URLs est désormais obligatoire.
Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : S. Perreault (Viagenie), J. Rosenberg (jdrosen.net)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 30 novembre 2010
Le protocole TURN, qui permet à deux machines coincées derrière des routeurs NAT de communiquer en utilisant un relais tiers, a été normalisé dans le RFC 5766 (remplacé depuis par le RFC 8656), dans une version minimale, uniquement pour IPv4 et seulement pour UDP, les services « incontestables », qui étaient pressés d'avoir une solution. Depuis, des extensions à TURN sont développées pour d'autres services. C'est ainsi que ce RFC 6062 permet d'utiliser TURN pour établir des liaisons avec TCP.
TURN, tel que normalisé dans le RFC 5766, pouvait déjà utiliser TCP entre le client et le relais (le serveur). Mais, en sortie du relais, vers l'autre pair, c'était forcément de l'UDP. Cela posait un problème (section 1 du RFC) lorsque l'autre pair ne pouvait pas faire d'UDP, ou bien lorsque les propriétés de TCP (notamment de fiabilité) étaient nécessaires. Supposons un logiciel d'audio-conférence : le son est typiquement transmis en UDP (car la rapidité est préférable à la fiabilité, pour ce service) mais si on veut ajouter un système permettant aux participants de se montrer des images, TCP est certainement préférable, afin de transférer le fichier représentant l'image. Avec le protocole TURN, cela se nomme une « allocation TCP » et ce sera désormais possible, aussi bien en demandant une session TCP entrant vers un pair, qu'en acceptant une session TCP sortant d'un pair.
La section 3 rappelle le fonctionnement de TURN : le client TURN ouvre une connexion avec le serveur TURN (qui servira de relais) pour le contrôle (messages TURN, pour ouvrir et fermer des connexions). De plus, pour chaque connexion avec un pair, le client TURN aura une connexion de données pour faire passer ses données (son et image, dans l'exemple précédent), avec divers protocoles (par exemple RTP). Pour chacune de ces connexions de données, il y aura également une connexion entre le relais (le serveur TURN) et le pair avec qui on communique.
Pour avoir une allocation TCP, le client TURN va envoyer, sur la
connexion de contrôle, une requête Allocate
avec un
attribut REQUESTED-TRANSPORT
indiquant TCP. Le
serveur, s'il accepte la requête, écoutera alors en TCP. Chaque fois
qu'il voudra envoyer des donnée à un pair, le client
enverra une requête Connect
au serveur TURN et celui-ci
se connectera à son tour en TCP au pair. Enfin, le client devra ouvrir
une nouvelle connexion TCP pour les données (voir section 4.3). Une fois cette dernière
connexion établie, le relais « connectera » les deux connexions
(client->relais et relais->pair) puis relaiera les données entre les deux
pairs.
Dans le cas où le client accepte que ce soit le pair qui initie la
session, il indique d'abord au serveur qu'il accepte les connections
entrantes (requête CreatePermission
), le serveur
écoute en TCP et, établit la connexion avec le pair et, lorsque c'est
fait, signale au client que le pair est arrivé. Le client peut alors
faire une connexion TCP vers le serveur puis tout continue comme dans
le cas précédent.
Les détails pratiques figurent dans la section 4 (obligations du
client) et 5 (obligations du serveur). On notera que, pour relayer du TCP, la connexion
entre le client et le serveur doit être en TCP
(pour relayer de l'UDP, elle pouvait être en UDP ou TCP). Outre
l'attribut REQUESTED-TRANSPORT
déjà mentionné,
qui doit avoir la valeur 6 (pour TCP), le client doit prendre soin de
ne pas inclure des attributs spécifiques à UDP
comme EVEN-PORT
(qui force l'utilisation d'un
port de numéro pair, et qui n'est utile que pour UDP, voir le RFC 5766, section 14.6). TURN utilisera un attribut
CONNECTION-ID
qui sera indiqué lors de
l'acceptation d'une allocation TCP, et devra être donné par le client
lors de sa connexion TCP ultérieure, pour permettre au relais de
mettre les deux opérations en correspondance.
Le serveur, lui, doit accepter toutes les connexions TCP entrantes (section 5.3), du moment qu'une allocation a été faite (et, donc, un port réservé). Un essai avec telnet montrera donc toujours Connected to $HOSTNAME. C'est ensuite que le serveur TURN vérifie que le client avait donné la permission de se connecter. Sinon (ou si le client, bien qu'il ait donné la permission, ne se manifeste pas lorsqu'on lui signale que le pair est arrivé), la session, à peine acceptée, sera close d'autorité.
La section 6 décrit l'enregistrement à
l'IANA des nouvelles méthodes
(Connect
, ConnectionBind
et
ConnectionAttempt
), d'un nouvel attribut
CONNECTION-ID
et de nouveaux codes d'erreur 446
(déjà une connexion pour ce couple adresse/port) et
447 (échec de la connexion avec le pair) dans le registre
des paramètres STUN (rappelez-vous que TURN est défini comme
une extension de STUN).
Enfin, la section 7, sur la sécurité, met en garde contre un petit piège : entre l'acceptation d'une connexion et son branchement de l'autre côté, le relais risque de recevoir des données, qu'il doit tamponner (section 5.2). Le tampon risquant de devenir trop gros, la section 7 demande qu'une taille maximale lui soit fixée.
Une mise en œuvre se trouve dans le service de Viagénie mais ne semble pas activée à l'heure actuelle. Pour une implémentation libre, turnserver a cette option TCP depuis la version 0.4.
Merci à Simon Perreault pour sa relecture et ses remarques.
Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : S. Krishnan (Ericsson), G. Daley (NetStar Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dna
Première rédaction de cet article le 2 décembre 2010
Un engin mobile connecté à l'Internet change souvent de réseau. Il se déplace, s'attache à un autre réseau, perd le contact avec la borne WiFi, retrouve du 3G un peu plus loin et, chaque fois, il peut se retrouver sur un réseau différent, avec des paramètres différents mais aussi parfois sur un réseau déjà visité, auquel cas il peut peut-être réutiliser tout de suite des paramètres mémorisés. Il est donc nécessaire de pouvoir déterminer rapidement à quel réseau on est attaché, et si les paramètres précédents sont toujours valables. C'est le but de la méthode exposée dans ce RFC, équivalent IPv6 du RFC 4436.
Le but, comme exposé par la section 2.1, est donc de rendre la mobilité plus agréable, sans avoir à changer les routeurs, sans dégrader le service existant (par exemple, le temps de réponse ne doit jamais être pire qu'avec les méthodes actuelles), en acceptant des faux négatifs (un réseau déjà visité n'est pas reconnu) mais jamais les faux positifs (un réseau nouveau est pris à tort pour un réseau connu).
A-t-on besoin d'un nouveau protocole pour cela ? Après tout (section 2.2), il existe déjà la procédure standard de Neighbor Discovery du RFC 4861. Le nouveau Simple DNA ne sera pas une amélioration de ND dans tous les cas mais il aidera dans certains, notamment ceux où l'engin se déplace régulièrement parmi un ensemble de quelques réseaux. Si le réseau est complètement nouveau, Simple DNA n'apportera rien (mais n'aura pas d'inconvénients). De même, Simple DNA n'aidera pas pour le cas où le réseau est statiquement configuré, il ne marche qu'avec les adresses allouées par Router Advertisement (RFC 4862) ou DHCP (RFC 8415).
Simple DNA va fonctionner en interrogeant les routeurs connus pour voir s'ils sont toujours là. Une autre approche aurait été possible, en interrogeant les couches basses (section 2.3) pour voir si l'attachement au réseau n'avait pas changé (par exemple, même si le RFC ne le mentionne pas, en WiFi, on peut regarder le SSID et l'adresse MAC de la borne). Mais cette méthode aurait été moins générale.
Donc, comment fonctionne ce Simple DNA (section 2.4) ? Le fait d'être connecté à un réseau est signalé par les couches basses (Link Up en Ethernet ou WiFi). Reste à trouver à quel réseau on est connecté. Simple DNA utilise à la fois des paquets unicast Neighbor Solicitation (RFC 4861, section 7.2.2) et des paquets multicast Router Solicitation (RFC 4861, section 6.3.7) pour tester les routeurs dont il se souvient. Si aucun ne répond, Simple DNA passe aux procédures normales, Stateless address autoconfiguration ou bien DHCP. Le fait de se servir de Neighbor Solicitation permettra d'obtenir une réponse plus rapide (les routeurs ne répondent pas instantanément aux Router Solicitation).
Bien sûr, dans la réalité, tout ne se passe pas aussi bien. Simple DNA dépend de plusieurs choses, résumées par la section 2.5 : le fait que le couple {adresse MAC du routeur, adresse IP du routeur locale au lien} soit unique et le fait que les machines sont prévenues lorsque le lien physique devient fonctionnel (RFC 4957 et section 5.4 de notre RFC).
La section 4 note ensuite que la mise en œuvre complète de l'algorithme nécessite une nouvelle structure de données, la SDAT (Simple DNA Address Table). Elle va contenir la liste des routeurs déjà vus et est donc composée d'entrées indexées par le couple {adresse MAC du routeur, adresse IP du routeur locale au lien}. Elle contiendra les informations suivantes : l'information a-t-elle été obtenue par DHCP ou bien autoconfiguration sans état, adresse IP de la machine, durée de vie, préfixe utilisé, l'information a-t-elle été sécurisée par SEND, ainsi que des informations spécifiques à DHCP. Ainsi, si Simple DNA trouve qu'un réseau a déjà été visité, il a toutes les informations sous la main pour configurer immédiatement l'interface réseau.
La marche exacte à suivre de la part de la machine qui se trouve connectée est détaillée en section 5 (avec une représentation en pseudo-code en section 6). La section 5.5 décrit ainsi l'envoi des paquets de sondage (un Router Solicitation pour voir si un routeur répond, des Neighbor Solicitations pour tester les routeurs dont on se souvient, six au maximum à la fois, pour ne pas surcharger le réseau). C'est là qu'est précisé le fait que ces paquets de sondage devraient être envoyés en parallèle, pour diminuer le temps total de l'opération (et garantir ainsi que Simple DNA ne prendra jamais plus de temps qu'une méthode classique).
Le traitement des réponses est en section 5.7 : il est important que la machine vérifie que les adresses MAC correspondent bien à ce dont elle se souvient. Sinon, cela signifie que le réseau est en fait différent et qu'il faut abandonner Simple DNA pour revenir à la méthode habituelle. Naturellement, si on reçoit un Router Advertisement normal, il faut l'utiliser, quelles que soient les informations stockées dans la table SDAT.
Bien plus embêtant est le cas où les informations recueillies sont incohérentes (section 5.7.3). Par exemple, si le test d'un routeur avec le Neighbor Solicitation ne coïncide pas avec les Router Advertisement reçus. Dans ce cas, le RFC décide qu'il faut croire le Router Advertisement (sauf si SEND est utilisé). Si le conflit est entre des tests par Neighbor Solicitation et DHCP, il faut faire confiance à DHCP.
Autres recommandations, ne pas effectuer de tests de duplication d'adresses (RFC 4862, section 5.4) si on retourne à un réseau connu et ne pas insister éternellement si les Neighbor Solicitations ne ramènent pas de réponses du tout : ce cas veut sans doute dire simplement que le réseau ne marche pas.
Ah, et si on tient à faire de l'IPv4 ? La section 8 rappelle que IPv4 a aussi un système équivalent (RFC 4436) mais qui suit un algorithme très différent (IPv4 n'a pas de Router Advertisement, par exemple).
Enfin, comme avec toutes les techniques de configuration automatiques ou semi-automatiques, il y a un sérieux problème de sécurité (section 10). Les messages reçus peuvent être des faux. À part utiliser SEND (RFC 3971), il n'y a pas de solution miracle, et la seule recommandation de notre RFC est de veiller à ce que des informations non sécurisées par SEND ne remplacent pas des informations sécurisées. Autrement dit, si on avait visité un réseau qui avait un routeur SEND et, qu'en revenant sur un réseau qui semble le même, on reçoit des Router Advertisement non-SEND, il ne faut pas les utiliser. (J'ai d'ailleurs bien l'impression que, si on suit strictement les règles du RFC, on ne pourra jamais se connecter à un réseau qui avait SEND mais a choisi ensuite de l'abandonner, sauf à vider la SDAT à la main.)
Reléguée en annexe A, une dernière recommandation. Bien que le DNA de IPv4 puisse se combiner avec des adresses manuellement configurées, les problèmes que cela a soulevé (notamment pour les réseaux qui utilisaient à la fois des adresses manuelles et des automatiques) font que DNA IPv6 déconseille formellement son utilisation dans les cas où l'adresse a été fixée à la main par l'administrateur système.
Date de publication du RFC : Décembre 2010
Auteur(s) du RFC : C. Bastian (Comcast), T. Klieber (Comcast), J. Livingood (Comcast), J. Mills (Comcast), R. Woundy (Comcast)
Intérêt historique uniquement
Première rédaction de cet article le 8 décembre 2010
Pour tout FAI, la gestion de la congestion est un problème récurrent. Même avec de très gros tuyaux, les utilisateurs, avides de profiter de leur abonnement à l'Internet (et poussés par des évolutions comme le remplacement de cours sous forme texte par des conneries multimédia genre webinar), envoient de plus en plus de paquets. Beaucoup de FAI, lors de débats sur la neutralité du réseau défendent leur droit à « gérer la congestion » par tous les moyens, même les plus inavouables. C'est ainsi que l'un des plus gros FAI états-uniens, Comcast, s'est rendu célèbre en usurpant l'adresse IP de ses propres abonnés pour couper leurs sessions BitTorrent fin 2007. Ces méthodes de cow-boys ont suscité beaucoup de protestation et, dans ce RFC, Comcast annonce un changement de cap et l'adoption d'un nouveau système de gestion de la congestion, neutre (protocol agnostic car « neutre » est un gros mot pour les FAI) et fondé sur des mesures objectives (le nombre d'octets envoyés ou reçus). Ce système est mis en œuvre dans le réseau de Comcast depuis la fin de 2008.
Comcast, qui connecte des dizaines de
millions de foyers états-uniens, notamment par le
câble (des détails sur leur réseau figurent en
section 7), s'est donc fait allumer par la
FCC au sujet de ses curieuses pratiques de
gestion du réseau, qui consistaient à générer, depuis un boîtier
Sandvine, des faux paquets
TCP de type RST
(Reset) prétendant venir des pairs, de manière à
couper les sessions pair-à-pair (voir le rapport très détaillé de l'EFF ou son résumé à Ars Technica). Ce mécanisme
visait, de manière complètement arbitraire, un protocole réseau
particulier, BitTorrent.
La section 1 du RFC resitue le problème de la congestion. TCP est un protocole gourmand : tant qu'il n'y a pas de perte (cf. RFC 7680) de paquets, il va augmenter le débit jusqu'à ce que le réseau ne puisse plus suivre et le signale en laissant tomber certains paquets (TCP réduira alors le débit). La congestion est donc un état normal du réseau (sinon, cela veut dire qu'il est sous-utilisé).
Le mécanisme déployé étant spécifique au réseau de Comcast, il est
utile, pour suivre le RFC, de bien apprendre la section 3 sur la
terminologie, notamment si on n'est pas habitué aux réseaux par
câble TV coaxial. Ainsi, un modem
câble est le CPE, l'engin placé
chez le client, et un CMTS
(Cable Modem Termination System, cf. section 2.6 du
RFC 3083) est l'équipement
situé dans les locaux du FAI où sont connectés les clients
(à peu près l'équivalent d'un DSLAM pour les
FAI ADSL). Le tout fonctionne grâce à la norme
DOCSIS dont les documents sont disponibles en
http://www.cablelabs.com/
. D'autre part, la rubrique
terminologique en section 3 référence également les RFC sur la
qualité de service, les RFC 1633 et
RFC 2475.
Le nouveau système de contrôle de la congestion a évolué, comme le résume la section 4, en partie en suivant les débats à l'IETF comme l'atelier de 2008, qui a été documenté dans le RFC 5594. La contribution de Comcast à cet atelier consistait en un document « Service Provider Perspective ». Le système décrit par Comcast à l'occasion de cet atelier (et qui avait été également présenté dans les réponses de Comcast à la FCC, qui était mécontente du système de piratage des sessions BitTorrent) a été progressivement déployé à partir de la fin de 2008.
En quoi consiste ce système de contrôle de la congestion ? La section 5 résume ses principes. Plusieurs éléments du réseau étant partagés, le but du système est de partager « équitablement » ces éléments (le terme « équitablement » est entre guillemets dans le RFC car il n'est pas évident d'en donner une définition rigoureuse). D'autre part, le système actuel est agnostique (le RFC aurait pu dire « neutre » mais la plupart des FAI ne veulent pas entendre parler du concept de neutralité), c'est-à-dire qu'il ne cible pas un protocole particulier, il tient juste compte d'un facteur objectif : le débit de la ligne de l'abonné. L'algorithme (simplifié) est donc le suivant : le logiciel surveille en permanence l'usage des ressources réseau. Si l'une de celles-ci devient congestionnée, le logiciel regarde quel client sur cette ressource consommait plus que les autres et lui affecte une priorité plus basse. Cela n'aura pas de conséquence pratique si les lignes ont de la capacité suffisante mais, si la congestion empêche de faire passer tous les paquets, ceux de ce(s) client(s) seront retardés, voire jetés (cela peut sembler violent mais c'est le mécanisme normal d'IP pour gérer la congestion ; les protocoles de transport savent réagir à ce problème, par exemple TCP réduit automatiquement son débit). Si le client diminue son usage, sa priorité redevient normale.
Ne serait-ce pas préférable, en cas de congestion, d'augmenter la capacité du réseau ? Certes, dit la section 6, mais le problème est plus compliqué que cela. D'abord, l'ajout de capacité nécessite souvent des travaux matériels, qui prennent du temps. Ensuite, quelle que soit la capacité du réseau, il y aura des pics de trafic imprévus et aucun réseau ne peut être assez dimensionné pour éviter complètement la congestion. (De même qu'aucun autoroute ne peut être assez large pour un samedi 1er août.) Pouvoir gérer la congestion est donc une nécessité.
Quelles sont les valeurs numériques exactes utilisées pour des opérations comme « abaisser la priorité » ? L'abaisser de combien ? Et que veut dire exactement « proche de la congestion » ? 90 % 95 % ? La section 7 du RFC traite de l'implémentation concrète des principes de la section 5. Elle commence par un excellent résumé de l'architecture du réseau de Comcast, où 3 200 CMTS servent environ 15 millions d'utilisateurs. Le réseau, comme illustré dans la figure 1 du RFC, est en fait mixte, les CMTS étant connectés en fibre optique, seul le dernier mile étant en câble de cuivre coaxial. La section 7.1 définit ensuite rigoureusement la métrique utilisée pour déclarer qu'un CMTS approche de la congestion. Ensuite, la valeur numérique a été déterminée par des essais en laboratoire : aujourd'hui 70 % d'utilisation en montée et 80 % en descente pendant 5 minutes de suite. La section 7.2 traite de la seconde partie de l'algorithme : définir ce que signifie, pour un utilisateur, « consommer plus que sa part ». (Les chiffres exacts dépendent de l'abonnement qu'il a souscrit : les riches ont plus que les pauvres.)
Ce RFC n'hésite pas devant les chiffres précis. Ainsi, un exemple donné est celui d'un abonné à un service à 22 Mb/s descendants. Malgré plusieurs usages simultanés (un flux vidéo HD depuis Hulu à 2,5 Mb/s, un appel Skype à 131 kb/s, et un flux musical à 128 kb/s), il reste en dessous de la limite. L'idée est donc que beaucoup d'utilisations, même multimédia, n'amèneront pas à la limite. Lors de tests avec de vrais utilisateurs, par exemple à Colorado Springs en 2008, 22 utilisateurs sur 6 016 ont été « déprioritisés ». Lors de tels tests, quel a été le ressenti des utilisateurs ? La section 7.3 note simplement que personne ne s'est plaint.
La section 9 argumente même que ce mécanisme, prévu pour gérer la minorité la plus gourmande des utilisateurs, est aussi utile en cas de congestion plus globale. Par exemple, si une brusque épidémie de grippe se développe, forçant l'arrêt des transports publics et amenant de nombreuses entreprises à fermer, le télétravail depuis la maison va brusquement augmenter. Le réseau tiendra-t-il ? En tout cas, le même mécanisme de gestion de la congestion peut être utile.
Rien n'étant parfait en ce bas monde, quelles sont les limites de ce système ? La section 10 en cite quelques unes. Entre autres, le mécanisme de Comcast ne signale pas à l'utilisateur qu'il a été déprioritisé. Cela empêche ses applications de s'adapter (par exemple en basculant vers une résolution vidéo plus faible) et l'utilisateur de changer son comportement.
D'autres mécanismes de contrôle de la congestion pourraient apparaître plus tard, par exemple issus des travaux de l'IETF, que la section 11 résume. Des groupes de travail comme Conex (signalisation explicite de la congestion), Alto (recherche du meilleur pair dans un réseau pair-à-pair) ou Ledbat (transfert de grosses quantités de données en arrière-plan, en se glissant dans les moments où le réseau est libre) produiront peut-être des solutions meilleures (voir le RFC 6817 pour Ledbat).
Enfin, la section 12, sur la sécurité, est une lecture intéressante : à chaque fois qu'on construit un tel appareillage, il faut se demander s'il ne risque pas d'être mal utilisé. Ici, la principale crainte est le risque d'injection de fausses données, pour bloquer les utilisateurs (une attaque par déni de service). Les équipements de statistiques doivent donc être protégés contre un accès non autorisé. Moins grand est le risque pour la vie privée : si le trafic par modem (donc par foyer) est stocké, cela n'inclut pas les adresses IP de destination, les ports, etc.
Arrivé au terme de ce très intéressant document, très détaillé (il faut noter qu'aucun FAI dans le monde n'a fait un tel effort de documentation, comparez par exemple avec le silence complet que maintient Free face aux accusations de shaping), quel bilan tirer ? D'abord, que les protestations des clients, de l'EFF et les menaces de la FCC ont eu un effet positif. Ensuite, je pense personnellement que le système est bon dans son principe. Face à la congestion, un problème auquel peut être confronté tout réseau, quelles que soient les dimensions de ses tuyaux, il est nécessaire de prendre des mesures. Celles-ci doivent être publiquement exposées (et, on l'a dit, Comcast est le seul à le faire) et être non-discriminatoires, fondées sur des problèmes objectifs (le débit dans les tuyaux) et pas sur les intérêts financiers du FAI (comme les opérateurs 3G qui interdisent la VoIP mais qui autorisent la vidéo ; cette dernière consomme pourtant bien plus de ressources mais, elle, elle n'empiète pas sur le business traditionnel de l'opérateur...). Donc, le principe du système de gestion de la congestion de Comcast est bon. Maitenant, tout est dans l'exécution en pratique. Le système effectivement déployé est-il celui décrit ? Les évolutions futures respecteront-elles les principes posés ? Poser la question n'est pas de la paranoïa. Comcast a déjà menti, par exemple en niant la création de faux TCP resets même si la section 8 du RFC reconnait aujourd'hui leur usage (cf. RFC 3360). Le lecteur des aventures de Thursday Next pensera certainement au tome 4, « Something rotten », où la tentaculaire société Goliath tente de faire croire qu'elle est devenue une église n'agissant plus que pour le bien commun...
Ce RFC a été reclassé « intérêt historique seulement » en août 2020, Comcast n'utilisant plus ce système.
Date de publication du RFC : Janvier 2011
Auteur(s) du RFC : M. Larsen (TietoEnator), F. Gont (UTN/FRH)
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 18 janvier 2011
Lorsqu'un méchant attaquant tente de s'infiltrer dans une conversation en TCP, par exemple pour la couper ou la ralentir, il doit, soit être sur le trajet des paquets et pouvoir les regarder soit, dans le cas le plus fréquent, celui d'une attaque en aveugle, deviner un certain nombre d'informations qui « authentifient » la connexion TCP. Parmi celles-ci, le port source est trop souvent trop facile à deviner. Notre RFC expose pourquoi et surtout comment rendre ce port source plus dur à trouver.
De manière plus rigoureuse : lors d'une attaque en aveugle (où le méchant n'est pas en position de sniffer les paquets de la connexion TCP), les paquets mensongers injectés par le méchant ne seront acceptés par la machine victime que si le penta-tuple {Adresse IP source, Adresse IP destination, Protocole, Port Source, Post Destination} est correct (cf. RFC 5961 et RFC 5927). Pour la sécurité de TCP face à ces attaques en aveugle, il vaut donc mieux que ce tuple soit caché. Mais une partie est triviale à deviner (par exemple, pour une connexion BGP, le port de destination sera forcément 179 dans un sens et, dans l'autre, ce sera le port source). Il faut donc faire porter l'effort sur les autres parties, en essayant de les rendre le moins prévisibles possible. Une telle protection fonctionnera aussi bien avec les attaques par TCP lui-même que en passant par ICMP.
Bien sûr, cela ne remplace pas une bonne protection cryptographique des familles mais le moins qu'on puisse dire est qu'IPsec est laborieux à déployer et le but de notre RFC est de fournir une solution aujourd'hui. Il est à noter que les mécanismes de ce RFC peuvent être déployés unilatéralement et ne changent pas les protocole de transport (il n'est d'ailleurs pas spécifique à TCP ; ainsi, le DNS, protocole qui tourne surtout sur UDP, a dû déployer des techniques analogues, notamment en réponse à la faille Kaminsky ; voir le RFC 5452).
La section 1 du RFC résume ce problème (voir aussi les RFC 4953, RFC 5927 et RFC 5961). Dans un protocole client-serveur, le protocole est souvent déterminé par l'application (BGP ne peut tourner que sur TCP), le port de destination est souvent fixe (80 pour HTTP), les adresses IP des serveurs en général connues. L'adresse IP du client n'est pas en général secrète (pour BGP, les adresses IP de tous les participants à un point d'échange sont un secret de Polichinelle). Il ne reste donc que le port source pour empêcher l'attaquant de fabriquer des faux paquets qui seraient acceptés. Certes, stocké sur 16 bits, il ne peut stocker, dans le meilleur des cas, que 65 536 valeurs différentes mais c'est mieux que rien. L'idée n'est pas de fournir une protection absolue mais simplement de rendre la tâche plus pénible pour l'attaquant.
Et, justement, il existe des moyens de faire varier ce port source de manière à rendre difficile sa prédiction par l'attaquant. Cela ne vaut pas des techniques comme l'authentification TCP du RFC 5925 mais c'est déjà un progrès pour la sécurité. En dépit du titre du RFC, il ne s'agit pas de rendre le port source réellement mathématiquement aléatoire mais simplement plus dur à deviner.
Place maintenant à l'exposé des méthodes. Juste un peu de vocabulaire : une « instance » est une communication identifiée par un penta-tuple (c'est équivalent à une connexion pour les protocoles de transport à connexions comme TCP). L'« ID » d'une instance est simplement le penta-tuple {Adresse IP source, Adresse IP destination, Protocole, Port Source, Post Destination}.
Il y a port et port. La section 2 explique
le concept de « port temporaire ». Pour chaque protocole
(TCP, UDP ou autre), les
65 536 valeurs possibles pour les ports se répartissent en « ports bien
connus » (jusqu'à 1023 inclus), « ports enregistrés » (jusqu'à 49151
inclus) et « ports dynamiques et/ou privés » (le reste). Normalement,
une application de type client/serveur se connecte à un « port bien
connu » (parfois à un « port enregistré ») et utilise comme port
source un port temporaire pris parmi les ports dynamiques. Pour que
l'ID d'instance soit unique (sinon, il ne jouerait pas son rôle), une
mise en œuvre simple est d'avoir une variable par protocole,
mettons next_ephemeral
, qui indique le prochain
port libre et est incrémentée à chaque connexion. L'algorithme est en
fait un peu plus compliqué que cela (section 2.2) car il faut tenir compte des
ports déjà en service, et de ceux que l'administrateur système a
manuellement interdit (par exemple, dans le serveur DNS
Unbound, la plage de ports à utiliser se
configure avec outgoing-port-permit
et
outgoing-port-avoid
, dans son concurrent
BIND, avec
use-v6-udp-ports
et
avoid-v6-udp-ports
; autre exemple, dans
FreeBSD, la fonction
in_pcblookup_local()
vérifie les ports
utilisés).
Mais le principal problème de cet algorithme simple est que le port source choisi pour la communication est facile à deviner. Si l'attaquant gère un serveur auquel le client se connecte, il lui suffit de regarder le port utilisé, d'ajouter un, et il saura le port utilisé pour la connexion suivante. Il pourra alors monter facilement les attaques décrites dans les RFC 4953 et RFC 5927.
Avant de trouver une solution à ce problème de prédictibilité, il faut se pencher sur le problème des collisions entre ID d'instances. Même si le client fait attention à utiliser un penta-tuple qui n'est pas en service de son côté, il peut parfaitement choisir un port source qui correspondra à un penta-tuple encore en activité de l'autre côté. En effet, l'autre côté doit garder la connexion (et donc le penta-tuple) en mémoire jusqu'à être sûr que plus aucun paquet IP n'est encore en route et, si le client est très actif (ouvre de nouvelles connexions souvent), le risque de tomber sur un penta-tuple encore en activité est élevé. Cela peut alors entraîner les problèmes décrits dans le RFC 1337. Choisir le prochain port de manière incrémentale, comme dans l'algorithme exposé plus haut, minimise le risque, puisqu'on ne réutilisera un port qu'après que toute la plage possible ait été épuisée.
Comment faire alors ? Faut-il choisir entre la sécurité qu'apportent une sélection non-linéaire du port source à utiliser et le sécurité par rapport aux collisions d'ID d'instances ? La section 3 expose plusieurs méthodes pour rendre le prochain port source plus difficile à prédire pour un attaquant. D'abord, qu'attend t-on d'un algorithme d'embrouillage du choix du port ? On voudrait à la fois qu'il rende la prédiction difficile pour l'attaquant, qu'il minimise le risque de collision d'ID, et qu'il ne marche pas sur les pieds des applications qui sont configurées pour un port précis (par exemple un serveur SSH qui écouterait sur le port 4222). Un algorithme qui assurerait la première fonction (rendre la prédiction difficile) pourrait, par exemple, être de tirer au hasard le prochain port utilisé. Mais les deux autres fonctions en souffriraient... N'imposons donc pas un vrai tirage aléatoire et voyons les compromis raisonnables. Le premier algorithme présenté, celui qui incrémente le numéro de port de un, a les problèmes inverses (il minimise la réutilisation mais maximise la prédictibilité).
On l'a vu, la plage des ports temporaires allait traditionnellement de 49152 à 65535. Mais elle est trop étroite pour assurer une vraie inprédictibilité du port source et la section 3.2 demande donc que, par défaut, la plage utilisée par les algorithmes de choix aille de 1024 à 65535. Comme cette plage inclus des ports réservés à l'IANA, l'algorithme de choix doit donc faire attention à ne pas sélectionner des ports qui sont utilisés sur la machine locale (ou qui pourraient l'être).
Place maintenant aux algorithmes effectifs. La section 3.3 décrit
successivement les différents algorithmes possibles, avec du
pseudo-code proche du C pour leur implémentation. L'algorithme 1,
en section 3.3.1, est celui de simple tirage au hasard de la variable
next_ephemeral
à chaque utilisation. Si le port
sélectionné n'est pas utilisable (par exemple parce qu'un serveur
écoute déjà sur ce port), on essaie le suivant, puis le suivant etc. Attention,
si on veut qu'il soit efficace, il faut que le générateur aléatoire le
soit réellement (cf. RFC 4086). La traditionnelle
fonction random()
, dans la plupart
des cas, ne l'est pas. Comme cet algorithme 1 n'a pas de mémoire, il
peut sélectionner un port qui avait été utilisé récemment, augmentant
ainsi les risques de collision des ID d'instances. En outre, il a une
autre faiblesse : s'il existe une longue plage de ports déjà utilisés,
et que le tirage au hasard fait tomber dans cette plage, le port situé
immédiatement après la plage sera très souvent sélectionné, ce qui
augmente la prévisibilité.
L'algorithme 2, en section 3.3.2, améliore l'algorithme 1 en tirant au hasard, non seulement le port initial, mais aussi l'incrément à utiliser si le port initial n'est pas libre. Il est donc le moins prévisible mais, en cas d'extrême malchance, il peut échouer à trouver un numéro de port, même s'il y en a un de libre.
L'algorithme 3 (section 3.3.3, inspiré du mécanisme décrit par
Bellovin dans le RFC 6528) renonce à utiliser un générateur
aléatoire et repose au contraire sur un condensat des paramètres de l'instance (adresses
IP, etc). Prenons une fonction F qui reçoit les deux adresses IP, le
numéro de port de l'autre partie et une clé secrète et les condensent
en un nombre qui sera l'incrément appliqué à la variable
next_ephemeral
. En dépendant des paramètres de
l'instance, on minimise la réutilisation des ID d'instances. On peut
d'ailleurs ajouter d'autres paramètres comme, sur un système
multi-utilisateurs, le nom de l'utilisateur. Cette fonction F doit évidemment être une fonction
de hachage cryptographique comme MD5 (RFC 1321). Certes, MD5 a aujourd'hui des faiblesses
cryptographiques connues mais il ne s'agit que de rendre le prochain
port imprévisible, tâche pour laquelle il suffit. La clé secrète,
elle, est ici pour empêcher un attaquant qui connaitrait la fonction
de hachage utilisée de faire tourner le même algorithme et de prédire
ainsi les numéros de port. Elle est typiquement choisie aléatoirement
au démarrage de la machine.
L'algorithme 3 peut être perfectionné en ajoutant un second
condensat, qui servira à indexer une table des variables
next_ephemeral
(au lieu d'avoir une variable
unique). C'est l'algorithme 4, présenté en section 3.3.4.
Enfin, le dernier algorithme, le numéro 5 (section 3.3.5) choisit
l'incrément de next_ephemeral
au hasard mais
l'applique ensuite de manière déterministe, ce qui limite les risques
de collision d'ID puisque le numéro de port utilisé augmente à chaque
fois (et repart une fois arrivé au bout). Notez le rôle du paramètre N
(dont le RFC dit qu'il devrait être configurable) pour déterminer si
on utilise de petits incréments (plus prévisibles mais diminuant les
risques de collision) ou des grands (avec les avantages et les
inconvénients renversés).
Certains de ces algorithmes dépendent d'une clé secrète, choisie au hasard. Comment choisir celle-ci ? La section 3.4 qu'elle doit être assez longue (128 bits sont recommandés). Elle suggère aussi de changer cette clé de temps en temps. Mais attention : juste après le changement, le risque de collision va augmenter.
On l'a vu, il existe plusieurs algorithmes acceptables pour
atteindre notre objectif de sélection de numéros de port peu
prévisibles. Lequel choisir ? La section 3.5 est une évaluation
comparée desdits algorithmes, basée sur le très bon article de Mark Allman,
« Comments On Selecting Ephemeral
Ports », publié dans ACM
Computer Communication Review, 39(2), 2009. Tous ces
algorithmes évitent les collisions de manière satisfaisante (moins de
0,3 % des cas mais le chiffre exact dépend de beaucoup de choses,
comme le rythme d'ouverture et de fermeture des nouvelles connexions).
L'étude empirique d'Allman montre que les algorithmes 1 et 2, les
seuls réellement aléatoires sont aussi, comme attendu, ceux qui
montrent le plus de collisions d'ID d'instances. Les algorithmes 3 et
surtout le 4 sont ceux qui imposent la plus grande consommation de
ressources machines (calcul du condensat cryptographique et, pour le
4, consommation de mémoire pour la table). À noter enfin que, dans
certains systèmes d'exploitation et certaines applications (celles qui appellent
bind()
sans indiquer de numéro de
port), les algorithmes 3 et 4 ne sont pas utilisables car l'adresse IP
et le port distant ne sont pas connus au moment où on sélectionne
le port local et la fonction de hachage ne dispose donc pas d'assez
d'arguments. Le système d'exploitation doit alors se rabattre sur un
algorithme comme le 2 ou bien effectuer un bind()
paresseux en retardant l'allocation effective du port local jusqu'au
moment où la connexion est réellement faite (avec, par exemple,
connect()
). C'est par exemple ce que
fait Linux. (Pour l'anecdote, ce point avait été ma contribution à ce RFC, en 2008, au début du processus d'écriture.)
De nos jours, un grand nombre de machines sont coincées derrière un routeur NAT ou plus exactement NAPT (Network Address and Port Translation, RFC 2663) qui utilise les numéros de ports pour démultiplexer le trafic entre les différentes machines du réseau local. Comme l'explique la section 4, les techniques d'obscurcissement du prochain numéro de port peuvent être alors prises en défaut si le routeur NAPT change ces ports par d'autres, choisis de manière trop prévisible. Le RFC impose donc que le routeur NAT, soit conserve les numéros de port (RFC 4787 et RFC 5382), soit choisisse lui-même les ports selon un mécanisme non prévisible.
Une fois les algorithmes exposés, compris et analysés, la section 5 reprend à nouveau de la hauteur pour parler d'une approche générale de la sécurité. D'abord, elle rappelle qu'un attaquant qui n'est pas aveugle, qui peut sniffer le réseau où passent les paquets, se moque des algorithmes exposés ici puisqu'il peut lire directement le numéro de port dans les paquets. Dans ce cas, il n'y a pas d'autre solution que des protections cryptographiques comme celles du RFC 4301.
Plus rigolo, certains choix pour la liste des ports exclus peuvent poser de sérieux problèmes de sécurité. Ainsi, si un système d'exploitation prend comme liste de ports à éviter la totalité de la liste IANA, il ne doit pas utiliser l'algorithme 1 car les ports qui se trouvent immédiatement après la liste réservée seront sur-représentés.
Comment est-ce mis en œuvre en pratique ? L'annexe A du RFC précise les choix effectués par les principaux systèmes d'exploitation libres (pour les autres, on ne sait pas s'ils sont sûrs puisqu'on ne peut pas examiner le source). Ainsi, Linux utilise l'algorithme 3, avec MD4 comme fonction de hachage (même si le RFC dit que c'est MD5). Sur un Linux 2.6 de septembre 2010, le code se trouve (de haut en bas, dans l'ordre des appels successifs), en indiquant fichier-source:fonction :
net/ipv4/inet_hastables.c:inet_hash_connect
(qui utilise
net/ipv4/inet_connection_sock.c:inet_get_local_port_range
pour récupèrer
auprès de sysctl les ports utilisables),net/ipv4/inet_hastables.c:inet_sk_port_offset
,drivers/char/random.c:secure_ipv4_port_ephemeral
qui fait le hachage des paramètres indiqués par l'algorithme 3
(adresses et ports).FreeBSD, OpenBSD et
OpenSolaris utilisent l'algorithme 1. La séquence des appels est (dans le HEAD
du CVS de FreeBSD en octobre 2010) :
in_pcbconnect
,in_pcbconnect_setup
,in_pcbbind_setup
(qu'on peut voir, si on n'a pas les sources sur sa machine, en http://fxr.watson.org/fxr/source/netinet/in_pcb.c?im=bigexcerpts#L325
).Merci à Benoit Boissinot pour son aide dans la navigation dans le source de FreeBSD.
Une petite anecdote historique pour terminer : la prédiction correcte des numéros de série des tanks allemands pendant la Seconde Guerre mondiale a permis aux Alliés de calculer le nombre de tanks ennemis. Comme quoi, toute information trop régulière et prévisible peut être exploitée par l'ennemi.
Date de publication du RFC : Février 2011
Auteur(s) du RFC : D. Thaler (Microsoft), J. Klensin, S. Cheshire (Apple)
Pour information
Première rédaction de cet article le 22 février 2011
Ce RFC de l'IAB fait
le point sur un petit problème lié aux IDN,
problème qui, semble t-il, n'avait jamais été traité en détail
avant. La norme actuelle (RFC 5890 et suivants)
est connue sous le nom d'IDNA pour IDN
in Applications car elle ne change rien au
protocole et que tout le travail doit être fait
dans l'application. Toutefois,
«application » est un terme un peu vague. Par exemple, un programme
écrit en C doit-il convertir le
U-label (forme Unicode du
nom) en A-label (forme
ASCII) avant l'appel à la fonction de
bibliothèque getaddrinfo()
? Ou bien
est-ce que getaddrinfo()
doit le faire seul ?
(Pour les impatients, la réponse, qui arrive au terme d'un long RFC,
est que l'application ne doit pas convertir en
Punycode avant d'être certaine que la résolution
de noms se fera avec le DNS, dans l'espace public.)
Les deux méthodes mènent en effet à des résultats différents dès
qu'un autre protocole que le DNS est utilisé
pour la résolution de nom. En effet, contrairement à ce qu'on lit
parfois, l'appel de getaddrinfo()
n'est pas un
appel au DNS mais aux mécanismes de résolution de nom locaux. Par
exemple, sur un système d'exploitation qui utilise la GNU
libc comme Debian, le mécanisme se
nomme NSS (pour Name Service
Switch) et le fichier
/etc/nsswitch.conf
permet de le configurer. Si
ce fichier contient une ligne comme :
hosts: files ldap dns
alors, un appel à getaddrinfo()
par une
application qui veut récupérer l'adresse IP
correspondant à un nom de domaine ne produira
pas forcément une requête DNS, le nom sera peut-être trouvé dans
/etc/hosts
ou dans LDAP
d'abord. Dans ce cas, traduire le nom en ACE
(ASCII compatible encoding, c'est-à-dire traduire palais-congrès.fr
en
xn--palais-congrs-7gb.fr
, selon le RFC 3492) serait une erreur car LDAP, par exemple,
est nativement Unicode depuis le début et n'a nul besoin de l'ACE.
La section 1 du RFC rappelle la terminologie, les textes de
référence (comme le RFC 2130) et les concepts,
notamment la notion d'encodage. Elle rappelle aussi que des opérations
aussi simples que l'égalité sont plus complexes en Unicode
qu'en ASCII. Cette même section revient sur la question des
API, résumée plus haut. La lecture du RFC 3490 pourrait faire croire à l'implémenteur d'IDN
que la situation est simple (figure 1 du RFC) avec l'application
parlant au stub resolver DNS qui parle à
l'Internet. La réalité est en fait plus riche comme le montre la
figure 2, avec un niveau d'indirection supplémentaire entre le
sous-programme appelé par l'application (par exemple
getaddrinfo()
, normalisé dans le RFC 3493) et les techniques de résolution
utilisées, le DNS mais aussi LLMNR (RFC 4795), Netbios (RFC 1001), /etc/hosts
(RFC 952),
etc.
Tiens, justement, ces API, elles prennent
des noms de domaine sous quelle forme ? UTF-8 ?
Punycode ? Autre ? La section 1.1 se penche sur
ce problème. La description de
getaddrinfo()
dit juste que le nom
(le paramètre nodename
)
est un char *
, une chaîne de caractères, sans
indiquer d'encodage. Les règles des chaînes de
caractères en C font que l'octet nul ne peut
pas en faire partie, ce qui élimine des encodages comme
UTF-16 et UTF-32. En
pratique, le nom passé peut être de l'ASCII
(c'est le cas s'il a été traité par Punycode),
de l'ISO 8859, du
ISO-2022-JP (très répandu au
Japon) ou de l'UTF-8. On
peut noter qu'il est possible de distinguer algorithmiquement certains de ces
différentes encodages avec des règles comme « Si le nom comporte un
ESC, U+001B, alors, c'est de l'ISO-2022-JP,
sinon si n'importe quel octet a un bit de poids fort à un, c'est de
l'UTF-8, sinon, si le nom commence par xn--
,
c'est du Punycode, sinon enfin c'est de l'ASCII traditionnel. » Ces
règles ne sont pas parfaites (celle-ci ne tient pas compte des ISO 8859, d'autre part un nom ASCII traditionnel peut
théoriquement commencer
par xn--
sans être un A-label)
et on peut préférer des règles plus sophistiquées comme celle exposée
dans « The
Properties and Promizes of UTF-8 ». Quant à
ISO 8859, c'est le plus ennuyeux, car il n'y a
aucun moyen fiable de reconnaître un membre du jeu ISO 8859 d'un
autre. Dans un texte long, des heuristiques sont possibles mais les
noms de domaines sont trop courts pour fournir assez d'information
pour distinguer, par exemple, ISO 8859-1 de
ISO 8859-15.
Enfin, il n'y a
pas que le getaddrinfo()
du RFC 3493, il y a d'autres sous-programmes comme, sur Windows,
GetAddrInfoW
qui accepte de l'UTF-16.
Tout cela, c'était pour expliquer que des sous-programmes de
résolution de noms comme getaddrinfo()
ne
reçoivent pas toujours assez d'information pour savoir ce qu'ils
doivent faire. L'autre moitié du problème est décrit dans la section
2 : il y a d'autres protocoles de résolution que le DNS. Par
exemple, la technologie privée d'Apple,
Bonjour, a des noms entièrement en
UTF-8 (ce qui est conforme aux recommandations
du RFC 2277). Une application qui traduirait les
noms Unicode en ACE empêcherait donc Bonjour de
trouver la machine portant ce nom. Même chose avec les autres
protocoles comme le fichier hosts
(RFC 952. Ainsi, si je mets dans mon /etc/hosts
sur Unix :
64.170.98.32 café-crème
je peux l'utiliser sans problème :
% ping -c 1 café-crème PING café-crème (64.170.98.32) 56(84) bytes of data. 64 bytes from café-crème (64.170.98.32): icmp_req=1 ttl=70 time=155 ms --- café-crème ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 155.568/155.568/155.568/0.000 ms
Traduire trop tôt est donc une méthode déconseillée : la traduction en ACE devrait se faire bien plus tard, lorsqu'on connait le protocole de résolution employé. Et cela ne peut pas se faire dans l'application à proprement parler, puisqu'elle ne connait jamais ce protocole.
D'ailleurs, puisque des protocoles comme LDAP utilisent Unicode de bout en bout, pourquoi le DNS n'en fait-il pas autant ? La section 3 décrit ce problème (voir aussi mon article « Pourquoi avoir développé IDNA au lieu d'utiliser directement l'Unicode dans le DNS ? »). Elle rappelle que, contrairement à ce que disent souvent les ignorants, le DNS est parfaitement capable, depuis le début, de faire passer autre chose que l'ASCII, a fortiori autre chose que le sous-ensemble LDH (Letters, Digits and Hyphen) de l'ASCII. Cette erreur est tellement répandue qu'il a fallu, en 1997, consacrer une part du RFC 2181 (section 11) à tordre le coup à cette idée. Le DNS peut donc gérer des octets où le huitième bit est à un et donc, par exemple, des noms en UTF-8 (il n'est donc pas en contradiction avec le RFC 2277 qui pose comme principe que UTF-8 est l'encodage Unicode de l'Internet). Il y a des raisons techniques pour ne pas utiliser UTF-16 ou UTF-32 (présence d'octets nuls qui pertuberaient les bibliothèques écrites en C pour lesquelles c'est une marque de fin de chaîne) mais UTF-8 ne pose pas de problème. En prime, UTF-8 est un sur-ensemble d'ASCII, toute chaîne ASCII est forcément une chaîne UTF-8, ce qui fait qu'une application peut tout traiter comme de l'UTF-8, même les noms existants.
Donc, le DNS ne pose pas de restrictions ASCII ou LDH. Par contre, les applications peuvent, elles, en imposer. Ainsi, pour le Web, l'ancienne norme des URI, le RFC 2396 (remplacé depuis par le RFC 3986), limitait (dans sa section 3.2.2) le nom de machine présent dans l'URL au jeu LDH (lettres, chiffres et tiret). C'est en raison de cette limitation (présente dans d'autres protocoles) que beaucoup de registres n'autorisent que ces noms à l'enregistrement.
Si le DNS n'est pas limité à l'ASCII, pourquoi ne pas faire des IDN uniquement en mettant carrément de l'UTF-8 dans les noms ? Certes, la représentation des chaînes de caractères dans le DNS ne permet pas d'indiquer l'encodage utilisé mais, après tout, le RFC 2277 dit clairement que, sur l'Internet, en l'absence de mention contraire, tout est en UTF-8. Cette méthode a effectivement été utilisée dans certaines zones, notamment privées (non visibles depuis l'Internet public). Elle marche : l'application passe de l'UTF-8 au résolveur qui la transmet aveuglément au DNS, qui sait répondre à ces requêtes. Le principal problème de cette méthode (et qui est à peine esquissé dans notre RFC 6055) est la canonicalisation. Le fait que les requêtes DNS soient insensibles à la casse ne marche pas pour l'Unicode, où les règles sont bien plus complexes (pensons au ß allemand dont la majuscule comprend deux lettres, SS, voir le RFC 5198 pour un point de vue plus large). C'est cette absence d'une canonicalisation satisfaisante (qui affecte également les autres protocoles comme LDAP), bien plus qu'une soi-disant incapacité du DNS à gérer l'Unicode, qui explique pourquoi l'actuelle norme IDN n'utilise pas UTF-8.
Parmi les autres surprises que nous réserve la résolution de noms,
la section 3 note aussi que le nom actuellement résolu n'est pas
forcément celui tapé par l'utilisateur. Il est en effet fréquent que
le nom tapé soit complété par des noms de domaines locaux. Par
exemple, sur Unix, le fichier /etc/resolv.conf
contient souvent une directive
search qui indique les noms « suffixes » à essayer (voir la
section 6 du
RFC 1536, le RFC 3397 et la section 4 du RFC 3646 pour
d'autres exemples). Si ce
fichier contient search foo.example bar.example
et qu'un utilisateur tape le nom de machine toto
,
le résolveur essaiera successivement
toto.foo.example
et
toto.bar.example
. Si
foo.example
et bar.example
utilisaient des règles différentes (par exemple que l'un de ces
domaines autorise de l'UTF-8 brut et pas l'autre), la pauvre
application qui reçoit le nom toto
n'aurait pas
de moyen de prévoir ce qui va se passer. (Ici,
toto
est en ASCII. Mais si on le remplace par
café
?)
La section 3.1 donne une longue liste d'exemples détaillés des
comportements actuels des applications. On y voit entre autres ce
qui peut se passer lorsque l'application est « trop maligne » et tente
de traduire trop tôt les noms. Par exemple, l'application reçoit le
nom crème
, le traduit en Punycode
(xn--crme-6oa
) mais
resolv.conf
contient un nom en UTF-8, mettons
café.example
et le résolveur (qui ne fait pas de
conversion en Unicode) va alors chercher la chaîne incohérente
xn--crme-6oa.café.example
!
Après toutes ses considérations, très détaillées, est-il encore
possible de donner une recommandation ? Oui, et elle tient en un
paragraphe dans la section 4 : « Une application qui va
appeler un sous-programme de résolution de noms ne doit pas convertir
le nom en Punycode si elle n'est pas absolument certaine que la
résolution se fera uniquement avec le DNS public. ». En
d'autres termes, l'application plus haut qui appelerait aveuglément, par exemple,
le sous-programme idna_to_ascii_8z()
(qui, avec
la GNU libidn, convertit du jeu de caractères
local vers Punycode) avant de faire un
getaddrinfo()
a tort.
La section 4 de notre RFC laisse une possibilité à l'application
d'essayer plusieurs méthodes, comme de tenter
getaddrinfo()
sur le nom brut, puis sur le nom
punycodé. Mais ce n'est pas obligatoire. Même recommandation pour les
traductions d'adresses IP en nom : une application « intelligente »
peut se préparer à recevoir de l'UTF-8 ou du Punycode et réagir
proprement dans les deux cas.
Dans tous les cas, une autre recommandation importante du RFC est
que les API de résolution de noms spécifient clairement l'encodage
qu'elles attendent. Sur Windows, GetAddrInfoW()
spécifie bien qu'il prend de l'UTF-16 alors que
la norme de getaddrinfo()
(le RFC 3493) n'en parle pas, faisant que la mise en
œuvre de getaddrinfo
sur Windows utilise la
page de code Windows alors que celle de
MacOS utilise UTF-8.
On peut noter que la norme IDN a été révisée récemment mais, pour les questions discutées dans ce RFC, cela n'a pas de conséquence.
Aujourd'hui, l'erreur qui consiste à traduire en ACE sans faire attention semble assez fréquente. C'est le cas par exemple d'echoping avec sa bogue #3125516.
Merci à Pascal Courtois pour sa découverte d'une bogue gênante dans ce texte (pas dans le RFC).
Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : E. Haleplidis (University of Patras), K. Ogawa (NTT Corporation), W. Wang (Zhejiang Gongshang University), J. Hadi Salim (Mojatatu Networks)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 8 novembre 2010
C'est bien joli de spécifier des protocoles réseau, encore faut-il qu'ils soient implémentés. Une des raisons pour lesquels les protocoles de la famille TCP/IP ont battu à plate couture les protocoles ISO, pourtant soutenus par divers moyens bureaucratiques, est l'accent mis sur la disponibilité de programmes mettant en œuvre les spécifications, les RFC. Ces programmes permettent de vérifier que la norme est implémentable (contrairement à beaucoup de normes qui sont restés sur le papier car irréalistes) et que les différentes implémentations interopèrent. Ce RFC 6053 est le rapport décrivant trois mises en œuvre du protocole ForCES (Forwarding and Control Element Separation, un protocole de communication à l'intérieur d'un routeur, entre ses divers éléments). Il suit donc les règles et principes du RFC sur les rapports d'implémentation, le RFC 5657.
Un petit rappel d'abord. ForCES (Forwarding and Control Element Separation), normalisé dans le RFC 5810, définit un modèle (RFC 3746) où le routeur est composé de CE (Control Element) qui pilotent des FE (Forwarding Element). Les CE parlent les protocoles de routage comme OSPF, les FE font la transmission des paquets. Entre CE et FE, les messages ForCES peuvent être transmis par plusieurs protocoles, le plus utilisé (car le seul qui soit obligatoire) étant SCTP-TML (SCTP-based Transport Mapping Layer) normalisé dans le RFC 5811 et fondé sur SCTP. (Voir la section 2 pour des rappels plus complets.)
Place aux tests, maintenant. Trois mises en œuvre indépendantes ont été testées (section 3) : celle de NTT, celle de l'université de Patras, et celle de l'université de Zhejiang Gongshang (aucune des trois n'est distribuée publiquement pour l'instant). Les tests ont été globalement couronnés de succès, la plupart des bogues ont été corrigées immédiatement, les manques ayant été identifiés et les programmeurs ayant promis qu'ils les combleraient bientôt. Le test d'interopérabilité a été fait en juillet 2009. Les chinois n'étaient pas présents physiquement sur le lieu du test, ce qui a été l'occasion de tester ForCES sur une longue distance, et à travers le NAT. Outre les trois implémentations citées, le test mettait en jeu des modifications locales de deux analyseurs réseaux répandus, Wireshark et tcpdump. (Le travail sur Wireshark a été publié dans « Method and implementation of building ForCES protocol dissector based on wireshark » par Feng Luo, Ligang Dong et Fenggen Jia, à la conférence Information Management and Engineering (ICIME), 2010. Le patch se trouve dans la bogue #3534. Quant à tcpdump, la gestion de ForCES a été intégrée à partir de la 4.1.1. Vous pouvez voir des exemples en ligne.)
Comment se fait un tel test d'interopérabilité ? La section 4 résume la méthodologie suivie. Les développeurs ont d'abord rempli un questionnaire où ils devaient indiquer quelle étaient les fonctions de ForCES que leur programme gérait. Les différents programmes ont ensuite été mis l'un en face =de l'autre dans le labo et ont échangé des messages. Le bon fonctionnemement a été vérifié à la fois par les réactions des programmes et par l'examen des sniffers. Quelques raccourcis ont été pris (section 5). Par exemple, bien qu'IPsec soit obligatoire pour SCTP-TML, il n'a pas été testé, en considérant qu'IPsec était un protocole suffisamment mûr pour qu'on puisse se dispenser de le tester.
La section 6 donne tous les détails des tests, des messages testés, et de leurs résultats. Par exemple, un des tests était d'activer le heartbeat (l'envoi de messages réguliers, permettant de vérifier que le système fonctionne toujours) sur un FE (section 6.1.2.6), puis de changer l'intervalle d'émission des battements.
On l'a dit, le test a été globalement réussi. Mais il y a eu quelques petits problèmes, listés dans la section 6.2.3. Par exemple, une ambiguité est apparue dans la section 4.2.1.2 du RFC 5811 (qui n'était pas encore publié au moment du test, et qui a finalement été publié en corrigeant l'ambiguité) quant au niveau de priorité à donner à une réponse lorsque la question n'avait pas le niveau de priorité standard. Il y avait aussi de franches bogues, comme le FE et le CE attendant tous les deux une action et se bloquant mutuellement ou bien comme un mauvais calcul du champ « longueur » des messages (qui ne doit pas inclure les bits de remplissage). Il y avait aussi des problèmes qui n'étaient de la faute, ni de la norme, ni du programme mais qui reflétaient des limites de ForCES (comme la détection trop lente, dans certains cas, des coupures de la liaison entre CE et FE : SCTP-TML n'est pas forcé de réagir en temps réel à une telle coupure).
Deux autres RFC sur la mise en œuvre de ForCES sont le RFC 6369 et le RFC 6984, ce dernier rendant compte d'un test d'interopérabilité équivalent, mais plus récent.
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : C. Bao (CERNET Center/Tsinghua University), C. Huitema (Microsoft), M. Bagnulo (UC3M), M. Boucadair (France Telecom), X. Li (CERNET Center/Tsinghua University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 1 novembre 2010
Il existe plusieurs mécanismes pour assurer la co-existence entre les protocoles IPv4 et IPv6. Ce RFC ne normalise pas un nouveau mécanisme mais spécifie les formats d'adresse à utiliser pour les traducteurs IPv4<->IPv6, les logiciels qui vont convertir d'un format dans l'autre. Il est donc le socle des résultats de la nouvelle version du groupe de travail IETF Behave qui, depuis l'échec de NAT-PT, essaie de normaliser une technique de traduction d'adresses permettant d'assurer la coexistence dans certains cas.
Le RFC du groupe Behave qui décrit le cadre
général de cette traduction (Framework for IPv4/IPv6
Translation) est le RFC 6144. Empruntons-lui
quelques exemples. Supposons par exemple un réseau purement
IPv6 (hypothèse réaliste à l'heure où il ne reste plus que quelques
mois d'adresses v4) et qui veut parler aux serveurs Web
existants qui n'ont que v4. Un des mécanismes possibles est la
traduction d'adresses. Supposons que le site Web convoité soit en
198.51.100.129
. La machine purement v6 interroge
un serveur DNS 64 (protocole pas encore
normalisé) qui lui répond « Va voir en
64:ff9b::c633:6481
»
(c633:6481
== 198.51.100.129
). Elle émet alors un paquet
IPv6 vers cette adresse. Sur le trajet, un traducteur d'adresses va
prendre ce paquet, le traduire en v4 algorithmiquement et, lorsque la
réponse reviendra, il la traduira en v6, l'envoyant à la machine
cliente. Voici un exemple où une machine purement IPv6 tente de contacter Twitter, service purement IPv4 :
% telnet twitter.com 80 Trying 64:ff9b::80f2:f0f4... Connected to twitter.com. Escape character is '^]'.
Bien sûr, cette présentation est très sommaire mais c'est parce que le travail de spécification n'est pas encore terminé. La première étape de cette spécification est de décider des adresses utilisées et c'est ce que fait notre RFC. (Il pourrait d'ailleurs, dans le futur, être utilisé par des techniques autre que la traduction, comme l'encapsulation, cf. section 1.1.)
Un peu de vocabulaire, d'abord (section 1.3) :
64:ff9b::c633:6481
plus haut).Les traductions peuvent être sans état (stateless) ou bien avec état (stateful). Dans le premier cas, le traducteur n'a aucune mémoire. Chaque paquet est traité isolément, comme si le traducteur venait juste de démarrer. Cela permet donc de traiter une bien plus grande quantité de paquets et assure les meilleures performances et, surtout, le passage à l'échelle. Dans le second cas, celui de la traduction avec état, la traduction dépend des paquets précédents, par exemple parce que le traducteur se souvient que les paquets venant de tel port sont destinés à telle adresse. Nécessitant une table des correspondances en mémoire, la traduction avec état passe moins à l'échelle. Mais, dans certains cas, elle est la seule réaliste, puisqu'on ne peut pas stocker toutes les informations dans une seule adresse, surtout si elle est IPv4.
Armé de ces définitions, quels sont les formats d'adresses
IPv4-embedded possibles ? La section 2 les
liste. D'abord, un préfixe spécial a été réservé
à l'IANA (cf. section 6) pour
certaines de ces adresses :
64:ff9b::/96
(section 2.1). Lorsque vous verrez passer une
adresse IPv6 commençant par ce préfixe, vous pouvez être sûr de voir
une adresse IPv4 embarquée.
Ensuite, toutes les adresses IPv6 IPv4-embedded,
qu'elles utilisent ce préfixe ou pas, suivent le même format (section 2.2) : un
préfixe (64:ff9b::/96
ou bien un préfixe tiré de
l'espace d'adressage de l'opérateur), l'adresse IPv4, un suffixe
(parfois nul). Pour respecter la section 2.5.1 du RFC 4291, un octet nul est parfois ajouté au milieu de l'adresse
IPv4. Six longueurs de préfixe sont acceptées, 32, 40, 48, 56, 64, ou
96 (cette dernière est celle qui est typiquement utilisée avec le
préfixe 64:ff9b::/96
). Les sections 3.3 et 3.4
expliquent quelle longueur choisir selon les cas.
Si on utilise un préfixe de longueur 48, comme l'octet qui va des bits 64 à 71 inclus doit être nul, l'adresse IPv4 est en deux parties. On a donc d'abord le préfixe IPv6, les deux premiers octets de l'adresse IPv4, un octet nul, le reste de l'adresse IPv4 et un suffixe de cinq octets. Avec un préfixe de longueur 96, tout est plus simple, le prefixe occupe les douze premiers octets, l'adresse IPv4 prend le reste (et le suffixe est absent). Le tableau 1 dans la section 2.2 résume les autres possibilités.
Une fois ce format défini, la section 2.3 décrit le (très simple) algorithme qui permet de passer d'une adresse IPv4 à une adresse IPv6 et réciproquement.
Petite question de présentation : comment afficher
les adresses IPv6 IPv4-embedded ? Bien sûr en
obéissant au RFC 4291 (section 2.2) et au RFC 5952. Comme le RFC 4291
permet de représenter les quatre derniers octets (et uniquement
ceux-ci) sous la forme d'une adresse IPv4, l'adresse
64:ff9b::c633:6481
, citée plus haut, aurait aussi
pu s'écrire 64:ff9b::198.51.100.129
, ce qui est
certainement plus lisible.
Ensuite, comment utiliser ces adresses sur un vrai réseau ? La
section 3 couvre les questions de déploiement. D'abord, le préfixe
64:ff9b::/96
ne doit être utilisé qu'avec des
adresses IPv4 globalement uniques (donc, par exemple, pas avec celles
du RFC 1918). Moins évident, il ne doit pas non
plus être utilisé pour construire des adresses IPv6
IPv4-translatable, celles-ci devant être
globalement uniques. Si tout le monde est libre de se servir de ce
préfixe 64:ff9b::/96
, on ne peut pas compter
qu'on recevra les paquets qui lui sont adressés depuis un point
quelconque de l'Internet. Son usage normal est
limité à l'intérieur d'un réseau (section 3.1), autrement, il faut se
servir de préfixes spécifiques d'un opérateur.
Pendant qu'on parle de ce préfixe, il faut noter que les opérateurs qui s'en servent peuvent l'annoncer dans leurs tables de routage et qu'il apparaîtra donc sur l'Internet, par exemple si un opérateur décide de fournir un service de traduction d'adresses à un autre. Mais une telle annonce devrait normalement être contrôlée (section 3.2) et ne pas être transmise à toute la DFZ. Et, normalement, ceux qui annoncent ce préfixe en BGP doivent logiquement fournir un service de traduction ensuite (ou bien ils créent un trou noir).
Quel préfixe choisir pour ses services de traduction ? La section 3.3 donne quelques conseils. Par exemple, la « meilleure » longueur est sans doute 32, car, une fois l'adresse IPv4 ajoutée, la totalité de l'information se trouve dans les bits « de routage » (les 64 premiers). Pour le routage, c'est donc la meilleure solution mais obtenir de son RIR un /32 entier uniquement pour le service de traduction d'adresses peut être dificile. Des préfixes plus longs sont donc plus raisonnables. Le RFC suggère par exemple qu'un opérateur qui a un /32 en tout consacre un /40 au service de traduction (moins de 0,5 % de son espace d'adressage). S'il s'agit d'un simple client et pas d'un opérateur, et qu'il a un /48, un /56 conviendra pour le service de traduction. Mais la valeur exacte dépend aussi du scénario de coexistence considéré.
En cas de traduction avec état (section 3.4), les choix peuvent
être différents et le préfixe 64:ff9b::/96
est
souvent la solution la plus intéressante.
Un des intérêts de ce RFC est la section 4, qui explique les raisons des choix faits. Ainsi, le suffixe, pour les formats où il y en avait un, aurait pu être utilisé pour stocker de l'information sur les ports (section 4.1). Cela aurait augmenté les chances de pouvoir faire une traduction sans état. Cette option n'a pas été retenue dans l'immédiat mais pourrait être ajoutée plus tard. En attendant, le suffixe a obligatoirement tous ses bits à zéro ce qui, pour le format avec préfixe /32, mène à un identificateur d'interface (les 64 derniers bits d'une adresse IPv6) entièrement nul. C'est normalement interdit (section 2.6.1 du RFC 4291) mais notre RFC explique que c'est acceptable dans le contexte limité de la traduction d'adresse.
Le choix de la valeur 64:ff9b::/96
pour le
préfixe de référence est expliqué en section 4.2. D'abord, le préfixe existant pour les adresses
IPv4, ::ffff:0:0/96
(section 2.5.5.2 du RFC 4291), aurait pu être réutilisé (c'était prévu dans la section
2.1 du RFC 2765). Cela aurait simplifié
l'effort de normalisation. Le problème est que, justement, ce préfixe
est déjà connu. Plusieurs mises en œuvre d'IPv6 le traitent à
part (par exemple, Windows génère systématiquement des paquets IPv4
lorsqu'on lui présente ces adresses IPv6).
Il fallait donc allouer un nouveau préfixe. Un /32 aurait permis
d'avoir tous les bits significatifs dans les 64 premiers bits mais
n'aurait pas permis d'utiliser la représentation texte avec une
adresse IPv4 (qui n'est possible qu'à la fin d'une adresse
v6). Finalement, un préfixe /96 a été choisi. Sa valeur 64:ff9b::/96
n'a pas été
tirée au hasard : elle est neutre pour le calcul de la
somme de contrôle. La somme de 64 et de ff9b
est ffff, ce qui est équivalent à zéro en complément à
un. (Depuis, un autre préfixe l'a rejoint, le
64:ff9b:1::/48
du RFC 8215.)
Ces systèmes de traduction d'adresse posent-ils des problèmes de sécurité ? Oui, dit la section 5 qui en expose certains. Par exemple, un paquet peut mentir sur son adresse IP source, qu'il y ait traduction ou pas. En fait, note la section 5.1, un traducteur IP est comme un routeur, il a les mêmes vulnérabilités et il peut mettre en œuvre les mêmes protections. Ainsi, lorsqu'il reçoit un paquet IPv6 incluant une adresse IPv4, il peut, avant traduction, s'assurer que la machine était autorisée à utiliser cette adresse IPv4 (si le paquet vient de l'intérieur d'un réseau, c'est relativement facile). D'autres tests sont possibles comme les vérifications du chemin de retour (cf. RFC 3704).
D'autre part, lorsqu'un pare-feu teste les adresses IPv4 (section 5.2), on pourrait imaginer un attaquant qui envoie des paquets IPv6 avec adresse v4 embarquée. Le paquet v6 ne serait pas arrêté par les filtres v4 mais, après traduction, le paquet v4 pourrait faire des dégâts. Il est donc crucial que le pare-feu vérifie les adresses v4 embarquées comme si elles étaient natives.
Date de publication du RFC : Janvier 2010
Auteur(s) du RFC : A. Morton (AT&T Labs), E. Stephan (France Telecom Division R&D
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 4 janvier 2011
Prenant la suite du RFC 5835, ce nouveau RFC du groupe de travail IPPM définit la composition spatiale des métriques, ou comment passer des mesures faites sur des parties du chemin d'un paquet à la mesure sur le chemin complet.
Déjà, le RFC 2330 spécifiait des possibilités de composition temporelle et spatiale des mesures faites sur le réseau. Le RFC 5835 définissait ensuite plus rigoureusement le cadre général des compositions de mesures. Il posait des exigences comme, par exemple, le fait qu'une fonction de composition devait spécifier si les mesures partielles étaient faites avec les mêmes paquets ou pas (cf. section 2.2). Finalement, notre RFC 6049 précise ce cadre pour les compositions dans l'espace : si un paquet se promène sur l'Internet et va de A à C en passant par B, peut-on composer deux mesures, faites de A à B et de B à C, en une mesure pour le chemin complet, de A à C ? Et, si oui, comment ?
D'abord, pourquoi cet exercice ? Juste pour le défi intellectuel ? Non, dit la section 1.1, il existe des raisons pratiques à cette composition. Les RFC qui définissent les métriques, comme le RFC 7679 sur le délai d'acheminement d'un paquet ou bien le RFC 7680 sur le taux de pertes de paquets tiennent pour acquis qu'on a un accès complet à la source et à la destination et qu'on peut donc effectuer une mesure de bout en bout. Mais, parfois, ce n'est pas possible, par exemple parce que le chemin franchit une frontière administrative, et on n'a parfois que la possibilité de mesurer des sous-chemins (comme dans l'exemple de A à C ci-dessus). La composition spatiale devient alors un moyen de calculer la mesure sur le chemin complet.
Dans le futur, on pourrait même imaginer d'autres possibilités comme, dans le cas où on n'a pas de mesure pour un des sous-chemins, de calculer la valeur à partir de la mesure du chemin complet et des mesures sur les autres sous-chemins (« soustraction » et non plus « addition »). Mais cette possibilité n'est pas encore définie par le RFC (cf. section 2.1 et 2.3, qui pose que, pour l'instant, si la mesure n'a pas été faite sur un des sous-chemins, c'est le résultat entier qui est indéfini).
Pour définir les compositions elles-mêmes, le RFC procède en deux temps. La section 3 définit les paramètres communs à toutes les métriques et les sections suivantes définissent les paramètres spécifiques aux trois métriques retenues, le délai d'acheminement, le taux de pertes et la variation du délai.
Parmi les paramètres génériques, on peut citer par exemple (section 3.1.8), les causes possibles de déviation par rapport à la vérité de base (section 3.7) du RFC 5835. Ainsi, lorsqu'on mesure sur une partie du chemin, rien ne garantit que les paquets suivront le même chemin que si on mesure sur le chemin complet, en raison, entre autres, de l'ECMP. Sans compter le fait que, si les mesures ne se font pas au même moment, le routage a pu changer entre la mesure d'un sous-chemin et celle du chemin complet.
Les trois métriques spécifiques suivent cet exposé des paramètres génériques. La première est le délai d'acheminement (RFC 7679). D'abord, avant de composer de tels délais, la section 4.1 définit la notion de Type-P-Finite-One-way-Delay-<Sample>-Stream qui est une réduction d'une série de mesures, excluant celles où le paquet n'est pas arrivé (cela permettra de calculer des choses comme la moyenne). Cette façon de simplifier le problème est analogue à celle du RFC 3393 et est également utilisée dans la Recommandation UIT Y.1540, « Internet protocol data communication service - IP packet transfer and availability performance parameters ».
Armé de cette nouvelle définition, on peut s'attaquer à celle de Type-P-Finite-One-way-Delay-Mean (section 4.2). Informellement, c'est simplement la moyenne des délais. Et, finalement, on en arrive à la fonction composée, Type-P-Finite-Composite-One-way-Delay-Mean, qui est simplement la somme des moyennes des délais, somme prise sur tous les sous-chemins. Pour prendre un exemple trivial, si un paquet met en moyenne 0,12 ms pour aller de A à B et 0,05 ms pour aller de A à C, alors la Type-P-Finite-Composite-One-way-Delay-Mean sur le chemin de A à C (s'il passe par B, bien sûr), sera de 0,17 ms. Naturellement, cela suppose que le nombre de paquets utilisé pour calculer la moyenne sur chaque sous-chemin soit suffisant pour qu'on ait une valeur représentative. Il y a aussi d'autres conditions : par exemple, si la distribution des paquets sur un sous-chemin est multi-modale, la moyenne ne voudra pas dire grand'chose.
Comme on a défini une moyenne, on peut définir un minimum (section 4.3). Type-P-Finite-Composite-One-way-Delay-Minimum est la somme des délais minimaux d'acheminement sur chaque sous-chemin. Si on a fait trois tests et que le trajet de A à B a pris 0,12, puis 0,16 puis enfin 0,1 ms, et que celui de B à C a pris 0,05 ms à chaque fois, le Type-P-Finite-Composite-One-way-Delay-Minimum vaut 0,1 + 0,05 = 0,15 ms. On voit que cela suppose que les délais des sous-chemins sont indépendants, ce qui est raisonnable.
Cela, c'était pour le délai d'acheminement, pour lequel on a défini deux fonctions de composition, pour la moyenne et pour le minimum. La section 5 passe au taux de pertes de paquet. En partant de la définition de la perte Type-P-One-way-Packet-Loss du RFC 7680, on peut définir une probabilité de pertes, Type-P-One-way-Packet-Loss-Empirical-Probability puis une composition de cette probabilité, Type-P-Composite-One-way-Packet-Loss-Empirical-Probability. La définition est un peu plus compliquée que pour les compositions précédentes mais, de manière résumée, la probabilité de survie sur le chemin complet est le produit des probabilités de survie sur chaque sous-chemin. Comme la probabilité de perte est 1 - la probabilité de survie, le calcul est facile à faire.
Toutes ces métriques (je n'ai pas détaillé la troisième, présentée en section 6) ont été enregistrées dans la MIB qui sert de registre des métriques (cf. RFC 4148).
Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : Kathleen M. Moriarty (EMC)
Intérêt historique uniquement
Première rédaction de cet article le 8 novembre 2010
La sécurité, face aux innombrables attaques que connaissent les réseaux tous les jours, nécessite un échange d'information permanent. Ce RFC normalise donc un format permettant d'échanger et de traiter ce genre d'informations (depuis mis à jour dans le RFC 6545). Il sera donc peut-être un outil technique utile pour les CSIRT et les opérateurs.
La section 1 résume les problèmes de la sécurité des réseaux auxquels les opérateurs font face. Une fois l'attaque détectée, que ce soit un hameçonnage, une DoS ou une pénétration réussie dans un système connecté au réseau, il faut rédiger un rapport, transmettre à l'opérateur d'origine de l'attaque, demander à un opérateur amont de prendre des mesures pour limiter les dégâts, demander de continuer l'enquête en suivant la trace de l'attaquant, etc. Par exemple, si on veut suivre une trace de paquets dont l'adresse IP source est mensongère, et que le filtrage recommandé par le RFC 2827 n'est pas en place, il faut repérer par quel câble sont entrés ces paquets et envoyer ensuite à l'opérateur situé derrière une demande de continuation de l'enquête. Il n'y a pas de mécanisme formel pour cela. Ça se fait typiquement par téléphone ou par envoi d'un courrier en langue naturelle, ce qui augmente les coûts de traitement.
Le nouveau format, normalisé dans ce RFC 6045 (puis dans le RFC 6545, qui lui a succédé), se nomme RID pour Real-time Inter-network Defense et se base sur le format IODEF du RFC 5070, qui lui-même utilise XML. L'apport par rapport à l'IODEF de base est de cibler la circulation d'informations en « temps réel ». RID vise donc à permettre la réponse immédiate à une attaque. Par exemple, lorsqu'une dDoS est perpétrée par un botnet, il faut certes retrouver les zombies mais aussi identifier le contrôleur qui les commande. RID permet de demander un suivi de la trace des premiers, puis ensuite du second.
La section 2 traite de l'intégration aux systèmes existants. L'opérateur a typiquement un système de gestion centralisé de son réseau, un NMS. Le futur IHS (Incident Handling System) qui recevra et enverra les messages RID devra être intégré à ce NMS. La détection de l'attaque pourra se faire manuellement, ou via un IDS mais cette question est hors-sujet pour RID, qui se contente de permettre le signalement d'attaques, une fois celles-ci détectées.
Quelles sont les obstacles que rencontrent les tentatives de remonter à la source d'une attaque ? La section 3 en donne une liste, et c'est une lecture très recommandée pour comprendre la variété des problèmes auxquels fait face l'opérateur réseau lors d'une attaque. Par exemple, certaines attaques utilisent tellement peu de paquets qu'il est difficile de les répérer. D'autre part, pour prendre rapidement une « empreinte » des paquets utilisés pour l'attaque, les techniques à base d'une fonction de hachage ont souvent été utilisées (cf. « Hash-Based IP Traceback »). Or, certaines attaques ont un contenu des paquets qui varie énormément et il est difficile de trouver une « signature » qui permettrait de dire à l'opérateur précédent « Voici ce que je cherche ». Les nombreuses techniques de traceback pour IP ont été utilisées pour déterminer quelles étaient les informations importantes à inclure dans RID. Ainsi, il est essentiel d'inclure beaucoup d'informations dans le message RID car les champs significatifs et l'attaque, permettant de repérer les paquets, peuvent être n'importe lesquels. RID permet même d'envoyer la totalité du paquet, si nécessaire (section 3.2).
Une fois que le message RID est prêt, que fait-on pour la communication avec les autres opérateurs et avec les CSIRT ? Les sections 4.1 et 4.2 font remarquer que le courrier électronique n'est pas forcément adapté car il peut être trop lent. Mais, de toute façon, il faut prévoir plusieurs canaux de communication car, en cas d'attaque, certains deviendront peut-être inutilisables. Un réseau distinct de celui utilisé pour le trafic « normal » peut donc être nécessaire (voir plus loin le commentaire de la section 6). Le RFC suggère qu'on peut profiter des négociations qui précèdent un accord de peering pour mettre en place un canal de communication sécurisé.
Recommandation utile ou vœu pieux ? En tout cas, la section 4.2 rappelle également que RID ne devrait être utilisé que pour lutter contre des attaques, et pas pour perpétuer des sabotages (en dénonçant un innocent dans l'espoir qu'il se fasse filtrer) ou pour censurer.
Maintenant, place au format utilisé (section 4.3), fondé sur IODEF (RFC 5070). Il y a six messages RID possibles :
TraceRequest
où on demande à un partenaire
d'examiner son réseau pour voir d'où venait l'attaque (l'idée est que,
partant de celui qui a détecté l'attaque, on envoit des
Tracerequest
successifs en remontant peu à peu
vers la source de l'attaque).Investigation
où on demande une enquête
mais pas un traçage de l'attaque, car le demandeur pense avoir déjà
identifié la source.Report
où on transmet de l'information,
sans demander d'action immédiate.IncidentQuery
où on demande des détails sur
une attaque dont on a entendu parler (les deux derniers types de
message sont typiquement pour la communication avec un CSIRT).RequestAuthorization
et
Result
servent à porter les résultats
intermédiaires ou finaux.La section 4.4 décrit plus en détail chacun de ces types.
La section 4.5 fournit plusieurs jolis exemples, que j'ai simplifié
ici. Par exemple, une TraceRequest
envoyé par un
CSIRT qui a détecté une DoS et qui demande à un
opérateur réseau de tracer l'attaque. Le message est composé d'un
document RID puis du document IODEF qui décrit l'attaque :
<iodef-rid:RID> <!-- Le schéma est enregistré en https://www.iana.org/assignments/xml-registry/ns.html --> <iodef-rid:RIDPolicy MsgType="TraceRequest" MsgDestination="RIDSystem"> <iodef:Node> <iodef:Address category="ipv4-addr">192.0.2.3</iodef:Address> </iodef:Node> <iodef-rid:TrafficType type="Attack"/> <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN"> CERT-FOR-OUR-DOMAIN#207-1 </iodef:IncidentID> </iodef-rid:RIDPolicy> </iodef-rid:RID> <!-- IODEF-Document accompanied by the above RID --> <iodef:IODEF-Document> <iodef:Incident restriction="need-to-know" purpose="traceback"> <iodef:DetectTime>2004-02-02T22:49:24+00:00</iodef:DetectTime> <iodef:StartTime>2004-02-02T22:19:24+00:00</iodef:StartTime> <iodef:ReportTime>2004-02-02T23:20:24+00:00</iodef:ReportTime> <iodef:Description>Host involved in DOS attack</iodef:Description> <iodef:EventData> <iodef:Flow> <iodef:System category="source"> <iodef:Node> <iodef:Address category="ipv4-addr">192.0.2.35 ...
Et la première réponse, qui indique que la demande de traçage a été approuvée :
<iodef-rid:RID> <iodef-rid:RIDPolicy MsgType="RequestAuthorization" MsgDestination="RIDSystem"> <iodef-rid:TrafficType type="Attack"/> </iodef-rid:RIDPolicy> <iodef-rid:RequestStatus AuthorizationStatus="Approved"/> </iodef-rid:RID>
Et enfin la réponse finale :
<iodef-rid:RID> <iodef-rid:RIDPolicy MsgType="Result" MsgDestination="RIDSystem"> <iodef:Node> <iodef:Address category="ipv4-addr">192.0.2.67</iodef:Address> </iodef:Node> <iodef-rid:TrafficType type="Attack"/> <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN"> CERT-FOR-OUR-DOMAIN#207-1 </iodef:IncidentID> </iodef-rid:RIDPolicy> <iodef-rid:IncidentSource> <iodef-rid:SourceFound>true</iodef-rid:SourceFound> <iodef:Node> <iodef:Address category="ipv4-addr">192.0.2.37</iodef:Address> </iodef:Node> </iodef-rid:IncidentSource> </iodef-rid:RID> <!-- IODEF-Document accompanied by the above RID --> <iodef:IODEF-Document> <iodef:Incident restriction="need-to-know" purpose="traceback"> <iodef:IncidentID name="CERT-FOR-OUR-DOMAIN"> CERT-FOR-OUR-DOMAIN#207-1 </iodef:IncidentID> <iodef:DetectTime>2004-02-02T22:49:24+00:00</iodef:DetectTime> <iodef:StartTime>2004-02-02T22:19:24+00:00</iodef:StartTime> ... <iodef:Expectation severity="high" action="rate-limit-host"> <iodef:Description> Rate limit traffic close to source </iodef:Description> </iodef:Expectation> <iodef:Record> <iodef:RecordData> <iodef:Description> The IPv4 packet included was used in the described attack </iodef:Description> <iodef:RecordItem dtype="ipv4-packet">450000522ad9 0000ff06c41fc0a801020a010102976d0050103e020810d9 4a1350021000ad6700005468616e6b20796f7520666f7220 6361726566756c6c792072656164696e6720746869732052 46432e0a </iodef:RecordItem> </iodef:RecordData> </iodef:Record> </iodef:EventData> <iodef:History> <iodef:HistoryItem> <iodef:DateTime>2004-02-02T22:53:01+00:00</iodef:DateTime> <iodef:IncidentID name="CSIRT-FOR-OUR-DOMAIN"> CSIRT-FOR-OUR-DOMAIN#207-1 </iodef:IncidentID> <iodef:Description> Notification sent to next upstream NP closer to 192.0.2.35 </iodef:Description> </iodef:HistoryItem> <iodef:HistoryItem action="rate-limit-host"> <iodef:DateTime>2004-02-02T23:07:21+00:00</iodef:DateTime> <iodef:IncidentID name="CSIRT-FOR-NP3"> CSIRT-FOR-NP3#3291-1 </iodef:IncidentID> <iodef:Description> Host rate limited for 24 hours </iodef:Description> </iodef:HistoryItem> </iodef:History> </iodef:Incident> </iodef:IODEF-Document>
Comme déjà noté, l'utilisation de ces messages RID ne va pas sans risques. La section 6 les analyse. D'abord, il faut évidemment un canal sécurisé pour les transmettre. Sécurisé au sens de :
Un canal physique dédié faciliterait l'obtention de ces propriétés mais n'est pas forcément réaliste. Le RFC recommande donc plutôt un tunnel chiffré. En combinant TLS sur le tunnel et les signatures XML du RFC 3275 sur le message, on atteint la sécurité désirée. Le protocole exact utilisé est normalisé dans un autre document, le RFC 6046. Bien qu'il utilise le chiffrement, RID ne repose pas uniquement sur la sécurité du canal et permet de chiffrer aussi le message par le chiffrement XML.
RID soulève aussi des questions liées à la protection de la
vie privée et la section 6.6 les étudie. RID
fournit le moyen de spécifier des détails comme l'extension du
« domaine de confiance » à qui on peut envoyer les informations
(élément PolicyRegion
, section 4.3.3.3).
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : A. Crouch, H. Khosravi (Intel), A. Doria (LTU), X. Wang (Huawei), K. Ogawa (NTT Corporation)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 30 octobre 2010
Le protocole ForCES (Forwarding and Control Element Separation), décrit dans le RFC 5810, normalise la communication entre les différents éléments d'un routeur, de façon à permettre la création d'un routeur par l'assemblage de composants venus de constructeurs différents. Ce RFC 6041 se focalise sur l'applicabilité de ForCES, à savoir dans quels cas ce protocole est applicable et ce qu'on peut exactement lui demander. Ce RFC peut donc servir d'introduction de haut niveau à ForCES.
ForCES considère un routeur comme composé d'un élément de contrôle, qui parle les protocoles de routage comme OSPF, c'est le CE (Control Engine), et d'un ou plusieurs éléments qui transmettent effectivement les paquets, les FE (Forwarding Engine). ForCES est le mécanisme par lequel le CE communique avec ses FE. Outre le protocole lui-même, dans le RFC 5810, ForCES a aussi un modèle de données (RFC 5812) et un protocole de transport (RFC 5811). Dans quels cas peut-on les employer et, inversement, quand sont-ils inapplicables ? La section 4 forme le cœur du RFC et c'est surtout elle qui est résumée ici.
D'abord, ForCES est prévu pour des routeurs assez gros pour que les
fonctions de contrôle et de transmission soient séparées. Sur un engin
bas de gamme, où tout tient dans le même circuit, ForCES n'est sans
doute pas utile. Par contre, les routeurs du milieu et du haut de
gamme ont déjà une séparation physique entre le mécanisme de contrôle
et les mécanismes de traitement des interfaces réseaux. Comme ce CE et
ces FE doivent communiquer (par exemple, si le CE apprend par OSPF
qu'une route pour 192.0.2.192/26
passe par
l'interface ge-0-1, il doit communiquer cette information au FE qui
gère cette interface, mais aussi à tous les autres pour qu'ils lui
transmettent ce trafic). Les routeurs ont donc tous un protocole de
communication entre CE et FE mais il est toujours privé (un des rares
qui soit documenté est le Netlink de
Linux, dans le RFC 3549). Avec ForCES, se profile la possibilité d'un
protocole standard pour les remplacer.
Quels services, dans cette communication entre FE et CE, peuvent être assurés par ForCES ? Notons bien (section 4.1) que ForCES ne traite pas de la découverte par le CE de ses FE, découverte qui doit être assurée autrement. En revanche, une fois celle-ci effectuée, ForCES pilote l'association entre CE et FE, et la transmission des informations comme, par exemple, le nombre de ports réseaux que gère le FE. Le CE peut ensuite configurer le FE (par exemple en lui indiquant les adresses IP locales, qui doivent être transmises au CE), comme indiqué en section 4.1.3.
Mais le principal service assuré par ForCES est évidemment l'envoi d'informations de routage (section 4.1.4). Un CE transmet à ses FE les adresses IP à router, de façon à ce que les paquets soient transmis à la bonne interface réseau.
La section 4.1 note de nombreux autres services. Citons-en juste un : l'envoi par le CE de règles de filtrage (quels paquets abandonner, et sur quels critères), en section 4.1.7.
De quoi a besoin ForCES pour rendre ces services, et qui n'est pas forcément présent sur tous les routeurs ? De capacité réseau (section 4.2). Entre le CE et le FE, la capacité n'est pas infinie et des opérations comme l'envoi d'une table de routage complète peuvent être non-triviales sur un réseau d'interconnexion lent, d'autant plus que ForCES se veut utilisable pour des futures tables de routage, plus grandes que celle d'aujourd'hui (fin octobre 2010, il y a 340 000 entrées dans la table de routage BGP globale).
Cette question de la capacité en amène une autre, celle de la localité. ForCES sépare logiquement le CE et le FE. Peuvent-ils aussi être séparés physiquement, et mis dans des boîtes différentes ? La section 4.3 examine la question. Le principe est que la disponibilité du routeur ne devrait pas être affectée par la séparation du contrôle et de la transmission. La connexion entre le FE et le CE est doit donc être un bus très fiable, ou en tout cas aussi fiable que le CE, de façon à partager son sort. En pratique, cela veut dire que ForCES est utilisable sans problème pour les NE (Network Element, typiquement un routeur) où tout tient dans une seule boîte, avec des lames différentes pour le CE et les FE, mais un seul châssis et une interconnexion en Ethernet, PCI, etc (le cas de la majorité des routeurs actuels). Une telle configuration simplifiera notamment les problèmes de sécurité (cf. section 5). Mais ForCES peut aussi marcher dans des cas où CE et FE sont situés dans des boîtiers séparés.
Pas de protocole réaliste sans possibilité de gestion. La section 6 détaille le comportement de ForCES face aux exigences de la gestion du réseau. Le point important est que, quel que soit le degré de séparation entre CE et FE, ForCES permet de voir le routeur comme un élément unique. Cela se réalise en faisant passer l'essentiel des fonctions de gestion à travers le CE. Notre RFC recommande ainsi que tous les messages SNMP soient transmis au CE (par exemple en utilisant les mécanismes du RFC 2741). Ceux qui vont quand même directement traités par les FE doivent, ou bien être en lecture seule, ou bien permettre une notification du CE, afin que celui-ci reste seul maître. ForCES dispose d'une MIB, décrite dans le RFC 5813, qui permet d'accéder à des informations comme les associations entre le CE et les FE.
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : Vishwas Manral (IP Infusion), Manav Bhatia (Alcatel-Lucent), Joel Jaeggli (Checkpoint Software), Russ White (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 24 octobre 2010
Le groupe de travail IETF opsec travaille à améliorer la sécurité des protocole de routage. Ce RFC du groupe (l'un des premiers, après les très intéressants RFC 4778 et RFC 5635) fait le point sur l'utilisation actuelle de la cryptographie dans ces protocoles et ses limites, les problèmes qu'elle soulève, notamment de gestion des clés.
Plusieurs protocoles de routage ont des mécanismes standards pour protéger par la cryptographie les informations transmises. OSPF v2 (RFC 2328), OSPF v3 (RFC 5340), IS-IS (RFC 1195), BGP (RFC 4271), ou des protocoles qui, sans être à proprement parler « de routage », en sont néanmoins proches comme BFD (RFC 5880), sont tous capables de prendre un condensat cryptographique de l'information transmise, en utilisant une fonction de hachage comme MD5 (RFC 1321) et une clé secrète. Le routeur récepteur, s'il a la même clé secrète, peut refaire le calcul du condensat et, s'il trouve la même valeur, être rassuré que le message vient bien d'un routeur autorisé, et qu'il n'a pas été modifié en route. (On notera que l'utilisation de protocoles à clés publiques est infiniment plus rare, au point d'être à peine mentionné dans le RFC.)
Notons que ces protocoles n'assurent pas de service de confidentialité : un méchant qui espionne la communication entre deux routeurs peut toujours apprendre les routes échangées.
Comme le note la section 1 du RFC, qui étudie les problèmes génériques, communs à tous les protocoles de routage, cette approche a des limites : l'utilisation de clés secrètes partagées entraine une gestion manuelle des clés, plutôt pénible. Remplacer une clé compromise est ainsi une opération longue et risquée (il est facile d'oublier un routeur, ce qui cassera les communication entre les routeurs ayant la nouvelle clé et les autres). D'autre part, plusieurs cas existent où les attaques par rejeu sont possibles.
Comme le note la section 1.1, la fonction de hachage la plus couramment utilisée est MD5. Celle-ci n'est pas sans reproche, cryptographiquement parlant. Des attaques par collision (trouver deux messages qui ont le même condensat cryptographique) ont déjà été publiées par exemple par Xiaoyun Wang, Xuejia Lai, Dengguo Feng & Hongbo Yu, dans « Collisions for hash functions MD4, MD5, HAVAL-128, and RIPEMD », Crypto 2004 Rump Session. En revanche, des attaques dites « pré-image » (où on produit un message qui a le même condensat qu'un message donné, ce qui est beaucoup plus difficile qu'une attaque par collision) ne semblent pas avoir été publiées. Pour le cas particulier des protocoles de routage, les collisions ne sont pas trop à craindre car beaucoup de champs dans un message ne peuvent pas prendre des valeurs arbitraires (par exemple, dans OSPF le champ « Link State Advertisement function code - section A.4.2.1 du RFC 5340 - peut valoir seulement de 1 à 14). Pour les attaques pré-image, elle seraient sans doute plus graves, mais la taille relativement limitée des messages de routage limite sans doute les risques d'exploitation effective.
SHA-1 a aussi ses faiblesses (section 1.2) mais il faut bien voir qu'elles ne sont pas réellement utilisables pour une attaque, dans les conditions spécifiques des protocoles de routage (cf. RFC 4270 pour un bon arrière-plan sur la question.)
Les sections suivantes détaillent ensuite les problèmes pour le cas spécifique de chaque protocole. À chaque fois, sont indiqués les problèmes d'ordre pratique (gestion des clés) et ceux d'ordre technique (faiblesses dans le protocole). OSPF v2 fait l'objet de la section 2. Les routeurs OSPF d'un même réseau peuvent s'authentifier en condensant les paquets et une clé secrète avec MD5 (RFC 2328, annexe D.3). Cette clé se configure avec :
interface eth0 ip ospf authentication message-digest ip ospf message-digest-key 1 md5 MACLESECRETE
sur Quagga et avec :
authentication-type md5; interface fe-0/0/1.0 { authentication { md5 1 key "$9$dEbgoZUjqP5GUApO1hcgoaJHq"; MACLESECRETE } }
sur JunOS. Il existe aussi un mécanisme expérimental de signature des messages par des clés asymétriques (RFC 2154) mais qui n'a apparemment jamais été déployé.
Le condensat cryptographique s'applique aux messages échangés entre routeurs, pas à l'information de routage elle-même. Autrement dit, MD5 dans OSPF sécurise le canal mais pas le message (le LSA). OSPF ne fournit aucun mécanisme de négociation de paramètres comme l'algorithme de hachage utilisé. Si on veut utiliser SHA (RFC 5709), tous les routeurs d'un même lien doivent être manuellement configurés de manière identique. D'une manière générale, tout changement dans les clés doit faire l'objet d'une prudente intervention planifiée et manuellement exécutée.
L'authentification cryptographique dans OSPF a aussi des problèmes techniques (section 2.2) comme le fait que la même clé soit utilisé pour tous les routeurs d'un même réseau Ethernet, obligeant à largement partager le secret.
Pour OSPF v3 (RFC 5340 et section 3), encore peu déployé, la situation est toute différente. Il n'a pas de mécanisme d'authentification intrinsèque et ses utilisateurs sont censés s'appuyer sur IPsec (par exemple RFC 4303, sans chiffrement, comme spécifié dans le RFC 2410, pour avoir juste la signature). La norme de sécurité d'OSPF v3 (RFC 4552) précise que les clés IPsec doivent être gérées manuellement, pas avec un protocole comme IKE parce que le modèle de fonctionnement d'OSPF (un-vers-plusieurs) est très particulier.
Même si le RFC n'en dit pas un mot, le principal problème d'OSPF v3, aussi bien technique que pratique, est qu'IPsec est très peu déployé et que peu d'administrateurs réseaux ont envie de s'y mettre pour assurer une fonction qui, en OSPF v2, ne prenait que deux lignes de configuration.
Et le concurrent d'OSPF, IS-IS (RFC 1195 et section 4 de notre RFC) ? Lui aussi peut utiliser MD5 pour l'authentification (voir RFC 5304). Mais, contrairement à OSPF, la signature porte sur l'annonce d'état d'un lien, pas sur un message échangé entre deux routeurs. Cela veut dire qu'on peut authentifier un routeur distant, mais cela oblige (section 4.1) tous les routeurs à avoir la même clé... Comme OSPF, pas moyen de négocier la clé, ou l'algorithme de condensation. Si on veut remplacer MD5 par SHA-256, un gros travail de gestion est à prévoir.
Faut-il également parler de l'antédiluvien RIP ? La section 6 lui consacre quelques paragraphes. La version historique, dans le RFC 1058, avait zéro service de sécurité. La version 2, actuellement normalisée dans le RFC 2453, et dispose désormais d'un mécanisme d'authentification analogue à ceux des autres protocoles (cf. RFC 4822).
Bien que n'étant pas un protocole de routage, BFD (RFC 5880) est tellement souvent utilisé dans les routeurs qu'il mérite sa section de ce RFC, la 7. BFD sert à détecter la panne d'une liaison. Il dispose d'un mécanisme d'authentification optionnel (sections 4.2 et 6.7 du RFC 5880), à clés partagées. Il hérite donc des problèmes de gestion de clés de ce système.
Et BGP, vedette des protocoles utilisés sur l'Internet, puisque c'est lui qui assure le routage entre opérateurs ? La section 5 détaille ce protocole. BGP est forcément transporté sur TCP. Il peut donc utiliser les options d'authentification de TCP comme celle du RFC 2385 (très répandue en pratique dans le monde BGP) ou bien celle du RFC 5925, plus récente, bien meilleure et plus rare en pratique. Pour cette raison, notre RFC 6039 ne couvre que l'authentification MD5 du RFC 2385. Parmi les problèmes de gestion, il y a le fait que BGP est typiquement utilisé de part et d'autre d'une frontière administrative. Cela complique sérieusement les opérations de gestion de clés. Par exemple, quand avez-vous pour la dernière fois changé un mot de passe MD5 sur une session BGP avec un pair ? (Réponse : vous ne l'avez probablement jamais fait.) Sur un gros point d'échange, un routeur BGP peut se connecter à des dizaines, voire des centaines de pairs, et la gestion des « mots de passe MD5 » pour tous ces pairs est un défi. En général, on ne complique pas ce défi en essayant de suivre des bonnes pratiques, comme le changement des mots de passe...
Et les problèmes techniques de BGP ? Comme il utilise TCP, il profite de ses mécanismes de sécurité (comme les numéros de séquence qui protègent des rejeux) et il hérite de ses faiblesses (voir l'excellent exposé de Convery & Franz à Black Hat, « BGP Vulnerability Testing: Separating Fact from FUD », un modèle pour toute analyse de la sécurité). À plusieurs reprises, les fabricants de routeurs BGP ont dû mettre à jour leur logiciel pour traiter ces vulnérabilités.
À noter que le RFC ne mentionne pas du tout ce qui est probablement
la plus grosse faiblesse de sécurité de BGP : le fait qu'on puisse
authentifier le voisin, mais pas l'information qu'il envoie (ou
relaie). Savoir que c'est bien mon pair
2001:db8:face:b00c::1
avec qui je parle, c'est
très bien mais, lorsqu'il annonce une route vers
2001:db8:137::/48
, comment savoir s'il a le droit
de le faire ou bien si Pakistan
Telecom a fait mumuse ? Il n'existe pour l'instant aucun protocole standard pour cela.
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : A. Morton, L. Ciavattone (AT&T Labs)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 11 octobre 2010
Voici deux petites extensions au protocole de mesure active TWAMP. L'une permet de demander le renvoi d'octets choisis par le client. L'autre permet de garantir l'usage de paquets de même taille dans les deux directions.
L'IETF a deux protocoles de mesure active, OWAMP (One-way Active Measurement Protocol, RFC 4656, unidirectionnel, et TWAMP (Two-Way Active Measurement Protocol, RFC 5357), bidirectionnel. Avec TWAMP, un client peut demander une réponse à des paquets de tests qu'il envoie et en déduire des informations sur le réseau (comme le RTT). Mais le RFC original ne garantit pas grand'chose sur ces paquets de retour (section 4.2.1 du RFC 5357), ce qui peut être gênant dans certains cas. Désormais, le client peut décider d'une partie du contenu des paquets de test, ainsi que de leur taille (sections 1 et 2 du RFC).
La possibilité de réflexion d'octets, choisis par le client, ouvre de nombreuses possibilités à ce dernier comme d'étiqueter les paquets de la manière de son choix, en pouvant relire l'« étiquette » au retour.
La section 4.2.1 du RFC 5357 recommande que le serveur TWAMP choisisse des paquets de réponse qui soient de taille proche de celui des paquets reçus. Mais ce n'était pas une obligation. La nouvelle option indique que le client veut l'égalité des tailles de paquets.
Ces deux options sont signalées par des bits du champ Mode (section 3.1 du RFC 4656) autrefois inutilisés. Un serveur TWAMP correct doit ignorer ces bits s'il ne les connait pas, assurant ainsi la compatibilité des nouveaux clients avec les anciens serveurs.
Les détails pratiques figurent en sections 3 (pour la session de contrôle du test) et 4 (pour celle de test à proprement parler). Les deux nouveaux bits ont été enregistrés dans le registre IANA (voir aussi la section 6). La section 3.2 décrit le format des paquets de l'option « Reflect Octets » qui permet d'indiquer deux octets à réfléchir lors de l'acceptation de la session (ce qui permet de vérifier que le serveur gère bien cette extension). On indique aussi le nombre d'octets (au maximum 65536) à réfléchir lors du test. L'autre option, « Symmetrical Size » n'a pas nécessité de changer le format.
Enfin, la section 4.2 normalise le comportement du réflecteur en présence de ces nouvelles options. Les deux extensions en question sont optionnelles et ne seront pas forcément mises en œuvre par tous les serveurs TWAMP. Il n'existe de toute façon pas encore de mise en œuvre de TWAMP en logiciel libre.
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : B. Carpenter (Univ. of Auckland), S. Jiang (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 23 octobre 2010
Maintenant que de nombreux FAI, dans le monde, ont déployé IPv6 et l'offrent comme service à leurs clients, il est temps de regarder ce qu'ils ont fait et de le documenter. Les auteurs de ce RFC ont donc commis un questionnaire début 2010 sur le thème « comment avez-vous déployé IPv6 », et l'ont envoyé à un certain nombres de FAI. Notre RFC 6036 résume les réponses.
Pendant longtemps, la décision de passer à IPv6 ou pas semblait ouverte. On déployait IPv6 quand, comme Nerim, on avait une clientèle techniquement exigeante, et on ne le déployait pas lorsqu'il n'y avait pas de demande des clients (le cas le plus fréquent). Mais, aujourd'hui, le business ne peut plus continuer comme avant, les adresses IPv4 étant presque épuisées. Cela laisse trois choix aux FAI (section 1 du RFC) :
Que font aujourd'hui les FAI ? L'enquête va essayer de répondre à cette question, en se focalisant sur ce qui est de la responsabilité directe des FAI, l'adressage, le routage, la gestion, le DNS, et en excluant les applications (qui sont souvent un des freins à la migration vers IPv6).
Plusieurs RFC couvrent ce champ. Par exemple, le RFC 4029 parle du déploiement chez un FAI, et prévoit la « double pile » (v4 et v6) sur tous les équipements. Compte-tenu du retard pris et de l'épuisement des adresses v4, cela ne sera sans doute pas possible et il faut aujourd'hui envisager la cohabitation et la communication entre des machines purement v4 et d'autres purement v6. Le RFC 5211 est une vision plus générale du déploiement d'IPv6, les FAI étant juste un cas particulier. Le RFC 4779 documente le déploiement de IPv6 dans des réseaux d'accès courants comme le câble TV ou l'ADSL. Les RFC 5181 et RFC 5121 traitent, eux, des accès 802.16. Les questions de sécurité sont abordées dans le RFC 4942 ainsi que dans le RFC 4864, ce dernier se focalisant sur la protection du réseau local du client.
Les normes IPv6 de base sont assez stables (la plupart des RFC récents n'ont touché qu'aux détails) mais le travail continue activement à l'IETF, par exemple dans des domaines comme la traduction d'adresses.
Place maintenant à l'étude elle-même (section 2). Le questionnaire figure dans l'annexe B. Il a été expédié à des listes d'opérateurs comme NANOG. 31 réponses ont été reçues. Seuls les volontaires répondaient, ce qui biaise évidemment les résultats (une liste - incomplète car certains ont demandé l'anonymat - des répondants figure en section 7). Les auteurs du RFC notent que les FAI qui ont déployé IPv6 étaient probablement plus prompts à répondre. Les réponses étaient confidentielles. Les réponses agrégées figurent dans l'annexe A.
Que trouve t-on dans ces réponses ? Les répondants fournissent de l'accès à l'Internet par un grand nombre de moyens (section 2.2), xDSL, DOCSIS, Ethernet, WiMAX et bien d'autres. Sur les adresses IP utilisées, plusieurs répondants poussent le négationnismes jusqu'à dire qu'ils n'auront jamais d'épuisement des adresses IPv4, les autres répondants citant, pour leur propre pénurie, des dates entre 2010 et 2015. En 2010, plusieurs FAI en Asie - 19 % des répondants - n'ont déjà plus une seule adresse IP publique et allouent du RFC 1918 à leurs clients ; ceux-ci n'ont donc pas un vrai accès Internet. 39 % des répondants utilisent des adresses privées en interne.
42 % des répondants ont déjà une offre IPv6 (section 2.4), mais moins d'1 % de clients l'utilise. 48 % des répondants ont une telle offre en travaux, avec l'idée d'ouvrir entre 2010 et 2013 (rappelez-vous que les réponses n'ont pas été vérifiées...) Donc, 10 % des répondants, en 2010, moins d'un an avant l'épuisement de la réserve IANA, ne font rien... Le pronostic sur le dépassement d'IPv4 par IPv6 en terme de trafic varie évidemment mais tourne autour de 2015.
Quelle technique de déploiement ? 94 % des répondants ont une épine dorsale en double-pile (section 2.5). 39 % ont ou bien vont avoir un relais 6to4 (je n'ai pas vérifié si cela incluait les relais 6rd comme ceux de Free) et 16 % du Teredo. Une des questions portait sur « les systèmes qui ne gèrent pas IPv6 ». Si les gros routeurs de l'épine dorsale sont évidemment tous prêts pour IPv6 depuis très longtemps, le maillon faible concerne plutôt des systèmes plus discrets : les CPE sont le plus souvent cités mais aussi les DSLAM, les répartiteurs de charge ou des logiciels comme celui de gestion des adresses IP des clients ou bien le système de facturation. À la question de savoir si des engins comme les CPE pourraient être mis à jour, beaucoup de réponses étaient « nous l'espérons »...
Parmi ceux qui allouent des adresses IPv6, les préfixes existants vont d'un /19 à un /48 (!) et celui alloué au client va de /48 à /64 en passant par plusieurs /56 (le RFC 6177 donne des recommandations à ce sujet). Pour déléguer le préfixe du client à la CPE, les méthodes vont de la configuration manuelle à DHCPv6 et SLAAC (StateLess Address AutoConfiguration). Certains utilisent Radius ou PPPoE bien qu'ils n'aient pas de moyen standard de déléguer un préfixe.
La moitié des répondants gèrent déjà des serveurs double-pile (SMTP, HTTP, IMAP). Des systèmes internes comme la surveillance du réseau semblent également v6isés à 50 % alors que les systèmes de facturation et de compatibilité, dejà cités, ne le sont qu'à 23 %.
Comment gérer la coexistence d'IPv4 et IPv6 ? 58 % des FAI ne croient pas aux clients « fixes » purement v6. Interrogés sur la date où la dernière application purement v4 disparaitra, les réponses sont souvent du type « au moins dix ans ». Il faudra donc gérer la coexistence. Sur ce point, la section 2.5 ne montre aucun consensus sur les solutions : un traducteur du genre NAT, par exemple, ou bien d'autres mécanismes pas forcément précisés.
Certains FAI ont IPv6 en production depuis des années. Quelles expériences peuvent-ils en tirer ? La section 3 fait le point. Ceux qui ont fait le choix de la double pile native (c'est le cas de Nerim en France) en sont contents. Mais ceux ceux qui utilisent 6to4 ou 6rd aussi. La plupart des répondants estiment a posteriori que le passage à IPv6 était plutôt facile, une opération qu'ils classent dans la catégorie « comment arriver à manger un éléphant ? » (la réponse est « une bouchée à la fois »). Les difficultés rencontrées portaient sur la difficulté à convaincre certains (il existe encore des négationnistes qui, cherchant à justifier leur inaction, prétendent que l'épuisement des adresses IPv4 est un faux problème) et, naturellement, sur le fait que, comme tous les changements d'infrastructure qui n'apportent pas un bénéfice immédiat et visible, le passage à IPv6 est difficile à justifier auprès de la direction, qui ne voit que l'intérêt financier immédiat. Des problèmes moins connus sont aussi soulevés, comme l'importance d'impliquer les gens qui font le support utilisateur, puisque certaines applications mal écrites ne se rabattront pas sur IPv4 si une connexion IPv6 échoue, ce qui peut entraîner des protestations des clients.
Puisqu'on parle des problèmes, quels sont les principaux manques à l'heure actuelle, pour le FAI qui veut passer à IPv6 ? La section 4 liste les réponses faites à ce sujet :
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : I. Rimac, V. Hilt, M. Tomsu, V. Gurbani (Bell Labs, Alcatel-Lucent), E. Marocco (Telecom Italia)
Pour information
Première rédaction de cet article le 23 octobre 2010
Dans le cadre des travaux menés à l'IETF (groupe de travail ALTO, RFC 5594, etc) et à l'IRTF sur le problème de l'optimisation du transfert de fichiers en pair-à-pair, ce RFC sert de bibliographie : il rassemble des pointeurs, classés et organisés, sur la littérature existante en matière d'optimisation, de recherche du « meilleur pair ».
Le pair-à-pair est un concept difficile à définir et encore plus à mesurer. D'autant plus, même si le RFC ne mentionne pas ce problème, que la répression dont il fait l'objet à l'instigation des ultras de l'appropriation intellectuelle oblige ses utilisateurs à diverses astuces pour dissimuler son utilisation, rendant ainsi les statistiques difficiles. Par exemple, les estimations de la part de trafic qui revient au pair-à-pair varient de 40 à 85 %... Une chose est sûre, cela représente un trafic important, et qu'il est donc logique de chercher à optimiser. Lorsqu'on utilise le pair-à-pair pour des transferts de fichier (avec des systèmes comme BitTorrent), le contenu convoité est répliqué sur de nombreux pairs à travers le monde (section 1 du RFC). Le problème est « Quel pair utiliser ? » Isolé, le pair qui veut récupérer un fichier ne peut utiliser que le hasard, ou bien des mesures qu'il fait lui-même et qui sont souvent imparfaites (par exemple, la mesure de la latence avec un ping ne donne qu'une vague idée du débit qu'on obtiendra). La DHT typique ne donne que des optimisations locales, qui ne sont pas forcément bonnes globalement. C'est le problème central de l'optimisation, décrit dans le RFC 5693.
Il y a plusieurs solutions à ce problème, comme des réseaux de machines faisant des mesures applicatives et donnant accès au résultat de ces mesures (Azureus le fait), ou bien comme des fournitures d'information aux pairs par le FAI, pour que les destinataires puissent prendre des décisions informées. Ce RFC résume la littérature existante sur ces solutions, en s'appuyant sur le RFC 4981.
La section 2 du RFC examine les résultats de recherche publiés sur ce thème, comme « The impact of DHT routing geometry on resilience and proximity » de Gummadi, K., Gummadi, R., Gribble, S., Ratnasamy, S., Shenker, S., et I. Stoica, qui étudie la relation entre le réseau overlay de plusieurs algorithmes de DHT et le réseau physique sous-jacent. Leur conclusion est notamment que les géométries les plus simples (comme l'anneau) sont les meilleures.
Pour les autres résultats de recherche, la section 2 les classe en deux groupes : les méthodes fondées sur des mesures faites uniquement par l'application (comme Meridian) et celles fondées sur une coopération entre les couches (comme P4P).
Les premières sont traitées plus en détail dans la section 2.1. L'idée de base est que les machines mesurent un coût (typiquement, la latence) par rapport à un certain nombre d'amers et qu'on peut ensuite calculer le coût de la communication entre deux machines, par le biais d'un système de coordonnées Internet. C'est ainsi que fonctionnent IDmaps ou GNP. Tous les deux dépendent d'un réseau d'amers stables. Au contraire, Vivaldi est entièrement distribué et c'est le système utilisé dans le client BitTorrent Azureus.
Les algorithmes cités dans le paragraphe précédent forment une sous-catégorie du groupe « Mesures faites par l'application ». Cette sous-catégorie est celle des systèmes de coordonnées explicites, qui essaient, à coup de mesures, de déterminer la topologie sous-jacente. Dans un réseau aussi complexe que l'Internet, où des inégalités aussi simples que l'inégalité triangulaire (qui dit que le coût pour aller de A à C est inférieur ou égal au coût de A à B plus celui de B à C) ne sont pas forcément vraies, il n'est pas évident qu'une telle approche soit efficace. D'où la seconde sous-catégorie, basée sur une mesure des distances. Moins générales, ces méthodes (dont la plus connue est Meridian) sont peut-être plus réalistes.
Dans tous les cas, toutes les mesures faites par les applications doivent se poser la problème de ce qu'on mesure. Le plus simple est de mesurer la latence (ce que fait, par exemple, la commande ping). Or, des métriques comme la capacité (RFC 5136) ou comme le taux de pertes de paquets (RFC 7680) seraient sans doute plus utiles. Plus difficiles à estimer par des mesures actives, elles conviennent par contre bien aux mesures passives (voir « Internet tomography » de Coates, M., Hero, A., Nowak, R., and B. Yu et ou iPlane).
Toutes les techniques de la section 2.1, où l'application cherche à se faire une idée de la topologie du réseau souffrent des mêmes problèmes : l'Internet est compliqué (section 3). Par exemple, le chemin le plus court n'est pas forcément le meilleur. Et la topologie ne renseigne pas sur les coûts financiers des liens, par exemple sur le fait que le transit est plus cher que le peering. Enfin, comme toutes les mesures actives, elles ajoutent à la charge du réseau.
Deuxième groupe, dans la section 2.2, les méthodes fondées sur une coopération entre les couches. Ce sont celles où l'application, au lieu de devoir faire les mesures elle-même, peut interroger un service qui a été configuré (typiquement par le FAI) avec des informations sur le réseau, sa capacité, son coût, etc. La plus connue est P4P (section 2.2.1) où des serveurs, les iTrackers, sont interrogés par les applications qui récupèrent ainsi des informations utiles. Des expériences, par exemple celle décrite dans le RFC 5632 indiquent que les gains de temps pour un téléchargement peuvent dépasser un facteur 2. Si le RFC ne parle pas des problèmes politiques, on note que ce mécanisme nécessite que le FAI soit prêt à révéler une partie de la structure de son réseau.
Une autre solution, décrite dans la section 2.2.2, est celle des « oracles » où l'application, au lieu d'avoir accès à des informations sur le réseau, fournit une liste de pairs potentiels et l'oracle lui indique les plus favorables. Là encore, le RFC ne rentre pas dans les questions politiques mais on voit que l'oracle acquière beaucoup d'informations sensibles, notamment sur les pairs avec qui on communique.
Une variante (section 2.2.3) du cas de l'oracle est celui où les deux machines qui veulent communiquer se connaissent déjà mais hésitent sur les adresses IP à utiliser, puisque ce choix influencera le chemin pris (cela ne concerne évidemment que les machines ayant plusieurs adresses). Cette approche, utilisée dans le système IDIPS (voir Saucez, D., Donnet, B., and O. Bonaventure, « Implementation and Preliminary Evaluation of an ISP-Driven Informed Path Selection », CoNEXT 2007) pourrait être utilisé pour le pair-à-pair en considérant l'ensemble des pairs possibles comme étant une immense machine virtuelle qu'on cherche à atteindre, un genre d'anycast.
Bien des questions restent ouvertes à l'heure actuelle (section 4). Ainsi, le problème des machines malveillantes qui vont essayer, dans le cas où le système de mesure est distribué, de perturber les mesures ou d'injecter de faux résultats (section 4.2). Dans un réseau de la taille de l'Internet, et compte-tenu du fait que certains ont un intérêt financier à limiter le partage de fichiers, il ne fait guère de doute qu'il y aura de telles machines pirates. Il n'existe pas actuellement de solutions miracles contre elles. Des tests de vraisemblance ont été proposés, pour vérifier si les mesures d'une machine ne s'écartent pas trop de celles des autres. Mais ces tests sont souvent fondés sur des suppositions qui ne sont pas forcément vraies sur l'Internet (comme l'inégalité triangulaire citée plus haut). Dans les cas où les pairs interrogent un oracle, la question de l'authentification de l'oracle est également cruciale. Mais les réseaux pair-à-pair se prêtent mal aux lourdes solutions d'identité comme les PKI.
Une variante de ce dernier problème se pose d'ailleurs au sujet de l'intégrité des données transmises (section 4.3). Ce n'est pas tout d'authentifier le pair ou l'oracle, encore faut-il être sûr que les informations reçues n'ont pas été modifiées en cours de route. Une telle modification permettrait, par exemple, d'affecter un coût très faible à une cible et de faire réaliser ainsi une dDoS contre elle (RFC 4732).
Enfin, parmi les différents problèmes encore largement ouverts, on peut citer les cas où l'optimisation marche trop bien (section 4.6). Poussée à l'extrême, en effet, l'optimisation ferait que les pairs ne s'adressent qu'à des pairs très proches, chez le même FAI et dans la même région. Les grands essaims pair-à-pair se fragmenteraient alors en essaims locaux, n'ayant pas de communication entre eux, ce qui réduirait la redondance qui fait la solidité du pair-à-pair (voir « Pushing BitTorrent Locality to the Limit » de Stevens Le Blond, Arnaud Legout et Walid Dabbous).
Date de publication du RFC : Octobre 2010
Auteur(s) du RFC : M. Bjorklund (Tail-f Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF netmod
Première rédaction de cet article le 6 octobre 2010
Le protocole standard Netconf (normalisé dans le RFC 6241) permet de configurer un équipement réseau (par exemple un commutateur) à distance. Netconf fonctionne par des RPC dont les paramètres sont des actions à faire effectuer par l'équipement configuré, ou bien les nouvelles valeurs que peut prendre telle ou telle des variables de configuration de cet équipement. Mais comment savoir quelles actions sont possibles, quelles variables existent, et quelles valeurs elles peuvent prendre ? Jusqu'à présent, cela pouvait se spécifier uniquement dans une documentation en langue naturelle fournie avec l'équipement. Désormais, il est possible de spécifier ces informations dans un langage formel, Yang, que décrit notre RFC.
Ce RFC 6020 est très détaillé, près de deux cents pages. Et je n'ai pas personnellement d'expérience pratique avec Yang. Donc, je ne donne ici qu'un très bref résumé. Un tel survol se trouve également dans la section 4 du RFC : Yang modélise les données qui seront utilisées par Netconf. Ces données sont représentées sous forme arborescente. Yang est modulaire (section 5 du RFC), un module Yang pouvant se référer à d'autres modules. Yang définit un ensemble de types pour décrire les données (section 9 et RFC 6991). Il permet également d'indiquer les contraintes que doivent respecter les données. Yang, langage de haut niveau, ne décrit pas l'encodage utilisé sur le câble.
Yang a donc bien des points communs avec le SMI des RFC 2578 et RFC 2579. Avant Netconf, beaucoup de gens pensaient que toute la gestion des équipements réseau se ferait en SNMP, en s'appuyant sur ce modèle SMI. Si, pour la lecture des variables, SNMP s'est largement imposé, force est de constater que, pour l'écriture de variables et pour les actions, SNMP reste très peu utilisé, au profit de toute une galaxie de mécanismes privés (Web, REST, SSH + CLI, etc), galaxie que Netconf vise à remplacer. Une MIB du SMI peut donc être traduite en Yang, l'inverse n'étant pas vrai (Yang étant plus riche).
La syntaxe de Yang utilise des groupes emboîtés, délimités par des accolades. Mais une syntaxe équivalente, en XML, existe, sous le nom de Yin. Tout module Yang peut être traduit en Yin sans perte et réciproquement (voir la section 11 pour plus de détails sur Yin).
Donc, un engin donné, routeur ou autre équipement qu'on veut gérer, est décrit par des modules Yang. Lorsqu'un serveur Netconf à bord dudit engin met en œuvre un module Yang, cela veut dire qu'il permet de modifier, via Netconf, les variables décrites dans le module (le serveur typique met en œuvre plusieurs modules). Voici le début d'un module possible :
// Only an example, not a real module. module acme-system { namespace "http://acme.example.com/system"; prefix "acme"; organization "ACME Inc."; contact "joe@acme.example"; description "The module for entities implementing the ACME system."; revision 2010-08-05 { description "Initial revision."; } ...
On l'a dit, Yang est arborescent. Les feuilles de l'arbre (section 4.2.2.1 du RFC) contiennent une valeur particulière, par exemple, ici, le nom de l'engin géré :
leaf host-name { type string; description "Hostname for this system"; }
Ici, leaf
est un mot-clé de Yang qui indique une
feuille de l'arbre (plus de nœuds en dessous),
host-name
est le nom que l'auteur du module a
donné à une variable, de type « chaîne de caractères ». Lorsqu'un
serveur Netconf enverra cette information à un client (ou
réciproquement), elle sera encodée en XML ainsi
(Netconf utilise XML pour l'encodage des messages) :
<host-name>my-router.example.com</host-name>
Donc, pour résumer, Yang modélise ce qu'on peut lire ou modifier, Netconf permet de le lire ou de le modifier effectivement.
Par contre, si un nœud de l'arbre Yang n'est pas une feuille,
il est désigné par le mot-clé container
. Par
exemple, il y a ici deux containers
emboîtés et
une feuille :
container system { container login { leaf message { type string; description "Message given at start of login session"; } } }
Lorsque Netconf utilise cette donnée, cela ressemblera, sur le câble, à ceci :
<system> <login> <message>Good morning</message> </login> </system>
Yang dispose d'un certain nombre de types pour représenter les données (section 4.2.4 et RFC 6991), mais on peut aussi créer ses types (sections 4.2.5 et 7.3) par exemple ainsi :
typedef percent { type uint8 { range "0 .. 100"; } description "Percentage"; } leaf completed { type percent; }
On a ajouté un intervalle de validité au type prédéfini uint8
.
Autre exemple, en indiquant une valeur par défaut, et en dérivant d'un
type défini dans le module inet
:
typedef listen-ipv4-address { type inet:ipv4-address; default "0.0.0.0"; }
Yang a bien d'autres possibilités, décrites en détail dans les
sections suivantes. Par exemple, dans un monde idéal, tous les engins
mettant en œuvre un module Yang donné géreraient la totalité des
variables du module. Mais, comme ce n'est pas forcément le cas, Yang
permet des déviations (sections 5.6.3 et 7.18.3). Prenons l'exemple du RFC, un
routeur BGP qui suit un module Yang BGP. Le
module ne donne pas de limite au nombre de pairs BGP mais un routeur
bas de gamme pourrait avoir une limite, disons à 16 pairs. Un client
Netconf qui tenterait de configurer un dix-septième pair recevrait
donc une erreur. Le mot-clé Yang deviation
permettrait audit client de savoir à l'avance en quoi ce routeur
particulier dévie du modèle BGP général. Le client Netconf n'aurait
donc pas à essayer pour voir, il pourrait savoir à l'avance que
l'opération de configuration du dix-septième pair ne marchera pas.
La syntaxe formelle de Yang est décrite en section 6. Elle ressemble à celle de langages de programmation comme C ou à celle de SMIng du RFC 3780 (RFC qui n'a pas eu de succès). Cette syntaxe favorise la lisibilité par des humains, le cahier des charges étant de privilégier les lecteurs, pas les auteurs de modules, ni les programmeurs d'outils Yang. À noter que, comme dans toutes les normes modernes, Yang n'est pas limité à l'ASCII et peut utiliser tout Unicode.
Bien que Yang n'utilise pas XML, il réutilise un langage de ce monde, XPath (sections 6.4 et 7.5.3). XPath sert à indiquer les dépendances entre nœuds de l'arbre.
Yang permet en effet de définir des contraintes (section 8) que doivent
respecter les variables, avec la directive
must
. Par exemple :
must "ifType != 'ethernet' or " + "(ifType = 'ethernet' and ifMTU = 1500)" { error-message "An ethernet MTU must be 1500"; }
Voici un exemple de requête Netconf complète, correspondant à une
variable Yang. Soit un équipement muni d'un serveur
SSH et d'un serveur Netconf pour
sa configuration. Disons que le serveur Netconf met en œuvre la variable
Yang port
, définie ainsi :
leaf port { type inet:port-number; default 22; description "The port which the SSH server listens to" }
La requête Netconf <edit-config>
(RFC 6241, section 7.2) qui configure le serveur SSH pour écouter sur le
port 2022 serait :
<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config> <target> <running/> </target> <config> <system xmlns="http://example.com/schema/config"> <services> <ssh> <port>2022</port> </ssh> </services> </system> </config> </edit-config> </rpc>
Le choix de Yang comme langage standard pour la description des capacités d'un serveur Netconf ne s'était pas fait sans mal. Plusieurs concurrents avaient été envisagés notamment Relax NG, un choix logique puisque Netconf utilise XML. Un langage de description de schémas comme Relax NG semblait donc un choix raisonnable. Parmi les discussions à ce sujet, citons par exemple le débat qui avait eu lieu sur la liste du secteur Applications de l'IETF. Les raisons du choix de Yang, telles que vues par les concepteurs de Yang, sont décrites sur le site officiel du projet mais je trouve cette comparaison très unilatérale.
Un bon tutoriel Netconf, couvrant également Yang, est disponible en
http://www.aims-conference.org/issnsm-2008/06-netconf-yang.pdf
.
Quelles sont les mises en œuvre de Yang ? Il en existe une
liste sur le
site officiel. Voyons par exemple l'outil pyang, qui sert à valider
des schémas Yang et à les convertir dans d'autres formats. Il ne
semble plus maintenu depuis longtemps mais, bon, il marche. Il peut produire du XSD et
du RelaxNG - enfin du DSDL mais c'est presque
pareil. Voici un exemple de test d'un schéma invalide
(leaf
a été tapé laf
) :
% pyang test.yang test.yang:11: error: unexpected keyword "laf"
Et, si on corrige :
% pyang test.yang %
Maintenant, convertissons en Yin :
% cat test.yang module acme-foo { namespace "http://acme.example.com/foo"; prefix "acfoo"; list interface { key "name"; leaf name { type string; } leaf mtu { type uint32; description "The MTU of the interface."; } } } % pyang -fyin test.yang <?xml version="1.0" encoding="UTF-8"?> <module name="acme-foo" xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:acfoo="http://acme.example.com/foo"> <namespace uri="http://acme.example.com/foo"/> <prefix value="acfoo"/> <list name="interface"> <key value="name"/> <leaf name="name"> <type name="string"/> </leaf> <leaf name="mtu"> <type name="uint32"/> <description> <text>The MTU of the interface.</text> </description> </leaf> </list> </module>
Et voici une conversion du même code en DSL :
% pyang -fdsdl test.yang <?xml version='1.0' encoding='UTF-8'?> <grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" ns="http://acme.example.com/foo" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:acfoo="http://acme.example.com/foo" xmlns:dc="http://purl.org/dc/terms" xmlns:dsrl="http://purl.oclc.org/dsdl/dsrl" xmlns:nm="urn:ietf:params:xml:ns:netmod:dsdl-attrib:1" xmlns:sch="http://purl.oclc.org/dsdl/schematron"> <dc:source>YANG module 'acme-foo' (automatic translation)</dc:source> <start> <zeroOrMore> <element name="interface" nm:key="name"> <element name="name"> <data type="string"/> </element> <optional> <element name="mtu"><a:documentation>The MTU of the interface.</a:documentation> <data type="unsignedInt"/> </element> </optional> </element> </zeroOrMore> </start> </grammar>
Le site officiel du projet, http://www.yang-central.org/
, contient beaucoup d'autre
information sur Yang. Une version de plus récente de Yang existe
aussi, la 1.1, normalisée dans le RFC 7950.
Date de publication du RFC : Septembre 2010
Auteur(s) du RFC : F. Baker (Cisco), W. Harrop, G. Armitage (CAIA, Swinburne University of Technology)
Pour information
Première rédaction de cet article le 30 septembre 2010
Il y a longtemps que les chercheurs en sécurité des réseaux utilisent des darknets, des réseaux dont les adresses IP ne sont normalement pas attribuées, pour analyser les attaques. Si on annonce une route vers un tel réseau, le trafic qu'on capte est essentiellement composé d'attaques ou de reconnaissances préalables à une attaque puisque rien de légitime ne peut utiliser ces réseaux. L'inconvénient des darknets est qu'ils sont trop gros et trop visibles : les attaquants apprennent vite leur existence et les mettent alors sur leur liste « pas touche » et les attaques cessent. Ce RFC décrit une alternative, le greynet, dont le préfixe IP est alloué et routé mais au sein duquel certaines adresses ne correspondent pas à une machine en activité.
Normalement, un routeur IP doit jeter les datagrammes destinés à une adresse qui ne répond pas aux requêtes ARP (RFC 826) ou ND (RFC 4861). On pourrait envisager de configurer des règles spéciales par adresse IP, pour copier les datagrammes destinés à ces machines vers la sonde d'observation. Mais, pour construire facilement le greynet, le RFC suggère une autre méthode : configurer le routeur pour que, au lieu de jeter les paquets qui ne peuvent pas être délivrés, il les copie vers la machine de surveillance. Toute adresse IP non affectée devient alors membre du greynet.
On peut ainsi détecter les attaques (ou les reconnaissances) vers ces adresses, mais aussi les cas d'usurpation de ces adresses par un tiers. Ces usurpations vont en effet produire du backscatter, de l'émission par les cibles en réponse aux reconnaissances, et une partie au moins de ce backscatter atteindra le greynet.
La section 2 sert ensuite de manuel pour
l'administrateur réseaux qui voudrait déployer
un tel système. Il doit évidemment d'abord mettre en place la machine
de collecte, qui va recevoir les paquets, les enregistrer et plus tard
les analyser. Ensuite, il peut utiliser le routage IP normal et
choisir un préfixe non utilisé pour le router vers cette machine,
créant ainsi un darknet (section 2.1). Sur
Linux, par exemple, cela se ferait avec
route add -net 192.0.2.128/25 gw 198.51.100.1
où
192.0.2.128/25
est le préfixe du
darknet et 198.51.100.1
l'adresse de la machine de collecte.
Mais s'il veut faire un greynet, il lui faut un routeur un peu spécial (section 2.2) qui va devoir, lorsqu'il reçoit un paquet pour lequel il n'a pas eu de réponse aux requêtes ARP et ND, le faire suivre à la machine de collecte. C'est à la fois plus simple qu'un darknet (pas de configuration explicite, à part l'adresse de la machine de collecte, cf. section 3) et plus compliqué (aucun routeur IP normal ne sait faire cela : en cas de non-réponse à ARP et ND, le paquet est abandonné).
La première documentation des greynets était
dans « Greynets: a definition and
evaluation of sparsely populated darknets », dans la
30th Conference on Local Computer Networks de
l'IEEE en 2005. Elle a
été suivie de plusieurs expériences, résumées dans la section 1.1 du
RFC. L'utilisation du routeur pour identifier les adresses du
greynet (ce sont celles qui ne répondent pas en ARP
ou en ND) est venue après. La première mise en œuvre était sur
un routeur Linux. Le fichier à récupérer est
http://www.owenstephens.co.uk/files/neigh_fwd.c
, et il
se place dans le répertoire net/core
des sources
du noyau. Il faut ensuite appeler les fonctions nécessaires depuis
neighbour.c
, le moyen le plus simple étant sans
doute de patcher ce dernier
avec http://www.owenstephens.co.uk/files/neighbour.c.diff
. (Merci à
Owen Stephens pour avoir mis les sources en ligne.)
L'ajout d'IPv6 est venue encore ultérieurement. Bien qu'on entende souvent dire qu'un balayage complet d'un réseau IPv6 est impossible, vu le nombre d'adresses possibles, le RFC 7707 a montré que c'était faux. En pratique, les attaques IPv6 n'ont jamais été observées dans la nature mais il ne fait guère de doute que cela se produira un jour.
Un dernier avertissement pour ceux qui veulent tenter l'aventure : lisez bien la section 6 sur la sécurité. Tout dispositif de collecte peut faire l'objet d'abus, par exemple par un méchant qui, sachant qu'une collecte est en cours, va tenter de la saturer en envoyant plein de paquets.
Date de publication du RFC : Novembre 2010
Auteur(s) du RFC : P. Hoffman (VPN Consortium)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 22 novembre 2010
L'allocation d'un nouveau numéro pour un algorithme cryptographique dans DNSSEC exigeait auparavant un RFC sur le chemin des normes. Désormais, n'importe quel RFC conviendra, ce qui est une libéralisation bienvenue.
Ces numéros sont attribués par l'IANA,
stockés dans un registre public et permettent,
lorsqu'on récupère un enregistrement DNSSEC,
de savoir comment l'interpréter. Ainsi, le TLD
.pm
est signé avec
l'algorithme de numéro 8, soit RSA/SHA-256 :
% dig +dnssec ANY pm. ... pm. 172800 IN RRSIG SOA 8 1 172800 20100818151448 20100719141448 14659 pm. oepDlhY...
L'espace de nommage de ces codes ne fait qu'un seul octet, soit 256 possibilités seulement. Ce point a fait l'objet d'inquiétudes au moment de la libéralisation de l'allocation.
La norme DNSSEC, le RFC 4034 (section 7), reprenant des normes antérieures, impose un « IETF standards action » pour enregistrer un nouveau code, sauf pour 253 et 254, qui sont utilisables pour de expérimentations sans formalité. Une « IETF standards action », comme nous l'apprend le RFC 5226, est la publication d'un RFC situé sur le chemin des normes. C'est donc une opération plutôt lourde (mais possible : GOST a eu le numéro 12 ainsi, grâce au RFC 5933).
La section 2 du RFC explique le pourquoi de la libéralisation :
Pour être complètement en sécurité, notre RFC demande à l'IETF de réévaluer les critères d'allocation lorsque 120 entrées du registre auront été allouées (en juillet 2010, on en a 11...). C'est pour cela que la plage 123-251 du registre est marquée comme réservée. Et les codes 253 et 254 restent disponibles pour les expérimentations.
Quelles sont les conséquences pour les mises en œuvre de DNSSEC (section 3) ? D'abord, il faut bien voir qu'un programme qui fait du DNSSEC n'a jamais été obligé d'implémenter tous les algorithmes du registre. Ceci ne change pas. Il y aura donc toujours des algorithmes qui ne seront pas universellement mis en œuvre. Les seuls algorithmes qui sont garantis sont ceux indiqués comme obligatoires dans le RFC 4034 (annexe A.1) ou son successeur. Actuellement, il n'y a que RSA/SHA-1.
Enfin, notons que le RFC précise que l'ordre des algorithmes dans le registre n'implique rien sur leur force cryptographique respective, ou leur sécurité...
Comme notre RFC ne fait que changer une règle d'allocation dans un registre IANA, toute sa partie normative se concentre dans la section 4, « IANA considerations ». En un mot, un RFC de n'importe quel statut suffit désormais pour demander un code dans le registre. Certains cas dans DNSSEC n'étaient pas couverts par cette libéralisation, mais c'est désormais le cas depuis le RFC 9157.
RFC des différentes séries : 0 1000 2000 3000 4000 5000 6000 7000 8000 9000