Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

echoping

Ève

Recherche dans ce blog :

Ce blog n'a d'autre prétention que de me permettre de mettre à la disposition de tous des petits textes que j'écris. On y parle surtout d'informatique mais d'autres sujets apparaissent parfois.


RFC 7323: TCP Extensions for High Performance

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : D. Borman (Quantum Corporation), B. Braden (University of Southern California), V. Jacobson (Google), R. Scheffenegger (NetApp)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 21 septembre 2014


L'algorithme originel de TCP rendait ce protocole de transport trop prudent et n'utilisant pas assez les réseaux, notamment ceux à forte latence. Après quelques essais, le RFC 1323, publié en 1992, a permis à TCP de fonctionner correctement sur une bien plus grande variété de réseaux, et jusqu'à aujourd'hui. Il est désormais remplacé par ce nouveau RFC 7323 qui, après une longue genèse, représente l'état de l'art en matière de performances TCP. Ce nouveau RFC est une lecture indispensable pour les fans de TCP ou tout simplement pour ceux qui veulent comprendre en détail ce protocole.

Avant le RFC 1323, TCP (normalisé dans le RFC 793 en 1981) se comportait très bien sur les réseaux locaux, ainsi que sur les réseaux distants à faible débit, comme ce qu'on avait sur un modem. Mais il était beaucoup moins satisfaisant sur les réseaux à forte latence et forte capacité, les réseaux à fort BDP où BDP signifie Bandwitdh-Delay Product. Si la capacité est faible ou la latence faible, pas de problèmes. Si leur produit dépasse une certaine valeur, TCP n'était pas capable de remplir la fenêtre et ses performances restaient en deça du maximum théorique du réseau.

La section 1 décrit ce problème. TCP avait été conçu (et avec succès) pour tourner sur des réseaux très disparates, et pour s'adapter automatiquement à leurs caractéristiques (taux de perte, latence, taux de duplication...) À l'époque du RFC 1323, TCP tournait en production sur des réseaux dont les capacités allaient de 100 b/s à 10 Mb/s et cette plage s'est nettement élargie depuis. Existe-t-il une limite au débit de TCP, au-delà de laquelle il ne servirait à rien d'accélérer encore les réseaux ? La question n'a pas de réponse simple.

La caractéristique importante du réseau n'est en effet pas la capacité mais le produit de la capacité et de la latence, le BDP cité plus haut. C'est cette caractéristique qui indique la taille du tuyau que TCP doit remplir, la capacité étant le « diamètre » du tuyau et la latence sa « longueur ». Si la capacité croît beaucoup, au rythme des progrès techniques, la latence est bloquée par la finitude de la vitesse de la lumière et la seule façon de l'améliorer est de raccourcir les câbles. Donc, un gros BDP oblige TCP à avoir davantage de données « en transit », envoyées, mais n'ayant pas encore fait l'objet d'un accusé de réception, ce qui implique des tampons d'entrée/sortie de grande taille mais qui implique aussi la possibilité de garder trace de grands nombres (par exemple le nombre d'octets en transit), donc d'avoir des compteurs de taille suffisante. Ces liaisons Internet avec un fort BDP sont parfois surnommées les « éléphants » de l'anglais LFN (Long Fat Network).

Un exemple typique d'éléphant est une liaison satellite, avec sa capacité souvent respectable mais sa latence terrible, due à la nécessite d'un aller-retour avec l'orbite géostationnaire. À l'époque du RFC 1123, le BDP de ces liaisons était d'environ 1 Mbit soit 100 segments TCP de 1 200 octets chacun. Si une mise en œuvre de TCP se limitait à 50 segments envoyés avant de recevoir un accusé de réception, elle n'utiliserait que la moitié de la capacité disponible. Et les liaisons terrestres peuvent être des éléphants aussi. Un lien transcontinental aux États-Unis a une latence de 30 ms, ce qui, à 45 Mb/s, fait également un BDP de 1 Mbit.

Qu'est-ce qui empêchait TCP de tirer profit de ces éléphants ? Trois points :

  • La taille de la fenêtre n'est stockée par défaut que sur 16 bits, ne permettant pas de fenêtre plus grande que 65 535 octets. Ce problème est résolu par le RFC 1323 avec l'introduction du window scaling.
  • La récupération était trop longue en cas de perte de paquets. Les premiers TCP, dès qu'un paquet était perdu, attendaient de vider complètement le pipeline, puis repartaient de zéro, comme pour une connexion TCP neuve. En 1990, l'algorithme de TCP avait été modifié pour permettre un redémarrage plus rapide, tant qu'on ne perdait qu'un seul paquet par fenêtre TCP. Mais, avec des fenêtres plus grandes, cette probabilité de perte augmente. Les accusés de réception de TCP étant cumulatifs, une perte de paquet survenant au début de la fenêtre peut faire tout perdre. La solution a été une option d'accusés de réception sélectifs (SACK pour Selective ACKnowledgment). Ce point n'a pas été traité dans le RFC 1323 mais dans le RFC 2018.

Un autre problème à considérer est la fiabilité. Si on utilise TCP, c'est pour avoir certaines garanties : que tous les octets émis seront reçus, dans le même ordre, etc. Est-ce que le passage à de plus hautes performances menace ces garanties ? Par exemple, avec des fenêtres plus grandes, la probabilité qu'un paquet ancien, appartenant à une précédente connexion, lorsqu'il finit par arriver, tombe dans la fenêtre courante, cette probabilité est plus élevée. Dans ces conditions, les données seraient corrompues. La principale protection de TCP contre cet accident est la notion de MSL (Maximum Segment Lifetime), le temps qu'un segment peut traîner sur l'Internet. Il ne faut pas réutiliser des numéros de séquence avant qu'une durée supérieure ou égale à la MSL se soit écoulée. Ce numéro ne faisant que 32 bits, cela peut être délicat, surtout aux débits élevés (même sans fenêtres agrandies). La MSL est généralement prise à deux minutes et, à seulement 1 Gb/s, les numéros de séquence ne durent que dix-sept secondes. Or, aucun mécanisme sur l'Internet ne garantit le respect de la MSL. Un vieux paquet ne sera pas jeté. D'où l'utilisation par notre RFC 7323 de l'option Timestamps pour détecter les segments trop anciens et se protéger donc contre la réutilisation des numéros de séquence TCP (solution PAWS, en section 5).

À noter que ces mécanismes sont conçus pour les réseaux à fort BDP. Sur des réseaux à faible BDP, il peut être intéressant de les débrayer, manuellement ou automatiquement.

Reste que les solutions proposées dans ce RFC dépendent des options TCP. Pour certains protocoles, par exemple IP, certaines options ont du mal à passer à travers le réseau (section 1.3 de notre RFC). TCP semble mieux placé de ce point de vue (il est mentionné à la fin de mon article sur les options IP). On peut consulter à ce sujet « Measuring Interactions Between Transport Protocols and Middleboxes » et « "Measuring the Evolution of Transport Protocols in the Internet ».

La section 2 de notre RFC présente la première option qui avait été normalisée pour améliorer les performances de TCP sur les liens à fort BDP (Bandwidth-Delay Product), le window scaling. L'idée de base est très simple : 16 bits pour indiquer la taille de la fenêtre, c'est trop peu, on va donc appliquer un facteur (indiqué dans une option TCP) au nombre décrit par ces 16 bits. À noter que, comme les options ne sont envoyées qu'au début de la connexion TCP, le facteur est constant (la fenêtre elle-même étant dynamique).

L'option Window Scale comprend trois champs : Type, Longueur et Valeur. Le type vaut 3 et est enregistré dans le registre des options, la longueur est forcément de 3 (trois octets en tout) et la valeur est un octet qui indique de combien de bits on va décaler la taille de la fenêtre. Une valeur de 0 indique pas de décalage, donc un facteur de 1 (une telle valeur n'est pas inutile car elle sert à indiquer au pair TCP qu'on sait gérer le window scaling). Une valeur de 1 indique qu'on double la taille de la fenêtre pour connaître la vraie valeur, etc. Voici un exemple vu par Wireshark :

Transmission Control Protocol, Src Port: 51336 (51336), Dst Port: 4332 (4332), Seq: 0, Len: 0
...
   Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
...
        Window scale: 5 (multiply by 32)
            Kind: Window Scale (3)
            Length: 3
            Shift count: 5

Et, quelques paquets plus loin, on voit bien le facteur d'échelle appliqué (32, soit 2^5). Le champ indiquant la longueur de la fenêtre vaut 728 octets mais il faut en fait lire 23 296 octets :

    Window size value: 728
    [Calculated window size: 23296]
    [Window size scaling factor: 32]

(À noter que je parlais aussi de cette option à la fin de l'article sur le RFC 793.) Sur Linux, cette option peut s'activer ou se désactiver avec le paramètre sysctl net.ipv4.tcp_window_scaling (c'est parfois nécessaire de la désactiver dans certains réseaux bogués qui bloquent les paquets TCP contenant des options inconnues d'eux).

Autre option normalisée ici, la meilleure mesure du RTT par l'option Timestamps, en section 3. La mesure du RTT est cruciale pour TCP, pour éviter des accidents comme la congestion brutale décrite dans le RFC 896. Si TCP ne mesure qu'un seul paquet par fenêtre, les résultats seront mauvais pour les grandes fenêtres, par simple problème d'échantillonage (critère de Nyquist).

L'option Timestamps a le type 8, une longueur de 10, et deux champs de quatre octets, l'heure qu'il était au moment de l'envoi et l'heure lue dans le paquet pour lequel on accuse réception (cette valeur n'a donc de sens que si le paquet a le bit ACK). L'« heure » n'est pas forcément celle de l'horloge au mur (puisque, de toute façon, on n'utilisera que des différences), l'important est qu'elle avance à peu près au même rythme. En fait, il est même recommandé que l'horloge ne soit pas directement celle de la machine, pour éviter de donner une information (la machine est-elle à l'heure) à un éventuel observateur indiscret. La section 7.1 recommande d'ajouter à l'horloge de la machine un décalage spécifique à chaque connexion, et tiré au hasard au début de la connexion.

Attention, il n'y a aucune raison qu'on ait le même nombre de paquets dans les deux sens. On peut voir un pair TCP envoyer deux paquets et le récepteur ne faire qu'un seul paquet d'accusé de réception. Dans ce cas, ledit récepteur devra renvoyer le temps du paquet le plus ancien. Toujours avec Wireshark, cela donne :

Transmission Control Protocol, Src Port: 4332 (4332), Dst Port: 51336 (51336), Seq: 0, Ack: 1, Len: 0
...
   Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
...
        Timestamps: TSval 2830995292, TSecr 27654541
            Kind: Timestamp (8)
            Length: 10
            Timestamp value: 2830995292
            Timestamp echo reply: 27654541

Et, dans le paquet suivant de la même direction, les compteurs ont augmenté :

        Timestamps: TSval 2830995566, TSecr 27654569
            Kind: Timestamp (8)
            Length: 10
            Timestamp value: 2830995566
            Timestamp echo reply: 27654569

Ici, il s'agissait d'une communication entre deux machines Linux. La génération des estampilles temporelles dans les options TCP est contrôlée par la variable sysctl net.ipv4.tcp_timestamps (documentée, comme les autres, dans le fichier Documentation/networking/ip-sysctl.txt des sources du noyau). Par exemple :

% sysctl net.ipv4.tcp_timestamps
net.ipv4.tcp_timestamps = 1

Cela signifie que cette option est activée sur cette machine (0 = désactivée).

Cette option d'estampillage temporel est utilisée dans PAWS (présenté plus loin) mais aussi dans d'autres systèmes comme ceux du RFC 3522 ou du RFC 4015.

La section 4 décrit l'utilisation des estampilles temporelles pour mesurer le RTT des paquets, ce qui sert à TCP à déterminer le RTO (Retransmission TimeOut), le délai au bout duquel TCP s'impatiente de ne pas avoir eu d'accusé de réception et réémet. Voir à ce sujet le RFC 6298, pour savoir tout de ce calcul du RTO, et aussi le papier « On Estimating End-to-End Network Path Properties ».

La section 5 présente le mécanisme PAWS (Protection Against Wrapped Sequence numbers), qui sert à lutter contre les vieux segments TCP qui arriveraient tard et avec, par malchance, un numéro de séquence qui a été réutilisé depuis et est donc considéré comme valide. Les numéros de séquence étant stockés sur 32 bits seulement, la probabilité d'un tel accident augmente avec la capacité des réseaux. PAWS se sert de la même option Timestamps qui a été présentée plus haut. L'idée est que si un segment TCP arrive avec une estampille temporelle trop ancienne, par rapport à celles reçues récemment, on peut le jeter sans remords. Comme pour tous les usages de l'option Timestamps, il ne nécessite pas de synchronisation d'horloges entre les deux pairs TCP car les comparaisons se font toujours entre les estampilles mises par une même machine.

Quels sont les changements depuis le RFC 1323 (voir l'annexe H) ? D'abord, une partie du texte a été supprimée, celle consacrée à la discussion des mérites des différentes options. Si on veut lire cette discussion, il faut reprendre le RFC 1323.

Ensuite, de nombreux changements importants ont été apportés. Je ne vais pas les lister tous ici mais, par exemple, la section 3.2 a été très enrichie pour mieux préciser l'utilisation des estampilles temporelles (trop floue précédémment), l'algorithme de sélection de l'estampille dans la section 3.4 du RFC 1323 a été corrigé (deux cas n'étaient pas traités), le cas des paquets TCP RST (ReSeT d'une connexion) a été décrit, la discussion sur la MSS a été déplacée dans le RFC 6691, etc.

Nouveauté de ce RFC (le RFC 1323) clamait qu'il ne se préoccupait pas du sujet), la section 7, sur la sécurité. Ouvrir la fenêtre TCP pour augmenter les performances, c'est bien. Mais cela ouvre également la voie à des attaques où un méchant tente de glisser un paquet dans la séquence des paquets TCP. Normalement, un attaquant situé en dehors du chemin des paquets, qui ne peut donc pas les observer, doit, s'il veut réussir cette injection, deviner le numéro de séquence (RFC 5961). Mais plus la fenêtre est grande et plus c'est facile (il n'a pas besoin de deviner le numéro exact, juste de deviner un numéro qui est dans la fenêtre). Il faut donc mettre en rapport le gain de performances avec le risque d'accepter de faux paquets. PAWS protège partiellement contre ces attaques mais en permet de nouvelles (par exemple l'injection d'un paquet ayant une estampille dans le futur permettrait, si ce paquet est accepté, de faire rejeter les vrais paquets comme étant trop anciens).

Les fanas de programmation et de placement des bits dans la mémoire liront avec plaisir l'annexe A, qui recommande un certain arrangement des options dans le paquet TCP : en mettant deux options vides (NOP) avant l'option Timestamp, on obtient le meilleur alignement en mémoire pour une machine 32-bits.


Téléchargez le RFC 7323


L'article seul

RFC 7343: An IPv6 Prefix for Overlay Routable Cryptographic Hash Identifiers Version 2 (ORCHIDv2)

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : J. Laganier (Luminate Wireless), F. Dupont (Internet Systems Consortium)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 21 septembre 2014


Une nouvelle pierre dans la construction d'une éventuelle future architecture Internet séparant identificateur et localisateur, les ORCHID sont des identificateurs dont la forme est celle d'une adresse IPv6 (afin de pouvoir être utilisés dans les API qui attendent des adresses IP). Ils sont typiquement utilisés dans le cadre de protocoles comme HIP (RFC 4423). Pour les distinguer, notre RFC réserve le préfixe 2001:20::/28. Si vous voyez une telle « adresse IP », ne vous attendez pas à pouvoir forcément la « pinguer », elle n'a pas vocation à être routable, c'est un pur identificateur.

ORCHID signifie Overlay Routable Cryptographic Hash Identifiers. L'adresse IP traditionnelle joue un rôle double, localisateur d'une machine dans le réseau et identificateur d'une machine. ORCHID est prévu pour les protocoles qui séparent identificateur et localisateur (comme HIP) et sert d'identificateur. Leur forme physique est celle d'une adresse IPv6, afin de ne pas changer les API et les applications qui les utilisent (on peut publier des ORCHID dans le DNS, faire un ssh 2001:20::1:42 si on est sur une machine HIP, etc). Bien sûr, il serait plus propre de tout refaire de zéro, avec de nouvelles API, plus adaptées à cette séparation identificateur/localisateur, mais c'est irréaliste. (Dommage, cela aurait permis d'utiliser tout le ::/0 pour ORCHID au lieu de les limiter à un préfixe. Voir la section 4 à ce sujet.)

Voilà pourquoi vous ne trouverez pas des adresses de ce préfixe dans les paquets IPv6 ordinaires (l'identificateur est traduit en localisateur par HIP avant que le paquet soit mis sur le câble). Les paquets ayant ces adresses sont routables dans le réseau virtuel HIP, pas dans l'Internet actuel. Les ORCHID sont donc utilisés « entre machines consentantes », dit le RFC. Un préfixe spécial, le 2001:20::/28, est réservé par l'IANA pour éviter les confusions avec les « vraies » adresses IP. Il figure dans le registre des adresses spéciales (RFC 6890). Cela permet aussi des choses comme une mise en œuvre de HIP sous forme d'un programme extérieur au noyau du système, utilisant le préfixe pour distinguer facilement les ORCHID, et permettre au noyau de transmettre les paquets utilisant des ORCHID à ce programme extérieur. Dans tous les cas, l'utilisation des ORCHID nécessitera un programme (dans le noyau ou extérieur) qui fera la correspondance entre les identificateurs maniés par les applications (les ORCHID) et les localisateurs mis dans l'en-tête des paquets IPv6 envoyés sur le réseau.

Les ORCHID ont été normalisés pour la première fois dans le RFC 4843. Ce nouveau RFC est la version 2, très différente (nouveau préfixe, nouvel algorithme de construction, voir l'annexe B pour toutes les différences entre ORCHID v1 et ORCHID v2).

Les ORCHID ont les propriétés suivantes :

  • Quasi-unicité (sauf malchance, voir l'annexe A),
  • Sécurité, via une chaîne de bits utilisée pour leur construction (la plupart du temps, une clé cryptographique, qui servira à authentifier l'ORCHID),
  • Limitation au préfixe 2001:20::/28,
  • Routabilité dans l'overlay, pas dans le réseau sous-jacent (l'Internet d'aujourd'hui).

Comme les adresses CGA (RFC 3972), les ORCHID sont en général utilisés avec de la cryptographie, la section 2 de notre RFC détaillant le mécanisme de construction d'une ORCHID. On part d'un certain nombre de paramètres, un OGA ID (ORCHID Generation Algorithm IDentifier) qui identifie la fonction de hachage utilisée, un contexte qui identifie le protocole qui utilise ORCHID (la liste possible est à l'IANA), une chaîne de bits et quelques autres. La chaîne de bits est censée être unique. En pratique, ce sera souvent une clé publique. Il y aura un contexte pour HIP, et un pour les futurs autres protocoles qui utiliseront ORCHID. On concatène chaîne de bits et contexte, on les condense et on a un identificateur de 96 bits de long. Il n'y a plus ensuite qu'à ajouter le préfixe 2001:20::/28 et l'identificateur OGA (4 bits) pour avoir l'ORCHID complet de 128 bits.

Maintenant qu'on a construit des ORCHID, comment s'en sert-on ? La section 3 décrit les questions de routage et de transmission. Les routeurs ne doivent pas traiter les ORCHID différemment des autres adresses IP par défaut (afin d'éviter de gêner le déploiement ultérieur de nouveaux usages des ORCHID). Par contre, ils peuvent être configurés pour les rejeter (on peut changer la configuration plus tard, mais c'est plus difficile pour le code), par exemple par une ACL.

La section 4 revient sur les décisions qui ont été prises pour la conception des ORCHID. La principale était la longueur du préfixe. Un préfixe plus court aurait laissé davantage de place pour le résultat de la fonction de condensation, résultat qu'on doit tronquer à 96 bits, au détriment de la sécurité. Mais cela aurait avalé une plus grande partie de l'espace d'adressage d'IPv6. Pour gagner des bits, le contexte (le protocole utilisé) n'est pas dans l'ORCHID lui-même mais dans les paramètres d'entrée qui seront condensés. On ne peut donc pas, en regardant un ORCHID, connaître le contexte (on peut connaitre la fonction de hachage utilisée, via l'OGA ID qui, lui, est dans l'ORCHID final). On ne peut que vérifier a posteriori que le contexte supposé était le bon. Cela comble un des principaux défauts d'ORCHID v1 (dans le RFC 4843), l'absence d'agilité cryptographique (la possibilité de changer d'algorithme suite aux progrès de la cryptanalyse). Par exemple, dans l'ancienne norme ORCHID, HIP était restreint à utiliser SHA-1.

Si vous vous lancez dans l'analyse sécurité d'ORCHID, regardez aussi la section 5. ORCHID dépend de la sécurité des fonctions de condensation (RFC 4270) pour garantir la liaison sécurisée entre une clé publique et l'ORCHID. La nécessité de tronquer leur résultat, pour tenir dans les 128 bits d'une adresse IPv6 (moins le préfixe et le OGA ID) a affaibli ces fonctions (le RFC 6920, quoique parlant d'un sujet très différent, discutait déjà des conséquences de cette troncation).

L'annexe A du RFC, elle, se penche sur les risques de collision. Après tout, chaque ORCHID est censé être unique. Or, il n'y a pas de registre central des ORCHID : chacun les génère de son côté. Il n'y a donc qu'une unicité statistique : il est très improbable que deux machines génèrent le même ORCHID.

Et l'annexe B résume les différences entre les ORCHID v1 du RFC 4843 et les v2 de ce RFC 7343 :

  • Mécanisme d'agilité cryptographique en mettant l'identificateur de l'algorithme (OGA ID) dans l'ORCHID,
  • Suppression de plusieurs discussions intéressantes mais pas indispensables pour créer des ORCHID (voir le RFC 4843 si vous êtes curieux),
  • Nouveau préfixe IPv6, 2001:20::/28, remplaçant l'ancien 2001:10::/28, désormais restitué à l'IANA et à nouveau libre. Les ORCHID v2 sont donc totalement incompatibles avec les v1.

Les programmeurs de HIP for Linux et OpenHIP ont déjà promis de modifier leur code pour s'adapter à ces nouveaux ORCHID (qui seront dans la prochaine norme HIP, qui remplacera le RFC 5201).

Merci aux deux auteurs du RFC pour leur relecture de cet article.


Téléchargez le RFC 7343


L'article seul

RFC 7321: Cryptographic Algorithm Implementation Requirements and Usage Guidance for Encapsulating Security Payload (ESP) and Authentication Header (AH)

Date de publication du RFC : Août 2014
Auteur(s) du RFC : D. McGrew (Cisco Systems), P. Hoffman (VPN Consortium)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ipsecme
Première rédaction de cet article le 19 septembre 2014


Le protocole de cryptographie IPsec vient avec une liste d'obligations concernant les algorithmes cryptographiques qu'il faut inclure. Autrefois dans le RFC 4835, cette liste est désormais dans ce nouveau RFC 7321. Ainsi, les différentes mises en œuvre d'IPsec sont sûres d'avoir un jeu d'algorithmes corrects en commun, assurant ainsi l'interopérabilité.

Plus précisément, ce nouveau RFC concerne les deux services d'IPsec, ESP (Encapsulating Security Payload, RFC 4303) et AH (Authentication Header, RFC 4302). Les RFC normatifs sur IPsec se veulent stables, alors que la cryptographie évolue. D'où le choix de mettre les algorithmes dans un RFC à part. Par exemple, la section 3.2 du RFC 4303 note « The mandatory-to-implement algorithms for use with ESP are described in a separate RFC, to facilitate updating the algorithm requirements independently from the protocol per se » (c'était à l'époque le RFC 4305, remplacé depuis par le RFC 4835, puis par notre RFC 7321, sept ans après son prédécesseur).

Ce RFC « extérieur » à IPsec spécifie les algorithmes obligatoires, ceux sur lesquels on peut toujours compter que le pair IPsec les comprenne, ceux qui ne sont pas encore obligatoires mais qu'il vaut mieux mettre en œuvre car ils vont sans doute le devenir dans le futur, et ceux qui sont au contraire déconseillés, en général suite aux progrès de la cryptanalyse, qui nécessitent de réviser régulièrement ce RFC (voir section 1). Cette subtilité (différence entre « obligatoire aujourd'hui » et « sans doute obligatoire demain ») mène à une légère adaptation des termes officiels du RFC 2119 : MUST- (avec le signe moins à la fin) est utilisé pour un algorithme obligatoire aujourd'hui mais qui ne le sera sans doute plus demain, en raison des avancées cryptanalytiques, et SHOULD+ est pour un algorithme qui n'est pas obligatoire maintenant mais le deviendra sans doute.

La section 2 donne la liste des algorithmes. Je ne la répète pas intégralement ici. Parmi les points à noter :

  • ESP a un mode de chiffrement intègre (authenticated encryption qu'on peut aussi traduire par chiffrement vérifié ou chiffrement authentifié, que je n'aime pas trop parce qu'on peut confondre avec l'authentification, cf. RFC 5116). Ce mode n'a pas d'algorithme obligatoire mais un SHOULD+ qui sera peut-être donc obligatoire dans la prochaine version, AES-GCM (il était MAY dans le RFC 4835).
  • Le mode le plus connu d'ESP, celui de chiffrement, a deux algorithmes obligatoires, AES-CBC (RFC 3602) et le surprenant NULL, c'est-à-dire l'absence de chiffrement (RFC 2410 ; on peut utiliser ESP pour l'authentification seule, d'où cet algorithme). Il y a aussi un algorithme noté MUST NOT, DES-CBC (RFC 2405) qui ne doit pas être mis en œuvre, afin d'être sûr qu'on ne s'en serve pas (il était seulement SHOULD NOT dans le RFC 4835).
  • Le mode d'authentification (enfin, intégrité serait peut-être un meilleur mot mais c'est subtil) d'ESP a un MUST, HMAC-SHA1 (RFC 2404) mais aussi un SHOULD+ qui pourra le rejoindre, AES-GMAC, GMAC étant une variante de GCM (et qui était en MAY dans le vieux RFC).
  • Et AH, lui, a les mêmes algorithmes que ce mode d'authentification d'ESP.

La section 3 donne des conseils sur l'utilisation d'ESP et AH. AH ne fournit que l'authentification, alors qu'ESP peut fournir également le chiffrement. Bien sûr, le chiffrement sans l'authentification ne sert pas à grand'chose, puisqu'on risque alors de parler à l'homme du milieu sans le savoir (voir l'article de Bellovin, S. « Problem areas for the IP security protocols » dans les Proceedings of the Sixth Usenix Unix Security Symposium en 1996). Certaines combinaisons d'algorithmes ne sont pas sûres, par exemple, évidemment, ESP avec les algorithmes de chiffrement et d'authentification tous les deux à NULL (voir par exemple l'article de Paterson, K. et J. Degabriele, « On the (in)security of IPsec in MAC-then-encrypt configurations » à l'ACM Conference on Computer and Communications Security en 2010). Si on veut de l'authentification/intégrité sans chiffrement, le RFC recommande d'utiliser ESP avec le chiffrement NULL, plutôt que AH. En fait, AH est rarement utile, puisque ESP en est presque un sur-ensemble, et il y a même eu des propositions de le supprimer. AH avait été prévu pour une époque où le chiffrement était interdit d'utilisation ou d'exportation dans certains pays et un logiciel n'ayant que AH posait donc moins de problèmes légaux. Aujourd'hui, la seule raison d'utiliser encore AH est si on veut protéger certains champs de l'en-tête IP, qu'ESP ne défend pas.

La section 4 de notre RFC donne quelques explications à certains des choix d'algorithmes effectués. Le chiffrement intègre/authentifié d'un algorithme comme AES-GCM (RFC 5116 et RFC 4106) est la solution recommandée dans la plupart des cas. L'intégration du chiffrement et de la vérification d'intégrité est probablement la meilleure façon d'obtenir une forte sécurité. L'algorithme de chiffrement AES-CTR (auquel on doit ajouter un contrôle d'intégrité) n'a pas de faiblesses cryptographiques, mais il ne fournit aucun avantage par rapport à AES-GCM (ne tapez pas sur le messager : c'est ce que dit le RFC, je sais que tous les cryptographes ne sont pas d'accord, par exemple parce qu'ils trouvent GCM beaucoup plus complexe).

Par contre, Triple DES et DES, eux, ont des défauts connus et ne doivent plus être utilisés. Triple DES a une taille de bloc trop faible et, au-delà d'un gigaoctet de données chiffrées avec la même clé, il laisse fuiter des informations à un écoutant, qui peuvent l'aider dans son travail de décryptage. Comme, en prime, il est plus lent qu'AES, il n'y a vraiment aucune raison de l'utiliser. (DES est encore pire, avec sa clé bien trop courte. Il a été cassé avec du matériel dont les plans sont publics.)

Pour l'authentification/intégrité, on sait que MD5 a des vulnérabilités connues (RFC 6151), question résistance aux collisions. Mais cela ne gêne pas son utilisation dans HMAC-MD5 donc cet algorithme, quoique non listé pour IPsec, n'est pas forcément ridicule aujourd'hui. SHA-1 a des vulnérabilités analogues (quoique beaucoup moins sérieuses) mais qui ne concernent pas non plus son utilisation dans HMAC-SHA1, qui est donc toujours en MUST. Bien que les membres de la famille SHA-2 n'aient pas ces défauts, ils ne sont pas cités dans ce RFC, SHA-1 étant très répandu et largement suffisant.

Dans le précédent RFC, Triple DES était encore noté comme une alternative possible à AES. Ce n'est plus le cas aujourd'hui, où les vulnérabilités de Triple DES sont bien connues (sans compter ses performances bien inférieures). Triple DES est maintenu dans IPsec (il est en MAY) mais uniquement pour des raisons de compatibilité avec la base installée. Le problème est qu'il n'y a donc plus de solution de remplacement si un gros problème est découvert dans AES (section 5, sur la diversité des algorithmes). Il n'y a aucune indication qu'une telle vulnérabilité existe mais, si elle était découverte, l'absence d'alternative rendrait le problème très sérieux.

Voilà, c'est fini, la section 8 sur la sécurité rappelle juste quelques règles bien connues, notamment que la sécurité d'un système cryptographique dépend certes des algorithmes utilisés mais aussi de la qualité des clés, et de tout l'environnement (logiciels, humains).

Ce RFC se conclut en rappelant que, de même qu'il a remplacé ses prédécesseurs comme le RFC 4835, il sera probablement à son tour remplacé par d'autres RFC, au fur et à mesure des progrès de la recherche en cryptographie.

Si vous voulez comparer avec un autre document sur les algorithmes cryptographiques à choisir, vous pouvez par exemple regarder l'annexe B1 du RGS, disponible en ligne.

Merci à Florian Maury pour sa relecture acharnée. Naturellement, comme c'est moi qui tiens le clavier, les erreurs et horreurs restantes viennent de ma seule décision. De toute façon, vous n'alliez pas vous lancer dans la programmation IPsec sur la base de ce seul article, non ?


Téléchargez le RFC 7321


L'article seul

RFC 7372: Email Authentication Status Codes

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : M. Kucherawy
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 17 septembre 2014


Il existe désormais plusieurs techniques d'authentification du courrier électronique, comme SPF ou DKIM. Elles permettent à un serveur de messagerie, s'il le désire, d'accepter ou de rejeter le courrier entrant s'il échoue à ces tests d'authentification. Mais il n'existait pas jusqu'à présent de moyen standard de prévenir l'expéditeur, lors de la session SMTP, de la raison de ce rejet. C'est désormais fait, avec ce nouveau RFC, qui permet de renvoyer des codes de retour SMTP explicites, si on veut.

J'ai bien dit « si on veut » car tous les administrateurs de serveurs ne sont pas d'accord pour indiquer à l'expéditeur les raisons exactes du rejet. Après tout, si l'authentification échoue, c'est peut-être que l'expéditeur était un méchant, un spammeur, par exemple, et, dans ce cas, on ne souhaite pas lui donner de l'information. L'utilisation de ces nouveaux codes de retour est donc optionnelle.

Ces codes sont de type « codes étendus », normalisés par le RFC 3463 et dotés d'un registre IANA depuis le RFC 5248. Les codes « améliorés » du RFC 3463 comportent trois nombres, la classe (2 : tout va bien, 4 : erreur temporaire, 5 : erreur définitive, etc), le second le sujet (6 : problème avec le contenu du message, 7 : problème avec la politique de sécurité, etc) et le troisième le détail. Ils s'écrivent avec un point comme séparateur, contrairement aux codes de retour traditionnels, eux aussi à trois chiffres, mais sans séparateur.

La section 3 du RFC liste ces nouveaux codes. Ils figurent tous dans le registre IANA. Dans quasiment tous les cas, le code de base (non étendu) associé sera 550, le code étendu donnant les détails.

D'abord, pour DKIM (RFC 6376). Il y a deux cas de succès, passing, où la signature DKIM est valide et acceptable, où non seulement la signature est valide mais où elle correspond aux règles locales du serveur récepteur (qui, par exemple, impose que tel ou tel en-tête soit couvert par la signature). Un cas particulier de acceptable (qui a son code spécifique) est celui où le serveur de réception impose que l'auteur du message (dans le champ From:) corresponde à une des identités DKIM utilisées pour signer le message. C'est donc la vérification la plus stricte.

Les codes sont respectivement :

  • X.7.20 (où X indique la classe, qui sera 5 Permanent Failure dans la plupart des cas) : aucune signature DKIM passing.
  • X.7.21 : aucune signature DKIM acceptable. Au moins une signature est valide (passing), autrement on utiliserait X.7.20 mais elle ne correspond pas aux exigences locales (rappelez-vous que la norme DKIM laisse une grande latitude à l'émetteur sur ce qu'il signe et notamment sur l'identité utilisée, voir entre autres la section 1.2 du RFC 6376).
  • X.7.22 : il y a au moins une signature DKIM passing mais elle n'est pas acceptable car l'identité utilisée n'est pas celle contenue dans le champ From: (un cas particulier de X.7.21, donc).

Notez que DKIM permet d'avoir des signatures valides et des invalides sur le même message. En effet, certains logiciels modifient le message en route, invalidant les signatures. Le principe de DKIM est donc qu'on ignore les signatures invalides. On n'envoie les codes de retour indiquant un rejet que lorsqu'on n'a aucune signature valable. À noter aussi que tous ces codes indiquent que le serveur SMTP de réception s'est assis sur l'avis de la section 6.3 (et non pas 6.1 contrairement à ce que dit le nouveau RFC) du RFC 6376. Cet avis dit en effet « In general, modules that consume DKIM verification output SHOULD NOT determine message acceptability based solely on a lack of any signature or on an unverifiable signature; such rejection would cause severe interoperability problems. » Le but est d'augmenter la robustesse de DKIM face à des intermédiaires qui massacreraient des signatures. Mais, bon, il y a des gens qui rejettent les messages juste pour une absence de signature valide, donc, autant leur fournir un code de retour adapté. (Voir aussi la section 4 qui discute ce point et insiste bien sur le fait que cela ne signifie pas une approbation de ce rejet violent par les auteurs du RFC. Cette question a été une des plus chaudement discutées dans le groupe de travail IETF.)

Ensuite, il y a des codes pour SPF (RFC 7208) :

  • X.7.23 : message invalide selon SPF,
  • X.7.24 : pas forcément invalide mais l'évaluation de SPF a entraîné une erreur (problème DNS, par exemple).

Voici à quoi pourrait ressembler une session SMTP avec rejet SPF :

% telnet mail.example.com smtp
220 myserver.example.com ESMTP Postfix (LibreBSD)
...
MAIL FROM:<me@foobar.fr>
550 5.7.23 Your server is not authorized to send mail from foobar.fr

Enfin, il y a un code pour le test dit reverse DNS décrit dans la section 3 du RFC 7001, qui consiste à traduire l'adresse IP de l'émetteur SMTP en nom(s) puis ce(s) nom(s) en adresses IP pour voir si l'adresse originale se trouve dans cet ensemble d'adresses. Il peut conduire au code SMTP X.7.25 en cas d'échec.

La section 4 de notre RFC mentionne un certain nombre de considérations générales sur ces codes de retour. Par exemple, les autres techniques d'authentification développées ultérieurement devront ajouter leur propre code SMTP étendu, sur le modèle de ceux-ci.

Autre point, SMTP ne permet de renvoyer qu'un seul code de retour étendu. Si on a plusieurs techniques d'authentification qui ont échoué, on peut toujours utiliser le code général X.7.26 qui indique que plusieurs tests ont échoué. Mais si on a une erreur d'authentification et une erreur d'un autre type, il n'y a pas de solution propre : il faut choisir une des causes de rejet et renvoyer le code correspondant.

Et la section 5, sur la sécurité, rappelle que l'utilisation de ces codes de retour étendus est facultative. Si vous ne voulez pas révéler à vos correspondants pourquoi vous rejetez leurs messages, vous êtes libre.


Téléchargez le RFC 7372


L'article seul

RFC 7352: Sieve Email Filtering: Detecting Duplicate Deliveries

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : S. Bosch
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 16 septembre 2014


Voici un nouveau test pour le langage de filtrage du courrier Sieve : duplicate permet de tester si un message reçu est un double d'un message déjà arrivé (en général en se fiant au Message-Id:) et, par exemple, d'ignorer le doublon.

Tout le monde a déjà rencontré ce problème : on est inscrit à une liste de diffusion et quelqu'un écrit à la liste en vous mettant en copie. Résultat, on reçoit deux fois le même message. La consommation de ressources réseau et système est négligeable, mais c'est gênant pour le lecteur, qui se retrouve avec deux messages à traiter au lieu d'un. Il serait bien plus pratique de détecter automatiquement le duplicata et de le résorber. Même chose si on est abonné à deux listes de diffusion (encore que, dans ce cas, des informations spécifiques à la liste et ajoutées dans les messages, comme le Archived-At: du RFC 5064, peuvent être utiles).

Beaucoup de gens traitent automatiquement leur courrier, avec des techniques comme Sieve ou procmail et la solution décrite dans ce RFC concerne Sieve (qui est normalisé dans le RFC 5228).

La section 3 de notre RFC décrit le nouveau test duplicate. Il s'utilise ainsi :

require ["duplicate", "fileinto", "mailbox"];

if duplicate {
     fileinto :create "Trash/Duplicate";
}

Ici, si le message est un doublon d'un message existant, il est mis dans le dossier Trash/Duplicate. Mais comment le test duplicate sait-il que le message est un doublon ? Il fonctionne en déterminant, pour chaque message, un identificateur unique. Lors du test, on regarde si l'identificateur est présent dans une base de données et, si ce n'est pas le cas, on l'y stocke. Contrairement à bien des extensions à Sieve, celle-ci va donc nécessiter un mécanisme de mémoire, permettant de garder trace des identificateurs de messages déjà vus.

Notez bien que la base est mise à jour lors du test duplicate, pas à la réception de chaque message (le test duplicate peut ne pas être exécuté dans tous les cas, par exemple s'il dépend d'un autre test). De même, l'ajout de l'identificateur unique dans la base ne doit être fait que si le script Sieve se termine normalement, pour éviter de considérer les messages suivants comme des doublons si le premier n'a pas pu être stocké correctement (disque plein ou autre erreur). Dans certains cas (livraison en parallèle), cela mènera à la distribution de deux copies mais le RFC considère qu'il faut éviter à tout prix la perte accidentelle d'un message donc qu'il vaut mieux quelques doublons en trop plutôt que le classement erroné d'un message comme étant un doublon.

Mais comment est déterminé l'identificateur unique indispensable au classement ? Il existe un en-tête prévu pour cela, Message-ID:, dont la section 3.6.4 du RFC 5322 dit bien qu'il doit être unique (il est en général formé d'une concaténation d'un grand nombre tiré au hasard et du nom de domaine du serveur, par exemple 5400B19D.70904@hackersrepublic.org). Mais, en pratique, on voit parfois des Message-ID: dupliqués et il faut donc prévoir des solutions de secours.

C'est ce que contient la section 3.1 de notre RFC, avec les arguments :header et :uniqueid. Par défaut, l'identificateur unique utilisé par le test duplicate est le Message-ID:. Si on utilise le paramètre :header, c'est le contenu de cet en-tête qui est utilisé comme identificateur unique. Par exemple :

if duplicate :header "X-Event-ID" {
     discard;
   }

va jeter tous les messages dont l'en-tête (non standard) X-Event-ID: a une valeur déjà vue (cas d'un système de supervision envoyant ses informations par courrier).

Si on utilise le paramètre :uniqueid, c'est la valeur indiquée par le paramètre qui est l'identificateur unique. Cela n'a d'intérêt, je crois, qu'en combinaison avec les variables Sieve du RFC 5229 (l'exemple suivant utilise aussi les statuts IMAP du RFC 5232) :

require ["duplicate", "variables", "imap4flags"]
if header :matches "subject" "ALERT: *" {
     if duplicate :uniqueid "${1}" {
       setflag "\\seen";
     }

Ici, la valeur du paramètre :uniqueid vaut la variable ${1}, c'est-à-dire le contenu du sujet du message, après l'étiquette « ALERT: ».

Bien sûr, on utilise :header ou :uniqueid mais jamais les deux en même temps.

Le test duplicate met tous les identificateurs uniques dans une seule base. Si on souhaite avoir plusieurs bases, on utilise le paramètre :handle (section 3.2) :

if duplicate :header "X-Event-ID" :handle "notifier" {
     discard;
   }
if duplicate :header "X-Ticket-ID" :handle "support" {
     # Utilisation d'une base différente: un X-Ticket-ID peut être
     # dans la base notifier mais pas dans la base support.
}

Pour mettre en œuvre le test duplicate, une façon simple de ne pas se compliquer la vie avec plusieurs fichiers est de garder dans un fichier unique un condensat de la concaténation de :handle avec l'identificateur unique.

On souhaite parfois que la mémorisation d'un identificateur unique ne soit que provisoire : si un message arrive un mois après, même s'il a un identificateur déjà vu, c'est probablement un nouveau message qui, par erreur ou par bogue, a un identificateur déjà existant. Il est peu probable que le même message, transmis par deux listes de diffusion différentes, traine autant... Le RFC conseille de ne mémoriser l'identificateur que pendant une semaine et fournit un paramètre :seconds (section 3.3) pour contrôler cette durée :

if not duplicate :seconds 1800 {
    notify :message "[SIEVE] New interesting message"
       "xmpp:user@im.example.com";

La durée est en secondes : ici, on indique une expiration au bout de seulement une demi-heure, peut-être parce qu'on ne veut absolument pas perdre de messages et qu'on craint que les identificateurs ne soient réutilisés trop fréquemment. (L'extension pour une notification par XMPP est dans le RFC 5437.)

La durée indiquée par le paramètre :seconds se compte à partir du premier message vu. Les messages ultérieurs portant le même identificateur ne remettent pas le compteur à zéro. Si on utilise le paramètre :last, par contre, la durée est comptée à partir du dernier message vu : tant que des messages arrivent avec cet identificateur, il n'y a pas d'expiration.

Comme toutes les extensions de Sieve, duplicate doit être annoncée au début du script Sieve (RFC 5228, section 6) :

require ["duplicate"]

Et la sécurité (section 6) ? Pour éviter de se faire DoSer, il faut imposer une limite à la taille de la base (en supprimant les identificateurs les plus anciens). Autrement, un flot important de messages avec chacun un identificateur unique pourrait faire exploser le disque dur.

Un autre problème de sécurité est le risque de faux positif : typiquement, on jette les messages dupliqués. Or des identificateurs censés être uniques, comme le Message-ID: ne le sont pas toujours. On risque donc, avec le test duplicate, de jeter à tort des messages. Il est donc prudent de ne pas détruire les messages dupliqués (action discard de Sieve) mais plutôt de les stocker dans une boîte spéciale (avec fileinto).

Il peut y avoir aussi de légères conséquences pour la vie privée : un utilisateur qui a détruit un message sur le serveur sera peut-être surpris que la base des identificateurs uniques continue à stocker le Message-ID: de ce message, qui peut être assez révélateur. Ceci dit, ce n'est pas pire que les actuels journaux (genre /var/log/mail.log, qui contient aussi ce genre d'informations).

Il y a apparemment deux mises en œuvre de Sieve qui gèrent cette extension.

Sinon, en dehors du monde Sieve, voici la solution traditionnelle avec procmail pour obtenir le même résultat :


:0:/var/tmp/.duplicate.lock
* ? formail -D 8192 $HOME/.duplicate.procmail-cache
$HOME/.mail-duplicates

Qui se lit : si le Message-ID: est déjà dans le fichier $HOME/.duplicate.procmail-cache (qui garde les 8 192 dernières entrées), on ne le distribue pas dans la boîte normale, mais dans $HOME/.mail-duplicates.


Téléchargez le RFC 7352


L'article seul

RFC 7366: Encrypt-then-MAC for TLS and DTLS

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : P. Gutmann (University of Auckland)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tls
Première rédaction de cet article le 16 septembre 2014


Depuis ses débuts, le protocole de cryptographie TLS (héritier de SSL) protège l'intégrité des paquets transmis en calculant un MAC, qui est inclus dans les données avant le chiffrement, une technique qu'on nomme MAC-then-encrypt. Plusieurs failles de sécurité ont été depuis identifiées dans cette technique et ce nouveau RFC normalise une extension à TLS qui permet de faire l'inverse, chiffrer avant de calculer le MAC, ce qui est aujourd'hui considéré comme plus sûr. On nomme cette méthode, logiquement, encrypt-then-MAC.

Lorsque le protocole SSL, ancêtre de TLS, avait été normalisé, au milieu des années 1990, le MAC-then-encrypt semblait tout à fait sûr. C'est ainsi que l'actuelle norme TLS, le RFC 5246 (section 6.2.3.1), continue à utiliser MAC-then-encrypt. Des études comme celle de M. Bellare et C. Namprempre, « Authenticated Encryption: Relations among notions and analysis of the generic composition paradigm » ou celle de H. Krawczyk, « The Order of Encryption and Authentication for Protecting Communications (or: How Secure Is SSL?) » ont depuis montré que MAC-then-encrypt est vulnérable à un certain nombre d'attaques cryptanalytiques, dans certaines conditions d'utilisation (je simplifie : la question de la vulnérabilité exacte de MAC-then-encrypt est plus compliquée que cela). Il est désormais recommandé d'utiliser plutôt encrypt-then-MAC (je simplifie encore : le RFC note par exemple que les algorithmes qui ne séparent pas chiffrement et calcul du MAC n'ont pas besoin de cette méthode).

Pour sélectionner la méthode recommandée, le groupe de travail TLS de l'IETF a choisi (section 2 de notre RFC) d'utiliser une extension à TLS (RFC 5246, section 7.4.1.4). Le client ajoute dans son message de bienvenue (client_hello) l'extension encrypt_then_mac (le extension_type de encrypt_then_mac vaut 22 et est désormais dans le registre IANA). Si le serveur TLS est d'accord, il mettra cette extension dans son server_hello.

Une autre solution (que d'utiliser le mécanisme d'extensions) aurait été de définir de nouveaux algorithmes de chiffrement et elle a fait l'objet de nombreux débats au sein du groupe de travail. Mais cela menait à une explosion du nombre d'algorithmes (ciphers), il aurait fallu presque doubler le nombre d'algorithmes concernés, pour avoir une version MAC-then-encrypt (l'actuelle) et une version encrypt-then-MAC. Encore une autre solution aurait été de créer une nouvelle version de TLS, la 1.3, où encrypt-then-MAC aurait été le comportement standard. Quand on sait que la version actuelle de TLS, la 1.2, est toujours minoritaire dans la nature, on voit qu'une telle solution aurait sérieusement retardé le déploiement. Au contraire, avec la solution choisie, il « suffira » de changer quelques dizaines de lignes de code dans les bibliothèques TLS actuelles. Un tel changement a des chances de se retrouver plus rapidement sur le terrain.

Comme le mécanisme d'extension est apparu avec TLS (il n'existait pas dans SSL, même dans sa dernière version, la 3), encrypt-then-MAC ne sera pas utilisable pour les logiciels qui utilisent encore SSL v3 (le cas principal semblant être la version 6 d'Internet Explorer). Comme SSL est abandonné depuis quinze ans, des logiciels aussi vieux ont probablement des tas d'autres failles de sécurité plus graves que l'utilisation de MAC-then-encrypt. (Au passage, c'est une des raisons pour lesquelles ce modeste blog n'accepte pas SSLv3.)

Arrêtons la discussion sur les alternatives qui auraient été possibles et revenons à la nouvelle extension (section 3 de notre RFC). Une fois qu'elle est acceptée par le client et le serveur, le traitement des paquets par TLS passera de l'ancien comportement encrypt (data || MAC || pad) (où || désigne la concaténation) au nouveau encrypt (data || pad) || MAC. Le MAC est calculé comme avant, sauf qu'il part du texte chiffré (TLSCiphertext) et plus du texte en clair (TLSCompressedtext, cf. RFC 5246, section 6.2.3.1). La structure de données TLS qui était (RFC 5246, section 6.2.3) :

struct {
          ContentType type;
          ProtocolVersion version;
          uint16 length;
          GenericBlockCipher fragment; /* Après moultes discussions,
	  le groupe de travail a décidé de n'appliquer
	  encrypt-then-MAC qu'aux "block ciphers". */
      } TLSCiphertext;

va devenir :

struct {
          ContentType type;
          ProtocolVersion version;
          uint16 length;
          GenericBlockCipher fragment;
          opaque MAC;  /* Ce champ supplémentaire est la seule
	  nouveauté */
      } TLSCiphertext;

Pour le déchiffrement, on fait les opérations en sens inverse, on vérifie le MAC d'abord, on jette immédiatement le paquet si le MAC est incorrect (en renvoyant un message bad_record_mac), sinon on déchiffre. Ainsi, un attaquant qui modifie les données en vol ne peut rien apprendre sur les clés cryptographiques utilisées : toute modification invalidera le MAC et tous les calculs d'un MAC incorrect prendront le même temps, ne permettant pas d'attaque par mesure du temps.

À noter que TLS permet d'utiliser un MAC raccourci (RFC 6066) et cela reste possible avec encrypt-then-MAC, dans les mêmes conditions.

Comme avec toute extension qui améliore la sécurité, il y a un risque qu'un attaquant actif perturbe la négociation (section 4 du RFC) pour amener les deux parties à ne pas choisir la nouvelle extension (attaque par repli), chacune croyant que l'autre ne la gère pas. La seule protection est de refuser le repli (ne jamais accepter de revenir à MAC-then-encrypt) mais, ce que le RFC ne dit pas, c'est que c'est irréaliste à court terme (la majorité des logiciels TLS dans la nature ne connait pas encore encrypt-then-MAC).

Il y a un serveur TLS public qui gère cette extension, si vous voulez tester votre code client : https://eid.vx4.net. Au 14 septembre 2014, la gestion de cette extension ne figure pas encore dans la version publiée d'OpenSSL, la 1.0.1i mais est dans la version de développement (voir le commit). Par contre, encore rien dans GnuTLS (la version publiée est la 3.3.7).

Merci à Florian Maury pour sa relecture.


Téléchargez le RFC 7366


L'article seul

Mon blog plus à poil sur l'Internet, grâce à TLS

Première rédaction de cet article le 10 septembre 2014


Voilà, plus d'un an après les révélations de Snowden, ce blog est enfin sécurisé par HTTPS. Avant de vous précipiter pour vous connecter à https://www.bortzmeyer.org/, il est prudent de lire quelques avertissements.

L'intérêt de TLS (et de son utilisation pour le Web, HTTPS) pour sécuriser un site ne se discute plus. C'est conseillé à la fois par l'ANSSI (dans ses « Recommandations pour la sécurisation des sites web » : « Le recourt [sic] à TLS, c’est à dire [re-sic] l’emploi du protocole HTTPS, est recommandé dès lors que les communications entre le client et le serveur doivent être protégées en confidentialité ou en intégrité »), mais également par tous les hackers, darknetteurs, cryptoterroristes, cipherpunks, etc. Depuis qu'Edward Snowden a courageusement publié plein de détails sur l'intensité de l'espionnage de masse sur le Web, c'est encore plus crucial. Sans TLS, n'importe qui peut savoir ce que vous regardez sur ce blog, quelles recherches vous faites, et un attaquant actif peut même modifier le contenu des pages avant qu'elles ne vous arrivent, me faisant dire encore plus n'importe quoi que d'habitude (voir un joli exemple avec Haka).

Alors, pourquoi cet avertissement au début, vous suggérant de ne pas vous précipiter ? C'est parce que j'ai fait le choix d'une autorité de certification que votre navigateur Web ne connait peut-être pas. Pour comprendre, il faut revenir au modèle de TLS (et donc de HTTPS). Client et serveur se mettent d'accord sur un mécanisme de chiffrement et sur ses paramètres, comme la clé. Une fois le chiffrement en route, un attaquant passif ne peut plus comprendre le contenu des communications (mais il peut toujours regarder qui communique, donc savoir que vous parlez à mon serveur) et un attaquant actif ne peut plus le modifier sans que ce soit détecté. Mais il reste un problème : comment le client peut-il savoir qu'il parle au vrai serveur et pas à un homme du milieu, un serveur qui se serait glissé au milieu de la conversation ? (Il existe plusieurs techniques pour être homme du milieu. Le domaine bortzmeyer.org étant signé avec DNSSEC, cela en élimine une, l'empoisonnement DNS, mais il en reste d'autres.) Ce genre d'attaques est fréquent : beaucoup d'entreprises font cela pour surveiller leurs employés, par exemple, et il existe une offre commerciale pour cela (par exemple, Blue Coat se vante d'être capable de « visibility of SSL [sic] -encrypted traffic (including the ability to stream decrypted content to an external server with an Encrypted Tap license) ». C'est réalisé en détournant le trafic dans le routeur de sortie et en l'envoyant à un équipement qui déchiffre et rechiffre après, pour l'envoyer au vrai serveur après examen. Cela se fait aussi au niveau des États (en Iran, par exemple).

Comment est-ce que TLS se protège contre ce genre d'attaques ? En authentifiant le serveur : il existe plusieurs techniques pour cela mais la plus courante, de loin, est d'utiliser un certificat à la norme X.509 (souvent appelé, par très gros abus de langage, « certificat SSL »). Ce certificat est composé d'une clé publique et de diverses métadonnées, notamment un nom (en X.509, on dit un sujet) comme www.bortzmeyer.org, et une signature de la clé publique par une autorité de certification (AC). Le client TLS va vérifier la signature des messages (prouvant que le serveur connait bien la clé privée) et la signature du certificat (prouvant que l'AC a validé que le certificat appartenait bien au titulaire légitime du nom). Quelles sont les autorités de certification acceptées ? Eh bien, c'est justement le piège : il n'existe pas de liste officielle, chacun a la sienne, stockée dans son magasin de certificats, et un même site Web peut donc parfaitement être accepté sans histoires par un navigateur et rejeté par un autre. En pratique, la plupart des utilisateurs font une confiance aveugle aux auteurs de leur navigateur Web (Mozilla, Google, Microsoft, etc) et utilisent sans se poser de questions les AC incluses par défauts dans les navigateurs. Cela marche à peu près, tant qu'une AC ne trahit pas (par exemple, au Ministère des finances français).

Mais le problème est qu'on ne peut jamais être sûr que son certificat sera accepté partout. Pour limiter les risques, la plupart des webmestres ne prennent pas de risques et font appel à une des grosses AC connues partout. Ce n'est pas satisfaisant, ni du point de vue de la sécurité, ni du point de vue du business (il devient très difficile d'introduire une nouvelle AC, la concurrence reste donc assez théorique). J'ai choisi une AC qui est très simple à utiliser, rend un bon service, et est contrôlée par ses utilisateurs, CAcert. Mais CAcert est dans peu de magasins et, si vous visitez mon blog en HTTPS, il y a des chances que vous ayiez un message d'erreur du genre « Unknown issuer ». Ce n'est pas satisfaisant, je le sais mais, comme je ne fais pas de e-commerce sur ce blog et que je ne manipule pas de données personnelles, je trouve que c'est acceptable et que c'est l'occasion de faire de la publicité pour les AC « alternatives ». Je vous encourage donc à ajouter le certificat de CAcert à votre magasin (j'ai mis un lien HTTP ordinaire car, si vous n'avez pas déjà le certificat CAcert, le HTTPS vous donnera une erreur : vous devez vérifier l'empreinte du certificat par un autre moyen). Au fait, pour les utilisateurs d'Android, on me souffle que sur un téléphone non rooté, il faut passer par les paramètres Sécurité > Installer depuis stockage. En tout cas, ça a bien marché sur mon Fairphone rooté.

Bien sûr, il y a d'autres AC, plus traditionnelles et qui auraient créé moins de surprises à mes visiteurs. Certaines sont très chères et, surtout, l'obtention d'un certificat nécessite un processus compliqué (et pas forcément plus sûr). En revanche, on m'a souvent cité StartSSL comme bonne AC assez reconnue. J'ai réussi à m'y créer un compte (non sans difficultés car ils testent l'adresse de courrier, non pas par la bonne méthode - envoyer un courrier - mais en faisant une connexion SMTP directe, ce qui pose un problème avec le greylisting et génère un stupide message d'errreur « We were not able to verify your email address! Please provide us with a real email address! »). Je testerai plus loin un autre jour. À noter que ce débat « AC commerciales privées ou bien CAcert » agite tous les acteurs du libre, par exemple LinuxFr, qui utilise également CAcert (pour ces raisons), ce qui suscite de vigoureuses discussions (merci à Patrick Guignot pour les références).

En raison de cettte méconnaissance de CAcert par beaucoup de magasins, je n'ai donc pas imposé HTTPS (par exemple, http://www.bortzmeyer.org/ ne redirige pas d'autorité vers https://www.bortzmeyer.org/). Pour la même raison, je n'ai pas mis d'en-tête HSTS (RFC 6797) car HSTS ne permet pas d'erreur : tout problème est fatal.

Bien sûr, une solution à ce problème des AC non connues est d'utiliser DANE (RFC 6698 et mon article à JRES). C'est sur ma liste des choses à faire (ceci dit, tant qu'aucun navigateur ne fait du DANE, cela limite l'intérêt).

Bon, assez parlé de ce problème des autorités de certification. Un autre sujet de dispute quand on configure TLS est le choix des algorithmes cryptographiques utilisés. TLS (RFC 5246) permet en effet un large choix, qui va être présenté par le client, et parmi lequel le serveur choisira. Il est donc important de ne pas proposer d'algorithmes qui soient trop faibles. Les sélections par défaut des logiciels utilisés pour faire du TLS sont en général bien trop larges. Cela convient au webmestre (car cela augmente les chances d'accepter tous les clients, même les plus anciens ou bogués) mais moins à l'auditeur de sécurité. Celui-ci teste le serveur avec SSLlabs ou bien un outil comme SSLyze ou encore https://testssl.sh/ et il vous engueule en disant « quoi, mais vous proposez encore SSLv3, c'est bien trop dangereux ». Pour éviter cette engueulade, on peut mettre dans sa configuration TLS une liste complète des bons algorithmes (on en trouve par exemple dans le document de l'ANSSI cité plus haut et Mozilla en publie une pour GnuTLS) mais cette méthode est longue et pénible et difficile à maintenir car la liste change évidemment dans le temps. Cela ne devrait pas être au webmestre de devenir expert en crypto ! Pour arriver à un réglage raisonnable, j'ai donc choisi une autre solution, en partant des jeux d'algorithmes disponibles dans le logiciel utilisé. Dans mon cas, c'est GnuTLS. Il fournit des identificateurs désignant des jeux d'algorithmes déterminés comme ayant certaines propriétés. Ainsi, NORMAL est le jeu par défaut. Il est très large. Pour le paranoïaque, il existe un jeu SECURE qui est plus raisonnable. On peut donc configurer son Apache ainsi :

GnuTLSPriorities SECURE

et c'est déjà mieux. Mais, tout l'intérêt de la méthode, est qu'on peut partir d'un jeu prédéfini puis ajouter ou enlever protocoles ou algorithmes. Par exemple, le jeu SECURE inclut actuellement le protocole SSLv3, vieux et bogué, et qui n'est apparement nécessaire que pour Internet Explorer version 6. Comme il est peu probable que beaucoup de visiteurs de mon blog utilisent cette horreur d'IE 6, je supprime SSL :

GnuTLSPriorities SECURE:-VERS-SSL3.0

(Cette directive veut dire : partir de la liste SECURE et retirer SSLv3.) Maintenant, si je teste avec testssl, j'ai :

% ./testssl.sh https://www.bortzmeyer.org/
...
 SSLv3      NOT offered (ok) 
 TLSv1      offered (ok) 
 TLSv1.1    offered (ok) 
 TLSv1.2    offered (ok) 
 SPDY/NPN   not offered

--> Testing standard cipher lists 

 Null Cipher              NOT offered (ok) 
 Anonymous NULL Cipher    NOT offered (ok) 
 Anonymous DH Cipher      NOT offered (ok) 
 40 Bit encryption        NOT offered (ok) 
 56 Bit encryption        Local problem: No  56 Bit encryption        configured in /usr/bin/openssl 
 Export Cipher (general)  NOT offered (ok) 
...
--> Checking RC4 Ciphers 

RC4 seems generally available. Now testing specific ciphers... 

 Hexcode    Cipher Suite Name (OpenSSL)   KeyExch. Encryption Bits      Cipher Suite Name (RFC)
--------------------------------------------------------------------------------------------------------------------
 [0x05]     RC4-SHA                       RSA        RC4      128       TLS_RSA_WITH_RC4_128_SHA                

RC4 is kind of broken, for e.g. IE6 consider 0x13 or 0x0a
...

Pas mal. SSLv3 a bien été retiré, le seul gros problème restant est que RC4 est encore proposé alors que cet algorithme a de sérieuses failles. Un dernier effort, pour le supprimer :

GnuTLSPriorities SECURE:-VERS-SSL3.0:-ARCFOUR-128:-ARCFOUR-40

Et, cette fois, RC4 n'est plus proposé :

...
--> Checking RC4 Ciphers 

No RC4 ciphers detected (OK) 

Voilà, j'ai maintenant une configuration TLS raisonnable. Principal manque : augmenter la priorité des algorithmes offrant la forward secrecy, ce sera pour une prochaine fois.

Ah, question outils de test, j'ai bien sûr utilisé SSLlabs mais il a deux inconvénients : stupidement, il teste également le nom sans www (et échoue donc souvent), et il ne connait pas CAcert donc la note globale reste à « T » (non documenté). Avec un certificat qu'il connaitrait, https://www.ssllabs.com/ssltest/analyze.html?d=www.bortzmeyer.org me donnerait une meilleure note (« If trust issues are ignored: A- »). J'ai aussi testé le logiciel sslscan (qui est en paquetage sur ma Debian) mais son ergonomie est vraiment horrible, il sort juste une longue liste de trucs testés, sans autre précision, hiérarchisation ou explication.

Quelques autres détails pratiques maintenant. Comme j'aime bien regarder les journaux, j'ai voulu indiquer si la connexion s'était faite en TLS ou pas (je rappelle que, pour l'instant, TLS n'est pas obligatoire sur ce blog). Il existe une variable HTTPS mais qui est spécifique à OpenSSL (voir un exemple de son utilisation). Pour GnuTLS, j'ai donc créé deux directives LogFormat :

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %v" complete
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %v TLS" completetls

et j'utilise l'une ou l'autre selon le VirtualHost :


<VirtualHost *:80>
    CustomLog ${APACHE_LOG_DIR}/access.log complete
...
<VirtualHost *:443>
    CustomLog ${APACHE_LOG_DIR}/access.log completetls
...

La visite de SSLlabs est ainsi correctement enregistrée :

64.41.200.103 - - [10/Sep/2014:08:43:13 +0000] "GET / HTTP/1.0" 200 285954 \
      "-" "SSL Labs (https://www.ssllabs.com/about/assessment.html)" \
      www.bortzmeyer.org TLS

Je n'ai pas encore changé la description OpenSearch de ce blog. Les recherches sont évidemment sensibles (elles indiquent à un attaquant vos sujets d'intérêt) mais je ne sais pas trop comment dire en OpenSearch « utilise HTTPS si tu peux et HTTP sinon ». Si on met deux éléments url, je ne sais pas lequel est choisi. Donc, il faut que je relise la spécification.

Un piège classique avec X.509 est l'oubli du fait que les certificats ont, parmi leurs métadonnées, une date d'expiration. Comme le mécanisme théorique de révocation des certificats ne marche pas en pratique, cette expiration est la seule protection qui empêche un voleur de clé privée de s'en servir éternellement. Il faut donc superviser l'expiration des certificats, ce que je fais depuis Icinga :

# HTTPS                                                                             
define service{
	use                             generic-service
	hostgroup_name                  Moi
	service_description             HTTPS
	check_command                   check_http!-S -C 30,7
	}

Cette directive indique de se connecter en HTTPS (option -S), d'avertir s'il ne reste que 30 jours de validité au certificat et de passer en mode panique s'il ne reste plus que 7 jours. Bien sûr, CAcert prévient automatiquement par courrier lorsqu'un certificat s'approche de l'expiration mais, renouveler le certificat chez l'AC ne suffit pas, encore faut-il l'installer sur le serveur, et c'est cela que teste Icinga.

Merci à Manuel Pégourié-Gonnard pour la correction d'une grosse erreur sur TLS.


L'article seul

RFC 7335: IPv4 Service Continuity Prefix

Date de publication du RFC : Août 2014
Auteur(s) du RFC : Cameron Byrne (T-Mobile US)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 7 septembre 2014


Le RFC 6333, qui normalisait le protocole DS-Lite, réservait un préfixe IPv4, 192.0.0.0/29, pour numéroter les entités impliquées dans le fonctionnement des tunnels DS-Lite. Ce nouveau RFC 7335 généralise ce préfixe en le rendant utilisable pour toutes les solutions techniques liées à la migration vers IPv6.

En effet, ces adresses ne doivent jamais apparaître sur l'Internet. Dans DS-Lite, elles sont limitées aux communications entre les extrémités du tunnel DS-Lite. Il n'y a donc pas de risque de collision si on se sert de ces adresses pour une autre utilisation interne. Si un autre système de transition vers IPv6 a besoin d'adresses IPv4 internes, il peut désormais les prendre dans ce préfixe. C'est par exemple le cas (section 3) de 464XLAT (RFC 6877) où la machine de l'utilisateur (CLAT : client side translator) peut faire de la traduction d'adresses mais a besoin d'une adresse IPv4 (qui ne sortira pas de la machine) à présenter aux applications.

Plutôt que de réserver un préfixe IPv4 différent pour DS-Lite, 464XLAT et les zillions d'autres mécanismes de transition, la section 4 de notre RFC pose donc comme principe que toutes les solutions utilisant des adresses IPv4 internes se serviront du même préfixe, 192.0.0.0/29 .Ce préfixe est donc ainsi documenté dans le registre des adresses spéciales.


Téléchargez le RFC 7335


L'article seul

RFC 7363: Self-tuning Distributed Hash Table (DHT) for REsource LOcation And Discovery (RELOAD)

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : J. Maenpaa, G. Camarillo (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF p2psip
Première rédaction de cet article le 7 septembre 2014


Le mécanisme RELOAD est un mécanisme pair-à-pair pour créer un réseau virtuel au-dessus des réseaux existants, notamment aux fins de téléphonie, messagerie instantanée et diffusion multimédia. Ce RFC étend le protocole Chord tel qu'utilisé par RELOAD de manière à permettre l'ajustement automatique de la DHT à des conditions changeantes (par exemple une augmentation ou diminution du taux de changement des pairs, le churn).

C'est le RFC 6940 qui normalise RELOAD. RELOAD offre le choix de plusieurs algorithmes de gestion du réseau virtuel mais, afin de permettre l'interopérabilité de toutes les machines RELOAD, il existe un algorithme obligatoire, que toute mise en œuvre de RELOAD doit connaître. Les autres algorithmes ne pourront être utilisées que si toutes les machines du réseau sont d'accord. Cet algorithme obligatoire se nomme CHORD-RELOAD et repose sur la DHT Chord. Comme toutes les DHT, Chord s'organise tout seul (pas besoin de chef pour créer le réseau virtuel), passe bien à l'échelle et est très résilient. Pour maintenir la DHT, les machines échangent des informations sur leur état et reconfigurent le réseau virtuel si nécessaire. Pour être le plus optimisé possible, afin de limiter le trafic réseau de gestion, ce travail dépend de paramètres comme le taux de changement des pairs (le churn), ou la taille du réseau. Souvent, ces paramètres sont fixés à l'avance lors de l'initialisation de la DHT. Ce n'est évidemment pas satisfaisant car ils peuvent varier dans le temps. Ils servent à calculer des caractéristiques de la DHT comme la taille de la liste des successeurs, ou comme la taille de la table de routage. Ces caractéristiques devraient pouvoir changer dans le temps, elles aussi. (Voir l'article de Mahajan, R., Castro, M., et A. Rowstron, « Controlling the Cost of Reliability in Peer-to-Peer Overlays ».)

Ces mécanismes de stabilisation qui tournent pour maintenir la DHT sont de deux types, périodique ou bien réactif. Dans l'approche périodique, les informations sont régulièrement échangés entre pairs, qu'il y ait eu des changements ou pas. La DHT est ajustée s'il y a du changement. Dans l'approche réactive, les pairs transmettent la nouvelle information lorsqu'il y a un changement et la DHT s'ajuste alors. On voit que l'approche réactive permet des ajustements plus rapides mais qu'elle écroule vite le réseau si le nombre de changements est trop important, notamment parce qu'elle peut entraîner une boucle de rétroaction. (Voir l'article de Rhea, S., Geels, D., Roscoe, T., et J. Kubiatowicz, « Handling Churn in a DHT ».) Le Chord de RELOAD permet d'utiliser les deux approches, alors que la plupart des mises en œuvre d'une DHT n'utilisent que la stabilisation périodique. La période de diffusion des informations fait partie de ces paramètres qu'on voudrait voir évoluer dynamiquement.

La section 4 de notre RFC résume ce qu'il faut savoir de Chord pour comprendre les changements introduits (je ne la répète pas ici). Les sections 5 et 6 décrivent ces changements, qu'est-ce qui peut être modifié dynamiquement et quand.

Ces changements se traduisent par des nouveaux enregistrements dans les registres IANA RELOAD : nouvel algorithme de gestion du réseau virtuel CHORD-SELF-TUNING, nouvelle extension self_tuning_data, etc.


Téléchargez le RFC 7363


L'article seul

RFC 7326: Energy Management Framework

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : J. Parello, B. Claise (Cisco Systems), B. Schoening (Independent Consultant), J. Quittek (NEC Europe)
Pour information
Réalisé dans le cadre du groupe de travail IETF eman
Première rédaction de cet article le 6 septembre 2014


Ce nouveau RFC présente un cadre général pour la gestion de l'énergie dans les protocoles IETF. La préoccupation est assez récente. Pendant longtemps, les ordinateurs et routeurs connectés à l'Internet consommaient autant de courant qu'ils voulaient et personne ne regardait la facture. La montée des préoccupations écologiques, le prix de plus en plus élevé de l'électricité dans les centres de données, et le désir d'avoir des machines sans fil à la patte, alimentées uniquement par une batterie, font que la gestion de l'énergie est maintenant devenue une préoccupation à part entière de l'IETF. Ce cadre modélise les consommateurs d'électricité comme des objets énergétiques (energy objects) qui vont pouvoir être supervisés et contrôlés à distance. On pourra, par exemple, par des protocoles normalisés, suivre la consommation électrique d'un serveur, ou bien la quantité d'énergie restante dans une batterie mais aussi faire passer une machine dans un état à consommation énergétique réduite.

La gestion de réseaux informatiques est divisée par la norme X.700 en cinq parties, Panne, Configuration, Comptabilité, Performance et Sécurité. La gestion de l'énergie n'y figure pas. La norme ISO 50001 ajoute cette préoccupation aux textes. L'IETF a créé un groupe de travail sur la gestion de l'énergie, EMAN, qui avait déjà produit un premier RFC, le cahier des charges, le RFC 6988.

Notre nouveau RFC introduit le concept d'interface énergie, en s'inspirant de celui bien connu d'interface réseau. C'est par une interface énergie que la machine fournit ou consomme de l'énergie. Une machine ne sait pas forcément mesurer ce qu'elle consomme et c'est donc parfois en interrogeant le dispositif de fourniture d'énergie qu'on aura cette information. (L'interface énergie de sortie de l'un étant l'interface énergie d'entrée de l'autre.)

Autres termes définis par ce RFC (section 2) :

  • Entrée (power inlet ou simplement inlet) : l'interface énergie par laquelle le courant arrive.
  • Sortie (outlet) : l'interface énergie par laquelle le courant sort.
  • Énergie : le nombre de kWh consommés ou produits, ou bien qu'on peut consommer ou produire.
  • Puissance : énergie divisée par le temps (en watts ou en joules/seconde). Si l'énergie est une distance, la puissance est la vitesse.
  • Demande : puissance moyennée sur un intervalle. Ces trois dernières définitions sont tirées de IEEE 100.
  • Attributs du courant : la tension, la phase, la fréquence, etc.
  • Qualité du courant : ses attributs par rapport à une référence. Comme le précédent, ce terme vient de IEC 60050.

La section 3 du RFC définit la notion de cible (target device). Ce sont tous les engins qui peuvent être supervisés ou contrôlés dans le cadre défini dans ce RFC : ordinateurs de bureau, serveurs, routeurs, imprimantes, commutateurs, points d'accès WiFi, batteries (lorsqu'elles sont autonomes et non pas enfermés dans un ordinateur), générateurs, fournisseurs PoE, compteurs, capteurs divers... Plusieurs de ces engins ne parleront pas IP et devront être interrogés / commandés via un relais.

Le cadre général défini par ce RFC concerne l'énergie, mais il ne couvre pas toutes les applications liées à l'énergie. La section 5 liste ce qui n'est pas l'objet du travail EMAN en cours : les engins non-électriques (si vous avez un routeur steampunk, propulsé par la vapeur, EMAN ne va pas vous aider) et la production électrique (seules sa distribution et sa consommation sont prises en compte).

La section 6 du RFC décrit le modèle utilisé pour la gestion de l'énergie. Il suit une conception objets classique : une classe Energy Object, avec trois sous-classes, Device, Component et Power Interface. La super-classe Energy Object modélise tout ce qui est relié au réseau et qui l'utilise pour superviser ou commander sa gestion de l'énergie. La classe Device modélise les équipements physiques qui consomment, distribuent ou stockent de l'énergie, comme les ordinateurs. Component sert à décrire les parties d'un objet Device, et le nouveau concept, Power Interface représente les interconnexions.

Tous les objets héritent de Energy Object qui a comme attributs :

  • Un identificateur unique, un UUID (RFC 4122),
  • Un nom (relativement) lisible ; cela pourra être un nom de domaine (pour les ordinateurs et routeurs, c'est déjà le cas), ou d'autres conventions de nommage,
  • Une importance, allant de 1 à 100, et qui sera utilisée pour prendre des décisions comme « les accumulateurs sont presque à plat, qui est-ce que je coupe en premier ? »,
  • Une série d'étiquettes (tags) permettant de trouver et de manipuler facilement tous les objets ayant une caractéristique commune,
  • Un rôle, qui indique le but principal de cet objet (routeur, lampe, réfrigérateur, etc),
  • Et quelques autres attributs que je n'ai pas cité ici.

Les objets de la classe Energy Object ont également des méthodes permettant la mesure de certaines grandeurs : puissance, attributs du courant électrique, énergie et demande.

D'autres méthode permettent le contrôle de l'objet et et changer son état. Plusieurs normes donnent des listes d'état possibles pour un objet. Par exemple, IEEE 1621 décrit trois états : allumé, éteint et dormant. D'autres normes, comme ACPI, vont avoir une liste différente. DMTF décrit pas moins de quinze états possibles, faisant par exemple la différence entre Sleep Light et Sleep Deep. Le groupe de travail EMAN, auteur de ce RFC, a produit sa propre liste, qui comprend douze états (section 6.5.4 du RFC), chacun numéroté (pour faciliter l'écriture des futures MIB, dont plusieurs sont proches de la publication en RFC). Par exemple, en cas de suspension, une machine est en sleep(3) et high(11) est au contraire l'état d'une machine complètement réveillée et qui ne cherche pas à faire des économies d'électricité. Un tableau en section 6.5.5 donne des équivalences entre ces normes. Par exemple, le sleep(3) d'EMAN correspond à l'état dormant de IEEE 1621, au "G1, S3" d'ACPI, et au Sleep Deep de DMTF. Ces états sont stockés dans un registre IANA (section 12 du RFC) et cette liste pourra être modifiée par la suite.

Une description formelle du modèle, en UML, figure en section 7.

Pour connaître l'état des mises en œuvre de ce cadre de gestion de l'énergie, voir le Wiki du groupe de travail (plusieurs MIB ont déjà été définies selon ce cadre).

Maintenant, la sécurité (section 11). Sérieux sujet dès qu'on touche à un service aussi essentiel que l'alimentation électrique. Va-t-on éteindre toute l'électricité d'une ville avec son téléphone, comme dans Watch Dogs ? Non, c'est plus compliqué que cela. Néanmoins, la gestion d'énergie doit être mise en œuvre prudemment. Si on gère les machines avec SNMP, le RFC 3410 sur la sécurité de SNMP est une lecture indispensable. Les accès en écriture, permettant de modifier l'état d'unee machine, peuvent en effet permettre, s'ils ne sont pas bien sécurisés, d'éteindre un appareil critique à distance. Mais même les accès en lecture seule peuvent être dangereux, car révélant des choses qu'on aurait préféré garder pour soi.


Téléchargez le RFC 7326


L'article seul

RFC 7285: ALTO Protocol

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : R. Alimi (Google), R. Penno (Cisco Systems), Y. Yang (Yale University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF alto
Première rédaction de cet article le 5 septembre 2014


Couronnant un travail commencé six ans auparavant, avec un net ralentissement de l'enthousiasme vers la fin, ce nouvel RFC normalise enfin le protocole ALTO (Application-Layer Traffic Optimization). Ce protocole sert notamment dans le cas de transferts de fichiers en pair à pair. Lorsqu'une machine qui veut récupérer un fichier (disons, au hasard, un épisode de Game of Thrones) a le choix entre plusieurs pairs possibles, qui ont chacun les données convoitées, lequel choisir ? ALTO permet d'interroger un oracle, le serveur ALTO, qui va nous donner des informations guidant le choix.

Il existe déjà des tas de façons, pour une application, de mesurer ou de calculer le « meilleur » pair. Par exemple, l'information de routage (annonces BGP, notamment) est publique et une application peut y accéder, par exemple via un looking glass. Mais cela ne donne pas une vue complète et, surtout, cela ne donne pas la vision de l'opérateur réseau, qui pourrait souhaiter, par exemple, qu'on utilise plutôt un pair qui fasse passer par un lien de peering (gratuit), plutôt que par un lien de transit (payant). ALTO est donc avant tout un moyen de faire connaître les préférences du FAI, de manière à ce que l'application puisse faire un choix plus informé. Par exemple, ALTO permet de distribuer des cartes simplifiées du réseau, suffisantes pour que l'application repère les liens intéressants.

Le but est donc bien que les applications changent leur comportement, en utilisant l'information ALTO, afin de mieux utiliser les ressources du réseau (le transfert en pair à pair peut représenter une bonne part du trafic et il est dans l'intérêt de tous de l'optimiser). La même méthode et le même protocole ALTO peut aussi être utilisé pour optimiser l'accès à un CDN et le serveur ALTO peut donc être fourni par d'autres acteurs que le FAI (le protocole lui-même est neutre, au sens où il n'impose pas de critères de choix ; le coût financier, utilisé dans l'exemple précédent peering/transit, n'est qu'une possibilité parmi d'autres).

Le problème que résout ALTO est formellement décrit dans le RFC 5693. Pour le résumer : en raison du modèle en couches, les applications n'ont pas assez d'information sur le réseau sous-jacent et ne peuvent donc pas prendre de décisions « intelligentes ». Il s'agit donc de leur donner cette information. Ainsi, le réseau sera mieux utilisé, on aura moins de gaspillage (avantage collectif) et les applications auront de meilleures performances (temps de téléchargement plus courts, par exemple, un avantage individuel, cette fois).

Techniquement, ALTO est un protocole HTTP/REST, où requêtes et réponses sont en JSON (RFC 7159). Que du classique, donc, et qui utilisera l'infrastructure HTTP existante.

Un petit rappel de terminologie (s'appuyant sur le RFC 5693) est fait en section 2. On y trouve les termes d'extrémités (endpoint), ALTO information base (l'ensemble des informations connues d'un serveur ALTO), etc.

Place maintenant à l'architecture d'ALTO, en section 3. Le cas typique est celui d'un opérateur, ayant un AS et un serveur ALTO pour distribuer l'information sur cet AS (bien sûr, des tas d'autres cas sont possibles). L'ALTO information base de cet AS est composée d'une série de coûts entre extrémités du réseau. Une extrémité est exprimée sous forme d'un préfixe IP (ce n'est donc pas forcément une seule adresse IP). Dans le cas le plus simple, la base peut tout simplement contenir quelque chose du genre « nos préfixes ont un coût fixe et faible, le reste de l'Internet un coût fixe et deux fois plus élevé » ou bien des informations bien plus complexes. La base contient donc les coûts, vus de cet opérateur. Elle va être distribuée par un serveur ALTO, interrogé par des clients ALTO. Plus tard, d'autres moyens de désigner une extrémité existeront, un registre IANA a été créé pour stocker les types d'adresses (section 14.4 de notre RFC).

Et d'où la base vient-elle ? Le protocole ALTO ne spécifie pas de méthode particulière. La base a pu être remplie à la main par les employés de l'opérateur réseau, en fonction de leur politique. Ou générée automatiquement à partir des données de l'opérateur sur la topologie du réseau. Ou elle a pu être assemblée dynamiquement par le biais d'un système de mesure, ou à partir des informations d'un protocole de routage. Ou encore elle peut être l'agrégation de plusieurs sources. La base n'est donc pas statique, mais elle est prévue pour ne pas changer en temps réel, elle ne tient donc typiquement pas compte de la congestion, phénomène très transitoire. On peut aussi imaginer des serveurs ALTO dialoguant entre eux, pour échanger leurs informations, mais il n'existe pas de protocole standard pour cela (notre RFC concerne uniquement le protocole d'interrogation d'un serveur par un client).

L'information ALTO sera peut-être dans le futur également distribuée par d'autres moyens (une DHT ?) mais rien n'est normalisé pour l'instant. Cela nécessiterait sans doute des mécanismes permettant d'indiquer la fraîcheur de l'information (date d'expiration, par exemple) et des mécanismes de sécurité (signatures) qui n'existent pas actuellement. Pour l'instant, ces services sont fournis par le protocole de transport, HTTP.

ALTO distribue l'information sous la forme de tables (map), indiquant les caractéristiques du réseau, et les coûts associés. (Comme indiqué plus haut, ces tables peuvent être de simples fichiers, distribués comme tels.) Une utilisation directe des tables (ce qu'on nomme le Map Service) ferait beaucoup de travail pour le client : télécharger les tables (qui peuvent être très grosses), puis faire des calculs compliqués pour trouver le meilleur pair. ALTO fournit donc en plus des services auxiliaires pour les clients paresseux. Le premier est le service de filtrage (Map Filtering Service) : le client donne des informations supplémentaires et le serveur lui envoie des tables simplifiées, ne correspondant qu'à ce que le client a demandé. Le second service auxiliaire est le service d'information sur une extrémité (Endpoint Property Service) : le client demande des détails sur une extrémité, par exemple son type de connectivité (on préférera un pair connecté en FTTH à un pair ADSL). Enfin, le troisième service auxiliaire, Endpoint Cost Service permet d'obtenir directement les coûts d'une extrémité donnée. Mais, avant de détailler le protocole pour ces trois services, voyons le service de base, le Map Service, d'abord pour les tables, puis pour les coûts.

D'abord, l'accès aux informations sur le réseau, la Network Map (section 5). Elle part d'une observation : il est coûteux de distribuer l'information sur chaque machine connectée et c'est surtout inutile, les machines se groupant selon la topologie du réseau. Une Network Map est donc surtout une série de regroupements. Chaque regroupement est identifié par un PID (Provider-defined IDentifier) qui, comme son nom l'indique, n'a de sens que pour un opérateur donné. Chaque groupe désigné par un PID va comprendre un ou plusieurs préfixes d'adresses IP (d'autres identificateurs des extrémités sont possibles). Un PID peut désigner toute une ville, ou bien tout ce qui est connecté à un POP donné. On verra plus loin que les coûts sont indiqués par PID et pas par préfixe ou par adresse, de manière à diminuer la quantité d'information à manier. Dans le futur, des groupes pourront être identifiés par autre chose qu'un PID, par exemple un pays ou un AS. Un registre IANA a été créé pour stocker ces futurs propriétés des extrémités. À la réunion IETF de Toronto, en 2014, ont été ainsi discutées des propriétés comme « type d'accès » (ADSL ou 3G...), « volume limité » (pour les offres illimitées des opérateurs 3G/4G, etc.

Un exemple d'une table triviale serait :

  • PID1 regroupe 192.0.2.0/24 et 198.51.100.0/25.
  • PID2 regroupe 198.51.100.128/25.
  • PID3 regroupe 0.0.0.0/0 (c'est-à-dire tout le reste de l'Internet).

Ensuite, la table des coûts (Cost Map, section 6). Elle est souvent plus dynamique que la table du réseau (ce qui justifie leur séparation) et indique les coûts vus par l'opérateur. Un « type de coût » comprend une métrique (une définition de comment on mesure un coût) et un mode (comment comparer les coûts, notamment est-ce qu'on peut appliquer des opérations arithmétiques comme l'addition). Les métriques possibles sont enregistrées à l'IANA et l'enregistrement de nouvelles métriques requiert un RFC qui ne soit pas un document individuel.

Au moins une métrique doit être utilisée par le serveur, routingcost, qui doit refléter le coût de routage. Elle n'est pas davantage définie donc cela peut être un nombre de kilomètres à vol d'oiseau, un nombre de sauts IP, un calcul à partir des coûts indiqués par l'IGP, etc. Quant aux modes, deux sont obligatoires, numerical et ordinal. Le premier utilise des nombres en virgule flottante et permet toutes les opérations arithmétiques classiques (comme l'addition de deux coûts), le second utilise des entiers et ne permet que les comparaisons. À la réunion IETF de Toronto, en juillet 2014, on a discuté de futures métriques comme par exemple le taux de perte de paquets, la gigue...

Une table des coûts triviale serait :

  • En partant de PID1, le coût d'aller à PID2 est de 2 et le coût vers tout l'Internet (PID3) est de 5,
  • En partant de PID2, le coût pour aller à PID1 est de 1 (les coûts ne sont pas forcément symétriques) et le coût vers le reste de l'Internet (PID3) de 4.

Pour la plupart des exemples ci-dessous, je vais utiliser un des rares serveurs ALTO publics existants, http://alto.alcatel-lucent.com:8000/. Le plus simple est d'utiliser curl, combiné avec jsonlint pour mieux afficher le JSON :

% curl -s http://alto.alcatel-lucent.com:8000/network/full | jsonlint -f
{ 
  "meta" : { "vtag" : { 
          "resource-id" : "default-network",
          "tag" : "192.11.155.88/f9d21e031e5cf58103d4687d65025cfb"
        } },
  "network-map" : { 
      "defaultpid" : { 
          "ipv4" : [ "0.0.0.0/0" ],
          "ipv6" : [ "::/0" ]
        },
      "mypid1" : { "ipv4" : [ 
              "15.0.0.0/8",
              "10.0.0.0/8"
            ] },
      "mypid2" : { "ipv4" : [ "192.168.0.0/16" ] },
      "mypid3" : { "ipv4" : [ "192.168.10.0/24" ] },
      "peeringpid1" : { "ipv4" : [ "128.0.0.0/16" ] },
      "peeringpid2" : { 
          "ipv4" : [ "130.0.0.0/16" ],
          "ipv6" : [ "2001:DB8::/32" ]
        },
      "transitpid1" : { "ipv4" : [ "132.0.0.0/16" ] },
      "transitpid2" : { "ipv4" : [ "135.0.0.0/16" ] }
    }
}

Et voilà, on a la table complète du réseau d'un FAI (fictif). La table contient des préfixes IP, avec le PID associé (par exemple, 128.0.0.0/16 a le PID peeringpid1).

La section 8 de notre RFC en vient au protocole : ALTO est un protocole REST pour accéder à des ressources (les tables) et à des annuaires de ressources, les IRD (Information Resource Directory). Les ressources sont récupérées en HTTP et ont donc un type de média indiqué (application/alto-networkmap+json pour la table du réseau, et application/alto-costmap+json pour la table des coûts). Ces types MIME ont été enregistrés dans le registre officiel. En général, les requêtes ALTO se font avec la méthode HTTP GET. Comme tous les protocoles s'appuyant sur HTTP, ALTO a à sa disposition toutes les fonctions rigolotes de HTTP, comme la mise en cache (RFC 7234). De même, la sécurité est fournie par les mécanismes HTTP habituels (HTTPS, authentification du RFC 7236, etc). Les codes de réponse habituels de HTTP sont utilisés, comme 200 si tout s'est bien passé, 405 si la méthode utilisée ne plait pas au serveur et 503 si le serveur a un problème temporaire.

Si la requête HTTP s'est bien passée, mais qu'un problème spécifique à ALTO est survenu, le serveur renvoie des données JSON de type application/alto-error+json. Elles comprennent au moins un champ code qui indiquera le type d'erreur par exemple E_SYNTAX pour des paramètres d'entrée incorrects, E_MISSING_FIELD pour l'absence d'un champ obligatoire, etc. Testons avec le serveur public, en envoyant du JSON incorrect (accolade ouvrante sans la fermante) :

% curl -s -d '{' -H "Content-Type: application/alto-networkmapfilter+json" \
   -X POST http://alto.alcatel-lucent.com:8000/network/filtered | jsonlint -f 
{ "meta" : { 
      "code" : "E_SYNTAX",
      "syntax-error" : "Premature EOF in JSON object; expecting key"
    } }

Les erreurs possibles sont dans un registre IANA (section 14.5 de notre RFC).

La section 9 présente l'IRD, l'Information Resource Base, le mécanisme de distribution de méta-information (où trouver la Network Map, où trouver la Cost Map, etc). Elle a aussi la forme de données JSON, servies sous le type application/alto-directory+json. Voici celle du serveur ALTO public indiqué plus haut :

% curl -s http://alto.alcatel-lucent.com:8000/directory | jsonlint -f 
{ 
  "meta" : { 
      "cost-types" : { 
          "hop-num" : { 
              "cost-metric" : "hopcount",
              "cost-mode" : "numerical",
              "description" : "Simple hopcount"
            },
...
      "default-alto-network-map" : "default-network",
      "priv:alu-server-info" : { 
          "Build-Date" : "2014-04-28 13:57:08 EDT",
          "Build-OS" : "Mac OS X 10.9.2",
          "Build-OS-Nodename" : "wdr-i7mbp2.mh.lucent.com",
          "Build-User" : "wdr",
          "Implementation-Title" : "ALTO Server Implementation",
          "Implementation-Vendor" : "Alcatel-Lucent (Bell Labs/Murray Hill)",
          "Implementation-Version" : "(2014-04-28 13:57:08 EDT)",
...
  "resources" : { 
      "costs-end" : { 
          "accepts" : "application/alto-endpointcostparams+json",
          "capabilities" : { 
              "cost-constraints" : true,
              "cost-type-names" : [ 
                  "rtg-num",
                  "rtg-ord",
                  "hop-ord",
                  "hop-num"
                ]
            },
          "media-type" : "application/alto-endpointcost+json",
          "uri" : "http://alto.alcatel-lucent.com:8000/costs/end"
        },
...
      "default-network" : { 
          "media-type" : "application/alto-networkmap+json",
          "uri" : "http://alto.alcatel-lucent.com:8000/network/full"
        },
...
    }
}

On y voit, par exemple, que si je veux obtenir la table complète du réseau, je dois demander http://alto.alcatel-lucent.com:8000/network/full, comme fait plus haut.

Bon, ce n'est pas tout, ça, il faut maintenant des données. La section 10 indique les types de base qui sont utilisés : les PID (identificateurs des réseaux) sont des chaînes de caractères ASCII, les ressources comme les Network Maps ont également un identificateur, le Resource ID (encore une chaîne ASCII), les extrémités sont en général identifiées par une adresse ou un préfixe IP, à la syntaxe traditionnelle, les mode et métriques des coûts sont des chaînes ASCII...

Avec ces types, on peut construire les données. Quand un client ALTO a l'adresse d'un pair potentiel, et cherche dans la table le PID correspondant, il peut y avoir plusieurs préfixes qui correspondent. Dans ce cas, c'est le plus spécifique qui gagne (règle dite du « longest match », cf. RFC 1812). Pour éviter toute ambiguité, la table doit être complète et sans recouvrement. Complète signifie que toutes les adresses doivent être présentes. Dans le cas d'un opérateur ayant une connectivité avec tout l'Internet, cela veut dire qu'il faut représenter toutes les adresses de l'Internet. Une entrée pour le réseau 0.0.0.0/0 en IPv4 et ::0/0 en IPv6 est le moyen le plus simple d'atteindre ce but : cette entrée, attrapera toutes les adresses non couvertes par un des préfixes plus spécifiques. Quant au non-recouvrement, il signifie que la table ne doit pas avoir deux préfixes identiques (il peut y avoir recouvrement mais uniquement entre préfixes de longueurs différentes, la règle du longest match permettra alors de sélectionner).

Par exemple, cette table est complète et sans recouvrement :

   "network-map" : {
     "PID0" : { "ipv6" : [ "::/0" ] },
     "PID1" : { "ipv4" : [ "0.0.0.0/0" ] },
     "PID2" : { "ipv4" : [ "192.0.2.0/24", "198.51.100.0/24" ] },
     "PID3" : { "ipv4" : [ "192.0.2.0/25", "192.0.2.128/25" ] }
   }

Avec cette table du réseau, 192.0.2.1 sera dans PID3 (le préfixe dans PID2 est moins spécifique), 198.51.100.200 sera dans PID2 et 203.0.113.156 sera dans PID1, en raison de la règle attrape-tout qui couvre tout l'Internet IPv4. Notez l'utilisation de la désagrégation : 192.0.2.0/24 a été représenté avec deux préfixes dans PID3 car, autrement, la table aurait eu un recouvrement.

Et la table des coûts ? Voici un exemple :

% curl -s http://alto.alcatel-lucent.com:8000/costs/full/routingcost/num | jsonlint -f
{ 
  "cost-map" : { 
      "defaultpid" : { 
          "defaultpid" : 15.0,
          "mypid1" : 15.0,
          "mypid2" : 15.0,
          "mypid3" : 15.0,
          "peeringpid1" : 15.0,
          "peeringpid2" : 15.0,
          "transitpid1" : 15.0,
          "transitpid2" : 15.0
        },
      "mypid1" : { 
          "defaultpid" : 4.0,
          "mypid1" : 15.0,
          "mypid2" : 15.0,
          "mypid3" : 15.0,
          "peeringpid1" : 15.0,
          "peeringpid2" : 15.0,
          "transitpid1" : 5.0,
          "transitpid2" : 10.0
        },
...
      "peeringpid1" : { 
          "defaultpid" : 15.0,
          "mypid1" : 15.0,
          "mypid2" : 15.0,
          "mypid3" : 15.0,
          "peeringpid1" : 15.0,
          "peeringpid2" : 15.0,
          "transitpid1" : 15.0,
          "transitpid2" : 15.0
        },
...
    },
  "meta" : { 
      "cost-type" : { 
          "cost-metric" : "routingcost",
          "cost-mode" : "numerical"
        },
      "dependent-vtags" : [ { 
            "resource-id" : "default-network",
            "tag" : "192.11.155.88/f9d21e031e5cf58103d4687d65025cfb"
          } ]
    }
}

On y voit, par exemple, que le coût entre

mypid1

et

peeringpid1

est de 15 (en utilisant la métrique routingcost).

On l'a vu, le client ALTO peut ne demander qu'une partie d'une table, pour réduire la consommation de ressources réseau et de temps de calcul. Ici, un client envoie un objet JSON (de type application/alto-networkmapfilter+json) qui indique quel(s) PID l'intéresse(nt) :

POST /networkmap/filtered HTTP/1.1
Host: custom.alto.example.com
Content-Length: 33
Content-Type: application/alto-networkmapfilter+json
Accept: application/alto-networkmap+json,application/alto-error+json

{
     "pids": [ "PID1", "PID2" ]
}

Notez qu'on utilise la méthode HTTP POST au lieu de GET. On peut aussi filtrer les tables de coûts, par exemple en n'acceptant qu'un seul mode.

Et voici une récupération des propriétés d'une extrémité, l'adresse de l'extrémité étant indiquée dans l'objet JSON application/alto-endpointpropparams+json :

POST /endpointprop/lookup HTTP/1.1
Host: alto.example.com
Content-Length: 181
Content-Type: application/alto-endpointpropparams+json
Accept: application/alto-endpointprop+json,application/alto-error+json

{
    "properties" : [ "my-default-networkmap.pid",
                     "priv:ietf-example-prop" ],
    "endpoints"  : [ "ipv4:192.0.2.34",
                     "ipv4:203.0.113.129" ]
}

HTTP/1.1 200 OK
Content-Length: 396
Content-Type: application/alto-endpointprop+json

...
    "endpoint-properties": {
      "ipv4:192.0.2.34"    : { "my-default-network-map.pid": "PID1",
                               "priv:ietf-example-prop": "1" },
      "ipv4:203.0.113.129" : { "my-default-network-map.pid": "PID3" }
    }
  }

Et ici une récupération des coûts associés à une extrémité. Par exemple, on est un client BitTorrent qui hésite entre trois pairs potentiels de l'essaim, 192.0.2.89, 198.51.100.34 et 132.0.113.45. On les envoie au serveur (notez les conséquences pour la vie privée : ce point est développé plus loin) :

# Les données JSON de la requête sont mises dans un fichier
% cat /tmp/select 
{
    "cost-type": {"cost-mode" : "ordinal",
                  "cost-metric" : "routingcost"},
    "endpoints" : {
      "srcs": [ "ipv4:10.0.2.2" ],
      "dsts": [
        "ipv4:192.0.2.89",
        "ipv4:198.51.100.34",
        "ipv4:132.0.113.45"
      ]
    }
  }

# On donne ce fichier à curl comme source des données à envoyer
# (option -d)
% curl -s -d '@/tmp/select' -H "Content-Type: application/alto-endpointcostparams+json" \
   -X POST http://alto.alcatel-lucent.com:8000/costs/end | jsonlint -f

Et le serveur ALTO répond en indiquant des coûts :

{ 
  "endpoint-cost-map" : { "ipv4:10.0.2.2" : { 
          "ipv4:132.0.113.45" : 2,
          "ipv4:192.0.2.89" : 1,
          "ipv4:198.51.100.34" : 1
        } },
  "meta" : { "cost-type" : { 
          "cost-metric" : "routingcost",
          "cost-mode" : "ordinal"
        } }
}

Ici, depuis la source 10.0.2.2, les meilleurs pairs sont 192.0.2.89 et 198.51.100.34, ex-aequo.

Pour rendre les choses plus concrètes, la section 12 du RFC présente un certain nombre de scénarios d'usage. Le premier, et le plus « évident » est celui d'un client ALTO placé dans un tracker pair à pair, un de ces logiciels qui aiguillent les pairs vers un pair qui a le contenu convoité. Chaque tracker gère des essaims (ensemble de pairs qui téléchargent le même fichier et a la tâche délicate de choisir quels pairs sont annoncés à chaque machine connectée au tracker (sauf si l'essaim est petit, auquel cas la tâche est triviale, on envoie tout). Les trackers utilisent déjà un ensemble de mécanismes pour cela et ils peuvent y ajouter ALTO. Comme un tracker pour un contenu populaire (mettons le dernier épisode d'une série télévisée très populaire) peut avoir des dizaines, voire des centaines de milliers de machines connectées, la meilleure solution ALTO est sans doute de télécharger la table du réseau et la table des coûts complètes et de les analyser. Pour chaque membre de l'essaim, le tracker cherchera le PID dans la table du réseau, puis le coût dans la table des coûts. Il enverra les pairs de préférence vers un pair du même PID ou, sinon, vers le pair au coût le plus bas.

Mais, pour diverses raisons, les pairs peuvent souhaiter faire la sélection eux-même. Les trackers sont des cibles évidentes pour la répression du pair à pair (ou, tout simplement, des SPOF...) et on peut vouloir se débrouiller sans eux, utilisant un mécanisme de rendez-vous complètement pair à pair comme une DHT. Dans ce cas, le client ALTO doit forcément être dans le logiciel de partage pair à pair (par exemple rTorrent). La technique la plus coûteuse, mais aussi celle qui préserve le mieux la vie privée de l'utilisateur, est que le logiciel télécharge la table du réseau et la table des coûts, puis fasse les calculs lui-même. Ainsi, il ne donnera presque aucune information au serveur ALTO.

Troisième scénario d'usage proposé par notre RFC, la sous-traitance des calculs et du filtrage au serveur ALTO, en utilisant le Map Filtering Service. Le logiciel pair à pair, cette fois, ne télécharge pas les tables entières, il indique au serveur ALTO une liste de pairs potentiels (trouvée, par exemple, sur la DHT), des critères de choix, et le serveur ALTO choisit le « meilleur » selon ces critères.

Notre RFC comprend ensuite une section 13 de discussion sur divers points du protocole. Premier point : comment un client trouve-t-il le serveur ALTO ? La norme ne définit pas une méthode unique et obligatoire. Le serveur peut être trouvé par une configuration manuelle, ou bien par la technique DNS du futur RFC sur la découverte de serveurs ALTO.

Et le cas d'une machine qui a plusieurs adresses IP ? C'est d'autant plus compliqué qu'il y a une interaction entre l'adresse utilisée, le FAI par lequel on passe et l'adresse du pair distant. ALTO ne fournit pas de solution immédiate, uniquement un mécanisme de description des extrémités suffisamment souple pour qu'on puisse y intégrer d'autres identificateurs que les bêtes adresses IP (voir plus haut les registres IANA de types d'adresses).

Reste à régler la question du passage par les routeurs NAT, le cauchemar habituel du pair à pair. En raison de ces obstacles, un protocole devrait éviter de transporter des adresses IP dans ses données, justement ce que fait ALTO. On a vu que, dans certains cas, le client ALTO indique son adresse au serveur, pour lui permettre un bon choix du pair. En raison du NAT, cette méthode ne marche pas forcément et le RFC autorise donc le serveur ALTO à utiliser l'adresse IP source des paquets ALTO entrants (adresse traduite par le routeur NAT) plutôt que celle indiquée dans les données JSON. Si le client ALTO n'est pas satisfait et veut indiquer lui-même son adresse IP dans les données, il doit utiliser un service comme STUN (RFC 5389) pour découvrir son adresse publique.

Et la sécurité dans tout ça ? La section 15 du RFC explore en détail les questions de sécurité d'ALTO. Le RFC cahier des charges, le RFC 6708, reconnaissait le problème et demandait des solutions minimum. D'abord, l'authentification. En effet, un attaquant peut vouloir distribuer de la fausse information ALTO, pour tromper un pair et l'envoyer vers des pairs plus lents. Cela serait une attaque par déni de service sur le réseau pair à pair. ALTO s'appuyant sur HTTP, les solutions de sécurité à utiliser sont celles de HTTP, essentiellement TLS. Pour l'authentification via un certificat, les clients et serveurs ALTO doivent bien suivre le RFC 6125. Attention, cette authentification se fait en fonction du nom présent dans l'URL utilisé par le client ALTO. Si celui-ci utilise un mécanisme de découverte de l'URL qui n'est pas fiable, la protection de TLS arrivera trop tard. Aujourd'hui, il n'y a pas de protection des données ALTO (pas de signature des maps, par exemple), seulement du canal par lequel elles transitent.

C'est bien joli d'authentifier le serveur ALTO mais encore faut-il qu'il soit digne de confiance. Si un méchant serveur ALTO distribue de mauvaise informations, comment peut-on se protéger ? Le RFC 5693 pointait déjà ce risque. Si les serveurs ALTO sont gérés par les FAI, comme beaucoup d'entre eux ont affirmé leur goût pour les violations de la neutralité du réseau, pourquoi les clients leur feraient-ils confiance ? Deux approches sont possibles pour le client ALTO. La première est d'analyser les conséquences de son choix. Si un logiciel pair à pair utilise parfois ALTO et parfois choisit les pairs au hasard, en mesurant les débits obtenus, il peut savoir si l'utilisation d'ALTO est dans son intérêt. (Attention, le but d'ALTO n'est pas uniquement la satisfaction du client : un FAI peut légitimement envoyer les clients vers des pairs qui ne sont pas plus rapides mais qui lui coûtent moins cher, par exemple parce qu'ils sont accessibles par un lien de peering gratuit.) Une seconde approche pour le client est de ne pas utiliser les serveurs ALTO du FAI (qui n'a pas forcément les mêmes intérêts que lui) mais des serveurs ALTO « neutres » fournis par une tierce partie (les exigences AR-20 et AR-21 dans le RFC 6708). Rappelez-vous aussi qu'ALTO n'est qu'une source d'information parmi d'autres, le client l'utilise pour sa prise de décision mais ne lui obéit pas aveuglément.

Et la confidentialité ? Bien sûr, une bonne partie des informations distribuées par ALTO sont publiques ou presque. La network map peut être vue comme confidentielle par le FAI mais, si elle est distribuée à tous ses clients, elle ne peut pas rester trop longtemps secrète. Néanmoins, on ne souhaite pas forcément que n'importe quel espion lise tout le trafic ALTO. Après tout, en combinant la table du réseau et celle des coûts, un attaquant peut récolter plein d'information sur le réseau d'un opérateur, à des fins d'espionnage industriel, ou bien pour préparer une attaque par déni de service. Et les informations données par les clients (liste de pairs potentiels...) sont également très sensibles. Que peut-on faire contre l'espionnage ? D'abord, au moment de créer les tables qui seront utilisées par ALTO, il faut se rappeler qu'ALTO n'impose pas un niveau de détail particulier. Le FAI qui veut avant tout optimiser le trafic fournira un grand niveau de détails, celui qui craint l'espionnage économique donnera des tables plus grossières. Ensuite, pour éviter l'écoute par un tiers, ALTO utilise, comme pour l'authentification, les solutions habituelles de HTTP, en l'occurrence TLS.

Notre RFC se penche aussi sur la vie privée des clients ALTO. D'abord, en raison de l'utilisation de HTTP, certains des risques de vie privée de HTTP affectent ALTO (par exemple l'utilisation de cookies, pas obligatoire dans ALTO mais qui peuvent être activés par défaut par certains clients HTTP). Ensuite, il y a clairement des risques de confidentialité différents pour le client et pour le serveur ALTO. Le client soucieux de vie privée a tout intérêt à télécharger l'intégralité des tables (réseau et coûts) et à faire la sélection soi-même, ne transmettant ainsi aucune information au serveur. En revanche, le serveur soucieux de sa vie privée à lui va vouloir le contraire : ne pas envoyer les tables complètes mais demander au client de lui fournir des critères de filtrage, avec lesquels le serveur fera son choix. On peut donc s'attendre, si ALTO se répand, à des conflits entre utilisateurs et FAI, par exemple si un FAI décide de ne pas fournir le service « tables complètes » et impose l'utilisation des services avec filtrage.

Dernier risque de sécurité pour ALTO, le risque de panne. Si on est habitué à utiliser ALTO, on sera bien embêté si un attaquant trouve le moyen de planter le serveur ALTO. Cela peut servir à aggraver une attaque par déni de service. Ce risque est d'autant plus important qu'un serveur ALTO peut se trouver, si on lui demande de faire des filtrages, dans l'obligation de faire des gros calculs, décidés par son client. Un client malveillant peut ainsi générer facilement une table avec N origines et M destinations, forçant le serveur à calculer N*M chemins. Un serveur ALTO doit donc être prudent sur ce point et prévoir de la limitation de trafic, et sans doute de l'authentification des clients (par exemple, pour un FAI, restreindre l'accès à ses abonnés).

Reste la gestion d'ALTO (section 16). Suivant le RFC 5706, cette section va se pencher sur les problèmes concrets des pauvres ingénieurs système qui vont devoir déployer ALTO et le maintenir en état de marche. ALTO reposant sur HTTP, cela impose l'installation et le maintien d'un serveur HTTP, soit un serveur standard avec un module ALTO, soit un serveur ALTO incluant le protocole HTTP. Mais il y a des problèmes plus sérieux, notamment les choix des services rendus. Par exemple, quel niveau de détail envoie-t-on, quelles requêtes permet-on ? Si on refuse d'envoyer la table du réseau complète, que doit-on faire lorsqu'une requête avec filtrage arrive, avec un filtre vide (un client ALTO astucieux peut utiliser cela pour contourner les restrictions d'accès à la table complète) ? Il faut aussi décider d'un mécanisme pour distriber l'URL où trouver le serveur ALTO. Dans la documentation accessible aux utilisateurs ? Uniquement avec la méthode du futur RFC sur l'utilisation du DNS pour trouver le serveur ? ? (Le RFC n'en parle pas mais le faible nombre de clients ALTO existants n'aide pas à trancher sur ces points.) Heureusement, il n'y a pas encore de question de migration à assurer, puisque ALTO est un nouveau service.

Pour l'opérateur réseau, ALTO va, s'il est utilisé, mener à des déplacements du trafic vers d'autres lignes. C'est bien son but mais cela peut entraîner des surprises : le responsable du serveur ALTO a désormais les moyens d'influencer sur la localisation du trafic, autant que celui qui configurait MPLS ou OSPF.

Pour la journalisation, le RFC recommande que les serveurs ALTO utilisent le standard syslog (RFC 5424), ce que ne font typiquement pas les serveurs HTTP habituels.

ALTO ne fournit pas encore d'interface standard de communication entre serveurs ALTO (par exemple pour agréger de l'information provenant de diverses sources), ni de MIB, ni d'interface standard de configuration, style NETCONF.

Pour les passionnés d'histoire, l'annexe B rappelle tous les ancêtres d'ALTO, notamment P4P (voir « P4P: Provider Portal for (P2P) Applications », présenté à SIGCOMM en 2008.

Et les mises en œuvre existantes ? On a vu le serveur d'Alcatel-Lucent. Il existe aussi celui fait à partir d'un dessin fameux de XKCD. Trois mises en œuvre différentes ont été montrées à la réunion IETF 80 et bien plus ont été testées rigoureusement lors d'un test d'interopérabilité à l'IETF 81. Les résultats sont documentés en ligne. Un autre test a eu lieu à l'IETF 85 et est également documenté.

Merci à Wendy Roome pour le serveur ALTO public utilisé ici, et pour ses patientes explications.


Téléchargez le RFC 7285


L'article seul

RFC 7344: Automating DNSSEC Delegation Trust Maintenance

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : W. Kumari (Google), O. Gudmundsson (Shinkuro), G. Barwood
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 4 septembre 2014
Dernière mise à jour le 12 septembre 2014


Un des obstacles à un plus large déploiement de DNSSEC est la nécessité de faire mettre, par le gestionnaire de la zone parente, un enregistrement faisant le lien avec la clé de signature de la zone fille. Cet enregistrement, nommé DS (pour Delegation Signer) est indispensable pour établir la chaîne de confiance qui va de la racine du DNS à la zone qu'on veut sécuriser. Mais, autant signer sa zone ne nécessite que des actions locales, qu'on peut faire tout seul, mettre cet enregistrement DS dans la zone parente nécessite une interaction avec une autre organisation et d'autres personnes, ce qui est souvent compliqué et réalisé d'une manière non standardisée. Ce nouveau RFC propose une méthode complètement automatique, où la zone fille publie les enregistrements de clé localement, et où la zone parente va les chercher (via le DNS) et les recopier.

Faire passer de l'information de la zone fille à la zone parente se fait actuellement avec des mécanismes ad hoc, par exemple via un formulaire Web ou une API chez le BE (cf. section 2.2 du RFC). Un exemple de l'opération est décrit dans mon article sur le remplacement d'une clé. Il faut transmettre les clés (ou leur condensat, le futur enregistrement DS, cf. RFC 4034) à la zone parente pour que la zone soit vérifiable avec DNSSEC. Et il faut le refaire lorsqu'on change la clé. Comme pour tout processus qui franchit les frontières entre deux organisations humaines, bien des choses peuvent aller de travers, surtout lorsqu'il est partiellement effectué manuellement. Et l'absence de techniques normalisées rend difficile le changement de prestataire.

Notre nouveau RFC propose donc une autre méthode : le gestionnaire de la zone signée publie ses clés uniquement dans sa zone, et la zone parente l'interroge à la recherche de nouvelles clés à publier. La sécurité du processus est assurée par les signatures DNSSEC. Ce mécanisme ne marchera donc que pour les mises à jour, pas pour la configuration initiale (puisque celle-ci ne peut pas être vérifiée par DNSSEC). Il supprimera néanmoins une opération pénible et qui est apparemment mal maitrisée par bien des gérants de zones DNS. Naturellement, les anciennes solutions resteront disponibles pour ceux qui préfèrent, et pour le premier envoi des clés, lorsque la zone devient signée. À noter que cette solution est spécifique aux informations DNSSEC (clés de signature). Il y a d'autres informations qu'on pourrait vouloir transmettre automatiquement au parent (serveurs de noms, colle) mais cela dépendra d'autres RFC.

Un petit mot de terminologie : il existe plusieurs mécanismes de gestion (au sens organisationnel) de la relation entre une zone DNS parente et une zone fille. Cette relation peut être directe (par exemple, dans une université, entre l'administrateur de la zone du département de mathématiques et l'administrateur de la zone de l'université), indirecte (passage par un intermédiaire, le BE, imposé, celui-ci communiquant ensuite avec le registre, souvent via EPP) ou complexe (gestion de la racine où le gérant d'un TLD passe par l'ICANN pour un changement qui est fait par le NTIA et Verisign). Pour traiter tous ces cas, le RFC utilise le terme d'« agent du parent » (parental agent) pour désigner l'entité avec lequel le gestionnaire de la zone fille communique, que cette entité soit le gestionnaire de la zone parente ou pas. L'agent du parent est donc l'administrateur de la zone de l'université dans le premier cas, le BE dans le second et l'ICANN dans le troisième. L'annexe A de notre RFC revient en détail sur ces différents modèles et leurs conséquences.

À noter d'ailleurs une complication supplémentaire : le titulaire de la zone fille ne gère pas forcément ses serveurs DNS lui-même (section 2.2.1 du RFC). Il a pu les déléguer à un tiers, l'hébergeur DNS, ou à son agent du parent (il est fréquent que les gens qui louent un nom de domaine à un BE lui confient également l'hébergement DNS). Dans ce dernier cas, tout est simple, l'utilisateur active la signature DNSSEC (ça peut même être fait par défaut, pour épargner ce choix technique à l'utilisateur) et l'hébergeur DNS s'occupe de tout.

Autre point à garder en tête : on peut transmettre à la zone parente un enregistrement DS (le condensat d'une clé) ou bien DNSKEY. Certains gérants de zones demandent un DS, d'autres un DNSKEY, d'autres acceptent les deux. La solution technique de ce RFC marche dans tous les cas.

Voyons maintenant la solution technique choisie. Elle est décrite en section 3. Deux nouveaux enregistrements DNS sont créés, CDS et CDNSKEY, correspondant respectivement aux DS et DNSKEY. Ils sont publiés dans la zone fille (le C initial veut dire Child) et indiquent à la zone parente les informations que la zone fille veut lui transmettre. Le CDS, type 59, a le même format que le DS (RFC 4034, section 5) et le CDNSKEY, type 60, le même format que le DNSKEY (RFC 4034, section 2). Comme on l'a vu plus haut, certains parents demandent un DS, d'autre un DNSKEY. La fille peut publier juste le CDS ou juste le CDNSKEY, selon la parente, ou bien les deux.

L'utilisation de CDS et de CDNSKEY (section 4) est facultative. S'ils sont absents, tout continue comme aujourd'hui. S'ils sont présents, la zone parente qui les détecte peut les publier sous forme d'enregistrement DS (en copiant le CDS ou bien en calculant un DS à partir du CDNSKEY). CDS et CDNSKEY doivent évidemment être signés avec DNSSEC (autrement, on pourrait empoisonner la zone parente) et doivent correspondre à ce qui est réellement dans la zone fille (par exemple, le CDS doit correspondre à une DNSKEY réellement existante). Le mécanisme marche aussi pour les suppressions, la zone parente pouvant retirer les DS qui n'ont plus de CDS mais avec des précautions (section 4.1) : pas question de « dé-sécuriser » la zone en retirant tous les DS valides, par exemple (la possibilité de retrait de DS de la zone parente est, à mon avis, pas très clairement expliquée dans le RFC). La parente peut ensuite prévenir la fille que les nouveaux DS ont été pris en compte et les anciens retirés (par exemple par courrier). Une fois que c'est fait, la zone fille peut supprimer CDS et CDNSKEY. (Attention à bien les supprimer tous : si on en supprime certains, la zone parente va retirer les DS correspondants. Aucun CDS/CDNSKEY ne veut pas dire « supprimer tous les DS » mais « ne faire aucun changement .)

(Au passage, pourquoi avoir un CDNSKEY, pourquoi la zone parente ne regarde pas directement le DNSKEY ? Il y a deux raisons : la première est qu'en général, on ne veut pas publier le DS tout de suite, on souhaite d'abord tester la configuration DNSSEC pendant plus ou moins longtemps. La zone va donc rester signée mais pas rattachée de manière sécurisée à sa parente. Ce rattachement doit être volontaire et explicite car, à partir du moment où il est fait, les erreurs DNSSEC ne pardonnent plus. La deuxième raison est qu'il peut y avoir plusieurs clés dans la zone fille, dont certaines sont, par exemple, en cours de retrait et ne doivent pas être utilisées pour faire un DS.)

Comment est-ce que l'agent du parent détecte qu'il y a de nouveaux CDS ou CDNSKEY dans la zone fille ? Une possibilité est l'interrogation régulière des zones. C'est simple à faire et automatique pour le gérant de la zone fille mais cela peut poser des problèmes de performance pour, par exemple, un gros BE qui gérerait des centaines de milliers de zones (section 6.1). Une autre est de fournir aux clients un bouton à pousser sur un formulaire Web quelconque, indiquant qu'il y a du nouveau dans la zone. Cette deuxième possibilité peut aussi permettre, si le formulaire Web est authentifié et qu'on présente à l'utilisateur le DS pour vérification, peut permettre de faire l'ajout initial du DS (cela suppose que l'utilisateur fasse une vérification sérieuse...). On peut aussi envisager une API simple pour cela, mais rien n'est encore normalisé. (C'était l'une des plus grosses controverses lors du développement de ce RFC : la méthode décrite ici doit-elle être la méthode officielle ou bien juste une méthode parmi d'autres ? Pour l'instant, c'est la seule normalisée mais elle n'est nullement obligatoire.)

La section 9 du RFC est l'analyse de sécurité de ce système. En automatisant le plus possible la transmission des clés de la fille à la parente, on espère augmenter la sécurité, en diminuant les risques d'erreurs humaines (copier/coller maladroit d'une DS dans un formulaire Web, par exemple). Cette décroissance des incidents aiderait au déploiement de DNSSEC. Mais il n'y a pas de miracle : le gérant de la zone fille pourra toujours faire des bêtises comme de supprimer de sa zone toutes les DNSKEY correspondant aux DS dans la zone parente.

Si le système d'avitaillement de la zone fille est piraté, le pirate pourra évidemment créer des CDS et CDNSKEY signés. Bien sûr, aujourd'hui, il peut déjà créer des enregistrements mais, dans ce cas, cela permettra peut-être d'étendre la durée de l'attaque (il faudra republier les bons CDS/CDNSKEY et attendre la mise à jour de la parente).

Dans le cas où la la gestion de la zone fille est sous-traitée à un hébergeur DNS, cette nouvelle technique a l'avantage que l'hébergeur DNS peut publier les CDS/CDNSKEY lui-même et donc mettre à jour la zone parente sans qu'on ait besoin de lui confier le mot de passe du compte chez le BE.

On peut mettre facilement des CDS et des CDNSKEY dans BIND depuis la version 9.10.1. Sinon, quels « agents de parent » mettent en œuvre ce RFC ? Pour l'instant, aucun et je ne connais pas de logiciel public qui fasse le travail de récupération et validation des CDS et CDNSKEY.


Téléchargez le RFC 7344


L'article seul

RFC 7353: Security Requirements for BGP Path Validation

Date de publication du RFC : Août 2014
Auteur(s) du RFC : S. Bellovin (Columbia University), R. Bush (Internet Initiative Japan), D. Ward (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF sidr
Première rédaction de cet article le 2 septembre 2014


La sécurité du routage BGP est un sujet de préoccupation sur l'Internet depuis de nombreuses années. Ce protocole ne dispose en effet par défaut d'aucune sécurité, n'importe quel opérateur (ou personne extérieure ayant piraté les routeurs d'un opérateur) pouvant annoncer une route vers n'importe quel préfixe, détournant, par exemple le trafic d'un service vital. Ce manque de sécurité ne vient pas d'une confiance naïve dans la nature humaine, mais plutôt de la nature même de l'Internet : il n'y a pas (heureusement !) de Haute Autorité Supérieure de l'Internet qui connaitrait tous les opérateurs et pourrait les autoriser et les surveiller. Un opérateur ne connait (et encore, pas toujours très bien) que ses voisins immédiats, et ne sait pas quelle confiance accorder aux autres. Dans ces conditions, la sécurisation de BGP est forcément un projet à long terme. La première grande étape avait été la normalisation et le déploiement de RPKI et ROA. L'étape suivante est la sécurisation du chemin entier (et pas uniquement de l'origine), dont ce nouveau RFC est le cahier des charges. En route donc vers BGPsec ! (Le nom PATHsec ne semble plus utilisé.)

Rappelons en effet qu'une annonce BGP (RFC 4271) comprend un chemin, la liste des AS par lesquels l'annonce est passée (et, dans la plupart des cas, celle, en sens inverse, dans lequel un paquet IP émis par le récepteur de l'annonce voyagera s'il veut atteindre l'AS d'origine). Voici un telle annonce, extraite du service de looking glass d'Hurricane Electric :

Prefix: 2001:678:c::/48,  Status: E,  Age: 31d9h14m31s
         NEXT_HOP: 2001:7fa:0:1::ca28:a116, Metric: 0,  Learned from Peer: 2001:7fa:0:1::ca28:a116 (1273)
          LOCAL_PREF: 100,  MED: 1,  ORIGIN: igp,  Weight: 0
         AS_PATH: 1273 2200 2484

Le chemin comprend trois AS, et l'origine, l'AS émetteur de l'annonce, est 2484 (oui, tout à droite : un chemin d'AS se lit de droite à gauche).

Avec les certificats de la RPKI (RFC 6480) et avec le système des ROA (Route Origin Authorization, RFC 6482), on peut désormais (RFC 6811) valider l'origine d'une annonce. Cela protège contre les détournements accidentels (comme celui de YouTube par Pakistan Telecom cité plus tôt), où l'AS d'origine est en général celle du détourneur. Mais lors d'une attaque délibérée, l'attaquant peut tricher sur le chemin et envoyer une annonce avec un chemin d'AS qui semble correct, avec la bonne origine. RPKI+ROA ne protègent pas contre cet attaquant compétent. (Les RFC 4593 et RFC 7132 décrivent en détail les vulnérabilités de BGP.)

Maintenant, place aux exigences que devra satisfaire la nouvelle solution de sécurisation. La section 3 du RFC liste les exigences générales et la section 4 celles spécifiques au traitement effectué lors de la réception d'une annonce BGP. Les exigences générales d'abord, numérotées de 3.1 à... 3.23 (oui, une longue liste). D'abord, 3.1 et 3.2, qui résument le projet complet : le routeur BGP qui reçoit une annonce doit pouvoir déterminer, avec un bon niveau de confiance, que l'origine dans l'annonce (exigence 3.1), et le chemin des AS (AS Path) dans l'annonce (exigence 3.2) sont authentiques. On veut être sûr que l'AS d'origine avait bien le droit d'annoncer ce préfixe, et que le chemin d'AS dans l'annonce reflète bien le chemin suivi par l'annonce (dans l'exemple ci-dessus, que 2484 avait bien le droit d'annoncer le préfixe 2001:678:c::/48, et qu'il a bien transmis l'annonce à 2200, qui l'a lui-même bien transmis à 1273). Attention, il ne s'agit pas uniquement de montrer que le chemin d'AS est possible (ces AS sont bien des pairs...) mais que c'est bien celui qui a effectivement été utilisé. Les autres attributs de l'annonce (comme le MED dans l'exemple ci-dessus) ne sont pas protégés (exigence 3.3) car ils ne sont utilisés que dans un AS ou ses voisins immédiats. (Voir aussi l'exigence 3.10.)

Comme toute technologie nouvelle, BGPsec aura des difficultés de déploiement, dans un Internet très ossifié, et la nouvelle solution devra donc être déployable de manière incrémentale (exigences 3.4 et 3.5) : les routeurs BGPsec devront pouvoir travailler avec les routeurs actuels (exigence 3.13 ; la section 5 reconnait que cette exigence ouvre la voie aux attaques par repli, où un attaquant réussit à faire croire qu'un pair ne gère pas BGPsec et qu'il faut donc se replier sur un protocole non sécurisé). Au début, les routeurs BGPsec auront sans doute des pairs BGPsec et d'autres en BGP non sécurisé et BGPsec doit donc pouvoir être configuré pair par pair (exigence 3.12). La cryptographie peut coûter cher en ressources matérielles et un routeur BGP typique a un CPU moins puissant que celui d'une console de jeu de salon. L'exigence 3.6 autorise donc BGPsec à réclamer du matériel nouveau (par exemple des processeurs cryptographiques spécialisés). La compatibilité avec le matériel existant n'est donc pas exigée.

L'attaquant n'est pas forcément situé dans un garage à des milliers de kilomètres, comme dans le cas des détournements BGP spectaculaires connus. Il peut aussi être mieux placé, par exemple sur le lien entre deux routeurs (l'attaquant peut être sur le même point d'échange que ses victimes...) L'exigence 3.8 impose donc une solution qui marche même en cas d'ennemi sur le lien Ethernet (le RFC note que AO - RFC 5925 - ou TLS - RFC 5246 suffisent).

La cryptographie ne sert pas à grand'chose si on n'a pas de moyen de vérifier l'authenticité des clés utilisés. C'est bien joli de tester l'intégrité d'une signature mais il faut aussi que la clé de signature soit reliée aux ressources qu'on veut protéger (ici, les préfixes d'adresses IP et les numéros d'AS). L'exigence 3.9 dit donc que la solution technique a le droit de s'appuyer sur une infrastructure existante établissant ce lien, comme la RPKI (et qu'évidemment cette infrastructure doit être fiable, cf. section 5). 3.17 ajoute que cette infrastructure doit permettre le choix, par l'opérateur, des entités à qui faire confiance (toutes les mises en œuvre actuelles de la RPKI permettent cela, en éditant la liste des trust anchors).

L'exigence 3.14 concerne une question de gouvernance. Il a souvent été reproché aux projets de sécurisation de BGP de faire un déplacement de pouvoir, des opérateurs BGP aux RIR qui gèrent les points de départ de la RPKI. Avec le BGP traditionnel, le RIR a un pur rôle de registre, il ne prend aucune décision opérationnelle concernant le routage. Avec un BGP sécurisé, ce n'est plus le cas. Pour rassurer les opérateurs, 3.14 rappelle que, signature correcte ou pas, la décision d'accepter, de refuser, de prioriser ou de déprioriser une annonce doit rester locale au routeur et à son opérateur. La question « que doit faire un routeur BGPsec en recevant une annonce invalide ? » n'a donc pas de sens et les futurs RFC n'y répondront pas. BGPsec permettra de dire « cette annonce est invalide », il ne dira pas quelle politique adopter vis-à-vis de ces annonces.

Pas question de sacrifier le secret des affaires à la sécurité BGP : l'exigence 3.18 dit que BGPsec ne doit pas révéler au monde plus que ce que BGP diffuse déjà. On ne pourra donc pas exiger, par exemple, qu'un opérateur publie la liste de ses pairs privés ou de ses clients.

Bien sûr, la solution adoptée devra permettre (exigence 3.19) la journalisation des événements pertinents, notamment en matière de sécurité (c'est plus une exigence pour les mises en œuvre que pour les futurs RFC).

Rien n'étant éternel dans l'Internet, le BGP sécurisé devra ré-authentifier les informations de temps en temps, par exemple suite aux mises à jour de la RPKI (exigence 3.20), même s'il n'y a pas eu de changement BGP (ce protocole n'annonce en effet que les changements : une route qui n'a pas changé ne sera pas ré-annoncée périodiquement, et les sessions BGP peuvent durer des mois, l'annonce montrée au début de cet article était vieille de 31 jours).

Enfin, pour en finir avec les exigences générales, la 3.21 impose que la solution BGPsec permette de changer les algorithmes cryptographiques utilisés, pour faire face aux progrès de la cryptanalyse.

La section 4 décrit les exigences spécifiques au traitement des messages BGP UPDATE qui annoncent une nouvelle route ou bien en retirent une ancienne. C'est le moment où il faut valider (exigences 4.1 et 4.2). L'exigence 4.3 dispense BGPsec d'une protection générale contre les attaques par rejeu, qui resteront donc possibles (retransmission d'une annonce BGP qui était valide mais ne l'est plus, vu les changements dans le graphe BGP). Plus difficile, 4.4 demande qu'on puisse se protéger, au moins partiellement, contre le retrait par l'attaquant d'un message BGP.

Pour terminer, la section 5, sur les problèmes généraux de sécurité, rappelle plusieurs choses importantes notamment le fait que la sécurité du routage ne garantit pas celle des paquets IP (« The data plane may not follow the control plane ») et le fait qu'une sécurité de bout en bout, assurée par les deux machines qui communiquent, reste nécessaire. (Il existe d'autres moyens de détourner le trafic que les attaques BGP.)

Le protocole n'est pas encore terminé (ce RFC n'est qu'un cahier des charges) et il n'existe donc pas encore de mise en œuvre de BGPsec dans du code livré aux opérateurs.

Merci à Bruno Decraene pour les corrections.


Téléchargez le RFC 7353


L'article seul

RFC 7351: A Media Type for XML Patch Operations

Date de publication du RFC : Août 2014
Auteur(s) du RFC : E. Wilde (UC Berkeley)
Pour information
Première rédaction de cet article le 31 août 2014


Vous voulez patcher des documents XML, c'est-à-dire envoyer juste la différence entre deux documents à un serveur pour qu'il applique les opérations de transformation qui vont rendre les deux documents identiques ? Le RFC 5261 fournissait un format de description de ces patches. Il manquait toutefois un type MIME décrivant ce format. C'est désormais fait, avec la normalisation dans ce RFC du type de média application/xml-patch+xml.

Outre le RFC 5261, qui décrivait un format pour les patches XML, l'un des protocoles qui utilisent le plus XML, HTTP, a une opération PATCH qui permet de mettre à jour une ressource Web distante (RFC 5789). HTTP, comme d'autres protocoles de l'Internet, étiquette les ressources envoyées ou récupérées avec un type de média (dit aussi « type MIME », cf. RFC 6838), et pour utiliser le format du RFC 5261 avec l'opération PATCH du RFC 5789, il fallait un tel type, désormais application/xml-patch+xml. (Pour l'opération PATCH, les serveurs HTTP choisissent librement les formats de patch qu'ils gèrent, il n'existe pas de format obligatoire. Ils peuvent accepter diff, ce nouvel application/xml-patch+xml et/ou bien d'autres.)

Notez que le RFC 5261 définissait un type MIME mais uniquement pour les messages d'erreur, application/patch-ops-error+xml.

Outre l'enregistrement du type MIME application/xml-patch+xml, ce nouveau RFC corrige également les erreurs du RFC 5261, liées à la complexité de la combinaison entre XPath et les namespaces XML.

Une des raisons pour lesquelles le RFC 5261 ne définissait pas de type MIME est qu'il ne définissait pas un format complet mais juste les éléments XML indiquant l'ajout, la suppression ou la modification d'éléments XML dans le document cible. Notre nouveau RFC, lui, définit un format complet, où les éléments de patch sont inclus dans un document dont l'élément racine est <patch> (et qui sera donc servi avec le type MIME application/xml-patch+xml). Voici un exemple d'un tel document :


<p:patch xmlns:p="urn:ietf:rfc:7351">
     <p:add sel="/section"><para>Nouveau paragraphe, lorem, ipsum, dolor, etc</p:add>
</p:patch>

Notez que l'élément à la racine, <patch> et les éléments du RFC 5261 comme <add> sont dans le même espace de noms urn:ietf:rfc:7351. À part ça, on peut reprendre les exemples du RFC 5261 tels quels (voir la section 2.2 de notre nouveau RFC).

L'annexe A contient un certain nombre de détails techniques. D'abord, une discussion détaillée du problème de la correspondance de deux espaces de noms en XML, problème difficile et où le RFC 5261 s'était planté. Ensuite, le problème des espaces de noms dans le document résultat, où les règles ne sont pas les mêmes en XML et en XPath.

Pour comprendre ce dernier problème, regardez ce document XML :


<x xmlns:a="tag:42">
       <y/>
</x>

L'espace de noms est le même pour les deux éléments XML (URI tag:42, qui utilise de manière inhabituelle le RFC 4151). Mais dans ce document XML quasi-identique :


<x xmlns:a="tag:42">
       <y xmlns:a="tag:42"/>
</x>

Chaque élément a sa propre déclaration d'espace et de noms et, si le patch veut modifier /x/namespace::a, ce sélecteur XPath ne désigne que le nœud <x>, et <y> ne doit pas, lui, être modifié. Or, XPath ne fournit pas assez d'informations pour cela, un logiciel de patch XML doit donc trouver une autre façon de déterminer où stopper sa récursion (par exemple en utilisant DOM). Une mise en œuvre naïve du RFC 5261 qui ne s'appuyerait que sur XPath échouerait dans des cas comme celui indiqué dans ce paragraphe.

Enfin, l'annexe B contient une grammaire ABNF des expressions autorisées par le sous-ensemble de XPath du RFC 5261, pour ceux qui n'aiment pas le W3C Schema qu'utilisait le premier RFC.

Des mises en œuvre complètes de XML Patch+ ce nouveau RFC ? Il y en a apparemment une dans le xDB d'EMC.


Téléchargez le RFC 7351


L'article seul

Fiche de lecture : Hackers, au cœur de la résistance numérique

Auteur(s) du livre: Amaelle Guiton
Éditeur: Au Diable vauvert
9-782846-265010
Publié en 2013
Première rédaction de cet article le 31 août 2014


S'il y a un mot galvaudé, dans l'univers du numérique, c'est bien celui de « hacker ». Ce terme est utilisé aussi bien pour parler du méchant en cagoule dans son sous-sol et qui fait sauter des centrales nucléaires à distance, que pour le type qui se croit un génie parce qu'il a installé Yo sur son iPhone. Ici, dans le livre d'Amaelle Guiton, « hacker » retrouve son sens original : celui (ou celle) qui ne se contente pas de faire fonctionner des systèmes techniques existants, mais qui veut les comprendre, les modifier, voire les subvertir.

Un petit livre trop court pour couvrir tous les hackers intéressants : on rencontre WikiLeaks, Telecomix, des gens anonymes et d'autres très exposés, toute la galaxie de ceux qui pensent qu'on peut changer le monde, et en tout cas la technique. À lire et surtout à faire lire par ceux qui ne connaissent du hacker que les reportages de TF1.

À noter que le livre n'est pas facile à trouver dans les librairies, le mieux, comme je l'ai fait, est de le faire commander par sa librairie de quartier (vous n'allez pas le commander sur Amazon, quand même, vu le sujet.) Mais vous avez aussi d'autres solutions expliquées sur le site officiel (oui, je sais, le lien vers  « version papier » ne marche plus. Comme je l'ai dit, demandez à votre libraire.)

Vous pouvez aussi regarder un interview de l'auteure ou un autre.


L'article seul

J'ai un téléphone Fairphone

Première rédaction de cet article le 29 août 2014


Voilà, il y a quelques jours, j'ai reçu mon téléphone « équitable » Fairphone. Qu'a-t-il d'équitable et que fournit-il ?


L'article complet

Les quatorze qui soi-disant contrôlent tout l'Internet

Première rédaction de cet article le 28 août 2014


Hier, le magazine GQ a cru bon de publier un article intitulé « Qui détient (vraiment) les clés d’Internet ? » et qui contient tellement d'erreurs, d'exagérations, et de sensationnalisme que c'était un exercice intéressant que de tenter de les lister toutes, de rectifier la vérité de manière (je l'espère) compréhensible par des gens qui ne sont pas des experts de l'infrastructure Internet, et d'en profiter pour regarder comment travaillent les médias auxquels tant de gens font confiance pour s'informer.

D'abord, il faut noter qu'il n'y a aucun travail d'enquête : cet article et d'autres qui l'ont précédé en français (comme celui de Paris-Match) sont juste de mauvaises traductions et adaptations d'un article du Guardian, qui était également pas mal sensationnaliste mais qui reposait au moins sur un reportage réel. Chaque adaptation successive de cet article a dégradé un peu plus le contenu. Mais, que voulez-vous, produire du contenu de qualité coûte cher, et adapter des articles déjà faits est plus rapide. Pour faire croire que le contenu est original, l'article doit prétendre qu'il va révéler « un des secrets les mieux gardés » alors que, on l'a vu, ce système a déjà été décrit dans plusieurs journaux.

Maintenant, reprenons l'article de GQ. Il use et abuse de termes sensationnels (« L’histoire est digne d’un film de science-fiction. ») pour faire du spectacle à partir d'une réalité nettement plus austère, qui n'intéresse normalement que les ingénieurs réseau. Résumé simplement, il s'agit de la technologie DNSSEC, un mécanisme technique et organisationnel qui permet de sécuriser une partie importante de l'infrastructure de l'Internet, le système des noms de domaine. Sans DNSSEC, il est relativement facile à un craqueur de subvertir ce système en redirigeant un nom (mettons bortzmeyer.org qui sert au courrier que je reçois) ailleurs que ce que voulait le titulaire du nom. Il est amusant que l'article de GQ ne mentionne pas une seule fois ce sigle DNSSEC. Une caractéristique importante de DNSSEC est qu'il est optionnel : aujourd'hui, seule une petite minorité des noms (bortzmeyer.org en fait partie) est protégée par DNSSEC et seule une minorité des utilisateurs se servent de serveurs de noms qui vérifient les signatures que DNSSEC appose. Il est donc ridicule de présenter ce système comme étant la sécurité de l'Internet (« le cœur de la sécurité du Net »). Il existe d'autres systèmes de sécurité qui jouent un rôle bien plus important pour l'instant.

Ce n'est pas trop glamour, bien sûr, et donc un certain nombre de personnes ont choisi de gonfler les choses, en menant une politique de communication personnelle active. On l'a vu, produire des articles de qualité coûte cher. Alors que les journalistes sont bombardés de contenus tout prêts, déversés sur eux par des entreprises ou des personnes qui veulent se mettre en avant. Il suffit de reprendre leurs discours, sans contre-enquête, sans nuance critique, et hop, on a une jolie histoire. Sur Internet comme ailleurs, ceux qui communiquent le plus ne sont pas forcément ceux qui font le travail (de « plombiers »)...

Bon, on va être indulgent, on va dire que ces abus sensationnalistes sont un choix de récit, que cela n'affecte pas le fond de l'article.

Mais c'est qu'il y a plein d'erreurs dans l'article. Citons-les dans l'ordre. D'abord, il y a une confusion entre l'Internet et le Web (les deux articles de Wikipédia sur ces deux technologies expliquent bien la différence). Des phrases comme « [une] simple clé qui permet de sécuriser tout le web » sont donc fausses : DNSSEC n'est pas spécifique au Web.

Ensuite, l'article parle d'une « une clé centrale de chiffrement » alors que DNSSEC ne fait pas de chiffrement ! Le chiffrement sert à garantir la confidentialité des communications mais ce n'est pas le rôle de DNSSEC. Son rôle est d'assurer l'authenticité des données, via un mécanisme de signature.

Passons sur « des data centers aussi sécurisés qu’une centrale nucléaire ». Si c'était vrai, les riverains de Fessenheim pourraient s'inquiéter...

Plus embêtant, « Ce que contrôle cette clé centrale est le "serveur-racine" ». Non, non, non. D'abord, il n'existe pas un seul serveur racine mais plusieurs (leur nombre dépend de comment on compte) et, surtout, la clé en question est tout simplement la clé de signature des données situées à la racine des noms de domaine. Elle ne contrôle pas une machine mais des données.

Revenons maintenant à la propriété la plus importante de DNSSEC, le fait qu'il soit optionnel. Ce point est complètement oublié dans l'article, parce que cela obligerait à dire que cette fameuse clé n'est pas si importante que cela, puisque seuls les gens qui utilisent DNSSEC pourraient éventuellement être affectés par sa perte ou son vol. Et l'infographie dans l'article cite un seul exemple de « nom de domaine sécurisé »... gqmagazine.fr qui justement ne l'est pas. Ce nom n'est pas signé avec DNSSEC et la perte ou le vol des clés de la racine n'auraient donc rigoureusement aucune influence sur la sécurité de GQ.

La partie de l'article concernant la gouvernance n'est pas épargnée, avec une affirmation comme quoi l'ICANN « définit également les protocoles qui permettent aux machines de communiquer entre elles » (c'est faux, c'est le rôle de l'IETF).


L'article seul

RFC 7342: Practices for Scaling ARP and Neighbor Discovery (ND) in Large Data Centers

Date de publication du RFC : Août 2014
Auteur(s) du RFC : L. Dunbar (Huawei), W. Kumari (Google), I. Gashinsky (Yahoo)
Pour information
Première rédaction de cet article le 28 août 2014


Les protocoles de résolution d'adresse IP en adresse MAC sur un réseau local, ARP pour IPv4 et ND pour IPv6, fonctionnent par diffusion. Le client crie à tout le monde « qui connaît 2001:db8:376:ab::23:c0f ? » et la machine qui se reconnaît répond. L'inconvénient de ce mécanisme est qu'il passe mal à l'échelle : lorsque des centaines de milliers de machines virtuelles sont sur le même réseau local dans un grand data center, et crient toutes en même temps, le réseau va souffrir. Ce nouveau RFC ne propose pas de solution mais décrit les pratiques qui sont actuellement utilisées pour limiter les dégâts.

Le problème des protocoles ARP (RFC 826) et ND (RFC 4861) dans les grands data centers a été décrit en détail dans le RFC 6820. Le problème a toujours existé mais est devenu bien plus sérieux depuis qu'on pratique massivement la virtualisation et que le nombre de machines qui font de l'ARP ou du ND a explosé. Le désir de souplesse dans la gestion de ces machines fait qu'il est difficile d'architecturer le réseau en fonction de ce problème. Par exemple, faire de chaque machine physique un réseau limiterait la diffusion des requêtes ARP ou ND mais obligerait à changer l'adresse IP des machines virtuelles lorsqu'elles passent d'une machine physique à une autre, annulant ainsi cette souplesse que fournit la virtualisation.

Les trois principales conséquences de cette augmentation du trafic ARP/ND :

  • Consommation de capacité réseau au détriment du trafic « utile » (bien sûr, avec les liens modernes à 10 Gb/s, c'est moins grave qu'avant),
  • Augmentation de la charge de travail des routeurs, sans doute la conséquence la plus gênante aujourd'hui (cf. une étude de Merit),
  • En IPv4, augmentation de la charge de toutes les machines car la diffusion est totale (IPv6 utilise le multicast). Là encore, l'augmentation des ressources de calcul des équipements réseau peut aider : un test en laboratoire indique que 2 000 messages ARP par seconde consomment 2 % du CPU d'un serveur.

Comme expliqué dans la section 3, le réseau interne d'un grand data center a en général une de ces trois architectures :

  • Connectivité au niveau 3 (L3), c'est-à-dire qu'on fait du routage IP dans le data center,
  • Tout en niveau 2, le data center est un grand réseau L2,
  • Virtualisation du réseau (overlay).

Pour chacune de ces architectures, une section de notre RFC décrit les pratiques actuelles pour limiter l'effet des protocoles de résolution.

Dans le premier cas (réseau L3), c'est la section 4. Les réseaux utilisant le routage mettent un routeur IP dans chaque baie, voire un pour chaque machine physique. Gros avantage : la diffusion des messages ARP ou ND, qui ne va pas au-delà du premier routeur, est très limitée. Le problème décrit dans le RFC 6820 disparaît donc complètement. Inconvénient : on n'a plus aucune souplesse. Changer une VM de baie, voire de serveur physique dans la même baie, oblige à la changer d'adresse IP, ce qui va casser les sessions en cours, nécessiter une reconfiguration, etc. Cette architecture ne convient donc que lorsque le data center est assez statique, ou bien lorsque les services qui y tournent peuvent supporter ces changements d'adresses IP.

Variante sur cette architecture (non mentionnée dans le RFC mais que j'emprunte à Vincent Bernat), annoncer dans le protocole de routage interne une route par machine (un préfixe /32 en IPv4 et /128 en IPv6). Cela résoud ce problème et permet de tout faire en L3, mais, si on a des centaines de milliers de machines, le protocole de routage va souffrir.

Deuxième architecture possible (section 5), le grand réseau L2 où toute diffusion va frapper toutes les machines. Cette fois, le problème des messages de diffusion ARP ou ND va se poser en grand. Les routeurs qui vont faire communiquer ce réseau L2 avec l'extérieur vont souffrir. Comment diminuer cette souffrance ? D'abord, pour le cas où une machine cherche à communiquer avec une machine externe et doit donc résoudre l'adresse IP du routeur en adresse MAC. Si cette adresse MAC n'est pas dans le cache de la machine, elle envoie une requête, et le routeur doit la traiter, ce qui se fait en général via le CPU généraliste du routeur, pas dans les circuits spécialisés.

Première solution : pré-charger l'adresse MAC du routeur dans toutes les machines (options -s et -f de la commande arp sur Unix). Deuxième solution, plus souple : que le routeur envoie des réponses ARP ou ND spontanément, sans attendre les requêtes (cf. RFC 5227). Ainsi, son adresse MAC sera quasiment toujours dans les caches. Cela marche très bien pour IPv4. Mais cela ne résoud pas complètement le problème pour IPv6 : ce protocole impose l'envoi de requêtes au routeur, pour valider que la liaison avec celui-ci fonctionne (RFC 4861, section 7.3, notamment « Receipt of other Neighbor Discovery messages, such as Router Advertisements and Neighbor Advertisement with the Solicited flag set to zero, MUST NOT be treated as a reachability confirmation. Receipt of unsolicited messages only confirms the one-way path from the sender to the recipient node. In contrast, Neighbor Unreachability Detection requires that a node keep track of the reachability of the forward path to a neighbor from its perspective, not the neighbor's perspective. »). Malgré cela, notre RFC recommande que cette pratique soit utilisée pour les réseaux IPv4 et que l'on travaille à améliorer la situation pour IPv6, dans la ligne du RFC 7048.

Second cas dans ce grand réseau L2, celui du traitement du trafic entrant dans le réseau. Le routeur de bordure reçoit un paquet pour une machine interne. L'adresse MAC de cette dernière n'est pas dans le cache ARP ou ND du routeur. Il faut donc émettre une requête ARP ou ND, ce qui fait du travail pour le CPU et utilise de nombreux tampons d'attente. Première solution : limiter la quantité de requêtes par seconde. Celles en excès seront simplement abandonnées. Deuxième solution : en IPv4, le routeur peut également surveiller le trafic ARP des machines afin d'apprendre leurs adresses MAC et de remplir son cache à l'avance. En IPv6, le trafic ND n'est pas toujours diffusé et donc pas toujours écoutable, et cette solution n'aide donc pas tellement. Notre RFC recommande cette deuxième solution, au moins pour IPv4, en notant que, s'il est possible que beaucoup de paquets soient destinés à des machines éteintes ou injoignables (et qui n'émettent donc jamais), il vaut mieux trouver d'autres solutions.

De même qu'on peut pré-configurer statiquement l'adresse MAC du routeur dans toutes les machines, on peut aussi pré-configurer statiquement les adresses MAC de toutes les machines dans les routeurs. C'est évidemment un cauchemar à gérer (ceci dit, ce n'est pas fait à la main pour chaque VM, mais typiquement à l'intérieur du programme de création des VM) et il n'existe pas de mécanisme standard pour cela. Le RFC suggère que l'IETF regarde si on peut augmenter des protocoles comme NETCONF pour faire ce genre d'opérations.

Autre approche, rendre la résolution ARP hiérarchique (voir RFC 1027 et les travaux ultérieurs comme cette proposition). Au lieu de n'avoir que deux niveaux, le client et le serveur, on pourrait avoir un relais ARP spécialisé qui puisse répondre aux requêtes, garder en cache les résultats, etc. Le RFC 4903 déconseillait cette approche, notamment parce qu'elle peut gêner le déplacement rapide d'une machine (il faut alors invalider les caches) et parce qu'elle est incompatible avec SEND (que personne n'utilise, il est vrai, cf. RFC 3971). Même possibilité, au moins en théorie, avec ND (RFC 4389 décrit un relais mais qui ne réduit pas le nombre de messages). Au bout du compte, notre RFC ne recommande pas cette technique, bien qu'elle ait parfois été déployée.

Troisième architecture possible pour un grand data center, les réseaux virtuels (overlays, section 6). Il existe des normes pour cela (TRILL ou IEEE 802.1ah) et plusieurs projets. L'idée est que seul un petit nombre d'adresses MAC sont visibles dans les paquets qui circulent entre les baies, les paquets étant décapsulés (révélant l'adresse MAC interne) à un endroit très proche des VM. Les équipements qui font l'encapsulation et la décapsulation doivent être suffisamment dimensionnés puisqu'ils se taperont presque tout le trafic ARP et ND. L'intensité du travail peut être diminuée par des correspondances statiques (comme cité pour les autres architectures) ou bien en répartissant astucieusement la charge entre les machines d'encapsulation/décapsulation.

La section 7 du RFC résume les recommandations : pas de solution miracle qui conviendrait à tous les cas, plusieurs solutions mais aucune parfaite. Certaines améliorations nécessiteraient un changement des protocoles et cela fait donc du travail possible pour l'IETF :

  • Atténuer certaines obligations de ND concernant la bidirectionnalité, obligations qui interdisent actuellement de profiter complètement des messages ND spontanés.
  • Spécifier rigoureusement les sémantiques des mises à jour (lorsqu'on reçoit une réponse ARP ou ND alors qu'on a déjà l'information en cache).
  • Développer des normes pour des relais/caches pouvant stocker les réponses ARP ou ND et les redistribuer largement. Le RFC 4389 peut donner des idées.

À l'heure actuelle, il n'y a plus de groupe de travail IETF sur ce sujet et ce développement de nouvelles solutions risque donc de ne pas être immédiat.


Téléchargez le RFC 7342


L'article seul

Sécurité, facilité d'usage, et les utilisateurs non-informaticiens

Première rédaction de cet article le 25 août 2014


La question de la facilité d'usage des solutions de sécurité informatique revient régulièrement sur le devant de la scène. S'il y a si peu d'utilisateurs de l'Internet qui se servent de la cryptographie ou d'autres mesures techniques qui les protégeraient, ne serait-ce pas parce que les techniques en question sont trop complexes, amenant les utilisateurs à préférer prendre des risques plutôt que de tenter de les maîtriser ?

La question revient souvent, mais elle est très ancienne. L'article qui avait été le premier à pointer ce problème de l'utilisabilité est « Why Johnny Can't Encrypt » d'Alma Whitten et J. D. Tygar1, en... 1999 Peu de progrès dans le débat depuis, à part une large reconnaissance, par la communauté des gens qui travaillent dans la sécurité informatique, que l'utilisabilité est en effet cruciale : la meilleure solution de sécurité du monde ne servira à rien si elle n'est pas utilisée car trop compliquée. Or, les révélations du héros Snowden ont rappelé l'importance de se protéger, face à l'espionnage massif qui a lieu sur l'Internet. La cryptographie fait donc l'objet d'un regain d'intérêt. Et il y a également une reprise du débat critique. Il y a deux semaines, Matthew Green avait écrit « What's the matter with PGP? » où il estimait que ce système devait disparaître (attention, son article contient bien des confusions, notamment entre le logiciel GPG et la norme OpenPGP, et des malhonnêtetés intellectuelles comme de comparer la longueur d'une clé avec celle d'un certificat).

Plus récemment, en France, Okhin à Pas Sage en Seine s'est attaqué aux informaticiens en critiquant vigoureusement « les barbus auto proclamés gourous des internets, cyber hactivistes, hackers, sysadmin et autre » et en annonçant que « Ce qui est cassé ce sont nos égos, nos réactions de sociopathes nihilistes face à un problème politique et social. » Ce thème a ensuite été repris par Barbayellow dans « Sécurité : pourquoi ça ne marche pas » et par Numendil en « Chers nous... » ainsi que par Tris Acatrinei dans « Une histoire de privilèges ».

Je vous laisse lire tous ces articles avant de voir le mien. Je ne vais pas essayer de réfuter la thèse « L'utilisabilité est essentielle pour la sécurité » car elle est exacte. La grande majorité des attaques réussies ne viennent pas d'une brillante réussite technique contre un algorithme de cryptographie, elles viennent d'erreurs commises par les utilisateurs. Mais je voudrais discuter un peu d'autres affirmations, comme de prétendre que la balle est à 100 % dans le camp des informaticiens/hackers/programmeurs, ou comme l'idée selon laquelle la difficulté d'utilisation des logiciels de sécurité est essentiellement due au manque d'intérêt des techniciens pour l'utilisabilité.

Alors, commençons par un problème pratique : clamer qu'il faut améliorer les logiciels, notamment du point de vue de l'ergonomie, c'est bien mais c'est vain. Encore faudrait-il dire en quoi on peut améliorer l'ergonomie existante. J'ai lu attentivement tous les articles cités plus haut et il y a beaucoup plus de temps passé à critiquer les développeurs (orgueilleux, autistes, méprisants, privilégiés) qu'à discuter de solutions concrètes. Il faut dire que le problème n'est pas trivial. Même un informaticien professionnel a du mal à configurer HTTPS sur son serveur Web, ou à utiliser PGP (et, plus encore, à l'utiliser tous les jours sans jamais faire d'erreur). C'est qu'il ne s'agit pas uniquement de compétences : même quand on a les compétences de base, on n'a pas forcément le temps. Donc, si on pouvait rendre ces logiciels plus faciles d'accès, ne nécessitant pas un week-end de travail pour générer une clé PGP conforme aux exigences de la cryptographie moderne, cela profiterait à tout le monde, de M. Michu au gourou informaticien. La question est « comment ? » Certaines améliorations sont assez évidentes (pour PGP, avoir des choix par défaut corrects, au lieu d'obliger les utilisateurs à demander à des experts en cryptographie comment les améliorer). D'autres le sont nettement moins. J'aimerai voir moins d'articles « les informaticiens sont méchants, ils font des logiciels peu utilisables » et plus d'articles « proposition concrète d'amélioration / de nouveau logiciel ». (Je ne suis pas exigeant, je ne demande pas de logiciel fini.) Donc, oui, les logiciels d'aujourd'hui peuvent et doivent être considérablement améliorés. Mais tout le monde en est convaincu ! Ce qu'il faudrait faire désormais, c'est d'avancer un peu et de proposer des améliorations précises, et je n'en ai pas encore vu. Et c'est un problème difficile, loin des Yakafokon. L'article « Why Johnny Can't Encrypt », cité plus haut, explique bien pourquoi le problème des interfaces utilisateur en sécurité est différent des problèmes d'ergonomie habituels. (Il explique également bien pourquoi le manque d'interface graphique est un faux problème : « All this failure is despite the fact that PGP 5.0 is attractive, with basic operations neatly represented by buttons with labels and icons, and pull-down menus for the rest ».)

Comme exemple de difficulté à concevoir une interface utilisateur simple et efficace, prenons le gros problème de la cryptographie, la gestion des clés. Une des difficultés de PGP est qu'il faut récupérer la clé publique de son correspondant (typiquement via un serveur de clés), la valider (c'est l'opération essentielle, sans laquelle il n'y a plus guère de sécurité) et la stocker. Ces opérations compliquées sont difficiles à expliquer et une erreur est vite arrivée (par exemple d'accepter une clé sans l'avoir vraiment vérifiée). OTR fonctionne sur un principe proche : comme OTR, contrairement à PGP, est limité aux communications synchrones, on n'a pas à récupérer la clé de son correspondant, mais il faut toujours la vérifier. Peut-on faire mieux ? Tout dépend de ce qu'on est prêt à abandonner en échange. Dans une discussion sur Twitter, Okhin vantait le modèle de clés de X.509 (utilisé dans TLS et donc dans HTTPS) comme étant plus simple : l'utilisateur n'a aucune vérification à faire. Mais Okhin oublie de dire que le prix à payer est la sous-traitance complète de sa sécurité aux autorités de certification qui valent... ce qu'elles valent. Si on veut protéger sa vie privée, devoir faire confiance à ces entreprises n'est pas l'idée la plus géniale qui soit. Autre solution au problème de la gestion de clés, SSH et son principe TOFU (Trust On First Use). Il est amusant que SSH soit si rarement cité par ceux qui réclament des logiciels de sécurité plus faciles à utiliser. Car SSH est justement une réussite de l'interface utilisateur, puisqu'il est plus simple que ne l'était son concurrent non sécurisé, telnet. Si on veut un exemple de conception réussie, il ne faut pas regarder TLS ou OTR mais certainement plutôt le grand succès qu'est SSH (cf. annexe A.3 du RFC 5218). Mais, là encore, rien n'est parfait. SSH est facile grâce au TOFU : la première fois qu'on se connecte à un nouveau serveur, la clé est vérifiée (en théorie...) et elle est automatiquement mémorisée pour la suite. Ce principe est assez bon (c'est un compromis raisonnable entre utilisabilité et sécurité) mais il a aussi des inconvénients : vulnérabilité lors du premier usage, difficulté à changer les clés par la suite...

Outre la notion de compromis, essentielle en sécurité (mais trop rarement citée dans les articles réclamant des logiciels plus simples), il y a une autre notion essentielle, et souvent oubliée : l'éducation. En général, elle est balayée avec des phrases du genre « il n'y a pas besoin d'être ingénieur pour conduire une voiture ». Mais c'est une illusion : bien sûr qu'il faut apprendre beaucoup de choses pour conduire une voiture. Pas besoin d'être ingénieur, certes, mais n'importe quel conducteur a dû apprendre beaucoup, simplement, comme c'est aujourd'hui un savoir banalisé, il ne s'en rend pas compte (voir à ce sujet l'hilarant texte sur le support de General Motors). Dans une société où de plus en plus de choses dépendent de l'informatique, dire que les outils modernes doivent être accessibles sans aucune éducation, c'est illusoire. Il faut au contraire développer une littératie numérique, qui implique un minimum de choses sur la sécurité. L'apprentissage de cette littératie va nécessiter des efforts des deux côtés. Réclamer des systèmes informatiques qui soient utilisables sans aucune formation, ni effort de la part des utilisateurs, va entretenir des illusions.

Quand Barbayellow écrit « [Le métier des journalistes], ce n'est pas de savoir comment fonctionne un ordinateur, un serveur ou même Internet », il se trompe. Aujourd'hui, où une si grande partie des activités humaines (le journalisme, mais pas uniquement), se passe sur l'Internet, il faut y connaître quelque chose. Dire que les journalistes ne devraient pas connaître l'Internet, c'est comme s'il disait « connaître le droit n'est pas notre métier », alors que tant de métiers aujourd'hui nécessitent forcément une culture juridique minimale. Et dire qu'il n'est pas nécessaire d'apprendre l'Internet en 2014, c'est comme dire en 1450 qu'il n'est pas nécessaire d'apprendre à lire si on n'est pas un professionnel de l'édition...

A translation in english of this article was kindly done by Pete Dushenski (footnotes are not mine).


L'article seul

RFC 7336: Framework for Content Distribution Network Interconnection (CDNI)

Date de publication du RFC : Août 2014
Auteur(s) du RFC : L. Peterson (Akamai Technologies), B. Davie (VMware), R. van Brandenburg (TNO)
Pour information
Réalisé dans le cadre du groupe de travail IETF cdni
Première rédaction de cet article le 22 août 2014


Ce RFC est le nouveau cadre technique pour les solutions standard d'interconnexion de CDN. Après le document de description du problème (RFC 6707), une liste de scénarios d'usage (RFC 6770) et un cahier des charges formel (RFC 7337), voici une nouvelle étape du travail du groupe CDNI de l'IETF. Il remplace un ancien travail équivalent, qui n'avait pas débouché, dans le RFC 3466.

Personnellement, je trouve qu'il ne va pas très loin par rapport aux RFC 6707 et RFC 7337. Mais, bon, c'est la description officielle de l'architecture des futurs protocoles d'interconnexion de CDN donc, allons-y.

N'attendez pas de ce RFC des protocoles précis : les spécifications viendront plus tard, ce qui est décrit ici est une architecture de haut niveau, très proche de ce qui avait été écrit dans le RFC 6707. (Par contre, terminologie et architecture du vieil RFC 3466 sont abandonnés.) Le principal ajout est que l'interface de routage des requêtes (Request routing interface) est désormais découpée en deux, une interface de redirection (Request routing indirection Interface) et une interface d'échange d'informations (Footprint & Capabilities Interface). Autrement, je vous renvoie à mon article sur le RFC 6707. Outre la terminologie des RFC 6707 et RFC 7337, quelques concepts nouveaux apparaissent :

  • [Rappel] « CDN amont » : celui sollicité par le client qui veut du contenu, mais qui n'a pas le contenu (ou bien, pour une raison ou pour une autre, qui ne peut pas / ne veut pas servir la requête) et doit donc utiliser les mécanismes CDNI pour déléguer ; le RFC écrit aussi uCDN pour upstream CDN,
  • [Rappel] « CDN aval » : celui qui a le contenu et va donc servir le client ; le RFC écrit aussi dCDN pour downstream CDN,,
  • « Domaine CDN » : le nom de domaine dans l'URL qui identifie le CDN. Par exemple, pour le site Web de l'Élysée, qui utilise le CDN de Level 3, c'est actuellement cdn.cdn-tech.com.c.footprint.net.
  • « Redirection Itérative » : lorsque le CDN amont renvoie simplement au CDN aval, sans essayer de traiter la requête lui-même,
  • « Redirection Récursive » : lorsque le CDN amont fait le travail de redirection lui-même, sans que le client qui accédait au contenu en soit même conscient.

La section 3 du RFC est un survol général du fonctionnement de CDN interconnectés. L'opérateur A gère le CDN amont, celui qui a un lien avec le fournisseur de contenu, qui a choisi A pour servir ses ressources. L'opérateur A a un accord avec l'opérateur B, qui gère un possible CDN aval, qui pourra servir des clients intéressés, par exemple sur une base de proximité géographique (mettons que A est en Europe et B aux États-Unis). Avant que le client n'arrive, A et B auront donc échangé des messages (via les interfaces MI et FCI, cf. RFC 7337) pour que B sache quoi servir (interface MI, envoi de métadonnées) et pour que A sache les capacités de B (interface FCI). Lorsque le client final envoie sa requête, elle est d'abord dirigée (par les techniques habituelles des CDN existants) vers A. Via l'interface RI, le client est redirigé vers B (voir plus loin les techniques de redirection). Le client envoie alors ses requêtes à B. Celui-ci doit contacter A pour obtenir le contenu lui-même (cette opération n'utilise pas les protocoles CDNI) et il sert ce contenu au client. Ensuite, il contactera A pour remplir les statistiques de ce dernier (interface LI).

La section 3 détaille ensuite les mécanismes de redirection récursifs et itératifs. La section 2 du RFC avait déjà résumé ces techniques de base utilisées par les CDN pour la redirection des requêtes. Dans le cas le plus simple, un client (par exemple un navigateur Web) va interroger un CDN qui, soit lui répondra, soit le renverra vers le CDN aval. Pour cette redirection, on peut utiliser le DNS ou bien des mécanismes de redirection du protocole applicatif (par exemple, en RTSP, un code de retour 302). D'abord, le DNS. Le principe est d'envoyer des réponses différentes selon le client. Ce dernier est situé en Europe et interroge un CDN amont qui ne sert de contenu qu'en Amérique ? Pas de problème, aux requêtes sur le domaine CDN, on renvoie l'adresse IP d'un CDN aval qui est présent en Europe. Il y a quelques précautions à prendre (se souvenir que les réponses DNS seront gardées en cache et qu'il faut donc choisir intelligemment le TTL, sans compter le fait que certains résolveurs trichent en gardant en cache plus longtemps, prêter attention à DNSSEC si on génère les redirections au vol, cf. section 3.4.1) mais cette méthode est simple et est déjà utilisée par les CDN actuels, non connectés entre eux. L'avantage de la technique DNS est qu'elle est complètement invisible à l'application, qui ne se rend même pas compte qu'elle a été servie par un autre CDN que celui demandé. L'un de ces inconvénients est que le serveur DNS qui fait autorité ne connait pas le client mais son résolveur DNS. Si le client utilise un résolveur DNS public (comme OpenDNS), le client du contenu et le résolveur peuvent être sur des continents différents et la redirection ne se fera pas vers le CDN optimal. Autre inconvénient, on ne pourra tenir compte, dans l'URL original, que du nom de domaine, le reste de l'URL n'étant pas connu du serveur DNS.

À noter qu'il existe une variante, où on ne renvoie pas directement l'adresse IP mais un nom (technique CNAME ou, mieux, DNAME). C'est le cas de l'Élysée citée plus haut :

% dig A www.elysee.fr
...
;; ANSWER SECTION:
www.elysee.fr.		3600 IN	CNAME cdn.cdn-tech.com.c.footprint.net.

Autre possibilité de redirection, la redirection HTTP : cette fois, on se sert des codes de retour 301 ou 302 qui indiquent au client HTTP qu'il doit aller chercher ailleurs ce qu'il voulait. La nouvelle URL est donnée dans la réponse (en-tête Location:). Cette fois, le serveur peut changer tout l'URL, pas juste le nom de domaine, on connait l'adresse IP du client original (le RFC oublie de mentionner qu'il peut être un relais), ce qui peut permettre de mieux choisir le serveur, et enfin on a plein d'autres informations qui peuvent être utiles pour une redirection intelligente, comme la marque du logiciel client utilisé.

Il y a par contre des inconvénients, le changement de domaine fait que les cookies ne suivront pas, et les caches ne gardent pas en mémoire les redirections (le RFC 7234 le permet mais ce n'est pas fréquemment mis en œuvre).

La section 4 du RFC donne quelques détails sur les différentes interfaces du système, interfaces qui avaient été présentées dans les RFC 6707 et RFC 7337. Dans certains cas, l'interconnexion des CDN se fait à l'intérieur du protocole de communication déjà utilisé (in-band). C'est le cas des redirections HTTP. Dans d'autres cas, on utilise un protocole externe (out-of-band). Il faut également noter, pour comprendre la complexe combinaison d'interfaces de CDNI que, bien que les interfaces soient largement indépendantes, elles reposent sur des conventions communes, par exemple pour le nommage des ressources.

Parmi les détails creusés dans ce RFC 7336 sur les interfaces :

  • Une liste des éléments d'information qui peuvent être intéressants pour l'interface de journalisation, LI (Logging Interface). Conceptuellement, cette interface peut être vue simplement comme une copie des fichiers apache/access.log du CDN aval vers l'amont... Attention, le champ indiquant le nom de domaine demandé (VirtualHost dans Apache) peut être différent de l'original, s'il y a eu redirection HTTP.
  • Certains services de l'interface de communication de métadonnées (MI pour Metadata Interface) peuvent être assurés par le mécanisme de redirection. Par exemple, si le fournisseur de contenu veut limiter l'accès aux utilisateurs européens, il suffit que le CDN amont ne redirige pas vers le CDN américain, pour les requêtes de ce contenu à accès limité. (Le RFC note toutefois que cela manque de souplesse : par exemple, il y a peu de chances que le CDN aval ait une couverture géographique qui coïncide parfaitement avec les exigences de géo-limitation du fournisseur de contenu.)

La section 5 du RFC décrit plusieurs scénarios d'usage de CDNI quand il sera terminé. Par exemple, bien que le modèle de référence (et les exemples que j'ai cités) soient unidirectionnels (le CDN A délègue au CDN B et jamais le contraire), on pourra se servir de CDNI pour les CDN maillés, avec des graphes arbitraires entre les différents CDN.

Déléguer ses fonctions soulève évidemment tout un tas de questions, comme toute sous-traitance. Le CDN amont peut-il faire confiance au CDN aval pour servir le contenu correctement ? Les statistiques de trafic qu'il remonte sont-elles correctes ou bien modifiées dans l'intérêt exclusif du CDN aval ? La section 6 explore le problème de la confiance dans un monde de CDN connectés. Notons que le fournisseur de contenu a déjà aujourd'hui le même problème avec son opérateur CDN : dès qu'on sous-traite, la question de la confiance surgit. Mais CDNI rend les choses un peu plus compliquées : un fournisseur de contenu qui a signé avec l'opérateur de CDN amont peut ne pas être conscient que celui-ci a un accord avec l'opérateur CDN aval. Et si un opérateur CDN modifiait les fichiers avant de les envoyer ? Il existe évidemment des solutions techniques, comme la signature cryptographique des fichiers. Mais, fondamentalement, il faut une combinaison de confiance et de quelques vérifications (par exemple des sondages aléatoires faits par divers clients pour vérifier que le contenu est bien là, et bien conforme à ce qui est demandé).

En parlant de confiance et de sécurité, la section 7 se demande quelles sont les conséquences de l'interconnexion de CDN pour la vie privée (l'existence d'une section nommée Privacy considerations est récente dans les RFC et vient du RFC 6973). Un CDN est bien placé pour observer beaucoup de choses dans le comportement de l'utilisateur, par exemple à quels fichiers il accède, de mécanique_quantique_pour_les_nuls.epub à how_to_make_bombs.avi. L'utilisateur qui accède à un site Web ne sait typiquement pas si celui-ci utilise un CDN (cela se trouve relativement facilement mais tout le monde n'a pas les compétences ou le temps nécessaire). Il fait confiance au site Web, mais ne se rend pas compte qu'il fait également confiance à l'opérateur CDN (qui peut avoir une autre éthique, ou être soumis à d'autres lois : lorsqu'on visite http://www.elysee.fr/, on croit faire confiance à un organisme public français, alors qu'il est en fait servi par un CDN états-unien, soumis au Patriot Act).

Certaines fonctions de CDNI sont justement conçues pour faire circuler de l'information sur l'activité des utilisateurs, notamment l'interface de journalisation (LI). Il faudra donc s'assurer qu'elles disposent de protections appropriées.

Et, toujours sur la sécurité, la section 8 note également d'autres points délicats, qui s'ajoute aux questions de sécurité déjà existantes pour les CDN actuels :

  • Certaines exigences des fournisseurs de contenu (distribution limitée géorgraphiquement, ou bien limitée dans le temps) sont plus difficiles à satisfaire lorsqu'il y a interconnexion des CDN,
  • Par contre, les menottes numériques ne sont pas affectées par CDNI puisqu'elles reposent typiquement sur des mécanismes présents dans le contenu lui-même,
  • Les interfaces entre CDN doivent être protégées, contre l'écoute (cas des journaux d'activité dans la section précédente) mais aussi contre les modifications non autorisées (imaginez qu'un méchant modifie les contenus servis lorsqu'ils passent d'un CDN amont au CDN aval), même si l'interconnexion se fait en utilisant l'Internet public, non sécurisé.

Deux fournisseurs de solutions techniques, Cisco et Alcatel-Lucent, ont annoncé qu'ils travaillaient sur des prototypes d'interconnexion de CDN, utilisant le futur protocole qui sera la concrétisation de ce cadre.


Téléchargez le RFC 7336


L'article seul

Articles des différentes années : 2014  2013  2012  2011  2010  2009  2008  Précédentes années

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